@freelygive/canvas-utils 0.2.0-dev.6dad937b → 0.3.0-dev.3a2544d4
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 +40 -23
- package/package.json +6 -2
- package/src/components/utils_editor_note/index.jsx +49 -0
package/README.md
CHANGED
|
@@ -7,11 +7,28 @@ Canvas utility components and test helpers for Drupal Canvas projects.
|
|
|
7
7
|
Utility components are scaffolded into your project via
|
|
8
8
|
[@freelygive/npm-scaffold](https://www.npmjs.com/package/@freelygive/npm-scaffold).
|
|
9
9
|
|
|
10
|
-
| Component
|
|
11
|
-
|
|
12
|
-
| `utils_editor_note` | Editor note component
|
|
13
|
-
| `utils_slots`
|
|
14
|
-
| `utils_entity`
|
|
10
|
+
| Component | Description |
|
|
11
|
+
| ------------------- | ---------------------------------------------------------- |
|
|
12
|
+
| `utils_editor_note` | Editor note component, `isCanvasEditorMode()` detection, and `useEditorFullHeight()` hook |
|
|
13
|
+
| `utils_slots` | `getSlotChildren()` for parsing Canvas slot content |
|
|
14
|
+
| `utils_entity` | `useMainEntity()` hook for fetching the page's main entity |
|
|
15
|
+
|
|
16
|
+
### `useEditorFullHeight(enabled)`
|
|
17
|
+
|
|
18
|
+
Canvas editor mode renders components inside an iframe whose height is stretched
|
|
19
|
+
to fit content, which breaks `min-h-screen` / `h-screen` CSS. This hook reads
|
|
20
|
+
the actual browser viewport height and returns a `{ minHeight }` style object
|
|
21
|
+
set to 80% of the viewport. Returns `undefined` when not in editor mode, so CSS
|
|
22
|
+
handles it normally.
|
|
23
|
+
|
|
24
|
+
```jsx
|
|
25
|
+
import { useEditorFullHeight, isCanvasEditorMode } from '@/components/utils_editor_note';
|
|
26
|
+
|
|
27
|
+
const MyComponent = () => {
|
|
28
|
+
const editorStyle = useEditorFullHeight(isCanvasEditorMode());
|
|
29
|
+
return <div className="min-h-screen" style={editorStyle}>...</div>;
|
|
30
|
+
};
|
|
31
|
+
```
|
|
15
32
|
|
|
16
33
|
## Test Helpers
|
|
17
34
|
|
|
@@ -20,8 +37,8 @@ Built JS entry points for use in Storybook test stories.
|
|
|
20
37
|
### Simulating Canvas Slots
|
|
21
38
|
|
|
22
39
|
Canvas delivers slot content as HTML containing `<canvas-island>` custom
|
|
23
|
-
elements. In Storybook, use the canvas-slots helpers to replicate this format
|
|
24
|
-
|
|
40
|
+
elements. In Storybook, use the canvas-slots helpers to replicate this format so
|
|
41
|
+
components can be tested under realistic conditions.
|
|
25
42
|
|
|
26
43
|
```js
|
|
27
44
|
import {
|
|
@@ -52,8 +69,8 @@ export const WithCanvasSlot: Story = {
|
|
|
52
69
|
### Simulating Editor Mode
|
|
53
70
|
|
|
54
71
|
Canvas editor mode changes component behaviour (e.g. expanding all accordion
|
|
55
|
-
items for editing). Use the `withEditorMode` decorator to enable editor mode
|
|
56
|
-
|
|
72
|
+
items for editing). Use the `withEditorMode` decorator to enable editor mode for
|
|
73
|
+
the lifetime of a story:
|
|
57
74
|
|
|
58
75
|
```js
|
|
59
76
|
import { withEditorMode } from '@freelygive/canvas-utils/testing/editor-mode';
|
|
@@ -65,11 +82,11 @@ export const InEditorMode: Story = {
|
|
|
65
82
|
```
|
|
66
83
|
|
|
67
84
|
The decorator enables editor mode before the first render and cleans up on
|
|
68
|
-
unmount via `useEffect`, so state is restored even when tests are interrupted
|
|
69
|
-
|
|
85
|
+
unmount via `useEffect`, so state is restored even when tests are interrupted or
|
|
86
|
+
Storybook navigates away.
|
|
70
87
|
|
|
71
|
-
`enableEditorMode()` and `disableEditorMode()` are also exported for cases
|
|
72
|
-
|
|
88
|
+
`enableEditorMode()` and `disableEditorMode()` are also exported for cases that
|
|
89
|
+
need direct control.
|
|
73
90
|
|
|
74
91
|
## Setup
|
|
75
92
|
|
|
@@ -97,16 +114,16 @@ Running `npm install` will scaffold the utility components into
|
|
|
97
114
|
|
|
98
115
|
### canvas-slots
|
|
99
116
|
|
|
100
|
-
| Export
|
|
101
|
-
|
|
102
|
-
| `rawProp(value)`
|
|
103
|
-
| `createCanvasIsland(props)` | Creates a `<canvas-island>` HTML string from a props object
|
|
104
|
-
| `createCanvasSlot(html)`
|
|
117
|
+
| Export | Description |
|
|
118
|
+
| --------------------------- | --------------------------------------------------------------------------------- |
|
|
119
|
+
| `rawProp(value)` | Wraps a value in the `["raw", value]` tuple format used by Canvas island props |
|
|
120
|
+
| `createCanvasIsland(props)` | Creates a `<canvas-island>` HTML string from a props object |
|
|
121
|
+
| `createCanvasSlot(html)` | Creates a React element simulating a Canvas slot for `getSlotChildren()` to parse |
|
|
105
122
|
|
|
106
123
|
### editor-mode
|
|
107
124
|
|
|
108
|
-
| Export
|
|
109
|
-
|
|
110
|
-
| `withEditorMode`
|
|
111
|
-
| `enableEditorMode()`
|
|
112
|
-
| `disableEditorMode()` | Removes `window.drupalSettings.canvas`
|
|
125
|
+
| Export | Description |
|
|
126
|
+
| --------------------- | ----------------------------------------------------------------------------- |
|
|
127
|
+
| `withEditorMode` | Storybook decorator — enables editor mode before render, cleans up on unmount |
|
|
128
|
+
| `enableEditorMode()` | Sets `window.drupalSettings.canvas` to simulate Canvas editor mode |
|
|
129
|
+
| `disableEditorMode()` | Removes `window.drupalSettings.canvas` |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@freelygive/canvas-utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-dev.3a2544d4",
|
|
4
4
|
"description": "Canvas utility components and test helpers for Drupal Canvas projects.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -40,5 +40,9 @@
|
|
|
40
40
|
"tsup": "^8.0.0",
|
|
41
41
|
"typescript": "^5.0.0"
|
|
42
42
|
},
|
|
43
|
-
"license": "GPL-2.0-or-later"
|
|
43
|
+
"license": "GPL-2.0-or-later",
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "https://gitlab.com/freelygive/canvas-utils"
|
|
47
|
+
}
|
|
44
48
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Detect if we're in Canvas page editor mode
|
|
3
5
|
* Returns true when the component is being edited in the Canvas UI
|
|
@@ -24,6 +26,53 @@ export const isCanvasEditorMode = () => {
|
|
|
24
26
|
return false;
|
|
25
27
|
};
|
|
26
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Get the actual browser viewport height, even inside Canvas editor iframes.
|
|
31
|
+
* Tries window.top (same-origin), then visualViewport, then falls back to
|
|
32
|
+
* a capped window.innerHeight (max 1200px to guard against stretched iframes).
|
|
33
|
+
*/
|
|
34
|
+
const getViewportHeight = () => {
|
|
35
|
+
try {
|
|
36
|
+
if (window.top && window.top.innerHeight > 0) {
|
|
37
|
+
return window.top.innerHeight;
|
|
38
|
+
}
|
|
39
|
+
} catch {
|
|
40
|
+
// Cross-origin — fall through
|
|
41
|
+
}
|
|
42
|
+
if (window.visualViewport?.height > 0) {
|
|
43
|
+
return window.visualViewport.height;
|
|
44
|
+
}
|
|
45
|
+
return Math.min(window.innerHeight, 1200);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Hook that returns a minHeight style for full-height sections in editor mode.
|
|
50
|
+
* Canvas editor mode breaks min-h-screen / h-screen because the component
|
|
51
|
+
* renders inside an iframe whose height is stretched to fit content.
|
|
52
|
+
* We read the actual browser viewport height and apply 80% as inline style.
|
|
53
|
+
* Returns undefined when not in editor mode (let CSS handle it).
|
|
54
|
+
*/
|
|
55
|
+
export const useEditorFullHeight = (enabled) => {
|
|
56
|
+
const [minHeight, setMinHeight] = useState(undefined);
|
|
57
|
+
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (!enabled) return;
|
|
60
|
+
const update = () =>
|
|
61
|
+
setMinHeight(`${Math.round(getViewportHeight() * 0.8)}px`);
|
|
62
|
+
update();
|
|
63
|
+
// Listen on visualViewport (preferred) and window resize as fallback
|
|
64
|
+
const vv = window.visualViewport;
|
|
65
|
+
if (vv) vv.addEventListener('resize', update);
|
|
66
|
+
window.addEventListener('resize', update);
|
|
67
|
+
return () => {
|
|
68
|
+
if (vv) vv.removeEventListener('resize', update);
|
|
69
|
+
window.removeEventListener('resize', update);
|
|
70
|
+
};
|
|
71
|
+
}, [enabled]);
|
|
72
|
+
|
|
73
|
+
return enabled ? { minHeight } : undefined;
|
|
74
|
+
};
|
|
75
|
+
|
|
27
76
|
/**
|
|
28
77
|
* Editor note component for displaying messages only visible in Canvas editor mode
|
|
29
78
|
* Used to explain runtime behavior that differs from editor preview
|