Skip to content

Commit

Permalink
feat(Formatters): add new Formatters.iconBoolean for icon w/truthy …
Browse files Browse the repository at this point in the history
…val (#1228)

- this formatter is meant to be generic to display any icon you want on a boolean truthy value. It was created to replace the `Formatters.checkmark` which is only working for users with Font-Awesome 4 and nothing else, basically this new formatter is a lot less restrictive and allows the user to use any CSS class name he wants to use.
  • Loading branch information
ghiscoding authored Nov 28, 2023
1 parent f94fb12 commit 17ab965
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 0 deletions.
116 changes: 116 additions & 0 deletions packages/common/src/formatters/__tests__/iconBooleanFormatter.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import { Column } from '../../interfaces/index';
import { iconBooleanFormatter } from '../iconBooleanFormatter';

describe('the Checkmark Formatter', () => {
it('should throw an error when omitting to pass "params.cssClass"', () => {
expect(() => iconBooleanFormatter(0, 0, 'anything', {} as Column, {}, {} as any))
.toThrow('Slickgrid-Universal] When using `Formatters.iconBoolean`, you must provide You must provide the "cssClass"');
});

it('should return an empty string when no value is passed', () => {
const value = null;
const cssClass = 'fa fa-check';
const result = iconBooleanFormatter(0, 0, value, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
expect(result).toBe('');
});

it('should return an empty string when False is provided', () => {
const value = false;
const cssClass = 'fa fa-check';
const result = iconBooleanFormatter(0, 0, value, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
expect(result).toBe('');
});

it('should return an empty string when the string "FALSE" (case insensitive) is provided', () => {
const value = 'FALSE';
const cssClass = 'fa fa-check';
const result1 = iconBooleanFormatter(0, 0, value.toLowerCase(), { field: 'user', params: { cssClass } } as Column, {}, {} as any);
const result2 = iconBooleanFormatter(0, 0, value.toUpperCase(), { field: 'user', params: { cssClass } } as Column, {}, {} as any);
expect(result1).toBe('');
expect(result2).toBe('');
});

it('should return the Font Awesome Checkmark icon when the string "True" (case insensitive) is provided', () => {
const value = 'True';
const cssClass = 'fa fa-check';
const result1 = iconBooleanFormatter(0, 0, value.toLowerCase(), { field: 'user', params: { cssClass } } as Column, {}, {} as any);
const result2 = iconBooleanFormatter(0, 0, value.toUpperCase(), { field: 'user', params: { cssClass } } as Column, {}, {} as any);
expect(result1).toBe('<i class="fa fa-check" aria-hidden="true"></i>');
expect(result2).toBe('<i class="fa fa-check" aria-hidden="true"></i>');
});

it('should return the Font Awesome Checkmark icon when input is True', () => {
const value = true;
const cssClass = 'fa fa-check';
const result = iconBooleanFormatter(0, 0, value, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
expect(result).toBe('<i class="fa fa-check" aria-hidden="true"></i>');
});

it('should return the Font Awesome Checkmark icon when input is a string even if it start with 0', () => {
const value = '005A00ABC';
const cssClass = 'fa fa-check';
const result1 = iconBooleanFormatter(0, 0, value, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
expect(result1).toBe('<i class="fa fa-check" aria-hidden="true"></i>');
});

it('should return an empty string when the string "0" is provided', () => {
const value = '0';
const cssClass = 'fa fa-check';
const result = iconBooleanFormatter(0, 0, value, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
expect(result).toBe('');
});

it('should return the Font Awesome Checkmark icon when input is a number greater than 0', () => {
const value = 0.000001;
const cssClass = 'fa fa-check';
const result1 = iconBooleanFormatter(0, 0, value, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
expect(result1).toBe('<i class="fa fa-check" aria-hidden="true"></i>');
});

it('should return the Font Awesome Checkmark icon when input is a number as a text greater than 0', () => {
const value = '0.000001';
const cssClass = 'fa fa-check';
const result1 = iconBooleanFormatter(0, 0, value, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
expect(result1).toBe('<i class="fa fa-check" aria-hidden="true"></i>');
});

it('should return an empty string when input is a number lower or equal to 0', () => {
const value1 = 0;
const value2 = -0.5;
const cssClass = 'fa fa-check';
const result1 = iconBooleanFormatter(0, 0, value1, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
const result2 = iconBooleanFormatter(0, 0, value2, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
expect(result1).toBe('');
expect(result2).toBe('');
});

it('should return an empty string when input is a number as a text and lower or equal to 0', () => {
const value1 = '0';
const value2 = '-0.5';
const cssClass = 'fa fa-check';
const result1 = iconBooleanFormatter(0, 0, value1, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
const result2 = iconBooleanFormatter(0, 0, value2, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
expect(result1).toBe('');
expect(result2).toBe('');
});

it('should return an empty string when input is type null or undefined', () => {
const value1 = null;
const value2 = undefined;
const cssClass = 'fa fa-check';
const result1 = iconBooleanFormatter(0, 0, value1, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
const result2 = iconBooleanFormatter(0, 0, value2, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
expect(result1).toBe('');
expect(result2).toBe('');
});

it('should return the Font Awesome Checkmark icon when input is the "null" or "undefined"', () => {
const value1 = 'null';
const value2 = 'undefined';
const cssClass = 'fa fa-check';
const result1 = iconBooleanFormatter(0, 0, value1, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
const result2 = iconBooleanFormatter(0, 0, value2, { field: 'user', params: { cssClass } } as Column, {}, {} as any);
expect(result1).toBe('<i class="fa fa-check" aria-hidden="true"></i>');
expect(result2).toBe('<i class="fa fa-check" aria-hidden="true"></i>');
});
});
7 changes: 7 additions & 0 deletions packages/common/src/formatters/formatters.index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { dollarFormatter } from './dollarFormatter';
import { editIconFormatter } from './editIconFormatter';
import { fakeHyperlinkFormatter } from './fakeHyperlinkFormatter';
import { hyperlinkFormatter } from './hyperlinkFormatter';
import { iconBooleanFormatter } from './iconBooleanFormatter';
import { iconFormatter } from './iconFormatter';
import { infoIconFormatter } from './infoIconFormatter';
import { italicFormatter } from './italicFormatter';
Expand Down Expand Up @@ -235,6 +236,12 @@ export const Formatters = {
/** Display whichever icon you want (library agnostic, it could be Font-Awesome or any other) */
icon: iconFormatter,

/**
* Display whichever icon but only for boolean truthy values (library agnostic, it could be Font-Awesome or any other)
* Note: a value of "false", null, undefined, "1" or any number below 0 are all considered falsy and will not display the icon
*/
iconBoolean: iconBooleanFormatter,

/** @deprecated @use `Formatters.icon` instead. Displays a Font-Awesome edit icon (fa-info-circle) */
infoIcon: infoIconFormatter,

Expand Down
19 changes: 19 additions & 0 deletions packages/common/src/formatters/iconBooleanFormatter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { type Formatter } from './../interfaces/index';

/** Display whichever icon for a boolean value (library agnostic, it could be Font-Awesome or any other) */
export const iconBooleanFormatter: Formatter = (_row, _cell, value, columnDef) => {
const columnParams = columnDef?.params || {};
const cssClass = columnParams.cssClass;

if (!cssClass) {
throw new Error('[Slickgrid-Universal] When using `Formatters.iconBoolean`, you must provide You must provide the "cssClass", e.g.: { formatter: Formatters.iconBoolean, params: { cssClass: "fa fa-check" }}');
}

let isTruthy = false;
const isNumber = !isNaN(value);
if (value === true || (isNumber && parseFloat(value) > 0) || (!isNumber && typeof value === 'string' && value.toLowerCase() !== 'false' && value !== '0')) {
isTruthy = true;
}

return isTruthy ? `<i class="${cssClass}" aria-hidden="true"></i>` : '';
};
1 change: 1 addition & 0 deletions packages/common/src/formatters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export * from './editIconFormatter';
export * from './formatters.index';
export * from './formatterUtilities';
export * from './hyperlinkFormatter';
export * from './iconBooleanFormatter';
export * from './iconFormatter';
export * from './infoIconFormatter';
export * from './italicFormatter';
Expand Down

0 comments on commit 17ab965

Please sign in to comment.