Skip to content

Commit

Permalink
feat: add OnyxTag component (#941)
Browse files Browse the repository at this point in the history
Relates to #566

Add `OnyxTag` component

---------

Co-authored-by: nerdrun <[email protected]>
  • Loading branch information
larsrickert and nerdrun authored Apr 19, 2024
1 parent 53ac6e0 commit 288afbd
Show file tree
Hide file tree
Showing 15 changed files with 191 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/fair-scissors-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"sit-onyx": minor
---

feat: add `OnyxTag` component
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
36 changes: 36 additions & 0 deletions packages/sit-onyx/src/components/OnyxTag/OnyxTag.ct.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { DENSITIES } from "../../composables/density";
import { expect, test } from "../../playwright/a11y";
import { executeMatrixScreenshotTest, mockPlaywrightIcon } from "../../playwright/screenshots";
import { ONYX_COLORS } from "../../types/colors";
import OnyxTag from "./OnyxTag.vue";

test.describe("Screenshot tests", () => {
executeMatrixScreenshotTest({
name: "Tag",
columns: DENSITIES,
rows: ONYX_COLORS,
component: (column, row) => <OnyxTag label="Tag" density={column} color={row} />,
});

executeMatrixScreenshotTest({
name: "Tag (with icon)",
columns: DENSITIES,
rows: ONYX_COLORS,
component: (column, row) => (
<OnyxTag label="Tag" density={column} color={row} icon={mockPlaywrightIcon} />
),
});
});

test("should truncate text", async ({ mount }) => {
const label = "Very long label that should be truncated";

// ARRANGE
const component = await mount(<OnyxTag label={label} style="max-width: 8rem;" />);

// ASSERT
await expect(component).toContainText(label);

// ASSERT
await expect(component).toHaveScreenshot("truncation.png");
});
63 changes: 63 additions & 0 deletions packages/sit-onyx/src/components/OnyxTag/OnyxTag.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import check from "@sit-onyx/icons/check.svg?raw";
import { defineStorybookActionsAndVModels } from "@sit-onyx/storybook-utils";
import type { Meta, StoryObj } from "@storybook/vue3";
import {
createIconSourceCodeTransformer,
createTruncationDecorator,
defineIconSelectArgType,
} from "../../utils/storybook";
import OnyxTag from "./OnyxTag.vue";

/**
* Tags are succinct textual labels that provide single-worded information or hints to their related parent element.
*/
const meta: Meta<typeof OnyxTag> = {
title: "components/Tag",
...defineStorybookActionsAndVModels({
component: OnyxTag,
events: [],
argTypes: {
icon: defineIconSelectArgType(),
},
}),
parameters: {
docs: {
source: {
transform: createIconSourceCodeTransformer("icon"),
},
},
},
};

export default meta;
type Story = StoryObj<typeof OnyxTag>;

/**
* This example shows the tag in primary color.
*/
export const Primary = {
args: {
label: "Tag",
},
} satisfies Story;

/**
* This example shows the tag with an icon.
*/
export const WithIcon = {
args: {
label: "Done",
icon: check,
color: "success",
},
} satisfies Story;

/**
* This example shows the tag with truncation.
*/
export const WithTruncation = {
args: {
label: "Tag with a very long text that gets truncated",
},
decorators: createTruncationDecorator("10rem"),
} satisfies Story;
67 changes: 67 additions & 0 deletions packages/sit-onyx/src/components/OnyxTag/OnyxTag.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<script lang="ts" setup>
import { useDensity } from "../../composables/density";
import OnyxIcon from "../OnyxIcon/OnyxIcon.vue";
import type { OnyxTagProps } from "./types";
const props = withDefaults(defineProps<OnyxTagProps>(), {
color: "primary",
});
const { densityClass } = useDensity(props);
</script>

<template>
<div :class="['onyx-tag', `onyx-tag--${props.color}`, densityClass]">
<OnyxIcon v-if="props.icon" :icon="props.icon" size="16px" />
<span class="onyx-text onyx-truncation-ellipsis">{{ props.label }}</span>
</div>
</template>

<style lang="scss">
@use "../../styles/mixins/density.scss";
@use "../../styles/mixins/layers.scss";
.onyx-tag {
@include density.compact {
--onyx-tag-padding: 0 var(--onyx-spacing-3xs);
}
@include density.default {
--onyx-tag-padding: var(--onyx-spacing-5xs) var(--onyx-spacing-2xs);
}
@include density.cozy {
--onyx-tag-padding: var(--onyx-spacing-4xs) var(--onyx-spacing-xs);
}
@include layers.component() {
display: inline-flex;
align-items: center;
gap: var(--onyx-spacing-3xs);
max-width: 100%;
padding: var(--onyx-tag-padding);
border-radius: var(--onyx-radius-sm);
font-family: var(--onyx-font-family);
color: var(--onyx-tag-color);
border: var(--onyx-1px-in-rem) solid var(--onyx-tag-border-color);
background-color: var(--onyx-tag-background-color);
$colors: primary, secondary, neutral, danger, warning, success, info;
@each $color in $colors {
&--#{$color} {
--onyx-tag-background-color: var(--onyx-color-base-#{$color}-200);
--onyx-tag-border-color: var(--onyx-color-base-#{$color}-600);
@if $color == "neutral" {
// neutral does not have a bold color so we need to use medium here
--onyx-tag-color: var(--onyx-color-text-icons-neutral-medium);
} @else {
--onyx-tag-color: var(--onyx-color-text-icons-#{$color}-bold);
}
}
}
}
}
</style>
17 changes: 17 additions & 0 deletions packages/sit-onyx/src/components/OnyxTag/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { DensityProp } from "../../composables/density";
import type { OnyxColor } from "../../types/colors";

export type OnyxTagProps = DensityProp & {
/**
* The text content of the tag.
*/
label: string;
/**
* The color of the tag.
*/
color?: OnyxColor;
/**
* An icon which will be displayed on the left side of the label.
*/
icon?: string;
};
3 changes: 3 additions & 0 deletions packages/sit-onyx/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ export * from "./components/OnyxTable/types";
export { default as OnyxTooltip } from "./components/OnyxTooltip/OnyxTooltip.vue";
export * from "./components/OnyxTooltip/types";

export { default as OnyxTag } from "./components/OnyxTag/OnyxTag.vue";
export * from "./components/OnyxTag/types";

export * from "./composables/density";
export * from "./composables/scrollEnd";
export type { OnyxTranslations, ProvideI18nOptions } from "./i18n";
Expand Down

0 comments on commit 288afbd

Please sign in to comment.