@appshoteditor/shot-dsl 0.1.1 → 0.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appshoteditor/shot-dsl",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "App Shot Editor layout DSL + device-frame geometry — framework-free building blocks for composing editable App Store screenshot layouts. Intended for use via a bundler (Vite, esbuild, etc.).",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/builders.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { BackgroundJSON, ColorStop, LayerJSON, ScreenLayersJSON, Template, TemplateRole } from './types';
1
+ import type { BackgroundJSON, ColorStop, DeviceClass, LayerJSON, ScreenLayersJSON, Template, TemplateRole } from './types';
2
2
  import { CURRENT_SCHEMA_VERSION } from './types';
3
3
  import { generateLayerId } from './validate';
4
4
 
@@ -176,11 +176,13 @@ export function makeScreen(opts: {
176
176
  background?: BackgroundJSON;
177
177
  canvasWidth?: number;
178
178
  canvasHeight?: number;
179
+ deviceClass?: DeviceClass;
179
180
  }): ScreenLayersJSON {
180
181
  return {
181
182
  schemaVersion: CURRENT_SCHEMA_VERSION,
182
183
  canvasWidth: opts.canvasWidth ?? DEFAULT_CANVAS_WIDTH,
183
184
  canvasHeight: opts.canvasHeight ?? DEFAULT_CANVAS_HEIGHT,
185
+ deviceClass: opts.deviceClass,
184
186
  layers: opts.layers,
185
187
  background: opts.background
186
188
  };
package/src/compose.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { BackgroundJSON, Template } from './types';
2
2
  import { makeTextLayer, makeScreen, makeTemplate } from './builders';
3
3
  import { makeDeviceFrameLayers } from './frames';
4
- import { getDeviceFrame } from './device-frames';
4
+ import { getDeviceFrame, deviceClassForDeviceId } from './device-frames';
5
5
 
6
6
  /**
7
7
  * Editor-unit canvas dimensions for a device, by frame class — so a plan that mixes iPhone, iPad,
@@ -85,6 +85,9 @@ export function composeTemplate(plan: ComposePlan): Template {
85
85
  background: screen.background,
86
86
  canvasWidth,
87
87
  canvasHeight,
88
+ // Tag the device GROUP (multi-device) so a mixed plan lands as separate sidebar groups in
89
+ // the editor instead of relying on frame inference. Absent ⇒ editor infers it.
90
+ deviceClass: deviceClassForDeviceId(screen.deviceId) ?? undefined,
88
91
  layers: [screenshot, frame, headline]
89
92
  });
90
93
  });
@@ -1,3 +1,5 @@
1
+ import type { DeviceClass } from './types';
2
+
1
3
  // =============================================================================
2
4
  // DEVICE FRAME DEFINITIONS
3
5
  // =============================================================================
@@ -316,3 +318,16 @@ export function getDeviceFramesByPlatform(platform: DeviceFrame['platform']): De
316
318
  export function getDeviceFramesByCategory(category: DeviceFrame['category']): DeviceFrame[] {
317
319
  return deviceFrames.filter((d) => d.category === category);
318
320
  }
321
+
322
+ /**
323
+ * Map a device-frame id to its device GROUP (multi-device), using the frame's platform + category.
324
+ * Returns null for an unknown id. Kept in sync with the app's `device-groups.ts` mapping.
325
+ */
326
+ export function deviceClassForDeviceId(deviceId: string): DeviceClass | null {
327
+ const frame = getDeviceFrame(deviceId);
328
+ if (!frame) return null;
329
+ if (frame.platform === 'ios') return frame.category === 'tablet' ? 'ipad_13' : 'iphone_6_9';
330
+ if (frame.platform === 'android') return 'android_phone';
331
+ if (frame.platform === 'macos' || frame.platform === 'windows') return 'macbook';
332
+ return null;
333
+ }
package/src/types.ts CHANGED
@@ -48,11 +48,19 @@ export interface BackgroundJSON {
48
48
  };
49
49
  }
50
50
 
51
+ /**
52
+ * Device GROUP a screen belongs to (multi-device). Mirrors the app's `db.ts` union so a composed
53
+ * template can tag each screen and the editor buckets it into the right sidebar group on import.
54
+ */
55
+ export type DeviceClass = 'iphone_6_9' | 'ipad_13' | 'android_phone' | 'macbook';
56
+
51
57
  /** One screen (canvas) of a design. */
52
58
  export interface ScreenLayersJSON {
53
59
  schemaVersion: number;
54
60
  canvasWidth?: number;
55
61
  canvasHeight?: number;
62
+ /** Device group (multi-device); optional/additive — absent ⇒ the editor infers it. */
63
+ deviceClass?: DeviceClass;
56
64
  layers: LayerJSON[];
57
65
  background?: BackgroundJSON;
58
66
  }