Rollup minify classnames - rollupjs

Is there any rollup.js plugins which allow to obfuscate / mangle CSS class names? I haven't found anything, except this one for webpack: https://github.com/sndyuk/mangle-css-class-webpack-plugin

This can be achieved with rollup-plugin-postcss. As per the readme, configuration options for the modules property are passed through to postcss-modules.
Using the generateScopedName property you're able to set the format of the class name:
generateScopedName: "[hash:base64:8]",
There are more examples in the postcss-modules readme including how to generate the name dynamically. Note that you are responsible for ensuring that the names are unique enough to not clash.
The full rollup config would look something like:
import postcss from "rollup-plugin-postcss";
... // other imports
export default {
... // rest of config
plugins: [
... // other plugins
postcss({
...
modules: {
generateScopedName: "[hash:base64:8]",
},
autoModules: true,
}),
...
],
};
Then something like:
.parent {
display: grid;
grid-template-rows: auto 1fr auto;
}
/* styles.module.css */
import STYLES from './styles.module.css';
...
// Use the style however
<div className={STYLES.parent}>
...
</div>
Ends up looking like:
.xSgFDOB2 {
display: grid;
grid-template-rows: auto 1fr auto;
}
<div class="xSgFDOB2">
...
</div>

Related

Web components with vaadin and rollup with svelte: Primary button ignores theme attribute

Maybe someone tried this before and is able to give me a hint.
I have used normal svelte setup (mentioned in the main page) which scaffolds the app;
npx degit sveltejs/template my-svelte-project
I wanted to use vaadin web components in Svelte. I've installed it;
npm install #vaadin/vaadin
the code of main.ts:
<script lang="ts">
import '#vaadin/button/theme/material'
</script>
<main>
<vaadin-button theme="primary">Primary</vaadin-button>
<vaadin-button theme="secondary">Sec</vaadin-button>
</main>
<style>
main {
text-align: center;
padding: 1em;
max-width: 240px;
margin: 0 auto;
}
#media (min-width: 640px) {
main {
max-width: none;
}
}
</style>
And the thing is that it almost works :) The buttons are styled, I can click on them but... the theme is ignored;
The primary should have a background color like stated in docs;
https://vaadin.com/docs/latest/ds/components/button/#styles
any idea???
This is happening because of how Svelte sets data on custom elements. If a property exists on the element with the same name as the attribute you set, Svelte will set the property instead of the attribute. Otherwise, it will fall back to the attribute. So, the following...
<vaadin-button theme="primary">Primary</vaadin-button>
...gets compiled to something like:
button.theme = "primary";
Normally this works great, especially when setting array and object properties. However, the vaadin-button styles expect the theme attribute to be set, not the property. Because Svelte sets the property instead, the styles don't apply.
:host([theme~="primary"]) {
background-color: var(--_lumo-button-primary-background-color, var(--lumo-primary-color));
color: var(--_lumo-button-primary-color, var(--lumo-primary-contrast-color));
font-weight: 600;
min-width: calc(var(--lumo-button-size) * 2.5);
}
I would argue that this is a Vaadin bug - if you expose an attribute and a property for the same data, it shouldn't matter which one the consumer sets. Setting the property should have the same effect as setting the attribute. A quick way to fix this would be for vaadin-button to reflect the theme property, so that setting theme also sets the attribute. Here's how to do that in Lit.
However, that change requires the component library authors to implement it. As a consumer of the library, you can also work around this in Svelte by using an action to force Svelte to set the attribute instead.
<script>
import "#vaadin/button";
function setAttributes(node, attributes) {
for (const [attr, value] of Object.entries(attributes))
node.setAttribute(attr, value);
}
</script>
<main>
<vaadin-button use:setAttributes={{ theme: "primary" }}>Primary</vaadin-button>
<vaadin-button>Normal</vaadin-button>
</main>
I wrote an article about this behavior and other workarounds at CSS-Tricks, if you want a more in-depth explanation.
You seem to be importing the Material theme version of the Button component. The "primary" theme variant is only available if you use the default Lumo theme. To import that, use import '#vaadin/button';
For the Material theme, you can use the "outlined" and "contained" theme variants instead: https://cdn.vaadin.com/vaadin-material-styles/1.3.2/demo/buttons.html

div tag class attribute contains lot of strings and cannot be replaced with css string definition string

I am trying to develop an UI and the first step is to create CssLayout. Each CssLayout component is added hierarchically with and many CssLayout component.
The problem is when i run the application and inspect the div tags, the class attribute has extra strings that needs to be removed.
<div class="v-csslayout v-layout v-widget .content-container v-
csslayout-.content-container v-has-width v-has-height" style="width: 100%;
height: 100%;"><div class="v-csslayout v-layout v-widget .inner-content-
container v-csslayout-.inner-content-container"></div></div>
and what I need is
<div class=".content-container">
<div class=".inner-content-container">
</div>
</div>
Java Code:
#StyleSheet("{css/spreadjsdefault.css}")
public class SpreadJSWidget extends CssLayout {
/**
*
*/
public SpreadJSWidget() {
super();
addStyleName(".content-container");
CssLayout mainBox = new CssLayout();
mainBox.addStyleName(".inner-content-container");
addComponent(mainBox);
}
spreadjsdefault.css (They are empty for now)
.content-container
{
}
.inner-content-container
{
}
Please advice !
Two things:
In order to be able to properly match the css rules, you have to omit the leading . when adding the style name, i.e. addStyleName("contentContainer"). This way, the css elements will match your style definition.
Css classes like v-csslayout are default classes defined by vaadin used by the default themes to provide a basic layout. They are there by default and can't (and actually shouldnt) be removed entirely. What you can do, however, is to define and overwrite these rules yourself. What's important: Either way, your custom classes will still match when you define them in your style sheet and can overwrite the default theming.

Using external VueJs components in a VueJS project

I'm trying to use VueStrap in a VueJS project, it looks like webpacker is loading it fine, I can see this in the terminal output, however, when I try use a component from vue-strap I get this error:
[Vue warn]: Property or method "input" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
I tried including the VueStrap as a component in the Vue instance but couldn't get it to work. How do I include the VueStrap into as a component correctly?
Thanks!
This is my application.js:
import Vue from 'vue/dist/vue.js'
import App from '../components/app.vue'
import VueStrap from 'vue-strap'
document.addEventListener('DOMContentLoaded', () => {
document.body.appendChild(document.createElement('app'))
const app = new Vue({
el: 'app',
template: '<App/>',
components: { App }
})
console.log('app')
})
This is my app.vue file
<template>
<div id='app'>
<p> {{ message }} </p>
<bs-input :value.sync="input" label="Username" help="Only allows lowercase letters and numbers."
error="Insert username" placeholder="Username can't start with a number." pattern="^[a-z][a-z0-9]+$"
:mask="mask" minlength="5" readonly required icon>
</bs-input>
</div>
</template>
<script>
export default {
data: function () {
return {
message: "Hello World"
}
}
}
</script>
<style scoped>
p {
font-size: 2em;
text-align: left;
}
</style>
Please see the documentation on complication scope, notably:
Everything in the parent template is compiled in parent scope; everything in the child template is compiled in child scope.
Your template includes input and mask properties but your data function does not set those up. They need to be set up and reactive so if they change, Vue can pass them down to the child component (which it looks like your bs-input component exposes an input and mask properties).

Dynamic styles for different user

I need dynamic styles for each user. The problem is such that it is possible to choose between two themes, one static and the other user can change. After change current user theme value will set to sass variable and need precompile. How I can do it?
It's better to rely on pure CSS features in this one rather than compile your SCSS on each request (which will be very inefficient).
Given this base SCSS file:
.base-theme {
.color-main {
color: $blue-lighter;
}
// and so on
}
You can use this like this:
<p class="color-main"> ... </p>
Based on settings stored in the database you can generate an alternative
theme like so:
<style>
.alt-theme .color-main {
color: <%= current_user.colors.main %>;
}
</style>
and apply them later like so:
<body class="<%= user.has_theme?? 'alt-theme' : 'base-theme' %>">...</body>

Is there a template creation Event in Darts Web_ui?

Is there anything like a notification mechanism for the instantiation of a template?
Assume the following simple template:
<template iterate="name in names">
<div>{{name}}</div>
</template>
When a name is very long, it might be possible that the container of the name div is overflown. So what I would like to do is to get an event when the name div is added to the DOM so that I can take a look at the resulting width. I would then shorten the name until it fits nicely.
Note: I assume you can't achieve what you want with CSS. So here's a code solution.
I am not aware of any event or a way to hook into the creation process.
However, I have done something like this with success:
import 'dart:async';
inserted() {
Timer.run(() {
// Do your calculations here...
});
}
If you set your name variable later, then you could alternatively make it observable and set the timer after the value changes:
observe(() => name), (_) {
Timer.run(() {
// Recalculate...
});
});
And remember to mark it #observable and set the listener in created().
You should really handle something like this in CSS:
.name {
width: 50px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
And give your div a class of name.
This will automatically shrink the text down to the container width and add an ellipsis to indicate that the text has been truncated.

Resources