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.
Related
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
I have been struggling for sometime now, trying to find ways to print out/generate document using vaadin.
i have tried using the below code but this prints all the components. I wanted to print only a particular form or layout.
UI.getCurrent().getElement().executeJs("print();")
Can some one guide me?
You'll need some CSS (similar to the approach mentioned here) that will hide everything when printing is invoked, except for the Layout or Component that needs to be printed.
For example, assuming you have the following two DIVs in your view:
Div printable = new Div(new Span("printable"));
Div nonPrintable = new Div(new Span("nonPrintable"));
You can give one of those a classname:
printable.addClassName("printable");
Then, you would add the following CSS to the global scope:
#media print {
body, body * {
visibility: hidden;
}
.printable, .printable * {
visibility: visible;
}
.printable {
position: absolute;
left: 0;
top: 0;
}
}
Note, in a Vaadin 14 project, the previous CSS is most easily incorporated using the #CssImport annotation. For example, the following annotations can be added to one of your Java classes:
#CssImport("./shared-styles.css")
Then under the directory {projecr-root-directory}/frontend, you'd need to create shared-styles.css and place the aforementioned styling there.
I've got a simple styled-components that is being applied to an antd component:
import { Card } from 'antd';
export const UsageCard = styled(Card)`
box-shadow: 1px 1px;
padding: 2px;
`
This creates a div with a class attribute that looks like : "ant-card edit-style__UsageCard-jsklqS hBLsXc ant-card-bordered"
Where .hBLsXc is my styled-component. Unfortunately the padding which is 2px in my styled-componentn gets overriden by the ant-card (0px).
Any idea why this is happening? The styled-components is supposed to come first since it's implemented over the thrid-party component. Is this a problem with the forwarding of className from third-party component I've read on multiple occasion? In any case, I don't really gets how this is supposed to work.
Thanks for your help!
The className has to be put in the Card Component, otherwise this will not work. You should check with antd to see if they did so. It has to look something like this:
const Card = ({ className }) => (
<div className={className}>
...
</div>
)
Here is the documentation for it:
https://www.styled-components.com/docs/basics#styling-any-components
edit:
I checked with antd and it looks like you can pass the className to it. There is a section in https://github.com/ant-design/ant-design/blob/master/components/card/index.tsx:
const classString = classNames(prefixCls, className, {
[`${prefixCls}-loading`]: loading,
[`${prefixCls}-bordered`]: bordered,
[`${prefixCls}-hoverable`]: this.getCompatibleHoverable(),
[`${prefixCls}-wider-padding`]: this.state.widerPadding,
[`${prefixCls}-padding-transition`]: this.updateWiderPaddingCalled,
[`${prefixCls}-contain-grid`]: this.isContainGrid(),
[`${prefixCls}-contain-tabs`]: tabList && tabList.length,
[`${prefixCls}-type-${type}`]: !!type,
});
You can pass the className via props. So this should actually work, but the passed className goes first, so I guess the antd styles will always override the styled-components ones, if they are the same. Maybe a fork might help?
I have a number of tabs, representing different services. I wish to have a final 'tab' tagged on the end of the list used to add a new service. Denoted by a simple '+'. This will open a simple dialogue.
I was hoping I could put my own ng-click behaviour on this single tab and prevent default but this doesn't work.
Is there any way I can 'catch' the tab click event BEFORE the tab body switch takes place and prevent it from happening?
It seems that it is not possible at the moment (see e.g. https://groups.google.com/forum/#!topic/ngmaterial/rNWMk3S9uDI) - at least using official api.
If you are ok with a solution which hacks into the directive internals then you can do following:
angular.module('MyApp').directive('tabWatcher', function() {
return {
require: ['mdTabs'],
restrict: 'A',
link: function(scope, el, attrs, controllers) {
var mdTabsCtrl = controllers[0];
var origSelectFn = mdTabsCtrl.select;
// overwrite original function with our own
mdTabsCtrl.select = function(index, canSkipClick) {
if (...) {
origSelectFn(index, canSkipClick);
}
}
}
};
I've placed a demo here http://codepen.io/jarek-jpa/pen/wGxqOq . Try to click some tabs. The select() call will be intercepted and depending on a condition let pass or not.
Disclaimer: Again, it hacks into the md-tabs directive internals, so may stop working any time (tested with angular-material 1.0.7)
You can set pointer-events to none to prevent the md-tab from responding to clicks.
Example:
<style>
md-tabs.readonly {
pointer-events: none;
user-select: none;
}
</style>
<md-tabs class="readonly">
<md-tab label="can't touch this"></md-tab>
</md-tabs>
This is tested to work with Angular Material 1.0.1
I've got a presentation running with reveal.js and everything is working. I am writing some sample code and highlight.js is working well within my presentation. But, I want to incrementally display code. E.g., imagine that I'm explaining a function to you, and I show you the first step, and then want to show the subsequent steps. Normally, I would use fragments to incrementally display items, but it's not working in a code block.
So I have something like this:
<pre><code>
def python_function()
<span class="fragment">display this first</span>
<span class="fragment">now display this</span>
</code></pre>
But the <span> elements are getting syntax-highlighted instead of read as HTML fragments. It looks something like this: http://imgur.com/nK3yNIS
FYI without the <span> elements highlight.js reads this correctly as python, but with the <span>, the language it detects is coffeescript.
Any ideas on how to have fragments inside a code block (or another way to simulate this) would be greatly appreciated.
To make fragments work in code snippets, you can now use the attribute data-noescape with the <code> tag
Source: Reveal.js docs
I got this to work. I had to change the init for the highlight.js dependency:
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() {
[].forEach.call( document.querySelectorAll( '.highlight' ), function( v, i) {
hljs.highlightBlock(v);
});
} },
Then I authored the section this way:
<section>
<h2>Demo</h2>
<pre class="stretch highlight cpp">
#pragma once
void step_one_setup(ofApp* app)
{
auto orbit_points = app-><span class="fragment zoom-in highlight-current-green">orbitPointsFromTimeInPeriod</span>(
app-><span class="fragment zoom-in highlight-current-green">timeInPeriodFromMilliseconds</span>(
app->updates.
<span class="fragment zoom-in highlight-current-green" data->milliseconds</span>()));
}
</pre>
</section>
Results:
I would try to use multiple <pre class="fragment">and change manually .reveal pre to margin: 0 auto; and box-shadow: none; so they will look like one block of code.
OR
Have you tried <code class="fragment">? If you use negative vertical margin to remove space between individual fragments and add the same background to <pre> as <code> has then you get what you want.
Result: