Generating an Angular Theme for Angular 15? - javascript

In the various tutorials I've seen themes generated like this:
//======================================
// SHARED THEME STYLES
//======================================
#include mat.core();
.dark-theme {
//======================================
// THEME INITIALIZATION
//======================================
#include mat.core-theme($theme);
#include mat.all-component-themes($theme);
}
.light-theme {
//======================================
// THEME INITIALIZATION
//======================================
#include mat.core-theme($theme);
#include mat.all-component-themes($theme);
}
If I understand it correctly, this is also how Angular's Documentation tells us to do it. However when I run the build I get these warnings.
./projects/playground/src/styles.scss - Warning: Module Warning (from ./node_modules/sass-loader/dist/cjs.js):
The same typography styles are generated multiple times. Read more about how style duplication can be avoided in a dedicated guide. https://github.com/angular/components/blob/main/guides/duplicate-theming-styles.md
../../../../node_modules/#angular/material/core/theming/_theming.scss 360:7 private-check-duplicate-theme-styles()
../../../../node_modules/#angular/material/core/_core-theme.scss 77:3 theme()
../../../elytra/src/lib/styles/themes/dark-theme.scss 139:5 #use
../styles.scss 9:1
How do we create the themes without duplicating commons styles like Typography?

According to their documentation
https://material.angular.io/guide/theming#multiple-themes-in-one-file
You will see that when defining two themes you should make use of the core-color for all themes aside from the primary.
A more thorough explanation can also be found in their docs https://material.angular.io/guide/duplicate-theming-styles
The primary concept is the *-theme mixins apply the entirety of the theme (aka duplicating it each time *-theme is called) whereas the *-color mixins only change the color of the respective components while leaving the rest alone.
I made changes to your example below to reflect the reading.
//Say this is your primary
.dark-theme {
//======================================
// THEME INITIALIZATION
//======================================
#include mat.core-theme($theme);
#include mat.all-component-themes($theme);
}
//and this being your secondary theme
.light-theme {
//======================================
// THEME INITIALIZATION
//======================================
#include mat.core-color($theme); <---- This is the magic
#include mat.all-component-colors($theme); <---- This is the magic
}

I believe this should work
Also I believe that mat.all-component-themes uses every single component, this will produce unnecessary CSS.
#use './node_modules/#angular/material' as mat;
#import './node_modules/#angular/material/_theming.scss';
#include mat-core();
//THEME INISTALIZATION
// ======== Light theme ========
$my-custom-primary: mat-palette($mat-pink, 500);
$my-custom-accent: mat-palette($mat-pink, 50);
$my-custom-theme: mat-light-theme($my-custom-primary, $my-custom-accent);
// ======== Dark theme ========
$my-custom-dark-primary: mat-palette($mat-deep-orange, 50);
$my-custom-dark-accent: mat-palette($mat-grey, 600);
$my-custom-dark-theme: mat-dark-theme($my-custom-dark-primary, $my-custom-dark-accent);
.light-theme {
#include angular-material-theme($my-custom-theme);
}
.dark-theme {
#include angular-material-theme($my-custom-dark-theme);
}

Related

AG Grid: Add license before export

We use AG Grid. I want to add our license as a side effect before exporting the React component for use, rather than having to add the license every time we use the grid component.
What I tried below doesn't work. I thought side effects would run before import/export if declared like this, but clearly my mental model was wrong. I assume the build tool may affect what happens too, we use Gulp in this particular case.
GridSupport.js (in a design package/repo)
/**
* AG Grid License
*/
import { LicenseManager } from "#ag-grid-enterprise/core";
LicenseManager.setLicenseKey('…some license key…');
// Export below happens, but no license set above :(
export { AgGridReact as default } from "#ag-grid-community/react";
Grid.js (in another package/repo)
import { AgGridReact } from 'GridSupport';
const Grid = (props) => {
// AgGridReact should be usable without printing license warnings to the console
return <AgGridReact {...props} />
}
What should I do instead?
Why not Initialize the license manager at the top level (App.js, or index.js)? it would cover all the encompassing grids.
As a side note: Just make sure to check that you are not mixing packages and modules for the grid when using enterprise package.
The question was edited to clarify that the two files were in two different packages.
We landed on adding the GridSupport.js to sideEffects in our design package/repo. This ensured that the license was set correctly as a side effect before the export happened.
package.json
{
"name": "#ourcompany/design",
"sideEffects": [
"some/path/GridSupport.js"
],
"dependencies": [
"ag-grid-community": "...",
"ag-grid-enterprise": "...",
"ag-grid-react": "..."
]
}

JSDoc: How do I let IntelliSense/TypeScript know about classes from other files?

I'm working on a relatively large project, and I want to add JSDoc to my classes and files to make it a lot easier to develop. I have a getter function for my "Configuration" class/object that returns its instance of a "SQLRegistry" object, which is set later on down the chain.
//configuration.js
/**
* #returns {SQLRegistry} registry
*/
getRegistry() {
return this._registry;
}
//sqlRegistry.js
const Configuration = require('./configuration');
class SQLRegistry {
//other code
}
Unfortunately, in VS Code with IntelliSense/ESLint, it provides an error saying that it cannot find the class 'SQLRegistry'. In any other situation, I would just import sqlRegistry.js into configuration.js, but in this situation I cannot (because sqlRegistry depends on configuration.js, as you can see above).
Is there some sort of JSDoc comment I can put at the top of the file that tells it to read sqlRegistry.js, so that it becomes aware of the SQLRegistry class? For example, something like:
/**
* #include {#link ./sqlRegistry.js}
*/
Your hypothetical #include {#link ./sqlRegistry.js} was very close in principal.
The actual way to write this under TypeScript's interpretation of JSDoc syntax is
/**
* #returns {import('./sqlRegistry.js')} registry
*/
getRegistry() {
return this._registry;
}
Note that it is TypeScript that actually powers the VS Code's primary JavaScript features like type inference, not ESLint
This syntax, import('module-specifier') in a type position, is known as import types, not to be confused with Type only imports and was introduced in TypeScript 2.9.
This is not a JSDoc specific feature but rather comes from TypeScript.
The TypeScript language service recognizes the syntax in JSDoc comment locations where a type is expected. Note that the official TypeScript Handbook states that
You can also import declarations from other files using import types. This syntax is TypeScript-specific and differs from the JSDoc standard:

Oracle-jet with typescript web component

I have created application with typescript run:
ojet create web-app-navbar --template=navbar --typescript
then I have creatd web component run:
ojet create components demo-card --typescript
ojet cli has created demo-card component successfully.
I want to add demo-card component to about page and I have add html tag:
// IT IS about.ts
class AboutViewModel {
constructor() {
}
/**
* Optional ViewModel method invoked after the View is inserted into the
* document DOM. The application can put logic that requires the DOM being
* attached here.
* This method might be called multiple times - after the View is created
* and inserted into the DOM and after the View is reconnected
* after being disconnected.
*/
connected(): void {
// implement if needed
}
/**
* Optional ViewModel method invoked after the View is disconnected from the DOM.
*/
disconnected(): void {
// implement if needed
}
/**
* Optional ViewModel method invoked after transition to the new View is complete.
* That includes any possible animation between the old and the new View.
*/
transitionCompleted(): void {
// implement if needed
}
}
export default AboutViewModel;
<!--
Copyright (c) 2014, 2020, Oracle and/or its affiliates.
The Universal Permissive License (UPL), Version 1.0
-->
<!-- IT IS about.html view -->
<div class="oj-hybrid-padding">
<h1>About Content Area</h1>
<div>
To change the content of this section, you will make edits to the about.html file located in the /js/views folder.
</div>
<deno-card></deno-card>
</div>
but it don't displayed on the page.
How can I add this component to my application?
Add import 'demo-card/loader' to about.ts
When using the ojet cli a path to the component is automatically set up for you.
You need to add import 'demo-card/loader' to automatically resolve the correct path for the transpiled component.

SCSS external Link to styling component in LitElement

The purpose of the web components is to encapsulate all HTML/CSS/JS in one place, but I must use general SCSS files, that have a lot of variables such as color, font size and a lot of other stuff. It's a design system and it's always changing. Is there a plugin or a way to solve this problem?
If the purpose of those Sass files is to only expose some variables then probably the smartest thing to do is converting them to CSS custom properties: they're the recommended and most effective way to theme WebComponents.
#use 'sass:meta';
#use 'variables-file-1'; // Import the variable files
#use 'variables-file-2'; // as Sass modules
// ...
#mixin export-vars($module-name) {
// Use module-variables() to extract a name-to-value map of the
// variables declared in the module identified by $module-name
#each $name, $value in meta.module-variables($module-name) {
--#{$name}: #{$value}; // Define an equivalent CSS custom prop
}
}
:root {
#include export-vars(variables-file-1);
#include export-vars(variables-file-2);
// ...
}
You can then import the compiled CSS (a normal <link> in index.html is fine in most cases since CSS custom properties cross shadow DOM boundaries) and use the variables in your components:
import { LitElement, html, css, customElement } from 'lit-element';
#customElement('my-component')
export class MyComponent extends LitElement {
static styles = css`
:host {
color: var(--my-var, <fallback-value>);
}
`;
}
With this said, if you need to share styles between LitElements, that is possible as well.

Exporting SCSS Variables to JS (auto looping variables)

UPDATE: If you plan to implement the export solution, you must
place it in a separate file to prevent redundant exports in your
compiled CSS code. See here.
I recently learned that you can export styles from SCSS into JS like so:
_variables.scss
:export {
some-variable: 'some-value';
}
app.js
import styles from 'core-styles/brand/_variables.scss';
Based on this, my _variables.scss is formatted like so:
/* Define all colours */
$some-color: #000;
$another-color: #000;
// Export the color palette to make it accessible to JS
:export {
some-color: $some-color;
another-color: $another-color;
}
The issue with the above format is that I have to re-define each of my variables within export. Therefore, I am interested to know whether there is a way to loop though each of my variables automatically and export them to JS?
Some improvements to the accepted answer:
Use camelcase so you will be able to individually export a variable.
Set the #each directive outside so it won't generate a new :export at-rule for each variable.
_variables.scss
$theme-colors: (
'someColor': #000,
'anotherColor': #FFF,
);
:export {
#each $key, $value in $theme-colors {
#{unquote($key)}: $value;
}
}
app.js
import styles from './core-styles/brand/_variables.scss' // { anotherColor: "#FFF", someColor: "#000" }
import { someColor } from './core-styles/brand/_variables.scss' // #000
Side note: I prefer using quotes inside Sass Maps, but you can omit them.
Taking a Cue from Bootstrap 4, you could combine a SASS map with a loop like below;
/* Define all colours */
$theme-colours: (
some-color: #000,
another-color: #000,
third-color: #000,
fourth-color: #000
)
#each $color, $value in $theme-colours {
:export{
$color: $value;
}
}
Here's some examples from the Bootstrap 4 Docs

Categories

Resources