@porsche-design-system/components-react 4.3.0 → 4.4.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/cjs/lib/components/popover.wrapper.cjs +4 -3
  3. package/esm/lib/components/popover.wrapper.d.ts +26 -2
  4. package/esm/lib/components/popover.wrapper.mjs +5 -4
  5. package/package.json +2 -2
  6. package/ssr/cjs/components/dist/styles/esm/styles-entry.cjs +354 -143
  7. package/ssr/cjs/components/dist/utils/esm/utils-entry.cjs +1 -1
  8. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/components/popover.wrapper.cjs +5 -4
  9. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/banner.cjs +15 -5
  10. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/dialog-base.cjs +3 -7
  11. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/drilldown.cjs +3 -0
  12. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/fc-dismiss-button.cjs +16 -0
  13. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/flyout.cjs +14 -1
  14. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/inline-notification.cjs +2 -2
  15. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/modal.cjs +14 -1
  16. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/popover.cjs +65 -16
  17. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/sheet.cjs +14 -1
  18. package/ssr/esm/components/dist/styles/esm/styles-entry.mjs +354 -144
  19. package/ssr/esm/components/dist/utils/esm/utils-entry.mjs +1 -1
  20. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/components/popover.wrapper.mjs +6 -5
  21. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/banner.mjs +15 -5
  22. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/dialog-base.mjs +3 -7
  23. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/drilldown.mjs +3 -0
  24. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/fc-dismiss-button.mjs +14 -0
  25. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/flyout.mjs +14 -1
  26. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/inline-notification.mjs +2 -2
  27. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/modal.mjs +14 -1
  28. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/popover.mjs +66 -17
  29. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/sheet.mjs +14 -1
  30. package/ssr/esm/lib/components/popover.wrapper.d.ts +26 -2
  31. package/ssr/esm/lib/dsr-components/banner.d.ts +2 -0
  32. package/ssr/esm/lib/dsr-components/dialog-base.d.ts +2 -2
  33. package/ssr/esm/lib/dsr-components/drilldown.d.ts +1 -0
  34. package/ssr/esm/lib/dsr-components/fc-dismiss-button.d.ts +16 -0
  35. package/ssr/esm/lib/dsr-components/flyout.d.ts +1 -0
  36. package/ssr/esm/lib/dsr-components/modal.d.ts +1 -0
  37. package/ssr/esm/lib/dsr-components/popover.d.ts +16 -7
  38. package/ssr/esm/lib/dsr-components/sheet.d.ts +1 -0
@@ -3847,7 +3847,7 @@ const OPTION_LIST_SAFE_ZONE = 6;
3847
3847
 
3848
3848
  const getCDNBaseURL = () => global.PORSCHE_DESIGN_SYSTEM_CDN_URL + "/porsche-design-system";
3849
3849
 
3850
- const prefix = `[Porsche Design System v${"4.3.0"}]` // this part isn't covered by unit tests
3850
+ const prefix = `[Porsche Design System v${"4.4.0-rc.1"}]` // this part isn't covered by unit tests
3851
3851
  ;
3852
3852
  const consoleError = (...messages) => {
3853
3853
  console.error(prefix, ...messages);
@@ -3982,11 +3982,11 @@ const cssVarSummaryTopDeprecated = '--p-accordion-position-sticky-top'; // depre
3982
3982
  /**
3983
3983
  * @css-variable {"name": "--p-accordion-px", "description": "Horizontal padding of the accordion.", "defaultValue": "16px"}
3984
3984
  */
3985
- const cssVarPaddingInline$1 = '--p-accordion-px';
3985
+ const cssVarPaddingInline$2 = '--p-accordion-px';
3986
3986
  /**
3987
3987
  * @css-variable {"name": "--p-accordion-py", "description": "Vertical padding of the accordion.", "defaultValue": "16px"}
3988
3988
  */
3989
- const cssVarPaddingBlock = '--p-accordion-py';
3989
+ const cssVarPaddingBlock$1 = '--p-accordion-py';
3990
3990
  const iconMarker = getInlineSVGBackgroundImage(`<path d="m12 15.125h-.001l-.005-.006-6.494-5.476.642-.768 5.858 4.94 5.858-4.94.642.769-6.497 5.477z"/>`);
3991
3991
  const backgroundMap$1 = {
3992
3992
  canvas: ref(colorCanvas),
@@ -4067,7 +4067,7 @@ const getComponentCss$1a = (alignMarker, background, isCompact, indent, isOpen,
4067
4067
  gridTemplate: `repeat(2, auto) / ${hasSummaryBefore ? 'auto ' : ''}${isIconAlignedStart ? 'auto minmax(0, 1fr)' : 'minmax(0, 1fr) auto'}${hasSummaryAfter ? ' auto ' : ''}`,
4068
4068
  columnGap: gap,
4069
4069
  alignItems: 'center',
4070
- padding: `${ref(cssVarPaddingBlock, background === 'none' ? '0' : paddingBlock)} ${ref(cssVarPaddingInline$1, background === 'none' ? '0' : paddingInline)}`,
4070
+ padding: `${ref(cssVarPaddingBlock$1, background === 'none' ? '0' : paddingBlock)} ${ref(cssVarPaddingInline$2, background === 'none' ? '0' : paddingInline)}`,
4071
4071
  background: backgroundMap$1[background],
4072
4072
  ...(background === 'frosted' && {
4073
4073
  WebkitBackdropFilter: ref(blurFrosted),
@@ -4077,7 +4077,7 @@ const getComponentCss$1a = (alignMarker, background, isCompact, indent, isOpen,
4077
4077
  ...forcedColorsMediaQuery({
4078
4078
  outline: '1px solid CanvasText',
4079
4079
  outlineOffset: background === 'none' ? '0' : '-1px',
4080
- padding: `${ref(cssVarPaddingBlock, paddingBlock)} ${ref(cssVarPaddingInline$1, paddingInline)}`,
4080
+ padding: `${ref(cssVarPaddingBlock$1, paddingBlock)} ${ref(cssVarPaddingInline$2, paddingInline)}`,
4081
4081
  }),
4082
4082
  '&::details-content': addImportantToEachRule({
4083
4083
  display: 'contents', // allows <details> to be used as grid layout
@@ -4102,8 +4102,8 @@ const getComponentCss$1a = (alignMarker, background, isCompact, indent, isOpen,
4102
4102
  opacity: 1,
4103
4103
  paddingTop,
4104
4104
  zIndex: 2, // Ensure details are above summary when using custom padding
4105
- paddingInline: `${ref(cssVarPaddingInline$1, background === 'none' ? '0' : paddingInline)}`,
4106
- marginInline: `calc(-1 * ${ref(cssVarPaddingInline$1, background === 'none' ? '0' : paddingInline)})`,
4105
+ paddingInline: `${ref(cssVarPaddingInline$2, background === 'none' ? '0' : paddingInline)}`,
4106
+ marginInline: `calc(-1 * ${ref(cssVarPaddingInline$2, background === 'none' ? '0' : paddingInline)})`,
4107
4107
  // as soon as all browsers support calc-size(auto) to be transitionable, we can remove the grid-template-rows rule and animation
4108
4108
  gridTemplateRows: '1fr',
4109
4109
  visibility: 'inherit', // since `::details-content` and `allow-discrete` transition doesn't work in Safari we need to take care ourselves for visibility state to be a11y compliant
@@ -4120,8 +4120,8 @@ const getComponentCss$1a = (alignMarker, background, isCompact, indent, isOpen,
4120
4120
  gridTemplateColumns: 'subgrid',
4121
4121
  alignItems: 'center',
4122
4122
  cursor: 'pointer',
4123
- padding: `${ref(cssVarPaddingBlock, background === 'none' ? '0' : paddingBlock)} ${ref(cssVarPaddingInline$1, background === 'none' ? '0' : paddingInline)}`,
4124
- margin: `calc(-1 * ${ref(cssVarPaddingBlock, background === 'none' ? '0' : paddingBlock)}) calc(-1 * ${ref(cssVarPaddingInline$1, background === 'none' ? '0' : paddingInline)})`,
4123
+ padding: `${ref(cssVarPaddingBlock$1, background === 'none' ? '0' : paddingBlock)} ${ref(cssVarPaddingInline$2, background === 'none' ? '0' : paddingInline)}`,
4124
+ margin: `calc(-1 * ${ref(cssVarPaddingBlock$1, background === 'none' ? '0' : paddingBlock)}) calc(-1 * ${ref(cssVarPaddingInline$2, background === 'none' ? '0' : paddingInline)})`,
4125
4125
  ...(isSticky &&
4126
4126
  (background === 'canvas' || background === 'surface') && {
4127
4127
  position: 'sticky',
@@ -4220,9 +4220,6 @@ const getComponentCss$19 = () => {
4220
4220
  });
4221
4221
  };
4222
4222
 
4223
- const TOAST_Z_INDEX = 999999;
4224
- const BANNER_Z_INDEX = 99;
4225
-
4226
4223
  const colorMap$3 = {
4227
4224
  primary: ref(colorPrimary),
4228
4225
  'contrast-higher': ref(colorContrastHigher),
@@ -4287,6 +4284,86 @@ const weightMap = {
4287
4284
  bold: ref(fontWeightBold),
4288
4285
  };
4289
4286
 
4287
+ // Inlined `close` icon (mirrors packages/assets/projects/icons/src/close.svg) rendered as a CSS mask, so the dismiss
4288
+ // button needs neither a nested `p-button` nor a `p-icon` (which would fetch the SVG from the CDN asynchronously).
4289
+ const iconClose = getInlineSVGBackgroundImage('<path d="m18 6.706-5.294 5.294 5.294 5.294-.706.706-5.294-5.294-5.294 5.294-.706-.706 5.294-5.294-5.294-5.294.706-.706 5.294 5.294 5.294-5.294z"/>');
4290
+ // NOTE: Values copied (and reduced to the fixed `compact` + `hideLabel` case the dismiss button always uses) from
4291
+ // `getVariantColors` in `packages/components/src/styles/link-button-styles.ts` to keep the visual identical to the
4292
+ // previously nested `p-button`. If the shared button styling changes, mirror it here (or extract a shared helper).
4293
+ const getVariantColors$1 = (variant) => {
4294
+ const colors = {
4295
+ primary: {
4296
+ textColor: ref(colorCanvas),
4297
+ backgroundColor: ref(colorPrimary),
4298
+ backgroundColorHover: ref(colorContrastHigh),
4299
+ },
4300
+ secondary: {
4301
+ textColor: ref(colorPrimary),
4302
+ backgroundColor: ref(colorFrostedStrong),
4303
+ backgroundColorHover: ref(colorFrosted),
4304
+ },
4305
+ };
4306
+ return colors[variant];
4307
+ };
4308
+ /**
4309
+ * Visual styles for the shared native `<button class="dismiss">` dismiss button. Returns the button rule (reset,
4310
+ * variant colors, focus ring, High Contrast Mode, hover, inlined close-icon mask and the visually-hidden label). Each
4311
+ * consumer merges this with its own positioning styles for the `dismiss` key (e.g. grid placement in
4312
+ * `notification-base-styles` / `dialog-base-styles`).
4313
+ *
4314
+ * Reduced to the dismiss button's fixed configuration (always `compact` + `hideLabel`): padding `6px`, full border
4315
+ * radius and no gap — the responsive `compact`/`hideLabel` branches from `getLinkButtonStyles` are therefore collapsed.
4316
+ */
4317
+ const getFCDismissButtonStyles = (variant) => {
4318
+ const { textColor, backgroundColor, backgroundColorHover } = getVariantColors$1(variant);
4319
+ return {
4320
+ all: 'unset',
4321
+ boxSizing: 'border-box',
4322
+ display: 'grid',
4323
+ placeItems: 'center',
4324
+ padding: '6px',
4325
+ borderRadius: ref(radiusFull),
4326
+ font: `${ref(fontWeightNormal$1)} ${ref(typescaleSm$1)} / ${ref(leadingNormal$1)} ${ref(fontPorscheNext$1)}`,
4327
+ backgroundColor,
4328
+ color: textColor,
4329
+ cursor: 'pointer',
4330
+ // The frosted backdrop-filter is only meaningful for the translucent `secondary` (frosted) background. For the
4331
+ // opaque `primary` background it is invisible AND — because the dialog consumer additionally applies
4332
+ // `filter: invert(1)` on the same element (see `getDialogDismissButtonJssStyle`) — the blurred backdrop bleeds past
4333
+ // the circular edge and the invert amplifies it into a visible glow/halo. So it is applied for `secondary` only.
4334
+ ...(variant === 'secondary' && {
4335
+ WebkitBackdropFilter: ref(blurFrosted),
4336
+ backdropFilter: ref(blurFrosted),
4337
+ }),
4338
+ transition: `${getTransition('background-color')}, ${getTransition('color')}`,
4339
+ ...forcedColorsMediaQuery({
4340
+ forcedColorAdjust: 'none',
4341
+ background: 'Canvas',
4342
+ boxShadow: 'inset 0 0 0 2px ButtonBorder',
4343
+ color: 'ButtonText',
4344
+ }),
4345
+ '&:focus-visible': getFocusBaseStyles(),
4346
+ ...hoverMediaQuery({
4347
+ '&:hover': {
4348
+ backgroundColor: backgroundColorHover,
4349
+ ...forcedColorsMediaQuery({
4350
+ background: 'Canvas',
4351
+ }),
4352
+ },
4353
+ }),
4354
+ '&::before': {
4355
+ content: '""',
4356
+ width: ref(leadingNormal$1),
4357
+ height: ref(leadingNormal$1),
4358
+ WebkitMask: `${iconClose} center/contain no-repeat`, // necessary for Sogou browser support :-)
4359
+ mask: `${iconClose} center/contain no-repeat`,
4360
+ background: 'currentColor', // follows the button's text color (variant + HCM `ButtonText`)
4361
+ },
4362
+ // visually-hidden accessible name (mirrors `hideLabel` on the former `p-button`)
4363
+ '& span': getHiddenTextJssStyle(),
4364
+ };
4365
+ };
4366
+
4290
4367
  const getFunctionalComponentNotificationBaseStyles = (state, hasAction, hasDismissButton, hasHeadingOrHeadingSlot) => {
4291
4368
  return {
4292
4369
  '@global': {
@@ -4337,6 +4414,8 @@ const getFunctionalComponentNotificationBaseStyles = (state, hasAction, hasDismi
4337
4414
  },
4338
4415
  ...(hasDismissButton && {
4339
4416
  dismiss: {
4417
+ // native dismiss button visual (secondary variant); grid positioning is applied on top
4418
+ ...getFCDismissButtonStyles('secondary'),
4340
4419
  gridArea: `1/4/-1`,
4341
4420
  alignSelf: 'flex-start',
4342
4421
  marginBlock: `calc(-6 * ${ref(spacingStatic2Xs)})`,
@@ -4377,12 +4456,12 @@ const cssVarInsetX = '--p-banner-inset-x';
4377
4456
  const cssVarPositionTop = '--p-banner-position-top'; // deprecated (aliased)
4378
4457
  const cssVarPositionBottom = '--p-banner-position-bottom'; // deprecated (aliased)
4379
4458
  const topBottomFallback = '56px';
4380
- const cssVariableZIndex = '--_p-banner-a';
4381
- const getComponentCss$18 = (isOpen, position, state, hasDismissButton, hasHeadingOrHeadingSlot) => {
4459
+ const cssVarTransform = '--_p-banner-a';
4460
+ const getComponentCss$18 = (isOpen, position, state, hasDismissButton, hasHeadingOrHeadingSlot, skipEntryTransition) => {
4382
4461
  const duration = isOpen ? 'moderate' : 'short';
4383
4462
  const easing = isOpen ? 'in' : 'out';
4384
- const transition = `visibility 0s linear ${ref(cssVariableTransitionDuration, isOpen ? '0s' : motionDurationMap[duration])},${getTransition('transform', duration, easing)}`;
4385
- return getCss({
4463
+ const transition = getTransition('transform', duration, easing);
4464
+ const css = getCss({
4386
4465
  ...mergeDeep({
4387
4466
  '@global': {
4388
4467
  ':host': {
@@ -4391,46 +4470,36 @@ const getComponentCss$18 = (isOpen, position, state, hasDismissButton, hasHeadin
4391
4470
  ...hostHiddenStyles,
4392
4471
  }),
4393
4472
  },
4394
- ...preventFoucOfNestedElementsStyles,
4395
4473
  '[popover]': {
4396
4474
  all: 'unset',
4397
4475
  position: 'fixed',
4398
- zIndex: ref(cssVariableZIndex, BANNER_Z_INDEX), // Fallback for browsers lacking `transition-behavior: allow-discrete` — keeps the banner visible during fade-out after leaving the top layer.
4399
4476
  ...buildResponsiveStyles(position, (v) => ({
4400
4477
  ...(v === 'top' && {
4478
+ [cssVarTransform]: `translate3d(-50%,calc(-100% - ${ref(cssVarTop, ref(cssVarPositionTop, topBottomFallback))}),0)`,
4401
4479
  insetBlock: `${ref(cssVarTop, ref(cssVarPositionTop, topBottomFallback))} auto`,
4402
- ...(!isOpen && {
4403
- transform: `translate3d(-50%,calc(-100% - ${ref(cssVarTop, ref(cssVarPositionTop, topBottomFallback))}),0)`,
4404
- }),
4405
4480
  }),
4406
4481
  ...(v === 'bottom' && {
4482
+ [cssVarTransform]: `translate3d(-50%,calc(${ref(cssVarBottom, ref(cssVarPositionBottom, topBottomFallback))} + 100%),0)`,
4407
4483
  insetBlock: `auto ${ref(cssVarBottom, ref(cssVarPositionBottom, topBottomFallback))}`,
4408
- ...(!isOpen && {
4409
- transform: `translate3d(-50%,calc(${ref(cssVarBottom, ref(cssVarPositionBottom, topBottomFallback))} + 100%),0)`,
4410
- }),
4411
4484
  }),
4412
4485
  })),
4413
4486
  left: '50vw',
4414
4487
  width: `min(calc(100vw - 2 * ${ref(cssVarInsetX, gridExtendedOffsetBase)}),${ref(cssVarMaxWidth, '100ch')})`,
4488
+ transform: isOpen ? 'translate3d(-50%,0,0)' : ref(cssVarTransform),
4489
+ transition,
4490
+ // keep the popover on the #top-layer while the fade-out runs (Chromium only; see `overlayTransitionSupportsQuery`)
4491
+ ...overlayTransitionSupportsQuery({
4492
+ transition: `${transition},${getTransition('overlay', duration, easing)} allow-discrete, ${getTransition('display', duration, easing)} allow-discrete`,
4493
+ }),
4415
4494
  overlay: 'none',
4495
+ display: 'none',
4416
4496
  '&:popover-open': {
4417
4497
  overlay: 'auto',
4498
+ display: 'grid',
4418
4499
  },
4419
4500
  '&::backdrop': {
4420
- display: 'none',
4501
+ display: 'none', // reset ua-style
4421
4502
  },
4422
- visibility: 'hidden', // element shall not be tabbable with keyboard after fade out transition has finished
4423
- pointerEvents: 'none', // element can't be interacted with mouse
4424
- ...(isOpen && {
4425
- visibility: 'inherit',
4426
- pointerEvents: 'inherit',
4427
- transform: 'translate3d(-50%,0,0)',
4428
- }),
4429
- transition,
4430
- // keep the popover on the #top-layer while the fade-out runs (Chromium only; see `overlayTransitionSupportsQuery`)
4431
- ...overlayTransitionSupportsQuery({
4432
- transition: `${transition},${getTransition('overlay', duration, easing)} allow-discrete`,
4433
- }),
4434
4503
  },
4435
4504
  },
4436
4505
  }, {
@@ -4441,6 +4510,17 @@ const getComponentCss$18 = (isOpen, position, state, hasDismissButton, hasHeadin
4441
4510
  },
4442
4511
  }, getFunctionalComponentNotificationBaseStyles(state, false, hasDismissButton, hasHeadingOrHeadingSlot)),
4443
4512
  });
4513
+ // Both the `[popover]` box (transform) and its nested `.notification` (opacity) need a `@starting-style`: while closed
4514
+ // the popover is `display: none`, so on open `.notification` renders fresh with a computed `opacity: 1` and has no
4515
+ // prior value to transition from — without the starting value it snaps to full opacity instead of fading in. The
4516
+ // opacity is split onto `.notification` (not `[popover]`) so the frosted-glass backdrop-filter renders correctly.
4517
+ //
4518
+ // `skipEntryTransition` omits the append on the component's FIRST render, so an initially-open banner (`open=true` on
4519
+ // page load) computes straight to its visible transform/opacity and appears instantly instead of sliding/fading in.
4520
+ // Every later render passes `false`, so a user-triggered open still animates normally.
4521
+ return isOpen && false
4522
+ ? `${css}\n@starting-style {\n [popover] {\n transform: ${ref(cssVarTransform)};\n }\n .notification {\n opacity: 0;\n }\n}`
4523
+ : css;
4444
4524
  };
4445
4525
 
4446
4526
  // Needed for slotted anchor and hidden label, which then enlarges the hidden label to equal host size and indents the text to be visually hidden.
@@ -5205,7 +5285,7 @@ const getComponentCss$14 = (isSidebarStartOpen, isSidebarEndOpen, background) =>
5205
5285
  /**
5206
5286
  * @css-variable {"name": "--p-carousel-px", "description": "Defines the logical inline start and end padding of the carousel, the extra space is used to show parts of the next/previous slide. When used then the prop `width` has no effect anymore.", "defaultValue": ""}
5207
5287
  */
5208
- const cssVarPaddingInline = '--p-carousel-px';
5288
+ const cssVarPaddingInline$1 = '--p-carousel-px';
5209
5289
  /**
5210
5290
  * @css-variable {"name": "--p-carousel-ps", "description": "Defines the logical inline start padding of the carousel, the extra space is used to show parts of the next/previous slide. Needs to be used in combination with `--p-carousel-px` or `--p-carousel-pe`. When used then the prop `width` has no effect anymore.", "defaultValue": ""}
5211
5291
  */
@@ -5324,17 +5404,17 @@ const getComponentCss$13 = (gradient, hasHeading, hasDescription, hasControlsSlo
5324
5404
  },
5325
5405
  header: {
5326
5406
  display: 'grid',
5327
- paddingInlineStart: ref(cssVarPaddingInlineStart, ref(cssVarPaddingInline, spacingMap[width].base)),
5328
- paddingInlineEnd: ref(cssVarPaddingInlineEnd, ref(cssVarPaddingInline, spacingMap[width].base)),
5407
+ paddingInlineStart: ref(cssVarPaddingInlineStart, ref(cssVarPaddingInline$1, spacingMap[width].base)),
5408
+ paddingInlineEnd: ref(cssVarPaddingInlineEnd, ref(cssVarPaddingInline$1, spacingMap[width].base)),
5329
5409
  [mediaQueryS]: {
5330
5410
  gridTemplateColumns: 'minmax(0px,1fr) auto',
5331
- paddingInlineStart: ref(cssVarPaddingInlineStart, ref(cssVarPaddingInline, spacingMap[width].s)),
5332
- paddingInlineEnd: ref(cssVarPaddingInlineEnd, ref(cssVarPaddingInline, spacingMap[width].s)),
5411
+ paddingInlineStart: ref(cssVarPaddingInlineStart, ref(cssVarPaddingInline$1, spacingMap[width].s)),
5412
+ paddingInlineEnd: ref(cssVarPaddingInlineEnd, ref(cssVarPaddingInline$1, spacingMap[width].s)),
5333
5413
  ...(hasNavigation && { columnGap: ref(spacingStaticMd) }),
5334
5414
  },
5335
5415
  [mediaQueryXXL]: {
5336
- paddingInlineStart: ref(cssVarPaddingInlineStart, ref(cssVarPaddingInline, spacingMap[width].xxl)),
5337
- paddingInlineEnd: ref(cssVarPaddingInlineEnd, ref(cssVarPaddingInline, spacingMap[width].xxl)),
5416
+ paddingInlineStart: ref(cssVarPaddingInlineStart, ref(cssVarPaddingInline$1, spacingMap[width].xxl)),
5417
+ paddingInlineEnd: ref(cssVarPaddingInlineEnd, ref(cssVarPaddingInline$1, spacingMap[width].xxl)),
5338
5418
  },
5339
5419
  },
5340
5420
  nav: {
@@ -5371,15 +5451,15 @@ const getComponentCss$13 = (gradient, hasHeading, hasDescription, hasControlsSlo
5371
5451
  // !important is necessary to override inline styles set by splide library
5372
5452
  ...addImportantToEachRule({
5373
5453
  paddingBlock: '0px',
5374
- paddingInlineStart: ref(cssVarPaddingInlineStart, ref(cssVarPaddingInline, spacingMap[width].base)),
5375
- paddingInlineEnd: ref(cssVarPaddingInlineEnd, ref(cssVarPaddingInline, spacingMap[width].base)),
5454
+ paddingInlineStart: ref(cssVarPaddingInlineStart, ref(cssVarPaddingInline$1, spacingMap[width].base)),
5455
+ paddingInlineEnd: ref(cssVarPaddingInlineEnd, ref(cssVarPaddingInline$1, spacingMap[width].base)),
5376
5456
  [mediaQueryS]: {
5377
- paddingInlineStart: ref(cssVarPaddingInlineStart, ref(cssVarPaddingInline, spacingMap[width].s)),
5378
- paddingInlineEnd: ref(cssVarPaddingInlineEnd, ref(cssVarPaddingInline, spacingMap[width].s)),
5457
+ paddingInlineStart: ref(cssVarPaddingInlineStart, ref(cssVarPaddingInline$1, spacingMap[width].s)),
5458
+ paddingInlineEnd: ref(cssVarPaddingInlineEnd, ref(cssVarPaddingInline$1, spacingMap[width].s)),
5379
5459
  },
5380
5460
  [mediaQueryXXL]: {
5381
- paddingInlineStart: ref(cssVarPaddingInlineStart, ref(cssVarPaddingInline, spacingMap[width].xxl)),
5382
- paddingInlineEnd: ref(cssVarPaddingInlineEnd, ref(cssVarPaddingInline, spacingMap[width].xxl)),
5461
+ paddingInlineStart: ref(cssVarPaddingInlineStart, ref(cssVarPaddingInline$1, spacingMap[width].xxl)),
5462
+ paddingInlineEnd: ref(cssVarPaddingInlineEnd, ref(cssVarPaddingInline$1, spacingMap[width].xxl)),
5383
5463
  },
5384
5464
  }),
5385
5465
  '&--draggable': {
@@ -5657,8 +5737,20 @@ const getFunctionalComponentLabelAfterStyles = () => {
5657
5737
  const labelAfterStyles = {
5658
5738
  display: 'inline-block',
5659
5739
  verticalAlign: 'top',
5740
+ // The inline-start spacing is applied to the assigned elements via `::slotted(*)` (not to the `<slot>` box or via
5741
+ // `:empty`), so it only exists when the "label-after" slot actually has content — an empty slot renders no margin.
5742
+ // `::slotted()` alone would fail for a slotted `p-popover`, whose `:host` uses `display: contents` (a `contents` box
5743
+ // has no margins). To fix that, we also set `display: inline-block` on the slotted element: since `::slotted()` is a
5744
+ // rule from the *outer* shadow tree, its normal declarations win over the popover's own (inner-tree) normal
5745
+ // `:host { display: contents }` in the shadow-tree cascade — this is a cascade/context precedence, not specificity.
5746
+ // The re-established inline-block box then has something for `margin-inline-start` to apply to.
5747
+ // Note: relies on `p-popover`'s `:host { display: contents }` staying non-`!important`; an inner `!important` would
5748
+ // beat this outer normal declaration. Keeping inline flow (vs. flex/gap) lets label-after follow a wrapped label's
5749
+ // last line. `:host(:has([slot="label-after"]))` would be an alternative but lacks reliable Chrome support for now.
5660
5750
  '&::slotted(*)': {
5661
5751
  ...addImportantToEachRule({
5752
+ display: 'inline-block',
5753
+ verticalAlign: 'top',
5662
5754
  marginInlineStart: ref(spacingStaticXs$1),
5663
5755
  }),
5664
5756
  },
@@ -5812,28 +5904,14 @@ const dialogHostJssStyle = (background) => {
5812
5904
  [cssVarBackgroundColor]: background === 'surface' ? ref(colorSurface) : ref(colorCanvas),
5813
5905
  };
5814
5906
  };
5907
+ // INTENTIONAL DIVERGENCE from `popover-styles.ts` (kept, not aligned — see the mirrored note there):
5908
+ // This dialog stays permanently rendered and collapses its CLOSED state via delayed `visibility: hidden` + `width/height: 0`
5909
+ // (driven by `isVisible`), so `opacity`/`background` fade in BOTH directions with NO `@starting-style`, and an initial
5910
+ // `open=true` computes straight to the visible state (no entry fade on load). `p-popover`/`p-banner` instead use the native
5911
+ // `[popover]` `display: none`/`:popover-open` toggle plus a `@starting-style` entry fade, because those components mimic the
5912
+ // native popover box model. Both share `createTopLayerController` + the Chromium-only `overlay allow-discrete` transition
5913
+ // (`overlayTransitionSupportsQuery`) and the `inert` toggle for tabbability; only the closed-state expression differs.
5815
5914
  const getFunctionalComponentDialogBaseStyles = (isVisible, backdrop = 'blur') => {
5816
- return {
5817
- dialog: {
5818
- ...dialogBackdropResetJssStyle,
5819
- ...getDialogBackdropTransitionJssStyle(isVisible, backdrop),
5820
- },
5821
- };
5822
- };
5823
- const dialogBackdropResetJssStyle = {
5824
- all: 'unset',
5825
- position: 'fixed',
5826
- inset: 0,
5827
- maxWidth: '100dvw',
5828
- maxHeight: '100dvh',
5829
- overflow: 'hidden',
5830
- display: 'block',
5831
- outline: 0, // we always expect a focusable element to be within the dialog
5832
- '&::backdrop': {
5833
- display: 'none', // ua-style (we can't use it atm because it's not animatable in all browsers)
5834
- },
5835
- };
5836
- const getDialogBackdropTransitionJssStyle = (isVisible, backdrop = 'blur') => {
5837
5915
  const isBackdropBlur = backdrop === 'blur';
5838
5916
  const duration = isVisible ? 'long' : 'moderate';
5839
5917
  const easing = isVisible ? 'in' : 'out';
@@ -5841,14 +5919,21 @@ const getDialogBackdropTransitionJssStyle = (isVisible, backdrop = 'blur') => {
5841
5919
  // as soon as all browsers are supporting `allow-discrete`, visibility transition shouldn't be necessary anymore
5842
5920
  const transition = `visibility 0s linear ${delay}, width 0s linear ${delay}, height 0s linear ${delay}, ${getTransition('background-color', duration, easing)}, ${getTransition('-webkit-backdrop-filter', duration, easing)}, ${getTransition('backdrop-filter', duration, easing)}`;
5843
5921
  return {
5844
- zIndex: 9999999, // fallback for fade out stacking until `overlay` + `allow-discrete` is supported in all browsers. It tries to mimic #top-layer positioning hierarchy.
5922
+ all: 'unset',
5923
+ position: 'fixed',
5924
+ inset: 0,
5925
+ maxWidth: '100dvw',
5926
+ maxHeight: '100dvh',
5927
+ overflow: 'hidden',
5928
+ display: 'block',
5929
+ userSelect: 'text', // allows text selection within dialog element (e.g. for copy & paste)
5930
+ outline: 0, // we always expect a focusable element to be within the dialog
5845
5931
  ...(isVisible
5846
5932
  ? {
5847
5933
  width: '100dvw',
5848
5934
  height: '100dvh',
5849
5935
  visibility: 'inherit',
5850
5936
  pointerEvents: 'auto',
5851
- overlay: 'auto',
5852
5937
  background: ref(colorBackdrop),
5853
5938
  ...(isBackdropBlur && {
5854
5939
  WebkitBackdropFilter: ref(blurFrosted),
@@ -5864,7 +5949,6 @@ const getDialogBackdropTransitionJssStyle = (isVisible, backdrop = 'blur') => {
5864
5949
  height: '0px',
5865
5950
  visibility: 'hidden', // element shall not be tabbable with keyboard after fade out transition has finished
5866
5951
  pointerEvents: 'none', // element can't be interacted with mouse
5867
- overlay: 'none',
5868
5952
  background: 'transparent',
5869
5953
  }),
5870
5954
  transition,
@@ -5872,6 +5956,13 @@ const getDialogBackdropTransitionJssStyle = (isVisible, backdrop = 'blur') => {
5872
5956
  ...overlayTransitionSupportsQuery({
5873
5957
  transition: `${transition}, ${getTransition('overlay', duration, easing)} allow-discrete`,
5874
5958
  }),
5959
+ overlay: 'none',
5960
+ '&:modal': {
5961
+ overlay: 'auto',
5962
+ },
5963
+ '&::backdrop': {
5964
+ display: 'none', // reset ua-style (we can't use it atm because it's not animatable in all browsers)
5965
+ },
5875
5966
  };
5876
5967
  };
5877
5968
  const getScrollerJssStyle = (position) => {
@@ -5951,6 +6042,9 @@ const getDialogTransitionJssStyle = (isVisible, slideIn) => {
5951
6042
  };
5952
6043
  const getDialogDismissButtonJssStyle = () => {
5953
6044
  return {
6045
+ // native dismiss button visual (primary variant); positioning + the `invert` filter (renders it light on the
6046
+ // dialog) are applied on top below
6047
+ ...getFCDismissButtonStyles('primary'),
5954
6048
  gridArea: '1/3',
5955
6049
  zIndex: 5, // controls layering + creates new stacking context (prevents content within to be above other dialog areas)
5956
6050
  position: 'sticky',
@@ -7044,7 +7138,7 @@ const getComponentCss$W = (size) => {
7044
7138
  /**
7045
7139
  * @css-variable {"name": "--p-flyout-width", "description": "Width of the flyout.", "defaultValue": "auto"}
7046
7140
  */
7047
- const cssVariableWidth$2 = '--p-flyout-width';
7141
+ const cssVariableWidth$3 = '--p-flyout-width';
7048
7142
  /**
7049
7143
  * @css-variable {"name": "--p-flyout-sticky-top", "description": "@experimental Exposes the header's height as a read-only CSS variable, set automatically by the component. Slotted sticky content can use this value to offset their top position correctly."}
7050
7144
  */
@@ -7075,7 +7169,6 @@ const getComponentCss$V = (isOpen, background, backdrop, position, hasHeader, ha
7075
7169
  ...hostHiddenStyles,
7076
7170
  }),
7077
7171
  },
7078
- ...preventFoucOfNestedElementsStyles,
7079
7172
  slot: {
7080
7173
  ...getSlotJssStyle(),
7081
7174
  '&:not([name])': getSlotMainJssStyle(),
@@ -7098,7 +7191,7 @@ const getComponentCss$V = (isOpen, background, backdrop, position, hasHeader, ha
7098
7191
  '&[name=sub-footer]': getSlotSubFooterJssStyle(),
7099
7192
  }),
7100
7193
  },
7101
- ...getFunctionalComponentDialogBaseStyles(isOpen, backdrop),
7194
+ dialog: getFunctionalComponentDialogBaseStyles(isOpen, backdrop),
7102
7195
  },
7103
7196
  scroller: {
7104
7197
  ...getScrollerJssStyle(isPositionStart ? 'start' : 'end'),
@@ -7127,7 +7220,7 @@ const getComponentCss$V = (isOpen, background, backdrop, position, hasHeader, ha
7127
7220
  },
7128
7221
  }
7129
7222
  : {
7130
- width: ref(cssVariableWidth$2, 'auto'),
7223
+ width: ref(cssVariableWidth$3, 'auto'),
7131
7224
  minWidth: '320px',
7132
7225
  maxWidth: '100vw',
7133
7226
  clipPath: isPositionStart
@@ -7900,7 +7993,7 @@ const getComponentCss$D = (icon, iconSource, variant, hideLabel, hasSlottedAncho
7900
7993
  * @css-variable {"name": "--p-modal-spacing-top", "description": "Spacing of the modal to the top.", "defaultValue": "clamp(16px, 10vh, 192px)"}
7901
7994
  * @css-variable {"name": "--p-modal-spacing-bottom", "description": "Spacing of the modal to the bottom.", "defaultValue": "clamp(16px, 10vh, 192px)"}
7902
7995
  */
7903
- const cssVariableWidth$1 = '--p-modal-width';
7996
+ const cssVariableWidth$2 = '--p-modal-width';
7904
7997
  const cssVariableSpacingTop = '--p-modal-spacing-top'; // TODO: maybe --p-modal-spacing-block-start would be more precise?
7905
7998
  const cssVariableSpacingBottom = '--p-modal-spacing-bottom'; // TODO: maybe --p-modal-spacing-block-end would be more precise?
7906
7999
  /**
@@ -7928,7 +8021,6 @@ const getComponentCss$C = (isOpen, background, backdrop, fullscreen, hasDismissB
7928
8021
  ...hostHiddenStyles,
7929
8022
  }),
7930
8023
  },
7931
- ...preventFoucOfNestedElementsStyles,
7932
8024
  slot: {
7933
8025
  ...getSlotJssStyle(),
7934
8026
  '&:not([name])': getSlotMainJssStyle(),
@@ -7942,7 +8034,7 @@ const getComponentCss$C = (isOpen, background, backdrop, fullscreen, hasDismissB
7942
8034
  '&[name=footer]': getSlotFooterJssStyle(),
7943
8035
  }),
7944
8036
  },
7945
- ...getFunctionalComponentDialogBaseStyles(isOpen, backdrop),
8037
+ dialog: getFunctionalComponentDialogBaseStyles(isOpen, backdrop),
7946
8038
  },
7947
8039
  scroller: getScrollerJssStyle('fullscreen'),
7948
8040
  modal: {
@@ -7960,7 +8052,7 @@ const getComponentCss$C = (isOpen, background, backdrop, fullscreen, hasDismissB
7960
8052
  clipPath: 'none', // fullscreen has square corners, so disable corner clipping
7961
8053
  }
7962
8054
  : {
7963
- width: ref(cssVariableWidth$1, 'auto'),
8055
+ width: ref(cssVariableWidth$2, 'auto'),
7964
8056
  minWidth: '276px', // to be in sync with "Porsche Grid" on viewport = 320px: calc(${gridColumnWidthBase} * 6 + ${gridGap} * 5)
7965
8057
  maxWidth: '1535.5px', // to be in sync with "Porsche Grid" on viewport >= 1920px: `calc(${gridColumnWidthXXL} * 14 + ${gridGap} * 13)`
7966
8058
  placeSelf: 'center',
@@ -7986,11 +8078,11 @@ const getSvgUrl = (model) => {
7986
8078
  /**
7987
8079
  * @css-variable {"name": "--p-model-signature-width", "description": "Overrides the width of the model signature.", "defaultValue": ""}
7988
8080
  */
7989
- const cssVariableWidth = '--p-model-signature-width';
8081
+ const cssVariableWidth$1 = '--p-model-signature-width';
7990
8082
  /**
7991
8083
  * @css-variable {"name": "--p-model-signature-height", "description": "Overrides the height of the model signature.", "defaultValue": "auto"}
7992
8084
  */
7993
- const cssVariableHeight = '--p-model-signature-height';
8085
+ const cssVariableHeight$1 = '--p-model-signature-height';
7994
8086
  /**
7995
8087
  * @css-variable {"name": "--p-model-signature-color", "description": "Overrides the fill color of the model signature. Overrides the `color` property when set.", "defaultValue": ""}
7996
8088
  */
@@ -8013,8 +8105,8 @@ const getComponentCss$B = (model, safeZone, size, color) => {
8013
8105
  maxWidth: '100%',
8014
8106
  maxHeight: '100%',
8015
8107
  // width + height style can't be !important atm to be backwards compatible with e.g. `<p-model-signature size="inherit" style="height: 50px"/>`
8016
- width: ref(cssVariableWidth, isSizeInherit ? 'auto' : `${width}px`),
8017
- height: ref(cssVariableHeight, 'auto'),
8108
+ width: ref(cssVariableWidth$1, isSizeInherit ? 'auto' : `${width}px`),
8109
+ height: ref(cssVariableHeight$1, 'auto'),
8018
8110
  ...addImportantToEachRule({
8019
8111
  mask: `url(${getSvgUrl(model)}) no-repeat left top / contain`,
8020
8112
  aspectRatio: `${width} / ${safeZone ? 36 : height}`, // 36px is the max-height for SVG model signature creation
@@ -8345,97 +8437,216 @@ const getComponentCss$w = (hideLabel, state, isDisabled, isLoading, length, isCo
8345
8437
  });
8346
8438
  };
8347
8439
 
8440
+ // Minimum gap (in px) kept between the panel and the viewport edges. Used both as Floating UI `shift`/`flip` padding
8441
+ // and to inset the panel's default max-width/height (`100dvw/dvh - 2 * POPOVER_SAFE_ZONE`) so it never touches the edge.
8348
8442
  const POPOVER_SAFE_ZONE = 8;
8349
8443
 
8350
- const getComponentCss$v = () => {
8351
- const shadowColor = 'rgba(0,0,0,0.3)';
8352
- return getCss({
8444
+ /**
8445
+ * @css-variable {"name": "--p-popover-w", "description": "Width of the popover.", "defaultValue": "max-content"}
8446
+ */
8447
+ const cssVariableWidth = '--p-popover-w';
8448
+ /**
8449
+ * @css-variable {"name": "--p-popover-h", "description": "Height of the popover.", "defaultValue": "auto"}
8450
+ */
8451
+ const cssVariableHeight = '--p-popover-h';
8452
+ /**
8453
+ * @css-variable {"name": "--p-popover-min-w", "description": "Min width of the popover.", "defaultValue": "0px"}
8454
+ */
8455
+ const cssVariableMinWidth = '--p-popover-min-w';
8456
+ /**
8457
+ * @css-variable {"name": "--p-popover-min-h", "description": "Min height of the popover.", "defaultValue": "auto"}
8458
+ */
8459
+ const cssVariableMinHeight = '--p-popover-min-h';
8460
+ /**
8461
+ * @css-variable {"name": "--p-popover-max-w", "description": "Max width of the popover.", "defaultValue": "min(calc(100dvw - 16px), 48ch)"}
8462
+ */
8463
+ const cssVariableMaxWidth = '--p-popover-max-w';
8464
+ /**
8465
+ * @css-variable {"name": "--p-popover-max-h", "description": "Max height of the popover.", "defaultValue": "calc(100dvh - 16px)"}
8466
+ */
8467
+ const cssVariableMaxHeight = '--p-popover-max-h';
8468
+ /**
8469
+ * @css-variable {"name": "--p-popover-px", "description": "Horizontal padding of the popover. It is recommended to apply an existing Porsche Design System spacing token, e.g. the CSS declaration `--p-popover-px: var(--p-spacing-static-md)`, the Tailwind CSS arbitrary property `[--p-popover-px:var(--spacing-static-md)]` or the equivalent SCSS/JS token.", "defaultValue": "16px"}
8470
+ */
8471
+ const cssVarPaddingInline = '--p-popover-px';
8472
+ /**
8473
+ * @css-variable {"name": "--p-popover-py", "description": "Vertical padding of the popover. It is recommended to apply an existing Porsche Design System spacing token, e.g. the CSS declaration `--p-popover-py: var(--p-spacing-static-sm)`, the Tailwind CSS arbitrary property `[--p-popover-py:var(--spacing-static-sm)]` or the equivalent SCSS/JS token.", "defaultValue": "12px"}
8474
+ */
8475
+ const cssVarPaddingBlock = '--p-popover-py';
8476
+ /**
8477
+ * @css-variable {"name": "--p-popover-radius", "description": "Border radius of the popover. It is recommended to apply an existing Porsche Design System border-radius token, e.g. the CSS declaration `--p-popover-radius: var(--p-radius-lg)`, the Tailwind CSS arbitrary property `[--p-popover-radius:var(--radius-lg)]` or the equivalent SCSS/JS token.", "defaultValue": "12px"}
8478
+ */
8479
+ const cssVarRadius = '--p-popover-radius';
8480
+ const iconInfo = getInlineSVGBackgroundImage(`<path d="M12.5 10v6h-1v-6zm0-2v1h-1V8zM12 4a8 8 0 0 1 0 16 8 8 0 0 1 0-16m0-1c-4.95 0-9 4.05-9 9s4.05 9 9 9 9-4.05 9-9-4.05-9-9-9"/>`);
8481
+ /**
8482
+ * Builds the popover's scoped CSS.
8483
+ * @param isOpen - The effective open state; drives the fade-in/fade-out direction and the `@starting-style` append.
8484
+ * @param isCompact - Reduces padding/spacing and uses smaller radii (mirrors the `compact` prop).
8485
+ * @param skipEntryTransition - Suppresses the `@starting-style` entry fade. Set on the component's first render so an
8486
+ * initially-open popover (`open=true` on page load) appears instantly instead of fading in. Later user-triggered opens
8487
+ * render with this `false`, so they keep the fade-in.
8488
+ * @returns The component CSS string, with a trailing `@starting-style` rule appended while opening (unless skipped).
8489
+ */
8490
+ const getComponentCss$v = (isOpen, isCompact, skipEntryTransition) => {
8491
+ // fade-in on open (via `@starting-style` below), fade-out on close. While closing, the panel keeps `display: grid`
8492
+ // (Chromium via `overlay` + `display` `allow-discrete`; Safari/Firefox via the deferred `hidePopover()`), so
8493
+ // `display: none` only describes the fully-closed terminal state. Tabbability / a11y-tree removal during the fade-out
8494
+ // is handled immediately via the `inert` attribute on the panel (see popover.tsx), so no `visibility` toggle is needed.
8495
+ const duration = 'short';
8496
+ const easing = isOpen ? 'in' : 'out';
8497
+ const transition = getTransition('opacity', duration, easing);
8498
+ const css = getCss({
8353
8499
  '@global': {
8354
- '@keyframes fade-in': {
8355
- from: {
8356
- opacity: 0,
8357
- },
8358
- to: {
8359
- opacity: 1,
8360
- },
8361
- },
8362
8500
  ':host': {
8363
- position: 'relative', // ensures correct reference for floating ui fallback positioning in older browsers
8364
- display: 'inline-block',
8365
- verticalAlign: 'top',
8366
- ...addImportantToEachRule({
8367
- ...hostHiddenStyles,
8368
- }),
8501
+ // `display: contents` so the host box does not participate in visual DOM rendering — the popover mimics the
8502
+ // native `[popover]` element, so the slotted trigger (or default info button) lays out directly in the parent
8503
+ // flow. Enabled by anchoring Floating UI to the assigned trigger element (see `triggerElement` in popover.tsx)
8504
+ // instead of the `<slot>` box, so the slot no longer needs a layout box of its own.
8505
+ display: 'contents',
8506
+ ...addImportantToEachRule(hostHiddenStyles),
8369
8507
  },
8370
- 'slot[name="button"]': {
8508
+ 'slot:not([name]), p': {
8371
8509
  display: 'block',
8372
- },
8373
- ...preventFoucOfNestedElementsStyles,
8374
- p: {
8375
- font: `${ref(fontWeightNormal$1)} ${ref(typescaleSm$1)} / ${ref(leadingNormal$1)} ${ref(fontPorscheNext$1)}`,
8376
- margin: 0,
8510
+ margin: 0, // reset ua-style for paragraphs
8511
+ minWidth: 0, // allow the grid item to shrink below its content size (needed for correct clamping via --p-popover-max-w)
8512
+ minHeight: 0, // allow the grid item to shrink below its content size so overflow scrolls instead of expanding the panel (needed for --p-popover-max-h)
8513
+ maxWidth: 'inherit',
8514
+ maxHeight: 'inherit',
8515
+ boxSizing: 'border-box',
8516
+ padding: `${ref(cssVarPaddingBlock, isCompact ? ref(spacingStaticXs$1) : `calc(12 * ${ref(spacingStatic2Xs)})`)} ${ref(cssVarPaddingInline, isCompact ? ref(spacingStaticSm$1) : ref(spacingStaticMd))}`,
8517
+ overflow: 'hidden auto',
8518
+ overscrollBehaviorY: 'none',
8377
8519
  },
8378
8520
  button: {
8379
8521
  all: 'unset',
8380
- display: 'block',
8522
+ display: 'inline-grid',
8523
+ verticalAlign: 'top',
8381
8524
  font: `${ref(typescaleSm$1)} ${ref(fontPorscheNext$1)}`, // needed for correct width/height definition based on ex-unit
8382
- width: ref(leadingNormal$1), // width needed to improve ssr support
8383
- height: ref(leadingNormal$1), // height needed to improve ssr support
8525
+ width: ref(leadingNormal$1),
8526
+ height: ref(leadingNormal$1),
8384
8527
  borderRadius: ref(radiusFull),
8385
8528
  cursor: 'pointer',
8386
- backgroundColor: ref(colorFrosted),
8529
+ background: ref(colorFrosted),
8387
8530
  transition: getTransition('background-color'),
8388
8531
  WebkitBackdropFilter: ref(blurFrosted),
8389
8532
  backdropFilter: ref(blurFrosted),
8390
8533
  ...hoverMediaQuery({
8391
8534
  '&:hover': {
8392
- backgroundColor: ref(colorFrostedSoft),
8535
+ background: ref(colorFrostedSoft),
8393
8536
  },
8394
8537
  }),
8395
8538
  '&:focus-visible': getFocusBaseStyles(),
8539
+ '&::after': {
8540
+ content: '""',
8541
+ WebkitMask: `${iconInfo} center/contain no-repeat`, // necessary for Sogou browser support :-)
8542
+ mask: `${iconInfo} center/contain no-repeat`,
8543
+ background: ref(colorPrimary),
8544
+ ...forcedColorsMediaQuery({
8545
+ background: 'CanvasText',
8546
+ }),
8547
+ },
8396
8548
  },
8397
8549
  '[popover]': {
8398
8550
  all: 'unset',
8399
- position: 'absolute',
8400
- pointerEvents: 'none',
8401
- filter: `drop-shadow(0 0 16px ${shadowColor})`,
8551
+ position: 'fixed', // matches floating ui's `fixed` strategy; required for correct top-layer positioning in Safari
8552
+ top: 0,
8553
+ left: 0,
8554
+ filter: 'drop-shadow(0 0 16px rgba(0,0,0,.3))',
8402
8555
  backdropFilter: 'drop-shadow(0 0 transparent)', // workaround for Firefox bug not rendering PDS frosted glass correctly when nested inside CSS filter: https://bugzilla.mozilla.org/show_bug.cgi?id=1797051
8403
- animation: `${ref(cssVariableAnimationDuration, ref(durationSm))} fade-in ${ref(easeInOut)} forwards`,
8404
- '&:not(:popover-open)': {
8405
- display: 'none', // ensures popover is not flickering when closed in some situations
8556
+ borderRadius: ref(cssVarRadius, isCompact ? ref(radiusLg) : ref(radiusXl)),
8557
+ // Fallback for engines without CSS relative color syntax (< Chromium 119 / Safari 16.4 / Firefox 128): the
8558
+ // `hsl(from …)` override below would be an invalid value and get dropped, leaving the panel with no background.
8559
+ // The plain `light-dark()` token renders correct white (light) / near-black (dark) as graceful degradation.
8560
+ background: ref(colorCanvas),
8561
+ // Relative color syntax: lightens ONLY the dark scheme (light `#fff` clamps at l=100 → stays white; dark
8562
+ // `l≈1.2%` → `≈15.2%`). Feature-test string kept in sync with `spinner-styles.ts` (one relative-color feature
8563
+ // covers all color functions).
8564
+ '@supports (color: oklch(from red l c h))': {
8565
+ background: `hsl(from ${ref(colorCanvas)} h 0% calc(l + 14))`,
8566
+ },
8567
+ font: `${ref(fontWeightNormal$1)} ${ref(typescaleSm$1)} / ${ref(leadingNormal$1)} ${ref(fontPorscheNext$1)}`,
8568
+ color: ref(colorPrimary),
8569
+ width: ref(cssVariableWidth, 'max-content'),
8570
+ height: ref(cssVariableHeight, 'auto'),
8571
+ minWidth: ref(cssVariableMinWidth, '0px'),
8572
+ minHeight: ref(cssVariableMinHeight, 'auto'),
8573
+ maxWidth: ref(cssVariableMaxWidth, `min(calc(100dvw - ${POPOVER_SAFE_ZONE * 2}px), 48ch)`),
8574
+ maxHeight: ref(cssVariableMaxHeight, `calc(100dvh - ${POPOVER_SAFE_ZONE * 2}px)`),
8575
+ opacity: isOpen ? 1 : 0,
8576
+ transition,
8577
+ // keep the popover on the #top-layer while the fade-out runs (Chromium only; see `overlayTransitionSupportsQuery`)
8578
+ ...overlayTransitionSupportsQuery({
8579
+ transition: `${transition},${getTransition('overlay', duration, easing)} allow-discrete, ${getTransition('display', duration, easing)} allow-discrete`,
8580
+ }),
8581
+ // Unlike `opacity` (driven by the `isOpen` render flag), `overlay` and `display` are toggled via the
8582
+ // `:popover-open` UA state instead of `isOpen`. Both are owned by the browser: they only flip once
8583
+ // `showPopover()` / `hidePopover()` actually promote/remove the element to/from the #top-layer. Driving them
8584
+ // from `isOpen` would desync from that native state — e.g. Safari/Firefox defer `hidePopover()` until the
8585
+ // fade-out ends (see `createTopLayerController`), so `display` must stay `grid` while `:popover-open` is still
8586
+ // truthy; an `isOpen`-based `display: none` would hide the panel instantly and kill the fade. Binding to
8587
+ // `:popover-open` keeps CSS in lockstep with the browser across all engines, while the Chromium-only
8588
+ // `allow-discrete` transition above animates the discrete `overlay`/`display` switch during the fade-out.
8589
+ overlay: 'none',
8590
+ display: 'none',
8591
+ '&:popover-open': {
8592
+ overlay: 'auto',
8593
+ display: 'grid',
8594
+ },
8595
+ ...forcedColorsMediaQuery({
8596
+ outline: '2px solid CanvasText',
8597
+ outlineOffset: '-2px',
8598
+ }),
8599
+ '&::backdrop': {
8600
+ display: 'none', // reset ua-style
8406
8601
  },
8407
8602
  },
8408
8603
  },
8409
- label: getHiddenTextJssStyle(),
8410
- icon: {
8411
- transform: 'translate3d(0,0,0)', // Fixes movement on hover in Safari
8412
- },
8413
8604
  arrow: {
8414
8605
  position: 'absolute',
8415
8606
  width: '24px',
8416
8607
  height: '12px',
8417
8608
  clipPath: 'polygon(50% 0, 100% 110%, 0 110%)',
8418
- background: ref(colorCanvas),
8609
+ background: 'inherit',
8419
8610
  ...forcedColorsMediaQuery({
8420
8611
  background: 'CanvasText',
8421
8612
  }),
8422
8613
  },
8423
- content: {
8424
- maxWidth: `min(calc(100dvw - ${POPOVER_SAFE_ZONE * 2}px), 48ch)`,
8425
- width: 'max-content', // ensures in older browsers correct width
8426
- boxSizing: 'border-box',
8427
- padding: `${ref(spacingStaticSm$1)} ${ref(spacingStaticMd)}`,
8428
- pointerEvents: 'auto',
8429
- borderRadius: ref(radiusXl),
8430
- background: ref(colorCanvas),
8431
- font: `${ref(fontWeightNormal$1)} ${ref(typescaleSm$1)} / ${ref(leadingNormal$1)} ${ref(fontPorscheNext$1)}`,
8432
- color: ref(colorPrimary),
8433
- ...forcedColorsMediaQuery({
8434
- outline: '2px solid CanvasText',
8435
- outlineOffset: '-2px',
8436
- }),
8437
- },
8438
8614
  });
8615
+ // Fade-IN: `@starting-style` supplies the opacity the browser transitions *from* on the first rendered frame, i.e. the
8616
+ // moment the panel leaves `display: none` via `:popover-open` (triggered by `showPopover()`). Without it the panel
8617
+ // snaps to full opacity, because its computed `opacity` is already `1` by the time it is promoted out of `display:
8618
+ // none`. The fade-OUT needs no starting style (a rendered prior state already exists). Appended as raw CSS because the
8619
+ // JSS conditional-rule plugin only supports `@media`/`@supports`/`@container`, not `@starting-style`. Unsupported
8620
+ // engines (< Chromium 117 / Safari 17.5 / Firefox 129) ignore the unknown at-rule and skip the entry fade (graceful
8621
+ // degradation). Formatting mirrors JSS output so the unit-test CSS parser can read it.
8622
+ //
8623
+ // `skipEntryTransition` omits the append on the component's FIRST render, so an initially-open popover (`open=true` on
8624
+ // page load) computes straight to `opacity: 1` and appears instantly instead of fading in. Every later render passes
8625
+ // `false`, so a user-triggered open still fades in normally.
8626
+ //
8627
+ // ALTERNATIVE APPROACH (INTENTIONALLY NOT IMPLEMENTED) — mirror the `dialog-base` (p-modal/p-flyout) pattern and drop `@starting-style`:
8628
+ // Decision: KEEP this divergence (see the mirrored note in `common/dialog-base/dialog-base-styles.ts`). `p-popover`/`p-banner`
8629
+ // mimic the native `[popover]` box model, so they use the native `display: none`/`:popover-open` toggle + `@starting-style`
8630
+ // entry fade rather than the dialog's permanently-rendered `visibility`/`width`/`height` collapse. Both approaches share
8631
+ // `createTopLayerController`, the Chromium-only `overlay allow-discrete` transition (`overlayTransitionSupportsQuery`) and
8632
+ // the `inert` toggle for tabbability; only the closed-state expression differs. The alternative below is documented for
8633
+ // context (and to record its one upside — no entry fade on initial `open=true`), but is deliberately left unimplemented.
8634
+ // • Keep the panel permanently rendered (never `display: none`); collapse the closed state via `visibility: hidden`
8635
+ // + `width/height: 0` instead. Because the element stays rendered, `opacity` fades normally in BOTH directions with
8636
+ // no `@starting-style`, and an initial `open=true` computes straight to `opacity: 1` (appears instantly, no entry
8637
+ // fade) — which fixes the one downside of the current approach (initial `open=true` fades in on page load).
8638
+ // • Caveat: drive `visibility` + `width/height` from the `isOpen` flag with a CLOSE-ONLY delayed transition
8639
+ // (`… 0s linear ${isOpen ? '0s' : motionDurationMap.short}`), NOT from `:popover-open`. `:popover-open` drops
8640
+ // immediately on Chromium (only Safari/FF defer `hidePopover()`), so `:popover-open`-bound dimensions would collapse
8641
+ // to 0 at the START of the Chromium fade-out and clip the panel mid-fade. The delay keeps size/visibility through
8642
+ // the fade and collapses them only afterwards. `:popover-open` then remains solely for `overlay` + the Chromium
8643
+ // `allow-discrete` top-layer retention.
8644
+ // • `visibility: hidden` still occupies layout (can cause scrollbars), which is why it must be paired with
8645
+ // `width/height: 0`. `inert` is still required either way (visibility is delayed, so the panel stays visible/
8646
+ // tabbable during the fade-out).
8647
+ // • Trade-off: removes the `@starting-style` raw-CSS append + the initial-load fade, at the cost of reintroducing the
8648
+ // delayed `visibility` plus delayed `width/height` and tighter coupling to the motion duration.
8649
+ return isOpen && !skipEntryTransition ? `${css}\n@starting-style {\n [popover] {\n opacity: 0;\n }\n}` : css;
8439
8650
  };
8440
8651
 
8441
8652
  const cssVarInternalRadioGroupOptionScaling = '--_p-radio-group-option-a';
@@ -9015,7 +9226,6 @@ const getComponentCss$n = (isOpen, background, hasDismissButton) => {
9015
9226
  ...hostHiddenStyles,
9016
9227
  }),
9017
9228
  },
9018
- ...preventFoucOfNestedElementsStyles,
9019
9229
  slot: {
9020
9230
  ...getSlotJssStyle(),
9021
9231
  '&:not([name])': getSlotMainJssStyle(),
@@ -9024,7 +9234,7 @@ const getComponentCss$n = (isOpen, background, hasDismissButton) => {
9024
9234
  zIndex: 0, // controls layering + creates new stacking context (prevents content within to be above other dialog areas)
9025
9235
  },
9026
9236
  },
9027
- ...getFunctionalComponentDialogBaseStyles(isOpen, 'shading'),
9237
+ dialog: getFunctionalComponentDialogBaseStyles(isOpen, 'shading'),
9028
9238
  },
9029
9239
  scroller: getScrollerJssStyle('fullscreen'),
9030
9240
  sheet: {
@@ -10162,7 +10372,7 @@ const getComponentCss$1 = () => {
10162
10372
  [cssVariablePositionBottomInternal]: ref(cssVariablePositionBottom, '56px'),
10163
10373
  position: 'fixed', // fallback for older browsers without native `popover` support
10164
10374
  inset: `auto ${gridExtendedOffsetBase} ${ref(cssVariablePositionBottomInternal)}`,
10165
- zIndex: TOAST_Z_INDEX, // fallback for older browsers without native `popover` support
10375
+ zIndex: 999999, // fallback for older browsers without native `popover` support
10166
10376
  [getMediaQueryMin('s')]: {
10167
10377
  [cssVariablePositionBottomInternal]: ref(cssVariablePositionBottom, '64px'),
10168
10378
  inset: `auto auto ${ref(cssVariablePositionBottomInternal)} 64px`,
@@ -10234,4 +10444,4 @@ const getComponentCss = (size) => {
10234
10444
  });
10235
10445
  };
10236
10446
 
10237
- export { cssVarButtonPureMargin, cssVarButtonPurePadding, cssVarInternalInputBaseScaling, dialogBorderRadius, dialogGridJssStyle, dialogHostJssStyle, dialogPaddingBottom, dialogPaddingInline, dialogPaddingTop, getComponentCss$1a as getAccordionCss, getComponentCss$19 as getAiTagCss, getComponentCss$18 as getBannerCss, getComponentCss$15 as getButtonCss, getComponentCss$17 as getButtonPureCss, getComponentCss$16 as getButtonTileCss, getComponentCss$14 as getCanvasCss, getComponentCss$13 as getCarouselCss, getComponentCss$12 as getCheckboxCss, getComponentCss$11 as getCrestCss, getDialogColorJssStyle, getDialogDismissButtonJssStyle, getDialogTransitionJssStyle, getComponentCss$10 as getDisplayCss, getComponentCss$$ as getDividerCss, getComponentCss$_ as getDrilldownCss, getComponentCss$Z as getDrilldownItemCss, getComponentCss$Y as getDrilldownLinkCss, getComponentCss$X as getFieldsetCss, getComponentCss$W as getFlagCss, getComponentCss$V as getFlyoutCss, getFunctionalComponentDialogBaseStyles, getFunctionalComponentInputBaseStyles, getFunctionalComponentLabelAfterStyles, getFunctionalComponentLabelStyles, getFunctionalComponentLoadingMessageStyles, getFunctionalComponentNoResultsOptionStyles, getFunctionalComponentNotificationBaseStyles, getFunctionalComponentRequiredStyles, getFunctionalComponentStateMessageStyles, getComponentCss$U as getHeadingCss, getComponentCss$T as getIconCss, getComponentCss$S as getInlineNotificationCss, getComponentCss$R as getInputDateCss, getComponentCss$Q as getInputEmailCss, getComponentCss$P as getInputMonthCss, getComponentCss$O as getInputNumberCss, getComponentCss$N as getInputPasswordCss, getComponentCss$M as getInputSearchCss, getComponentCss$L as getInputTelCss, getComponentCss$K as getInputTextCss, getComponentCss$J as getInputTimeCss, getComponentCss$I as getInputUrlCss, getComponentCss$H as getInputWeekCss, getComponentCss$D as getLinkCss, getComponentCss$G as getLinkPureCss, getComponentCss$E as getLinkTileCss, getComponentCss$F as getLinkTileProductCss, getComponentCss$C as getModalCss, getComponentCss$B as getModelSignatureCss, getComponentCss$y as getMultiSelectCss, getComponentCss$A as getMultiSelectOptionCss, getComponentCss$z as getOptgroupCss, getComponentCss$x as getPaginationCss, getComponentCss$w as getPinCodeCss, getComponentCss$v as getPopoverCss, getComponentCss$t as getRadioGroupCss, getComponentCss$u as getRadioGroupOptionCss, getComponentCss$s as getScrollerCss, getScrollerJssStyle, getComponentCss$q as getSegmentedControlCss, getComponentCss$r as getSegmentedControlItemCss, getComponentCss$o as getSelectCss, getComponentCss$p as getSelectOptionCss, getComponentCss$n as getSheetCss, getSlotFooterJssStyle, getSlotHeaderJssStyle, getSlotJssStyle, getSlotMainJssStyle, getSlotSubFooterJssStyle, getComponentCss$m as getSpinnerCss, getComponentCss$k as getStepperHorizontalCss, getComponentCss$l as getStepperHorizontalItemCss, getComponentCss$j as getSwitchCss, getComponentCss$i as getTableBodyCss, getComponentCss$g as getTableCellCss, getComponentCss$h as getTableCss, getComponentCss$f as getTableHeadCellCss, getComponentCss$d as getTableHeadCss, getComponentCss$e as getTableHeadRowCss, getComponentCss$c as getTableRowCss, getComponentCss$b as getTabsBarCss, getComponentCss$9 as getTabsCss, getComponentCss$a as getTabsItemCss, getComponentCss$7 as getTagCss, getComponentCss$8 as getTagDismissibleCss, getComponentCss$4 as getTextCss, getComponentCss$6 as getTextListCss, getComponentCss$5 as getTextListItemCss, getComponentCss$3 as getTextareaCss, getComponentCss$1 as getToastCss, getComponentCss as getWordmarkCss };
10447
+ export { cssVarButtonPureMargin, cssVarButtonPurePadding, cssVarInternalInputBaseScaling, dialogBorderRadius, dialogGridJssStyle, dialogHostJssStyle, dialogPaddingBottom, dialogPaddingInline, dialogPaddingTop, getComponentCss$1a as getAccordionCss, getComponentCss$19 as getAiTagCss, getComponentCss$18 as getBannerCss, getComponentCss$15 as getButtonCss, getComponentCss$17 as getButtonPureCss, getComponentCss$16 as getButtonTileCss, getComponentCss$14 as getCanvasCss, getComponentCss$13 as getCarouselCss, getComponentCss$12 as getCheckboxCss, getComponentCss$11 as getCrestCss, getDialogColorJssStyle, getDialogDismissButtonJssStyle, getDialogTransitionJssStyle, getComponentCss$10 as getDisplayCss, getComponentCss$$ as getDividerCss, getComponentCss$_ as getDrilldownCss, getComponentCss$Z as getDrilldownItemCss, getComponentCss$Y as getDrilldownLinkCss, getFCDismissButtonStyles, getComponentCss$X as getFieldsetCss, getComponentCss$W as getFlagCss, getComponentCss$V as getFlyoutCss, getFunctionalComponentDialogBaseStyles, getFunctionalComponentInputBaseStyles, getFunctionalComponentLabelAfterStyles, getFunctionalComponentLabelStyles, getFunctionalComponentLoadingMessageStyles, getFunctionalComponentNoResultsOptionStyles, getFunctionalComponentNotificationBaseStyles, getFunctionalComponentRequiredStyles, getFunctionalComponentStateMessageStyles, getComponentCss$U as getHeadingCss, getComponentCss$T as getIconCss, getComponentCss$S as getInlineNotificationCss, getComponentCss$R as getInputDateCss, getComponentCss$Q as getInputEmailCss, getComponentCss$P as getInputMonthCss, getComponentCss$O as getInputNumberCss, getComponentCss$N as getInputPasswordCss, getComponentCss$M as getInputSearchCss, getComponentCss$L as getInputTelCss, getComponentCss$K as getInputTextCss, getComponentCss$J as getInputTimeCss, getComponentCss$I as getInputUrlCss, getComponentCss$H as getInputWeekCss, getComponentCss$D as getLinkCss, getComponentCss$G as getLinkPureCss, getComponentCss$E as getLinkTileCss, getComponentCss$F as getLinkTileProductCss, getComponentCss$C as getModalCss, getComponentCss$B as getModelSignatureCss, getComponentCss$y as getMultiSelectCss, getComponentCss$A as getMultiSelectOptionCss, getComponentCss$z as getOptgroupCss, getComponentCss$x as getPaginationCss, getComponentCss$w as getPinCodeCss, getComponentCss$v as getPopoverCss, getComponentCss$t as getRadioGroupCss, getComponentCss$u as getRadioGroupOptionCss, getComponentCss$s as getScrollerCss, getScrollerJssStyle, getComponentCss$q as getSegmentedControlCss, getComponentCss$r as getSegmentedControlItemCss, getComponentCss$o as getSelectCss, getComponentCss$p as getSelectOptionCss, getComponentCss$n as getSheetCss, getSlotFooterJssStyle, getSlotHeaderJssStyle, getSlotJssStyle, getSlotMainJssStyle, getSlotSubFooterJssStyle, getComponentCss$m as getSpinnerCss, getComponentCss$k as getStepperHorizontalCss, getComponentCss$l as getStepperHorizontalItemCss, getComponentCss$j as getSwitchCss, getComponentCss$i as getTableBodyCss, getComponentCss$g as getTableCellCss, getComponentCss$h as getTableCss, getComponentCss$f as getTableHeadCellCss, getComponentCss$d as getTableHeadCss, getComponentCss$e as getTableHeadRowCss, getComponentCss$c as getTableRowCss, getComponentCss$b as getTabsBarCss, getComponentCss$9 as getTabsCss, getComponentCss$a as getTabsItemCss, getComponentCss$7 as getTagCss, getComponentCss$8 as getTagDismissibleCss, getComponentCss$4 as getTextCss, getComponentCss$6 as getTextListCss, getComponentCss$5 as getTextListItemCss, getComponentCss$3 as getTextareaCss, getComponentCss$1 as getToastCss, getComponentCss as getWordmarkCss };