@nucleux/caveat 0.0.0-stage → 0.6.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/LICENSE +21 -0
- package/README.md +39 -2
- package/dist/index.cjs +81 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +49 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nucleux
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,40 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @nucleux/caveat
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Caveat — says what is incomplete, uncertain or out of date about an AI result — Nucleux agentic UI for React.
|
|
4
|
+
|
|
5
|
+
Part of **[Nucleux](https://github.com/intelligaia-open-labs/nucleux)** — agentic UI components for React. Install a single component, or the full kit via [`@nucleux/react`](https://www.npmjs.com/package/@nucleux/react).
|
|
6
|
+
|
|
7
|
+
## Exports
|
|
8
|
+
|
|
9
|
+
- **`Caveat`** — a calm reminder that AI output can be wrong, or (better) the specific limitation of this result. `variant`: `below-input` (default caption under the composer) / `output-footer` (filled note under output that will be acted on); `icon` (`null` to omit); `actions` (next steps such as "Review sources"). Rendered as `role="note"`.
|
|
10
|
+
- **`CaveatTooltip`** — the `info-tooltip` variant: wraps the generate control (e.g. `Iconography`), shows the caveat on hover and focus, and links it with `aria-describedby`. `content`, `side`, `showIcon`.
|
|
11
|
+
|
|
12
|
+
Caption-size, muted, never alarming or apologetic; once per surface, repeated only where output will be acted on.
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add @nucleux/caveat @nucleux/tokens
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`react` / `react-dom` are peer dependencies.
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import { Caveat, CaveatTooltip } from "@nucleux/caveat";
|
|
26
|
+
import { Iconography } from "@nucleux/iconography";
|
|
27
|
+
|
|
28
|
+
<Caveat>Aria may make mistakes. Verify important info.</Caveat>
|
|
29
|
+
<Caveat variant="output-footer" actions={<Button size="sm" variant="ghost">Review sources</Button>}>
|
|
30
|
+
2 of 8 interviews could not be opened, so this summary reflects 6.
|
|
31
|
+
</Caveat>
|
|
32
|
+
<CaveatTooltip content="Output may be inaccurate"><Iconography label="Generate" /></CaveatTooltip>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Requires the theme once in your app: `import "@nucleux/tokens/styles.css";`
|
|
36
|
+
and the Tailwind preset from `@nucleux/tokens/preset`.
|
|
37
|
+
|
|
38
|
+
## License
|
|
39
|
+
|
|
40
|
+
MIT © Nucleux
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var lucideReact = require('lucide-react');
|
|
6
|
+
var utils = require('@nucleux/utils');
|
|
7
|
+
var tooltip = require('@nucleux/tooltip');
|
|
8
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
9
|
+
|
|
10
|
+
function _interopNamespace(e) {
|
|
11
|
+
if (e && e.__esModule) return e;
|
|
12
|
+
var n = Object.create(null);
|
|
13
|
+
if (e) {
|
|
14
|
+
Object.keys(e).forEach(function (k) {
|
|
15
|
+
if (k !== 'default') {
|
|
16
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
17
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
get: function () { return e[k]; }
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
n.default = e;
|
|
25
|
+
return Object.freeze(n);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
29
|
+
|
|
30
|
+
// src/index.tsx
|
|
31
|
+
var DEFAULT_TEXT = "AI can make mistakes. Verify important information.";
|
|
32
|
+
var Caveat = React__namespace.forwardRef(
|
|
33
|
+
({ variant = "below-input", icon, actions, className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
34
|
+
"p",
|
|
35
|
+
{
|
|
36
|
+
ref,
|
|
37
|
+
role: "note",
|
|
38
|
+
"data-variant": variant,
|
|
39
|
+
className: utils.cn(
|
|
40
|
+
"items-center gap-1.5 text-xs text-muted-foreground [&_svg]:size-3.5 [&_svg]:shrink-0",
|
|
41
|
+
variant === "output-footer" ? "mt-2.5 flex w-full flex-wrap rounded-md border border-border bg-muted/60 px-2.5 py-2 text-foreground/80" : "inline-flex",
|
|
42
|
+
className
|
|
43
|
+
),
|
|
44
|
+
...props,
|
|
45
|
+
children: [
|
|
46
|
+
icon === void 0 ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Info, { "aria-hidden": "true" }) : icon,
|
|
47
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: children ?? DEFAULT_TEXT }),
|
|
48
|
+
actions && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto inline-flex flex-wrap items-center gap-1.5", children: actions })
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
);
|
|
53
|
+
Caveat.displayName = "Caveat";
|
|
54
|
+
var CaveatTooltip = React__namespace.forwardRef(
|
|
55
|
+
({ content = "Output may be inaccurate", side = "top", showIcon = true, children, ...props }, ref) => {
|
|
56
|
+
const id = React__namespace.useId();
|
|
57
|
+
const childProps = children.props;
|
|
58
|
+
const trigger = React__namespace.cloneElement(children, {
|
|
59
|
+
"aria-describedby": [childProps["aria-describedby"], id].filter(Boolean).join(" ")
|
|
60
|
+
});
|
|
61
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
62
|
+
tooltip.Tooltip,
|
|
63
|
+
{
|
|
64
|
+
ref,
|
|
65
|
+
side,
|
|
66
|
+
content: /* @__PURE__ */ jsxRuntime.jsxs("span", { id, className: "inline-flex items-center gap-1.5 [&_svg]:size-3", children: [
|
|
67
|
+
showIcon && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Info, { "aria-hidden": "true" }),
|
|
68
|
+
content
|
|
69
|
+
] }),
|
|
70
|
+
...props,
|
|
71
|
+
children: trigger
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
CaveatTooltip.displayName = "CaveatTooltip";
|
|
77
|
+
|
|
78
|
+
exports.Caveat = Caveat;
|
|
79
|
+
exports.CaveatTooltip = CaveatTooltip;
|
|
80
|
+
//# sourceMappingURL=index.cjs.map
|
|
81
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"names":["React","jsxs","cn","jsx","Info","Tooltip"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,IAAM,YAAA,GAAe,qDAAA;AAUd,IAAM,MAAA,GAAeA,gBAAA,CAAA,UAAA;AAAA,EAC1B,CAAC,EAAE,OAAA,GAAU,aAAA,EAAe,IAAA,EAAM,OAAA,EAAS,SAAA,EAAW,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1EC,eAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,IAAA,EAAK,MAAA;AAAA,MACL,cAAA,EAAc,OAAA;AAAA,MACd,SAAA,EAAWC,QAAA;AAAA,QACT,sFAAA;AAAA,QACA,OAAA,KAAY,kBACR,yGAAA,GACA,aAAA;AAAA,QACJ;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,IAAA,KAAS,MAAA,mBAAYC,cAAA,CAACC,gBAAA,EAAA,EAAK,aAAA,EAAY,QAAO,CAAA,GAAK,IAAA;AAAA,wBACpDD,cAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,QAAA,IAAY,YAAA,EAAa,CAAA;AAAA,QAC/B,OAAA,oBAAWA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,sDAAsD,QAAA,EAAA,OAAA,EAAQ;AAAA;AAAA;AAAA;AAGhG;AACA,MAAA,CAAO,WAAA,GAAc,QAAA;AAkBd,IAAM,aAAA,GAAsBH,gBAAA,CAAA,UAAA;AAAA,EACjC,CAAC,EAAE,OAAA,GAAU,0BAAA,EAA4B,IAAA,GAAO,KAAA,EAAO,QAAA,GAAW,IAAA,EAAM,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACpG,IAAA,MAAM,KAAWA,gBAAA,CAAA,KAAA,EAAM;AACvB,IAAA,MAAM,aAAa,QAAA,CAAS,KAAA;AAC5B,IAAA,MAAM,OAAA,GAAgBA,8BAAa,QAAA,EAAU;AAAA,MAC3C,kBAAA,EAAoB,CAAC,UAAA,CAAW,kBAAkB,CAAA,EAAG,EAAE,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG;AAAA,KACvD,CAAA;AAC5B,IAAA,uBACEG,cAAA;AAAA,MAACE,eAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,IAAA;AAAA,QACA,OAAA,kBACEJ,eAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAQ,WAAU,iDAAA,EACrB,QAAA,EAAA;AAAA,UAAA,QAAA,oBAAYE,cAAA,CAACC,gBAAA,EAAA,EAAK,aAAA,EAAY,MAAA,EAAO,CAAA;AAAA,UACrC;AAAA,SAAA,EACH,CAAA;AAAA,QAED,GAAG,KAAA;AAAA,QAEH,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,EAEJ;AACF;AACA,aAAA,CAAc,WAAA,GAAc,eAAA","file":"index.cjs","sourcesContent":["import * as React from \"react\";\nimport { Info } from \"lucide-react\";\nimport { cn } from \"@nucleux/utils\";\nimport { Tooltip, type TooltipSide } from \"@nucleux/tooltip\";\n\n/**\n * Where the caveat sits.\n * - `below-input` — a quiet caption under the composer, seen before anything is sent (default).\n * - `output-footer` — a filled note under output that will be acted on (sent, published,\n * deployed); can carry next steps in `actions`.\n * For the third spec variant, `info-tooltip`, wrap the generate control in `CaveatTooltip`.\n */\nexport type CaveatVariant = \"below-input\" | \"output-footer\";\n\nexport interface CaveatProps extends React.HTMLAttributes<HTMLParagraphElement> {\n /** Placement style. Default `below-input`. */\n variant?: CaveatVariant;\n /** Leading icon. Defaults to an info glyph. Pass `null` to omit. */\n icon?: React.ReactNode;\n /**\n * Next steps that remove the reason for the caveat — \"Review sources\",\n * \"Reconnect\". Shown after the text; use small Buttons or links.\n */\n actions?: React.ReactNode;\n}\n\nconst DEFAULT_TEXT = \"AI can make mistakes. Verify important information.\";\n\n/**\n * A short, calm reminder that AI output can be wrong and should be checked —\n * or, better, the specific limitation of this result (\"2 of 8 interviews\n * could not be opened\"). Caption-size and muted, never alarming or\n * apologetic, once per surface. `below-input` sits under the composer;\n * `output-footer` sits under output that will be acted on and can offer\n * next steps. Rendered as a `note`.\n */\nexport const Caveat = React.forwardRef<HTMLParagraphElement, CaveatProps>(\n ({ variant = \"below-input\", icon, actions, className, children, ...props }, ref) => (\n <p\n ref={ref}\n role=\"note\"\n data-variant={variant}\n className={cn(\n \"items-center gap-1.5 text-xs text-muted-foreground [&_svg]:size-3.5 [&_svg]:shrink-0\",\n variant === \"output-footer\"\n ? \"mt-2.5 flex w-full flex-wrap rounded-md border border-border bg-muted/60 px-2.5 py-2 text-foreground/80\"\n : \"inline-flex\",\n className,\n )}\n {...props}\n >\n {icon === undefined ? <Info aria-hidden=\"true\" /> : icon}\n <span>{children ?? DEFAULT_TEXT}</span>\n {actions && <span className=\"ml-auto inline-flex flex-wrap items-center gap-1.5\">{actions}</span>}\n </p>\n ),\n);\nCaveat.displayName = \"Caveat\";\n\nexport interface CaveatTooltipProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, \"content\"> {\n /** The caveat. Default \"Output may be inaccurate\". */\n content?: React.ReactNode;\n /** Side of the trigger. Default `top`. */\n side?: TooltipSide;\n /** Show the info glyph in the tooltip. Default `true`. */\n showIcon?: boolean;\n /** The AI action the caveat rides on — a single focusable element (e.g. an `Iconography` or Button). */\n children: React.ReactElement;\n}\n\n/**\n * The `info-tooltip` caveat: the reminder rides the generate control,\n * shown on hover and keyboard focus without ever being in the way, and\n * linked to the control with `aria-describedby` so screen readers hear it too.\n */\nexport const CaveatTooltip = React.forwardRef<HTMLSpanElement, CaveatTooltipProps>(\n ({ content = \"Output may be inaccurate\", side = \"top\", showIcon = true, children, ...props }, ref) => {\n const id = React.useId();\n const childProps = children.props as { \"aria-describedby\"?: string };\n const trigger = React.cloneElement(children, {\n \"aria-describedby\": [childProps[\"aria-describedby\"], id].filter(Boolean).join(\" \"),\n } as Record<string, unknown>);\n return (\n <Tooltip\n ref={ref}\n side={side}\n content={\n <span id={id} className=\"inline-flex items-center gap-1.5 [&_svg]:size-3\">\n {showIcon && <Info aria-hidden=\"true\" />}\n {content}\n </span>\n }\n {...props}\n >\n {trigger}\n </Tooltip>\n );\n },\n);\nCaveatTooltip.displayName = \"CaveatTooltip\";\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { TooltipSide } from '@nucleux/tooltip';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Where the caveat sits.
|
|
6
|
+
* - `below-input` — a quiet caption under the composer, seen before anything is sent (default).
|
|
7
|
+
* - `output-footer` — a filled note under output that will be acted on (sent, published,
|
|
8
|
+
* deployed); can carry next steps in `actions`.
|
|
9
|
+
* For the third spec variant, `info-tooltip`, wrap the generate control in `CaveatTooltip`.
|
|
10
|
+
*/
|
|
11
|
+
type CaveatVariant = "below-input" | "output-footer";
|
|
12
|
+
interface CaveatProps extends React.HTMLAttributes<HTMLParagraphElement> {
|
|
13
|
+
/** Placement style. Default `below-input`. */
|
|
14
|
+
variant?: CaveatVariant;
|
|
15
|
+
/** Leading icon. Defaults to an info glyph. Pass `null` to omit. */
|
|
16
|
+
icon?: React.ReactNode;
|
|
17
|
+
/**
|
|
18
|
+
* Next steps that remove the reason for the caveat — "Review sources",
|
|
19
|
+
* "Reconnect". Shown after the text; use small Buttons or links.
|
|
20
|
+
*/
|
|
21
|
+
actions?: React.ReactNode;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A short, calm reminder that AI output can be wrong and should be checked —
|
|
25
|
+
* or, better, the specific limitation of this result ("2 of 8 interviews
|
|
26
|
+
* could not be opened"). Caption-size and muted, never alarming or
|
|
27
|
+
* apologetic, once per surface. `below-input` sits under the composer;
|
|
28
|
+
* `output-footer` sits under output that will be acted on and can offer
|
|
29
|
+
* next steps. Rendered as a `note`.
|
|
30
|
+
*/
|
|
31
|
+
declare const Caveat: React.ForwardRefExoticComponent<CaveatProps & React.RefAttributes<HTMLParagraphElement>>;
|
|
32
|
+
interface CaveatTooltipProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "content"> {
|
|
33
|
+
/** The caveat. Default "Output may be inaccurate". */
|
|
34
|
+
content?: React.ReactNode;
|
|
35
|
+
/** Side of the trigger. Default `top`. */
|
|
36
|
+
side?: TooltipSide;
|
|
37
|
+
/** Show the info glyph in the tooltip. Default `true`. */
|
|
38
|
+
showIcon?: boolean;
|
|
39
|
+
/** The AI action the caveat rides on — a single focusable element (e.g. an `Iconography` or Button). */
|
|
40
|
+
children: React.ReactElement;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The `info-tooltip` caveat: the reminder rides the generate control,
|
|
44
|
+
* shown on hover and keyboard focus without ever being in the way, and
|
|
45
|
+
* linked to the control with `aria-describedby` so screen readers hear it too.
|
|
46
|
+
*/
|
|
47
|
+
declare const CaveatTooltip: React.ForwardRefExoticComponent<CaveatTooltipProps & React.RefAttributes<HTMLSpanElement>>;
|
|
48
|
+
|
|
49
|
+
export { Caveat, type CaveatProps, CaveatTooltip, type CaveatTooltipProps, type CaveatVariant };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { TooltipSide } from '@nucleux/tooltip';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Where the caveat sits.
|
|
6
|
+
* - `below-input` — a quiet caption under the composer, seen before anything is sent (default).
|
|
7
|
+
* - `output-footer` — a filled note under output that will be acted on (sent, published,
|
|
8
|
+
* deployed); can carry next steps in `actions`.
|
|
9
|
+
* For the third spec variant, `info-tooltip`, wrap the generate control in `CaveatTooltip`.
|
|
10
|
+
*/
|
|
11
|
+
type CaveatVariant = "below-input" | "output-footer";
|
|
12
|
+
interface CaveatProps extends React.HTMLAttributes<HTMLParagraphElement> {
|
|
13
|
+
/** Placement style. Default `below-input`. */
|
|
14
|
+
variant?: CaveatVariant;
|
|
15
|
+
/** Leading icon. Defaults to an info glyph. Pass `null` to omit. */
|
|
16
|
+
icon?: React.ReactNode;
|
|
17
|
+
/**
|
|
18
|
+
* Next steps that remove the reason for the caveat — "Review sources",
|
|
19
|
+
* "Reconnect". Shown after the text; use small Buttons or links.
|
|
20
|
+
*/
|
|
21
|
+
actions?: React.ReactNode;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A short, calm reminder that AI output can be wrong and should be checked —
|
|
25
|
+
* or, better, the specific limitation of this result ("2 of 8 interviews
|
|
26
|
+
* could not be opened"). Caption-size and muted, never alarming or
|
|
27
|
+
* apologetic, once per surface. `below-input` sits under the composer;
|
|
28
|
+
* `output-footer` sits under output that will be acted on and can offer
|
|
29
|
+
* next steps. Rendered as a `note`.
|
|
30
|
+
*/
|
|
31
|
+
declare const Caveat: React.ForwardRefExoticComponent<CaveatProps & React.RefAttributes<HTMLParagraphElement>>;
|
|
32
|
+
interface CaveatTooltipProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, "content"> {
|
|
33
|
+
/** The caveat. Default "Output may be inaccurate". */
|
|
34
|
+
content?: React.ReactNode;
|
|
35
|
+
/** Side of the trigger. Default `top`. */
|
|
36
|
+
side?: TooltipSide;
|
|
37
|
+
/** Show the info glyph in the tooltip. Default `true`. */
|
|
38
|
+
showIcon?: boolean;
|
|
39
|
+
/** The AI action the caveat rides on — a single focusable element (e.g. an `Iconography` or Button). */
|
|
40
|
+
children: React.ReactElement;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The `info-tooltip` caveat: the reminder rides the generate control,
|
|
44
|
+
* shown on hover and keyboard focus without ever being in the way, and
|
|
45
|
+
* linked to the control with `aria-describedby` so screen readers hear it too.
|
|
46
|
+
*/
|
|
47
|
+
declare const CaveatTooltip: React.ForwardRefExoticComponent<CaveatTooltipProps & React.RefAttributes<HTMLSpanElement>>;
|
|
48
|
+
|
|
49
|
+
export { Caveat, type CaveatProps, CaveatTooltip, type CaveatTooltipProps, type CaveatVariant };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Info } from 'lucide-react';
|
|
4
|
+
import { cn } from '@nucleux/utils';
|
|
5
|
+
import { Tooltip } from '@nucleux/tooltip';
|
|
6
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
// src/index.tsx
|
|
9
|
+
var DEFAULT_TEXT = "AI can make mistakes. Verify important information.";
|
|
10
|
+
var Caveat = React.forwardRef(
|
|
11
|
+
({ variant = "below-input", icon, actions, className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
12
|
+
"p",
|
|
13
|
+
{
|
|
14
|
+
ref,
|
|
15
|
+
role: "note",
|
|
16
|
+
"data-variant": variant,
|
|
17
|
+
className: cn(
|
|
18
|
+
"items-center gap-1.5 text-xs text-muted-foreground [&_svg]:size-3.5 [&_svg]:shrink-0",
|
|
19
|
+
variant === "output-footer" ? "mt-2.5 flex w-full flex-wrap rounded-md border border-border bg-muted/60 px-2.5 py-2 text-foreground/80" : "inline-flex",
|
|
20
|
+
className
|
|
21
|
+
),
|
|
22
|
+
...props,
|
|
23
|
+
children: [
|
|
24
|
+
icon === void 0 ? /* @__PURE__ */ jsx(Info, { "aria-hidden": "true" }) : icon,
|
|
25
|
+
/* @__PURE__ */ jsx("span", { children: children ?? DEFAULT_TEXT }),
|
|
26
|
+
actions && /* @__PURE__ */ jsx("span", { className: "ml-auto inline-flex flex-wrap items-center gap-1.5", children: actions })
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
)
|
|
30
|
+
);
|
|
31
|
+
Caveat.displayName = "Caveat";
|
|
32
|
+
var CaveatTooltip = React.forwardRef(
|
|
33
|
+
({ content = "Output may be inaccurate", side = "top", showIcon = true, children, ...props }, ref) => {
|
|
34
|
+
const id = React.useId();
|
|
35
|
+
const childProps = children.props;
|
|
36
|
+
const trigger = React.cloneElement(children, {
|
|
37
|
+
"aria-describedby": [childProps["aria-describedby"], id].filter(Boolean).join(" ")
|
|
38
|
+
});
|
|
39
|
+
return /* @__PURE__ */ jsx(
|
|
40
|
+
Tooltip,
|
|
41
|
+
{
|
|
42
|
+
ref,
|
|
43
|
+
side,
|
|
44
|
+
content: /* @__PURE__ */ jsxs("span", { id, className: "inline-flex items-center gap-1.5 [&_svg]:size-3", children: [
|
|
45
|
+
showIcon && /* @__PURE__ */ jsx(Info, { "aria-hidden": "true" }),
|
|
46
|
+
content
|
|
47
|
+
] }),
|
|
48
|
+
...props,
|
|
49
|
+
children: trigger
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
CaveatTooltip.displayName = "CaveatTooltip";
|
|
55
|
+
|
|
56
|
+
export { Caveat, CaveatTooltip };
|
|
57
|
+
//# sourceMappingURL=index.js.map
|
|
58
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx"],"names":[],"mappings":";;;;;;;AA0BA,IAAM,YAAA,GAAe,qDAAA;AAUd,IAAM,MAAA,GAAe,KAAA,CAAA,UAAA;AAAA,EAC1B,CAAC,EAAE,OAAA,GAAU,aAAA,EAAe,IAAA,EAAM,OAAA,EAAS,SAAA,EAAW,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1E,IAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,IAAA,EAAK,MAAA;AAAA,MACL,cAAA,EAAc,OAAA;AAAA,MACd,SAAA,EAAW,EAAA;AAAA,QACT,sFAAA;AAAA,QACA,OAAA,KAAY,kBACR,yGAAA,GACA,aAAA;AAAA,QACJ;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,IAAA,KAAS,MAAA,mBAAY,GAAA,CAAC,IAAA,EAAA,EAAK,aAAA,EAAY,QAAO,CAAA,GAAK,IAAA;AAAA,wBACpD,GAAA,CAAC,MAAA,EAAA,EAAM,QAAA,EAAA,QAAA,IAAY,YAAA,EAAa,CAAA;AAAA,QAC/B,OAAA,oBAAW,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,sDAAsD,QAAA,EAAA,OAAA,EAAQ;AAAA;AAAA;AAAA;AAGhG;AACA,MAAA,CAAO,WAAA,GAAc,QAAA;AAkBd,IAAM,aAAA,GAAsB,KAAA,CAAA,UAAA;AAAA,EACjC,CAAC,EAAE,OAAA,GAAU,0BAAA,EAA4B,IAAA,GAAO,KAAA,EAAO,QAAA,GAAW,IAAA,EAAM,QAAA,EAAU,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACpG,IAAA,MAAM,KAAW,KAAA,CAAA,KAAA,EAAM;AACvB,IAAA,MAAM,aAAa,QAAA,CAAS,KAAA;AAC5B,IAAA,MAAM,OAAA,GAAgB,mBAAa,QAAA,EAAU;AAAA,MAC3C,kBAAA,EAAoB,CAAC,UAAA,CAAW,kBAAkB,CAAA,EAAG,EAAE,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG;AAAA,KACvD,CAAA;AAC5B,IAAA,uBACE,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,IAAA;AAAA,QACA,OAAA,kBACE,IAAA,CAAC,MAAA,EAAA,EAAK,EAAA,EAAQ,WAAU,iDAAA,EACrB,QAAA,EAAA;AAAA,UAAA,QAAA,oBAAY,GAAA,CAAC,IAAA,EAAA,EAAK,aAAA,EAAY,MAAA,EAAO,CAAA;AAAA,UACrC;AAAA,SAAA,EACH,CAAA;AAAA,QAED,GAAG,KAAA;AAAA,QAEH,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,EAEJ;AACF;AACA,aAAA,CAAc,WAAA,GAAc,eAAA","file":"index.js","sourcesContent":["import * as React from \"react\";\nimport { Info } from \"lucide-react\";\nimport { cn } from \"@nucleux/utils\";\nimport { Tooltip, type TooltipSide } from \"@nucleux/tooltip\";\n\n/**\n * Where the caveat sits.\n * - `below-input` — a quiet caption under the composer, seen before anything is sent (default).\n * - `output-footer` — a filled note under output that will be acted on (sent, published,\n * deployed); can carry next steps in `actions`.\n * For the third spec variant, `info-tooltip`, wrap the generate control in `CaveatTooltip`.\n */\nexport type CaveatVariant = \"below-input\" | \"output-footer\";\n\nexport interface CaveatProps extends React.HTMLAttributes<HTMLParagraphElement> {\n /** Placement style. Default `below-input`. */\n variant?: CaveatVariant;\n /** Leading icon. Defaults to an info glyph. Pass `null` to omit. */\n icon?: React.ReactNode;\n /**\n * Next steps that remove the reason for the caveat — \"Review sources\",\n * \"Reconnect\". Shown after the text; use small Buttons or links.\n */\n actions?: React.ReactNode;\n}\n\nconst DEFAULT_TEXT = \"AI can make mistakes. Verify important information.\";\n\n/**\n * A short, calm reminder that AI output can be wrong and should be checked —\n * or, better, the specific limitation of this result (\"2 of 8 interviews\n * could not be opened\"). Caption-size and muted, never alarming or\n * apologetic, once per surface. `below-input` sits under the composer;\n * `output-footer` sits under output that will be acted on and can offer\n * next steps. Rendered as a `note`.\n */\nexport const Caveat = React.forwardRef<HTMLParagraphElement, CaveatProps>(\n ({ variant = \"below-input\", icon, actions, className, children, ...props }, ref) => (\n <p\n ref={ref}\n role=\"note\"\n data-variant={variant}\n className={cn(\n \"items-center gap-1.5 text-xs text-muted-foreground [&_svg]:size-3.5 [&_svg]:shrink-0\",\n variant === \"output-footer\"\n ? \"mt-2.5 flex w-full flex-wrap rounded-md border border-border bg-muted/60 px-2.5 py-2 text-foreground/80\"\n : \"inline-flex\",\n className,\n )}\n {...props}\n >\n {icon === undefined ? <Info aria-hidden=\"true\" /> : icon}\n <span>{children ?? DEFAULT_TEXT}</span>\n {actions && <span className=\"ml-auto inline-flex flex-wrap items-center gap-1.5\">{actions}</span>}\n </p>\n ),\n);\nCaveat.displayName = \"Caveat\";\n\nexport interface CaveatTooltipProps extends Omit<React.HTMLAttributes<HTMLSpanElement>, \"content\"> {\n /** The caveat. Default \"Output may be inaccurate\". */\n content?: React.ReactNode;\n /** Side of the trigger. Default `top`. */\n side?: TooltipSide;\n /** Show the info glyph in the tooltip. Default `true`. */\n showIcon?: boolean;\n /** The AI action the caveat rides on — a single focusable element (e.g. an `Iconography` or Button). */\n children: React.ReactElement;\n}\n\n/**\n * The `info-tooltip` caveat: the reminder rides the generate control,\n * shown on hover and keyboard focus without ever being in the way, and\n * linked to the control with `aria-describedby` so screen readers hear it too.\n */\nexport const CaveatTooltip = React.forwardRef<HTMLSpanElement, CaveatTooltipProps>(\n ({ content = \"Output may be inaccurate\", side = \"top\", showIcon = true, children, ...props }, ref) => {\n const id = React.useId();\n const childProps = children.props as { \"aria-describedby\"?: string };\n const trigger = React.cloneElement(children, {\n \"aria-describedby\": [childProps[\"aria-describedby\"], id].filter(Boolean).join(\" \"),\n } as Record<string, unknown>);\n return (\n <Tooltip\n ref={ref}\n side={side}\n content={\n <span id={id} className=\"inline-flex items-center gap-1.5 [&_svg]:size-3\">\n {showIcon && <Info aria-hidden=\"true\" />}\n {content}\n </span>\n }\n {...props}\n >\n {trigger}\n </Tooltip>\n );\n },\n);\nCaveatTooltip.displayName = \"CaveatTooltip\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,59 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nucleux/caveat",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"sideEffects": false,
|
|
6
|
+
"description": "Caveat — says what is incomplete, uncertain or out of date about an AI result — Nucleux agentic UI for React.",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"nucleux",
|
|
9
|
+
"react",
|
|
10
|
+
"ui",
|
|
11
|
+
"components",
|
|
12
|
+
"agentic",
|
|
13
|
+
"ai",
|
|
14
|
+
"tailwind",
|
|
15
|
+
"caveat"
|
|
16
|
+
],
|
|
17
|
+
"main": "./dist/index.cjs",
|
|
18
|
+
"module": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"import": "./dist/index.js",
|
|
24
|
+
"require": "./dist/index.cjs"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"react": ">=18",
|
|
33
|
+
"react-dom": ">=18"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"@nucleux/tooltip": "0.6.0",
|
|
37
|
+
"@nucleux/utils": "0.6.0",
|
|
38
|
+
"lucide-react": "^0.469.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"tsup": "^8.3.5",
|
|
42
|
+
"typescript": "^5.7.2",
|
|
43
|
+
"@types/react": "^18.3.18",
|
|
44
|
+
"react": "^18.3.1"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "git+https://github.com/intelligaia-open-labs/nucleux.git",
|
|
53
|
+
"directory": "packages/caveat"
|
|
54
|
+
},
|
|
55
|
+
"homepage": "https://github.com/intelligaia-open-labs/nucleux#readme",
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "tsup"
|
|
58
|
+
}
|
|
6
59
|
}
|