@almadar/ui 5.13.3 → 5.14.1

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.
@@ -13941,6 +13941,8 @@ var init_CodeBlock = __esm({
13941
13941
  collapsedRef.current = collapsed;
13942
13942
  const foldStartMapRef = useRef(foldStartMap);
13943
13943
  foldStartMapRef.current = foldStartMap;
13944
+ const hiddenLinesRef = useRef(hiddenLines);
13945
+ hiddenLinesRef.current = hiddenLines;
13944
13946
  const toggleFold = useCallback((lineNum) => {
13945
13947
  setCollapsed((prev) => {
13946
13948
  const next = new Set(prev);
@@ -14053,6 +14055,60 @@ var init_CodeBlock = __esm({
14053
14055
  eventBus.emit("UI:COPY_CODE", { language, success: false });
14054
14056
  }
14055
14057
  };
14058
+ const handleSelectionCopy = useCallback((e) => {
14059
+ if (hiddenLinesRef.current.size === 0) return;
14060
+ const sel = typeof window !== "undefined" ? window.getSelection() : null;
14061
+ if (!sel || sel.rangeCount === 0 || sel.isCollapsed) return;
14062
+ const lineOf = (node) => {
14063
+ const start = node instanceof HTMLElement ? node : node?.parentElement ?? null;
14064
+ const lineEl = start?.closest("[data-line]");
14065
+ if (!lineEl) return null;
14066
+ const n = parseInt(lineEl.getAttribute("data-line") ?? "", 10);
14067
+ return Number.isNaN(n) ? null : n;
14068
+ };
14069
+ const range = sel.getRangeAt(0);
14070
+ let a = lineOf(range.startContainer);
14071
+ let b = lineOf(range.endContainer);
14072
+ if (a === null || b === null) {
14073
+ const container = codeRef.current;
14074
+ if (!container) return;
14075
+ let min = Infinity, max = -Infinity;
14076
+ container.querySelectorAll("[data-line]").forEach((el) => {
14077
+ if (!sel.containsNode(el, true)) return;
14078
+ const n = parseInt(el.getAttribute("data-line") ?? "", 10);
14079
+ if (!Number.isNaN(n)) {
14080
+ min = Math.min(min, n);
14081
+ max = Math.max(max, n);
14082
+ }
14083
+ });
14084
+ if (min === Infinity) return;
14085
+ a = a ?? min;
14086
+ b = b ?? max;
14087
+ }
14088
+ if (a > b) [a, b] = [b, a];
14089
+ let touchesFold = false;
14090
+ for (let i = a; i <= b; i++) {
14091
+ if (hiddenLinesRef.current.has(i) || foldStartMapRef.current.has(i) && collapsedRef.current.has(i)) {
14092
+ touchesFold = true;
14093
+ break;
14094
+ }
14095
+ }
14096
+ if (!touchesFold) return;
14097
+ let endLine = b;
14098
+ let changed = true;
14099
+ while (changed) {
14100
+ changed = false;
14101
+ foldStartMapRef.current.forEach((region, start) => {
14102
+ if (start >= a && start <= endLine && collapsedRef.current.has(start) && region.end > endLine) {
14103
+ endLine = region.end;
14104
+ changed = true;
14105
+ }
14106
+ });
14107
+ }
14108
+ const full = code.split("\n").slice(a, endLine + 1).join("\n");
14109
+ e.clipboardData.setData("text/plain", full);
14110
+ e.preventDefault();
14111
+ }, [code]);
14056
14112
  const hasHeader = showLanguageBadge || showCopyButton;
14057
14113
  return /* @__PURE__ */ jsxs(Box, { className: `relative group ${className || ""}`, style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
14058
14114
  hasHeader && /* @__PURE__ */ jsxs(
@@ -14203,6 +14259,7 @@ var init_CodeBlock = __esm({
14203
14259
  "div",
14204
14260
  {
14205
14261
  ref: scrollRef,
14262
+ onCopy: handleSelectionCopy,
14206
14263
  style: {
14207
14264
  flex: 1,
14208
14265
  minHeight: 0,
@@ -13890,6 +13890,8 @@ var init_CodeBlock = __esm({
13890
13890
  collapsedRef.current = collapsed;
13891
13891
  const foldStartMapRef = React85.useRef(foldStartMap);
13892
13892
  foldStartMapRef.current = foldStartMap;
13893
+ const hiddenLinesRef = React85.useRef(hiddenLines);
13894
+ hiddenLinesRef.current = hiddenLines;
13893
13895
  const toggleFold = React85.useCallback((lineNum) => {
13894
13896
  setCollapsed((prev) => {
13895
13897
  const next = new Set(prev);
@@ -14002,6 +14004,60 @@ var init_CodeBlock = __esm({
14002
14004
  eventBus.emit("UI:COPY_CODE", { language, success: false });
14003
14005
  }
14004
14006
  };
14007
+ const handleSelectionCopy = React85.useCallback((e) => {
14008
+ if (hiddenLinesRef.current.size === 0) return;
14009
+ const sel = typeof window !== "undefined" ? window.getSelection() : null;
14010
+ if (!sel || sel.rangeCount === 0 || sel.isCollapsed) return;
14011
+ const lineOf = (node) => {
14012
+ const start = node instanceof HTMLElement ? node : node?.parentElement ?? null;
14013
+ const lineEl = start?.closest("[data-line]");
14014
+ if (!lineEl) return null;
14015
+ const n = parseInt(lineEl.getAttribute("data-line") ?? "", 10);
14016
+ return Number.isNaN(n) ? null : n;
14017
+ };
14018
+ const range = sel.getRangeAt(0);
14019
+ let a = lineOf(range.startContainer);
14020
+ let b = lineOf(range.endContainer);
14021
+ if (a === null || b === null) {
14022
+ const container = codeRef.current;
14023
+ if (!container) return;
14024
+ let min = Infinity, max = -Infinity;
14025
+ container.querySelectorAll("[data-line]").forEach((el) => {
14026
+ if (!sel.containsNode(el, true)) return;
14027
+ const n = parseInt(el.getAttribute("data-line") ?? "", 10);
14028
+ if (!Number.isNaN(n)) {
14029
+ min = Math.min(min, n);
14030
+ max = Math.max(max, n);
14031
+ }
14032
+ });
14033
+ if (min === Infinity) return;
14034
+ a = a ?? min;
14035
+ b = b ?? max;
14036
+ }
14037
+ if (a > b) [a, b] = [b, a];
14038
+ let touchesFold = false;
14039
+ for (let i = a; i <= b; i++) {
14040
+ if (hiddenLinesRef.current.has(i) || foldStartMapRef.current.has(i) && collapsedRef.current.has(i)) {
14041
+ touchesFold = true;
14042
+ break;
14043
+ }
14044
+ }
14045
+ if (!touchesFold) return;
14046
+ let endLine = b;
14047
+ let changed = true;
14048
+ while (changed) {
14049
+ changed = false;
14050
+ foldStartMapRef.current.forEach((region, start) => {
14051
+ if (start >= a && start <= endLine && collapsedRef.current.has(start) && region.end > endLine) {
14052
+ endLine = region.end;
14053
+ changed = true;
14054
+ }
14055
+ });
14056
+ }
14057
+ const full = code.split("\n").slice(a, endLine + 1).join("\n");
14058
+ e.clipboardData.setData("text/plain", full);
14059
+ e.preventDefault();
14060
+ }, [code]);
14005
14061
  const hasHeader = showLanguageBadge || showCopyButton;
14006
14062
  return /* @__PURE__ */ jsxRuntime.jsxs(Box, { className: `relative group ${className || ""}`, style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
14007
14063
  hasHeader && /* @__PURE__ */ jsxRuntime.jsxs(
@@ -14152,6 +14208,7 @@ var init_CodeBlock = __esm({
14152
14208
  "div",
14153
14209
  {
14154
14210
  ref: scrollRef,
14211
+ onCopy: handleSelectionCopy,
14155
14212
  style: {
14156
14213
  flex: 1,
14157
14214
  minHeight: 0,
@@ -13841,6 +13841,8 @@ var init_CodeBlock = __esm({
13841
13841
  collapsedRef.current = collapsed;
13842
13842
  const foldStartMapRef = useRef(foldStartMap);
13843
13843
  foldStartMapRef.current = foldStartMap;
13844
+ const hiddenLinesRef = useRef(hiddenLines);
13845
+ hiddenLinesRef.current = hiddenLines;
13844
13846
  const toggleFold = useCallback((lineNum) => {
13845
13847
  setCollapsed((prev) => {
13846
13848
  const next = new Set(prev);
@@ -13953,6 +13955,60 @@ var init_CodeBlock = __esm({
13953
13955
  eventBus.emit("UI:COPY_CODE", { language, success: false });
13954
13956
  }
13955
13957
  };
13958
+ const handleSelectionCopy = useCallback((e) => {
13959
+ if (hiddenLinesRef.current.size === 0) return;
13960
+ const sel = typeof window !== "undefined" ? window.getSelection() : null;
13961
+ if (!sel || sel.rangeCount === 0 || sel.isCollapsed) return;
13962
+ const lineOf = (node) => {
13963
+ const start = node instanceof HTMLElement ? node : node?.parentElement ?? null;
13964
+ const lineEl = start?.closest("[data-line]");
13965
+ if (!lineEl) return null;
13966
+ const n = parseInt(lineEl.getAttribute("data-line") ?? "", 10);
13967
+ return Number.isNaN(n) ? null : n;
13968
+ };
13969
+ const range = sel.getRangeAt(0);
13970
+ let a = lineOf(range.startContainer);
13971
+ let b = lineOf(range.endContainer);
13972
+ if (a === null || b === null) {
13973
+ const container = codeRef.current;
13974
+ if (!container) return;
13975
+ let min = Infinity, max = -Infinity;
13976
+ container.querySelectorAll("[data-line]").forEach((el) => {
13977
+ if (!sel.containsNode(el, true)) return;
13978
+ const n = parseInt(el.getAttribute("data-line") ?? "", 10);
13979
+ if (!Number.isNaN(n)) {
13980
+ min = Math.min(min, n);
13981
+ max = Math.max(max, n);
13982
+ }
13983
+ });
13984
+ if (min === Infinity) return;
13985
+ a = a ?? min;
13986
+ b = b ?? max;
13987
+ }
13988
+ if (a > b) [a, b] = [b, a];
13989
+ let touchesFold = false;
13990
+ for (let i = a; i <= b; i++) {
13991
+ if (hiddenLinesRef.current.has(i) || foldStartMapRef.current.has(i) && collapsedRef.current.has(i)) {
13992
+ touchesFold = true;
13993
+ break;
13994
+ }
13995
+ }
13996
+ if (!touchesFold) return;
13997
+ let endLine = b;
13998
+ let changed = true;
13999
+ while (changed) {
14000
+ changed = false;
14001
+ foldStartMapRef.current.forEach((region, start) => {
14002
+ if (start >= a && start <= endLine && collapsedRef.current.has(start) && region.end > endLine) {
14003
+ endLine = region.end;
14004
+ changed = true;
14005
+ }
14006
+ });
14007
+ }
14008
+ const full = code.split("\n").slice(a, endLine + 1).join("\n");
14009
+ e.clipboardData.setData("text/plain", full);
14010
+ e.preventDefault();
14011
+ }, [code]);
13956
14012
  const hasHeader = showLanguageBadge || showCopyButton;
13957
14013
  return /* @__PURE__ */ jsxs(Box, { className: `relative group ${className || ""}`, style: { display: "flex", flexDirection: "column", height: "100%" }, children: [
13958
14014
  hasHeader && /* @__PURE__ */ jsxs(
@@ -14103,6 +14159,7 @@ var init_CodeBlock = __esm({
14103
14159
  "div",
14104
14160
  {
14105
14161
  ref: scrollRef,
14162
+ onCopy: handleSelectionCopy,
14106
14163
  style: {
14107
14164
  flex: 1,
14108
14165
  minHeight: 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "5.13.3",
3
+ "version": "5.14.1",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -169,7 +169,7 @@
169
169
  "three": "^0.160.0"
170
170
  },
171
171
  "devDependencies": {
172
- "@almadar/eslint-plugin": ">=2.3.0",
172
+ "@almadar/eslint-plugin": "^2.8.2",
173
173
  "@react-three/drei": "^10.7.7",
174
174
  "@react-three/fiber": "^9.6.0",
175
175
  "@react-three/postprocessing": "3.0.4",