Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: (core) introduce Card component #3344

Merged
merged 16 commits into from
Sep 25, 2020

Conversation

dimamarksman
Copy link
Contributor

@dimamarksman dimamarksman commented Sep 21, 2020

Please provide a link to the associated issue.

Closes: #3344

Please provide a brief summary of this pull request.

Introduce core standard card component.

Please check whether the PR fulfills the following requirements

Documentation checklist:

  • Documentation Examples
  • Stackblitz works for all examples

@netlify
Copy link

netlify bot commented Sep 21, 2020

Deploy preview for fundamental-ngx ready!

Built with commit 59d5451

https://deploy-preview-3344--fundamental-ngx.netlify.app

@salarenko salarenko requested review from fkolar, KevinOkamoto and a team September 21, 2020 13:58
@salarenko salarenko added the core Core library specific issues label Sep 21, 2020
@salarenko salarenko added this to In progress in Development via automation Sep 21, 2020
@salarenko salarenko added this to the Sprint 46 - Montreal milestone Sep 21, 2020
Copy link
Member

@KevinOkamoto KevinOkamoto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments.

Comment on lines 1 to 12
<fd-toolbar size="compact" [shouldOverflow]="true" fdType="transparent" [clearBorder]="true">
<!--
<ng-content> approach does not work with "overflow" as we have to assign
"fd-toolbar-item" directive to each fd-button to make it working.
The ContentChildren(FdButton) list approach with rendering in the template
does not work as we can not access FdButton projected content and render it here
withing a loop.
We need to find a way to make button projected content available here to keep
control over its rendering in order to make working overflow and force some options
-->
<ng-content></ng-content>
</fd-toolbar>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be easier to have the application developer (user) provide the whole fd-toolbar as ng-content instead of trying to internalize here? It's not as convenient, but may be easier for us.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved toolbar out of footer, so app developer is responsible to add it properly

Comment on lines 25 to 33
private _addClassName(element: HTMLElement, className: string): void {
this._renderer.addClass(element, className);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this extra function? Can we just call this._renderer.addClass(element, className) directly in _addClassNameToHostElement as is done in other components?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed it so now it implements cssClassBuilder interface since it was requested by other reviewers

<fd-card-counter>3 of 10</fd-card-counter>
</fd-card-header>
<fd-card-content>
<ul>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the card content should display some compact components since there is no discernible difference in this example

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added list in compact mode

<fd-avatar image="http://lorempixel.com/400/400/nature/4/"></fd-avatar>
<fd-card-title>Card Title</fd-card-title>
<fd-card-subtitle>Card Subtitle</fd-card-subtitle>
<fd-card-counter>1 of 5</fd-card-counter>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per the styles lib this is actually an "object status". You should be using the fd-object-status directive for this, and add an input to the object status directive called 'isCardCounter' that applies the fd-card__counter class is true.

<span fd-object-status [isCardCounter]="true">1 of 5</span>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it's a good idea to add specific isCardCounter option to fd-object-status.
I believe object-status should know nothing about card component.
Instead we can add status option to fd-card-counter which will support the same values as fd-object-status directive.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about having @ContentChildren('fd-status-object') in fd-card-header and whenever there is fd-object-status add fd-card__counter class into this element?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have a predefined selector for that anyway to make it explicit, having fd-object-status that plays a role of card-counter is not obvious and does not look consistently.
So if we have to make it as a directive user needs to add fd-object-status by its own.
If we are going to make it as a component we could hide it in the template of component and expose an input for that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taking into account that you suggest stick with a directive approach for the rest staff (title, subtitle) we should make it directive as well, what do you think @JKMarkowski @mikerodonnell89 ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dimamarksman I think you can

  • keep it as compnoent and put fd-object-status into template, or
  • change it to directive and somehow extend fd-object-status, to keep same inputs. And maybe overwrite cssClassBuilder functions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to a directive with status input to support object-status modifiers

import { CLASS_NAME } from './constants';

@Component({
selector: 'fd-card-counter',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this component can be deleted, see my other comment about fd-object-status

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed it to a directive, please see my comments above

<fd-card cardType="analytical">
<fd-card-header
>Describes the type of
<fd-card-title>Projected revenue</fd-card-title>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should adhere to what we're doing with fd-tile which is to have these be directives rather than components, so instead you'd see <h1 fd-card-title> or <div fd-card-kpi-header>, etc. Maybe the argument could be made that tile should actually be doing what you're doing here, and I'm open to hearing that argument but we should definitely be consistent across these two components as they're very similar

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's about following the gitbook specs. It can be for sure transformed to directive, While setting specifications I was almost sure that this fd-card-title will need to keep some additional template, but there is only ng-content. Could you please transform it to directive? Just to let user decide about the markup

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed it to directives


/** Background image resource: url or base64. */
@Input()
set image(value: string) {
this._setImage(value);
}
get image(): string {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not understand the purpose of the changes to this file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is needed to make the avatar image accessble here in the template
https://github.com/SAP/fundamental-ngx/pull/3344/files#diff-df9fe7dae64471bbb9f2e6b9e980a247R7


/**@hidden */
private _addClassNameToHostElement(className: string): void {
this._renderer.addClass(this._elementRef.nativeElement, className);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should use cssClassBuilder (same throughout this pr)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's only one class you can use event @HostBinding(), but I would like to hear the reason why renderer is used there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to CssClassBuilder

Development automation moved this from In progress to Review in progress Sep 21, 2020
@droshev
Copy link
Contributor

droshev commented Sep 22, 2020

This should be feat

@dimamarksman
Copy link
Contributor Author

This should be feat

Sorry, didn't get it

Copy link
Contributor

@JKMarkowski JKMarkowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello @dimamarksman, Great Job! I added couple of comments, let me know if something is not clear.
Also let's consider using CssClassBuilder in directives/components

Comment on lines 9 to 11
<li>Card content 1</li>
<li>Card content 2</li>
<li>Card content 3</li>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about just placing compact list component there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added list component

<fd-card-counter>1 of 5</fd-card-counter>
</fd-card-header>
<fd-card-content>
<ul>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you place list there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

<fd-avatar image="http://lorempixel.com/400/400/nature/4/"></fd-avatar>
<fd-card-title>Card Title</fd-card-title>
<fd-card-subtitle>Card Subtitle</fd-card-subtitle>
<fd-card-counter>1 of 5</fd-card-counter>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about having @ContentChildren('fd-status-object') in fd-card-header and whenever there is fd-object-status add fd-card__counter class into this element?

<fd-card cardType="analytical">
<fd-card-header
>Describes the type of
<fd-card-title>Projected revenue</fd-card-title>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's about following the gitbook specs. It can be for sure transformed to directive, While setting specifications I was almost sure that this fd-card-title will need to keep some additional template, but there is only ng-content. Could you please transform it to directive? Just to let user decide about the markup

<fd-card-header
>Describes the type of
<fd-card-title>Projected revenue</fd-card-title>
<fd-card-subtitle>Values include taxes | USD</fd-card-subtitle>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is same case as title component. It would be great to make it as directive

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed it to directive


import { CLASS_NAME } from './constants';

@Component({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check my comment regarding title/subtitle

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's only one class you can use event @HostBinding(), but I would like to hear the reason why renderer is used there.

@HostBinding() creates a binding that should be watched by angular, so if we want to add a static class to the host element only we can do it by renderer, that's more efficient way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So performace purposes, that's fine for me

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed it to CssClassBuilder

import { CLASS_NAME } from './constants';

@Component({
selector: 'fd-card-subtitle',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check my comment regarding title/subtitle


import { CLASS_NAME } from './constants';

@Component({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check my comment regarding title/subtitle

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines 48 to 53
set cardType(cardType: CardType) {
this._setCardType(cardType);
}
get cardType(): CardType {
return this._cardType;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't be much easier for you to use CssClassBuilder?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not use CssClassBuilder intentionally cause as far as I know Frank does not like this approach and try to avoid it in the platform project. To be honest I'm not a big fun of this too cause this approach potentially might have some performance issues, sometimes can lead to not obvious bugs

But this is not the platform project so I switched to CssClassBuilder interface.

Comment on lines 1 to 25
export const CLASS_NAME = {
card: 'fd-card',
cardCompact: 'fd-card--compact',
cardHeader: 'fd-card__header',
cardTitle: 'fd-card__title',
cardSubtitle: 'fd-card__subtitle',
cardSecondSubtitle: 'fd-card__second-subtitle',

cardAnalyticalArea: 'fd-card__analytics-area',
cardAnalytics: 'fd-card__analytics',
cardAnalyticsText: 'fd-card__analytics-text',
cardAnalyticsContent: 'fd-card__analytics-content',
cardAnalyticsKpiValue: 'fd-numeric-content__kpi',
cardAnalyticsScaleIcon: 'fd-numeric-content__scale-arrow',
cardAnalyticsScaleText: 'fd-numeric-content__scale-text',

cardCounter: 'fd-card__counter',
cardBadge: 'fd-card__badge',
cardContent: 'fd-card__content',
cardFooter: 'fd-card__footer',
cardLoader: 'fd-card__loader'
} as const;

export type CardType = 'standard' | 'component' | 'analytical' | 'list' | 'table' | 'object' | 'quickView' | 'linkList';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of it, keeping all of class names in one place

Copy link
Contributor

@JKMarkowski JKMarkowski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - The only thing you can do there is to change name of spec files. Some of them are still component, when .ts file is directive

@dimamarksman
Copy link
Contributor Author

LGTM - The only thing you can do there is to change name of spec files. Some of them are still component, when .ts file is directive

Thank you!
Spec files have been renamed.

Copy link
Member

@mikerodonnell89 mikerodonnell89 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changes look good 👍

Development automation moved this from Review in progress to Reviewer approved Sep 23, 2020
Copy link
Member

@KevinOkamoto KevinOkamoto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@InnaAtanasova InnaAtanasova changed the title fix: (core) introduce card component fix: (core) introduce Card component Sep 24, 2020
@@ -0,0 +1,25 @@
export const CLASS_NAME = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very smart!!!!! I like the idea

@import '~fundamental-styles/dist/numeric-content';
// @import '~fundamental-styles/dist/card';

// TODO delete it once card styles is released
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be deleted now since we brought 0.12

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@droshev droshev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great Work! We brought styles version 0.12 so you can delete the copy of CSS

@droshev droshev merged commit bc0ebca into SAP:master Sep 25, 2020
JKMarkowski pushed a commit that referenced this pull request Sep 25, 2020
* setup card module

* [wip] in progress

* card [wip]

* [wip]

* add kpi components

* [wip] tests

* add tests [wip]

* add api files

* add onPush

* make some components as directives

* add object-status to counter

* minor

* minor

* rename unit test files

* use fundamental styles

* formatting
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Core library specific issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants