@porsche-design-system/components-react 4.2.0-rc.2 → 4.2.0-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -14,6 +14,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0),
14
14
 
15
15
  ## [Unreleased]
16
16
 
17
+ ## [4.2.0-rc.4] - 2026-06-10
18
+
19
+ ### Fixed
20
+
21
+ - `Radio Group`: Prevent clicks on `label-after` slot from bubbling to the host element
22
+ ([#4477](https://github.com/porsche-design-system/porsche-design-system/pull/4477))
23
+ - `Flyout`, `Modal`, `Sheet`: Prevent dialog elements from reserving layout space in closed state when placed within a
24
+ new stacking context ([#4494](https://github.com/porsche-design-system/porsche-design-system/pull/4494))
25
+
26
+ ## [4.2.0-rc.3] - 2026-06-09
27
+
28
+ ### Fixed
29
+
30
+ - `Flyout`, `Modal`, `Sheet`: content no longer disappears in Chromium when many elements with a frosted
31
+ `backdrop-filter` (e.g. `p-tag`) are rendered
32
+ ([#4490](https://github.com/porsche-design-system/porsche-design-system/pull/4490))
33
+
17
34
  ## [4.2.0-rc.2] - 2026-06-04
18
35
 
19
36
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@porsche-design-system/components-react",
3
- "version": "4.2.0-rc.2",
3
+ "version": "4.2.0-rc.4",
4
4
  "description": "Porsche Design System is a component library designed to help developers create the best experience for software or services distributed by Dr. Ing. h.c. F. Porsche AG.",
5
5
  "keywords": [
6
6
  "porsche",
@@ -21,7 +21,7 @@
21
21
  "url": "https://github.com/porsche-design-system/porsche-design-system"
22
22
  },
23
23
  "dependencies": {
24
- "@porsche-design-system/components-js": "4.2.0-rc.2"
24
+ "@porsche-design-system/components-js": "4.2.0-rc.4"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "ag-grid-community": ">= 35.0.0 <36.0.0",
@@ -4132,7 +4132,7 @@ const OPTION_LIST_SAFE_ZONE = 6;
4132
4132
 
4133
4133
  const getCDNBaseURL = () => global.PORSCHE_DESIGN_SYSTEM_CDN_URL + "/porsche-design-system";
4134
4134
 
4135
- const prefix = `[Porsche Design System v${"4.2.0-rc.2"}]` // this part isn't covered by unit tests
4135
+ const prefix = `[Porsche Design System v${"4.2.0-rc.4"}]` // this part isn't covered by unit tests
4136
4136
  ;
4137
4137
  const consoleError = (...messages) => {
4138
4138
  console.error(prefix, ...messages);
@@ -5899,15 +5899,20 @@ const getFunctionalComponentRequiredStyles = () => {
5899
5899
  };
5900
5900
 
5901
5901
  const getFunctionalComponentLabelAfterStyles = () => {
5902
+ const labelAfterStyles = {
5903
+ display: 'inline-block',
5904
+ verticalAlign: 'top',
5905
+ '&::slotted(*)': {
5906
+ ...addImportantToEachRule({
5907
+ marginInlineStart: ref(spacingStaticXs),
5908
+ }),
5909
+ },
5910
+ };
5902
5911
  return {
5903
- 'slot[name="label-after"]': {
5904
- display: 'inline-block',
5905
- verticalAlign: 'top',
5906
- '&::slotted(*)': {
5907
- ...addImportantToEachRule({
5908
- marginInlineStart: ref(spacingStaticXs),
5909
- }),
5910
- },
5912
+ 'slot[name="label-after"]': labelAfterStyles,
5913
+ '.label-after': {
5914
+ display: labelAfterStyles.display,
5915
+ verticalAlign: labelAfterStyles.verticalAlign,
5911
5916
  },
5912
5917
  };
5913
5918
  };
@@ -6061,18 +6066,14 @@ const getFunctionalComponentDialogBaseStyles = (isVisible, backdrop = 'blur') =>
6061
6066
  };
6062
6067
  };
6063
6068
  const dialogBackdropResetJssStyle = {
6064
- position: 'fixed', // ua-style
6065
- inset: 0, // ua-style
6066
- margin: 0, // ua-style
6067
- padding: 0, // ua-style
6068
- border: 0, // ua-style
6069
- width: '100dvw', // ua-style
6070
- height: '100dvh', // ua-style
6071
- maxWidth: '100dvw', // ua-style
6072
- maxHeight: '100dvh', // ua-style
6073
- overflow: 'hidden', // ua-style
6074
- display: 'block', // ua-style
6075
- outline: 0, // ua-style (we always expect a focusable element to be within the dialog)
6069
+ all: 'unset',
6070
+ position: 'fixed',
6071
+ inset: 0,
6072
+ maxWidth: '100dvw',
6073
+ maxHeight: '100dvh',
6074
+ overflow: 'hidden',
6075
+ display: 'block',
6076
+ outline: 0, // we always expect a focusable element to be within the dialog
6076
6077
  '&::backdrop': {
6077
6078
  display: 'none', // ua-style (we can't use it atm because it's not animatable in all browsers)
6078
6079
  },
@@ -6081,12 +6082,15 @@ const getDialogBackdropTransitionJssStyle = (isVisible, backdrop = 'blur') => {
6081
6082
  const isBackdropBlur = backdrop === 'blur';
6082
6083
  const duration = isVisible ? 'long' : 'moderate';
6083
6084
  const easing = isVisible ? 'in' : 'out';
6085
+ const delay = ref(cssVariableTransitionDuration, isVisible ? '0s' : motionDurationMap[duration]);
6084
6086
  // as soon as all browsers are supporting `allow-discrete`, visibility transition shouldn't be necessary anymore
6085
- const transition = `visibility 0s linear ${ref(cssVariableTransitionDuration, isVisible ? '0s' : motionDurationMap[duration])}, ${getTransition('background-color', duration, easing)}, ${getTransition('-webkit-backdrop-filter', duration, easing)}, ${getTransition('backdrop-filter', duration, easing)}`;
6087
+ 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)}`;
6086
6088
  return {
6087
6089
  zIndex: 9999999, // fallback for fade out stacking until `overlay` + `allow-discrete` is supported in all browsers. It tries to mimic #top-layer positioning hierarchy.
6088
6090
  ...(isVisible
6089
6091
  ? {
6092
+ width: '100dvw',
6093
+ height: '100dvh',
6090
6094
  visibility: 'inherit',
6091
6095
  pointerEvents: 'auto',
6092
6096
  background: ref(colorBackdrop),
@@ -6096,6 +6100,12 @@ const getDialogBackdropTransitionJssStyle = (isVisible, backdrop = 'blur') => {
6096
6100
  }),
6097
6101
  }
6098
6102
  : {
6103
+ // When the dialog lives inside a new stacking context, it is no longer promoted to the #top-layer while closed.
6104
+ // In that case it can reserve additional space and break the surrounding layout, so width and height are collapsed to zero.
6105
+ // A future improvement could use `transition-behavior: allow-discrete` to toggle between `display: none` and `block`,
6106
+ // but browser support is still insufficient and behaves inconsistently in Safari and Firefox.
6107
+ width: '0px',
6108
+ height: '0px',
6099
6109
  visibility: 'hidden', // element shall not be tabbable with keyboard after fade out transition has finished
6100
6110
  pointerEvents: 'none', // element can't be interacted with mouse
6101
6111
  background: 'transparent',
@@ -6139,7 +6149,7 @@ const dialogBorderRadius = ref(radius3Xl);
6139
6149
  const dialogPaddingTop = ref(spacingFluidMd$1);
6140
6150
  const dialogPaddingBottom = `calc(${dialogBorderRadius} + ${ref(spacingFluidMd$1)})`;
6141
6151
  const dialogPaddingInline = ref(spacingFluidLg);
6142
- const dialogGridJssStyle = () => {
6152
+ const dialogGridJssStyle = (clipPath = 'none') => {
6143
6153
  return {
6144
6154
  position: 'relative',
6145
6155
  display: 'grid',
@@ -6148,7 +6158,8 @@ const dialogGridJssStyle = () => {
6148
6158
  paddingTop: dialogPaddingTop,
6149
6159
  paddingBottom: dialogPaddingBottom,
6150
6160
  alignContent: 'flex-start',
6151
- overflow: 'clip',
6161
+ // `overflow: clip` can't be used due to a Chromium bug that drops descendant backdrop-filter tiles (e.g. frosted p-tag); `clip-path` clips slotted content to the rounded corners without the faulty paint-containment box while keeping the scroll behavior intact
6162
+ clipPath,
6152
6163
  };
6153
6164
  };
6154
6165
  const getDialogColorJssStyle = () => {
@@ -7334,11 +7345,20 @@ const getComponentCss$V = (isOpen, background, backdrop, position, hasHeader, ha
7334
7345
  },
7335
7346
  },
7336
7347
  flyout: {
7337
- ...dialogGridJssStyle(),
7348
+ ...dialogGridJssStyle(isPositionStart
7349
+ ? `inset(0 round 0 ${dialogBorderRadius} ${dialogBorderRadius} 0)` // position 'start': round inline-end (right in LTR) corners only
7350
+ : `inset(0 round ${dialogBorderRadius} 0 0 ${dialogBorderRadius})` // position 'end': round inline-start (left in LTR) corners only
7351
+ ),
7338
7352
  ...getDialogColorJssStyle(),
7339
7353
  width: ref(cssVariableWidth$2, 'auto'),
7340
7354
  minWidth: '320px',
7341
7355
  maxWidth: '100vw',
7356
+ // `clip-path` uses physical corners, so mirror for RTL to keep parity with the logical border*Radius below
7357
+ '&:dir(rtl)': {
7358
+ clipPath: isPositionStart
7359
+ ? `inset(0 round ${dialogBorderRadius} 0 0 ${dialogBorderRadius})`
7360
+ : `inset(0 round 0 ${dialogBorderRadius} ${dialogBorderRadius} 0)`,
7361
+ },
7342
7362
  ...(isPositionStart
7343
7363
  ? {
7344
7364
  borderStartEndRadius: dialogBorderRadius,
@@ -8147,7 +8167,7 @@ const getComponentCss$C = (isOpen, background, backdrop, fullscreen, hasDismissB
8147
8167
  },
8148
8168
  scroller: getScrollerJssStyle('fullscreen'),
8149
8169
  modal: {
8150
- ...dialogGridJssStyle(),
8170
+ ...dialogGridJssStyle(`inset(0 round ${dialogBorderRadius})`),
8151
8171
  ...getDialogColorJssStyle(),
8152
8172
  ...getDialogTransitionJssStyle(isOpen, '^'),
8153
8173
  ...buildResponsiveStyles(fullscreen, (fullscreenValue) => fullscreenValue
@@ -8158,6 +8178,7 @@ const getComponentCss$C = (isOpen, background, backdrop, fullscreen, hasDismissB
8158
8178
  placeSelf: 'stretch',
8159
8179
  margin: 0,
8160
8180
  borderRadius: 0,
8181
+ clipPath: 'none', // fullscreen has square corners, so disable corner clipping
8161
8182
  }
8162
8183
  : {
8163
8184
  width: ref(cssVariableWidth$1, 'auto'),
@@ -9218,7 +9239,7 @@ const getComponentCss$n = (isOpen, background, hasDismissButton) => {
9218
9239
  },
9219
9240
  scroller: getScrollerJssStyle('fullscreen'),
9220
9241
  sheet: {
9221
- ...dialogGridJssStyle(),
9242
+ ...dialogGridJssStyle(`inset(0 round ${dialogBorderRadius} ${dialogBorderRadius} 0 0)`), // round top corners only
9222
9243
  ...getDialogColorJssStyle(),
9223
9244
  ...getDialogTransitionJssStyle(isOpen, '^'),
9224
9245
  width: '100%',
@@ -3465,7 +3465,7 @@ const hasShowPickerSupport = () => (hasDocument &&
3465
3465
  'showPicker' in HTMLInputElement.prototype &&
3466
3466
  CSS.supports('selector(::-webkit-calendar-picker-indicator)'));
3467
3467
 
3468
- const prefix = `[Porsche Design System v${"4.2.0-rc.2"}]` // this part isn't covered by unit tests
3468
+ const prefix = `[Porsche Design System v${"4.2.0-rc.4"}]` // this part isn't covered by unit tests
3469
3469
  ;
3470
3470
  const consoleError$1 = (...messages) => {
3471
3471
  console.error(prefix, ...messages);
@@ -10,7 +10,7 @@ const Label = ({ hasLabel, hasDescription, children,
10
10
  label, tag, description, htmlFor, isRequired, isLoading, isDisabled, stopClickPropagation, }) => {
11
11
  splitChildren.splitChildren(children);
12
12
  const TagType = tag || 'label';
13
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [hasLabel && (jsxRuntime.jsxs("div", { className: "label-wrapper", children: [jsxRuntime.jsx(TagType, { className: "label", id: utilsEntry.labelId, "aria-disabled": isLoading || isDisabled ? 'true' : null, htmlFor: htmlFor, children: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [label || jsxRuntime.jsx("slot", { name: "label" }), isRequired /* && !isParentFieldsetRequired(host) */ && jsxRuntime.jsx(required.Required, {})] }) }), jsxRuntime.jsx("slot", { name: "label-after" })] })), hasDescription && (jsxRuntime.jsx("span", { className: "label", id: utilsEntry.descriptionId, "aria-disabled": isLoading || isDisabled ? 'true' : null, children: description || jsxRuntime.jsx("slot", { name: "description" }) }))] }));
13
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [hasLabel && (jsxRuntime.jsxs("div", { className: "label-wrapper", children: [jsxRuntime.jsx(TagType, { className: "label", id: utilsEntry.labelId, "aria-disabled": isLoading || isDisabled ? 'true' : null, htmlFor: htmlFor, children: jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [label || jsxRuntime.jsx("slot", { name: "label" }), isRequired /* && !isParentFieldsetRequired(host) */ && jsxRuntime.jsx(required.Required, {})] }) }), stopClickPropagation ? (jsxRuntime.jsx("span", { className: "label-after", children: jsxRuntime.jsx("slot", { name: "label-after" }) })) : (jsxRuntime.jsx("slot", { name: "label-after" }))] })), hasDescription && (jsxRuntime.jsx("span", { className: "label", id: utilsEntry.descriptionId, "aria-disabled": isLoading || isDisabled ? 'true' : null, children: description || jsxRuntime.jsx("slot", { name: "description" }) }))] }));
14
14
  };
15
15
 
16
16
  exports.Label = Label;
@@ -4130,7 +4130,7 @@ const OPTION_LIST_SAFE_ZONE = 6;
4130
4130
 
4131
4131
  const getCDNBaseURL = () => global.PORSCHE_DESIGN_SYSTEM_CDN_URL + "/porsche-design-system";
4132
4132
 
4133
- const prefix = `[Porsche Design System v${"4.2.0-rc.2"}]` // this part isn't covered by unit tests
4133
+ const prefix = `[Porsche Design System v${"4.2.0-rc.4"}]` // this part isn't covered by unit tests
4134
4134
  ;
4135
4135
  const consoleError = (...messages) => {
4136
4136
  console.error(prefix, ...messages);
@@ -5897,15 +5897,20 @@ const getFunctionalComponentRequiredStyles = () => {
5897
5897
  };
5898
5898
 
5899
5899
  const getFunctionalComponentLabelAfterStyles = () => {
5900
+ const labelAfterStyles = {
5901
+ display: 'inline-block',
5902
+ verticalAlign: 'top',
5903
+ '&::slotted(*)': {
5904
+ ...addImportantToEachRule({
5905
+ marginInlineStart: ref(spacingStaticXs),
5906
+ }),
5907
+ },
5908
+ };
5900
5909
  return {
5901
- 'slot[name="label-after"]': {
5902
- display: 'inline-block',
5903
- verticalAlign: 'top',
5904
- '&::slotted(*)': {
5905
- ...addImportantToEachRule({
5906
- marginInlineStart: ref(spacingStaticXs),
5907
- }),
5908
- },
5910
+ 'slot[name="label-after"]': labelAfterStyles,
5911
+ '.label-after': {
5912
+ display: labelAfterStyles.display,
5913
+ verticalAlign: labelAfterStyles.verticalAlign,
5909
5914
  },
5910
5915
  };
5911
5916
  };
@@ -6059,18 +6064,14 @@ const getFunctionalComponentDialogBaseStyles = (isVisible, backdrop = 'blur') =>
6059
6064
  };
6060
6065
  };
6061
6066
  const dialogBackdropResetJssStyle = {
6062
- position: 'fixed', // ua-style
6063
- inset: 0, // ua-style
6064
- margin: 0, // ua-style
6065
- padding: 0, // ua-style
6066
- border: 0, // ua-style
6067
- width: '100dvw', // ua-style
6068
- height: '100dvh', // ua-style
6069
- maxWidth: '100dvw', // ua-style
6070
- maxHeight: '100dvh', // ua-style
6071
- overflow: 'hidden', // ua-style
6072
- display: 'block', // ua-style
6073
- outline: 0, // ua-style (we always expect a focusable element to be within the dialog)
6067
+ all: 'unset',
6068
+ position: 'fixed',
6069
+ inset: 0,
6070
+ maxWidth: '100dvw',
6071
+ maxHeight: '100dvh',
6072
+ overflow: 'hidden',
6073
+ display: 'block',
6074
+ outline: 0, // we always expect a focusable element to be within the dialog
6074
6075
  '&::backdrop': {
6075
6076
  display: 'none', // ua-style (we can't use it atm because it's not animatable in all browsers)
6076
6077
  },
@@ -6079,12 +6080,15 @@ const getDialogBackdropTransitionJssStyle = (isVisible, backdrop = 'blur') => {
6079
6080
  const isBackdropBlur = backdrop === 'blur';
6080
6081
  const duration = isVisible ? 'long' : 'moderate';
6081
6082
  const easing = isVisible ? 'in' : 'out';
6083
+ const delay = ref(cssVariableTransitionDuration, isVisible ? '0s' : motionDurationMap[duration]);
6082
6084
  // as soon as all browsers are supporting `allow-discrete`, visibility transition shouldn't be necessary anymore
6083
- const transition = `visibility 0s linear ${ref(cssVariableTransitionDuration, isVisible ? '0s' : motionDurationMap[duration])}, ${getTransition('background-color', duration, easing)}, ${getTransition('-webkit-backdrop-filter', duration, easing)}, ${getTransition('backdrop-filter', duration, easing)}`;
6085
+ 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)}`;
6084
6086
  return {
6085
6087
  zIndex: 9999999, // fallback for fade out stacking until `overlay` + `allow-discrete` is supported in all browsers. It tries to mimic #top-layer positioning hierarchy.
6086
6088
  ...(isVisible
6087
6089
  ? {
6090
+ width: '100dvw',
6091
+ height: '100dvh',
6088
6092
  visibility: 'inherit',
6089
6093
  pointerEvents: 'auto',
6090
6094
  background: ref(colorBackdrop),
@@ -6094,6 +6098,12 @@ const getDialogBackdropTransitionJssStyle = (isVisible, backdrop = 'blur') => {
6094
6098
  }),
6095
6099
  }
6096
6100
  : {
6101
+ // When the dialog lives inside a new stacking context, it is no longer promoted to the #top-layer while closed.
6102
+ // In that case it can reserve additional space and break the surrounding layout, so width and height are collapsed to zero.
6103
+ // A future improvement could use `transition-behavior: allow-discrete` to toggle between `display: none` and `block`,
6104
+ // but browser support is still insufficient and behaves inconsistently in Safari and Firefox.
6105
+ width: '0px',
6106
+ height: '0px',
6097
6107
  visibility: 'hidden', // element shall not be tabbable with keyboard after fade out transition has finished
6098
6108
  pointerEvents: 'none', // element can't be interacted with mouse
6099
6109
  background: 'transparent',
@@ -6137,7 +6147,7 @@ const dialogBorderRadius = ref(radius3Xl);
6137
6147
  const dialogPaddingTop = ref(spacingFluidMd$1);
6138
6148
  const dialogPaddingBottom = `calc(${dialogBorderRadius} + ${ref(spacingFluidMd$1)})`;
6139
6149
  const dialogPaddingInline = ref(spacingFluidLg);
6140
- const dialogGridJssStyle = () => {
6150
+ const dialogGridJssStyle = (clipPath = 'none') => {
6141
6151
  return {
6142
6152
  position: 'relative',
6143
6153
  display: 'grid',
@@ -6146,7 +6156,8 @@ const dialogGridJssStyle = () => {
6146
6156
  paddingTop: dialogPaddingTop,
6147
6157
  paddingBottom: dialogPaddingBottom,
6148
6158
  alignContent: 'flex-start',
6149
- overflow: 'clip',
6159
+ // `overflow: clip` can't be used due to a Chromium bug that drops descendant backdrop-filter tiles (e.g. frosted p-tag); `clip-path` clips slotted content to the rounded corners without the faulty paint-containment box while keeping the scroll behavior intact
6160
+ clipPath,
6150
6161
  };
6151
6162
  };
6152
6163
  const getDialogColorJssStyle = () => {
@@ -7332,11 +7343,20 @@ const getComponentCss$V = (isOpen, background, backdrop, position, hasHeader, ha
7332
7343
  },
7333
7344
  },
7334
7345
  flyout: {
7335
- ...dialogGridJssStyle(),
7346
+ ...dialogGridJssStyle(isPositionStart
7347
+ ? `inset(0 round 0 ${dialogBorderRadius} ${dialogBorderRadius} 0)` // position 'start': round inline-end (right in LTR) corners only
7348
+ : `inset(0 round ${dialogBorderRadius} 0 0 ${dialogBorderRadius})` // position 'end': round inline-start (left in LTR) corners only
7349
+ ),
7336
7350
  ...getDialogColorJssStyle(),
7337
7351
  width: ref(cssVariableWidth$2, 'auto'),
7338
7352
  minWidth: '320px',
7339
7353
  maxWidth: '100vw',
7354
+ // `clip-path` uses physical corners, so mirror for RTL to keep parity with the logical border*Radius below
7355
+ '&:dir(rtl)': {
7356
+ clipPath: isPositionStart
7357
+ ? `inset(0 round ${dialogBorderRadius} 0 0 ${dialogBorderRadius})`
7358
+ : `inset(0 round 0 ${dialogBorderRadius} ${dialogBorderRadius} 0)`,
7359
+ },
7340
7360
  ...(isPositionStart
7341
7361
  ? {
7342
7362
  borderStartEndRadius: dialogBorderRadius,
@@ -8145,7 +8165,7 @@ const getComponentCss$C = (isOpen, background, backdrop, fullscreen, hasDismissB
8145
8165
  },
8146
8166
  scroller: getScrollerJssStyle('fullscreen'),
8147
8167
  modal: {
8148
- ...dialogGridJssStyle(),
8168
+ ...dialogGridJssStyle(`inset(0 round ${dialogBorderRadius})`),
8149
8169
  ...getDialogColorJssStyle(),
8150
8170
  ...getDialogTransitionJssStyle(isOpen, '^'),
8151
8171
  ...buildResponsiveStyles(fullscreen, (fullscreenValue) => fullscreenValue
@@ -8156,6 +8176,7 @@ const getComponentCss$C = (isOpen, background, backdrop, fullscreen, hasDismissB
8156
8176
  placeSelf: 'stretch',
8157
8177
  margin: 0,
8158
8178
  borderRadius: 0,
8179
+ clipPath: 'none', // fullscreen has square corners, so disable corner clipping
8159
8180
  }
8160
8181
  : {
8161
8182
  width: ref(cssVariableWidth$1, 'auto'),
@@ -9216,7 +9237,7 @@ const getComponentCss$n = (isOpen, background, hasDismissButton) => {
9216
9237
  },
9217
9238
  scroller: getScrollerJssStyle('fullscreen'),
9218
9239
  sheet: {
9219
- ...dialogGridJssStyle(),
9240
+ ...dialogGridJssStyle(`inset(0 round ${dialogBorderRadius} ${dialogBorderRadius} 0 0)`), // round top corners only
9220
9241
  ...getDialogColorJssStyle(),
9221
9242
  ...getDialogTransitionJssStyle(isOpen, '^'),
9222
9243
  width: '100%',
@@ -3463,7 +3463,7 @@ const hasShowPickerSupport = () => (hasDocument &&
3463
3463
  'showPicker' in HTMLInputElement.prototype &&
3464
3464
  CSS.supports('selector(::-webkit-calendar-picker-indicator)'));
3465
3465
 
3466
- const prefix = `[Porsche Design System v${"4.2.0-rc.2"}]` // this part isn't covered by unit tests
3466
+ const prefix = `[Porsche Design System v${"4.2.0-rc.4"}]` // this part isn't covered by unit tests
3467
3467
  ;
3468
3468
  const consoleError$1 = (...messages) => {
3469
3469
  console.error(prefix, ...messages);
@@ -8,7 +8,7 @@ const Label = ({ hasLabel, hasDescription, children,
8
8
  label, tag, description, htmlFor, isRequired, isLoading, isDisabled, stopClickPropagation, }) => {
9
9
  splitChildren(children);
10
10
  const TagType = tag || 'label';
11
- return (jsxs(Fragment, { children: [hasLabel && (jsxs("div", { className: "label-wrapper", children: [jsx(TagType, { className: "label", id: labelId, "aria-disabled": isLoading || isDisabled ? 'true' : null, htmlFor: htmlFor, children: jsxs(Fragment, { children: [label || jsx("slot", { name: "label" }), isRequired /* && !isParentFieldsetRequired(host) */ && jsx(Required, {})] }) }), jsx("slot", { name: "label-after" })] })), hasDescription && (jsx("span", { className: "label", id: descriptionId, "aria-disabled": isLoading || isDisabled ? 'true' : null, children: description || jsx("slot", { name: "description" }) }))] }));
11
+ return (jsxs(Fragment, { children: [hasLabel && (jsxs("div", { className: "label-wrapper", children: [jsx(TagType, { className: "label", id: labelId, "aria-disabled": isLoading || isDisabled ? 'true' : null, htmlFor: htmlFor, children: jsxs(Fragment, { children: [label || jsx("slot", { name: "label" }), isRequired /* && !isParentFieldsetRequired(host) */ && jsx(Required, {})] }) }), stopClickPropagation ? (jsx("span", { className: "label-after", children: jsx("slot", { name: "label-after" }) })) : (jsx("slot", { name: "label-after" }))] })), hasDescription && (jsx("span", { className: "label", id: descriptionId, "aria-disabled": isLoading || isDisabled ? 'true' : null, children: description || jsx("slot", { name: "description" }) }))] }));
12
12
  };
13
13
 
14
14
  export { Label };
@@ -14,8 +14,8 @@ type LabelProps = {
14
14
  isLoading?: boolean;
15
15
  isDisabled?: boolean;
16
16
  /**
17
- * If true, clicking the label will not bubble to the host element,
18
- * preventing duplicate handling on host click listeners.
17
+ * If true, clicks on the label use `htmlFor` only and do not bubble to the host.
18
+ * Clicks on the `label-after` slot are also stopped so they do not trigger host handlers (e.g. radio selection).
19
19
  */
20
20
  stopClickPropagation?: boolean;
21
21
  };