@keboola/design 6.0.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.
package/dist/index.cjs CHANGED
@@ -13,6 +13,7 @@ var DropdownMenuPrimitive3 = require('@radix-ui/react-dropdown-menu');
13
13
  var ScrollAreaPrimitive2 = require('@radix-ui/react-scroll-area');
14
14
  var reactToggle = require('@radix-ui/react-toggle');
15
15
  var ToggleGroupPrimitive = require('@radix-ui/react-toggle-group');
16
+ var RLabel = require('@radix-ui/react-label');
16
17
  var AlertDialogPrimitive = require('@radix-ui/react-alert-dialog');
17
18
  var DialogPrimitive = require('@radix-ui/react-dialog');
18
19
  var RSeparator = require('@radix-ui/react-separator');
@@ -21,7 +22,6 @@ var reactPopover = require('@radix-ui/react-popover');
21
22
  var reactHoverCard = require('@radix-ui/react-hover-card');
22
23
  var cmdk = require('cmdk');
23
24
  var TextareaAutosize = require('react-textarea-autosize');
24
- var RLabel = require('@radix-ui/react-label');
25
25
  var reactSwitch = require('@radix-ui/react-switch');
26
26
  var RRadioGroup = require('@radix-ui/react-radio-group');
27
27
  var reactSlider = require('@radix-ui/react-slider');
@@ -70,11 +70,11 @@ var React26__default = /*#__PURE__*/_interopDefault(React26);
70
70
  var DropdownMenuPrimitive3__namespace = /*#__PURE__*/_interopNamespace(DropdownMenuPrimitive3);
71
71
  var ScrollAreaPrimitive2__namespace = /*#__PURE__*/_interopNamespace(ScrollAreaPrimitive2);
72
72
  var ToggleGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(ToggleGroupPrimitive);
73
+ var RLabel__namespace = /*#__PURE__*/_interopNamespace(RLabel);
73
74
  var AlertDialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(AlertDialogPrimitive);
74
75
  var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
75
76
  var RSeparator__namespace = /*#__PURE__*/_interopNamespace(RSeparator);
76
77
  var TextareaAutosize__default = /*#__PURE__*/_interopDefault(TextareaAutosize);
77
- var RLabel__namespace = /*#__PURE__*/_interopNamespace(RLabel);
78
78
  var RRadioGroup__namespace = /*#__PURE__*/_interopNamespace(RRadioGroup);
79
79
  var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
80
80
  var ReactMarkdown__default = /*#__PURE__*/_interopDefault(ReactMarkdown);
@@ -2800,6 +2800,7 @@ var Clipboard = ({
2800
2800
  ] });
2801
2801
  };
2802
2802
  var DEFAULT_ICON = /* @__PURE__ */ jsxRuntime.jsx(icons_exports.Copy, {});
2803
+ var DEFAULT_ARIA_LABEL = "Copy";
2803
2804
  var ClipboardButton = ({
2804
2805
  // clipboard props
2805
2806
  text,
@@ -2811,20 +2812,24 @@ var ClipboardButton = ({
2811
2812
  variant = "outline",
2812
2813
  children,
2813
2814
  ...rest
2814
- }) => /* @__PURE__ */ jsxRuntime.jsx(
2815
- Clipboard,
2816
- {
2817
- asChild: true,
2818
- tooltip,
2819
- tooltipPlacement,
2820
- tooltipVariant,
2821
- text,
2822
- children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { ...rest, variant, disabled: !text, children: [
2823
- icon,
2824
- children
2825
- ] })
2826
- }
2827
- );
2815
+ }) => {
2816
+ const defaultAriaLabel = typeof tooltip === "string" && tooltip.trim() ? tooltip : DEFAULT_ARIA_LABEL;
2817
+ const ariaLabel = rest["aria-label"] ?? (children == null ? defaultAriaLabel : void 0);
2818
+ return /* @__PURE__ */ jsxRuntime.jsx(
2819
+ Clipboard,
2820
+ {
2821
+ asChild: true,
2822
+ tooltip,
2823
+ tooltipPlacement,
2824
+ tooltipVariant,
2825
+ text,
2826
+ children: /* @__PURE__ */ jsxRuntime.jsxs(Button, { ...rest, "aria-label": ariaLabel, variant, disabled: !text, children: [
2827
+ icon,
2828
+ children
2829
+ ] })
2830
+ }
2831
+ );
2832
+ };
2828
2833
  var ClipboardInline = ({
2829
2834
  // clipboard props
2830
2835
  text,
@@ -2849,6 +2854,264 @@ var ClipboardInline = ({
2849
2854
  ] })
2850
2855
  }
2851
2856
  );
2857
+ var CopyContext = React26.createContext(null);
2858
+ var useCopyContext = () => {
2859
+ const ctx = React26.use(CopyContext);
2860
+ if (!ctx) throw new Error("CopyField.* components must be used within a CopyField.Root");
2861
+ return ctx;
2862
+ };
2863
+ var LINE_HEIGHT_REM = 1.25;
2864
+ var VERTICAL_PADDING_REM = 1.25;
2865
+ var CopyBox = ({ className, children }) => {
2866
+ const { copied, handleCopy, mono, minLines, maxLines, boxId, labelId, hasLabel } = useCopyContext();
2867
+ const multiline = maxLines > 1;
2868
+ const multilineStyle = multiline ? {
2869
+ minHeight: `${minLines * LINE_HEIGHT_REM + VERTICAL_PADDING_REM}rem`,
2870
+ maxHeight: `${maxLines * LINE_HEIGHT_REM + VERTICAL_PADDING_REM}rem`
2871
+ } : void 0;
2872
+ const handleKeyDown2 = (event) => {
2873
+ if (event.target !== event.currentTarget) return;
2874
+ if (event.key !== "Enter" && event.key !== " ") return;
2875
+ event.preventDefault();
2876
+ handleCopy();
2877
+ };
2878
+ return /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { triggerAsChild: true, placement: "top", tooltip: copied ? "Copied" : "Copy", forceShow: copied, children: /* @__PURE__ */ jsxRuntime.jsx(
2879
+ "div",
2880
+ {
2881
+ role: "button",
2882
+ tabIndex: 0,
2883
+ id: boxId,
2884
+ "aria-labelledby": hasLabel ? labelId : void 0,
2885
+ onClick: handleCopy,
2886
+ onKeyDown: handleKeyDown2,
2887
+ style: multilineStyle,
2888
+ className: cn(
2889
+ "tw-group tw-relative tw-flex tw-w-fit tw-max-w-full tw-cursor-pointer tw-gap-2 tw-rounded-2xl [corner-shape:superellipse(2)] tw-border tw-border-[#e4e4e4] tw-bg-[#fafafa] tw-px-3 tw-py-2.5 tw-text-left tw-shadow-sm tw-transition-colors hover:tw-bg-[#f2f2f2]",
2890
+ multiline ? "tw-items-start tw-overflow-auto" : "tw-items-center tw-overflow-hidden",
2891
+ mono && "tw-font-mono tw-text-[13px]",
2892
+ className
2893
+ ),
2894
+ children
2895
+ }
2896
+ ) });
2897
+ };
2898
+ var CopyButton = ({ className }) => {
2899
+ const { copied, maxLines } = useCopyContext();
2900
+ return /* @__PURE__ */ jsxRuntime.jsx(
2901
+ "span",
2902
+ {
2903
+ "aria-hidden": true,
2904
+ className: cn(
2905
+ "tw-pointer-events-none tw-flex tw-shrink-0 tw-items-center tw-text-[#8b8b8b] group-hover:tw-text-[#5c5c5c]",
2906
+ maxLines > 1 && "tw-self-start tw-pt-0.5",
2907
+ className
2908
+ ),
2909
+ children: copied ? /* @__PURE__ */ jsxRuntime.jsx(icons_exports.Check, { className: "tw-size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(icons_exports.Copy, { className: "tw-size-4" })
2910
+ }
2911
+ );
2912
+ };
2913
+ var CopyChildren = ({ children, className }) => {
2914
+ const { maxLines } = useCopyContext();
2915
+ const multiline = maxLines > 1;
2916
+ return /* @__PURE__ */ jsxRuntime.jsx(
2917
+ "span",
2918
+ {
2919
+ className: cn(
2920
+ "tw-min-w-0 tw-flex-1 tw-select-text tw-text-[#3f3f3f]",
2921
+ multiline ? "tw-whitespace-pre-wrap tw-break-words" : "tw-truncate",
2922
+ className
2923
+ ),
2924
+ children
2925
+ }
2926
+ );
2927
+ };
2928
+ var CopyFooter = ({ children, className }) => {
2929
+ if (!children) return null;
2930
+ return /* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("tw-m-0 tw-text-xs tw-text-muted-foreground", className), children });
2931
+ };
2932
+ var MASK = "*".repeat(12);
2933
+ var CopyHidden = ({ children, revealable = true, className }) => {
2934
+ const { hidden, registerRevealable } = useCopyContext();
2935
+ React26.useEffect(() => {
2936
+ if (!revealable) return void 0;
2937
+ return registerRevealable();
2938
+ }, [revealable, registerRevealable]);
2939
+ const masked = revealable ? hidden : true;
2940
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("tw-select-none", className), children: masked ? MASK : children });
2941
+ };
2942
+ 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)" });
2943
+ var Required = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("span", { ...props, "aria-hidden": true, className: cn("tw-ml-0.5", "tw-text-primary", className), children: "*" });
2944
+ var Label2 = ({ className, children, id, htmlFor, ...rest }) => /* @__PURE__ */ jsxRuntime.jsx(
2945
+ RLabel__namespace.Root,
2946
+ {
2947
+ ...rest,
2948
+ id: id?.toString(),
2949
+ htmlFor: htmlFor?.toString(),
2950
+ className: cn(
2951
+ "tw-m-0 tw-text-foreground tw-font-normal peer-disabled:tw-opacity-50",
2952
+ className
2953
+ ),
2954
+ children
2955
+ }
2956
+ );
2957
+ Label2.Optional = Optional;
2958
+ Label2.Required = Required;
2959
+ var CopyLabel = ({ children, leading, trailing, className }) => {
2960
+ const { labelId, registerLabel } = useCopyContext();
2961
+ React26.useEffect(() => registerLabel(), [registerLabel]);
2962
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("tw-flex tw-items-center tw-gap-1", className), children: [
2963
+ /* @__PURE__ */ jsxRuntime.jsx(Label2, { id: labelId, children }),
2964
+ leading,
2965
+ trailing != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tw-ml-auto tw-flex tw-items-center", children: trailing })
2966
+ ] });
2967
+ };
2968
+ var CopyPrefix = ({ children, className }) => /* @__PURE__ */ jsxRuntime.jsx(
2969
+ "span",
2970
+ {
2971
+ "aria-hidden": true,
2972
+ className: cn(
2973
+ "tw-shrink-0 tw-select-none tw-self-stretch tw-border-r tw-border-[#e4e4e4] tw-pr-2 tw-text-[#6b6b6b]",
2974
+ className
2975
+ ),
2976
+ children
2977
+ }
2978
+ );
2979
+ var CopyReveal = ({ className }) => {
2980
+ const { hidden, toggleHidden, hasRevealable, maxLines } = useCopyContext();
2981
+ if (!hasRevealable) return null;
2982
+ const handleClick = (event) => {
2983
+ event.stopPropagation();
2984
+ toggleHidden();
2985
+ };
2986
+ return /* @__PURE__ */ jsxRuntime.jsx(
2987
+ "button",
2988
+ {
2989
+ type: "button",
2990
+ onClick: handleClick,
2991
+ "aria-label": hidden ? "Show value" : "Hide value",
2992
+ className: cn(
2993
+ "tw-flex tw-shrink-0 tw-items-center tw-text-[#8b8b8b] hover:tw-text-[#5c5c5c]",
2994
+ maxLines > 1 && "tw-self-start tw-pt-0.5",
2995
+ className
2996
+ ),
2997
+ children: hidden ? /* @__PURE__ */ jsxRuntime.jsx(icons_exports.Eye, { className: "tw-size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(icons_exports.EyeOff, { className: "tw-size-4" })
2998
+ }
2999
+ );
3000
+ };
3001
+ var CopyRoot = ({
3002
+ value,
3003
+ mono = false,
3004
+ onCopy,
3005
+ hiddenByDefault = false,
3006
+ minLines = 1,
3007
+ maxLines,
3008
+ className,
3009
+ children
3010
+ }) => {
3011
+ const [copied, setCopied] = React26.useState(false);
3012
+ const [hidden, setHidden] = React26.useState(hiddenByDefault);
3013
+ const [revealableCount, setRevealableCount] = React26.useState(0);
3014
+ const [labelCount, setLabelCount] = React26.useState(0);
3015
+ const resetTimerRef = React26.useRef(void 0);
3016
+ const generatedId = React26.useId();
3017
+ const labelId = `${generatedId}-label`;
3018
+ const boxId = `${generatedId}-box`;
3019
+ React26.useEffect(() => () => clearTimeout(resetTimerRef.current), []);
3020
+ const handleCopy = React26.useCallback(() => {
3021
+ const selection = window.getSelection();
3022
+ const boxEl = document.getElementById(boxId);
3023
+ if (selection && !selection.isCollapsed && selection.anchorNode && boxEl?.contains(selection.anchorNode)) {
3024
+ return;
3025
+ }
3026
+ copyToClipboard(value).then(() => {
3027
+ onCopy?.();
3028
+ setCopied(true);
3029
+ clearTimeout(resetTimerRef.current);
3030
+ resetTimerRef.current = setTimeout(() => setCopied(false), 1500);
3031
+ }).catch((error) => {
3032
+ console.error("Copy to clipboard failed", error);
3033
+ });
3034
+ }, [value, onCopy, boxId]);
3035
+ const toggleHidden = React26.useCallback(() => setHidden((prev) => !prev), []);
3036
+ const registerRevealable = React26.useCallback(() => {
3037
+ setRevealableCount((count) => count + 1);
3038
+ return () => setRevealableCount((count) => count - 1);
3039
+ }, []);
3040
+ const registerLabel = React26.useCallback(() => {
3041
+ setLabelCount((count) => count + 1);
3042
+ return () => setLabelCount((count) => count - 1);
3043
+ }, []);
3044
+ const contextValue = React26.useMemo(
3045
+ () => ({
3046
+ copied,
3047
+ handleCopy,
3048
+ value,
3049
+ mono,
3050
+ hidden,
3051
+ toggleHidden,
3052
+ registerRevealable,
3053
+ hasRevealable: revealableCount > 0,
3054
+ registerLabel,
3055
+ hasLabel: labelCount > 0,
3056
+ minLines,
3057
+ maxLines: maxLines ?? minLines,
3058
+ labelId,
3059
+ boxId
3060
+ }),
3061
+ [
3062
+ copied,
3063
+ handleCopy,
3064
+ value,
3065
+ mono,
3066
+ hidden,
3067
+ toggleHidden,
3068
+ registerRevealable,
3069
+ revealableCount,
3070
+ registerLabel,
3071
+ labelCount,
3072
+ minLines,
3073
+ maxLines,
3074
+ labelId,
3075
+ boxId
3076
+ ]
3077
+ );
3078
+ return /* @__PURE__ */ jsxRuntime.jsx(CopyContext, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("tw-flex tw-w-fit tw-max-w-full tw-flex-col tw-gap-1", className), children }) });
3079
+ };
3080
+ var CopySuffix = ({ children, className }) => /* @__PURE__ */ jsxRuntime.jsx(
3081
+ "span",
3082
+ {
3083
+ "aria-hidden": true,
3084
+ className: cn(
3085
+ "tw-shrink-0 tw-select-none tw-self-stretch tw-border-l tw-border-[#e4e4e4] tw-pl-2 tw-text-[#6b6b6b]",
3086
+ className
3087
+ ),
3088
+ children
3089
+ }
3090
+ );
3091
+
3092
+ // src/blocks/CopyField/CopyField.tsx
3093
+ var CopyField = {
3094
+ /** Container. Owns the copied `value`, mask state, and copy context. */
3095
+ Root: CopyRoot,
3096
+ /** Visible label above the box, with optional `leading`/`trailing` slots. */
3097
+ Label: CopyLabel,
3098
+ /** The clickable copy target row. */
3099
+ Box: CopyBox,
3100
+ /** Muted, non-selectable prefix addon (not copied). */
3101
+ Prefix: CopyPrefix,
3102
+ /** Displayed value (truncates single-line, wraps multi-line). */
3103
+ Children: CopyChildren,
3104
+ /** Muted, non-selectable suffix addon (not copied). */
3105
+ Suffix: CopySuffix,
3106
+ /** Masks its children with dots; copy still copies the real value. */
3107
+ Hidden: CopyHidden,
3108
+ /** Eye toggle that reveals/masks revealable `CopyField.Hidden` content. */
3109
+ Reveal: CopyReveal,
3110
+ /** Copy affordance icon — shows Copy/Check with feedback. */
3111
+ Button: CopyButton,
3112
+ /** Small helper text below the box. */
3113
+ Footer: CopyFooter
3114
+ };
2852
3115
  var Link = ({
2853
3116
  ref,
2854
3117
  children,
@@ -6783,7 +7046,7 @@ __export(custom_components_exports, {
6783
7046
  NextMonthButton: () => NextMonthButton,
6784
7047
  Option: () => Option,
6785
7048
  PreviousMonthButton: () => PreviousMonthButton,
6786
- Root: () => Root16,
7049
+ Root: () => Root17,
6787
7050
  Select: () => Select,
6788
7051
  Week: () => Week,
6789
7052
  WeekNumber: () => WeekNumber,
@@ -6963,7 +7226,7 @@ function Option(props) {
6963
7226
  function PreviousMonthButton(props) {
6964
7227
  return React26__default.default.createElement("button", { ...props });
6965
7228
  }
6966
- function Root16(props) {
7229
+ function Root17(props) {
6967
7230
  const { rootRef, ...rest } = props;
6968
7231
  return React26__default.default.createElement("div", { ...rest, ref: rootRef });
6969
7232
  }
@@ -10031,23 +10294,6 @@ var TimePicker = ({
10031
10294
  )
10032
10295
  ] });
10033
10296
  };
10034
- 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)" });
10035
- var Required = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("span", { ...props, "aria-hidden": true, className: cn("tw-ml-0.5", "tw-text-primary", className), children: "*" });
10036
- var Label2 = ({ className, children, id, htmlFor, ...rest }) => /* @__PURE__ */ jsxRuntime.jsx(
10037
- RLabel__namespace.Root,
10038
- {
10039
- ...rest,
10040
- id: id?.toString(),
10041
- htmlFor: htmlFor?.toString(),
10042
- className: cn(
10043
- "tw-m-0 tw-text-foreground tw-font-normal peer-disabled:tw-opacity-50",
10044
- className
10045
- ),
10046
- children
10047
- }
10048
- );
10049
- Label2.Optional = Optional;
10050
- Label2.Required = Required;
10051
10297
  var FieldBoxDescription = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(
10052
10298
  "span",
10053
10299
  {
@@ -16400,6 +16646,12 @@ var PromptInputCommands = ({ items, open, onSelect, filterValue, children }) =>
16400
16646
  children
16401
16647
  ] });
16402
16648
  };
16649
+ var ARIA_LABEL_BY_STATUS = {
16650
+ ready: "Send message",
16651
+ streaming: "Stop",
16652
+ interrupted: "Continue",
16653
+ submitted: "Sending\u2026"
16654
+ };
16403
16655
  var PromptInputSubmit = ({
16404
16656
  ref,
16405
16657
  disabled,
@@ -16422,6 +16674,7 @@ var PromptInputSubmit = ({
16422
16674
  ref,
16423
16675
  type: "submit",
16424
16676
  disabled,
16677
+ "aria-label": ARIA_LABEL_BY_STATUS[status],
16425
16678
  size: "icon-sm",
16426
16679
  variant: "invisible",
16427
16680
  isLoading: status === "submitted",
@@ -17868,7 +18121,7 @@ var cardTitleClassnames = cn(
17868
18121
  "tw-text-base",
17869
18122
  "tw-text-card-foreground"
17870
18123
  );
17871
- var CardTitle = ({ children, className, ...rest }) => /* @__PURE__ */ jsxRuntime.jsx("h3", { className: cn(cardTitleClassnames, className), ...rest, children });
18124
+ var CardTitle = ({ children, className, as: Tag = "h3", ...rest }) => /* @__PURE__ */ jsxRuntime.jsx(Tag, { className: cn(cardTitleClassnames, className), ...rest, children });
17872
18125
  var Card = ({
17873
18126
  children,
17874
18127
  className,
@@ -23533,6 +23786,7 @@ exports.CommandInput = CommandInput;
23533
23786
  exports.CommandItem = CommandItem;
23534
23787
  exports.CommandList = CommandList;
23535
23788
  exports.ConflictStatusIndicator = ConflictStatusIndicator;
23789
+ exports.CopyField = CopyField;
23536
23790
  exports.DEFAULT_COLOR_SCHEME = DEFAULT_COLOR_SCHEME;
23537
23791
  exports.DEFAULT_KEBOOLA_BRAND_ID = DEFAULT_BRAND_ID;
23538
23792
  exports.DateInput = DateInput;