@cratis/scene.react 3.0.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  // Copyright (c) Cratis. All rights reserved.
2
2
  // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
3
 
4
- import { ColumnDefinition, Dock, DockPanel, Grid, GridUnitType, HorizontalAlignment, Orientation, RowDefinition, SceneElement, StackPanel, VerticalAlignment, Visibility, WrapPanel } from '@cratis/scene.model';
4
+ import { Canvas, ColumnDefinition, Dock, DockPanel, Grid, GridUnitType, HorizontalAlignment, Orientation, RowDefinition, SceneElement, StackPanel, VerticalAlignment, Visibility, WrapPanel } from '@cratis/scene.model';
5
5
  import { childStyle, panelStyle } from '../renderer/panelLayout';
6
6
 
7
7
  const base = {
@@ -28,6 +28,29 @@ const row = (over: Partial<RowDefinition> = {}): RowDefinition => ({ height: sta
28
28
  const column = (over: Partial<ColumnDefinition> = {}): ColumnDefinition => ({ width: star(1), minimumWidth: 0, maximumWidth: Number.POSITIVE_INFINITY, ...over });
29
29
 
30
30
  describe('when arranging a panel', () => {
31
+ it('should make a canvas the coordinate space its children are placed against', () => {
32
+ const panel: Canvas = { ...base, extent: {} };
33
+ panelStyle(panel)!.position!.should.equal('relative');
34
+ });
35
+
36
+ it('should size a canvas to its extent', () => {
37
+ const panel: Canvas = { ...base, extent: { width: 1280, height: 800 } };
38
+ const style = panelStyle(panel)!;
39
+ [style.width, style.height].should.have.members([1280, 800]);
40
+ });
41
+
42
+ it('should place a canvas child at the edges it names', () => {
43
+ const panel: Canvas = { ...base, extent: {} };
44
+ const style = childStyle(panel, child({ 'Canvas.Left': 40, 'Canvas.Top': 24 }), 0)!;
45
+ style.position!.should.equal('absolute');
46
+ [style.left, style.top].should.have.members([40, 24]);
47
+ });
48
+
49
+ it('should leave a canvas child that names no edge in flow', () => {
50
+ const panel: Canvas = { ...base, extent: {} };
51
+ (childStyle(panel, child(), 0) === undefined).should.be.true;
52
+ });
53
+
31
54
  it('should lay a stack panel out along its orientation', () => {
32
55
  const panel: StackPanel = { ...base, orientation: Orientation.Horizontal, spacing: 8 };
33
56
  panelStyle(panel)!.flexDirection!.should.equal('row');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cratis/scene.react",
3
- "version": "3.0.0",
3
+ "version": "3.2.0",
4
4
  "description": "The React renderer implementing Scene.Engine's Renderer contract against real React/DOM.",
5
5
  "keywords": [
6
6
  "cratis",
@@ -50,12 +50,12 @@
50
50
  "build-storybook": "storybook build"
51
51
  },
52
52
  "dependencies": {
53
- "@cratis/scene.engine": "3.0.0",
54
- "@cratis/scene.model": "3.0.0"
53
+ "@cratis/scene.engine": "3.2.0",
54
+ "@cratis/scene.model": "3.2.0"
55
55
  },
56
56
  "devDependencies": {
57
- "@cratis/scene.engine": "3.0.0",
58
- "@cratis/scene.model": "3.0.0",
57
+ "@cratis/scene.engine": "3.2.0",
58
+ "@cratis/scene.model": "3.2.0",
59
59
  "@storybook/addon-links": "^10.4.1",
60
60
  "@storybook/react": "^10.4.1",
61
61
  "@storybook/react-vite": "^10.4.1",
@@ -2,7 +2,7 @@
2
2
  // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
3
 
4
4
  import type { CSSProperties } from 'react';
5
- import { isDockPanel, isGrid, isStackPanel, isWrapPanel } from '@cratis/scene.engine';
5
+ import { isCanvas, isDockPanel, isGrid, isStackPanel, isWrapPanel } from '@cratis/scene.engine';
6
6
  import { Dock, GridUnitType, Orientation } from '@cratis/scene.model';
7
7
  import type { ColumnDefinition, GridLength, Panel, RowDefinition, SceneElement } from '@cratis/scene.model';
8
8
 
@@ -39,6 +39,16 @@ const number = (value: unknown): number | undefined => (typeof value === 'number
39
39
 
40
40
  /** The CSS that arranges a panel's own children. */
41
41
  export function panelStyle(panel: Panel): CSSProperties | undefined {
42
+ if (isCanvas(panel)) {
43
+ // Absolutely placed children need a positioned ancestor to be placed against, and the canvas is
44
+ // that ancestor rather than whatever happens to be above it.
45
+ return {
46
+ position: 'relative',
47
+ width: panel.extent?.width ?? undefined,
48
+ height: panel.extent?.height ?? undefined,
49
+ };
50
+ }
51
+
42
52
  if (isGrid(panel)) {
43
53
  return {
44
54
  display: 'grid',
@@ -77,6 +87,17 @@ export function panelStyle(panel: Panel): CSSProperties | undefined {
77
87
  export function childStyle(panel: Panel, child: SceneElement, index: number): CSSProperties | undefined {
78
88
  const properties = child.properties ?? {};
79
89
 
90
+ if (isCanvas(panel)) {
91
+ const left = number(properties['Canvas.Left']);
92
+ const top = number(properties['Canvas.Top']);
93
+ const right = number(properties['Canvas.Right']);
94
+ const bottom = number(properties['Canvas.Bottom']);
95
+ // A child that names no edge is not placed by the canvas at all, so it keeps whatever flow the
96
+ // renderer would otherwise have given it rather than being pinned to the origin.
97
+ if (left === undefined && top === undefined && right === undefined && bottom === undefined) return undefined;
98
+ return { position: 'absolute', left, top, right, bottom };
99
+ }
100
+
80
101
  if (isGrid(panel)) {
81
102
  const row = number(properties['Grid.Row']);
82
103
  const column = number(properties['Grid.Column']);