@e-burgos/tucu-ui 2.7.1 → 2.7.3

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 CHANGED
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.7.3] - 2026-07-15
9
+
10
+ ### Changed
11
+
12
+ - replace react-use with native React implementations
13
+ - bump @e-burgos/tucu-ui to ^2.7.2
14
+
15
+ ### Fixed
16
+
17
+ - resolve typecheck errors in CodeBlock's lazy prismjs loading
18
+ ## [2.7.2] - 2026-07-15
19
+
20
+ ### Fixed
21
+
22
+ - lazy-load prismjs in CodeBlock to fix dev-mode crash for consumers
8
23
  ## [2.7.1] - 2026-07-15
9
24
 
10
25
  ### Fixed
@@ -1,99 +1,133 @@
1
- import { jsxs as n, jsx as r } from "react/jsx-runtime";
2
- import { useState as l, useEffect as x } from "react";
3
- import { Scrollbar as k } from "../common/scrollbar.mjs";
4
- import { Check as v, Copy as C, ChevronUp as w, ChevronDown as N } from "lucide-react";
5
- import d from "prismjs";
6
- import e from "classnames";
7
- import "prismjs/components/prism-javascript";
8
- import "prismjs/components/prism-typescript";
9
- import "prismjs/components/prism-jsx";
10
- import "prismjs/components/prism-tsx";
11
- import "prismjs/components/prism-css";
12
- import "prismjs/components/prism-bash";
13
- import "prismjs/components/prism-json";
14
- import "prismjs/components/prism-python";
15
- import "prismjs/components/prism-java";
16
- import "prismjs/components/prism-sql";
17
- import { useIsMobile as j } from "../../hooks/use-is-mobile.mjs";
18
- const G = ({
19
- code: t,
1
+ import { jsxs as d, jsx as e } from "react/jsx-runtime";
2
+ import { useState as c, useEffect as C } from "react";
3
+ import { Scrollbar as N } from "../common/scrollbar.mjs";
4
+ import { Check as j, Copy as M, ChevronUp as P, ChevronDown as E } from "lucide-react";
5
+ import a from "classnames";
6
+ import { useIsMobile as I } from "../../hooks/use-is-mobile.mjs";
7
+ const b = {
8
+ markup: { load: () => import("prismjs/components/prism-markup") },
9
+ clike: { load: () => import("prismjs/components/prism-clike") },
10
+ javascript: {
11
+ deps: ["clike"],
12
+ load: () => import("prismjs/components/prism-javascript")
13
+ },
14
+ typescript: {
15
+ deps: ["javascript"],
16
+ load: () => import("prismjs/components/prism-typescript")
17
+ },
18
+ jsx: {
19
+ deps: ["markup", "javascript"],
20
+ load: () => import("prismjs/components/prism-jsx")
21
+ },
22
+ tsx: {
23
+ deps: ["jsx", "typescript"],
24
+ load: () => import("prismjs/components/prism-tsx")
25
+ },
26
+ css: { load: () => import("prismjs/components/prism-css") },
27
+ bash: { load: () => import("prismjs/components/prism-bash") },
28
+ json: { load: () => import("prismjs/components/prism-json") },
29
+ python: { load: () => import("prismjs/components/prism-python") },
30
+ java: {
31
+ deps: ["clike"],
32
+ load: () => import("prismjs/components/prism-java")
33
+ },
34
+ sql: { load: () => import("prismjs/components/prism-sql") }
35
+ };
36
+ let p = null;
37
+ const m = /* @__PURE__ */ new Map();
38
+ function y(r) {
39
+ const o = b[r];
40
+ if (!o) return Promise.resolve();
41
+ let t = m.get(r);
42
+ return t || (t = Promise.all((o.deps ?? []).map(y)).then(
43
+ () => o.load()
44
+ ), m.set(r, t)), t;
45
+ }
46
+ async function L(r) {
47
+ p || (p = import("prismjs"));
48
+ const o = await p;
49
+ return r && b[r] && await y(r).catch(() => {
50
+ m.delete(r);
51
+ }), o;
52
+ }
53
+ const z = ({
54
+ code: r,
20
55
  language: o,
21
- expanded: f = !0,
22
- noExpand: c = !1,
23
- className: m
56
+ expanded: t = !0,
57
+ noExpand: f = !1,
58
+ className: x
24
59
  }) => {
25
- const { isMobile: a } = j(), [i, g] = l(!1), [s, h] = l(
26
- !!(!c && f)
27
- ), [b, p] = l("");
28
- x(() => {
29
- if (o && d.languages[o]) {
30
- const y = d.highlight(
31
- t,
32
- d.languages[o],
33
- o
34
- );
35
- p(y);
36
- } else
37
- p(t);
38
- }, [t, o]);
39
- const u = () => {
40
- navigator.clipboard.writeText(t).then(() => {
60
+ const { isMobile: s } = I(), [i, g] = c(!1), [l, k] = c(
61
+ !!(!f && t)
62
+ ), [v, h] = c("");
63
+ C(() => {
64
+ let u = !1;
65
+ return L(o).then((n) => {
66
+ u || (o && n.languages[o] ? h(
67
+ n.highlight(r, n.languages[o], o)
68
+ ) : h(r));
69
+ }), () => {
70
+ u = !0;
71
+ };
72
+ }, [r, o]);
73
+ const w = () => {
74
+ navigator.clipboard.writeText(r).then(() => {
41
75
  g(!0), setTimeout(() => g(!1), 2e3);
42
76
  });
43
77
  };
44
- return /* @__PURE__ */ n(
78
+ return /* @__PURE__ */ d(
45
79
  "div",
46
80
  {
47
81
  "data-tucu": "code-block",
48
- className: e(
82
+ className: a(
49
83
  "overflow-x-auto min-h-[150px] relative rounded-xl border mt-4",
50
84
  "bg-gray-100 dark:bg-gray-800 border-border hover:border-gray-400 dark:hover:border-gray-600",
51
- s ? "h-fit max-h-[300px] transition-all duration-300" : "h-full transition-all duration-300",
52
- m
85
+ l ? "h-fit max-h-[300px] transition-all duration-300" : "h-full transition-all duration-300",
86
+ x
53
87
  ),
54
88
  children: [
55
- /* @__PURE__ */ n(
89
+ /* @__PURE__ */ d(
56
90
  "div",
57
91
  {
58
- className: e(
92
+ className: a(
59
93
  "absolute z-10 top-1 right-1 p-2 flex justify-end items-center w-full gap-1",
60
- a && "flex-col items-end"
94
+ s && "flex-col items-end"
61
95
  ),
62
96
  children: [
63
- /* @__PURE__ */ n(
97
+ /* @__PURE__ */ d(
64
98
  "button",
65
99
  {
66
- onClick: u,
100
+ onClick: w,
67
101
  "aria-label": i ? "Copied to clipboard" : "Copy to clipboard",
68
- className: e(
102
+ className: a(
69
103
  "code-block-btn p-2 bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-brand focus:ring-offset-2 dark:focus:ring-offset-gray-800",
70
- a && "p-1 w-8 h-8"
104
+ s && "p-1 w-8 h-8"
71
105
  ),
72
106
  title: "Copy to clipboard",
73
107
  children: [
74
- i ? /* @__PURE__ */ r(v, { className: "w-4 h-4 text-green-500" }) : /* @__PURE__ */ r(C, { className: "w-4 h-4 text-gray-600 dark:text-gray-300" }),
75
- /* @__PURE__ */ r("span", { className: "sr-only", children: i ? "Copied!" : "Copy code" })
108
+ i ? /* @__PURE__ */ e(j, { className: "w-4 h-4 text-green-500" }) : /* @__PURE__ */ e(M, { className: "w-4 h-4 text-gray-600 dark:text-gray-300" }),
109
+ /* @__PURE__ */ e("span", { className: "sr-only", children: i ? "Copied!" : "Copy code" })
76
110
  ]
77
111
  }
78
112
  ),
79
- !c && /* @__PURE__ */ r(
113
+ !f && /* @__PURE__ */ e(
80
114
  "button",
81
115
  {
82
- onClick: () => h(!s),
83
- className: e(
116
+ onClick: () => k(!l),
117
+ className: a(
84
118
  "code-block-btn p-2 bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-brand focus:ring-offset-2 dark:focus:ring-offset-gray-800",
85
- a && "p-1 w-8 h-8"
119
+ s && "p-1 w-8 h-8"
86
120
  ),
87
121
  title: "Expand/Collapse",
88
- children: s ? /* @__PURE__ */ r(N, { className: "w-4 h-4 text-gray-600 dark:text-gray-300" }) : /* @__PURE__ */ r(w, { className: "w-4 h-4 text-gray-600 dark:text-gray-300" })
122
+ children: l ? /* @__PURE__ */ e(E, { className: "w-4 h-4 text-gray-600 dark:text-gray-300" }) : /* @__PURE__ */ e(P, { className: "w-4 h-4 text-gray-600 dark:text-gray-300" })
89
123
  }
90
124
  ),
91
- o && /* @__PURE__ */ r(
125
+ o && /* @__PURE__ */ e(
92
126
  "div",
93
127
  {
94
- className: e(
128
+ className: a(
95
129
  "code-block-btn p-2 text-sm font-mono bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 hover:pointer dark:hover:bg-gray-600 rounded-md transition-colors focus:outline-none focus:ring-2 focus:ring-brand focus:ring-offset-2 dark:focus:ring-offset-gray-800",
96
- a && "w-max max-w-11 h-8"
130
+ s && "w-max max-w-11 h-8"
97
131
  ),
98
132
  children: o
99
133
  }
@@ -101,15 +135,15 @@ const G = ({
101
135
  ]
102
136
  }
103
137
  ),
104
- /* @__PURE__ */ r(
105
- k,
138
+ /* @__PURE__ */ e(
139
+ N,
106
140
  {
107
141
  className: "overflow-x-auto h-full p-4 pr-16 pt-4 lg:pr-4 lg:pt-16 transition-all duration-300",
108
- children: /* @__PURE__ */ r("pre", { className: "text-xs whitespace-pre-wrap font-mono block", children: /* @__PURE__ */ r(
142
+ children: /* @__PURE__ */ e("pre", { className: "text-xs whitespace-pre-wrap font-mono block", children: /* @__PURE__ */ e(
109
143
  "code",
110
144
  {
111
145
  className: `language-${o || "text"}`,
112
- dangerouslySetInnerHTML: { __html: b }
146
+ dangerouslySetInnerHTML: { __html: v }
113
147
  }
114
148
  ) })
115
149
  }
@@ -119,6 +153,6 @@ const G = ({
119
153
  );
120
154
  };
121
155
  export {
122
- G as CodeBlock,
123
- G as default
156
+ z as CodeBlock,
157
+ z as default
124
158
  };
@@ -1,6 +1,5 @@
1
- import * as o from "react-use/lib/factory/createBreakpoint";
2
- import { unwrapCjsDefault as t } from "./internal/cjs-esm-interop.mjs";
3
- const e = t(o), r = {
1
+ import { useState as s, useEffect as d } from "react";
2
+ const a = {
4
3
  xs: 480,
5
4
  sm: 640,
6
5
  md: 768,
@@ -9,7 +8,24 @@ const e = t(o), r = {
9
8
  "2xl": 1440,
10
9
  "3xl": 1780,
11
10
  "4xl": 2160
12
- }, s = e(r);
11
+ }, i = Object.entries(a).sort(
12
+ (n, e) => n[1] - e[1]
13
+ );
14
+ function r(n) {
15
+ let e = i[0][0];
16
+ for (const [t, o] of i)
17
+ n >= o && (e = t);
18
+ return e;
19
+ }
20
+ function f() {
21
+ const [n, e] = s(
22
+ () => r(typeof window < "u" ? window.innerWidth : 0)
23
+ );
24
+ return d(() => {
25
+ const t = () => e(r(window.innerWidth));
26
+ return t(), window.addEventListener("resize", t), () => window.removeEventListener("resize", t);
27
+ }, []), n;
28
+ }
13
29
  export {
14
- s as useBreakpoint
30
+ f as useBreakpoint
15
31
  };
@@ -1,8 +1,19 @@
1
- import * as o from "react-use/lib/useClickAway";
2
- import { unwrapCjsDefault as r } from "./internal/cjs-esm-interop.mjs";
3
- const e = r(
4
- o
5
- );
1
+ import { useRef as s, useEffect as a } from "react";
2
+ const d = ["mousedown", "touchstart"];
3
+ function i(r, n, e = d) {
4
+ const c = s(n);
5
+ c.current = n, a(() => {
6
+ const o = (t) => {
7
+ const u = r.current;
8
+ u && !u.contains(t.target) && c.current(t);
9
+ };
10
+ return e.forEach((t) => document.addEventListener(t, o)), () => {
11
+ e.forEach(
12
+ (t) => document.removeEventListener(t, o)
13
+ );
14
+ };
15
+ }, [r, e]);
16
+ }
6
17
  export {
7
- e as useClickAway
18
+ i as useClickAway
8
19
  };
@@ -1,8 +1,47 @@
1
- import * as o from "react-use/lib/useCopyToClipboard";
2
- import { unwrapCjsDefault as p } from "./internal/cjs-esm-interop.mjs";
3
- const a = p(
4
- o
5
- );
1
+ import { useState as c, useCallback as i } from "react";
2
+ function s(t) {
3
+ const e = document.createElement("textarea");
4
+ e.value = t, e.style.position = "fixed", e.style.opacity = "0", document.body.appendChild(e), e.focus(), e.select();
5
+ let r = !1;
6
+ try {
7
+ r = document.execCommand("copy");
8
+ } catch {
9
+ r = !1;
10
+ }
11
+ return document.body.removeChild(e), r;
12
+ }
13
+ function d() {
14
+ const [t, e] = c({
15
+ value: void 0,
16
+ error: void 0,
17
+ noUserInteraction: !0
18
+ }), r = i((o) => {
19
+ if (typeof o != "string") {
20
+ e({
21
+ value: o,
22
+ error: new Error(
23
+ `Cannot copy typeof ${typeof o} to clipboard, must be a string`
24
+ ),
25
+ noUserInteraction: !0
26
+ });
27
+ return;
28
+ }
29
+ if (navigator.clipboard && window.isSecureContext) {
30
+ navigator.clipboard.writeText(o).then(
31
+ () => e({ value: o, error: void 0, noUserInteraction: !1 }),
32
+ (a) => e({ value: o, error: a, noUserInteraction: !1 })
33
+ );
34
+ return;
35
+ }
36
+ const n = s(o);
37
+ e({
38
+ value: o,
39
+ error: n ? void 0 : new Error("Copy failed"),
40
+ noUserInteraction: !1
41
+ });
42
+ }, []);
43
+ return [t, r];
44
+ }
6
45
  export {
7
- a as useCopyToClipboard
46
+ d as useCopyToClipboard
8
47
  };
@@ -1,6 +1,26 @@
1
- import * as e from "react-use/lib/useMeasure";
2
- import { unwrapCjsDefault as r } from "./internal/cjs-esm-interop.mjs";
3
- const s = r(e);
1
+ import { useState as n, useEffect as m } from "react";
2
+ const p = {
3
+ x: 0,
4
+ y: 0,
5
+ width: 0,
6
+ height: 0,
7
+ top: 0,
8
+ right: 0,
9
+ bottom: 0,
10
+ left: 0
11
+ };
12
+ function a() {
13
+ const [e, o] = n(null), [s, i] = n(p);
14
+ return m(() => {
15
+ if (!e || typeof ResizeObserver > "u") return;
16
+ const t = new ResizeObserver(([r]) => {
17
+ if (!r) return;
18
+ const { x: c, y: u, width: f, height: h, top: l, right: d, bottom: g, left: b } = r.target.getBoundingClientRect();
19
+ i({ x: c, y: u, width: f, height: h, top: l, right: d, bottom: g, left: b });
20
+ });
21
+ return t.observe(e), () => t.disconnect();
22
+ }, [e]), [o, s];
23
+ }
4
24
  export {
5
- s as useMeasure
25
+ a as useMeasure
6
26
  };
package/index.d.ts CHANGED
@@ -47,12 +47,10 @@ import * as TanstackTable from '@tanstack/react-table';
47
47
  import { TooltipContentProps } from 'recharts';
48
48
  import { Updater } from '@tanstack/react-table';
49
49
  import { UseBoundStore } from 'zustand';
50
- import * as useCopyToClipboardModule from 'react-use/lib/useCopyToClipboard';
51
50
  import { useEffect } from 'react';
52
51
  import { useFormContext } from 'react-hook-form';
53
52
  import { UseFormProps } from 'react-hook-form';
54
53
  import { UseFormReturn } from 'react-hook-form';
55
- import * as useMeasureModule from 'react-use/lib/useMeasure';
56
54
  import { VisibilityState } from '@tanstack/react-table';
57
55
 
58
56
  export declare const acceptedFileType: {
@@ -911,6 +909,8 @@ export declare function CleanLayout({ children, className, }: {
911
909
  className?: string;
912
910
  }): JSX.Element;
913
911
 
912
+ declare type ClickAwayEvent = MouseEvent | TouchEvent;
913
+
914
914
  export declare function Close(props: React.SVGAttributes<SVGElement>): JSX.Element;
915
915
 
916
916
  export declare const CodeBlock: ({ code, language, expanded, noExpand, className, }: {
@@ -1119,6 +1119,12 @@ export declare function convertColumns<TData extends RowData, TValue = unknown>(
1119
1119
 
1120
1120
  export declare const Copy: React.FC<React.SVGAttributes<SVGElement>>;
1121
1121
 
1122
+ export declare type CopyToClipboardState = {
1123
+ value?: string;
1124
+ error?: Error;
1125
+ noUserInteraction: boolean;
1126
+ };
1127
+
1122
1128
  export declare function CurrencySwapIcons({ from, to }: CurrencySwapIconsProps): JSX.Element;
1123
1129
 
1124
1130
  export declare interface CurrencySwapIconsProps {
@@ -3604,6 +3610,17 @@ export declare interface ManualPaginationState {
3604
3610
  pagination?: PaginationState;
3605
3611
  }
3606
3612
 
3613
+ export declare type MeasureRect = {
3614
+ x: number;
3615
+ y: number;
3616
+ width: number;
3617
+ height: number;
3618
+ top: number;
3619
+ right: number;
3620
+ bottom: number;
3621
+ left: number;
3622
+ };
3623
+
3607
3624
  export declare function MediaPlayIcon(props: React.SVGAttributes<SVGElement>): JSX.Element;
3608
3625
 
3609
3626
  export declare function MenuItem({ name, icon, path, href, dropdownItems, isActive: isActiveProps, hide, onClick, }: MenuItemProps): JSX.Element;
@@ -5267,11 +5284,11 @@ export declare function Usdc(props: React.SVGAttributes<SVGElement>): JSX.Elemen
5267
5284
 
5268
5285
  export declare const useAnchorScroll: () => null;
5269
5286
 
5270
- export declare const useBreakpoint: () => string;
5287
+ export declare function useBreakpoint(): string;
5271
5288
 
5272
5289
  export declare function useChartTheme(): ChartTheme;
5273
5290
 
5274
- export declare const useClickAway: <E extends Event = Event>(ref: RefObject<HTMLElement | null>, onClickAway: (event: E) => void, events?: string[]) => void;
5291
+ export declare function useClickAway<T extends HTMLElement = HTMLElement>(ref: RefObject<T | null>, onClickAway: (event: ClickAwayEvent) => void, events?: string[]): void;
5275
5292
 
5276
5293
  /**
5277
5294
  * useComponentEventListener
@@ -5294,7 +5311,10 @@ export declare const useComponentEventListener: (id: string) => {
5294
5311
  };
5295
5312
  };
5296
5313
 
5297
- export declare const useCopyToClipboard: () => [useCopyToClipboardModule.CopyToClipboardState, (value: string) => void];
5314
+ export declare function useCopyToClipboard(): [
5315
+ CopyToClipboardState,
5316
+ (text: string) => void
5317
+ ];
5298
5318
 
5299
5319
  /**
5300
5320
  * Hook for the data table context.
@@ -5418,7 +5438,10 @@ export declare const useIsomorphicLayoutEffect: typeof useEffect;
5418
5438
 
5419
5439
  export declare function useLockBodyScroll(freezeBodyScroll: boolean): void;
5420
5440
 
5421
- export declare const useMeasure: <E extends Element = Element>() => useMeasureModule.UseMeasureResult<E>;
5441
+ export declare function useMeasure<T extends HTMLElement = HTMLElement>(): [
5442
+ (node: T | null) => void,
5443
+ MeasureRect
5444
+ ];
5422
5445
 
5423
5446
  export declare const usePublicErrorRoutesConfig: () => {
5424
5447
  key: AppErrorPage;