@djangocfg/ui-tools 2.1.210 → 2.1.213

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.
Files changed (91) hide show
  1. package/dist/JsonTree-EFWAIIUV.mjs +5 -0
  2. package/dist/{JsonTree-5CRPHRP5.mjs.map → JsonTree-EFWAIIUV.mjs.map} +1 -1
  3. package/dist/JsonTree-LULSGFAW.cjs +11 -0
  4. package/dist/{JsonTree-IIVOSSVZ.cjs.map → JsonTree-LULSGFAW.cjs.map} +1 -1
  5. package/dist/JsonTree-MLET23ZA.css +6 -0
  6. package/dist/JsonTree-MLET23ZA.css.map +1 -0
  7. package/dist/{Mermaid.client-HG24D5KB.mjs → Mermaid.client-5EKULAUZ.mjs} +12 -22
  8. package/dist/Mermaid.client-5EKULAUZ.mjs.map +1 -0
  9. package/dist/Mermaid.client-DDXWXZXY.css +6 -0
  10. package/dist/Mermaid.client-DDXWXZXY.css.map +1 -0
  11. package/dist/{Mermaid.client-2TAFAXPW.cjs → Mermaid.client-Z25LMNPA.cjs} +12 -22
  12. package/dist/Mermaid.client-Z25LMNPA.cjs.map +1 -0
  13. package/dist/{PlaygroundLayout-XYMJBNT4.cjs → PlaygroundLayout-F47LFRYB.cjs} +21 -20
  14. package/dist/PlaygroundLayout-F47LFRYB.cjs.map +1 -0
  15. package/dist/{PlaygroundLayout-DWRNA2QM.mjs → PlaygroundLayout-NFNVEPIL.mjs} +5 -4
  16. package/dist/PlaygroundLayout-NFNVEPIL.mjs.map +1 -0
  17. package/dist/PlaygroundLayout-O52C6HK5.css +6 -0
  18. package/dist/PlaygroundLayout-O52C6HK5.css.map +1 -0
  19. package/dist/PrettyCode.client-GWFAIVFN.css +6 -0
  20. package/dist/PrettyCode.client-GWFAIVFN.css.map +1 -0
  21. package/dist/{PrettyCode.client-TCVEDDCJ.cjs → PrettyCode.client-VH6C6OC5.cjs} +15 -18
  22. package/dist/PrettyCode.client-VH6C6OC5.cjs.map +1 -0
  23. package/dist/{PrettyCode.client-RHOS5D6V.mjs → PrettyCode.client-VNTMCHXR.mjs} +16 -19
  24. package/dist/PrettyCode.client-VNTMCHXR.mjs.map +1 -0
  25. package/dist/{chunk-QP6QAK3F.cjs → chunk-3IIZ5ESQ.cjs} +3 -3
  26. package/dist/{chunk-QP6QAK3F.cjs.map → chunk-3IIZ5ESQ.cjs.map} +1 -1
  27. package/dist/chunk-3Q2X3CYQ.mjs +208 -0
  28. package/dist/chunk-3Q2X3CYQ.mjs.map +1 -0
  29. package/dist/chunk-G2A6SX5L.cjs +235 -0
  30. package/dist/chunk-G2A6SX5L.cjs.map +1 -0
  31. package/dist/chunk-LJ2VEBBZ.cjs +210 -0
  32. package/dist/chunk-LJ2VEBBZ.cjs.map +1 -0
  33. package/dist/chunk-MBFBVGUP.mjs +229 -0
  34. package/dist/chunk-MBFBVGUP.mjs.map +1 -0
  35. package/dist/{chunk-52WXASRO.mjs → chunk-SQLEKTT2.mjs} +8 -8
  36. package/dist/chunk-SQLEKTT2.mjs.map +1 -0
  37. package/dist/{chunk-FXFTJW2Y.mjs → chunk-TROOIHOR.mjs} +3 -3
  38. package/dist/{chunk-FXFTJW2Y.mjs.map → chunk-TROOIHOR.mjs.map} +1 -1
  39. package/dist/{chunk-DF6ORMTF.cjs → chunk-ZQX7KIC5.cjs} +8 -8
  40. package/dist/chunk-ZQX7KIC5.cjs.map +1 -0
  41. package/dist/{components-4Z2JIRZI.cjs → components-4FGDYL7K.cjs} +12 -12
  42. package/dist/{components-4Z2JIRZI.cjs.map → components-4FGDYL7K.cjs.map} +1 -1
  43. package/dist/{components-YWYUZQIH.mjs → components-MPEPRVCT.mjs} +3 -3
  44. package/dist/{components-YWYUZQIH.mjs.map → components-MPEPRVCT.mjs.map} +1 -1
  45. package/dist/index.cjs +53 -52
  46. package/dist/index.cjs.map +1 -1
  47. package/dist/index.css +6 -0
  48. package/dist/index.css.map +1 -0
  49. package/dist/index.d.cts +8 -7
  50. package/dist/index.d.ts +8 -7
  51. package/dist/index.mjs +14 -13
  52. package/dist/index.mjs.map +1 -1
  53. package/package.json +6 -6
  54. package/src/components/FloatingToolbar/FloatingToolbar.css +5 -0
  55. package/src/components/FloatingToolbar/actions/CopyAction.tsx +22 -0
  56. package/src/components/FloatingToolbar/actions/DownloadAction.tsx +46 -0
  57. package/src/components/FloatingToolbar/actions/ExpandAction.tsx +25 -0
  58. package/src/components/FloatingToolbar/actions/FullscreenAction.tsx +30 -0
  59. package/src/components/FloatingToolbar/actions/index.ts +4 -0
  60. package/src/components/FloatingToolbar/hooks/useElementCorner.ts +84 -0
  61. package/src/components/FloatingToolbar/hooks/useScrollIsolation.ts +62 -0
  62. package/src/components/FloatingToolbar/index.tsx +131 -0
  63. package/src/styles/index.css +1 -0
  64. package/src/tools/AudioPlayer/components/HybridCompactPlayer.tsx +1 -1
  65. package/src/tools/AudioPlayer/components/HybridWaveform.tsx +10 -10
  66. package/src/tools/JsonTree/JsonTree.story.tsx +3 -2
  67. package/src/tools/JsonTree/README.md +60 -0
  68. package/src/tools/JsonTree/components/JsonContent.tsx +98 -0
  69. package/src/tools/JsonTree/components/JsonToolbar.tsx +88 -0
  70. package/src/tools/JsonTree/hooks/useElementCorner.ts +84 -0
  71. package/src/tools/JsonTree/hooks/useJsonExpand.ts +50 -0
  72. package/src/tools/JsonTree/hooks/useNavbarHeight.ts +83 -0
  73. package/src/tools/JsonTree/index.tsx +46 -278
  74. package/src/tools/JsonTree/types.ts +65 -0
  75. package/src/tools/Mermaid/Mermaid.client.tsx +12 -20
  76. package/src/tools/PrettyCode/PrettyCode.client.tsx +19 -19
  77. package/src/tools/PrettyCode/PrettyCode.story.tsx +476 -41
  78. package/dist/JsonTree-5CRPHRP5.mjs +0 -4
  79. package/dist/JsonTree-IIVOSSVZ.cjs +0 -10
  80. package/dist/Mermaid.client-2TAFAXPW.cjs.map +0 -1
  81. package/dist/Mermaid.client-HG24D5KB.mjs.map +0 -1
  82. package/dist/PlaygroundLayout-DWRNA2QM.mjs.map +0 -1
  83. package/dist/PlaygroundLayout-XYMJBNT4.cjs.map +0 -1
  84. package/dist/PrettyCode.client-RHOS5D6V.mjs.map +0 -1
  85. package/dist/PrettyCode.client-TCVEDDCJ.cjs.map +0 -1
  86. package/dist/chunk-52WXASRO.mjs.map +0 -1
  87. package/dist/chunk-DF6ORMTF.cjs.map +0 -1
  88. package/dist/chunk-DFWXRCIC.cjs +0 -242
  89. package/dist/chunk-DFWXRCIC.cjs.map +0 -1
  90. package/dist/chunk-XXFYTIQK.mjs +0 -240
  91. package/dist/chunk-XXFYTIQK.mjs.map +0 -1
@@ -0,0 +1,65 @@
1
+ import { CommonExternalProps } from 'react-json-tree';
2
+
3
+ export type JsonTreeMode = 'full' | 'compact' | 'inline';
4
+
5
+ export interface JsonTreeConfig {
6
+ /** Maximum depth to expand automatically (default: 2) */
7
+ maxAutoExpandDepth?: number;
8
+ /** Maximum items in array to auto-expand (default: 10) */
9
+ maxAutoExpandArrayItems?: number;
10
+ /** Maximum object keys to auto-expand (default: 5) */
11
+ maxAutoExpandObjectKeys?: number;
12
+ /** Maximum string length before truncation (default: 200) */
13
+ maxStringLength?: number;
14
+ /** Collection limit for performance (default: 50) */
15
+ collectionLimit?: number;
16
+ /** Whether to show collection info (array length, object keys count) */
17
+ showCollectionInfo?: boolean;
18
+ /** Whether to show expand/collapse all buttons */
19
+ showExpandControls?: boolean;
20
+ /** Whether to show copy/download buttons */
21
+ showActionButtons?: boolean;
22
+ /** Custom CSS classes for the container */
23
+ className?: string;
24
+ /** Whether to preserve object key order (default: true) */
25
+ preserveKeyOrder?: boolean;
26
+ }
27
+
28
+ export interface JsonTreeComponentProps {
29
+ title?: string;
30
+ data: unknown;
31
+ /**
32
+ * Extra top offset in px for the floating toolbar — use when your layout
33
+ * has a non-sticky header that useNavbarHeight cannot auto-detect.
34
+ * Adds to the auto-detected navbar height.
35
+ */
36
+ toolbarOffset?: number;
37
+ /**
38
+ * Display mode:
39
+ * - "full" (default): With toolbar and border
40
+ * - "compact": No toolbar, subtle styling
41
+ * - "inline": Minimal, no border
42
+ */
43
+ mode?: JsonTreeMode;
44
+ config?: JsonTreeConfig;
45
+ /** Override for react-json-tree props */
46
+ jsonTreeProps?: Partial<CommonExternalProps>;
47
+ }
48
+
49
+ export const MODE_PRESETS: Record<JsonTreeMode, Partial<JsonTreeConfig>> = {
50
+ full: {
51
+ showExpandControls: true,
52
+ showActionButtons: true,
53
+ showCollectionInfo: true,
54
+ },
55
+ compact: {
56
+ showExpandControls: false,
57
+ showActionButtons: false,
58
+ showCollectionInfo: true,
59
+ },
60
+ inline: {
61
+ showExpandControls: false,
62
+ showActionButtons: false,
63
+ showCollectionInfo: false,
64
+ },
65
+ };
@@ -1,10 +1,10 @@
1
1
  'use client';
2
2
 
3
- import React from 'react';
4
- import { Maximize2 } from 'lucide-react';
3
+ import React, { useRef } from 'react';
5
4
 
6
- import { Button } from '@djangocfg/ui-core/components';
7
5
  import { useResolvedTheme } from '@djangocfg/ui-core/hooks';
6
+ import { FloatingToolbar } from '../../components/FloatingToolbar';
7
+ import { CopyAction, FullscreenAction } from '../../components/FloatingToolbar/actions';
8
8
  import { MermaidFullscreenModal } from './components/MermaidFullscreenModal';
9
9
  import { useMermaidFullscreen } from './hooks/useMermaidFullscreen';
10
10
  import { useMermaidRenderer } from './hooks/useMermaidRenderer';
@@ -23,6 +23,7 @@ const Mermaid: React.FC<MermaidProps> = ({
23
23
  isCompact = false,
24
24
  fullscreen = true,
25
25
  }) => {
26
+ const containerRef = useRef<HTMLDivElement>(null);
26
27
  const theme = useResolvedTheme();
27
28
 
28
29
  // Rendering logic
@@ -41,16 +42,10 @@ const Mermaid: React.FC<MermaidProps> = ({
41
42
  handleBackdropClick,
42
43
  } = useMermaidFullscreen();
43
44
 
44
- const handleOpenFullscreen = (e: React.MouseEvent) => {
45
- e.stopPropagation();
46
- if (svgContent) {
47
- openFullscreen();
48
- }
49
- };
50
45
 
51
46
  return (
52
47
  <>
53
- <div className={`relative ${className}`}>
48
+ <div ref={containerRef} className={`relative ${className}`}>
54
49
  <div
55
50
  ref={mermaidRef}
56
51
  className="flex justify-center items-center"
@@ -62,16 +57,13 @@ const Mermaid: React.FC<MermaidProps> = ({
62
57
  </div>
63
58
  )}
64
59
 
65
- {/* Fullscreen button in bottom-right corner */}
66
- {fullscreen && svgContent && !isRendering && (
67
- <Button
68
- variant="secondary"
69
- size="icon"
70
- className="absolute bottom-2 right-2 h-8 w-8 opacity-60 hover:opacity-100 transition-opacity"
71
- onClick={handleOpenFullscreen}
72
- >
73
- <Maximize2 className="h-4 w-4" />
74
- </Button>
60
+ {svgContent && !isRendering && (
61
+ <FloatingToolbar containerRef={containerRef}>
62
+ <CopyAction value={chart} title="Copy source" />
63
+ {fullscreen && (
64
+ <FullscreenAction onToggle={openFullscreen} title="Fullscreen" />
65
+ )}
66
+ </FloatingToolbar>
75
67
  )}
76
68
  </div>
77
69
 
@@ -1,12 +1,12 @@
1
1
  'use client';
2
2
 
3
3
  import { Highlight, Language, themes } from 'prism-react-renderer';
4
- import React, { useMemo } from 'react';
5
-
6
- import { CopyButton } from '@djangocfg/ui-core/components';
4
+ import React, { useMemo, useRef } from 'react';
7
5
 
8
6
  import { useTypedT, type I18nTranslations } from '@djangocfg/i18n';
9
7
  import { useResolvedTheme } from '@djangocfg/ui-core/hooks';
8
+ import { FloatingToolbar } from '../../components/FloatingToolbar';
9
+ import { CopyAction } from '../../components/FloatingToolbar/actions';
10
10
 
11
11
  interface PrettyCodeProps {
12
12
  data: string | object;
@@ -16,9 +16,11 @@ interface PrettyCodeProps {
16
16
  inline?: boolean;
17
17
  customBg?: string; // Custom background class
18
18
  isCompact?: boolean; // Compact mode for smaller font sizes
19
+ scrollIsolation?: boolean; // Block scroll capture until user clicks (default: true)
19
20
  }
20
21
 
21
- const PrettyCode = ({ data, language, className, mode, inline = false, customBg, isCompact = false }: PrettyCodeProps) => {
22
+ const PrettyCode = ({ data, language, className, mode, inline = false, customBg, isCompact = false, scrollIsolation }: PrettyCodeProps) => {
23
+ const containerRef = useRef<HTMLDivElement>(null);
22
24
  const t = useTypedT<I18nTranslations>();
23
25
  const detectedTheme = useResolvedTheme();
24
26
 
@@ -168,21 +170,19 @@ const PrettyCode = ({ data, language, className, mode, inline = false, customBg,
168
170
  const borderClass = isDarkMode ? 'border-zinc-700' : 'border-border';
169
171
 
170
172
  return (
171
- <div className={`relative h-full ${bgClass} rounded-lg border ${borderClass} ${className || ''}`}>
172
- {/* Header with language badge and copy button */}
173
- <div className="absolute top-2 left-3 right-3 z-10 flex items-center justify-between">
174
- <span className="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-background/80 text-muted-foreground border border-border/50 backdrop-blur-sm">
175
- {displayLanguage}
176
- </span>
177
- <CopyButton
178
- value={contentJson}
179
- variant="ghost"
180
- className="h-7 w-7 bg-background/80 border border-border/50 backdrop-blur-sm"
181
- iconClassName="h-3.5 w-3.5"
182
- title={labels.copyCode}
183
- />
184
- </div>
185
-
173
+ <div ref={containerRef} className={`relative h-full ${bgClass} rounded-lg border ${borderClass} ${className || ''}`}>
174
+ <FloatingToolbar
175
+ containerRef={containerRef}
176
+ scrollIsolation={scrollIsolation}
177
+ label={
178
+ <span className="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-muted/80 text-muted-foreground border border-border/50 backdrop-blur-sm">
179
+ {displayLanguage}
180
+ </span>
181
+ }
182
+ >
183
+ <CopyAction value={contentJson} title={labels.copyCode} />
184
+ </FloatingToolbar>
185
+
186
186
  <div className="h-full overflow-auto">
187
187
  <Highlight theme={prismTheme} code={contentJson} language={normalizedLanguage as Language}>
188
188
  {({ className, style, tokens, getLineProps, getTokenProps }) => {