When to use styled component vs when to use css prop in emotion? - emotion

Is there a best practice or list of pros and cons in deciding when to use a styled component instead of the css prop?

I generally prefer styledComponent but, there are certain edge cases like styling your <Link /> for react-router where you have to provide a compiled style to className prop.
There is no harm in using CSS props but, there is a chance of accidentally overriding your styles, plus it makes your JSX messier. But if you know what you are doing and you are heavily using composition then IMO it is quite a powerful feature.
It is much easier to understand and manage the styled-components, like when using themes you can encapsulate the whole styling logic away from your JSX. +1 to styled-components for lego based design.
I think it is safe to say, you can use styled-components and CSS together but adopting either one for the majority of your components.
I absolutely love how you can override your base components using emotion's composition(which saves us from passing weird props and helps to keep the props cleaner) but at the same time you should not abuse it as from personal experience it's tempting to just use CSS composition where you should be using props like isBold fontSize: "sm" ...

Related

How to hide functional components (JSX) in vue devtools?

i'm currently using JSX for Vue component, but currently, the devtool would show a very ugly nested hashed functional component tree like this, is there any way to avoid this? As far as I know, Vue devtools doesn't provide us an option to hide these functional components, therefore this would be very annoying
I'm building a UI package for Form module, I want to use JSX for Vue because that would make contribution much easier when a lot of people from React.js can jump in and help.
My package: https://www.npmjs.com/package/formkl

Is it wrong to create a vue component for every svg icon?

I like to use inline svg in my projects because it gives me great control over things like width, height, fill color, stroke width and stroke color using css and js(props). I usually create a vue.js SFC (single file component) for every SVG icon. Here's an example:
<!-- IconsArrowRight.vue -->
<template>
<svg
viewBox="0 0 14 14"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7.57026 0.888947L5.98842 2.46006L9.4199 5.89117L0.333374 5.89117L0.333374 8.10895H9.4199L5.98842 11.5401L7.57026 13.1112L13.6681 7.00006L7.57026 0.888947Z"
/>
</svg>
</template>
And then I would use it like this (I'm using tailwindCSS for styling):
<template>
<div>
<IconsArrowRight class="w-8 h-8 text-blue-500" />
</div>
</template>
I use more than 50 icons in my project, and I've created a vue.js component for each one; Is it a bad practice regarding production performance to have so many components just for icons? Should I use font-icons instead, or any other alternative method?
Using one .vue file for one .svg is totally fine IMO. It will not have any big impact performance-wise, just maybe take a bit longer when building your app but nothing that critical IMO.
Also, using it this way can have quite some flexibility in some rare situations regarding HTML specification.
Now, regarding the best approach ever, I'd probably say to use #unocss/preset-icons or any package based on Iconify simply because it will bring you all the available and imaginable icons on the fly, with no drawbacks and a LOT of flexibility + nice DX.
Here is an article in 4 parts that will explain all the reasoning behind this approach and how it can be integrated universally to any solution (even if not using Antfu's solution).
Most probably either using the svg as component or as font icon from performance side I would not consider any issue at all. Vue.js is a framework that can be used for large scale applications and your components are not heavy at all, they just use an SVG.
My personal preference would be to be used as font icons as you mentioned and use a component that you will be passing as props the font icon, so with this way you would have 1 component for all svgs.
About the styling, again using a prop to pass all the styles and bind that prop with the :class
This would be much cleaner I think,
Cheers

Best solution to update component content from another component in Nuxt

I'm new to Nuxt and Vue in general, so I'm not sure, what would be the best solution for this use case.
I want to change the text (like "Home", "Settings", "Favourites" etc.) inside my Header.vue (always fixed on top of the page) from another component. like Favourites.vue for example.
Sometimes I want to hide the header completely or hide the title and display buttons instead,
so I need to pass more props than just the title.
I tried using different layouts, but that breaks the animation transitions (I haven't found the solution for this yet), but I think it's still better to have control from the page in what I'm passing into this component.
Should I pass props from Page.vue to parent and read it from there in Header.vue component?
Should I use Vuex to pass this through the store and update it when the route changes? Or is that too complex for this use case?
Maybe there's a simpler solution that I'm not aware of.
Folder structure:
/components
├──Header.vue
└──Nav.vue
/pages
├──Index.vue
├──Profile.vue
├──Settings.vue
└──Favourites.vue
Vuex is the answer here— don’t worry about the 'simple' use case. As soon as you notice you’re creating data that other components may rely on (is the header visible on this page? Is the text different? etc) it’s a good idea to move into Vuex and maintain a single source of truth.
Your app may seem simple to begin with, but it’ll inevitably grow and at that point you’ll appreciate having a single source of truth vs. trying to pass things between components via props.
Nuxt also makes implementing Vuex very straight forward. No doubt you’re capable of pulling up the docs!

Is there a way to make wrapper div/container to group CMS components in slots?

By design we have visually grouped CMS components on multiple pages. We need some kind of wrapper div or a container around specific component groups to add CSS to it and make them visually appear like one entity. We have tried with styling the slots, but this is by no means a good solution. Do you have any suggestions how we could achieve this?
I can think of various ways, they all have PROs/CONs and limitations. You could combine those strategies as well to have an optimised mix.
The easiest way to implement this is by using standard CSS selectors. There are various selectors that could be used, such as sibling selectors, last-of-type selector.
Changing the CMS structure to fit the grouping, by using a specific slot for the components. With this approach you can influence the layout by using the pageslot position based CSS selector. The disadvantage here is the the page slot is less flexible and cannot contain additional components that you don't like to be part of the "group".
You could combine components in a so-called container component; container components have a list of embedded components. The advantage is that the container component can have non-grouped component siblings, which can be rendered in a different way.
the last resort would be a rewrite of the page layout / page slot component in Spartacus, and conditionally add specific DOM. This is a lower level change and is causing more work and will derail you from the standard implementation.
Hope this will give you some ideas, if not, you should provide more details.

Is overriding a global Vue component safe?

Let's say there is a global component BIcon.vue available everywhere.
And another component, but regular not global, called BIconFake.vue.
We can override BIcon.vue by BIconFake.vue like that:
<template>
<div>
<b-icon icon="plus"><!-- <- Here is it BIconFake component! -->
</div>
</template>
<script>
import BIcon from '~/components/BIconFake'
export default {
components: {
BIcon // <- BIconFake component inside!
}
}
</script>
By this way, Vue.js will display BIconFake component instead of regular BIcon component.
I tried to pass props, events or attributes and it works like expected.
Vue.js is awesome... and big. Really, I don't know everything about it, and I don't want to see side effects or unexpected behavior when doing this override.
So, I want to know if it's safe to do that? Does it make a mess in Vue.js instance? What about memory?
we can override component with pure vue.js. Also, I made this example for Buefy, but we can do that with any UI frameworks like Quasar, Vuetify...
Thinking globaly, Is it good to override components of UI frameworks? What about security, scalability and maintenability?
In fact, I searched a way to build a plugins or addons system to my Nuxt.js app, like wordpress plugins.
Is it a good architecture to start building my app by overriding vue component? Is there another way to build app addons for vue, by using npm or webpack?
If you are going to wrap existing components like that then you should keep in mind the Liskov substitution principle. <b-icon-fake> can likely be used in place of <b-icon> provided that it:
accepts the same props
emits the same events
exposes the same public methods (if it is used with a ref)
behaves in the same way
Most of those points probably do not apply for a simple <b-icon> component.
Also keep in mind the template of your wrapped component now includes an extra <div> around it. This can interfere with styling and things like that.
You can eliminate the additional memory overhead by using a functional component instead, but you will need to write the render function manually to preserve the behavior of the wrapped component. But honestly I wouldn't worry too much about memory usage unless you have determined it to be an issue (after profiling your app).
In terms of whether it is "good" to do this or not, I can't say. There are advantages and disadvantages. In my opinion, wrapping components is fine as long as you are the only consumer of the wrapper component and doing so doesn't affect any existing usage of the wrapped component outside of your code.