@atlaskit/native-embeds-common 2.2.2 → 2.2.4
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/CHANGELOG.md +14 -0
- package/dist/cjs/entry-points/initial-placeholder.compiled.css +9 -0
- package/dist/cjs/entry-points/initial-placeholder.js +89 -0
- package/dist/cjs/entry-points/native-embed-styles.js +195 -0
- package/dist/cjs/ui/index.js +1 -1
- package/dist/es2019/entry-points/initial-placeholder.compiled.css +9 -0
- package/dist/es2019/entry-points/initial-placeholder.js +77 -0
- package/dist/es2019/entry-points/native-embed-styles.js +188 -0
- package/dist/es2019/ui/index.js +1 -1
- package/dist/esm/entry-points/initial-placeholder.compiled.css +9 -0
- package/dist/esm/entry-points/initial-placeholder.js +77 -0
- package/dist/esm/entry-points/native-embed-styles.js +188 -0
- package/dist/esm/ui/index.js +1 -1
- package/dist/types/entry-points/initial-placeholder.d.ts +23 -0
- package/dist/types/entry-points/native-embed-styles.d.ts +5 -0
- package/initial-placeholder/package.json +10 -0
- package/native-embed-styles/package.json +10 -0
- package/package.json +8 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @atlaskit/native-embeds-common
|
|
2
2
|
|
|
3
|
+
## 2.2.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`9135fb9538960`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9135fb9538960) -
|
|
8
|
+
[ux] Reuse native embed placement for first-paint placeholders
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
11
|
+
## 2.2.3
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
|
|
3
17
|
## 2.2.2
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
._2rko12b0{border-radius:var(--ds-radius-small,4px)}
|
|
2
|
+
._2rkopb1k{border-radius:var(--ds-radius-xlarge,9pt)}._189ee4h9{border-width:var(--ds-border-width,1px)}
|
|
3
|
+
._1dqonqa1{border-style:solid}
|
|
4
|
+
._1h6d1l7x{border-color:var(--ds-border,#0b120e24)}
|
|
5
|
+
._18m915vq{overflow-y:hidden}
|
|
6
|
+
._1reo15vq{overflow-x:hidden}
|
|
7
|
+
._bfhkhfxm{background-color:var(--ds-surface-sunken,#f8f8f8)}
|
|
8
|
+
._p12f1osq{max-width:100%}
|
|
9
|
+
._vchhusvi{box-sizing:border-box}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/* initial-placeholder.tsx generated by @compiled/babel-plugin v0.40.0 */
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.NativeEmbedInitialPlaceholderFrame = exports.NativeEmbedInitialPlaceholder = void 0;
|
|
9
|
+
Object.defineProperty(exports, "resolveNativeEmbedInitialLayout", {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function get() {
|
|
12
|
+
return _initialLayout.resolveNativeEmbedInitialLayout;
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
require("./initial-placeholder.compiled.css");
|
|
16
|
+
var _runtime = require("@compiled/react/runtime");
|
|
17
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
18
|
+
var _react = _interopRequireDefault(require("react"));
|
|
19
|
+
var _react2 = require("@emotion/react");
|
|
20
|
+
var _initialLayout = require("./initial-layout");
|
|
21
|
+
var _nativeEmbedStyles = require("./native-embed-styles");
|
|
22
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-global-styles, @atlaskit/ui-styling-standard/use-compiled -- Native embed placement must style renderer/editor ancestor wrappers that this component does not own.
|
|
23
|
+
var placeholderFrameStyles = null;
|
|
24
|
+
var borderedPlaceholderFrameStyles = null;
|
|
25
|
+
var borderlessPlaceholderFrameStyles = null;
|
|
26
|
+
var NativeEmbedInitialPlaceholderFrame = exports.NativeEmbedInitialPlaceholderFrame = function NativeEmbedInitialPlaceholderFrame(_ref) {
|
|
27
|
+
var effectiveHeight = _ref.effectiveHeight,
|
|
28
|
+
effectiveWidth = _ref.effectiveWidth,
|
|
29
|
+
_ref$hasEmbedBorder = _ref.hasEmbedBorder,
|
|
30
|
+
hasEmbedBorder = _ref$hasEmbedBorder === void 0 ? true : _ref$hasEmbedBorder,
|
|
31
|
+
lockAspectRatio = _ref.lockAspectRatio,
|
|
32
|
+
placeholderId = _ref.placeholderId,
|
|
33
|
+
_ref$testId = _ref.testId,
|
|
34
|
+
testId = _ref$testId === void 0 ? 'native-embed-initial-placeholder' : _ref$testId;
|
|
35
|
+
var placeholderStyle = {
|
|
36
|
+
width: effectiveWidth ? "".concat(effectiveWidth, "px") : '100%',
|
|
37
|
+
height: lockAspectRatio ? 'auto' : "".concat(effectiveHeight, "px"),
|
|
38
|
+
aspectRatio: lockAspectRatio ? effectiveWidth && effectiveHeight ? "".concat(effectiveWidth, " / ").concat(effectiveHeight) : _initialLayout.NATIVE_EMBED_INITIAL_LAYOUT_FALLBACK_ASPECT_RATIO : undefined
|
|
39
|
+
};
|
|
40
|
+
return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({
|
|
41
|
+
"data-testid": testId
|
|
42
|
+
}, placeholderId && {
|
|
43
|
+
'data-ssr-placeholder': placeholderId
|
|
44
|
+
}, {
|
|
45
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- width/height/aspectRatio are dynamic ADF + manifest-derived layout values
|
|
46
|
+
style: placeholderStyle,
|
|
47
|
+
className: (0, _runtime.ax)(["_1reo15vq _18m915vq _vchhusvi _p12f1osq _bfhkhfxm", hasEmbedBorder ? "_2rkopb1k _1dqonqa1 _189ee4h9 _1h6d1l7x" : "_2rko12b0"])
|
|
48
|
+
}));
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Renders the shared native embed placeholder contract used by editor loading, renderer interim,
|
|
52
|
+
* and Confluence SSR paths. The data attributes let the same ancestor placement styles apply before
|
|
53
|
+
* the full native embed UI is available.
|
|
54
|
+
*/
|
|
55
|
+
var NativeEmbedInitialPlaceholder = exports.NativeEmbedInitialPlaceholder = function NativeEmbedInitialPlaceholder(_ref2) {
|
|
56
|
+
var _ref2$firstPaint = _ref2.firstPaint,
|
|
57
|
+
firstPaint = _ref2$firstPaint === void 0 ? false : _ref2$firstPaint,
|
|
58
|
+
manifest = _ref2.manifest,
|
|
59
|
+
parameters = _ref2.parameters,
|
|
60
|
+
placeholderId = _ref2.placeholderId,
|
|
61
|
+
testId = _ref2.testId;
|
|
62
|
+
var _resolveNativeEmbedIn = (0, _initialLayout.resolveNativeEmbedInitialLayout)({
|
|
63
|
+
manifest: manifest,
|
|
64
|
+
parameters: parameters,
|
|
65
|
+
placeholderId: placeholderId
|
|
66
|
+
}),
|
|
67
|
+
alignment = _resolveNativeEmbedIn.alignment,
|
|
68
|
+
effectiveHeight = _resolveNativeEmbedIn.effectiveHeight,
|
|
69
|
+
effectiveWidth = _resolveNativeEmbedIn.effectiveWidth,
|
|
70
|
+
hasEmbedBorder = _resolveNativeEmbedIn.hasEmbedBorder,
|
|
71
|
+
lockAspectRatio = _resolveNativeEmbedIn.lockAspectRatio,
|
|
72
|
+
resolvedPlaceholderId = _resolveNativeEmbedIn.placeholderId;
|
|
73
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
74
|
+
"data-native-embed-alignment": alignment,
|
|
75
|
+
"data-native-embed-first-paint-placeholder": firstPaint ? 'true' : undefined,
|
|
76
|
+
"data-native-embed-initial-placeholder": "true",
|
|
77
|
+
"data-native-embed-width": effectiveWidth,
|
|
78
|
+
"data-native-embed-show-border": hasEmbedBorder ? 'true' : 'false'
|
|
79
|
+
}, /*#__PURE__*/_react.default.createElement(_react2.Global, {
|
|
80
|
+
styles: _nativeEmbedStyles.nativeEmbedAlignmentStyles
|
|
81
|
+
}), /*#__PURE__*/_react.default.createElement(NativeEmbedInitialPlaceholderFrame, {
|
|
82
|
+
effectiveHeight: effectiveHeight,
|
|
83
|
+
effectiveWidth: effectiveWidth,
|
|
84
|
+
hasEmbedBorder: hasEmbedBorder,
|
|
85
|
+
lockAspectRatio: lockAspectRatio,
|
|
86
|
+
placeholderId: resolvedPlaceholderId,
|
|
87
|
+
testId: testId
|
|
88
|
+
}));
|
|
89
|
+
};
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.nativeEmbedAlignmentStyles = void 0;
|
|
7
|
+
var _react = require("@emotion/react");
|
|
8
|
+
/**
|
|
9
|
+
* Injected by the extension UI via Global; also exported for consumers who inject styles elsewhere.
|
|
10
|
+
*/
|
|
11
|
+
/* eslint-disable @repo/internal/styles/no-exported-styles, @atlaskit/design-system/no-nested-styles -- Native embed placement must target renderer/editor ancestor wrappers that the embed component does not own. */
|
|
12
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Extension container override requires :has and !important
|
|
13
|
+
|
|
14
|
+
var wrapGap = "var(--ds-space-150, 12px)";
|
|
15
|
+
var noWrapGap = "var(--ds-space-300, 24px)";
|
|
16
|
+
|
|
17
|
+
/* eslint-disable @atlaskit/ui-styling-standard/no-exported-styles, @atlaskit/ui-styling-standard/no-important-styles -- Styles injected via Global; !important overrides extension inline width */
|
|
18
|
+
var nativeEmbedAlignmentStyles = exports.nativeEmbedAlignmentStyles = (0, _react.css)({
|
|
19
|
+
// Remove margin on extension-overflow-wrapper when it contains a native embed to prevent width overflow.
|
|
20
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target overflow wrapper by data attribute
|
|
21
|
+
'.extension-overflow-wrapper:has([data-native-embed-alignment])': {
|
|
22
|
+
margin: '0 !important'
|
|
23
|
+
},
|
|
24
|
+
// The renderer sets overflow-x:auto on .ak-renderer-extension-overflow-container, which clips a
|
|
25
|
+
// pixel-resized native embed that is wider than the text column and prevents centering from
|
|
26
|
+
// working (the scroll container also becomes the reference for the 50% offset). Override to
|
|
27
|
+
// visible so the embed can break out symmetrically on both sides, exactly as images do.
|
|
28
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target overflow container by data attribute
|
|
29
|
+
'.ak-renderer-extension-overflow-container:has([data-native-embed-alignment])': {
|
|
30
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- !important string requires type cast incompatible with the CSSProperties type
|
|
31
|
+
overflowX: 'visible !important'
|
|
32
|
+
},
|
|
33
|
+
// For a center-aligned embed with an explicit pixel width, the outer .ak-renderer-extension
|
|
34
|
+
// wrapper's width is set directly as an inline style by the native embed useEffect (to override
|
|
35
|
+
// the renderer's own inline style="width:100%"). These CSS rules apply the centering transforms
|
|
36
|
+
// on that same wrapper — now that it has the exact pixel width, margin-left:50% +
|
|
37
|
+
// translateX(-50%) breaks it out symmetrically, exactly as MediaSingle does for images.
|
|
38
|
+
// max-width:100cqw prevents overflow beyond the container while still allowing
|
|
39
|
+
// the embed to break out of the narrow layout column (unlike 100% which would
|
|
40
|
+
// clamp to the ~760px parent).
|
|
41
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target renderer extension wrapper by data attribute
|
|
42
|
+
'.ak-renderer-extension:has([data-native-embed-alignment="center"]):has([data-native-embed-width])': {
|
|
43
|
+
position: 'relative',
|
|
44
|
+
// eslint-disable-next-line @atlaskit/design-system/use-tokens-space -- geometric centering offset, not a spacing value
|
|
45
|
+
marginLeft: '50%',
|
|
46
|
+
transform: 'translateX(-50%)',
|
|
47
|
+
maxWidth: '100cqw'
|
|
48
|
+
},
|
|
49
|
+
// Before the async native embed UI mounts, no effect is available to size the renderer's outer
|
|
50
|
+
// extension wrapper. Shrink-wrap it to the placeholder's persisted width so alignment and text
|
|
51
|
+
// wrapping are correct on first paint. Top-level embeds may break out to the renderer container;
|
|
52
|
+
// nested embeds clamp to their immediate layout/table/extension parent.
|
|
53
|
+
// The renderer's inner wrapper is normally an inline-size query container. Inline-size containment
|
|
54
|
+
// contributes zero intrinsic width, which collapses a fit-content extension wrapper to 0px. Turn
|
|
55
|
+
// that containment off only while an explicit-width placeholder is mounted; the native embed UI
|
|
56
|
+
// restores the normal renderer path once it loads and imperatively sizes the outer wrapper.
|
|
57
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target the renderer-owned size container by the shared placeholder marker
|
|
58
|
+
'.ak-renderer-extension-inner-wrapper:has([data-native-embed-initial-placeholder="true"][data-native-embed-width])': {
|
|
59
|
+
containerType: 'normal'
|
|
60
|
+
},
|
|
61
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target the renderer-owned wrapper by the shared native embed placeholder marker
|
|
62
|
+
'.ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width])': {
|
|
63
|
+
width: 'fit-content !important',
|
|
64
|
+
maxWidth: '100cqw'
|
|
65
|
+
},
|
|
66
|
+
// Some renderer variants omit data-top-level even for top-level extensions. Mirror the native
|
|
67
|
+
// embed runtime's DOM nesting detection instead: table cells/headers, expands, layouts, enclosing
|
|
68
|
+
// extensions, sync blocks, and panels clamp the placeholder to the immediate containing node.
|
|
69
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Mirror native embed runtime nesting ancestors before its mounting effect is available
|
|
70
|
+
'td .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), th .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), [data-node-type="expand"] .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), [data-layout-section] .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), .ak-renderer-extension .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), [data-bodied-sync-block] .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), .ak-editor-panel .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width])': {
|
|
71
|
+
maxWidth: '100%'
|
|
72
|
+
},
|
|
73
|
+
// Width: 100% when no explicit width set; fit-content when data-native-embed-width is set.
|
|
74
|
+
// Combined selectors cover both .extension-container (editor) and .ak-renderer-extension (renderer)
|
|
75
|
+
// which use different wrapper class names for the same structural element.
|
|
76
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
77
|
+
'.extension-container:has([data-native-embed-alignment]):not(:has([data-native-embed-width])), .ak-renderer-extension:has([data-native-embed-alignment]):not(:has([data-native-embed-width]))': {
|
|
78
|
+
width: '100% !important',
|
|
79
|
+
marginLeft: '0 !important',
|
|
80
|
+
marginRight: '0 !important',
|
|
81
|
+
paddingLeft: '0 !important',
|
|
82
|
+
paddingRight: '0 !important'
|
|
83
|
+
},
|
|
84
|
+
// Match editor/renderer wrapper clipping and selected-node ring to the native embed frame radius.
|
|
85
|
+
// Borderless experiences keep the smaller core wrapper radius so their iframe content is not clipped
|
|
86
|
+
// to a framed shape they do not visually own.
|
|
87
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by the resolved showBorder value
|
|
88
|
+
'.extension-container:has([data-native-embed-show-border="true"]), .ak-renderer-extension:has([data-native-embed-show-border="true"])': {
|
|
89
|
+
borderRadius: "var(--ds-radius-xlarge, 12px)"
|
|
90
|
+
},
|
|
91
|
+
// In the editor, the --native-embed-width CSS variable is set on .extension-container by the
|
|
92
|
+
// resize plugin. When the embed is nested inside another node (e.g. a table cell or expand),
|
|
93
|
+
// data-native-embed-nested is present and we use maxWidth so the embed shrinks with the parent.
|
|
94
|
+
// When the embed is top-level (not nested), we use width so it takes the exact pixel size.
|
|
95
|
+
// In the renderer, width is set directly as an inline style on .ak-renderer-extension (overriding
|
|
96
|
+
// the renderer's own inline style="width:100%"), so no CSS variable rule is needed for the renderer.
|
|
97
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target nested extension container by data attribute on the container itself
|
|
98
|
+
'.extension-container[data-native-embed-nested]:has([data-native-embed-alignment]):has([data-native-embed-width])': {
|
|
99
|
+
maxWidth: 'var(--native-embed-width) !important',
|
|
100
|
+
paddingLeft: '0 !important',
|
|
101
|
+
paddingRight: '0 !important'
|
|
102
|
+
},
|
|
103
|
+
// The second selector adds an ID-level specificity bump so this rule also wins in full-width mode
|
|
104
|
+
// (Confluence "wide" page width), where the editor applies `width: 100% !important` to
|
|
105
|
+
// `.extension-container.block` via a rule scoped under
|
|
106
|
+
// `.fabric-editor--full-width-mode:not(:has(#chromeless-editor))` with specificity (1, 3, 0).
|
|
107
|
+
// Without the second selector, the native embed's (0, 3, 0) rule loses the cascade battle.
|
|
108
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Second selector matches specificity of editor-core's full-width-mode rule; own ID won't work as our div is inside .extension-container, not an ancestor
|
|
109
|
+
'.extension-container:not([data-native-embed-nested]):has([data-native-embed-alignment]):has([data-native-embed-width]), .fabric-editor--full-width-mode:not(:has(#chromeless-editor)) .extension-container.block:not([data-native-embed-nested]):has([data-native-embed-alignment]):has([data-native-embed-width])': {
|
|
110
|
+
width: 'var(--native-embed-width) !important',
|
|
111
|
+
paddingLeft: '0 !important',
|
|
112
|
+
paddingRight: '0 !important'
|
|
113
|
+
},
|
|
114
|
+
// Layout column resizing can temporarily rebuild column content before the
|
|
115
|
+
// native embed plugin re-syncs data-native-embed-nested. Fall back to the
|
|
116
|
+
// actual layout-column DOM ancestry so an embed in a column still shrinks to
|
|
117
|
+
// the column instead of taking its stored pixel width.
|
|
118
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- DOM ancestry fallback for transient missing data-native-embed-nested
|
|
119
|
+
'.ProseMirror [data-layout-column] .extension-container:has([data-native-embed-alignment]):has([data-native-embed-width]), .fabric-editor--full-width-mode:not(:has(#chromeless-editor)) [data-layout-column] .extension-container.block:has([data-native-embed-alignment]):has([data-native-embed-width])': {
|
|
120
|
+
width: 'auto !important',
|
|
121
|
+
maxWidth: 'var(--native-embed-width) !important',
|
|
122
|
+
paddingLeft: '0 !important',
|
|
123
|
+
paddingRight: '0 !important'
|
|
124
|
+
},
|
|
125
|
+
// Override the extension wrapper's width so alignment margins take effect.
|
|
126
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
127
|
+
'.extension-container:has([data-native-embed-alignment="left"]), .ak-renderer-extension:has([data-native-embed-alignment="left"])': {
|
|
128
|
+
margin: "".concat(noWrapGap, " auto ").concat(noWrapGap, " 0 !important"),
|
|
129
|
+
overflow: 'auto'
|
|
130
|
+
},
|
|
131
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
132
|
+
'.extension-container:has([data-native-embed-alignment="center"]), .ak-renderer-extension:has([data-native-embed-alignment="center"])': {
|
|
133
|
+
margin: "".concat(noWrapGap, " 0 !important"),
|
|
134
|
+
position: 'relative',
|
|
135
|
+
left: '50%',
|
|
136
|
+
transform: 'translateX(-50%)',
|
|
137
|
+
marginLeft: '0 !important',
|
|
138
|
+
marginRight: '0 !important'
|
|
139
|
+
},
|
|
140
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
141
|
+
'.extension-container:has([data-native-embed-alignment="right"]), .ak-renderer-extension:has([data-native-embed-alignment="right"])': {
|
|
142
|
+
margin: "".concat(noWrapGap, " 0 ").concat(noWrapGap, " auto !important"),
|
|
143
|
+
overflow: 'auto'
|
|
144
|
+
},
|
|
145
|
+
// wrap-left / wrap-right: float + margin like MediaSingle so text wraps around the embed.
|
|
146
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
147
|
+
'.extension-container:has([data-native-embed-alignment="wrap-left"])': {
|
|
148
|
+
float: 'left',
|
|
149
|
+
margin: "".concat(wrapGap, " ").concat(wrapGap, " ").concat(wrapGap, " auto !important"),
|
|
150
|
+
maxWidth: "calc((var(--ak-editor-max-container-width, 100%) / 2) - ".concat(wrapGap, ")")
|
|
151
|
+
},
|
|
152
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
153
|
+
'.ak-renderer-extension:has([data-native-embed-alignment="wrap-left"])': {
|
|
154
|
+
float: 'left',
|
|
155
|
+
margin: "".concat(wrapGap, " ").concat(wrapGap, " ").concat(wrapGap, " auto !important")
|
|
156
|
+
},
|
|
157
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
158
|
+
'.extension-container:has([data-native-embed-alignment="wrap-right"])': {
|
|
159
|
+
float: 'right',
|
|
160
|
+
margin: "".concat(wrapGap, " auto ").concat(wrapGap, " ").concat(wrapGap, " !important"),
|
|
161
|
+
maxWidth: "calc((var(--ak-editor-max-container-width, 100%) / 2) - ".concat(wrapGap, ")")
|
|
162
|
+
},
|
|
163
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
164
|
+
'.ak-renderer-extension:has([data-native-embed-alignment="wrap-right"])': {
|
|
165
|
+
float: 'right',
|
|
166
|
+
margin: "".concat(wrapGap, " auto ").concat(wrapGap, " ").concat(wrapGap, " !important")
|
|
167
|
+
},
|
|
168
|
+
// Suppress the hover box-shadow on the extension container for all native embeds.
|
|
169
|
+
// Native embeds provide their own chrome so the generic extension hover ring is not appropriate.
|
|
170
|
+
// The selection ring (from .ak-editor-selected-node) is also applied as a box-shadow,
|
|
171
|
+
// and would be incorrectly hidden on hover without the :not() guard.
|
|
172
|
+
// Using :not(.ak-editor-selected-node *) avoids coupling to the intermediate DOM structure.
|
|
173
|
+
// In the renderer there is no selection ring so the :not() guard is not needed.
|
|
174
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrapper hover by data attribute
|
|
175
|
+
'.extension-container:has([data-native-embed-alignment]):not(.ak-editor-selected-node *):hover': {
|
|
176
|
+
boxShadow: 'none !important'
|
|
177
|
+
},
|
|
178
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target renderer extension wrapper hover by data attribute
|
|
179
|
+
'.ak-renderer-extension:has([data-native-embed-alignment]):hover': {
|
|
180
|
+
boxShadow: 'none !important'
|
|
181
|
+
},
|
|
182
|
+
// Suppress the selection ring (box-shadow from .ak-editor-selected-node) for database embeds.
|
|
183
|
+
// Database embeds use appearance="minimal" with no content border, so the selection ring
|
|
184
|
+
// creates a jarring visual effect around a borderless embed.
|
|
185
|
+
// The box-shadow is applied by editor-core to `.extension-container` via the selector:
|
|
186
|
+
// `.extensionView-content-wrap.ak-editor-selected-node > span > .extension-container`
|
|
187
|
+
// We target `.extension-container` directly using :has() to check for the experience attribute
|
|
188
|
+
// on the inner div, matching regardless of the intermediate DOM structure.
|
|
189
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension-container for database embeds when selected
|
|
190
|
+
'.extension-container:has([data-native-embed-experience="database"])': {
|
|
191
|
+
boxShadow: 'none !important'
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
/* eslint-enable @atlaskit/ui-styling-standard/no-exported-styles, @atlaskit/ui-styling-standard/no-important-styles */
|
package/dist/cjs/ui/index.js
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
._2rko12b0{border-radius:var(--ds-radius-small,4px)}
|
|
2
|
+
._2rkopb1k{border-radius:var(--ds-radius-xlarge,9pt)}._189ee4h9{border-width:var(--ds-border-width,1px)}
|
|
3
|
+
._1dqonqa1{border-style:solid}
|
|
4
|
+
._1h6d1l7x{border-color:var(--ds-border,#0b120e24)}
|
|
5
|
+
._18m915vq{overflow-y:hidden}
|
|
6
|
+
._1reo15vq{overflow-x:hidden}
|
|
7
|
+
._bfhkhfxm{background-color:var(--ds-surface-sunken,#f8f8f8)}
|
|
8
|
+
._p12f1osq{max-width:100%}
|
|
9
|
+
._vchhusvi{box-sizing:border-box}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* initial-placeholder.tsx generated by @compiled/babel-plugin v0.40.0 */
|
|
2
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
3
|
+
import "./initial-placeholder.compiled.css";
|
|
4
|
+
import { ax, ix } from "@compiled/react/runtime";
|
|
5
|
+
import React from 'react';
|
|
6
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-global-styles, @atlaskit/ui-styling-standard/use-compiled -- Native embed placement must style renderer/editor ancestor wrappers that this component does not own.
|
|
7
|
+
import { Global } from '@emotion/react';
|
|
8
|
+
import { NATIVE_EMBED_INITIAL_LAYOUT_FALLBACK_ASPECT_RATIO, resolveNativeEmbedInitialLayout } from './initial-layout';
|
|
9
|
+
import { nativeEmbedAlignmentStyles } from './native-embed-styles';
|
|
10
|
+
export { resolveNativeEmbedInitialLayout };
|
|
11
|
+
const placeholderFrameStyles = null;
|
|
12
|
+
const borderedPlaceholderFrameStyles = null;
|
|
13
|
+
const borderlessPlaceholderFrameStyles = null;
|
|
14
|
+
export const NativeEmbedInitialPlaceholderFrame = ({
|
|
15
|
+
effectiveHeight,
|
|
16
|
+
effectiveWidth,
|
|
17
|
+
hasEmbedBorder = true,
|
|
18
|
+
lockAspectRatio,
|
|
19
|
+
placeholderId,
|
|
20
|
+
testId = 'native-embed-initial-placeholder'
|
|
21
|
+
}) => {
|
|
22
|
+
const placeholderStyle = {
|
|
23
|
+
width: effectiveWidth ? `${effectiveWidth}px` : '100%',
|
|
24
|
+
height: lockAspectRatio ? 'auto' : `${effectiveHeight}px`,
|
|
25
|
+
aspectRatio: lockAspectRatio ? effectiveWidth && effectiveHeight ? `${effectiveWidth} / ${effectiveHeight}` : NATIVE_EMBED_INITIAL_LAYOUT_FALLBACK_ASPECT_RATIO : undefined
|
|
26
|
+
};
|
|
27
|
+
return /*#__PURE__*/React.createElement("div", _extends({
|
|
28
|
+
"data-testid": testId
|
|
29
|
+
}, placeholderId && {
|
|
30
|
+
'data-ssr-placeholder': placeholderId
|
|
31
|
+
}, {
|
|
32
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- width/height/aspectRatio are dynamic ADF + manifest-derived layout values
|
|
33
|
+
style: placeholderStyle,
|
|
34
|
+
className: ax(["_1reo15vq _18m915vq _vchhusvi _p12f1osq _bfhkhfxm", hasEmbedBorder ? "_2rkopb1k _1dqonqa1 _189ee4h9 _1h6d1l7x" : "_2rko12b0"])
|
|
35
|
+
}));
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Renders the shared native embed placeholder contract used by editor loading, renderer interim,
|
|
39
|
+
* and Confluence SSR paths. The data attributes let the same ancestor placement styles apply before
|
|
40
|
+
* the full native embed UI is available.
|
|
41
|
+
*/
|
|
42
|
+
export const NativeEmbedInitialPlaceholder = ({
|
|
43
|
+
firstPaint = false,
|
|
44
|
+
manifest,
|
|
45
|
+
parameters,
|
|
46
|
+
placeholderId,
|
|
47
|
+
testId
|
|
48
|
+
}) => {
|
|
49
|
+
const {
|
|
50
|
+
alignment,
|
|
51
|
+
effectiveHeight,
|
|
52
|
+
effectiveWidth,
|
|
53
|
+
hasEmbedBorder,
|
|
54
|
+
lockAspectRatio,
|
|
55
|
+
placeholderId: resolvedPlaceholderId
|
|
56
|
+
} = resolveNativeEmbedInitialLayout({
|
|
57
|
+
manifest,
|
|
58
|
+
parameters,
|
|
59
|
+
placeholderId
|
|
60
|
+
});
|
|
61
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
62
|
+
"data-native-embed-alignment": alignment,
|
|
63
|
+
"data-native-embed-first-paint-placeholder": firstPaint ? 'true' : undefined,
|
|
64
|
+
"data-native-embed-initial-placeholder": "true",
|
|
65
|
+
"data-native-embed-width": effectiveWidth,
|
|
66
|
+
"data-native-embed-show-border": hasEmbedBorder ? 'true' : 'false'
|
|
67
|
+
}, /*#__PURE__*/React.createElement(Global, {
|
|
68
|
+
styles: nativeEmbedAlignmentStyles
|
|
69
|
+
}), /*#__PURE__*/React.createElement(NativeEmbedInitialPlaceholderFrame, {
|
|
70
|
+
effectiveHeight: effectiveHeight,
|
|
71
|
+
effectiveWidth: effectiveWidth,
|
|
72
|
+
hasEmbedBorder: hasEmbedBorder,
|
|
73
|
+
lockAspectRatio: lockAspectRatio,
|
|
74
|
+
placeholderId: resolvedPlaceholderId,
|
|
75
|
+
testId: testId
|
|
76
|
+
}));
|
|
77
|
+
};
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Injected by the extension UI via Global; also exported for consumers who inject styles elsewhere.
|
|
3
|
+
*/
|
|
4
|
+
/* eslint-disable @repo/internal/styles/no-exported-styles, @atlaskit/design-system/no-nested-styles -- Native embed placement must target renderer/editor ancestor wrappers that the embed component does not own. */
|
|
5
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Extension container override requires :has and !important
|
|
6
|
+
import { css } from '@emotion/react';
|
|
7
|
+
const wrapGap = "var(--ds-space-150, 12px)";
|
|
8
|
+
const noWrapGap = "var(--ds-space-300, 24px)";
|
|
9
|
+
|
|
10
|
+
/* eslint-disable @atlaskit/ui-styling-standard/no-exported-styles, @atlaskit/ui-styling-standard/no-important-styles -- Styles injected via Global; !important overrides extension inline width */
|
|
11
|
+
export const nativeEmbedAlignmentStyles = css({
|
|
12
|
+
// Remove margin on extension-overflow-wrapper when it contains a native embed to prevent width overflow.
|
|
13
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target overflow wrapper by data attribute
|
|
14
|
+
'.extension-overflow-wrapper:has([data-native-embed-alignment])': {
|
|
15
|
+
margin: '0 !important'
|
|
16
|
+
},
|
|
17
|
+
// The renderer sets overflow-x:auto on .ak-renderer-extension-overflow-container, which clips a
|
|
18
|
+
// pixel-resized native embed that is wider than the text column and prevents centering from
|
|
19
|
+
// working (the scroll container also becomes the reference for the 50% offset). Override to
|
|
20
|
+
// visible so the embed can break out symmetrically on both sides, exactly as images do.
|
|
21
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target overflow container by data attribute
|
|
22
|
+
'.ak-renderer-extension-overflow-container:has([data-native-embed-alignment])': {
|
|
23
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- !important string requires type cast incompatible with the CSSProperties type
|
|
24
|
+
overflowX: 'visible !important'
|
|
25
|
+
},
|
|
26
|
+
// For a center-aligned embed with an explicit pixel width, the outer .ak-renderer-extension
|
|
27
|
+
// wrapper's width is set directly as an inline style by the native embed useEffect (to override
|
|
28
|
+
// the renderer's own inline style="width:100%"). These CSS rules apply the centering transforms
|
|
29
|
+
// on that same wrapper — now that it has the exact pixel width, margin-left:50% +
|
|
30
|
+
// translateX(-50%) breaks it out symmetrically, exactly as MediaSingle does for images.
|
|
31
|
+
// max-width:100cqw prevents overflow beyond the container while still allowing
|
|
32
|
+
// the embed to break out of the narrow layout column (unlike 100% which would
|
|
33
|
+
// clamp to the ~760px parent).
|
|
34
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target renderer extension wrapper by data attribute
|
|
35
|
+
'.ak-renderer-extension:has([data-native-embed-alignment="center"]):has([data-native-embed-width])': {
|
|
36
|
+
position: 'relative',
|
|
37
|
+
// eslint-disable-next-line @atlaskit/design-system/use-tokens-space -- geometric centering offset, not a spacing value
|
|
38
|
+
marginLeft: '50%',
|
|
39
|
+
transform: 'translateX(-50%)',
|
|
40
|
+
maxWidth: '100cqw'
|
|
41
|
+
},
|
|
42
|
+
// Before the async native embed UI mounts, no effect is available to size the renderer's outer
|
|
43
|
+
// extension wrapper. Shrink-wrap it to the placeholder's persisted width so alignment and text
|
|
44
|
+
// wrapping are correct on first paint. Top-level embeds may break out to the renderer container;
|
|
45
|
+
// nested embeds clamp to their immediate layout/table/extension parent.
|
|
46
|
+
// The renderer's inner wrapper is normally an inline-size query container. Inline-size containment
|
|
47
|
+
// contributes zero intrinsic width, which collapses a fit-content extension wrapper to 0px. Turn
|
|
48
|
+
// that containment off only while an explicit-width placeholder is mounted; the native embed UI
|
|
49
|
+
// restores the normal renderer path once it loads and imperatively sizes the outer wrapper.
|
|
50
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target the renderer-owned size container by the shared placeholder marker
|
|
51
|
+
'.ak-renderer-extension-inner-wrapper:has([data-native-embed-initial-placeholder="true"][data-native-embed-width])': {
|
|
52
|
+
containerType: 'normal'
|
|
53
|
+
},
|
|
54
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target the renderer-owned wrapper by the shared native embed placeholder marker
|
|
55
|
+
'.ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width])': {
|
|
56
|
+
width: 'fit-content !important',
|
|
57
|
+
maxWidth: '100cqw'
|
|
58
|
+
},
|
|
59
|
+
// Some renderer variants omit data-top-level even for top-level extensions. Mirror the native
|
|
60
|
+
// embed runtime's DOM nesting detection instead: table cells/headers, expands, layouts, enclosing
|
|
61
|
+
// extensions, sync blocks, and panels clamp the placeholder to the immediate containing node.
|
|
62
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Mirror native embed runtime nesting ancestors before its mounting effect is available
|
|
63
|
+
'td .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), th .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), [data-node-type="expand"] .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), [data-layout-section] .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), .ak-renderer-extension .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), [data-bodied-sync-block] .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), .ak-editor-panel .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width])': {
|
|
64
|
+
maxWidth: '100%'
|
|
65
|
+
},
|
|
66
|
+
// Width: 100% when no explicit width set; fit-content when data-native-embed-width is set.
|
|
67
|
+
// Combined selectors cover both .extension-container (editor) and .ak-renderer-extension (renderer)
|
|
68
|
+
// which use different wrapper class names for the same structural element.
|
|
69
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
70
|
+
'.extension-container:has([data-native-embed-alignment]):not(:has([data-native-embed-width])), .ak-renderer-extension:has([data-native-embed-alignment]):not(:has([data-native-embed-width]))': {
|
|
71
|
+
width: '100% !important',
|
|
72
|
+
marginLeft: '0 !important',
|
|
73
|
+
marginRight: '0 !important',
|
|
74
|
+
paddingLeft: '0 !important',
|
|
75
|
+
paddingRight: '0 !important'
|
|
76
|
+
},
|
|
77
|
+
// Match editor/renderer wrapper clipping and selected-node ring to the native embed frame radius.
|
|
78
|
+
// Borderless experiences keep the smaller core wrapper radius so their iframe content is not clipped
|
|
79
|
+
// to a framed shape they do not visually own.
|
|
80
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by the resolved showBorder value
|
|
81
|
+
'.extension-container:has([data-native-embed-show-border="true"]), .ak-renderer-extension:has([data-native-embed-show-border="true"])': {
|
|
82
|
+
borderRadius: "var(--ds-radius-xlarge, 12px)"
|
|
83
|
+
},
|
|
84
|
+
// In the editor, the --native-embed-width CSS variable is set on .extension-container by the
|
|
85
|
+
// resize plugin. When the embed is nested inside another node (e.g. a table cell or expand),
|
|
86
|
+
// data-native-embed-nested is present and we use maxWidth so the embed shrinks with the parent.
|
|
87
|
+
// When the embed is top-level (not nested), we use width so it takes the exact pixel size.
|
|
88
|
+
// In the renderer, width is set directly as an inline style on .ak-renderer-extension (overriding
|
|
89
|
+
// the renderer's own inline style="width:100%"), so no CSS variable rule is needed for the renderer.
|
|
90
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target nested extension container by data attribute on the container itself
|
|
91
|
+
'.extension-container[data-native-embed-nested]:has([data-native-embed-alignment]):has([data-native-embed-width])': {
|
|
92
|
+
maxWidth: 'var(--native-embed-width) !important',
|
|
93
|
+
paddingLeft: '0 !important',
|
|
94
|
+
paddingRight: '0 !important'
|
|
95
|
+
},
|
|
96
|
+
// The second selector adds an ID-level specificity bump so this rule also wins in full-width mode
|
|
97
|
+
// (Confluence "wide" page width), where the editor applies `width: 100% !important` to
|
|
98
|
+
// `.extension-container.block` via a rule scoped under
|
|
99
|
+
// `.fabric-editor--full-width-mode:not(:has(#chromeless-editor))` with specificity (1, 3, 0).
|
|
100
|
+
// Without the second selector, the native embed's (0, 3, 0) rule loses the cascade battle.
|
|
101
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Second selector matches specificity of editor-core's full-width-mode rule; own ID won't work as our div is inside .extension-container, not an ancestor
|
|
102
|
+
'.extension-container:not([data-native-embed-nested]):has([data-native-embed-alignment]):has([data-native-embed-width]), .fabric-editor--full-width-mode:not(:has(#chromeless-editor)) .extension-container.block:not([data-native-embed-nested]):has([data-native-embed-alignment]):has([data-native-embed-width])': {
|
|
103
|
+
width: 'var(--native-embed-width) !important',
|
|
104
|
+
paddingLeft: '0 !important',
|
|
105
|
+
paddingRight: '0 !important'
|
|
106
|
+
},
|
|
107
|
+
// Layout column resizing can temporarily rebuild column content before the
|
|
108
|
+
// native embed plugin re-syncs data-native-embed-nested. Fall back to the
|
|
109
|
+
// actual layout-column DOM ancestry so an embed in a column still shrinks to
|
|
110
|
+
// the column instead of taking its stored pixel width.
|
|
111
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- DOM ancestry fallback for transient missing data-native-embed-nested
|
|
112
|
+
'.ProseMirror [data-layout-column] .extension-container:has([data-native-embed-alignment]):has([data-native-embed-width]), .fabric-editor--full-width-mode:not(:has(#chromeless-editor)) [data-layout-column] .extension-container.block:has([data-native-embed-alignment]):has([data-native-embed-width])': {
|
|
113
|
+
width: 'auto !important',
|
|
114
|
+
maxWidth: 'var(--native-embed-width) !important',
|
|
115
|
+
paddingLeft: '0 !important',
|
|
116
|
+
paddingRight: '0 !important'
|
|
117
|
+
},
|
|
118
|
+
// Override the extension wrapper's width so alignment margins take effect.
|
|
119
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
120
|
+
'.extension-container:has([data-native-embed-alignment="left"]), .ak-renderer-extension:has([data-native-embed-alignment="left"])': {
|
|
121
|
+
margin: `${noWrapGap} auto ${noWrapGap} 0 !important`,
|
|
122
|
+
overflow: 'auto'
|
|
123
|
+
},
|
|
124
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
125
|
+
'.extension-container:has([data-native-embed-alignment="center"]), .ak-renderer-extension:has([data-native-embed-alignment="center"])': {
|
|
126
|
+
margin: `${noWrapGap} 0 !important`,
|
|
127
|
+
position: 'relative',
|
|
128
|
+
left: '50%',
|
|
129
|
+
transform: 'translateX(-50%)',
|
|
130
|
+
marginLeft: '0 !important',
|
|
131
|
+
marginRight: '0 !important'
|
|
132
|
+
},
|
|
133
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
134
|
+
'.extension-container:has([data-native-embed-alignment="right"]), .ak-renderer-extension:has([data-native-embed-alignment="right"])': {
|
|
135
|
+
margin: `${noWrapGap} 0 ${noWrapGap} auto !important`,
|
|
136
|
+
overflow: 'auto'
|
|
137
|
+
},
|
|
138
|
+
// wrap-left / wrap-right: float + margin like MediaSingle so text wraps around the embed.
|
|
139
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
140
|
+
'.extension-container:has([data-native-embed-alignment="wrap-left"])': {
|
|
141
|
+
float: 'left',
|
|
142
|
+
margin: `${wrapGap} ${wrapGap} ${wrapGap} auto !important`,
|
|
143
|
+
maxWidth: `calc((var(--ak-editor-max-container-width, 100%) / 2) - ${wrapGap})`
|
|
144
|
+
},
|
|
145
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
146
|
+
'.ak-renderer-extension:has([data-native-embed-alignment="wrap-left"])': {
|
|
147
|
+
float: 'left',
|
|
148
|
+
margin: `${wrapGap} ${wrapGap} ${wrapGap} auto !important`
|
|
149
|
+
},
|
|
150
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
151
|
+
'.extension-container:has([data-native-embed-alignment="wrap-right"])': {
|
|
152
|
+
float: 'right',
|
|
153
|
+
margin: `${wrapGap} auto ${wrapGap} ${wrapGap} !important`,
|
|
154
|
+
maxWidth: `calc((var(--ak-editor-max-container-width, 100%) / 2) - ${wrapGap})`
|
|
155
|
+
},
|
|
156
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
157
|
+
'.ak-renderer-extension:has([data-native-embed-alignment="wrap-right"])': {
|
|
158
|
+
float: 'right',
|
|
159
|
+
margin: `${wrapGap} auto ${wrapGap} ${wrapGap} !important`
|
|
160
|
+
},
|
|
161
|
+
// Suppress the hover box-shadow on the extension container for all native embeds.
|
|
162
|
+
// Native embeds provide their own chrome so the generic extension hover ring is not appropriate.
|
|
163
|
+
// The selection ring (from .ak-editor-selected-node) is also applied as a box-shadow,
|
|
164
|
+
// and would be incorrectly hidden on hover without the :not() guard.
|
|
165
|
+
// Using :not(.ak-editor-selected-node *) avoids coupling to the intermediate DOM structure.
|
|
166
|
+
// In the renderer there is no selection ring so the :not() guard is not needed.
|
|
167
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrapper hover by data attribute
|
|
168
|
+
'.extension-container:has([data-native-embed-alignment]):not(.ak-editor-selected-node *):hover': {
|
|
169
|
+
boxShadow: 'none !important'
|
|
170
|
+
},
|
|
171
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target renderer extension wrapper hover by data attribute
|
|
172
|
+
'.ak-renderer-extension:has([data-native-embed-alignment]):hover': {
|
|
173
|
+
boxShadow: 'none !important'
|
|
174
|
+
},
|
|
175
|
+
// Suppress the selection ring (box-shadow from .ak-editor-selected-node) for database embeds.
|
|
176
|
+
// Database embeds use appearance="minimal" with no content border, so the selection ring
|
|
177
|
+
// creates a jarring visual effect around a borderless embed.
|
|
178
|
+
// The box-shadow is applied by editor-core to `.extension-container` via the selector:
|
|
179
|
+
// `.extensionView-content-wrap.ak-editor-selected-node > span > .extension-container`
|
|
180
|
+
// We target `.extension-container` directly using :has() to check for the experience attribute
|
|
181
|
+
// on the inner div, matching regardless of the intermediate DOM structure.
|
|
182
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension-container for database embeds when selected
|
|
183
|
+
'.extension-container:has([data-native-embed-experience="database"])': {
|
|
184
|
+
boxShadow: 'none !important'
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
/* eslint-enable @atlaskit/ui-styling-standard/no-exported-styles, @atlaskit/ui-styling-standard/no-important-styles */
|
package/dist/es2019/ui/index.js
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
._2rko12b0{border-radius:var(--ds-radius-small,4px)}
|
|
2
|
+
._2rkopb1k{border-radius:var(--ds-radius-xlarge,9pt)}._189ee4h9{border-width:var(--ds-border-width,1px)}
|
|
3
|
+
._1dqonqa1{border-style:solid}
|
|
4
|
+
._1h6d1l7x{border-color:var(--ds-border,#0b120e24)}
|
|
5
|
+
._18m915vq{overflow-y:hidden}
|
|
6
|
+
._1reo15vq{overflow-x:hidden}
|
|
7
|
+
._bfhkhfxm{background-color:var(--ds-surface-sunken,#f8f8f8)}
|
|
8
|
+
._p12f1osq{max-width:100%}
|
|
9
|
+
._vchhusvi{box-sizing:border-box}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* initial-placeholder.tsx generated by @compiled/babel-plugin v0.40.0 */
|
|
2
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
3
|
+
import "./initial-placeholder.compiled.css";
|
|
4
|
+
import { ax, ix } from "@compiled/react/runtime";
|
|
5
|
+
import React from 'react';
|
|
6
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-global-styles, @atlaskit/ui-styling-standard/use-compiled -- Native embed placement must style renderer/editor ancestor wrappers that this component does not own.
|
|
7
|
+
import { Global } from '@emotion/react';
|
|
8
|
+
import { NATIVE_EMBED_INITIAL_LAYOUT_FALLBACK_ASPECT_RATIO, resolveNativeEmbedInitialLayout } from './initial-layout';
|
|
9
|
+
import { nativeEmbedAlignmentStyles } from './native-embed-styles';
|
|
10
|
+
export { resolveNativeEmbedInitialLayout };
|
|
11
|
+
var placeholderFrameStyles = null;
|
|
12
|
+
var borderedPlaceholderFrameStyles = null;
|
|
13
|
+
var borderlessPlaceholderFrameStyles = null;
|
|
14
|
+
export var NativeEmbedInitialPlaceholderFrame = function NativeEmbedInitialPlaceholderFrame(_ref) {
|
|
15
|
+
var effectiveHeight = _ref.effectiveHeight,
|
|
16
|
+
effectiveWidth = _ref.effectiveWidth,
|
|
17
|
+
_ref$hasEmbedBorder = _ref.hasEmbedBorder,
|
|
18
|
+
hasEmbedBorder = _ref$hasEmbedBorder === void 0 ? true : _ref$hasEmbedBorder,
|
|
19
|
+
lockAspectRatio = _ref.lockAspectRatio,
|
|
20
|
+
placeholderId = _ref.placeholderId,
|
|
21
|
+
_ref$testId = _ref.testId,
|
|
22
|
+
testId = _ref$testId === void 0 ? 'native-embed-initial-placeholder' : _ref$testId;
|
|
23
|
+
var placeholderStyle = {
|
|
24
|
+
width: effectiveWidth ? "".concat(effectiveWidth, "px") : '100%',
|
|
25
|
+
height: lockAspectRatio ? 'auto' : "".concat(effectiveHeight, "px"),
|
|
26
|
+
aspectRatio: lockAspectRatio ? effectiveWidth && effectiveHeight ? "".concat(effectiveWidth, " / ").concat(effectiveHeight) : NATIVE_EMBED_INITIAL_LAYOUT_FALLBACK_ASPECT_RATIO : undefined
|
|
27
|
+
};
|
|
28
|
+
return /*#__PURE__*/React.createElement("div", _extends({
|
|
29
|
+
"data-testid": testId
|
|
30
|
+
}, placeholderId && {
|
|
31
|
+
'data-ssr-placeholder': placeholderId
|
|
32
|
+
}, {
|
|
33
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- width/height/aspectRatio are dynamic ADF + manifest-derived layout values
|
|
34
|
+
style: placeholderStyle,
|
|
35
|
+
className: ax(["_1reo15vq _18m915vq _vchhusvi _p12f1osq _bfhkhfxm", hasEmbedBorder ? "_2rkopb1k _1dqonqa1 _189ee4h9 _1h6d1l7x" : "_2rko12b0"])
|
|
36
|
+
}));
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Renders the shared native embed placeholder contract used by editor loading, renderer interim,
|
|
40
|
+
* and Confluence SSR paths. The data attributes let the same ancestor placement styles apply before
|
|
41
|
+
* the full native embed UI is available.
|
|
42
|
+
*/
|
|
43
|
+
export var NativeEmbedInitialPlaceholder = function NativeEmbedInitialPlaceholder(_ref2) {
|
|
44
|
+
var _ref2$firstPaint = _ref2.firstPaint,
|
|
45
|
+
firstPaint = _ref2$firstPaint === void 0 ? false : _ref2$firstPaint,
|
|
46
|
+
manifest = _ref2.manifest,
|
|
47
|
+
parameters = _ref2.parameters,
|
|
48
|
+
placeholderId = _ref2.placeholderId,
|
|
49
|
+
testId = _ref2.testId;
|
|
50
|
+
var _resolveNativeEmbedIn = resolveNativeEmbedInitialLayout({
|
|
51
|
+
manifest: manifest,
|
|
52
|
+
parameters: parameters,
|
|
53
|
+
placeholderId: placeholderId
|
|
54
|
+
}),
|
|
55
|
+
alignment = _resolveNativeEmbedIn.alignment,
|
|
56
|
+
effectiveHeight = _resolveNativeEmbedIn.effectiveHeight,
|
|
57
|
+
effectiveWidth = _resolveNativeEmbedIn.effectiveWidth,
|
|
58
|
+
hasEmbedBorder = _resolveNativeEmbedIn.hasEmbedBorder,
|
|
59
|
+
lockAspectRatio = _resolveNativeEmbedIn.lockAspectRatio,
|
|
60
|
+
resolvedPlaceholderId = _resolveNativeEmbedIn.placeholderId;
|
|
61
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
62
|
+
"data-native-embed-alignment": alignment,
|
|
63
|
+
"data-native-embed-first-paint-placeholder": firstPaint ? 'true' : undefined,
|
|
64
|
+
"data-native-embed-initial-placeholder": "true",
|
|
65
|
+
"data-native-embed-width": effectiveWidth,
|
|
66
|
+
"data-native-embed-show-border": hasEmbedBorder ? 'true' : 'false'
|
|
67
|
+
}, /*#__PURE__*/React.createElement(Global, {
|
|
68
|
+
styles: nativeEmbedAlignmentStyles
|
|
69
|
+
}), /*#__PURE__*/React.createElement(NativeEmbedInitialPlaceholderFrame, {
|
|
70
|
+
effectiveHeight: effectiveHeight,
|
|
71
|
+
effectiveWidth: effectiveWidth,
|
|
72
|
+
hasEmbedBorder: hasEmbedBorder,
|
|
73
|
+
lockAspectRatio: lockAspectRatio,
|
|
74
|
+
placeholderId: resolvedPlaceholderId,
|
|
75
|
+
testId: testId
|
|
76
|
+
}));
|
|
77
|
+
};
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Injected by the extension UI via Global; also exported for consumers who inject styles elsewhere.
|
|
3
|
+
*/
|
|
4
|
+
/* eslint-disable @repo/internal/styles/no-exported-styles, @atlaskit/design-system/no-nested-styles -- Native embed placement must target renderer/editor ancestor wrappers that the embed component does not own. */
|
|
5
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Extension container override requires :has and !important
|
|
6
|
+
import { css } from '@emotion/react';
|
|
7
|
+
var wrapGap = "var(--ds-space-150, 12px)";
|
|
8
|
+
var noWrapGap = "var(--ds-space-300, 24px)";
|
|
9
|
+
|
|
10
|
+
/* eslint-disable @atlaskit/ui-styling-standard/no-exported-styles, @atlaskit/ui-styling-standard/no-important-styles -- Styles injected via Global; !important overrides extension inline width */
|
|
11
|
+
export var nativeEmbedAlignmentStyles = css({
|
|
12
|
+
// Remove margin on extension-overflow-wrapper when it contains a native embed to prevent width overflow.
|
|
13
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target overflow wrapper by data attribute
|
|
14
|
+
'.extension-overflow-wrapper:has([data-native-embed-alignment])': {
|
|
15
|
+
margin: '0 !important'
|
|
16
|
+
},
|
|
17
|
+
// The renderer sets overflow-x:auto on .ak-renderer-extension-overflow-container, which clips a
|
|
18
|
+
// pixel-resized native embed that is wider than the text column and prevents centering from
|
|
19
|
+
// working (the scroll container also becomes the reference for the 50% offset). Override to
|
|
20
|
+
// visible so the embed can break out symmetrically on both sides, exactly as images do.
|
|
21
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target overflow container by data attribute
|
|
22
|
+
'.ak-renderer-extension-overflow-container:has([data-native-embed-alignment])': {
|
|
23
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- !important string requires type cast incompatible with the CSSProperties type
|
|
24
|
+
overflowX: 'visible !important'
|
|
25
|
+
},
|
|
26
|
+
// For a center-aligned embed with an explicit pixel width, the outer .ak-renderer-extension
|
|
27
|
+
// wrapper's width is set directly as an inline style by the native embed useEffect (to override
|
|
28
|
+
// the renderer's own inline style="width:100%"). These CSS rules apply the centering transforms
|
|
29
|
+
// on that same wrapper — now that it has the exact pixel width, margin-left:50% +
|
|
30
|
+
// translateX(-50%) breaks it out symmetrically, exactly as MediaSingle does for images.
|
|
31
|
+
// max-width:100cqw prevents overflow beyond the container while still allowing
|
|
32
|
+
// the embed to break out of the narrow layout column (unlike 100% which would
|
|
33
|
+
// clamp to the ~760px parent).
|
|
34
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target renderer extension wrapper by data attribute
|
|
35
|
+
'.ak-renderer-extension:has([data-native-embed-alignment="center"]):has([data-native-embed-width])': {
|
|
36
|
+
position: 'relative',
|
|
37
|
+
// eslint-disable-next-line @atlaskit/design-system/use-tokens-space -- geometric centering offset, not a spacing value
|
|
38
|
+
marginLeft: '50%',
|
|
39
|
+
transform: 'translateX(-50%)',
|
|
40
|
+
maxWidth: '100cqw'
|
|
41
|
+
},
|
|
42
|
+
// Before the async native embed UI mounts, no effect is available to size the renderer's outer
|
|
43
|
+
// extension wrapper. Shrink-wrap it to the placeholder's persisted width so alignment and text
|
|
44
|
+
// wrapping are correct on first paint. Top-level embeds may break out to the renderer container;
|
|
45
|
+
// nested embeds clamp to their immediate layout/table/extension parent.
|
|
46
|
+
// The renderer's inner wrapper is normally an inline-size query container. Inline-size containment
|
|
47
|
+
// contributes zero intrinsic width, which collapses a fit-content extension wrapper to 0px. Turn
|
|
48
|
+
// that containment off only while an explicit-width placeholder is mounted; the native embed UI
|
|
49
|
+
// restores the normal renderer path once it loads and imperatively sizes the outer wrapper.
|
|
50
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target the renderer-owned size container by the shared placeholder marker
|
|
51
|
+
'.ak-renderer-extension-inner-wrapper:has([data-native-embed-initial-placeholder="true"][data-native-embed-width])': {
|
|
52
|
+
containerType: 'normal'
|
|
53
|
+
},
|
|
54
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target the renderer-owned wrapper by the shared native embed placeholder marker
|
|
55
|
+
'.ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width])': {
|
|
56
|
+
width: 'fit-content !important',
|
|
57
|
+
maxWidth: '100cqw'
|
|
58
|
+
},
|
|
59
|
+
// Some renderer variants omit data-top-level even for top-level extensions. Mirror the native
|
|
60
|
+
// embed runtime's DOM nesting detection instead: table cells/headers, expands, layouts, enclosing
|
|
61
|
+
// extensions, sync blocks, and panels clamp the placeholder to the immediate containing node.
|
|
62
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Mirror native embed runtime nesting ancestors before its mounting effect is available
|
|
63
|
+
'td .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), th .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), [data-node-type="expand"] .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), [data-layout-section] .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), .ak-renderer-extension .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), [data-bodied-sync-block] .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width]), .ak-editor-panel .ak-renderer-extension:has([data-native-embed-initial-placeholder="true"][data-native-embed-width])': {
|
|
64
|
+
maxWidth: '100%'
|
|
65
|
+
},
|
|
66
|
+
// Width: 100% when no explicit width set; fit-content when data-native-embed-width is set.
|
|
67
|
+
// Combined selectors cover both .extension-container (editor) and .ak-renderer-extension (renderer)
|
|
68
|
+
// which use different wrapper class names for the same structural element.
|
|
69
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
70
|
+
'.extension-container:has([data-native-embed-alignment]):not(:has([data-native-embed-width])), .ak-renderer-extension:has([data-native-embed-alignment]):not(:has([data-native-embed-width]))': {
|
|
71
|
+
width: '100% !important',
|
|
72
|
+
marginLeft: '0 !important',
|
|
73
|
+
marginRight: '0 !important',
|
|
74
|
+
paddingLeft: '0 !important',
|
|
75
|
+
paddingRight: '0 !important'
|
|
76
|
+
},
|
|
77
|
+
// Match editor/renderer wrapper clipping and selected-node ring to the native embed frame radius.
|
|
78
|
+
// Borderless experiences keep the smaller core wrapper radius so their iframe content is not clipped
|
|
79
|
+
// to a framed shape they do not visually own.
|
|
80
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by the resolved showBorder value
|
|
81
|
+
'.extension-container:has([data-native-embed-show-border="true"]), .ak-renderer-extension:has([data-native-embed-show-border="true"])': {
|
|
82
|
+
borderRadius: "var(--ds-radius-xlarge, 12px)"
|
|
83
|
+
},
|
|
84
|
+
// In the editor, the --native-embed-width CSS variable is set on .extension-container by the
|
|
85
|
+
// resize plugin. When the embed is nested inside another node (e.g. a table cell or expand),
|
|
86
|
+
// data-native-embed-nested is present and we use maxWidth so the embed shrinks with the parent.
|
|
87
|
+
// When the embed is top-level (not nested), we use width so it takes the exact pixel size.
|
|
88
|
+
// In the renderer, width is set directly as an inline style on .ak-renderer-extension (overriding
|
|
89
|
+
// the renderer's own inline style="width:100%"), so no CSS variable rule is needed for the renderer.
|
|
90
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target nested extension container by data attribute on the container itself
|
|
91
|
+
'.extension-container[data-native-embed-nested]:has([data-native-embed-alignment]):has([data-native-embed-width])': {
|
|
92
|
+
maxWidth: 'var(--native-embed-width) !important',
|
|
93
|
+
paddingLeft: '0 !important',
|
|
94
|
+
paddingRight: '0 !important'
|
|
95
|
+
},
|
|
96
|
+
// The second selector adds an ID-level specificity bump so this rule also wins in full-width mode
|
|
97
|
+
// (Confluence "wide" page width), where the editor applies `width: 100% !important` to
|
|
98
|
+
// `.extension-container.block` via a rule scoped under
|
|
99
|
+
// `.fabric-editor--full-width-mode:not(:has(#chromeless-editor))` with specificity (1, 3, 0).
|
|
100
|
+
// Without the second selector, the native embed's (0, 3, 0) rule loses the cascade battle.
|
|
101
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Second selector matches specificity of editor-core's full-width-mode rule; own ID won't work as our div is inside .extension-container, not an ancestor
|
|
102
|
+
'.extension-container:not([data-native-embed-nested]):has([data-native-embed-alignment]):has([data-native-embed-width]), .fabric-editor--full-width-mode:not(:has(#chromeless-editor)) .extension-container.block:not([data-native-embed-nested]):has([data-native-embed-alignment]):has([data-native-embed-width])': {
|
|
103
|
+
width: 'var(--native-embed-width) !important',
|
|
104
|
+
paddingLeft: '0 !important',
|
|
105
|
+
paddingRight: '0 !important'
|
|
106
|
+
},
|
|
107
|
+
// Layout column resizing can temporarily rebuild column content before the
|
|
108
|
+
// native embed plugin re-syncs data-native-embed-nested. Fall back to the
|
|
109
|
+
// actual layout-column DOM ancestry so an embed in a column still shrinks to
|
|
110
|
+
// the column instead of taking its stored pixel width.
|
|
111
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- DOM ancestry fallback for transient missing data-native-embed-nested
|
|
112
|
+
'.ProseMirror [data-layout-column] .extension-container:has([data-native-embed-alignment]):has([data-native-embed-width]), .fabric-editor--full-width-mode:not(:has(#chromeless-editor)) [data-layout-column] .extension-container.block:has([data-native-embed-alignment]):has([data-native-embed-width])': {
|
|
113
|
+
width: 'auto !important',
|
|
114
|
+
maxWidth: 'var(--native-embed-width) !important',
|
|
115
|
+
paddingLeft: '0 !important',
|
|
116
|
+
paddingRight: '0 !important'
|
|
117
|
+
},
|
|
118
|
+
// Override the extension wrapper's width so alignment margins take effect.
|
|
119
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
120
|
+
'.extension-container:has([data-native-embed-alignment="left"]), .ak-renderer-extension:has([data-native-embed-alignment="left"])': {
|
|
121
|
+
margin: "".concat(noWrapGap, " auto ").concat(noWrapGap, " 0 !important"),
|
|
122
|
+
overflow: 'auto'
|
|
123
|
+
},
|
|
124
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
125
|
+
'.extension-container:has([data-native-embed-alignment="center"]), .ak-renderer-extension:has([data-native-embed-alignment="center"])': {
|
|
126
|
+
margin: "".concat(noWrapGap, " 0 !important"),
|
|
127
|
+
position: 'relative',
|
|
128
|
+
left: '50%',
|
|
129
|
+
transform: 'translateX(-50%)',
|
|
130
|
+
marginLeft: '0 !important',
|
|
131
|
+
marginRight: '0 !important'
|
|
132
|
+
},
|
|
133
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
134
|
+
'.extension-container:has([data-native-embed-alignment="right"]), .ak-renderer-extension:has([data-native-embed-alignment="right"])': {
|
|
135
|
+
margin: "".concat(noWrapGap, " 0 ").concat(noWrapGap, " auto !important"),
|
|
136
|
+
overflow: 'auto'
|
|
137
|
+
},
|
|
138
|
+
// wrap-left / wrap-right: float + margin like MediaSingle so text wraps around the embed.
|
|
139
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
140
|
+
'.extension-container:has([data-native-embed-alignment="wrap-left"])': {
|
|
141
|
+
float: 'left',
|
|
142
|
+
margin: "".concat(wrapGap, " ").concat(wrapGap, " ").concat(wrapGap, " auto !important"),
|
|
143
|
+
maxWidth: "calc((var(--ak-editor-max-container-width, 100%) / 2) - ".concat(wrapGap, ")")
|
|
144
|
+
},
|
|
145
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
146
|
+
'.ak-renderer-extension:has([data-native-embed-alignment="wrap-left"])': {
|
|
147
|
+
float: 'left',
|
|
148
|
+
margin: "".concat(wrapGap, " ").concat(wrapGap, " ").concat(wrapGap, " auto !important")
|
|
149
|
+
},
|
|
150
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
151
|
+
'.extension-container:has([data-native-embed-alignment="wrap-right"])': {
|
|
152
|
+
float: 'right',
|
|
153
|
+
margin: "".concat(wrapGap, " auto ").concat(wrapGap, " ").concat(wrapGap, " !important"),
|
|
154
|
+
maxWidth: "calc((var(--ak-editor-max-container-width, 100%) / 2) - ".concat(wrapGap, ")")
|
|
155
|
+
},
|
|
156
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrappers by data attribute
|
|
157
|
+
'.ak-renderer-extension:has([data-native-embed-alignment="wrap-right"])': {
|
|
158
|
+
float: 'right',
|
|
159
|
+
margin: "".concat(wrapGap, " auto ").concat(wrapGap, " ").concat(wrapGap, " !important")
|
|
160
|
+
},
|
|
161
|
+
// Suppress the hover box-shadow on the extension container for all native embeds.
|
|
162
|
+
// Native embeds provide their own chrome so the generic extension hover ring is not appropriate.
|
|
163
|
+
// The selection ring (from .ak-editor-selected-node) is also applied as a box-shadow,
|
|
164
|
+
// and would be incorrectly hidden on hover without the :not() guard.
|
|
165
|
+
// Using :not(.ak-editor-selected-node *) avoids coupling to the intermediate DOM structure.
|
|
166
|
+
// In the renderer there is no selection ring so the :not() guard is not needed.
|
|
167
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension wrapper hover by data attribute
|
|
168
|
+
'.extension-container:has([data-native-embed-alignment]):not(.ak-editor-selected-node *):hover': {
|
|
169
|
+
boxShadow: 'none !important'
|
|
170
|
+
},
|
|
171
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target renderer extension wrapper hover by data attribute
|
|
172
|
+
'.ak-renderer-extension:has([data-native-embed-alignment]):hover': {
|
|
173
|
+
boxShadow: 'none !important'
|
|
174
|
+
},
|
|
175
|
+
// Suppress the selection ring (box-shadow from .ak-editor-selected-node) for database embeds.
|
|
176
|
+
// Database embeds use appearance="minimal" with no content border, so the selection ring
|
|
177
|
+
// creates a jarring visual effect around a borderless embed.
|
|
178
|
+
// The box-shadow is applied by editor-core to `.extension-container` via the selector:
|
|
179
|
+
// `.extensionView-content-wrap.ak-editor-selected-node > span > .extension-container`
|
|
180
|
+
// We target `.extension-container` directly using :has() to check for the experience attribute
|
|
181
|
+
// on the inner div, matching regardless of the intermediate DOM structure.
|
|
182
|
+
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors, @atlaskit/ui-styling-standard/no-unsafe-selectors -- Target extension-container for database embeds when selected
|
|
183
|
+
'.extension-container:has([data-native-embed-experience="database"])': {
|
|
184
|
+
boxShadow: 'none !important'
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
/* eslint-enable @atlaskit/ui-styling-standard/no-exported-styles, @atlaskit/ui-styling-standard/no-important-styles */
|
package/dist/esm/ui/index.js
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jsxRuntime classic
|
|
3
|
+
* @jsx jsx
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { resolveNativeEmbedInitialLayout, type NativeEmbedInitialLayout, type ResolveNativeEmbedInitialLayoutInput } from './initial-layout';
|
|
7
|
+
export { resolveNativeEmbedInitialLayout, type NativeEmbedInitialLayout };
|
|
8
|
+
export type NativeEmbedInitialPlaceholderFrameProps = Pick<NativeEmbedInitialLayout, 'effectiveHeight' | 'effectiveWidth' | 'lockAspectRatio'> & {
|
|
9
|
+
hasEmbedBorder?: boolean;
|
|
10
|
+
placeholderId?: string;
|
|
11
|
+
testId?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare const NativeEmbedInitialPlaceholderFrame: ({ effectiveHeight, effectiveWidth, hasEmbedBorder, lockAspectRatio, placeholderId, testId, }: NativeEmbedInitialPlaceholderFrameProps) => React.JSX.Element;
|
|
14
|
+
export type NativeEmbedInitialPlaceholderProps = ResolveNativeEmbedInitialLayoutInput & {
|
|
15
|
+
firstPaint?: boolean;
|
|
16
|
+
testId?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Renders the shared native embed placeholder contract used by editor loading, renderer interim,
|
|
20
|
+
* and Confluence SSR paths. The data attributes let the same ancestor placement styles apply before
|
|
21
|
+
* the full native embed UI is available.
|
|
22
|
+
*/
|
|
23
|
+
export declare const NativeEmbedInitialPlaceholder: ({ firstPaint, manifest, parameters, placeholderId, testId, }: NativeEmbedInitialPlaceholderProps) => React.JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atlaskit/native-embeds-common/initial-placeholder",
|
|
3
|
+
"main": "../dist/cjs/entry-points/initial-placeholder.js",
|
|
4
|
+
"module": "../dist/esm/entry-points/initial-placeholder.js",
|
|
5
|
+
"module:es2019": "../dist/es2019/entry-points/initial-placeholder.js",
|
|
6
|
+
"sideEffects": [
|
|
7
|
+
"*.compiled.css"
|
|
8
|
+
],
|
|
9
|
+
"types": "../dist/types/entry-points/initial-placeholder.d.ts"
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atlaskit/native-embeds-common/native-embed-styles",
|
|
3
|
+
"main": "../dist/cjs/entry-points/native-embed-styles.js",
|
|
4
|
+
"module": "../dist/esm/entry-points/native-embed-styles.js",
|
|
5
|
+
"module:es2019": "../dist/es2019/entry-points/native-embed-styles.js",
|
|
6
|
+
"sideEffects": [
|
|
7
|
+
"*.compiled.css"
|
|
8
|
+
],
|
|
9
|
+
"types": "../dist/types/entry-points/native-embed-styles.d.ts"
|
|
10
|
+
}
|
package/package.json
CHANGED
|
@@ -17,16 +17,17 @@
|
|
|
17
17
|
"atlaskit:src": "src/index.ts",
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@atlaskit/button": "^24.3.0",
|
|
20
|
-
"@atlaskit/editor-common": "^116.
|
|
20
|
+
"@atlaskit/editor-common": "^116.35.0",
|
|
21
21
|
"@atlaskit/editor-plugin-local-id": "^10.1.0",
|
|
22
22
|
"@atlaskit/editor-prosemirror": "^8.0.0",
|
|
23
23
|
"@atlaskit/heading": "^6.2.0",
|
|
24
|
-
"@atlaskit/icon": "^37.
|
|
25
|
-
"@atlaskit/primitives": "^
|
|
26
|
-
"@atlaskit/tokens": "^16.
|
|
24
|
+
"@atlaskit/icon": "^37.1.0",
|
|
25
|
+
"@atlaskit/primitives": "^22.1.0",
|
|
26
|
+
"@atlaskit/tokens": "^16.2.0",
|
|
27
27
|
"@atlassian/afm-i18n-platform-native-embeds-native-embeds-common": "1.7.0",
|
|
28
28
|
"@babel/runtime": "^7.0.0",
|
|
29
|
-
"@compiled/react": "^0.
|
|
29
|
+
"@compiled/react": "^0.22.2",
|
|
30
|
+
"@emotion/react": "^11.7.1"
|
|
30
31
|
},
|
|
31
32
|
"peerDependencies": {
|
|
32
33
|
"react": "^18.2.0",
|
|
@@ -36,6 +37,7 @@
|
|
|
36
37
|
"@af/integration-testing": "workspace:^",
|
|
37
38
|
"@af/visual-regression": "workspace:^",
|
|
38
39
|
"@atlaskit/ssr": "workspace:^",
|
|
40
|
+
"@atlassian/testing-library": "^0.11.0",
|
|
39
41
|
"@testing-library/react": "^16.3.0",
|
|
40
42
|
"react": "^18.2.0",
|
|
41
43
|
"react-dom": "^18.2.0",
|
|
@@ -80,7 +82,7 @@
|
|
|
80
82
|
}
|
|
81
83
|
},
|
|
82
84
|
"name": "@atlaskit/native-embeds-common",
|
|
83
|
-
"version": "2.2.
|
|
85
|
+
"version": "2.2.4",
|
|
84
86
|
"description": "A shared package for native embeds to be used across experiences and plugin",
|
|
85
87
|
"author": "Atlassian Pty Ltd",
|
|
86
88
|
"license": "Apache-2.0",
|