@sqlrooms/mosaic 0.29.0-rc.0 → 0.29.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -2
- package/dist/MosaicChart.d.ts +20 -0
- package/dist/MosaicChart.d.ts.map +1 -0
- package/dist/MosaicChart.js +25 -0
- package/dist/MosaicChart.js.map +1 -0
- package/dist/MosaicChartBuilder.d.ts +32 -0
- package/dist/MosaicChartBuilder.d.ts.map +1 -0
- package/dist/MosaicChartBuilder.js +35 -0
- package/dist/MosaicChartBuilder.js.map +1 -0
- package/dist/MosaicColorLegend.d.ts +18 -0
- package/dist/MosaicColorLegend.d.ts.map +1 -0
- package/dist/MosaicColorLegend.js +117 -0
- package/dist/MosaicColorLegend.js.map +1 -0
- package/dist/MosaicSlice.d.ts +16 -13
- package/dist/MosaicSlice.d.ts.map +1 -1
- package/dist/MosaicSlice.js +67 -32
- package/dist/MosaicSlice.js.map +1 -1
- package/dist/VgPlotChart.d.ts +8 -0
- package/dist/VgPlotChart.d.ts.map +1 -1
- package/dist/VgPlotChart.js +26 -6
- package/dist/VgPlotChart.js.map +1 -1
- package/dist/chart-builders/ChartBuilderContent.d.ts +26 -0
- package/dist/chart-builders/ChartBuilderContent.d.ts.map +1 -0
- package/dist/chart-builders/ChartBuilderContent.js +59 -0
- package/dist/chart-builders/ChartBuilderContent.js.map +1 -0
- package/dist/chart-builders/ChartBuilderContext.d.ts +11 -0
- package/dist/chart-builders/ChartBuilderContext.d.ts.map +1 -0
- package/dist/chart-builders/ChartBuilderContext.js +10 -0
- package/dist/chart-builders/ChartBuilderContext.js.map +1 -0
- package/dist/chart-builders/ChartBuilderDialog.d.ts +23 -0
- package/dist/chart-builders/ChartBuilderDialog.d.ts.map +1 -0
- package/dist/chart-builders/ChartBuilderDialog.js +15 -0
- package/dist/chart-builders/ChartBuilderDialog.js.map +1 -0
- package/dist/chart-builders/FieldSelectorInput.d.ts +13 -0
- package/dist/chart-builders/FieldSelectorInput.d.ts.map +1 -0
- package/dist/chart-builders/FieldSelectorInput.js +19 -0
- package/dist/chart-builders/FieldSelectorInput.js.map +1 -0
- package/dist/chart-builders/builders.d.ts +7 -0
- package/dist/chart-builders/builders.d.ts.map +1 -0
- package/dist/chart-builders/builders.js +280 -0
- package/dist/chart-builders/builders.js.map +1 -0
- package/dist/chart-builders/chartSpecTitle.d.ts +7 -0
- package/dist/chart-builders/chartSpecTitle.d.ts.map +1 -0
- package/dist/chart-builders/chartSpecTitle.js +10 -0
- package/dist/chart-builders/chartSpecTitle.js.map +1 -0
- package/dist/chart-builders/createMosaicChartTool.d.ts +45 -0
- package/dist/chart-builders/createMosaicChartTool.d.ts.map +1 -0
- package/dist/chart-builders/createMosaicChartTool.js +109 -0
- package/dist/chart-builders/createMosaicChartTool.js.map +1 -0
- package/dist/chart-builders/describeChartSpecs.d.ts +7 -0
- package/dist/chart-builders/describeChartSpecs.d.ts.map +1 -0
- package/dist/chart-builders/describeChartSpecs.js +38 -0
- package/dist/chart-builders/describeChartSpecs.js.map +1 -0
- package/dist/chart-builders/types.d.ts +40 -0
- package/dist/chart-builders/types.d.ts.map +1 -0
- package/dist/chart-builders/types.js +2 -0
- package/dist/chart-builders/types.js.map +1 -0
- package/dist/dashboard/MosaicDashboard.d.ts +20 -0
- package/dist/dashboard/MosaicDashboard.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboard.js +68 -0
- package/dist/dashboard/MosaicDashboard.js.map +1 -0
- package/dist/dashboard/MosaicDashboardChartPanel.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardChartPanel.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardChartPanel.js +49 -0
- package/dist/dashboard/MosaicDashboardChartPanel.js.map +1 -0
- package/dist/dashboard/MosaicDashboardCharts.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardCharts.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardCharts.js +45 -0
- package/dist/dashboard/MosaicDashboardCharts.js.map +1 -0
- package/dist/dashboard/MosaicDashboardContext.d.ts +11 -0
- package/dist/dashboard/MosaicDashboardContext.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardContext.js +10 -0
- package/dist/dashboard/MosaicDashboardContext.js.map +1 -0
- package/dist/dashboard/MosaicDashboardProfiler.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardProfiler.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardProfiler.js +21 -0
- package/dist/dashboard/MosaicDashboardProfiler.js.map +1 -0
- package/dist/dashboard/MosaicDashboardSlice.d.ts +68 -0
- package/dist/dashboard/MosaicDashboardSlice.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardSlice.js +230 -0
- package/dist/dashboard/MosaicDashboardSlice.js.map +1 -0
- package/dist/dashboard/MosaicDashboardToolbar.d.ts +3 -0
- package/dist/dashboard/MosaicDashboardToolbar.d.ts.map +1 -0
- package/dist/dashboard/MosaicDashboardToolbar.js +19 -0
- package/dist/dashboard/MosaicDashboardToolbar.js.map +1 -0
- package/dist/dashboard/VgPlotSpecPopoverEditor.d.ts +8 -0
- package/dist/dashboard/VgPlotSpecPopoverEditor.d.ts.map +1 -0
- package/dist/dashboard/VgPlotSpecPopoverEditor.js +40 -0
- package/dist/dashboard/VgPlotSpecPopoverEditor.js.map +1 -0
- package/dist/editor/MosaicChartContainer.d.ts +51 -0
- package/dist/editor/MosaicChartContainer.d.ts.map +1 -0
- package/dist/editor/MosaicChartContainer.js +39 -0
- package/dist/editor/MosaicChartContainer.js.map +1 -0
- package/dist/editor/MosaicChartDisplay.d.ts +18 -0
- package/dist/editor/MosaicChartDisplay.d.ts.map +1 -0
- package/dist/editor/MosaicChartDisplay.js +21 -0
- package/dist/editor/MosaicChartDisplay.js.map +1 -0
- package/dist/editor/MosaicChartEditorActions.d.ts +20 -0
- package/dist/editor/MosaicChartEditorActions.d.ts.map +1 -0
- package/dist/editor/MosaicChartEditorActions.js +18 -0
- package/dist/editor/MosaicChartEditorActions.js.map +1 -0
- package/dist/editor/MosaicCodeMirrorEditor.d.ts +15 -0
- package/dist/editor/MosaicCodeMirrorEditor.d.ts.map +1 -0
- package/dist/editor/MosaicCodeMirrorEditor.js +26 -0
- package/dist/editor/MosaicCodeMirrorEditor.js.map +1 -0
- package/dist/editor/MosaicEditorContext.d.ts +8 -0
- package/dist/editor/MosaicEditorContext.d.ts.map +1 -0
- package/dist/editor/MosaicEditorContext.js +14 -0
- package/dist/editor/MosaicEditorContext.js.map +1 -0
- package/dist/editor/MosaicSpecEditorPanel.d.ts +20 -0
- package/dist/editor/MosaicSpecEditorPanel.d.ts.map +1 -0
- package/dist/editor/MosaicSpecEditorPanel.js +25 -0
- package/dist/editor/MosaicSpecEditorPanel.js.map +1 -0
- package/dist/editor/mosaicSchema.d.ts +20 -0
- package/dist/editor/mosaicSchema.d.ts.map +1 -0
- package/dist/editor/mosaicSchema.js +57 -0
- package/dist/editor/mosaicSchema.js.map +1 -0
- package/dist/editor/types.d.ts +72 -0
- package/dist/editor/types.d.ts.map +1 -0
- package/dist/editor/types.js +2 -0
- package/dist/editor/types.js.map +1 -0
- package/dist/editor/useMosaicChartEditor.d.ts +9 -0
- package/dist/editor/useMosaicChartEditor.d.ts.map +1 -0
- package/dist/editor/useMosaicChartEditor.js +199 -0
- package/dist/editor/useMosaicChartEditor.js.map +1 -0
- package/dist/index.d.ts +27 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/dist/profiler/MosaicProfiler.d.ts +32 -0
- package/dist/profiler/MosaicProfiler.d.ts.map +1 -0
- package/dist/profiler/MosaicProfiler.js +57 -0
- package/dist/profiler/MosaicProfiler.js.map +1 -0
- package/dist/profiler/MosaicProfilerHeader.d.ts +7 -0
- package/dist/profiler/MosaicProfilerHeader.d.ts.map +1 -0
- package/dist/profiler/MosaicProfilerHeader.js +196 -0
- package/dist/profiler/MosaicProfilerHeader.js.map +1 -0
- package/dist/profiler/MosaicProfilerRows.d.ts +9 -0
- package/dist/profiler/MosaicProfilerRows.d.ts.map +1 -0
- package/dist/profiler/MosaicProfilerRows.js +65 -0
- package/dist/profiler/MosaicProfilerRows.js.map +1 -0
- package/dist/profiler/MosaicProfilerStatusBar.d.ts +9 -0
- package/dist/profiler/MosaicProfilerStatusBar.d.ts.map +1 -0
- package/dist/profiler/MosaicProfilerStatusBar.js +28 -0
- package/dist/profiler/MosaicProfilerStatusBar.js.map +1 -0
- package/dist/profiler/ProfilerCategoryClient.d.ts +50 -0
- package/dist/profiler/ProfilerCategoryClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerCategoryClient.js +121 -0
- package/dist/profiler/ProfilerCategoryClient.js.map +1 -0
- package/dist/profiler/ProfilerCountClient.d.ts +28 -0
- package/dist/profiler/ProfilerCountClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerCountClient.js +51 -0
- package/dist/profiler/ProfilerCountClient.js.map +1 -0
- package/dist/profiler/ProfilerHistogramClient.d.ts +69 -0
- package/dist/profiler/ProfilerHistogramClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerHistogramClient.js +179 -0
- package/dist/profiler/ProfilerHistogramClient.js.map +1 -0
- package/dist/profiler/ProfilerPageClient.d.ts +37 -0
- package/dist/profiler/ProfilerPageClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerPageClient.js +65 -0
- package/dist/profiler/ProfilerPageClient.js.map +1 -0
- package/dist/profiler/ProfilerUnsupportedSummaryClient.d.ts +24 -0
- package/dist/profiler/ProfilerUnsupportedSummaryClient.d.ts.map +1 -0
- package/dist/profiler/ProfilerUnsupportedSummaryClient.js +51 -0
- package/dist/profiler/ProfilerUnsupportedSummaryClient.js.map +1 -0
- package/dist/profiler/createProfilerStore.d.ts +45 -0
- package/dist/profiler/createProfilerStore.d.ts.map +1 -0
- package/dist/profiler/createProfilerStore.js +120 -0
- package/dist/profiler/createProfilerStore.js.map +1 -0
- package/dist/profiler/layout.d.ts +7 -0
- package/dist/profiler/layout.d.ts.map +1 -0
- package/dist/profiler/layout.js +13 -0
- package/dist/profiler/layout.js.map +1 -0
- package/dist/profiler/profilerController.d.ts +64 -0
- package/dist/profiler/profilerController.d.ts.map +1 -0
- package/dist/profiler/profilerController.js +123 -0
- package/dist/profiler/profilerController.js.map +1 -0
- package/dist/profiler/types.d.ts +86 -0
- package/dist/profiler/types.d.ts.map +1 -0
- package/dist/profiler/types.js +2 -0
- package/dist/profiler/types.js.map +1 -0
- package/dist/profiler/useMosaicProfiler.d.ts +7 -0
- package/dist/profiler/useMosaicProfiler.d.ts.map +1 -0
- package/dist/profiler/useMosaicProfiler.js +339 -0
- package/dist/profiler/useMosaicProfiler.js.map +1 -0
- package/dist/profiler/utils.d.ts +61 -0
- package/dist/profiler/utils.d.ts.map +1 -0
- package/dist/profiler/utils.js +347 -0
- package/dist/profiler/utils.js.map +1 -0
- package/dist/tableInterop.d.ts +30 -0
- package/dist/tableInterop.d.ts.map +1 -0
- package/dist/tableInterop.js +85 -0
- package/dist/tableInterop.js.map +1 -0
- package/dist/use-mosaic.d.ts +11 -0
- package/dist/use-mosaic.d.ts.map +1 -0
- package/dist/use-mosaic.js +42 -0
- package/dist/use-mosaic.js.map +1 -0
- package/dist/useMosaicClient.d.ts +5 -4
- package/dist/useMosaicClient.d.ts.map +1 -1
- package/dist/useMosaicClient.js +13 -3
- package/dist/useMosaicClient.js.map +1 -1
- package/package.json +24 -6
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { JsonCodeMirrorEditor, } from '@sqlrooms/codemirror';
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { loadMosaicSchema } from './mosaicSchema';
|
|
5
|
+
/**
|
|
6
|
+
* A CodeMirror editor specialized for editing Mosaic vgplot specifications.
|
|
7
|
+
* Automatically loads and configures the Mosaic JSON schema for validation.
|
|
8
|
+
*/
|
|
9
|
+
export const MosaicCodeMirrorEditor = ({ value, onChange, readOnly = false, className, enableSchemaValidation = false, ...props }) => {
|
|
10
|
+
const [schema, setSchema] = useState(null);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (enableSchemaValidation) {
|
|
13
|
+
let cancelled = false;
|
|
14
|
+
loadMosaicSchema().then((loadedSchema) => {
|
|
15
|
+
if (!cancelled && loadedSchema) {
|
|
16
|
+
setSchema(loadedSchema);
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return () => {
|
|
20
|
+
cancelled = true;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
}, [enableSchemaValidation]);
|
|
24
|
+
return (_jsx(JsonCodeMirrorEditor, { value: value, onChange: onChange, schema: enableSchemaValidation ? (schema ?? undefined) : undefined, readOnly: readOnly, className: className, ...props }));
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=MosaicCodeMirrorEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MosaicCodeMirrorEditor.js","sourceRoot":"","sources":["../../src/editor/MosaicCodeMirrorEditor.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,oBAAoB,GAErB,MAAM,sBAAsB,CAAC;AAC9B,OAAc,EAAC,SAAS,EAAE,QAAQ,EAAC,MAAM,OAAO,CAAC;AACjD,OAAO,EAAC,gBAAgB,EAAC,MAAM,gBAAgB,CAAC;AAahD;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAA0C,CAAC,EAC5E,KAAK,EACL,QAAQ,EACR,QAAQ,GAAG,KAAK,EAChB,SAAS,EACT,sBAAsB,GAAG,KAAK,EAC9B,GAAG,KAAK,EACT,EAAE,EAAE;IACH,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAE1D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,sBAAsB,EAAE,CAAC;YAC3B,IAAI,SAAS,GAAG,KAAK,CAAC;YACtB,gBAAgB,EAAE,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE;gBACvC,IAAI,CAAC,SAAS,IAAI,YAAY,EAAE,CAAC;oBAC/B,SAAS,CAAC,YAAY,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC,CAAC,CAAC;YACH,OAAO,GAAG,EAAE;gBACV,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC,CAAC;QACJ,CAAC;IACH,CAAC,EAAE,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAE7B,OAAO,CACL,KAAC,oBAAoB,IACnB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,EAClE,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,KAChB,KAAK,GACT,CACH,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {\n JsonCodeMirrorEditor,\n JsonCodeMirrorEditorProps,\n} from '@sqlrooms/codemirror';\nimport React, {useEffect, useState} from 'react';\nimport {loadMosaicSchema} from './mosaicSchema';\n\nexport interface MosaicCodeMirrorEditorProps extends Omit<\n JsonCodeMirrorEditorProps,\n 'schema'\n> {\n /**\n * Whether to enable Mosaic JSON schema validation\n * @default false\n */\n enableSchemaValidation?: boolean;\n}\n\n/**\n * A CodeMirror editor specialized for editing Mosaic vgplot specifications.\n * Automatically loads and configures the Mosaic JSON schema for validation.\n */\nexport const MosaicCodeMirrorEditor: React.FC<MosaicCodeMirrorEditorProps> = ({\n value,\n onChange,\n readOnly = false,\n className,\n enableSchemaValidation = false,\n ...props\n}) => {\n const [schema, setSchema] = useState<object | null>(null);\n\n useEffect(() => {\n if (enableSchemaValidation) {\n let cancelled = false;\n loadMosaicSchema().then((loadedSchema) => {\n if (!cancelled && loadedSchema) {\n setSchema(loadedSchema);\n }\n });\n return () => {\n cancelled = true;\n };\n }\n }, [enableSchemaValidation]);\n\n return (\n <JsonCodeMirrorEditor\n value={value}\n onChange={onChange}\n schema={enableSchemaValidation ? (schema ?? undefined) : undefined}\n readOnly={readOnly}\n className={className}\n {...props}\n />\n );\n};\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { MosaicEditorContextValue } from './types';
|
|
2
|
+
export declare const MosaicEditorContext: import("react").Context<MosaicEditorContextValue | null>;
|
|
3
|
+
/**
|
|
4
|
+
* Hook to access the Mosaic editor context.
|
|
5
|
+
* Must be used within a MosaicChart.Container component.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useMosaicEditorContext(): MosaicEditorContextValue;
|
|
8
|
+
//# sourceMappingURL=MosaicEditorContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MosaicEditorContext.d.ts","sourceRoot":"","sources":["../../src/editor/MosaicEditorContext.tsx"],"names":[],"mappings":"AACA,OAAO,EAAC,wBAAwB,EAAC,MAAM,SAAS,CAAC;AAEjD,eAAO,MAAM,mBAAmB,0DACsB,CAAC;AAEvD;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,wBAAwB,CAQjE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
export const MosaicEditorContext = createContext(null);
|
|
3
|
+
/**
|
|
4
|
+
* Hook to access the Mosaic editor context.
|
|
5
|
+
* Must be used within a MosaicChart.Container component.
|
|
6
|
+
*/
|
|
7
|
+
export function useMosaicEditorContext() {
|
|
8
|
+
const ctx = useContext(MosaicEditorContext);
|
|
9
|
+
if (!ctx) {
|
|
10
|
+
throw new Error('useMosaicEditorContext must be used within MosaicChart.Container');
|
|
11
|
+
}
|
|
12
|
+
return ctx;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=MosaicEditorContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MosaicEditorContext.js","sourceRoot":"","sources":["../../src/editor/MosaicEditorContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAE,UAAU,EAAC,MAAM,OAAO,CAAC;AAGhD,MAAM,CAAC,MAAM,mBAAmB,GAC9B,aAAa,CAAkC,IAAI,CAAC,CAAC;AAEvD;;;GAGG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,GAAG,GAAG,UAAU,CAAC,mBAAmB,CAAC,CAAC;IAC5C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import {createContext, useContext} from 'react';\nimport {MosaicEditorContextValue} from './types';\n\nexport const MosaicEditorContext =\n createContext<MosaicEditorContextValue | null>(null);\n\n/**\n * Hook to access the Mosaic editor context.\n * Must be used within a MosaicChart.Container component.\n */\nexport function useMosaicEditorContext(): MosaicEditorContextValue {\n const ctx = useContext(MosaicEditorContext);\n if (!ctx) {\n throw new Error(\n 'useMosaicEditorContext must be used within MosaicChart.Container',\n );\n }\n return ctx;\n}\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface MosaicSpecEditorPanelProps {
|
|
3
|
+
/**
|
|
4
|
+
* Custom class name for the panel
|
|
5
|
+
*/
|
|
6
|
+
className?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Title shown in the panel header
|
|
9
|
+
* @default "Mosaic Spec"
|
|
10
|
+
*/
|
|
11
|
+
title?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Spec editor panel subcomponent for MosaicChart.Container.
|
|
15
|
+
* Renders a CodeMirror editor with Mosaic JSON schema validation.
|
|
16
|
+
*
|
|
17
|
+
* Must be used within a MosaicChart.Container component.
|
|
18
|
+
*/
|
|
19
|
+
export declare const MosaicSpecEditorPanel: React.FC<MosaicSpecEditorPanelProps>;
|
|
20
|
+
//# sourceMappingURL=MosaicSpecEditorPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MosaicSpecEditorPanel.d.ts","sourceRoot":"","sources":["../../src/editor/MosaicSpecEditorPanel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,0BAA0B;IACzC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CA4CtE,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from '@sqlrooms/ui';
|
|
3
|
+
import { AlertCircle } from 'lucide-react';
|
|
4
|
+
import { useMosaicEditorContext } from './MosaicEditorContext';
|
|
5
|
+
import { MosaicCodeMirrorEditor } from './MosaicCodeMirrorEditor';
|
|
6
|
+
/**
|
|
7
|
+
* Spec editor panel subcomponent for MosaicChart.Container.
|
|
8
|
+
* Renders a CodeMirror editor with Mosaic JSON schema validation.
|
|
9
|
+
*
|
|
10
|
+
* Must be used within a MosaicChart.Container component.
|
|
11
|
+
*/
|
|
12
|
+
export const MosaicSpecEditorPanel = ({ className, title = 'Mosaic Spec', }) => {
|
|
13
|
+
const { state, actions, editable } = useMosaicEditorContext();
|
|
14
|
+
const showHeader = title !== '';
|
|
15
|
+
return (_jsxs("div", { className: cn('flex h-full flex-col', className), children: [showHeader && (_jsxs("div", { className: "flex items-center justify-between border-b px-3 py-2", children: [_jsx("span", { className: "text-sm font-medium", children: title }), state.isSpecDirty && (_jsx("span", { className: "text-muted-foreground text-xs", children: "Modified" }))] })), _jsx("div", { className: "relative flex-1", children: _jsx(MosaicCodeMirrorEditor, { className: "absolute inset-0 h-full w-full", value: state.editedSpecString, onChange: (value) => {
|
|
16
|
+
if (value !== undefined) {
|
|
17
|
+
actions.setEditedSpec(value);
|
|
18
|
+
}
|
|
19
|
+
}, readOnly: !editable, options: {
|
|
20
|
+
lineNumbers: true,
|
|
21
|
+
lineWrapping: false,
|
|
22
|
+
foldGutter: true,
|
|
23
|
+
} }) }), state.specParseError && (_jsxs("div", { className: "bg-destructive/90 text-destructive-foreground flex items-center gap-2 px-3 py-2 backdrop-blur-sm", children: [_jsx(AlertCircle, { className: "h-4 w-4 shrink-0" }), _jsx("span", { className: "truncate text-xs", children: state.specParseError })] }))] }));
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=MosaicSpecEditorPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MosaicSpecEditorPanel.js","sourceRoot":"","sources":["../../src/editor/MosaicSpecEditorPanel.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAC,EAAE,EAAC,MAAM,cAAc,CAAC;AAChC,OAAO,EAAC,WAAW,EAAC,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAC,sBAAsB,EAAC,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAC,sBAAsB,EAAC,MAAM,0BAA0B,CAAC;AAchE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAyC,CAAC,EAC1E,SAAS,EACT,KAAK,GAAG,aAAa,GACtB,EAAE,EAAE;IACH,MAAM,EAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAC,GAAG,sBAAsB,EAAE,CAAC;IAC5D,MAAM,UAAU,GAAG,KAAK,KAAK,EAAE,CAAC;IAEhC,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,sBAAsB,EAAE,SAAS,CAAC,aAClD,UAAU,IAAI,CACb,eAAK,SAAS,EAAC,sDAAsD,aACnE,eAAM,SAAS,EAAC,qBAAqB,YAAE,KAAK,GAAQ,EACnD,KAAK,CAAC,WAAW,IAAI,CACpB,eAAM,SAAS,EAAC,+BAA+B,yBAAgB,CAChE,IACG,CACP,EAED,cAAK,SAAS,EAAC,iBAAiB,YAC9B,KAAC,sBAAsB,IACrB,SAAS,EAAC,gCAAgC,EAC1C,KAAK,EAAE,KAAK,CAAC,gBAAgB,EAC7B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;wBAClB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;4BACxB,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;wBAC/B,CAAC;oBACH,CAAC,EACD,QAAQ,EAAE,CAAC,QAAQ,EACnB,OAAO,EAAE;wBACP,WAAW,EAAE,IAAI;wBACjB,YAAY,EAAE,KAAK;wBACnB,UAAU,EAAE,IAAI;qBACjB,GACD,GACE,EAEL,KAAK,CAAC,cAAc,IAAI,CACvB,eAAK,SAAS,EAAC,kGAAkG,aAC/G,KAAC,WAAW,IAAC,SAAS,EAAC,kBAAkB,GAAG,EAC5C,eAAM,SAAS,EAAC,kBAAkB,YAAE,KAAK,CAAC,cAAc,GAAQ,IAC5D,CACP,IACG,CACP,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {cn} from '@sqlrooms/ui';\nimport {AlertCircle} from 'lucide-react';\nimport React from 'react';\nimport {useMosaicEditorContext} from './MosaicEditorContext';\nimport {MosaicCodeMirrorEditor} from './MosaicCodeMirrorEditor';\n\nexport interface MosaicSpecEditorPanelProps {\n /**\n * Custom class name for the panel\n */\n className?: string;\n /**\n * Title shown in the panel header\n * @default \"Mosaic Spec\"\n */\n title?: string;\n}\n\n/**\n * Spec editor panel subcomponent for MosaicChart.Container.\n * Renders a CodeMirror editor with Mosaic JSON schema validation.\n *\n * Must be used within a MosaicChart.Container component.\n */\nexport const MosaicSpecEditorPanel: React.FC<MosaicSpecEditorPanelProps> = ({\n className,\n title = 'Mosaic Spec',\n}) => {\n const {state, actions, editable} = useMosaicEditorContext();\n const showHeader = title !== '';\n\n return (\n <div className={cn('flex h-full flex-col', className)}>\n {showHeader && (\n <div className=\"flex items-center justify-between border-b px-3 py-2\">\n <span className=\"text-sm font-medium\">{title}</span>\n {state.isSpecDirty && (\n <span className=\"text-muted-foreground text-xs\">Modified</span>\n )}\n </div>\n )}\n\n <div className=\"relative flex-1\">\n <MosaicCodeMirrorEditor\n className=\"absolute inset-0 h-full w-full\"\n value={state.editedSpecString}\n onChange={(value) => {\n if (value !== undefined) {\n actions.setEditedSpec(value);\n }\n }}\n readOnly={!editable}\n options={{\n lineNumbers: true,\n lineWrapping: false,\n foldGutter: true,\n }}\n />\n </div>\n\n {state.specParseError && (\n <div className=\"bg-destructive/90 text-destructive-foreground flex items-center gap-2 px-3 py-2 backdrop-blur-sm\">\n <AlertCircle className=\"h-4 w-4 shrink-0\" />\n <span className=\"truncate text-xs\">{state.specParseError}</span>\n </div>\n )}\n </div>\n );\n};\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy loader for the Mosaic JSON schema.
|
|
3
|
+
* The schema is ~8.7MB so we load it on demand and cache it.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Lazily loads the Mosaic JSON schema for editor validation.
|
|
7
|
+
* The schema is fetched from the UW IDL CDN and cached.
|
|
8
|
+
*
|
|
9
|
+
* @returns Promise that resolves to the Mosaic JSON schema, or null if loading failed
|
|
10
|
+
*/
|
|
11
|
+
export declare function loadMosaicSchema(): Promise<object | null>;
|
|
12
|
+
/**
|
|
13
|
+
* Synchronously returns cached schema, or null if not yet loaded.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getCachedMosaicSchema(): object | null;
|
|
16
|
+
/**
|
|
17
|
+
* Preload the schema without waiting for it.
|
|
18
|
+
*/
|
|
19
|
+
export declare function preloadMosaicSchema(): void;
|
|
20
|
+
//# sourceMappingURL=mosaicSchema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mosaicSchema.d.ts","sourceRoot":"","sources":["../../src/editor/mosaicSchema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;;;;GAKG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+B/D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,IAAI,CAErD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lazy loader for the Mosaic JSON schema.
|
|
3
|
+
* The schema is ~8.7MB so we load it on demand and cache it.
|
|
4
|
+
*/
|
|
5
|
+
const MOSAIC_SCHEMA_URL = 'https://idl.uw.edu/mosaic/schema/latest.json';
|
|
6
|
+
let cachedSchema = null;
|
|
7
|
+
let loadingPromise = null;
|
|
8
|
+
/**
|
|
9
|
+
* Lazily loads the Mosaic JSON schema for editor validation.
|
|
10
|
+
* The schema is fetched from the UW IDL CDN and cached.
|
|
11
|
+
*
|
|
12
|
+
* @returns Promise that resolves to the Mosaic JSON schema, or null if loading failed
|
|
13
|
+
*/
|
|
14
|
+
export async function loadMosaicSchema() {
|
|
15
|
+
if (cachedSchema) {
|
|
16
|
+
return cachedSchema;
|
|
17
|
+
}
|
|
18
|
+
if (loadingPromise) {
|
|
19
|
+
return loadingPromise;
|
|
20
|
+
}
|
|
21
|
+
loadingPromise = (async () => {
|
|
22
|
+
try {
|
|
23
|
+
const response = await fetch(MOSAIC_SCHEMA_URL);
|
|
24
|
+
if (!response.ok) {
|
|
25
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
26
|
+
}
|
|
27
|
+
cachedSchema = await response.json();
|
|
28
|
+
return cachedSchema;
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.warn('Failed to load Mosaic schema from CDN:', error);
|
|
32
|
+
cachedSchema = {
|
|
33
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
34
|
+
type: 'object',
|
|
35
|
+
description: 'Mosaic specification (schema loading failed)',
|
|
36
|
+
};
|
|
37
|
+
return cachedSchema;
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
loadingPromise = null;
|
|
41
|
+
}
|
|
42
|
+
})();
|
|
43
|
+
return loadingPromise;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Synchronously returns cached schema, or null if not yet loaded.
|
|
47
|
+
*/
|
|
48
|
+
export function getCachedMosaicSchema() {
|
|
49
|
+
return cachedSchema;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Preload the schema without waiting for it.
|
|
53
|
+
*/
|
|
54
|
+
export function preloadMosaicSchema() {
|
|
55
|
+
loadMosaicSchema().catch(() => { });
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=mosaicSchema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mosaicSchema.js","sourceRoot":"","sources":["../../src/editor/mosaicSchema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,iBAAiB,GAAG,8CAA8C,CAAC;AAEzE,IAAI,YAAY,GAAkB,IAAI,CAAC;AACvC,IAAI,cAAc,GAAkC,IAAI,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,IAAI,cAAc,EAAE,CAAC;QACnB,OAAO,cAAc,CAAC;IACxB,CAAC;IAED,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;QAC3B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,iBAAiB,CAAC,CAAC;YAChD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YACrE,CAAC;YACD,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACrC,OAAO,YAAY,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAC;YAC9D,YAAY,GAAG;gBACb,OAAO,EAAE,yCAAyC;gBAClD,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,8CAA8C;aAC5D,CAAC;YACF,OAAO,YAAY,CAAC;QACtB,CAAC;gBAAS,CAAC;YACT,cAAc,GAAG,IAAI,CAAC;QACxB,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IAEL,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,gBAAgB,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AACrC,CAAC","sourcesContent":["/**\n * Lazy loader for the Mosaic JSON schema.\n * The schema is ~8.7MB so we load it on demand and cache it.\n */\n\nconst MOSAIC_SCHEMA_URL = 'https://idl.uw.edu/mosaic/schema/latest.json';\n\nlet cachedSchema: object | null = null;\nlet loadingPromise: Promise<object | null> | null = null;\n\n/**\n * Lazily loads the Mosaic JSON schema for editor validation.\n * The schema is fetched from the UW IDL CDN and cached.\n *\n * @returns Promise that resolves to the Mosaic JSON schema, or null if loading failed\n */\nexport async function loadMosaicSchema(): Promise<object | null> {\n if (cachedSchema) {\n return cachedSchema;\n }\n\n if (loadingPromise) {\n return loadingPromise;\n }\n\n loadingPromise = (async () => {\n try {\n const response = await fetch(MOSAIC_SCHEMA_URL);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n cachedSchema = await response.json();\n return cachedSchema;\n } catch (error) {\n console.warn('Failed to load Mosaic schema from CDN:', error);\n cachedSchema = {\n $schema: 'http://json-schema.org/draft-07/schema#',\n type: 'object',\n description: 'Mosaic specification (schema loading failed)',\n };\n return cachedSchema;\n } finally {\n loadingPromise = null;\n }\n })();\n\n return loadingPromise;\n}\n\n/**\n * Synchronously returns cached schema, or null if not yet loaded.\n */\nexport function getCachedMosaicSchema(): object | null {\n return cachedSchema;\n}\n\n/**\n * Preload the schema without waiting for it.\n */\nexport function preloadMosaicSchema(): void {\n loadMosaicSchema().catch(() => {});\n}\n"]}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Param } from '@uwdata/mosaic-core';
|
|
2
|
+
import { Spec } from '@uwdata/mosaic-spec';
|
|
3
|
+
/**
|
|
4
|
+
* State managed by the Mosaic spec editor
|
|
5
|
+
*/
|
|
6
|
+
export interface MosaicEditorState {
|
|
7
|
+
/** The edited spec as a JSON string */
|
|
8
|
+
editedSpecString: string;
|
|
9
|
+
/** Parsed spec object (null if parse error) */
|
|
10
|
+
parsedSpec: Spec | null;
|
|
11
|
+
/** Last successfully parsed spec (for fallback during errors) */
|
|
12
|
+
lastValidSpec: Spec;
|
|
13
|
+
/** JSON parse error message if any */
|
|
14
|
+
specParseError: string | null;
|
|
15
|
+
/** Whether spec has been modified from last applied state */
|
|
16
|
+
isSpecDirty: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Actions available in the Mosaic spec editor
|
|
20
|
+
*/
|
|
21
|
+
export interface MosaicEditorActions {
|
|
22
|
+
/** Update the edited spec string */
|
|
23
|
+
setEditedSpec: (spec: string) => void;
|
|
24
|
+
/** Apply all changes (calls onSpecChange callback) */
|
|
25
|
+
applyChanges: () => void;
|
|
26
|
+
/** Cancel changes and revert to last applied state */
|
|
27
|
+
cancelChanges: () => void;
|
|
28
|
+
/** Reset to original initial values */
|
|
29
|
+
resetToOriginal: () => void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Callback when spec changes are applied
|
|
33
|
+
*/
|
|
34
|
+
export type OnMosaicSpecChange = (newSpec: Spec) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Context value provided by MosaicChart.Container
|
|
37
|
+
*/
|
|
38
|
+
export interface MosaicEditorContextValue {
|
|
39
|
+
state: MosaicEditorState;
|
|
40
|
+
actions: MosaicEditorActions;
|
|
41
|
+
/** Whether editing is enabled */
|
|
42
|
+
editable: boolean;
|
|
43
|
+
/** Pre-defined params/selections for shared cross-filtering */
|
|
44
|
+
params?: Map<string, Param<any>>;
|
|
45
|
+
/** Whether apply is possible (no errors, has changes) */
|
|
46
|
+
canApply: boolean;
|
|
47
|
+
/** Whether there are any unsaved changes */
|
|
48
|
+
hasChanges: boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Props for the useMosaicChartEditor hook
|
|
52
|
+
*/
|
|
53
|
+
export interface UseMosaicChartEditorOptions {
|
|
54
|
+
/** Initial Mosaic spec */
|
|
55
|
+
initialSpec: Spec | string;
|
|
56
|
+
/** Callback when spec changes are applied */
|
|
57
|
+
onSpecChange?: OnMosaicSpecChange;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Return type for useMosaicChartEditor hook
|
|
61
|
+
*/
|
|
62
|
+
export interface UseMosaicChartEditorReturn {
|
|
63
|
+
state: MosaicEditorState;
|
|
64
|
+
actions: MosaicEditorActions;
|
|
65
|
+
/** Parsed spec ready for rendering (null if parse error) */
|
|
66
|
+
parsedSpec: Spec | null;
|
|
67
|
+
/** Whether apply button should be enabled */
|
|
68
|
+
canApply: boolean;
|
|
69
|
+
/** Whether there are any unsaved changes */
|
|
70
|
+
hasChanges: boolean;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/editor/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAC,IAAI,EAAC,MAAM,qBAAqB,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,uCAAuC;IACvC,gBAAgB,EAAE,MAAM,CAAC;IACzB,+CAA+C;IAC/C,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,iEAAiE;IACjE,aAAa,EAAE,IAAI,CAAC;IACpB,sCAAsC;IACtC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,6DAA6D;IAC7D,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,oCAAoC;IACpC,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,sDAAsD;IACtD,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,sDAAsD;IACtD,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,uCAAuC;IACvC,eAAe,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,EAAE,IAAI,KAAK,IAAI,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,iBAAiB,CAAC;IACzB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,iCAAiC;IACjC,QAAQ,EAAE,OAAO,CAAC;IAClB,+DAA+D;IAE/D,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,yDAAyD;IACzD,QAAQ,EAAE,OAAO,CAAC;IAClB,4CAA4C;IAC5C,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,0BAA0B;IAC1B,WAAW,EAAE,IAAI,GAAG,MAAM,CAAC;IAC3B,6CAA6C;IAC7C,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,iBAAiB,CAAC;IACzB,OAAO,EAAE,mBAAmB,CAAC;IAC7B,4DAA4D;IAC5D,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;IACxB,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAC;IAClB,4CAA4C;IAC5C,UAAU,EAAE,OAAO,CAAC;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/editor/types.ts"],"names":[],"mappings":"","sourcesContent":["import {Param} from '@uwdata/mosaic-core';\nimport {Spec} from '@uwdata/mosaic-spec';\n\n/**\n * State managed by the Mosaic spec editor\n */\nexport interface MosaicEditorState {\n /** The edited spec as a JSON string */\n editedSpecString: string;\n /** Parsed spec object (null if parse error) */\n parsedSpec: Spec | null;\n /** Last successfully parsed spec (for fallback during errors) */\n lastValidSpec: Spec;\n /** JSON parse error message if any */\n specParseError: string | null;\n /** Whether spec has been modified from last applied state */\n isSpecDirty: boolean;\n}\n\n/**\n * Actions available in the Mosaic spec editor\n */\nexport interface MosaicEditorActions {\n /** Update the edited spec string */\n setEditedSpec: (spec: string) => void;\n /** Apply all changes (calls onSpecChange callback) */\n applyChanges: () => void;\n /** Cancel changes and revert to last applied state */\n cancelChanges: () => void;\n /** Reset to original initial values */\n resetToOriginal: () => void;\n}\n\n/**\n * Callback when spec changes are applied\n */\nexport type OnMosaicSpecChange = (newSpec: Spec) => void;\n\n/**\n * Context value provided by MosaicChart.Container\n */\nexport interface MosaicEditorContextValue {\n state: MosaicEditorState;\n actions: MosaicEditorActions;\n /** Whether editing is enabled */\n editable: boolean;\n /** Pre-defined params/selections for shared cross-filtering */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n params?: Map<string, Param<any>>;\n /** Whether apply is possible (no errors, has changes) */\n canApply: boolean;\n /** Whether there are any unsaved changes */\n hasChanges: boolean;\n}\n\n/**\n * Props for the useMosaicChartEditor hook\n */\nexport interface UseMosaicChartEditorOptions {\n /** Initial Mosaic spec */\n initialSpec: Spec | string;\n /** Callback when spec changes are applied */\n onSpecChange?: OnMosaicSpecChange;\n}\n\n/**\n * Return type for useMosaicChartEditor hook\n */\nexport interface UseMosaicChartEditorReturn {\n state: MosaicEditorState;\n actions: MosaicEditorActions;\n /** Parsed spec ready for rendering (null if parse error) */\n parsedSpec: Spec | null;\n /** Whether apply button should be enabled */\n canApply: boolean;\n /** Whether there are any unsaved changes */\n hasChanges: boolean;\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { UseMosaicChartEditorOptions, UseMosaicChartEditorReturn } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Hook for managing Mosaic chart editor state.
|
|
4
|
+
*
|
|
5
|
+
* Provides local state management with debounced spec parsing for live preview,
|
|
6
|
+
* and external callbacks for persisting changes.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useMosaicChartEditor({ initialSpec, onSpecChange, }: UseMosaicChartEditorOptions): UseMosaicChartEditorReturn;
|
|
9
|
+
//# sourceMappingURL=useMosaicChartEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMosaicChartEditor.d.ts","sourceRoot":"","sources":["../../src/editor/useMosaicChartEditor.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,2BAA2B,EAC3B,0BAA0B,EAC3B,MAAM,SAAS,CAAC;AAiCjB;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,WAAW,EACX,YAAY,GACb,EAAE,2BAA2B,GAAG,0BAA0B,CA4L1D"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { safeJsonParse } from '@sqlrooms/utils';
|
|
3
|
+
function normalizeInitialSpec(spec) {
|
|
4
|
+
if (typeof spec === 'string') {
|
|
5
|
+
const parsed = safeJsonParse(spec);
|
|
6
|
+
if (typeof parsed === 'object' &&
|
|
7
|
+
parsed !== null &&
|
|
8
|
+
!Array.isArray(parsed)) {
|
|
9
|
+
return {
|
|
10
|
+
parsed: parsed,
|
|
11
|
+
normalized: JSON.stringify(parsed),
|
|
12
|
+
formatted: JSON.stringify(parsed, null, 2),
|
|
13
|
+
parseOk: true,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
parsed: null,
|
|
18
|
+
normalized: spec,
|
|
19
|
+
formatted: spec,
|
|
20
|
+
parseOk: false,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
parsed: spec,
|
|
25
|
+
normalized: JSON.stringify(spec),
|
|
26
|
+
formatted: JSON.stringify(spec, null, 2),
|
|
27
|
+
parseOk: true,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Hook for managing Mosaic chart editor state.
|
|
32
|
+
*
|
|
33
|
+
* Provides local state management with debounced spec parsing for live preview,
|
|
34
|
+
* and external callbacks for persisting changes.
|
|
35
|
+
*/
|
|
36
|
+
export function useMosaicChartEditor({ initialSpec, onSpecChange, }) {
|
|
37
|
+
const initialSpecState = normalizeInitialSpec(initialSpec);
|
|
38
|
+
const [editorState, setEditorState] = useState(() => ({
|
|
39
|
+
editedSpecString: initialSpecState.formatted,
|
|
40
|
+
appliedSpecString: initialSpecState.normalized,
|
|
41
|
+
originalSpecString: initialSpecState.formatted,
|
|
42
|
+
prevInitialSpecString: initialSpecState.normalized,
|
|
43
|
+
lastValidSpec: initialSpecState.parsed ?? {},
|
|
44
|
+
}));
|
|
45
|
+
// Detect prop changes during render
|
|
46
|
+
const currentInitialSpec = normalizeInitialSpec(initialSpec);
|
|
47
|
+
if (currentInitialSpec.normalized !== editorState.prevInitialSpecString) {
|
|
48
|
+
setEditorState((prev) => ({
|
|
49
|
+
...prev,
|
|
50
|
+
prevInitialSpecString: currentInitialSpec.normalized,
|
|
51
|
+
appliedSpecString: currentInitialSpec.normalized,
|
|
52
|
+
editedSpecString: currentInitialSpec.formatted,
|
|
53
|
+
originalSpecString: currentInitialSpec.formatted,
|
|
54
|
+
lastValidSpec: currentInitialSpec.parseOk
|
|
55
|
+
? currentInitialSpec.parsed
|
|
56
|
+
: prev.lastValidSpec,
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
59
|
+
const { editedSpecString, appliedSpecString } = editorState;
|
|
60
|
+
// Debounced spec parsing for live preview.
|
|
61
|
+
// Only update parsedSpec/specParseError after the user stops typing.
|
|
62
|
+
const [debouncedParsed, setDebouncedParsed] = useState(() => {
|
|
63
|
+
try {
|
|
64
|
+
const parsed = JSON.parse(editedSpecString);
|
|
65
|
+
return {
|
|
66
|
+
parsedSpec: parsed,
|
|
67
|
+
specParseError: null,
|
|
68
|
+
normalized: JSON.stringify(parsed),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
const message = e instanceof Error ? e.message : 'Invalid JSON';
|
|
73
|
+
return { parsedSpec: null, specParseError: message, normalized: null };
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
const timer = setTimeout(() => {
|
|
78
|
+
setDebouncedParsed((prev) => {
|
|
79
|
+
try {
|
|
80
|
+
const parsed = JSON.parse(editedSpecString);
|
|
81
|
+
const normalized = JSON.stringify(parsed);
|
|
82
|
+
if (normalized === prev.normalized) {
|
|
83
|
+
return prev;
|
|
84
|
+
}
|
|
85
|
+
return { parsedSpec: parsed, specParseError: null, normalized };
|
|
86
|
+
}
|
|
87
|
+
catch (e) {
|
|
88
|
+
const message = e instanceof Error ? e.message : 'Invalid JSON';
|
|
89
|
+
if (prev.specParseError === message) {
|
|
90
|
+
return prev;
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
parsedSpec: null,
|
|
94
|
+
specParseError: message,
|
|
95
|
+
normalized: prev.normalized,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}, 300);
|
|
100
|
+
return () => clearTimeout(timer);
|
|
101
|
+
}, [editedSpecString]);
|
|
102
|
+
const { parsedSpec, specParseError } = debouncedParsed;
|
|
103
|
+
if (parsedSpec && parsedSpec !== editorState.lastValidSpec) {
|
|
104
|
+
setEditorState((prev) => ({ ...prev, lastValidSpec: parsedSpec }));
|
|
105
|
+
}
|
|
106
|
+
const lastValidSpec = editorState.lastValidSpec;
|
|
107
|
+
const isSpecDirty = useMemo(() => {
|
|
108
|
+
try {
|
|
109
|
+
const currentNormalized = JSON.stringify(JSON.parse(editedSpecString));
|
|
110
|
+
return currentNormalized !== appliedSpecString;
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
}, [editedSpecString, appliedSpecString]);
|
|
116
|
+
const hasChanges = isSpecDirty;
|
|
117
|
+
const canApply = hasChanges && !specParseError;
|
|
118
|
+
const onSpecChangeRef = useRef(onSpecChange);
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
onSpecChangeRef.current = onSpecChange;
|
|
121
|
+
}, [onSpecChange]);
|
|
122
|
+
const setEditedSpec = useCallback((spec) => {
|
|
123
|
+
setEditorState((prev) => ({ ...prev, editedSpecString: spec }));
|
|
124
|
+
}, []);
|
|
125
|
+
const applyChanges = useCallback(() => {
|
|
126
|
+
setEditorState((prev) => {
|
|
127
|
+
let parsed;
|
|
128
|
+
try {
|
|
129
|
+
parsed = JSON.parse(prev.editedSpecString);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return prev;
|
|
133
|
+
}
|
|
134
|
+
const newAppliedSpecString = JSON.stringify(parsed);
|
|
135
|
+
const dirty = newAppliedSpecString !== prev.appliedSpecString;
|
|
136
|
+
if (dirty) {
|
|
137
|
+
onSpecChangeRef.current?.(parsed);
|
|
138
|
+
}
|
|
139
|
+
return dirty
|
|
140
|
+
? {
|
|
141
|
+
...prev,
|
|
142
|
+
appliedSpecString: newAppliedSpecString,
|
|
143
|
+
prevInitialSpecString: newAppliedSpecString,
|
|
144
|
+
}
|
|
145
|
+
: prev;
|
|
146
|
+
});
|
|
147
|
+
}, []);
|
|
148
|
+
const cancelChanges = useCallback(() => {
|
|
149
|
+
setEditorState((prev) => {
|
|
150
|
+
try {
|
|
151
|
+
const appliedSpec = JSON.parse(prev.appliedSpecString);
|
|
152
|
+
return {
|
|
153
|
+
...prev,
|
|
154
|
+
editedSpecString: JSON.stringify(appliedSpec, null, 2),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
return {
|
|
159
|
+
...prev,
|
|
160
|
+
editedSpecString: prev.appliedSpecString,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}, []);
|
|
165
|
+
const resetToOriginal = useCallback(() => {
|
|
166
|
+
setEditorState((prev) => {
|
|
167
|
+
try {
|
|
168
|
+
const originalSpec = JSON.parse(prev.originalSpecString);
|
|
169
|
+
const originalSpecNormalized = JSON.stringify(originalSpec);
|
|
170
|
+
onSpecChangeRef.current?.(originalSpec);
|
|
171
|
+
return {
|
|
172
|
+
...prev,
|
|
173
|
+
editedSpecString: prev.originalSpecString,
|
|
174
|
+
appliedSpecString: originalSpecNormalized,
|
|
175
|
+
prevInitialSpecString: originalSpecNormalized,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return prev;
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}, []);
|
|
183
|
+
const actions = useMemo(() => ({ setEditedSpec, applyChanges, cancelChanges, resetToOriginal }), [setEditedSpec, applyChanges, cancelChanges, resetToOriginal]);
|
|
184
|
+
const state = useMemo(() => ({
|
|
185
|
+
editedSpecString,
|
|
186
|
+
parsedSpec,
|
|
187
|
+
lastValidSpec,
|
|
188
|
+
specParseError,
|
|
189
|
+
isSpecDirty,
|
|
190
|
+
}), [editedSpecString, parsedSpec, lastValidSpec, specParseError, isSpecDirty]);
|
|
191
|
+
return {
|
|
192
|
+
state,
|
|
193
|
+
actions,
|
|
194
|
+
parsedSpec,
|
|
195
|
+
canApply,
|
|
196
|
+
hasChanges,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=useMosaicChartEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMosaicChartEditor.js","sourceRoot":"","sources":["../../src/editor/useMosaicChartEditor.ts"],"names":[],"mappings":"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","sourcesContent":["import {Spec} from '@uwdata/mosaic-spec';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {safeJsonParse} from '@sqlrooms/utils';\nimport {\n MosaicEditorActions,\n MosaicEditorState,\n UseMosaicChartEditorOptions,\n UseMosaicChartEditorReturn,\n} from './types';\n\nfunction normalizeInitialSpec(spec: Spec | string) {\n if (typeof spec === 'string') {\n const parsed = safeJsonParse(spec) as unknown;\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n !Array.isArray(parsed)\n ) {\n return {\n parsed: parsed as Spec,\n normalized: JSON.stringify(parsed),\n formatted: JSON.stringify(parsed, null, 2),\n parseOk: true,\n };\n }\n return {\n parsed: null,\n normalized: spec,\n formatted: spec,\n parseOk: false,\n };\n }\n\n return {\n parsed: spec,\n normalized: JSON.stringify(spec),\n formatted: JSON.stringify(spec, null, 2),\n parseOk: true,\n };\n}\n\n/**\n * Hook for managing Mosaic chart editor state.\n *\n * Provides local state management with debounced spec parsing for live preview,\n * and external callbacks for persisting changes.\n */\nexport function useMosaicChartEditor({\n initialSpec,\n onSpecChange,\n}: UseMosaicChartEditorOptions): UseMosaicChartEditorReturn {\n const initialSpecState = normalizeInitialSpec(initialSpec);\n\n const [editorState, setEditorState] = useState(() => ({\n editedSpecString: initialSpecState.formatted,\n appliedSpecString: initialSpecState.normalized,\n originalSpecString: initialSpecState.formatted,\n prevInitialSpecString: initialSpecState.normalized,\n lastValidSpec: initialSpecState.parsed ?? ({} as unknown as Spec),\n }));\n\n // Detect prop changes during render\n const currentInitialSpec = normalizeInitialSpec(initialSpec);\n if (currentInitialSpec.normalized !== editorState.prevInitialSpecString) {\n setEditorState((prev) => ({\n ...prev,\n prevInitialSpecString: currentInitialSpec.normalized,\n appliedSpecString: currentInitialSpec.normalized,\n editedSpecString: currentInitialSpec.formatted,\n originalSpecString: currentInitialSpec.formatted,\n lastValidSpec: currentInitialSpec.parseOk\n ? (currentInitialSpec.parsed as Spec)\n : prev.lastValidSpec,\n }));\n }\n\n const {editedSpecString, appliedSpecString} = editorState;\n\n // Debounced spec parsing for live preview.\n // Only update parsedSpec/specParseError after the user stops typing.\n const [debouncedParsed, setDebouncedParsed] = useState<{\n parsedSpec: Spec | null;\n specParseError: string | null;\n normalized: string | null;\n }>(() => {\n try {\n const parsed = JSON.parse(editedSpecString) as Spec;\n return {\n parsedSpec: parsed,\n specParseError: null,\n normalized: JSON.stringify(parsed),\n };\n } catch (e) {\n const message = e instanceof Error ? e.message : 'Invalid JSON';\n return {parsedSpec: null, specParseError: message, normalized: null};\n }\n });\n\n useEffect(() => {\n const timer = setTimeout(() => {\n setDebouncedParsed((prev) => {\n try {\n const parsed = JSON.parse(editedSpecString) as Spec;\n const normalized = JSON.stringify(parsed);\n if (normalized === prev.normalized) {\n return prev;\n }\n return {parsedSpec: parsed, specParseError: null, normalized};\n } catch (e) {\n const message = e instanceof Error ? e.message : 'Invalid JSON';\n if (prev.specParseError === message) {\n return prev;\n }\n return {\n parsedSpec: null,\n specParseError: message,\n normalized: prev.normalized,\n };\n }\n });\n }, 300);\n return () => clearTimeout(timer);\n }, [editedSpecString]);\n\n const {parsedSpec, specParseError} = debouncedParsed;\n\n if (parsedSpec && parsedSpec !== editorState.lastValidSpec) {\n setEditorState((prev) => ({...prev, lastValidSpec: parsedSpec}));\n }\n const lastValidSpec = editorState.lastValidSpec;\n\n const isSpecDirty = useMemo(() => {\n try {\n const currentNormalized = JSON.stringify(JSON.parse(editedSpecString));\n return currentNormalized !== appliedSpecString;\n } catch {\n return true;\n }\n }, [editedSpecString, appliedSpecString]);\n\n const hasChanges = isSpecDirty;\n const canApply = hasChanges && !specParseError;\n\n const onSpecChangeRef = useRef(onSpecChange);\n useEffect(() => {\n onSpecChangeRef.current = onSpecChange;\n }, [onSpecChange]);\n\n const setEditedSpec = useCallback((spec: string) => {\n setEditorState((prev) => ({...prev, editedSpecString: spec}));\n }, []);\n\n const applyChanges = useCallback(() => {\n setEditorState((prev) => {\n let parsed: Spec;\n try {\n parsed = JSON.parse(prev.editedSpecString) as Spec;\n } catch {\n return prev;\n }\n\n const newAppliedSpecString = JSON.stringify(parsed);\n const dirty = newAppliedSpecString !== prev.appliedSpecString;\n\n if (dirty) {\n onSpecChangeRef.current?.(parsed);\n }\n\n return dirty\n ? {\n ...prev,\n appliedSpecString: newAppliedSpecString,\n prevInitialSpecString: newAppliedSpecString,\n }\n : prev;\n });\n }, []);\n\n const cancelChanges = useCallback(() => {\n setEditorState((prev) => {\n try {\n const appliedSpec = JSON.parse(prev.appliedSpecString);\n return {\n ...prev,\n editedSpecString: JSON.stringify(appliedSpec, null, 2),\n };\n } catch {\n return {\n ...prev,\n editedSpecString: prev.appliedSpecString,\n };\n }\n });\n }, []);\n\n const resetToOriginal = useCallback(() => {\n setEditorState((prev) => {\n try {\n const originalSpec = JSON.parse(prev.originalSpecString) as Spec;\n const originalSpecNormalized = JSON.stringify(originalSpec);\n\n onSpecChangeRef.current?.(originalSpec);\n\n return {\n ...prev,\n editedSpecString: prev.originalSpecString,\n appliedSpecString: originalSpecNormalized,\n prevInitialSpecString: originalSpecNormalized,\n };\n } catch {\n return prev;\n }\n });\n }, []);\n\n const actions: MosaicEditorActions = useMemo(\n () => ({setEditedSpec, applyChanges, cancelChanges, resetToOriginal}),\n [setEditedSpec, applyChanges, cancelChanges, resetToOriginal],\n );\n\n const state: MosaicEditorState = useMemo(\n () => ({\n editedSpecString,\n parsedSpec,\n lastValidSpec,\n specParseError,\n isSpecDirty,\n }),\n [editedSpecString, parsedSpec, lastValidSpec, specParseError, isSpecDirty],\n );\n\n return {\n state,\n actions,\n parsedSpec,\n canApply,\n hasChanges,\n };\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,10 +3,35 @@
|
|
|
3
3
|
* @packageDocumentation
|
|
4
4
|
*/
|
|
5
5
|
export { isParam, isSelection, makeClient, Param, Selection, } from '@uwdata/mosaic-core';
|
|
6
|
+
export { astToDOM, astToESM, parseSpec } from '@uwdata/mosaic-spec';
|
|
6
7
|
export type { Spec } from '@uwdata/mosaic-spec';
|
|
7
|
-
export { Query, sql } from '@uwdata/mosaic-sql';
|
|
8
|
+
export { asc, column, desc, Query, sql } from '@uwdata/mosaic-sql';
|
|
8
9
|
export * as vg from '@uwdata/vgplot';
|
|
9
|
-
export { createDefaultMosaicConfig, createMosaicSlice, MosaicSliceConfig, type MosaicClientOptions, type TrackedClient, } from './MosaicSlice';
|
|
10
|
+
export { createDefaultMosaicConfig, createMosaicSlice, MosaicSliceConfig, type CreateMosaicSliceProps, type MosaicClientOptions, type MosaicSliceState, type TrackedClient, } from './MosaicSlice';
|
|
11
|
+
export { MosaicProfiler, type MosaicProfilerCompoundHeaderProps, type MosaicProfilerCompoundRowsProps, type MosaicProfilerCompoundStatusBarProps, type MosaicProfilerCompoundTableProps, type MosaicProfilerProps, type MosaicProfilerRootProps, } from './profiler/MosaicProfiler';
|
|
12
|
+
export { MosaicProfilerHeader, type MosaicProfilerHeaderProps, } from './profiler/MosaicProfilerHeader';
|
|
13
|
+
export { MosaicProfilerRows, type MosaicProfilerRowsProps, } from './profiler/MosaicProfilerRows';
|
|
14
|
+
export { MosaicProfilerStatusBar, type MosaicProfilerStatusBarProps, } from './profiler/MosaicProfilerStatusBar';
|
|
15
|
+
export { useMosaicProfiler } from './profiler/useMosaicProfiler';
|
|
10
16
|
export { useMosaicClient, type UseMosaicClientOptions } from './useMosaicClient';
|
|
17
|
+
export { createMosaicColorLegendPlot, MosaicColorLegend, type MosaicColorLegendProps, } from './MosaicColorLegend';
|
|
11
18
|
export { VgPlotChart } from './VgPlotChart';
|
|
19
|
+
export { MosaicChart } from './MosaicChart';
|
|
20
|
+
export { MosaicChartBuilder } from './MosaicChartBuilder';
|
|
21
|
+
export { useMosaicEditorContext } from './editor/MosaicEditorContext';
|
|
22
|
+
export { getCachedMosaicSchema, loadMosaicSchema, preloadMosaicSchema, } from './editor/mosaicSchema';
|
|
23
|
+
export { useMosaicChartEditor } from './editor/useMosaicChartEditor';
|
|
24
|
+
export type { MosaicChartContainerProps } from './editor/MosaicChartContainer';
|
|
25
|
+
export type { MosaicChartDisplayProps } from './editor/MosaicChartDisplay';
|
|
26
|
+
export type { MosaicChartEditorActionsProps } from './editor/MosaicChartEditorActions';
|
|
27
|
+
export type { MosaicCodeMirrorEditorProps } from './editor/MosaicCodeMirrorEditor';
|
|
28
|
+
export type { MosaicSpecEditorPanelProps } from './editor/MosaicSpecEditorPanel';
|
|
29
|
+
export type { MosaicEditorActions, MosaicEditorContextValue, MosaicEditorState, OnMosaicSpecChange, UseMosaicChartEditorOptions, UseMosaicChartEditorReturn, } from './editor/types';
|
|
30
|
+
export { getProfilerTableWidth, PROFILER_DEFAULT_COLUMN_WIDTH_PX, PROFILER_ROW_NUMBER_COLUMN_WIDTH_PX, PROFILER_UNSUPPORTED_COLUMN_WIDTH_PX, } from './profiler/layout';
|
|
31
|
+
export type { MosaicProfilerCategoryBucket, MosaicProfilerCategorySummary, MosaicProfilerColumnKind, MosaicProfilerColumnState, MosaicProfilerHistogramSummary, MosaicProfilerOptions, MosaicProfilerPaginationState, MosaicProfilerSorting, MosaicProfilerSummaryState, UseMosaicProfilerReturn, } from './profiler/types';
|
|
32
|
+
export { createDefaultChartBuilders } from './chart-builders/builders';
|
|
33
|
+
export type { ChartBuilderContentProps } from './chart-builders/ChartBuilderContent';
|
|
34
|
+
export type { ChartBuilderDialogProps } from './chart-builders/ChartBuilderDialog';
|
|
35
|
+
export type { FieldSelectorInputProps } from './chart-builders/FieldSelectorInput';
|
|
36
|
+
export type { ChartBuilderColumn, ChartBuilderField, ChartBuilderTemplate, } from './chart-builders/types';
|
|
12
37
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,OAAO,EACP,WAAW,EACX,UAAU,EACV,KAAK,EACL,SAAS,GACV,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAC,IAAI,EAAC,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAC,KAAK,EAAE,GAAG,EAAC,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,9 +3,26 @@
|
|
|
3
3
|
* @packageDocumentation
|
|
4
4
|
*/
|
|
5
5
|
export { isParam, isSelection, makeClient, Param, Selection, } from '@uwdata/mosaic-core';
|
|
6
|
-
export {
|
|
6
|
+
export { astToDOM, astToESM, parseSpec } from '@uwdata/mosaic-spec';
|
|
7
|
+
export { asc, column, desc, Query, sql } from '@uwdata/mosaic-sql';
|
|
7
8
|
export * as vg from '@uwdata/vgplot';
|
|
8
9
|
export { createDefaultMosaicConfig, createMosaicSlice, MosaicSliceConfig, } from './MosaicSlice';
|
|
10
|
+
export { MosaicProfiler, } from './profiler/MosaicProfiler';
|
|
11
|
+
export { MosaicProfilerHeader, } from './profiler/MosaicProfilerHeader';
|
|
12
|
+
export { MosaicProfilerRows, } from './profiler/MosaicProfilerRows';
|
|
13
|
+
export { MosaicProfilerStatusBar, } from './profiler/MosaicProfilerStatusBar';
|
|
14
|
+
export { useMosaicProfiler } from './profiler/useMosaicProfiler';
|
|
9
15
|
export { useMosaicClient } from './useMosaicClient';
|
|
16
|
+
export { createMosaicColorLegendPlot, MosaicColorLegend, } from './MosaicColorLegend';
|
|
10
17
|
export { VgPlotChart } from './VgPlotChart';
|
|
18
|
+
// Compound components
|
|
19
|
+
export { MosaicChart } from './MosaicChart';
|
|
20
|
+
export { MosaicChartBuilder } from './MosaicChartBuilder';
|
|
21
|
+
// Editor hooks and context
|
|
22
|
+
export { useMosaicEditorContext } from './editor/MosaicEditorContext';
|
|
23
|
+
export { getCachedMosaicSchema, loadMosaicSchema, preloadMosaicSchema, } from './editor/mosaicSchema';
|
|
24
|
+
export { useMosaicChartEditor } from './editor/useMosaicChartEditor';
|
|
25
|
+
export { getProfilerTableWidth, PROFILER_DEFAULT_COLUMN_WIDTH_PX, PROFILER_ROW_NUMBER_COLUMN_WIDTH_PX, PROFILER_UNSUPPORTED_COLUMN_WIDTH_PX, } from './profiler/layout';
|
|
26
|
+
// Chart builder types and utilities
|
|
27
|
+
export { createDefaultChartBuilders } from './chart-builders/builders';
|
|
11
28
|
//# sourceMappingURL=index.js.map
|