@porsche-design-system/components-react 3.15.2 → 3.16.0-rc.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.
Files changed (28) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/cjs/lib/components/flyout.wrapper.cjs +3 -3
  3. package/esm/lib/components/carousel.wrapper.d.ts +2 -2
  4. package/esm/lib/components/flyout.wrapper.d.ts +8 -0
  5. package/esm/lib/components/flyout.wrapper.mjs +3 -3
  6. package/esm/lib/components/modal.wrapper.d.ts +2 -2
  7. package/esm/lib/components/pagination.wrapper.d.ts +1 -1
  8. package/esm/lib/types.d.ts +4 -4
  9. package/package.json +2 -2
  10. package/ssr/cjs/components/dist/styles/esm/styles-entry.cjs +347 -320
  11. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/components/flyout.wrapper.cjs +4 -4
  12. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/flyout-navigation-item.cjs +5 -1
  13. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/flyout-navigation.cjs +5 -1
  14. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/flyout.cjs +11 -5
  15. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/modal.cjs +13 -7
  16. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/multi-select.cjs +1 -1
  17. package/ssr/esm/components/dist/styles/esm/styles-entry.mjs +347 -320
  18. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/components/flyout.wrapper.mjs +4 -4
  19. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/flyout-navigation-item.mjs +5 -1
  20. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/flyout-navigation.mjs +5 -1
  21. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/flyout.mjs +11 -5
  22. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/modal.mjs +13 -7
  23. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/multi-select.mjs +1 -1
  24. package/ssr/esm/lib/components/flyout.wrapper.d.ts +8 -0
  25. package/ssr/esm/lib/components/modal.wrapper.d.ts +2 -2
  26. package/ssr/esm/lib/dsr-components/banner.d.ts +8 -0
  27. package/ssr/esm/lib/dsr-components/flyout.d.ts +1 -3
  28. package/ssr/esm/lib/types.d.ts +4 -4
@@ -3474,6 +3474,7 @@ const themeLight = {
3474
3474
  backgroundSurfaceColor: '#EEEFF2',
3475
3475
  backgroundSurfaceColorDarken: '#CBCED7',
3476
3476
  backgroundSurfaceColorLighten: '#FFFFFF',
3477
+ backgroundShadingColor: 'rgba(1, 2, 5, 0.67)',
3477
3478
  contrastLowColor: '#D8D8DB',
3478
3479
  contrastMediumColor: '#6B6D70',
3479
3480
  contrastHighColor: '#535457',
@@ -3512,6 +3513,7 @@ const themeDark = {
3512
3513
  backgroundSurfaceColor: '#212225',
3513
3514
  backgroundSurfaceColorDarken: '#040405',
3514
3515
  backgroundSurfaceColorLighten: '#3E4045',
3516
+ backgroundShadingColor: 'rgba(38, 38, 41, 0.67)',
3515
3517
  contrastLowColor: '#404044',
3516
3518
  contrastMediumColor: '#88898C',
3517
3519
  contrastHighColor: '#AFB0B3',
@@ -3664,8 +3666,7 @@ const getHiddenTextJssStyle = (isHidden = true, isShownJssStyle) => {
3664
3666
  ...isShownJssStyle,
3665
3667
  };
3666
3668
  };
3667
- // TODO: there should be a shared style util for modal, flyout and flyout-navigation instead of having this code in the
3668
- // main bundle. Or don't share it at all, in case same transition concept isn't ideal to be shared from an UI point of view.
3669
+ // TODO: migrate flyout-navigation to use shared backdrop of dialog-styles.ts
3669
3670
  /**
3670
3671
  * Generates JSS styles for a frosted glass background.
3671
3672
  * @param {boolean} isVisible - Determines if the frosted glass effect is visible.
@@ -3675,7 +3676,7 @@ const getHiddenTextJssStyle = (isHidden = true, isShownJssStyle) => {
3675
3676
  * @param {'blur' | 'shading'} backdrop - The backdrop variant.
3676
3677
  * @returns {JssStyle} - The JSS styles for the frosted glass backdrop.
3677
3678
  */
3678
- const getBackdropJssStyle = (isVisible, zIndex, theme, duration = 'long', backdrop = 'blur') => {
3679
+ const getBackdropJssStyle = (isVisible, zIndex, theme, duration = 'long') => {
3679
3680
  return {
3680
3681
  position: 'fixed',
3681
3682
  inset: 0,
@@ -3689,17 +3690,14 @@ const getBackdropJssStyle = (isVisible, zIndex, theme, duration = 'long', backdr
3689
3690
  ? {
3690
3691
  visibility: 'inherit',
3691
3692
  pointerEvents: 'auto',
3692
- ...(backdrop === 'blur' && frostedGlassStyle),
3693
+ ...frostedGlassStyle,
3693
3694
  opacity: 1,
3694
3695
  }
3695
3696
  : {
3696
3697
  visibility: 'hidden', // element shall not be tabbable after fade out transition has finished
3697
3698
  pointerEvents: 'none',
3698
- ...(backdrop === 'blur' && {
3699
- // TODO: is `blur(0px)` necessary at all?
3700
- WebkitBackdropFilter: 'blur(0px)',
3701
- backdropFilter: 'blur(0px)',
3702
- }),
3699
+ WebkitBackdropFilter: 'blur(0px)',
3700
+ backdropFilter: 'blur(0px)',
3703
3701
  opacity: 0,
3704
3702
  }),
3705
3703
  transition: `${getTransition('opacity', duration)}, ${getTransition('backdrop-filter', duration)}, ${getTransition('-webkit-backdrop-filter', duration)}, visibility 0s linear var(${cssVariableTransitionDuration}, ${isVisible ? '0s' : motionDurationMap[duration]})`,
@@ -4026,9 +4024,6 @@ const getCDNBaseURL = () => global.PORSCHE_DESIGN_SYSTEM_CDN_URL + "/porsche-des
4026
4024
 
4027
4025
  const MODEL_SIGNATURES_MANIFEST = { "718": { "src": "718.min.493a9e3509d6e263fa2207150082def5.svg", "width": 79, "height": 26 }, "911": { "src": "911.min.b68f913216168583298ccf83f1a6b8d5.svg", "width": 94, "height": 25 }, "boxster": { "src": "boxster.min.c321738789b37fda4bba3f7c587542aa.svg", "width": 239, "height": 26 }, "cayenne": { "src": "cayenne.min.25562011631a831516f91ec31d144104.svg", "width": 245, "height": 35 }, "cayman": { "src": "cayman.min.cc8919694c002873e1bb6a3c1dae5d41.svg", "width": 229, "height": 35 }, "macan": { "src": "macan.min.a1844f4c8d23b75e371745e9b8eb49b9.svg", "width": 196, "height": 26 }, "panamera": { "src": "panamera.min.6dae8095186567168f85c145845f090c.svg", "width": 260, "height": 25 }, "taycan": { "src": "taycan.min.df444c6f4cc1f627ceaf1b02584d6bea.svg", "width": 167, "height": 36 }, "turbo-s": { "src": "turbo-s.min.73f1e10731caffe93c07d96fa08546c1.svg", "width": 199, "height": 25 }, "turbo": { "src": "turbo.min.6a4084a8704a6c47a099b2de56b22aef.svg", "width": 143, "height": 25 } };
4028
4026
 
4029
- const scrollShadowColor = 'rgba(204, 204, 204, 0.35)';
4030
- const scrollShadowColorDark = 'rgba(0, 0, 0, 0.6)';
4031
-
4032
4027
  const OPTION_HEIGHT = 40; // optgroups are higher and ignored
4033
4028
  const MULTI_SELECT_OPTION_HEIGHT = 44;
4034
4029
  const getNoResultsOptionJssStyle = () => ({
@@ -4235,7 +4230,6 @@ const getComponentCss$15 = (size, compact, open, theme, sticky) => {
4235
4230
  };
4236
4231
 
4237
4232
  const TOAST_Z_INDEX = 999999;
4238
- const MODAL_Z_INDEX = 99999;
4239
4233
  const FLYOUT_Z_INDEX = 99998;
4240
4234
  const POPOVER_Z_INDEX = 9999;
4241
4235
  const BANNER_Z_INDEX = 99;
@@ -4671,14 +4665,14 @@ const getComponentCss$11 = (isDisabledOrLoading, ...args) => {
4671
4665
  });
4672
4666
  };
4673
4667
 
4674
- const { primaryColor: darkThemePrimaryColor$1 } = getThemedColors('dark');
4668
+ const { primaryColor: darkThemePrimaryColor } = getThemedColors('dark');
4675
4669
  const { primaryColor: lightThemePrimaryColor } = getThemedColors('light');
4676
4670
  const getVariantColors = (variant, theme) => {
4677
4671
  const { primaryColor, contrastHighColor, contrastMediumColor, hoverColor } = getThemedColors(theme);
4678
4672
  const { canvasColor } = getHighContrastColors();
4679
4673
  const colors = {
4680
4674
  primary: {
4681
- textColor: theme === 'dark' ? lightThemePrimaryColor : darkThemePrimaryColor$1,
4675
+ textColor: theme === 'dark' ? lightThemePrimaryColor : darkThemePrimaryColor,
4682
4676
  borderColor: primaryColor,
4683
4677
  borderColorHover: contrastHighColor,
4684
4678
  backgroundColor: primaryColor,
@@ -6022,150 +6016,260 @@ const getComponentCss$Q = (isSecondaryScrollerVisible, theme) => {
6022
6016
  });
6023
6017
  };
6024
6018
 
6025
- const headerShadowClass = 'header--shadow';
6026
- const footerShadowClass$1 = 'footer--shadow';
6027
- const getComponentCss$P = (isOpen, position, hasFooter, hasSubFooter, theme) => {
6019
+ const headingTags = 'h1,h2,h3,h4,h5,h6';
6020
+ const dialogHostJssStyle = {
6021
+ '--pds-internal-grid-outer-column': `calc(${spacingFluidLarge} - ${gridGap})`,
6022
+ '--pds-internal-grid-margin': `calc(${spacingFluidLarge} * -1)`,
6023
+ '--pds-internal-grid-width-min': 'auto',
6024
+ '--pds-internal-grid-width-max': 'none',
6025
+ };
6026
+ const getDialogJssStyle = (isVisible, theme, backdrop = 'blur') => {
6027
+ return {
6028
+ ...dialogBackdropResetJssStyle,
6029
+ ...getDialogBackdropTransitionJssStyle(isVisible, theme, backdrop),
6030
+ };
6031
+ };
6032
+ const dialogBackdropResetJssStyle = {
6033
+ position: 'fixed', // ua-style
6034
+ inset: 0, // ua-style
6035
+ margin: 0, // ua-style
6036
+ padding: 0, // ua-style
6037
+ border: 0, // ua-style
6038
+ width: '100dvw', // ua-style
6039
+ height: '100dvh', // ua-style
6040
+ maxWidth: '100dvw', // ua-style
6041
+ maxHeight: '100dvh', // ua-style
6042
+ overflow: 'hidden', // ua-style
6043
+ display: 'block', // ua-style
6044
+ outline: 0, // ua-style (we always expect a focusable element to be within the dialog)
6045
+ '&::backdrop': {
6046
+ display: 'none', // ua-style (we can't use it atm because it's not animatable in all browsers)
6047
+ },
6048
+ };
6049
+ const getDialogBackdropTransitionJssStyle = (isVisible, theme, backdrop = 'blur') => {
6050
+ const isBackdropBlur = backdrop === 'blur';
6051
+ const { backgroundShadingColor } = getThemedColors(theme);
6052
+ const { backgroundShadingColor: backgroundShadingColorDark } = getThemedColors('dark');
6053
+ const duration = isVisible ? 'long' : 'moderate';
6054
+ const easing = isVisible ? 'in' : 'out';
6055
+ // as soon as all browsers are supporting `allow-discrete`, visibility transition shouldn't be necessary anymore
6056
+ const transition = `visibility 0s linear var(${cssVariableTransitionDuration}, ${isVisible ? '0s' : motionDurationMap[duration]}), ${getTransition('background-color', duration, easing)}, ${getTransition('-webkit-backdrop-filter', duration, easing)}, ${getTransition('backdrop-filter', duration, easing)}`;
6057
+ return {
6058
+ zIndex: 9999999, // fallback for fade out stacking until `overlay` + `allow-discrete` is supported in all browsers. It tries to mimic #top-layer positioning hierarchy.
6059
+ ...(isVisible
6060
+ ? {
6061
+ visibility: 'inherit',
6062
+ pointerEvents: 'auto',
6063
+ background: backgroundShadingColor,
6064
+ ...(isBackdropBlur && frostedGlassStyle),
6065
+ ...prefersColorSchemeDarkMediaQuery(theme, {
6066
+ background: backgroundShadingColorDark,
6067
+ }),
6068
+ }
6069
+ : {
6070
+ visibility: 'hidden', // element shall not be tabbable with keyboard after fade out transition has finished
6071
+ pointerEvents: 'none', // element can't be interacted with mouse
6072
+ background: 'transparent',
6073
+ }),
6074
+ transition,
6075
+ // `allow-discrete` transition for ua-style `overlay` (supported browsers only) ensures dialog is rendered on
6076
+ // #top-layer as long as fade-in or fade-out transition/animation is running
6077
+ '@supports (transition-behavior: allow-discrete)': {
6078
+ transition: `${transition}, ${getTransition('overlay', duration, easing)} allow-discrete`,
6079
+ },
6080
+ };
6081
+ };
6082
+ const getScrollerJssStyle = (position, theme) => {
6083
+ // ensures scrollbar color is set correctly (e.g. when scrollbar is shown on backdrop, on flyout/modal surface or with Auto Dark Mode)
6084
+ const backgroundLight = 'rgba(255,255,255,.01)';
6085
+ const backgroundDark = 'rgba(0,0,0,.01)';
6086
+ const background = {
6087
+ light: backgroundLight,
6088
+ dark: backgroundDark,
6089
+ auto: backgroundLight,
6090
+ };
6091
+ return {
6092
+ position: 'absolute',
6093
+ display: 'grid',
6094
+ ...(position === 'fullscreen'
6095
+ ? {
6096
+ inset: 0,
6097
+ }
6098
+ : {
6099
+ insetBlock: 0,
6100
+ [position === 'start' ? 'insetInlineStart' : 'insetInlineEnd']: 0,
6101
+ }),
6102
+ overflow: 'hidden auto',
6103
+ overscrollBehaviorY: 'none',
6104
+ // TODO: check if smooth scrolling on iOS is given?
6105
+ background: background[theme],
6106
+ ...prefersColorSchemeDarkMediaQuery(theme, {
6107
+ background: background.dark,
6108
+ }),
6109
+ };
6110
+ };
6111
+ const dialogGridJssStyle = {
6112
+ display: 'grid',
6113
+ gridTemplate: `auto/${spacingFluidSmall} auto ${spacingFluidSmall}`,
6114
+ paddingBlock: `calc(${spacingFluidSmall} + ${spacingFluidMedium})`,
6115
+ rowGap: spacingFluidMedium,
6116
+ columnGap: `calc(${spacingFluidLarge} - ${spacingFluidSmall})`,
6117
+ alignContent: 'flex-start',
6118
+ };
6119
+ const getDialogColorJssStyle = (theme) => {
6028
6120
  const { primaryColor, backgroundColor } = getThemedColors(theme);
6029
6121
  const { primaryColor: primaryColorDark, backgroundColor: backgroundColorDark } = getThemedColors('dark');
6030
- const isPositionStart = position === 'start';
6031
- const contentPadding = `${spacingStaticMedium} ${spacingFluidLarge}`;
6032
- const isDark = isThemeDark(theme);
6033
- const shadowColor = isDark ? scrollShadowColorDark : scrollShadowColor;
6034
- const transparentColorDark = 'rgba(14, 14, 18, 0)';
6035
- const transparentColor = isDark ? transparentColorDark : 'rgba(255, 255, 255, 0)';
6122
+ return {
6123
+ color: primaryColor, // enables color inheritance for slots
6124
+ background: backgroundColor,
6125
+ ...prefersColorSchemeDarkMediaQuery(theme, {
6126
+ color: primaryColorDark,
6127
+ background: backgroundColorDark,
6128
+ }),
6129
+ };
6130
+ };
6131
+ const getDialogTransitionJssStyle = (isVisible, slideIn) => {
6132
+ const duration = isVisible ? 'moderate' : 'short';
6133
+ const easing = isVisible ? 'in' : 'out';
6134
+ return {
6135
+ // transition offset relies vertically on viewport (vh) because the dialog height can be infinite, while horizontally
6136
+ // it relies on the dialog width (%) which has a max-width
6137
+ ...(isVisible
6138
+ ? {
6139
+ opacity: 1,
6140
+ transform: 'initial',
6141
+ }
6142
+ : {
6143
+ opacity: 0,
6144
+ transform: slideIn === '^' ? 'translateY(25vh)' : `translateX(${slideIn === '>' ? '-' : ''}100%)`,
6145
+ '&:dir(rtl)': {
6146
+ transform: slideIn === '^' ? 'translateY(25vh)' : `translateX(${slideIn === '>' ? '' : '-'}100%)`,
6147
+ },
6148
+ }),
6149
+ transition: `${getTransition('opacity', duration, easing)}, ${getTransition('transform', duration, easing)}`,
6150
+ };
6151
+ };
6152
+ const getDismissButtonJssStyle = (theme, isOpen, applyAutoFocusHack = false) => {
6153
+ const { backgroundSurfaceColor } = getThemedColors(theme);
6154
+ const { backgroundSurfaceColor: backgroundSurfaceColorDark } = getThemedColors('dark');
6155
+ return {
6156
+ width: 'fit-content',
6157
+ height: 'fit-content',
6158
+ border: `2px solid ${backgroundSurfaceColor}`, // needed to enlarge button slightly without affecting the hover area (are equal now).
6159
+ borderRadius: borderRadiusSmall,
6160
+ background: backgroundSurfaceColor,
6161
+ ...prefersColorSchemeDarkMediaQuery(theme, {
6162
+ background: backgroundSurfaceColorDark,
6163
+ borderColor: backgroundSurfaceColorDark,
6164
+ }),
6165
+ // we need to ensure that the dismiss button, which gets auto focused by `.showModal()`, to always be in the
6166
+ // viewport (or off the view on the start-hand side) before the dialog transition starts otherwise the transition
6167
+ // won't work in all cases, e.g. `dir="rtl"` and `<p-flyout position="end" />`. Because auto focus would force the
6168
+ // dismiss button to be rendered in the viewport immediately and ignore the transition.
6169
+ ...(applyAutoFocusHack && {
6170
+ marginInlineEnd: isOpen ? 0 : '200vw',
6171
+ transition: `margin-inline-end 0s linear var(${cssVariableTransitionDuration}, ${isOpen ? '1ms' : '0s'})`,
6172
+ }),
6173
+ };
6174
+ };
6175
+ const getDialogStickyAreaJssStyle = (area, theme) => {
6176
+ const { backgroundColor } = getThemedColors(theme);
6177
+ const { backgroundColor: backgroundColorDark } = getThemedColors('dark');
6178
+ const scrollShadowColor = 'rgba(204, 204, 204, 0.35)';
6179
+ const scrollShadowColorDark = 'rgba(0, 0, 0, 0.6)';
6180
+ const isAreaHeader = area === 'header';
6181
+ const boxShadowDimension = `0 ${isAreaHeader ? 5 : -5}px 10px`;
6182
+ return {
6183
+ position: 'sticky',
6184
+ [isAreaHeader ? 'top' : 'bottom']: '-.1px', // necessary for `IntersectionObserver` to detect if sticky element is stuck or not. Float value is used, so that sticky area isn't moved out visually by e.g. 1px when container gets scrolled.
6185
+ transform: 'translateZ(0)', // prevents slightly squeezed elements within sticky area for some browsers (e.g. Firefox) caused by float value of sticky top position
6186
+ padding: `${spacingStaticMedium} ${spacingFluidLarge}`,
6187
+ marginBlock: `${isAreaHeader ? `calc((${spacingFluidSmall} + ${spacingFluidMedium}) * -1)` : `-${spacingStaticMedium}`} -${spacingStaticMedium}`,
6188
+ background: backgroundColor,
6189
+ ...prefersColorSchemeDarkMediaQuery(theme, {
6190
+ background: backgroundColorDark,
6191
+ }),
6192
+ clipPath: `inset(${isAreaHeader ? '0 0 -20px 0' : '-20px 0 0 0'})`, // crop leaking box-shadow on left and right side
6193
+ transition: `${getTransition('box-shadow')}`,
6194
+ '&[data-stuck]': {
6195
+ boxShadow: `${isThemeDark(theme) ? scrollShadowColorDark : scrollShadowColor} ${boxShadowDimension}`,
6196
+ ...prefersColorSchemeDarkMediaQuery(theme, {
6197
+ boxShadow: `${scrollShadowColorDark} ${boxShadowDimension}`,
6198
+ }),
6199
+ },
6200
+ };
6201
+ };
6202
+
6203
+ const cssVariableWidth$2 = '--p-flyout-width';
6204
+ // TODO: we shouldn't expose --p-flyout-max-width
6205
+ const cssVariableMaxWidth = '--p-flyout-max-width';
6206
+ const getComponentCss$P = (isOpen, position, hasHeader, hasFooter, hasSubFooter, theme) => {
6207
+ const isPositionStart = position === 'start' || position === 'left';
6036
6208
  return getCss({
6037
6209
  '@global': {
6038
6210
  ':host': {
6039
6211
  display: 'block',
6040
6212
  ...addImportantToEachRule({
6041
- // needed for correct alignment of the Porsche Grid within the Flyout
6042
- '--pds-internal-grid-outer-column': `calc(${spacingFluidLarge} - ${gridGap})`,
6043
- '--pds-internal-grid-margin': `calc(${spacingFluidLarge} * -1)`,
6044
- ...getBackdropJssStyle(isOpen, FLYOUT_Z_INDEX, theme),
6213
+ ...dialogHostJssStyle,
6045
6214
  ...colorSchemeStyles,
6046
6215
  ...hostHiddenStyles,
6047
6216
  }),
6048
6217
  },
6049
- dialog: {
6050
- ...getFlyoutDialogResetJssStyle(),
6051
- insetInline: isPositionStart ? '0 0' : 'auto 0',
6052
- insetBlock: '0 0',
6053
- display: 'flex',
6054
- flexDirection: 'column',
6055
- boxSizing: 'border-box',
6056
- width: 'var(--p-flyout-width, fit-content)',
6057
- minWidth: '320px',
6058
- maxWidth: 'var(--p-flyout-max-width, 1180px)',
6059
- color: primaryColor, // enables color inheritance for slotted content
6060
- background: backgroundColor,
6061
- ...(isOpen
6062
- ? {
6063
- opacity: 1,
6064
- transform: 'initial',
6065
- transition: `${getTransition('opacity', 'long', 'in')}, ${getTransition('transform', 'long', 'in')}`,
6066
- }
6067
- : {
6068
- opacity: 0,
6069
- transform: `translate3d(${isPositionStart ? '-100%' : '100%'}, 0, 0)`,
6070
- transition: `${getTransition('opacity', 'short', 'out', 'long')}, ${getTransition('transform', 'long', 'out')}`,
6071
- }),
6072
- boxShadow: `${isPositionStart ? '3px' : '-3px'} 0px 30px rgba(0, 0, 0, 0.25)`,
6073
- ...prefersColorSchemeDarkMediaQuery(theme, {
6074
- color: primaryColorDark,
6075
- background: backgroundColorDark,
6076
- }),
6077
- '&:focus-visible': {
6078
- outline: 'none', // ua-style reset
6218
+ slot: {
6219
+ display: 'block',
6220
+ '&:first-of-type': {
6221
+ gridRowStart: 1,
6079
6222
  },
6080
- '&::backdrop': {
6081
- // to improve browser backwards compatibility we visually style the backdrop on the :host,
6082
- // although it's not on the #top-layer like it would be for modern browsers supporting ::backdrop
6083
- opacity: 0, // to support backdrop click for modern browsers supporting ::backdrop
6223
+ '&:not([name])': {
6224
+ gridColumn: '2/3',
6225
+ zIndex: 0, // controls layering + creates new stacking context (prevents content within to be above other dialog areas)
6084
6226
  },
6227
+ ...(hasHeader && {
6228
+ '&[name=header]': {
6229
+ ...getDialogStickyAreaJssStyle('header', theme),
6230
+ gridColumn: '1/-1',
6231
+ zIndex: 3, // controls layering + creates new stacking context (prevents content within to be above other dialog areas)
6232
+ },
6233
+ }),
6234
+ ...(hasFooter && {
6235
+ '&[name=footer]': {
6236
+ ...getDialogStickyAreaJssStyle('footer', theme),
6237
+ gridColumn: '1/-1',
6238
+ zIndex: 2, // controls layering + creates new stacking context (prevents content within to be above other dialog areas)
6239
+ },
6240
+ }),
6241
+ ...(hasSubFooter && {
6242
+ '&[name=sub-footer]': {
6243
+ gridColumn: '2/3',
6244
+ zIndex: 1, // controls layering + creates new stacking context (prevents content within to be above other dialog areas)
6245
+ },
6246
+ }),
6085
6247
  },
6248
+ dialog: getDialogJssStyle(isOpen, theme),
6086
6249
  },
6087
- wrapper: {
6088
- display: 'flex', // ua-style reset
6089
- flexGrow: 1,
6090
- height: 0,
6091
- flexDirection: 'column',
6092
- ...(hasSubFooter && {
6093
- overflowY: 'auto',
6094
- overscrollBehaviorY: 'none',
6095
- }),
6096
- },
6097
- header: {
6098
- position: 'sticky',
6099
- top: 0,
6100
- zIndex: 2,
6101
- display: 'grid',
6102
- gridTemplateColumns: `minmax(0, 1fr) ${spacingFluidLarge}`,
6103
- alignItems: 'flex-start',
6104
- padding: `${spacingStaticMedium} 0`,
6105
- paddingInlineStart: spacingFluidLarge,
6106
- background: backgroundColor,
6107
- ...prefersColorSchemeDarkMediaQuery(theme, {
6108
- background: backgroundColorDark,
6109
- }),
6110
- },
6111
- [headerShadowClass]: {
6112
- boxShadow: `${isDark ? scrollShadowColorDark : scrollShadowColor} 0px 5px 10px`,
6113
- ...prefersColorSchemeDarkMediaQuery(theme, {
6114
- boxShadow: `${scrollShadowColorDark} 0px 5px 10px`,
6115
- }),
6250
+ scroller: {
6251
+ ...getScrollerJssStyle(isPositionStart ? 'start' : 'end', theme),
6252
+ // compared to Modal, the transition is handled on the scroller to have correct stucked behaviour (visibility of drop shadow)
6253
+ // for sticky header area while transitioned
6254
+ ...getDialogTransitionJssStyle(isOpen, isPositionStart ? '>' : '<'),
6255
+ },
6256
+ flyout: {
6257
+ ...dialogGridJssStyle,
6258
+ ...getDialogColorJssStyle(theme),
6259
+ width: `var(${cssVariableWidth$2},auto)`,
6260
+ minWidth: '320px',
6261
+ maxWidth: `var(${cssVariableMaxWidth},1180px)`,
6116
6262
  },
6117
6263
  dismiss: {
6118
- gridArea: '1 / 2',
6119
- justifySelf: 'center',
6120
- },
6121
- content: {
6122
- padding: contentPadding,
6123
- maxWidth: `calc(100vw - calc(${spacingFluidLarge} * 2))`,
6124
- position: 'relative',
6125
- zIndex: 0,
6126
- backgroundColor, // to ensure scrollbar coloring is optimal for light theme
6127
- ...prefersColorSchemeDarkMediaQuery(theme, {
6128
- backgroundColor: backgroundColorDark, // to ensure scrollbar coloring is optimal for dark theme
6129
- }),
6130
- // If sub-footer is used scroll shadows have to be done via JS
6131
- ...(!hasSubFooter && {
6132
- overflowY: 'auto',
6133
- WebkitOverflowScrolling: 'touch',
6134
- backgroundImage: `linear-gradient(to top, ${backgroundColor}, ${backgroundColor}), linear-gradient(to top, ${backgroundColor}, ${backgroundColor}), linear-gradient(to top, ${shadowColor}, ${transparentColor}), linear-gradient(to bottom, ${shadowColor}, ${transparentColor})`,
6135
- backgroundPosition: 'bottom center, top center, bottom center, top center',
6136
- backgroundRepeat: 'no-repeat',
6137
- backgroundSize: '100% 20px, 100% 20px, 100% 10px, 100% 10px',
6138
- backgroundAttachment: 'local, local, scroll, scroll',
6139
- overscrollBehaviorY: 'none',
6140
- ...prefersColorSchemeDarkMediaQuery(theme, {
6141
- backgroundImage: `linear-gradient(to top, ${backgroundColorDark}, ${backgroundColorDark}), linear-gradient(to top, ${backgroundColorDark}, ${backgroundColorDark}), linear-gradient(to top, ${scrollShadowColorDark}, ${transparentColorDark}), linear-gradient(to bottom, ${scrollShadowColorDark}, ${transparentColorDark})`,
6142
- backgroundColor: backgroundColorDark, // to ensure scrollbar coloring is optimal for dark theme
6143
- }),
6144
- }),
6264
+ ...getDismissButtonJssStyle(theme, isOpen, !isPositionStart),
6265
+ gridArea: '1/3',
6266
+ zIndex: 4, // ensures dismiss button is above everything
6267
+ position: 'sticky',
6268
+ insetBlockStart: spacingFluidSmall,
6269
+ insetInlineEnd: spacingFluidSmall,
6270
+ marginBlockStart: `calc(${spacingFluidMedium} * -1)`,
6271
+ justifySelf: 'flex-end',
6145
6272
  },
6146
- ...(hasFooter && {
6147
- footer: {
6148
- position: 'sticky',
6149
- bottom: 0,
6150
- zIndex: 1,
6151
- padding: contentPadding,
6152
- background: backgroundColor,
6153
- ...prefersColorSchemeDarkMediaQuery(theme, {
6154
- background: backgroundColorDark,
6155
- }),
6156
- },
6157
- [footerShadowClass$1]: {
6158
- boxShadow: `${isDark ? scrollShadowColorDark : scrollShadowColor} 0px -5px 10px`,
6159
- ...prefersColorSchemeDarkMediaQuery(theme, {
6160
- boxShadow: `${scrollShadowColorDark} 0px -5px 10px`,
6161
- }),
6162
- },
6163
- }),
6164
- ...(hasSubFooter && {
6165
- 'sub-footer': {
6166
- padding: contentPadding,
6167
- },
6168
- }),
6169
6273
  });
6170
6274
  };
6171
6275
 
@@ -6878,203 +6982,126 @@ const getComponentCss$D = (size) => {
6878
6982
  });
6879
6983
  };
6880
6984
 
6881
- const cssVariableSpacingTop = '--p-modal-spacing-top';
6882
- const cssVariableSpacingBottom = '--p-modal-spacing-bottom';
6883
- const mediaQueryXl = getMediaQueryMin('xl');
6884
- const { primaryColor: darkThemePrimaryColor, contrastHighColor: darkThemeContrastHighColor } = getThemedColors('dark');
6885
- const stretchToFullModalWidthClassName = 'stretch-to-full-modal-width';
6886
- const marginTopBottomFallback = 'clamp(16px, 7vh, 192px)';
6887
- const marginTopBottomXlandXxlFallback = 'min(192px, 10vh)';
6888
- const footerShadowClass = 'footer--shadow';
6889
- const getFullscreenJssStyles = (fullscreen) => {
6890
- return fullscreen
6891
- ? {
6892
- minWidth: '100%',
6893
- maxWidth: 'none',
6894
- minHeight: '100%',
6895
- margin: 0,
6896
- borderRadius: 0,
6897
- }
6898
- : {
6899
- minWidth: '276px', // on viewport 320px: calc(${gridColumnWidthBase} * 6 + ${gridGap} * 5)
6900
- maxWidth: '1535.5px', // on viewport 1920px: `calc(${gridColumnWidthXXL} * 14 + ${gridGap} * 13)`
6901
- minHeight: 'auto',
6902
- margin: `var(${cssVariableSpacingTop},${marginTopBottomFallback}) ${gridExtendedOffsetBase} var(${cssVariableSpacingBottom},${marginTopBottomFallback})`,
6903
- borderRadius: borderRadiusMedium,
6904
- };
6905
- };
6906
- const isFullscreenForXl = (fullscreen) => {
6907
- const fullscreenParsed = parseJSON(fullscreen);
6908
- if (typeof fullscreenParsed === 'boolean') {
6909
- return fullscreenParsed;
6910
- }
6911
- else {
6912
- const entries = Object.entries(fullscreenParsed);
6913
- const [lastTrueBreakpoint] = entries.filter(([, val]) => val).pop() || [];
6914
- const [lastFalseBreakpoint] = entries.filter(([, val]) => !val).pop() || [];
6915
- return breakpoints.indexOf(lastTrueBreakpoint) > breakpoints.indexOf(lastFalseBreakpoint);
6916
- }
6917
- };
6918
- const getSlottedJssStyle = (marginValue, hasHeader, hasDismissButton) => {
6919
- const marginPx = `${-marginValue}px`;
6920
- return {
6921
- [`&(.${stretchToFullModalWidthClassName})`]: {
6922
- width: `calc(100% + ${marginValue * 2}px)`,
6923
- margin: `0 ${marginPx}`,
6924
- },
6925
- ...(!hasHeader && {
6926
- [`&(.${stretchToFullModalWidthClassName}:first-child)`]: {
6927
- marginTop: hasDismissButton ? `${-marginValue / 16}rem` : marginPx,
6928
- },
6929
- }),
6930
- [`&(.${stretchToFullModalWidthClassName}:last-child)`]: {
6931
- marginBottom: marginPx,
6932
- },
6933
- };
6934
- };
6935
- const getComponentCss$C = (isOpen, backdrop, isFullscreen, hasDismissButton, hasHeader, hasFooter, theme) => {
6936
- const { primaryColor, backgroundColor } = getThemedColors(theme);
6937
- const { primaryColor: primaryColorDark, backgroundColor: backgroundColorDark } = getThemedColors('dark');
6938
- const isFullscreenForXlAndXxl = isFullscreenForXl(isFullscreen);
6939
- const duration = isOpen ? 'moderate' : 'short';
6940
- const easing = isOpen ? 'in' : 'out';
6941
- const contentPadding = '32px';
6985
+ const cssVariableWidth$1 = '--p-modal-width';
6986
+ const cssVariableSpacingTop = '--p-modal-spacing-top'; // TODO: maybe --p-modal-spacing-block-start would be more precise?
6987
+ const cssVariableSpacingBottom = '--p-modal-spacing-bottom'; // TODO: maybe --p-modal-spacing-block-end would be more precise?
6988
+ const safeZoneVertical = `calc(${spacingFluidSmall} + ${spacingFluidMedium})`;
6989
+ const safeZoneHorizontal = `${spacingFluidLarge}`;
6990
+ const cssClassNameStretchToFullModalWidth = 'stretch-to-full-modal-width';
6991
+ const getComponentCss$C = (isOpen, backdrop, fullscreen, hasDismissButton, hasHeader, hasFooter, theme) => {
6942
6992
  return getCss({
6943
6993
  '@global': {
6944
6994
  ':host': {
6945
- overflowY: 'auto', // overrideable
6995
+ display: 'block',
6946
6996
  ...addImportantToEachRule({
6997
+ ...dialogHostJssStyle,
6947
6998
  ...colorSchemeStyles,
6948
6999
  ...hostHiddenStyles,
6949
- ...getBackdropJssStyle(isOpen, MODAL_Z_INDEX, theme, duration, backdrop),
6950
7000
  }),
6951
7001
  },
6952
- '::slotted': addImportantToEachRule(mergeDeep(getSlottedJssStyle(32, hasHeader, hasDismissButton), buildResponsiveStyles(isFullscreen, (fullscreenValue) => ({
6953
- [`&(.${stretchToFullModalWidthClassName}`]: {
6954
- '&:first-child)': {
6955
- borderRadius: fullscreenValue ? 0 : '8px 8px 0 0',
7002
+ // TODO: why not available to Flyout too?
7003
+ // TODO: discussable if so many styles are a good thing, since we could also expose one or two CSS variables with which a stretch to full width is possible too
7004
+ '::slotted': addImportantToEachRule(mergeDeep({
7005
+ [`&(.${cssClassNameStretchToFullModalWidth})`]: {
7006
+ display: 'block',
7007
+ margin: `0 calc(${safeZoneHorizontal} * -1)`,
7008
+ width: `calc(100% + calc(${safeZoneHorizontal} * 2))`,
7009
+ },
7010
+ ...(!hasHeader && {
7011
+ [`&(.${cssClassNameStretchToFullModalWidth}:first-child)`]: {
7012
+ marginBlockStart: `calc(${safeZoneVertical} * -1)`,
6956
7013
  },
6957
- '&:last-child)': {
6958
- borderRadius: fullscreenValue ? 0 : '0 0 8px 8px',
7014
+ }),
7015
+ ...(!hasFooter && {
7016
+ [`&(.${cssClassNameStretchToFullModalWidth}:last-child)`]: {
7017
+ marginBlockEnd: `calc(${safeZoneVertical} * -1)`,
6959
7018
  },
7019
+ }),
7020
+ }, buildResponsiveStyles(fullscreen, (fullscreenValue) => ({
7021
+ [`&(.${cssClassNameStretchToFullModalWidth}:first-child)`]: {
7022
+ borderTopLeftRadius: fullscreenValue ? 0 : borderRadiusMedium,
7023
+ borderTopRightRadius: fullscreenValue ? 0 : borderRadiusMedium,
7024
+ },
7025
+ [`&(.${cssClassNameStretchToFullModalWidth}:last-child)`]: {
7026
+ borderBottomLeftRadius: fullscreenValue ? 0 : borderRadiusMedium,
7027
+ borderBottomRightRadius: fullscreenValue ? 0 : borderRadiusMedium,
6960
7028
  },
6961
7029
  })))),
6962
- h2: {
6963
- ...headingLargeStyle,
6964
- margin: 0,
6965
- color: primaryColor,
6966
- ...prefersColorSchemeDarkMediaQuery(theme, {
6967
- color: primaryColorDark,
7030
+ slot: {
7031
+ display: 'block',
7032
+ '&:first-of-type': {
7033
+ gridRowStart: 1,
7034
+ },
7035
+ '&:not([name])': {
7036
+ gridColumn: '2/3',
7037
+ zIndex: 0, // controls layering + creates new stacking context (prevents content within to be above other dialog areas)
7038
+ },
7039
+ ...(hasHeader && {
7040
+ '&[name=header]': {
7041
+ gridColumn: '2/3',
7042
+ zIndex: 0, // controls layering + creates new stacking context (prevents content within to be above other dialog areas)
7043
+ },
6968
7044
  }),
6969
- },
6970
- },
6971
- 'scroll-container': {
6972
- display: 'flex',
6973
- inset: 0, // TODO: is this still needed?
6974
- height: '100%',
6975
- overflowY: 'inherit',
6976
- alignItems: 'center',
6977
- justifyContent: 'center',
6978
- flexWrap: 'wrap',
6979
- },
6980
- root: mergeDeep({
6981
- color: primaryColor, // enables color inheritance for slotted content
6982
- position: 'relative',
6983
- boxSizing: 'border-box',
6984
- transform: isOpen ? 'translateY(0%)' : 'translateY(25%)',
6985
- opacity: isOpen ? 1 : 0,
6986
- transition: `${getTransition('opacity', duration, easing)}, ${getTransition('transform', duration, easing)}`,
6987
- paddingTop: hasDismissButton ? '2rem' : contentPadding, // rem value needed to prevent overlapping of close button and contents in scaling mode
6988
- ...(!hasFooter && { paddingBottom: contentPadding }),
6989
- background: backgroundColor,
6990
- outline: isHighContrastMode ? '1px solid transparent' : 0,
6991
- // TODO: getFocusJssStyle() can't be re-used atm, but as soon as component is refactored to `<dialog />` then no
6992
- // focus should be necessary at all because focus is auto forwarded to dismiss button.
6993
- // ::after to be above sticky footer without z-index games
6994
- '&:focus::after': {
6995
- content: '""',
6996
- position: 'fixed',
6997
- border: `${borderWidthBase} solid`,
6998
- pointerEvents: 'none', // fix text selection in focus state
6999
- ...buildResponsiveStyles(isFullscreen, (fullscreenValue) => ({
7000
- borderRadius: fullscreenValue ? 0 : '12px',
7001
- borderColor: fullscreenValue ? primaryColor : darkThemePrimaryColor,
7002
- inset: fullscreenValue ? 0 : '-4px',
7003
- ...prefersColorSchemeDarkMediaQuery(theme, {
7004
- borderColor: darkThemePrimaryColor,
7005
- }),
7006
- })),
7007
- },
7008
- '&:not(:focus-visible)::before': {
7009
- border: 0,
7010
- },
7011
- [mediaQueryXl]: {
7012
- margin: isFullscreenForXlAndXxl
7013
- ? 0
7014
- : `var(${cssVariableSpacingTop},${marginTopBottomXlandXxlFallback}) ${gridExtendedOffsetBase} var(${cssVariableSpacingBottom},${marginTopBottomXlandXxlFallback})`,
7015
- },
7016
- ...prefersColorSchemeDarkMediaQuery(theme, {
7017
- color: primaryColorDark,
7018
- background: backgroundColorDark,
7019
- }),
7020
- }, buildResponsiveStyles(isFullscreen, getFullscreenJssStyles) // potentially needs to be merged with mediaQueryXl
7021
- ),
7022
- ...(hasHeader && {
7023
- header: {
7024
- padding: `0 ${contentPadding} 8px`,
7025
- },
7026
- }),
7027
- content: {
7028
- ...(hasFooter && {
7029
- position: 'relative', // to make sure content isn't above sticky footer, but might affect consumer's absolute positioning
7030
- zIndex: 0,
7031
- }),
7032
- padding: `0 ${contentPadding}`,
7033
- },
7034
- ...(hasFooter && {
7035
- footer: {
7036
- position: 'sticky',
7037
- background: backgroundColor,
7038
- padding: contentPadding,
7039
- bottom: 0,
7040
- borderBottomLeftRadius: borderRadiusMedium,
7041
- borderBottomRightRadius: borderRadiusMedium,
7042
- ...prefersColorSchemeDarkMediaQuery(theme, {
7043
- background: backgroundColorDark,
7045
+ ...(hasFooter && {
7046
+ '&[name=footer]': {
7047
+ ...getDialogStickyAreaJssStyle('footer', theme),
7048
+ gridColumn: '1/-1',
7049
+ zIndex: 1, // controls layering + creates new stacking context (prevents content within to be above other dialog areas)
7050
+ },
7044
7051
  }),
7045
7052
  },
7046
- [footerShadowClass]: {
7047
- boxShadow: `${isThemeDark(theme) ? scrollShadowColorDark : scrollShadowColor} 0 -5px 10px`,
7048
- clipPath: 'inset(-20px 0 0 0)', // crop leaking box-shadow on left and right side
7049
- ...prefersColorSchemeDarkMediaQuery(theme, {
7050
- boxShadow: `${scrollShadowColorDark} 0 -5px 10px`,
7053
+ ...(hasHeader && {
7054
+ // TODO: we should either deprecate heading slot + pre-styled headings or implement it in flyout too
7055
+ [`slot[name=heading],${headingTags}`]: {
7056
+ gridRowStart: 1,
7057
+ gridColumn: '2/3',
7058
+ zIndex: 0, // controls layering + creates new stacking context (prevents content within to be above other dialog areas)
7059
+ ...headingLargeStyle,
7060
+ margin: 0, // relevant for shadowed h1,h2,h3,…
7061
+ },
7062
+ [`:is(${headingTags}) ~ slot:first-of-type`]: {
7063
+ gridRowStart: 'auto',
7064
+ },
7065
+ [`::slotted([slot="heading"]:is(${headingTags}))`]: {
7066
+ margin: 0, // ua-style (relevant for e.g. <h3 slot="heading"/>)
7067
+ },
7068
+ }),
7069
+ dialog: getDialogJssStyle(isOpen, theme, backdrop),
7070
+ },
7071
+ scroller: getScrollerJssStyle('fullscreen', theme),
7072
+ modal: {
7073
+ ...dialogGridJssStyle,
7074
+ ...getDialogColorJssStyle(theme),
7075
+ ...getDialogTransitionJssStyle(isOpen, '^'),
7076
+ // TODO: maybe we should deprecate the fullscreen property and force the modal to be fullscreen on mobile only
7077
+ ...buildResponsiveStyles(fullscreen, (fullscreenValue) => fullscreenValue
7078
+ ? {
7079
+ width: 'auto',
7080
+ minWidth: 'auto',
7081
+ maxWidth: 'none',
7082
+ placeSelf: 'stretch',
7083
+ margin: 0,
7084
+ borderRadius: 0,
7085
+ }
7086
+ : {
7087
+ width: `var(${cssVariableWidth$1},auto)`,
7088
+ minWidth: '276px', // to be in sync with "Porsche Grid" on viewport = 320px: calc(${gridColumnWidthBase} * 6 + ${gridGap} * 5)
7089
+ maxWidth: '1535.5px', // to be in sync with "Porsche Grid" on viewport >= 1920px: `calc(${gridColumnWidthXXL} * 14 + ${gridGap} * 13)`
7090
+ placeSelf: 'center',
7091
+ margin: `var(${cssVariableSpacingTop},clamp(16px, 10vh, 192px)) ${gridExtendedOffsetBase} var(${cssVariableSpacingBottom},clamp(16px, 10vh, 192px))`, // horizontal margin is needed to ensure modal is placed on "Porsche Grid" when slotted content is wider than the viewport width
7092
+ borderRadius: borderRadiusMedium,
7051
7093
  }),
7052
- },
7053
- }),
7094
+ },
7054
7095
  ...(hasDismissButton && {
7055
- controls: {
7056
- position: 'absolute',
7057
- top: '8px',
7058
- right: '8px',
7059
- left: '8px',
7060
- display: 'flex',
7061
- justifyContent: 'flex-end',
7062
- zIndex: 1, // To assure controls are on top when using stretchToFullModalWidthClassName and transformed slotted content
7063
- },
7064
7096
  dismiss: {
7065
- border: `2px solid ${backgroundColor}`, // needed to enlarge button slightly without affecting the hover area (are equal now).
7066
- borderRadius: '4px',
7067
- background: backgroundColor,
7068
- ...hoverMediaQuery({
7069
- '&:hover': {
7070
- background: darkThemeContrastHighColor,
7071
- borderColor: darkThemeContrastHighColor,
7072
- },
7073
- }),
7074
- ...prefersColorSchemeDarkMediaQuery(theme, {
7075
- background: backgroundColorDark,
7076
- borderColor: backgroundColorDark,
7077
- }),
7097
+ ...getDismissButtonJssStyle(theme, isOpen),
7098
+ gridArea: '1/3',
7099
+ zIndex: 2, // ensures dismiss button is above sticky footer, header and content
7100
+ position: 'sticky',
7101
+ insetBlockStart: spacingFluidSmall,
7102
+ marginBlockStart: `calc(${spacingFluidMedium} * -1)`,
7103
+ marginInlineEnd: spacingFluidSmall,
7104
+ justifySelf: 'flex-end',
7078
7105
  },
7079
7106
  }),
7080
7107
  });