Skip to content

Commit

Permalink
feat(Tag): allow custom tag color (#724)
Browse files Browse the repository at this point in the history
Co-authored-by: Dabiel González Ramos <dabiel.ramos@endava.com>
Cata1989 and dgonzalezr authored Jan 9, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent e44b8d1 commit ff05338
Showing 6 changed files with 488 additions and 258 deletions.
678 changes: 427 additions & 251 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -121,6 +121,7 @@
"husky": "8.0.3",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
"jsdom": "23.2.0",
"jsonc-eslint-parser": "2.4.0",
"lint-staged": "15.2.0",
"lit-html": "3.1.0",
17 changes: 17 additions & 0 deletions packages/beeq/src/components/tag/_storybook/bq-tag.stories.tsx
Original file line number Diff line number Diff line change
@@ -144,6 +144,23 @@ export const ColorOutline: Story = {
},
};

export const CustomColor: Story = {
name: 'Color - custom',
render: (args: Args) => html`
<div class="flex gap-s">
<!-- Hex custom color -->
${Template({ ...args, color: '#FF5733', text: 'HEX', icon: 'yin-yang' })}
<!-- Rgba custom color -->
${Template({ ...args, color: 'rgba(255, 87, 51, 0.7)', text: 'RGBA', icon: 'rss' })}
<!-- Theme custom color palette -->
${Template({ ...args, color: 'data--sky', text: 'Theme Palette', icon: 'palette' })}
</div>
`,
args: {
variant: 'outline',
},
};

export const RemovableFilled: Story = {
name: 'Removable - filled',
render: (args: Args) => html`
17 changes: 12 additions & 5 deletions packages/beeq/src/components/tag/bq-tag.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Component, Element, Event, EventEmitter, h, Host, Method, Prop, State, Watch } from '@stencil/core';

import { TAG_SIZE, TAG_VARIANT, TTagBorderRadius, TTagColor, TTagSize, TTagVariant } from './bq-tag.types';
import { TAG_COLOR, TAG_SIZE, TAG_VARIANT, TTagBorderRadius, TTagColor, TTagSize, TTagVariant } from './bq-tag.types';
import { iconSize, textColor } from './helper';
import { hasSlotContent, validatePropValue } from '../../shared/utils';
import { getColorCSSVariable, hasSlotContent, validatePropValue } from '../../shared/utils';

/**
* @part wrapper - The wrapper container `<div>` of the element inside the shadow DOM.
@@ -174,7 +174,7 @@ export class BqTag {
};

private get isClickable(): boolean {
return this.clickable && !this.color && !this.removable;
return this.clickable && !this.color && !this.hasCustomColor && !this.removable;
}

private get isRemovable(): boolean {
@@ -185,6 +185,10 @@ export class BqTag {
return this.isRemovable && this.hidden;
}

private get hasCustomColor(): boolean {
return this.color !== undefined ? !TAG_COLOR.includes(this.color) : false;
}

// render() function
// Always the last one in the class.
// ===================================
@@ -193,13 +197,16 @@ export class BqTag {
const style = {
'--bq-tag--icon-prefix-size': `${iconSize(this.size)}px`,
...(this.border && { '--bq-tag--border-radius': `var(--bq-radius--${this.border})` }),
...(this.color && { '--bq-tag--background-color': getColorCSSVariable(this.color) ?? this.color }),
...(this.hasCustomColor && { '--bq-text--primary': `var(--bq-text--primary-alt)` }),
};

return (
<Host style={style} aria-hidden={this.isHidden ? 'true' : 'false'} hidden={this.isHidden ? 'true' : 'false'}>
<button
class={{
[`bq-tag bq-tag__${this.size} bq-tag__${this.color || 'default'} bq-tag__${this.variant}`]: true,
[`bq-tag bq-tag__${this.size}`]: true,
[`bq-tag__${this.color || 'default'} bq-tag__${this.variant}`]: !this.hasCustomColor,
'is-clickable': this.isClickable,
'is-removable': this.removable,
// Active/Selected state when clickable
@@ -236,7 +243,7 @@ export class BqTag {
<bq-icon
size={iconSize(this.size)}
name="x-circle"
color={this.color ? textColor(this.color)[this.variant] : 'text--primary'}
color={this.color && !this.hasCustomColor ? textColor(this.color)[this.variant] : 'text--primary'}
/>
</bq-button>
)}
25 changes: 25 additions & 0 deletions packages/beeq/src/shared/utils/__tests__/cssVariables.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
import jsdom from 'jsdom';
import { getColorCSSVariable } from '..';

// Helper function to setup JSDOM and global variables
function setupDOM(html: string) {
const DOM = new jsdom.JSDOM(html);
const { document } = DOM.window;
global.document = document;
global.window = document.defaultView;
global.getComputedStyle = window.getComputedStyle.bind(window);
}

describe('cssVariables - getColorCSSVariable()', () => {
it('should return the correct CSS Custom Property string', () => {
setupDOM(`
<html>
<head>
<style>
:root {
--bq-ui--primary: #fbfbfc;
}
</style>
</head>
<body>
<div></div>
</body>
</html>
`);

const token = 'ui--primary';
const result = `var(--bq-${token})`;

8 changes: 6 additions & 2 deletions packages/beeq/src/shared/utils/cssVariables.ts
Original file line number Diff line number Diff line change
@@ -4,10 +4,14 @@ const CSSVALUEPREFIX = '--bq-';
* Get CSS custom property variable of a given color string value
*
* @param {string} colorName - Valid string value.
* @return {string} The correspongin CSS custom property variable
* @return {string} The corresponding CSS custom property variable
*/
export function getColorCSSVariable(colorName: string): string {
return `var(${CSSVALUEPREFIX}${colorName})`;
const token = `${CSSVALUEPREFIX}${colorName}`;
const value = getComputedStyle(document.documentElement).getPropertyValue(token);
if (!value) return undefined;

return `var(${token})`;
}

/**

0 comments on commit ff05338

Please sign in to comment.