Svelte Material UI colored snackbar - sass

In a SvelteKit app,
I'm trying to use a smui colored snackbar.
My src/theme/_smui-theme.scss is:
#use 'sass:color';
#use '#material/theme/color-palette';
#use '#material/theme/theme-color';
#use '#material/snackbar/mixins';
// Svelte Colors!
#use '#material/theme/index' as theme with (
$primary: #ff3e00,
$secondary: #676778,
$surface: #fff,
$background: #fff,
$error: color-palette.$red-900
);
...
.mdc-snackbar.demo-success {
#include mixins.fill-color(color-palette.$green-500);
#include mixins.label-ink-color(
theme-color.accessible-ink-color(color-palette.$green-500)
);
}
.mdc-snackbar.demo-warning {
#include mixins.fill-color(color-palette.$orange-500);
#include mixins.label-ink-color(
theme-color.accessible-ink-color(color-palette.$orange-500)
);
}
.mdc-snackbar.demo-error {
#include mixins.fill-color(color-palette.$red-500);
#include mixins.label-ink-color(
theme-color.accessible-ink-color(color-palette.$red-500)
);
}
but compiling with npm run smui-theme-light I got an error:
This module was already loaded, so it can't be configured using "with".
node_modules/#material/theme/_index.scss
#forward './theme-color' show
[...]
src/theme/_smui-theme.scss
#use '#material/theme/theme-color';
[..]
#use '#material/theme/index' as theme with (
$primary: #ff3e00,
How I can add these scss customizations for reusable components that live outside /src/routes?

Related

SASS using mixins (breakpoints) in different file

i am struggling with breaktpoints in SASS.
I have this file structure
style.scss
_layout.scss
_variables.scss
I wanna use code breakpotints from _variables.scss in _layout.scss
_variables.scss
$screen-xl-min: 1200px;
#mixin xl {
#media (min-width: #{$screen-xl-min}) {
#content;
}
}
_layout.scss
#use 'variables';
nav {
height: 80px;
#include xl {
background-color: red;
}
}
style.scss
#use 'variables';
#use 'layout';
And I have error
SassError: Undefined mixin.
Can someone tell me, what am I doing wrong? Thanks a lot for a help!
Try and change
#use 'variables'
for
#use 'variables' as *;
Check the documentation: https://sass-lang.com/documentation/at-rules/use
In your example correct way will be write #include variables.xl {}
Or modify #use rule like #Café wrote

How to migrate cases that make use of #content and #import with #content and #forward in SASS

I'm migrating a codebase from using #import to #use and #forward. Most of it is okay but I'm unsure what to do in a case where #import is used with #content.
Considering the following mixing that the only goal is to wrap styles in a class:
#mixin alternative-styles {
.parent-class {
#content;
}
}
The mixin is then used with #import to wrap all those styles in a .parent-class:
#include alternative-styles {
#import 'components';
}
I assumed replacing it with a #forward wouldn't work but have it a try anyway in this way:
#include alternative-styles {
#forward 'components';
}
This threw the following error:
Error: This at-rule is not allowed here.
╷
22 │ #forward 'components';
│ ^^^^^^^^^^^^^^^^^^^^^
╵
I have found that the sass-migration tool solves the issue this way:
#use 'sass:meta';
#use 'mixins';
#include mixins.alternative-styles {
#include meta.load-css('components');
}
The components.scss files has multiple #forward statements to keep all component references in one place like this:
// components.scss
#forward 'components/buttons';
#forward 'components/text';
After the sass compiler runs it results in an empty block:
.parent-class {
}
Is there any way to achieve wrapping a bunch of styles in a class that supports the #use and #forward rules?
I found that the meta.load-css mixin actually does work after creating a separate prototype with the same structure:
#use 'sass:meta';
#use 'mixins';
#include mixins.alternative-styles {
#include meta.load-css('components');
}
More details on using meta.load-css for this case can be found in this GitHub issue: https://github.com/sass/sass/issues/3095
The reason I got the empty .parent-class block was because I was making use of asynchronous compiling with the gulp-sass package. Replacing sass().on(...) with sass.sync().on(...) solved the issue.

sass : import only a part

I have 2 scss files, I want to use one mixin from the first into the second, but without importing the rest of the file ( I have a few url() who don't react well into this file
someDir/F1.scss
#mixin somemixin($width, $height) {
}
.someClass {
#include somemixin(17px, 10px);
background-image: url('./someUrl');
}
anotherDir/anotherAnotherDir/F2.scss
#import '../../someDir/F1';
.someOtherClass {
#include somemixin(17px, 10px);
background-image: url('./someOtherUrl');
}
How can I do it?
You can instead try #use module instead of #import and make only mixins public or decide on what you want to make public from file 1.
Check it here
https://sass-lang.com/documentation/at-rules/use

How do i change material.io web component fill-color (mdc-top-app.bar)

I have been looking into google material design for web and am also totally new to SASS.
As it stands, i have been trying to change the background-color for the mdc-top-app-bar using the sass mixin fill-color($color) provided in the framework.
Having tried these few lines
#use '#material/button/mdc-button';
#use '#material/button';
#use "#material/top-app-bar/mdc-top-app-bar";
#use "#material/icon-button/mdc-icon-button";
.mdc-top-app-bar {
#include mdc-top-app-bar.fill-color(#8e44ad);
}
Am displayed with the follow error messages
ERROR in ./app.scss
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Undefined mixin.
╷
10 │ #include mdc-top-app-bar.fill-color(#8e44ad);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I completely cooked the last answer but I have worked it out.
instead of:
#use "#material/top-app-bar/mdc-top-app-bar";
#use "#material/icon-button/mdc-icon-button";
use:
#import "#material/top-app-bar/mdc-top-app-bar";
#import "#material/icon-button/mdc-icon-button";
and then to use the mixin,
instead of:
.mdc-top-app-bar {
#include mdc-top-app-bar.fill-color(#8e44ad);
}
use:
.mdc-top-app-bar {
#include mdc-top-app-bar-fill-color(#8e44ad);
}
I hope this helps
--Nathaniel
To avoid import statement you should do:
#use "#material/top-app-bar";
and then
.mdc-top-app-bar {
#include top-app-bar.fill-color(#8e44ad);
}
Also you can create alias
#use "#material/top-app-bar" as topbar;
.mdc-top-app-bar {
#include topbar.fill-color(#8e44ad);
}

Why does my code duplicate the css of a file?

In Sass I have some components (navbar, footer) and some #mixins (fonts) and a function to control the fonts.
I #import the location of the fonts and do #include in the function of the fonts, in this function I just choose the font I want to use.
The problem is that as I separated as "partials" the components (navbar and footer) they have the same sources and I gave #import in those sources in each .scss.
And with that it generates duplicate code in my generated .scss file. I'd like to know what good practices are for this and if I'm doing it right and how do I avoid these duplicates in .scss?
Since I can't see your code, I am not sure how you imported your resources exactly. However, if you are only generating one .css file, a good practice is to import everything on the file that will be compiled and not on each partial.
Let's imagine you have the following structure :
styles
├─ components
│ ├─ _footer.scss
│ └─ _navbar.scss
├─ settings
│ ├─ _functions.scss
│ └─ _mixins.scss
└─ styles.scss
In this example, styles.sccs is the only one that will be compiled, it will be used only to import all partials (the order matters):
// Settings
#import './settings/mixins';
#import './settings/functions';
// Components
#import './components/footer';
#import './components/navbar';
You then can use any mixins or functions in your components and everything is only imported once.
I'm not sure this answers your question – but to prevent duplicates in Sass I would create a mixin to check if an #include has already been made
SCSS
// Global list to keep track of what mixins has been included
$include-once: ();
// Mixin helper to be used inside other mixins we would like
// not to produce duplicate content
#mixin once($mixin-name) {
// check if mixin name exists in our list
#if not index($include-once, $mixin-name) {
// add mixin name to list (using the global flag)
$include-once: append($include-once, $mixin-name) !global;
// print out the content of the mixin
#content;
}
}
// Use example
#mixin font {
// wrap content in the include once wrapper passing the name of the mixin
#include once(font){
// make sure font import is not nested
#at-root {
#import url("https://fonts.googleapis.com/css?family=Open+Sans");
}
}
}
// Test
.foo { #include font; color: red; }
.bar { #include font; color: green; }
.baz { #include font; color: blue; }
CSS Output
#import url("https://fonts.googleapis.com/css?family=Open+Sans")
.foo {
color: red;
}
.bar {
color: green;
}
.baz {
color: blue;
}
I'm sort of late to the game, but I experienced this issue and having partials or using #include did not work. What did it for me was using i.e. css-nano-webpack-plugin https://www.npmjs.com/package/cssnano-webpack-plugin. I'm using webpack v5, so could not get it to work using the webpack mini-css-extract-plugin https://www.npmjs.com/package/mini-css-extract-plugin.
Please bear in mind that the below snippet minimizes and minifies the css PER scss file. So, repetitions between files may still make it in the .css output file.
So, include it in your webpack config like so (source is the npmjs cssnano-webpack-plugin site)
const CssnanoPlugin = require('cssnano-webpack-plugin');
module.exports = {
module: {
loaders: [
{
test: /.s?css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader'
]
}
]
},
optimization: {
minimizer: [
new CssnanoPlugin()
]
}
};
´´´

Resources