Skip to content

Commit

Permalink
Create nimble-mapping-empty component (#2077)
Browse files Browse the repository at this point in the history
# Pull Request

## 🤨 Rationale

As part of #1992, we decided to create a `nimble-mapping-empty`
component that would allow a cell to render as blank for a given mapping
while still having text provided for use in group rows.

This PR creates that component within `nimble-components`. Support for
Blazor and Angular will be added in a subsequent PR.

## 👩‍💻 Implementation

- Create `nimble-mapping-empty` component
- Add support for the component in the mapping column
- Update tests

## 🧪 Testing

- Extended the unit tests for the mapping column to include tests for
empty mappings
- Add empty mapping to the matrix test for the mapping column

## ✅ Checklist

<!--- Review the list and put an x in the boxes that apply or ~~strike
through~~ around items that don't (along with an explanation). -->

- [ ] I have updated the project documentation to reflect my changes or
determined no changes are needed.
  • Loading branch information
mollykreis authored May 10, 2024
1 parent 8234266 commit 090b724
Show file tree
Hide file tree
Showing 15 changed files with 298 additions and 45 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Create empty mapping element and support it in the icon column",
"packageName": "@ni/nimble-components",
"email": "20542556+mollykreis@users.noreply.github.com",
"dependentChangeType": "patch"
}
28 changes: 28 additions & 0 deletions packages/nimble-components/src/mapping/empty/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { DesignSystem } from '@microsoft/fast-foundation';
import { attr } from '@microsoft/fast-element';
import { Mapping } from '../base';
import { template } from '../base/template';
import type { MappingKey } from '../base/types';

declare global {
interface HTMLElementTagNameMap {
'nimble-mapping-empty': MappingEmpty;
}
}

/**
* Maps data values to text.
* One or more may be added as children of a nimble-table-column-mapping element. The
* mapping displays an empty cell and text-only group rows.
*/
export class MappingEmpty extends Mapping<MappingKey> {
@attr()
public text?: string;
}

const emptyMapping = MappingEmpty.compose({
baseName: 'mapping-empty',
template
});
DesignSystem.getOrCreate().withPrefix('nimble').register(emptyMapping());
export const mappingEmptyTag = 'nimble-mapping-empty';
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { MappingEmpty, mappingEmptyTag } from '..';

describe('Empty Mapping', () => {
it('should export its tag', () => {
expect(mappingEmptyTag).toBe('nimble-mapping-empty');
});

it('can construct an element instance', () => {
expect(document.createElement('nimble-mapping-empty')).toBeInstanceOf(
MappingEmpty
);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { MappingConfig } from './mapping-config';

/**
* Mapping configuration corresponding to an empty mapping
*/
export class MappingEmptyConfig extends MappingConfig {}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
SpinnerView
} from '../../enum-base/models/mapping-spinner-config';
import { MappingTextConfig } from '../../enum-base/models/mapping-text-config';
import { MappingEmptyConfig } from '../../enum-base/models/mapping-empty-config';

declare global {
interface HTMLElementTagNameMap {
Expand Down Expand Up @@ -82,6 +83,9 @@ export class TableColumnMappingCellView
} else if (mappingConfig instanceof MappingTextConfig) {
this.text = mappingConfig.text;
this.textHidden = false;
} else if (mappingConfig instanceof MappingEmptyConfig) {
this.text = mappingConfig.text;
this.textHidden = true;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { styles } from './styles';
import { template } from './template';
import type { TableColumnEnumColumnConfig } from '../../enum-base';
import type { TableFieldValue } from '../../../table/types';
import { TableColumnTextGroupHeaderViewBase } from '../../text-base/group-header-view';
import { IconSeverity } from '../../../icon-base/types';
import {
MappingIconConfig,
Expand All @@ -15,6 +14,8 @@ import {
SpinnerView
} from '../../enum-base/models/mapping-spinner-config';
import { MappingTextConfig } from '../../enum-base/models/mapping-text-config';
import { MappingEmptyConfig } from '../../enum-base/models/mapping-empty-config';
import { TableGroupHeaderView } from '../../base/group-header-view';

declare global {
interface HTMLElementTagNameMap {
Expand All @@ -26,11 +27,15 @@ declare global {
* The group header view for the mapping column
*/
export class TableColumnMappingGroupHeaderView
extends TableColumnTextGroupHeaderViewBase<
TableFieldValue,
TableColumnEnumColumnConfig
>
extends TableGroupHeaderView<TableFieldValue, TableColumnEnumColumnConfig>
implements IconView, SpinnerView {
/** @internal */
@observable
public hasOverflow = false;

@observable
public text = '';

@observable
public severity: IconSeverity;

Expand All @@ -41,7 +46,15 @@ export class TableColumnMappingGroupHeaderView

public readonly textHidden = false;

protected updateText(): void {
private columnConfigChanged(): void {
this.updateState();
}

private groupHeaderValueChanged(): void {
this.updateState();
}

private updateState(): void {
this.resetState();

if (!this.columnConfig) {
Expand All @@ -58,6 +71,8 @@ export class TableColumnMappingGroupHeaderView
this.visualizationTemplate = mappingConfig.spinnerTemplate;
} else if (mappingConfig instanceof MappingTextConfig) {
this.text = mappingConfig.text ?? '';
} else if (mappingConfig instanceof MappingEmptyConfig) {
this.text = mappingConfig.text ?? '';
}
}

Expand Down
5 changes: 5 additions & 0 deletions packages/nimble-components/src/table-column/mapping/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import { MappingIconConfig } from '../enum-base/models/mapping-icon-config';
import { MappingSpinnerConfig } from '../enum-base/models/mapping-spinner-config';
import { MappingText } from '../../mapping/text';
import { MappingTextConfig } from '../enum-base/models/mapping-text-config';
import { MappingEmpty } from '../../mapping/empty';
import { MappingEmptyConfig } from '../enum-base/models/mapping-empty-config';
import { TableColumnMappingWidthMode } from './types';

declare global {
Expand Down Expand Up @@ -89,6 +91,9 @@ export class TableColumnMapping extends mixinGroupableColumnAPI(
if (mapping instanceof MappingText) {
return new MappingTextConfig(mapping.text);
}
if (mapping instanceof MappingEmpty) {
return new MappingEmptyConfig(mapping.text);
}
// Getting here would indicate a programming error, b/c validation will prevent
// this function from running when there is an unsupported mapping.
throw new Error('Unsupported mapping');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Mapping } from '../../../mapping/base';
import { MappingEmpty } from '../../../mapping/empty';
import { MappingIcon } from '../../../mapping/icon';
import { MappingSpinner } from '../../../mapping/spinner';
import { MappingText } from '../../../mapping/text';
Expand Down Expand Up @@ -33,11 +34,12 @@ export class TableColumnMappingValidator extends TableColumnEnumBaseValidator<

private static isSupportedMappingElement(
mapping: Mapping<unknown>
): mapping is MappingIcon | MappingSpinner | MappingText {
): mapping is MappingIcon | MappingSpinner | MappingText | MappingEmpty {
return (
mapping instanceof MappingIcon
|| mapping instanceof MappingSpinner
|| mapping instanceof MappingText
|| mapping instanceof MappingEmpty
);
}

Expand Down
Loading

0 comments on commit 090b724

Please sign in to comment.