@porsche-design-system/components-react 4.4.0-rc.0 → 4.4.0
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 +12 -0
- package/package.json +2 -2
- package/ssr/cjs/components/dist/styles/esm/styles-entry.cjs +164 -68
- package/ssr/cjs/components/dist/utils/esm/utils-entry.cjs +1 -1
- package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/banner.cjs +15 -5
- package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/dialog-base.cjs +3 -7
- package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/drilldown.cjs +3 -0
- package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/fc-dismiss-button.cjs +16 -0
- package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/flyout.cjs +14 -1
- package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/inline-notification.cjs +2 -2
- package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/modal.cjs +14 -1
- package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/popover.cjs +5 -1
- package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/sheet.cjs +14 -1
- package/ssr/esm/components/dist/styles/esm/styles-entry.mjs +164 -69
- package/ssr/esm/components/dist/utils/esm/utils-entry.mjs +1 -1
- package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/banner.mjs +15 -5
- package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/dialog-base.mjs +3 -7
- package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/drilldown.mjs +3 -0
- package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/fc-dismiss-button.mjs +14 -0
- package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/flyout.mjs +14 -1
- package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/inline-notification.mjs +2 -2
- package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/modal.mjs +14 -1
- package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/popover.mjs +5 -1
- package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/sheet.mjs +14 -1
- package/ssr/esm/lib/dsr-components/banner.d.ts +2 -0
- package/ssr/esm/lib/dsr-components/dialog-base.d.ts +2 -2
- package/ssr/esm/lib/dsr-components/drilldown.d.ts +1 -0
- package/ssr/esm/lib/dsr-components/fc-dismiss-button.d.ts +16 -0
- package/ssr/esm/lib/dsr-components/flyout.d.ts +1 -0
- package/ssr/esm/lib/dsr-components/modal.d.ts +1 -0
- package/ssr/esm/lib/dsr-components/popover.d.ts +1 -0
- package/ssr/esm/lib/dsr-components/sheet.d.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0),
|
|
|
14
14
|
|
|
15
15
|
## [Unreleased]
|
|
16
16
|
|
|
17
|
+
## [4.4.0] - 2026-07-15
|
|
18
|
+
|
|
19
|
+
## [4.4.0-rc.1] - 2026-07-10
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- `Flyout`, `Modal`, `Sheet` ([#4578](https://github.com/porsche-design-system/porsche-design-system/pull/4578)):
|
|
24
|
+
- enable selecting text within dialog element
|
|
25
|
+
- prevent dialog from being dismissed when a text selection started inside the dialog is released on the backdrop
|
|
26
|
+
- `Popover`, `Banner`: prevent entry animation from playing when initially rendered in an open state
|
|
27
|
+
([#4578](https://github.com/porsche-design-system/porsche-design-system/pull/4578))
|
|
28
|
+
|
|
17
29
|
## [4.4.0-rc.0] - 2026-07-06
|
|
18
30
|
|
|
19
31
|
### Added
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@porsche-design-system/components-react",
|
|
3
|
-
"version": "4.4.0
|
|
3
|
+
"version": "4.4.0",
|
|
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.4.0
|
|
24
|
+
"@porsche-design-system/components-js": "4.4.0"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
27
|
"ag-grid-community": ">= 35.0.0 <36.0.0",
|
|
@@ -3849,7 +3849,7 @@ const OPTION_LIST_SAFE_ZONE = 6;
|
|
|
3849
3849
|
|
|
3850
3850
|
const getCDNBaseURL = () => global.PORSCHE_DESIGN_SYSTEM_CDN_URL + "/porsche-design-system";
|
|
3851
3851
|
|
|
3852
|
-
const prefix = `[Porsche Design System v${"4.4.0
|
|
3852
|
+
const prefix = `[Porsche Design System v${"4.4.0"}]` // this part isn't covered by unit tests
|
|
3853
3853
|
;
|
|
3854
3854
|
const consoleError = (...messages) => {
|
|
3855
3855
|
console.error(prefix, ...messages);
|
|
@@ -4222,9 +4222,6 @@ const getComponentCss$19 = () => {
|
|
|
4222
4222
|
});
|
|
4223
4223
|
};
|
|
4224
4224
|
|
|
4225
|
-
const TOAST_Z_INDEX = 999999;
|
|
4226
|
-
const BANNER_Z_INDEX = 99;
|
|
4227
|
-
|
|
4228
4225
|
const colorMap$3 = {
|
|
4229
4226
|
primary: ref(colorPrimary),
|
|
4230
4227
|
'contrast-higher': ref(colorContrastHigher),
|
|
@@ -4289,6 +4286,86 @@ const weightMap = {
|
|
|
4289
4286
|
bold: ref(fontWeightBold),
|
|
4290
4287
|
};
|
|
4291
4288
|
|
|
4289
|
+
// Inlined `close` icon (mirrors packages/assets/projects/icons/src/close.svg) rendered as a CSS mask, so the dismiss
|
|
4290
|
+
// button needs neither a nested `p-button` nor a `p-icon` (which would fetch the SVG from the CDN asynchronously).
|
|
4291
|
+
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"/>');
|
|
4292
|
+
// NOTE: Values copied (and reduced to the fixed `compact` + `hideLabel` case the dismiss button always uses) from
|
|
4293
|
+
// `getVariantColors` in `packages/components/src/styles/link-button-styles.ts` to keep the visual identical to the
|
|
4294
|
+
// previously nested `p-button`. If the shared button styling changes, mirror it here (or extract a shared helper).
|
|
4295
|
+
const getVariantColors$1 = (variant) => {
|
|
4296
|
+
const colors = {
|
|
4297
|
+
primary: {
|
|
4298
|
+
textColor: ref(colorCanvas),
|
|
4299
|
+
backgroundColor: ref(colorPrimary),
|
|
4300
|
+
backgroundColorHover: ref(colorContrastHigh),
|
|
4301
|
+
},
|
|
4302
|
+
secondary: {
|
|
4303
|
+
textColor: ref(colorPrimary),
|
|
4304
|
+
backgroundColor: ref(colorFrostedStrong),
|
|
4305
|
+
backgroundColorHover: ref(colorFrosted),
|
|
4306
|
+
},
|
|
4307
|
+
};
|
|
4308
|
+
return colors[variant];
|
|
4309
|
+
};
|
|
4310
|
+
/**
|
|
4311
|
+
* Visual styles for the shared native `<button class="dismiss">` dismiss button. Returns the button rule (reset,
|
|
4312
|
+
* variant colors, focus ring, High Contrast Mode, hover, inlined close-icon mask and the visually-hidden label). Each
|
|
4313
|
+
* consumer merges this with its own positioning styles for the `dismiss` key (e.g. grid placement in
|
|
4314
|
+
* `notification-base-styles` / `dialog-base-styles`).
|
|
4315
|
+
*
|
|
4316
|
+
* Reduced to the dismiss button's fixed configuration (always `compact` + `hideLabel`): padding `6px`, full border
|
|
4317
|
+
* radius and no gap — the responsive `compact`/`hideLabel` branches from `getLinkButtonStyles` are therefore collapsed.
|
|
4318
|
+
*/
|
|
4319
|
+
const getFCDismissButtonStyles = (variant) => {
|
|
4320
|
+
const { textColor, backgroundColor, backgroundColorHover } = getVariantColors$1(variant);
|
|
4321
|
+
return {
|
|
4322
|
+
all: 'unset',
|
|
4323
|
+
boxSizing: 'border-box',
|
|
4324
|
+
display: 'grid',
|
|
4325
|
+
placeItems: 'center',
|
|
4326
|
+
padding: '6px',
|
|
4327
|
+
borderRadius: ref(radiusFull),
|
|
4328
|
+
font: `${ref(fontWeightNormal$1)} ${ref(typescaleSm$1)} / ${ref(leadingNormal$1)} ${ref(fontPorscheNext$1)}`,
|
|
4329
|
+
backgroundColor,
|
|
4330
|
+
color: textColor,
|
|
4331
|
+
cursor: 'pointer',
|
|
4332
|
+
// The frosted backdrop-filter is only meaningful for the translucent `secondary` (frosted) background. For the
|
|
4333
|
+
// opaque `primary` background it is invisible AND — because the dialog consumer additionally applies
|
|
4334
|
+
// `filter: invert(1)` on the same element (see `getDialogDismissButtonJssStyle`) — the blurred backdrop bleeds past
|
|
4335
|
+
// the circular edge and the invert amplifies it into a visible glow/halo. So it is applied for `secondary` only.
|
|
4336
|
+
...(variant === 'secondary' && {
|
|
4337
|
+
WebkitBackdropFilter: ref(blurFrosted),
|
|
4338
|
+
backdropFilter: ref(blurFrosted),
|
|
4339
|
+
}),
|
|
4340
|
+
transition: `${getTransition('background-color')}, ${getTransition('color')}`,
|
|
4341
|
+
...forcedColorsMediaQuery({
|
|
4342
|
+
forcedColorAdjust: 'none',
|
|
4343
|
+
background: 'Canvas',
|
|
4344
|
+
boxShadow: 'inset 0 0 0 2px ButtonBorder',
|
|
4345
|
+
color: 'ButtonText',
|
|
4346
|
+
}),
|
|
4347
|
+
'&:focus-visible': getFocusBaseStyles(),
|
|
4348
|
+
...hoverMediaQuery({
|
|
4349
|
+
'&:hover': {
|
|
4350
|
+
backgroundColor: backgroundColorHover,
|
|
4351
|
+
...forcedColorsMediaQuery({
|
|
4352
|
+
background: 'Canvas',
|
|
4353
|
+
}),
|
|
4354
|
+
},
|
|
4355
|
+
}),
|
|
4356
|
+
'&::before': {
|
|
4357
|
+
content: '""',
|
|
4358
|
+
width: ref(leadingNormal$1),
|
|
4359
|
+
height: ref(leadingNormal$1),
|
|
4360
|
+
WebkitMask: `${iconClose} center/contain no-repeat`, // necessary for Sogou browser support :-)
|
|
4361
|
+
mask: `${iconClose} center/contain no-repeat`,
|
|
4362
|
+
background: 'currentColor', // follows the button's text color (variant + HCM `ButtonText`)
|
|
4363
|
+
},
|
|
4364
|
+
// visually-hidden accessible name (mirrors `hideLabel` on the former `p-button`)
|
|
4365
|
+
'& span': getHiddenTextJssStyle(),
|
|
4366
|
+
};
|
|
4367
|
+
};
|
|
4368
|
+
|
|
4292
4369
|
const getFunctionalComponentNotificationBaseStyles = (state, hasAction, hasDismissButton, hasHeadingOrHeadingSlot) => {
|
|
4293
4370
|
return {
|
|
4294
4371
|
'@global': {
|
|
@@ -4339,6 +4416,8 @@ const getFunctionalComponentNotificationBaseStyles = (state, hasAction, hasDismi
|
|
|
4339
4416
|
},
|
|
4340
4417
|
...(hasDismissButton && {
|
|
4341
4418
|
dismiss: {
|
|
4419
|
+
// native dismiss button visual (secondary variant); grid positioning is applied on top
|
|
4420
|
+
...getFCDismissButtonStyles('secondary'),
|
|
4342
4421
|
gridArea: `1/4/-1`,
|
|
4343
4422
|
alignSelf: 'flex-start',
|
|
4344
4423
|
marginBlock: `calc(-6 * ${ref(spacingStatic2Xs)})`,
|
|
@@ -4379,12 +4458,12 @@ const cssVarInsetX = '--p-banner-inset-x';
|
|
|
4379
4458
|
const cssVarPositionTop = '--p-banner-position-top'; // deprecated (aliased)
|
|
4380
4459
|
const cssVarPositionBottom = '--p-banner-position-bottom'; // deprecated (aliased)
|
|
4381
4460
|
const topBottomFallback = '56px';
|
|
4382
|
-
const
|
|
4383
|
-
const getComponentCss$18 = (isOpen, position, state, hasDismissButton, hasHeadingOrHeadingSlot) => {
|
|
4461
|
+
const cssVarTransform = '--_p-banner-a';
|
|
4462
|
+
const getComponentCss$18 = (isOpen, position, state, hasDismissButton, hasHeadingOrHeadingSlot, skipEntryTransition) => {
|
|
4384
4463
|
const duration = isOpen ? 'moderate' : 'short';
|
|
4385
4464
|
const easing = isOpen ? 'in' : 'out';
|
|
4386
|
-
const transition =
|
|
4387
|
-
|
|
4465
|
+
const transition = getTransition('transform', duration, easing);
|
|
4466
|
+
const css = getCss({
|
|
4388
4467
|
...mergeDeep({
|
|
4389
4468
|
'@global': {
|
|
4390
4469
|
':host': {
|
|
@@ -4393,46 +4472,36 @@ const getComponentCss$18 = (isOpen, position, state, hasDismissButton, hasHeadin
|
|
|
4393
4472
|
...hostHiddenStyles,
|
|
4394
4473
|
}),
|
|
4395
4474
|
},
|
|
4396
|
-
...preventFoucOfNestedElementsStyles,
|
|
4397
4475
|
'[popover]': {
|
|
4398
4476
|
all: 'unset',
|
|
4399
4477
|
position: 'fixed',
|
|
4400
|
-
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.
|
|
4401
4478
|
...buildResponsiveStyles(position, (v) => ({
|
|
4402
4479
|
...(v === 'top' && {
|
|
4480
|
+
[cssVarTransform]: `translate3d(-50%,calc(-100% - ${ref(cssVarTop, ref(cssVarPositionTop, topBottomFallback))}),0)`,
|
|
4403
4481
|
insetBlock: `${ref(cssVarTop, ref(cssVarPositionTop, topBottomFallback))} auto`,
|
|
4404
|
-
...(!isOpen && {
|
|
4405
|
-
transform: `translate3d(-50%,calc(-100% - ${ref(cssVarTop, ref(cssVarPositionTop, topBottomFallback))}),0)`,
|
|
4406
|
-
}),
|
|
4407
4482
|
}),
|
|
4408
4483
|
...(v === 'bottom' && {
|
|
4484
|
+
[cssVarTransform]: `translate3d(-50%,calc(${ref(cssVarBottom, ref(cssVarPositionBottom, topBottomFallback))} + 100%),0)`,
|
|
4409
4485
|
insetBlock: `auto ${ref(cssVarBottom, ref(cssVarPositionBottom, topBottomFallback))}`,
|
|
4410
|
-
...(!isOpen && {
|
|
4411
|
-
transform: `translate3d(-50%,calc(${ref(cssVarBottom, ref(cssVarPositionBottom, topBottomFallback))} + 100%),0)`,
|
|
4412
|
-
}),
|
|
4413
4486
|
}),
|
|
4414
4487
|
})),
|
|
4415
4488
|
left: '50vw',
|
|
4416
4489
|
width: `min(calc(100vw - 2 * ${ref(cssVarInsetX, gridExtendedOffsetBase)}),${ref(cssVarMaxWidth, '100ch')})`,
|
|
4490
|
+
transform: isOpen ? 'translate3d(-50%,0,0)' : ref(cssVarTransform),
|
|
4491
|
+
transition,
|
|
4492
|
+
// keep the popover on the #top-layer while the fade-out runs (Chromium only; see `overlayTransitionSupportsQuery`)
|
|
4493
|
+
...overlayTransitionSupportsQuery({
|
|
4494
|
+
transition: `${transition},${getTransition('overlay', duration, easing)} allow-discrete, ${getTransition('display', duration, easing)} allow-discrete`,
|
|
4495
|
+
}),
|
|
4417
4496
|
overlay: 'none',
|
|
4497
|
+
display: 'none',
|
|
4418
4498
|
'&:popover-open': {
|
|
4419
4499
|
overlay: 'auto',
|
|
4500
|
+
display: 'grid',
|
|
4420
4501
|
},
|
|
4421
4502
|
'&::backdrop': {
|
|
4422
|
-
display: 'none',
|
|
4503
|
+
display: 'none', // reset ua-style
|
|
4423
4504
|
},
|
|
4424
|
-
visibility: 'hidden', // element shall not be tabbable with keyboard after fade out transition has finished
|
|
4425
|
-
pointerEvents: 'none', // element can't be interacted with mouse
|
|
4426
|
-
...(isOpen && {
|
|
4427
|
-
visibility: 'inherit',
|
|
4428
|
-
pointerEvents: 'inherit',
|
|
4429
|
-
transform: 'translate3d(-50%,0,0)',
|
|
4430
|
-
}),
|
|
4431
|
-
transition,
|
|
4432
|
-
// keep the popover on the #top-layer while the fade-out runs (Chromium only; see `overlayTransitionSupportsQuery`)
|
|
4433
|
-
...overlayTransitionSupportsQuery({
|
|
4434
|
-
transition: `${transition},${getTransition('overlay', duration, easing)} allow-discrete`,
|
|
4435
|
-
}),
|
|
4436
4505
|
},
|
|
4437
4506
|
},
|
|
4438
4507
|
}, {
|
|
@@ -4443,6 +4512,17 @@ const getComponentCss$18 = (isOpen, position, state, hasDismissButton, hasHeadin
|
|
|
4443
4512
|
},
|
|
4444
4513
|
}, getFunctionalComponentNotificationBaseStyles(state, false, hasDismissButton, hasHeadingOrHeadingSlot)),
|
|
4445
4514
|
});
|
|
4515
|
+
// Both the `[popover]` box (transform) and its nested `.notification` (opacity) need a `@starting-style`: while closed
|
|
4516
|
+
// the popover is `display: none`, so on open `.notification` renders fresh with a computed `opacity: 1` and has no
|
|
4517
|
+
// prior value to transition from — without the starting value it snaps to full opacity instead of fading in. The
|
|
4518
|
+
// opacity is split onto `.notification` (not `[popover]`) so the frosted-glass backdrop-filter renders correctly.
|
|
4519
|
+
//
|
|
4520
|
+
// `skipEntryTransition` omits the append on the component's FIRST render, so an initially-open banner (`open=true` on
|
|
4521
|
+
// page load) computes straight to its visible transform/opacity and appears instantly instead of sliding/fading in.
|
|
4522
|
+
// Every later render passes `false`, so a user-triggered open still animates normally.
|
|
4523
|
+
return isOpen && false
|
|
4524
|
+
? `${css}\n@starting-style {\n [popover] {\n transform: ${ref(cssVarTransform)};\n }\n .notification {\n opacity: 0;\n }\n}`
|
|
4525
|
+
: css;
|
|
4446
4526
|
};
|
|
4447
4527
|
|
|
4448
4528
|
// 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.
|
|
@@ -5826,28 +5906,14 @@ const dialogHostJssStyle = (background) => {
|
|
|
5826
5906
|
[cssVarBackgroundColor]: background === 'surface' ? ref(colorSurface) : ref(colorCanvas),
|
|
5827
5907
|
};
|
|
5828
5908
|
};
|
|
5909
|
+
// INTENTIONAL DIVERGENCE from `popover-styles.ts` (kept, not aligned — see the mirrored note there):
|
|
5910
|
+
// This dialog stays permanently rendered and collapses its CLOSED state via delayed `visibility: hidden` + `width/height: 0`
|
|
5911
|
+
// (driven by `isVisible`), so `opacity`/`background` fade in BOTH directions with NO `@starting-style`, and an initial
|
|
5912
|
+
// `open=true` computes straight to the visible state (no entry fade on load). `p-popover`/`p-banner` instead use the native
|
|
5913
|
+
// `[popover]` `display: none`/`:popover-open` toggle plus a `@starting-style` entry fade, because those components mimic the
|
|
5914
|
+
// native popover box model. Both share `createTopLayerController` + the Chromium-only `overlay allow-discrete` transition
|
|
5915
|
+
// (`overlayTransitionSupportsQuery`) and the `inert` toggle for tabbability; only the closed-state expression differs.
|
|
5829
5916
|
const getFunctionalComponentDialogBaseStyles = (isVisible, backdrop = 'blur') => {
|
|
5830
|
-
return {
|
|
5831
|
-
dialog: {
|
|
5832
|
-
...dialogBackdropResetJssStyle,
|
|
5833
|
-
...getDialogBackdropTransitionJssStyle(isVisible, backdrop),
|
|
5834
|
-
},
|
|
5835
|
-
};
|
|
5836
|
-
};
|
|
5837
|
-
const dialogBackdropResetJssStyle = {
|
|
5838
|
-
all: 'unset',
|
|
5839
|
-
position: 'fixed',
|
|
5840
|
-
inset: 0,
|
|
5841
|
-
maxWidth: '100dvw',
|
|
5842
|
-
maxHeight: '100dvh',
|
|
5843
|
-
overflow: 'hidden',
|
|
5844
|
-
display: 'block',
|
|
5845
|
-
outline: 0, // we always expect a focusable element to be within the dialog
|
|
5846
|
-
'&::backdrop': {
|
|
5847
|
-
display: 'none', // ua-style (we can't use it atm because it's not animatable in all browsers)
|
|
5848
|
-
},
|
|
5849
|
-
};
|
|
5850
|
-
const getDialogBackdropTransitionJssStyle = (isVisible, backdrop = 'blur') => {
|
|
5851
5917
|
const isBackdropBlur = backdrop === 'blur';
|
|
5852
5918
|
const duration = isVisible ? 'long' : 'moderate';
|
|
5853
5919
|
const easing = isVisible ? 'in' : 'out';
|
|
@@ -5855,14 +5921,21 @@ const getDialogBackdropTransitionJssStyle = (isVisible, backdrop = 'blur') => {
|
|
|
5855
5921
|
// as soon as all browsers are supporting `allow-discrete`, visibility transition shouldn't be necessary anymore
|
|
5856
5922
|
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)}`;
|
|
5857
5923
|
return {
|
|
5858
|
-
|
|
5924
|
+
all: 'unset',
|
|
5925
|
+
position: 'fixed',
|
|
5926
|
+
inset: 0,
|
|
5927
|
+
maxWidth: '100dvw',
|
|
5928
|
+
maxHeight: '100dvh',
|
|
5929
|
+
overflow: 'hidden',
|
|
5930
|
+
display: 'block',
|
|
5931
|
+
userSelect: 'text', // allows text selection within dialog element (e.g. for copy & paste)
|
|
5932
|
+
outline: 0, // we always expect a focusable element to be within the dialog
|
|
5859
5933
|
...(isVisible
|
|
5860
5934
|
? {
|
|
5861
5935
|
width: '100dvw',
|
|
5862
5936
|
height: '100dvh',
|
|
5863
5937
|
visibility: 'inherit',
|
|
5864
5938
|
pointerEvents: 'auto',
|
|
5865
|
-
overlay: 'auto',
|
|
5866
5939
|
background: ref(colorBackdrop),
|
|
5867
5940
|
...(isBackdropBlur && {
|
|
5868
5941
|
WebkitBackdropFilter: ref(blurFrosted),
|
|
@@ -5878,7 +5951,6 @@ const getDialogBackdropTransitionJssStyle = (isVisible, backdrop = 'blur') => {
|
|
|
5878
5951
|
height: '0px',
|
|
5879
5952
|
visibility: 'hidden', // element shall not be tabbable with keyboard after fade out transition has finished
|
|
5880
5953
|
pointerEvents: 'none', // element can't be interacted with mouse
|
|
5881
|
-
overlay: 'none',
|
|
5882
5954
|
background: 'transparent',
|
|
5883
5955
|
}),
|
|
5884
5956
|
transition,
|
|
@@ -5886,6 +5958,13 @@ const getDialogBackdropTransitionJssStyle = (isVisible, backdrop = 'blur') => {
|
|
|
5886
5958
|
...overlayTransitionSupportsQuery({
|
|
5887
5959
|
transition: `${transition}, ${getTransition('overlay', duration, easing)} allow-discrete`,
|
|
5888
5960
|
}),
|
|
5961
|
+
overlay: 'none',
|
|
5962
|
+
'&:modal': {
|
|
5963
|
+
overlay: 'auto',
|
|
5964
|
+
},
|
|
5965
|
+
'&::backdrop': {
|
|
5966
|
+
display: 'none', // reset ua-style (we can't use it atm because it's not animatable in all browsers)
|
|
5967
|
+
},
|
|
5889
5968
|
};
|
|
5890
5969
|
};
|
|
5891
5970
|
const getScrollerJssStyle = (position) => {
|
|
@@ -5965,6 +6044,9 @@ const getDialogTransitionJssStyle = (isVisible, slideIn) => {
|
|
|
5965
6044
|
};
|
|
5966
6045
|
const getDialogDismissButtonJssStyle = () => {
|
|
5967
6046
|
return {
|
|
6047
|
+
// native dismiss button visual (primary variant); positioning + the `invert` filter (renders it light on the
|
|
6048
|
+
// dialog) are applied on top below
|
|
6049
|
+
...getFCDismissButtonStyles('primary'),
|
|
5968
6050
|
gridArea: '1/3',
|
|
5969
6051
|
zIndex: 5, // controls layering + creates new stacking context (prevents content within to be above other dialog areas)
|
|
5970
6052
|
position: 'sticky',
|
|
@@ -7089,7 +7171,6 @@ const getComponentCss$V = (isOpen, background, backdrop, position, hasHeader, ha
|
|
|
7089
7171
|
...hostHiddenStyles,
|
|
7090
7172
|
}),
|
|
7091
7173
|
},
|
|
7092
|
-
...preventFoucOfNestedElementsStyles,
|
|
7093
7174
|
slot: {
|
|
7094
7175
|
...getSlotJssStyle(),
|
|
7095
7176
|
'&:not([name])': getSlotMainJssStyle(),
|
|
@@ -7112,7 +7193,7 @@ const getComponentCss$V = (isOpen, background, backdrop, position, hasHeader, ha
|
|
|
7112
7193
|
'&[name=sub-footer]': getSlotSubFooterJssStyle(),
|
|
7113
7194
|
}),
|
|
7114
7195
|
},
|
|
7115
|
-
|
|
7196
|
+
dialog: getFunctionalComponentDialogBaseStyles(isOpen, backdrop),
|
|
7116
7197
|
},
|
|
7117
7198
|
scroller: {
|
|
7118
7199
|
...getScrollerJssStyle(isPositionStart ? 'start' : 'end'),
|
|
@@ -7942,7 +8023,6 @@ const getComponentCss$C = (isOpen, background, backdrop, fullscreen, hasDismissB
|
|
|
7942
8023
|
...hostHiddenStyles,
|
|
7943
8024
|
}),
|
|
7944
8025
|
},
|
|
7945
|
-
...preventFoucOfNestedElementsStyles,
|
|
7946
8026
|
slot: {
|
|
7947
8027
|
...getSlotJssStyle(),
|
|
7948
8028
|
'&:not([name])': getSlotMainJssStyle(),
|
|
@@ -7956,7 +8036,7 @@ const getComponentCss$C = (isOpen, background, backdrop, fullscreen, hasDismissB
|
|
|
7956
8036
|
'&[name=footer]': getSlotFooterJssStyle(),
|
|
7957
8037
|
}),
|
|
7958
8038
|
},
|
|
7959
|
-
|
|
8039
|
+
dialog: getFunctionalComponentDialogBaseStyles(isOpen, backdrop),
|
|
7960
8040
|
},
|
|
7961
8041
|
scroller: getScrollerJssStyle('fullscreen'),
|
|
7962
8042
|
modal: {
|
|
@@ -8392,7 +8472,7 @@ const cssVariableMaxHeight = '--p-popover-max-h';
|
|
|
8392
8472
|
*/
|
|
8393
8473
|
const cssVarPaddingInline = '--p-popover-px';
|
|
8394
8474
|
/**
|
|
8395
|
-
* @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": "
|
|
8475
|
+
* @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": "16px"}
|
|
8396
8476
|
*/
|
|
8397
8477
|
const cssVarPaddingBlock = '--p-popover-py';
|
|
8398
8478
|
/**
|
|
@@ -8404,14 +8484,19 @@ const iconInfo = getInlineSVGBackgroundImage(`<path d="M12.5 10v6h-1v-6zm0-2v1h-
|
|
|
8404
8484
|
* Builds the popover's scoped CSS.
|
|
8405
8485
|
* @param isOpen - The effective open state; drives the fade-in/fade-out direction and the `@starting-style` append.
|
|
8406
8486
|
* @param isCompact - Reduces padding/spacing and uses smaller radii (mirrors the `compact` prop).
|
|
8407
|
-
* @
|
|
8487
|
+
* @param skipEntryTransition - Suppresses the `@starting-style` entry fade. Set on the component's first render so an
|
|
8488
|
+
* initially-open popover (`open=true` on page load) appears instantly instead of fading in. Later user-triggered opens
|
|
8489
|
+
* render with this `false`, so they keep the fade-in.
|
|
8490
|
+
* @returns The component CSS string, with a trailing `@starting-style` rule appended while opening (unless skipped).
|
|
8408
8491
|
*/
|
|
8409
|
-
const getComponentCss$v = (isOpen, isCompact) => {
|
|
8492
|
+
const getComponentCss$v = (isOpen, isCompact, skipEntryTransition) => {
|
|
8410
8493
|
// fade-in on open (via `@starting-style` below), fade-out on close. While closing, the panel keeps `display: grid`
|
|
8411
8494
|
// (Chromium via `overlay` + `display` `allow-discrete`; Safari/Firefox via the deferred `hidePopover()`), so
|
|
8412
8495
|
// `display: none` only describes the fully-closed terminal state. Tabbability / a11y-tree removal during the fade-out
|
|
8413
8496
|
// is handled immediately via the `inert` attribute on the panel (see popover.tsx), so no `visibility` toggle is needed.
|
|
8414
|
-
const
|
|
8497
|
+
const duration = 'short';
|
|
8498
|
+
const easing = isOpen ? 'in' : 'out';
|
|
8499
|
+
const transition = getTransition('opacity', duration, easing);
|
|
8415
8500
|
const css = getCss({
|
|
8416
8501
|
'@global': {
|
|
8417
8502
|
':host': {
|
|
@@ -8430,7 +8515,8 @@ const getComponentCss$v = (isOpen, isCompact) => {
|
|
|
8430
8515
|
maxWidth: 'inherit',
|
|
8431
8516
|
maxHeight: 'inherit',
|
|
8432
8517
|
boxSizing: 'border-box',
|
|
8433
|
-
|
|
8518
|
+
paddingBlock: `${ref(cssVarPaddingBlock, isCompact ? ref(spacingStaticSm$1) : ref(spacingStaticMd))}`,
|
|
8519
|
+
paddingInline: `${ref(cssVarPaddingInline, isCompact ? ref(spacingStaticSm$1) : ref(spacingStaticMd))}`,
|
|
8434
8520
|
overflow: 'hidden auto',
|
|
8435
8521
|
overscrollBehaviorY: 'none',
|
|
8436
8522
|
},
|
|
@@ -8493,7 +8579,7 @@ const getComponentCss$v = (isOpen, isCompact) => {
|
|
|
8493
8579
|
transition,
|
|
8494
8580
|
// keep the popover on the #top-layer while the fade-out runs (Chromium only; see `overlayTransitionSupportsQuery`)
|
|
8495
8581
|
...overlayTransitionSupportsQuery({
|
|
8496
|
-
transition: `${transition},${getTransition('overlay',
|
|
8582
|
+
transition: `${transition},${getTransition('overlay', duration, easing)} allow-discrete, ${getTransition('display', duration, easing)} allow-discrete`,
|
|
8497
8583
|
}),
|
|
8498
8584
|
// Unlike `opacity` (driven by the `isOpen` render flag), `overlay` and `display` are toggled via the
|
|
8499
8585
|
// `:popover-open` UA state instead of `isOpen`. Both are owned by the browser: they only flip once
|
|
@@ -8537,7 +8623,17 @@ const getComponentCss$v = (isOpen, isCompact) => {
|
|
|
8537
8623
|
// engines (< Chromium 117 / Safari 17.5 / Firefox 129) ignore the unknown at-rule and skip the entry fade (graceful
|
|
8538
8624
|
// degradation). Formatting mirrors JSS output so the unit-test CSS parser can read it.
|
|
8539
8625
|
//
|
|
8540
|
-
//
|
|
8626
|
+
// `skipEntryTransition` omits the append on the component's FIRST render, so an initially-open popover (`open=true` on
|
|
8627
|
+
// page load) computes straight to `opacity: 1` and appears instantly instead of fading in. Every later render passes
|
|
8628
|
+
// `false`, so a user-triggered open still fades in normally.
|
|
8629
|
+
//
|
|
8630
|
+
// ALTERNATIVE APPROACH (INTENTIONALLY NOT IMPLEMENTED) — mirror the `dialog-base` (p-modal/p-flyout) pattern and drop `@starting-style`:
|
|
8631
|
+
// Decision: KEEP this divergence (see the mirrored note in `common/dialog-base/dialog-base-styles.ts`). `p-popover`/`p-banner`
|
|
8632
|
+
// mimic the native `[popover]` box model, so they use the native `display: none`/`:popover-open` toggle + `@starting-style`
|
|
8633
|
+
// entry fade rather than the dialog's permanently-rendered `visibility`/`width`/`height` collapse. Both approaches share
|
|
8634
|
+
// `createTopLayerController`, the Chromium-only `overlay allow-discrete` transition (`overlayTransitionSupportsQuery`) and
|
|
8635
|
+
// the `inert` toggle for tabbability; only the closed-state expression differs. The alternative below is documented for
|
|
8636
|
+
// context (and to record its one upside — no entry fade on initial `open=true`), but is deliberately left unimplemented.
|
|
8541
8637
|
// • Keep the panel permanently rendered (never `display: none`); collapse the closed state via `visibility: hidden`
|
|
8542
8638
|
// + `width/height: 0` instead. Because the element stays rendered, `opacity` fades normally in BOTH directions with
|
|
8543
8639
|
// no `@starting-style`, and an initial `open=true` computes straight to `opacity: 1` (appears instantly, no entry
|
|
@@ -8553,7 +8649,7 @@ const getComponentCss$v = (isOpen, isCompact) => {
|
|
|
8553
8649
|
// tabbable during the fade-out).
|
|
8554
8650
|
// • Trade-off: removes the `@starting-style` raw-CSS append + the initial-load fade, at the cost of reintroducing the
|
|
8555
8651
|
// delayed `visibility` plus delayed `width/height` and tighter coupling to the motion duration.
|
|
8556
|
-
return isOpen ? `${css}\n@starting-style {\n [popover] {\n opacity: 0;\n }\n}` : css;
|
|
8652
|
+
return isOpen && !skipEntryTransition ? `${css}\n@starting-style {\n [popover] {\n opacity: 0;\n }\n}` : css;
|
|
8557
8653
|
};
|
|
8558
8654
|
|
|
8559
8655
|
const cssVarInternalRadioGroupOptionScaling = '--_p-radio-group-option-a';
|
|
@@ -9133,7 +9229,6 @@ const getComponentCss$n = (isOpen, background, hasDismissButton) => {
|
|
|
9133
9229
|
...hostHiddenStyles,
|
|
9134
9230
|
}),
|
|
9135
9231
|
},
|
|
9136
|
-
...preventFoucOfNestedElementsStyles,
|
|
9137
9232
|
slot: {
|
|
9138
9233
|
...getSlotJssStyle(),
|
|
9139
9234
|
'&:not([name])': getSlotMainJssStyle(),
|
|
@@ -9142,7 +9237,7 @@ const getComponentCss$n = (isOpen, background, hasDismissButton) => {
|
|
|
9142
9237
|
zIndex: 0, // controls layering + creates new stacking context (prevents content within to be above other dialog areas)
|
|
9143
9238
|
},
|
|
9144
9239
|
},
|
|
9145
|
-
|
|
9240
|
+
dialog: getFunctionalComponentDialogBaseStyles(isOpen, 'shading'),
|
|
9146
9241
|
},
|
|
9147
9242
|
scroller: getScrollerJssStyle('fullscreen'),
|
|
9148
9243
|
sheet: {
|
|
@@ -10280,7 +10375,7 @@ const getComponentCss$1 = () => {
|
|
|
10280
10375
|
[cssVariablePositionBottomInternal]: ref(cssVariablePositionBottom, '56px'),
|
|
10281
10376
|
position: 'fixed', // fallback for older browsers without native `popover` support
|
|
10282
10377
|
inset: `auto ${gridExtendedOffsetBase} ${ref(cssVariablePositionBottomInternal)}`,
|
|
10283
|
-
zIndex:
|
|
10378
|
+
zIndex: 999999, // fallback for older browsers without native `popover` support
|
|
10284
10379
|
[getMediaQueryMin('s')]: {
|
|
10285
10380
|
[cssVariablePositionBottomInternal]: ref(cssVariablePositionBottom, '64px'),
|
|
10286
10381
|
inset: `auto auto ${ref(cssVariablePositionBottomInternal)} 64px`,
|
|
@@ -10379,6 +10474,7 @@ exports.getDividerCss = getComponentCss$$;
|
|
|
10379
10474
|
exports.getDrilldownCss = getComponentCss$_;
|
|
10380
10475
|
exports.getDrilldownItemCss = getComponentCss$Z;
|
|
10381
10476
|
exports.getDrilldownLinkCss = getComponentCss$Y;
|
|
10477
|
+
exports.getFCDismissButtonStyles = getFCDismissButtonStyles;
|
|
10382
10478
|
exports.getFieldsetCss = getComponentCss$X;
|
|
10383
10479
|
exports.getFlagCss = getComponentCss$W;
|
|
10384
10480
|
exports.getFlyoutCss = getComponentCss$V;
|
|
@@ -3482,7 +3482,7 @@ const hasShowPickerSupport = () => (hasDocument &&
|
|
|
3482
3482
|
'showPicker' in HTMLInputElement.prototype &&
|
|
3483
3483
|
CSS.supports('selector(::-webkit-calendar-picker-indicator)'));
|
|
3484
3484
|
|
|
3485
|
-
const prefix = `[Porsche Design System v${"4.4.0
|
|
3485
|
+
const prefix = `[Porsche Design System v${"4.4.0"}]` // this part isn't covered by unit tests
|
|
3486
3486
|
;
|
|
3487
3487
|
const consoleError$1 = (...messages) => {
|
|
3488
3488
|
console.error(prefix, ...messages);
|
package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/banner.cjs
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var react = require('react');
|
|
5
|
-
require('../../provider.cjs');
|
|
6
4
|
var splitChildren = require('../../splitChildren.cjs');
|
|
5
|
+
var react = require('react');
|
|
7
6
|
var minifyCss = require('../../minifyCss.cjs');
|
|
8
7
|
var stylesEntry = require('../../../../../../components/dist/styles/esm/styles-entry.cjs');
|
|
9
8
|
var utilsEntry = require('../../../../../../components/dist/utils/esm/utils-entry.cjs');
|
|
9
|
+
var fcDismissButton = require('./fc-dismiss-button.cjs');
|
|
10
10
|
var notificationBase = require('./notification-base.cjs');
|
|
11
|
-
var button_wrapper = require('../components/button.wrapper.cjs');
|
|
12
11
|
|
|
13
12
|
/**
|
|
14
13
|
* @slot {"name": "heading", "description": "Defines the heading of the banner. Can be used as an alternative to the `heading` prop for rich content." }
|
|
@@ -23,6 +22,12 @@ class DSRBanner extends react.Component {
|
|
|
23
22
|
refDismiss;
|
|
24
23
|
hasHeadingSlot;
|
|
25
24
|
hasDescriptionSlot;
|
|
25
|
+
// Tracks whether the document-level Escape listener is currently registered (guards the idempotent sync below).
|
|
26
|
+
hasKeydownListener = false;
|
|
27
|
+
// Tracks the component's first render. While `true`, the entry transition (`@starting-style`) is suppressed so an
|
|
28
|
+
// initially-open banner (`open=true` on page load) appears instantly instead of sliding/fading in; flipped to `false`
|
|
29
|
+
// in `componentDidLoad`, so every later (user-triggered) open keeps the entry animation.
|
|
30
|
+
isInitialRender = true;
|
|
26
31
|
topLayer = utilsEntry.createTopLayerController({
|
|
27
32
|
getElement: () => this.props.refPopover,
|
|
28
33
|
isShown: () => !!this.props.refPopover?.matches(':popover-open'),
|
|
@@ -35,8 +40,13 @@ class DSRBanner extends react.Component {
|
|
|
35
40
|
const hasDescriptionSlot = namedSlotChildren.filter(({ props: { slot } }) => slot === 'description').length > 0;
|
|
36
41
|
const headingText = this.props.heading ? this.props.heading : namedSlotChildren.find(({ props: { slot } }) => slot === 'heading')?.props.children;
|
|
37
42
|
const style = minifyCss.minifyCss(stylesEntry.getBannerCss(this.props.open, this.props.position, this.props.state, this.props.dismissButton, !!(this.props.heading || hasHeadingSlot)));
|
|
38
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("template", { shadowroot: "open", shadowrootmode: "open", children: [jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: style
|
|
39
|
-
|
|
43
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("template", { shadowroot: "open", shadowrootmode: "open", children: [jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: style + (this.props.open ? '[popover]{display:grid!important}' : '') } }), jsxRuntime.jsx("div", { popover: "manual",
|
|
44
|
+
// `inert` (not `aria-hidden`) removes the panel from the a11y tree AND prevents focus while closed / during the
|
|
45
|
+
// fade-out. Using `aria-hidden` here triggers a browser warning when a focusable descendant still holds focus
|
|
46
|
+
// during the closing transition ("Blocked aria-hidden on an element because its descendant retained focus").
|
|
47
|
+
// `inert` avoids that and mirrors the pattern used by `p-modal` / `p-popover` / `p-drilldown`.
|
|
48
|
+
inert: !this.props.open, ...utilsEntry.getBannerAriaAttributes(this.props.state, headingText), children: jsxRuntime.jsx(notificationBase.NotificationBase, { heading: this.props.heading, headingTag: this.props.headingTag, hasHeadingSlot: hasHeadingSlot, description: this.props.description, hasDescriptionSlot: hasDescriptionSlot, ...(this.props.dismissButton && {
|
|
49
|
+
dismissButton: (jsxRuntime.jsx(fcDismissButton.FCDismissButton, { label: "Close banner", ariaDescription: headingText || undefined })),
|
|
40
50
|
}) }) })] }), this.props.children] }));
|
|
41
51
|
}
|
|
42
52
|
}
|
package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/dialog-base.cjs
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
require('
|
|
5
|
-
require('../../provider.cjs');
|
|
6
|
-
var button_wrapper = require('../components/button.wrapper.cjs');
|
|
4
|
+
var fcDismissButton = require('./fc-dismiss-button.cjs');
|
|
7
5
|
|
|
8
|
-
const DialogBase = ({ children,
|
|
9
|
-
|
|
10
|
-
inert, containerClass, ariaAttributes, dismissable = false, header, footer, subFooter, }) => {
|
|
11
|
-
return (jsxRuntime.jsx("dialog", { inert: inert, tabIndex: -1, ...(ariaAttributes ?? {}), children: jsxRuntime.jsx("div", { className: "scroller", children: jsxRuntime.jsxs("div", { className: containerClass, children: [dismissable && (jsxRuntime.jsx(button_wrapper.PButton, { className: "dismiss", compact: true, type: "button", hideLabel: true, icon: "close", children: `Dismiss ${containerClass}` })), header, children, footer, subFooter] }) }) }));
|
|
6
|
+
const DialogBase = ({ children, inert, containerClass, ariaAttributes, onMouseDown, dismissable = false, header, footer, subFooter, }) => {
|
|
7
|
+
return (jsxRuntime.jsx("dialog", { inert: inert, tabIndex: -1, ...(ariaAttributes ?? {}), children: jsxRuntime.jsx("div", { className: "scroller", children: jsxRuntime.jsxs("div", { className: containerClass, children: [dismissable && jsxRuntime.jsx(fcDismissButton.FCDismissButton, { label: `Dismiss ${containerClass}` }), header, children, footer, subFooter] }) }) }));
|
|
12
8
|
};
|
|
13
9
|
|
|
14
10
|
exports.DialogBase = DialogBase;
|
package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/drilldown.cjs
CHANGED
|
@@ -26,6 +26,9 @@ class DSRDrilldown extends react.Component {
|
|
|
26
26
|
dialog;
|
|
27
27
|
drawer;
|
|
28
28
|
isDesktop = false;
|
|
29
|
+
// Tracks whether the current pointer gesture started inside the drawer (not on the backdrop). Lets `onClickDialog`
|
|
30
|
+
// skip dismissal when a selection is dragged out of the drawer and released on the backdrop.
|
|
31
|
+
isPointerDownInside = false;
|
|
29
32
|
async componentWillLoad() {
|
|
30
33
|
this.props.defineDrilldownItemElements();
|
|
31
34
|
const activeItem = this.props.drilldownItemElements.find((item) => item.identifier === this.props.activeIdentifier);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Shared dismiss/close button used across dialog-based (flyout/modal/sheet) and notification-based
|
|
7
|
+
* (banner/inline-notification/toast) components. Renders a native `<button className="dismiss">` with the close icon
|
|
8
|
+
* inlined as a CSS mask (see `fc-dismiss-button-styles.ts`) — so it needs neither a nested `p-button` nor a `p-icon`
|
|
9
|
+
* (avoiding the async CDN icon fetch). Each consumer supplies the variant/positioning styling via the `.dismiss` class.
|
|
10
|
+
* The visible label text is visually hidden but exposed to assistive technology as the accessible name.
|
|
11
|
+
*/
|
|
12
|
+
const FCDismissButton = ({ label, ariaDescription, }) => {
|
|
13
|
+
return (jsxRuntime.jsx("button", { className: "dismiss", type: "button", ...(ariaDescription ? { 'aria-description': ariaDescription } : {}), children: jsxRuntime.jsx("span", { children: label }) }));
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
exports.FCDismissButton = FCDismissButton;
|
package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/flyout.cjs
CHANGED
|
@@ -25,6 +25,9 @@ class DSRFlyout extends react.Component {
|
|
|
25
25
|
hasHeader;
|
|
26
26
|
hasFooter;
|
|
27
27
|
hasSubFooter;
|
|
28
|
+
// Tracks whether the current pointer gesture started inside the panel (not on the backdrop). Lets `onClickDialog`
|
|
29
|
+
// skip dismissal when a selection is dragged out of the panel and released on the backdrop.
|
|
30
|
+
isPointerDownInside = false;
|
|
28
31
|
topLayer = utilsEntry.createTopLayerController({
|
|
29
32
|
getElement: () => this.props.dialog,
|
|
30
33
|
isShown: () => !!this.props.dialog?.open,
|
|
@@ -37,7 +40,17 @@ class DSRFlyout extends react.Component {
|
|
|
37
40
|
const hasFooter = namedSlotChildren.filter(({ props: { slot } }) => slot === 'footer').length > 0;
|
|
38
41
|
const hasSubFooter = namedSlotChildren.filter(({ props: { slot } }) => slot === 'sub-footer').length > 0;
|
|
39
42
|
const style = minifyCss.minifyCss(stylesEntry.getFlyoutCss(this.props.open, this.props.background, this.props.backdrop, this.props.position, hasHeader, hasFooter, hasSubFooter, this.props.footerBehavior, this.props.fullscreen));
|
|
40
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("template", { shadowroot: "open", shadowrootmode: "open", children: [jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: style } }), jsxRuntime.jsx(dialogBase.DialogBase
|
|
43
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("template", { shadowroot: "open", shadowrootmode: "open", children: [jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: style } }), jsxRuntime.jsx(dialogBase.DialogBase
|
|
44
|
+
// `inert` (not `aria-hidden`) removes the panel from the a11y tree AND prevents focus while closed / during the
|
|
45
|
+
// fade-out. Using `aria-hidden` here triggers a browser warning when a focusable descendant still holds focus
|
|
46
|
+
// during the closing transition ("Blocked aria-hidden on an element because its descendant retained focus").
|
|
47
|
+
// `inert` avoids that and mirrors the pattern used by `p-modal` / `p-popover` / `p-drilldown`.
|
|
48
|
+
, {
|
|
49
|
+
// `inert` (not `aria-hidden`) removes the panel from the a11y tree AND prevents focus while closed / during the
|
|
50
|
+
// fade-out. Using `aria-hidden` here triggers a browser warning when a focusable descendant still holds focus
|
|
51
|
+
// during the closing transition ("Blocked aria-hidden on an element because its descendant retained focus").
|
|
52
|
+
// `inert` avoids that and mirrors the pattern used by `p-modal` / `p-popover` / `p-drilldown`.
|
|
53
|
+
inert: !this.props.open, dismissable: true, containerClass: "flyout", header: hasHeader ? jsxRuntime.jsx("slot", { name: "header" }) : undefined, footer: hasFooter ? jsxRuntime.jsx("slot", { name: "footer" }) : undefined, subFooter: hasSubFooter ? jsxRuntime.jsx("slot", { name: "sub-footer" }) : undefined, ariaAttributes: utilsEntry.parseAndGetAriaAttributes({
|
|
41
54
|
'aria-modal': true,
|
|
42
55
|
...{ 'aria-label': hasHeader ? namedSlotChildren.find(({ props: { slot } }) => slot === 'header')?.props.children : 'Flyout' },
|
|
43
56
|
...utilsEntry.parseAndGetAriaAttributes(this.props.aria),
|