@cere/cere-design-system 0.1.0 → 0.2.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.
- package/README.md +76 -0
- package/dist/buttons.d.mts +27 -22
- package/dist/buttons.d.ts +27 -22
- package/dist/buttons.js +5 -5
- package/dist/buttons.mjs +4 -4
- package/dist/charts.d.mts +1 -23
- package/dist/charts.d.ts +1 -23
- package/dist/charts.js +2 -9
- package/dist/charts.js.map +1 -1
- package/dist/charts.mjs +1 -8
- package/dist/{chunk-THQKYTQE.js → chunk-2KDN37PQ.js} +28 -32
- package/dist/chunk-2KDN37PQ.js.map +1 -0
- package/dist/{chunk-3WCMINE5.mjs → chunk-34LFXT6C.mjs} +25 -29
- package/dist/chunk-34LFXT6C.mjs.map +1 -0
- package/dist/chunk-3KCXCVOX.mjs +411 -0
- package/dist/chunk-3KCXCVOX.mjs.map +1 -0
- package/dist/{chunk-NXTVJ6PY.js → chunk-4OKTICU5.js} +10 -10
- package/dist/chunk-4OKTICU5.js.map +1 -0
- package/dist/{chunk-FN5YL4BK.js → chunk-72TQ56EP.js} +47 -45
- package/dist/chunk-72TQ56EP.js.map +1 -0
- package/dist/{chunk-QYYQYZHV.js → chunk-7KXKK2RE.js} +3 -5
- package/dist/chunk-7KXKK2RE.js.map +1 -0
- package/dist/{chunk-CCN6M4LI.js → chunk-ARSCL4ZZ.js} +18 -10
- package/dist/chunk-ARSCL4ZZ.js.map +1 -0
- package/dist/chunk-AWVNEU6R.mjs +1478 -0
- package/dist/chunk-AWVNEU6R.mjs.map +1 -0
- package/dist/{chunk-CUCKULYC.mjs → chunk-BH4FNZKK.mjs} +74 -1260
- package/dist/chunk-BH4FNZKK.mjs.map +1 -0
- package/dist/{chunk-FFZ5S7PQ.mjs → chunk-BOQPWZIB.mjs} +6 -5
- package/dist/chunk-BOQPWZIB.mjs.map +1 -0
- package/dist/chunk-BT7XUTT5.mjs +392 -0
- package/dist/chunk-BT7XUTT5.mjs.map +1 -0
- package/dist/{chunk-ATIFLPH6.mjs → chunk-D7D25O6E.mjs} +4 -2
- package/dist/{chunk-ATIFLPH6.mjs.map → chunk-D7D25O6E.mjs.map} +1 -1
- package/dist/{chunk-JS4IB5IU.mjs → chunk-DRGMEIPT.mjs} +2 -2
- package/dist/chunk-DRGMEIPT.mjs.map +1 -0
- package/dist/{chunk-KF2Y7HO3.js → chunk-DZXNYLVG.js} +43 -246
- package/dist/chunk-DZXNYLVG.js.map +1 -0
- package/dist/{chunk-IE6GCHDI.mjs → chunk-GR52ENYI.mjs} +26 -29
- package/dist/chunk-GR52ENYI.mjs.map +1 -0
- package/dist/chunk-GTBKQXXI.js +1472 -0
- package/dist/chunk-GTBKQXXI.js.map +1 -0
- package/dist/{chunk-463SRKKD.js → chunk-HJ24WKU4.js} +14 -5
- package/dist/chunk-HJ24WKU4.js.map +1 -0
- package/dist/{chunk-EOF3QNPF.js → chunk-KKIKOIMP.js} +140 -1028
- package/dist/chunk-KKIKOIMP.js.map +1 -0
- package/dist/{chunk-MNM6HE72.js → chunk-LVJSKRX3.js} +16 -15
- package/dist/chunk-LVJSKRX3.js.map +1 -0
- package/dist/{chunk-KPDYKK3V.js → chunk-PFZZJZ64.js} +8 -8
- package/dist/{chunk-KPDYKK3V.js.map → chunk-PFZZJZ64.js.map} +1 -1
- package/dist/{chunk-KVBMZNWT.mjs → chunk-POCAW2G4.mjs} +18 -10
- package/dist/chunk-POCAW2G4.mjs.map +1 -0
- package/dist/{chunk-L2TIGA7I.js → chunk-QCFLZ7X3.js} +39 -42
- package/dist/chunk-QCFLZ7X3.js.map +1 -0
- package/dist/{chunk-6EUAU67C.mjs → chunk-SG2TD7FQ.mjs} +8 -8
- package/dist/chunk-SG2TD7FQ.mjs.map +1 -0
- package/dist/{chunk-QY65OUAC.mjs → chunk-SSFALO6S.mjs} +13 -4
- package/dist/chunk-SSFALO6S.mjs.map +1 -0
- package/dist/{chunk-PWF2NJDB.mjs → chunk-WC2TCWXK.mjs} +82 -14
- package/dist/chunk-WC2TCWXK.mjs.map +1 -0
- package/dist/{chunk-ZGCN5WCG.js → chunk-XZZZ4MZV.js} +83 -15
- package/dist/chunk-XZZZ4MZV.js.map +1 -0
- package/dist/chunk-YCDCQSYH.js +411 -0
- package/dist/chunk-YCDCQSYH.js.map +1 -0
- package/dist/{chunk-CWJ4OU6W.mjs → chunk-ZDAZYIXB.mjs} +2 -4
- package/dist/chunk-ZDAZYIXB.mjs.map +1 -0
- package/dist/feedback.d.mts +20 -8
- package/dist/feedback.d.ts +20 -8
- package/dist/feedback.js +5 -5
- package/dist/feedback.mjs +4 -4
- package/dist/fonts/HumanSans-BlackOblique.otf +0 -0
- package/dist/fonts/HumanSans-Thin.otf +0 -0
- package/dist/fonts/HumanSans-ThinOblique.otf +0 -0
- package/dist/fonts/human-sans-font.css +88 -0
- package/dist/fonts/human-sans.css +3 -0
- package/dist/fonts/inter.css +3 -0
- package/dist/icons.d.mts +2 -3
- package/dist/icons.d.ts +2 -3
- package/dist/icons.js +2 -2
- package/dist/icons.mjs +1 -1
- package/dist/index.d.mts +37 -8
- package/dist/index.d.ts +37 -8
- package/dist/index.js +23 -90
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +46 -113
- package/dist/index.mjs.map +1 -1
- package/dist/inputs.d.mts +23 -3
- package/dist/inputs.d.ts +23 -3
- package/dist/inputs.js +5 -5
- package/dist/inputs.js.map +1 -1
- package/dist/inputs.mjs +15 -15
- package/dist/layout.d.mts +37 -283
- package/dist/layout.d.ts +37 -283
- package/dist/layout.js +8 -32
- package/dist/layout.js.map +1 -1
- package/dist/layout.mjs +16 -40
- package/dist/navigation.d.mts +9 -114
- package/dist/navigation.d.ts +9 -114
- package/dist/navigation.js +5 -9
- package/dist/navigation.js.map +1 -1
- package/dist/navigation.mjs +6 -10
- package/dist/third-party.d.mts +3 -527
- package/dist/third-party.d.ts +3 -527
- package/dist/third-party.js +2 -40
- package/dist/third-party.js.map +1 -1
- package/dist/third-party.mjs +3 -41
- package/dist/tokens.css +45 -71
- package/dist/utilities.js +2 -4
- package/dist/utilities.js.map +1 -1
- package/dist/utilities.mjs +2 -4
- package/package.json +23 -9
- package/dist/WorkflowNode-BnxXO6t_.d.mts +0 -46
- package/dist/WorkflowNode-BnxXO6t_.d.ts +0 -46
- package/dist/chunk-27JEWSWA.mjs +0 -233
- package/dist/chunk-27JEWSWA.mjs.map +0 -1
- package/dist/chunk-3WCMINE5.mjs.map +0 -1
- package/dist/chunk-463SRKKD.js.map +0 -1
- package/dist/chunk-6EUAU67C.mjs.map +0 -1
- package/dist/chunk-AIY6222Q.js +0 -11
- package/dist/chunk-AIY6222Q.js.map +0 -1
- package/dist/chunk-AJBM7IE6.mjs +0 -2366
- package/dist/chunk-AJBM7IE6.mjs.map +0 -1
- package/dist/chunk-CCN6M4LI.js.map +0 -1
- package/dist/chunk-CUCKULYC.mjs.map +0 -1
- package/dist/chunk-CWJ4OU6W.mjs.map +0 -1
- package/dist/chunk-EOF3QNPF.js.map +0 -1
- package/dist/chunk-FFZ5S7PQ.mjs.map +0 -1
- package/dist/chunk-FN5YL4BK.js.map +0 -1
- package/dist/chunk-HLH2VWXL.js +0 -2658
- package/dist/chunk-HLH2VWXL.js.map +0 -1
- package/dist/chunk-IE6GCHDI.mjs.map +0 -1
- package/dist/chunk-JS4IB5IU.mjs.map +0 -1
- package/dist/chunk-KF2Y7HO3.js.map +0 -1
- package/dist/chunk-KVBMZNWT.mjs.map +0 -1
- package/dist/chunk-L2TIGA7I.js.map +0 -1
- package/dist/chunk-MNM6HE72.js.map +0 -1
- package/dist/chunk-NXTVJ6PY.js.map +0 -1
- package/dist/chunk-PWF2NJDB.mjs.map +0 -1
- package/dist/chunk-QD6RLAO2.mjs +0 -11
- package/dist/chunk-QD6RLAO2.mjs.map +0 -1
- package/dist/chunk-QY65OUAC.mjs.map +0 -1
- package/dist/chunk-QYYQYZHV.js.map +0 -1
- package/dist/chunk-T7LPABOL.mjs +0 -595
- package/dist/chunk-T7LPABOL.mjs.map +0 -1
- package/dist/chunk-THQKYTQE.js.map +0 -1
- package/dist/chunk-X7E6GMFL.js +0 -233
- package/dist/chunk-X7E6GMFL.js.map +0 -1
- package/dist/chunk-XF66WQZE.mjs +0 -1535
- package/dist/chunk-XF66WQZE.mjs.map +0 -1
- package/dist/chunk-YQOZPLTY.js +0 -1535
- package/dist/chunk-YQOZPLTY.js.map +0 -1
- package/dist/chunk-ZGCN5WCG.js.map +0 -1
- package/dist/index.css +0 -79
- package/dist/index.css.map +0 -1
- /package/dist/{HumanSans-Black-C4YJONK7.otf → fonts/HumanSans-Black.otf} +0 -0
- /package/dist/{HumanSans-Bold-4EAJ3L3T.otf → fonts/HumanSans-Bold.otf} +0 -0
- /package/dist/{HumanSans-BoldOblique-4D325T4F.otf → fonts/HumanSans-BoldOblique.otf} +0 -0
- /package/dist/{HumanSans-ExtraLight-VL7DEKQ4.otf → fonts/HumanSans-ExtraLight.otf} +0 -0
- /package/dist/{HumanSans-ExtraLightOblique-VK2JTUXF.otf → fonts/HumanSans-ExtraLightOblique.otf} +0 -0
- /package/dist/{HumanSans-Light-YV7AFKRB.otf → fonts/HumanSans-Light.otf} +0 -0
- /package/dist/{HumanSans-LightOblique-VIXV7QA6.otf → fonts/HumanSans-LightOblique.otf} +0 -0
- /package/dist/{HumanSans-Medium-UULJ3PIR.otf → fonts/HumanSans-Medium.otf} +0 -0
- /package/dist/{HumanSans-MediumOblique-M7FHDZRS.otf → fonts/HumanSans-MediumOblique.otf} +0 -0
- /package/dist/{HumanSans-Regular-QMFEP3F6.otf → fonts/HumanSans-Regular.otf} +0 -0
- /package/dist/{HumanSans-RegularOblique-YPKQJAAM.otf → fonts/HumanSans-RegularOblique.otf} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Card,
|
|
3
|
-
|
|
4
|
-
} from "./chunk-
|
|
3
|
+
default as default2
|
|
4
|
+
} from "./chunk-POCAW2G4.mjs";
|
|
5
5
|
import {
|
|
6
6
|
TextField
|
|
7
7
|
} from "./chunk-ZP26PGMS.mjs";
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
fontFamilyMono,
|
|
10
10
|
motion,
|
|
11
11
|
webSurfaceTokens
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WC2TCWXK.mjs";
|
|
13
13
|
|
|
14
14
|
// src/components/inputs/CopyableField.tsx
|
|
15
15
|
import React, { useCallback, useEffect, useRef, useState } from "react";
|
|
@@ -94,7 +94,7 @@ var CopyableField = React.forwardRef(
|
|
|
94
94
|
minHeight: label || copied ? void 0 : 0
|
|
95
95
|
},
|
|
96
96
|
children: [
|
|
97
|
-
label ? /* @__PURE__ */ jsx(
|
|
97
|
+
label ? /* @__PURE__ */ jsx(default2, { variant: "overline", children: label }) : /* @__PURE__ */ jsx("span", {}),
|
|
98
98
|
/* @__PURE__ */ jsx(FlashLabel, { role: "status", "aria-live": "polite", "aria-atomic": "true", children: copied ? flashLabel : "" })
|
|
99
99
|
]
|
|
100
100
|
}
|
|
@@ -223,20 +223,16 @@ var SearchField = React2.forwardRef(
|
|
|
223
223
|
);
|
|
224
224
|
|
|
225
225
|
// src/components/inputs/FormControl.tsx
|
|
226
|
-
import {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
InputAdornment as InputAdornment2
|
|
233
|
-
} from "@mui/material";
|
|
226
|
+
import { default as default3 } from "@mui/material/FormControl";
|
|
227
|
+
import { default as default4 } from "@mui/material/FormLabel";
|
|
228
|
+
import { default as default5 } from "@mui/material/FormHelperText";
|
|
229
|
+
import { default as default6 } from "@mui/material/FormControlLabel";
|
|
230
|
+
import { default as default7 } from "@mui/material/InputLabel";
|
|
231
|
+
import { default as default8 } from "@mui/material/InputAdornment";
|
|
234
232
|
|
|
235
233
|
// src/components/inputs/ToggleButton.tsx
|
|
236
|
-
import
|
|
237
|
-
|
|
238
|
-
ToggleButtonGroup as MuiToggleButtonGroup
|
|
239
|
-
} from "@mui/material";
|
|
234
|
+
import MuiToggleButton from "@mui/material/ToggleButton";
|
|
235
|
+
import MuiToggleButtonGroup from "@mui/material/ToggleButtonGroup";
|
|
240
236
|
import { styled as styled2 } from "@mui/material/styles";
|
|
241
237
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
242
238
|
var ToggleButton = (props) => {
|
|
@@ -330,7 +326,7 @@ var Switch = ({
|
|
|
330
326
|
// src/components/inputs/Checkbox.tsx
|
|
331
327
|
import MuiCheckbox from "@mui/material/Checkbox";
|
|
332
328
|
import { styled as styled4 } from "@mui/material/styles";
|
|
333
|
-
import
|
|
329
|
+
import FormControlLabel from "@mui/material/FormControlLabel";
|
|
334
330
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
335
331
|
var StyledCheckbox = styled4(MuiCheckbox)(({ theme }) => ({
|
|
336
332
|
color: theme.palette.grey[400],
|
|
@@ -365,7 +361,7 @@ var Checkbox = ({
|
|
|
365
361
|
right: "end"
|
|
366
362
|
};
|
|
367
363
|
return /* @__PURE__ */ jsx5(
|
|
368
|
-
|
|
364
|
+
FormControlLabel,
|
|
369
365
|
{
|
|
370
366
|
control: checkboxComponent,
|
|
371
367
|
label,
|
|
@@ -377,7 +373,7 @@ var Checkbox = ({
|
|
|
377
373
|
// src/components/inputs/Radio.tsx
|
|
378
374
|
import MuiRadio from "@mui/material/Radio";
|
|
379
375
|
import { styled as styled5 } from "@mui/material/styles";
|
|
380
|
-
import
|
|
376
|
+
import FormControlLabel2 from "@mui/material/FormControlLabel";
|
|
381
377
|
import RadioGroup from "@mui/material/RadioGroup";
|
|
382
378
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
383
379
|
var StyledRadio = styled5(MuiRadio)(({ theme }) => ({
|
|
@@ -410,7 +406,7 @@ var Radio = ({
|
|
|
410
406
|
right: "end"
|
|
411
407
|
};
|
|
412
408
|
return /* @__PURE__ */ jsx6(
|
|
413
|
-
|
|
409
|
+
FormControlLabel2,
|
|
414
410
|
{
|
|
415
411
|
control: radioComponent,
|
|
416
412
|
label,
|
|
@@ -421,7 +417,7 @@ var Radio = ({
|
|
|
421
417
|
|
|
422
418
|
// src/components/inputs/DateRangePicker/DateRangePicker.tsx
|
|
423
419
|
import Stack from "@mui/material/Stack";
|
|
424
|
-
import
|
|
420
|
+
import Typography from "@mui/material/Typography";
|
|
425
421
|
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
|
|
426
422
|
import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
|
|
427
423
|
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFnsV3";
|
|
@@ -451,7 +447,7 @@ var DateRangePicker = ({
|
|
|
451
447
|
}
|
|
452
448
|
}
|
|
453
449
|
),
|
|
454
|
-
/* @__PURE__ */ jsx7(
|
|
450
|
+
/* @__PURE__ */ jsx7(Typography, { variant: "body2", color: "text.secondary", children: "\u2013" }),
|
|
455
451
|
/* @__PURE__ */ jsx7(
|
|
456
452
|
DatePicker,
|
|
457
453
|
{
|
|
@@ -473,12 +469,12 @@ export {
|
|
|
473
469
|
CopyableField,
|
|
474
470
|
useSearchHotkeys,
|
|
475
471
|
SearchField,
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
472
|
+
default3 as default,
|
|
473
|
+
default4 as default2,
|
|
474
|
+
default5 as default3,
|
|
475
|
+
default6 as default4,
|
|
476
|
+
default7 as default5,
|
|
477
|
+
default8 as default6,
|
|
482
478
|
ToggleButton,
|
|
483
479
|
ToggleButtonGroup,
|
|
484
480
|
Switch,
|
|
@@ -487,4 +483,4 @@ export {
|
|
|
487
483
|
Radio,
|
|
488
484
|
DateRangePicker
|
|
489
485
|
};
|
|
490
|
-
//# sourceMappingURL=chunk-
|
|
486
|
+
//# sourceMappingURL=chunk-34LFXT6C.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/inputs/CopyableField.tsx","../src/components/inputs/SearchField.tsx","../src/components/inputs/useSearchHotkeys.ts","../src/components/inputs/FormControl.tsx","../src/components/inputs/ToggleButton.tsx","../src/components/inputs/Switch.tsx","../src/components/inputs/Checkbox.tsx","../src/components/inputs/Radio.tsx","../src/components/inputs/DateRangePicker/DateRangePicker.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport Box from '@mui/material/Box';\nimport { styled } from '@mui/material/styles';\nimport { Card } from '../layout/Card';\nimport { Typography } from '../layout/Typography';\nimport {\n fontFamilyMono,\n} from '../../theme/typography';\nimport { motion } from '../../theme/motion';\nimport { webSurfaceTokens } from '../../theme/webSurfaceTokens';\n\nexport interface CopyableFieldProps {\n /** The string copied to the clipboard. Also rendered as the button label. */\n value: string;\n /** Small label rendered above the value (overline-styled). */\n label?: React.ReactNode;\n /** Custom aria-label; defaults to \"Copy {value}\". */\n ariaLabel?: string;\n /** How long the \"Copied\" flash stays visible, in ms. @default 1400 */\n flashDurationMs?: number;\n /** Text shown during the flash. @default \"Copied\" */\n flashLabel?: string;\n /** Optional callback invoked after a successful copy. */\n onCopy?: (value: string) => void;\n}\n\nconst ValueButton = styled('button')({\n fontFamily: fontFamilyMono,\n fontSize: '11.5px',\n fontWeight: 400,\n lineHeight: 1.45,\n padding: '8px 10px',\n borderRadius: '8px',\n backgroundColor: webSurfaceTokens.surfaceMid,\n border: `1px solid ${webSurfaceTokens.strokeOnLow}`,\n color: webSurfaceTokens.textSecondary,\n wordBreak: 'break-all',\n display: 'block',\n width: '100%',\n textAlign: 'left',\n cursor: 'pointer',\n appearance: 'none',\n transition: `background ${motion.dur.fast} ${motion.ease.standard},\n border-color ${motion.dur.fast} ${motion.ease.standard},\n color ${motion.dur.fast} ${motion.ease.standard}`,\n '&:hover': {\n backgroundColor: webSurfaceTokens.surfaceContrast,\n borderColor: webSurfaceTokens.strokeOnMed,\n color: webSurfaceTokens.textPrimary,\n },\n '&:active': {\n transform: 'translateY(1px)',\n },\n '&:focus-visible': {\n outline: 'none',\n boxShadow: webSurfaceTokens.shadowFocus,\n },\n});\n\nconst FlashLabel = styled('span')({\n fontSize: '11px',\n fontWeight: 600,\n color: webSurfaceTokens.cVioletDark,\n letterSpacing: '0.04em',\n '@media (prefers-reduced-motion: no-preference)': {\n animation: 'cere-copyable-flash 180ms ease-out',\n },\n '@keyframes cere-copyable-flash': {\n from: { opacity: 0, transform: 'translateY(-2px)' },\n to: { opacity: 1, transform: 'translateY(0)' },\n },\n});\n\n/**\n * Tinted card with a label row and a monospace, click-to-copy value button.\n * Replaces ad-hoc `.share-card / .url / .share-card__flash` markup.\n */\nexport const CopyableField = React.forwardRef<HTMLDivElement, CopyableFieldProps>(\n function CopyableField(\n { value, label, ariaLabel, flashDurationMs = 1400, flashLabel = 'Copied', onCopy },\n ref,\n ) {\n const [copied, setCopied] = useState(false);\n const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(\n () => () => {\n if (timerRef.current) clearTimeout(timerRef.current);\n },\n [],\n );\n\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n onCopy?.(value);\n if (timerRef.current) clearTimeout(timerRef.current);\n timerRef.current = setTimeout(() => setCopied(false), flashDurationMs);\n } catch {\n // Clipboard blocked (insecure context / permissions). The value is\n // still visible as plain text — silently no-op.\n }\n }, [value, onCopy, flashDurationMs]);\n\n return (\n <Card ref={ref} variant=\"tinted\" sx={{ p: 1.75 }}>\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: 1,\n mb: label || copied ? '6px' : 0,\n minHeight: label || copied ? undefined : 0,\n }}\n >\n {label ? <Typography variant=\"overline\">{label}</Typography> : <span />}\n {/*\n * Live region stays mounted (even when empty) so SRs reliably\n * announce the swap to flashLabel after a copy. The visual flash\n * uses the same node, so we don't double-render the text.\n */}\n <FlashLabel role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">\n {copied ? flashLabel : ''}\n </FlashLabel>\n </Box>\n <ValueButton\n type=\"button\"\n onClick={handleCopy}\n aria-label={ariaLabel ?? `Copy ${value}`}\n >\n {value}\n </ValueButton>\n </Card>\n );\n },\n);\n","import React, { useEffect, useState } from 'react';\nimport { TextField, TextFieldProps } from './TextField';\nimport SearchIcon from '@mui/icons-material/Search';\nimport InputAdornment from '@mui/material/InputAdornment';\nimport Box from '@mui/material/Box';\nimport { useTheme } from '@mui/material/styles';\nimport { isMacPlatform } from './useSearchHotkeys';\n\nexport type SearchFieldVariant = 'standard' | 'pill';\n\nexport interface SearchFieldProps extends Omit<TextFieldProps, 'InputProps' | 'variant'> {\n placeholder?: string;\n /** Fires with the next input value on every change. */\n onSearch?: (value: string) => void;\n /** Visual treatment. `pill` renders a fully-rounded input. @default 'standard' */\n variant?: SearchFieldVariant;\n /**\n * Show a keyboard-shortcut hint adornment (⌘ K on Mac, Ctrl + K elsewhere) at\n * the right edge. Pair with `useSearchHotkeys` to wire the key handler.\n */\n shortcutHint?: boolean;\n}\n\nconst ShortcutHint = () => {\n // We render nothing on the server (and on the first client render) because\n // we have no reliable SSR signal for platform — `navigator.platform` is only\n // available after hydration. Rendering either default (⌘ or Ctrl) would be\n // wrong roughly half the time, so we accept a one-frame flash and swap to\n // the correct glyph in a post-mount effect. The hint is decorative.\n const [mounted, setMounted] = useState(false);\n useEffect(() => {\n setMounted(true);\n }, []);\n if (!mounted) return null;\n const isMac = isMacPlatform();\n // Mac convention is the cmd glyph + a thin gap before the letter; on other\n // platforms the explicit \"Ctrl + K\" form reads better than \"CtrlK\".\n const label = isMac ? '⌘ K' : 'Ctrl + K';\n return (\n <Box\n component=\"span\"\n aria-hidden\n sx={{\n fontFamily: 'monospace',\n fontSize: 11,\n letterSpacing: 0.4,\n px: 0.75,\n py: 0.25,\n borderRadius: 1,\n border: '1px solid',\n borderColor: 'divider',\n color: 'text.secondary',\n lineHeight: 1,\n }}\n >\n {label}\n </Box>\n );\n};\n\nexport const SearchField = React.forwardRef<HTMLDivElement, SearchFieldProps>(\n function SearchField(\n {\n placeholder = 'Search...',\n onSearch,\n onChange,\n variant = 'standard',\n shortcutHint = false,\n sx,\n ...props\n },\n ref,\n ) {\n const theme = useTheme();\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange?.(e);\n onSearch?.(e.target.value);\n };\n\n const pillInputSx =\n variant === 'pill'\n ? { borderRadius: '999px', paddingRight: '6px' }\n : undefined;\n\n return (\n <TextField\n ref={ref}\n placeholder={placeholder}\n onChange={handleChange}\n sx={sx}\n slotProps={{\n input: {\n ...(pillInputSx ? { sx: pillInputSx } : {}),\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchIcon style={{ fontSize: 18, color: theme.palette.text.disabled }} />\n </InputAdornment>\n ),\n endAdornment: shortcutHint ? (\n <InputAdornment position=\"end\">\n <ShortcutHint />\n </InputAdornment>\n ) : undefined,\n },\n }}\n {...props}\n />\n );\n },\n);\n","import { RefObject, useEffect } from 'react';\n\nexport interface UseSearchHotkeysOptions {\n /** Cmd/Ctrl + K focuses the ref. @default true */\n k?: boolean;\n /** `/` (when not already typing in another field) focuses the ref. @default true */\n slash?: boolean;\n}\n\n/** Detect Mac via the modern `userAgentData.platform`, falling back to `navigator.platform`. */\nexport function isMacPlatform(): boolean {\n if (typeof navigator === 'undefined') return false;\n const uaDataPlatform = (navigator as Navigator & { userAgentData?: { platform?: string } })\n .userAgentData?.platform;\n if (typeof uaDataPlatform === 'string') return /mac/i.test(uaDataPlatform);\n return /Mac|iPhone|iPad|iPod/i.test(navigator.platform);\n}\n\n/**\n * Wire global Cmd+K (Mac) / Ctrl+K (everywhere else) and `/` hotkeys to focus\n * the input pointed to by `inputRef`. The `/` hotkey is suppressed while the\n * user is typing in another input, textarea or contentEditable element so it\n * doesn't hijack normal typing. Either hotkey can be disabled via options.\n */\nexport function useSearchHotkeys(\n inputRef: RefObject<HTMLInputElement | null>,\n options: UseSearchHotkeysOptions = {},\n) {\n const { k: enableK = true, slash: enableSlash = true } = options;\n\n useEffect(() => {\n if (!enableK && !enableSlash) return;\n const mac = isMacPlatform();\n function onKeyDown(event: KeyboardEvent) {\n if (enableK && event.key.toLowerCase() === 'k') {\n // Mac users press Cmd-K (metaKey); Ctrl-K is reserved for kill-to-end-of-line.\n // Everyone else uses Ctrl-K. Exclude Shift/Alt so we don't hijack browser\n // shortcuts like Cmd+Shift+K (Chrome dev tools tab).\n const correctMod = mac ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey;\n if (correctMod && !event.shiftKey && !event.altKey) {\n event.preventDefault();\n inputRef.current?.focus();\n return;\n }\n }\n if (enableSlash && event.key === '/') {\n const target = event.target as HTMLElement | null;\n const typingInField =\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n (target?.isContentEditable ?? false);\n if (!typingInField) {\n event.preventDefault();\n inputRef.current?.focus();\n }\n }\n }\n window.addEventListener('keydown', onKeyDown);\n return () => window.removeEventListener('keydown', onKeyDown);\n }, [inputRef, enableK, enableSlash]);\n}\n","export { default as FormControl } from '@mui/material/FormControl';\nexport type { FormControlProps } from '@mui/material/FormControl';\nexport { default as FormLabel } from '@mui/material/FormLabel';\nexport type { FormLabelProps } from '@mui/material/FormLabel';\nexport { default as FormHelperText } from '@mui/material/FormHelperText';\nexport type { FormHelperTextProps } from '@mui/material/FormHelperText';\nexport { default as FormControlLabel } from '@mui/material/FormControlLabel';\nexport type { FormControlLabelProps } from '@mui/material/FormControlLabel';\nexport { default as InputLabel } from '@mui/material/InputLabel';\nexport type { InputLabelProps } from '@mui/material/InputLabel';\nexport { default as InputAdornment } from '@mui/material/InputAdornment';\nexport type { InputAdornmentProps } from '@mui/material/InputAdornment';\n\n","import React from 'react';\nimport MuiToggleButton from '@mui/material/ToggleButton';\nimport type { ToggleButtonProps as MuiToggleButtonProps } from '@mui/material/ToggleButton';\nimport MuiToggleButtonGroup from '@mui/material/ToggleButtonGroup';\nimport type { ToggleButtonGroupProps as MuiToggleButtonGroupProps } from '@mui/material/ToggleButtonGroup';\nimport { styled } from '@mui/material/styles';\n\nexport type ToggleButtonProps = MuiToggleButtonProps\n\nexport const ToggleButton: React.FC<ToggleButtonProps> = (props) => {\n return <MuiToggleButton {...props} />;\n};\n\nexport type ToggleButtonGroupProps = MuiToggleButtonGroupProps\n\nconst StyledToggleButtonGroup = styled(MuiToggleButtonGroup)(({ theme }) => ({\n '& .MuiToggleButton-root': {\n border: `1px solid ${theme.palette.grey[300]}`,\n '&.Mui-selected': {\n backgroundColor: theme.palette.primary.main,\n color: theme.palette.primary.contrastText,\n '&:hover': {\n backgroundColor: theme.palette.primary.light,\n },\n },\n '&:hover': {\n backgroundColor: theme.palette.grey[50],\n },\n },\n}));\n\nexport const ToggleButtonGroup: React.FC<ToggleButtonGroupProps> = (props) => {\n return <StyledToggleButtonGroup {...props} />;\n};\n\n","import React from 'react';\nimport MuiSwitch, { SwitchProps as MuiSwitchProps } from '@mui/material/Switch';\nimport { styled } from '@mui/material/styles';\n\nexport interface SwitchProps extends MuiSwitchProps {\n label?: string;\n labelPosition?: 'left' | 'right';\n}\n\nconst StyledSwitch = styled(MuiSwitch)(({ theme }) => ({\n width: 44,\n height: 24,\n padding: 0,\n '& .MuiSwitch-switchBase': {\n padding: 0,\n margin: 2,\n transitionDuration: '300ms',\n '&.Mui-checked': {\n transform: 'translateX(20px)',\n color: theme.palette.common.white,\n '& + .MuiSwitch-track': {\n backgroundColor: theme.palette.success.main,\n opacity: 1,\n border: 0,\n },\n '&.Mui-disabled + .MuiSwitch-track': {\n opacity: 0.5,\n },\n },\n '&.Mui-focusVisible .MuiSwitch-thumb': {\n color: theme.palette.success.main,\n border: `6px solid ${theme.palette.common.white}`,\n },\n '&.Mui-disabled .MuiSwitch-thumb': {\n color: theme.palette.grey[300],\n },\n '&.Mui-disabled + .MuiSwitch-track': {\n opacity: 0.5,\n backgroundColor: theme.palette.grey[300],\n },\n },\n '& .MuiSwitch-thumb': {\n boxSizing: 'border-box',\n width: 20,\n height: 20,\n },\n '& .MuiSwitch-track': {\n borderRadius: 24 / 2,\n backgroundColor: theme.palette.grey[300],\n opacity: 1,\n transition: theme.transitions.create(['background-color'], {\n duration: 500,\n }),\n },\n}));\n\nexport const Switch: React.FC<SwitchProps> = ({\n label,\n labelPosition = 'right',\n ...props\n}) => {\n const switchComponent = <StyledSwitch {...props} />;\n\n if (!label) {\n return switchComponent;\n }\n\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>\n {labelPosition === 'left' && <span>{label}</span>}\n {switchComponent}\n {labelPosition === 'right' && <span>{label}</span>}\n </div>\n );\n};\n\n","import React from 'react';\nimport MuiCheckbox, { CheckboxProps as MuiCheckboxProps } from '@mui/material/Checkbox';\nimport { styled } from '@mui/material/styles';\nimport FormControlLabel from '@mui/material/FormControlLabel';\n\n/**\n * **Prop-forwarding note.**\n *\n * When `label` is absent, all props (including `sx` and `className`) are\n * forwarded directly to the inner `<Checkbox>` element.\n *\n * When `label` is provided, the component renders:\n * ```\n * <FormControlLabel control={<Checkbox {...props} />} label={label} />\n * ```\n * `sx` and `className` from the spread go to the inner `<Checkbox>`, NOT to\n * the outer `<FormControlLabel>`. If you need to style the label wrapper,\n * use MUI's `FormControlLabel` directly and pass `<Checkbox />` as `control`.\n */\nexport interface CheckboxProps extends Omit<MuiCheckboxProps, 'color'> {\n label?: string;\n labelPosition?: 'left' | 'right';\n}\n\nconst StyledCheckbox = styled(MuiCheckbox)(({ theme }) => ({\n color: theme.palette.grey[400],\n '&.Mui-checked': {\n color: theme.palette.primary.main,\n },\n '&.MuiCheckbox-indeterminate': {\n color: theme.palette.primary.main,\n },\n '&.Mui-disabled': {\n color: theme.palette.grey[300],\n },\n '&:hover': {\n backgroundColor: theme.palette.background.selected,\n },\n '&.Mui-focusVisible': {\n outline: `2px solid ${theme.palette.primary.main}`,\n outlineOffset: 2,\n },\n}));\n\nexport const Checkbox: React.FC<CheckboxProps> = ({\n label,\n labelPosition = 'right',\n ...props\n}) => {\n const checkboxComponent = <StyledCheckbox {...props} />;\n\n if (!label) {\n return checkboxComponent;\n }\n\n const labelPlacementMap: Record<string, 'start' | 'end' | 'top' | 'bottom'> = {\n left: 'start',\n right: 'end',\n };\n\n return (\n <FormControlLabel\n control={checkboxComponent}\n label={label}\n labelPlacement={labelPlacementMap[labelPosition] || 'end'}\n />\n );\n};\n\n","import React from 'react';\nimport MuiRadio, { RadioProps as MuiRadioProps } from '@mui/material/Radio';\nimport { styled } from '@mui/material/styles';\nimport FormControlLabel from '@mui/material/FormControlLabel';\nimport RadioGroup from '@mui/material/RadioGroup';\n\nexport interface RadioProps extends Omit<MuiRadioProps, 'color'> {\n label?: string;\n labelPosition?: 'left' | 'right';\n}\n\nconst StyledRadio = styled(MuiRadio)(({ theme }) => ({\n color: theme.palette.grey[400],\n '&.Mui-checked': {\n color: theme.palette.primary.main,\n },\n '&.Mui-disabled': {\n color: theme.palette.grey[300],\n },\n '&:hover': {\n backgroundColor: theme.palette.background.selected,\n },\n '&.Mui-focusVisible': {\n outline: `2px solid ${theme.palette.primary.main}`,\n outlineOffset: 2,\n },\n}));\n\nexport const Radio: React.FC<RadioProps> = ({\n label,\n labelPosition = 'right',\n ...props\n}) => {\n const radioComponent = <StyledRadio {...props} />;\n\n if (!label) {\n return radioComponent;\n }\n\n const labelPlacementMap: Record<string, 'start' | 'end' | 'top' | 'bottom'> = {\n left: 'start',\n right: 'end',\n };\n\n return (\n <FormControlLabel\n control={radioComponent}\n label={label}\n labelPlacement={labelPlacementMap[labelPosition] || 'end'}\n />\n );\n};\n\nexport { RadioGroup };\n\n","import React from 'react';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\nimport { DatePicker } from '@mui/x-date-pickers/DatePicker';\nimport { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';\nimport { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFnsV3';\n\n/** Props for the DateRangePicker component. */\nexport interface DateRangePickerProps {\n /** The selected start date, or null if unset. */\n startDate: Date | null;\n /** The selected end date, or null if unset. */\n endDate: Date | null;\n /** Callback fired when the start date changes. */\n onStartDateChange: (date: Date | null) => void;\n /** Callback fired when the end date changes. */\n onEndDateChange: (date: Date | null) => void;\n /** Earliest selectable date for both pickers. */\n minDate?: Date;\n /** Latest selectable date for both pickers. */\n maxDate?: Date;\n /** If true, both date pickers are disabled. @default false */\n disabled?: boolean;\n /** Size of the text field inputs. @default 'small' */\n size?: 'small' | 'medium';\n}\n\nexport const DateRangePicker: React.FC<DateRangePickerProps> = ({\n startDate,\n endDate,\n onStartDateChange,\n onEndDateChange,\n minDate,\n maxDate,\n disabled = false,\n size = 'small',\n}) => {\n return (\n <LocalizationProvider dateAdapter={AdapterDateFns}>\n <Stack direction=\"row\" spacing={1} alignItems=\"center\">\n <DatePicker\n label=\"Start date\"\n value={startDate}\n onChange={onStartDateChange}\n minDate={minDate}\n maxDate={endDate ?? maxDate}\n disabled={disabled}\n slotProps={{\n textField: { size },\n }}\n />\n <Typography variant=\"body2\" color=\"text.secondary\">\n –\n </Typography>\n <DatePicker\n label=\"End date\"\n value={endDate}\n onChange={onEndDateChange}\n minDate={startDate ?? minDate}\n maxDate={maxDate}\n disabled={disabled}\n slotProps={{\n textField: { size },\n }}\n />\n </Stack>\n </LocalizationProvider>\n );\n};\n"],"mappings":"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","names":["CopyableField","default","React","useEffect","useState","Box","useEffect","jsx","useState","useEffect","Box","React","SearchField","default","styled","jsx","styled","jsx","jsxs","styled","jsx","styled","FormControlLabel","jsx","jsx","jsxs"]}
|
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
// src/components/third-party/CodeEditor.tsx
|
|
2
|
+
import { useCallback, useEffect, useState, useRef } from "react";
|
|
3
|
+
import Editor from "@monaco-editor/react";
|
|
4
|
+
import Box from "@mui/material/Box";
|
|
5
|
+
import IconButton from "@mui/material/IconButton";
|
|
6
|
+
import Tooltip from "@mui/material/Tooltip";
|
|
7
|
+
import FullscreenIcon from "@mui/icons-material/Fullscreen";
|
|
8
|
+
import FullscreenExitIcon from "@mui/icons-material/FullscreenExit";
|
|
9
|
+
import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
|
|
10
|
+
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
|
|
11
|
+
import ExpandLessIcon from "@mui/icons-material/ExpandLess";
|
|
12
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
|
+
var configureTypeScript = (monaco) => {
|
|
14
|
+
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
|
|
15
|
+
target: monaco.languages.typescript.ScriptTarget.ES2020,
|
|
16
|
+
allowNonTsExtensions: true,
|
|
17
|
+
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
|
|
18
|
+
module: monaco.languages.typescript.ModuleKind.ESNext,
|
|
19
|
+
noEmit: false,
|
|
20
|
+
lib: ["es2020", "dom"],
|
|
21
|
+
noUnusedLocals: false,
|
|
22
|
+
noUnusedParameters: false,
|
|
23
|
+
noImplicitAny: false,
|
|
24
|
+
noImplicitReturns: false,
|
|
25
|
+
noFallthroughCasesInSwitch: false,
|
|
26
|
+
// Treat every file as a module so top-level declarations don't clash
|
|
27
|
+
// across files in the workspace (prevents false "Cannot redeclare" errors).
|
|
28
|
+
moduleDetection: 3
|
|
29
|
+
// ts.ModuleDetectionKind.Force
|
|
30
|
+
});
|
|
31
|
+
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
|
|
32
|
+
noSemanticValidation: false,
|
|
33
|
+
noSyntaxValidation: false,
|
|
34
|
+
noSuggestionDiagnostics: true,
|
|
35
|
+
diagnosticCodesToIgnore: [
|
|
36
|
+
6133,
|
|
37
|
+
// 'x' is declared but its value is never read
|
|
38
|
+
6196
|
|
39
|
+
// 'x' is declared but its value is never read (different variant)
|
|
40
|
+
]
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
var CodeEditor = ({
|
|
44
|
+
value,
|
|
45
|
+
onChange,
|
|
46
|
+
language = "typescript",
|
|
47
|
+
height = "400px",
|
|
48
|
+
minHeight,
|
|
49
|
+
theme: themeProp,
|
|
50
|
+
lineNumbers = "on",
|
|
51
|
+
options,
|
|
52
|
+
onMount,
|
|
53
|
+
onValidate,
|
|
54
|
+
editorRef,
|
|
55
|
+
monacoRef,
|
|
56
|
+
onFullscreenChange,
|
|
57
|
+
containerProps,
|
|
58
|
+
typeDefinitions,
|
|
59
|
+
externalModelManagement = false
|
|
60
|
+
}) => {
|
|
61
|
+
const [isEditorReady, setIsEditorReady] = useState(false);
|
|
62
|
+
const [validationErrors, setValidationErrors] = useState([]);
|
|
63
|
+
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
64
|
+
const [tsCode, setTsCode] = useState(value);
|
|
65
|
+
const [actualHeight, setActualHeight] = useState(
|
|
66
|
+
typeof height === "number" ? `${height}px` : height
|
|
67
|
+
);
|
|
68
|
+
const [showProblems, setShowProblems] = useState(false);
|
|
69
|
+
const [hasUserToggledProblems, setHasUserToggledProblems] = useState(false);
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
if (hasUserToggledProblems) return;
|
|
72
|
+
if (validationErrors.length > 0) {
|
|
73
|
+
setShowProblems(true);
|
|
74
|
+
} else {
|
|
75
|
+
setShowProblems(false);
|
|
76
|
+
}
|
|
77
|
+
}, [validationErrors, hasUserToggledProblems]);
|
|
78
|
+
const internalEditorRef = useRef(null);
|
|
79
|
+
const internalMonacoRef = useRef(null);
|
|
80
|
+
const finalEditorRef = editorRef || internalEditorRef;
|
|
81
|
+
const finalMonacoRef = monacoRef || internalMonacoRef;
|
|
82
|
+
useEffect(() => {
|
|
83
|
+
if (isFullscreen) {
|
|
84
|
+
setActualHeight("calc(100vh - 80px)");
|
|
85
|
+
} else {
|
|
86
|
+
setActualHeight(typeof height === "number" ? `${height}px` : height);
|
|
87
|
+
}
|
|
88
|
+
}, [height, isFullscreen]);
|
|
89
|
+
const toggleFullscreen = useCallback(() => {
|
|
90
|
+
const newFullscreenState = !isFullscreen;
|
|
91
|
+
setIsFullscreen(newFullscreenState);
|
|
92
|
+
if (onFullscreenChange) {
|
|
93
|
+
onFullscreenChange(newFullscreenState);
|
|
94
|
+
}
|
|
95
|
+
}, [isFullscreen, onFullscreenChange]);
|
|
96
|
+
const gotoMarker = useCallback(
|
|
97
|
+
(marker) => {
|
|
98
|
+
const ed = finalEditorRef?.current;
|
|
99
|
+
if (!ed) return;
|
|
100
|
+
const position = { lineNumber: marker.startLineNumber, column: marker.startColumn || 1 };
|
|
101
|
+
try {
|
|
102
|
+
ed.revealPositionInCenter(position);
|
|
103
|
+
ed.setPosition(position);
|
|
104
|
+
ed.focus();
|
|
105
|
+
} catch (e) {
|
|
106
|
+
console.error("CodeEditor: Failed to navigate to marker", e);
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
[finalEditorRef]
|
|
110
|
+
);
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
if (!isFullscreen) return;
|
|
113
|
+
function escapeHandler(event) {
|
|
114
|
+
if (event.key === "Escape") {
|
|
115
|
+
event.preventDefault();
|
|
116
|
+
event.stopPropagation();
|
|
117
|
+
setIsFullscreen(false);
|
|
118
|
+
if (onFullscreenChange) {
|
|
119
|
+
onFullscreenChange(false);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
window.addEventListener("keydown", escapeHandler, { capture: true });
|
|
124
|
+
return () => {
|
|
125
|
+
window.removeEventListener("keydown", escapeHandler, { capture: true });
|
|
126
|
+
};
|
|
127
|
+
}, [isFullscreen, onFullscreenChange]);
|
|
128
|
+
const handleEditorDidMount = useCallback(
|
|
129
|
+
(editor, monaco) => {
|
|
130
|
+
console.log("CodeEditor: onMount called", { editor: !!editor, monaco: !!monaco });
|
|
131
|
+
try {
|
|
132
|
+
configureTypeScript(monaco);
|
|
133
|
+
} catch (e) {
|
|
134
|
+
console.error("CodeEditor: Failed to configure TypeScript", e);
|
|
135
|
+
}
|
|
136
|
+
if (finalEditorRef) {
|
|
137
|
+
finalEditorRef.current = editor;
|
|
138
|
+
}
|
|
139
|
+
if (finalMonacoRef) {
|
|
140
|
+
finalMonacoRef.current = monaco;
|
|
141
|
+
}
|
|
142
|
+
setIsEditorReady(true);
|
|
143
|
+
console.log("CodeEditor: Editor ready");
|
|
144
|
+
try {
|
|
145
|
+
editor.addCommand(monaco.KeyCode.Escape, () => {
|
|
146
|
+
if (isFullscreen) {
|
|
147
|
+
setIsFullscreen(false);
|
|
148
|
+
if (onFullscreenChange) {
|
|
149
|
+
onFullscreenChange(false);
|
|
150
|
+
}
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
return false;
|
|
154
|
+
});
|
|
155
|
+
editor.onDidChangeModelDecorations(() => {
|
|
156
|
+
const model2 = editor.getModel();
|
|
157
|
+
if (model2 && onValidate) {
|
|
158
|
+
const markers = monaco.editor.getModelMarkers({ resource: model2.uri });
|
|
159
|
+
onValidate(markers);
|
|
160
|
+
setValidationErrors(markers);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
const model = editor.getModel();
|
|
164
|
+
if (model && onValidate) {
|
|
165
|
+
const markers = monaco.editor.getModelMarkers({ resource: model.uri });
|
|
166
|
+
onValidate(markers);
|
|
167
|
+
setValidationErrors(markers);
|
|
168
|
+
}
|
|
169
|
+
} catch (e) {
|
|
170
|
+
console.error("CodeEditor: Error setting up editor callbacks", e);
|
|
171
|
+
}
|
|
172
|
+
if (onMount) {
|
|
173
|
+
try {
|
|
174
|
+
onMount(editor, monaco);
|
|
175
|
+
} catch (e) {
|
|
176
|
+
console.error("CodeEditor: Error in custom onMount", e);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
[isFullscreen, onFullscreenChange, onValidate, onMount, finalEditorRef, finalMonacoRef]
|
|
181
|
+
);
|
|
182
|
+
useEffect(() => {
|
|
183
|
+
if (!isEditorReady || !finalMonacoRef?.current || !typeDefinitions) return;
|
|
184
|
+
const monaco = finalMonacoRef.current;
|
|
185
|
+
const definitions = Array.isArray(typeDefinitions) ? typeDefinitions : [typeDefinitions];
|
|
186
|
+
const uris = [];
|
|
187
|
+
try {
|
|
188
|
+
definitions.forEach((def, index) => {
|
|
189
|
+
if (def && def.trim()) {
|
|
190
|
+
const uri = `ts:filename/custom-types-${index}.d.ts`;
|
|
191
|
+
uris.push(uri);
|
|
192
|
+
monaco.languages.typescript.typescriptDefaults.addExtraLib(def, uri);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
} catch (error) {
|
|
196
|
+
console.error("CodeEditor: Error adding type definitions:", error);
|
|
197
|
+
}
|
|
198
|
+
}, [isEditorReady, finalMonacoRef, typeDefinitions]);
|
|
199
|
+
const handleCodeChange = (newValue) => {
|
|
200
|
+
const valueStr = newValue || "";
|
|
201
|
+
setTsCode(valueStr);
|
|
202
|
+
onChange(valueStr);
|
|
203
|
+
};
|
|
204
|
+
useEffect(() => {
|
|
205
|
+
if (externalModelManagement) return;
|
|
206
|
+
if (value !== tsCode) {
|
|
207
|
+
setTsCode(value);
|
|
208
|
+
if (isEditorReady && finalEditorRef?.current) {
|
|
209
|
+
const editor = finalEditorRef.current;
|
|
210
|
+
const currentValue = editor.getValue();
|
|
211
|
+
if (currentValue !== value) {
|
|
212
|
+
editor.setValue(value);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}, [value, tsCode, isEditorReady, finalEditorRef, externalModelManagement]);
|
|
217
|
+
const editorMinHeight = minHeight ? typeof minHeight === "number" ? `${minHeight}px` : minHeight : "400px";
|
|
218
|
+
const defaultOptions = {
|
|
219
|
+
lineNumbers,
|
|
220
|
+
minimap: { enabled: false },
|
|
221
|
+
readOnly: false,
|
|
222
|
+
wordWrap: "on",
|
|
223
|
+
fontSize: 14,
|
|
224
|
+
fontFamily: 'Monaco, Menlo, "Ubuntu Mono", Consolas, "source-code-pro", monospace',
|
|
225
|
+
automaticLayout: true,
|
|
226
|
+
scrollBeyondLastLine: false,
|
|
227
|
+
theme: themeProp || "vs",
|
|
228
|
+
...options
|
|
229
|
+
};
|
|
230
|
+
return /* @__PURE__ */ jsx(
|
|
231
|
+
Box,
|
|
232
|
+
{
|
|
233
|
+
sx: {
|
|
234
|
+
display: "flex",
|
|
235
|
+
flexDirection: "column",
|
|
236
|
+
height: isFullscreen ? "100vh" : "100%",
|
|
237
|
+
minHeight: isFullscreen ? "100vh" : editorMinHeight,
|
|
238
|
+
position: isFullscreen ? "fixed" : "relative",
|
|
239
|
+
top: isFullscreen ? 0 : "auto",
|
|
240
|
+
left: isFullscreen ? 0 : "auto",
|
|
241
|
+
right: isFullscreen ? 0 : "auto",
|
|
242
|
+
bottom: isFullscreen ? 0 : "auto",
|
|
243
|
+
zIndex: isFullscreen ? 9999 : "auto",
|
|
244
|
+
bgcolor: "background.paper",
|
|
245
|
+
pt: isFullscreen ? "80px" : 0,
|
|
246
|
+
// Add padding top in fullscreen to account for header (64px) + spacing (16px)
|
|
247
|
+
px: isFullscreen ? 2 : 0,
|
|
248
|
+
pb: isFullscreen ? 2 : 0,
|
|
249
|
+
overflow: isFullscreen ? "hidden" : "visible"
|
|
250
|
+
},
|
|
251
|
+
children: /* @__PURE__ */ jsxs(
|
|
252
|
+
Box,
|
|
253
|
+
{
|
|
254
|
+
sx: {
|
|
255
|
+
flex: 1,
|
|
256
|
+
border: 1,
|
|
257
|
+
borderColor: validationErrors.length > 0 ? "error.main" : "divider",
|
|
258
|
+
borderRadius: 1,
|
|
259
|
+
minHeight: editorMinHeight,
|
|
260
|
+
overflow: "hidden",
|
|
261
|
+
position: "relative",
|
|
262
|
+
display: "flex",
|
|
263
|
+
flexDirection: "column"
|
|
264
|
+
},
|
|
265
|
+
...containerProps,
|
|
266
|
+
children: [
|
|
267
|
+
/* @__PURE__ */ jsx(Tooltip, { title: isFullscreen ? "Exit Fullscreen" : "Fullscreen", children: /* @__PURE__ */ jsx(
|
|
268
|
+
IconButton,
|
|
269
|
+
{
|
|
270
|
+
onClick: toggleFullscreen,
|
|
271
|
+
size: "small",
|
|
272
|
+
sx: {
|
|
273
|
+
position: isFullscreen ? "fixed" : "absolute",
|
|
274
|
+
top: isFullscreen ? 72 : 8,
|
|
275
|
+
// Position below header in fullscreen mode (header is ~64px)
|
|
276
|
+
right: isFullscreen ? 16 : 8,
|
|
277
|
+
zIndex: 1e4,
|
|
278
|
+
// Ensure it's above other elements
|
|
279
|
+
bgcolor: "rgba(255, 255, 255, 0.7)",
|
|
280
|
+
"&:hover": {
|
|
281
|
+
bgcolor: "rgba(255, 255, 255, 0.9)"
|
|
282
|
+
},
|
|
283
|
+
boxShadow: 1
|
|
284
|
+
},
|
|
285
|
+
children: isFullscreen ? /* @__PURE__ */ jsx(FullscreenExitIcon, { fontSize: "small" }) : /* @__PURE__ */ jsx(FullscreenIcon, { fontSize: "small" })
|
|
286
|
+
}
|
|
287
|
+
) }),
|
|
288
|
+
/* @__PURE__ */ jsx(
|
|
289
|
+
Box,
|
|
290
|
+
{
|
|
291
|
+
sx: {
|
|
292
|
+
flex: 1,
|
|
293
|
+
display: "flex",
|
|
294
|
+
flexDirection: "column",
|
|
295
|
+
overflow: "hidden",
|
|
296
|
+
minHeight: editorMinHeight,
|
|
297
|
+
position: "relative",
|
|
298
|
+
height: isFullscreen ? "100%" : actualHeight
|
|
299
|
+
},
|
|
300
|
+
children: /* @__PURE__ */ jsx(
|
|
301
|
+
Editor,
|
|
302
|
+
{
|
|
303
|
+
height: "100%",
|
|
304
|
+
defaultLanguage: language,
|
|
305
|
+
defaultValue: value,
|
|
306
|
+
value: tsCode,
|
|
307
|
+
onChange: handleCodeChange,
|
|
308
|
+
onMount: handleEditorDidMount,
|
|
309
|
+
theme: themeProp || "vs",
|
|
310
|
+
options: defaultOptions,
|
|
311
|
+
loading: /* @__PURE__ */ jsx(Box, { sx: { p: 2, textAlign: "center" }, children: "Loading Monaco Editor..." }),
|
|
312
|
+
beforeMount: (monaco) => {
|
|
313
|
+
console.log("CodeEditor: beforeMount called", { monaco: !!monaco });
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
)
|
|
317
|
+
}
|
|
318
|
+
),
|
|
319
|
+
validationErrors.length > 0 && /* @__PURE__ */ jsxs(
|
|
320
|
+
Box,
|
|
321
|
+
{
|
|
322
|
+
sx: {
|
|
323
|
+
borderTop: 1,
|
|
324
|
+
borderColor: "divider",
|
|
325
|
+
bgcolor: "background.default",
|
|
326
|
+
display: "flex",
|
|
327
|
+
flexDirection: "column",
|
|
328
|
+
maxHeight: showProblems ? 180 : 40,
|
|
329
|
+
minHeight: 40,
|
|
330
|
+
transition: "max-height 0.2s ease"
|
|
331
|
+
},
|
|
332
|
+
children: [
|
|
333
|
+
/* @__PURE__ */ jsxs(
|
|
334
|
+
Box,
|
|
335
|
+
{
|
|
336
|
+
sx: {
|
|
337
|
+
display: "flex",
|
|
338
|
+
alignItems: "center",
|
|
339
|
+
px: 1,
|
|
340
|
+
py: 0.5,
|
|
341
|
+
gap: 1,
|
|
342
|
+
borderBottom: showProblems ? "1px solid" : "none",
|
|
343
|
+
borderColor: "divider",
|
|
344
|
+
fontSize: "0.875rem",
|
|
345
|
+
color: "text.secondary"
|
|
346
|
+
},
|
|
347
|
+
children: [
|
|
348
|
+
/* @__PURE__ */ jsx(ErrorOutlineIcon, { color: "error", fontSize: "small" }),
|
|
349
|
+
/* @__PURE__ */ jsx(Box, { sx: { fontWeight: 600, color: "text.primary" }, children: "Problems" }),
|
|
350
|
+
/* @__PURE__ */ jsxs(Box, { sx: { ml: 1 }, children: [
|
|
351
|
+
validationErrors.length,
|
|
352
|
+
" error",
|
|
353
|
+
validationErrors.length > 1 ? "s" : ""
|
|
354
|
+
] }),
|
|
355
|
+
/* @__PURE__ */ jsx(Box, { sx: { flex: 1 } }),
|
|
356
|
+
/* @__PURE__ */ jsx(
|
|
357
|
+
IconButton,
|
|
358
|
+
{
|
|
359
|
+
size: "small",
|
|
360
|
+
"aria-label": "Toggle problems panel",
|
|
361
|
+
onClick: () => {
|
|
362
|
+
setHasUserToggledProblems(true);
|
|
363
|
+
setShowProblems((s) => !s);
|
|
364
|
+
},
|
|
365
|
+
children: showProblems ? /* @__PURE__ */ jsx(ExpandMoreIcon, { fontSize: "small" }) : /* @__PURE__ */ jsx(ExpandLessIcon, { fontSize: "small" })
|
|
366
|
+
}
|
|
367
|
+
)
|
|
368
|
+
]
|
|
369
|
+
}
|
|
370
|
+
),
|
|
371
|
+
showProblems && /* @__PURE__ */ jsx(Box, { sx: { overflow: "auto" }, children: validationErrors.map((error, index) => /* @__PURE__ */ jsxs(
|
|
372
|
+
Box,
|
|
373
|
+
{
|
|
374
|
+
onClick: () => gotoMarker(error),
|
|
375
|
+
sx: {
|
|
376
|
+
display: "flex",
|
|
377
|
+
alignItems: "center",
|
|
378
|
+
px: 1.5,
|
|
379
|
+
py: 0.75,
|
|
380
|
+
gap: 1,
|
|
381
|
+
cursor: "pointer",
|
|
382
|
+
"&:hover": { bgcolor: "action.hover" },
|
|
383
|
+
borderBottom: "1px dashed",
|
|
384
|
+
borderColor: "divider",
|
|
385
|
+
fontSize: "0.85rem"
|
|
386
|
+
},
|
|
387
|
+
children: [
|
|
388
|
+
/* @__PURE__ */ jsx(ErrorOutlineIcon, { color: "error", sx: { fontSize: 18 } }),
|
|
389
|
+
/* @__PURE__ */ jsxs(Box, { sx: { color: "text.secondary", width: 64 }, children: [
|
|
390
|
+
"Line ",
|
|
391
|
+
error.startLineNumber
|
|
392
|
+
] }),
|
|
393
|
+
/* @__PURE__ */ jsx(Box, { sx: { color: "text.primary", flex: 1, minWidth: 0 }, children: error.message })
|
|
394
|
+
]
|
|
395
|
+
},
|
|
396
|
+
`${error.startLineNumber}-${error.startColumn}-${index}`
|
|
397
|
+
)) })
|
|
398
|
+
]
|
|
399
|
+
}
|
|
400
|
+
)
|
|
401
|
+
]
|
|
402
|
+
}
|
|
403
|
+
)
|
|
404
|
+
}
|
|
405
|
+
);
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
export {
|
|
409
|
+
CodeEditor
|
|
410
|
+
};
|
|
411
|
+
//# sourceMappingURL=chunk-3KCXCVOX.mjs.map
|