@conduction/docusaurus-preset 2.4.0 → 2.4.1

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": "@conduction/docusaurus-preset",
3
- "version": "2.4.0",
3
+ "version": "2.4.1",
4
4
  "scripts": {
5
5
  "prepack": "node scripts/prepack-bundle-css.js"
6
6
  },
@@ -1,66 +1,86 @@
1
1
  /**
2
2
  * <MockScene />
3
3
  *
4
- * Marketing-surface composition. A SidebarMock anchors the centre,
5
- * three to five WidgetMocks float around it on a tinted cobalt-50
6
- * surface with a soft hex-network watermark. Reach for this when a
7
- * card or hero needs to show "data surfaced across the whole
8
- * workspace": one sidebar + several widgets, each carrying a real
9
- * integration icon, all lit on the same surface.
4
+ * Free-form positioning surface for assembling overlap shots out of
5
+ * WidgetMocks and SidebarMocks. The scene itself is a transparent
6
+ * stage; the caller decides the canvas size and where each item
7
+ * lands. Multiple sidebars and widgets can share a scene, can be
8
+ * different sizes, and can overlap as needed.
10
9
  *
11
- * Sibling to AppMock + WidgetMock + SidebarMock in the mock family.
12
- * AppMock paints a single product surface with chassis chrome.
13
- * WidgetMock paints a single dashboard tile. SidebarMock paints a
14
- * single detail panel. MockScene paints the overlap.
10
+ * Sibling to AppMock + WidgetMock + SidebarMock. AppMock paints a
11
+ * single product surface, WidgetMock one tile, SidebarMock one detail
12
+ * panel; MockScene paints the overlap. No background, no rotation,
13
+ * no centred-anchor pattern; each item carries its own shadow and
14
+ * lifts off whatever card the scene sits inside.
15
15
  *
16
16
  * Usage:
17
17
  *
18
18
  * <MockScene
19
- * sidebar={<SidebarMock kind="openregister-metadata" />}
20
- * widgets={[
21
- * { node: <WidgetMock kind="nextcloud-mail" />, pos: 'top-left' },
22
- * { node: <WidgetMock kind="nextcloud-files" />, pos: 'top-right' },
23
- * { node: <WidgetMock kind="openregister-activity" />, pos: 'bottom-right' },
19
+ * width={960}
20
+ * height={420}
21
+ * items={[
22
+ * { type: 'widget', kind: 'nextcloud-mail', x: 0, y: 0, size: 'sm' },
23
+ * { type: 'sidebar', kind: 'openregister-metadata', x: 220, y: 30, size: 'md' },
24
+ * { type: 'widget', kind: 'openregister-activity', x: 540, y: 80, size: 'md' },
25
+ * { type: 'sidebar', kind: 'procest-xwiki', x: 700, y: 0, size: 'sm' },
24
26
  * ]}
25
27
  * />
26
28
  *
27
- * Each widget entry is { node, pos } where `pos` selects a corner of
28
- * the stage:
29
- * 'top-left' | 'top-right' |
30
- * 'middle-left' | 'middle-right' |
31
- * 'bottom-left' | 'bottom-right'
29
+ * Each item:
30
+ * - type: 'widget' | 'sidebar'
31
+ * - kind: variant slug (see WidgetMock or SidebarMock VARIANTS)
32
+ * - x, y: pixel offset from the scene's top-left corner
33
+ * - size: 'sm' | 'md' | 'lg' (defaults to 'md' for both types)
34
+ * - z: z-index override (defaults to array order, later items
35
+ * render on top)
32
36
  *
33
- * Default rotations and offsets give each widget a slight tilt so
34
- * the composition reads as playfully arranged rather than gridded.
37
+ * Caller can also pass a `style` field on an item for inline overrides
38
+ * beyond what `size` provides (custom widths, transforms, etc.). The
39
+ * inline style is merged onto the item wrapper, so anything
40
+ * position-related on the wrapper (left, top, z-index) takes
41
+ * precedence over the caller's style.
35
42
  *
36
43
  * Props:
37
- * - sidebar: ReactNode (typically <SidebarMock />)
38
- * - widgets: Array<{node: ReactNode, pos: string}>
39
- * - compact: boolean (default false) — tighter scene for use
40
- * inside a card
44
+ * - items: Array of item descriptors (see above)
45
+ * - width: scene width in px (default 960)
46
+ * - height: scene height in px (default 420)
41
47
  * - className: string
42
48
  */
43
49
 
44
50
  import React from 'react';
45
51
  import styles from './MockScene.module.css';
46
52
  import amStyles from '../AppMock/AppMock.module.css';
53
+ import WidgetMock from '../WidgetMock/WidgetMock.jsx';
54
+ import SidebarMock from '../SidebarMock/SidebarMock.jsx';
47
55
 
48
- export default function MockScene({ sidebar, widgets = [], compact = false, className }) {
56
+ function renderItem(item) {
57
+ const size = item.size || 'md';
58
+ if (item.type === 'widget') {
59
+ return <WidgetMock kind={item.kind} size={size} />;
60
+ }
61
+ if (item.type === 'sidebar') {
62
+ return <SidebarMock kind={item.kind} size={size} />;
63
+ }
64
+ return item.node || null;
65
+ }
66
+
67
+ export default function MockScene({ items = [], width = 960, height = 420, className }) {
49
68
  return (
50
69
  <div className={[amStyles.am, styles.scene, className].filter(Boolean).join(' ')}>
51
- <div className={[styles.sceneFrame, compact && styles.compact].filter(Boolean).join(' ')}>
52
- <div className={styles.sceneStage}>
53
- {widgets.map((w, i) => (
54
- <div key={i} className={styles.sceneFloat} data-pos={w.pos || 'top-left'}>
55
- {w.node}
56
- </div>
57
- ))}
58
- {sidebar && (
59
- <div className={styles.sceneCenter}>
60
- {sidebar}
70
+ <div className={styles.sceneFrame} style={{ width, height }}>
71
+ {items.map((item, i) => {
72
+ const wrapperStyle = {
73
+ ...(item.style || {}),
74
+ left: item.x || 0,
75
+ top: item.y || 0,
76
+ zIndex: item.z != null ? item.z : i,
77
+ };
78
+ return (
79
+ <div key={i} className={styles.sceneItem} style={wrapperStyle}>
80
+ {renderItem(item)}
61
81
  </div>
62
- )}
63
- </div>
82
+ );
83
+ })}
64
84
  </div>
65
85
  </div>
66
86
  );
@@ -1,99 +1,26 @@
1
1
  /**
2
2
  * <MockScene /> styles.
3
3
  *
4
- * Marketing-surface composition. A single sidebar sits at the centre
5
- * (slightly larger than its standalone size), with three to five
6
- * widgets floating around it at staggered offsets and rotations.
7
- * Background: a tinted cobalt-50 surface with a soft hex-network
8
- * watermark, so the scene reads as "the workspace" without committing
9
- * to a specific app frame.
4
+ * Free-form positioning surface. Each item in the items[] prop renders
5
+ * inside a `.sceneItem` wrapper that's absolutely positioned via
6
+ * inline style (`left`, `top`, `z-index`). The scene itself is a
7
+ * transparent stage; layout is up to the caller.
10
8
  *
11
- * Use as the illustration on a card that talks about cross-cutting
12
- * integration ("typed data, surfaced everywhere"; "every register,
13
- * every workspace surface"). The scene is layout-only; the props pass
14
- * through fully-formed SidebarMock + WidgetMock JSX.
9
+ * No background, no padding, no rotation. The mocks themselves carry
10
+ * their own borders and shadows so they read as panels lifted off
11
+ * the surrounding card.
15
12
  */
16
13
 
17
14
  .am.scene { display: contents; }
18
15
 
19
16
  .am .sceneFrame {
20
17
  position: relative;
21
- background: var(--c-cobalt-50);
22
- border-radius: var(--radius-lg);
23
- border: 1px solid var(--c-cobalt-100);
24
- padding: var(--space-8);
25
- min-height: 360px;
26
- overflow: hidden;
27
- isolation: isolate;
18
+ /* Width and height come from inline style on the rendered element
19
+ so the caller decides the canvas size per scene. */
28
20
  }
29
21
 
30
- /* Soft hex-network watermark using radial gradients on top of cobalt-50.
31
- Cheap visual texture; no need to bring HexNetwork in for this. */
32
- .am .sceneFrame::before {
33
- content: "";
22
+ .am .sceneItem {
34
23
  position: absolute;
35
- inset: 0;
36
- background-image:
37
- radial-gradient(circle at 20% 25%, var(--c-cobalt-100) 0, transparent 35%),
38
- radial-gradient(circle at 80% 70%, var(--c-cobalt-100) 0, transparent 35%),
39
- radial-gradient(circle at 50% 90%, var(--c-cobalt-100) 0, transparent 30%);
40
- opacity: 0.5;
41
- pointer-events: none;
42
- z-index: 0;
24
+ /* `left`, `top`, and optionally `z-index` are set inline by the
25
+ component from the item's x/y/z values. */
43
26
  }
44
-
45
- /* Stage holds the sidebar at the centre and widgets at offsets.
46
- position: relative so child position: absolute resolves here. */
47
- .am .sceneStage {
48
- position: relative;
49
- display: flex;
50
- align-items: center;
51
- justify-content: center;
52
- min-height: 360px;
53
- z-index: 1;
54
- }
55
-
56
- /* Centre sidebar: anchored, slightly enlarged, drop-shadow for lift. */
57
- .am .sceneCenter {
58
- position: relative;
59
- z-index: 4;
60
- filter: drop-shadow(0 16px 32px rgba(15, 35, 75, 0.2));
61
- }
62
- .am .sceneCenter > .am > .smFrame,
63
- .am .sceneCenter > .smFrame {
64
- width: 320px;
65
- height: 440px;
66
- }
67
-
68
- /* Floating widget wrappers. Each one positions absolutely relative
69
- to .sceneStage; the data-pos attribute maps to a corner. */
70
- .am .sceneFloat {
71
- position: absolute;
72
- z-index: 2;
73
- filter: drop-shadow(0 12px 22px rgba(15, 35, 75, 0.15));
74
- transition: transform 200ms;
75
- }
76
-
77
- .am .sceneFloat[data-pos="top-left"] { top: 0; left: 0; transform: rotate(-3deg); }
78
- .am .sceneFloat[data-pos="top-right"] { top: 4%; right: 0; transform: rotate(2deg); }
79
- .am .sceneFloat[data-pos="bottom-left"] { bottom: 0; left: 6%; transform: rotate(2deg); }
80
- .am .sceneFloat[data-pos="bottom-right"] { bottom: 0; right: 0; transform: rotate(-2deg); }
81
- .am .sceneFloat[data-pos="middle-left"] { top: 40%; left: 0; transform: translateY(-50%) rotate(-2deg); }
82
- .am .sceneFloat[data-pos="middle-right"] { top: 40%; right: 0; transform: translateY(-50%) rotate(2deg); }
83
-
84
- /* Widget frames inside floats: scale down a hair and drop their own
85
- shadow so the float-level shadow does the heavy lifting. */
86
- .am .sceneFloat .wmFrame {
87
- box-shadow: none;
88
- width: 240px;
89
- }
90
-
91
- /* Tighter scenes for cards: pass `compact` to the component. */
92
- .am .sceneFrame.compact {
93
- padding: var(--space-6);
94
- min-height: 300px;
95
- }
96
- .am .sceneFrame.compact .sceneStage { min-height: 300px; }
97
- .am .sceneFrame.compact .sceneCenter > .am > .smFrame,
98
- .am .sceneFrame.compact .sceneCenter > .smFrame { width: 260px; height: 360px; }
99
- .am .sceneFrame.compact .sceneFloat .wmFrame { width: 200px; }
@@ -42,6 +42,13 @@
42
42
  *
43
43
  * Props:
44
44
  * - kind: one of VARIANTS keys (required)
45
+ * - size: 'sm' | 'md' (default) | 'lg' — standalone frame size
46
+ * (240x320 / 300x400 /
47
+ * 360x480). Ignored in
48
+ * embedded mode (the
49
+ * panel sizes itself
50
+ * to AppMock's .body
51
+ * layout)
45
52
  * - embedded: boolean (default false) — drop the standalone
46
53
  * .smFrame chrome so the
47
54
  * panel slots into
@@ -168,12 +175,12 @@ const VARIANTS = {
168
175
  },
169
176
  };
170
177
 
171
- export default function SidebarMock({ kind, embedded = false, className }) {
178
+ export default function SidebarMock({ kind, size = 'md', embedded = false, className }) {
172
179
  const variant = VARIANTS[kind];
173
180
  if (!variant) {
174
181
  return (
175
182
  <div className={[amStyles.am, styles.sm].filter(Boolean).join(' ')}>
176
- <div className={styles.smFrame}>
183
+ <div className={[styles.smFrame, styles[`sb-size-${size}`]].filter(Boolean).join(' ')}>
177
184
  <div style={{ padding: 12, color: 'var(--c-cobalt-400)', fontSize: 11 }}>Unknown sidebar: {kind}</div>
178
185
  </div>
179
186
  </div>
@@ -214,7 +221,7 @@ export default function SidebarMock({ kind, embedded = false, className }) {
214
221
 
215
222
  return (
216
223
  <div className={[amStyles.am, styles.sm, className].filter(Boolean).join(' ')}>
217
- <div className={styles.smFrame}>
224
+ <div className={[styles.smFrame, styles[`sb-size-${size}`]].filter(Boolean).join(' ')}>
218
225
  {panel}
219
226
  </div>
220
227
  </div>
@@ -28,10 +28,9 @@
28
28
  .am.sm { display: contents; }
29
29
 
30
30
  /* Standalone wrapper card. Inside, the .detail.rich panel renders
31
- identically to its embedded twin, just clipped to the smFrame box. */
31
+ identically to its embedded twin, just clipped to the smFrame box.
32
+ Width/height come from the .sb-size-* modifier on the same element. */
32
33
  .am .smFrame {
33
- width: 300px;
34
- height: 400px;
35
34
  background: white;
36
35
  border-radius: var(--radius-md);
37
36
  border: 1px solid var(--c-cobalt-100);
@@ -40,6 +39,9 @@
40
39
  display: flex;
41
40
  flex-direction: column;
42
41
  }
42
+ .am .smFrame.sb-size-sm { width: 240px; height: 320px; }
43
+ .am .smFrame.sb-size-md { width: 300px; height: 400px; }
44
+ .am .smFrame.sb-size-lg { width: 360px; height: 480px; }
43
45
 
44
46
  /* Inside .smFrame the .detail.rich child needs to fill the box; the
45
47
  default .detail width: 26% rule is meant for an embedded layout so