@pixel-point/toolcraft 0.0.3 → 0.0.6
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/package.json +1 -1
- package/scripts/prepare-pack.mjs +5 -0
- package/src/generate.mjs +13 -0
- package/src/generate.test.mjs +6 -0
- package/templates/runtime/contracts/component-contracts.test.ts +86 -8
- package/templates/runtime/contracts/component-contracts.ts +36 -8
- package/templates/runtime/contracts/decision-contracts.ts +2 -2
- package/templates/runtime/export/export.test.ts +65 -0
- package/templates/runtime/export/export.ts +54 -1
- package/templates/runtime/react/canvas-shell.test.tsx +7 -7
- package/templates/runtime/react/controls-panel.test.tsx +323 -6
- package/templates/runtime/react/controls-panel.tsx +349 -24
- package/templates/runtime/react/settings-transfer.test.ts +6 -0
- package/templates/runtime/react/settings-transfer.ts +28 -2
- package/templates/runtime/react/timeline-panel.test.tsx +69 -0
- package/templates/runtime/react/timeline-panel.tsx +98 -10
- package/templates/runtime/react/toolbar-panel.test.tsx +6 -6
- package/templates/runtime/react/toolcraft-app.integration.test.tsx +2 -2
- package/templates/runtime/schema/canvas-aspect-ratio-presets.ts +50 -0
- package/templates/runtime/schema/define-toolcraft.test.ts +122 -2
- package/templates/runtime/schema/define-toolcraft.ts +197 -6
- package/templates/runtime/schema/keyframe-capability.test.ts +7 -0
- package/templates/runtime/schema/keyframe-capability.ts +2 -2
- package/templates/runtime/schema/runtime-targets.ts +6 -0
- package/templates/runtime/schema/types.ts +23 -1
- package/templates/runtime/state/canvas-zoom.ts +1 -1
- package/templates/runtime/state/create-template-state.test.ts +9 -3
- package/templates/runtime/state/reducer.test.ts +135 -2
- package/templates/runtime/state/reducer.ts +236 -12
- package/templates/runtime/state/types.ts +1 -0
- package/templates/starter/AGENTS.md +6 -4
- package/templates/starter/docs/toolcraft/README.md +1 -1
- package/templates/starter/docs/toolcraft/acceptance-testing.md +4 -2
- package/templates/starter/docs/toolcraft/assembly-workflow.md +13 -4
- package/templates/starter/docs/toolcraft/component-rules.md +24 -5
- package/templates/starter/docs/toolcraft/performance.md +5 -0
- package/templates/starter/docs/toolcraft/renderer-technique.md +1 -1
- package/templates/starter/docs/toolcraft/schema-reference.md +53 -9
- package/templates/starter/gitignore +36 -0
- package/templates/starter/src/app/starter-acceptance.test.ts +678 -21
- package/templates/starter/src/app/starter-acceptance.ts +357 -4
- package/templates/ui/components/control-layout/index.tsx +4 -4
- package/templates/ui/components/controls/file-drop/file-drop-control.tsx +101 -18
- package/templates/ui/components/controls/font-picker/font-picker-control.tsx +1 -1
- package/templates/ui/components/controls/range-slider/range-slider-value.ts +4 -1
- package/templates/ui/components/controls/slider/slider-value.ts +48 -5
- package/templates/ui/components/primitives/editable-slider-value-label.tsx +6 -1
|
@@ -17,19 +17,62 @@ export function formatSliderValue(value: number, step: number): string {
|
|
|
17
17
|
return String(rounded);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
const compactSliderValueUnits = new Set([
|
|
21
|
+
"%",
|
|
22
|
+
"°",
|
|
23
|
+
"px",
|
|
24
|
+
"em",
|
|
25
|
+
"rem",
|
|
26
|
+
"vw",
|
|
27
|
+
"vh",
|
|
28
|
+
"vmin",
|
|
29
|
+
"vmax",
|
|
30
|
+
"x",
|
|
31
|
+
"s",
|
|
32
|
+
"ms",
|
|
33
|
+
]);
|
|
34
|
+
|
|
35
|
+
function escapeRegExp(value: string): string {
|
|
36
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getSliderValueUnitSeparator(unit: string): "" | " " {
|
|
40
|
+
const normalizedUnit = unit.trim();
|
|
41
|
+
|
|
42
|
+
if (
|
|
43
|
+
normalizedUnit === "" ||
|
|
44
|
+
compactSliderValueUnits.has(normalizedUnit) ||
|
|
45
|
+
/^[^\p{Letter}\p{Number}]+$/u.test(normalizedUnit)
|
|
46
|
+
) {
|
|
47
|
+
return "";
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return " ";
|
|
51
|
+
}
|
|
52
|
+
|
|
20
53
|
export function applySliderValueLabelUnit(
|
|
21
54
|
valueLabel: string,
|
|
22
55
|
unit?: string,
|
|
23
56
|
): string {
|
|
24
|
-
|
|
57
|
+
const normalizedUnit = unit?.trim();
|
|
58
|
+
|
|
59
|
+
if (
|
|
60
|
+
!normalizedUnit ||
|
|
61
|
+
typeof parseSliderValueLabel(valueLabel) !== "number"
|
|
62
|
+
) {
|
|
25
63
|
return valueLabel;
|
|
26
64
|
}
|
|
27
65
|
|
|
28
|
-
|
|
29
|
-
|
|
66
|
+
const separator = getSliderValueUnitSeparator(normalizedUnit);
|
|
67
|
+
const unitPattern = new RegExp(
|
|
68
|
+
`(-?\\d+(?:\\.\\d+)?)(?:\\s*${escapeRegExp(normalizedUnit)})?`,
|
|
69
|
+
"g",
|
|
70
|
+
);
|
|
30
71
|
|
|
31
|
-
|
|
32
|
-
|
|
72
|
+
return valueLabel.replaceAll(
|
|
73
|
+
unitPattern,
|
|
74
|
+
(_match, value: string) => `${value}${separator}${normalizedUnit}`,
|
|
75
|
+
);
|
|
33
76
|
}
|
|
34
77
|
|
|
35
78
|
export function formatSliderValueWithUnit(
|
|
@@ -40,6 +40,7 @@ export function EditableSliderValueLabel({
|
|
|
40
40
|
const [editing, setEditing] = useState(false);
|
|
41
41
|
const editorRef = useRef<HTMLSpanElement>(null);
|
|
42
42
|
const valueLabelRef = useRef(valueLabel);
|
|
43
|
+
const isEditableValueLabel = hasEditableNumericValueLabel(valueLabel);
|
|
43
44
|
const valueTextClassName = getEditableValueTextClassName({ layout, textAlign });
|
|
44
45
|
const widestValueLabel = getWidestValueLabel(valueLabel, maxValueLabel);
|
|
45
46
|
|
|
@@ -61,7 +62,7 @@ export function EditableSliderValueLabel({
|
|
|
61
62
|
}
|
|
62
63
|
}, [editing]);
|
|
63
64
|
|
|
64
|
-
if (disabled || !onCommit) {
|
|
65
|
+
if (disabled || !onCommit || !isEditableValueLabel) {
|
|
65
66
|
const valueTextToneClassName = disabled
|
|
66
67
|
? "text-[color:color-mix(in_oklab,var(--foreground)_60%,transparent)] opacity-60"
|
|
67
68
|
: "text-[color:var(--muted-foreground)]";
|
|
@@ -323,6 +324,10 @@ function getWidestValueLabel(valueLabel: string, maxValueLabel?: string): string
|
|
|
323
324
|
return maxValueLabel;
|
|
324
325
|
}
|
|
325
326
|
|
|
327
|
+
function hasEditableNumericValueLabel(valueLabel: string): boolean {
|
|
328
|
+
return /-?\d+(?:\.\d+)?/.test(valueLabel);
|
|
329
|
+
}
|
|
330
|
+
|
|
326
331
|
function selectEditableText(node: HTMLElement): void {
|
|
327
332
|
const selection = window.getSelection();
|
|
328
333
|
|