@cere/cere-design-system 0.0.45 → 0.1.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/dist/WorkflowNode-BnxXO6t_.d.mts +46 -0
- package/dist/WorkflowNode-BnxXO6t_.d.ts +46 -0
- package/dist/buttons.d.mts +114 -0
- package/dist/buttons.d.ts +114 -0
- package/dist/buttons.js +19 -0
- package/dist/buttons.js.map +1 -0
- package/dist/buttons.mjs +19 -0
- package/dist/buttons.mjs.map +1 -0
- package/dist/carousel.d.mts +51 -0
- package/dist/carousel.d.ts +51 -0
- package/dist/carousel.js +185 -0
- package/dist/carousel.js.map +1 -0
- package/dist/carousel.mjs +185 -0
- package/dist/carousel.mjs.map +1 -0
- package/dist/charts.d.mts +209 -0
- package/dist/charts.d.ts +209 -0
- package/dist/charts.js +20 -0
- package/dist/charts.js.map +1 -0
- package/dist/charts.mjs +20 -0
- package/dist/charts.mjs.map +1 -0
- package/dist/chunk-27JEWSWA.mjs +233 -0
- package/dist/chunk-27JEWSWA.mjs.map +1 -0
- package/dist/chunk-2EBCST6X.js +25 -0
- package/dist/chunk-2EBCST6X.js.map +1 -0
- package/dist/chunk-3WCMINE5.mjs +490 -0
- package/dist/chunk-3WCMINE5.mjs.map +1 -0
- package/dist/chunk-463SRKKD.js +111 -0
- package/dist/chunk-463SRKKD.js.map +1 -0
- package/dist/chunk-5ASG6G6U.mjs +40 -0
- package/dist/chunk-5ASG6G6U.mjs.map +1 -0
- package/dist/chunk-6EUAU67C.mjs +374 -0
- package/dist/chunk-6EUAU67C.mjs.map +1 -0
- package/dist/chunk-AIY6222Q.js +11 -0
- package/dist/chunk-AIY6222Q.js.map +1 -0
- package/dist/chunk-AJBM7IE6.mjs +2366 -0
- package/dist/chunk-AJBM7IE6.mjs.map +1 -0
- package/dist/chunk-ATIFLPH6.mjs +278 -0
- package/dist/chunk-ATIFLPH6.mjs.map +1 -0
- package/dist/chunk-BIZK6FUD.js +37 -0
- package/dist/chunk-BIZK6FUD.js.map +1 -0
- package/dist/chunk-CCN6M4LI.js +103 -0
- package/dist/chunk-CCN6M4LI.js.map +1 -0
- package/dist/chunk-CUCKULYC.mjs +2658 -0
- package/dist/chunk-CUCKULYC.mjs.map +1 -0
- package/dist/chunk-CWJ4OU6W.mjs +45 -0
- package/dist/chunk-CWJ4OU6W.mjs.map +1 -0
- package/dist/chunk-EOF3QNPF.js +2366 -0
- package/dist/chunk-EOF3QNPF.js.map +1 -0
- package/dist/chunk-FFZ5S7PQ.mjs +146 -0
- package/dist/chunk-FFZ5S7PQ.mjs.map +1 -0
- package/dist/chunk-FN5YL4BK.js +278 -0
- package/dist/chunk-FN5YL4BK.js.map +1 -0
- package/dist/chunk-HLH2VWXL.js +2658 -0
- package/dist/chunk-HLH2VWXL.js.map +1 -0
- package/dist/chunk-IE6GCHDI.mjs +530 -0
- package/dist/chunk-IE6GCHDI.mjs.map +1 -0
- package/dist/chunk-JBHRAAN3.js +31 -0
- package/dist/chunk-JBHRAAN3.js.map +1 -0
- package/dist/chunk-JS4IB5IU.mjs +162 -0
- package/dist/chunk-JS4IB5IU.mjs.map +1 -0
- package/dist/chunk-KF2Y7HO3.js +595 -0
- package/dist/chunk-KF2Y7HO3.js.map +1 -0
- package/dist/chunk-KPDYKK3V.js +162 -0
- package/dist/chunk-KPDYKK3V.js.map +1 -0
- package/dist/chunk-KVBMZNWT.mjs +103 -0
- package/dist/chunk-KVBMZNWT.mjs.map +1 -0
- package/dist/chunk-L2TIGA7I.js +530 -0
- package/dist/chunk-L2TIGA7I.js.map +1 -0
- package/dist/chunk-MNM6HE72.js +146 -0
- package/dist/chunk-MNM6HE72.js.map +1 -0
- package/dist/chunk-NXTVJ6PY.js +374 -0
- package/dist/chunk-NXTVJ6PY.js.map +1 -0
- package/dist/chunk-OWWDNDF4.js +40 -0
- package/dist/chunk-OWWDNDF4.js.map +1 -0
- package/dist/chunk-PHMNZK2R.mjs +18 -0
- package/dist/chunk-PHMNZK2R.mjs.map +1 -0
- package/dist/chunk-PWF2NJDB.mjs +377 -0
- package/dist/chunk-PWF2NJDB.mjs.map +1 -0
- package/dist/chunk-QBCRH7YF.mjs +37 -0
- package/dist/chunk-QBCRH7YF.mjs.map +1 -0
- package/dist/chunk-QD6RLAO2.mjs +11 -0
- package/dist/chunk-QD6RLAO2.mjs.map +1 -0
- package/dist/chunk-QY65OUAC.mjs +111 -0
- package/dist/chunk-QY65OUAC.mjs.map +1 -0
- package/dist/chunk-QYYQYZHV.js +45 -0
- package/dist/chunk-QYYQYZHV.js.map +1 -0
- package/dist/chunk-T7LPABOL.mjs +595 -0
- package/dist/chunk-T7LPABOL.mjs.map +1 -0
- package/dist/chunk-THQKYTQE.js +490 -0
- package/dist/chunk-THQKYTQE.js.map +1 -0
- package/dist/chunk-U2QHFISG.js +18 -0
- package/dist/chunk-U2QHFISG.js.map +1 -0
- package/dist/chunk-UPGFBPFX.mjs +25 -0
- package/dist/chunk-UPGFBPFX.mjs.map +1 -0
- package/dist/chunk-X7E6GMFL.js +233 -0
- package/dist/chunk-X7E6GMFL.js.map +1 -0
- package/dist/chunk-XF66WQZE.mjs +1535 -0
- package/dist/chunk-XF66WQZE.mjs.map +1 -0
- package/dist/chunk-YQOZPLTY.js +1535 -0
- package/dist/chunk-YQOZPLTY.js.map +1 -0
- package/dist/chunk-ZGCN5WCG.js +377 -0
- package/dist/chunk-ZGCN5WCG.js.map +1 -0
- package/dist/chunk-ZP26PGMS.mjs +31 -0
- package/dist/chunk-ZP26PGMS.mjs.map +1 -0
- package/dist/feedback.d.mts +356 -0
- package/dist/feedback.d.ts +356 -0
- package/dist/feedback.js +43 -0
- package/dist/feedback.js.map +1 -0
- package/dist/feedback.mjs +43 -0
- package/dist/feedback.mjs.map +1 -0
- package/dist/icons.d.mts +22 -0
- package/dist/icons.d.ts +22 -0
- package/dist/icons.js +23 -0
- package/dist/icons.js.map +1 -0
- package/dist/icons.mjs +23 -0
- package/dist/icons.mjs.map +1 -0
- package/dist/index.d.mts +165 -3080
- package/dist/index.d.ts +165 -3080
- package/dist/index.js +320 -10082
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +262 -9983
- package/dist/index.mjs.map +1 -1
- package/dist/inputs.d.mts +109 -0
- package/dist/inputs.d.ts +109 -0
- package/dist/inputs.js +43 -0
- package/dist/inputs.js.map +1 -0
- package/dist/inputs.mjs +43 -0
- package/dist/inputs.mjs.map +1 -0
- package/dist/layout.d.mts +927 -0
- package/dist/layout.d.ts +927 -0
- package/dist/layout.js +122 -0
- package/dist/layout.js.map +1 -0
- package/dist/layout.mjs +122 -0
- package/dist/layout.mjs.map +1 -0
- package/dist/navigation.d.mts +716 -0
- package/dist/navigation.d.ts +716 -0
- package/dist/navigation.js +58 -0
- package/dist/navigation.js.map +1 -0
- package/dist/navigation.mjs +58 -0
- package/dist/navigation.mjs.map +1 -0
- package/dist/third-party.d.mts +637 -0
- package/dist/third-party.d.ts +637 -0
- package/dist/third-party.js +45 -0
- package/dist/third-party.js.map +1 -0
- package/dist/third-party.mjs +45 -0
- package/dist/third-party.mjs.map +1 -0
- package/dist/utilities.d.mts +39 -0
- package/dist/utilities.d.ts +39 -0
- package/dist/utilities.js +19 -0
- package/dist/utilities.js.map +1 -0
- package/dist/utilities.mjs +19 -0
- package/dist/utilities.mjs.map +1 -0
- package/package.json +55 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/charts/ChartWidget/ChartWidget.tsx","../src/components/charts/MetricsChart/MetricsChart.tsx","../src/components/charts/MetricsChart/PeriodSelect.tsx","../src/components/charts/TimeSeriesGraph/TimeSeriesGraph.tsx","../src/components/charts/TimeSeriesGraph/TimeRangeSelect.tsx","../src/components/charts/TimeSeriesGraph/SummaryStats.tsx"],"sourcesContent":["import { ReactNode } from 'react';\nimport { Box, Stack, Typography, styled, useTheme } from '@mui/material';\nimport { LineChart } from '@mui/x-charts';\nimport size from 'byte-size';\nimport { format } from 'date-fns';\n\ntype ChartWidgetHistoryRecord = {\n date: Date;\n value: number;\n};\n\nexport type ChartWidgetProps = {\n title: string;\n value?: ReactNode;\n history?: ChartWidgetHistoryRecord[];\n formatValue?: (value: number) => string;\n};\n\nconst Chart = styled(Box)(() => ({\n height: 200,\n}));\n\nexport const ChartWidget = ({\n title,\n value,\n history,\n formatValue = (value) => size(value || 0).toString(),\n}: ChartWidgetProps) => {\n const theme = useTheme();\n\n return (\n <Stack spacing={1}>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {title}\n </Typography>\n <Typography fontWeight=\"bold\">{value}</Typography>\n\n <Chart>\n <LineChart\n dataset={history || []}\n axisHighlight={{ x: 'none', y: 'none' }}\n grid={{ horizontal: true, vertical: false }}\n margin={{ top: 10, right: 20, bottom: 40, left: 40 }}\n colors={[theme.palette.primary.main]}\n slots={{\n noDataOverlay: () => null,\n }}\n yAxis={[\n {\n dataKey: 'value',\n disableLine: true,\n disableTicks: true,\n min: history?.length ? undefined : 0,\n max: history?.length ? undefined : 100,\n tickNumber: history?.length ? undefined : 5,\n valueFormatter: (value) => formatValue(value || 0),\n tickLabelStyle: {\n fontSize: 10,\n },\n },\n ]}\n xAxis={[\n {\n dataKey: 'date',\n min: history && Math.min(...history.map((record) => +record.date)),\n max: history && Math.max(...history.map((record) => +record.date)),\n disableLine: true,\n disableTicks: true,\n valueFormatter: (date) => format(date, 'do MMM'),\n tickPlacement: 'end',\n tickNumber: 1,\n\n tickLabelStyle: {\n fontSize: 10,\n transform: 'translate(-16px, 16px) rotate(-30deg)',\n },\n },\n ]}\n series={[\n {\n curve: 'linear',\n dataKey: 'value',\n showMark: false,\n valueFormatter: (value) => formatValue(value || 0),\n },\n ]}\n />\n </Chart>\n </Stack>\n );\n};\n","import { format, startOfDay, subHours, subWeeks, subMonths } from 'date-fns';\nimport { LineChart } from '@mui/x-charts';\nimport { useDrawingArea, useYScale } from '@mui/x-charts/hooks';\nimport { Box, Card, CardHeader, CardMedia, Divider, Stack, styled, Typography, useTheme } from '@mui/material';\n\nimport { deploymentSurfaceTokens } from '../../../theme';\nimport { PeriodSelect, MetricsPeriod } from './PeriodSelect';\nimport { useMemo, useState } from 'react';\nimport { BytesSize } from '../../utilities/BytesSize';\n\ntype MetricsHistoryRecord = {\n storedBytes: number;\n transferredBytes: number;\n puts: number;\n gets: number;\n recordTime: Date;\n};\n\nexport type MetricsChartProps = {\n history?: MetricsHistoryRecord[];\n};\n\nconst mapPeriodToFromDate = (period: MetricsPeriod = 'month') => {\n const date = new Date();\n\n if (period === 'hour') {\n return subHours(date, 1);\n }\n\n if (period === 'day') {\n return subHours(date, 24);\n }\n\n if (period === 'week') {\n return startOfDay(subWeeks(date, 1));\n }\n\n return startOfDay(subMonths(date, 1));\n};\n\nconst Chart = styled(LineChart)({\n height: 320,\n marginBottom: 16,\n});\n\nconst NoDataRect = styled('rect')({\n fill: deploymentSurfaceTokens.highlightBg,\n});\n\nconst LoadingText = styled('text')(({ theme }) => ({\n stroke: 'none',\n fill: theme.palette.text.primary,\n shapeRendering: 'crispEdges',\n textAnchor: 'middle',\n dominantBaseline: 'middle',\n}));\n\n/**\n * TODO: Refactor this component to use shared graphs configuration\n */\nexport const MetricsChart = ({ history = [] }: MetricsChartProps) => {\n const theme = useTheme();\n const [period, setPeriod] = useState<MetricsPeriod>('week');\n const periodFrom = useMemo(() => mapPeriodToFromDate(period), [period]);\n const periodHistory = useMemo(\n () => history.filter((record) => record.recordTime > periodFrom),\n [history, periodFrom],\n );\n\n const total = useMemo(\n () =>\n periodHistory.reduce(\n (acc, record) => ({\n gets: acc.gets + record.gets,\n puts: acc.puts + record.puts,\n storedBytes: acc.storedBytes + record.storedBytes,\n transferredBytes: acc.transferredBytes + record.transferredBytes,\n }),\n { gets: 0, puts: 0, storedBytes: 0, transferredBytes: 0 } as Omit<MetricsHistoryRecord, 'recordTime'>,\n ),\n [periodHistory],\n );\n\n const NoDataOverlay = () => {\n const yScale = useYScale();\n const { left, width, height } = useDrawingArea();\n\n // Conditional handling if bandwidth is not available\n // const bandWidth = xScale.bandwidth ? xScale.bandwidth() : 0;\n\n const [, top] = yScale.range();\n\n const padding = { top: 8, bottom: 8, left: 20, right: 20 };\n const text = 'No data for selected period';\n\n const textWidth = 211;\n const textHeight = 24;\n\n const backgroundWidth = textWidth + padding.left + padding.right;\n const backgroundHeight = textHeight + padding.top + padding.bottom;\n\n const rectX = left + (width - backgroundWidth) / 2;\n const rectY = top + (height - backgroundHeight) / 2;\n return (\n <g>\n <NoDataRect x={rectX} y={rectY} width={backgroundWidth} height={backgroundHeight} />\n <LoadingText style={{ ...theme.typography.subtitle1 }} x={left + width / 2} y={top + height / 2}>\n {text}\n </LoadingText>\n </g>\n );\n };\n\n return (\n <Card>\n <CardHeader title=\"GET / PUT Requests\" action={<PeriodSelect value={period} onChange={setPeriod} />} />\n <CardMedia>\n <Chart\n skipAnimation\n dataset={periodHistory || []}\n axisHighlight={{ x: 'none', y: 'none' }}\n grid={{ horizontal: true, vertical: false }}\n margin={{ top: 10, right: 20, bottom: 40, left: 40 }}\n colors={[theme.palette.primary.main, theme.palette.success.main]}\n slots={{\n noDataOverlay: NoDataOverlay,\n }}\n slotProps={{\n noDataOverlay: {\n style: {\n ...theme.typography.h4,\n },\n },\n }}\n yAxis={\n periodHistory.length\n ? [\n {\n min: periodHistory.length ? undefined : 0,\n max: periodHistory.length ? undefined : 100,\n tickNumber: periodHistory.length ? undefined : 5,\n disableLine: true,\n disableTicks: true,\n tickLabelStyle: {\n fontSize: 10,\n },\n },\n ]\n : []\n }\n xAxis={[\n {\n dataKey: 'recordTime',\n min: periodFrom,\n max: new Date(),\n disableLine: false,\n disableTicks: false,\n valueFormatter: (date) => format(date, 'do MMM'),\n tickMinStep: 3600 * 1000 * 24, // min step: 24h\n\n tickLabelStyle: {\n fontSize: 10,\n transform: 'translate(-16px, 16px) rotate(-30deg)',\n },\n },\n ]}\n series={[\n {\n curve: 'linear',\n dataKey: 'gets',\n showMark: false,\n },\n\n {\n curve: 'linear',\n dataKey: 'puts',\n showMark: false,\n },\n ]}\n />\n {periodHistory.length > 0 && (\n <Stack direction=\"row\" spacing={2} marginY={3} justifyContent=\"center\">\n <Stack direction=\"row\" spacing={1} alignItems=\"center\">\n <Box sx={{ width: 14, height: 14, borderRadius: '4px', backgroundColor: theme.palette.primary.main }} />\n <Typography variant=\"body2\">Get</Typography>\n </Stack>\n\n <Stack direction=\"row\" spacing={1} alignItems=\"center\">\n <Box sx={{ width: 14, height: 14, borderRadius: '4px', backgroundColor: theme.palette.success.main }} />\n <Typography variant=\"body2\">Put</Typography>\n </Stack>\n </Stack>\n )}\n </CardMedia>\n <CardMedia>\n <Divider flexItem />\n <Stack direction=\"row\" spacing={2} padding={2}>\n <Stack direction=\"row\" alignItems=\"center\" spacing={1}>\n <Typography variant=\"body2\" color=\"secondary\">\n GET Requests per account\n </Typography>\n <Typography variant=\"h3\">{total.gets}</Typography>\n </Stack>\n\n <Stack direction=\"row\" alignItems=\"center\" spacing={1}>\n <Typography variant=\"body2\" color=\"secondary\">\n PUT Requests per account\n </Typography>\n <Typography variant=\"h3\">{total.puts}</Typography>\n </Stack>\n\n <Stack direction=\"row\" alignItems=\"center\" spacing={1}>\n <Typography variant=\"body2\" color=\"secondary\">\n Total Consumed per account\n </Typography>\n <Typography variant=\"h3\">\n <BytesSize bytes={total.transferredBytes} />\n </Typography>\n </Stack>\n\n <Stack direction=\"row\" alignItems=\"center\" spacing={1}>\n <Typography variant=\"body2\" color=\"secondary\">\n Total Stored per account\n </Typography>\n <Typography variant=\"h3\">\n <BytesSize bytes={total.storedBytes} />\n </Typography>\n </Stack>\n </Stack>\n </CardMedia>\n </Card>\n );\n};\n","import { MenuItem, TextField } from '@mui/material';\n\nexport type MetricsPeriod = 'hour' | 'day' | 'week' | 'month';\n\nexport type PeriodSelectProps = {\n value?: MetricsPeriod;\n onChange?: (value: MetricsPeriod) => void;\n};\n\ntype Option = {\n value: MetricsPeriod;\n label: string;\n};\n\nconst options: Option[] = [\n /**\n * TODO: Enable the options below when the backend supports them\n */\n // { value: 'hour', label: 'Last hour' },\n // { value: 'day', label: '24 hours' },\n { value: 'week', label: '1 week' },\n { value: 'month', label: '1 month' },\n];\n\nexport const PeriodSelect = ({ value, onChange }: PeriodSelectProps) => (\n <TextField\n select\n size=\"small\"\n value={value}\n defaultValue={options[0].value}\n onChange={(e) => onChange?.(e.target.value as MetricsPeriod)}\n >\n {options.map(({ value, label }) => (\n <MenuItem key={value} value={value}>\n {label}\n </MenuItem>\n ))}\n </TextField>\n);\n","import { ReactNode, useCallback, useMemo, useState } from 'react';\nimport {\n Box,\n Card,\n CardHeader,\n CardMedia,\n CircularProgress,\n Divider,\n Stack,\n Typography,\n styled,\n useTheme,\n} from '@mui/material';\nimport { LineChart } from '@mui/x-charts';\nimport { format } from 'date-fns';\n\nimport { TimeRangeSelect, type TimeRangeOption } from './TimeRangeSelect';\nimport { SummaryStats, type SummaryItem } from './SummaryStats';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * A single data point in a time series.\n * Use `null` for the value to represent missing/gap data — the line will break.\n */\nexport interface DataPoint {\n /** Timestamp of the observation */\n timestamp: Date;\n /** Numeric value, or `null` to indicate a gap in the data */\n value: number | null;\n}\n\n/**\n * Represents one line on the graph (a named data series).\n */\nexport interface DataSeries {\n /** Unique display name for this series (shown in legend) */\n name: string;\n /** CSS color string for the line and legend indicator */\n color: string;\n /** Ordered array of data points */\n data: DataPoint[];\n}\n\nexport interface TimeSeriesGraphProps {\n /** Optional title displayed at the top-left of the graph card */\n title?: string;\n /**\n * Array of data series to render. Each series becomes one line on the graph.\n * There is no hardcoded limit on the number of series.\n */\n series: DataSeries[];\n /**\n * Configurable time range options for the dropdown selector.\n * When omitted, the time range dropdown is not rendered.\n */\n timeRangeOptions?: TimeRangeOption[];\n /** Currently selected time range value (controlled) */\n selectedTimeRange?: string;\n /** Callback invoked when the user picks a different time range */\n onTimeRangeChange?: (value: string) => void;\n /**\n * Optional array of summary statistics displayed below the graph.\n * When omitted or empty, the summary section is hidden.\n */\n summaryItems?: SummaryItem[];\n /**\n * Whether to show the summary statistics section.\n * Defaults to `true`. Set to `false` to explicitly hide, even when `summaryItems` are provided.\n */\n showSummary?: boolean;\n /**\n * Optional header action element rendered to the right of the title\n * (e.g., a secondary dropdown or filter control).\n */\n headerAction?: ReactNode;\n /**\n * When `true`, shows a loading overlay (spinner) over the graph area\n * while the header remains visible and interactive.\n */\n loading?: boolean;\n /**\n * Override the x-axis date format string (date-fns format tokens).\n * When omitted, the format is auto-detected from the data's time span:\n * - <= 24 hours → `'HH:mm'`\n * - > 24 hours → `'do MMM'`\n */\n xAxisFormat?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Styled helpers\n// ---------------------------------------------------------------------------\n\nconst ChartContainer = styled(Box)({\n position: 'relative',\n height: 320,\n});\n\nconst LoadingOverlay = styled(Box)(({ theme }) => ({\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n backgroundColor: 'rgba(255, 255, 255, 0.7)',\n zIndex: 1,\n borderRadius: theme.shape.borderRadius,\n}));\n\nconst LegendDot = styled(Box, {\n shouldForwardProp: (prop) => prop !== 'dotColor',\n})<{ dotColor: string }>(({ dotColor }) => ({\n width: 14,\n height: 14,\n borderRadius: 4,\n backgroundColor: dotColor,\n flexShrink: 0,\n}));\n\n// ---------------------------------------------------------------------------\n// Utility functions\n// ---------------------------------------------------------------------------\n\n/**\n * Formats large Y-axis values into shorthand notation.\n * 1,000 → 1K, 1,000,000 → 1M, 1,000,000,000 → 1B\n */\nconst formatYAxisValue = (value: number): string => {\n const absValue = Math.abs(value);\n if (absValue >= 1_000_000_000) {\n return `${(value / 1_000_000_000).toFixed(absValue % 1_000_000_000 === 0 ? 0 : 1)}B`;\n }\n if (absValue >= 1_000_000) {\n return `${(value / 1_000_000).toFixed(absValue % 1_000_000 === 0 ? 0 : 1)}M`;\n }\n if (absValue >= 1_000) {\n return `${(value / 1_000).toFixed(absValue % 1_000 === 0 ? 0 : 1)}K`;\n }\n return String(value);\n};\n\nconst TWENTY_FOUR_HOURS_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Infers the appropriate x-axis date format string based on the time span of the data.\n * - Span <= 24 hours → `'HH:mm'` (e.g., \"14:30\")\n * - Span > 24 hours → `'do MMM'` (e.g., \"2nd Jan\")\n */\nexport const inferXAxisFormat = (\n min: Date | undefined,\n max: Date | undefined,\n): string => {\n if (!min || !max) return 'do MMM';\n const spanMs = max.getTime() - min.getTime();\n return spanMs <= TWENTY_FOUR_HOURS_MS ? 'HH:mm' : 'do MMM';\n};\n\n/** A single row in the chart dataset — timestamp plus one field per series. */\ntype DatasetRow = Record<string, string | number | Date | null | undefined>;\n\n/**\n * Builds the unified dataset array that MUI X-Charts expects.\n * Each row is keyed by timestamp with one field per series.\n */\nconst buildDataset = (\n series: DataSeries[],\n hiddenSeries: Set<string>,\n): DatasetRow[] => {\n // Collect all unique timestamps across all visible series\n const timestampMap = new Map<number, DatasetRow>();\n\n series.forEach((s) => {\n if (hiddenSeries.has(s.name)) return;\n s.data.forEach((dp) => {\n const ts = dp.timestamp.getTime();\n if (!timestampMap.has(ts)) {\n timestampMap.set(ts, { timestamp: dp.timestamp } as DatasetRow);\n }\n timestampMap.get(ts)![s.name] = dp.value;\n });\n });\n\n // Sort by timestamp ascending\n return Array.from(timestampMap.values()).sort(\n (a, b) => (a.timestamp as Date).getTime() - (b.timestamp as Date).getTime(),\n );\n};\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * A reusable time series graph component that displays one or more data lines\n * over a shared time axis. Supports configurable time range selection,\n * optional summary statistics, interactive legend toggling, crosshair tooltips,\n * and a loading state.\n *\n * Built on `@mui/x-charts` LineChart and the Cere Design System theme.\n *\n * @example\n * ```tsx\n * <TimeSeriesGraph\n * title=\"Engagement over time\"\n * series={[\n * { name: 'Engagements', color: '#6750A4', data: engagementData },\n * { name: 'Unique Streams', color: '#4caf50', data: streamData },\n * ]}\n * timeRangeOptions={[\n * { label: 'Last hour', value: 'hour' },\n * { label: '24 hours', value: 'day' },\n * { label: '1 week', value: 'week' },\n * { label: '1 month', value: 'month' },\n * ]}\n * selectedTimeRange=\"week\"\n * onTimeRangeChange={(range) => fetchData(range)}\n * summaryItems={[\n * { label: 'Total Engagements', value: 11372 },\n * { label: 'Daily Engagements', value: 156 },\n * ]}\n * />\n * ```\n *\n * Figma reference: [ROB Design - Node 162:1172](https://www.figma.com/design/xky11VbkkFcgZLwZE8BdCN/ROB?node-id=162-1172&m=dev)\n */\nexport const TimeSeriesGraph = ({\n title,\n series,\n timeRangeOptions,\n selectedTimeRange,\n onTimeRangeChange,\n summaryItems,\n showSummary = true,\n headerAction,\n loading = false,\n xAxisFormat,\n}: TimeSeriesGraphProps) => {\n const theme = useTheme();\n const [hiddenSeries, setHiddenSeries] = useState<Set<string>>(new Set());\n\n // Build the MUI X-Charts dataset from visible series\n const dataset = useMemo(() => buildDataset(series, hiddenSeries), [series, hiddenSeries]);\n\n // Visible series (exclude hidden)\n const visibleSeries = useMemo(\n () => series.filter((s) => !hiddenSeries.has(s.name)),\n [series, hiddenSeries],\n );\n\n // Colors array matching the order of visible series\n const chartColors = useMemo(() => visibleSeries.map((s) => s.color), [visibleSeries]);\n\n // Toggle a series' visibility\n const handleLegendToggle = useCallback((seriesName: string) => {\n setHiddenSeries((prev) => {\n const next = new Set(prev);\n if (next.has(seriesName)) {\n next.delete(seriesName);\n } else {\n next.add(seriesName);\n }\n return next;\n });\n }, []);\n\n // Compute time bounds for the X-axis from visible data\n const timeBounds = useMemo(() => {\n if (dataset.length === 0) return { min: undefined, max: undefined };\n const timestamps = dataset.map((row) => (row.timestamp as Date).getTime());\n return {\n min: new Date(Math.min(...timestamps)),\n max: new Date(Math.max(...timestamps)),\n };\n }, [dataset]);\n\n // Resolve the x-axis date format: explicit prop wins, otherwise auto-detect\n const resolvedXAxisFormat = useMemo(\n () => xAxisFormat ?? inferXAxisFormat(timeBounds.min, timeBounds.max),\n [xAxisFormat, timeBounds.min, timeBounds.max],\n );\n\n // Determine whether we have data to display\n const hasData = dataset.length > 0;\n\n // Whether to render the summary section\n const shouldShowSummary = showSummary && summaryItems && summaryItems.length > 0;\n\n // Build the header action area (time range + optional custom action)\n const headerActionElement = (\n <Stack direction=\"row\" spacing={1} alignItems=\"center\">\n {headerAction}\n {timeRangeOptions && timeRangeOptions.length > 0 && (\n <TimeRangeSelect\n options={timeRangeOptions}\n value={selectedTimeRange}\n onChange={onTimeRangeChange}\n />\n )}\n </Stack>\n );\n\n // Determine whether to show the header at all\n const showHeader = !!title || !!headerAction || (timeRangeOptions && timeRangeOptions.length > 0);\n\n return (\n <Card\n aria-label={title ? `Line chart showing ${title}` : 'Line chart'}\n role=\"figure\"\n >\n {showHeader && (\n <CardHeader\n title={title}\n titleTypographyProps={{\n variant: 'subtitle1',\n fontWeight: 500,\n }}\n action={headerActionElement}\n />\n )}\n\n <CardMedia>\n <ChartContainer>\n {loading && (\n <LoadingOverlay role=\"status\" aria-label=\"Loading chart data\">\n <CircularProgress size={40} />\n </LoadingOverlay>\n )}\n\n <LineChart\n dataset={dataset}\n axisHighlight={{ x: 'line', y: 'none' }}\n grid={{ horizontal: true, vertical: false }}\n margin={{ top: 10, right: 20, bottom: 40, left: 50 }}\n colors={chartColors.length > 0 ? chartColors : [theme.palette.primary.main]}\n slots={{\n noDataOverlay: () => null,\n }}\n tooltip={{ trigger: hasData ? 'axis' : 'none' }}\n yAxis={[\n {\n disableLine: true,\n disableTicks: true,\n min: hasData ? undefined : 0,\n max: hasData ? undefined : 100,\n tickNumber: hasData ? undefined : 5,\n valueFormatter: (value: number) => formatYAxisValue(value || 0),\n tickLabelStyle: {\n fontSize: 10,\n },\n },\n ]}\n xAxis={[\n {\n dataKey: 'timestamp',\n scaleType: 'time',\n min: timeBounds.min,\n max: timeBounds.max,\n disableLine: true,\n disableTicks: true,\n valueFormatter: (date: Date) => format(date, resolvedXAxisFormat),\n tickLabelStyle: {\n fontSize: 10,\n },\n },\n ]}\n series={visibleSeries.map((s) => ({\n curve: 'linear' as const,\n dataKey: s.name,\n label: s.name,\n showMark: false,\n connectNulls: false,\n }))}\n // Hide the built-in legend — we render a custom one below\n slotProps={{\n legend: { hidden: true },\n }}\n />\n </ChartContainer>\n\n {/* Custom interactive legend */}\n {series.length > 0 && (\n <Stack\n direction=\"row\"\n spacing={2}\n justifyContent=\"center\"\n paddingY={1}\n flexWrap=\"wrap\"\n useFlexGap\n role=\"list\"\n aria-label=\"Chart legend\"\n >\n {series.map((s) => {\n const isHidden = hiddenSeries.has(s.name);\n return (\n <Stack\n key={s.name}\n direction=\"row\"\n spacing={1}\n alignItems=\"center\"\n role=\"listitem\"\n onClick={() => handleLegendToggle(s.name)}\n sx={{\n cursor: 'pointer',\n opacity: isHidden ? 0.4 : 1,\n transition: 'opacity 0.2s ease',\n userSelect: 'none',\n }}\n aria-pressed={!isHidden}\n aria-label={`Toggle ${s.name} visibility`}\n >\n <LegendDot dotColor={s.color} />\n <Typography variant=\"body2\">{s.name}</Typography>\n </Stack>\n );\n })}\n </Stack>\n )}\n </CardMedia>\n\n {/* Summary statistics */}\n {shouldShowSummary && (\n <>\n <Divider />\n <SummaryStats items={summaryItems!} />\n </>\n )}\n </Card>\n );\n};\n","import { MenuItem, TextField } from '@mui/material';\n\n/**\n * Represents a single time range option in the dropdown.\n */\nexport interface TimeRangeOption {\n /** Display label shown in the dropdown (e.g., \"1 week\") */\n label: string;\n /** Value identifier passed to the callback on selection */\n value: string;\n}\n\nexport interface TimeRangeSelectProps {\n /** Available time range options */\n options: TimeRangeOption[];\n /** Currently selected time range value */\n value?: string;\n /** Callback invoked when user selects a different time range */\n onChange?: (value: string) => void;\n}\n\n/**\n * Configurable time range dropdown selector.\n * Renders a compact select field with the provided time range options.\n *\n * @example\n * ```tsx\n * <TimeRangeSelect\n * options={[\n * { label: 'Last hour', value: 'hour' },\n * { label: '24 hours', value: 'day' },\n * { label: '1 week', value: 'week' },\n * ]}\n * value=\"week\"\n * onChange={(value) => console.log(value)}\n * />\n * ```\n */\nexport const TimeRangeSelect = ({ options, value, onChange }: TimeRangeSelectProps) => (\n <TextField\n select\n size=\"small\"\n value={value ?? (options.length > 0 ? options[0].value : '')}\n onChange={(e) => onChange?.(e.target.value)}\n aria-label=\"Time range selector\"\n sx={{ minWidth: 120 }}\n >\n {options.map((option) => (\n <MenuItem key={option.value} value={option.value}>\n {option.label}\n </MenuItem>\n ))}\n </TextField>\n);\n","import { Stack, Typography } from '@mui/material';\n\n/**\n * Represents a single summary statistic item displayed below the graph.\n */\nexport interface SummaryItem {\n /** Descriptive label (e.g., \"Total Engagements\") */\n label: string;\n /** Numeric or string value (e.g., \"13.72\" or 11372) */\n value: string | number;\n /** Optional unit suffix (e.g., \"K\", \"GB\", \"%\") */\n unit?: string;\n}\n\nexport interface SummaryStatsProps {\n /** Array of summary items to display */\n items: SummaryItem[];\n}\n\n/**\n * Formats a summary value with its optional unit.\n */\nconst formatSummaryValue = (value: string | number, unit?: string): string => {\n const displayValue = typeof value === 'number' ? value.toLocaleString() : value;\n return unit ? `${displayValue} ${unit}` : displayValue;\n};\n\n/**\n * Renders a horizontal row of summary statistics below the graph.\n * Each item shows a label with its corresponding value and optional unit.\n *\n * Matches the Figma design layout with label in secondary text color\n * and value in bold heading typography.\n *\n * @example\n * ```tsx\n * <SummaryStats\n * items={[\n * { label: 'Total Engagements', value: 11372 },\n * { label: 'Total Consumed', value: '156.91', unit: 'GB' },\n * ]}\n * />\n * ```\n */\nexport const SummaryStats = ({ items }: SummaryStatsProps) => {\n if (items.length === 0) {\n return null;\n }\n\n return (\n <Stack\n direction=\"row\"\n spacing={3}\n padding={2}\n flexWrap=\"wrap\"\n useFlexGap\n role=\"list\"\n aria-label=\"Summary statistics\"\n >\n {items.map((item) => (\n <Stack\n key={item.label}\n direction=\"row\"\n alignItems=\"center\"\n spacing={1}\n role=\"listitem\"\n >\n <Typography variant=\"body2\" color=\"text.secondary\">\n {item.label}\n </Typography>\n <Typography variant=\"h5\" fontWeight={600}>\n {formatSummaryValue(item.value, item.unit)}\n </Typography>\n </Stack>\n ))}\n </Stack>\n );\n};\n"],"mappings":"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","names":["value","format","LineChart","Box","Stack","styled","Typography","useTheme","jsx","value","jsx","jsxs","Chart","styled","LineChart","useTheme","format","Stack","Box","Typography","useMemo","useState","Box","Card","CardHeader","CardMedia","Divider","Stack","Typography","styled","useTheme","LineChart","format","MenuItem","TextField","jsx","options","Stack","Typography","jsx","jsxs","jsx","jsxs","styled","Box","useTheme","useState","useMemo","Stack","Card","CardHeader","CardMedia","LineChart","format","Typography","Divider"]}
|
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunkCCN6M4LIjs = require('./chunk-CCN6M4LI.js');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _chunkJBHRAAN3js = require('./chunk-JBHRAAN3.js');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
var _chunkZGCN5WCGjs = require('./chunk-ZGCN5WCG.js');
|
|
13
|
+
|
|
14
|
+
// src/components/inputs/CopyableField.tsx
|
|
15
|
+
var _react = require('react'); var _react2 = _interopRequireDefault(_react);
|
|
16
|
+
var _Box = require('@mui/material/Box'); var _Box2 = _interopRequireDefault(_Box);
|
|
17
|
+
var _styles = require('@mui/material/styles');
|
|
18
|
+
var _jsxruntime = require('react/jsx-runtime');
|
|
19
|
+
var ValueButton = _styles.styled.call(void 0, "button")({
|
|
20
|
+
fontFamily: _chunkZGCN5WCGjs.fontFamilyMono,
|
|
21
|
+
fontSize: "11.5px",
|
|
22
|
+
fontWeight: 400,
|
|
23
|
+
lineHeight: 1.45,
|
|
24
|
+
padding: "8px 10px",
|
|
25
|
+
borderRadius: "8px",
|
|
26
|
+
backgroundColor: _chunkZGCN5WCGjs.webSurfaceTokens.surfaceMid,
|
|
27
|
+
border: `1px solid ${_chunkZGCN5WCGjs.webSurfaceTokens.strokeOnLow}`,
|
|
28
|
+
color: _chunkZGCN5WCGjs.webSurfaceTokens.textSecondary,
|
|
29
|
+
wordBreak: "break-all",
|
|
30
|
+
display: "block",
|
|
31
|
+
width: "100%",
|
|
32
|
+
textAlign: "left",
|
|
33
|
+
cursor: "pointer",
|
|
34
|
+
appearance: "none",
|
|
35
|
+
transition: `background ${_chunkZGCN5WCGjs.motion.dur.fast} ${_chunkZGCN5WCGjs.motion.ease.standard},
|
|
36
|
+
border-color ${_chunkZGCN5WCGjs.motion.dur.fast} ${_chunkZGCN5WCGjs.motion.ease.standard},
|
|
37
|
+
color ${_chunkZGCN5WCGjs.motion.dur.fast} ${_chunkZGCN5WCGjs.motion.ease.standard}`,
|
|
38
|
+
"&:hover": {
|
|
39
|
+
backgroundColor: _chunkZGCN5WCGjs.webSurfaceTokens.surfaceContrast,
|
|
40
|
+
borderColor: _chunkZGCN5WCGjs.webSurfaceTokens.strokeOnMed,
|
|
41
|
+
color: _chunkZGCN5WCGjs.webSurfaceTokens.textPrimary
|
|
42
|
+
},
|
|
43
|
+
"&:active": {
|
|
44
|
+
transform: "translateY(1px)"
|
|
45
|
+
},
|
|
46
|
+
"&:focus-visible": {
|
|
47
|
+
outline: "none",
|
|
48
|
+
boxShadow: _chunkZGCN5WCGjs.webSurfaceTokens.shadowFocus
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
var FlashLabel = _styles.styled.call(void 0, "span")({
|
|
52
|
+
fontSize: "11px",
|
|
53
|
+
fontWeight: 600,
|
|
54
|
+
color: _chunkZGCN5WCGjs.webSurfaceTokens.cVioletDark,
|
|
55
|
+
letterSpacing: "0.04em",
|
|
56
|
+
"@media (prefers-reduced-motion: no-preference)": {
|
|
57
|
+
animation: "cere-copyable-flash 180ms ease-out"
|
|
58
|
+
},
|
|
59
|
+
"@keyframes cere-copyable-flash": {
|
|
60
|
+
from: { opacity: 0, transform: "translateY(-2px)" },
|
|
61
|
+
to: { opacity: 1, transform: "translateY(0)" }
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
var CopyableField = _react2.default.forwardRef(
|
|
65
|
+
function CopyableField2({ value, label, ariaLabel, flashDurationMs = 1400, flashLabel = "Copied", onCopy }, ref) {
|
|
66
|
+
const [copied, setCopied] = _react.useState.call(void 0, false);
|
|
67
|
+
const timerRef = _react.useRef.call(void 0, null);
|
|
68
|
+
_react.useEffect.call(void 0,
|
|
69
|
+
() => () => {
|
|
70
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
71
|
+
},
|
|
72
|
+
[]
|
|
73
|
+
);
|
|
74
|
+
const handleCopy = _react.useCallback.call(void 0, async () => {
|
|
75
|
+
try {
|
|
76
|
+
await navigator.clipboard.writeText(value);
|
|
77
|
+
setCopied(true);
|
|
78
|
+
_optionalChain([onCopy, 'optionalCall', _ => _(value)]);
|
|
79
|
+
if (timerRef.current) clearTimeout(timerRef.current);
|
|
80
|
+
timerRef.current = setTimeout(() => setCopied(false), flashDurationMs);
|
|
81
|
+
} catch (e2) {
|
|
82
|
+
}
|
|
83
|
+
}, [value, onCopy, flashDurationMs]);
|
|
84
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkCCN6M4LIjs.Card, { ref, variant: "tinted", sx: { p: 1.75 }, children: [
|
|
85
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
86
|
+
_Box2.default,
|
|
87
|
+
{
|
|
88
|
+
sx: {
|
|
89
|
+
display: "flex",
|
|
90
|
+
alignItems: "center",
|
|
91
|
+
justifyContent: "space-between",
|
|
92
|
+
gap: 1,
|
|
93
|
+
mb: label || copied ? "6px" : 0,
|
|
94
|
+
minHeight: label || copied ? void 0 : 0
|
|
95
|
+
},
|
|
96
|
+
children: [
|
|
97
|
+
label ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkCCN6M4LIjs.Typography, { variant: "overline", children: label }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", {}),
|
|
98
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, FlashLabel, { role: "status", "aria-live": "polite", "aria-atomic": "true", children: copied ? flashLabel : "" })
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
),
|
|
102
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
103
|
+
ValueButton,
|
|
104
|
+
{
|
|
105
|
+
type: "button",
|
|
106
|
+
onClick: handleCopy,
|
|
107
|
+
"aria-label": _nullishCoalesce(ariaLabel, () => ( `Copy ${value}`)),
|
|
108
|
+
children: value
|
|
109
|
+
}
|
|
110
|
+
)
|
|
111
|
+
] });
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
// src/components/inputs/SearchField.tsx
|
|
116
|
+
|
|
117
|
+
var _Search = require('@mui/icons-material/Search'); var _Search2 = _interopRequireDefault(_Search);
|
|
118
|
+
var _InputAdornment = require('@mui/material/InputAdornment'); var _InputAdornment2 = _interopRequireDefault(_InputAdornment);
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
// src/components/inputs/useSearchHotkeys.ts
|
|
123
|
+
|
|
124
|
+
function isMacPlatform() {
|
|
125
|
+
if (typeof navigator === "undefined") return false;
|
|
126
|
+
const uaDataPlatform = _optionalChain([navigator, 'access', _2 => _2.userAgentData, 'optionalAccess', _3 => _3.platform]);
|
|
127
|
+
if (typeof uaDataPlatform === "string") return /mac/i.test(uaDataPlatform);
|
|
128
|
+
return /Mac|iPhone|iPad|iPod/i.test(navigator.platform);
|
|
129
|
+
}
|
|
130
|
+
function useSearchHotkeys(inputRef, options = {}) {
|
|
131
|
+
const { k: enableK = true, slash: enableSlash = true } = options;
|
|
132
|
+
_react.useEffect.call(void 0, () => {
|
|
133
|
+
if (!enableK && !enableSlash) return;
|
|
134
|
+
const mac = isMacPlatform();
|
|
135
|
+
function onKeyDown(event) {
|
|
136
|
+
if (enableK && event.key.toLowerCase() === "k") {
|
|
137
|
+
const correctMod = mac ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey;
|
|
138
|
+
if (correctMod && !event.shiftKey && !event.altKey) {
|
|
139
|
+
event.preventDefault();
|
|
140
|
+
_optionalChain([inputRef, 'access', _4 => _4.current, 'optionalAccess', _5 => _5.focus, 'call', _6 => _6()]);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (enableSlash && event.key === "/") {
|
|
145
|
+
const target = event.target;
|
|
146
|
+
const typingInField = target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || (_nullishCoalesce(_optionalChain([target, 'optionalAccess', _7 => _7.isContentEditable]), () => ( false)));
|
|
147
|
+
if (!typingInField) {
|
|
148
|
+
event.preventDefault();
|
|
149
|
+
_optionalChain([inputRef, 'access', _8 => _8.current, 'optionalAccess', _9 => _9.focus, 'call', _10 => _10()]);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
window.addEventListener("keydown", onKeyDown);
|
|
154
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
155
|
+
}, [inputRef, enableK, enableSlash]);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// src/components/inputs/SearchField.tsx
|
|
159
|
+
|
|
160
|
+
var ShortcutHint = () => {
|
|
161
|
+
const [mounted, setMounted] = _react.useState.call(void 0, false);
|
|
162
|
+
_react.useEffect.call(void 0, () => {
|
|
163
|
+
setMounted(true);
|
|
164
|
+
}, []);
|
|
165
|
+
if (!mounted) return null;
|
|
166
|
+
const isMac = isMacPlatform();
|
|
167
|
+
const label = isMac ? "\u2318\u2009K" : "Ctrl + K";
|
|
168
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
169
|
+
_Box2.default,
|
|
170
|
+
{
|
|
171
|
+
component: "span",
|
|
172
|
+
"aria-hidden": true,
|
|
173
|
+
sx: {
|
|
174
|
+
fontFamily: "monospace",
|
|
175
|
+
fontSize: 11,
|
|
176
|
+
letterSpacing: 0.4,
|
|
177
|
+
px: 0.75,
|
|
178
|
+
py: 0.25,
|
|
179
|
+
borderRadius: 1,
|
|
180
|
+
border: "1px solid",
|
|
181
|
+
borderColor: "divider",
|
|
182
|
+
color: "text.secondary",
|
|
183
|
+
lineHeight: 1
|
|
184
|
+
},
|
|
185
|
+
children: label
|
|
186
|
+
}
|
|
187
|
+
);
|
|
188
|
+
};
|
|
189
|
+
var SearchField = _react2.default.forwardRef(
|
|
190
|
+
function SearchField2({
|
|
191
|
+
placeholder = "Search...",
|
|
192
|
+
onSearch,
|
|
193
|
+
onChange,
|
|
194
|
+
variant = "standard",
|
|
195
|
+
shortcutHint = false,
|
|
196
|
+
sx,
|
|
197
|
+
...props
|
|
198
|
+
}, ref) {
|
|
199
|
+
const theme = _styles.useTheme.call(void 0, );
|
|
200
|
+
const handleChange = (e) => {
|
|
201
|
+
_optionalChain([onChange, 'optionalCall', _11 => _11(e)]);
|
|
202
|
+
_optionalChain([onSearch, 'optionalCall', _12 => _12(e.target.value)]);
|
|
203
|
+
};
|
|
204
|
+
const pillInputSx = variant === "pill" ? { borderRadius: "999px", paddingRight: "6px" } : void 0;
|
|
205
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
206
|
+
_chunkJBHRAAN3js.TextField,
|
|
207
|
+
{
|
|
208
|
+
ref,
|
|
209
|
+
placeholder,
|
|
210
|
+
onChange: handleChange,
|
|
211
|
+
sx,
|
|
212
|
+
slotProps: {
|
|
213
|
+
input: {
|
|
214
|
+
...pillInputSx ? { sx: pillInputSx } : {},
|
|
215
|
+
startAdornment: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _InputAdornment2.default, { position: "start", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _Search2.default, { style: { fontSize: 18, color: theme.palette.text.disabled } }) }),
|
|
216
|
+
endAdornment: shortcutHint ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _InputAdornment2.default, { position: "end", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ShortcutHint, {}) }) : void 0
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
...props
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
}
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
// src/components/inputs/FormControl.tsx
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
var _material = require('@mui/material');
|
|
234
|
+
|
|
235
|
+
// src/components/inputs/ToggleButton.tsx
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
var ToggleButton = (props) => {
|
|
243
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _material.ToggleButton, { ...props });
|
|
244
|
+
};
|
|
245
|
+
var StyledToggleButtonGroup = _styles.styled.call(void 0, (0, _material.ToggleButtonGroup))(({ theme }) => ({
|
|
246
|
+
"& .MuiToggleButton-root": {
|
|
247
|
+
border: `1px solid ${theme.palette.grey[300]}`,
|
|
248
|
+
"&.Mui-selected": {
|
|
249
|
+
backgroundColor: theme.palette.primary.main,
|
|
250
|
+
color: theme.palette.primary.contrastText,
|
|
251
|
+
"&:hover": {
|
|
252
|
+
backgroundColor: theme.palette.primary.light
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
"&:hover": {
|
|
256
|
+
backgroundColor: theme.palette.grey[50]
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}));
|
|
260
|
+
var ToggleButtonGroup = (props) => {
|
|
261
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StyledToggleButtonGroup, { ...props });
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
// src/components/inputs/Switch.tsx
|
|
265
|
+
var _Switch = require('@mui/material/Switch'); var _Switch2 = _interopRequireDefault(_Switch);
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
var StyledSwitch = _styles.styled.call(void 0, (0, _Switch2.default))(({ theme }) => ({
|
|
269
|
+
width: 44,
|
|
270
|
+
height: 24,
|
|
271
|
+
padding: 0,
|
|
272
|
+
"& .MuiSwitch-switchBase": {
|
|
273
|
+
padding: 0,
|
|
274
|
+
margin: 2,
|
|
275
|
+
transitionDuration: "300ms",
|
|
276
|
+
"&.Mui-checked": {
|
|
277
|
+
transform: "translateX(20px)",
|
|
278
|
+
color: theme.palette.common.white,
|
|
279
|
+
"& + .MuiSwitch-track": {
|
|
280
|
+
backgroundColor: theme.palette.success.main,
|
|
281
|
+
opacity: 1,
|
|
282
|
+
border: 0
|
|
283
|
+
},
|
|
284
|
+
"&.Mui-disabled + .MuiSwitch-track": {
|
|
285
|
+
opacity: 0.5
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
"&.Mui-focusVisible .MuiSwitch-thumb": {
|
|
289
|
+
color: theme.palette.success.main,
|
|
290
|
+
border: `6px solid ${theme.palette.common.white}`
|
|
291
|
+
},
|
|
292
|
+
"&.Mui-disabled .MuiSwitch-thumb": {
|
|
293
|
+
color: theme.palette.grey[300]
|
|
294
|
+
},
|
|
295
|
+
"&.Mui-disabled + .MuiSwitch-track": {
|
|
296
|
+
opacity: 0.5,
|
|
297
|
+
backgroundColor: theme.palette.grey[300]
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
"& .MuiSwitch-thumb": {
|
|
301
|
+
boxSizing: "border-box",
|
|
302
|
+
width: 20,
|
|
303
|
+
height: 20
|
|
304
|
+
},
|
|
305
|
+
"& .MuiSwitch-track": {
|
|
306
|
+
borderRadius: 24 / 2,
|
|
307
|
+
backgroundColor: theme.palette.grey[300],
|
|
308
|
+
opacity: 1,
|
|
309
|
+
transition: theme.transitions.create(["background-color"], {
|
|
310
|
+
duration: 500
|
|
311
|
+
})
|
|
312
|
+
}
|
|
313
|
+
}));
|
|
314
|
+
var Switch = ({
|
|
315
|
+
label,
|
|
316
|
+
labelPosition = "right",
|
|
317
|
+
...props
|
|
318
|
+
}) => {
|
|
319
|
+
const switchComponent = /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StyledSwitch, { ...props });
|
|
320
|
+
if (!label) {
|
|
321
|
+
return switchComponent;
|
|
322
|
+
}
|
|
323
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
324
|
+
labelPosition === "left" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: label }),
|
|
325
|
+
switchComponent,
|
|
326
|
+
labelPosition === "right" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: label })
|
|
327
|
+
] });
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
// src/components/inputs/Checkbox.tsx
|
|
331
|
+
var _Checkbox = require('@mui/material/Checkbox'); var _Checkbox2 = _interopRequireDefault(_Checkbox);
|
|
332
|
+
|
|
333
|
+
var _FormControlLabel = require('@mui/material/FormControlLabel'); var _FormControlLabel2 = _interopRequireDefault(_FormControlLabel);
|
|
334
|
+
|
|
335
|
+
var StyledCheckbox = _styles.styled.call(void 0, (0, _Checkbox2.default))(({ theme }) => ({
|
|
336
|
+
color: theme.palette.grey[400],
|
|
337
|
+
"&.Mui-checked": {
|
|
338
|
+
color: theme.palette.primary.main
|
|
339
|
+
},
|
|
340
|
+
"&.MuiCheckbox-indeterminate": {
|
|
341
|
+
color: theme.palette.primary.main
|
|
342
|
+
},
|
|
343
|
+
"&.Mui-disabled": {
|
|
344
|
+
color: theme.palette.grey[300]
|
|
345
|
+
},
|
|
346
|
+
"&:hover": {
|
|
347
|
+
backgroundColor: theme.palette.background.selected
|
|
348
|
+
},
|
|
349
|
+
"&.Mui-focusVisible": {
|
|
350
|
+
outline: `2px solid ${theme.palette.primary.main}`,
|
|
351
|
+
outlineOffset: 2
|
|
352
|
+
}
|
|
353
|
+
}));
|
|
354
|
+
var Checkbox = ({
|
|
355
|
+
label,
|
|
356
|
+
labelPosition = "right",
|
|
357
|
+
...props
|
|
358
|
+
}) => {
|
|
359
|
+
const checkboxComponent = /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StyledCheckbox, { ...props });
|
|
360
|
+
if (!label) {
|
|
361
|
+
return checkboxComponent;
|
|
362
|
+
}
|
|
363
|
+
const labelPlacementMap = {
|
|
364
|
+
left: "start",
|
|
365
|
+
right: "end"
|
|
366
|
+
};
|
|
367
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
368
|
+
_FormControlLabel2.default,
|
|
369
|
+
{
|
|
370
|
+
control: checkboxComponent,
|
|
371
|
+
label,
|
|
372
|
+
labelPlacement: labelPlacementMap[labelPosition] || "end"
|
|
373
|
+
}
|
|
374
|
+
);
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
// src/components/inputs/Radio.tsx
|
|
378
|
+
var _Radio = require('@mui/material/Radio'); var _Radio2 = _interopRequireDefault(_Radio);
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
var _RadioGroup = require('@mui/material/RadioGroup'); var _RadioGroup2 = _interopRequireDefault(_RadioGroup);
|
|
382
|
+
|
|
383
|
+
var StyledRadio = _styles.styled.call(void 0, (0, _Radio2.default))(({ theme }) => ({
|
|
384
|
+
color: theme.palette.grey[400],
|
|
385
|
+
"&.Mui-checked": {
|
|
386
|
+
color: theme.palette.primary.main
|
|
387
|
+
},
|
|
388
|
+
"&.Mui-disabled": {
|
|
389
|
+
color: theme.palette.grey[300]
|
|
390
|
+
},
|
|
391
|
+
"&:hover": {
|
|
392
|
+
backgroundColor: theme.palette.background.selected
|
|
393
|
+
},
|
|
394
|
+
"&.Mui-focusVisible": {
|
|
395
|
+
outline: `2px solid ${theme.palette.primary.main}`,
|
|
396
|
+
outlineOffset: 2
|
|
397
|
+
}
|
|
398
|
+
}));
|
|
399
|
+
var Radio = ({
|
|
400
|
+
label,
|
|
401
|
+
labelPosition = "right",
|
|
402
|
+
...props
|
|
403
|
+
}) => {
|
|
404
|
+
const radioComponent = /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StyledRadio, { ...props });
|
|
405
|
+
if (!label) {
|
|
406
|
+
return radioComponent;
|
|
407
|
+
}
|
|
408
|
+
const labelPlacementMap = {
|
|
409
|
+
left: "start",
|
|
410
|
+
right: "end"
|
|
411
|
+
};
|
|
412
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
413
|
+
_FormControlLabel2.default,
|
|
414
|
+
{
|
|
415
|
+
control: radioComponent,
|
|
416
|
+
label,
|
|
417
|
+
labelPlacement: labelPlacementMap[labelPosition] || "end"
|
|
418
|
+
}
|
|
419
|
+
);
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
// src/components/inputs/DateRangePicker/DateRangePicker.tsx
|
|
423
|
+
var _Stack = require('@mui/material/Stack'); var _Stack2 = _interopRequireDefault(_Stack);
|
|
424
|
+
var _Typography = require('@mui/material/Typography'); var _Typography2 = _interopRequireDefault(_Typography);
|
|
425
|
+
var _DatePicker = require('@mui/x-date-pickers/DatePicker');
|
|
426
|
+
var _LocalizationProvider = require('@mui/x-date-pickers/LocalizationProvider');
|
|
427
|
+
var _AdapterDateFnsV3 = require('@mui/x-date-pickers/AdapterDateFnsV3');
|
|
428
|
+
|
|
429
|
+
var DateRangePicker = ({
|
|
430
|
+
startDate,
|
|
431
|
+
endDate,
|
|
432
|
+
onStartDateChange,
|
|
433
|
+
onEndDateChange,
|
|
434
|
+
minDate,
|
|
435
|
+
maxDate,
|
|
436
|
+
disabled = false,
|
|
437
|
+
size = "small"
|
|
438
|
+
}) => {
|
|
439
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _LocalizationProvider.LocalizationProvider, { dateAdapter: _AdapterDateFnsV3.AdapterDateFns, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _Stack2.default, { direction: "row", spacing: 1, alignItems: "center", children: [
|
|
440
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
441
|
+
_DatePicker.DatePicker,
|
|
442
|
+
{
|
|
443
|
+
label: "Start date",
|
|
444
|
+
value: startDate,
|
|
445
|
+
onChange: onStartDateChange,
|
|
446
|
+
minDate,
|
|
447
|
+
maxDate: _nullishCoalesce(endDate, () => ( maxDate)),
|
|
448
|
+
disabled,
|
|
449
|
+
slotProps: {
|
|
450
|
+
textField: { size }
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
),
|
|
454
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _Typography2.default, { variant: "body2", color: "text.secondary", children: "\u2013" }),
|
|
455
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
456
|
+
_DatePicker.DatePicker,
|
|
457
|
+
{
|
|
458
|
+
label: "End date",
|
|
459
|
+
value: endDate,
|
|
460
|
+
onChange: onEndDateChange,
|
|
461
|
+
minDate: _nullishCoalesce(startDate, () => ( minDate)),
|
|
462
|
+
maxDate,
|
|
463
|
+
disabled,
|
|
464
|
+
slotProps: {
|
|
465
|
+
textField: { size }
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
)
|
|
469
|
+
] }) });
|
|
470
|
+
};
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
exports.CopyableField = CopyableField; exports.useSearchHotkeys = useSearchHotkeys; exports.SearchField = SearchField; exports.FormControl = _material.FormControl; exports.FormLabel = _material.FormLabel; exports.FormHelperText = _material.FormHelperText; exports.FormControlLabel = _material.FormControlLabel; exports.InputLabel = _material.InputLabel; exports.InputAdornment = _material.InputAdornment; exports.ToggleButton = ToggleButton; exports.ToggleButtonGroup = ToggleButtonGroup; exports.Switch = Switch; exports.Checkbox = Checkbox; exports.RadioGroup = _RadioGroup2.default; exports.Radio = Radio; exports.DateRangePicker = DateRangePicker;
|
|
490
|
+
//# sourceMappingURL=chunk-THQKYTQE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/cere-design-system/cere-design-system/dist/chunk-THQKYTQE.js","../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"],"names":["jsx","Box","InputAdornment","FormControlLabel"],"mappings":"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","file":"/home/runner/work/cere-design-system/cere-design-system/dist/chunk-THQKYTQE.js","sourcesContent":[null,"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<HTMLElement, 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 {\n FormControl,\n FormLabel,\n FormHelperText,\n FormControlLabel,\n InputLabel,\n InputAdornment,\n} from '@mui/material';\nexport type {\n FormControlProps,\n FormLabelProps,\n FormHelperTextProps,\n FormControlLabelProps,\n InputLabelProps,\n InputAdornmentProps,\n} from '@mui/material';\n\n","import React from 'react';\nimport {\n ToggleButton as MuiToggleButton,\n ToggleButtonGroup as MuiToggleButtonGroup,\n ToggleButtonProps as MuiToggleButtonProps,\n ToggleButtonGroupProps as MuiToggleButtonGroupProps,\n} from '@mui/material';\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\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"]}
|