From 6758633c2b59960308349bdc1147362f3c74225e Mon Sep 17 00:00:00 2001 From: Kirill Chernakov Date: Mon, 14 Oct 2024 18:18:18 +0400 Subject: [PATCH] fix: tooltips --- keep-ui/app/rules/AIGenRules.tsx | 74 +++++++---- keep-ui/components/ui/Tooltip.tsx | 95 ++++++++++++++ keep-ui/components/ui/index.ts | 1 + keep-ui/package-lock.json | 200 ++++++++++++++++++++++++------ keep-ui/package.json | 1 + keep-ui/tailwind.config.js | 32 +++++ 6 files changed, 340 insertions(+), 63 deletions(-) create mode 100644 keep-ui/components/ui/Tooltip.tsx diff --git a/keep-ui/app/rules/AIGenRules.tsx b/keep-ui/app/rules/AIGenRules.tsx index 46e840601..084ec65d3 100644 --- a/keep-ui/app/rules/AIGenRules.tsx +++ b/keep-ui/app/rules/AIGenRules.tsx @@ -40,7 +40,7 @@ import { useSession } from "next-auth/react"; import { getApiURL } from "utils/apiUrl"; import useSWR, { mutate } from "swr"; import Loading from "app/loading"; -import { Button } from "@/components/ui"; +import { Button, Tooltip } from "@/components/ui"; const columnHelper = createColumnHelper(); @@ -203,30 +203,54 @@ export const AIGenRules: React.FC = () => { const rule = info.row.original; return (
- - - + +

Thinking behind the rule

+ {rule.ChainOfThought} + + } + > + +
+ +

Why rule may be too general

+ {rule.WhyTooGeneral} + + } + > + +
+ +

Why rule may be too specific

+ {rule.WhyTooSpecific} + + } + > + +
); }, diff --git a/keep-ui/components/ui/Tooltip.tsx b/keep-ui/components/ui/Tooltip.tsx new file mode 100644 index 000000000..049ccf098 --- /dev/null +++ b/keep-ui/components/ui/Tooltip.tsx @@ -0,0 +1,95 @@ +// Tremor Tooltip [v0.0.2] + +"use client"; + +import React from "react"; +import * as TooltipPrimitives from "@radix-ui/react-tooltip"; +import cx from "clsx"; + +interface TooltipProps + extends Omit, + Pick< + TooltipPrimitives.TooltipProps, + "open" | "defaultOpen" | "onOpenChange" | "delayDuration" + > { + content: React.ReactNode; + onClick?: React.MouseEventHandler; + side?: "bottom" | "left" | "top" | "right"; + showArrow?: boolean; + triggerAsChild?: boolean; +} + +const Tooltip = React.forwardRef< + React.ElementRef, + TooltipProps +>( + ( + { + children, + className, + content, + delayDuration, + defaultOpen, + open, + onClick, + onOpenChange, + showArrow = true, + side, + sideOffset = 10, + triggerAsChild = false, + ...props + }: TooltipProps, + forwardedRef + ) => { + return ( + + + + {children} + + + + {content} + {showArrow ? ( + + + + + ); + } +); + +Tooltip.displayName = "Tooltip"; + +export { Tooltip, type TooltipProps }; diff --git a/keep-ui/components/ui/index.ts b/keep-ui/components/ui/index.ts index ef21724bf..70ed1d8d5 100644 --- a/keep-ui/components/ui/index.ts +++ b/keep-ui/components/ui/index.ts @@ -4,3 +4,4 @@ export { Textarea } from "./Textarea"; export { Button } from "./Button"; export { Link } from "./Link"; export { EmptyStateCard } from "./EmptyStateCard"; +export { Tooltip } from "./Tooltip"; diff --git a/keep-ui/package-lock.json b/keep-ui/package-lock.json index ed04f115f..086ca2fbe 100644 --- a/keep-ui/package-lock.json +++ b/keep-ui/package-lock.json @@ -28,6 +28,7 @@ "@heroicons/react": "^2.0.18", "@mui/material": "^5.15.18", "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-tooltip": "^1.1.3", "@svgr/webpack": "^8.0.1", "@tanstack/react-table": "^8.11.0", "@tremor/react": "^3.18.3", @@ -5395,6 +5396,28 @@ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", + "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", @@ -5569,6 +5592,51 @@ } } }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", + "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-portal": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.2.tgz", @@ -5676,6 +5744,39 @@ } } }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.3.tgz", + "integrity": "sha512-Z4w1FIS0BqVFI2c1jZvb/uDVJijJjJ2ZMuPV81oVgTZ7g3BZxobplnMVvXtFWgtozdvYJ+MFWtwkM5S2HnAong==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.2", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", @@ -5738,6 +5839,67 @@ } } }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "dependencies": { + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", + "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" + }, "node_modules/@react-aria/focus": { "version": "3.18.2", "resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.18.2.tgz", @@ -11890,29 +12052,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast-util-to-html": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.3.tgz", - "integrity": "sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "@types/unist": "^3.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-whitespace": "^3.0.0", - "html-void-elements": "^3.0.0", - "mdast-util-to-hast": "^13.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", @@ -17981,21 +18120,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/rehype-stringify": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", - "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0", - "hast-util-to-html": "^9.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/remark-gfm": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", diff --git a/keep-ui/package.json b/keep-ui/package.json index 1209ef2c6..30d2c6187 100644 --- a/keep-ui/package.json +++ b/keep-ui/package.json @@ -29,6 +29,7 @@ "@heroicons/react": "^2.0.18", "@mui/material": "^5.15.18", "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-tooltip": "^1.1.3", "@svgr/webpack": "^8.0.1", "@tanstack/react-table": "^8.11.0", "@tremor/react": "^3.18.3", diff --git a/keep-ui/tailwind.config.js b/keep-ui/tailwind.config.js index 595f66d20..ff29d25be 100644 --- a/keep-ui/tailwind.config.js +++ b/keep-ui/tailwind.config.js @@ -102,6 +102,38 @@ module.exports = { "tremor-title": ["1.125rem", { lineHeight: "1.75rem" }], "tremor-metric": ["1.875rem", { lineHeight: "2.25rem" }], }, + keyframes: { + hide: { + from: { opacity: "1" }, + to: { opacity: "0" }, + }, + slideDownAndFade: { + from: { opacity: "0", transform: "translateY(-6px)" }, + to: { opacity: "1", transform: "translateY(0)" }, + }, + slideLeftAndFade: { + from: { opacity: "0", transform: "translateX(6px)" }, + to: { opacity: "1", transform: "translateX(0)" }, + }, + slideUpAndFade: { + from: { opacity: "0", transform: "translateY(6px)" }, + to: { opacity: "1", transform: "translateY(0)" }, + }, + slideRightAndFade: { + from: { opacity: "0", transform: "translateX(-6px)" }, + to: { opacity: "1", transform: "translateX(0)" }, + }, + }, + animation: { + hide: "hide 150ms cubic-bezier(0.16, 1, 0.3, 1)", + slideDownAndFade: + "slideDownAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)", + slideLeftAndFade: + "slideLeftAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)", + slideUpAndFade: "slideUpAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)", + slideRightAndFade: + "slideRightAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)", + }, }, }, safelist: [