Code Monkey home page Code Monkey logo

Comments (103)

anisabboud avatar anisabboud commented on May 23, 2024 109

I've successfully migrated from flex-layout (~200 usages) to CSS Flexbox + CSS Grid + Angular CDK layout (without Tailwind).

Here are the replacements I made, in case they are helpful to others.

fxLayout="row", fxLayout="col"

<div fxLayout="row"> → <div class="flex-row">.
Global CSS:

// Flex row/col + grid.
.flex-row { display: flex; flex-direction: row; }
.flex-col { display: flex; flex-direction: column; }
.grid { display: grid; }

// Flex-wrap utils.
.flex-wrap { flex-wrap: wrap; }  // Mostly used with flex-row, when wrapping is desired.
.flex-col-xs { @media screen and (max-width: 599px) { flex-direction: column; } }  // Switch from flex-row to flex-col on mobile.

fxLayoutGap

<div fxLayoutGap="8px"> → <div class="gap-8">.
Global CSS for common gaps (& inline CSS for uncommon gaps):

// Gap.
.gap-4 { gap: 4px; }
.gap-8 { gap: 8px; }
.gap-10 { gap: 10px; }
.gap-12 { gap: 12px; }
.gap-16 { gap: 16px; }

fxLayoutAlign

<div fxLayoutAlign="justify-between center"> → <div class="space-between items-center">.
Global CSS for common alignments (& inline CSS for uncommon ones):

// Justify content.
.space-between { justify-content: space-between; }  // Used very often with flex-row.
.justify-center { justify-content: center; }  // Used to center something via flexbox.

// Align items. (Naming inspiration: https://tailwindcss.com/docs/align-items.)
.items-center { align-items: center; }  // Used very often with flex-row.

fxFlex

<div fxFlex> → <div class="flex-1">.
Global CSS for common flex values (& inline CSS for uncommon values like flex-basis):

// Flex/grow/shrink properties https://developer.mozilla.org/en-US/docs/Web/CSS/flex.
.flex-1 { flex: 1 }  // Same as flex: 1 1 0 (grow, shrink, basis 0). Has similar effect to width: 100%;
.flex-grow { flex-grow: 1; }  // Same as flex: 1 1 auto (grow, shrink, basis auto). For spacer, etc. 

fxHide, fxShow

<div fxHide.xs> → <div class="hide-xs">.
Global CSS for common hide breakpoints (depending on your app):

// Hide & show for different breakpoints.
.hide-xs    { @media screen and (max-width: 599px) { display: none; } }  // Hide on mobile.
.hide-gt-xs { @media screen and (min-width: 600px) { display: none; } }  // Show only on mobile. Hide on desktop.
.hide-sm    { @media screen and (max-width: 959px) { display: none; } }  // Hide on mobile/tablet.
.hide-gt-sm { @media screen and (min-width: 960px) { display: none; } }  // Show only on mobile/tablet. Hide on desktop.

gdColumns

<div gdColumns="XYZ" gdGap="8px"> → <div class="grid gap-8" style="grid-template-columns: XYZ">.
I.e., re-using grid & gap classes from above, and using inline style for grid-template-columns.

ngStyle.xs, ngClass.xs

These are the most challenging to replace - they're one of the nicest features of the flex-layout library.
I didn't find a straight-forward replacement. I just replaced them with custom CSS classes & breakpoints in the CSS file.
For example, <div style="width: 100px" ngStyle.xs="width: 50px"> → <div class="my-div"> + CSS below

.my-div {
  width: 100px;
  @media screen and (max-width: 599px) {
    width: 50px;  // Smaller on mobile.
  }
}

Note to avoid confusion: Angular's own ngStyle & ngClass are not deprecated.
Only the flex-layout extension of these (ngStyle.breakpoint & ngClass.breakpoint) is deprecated.

MediaObserver

Replaced with Angular CDK Layout's BreakpointObserver (which felt faster to me in run-time).
Before:

const isMobile: Observable<boolean> = this.mediaObserver.asObservable().pipe(
  map((changes: MediaChange[]) => changes.some(change => change.mqAlias === 'xs')));

After:

const isMobile: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.XSmall).pipe(
  map(state => state.matches));

from flex-layout.

blogcraft avatar blogcraft commented on May 23, 2024 62

I started giving (unwillingly) a try to Tailwind CSS. And I was quite surprised as it is not a bad experience at all.

I found a guide here to help migrate from Flex Layout to Tailwind and it's pretty straight forward.

Also, for people using VS Code I recommend getting the Tailwind CSS IntelliSense extension. It is quite useful.


In a nutshell it is this:

Angular Flex-Layout directives Tailwind Equivalent CSS classes
fxLayout=”<direction> <wrap>” Use flex-<direction> flex-<wrap> classes
fxLayoutAlign=”<main-axis> <cross-axis>” Use justify-<main-axis> items-<cross-axis> content-<cross-axis> classes
fxLayoutGap=”% | px | vw | vh” Use gap on flex items
fxFlex=”” | px | % | vw | vh | <grow> | <shrink> <basis> Use flex, grow, and shrink classes along with customflex-basis classes overriding tailwind config
fxFlexOrder=”int” Use Order classes along with custom classesoverriding tailwind config
fxFlexOffset=”% | px | vw | vh” Use Margin classes
fxFlexAlign=”start | baseline | center | end” Use Align Self classes
fxFlexFill and fxFill Use w-full and h-full classes
fxShow and fxHide Use block and hidden classes
Responsive API Override Tailwind’s default breakpoints to matchwith Angular Flex-Layout. For example,theme: {extend: {screens: {‘sm’: { ‘min’: ‘600px’, ‘max’: ‘959px’ },‘lt-sm’: { ‘max’: ‘599px’ }….},}} I personally I didn't need to do this.
[ngClass.xs]=”{‘first’:false, ‘third’:true}” Use aforementioned responsive APIclass=”gt-xs:first xs:third”
[ngStyle.sm]=”{‘font-size’: ’16px’}” Use custom CSS classes as mentioned above.
<img src=”a.ico” src.xs=”b.ico”/> Use custom CSS classes as mentioned above.
gdAreas.xs=”header header | sidebar content” Tailwind does not have a support forgrid-template-areas so we have to use grid columnsand then apply Grid Row Start/End or
Grid Column Start/End classes on grid items.For example, xs:grid-cols-2 xs:grid-rows-2
gdAlignColumns=”<main-axis> <cross-axis>” Use Align Items and Align Content classes
gdAlignRows=”<main-axis> <cross-axis>” Use Place Content and Place Items and Place Items classes
gdAuto Use Grid Auto Flow classes
gdColumns Use Grid Template Columns classes along with customclasses overriding tailwind config
gdRows Use Grid Template Rows classes along with customclasses overriding tailwind config
gdGap Use Gap classes along with custom classesoverriding tailwind config

from flex-layout.

DuncanFaulkner avatar DuncanFaulkner commented on May 23, 2024 33

Hi
I'm looking into the possibility to take on this project and keep it running. I have used this in the past and have written a couple of blog posts on this library and contributed to the project's documentation on several occasions. I see a lot of people being affected by the Angular team's decision to drop this project leaving the community with a lot of modifications to their projects to migrate to something else. If I can keep the project running (with the help and support of this great community) then that's got to be good for everyone (I hope).

The thing is, I can't do this by myself so I will need help from the community, so I would like to know what the community would like to see initially for things like:

  1. SLA for cutting releases*
  2. Addressing security issues*
  3. Addressing bug fixes*
  4. What direction the project takes
  5. Anything else the community feels is good for the project.
  6. What we should be doing more off
  7. What we should be doing less off

These are my top priority items (*)
All suggestions are welcomed and encouraged.

Thanks
Duncan

from flex-layout.

michaelfaith avatar michaelfaith commented on May 23, 2024 31

Our layout needs, I feel, are pretty straightforward. We're almost exclusively using the fx directives (e.g. fxLayout, fxFlex, fxLayoutGap, fxLayoutAlign) in our components, along with the breakpoint aliases (e.g. fxFlex.md), and it seems like Tailwind might be a good alternative to migrate to for that. The main issue is that tailwind isn't currently supported for Angular libraries (via ng-packagr). Any advice on how to achieve that in a re-usable way (since it'll be used across our component library) without tailwind?

Also, really sorry to see this close down. Appreciate all your hard work over the years keeping it alive.

from flex-layout.

coreConvention avatar coreConvention commented on May 23, 2024 28

Just now seeing this. This is upsetting news to say the least. I built an entire JsonSchema/ui-schema based platform around angular flex for one of the biggest hospital chains in the country, which only works because of the way angular flex works (using the directives). There really is no alternative that I am aware of.

Have you all considered handing the project off to the community to maintain? Or is the issue some necessary collaboration with the angular team?

from flex-layout.

blogcraft avatar blogcraft commented on May 23, 2024 25

It's sad to see this library go away when it was clearly very good! 😕

For me I have no idea where to migrate and what would be even the benefits, but I foresee it to be a very big pain. Our app has ~370 Components and counting and ~4700 attributes in the templates (and we have 3 of those apps). We heavily use fxLayout (cloumn, rows and wraps), fxLayoutGap, fxFlex (with breakpoints and calc), fxFlexFill, fxLayoutAlign, ngClass.*, fxHide and show mostly...

But Thanks a lot @CaerusKaru for all your time and dedication maintaining this library. It has been extremely helpful!

from flex-layout.

MikaStark avatar MikaStark commented on May 23, 2024 22

Using tailwind is pointless to me. I personally prefer to write few css lines eventually coupled with CDK layout API than over weight my project with a css framework built for people unable to actually write CSS by themself.

I agree with the previous post, if this lib should be maintained by the community it would be fantastic

from flex-layout.

aceArt-GmbH avatar aceArt-GmbH commented on May 23, 2024 18

We replaced ~2000 simple usages of flex-layout with following CSS.
Kinda hacky, but seems to work.

CSS
// fxFlex
[fxFlex] {
    flex: 1 1 0%;
    box-sizing: border-box;
}

*:has(> [fxFlex]) {
    flex-direction: row;
    box-sizing: border-box;
    display: flex;
}

[fxFlex='5'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 5%;
}

[fxFlex='20'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 20%;
}

[fxFlex='25'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 25%;
}

[fxFlex='30'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 30%;
}

[fxFlex='33'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 33%;
}

[fxFlex='50'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 50%;
}

[fxFlex='66'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 66%;
}

[fxFlex='67'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 67%;
}

[fxFlex='70'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 70%;
}

[fxFlex='80'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 80%;
}

[fxFlex='100'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 100%;
}

[fxFlex='1 0 auto'] {
    flex: 1 0 auto;
    box-sizing: border-box;
}

[fxFlex='0 1 auto'] {
    flex: 0 1 auto;
    box-sizing: border-box;
}

// fxLayout
[fxLayout] {
    box-sizing: border-box;
    display: flex !important;
}

[fxLayout='row wrap'] {
    flex-flow: row wrap;
    flex: 1 1 1e-9px;
}

[fxLayout='row'] {
    flex-direction: row;
}

[fxLayout='column'] {
    flex-direction: column !important;

    &[fxLayoutGap='8px'] > *:not(:last-child) {
        margin-right: unset;
        margin-bottom: 8px;
    }
    &[fxLayoutGap='12px'] > *:not(:last-child) {
        margin-right: unset;
        margin-bottom: 12px;
    }
    &[fxLayoutGap='16px'] > *:not(:last-child) {
        margin-right: unset;
        margin-bottom: 16px;
    }
    &[fxLayoutGap='24px'] > *:not(:last-child) {
        margin-right: unset;
        margin-bottom: 24px;
    }
    &[fxLayoutGap='32px'] > *:not(:last-child) {
        margin-right: unset;
        margin-bottom: 32px;
    }

    & > [fxFlex='5'] {
        max-height: 5%;
        max-width: unset;
    }
    & > [fxFlex='20'] {
        max-height: 20%;
        max-width: unset;
    }
    & > [fxFlex='25'] {
        max-height: 25%;
        max-width: unset;
    }
    & > [fxFlex='30'] {
        max-height: 30%;
        max-width: unset;
    }
    & > [fxFlex='33'] {
        max-height: 33%;
        max-width: unset;
    }
    & > [fxFlex='50'] {
        max-height: 50%;
        max-width: unset;
    }
    & > [fxFlex='66'] {
        max-height: 66%;
        max-width: unset;
    }
    & > [fxFlex='67'] {
        max-height: 67%;
        max-width: unset;
    }
    & > [fxFlex='70'] {
        max-height: 70%;
        max-width: unset;
    }
    & > [fxFlex='80'] {
        max-height: 80%;
        max-width: unset;
    }
    & > [fxFlex='100'] {
        max-height: 100%;
        max-width: unset;
    }
}

// fxLayoutGap
[fxLayoutGap='8px'] > *:not(:last-child) {
    margin-right: 8px;
}
[fxLayoutGap='12px'] > *:not(:last-child) {
    margin-right: 12px;
}
[fxLayoutGap='16px'] > *:not(:last-child) {
    margin-right: 16px;
}
[fxLayoutGap='24px'] > *:not(:last-child) {
    margin-right: 24px;
}
[fxLayoutGap='32px'] > *:not(:last-child) {
    margin-right: 32px;
}

// fxLayoutAlign
[fxLayoutAlign] {
    display: flex;
    box-sizing: border-box;
    flex-direction: row;
}
[fxLayoutAlign='center center'] {
    place-content: center;
    align-items: center;
}
[fxLayoutAlign='end center'] {
    place-content: center flex-end;
    align-items: center;
}
[fxLayoutAlign='end top'] {
    place-content: stretch flex-end;
    align-items: stretch;
}
[fxLayoutAlign='start center'] {
    place-content: center flex-start;
    align-items: center;
}
[fxLayoutAlign='start start'] {
    place-content: flex-start;
    align-items: flex-start;
}
[fxLayoutAlign='space-between center'] {
    place-content: center space-between;
    align-items: center;
}
[fxLayoutAlign='start stretch'] {
    place-content: stretch flex-start;
    align-items: stretch;
    max-height: 100%;
}
[fxLayoutAlign='end'] {
    place-content: stretch flex-end;
    align-items: stretch;
}
[fxLayoutAlign='center stretch'] {
    place-content: stretch center;
    align-items: stretch;
    max-height: 100%;
}
[fxLayoutAlign='center center'] {
    place-content: center;
    align-items: center;
}
[fxLayoutAlign='center end'] {
    place-content: flex-end center;
    align-items: flex-end;
}
[fxLayoutAlign='stretch stretch'] {
    place-content: stretch flex-start;
    align-items: stretch !important;
}

// fxHide
[fxHide] {
    display: none;
}

// `.` can't be part of attribute selector :(
// fxHide.lt-lg
@media screen and (max-width: 1279px) {
    [fxHidelt-lg] {
        display: none !important;
    }
}

// fxHide.gt-md
@media screen and (min-width: 1280px) {
    [fxHidegt-md] {
        display: none !important;
    }
}

// fxShow.gt-sm
@media screen and (min-width: 960px) {
    [fxShowgt-sm] {
        display: initial;
    }
}

// fxShow.gt-xs
@media screen and (min-width: 600px) {
    [fxShowgt-xs] {
        display: initial;
    }
}

// fxFill
[fxFill] {
    height: 100%;
    min-height: 100%;
    min-width: 100%;
    width: 100%;
}

from flex-layout.

yuveliremil avatar yuveliremil commented on May 23, 2024 14

Angular Team !
@andrewseguin, @mgechev, @filipesilva, @gkalpak, @jessicajaniuk, @crisbeto, @devversion, @simonaco, @waterplea, @alisaduncan and etc.

What do you think about this?
Why should people have bad thoughts about Angular because of this deprecation?

@CaerusKaru, you say below message last mounth:
We will publish a v15 version. This will unpin the dependencies so, barring any structural breaking changes, this will not happen in the near future. We hope to get this version out this coming week.

We still wait for the v15.

from flex-layout.

sourav-bhar avatar sourav-bhar commented on May 23, 2024 13

Really sad and disappointed to see this library be deprecated. Like many others here, we have used and depended on flex-layout heavily over the years and it's a core part of every component we have ever written.

I see migrating all of that to other alternatives like Tailwind to be a huge, non-trivial, undertaking.

This was a great library and we're truly grateful to all the maintainers who have done such a wonderful job over the years. Please consider handing it over to the community instead of a complete deprecation.

Here is our usage statistics:

We are using flex-layout heavily across 4 production apps. We mainly use the flex-layout directives with breakpoints in all the apps.

Total usage statistics: 7,309 times across 352 components

Here's the breakdown by directive:
fxFlex – 3,625 times across 352 components
fxLayout – 3,586 times across 351 components
fxLayoutGap – 909 times across 283 components
fxLayoutAlign – 1,346 times across 350 components
fxFlexFill – 6 times in 5 components
fxHide, fxShow – 57 times across 32 components

from flex-layout.

cubidobusinesssolutions avatar cubidobusinesssolutions commented on May 23, 2024 13

For basic usage, plain CSS will do (typos included and not exhaustive)

[fxLayout] {
  display: flex;
  box-sizing: border-box;
}
[fxLayout=row] {
  flex-direction: row;
}
[fxLayout='row wrap'] {
  flex-direction: row;
  flex-wrap: wrap;
}
[fxLayout=column] {
  flex-direction: column;
}
[fxLayout='column wrap'] {
  flex-direction: column;
  flex-wrap: wrap;
}

[fxFlex] {
  flex: 1 1 auto;
}

[fxLayoutAlign='start center'] {
  justify-content: flex-start;
  align-items: center;
}
[fxLayoutAlign='start stretch'] {
  justify-content: flex-start;
  align-items: stretch;
}
[fxLayoutAlign='center start'] {
  justify-content: center;
  align-items: flex-start;
}
[fxLayoutAlign='space-between center'] {
  justify-content: space-between;
  align-items: center;
}
[fxLayoutAlign='stretch stretch'] {
  align-content: stretch;
  align-items: stretch;
}
[fxLayoutAlign='stretch center'] {
  align-content: stretch;
  align-items: center;
}

[fxLayoutGap='1rem'] {
  column-gap: 1rem;
}
[fxLayoutGap='1rem grid'] {
  gap: 1rem;
}

from flex-layout.

jpike88 avatar jpike88 commented on May 23, 2024 12

All I can say is wow.

The entire purpose of this library was to prevent the need to pollute elements with css classes. It serves that purpose extremely well, increasing readability and preventing the code from descending into css hell, falling back to CSS when absolutely necessary.

If the Angular team knew what was good they'd put in the small amount effort to keep it as a part of their toolkit, or even integrate it into the CDK itself. It's like second nature to use in an Angular project, very disappointing news really.

There is no other library I know of that works in this way using directives, and the utility is too good to lose. I'll happily join an unofficial fork to keep it up to speed, and probably like many others, have no intention of dropping it for my various projects.

from flex-layout.

azimuthdeveloper avatar azimuthdeveloper commented on May 23, 2024 12

which is that unfortunately no amount of money (short of paying a full Google employee salary) will fund this to stay in the same namespace, because at the end of the day, Google would be responsible, and that's something the team cannot afford.

If the Angular team, or the people funding the Angular team, can't afford to maintain a widely used package like this (one that the deprecation of is going to cause literally thousands of man-hours of development work to refactor away from) then that is deeply concerning for the future of Angular as a whole. Why? Because it sounds like more of a financial decision than a "What's best for Angular and Angular developers decision". You can unpin dependencies etc, but won't this just simply lead to the atrophy of Angular Layout and increased breakages/incompatibilities over time? As you say, it won't guarantee compatibility forever, which is totally understandable (even in the v14 to v15 migration guide, there are nineteen steps to migrate from an Angular Material v14 app to an Angular Material v15 app. It's easy to imagine how one of these changes, possibly even as soon as v15 to v16, would cause a breaking change that nobody would be able to fix. And because of unpinned dependencies, that's going to culminate in the Angular compiler just throwing up and dumping errors of hard-to-read/hard-to-debug problems, possibly without the developer knowing exactly what has gone wrong. Or worse still, CSS weirdness with no obvious console output).

I understand your frustration, and those of the other users here, but I would like to remind everyone the primary goal of this issue is to track meaningful and impactful migration guides that would ease this transition. I am fully committed to authoring those guides depending on feedback, but the complexity of the library is such that it's really hard to understand where the priority is without it.

To write a migration guide, for even basic apps, I would suggest would be an extremely difficult and lengthy process. Extending that process by adding in how many corner cases and specialized layout needs developers would have, it's hard to see how such a task could have a meaningful outcome. Plus, even if there was an incredible migration guide, many Angular developers work against tightly defined sprints and deadlines and don't have an extra couple of months to refactor away from flex-layout.

Anyway - the decision has been made, so agitating on the particulars of that decision is fruitless (and I'm also probably aggravating someone who has given a lot of time to flex-layout, which seems counter-intuitive as well). It just seems like a genuinely good solution is being dropped for fiscal reasons, which makes me wonder what part of Angular would be dropped next for the same reason. That spooks me.

Thanks for all your hard work on flex-layout. I hope it wasn't all for nothing, and in some way, it survives into the future. I'm also sorry for taking the issue offtopic, it's just surprising (and unpleasant) that there's a huge refactor coming, to get the apps I maintain to look the same as they do today.

EDIT: Just to round this out, according to the Angular release schedule, we can expect a stable release of Angular every 6 months. Angular 15 was released in November 2022, so by May 2023, we should be welcoming Angular 16, and the end of official support for flex-layout. At this point in time, because no tests are being run against flex-layout, and it has unpinned dependencies, we can expect our apps to stop compiling, or the layouts to become totally wrong after we have upgraded to Angular 16. This is about when several developers will notice that something is up. So, in reality, we have five months from now to refactor away from flex-layout, if we would like to take Angular 16 when that lands.

To quote the Angular release page, under "Angular versioning and releases", it says there: "We recognize that you need stability from the Angular framework. Stability ensures that reusable components and libraries, tutorials, tools, and learned practices don't become obsolete unexpectedly. Stability is essential for the ecosystem around Angular to thrive."

A package within the Angular namespace being deprecated like this, and only really being supported until Angular 16 lands (which should happen in roughly five months), to me, is proof that the Angular team is really not living up to what they write on their release page. Literally, an Angular-exclusive package, published within the Angular namespace, tooling which can only be used for Angular, is being deprecated. This is the definition of learned practices becoming obsolete unexpectedly.

@jpike88 talks about the "damage of trust" between the angular brand and the devs who use the library. That's absolutely correct and should occur when the people in the Angular core team can't adhere to the things they write on the release page. How can anyone be sure that specific knowledge they have about Angular Material won't become obsolete when the next major version of Angular lands? We can't. And that's a problem.

Obviously, and I want to really strain this point, I sincerely appreciate everyone's hard work on flex-layout, and what I'm saying here is not supposed to reflect negatively on that, or be taken as an affront or be offensive to the Angular team, and certainly not the developers of flex-layout itself. But somehow, the people behind Angular dun goofed and snookered themselves into a corner where they seemingly have no choice but to go against what is written on their release page and make us all wonder if this is the last thing to go. By itself, that is a problem, and it probably should get an answer.

from flex-layout.

jpike88 avatar jpike88 commented on May 23, 2024 11

Notably absent and what personally rubs me the wrong way that is a representative from the Angular team is not taking ownership of this situation, even if it’s for the decommissioning of this library. This is a heavily used key component by many that was under their namespace, and I would have expected better leadership from them here. The unfortunate outcome is the damage of trust between the angular brand and the large amount of devs using this library under the impression that it would be given the attention it deserves.

Thanks for your efforts, this library has been instrumental in making developer onboarding easier and decluttering our styling. Good luck in the future.

from flex-layout.

azimuthdeveloper avatar azimuthdeveloper commented on May 23, 2024 10

There's a lot wrong here.

First, community engagement: There are over 350k weekly downloads of this package.

image

In a month, that's over a million downloads of Angular Layout. Now, these people pay nothing for Angular Layout, but I guess they also pay nothing for the entire Angular toolset. Despite these millions of downloads and significant community usage of Angular Layout, this conversation took place within the Angular team. With such significant and extended use by the community, deciding the fate of a critical piece of Angular that so many people used, without engaging the community, is simply the wrong thing to do. Could we, the community, have the option to pay into something, like a Patreon or something, to continue the development of this critical piece of Angular?

Secondly, killing something that works: This lends itself, quite unfortunately, to an affliction that Google-related products seem to suffer from disproportionately. Namely - "This thing is working well and is in use by a lot of people. Let's kill it". Angular v15,v16,v17, and beyond may be high-quality and genuinely beautiful pieces of software. But there are a lot of people out there that don't know that flex-layout has been deprecated, and when they try to move to the next version of Angular, their first warning will be the package failing in the ng update step. I won't remember the improvements to the rendering engine, or that my page views are 0.2 seconds faster. I will care that a package in my packages.json has been deprecated and there is no replacement, forcing me to either stick with the old version of Angular or refactor my entire application.

Finally, undermining confidence in Angular as a whole: Removing widely used packages from mainline support undermines and reduces the confidence that developers can have in Angular as a whole. Should we expect Angular Material to be spontaneously deprecated next week? And if not, why not? Flex layout has 350k downloads a week, Angular material only has three times that. It's not off by some order of magnitude. I suppose we could say that flex layout is "just a layout library". Could we not just say "Angular Material is just a look and feel library, we're dropping it as well, refactor your code to Materialize.css"? It would be nice to be assured that other highly-used pieces of Angular will be around this time next month.

Also, small nitpick. The linked article, entitled "Farewell, Flex Layout" is 3/4 of the author telling a fond recollection of bygone eras, and cute memories they have of the Angular team. Then it abruptly turns to "Angular Flex Layout is going away. Nothing is available to replace it byeeeeeeeeeee". This isn't a good deprecation article. A good deprecation article would have the headings "What is happening?" "What does this mean for you?" "What are your migration options?". Such an article, written so light-heartedly with no real answers or help for the developer, is so bad that it borders on the offensive.

I'm an avid Angular developer, and I sincerely hope that the incorrect decision to deprecate this library is reversed, and flex-layout is instead brought into the main Angular tooling. If not, I hope the article is updated with information that developers can actually use. And still, if both of those things don't come to pass, I genuinely hope that this is a flash in a pan and not a sign of things to expect from Angular moving forward. Because, at this point, if Angular Material got deprecated as well next year, I could only blame myself if I was surprised.

from flex-layout.

DuncanFaulkner avatar DuncanFaulkner commented on May 23, 2024 9

Thank you all for your feedback and support on this I will try and collate all the information and put something together.

from flex-layout.

erenerdilli avatar erenerdilli commented on May 23, 2024 9

@CaerusKaru is there an estimated date for release of v15, since the holidays are over? We are quite intertwined with this library in our applications, and the migration brings a lot of challenges with tight deadlines.

from flex-layout.

jnfaerch avatar jnfaerch commented on May 23, 2024 7

Sad to see this project close own :(

We are using flex-layout heavily in one big and several smaller apps.
I hope Tailwind can be a replacement but right now I have no overview of this.

We use this library in our large app ~1.200 times
Breakpoints heavily used all through the app
These are the main directives we use
fxLayout
fxLayoutGap
fxLayoutAlign
fxFlex
fxFlexFill
fxHide
fxShow

Thank you for your work on this library and thank you for the planned transition/shut-down period 👍

from flex-layout.

CaerusKaru avatar CaerusKaru commented on May 23, 2024 7

First and foremost, thank you to everyone who has so far shared a solution that has worked for them. This kind of upstreaming and knowledge sharing is crucial to a smooth transition, and is a benefit to all. Sincerely, thank you.

Second, in response to a few comments about "handing off to the community": I am totally ok with anyone forking this package under a new namespace and maintaining something supported the community can move to. If the support story is truly solid, I'm also more than happy to endorse the "official" successor. I do want to make clear, though, that we did search for an appropriate community sponsor of the project prior to the sunsetting of this repo. Unfortunately, no one we talked to really felt it was in their primary domain/expertise to maintain, and so here we are. The project cannot continue under the Angular namespace, and therefore its current NPM package name, because the credentials for publishing must remain tightly controlled by the Angular team. This, along with the unofficial "supported by Angular" moniker the namespace gives the library. But if someone wants to setup, for instance ngx-layout or the like, you are more than welcome.

In the meantime, please keep adding migration stories here. When we get closer to the beginning/middle of LTS, I will start publishing guides/blogs, collated from the cases here (along with some harder cases without easy solutions).

from flex-layout.

ginxdroid avatar ginxdroid commented on May 23, 2024 7

A library which has 300k downloads per week is going to halt with just a single Medium post!!!! What the hell........ I am pretty frustrated and sad.

from flex-layout.

born2net avatar born2net commented on May 23, 2024 6

Angular team drop of flex-layout is disconcerting and we hope the angular team will reconsider.

We have a huge project in Angular 14 with thousands of libraries which is developed by a over dozen developers.
We rely heavily on flex-layout, we simply are in shock that the Angular team has decided to drop support for it.
We tried to upgrade to Angular v15 and failed due to the lack of support from angular-material.
We really hope that through this post and the support of the community the Angular team will reconsider and allow opt-in to flex-layout while supporting it for backwards and forward compatibility, test it for upgrade to v15+ and beyond or allow for a solid migration guide (possibly via CLI).

we use:

fxLayout
fxLayoutGap
fxLayoutAlign
fxFlex
fxFlexFill
fxHide
fxShow

We simply are unsure on how to move forward and we are asking the team and the community for assistance.

Sean.

from flex-layout.

Franweb79 avatar Franweb79 commented on May 23, 2024 6

Angular Team ! @andrewseguin, @mgechev, @filipesilva, @gkalpak, @jessicajaniuk, @crisbeto, @devversion, @simonaco, @waterplea, @alisaduncan and etc.

What do you think about this? Why should people have bad thoughts about Angular because of this deprecation?

@CaerusKaru, you say below message last mounth: We will publish a v15 version. This will unpin the dependencies so, barring any structural breaking changes, this will not happen in the near future. We hope to get this version out this coming week.

We still wait for the v15.

Seems they answered something on this closed issue (closed because it was "too heated", as if what they are doing was not worthy of it), also showing us how commited they are because they state there they give us at least a year of TLS support while we waste the time fixing and paying the consequences of their decission ( aka "we plan for migrations").

#1430 (comment)

Maybe they will delete this post or mark it as off-topic, as they do with any uncomfortable truth, but just wanted to point to a response they gave today.

If it is frustrating for them, as they say, which don´t have to face the consequences of what they have done (regarding applications, because for the image of Angular, Google and its team, those consequences are clear), imagine for us.

But well, who cares, I am learning React. Merry Christmas.

from flex-layout.

DuncanFaulkner avatar DuncanFaulkner commented on May 23, 2024 6

I've now setup a clone of the Angular Flex-Layout library- this is still very much at the early stages but I've got the GitHub repo set up along with the Circle CI and a package on NPM.

The new home is now at

@ngbracket/ngx-layout.

or copy this link
https://github.com/ngbracket/ngx-layout

I've pushed up a pre-release version 15.0.1-beta.42, this version is just an initial release just to make sure things are working, the only thing that got changed was the name which has been changed from @angular to @ngbracket, some of the readme's, and documentation still need to be updated to reflect this change which I'm hoping to complete shortly.

Please do check it out I welcome all feedback

from flex-layout.

wassim-k avatar wassim-k commented on May 23, 2024 6

Here's a basic javascript code for migrating flex layout directives to tailwindcss classes.

It supports fxLayout, fxLayoutAlign, fxFlex, fxGap & fxFill directives, which covered 95% of our project, the rest I updated manually.

mkdir flex-layout-to-tailwind
cd flex-layout-to-tailwind
npm i cheerio
code index.js # this opens a vscode window with an empty index.js file
# Paste the code below.
# Replace [Enter path to angular application here] with the correct path.
node index.js
const fs = require('fs');
const path = require('path');
const { load } = require('cheerio');

const mainAxisMap = {
    'start': 'justify-start',
    'center': 'justify-center',
    'end': 'justify-end',
    'space-around': 'justify-around',
    'space-between': 'justify-between',
    'space-evenly': 'justify-evenly',
};

const crossAxisMap = {
    'start': 'items-start',
    'center': 'items-center',
    'end': 'items-end',
    'baseline': 'items-baseline',
    'stretch': 'items-stretch',
};

const fxAttributes = [
    'fxFill',
    'fxLayout',
    'fxLayoutAlign',
    'fxGap',
    'fxFlex'
];

function convertFlexLayoutToTailwind(filePath) {
    const html = fs.readFileSync(filePath, 'utf-8');
    return extractHtmlTags(html)
        .reduce((html, tag) => html.replace(tag, convertTag(tag)), html);
};

function convertTag(tag) {
    if (!fxAttributes.some(a => tag.includes(a))) return tag;

    const $ = load(tag, { xmlMode: true, decodeEntities: false });

    $('[fxLayout], [fxLayoutGap], [fxLayoutAlign]').each((_, element) => {
        const $element = $(element);

        const fxLayout = $element.attr('fxLayout');
        const fxLayoutGap = $element.attr('fxLayoutGap');
        const fxLayoutAlign = $element.attr('fxLayoutAlign');

        if (fxLayout) {
            convertFxLayoutToTailwind($element, fxLayout);
        }

        if (fxLayoutGap) {
            convertFxLayoutGapToTailwind($element, fxLayout, fxLayoutGap);
        }

        if (fxLayoutAlign) {
            const [mainAxis, crossAxis] = fxLayoutAlign.split(' ');

            if (mainAxis !== 'start' && crossAxis !== 'start') {
                $element
                    .addClass(`${mainAxisMap[mainAxis] || ''} ${crossAxisMap[crossAxis] || ''}`)
                    .removeAttr('fxLayoutAlign');
            } else if (mainAxis !== 'start') {
                $element
                    .addClass(`${mainAxisMap[mainAxis] || ''}`)
                    .removeAttr('fxLayoutAlign');
            } else {
                $element
                    .addClass(crossAxisMap[crossAxis] || '')
                    .removeAttr('fxLayoutAlign');
            }
        }
    });

    $('[fxFlex]').each((_, elem) => {
        let fxFlex = $(elem).attr('fxFlex');

        if (!fxFlex) {
            $(elem)
                .addClass(`flex-1`)
                .removeAttr('fxFlex');
            return;
        }

        let widthClass = '';
        switch (+fxFlex) {
            case 33: widthClass = '1/3'; break;
            case 66: widthClass = '2/3'; break;
            case 100: widthClass = 'full'; break;
            default: widthClass = percentageToFraction(+fxFlex); break;
        }

        $(elem)
            .addClass(`basis-${widthClass}`)
            .removeAttr('fxFlex');
    });

    $('[fxFill]').each((_, elem) => {
        $(elem)
            .addClass(`h-full w-full min-h-full min-w-full`)
            .removeAttr('fxFill');
    });

    let newTag = $.html();
    newTag = newTag.replace(/(\W\w+)=""/gm, '$1');

    if (newTag.endsWith('/>') && tag.endsWith('/>')) {
        return newTag;
    } else {
        return newTag.slice(0, -2) + '>';
    }
}

function convertFxLayoutToTailwind($element, fxLayout) {
    let [layout, other] = (fxLayout || 'column').split(' ');

    let className = '';
    switch(layout) {
        case 'row': className = 'flex-row'; break;
        case 'column': className = 'flex-col'; break;
        case 'row-reverse': className = 'flex-row-reverse'; break;
        case 'column-reverse': className = 'flex-col-reverse'; break;
        default: return;
    }
    
    $element.addClass(`flex ${className}`);

    if (other === 'wrap') {
        $element.addClass('flex-wrap');
    }

    if (other === 'inline') {
        $element.removeClass('flex');
        $element.addClass('inline-flex');
    }

    $element.removeAttr('fxLayout');
};

function convertFxLayoutGapToTailwind($element, fxLayout, fxLayoutGap) {
    let [layout] = (fxLayout || 'column').split(' ');

    if (fxLayoutGap === undefined) return;

    const spacing = Math.ceil(parseFloat(fxLayoutGap) * 4); // convert from em

    if (layout === 'row') {
        $element.addClass(`space-x-${spacing}`);
    } else {
        $element.addClass(`space-y-${spacing}`);
    }

    $element.removeAttr('fxLayoutGap');
};

function gcd(a, b) {
    if (!b) {
        return a;
    }
    return gcd(b, a % b);
}

function percentageToFraction(percentage) {
    const denominator = 100;
    const numerator = percentage;
    const gcdValue = gcd(numerator, denominator);
    const simplifiedNumerator = numerator / gcdValue;
    const simplifiedDenominator = denominator / gcdValue;
    return `${simplifiedNumerator}/${simplifiedDenominator}`;
}

function extractHtmlTags(html) {
    let openingTags = [];
    let tag = "";
    let inTag = false;
    let quote = null;

    for (const ch of [...html]) {
        if (!inTag && ch === "<") {
            inTag = true;
            tag += ch;
        } else if (inTag) {
            tag += ch;

            if (quote === null && (ch === "\"" || ch === "'")) {
                quote = ch;
            } else if (quote !== null && ch === quote) {
                quote = null;
            } else if (quote === null && ch === ">") {
                openingTags.push(tag);
                tag = "";
                inTag = false;
            }
        }
    }

    return openingTags;
}

function convertFile(filePath) {
    const convertedData = convertFlexLayoutToTailwind(filePath);
    fs.writeFileSync(filePath, convertedData, 'utf-8');
    console.log(`File converted successfully: ${filePath}`);
};

function processFiles(
    folderPath,
    processFile,
    processFolder,
    level = 0
) {
    if (fs.existsSync(folderPath)) {
        fs.readdirSync(folderPath).forEach(file => {
            const currentPath = path.join(folderPath, file);
            if (fs.lstatSync(currentPath).isDirectory()) {

                if (currentPath.endsWith('node_modules') || currentPath.endsWith('dist')) {
                    return;
                }

                if (processFiles(currentPath, processFile, processFolder, level + 1)) {
                    processFolder?.(currentPath);
                }
            } else {
                if (currentPath.endsWith('.html')) {
                    processFile(currentPath, level);
                }
            }
        });
        return true;
    } else {
        return false;
    }
}

processFiles('[Enter path to angular application here]', convertFile);

from flex-layout.

Interscope19 avatar Interscope19 commented on May 23, 2024 5

I know that the angular team have their thoughts about the web standar but this library offers more than just alternative for css , it makes the flex and grid hell( joke) more easy to implement and it provides some directives for breakpoints i mean, its a bit agressive to declare a library -that is commonly used for a bunch of teams in their productions projects- as deprecated, i think that we can keep those directives and other stuff that the library offers ( breakpoints and declarative simplicity on flex grid) and incorporate as default in the framework, that can give angular more unique identity instead to make it more like react.

from flex-layout.

philmtd avatar philmtd commented on May 23, 2024 5

Just in case anyone is interested and reads this: I've created a library inspired by this one a few years ago and just updated it a little. It does not replicate everything Flex Layout is capable of, but I think the most popular features are available and it might be a good alternative for at least smaller projects: https://github.com/philmtd/css-fx-layout

from flex-layout.

BryanYin avatar BryanYin commented on May 23, 2024 4

By reading Angular blog, I found this issue. We have been using this lib for years and it works really good, thank you for your efforts to support it for such a long time! But it's really sad this lib is going to the end of its lifecycle. We are heavily using below directives with different breakpoints:
fxFlex
fxLayout
fxLayoutAlign
fxLayoutGap

I agree with @coreConvention's comments above, please consider hand over this project to the community.

from flex-layout.

stevebor1 avatar stevebor1 commented on May 23, 2024 4

I recently converted our large government focused app from angular/bootstrap to angular/material/flex-layout, as we made the decision to stick with core technologies and offerings as they would be more stable. 😔......

We heavily use the standard fxLayout/fxFlex as well as all breakpoints to simplify and standardize development across a responsive application. We've been waiting on 'density' to be finally supported in components, and now that it is in 15, we were ready to upgrade. Now this.

from flex-layout.

CaerusKaru avatar CaerusKaru commented on May 23, 2024 4

@azimuthdeveloper I empathize with a lot of your points. The reality, though, is that a) we did consult the community; and b) Google is unfortunately not transactional. What do I mean by this: we asked some well-established actors in the community to take over the project; they declined. I've mentioned earlier in this issue that if another community member wanted to take on this project, they are welcome to do so, but the namespace cannot be reused. Which brings us to the second point, which is that unfortunately no amount of money (short of paying a full Google employee salary) will fund this to stay in the same namespace, because at the end of the day, Google would be responsible, and that's something the team cannot afford. I believe we all like to think sometimes that Google does these things out of spite, or that they make the wrong investments/decisions on products we really like, but at the end of the day, we aren't the ones looking at the balance sheets and paying for developer time.

In our last release, which will fully support v15, we will unpin our peer dependencies, meaning that ng update should not be blocked in the future. This does not mean every future version will work with the last published version of this library, namely if there are APF or other breaking changes, but in the best case it should maintain compatibility otherwise. We hope to get this version out this coming week.

I understand your frustration, and those of the other users here, but I would like to remind everyone the primary goal of this issue is to track meaningful and impactful migration guides that would ease this transition. I am fully committed to authoring those guides depending on feedback, but the complexity of the library is such that it's really hard to understand where the priority is without it. For instance, and this was written about above, it would be trivial to migrate some of the simpler directive-based usage, but really complex to migrate inter-connected directive usage, print, etc. If there is no demand for that, though, we can focus on really nice simple utilities for migration.

As @michaelfaith mentioned, my Medium post was a "how we got here" kind of post, to explain the situation to users otherwise caught unawares of the "why". I understand you would like more information about how to transition, which is 100% why this issue exists. And as Michael otherwise mentioned, there is another article with a brief explainer of alternatives generally available in the meantime.

from flex-layout.

chris-wahl avatar chris-wahl commented on May 23, 2024 4

If anyone else is like me and have a big (150k+ LOC) app that makes extensive use of this package, here's what I'm doing to help migrate into @media queries from things like fxLayout.gt-xs, etc. Definitely not claiming it's the right solution, but hopefully it helps someone else.

This is a simple-and-much-to-be-desired drop in, but it's quick enough if you need to pull out a couple thousand flex-layout directives that deal with breakpoints.


  1. Move your global styles.scss into a subdirectory (i.e. move the file to src/styles/styles.scss). I did this a while back to organize my variables, themes, etc, into a number of different scss files, so if you've also done it, just skip to step 2.

Will need to update angular.json to look in this folder, rather than just at the global file by updating the styles and stylePreoprocessorOptions property under your build settings.

    "build": {
        ....
        "styles": [ "src/styles/styles.scss" },
        "stylePreprocessorOptions": {
              "includePaths": [
                "src/styles"
              ]
        }
        ....
    }

  1. In this styles/ directory, add a breakpoints.scss with the following content:
$xs: 599px;
$sm: 969px;
$md: 1279px;
$lg: 1919px;
$xl: 5000px;

$fx-media-queries: (
  'xs': 	"screen and (max-width: #{$xs})",
  'sm': 	"screen and (min-width: #{$xs + 1}) and (max-width: #{$sm})",
  "md": 	"screen and (min-width: #{$sm + 1}) and (max-width: #{$md})",
  "lg": 	'screen and (min-width: #{$md + 1}) and (max-width: #{$lg})',
  "xl": 	'screen and (min-width: #{$lg + 1}) and (max-width: #{$xl})',

  "lt-sm": 	'screen and (max-width: #{$xs})',
  "lt-md": 	'screen and (max-width: #{$sm})',
  "lt-lg": 	'screen and (max-width: #{$md})',
  "lt-xl": 	'screen and (max-width: #{$lg})',

  "gt-xs": 	'screen and (min-width: #{$xs + 1})',
  "gt-sm": 	'screen and (min-width: #{$sm + 1})',
  "gt-md": 	'screen and (min-width: #{$md + 1})',
  "gt-lg": 	'screen and (min-width: #{$lg + 1})',
);

This just stores all the flex-layout breakpoints into a simple map, using the same language ('xs', 'gt-sm', etc.). In the next step, we can grab the query by using map-get with whatever breakpoint descriptor.


  1. Apply where necessary. For example, if I was using <div fxLayout="row" fxLayout.lt-md="column">...</div> for some component, in that component's local scss file, I'd create a class with:
@import "breakpoints";

.container {
    display: flex;
    flex-direction: row;

    @media #{map-get($fx-media-queries, 'lt-md')} {
        flex-direction: column;
    }
}

and replace the directives with <div class="container">...</div>

Of course, add in your place-content and align-items changes in there as necessary.

I'm absolutely certain this could be wrapped into an even easier @mixin call but I've already used this much in a dozen places and I'm not really in the mood to re-write it. But you can! And should!


Edit: Here's a shortcut @mixin that can be slapped into breakpoints.scss:

@mixin breakpoint($bp) {
  @media #{map-get($fx-media-queries, $bp)} {
      @content;
  }
}

and now Sass will compile

.test {
    display: flex;
    flex-direction: row;
    @include breakpoint('lt-md') {
        flex-direction: column;
    };
}

into

.test {
  display: flex;
  flex-direction: row;
}
@media screen and (max-width: 969px) {
  .test {
    flex-direction: column;
  }
}

from flex-layout.

Anthony-Wratpor avatar Anthony-Wratpor commented on May 23, 2024 4

Hello i have done a different approach where I replaced the fxlayouts and fxLayoutAlign with CSS Classes and replaced all of the occurences in my code.

I have made a corresponding table to replicate this on other applications and it looks something like this :

Before After
fxLayout="column" class="flex-col"
fxLayout="column" fxLayoutAlign="space-evenly stretch" class="flex-col space-evenly stretch"
fxLayout="column" fxLayoutAlign="space-evenly center" class="flex-col space-evenly align-center"
fxLayout="column" fxLayoutAlign="center space-evenly" class="flex-col space-evenly justify-center"
fxLayout="column" fxLayoutAlign="center stretch" class="flex-col stretch justify-center"
fxLayout="column" fxLayoutAlign="center center" class="flex-col justify-center align-center"
fxLayout="column" fxLayoutAlign="space-around center" class="flex-col space-around align-center"
fxLayout="column" fxLayoutAlign="space-between center" class="flex-col space-between align-center"
fxLayout="column" fxLayoutAlign="start stretch" class="flex-col start stretch"
fxLayout="column" fxLayoutAlign="start start" class="flex-col start flex-start"
   
fxLayout="row" class="flex-row"
fxLayout="row" fxLayoutAlign="space-evenly center" class="flex-row space-evenly align-center"
fxLayout="row" fxLayoutAlign="space-evenly stretch" class="flex-row space-evenly align-stretch"
fxlayout="row" fxLayoutAlign="center center" class="flex-row justify-center align-center"
fxLayout="row" fxLayoutAlign="center stretch" class="flex-row align-center align-stretch"
fxLayout="row" fxLayoutAlign="start center" class="flex-row start align-center"
fxLayout="row" fxLayoutAlign="end center" class="flex-row end align-center"
fxLayout="row" fxLayoutAlign="space-between center" class="flex-row space-between align-center"
fxLayout="row wrap" fxLayoutAlign="space-evenly center" class="flex-row flex-wrap space-evenly align-center"
fxLayout="row wrap" fxLayoutAlign="start start" class="flex-row flex-wrap start flex-start"
With theses css classes

// Flex row/col + grid.
.flex-row {
    display: flex;
    flex-direction: row;
}

.flex-col {
    display: flex;
    flex-direction: column;
}

.grid {
    display: grid;
}

.grid {
    display: grid;
}

.flex-wrap {
    flex-wrap: wrap;
}

.flex-col-xs {
    @media screen and (max-width: 599px) {
        flex-direction: column;
    }
}

.flex-col-sm {
    @media screen and (min-width: 959px) {
        flex-direction: column;
    }
}

.flex-row-xs {
    @media screen and (max-width: 599px) {
        flex-direction: row;
    }
}

.flex-row-sm {
    @media screen and (min-width: 959px) {
        flex-direction: row;
    }
}

.gap-5 {
    gap: 5px;
}

.gap-10 {
    gap: 10px;
}

.gap-15 {
    gap: 15px;
}

.gap-14 {
    gap: 14px;
}

.gap-20 {
    gap: 20px;
}

.flex-auto {
    flex: 1 1 auto;
}

.space-between {
    justify-content: space-between;
}

.space-around {
    justify-content: space-around;
}

.space-evenly {
    justify-content: space-evenly;
}

.stretch {
    justify-content: stretch;
}

.align-stretch {
    align-content: stretch
}

.start {
    justify-content: start;
}

.content-start {
    align-content: flex-start;
}

.flex-start {
    align-items: flex-start;
}

.end {
    justify-content: end;
}

.flex-end {
    align-items: flex-end;
}

.justify-center {
    justify-content: center;
}

.align-center {
    align-items: center;
}

.align-baseline {
    align-items: baseline;
}

.flex {
    display: flex !important;
}

.flex-1 {
    flex: 1
}

.flex-grow {
    flex-grow: 1;
}

.center {
    display: block;
    margin-left: auto;
    margin-right: auto;
}

As you can see I also added gap classes but i added them manually after the big replace.

I don't think it's perfect in any way, feel free to post your own spin on it, but it kinda works for me so I might as well share it.

I think it's a huge mistake from the angular team to drop this when it's used that much, when there's no 1 to 1 replacement and knowing that it'll break many many applications..

from flex-layout.

Cylop avatar Cylop commented on May 23, 2024 4

Hi everyone! 👋

As we all know, this issue is a concern for many developers who rely on it. In response to this, I've started an open-source project with the goal of helping everyone migrate from the deprecated attributes to their modern alternatives.

🔗 Here's the link to the project: https://github.com/NIPE-Solutions/flex-layout-migrator

Currently, the basic structure is in place, but we're still working on implementing the actual mechanisms to replace the old attributes. Any help, feedback, or suggestions are more than welcome, as this is a community-driven project and we want to make it as useful as possible for everyone.

If you're interested in contributing or have any questions, please don't hesitate to join the project or reach out to me. Together, we can make this migration process smoother and more efficient for everyone involved. Thank you! 😊

from flex-layout.

michaelfaith avatar michaelfaith commented on May 23, 2024 3

@anisabboud this is great. Thanks. Just a note though, ngStyle and ngClass are not part of flex-layout, and won't be affected by its retirement. They're part of angular core.

from flex-layout.

anisabboud avatar anisabboud commented on May 23, 2024 3

Indeed, I was referring to ngStyle.xs & ngClass.xs, etc. (with breakpoints).
But it's an important clarification to make to avoid confusing others, so I updated my post, thanks @michaelfaith!

from flex-layout.

geo242 avatar geo242 commented on May 23, 2024 3

I have to say this is an utter failure and I will take responsibility. I have been very careful to not use packages outside of the default core lib rather be it be python and esp angular. I am now even more risk-averse with using third-party apps to the point of never again. The depreciation of the lib and the amount of refactoring I have to do now ranks as the number one fail of package choice over 20 years of development and the margins are not even close. I was fooled and again my fault because I remember thinking there was a strong synergy with the and the app ... almost like angular approved. I was wrong.

I am the same way and now it looks like I really can't trust any package maintainer, even if it's backed by one of the largest corporations on the planet. Does this kind of thing happen with Vue, React, etc.? I am honestly asking since I don't have as much experience with those libraries and communities. I would hope not. And if not, that tells me it's a symptom (as mentioned above) of the Google culture of blowing up widely used products on the regular. I just didn't expect that culture to seep into Angular, but maybe that's me being naive. As many others have stated, this ruins my trust in Angular as a whole and I will start thinking about considering moving to other frameworks in the future.

It would be interested to see if it's possible to somehow quantify the monetary impact this is going to have on the community and companies that will now have to pay developers to do a ton of refactoring (myself and the company I work for included). I would guess we are talking multiple millions of dollars, but I wouldn't know where to start in coming up with that number. I would also guess that many of the companies affected are either one man operations or small businesses that don't have a huge budget and can't easily absorb things like this. But I have to wonder if anyone that was part of this decision even considered that.

from flex-layout.

PeterNSkovgaard avatar PeterNSkovgaard commented on May 23, 2024 3

@DuncanFaulkner if you manage to keep this library up to speed with angular versions you are an absolute champ. As a very small startup we are using it widely and do not have the resources for the migration options suggested by the Angular team, so this would be a lifesaver.

Unfortunately we do not have the economy to fund it at the moment, but you will definitely have our appreciation! Hope it works out.

from flex-layout.

maxfriedmann avatar maxfriedmann commented on May 23, 2024 3

@wassim-k Many thanks for your code, I added another finding from myself (fxFlex=* appeared in our code ???), added another fix from @chrispharmac (spacing px should be divided by 4) and published it as https://www.npmjs.com/package/migrate-angular-flex-to-tailwind I hope thats fine with you.

We actually managed to get 100% migrated with your code so I thought it might worth it to publish it.

from flex-layout.

blogcraft avatar blogcraft commented on May 23, 2024 3

@wassim-k Many thanks for your code, I added another finding from myself (fxFlex=* appeared in our code ???), added another fix from @chrispharmac (spacing px should be divided by 4) and published it as https://www.npmjs.com/package/migrate-angular-flex-to-tailwind I hope thats fine with you.

We actually managed to get 100% migrated with your code so I thought it might worth it to publish it.

There where alot of attributes it does not convert, some examples:
fxFlexFill
fxFlex.lt-md="0 0 calc(50% - 10px)"
fxLayout.sm="row wrap"

Somehow it translated this:
fxLayout.sm="row wrap" fxLayout.xs="column" fxFlex="50%"
Into this:
fxLayout.sm="row wrap" fxLayout.xs="column" class="basis-NaN/1"

and this:
class="flex flex-row flex-wrap space-x-3 justify-between items-center basis-NaN/1"
into this:
fxLayout="row wrap" fxLayoutGap="10px" fxFlex="50%" fxLayoutAlign="space-between center"

from flex-layout.

Cylop avatar Cylop commented on May 23, 2024 3

Hello Everyone,

Just a brief reminder for those looking for migration solutions: I've created an open-source tool to help migrate from ngFlex to TailwindCSS. It's not perfect, but it might make the process a bit easier for some!

Flex Layout Migrator

Please don't hesitate to check it out, and any feedback is welcome!

Best,
Nicholas

from flex-layout.

ianvink avatar ianvink commented on May 23, 2024 2

We have a huge app with about 900 directives from this project. Mostly these directives:

  • fxLayout
  • fxLayoutGap
  • fxLayoutAlign
  • fxFlex
  • fxFlexFill
  • fxHide
  • fxShow
    We also have use of many break points like fxFlex.md etc

from flex-layout.

ginxdroid avatar ginxdroid commented on May 23, 2024 2

Maybe consider taking votes from community before halting this project.
There are many production applications which are using this great library in their templates for building layouts.

from flex-layout.

ianvink avatar ianvink commented on May 23, 2024 2

Does anyone have a small set of Directives which will do the very basics, like the ones below. I feel that if there was it would solve the majority of uses and provide tremendous value to the community.

fxLayout
fxLayoutGap
fxLayoutAlign
fxFlex
fxFlexFill
fxHide
fxShow

from flex-layout.

davidmontgom avatar davidmontgom commented on May 23, 2024 2

I have to say this is an utter failure and I will take responsibility. I have been very careful to not use packages outside of the default core lib rather be it be python and esp angular. I am now even more risk-averse with using third-party apps to the point of never again. The depreciation of the lib and the amount of refactoring I have to do now ranks as the number one fail of package choice over 20 years of development and the margins are not even close. I was fooled and again my fault because I remember thinking there was a strong synergy with the and the app ... almost like angular approved. I was wrong.

from flex-layout.

aureldussauge avatar aureldussauge commented on May 23, 2024 2

If you choose to migrate to Tailwind CSS, I recommend using important: true in your tailwind.config.js. This property will add !important to every Tailwind style.

This must seem like bad practice to you. However, don't forget that flex-layout adds inline styles, which isn't really any different, since it also prevents to play with CSS specificity.

Also, it is recommended that utility classes, such as those added by tailwind, have a higher CSS importance than component classes.

For a migration in a large application with thousands flex-layout directives, you may have regressions if you don't work like that. For example, if you had a fxLayout="column" on a <mat-card>, it won't work to use class="flex flex-col" because .mat-card has a display: block that has greater specificity than the Tailwind classes.

If you're thinking of using Tailwind's @layer, keep in mind that it only performs a code reorganization and does not prevent a more specific selector from overriding Tailwind styles.

Also, native CSS @layer won't be able to save you either because there is no Angular way to scope styles from libraries into a @layer.

And finally, Adam Wathan, the creator of Tailwind, confirmed that this is a good practice and that Bootstrap works the same way.

You can also use the selector strategy instead by adding important: 'your selector', but it still won't prevent to have a more specific selector.

from flex-layout.

geo242 avatar geo242 commented on May 23, 2024 2

@DuncanFaulkner Bravo! I really hope you can take this on!

Here are some opinions regarding the points you mentioned...

  1. I would think that matching the Angular release schedule would be a good goal
  2. I would like to see the library either be trimmed down to the most used features or split into multiple projects or at least namespaces for well defined feature separations (e.g. grid vs flexbox). But this is not something I feel strongly about, nor should it be forced if it's going to cause a lot of disruption for the current user base.

I don't have much else to add to the other points as I was pretty happy with the cadence of the existing package regarding bugs/security etc.

I am happy to help contribute to the project as well. I have a vested interest in keeping it alive as I have many large projects that depend on it.

from flex-layout.

jpike88 avatar jpike88 commented on May 23, 2024 2

I attempted to migrate to pure css. It is a major, major PITA, and it reminded me why I use flex-layout in the first place! So I am much more happy to stick with a spinoff of flex-layout., and will happily contribute if needed.

from flex-layout.

pashvin avatar pashvin commented on May 23, 2024 2

Here is one full replacement for the angular flex library - https://www.npmjs.com/package/ngx-flexible-layout. Has the same directive names so no change in any HTML file. Just replace package imports and it should work.

from flex-layout.

thoxx avatar thoxx commented on May 23, 2024 2

If someone uses Flex-Layout primarily for layouting with columns and rows, it may be possible to migrate with CSS Grid and an Angular directive with moderate effort:

Angular Flex-Layout example:

<div fxLayout="row">
    <div fxFlex="40%">[...]</div>
    <div fxFlex="15%">[...]</div>
    <div fxFlex="45%">[...]</div>
</div>

Angular Directive:

import { Directive, HostBinding, Input } from '@angular/core';

@Directive({
  selector: '[grid]'
})
export class GridDirective {

  @HostBinding('style.display') display = 'grid';

  @Input() columns: string | null = null;
  @Input() rows: string | null = null;

  @HostBinding('style.grid-template-columns')
  get gridTemplateColumns(): string | null {
    return this.columns ? this.columns : null;
  }

  @HostBinding('style.grid-template-rows')
  get gridTemplateRows(): string | null {
    return this.rows ? this.rows : null;
  }
}

Replacement of example with Grid:

<div grid columns="40% 15% 45%">
    <div>[...]</div>
    <div>[...]</div>
    <div>[...]</div>
</div>

The directive can then be easily extended for other cases.

from flex-layout.

DuncanFaulkner avatar DuncanFaulkner commented on May 23, 2024 2

I've now setup a clone of the Angular Flex-Layout library- this is still very much at the early stages but I've got the GitHub repo set up along with the Circle CI and a package on NPM.

The new home is now at

@ngbracket/ngx-layout.

I've pushed up a pre-release version 15.0.1-beta.42, this version is just an initial release just to make sure things are working, the only thing that got changed was the name which has been changed from https://github.com/angular/flex-layout to https://github.com/ngbracket/ngx-layout, some of the readme's, and documentation still need to be updated to reflect this change which I'm hoping to complete shortly.

Please do check it out I welcome all feedback

from flex-layout.

wassim-k avatar wassim-k commented on May 23, 2024 2

@maxfriedmann glad you found it useful and more than happy for it to be published, the more people it reaches the better.

from flex-layout.

ayan-bloomscorp avatar ayan-bloomscorp commented on May 23, 2024 2

Hello,

I've developed a CLI designed to simplify the migration process from flex-layout to tailwindcss. The primary goal of this CLI is to automate the entire process, minimizing the need for manual intervention. Ideally, you should not have to make any additional changes once the CLI completes its tasks.

Here's what the CLI does for you:

  • It automatically installs tailwindcss.
  • Removes the old flex-layout dependency.
  • Converts all directives into tailwindcss classes.

Since it's a CLI tool, you can install it globally and smoothly execute it across multiple projects.

My objective with this CLI is to offer a comprehensive 1-to-1 migration solution. Some existing solutions in the discussion thread do not adequately handle some specific cases, which I have taken care to address.

Please note that this project is still a work in progress. While you can already use the tool, it's currently in a release candidate state. At present, all flex directives are supported, and my next target is to cover grid directives.

no one mentened about a attribute like the following [fxLayoutAlign]="(settings.menuType=='default') ? 'start center' : 'center center'", any idea on converting the above attribute into Tailwind?

Unfortunately, this part may require manual adjustment for now. I'll continue working on finding a solution, but I cannot guarantee a quick resolution to this particular issue. Same story for custom breakpoints.

Feel free to open issues if you notice any problem, any contribution is also welcomed.

Link: https://github.com/synopss/flex-layout-to-tailwind

@synopss I have raised couple of issues/PR for your migration. Among the ones I know it is working best out of them, but it lacks in some specific use cases. I will be happy to contribute to it. Let me know if you have enough time to maintain the codebase.

from flex-layout.

Interscope19 avatar Interscope19 commented on May 23, 2024 1

@anisabboud this is great. Thanks. Just a note though, ngStyle and ngClass are not part of flex-layout, and won't be affected by its retirement. They're part of angular core.

i think that he talk about de .sm .xs after the ngStyle or ngClass

from flex-layout.

ginxdroid avatar ginxdroid commented on May 23, 2024 1

I experienced follwing problems while migrating to other libraries:

  1. Migrating to Bootstrap grid = bloated class attribute
  2. Migrating to Tailwind css = same, bloated class attribute
  3. Writing your own classes = difficult to maintain when application grows larger and difficult to understand 'quickly' for other devs who are working on the same project.

Main speciality of this library:
We can use directives instead of classes which will make class attribute less bloated.

I will not prefer writing different attribute values in the same attribute in template because it is not an easy thing to understand especially when building responsive user interface as class attribute grows larger and larger........
e.g.
class="col-xs-12 col-sm-8 col-md-6 col-lg-4 <other -class-1> <other -class-2> <other -class-3>"

Bloating bloating and bloating.....

Now consider this:
class="<other -class-1> <other -class-2> <other -class-3>" fxFlex.xs="100%" fxFlex.sm="80%" fxFlex.md="50%" fxFlex="33%

which bloats class attribute less than the above example.

This is what I liked about this library. When there is complex layout ui then those separate directives makes code easy to understand and fix.

That is if there is something wrong in mobile device layout then we only need to focus and fix fxFlex.xs directive and not others.

from flex-layout.

aceArt-GmbH avatar aceArt-GmbH commented on May 23, 2024 1

[fxFlex] {
flex: 1 1 auto;
}

@cubidobusinesssolutions I had a similar idea.
But adding fxFlex does add style properties to the parent element as well and not just the element itself.

<div>
    <div>
        test 1
        <div fxFlex>test 2</div>
    </div>
</div>

<style>
[fxFlex2] {
  flex: 1 1 auto;
}
</style>
<div>
    <div>
        test 3
        <div fxFlex2>test 4</div>
    </div>
</div>

is not the same thing. Or am I wrong here?
Using the new :has() selector should work however

from flex-layout.

aureldussauge avatar aureldussauge commented on May 23, 2024 1

For basic usage, plain CSS will do (typos included and not exhaustive)

[fxLayout] {
  display: flex;
  box-sizing: border-box;
}
...

Thank you for this answer. Also, don't forget that fxFlex is able to add display: flex on a parent that doesn't have an fxLayout directive. fxLayoutAlign can also add display: flex on its host element even without fxLayout.
This should be taken into account for your migration, depending on how you were using flex-layout.

from flex-layout.

michaelfaith avatar michaelfaith commented on May 23, 2024 1

@DuncanFaulkner really appreciate the leadership on this!
With regard to what direction the project should take, it seems like we've gotten a lot of good information in this thread about what aspects of the library people are using most. That could help guide decisions about what to prioritize and/or descope entirely. And from a branding perspective, there was this old issue discussing a possible renaming of the library to reflect that it includes both flex and grid (so possibly just naming it /layout)

from flex-layout.

sourav-bhar avatar sourav-bhar commented on May 23, 2024 1

@DuncanFaulkner, I really appreciate your initiative and volunteering to keep this alive. 👏👏

As you have seen from the many dozens of posts, this is a core technology finely integrated into the fabric of thousands of production apps, with no easy migration path that works out of the box. Moreover, this really works, and works well for all those teams ( including ours), so makes little sense to migrate off of it.

The two main requirements, from our end, for this project would be:

  • Match the release schedule of Angular (say Angular release + 1-4 weeks, based on capacity)
  • Stability of existing features over adding new ones, or deprecating less used ones

I'll not be able to contribute towards maintaining it, but I will definitely consider sponsoring it, if that helps. I hope that you, potentially along with few others, can keep this alive. 🤞

from flex-layout.

coreConvention avatar coreConvention commented on May 23, 2024 1

We use it in an extremely complex json-schema/ui-schema/formly reactive forms configuration based questionnaire-like form generator because it allows me to individually define things in a single ui-schema. For example:

Json-Schema

{  
  type: "object",
  properties: {
    someproperty: {
      type: "string"
    }
  }   
}

Ui-schema:

 {
   scope: "#",
   formlyConfig: {
     templateOptions: {
       fxLayout: "row wrap
     }     
   }
 }
 {
   scope: "#/properties/someproperty",
   formlyConfig: {
     templateOptions: {
       fxFlex: 50,
       fxLayoutAlign="end center"
     }     
   }
 }

I removed a lot of stuff for the example but you can hopefully see the correlation, I think. Alot of the above stuff is programatically generated from configuration in a mongo database, using a very complex json merging scheme.

Which then applies the necessary css to both the element generated by formly as well as the wrappers formly generates by adding the directives in the formly custom field types:

<div
  [fxLayout]="to.fxLayout ?? 'row wrap'"
  [fxLayoutAlign]="to.fxLayoutAlign ?? ''"
  [fxLayoutGap]="to.fxLayoutGap ?? '1rem grid'"
>
  <ng-container *ngFor="let f of field.fieldGroup; trackBy: trackById">
    <formly-field [fxFlex]="getFlex(f)" [field]="f"></formly-field>
  </ng-container>
</div>

Without this it would be almost impossible because some of the wrappers/parent elements formly generates can't be affected directly without parsing and validating existing classes applied to the elements. And doing some fancy pseduo class css magic that defeats the purpose of being able to apply it with just the json.

This is a bit of an oversimplification but without flex-layout this is going to be EXTREMELY difficult. Not all of the customizations can just be applied via css classes, as both formly and flex-layout use both the class and style attributes on the fly to do their magic and deal with the outer and inner elements where they are applied. Applying the flex css itself wouldn't be super difficult, its what the directives themselves do that makes this work, not just the css.

@DuncanFaulkner I would likely be willing to chip in on maintenance as well. As you can see from the above explanation I have a vested interest in seeing this project continue. I will end up having to write my own directives otherwise, which I will do if I have to, but this is such a great package I would rather continue using it lol!

from flex-layout.

jpike88 avatar jpike88 commented on May 23, 2024 1

The angular team has a whole trail of drama and short-sighted decisions behind it, we can all agree. But we need to pay out respects @CaerusKaru for making this possible. It's a stroke of genius this library, I have worked on a range of OSS bundlers and linters, this is like having teeth, you don't know how important they are until they're removed.

And at the same time, despite the pain and time wasted we may be feeling from this, we need to pay our respects to the efforts that have made Angular what it is, because without it, this library wouldn't exist. We stand on the shoulders of giants.

I'll happily tear into the decision to keep this library beta and finally kill it (which I still maintain as a silly silly thing to do), but we have to accept that it is their decision to make.

Let's make lemonade out of lemons, and entertain two clear possible pathways:

  • a pure CSS move away from flex-layout
  • keeping the library alive and moving forward

Anything else is a waste of our collective time.

from flex-layout.

michaelfaith avatar michaelfaith commented on May 23, 2024 1

Hi guys, it seems all the concern is about the migration after the deprecation. But for the new projects it is not easy to decide what to use as CSS library along with Angular + Angular Components. The best solution seems to be using pure css but it is much more work. Do you have any idea, recommedations etc.?

Tailwind CSS has some very similar capabilities and has been supported by Angular for a couple versions now. That would be my personal recommendation for a brand new app.

from flex-layout.

afnecors avatar afnecors commented on May 23, 2024 1

With primer/css you can import flexbox utilities (and dependencies) in your style.scss:

@import "@primer/css/support/mixins/layout.scss";
@import "@primer/css/support/variables/layout.scss";
@import "@primer/css/utilities/visibility-display.scss";
@import "@primer/css/utilities/flexbox.scss";

So, you can migrate from

<div fxLayout="row" fxLayoutAlign="space-between center">
  <div>1</div>
  <div>2</div>
</div>

To

<div class="d-flex flex-row flex-justify-between flex-content-center">
  <div>1</div>
  <div>2</div>
</div>

For more info, see https://primer.style/css/utilities/flexbox

from flex-layout.

chrispharmac avatar chrispharmac commented on May 23, 2024 1

@wassim-k Thanks much for this! I hacked on it a bit more, and as it did for you, it took care of around 90% of the job. I couldn't figure out how to do the media queries, perhaps someone can. But our project only used them in a few places, so it was quite easy to change those by hand.

index.js.txt

from flex-layout.

jeffschulzusc avatar jeffschulzusc commented on May 23, 2024 1

For our current monorepo, replacing FlexLayout with ex. TailwindCSS would not be practical.
We will try and support https://github.com/ngbracket/ngx-layout

Statistics (instances/files):

fxFlex ... 3395 / 523
fxLayout ... 6214 / 649
fxLayoutGap ... 614 / 287
fxLayoutAlign ... 2570 / 629
fxFlexAlign ... 110 / 88
fxFill ... 138 / 55
fxHide,fxShow ... 199 / 52
.xs,...,gt-lg ... 1315 / 535
ngClass.* ... 481 / 207
ngStyle.* ... 20 / 14

@Component 808 / 806
@Injectable 173 / 155

Going forward with new components we will just use css flex-grid ... but so that we can keep the
styling/layout in the html template, here are some rudimentary mixins that i cooked up (with help from other's posts):

@mixin m_vxFlex($dir, $axa, $axb) {
  display: flex;
  flex-direction: $dir;
  flex-wrap: nowrap;
  align-content: normal;
  justify-content: $axa;
  align-items: $axb;
}

[vxFlex~='csc'] { // fxLayout="column" fxLayoutAlign="start center"
  @include m_vxFlex(row, flex-start, flex-start);
}
... each permutation


@mixin m_vxFlexXS($dir, $axa, $axb) {
  @media (max-width: $XS) {
    display: flex !important;
    flex-direction: $dir !important;
    flex-wrap: nowrap !important;
    align-content: normal !important;
    justify-content: $axa !important;
    align-items: $axb !important;
  }
}

[vxFlexXS~='rss'] { // fxLayout="row" fxLayoutAlign="start start"
  @include m_vxFlexXS(row, flex-start, flex-start);
}
... each permutation 

[vxHideXS] { // fxHide / fxShow
  @media (max-width: $XS) {
    display: none !important;
  }
}

example:
<div vxFlex="rsc" vxHideXS> ...

And some basic directives:

@Directive({
  selector: '[vxHGap]', // fxFlex="n"
  standalone: true,
})
export class VXHGapDirective implements OnInit {
  @Input('vxHGap') gap: string | undefined;

  constructor(private readonly elementref: ElementRef<HTMLElement>) {}

  ngOnInit(): void {
    this.elementref.nativeElement.style.width = this.gap ?? '';
  }
}

@Directive({
  selector: '[vxGrow]', // fxFlex="auto"
  standalone: true,
})
export class VXGrowDirective implements OnInit {
  @Input('vxGrow') grow: string | undefined;

  constructor(private readonly elementref: ElementRef<HTMLElement>) {}

  ngOnInit(): void {
    this.elementref.nativeElement.style.flexGrow = this.grow ?? '';
  }
}

Note that this is fairly simple (on purpose) and does not consider its parent nor children styles.

from flex-layout.

DuncanFaulkner avatar DuncanFaulkner commented on May 23, 2024 1

@shripadgodse just to let you know I have forked this project and updated it to use version 16 of Angular, I had to rename the project but that is a minimal change in your project. I understand that (in the mid to long term) you need to find an alternative for this library, but I plan on supporting this library for the foreseeable future to help those that have a number of projects that require migration to something more modern but don't have the time, resources or the budget to do so.

The project can be found on NPM ngx-layout and the repo can be found ngx-layout.

I hope this helps by giving you time to port your projects.

If you would like to sponsor the project you can find details on our sponsor page.

from flex-layout.

synopss avatar synopss commented on May 23, 2024 1

Hello,

I've developed a CLI designed to simplify the migration process from flex-layout to tailwindcss. The primary goal of this CLI is to automate the entire process, minimizing the need for manual intervention. Ideally, you should not have to make any additional changes once the CLI completes its tasks.

Here's what the CLI does for you:

  • It automatically installs tailwindcss.
  • Removes the old flex-layout dependency.
  • Converts all directives into tailwindcss classes.

Since it's a CLI tool, you can install it globally and smoothly execute it across multiple projects.

My objective with this CLI is to offer a comprehensive 1-to-1 migration solution. Some existing solutions in the discussion thread do not adequately handle some specific cases, which I have taken care to address.

Please note that this project is still a work in progress. While you can already use the tool, it's currently in a release candidate state. At present, all flex directives are supported, and my next target is to cover grid directives.

no one mentened about a attribute like the following [fxLayoutAlign]="(settings.menuType=='default') ? 'start center' : 'center center'", any idea on converting the above attribute into Tailwind?

Unfortunately, this part may require manual adjustment for now. I'll continue working on finding a solution, but I cannot guarantee a quick resolution to this particular issue. Same story for custom breakpoints.

Feel free to open issues if you notice any problem, any contribution is also welcomed.

Link: https://github.com/synopss/flex-layout-to-tailwind

from flex-layout.

synopss avatar synopss commented on May 23, 2024 1

@ayan-bloomscorp thanks for your inputs, I'll check asap.

from flex-layout.

MikaStark avatar MikaStark commented on May 23, 2024

So so so so so sad. This project is fantastic, I can't believe it comes to an end...
I use this library massively and It will be very hard to something else. I almost use all fxFlex* and fxLayout* features.

I'm not very okay with using tailwind, I hope someone would like to continue to maintain flex layout.

Anyway thanks for everything @CaerusKaru, the job you have done so far is great :)

from flex-layout.

michaelfaith avatar michaelfaith commented on May 23, 2024

Ah, gotcha. Fair enough

from flex-layout.

aceArt-GmbH avatar aceArt-GmbH commented on May 23, 2024

<div fxFlex> → <div class="flex-1">.

@anisabboud I had a similar idea.
But adding fxFlex does add style properties to the parent element as well and not just the elment itself.

<div>
    <div>
        test 1
        <div fxFlex>test 2</div>
    </div>
</div>
<div>
    <div>
        test 1
        <div class="flex-1">test 2</div>
    </div>
</div>

is not the same thing.
Using the new :has() selector should work however

from flex-layout.

ginxdroid avatar ginxdroid commented on May 23, 2024

What about using Bootstrap's grid system + angular material components? (Only bootstrap grid and not other ones like ui components of bootstrap)

from flex-layout.

ginxdroid avatar ginxdroid commented on May 23, 2024

Please consider handing over this project to the community. This project is so good.
What I liked about using this:

We can use directives instead of classes.
That is in other libraries we have to use multiple classes altogether but if we use this one then there is no need to use multiple classes in single class attribute.

Directives makes code easy to maintain and understand since different directives handle different things.
e.g
if we use bootstrap grid system then code will look like:
class="col-12 col-md-6 <our other classes>"
but if we use this library then:
fxFlex="100%" fxFlex.gt-sm="50%"

(It is not full code ofcourse it is just an example.)

which makes code easy to understand since class attribute is less bloated.

from flex-layout.

ginxdroid avatar ginxdroid commented on May 23, 2024

I am totally agree with you @jpike88 .

from flex-layout.

arambazamba avatar arambazamba commented on May 23, 2024

I've successfully migrated from flex-layout (~200 usages) to CSS Flexbox + CSS Grid + Angular CDK layout (without Tailwind).

Here are the replacements I made, in case they are helpful to others.

fxLayout="row", fxLayout="col"

<div fxLayout="row"> → <div class="flex-row">. Global CSS:

// Flex row/col + grid.
.flex-row { display: flex; flex-direction: row; }
.flex-col { display: flex; flex-direction: column; }
.grid { display: grid; }

// Flex-wrap utils.
.flex-wrap { flex-wrap: wrap; }  // Mostly used with flex-row, when wrapping is desired.
.flex-col-xs { @media screen and (max-width: 599px) { flex-direction: column; } }  // Switch from flex-row to flex-col on mobile.

fxLayoutGap

<div fxLayoutGap="8px"> → <div class="gap-8">. Global CSS for common gaps (& inline CSS for uncommon gaps):

// Gap.
.gap-4 { gap: 4px; }
.gap-8 { gap: 8px; }
.gap-10 { gap: 10px; }
.gap-12 { gap: 12px; }
.gap-16 { gap: 16px; }

fxLayoutAlign

<div fxLayoutAlign="justify-between center"> → <div class="space-between items-center">. Global CSS for common alignments (& inline CSS for uncommon ones):

// Justify content.
.space-between { justify-content: space-between; }  // Used very often with flex-row.
.justify-center { justify-content: center; }  // Used to center something via flexbox.

// Align items. (Naming inspiration: https://tailwindcss.com/docs/align-items.)
.items-center { align-items: center; }  // Used very often with flex-row.

fxFlex

<div fxFlex> → <div class="flex-1">. Global CSS for common flex values (& inline CSS for uncommon values like flex-basis):

// Flex/grow/shrink properties https://developer.mozilla.org/en-US/docs/Web/CSS/flex.
.flex-1 { flex: 1 }  // Same as flex: 1 1 0 (grow, shrink, basis 0). Has similar effect to width: 100%;
.flex-grow { flex-grow: 1; }  // Same as flex: 1 1 auto (grow, shrink, basis auto). For spacer, etc. 

fxHide, fxShow

<div fxHide.xs> → <div class="hide-xs">. Global CSS for common hide breakpoints (depending on your app):

// Hide & show for different breakpoints.
.hide-xs    { @media screen and (max-width: 599px) { display: none; } }  // Hide on mobile.
.hide-gt-xs { @media screen and (min-width: 600px) { display: none; } }  // Show only on mobile. Hide on desktop.
.hide-sm    { @media screen and (max-width: 959px) { display: none; } }  // Hide on mobile/tablet.
.hide-gt-sm { @media screen and (min-width: 960px) { display: none; } }  // Show only on mobile/tablet. Hide on desktop.

gdColumns

<div gdColumns="XYZ" gdGap="8px"> → <div class="grid gap-8" style="grid-template-columns: XYZ">. I.e., re-using grid & gap classes from above, and using inline style for grid-template-columns.

ngStyle.xs, ngClass.xs

These are the most challenging to replace - they're one of the nicest features of the flex-layout library. I didn't find a straight-forward replacement. I just replaced them with custom CSS classes & breakpoints in the CSS file. For example, <div style="width: 100px" ngStyle.xs="width: 50px"> → <div class="my-div"> + CSS below

.my-div {
  width: 100px;
  @media screen and (max-width: 599px) {
    width: 50px;  // Smaller on mobile.
  }
}

Note to avoid confusion: Angular's own ngStyle & ngClass are not deprecated.
Only the flex-layout extension of these (ngStyle.breakpoint & ngClass.breakpoint) is deprecated.

MediaObserver

Replaced with Angular CDK Layout's BreakpointObserver (which felt faster to me in run-time). Before:

const isMobile: Observable<boolean> = this.mediaObserver.asObservable().pipe(
  map((changes: MediaChange[]) => changes.some(change => change.mqAlias === 'xs')));

After:

const isMobile: Observable<boolean> = this.breakpointObserver.observe(Breakpoints.XSmall).pipe(
  map(state => state.matches));

👍 Actually one could go one step further and create directives out of this … most samples for the new directives composition api just combine styles 😜

from flex-layout.

michaelfaith avatar michaelfaith commented on May 23, 2024

@CaerusKaru just to clarify, v15 will be the final version of flex-layout right? That was my read of the medium article, and it seems like a lot of folks'.

from flex-layout.

EduardoMiguel2109 avatar EduardoMiguel2109 commented on May 23, 2024

why not create a simple library that maps the directives to the css in the element? I was thinking of doing it this way to avoid changes to existing code. Before the project dies, you could do one last release with this css mapping

from flex-layout.

michaelfaith avatar michaelfaith commented on May 23, 2024

@azimuthdeveloper I generally agree with your sentiments. However

This isn't a good deprecation article.

That wasn't the official deprecation article from the Angular team. This was. That was @CaerusKaru's farewell.

from flex-layout.

Franweb79 avatar Franweb79 commented on May 23, 2024

which is that unfortunately no amount of money (short of paying a full Google employee salary) will fund this to stay in the same namespace, because at the end of the day, Google would be responsible, and that's something the team cannot afford.

If the Angular team, or the people funding the Angular team, can't afford to maintain a widely used package like this (one that the deprecation of is going to cause literally thousands of man-hours of development work to refactor away from) then that is deeply concerning for the future of Angular as a whole. Why? Because it sounds like more of a financial decision than a "What's best for Angular and Angular developers decision". You can unpin dependencies etc, but won't this just simply lead to the atrophy of Angular Layout and increased breakages/incompatibilities over time? As you say, it won't guarantee compatibility forever, which is totally understandable (even in the v14 to v15 migration guide, there are nineteen steps to migrate from an Angular Material v14 app to an Angular Material v15 app. It's easy to imagine how one of these changes, possibly even as soon as v15 to v16, would cause a breaking change that nobody would be able to fix. And because of unpinned dependencies, that's going to culminate in the Angular compiler just throwing up and dumping errors of hard-to-read/hard-to-debug problems, possibly without the developer knowing exactly what has gone wrong. Or worse still, CSS weirdness with no obvious console output).

I understand your frustration, and those of the other users here, but I would like to remind everyone the primary goal of this issue is to track meaningful and impactful migration guides that would ease this transition. I am fully committed to authoring those guides depending on feedback, but the complexity of the library is such that it's really hard to understand where the priority is without it.

To write a migration guide, for even basic apps, I would suggest would be an extremely difficult and lengthy process. Extending that process by adding in how many corner cases and specialized layout needs developers would have, it's hard to see how such a task could have a meaningful outcome. Plus, even if there was an incredible migration guide, many Angular developers work against tightly defined sprints and deadlines and don't have an extra couple of months to refactor away from flex-layout.

Anyway - the decision has been made, so agitating on the particulars of that decision is fruitless (and I'm also probably aggravating someone who has given a lot of time to flex-layout, which seems counter-intuitive as well). It just seems like a genuinely good solution is being dropped for fiscal reasons, which makes me wonder what part of Angular would be dropped next for the same reason. That spooks me.

Thanks for all your hard work on flex-layout. I hope it wasn't all for nothing, and in some way, it survives into the future. I'm also sorry for taking the issue offtopic, it's just surprising (and unpleasant) that there's a huge refactor coming, to get the apps I maintain to look the same as they do today.

EDIT: Just to round this out, according to the Angular release schedule, we can expect a stable release of Angular every 6 months. Angular 15 was released in November 2022, so by May 2023, we should be welcoming Angular 16, and the end of official support for flex-layout. At this point in time, because no tests are being run against flex-layout, and it has unpinned dependencies, we can expect our apps to stop compiling, or the layouts to become totally wrong after we have upgraded to Angular 16. This is about when several developers will notice that something is up. So, in reality, we have five months from now to refactor away from flex-layout, if we would like to take Angular 16 when that lands.

To quote the Angular release page, under "Angular versioning and releases", it says there: "We recognize that you need stability from the Angular framework. Stability ensures that reusable components and libraries, tutorials, tools, and learned practices don't become obsolete unexpectedly. Stability is essential for the ecosystem around Angular to thrive."

A package within the Angular namespace being deprecated like this, and only really being supported until Angular 16 lands (which should happen in roughly five months), to me, is proof that the Angular team is really not living up to what they write on their release page. Literally, an Angular-exclusive package, published within the Angular namespace, tooling which can only be used for Angular, is being deprecated. This is the definition of learned practices becoming obsolete unexpectedly.

@jpike88 talks about the "damage of trust" between the angular brand and the devs who use the library. That's absolutely correct and should occur when the people in the Angular core team can't adhere to the things they write on the release page. How can anyone be sure that specific knowledge they have about Angular Material won't become obsolete when the next major version of Angular lands? We can't. And that's a problem.

Obviously, and I want to really strain this point, I sincerely appreciate everyone's hard work on flex-layout, and what I'm saying here is not supposed to reflect negatively on that, or be taken as an affront or be offensive to the Angular team, and certainly not the developers of flex-layout itself. But somehow, the people behind Angular dun goofed and snookered themselves into a corner where they seemingly have no choice but to go against what is written on their release page and make us all wonder if this is the last thing to go. By itself, that is a problem, and it probably should get an answer.

I can´t agree more. Despite they say it is "allowing the Angular team to focus on high-impact projects that further move Angular into the future", what I see here is a lack of commitment and probably a Google´s lack of wish to hire and pay more developers to maintain it, if the problem is that they have no time or people to do it.

They say angular-flex is experimental and thus it is not under their commitment but I don´t think "giving a year support while users plan for migration" is the exact meaning of reliability and commitment, angular users and their projects want/ need. That is the response an angular team member gave on another issue which she closed for being "too heated" (I don´t know what did you all expect with this decission)-,

It will be the last message I write about it but I wish to stress how unworthy of trust looks like the angular team now wth this decission. Yesterday was the angularJS to angular 2 migration, now is flex-layout, and tomorrow who will know... I feel exactly the opposite they state under their commitments: I feel that Angular is now a framework which can throw your efforts useless unexpectedly. And definitely a framework which gives us these "surprises" can´t be our main dev tool.

from flex-layout.

Franweb79 avatar Franweb79 commented on May 23, 2024

I have to say this is an utter failure and I will take responsibility. I have been very careful to not use packages outside of the default core lib rather be it be python and esp angular. I am now even more risk-averse with using third-party apps to the point of never again. The depreciation of the lib and the amount of refactoring I have to do now ranks as the number one fail of package choice over 20 years of development and the margins are not even close. I was fooled and again my fault because I remember thinking there was a strong synergy with the and the app ... almost like angular approved. I was wrong.

I am the same way and now it looks like I really can't trust any package maintainer, even if it's backed by one of the largest corporations on the planet. Does this kind of thing happen with Vue, React, etc.? I am honestly asking since I don't have as much experience with those libraries and communities. I would hope not. And if not, that tells me it's a symptom (as mentioned above) of the Google culture of blowing up widely used products on the regular. I just didn't expect that culture to seep into Angular, but maybe that's me being naive. As many others have stated, this ruins my trust in Angular as a whole and I will start thinking about considering moving to other frameworks in the future.

It would be interested to see if it's possible to somehow quantify the monetary impact this is going to have on the community and companies that will now have to pay developers to do a ton of refactoring (myself and the company I work for included). I would guess we are talking multiple millions of dollars, but I wouldn't know where to start in coming up with that number. I would also guess that many of the companies affected are either one man operations or small businesses that don't have a huge budget and can't easily absorb things like this. But I have to wonder if anyone that was part of this decision even considered that.

The real impact of this will come with the release of angular v16, since many devs are not aware of this deprecation and will face a HUGE problem with their proyects when they update. I guess many will prefer even making a new app from scratch with v16 or with another more mature framework. It will be translated into great delays on deadlines, freelances spending sleepless nights to fix this, and big companies maybe hiring devs to solve the migration problems or create new apps. Others maybe will be even fired for having chosen Angular for the project. They will be made responsibles by their angry bosses for what Angular Team made.

Also we have around 5 months until v16 is released; so the TLS year support they gave us are actually 6 months to make all migrations, and counting we have still no clear paths and guides to do that and how many breaking changes we will encounter. For a dev with various Angular projects based on angular flex-layout, this can be just hell and even could affect their health for the amount of unpaid job or extra hours they will have to do.

Has Angular Team thought about all of these things?

As others pointed out, if Google can´t afford the hiring of new devs to maintain a widely used library which is the base of thousands of angular projects, what can be expect in the future? I am now afraid of even using Angular Material.

Maybe it is a good chance, as you pointed out, to get new jobs if we learn how to properly migrate from flex-layout to CSS. You know, every crisis means a chance... But that is not the point.

I won´t leave Angular because that would mean, closing many doors and wasting a lot of years' learning effort; but with all of this I have learned how dangerous is to rely all your efforts to one single framework. I will start learning React and, if it is good enough, will become my primary dev tool, using only Angular when the projects could be made relying on the less libraries possible in a fast way, when I am sure that a decission like this can´t affect my project.

from flex-layout.

michaelfaith avatar michaelfaith commented on May 23, 2024

The real impact of this will come with the release of angular v16, since many devs are not aware of this deprecation and will face a HUGE problem with their proyects when they update.

Also we have around 5 months until v16 is released; so the TLS year support they gave us are actually 6 months

They said they're going to unlock the peer dependencies in the new release. So I suspect it'll be >=15 or something like that, rather than ^15.

from flex-layout.

jpike88 avatar jpike88 commented on May 23, 2024

I’d recommend keeping the goals nice and tight, aka maintenance mode. Only when things break in a way that’s obviously a break should it be put up as a bug fix. People here don’t need flex layout to do anything novel or different from its intended purpose, which should make taking it on very light work

from flex-layout.

runeabrahams1 avatar runeabrahams1 commented on May 23, 2024

Thank you all for your feedback and support on this I will try and collate all the information and put something together.

@DuncanFaulkner Please consider accepting sponsorship if that helps in your decision.

As for features, nor sure if everyone agrees, but I was hoping this feature would eventually be implemented: #1185
Ofc only if the most common use-cases has an automated migration

Updating the library with new releases of Angular within 2-3 weeks, and just keeping the Directive features, would be a minimal requirement for us to keep using this library.

from flex-layout.

michaelfaith avatar michaelfaith commented on May 23, 2024

As for features, nor sure if everyone agrees, but I was hoping this feature would eventually be implemented: #1185 Ofc only if the most common use-cases has an automated migration

Idk, I feel like this would end up creating just as much re-work for people as moving off of the library entirely. I mean, the performance improvements would certainly be attractive, but I wonder if some of that can be achieved with the new Directive Composition API they just rolled out in v15 (which could allow the public API to remain unchanged).

from flex-layout.

zijianhuang avatar zijianhuang commented on May 23, 2024

I have a complex business app with around 1000 angular flex layout directives. It had taken me 3 days including the time to learn CSS flex and examples by other commentators in this thread to migrate to pure CSS even though many of the directives had been replaced through search & replace. I had thought of writing a tool, however I was thinking, it may take me 20 hours to write this tool, while the angular flex layout team may just need 10 hours and produce much better results for different scenarios.

If I develop such tool, I would probably take such approach.

  1. Have some CSS classes that could replace some directives easily.
  2. A tool (probably coded in JavaScript/TS) scans nominated HTML of the SPA, replace some directives with CSS classes, or append to existing class attribute of an element.
  3. Along the scanning, generate some new CSS classes, for example for those "fxFlex" directives with different length, "grow" and "shrink", like class="some-existing-class flex-27 fx-grow-2 fx-shrink-1".
  4. For scenarios that a tool can not handle, leave some annotations near respective elements so programmers may manually modify.

I believe angular flex layout is capable of better designs. They had made such beautiful baby angular flex layout, hopefully they are going to give it a beautiful funeral.

from flex-layout.

alanpurple avatar alanpurple commented on May 23, 2024

hide-related directives are most critical since angular-material components cannot be hidden with class definition "display:none"

display:none should be applied for every components with style or [ngStyle]

from flex-layout.

alanpurple avatar alanpurple commented on May 23, 2024

@arambazamba

define class with "display:none" does not work with angular-material components

from flex-layout.

emonney avatar emonney commented on May 23, 2024

I created this sass css file to handle the common flex use cases flex-layout.scss
Give it a star for me will ya!

How to Use

e.g. 1 - In your html files:

  <div class="flex justify-around align-center">
      ...
  </div>

e.g. 2 - In your sass css files

  // style.scss
  @use 'flex-layout'; //import it
  
  .some-div {
    margin-right: 16px;

    @include flex-layout.breakpoint('lt-sm') { //use the breakpoint mixin
        margin-right: 0;
    }
  }

Note: Modify this file with your own use cases/additions to handle unique flexbox requirements for your project.
Treat it as just another sass file in your project that you use for general flex styles

Regards,
www.ebenmonney.com

from flex-layout.

iKrishnaSahu avatar iKrishnaSahu commented on May 23, 2024

@CaerusKaru

Just started working on migration.

We had created a custom directive on top of BaseDirective2 which toggles the visibility of a element based on the viewport size.
We are heavily using this directive in our component library and our internal clients are also using it.
I don't have the exact count of this custom directive's usage.

My question is - What is the best alternative of BaseDirective2?

I am currently exploring BreakpointObserver. This may help me to replace BaseDirective2

Update - I successfully replaced BaseDirective2 with BreakpointObserver

from flex-layout.

celalettin-turgut avatar celalettin-turgut commented on May 23, 2024

Hi guys, it seems all the concern is about the migration after the deprecation. But for the new projects it is not easy to decide what to use as CSS library along with Angular + Angular Components. The best solution seems to be using pure css but it is much more work. Do you have any idea, recommedations etc.?

from flex-layout.

celalettin-turgut avatar celalettin-turgut commented on May 23, 2024

Thank you @michaelfaith for the recommendation. What are the advantages and disadvantages using Tailwind css? What should we consider before using it? Don't you think it is an overkill to use angular components as ui library and Tailwind only for layout purposes?

from flex-layout.

Sergiobop avatar Sergiobop commented on May 23, 2024

Hi @DuncanFaulkner , thank you. Can you edit and add in your comments the link to the project so it's easier to find? (https://github.com/ngbracket/ngx-layout)

from flex-layout.

DuncanFaulkner avatar DuncanFaulkner commented on May 23, 2024

@Sergiobop updated, sorry thought I had added it as a link

from flex-layout.

AngularTx avatar AngularTx commented on May 23, 2024

Hi All,

We have also been using this package for our project . But we would probably be freezing the version to Angular 15 and for this package and no plans to upgrade going forward .

So the question is . For this scenario, is it still OK to continue with this package and I don't plan to migrate my application to any version more than 15. This project is kind of internal application and we are fine with how it works till Angular 15 with the last version of flex layout also.

from flex-layout.

chrispharmac avatar chrispharmac commented on May 23, 2024

I was unable to upgrade to 15 until I migrated, even with --legacy-peer-deps. But you may have better luck. Mine was complicated by needing to upgrade material components also.

from flex-layout.

shripadgodse avatar shripadgodse commented on May 23, 2024

Tailwind

Were you able to migrate from flex to any other framework ? We are also having around 6/10 projects which are using FlexLayout. Let us know if you guys have any solution.

from flex-layout.

michaelfaith avatar michaelfaith commented on May 23, 2024

Tailwind

Were you able to migrate from flex to any other framework ? We are also having around 6/10 projects which are using FlexLayout. Let us know if you guys have any solution.

For one of our libraries, which made minimal use of Flex Layout, we just shifted to pure css to avoid another dependency. But for our apps, which made extensive use, we moved to TailwindCSS

from flex-layout.

chrispharmac avatar chrispharmac commented on May 23, 2024

from flex-layout.

guoapeng avatar guoapeng commented on May 23, 2024

no one mentened about a attribute like the following [fxLayoutAlign]="(settings.menuType=='default') ? 'start center' : 'center center'", any idea on converting the above attribute into Tailwind?

from flex-layout.

lasimard avatar lasimard commented on May 23, 2024

oes add style properties to the parent element as well and not just the elment itself.

<div fxFlex> → <div class="flex-1">.

@anisabboud I had a similar idea. But adding fxFlex does add style properties to the parent element as well and not just the elment itself.

<div>
    <div>
        test 1
        <div fxFlex>test 2</div>
    </div>
</div>
<div>
    <div>
        test 1
        <div class="flex-1">test 2</div>
    </div>
</div>

is not the same thing. Using the new :has() selector should work however

Has anyone found a solution for this issue with fxFlex. Our use looks like

<div fxFlex="1 1 auto">Content</div>

.c3-flex-1-1-auto {
flex: 1 1 auto;
}

It does not translate 1:1 wjat fxFlex does

from flex-layout.

reuse-ay avatar reuse-ay commented on May 23, 2024

We replaced ~2000 simple usages of flex-layout with following CSS. Kinda hacky, but seems to work.

CSS

// fxFlex
[fxFlex] {
    flex: 1 1 0%;
    box-sizing: border-box;
}

*:has(> [fxFlex]) {
    flex-direction: row;
    box-sizing: border-box;
    display: flex;
}

[fxFlex='5'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 5%;
}

[fxFlex='20'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 20%;
}

[fxFlex='25'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 25%;
}

[fxFlex='30'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 30%;
}

[fxFlex='33'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 33%;
}

[fxFlex='50'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 50%;
}

[fxFlex='66'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 66%;
}

[fxFlex='67'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 67%;
}

[fxFlex='70'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 70%;
}

[fxFlex='80'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 80%;
}

[fxFlex='100'] {
    flex: 1 1 100%;
    box-sizing: border-box;
    max-width: 100%;
}

[fxFlex='1 0 auto'] {
    flex: 1 0 auto;
    box-sizing: border-box;
}

[fxFlex='0 1 auto'] {
    flex: 0 1 auto;
    box-sizing: border-box;
}

// fxLayout
[fxLayout] {
    box-sizing: border-box;
    display: flex !important;
}

[fxLayout='row wrap'] {
    flex-flow: row wrap;
    flex: 1 1 1e-9px;
}

[fxLayout='row'] {
    flex-direction: row;
}

[fxLayout='column'] {
    flex-direction: column !important;

    &[fxLayoutGap='8px'] > *:not(:last-child) {
        margin-right: unset;
        margin-bottom: 8px;
    }
    &[fxLayoutGap='12px'] > *:not(:last-child) {
        margin-right: unset;
        margin-bottom: 12px;
    }
    &[fxLayoutGap='16px'] > *:not(:last-child) {
        margin-right: unset;
        margin-bottom: 16px;
    }
    &[fxLayoutGap='24px'] > *:not(:last-child) {
        margin-right: unset;
        margin-bottom: 24px;
    }
    &[fxLayoutGap='32px'] > *:not(:last-child) {
        margin-right: unset;
        margin-bottom: 32px;
    }

    & > [fxFlex='5'] {
        max-height: 5%;
        max-width: unset;
    }
    & > [fxFlex='20'] {
        max-height: 20%;
        max-width: unset;
    }
    & > [fxFlex='25'] {
        max-height: 25%;
        max-width: unset;
    }
    & > [fxFlex='30'] {
        max-height: 30%;
        max-width: unset;
    }
    & > [fxFlex='33'] {
        max-height: 33%;
        max-width: unset;
    }
    & > [fxFlex='50'] {
        max-height: 50%;
        max-width: unset;
    }
    & > [fxFlex='66'] {
        max-height: 66%;
        max-width: unset;
    }
    & > [fxFlex='67'] {
        max-height: 67%;
        max-width: unset;
    }
    & > [fxFlex='70'] {
        max-height: 70%;
        max-width: unset;
    }
    & > [fxFlex='80'] {
        max-height: 80%;
        max-width: unset;
    }
    & > [fxFlex='100'] {
        max-height: 100%;
        max-width: unset;
    }
}

// fxLayoutGap
[fxLayoutGap='8px'] > *:not(:last-child) {
    margin-right: 8px;
}
[fxLayoutGap='12px'] > *:not(:last-child) {
    margin-right: 12px;
}
[fxLayoutGap='16px'] > *:not(:last-child) {
    margin-right: 16px;
}
[fxLayoutGap='24px'] > *:not(:last-child) {
    margin-right: 24px;
}
[fxLayoutGap='32px'] > *:not(:last-child) {
    margin-right: 32px;
}

// fxLayoutAlign
[fxLayoutAlign] {
    display: flex;
    box-sizing: border-box;
    flex-direction: row;
}
[fxLayoutAlign='center center'] {
    place-content: center;
    align-items: center;
}
[fxLayoutAlign='end center'] {
    place-content: center flex-end;
    align-items: center;
}
[fxLayoutAlign='end top'] {
    place-content: stretch flex-end;
    align-items: stretch;
}
[fxLayoutAlign='start center'] {
    place-content: center flex-start;
    align-items: center;
}
[fxLayoutAlign='start start'] {
    place-content: flex-start;
    align-items: flex-start;
}
[fxLayoutAlign='space-between center'] {
    place-content: center space-between;
    align-items: center;
}
[fxLayoutAlign='start stretch'] {
    place-content: stretch flex-start;
    align-items: stretch;
    max-height: 100%;
}
[fxLayoutAlign='end'] {
    place-content: stretch flex-end;
    align-items: stretch;
}
[fxLayoutAlign='center stretch'] {
    place-content: stretch center;
    align-items: stretch;
    max-height: 100%;
}
[fxLayoutAlign='center center'] {
    place-content: center;
    align-items: center;
}
[fxLayoutAlign='center end'] {
    place-content: flex-end center;
    align-items: flex-end;
}
[fxLayoutAlign='stretch stretch'] {
    place-content: stretch flex-start;
    align-items: stretch !important;
}

// fxHide
[fxHide] {
    display: none;
}

// `.` can't be part of attribute selector :(
// fxHide.lt-lg
@media screen and (max-width: 1279px) {
    [fxHidelt-lg] {
        display: none !important;
    }
}

// fxHide.gt-md
@media screen and (min-width: 1280px) {
    [fxHidegt-md] {
        display: none !important;
    }
}

// fxShow.gt-sm
@media screen and (min-width: 960px) {
    [fxShowgt-sm] {
        display: initial;
    }
}

// fxShow.gt-xs
@media screen and (min-width: 600px) {
    [fxShowgt-xs] {
        display: initial;
    }
}

// fxFill
[fxFill] {
    height: 100%;
    min-height: 100%;
    min-width: 100%;
    width: 100%;
}

This may work about period.
@media screen and (max-width:600px) { [fxHide\.xs]:not([fxHide\.xs="false"]) { display: none!important; } }

from flex-layout.

melroy89 avatar melroy89 commented on May 23, 2024

Using flex layout with hot cache (fast rebuild) in my Angular app in around 200-300ms:

Initial chunk files | Names   |  Raw size
main.js             | main    | 442.17 kB | 
runtime.js          | runtime |   6.46 kB | 

3 unchanged chunks

Build at: 2024-04-13T09:53:44.197Z - Hash: a8c99904de752972 - Time: 237ms

✔ Compiled successfully.

When I moved to Tailwind also with hot cache a rebuild takes 6500ms+:

Build at: 2024-04-13T09:52:23.268Z - Hash: 9752dba1b11aedf0 - Time: 6764ms

✔ Compiled successfully.

Initial chunk files | Names   |  Raw size
main.js             | main    | 441.88 kB | 
runtime.js          | runtime |   6.46 kB | 

3 unchanged chunks

Using tailwindcss/base, tailwindcss/components and tailwindcss/utilities. This is 30 times slower than angular flex layout.

Uh no thanks. This make rapid development a no go.

I go with the community fork: https://github.com/alessiobianchini/ng-flex-layout

from flex-layout.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.