@mastra/playground-ui 41.1.0-alpha.2 → 42.0.0-alpha.4
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/CHANGELOG.md +24 -0
- package/dist/{Txt-p33XTnu8.js → Txt-Df42XG5p.js} +3 -3
- package/dist/Txt-Df42XG5p.js.map +1 -0
- package/dist/{Txt-BT8_EkuZ.cjs → Txt-I5lK8zy7.cjs} +3 -3
- package/dist/Txt-I5lK8zy7.cjs.map +1 -0
- package/dist/components/Avatar.cjs.js +1 -1
- package/dist/components/Avatar.es.js +1 -1
- package/dist/components/ClampedText.cjs.js +51 -0
- package/dist/components/ClampedText.cjs.js.map +1 -0
- package/dist/components/ClampedText.d.ts +2 -0
- package/dist/components/ClampedText.es.js +47 -0
- package/dist/components/ClampedText.es.js.map +1 -0
- package/dist/components/Entity.cjs.js +1 -1
- package/dist/components/Entity.es.js +1 -1
- package/dist/components/EntityHeader.cjs.js +1 -1
- package/dist/components/EntityHeader.es.js +1 -1
- package/dist/components/Entry.cjs.js +1 -1
- package/dist/components/Entry.es.js +1 -1
- package/dist/components/EnvironmentVariablesEditor.cjs.js +1 -1
- package/dist/components/EnvironmentVariablesEditor.es.js +1 -1
- package/dist/components/Header.cjs.js +1 -1
- package/dist/components/Header.es.js +1 -1
- package/dist/components/Table.cjs.js +1 -1
- package/dist/components/Table.es.js +1 -1
- package/dist/components/ThreadList.cjs.js +1 -1
- package/dist/components/ThreadList.es.js +1 -1
- package/dist/components/Truncate.cjs.js +1 -1
- package/dist/components/Truncate.es.js +1 -1
- package/dist/components/Txt.cjs.js +1 -1
- package/dist/components/Txt.es.js +1 -1
- package/dist/components/ai/plan.cjs.js +1 -1
- package/dist/components/ai/plan.es.js +1 -1
- package/dist/domains/memory/components/memory-studio-panel.cjs.js +1 -1
- package/dist/domains/memory/components/memory-studio-panel.es.js +1 -1
- package/dist/hooks/use-is-clamped.cjs.js +36 -0
- package/dist/hooks/use-is-clamped.cjs.js.map +1 -0
- package/dist/hooks/use-is-clamped.d.ts +2 -0
- package/dist/hooks/use-is-clamped.es.js +32 -0
- package/dist/hooks/use-is-clamped.es.js.map +1 -0
- package/dist/src/ds/components/ClampedText/clamped-text.d.ts +20 -0
- package/dist/src/ds/components/ClampedText/clamped-text.stories.d.ts +8 -0
- package/dist/src/ds/components/ClampedText/index.d.ts +1 -0
- package/dist/src/ds/components/Txt/Txt.d.ts +3 -2
- package/dist/src/hooks/use-is-clamped.d.ts +11 -0
- package/dist/style.css +32 -0
- package/package.json +6 -6
- package/dist/Txt-BT8_EkuZ.cjs.map +0 -1
- package/dist/Txt-p33XTnu8.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @mastra/playground-ui
|
|
2
2
|
|
|
3
|
+
## 42.0.0-alpha.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [[`4cfdd64`](https://github.com/mastra-ai/mastra/commit/4cfdd645794feaea0c4ea711e70ecdfbef0c5b8e)]:
|
|
8
|
+
- @mastra/core@1.52.0-alpha.4
|
|
9
|
+
- @mastra/client-js@1.33.0-alpha.4
|
|
10
|
+
- @mastra/react@1.2.6-alpha.4
|
|
11
|
+
|
|
12
|
+
## 42.0.0-alpha.3
|
|
13
|
+
|
|
14
|
+
### Minor Changes
|
|
15
|
+
|
|
16
|
+
- Added ClampedText, a design-system component that clamps text to a number of lines and shows a "Read more" toggle only when the clamp actually cuts content. Detection is based on the rendered layout (element measurement, re-checked on resize and after fonts load), not on character count. ([#19565](https://github.com/mastra-ai/mastra/pull/19565))
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Fixed the ClampedText read-more button to announce its expanded state to screen readers, and fixed clamp measurement so font-load re-measure and effect cleanup still run in browsers without ResizeObserver. ([#19582](https://github.com/mastra-ai/mastra/pull/19582))
|
|
21
|
+
|
|
22
|
+
- Updated dependencies [[`1426af2`](https://github.com/mastra-ai/mastra/commit/1426af24975879c000d13ac75673f630fcc970c1), [`4696604`](https://github.com/mastra-ai/mastra/commit/4696604a8db7517459e7075ed4a6924114cdbdfb), [`975295d`](https://github.com/mastra-ai/mastra/commit/975295d418552f0d46a59edfef4c3ee555f9930a), [`85e4fb5`](https://github.com/mastra-ai/mastra/commit/85e4fb50087a81c74df3a762f53b56373db0b912), [`22c7ca8`](https://github.com/mastra-ai/mastra/commit/22c7ca85b893ebc9bf0113309e13d238a896bdaf), [`85e4fb5`](https://github.com/mastra-ai/mastra/commit/85e4fb50087a81c74df3a762f53b56373db0b912), [`ef03c0c`](https://github.com/mastra-ai/mastra/commit/ef03c0cfc62367a458e4cc56462e2148b35681c5), [`4fb4d88`](https://github.com/mastra-ai/mastra/commit/4fb4d881bc107acee13890ad4d78661016c510ed), [`4eba27a`](https://github.com/mastra-ai/mastra/commit/4eba27adcf60f991df0e62f94b3e75b4e67f3b4b), [`c701be3`](https://github.com/mastra-ai/mastra/commit/c701be32d7d9aa94a66da8c6cc38dcac6856f464), [`50e0ec5`](https://github.com/mastra-ai/mastra/commit/50e0ec5a1b2f3dec9eb1333487be733ac499173c)]:
|
|
23
|
+
- @mastra/core@1.52.0-alpha.3
|
|
24
|
+
- @mastra/client-js@1.33.0-alpha.3
|
|
25
|
+
- @mastra/react@1.2.6-alpha.3
|
|
26
|
+
|
|
3
27
|
## 41.1.0-alpha.2
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -18,9 +18,9 @@ const variants = {
|
|
|
18
18
|
const fonts = {
|
|
19
19
|
mono: "font-mono"
|
|
20
20
|
};
|
|
21
|
-
const Txt = ({ as: Root = "p", className, variant = "ui-md", font, ...props }) => {
|
|
22
|
-
return /* @__PURE__ */ jsx(Root, { className: cn(variants[variant], font && fonts[font], className), ...props });
|
|
21
|
+
const Txt = ({ as: Root = "p", className, variant = "ui-md", font, ref, ...props }) => {
|
|
22
|
+
return /* @__PURE__ */ jsx(Root, { ref, className: cn(variants[variant], font && fonts[font], className), ...props });
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
export { Txt as T };
|
|
26
|
-
//# sourceMappingURL=Txt-
|
|
26
|
+
//# sourceMappingURL=Txt-Df42XG5p.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Txt-Df42XG5p.js","sources":["../src/ds/components/Txt/Txt.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode, Ref } from 'react';\n\nimport type { FontSizes } from '../../tokens';\nimport { cn } from '@/lib/utils';\n\nexport interface TxtProps extends HTMLAttributes<HTMLDivElement | HTMLLabelElement> {\n as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'label' | 'div';\n ref?: Ref<HTMLElement>;\n variant?: keyof typeof FontSizes;\n font?: 'mono';\n htmlFor?: string;\n className?: string;\n title?: string;\n children?: ReactNode;\n}\n\nconst variants = {\n // UI text sizes\n 'ui-xs': 'text-ui-xs leading-ui-xs',\n 'ui-sm': 'text-ui-sm leading-ui-sm',\n 'ui-smd': 'text-ui-smd leading-ui-smd',\n 'ui-md': 'text-ui-md leading-ui-md',\n 'ui-lg': 'text-ui-lg leading-ui-lg',\n // Header sizes\n 'header-xs': 'text-header-xs leading-header-xs',\n 'header-sm': 'text-header-sm leading-header-sm',\n 'header-md': 'text-header-md leading-header-md',\n 'header-lg': 'text-header-lg leading-header-lg',\n 'header-xl': 'text-header-xl leading-header-xl',\n};\n\nconst fonts = {\n mono: 'font-mono',\n};\n\nexport const Txt = ({ as: Root = 'p', className, variant = 'ui-md', font, ref, ...props }: TxtProps) => {\n // Cast needed: `Root` is polymorphic, so TS narrows the expected ref to a single element type.\n return <Root ref={ref as never} className={cn(variants[variant], font && fonts[font], className)} {...props} />;\n};\n"],"names":[],"mappings":";;;AAgBA,MAAM,QAAA,GAAW;AAAA;AAAA,EAEf,OAAA,EAAS,0BAAA;AAAA,EACT,OAAA,EAAS,0BAAA;AAAA,EACT,QAAA,EAAU,4BAAA;AAAA,EACV,OAAA,EAAS,0BAAA;AAAA,EACT,OAAA,EAAS,0BAAA;AAAA;AAAA,EAET,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa;AACf,CAAA;AAEA,MAAM,KAAA,GAAQ;AAAA,EACZ,IAAA,EAAM;AACR,CAAA;AAEO,MAAM,GAAA,GAAM,CAAC,EAAE,EAAA,EAAI,IAAA,GAAO,GAAA,EAAK,SAAA,EAAW,OAAA,GAAU,OAAA,EAAS,IAAA,EAAM,GAAA,EAAK,GAAG,OAAM,KAAgB;AAEtG,EAAA,uBAAO,GAAA,CAAC,IAAA,EAAA,EAAK,GAAA,EAAmB,SAAA,EAAW,GAAG,QAAA,CAAS,OAAO,CAAA,EAAG,IAAA,IAAQ,MAAM,IAAI,CAAA,EAAG,SAAS,CAAA,EAAI,GAAG,KAAA,EAAO,CAAA;AAC/G;;;;"}
|
|
@@ -20,9 +20,9 @@ const variants = {
|
|
|
20
20
|
const fonts = {
|
|
21
21
|
mono: "font-mono"
|
|
22
22
|
};
|
|
23
|
-
const Txt = ({ as: Root = "p", className, variant = "ui-md", font, ...props }) => {
|
|
24
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Root, { className: utils_cn.cn(variants[variant], font && fonts[font], className), ...props });
|
|
23
|
+
const Txt = ({ as: Root = "p", className, variant = "ui-md", font, ref, ...props }) => {
|
|
24
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Root, { ref, className: utils_cn.cn(variants[variant], font && fonts[font], className), ...props });
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
exports.Txt = Txt;
|
|
28
|
-
//# sourceMappingURL=Txt-
|
|
28
|
+
//# sourceMappingURL=Txt-I5lK8zy7.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Txt-I5lK8zy7.cjs","sources":["../src/ds/components/Txt/Txt.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode, Ref } from 'react';\n\nimport type { FontSizes } from '../../tokens';\nimport { cn } from '@/lib/utils';\n\nexport interface TxtProps extends HTMLAttributes<HTMLDivElement | HTMLLabelElement> {\n as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'label' | 'div';\n ref?: Ref<HTMLElement>;\n variant?: keyof typeof FontSizes;\n font?: 'mono';\n htmlFor?: string;\n className?: string;\n title?: string;\n children?: ReactNode;\n}\n\nconst variants = {\n // UI text sizes\n 'ui-xs': 'text-ui-xs leading-ui-xs',\n 'ui-sm': 'text-ui-sm leading-ui-sm',\n 'ui-smd': 'text-ui-smd leading-ui-smd',\n 'ui-md': 'text-ui-md leading-ui-md',\n 'ui-lg': 'text-ui-lg leading-ui-lg',\n // Header sizes\n 'header-xs': 'text-header-xs leading-header-xs',\n 'header-sm': 'text-header-sm leading-header-sm',\n 'header-md': 'text-header-md leading-header-md',\n 'header-lg': 'text-header-lg leading-header-lg',\n 'header-xl': 'text-header-xl leading-header-xl',\n};\n\nconst fonts = {\n mono: 'font-mono',\n};\n\nexport const Txt = ({ as: Root = 'p', className, variant = 'ui-md', font, ref, ...props }: TxtProps) => {\n // Cast needed: `Root` is polymorphic, so TS narrows the expected ref to a single element type.\n return <Root ref={ref as never} className={cn(variants[variant], font && fonts[font], className)} {...props} />;\n};\n"],"names":["jsx","cn"],"mappings":";;;;;AAgBA,MAAM,QAAA,GAAW;AAAA;AAAA,EAEf,OAAA,EAAS,0BAAA;AAAA,EACT,OAAA,EAAS,0BAAA;AAAA,EACT,QAAA,EAAU,4BAAA;AAAA,EACV,OAAA,EAAS,0BAAA;AAAA,EACT,OAAA,EAAS,0BAAA;AAAA;AAAA,EAET,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa;AACf,CAAA;AAEA,MAAM,KAAA,GAAQ;AAAA,EACZ,IAAA,EAAM;AACR,CAAA;AAEO,MAAM,GAAA,GAAM,CAAC,EAAE,EAAA,EAAI,IAAA,GAAO,GAAA,EAAK,SAAA,EAAW,OAAA,GAAU,OAAA,EAAS,IAAA,EAAM,GAAA,EAAK,GAAG,OAAM,KAAgB;AAEtG,EAAA,uBAAOA,cAAA,CAAC,IAAA,EAAA,EAAK,GAAA,EAAmB,SAAA,EAAWC,YAAG,QAAA,CAAS,OAAO,CAAA,EAAG,IAAA,IAAQ,MAAM,IAAI,CAAA,EAAG,SAAS,CAAA,EAAI,GAAG,KAAA,EAAO,CAAA;AAC/G;;;;"}
|
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
4
4
|
|
|
5
5
|
const jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
const React = require('react');
|
|
7
|
-
const Txt = require('../Txt-
|
|
7
|
+
const Txt = require('../Txt-I5lK8zy7.cjs');
|
|
8
8
|
const primitives_transitions = require('../primitives/transitions.cjs.js');
|
|
9
9
|
const utils_cn = require('../cn-vA5sWo9W.cjs');
|
|
10
10
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { useState } from 'react';
|
|
3
|
-
import { T as Txt } from '../Txt-
|
|
3
|
+
import { T as Txt } from '../Txt-Df42XG5p.js';
|
|
4
4
|
import { transitions } from '../primitives/transitions.es.js';
|
|
5
5
|
import { c as cn } from '../cn-BakJzhuv.js';
|
|
6
6
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
|
+
|
|
5
|
+
const jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
const React = require('react');
|
|
7
|
+
const Button = require('../Button-B5RnKrGb.cjs');
|
|
8
|
+
const Txt = require('../Txt-I5lK8zy7.cjs');
|
|
9
|
+
const icons_ChevronIcon = require('../icons/ChevronIcon.cjs.js');
|
|
10
|
+
const hooks_useIsClamped = require('../hooks/use-is-clamped.cjs.js');
|
|
11
|
+
const utils_cn = require('../cn-vA5sWo9W.cjs');
|
|
12
|
+
|
|
13
|
+
const clampClasses = {
|
|
14
|
+
1: "line-clamp-1",
|
|
15
|
+
2: "line-clamp-2",
|
|
16
|
+
3: "line-clamp-3",
|
|
17
|
+
4: "line-clamp-4",
|
|
18
|
+
5: "line-clamp-5",
|
|
19
|
+
6: "line-clamp-6"
|
|
20
|
+
};
|
|
21
|
+
function ClampedText({
|
|
22
|
+
children,
|
|
23
|
+
lines = 2,
|
|
24
|
+
readMoreLabel = "Read more",
|
|
25
|
+
showLessLabel = "Show less",
|
|
26
|
+
className,
|
|
27
|
+
...txtProps
|
|
28
|
+
}) {
|
|
29
|
+
const [isExpanded, setIsExpanded] = React.useState(false);
|
|
30
|
+
const { ref, isClamped } = hooks_useIsClamped.useIsClamped({ enabled: !isExpanded });
|
|
31
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
32
|
+
/* @__PURE__ */ jsxRuntime.jsx(Txt.Txt, { ...txtProps, className: utils_cn.cn(!isExpanded && clampClasses[lines], className), ref, children }),
|
|
33
|
+
(isClamped || isExpanded) && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
34
|
+
Button.Button,
|
|
35
|
+
{
|
|
36
|
+
variant: "ghost",
|
|
37
|
+
size: "xs",
|
|
38
|
+
className: "mt-1 -ml-[.8em] self-start justify-self-start",
|
|
39
|
+
"aria-expanded": isExpanded,
|
|
40
|
+
onClick: () => setIsExpanded((v) => !v),
|
|
41
|
+
children: [
|
|
42
|
+
isExpanded ? showLessLabel : readMoreLabel,
|
|
43
|
+
/* @__PURE__ */ jsxRuntime.jsx(icons_ChevronIcon.ChevronIcon, { className: utils_cn.cn("transition-transform", isExpanded && "rotate-180") })
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
] });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
exports.ClampedText = ClampedText;
|
|
51
|
+
//# sourceMappingURL=ClampedText.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClampedText.cjs.js","sources":["../../src/ds/components/ClampedText/clamped-text.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Button } from '@/ds/components/Button';\nimport type { TxtProps } from '@/ds/components/Txt';\nimport { Txt } from '@/ds/components/Txt';\nimport { ChevronIcon } from '@/ds/icons/ChevronIcon';\nimport { useIsClamped } from '@/hooks/use-is-clamped';\nimport { cn } from '@/lib/utils';\n\n// Tailwind needs static class names — map instead of interpolating.\nconst clampClasses = {\n 1: 'line-clamp-1',\n 2: 'line-clamp-2',\n 3: 'line-clamp-3',\n 4: 'line-clamp-4',\n 5: 'line-clamp-5',\n 6: 'line-clamp-6',\n} as const;\n\nexport type ClampedTextLines = keyof typeof clampClasses;\n\nexport interface ClampedTextProps extends Omit<TxtProps, 'children' | 'ref'> {\n children: string;\n /** Number of lines to clamp to (default: 2) */\n lines?: ClampedTextLines;\n readMoreLabel?: string;\n showLessLabel?: string;\n}\n\n/** Text clamped to a number of lines, with a \"read more\" toggle shown only when the clamp actually cuts content. */\nexport function ClampedText({\n children,\n lines = 2,\n readMoreLabel = 'Read more',\n showLessLabel = 'Show less',\n className,\n ...txtProps\n}: ClampedTextProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n const { ref, isClamped } = useIsClamped({ enabled: !isExpanded });\n\n return (\n <>\n <Txt {...txtProps} className={cn(!isExpanded && clampClasses[lines], className)} ref={ref}>\n {children}\n </Txt>\n {(isClamped || isExpanded) && (\n <Button\n variant=\"ghost\"\n size=\"xs\"\n className=\"mt-1 -ml-[.8em] self-start justify-self-start\"\n aria-expanded={isExpanded}\n onClick={() => setIsExpanded(v => !v)}\n >\n {isExpanded ? showLessLabel : readMoreLabel}\n <ChevronIcon className={cn('transition-transform', isExpanded && 'rotate-180')} />\n </Button>\n )}\n </>\n );\n}\n"],"names":["useState","useIsClamped","jsxs","Fragment","jsx","Txt","cn","Button","ChevronIcon"],"mappings":";;;;;;;;;;;;AASA,MAAM,YAAA,GAAe;AAAA,EACnB,CAAA,EAAG,cAAA;AAAA,EACH,CAAA,EAAG,cAAA;AAAA,EACH,CAAA,EAAG,cAAA;AAAA,EACH,CAAA,EAAG,cAAA;AAAA,EACH,CAAA,EAAG,cAAA;AAAA,EACH,CAAA,EAAG;AACL,CAAA;AAaO,SAAS,WAAA,CAAY;AAAA,EAC1B,QAAA;AAAA,EACA,KAAA,GAAQ,CAAA;AAAA,EACR,aAAA,GAAgB,WAAA;AAAA,EAChB,aAAA,GAAgB,WAAA;AAAA,EAChB,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAqB;AACnB,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAAS,KAAK,CAAA;AAClD,EAAA,MAAM,EAAE,KAAK,SAAA,EAAU,GAAIC,gCAAa,EAAE,OAAA,EAAS,CAAC,UAAA,EAAY,CAAA;AAEhE,EAAA,uBACEC,eAAA,CAAAC,mBAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAACC,OAAA,EAAA,EAAK,GAAG,QAAA,EAAU,SAAA,EAAWC,WAAA,CAAG,CAAC,UAAA,IAAc,YAAA,CAAa,KAAK,CAAA,EAAG,SAAS,CAAA,EAAG,KAC9E,QAAA,EACH,CAAA;AAAA,IAAA,CACE,aAAa,UAAA,qBACbJ,eAAA;AAAA,MAACK,aAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,OAAA;AAAA,QACR,IAAA,EAAK,IAAA;AAAA,QACL,SAAA,EAAU,+CAAA;AAAA,QACV,eAAA,EAAe,UAAA;AAAA,QACf,OAAA,EAAS,MAAM,aAAA,CAAc,CAAA,CAAA,KAAK,CAAC,CAAC,CAAA;AAAA,QAEnC,QAAA,EAAA;AAAA,UAAA,UAAA,GAAa,aAAA,GAAgB,aAAA;AAAA,yCAC7BC,6BAAA,EAAA,EAAY,SAAA,EAAWF,YAAG,sBAAA,EAAwB,UAAA,IAAc,YAAY,CAAA,EAAG;AAAA;AAAA;AAAA;AAClF,GAAA,EAEJ,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { B as Button } from '../Button-Dh5CZ6Ir.js';
|
|
4
|
+
import { T as Txt } from '../Txt-Df42XG5p.js';
|
|
5
|
+
import { ChevronIcon } from '../icons/ChevronIcon.es.js';
|
|
6
|
+
import { useIsClamped } from '../hooks/use-is-clamped.es.js';
|
|
7
|
+
import { c as cn } from '../cn-BakJzhuv.js';
|
|
8
|
+
|
|
9
|
+
const clampClasses = {
|
|
10
|
+
1: "line-clamp-1",
|
|
11
|
+
2: "line-clamp-2",
|
|
12
|
+
3: "line-clamp-3",
|
|
13
|
+
4: "line-clamp-4",
|
|
14
|
+
5: "line-clamp-5",
|
|
15
|
+
6: "line-clamp-6"
|
|
16
|
+
};
|
|
17
|
+
function ClampedText({
|
|
18
|
+
children,
|
|
19
|
+
lines = 2,
|
|
20
|
+
readMoreLabel = "Read more",
|
|
21
|
+
showLessLabel = "Show less",
|
|
22
|
+
className,
|
|
23
|
+
...txtProps
|
|
24
|
+
}) {
|
|
25
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
26
|
+
const { ref, isClamped } = useIsClamped({ enabled: !isExpanded });
|
|
27
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
28
|
+
/* @__PURE__ */ jsx(Txt, { ...txtProps, className: cn(!isExpanded && clampClasses[lines], className), ref, children }),
|
|
29
|
+
(isClamped || isExpanded) && /* @__PURE__ */ jsxs(
|
|
30
|
+
Button,
|
|
31
|
+
{
|
|
32
|
+
variant: "ghost",
|
|
33
|
+
size: "xs",
|
|
34
|
+
className: "mt-1 -ml-[.8em] self-start justify-self-start",
|
|
35
|
+
"aria-expanded": isExpanded,
|
|
36
|
+
onClick: () => setIsExpanded((v) => !v),
|
|
37
|
+
children: [
|
|
38
|
+
isExpanded ? showLessLabel : readMoreLabel,
|
|
39
|
+
/* @__PURE__ */ jsx(ChevronIcon, { className: cn("transition-transform", isExpanded && "rotate-180") })
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
] });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { ClampedText };
|
|
47
|
+
//# sourceMappingURL=ClampedText.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClampedText.es.js","sources":["../../src/ds/components/ClampedText/clamped-text.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { Button } from '@/ds/components/Button';\nimport type { TxtProps } from '@/ds/components/Txt';\nimport { Txt } from '@/ds/components/Txt';\nimport { ChevronIcon } from '@/ds/icons/ChevronIcon';\nimport { useIsClamped } from '@/hooks/use-is-clamped';\nimport { cn } from '@/lib/utils';\n\n// Tailwind needs static class names — map instead of interpolating.\nconst clampClasses = {\n 1: 'line-clamp-1',\n 2: 'line-clamp-2',\n 3: 'line-clamp-3',\n 4: 'line-clamp-4',\n 5: 'line-clamp-5',\n 6: 'line-clamp-6',\n} as const;\n\nexport type ClampedTextLines = keyof typeof clampClasses;\n\nexport interface ClampedTextProps extends Omit<TxtProps, 'children' | 'ref'> {\n children: string;\n /** Number of lines to clamp to (default: 2) */\n lines?: ClampedTextLines;\n readMoreLabel?: string;\n showLessLabel?: string;\n}\n\n/** Text clamped to a number of lines, with a \"read more\" toggle shown only when the clamp actually cuts content. */\nexport function ClampedText({\n children,\n lines = 2,\n readMoreLabel = 'Read more',\n showLessLabel = 'Show less',\n className,\n ...txtProps\n}: ClampedTextProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n const { ref, isClamped } = useIsClamped({ enabled: !isExpanded });\n\n return (\n <>\n <Txt {...txtProps} className={cn(!isExpanded && clampClasses[lines], className)} ref={ref}>\n {children}\n </Txt>\n {(isClamped || isExpanded) && (\n <Button\n variant=\"ghost\"\n size=\"xs\"\n className=\"mt-1 -ml-[.8em] self-start justify-self-start\"\n aria-expanded={isExpanded}\n onClick={() => setIsExpanded(v => !v)}\n >\n {isExpanded ? showLessLabel : readMoreLabel}\n <ChevronIcon className={cn('transition-transform', isExpanded && 'rotate-180')} />\n </Button>\n )}\n </>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AASA,MAAM,YAAA,GAAe;AAAA,EACnB,CAAA,EAAG,cAAA;AAAA,EACH,CAAA,EAAG,cAAA;AAAA,EACH,CAAA,EAAG,cAAA;AAAA,EACH,CAAA,EAAG,cAAA;AAAA,EACH,CAAA,EAAG,cAAA;AAAA,EACH,CAAA,EAAG;AACL,CAAA;AAaO,SAAS,WAAA,CAAY;AAAA,EAC1B,QAAA;AAAA,EACA,KAAA,GAAQ,CAAA;AAAA,EACR,aAAA,GAAgB,WAAA;AAAA,EAChB,aAAA,GAAgB,WAAA;AAAA,EAChB,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAqB;AACnB,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,SAAS,KAAK,CAAA;AAClD,EAAA,MAAM,EAAE,KAAK,SAAA,EAAU,GAAI,aAAa,EAAE,OAAA,EAAS,CAAC,UAAA,EAAY,CAAA;AAEhE,EAAA,uBACE,IAAA,CAAA,QAAA,EAAA,EACE,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,GAAA,EAAA,EAAK,GAAG,QAAA,EAAU,SAAA,EAAW,EAAA,CAAG,CAAC,UAAA,IAAc,YAAA,CAAa,KAAK,CAAA,EAAG,SAAS,CAAA,EAAG,KAC9E,QAAA,EACH,CAAA;AAAA,IAAA,CACE,aAAa,UAAA,qBACb,IAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAQ,OAAA;AAAA,QACR,IAAA,EAAK,IAAA;AAAA,QACL,SAAA,EAAU,+CAAA;AAAA,QACV,eAAA,EAAe,UAAA;AAAA,QACf,OAAA,EAAS,MAAM,aAAA,CAAc,CAAA,CAAA,KAAK,CAAC,CAAC,CAAA;AAAA,QAEnC,QAAA,EAAA;AAAA,UAAA,UAAA,GAAa,aAAA,GAAgB,aAAA;AAAA,8BAC7B,WAAA,EAAA,EAAY,SAAA,EAAW,GAAG,sBAAA,EAAwB,UAAA,IAAc,YAAY,CAAA,EAAG;AAAA;AAAA;AAAA;AAClF,GAAA,EAEJ,CAAA;AAEJ;;;;"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
|
|
5
5
|
const jsxRuntime = require('react/jsx-runtime');
|
|
6
|
-
const Txt = require('../Txt-
|
|
6
|
+
const Txt = require('../Txt-I5lK8zy7.cjs');
|
|
7
7
|
const icons_Icon = require('../icons/Icon.cjs.js');
|
|
8
8
|
require('lucide-react');
|
|
9
9
|
const utils_cn = require('../cn-vA5sWo9W.cjs');
|
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
4
4
|
|
|
5
5
|
const jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
const skeleton = require('../skeleton-C0zXt2_f.cjs');
|
|
7
|
-
const Txt = require('../Txt-
|
|
7
|
+
const Txt = require('../Txt-I5lK8zy7.cjs');
|
|
8
8
|
const icons_Icon = require('../icons/Icon.cjs.js');
|
|
9
9
|
require('lucide-react');
|
|
10
10
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { S as Skeleton } from '../skeleton-C5-7V8Ni.js';
|
|
3
|
-
import { T as Txt } from '../Txt-
|
|
3
|
+
import { T as Txt } from '../Txt-Df42XG5p.js';
|
|
4
4
|
import { Icon } from '../icons/Icon.es.js';
|
|
5
5
|
import 'lucide-react';
|
|
6
6
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
|
|
5
5
|
const jsxRuntime = require('react/jsx-runtime');
|
|
6
|
-
const Txt = require('../Txt-
|
|
6
|
+
const Txt = require('../Txt-I5lK8zy7.cjs');
|
|
7
7
|
|
|
8
8
|
const Entry = ({ label, children }) => {
|
|
9
9
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
|
|
@@ -9,7 +9,7 @@ const React = require('react');
|
|
|
9
9
|
const Button = require('../Button-B5RnKrGb.cjs');
|
|
10
10
|
const Notice = require('../Notice-WhHdy89l.cjs');
|
|
11
11
|
const envFile = require('../env-file-BU2hStkm.cjs');
|
|
12
|
-
const Txt = require('../Txt-
|
|
12
|
+
const Txt = require('../Txt-I5lK8zy7.cjs');
|
|
13
13
|
const dataList = require('../data-list-BwGRWaNd.cjs');
|
|
14
14
|
const hooks_useCopyToClipboard = require('../hooks/use-copy-to-clipboard.cjs.js');
|
|
15
15
|
const fieldBlock = require('../field-block-Dx-fDIP9.cjs');
|
|
@@ -5,7 +5,7 @@ import { createContext, use, useState, useMemo } from 'react';
|
|
|
5
5
|
import { B as Button } from '../Button-Dh5CZ6Ir.js';
|
|
6
6
|
import { N as Notice } from '../Notice-jmHNt3gS.js';
|
|
7
7
|
import { D as DUPLICATE_ENVIRONMENT_VARIABLE_MESSAGE } from '../env-file-BITYowCx.js';
|
|
8
|
-
import { T as Txt } from '../Txt-
|
|
8
|
+
import { T as Txt } from '../Txt-Df42XG5p.js';
|
|
9
9
|
import { D as DataList } from '../data-list-By3xmGvT.js';
|
|
10
10
|
import { useCopyToClipboard } from '../hooks/use-copy-to-clipboard.es.js';
|
|
11
11
|
import { F as FieldBlock } from '../field-block-CC_EYPWe.js';
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
|
|
5
5
|
const jsxRuntime = require('react/jsx-runtime');
|
|
6
|
-
const Txt = require('../Txt-
|
|
6
|
+
const Txt = require('../Txt-I5lK8zy7.cjs');
|
|
7
7
|
const utils_cn = require('../cn-vA5sWo9W.cjs');
|
|
8
8
|
|
|
9
9
|
const Header = ({ children, border = true, className }) => {
|
|
@@ -6,7 +6,7 @@ const jsxRuntime = require('react/jsx-runtime');
|
|
|
6
6
|
const React = require('react');
|
|
7
7
|
const utils_cn = require('../cn-vA5sWo9W.cjs');
|
|
8
8
|
const icons_Icon = require('../icons/Icon.cjs.js');
|
|
9
|
-
const Txt = require('../Txt-
|
|
9
|
+
const Txt = require('../Txt-I5lK8zy7.cjs');
|
|
10
10
|
|
|
11
11
|
const rowSize = {
|
|
12
12
|
default: "[&>tbody>tr]:h-table-row",
|
|
@@ -2,7 +2,7 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
2
2
|
import { forwardRef, useRef, useEffect, useState, useCallback } from 'react';
|
|
3
3
|
import { c as cn } from '../cn-BakJzhuv.js';
|
|
4
4
|
import { Icon } from '../icons/Icon.es.js';
|
|
5
|
-
import { T as Txt } from '../Txt-
|
|
5
|
+
import { T as Txt } from '../Txt-Df42XG5p.js';
|
|
6
6
|
|
|
7
7
|
const rowSize = {
|
|
8
8
|
default: "[&>tbody>tr]:h-table-row",
|
|
@@ -6,7 +6,7 @@ const jsxRuntime = require('react/jsx-runtime');
|
|
|
6
6
|
const lucideReact = require('lucide-react');
|
|
7
7
|
const utils_cn = require('../cn-vA5sWo9W.cjs');
|
|
8
8
|
const Button = require('../Button-B5RnKrGb.cjs');
|
|
9
|
-
const Txt = require('../Txt-
|
|
9
|
+
const Txt = require('../Txt-I5lK8zy7.cjs');
|
|
10
10
|
|
|
11
11
|
const ThreadList = ({ children, "aria-label": ariaLabel = "Threads", embedded = false }) => {
|
|
12
12
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils_cn.cn("size-full", !embedded && "pb-2 pl-2"), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2,7 +2,7 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
2
2
|
import { X } from 'lucide-react';
|
|
3
3
|
import { c as cn } from '../cn-BakJzhuv.js';
|
|
4
4
|
import { B as Button } from '../Button-Dh5CZ6Ir.js';
|
|
5
|
-
import { T as Txt } from '../Txt-
|
|
5
|
+
import { T as Txt } from '../Txt-Df42XG5p.js';
|
|
6
6
|
|
|
7
7
|
const ThreadList = ({ children, "aria-label": ariaLabel = "Threads", embedded = false }) => {
|
|
8
8
|
return /* @__PURE__ */ jsx("div", { className: cn("size-full", !embedded && "pb-2 pl-2"), children: /* @__PURE__ */ jsx(
|
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
5
5
|
const jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
const copyButton = require('../copy-button-DNR760m7.cjs');
|
|
7
7
|
const tooltip = require('../tooltip-VGyJcEoE.cjs');
|
|
8
|
-
const Txt = require('../Txt-
|
|
8
|
+
const Txt = require('../Txt-I5lK8zy7.cjs');
|
|
9
9
|
const utils_cn = require('../cn-vA5sWo9W.cjs');
|
|
10
10
|
|
|
11
11
|
function Truncate({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { C as CopyButton } from '../copy-button-BuIpvUI7.js';
|
|
3
3
|
import { T as Tooltip, c as TooltipTrigger, a as TooltipContent } from '../tooltip-Ch06EF_U.js';
|
|
4
|
-
import { T as Txt } from '../Txt-
|
|
4
|
+
import { T as Txt } from '../Txt-Df42XG5p.js';
|
|
5
5
|
import { c as cn } from '../cn-BakJzhuv.js';
|
|
6
6
|
|
|
7
7
|
function Truncate({
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { T as Txt } from '../Txt-
|
|
1
|
+
export { T as Txt } from '../Txt-Df42XG5p.js';
|
|
2
2
|
//# sourceMappingURL=Txt.es.js.map
|
|
@@ -8,7 +8,7 @@ const React = require('react');
|
|
|
8
8
|
const Badge = require('../../Badge-BlJpI3fY.cjs');
|
|
9
9
|
const Button = require('../../Button-B5RnKrGb.cjs');
|
|
10
10
|
const markdownRenderer = require('../../markdown-renderer-DRnUrMmF.cjs');
|
|
11
|
-
const Txt = require('../../Txt-
|
|
11
|
+
const Txt = require('../../Txt-I5lK8zy7.cjs');
|
|
12
12
|
const icons_Icon = require('../../icons/Icon.cjs.js');
|
|
13
13
|
const hooks_useCopyToClipboard = require('../../hooks/use-copy-to-clipboard.cjs.js');
|
|
14
14
|
const utils_cn = require('../../cn-vA5sWo9W.cjs');
|
|
@@ -4,7 +4,7 @@ import { useState, createContext, useContext } from 'react';
|
|
|
4
4
|
import { B as Badge } from '../../Badge-woV6OD8k.js';
|
|
5
5
|
import { B as Button } from '../../Button-Dh5CZ6Ir.js';
|
|
6
6
|
import { M as MarkdownRenderer } from '../../markdown-renderer-ZzJcwfS3.js';
|
|
7
|
-
import { T as Txt } from '../../Txt-
|
|
7
|
+
import { T as Txt } from '../../Txt-Df42XG5p.js';
|
|
8
8
|
import { Icon } from '../../icons/Icon.es.js';
|
|
9
9
|
import { useCopyToClipboard } from '../../hooks/use-copy-to-clipboard.es.js';
|
|
10
10
|
import { c as cn } from '../../cn-BakJzhuv.js';
|
|
@@ -7,7 +7,7 @@ const lucideReact = require('lucide-react');
|
|
|
7
7
|
const React = require('react');
|
|
8
8
|
const Button = require('../../../Button-B5RnKrGb.cjs');
|
|
9
9
|
const skeleton = require('../../../skeleton-C0zXt2_f.cjs');
|
|
10
|
-
const Txt = require('../../../Txt-
|
|
10
|
+
const Txt = require('../../../Txt-I5lK8zy7.cjs');
|
|
11
11
|
const icons_MemoryIcon = require('../../../icons/MemoryIcon.cjs.js');
|
|
12
12
|
const domains_memory_lib_extractMarkers = require('../lib/extract-markers.cjs.js');
|
|
13
13
|
const domains_memory_lib_replaySelection = require('../lib/replay-selection.cjs.js');
|
|
@@ -3,7 +3,7 @@ import { ArrowLeftIcon } from 'lucide-react';
|
|
|
3
3
|
import { useState, useMemo, useEffect } from 'react';
|
|
4
4
|
import { B as Button } from '../../../Button-Dh5CZ6Ir.js';
|
|
5
5
|
import { S as Skeleton } from '../../../skeleton-C5-7V8Ni.js';
|
|
6
|
-
import { T as Txt } from '../../../Txt-
|
|
6
|
+
import { T as Txt } from '../../../Txt-Df42XG5p.js';
|
|
7
7
|
import { MemoryIcon } from '../../../icons/MemoryIcon.es.js';
|
|
8
8
|
import { extractOmMarkers } from '../lib/extract-markers.es.js';
|
|
9
9
|
import { getObservationTimestampMs, findRecordIdAtOrBefore } from '../lib/replay-selection.es.js';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
|
+
|
|
5
|
+
const React = require('react');
|
|
6
|
+
const hooks_useIsomorphicLayoutEffect = require('./use-isomorphic-layout-effect.cjs.js');
|
|
7
|
+
|
|
8
|
+
function useIsClamped({
|
|
9
|
+
enabled = true
|
|
10
|
+
} = {}) {
|
|
11
|
+
const [element, setElement] = React.useState(null);
|
|
12
|
+
const [isClamped, setIsClamped] = React.useState(false);
|
|
13
|
+
hooks_useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
|
|
14
|
+
if (!element || !enabled) return;
|
|
15
|
+
let stopped = false;
|
|
16
|
+
const measure = () => {
|
|
17
|
+
if (!stopped) setIsClamped(element.scrollHeight > element.clientHeight);
|
|
18
|
+
};
|
|
19
|
+
measure();
|
|
20
|
+
let observer;
|
|
21
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
22
|
+
observer = new ResizeObserver(measure);
|
|
23
|
+
observer.observe(element);
|
|
24
|
+
}
|
|
25
|
+
document.fonts?.ready.then(measure).catch(() => {
|
|
26
|
+
});
|
|
27
|
+
return () => {
|
|
28
|
+
stopped = true;
|
|
29
|
+
observer?.disconnect();
|
|
30
|
+
};
|
|
31
|
+
}, [element, enabled]);
|
|
32
|
+
return { ref: setElement, isClamped };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
exports.useIsClamped = useIsClamped;
|
|
36
|
+
//# sourceMappingURL=use-is-clamped.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-is-clamped.cjs.js","sources":["../../src/hooks/use-is-clamped.ts"],"sourcesContent":["import { useState } from 'react';\nimport type { RefCallback } from 'react';\n\nimport { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect';\n\nexport interface UseIsClampedOptions {\n /** Set false while the clamp is lifted (e.g. text expanded) to freeze the last measurement. */\n enabled?: boolean;\n}\n\nexport interface UseIsClampedResult<TElement extends HTMLElement> {\n ref: RefCallback<TElement>;\n isClamped: boolean;\n}\n\n/** Measures whether a clamped element has content cut off (`scrollHeight > clientHeight`), re-measuring on resize and font load. */\nexport function useIsClamped<TElement extends HTMLElement = HTMLElement>({\n enabled = true,\n}: UseIsClampedOptions = {}): UseIsClampedResult<TElement> {\n const [element, setElement] = useState<TElement | null>(null);\n const [isClamped, setIsClamped] = useState(false);\n\n useIsomorphicLayoutEffect(() => {\n if (!element || !enabled) return;\n\n let stopped = false;\n const measure = () => {\n if (!stopped) setIsClamped(element.scrollHeight > element.clientHeight);\n };\n\n measure();\n\n let observer: ResizeObserver | undefined;\n if (typeof ResizeObserver !== 'undefined') {\n observer = new ResizeObserver(measure);\n observer.observe(element);\n }\n // Font swaps change line wrapping without resizing the observed box.\n document.fonts?.ready.then(measure).catch(() => {});\n\n return () => {\n stopped = true;\n observer?.disconnect();\n };\n }, [element, enabled]);\n\n return { ref: setElement, isClamped };\n}\n"],"names":["useState","useIsomorphicLayoutEffect"],"mappings":";;;;;;;AAgBO,SAAS,YAAA,CAAyD;AAAA,EACvE,OAAA,GAAU;AACZ,CAAA,GAAyB,EAAC,EAAiC;AACzD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAA0B,IAAI,CAAA;AAC5D,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIA,eAAS,KAAK,CAAA;AAEhD,EAAAC,yDAAA,CAA0B,MAAM;AAC9B,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,OAAA,EAAS;AAE1B,IAAA,IAAI,OAAA,GAAU,KAAA;AACd,IAAA,MAAM,UAAU,MAAM;AACpB,MAAA,IAAI,CAAC,OAAA,EAAS,YAAA,CAAa,OAAA,CAAQ,YAAA,GAAe,QAAQ,YAAY,CAAA;AAAA,IACxE,CAAA;AAEA,IAAA,OAAA,EAAQ;AAER,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI,OAAO,mBAAmB,WAAA,EAAa;AACzC,MAAA,QAAA,GAAW,IAAI,eAAe,OAAO,CAAA;AACrC,MAAA,QAAA,CAAS,QAAQ,OAAO,CAAA;AAAA,IAC1B;AAEA,IAAA,QAAA,CAAS,OAAO,KAAA,CAAM,IAAA,CAAK,OAAO,CAAA,CAAE,MAAM,MAAM;AAAA,IAAC,CAAC,CAAA;AAElD,IAAA,OAAO,MAAM;AACX,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,QAAA,EAAU,UAAA,EAAW;AAAA,IACvB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,OAAO,CAAC,CAAA;AAErB,EAAA,OAAO,EAAE,GAAA,EAAK,UAAA,EAAY,SAAA,EAAU;AACtC;;;;"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect.es.js';
|
|
3
|
+
|
|
4
|
+
function useIsClamped({
|
|
5
|
+
enabled = true
|
|
6
|
+
} = {}) {
|
|
7
|
+
const [element, setElement] = useState(null);
|
|
8
|
+
const [isClamped, setIsClamped] = useState(false);
|
|
9
|
+
useIsomorphicLayoutEffect(() => {
|
|
10
|
+
if (!element || !enabled) return;
|
|
11
|
+
let stopped = false;
|
|
12
|
+
const measure = () => {
|
|
13
|
+
if (!stopped) setIsClamped(element.scrollHeight > element.clientHeight);
|
|
14
|
+
};
|
|
15
|
+
measure();
|
|
16
|
+
let observer;
|
|
17
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
18
|
+
observer = new ResizeObserver(measure);
|
|
19
|
+
observer.observe(element);
|
|
20
|
+
}
|
|
21
|
+
document.fonts?.ready.then(measure).catch(() => {
|
|
22
|
+
});
|
|
23
|
+
return () => {
|
|
24
|
+
stopped = true;
|
|
25
|
+
observer?.disconnect();
|
|
26
|
+
};
|
|
27
|
+
}, [element, enabled]);
|
|
28
|
+
return { ref: setElement, isClamped };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { useIsClamped };
|
|
32
|
+
//# sourceMappingURL=use-is-clamped.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-is-clamped.es.js","sources":["../../src/hooks/use-is-clamped.ts"],"sourcesContent":["import { useState } from 'react';\nimport type { RefCallback } from 'react';\n\nimport { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect';\n\nexport interface UseIsClampedOptions {\n /** Set false while the clamp is lifted (e.g. text expanded) to freeze the last measurement. */\n enabled?: boolean;\n}\n\nexport interface UseIsClampedResult<TElement extends HTMLElement> {\n ref: RefCallback<TElement>;\n isClamped: boolean;\n}\n\n/** Measures whether a clamped element has content cut off (`scrollHeight > clientHeight`), re-measuring on resize and font load. */\nexport function useIsClamped<TElement extends HTMLElement = HTMLElement>({\n enabled = true,\n}: UseIsClampedOptions = {}): UseIsClampedResult<TElement> {\n const [element, setElement] = useState<TElement | null>(null);\n const [isClamped, setIsClamped] = useState(false);\n\n useIsomorphicLayoutEffect(() => {\n if (!element || !enabled) return;\n\n let stopped = false;\n const measure = () => {\n if (!stopped) setIsClamped(element.scrollHeight > element.clientHeight);\n };\n\n measure();\n\n let observer: ResizeObserver | undefined;\n if (typeof ResizeObserver !== 'undefined') {\n observer = new ResizeObserver(measure);\n observer.observe(element);\n }\n // Font swaps change line wrapping without resizing the observed box.\n document.fonts?.ready.then(measure).catch(() => {});\n\n return () => {\n stopped = true;\n observer?.disconnect();\n };\n }, [element, enabled]);\n\n return { ref: setElement, isClamped };\n}\n"],"names":[],"mappings":";;;AAgBO,SAAS,YAAA,CAAyD;AAAA,EACvE,OAAA,GAAU;AACZ,CAAA,GAAyB,EAAC,EAAiC;AACzD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,SAA0B,IAAI,CAAA;AAC5D,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAEhD,EAAA,yBAAA,CAA0B,MAAM;AAC9B,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,OAAA,EAAS;AAE1B,IAAA,IAAI,OAAA,GAAU,KAAA;AACd,IAAA,MAAM,UAAU,MAAM;AACpB,MAAA,IAAI,CAAC,OAAA,EAAS,YAAA,CAAa,OAAA,CAAQ,YAAA,GAAe,QAAQ,YAAY,CAAA;AAAA,IACxE,CAAA;AAEA,IAAA,OAAA,EAAQ;AAER,IAAA,IAAI,QAAA;AACJ,IAAA,IAAI,OAAO,mBAAmB,WAAA,EAAa;AACzC,MAAA,QAAA,GAAW,IAAI,eAAe,OAAO,CAAA;AACrC,MAAA,QAAA,CAAS,QAAQ,OAAO,CAAA;AAAA,IAC1B;AAEA,IAAA,QAAA,CAAS,OAAO,KAAA,CAAM,IAAA,CAAK,OAAO,CAAA,CAAE,MAAM,MAAM;AAAA,IAAC,CAAC,CAAA;AAElD,IAAA,OAAO,MAAM;AACX,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,QAAA,EAAU,UAAA,EAAW;AAAA,IACvB,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,OAAA,EAAS,OAAO,CAAC,CAAA;AAErB,EAAA,OAAO,EAAE,GAAA,EAAK,UAAA,EAAY,SAAA,EAAU;AACtC;;;;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { TxtProps } from '../Txt';
|
|
2
|
+
declare const clampClasses: {
|
|
3
|
+
readonly 1: "line-clamp-1";
|
|
4
|
+
readonly 2: "line-clamp-2";
|
|
5
|
+
readonly 3: "line-clamp-3";
|
|
6
|
+
readonly 4: "line-clamp-4";
|
|
7
|
+
readonly 5: "line-clamp-5";
|
|
8
|
+
readonly 6: "line-clamp-6";
|
|
9
|
+
};
|
|
10
|
+
export type ClampedTextLines = keyof typeof clampClasses;
|
|
11
|
+
export interface ClampedTextProps extends Omit<TxtProps, 'children' | 'ref'> {
|
|
12
|
+
children: string;
|
|
13
|
+
/** Number of lines to clamp to (default: 2) */
|
|
14
|
+
lines?: ClampedTextLines;
|
|
15
|
+
readMoreLabel?: string;
|
|
16
|
+
showLessLabel?: string;
|
|
17
|
+
}
|
|
18
|
+
/** Text clamped to a number of lines, with a "read more" toggle shown only when the clamp actually cuts content. */
|
|
19
|
+
export declare function ClampedText({ children, lines, readMoreLabel, showLessLabel, className, ...txtProps }: ClampedTextProps): import("react").JSX.Element;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { ClampedText } from './clamped-text';
|
|
3
|
+
declare const meta: Meta<typeof ClampedText>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof ClampedText>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const ShortTextNoToggle: Story;
|
|
8
|
+
export declare const ThreeLines: Story;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './clamped-text';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { HTMLAttributes, ReactNode } from 'react';
|
|
1
|
+
import { HTMLAttributes, ReactNode, Ref } from 'react';
|
|
2
2
|
import { FontSizes } from '../../tokens';
|
|
3
3
|
export interface TxtProps extends HTMLAttributes<HTMLDivElement | HTMLLabelElement> {
|
|
4
4
|
as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'label' | 'div';
|
|
5
|
+
ref?: Ref<HTMLElement>;
|
|
5
6
|
variant?: keyof typeof FontSizes;
|
|
6
7
|
font?: 'mono';
|
|
7
8
|
htmlFor?: string;
|
|
@@ -9,4 +10,4 @@ export interface TxtProps extends HTMLAttributes<HTMLDivElement | HTMLLabelEleme
|
|
|
9
10
|
title?: string;
|
|
10
11
|
children?: ReactNode;
|
|
11
12
|
}
|
|
12
|
-
export declare const Txt: ({ as: Root, className, variant, font, ...props }: TxtProps) => import("react").JSX.Element;
|
|
13
|
+
export declare const Txt: ({ as: Root, className, variant, font, ref, ...props }: TxtProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RefCallback } from 'react';
|
|
2
|
+
export interface UseIsClampedOptions {
|
|
3
|
+
/** Set false while the clamp is lifted (e.g. text expanded) to freeze the last measurement. */
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface UseIsClampedResult<TElement extends HTMLElement> {
|
|
7
|
+
ref: RefCallback<TElement>;
|
|
8
|
+
isClamped: boolean;
|
|
9
|
+
}
|
|
10
|
+
/** Measures whether a clamped element has content cut off (`scrollHeight > clientHeight`), re-measuring on resize and font load. */
|
|
11
|
+
export declare function useIsClamped<TElement extends HTMLElement = HTMLElement>({ enabled, }?: UseIsClampedOptions): UseIsClampedResult<TElement>;
|
package/dist/style.css
CHANGED
|
@@ -1162,6 +1162,10 @@
|
|
|
1162
1162
|
margin-left: calc(var(--spacing-5) * -1);
|
|
1163
1163
|
}
|
|
1164
1164
|
|
|
1165
|
+
.-ml-\[\.8em\] {
|
|
1166
|
+
margin-left: -.8em;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1165
1169
|
.-ml-px {
|
|
1166
1170
|
margin-left: -1px;
|
|
1167
1171
|
margin-left: calc(var(--spacing-px) * -1);
|
|
@@ -1203,6 +1207,13 @@
|
|
|
1203
1207
|
box-sizing: border-box;
|
|
1204
1208
|
}
|
|
1205
1209
|
|
|
1210
|
+
.line-clamp-1 {
|
|
1211
|
+
-webkit-line-clamp: 1;
|
|
1212
|
+
-webkit-box-orient: vertical;
|
|
1213
|
+
display: -webkit-box;
|
|
1214
|
+
overflow: hidden;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1206
1217
|
.line-clamp-2 {
|
|
1207
1218
|
-webkit-line-clamp: 2;
|
|
1208
1219
|
-webkit-box-orient: vertical;
|
|
@@ -1217,6 +1228,27 @@
|
|
|
1217
1228
|
overflow: hidden;
|
|
1218
1229
|
}
|
|
1219
1230
|
|
|
1231
|
+
.line-clamp-4 {
|
|
1232
|
+
-webkit-line-clamp: 4;
|
|
1233
|
+
-webkit-box-orient: vertical;
|
|
1234
|
+
display: -webkit-box;
|
|
1235
|
+
overflow: hidden;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
.line-clamp-5 {
|
|
1239
|
+
-webkit-line-clamp: 5;
|
|
1240
|
+
-webkit-box-orient: vertical;
|
|
1241
|
+
display: -webkit-box;
|
|
1242
|
+
overflow: hidden;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
.line-clamp-6 {
|
|
1246
|
+
-webkit-line-clamp: 6;
|
|
1247
|
+
-webkit-box-orient: vertical;
|
|
1248
|
+
display: -webkit-box;
|
|
1249
|
+
overflow: hidden;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1220
1252
|
.block {
|
|
1221
1253
|
display: block;
|
|
1222
1254
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/playground-ui",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "42.0.0-alpha.4",
|
|
5
5
|
"description": "Mastra Playground components",
|
|
6
6
|
"sideEffects": [
|
|
7
7
|
"**/*.css"
|
|
@@ -150,8 +150,8 @@
|
|
|
150
150
|
"react": ">=19.0.0",
|
|
151
151
|
"react-dom": ">=19.0.0",
|
|
152
152
|
"tailwindcss": "^4.0.0",
|
|
153
|
-
"@mastra/client-js": "^1.
|
|
154
|
-
"@mastra/react": "1.2.6-alpha.
|
|
153
|
+
"@mastra/client-js": "^1.33.0-alpha.4",
|
|
154
|
+
"@mastra/react": "1.2.6-alpha.4"
|
|
155
155
|
},
|
|
156
156
|
"devDependencies": {
|
|
157
157
|
"@storybook/addon-a11y": "^10.4.1",
|
|
@@ -190,10 +190,10 @@
|
|
|
190
190
|
"vite-plugin-lib-inject-css": "^2.2.2",
|
|
191
191
|
"vitest": "4.1.10",
|
|
192
192
|
"@internal/lint": "0.0.114",
|
|
193
|
-
"@mastra/
|
|
194
|
-
"@mastra/client-js": "^1.32.1-alpha.2",
|
|
193
|
+
"@mastra/client-js": "^1.33.0-alpha.4",
|
|
195
194
|
"@mastra/memory": "1.23.1-alpha.0",
|
|
196
|
-
"@mastra/
|
|
195
|
+
"@mastra/core": "1.52.0-alpha.4",
|
|
196
|
+
"@mastra/react": "1.2.6-alpha.4"
|
|
197
197
|
},
|
|
198
198
|
"homepage": "https://mastra.ai",
|
|
199
199
|
"repository": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Txt-BT8_EkuZ.cjs","sources":["../src/ds/components/Txt/Txt.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from 'react';\n\nimport type { FontSizes } from '../../tokens';\nimport { cn } from '@/lib/utils';\n\nexport interface TxtProps extends HTMLAttributes<HTMLDivElement | HTMLLabelElement> {\n as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'label' | 'div';\n variant?: keyof typeof FontSizes;\n font?: 'mono';\n htmlFor?: string;\n className?: string;\n title?: string;\n children?: ReactNode;\n}\n\nconst variants = {\n // UI text sizes\n 'ui-xs': 'text-ui-xs leading-ui-xs',\n 'ui-sm': 'text-ui-sm leading-ui-sm',\n 'ui-smd': 'text-ui-smd leading-ui-smd',\n 'ui-md': 'text-ui-md leading-ui-md',\n 'ui-lg': 'text-ui-lg leading-ui-lg',\n // Header sizes\n 'header-xs': 'text-header-xs leading-header-xs',\n 'header-sm': 'text-header-sm leading-header-sm',\n 'header-md': 'text-header-md leading-header-md',\n 'header-lg': 'text-header-lg leading-header-lg',\n 'header-xl': 'text-header-xl leading-header-xl',\n};\n\nconst fonts = {\n mono: 'font-mono',\n};\n\nexport const Txt = ({ as: Root = 'p', className, variant = 'ui-md', font, ...props }: TxtProps) => {\n return <Root className={cn(variants[variant], font && fonts[font], className)} {...props} />;\n};\n"],"names":["jsx","cn"],"mappings":";;;;;AAeA,MAAM,QAAA,GAAW;AAAA;AAAA,EAEf,OAAA,EAAS,0BAAA;AAAA,EACT,OAAA,EAAS,0BAAA;AAAA,EACT,QAAA,EAAU,4BAAA;AAAA,EACV,OAAA,EAAS,0BAAA;AAAA,EACT,OAAA,EAAS,0BAAA;AAAA;AAAA,EAET,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa;AACf,CAAA;AAEA,MAAM,KAAA,GAAQ;AAAA,EACZ,IAAA,EAAM;AACR,CAAA;AAEO,MAAM,GAAA,GAAM,CAAC,EAAE,EAAA,EAAI,IAAA,GAAO,GAAA,EAAK,SAAA,EAAW,OAAA,GAAU,OAAA,EAAS,IAAA,EAAM,GAAG,KAAA,EAAM,KAAgB;AACjG,EAAA,uBAAOA,cAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAWC,WAAA,CAAG,SAAS,OAAO,CAAA,EAAG,IAAA,IAAQ,KAAA,CAAM,IAAI,CAAA,EAAG,SAAS,CAAA,EAAI,GAAG,KAAA,EAAO,CAAA;AAC5F;;;;"}
|
package/dist/Txt-p33XTnu8.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Txt-p33XTnu8.js","sources":["../src/ds/components/Txt/Txt.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from 'react';\n\nimport type { FontSizes } from '../../tokens';\nimport { cn } from '@/lib/utils';\n\nexport interface TxtProps extends HTMLAttributes<HTMLDivElement | HTMLLabelElement> {\n as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'label' | 'div';\n variant?: keyof typeof FontSizes;\n font?: 'mono';\n htmlFor?: string;\n className?: string;\n title?: string;\n children?: ReactNode;\n}\n\nconst variants = {\n // UI text sizes\n 'ui-xs': 'text-ui-xs leading-ui-xs',\n 'ui-sm': 'text-ui-sm leading-ui-sm',\n 'ui-smd': 'text-ui-smd leading-ui-smd',\n 'ui-md': 'text-ui-md leading-ui-md',\n 'ui-lg': 'text-ui-lg leading-ui-lg',\n // Header sizes\n 'header-xs': 'text-header-xs leading-header-xs',\n 'header-sm': 'text-header-sm leading-header-sm',\n 'header-md': 'text-header-md leading-header-md',\n 'header-lg': 'text-header-lg leading-header-lg',\n 'header-xl': 'text-header-xl leading-header-xl',\n};\n\nconst fonts = {\n mono: 'font-mono',\n};\n\nexport const Txt = ({ as: Root = 'p', className, variant = 'ui-md', font, ...props }: TxtProps) => {\n return <Root className={cn(variants[variant], font && fonts[font], className)} {...props} />;\n};\n"],"names":[],"mappings":";;;AAeA,MAAM,QAAA,GAAW;AAAA;AAAA,EAEf,OAAA,EAAS,0BAAA;AAAA,EACT,OAAA,EAAS,0BAAA;AAAA,EACT,QAAA,EAAU,4BAAA;AAAA,EACV,OAAA,EAAS,0BAAA;AAAA,EACT,OAAA,EAAS,0BAAA;AAAA;AAAA,EAET,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa,kCAAA;AAAA,EACb,WAAA,EAAa;AACf,CAAA;AAEA,MAAM,KAAA,GAAQ;AAAA,EACZ,IAAA,EAAM;AACR,CAAA;AAEO,MAAM,GAAA,GAAM,CAAC,EAAE,EAAA,EAAI,IAAA,GAAO,GAAA,EAAK,SAAA,EAAW,OAAA,GAAU,OAAA,EAAS,IAAA,EAAM,GAAG,KAAA,EAAM,KAAgB;AACjG,EAAA,uBAAO,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAW,EAAA,CAAG,SAAS,OAAO,CAAA,EAAG,IAAA,IAAQ,KAAA,CAAM,IAAI,CAAA,EAAG,SAAS,CAAA,EAAI,GAAG,KAAA,EAAO,CAAA;AAC5F;;;;"}
|