@almadar/ui 2.54.0 → 2.55.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.
@@ -10016,7 +10016,8 @@ var CodeBlock = React114__namespace.default.memo(
10016
10016
  foldable: foldableProp,
10017
10017
  className,
10018
10018
  editable = false,
10019
- onChange
10019
+ onChange,
10020
+ errorLines
10020
10021
  }) => {
10021
10022
  const code = typeof rawCode === "string" ? rawCode : String(rawCode ?? "");
10022
10023
  const isOrb = language === "orb";
@@ -10048,6 +10049,28 @@ var CodeBlock = React114__namespace.default.memo(
10048
10049
  ov.scrollLeft = ta.scrollLeft;
10049
10050
  }
10050
10051
  }, []);
10052
+ const errorLineProps = React114.useMemo(() => {
10053
+ if (!errorLines || errorLines.size === 0) {
10054
+ return LINE_PROPS_FN;
10055
+ }
10056
+ return (lineNumber) => {
10057
+ const severity = errorLines.get(lineNumber);
10058
+ if (!severity) {
10059
+ return { "data-line": String(lineNumber - 1) };
10060
+ }
10061
+ return {
10062
+ "data-line": String(lineNumber - 1),
10063
+ style: {
10064
+ display: "block",
10065
+ backgroundColor: severity === "error" ? "rgba(248, 113, 113, 0.18)" : "rgba(251, 191, 36, 0.18)",
10066
+ // amber-400 @ 18%
10067
+ borderLeft: `3px solid ${severity === "error" ? "#ef4444" : "#f59e0b"}`,
10068
+ paddingLeft: "0.5rem",
10069
+ marginLeft: "-0.5rem"
10070
+ }
10071
+ };
10072
+ };
10073
+ }, [errorLines]);
10051
10074
  const isFoldable = foldableProp ?? (language === "orb" || language === "json");
10052
10075
  const [collapsed, setCollapsed] = React114.useState(() => /* @__PURE__ */ new Set());
10053
10076
  const foldRegions = React114.useMemo(
@@ -10208,24 +10231,40 @@ var CodeBlock = React114__namespace.default.memo(
10208
10231
  }
10209
10232
  ),
10210
10233
  editable ? (
10211
- /* GAP-77: editable mode = transparent Textarea on top + Prism-highlighted
10212
- overlay underneath. The textarea is uncontrolled (defaultValue + key)
10213
- to avoid cursor jumps; the overlay reads `editableValue` which is
10214
- mirrored from the textarea via onChange. Both elements share IDENTICAL
10215
- font / line-height / padding so the highlighted text aligns with the
10216
- textarea's invisible glyphs.
10234
+ /* GAP-77 / GAP-82 / GAP-83: editable mode = transparent textarea on
10235
+ top of a Prism-highlighted SyntaxHighlighter overlay.
10236
+
10237
+ Layout: BOTH children are `position: absolute, inset: 0` so neither
10238
+ contributes to flow. The parent Box has `height: 100%` so it fills
10239
+ whatever container the consumer provides (the consumer is
10240
+ responsible for giving the parent a real height — usually via flex
10241
+ column with `minHeight: 0`).
10242
+
10243
+ Stacking: the overlay is FIRST in DOM order so it paints first
10244
+ (behind), the textarea is SECOND so it paints second (on top). No
10245
+ explicit z-index — DOM order alone determines stacking inside the
10246
+ parent's stacking context. The textarea has `color: transparent`
10247
+ plus `WebkitTextFillColor: transparent` (Safari) so its glyphs
10248
+ never paint, but the caret stays visible via `caretColor`.
10217
10249
 
10218
- Scroll sync: the overlay has `pointer-events: none` and the textarea
10219
- scrolls; `handleEditableScroll` keeps the overlay's scroll matched. */
10250
+ Scroll sync: textarea scrolls naturally; `handleEditableScroll`
10251
+ mirrors its scrollTop/scrollLeft onto the overlay div so the
10252
+ highlighted spans stay aligned with the textarea content.
10253
+
10254
+ Error highlights (GAP-80): `errorLines` prop accepts a Map of
10255
+ 1-based line numbers → severity. The overlay's SyntaxHighlighter
10256
+ uses `wrapLines` + `lineProps` to paint a colored background on
10257
+ those lines. */
10220
10258
  /* @__PURE__ */ jsxRuntime.jsxs(
10221
10259
  Box,
10222
10260
  {
10223
10261
  style: {
10224
10262
  position: "relative",
10225
- backgroundColor: "#1e1e1e",
10226
- borderRadius: hasHeader ? "0 0 0.5rem 0.5rem" : "0.5rem",
10263
+ height: "100%",
10227
10264
  minHeight: "160px",
10228
10265
  maxHeight,
10266
+ backgroundColor: "#1e1e1e",
10267
+ borderRadius: hasHeader ? "0 0 0.5rem 0.5rem" : "0.5rem",
10229
10268
  overflow: "hidden"
10230
10269
  },
10231
10270
  children: [
@@ -10236,10 +10275,12 @@ var CodeBlock = React114__namespace.default.memo(
10236
10275
  "aria-hidden": true,
10237
10276
  style: {
10238
10277
  position: "absolute",
10239
- inset: 0,
10278
+ top: 0,
10279
+ left: 0,
10280
+ width: "100%",
10281
+ height: "100%",
10240
10282
  overflow: "hidden",
10241
- pointerEvents: "none",
10242
- maxHeight
10283
+ pointerEvents: "none"
10243
10284
  },
10244
10285
  children: /* @__PURE__ */ jsxRuntime.jsx(
10245
10286
  SyntaxHighlighter__default.default,
@@ -10247,6 +10288,8 @@ var CodeBlock = React114__namespace.default.memo(
10247
10288
  PreTag: "div",
10248
10289
  language,
10249
10290
  style: activeStyle,
10291
+ wrapLines: errorLines && errorLines.size > 0,
10292
+ lineProps: errorLineProps,
10250
10293
  customStyle: {
10251
10294
  backgroundColor: "transparent",
10252
10295
  borderRadius: 0,
@@ -10254,7 +10297,6 @@ var CodeBlock = React114__namespace.default.memo(
10254
10297
  margin: 0,
10255
10298
  whiteSpace: "pre",
10256
10299
  minWidth: "100%",
10257
- minHeight: "160px",
10258
10300
  fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
10259
10301
  fontSize: "13px",
10260
10302
  lineHeight: "1.5"
@@ -10283,23 +10325,23 @@ var CodeBlock = React114__namespace.default.memo(
10283
10325
  onScroll: handleEditableScroll,
10284
10326
  spellCheck: false,
10285
10327
  style: {
10286
- position: "relative",
10287
- zIndex: 1,
10288
- fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
10289
- fontSize: "13px",
10290
- lineHeight: "1.5",
10291
- backgroundColor: "transparent",
10292
- color: "transparent",
10293
- caretColor: "#e6e6e6",
10294
- borderRadius: hasHeader ? "0 0 0.5rem 0.5rem" : "0.5rem",
10295
- border: "none",
10296
- padding: "1rem",
10297
- resize: "none",
10298
- minHeight: "160px",
10299
- maxHeight,
10328
+ position: "absolute",
10329
+ top: 0,
10330
+ left: 0,
10300
10331
  width: "100%",
10301
10332
  height: "100%",
10333
+ padding: "1rem",
10334
+ margin: 0,
10335
+ border: "none",
10302
10336
  outline: "none",
10337
+ resize: "none",
10338
+ backgroundColor: "transparent",
10339
+ color: "transparent",
10340
+ caretColor: "#e6e6e6",
10341
+ WebkitTextFillColor: "transparent",
10342
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
10343
+ fontSize: "13px",
10344
+ lineHeight: "1.5",
10303
10345
  whiteSpace: "pre",
10304
10346
  overflowWrap: "normal",
10305
10347
  overflow: "auto"
@@ -10330,7 +10372,7 @@ var CodeBlock = React114__namespace.default.memo(
10330
10372
  )
10331
10373
  ] });
10332
10374
  },
10333
- (prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.maxHeight === next.maxHeight && prev.foldable === next.foldable && prev.editable === next.editable && prev.onChange === next.onChange
10375
+ (prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.maxHeight === next.maxHeight && prev.foldable === next.foldable && prev.editable === next.editable && prev.onChange === next.onChange && prev.errorLines === next.errorLines
10334
10376
  );
10335
10377
  CodeBlock.displayName = "CodeBlock";
10336
10378
 
@@ -9971,7 +9971,8 @@ var CodeBlock = React114__default.memo(
9971
9971
  foldable: foldableProp,
9972
9972
  className,
9973
9973
  editable = false,
9974
- onChange
9974
+ onChange,
9975
+ errorLines
9975
9976
  }) => {
9976
9977
  const code = typeof rawCode === "string" ? rawCode : String(rawCode ?? "");
9977
9978
  const isOrb = language === "orb";
@@ -10003,6 +10004,28 @@ var CodeBlock = React114__default.memo(
10003
10004
  ov.scrollLeft = ta.scrollLeft;
10004
10005
  }
10005
10006
  }, []);
10007
+ const errorLineProps = useMemo(() => {
10008
+ if (!errorLines || errorLines.size === 0) {
10009
+ return LINE_PROPS_FN;
10010
+ }
10011
+ return (lineNumber) => {
10012
+ const severity = errorLines.get(lineNumber);
10013
+ if (!severity) {
10014
+ return { "data-line": String(lineNumber - 1) };
10015
+ }
10016
+ return {
10017
+ "data-line": String(lineNumber - 1),
10018
+ style: {
10019
+ display: "block",
10020
+ backgroundColor: severity === "error" ? "rgba(248, 113, 113, 0.18)" : "rgba(251, 191, 36, 0.18)",
10021
+ // amber-400 @ 18%
10022
+ borderLeft: `3px solid ${severity === "error" ? "#ef4444" : "#f59e0b"}`,
10023
+ paddingLeft: "0.5rem",
10024
+ marginLeft: "-0.5rem"
10025
+ }
10026
+ };
10027
+ };
10028
+ }, [errorLines]);
10006
10029
  const isFoldable = foldableProp ?? (language === "orb" || language === "json");
10007
10030
  const [collapsed, setCollapsed] = useState(() => /* @__PURE__ */ new Set());
10008
10031
  const foldRegions = useMemo(
@@ -10163,24 +10186,40 @@ var CodeBlock = React114__default.memo(
10163
10186
  }
10164
10187
  ),
10165
10188
  editable ? (
10166
- /* GAP-77: editable mode = transparent Textarea on top + Prism-highlighted
10167
- overlay underneath. The textarea is uncontrolled (defaultValue + key)
10168
- to avoid cursor jumps; the overlay reads `editableValue` which is
10169
- mirrored from the textarea via onChange. Both elements share IDENTICAL
10170
- font / line-height / padding so the highlighted text aligns with the
10171
- textarea's invisible glyphs.
10189
+ /* GAP-77 / GAP-82 / GAP-83: editable mode = transparent textarea on
10190
+ top of a Prism-highlighted SyntaxHighlighter overlay.
10191
+
10192
+ Layout: BOTH children are `position: absolute, inset: 0` so neither
10193
+ contributes to flow. The parent Box has `height: 100%` so it fills
10194
+ whatever container the consumer provides (the consumer is
10195
+ responsible for giving the parent a real height — usually via flex
10196
+ column with `minHeight: 0`).
10197
+
10198
+ Stacking: the overlay is FIRST in DOM order so it paints first
10199
+ (behind), the textarea is SECOND so it paints second (on top). No
10200
+ explicit z-index — DOM order alone determines stacking inside the
10201
+ parent's stacking context. The textarea has `color: transparent`
10202
+ plus `WebkitTextFillColor: transparent` (Safari) so its glyphs
10203
+ never paint, but the caret stays visible via `caretColor`.
10172
10204
 
10173
- Scroll sync: the overlay has `pointer-events: none` and the textarea
10174
- scrolls; `handleEditableScroll` keeps the overlay's scroll matched. */
10205
+ Scroll sync: textarea scrolls naturally; `handleEditableScroll`
10206
+ mirrors its scrollTop/scrollLeft onto the overlay div so the
10207
+ highlighted spans stay aligned with the textarea content.
10208
+
10209
+ Error highlights (GAP-80): `errorLines` prop accepts a Map of
10210
+ 1-based line numbers → severity. The overlay's SyntaxHighlighter
10211
+ uses `wrapLines` + `lineProps` to paint a colored background on
10212
+ those lines. */
10175
10213
  /* @__PURE__ */ jsxs(
10176
10214
  Box,
10177
10215
  {
10178
10216
  style: {
10179
10217
  position: "relative",
10180
- backgroundColor: "#1e1e1e",
10181
- borderRadius: hasHeader ? "0 0 0.5rem 0.5rem" : "0.5rem",
10218
+ height: "100%",
10182
10219
  minHeight: "160px",
10183
10220
  maxHeight,
10221
+ backgroundColor: "#1e1e1e",
10222
+ borderRadius: hasHeader ? "0 0 0.5rem 0.5rem" : "0.5rem",
10184
10223
  overflow: "hidden"
10185
10224
  },
10186
10225
  children: [
@@ -10191,10 +10230,12 @@ var CodeBlock = React114__default.memo(
10191
10230
  "aria-hidden": true,
10192
10231
  style: {
10193
10232
  position: "absolute",
10194
- inset: 0,
10233
+ top: 0,
10234
+ left: 0,
10235
+ width: "100%",
10236
+ height: "100%",
10195
10237
  overflow: "hidden",
10196
- pointerEvents: "none",
10197
- maxHeight
10238
+ pointerEvents: "none"
10198
10239
  },
10199
10240
  children: /* @__PURE__ */ jsx(
10200
10241
  SyntaxHighlighter,
@@ -10202,6 +10243,8 @@ var CodeBlock = React114__default.memo(
10202
10243
  PreTag: "div",
10203
10244
  language,
10204
10245
  style: activeStyle,
10246
+ wrapLines: errorLines && errorLines.size > 0,
10247
+ lineProps: errorLineProps,
10205
10248
  customStyle: {
10206
10249
  backgroundColor: "transparent",
10207
10250
  borderRadius: 0,
@@ -10209,7 +10252,6 @@ var CodeBlock = React114__default.memo(
10209
10252
  margin: 0,
10210
10253
  whiteSpace: "pre",
10211
10254
  minWidth: "100%",
10212
- minHeight: "160px",
10213
10255
  fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
10214
10256
  fontSize: "13px",
10215
10257
  lineHeight: "1.5"
@@ -10238,23 +10280,23 @@ var CodeBlock = React114__default.memo(
10238
10280
  onScroll: handleEditableScroll,
10239
10281
  spellCheck: false,
10240
10282
  style: {
10241
- position: "relative",
10242
- zIndex: 1,
10243
- fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
10244
- fontSize: "13px",
10245
- lineHeight: "1.5",
10246
- backgroundColor: "transparent",
10247
- color: "transparent",
10248
- caretColor: "#e6e6e6",
10249
- borderRadius: hasHeader ? "0 0 0.5rem 0.5rem" : "0.5rem",
10250
- border: "none",
10251
- padding: "1rem",
10252
- resize: "none",
10253
- minHeight: "160px",
10254
- maxHeight,
10283
+ position: "absolute",
10284
+ top: 0,
10285
+ left: 0,
10255
10286
  width: "100%",
10256
10287
  height: "100%",
10288
+ padding: "1rem",
10289
+ margin: 0,
10290
+ border: "none",
10257
10291
  outline: "none",
10292
+ resize: "none",
10293
+ backgroundColor: "transparent",
10294
+ color: "transparent",
10295
+ caretColor: "#e6e6e6",
10296
+ WebkitTextFillColor: "transparent",
10297
+ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Mono", "Courier New", monospace',
10298
+ fontSize: "13px",
10299
+ lineHeight: "1.5",
10258
10300
  whiteSpace: "pre",
10259
10301
  overflowWrap: "normal",
10260
10302
  overflow: "auto"
@@ -10285,7 +10327,7 @@ var CodeBlock = React114__default.memo(
10285
10327
  )
10286
10328
  ] });
10287
10329
  },
10288
- (prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.maxHeight === next.maxHeight && prev.foldable === next.foldable && prev.editable === next.editable && prev.onChange === next.onChange
10330
+ (prev, next) => prev.language === next.language && prev.code === next.code && prev.showCopyButton === next.showCopyButton && prev.maxHeight === next.maxHeight && prev.foldable === next.foldable && prev.editable === next.editable && prev.onChange === next.onChange && prev.errorLines === next.errorLines
10289
10331
  );
10290
10332
  CodeBlock.displayName = "CodeBlock";
10291
10333
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "2.54.0",
3
+ "version": "2.55.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "main": "./dist/components/index.js",