Skip to content

Commit

Permalink
feat(list): add support for displaying pictures in the list items
Browse files Browse the repository at this point in the history
  • Loading branch information
Befkadu1 committed Jan 9, 2025
1 parent a900aae commit dea4059
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 0 deletions.
109 changes: 109 additions & 0 deletions src/components/list/examples/list-pictures.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { ListItem } from '@limetech/lime-elements';
import { Component, h, State } from '@stencil/core';

/**
* List with Pictures and Icons
*
* :::note
* While it's technically possible to display both images and icons simultaneously
* for each list item, we recommend against using identical icons across all items.
* Repeating the same icon for every list item adds unnecessary visual clutter
* without providing additional value.
*
* Icons, like images, should serve to help users quickly differentiate between
* list items. They are most effective when each icon uniquely identifies
* the type or category of its list item.
* :::
*/
@Component({
tag: 'limel-example-list-pictures',
shadow: true,
})
export class PictureListExample {
private items: Array<ListItem<number>> = [
{
text: 'Lucy Chyzhova',
secondaryText: 'UX Designer',
value: 1,
icon: {
name: 'santas_hat',
color: 'rgb(var(--color-coral-default))',
},
image: {
src: 'https://lundalogik.github.io/lime-elements/780af2a6-d3d1-4593-8642-f03210d09271.png',
alt: 'A picture of Lucy Chyzhova, UX designer at Lime Technologies',
},
},
{
text: 'Kiarokh Moattar',
secondaryText: 'Product Designer',
value: 2,
icon: {
name: 'party_hat',
color: 'rgb(var(--color-pink-default))',
},
image: {
src: 'https://lundalogik.github.io/lime-elements/2e86c284-d190-4c41-8da2-4de50103a0cd.png',
alt: 'A picture of Kiarokh Moattar, Product Designer at Lime Technologies',
},
},
{
text: 'Adrian Schmidt',
secondaryText: 'Engineer',
value: 3,
icon: 'viking_helmet',
image: {
src: 'https://lundalogik.github.io/lime-elements/0e6f74c0-11d9-465b-aac6-44f33da3cb7c.png',
alt: 'A picture of Adrian Schmidt, Head of Smooth Operations at Lime Technologies',
},
},
{
text: 'Befkadu Degefa',
secondaryText: 'Engineer',
value: 4,
icon: {
name: 'bowler_hat',
color: 'rgb(var(--color-sky-default))',
},
},
];

@State()
private badgeIcons: boolean = false;

@State()
private hasStripedRows: boolean = true;

public render() {
return [
<limel-list
items={this.items}
type="selectable"
badgeIcons={this.badgeIcons}
class={this.hasStripedRows ? 'has-striped-rows' : ''}
/>,
<limel-example-controls>
<limel-checkbox
checked={this.badgeIcons}
label="badge icons"
onChange={this.setBadgeIcons}
/>
<limel-checkbox
checked={this.hasStripedRows}
label="striped rows"
onChange={this.setHasStripedRows}
/>
</limel-example-controls>,
];
}

private setBadgeIcons = (event: CustomEvent<boolean>) => {
event.stopPropagation();
this.badgeIcons = event.detail;
};

private setHasStripedRows = (event: CustomEvent<boolean>) => {
event.stopPropagation();
this.hasStripedRows = event.detail;
};
}
11 changes: 11 additions & 0 deletions src/components/list/list-renderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { CheckboxTemplate } from '../checkbox/checkbox.template';
import { ListRendererConfig } from './list-renderer-config';
import { RadioButtonTemplate } from './radio-button/radio-button.template';
import { getIconColor, getIconName } from '../icon/get-icon-props';
import { isEmpty } from 'lodash-es';

export class ListRenderer {
private defaultConfig: ListRendererConfig = {
Expand Down Expand Up @@ -152,6 +153,7 @@ export class ListRenderer {
{...attributes}
>
{this.renderIcon(this.config, item)}
{this.renderPicture(item)}
{this.getPrimaryComponent(item)}
{this.renderText(item)}
{this.twoLines && this.avatarList ? this.renderDivider() : null}
Expand Down Expand Up @@ -247,6 +249,15 @@ export class ListRenderer {
);
};

private renderPicture(item: ListItem) {
const image = item.image;
if (isEmpty(image)) {
return;
}

return <img src={image.src} alt={image.alt} loading="lazy" />;
}

private renderDivider = () => {
const classes = {
'mdc-deprecated-list-divider': true,
Expand Down
28 changes: 28 additions & 0 deletions src/components/list/list.scss
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,34 @@ $list-mdc-list-item: 0;
}
}

img {
flex-shrink: 0;
object-fit: cover;

border-radius: 50%;
width: 2rem;
height: 2rem;
box-shadow: 0 0 0 1px rgb(var(--contrast-800), 0.5);
}

.mdc-deprecated-list-item {
&:has(img) {
limel-icon {
position: absolute;
top: 0.125rem;
left: 0.125rem;
padding: 0.1875rem; // 3px
background-color: rgb(var(--contrast-200), 0.8);

&[badge] {
top: 0;
padding: 0;
scale: 0.6;
}
}
}
}

@import '../checkbox/checkbox.scss';

@import './radio-button/radio-button.scss';
Expand Down
1 change: 1 addition & 0 deletions src/components/list/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const { ACTION_EVENT } = listStrings;
* @exampleComponent limel-example-list-selectable
* @exampleComponent limel-example-list-icons
* @exampleComponent limel-example-list-badge-icons
* @exampleComponent limel-example-list-pictures
* @exampleComponent limel-example-list-checkbox
* @exampleComponent limel-example-list-checkbox-icons
* @exampleComponent limel-example-list-radio-button
Expand Down

0 comments on commit dea4059

Please sign in to comment.