@orangesk/orange-design-system 2.0.0-beta.38 → 2.0.0-beta.39
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/build/components/Carousel/style.css +1 -1
- package/build/components/Carousel/style.css.map +1 -1
- package/build/components/CarouselPromotions/style.css +1 -1
- package/build/components/CarouselPromotions/style.css.map +1 -1
- package/build/components/Footer/style.css +1 -1
- package/build/components/Footer/style.css.map +1 -1
- package/build/components/Grid/style.css +1 -1
- package/build/components/Grid/style.css.map +1 -1
- package/build/components/Preview/style.css +1 -1
- package/build/components/Preview/style.css.map +1 -1
- package/build/components/index.js +1 -1
- package/build/components/index.js.map +1 -1
- package/build/components/tsconfig.tsbuildinfo +1 -1
- package/build/components/types/src/components/Preview/PreviewGenerator.d.ts +2 -0
- package/build/lib/base.css +1 -1
- package/build/lib/base.css.map +1 -1
- package/build/lib/components.css +1 -1
- package/build/lib/components.css.map +1 -1
- package/build/lib/footer.css +1 -1
- package/build/lib/footer.css.map +1 -1
- package/build/lib/scripts.js +1 -1
- package/build/lib/scripts.js.map +1 -1
- package/build/lib/style.css +1 -1
- package/build/lib/style.css.map +1 -1
- package/build/lib/utilities.css +1 -1
- package/build/lib/utilities.css.map +1 -1
- package/build/search-index.json +426 -0
- package/package.json +11 -11
- package/src/components/Carousel/styles/mixins.scss +4 -0
- package/src/components/Dropdown/Dropdown.static.ts +2 -1
- package/src/components/Grid/styles/mixins.scss +42 -16
- package/src/components/Preview/PreviewGenerator.tsx +258 -2
- package/src/components/Preview/styles/style.scss +49 -0
- package/src/styles/typography/config.scss +14 -14
- package/src/styles/utilities/horizontal-scroll.scss +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orangesk/orange-design-system",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.39",
|
|
4
4
|
"private": false,
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.x"
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"@mdx-js/loader": "^3.1.1",
|
|
57
57
|
"@mdx-js/react": "^3.1.1",
|
|
58
58
|
"@next/mdx": "16.2.1",
|
|
59
|
-
"@orangesk/accessible-autocomplete": "3.2.
|
|
59
|
+
"@orangesk/accessible-autocomplete": "3.2.2",
|
|
60
60
|
"@popperjs/core": "^2.11.8",
|
|
61
61
|
"@types/mdx": "^2.0.13",
|
|
62
62
|
"a11y-dialog": "^8.1.5",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"rehype-slug": "^6.0.0",
|
|
81
81
|
"remark-gemoji": "^8.0.0",
|
|
82
82
|
"remark-gfm": "^4.0.1",
|
|
83
|
-
"swiper": "12.1.
|
|
83
|
+
"swiper": "12.1.3",
|
|
84
84
|
"tabbable": "^6.4.0",
|
|
85
85
|
"unescape-html": "^1.1.0",
|
|
86
86
|
"wnumb": "^1.2.0"
|
|
@@ -99,7 +99,7 @@
|
|
|
99
99
|
"@rollup/plugin-terser": "1.0.0",
|
|
100
100
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
101
101
|
"@rollup/plugin-url": "^8.0.2",
|
|
102
|
-
"@rollup/rollup-darwin-arm64": "^4.60.
|
|
102
|
+
"@rollup/rollup-darwin-arm64": "^4.60.1",
|
|
103
103
|
"@testing-library/dom": "^10.4.1",
|
|
104
104
|
"@testing-library/jest-dom": "^6.9.1",
|
|
105
105
|
"@testing-library/react": "^16.3.2",
|
|
@@ -109,11 +109,11 @@
|
|
|
109
109
|
"@types/react-dom": "19.2.3",
|
|
110
110
|
"@types/wnumb": "^1.2.3",
|
|
111
111
|
"@vitejs/plugin-react": "6.0.1",
|
|
112
|
-
"@vitest/browser": "^4.1.
|
|
113
|
-
"@vitest/browser-playwright": "^4.1.
|
|
114
|
-
"@vitest/coverage-v8": "^4.1.
|
|
115
|
-
"@vitest/ui": "^4.1.
|
|
116
|
-
"canvas": "^3.2.
|
|
112
|
+
"@vitest/browser": "^4.1.2",
|
|
113
|
+
"@vitest/browser-playwright": "^4.1.2",
|
|
114
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
115
|
+
"@vitest/ui": "^4.1.2",
|
|
116
|
+
"canvas": "^3.2.3",
|
|
117
117
|
"fs-extra": "^11.3.4",
|
|
118
118
|
"glob": "13.0.6",
|
|
119
119
|
"html-validate": "10.11.2",
|
|
@@ -123,14 +123,14 @@
|
|
|
123
123
|
"lint-staged": "16.4.0",
|
|
124
124
|
"playwright": "^1.58.2",
|
|
125
125
|
"prettier": "^3.8.1",
|
|
126
|
-
"rollup": "^4.60.
|
|
126
|
+
"rollup": "^4.60.1",
|
|
127
127
|
"rollup-plugin-copy": "^3.5.0",
|
|
128
128
|
"rollup-plugin-dts": "^6.4.1",
|
|
129
129
|
"rollup-plugin-postcss": "^4.0.2",
|
|
130
130
|
"sass": "^1.98.0",
|
|
131
131
|
"svg-sprite": "^2.0.4",
|
|
132
132
|
"typescript": "6.0.2",
|
|
133
|
-
"vitest": "^4.1.
|
|
133
|
+
"vitest": "^4.1.2",
|
|
134
134
|
"vitest-axe": "^0.1.0",
|
|
135
135
|
"vitest-browser-react": "^2.1.0"
|
|
136
136
|
},
|
|
@@ -187,7 +187,8 @@ export default class Dropdown {
|
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
destroy() {
|
|
190
|
-
this.trigger.removeEventListener("click", this.handleVisibility);
|
|
190
|
+
this.trigger.removeEventListener("click", this.handleVisibility, true);
|
|
191
|
+
this.hide();
|
|
191
192
|
this.instance.destroy();
|
|
192
193
|
(this.element as any).ODS_Dropdown = null;
|
|
193
194
|
window.onresize = null;
|
|
@@ -23,16 +23,30 @@
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
@mixin grid-column-gap($size: "default") {
|
|
27
|
-
$gap: map.get(
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
@mixin grid-column-gap($size: "default", $column-gap: config.$column-gap) {
|
|
27
|
+
$gap: map.get($column-gap, $size);
|
|
28
|
+
|
|
29
|
+
@if ($size == "default" or $size == "small") {
|
|
30
|
+
@if ($size == "default") {
|
|
31
|
+
margin-left: -$gap;
|
|
32
|
+
margin-right: -$gap;
|
|
33
|
+
} @else {
|
|
34
|
+
margin-left: -$gap !important;
|
|
35
|
+
margin-right: -$gap !important;
|
|
36
|
+
}
|
|
37
|
+
} @else {
|
|
38
|
+
@include breakpoint.get("md") {
|
|
39
|
+
margin-left: -$gap !important;
|
|
40
|
+
margin-right: -$gap !important;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
30
43
|
}
|
|
31
44
|
|
|
32
|
-
@mixin grid-column-gap-responsive(
|
|
33
|
-
$
|
|
34
|
-
|
|
35
|
-
|
|
45
|
+
@mixin grid-column-gap-responsive(
|
|
46
|
+
$size: "default",
|
|
47
|
+
$column-gap: config.$column-gap
|
|
48
|
+
) {
|
|
49
|
+
@include grid-column-gap($size, $column-gap);
|
|
36
50
|
}
|
|
37
51
|
|
|
38
52
|
@mixin grid-with-equal-height-content(
|
|
@@ -75,16 +89,28 @@
|
|
|
75
89
|
max-width: 100%;
|
|
76
90
|
}
|
|
77
91
|
|
|
78
|
-
@mixin grid-col-column-gap($size: "default") {
|
|
79
|
-
$gap: map.get(
|
|
80
|
-
|
|
81
|
-
|
|
92
|
+
@mixin grid-col-column-gap($size: "default", $column-gap: config.$column-gap) {
|
|
93
|
+
$gap: map.get($column-gap, $size);
|
|
94
|
+
|
|
95
|
+
@if ($size == "default") {
|
|
96
|
+
padding-left: $gap;
|
|
97
|
+
padding-right: $gap;
|
|
98
|
+
} @else if ($size == "small") {
|
|
99
|
+
padding-left: $gap !important;
|
|
100
|
+
padding-right: $gap !important;
|
|
101
|
+
} @else {
|
|
102
|
+
@include breakpoint.get("md") {
|
|
103
|
+
padding-left: $gap !important;
|
|
104
|
+
padding-right: $gap !important;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
82
107
|
}
|
|
83
108
|
|
|
84
|
-
@mixin grid-col-column-gap-responsive(
|
|
85
|
-
$
|
|
86
|
-
|
|
87
|
-
|
|
109
|
+
@mixin grid-col-column-gap-responsive(
|
|
110
|
+
$size: "default",
|
|
111
|
+
$column-gap: config.$column-gap
|
|
112
|
+
) {
|
|
113
|
+
@include grid-col-column-gap($size, $column-gap);
|
|
88
114
|
}
|
|
89
115
|
|
|
90
116
|
@mixin column-size($width: config.$grid-base, $grid-base: config.$grid-base) {
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import cx from "classnames";
|
|
4
|
-
import React, {
|
|
4
|
+
import React, {
|
|
5
|
+
FunctionComponent,
|
|
6
|
+
ReactNode,
|
|
7
|
+
useEffect,
|
|
8
|
+
useId,
|
|
9
|
+
useRef,
|
|
10
|
+
useState,
|
|
11
|
+
} from "react";
|
|
12
|
+
import { createPortal } from "react-dom";
|
|
5
13
|
import reactElementToJSXString from "react-element-to-jsx-string";
|
|
14
|
+
import breakpoints from "@/styles/export/breakpoint";
|
|
6
15
|
import { Button } from "../Button";
|
|
7
16
|
import { Card } from "../Card";
|
|
8
17
|
import { Dropdown, DropdownItem } from "../Dropdown";
|
|
@@ -85,6 +94,184 @@ interface PreviewRenderContext {
|
|
|
85
94
|
isDarkMode: boolean;
|
|
86
95
|
}
|
|
87
96
|
|
|
97
|
+
interface PreviewBreakpoint {
|
|
98
|
+
key: string;
|
|
99
|
+
label: string;
|
|
100
|
+
width: number | null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const PREVIEW_BREAKPOINTS: PreviewBreakpoint[] = [
|
|
104
|
+
{ key: "auto", label: "Auto", width: null },
|
|
105
|
+
...Object.entries(breakpoints).map(([key, value]) => {
|
|
106
|
+
const tokenWidth = Number.parseInt(value, 10);
|
|
107
|
+
// `xs` is 0 in tokens (mobile-first min-width), but preview needs a real viewport size.
|
|
108
|
+
const width = key === "xs" ? 320 : tokenWidth;
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
key,
|
|
112
|
+
label: `${key.toUpperCase()} (${width}px)`,
|
|
113
|
+
width,
|
|
114
|
+
};
|
|
115
|
+
}),
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
const IFRAME_VIEWPORT_GUTTER = 16;
|
|
119
|
+
|
|
120
|
+
const getScreenLikeMinHeight = (width: number | null): number => {
|
|
121
|
+
if (width === null) {
|
|
122
|
+
return 1;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (width <= 480) {
|
|
126
|
+
return 700;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (width <= 768) {
|
|
130
|
+
return 640;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return 560;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
interface PreviewViewportFrameProps {
|
|
137
|
+
children: ReactNode;
|
|
138
|
+
className?: string;
|
|
139
|
+
minHeight?: number;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const PreviewViewportFrame: React.FC<PreviewViewportFrameProps> = ({
|
|
143
|
+
children,
|
|
144
|
+
className,
|
|
145
|
+
minHeight = 1,
|
|
146
|
+
}) => {
|
|
147
|
+
const iframeRef = useRef<HTMLIFrameElement | null>(null);
|
|
148
|
+
const [iframeRoot, setIframeRoot] = useState<HTMLElement | null>(null);
|
|
149
|
+
const [height, setHeight] = useState(1);
|
|
150
|
+
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
const iframe = iframeRef.current;
|
|
153
|
+
if (!iframe) return;
|
|
154
|
+
|
|
155
|
+
const doc = iframe.contentDocument;
|
|
156
|
+
if (!doc) return;
|
|
157
|
+
|
|
158
|
+
doc.open();
|
|
159
|
+
doc.write(
|
|
160
|
+
`<!doctype html><html><head></head><body><div id="preview-iframe-root"></div></body></html>`,
|
|
161
|
+
);
|
|
162
|
+
doc.close();
|
|
163
|
+
|
|
164
|
+
// Mirror parent styles so components inside iframe have the same look.
|
|
165
|
+
const stylesToClone = document.querySelectorAll(
|
|
166
|
+
'link[rel="stylesheet"], style',
|
|
167
|
+
);
|
|
168
|
+
stylesToClone.forEach((styleNode) => {
|
|
169
|
+
const clonedNode = styleNode.cloneNode(true);
|
|
170
|
+
doc.head.appendChild(clonedNode);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
doc.body.style.margin = "0";
|
|
174
|
+
doc.body.style.padding = "0";
|
|
175
|
+
doc.body.style.background = "transparent";
|
|
176
|
+
doc.body.style.overflow = "visible";
|
|
177
|
+
doc.documentElement.style.margin = "0";
|
|
178
|
+
doc.documentElement.style.padding = "0";
|
|
179
|
+
doc.documentElement.style.overflow = "visible";
|
|
180
|
+
|
|
181
|
+
iframe.setAttribute("scrolling", "no");
|
|
182
|
+
|
|
183
|
+
const root = doc.getElementById("preview-iframe-root");
|
|
184
|
+
if (!root) return;
|
|
185
|
+
|
|
186
|
+
root.style.width = "100%";
|
|
187
|
+
root.style.minHeight = "1px";
|
|
188
|
+
root.style.boxSizing = "border-box";
|
|
189
|
+
root.style.paddingInline = `${IFRAME_VIEWPORT_GUTTER}px`;
|
|
190
|
+
root.style.overflow = "visible";
|
|
191
|
+
setIframeRoot(root);
|
|
192
|
+
}, []);
|
|
193
|
+
|
|
194
|
+
useEffect(() => {
|
|
195
|
+
if (!iframeRoot) return;
|
|
196
|
+
|
|
197
|
+
const doc = iframeRoot.ownerDocument;
|
|
198
|
+
const frameWindow = doc.defaultView;
|
|
199
|
+
|
|
200
|
+
const updateHeight = () => {
|
|
201
|
+
const rootRect = iframeRoot.getBoundingClientRect();
|
|
202
|
+
|
|
203
|
+
// Include absolutely positioned descendants that may not contribute to
|
|
204
|
+
// scrollHeight/offsetHeight (e.g. sliders/popovers in docs previews).
|
|
205
|
+
let maxDescendantBottom = rootRect.bottom;
|
|
206
|
+
iframeRoot.querySelectorAll("*").forEach((node) => {
|
|
207
|
+
const nodeRect = node.getBoundingClientRect();
|
|
208
|
+
if (nodeRect.bottom > maxDescendantBottom) {
|
|
209
|
+
maxDescendantBottom = nodeRect.bottom;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
const nextHeight = Math.max(
|
|
214
|
+
Math.ceil(iframeRoot.getBoundingClientRect().height),
|
|
215
|
+
iframeRoot.scrollHeight,
|
|
216
|
+
Math.ceil(maxDescendantBottom - rootRect.top),
|
|
217
|
+
minHeight,
|
|
218
|
+
1,
|
|
219
|
+
);
|
|
220
|
+
// Update only when there is a meaningful delta to avoid feedback loops.
|
|
221
|
+
setHeight((prevHeight) =>
|
|
222
|
+
Math.abs(prevHeight - nextHeight) <= 1 ? prevHeight : nextHeight,
|
|
223
|
+
);
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
updateHeight();
|
|
227
|
+
|
|
228
|
+
const rafId = frameWindow?.requestAnimationFrame(updateHeight);
|
|
229
|
+
const timeoutId = frameWindow?.setTimeout(updateHeight, 100);
|
|
230
|
+
const resizeObserver =
|
|
231
|
+
typeof ResizeObserver !== "undefined"
|
|
232
|
+
? new ResizeObserver(updateHeight)
|
|
233
|
+
: null;
|
|
234
|
+
resizeObserver?.observe(iframeRoot);
|
|
235
|
+
|
|
236
|
+
const mutationObserver =
|
|
237
|
+
typeof MutationObserver !== "undefined"
|
|
238
|
+
? new MutationObserver(updateHeight)
|
|
239
|
+
: null;
|
|
240
|
+
mutationObserver?.observe(iframeRoot, {
|
|
241
|
+
subtree: true,
|
|
242
|
+
childList: true,
|
|
243
|
+
attributes: true,
|
|
244
|
+
characterData: true,
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
frameWindow?.addEventListener("resize", updateHeight);
|
|
248
|
+
|
|
249
|
+
return () => {
|
|
250
|
+
if (typeof rafId === "number" && frameWindow) {
|
|
251
|
+
frameWindow.cancelAnimationFrame(rafId);
|
|
252
|
+
}
|
|
253
|
+
if (typeof timeoutId === "number" && frameWindow) {
|
|
254
|
+
frameWindow.clearTimeout(timeoutId);
|
|
255
|
+
}
|
|
256
|
+
resizeObserver?.disconnect();
|
|
257
|
+
mutationObserver?.disconnect();
|
|
258
|
+
frameWindow?.removeEventListener("resize", updateHeight);
|
|
259
|
+
};
|
|
260
|
+
}, [children, iframeRoot, minHeight]);
|
|
261
|
+
|
|
262
|
+
return (
|
|
263
|
+
<>
|
|
264
|
+
<iframe
|
|
265
|
+
ref={iframeRef}
|
|
266
|
+
title="Preview viewport"
|
|
267
|
+
className={cx("previewViewportFrame", className)}
|
|
268
|
+
style={{ height }}
|
|
269
|
+
/>
|
|
270
|
+
{iframeRoot && createPortal(children, iframeRoot)}
|
|
271
|
+
</>
|
|
272
|
+
);
|
|
273
|
+
};
|
|
274
|
+
|
|
88
275
|
interface PreviewProps {
|
|
89
276
|
isDark?: boolean;
|
|
90
277
|
bgTheme?: string | boolean;
|
|
@@ -99,6 +286,8 @@ interface PreviewProps {
|
|
|
99
286
|
hasCodePreview?: boolean;
|
|
100
287
|
html?: string;
|
|
101
288
|
jsxCode?: string; // Pre-generated JSX string (from server component)
|
|
289
|
+
disableBreakpoints?: boolean;
|
|
290
|
+
showBreakpointControls?: boolean;
|
|
102
291
|
[key: string]: any;
|
|
103
292
|
}
|
|
104
293
|
|
|
@@ -158,6 +347,8 @@ const PreviewGenerator: FunctionComponent<PreviewProps> = ({
|
|
|
158
347
|
html,
|
|
159
348
|
jsxCode,
|
|
160
349
|
isDark = false,
|
|
350
|
+
disableBreakpoints = false,
|
|
351
|
+
showBreakpointControls = true,
|
|
161
352
|
...other
|
|
162
353
|
}) => {
|
|
163
354
|
const [isCodeShown, setIsCodeShown] = useState(false);
|
|
@@ -165,6 +356,10 @@ const PreviewGenerator: FunctionComponent<PreviewProps> = ({
|
|
|
165
356
|
const [isDarkMode, setIsDarkMode] = useState(isDark);
|
|
166
357
|
// Ensure unique dropdown id per Preview instance to avoid id collisions (SSR-safe)
|
|
167
358
|
const backgroundDropdownId = `background-select-${useId()}`;
|
|
359
|
+
const breakpointDropdownId = `breakpoint-select-${useId()}`;
|
|
360
|
+
const [previewBreakpoint, setPreviewBreakpoint] = useState<PreviewBreakpoint>(
|
|
361
|
+
PREVIEW_BREAKPOINTS[0],
|
|
362
|
+
);
|
|
168
363
|
const [previewBackground, setPreviewBackground] = useState<PreviewBackground>(
|
|
169
364
|
() => {
|
|
170
365
|
if (bgThemeColors && typeof bgTheme === "string") {
|
|
@@ -218,6 +413,10 @@ const PreviewGenerator: FunctionComponent<PreviewProps> = ({
|
|
|
218
413
|
setIsDarkMode(!isDarkMode);
|
|
219
414
|
}
|
|
220
415
|
|
|
416
|
+
function handlePreviewBreakpoint(previewBreakpoint: PreviewBreakpoint) {
|
|
417
|
+
setPreviewBreakpoint(previewBreakpoint);
|
|
418
|
+
}
|
|
419
|
+
|
|
221
420
|
const themeClass = isDarkMode ? "is-dark" : "is-light";
|
|
222
421
|
const bgClass = getBgClassFromName(previewBackground.label);
|
|
223
422
|
|
|
@@ -274,6 +473,29 @@ const PreviewGenerator: FunctionComponent<PreviewProps> = ({
|
|
|
274
473
|
}
|
|
275
474
|
}
|
|
276
475
|
|
|
476
|
+
if (showBreakpointControls && !disableBreakpoints) {
|
|
477
|
+
actions.push(
|
|
478
|
+
<Dropdown
|
|
479
|
+
key="breakpoint-select"
|
|
480
|
+
id={breakpointDropdownId}
|
|
481
|
+
button={{
|
|
482
|
+
children: `Viewport: ${previewBreakpoint.label}`,
|
|
483
|
+
iconName: "chevron-down",
|
|
484
|
+
type: "ghost",
|
|
485
|
+
}}
|
|
486
|
+
>
|
|
487
|
+
{PREVIEW_BREAKPOINTS.map((option) => (
|
|
488
|
+
<DropdownItem
|
|
489
|
+
key={option.key}
|
|
490
|
+
onClick={() => handlePreviewBreakpoint(option)}
|
|
491
|
+
>
|
|
492
|
+
{option.label}
|
|
493
|
+
</DropdownItem>
|
|
494
|
+
))}
|
|
495
|
+
</Dropdown>,
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
|
|
277
499
|
if (hasCodePreview) {
|
|
278
500
|
actions.push(
|
|
279
501
|
<Button key="code-toggle" onClick={handleToggleCode} type="ghost">
|
|
@@ -369,11 +591,45 @@ const PreviewGenerator: FunctionComponent<PreviewProps> = ({
|
|
|
369
591
|
// Use toCode for HTML rendering
|
|
370
592
|
const codeForHTML = toCode;
|
|
371
593
|
|
|
594
|
+
const previewViewportWidth = disableBreakpoints
|
|
595
|
+
? null
|
|
596
|
+
: previewBreakpoint.width;
|
|
597
|
+
const previewViewportMinHeight = getScreenLikeMinHeight(previewViewportWidth);
|
|
598
|
+
const shouldUseIframeViewport = previewViewportWidth !== null;
|
|
599
|
+
|
|
372
600
|
return (
|
|
373
601
|
<div className={wrapperClasses}>
|
|
374
602
|
<PreviewTitleBar actions={actions} />
|
|
375
603
|
<Card className={classes} {...other}>
|
|
376
|
-
<div
|
|
604
|
+
<div
|
|
605
|
+
className={cx("previewLiveViewportArea", {
|
|
606
|
+
hasFixedViewport: shouldUseIframeViewport,
|
|
607
|
+
})}
|
|
608
|
+
>
|
|
609
|
+
<div
|
|
610
|
+
className={cx("previewLiveViewport", {
|
|
611
|
+
isAuto: previewViewportWidth === null,
|
|
612
|
+
})}
|
|
613
|
+
style={{
|
|
614
|
+
width:
|
|
615
|
+
previewViewportWidth === null
|
|
616
|
+
? "100%"
|
|
617
|
+
: `${previewViewportWidth}px`,
|
|
618
|
+
}}
|
|
619
|
+
>
|
|
620
|
+
{!shouldUseIframeViewport ? (
|
|
621
|
+
<div className="previewLive">{toRender}</div>
|
|
622
|
+
) : (
|
|
623
|
+
<PreviewViewportFrame
|
|
624
|
+
key={previewBreakpoint.key}
|
|
625
|
+
className={themeClass}
|
|
626
|
+
minHeight={previewViewportMinHeight}
|
|
627
|
+
>
|
|
628
|
+
<div className="previewLive">{toRender}</div>
|
|
629
|
+
</PreviewViewportFrame>
|
|
630
|
+
)}
|
|
631
|
+
</div>
|
|
632
|
+
</div>
|
|
377
633
|
</Card>
|
|
378
634
|
{isCodeShown && hasCodePreview && toCode && (
|
|
379
635
|
<Card className="codeExample">
|
|
@@ -56,11 +56,60 @@
|
|
|
56
56
|
overflow: visible !important;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
// Card defaults to overflow hidden; ensure preview content can escape.
|
|
60
|
+
.card.preview {
|
|
61
|
+
overflow: visible !important;
|
|
62
|
+
}
|
|
63
|
+
|
|
59
64
|
.previewLive {
|
|
60
65
|
transition: all 200ms ease-in-out;
|
|
61
66
|
overflow: visible;
|
|
62
67
|
}
|
|
63
68
|
|
|
69
|
+
.previewLiveViewportArea {
|
|
70
|
+
overflow: visible;
|
|
71
|
+
width: 100%;
|
|
72
|
+
|
|
73
|
+
&.hasFixedViewport {
|
|
74
|
+
overflow-x: auto;
|
|
75
|
+
overflow-y: visible;
|
|
76
|
+
padding: 1rem 0;
|
|
77
|
+
background: color-mix(
|
|
78
|
+
in srgb,
|
|
79
|
+
var(--color-text-default),
|
|
80
|
+
transparent 96%
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
.previewLiveViewport {
|
|
84
|
+
background: var(--color-background-primary);
|
|
85
|
+
border: 1px solid
|
|
86
|
+
color-mix(in srgb, var(--color-border-strong), transparent 25%);
|
|
87
|
+
box-shadow:
|
|
88
|
+
0 0 0 1px
|
|
89
|
+
color-mix(in srgb, var(--color-border-strong), transparent 60%),
|
|
90
|
+
0 12px 28px
|
|
91
|
+
color-mix(in srgb, var(--color-text-default), transparent 88%);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.previewLiveViewport {
|
|
97
|
+
margin: 0 auto;
|
|
98
|
+
overflow: visible;
|
|
99
|
+
|
|
100
|
+
&.isAuto {
|
|
101
|
+
width: 100%;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.previewViewportFrame {
|
|
106
|
+
width: 100%;
|
|
107
|
+
border: 0;
|
|
108
|
+
display: block;
|
|
109
|
+
background: transparent;
|
|
110
|
+
padding-top: 16px;
|
|
111
|
+
}
|
|
112
|
+
|
|
64
113
|
.selectWrapper {
|
|
65
114
|
position: relative;
|
|
66
115
|
font-family: inherit;
|
|
@@ -67,12 +67,12 @@ $body-text: (
|
|
|
67
67
|
|
|
68
68
|
$heading-base: (
|
|
69
69
|
margin-top: 0,
|
|
70
|
-
margin-bottom: space.get("large"),
|
|
70
|
+
margin-bottom: space.get("large"),
|
|
71
71
|
);
|
|
72
72
|
|
|
73
73
|
$display-base: (
|
|
74
74
|
margin-top: 0,
|
|
75
|
-
margin-bottom: space.get("large"),
|
|
75
|
+
margin-bottom: space.get("large"),
|
|
76
76
|
);
|
|
77
77
|
|
|
78
78
|
$headings: (
|
|
@@ -120,27 +120,27 @@ $headings: (
|
|
|
120
120
|
default: (
|
|
121
121
|
font-size: convert.to-rem(24px),
|
|
122
122
|
line-height: convert.to-rem(28px),
|
|
123
|
-
font-weight:
|
|
123
|
+
font-weight: 700,
|
|
124
124
|
letter-spacing: convert.to-rem(-0.6px),
|
|
125
125
|
),
|
|
126
126
|
md: (
|
|
127
127
|
font-size: convert.to-rem(28px),
|
|
128
128
|
line-height: convert.to-rem(32px),
|
|
129
|
-
font-weight:
|
|
129
|
+
font-weight: 700,
|
|
130
130
|
letter-spacing: convert.to-rem(-0.6px),
|
|
131
131
|
),
|
|
132
132
|
),
|
|
133
133
|
4: (
|
|
134
134
|
default: (
|
|
135
|
-
font-size: convert.to-rem(
|
|
136
|
-
line-height: convert.to-rem(
|
|
137
|
-
font-weight:
|
|
135
|
+
font-size: convert.to-rem(16px),
|
|
136
|
+
line-height: convert.to-rem(20px),
|
|
137
|
+
font-weight: 700,
|
|
138
138
|
letter-spacing: convert.to-rem(-0.1px),
|
|
139
139
|
),
|
|
140
140
|
md: (
|
|
141
141
|
font-size: convert.to-rem(24px),
|
|
142
142
|
line-height: convert.to-rem(28px),
|
|
143
|
-
font-weight:
|
|
143
|
+
font-weight: 700,
|
|
144
144
|
letter-spacing: convert.to-rem(-0.4px),
|
|
145
145
|
),
|
|
146
146
|
),
|
|
@@ -148,27 +148,27 @@ $headings: (
|
|
|
148
148
|
default: (
|
|
149
149
|
font-size: convert.to-rem(16px),
|
|
150
150
|
line-height: convert.to-rem(20px),
|
|
151
|
-
font-weight:
|
|
151
|
+
font-weight: 700,
|
|
152
152
|
letter-spacing: convert.to-rem(-0.1px),
|
|
153
153
|
),
|
|
154
154
|
md: (
|
|
155
155
|
font-size: convert.to-rem(18px),
|
|
156
156
|
line-height: convert.to-rem(22px),
|
|
157
|
-
font-weight:
|
|
157
|
+
font-weight: 700,
|
|
158
158
|
letter-spacing: convert.to-rem(-0.2px),
|
|
159
159
|
),
|
|
160
160
|
),
|
|
161
161
|
6: (
|
|
162
162
|
default: (
|
|
163
163
|
font-size: convert.to-rem(16px),
|
|
164
|
-
line-height: convert.to-rem(
|
|
165
|
-
font-weight:
|
|
164
|
+
line-height: convert.to-rem(20px),
|
|
165
|
+
font-weight: 700,
|
|
166
166
|
letter-spacing: convert.to-rem(-0.1px),
|
|
167
167
|
),
|
|
168
168
|
md: (
|
|
169
169
|
font-size: convert.to-rem(18px),
|
|
170
|
-
line-height: convert.to-rem(
|
|
171
|
-
font-weight:
|
|
170
|
+
line-height: convert.to-rem(22px),
|
|
171
|
+
font-weight: 700,
|
|
172
172
|
letter-spacing: convert.to-rem(-0.2px),
|
|
173
173
|
),
|
|
174
174
|
),
|