How to use images in CSS code inside an Angular library - css

I've built a library that will be used by several Angular applications (multiple teams and no monorepo). This library includes a scss-theme. This theme uses two SVG-files. However, I can't get it to work. The path is always incorrect.
My theme scss:
.test::before {
content: url('/test.svg');
}
I've written a Schematic that can be used by the library consumers to store the images inside a subdirectory of the assets folder of the application (e.g. src/assets/test-path). The Schematic does work as expected.
It does work when I add the following style inside the client's scss:
#import "test-company/test-lib/theme";
.a-client-test::before {
// This is just an example and assumes that the test image is located at this path.
background-image: url('../../assets/test-path/test.svg');
}
But as soon as I remove the line above (that actually uses the image from the assets folder and is not required at all). The path won't work anymore.
I've tested the following paths inside the library: ./test.svg, ~/test.svg, /test.svg. Only the latter does work but only with additional styles like the one above (that wouldn't be used) on app side. That's something I want to avoid as maybe we provide 50 icons on the library-side and it would be tedious to add these classes only to use the assets.
Some additional information:
I've added node_modules to the predecessor options in angular.json.
All other styles are working correctly. Only the image doesn't work.
I know that I can use ccsUrl: "inline" option inside the ng-package.json. However, I think this option only works (as far as I know) on styles that are used by components. But I actually copy the theme styles over after the build process. Additionally, the number of icons that are used inline shouldn't be too big, otherwise, the bundle size will increase and is therefore not an option for me.
I also don't know what is best practice for a scenario like that. I just couldn't figure out a proper way so far. But I assume writing a Schematic that copies over files is also not the best approach. Maybe there is a better way (e.g. a way to reference assets from the library but keep in mind I have the styles inside my library and the path is, therefore, complicated to figure out for all modules).
Just to make it clear again: My library has a scss file that uses an image. That image path is clear at the built time but doesn't work when used by an app. I can copy over the images, but that only helps when those images are used by the app somewhere in the styles. Then the path /image.svg works. The image as well as the scss that makes use of it are provided by my application.
Thanks for your help!

Related

How to use own icons in Flet

I can't find how to load my own icons in Flet.
I'm testing Flet with the intention of making a desktop app (pure desktop, not Internet needed), but I'm not able to use my own icons to begin with. I can only use the ones that come inside ft.icons, but I'd rather use my own by loading them from a folder similar to /assets/icons. Can I do that? How?
Thanks.
Currently, I don't see a way of doing this; however, you could use the Image class instead.
I would suggest you create an assets folder under your main project folder.
Let's assume you have the following folder structure on your project:
/assets
/icons/my-icon.png
main.py
When you are running your app, you should provide that folder to the initializer in the following way:
flet.app(target=YourApp(), assets_dir="assets")
Then you can access your images there directly and create an Image instance in the following way:
test_image = flet.Image(src="icons/my-icon.png", width=32, height=32, tooltip="Image Tooltip")
You can nest these Image controls inside of anything you want, so you have a lot of flexibility.
The only downside of doing it this way is if you are using light/dark themes on your app. Compared to the Icon class, you will have to specify the light/dark theme versions yourself and update them manually when you are switching your theme.
Here is the official documentation

Angular scss url(), cant resolve relative path when project is build

i have a folder filled with svg's (path: src/assets/icons).
The css function url() is implemented like this:
url("/assets/icons/CheckSmall.svg");
It finds the svg data, when I run ng serve.
But when I build my Project, it cant find the svg data. Although it exists in the folder dist/myApp/assets/icons/CheckSmall.svg
I have read through many forums and discussions and tested a few things (One of many discussions).
For example i used different pathing "strategies":
1. url("^assets/icons/CheckSmall.svg")
2. url("~/assets/icons/CheckSmall.svg")
For number (1) it seems like it is not a supported feature in Angular, thats why i dont want to use it. And for (2) it copies my Assets and puts them into the folder dist/myApp.
Is there a viable(supported or documented) alternative? Or can I somehow adjust the angular.json.
Try using the following syntax:
background-image: url('../../assets/icons/<file-name>')
Where the route is relative to the css file
If you're setting non-default baseHref or deployUrl flags as part of the build that can also affect it
Try using that approach in styles.scss or in the relevant component, without the scss variable. The relative path won't be correct when the scss variable is used in different folders

'react-scripts' build embedding some images in CSS as data-uri's

I've just inherited a large React project. I do not have much experience with React but I'm trying to make some improvements where I know how.
One issue we have is that our main CSS file is huge and one of the main reasons for this is that a bunch of images used in background-image properties have been embedded as Data-URIs despite them being set to relative URLs in the original SASS files.
These images are used multiple times throughout the app and so we end up with a final CSS file that has the same images embedded multiple times!
The application is built using react-scripts build which I believe is the culprit. As stated here:
To reduce the number of requests to the server, importing images that
are less than 10,000 bytes returns a data URI instead of a path.
I don't want this. Is there a way I can disable this? The project isn't using Webpack or any other build tool/bundler. All I have is the scripts in package.json to play with.
I'm not sure if you can do this with a simple toggle, since create-react-app isn't very customizable by design.
In order to change any configuration you'd like, you have a couple of options:
Forking the configuration (https://auth0.com/blog/how-to-configure-create-react-app/), which allows you to modify the configuration but still stay within create-react-app's boundaries.
Ejecting (https://facebook.github.io/create-react-app/docs/available-scripts#npm-run-eject) which will irreversably give you full power over the build configuration (which means you also have to maintain it going forward).

CSS modules and rollup - generating separate CSS files ("themes") with same hashes

I'm using CSS Modules (Sass) with rollup on a component library project, which is working well. Each component ends up with a dist folder containing a single JS bundle file, and a corresponding CSS file with the scoped CSS classes so consumers of the component don't have to worry about CSS class name conflicts. All they do is include the JS bundle and the CSS file and everything is great. Yay CSS Modules.
The problem I'm now facing is that some components really need separate "themes" - ideally, separate CSS files, one per theme. So consumers can continue as they've been doing: including the JS bundle, but now choosing which CSS file to include to pick a theme.
I'm not sure how to get this going with CSS modules & rollup, and whether this is even the sort of approach others are taking. From what I can see, rollup always handles bundling things together, whereas I want separate CSS files, all of which get their classes renamed identically during the build phase. That way, if within my JS I refer to styles.myclass, if myclass had gotten renamed to scoped-myclass by CSS modules for the original CSS file, for a second CSS file it would also get the same name.
This would keep consumption of the component extremely simple - just a matter of including a different CSS file.
Any suggestions?
Awfully late, but let me answer this 3 years on. So what I ended up doing was totally detaching the CSS generation step from rollup and relying on the Sass CLI to handle that portion of the build process. It felt a bit klutzy, but I remember it wasn't awfully hard to do and solved the problem I outlined above. I don't believe there was a plain rollup solution at the time, nor do I think there's one today.
However... in my case the whole approach was kinda mistaken. This certainly won't be everyone's scenario, but let me spell it all out because hey it may be useful and it definitely wasn't obvious to me at the time.
This was for an in-house shared component library, where each component and its corresponding CSS was a separate npm package stored in our Artifactory. When it grew, plenty of internal references popped up, e.g. multiple components would reference the Button component, and over time they'd reference different versions of the Buttons component - each of which needed its own properly scoped CSS, unique to that package-version.
So what I found was that by doing it this way - having the CSS generated as part of the npm package dist files - I had to write an additional layer for the consumer applications that would parse their node_modules/ folder for our own internal components and combine all the different CSS files, such as the multiple versions of buttons. e.g. the main application would directly import buttons v1.0.0 in its package.json file, but the Dialog component (also included in the package.json) could include buttons 2.0.0 as its own dependency. For every version of the package, there was a uniquely scoped version of the CSS - so the consuming application HAD to include every version otherwise the styling would be borked.
So all in all, it ended up being way more complex that I wanted. I thought I could make it easier & better with the separate generated themed CSS files as part of the package dist, but it didn't end up that way. If I could revisit that project today, I'd re-examine a solution used by Material UI and others which I kinda poo-poo'd at the time: automatic injection of the CSS into the page by the component JS, rather than generating standalone CSS files which required extra work by the consumer applications to gather up and add to the final webpage. Frankly, now I regard it as the "least crap". There are definite downsides to the injection approach (extra work done on every page render for everyone! Yikes!), but there's no doubt in my mind it hugely simplifies the job of the consumer applications. It's a balancing act, but in 20-20 hindsight I'd lean towards the injection approach. With that, scoping & theming is a different and much simpler problem.
If I got you right, consider looking at SCSS plugin: rollup-plugin-scss. It captures all spare .css files imported in the components, and then processes them through underlying node-sass. The catch is, it seems like you can write a custom callback function that'd handle your CSSs differently based on conditions you throw in.
Based on the example from the plugin's page:
import scss from 'rollup-plugin-scss'
...
export default {
input: 'src/index.tsx',
output: [...],
plugins: [
...
output: function (styles, styleNodes) {
// replace this with conditioned outputs as needed:
writeFileSync('bundle1.css', styles)
writeFileSync('bundle2.css', styles)
},
]
}

flip css for right to left (rtl) languages

Note: I'm open to other solutions if this is the wrong approach
I want to used https://github.com/twitter/css-flip for rtl support on
my project
The documentation is sparse and seems to make a lot of assumptions. I can successfully run the CLI against a .css file but not a scss file as I suspected.
I was thinking about adding a step that ran the css-flip on the compiled styles like so:
css-flip app/assets/stylesheets/application.css > app/assets/stylesheets/application.rtl.css
One, I'm not sure this is the best approach, and Two, if it is reasonable, how could I run the css-flip command on the assets after they've been compiled?
I'm not sure if this is the right approach, but I'd say you can use css-flip to generate your css files, and afterwards, I see 2 different solutions. (In the case you don't want to use Pete suggestion about the direction property, but I assume you may want some custom style depending of the orientation of the language.)
1 - depending on the version of your site, you change the asset being loaded.
2 - Or, I'd say you concat your two css files generated to put both behind a class (probably with the help of a preprocessor such as sass), and you put this class on your body, and change it whenever the user changes their language settings.
solution 1 creates lighter css file, but your user need to reload the page when they change language, whereas solution 2 creates bigger css file, but user won't need to reload their page when they change language.
Hope this helps.

Resources