Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Angular Layout Migration Guides #1426

Open
CaerusKaru opened this issue Oct 17, 2022 · 107 comments
Open

Angular Layout Migration Guides #1426

CaerusKaru opened this issue Oct 17, 2022 · 107 comments

Comments

@CaerusKaru
Copy link
Member

CaerusKaru commented Oct 17, 2022

In accordance with the announcement in the Medium post about this library's future, this is a tracking issue for requesting assistance in migrating complex usages of Angular Layout.

If you believe that your library falls under this case, you can request (or vote on existing) migration guides to other, supported solutions like Tailwind or Angular CDK.

Please use the +1 reaction wherever applicable, and do not comment +1. Those comments will be ignored/deleted.

I appreciate your patience as we go through this process. Until the campaign is complete, the library will still be actively maintained.

In your request, please include the following details:

  • How many usages you have in your application/library
  • Which directives/services from this library you are using
  • Why it is non-trivial to migrate

This will help us prioritize the guides as they are submitted.

@CaerusKaru CaerusKaru pinned this issue Oct 17, 2022
@michaelfaith
Copy link

michaelfaith commented Oct 19, 2022

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.

@blogcraft
Copy link

blogcraft commented Oct 19, 2022

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!

@jnfaerch
Copy link

jnfaerch commented Oct 20, 2022

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 👍

@MikaStark
Copy link

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 :)

@ianvink
Copy link

ianvink commented Oct 30, 2022

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

@Interscope19
Copy link

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.

@blogcraft
Copy link

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

@coreConvention
Copy link

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?

@MikaStark
Copy link

MikaStark commented Nov 3, 2022

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

@anisabboud
Copy link

anisabboud commented Nov 4, 2022

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));

@michaelfaith
Copy link

@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.

@Interscope19
Copy link

@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

@michaelfaith
Copy link

Ah, gotcha. Fair enough

@anisabboud
Copy link

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!

@sourav-bhar
Copy link

sourav-bhar commented Nov 6, 2022

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

@BryanYin
Copy link

BryanYin commented Nov 7, 2022

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.

@aceArt-GmbH
Copy link

<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

@ginxdroid
Copy link

ginxdroid commented Nov 14, 2022

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

@ginxdroid
Copy link

ginxdroid commented Nov 14, 2022

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.

@ginxdroid

This comment was marked as off-topic.

@CaerusKaru
Copy link
Member Author

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).

@ginxdroid

This comment was marked as off-topic.

@jpike88

This comment was marked as off-topic.

@ginxdroid

This comment was marked as off-topic.

@ginxdroid

This comment was marked as off-topic.

@alexander-kastil
Copy link

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 😜

@michaelfaith
Copy link

@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'.

@ianvink
Copy link

ianvink commented Nov 18, 2022

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

@guoapeng
Copy link

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?

bpedersen2 added a commit to bpedersen2/frontend that referenced this issue Aug 28, 2023
ngy-layout is a replacement clone for the discontinued flex-layout.

See https://blog.angular.io/modern-css-in-angular-layouts-4a259dca9127
and
angular/flex-layout#1426 (comment)

Change-Id: Id6f743428d52e8e34ecbddcc3d7b28c1345a3a90
bpedersen2 added a commit to bpedersen2/frontend that referenced this issue Sep 4, 2023
ngy-layout is a replacement clone for the discontinued flex-layout.

See https://blog.angular.io/modern-css-in-angular-layouts-4a259dca9127
and
angular/flex-layout#1426 (comment)

Change-Id: Id6f743428d52e8e34ecbddcc3d7b28c1345a3a90
bpedersen2 added a commit to bpedersen2/frontend that referenced this issue Sep 4, 2023
ngy-layout is a replacement clone for the discontinued flex-layout.

See https://blog.angular.io/modern-css-in-angular-layouts-4a259dca9127
and
angular/flex-layout#1426 (comment)

Change-Id: Id6f743428d52e8e34ecbddcc3d7b28c1345a3a90
bpedersen2 added a commit to bpedersen2/frontend that referenced this issue Sep 4, 2023
ngy-layout is a replacement clone for the discontinued flex-layout.

See https://blog.angular.io/modern-css-in-angular-layouts-4a259dca9127
and
angular/flex-layout#1426 (comment)

Change-Id: Id6f743428d52e8e34ecbddcc3d7b28c1345a3a90
bpedersen2 added a commit to bpedersen2/frontend that referenced this issue Sep 4, 2023
ngy-layout is a replacement clone for the discontinued flex-layout.

See https://blog.angular.io/modern-css-in-angular-layouts-4a259dca9127
and
angular/flex-layout#1426 (comment)

Change-Id: Id6f743428d52e8e34ecbddcc3d7b28c1345a3a90
bpedersen2 added a commit to bpedersen2/frontend that referenced this issue Sep 4, 2023
ngy-layout is a replacement clone for the discontinued flex-layout.

See https://blog.angular.io/modern-css-in-angular-layouts-4a259dca9127
and
angular/flex-layout#1426 (comment)

Change-Id: Id6f743428d52e8e34ecbddcc3d7b28c1345a3a90
bpedersen2 added a commit to bpedersen2/frontend that referenced this issue Sep 5, 2023
ngy-layout is a replacement clone for the discontinued flex-layout.

See https://blog.angular.io/modern-css-in-angular-layouts-4a259dca9127
and
angular/flex-layout#1426 (comment)

Change-Id: Id6f743428d52e8e34ecbddcc3d7b28c1345a3a90
bpedersen2 added a commit to bpedersen2/frontend that referenced this issue Sep 5, 2023
ngy-layout is a replacement clone for the discontinued flex-layout.

See https://blog.angular.io/modern-css-in-angular-layouts-4a259dca9127
and
angular/flex-layout#1426 (comment)

Change-Id: Id6f743428d52e8e34ecbddcc3d7b28c1345a3a90
Junjiequan pushed a commit to SciCatProject/frontend that referenced this issue Sep 15, 2023
ngy-layout is a replacement clone for the discontinued flex-layout.

See https://blog.angular.io/modern-css-in-angular-layouts-4a259dca9127
and
angular/flex-layout#1426 (comment)

Change-Id: Id6f743428d52e8e34ecbddcc3d7b28c1345a3a90
@lasimard
Copy link

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

@Cylop
Copy link

Cylop commented Sep 25, 2023

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

@synopss
Copy link

synopss commented Oct 1, 2023

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

@reuse-ay
Copy link

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; } }

@ayan-bloomscorp
Copy link

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.

@synopss
Copy link

synopss commented Jan 26, 2024

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

@melroy89
Copy link

melroy89 commented Apr 13, 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

@synopss
Copy link

synopss commented Apr 13, 2024

@melroy89 I found that issue if that helps you angular/angular-cli#21228

@melroy89
Copy link

No, that issue you mentioned is closed without any solution.

I'm gonna use the ng flex layout fork by alessiobianchini I guess for now.

@synopss
Copy link

synopss commented Apr 13, 2024

No, that issue you mentioned is closed without any solution.

I'm gonna use the ng flex layout fork by alessiobianchini I guess for now.

Well, if you examine the commit history, you'll see that they worked on it. So, it wasn't necessarily closed without any solution.

But if the fork works fine for you then it's best to keep using it I guess.

@kiranbs-github
Copy link

@CaerusKaru , please let us know is there any plan to publish a migration guides/blogs ?

@CaerusKaru
Copy link
Member Author

@kiranbs-github This thread has served as a migration guide of sorts, where this excellent community has provided a number of very easy to use alternatives for migrating, running the gamut from static transforms to drop-in replacements (a la @DuncanFaulkner's fork). Unless there are very specific use cases not captured above, in which the community upvotes for a supported approach, this thread (which will remain in perpetuity on the repo) will be the limit of what is provided.

I want to take this opportunity to send my deep thanks and concrete appreciation for the efforts of everyone above. You came together to solve an unexpected, shared problem, and did so in a manner that is truly admirable. You're one of the best open source communities out there, and that does not go unnoticed.

@mghaoui-interpulse
Copy link

mghaoui-interpulse commented Aug 23, 2024

Thanks for pointing out to me @DuncanFaulkner 's fork, which in case anybody else is looking is:

You can remove the dicontinued one:

npm uninstall @angular/flex-layout --save

Install the fork:

npm install @ngbracket/ngx-layout --save

And change the import:

- import { FlexLayoutModule } from '@angular/flex-layout';
+ import { FlexLayoutModule } from '@ngbracket/ngx-layout';

@melroy89
Copy link

@mghaoui-interpulse That is a possibility, note that there is another fork as well.

Remove the discontinued one:

npm uninstall @angular/flex-layout --save

So alternatively, you can migrate to the other fork:

npm i -s ng-flex-layout @angular/cdk

And change the import:

- import { FlexLayoutModule } from '@angular/flex-layout';
+ import { FlexLayoutModule } from 'ng-flex-layout';

Which fork is better? I dunno.

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

No branches or pull requests