From 2793a70e800650e9b1acafcac1cec05022273ad6 Mon Sep 17 00:00:00 2001 From: a11delavar Date: Mon, 4 Nov 2024 23:44:54 +0100 Subject: [PATCH 1/2] Proof of concept --- packages/List/List.ts | 15 +++++++-- packages/List/ListItem.ts | 33 +++++++++++++++---- packages/List/NavigationListItem.ts | 6 ++++ packages/List/SelectionListItemWithControl.ts | 18 +++------- packages/Menu/MenuItem.ts | 15 ++++++++- packages/Menu/NestedMenuItem.ts | 7 +++- packages/SelectField/Option.ts | 9 ++--- 7 files changed, 73 insertions(+), 30 deletions(-) diff --git a/packages/List/List.ts b/packages/List/List.ts index 92e43772..5c34c7e9 100644 --- a/packages/List/List.ts +++ b/packages/List/List.ts @@ -1,4 +1,4 @@ -import { Component, component, css, event, html } from '@a11d/lit' +import { Component, component, css, event, html, unsafeCSS } from '@a11d/lit' import { SlotController } from '@3mo/slot-controller' import { ListFocusController } from './ListFocusController.js' import { listItems } from './extensions.js' @@ -29,12 +29,23 @@ export class List extends Component { static override get styles() { return css` :host { - display: block; + display: grid; + grid-template-columns: auto 1fr auto; + column-gap: 16px; } :host(:focus) { outline: none; } + + ::slotted(*) { + grid-column: -1 / 1; + } + + ${unsafeCSS(List.itemRoles.map(role => `::slotted([role='${role}'])`).join(','))} { + grid-template-columns: subgrid; + display: grid; + } ` } diff --git a/packages/List/ListItem.ts b/packages/List/ListItem.ts index c7ceb421..878cbca9 100644 --- a/packages/List/ListItem.ts +++ b/packages/List/ListItem.ts @@ -11,6 +11,8 @@ import './ListItemRipple.js' * @attr preventClickOnSpace - Whether the list item should prevent click on space * * @slot - Default slot for content + * @slot start - Slot for content at the start + * @slot end - Slot for content at the end */ @component('mo-list-item') export class ListItem extends Component { @@ -32,10 +34,11 @@ export class ListItem extends Component { user-select: none; padding-inline: 1rem; padding-block: 0.48em; - display: flex; - gap: 1rem; align-items: center; min-height: 3rem; + /* For list-items without a list */ + display: flex; + gap: 16px; } :host([disabled]) { @@ -46,6 +49,19 @@ export class ListItem extends Component { :host(:focus) { outline: none; } + + slot[name=start], slot:not([name]), slot[name=end] { + display: inline-flex; + } + + slot:not([name]) { + /* For list-items without a list */ + flex: 1; + } + + slot[name=end] { + justify-content: end; + } ` } @@ -61,15 +77,18 @@ export class ListItem extends Component { return html` ${!this.focusRingActive ? html.nothing : html``} - ${this.iconTemplate} + ${this.startSlotDefaultContent} + ${this.endSlotDefaultContent} ` } - protected get iconTemplate() { - return !this.icon ? html.nothing : html` - - ` + protected get startSlotDefaultContent() { + return html.nothing + } + + protected get endSlotDefaultContent() { + return html.nothing } } diff --git a/packages/List/NavigationListItem.ts b/packages/List/NavigationListItem.ts index eca822a3..47ea7ff3 100644 --- a/packages/List/NavigationListItem.ts +++ b/packages/List/NavigationListItem.ts @@ -20,6 +20,12 @@ export class NavigationListItem extends ListItem { } ` } + + protected override get startSlotDefaultContent() { + return !this.icon ? html.nothing : html` + + ` + } } declare global { diff --git a/packages/List/SelectionListItemWithControl.ts b/packages/List/SelectionListItemWithControl.ts index 13805e5e..2618ebd5 100644 --- a/packages/List/SelectionListItemWithControl.ts +++ b/packages/List/SelectionListItemWithControl.ts @@ -1,23 +1,15 @@ -import { html, type HTMLTemplateResult, property } from '@a11d/lit' +import { type HTMLTemplateResult, property } from '@a11d/lit' import { SelectionListItem } from './SelectionListItem.js' export abstract class SelectionListItemWithControl extends SelectionListItem { @property() selectionControlAlignment: 'start' | 'end' = 'end' - protected override get template() { - return html` - ${this.selectionControlAlignment === 'start' ? this.selectionControlContainerTemplate : html.nothing} - ${super.template} - ${this.selectionControlAlignment === 'end' ? this.selectionControlContainerTemplate : html.nothing} - ` + protected override get startSlotDefaultContent() { + return this.selectionControlAlignment === 'start' ? this.selectionControlTemplate : super.startSlotDefaultContent } - private get selectionControlContainerTemplate() { - return html` -
- ${this.selectionControlTemplate} -
- ` + protected override get endSlotDefaultContent() { + return this.selectionControlAlignment === 'end' ? this.selectionControlTemplate : super.endSlotDefaultContent } protected abstract get selectionControlTemplate(): HTMLTemplateResult diff --git a/packages/Menu/MenuItem.ts b/packages/Menu/MenuItem.ts index e0298fbe..644ef133 100644 --- a/packages/Menu/MenuItem.ts +++ b/packages/Menu/MenuItem.ts @@ -11,7 +11,20 @@ export class MenuItem extends ListItem { static override get styles() { return css` ${super.styles} - :host { min-height: 2.25rem; } + + :host { + min-height: 2.25rem; + } + ` + } + + protected override get startSlotDefaultContent() { + return this.iconTemplate + } + + protected get iconTemplate() { + return !this.icon ? html.nothing : html` + ` } } diff --git a/packages/Menu/NestedMenuItem.ts b/packages/Menu/NestedMenuItem.ts index c3750530..db165eba 100644 --- a/packages/Menu/NestedMenuItem.ts +++ b/packages/Menu/NestedMenuItem.ts @@ -77,13 +77,18 @@ export class NestedMenuItem extends MenuItem { ` } + protected override get endSlotDefaultContent() { + return !this.hasSubMenu ? html.nothing : html` + + ` + } + protected get hasSubMenu() { return this.slotController.hasAssignedContent('submenu') } protected get subMenuTemplate() { return !this.hasSubMenu ? html.nothing : html` - ) => { e.stopImmediatePropagation(); !['Left', 'ArrowLeft'].includes(e.detail.key) ? void 0 : this.setOpen(false) }} diff --git a/packages/SelectField/Option.ts b/packages/SelectField/Option.ts index c18af767..fe566e25 100644 --- a/packages/SelectField/Option.ts +++ b/packages/SelectField/Option.ts @@ -67,7 +67,7 @@ export class Option extends SelectionListItem { } :host([data-search-no-match]) { - display: none; + display: none !important; pointer-events: none; } @@ -78,11 +78,8 @@ export class Option extends SelectionListItem { ` } - protected override get template() { - return html` - ${super.template} - ${this.checkboxTemplate} - ` + protected override get endSlotDefaultContent() { + return this.checkboxTemplate } protected get checkboxTemplate() { From bcf6dd439fad5d623687022881bbb55729702f1a Mon Sep 17 00:00:00 2001 From: a11delavar Date: Mon, 4 Nov 2024 23:46:11 +0100 Subject: [PATCH 2/2] Migrate stories --- packages/ContextMenu/ContextMenu.stories.ts | 18 +++++++++--------- packages/List/List.stories.ts | 18 +++++++++++------- packages/Menu/Menu.stories.ts | 8 ++++---- packages/SelectField/FieldSelect.stories.ts | 6 +++--- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/packages/ContextMenu/ContextMenu.stories.ts b/packages/ContextMenu/ContextMenu.stories.ts index 8ad7a8c7..6239ff3b 100644 --- a/packages/ContextMenu/ContextMenu.stories.ts +++ b/packages/ContextMenu/ContextMenu.stories.ts @@ -9,22 +9,22 @@ export default { package: p, } as Meta -const keyboardShortcut = (shortcut: string) => html`${shortcut}` +const keyboardShortcut = (shortcut: string) => html`${shortcut}` const mainContextMenu = html` - - Cut + + Cut ${keyboardShortcut('Ctrl + X')} - - Copy + + Copy ${keyboardShortcut('Ctrl + C')} - - Paste + + Paste ${keyboardShortcut('Ctrl + V')}
@@ -44,8 +44,8 @@ const mainContextMenu = html` const specialContextMenu = html` - - Another Item + + Another Item ` diff --git a/packages/List/List.stories.ts b/packages/List/List.stories.ts index 93d78b06..cff63e70 100644 --- a/packages/List/List.stories.ts +++ b/packages/List/List.stories.ts @@ -12,7 +12,7 @@ export default { } as Meta const keyboardShortcut = (shortcut: string) => html` - ${shortcut} + ${shortcut} ` const separator = html` @@ -20,25 +20,29 @@ const separator = html` ` const items = html` - - Inbox + + + Inbox ${keyboardShortcut('Ctrl + I')} - - Drafts + + + Drafts ${keyboardShortcut('Ctrl + D')} ${separator} Trash Spam ${separator} - + + Personalization - Upgrade to Pro! - + + Logout ` diff --git a/packages/Menu/Menu.stories.ts b/packages/Menu/Menu.stories.ts index 94c257c3..828f01a6 100644 --- a/packages/Menu/Menu.stories.ts +++ b/packages/Menu/Menu.stories.ts @@ -45,19 +45,19 @@ export const WithCustomContainer: StoryObj = { ` } -const keyboardShortcut = (shortcut: string) => html`${shortcut}` +const keyboardShortcut = (shortcut: string) => html`${shortcut}` const items = html` - Cut + Cut ${keyboardShortcut('Ctrl + X')} - Copy + Copy ${keyboardShortcut('Ctrl + C')} - Paste + Paste ${keyboardShortcut('Ctrl + V')} diff --git a/packages/SelectField/FieldSelect.stories.ts b/packages/SelectField/FieldSelect.stories.ts index e688c3e3..51a53fd2 100644 --- a/packages/SelectField/FieldSelect.stories.ts +++ b/packages/SelectField/FieldSelect.stories.ts @@ -21,7 +21,7 @@ export const Select: StoryObj = { ${countries.map(country => html` - + ${country.label} `)} @@ -36,7 +36,7 @@ export const FreeInput: StoryObj = { ${countries.map(country => html` - + ${country.label} `)} @@ -51,7 +51,7 @@ export const PreSelectedValue: StoryObj = { ${countries.map(country => html` - + ${country.label} `)}