@purpurds/badge 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ ._purpur-badge_yhork_1{font-family:var(--purpur-typography-family-default),Helvetica,Arial,"Lucida Grande",sans-serif;font-weight:var(--purpur-typography-weight-medium);font-size:var(--purpur-typography-scale-75);min-height:var(--purpur-spacing-200);border-radius:var(--purpur-border-radius-xs);line-height:1;padding:var(--purpur-spacing-50) var(--purpur-spacing-100);display:inline-flex;align-items:center;gap:var(--purpur-spacing-50)}._purpur-badge--attention_yhork_13{background-color:var(--purpur-color-background-status-attention);color:var(--purpur-color-text-status-attention)}._purpur-badge--special_yhork_17{background-color:var(--purpur-color-background-status-special);color:var(--purpur-color-text-status-special)}._purpur-badge--neutral_yhork_21{background-color:var(--purpur-color-background-status-neutral);color:var(--purpur-color-text-status-neutral)}._purpur-badge--information_yhork_25{background-color:var(--purpur-color-background-status-info-strong);color:var(--purpur-color-text-status-info-strong)}._purpur-badge--success_yhork_29{background-color:var(--purpur-color-background-status-success-strong);color:var(--purpur-color-text-status-success-strong)}._purpur-badge--warning_yhork_33{background-color:var(--purpur-color-background-status-warning-strong);color:var(--purpur-color-text-status-warning-strong)}._purpur-badge--error_yhork_37{background-color:var(--purpur-color-background-status-error-strong);color:var(--purpur-color-text-status-error-strong)}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@purpurds/badge",
3
+ "version": "3.0.0",
4
+ "license": "AGPL-3.0-only",
5
+ "main": "./dist/badge.cjs.js",
6
+ "types": "./dist/badge.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "require": "./dist/badge.cjs.js",
10
+ "systemjs": "./dist/badge.system.js",
11
+ "types": "./dist/badge.d.ts",
12
+ "default": "./dist/badge.es.js"
13
+ },
14
+ "./styles": "./dist/styles.css"
15
+ },
16
+ "source": "src/badge.tsx",
17
+ "dependencies": {
18
+ "classnames": "~2.5.0",
19
+ "@purpurds/icon": "3.0.0",
20
+ "@purpurds/tokens": "3.0.0"
21
+ },
22
+ "devDependencies": {
23
+ "@rushstack/eslint-patch": "~1.7.0",
24
+ "@storybook/blocks": "~7.6.0",
25
+ "@storybook/react": "~7.6.0",
26
+ "@telia/base-rig": "~8.2.0",
27
+ "@telia/react-rig": "~3.2.0",
28
+ "@testing-library/dom": "~9.3.3",
29
+ "@testing-library/jest-dom": "~6.3.0",
30
+ "@testing-library/react": "~14.1.2",
31
+ "@types/node": "18",
32
+ "@types/react-dom": "~18.2.17",
33
+ "@types/react": "~18.2.42",
34
+ "eslint-plugin-testing-library": "~6.2.0",
35
+ "eslint": "~8.56.0",
36
+ "jsdom": "~22.1.0",
37
+ "lint-staged": "~10.5.3",
38
+ "prettier": "~2.8.8",
39
+ "react-dom": "~18.2.0",
40
+ "react": "~18.2.0",
41
+ "typescript": "~5.2.2",
42
+ "vite": "~5.0.6",
43
+ "vitest": "~1.2.0",
44
+ "@purpurds/component-rig": "1.0.0"
45
+ },
46
+ "scripts": {
47
+ "build:dev": "vite",
48
+ "build:watch": "vite build --watch",
49
+ "build": "rm -rf dist && vite build && vite build --mode systemjs",
50
+ "ci:build": "rushx build",
51
+ "coverage": "vitest run --coverage",
52
+ "lint:fix": "eslint . --fix",
53
+ "lint": "lint-staged --no-stash 2>&1",
54
+ "sbdev": "rush sbdev",
55
+ "test:unit": "vitest run --passWithNoTests",
56
+ "test:watch": "vitest --watch",
57
+ "test": "rushx test:unit",
58
+ "typecheck": "tsc -p ./tsconfig.json"
59
+ }
60
+ }
package/readme.mdx ADDED
@@ -0,0 +1,56 @@
1
+ import { Meta, Stories, ArgTypes, Primary, Subtitle } from "@storybook/blocks";
2
+
3
+ import * as BadgeStories from "./src/badge.stories";
4
+ import packageInfo from "./package.json";
5
+
6
+ <Meta name="Docs" title="Components/Badge" of={BadgeStories} />
7
+
8
+ # Badge
9
+
10
+ <Subtitle>Version {packageInfo.version}</Subtitle>
11
+
12
+ ### Showcase
13
+
14
+ <Primary />
15
+
16
+ ### Properties
17
+
18
+ <ArgTypes />
19
+
20
+ ### Installation
21
+
22
+ #### Via NPM, in the monorepo
23
+
24
+ Add the dependency to your consumer app like `"@purpurds/badge": "x.y.z"`
25
+
26
+ ### Via NPM, outside the monorepo (build-time)
27
+
28
+ To install this package, you need to setup access to the new artifactory. [Click here to go to the guide on how to do that](https://github.com/telia-company/jfrog-documentation/blob/main/doc/JFrog/JFrog_Onboarding.md#getting-access-to-artifactory-and-other-jfrog-applications).
29
+
30
+ ---
31
+
32
+ In MyApp.tsx
33
+
34
+ ```tsx
35
+ import "@purpurds/badge/styles";
36
+ ```
37
+
38
+ and
39
+
40
+ ```tsx
41
+ import "@purpurds/badge/styles";
42
+ ```
43
+
44
+ In MyComponent.tsx
45
+
46
+ ```tsx
47
+ import { Badge } from "@purpurds/badge";
48
+
49
+ export const MyComponent = () => {
50
+ return (
51
+ <div>
52
+ <Badge {...someProps}>Some content</Badge>
53
+ </div>
54
+ );
55
+ };
56
+ ```
@@ -0,0 +1,49 @@
1
+ .purpur-badge {
2
+ font-family: var(--purpur-typography-family-default), Helvetica, Arial, "Lucida Grande",
3
+ sans-serif;
4
+ font-weight: var(--purpur-typography-weight-medium);
5
+ font-size: var(--purpur-typography-scale-75);
6
+
7
+ min-height: var(--purpur-spacing-200);
8
+ border-radius: var(--purpur-border-radius-xs);
9
+ line-height: 1;
10
+ padding: var(--purpur-spacing-50) var(--purpur-spacing-100);
11
+ display: inline-flex;
12
+ align-items: center;
13
+ gap: var(--purpur-spacing-50);
14
+
15
+ &--attention {
16
+ background-color: var(--purpur-color-background-status-attention);
17
+ color: var(--purpur-color-text-status-attention);
18
+ }
19
+
20
+ &--special {
21
+ background-color: var(--purpur-color-background-status-special);
22
+ color: var(--purpur-color-text-status-special);
23
+ }
24
+
25
+ &--neutral {
26
+ background-color: var(--purpur-color-background-status-neutral);
27
+ color: var(--purpur-color-text-status-neutral);
28
+ }
29
+
30
+ &--information {
31
+ background-color: var(--purpur-color-background-status-info-strong);
32
+ color: var(--purpur-color-text-status-info-strong);
33
+ }
34
+
35
+ &--success {
36
+ background-color: var(--purpur-color-background-status-success-strong);
37
+ color: var(--purpur-color-text-status-success-strong);
38
+ }
39
+
40
+ &--warning {
41
+ background-color: var(--purpur-color-background-status-warning-strong);
42
+ color: var(--purpur-color-text-status-warning-strong);
43
+ }
44
+
45
+ &--error {
46
+ background-color: var(--purpur-color-background-status-error-strong);
47
+ color: var(--purpur-color-text-status-error-strong);
48
+ }
49
+ }
@@ -0,0 +1,29 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+
3
+ import "@purpurds/icon/styles";
4
+ import { Badge, BADGE_VARIANT } from "./badge";
5
+
6
+ const meta: Meta<typeof Badge> = {
7
+ title: "Components/Badge",
8
+ component: Badge,
9
+ parameters: {
10
+ design: [
11
+ {
12
+ name: "Badge",
13
+ type: "figma",
14
+ url: "https://www.figma.com/file/XEaIIFskrrxIBHMZDkIuIg/Purpur-DS---Component-library-%26-guidelines?type=design&node-id=951%3A86&mode=design&t=Mx6nWh1kDdDxw6h1-1",
15
+ },
16
+ ],
17
+ },
18
+ };
19
+ export default meta;
20
+
21
+ type Story = StoryObj<typeof Badge>;
22
+
23
+ export const Showcase: Story = {
24
+ args: {
25
+ variant: BADGE_VARIANT.SUCCESS,
26
+ children: "Badge",
27
+ showIcon: true,
28
+ },
29
+ };
@@ -0,0 +1,55 @@
1
+ import React from "react";
2
+ import { fiveg, Icon } from "@purpurds/icon";
3
+ import * as matchers from "@testing-library/jest-dom/matchers";
4
+ import { cleanup, render, screen } from "@testing-library/react";
5
+ import { afterEach, describe, expect, it } from "vitest";
6
+
7
+ import { Badge } from "./badge";
8
+
9
+ expect.extend(matchers);
10
+
11
+ afterEach(() => {
12
+ cleanup();
13
+ });
14
+
15
+ describe("Badge", () => {
16
+ it("should render with badge variant with default icon", () => {
17
+ render(
18
+ <Badge data-testid="badge" variant="success" allyLabel="Testing badge">
19
+ Badge test
20
+ </Badge>
21
+ );
22
+
23
+ expect(screen.getByTestId("badge")).toHaveTextContent("Badge test");
24
+ expect(screen.getByTestId("badge").className).toContain("success");
25
+ expect(screen.getByTestId("badge-icon")).toBeInTheDocument();
26
+ expect(screen.getByTestId("badge-icon")).toHaveAttribute("aria-label", "Testing badge");
27
+ });
28
+
29
+ it("should render with badge variant without default icon", () => {
30
+ render(
31
+ <Badge data-testid="badge" variant="special" allyLabel="Testing badge">
32
+ Badge test
33
+ </Badge>
34
+ );
35
+
36
+ expect(screen.getByTestId("badge")).toHaveTextContent("Badge test");
37
+ expect(screen.getByTestId("badge").className).toContain("special");
38
+ expect(screen.queryByTestId("badge-icon")).not.toBeInTheDocument();
39
+ });
40
+
41
+ it("should render with custom icon", () => {
42
+ render(
43
+ <Badge data-testid="badge" variant="neutral" allyLabel="Testing badge">
44
+ <>
45
+ <Icon svg={fiveg} size="xs" data-testid="badge-custom-icon" />
46
+ Badge test
47
+ </>
48
+ </Badge>
49
+ );
50
+
51
+ expect(screen.getByTestId("badge")).toHaveTextContent("Badge test");
52
+ expect(screen.getByTestId("badge").className).toContain("neutral");
53
+ expect(screen.getByTestId("badge-custom-icon")).toBeInTheDocument();
54
+ });
55
+ });
package/src/badge.tsx ADDED
@@ -0,0 +1,64 @@
1
+ import React, { ReactNode } from "react";
2
+ import { alert, checkCircle, error, Icon } from "@purpurds/icon";
3
+ import c from "classnames";
4
+
5
+ import styles from "./badge.module.scss";
6
+ const rootClassName = "purpur-badge";
7
+
8
+ export const BADGE_VARIANT = {
9
+ ATTENTION: "attention",
10
+ SPECIAL: "special",
11
+ NEUTRAL: "neutral",
12
+ INFORMATION: "information",
13
+ SUCCESS: "success",
14
+ WARNING: "warning",
15
+ ERROR: "error",
16
+ } as const;
17
+
18
+ export const badgeVariants = Object.values(BADGE_VARIANT);
19
+ export type BadgeVariant = (typeof BADGE_VARIANT)[keyof typeof BADGE_VARIANT];
20
+
21
+ const getIcon = (variant: BadgeVariant) => {
22
+ switch (variant) {
23
+ case BADGE_VARIANT.SUCCESS:
24
+ return checkCircle;
25
+ case BADGE_VARIANT.WARNING:
26
+ return alert;
27
+ case BADGE_VARIANT.ERROR:
28
+ return error;
29
+ default:
30
+ return;
31
+ }
32
+ };
33
+
34
+ export type BadgeProps = {
35
+ children: ReactNode;
36
+ showIcon?: boolean;
37
+ variant: BadgeVariant;
38
+ ["data-testid"]?: string;
39
+ allyLabel?: string;
40
+ className?: string;
41
+ };
42
+
43
+ export const Badge = ({
44
+ children,
45
+ showIcon = true,
46
+ variant,
47
+ ["data-testid"]: dataTestid,
48
+ allyLabel,
49
+ className = "",
50
+ ...props
51
+ }: BadgeProps) => {
52
+ const icon = getIcon(variant);
53
+
54
+ const classes = c([className, styles[rootClassName], styles[`${rootClassName}--${variant}`]]);
55
+
56
+ return (
57
+ <span aria-label={allyLabel} className={classes} data-testid={dataTestid} {...props}>
58
+ {showIcon && icon && (
59
+ <Icon data-testid={`${dataTestid}-icon`} allyTitle={allyLabel} size="xs" svg={icon} />
60
+ )}
61
+ {children}
62
+ </span>
63
+ );
64
+ };
@@ -0,0 +1,4 @@
1
+ declare module "*.scss" {
2
+ const styles: { [className: string]: string };
3
+ export default styles;
4
+ }