Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(list, list-item, list-item-group): improve drag experience by indenting items #9169

Merged
merged 13 commits into from
Apr 25, 2024
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 @@ -2841,6 +2841,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 @@ -10346,6 +10350,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
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();
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
Loading
Loading