-
Notifications
You must be signed in to change notification settings - Fork 290
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Angular Material Card component (#1082)
* Add Angular Material Card component This component consists of the following components: - card - card_header - card_content - card_actions I did not include card_footer since I couldn't tell what benefit it added, but we can added later if needed. I did not include an card_image component since it was easy enough to use image with width 100%. Closes #1080
- Loading branch information
1 parent
18b7c3d
commit 7a54883
Showing
38 changed files
with
592 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import mesop as me | ||
|
||
|
||
def load(e: me.LoadEvent): | ||
me.set_theme_mode("system") | ||
|
||
|
||
@me.page( | ||
on_load=load, | ||
security_policy=me.SecurityPolicy( | ||
allowed_iframe_parents=["https://google.github.io"], | ||
), | ||
path="/card", | ||
) | ||
def app(): | ||
with me.box( | ||
style=me.Style( | ||
display="flex", | ||
flex_direction="column", | ||
gap=15, | ||
margin=me.Margin.all(15), | ||
max_width=500, | ||
) | ||
): | ||
with me.card(appearance="outlined"): | ||
me.card_header( | ||
title="Grapefruit", | ||
subtitle="Kind of fruit", | ||
image="https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg", | ||
) | ||
me.image( | ||
style=me.Style( | ||
width="100%", | ||
), | ||
src="https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg", | ||
) | ||
with me.card_content(): | ||
me.text( | ||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed augue ultricies, laoreet nunc eget, ultricies augue. In ornare bibendum mauris vel sodales. Donec ut interdum felis. Nulla facilisi. Morbi a laoreet turpis, sed posuere arcu. Nam nisi neque, molestie vitae euismod eu, sollicitudin eu lectus. Pellentesque orci metus, finibus id faucibus et, ultrices quis dui. Duis in augue ac metus tristique lacinia." | ||
) | ||
|
||
with me.card_actions(align="end"): | ||
me.button(label="Add to cart") | ||
me.button(label="Buy") | ||
|
||
with me.card(appearance="raised"): | ||
me.card_header( | ||
title="Grapefruit", | ||
subtitle="Kind of fruit", | ||
image="https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg", | ||
image_type="small", | ||
) | ||
|
||
with me.card_content(): | ||
me.text( | ||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed augue ultricies, laoreet nunc eget, ultricies augue. In ornare bibendum mauris vel sodales. Donec ut interdum felis. Nulla facilisi. Morbi a laoreet turpis, sed posuere arcu. Nam nisi neque, molestie vitae euismod eu, sollicitudin eu lectus. Pellentesque orci metus, finibus id faucibus et, ultrices quis dui. Duis in augue ac metus tristique lacinia." | ||
) | ||
|
||
with me.card_actions(align="start"): | ||
me.button(label="Add to cart") | ||
me.button(label="Buy") | ||
|
||
with me.card(appearance="outlined"): | ||
me.card_header( | ||
title="Grapefruit", | ||
subtitle="Kind of fruit", | ||
image="https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg", | ||
image_type="medium", | ||
) | ||
|
||
with me.card_content(): | ||
me.text( | ||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed augue ultricies, laoreet nunc eget, ultricies augue. In ornare bibendum mauris vel sodales. Donec ut interdum felis. Nulla facilisi. Morbi a laoreet turpis, sed posuere arcu. Nam nisi neque, molestie vitae euismod eu, sollicitudin eu lectus. Pellentesque orci metus, finibus id faucibus et, ultrices quis dui. Duis in augue ac metus tristique lacinia." | ||
) | ||
|
||
with me.card_actions(align="start"): | ||
me.button(label="Add to cart") | ||
me.button(label="Buy") | ||
|
||
me.card_header( | ||
title="Grapefruit", | ||
image="https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg", | ||
image_type="large", | ||
) | ||
|
||
with me.card_content(): | ||
me.text( | ||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed augue ultricies, laoreet nunc eget, ultricies augue. In ornare bibendum mauris vel sodales. Donec ut interdum felis. Nulla facilisi. Morbi a laoreet turpis, sed posuere arcu. Nam nisi neque, molestie vitae euismod eu, sollicitudin eu lectus. Pellentesque orci metus, finibus id faucibus et, ultrices quis dui. Duis in augue ac metus tristique lacinia." | ||
) | ||
|
||
with me.card_actions(align="end"): | ||
me.button(label="Add to cart") | ||
me.button(label="Buy") | ||
|
||
me.card_header( | ||
title="Grapefruit", | ||
image_type="large", | ||
) | ||
|
||
with me.card_content(): | ||
me.text( | ||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed augue ultricies, laoreet nunc eget, ultricies augue. In ornare bibendum mauris vel sodales. Donec ut interdum felis. Nulla facilisi. Morbi a laoreet turpis, sed posuere arcu. Nam nisi neque, molestie vitae euismod eu, sollicitudin eu lectus. Pellentesque orci metus, finibus id faucibus et, ultrices quis dui. Duis in augue ac metus tristique lacinia." | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
## Overview | ||
|
||
Card is based on the [Angular Material card component](https://material.angular.io/components/card/overview). | ||
|
||
## Examples | ||
|
||
<iframe class="component-demo" src="https://google.github.io/mesop/demo/?demo=card" style="height: 200px"></iframe> | ||
|
||
```python | ||
--8<-- "demo/card.py" | ||
``` | ||
|
||
## API | ||
|
||
::: mesop.components.card.card.card | ||
::: mesop.components.card_content.card_content.card_header | ||
::: mesop.components.card_content.card_content.card_content | ||
::: mesop.components.card_actions.card_actions.card_actions |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
load("//mesop/components:defs.bzl", "mesop_component") | ||
|
||
package( | ||
default_visibility = ["//build_defs:mesop_internal"], | ||
) | ||
|
||
mesop_component( | ||
name = "card", | ||
) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<mat-card [appearance]="getAppearance()" [style]="getStyle()"> | ||
<ng-content></ng-content> | ||
</mat-card> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
syntax = "proto2"; | ||
|
||
package mesop.components.card; | ||
|
||
message CardType { | ||
optional string appearance = 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from typing import Literal | ||
|
||
import mesop.components.card.card_pb2 as card_pb | ||
from mesop.component_helpers import ( | ||
Style, | ||
insert_composite_component, | ||
register_native_component, | ||
) | ||
|
||
|
||
@register_native_component | ||
def card( | ||
*, | ||
appearance: Literal["outlined", "raised"] = "outlined", | ||
style: Style | None = None, | ||
key: str | None = None, | ||
): | ||
""" | ||
This function creates a card. | ||
Args: | ||
appearance: Card appearance style: outlined or raised. | ||
style: Style for the component. | ||
key: The component [key](../components/index.md#component-key). | ||
""" | ||
return insert_composite_component( | ||
key=key, | ||
type_name="card", | ||
style=style, | ||
proto=card_pb.CardType( | ||
appearance=appearance, | ||
), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import {MatCardModule} from '@angular/material/card'; | ||
import {Component, Input} from '@angular/core'; | ||
import { | ||
Key, | ||
Type, | ||
Style, | ||
} from 'mesop/mesop/protos/ui_jspb_proto_pb/mesop/protos/ui_pb'; | ||
import {CardType} from 'mesop/mesop/components/card/card_jspb_proto_pb/mesop/components/card/card_pb'; | ||
import {formatStyle} from '../../web/src/utils/styles'; | ||
|
||
@Component({ | ||
selector: 'mesop-card', | ||
templateUrl: 'card.ng.html', | ||
standalone: true, | ||
imports: [MatCardModule], | ||
}) | ||
export class CardComponent { | ||
@Input({required: true}) type!: Type; | ||
@Input() key!: Key; | ||
@Input() style!: Style; | ||
private _config!: CardType; | ||
|
||
ngOnChanges() { | ||
this._config = CardType.deserializeBinary( | ||
this.type.getValue() as unknown as Uint8Array, | ||
); | ||
} | ||
|
||
config(): CardType { | ||
return this._config; | ||
} | ||
|
||
getStyle(): string { | ||
return formatStyle(this.style); | ||
} | ||
|
||
getAppearance(): 'outlined' | 'raised' { | ||
return this.config().getAppearance() as 'outlined' | 'raised'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
load("//build_defs:defaults.bzl", "py_library") | ||
|
||
package( | ||
default_visibility = ["//build_defs:mesop_examples"], | ||
) | ||
|
||
py_library( | ||
name = "e2e", | ||
srcs = glob(["*.py"]), | ||
deps = [ | ||
"//mesop", | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import card_app as card_app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import mesop as me | ||
|
||
|
||
@me.page(path="/components/card/e2e/card_app") | ||
def app(): | ||
with me.card(appearance="outlined"): | ||
me.card_header( | ||
title="Grapefruit", | ||
subtitle="Kind of fruit", | ||
image="https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg", | ||
) | ||
me.image( | ||
style=me.Style( | ||
width="100%", | ||
), | ||
src="https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg", | ||
) | ||
with me.card_content(): | ||
me.text( | ||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed augue ultricies, laoreet nunc eget, ultricies augue. In ornare bibendum mauris vel sodales. Donec ut interdum felis. Nulla facilisi. Morbi a laoreet turpis, sed posuere arcu. Nam nisi neque, molestie vitae euismod eu, sollicitudin eu lectus. Pellentesque orci metus, finibus id faucibus et, ultrices quis dui. Duis in augue ac metus tristique lacinia." | ||
) | ||
|
||
with me.card_actions(align="end"): | ||
me.button(label="Add to cart") | ||
me.button(label="Buy") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import {test, expect} from '@playwright/test'; | ||
|
||
test.describe('Card', () => { | ||
test('renders card', async ({page}) => { | ||
await page.goto('/components/card/e2e/card_app'); | ||
expect( | ||
await page | ||
.locator('mat-card') | ||
.evaluate((el) => el.classList.contains('mat-mdc-card-outlined')), | ||
).toBeTruthy(); | ||
expect(await page.locator('mat-card-title').textContent()).toContain( | ||
'Grapefruit', | ||
); | ||
expect(await page.locator('mat-card-subtitle').textContent()).toContain( | ||
'Kind of fruit', | ||
); | ||
expect(await page.locator('mat-card-content').textContent()).toContain( | ||
'Lorem ipsum dolor sit amet', | ||
); | ||
expect( | ||
await page | ||
.locator('mat-card-actions') | ||
.evaluate((el) => | ||
el.classList.contains('mat-mdc-card-actions-align-end'), | ||
), | ||
).toBeTruthy(); | ||
expect(await page.getByText('Add to cart')).toHaveCount(1); | ||
expect(await page.getByText('Buy')).toHaveCount(1); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
load("//mesop/components:defs.bzl", "mesop_component") | ||
|
||
package( | ||
default_visibility = ["//build_defs:mesop_internal"], | ||
) | ||
|
||
mesop_component( | ||
name = "card_actions", | ||
) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<mat-card-actions [align]="getAlign()"> | ||
<ng-content></ng-content> | ||
</mat-card-actions> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
syntax = "proto2"; | ||
|
||
package mesop.components.card_actions; | ||
|
||
message CardActionsType { | ||
optional string align = 1; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
from typing import Literal | ||
|
||
import mesop.components.card_actions.card_actions_pb2 as card_actions_pb | ||
from mesop.component_helpers import ( | ||
insert_composite_component, | ||
register_native_component, | ||
) | ||
|
||
|
||
@register_native_component | ||
def card_actions( | ||
*, | ||
align: Literal["start", "end"], | ||
key: str | None = None, | ||
): | ||
""" | ||
This function creates a card_actions. | ||
This component is meant to be used with the `card` component. It is used for the | ||
bottom area of a card that contains action buttons. | ||
This component is a optional. It is mainly used as a convenience for consistent | ||
formatting with the card component. | ||
Args: | ||
align: Align elements to the left (start) or right (end). | ||
""" | ||
return insert_composite_component( | ||
key=key, | ||
type_name="card_actions", | ||
proto=card_actions_pb.CardActionsType( | ||
align=align, | ||
), | ||
) |
Oops, something went wrong.