@keboola/design 5.1.0 → 6.1.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.
@@ -619,11 +619,12 @@ var init_styles = __esm({
619
619
  "tw-items-center",
620
620
  "tw-justify-center",
621
621
  "tw-gap-2",
622
- // text
622
+ // text — chrome weight/tracking are brand-overridable tokens
623
+ // (`--font-weight-medium` / `--letter-spacing-chrome`); casing stays `tw-uppercase`.
623
624
  "tw-text-xs",
624
625
  "tw-leading-5",
625
626
  "tw-font-medium",
626
- "tw-tracking-[1px]",
627
+ "tw-tracking-chrome",
627
628
  "tw-uppercase",
628
629
  // border — legacy (non-argo) chrome uses a fixed radius, not the brand token.
629
630
  "tw-rounded",
@@ -1071,13 +1072,14 @@ var init_Clipboard2 = __esm({
1071
1072
  init_Clipboard();
1072
1073
  }
1073
1074
  });
1074
- var DEFAULT_ICON, ClipboardButton;
1075
+ var DEFAULT_ICON, DEFAULT_ARIA_LABEL, ClipboardButton;
1075
1076
  var init_ClipboardButton = __esm({
1076
1077
  "src/blocks/ClipboardButton/ClipboardButton.tsx"() {
1077
1078
  init_Button2();
1078
1079
  init_Clipboard2();
1079
1080
  init_icons();
1080
1081
  DEFAULT_ICON = /* @__PURE__ */ jsxRuntime.jsx(icons_exports.Copy, {});
1082
+ DEFAULT_ARIA_LABEL = "Copy";
1081
1083
  ClipboardButton = ({
1082
1084
  // clipboard props
1083
1085
  text,
@@ -1089,20 +1091,24 @@ var init_ClipboardButton = __esm({
1089
1091
  variant = "outline",
1090
1092
  children,
1091
1093
  ...rest
1092
- }) => /* @__PURE__ */ jsxRuntime.jsx(
1093
- Clipboard,
1094
- {
1095
- asChild: true,
1096
- tooltip,
1097
- tooltipPlacement,
1098
- tooltipVariant,
1099
- text,
1100
- children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { ...rest, variant, disabled: !text, children: [
1101
- icon,
1102
- children
1103
- ] })
1104
- }
1105
- );
1094
+ }) => {
1095
+ const defaultAriaLabel = typeof tooltip === "string" && tooltip.trim() ? tooltip : DEFAULT_ARIA_LABEL;
1096
+ const ariaLabel = rest["aria-label"] ?? (children == null ? defaultAriaLabel : void 0);
1097
+ return /* @__PURE__ */ jsxRuntime.jsx(
1098
+ Clipboard,
1099
+ {
1100
+ asChild: true,
1101
+ tooltip,
1102
+ tooltipPlacement,
1103
+ tooltipVariant,
1104
+ text,
1105
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { ...rest, "aria-label": ariaLabel, variant, disabled: !text, children: [
1106
+ icon,
1107
+ children
1108
+ ] })
1109
+ }
1110
+ );
1111
+ };
1106
1112
  }
1107
1113
  });
1108
1114
 
@@ -3455,11 +3461,23 @@ var inputGroupVariants = classVarianceAuthority.cva(
3455
3461
  off: ["has-[:is(input,textarea):focus]:!tw-ring-0"]
3456
3462
  },
3457
3463
  variant: {
3458
- primary: ["tw-bg-white", "has-[:is(input,textarea):disabled]:tw-opacity-40"],
3464
+ primary: [
3465
+ "tw-bg-white",
3466
+ "has-[:is(input,textarea):disabled]:tw-opacity-40",
3467
+ // aria-invalid on the control surfaces the error chrome without a `state` prop — the
3468
+ // accessible path (mirrors the `state="error"` legacy tokens). Higher specificity than
3469
+ // the default focus selector, so it wins without `!important`.
3470
+ "has-[:is(input,textarea)[aria-invalid=true]]:tw-border-error-500",
3471
+ "has-[:is(input,textarea)[aria-invalid=true]:focus]:tw-border-error-500",
3472
+ "has-[:is(input,textarea)[aria-invalid=true]:focus]:tw-ring-error-200"
3473
+ ],
3459
3474
  secondary: [
3460
3475
  "tw-bg-neutral-100",
3461
3476
  "tw-border-neutral-100",
3462
- "has-[:is(input,textarea):disabled]:tw-opacity-40"
3477
+ "has-[:is(input,textarea):disabled]:tw-opacity-40",
3478
+ "has-[:is(input,textarea)[aria-invalid=true]]:tw-border-error-500",
3479
+ "has-[:is(input,textarea)[aria-invalid=true]:focus]:tw-border-error-500",
3480
+ "has-[:is(input,textarea)[aria-invalid=true]:focus]:tw-ring-error-200"
3463
3481
  ],
3464
3482
  argo: [
3465
3483
  // argo follows the brand radius token (overrides the static base)
@@ -3470,7 +3488,12 @@ var inputGroupVariants = classVarianceAuthority.cva(
3470
3488
  "tw-text-foreground",
3471
3489
  "has-[:is(input,textarea):disabled]:tw-opacity-50",
3472
3490
  // higher specificity than has-[:is(input,textarea):focus] — prevents focus border on readonly
3473
- "has-[:is(input,textarea)[readonly]:focus]:tw-border-neutral-150"
3491
+ "has-[:is(input,textarea)[readonly]:focus]:tw-border-neutral-150",
3492
+ // aria-invalid on the control surfaces the error chrome without a `state` prop — the
3493
+ // accessible path (uses the themeable `destructive` status token).
3494
+ "has-[:is(input,textarea)[aria-invalid=true]]:tw-border-destructive",
3495
+ "has-[:is(input,textarea)[aria-invalid=true]:focus]:tw-border-destructive",
3496
+ "has-[:is(input,textarea)[aria-invalid=true]:focus]:tw-ring-destructive/20"
3474
3497
  ]
3475
3498
  },
3476
3499
  sizing: {
@@ -3758,6 +3781,21 @@ var FormGroupColorInput = ({
3758
3781
  const { state } = useFormGroupContext();
3759
3782
  return /* @__PURE__ */ jsxRuntime.jsx(ColorInput, { state, ...props, ref });
3760
3783
  };
3784
+
3785
+ // src/components/FormGroup/FormGroupError.tsx
3786
+ init_utils2();
3787
+ var toMessage = (entry) => typeof entry === "string" ? entry : entry?.message;
3788
+ var FormGroupError = ({ children, className, errors, ...rest }) => {
3789
+ const content = react.useMemo(() => {
3790
+ if (children) return children;
3791
+ const messages = (errors ?? []).map(toMessage).filter((message) => !!message);
3792
+ if (messages.length === 0) return null;
3793
+ if (messages.length === 1) return messages[0];
3794
+ return /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "tw-m-0 tw-flex tw-list-disc tw-flex-col tw-gap-0 tw-pl-4", children: messages.map((message, index) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: message }, index)) });
3795
+ }, [children, errors]);
3796
+ if (!content) return null;
3797
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ...rest, role: "alert", className: cn("tw-m-0 tw-text-xs tw-text-destructive", className), children: content });
3798
+ };
3761
3799
  var helpVariants = classVarianceAuthority.cva(["tw-m-0", "tw-text-xs"], {
3762
3800
  defaultVariants: {
3763
3801
  state: "default"
@@ -3765,18 +3803,17 @@ var helpVariants = classVarianceAuthority.cva(["tw-m-0", "tw-text-xs"], {
3765
3803
  variants: {
3766
3804
  state: {
3767
3805
  default: ["tw-text-muted-foreground"],
3768
- error: ["tw-text-destructive"],
3769
3806
  warning: ["tw-text-warning"]
3770
3807
  }
3771
3808
  }
3772
3809
  });
3773
- var HelpBlock = ({ children, className, state = "default", testId }) => {
3810
+ var HelpBlock = ({ children, className, state = "default", ...rest }) => {
3774
3811
  if (!children) return null;
3775
- return /* @__PURE__ */ jsxRuntime.jsx("p", { "data-testid": testId, className: helpVariants({ state, className }), children });
3812
+ return /* @__PURE__ */ jsxRuntime.jsx("p", { ...rest, className: helpVariants({ state, className }), children });
3776
3813
  };
3777
3814
  var FormGroupHelp = ({ children, ...rest }) => {
3778
3815
  const formGroupContext = useFormGroupContext();
3779
- return /* @__PURE__ */ jsxRuntime.jsx(HelpBlock, { state: formGroupContext.state, ...rest, children });
3816
+ return /* @__PURE__ */ jsxRuntime.jsx(HelpBlock, { state: formGroupContext.state === "warning" ? "warning" : "default", ...rest, children });
3780
3817
  };
3781
3818
  var toNumberOrNull = (event) => Number.isNaN(event.target.valueAsNumber) ? null : event.target.valueAsNumber;
3782
3819
  var NumberInput = ({
@@ -4031,10 +4068,11 @@ var FormGroupTextInput = ({
4031
4068
  const { state } = useFormGroupContext();
4032
4069
  return /* @__PURE__ */ jsxRuntime.jsx(TextInput, { state, ...props, ref });
4033
4070
  };
4034
- var FormGroup = ({ className, children, state, testId }) => {
4035
- return /* @__PURE__ */ jsxRuntime.jsx(FormGroupProvider, { value: { state }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { "data-testid": testId, className: cn("tw-flex tw-flex-col tw-gap-1", className), children }) });
4071
+ var FormGroup = ({ className, children, state, ...rest }) => {
4072
+ return /* @__PURE__ */ jsxRuntime.jsx(FormGroupProvider, { value: { state }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { ...rest, className: cn("tw-flex tw-flex-col tw-gap-1", className), children }) });
4036
4073
  };
4037
4074
  FormGroup.Help = FormGroupHelp;
4075
+ FormGroup.Error = FormGroupError;
4038
4076
  FormGroup.TextInput = FormGroupTextInput;
4039
4077
  FormGroup.NumberInput = FormGroupNumberInput;
4040
4078
  FormGroup.ColorInput = FormGroupColorInput;
@@ -4042,23 +4080,23 @@ FormGroup.Textarea = FormGroupTextarea;
4042
4080
 
4043
4081
  // src/components/Label/Label.tsx
4044
4082
  init_utils2();
4045
- var Optional = ({ className }) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("tw-text-muted-foreground", className), children: "(optional)" });
4046
- var Label2 = ({ className, children, id, htmlFor, ...rest }) => {
4047
- return /* @__PURE__ */ jsxRuntime.jsx(
4048
- RLabel__namespace.Root,
4049
- {
4050
- ...rest,
4051
- id: id?.toString(),
4052
- htmlFor: htmlFor?.toString(),
4053
- className: cn(
4054
- "tw-m-0 tw-text-foreground tw-font-normal peer-disabled:tw-opacity-50",
4055
- className
4056
- ),
4057
- children
4058
- }
4059
- );
4060
- };
4083
+ var Optional = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("span", { ...props, "aria-hidden": true, className: cn("tw-ml-0.5", "tw-text-muted-foreground", className), children: "(optional)" });
4084
+ var Required = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("span", { ...props, "aria-hidden": true, className: cn("tw-ml-0.5", "tw-text-primary", className), children: "*" });
4085
+ var Label2 = ({ className, children, id, htmlFor, ...rest }) => /* @__PURE__ */ jsxRuntime.jsx(
4086
+ RLabel__namespace.Root,
4087
+ {
4088
+ ...rest,
4089
+ id: id?.toString(),
4090
+ htmlFor: htmlFor?.toString(),
4091
+ className: cn(
4092
+ "tw-m-0 tw-text-foreground tw-font-normal peer-disabled:tw-opacity-50",
4093
+ className
4094
+ ),
4095
+ children
4096
+ }
4097
+ );
4061
4098
  Label2.Optional = Optional;
4099
+ Label2.Required = Required;
4062
4100
 
4063
4101
  // src/components/MarkdownEditor/plugins/toolbar/ToolbarButton.tsx
4064
4102
  init_utils2();