@refinn/core-ui 0.1.15 → 0.1.17

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/dist/index.cjs CHANGED
@@ -553,6 +553,7 @@ var AlertBanner = (0, import_react5.forwardRef)(
553
553
  const descColorClass = isPage ? pageIsDark ? "text-alert-text-secondary" : "text-alert-text-secondary-inverse" : "text-alert-text-secondary";
554
554
  const linkColorClass = isPage ? pageIsDark ? "text-alert-text-primary" : "text-white-100" : "text-enabled";
555
555
  const closeButtonSurface = isPage ? "dark" : "default";
556
+ const hasIcon = Boolean(icon) || variant !== "none";
556
557
  const containerClasses = [
557
558
  "flex font-sans",
558
559
  isStacked ? "flex-col items-start gap-8" : "items-center gap-24",
@@ -561,7 +562,7 @@ var AlertBanner = (0, import_react5.forwardRef)(
561
562
  className
562
563
  ].filter(Boolean).join(" ");
563
564
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", __spreadProps(__spreadValues({ ref, role: "alert", className: containerClasses }, rest), { children: [
564
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `flex w-full items-start gap-8 ${isStacked ? "" : "flex-1 min-w-0"}`, children: [
565
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `flex w-full gap-8 ${isStacked ? "items-start" : "items-center flex-1 min-w-0"}`, children: [
565
566
  icon != null ? icon : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DefaultIcon, { className: `h-20 w-20 shrink-0 ${iconColorClass}` }),
566
567
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex-1 min-w-0 flex flex-col gap-2", children: [
567
568
  title && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: `text-label-medium ${titleColorClass}`, children: title }),
@@ -590,7 +591,7 @@ var AlertBanner = (0, import_react5.forwardRef)(
590
591
  }
591
592
  )
592
593
  ] }),
593
- isStacked && buttonAction && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex w-full items-start gap-12 pl-28", children: isPage ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Button, { variant: "secondary", size: "sm", onClick: buttonAction.onClick, children: buttonAction.label }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
594
+ isStacked && buttonAction && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: `flex w-full items-start gap-12 ${hasIcon ? "pl-28" : ""}`, children: isPage ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Button, { variant: "secondary", size: "sm", onClick: buttonAction.onClick, children: buttonAction.label }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
594
595
  "a",
595
596
  {
596
597
  href: buttonAction.href,
@@ -1049,70 +1050,107 @@ Checkbox.displayName = "Checkbox";
1049
1050
  // src/components/Chip/Chip.tsx
1050
1051
  var import_react10 = require("react");
1051
1052
  var import_jsx_runtime10 = require("react/jsx-runtime");
1052
- var sizeClasses5 = {
1053
- sm: "h-32 text-label-medium px-12 py-6",
1054
- md: "h-40 text-label-large px-16 py-10",
1055
- lg: "h-48 text-label-large px-24 py-14"
1053
+ var sizeBaseClasses = {
1054
+ sm: "min-h-32 min-w-56 gap-4 py-2 text-label-medium",
1055
+ md: "min-h-40 min-w-56 gap-8 py-4 text-label-large",
1056
+ lg: "min-h-48 min-w-96 gap-8 py-8 text-label-large"
1056
1057
  };
1057
- var marginImgClasses = {
1058
- sm: "-ml-10 -my-4 h-28 w-28",
1059
- md: "-ml-12 -my-6 h-32 w-32",
1060
- lg: "-ml-18 -my-8 h-32 w-32"
1058
+ var paddingXClasses = {
1059
+ sm: "px-12",
1060
+ md: "px-16",
1061
+ lg: "px-24"
1061
1062
  };
1062
- var isOutlinedClasses = {
1063
- true: "border border-chip-border-enabled bg-chip-background-inverse",
1064
- false: "border-0 bg-chip-background-enabled"
1065
- };
1066
- var isDarkClasses = {
1067
- true: "!bg-chip-background-black-active !text-chip-text-inverse",
1068
- false: "!bg-chip-background-active !text-chip-text-inverse"
1063
+ var bankLogoPaddingXClasses = {
1064
+ md: "pl-4 pr-16",
1065
+ lg: "pl-8 pr-16"
1069
1066
  };
1067
+ function toneClasses(selected, outline, variant) {
1068
+ if (selected) {
1069
+ return variant === "dark" ? "bg-chip-background-black-active text-chip-text-inverse hover:bg-chip-background-black-active-hover group-disabled:bg-chip-background-active-disabled group-disabled:text-chip-text-inverse-disabled" : "bg-chip-background-active text-chip-text-inverse hover:bg-chip-background-active-hover group-disabled:bg-chip-background-active-disabled group-disabled:text-chip-text-inverse-disabled";
1070
+ }
1071
+ if (outline) {
1072
+ return "bg-chip-background-inverse text-chip-text-enabled border border-chip-border-enabled hover:bg-chip-background-hover hover:border-chip-border-hover group-disabled:text-chip-text-disabled";
1073
+ }
1074
+ return "bg-chip-background-enabled text-chip-text-enabled hover:bg-chip-background-hover group-disabled:bg-chip-background-disabled group-disabled:text-chip-text-disabled";
1075
+ }
1070
1076
  var Chip = (0, import_react10.forwardRef)(
1071
1077
  (_a, ref) => {
1072
1078
  var _b = _a, {
1073
1079
  size = "md",
1074
- src,
1075
- alt = "",
1076
1080
  label,
1077
- icon,
1078
- isOutlined = false,
1079
- isDark = false,
1080
- isSelected = false,
1081
+ variant = "brand",
1082
+ outline = false,
1083
+ selected,
1084
+ defaultSelected = false,
1085
+ onSelectedChange,
1086
+ startIcon,
1087
+ endIcon,
1088
+ bankLogoSrc,
1089
+ bankLogoAlt = "",
1081
1090
  disabled = false,
1091
+ onClick,
1082
1092
  className = ""
1083
1093
  } = _b, rest = __objRest(_b, [
1084
1094
  "size",
1085
- "src",
1086
- "alt",
1087
1095
  "label",
1088
- "icon",
1089
- "isOutlined",
1090
- "isDark",
1091
- "isSelected",
1096
+ "variant",
1097
+ "outline",
1098
+ "selected",
1099
+ "defaultSelected",
1100
+ "onSelectedChange",
1101
+ "startIcon",
1102
+ "endIcon",
1103
+ "bankLogoSrc",
1104
+ "bankLogoAlt",
1092
1105
  "disabled",
1106
+ "onClick",
1093
1107
  "className"
1094
1108
  ]);
1095
- const sz = sizeClasses5[size];
1096
- const outlinedClass = isOutlinedClasses[String(isOutlined)];
1097
- const darkClass = isDarkClasses[String(isDark)];
1098
- const containerClasses = [
1099
- "w-fit rounded-full flex flex-row gap-8 items-center justify-center text-chip-text-enabled",
1109
+ const [uncontrolledSelected, setUncontrolledSelected] = (0, import_react10.useState)(defaultSelected);
1110
+ const isSelected = selected != null ? selected : uncontrolledSelected;
1111
+ const showBankLogo = Boolean(bankLogoSrc) && size !== "sm";
1112
+ const handleClick = (event) => {
1113
+ onClick == null ? void 0 : onClick(event);
1114
+ if (event.defaultPrevented) return;
1115
+ const next = !isSelected;
1116
+ if (selected === void 0) setUncontrolledSelected(next);
1117
+ onSelectedChange == null ? void 0 : onSelectedChange(next);
1118
+ };
1119
+ const wrapperClasses = [
1120
+ "group rounded-full border-2 border-transparent p-2 outline-none",
1121
+ "transition-colors",
1100
1122
  disabled ? "cursor-not-allowed" : "cursor-pointer",
1101
- outlinedClass,
1102
- sz,
1103
- className,
1104
- isSelected ? darkClass : ""
1123
+ "focus-visible:border-chip-border-focus",
1124
+ className
1105
1125
  ].filter(Boolean).join(" ");
1106
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1107
- "div",
1126
+ const baseClasses = [
1127
+ "flex items-center justify-center rounded-full transition-colors",
1128
+ sizeBaseClasses[size],
1129
+ showBankLogo ? bankLogoPaddingXClasses[size] : paddingXClasses[size],
1130
+ toneClasses(isSelected, outline && !isSelected, variant)
1131
+ ].filter(Boolean).join(" ");
1132
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1133
+ "button",
1108
1134
  __spreadProps(__spreadValues({
1109
1135
  ref,
1110
- className: containerClasses
1136
+ type: "button",
1137
+ disabled,
1138
+ "aria-pressed": isSelected,
1139
+ onClick: handleClick,
1140
+ className: wrapperClasses
1111
1141
  }, rest), {
1112
- children: [
1113
- icon ? icon : src && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("img", { src, alt, className: `${marginImgClasses[size]} rounded-full` }),
1114
- label
1115
- ]
1142
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: baseClasses, children: [
1143
+ showBankLogo ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1144
+ "img",
1145
+ {
1146
+ src: bankLogoSrc,
1147
+ alt: bankLogoAlt,
1148
+ className: "size-32 shrink-0 rounded-full object-contain"
1149
+ }
1150
+ ) : startIcon,
1151
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "min-w-0 truncate", children: label }),
1152
+ !showBankLogo && endIcon
1153
+ ] })
1116
1154
  })
1117
1155
  );
1118
1156
  }
@@ -2507,25 +2545,43 @@ Radio.displayName = "Radio";
2507
2545
  // src/components/SegmentControl/SegmentControl.tsx
2508
2546
  var import_react20 = require("react");
2509
2547
  var import_jsx_runtime20 = require("react/jsx-runtime");
2548
+ var itemSizeClasses = {
2549
+ sm: "min-h-32 px-8 py-6 text-label-medium",
2550
+ md: "min-h-40 px-12 py-8 text-label-large",
2551
+ lg: "min-h-48 px-16 py-8 text-label-large"
2552
+ };
2510
2553
  var SegmentControl = (0, import_react20.forwardRef)(
2511
2554
  (_a, ref) => {
2512
- var _b = _a, { size = "md", items, selected, setSelected, className = "" } = _b, rest = __objRest(_b, ["size", "items", "selected", "setSelected", "className"]);
2555
+ var _b = _a, { size = "md", items, selected, setSelected, onChange, className = "" } = _b, rest = __objRest(_b, ["size", "items", "selected", "setSelected", "onChange", "className"]);
2513
2556
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2514
2557
  "div",
2515
2558
  __spreadProps(__spreadValues({
2516
2559
  ref,
2517
- className: `bg-background-tertiary rounded-full flex flex-row items-center justify-center p-4 gap-4 ${className}`
2560
+ className: `bg-background-tertiary rounded-full flex flex-row items-center p-4 gap-4 ${className}`
2518
2561
  }, rest), {
2519
- children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2520
- "div",
2521
- {
2522
- onClick: () => setSelected == null ? void 0 : setSelected(item.value),
2523
- className: `cursor-pointer rounded-full text-center grow
2524
- ${size === "sm" ? "px-8 py-6 text-label-medium" : size === "md" ? "px-12 py-10 text-label-large" : "px-16 py-14 text-label-large"} ${selected === item.value ? "bg-segmented-control-background-active shadow-base text-segmented-control-text-primary hover:bg-segmented-control-background-active-hover" : "bg-segmented-control-background-enabled text-segmented-control-text-primary hover:bg-segmented-control-background-hover"} `,
2525
- children: item.label
2526
- },
2527
- item.value
2528
- ))
2562
+ children: items.map((item) => {
2563
+ const isSelected = selected === item.value;
2564
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2565
+ "button",
2566
+ {
2567
+ type: "button",
2568
+ "aria-pressed": isSelected,
2569
+ onClick: () => {
2570
+ setSelected == null ? void 0 : setSelected(item.value);
2571
+ onChange == null ? void 0 : onChange(item.value);
2572
+ },
2573
+ className: "group flex-1 min-w-0 rounded-full border-2 border-transparent p-2 outline-none cursor-pointer transition-colors focus-visible:border-segmented-control-border-focus",
2574
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2575
+ "span",
2576
+ {
2577
+ className: `flex w-full items-center justify-center rounded-full text-center transition-colors ${itemSizeClasses[size]} ${isSelected ? "bg-segmented-control-background-active text-segmented-control-text-inverse shadow-small group-focus-visible:bg-segmented-control-background-active-focus group-focus-visible:text-segmented-control-text-primary" : "text-segmented-control-text-primary hover:bg-segmented-control-background-hover"}`,
2578
+ children: item.label
2579
+ }
2580
+ )
2581
+ },
2582
+ item.value
2583
+ );
2584
+ })
2529
2585
  })
2530
2586
  );
2531
2587
  }
package/dist/index.d.mts CHANGED
@@ -92,18 +92,24 @@ interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "siz
92
92
  declare const Checkbox: react.ForwardRefExoticComponent<CheckboxProps & react.RefAttributes<HTMLInputElement>>;
93
93
 
94
94
  type ChipSize = "sm" | "md" | "lg";
95
- interface ChipProps extends HTMLAttributes<HTMLDivElement> {
95
+ type ChipVariant = "brand" | "dark";
96
+ interface ChipProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "onChange"> {
96
97
  size?: ChipSize;
97
- src?: string;
98
- alt?: string;
99
98
  label: string;
100
- icon?: ReactNode;
101
- isOutlined?: boolean;
102
- isDark?: boolean;
103
- isSelected?: boolean;
104
- disabled?: boolean;
99
+ /** Only affects the selected appearance — unselected chips look the same for both variants. */
100
+ variant?: ChipVariant;
101
+ /** Ignored while selected — selection always renders as a solid chip. */
102
+ outline?: boolean;
103
+ selected?: boolean;
104
+ defaultSelected?: boolean;
105
+ onSelectedChange?: (selected: boolean) => void;
106
+ startIcon?: ReactNode;
107
+ endIcon?: ReactNode;
108
+ /** Renders a circular financial-institution logo in place of startIcon. Not supported at size "sm". */
109
+ bankLogoSrc?: string;
110
+ bankLogoAlt?: string;
105
111
  }
106
- declare const Chip: react.ForwardRefExoticComponent<ChipProps & react.RefAttributes<HTMLDivElement>>;
112
+ declare const Chip: react.ForwardRefExoticComponent<ChipProps & react.RefAttributes<HTMLButtonElement>>;
107
113
 
108
114
  type TextFieldSize = "md" | "lg";
109
115
  interface TextFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "prefix"> {
@@ -270,7 +276,7 @@ interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size"
270
276
  declare const Radio: react.ForwardRefExoticComponent<RadioProps & react.RefAttributes<HTMLInputElement>>;
271
277
 
272
278
  type SegmentControlSize = "sm" | "md" | "lg";
273
- interface SegmentControlProps extends HTMLAttributes<HTMLDivElement> {
279
+ interface SegmentControlProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> {
274
280
  size?: SegmentControlSize;
275
281
  items: {
276
282
  label: string;
@@ -278,6 +284,7 @@ interface SegmentControlProps extends HTMLAttributes<HTMLDivElement> {
278
284
  }[];
279
285
  selected: string;
280
286
  setSelected?: (value: string) => void;
287
+ onChange?: (value: string) => void;
281
288
  }
282
289
  declare const SegmentControl: react.ForwardRefExoticComponent<SegmentControlProps & react.RefAttributes<HTMLDivElement>>;
283
290
 
package/dist/index.d.ts CHANGED
@@ -92,18 +92,24 @@ interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "siz
92
92
  declare const Checkbox: react.ForwardRefExoticComponent<CheckboxProps & react.RefAttributes<HTMLInputElement>>;
93
93
 
94
94
  type ChipSize = "sm" | "md" | "lg";
95
- interface ChipProps extends HTMLAttributes<HTMLDivElement> {
95
+ type ChipVariant = "brand" | "dark";
96
+ interface ChipProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "onChange"> {
96
97
  size?: ChipSize;
97
- src?: string;
98
- alt?: string;
99
98
  label: string;
100
- icon?: ReactNode;
101
- isOutlined?: boolean;
102
- isDark?: boolean;
103
- isSelected?: boolean;
104
- disabled?: boolean;
99
+ /** Only affects the selected appearance — unselected chips look the same for both variants. */
100
+ variant?: ChipVariant;
101
+ /** Ignored while selected — selection always renders as a solid chip. */
102
+ outline?: boolean;
103
+ selected?: boolean;
104
+ defaultSelected?: boolean;
105
+ onSelectedChange?: (selected: boolean) => void;
106
+ startIcon?: ReactNode;
107
+ endIcon?: ReactNode;
108
+ /** Renders a circular financial-institution logo in place of startIcon. Not supported at size "sm". */
109
+ bankLogoSrc?: string;
110
+ bankLogoAlt?: string;
105
111
  }
106
- declare const Chip: react.ForwardRefExoticComponent<ChipProps & react.RefAttributes<HTMLDivElement>>;
112
+ declare const Chip: react.ForwardRefExoticComponent<ChipProps & react.RefAttributes<HTMLButtonElement>>;
107
113
 
108
114
  type TextFieldSize = "md" | "lg";
109
115
  interface TextFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size" | "prefix"> {
@@ -270,7 +276,7 @@ interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size"
270
276
  declare const Radio: react.ForwardRefExoticComponent<RadioProps & react.RefAttributes<HTMLInputElement>>;
271
277
 
272
278
  type SegmentControlSize = "sm" | "md" | "lg";
273
- interface SegmentControlProps extends HTMLAttributes<HTMLDivElement> {
279
+ interface SegmentControlProps extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> {
274
280
  size?: SegmentControlSize;
275
281
  items: {
276
282
  label: string;
@@ -278,6 +284,7 @@ interface SegmentControlProps extends HTMLAttributes<HTMLDivElement> {
278
284
  }[];
279
285
  selected: string;
280
286
  setSelected?: (value: string) => void;
287
+ onChange?: (value: string) => void;
281
288
  }
282
289
  declare const SegmentControl: react.ForwardRefExoticComponent<SegmentControlProps & react.RefAttributes<HTMLDivElement>>;
283
290
 
package/dist/index.js CHANGED
@@ -510,6 +510,7 @@ var AlertBanner = forwardRef5(
510
510
  const descColorClass = isPage ? pageIsDark ? "text-alert-text-secondary" : "text-alert-text-secondary-inverse" : "text-alert-text-secondary";
511
511
  const linkColorClass = isPage ? pageIsDark ? "text-alert-text-primary" : "text-white-100" : "text-enabled";
512
512
  const closeButtonSurface = isPage ? "dark" : "default";
513
+ const hasIcon = Boolean(icon) || variant !== "none";
513
514
  const containerClasses = [
514
515
  "flex font-sans",
515
516
  isStacked ? "flex-col items-start gap-8" : "items-center gap-24",
@@ -518,7 +519,7 @@ var AlertBanner = forwardRef5(
518
519
  className
519
520
  ].filter(Boolean).join(" ");
520
521
  return /* @__PURE__ */ jsxs4("div", __spreadProps(__spreadValues({ ref, role: "alert", className: containerClasses }, rest), { children: [
521
- /* @__PURE__ */ jsxs4("div", { className: `flex w-full items-start gap-8 ${isStacked ? "" : "flex-1 min-w-0"}`, children: [
522
+ /* @__PURE__ */ jsxs4("div", { className: `flex w-full gap-8 ${isStacked ? "items-start" : "items-center flex-1 min-w-0"}`, children: [
522
523
  icon != null ? icon : /* @__PURE__ */ jsx5(DefaultIcon, { className: `h-20 w-20 shrink-0 ${iconColorClass}` }),
523
524
  /* @__PURE__ */ jsxs4("div", { className: "flex-1 min-w-0 flex flex-col gap-2", children: [
524
525
  title && /* @__PURE__ */ jsx5("p", { className: `text-label-medium ${titleColorClass}`, children: title }),
@@ -547,7 +548,7 @@ var AlertBanner = forwardRef5(
547
548
  }
548
549
  )
549
550
  ] }),
550
- isStacked && buttonAction && /* @__PURE__ */ jsx5("div", { className: "flex w-full items-start gap-12 pl-28", children: isPage ? /* @__PURE__ */ jsx5(Button, { variant: "secondary", size: "sm", onClick: buttonAction.onClick, children: buttonAction.label }) : /* @__PURE__ */ jsxs4(
551
+ isStacked && buttonAction && /* @__PURE__ */ jsx5("div", { className: `flex w-full items-start gap-12 ${hasIcon ? "pl-28" : ""}`, children: isPage ? /* @__PURE__ */ jsx5(Button, { variant: "secondary", size: "sm", onClick: buttonAction.onClick, children: buttonAction.label }) : /* @__PURE__ */ jsxs4(
551
552
  "a",
552
553
  {
553
554
  href: buttonAction.href,
@@ -1011,73 +1012,111 @@ Checkbox.displayName = "Checkbox";
1011
1012
 
1012
1013
  // src/components/Chip/Chip.tsx
1013
1014
  import {
1014
- forwardRef as forwardRef10
1015
+ forwardRef as forwardRef10,
1016
+ useState as useState3
1015
1017
  } from "react";
1016
1018
  import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1017
- var sizeClasses5 = {
1018
- sm: "h-32 text-label-medium px-12 py-6",
1019
- md: "h-40 text-label-large px-16 py-10",
1020
- lg: "h-48 text-label-large px-24 py-14"
1019
+ var sizeBaseClasses = {
1020
+ sm: "min-h-32 min-w-56 gap-4 py-2 text-label-medium",
1021
+ md: "min-h-40 min-w-56 gap-8 py-4 text-label-large",
1022
+ lg: "min-h-48 min-w-96 gap-8 py-8 text-label-large"
1021
1023
  };
1022
- var marginImgClasses = {
1023
- sm: "-ml-10 -my-4 h-28 w-28",
1024
- md: "-ml-12 -my-6 h-32 w-32",
1025
- lg: "-ml-18 -my-8 h-32 w-32"
1024
+ var paddingXClasses = {
1025
+ sm: "px-12",
1026
+ md: "px-16",
1027
+ lg: "px-24"
1026
1028
  };
1027
- var isOutlinedClasses = {
1028
- true: "border border-chip-border-enabled bg-chip-background-inverse",
1029
- false: "border-0 bg-chip-background-enabled"
1030
- };
1031
- var isDarkClasses = {
1032
- true: "!bg-chip-background-black-active !text-chip-text-inverse",
1033
- false: "!bg-chip-background-active !text-chip-text-inverse"
1029
+ var bankLogoPaddingXClasses = {
1030
+ md: "pl-4 pr-16",
1031
+ lg: "pl-8 pr-16"
1034
1032
  };
1033
+ function toneClasses(selected, outline, variant) {
1034
+ if (selected) {
1035
+ return variant === "dark" ? "bg-chip-background-black-active text-chip-text-inverse hover:bg-chip-background-black-active-hover group-disabled:bg-chip-background-active-disabled group-disabled:text-chip-text-inverse-disabled" : "bg-chip-background-active text-chip-text-inverse hover:bg-chip-background-active-hover group-disabled:bg-chip-background-active-disabled group-disabled:text-chip-text-inverse-disabled";
1036
+ }
1037
+ if (outline) {
1038
+ return "bg-chip-background-inverse text-chip-text-enabled border border-chip-border-enabled hover:bg-chip-background-hover hover:border-chip-border-hover group-disabled:text-chip-text-disabled";
1039
+ }
1040
+ return "bg-chip-background-enabled text-chip-text-enabled hover:bg-chip-background-hover group-disabled:bg-chip-background-disabled group-disabled:text-chip-text-disabled";
1041
+ }
1035
1042
  var Chip = forwardRef10(
1036
1043
  (_a, ref) => {
1037
1044
  var _b = _a, {
1038
1045
  size = "md",
1039
- src,
1040
- alt = "",
1041
1046
  label,
1042
- icon,
1043
- isOutlined = false,
1044
- isDark = false,
1045
- isSelected = false,
1047
+ variant = "brand",
1048
+ outline = false,
1049
+ selected,
1050
+ defaultSelected = false,
1051
+ onSelectedChange,
1052
+ startIcon,
1053
+ endIcon,
1054
+ bankLogoSrc,
1055
+ bankLogoAlt = "",
1046
1056
  disabled = false,
1057
+ onClick,
1047
1058
  className = ""
1048
1059
  } = _b, rest = __objRest(_b, [
1049
1060
  "size",
1050
- "src",
1051
- "alt",
1052
1061
  "label",
1053
- "icon",
1054
- "isOutlined",
1055
- "isDark",
1056
- "isSelected",
1062
+ "variant",
1063
+ "outline",
1064
+ "selected",
1065
+ "defaultSelected",
1066
+ "onSelectedChange",
1067
+ "startIcon",
1068
+ "endIcon",
1069
+ "bankLogoSrc",
1070
+ "bankLogoAlt",
1057
1071
  "disabled",
1072
+ "onClick",
1058
1073
  "className"
1059
1074
  ]);
1060
- const sz = sizeClasses5[size];
1061
- const outlinedClass = isOutlinedClasses[String(isOutlined)];
1062
- const darkClass = isDarkClasses[String(isDark)];
1063
- const containerClasses = [
1064
- "w-fit rounded-full flex flex-row gap-8 items-center justify-center text-chip-text-enabled",
1075
+ const [uncontrolledSelected, setUncontrolledSelected] = useState3(defaultSelected);
1076
+ const isSelected = selected != null ? selected : uncontrolledSelected;
1077
+ const showBankLogo = Boolean(bankLogoSrc) && size !== "sm";
1078
+ const handleClick = (event) => {
1079
+ onClick == null ? void 0 : onClick(event);
1080
+ if (event.defaultPrevented) return;
1081
+ const next = !isSelected;
1082
+ if (selected === void 0) setUncontrolledSelected(next);
1083
+ onSelectedChange == null ? void 0 : onSelectedChange(next);
1084
+ };
1085
+ const wrapperClasses = [
1086
+ "group rounded-full border-2 border-transparent p-2 outline-none",
1087
+ "transition-colors",
1065
1088
  disabled ? "cursor-not-allowed" : "cursor-pointer",
1066
- outlinedClass,
1067
- sz,
1068
- className,
1069
- isSelected ? darkClass : ""
1089
+ "focus-visible:border-chip-border-focus",
1090
+ className
1070
1091
  ].filter(Boolean).join(" ");
1071
- return /* @__PURE__ */ jsxs9(
1072
- "div",
1092
+ const baseClasses = [
1093
+ "flex items-center justify-center rounded-full transition-colors",
1094
+ sizeBaseClasses[size],
1095
+ showBankLogo ? bankLogoPaddingXClasses[size] : paddingXClasses[size],
1096
+ toneClasses(isSelected, outline && !isSelected, variant)
1097
+ ].filter(Boolean).join(" ");
1098
+ return /* @__PURE__ */ jsx10(
1099
+ "button",
1073
1100
  __spreadProps(__spreadValues({
1074
1101
  ref,
1075
- className: containerClasses
1102
+ type: "button",
1103
+ disabled,
1104
+ "aria-pressed": isSelected,
1105
+ onClick: handleClick,
1106
+ className: wrapperClasses
1076
1107
  }, rest), {
1077
- children: [
1078
- icon ? icon : src && /* @__PURE__ */ jsx10("img", { src, alt, className: `${marginImgClasses[size]} rounded-full` }),
1079
- label
1080
- ]
1108
+ children: /* @__PURE__ */ jsxs9("span", { className: baseClasses, children: [
1109
+ showBankLogo ? /* @__PURE__ */ jsx10(
1110
+ "img",
1111
+ {
1112
+ src: bankLogoSrc,
1113
+ alt: bankLogoAlt,
1114
+ className: "size-32 shrink-0 rounded-full object-contain"
1115
+ }
1116
+ ) : startIcon,
1117
+ /* @__PURE__ */ jsx10("span", { className: "min-w-0 truncate", children: label }),
1118
+ !showBankLogo && endIcon
1119
+ ] })
1081
1120
  })
1082
1121
  );
1083
1122
  }
@@ -2499,29 +2538,45 @@ var Radio = forwardRef19(
2499
2538
  Radio.displayName = "Radio";
2500
2539
 
2501
2540
  // src/components/SegmentControl/SegmentControl.tsx
2502
- import {
2503
- forwardRef as forwardRef20
2504
- } from "react";
2541
+ import { forwardRef as forwardRef20 } from "react";
2505
2542
  import { jsx as jsx20 } from "react/jsx-runtime";
2543
+ var itemSizeClasses = {
2544
+ sm: "min-h-32 px-8 py-6 text-label-medium",
2545
+ md: "min-h-40 px-12 py-8 text-label-large",
2546
+ lg: "min-h-48 px-16 py-8 text-label-large"
2547
+ };
2506
2548
  var SegmentControl = forwardRef20(
2507
2549
  (_a, ref) => {
2508
- var _b = _a, { size = "md", items, selected, setSelected, className = "" } = _b, rest = __objRest(_b, ["size", "items", "selected", "setSelected", "className"]);
2550
+ var _b = _a, { size = "md", items, selected, setSelected, onChange, className = "" } = _b, rest = __objRest(_b, ["size", "items", "selected", "setSelected", "onChange", "className"]);
2509
2551
  return /* @__PURE__ */ jsx20(
2510
2552
  "div",
2511
2553
  __spreadProps(__spreadValues({
2512
2554
  ref,
2513
- className: `bg-background-tertiary rounded-full flex flex-row items-center justify-center p-4 gap-4 ${className}`
2555
+ className: `bg-background-tertiary rounded-full flex flex-row items-center p-4 gap-4 ${className}`
2514
2556
  }, rest), {
2515
- children: items.map((item) => /* @__PURE__ */ jsx20(
2516
- "div",
2517
- {
2518
- onClick: () => setSelected == null ? void 0 : setSelected(item.value),
2519
- className: `cursor-pointer rounded-full text-center grow
2520
- ${size === "sm" ? "px-8 py-6 text-label-medium" : size === "md" ? "px-12 py-10 text-label-large" : "px-16 py-14 text-label-large"} ${selected === item.value ? "bg-segmented-control-background-active shadow-base text-segmented-control-text-primary hover:bg-segmented-control-background-active-hover" : "bg-segmented-control-background-enabled text-segmented-control-text-primary hover:bg-segmented-control-background-hover"} `,
2521
- children: item.label
2522
- },
2523
- item.value
2524
- ))
2557
+ children: items.map((item) => {
2558
+ const isSelected = selected === item.value;
2559
+ return /* @__PURE__ */ jsx20(
2560
+ "button",
2561
+ {
2562
+ type: "button",
2563
+ "aria-pressed": isSelected,
2564
+ onClick: () => {
2565
+ setSelected == null ? void 0 : setSelected(item.value);
2566
+ onChange == null ? void 0 : onChange(item.value);
2567
+ },
2568
+ className: "group flex-1 min-w-0 rounded-full border-2 border-transparent p-2 outline-none cursor-pointer transition-colors focus-visible:border-segmented-control-border-focus",
2569
+ children: /* @__PURE__ */ jsx20(
2570
+ "span",
2571
+ {
2572
+ className: `flex w-full items-center justify-center rounded-full text-center transition-colors ${itemSizeClasses[size]} ${isSelected ? "bg-segmented-control-background-active text-segmented-control-text-inverse shadow-small group-focus-visible:bg-segmented-control-background-active-focus group-focus-visible:text-segmented-control-text-primary" : "text-segmented-control-text-primary hover:bg-segmented-control-background-hover"}`,
2573
+ children: item.label
2574
+ }
2575
+ )
2576
+ },
2577
+ item.value
2578
+ );
2579
+ })
2525
2580
  })
2526
2581
  );
2527
2582
  }
@@ -2533,7 +2588,7 @@ import {
2533
2588
  forwardRef as forwardRef21,
2534
2589
  useCallback as useCallback2,
2535
2590
  useId as useId5,
2536
- useState as useState10
2591
+ useState as useState9
2537
2592
  } from "react";
2538
2593
  import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
2539
2594
  var sizeConfig = {
@@ -2641,7 +2696,7 @@ var Slider = forwardRef21(
2641
2696
  const ariaLabel = ariaLabelProp != null ? ariaLabelProp : typeof label === "string" ? void 0 : "Slider";
2642
2697
  const ariaDescriptionId = description ? `${inputId}-description` : void 0;
2643
2698
  const isControlled = controlledValue !== void 0;
2644
- const [internalValue, setInternalValue] = useState10(defaultValue != null ? defaultValue : min);
2699
+ const [internalValue, setInternalValue] = useState9(defaultValue != null ? defaultValue : min);
2645
2700
  const currentValue = isControlled ? controlledValue : internalValue;
2646
2701
  const handleChange = useCallback2(
2647
2702
  (e) => {
@@ -2812,7 +2867,7 @@ Tab.displayName = "Tab";
2812
2867
 
2813
2868
  // src/components/TextArea/TextArea.tsx
2814
2869
  import {
2815
- useState as useState11,
2870
+ useState as useState10,
2816
2871
  forwardRef as forwardRef23
2817
2872
  } from "react";
2818
2873
  import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
@@ -2856,7 +2911,7 @@ var TextArea = forwardRef23(
2856
2911
  "className"
2857
2912
  ]);
2858
2913
  var _a2;
2859
- const [isFocused, setIsFocused] = useState11(false);
2914
+ const [isFocused, setIsFocused] = useState10(false);
2860
2915
  const isActive = isFocused && !!value;
2861
2916
  return /* @__PURE__ */ jsxs18("div", { className: "w-full flex flex-col gap-4 font-sans", children: [
2862
2917
  label || showCounter ? /* @__PURE__ */ jsxs18("div", { className: "w-full flex justify-between items-center gap-8", children: [
@@ -3134,7 +3189,7 @@ ToggleSwitch.displayName = "ToggleSwitch";
3134
3189
 
3135
3190
  // src/components/Tooltip/Tooltip.tsx
3136
3191
  import {
3137
- useState as useState12,
3192
+ useState as useState11,
3138
3193
  useEffect as useEffect5,
3139
3194
  useRef as useRef4,
3140
3195
  forwardRef as forwardRef26
@@ -3158,8 +3213,8 @@ var Tooltip = forwardRef26(
3158
3213
  "className"
3159
3214
  ]);
3160
3215
  const wrapperRef = useRef4(null);
3161
- const [isVisible, setIsVisible] = useState12(false);
3162
- const [isHovered, setIsHovered] = useState12(false);
3216
+ const [isVisible, setIsVisible] = useState11(false);
3217
+ const [isHovered, setIsHovered] = useState11(false);
3163
3218
  useEffect5(() => {
3164
3219
  const handleClickOutside = (event) => {
3165
3220
  if (wrapperRef.current && !wrapperRef.current.contains(event.target)) {
package/dist/theme.css CHANGED
@@ -401,8 +401,8 @@
401
401
  --color-button-background-primary-hover: var(--color-blue-700);
402
402
  --color-button-background-primary-active: var(--color-blue-800);
403
403
  --color-button-background-primary-focus: var(--color-blue-600);
404
- --color-button-background-primary-disabled: var(--color-blue-600 / 40%);
405
- --color-button-background-primary-pending: var(--color-blue-600 / 40%);
404
+ --color-button-background-primary-disabled: color-mix(in oklab, var(--color-blue-600) 40%, transparent);
405
+ --color-button-background-primary-pending: color-mix(in oklab, var(--color-blue-600) 40%, transparent);
406
406
  --color-button-background-secondary-enabled: var(--color-gray-100);
407
407
  --color-button-background-secondary-hover: var(--color-gray-200);
408
408
  --color-button-background-secondary-active: var(--color-gray-300);
@@ -433,7 +433,7 @@
433
433
  --color-button-text-brand: var(--color-blue-600);
434
434
  --color-button-text-inverse: var(--color-white-100);
435
435
  --color-button-text-inverse-disabled: var(--color-white-40);
436
- --color-button-text-brand-pending: var(--color-blue-600 / 40%);
436
+ --color-button-text-brand-pending: color-mix(in oklab, var(--color-blue-600) 40%, transparent);
437
437
  --color-button-border-focus: var(--color-blue-500);
438
438
  --color-button-border-inverse: var(--color-white-100);
439
439
  --color-accordion-background-enabled: var(--color-white-100);
@@ -472,7 +472,7 @@
472
472
  --color-icon-button-icon-disabled: var(--color-gray-400);
473
473
  --color-icon-button-icon-inverse-disabled: var(--color-white-40);
474
474
  --color-icon-button-icon-brand: var(--color-blue-600);
475
- --color-icon-button-icon-brand-disabled: var(--color-blue-600 / 40%);
475
+ --color-icon-button-icon-brand-disabled: color-mix(in oklab, var(--color-blue-600) 40%, transparent);
476
476
  --color-icon-button-icon-danger: var(--color-red-500);
477
477
  --color-icon-button-icon-inverse-danger: var(--color-red-400);
478
478
  --color-icon-button-border-focus: var(--color-blue-500);
@@ -482,7 +482,7 @@
482
482
  --color-toggle-switch-background-focus: var(--color-gray-200);
483
483
  --color-toggle-switch-background-disabled: var(--color-gray-100);
484
484
  --color-toggle-switch-background-active-hover: var(--color-green-700);
485
- --color-toggle-switch-background-active-disabled: var(--color-green-600 / 40%);
485
+ --color-toggle-switch-background-active-disabled: color-mix(in oklab, var(--color-green-600) 40%, transparent);
486
486
  --color-toggle-switch-background-toggle: var(--color-white-100);
487
487
  --color-toggle-switch-background-active-focus: var(--color-green-600);
488
488
  --color-toggle-switch-text-primary: var(--color-gray-900);
@@ -686,7 +686,7 @@
686
686
  --color-chip-background-inverse: var(--color-white-100);
687
687
  --color-chip-background-black-active: var(--color-blue-950);
688
688
  --color-chip-background-black-active-hover: var(--color-blue-900);
689
- --color-chip-background-active-disabled: var(--color-blue-600 / 40%);
689
+ --color-chip-background-active-disabled: color-mix(in oklab, var(--color-blue-600) 40%, transparent);
690
690
  --color-chip-text-disabled: var(--color-gray-400);
691
691
  --color-chip-text-inverse-disabled: var(--color-white-65);
692
692
  --color-chip-text-inverse: var(--color-white-100);
@@ -725,7 +725,7 @@
725
725
  * ======================================== */
726
726
  --color-background-primary: var(--color-white-100);
727
727
  --color-background-tertiary: var(--color-gray-100);
728
- --color-background-overlay: var(--color-gray-900 / 50%);
728
+ --color-background-overlay: color-mix(in oklab, var(--color-gray-900) 50%, transparent);
729
729
  --color-background-disabled: var(--color-gray-100);
730
730
  --color-background-secondary: var(--color-gray-50);
731
731
  --color-background-inverse: var(--color-gray-900);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@refinn/core-ui",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Refinn Design System — UI components + Tailwind v4 theme preset",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",