@atlaskit/top-layer 0.1.2 → 0.1.5

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 CHANGED
@@ -1,5 +1,26 @@
1
1
  # @atlaskit/top-layer
2
2
 
3
+ ## 0.1.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [`034e29787df79`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/034e29787df79) -
8
+ Fix arrow tips being squared off instead of coming to a point by changing clip-path inset from 1px
9
+ to 0px
10
+
11
+ ## 0.1.4
12
+
13
+ ### Patch Changes
14
+
15
+ - [`f4eca31807dcc`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f4eca31807dcc) -
16
+ Add new xcss on popover to support customize background color and address arrow style issue
17
+
18
+ ## 0.1.3
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies
23
+
3
24
  ## 0.1.2
4
25
 
5
26
  ### Patch Changes
@@ -13,7 +13,7 @@ var _useAnchorPositioning = require("../internal/use-anchor-positioning");
13
13
  * How it works:
14
14
  * 1. Four arrow shapes exist simultaneously as `::before` (top/bottom) and
15
15
  * `::after` (left/right) hexagonal pseudo-elements.
16
- * 2. `clip-path: inset(1px) margin-box` clips the popover to its margin-box.
16
+ * 2. `clip-path: inset(0) margin-box` clips the popover to its margin-box.
17
17
  * 3. Margin on the anchor-facing side pushes the popover away, creating space
18
18
  * where one arrow "escapes" the clip boundary and becomes visible.
19
19
  * 4. `@position-try` rules change both `position-area` and `margin` when
@@ -26,7 +26,7 @@ var _useAnchorPositioning = require("../internal/use-anchor-positioning");
26
26
  *
27
27
  * @see https://goulet.dev/posts/tooltip-with-popover-and-anchor-positioning/
28
28
  */
29
- var ARROW_CSS = "\n[data-ds-popover-arrow] {\n clip-path: inset(var(--ds-arrow-offset, 1px)) margin-box;\n box-shadow: none;\n}\n\n/* Top and Bottom arrows (vertical hexagon) */\n[data-ds-popover-arrow]::before {\n content: \"\";\n position: absolute;\n z-index: -1;\n background: inherit;\n left: 50%;\n transform: translateX(-50%);\n width: calc(var(--ds-arrow-size, 8px) * 2);\n height: calc(100% + var(--ds-arrow-size, 8px) * 2);\n top: calc(var(--ds-arrow-size, 8px) * -1);\n clip-path: polygon(\n 0 var(--ds-arrow-size, 8px),\n 50% 0,\n 100% var(--ds-arrow-size, 8px),\n 100% calc(100% - var(--ds-arrow-size, 8px)),\n 50% 100%,\n 0 calc(100% - var(--ds-arrow-size, 8px))\n );\n}\n\n/* Left and Right arrows (horizontal hexagon) */\n[data-ds-popover-arrow]::after {\n content: \"\";\n position: absolute;\n z-index: -1;\n background: inherit;\n top: 50%;\n transform: translateY(-50%);\n height: calc(var(--ds-arrow-size, 8px) * 2);\n width: calc(100% + var(--ds-arrow-size, 8px) * 2);\n left: calc(var(--ds-arrow-size, 8px) * -1);\n clip-path: polygon(\n var(--ds-arrow-size, 8px) 0,\n calc(100% - var(--ds-arrow-size, 8px)) 0,\n 100% 50%,\n calc(100% - var(--ds-arrow-size, 8px)) 100%,\n var(--ds-arrow-size, 8px) 100%,\n 0 50%\n );\n}\n\n/* \u2500\u2500 @position-try rules \u2500\u2500\n * One rule per possible position-area value.\n * Each sets the position-area and the correct margin direction\n * so the arrow on the anchor-facing side is revealed.\n *\n * Margin direction per edge:\n * block-start (above anchor) \u2192 margin-block-end (bottom, facing anchor)\n * block-end (below anchor) \u2192 margin-block-start (top, facing anchor)\n * inline-start (left of anchor) \u2192 margin-inline-end (right, facing anchor)\n * inline-end (right of anchor) \u2192 margin-inline-start (left, facing anchor)\n */\n\n/* Single-axis centered */\n@position-try --ds-arrow-block-start {\n position-area: block-start;\n margin: 0;\n margin-block-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-end {\n position-area: block-end;\n margin: 0;\n margin-block-start: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-start {\n position-area: inline-start;\n margin: 0;\n margin-inline-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-end {\n position-area: inline-end;\n margin: 0;\n margin-inline-start: var(--ds-arrow-size, 8px);\n}\n\n/* Block edge + inline span */\n@position-try --ds-arrow-block-start-span-inline-start {\n position-area: block-start span-inline-start;\n margin: 0;\n margin-block-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-start-span-inline-end {\n position-area: block-start span-inline-end;\n margin: 0;\n margin-block-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-end-span-inline-start {\n position-area: block-end span-inline-start;\n margin: 0;\n margin-block-start: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-end-span-inline-end {\n position-area: block-end span-inline-end;\n margin: 0;\n margin-block-start: var(--ds-arrow-size, 8px);\n}\n\n/* Inline edge + block span */\n@position-try --ds-arrow-inline-start-span-block-start {\n position-area: inline-start span-block-start;\n margin: 0;\n margin-inline-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-start-span-block-end {\n position-area: inline-start span-block-end;\n margin: 0;\n margin-inline-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-end-span-block-start {\n position-area: inline-end span-block-start;\n margin: 0;\n margin-inline-start: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-end-span-block-end {\n position-area: inline-end span-block-end;\n margin: 0;\n margin-inline-start: var(--ds-arrow-size, 8px);\n}\n";
29
+ var ARROW_CSS = "\n[data-ds-popover-arrow] {\n clip-path: inset(var(--ds-arrow-offset, 0px)) margin-box;\n box-shadow: none;\n}\n\n/* Top and Bottom arrows (vertical hexagon) */\n[data-ds-popover-arrow]::before {\n content: \"\";\n position: absolute;\n z-index: -1;\n background: inherit;\n left: 50%;\n transform: translateX(-50%);\n width: calc(var(--ds-arrow-size, 8px) * 2);\n height: calc(100% + var(--ds-arrow-size, 8px) * 2);\n top: calc(var(--ds-arrow-size, 8px) * -1);\n clip-path: polygon(\n 0 var(--ds-arrow-size, 8px),\n 50% 0,\n 100% var(--ds-arrow-size, 8px),\n 100% calc(100% - var(--ds-arrow-size, 8px)),\n 50% 100%,\n 0 calc(100% - var(--ds-arrow-size, 8px))\n );\n}\n\n/* Left and Right arrows (horizontal hexagon) */\n[data-ds-popover-arrow]::after {\n content: \"\";\n position: absolute;\n z-index: -1;\n background: inherit;\n top: 50%;\n transform: translateY(-50%);\n height: calc(var(--ds-arrow-size, 8px) * 2);\n width: calc(100% + var(--ds-arrow-size, 8px) * 2);\n left: calc(var(--ds-arrow-size, 8px) * -1);\n clip-path: polygon(\n var(--ds-arrow-size, 8px) 0,\n calc(100% - var(--ds-arrow-size, 8px)) 0,\n 100% 50%,\n calc(100% - var(--ds-arrow-size, 8px)) 100%,\n var(--ds-arrow-size, 8px) 100%,\n 0 50%\n );\n}\n\n/* \u2500\u2500 @position-try rules \u2500\u2500\n * One rule per possible position-area value.\n * Each sets the position-area and the correct margin direction\n * so the arrow on the anchor-facing side is revealed.\n *\n * Margin direction per edge:\n * block-start (above anchor) \u2192 margin-block-end (bottom, facing anchor)\n * block-end (below anchor) \u2192 margin-block-start (top, facing anchor)\n * inline-start (left of anchor) \u2192 margin-inline-end (right, facing anchor)\n * inline-end (right of anchor) \u2192 margin-inline-start (left, facing anchor)\n */\n\n/* Single-axis centered */\n@position-try --ds-arrow-block-start {\n position-area: block-start;\n margin: 0;\n margin-block-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-end {\n position-area: block-end;\n margin: 0;\n margin-block-start: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-start {\n position-area: inline-start;\n margin: 0;\n margin-inline-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-end {\n position-area: inline-end;\n margin: 0;\n margin-inline-start: var(--ds-arrow-size, 8px);\n}\n\n/* Block edge + inline span */\n@position-try --ds-arrow-block-start-span-inline-start {\n position-area: block-start span-inline-start;\n margin: 0;\n margin-block-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-start-span-inline-end {\n position-area: block-start span-inline-end;\n margin: 0;\n margin-block-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-end-span-inline-start {\n position-area: block-end span-inline-start;\n margin: 0;\n margin-block-start: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-end-span-inline-end {\n position-area: block-end span-inline-end;\n margin: 0;\n margin-block-start: var(--ds-arrow-size, 8px);\n}\n\n/* Inline edge + block span */\n@position-try --ds-arrow-inline-start-span-block-start {\n position-area: inline-start span-block-start;\n margin: 0;\n margin-inline-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-start-span-block-end {\n position-area: inline-start span-block-end;\n margin: 0;\n margin-inline-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-end-span-block-start {\n position-area: inline-end span-block-start;\n margin: 0;\n margin-inline-start: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-end-span-block-end {\n position-area: inline-end span-block-end;\n margin: 0;\n margin-inline-start: var(--ds-arrow-size, 8px);\n}\n";
30
30
 
31
31
  // ── Placement utilities ──
32
32
 
@@ -239,6 +239,11 @@ function useAnchorPosition(_ref4) {
239
239
  property: '--ds-arrow-size',
240
240
  value: "".concat(offset, "px")
241
241
  });
242
+ // Mark the popover root as the arrow host. The ARROW_CSS targets
243
+ // [data-ds-popover-arrow] to apply clip-path: inset(0) margin-box
244
+ // and box-shadow: none. Must be on the popover root (not a child)
245
+ // because that's where useAnchorPosition sets the margin gap.
246
+ popover.setAttribute('data-ds-popover-arrow', '');
242
247
  }
243
248
  var _undoPositioning = (0, _combine.combine)((0, _setStyle.setStyle)({
244
249
  el: trigger,
@@ -249,7 +254,9 @@ function useAnchorPosition(_ref4) {
249
254
  }), (0, _setStyle.setStyle)({
250
255
  el: popover,
251
256
  styles: popoverStyles
252
- }));
257
+ }), arrow ? function () {
258
+ return popover.removeAttribute('data-ds-popover-arrow');
259
+ } : function () {});
253
260
  return _undoPositioning;
254
261
  }
255
262
 
@@ -67,6 +67,7 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
67
67
  placement = _ref.placement,
68
68
  testId = _ref.testId,
69
69
  isOpen = _ref.isOpen,
70
+ xcssFromProps = _ref.xcss,
70
71
  role = _ref.role,
71
72
  label = _ref.label,
72
73
  labelledBy = _ref.labelledBy,
@@ -248,6 +249,7 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
248
249
  "aria-labelledby": labelledBy,
249
250
  "data-testid": testId
250
251
  }, preset ? (0, _defineProperty2.default)({}, "data-ds-popover-".concat(preset.name), '') : undefined, {
251
- className: (0, _runtime.ax)([styles.root])
252
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- xcss prop passes compiled atomic class names
253
+ className: (0, _runtime.ax)([styles.root, xcssFromProps])
252
254
  }), showChildren ? children : null);
253
255
  });
@@ -35,6 +35,7 @@ var PopupContent = exports.PopupContent = /*#__PURE__*/(0, _react.forwardRef)(fu
35
35
  mode = _ref.mode,
36
36
  _ref$width = _ref.width,
37
37
  width = _ref$width === void 0 ? 'content' : _ref$width,
38
+ xcss = _ref.xcss,
38
39
  isOpenProp = _ref.isOpen,
39
40
  triggerRefProp = _ref.triggerRef,
40
41
  placementProp = _ref.placement,
@@ -193,7 +194,8 @@ var PopupContent = exports.PopupContent = /*#__PURE__*/(0, _react.forwardRef)(fu
193
194
  onOpenChange: handleOpenChange,
194
195
  testId: testId,
195
196
  children: children,
196
- id: ctx === null || ctx === void 0 ? void 0 : ctx.popoverId
197
+ id: ctx === null || ctx === void 0 ? void 0 : ctx.popoverId,
198
+ xcss: xcss
197
199
  };
198
200
  return /*#__PURE__*/_react.default.createElement(_popover.Popover, (0, _extends2.default)({
199
201
  ref: combinedRef
@@ -6,7 +6,7 @@ import { getPlacement, placementToPositionArea } from '../internal/use-anchor-po
6
6
  * How it works:
7
7
  * 1. Four arrow shapes exist simultaneously as `::before` (top/bottom) and
8
8
  * `::after` (left/right) hexagonal pseudo-elements.
9
- * 2. `clip-path: inset(1px) margin-box` clips the popover to its margin-box.
9
+ * 2. `clip-path: inset(0) margin-box` clips the popover to its margin-box.
10
10
  * 3. Margin on the anchor-facing side pushes the popover away, creating space
11
11
  * where one arrow "escapes" the clip boundary and becomes visible.
12
12
  * 4. `@position-try` rules change both `position-area` and `margin` when
@@ -21,7 +21,7 @@ import { getPlacement, placementToPositionArea } from '../internal/use-anchor-po
21
21
  */
22
22
  const ARROW_CSS = `
23
23
  [data-ds-popover-arrow] {
24
- clip-path: inset(var(--ds-arrow-offset, 1px)) margin-box;
24
+ clip-path: inset(var(--ds-arrow-offset, 0px)) margin-box;
25
25
  box-shadow: none;
26
26
  }
27
27
 
@@ -232,6 +232,11 @@ export function useAnchorPosition({
232
232
  property: '--ds-arrow-size',
233
233
  value: `${offset}px`
234
234
  });
235
+ // Mark the popover root as the arrow host. The ARROW_CSS targets
236
+ // [data-ds-popover-arrow] to apply clip-path: inset(0) margin-box
237
+ // and box-shadow: none. Must be on the popover root (not a child)
238
+ // because that's where useAnchorPosition sets the margin gap.
239
+ popover.setAttribute('data-ds-popover-arrow', '');
235
240
  }
236
241
  const undoPositioning = combine(setStyle({
237
242
  el: trigger,
@@ -242,7 +247,7 @@ export function useAnchorPosition({
242
247
  }), setStyle({
243
248
  el: popover,
244
249
  styles: popoverStyles
245
- }));
250
+ }), arrow ? () => popover.removeAttribute('data-ds-popover-arrow') : () => {});
246
251
  return undoPositioning;
247
252
  }
248
253
 
@@ -54,6 +54,7 @@ export const Popover = /*#__PURE__*/forwardRef(function Popover({
54
54
  placement,
55
55
  testId,
56
56
  isOpen,
57
+ xcss: xcssFromProps,
57
58
  // ARIA
58
59
  role,
59
60
  label,
@@ -237,6 +238,7 @@ export const Popover = /*#__PURE__*/forwardRef(function Popover({
237
238
  }, preset ? {
238
239
  [`data-ds-popover-${preset.name}`]: ''
239
240
  } : undefined, {
240
- className: ax([styles.root])
241
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- xcss prop passes compiled atomic class names
242
+ className: ax([styles.root, xcssFromProps])
241
243
  }), showChildren ? children : null);
242
244
  });
@@ -24,6 +24,7 @@ export const PopupContent = /*#__PURE__*/forwardRef(function PopupContent({
24
24
  arrow,
25
25
  mode,
26
26
  width = 'content',
27
+ xcss,
27
28
  isOpen: isOpenProp,
28
29
  triggerRef: triggerRefProp,
29
30
  placement: placementProp,
@@ -184,7 +185,8 @@ export const PopupContent = /*#__PURE__*/forwardRef(function PopupContent({
184
185
  onOpenChange: handleOpenChange,
185
186
  testId,
186
187
  children,
187
- id: ctx === null || ctx === void 0 ? void 0 : ctx.popoverId
188
+ id: ctx === null || ctx === void 0 ? void 0 : ctx.popoverId,
189
+ xcss
188
190
  };
189
191
  return /*#__PURE__*/React.createElement(Popover, _extends({
190
192
  ref: combinedRef
@@ -6,7 +6,7 @@ import { getPlacement, placementToPositionArea } from '../internal/use-anchor-po
6
6
  * How it works:
7
7
  * 1. Four arrow shapes exist simultaneously as `::before` (top/bottom) and
8
8
  * `::after` (left/right) hexagonal pseudo-elements.
9
- * 2. `clip-path: inset(1px) margin-box` clips the popover to its margin-box.
9
+ * 2. `clip-path: inset(0) margin-box` clips the popover to its margin-box.
10
10
  * 3. Margin on the anchor-facing side pushes the popover away, creating space
11
11
  * where one arrow "escapes" the clip boundary and becomes visible.
12
12
  * 4. `@position-try` rules change both `position-area` and `margin` when
@@ -19,7 +19,7 @@ import { getPlacement, placementToPositionArea } from '../internal/use-anchor-po
19
19
  *
20
20
  * @see https://goulet.dev/posts/tooltip-with-popover-and-anchor-positioning/
21
21
  */
22
- var ARROW_CSS = "\n[data-ds-popover-arrow] {\n clip-path: inset(var(--ds-arrow-offset, 1px)) margin-box;\n box-shadow: none;\n}\n\n/* Top and Bottom arrows (vertical hexagon) */\n[data-ds-popover-arrow]::before {\n content: \"\";\n position: absolute;\n z-index: -1;\n background: inherit;\n left: 50%;\n transform: translateX(-50%);\n width: calc(var(--ds-arrow-size, 8px) * 2);\n height: calc(100% + var(--ds-arrow-size, 8px) * 2);\n top: calc(var(--ds-arrow-size, 8px) * -1);\n clip-path: polygon(\n 0 var(--ds-arrow-size, 8px),\n 50% 0,\n 100% var(--ds-arrow-size, 8px),\n 100% calc(100% - var(--ds-arrow-size, 8px)),\n 50% 100%,\n 0 calc(100% - var(--ds-arrow-size, 8px))\n );\n}\n\n/* Left and Right arrows (horizontal hexagon) */\n[data-ds-popover-arrow]::after {\n content: \"\";\n position: absolute;\n z-index: -1;\n background: inherit;\n top: 50%;\n transform: translateY(-50%);\n height: calc(var(--ds-arrow-size, 8px) * 2);\n width: calc(100% + var(--ds-arrow-size, 8px) * 2);\n left: calc(var(--ds-arrow-size, 8px) * -1);\n clip-path: polygon(\n var(--ds-arrow-size, 8px) 0,\n calc(100% - var(--ds-arrow-size, 8px)) 0,\n 100% 50%,\n calc(100% - var(--ds-arrow-size, 8px)) 100%,\n var(--ds-arrow-size, 8px) 100%,\n 0 50%\n );\n}\n\n/* \u2500\u2500 @position-try rules \u2500\u2500\n * One rule per possible position-area value.\n * Each sets the position-area and the correct margin direction\n * so the arrow on the anchor-facing side is revealed.\n *\n * Margin direction per edge:\n * block-start (above anchor) \u2192 margin-block-end (bottom, facing anchor)\n * block-end (below anchor) \u2192 margin-block-start (top, facing anchor)\n * inline-start (left of anchor) \u2192 margin-inline-end (right, facing anchor)\n * inline-end (right of anchor) \u2192 margin-inline-start (left, facing anchor)\n */\n\n/* Single-axis centered */\n@position-try --ds-arrow-block-start {\n position-area: block-start;\n margin: 0;\n margin-block-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-end {\n position-area: block-end;\n margin: 0;\n margin-block-start: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-start {\n position-area: inline-start;\n margin: 0;\n margin-inline-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-end {\n position-area: inline-end;\n margin: 0;\n margin-inline-start: var(--ds-arrow-size, 8px);\n}\n\n/* Block edge + inline span */\n@position-try --ds-arrow-block-start-span-inline-start {\n position-area: block-start span-inline-start;\n margin: 0;\n margin-block-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-start-span-inline-end {\n position-area: block-start span-inline-end;\n margin: 0;\n margin-block-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-end-span-inline-start {\n position-area: block-end span-inline-start;\n margin: 0;\n margin-block-start: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-end-span-inline-end {\n position-area: block-end span-inline-end;\n margin: 0;\n margin-block-start: var(--ds-arrow-size, 8px);\n}\n\n/* Inline edge + block span */\n@position-try --ds-arrow-inline-start-span-block-start {\n position-area: inline-start span-block-start;\n margin: 0;\n margin-inline-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-start-span-block-end {\n position-area: inline-start span-block-end;\n margin: 0;\n margin-inline-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-end-span-block-start {\n position-area: inline-end span-block-start;\n margin: 0;\n margin-inline-start: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-end-span-block-end {\n position-area: inline-end span-block-end;\n margin: 0;\n margin-inline-start: var(--ds-arrow-size, 8px);\n}\n";
22
+ var ARROW_CSS = "\n[data-ds-popover-arrow] {\n clip-path: inset(var(--ds-arrow-offset, 0px)) margin-box;\n box-shadow: none;\n}\n\n/* Top and Bottom arrows (vertical hexagon) */\n[data-ds-popover-arrow]::before {\n content: \"\";\n position: absolute;\n z-index: -1;\n background: inherit;\n left: 50%;\n transform: translateX(-50%);\n width: calc(var(--ds-arrow-size, 8px) * 2);\n height: calc(100% + var(--ds-arrow-size, 8px) * 2);\n top: calc(var(--ds-arrow-size, 8px) * -1);\n clip-path: polygon(\n 0 var(--ds-arrow-size, 8px),\n 50% 0,\n 100% var(--ds-arrow-size, 8px),\n 100% calc(100% - var(--ds-arrow-size, 8px)),\n 50% 100%,\n 0 calc(100% - var(--ds-arrow-size, 8px))\n );\n}\n\n/* Left and Right arrows (horizontal hexagon) */\n[data-ds-popover-arrow]::after {\n content: \"\";\n position: absolute;\n z-index: -1;\n background: inherit;\n top: 50%;\n transform: translateY(-50%);\n height: calc(var(--ds-arrow-size, 8px) * 2);\n width: calc(100% + var(--ds-arrow-size, 8px) * 2);\n left: calc(var(--ds-arrow-size, 8px) * -1);\n clip-path: polygon(\n var(--ds-arrow-size, 8px) 0,\n calc(100% - var(--ds-arrow-size, 8px)) 0,\n 100% 50%,\n calc(100% - var(--ds-arrow-size, 8px)) 100%,\n var(--ds-arrow-size, 8px) 100%,\n 0 50%\n );\n}\n\n/* \u2500\u2500 @position-try rules \u2500\u2500\n * One rule per possible position-area value.\n * Each sets the position-area and the correct margin direction\n * so the arrow on the anchor-facing side is revealed.\n *\n * Margin direction per edge:\n * block-start (above anchor) \u2192 margin-block-end (bottom, facing anchor)\n * block-end (below anchor) \u2192 margin-block-start (top, facing anchor)\n * inline-start (left of anchor) \u2192 margin-inline-end (right, facing anchor)\n * inline-end (right of anchor) \u2192 margin-inline-start (left, facing anchor)\n */\n\n/* Single-axis centered */\n@position-try --ds-arrow-block-start {\n position-area: block-start;\n margin: 0;\n margin-block-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-end {\n position-area: block-end;\n margin: 0;\n margin-block-start: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-start {\n position-area: inline-start;\n margin: 0;\n margin-inline-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-end {\n position-area: inline-end;\n margin: 0;\n margin-inline-start: var(--ds-arrow-size, 8px);\n}\n\n/* Block edge + inline span */\n@position-try --ds-arrow-block-start-span-inline-start {\n position-area: block-start span-inline-start;\n margin: 0;\n margin-block-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-start-span-inline-end {\n position-area: block-start span-inline-end;\n margin: 0;\n margin-block-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-end-span-inline-start {\n position-area: block-end span-inline-start;\n margin: 0;\n margin-block-start: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-block-end-span-inline-end {\n position-area: block-end span-inline-end;\n margin: 0;\n margin-block-start: var(--ds-arrow-size, 8px);\n}\n\n/* Inline edge + block span */\n@position-try --ds-arrow-inline-start-span-block-start {\n position-area: inline-start span-block-start;\n margin: 0;\n margin-inline-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-start-span-block-end {\n position-area: inline-start span-block-end;\n margin: 0;\n margin-inline-end: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-end-span-block-start {\n position-area: inline-end span-block-start;\n margin: 0;\n margin-inline-start: var(--ds-arrow-size, 8px);\n}\n@position-try --ds-arrow-inline-end-span-block-end {\n position-area: inline-end span-block-end;\n margin: 0;\n margin-inline-start: var(--ds-arrow-size, 8px);\n}\n";
23
23
 
24
24
  // ── Placement utilities ──
25
25
 
@@ -226,6 +226,11 @@ export function useAnchorPosition(_ref4) {
226
226
  property: '--ds-arrow-size',
227
227
  value: "".concat(offset, "px")
228
228
  });
229
+ // Mark the popover root as the arrow host. The ARROW_CSS targets
230
+ // [data-ds-popover-arrow] to apply clip-path: inset(0) margin-box
231
+ // and box-shadow: none. Must be on the popover root (not a child)
232
+ // because that's where useAnchorPosition sets the margin gap.
233
+ popover.setAttribute('data-ds-popover-arrow', '');
229
234
  }
230
235
  var _undoPositioning = combine(setStyle({
231
236
  el: trigger,
@@ -236,7 +241,9 @@ export function useAnchorPosition(_ref4) {
236
241
  }), setStyle({
237
242
  el: popover,
238
243
  styles: popoverStyles
239
- }));
244
+ }), arrow ? function () {
245
+ return popover.removeAttribute('data-ds-popover-arrow');
246
+ } : function () {});
240
247
  return _undoPositioning;
241
248
  }
242
249
 
@@ -58,6 +58,7 @@ export var Popover = /*#__PURE__*/forwardRef(function Popover(_ref, ref) {
58
58
  placement = _ref.placement,
59
59
  testId = _ref.testId,
60
60
  isOpen = _ref.isOpen,
61
+ xcssFromProps = _ref.xcss,
61
62
  role = _ref.role,
62
63
  label = _ref.label,
63
64
  labelledBy = _ref.labelledBy,
@@ -239,6 +240,7 @@ export var Popover = /*#__PURE__*/forwardRef(function Popover(_ref, ref) {
239
240
  "aria-labelledby": labelledBy,
240
241
  "data-testid": testId
241
242
  }, preset ? _defineProperty({}, "data-ds-popover-".concat(preset.name), '') : undefined, {
242
- className: ax([styles.root])
243
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- xcss prop passes compiled atomic class names
244
+ className: ax([styles.root, xcssFromProps])
243
245
  }), showChildren ? children : null);
244
246
  });
@@ -26,6 +26,7 @@ export var PopupContent = /*#__PURE__*/forwardRef(function PopupContent(_ref, re
26
26
  mode = _ref.mode,
27
27
  _ref$width = _ref.width,
28
28
  width = _ref$width === void 0 ? 'content' : _ref$width,
29
+ xcss = _ref.xcss,
29
30
  isOpenProp = _ref.isOpen,
30
31
  triggerRefProp = _ref.triggerRef,
31
32
  placementProp = _ref.placement,
@@ -184,7 +185,8 @@ export var PopupContent = /*#__PURE__*/forwardRef(function PopupContent(_ref, re
184
185
  onOpenChange: handleOpenChange,
185
186
  testId: testId,
186
187
  children: children,
187
- id: ctx === null || ctx === void 0 ? void 0 : ctx.popoverId
188
+ id: ctx === null || ctx === void 0 ? void 0 : ctx.popoverId,
189
+ xcss: xcss
188
190
  };
189
191
  return /*#__PURE__*/React.createElement(Popover, _extends({
190
192
  ref: combinedRef
@@ -1,4 +1,5 @@
1
1
  import { type ReactNode } from 'react';
2
+ import { type StrictXCSSProp } from '@atlaskit/css';
2
3
  import { type TAnimationPreset } from '../animations/types';
3
4
  import { type TAriaRoleOptional, type TRoleRequiringAccessibleName, type TRoleWithImplicitName } from '../internal/role-types';
4
5
  import { type TPlacementOptions } from '../popup/types';
@@ -38,6 +39,12 @@ export type TPopoverForwardedProps = TPopoverBaseProps & {
38
39
  export type TPopoverInternalProps = TPopoverForwardedProps;
39
40
  type TPopoverBaseProps = {
40
41
  children: ReactNode;
42
+ /**
43
+ * Additional CSS styles applied to the popover root element.
44
+ * Use to set `backgroundColor` so arrow pseudo-elements (which use
45
+ * `background: inherit`) match the popup surface colour.
46
+ */
47
+ xcss?: StrictXCSSProp<'backgroundColor', never>;
41
48
  /**
42
49
  * Animation preset for entry/exit transitions.
43
50
  *
@@ -1,4 +1,5 @@
1
1
  import { type ReactElement, type ReactNode, type Ref, type RefObject } from 'react';
2
+ import { type StrictXCSSProp } from '@atlaskit/css';
2
3
  import { type TAnimationPreset } from '../animations/types';
3
4
  import { type TArrowPreset } from '../arrow/types';
4
5
  import { type TPlacement } from '../internal/resolve-placement';
@@ -135,6 +136,21 @@ type TPopupContentBaseProps = {
135
136
  * Falls back to a one-off measurement of the trigger's width.
136
137
  */
137
138
  width?: 'content' | 'trigger' | 'min-trigger';
139
+ /**
140
+ * Applies additional CSS styles to the popover root element using
141
+ * design-system-safe xcss.
142
+ *
143
+ * **Required when using `arrow`:** the arrow pseudo-elements use
144
+ * `background: inherit` to pick up their color from the popover root.
145
+ * Without setting `backgroundColor` here, the arrow tip will be transparent.
146
+ *
147
+ * @example
148
+ * ```tsx
149
+ * const styles = cssMap({ surface: { backgroundColor: token('elevation.surface.overlay') } });
150
+ * <Popup.Content xcss={styles.surface} arrow={arrowPreset} ... />
151
+ * ```
152
+ */
153
+ xcss?: StrictXCSSProp<'backgroundColor', never>;
138
154
  /**
139
155
  * Ref to the trigger element for anchor positioning.
140
156
  * When absent, anchor positioning is skipped (consumer handles positioning).
@@ -1,4 +1,5 @@
1
1
  import { type ReactNode } from 'react';
2
+ import { type StrictXCSSProp } from '@atlaskit/css';
2
3
  import { type TAnimationPreset } from '../animations/types';
3
4
  import { type TAriaRoleOptional, type TRoleRequiringAccessibleName, type TRoleWithImplicitName } from '../internal/role-types';
4
5
  import { type TPlacementOptions } from '../popup/types';
@@ -38,6 +39,12 @@ export type TPopoverForwardedProps = TPopoverBaseProps & {
38
39
  export type TPopoverInternalProps = TPopoverForwardedProps;
39
40
  type TPopoverBaseProps = {
40
41
  children: ReactNode;
42
+ /**
43
+ * Additional CSS styles applied to the popover root element.
44
+ * Use to set `backgroundColor` so arrow pseudo-elements (which use
45
+ * `background: inherit`) match the popup surface colour.
46
+ */
47
+ xcss?: StrictXCSSProp<'backgroundColor', never>;
41
48
  /**
42
49
  * Animation preset for entry/exit transitions.
43
50
  *
@@ -1,4 +1,5 @@
1
1
  import { type ReactElement, type ReactNode, type Ref, type RefObject } from 'react';
2
+ import { type StrictXCSSProp } from '@atlaskit/css';
2
3
  import { type TAnimationPreset } from '../animations/types';
3
4
  import { type TArrowPreset } from '../arrow/types';
4
5
  import { type TPlacement } from '../internal/resolve-placement';
@@ -135,6 +136,21 @@ type TPopupContentBaseProps = {
135
136
  * Falls back to a one-off measurement of the trigger's width.
136
137
  */
137
138
  width?: 'content' | 'trigger' | 'min-trigger';
139
+ /**
140
+ * Applies additional CSS styles to the popover root element using
141
+ * design-system-safe xcss.
142
+ *
143
+ * **Required when using `arrow`:** the arrow pseudo-elements use
144
+ * `background: inherit` to pick up their color from the popover root.
145
+ * Without setting `backgroundColor` here, the arrow tip will be transparent.
146
+ *
147
+ * @example
148
+ * ```tsx
149
+ * const styles = cssMap({ surface: { backgroundColor: token('elevation.surface.overlay') } });
150
+ * <Popup.Content xcss={styles.surface} arrow={arrowPreset} ... />
151
+ * ```
152
+ */
153
+ xcss?: StrictXCSSProp<'backgroundColor', never>;
138
154
  /**
139
155
  * Ref to the trigger element for anchor positioning.
140
156
  * When absent, anchor positioning is skipped (consumer handles positioning).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/top-layer",
3
- "version": "0.1.2",
3
+ "version": "0.1.5",
4
4
  "description": "Low-level layering primitives based on popover and dialog",
5
5
  "homepage": "https://atlassian.design/components/top-layer",
6
6
  "repository": "https://bitbucket.org/atlassian/atlassian-frontend-mirror",
@@ -37,7 +37,7 @@
37
37
  "@atlaskit/browser-apis": "^0.0.1",
38
38
  "@atlaskit/css": "^0.19.0",
39
39
  "@atlaskit/ds-lib": "^7.0.0",
40
- "@atlaskit/tokens": "^12.0.0",
40
+ "@atlaskit/tokens": "^13.0.0",
41
41
  "@babel/runtime": "^7.0.0",
42
42
  "@compiled/react": "^0.20.0",
43
43
  "bind-event-listener": "^3.0.0",
@@ -52,8 +52,8 @@
52
52
  "@af/visual-regression": "workspace:^",
53
53
  "@atlaskit/button": "^23.11.0",
54
54
  "@atlaskit/heading": "^5.4.0",
55
- "@atlaskit/lozenge": "^13.5.0",
56
- "@atlaskit/primitives": "^18.1.0",
55
+ "@atlaskit/lozenge": "^13.6.0",
56
+ "@atlaskit/primitives": "^19.0.0",
57
57
  "@atlaskit/ssr": "workspace:^",
58
58
  "@atlaskit/textfield": "^8.3.0",
59
59
  "@atlassian/react-compiler-gating": "workspace:^",