Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 58 additions & 2 deletions etc/lime-elements.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,21 @@ export namespace Components {
"maxLinesSecondaryText": number;
"type": ListType;
}
export interface LimelListItem {
"actions"?: ListItem['actions'];
"badgeIcon": boolean;
"disabled": boolean;
"icon"?: string | ListItem['icon'];
"iconSize": IconSize;
"image"?: ListItem['image'];
"language": Languages;
"primaryComponent"?: ListItem['primaryComponent'];
"secondaryText"?: string;
"selected": boolean;
"text": string;
"type": 'listitem' | 'menuitem' | 'option' | 'radio' | 'checkbox';
"value"?: any;
}
export interface LimelMarkdown {
"lazyLoadImages": boolean;
"value": string;
Expand All @@ -553,12 +568,16 @@ export namespace Components {
"searcher": MenuSearcher;
"surfaceWidth": SurfaceWidth;
}
export interface LimelMenuItemMeta {
"badge"?: string | number;
"commandText"?: string;
"showChevron": boolean;
}
// (undocumented)
export interface LimelMenuList {
"badgeIcons": boolean;
"iconSize": IconSize;
"items": Array<MenuItem | ListSeparator>;
"maxLinesSecondaryText": number;
}
// (undocumented)
export interface LimelMenuSurface {
Expand Down Expand Up @@ -1185,10 +1204,14 @@ export namespace JSX {
// (undocumented)
"limel-list": LimelList;
// (undocumented)
"limel-list-item": LimelListItem;
// (undocumented)
"limel-markdown": LimelMarkdown;
// (undocumented)
"limel-menu": LimelMenu;
// (undocumented)
"limel-menu-item-meta": LimelMenuItemMeta;
// (undocumented)
"limel-menu-list": LimelMenuList;
// (undocumented)
"limel-menu-surface": LimelMenuSurface;
Expand Down Expand Up @@ -1670,6 +1693,25 @@ export namespace JSX {
"onSelect"?: (event: LimelListCustomEvent<ListItem | ListItem[]>) => void;
"type"?: ListType;
}
export interface LimelListItem {
"actions"?: ListItem['actions'];
"badgeIcon"?: boolean;
"disabled"?: boolean;
"icon"?: string | ListItem['icon'];
"iconSize"?: IconSize;
"image"?: ListItem['image'];
"language"?: Languages;
"onInteract"?: (event: LimelListItemCustomEvent<{
selected: boolean;
item: ListItem;
}>) => void;
"primaryComponent"?: ListItem['primaryComponent'];
"secondaryText"?: string;
"selected"?: boolean;
"text"?: string;
"type"?: 'listitem' | 'menuitem' | 'option' | 'radio' | 'checkbox';
"value"?: any;
}
export interface LimelMarkdown {
"lazyLoadImages"?: boolean;
"value"?: string;
Expand All @@ -1692,12 +1734,16 @@ export namespace JSX {
"searcher"?: MenuSearcher;
"surfaceWidth"?: SurfaceWidth;
}
export interface LimelMenuItemMeta {
"badge"?: string | number;
"commandText"?: string;
"showChevron"?: boolean;
}
// (undocumented)
export interface LimelMenuList {
"badgeIcons"?: boolean;
"iconSize"?: IconSize;
"items"?: Array<MenuItem | ListSeparator>;
"maxLinesSecondaryText"?: number;
"onInteract"?: (event: LimelMenuListCustomEvent<MenuItem>) => void;
"onSelect"?: (event: LimelMenuListCustomEvent<MenuItem>) => void;
}
Expand Down Expand Up @@ -2267,6 +2313,16 @@ export interface LimelListCustomEvent<T> extends CustomEvent<T> {
target: HTMLLimelListElement;
}

// Warning: (ae-missing-release-tag) "LimelListItemCustomEvent" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export interface LimelListItemCustomEvent<T> extends CustomEvent<T> {
// (undocumented)
detail: T;
// (undocumented)
target: HTMLLimelListItemElement;
}

// Warning: (ae-missing-release-tag) "LimelMenuCustomEvent" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
Prop,
} from '@stencil/core';
import { ActionBarItem } from '../../action-bar/action-bar.types';
import { ListSeparator } from '../../list/list-item.types';
import { ListSeparator } from '../../list-item/list-item.types';
import { createRandomString } from '../../../util/random-string';
import {
makeEnterClickable,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Component, Prop, h, Event, EventEmitter } from '@stencil/core';
import { ActionBarItem } from '../../action-bar/action-bar.types';
import { ListSeparator } from '../../list/list-item.types';
import { ListSeparator } from '../../list-item/list-item.types';
import { MenuItem, OpenDirection } from '../../menu/menu.types';
import { LimelMenuCustomEvent } from '../../../components';
import { Icon } from '../../../global/shared-types/icon.types';
Expand Down
2 changes: 1 addition & 1 deletion src/components/action-bar/action-bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
State,
Element,
} from '@stencil/core';
import { ListSeparator } from '../list/list-item.types';
import { ListSeparator } from '../list-item/list-item.types';
import { MenuItem, OpenDirection } from '../menu/menu.types';
import { ActionBarItem } from './action-bar.types';
import { Languages } from './../date-picker/date.types';
Expand Down
2 changes: 1 addition & 1 deletion src/components/action-bar/is-item.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ListSeparator } from '../list/list-item.types';
import { ListSeparator } from '../list-item/list-item.types';
import { ActionBarItem } from './action-bar.types';
import { isItem } from './is-item';

Expand Down
2 changes: 1 addition & 1 deletion src/components/action-bar/is-item.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ActionBarItem } from './action-bar.types';
import { ListSeparator } from '../list/list-item.types';
import { ListSeparator } from '../list-item/list-item.types';

/**
*
Expand Down
2 changes: 1 addition & 1 deletion src/components/chip-set/chip.types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Image } from '../../global/shared-types/image.types';
import { Icon } from '../../global/shared-types/icon.types';
import { MenuItem } from '../menu/menu.types';
import { ListSeparator } from '../list/list-item.types';
import { ListSeparator } from '../list-item/list-item.types';
import { Color } from '../../global/shared-types/color.types';

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from '@limetech/lime-elements';
import { MenuItem } from '../../menu/menu.types';
import { Chip } from '../chip.types';
import { ListSeparator } from '../../list/list-item.types';
import { ListSeparator } from '../../list-item/list-item.types';

const MENU_ITEMS: Array<MenuItem | ListSeparator> = [
{
Expand Down
2 changes: 1 addition & 1 deletion src/components/chip/chip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { ChipType, Chip as OldChipInterface } from '../chip-set/chip.types';
import { Image } from '../../global/shared-types/image.types';
import { isEmpty } from 'lodash-es';

import { ListSeparator } from '../list/list-item.types';
import { ListSeparator } from '../list-item/list-item.types';
import { LimelMenuCustomEvent, MenuItem } from '../../components';

interface ChipInterface extends Omit<OldChipInterface, 'id' | 'badge'> {
Expand Down
2 changes: 1 addition & 1 deletion src/components/file-viewer/file-viewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
Watch,
} from '@stencil/core';
import { Languages } from '../date-picker/date.types';
import { ListItem } from '../list/list-item.types';
import { ListItem } from '../list-item/list-item.types';
import translate from '../../global/translations';
import { detectExtension } from './extension-mapping';
import { Fullscreen } from './fullscreen';
Expand Down
2 changes: 1 addition & 1 deletion src/components/input-field/input-field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
TAB,
} from '../../util/keycodes';
import { InputType } from '../input-field/input-field.types';
import { ListItem } from '../list/list-item.types';
import { ListItem } from '../list-item/list-item.types';
import { getHref, getTarget, getRel } from '../../util/link-helper';
import { JSXBase } from '@stencil/core/internal';
import { createRandomString } from '../../util/random-string';
Expand Down
108 changes: 108 additions & 0 deletions src/components/list-item/examples/list-item-actions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { ListItem, MenuItem, ListSeparator } from '@limetech/lime-elements';
import { Component, h, Host, State } from '@stencil/core';

/**
* List item with action menu
*
* This example shows how a list item can have an action menu
* with multiple actions that can be triggered by the user.
*
* The consumer (e.g. `limel-list`) component should handle the interaction with the action menu.
* - Action menu items are `MenuItem` objects where `value` contains the actual `Action`
* - **Event bubbling:** `limel-menu` emits `select` events with the `MenuItem` as `event.detail`
* - **Natural forwarding:** The select event bubbles up and `limel-list` re-emits it
* - **Value extraction:** the final consumer of `limel-list`
* will eventually extract `event.detail.value` to get the actual `Action`
*
* :::note
* The action menu of the disabled items remains enabled!
* :::
*/
@Component({
tag: 'limel-example-list-item-actions',
shadow: true,
styleUrl: 'list-item-basic.scss',
})
export class ListItemActionsExample {
@State()
private disabled = false;

@State()
private lastInteraction: string = '';

@State()
private selectedItems: Set<number> = new Set();

private actionItems: Array<MenuItem | ListSeparator> = [
{ text: 'Edit', value: 'edit', icon: 'edit' },
{ text: 'Duplicate', value: 'duplicate', icon: 'copy' },
{ text: 'Share', value: 'share', icon: 'share' },
{ separator: true },
{ text: 'Delete', value: 'delete', icon: 'trash', disabled: true },
];

public render() {
return (
<Host>
<ul>
<limel-list-item
tabIndex={0}
value={1}
type="option"
selected={this.selectedItems.has(1)}
text="King of Tokyo"
secondaryText="A fun dice game for 2-6 players"
icon="gorilla"
actions={this.actionItems}
onInteract={this.onListItemInteraction}
disabled={this.disabled}
/>
<limel-list-item
tabIndex={0}
value={2}
type="option"
selected={this.selectedItems.has(2)}
text="Pandemic"
secondaryText="Cooperative board game where players work together to save the world"
icon="virus"
actions={this.actionItems}
onInteract={this.onListItemInteraction}
disabled={this.disabled}
/>
</ul>
<limel-example-controls>
<limel-switch
label="Disabled"
value={this.disabled}
onChange={this.setDisabled}
/>
</limel-example-controls>
<limel-example-value
label="Last interaction"
value={this.lastInteraction}
/>
</Host>
);
}

private onListItemInteraction = (
event: CustomEvent<{ selected: boolean; item: ListItem }>
) => {
const itemValue = event.detail.item.value as number;
const isSelected = event.detail.selected;

if (isSelected) {
this.selectedItems = new Set([...this.selectedItems, itemValue]);
} else {
this.selectedItems = new Set(
[...this.selectedItems].filter((id) => id !== itemValue)
);
}

this.lastInteraction = `Item "${event.detail.item.text}" interaction: selected=${isSelected}`;
};

private setDisabled = (event: CustomEvent<boolean>) => {
this.disabled = event.detail;
};
}
32 changes: 32 additions & 0 deletions src/components/list-item/examples/list-item-basic.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
@use '../../../style/mixins';

:host {
display: flex;
flex-direction: column;
border-radius: 0.25rem;
}

ul {
position: relative;
list-style: none;
padding: 1rem 1rem 2rem 1rem;
margin: 0;

background: url("data:image/svg+xml;charset=utf-8, <svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8' style='fill-rule:evenodd;'><path fill='rgba(186,186,192,0.16)' d='M0 0h4v4H0zM4 4h4v4H4z'/></svg>");
background-size: 0.5rem;

&.is-resizable {
overflow: hidden;
resize: horizontal;
max-width: calc(100% - 2rem);
min-width: 10rem;

&::after {
content: 'Resize me ⤵';
font-size: 0.75rem;
position: absolute;
right: 0.25rem;
bottom: 0.25rem;
}
}
}
38 changes: 38 additions & 0 deletions src/components/list-item/examples/list-item-basic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Component, h } from '@stencil/core';

/**
* Basic list item
*
* This example demonstrates the basic usage of the `limel-list-item`
* component with text and secondary text.
*
* :::important
* The list items are not focusable by default.
* The consumer should handle the focusability of the list items
* by dynamically setting and altering the `tabindex` attribute.
* :::
*/
@Component({
tag: 'limel-example-list-item-basic',
shadow: true,
styleUrl: 'list-item-basic.scss',
})
export class ListItemBasicExample {
public render() {
return (
<ul>
<limel-list-item
value={1}
tabindex="0"
text="Basic List Item"
/>
<limel-list-item
value={2}
tabindex="0"
text="This is the `text`"
secondaryText="This is the `secondaryText`"
/>
</ul>
);
}
}
Loading