Skip to content

Commit

Permalink
fix(list, list-item, list-item-group): improve drag experience by ind…
Browse files Browse the repository at this point in the history
…enting items (#9169)

**Related Issue:** #8242 #8667 #9058

## Summary

- Properly indents each list-item nested within another list or
list-item
- Removes transparent bg from handle, not necessary
- Updates internal table cell classes to remove padding being set by
default browser styles.
- Changes borders to use proper css borders instead of a 1px margin and
shadow
- Sets bg color of foreground 1 on list-item.
- Stretch action and handles slotted within a list-item.
- Removes padding from empty lists
- Remove unnecessary utils from list
- Add and improve screenshot tests
  • Loading branch information
driskull committed Apr 25, 2024
1 parent 193bb7d commit 88aab49
Show file tree
Hide file tree
Showing 10 changed files with 168 additions and 177 deletions.
8 changes: 8 additions & 0 deletions packages/calcite-components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2845,6 +2845,10 @@ export namespace Components {
* Sets the item as focusable. Only one item should be focusable within a list.
*/
"active": boolean;
/**
* Sets the item to display a border.
*/
"bordered": boolean;
/**
* When `true`, a close button is added to the component.
*/
Expand Down Expand Up @@ -10362,6 +10366,10 @@ declare namespace LocalJSX {
* Sets the item as focusable. Only one item should be focusable within a list.
*/
"active"?: boolean;
/**
* Sets the item to display a border.
*/
"bordered"?: boolean;
/**
* When `true`, a close button is added to the component.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
items-center
justify-center
self-stretch
border-none
bg-transparent;
border-none;
color: theme("borderColor.color.input");
padding-block: theme("spacing.3");
padding-inline: theme("spacing.1");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
:host {
@apply flex flex-col bg-foreground-1;
--calcite-list-item-spacing-indent: theme("spacing.4");
}

:host([filter-hidden]) {
Expand All @@ -15,20 +14,6 @@

.heading {
@apply p-0;
padding-inline-start: calc(
var(--calcite-list-item-spacing-indent) * var(--calcite-list-item-spacing-indent-multiplier)
);
}

::slotted(calcite-list-item) {
@apply shadow-border-top;
margin-block-start: 1px;
}

// removes shadow for the first item of the group for both filtered and unfiltered items.
::slotted(calcite-list-item:nth-child(1 of :not([hidden]))) {
@apply shadow-none;
margin-block-start: 0px;
}

@include base-component();
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
import {
Component,
Element,
Event,
EventEmitter,
h,
Host,
Prop,
State,
VNode,
} from "@stencil/core";
import { Component, Element, Event, EventEmitter, h, Host, Prop, VNode } from "@stencil/core";
import {
connectInteractive,
disconnectInteractive,
Expand All @@ -17,7 +7,6 @@ import {
updateHostInteraction,
} from "../../utils/interactive";
import { MAX_COLUMNS } from "../list-item/resources";
import { getDepth } from "../list-item/utils";
import { CSS } from "./resources";
/**
* @slot - A slot for adding `calcite-list-item` and `calcite-list-item-group` elements.
Expand Down Expand Up @@ -71,8 +60,6 @@ export class ListItemGroup implements InteractiveComponent {
// --------------------------------------------------------------------------

connectedCallback(): void {
const { el } = this;
this.visualLevel = getDepth(el, true);
connectInteractive(this);
}

Expand All @@ -92,23 +79,18 @@ export class ListItemGroup implements InteractiveComponent {

@Element() el: HTMLCalciteListItemGroupElement;

@State() visualLevel: number = null;

// --------------------------------------------------------------------------
//
// Render Methods
//
// --------------------------------------------------------------------------

render(): VNode {
const { disabled, heading, visualLevel } = this;
const { disabled, heading } = this;
return (
<Host>
<InteractiveContainer disabled={disabled}>
<tr
class={CSS.container}
style={{ "--calcite-list-item-spacing-indent-multiplier": `${visualLevel}` }}
>
<tr class={CSS.container}>
<td class={CSS.heading} colSpan={MAX_COLUMNS}>
{heading}
</td>
Expand Down
55 changes: 32 additions & 23 deletions packages/calcite-components/src/components/list-item/list-item.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
:host {
@apply flex flex-col;
@apply flex flex-col bg-foreground-1;
--calcite-list-item-icon-color: theme("colors.brand");
--calcite-list-item-spacing-indent: theme("spacing.4");
}

:host([filter-hidden]),
:host([closed]) {
@apply hidden;
}

.wrapper--bordered {
border-block-end: 1px solid var(--calcite-color-border-3);
}

@include disabled();

.indent {
@apply flex
flex-col
border-solid
border-0
border-color-3;

margin-inline-start: var(--calcite-list-item-spacing-indent, theme("spacing.6"));
}

.container {
@apply bg-foreground-1
box-border
Expand All @@ -14,9 +32,6 @@
* {
@apply box-border;
}
padding-inline-start: calc(
var(--calcite-list-item-spacing-indent) * var(--calcite-list-item-spacing-indent-multiplier)
);
}

.container--hover:hover {
Expand Down Expand Up @@ -47,7 +62,7 @@
}

.nested-container {
@apply bg-foreground-1 flex flex-col;
@apply flex flex-col;
}

.nested-container--hidden {
Expand Down Expand Up @@ -122,13 +137,14 @@ td:focus {
.content-start,
.content-end {
@apply flex-auto;

::slotted(calcite-icon) {
@apply self-center mx-3;
}
}

.content-bottom {
@apply bg-foreground-1 flex flex-col;
padding-inline-start: calc(
var(--calcite-list-item-spacing-indent) * var(--calcite-list-item-spacing-indent-multiplier)
);
@apply flex flex-col;
}

.content-container--has-center-content .content-start,
Expand Down Expand Up @@ -171,20 +187,18 @@ td:focus {
.drag-container,
.open-container {
@apply flex items-center;

calcite-action,
calcite-handle {
@apply self-stretch;
}
}

.open-container,
.selection-container {
@apply cursor-pointer;
}

.content-start,
.content-end {
::slotted(calcite-icon) {
@apply self-center mx-3;
}
}

.actions-start,
.actions-end {
@apply p-0;
Expand All @@ -198,13 +212,8 @@ td:focus {
}
}

::slotted(calcite-list-item),
::slotted(calcite-list) {
@apply border-solid border-0 border-t border-color-3;
}

::slotted(calcite-list:empty) {
@apply py-3;
@apply border-t-0;
}

@include base-component();
90 changes: 46 additions & 44 deletions packages/calcite-components/src/components/list-item/list-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ export class ListItem
}
}

/**
* Sets the item to display a border.
*
* @internal
*/
@Prop() bordered = false;

/** When `true`, a close button is added to the component. */
@Prop({ reflect: true }) closable = false;

Expand Down Expand Up @@ -312,8 +319,6 @@ export class ListItem

@State() level: number = null;

@State() visualLevel: number = null;

@State() parentListEl: HTMLCalciteListElement;

@State() openable = false;
Expand Down Expand Up @@ -355,7 +360,6 @@ export class ListItem
const { el } = this;
this.parentListEl = el.closest(listSelector);
this.level = getDepth(el) + 1;
this.visualLevel = getDepth(el, true);
this.setSelectionDefaults();
}

Expand Down Expand Up @@ -560,13 +564,9 @@ export class ListItem
}

renderContentBottom(): VNode {
const { hasContentBottom, visualLevel } = this;
const { hasContentBottom } = this;
return (
<div
class={CSS.contentBottom}
hidden={!hasContentBottom}
style={{ "--calcite-list-item-spacing-indent-multiplier": `${visualLevel}` }}
>
<div class={CSS.contentBottom} hidden={!hasContentBottom}>
<slot name={SLOTS.contentBottom} onSlotchange={this.handleContentBottomSlotChange} />
</div>
);
Expand Down Expand Up @@ -651,8 +651,9 @@ export class ListItem
selectionAppearance,
selectionMode,
closed,
visualLevel,
filterHidden,
bordered,
disabled,
} = this;

const showBorder = selectionMode !== "none" && selectionAppearance === "border";
Expand All @@ -661,40 +662,41 @@ export class ListItem

return (
<Host>
<InteractiveContainer disabled={this.disabled}>
<tr
aria-expanded={openable ? toAriaBoolean(open) : null}
aria-label={label}
aria-level={level}
aria-posinset={setPosition}
aria-selected={toAriaBoolean(selected)}
aria-setsize={setSize}
class={{
[CSS.container]: true,
[CSS.containerHover]: true,
[CSS.containerBorder]: showBorder,
[CSS.containerBorderSelected]: borderSelected,
[CSS.containerBorderUnselected]: borderUnselected,
}}
hidden={closed || filterHidden}
onFocus={this.focusCellNull}
onFocusin={this.emitInternalListItemActive}
onKeyDown={this.handleItemKeyDown}
role="row"
style={{ "--calcite-list-item-spacing-indent-multiplier": `${visualLevel}` }}
tabIndex={active ? 0 : -1}
// eslint-disable-next-line react/jsx-sort-props -- ref should be last so node attrs/props are in sync (see https://github.com/Esri/calcite-design-system/pull/6530)
ref={(el) => (this.containerEl = el)}
>
{this.renderDragHandle()}
{this.renderSelected()}
{this.renderOpen()}
{this.renderActionsStart()}
{this.renderContentContainer()}
{this.renderActionsEnd()}
</tr>
{this.renderContentBottom()}
{this.renderDefaultContainer()}
<InteractiveContainer disabled={disabled}>
<div class={{ [CSS.wrapper]: true, [CSS.wrapperBordered]: bordered }}>
<tr
aria-expanded={openable ? toAriaBoolean(open) : null}
aria-label={label}
aria-level={level}
aria-posinset={setPosition}
aria-selected={toAriaBoolean(selected)}
aria-setsize={setSize}
class={{
[CSS.container]: true,
[CSS.containerHover]: true,
[CSS.containerBorder]: showBorder,
[CSS.containerBorderSelected]: borderSelected,
[CSS.containerBorderUnselected]: borderUnselected,
}}
hidden={closed || filterHidden}
onFocus={this.focusCellNull}
onFocusin={this.emitInternalListItemActive}
onKeyDown={this.handleItemKeyDown}
role="row"
tabIndex={active ? 0 : -1}
// eslint-disable-next-line react/jsx-sort-props -- ref should be last so node attrs/props are in sync (see https://github.com/Esri/calcite-design-system/pull/6530)
ref={(el) => (this.containerEl = el)}
>
{this.renderDragHandle()}
{this.renderSelected()}
{this.renderOpen()}
{this.renderActionsStart()}
{this.renderContentContainer()}
{this.renderActionsEnd()}
</tr>
{this.renderContentBottom()}
</div>
<div class={CSS.indent}>{this.renderDefaultContainer()}</div>
</InteractiveContainer>
</Host>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
export const CSS = {
wrapper: "wrapper",
wrapperBordered: "wrapper--bordered",
container: "container",
indent: "indent",
containerHover: "container--hover",
containerBorder: "container--border",
containerBorderSelected: "container--border-selected",
Expand Down
15 changes: 0 additions & 15 deletions packages/calcite-components/src/components/list/list.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,21 +28,6 @@
--calcite-stack-padding-block: 0;
}

::slotted(calcite-list-item:not([filter-hidden], [closed])) {
@apply shadow-border-top;
margin-block-start: 1px;
}

::slotted(calcite-list-item:first-of-type) {
@apply shadow-none;
}

// removes shadow for the first item in filteredItems of the list.
::slotted(calcite-list-item[data-filter]) {
@apply shadow-none;
margin-block-start: 0px;
}

.sticky-pos {
@apply sticky
top-0
Expand Down

0 comments on commit 88aab49

Please sign in to comment.