Skip to content

Commit

Permalink
Merge 67f3502 into 92f9965
Browse files Browse the repository at this point in the history
  • Loading branch information
raoufswe authored Nov 6, 2024
2 parents 92f9965 + 67f3502 commit 294b5a0
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 29 deletions.
7 changes: 7 additions & 0 deletions .changeset/plenty-months-hope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@justeattakeaway/pie-tag": minor
"pie-storybook": minor
"pie-docs": minor
---

[Added] - Implement trailing icon for interactive variants
4 changes: 4 additions & 0 deletions apps/pie-docs/src/components/tag/code/code.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ You can customise the disabled appearance by setting the `--tag-opacity` css var
tableData: slots
} %}

## Events

The interactive tag component does not emit any custom events. In order to add event listening to it, you can treat the component like a native HTML element in your application.

### Using `pie-icons-webc` with the `pie-tag` icon slot

We recommend using `pie-icons-webc` when using the `icon` slot. Here is an example of how you would do this:
Expand Down
12 changes: 12 additions & 0 deletions apps/pie-docs/src/components/tag/code/props.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@
"type": "code",
"item": ["false"]
}
],
[
"iconPlacement",
{
"type": "code",
"item": ["\"leading\"", "\"trailing\""]
},
"Sets the position of the icon relative to the text. Leading comes before the text and trailing comes after, taking writing direction into account. To use this, you must pass an icon into the <a href=\"#slots\">icon slot</a>. Can be only used if `isInteractive` is set to true",
{
"type": "code",
"item": ["\"leading\""]
}
]
]
}
19 changes: 17 additions & 2 deletions apps/pie-storybook/stories/pie-tag.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { type Meta } from '@storybook/web-components';

import '@justeattakeaway/pie-tag';
import {
type TagProps as TagBaseProps, variants, sizes, defaultProps,
type TagProps as TagBaseProps,
variants,
sizes,
defaultProps,
iconPlacements,
} from '@justeattakeaway/pie-tag';
import '@justeattakeaway/pie-icons-webc/dist/IconHeartFilled.js';

Expand Down Expand Up @@ -55,7 +59,7 @@ const tagStoryMeta: TagStoryMeta = {
},
},
showIcon: {
description: 'Enable to see the example of Tag with icon. Available only for large tag size.',
description: '<b>**Not a component prop</b><br><br>Use the `icon` slot to pass a PIE icon component. Available only for large tag size.',
control: 'boolean',
defaultValue: {
summary: defaultArgs.showIcon,
Expand All @@ -66,6 +70,15 @@ const tagStoryMeta: TagStoryMeta = {
description: 'Content to place within the tag',
control: 'text',
},
iconPlacement: {
description: 'The placement of the icon slot such as leading or trailing. <br /><br /> Can be only used if `isInteractive` is set to true',
control: 'select',
options: iconPlacements,
defaultValue: {
summary: defaultArgs.iconPlacement,
},
if: { arg: 'isInteractive', eq: true },
},
},
args: defaultArgs,
parameters: {
Expand All @@ -86,10 +99,12 @@ const Template : TemplateFunction<TagProps> = ({
disabled,
showIcon,
slot,
iconPlacement,
}) => html`
<pie-tag
variant="${ifDefined(variant)}"
size="${ifDefined(size)}"
iconPlacement="${ifDefined(iconPlacement)}"
?isInteractive="${isInteractive}"
?isStrong="${isStrong}"
?disabled="${disabled}">
Expand Down
7 changes: 7 additions & 0 deletions packages/components/pie-tag/src/defs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { type ComponentDefaultProps } from '@justeattakeaway/pie-webc-core';

export const variants = ['neutral-alternative', 'neutral', 'outline', 'ghost', 'blue', 'green', 'yellow', 'red', 'brand', 'brand-03', 'brand-04', 'brand-06'] as const;
export const sizes = ['small', 'large'] as const;
export const iconPlacements = ['leading', 'trailing'] as const;

export interface TagProps {
/**
Expand Down Expand Up @@ -29,6 +30,11 @@ export interface TagProps {
* What size the tag should be.
*/
size?: typeof sizes[number];

/**
* The placement of the icon slot such as leading (default) or trailing. Available only if `isInteractive` is set to true.
*/
iconPlacement?: typeof iconPlacements[number];
}

export type DefaultProps = ComponentDefaultProps<TagProps>;
Expand All @@ -39,4 +45,5 @@ export const defaultProps: DefaultProps = {
isInteractive: false,
disabled: false,
size: 'large',
iconPlacement: 'leading',
};
60 changes: 35 additions & 25 deletions packages/components/pie-tag/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ 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 {
type TagProps, variants, sizes, defaultProps,
variants,
sizes,
defaultProps,
iconPlacements,
type TagProps,
} from './defs';

// Valid values available to consumers
Expand Down Expand Up @@ -37,30 +41,9 @@ export class PieTag extends LitElement implements TagProps {
@property({ type: Boolean })
public isInteractive = defaultProps.isInteractive;

render () {
const {
disabled,
isInteractive,
isStrong,
size,
variant,
} = this;

const classes = {
'c-tag': true,
[`c-tag--${size}`]: true,
[`c-tag--${variant}`]: true,
'c-tag--disabled': disabled,
'c-tag--strong': isStrong,
'c-tag--interactive': isInteractive,
};

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

return this.renderTag(classes);
}
@property({ type: String })
@validPropertyValues(componentSelector, iconPlacements, defaultProps.iconPlacement)
public iconPlacement = defaultProps.iconPlacement;

private renderIconSlot () {
if (this.size !== 'large') return nothing;
Expand Down Expand Up @@ -90,6 +73,33 @@ export class PieTag extends LitElement implements TagProps {
</button>`;
}

render () {
const {
disabled,
isInteractive,
isStrong,
size,
variant,
iconPlacement,
} = this;

const classes = {
'c-tag': true,
[`c-tag--${size}`]: true,
[`c-tag--${variant}`]: true,
'c-tag--disabled': disabled,
'c-tag--strong': isStrong,
'c-tag--interactive': isInteractive,
[`c-tag--icon-placement--${iconPlacement}`]: isInteractive && iconPlacement,
};

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

return this.renderTag(classes);
}

// Renders a `CSSResult` generated from SCSS by Vite
static styles = unsafeCSS(styles);
}
Expand Down
9 changes: 9 additions & 0 deletions packages/components/pie-tag/src/tag.scss
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
--icon-size-override: 16px;

display: inline-flex;
flex-direction: row;
vertical-align: middle;
align-items: center;
justify-content: center;
Expand All @@ -80,6 +81,14 @@
}
}

&.c-tag--icon-placement--leading {
// same as default styles
}

&.c-tag--icon-placement--trailing {
flex-direction: row-reverse;
}

// Size
&.c-tag--small {
--tag-padding-block: 0;
Expand Down
10 changes: 8 additions & 2 deletions packages/components/pie-tag/test/visual/pie-tag.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,23 @@ import {
} from '@justeattakeaway/pie-webc-testing/src/helpers/components/web-component-test-wrapper/WebComponentTestWrapper.ts';
import { percyWidths } from '@justeattakeaway/pie-webc-testing/src/percy/breakpoints.ts';
import { IconHeartFilled } from '@justeattakeaway/pie-icons-webc/dist/IconHeartFilled';
import { type TagProps, sizes, variants } from '../../src/defs.ts';
import {
type TagProps, sizes, variants, iconPlacements,
} from '../../src/defs.ts';
import { PieTag } from '../../src/index.ts';

const props: PropObject<TagProps & { iconSlot: string }> = {
variant: variants,
size: sizes,
iconPlacement: iconPlacements,
isInteractive: [true, false],
isStrong: [true, false],
disabled: [true, false],
iconSlot: ['', '<icon-heart-filled slot="icon"></icon-heart-filled>'],
};

// Renders a <pie-tag> HTML string with the given prop values
const renderTestPieTag = (propVals: WebComponentPropValues) => `<pie-tag variant="${propVals.variant}" size="${propVals.size}" ${propVals.isStrong ? 'isStrong' : ''} ${propVals.disabled ? 'disabled' : ''}>${propVals.iconSlot} Hello world</pie-tag>`;
const renderTestPieTag = (propVals: WebComponentPropValues) => `<pie-tag variant="${propVals.variant}" size="${propVals.size}" iconPlacement="${propVals.iconPlacement}" ${propVals.isStrong ? 'isStrong' : ''} ${propVals.disabled ? 'disabled' : ''} ${propVals.isInteractive ? 'isInteractive' : ''}>${propVals.iconSlot} Hello world</pie-tag>`;

const componentPropsMatrix = getAllPropCombinations(props);
const componentPropsMatrixByVariant = splitCombinationsByPropertyValue(componentPropsMatrix, 'variant');
Expand All @@ -49,7 +53,9 @@ componentVariants.forEach((variant) => test(`should render all prop variations f
const propKeyValues = `
size: ${testComponent.propValues.size},
variant: ${testComponent.propValues.variant},
iconPlacement: ${testComponent.propValues.iconPlacement},
isStrong: ${testComponent.propValues.isStrong},
isInteractive: ${testComponent.propValues.isInteractive},
disabled: ${testComponent.propValues.disabled},
iconSlot: ${testComponent.propValues.iconSlot ? 'with icon' : 'no icon'}`;
const darkMode = ['neutral-alternative'].includes(variant);
Expand Down

0 comments on commit 294b5a0

Please sign in to comment.