@bioturing/components 0.22.0 → 0.24.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/components/button/style.css +1 -1
- package/dist/components/drag-drop/draggable.js +7 -1
- package/dist/components/drag-drop/draggable.js.map +1 -1
- package/dist/components/drag-drop/droppable.js +58 -50
- package/dist/components/drag-drop/droppable.js.map +1 -1
- package/dist/components/drag-drop/style.css +1 -1
- package/dist/components/drag-drop/value.js +91 -67
- package/dist/components/drag-drop/value.js.map +1 -1
- package/dist/components/form/component.js +6 -4
- package/dist/components/form/component.js.map +1 -1
- package/dist/components/form/item.js +23 -38
- package/dist/components/form/item.js.map +1 -1
- package/dist/components/form/label.js +49 -0
- package/dist/components/form/label.js.map +1 -0
- package/dist/components/icon-button/component.js.map +1 -1
- package/dist/components/icon-button/style.css +1 -1
- package/dist/components/input/component.js +65 -21
- package/dist/components/input/component.js.map +1 -1
- package/dist/components/input/style.css +1 -0
- package/dist/components/modal/style.css +1 -1
- package/dist/components/popup-panel/component.js +63 -63
- package/dist/components/popup-panel/component.js.map +1 -1
- package/dist/components/spin/component.js +16 -6
- package/dist/components/spin/component.js.map +1 -1
- package/dist/components/spin/style.css +1 -1
- package/dist/components/tag/component.js.map +1 -1
- package/dist/components/tag/style.css +1 -1
- package/dist/components/truncate/component.js +87 -72
- package/dist/components/truncate/component.js.map +1 -1
- package/dist/components/truncate/helpers.js +44 -24
- package/dist/components/truncate/helpers.js.map +1 -1
- package/dist/components/truncate/style.css +1 -1
- package/dist/index.d.ts +41 -17
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer components{:root{--ds-animate-spin: ds-spin 1s linear infinite}@keyframes ds-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.ds-spin .ds-spin-icon{animation:var(--ds-animate-spin);color:var(--ds-color-icon)}.ds-spin .ds-spin-text{color:var(--ds-color-icon)}.ds-spin-loader{width:1em;height:1em;border:max(2px,.12em) solid var(--ds-color-border);border-bottom-color:var(--ds-color-icon);border-radius:50%;display:inline-block;box-sizing:border-box;animation:spin 1s linear infinite}}
|
|
1
|
+
@layer components{:root{--ds-animate-spin: ds-spin 1s linear infinite}@keyframes ds-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.ds-spin .ds-spin-icon{animation:var(--ds-animate-spin);color:var(--ds-color-icon)}.ds-spin .ds-spin-text{color:var(--ds-color-icon)}.ds-spin-loader{width:var(--spin-size, 1em);height:var(--spin-size, 1em);border:max(2px,.12em) solid var(--ds-color-border);border-bottom-color:var(--ds-color-icon);border-radius:50%;display:inline-block;box-sizing:border-box;animation:spin 1s linear infinite}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.js","sources":["../../../src/components/tag/component.tsx"],"sourcesContent":["\"use client\";\nimport {\n forwardRef,\n cloneElement,\n isValidElement,\n
|
|
1
|
+
{"version":3,"file":"component.js","sources":["../../../src/components/tag/component.tsx"],"sourcesContent":["\"use client\";\nimport {\n forwardRef,\n cloneElement,\n isValidElement,\n HTMLAttributes,\n} from \"react\";\nimport { XIcon } from \"@bioturing/assets\";\nimport AntTag, {\n type TagProps as AntTagProps,\n type TagType,\n} from \"antd/es/tag\";\nimport AntCheckableTag, {\n type CheckableTagProps as AntCheckableTagProps,\n} from \"antd/es/tag/CheckableTag\";\nimport { clsx, useCls } from \"../utils\";\n\n// Import component-specific styles\nimport \"./style.css\";\n\nexport { TagType };\n\n// Define props interface extending Ant Design's TagProps\nexport interface TagProps extends AntTagProps {\n /**\n * Indicates if the tag is active\n * @default false\n */\n active?: boolean;\n /**\n * Size of the tag\n * @default \"small\"\n */\n size?: \"small\" | \"medium\" | \"large\";\n}\n\nexport interface CheckableTagProps extends AntCheckableTagProps {\n size?: \"small\" | \"medium\" | \"large\";\n}\n\n// Create Tag component\nconst InternalTag = forwardRef<HTMLSpanElement, TagProps>(\n (\n {\n className,\n active = false,\n color,\n style,\n closeIcon,\n closable,\n size = \"small\",\n children,\n icon,\n ...rest\n },\n ref,\n ) => {\n const renderedCloseIcon = <XIcon weight=\"bold\" />;\n const cls = useCls();\n const renderedIcon = isValidElement(icon)\n ? cloneElement<HTMLAttributes<SVGElement>>(icon, {\n className: clsx(\n cls(\"tag-icon\"),\n icon.props &&\n typeof icon.props === \"object\" &&\n \"className\" in icon.props &&\n typeof icon.props.className === \"string\"\n ? icon.props.className\n : \"\",\n ),\n })\n : icon;\n return (\n <AntTag\n ref={ref}\n className={clsx(\n cls(\"tag\"),\n cls(`tag-${size}`),\n !children && cls(\"tag-empty\"),\n className,\n )}\n color={color}\n style={style}\n closable={closable}\n closeIcon={closable ? closeIcon || renderedCloseIcon : undefined}\n icon={renderedIcon}\n {...(active ? { \"data-active\": \"true\" } : {})}\n {...rest}\n >\n {children}\n </AntTag>\n );\n },\n);\n\nconst CheckableTag = forwardRef<HTMLSpanElement, CheckableTagProps>(\n ({ className, size = \"small\", children, ...rest }, ref) => {\n const cls = useCls();\n return (\n <AntCheckableTag\n ref={ref}\n className={clsx(\n cls(\"tag\"),\n cls(`tag-${size}`),\n !children && cls(\"tag-empty\"),\n className,\n )}\n {...rest}\n >\n {children}\n </AntCheckableTag>\n );\n },\n);\n\nexport const Tag = Object.assign(InternalTag, {\n CheckableTag,\n});\n"],"names":["InternalTag","forwardRef","className","active","color","style","closeIcon","closable","size","children","icon","rest","ref","renderedCloseIcon","jsx","XIcon","cls","useCls","renderedIcon","isValidElement","cloneElement","clsx","AntTag","CheckableTag","AntCheckableTag","Tag"],"mappings":";;;;;;;;;AAyCA,MAAMA,IAAcC;AAAA,EAClB,CACE;AAAA,IACE,WAAAC;AAAA,IACA,QAAAC,IAAS;AAAA,IACT,OAAAC;AAAA,IACA,OAAAC;AAAA,IACA,WAAAC;AAAA,IACA,UAAAC;AAAA,IACA,MAAAC,IAAO;AAAA,IACP,UAAAC;AAAA,IACA,MAAAC;AAAA,IACA,GAAGC;AAAA,KAELC,MACG;AACH,UAAMC,IAAoB,gBAAAC,EAACC,GAAM,EAAA,QAAO,OAAO,CAAA,GACzCC,IAAMC,EAAO,GACbC,IAAeC,EAAeT,CAAI,IACpCU,EAAyCV,GAAM;AAAA,MAC7C,WAAWW;AAAA,QACTL,EAAI,UAAU;AAAA,QACdN,EAAK,SACH,OAAOA,EAAK,SAAU,YACtB,eAAeA,EAAK,SACpB,OAAOA,EAAK,MAAM,aAAc,WAC9BA,EAAK,MAAM,YACX;AAAA,MAAA;AAAA,IAEP,CAAA,IACDA;AAEF,WAAA,gBAAAI;AAAA,MAACQ;AAAA,MAAA;AAAA,QACC,KAAAV;AAAA,QACA,WAAWS;AAAA,UACTL,EAAI,KAAK;AAAA,UACTA,EAAI,OAAOR,CAAI,EAAE;AAAA,UACjB,CAACC,KAAYO,EAAI,WAAW;AAAA,UAC5Bd;AAAA,QACF;AAAA,QACA,OAAAE;AAAA,QACA,OAAAC;AAAA,QACA,UAAAE;AAAA,QACA,WAAWA,IAAWD,KAAaO,IAAoB;AAAA,QACvD,MAAMK;AAAA,QACL,GAAIf,IAAS,EAAE,eAAe,WAAW,CAAC;AAAA,QAC1C,GAAGQ;AAAA,QAEH,UAAAF;AAAA,MAAA;AAAA,IACH;AAAA,EAAA;AAGN,GAEMc,IAAetB;AAAA,EACnB,CAAC,EAAE,WAAAC,GAAW,MAAAM,IAAO,SAAS,UAAAC,GAAU,GAAGE,EAAK,GAAGC,MAAQ;AACzD,UAAMI,IAAMC,EAAO;AAEjB,WAAA,gBAAAH;AAAA,MAACU;AAAA,MAAA;AAAA,QACC,KAAAZ;AAAA,QACA,WAAWS;AAAA,UACTL,EAAI,KAAK;AAAA,UACTA,EAAI,OAAOR,CAAI,EAAE;AAAA,UACjB,CAACC,KAAYO,EAAI,WAAW;AAAA,UAC5Bd;AAAA,QACF;AAAA,QACC,GAAGS;AAAA,QAEH,UAAAF;AAAA,MAAA;AAAA,IACH;AAAA,EAAA;AAGN,GAEagB,IAAM,OAAO,OAAOzB,GAAa;AAAA,EAC5C,cAAAuB;AACF,CAAC;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer components{.ds-tag{display:inline-flex;align-items:center;font-size:var(--ds-font-size-sm);padding:.0625rem .4375rem}.ds-tag[data-active]{background-color:var(--ds-color-primary-bg);border-color:var(--ds-color-primary);color:var(--ds-color-primary)}.ds-tag .ds-tag-close-icon{color:var(--ds-color-icon)}.ds-tag.ds-tag-medium{padding:.1875rem .4375rem}.ds-tag.ds-tag-large{font-size:var(--ds-font-size);padding:.1875rem .4375rem}.ds-tag:is(.ds-tag-magenta,.ds-tag-red,.ds-tag-volcano,.ds-tag-orange,.ds-tag-gold,.ds-tag-lime,.ds-tag-green,.ds-tag-cyan,.ds-tag-blue,.ds-tag-geekblue,.ds-tag-purple) .ds-tag-close-icon{color:currentColor}.ds-tag.ds-tag-empty .ds-tag-close-icon{margin-left:0}.ds-tag .ds-tag-icon{margin-right:.25rem}}
|
|
1
|
+
@layer components{.ds-tag{display:inline-flex;align-items:center;font-size:var(--ds-font-size-sm);padding:.0625rem .4375rem}.ds-tag[data-active]{background-color:var(--ds-color-primary-bg);border-color:var(--ds-color-primary);color:var(--ds-color-primary)}.ds-tag .ds-tag-close-icon{color:var(--ds-color-icon)}.ds-tag.ds-tag-medium{padding:.1875rem .4375rem}.ds-tag.ds-tag-large{font-size:var(--ds-font-size);padding:.1875rem .4375rem}.ds-tag:is(.ds-tag-magenta,.ds-tag-red,.ds-tag-volcano,.ds-tag-orange,.ds-tag-gold,.ds-tag-lime,.ds-tag-green,.ds-tag-cyan,.ds-tag-blue,.ds-tag-geekblue,.ds-tag-purple) .ds-tag-close-icon{color:currentColor}.ds-tag.ds-tag-empty .ds-tag-close-icon{margin-left:0}.ds-tag .ds-tag-icon{margin-right:.25rem}.ds-tag>span:not(.ds-tag-icon,.ds-tag-close-icon){flex-shrink:1;min-height:0;min-width:0;flex-grow:1;flex-basis:max-content}}
|
|
@@ -1,94 +1,109 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as
|
|
3
|
-
import { useRef as
|
|
4
|
-
import { getMiddleTruncatedString as
|
|
2
|
+
import { jsx as y } from "react/jsx-runtime";
|
|
3
|
+
import { useRef as k, useState as M, useCallback as g, useLayoutEffect as z } from "react";
|
|
4
|
+
import { calculateAvailableHeight as A, checkIfTextTruncated as b, getMiddleTruncatedString as F } from "./helpers.js";
|
|
5
5
|
import './style.css';/* empty css */
|
|
6
|
-
import { useCls as
|
|
7
|
-
import { clsx as
|
|
8
|
-
const
|
|
9
|
-
children:
|
|
10
|
-
position:
|
|
6
|
+
import { useCls as O } from "../utils/antdUtils.js";
|
|
7
|
+
import { clsx as R } from "../utils/cn.js";
|
|
8
|
+
const D = ({
|
|
9
|
+
children: x,
|
|
10
|
+
position: f = "end",
|
|
11
11
|
lines: r = 1,
|
|
12
|
-
className:
|
|
13
|
-
style:
|
|
14
|
-
|
|
12
|
+
className: C,
|
|
13
|
+
style: m,
|
|
14
|
+
container: l,
|
|
15
|
+
...E
|
|
15
16
|
}) => {
|
|
16
|
-
const
|
|
17
|
-
...
|
|
17
|
+
const d = O(), h = k(null), [S, T] = M(!1), [p, v] = M(x), c = x, H = g(() => r !== "auto" ? {
|
|
18
|
+
...m,
|
|
18
19
|
...r > 1 ? { "--ds-line-clamp": r } : {}
|
|
19
20
|
} : {
|
|
20
|
-
...
|
|
21
|
+
...m,
|
|
21
22
|
// Set a temporary high value to ensure it fits the parent
|
|
22
23
|
"--ds-line-clamp": 999
|
|
23
|
-
}, [r,
|
|
24
|
-
|
|
25
|
-
var v, T, H, x, C, S;
|
|
26
|
-
const e = y.current;
|
|
24
|
+
}, [r, m]), w = g(() => {
|
|
25
|
+
const e = h.current;
|
|
27
26
|
if (!e) return;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
(T = (v = window.document.fonts) == null ? void 0 : v.ready) == null || T.then(i);
|
|
41
|
-
const c = new ResizeObserver(() => {
|
|
42
|
-
window.requestAnimationFrame(i);
|
|
27
|
+
const t = window.getComputedStyle(e), u = parseFloat(t.fontSize), n = t.lineHeight === "normal" ? u * 1.2 : parseFloat(t.lineHeight), a = A(e), o = Math.max(1, Math.floor(a / n));
|
|
28
|
+
e.style.setProperty("--ds-line-clamp", String(o));
|
|
29
|
+
const i = b(c, e, a);
|
|
30
|
+
T(i);
|
|
31
|
+
}, [c]), s = g(
|
|
32
|
+
(e, t, u) => {
|
|
33
|
+
var o, i;
|
|
34
|
+
const n = e.filter(Boolean);
|
|
35
|
+
if (n.length === 0) return;
|
|
36
|
+
(i = (o = window.document.fonts) == null ? void 0 : o.ready) == null || i.then(t);
|
|
37
|
+
const a = new ResizeObserver(() => {
|
|
38
|
+
window.requestAnimationFrame(t);
|
|
43
39
|
});
|
|
44
|
-
return
|
|
45
|
-
|
|
46
|
-
if (typeof r == "number" && r > 1) {
|
|
47
|
-
d(n);
|
|
48
|
-
const i = () => {
|
|
49
|
-
const t = document.createElement("span");
|
|
50
|
-
t.style.visibility = "hidden", t.style.position = "absolute", t.style.width = `${e.clientWidth}px`, t.textContent = n, document.body.appendChild(t);
|
|
51
|
-
const s = t.scrollHeight > (e.clientHeight || e.offsetHeight);
|
|
52
|
-
document.body.removeChild(t), p(s);
|
|
40
|
+
return n.forEach((L) => a.observe(L)), () => {
|
|
41
|
+
a.disconnect(), u && u();
|
|
53
42
|
};
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
43
|
+
},
|
|
44
|
+
[]
|
|
45
|
+
);
|
|
46
|
+
return z(() => {
|
|
47
|
+
const e = h.current;
|
|
48
|
+
let t = l instanceof HTMLElement ? l : l && "current" in l ? l.current : null;
|
|
49
|
+
if (!e || (t || (t = e.closest("[data-truncate-container]")), typeof l < "u" && !t)) return;
|
|
50
|
+
if (v(c), r === "auto")
|
|
51
|
+
return s(
|
|
52
|
+
[e, e.parentElement],
|
|
53
|
+
w
|
|
54
|
+
);
|
|
55
|
+
if (typeof r == "number" && r > 1)
|
|
56
|
+
return s([e], () => {
|
|
57
|
+
const a = b(c, e);
|
|
58
|
+
T(a);
|
|
57
59
|
});
|
|
58
|
-
|
|
60
|
+
if (f == "middle") {
|
|
61
|
+
let n = { cancelled: !1 };
|
|
62
|
+
return s(
|
|
63
|
+
[t || e],
|
|
64
|
+
() => {
|
|
65
|
+
n && (n.cancelled = !0);
|
|
66
|
+
const o = { cancelled: !1 };
|
|
67
|
+
n = o;
|
|
68
|
+
const i = F(c, "…", e);
|
|
69
|
+
o.cancelled || v(i);
|
|
70
|
+
},
|
|
71
|
+
() => {
|
|
72
|
+
n.cancelled = !0;
|
|
73
|
+
}
|
|
74
|
+
);
|
|
59
75
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
};
|
|
75
|
-
}, [n, a, r]), /* @__PURE__ */ W(
|
|
76
|
+
return s(
|
|
77
|
+
[t || e],
|
|
78
|
+
() => {
|
|
79
|
+
e.scrollWidth > e.clientWidth && T(!0);
|
|
80
|
+
}
|
|
81
|
+
);
|
|
82
|
+
}, [
|
|
83
|
+
c,
|
|
84
|
+
f,
|
|
85
|
+
r,
|
|
86
|
+
l,
|
|
87
|
+
w,
|
|
88
|
+
s
|
|
89
|
+
]), /* @__PURE__ */ y(
|
|
76
90
|
"span",
|
|
77
91
|
{
|
|
78
|
-
ref:
|
|
79
|
-
style:
|
|
80
|
-
className:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
92
|
+
ref: h,
|
|
93
|
+
style: H(),
|
|
94
|
+
className: R(
|
|
95
|
+
d(r === 1 ? "truncate" : "truncate-multiline"),
|
|
96
|
+
d(f === "middle" ? "truncate-middle" : "truncate-end"),
|
|
97
|
+
C
|
|
84
98
|
),
|
|
85
|
-
title:
|
|
86
|
-
|
|
87
|
-
|
|
99
|
+
title: S ? c : void 0,
|
|
100
|
+
"data-truncate-text-node": !0,
|
|
101
|
+
...E,
|
|
102
|
+
children: c === p ? c : /* @__PURE__ */ y("span", { children: p })
|
|
88
103
|
}
|
|
89
104
|
);
|
|
90
105
|
};
|
|
91
106
|
export {
|
|
92
|
-
|
|
107
|
+
D as Truncate
|
|
93
108
|
};
|
|
94
109
|
//# sourceMappingURL=component.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.js","sources":["../../../src/components/truncate/component.tsx"],"sourcesContent":["\"use client\";\nimport React, { useCallback, useLayoutEffect, useRef, useState } from \"react\";\nimport { clsx, useCls } from \"../utils\";\nimport { getMiddleTruncatedString } from \"./helpers\";\n\nimport \"./style.css\";\n\nexport type TruncatePosition = \"middle\" | \"end\";\n\nexport type Props = {\n text: string;\n} & React.CSSProperties;\n\nexport interface TruncateProps\n extends Omit<React.ComponentPropsWithoutRef<\"span\">, \"title\"> {\n /** Text content to be truncated */\n children: string;\n /** Where to truncate the text: start, middle, or end */\n position?: TruncatePosition;\n /** Number of lines to display before truncating (default: 1, 'auto' to fit parent height) */\n lines?: number | \"auto\";\n}\n\nexport const Truncate: React.FC<TruncateProps> = ({\n children,\n position = \"end\",\n lines = 1,\n className,\n style,\n ...rest\n}) => {\n const cls = useCls();\n const containerRef = useRef<HTMLElement>(null);\n const [isTruncated, setIsTruncated] = useState(false);\n const [truncatedText, setTruncatedText] = useState(children);\n\n const text = children;\n\n // Get appropriate container styles based on position and lines\n const getContainerStyles = useCallback(() => {\n // For explicit line numbers or single line\n if (lines !== \"auto\") {\n return {\n ...style,\n ...(lines > 1 ? { \"--ds-line-clamp\": lines } : {}),\n } as React.CSSProperties;\n }\n\n // For auto line calculation, we'll let the useLayoutEffect handle it\n return {\n ...style,\n // Set a temporary high value to ensure it fits the parent\n \"--ds-line-clamp\": 999,\n } as React.CSSProperties;\n }, [lines, style]);\n\n useLayoutEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n // Handle auto-height calculation\n if (lines === \"auto\") {\n setTruncatedText(text);\n\n const calculateLines = () => {\n // Get the parent element's height\n const parent = container.parentElement;\n if (!parent) return;\n\n // Calculate the font size and line height\n const styles = window.getComputedStyle(container);\n const fontSize = parseFloat(styles.fontSize);\n const lineHeight =\n styles.lineHeight === \"normal\"\n ? fontSize * 1.2 // Approximate for \"normal\"\n : parseFloat(styles.lineHeight);\n\n // Get parent's padding and border to subtract from available height\n const parentStyles = window.getComputedStyle(parent);\n const paddingTop = parseFloat(parentStyles.paddingTop) || 0;\n const paddingBottom = parseFloat(parentStyles.paddingBottom) || 0;\n const borderTopWidth = parseFloat(parentStyles.borderTopWidth) || 0;\n const borderBottomWidth =\n parseFloat(parentStyles.borderBottomWidth) || 0;\n\n // Calculate how many lines can fit in the available space\n const parentHeight = parent.clientHeight;\n const availableHeight =\n parentHeight -\n paddingTop -\n paddingBottom -\n borderTopWidth -\n borderBottomWidth;\n const maxLines = Math.max(1, Math.floor(availableHeight / lineHeight));\n\n // Apply the calculated line-clamp\n if (container) {\n container.style.setProperty(\"--ds-line-clamp\", String(maxLines));\n }\n\n // Check if the text is truncated\n const clone = document.createElement(\"span\");\n clone.style.visibility = \"hidden\";\n clone.style.position = \"absolute\";\n clone.style.width = `${container.clientWidth}px`;\n clone.style.fontSize = styles.fontSize;\n clone.style.fontFamily = styles.fontFamily;\n clone.style.lineHeight = styles.lineHeight;\n clone.textContent = text;\n document.body.appendChild(clone);\n\n const isTruncated = clone.scrollHeight > availableHeight;\n document.body.removeChild(clone);\n\n setIsTruncated(isTruncated);\n };\n\n window.document.fonts?.ready?.then(calculateLines);\n const observer = new ResizeObserver(() => {\n window.requestAnimationFrame(calculateLines);\n });\n\n observer.observe(container);\n if (container.parentElement) {\n observer.observe(container.parentElement);\n }\n\n return () => observer.disconnect();\n }\n\n // Skip custom truncation logic for multi-line mode\n if (typeof lines === \"number\" && lines > 1) {\n setTruncatedText(text);\n // Check if text is truncated by comparing heights\n const checkIfTruncated = () => {\n const clone = document.createElement(\"span\");\n clone.style.visibility = \"hidden\";\n clone.style.position = \"absolute\";\n clone.style.width = `${container.clientWidth}px`;\n clone.textContent = text;\n document.body.appendChild(clone);\n const isTruncated =\n clone.scrollHeight >\n (container.clientHeight || container.offsetHeight);\n document.body.removeChild(clone);\n setIsTruncated(isTruncated);\n };\n\n window.document.fonts?.ready?.then(checkIfTruncated);\n const observer = new ResizeObserver(() => {\n window.requestAnimationFrame(checkIfTruncated);\n });\n\n observer.observe(container);\n return () => observer.disconnect();\n }\n\n // Original single-line truncation logic\n let cancellationToken = { cancelled: false };\n\n const calculateTruncatedString = () => {\n if (cancellationToken) cancellationToken.cancelled = true;\n\n const requestCancellationToken = { cancelled: false };\n cancellationToken = requestCancellationToken;\n\n const truncated = getMiddleTruncatedString(text, \"\\u2026\", container);\n\n if (requestCancellationToken.cancelled) return;\n\n setTruncatedText(truncated);\n };\n\n if (position == \"middle\") {\n window.document.fonts?.ready?.then(calculateTruncatedString);\n }\n\n if (position == \"end\") {\n setTruncatedText(text);\n }\n\n const observer = new ResizeObserver(() => {\n if (position == \"middle\")\n window.requestAnimationFrame(calculateTruncatedString);\n if (position == \"end\") {\n const isOverflowing = container.scrollWidth > container.clientWidth;\n if (isOverflowing) {\n setIsTruncated(true);\n }\n }\n });\n\n observer.observe(container);\n\n return () => {\n cancellationToken.cancelled = true;\n observer.disconnect();\n };\n }, [text, position, lines]);\n\n return (\n <span\n ref={containerRef}\n style={getContainerStyles()}\n className={clsx(\n lines === 1 ? cls(\"truncate\") : cls(\"truncate-multiline\"),\n position === \"middle\" ? cls(\"truncate-middle\") : cls(\"truncate-end\"),\n className\n )}\n title={isTruncated ? text : undefined}\n {...rest}\n >\n {text === truncatedText ? text : <span>{truncatedText}</span>}\n </span>\n );\n};\n"],"names":["Truncate","children","position","lines","className","style","rest","cls","useCls","containerRef","useRef","isTruncated","setIsTruncated","useState","truncatedText","setTruncatedText","text","getContainerStyles","useCallback","useLayoutEffect","container","calculateLines","parent","styles","fontSize","lineHeight","parentStyles","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth","availableHeight","maxLines","clone","_b","_a","observer","checkIfTruncated","_d","_c","cancellationToken","calculateTruncatedString","requestCancellationToken","truncated","getMiddleTruncatedString","_f","_e","jsx","clsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"component.js","sources":["../../../src/components/truncate/component.tsx"],"sourcesContent":["\"use client\";\nimport React, { useCallback, useLayoutEffect, useRef, useState } from \"react\";\nimport { clsx, useCls } from \"../utils\";\nimport {\n calculateAvailableHeight,\n checkIfTextTruncated,\n getMiddleTruncatedString,\n} from \"./helpers\";\n\nimport \"./style.css\";\n\nexport type TruncatePosition = \"middle\" | \"end\";\n\nexport interface TruncateProps\n extends Omit<React.ComponentPropsWithoutRef<\"span\">, \"title\"> {\n /** Text content to be truncated */\n children: string;\n /** Position where the truncation should occur */\n position?: TruncatePosition;\n /**\n * Number of lines to display before truncating\n * @default 1\n * @remarks Use 'auto' to fit parent height\n */\n lines?: number | \"auto\";\n /*\n * Ref to the container element of the truncated text. It will have resize observer attached to it.\n */\n container?: HTMLElement | React.RefObject<HTMLElement>;\n}\n\nexport const Truncate: React.FC<TruncateProps> = ({\n children,\n position = \"end\",\n lines = 1,\n className,\n style,\n container: containerProp,\n ...rest\n}) => {\n const cls = useCls();\n const containerRef = useRef<HTMLElement>(null);\n const [isTruncated, setIsTruncated] = useState(false);\n const [truncatedText, setTruncatedText] = useState(children);\n\n const text = children;\n\n // Get appropriate container styles based on position and lines\n const getContainerStyles = useCallback(() => {\n // For explicit line numbers or single line\n if (lines !== \"auto\") {\n return {\n ...style,\n ...(lines > 1 ? { \"--ds-line-clamp\": lines } : {}),\n } as React.CSSProperties;\n }\n\n // For auto line calculation, we'll let the useLayoutEffect handle it\n return {\n ...style,\n // Set a temporary high value to ensure it fits the parent\n \"--ds-line-clamp\": 999,\n } as React.CSSProperties;\n }, [lines, style]);\n\n // Handle auto line calculation\n const handleAutoLineCalculation = useCallback(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const styles = window.getComputedStyle(container);\n const fontSize = parseFloat(styles.fontSize);\n const lineHeight =\n styles.lineHeight === \"normal\"\n ? fontSize * 1.2\n : parseFloat(styles.lineHeight);\n\n const availableHeight = calculateAvailableHeight(container);\n const maxLines = Math.max(1, Math.floor(availableHeight / lineHeight));\n\n container.style.setProperty(\"--ds-line-clamp\", String(maxLines));\n const isTruncated = checkIfTextTruncated(text, container, availableHeight);\n setIsTruncated(isTruncated);\n }, [text]);\n\n const observe = useCallback(\n (\n elements: (HTMLElement | null)[],\n callback: () => void,\n cleanup?: () => void\n ) => {\n const validElements = elements.filter(Boolean) as HTMLElement[];\n if (validElements.length === 0) return;\n\n window.document.fonts?.ready?.then(callback);\n\n const observer = new ResizeObserver(() => {\n window.requestAnimationFrame(callback);\n });\n\n validElements.forEach((el) => observer.observe(el));\n return () => {\n observer.disconnect();\n if (cleanup) cleanup();\n };\n },\n []\n );\n\n useLayoutEffect(() => {\n const container = containerRef.current;\n let flexContainer =\n containerProp instanceof HTMLElement\n ? containerProp\n : containerProp && \"current\" in containerProp\n ? containerProp.current\n : null;\n if (!container) return;\n if (!flexContainer) {\n flexContainer = container.closest(\"[data-truncate-container]\");\n }\n if (typeof containerProp !== \"undefined\" && !flexContainer) return;\n\n // reset\n setTruncatedText(text);\n\n // Handle auto-height calculation\n if (lines === \"auto\") {\n return observe(\n [container, container.parentElement],\n handleAutoLineCalculation\n );\n }\n\n // Skip custom truncation logic for multi-line mode\n if (typeof lines === \"number\" && lines > 1) {\n // Check if text is truncated by comparing heights\n const handleMultilineTruncation = () => {\n const isTruncated = checkIfTextTruncated(text, container);\n setIsTruncated(isTruncated);\n };\n\n return observe([container], handleMultilineTruncation);\n }\n\n if (position == \"middle\") {\n // Middle truncate\n let cancellationToken = { cancelled: false };\n\n const handleMiddleTruncate = () => {\n if (cancellationToken) cancellationToken.cancelled = true;\n\n const requestCancellationToken = { cancelled: false };\n cancellationToken = requestCancellationToken;\n\n const truncated = getMiddleTruncatedString(text, \"\\u2026\", container);\n\n if (requestCancellationToken.cancelled) return;\n\n setTruncatedText(truncated);\n };\n // to do: optimize resize observer here to avoid re-calculate\n return observe(\n [flexContainer ? flexContainer : container],\n handleMiddleTruncate,\n () => {\n cancellationToken.cancelled = true;\n }\n );\n }\n\n // End truncate\n const handleEndTruncate = () => {\n const isOverflowing = container.scrollWidth > container.clientWidth;\n if (isOverflowing) {\n setIsTruncated(true);\n }\n };\n\n return observe(\n [flexContainer ? flexContainer : container],\n handleEndTruncate\n );\n }, [\n text,\n position,\n lines,\n containerProp,\n handleAutoLineCalculation,\n observe,\n ]);\n\n return (\n <span\n ref={containerRef}\n style={getContainerStyles()}\n className={clsx(\n lines === 1 ? cls(\"truncate\") : cls(\"truncate-multiline\"),\n position === \"middle\" ? cls(\"truncate-middle\") : cls(\"truncate-end\"),\n className\n )}\n title={isTruncated ? text : undefined}\n data-truncate-text-node\n {...rest}\n >\n {text === truncatedText ? text : <span>{truncatedText}</span>}\n </span>\n );\n};\n"],"names":["Truncate","children","position","lines","className","style","containerProp","rest","cls","useCls","containerRef","useRef","isTruncated","setIsTruncated","useState","truncatedText","setTruncatedText","text","getContainerStyles","useCallback","handleAutoLineCalculation","container","styles","fontSize","lineHeight","availableHeight","calculateAvailableHeight","maxLines","checkIfTextTruncated","observe","elements","callback","cleanup","validElements","_b","_a","observer","el","useLayoutEffect","flexContainer","cancellationToken","requestCancellationToken","truncated","getMiddleTruncatedString","jsx","clsx"],"mappings":"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"}
|
|
@@ -1,36 +1,56 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
const g = (n) => {
|
|
2
|
+
var l;
|
|
3
|
+
const e = document.createElement("span");
|
|
4
|
+
e.style.opacity = "0", e.style.position = "absolute", e.style.top = "-1000px", e.style.left = "-1000px", e.style.whiteSpace = "nowrap", e.style.pointerEvents = "none";
|
|
5
|
+
const o = n.getBoundingClientRect(), t = n.cloneNode(!0);
|
|
6
|
+
return t.style.maxWidth = `${o.width}px`, t.style.position = "absolute", t.style.pointerEvents = "none", t.style.top = "-99px", t.style.left = "-99px", t.style.zIndex = "-1", (l = n.parentElement) == null || l.appendChild(t), t.appendChild(e), {
|
|
7
|
+
measure: (i) => (e.innerText = i, e.clientWidth),
|
|
5
8
|
destroy: () => {
|
|
6
|
-
|
|
9
|
+
var i;
|
|
10
|
+
t.removeChild(e), (i = n.parentElement) == null || i.removeChild(t);
|
|
7
11
|
}
|
|
8
12
|
};
|
|
9
|
-
},
|
|
10
|
-
var
|
|
11
|
-
if (!
|
|
12
|
-
const { measure:
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
}, C = (n, e, o) => {
|
|
14
|
+
var p;
|
|
15
|
+
if (!n) return n;
|
|
16
|
+
const { measure: t, destroy: l } = g(o), i = t(n), r = o.clientWidth, u = Math.floor(
|
|
17
|
+
r / i * n.length
|
|
18
|
+
);
|
|
19
|
+
if (i <= r)
|
|
20
|
+
return l(), n;
|
|
21
|
+
let s = u;
|
|
22
|
+
const d = {}, m = 20, y = 4;
|
|
23
|
+
for (; Object.values(d).length <= m && !d[s]; ) {
|
|
24
|
+
if (s <= 1) {
|
|
25
|
+
d[0] = [0, e];
|
|
20
26
|
break;
|
|
21
27
|
}
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
24
|
-
|
|
28
|
+
const c = n.slice(0, Math.ceil((s - e.length) / 2 - 1)).trimEnd(), f = n.slice(Math.floor((s - e.length) / 2) - s).trimStart(), h = c + e + f, a = t(h);
|
|
29
|
+
if (d[s] = [a, h], a >= r)
|
|
30
|
+
s = s - 2;
|
|
25
31
|
else {
|
|
26
|
-
if (
|
|
27
|
-
|
|
32
|
+
if (r - a < y) break;
|
|
33
|
+
s = s + 2;
|
|
28
34
|
}
|
|
29
35
|
}
|
|
30
|
-
return l(), ((
|
|
36
|
+
return l(), ((p = Object.values(d).reverse().find(([c]) => c < r)) == null ? void 0 : p[1]) ?? Object.values(d)[0][1];
|
|
37
|
+
}, b = (n, e) => {
|
|
38
|
+
const o = window.getComputedStyle(e), t = document.createElement("span");
|
|
39
|
+
return t.style.visibility = "hidden", t.style.position = "absolute", t.style.width = `${e.clientWidth}px`, t.style.fontSize = o.fontSize, t.style.fontFamily = o.fontFamily, t.style.lineHeight = o.lineHeight, t.textContent = n, document.body.appendChild(t), t;
|
|
40
|
+
}, T = (n, e, o) => {
|
|
41
|
+
const t = b(n, e), l = o ? t.scrollHeight > o : t.scrollHeight > (e.clientHeight || e.offsetHeight);
|
|
42
|
+
return document.body.removeChild(t), l;
|
|
43
|
+
}, W = (n) => {
|
|
44
|
+
const e = n.parentElement;
|
|
45
|
+
if (!e) return 0;
|
|
46
|
+
const o = window.getComputedStyle(e), t = parseFloat(o.paddingTop) || 0, l = parseFloat(o.paddingBottom) || 0, i = parseFloat(o.borderTopWidth) || 0, r = parseFloat(o.borderBottomWidth) || 0;
|
|
47
|
+
return e.clientHeight - t - l - i - r;
|
|
31
48
|
};
|
|
32
49
|
export {
|
|
33
|
-
|
|
34
|
-
|
|
50
|
+
W as calculateAvailableHeight,
|
|
51
|
+
T as checkIfTextTruncated,
|
|
52
|
+
b as createMeasurementClone,
|
|
53
|
+
C as getMiddleTruncatedString,
|
|
54
|
+
g as measureText
|
|
35
55
|
};
|
|
36
56
|
//# sourceMappingURL=helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sources":["../../../src/components/truncate/helpers.ts"],"sourcesContent":["export const measureText = (container: HTMLElement) => {\n const span = document.createElement(\"span\");\n span.style.opacity = \"0\";\n span.style.position = \"absolute\";\n span.style.top = \"-1000px\";\n span.style.left = \"-1000px\";\n span.style.whiteSpace = \"nowrap\";\n span.style.pointerEvents = \"none\";\n container.appendChild(span);\n\n return {\n measure: (text: string) => {\n span.innerText = text;\n return span.clientWidth;\n },\n destroy: () => {\n container.removeChild(span);\n },\n };\n};\n\nexport const getMiddleTruncatedString = (\n text: string,\n ellipsis: string,\n container: HTMLElement\n): string => {\n if (!text) return text;\n\n const { measure: getTextWidth, destroy: destroyMeasure } =\n measureText(container);\n\n const textWidth = getTextWidth(text);\n const containerWidth = container.clientWidth;\n const initialOffset = Math.floor((containerWidth / textWidth) * text.length);\n\n if (textWidth <= containerWidth) {\n destroyMeasure();\n return text;\n }\n\n let offset = initialOffset;\n const attempts: Record<number, [number, string]> = {};\n const maxAttempts = 20;\n const buffer = 10;\n\n while (Object.values(attempts).length <= maxAttempts) {\n // If we have already tried this offset, stop\n if (attempts[offset]) break;\n\n // If we are at the beginning of the string, just return the ellipsis\n if (offset <= 1) {\n attempts[0] = [0, ellipsis];\n break;\n }\n\n const start = text\n .slice(0, Math.ceil((offset - ellipsis.length) / 2 - 1))\n .trimEnd();\n const end = text\n .slice(Math.floor((offset - ellipsis.length) / 2) - offset)\n .trimStart();\n const truncatedStr = start + ellipsis + end;\n const width = getTextWidth(truncatedStr);\n\n attempts[offset] = [width, truncatedStr];\n\n if (width >= containerWidth) {\n offset = offset - 2;\n } else {\n // If we are close to the container width, stop\n if (containerWidth - width < buffer) break;\n offset = offset + 2;\n }\n }\n\n // Remove the span element used for measuring text\n destroyMeasure();\n\n // Find the closest attempt that is smaller than the container width\n return (\n Object.values(attempts)\n .reverse()\n .find(([width]) => width < containerWidth)?.[1] ??\n Object.values(attempts)[0][1]\n );\n};\n"],"names":["measureText","container","span","text","getMiddleTruncatedString","ellipsis","_a","getTextWidth","destroyMeasure","textWidth","containerWidth","initialOffset","offset","attempts","maxAttempts","buffer","start","end","truncatedStr","width"],"mappings":"AAAa,MAAAA,IAAc,CAACC,MAA2B;AAC/C,QAAAC,IAAO,SAAS,cAAc,MAAM;AAC1C,SAAAA,EAAK,MAAM,UAAU,KACrBA,EAAK,MAAM,WAAW,YACtBA,EAAK,MAAM,MAAM,WACjBA,EAAK,MAAM,OAAO,WAClBA,EAAK,MAAM,aAAa,UACxBA,EAAK,MAAM,gBAAgB,QAC3BD,EAAU,YAAYC,CAAI,GAEnB;AAAA,IACL,SAAS,CAACC,OACRD,EAAK,YAAYC,GACVD,EAAK;AAAA,IAEd,SAAS,MAAM;AACb,MAAAD,EAAU,YAAYC,CAAI;AAAA,IAAA;AAAA,EAE9B;AACF,GAEaE,IAA2B,CACtCD,GACAE,GACAJ,MACW;AAzBA,MAAAK;AA0BP,MAAA,CAACH,EAAa,QAAAA;AAElB,QAAM,EAAE,SAASI,GAAc,SAASC,EAAe,IACrDR,EAAYC,CAAS,GAEjBQ,IAAYF,EAAaJ,CAAI,GAC7BO,IAAiBT,EAAU,aAC3BU,IAAgB,KAAK,MAAOD,IAAiBD,IAAaN,EAAK,MAAM;AAE3E,MAAIM,KAAaC;AACA,WAAAF,EAAA,GACRL;AAGT,MAAIS,IAASD;AACb,QAAME,IAA6C,CAAC,GAC9CC,IAAc,IACdC,IAAS;AAEf,SAAO,OAAO,OAAOF,CAAQ,EAAE,UAAUC,KAEnC,CAAAD,EAASD,CAAM,KAFiC;AAKpD,QAAIA,KAAU,GAAG;AACf,MAAAC,EAAS,CAAC,IAAI,CAAC,GAAGR,CAAQ;AAC1B;AAAA,IAAA;AAGF,UAAMW,IAAQb,EACX,MAAM,GAAG,KAAK,MAAMS,IAASP,EAAS,UAAU,IAAI,CAAC,CAAC,EACtD,QAAQ,GACLY,IAAMd,EACT,MAAM,KAAK,OAAOS,IAASP,EAAS,UAAU,CAAC,IAAIO,CAAM,EACzD,UAAU,GACPM,IAAeF,IAAQX,IAAWY,GAClCE,IAAQZ,EAAaW,CAAY;AAIvC,QAFAL,EAASD,CAAM,IAAI,CAACO,GAAOD,CAAY,GAEnCC,KAAST;AACX,MAAAE,IAASA,IAAS;AAAA,SACb;AAED,UAAAF,IAAiBS,IAAQJ,EAAQ;AACrC,MAAAH,IAASA,IAAS;AAAA,IAAA;AAAA,EACpB;AAIa,SAAAJ,EAAA,KAIbF,IAAA,OAAO,OAAOO,CAAQ,EACnB,UACA,KAAK,CAAC,CAACM,CAAK,MAAMA,IAAQT,CAAc,MAF3C,gBAAAJ,EAE+C,OAC/C,OAAO,OAAOO,CAAQ,EAAE,CAAC,EAAE,CAAC;AAEhC;"}
|
|
1
|
+
{"version":3,"file":"helpers.js","sources":["../../../src/components/truncate/helpers.ts"],"sourcesContent":["/**\n * Finds the closest parent element that has inline flex display\n * @param element - The starting HTMLElement\n * @returns The closest inline flex parent or null if not found\n */\nexport function findClosestInlineFlexParent(\n element: HTMLElement\n): HTMLElement | null {\n if (!element) return null;\n\n let currentElement = element.parentElement;\n let attempts = 0;\n const maxAttempts = 10;\n\n while (currentElement && attempts < maxAttempts) {\n const computedStyle = window.getComputedStyle(currentElement);\n\n // Check if display is inline-flex\n if (computedStyle.display === \"inline-flex\") {\n return currentElement;\n }\n\n // Move to the next parent\n currentElement = currentElement.parentElement;\n attempts++;\n }\n\n return null;\n}\n\nexport function getFlexRemainingSpace(\n flexContainer: HTMLElement,\n ignoreElement: HTMLElement | ((e: HTMLElement) => boolean) = null\n) {\n const style = window.getComputedStyle(flexContainer);\n const isRow =\n style.flexDirection === \"row\" || style.flexDirection === \"row-reverse\";\n const containerSize = isRow\n ? flexContainer.offsetWidth\n : flexContainer.offsetHeight;\n const gap = parseFloat(style.gap) || 0;\n const paddingStart =\n parseFloat(isRow ? style.paddingLeft : style.paddingTop) || 0;\n const paddingEnd =\n parseFloat(isRow ? style.paddingRight : style.paddingBottom) || 0;\n\n let totalItemSize = 0;\n const items: HTMLElement[] = (\n [...flexContainer.children] as HTMLElement[]\n ).filter(\n (child) =>\n child instanceof HTMLElement &&\n (typeof ignoreElement === \"function\"\n ? !ignoreElement(child)\n : child !== ignoreElement)\n );\n for (let i = 0; i < items.length; i++) {\n const itemStyle = window.getComputedStyle(items[i]);\n const marginStart =\n parseFloat(isRow ? itemStyle.marginLeft : itemStyle.marginTop) || 0;\n const marginEnd =\n parseFloat(isRow ? itemStyle.marginRight : itemStyle.marginBottom) || 0;\n totalItemSize +=\n (isRow ? items[i].offsetWidth : items[i].offsetHeight) +\n marginStart +\n marginEnd;\n }\n\n // Add gaps (n-1 gaps for n items)\n totalItemSize += gap * (items.length - 1);\n\n // Calculate remaining space\n const remainingSpace =\n containerSize - totalItemSize - paddingStart - paddingEnd;\n return Math.max(0, remainingSpace);\n}\n\nexport const measureText = (container: HTMLElement) => {\n const span = document.createElement(\"span\");\n span.style.opacity = \"0\";\n span.style.position = \"absolute\";\n span.style.top = \"-1000px\";\n span.style.left = \"-1000px\";\n span.style.whiteSpace = \"nowrap\";\n span.style.pointerEvents = \"none\";\n\n const nodeRect = container.getBoundingClientRect();\n\n const containerClone = container.cloneNode(true) as HTMLElement;\n containerClone.style.maxWidth = `${nodeRect.width}px`;\n containerClone.style.position = \"absolute\";\n containerClone.style.pointerEvents = \"none\";\n containerClone.style.top = \"-99px\";\n containerClone.style.left = \"-99px\";\n containerClone.style.zIndex = \"-1\";\n\n container.parentElement?.appendChild(containerClone);\n containerClone.appendChild(span);\n\n return {\n measure: (text: string) => {\n span.innerText = text;\n return span.clientWidth;\n },\n destroy: () => {\n containerClone.removeChild(span);\n container.parentElement?.removeChild(containerClone);\n },\n };\n};\n\nexport const getMiddleTruncatedString = (\n text: string,\n ellipsis: string,\n container: HTMLElement\n): string => {\n if (!text) return text;\n\n const { measure: getTextWidth, destroy: destroyMeasure } =\n measureText(container);\n\n const textWidth = getTextWidth(text);\n\n const containerWidthToCompare = container.clientWidth;\n\n const initialOffset = Math.floor(\n (containerWidthToCompare / textWidth) * text.length\n );\n\n if (textWidth <= containerWidthToCompare) {\n destroyMeasure();\n return text;\n }\n\n let offset = initialOffset;\n const attempts: Record<number, [number, string]> = {};\n const maxAttempts = 20;\n const buffer = 4;\n\n while (Object.values(attempts).length <= maxAttempts) {\n // If we have already tried this offset, stop\n if (attempts[offset]) break;\n\n // If we are at the beginning of the string, just return the ellipsis\n if (offset <= 1) {\n attempts[0] = [0, ellipsis];\n break;\n }\n\n const start = text\n .slice(0, Math.ceil((offset - ellipsis.length) / 2 - 1))\n .trimEnd();\n const end = text\n .slice(Math.floor((offset - ellipsis.length) / 2) - offset)\n .trimStart();\n const truncatedStr = start + ellipsis + end;\n const width = getTextWidth(truncatedStr);\n\n attempts[offset] = [width, truncatedStr];\n\n if (width >= containerWidthToCompare) {\n offset = offset - 2;\n } else {\n // If we are close to the container width, stop\n if (containerWidthToCompare - width < buffer) break;\n offset = offset + 2;\n }\n }\n\n // Remove the span element used for measuring text\n destroyMeasure();\n\n // Find the closest attempt that is smaller than the container width\n return (\n Object.values(attempts)\n .reverse()\n .find(([width]) => width < containerWidthToCompare)?.[1] ??\n Object.values(attempts)[0][1]\n );\n};\n\n// Utility functions for measurements\nexport const createMeasurementClone = (\n text: string,\n container: HTMLElement\n) => {\n const styles = window.getComputedStyle(container);\n const clone = document.createElement(\"span\");\n clone.style.visibility = \"hidden\";\n clone.style.position = \"absolute\";\n clone.style.width = `${container.clientWidth}px`;\n clone.style.fontSize = styles.fontSize;\n clone.style.fontFamily = styles.fontFamily;\n clone.style.lineHeight = styles.lineHeight;\n clone.textContent = text;\n document.body.appendChild(clone);\n return clone;\n};\n\nexport const checkIfTextTruncated = (\n text: string,\n container: HTMLElement,\n availableHeight?: number\n) => {\n const clone = createMeasurementClone(text, container);\n const isTruncated = availableHeight\n ? clone.scrollHeight > availableHeight\n : clone.scrollHeight > (container.clientHeight || container.offsetHeight);\n document.body.removeChild(clone);\n return isTruncated;\n};\n\nexport const calculateAvailableHeight = (container: HTMLElement) => {\n const parent = container.parentElement;\n if (!parent) return 0;\n\n const parentStyles = window.getComputedStyle(parent);\n const paddingTop = parseFloat(parentStyles.paddingTop) || 0;\n const paddingBottom = parseFloat(parentStyles.paddingBottom) || 0;\n const borderTopWidth = parseFloat(parentStyles.borderTopWidth) || 0;\n const borderBottomWidth = parseFloat(parentStyles.borderBottomWidth) || 0;\n\n return (\n parent.clientHeight -\n paddingTop -\n paddingBottom -\n borderTopWidth -\n borderBottomWidth\n );\n};\n\nexport const calculateAvailableWidth = (container: HTMLElement) => {\n const parent = container.parentElement;\n if (!parent) return 0;\n\n const parentStyles = window.getComputedStyle(parent);\n const paddingLeft = parseFloat(parentStyles.paddingLeft) || 0;\n const paddingRight = parseFloat(parentStyles.paddingRight) || 0;\n const borderLeftWidth = parseFloat(parentStyles.borderLeftWidth) || 0;\n const borderRightWidth = parseFloat(parentStyles.borderRightWidth) || 0;\n\n return (\n parent.clientWidth -\n paddingLeft -\n paddingRight -\n borderLeftWidth -\n borderRightWidth\n );\n};\n"],"names":["measureText","container","_a","span","nodeRect","containerClone","text","getMiddleTruncatedString","ellipsis","getTextWidth","destroyMeasure","textWidth","containerWidthToCompare","initialOffset","offset","attempts","maxAttempts","buffer","start","end","truncatedStr","width","createMeasurementClone","styles","clone","checkIfTextTruncated","availableHeight","isTruncated","calculateAvailableHeight","parent","parentStyles","paddingTop","paddingBottom","borderTopWidth","borderBottomWidth"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer components{.ds-truncate{white-space:nowrap;overflow:hidden;flex-grow:1;min-width:0;max-width:100%;display:block}.ds-truncate-end{text-overflow:ellipsis}.ds-truncate-middle{text-overflow:clip}.ds-truncate-multiline{display:-webkit-box;-webkit-line-clamp:var(--ds-line-clamp, 2);line-clamp:var(--ds-line-clamp, 2);-webkit-box-orient:vertical;overflow:hidden;white-space:normal;text-overflow:ellipsis;word-break:break-word}}
|
|
1
|
+
@layer components{.ds-truncate{white-space:nowrap;overflow:hidden;flex-grow:1;min-width:0;max-width:100%;display:block}.ds-truncate-end{text-overflow:ellipsis}.ds-truncate-middle{text-overflow:clip;width:100%;flex-grow:0}.ds-truncate-multiline{display:-webkit-box;-webkit-line-clamp:var(--ds-line-clamp, 2);line-clamp:var(--ds-line-clamp, 2);-webkit-box-orient:vertical;overflow:hidden;white-space:normal;text-overflow:ellipsis;word-break:break-word}}
|
package/dist/index.d.ts
CHANGED
|
@@ -82,6 +82,7 @@ import { Dropdown } from 'antd';
|
|
|
82
82
|
import { DropDownProps } from 'antd';
|
|
83
83
|
import { DropdownProps } from 'antd';
|
|
84
84
|
import { ElementType } from 'react';
|
|
85
|
+
import { ElementTypeToDOMType as ElementTypeToDOMType_2 } from '..';
|
|
85
86
|
import { EmptyProps as EmptyProps_2 } from 'antd/es/empty';
|
|
86
87
|
import { ErrorListProps } from 'antd/es/form';
|
|
87
88
|
import { EventDataNode } from 'antd/es/tree';
|
|
@@ -94,6 +95,7 @@ import { FloatButtonProps } from 'antd';
|
|
|
94
95
|
import { FloatButtonRef } from 'antd';
|
|
95
96
|
import { FormInstance } from 'antd';
|
|
96
97
|
import { FormItemProps as FormItemProps_2 } from 'antd/es/form/FormItem';
|
|
98
|
+
import { FormLabelProps } from './label';
|
|
97
99
|
import { FormListFieldData } from 'antd';
|
|
98
100
|
import { FormListOperation } from 'antd';
|
|
99
101
|
import { FormListProps } from 'antd/es/form';
|
|
@@ -1380,13 +1382,13 @@ export declare const DragDrop: typeof DragDropRoot & {
|
|
|
1380
1382
|
/**
|
|
1381
1383
|
* Zone where items can be dropped
|
|
1382
1384
|
*/
|
|
1383
|
-
Droppable: <T extends DragData = unknown, M extends boolean = false>({ id, children, className, disabled, placeholder, icon, render, onDrop, validate, multiple, value, onChange, renderValueLabel, renderValueIcon, ...rest }: DragDropDroppableProps<T, M>) => null;
|
|
1385
|
+
Droppable: <T extends DragData = unknown, M extends boolean = false>({ id, children, className, disabled, placeholder, icon, render, onDrop, validate, multiple, value, onChange, maxItems, renderValueLabel, renderValueIcon, ...rest }: DragDropDroppableProps<T, M>) => null;
|
|
1384
1386
|
/**
|
|
1385
1387
|
* Value component to display the value of the dragged item
|
|
1386
1388
|
*/
|
|
1387
1389
|
Value: <T extends DragData, M extends boolean>(props: DragDropValueProps_2<T, M> & {
|
|
1388
1390
|
ref?: ForwardedRef<HTMLDivElement>;
|
|
1389
|
-
}) => ReturnType<(<T_1 extends DragData, M_1 extends boolean>({ value, onChange, multiple, renderValueLabel, renderValueIcon, className, style, ...rest }: DragDropValueProps_2<T_1, M_1
|
|
1391
|
+
}) => ReturnType<(<T_1 extends DragData, M_1 extends boolean>({ value, onChange, multiple, renderValueLabel, renderValueIcon, className, style, maxItems, ...rest }: DragDropValueProps_2<T_1, M_1>, ref: ForwardedRef<HTMLDivElement>) => JSX.Element)>;
|
|
1390
1392
|
};
|
|
1391
1393
|
|
|
1392
1394
|
/**
|
|
@@ -1476,10 +1478,6 @@ export declare interface DragDropDroppableProps<T extends DragData = DragData, M
|
|
|
1476
1478
|
* Validate if the item can be dropped
|
|
1477
1479
|
*/
|
|
1478
1480
|
validate?: (item: DraggableInfo<T>) => boolean;
|
|
1479
|
-
/**
|
|
1480
|
-
* Maximum number of items that can be dropped
|
|
1481
|
-
*/
|
|
1482
|
-
maxItems?: number;
|
|
1483
1481
|
}
|
|
1484
1482
|
|
|
1485
1483
|
/**
|
|
@@ -1519,11 +1517,31 @@ export declare interface DragDropProps<T extends DragData = DragData> {
|
|
|
1519
1517
|
export declare function DragDropRoot<T extends DragData = DragData>({ children, onDragEnd: _onDragEnd, onDragStart: _onDragStart, onDrop: _onDrop, className, }: DragDropProps<T>): JSX.Element;
|
|
1520
1518
|
|
|
1521
1519
|
declare interface DragDropValueProps<T extends DragData = DragData, M extends boolean = false> extends Omit<ComponentPropsWithoutRef<"div">, "onDragEnter" | "onDragOver" | "onDragLeave" | "onDrop" | "onChange"> {
|
|
1520
|
+
/**
|
|
1521
|
+
* Whether to allow multiple values
|
|
1522
|
+
* @default false
|
|
1523
|
+
*/
|
|
1522
1524
|
multiple?: M;
|
|
1525
|
+
/**
|
|
1526
|
+
* The current value(s) of the drop zone
|
|
1527
|
+
*/
|
|
1523
1528
|
value?: M extends true ? T[] : T;
|
|
1529
|
+
/**
|
|
1530
|
+
* Callback fired when the value changes
|
|
1531
|
+
*/
|
|
1524
1532
|
onChange?: M extends true ? (value: T[]) => void : (value: T) => void;
|
|
1533
|
+
/**
|
|
1534
|
+
* Function to render the label for a single value
|
|
1535
|
+
*/
|
|
1525
1536
|
renderValueLabel?: (singleValue: T) => ReactElement | string;
|
|
1537
|
+
/**
|
|
1538
|
+
* Function to render the icon for a single value
|
|
1539
|
+
*/
|
|
1526
1540
|
renderValueIcon?: (singleValue: T) => ReactElement;
|
|
1541
|
+
/**
|
|
1542
|
+
* Maximum number of items that can be dropped
|
|
1543
|
+
*/
|
|
1544
|
+
maxItems?: number;
|
|
1527
1545
|
}
|
|
1528
1546
|
|
|
1529
1547
|
export declare interface DragEndEvent<T extends DragData = DragData> {
|
|
@@ -1718,7 +1736,7 @@ export { FloatButtonProps }
|
|
|
1718
1736
|
|
|
1719
1737
|
export { FloatButtonRef }
|
|
1720
1738
|
|
|
1721
|
-
export declare const Form: (<Values =
|
|
1739
|
+
export declare const Form: (<Values = unknown>({ ...rest }: InternalFormProps<Values>) => JSX.Element) & {
|
|
1722
1740
|
useForm: typeof useForm;
|
|
1723
1741
|
useFormInstance: typeof default_9;
|
|
1724
1742
|
useWatch: typeof useWatch;
|
|
@@ -1726,6 +1744,9 @@ export declare const Form: (<Values = any>({ ...rest }: InternalFormProps<Values
|
|
|
1726
1744
|
List: React_2.FC<FormListProps>;
|
|
1727
1745
|
ErrorList: React_2.FC<ErrorListProps>;
|
|
1728
1746
|
Provider: React_2.FC<FormProviderProps>;
|
|
1747
|
+
Label: <E extends React_2.ElementType = "label">(props: FormLabelProps<E> & {
|
|
1748
|
+
ref?: React_2.ComponentPropsWithRef<E>["ref"];
|
|
1749
|
+
}) => ReturnType<(<E_1 extends React_2.ElementType = "label">({ label, tooltip, optionalMark, requiredMark, className, as, render, ...rest }: FormLabelProps<E_1>, ref: React_2.Ref<ElementTypeToDOMType_2<E_1>>) => JSX.Element)>;
|
|
1729
1750
|
};
|
|
1730
1751
|
|
|
1731
1752
|
export { FormInstance }
|
|
@@ -1865,7 +1886,7 @@ export declare interface InputProps extends InputProps_2 {
|
|
|
1865
1886
|
|
|
1866
1887
|
export declare const InternalBadge: ({ count, showZero, ...rest }: BadgeProps) => JSX.Element;
|
|
1867
1888
|
|
|
1868
|
-
declare interface InternalFormProps<Values =
|
|
1889
|
+
declare interface InternalFormProps<Values = unknown> extends React_2.ComponentProps<typeof default_8<Values>> {
|
|
1869
1890
|
}
|
|
1870
1891
|
|
|
1871
1892
|
declare const InternalTable: <RecordType extends object = object>(props: TableProps<RecordType> & {
|
|
@@ -2390,10 +2411,6 @@ export { Progress }
|
|
|
2390
2411
|
|
|
2391
2412
|
export { ProgressProps }
|
|
2392
2413
|
|
|
2393
|
-
export declare type Props = {
|
|
2394
|
-
text: string;
|
|
2395
|
-
} & default_2.CSSProperties;
|
|
2396
|
-
|
|
2397
2414
|
export { QRCode }
|
|
2398
2415
|
|
|
2399
2416
|
export { QRCodeProps }
|
|
@@ -2934,7 +2951,7 @@ export declare interface ScrollAreaProps {
|
|
|
2934
2951
|
orientation?: "vertical" | "horizontal";
|
|
2935
2952
|
}
|
|
2936
2953
|
|
|
2937
|
-
declare const SearchInner: (
|
|
2954
|
+
declare const SearchInner: ({ enterButton, onSearch, prefix, onPressEnter, onClear, loading, ...rest }: SearchProps, ref: React.Ref<InputRef>) => JSX.Element;
|
|
2938
2955
|
|
|
2939
2956
|
export declare interface SearchProps extends SearchProps_2 {
|
|
2940
2957
|
}
|
|
@@ -2999,9 +3016,11 @@ export { Space }
|
|
|
2999
3016
|
|
|
3000
3017
|
export { SpaceProps }
|
|
3001
3018
|
|
|
3002
|
-
export declare const Spin: ({ indicator, ...rest }: SpinProps) => JSX.Element;
|
|
3019
|
+
export declare const Spin: ({ indicator, size, ...rest }: SpinProps) => JSX.Element;
|
|
3003
3020
|
|
|
3004
|
-
export declare type SpinProps = SpinProps_2
|
|
3021
|
+
export declare type SpinProps = Omit<SpinProps_2, "size"> & {
|
|
3022
|
+
size?: "small" | "default" | "large" | number;
|
|
3023
|
+
};
|
|
3005
3024
|
|
|
3006
3025
|
export declare const Split: default_2.FC<SplitterProps> & {
|
|
3007
3026
|
Panel: default_2.FC<SplitterPanelProps>;
|
|
@@ -3330,10 +3349,15 @@ export declare type TruncatePosition = "middle" | "end";
|
|
|
3330
3349
|
export declare interface TruncateProps extends Omit<default_2.ComponentPropsWithoutRef<"span">, "title"> {
|
|
3331
3350
|
/** Text content to be truncated */
|
|
3332
3351
|
children: string;
|
|
3333
|
-
/**
|
|
3352
|
+
/** Position where the truncation should occur */
|
|
3334
3353
|
position?: TruncatePosition;
|
|
3335
|
-
/**
|
|
3354
|
+
/**
|
|
3355
|
+
* Number of lines to display before truncating
|
|
3356
|
+
* @default 1
|
|
3357
|
+
* @remarks Use 'auto' to fit parent height
|
|
3358
|
+
*/
|
|
3336
3359
|
lines?: number | "auto";
|
|
3360
|
+
container?: HTMLElement | default_2.RefObject<HTMLElement>;
|
|
3337
3361
|
}
|
|
3338
3362
|
|
|
3339
3363
|
export { Typography }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bioturing/components",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"module": "./dist/index.js",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@ant-design/cssinjs": "^1.23.0",
|
|
20
|
-
"@base-ui-components/react": "1.0.0-beta.
|
|
21
|
-
"@floating-ui/react": "^0.27.
|
|
20
|
+
"@base-ui-components/react": "1.0.0-beta.1",
|
|
21
|
+
"@floating-ui/react": "^0.27.13",
|
|
22
22
|
"cmdk": "^1.1.1",
|
|
23
23
|
"es-toolkit": "^1.37.2",
|
|
24
24
|
"merge-refs": "^2.0.0",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"rc-table": "^7.50.4",
|
|
28
28
|
"rc-tree": "^5.13.1",
|
|
29
29
|
"react-use-resizable": "^0.2.0",
|
|
30
|
-
"tailwind-merge": "^3.
|
|
31
|
-
"@bioturing/assets": "0.
|
|
30
|
+
"tailwind-merge": "^3.3.1",
|
|
31
|
+
"@bioturing/assets": "0.19.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"antd": "^5.25.0",
|