From 8081fc2b3c6a9fd50afe2c2321edc7e26e3d419e Mon Sep 17 00:00:00 2001 From: Okke Harsta Date: Thu, 10 Sep 2026 11:43:58 +0200 Subject: [PATCH 1/2] Synced Figma variables --- packages/tokens/src/tokens.groenvermogen-nkph2.json | 6 +++--- packages/tokens/src/tokens.json | 2 +- .../tokens/src/tokens.shadcn-default-grey-background.json | 2 +- packages/tokens/src/tokens.shadcn-default.json | 6 +++--- packages/tokens/src/tokens.surf-blue-purple.json | 2 +- packages/tokens/src/tokens.surf-blue-turquoise.json | 2 +- packages/tokens/src/tokens.surf-blue-yellow.json | 2 +- packages/tokens/src/tokens.surf-green.json | 2 +- packages/tokens/src/tokens.surf-orange-turquoise.json | 6 +++--- packages/tokens/src/tokens.surf-orange.json | 2 +- packages/tokens/src/tokens.surf-pilot.json | 6 +++--- packages/tokens/src/tokens.surf-purple-orange.json | 2 +- packages/tokens/src/tokens.surf-purple.json | 2 +- packages/tokens/src/tokens.surf-yellow.json | 2 +- 14 files changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/tokens/src/tokens.groenvermogen-nkph2.json b/packages/tokens/src/tokens.groenvermogen-nkph2.json index a25d984d..e9a7a028 100644 --- a/packages/tokens/src/tokens.groenvermogen-nkph2.json +++ b/packages/tokens/src/tokens.groenvermogen-nkph2.json @@ -133,7 +133,7 @@ }, "border-subtle": { "$type": "color", - "$value": "rgba(0, 0, 0, 0.08)" + "$value": "rgba(0, 0, 0, 0.06)" }, "destructive-foreground": { "$type": "color", @@ -225,11 +225,11 @@ }, "danger-subtle": { "$type": "color", - "$value": "rgba(254, 226, 226, 1)" + "$value": "rgba(255, 224, 222, 1)" }, "danger-subtle-hover": { "$type": "color", - "$value": "rgba(254, 202, 202, 1)" + "$value": "rgba(246, 167, 163, 1)" }, "danger-subtle-foreground": { "$type": "color", diff --git a/packages/tokens/src/tokens.json b/packages/tokens/src/tokens.json index eb4e631c..d31418f4 100644 --- a/packages/tokens/src/tokens.json +++ b/packages/tokens/src/tokens.json @@ -133,7 +133,7 @@ }, "border-subtle": { "$type": "color", - "$value": "rgba(0, 0, 0, 0.08)" + "$value": "rgba(0, 0, 0, 0.06)" }, "destructive-foreground": { "$type": "color", diff --git a/packages/tokens/src/tokens.shadcn-default-grey-background.json b/packages/tokens/src/tokens.shadcn-default-grey-background.json index 2b8618a3..af48363b 100644 --- a/packages/tokens/src/tokens.shadcn-default-grey-background.json +++ b/packages/tokens/src/tokens.shadcn-default-grey-background.json @@ -133,7 +133,7 @@ }, "border-subtle": { "$type": "color", - "$value": "rgba(0, 0, 0, 0.08)" + "$value": "rgba(0, 0, 0, 0.06)" }, "destructive-foreground": { "$type": "color", diff --git a/packages/tokens/src/tokens.shadcn-default.json b/packages/tokens/src/tokens.shadcn-default.json index 1487e41f..f6f5e090 100644 --- a/packages/tokens/src/tokens.shadcn-default.json +++ b/packages/tokens/src/tokens.shadcn-default.json @@ -133,7 +133,7 @@ }, "border-subtle": { "$type": "color", - "$value": "rgba(0, 0, 0, 0.08)" + "$value": "rgba(0, 0, 0, 0.06)" }, "destructive-foreground": { "$type": "color", @@ -225,11 +225,11 @@ }, "danger-subtle": { "$type": "color", - "$value": "rgba(254, 226, 226, 1)" + "$value": "rgba(255, 224, 222, 1)" }, "danger-subtle-hover": { "$type": "color", - "$value": "rgba(254, 202, 202, 1)" + "$value": "rgba(246, 167, 163, 1)" }, "danger-subtle-foreground": { "$type": "color", diff --git a/packages/tokens/src/tokens.surf-blue-purple.json b/packages/tokens/src/tokens.surf-blue-purple.json index 90a6cb3a..8f8072dd 100644 --- a/packages/tokens/src/tokens.surf-blue-purple.json +++ b/packages/tokens/src/tokens.surf-blue-purple.json @@ -133,7 +133,7 @@ }, "border-subtle": { "$type": "color", - "$value": "rgba(0, 0, 0, 0.08)" + "$value": "rgba(0, 0, 0, 0.06)" }, "destructive-foreground": { "$type": "color", diff --git a/packages/tokens/src/tokens.surf-blue-turquoise.json b/packages/tokens/src/tokens.surf-blue-turquoise.json index e99dcd1b..d181f942 100644 --- a/packages/tokens/src/tokens.surf-blue-turquoise.json +++ b/packages/tokens/src/tokens.surf-blue-turquoise.json @@ -133,7 +133,7 @@ }, "border-subtle": { "$type": "color", - "$value": "rgba(0, 0, 0, 0.08)" + "$value": "rgba(0, 0, 0, 0.06)" }, "destructive-foreground": { "$type": "color", diff --git a/packages/tokens/src/tokens.surf-blue-yellow.json b/packages/tokens/src/tokens.surf-blue-yellow.json index 601c35dc..5a84b7ef 100644 --- a/packages/tokens/src/tokens.surf-blue-yellow.json +++ b/packages/tokens/src/tokens.surf-blue-yellow.json @@ -133,7 +133,7 @@ }, "border-subtle": { "$type": "color", - "$value": "rgba(0, 0, 0, 0.08)" + "$value": "rgba(0, 0, 0, 0.06)" }, "destructive-foreground": { "$type": "color", diff --git a/packages/tokens/src/tokens.surf-green.json b/packages/tokens/src/tokens.surf-green.json index 66eb90f7..9dd0e455 100644 --- a/packages/tokens/src/tokens.surf-green.json +++ b/packages/tokens/src/tokens.surf-green.json @@ -133,7 +133,7 @@ }, "border-subtle": { "$type": "color", - "$value": "rgba(0, 0, 0, 0.08)" + "$value": "rgba(0, 0, 0, 0.06)" }, "destructive-foreground": { "$type": "color", diff --git a/packages/tokens/src/tokens.surf-orange-turquoise.json b/packages/tokens/src/tokens.surf-orange-turquoise.json index 2f177dac..12159631 100644 --- a/packages/tokens/src/tokens.surf-orange-turquoise.json +++ b/packages/tokens/src/tokens.surf-orange-turquoise.json @@ -133,7 +133,7 @@ }, "border-subtle": { "$type": "color", - "$value": "rgba(0, 0, 0, 0.08)" + "$value": "rgba(0, 0, 0, 0.06)" }, "destructive-foreground": { "$type": "color", @@ -225,11 +225,11 @@ }, "danger-subtle": { "$type": "color", - "$value": "rgba(254, 226, 226, 1)" + "$value": "rgba(255, 224, 222, 1)" }, "danger-subtle-hover": { "$type": "color", - "$value": "rgba(254, 202, 202, 1)" + "$value": "rgba(246, 167, 163, 1)" }, "danger-subtle-foreground": { "$type": "color", diff --git a/packages/tokens/src/tokens.surf-orange.json b/packages/tokens/src/tokens.surf-orange.json index 022e766d..4d329d27 100644 --- a/packages/tokens/src/tokens.surf-orange.json +++ b/packages/tokens/src/tokens.surf-orange.json @@ -133,7 +133,7 @@ }, "border-subtle": { "$type": "color", - "$value": "rgba(0, 0, 0, 0.08)" + "$value": "rgba(0, 0, 0, 0.06)" }, "destructive-foreground": { "$type": "color", diff --git a/packages/tokens/src/tokens.surf-pilot.json b/packages/tokens/src/tokens.surf-pilot.json index d1aeae7f..23fd15d7 100644 --- a/packages/tokens/src/tokens.surf-pilot.json +++ b/packages/tokens/src/tokens.surf-pilot.json @@ -133,7 +133,7 @@ }, "border-subtle": { "$type": "color", - "$value": "rgba(0, 0, 0, 0.08)" + "$value": "rgba(0, 0, 0, 0.06)" }, "destructive-foreground": { "$type": "color", @@ -225,11 +225,11 @@ }, "danger-subtle": { "$type": "color", - "$value": "rgba(254, 226, 226, 1)" + "$value": "rgba(255, 224, 222, 1)" }, "danger-subtle-hover": { "$type": "color", - "$value": "rgba(254, 202, 202, 1)" + "$value": "rgba(246, 167, 163, 1)" }, "danger-subtle-foreground": { "$type": "color", diff --git a/packages/tokens/src/tokens.surf-purple-orange.json b/packages/tokens/src/tokens.surf-purple-orange.json index adb6e780..4939e913 100644 --- a/packages/tokens/src/tokens.surf-purple-orange.json +++ b/packages/tokens/src/tokens.surf-purple-orange.json @@ -133,7 +133,7 @@ }, "border-subtle": { "$type": "color", - "$value": "rgba(0, 0, 0, 0.08)" + "$value": "rgba(0, 0, 0, 0.06)" }, "destructive-foreground": { "$type": "color", diff --git a/packages/tokens/src/tokens.surf-purple.json b/packages/tokens/src/tokens.surf-purple.json index 94e6d17c..fc83fd42 100644 --- a/packages/tokens/src/tokens.surf-purple.json +++ b/packages/tokens/src/tokens.surf-purple.json @@ -133,7 +133,7 @@ }, "border-subtle": { "$type": "color", - "$value": "rgba(0, 0, 0, 0.08)" + "$value": "rgba(0, 0, 0, 0.06)" }, "destructive-foreground": { "$type": "color", diff --git a/packages/tokens/src/tokens.surf-yellow.json b/packages/tokens/src/tokens.surf-yellow.json index 4fb43c72..e52dbc3e 100644 --- a/packages/tokens/src/tokens.surf-yellow.json +++ b/packages/tokens/src/tokens.surf-yellow.json @@ -133,7 +133,7 @@ }, "border-subtle": { "$type": "color", - "$value": "rgba(0, 0, 0, 0.08)" + "$value": "rgba(0, 0, 0, 0.06)" }, "destructive-foreground": { "$type": "color", From 8762dda27928f5eb545810d68558835001c4fdca Mon Sep 17 00:00:00 2001 From: Okke Harsta Date: Thu, 10 Sep 2026 14:21:29 +0200 Subject: [PATCH 2/2] Add signal-color variants to Badge, rename destructive to danger Mirrors the Alert component's signal-color work: info/success/warning/ danger variants styled as a subtle tint (bg--subtle / text--subtle-foreground), per the Figma Badge spec (node 29163:153619). destructive is renamed to danger for naming parity with Alert; other existing variants (secondary/outline/ghost/ link) are untouched. Co-Authored-By: Claude Sonnet 5 --- .changeset/badge-signal-colors.md | 9 +++++++++ .../lib/ui/badge/src/lib/hlm-badge.stories.ts | 4 ++-- .../src/lib/ui/badge/src/lib/hlm-badge.ts | 9 +++++++-- packages/contracts/src/badge.ts | 17 +++++++++++++++-- .../src/components/ui/badge/badge.stories.tsx | 4 ++-- .../react/src/components/ui/badge/badge.tsx | 9 +++++++-- 6 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 .changeset/badge-signal-colors.md diff --git a/.changeset/badge-signal-colors.md b/.changeset/badge-signal-colors.md new file mode 100644 index 00000000..bbb3d273 --- /dev/null +++ b/.changeset/badge-signal-colors.md @@ -0,0 +1,9 @@ +--- +'@surfnet/curve-react': minor +'@surfnet/curve-angular': minor +'@surfnet/curve-contracts': minor +--- + +Add `info`, `success`, `warning`, and `danger` signal-color variants to the Badge component, styled as a subtle tint (`bg--subtle` / `text--subtle-foreground`), matching the Alert component's signal variants and the Figma spec. + +**Breaking:** the `destructive` variant is renamed to `danger`. Replace `variant="destructive"` with `variant="danger"` on `Badge` (Alert was already renamed in a previous release; other components are unaffected). diff --git a/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.stories.ts b/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.stories.ts index 13432a9e..6a865d8e 100644 --- a/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.stories.ts +++ b/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.stories.ts @@ -102,7 +102,7 @@ export const Counts: Story = { template: `
8 - 99 + 99 20+
`, }), @@ -130,7 +130,7 @@ export const StatusList: Story = {
  • Rotate API credentials - Overdue + Overdue
  • Archive old backups diff --git a/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.ts b/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.ts index fcb62ba9..7b68d845 100644 --- a/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.ts +++ b/packages/angular/src/lib/ui/badge/src/lib/hlm-badge.ts @@ -6,8 +6,13 @@ import { type VariantProps, cva } from 'class-variance-authority'; const badgeVariantClasses = { default: 'bg-primary text-primary-foreground [a]:hover:bg-primary/80', secondary: 'bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80', - destructive: - 'bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20', + info: 'bg-info-subtle text-info-subtle-foreground [a]:hover:bg-info-subtle-hover focus-visible:ring-info/20 dark:focus-visible:ring-info/40', + success: + 'bg-success-subtle text-success-subtle-foreground [a]:hover:bg-success-subtle-hover focus-visible:ring-success/20 dark:focus-visible:ring-success/40', + warning: + 'bg-warning-subtle text-warning-subtle-foreground [a]:hover:bg-warning-subtle-hover focus-visible:ring-warning/20 dark:focus-visible:ring-warning/40', + danger: + 'bg-danger-subtle text-danger-subtle-foreground [a]:hover:bg-danger-subtle-hover focus-visible:ring-danger/20 dark:focus-visible:ring-danger/40', outline: 'border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground', ghost: 'hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50', link: 'text-primary underline-offset-4 hover:underline', diff --git a/packages/contracts/src/badge.ts b/packages/contracts/src/badge.ts index c2816a33..a912d5ad 100644 --- a/packages/contracts/src/badge.ts +++ b/packages/contracts/src/badge.ts @@ -2,7 +2,17 @@ import { defineContract } from './define-contract.js'; export const badgeContract = defineContract({ props: { - variants: ['default', 'secondary', 'destructive', 'outline', 'ghost', 'link'], + variants: [ + 'default', + 'secondary', + 'info', + 'success', + 'warning', + 'danger', + 'outline', + 'ghost', + 'link', + ], }, defaults: { variants: 'default', @@ -12,7 +22,10 @@ export const badgeContract = defineContract({ variants: { default: 'Primary brand fill — the most prominent badge style.', secondary: 'Muted fill — general-purpose secondary label.', - destructive: 'Danger tint — errors, warnings, or destructive states.', + info: 'Informational tint — does not require immediate action.', + success: 'Success tint — confirms a successful action or state.', + warning: 'Warning tint — highlights something that needs attention.', + danger: 'Danger tint — errors, warnings, or destructive states.', outline: 'Bordered, transparent fill — low-emphasis label.', ghost: 'No background or border — minimal label.', link: 'Looks like a hyperlink — inline actionable label.', diff --git a/packages/react/src/components/ui/badge/badge.stories.tsx b/packages/react/src/components/ui/badge/badge.stories.tsx index b4672266..7c13a92f 100644 --- a/packages/react/src/components/ui/badge/badge.stories.tsx +++ b/packages/react/src/components/ui/badge/badge.stories.tsx @@ -70,7 +70,7 @@ export const Counts: Story = { render: () => (
    8 - + 99 @@ -106,7 +106,7 @@ export const StatusList: Story = {
  • Rotate API credentials - Overdue + Overdue
  • Archive old backups diff --git a/packages/react/src/components/ui/badge/badge.tsx b/packages/react/src/components/ui/badge/badge.tsx index a81649eb..b9c52b65 100644 --- a/packages/react/src/components/ui/badge/badge.tsx +++ b/packages/react/src/components/ui/badge/badge.tsx @@ -10,8 +10,13 @@ import { cn } from '@/lib/utils'; const badgeVariantClasses = { default: 'bg-primary text-primary-foreground [a]:hover:bg-primary/80', secondary: 'bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80', - destructive: - 'bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20', + info: 'bg-info-subtle text-info-subtle-foreground focus-visible:ring-info/20 dark:focus-visible:ring-info/40 [a]:hover:bg-info-subtle-hover', + success: + 'bg-success-subtle text-success-subtle-foreground focus-visible:ring-success/20 dark:focus-visible:ring-success/40 [a]:hover:bg-success-subtle-hover', + warning: + 'bg-warning-subtle text-warning-subtle-foreground focus-visible:ring-warning/20 dark:focus-visible:ring-warning/40 [a]:hover:bg-warning-subtle-hover', + danger: + 'bg-danger-subtle text-danger-subtle-foreground focus-visible:ring-danger/20 dark:focus-visible:ring-danger/40 [a]:hover:bg-danger-subtle-hover', outline: 'border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground', ghost: 'hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50', link: 'text-primary underline-offset-4 hover:underline',