@vectramindnpm/unified-design-system 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -111,36 +111,39 @@ independently confirmed visually.)
111
111
 
112
112
  `Button` originally had **19 `variant` values** conflating four unrelated things: color/
113
113
  emphasis, shape (pill vs. rounded), fixed footer sizing, and one-off page-specific skins.
114
- Redesigned into three independent, composable axes instead:
114
+ Redesigned into independent, composable axes instead:
115
115
 
116
116
  ```tsx
117
- variant: "primary" | "secondary" | "destructive" | "outline" | "ghost" | "link" // 6
117
+ variant: "primary" | "secondary" | "destructive" | "outline" | "ghost" | "link" // 6 semantic colors
118
+ | "borderPrimary" | "deptedit" | "submenu" // page-context presets
119
+ | "cancel" | "save" | "close"
120
+ | "formButtonSubmit" | "formButtonCancel" | "formButtonBack"
118
121
  size: "default" | "sm" | "lg" | "icon" | "iconLg" // unchanged
119
122
  shape?: "default" | "pill" // NEW
120
123
  selected?: boolean // unchanged
121
124
  ```
122
125
 
123
- Nothing else in this package used any variant beyond `"ghost"` internally (checked before
124
- making this change), and the package has no external consumers yet, so this was a clean
125
- breaking change with nothing to migrate. Mapping from the old 19 to the new API:
126
+ Originally shipped (v0.1.x) with only the 6 semantic colors — the 9 "preset" variants below
127
+ were deliberately left out, on the theory that fixed page-context styling (specific sizing +
128
+ a one-off color skin) belonged in a consumer's own `className`, not the shared component.
129
+ That held up fine in isolation, but once a real consumer (Firstpass-Neo) migrated ~90 call
130
+ sites, the same `className` string ended up duplicated across dozens of files with no single
131
+ place to update it. Re-added in v0.2.0 as named variants for exactly that reason — each is a
132
+ self-contained preset (see `PRESET_BASE`/`PRESET_OVERRIDE` in `button.tsx`) that doesn't
133
+ interact with `shape`/`selected` at all, so it's safe to combine with them if you ever need to
134
+ (you generally won't - just use the variant alone).
126
135
 
127
- | Old `variant` | New equivalent | Note |
136
+ Mapping from the original 19 to the current API:
137
+
138
+ | Old `variant` | Current equivalent | Note |
128
139
  |---|---|---|
129
- | `default` (purple) **and** `primary` (blue) | `variant="primary"` | Consolidated to one color — the token-driven `interactive-brand` (purple), not the hardcoded blue. If you specifically need the old blue, add `className="bg-[var(--color-brand-blue)]"`. |
140
+ | `default` (purple) **and** `primary` (blue) | `variant="primary"` | Consolidated to one color — the token-driven `interactive-brand` (purple), not the hardcoded blue. The two hex values are ~identical anyway (`#5D62B5` vs `#5c62bc`), so this is not a visible change. |
130
141
  | `secondary`, `destructive`, `outline`, `ghost` | same name, unchanged | No visual change. |
142
+ | `lang` | `variant="ghost"` | One-off page skin, not worth a dedicated preset for its single call site — the only difference from `ghost` was a missing hover effect, not worth preserving. |
131
143
  | `pill` | `shape="pill"` (with any `variant`) | Combine, e.g. `variant="outline" shape="pill"`. |
132
- | `borderPrimary` | `variant="outline"` | Brand-colored border was a one-off tint add `className="border-interactive-brand text-interactive-brand"` to restore it exactly. |
144
+ | `borderPrimary`, `deptedit`, `submenu`, `cancel`, `save`, `close`, `formButtonSubmit`, `formButtonCancel`, `formButtonBack` | same name, now a real `variant` again | Just `variant="cancel"` etc. no `shape`/`className` needed, each preset is fully self-contained. `deptedit` no longer includes the legacy `dept-edit-btn` className-sniffing hack (pass the variant explicitly). |
133
145
  | `refreshIcon` | **removed** — use `<ButtonIcon variant="refresh" />` | That's already `ButtonIcon`'s job; `Button` doesn't need to duplicate it. |
134
146
  | `selectedIcon` | **removed** — use `<ButtonIcon variant="filled" />` or `<Button variant="primary" size="icon">` | Same reasoning. |
135
- | `lang` | `variant="ghost"` + `className` | One-off page skin, not a reusable color. |
136
- | `submenu` | `variant="outline" shape="pill" size="sm"` + `className` | Same. |
137
- | `deptedit` | `variant="ghost"` + `className="text-interactive-brand hover:bg-[var(--color-ext-eef2ff)]"` | Also drops the legacy `dept-edit-btn` className-sniffing hack entirely. |
138
- | `cancel` | `variant="outline"` + `className="h-9 px-5 border-[var(--color-button-cancel)] text-[var(--color-button-cancel)]"` | Footer trio: fixed sizing + color both become explicit `className`, since they're page-context, not a semantic color. |
139
- | `save` | `variant="primary"` + `className="h-9 px-5"` | |
140
- | `close` | `variant="secondary"` + `className="h-9 px-5"` | |
141
- | `formButtonSubmit` | `variant="primary" shape="pill"` + `className="h-9 px-6"` | |
142
- | `formButtonCancel` | `variant="outline" shape="pill"` + `className` for the soft-pink tone | |
143
- | `formButtonBack` | `variant="outline" shape="pill"` + `className="h-9 px-6"` | |
144
147
 
145
148
  `link` is genuinely new (no old equivalent) — a text-only, underline-on-hover variant with
146
149
  no padding/height, the one common pattern the original 19 never actually had.
package/dist/index.cjs CHANGED
@@ -748,7 +748,17 @@ var buttonVariants = (0, import_class_variance_authority2.cva)(
748
748
  destructive: "",
749
749
  outline: "",
750
750
  ghost: "",
751
- link: ""
751
+ link: "",
752
+ // Page-context presets - see PRESET_BASE/PRESET_OVERRIDE.
753
+ borderPrimary: "",
754
+ deptedit: "",
755
+ submenu: "",
756
+ cancel: "",
757
+ save: "",
758
+ close: "",
759
+ formButtonSubmit: "",
760
+ formButtonCancel: "",
761
+ formButtonBack: ""
752
762
  },
753
763
  size: {
754
764
  default: "",
@@ -784,6 +794,28 @@ var variantClasses = {
784
794
  var variantStyles = {
785
795
  secondary: { ["--btn-secondary-color"]: color3.text.cancel }
786
796
  };
797
+ var PRESET_BASE = {
798
+ borderPrimary: "outline",
799
+ deptedit: "ghost",
800
+ submenu: "outline",
801
+ cancel: "outline",
802
+ save: "primary",
803
+ close: "secondary",
804
+ formButtonSubmit: "primary",
805
+ formButtonCancel: "outline",
806
+ formButtonBack: "outline"
807
+ };
808
+ var PRESET_OVERRIDE = {
809
+ borderPrimary: "border-interactive-brand text-interactive-brand rounded-lg",
810
+ deptedit: "rounded-lg transition-colors text-interactive-brand hover:bg-[var(--color-ext-eef2ff)]",
811
+ submenu: "px-[1.375rem] py-[0.1875rem] rounded-[0.7rem] text-[0.75rem] font-medium text-[var(--color-button-submenu-text)] border border-[var(--color-ext-0000001a)] bg-transparent whitespace-nowrap shrink-0 transition-colors",
812
+ cancel: "h-9 px-5 rounded-lg border border-[var(--color-button-cancel)] text-[var(--color-button-cancel)] bg-transparent hover:bg-[var(--color-button-cancel-hover-bg)] text-[0.8125rem] font-medium transition-colors",
813
+ save: "h-9 px-5 rounded-lg text-white bg-[var(--color-brand-blue)] hover:opacity-85 text-[0.8125rem] font-semibold transition-colors disabled:cursor-not-allowed",
814
+ close: "h-9 px-5 rounded-lg border border-neutral-350 text-neutral-700 bg-neutral-white hover:bg-neutral-100 text-[0.8125rem] font-medium transition-colors",
815
+ formButtonSubmit: "h-9 px-6 rounded-[50px] font-medium text-[0.8125rem] active:scale-[0.98] transition-all bg-interactive-brand text-white hover:bg-[var(--color-button-formsubmit-hover-bg)] shadow-sm hover:shadow-md disabled:bg-neutral-450 disabled:text-neutral-900 disabled:cursor-not-allowed disabled:hover:bg-neutral-350 disabled:shadow-none",
816
+ formButtonCancel: "h-9 px-6 rounded-[50px] font-medium text-[0.8125rem] active:scale-[0.98] transition-all bg-[var(--color-button-formcancel-bg)] hover:bg-[var(--color-button-formcancel-hover-bg)] text-[var(--color-toast-danger-bg)] shadow-none hover:shadow-none",
817
+ formButtonBack: "h-9 px-6 rounded-[50px] font-medium text-[0.8125rem] active:scale-[0.98] transition-all bg-neutral-white hover:bg-neutral-100 text-interactive-brand border border-interactive-brand shadow-none hover:shadow-none"
818
+ };
787
819
  var sizeClasses = {
788
820
  default: "px-4 py-1",
789
821
  sm: "h-8 px-3 py-2 rounded-md",
@@ -809,6 +841,8 @@ var Button = React4.forwardRef(
809
841
  const isPill = shape === "pill";
810
842
  const isLink = finalVariant === "link";
811
843
  const isIconButton = finalSize === "icon" || finalSize === "iconLg";
844
+ const colorBase = PRESET_BASE[finalVariant] ?? finalVariant;
845
+ const presetOverride = PRESET_OVERRIDE[finalVariant];
812
846
  const baseClasses2 = cn(
813
847
  "inline-flex items-center justify-center gap-2 font-medium text-body rounded-md disabled:opacity-50",
814
848
  isIconButton ? "focus:outline-none focus:ring-0 focus:ring-offset-0 focus-visible:outline-none focus-visible:ring-0 focus-visible:ring-offset-0 focus-within:ring-0" : "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-interactive-brand"
@@ -816,15 +850,18 @@ var Button = React4.forwardRef(
816
850
  const composed = cn(
817
851
  baseClasses2,
818
852
  isPill ? "rounded-full" : "",
819
- variantClasses[finalVariant],
853
+ variantClasses[colorBase],
820
854
  // Link never carries the size scale's own padding/height — it reads as inline text.
821
855
  isLink ? "h-auto p-0" : isPill ? pillSizeClasses[finalSize] : sizeClasses[finalSize],
822
856
  isPill ? selected ? pillSelected : pillUnselected : selected ? selectedGradient : "",
823
857
  isPill && props.disabled ? pillDisabled : "",
858
+ // Preset's own styling always wins over the base variant/size classes above it, but
859
+ // still loses to a `className` the consumer explicitly passes (buttonVariants(), next).
860
+ presetOverride,
824
861
  buttonVariants({ variant: finalVariant, size: finalSize, shape, className })
825
862
  );
826
863
  const mergedStyle = {
827
- ...variantStyles[finalVariant],
864
+ ...variantStyles[colorBase],
828
865
  ...isPill && selected ? { ["--pill-selected-bg"]: `${color3.text.blue}24` } : void 0,
829
866
  ...style
830
867
  };