Migrating components from Emotion to Chakra UI - emotion

This is the Emotion component
const Intro = styled(Content)`
padding-bottom: 0;
h2 {
margin-bottom: 0;
}
`
How do I convert that h2 { margin-bottom: 0; }
to chakra UI
I searched the documentation couldn't find how to deal with it.

Related

Using #vue/server-renderer (vuejs 3) how do you get the CSS?

I have been able to set up Server side rendering with Vuejs 3 using the code below but the renderToString method doesn't include the CSS and I also need to get the CSS rendered by the components.
example
const { renderToString } = require('#vue/server-renderer')
const createApp = require('./server/app').default
module.exports = async function (settings) {
const { app, router } = createApp(settings);
if (settings && settings.url) {
router.push(settings.url);
await router.isReady()
}
const html = await renderToString(app);
var toRet = { html: html, css: 'Still Need to get' };
return toRet;
};
The Single File Components so far are just boilerplate code specifying the CSS as scoped (shown below) but I'm also debating using CSS modules. I need the CSS in the Javascript file and not loaded separately as the site will be ran both in a Client Side manner with no Server Rendering and a Server Rendering manner.
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

How can I add dash between the value on input field?

I am trying to achieve something like this when the user is typing in the input field ABC you should get - after letter C while user is typing so in the end value should show ABC-123.
I have following hook const [newCar, setNewCar] = useState('') that I am calling in the following function
const addCar = () => {
if (newCar.length > 0) {
setCars([
...cars,
{
id: cars.length + 1,
license: newCar,
},
])
setValid(true)
} else {
setValid(false)
}
}
And I created changeText function as follows
const changeText = (newCar) => {
var newVal = newCar.length
if ((newVal === 3) && newVal >= newCar.length){
newCar = newCar + "-"
}
if (newCar.length === 7) {
setNewCar(newCar);
}
}
``` that I call in the `onChangeText={(newCar) => changeText(newCar)}` But when I try to write something in the input field it doesn't add the dash.
Your css selectors are wrong.
You want to style every h2/strong/p that are children of your S.StaffContent component. To do that, the proper css selector is & > h2
Final styles will look like this
& > h2 {
text-align: left;
margin-top: 1em;
margin-bottom: 1em;
}
& > p {
text-align: left;
margin-bottom: 1em;
}
& > strong {
font-size: 1.4em;
font-weight: bold;
margin-top: 1em;
}
By doing so, will get your components styled, assuming that the DOM looks like this.
<div classname='StaffContent'>
<h2>Styled h2</h2>
<p>Styled p</p>
<strong>Styled h2</strong>
</div>
Otherwise, if you wanted to apply the same styles to all the h2, strong and p elements descendants, at any level in the tree, you will need to add universal selectors.
const Component = styled.div(`
h2, * > h2 {
text-align: left;
margin-top: 1em;
margin-bottom: 1em;
color: white;
}
p, * > p {
text-align: left;
margin-bottom: 1em;
}
strong, * > strong {
font-size: 1.4em;
font-weight: bold;
margin-top: 1em;
}
`);
The problem was solved by running yarn upgrade --latest did it before using the yarn upgrade gatsby#3.0.1 as an example

Check if everything (including video) is loaded in Vue?

I have a Vue project that is getting a little large due to an embedded html5 video and am wondering how to tackle the loading issue for this site.
Is there a way to know if everything is loaded in Vue so I can show a loading screen before everything is ready? And does this loading take into account of assets loading like images, videos, etc?
If you want to wait for the rest of the webpage to finish loading before displaying the video, you can wait until the window has loaded (load event) and then display the video via v-if.
Here's some additional things to consider (you're using webpack, right?):
Code splitting
If your JS bundle is getting too big, you can split it into smaller chunks and the webpack runtime will download the chunks asynchronously on demand.
I like to split my vendor code into a separate chunk, as well as split off some router components like this:
{
path: 'foo',
component: () => import('./components/foo.vue'),
}
See Code Splitting (Webpack docs) and Async Components (Vue docs) for more info.
Loading page
Your webpage will initially appear blank while the browser is downloading the HTML and JS assets before the Vue app has been bootstrapped. During this time, you can display whatever plain HTML content you want, then mount the root Vue component over the loading HTML.
const App = {
template: '<div>My App</div>',
};
function bootstrap() {
new Vue({
el: '#app',
render: h => h(App),
});
}
// Simulate loading
setTimeout(bootstrap, 2000);
body {
font-family: sans-serif;
}
#keyframes loading-anim {
from { opacity: 1; }
to { opacity: 0.3; }
}
.loading {
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
font-size: 40px;
color: #888;
letter-spacing: -0.05em;
font-weight: bold;
animation: loading-anim 1s ease-in-out alternate infinite;
}
<div id="app">
<!-- Put whatever loading HTML content here -->
<div class="loading">LOADING</div>
</div>
<script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>

Extend in Less like it Sass can

I like to use :extend() in Less like I can do it in Sass.
Example in SCSS: http://codepen.io/Grawl/pen/qEeQPG
Example in Less: http://codepen.io/Grawl/pen/qEeQpz (not worked)
Expected output:
.datalist-item {
display: block;
}
.datalist-item-term {
font-weight: normal;
}
.datalist-item-description {
font-weight: bold;
}
.datalist-float .datalist-item {
display: inline-block;
}
.datalist-float .datalist-item:not(:last-of-type) {
margin-right: 1em;
padding-right: 1em;
border-right: 1px solid;
}
The purpose is to not self-repeat, so if I rename one class in Sass I have not to rename others.
I know I can put root class in a variable and use it twice with it http://codepen.io/Grawl/pen/qEeQpz but it looks ugly :(
Your Sass (SCSS) example uses #extend-Only Selectors which is some special form of extending which does not exists in Less.
Firstly a "normal" extend:
SCSS:
.class {
p: 1;
}
.class2 {
#extend .class;
}
and Less:
.class {
p: 1;
}
.class2 {
&:extend(.class);
}
both compile into:
.class,
.class2 {
p: 1;
}
In Less .class2 { &:extend(.class); } can also be written as .class2:extend(.class1){}
Now consider the following SCSS code which uses #extend-Only Selectors:
%class {
p: 1;
}
.class2 {
#extend %class;
}
The preceding code compile into CSS code as follows:
.class2 {
p: 1; }
Sass documentation tells you:
#extend-Only Selectors
Sometimes you’ll write styles for a class that you only ever want to
#extend, and never want to use directly in your HTML. This is
especially true when writing a Sass library, where you may provide
styles for users to #extend if they need and ignore if they don’t.
If you use normal classes for this, you end up creating a lot of extra
CSS when the stylesheets are generated, and run the risk of colliding
with other classes that are being used in the HTML. That’s why Sass
supports “placeholder selectors” (for example, %foo).
Placeholder selectors look like class and id selectors, except the #
or . is replaced by %. They can be used anywhere a class or id could,
and on their own they prevent rulesets from being rendered to CSS.
In Less you will have two options to have code that does not generate output:
1) use a mixin, mixins do not generate output:
.class() {
p: 1;
}
.class2 {
.class();
}
outputs:
.class2 {
p: 1;
}
2) put your classes which should not output in a different file and import this file with the reference kewyword:
file1.less:
.class {
p: 1;
}
file2.less:
#import (reference) "file1";
.class2 {
&:extend(.class);
}
lessc file2.less will output now:
.class2 {
p: 1;
}
But i agree with #seven-phases-max in the comments in the first place. In your example there is no need to use extend. #seven-phases-max shows you some examples to solve this use case. Alternatively you can consider; changing selector order with parent reference, which should work in both Less and SASS:
.datalist-item {
display: block;
&-term {
font-weight: normal;
}
&-description {
font-weight: bold;
}
.datalist-float & {
display: inline-block;
&:not(:last-of-type) {
margin-right: 1em;
padding-right: 1em;
border-right: 1px solid;
}
}
}
Compile into:
.datalist-item {
display: block;
}
.datalist-item-term {
font-weight: normal;
}
.datalist-item-description {
font-weight: bold;
}
.datalist-float .datalist-item {
display: inline-block;
}
.datalist-float .datalist-item:not(:last-of-type) {
margin-right: 1em;
padding-right: 1em;
border-right: 1px solid;
}
Finally notice that you are using nesting of properties such as:
border: {
right: 1px solid;
};
which should compile into:
border-right {
1px solid;
}
Less does NOT support nesting of properties.

Splitting up a list of variables in Sass

In Sass is there a way to split up a list of variables / classes with hyphens?
It's a fuzzy question title so it's probably best I show what I'm trying to achieve.
In the below example I'm trying to create some utility classes that I can apply to HTML elements to help with vertical rhythm.
For example I may want to give an element a small margin that is consistent with my vertical rhythm strategy and so I'll add the class .m-t-s (which stands for margin-top-small).
I then want to output versions of those utility classes against for each media query I have for fine grain control e.g. I may want a class .m-t-s-768 which will add a small top margin when there is a minimum viewport width of 768px.
I have achieved this below, but it is a very long-winded and repetitive way of doing it. Can anyone suggest a more concise way?
Variables
––––––––––
$mediaQueries-px:
640,
768,
1024
;
$s: 20px; /* FYI I've simplified these examples for the sake of demonstration, normally I use something like ($baseLineHeight / 1.5) + rem */
$m: 50px;
$l: 60px;
Creating the classes
–––––––––––––––––––––
.m-t-s {
margin-top: $s;
}
/* Create versions for each defined media query */
#each $mediaQuery in $mediaQueries-px {
#media screen and (min-width: ($mediaQuery / 16px)) {
.m-t-s-#{$mediaQuery} {
margin-top: $s;
}
}
}
.m-t-m {
margin-top: $m;
}
/* Create versions for each defined media query */
#each $mediaQuery in $mediaQueries-px {
#media screen and (min-width: ($mediaQuery / 16px)) {
.m-t-m-#{$mediaQuery} {
margin-top: $m;
}
}
}
This repeats for .m-t-l too (margin top large), and then it continues for padding classes (e.g. .p-t-s and so on), so it gets to be a pretty long list of utility classes.
To programatically generate that output, you need another list and an inner loop:
$mediaQueries-px:
640,
768,
1024
;
$s: 20px;
$m: 50px;
$l: 60px;
$sizes: s $s, m $m, l $l;
#each $size in $sizes {
.m-t-#{nth($size, 1)} {
margin-top: nth($size, 2);
}
}
#each $mediaQuery in $mediaQueries-px {
#media screen and (min-width: ($mediaQuery / 16 * 1em)) { // modified for compilation purposes
#each $size in $sizes {
.m-t-#{nth($size, 1)}-#{$mediaQuery} {
margin-top: nth($size, 2);
}
}
}
}
Output:
.m-t-s {
margin-top: 20px;
}
.m-t-m {
margin-top: 50px;
}
.m-t-l {
margin-top: 60px;
}
#media screen and (min-width: 40em) {
.m-t-s-640 {
margin-top: 20px;
}
.m-t-m-640 {
margin-top: 50px;
}
.m-t-l-640 {
margin-top: 60px;
}
}
#media screen and (min-width: 48em) {
.m-t-s-768 {
margin-top: 20px;
}
.m-t-m-768 {
margin-top: 50px;
}
.m-t-l-768 {
margin-top: 60px;
}
}
#media screen and (min-width: 64em) {
.m-t-s-1024 {
margin-top: 20px;
}
.m-t-m-1024 {
margin-top: 50px;
}
.m-t-l-1024 {
margin-top: 60px;
}
}