Clarity Datagrid Custom filter example - vmware-clarity

Does anyone have a complete example of a custom filter for the clarity datagrid? The custom filter documentation is lacking and I can't figure out how to get their example to work. Better yet, a stackblitz for the full datagrid demo would be amazing!

Hope this helps:
1) My Field model field.ts
export interface Field {
field_nbr: number;
fieldType: string;
dataType: string;
}
2) Utility file util-filters.ts -
import {ClrDatagridStringFilterInterface} from "#clr/angular";
//Models
import { Field } from '../models/field';
/**
* Class for filtering Field metadata in datagrids on filterType property of model
*/
export class FieldTypeFilter implements ClrDatagridStringFilterInterface<Field> {
accepts(field: Field, search: string):boolean {
return "" + field.fieldType == search
|| field.fieldType.toLowerCase().indexOf(search) >= 0;
}
}
3) model-component.html
<clr-datagrid [(clrDgSingleSelected)]="singleSelected" [clDgRowSelection]="false">
<clr-dg-column >
Field Type
<clr-dg-string-filter [clrDgStringFilter]="fieldTypeFilter"></clr-dg-string-filter>
</clr-dg-column>
<clr-dg-column ><ng-container *clrDgHideableColumn="{hidden: false}">Data Type</ng-container></clr-dg-column>
<clr-dg-placeholder>No matching fields found</clr-dg-placeholder>
<clr-dg-row *clrDgItems="let field of allFields" [clrDgItem]="field" (click)='openModal(field)'>
<clr-dg-cell>{{field.fieldType}}</clr-dg-cell>
<clr-dg-cell>{{field.dataType}}</clr-dg-cell>
</clr-dg-row>
</clr-datagrid>
4) model-component.ts
import { Component, OnInit, ViewChild } from '#angular/core';
import { NgIf } from '#angular/common';
import { Wizard } from "#clr/angular";
import { Observable } from 'rxjs';
//Models
import { Field } from '../models/field';
//Utilities
import { FieldTypeFilter } from "../utils/field-filters";
#Component({
selector: 'model',
templateUrl: './model.component.html',
providers: [],
styleUrls: ['../app.component.css']
})
export class ModelComponent {
private fieldTypeFilter = new FieldTypeFilter;
....
}

Edit 01/14/2022
Sorry, I moved some things around on stackblitz and we have updated the repo since this was written.
Here is where the custom filter lives for the demo: https://github.com/vmware/clarity/blob/angular/src/app/datagrid/utils/color-filter.ts
I'm not posting source code because there are 12 different files and some are pretty long (> 100 loc).
Here is a working reproduction of the full demo in the Clarity docs: https://stackblitz.com/edit/full-datagrid-demo
If you ever have questions about how a Clarity component works you can always dive into the source code for the demos we use for development and testing. Take a look here, I linked to the dev app we use for dev/testing so you know where I got the full datagrid code from. https://github.com/vmware/clarity/tree/master/src/dev/src/app

Related

How do I insert an Angular Component in CSS grid

I'm learning Angular, and I'm working on a project ,in which, I need to use a CSS grid layout. However, I'm trying to find a way to insert a component inside a grid with given grid-area.
I tried to do this, <app-slots></app-slots>, in app.component.html but the component <app-slots> was counted as one grid place only; even though, it's 42 places.
slots.component.html:
<div class="abc" *ngFor="let in of getArrayOfNumbers(42) ;let i = index" [style.grid-row] = "i+1" style = "height:20px" > {{in}} </div>
slots.component.ts:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-slots',
templateUrl: './slots.component.html',
styleUrls: ['../../app.component.css']
})
export class SlotsComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
getArrayOfNumbers(x: number){
var slots:number[] = [];
var a: number = x;
while(x != 0){
slots.push(x);
x--;
}
return slots;
}
}
Note: If something is not clear please tell me to add more info
can you just insert the component between your tags (instead of {{in}}), then send whatever updating variables from the .ts file through that using angular's binding feature ?
two way binding

Import .stories file into another .stories file with Storybook?

Can you import one .stories file into another .stories with Storybook?
Eg I have
/component1/component1.tsx
/component1/component1.stories.tsx
/component2/component2.tsx
/component2/component2.stories.tsx
I would like to also have a story for all of my components:
In /all-components/all-components.stories.tsx
import * as React from 'react';
import Component1Story from '../component1/component1.stories.tsx';
import Component2Story from '../component2/component2.stories.tsx';
export const Test = () => {
return (
<div>
<Component1Story />
<Component2Story />
</div>
);
};
export default {
title: 'Components',
};
I get this error:
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
Check the render method of storyFn.
this should be doable as your stories are just React components. Your problem is happening because you're trying to import the default from your module, which is actually just an object:
export default {
title: 'Components',
};
All stories are named exports, and you should import them with destructuring:
import { Component1Story } from '../component1/component1.stories';
import { Component2Story } from '../component2/component2.stories';
I created an example for you which shows a working scenario here.
p.s. It's interesting to know that starting with Storybook 6 there's a new mechanism to simplify the creation and reuse of stories so stay tuned! It's called Args.

How to extend and style existing LitElements?

We want to work with components from https://github.com/ing-bank/lion and style them to our needs. Their repo advertises with the components being extensible and minimally styled. However, I cannot seem to figure out how to actually style them. We tried using style element in the parent component, but we cant seem to style these components properly.
Could you give me an example of how to extend a component?
update after answer by #niiyeboah
After a very nice answer by #niiyeboah, I created the following class:
import {css, customElement} from 'lit-element'
import {LionButton} from '#lion/button'
#customElement('my-custom-button')
class MyCustomButton extends LionButton {
static get styles() {
return [
super.styles,
css`
:host {
background-color: red;
}
`,
]
}
constructor() {
super()
}
}
However, now it just shows be the button completely unstyled, i.e. only the text. Does anyone know whats happening?
They provide an example of how to extend and style their components on this page.
For tabs, the code will look something like this:
import { css } from 'lit-element';
import { LionTabs } from '#lion/tabs';
export class MyTabs extends LionTabs {
static get styles() {
return [
super.styles,
css`
/* my stylings */
`
];
}
}
customElements.define('my-tabs', MyTabs);
The ING Lion team has a Slack channel: https://www.polymer-project.org/slack-invite
for support questions.
It is the #lion sub-channel in the Polymer Project Slack

Firebase angularfire2 get object from database

I have a problem using an object i get from my firebase db.
I can recieve the json file without any problems as you can see on the picture below.
https://i.gyazo.com/6c1c69aca47f92a4e1029bb019042ab2.png
<h1>{{ item | async | json}}</h1>
the above code is in /src/app/app.component.html ,
this recieves the item object from /src/app/app.component.ts
import { Component } from '#angular/core';
import { AngularFire, FirebaseObjectObservable } from 'angularfire2';
#Component({
moduleId: module.id,
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css']
})
export class AppComponent {
item: FirebaseObjectObservable<any>;
constructor(af: AngularFire) {
this.item = af.database.object('/releases/');
}
}
I also have tried using item.name.$value but it doesn't work. I would want to get the values in the json file. And be able to use them in the website.
First you don't need the beginning and ending slash when searching for the object, this will work:
af.database.object('releases')
Next, you don't need the json pipe because firebase objects are already in json notation. Your html can look like this:
<h1>{{ item | async }}</h1>
Typically, however, instead of using your firebase async object directly on your template, you would pass it into a presentation component (also known as a dumb component). The presentation component doesn't need to know anything about the asynchronous behavior of your object, it just needs to handle how to generate the html. This is a common pattern when dealing with async objects in your template.
So your html would become:
<my-child-component [item]="item | async">
The child component:
#Component({
selector: 'my-child-component',
template: '<h1>{{ item }}</h1>'
})
export class MyChildComponent {
#Input() item: any;
...
as described here
https://github.com/angular/angularfire2/blob/master/docs/2-retrieving-data-as-objects.md#retrieve-data
try:
<h1>{{ (item | async)?.gore}}</h1>

Dynamic styleUrls in angular 2?

Is it possible to dynamically inject urls to stylesheets into a component?
Something like:
styleUrls: [
'stylesheet1.css',
this.additionalUrls
]
or (wishful thinking and note that this is just fake code):
export class MyComponent implements dynamicUrls {
ngDynamicUrls() {
this.inject(['anotherStylesheet.css', 'anotherStylesheet2.css']);
}
}
Because if you're gonna be able to override certain styles from stylesheet1 without having access to it, how are you supposed to do that? My only idea is to have dynamic styleUrls somehow but I don't think this is even possible from what I could find.
Any ideas?
It's possible in some maybe hack way it worked for me. You can manipulate Angular 2 Component decorator, create your own and return Angular's decorator with your properties.
import { Component } from '#angular/core';
export interface IComponent {
selector: string;
template?: string;
templateUrl?: string;
styles?: string[];
styleUrls?: string[];
directives?: any;
providers?: any;
encapsulation?: number;
}
export function CustomComponent( properties: IComponent): Function {
let aditionalStyles: string;
try {
aditionalStyles = require(`path to aditional styles/${ properties.selector }/style/${ properties.selector }.${ GAME }.scss`);
properties.styles.push(aditionalStyles);
} catch (err) {
console.warn(err)
}
}
return Component( properties );
}
And in your component replace default angular 2 #Component with new one.
import { CustomComponent } from 'path to CustomComponent';
#CustomComponent({
selector: 'home',
templateUrl: './template/home.template.html',
styleUrls: [ './style/home.style.scss']
})
export class ......
I have found a solution:
1. I have changed the styleurls to styles in the component decorator.
2. I will get my variable.
3. I will use the require command in my decorator.
import { Component } from '#angular/core';
import { environment } from '../environments/environment';
let lang = environment['lang'];
#Component({
selector: 'app',
templateUrl: './app.component.html',
styles: [require('./app.component.css'), require('./app.component.' + lang + '.css')]
})
export class AppComponent {
constructor() { }
}
In this basic example I have imported the environment variable and changed the css string dynamically.
I used to have the same need to dynamically inject urls to stylesheets and eventually ended to initialize a component for each variable css (in my case 3 differents styles) with empty template and use them in my app component with ngIf condition.
Thanks to the use of property "encapsulation: ViewEncapsulation.None", the style of the selected component is then added to the header of the page and enable to get the correct renderer for the whole page.
I don't think you can have dynamic stylesheet URLs, because you cannot access your class property or method inside #Component decorator.
But you can achieve your goal by having dynamic style classes in your template.
I used the stylesheet link in the html template with ngIf condition, it worked for me.
<link rel='stylesheet' href="/stylesheets/classicTheme.css" *ngIf="theme === 'classic' " />
<link rel='stylesheet' href="/stylesheets/styleTheme.css" *ngIf="theme === 'style' " />

Resources