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

feat(pie-tag): DSW-2323 add isInteractive prop and rename isDimmed to disabled #1765

Merged
merged 5 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/eighty-cobras-serve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"pie-docs": patch
---

[Changed] - Update code page for pie-tag
8 changes: 8 additions & 0 deletions .changeset/rude-dolphins-lick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@justeattakeaway/pie-tag": minor
"pie-storybook": patch
---

[Changed] - Rename `isDimmed` prop to `disabled`
[Added] - `isInteractive` prop which renders the tag as a button
[Added] - Interactive styling
2 changes: 1 addition & 1 deletion apps/pie-docs/src/components/tag/code/code.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ yarn add @justeattakeaway/pie-webc
tableData: props
} %}

Since the component is not interactive, it doesn't have a disabled property. To give the Tag a disabled look, please set the `--tag-opacity` css variable. Recommended opacity level for disabled tag is 0.5.
You can customise the disabled appearance by setting the `--tag-opacity` css variable. The default opacity level for the disabled state is 0.5.

## Slots

Expand Down
27 changes: 26 additions & 1 deletion apps/pie-docs/src/components/tag/code/props.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,32 @@
"type": "code",
"item": ["true", "false"]
},
"If `true`, displays strong tag styles for `green`, `yellow`, `red`, `blue` and `neutral` variants.",
"If `true`, displays strong tag styles for `green`, `yellow`, `red`, `blue` and `neutral` variants. Has no effect for other variants.",
{
"type": "code",
"item": ["false"]
}
],
[
"isInteractive",
{
"type": "code",
"item": ["true", "false"]

},
"When `true`, the tag will be rendered as a button and can be interacted with.",
{
"type": "code",
"item": ["false"]
}
],
[
"disabled",
{
"type": "code",
"item": ["true", "false"]
},
"For an interactive tag, this applies the disabled attribute to the button and styles it appropriately. For a non-interactive tag, this only applies the disabled styling.",
{
"type": "code",
"item": ["false"]
Expand Down
12 changes: 7 additions & 5 deletions apps/pie-storybook/stories/pie-tag.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ const tagStoryMeta: TagStoryMeta = {
summary: defaultProps.isStrong,
},
},
isDimmed: {
description: 'If `true`, lowers the tag opacity.',
disabled: {
description: 'For an interactive tag, this applies the disabled attribute to the button and styles it appropriately.<br>For a non-interactive tag, this only applies the disabled styling.',
control: 'boolean',
defaultValue: {
summary: defaultProps.isDimmed,
summary: defaultProps.disabled,
},
},
showIcon: {
Expand Down Expand Up @@ -80,16 +80,18 @@ export default tagStoryMeta;
const Template : TemplateFunction<TagProps> = ({
variant,
size,
isInteractive,
isStrong,
isDimmed,
disabled,
showIcon,
slot,
}) => html`
<pie-tag
variant="${ifDefined(variant)}"
size="${ifDefined(size)}"
?isInteractive="${isInteractive}"
?isStrong="${isStrong}"
?isDimmed="${isDimmed}">
?disabled="${disabled}">
${showIcon ? html`<icon-heart-filled slot="icon"></icon-heart-filled>` : nothing}
${sanitizeAndRenderHTML(slot)}
</pie-tag>
Expand Down
15 changes: 11 additions & 4 deletions packages/components/pie-tag/src/defs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,20 @@ export interface TagProps {
variant?: typeof variants[number];

/**
* When true, the 'green', "yellow", "red", "blue" and "neutral" variants change their styles and become bolder
* When true, the "green", "yellow", "red", "blue" and "neutral" variants change their styles and become bolder
*/
isStrong?: boolean;

/**
* When `true`, lowers the tag opacity.
* When `true`, the tag will be rendered as a button and can be interacted with.
*/
isDimmed?: boolean;
isInteractive?: boolean;

/**
* For an interactive tag, this applies the disabled attribute to the button and styles it appropriately.
* For a non-interactive tag, this only applies the disabled styling.
*/
disabled?: boolean;

/**
* What size the tag should be.
Expand All @@ -30,6 +36,7 @@ export type DefaultProps = ComponentDefaultProps<TagProps>;
export const defaultProps: DefaultProps = {
variant: 'neutral',
isStrong: false,
isDimmed: false,
isInteractive: false,
disabled: false,
size: 'large',
};
52 changes: 41 additions & 11 deletions packages/components/pie-tag/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
LitElement, html, unsafeCSS, nothing,
} from 'lit';
import { property } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { classMap, type ClassInfo } from 'lit/directives/class-map.js';
import { validPropertyValues, defineCustomElement } from '@justeattakeaway/pie-webc-core';
import styles from './tag.scss?inline';
import {
Expand Down Expand Up @@ -32,11 +32,15 @@ export class PieTag extends LitElement implements TagProps {
public isStrong = defaultProps.isStrong;

@property({ type: Boolean })
public isDimmed = defaultProps.isDimmed;
public disabled = defaultProps.disabled;

@property({ type: Boolean })
public isInteractive = defaultProps.isInteractive;

render () {
const {
isDimmed,
disabled,
isInteractive,
isStrong,
size,
variant,
Expand All @@ -46,18 +50,44 @@ export class PieTag extends LitElement implements TagProps {
'c-tag': true,
[`c-tag--${size}`]: true,
[`c-tag--${variant}`]: true,
'c-tag--dimmed': isDimmed,
'c-tag--disabled': disabled,
'c-tag--strong': isStrong,
'c-tag--interactive': isInteractive,
};

if (isInteractive) {
return this.renderButtonTag(classes);
}

return this.renderTag(classes);
}

private renderIconSlot () {
if (this.size !== 'large') return nothing;

return html`<slot name="icon"></slot>`;
}

private renderTag (classes: ClassInfo) {
return html`
<div
class="${classMap(classes)}"
data-test-id="pie-tag">
${this.renderIconSlot()}
<slot></slot>
</div>`;
}

private renderButtonTag (classes: ClassInfo) {
return html`
<div
class="${classMap(classes)}"
data-test-id="pie-tag"
>
${size === 'large' ? html`<slot name="icon"></slot>` : nothing}
<slot></slot>
</div>`;
<button
type="button"
?disabled="${this.disabled}"
class="${classMap(classes)}"
data-test-id="pie-tag">
${this.renderIconSlot()}
<slot></slot>
</button>`;
}

// Renders a `CSSResult` generated from SCSS by Vite
Expand Down
63 changes: 61 additions & 2 deletions packages/components/pie-tag/src/tag.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
@use '@justeattakeaway/pie-css/scss' as p;

@mixin tag-interactive-states($bg-color, $mode: 'default') {
&.c-tag--interactive {
&:hover:not(.c-tag--disabled) {
@if $mode == 'inverse' {
--hover-modifier: var(--dt-color-hover-02);
} @else {
--hover-modifier: calc(-1 * var(--dt-color-hover-01));
fernandofranca marked this conversation as resolved.
Show resolved Hide resolved
}

@if $mode == 'transparent' {
--hover-modifier: var(--dt-color-hover-01);
--tag-bg-color: hsl(var(#{$bg-color}-h), var(#{$bg-color}-s), var(#{$bg-color}-l), var(--hover-modifier));
} @else {
--tag-bg-color: hsl(var(#{$bg-color}-h), var(#{$bg-color}-s), calc(var(#{$bg-color}-l) + var(--hover-modifier)));
}
}

&:active:not(.c-tag--disabled) {
@if $mode == 'inverse' {
--active-modifier: var(--dt-color-active-02);
} @else {
--active-modifier: calc(-1 * var(--dt-color-active-01));
}

@if $mode == 'transparent' {
--active-modifier: var(--dt-color-active-01);
--tag-bg-color: hsl(var(#{$bg-color}-h), var(#{$bg-color}-s), var(#{$bg-color}-l), var(--active-modifier));
} @else {
--tag-bg-color: hsl(var(#{$bg-color}-h), var(#{$bg-color}-s), calc(var(#{$bg-color}-l) + var(--active-modifier)));
}
}
}
}

// Base tag styles
.c-tag {
--tag-bg-color: var(--dt-color-container-strong);
Expand Down Expand Up @@ -33,6 +67,14 @@
font-size: var(--tag-font-size);
line-height: var(--tag-line-height);

&.c-tag--interactive {
border: none;

&:focus-visible {
@include p.focus;
}
}

// Size
&.c-tag--small {
--tag-padding-block: 0;
Expand All @@ -48,67 +90,79 @@

// Variant
&.c-tag--neutral {
// same as default styles
@include tag-interactive-states('--dt-color-container-strong');

&.c-tag--strong {
--tag-bg-color: var(--dt-color-container-inverse);
--tag-color: var(--dt-color-content-inverse);
@include tag-interactive-states('--dt-color-container-inverse', 'inverse');
}
}

&.c-tag--blue {
--tag-bg-color: var(--dt-color-support-info-02);
--tag-color: var(--dt-color-content-default);
@include tag-interactive-states('--dt-color-support-info-02');

&.c-tag--strong {
--tag-bg-color: var(--dt-color-support-info);
--tag-color: var(--dt-color-content-inverse);
@include tag-interactive-states('--dt-color-support-info');
}
}

&.c-tag--green {
--tag-bg-color: var(--dt-color-support-positive-02);
--tag-color: var(--dt-color-content-default);
@include tag-interactive-states('--dt-color-support-positive-02');

&.c-tag--strong {
--tag-bg-color: var(--dt-color-support-positive);
--tag-color: var(--dt-color-content-inverse);
@include tag-interactive-states('--dt-color-support-positive');
}
}

&.c-tag--yellow {
--tag-bg-color: var(--dt-color-support-warning-02);
--tag-color: var(--dt-color-content-default);
@include tag-interactive-states('--dt-color-support-warning-02');

&.c-tag--strong {
--tag-bg-color: var(--dt-color-support-warning);
--tag-color: var(--dt-color-content-dark);
@include tag-interactive-states('--dt-color-support-warning');
}
}

&.c-tag--red {
--tag-bg-color: var(--dt-color-support-error-02);
--tag-color: var(--dt-color-content-default);
@include tag-interactive-states('--dt-color-support-error-02');

&.c-tag--strong {
--tag-bg-color: var(--dt-color-support-error);
--tag-color: var(--dt-color-content-light);
@include tag-interactive-states('--dt-color-support-error');
}
}

&.c-tag--brand {
--tag-bg-color: var(--dt-color-support-brand-02);
--tag-color: var(--dt-color-content-default);
@include tag-interactive-states('--dt-color-support-brand-02');
}

&.c-tag--neutral-alternative {
--tag-bg-color: var(--dt-color-container-default);
--tag-color: var(--dt-color-content-default);
@include tag-interactive-states('--dt-color-container-default');
}

&.c-tag--outline {
--tag-bg-color: var(--tag-transparent-bg-color);
--tag-color: var(--dt-color-content-default);
@include tag-interactive-states('--dt-color-black', 'transparent');

// the outline in design specs is part of the total component
// height calculation, thus, we use box-shadow to mimic borders
Expand All @@ -119,11 +173,16 @@
&.c-tag--ghost {
--tag-bg-color: var(--tag-transparent-bg-color);
--tag-color: var(--dt-color-content-default);
@include tag-interactive-states('--dt-color-black', 'transparent');
}

&.c-tag--dimmed {
&.c-tag--disabled {
opacity: 0.5;
}

&[disabled] {
cursor: not-allowed;
}
}

// Used to size an SVG if one is passed in (when not using the component icons)
Expand Down
Loading
Loading