@almadar/ui 5.146.0 → 5.146.2

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.
@@ -16147,8 +16147,10 @@ var init_CodeBlock = __esm({
16147
16147
  ref: editableTextareaRef,
16148
16148
  defaultValue: code,
16149
16149
  onChange: (e) => {
16150
- setEditableValue(e.target.value);
16151
- onChange?.(e.target.value);
16150
+ const v = e.target.value;
16151
+ lastPropCodeRef.current = v;
16152
+ setEditableValue(v);
16153
+ onChange?.(v);
16152
16154
  },
16153
16155
  onScroll: handleEditableScroll,
16154
16156
  spellCheck: false,
@@ -21969,6 +21971,7 @@ var init_CodeRunnerPanel = __esm({
21969
21971
  const [output, setOutput] = React87.useState(null);
21970
21972
  const [error, setError] = React87.useState(null);
21971
21973
  const [isRunning, setIsRunning] = React87.useState(false);
21974
+ const [copied, setCopied] = React87.useState(false);
21972
21975
  const handleRun = React87.useCallback(async () => {
21973
21976
  if (!onRun) return;
21974
21977
  setIsRunning(true);
@@ -21991,63 +21994,75 @@ var init_CodeRunnerPanel = __esm({
21991
21994
  setOutput(null);
21992
21995
  setError(null);
21993
21996
  }, [initialCode]);
21997
+ const handleCopy = React87.useCallback(async () => {
21998
+ try {
21999
+ await navigator.clipboard.writeText(code);
22000
+ setCopied(true);
22001
+ eventBus.emit("UI:COPY_CODE", { language, success: true });
22002
+ setTimeout(() => setCopied(false), 2e3);
22003
+ } catch {
22004
+ eventBus.emit("UI:COPY_CODE", { language, success: false });
22005
+ }
22006
+ }, [code, language, eventBus]);
21994
22007
  if (!runnable || !onRun) {
21995
22008
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { className, children: /* @__PURE__ */ jsxRuntime.jsx(CodeBlock, { language, code }) });
21996
22009
  }
21997
22010
  const hasOutput = output !== null || error !== null;
21998
22011
  return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: cn("space-y-3", className), children: [
21999
- /* @__PURE__ */ jsxRuntime.jsx(
22000
- CodeBlock,
22001
- {
22002
- language,
22003
- code,
22004
- editable: true,
22005
- onChange: setCode,
22006
- showLanguageBadge: true,
22007
- showCopyButton: true
22008
- }
22009
- ),
22010
- /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", justify: "between", children: [
22011
- /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", children: [
22012
- /* @__PURE__ */ jsxRuntime.jsx(
22013
- Button,
22014
- {
22015
- variant: "primary",
22016
- size: "sm",
22017
- onClick: handleRun,
22018
- disabled: isRunning,
22019
- className: "min-w-[5rem]",
22020
- children: isRunning ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-2", children: [
22021
- /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.RotateCcw, { size: 16, className: "animate-spin" }),
22022
- t("common.loading")
22023
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-2", children: [
22024
- /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.Play, { size: 16 }),
22025
- "Run"
22026
- ] })
22027
- }
22028
- ),
22029
- /* @__PURE__ */ jsxRuntime.jsx(
22030
- Button,
22031
- {
22032
- variant: "secondary",
22033
- size: "sm",
22034
- onClick: handleReset,
22035
- disabled: isRunning,
22036
- children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-2", children: [
22037
- /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.RotateCcw, { size: 16 }),
22038
- "Reset"
22039
- ] })
22040
- }
22041
- )
22042
- ] }),
22043
- output && /* @__PURE__ */ jsxRuntime.jsxs(
22044
- Badge,
22012
+ /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "group relative", style: { height: 360 }, children: [
22013
+ /* @__PURE__ */ jsxRuntime.jsx(
22014
+ CodeBlock,
22045
22015
  {
22046
- variant: output.exitCode === 0 ? "success" : "danger",
22047
- size: "sm",
22016
+ language,
22017
+ code,
22018
+ editable: true,
22019
+ onChange: setCode,
22020
+ showLanguageBadge: true,
22021
+ showCopyButton: false,
22022
+ maxHeight: "100%"
22023
+ }
22024
+ ),
22025
+ /* @__PURE__ */ jsxRuntime.jsxs(
22026
+ HStack,
22027
+ {
22028
+ gap: "xs",
22029
+ align: "center",
22030
+ className: "absolute top-2 right-2 z-10 opacity-0 pointer-events-none group-hover:opacity-100 group-hover:pointer-events-auto focus-within:opacity-100 focus-within:pointer-events-auto transition-opacity bg-[var(--color-card)]/90 backdrop-blur-sm rounded-md p-1 shadow-sm border border-border",
22048
22031
  children: [
22049
- "Exit ",
22050
- output.exitCode
22032
+ /* @__PURE__ */ jsxRuntime.jsx(
22033
+ Button,
22034
+ {
22035
+ variant: "ghost",
22036
+ size: "sm",
22037
+ onClick: handleCopy,
22038
+ icon: copied ? LucideIcons2.Check : LucideIcons2.Copy,
22039
+ "aria-label": t("common.copy"),
22040
+ className: copied ? "text-success" : ""
22041
+ }
22042
+ ),
22043
+ /* @__PURE__ */ jsxRuntime.jsx(
22044
+ Button,
22045
+ {
22046
+ variant: "ghost",
22047
+ size: "sm",
22048
+ onClick: handleReset,
22049
+ disabled: isRunning,
22050
+ icon: LucideIcons2.RotateCcw,
22051
+ "aria-label": "Reset"
22052
+ }
22053
+ ),
22054
+ /* @__PURE__ */ jsxRuntime.jsx(
22055
+ Button,
22056
+ {
22057
+ variant: "primary",
22058
+ size: "sm",
22059
+ onClick: handleRun,
22060
+ disabled: isRunning,
22061
+ icon: isRunning ? LucideIcons2.RotateCcw : LucideIcons2.Play,
22062
+ className: isRunning ? "[&_svg]:animate-spin" : "",
22063
+ children: isRunning ? t("common.loading") : "Run"
22064
+ }
22065
+ )
22051
22066
  ]
22052
22067
  }
22053
22068
  )
@@ -22061,7 +22076,18 @@ var init_CodeRunnerPanel = __esm({
22061
22076
  className: "px-3 py-2 bg-card border-b border-border",
22062
22077
  children: [
22063
22078
  /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.Terminal, { size: 16, className: "text-muted-foreground" }),
22064
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "text-foreground font-medium", children: "Output" })
22079
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "text-foreground font-medium", children: "Output" }),
22080
+ output && /* @__PURE__ */ jsxRuntime.jsxs(
22081
+ Badge,
22082
+ {
22083
+ variant: output.exitCode === 0 ? "success" : "danger",
22084
+ size: "sm",
22085
+ children: [
22086
+ "Exit ",
22087
+ output.exitCode
22088
+ ]
22089
+ }
22090
+ )
22065
22091
  ]
22066
22092
  }
22067
22093
  ),
@@ -16073,8 +16073,10 @@ var init_CodeBlock = __esm({
16073
16073
  ref: editableTextareaRef,
16074
16074
  defaultValue: code,
16075
16075
  onChange: (e) => {
16076
- setEditableValue(e.target.value);
16077
- onChange?.(e.target.value);
16076
+ const v = e.target.value;
16077
+ lastPropCodeRef.current = v;
16078
+ setEditableValue(v);
16079
+ onChange?.(v);
16078
16080
  },
16079
16081
  onScroll: handleEditableScroll,
16080
16082
  spellCheck: false,
@@ -21895,6 +21897,7 @@ var init_CodeRunnerPanel = __esm({
21895
21897
  const [output, setOutput] = useState(null);
21896
21898
  const [error, setError] = useState(null);
21897
21899
  const [isRunning, setIsRunning] = useState(false);
21900
+ const [copied, setCopied] = useState(false);
21898
21901
  const handleRun = useCallback(async () => {
21899
21902
  if (!onRun) return;
21900
21903
  setIsRunning(true);
@@ -21917,63 +21920,75 @@ var init_CodeRunnerPanel = __esm({
21917
21920
  setOutput(null);
21918
21921
  setError(null);
21919
21922
  }, [initialCode]);
21923
+ const handleCopy = useCallback(async () => {
21924
+ try {
21925
+ await navigator.clipboard.writeText(code);
21926
+ setCopied(true);
21927
+ eventBus.emit("UI:COPY_CODE", { language, success: true });
21928
+ setTimeout(() => setCopied(false), 2e3);
21929
+ } catch {
21930
+ eventBus.emit("UI:COPY_CODE", { language, success: false });
21931
+ }
21932
+ }, [code, language, eventBus]);
21920
21933
  if (!runnable || !onRun) {
21921
21934
  return /* @__PURE__ */ jsx(Box, { className, children: /* @__PURE__ */ jsx(CodeBlock, { language, code }) });
21922
21935
  }
21923
21936
  const hasOutput = output !== null || error !== null;
21924
21937
  return /* @__PURE__ */ jsxs(Box, { className: cn("space-y-3", className), children: [
21925
- /* @__PURE__ */ jsx(
21926
- CodeBlock,
21927
- {
21928
- language,
21929
- code,
21930
- editable: true,
21931
- onChange: setCode,
21932
- showLanguageBadge: true,
21933
- showCopyButton: true
21934
- }
21935
- ),
21936
- /* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "between", children: [
21937
- /* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
21938
- /* @__PURE__ */ jsx(
21939
- Button,
21940
- {
21941
- variant: "primary",
21942
- size: "sm",
21943
- onClick: handleRun,
21944
- disabled: isRunning,
21945
- className: "min-w-[5rem]",
21946
- children: isRunning ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2", children: [
21947
- /* @__PURE__ */ jsx(RotateCcw, { size: 16, className: "animate-spin" }),
21948
- t("common.loading")
21949
- ] }) : /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2", children: [
21950
- /* @__PURE__ */ jsx(Play, { size: 16 }),
21951
- "Run"
21952
- ] })
21953
- }
21954
- ),
21955
- /* @__PURE__ */ jsx(
21956
- Button,
21957
- {
21958
- variant: "secondary",
21959
- size: "sm",
21960
- onClick: handleReset,
21961
- disabled: isRunning,
21962
- children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2", children: [
21963
- /* @__PURE__ */ jsx(RotateCcw, { size: 16 }),
21964
- "Reset"
21965
- ] })
21966
- }
21967
- )
21968
- ] }),
21969
- output && /* @__PURE__ */ jsxs(
21970
- Badge,
21938
+ /* @__PURE__ */ jsxs(Box, { className: "group relative", style: { height: 360 }, children: [
21939
+ /* @__PURE__ */ jsx(
21940
+ CodeBlock,
21971
21941
  {
21972
- variant: output.exitCode === 0 ? "success" : "danger",
21973
- size: "sm",
21942
+ language,
21943
+ code,
21944
+ editable: true,
21945
+ onChange: setCode,
21946
+ showLanguageBadge: true,
21947
+ showCopyButton: false,
21948
+ maxHeight: "100%"
21949
+ }
21950
+ ),
21951
+ /* @__PURE__ */ jsxs(
21952
+ HStack,
21953
+ {
21954
+ gap: "xs",
21955
+ align: "center",
21956
+ className: "absolute top-2 right-2 z-10 opacity-0 pointer-events-none group-hover:opacity-100 group-hover:pointer-events-auto focus-within:opacity-100 focus-within:pointer-events-auto transition-opacity bg-[var(--color-card)]/90 backdrop-blur-sm rounded-md p-1 shadow-sm border border-border",
21974
21957
  children: [
21975
- "Exit ",
21976
- output.exitCode
21958
+ /* @__PURE__ */ jsx(
21959
+ Button,
21960
+ {
21961
+ variant: "ghost",
21962
+ size: "sm",
21963
+ onClick: handleCopy,
21964
+ icon: copied ? Check : Copy,
21965
+ "aria-label": t("common.copy"),
21966
+ className: copied ? "text-success" : ""
21967
+ }
21968
+ ),
21969
+ /* @__PURE__ */ jsx(
21970
+ Button,
21971
+ {
21972
+ variant: "ghost",
21973
+ size: "sm",
21974
+ onClick: handleReset,
21975
+ disabled: isRunning,
21976
+ icon: RotateCcw,
21977
+ "aria-label": "Reset"
21978
+ }
21979
+ ),
21980
+ /* @__PURE__ */ jsx(
21981
+ Button,
21982
+ {
21983
+ variant: "primary",
21984
+ size: "sm",
21985
+ onClick: handleRun,
21986
+ disabled: isRunning,
21987
+ icon: isRunning ? RotateCcw : Play,
21988
+ className: isRunning ? "[&_svg]:animate-spin" : "",
21989
+ children: isRunning ? t("common.loading") : "Run"
21990
+ }
21991
+ )
21977
21992
  ]
21978
21993
  }
21979
21994
  )
@@ -21987,7 +22002,18 @@ var init_CodeRunnerPanel = __esm({
21987
22002
  className: "px-3 py-2 bg-card border-b border-border",
21988
22003
  children: [
21989
22004
  /* @__PURE__ */ jsx(Terminal, { size: 16, className: "text-muted-foreground" }),
21990
- /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-foreground font-medium", children: "Output" })
22005
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-foreground font-medium", children: "Output" }),
22006
+ output && /* @__PURE__ */ jsxs(
22007
+ Badge,
22008
+ {
22009
+ variant: output.exitCode === 0 ? "success" : "danger",
22010
+ size: "sm",
22011
+ children: [
22012
+ "Exit ",
22013
+ output.exitCode
22014
+ ]
22015
+ }
22016
+ )
21991
22017
  ]
21992
22018
  }
21993
22019
  ),
@@ -15851,8 +15851,10 @@ var init_CodeBlock = __esm({
15851
15851
  ref: editableTextareaRef,
15852
15852
  defaultValue: code,
15853
15853
  onChange: (e) => {
15854
- setEditableValue(e.target.value);
15855
- onChange?.(e.target.value);
15854
+ const v = e.target.value;
15855
+ lastPropCodeRef.current = v;
15856
+ setEditableValue(v);
15857
+ onChange?.(v);
15856
15858
  },
15857
15859
  onScroll: handleEditableScroll,
15858
15860
  spellCheck: false,
@@ -21556,6 +21558,7 @@ var init_CodeRunnerPanel = __esm({
21556
21558
  const [output, setOutput] = React85.useState(null);
21557
21559
  const [error, setError] = React85.useState(null);
21558
21560
  const [isRunning, setIsRunning] = React85.useState(false);
21561
+ const [copied, setCopied] = React85.useState(false);
21559
21562
  const handleRun = React85.useCallback(async () => {
21560
21563
  if (!onRun) return;
21561
21564
  setIsRunning(true);
@@ -21578,63 +21581,75 @@ var init_CodeRunnerPanel = __esm({
21578
21581
  setOutput(null);
21579
21582
  setError(null);
21580
21583
  }, [initialCode]);
21584
+ const handleCopy = React85.useCallback(async () => {
21585
+ try {
21586
+ await navigator.clipboard.writeText(code);
21587
+ setCopied(true);
21588
+ eventBus.emit("UI:COPY_CODE", { language, success: true });
21589
+ setTimeout(() => setCopied(false), 2e3);
21590
+ } catch {
21591
+ eventBus.emit("UI:COPY_CODE", { language, success: false });
21592
+ }
21593
+ }, [code, language, eventBus]);
21581
21594
  if (!runnable || !onRun) {
21582
21595
  return /* @__PURE__ */ jsxRuntime.jsx(Box, { className, children: /* @__PURE__ */ jsxRuntime.jsx(CodeBlock, { language, code }) });
21583
21596
  }
21584
21597
  const hasOutput = output !== null || error !== null;
21585
21598
  return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: cn("space-y-3", className), children: [
21586
- /* @__PURE__ */ jsxRuntime.jsx(
21587
- CodeBlock,
21588
- {
21589
- language,
21590
- code,
21591
- editable: true,
21592
- onChange: setCode,
21593
- showLanguageBadge: true,
21594
- showCopyButton: true
21595
- }
21596
- ),
21597
- /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", justify: "between", children: [
21598
- /* @__PURE__ */ jsxRuntime.jsxs(HStack, { gap: "sm", children: [
21599
- /* @__PURE__ */ jsxRuntime.jsx(
21600
- Button,
21601
- {
21602
- variant: "primary",
21603
- size: "sm",
21604
- onClick: handleRun,
21605
- disabled: isRunning,
21606
- className: "min-w-[5rem]",
21607
- children: isRunning ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-2", children: [
21608
- /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.RotateCcw, { size: 16, className: "animate-spin" }),
21609
- t("common.loading")
21610
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-2", children: [
21611
- /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.Play, { size: 16 }),
21612
- "Run"
21613
- ] })
21614
- }
21615
- ),
21616
- /* @__PURE__ */ jsxRuntime.jsx(
21617
- Button,
21618
- {
21619
- variant: "secondary",
21620
- size: "sm",
21621
- onClick: handleReset,
21622
- disabled: isRunning,
21623
- children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "inline-flex items-center gap-2", children: [
21624
- /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.RotateCcw, { size: 16 }),
21625
- "Reset"
21626
- ] })
21627
- }
21628
- )
21629
- ] }),
21630
- output && /* @__PURE__ */ jsxRuntime.jsxs(
21631
- Badge,
21599
+ /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: "group relative", style: { height: 360 }, children: [
21600
+ /* @__PURE__ */ jsxRuntime.jsx(
21601
+ CodeBlock,
21632
21602
  {
21633
- variant: output.exitCode === 0 ? "success" : "danger",
21634
- size: "sm",
21603
+ language,
21604
+ code,
21605
+ editable: true,
21606
+ onChange: setCode,
21607
+ showLanguageBadge: true,
21608
+ showCopyButton: false,
21609
+ maxHeight: "100%"
21610
+ }
21611
+ ),
21612
+ /* @__PURE__ */ jsxRuntime.jsxs(
21613
+ HStack,
21614
+ {
21615
+ gap: "xs",
21616
+ align: "center",
21617
+ className: "absolute top-2 right-2 z-10 opacity-0 pointer-events-none group-hover:opacity-100 group-hover:pointer-events-auto focus-within:opacity-100 focus-within:pointer-events-auto transition-opacity bg-[var(--color-card)]/90 backdrop-blur-sm rounded-md p-1 shadow-sm border border-border",
21635
21618
  children: [
21636
- "Exit ",
21637
- output.exitCode
21619
+ /* @__PURE__ */ jsxRuntime.jsx(
21620
+ Button,
21621
+ {
21622
+ variant: "ghost",
21623
+ size: "sm",
21624
+ onClick: handleCopy,
21625
+ icon: copied ? LucideIcons2.Check : LucideIcons2.Copy,
21626
+ "aria-label": t("common.copy"),
21627
+ className: copied ? "text-success" : ""
21628
+ }
21629
+ ),
21630
+ /* @__PURE__ */ jsxRuntime.jsx(
21631
+ Button,
21632
+ {
21633
+ variant: "ghost",
21634
+ size: "sm",
21635
+ onClick: handleReset,
21636
+ disabled: isRunning,
21637
+ icon: LucideIcons2.RotateCcw,
21638
+ "aria-label": "Reset"
21639
+ }
21640
+ ),
21641
+ /* @__PURE__ */ jsxRuntime.jsx(
21642
+ Button,
21643
+ {
21644
+ variant: "primary",
21645
+ size: "sm",
21646
+ onClick: handleRun,
21647
+ disabled: isRunning,
21648
+ icon: isRunning ? LucideIcons2.RotateCcw : LucideIcons2.Play,
21649
+ className: isRunning ? "[&_svg]:animate-spin" : "",
21650
+ children: isRunning ? t("common.loading") : "Run"
21651
+ }
21652
+ )
21638
21653
  ]
21639
21654
  }
21640
21655
  )
@@ -21648,7 +21663,18 @@ var init_CodeRunnerPanel = __esm({
21648
21663
  className: "px-3 py-2 bg-card border-b border-border",
21649
21664
  children: [
21650
21665
  /* @__PURE__ */ jsxRuntime.jsx(LucideIcons2.Terminal, { size: 16, className: "text-muted-foreground" }),
21651
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "text-foreground font-medium", children: "Output" })
21666
+ /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", className: "text-foreground font-medium", children: "Output" }),
21667
+ output && /* @__PURE__ */ jsxRuntime.jsxs(
21668
+ Badge,
21669
+ {
21670
+ variant: output.exitCode === 0 ? "success" : "danger",
21671
+ size: "sm",
21672
+ children: [
21673
+ "Exit ",
21674
+ output.exitCode
21675
+ ]
21676
+ }
21677
+ )
21652
21678
  ]
21653
21679
  }
21654
21680
  ),
@@ -15777,8 +15777,10 @@ var init_CodeBlock = __esm({
15777
15777
  ref: editableTextareaRef,
15778
15778
  defaultValue: code,
15779
15779
  onChange: (e) => {
15780
- setEditableValue(e.target.value);
15781
- onChange?.(e.target.value);
15780
+ const v = e.target.value;
15781
+ lastPropCodeRef.current = v;
15782
+ setEditableValue(v);
15783
+ onChange?.(v);
15782
15784
  },
15783
15785
  onScroll: handleEditableScroll,
15784
15786
  spellCheck: false,
@@ -21482,6 +21484,7 @@ var init_CodeRunnerPanel = __esm({
21482
21484
  const [output, setOutput] = useState(null);
21483
21485
  const [error, setError] = useState(null);
21484
21486
  const [isRunning, setIsRunning] = useState(false);
21487
+ const [copied, setCopied] = useState(false);
21485
21488
  const handleRun = useCallback(async () => {
21486
21489
  if (!onRun) return;
21487
21490
  setIsRunning(true);
@@ -21504,63 +21507,75 @@ var init_CodeRunnerPanel = __esm({
21504
21507
  setOutput(null);
21505
21508
  setError(null);
21506
21509
  }, [initialCode]);
21510
+ const handleCopy = useCallback(async () => {
21511
+ try {
21512
+ await navigator.clipboard.writeText(code);
21513
+ setCopied(true);
21514
+ eventBus.emit("UI:COPY_CODE", { language, success: true });
21515
+ setTimeout(() => setCopied(false), 2e3);
21516
+ } catch {
21517
+ eventBus.emit("UI:COPY_CODE", { language, success: false });
21518
+ }
21519
+ }, [code, language, eventBus]);
21507
21520
  if (!runnable || !onRun) {
21508
21521
  return /* @__PURE__ */ jsx(Box, { className, children: /* @__PURE__ */ jsx(CodeBlock, { language, code }) });
21509
21522
  }
21510
21523
  const hasOutput = output !== null || error !== null;
21511
21524
  return /* @__PURE__ */ jsxs(Box, { className: cn("space-y-3", className), children: [
21512
- /* @__PURE__ */ jsx(
21513
- CodeBlock,
21514
- {
21515
- language,
21516
- code,
21517
- editable: true,
21518
- onChange: setCode,
21519
- showLanguageBadge: true,
21520
- showCopyButton: true
21521
- }
21522
- ),
21523
- /* @__PURE__ */ jsxs(HStack, { gap: "sm", justify: "between", children: [
21524
- /* @__PURE__ */ jsxs(HStack, { gap: "sm", children: [
21525
- /* @__PURE__ */ jsx(
21526
- Button,
21527
- {
21528
- variant: "primary",
21529
- size: "sm",
21530
- onClick: handleRun,
21531
- disabled: isRunning,
21532
- className: "min-w-[5rem]",
21533
- children: isRunning ? /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2", children: [
21534
- /* @__PURE__ */ jsx(RotateCcw, { size: 16, className: "animate-spin" }),
21535
- t("common.loading")
21536
- ] }) : /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2", children: [
21537
- /* @__PURE__ */ jsx(Play, { size: 16 }),
21538
- "Run"
21539
- ] })
21540
- }
21541
- ),
21542
- /* @__PURE__ */ jsx(
21543
- Button,
21544
- {
21545
- variant: "secondary",
21546
- size: "sm",
21547
- onClick: handleReset,
21548
- disabled: isRunning,
21549
- children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2", children: [
21550
- /* @__PURE__ */ jsx(RotateCcw, { size: 16 }),
21551
- "Reset"
21552
- ] })
21553
- }
21554
- )
21555
- ] }),
21556
- output && /* @__PURE__ */ jsxs(
21557
- Badge,
21525
+ /* @__PURE__ */ jsxs(Box, { className: "group relative", style: { height: 360 }, children: [
21526
+ /* @__PURE__ */ jsx(
21527
+ CodeBlock,
21558
21528
  {
21559
- variant: output.exitCode === 0 ? "success" : "danger",
21560
- size: "sm",
21529
+ language,
21530
+ code,
21531
+ editable: true,
21532
+ onChange: setCode,
21533
+ showLanguageBadge: true,
21534
+ showCopyButton: false,
21535
+ maxHeight: "100%"
21536
+ }
21537
+ ),
21538
+ /* @__PURE__ */ jsxs(
21539
+ HStack,
21540
+ {
21541
+ gap: "xs",
21542
+ align: "center",
21543
+ className: "absolute top-2 right-2 z-10 opacity-0 pointer-events-none group-hover:opacity-100 group-hover:pointer-events-auto focus-within:opacity-100 focus-within:pointer-events-auto transition-opacity bg-[var(--color-card)]/90 backdrop-blur-sm rounded-md p-1 shadow-sm border border-border",
21561
21544
  children: [
21562
- "Exit ",
21563
- output.exitCode
21545
+ /* @__PURE__ */ jsx(
21546
+ Button,
21547
+ {
21548
+ variant: "ghost",
21549
+ size: "sm",
21550
+ onClick: handleCopy,
21551
+ icon: copied ? Check : Copy,
21552
+ "aria-label": t("common.copy"),
21553
+ className: copied ? "text-success" : ""
21554
+ }
21555
+ ),
21556
+ /* @__PURE__ */ jsx(
21557
+ Button,
21558
+ {
21559
+ variant: "ghost",
21560
+ size: "sm",
21561
+ onClick: handleReset,
21562
+ disabled: isRunning,
21563
+ icon: RotateCcw,
21564
+ "aria-label": "Reset"
21565
+ }
21566
+ ),
21567
+ /* @__PURE__ */ jsx(
21568
+ Button,
21569
+ {
21570
+ variant: "primary",
21571
+ size: "sm",
21572
+ onClick: handleRun,
21573
+ disabled: isRunning,
21574
+ icon: isRunning ? RotateCcw : Play,
21575
+ className: isRunning ? "[&_svg]:animate-spin" : "",
21576
+ children: isRunning ? t("common.loading") : "Run"
21577
+ }
21578
+ )
21564
21579
  ]
21565
21580
  }
21566
21581
  )
@@ -21574,7 +21589,18 @@ var init_CodeRunnerPanel = __esm({
21574
21589
  className: "px-3 py-2 bg-card border-b border-border",
21575
21590
  children: [
21576
21591
  /* @__PURE__ */ jsx(Terminal, { size: 16, className: "text-muted-foreground" }),
21577
- /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-foreground font-medium", children: "Output" })
21592
+ /* @__PURE__ */ jsx(Typography, { variant: "small", className: "text-foreground font-medium", children: "Output" }),
21593
+ output && /* @__PURE__ */ jsxs(
21594
+ Badge,
21595
+ {
21596
+ variant: output.exitCode === 0 ? "success" : "danger",
21597
+ size: "sm",
21598
+ children: [
21599
+ "Exit ",
21600
+ output.exitCode
21601
+ ]
21602
+ }
21603
+ )
21578
21604
  ]
21579
21605
  }
21580
21606
  ),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "5.146.0",
3
+ "version": "5.146.2",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [