sculpted 0.3.0 → 0.3.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 +2 -5
- package/dist/{runtime-C911j-aR.d.mts → runtime-C1gUOAc9.d.mts} +2 -1
- package/dist/runtime.d.mts +1 -1
- package/dist/runtime.mjs +5 -1
- package/dist/ui.d.mts +1 -1
- package/dist/ui.mjs +147 -10
- package/dist/vite.d.mts +0 -11
- package/dist/vite.mjs +5 -8
- package/docs/examples.md +4 -4
- package/docs/source-syntax-adapters.md +6 -49
- package/docs/source-writeback.md +5 -10
- package/docs/vite-plugin.md +6 -85
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -117,13 +117,10 @@ instead of pretending the full cascade can be edited safely.
|
|
|
117
117
|
|
|
118
118
|
## Documentation
|
|
119
119
|
|
|
120
|
-
- [Vite plugin options](docs/vite-plugin.md) covers setup, defaults,
|
|
121
|
-
dev/prod behavior.
|
|
120
|
+
- [Vite plugin options](docs/vite-plugin.md) covers setup, defaults, and dev/prod behavior.
|
|
122
121
|
- [Source writeback](docs/source-writeback.md) covers the safety model, supported edit shapes, and
|
|
123
122
|
common failure modes.
|
|
124
|
-
- [Source syntax adapters](docs/source-syntax-adapters.md) covers TSRX
|
|
125
|
-
- [Example apps](docs/examples.md) covers the React and Preact Panda CSS examples used for manual
|
|
126
|
-
verification.
|
|
123
|
+
- [Source syntax adapters](docs/source-syntax-adapters.md) covers opt-in TSRX support.
|
|
127
124
|
|
|
128
125
|
## Troubleshooting
|
|
129
126
|
|
|
@@ -45,7 +45,8 @@ declare class SculptedRuntime {
|
|
|
45
45
|
requestTokenConfigEdit(request: TokenConfigEditRequest, write: boolean): Promise<TokenConfigEditResponse>;
|
|
46
46
|
openSourceLocation(request: OpenSourceLocationRequest): Promise<OpenSourceLocationResponse>;
|
|
47
47
|
selectElement(element: Element): Promise<SelectedElementInfo>;
|
|
48
|
-
|
|
48
|
+
inspectElementEvidence(element: Element): SelectedElementInfo['evidence'];
|
|
49
|
+
startInspecting(onSelect?: (info: SelectedElementInfo, element: Element) => void, onStop?: () => void, onInspect?: (element: Element, evidence: SelectedElementInfo['evidence']) => void): () => void;
|
|
49
50
|
stopInspecting(): void;
|
|
50
51
|
highlightElement(element: Element): void;
|
|
51
52
|
highlightElements(elements: readonly Element[]): void;
|
package/dist/runtime.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as installSculptedRuntime, n as RuntimeInspectorOptions, r as SculptedRuntime, t as RuntimeEnvironment } from "./runtime-
|
|
1
|
+
import { i as installSculptedRuntime, n as RuntimeInspectorOptions, r as SculptedRuntime, t as RuntimeEnvironment } from "./runtime-C1gUOAc9.mjs";
|
|
2
2
|
export { RuntimeEnvironment, RuntimeInspectorOptions, SculptedRuntime, installSculptedRuntime };
|
package/dist/runtime.mjs
CHANGED
|
@@ -262,7 +262,10 @@ var SculptedRuntime = class {
|
|
|
262
262
|
message: target?.reason ?? "Selected Panda source target is not editable."
|
|
263
263
|
};
|
|
264
264
|
}
|
|
265
|
-
|
|
265
|
+
inspectElementEvidence(element) {
|
|
266
|
+
return this.#elementEvidence(element);
|
|
267
|
+
}
|
|
268
|
+
startInspecting(onSelect, onStop, onInspect) {
|
|
266
269
|
this.stopInspecting();
|
|
267
270
|
const { window } = this.#environment;
|
|
268
271
|
const onPointerMove = (event) => {
|
|
@@ -279,6 +282,7 @@ var SculptedRuntime = class {
|
|
|
279
282
|
event.preventDefault();
|
|
280
283
|
event.stopPropagation();
|
|
281
284
|
this.stopInspecting();
|
|
285
|
+
onInspect?.(element, this.#elementEvidence(element));
|
|
282
286
|
this.selectElement(element).then((info) => {
|
|
283
287
|
onSelect?.(info, element);
|
|
284
288
|
});
|
package/dist/ui.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { F as RuntimePropertyContext, L as SelectedElementInfo, N as RuntimeCssDeclaration, j as RuntimeComponentLayer } from "./types-CdByW0ji.mjs";
|
|
2
|
-
import { r as SculptedRuntime } from "./runtime-
|
|
2
|
+
import { r as SculptedRuntime } from "./runtime-C1gUOAc9.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/ui/inspectorPanel.d.ts
|
|
5
5
|
type ReadonlyInspectorPanelOptions = {
|
package/dist/ui.mjs
CHANGED
|
@@ -1011,6 +1011,23 @@ const RefreshCw = createLucideIcon("refresh-cw", [
|
|
|
1011
1011
|
}]
|
|
1012
1012
|
]);
|
|
1013
1013
|
//#endregion
|
|
1014
|
+
//#region node_modules/.pnpm/lucide-preact@1.16.0_preact@10.29.2/node_modules/lucide-preact/dist/esm/icons/settings.mjs
|
|
1015
|
+
/**
|
|
1016
|
+
* @license lucide-preact v1.16.0 - ISC
|
|
1017
|
+
*
|
|
1018
|
+
* This source code is licensed under the ISC license.
|
|
1019
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
1020
|
+
*/
|
|
1021
|
+
const Settings = createLucideIcon("settings", [["path", {
|
|
1022
|
+
d: "M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",
|
|
1023
|
+
key: "1i5ecw"
|
|
1024
|
+
}], ["circle", {
|
|
1025
|
+
cx: "12",
|
|
1026
|
+
cy: "12",
|
|
1027
|
+
r: "3",
|
|
1028
|
+
key: "1v7zrd"
|
|
1029
|
+
}]]);
|
|
1030
|
+
//#endregion
|
|
1014
1031
|
//#region node_modules/.pnpm/lucide-preact@1.16.0_preact@10.29.2/node_modules/lucide-preact/dist/esm/icons/square-dashed-mouse-pointer.mjs
|
|
1015
1032
|
/**
|
|
1016
1033
|
* @license lucide-preact v1.16.0 - ISC
|
|
@@ -7461,6 +7478,9 @@ const INSPECTOR_DIALOG_PORTAL_ROOT = "data-sculpted-dialog-root";
|
|
|
7461
7478
|
const INSPECTOR_MENU_PORTAL_ROOT = "data-sculpted-menu-root";
|
|
7462
7479
|
const INLINE_SOURCE_PREVIEW_PATH = ["__inlineSource"];
|
|
7463
7480
|
const STYLE_MODULE_ACTION_PREVIEW_PATH = ["__styleModuleAction"];
|
|
7481
|
+
const COPY_ELEMENT_PATH_AFTER_INSPECT_STORAGE_KEY = "sculpted.copyElementPathAfterInspect";
|
|
7482
|
+
const PANEL_DOCKED_STORAGE_KEY = "sculpted.panelDocked";
|
|
7483
|
+
const PANEL_SIDE_STORAGE_KEY = "sculpted.panelSide";
|
|
7464
7484
|
function installReadonlyInspectorPanel(runtime, options = {}) {
|
|
7465
7485
|
let panel = null;
|
|
7466
7486
|
let previousBodyMarginLeft;
|
|
@@ -7575,14 +7595,41 @@ function applyInspectorPanelFrame(panel, state) {
|
|
|
7575
7595
|
panel.style.borderRadius = "8px";
|
|
7576
7596
|
panel.style.boxShadow = "0 18px 54px rgba(15, 23, 42, 0.18)";
|
|
7577
7597
|
}
|
|
7598
|
+
function loadBooleanPreference(storageKey, defaultValue) {
|
|
7599
|
+
try {
|
|
7600
|
+
const stored = window.localStorage.getItem(storageKey);
|
|
7601
|
+
if (stored === "true") return true;
|
|
7602
|
+
if (stored === "false") return false;
|
|
7603
|
+
} catch {}
|
|
7604
|
+
return defaultValue;
|
|
7605
|
+
}
|
|
7606
|
+
function saveBooleanPreference(storageKey, value) {
|
|
7607
|
+
try {
|
|
7608
|
+
window.localStorage.setItem(storageKey, value ? "true" : "false");
|
|
7609
|
+
} catch {}
|
|
7610
|
+
}
|
|
7611
|
+
function loadPanelSidePreference(defaultValue) {
|
|
7612
|
+
try {
|
|
7613
|
+
const stored = window.localStorage.getItem(PANEL_SIDE_STORAGE_KEY);
|
|
7614
|
+
if (stored === "left" || stored === "right") return stored;
|
|
7615
|
+
} catch {}
|
|
7616
|
+
return defaultValue;
|
|
7617
|
+
}
|
|
7618
|
+
function savePanelSidePreference(value) {
|
|
7619
|
+
try {
|
|
7620
|
+
window.localStorage.setItem(PANEL_SIDE_STORAGE_KEY, value);
|
|
7621
|
+
} catch {}
|
|
7622
|
+
}
|
|
7578
7623
|
function InspectorPanel(props) {
|
|
7579
7624
|
const { runtime, title, onFrameChange } = props;
|
|
7580
7625
|
const selected = useSignal();
|
|
7581
7626
|
const visible = useSignal(false);
|
|
7582
|
-
const docked = useSignal(false);
|
|
7583
|
-
const side = useSignal("right");
|
|
7627
|
+
const docked = useSignal(loadBooleanPreference(PANEL_DOCKED_STORAGE_KEY, false));
|
|
7628
|
+
const side = useSignal(loadPanelSidePreference("right"));
|
|
7584
7629
|
const isInspecting = useSignal(false);
|
|
7630
|
+
const settingsOpen = useSignal(false);
|
|
7585
7631
|
const previewEnabled = useSignal(true);
|
|
7632
|
+
const copyElementPathAfterInspect = useSignal(loadBooleanPreference(COPY_ELEMENT_PATH_AFTER_INSPECT_STORAGE_KEY, false));
|
|
7586
7633
|
const forcedPreviewStates = useSignal(/* @__PURE__ */ new Set());
|
|
7587
7634
|
const pendingPreviewChanges = useSignal(/* @__PURE__ */ new Map());
|
|
7588
7635
|
const expandedShorthandInputs = useSignal(/* @__PURE__ */ new Set());
|
|
@@ -7593,6 +7640,7 @@ function InspectorPanel(props) {
|
|
|
7593
7640
|
const elementStyleModule = useSignal({ status: "idle" });
|
|
7594
7641
|
const showingStyleModulePage = useComputed(() => styleModulePanel.value.status !== "idle");
|
|
7595
7642
|
const panelHeaderTitle = useComputed(() => {
|
|
7643
|
+
if (settingsOpen.value) return "Settings";
|
|
7596
7644
|
return styleModulePanel.value.status === "idle" ? title : "Style List";
|
|
7597
7645
|
});
|
|
7598
7646
|
const editorMetadata = useSignal();
|
|
@@ -7923,6 +7971,11 @@ function InspectorPanel(props) {
|
|
|
7923
7971
|
isInspecting.value = false;
|
|
7924
7972
|
clearInspectCursor();
|
|
7925
7973
|
};
|
|
7974
|
+
const copyInspectedElementPath = (evidence) => {
|
|
7975
|
+
if (!copyElementPathAfterInspect.value) return;
|
|
7976
|
+
const identity = inspectedElementIdentityFromLayers(evidence?.componentLayers ?? []);
|
|
7977
|
+
if (identity) navigator.clipboard?.writeText(identity).catch(() => {});
|
|
7978
|
+
};
|
|
7926
7979
|
const isPanelEditableFocused = () => {
|
|
7927
7980
|
const root = shell.current?.getRootNode();
|
|
7928
7981
|
const active = root && isShadowRoot(root) ? root.activeElement : document.activeElement;
|
|
@@ -7971,6 +8024,7 @@ function InspectorPanel(props) {
|
|
|
7971
8024
|
document.getSelection()?.removeAllRanges();
|
|
7972
8025
|
stopActiveInspecting();
|
|
7973
8026
|
clearModifierPreview();
|
|
8027
|
+
copyInspectedElementPath(typeof runtime.inspectElementEvidence === "function" ? runtime.inspectElementEvidence(element) : void 0);
|
|
7974
8028
|
runtime.selectElement(element).then((info) => {
|
|
7975
8029
|
selectedElement.current = element;
|
|
7976
8030
|
selectedElementAutofocusRevision.value += 1;
|
|
@@ -8015,9 +8069,12 @@ function InspectorPanel(props) {
|
|
|
8015
8069
|
selectedElement.current = element;
|
|
8016
8070
|
selectedElementAutofocusRevision.value += 1;
|
|
8017
8071
|
selected.value = info;
|
|
8072
|
+
settingsOpen.value = false;
|
|
8018
8073
|
applyPreviewChanges(pendingPreviewChanges.value, previewEnabled.value);
|
|
8019
8074
|
setPanelVisible(true);
|
|
8020
|
-
}, onStopInspecting)
|
|
8075
|
+
}, onStopInspecting, (_element, evidence) => {
|
|
8076
|
+
copyInspectedElementPath(evidence);
|
|
8077
|
+
});
|
|
8021
8078
|
isInspecting.value = true;
|
|
8022
8079
|
setInspectCursor();
|
|
8023
8080
|
};
|
|
@@ -8050,6 +8107,7 @@ function InspectorPanel(props) {
|
|
|
8050
8107
|
};
|
|
8051
8108
|
const toggleDocked = () => {
|
|
8052
8109
|
docked.value = !docked.value;
|
|
8110
|
+
saveBooleanPreference(PANEL_DOCKED_STORAGE_KEY, docked.value);
|
|
8053
8111
|
onFrameChange({
|
|
8054
8112
|
visible: visible.value,
|
|
8055
8113
|
docked: docked.value,
|
|
@@ -8059,12 +8117,20 @@ function InspectorPanel(props) {
|
|
|
8059
8117
|
const snapPanelSide = (nextSide) => {
|
|
8060
8118
|
if (side.value === nextSide) return;
|
|
8061
8119
|
side.value = nextSide;
|
|
8120
|
+
savePanelSidePreference(nextSide);
|
|
8062
8121
|
onFrameChange({
|
|
8063
8122
|
visible: visible.value,
|
|
8064
8123
|
docked: docked.value,
|
|
8065
8124
|
side: nextSide
|
|
8066
8125
|
});
|
|
8067
8126
|
};
|
|
8127
|
+
const openSettings = () => {
|
|
8128
|
+
settingsOpen.value = true;
|
|
8129
|
+
};
|
|
8130
|
+
const updateCopyElementPathAfterInspect = (enabled) => {
|
|
8131
|
+
copyElementPathAfterInspect.value = enabled;
|
|
8132
|
+
saveBooleanPreference(COPY_ELEMENT_PATH_AFTER_INSPECT_STORAGE_KEY, enabled);
|
|
8133
|
+
};
|
|
8068
8134
|
const togglePreview = (enabled) => {
|
|
8069
8135
|
previewEnabled.value = enabled;
|
|
8070
8136
|
applyPreviewChanges(pendingPreviewChanges.value, enabled);
|
|
@@ -8469,8 +8535,10 @@ function InspectorPanel(props) {
|
|
|
8469
8535
|
title: panelHeaderTitle,
|
|
8470
8536
|
isInspecting,
|
|
8471
8537
|
docked,
|
|
8472
|
-
showInspect: !showingStyleModulePage.value,
|
|
8473
|
-
onBack:
|
|
8538
|
+
showInspect: !showingStyleModulePage.value && !settingsOpen.value,
|
|
8539
|
+
onBack: settingsOpen.value ? () => {
|
|
8540
|
+
settingsOpen.value = false;
|
|
8541
|
+
} : showingStyleModulePage.value ? () => {
|
|
8474
8542
|
styleModulePanel.value = { status: "idle" };
|
|
8475
8543
|
} : void 0,
|
|
8476
8544
|
onInspect: toggleInspecting,
|
|
@@ -8481,6 +8549,7 @@ function InspectorPanel(props) {
|
|
|
8481
8549
|
disabled: saving,
|
|
8482
8550
|
onUndoPreview: undoPreviewChange,
|
|
8483
8551
|
onRedoPreview: redoPreviewChange,
|
|
8552
|
+
onSettings: openSettings,
|
|
8484
8553
|
onToggleDocked: toggleDocked,
|
|
8485
8554
|
onToggleSide: () => {
|
|
8486
8555
|
snapPanelSide(side.value === "right" ? "left" : "right");
|
|
@@ -8494,11 +8563,15 @@ function InspectorPanel(props) {
|
|
|
8494
8563
|
flex: "1 1 auto",
|
|
8495
8564
|
padding: "12px",
|
|
8496
8565
|
display: "grid",
|
|
8566
|
+
alignContent: "start",
|
|
8497
8567
|
gap: "12px",
|
|
8498
8568
|
overflow: "auto",
|
|
8499
8569
|
minHeight: 0
|
|
8500
8570
|
},
|
|
8501
|
-
children: [/* @__PURE__ */ u(SaveStatusSection, { saveFlow }),
|
|
8571
|
+
children: [/* @__PURE__ */ u(SaveStatusSection, { saveFlow }), settingsOpen.value ? /* @__PURE__ */ u(SettingsSection, {
|
|
8572
|
+
copyElementPathAfterInspect,
|
|
8573
|
+
onCopyElementPathAfterInspectChange: updateCopyElementPathAfterInspect
|
|
8574
|
+
}) : showingStyleModulePage.value ? /* @__PURE__ */ u(StyleModuleSection, {
|
|
8502
8575
|
state: styleModulePanel,
|
|
8503
8576
|
pendingChanges: pendingPreviewChanges,
|
|
8504
8577
|
preview,
|
|
@@ -9015,6 +9088,22 @@ function PanelHeader(props) {
|
|
|
9015
9088
|
children: "Clear"
|
|
9016
9089
|
})]
|
|
9017
9090
|
})
|
|
9091
|
+
}),
|
|
9092
|
+
/* @__PURE__ */ u(ShadowMenuItem, {
|
|
9093
|
+
class: "sculpted-menu-item",
|
|
9094
|
+
disabled: props.disabled.value,
|
|
9095
|
+
onSelect: props.onSettings,
|
|
9096
|
+
children: /* @__PURE__ */ u("span", {
|
|
9097
|
+
"data-menu-action": "settings",
|
|
9098
|
+
style: { display: "contents" },
|
|
9099
|
+
children: [/* @__PURE__ */ u(Settings, {
|
|
9100
|
+
size: 15,
|
|
9101
|
+
"aria-hidden": "true"
|
|
9102
|
+
}), /* @__PURE__ */ u("span", {
|
|
9103
|
+
style: { font: "inherit" },
|
|
9104
|
+
children: "Settings"
|
|
9105
|
+
})]
|
|
9106
|
+
})
|
|
9018
9107
|
})
|
|
9019
9108
|
]
|
|
9020
9109
|
})]
|
|
@@ -9064,6 +9153,39 @@ function SaveStatusSection(props) {
|
|
|
9064
9153
|
children: /* @__PURE__ */ u("div", { children: state.message })
|
|
9065
9154
|
});
|
|
9066
9155
|
}
|
|
9156
|
+
function SettingsSection(props) {
|
|
9157
|
+
return /* @__PURE__ */ u("section", {
|
|
9158
|
+
"data-settings-section": "true",
|
|
9159
|
+
style: {
|
|
9160
|
+
display: "grid",
|
|
9161
|
+
gap: "10px"
|
|
9162
|
+
},
|
|
9163
|
+
children: /* @__PURE__ */ u("label", {
|
|
9164
|
+
style: {
|
|
9165
|
+
display: "flex",
|
|
9166
|
+
alignItems: "center",
|
|
9167
|
+
justifyContent: "space-between",
|
|
9168
|
+
gap: "12px",
|
|
9169
|
+
border: "1px solid #d6dde8",
|
|
9170
|
+
borderRadius: "6px",
|
|
9171
|
+
padding: "10px",
|
|
9172
|
+
cursor: "pointer"
|
|
9173
|
+
},
|
|
9174
|
+
children: [/* @__PURE__ */ u("span", {
|
|
9175
|
+
style: { fontWeight: 700 },
|
|
9176
|
+
children: "Copy element path after inspect"
|
|
9177
|
+
}), /* @__PURE__ */ u("input", {
|
|
9178
|
+
type: "checkbox",
|
|
9179
|
+
"data-setting": "copy-element-path-after-inspect",
|
|
9180
|
+
checked: props.copyElementPathAfterInspect.value,
|
|
9181
|
+
onChange: (event) => {
|
|
9182
|
+
props.onCopyElementPathAfterInspectChange(event.currentTarget.checked);
|
|
9183
|
+
},
|
|
9184
|
+
style: { margin: 0 }
|
|
9185
|
+
})]
|
|
9186
|
+
})
|
|
9187
|
+
});
|
|
9188
|
+
}
|
|
9067
9189
|
function StyleModuleSection(props) {
|
|
9068
9190
|
const { state, pendingChanges, preview, forcedPreviewStates, expandedShorthandInputs, shorthandFocusRequest, colorTokenOptions, fontTokenOptions, tokenSources, propertyOptions, saving, addedInputActivationRequest, onPreviewInput, onCreateColorToken, onAddedInputActivationHandled, onAddProperty, onRemoveProperty, onFocusRestoreButton, onFocusPreviewControl, onRestoreProperty, onHighlightSourceTarget, onClearHighlight, onOpenSource, onInputMenuOpenChange, onToggleShorthandInput, onExpandShorthandInput, onCollapseShorthandInput, onRequestShorthandFocus, onShorthandFocusRequestHandled, onAddSource } = props;
|
|
9069
9191
|
if (state.value.status === "idle") return null;
|
|
@@ -10977,11 +11099,19 @@ function ComponentLayersSection(props) {
|
|
|
10977
11099
|
})] });
|
|
10978
11100
|
}
|
|
10979
11101
|
function componentLayerElementIdentity(view, layerIndex, elementIndex, jsxSource) {
|
|
10980
|
-
|
|
11102
|
+
return componentLayerElementIdentityFromLayers(view.componentLayers, layerIndex, elementIndex, jsxSource);
|
|
11103
|
+
}
|
|
11104
|
+
function componentLayerElementIdentityFromLayers(layers, layerIndex, elementIndex, jsxSource) {
|
|
10981
11105
|
const parentComponents = layers.slice(layerIndex).toReversed().map((layer) => layer.component);
|
|
10982
11106
|
const elementPath = layers[layerIndex]?.elements.slice(elementIndex).toReversed().map((element) => element.tagName);
|
|
10983
11107
|
return `I want to edit the following JSX element:\n ${[...parentComponents, ...elementPath ?? []].join(" → ")}${sourceLocationAvailable(jsxSource) ? `\n (found at ${jsxSource})` : ""}\n\n\n`;
|
|
10984
11108
|
}
|
|
11109
|
+
function inspectedElementIdentityFromLayers(layers) {
|
|
11110
|
+
for (const [layerIndex, layer] of layers.entries()) {
|
|
11111
|
+
const elementIndex = layer.elements.findIndex((element) => element.inspected === true);
|
|
11112
|
+
if (elementIndex !== -1) return componentLayerElementIdentityFromLayers(layers, layerIndex, elementIndex, layer.elements[elementIndex]?.source);
|
|
11113
|
+
}
|
|
11114
|
+
}
|
|
10985
11115
|
function componentLayerSource(layer) {
|
|
10986
11116
|
return layer.elements.find((element) => sourceLocationAvailable(element.source))?.source;
|
|
10987
11117
|
}
|
|
@@ -11031,12 +11161,19 @@ function ComputedRowsSection(props) {
|
|
|
11031
11161
|
gridTemplateColumns: "120px 1fr",
|
|
11032
11162
|
gap: "8px",
|
|
11033
11163
|
marginTop: "4px",
|
|
11034
|
-
color: "#526070"
|
|
11164
|
+
color: "#526070",
|
|
11165
|
+
userSelect: "text"
|
|
11035
11166
|
},
|
|
11036
|
-
children: [/* @__PURE__ */ u("code", {
|
|
11167
|
+
children: [/* @__PURE__ */ u("code", {
|
|
11168
|
+
"data-computed-css-property": "true",
|
|
11169
|
+
style: { userSelect: "text" },
|
|
11170
|
+
children: row.property
|
|
11171
|
+
}), /* @__PURE__ */ u("code", {
|
|
11172
|
+
"data-computed-css-value": "true",
|
|
11037
11173
|
style: {
|
|
11038
11174
|
whiteSpace: "normal",
|
|
11039
|
-
wordBreak: "break-word"
|
|
11175
|
+
wordBreak: "break-word",
|
|
11176
|
+
userSelect: "text"
|
|
11040
11177
|
},
|
|
11041
11178
|
children: row.value
|
|
11042
11179
|
})]
|
package/dist/vite.d.mts
CHANGED
|
@@ -9,12 +9,8 @@ type InspectorVitePluginOptions = {
|
|
|
9
9
|
readonly panda?: {
|
|
10
10
|
readonly configPath?: string;
|
|
11
11
|
readonly cssImportSources?: readonly string[];
|
|
12
|
-
readonly recipeImportSources?: readonly string[];
|
|
13
|
-
readonly cssFunctionNames?: readonly string[];
|
|
14
|
-
readonly cxFunctionNames?: readonly string[];
|
|
15
12
|
};
|
|
16
13
|
readonly manifest?: {
|
|
17
|
-
readonly outFile?: string;
|
|
18
14
|
readonly virtualEndpoint?: string;
|
|
19
15
|
};
|
|
20
16
|
readonly metadata?: {
|
|
@@ -22,13 +18,6 @@ type InspectorVitePluginOptions = {
|
|
|
22
18
|
};
|
|
23
19
|
readonly runtime?: {
|
|
24
20
|
readonly inject?: boolean;
|
|
25
|
-
readonly globalName?: string;
|
|
26
|
-
};
|
|
27
|
-
readonly attributes?: {
|
|
28
|
-
readonly editId?: string;
|
|
29
|
-
readonly source?: string;
|
|
30
|
-
readonly jsxSource?: string;
|
|
31
|
-
readonly component?: string;
|
|
32
21
|
};
|
|
33
22
|
readonly sourceSyntax?: SourceSyntaxOption;
|
|
34
23
|
};
|
package/dist/vite.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as markerClassForEditId, c as DEFAULT_OPEN_SOURCE_ENDPOINT, d as DEFAULT_TOKEN_WRITEBACK_ENDPOINT, f as DEFAULT_WRITEBACK_ENDPOINT, p as SCULPTED_EVENTS, u as DEFAULT_STYLE_MODULE_ENDPOINT } from "./protocol-D5heR2QM.mjs";
|
|
1
|
+
import { _ as markerClassForEditId, a as DEFAULT_JSX_SOURCE_ATTRIBUTE, c as DEFAULT_OPEN_SOURCE_ENDPOINT, d as DEFAULT_TOKEN_WRITEBACK_ENDPOINT, f as DEFAULT_WRITEBACK_ENDPOINT, l as DEFAULT_SOURCE_ATTRIBUTE, p as SCULPTED_EVENTS, r as DEFAULT_EDIT_ID_ATTRIBUTE, t as DEFAULT_COMPONENT_ATTRIBUTE, u as DEFAULT_STYLE_MODULE_ENDPOINT } from "./protocol-D5heR2QM.mjs";
|
|
2
2
|
import { S as resolveSourceParserAdapter, _ as analyzePandaCssSource, a as createStyleModuleSourcePatch, b as parsePandaSource, c as resolveProjectPath, d as toRelativeProjectPath$1, f as trustedManifestFilePath, g as createInlineCssSourcePatch, h as createStaticCssPatch, i as createStyleModuleDetachPatch, l as safeProjectSourcePath, m as createStaticCssBatchPatch, n as componentStyleModulePaths, o as readComponentStyleModule, p as trustedTokenSourceFilePath, r as createStyleModuleAttachPatch, s as normalizePath$1, t as createTokenConfigPatch, u as stripViteQuery, v as hashSource } from "./patcher-DQgKdozw.mjs";
|
|
3
3
|
import ts from "typescript";
|
|
4
4
|
import { access, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
@@ -998,7 +998,6 @@ function registerRuntimeModuleRoutes(server, options) {
|
|
|
998
998
|
response.end(runtimeBootstrapSource({
|
|
999
999
|
manifestEndpoint: options.manifestEndpoint,
|
|
1000
1000
|
editorMetadataEndpoint: options.editorMetadataEndpoint,
|
|
1001
|
-
globalName: options.globalName,
|
|
1002
1001
|
runtimeModuleEndpoint: options.runtimeModuleEndpoint,
|
|
1003
1002
|
uiModuleEndpoint: options.uiModuleEndpoint
|
|
1004
1003
|
}));
|
|
@@ -1084,7 +1083,6 @@ function registerRuntimeModuleRoutes(server, options) {
|
|
|
1084
1083
|
}
|
|
1085
1084
|
function runtimeBootstrapSource(options) {
|
|
1086
1085
|
const runtimeOptions = JSON.stringify({
|
|
1087
|
-
globalName: options.globalName,
|
|
1088
1086
|
manifestEndpoint: options.manifestEndpoint,
|
|
1089
1087
|
editorMetadataEndpoint: options.editorMetadataEndpoint
|
|
1090
1088
|
});
|
|
@@ -2189,10 +2187,10 @@ function sculpted(options = {}) {
|
|
|
2189
2187
|
const uiModuleEndpoint = DEFAULT_UI_MODULE_ENDPOINT;
|
|
2190
2188
|
const runtimeChunkEndpoint = DEFAULT_RUNTIME_CHUNK_ENDPOINT;
|
|
2191
2189
|
const attributes = {
|
|
2192
|
-
editId:
|
|
2193
|
-
source:
|
|
2194
|
-
jsxSource:
|
|
2195
|
-
component:
|
|
2190
|
+
editId: DEFAULT_EDIT_ID_ATTRIBUTE,
|
|
2191
|
+
source: DEFAULT_SOURCE_ATTRIBUTE,
|
|
2192
|
+
jsxSource: DEFAULT_JSX_SOURCE_ATTRIBUTE,
|
|
2193
|
+
component: DEFAULT_COMPONENT_ATTRIBUTE
|
|
2196
2194
|
};
|
|
2197
2195
|
let projectRoot = normalizePath$1(options.projectRoot ?? "");
|
|
2198
2196
|
let devEnabled = options.enabled !== false;
|
|
@@ -2273,7 +2271,6 @@ function sculpted(options = {}) {
|
|
|
2273
2271
|
registerRuntimeModuleRoutes(nextServer, {
|
|
2274
2272
|
manifestEndpoint: endpoint,
|
|
2275
2273
|
editorMetadataEndpoint,
|
|
2276
|
-
globalName: options.runtime?.globalName,
|
|
2277
2274
|
runtimeBootstrapEndpoint,
|
|
2278
2275
|
runtimeModuleEndpoint,
|
|
2279
2276
|
uiModuleEndpoint,
|
package/docs/examples.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Example Apps
|
|
2
2
|
|
|
3
|
-
Sculpted includes minimal Vite + Panda CSS apps for
|
|
4
|
-
writeback while the package
|
|
3
|
+
Sculpted includes minimal Vite + Panda CSS apps for contributors who need to manually verify
|
|
4
|
+
inspector behavior and source writeback while developing the package.
|
|
5
5
|
|
|
6
6
|
## React
|
|
7
7
|
|
|
@@ -26,5 +26,5 @@ pnpm install
|
|
|
26
26
|
pnpm dev
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
These apps intentionally include edge cases and maintainer-focused checks. Most users should start
|
|
30
|
+
with the setup examples in the main README instead.
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
# Source Syntax Adapters
|
|
2
2
|
|
|
3
|
-
Sculpted can support non-standard source syntax when
|
|
4
|
-
the original authoring
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Sourcemaps are not the writeback authority. A future fallback may use sourcemaps to explain
|
|
8
|
-
generated-code provenance, but safe writes still require an original-source parser and patchable
|
|
9
|
-
target. If the adapter cannot provide stable original ranges for a source shape, Sculpted should
|
|
10
|
-
report that target as read-only.
|
|
3
|
+
Sculpted can support non-standard source syntax when that syntax can be parsed back to stable
|
|
4
|
+
locations in the original authoring file. Unsupported source shapes are shown as read-only instead
|
|
5
|
+
of guessed.
|
|
11
6
|
|
|
12
7
|
## TSRX Support
|
|
13
8
|
|
|
@@ -30,17 +25,6 @@ export default defineConfig({
|
|
|
30
25
|
})
|
|
31
26
|
```
|
|
32
27
|
|
|
33
|
-
When a config imports more than one syntax adapter, alias the TSRX export at the import site:
|
|
34
|
-
|
|
35
|
-
```ts
|
|
36
|
-
import { sourceSyntax as tsrx } from 'sculpted/tsrx'
|
|
37
|
-
|
|
38
|
-
sculpted({
|
|
39
|
-
include: ['src/**/*.{ts,tsx,tsrx,view}'],
|
|
40
|
-
sourceSyntax: [tsrx, customViewSyntax],
|
|
41
|
-
})
|
|
42
|
-
```
|
|
43
|
-
|
|
44
28
|
The supported TSRX authoring shape is a TSRX component with a static Panda `css({ ... })` object:
|
|
45
29
|
|
|
46
30
|
```ts
|
|
@@ -56,38 +40,11 @@ export function Card() {
|
|
|
56
40
|
TSRX support covers:
|
|
57
41
|
|
|
58
42
|
- static `css({ ... })` object literal analysis;
|
|
59
|
-
-
|
|
60
|
-
- existing literal
|
|
43
|
+
- element selection in the inspector;
|
|
44
|
+
- saving edits to existing literal values in the original `.tsrx` source.
|
|
61
45
|
|
|
62
46
|
TSRX support does not cover:
|
|
63
47
|
|
|
64
|
-
- direct `data-panda-*` metadata insertion;
|
|
65
48
|
- inline source creation;
|
|
66
49
|
- add, delete, or rename operations;
|
|
67
|
-
- generated TSX or sourcemap-based writeback
|
|
68
|
-
|
|
69
|
-
## Custom Adapters
|
|
70
|
-
|
|
71
|
-
Languages that can expose original source ranges can opt into the same writeback lane with a
|
|
72
|
-
`sourceSyntax` parser adapter. The option accepts one adapter or an ordered adapter list.
|
|
73
|
-
|
|
74
|
-
```ts
|
|
75
|
-
sculpted({
|
|
76
|
-
include: ['src/**/*.view'],
|
|
77
|
-
sourceSyntax: {
|
|
78
|
-
languageId: 'my-tsx-superset',
|
|
79
|
-
kind: 'typescript',
|
|
80
|
-
isSupportedFile: (file) => file.endsWith('.view'),
|
|
81
|
-
parse({ filePath, sourceText }) {
|
|
82
|
-
return {
|
|
83
|
-
kind: 'typescript',
|
|
84
|
-
languageId: 'my-tsx-superset',
|
|
85
|
-
sourceFile: parseToTypeScriptCompatibleSourceFile(filePath, sourceText),
|
|
86
|
-
}
|
|
87
|
-
},
|
|
88
|
-
},
|
|
89
|
-
})
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
Parser adapters must expose node ranges as offsets into the original authoring source text. Use
|
|
93
|
-
read-only failures for any syntax that cannot provide stable original ranges for a source shape.
|
|
50
|
+
- generated TSX or sourcemap-based writeback.
|
package/docs/source-writeback.md
CHANGED
|
@@ -31,17 +31,12 @@ Sculpted does not edit:
|
|
|
31
31
|
|
|
32
32
|
## Safety Model
|
|
33
33
|
|
|
34
|
-
Source writes are revalidated on the dev server before writing
|
|
34
|
+
Source writes are revalidated on the dev server before writing. Sculpted only writes to files inside
|
|
35
|
+
the configured project root, re-checks the current source before saving, and rejects stale source,
|
|
36
|
+
unsupported shapes, duplicate keys, parser errors, and unsafe paths.
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
- the patcher re-reads source and validates project-root containment;
|
|
39
|
-
- stale source hashes, unsupported source shapes, duplicate keys, parse errors, and path escapes are
|
|
40
|
-
rejected;
|
|
41
|
-
- batched saves apply same-file edits against one source snapshot before writing.
|
|
42
|
-
|
|
43
|
-
The UI saves immediately after clicking Save. The writeback endpoint still supports dry-run patch
|
|
44
|
-
responses with focused diffs for tests and tooling.
|
|
38
|
+
The UI saves immediately after clicking Save. If a save cannot be applied confidently, Sculpted
|
|
39
|
+
shows the failure instead of guessing at a source edit.
|
|
45
40
|
|
|
46
41
|
## Supported Edit Example
|
|
47
42
|
|
package/docs/vite-plugin.md
CHANGED
|
@@ -68,12 +68,8 @@ type InspectorVitePluginOptions = {
|
|
|
68
68
|
readonly panda?: {
|
|
69
69
|
readonly configPath?: string
|
|
70
70
|
readonly cssImportSources?: readonly string[]
|
|
71
|
-
readonly recipeImportSources?: readonly string[]
|
|
72
|
-
readonly cssFunctionNames?: readonly string[]
|
|
73
|
-
readonly cxFunctionNames?: readonly string[]
|
|
74
71
|
}
|
|
75
72
|
readonly manifest?: {
|
|
76
|
-
readonly outFile?: string
|
|
77
73
|
readonly virtualEndpoint?: string
|
|
78
74
|
}
|
|
79
75
|
readonly metadata?: {
|
|
@@ -81,13 +77,6 @@ type InspectorVitePluginOptions = {
|
|
|
81
77
|
}
|
|
82
78
|
readonly runtime?: {
|
|
83
79
|
readonly inject?: boolean
|
|
84
|
-
readonly globalName?: string
|
|
85
|
-
}
|
|
86
|
-
readonly attributes?: {
|
|
87
|
-
readonly editId?: string
|
|
88
|
-
readonly source?: string
|
|
89
|
-
readonly jsxSource?: string
|
|
90
|
-
readonly component?: string
|
|
91
80
|
}
|
|
92
81
|
readonly sourceSyntax?: SourceSyntaxOption
|
|
93
82
|
}
|
|
@@ -169,12 +158,6 @@ sculpted({
|
|
|
169
158
|
})
|
|
170
159
|
```
|
|
171
160
|
|
|
172
|
-
### Reserved Panda Options
|
|
173
|
-
|
|
174
|
-
`panda.recipeImportSources`, `panda.cssFunctionNames`, and `panda.cxFunctionNames` are part of the
|
|
175
|
-
public option type but are not wired into the Vite plugin implementation. Recipes, patterns,
|
|
176
|
-
`cva()`, and broader function-name customization are not supported.
|
|
177
|
-
|
|
178
161
|
### `manifest.virtualEndpoint`
|
|
179
162
|
|
|
180
163
|
Defaults to `/@sculpted/manifest`.
|
|
@@ -190,10 +173,6 @@ sculpted({
|
|
|
190
173
|
})
|
|
191
174
|
```
|
|
192
175
|
|
|
193
|
-
### `manifest.outFile`
|
|
194
|
-
|
|
195
|
-
Reserved. The option is typed but not wired into the Vite plugin implementation.
|
|
196
|
-
|
|
197
176
|
### `metadata.virtualEndpoint`
|
|
198
177
|
|
|
199
178
|
Defaults to `/@sculpted/editor-metadata`.
|
|
@@ -223,46 +202,10 @@ sculpted({
|
|
|
223
202
|
})
|
|
224
203
|
```
|
|
225
204
|
|
|
226
|
-
### `runtime.globalName`
|
|
227
|
-
|
|
228
|
-
Overrides the browser global name used by the installed runtime.
|
|
229
|
-
|
|
230
|
-
```ts
|
|
231
|
-
sculpted({
|
|
232
|
-
runtime: {
|
|
233
|
-
globalName: '__mySculptedRuntime',
|
|
234
|
-
},
|
|
235
|
-
})
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### `attributes`
|
|
239
|
-
|
|
240
|
-
Overrides the DOM attributes used for inspector metadata.
|
|
241
|
-
|
|
242
|
-
Defaults:
|
|
243
|
-
|
|
244
|
-
- `editId`: `data-sculpted-edit-id`
|
|
245
|
-
- `source`: `data-sculpted-source`
|
|
246
|
-
- `jsxSource`: `data-sculpted-jsx-source`
|
|
247
|
-
- `component`: `data-sculpted-component`
|
|
248
|
-
|
|
249
|
-
Use these only when the defaults collide with app-specific tooling.
|
|
250
|
-
|
|
251
|
-
```ts
|
|
252
|
-
sculpted({
|
|
253
|
-
attributes: {
|
|
254
|
-
editId: 'data-dev-edit-id',
|
|
255
|
-
source: 'data-dev-source',
|
|
256
|
-
jsxSource: 'data-dev-jsx-source',
|
|
257
|
-
component: 'data-dev-component',
|
|
258
|
-
},
|
|
259
|
-
})
|
|
260
|
-
```
|
|
261
|
-
|
|
262
205
|
### `sourceSyntax`
|
|
263
206
|
|
|
264
|
-
Adds
|
|
265
|
-
|
|
207
|
+
Adds source parsing support for non-standard source syntax. Sculpted currently documents this for
|
|
208
|
+
the bundled TSRX adapter. See [source syntax adapters](source-syntax-adapters.md).
|
|
266
209
|
|
|
267
210
|
```ts
|
|
268
211
|
import { sourceSyntax } from 'sculpted/tsrx'
|
|
@@ -273,30 +216,8 @@ sculpted({
|
|
|
273
216
|
})
|
|
274
217
|
```
|
|
275
218
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
```ts
|
|
279
|
-
import { sourceSyntax as tsrx } from 'sculpted/tsrx'
|
|
280
|
-
|
|
281
|
-
sculpted({
|
|
282
|
-
include: ['src/**/*.{ts,tsx,tsrx,view}'],
|
|
283
|
-
sourceSyntax: [tsrx, customViewSyntax],
|
|
284
|
-
})
|
|
285
|
-
```
|
|
286
|
-
|
|
287
|
-
## Endpoint Defaults
|
|
288
|
-
|
|
289
|
-
These endpoint defaults are fixed unless an option above says otherwise:
|
|
290
|
-
|
|
291
|
-
- Manifest: `/@sculpted/manifest`
|
|
292
|
-
- Editor metadata: `/@sculpted/editor-metadata`
|
|
293
|
-
- Source writeback: `/@sculpted/writeback`
|
|
294
|
-
- Token writeback: `/@sculpted/token-writeback`
|
|
295
|
-
- Open source location: `/@sculpted/open-source`
|
|
296
|
-
- Style module route: `/@sculpted/style-module`
|
|
297
|
-
- Runtime bootstrap: `/@sculpted/runtime`
|
|
298
|
-
- Runtime module: `/@sculpted/runtime-module`
|
|
299
|
-
- UI module: `/@sculpted/ui-module`
|
|
219
|
+
## Development Routes
|
|
300
220
|
|
|
301
|
-
|
|
302
|
-
|
|
221
|
+
Sculpted reserves development-only routes under `/@sculpted/*`. The manifest and editor metadata
|
|
222
|
+
routes can be customized with `manifest.virtualEndpoint` and `metadata.virtualEndpoint`; other
|
|
223
|
+
routes are internal runtime details and should not be treated as public integration points.
|