@porsche-design-system/components-react 4.7.0-beta.0 → 4.7.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 (24) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/bin/pds-skill.js +50 -41
  3. package/package.json +2 -2
  4. package/skills/pds-audit-deprecations-react/SKILL.md +247 -0
  5. package/skills/pds-audit-deprecations-react/references/report-template.md +128 -0
  6. package/skills/pds-audit-deprecations-react/references/report.schema.json +446 -0
  7. package/skills/pds-knowledge-react/SKILL.md +10 -4
  8. package/skills/pds-knowledge-react/references/components/p-button/examples/AiGradientGlow.tsx +1 -1
  9. package/skills/pds-knowledge-react/references/deprecations.md +686 -0
  10. package/skills/pds-knowledge-react/references/styles/scss.md +3 -2
  11. package/skills/pds-knowledge-react/references/styles/tailwindcss.md +0 -2
  12. package/ssr/cjs/components/dist/styles/esm/styles-entry.cjs +66 -48
  13. package/ssr/cjs/components/dist/utils/esm/utils-entry.cjs +39 -10
  14. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/button-tile.cjs +1 -2
  15. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/dialog-base.cjs +1 -1
  16. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/link-tile.cjs +2 -2
  17. package/ssr/cjs/components-react/projects/react-ssr-wrapper/src/splitChildren.cjs +3 -1
  18. package/ssr/esm/components/dist/styles/esm/styles-entry.mjs +66 -48
  19. package/ssr/esm/components/dist/utils/esm/utils-entry.mjs +38 -11
  20. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/button-tile.mjs +2 -3
  21. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/dialog-base.mjs +1 -1
  22. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/link-tile.mjs +2 -2
  23. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/splitChildren.mjs +3 -1
  24. package/tailwindcss/index.css +16 -16
@@ -93,8 +93,9 @@ reference below to discover what is available; read the shipped partials for the
93
93
  ### Deprecated aliases
94
94
 
95
95
  The package still ships the legacy `$pds-*` variables and `pds-*` mixins as deprecated aliases so
96
- existing stylesheets keep compiling. Prefer the documented variables and mixins listed here for new
97
- code.
96
+ existing stylesheets keep compiling. Each is preceded by a `// @deprecated …` comment in the
97
+ shipped partials naming its replacement, and the complete list is in the knowledge skill's
98
+ `references/deprecations.md`. Prefer the documented variables and mixins listed here for new code.
98
99
 
99
100
  ## Contents
100
101
 
@@ -85,8 +85,6 @@ valid when sections need independent grids.
85
85
  | Theme variable | Tailwind class(es) | Description | Value |
86
86
  | --- | --- | --- | --- |
87
87
  | `--default-border-width` | – | Default border width applied globally via the Tailwind `@theme` block. | `1px` |
88
- | `--border-width-regular` | – | Alias for the regular (2 px) border width. **Deprecated** — prefer `--default-border-width`. | `2px` |
89
- | `--border-width-thin` | – | Alias for the thin (1 px) border width. **Deprecated** — prefer `--default-border-width`. | `1px` |
90
88
 
91
89
  ### Blur
92
90
 
@@ -3509,37 +3509,37 @@ const isDisabledOrLoading = (disabled, loading) => {
3509
3509
  /** Holds the **Porsche Next** font family along with fallback fonts. */
3510
3510
  const fontPorscheNext = "'Porsche Next','Arial Narrow',Arial,'Heiti SC',SimHei,sans-serif";
3511
3511
 
3512
- /** @deprecated since v4.0.0, will be removed with next major release. Use fontPorscheNext instead. */
3512
+ /** @deprecated Use {@link fontPorscheNext} instead. This API will be removed with the next major release. */
3513
3513
  const fontFamily = fontPorscheNext;
3514
3514
 
3515
3515
  /** Holds a dynamic default line height specifically optimized for the Porsche Next typeface. */
3516
3516
  const leadingNormal = 'calc(6px + 2.125ex)';
3517
3517
 
3518
- /** @deprecated since v4.0.0, will be removed with next major release. Use leadingNormal instead */
3518
+ /** @deprecated Use {@link leadingNormal} instead. This API will be removed with the next major release. */
3519
3519
  const fontLineHeight = leadingNormal;
3520
3520
 
3521
3521
  /** Holds the **small** font size optimized for the Porsche Next typeface. */
3522
3522
  const typescaleSm = '1rem';
3523
3523
 
3524
- /** @deprecated since v4.0.0, will be removed with next major release. Use typescaleSm instead. */
3524
+ /** @deprecated Use {@link typescaleSm} instead. This API will be removed with the next major release. */
3525
3525
  const fontSizeTextSmall = typescaleSm;
3526
3526
 
3527
3527
  /** Holds the **x-small** font size optimized for the Porsche Next typeface. */
3528
3528
  const typescaleXs = '.875rem';
3529
3529
 
3530
- /** @deprecated since v4.0.0, will be removed with next major release. Use typescaleXs instead. */
3530
+ /** @deprecated Use {@link typescaleXs} instead. This API will be removed with the next major release. */
3531
3531
  const fontSizeTextXSmall = typescaleXs;
3532
3532
 
3533
- /** @deprecated since v4.0.0, will be removed with next major release. Use 'normal' instead. */
3533
+ /** @deprecated This API will be removed with the next major release. Use 'normal' instead. */
3534
3534
  const fontStyleNormal = 'normal';
3535
3535
 
3536
- /** @deprecated since v4.0.0, will be removed with next major release. Use 'normal' instead. */
3536
+ /** @deprecated This API will be removed with the next major release. Use 'normal' instead. */
3537
3537
  const fontVariant = 'normal';
3538
3538
 
3539
3539
  /** Holds the **normal** font weight optimized for the Porsche Next typeface. */
3540
3540
  const fontWeightNormal = 400;
3541
3541
 
3542
- /** @deprecated since v4.0.0, will be removed with next major release. Use fontWeightNormal instead. */
3542
+ /** @deprecated Use {@link fontWeightNormal} instead. This API will be removed with the next major release. */
3543
3543
  const fontWeightRegular = fontWeightNormal;
3544
3544
 
3545
3545
  /** Holds a gradient fade. */
@@ -3560,12 +3560,12 @@ const gradientStopsFadeDark = 'hsla(0,0%,0%,.8) 0%,' +
3560
3560
  'hsla(0,0%,0%,.011) 91.9%,' +
3561
3561
  'hsla(0,0%,0%,0) 100%';
3562
3562
 
3563
- /** @deprecated since v4.0.0, will be removed with next major release. Use background: `linear-gradient(to bottom, ${gradientStopsFadeDark});` instead */
3563
+ /** @deprecated This API will be removed with the next major release. Use background: `linear-gradient(to bottom, ${gradientStopsFadeDark});` instead. */
3564
3564
  const gradientToBottomStyle = {
3565
3565
  background: `linear-gradient(to bottom, ${gradientStopsFadeDark});`,
3566
3566
  };
3567
3567
 
3568
- /** @deprecated since v4.0.0, will be removed with next major release. background: `linear-gradient(to top, ${gradientStopsFadeDark});` instead */
3568
+ /** @deprecated This API will be removed with the next major release. background: `linear-gradient(to top, ${gradientStopsFadeDark});` instead. */
3569
3569
  const gradientToTopStyle = {
3570
3570
  background: `linear-gradient(to top, ${gradientStopsFadeDark});`,
3571
3571
  };
@@ -3619,7 +3619,7 @@ function getMediaQueryMin(min) {
3619
3619
  /** Holds the **medium fluid** spacing. */
3620
3620
  const spacingFluidMd = 'clamp(16px, 1.25vw + 12px, 36px)';
3621
3621
 
3622
- /** @deprecated since v4.0.0, will be removed with next major release. Use spacingFluidMd instead. */
3622
+ /** @deprecated Use {@link spacingFluidMd} instead. This API will be removed with the next major release. */
3623
3623
  const spacingFluidMedium = spacingFluidMd;
3624
3624
 
3625
3625
  const gridGap = spacingFluidMedium;
@@ -3688,35 +3688,35 @@ function getMediaQueryMax(max) {
3688
3688
  /** Holds a **moderate** motion/transition duration value. */
3689
3689
  const durationMd = '.4s';
3690
3690
 
3691
- /** @deprecated since v4.0.0, will be removed with next major release. Use durationMd instead. */
3691
+ /** @deprecated Use {@link durationMd} instead. This API will be removed with the next major release. */
3692
3692
  const motionDurationModerate = durationMd;
3693
3693
 
3694
3694
  /** Holds an **in** `transition-timing-function`. */
3695
3695
  const easeIn = 'cubic-bezier(0,0,.2,1)';
3696
3696
 
3697
- /** @deprecated since v4.0.0, will be removed with next major release. Use easeIn instead. */
3697
+ /** @deprecated Use {@link easeIn} instead. This API will be removed with the next major release. */
3698
3698
  const motionEasingIn = easeIn;
3699
3699
 
3700
3700
  /** Holds an **out** `transition-timing-function`. */
3701
3701
  const easeOut = 'cubic-bezier(.4,0,.5,1)';
3702
3702
 
3703
- /** @deprecated since v4.0.0, will be removed with next major release. Use easeOut instead. */
3703
+ /** @deprecated Use {@link easeOut} instead. This API will be removed with the next major release. */
3704
3704
  const motionEasingOut = easeOut;
3705
3705
 
3706
3706
  const _textFontPartA = `${fontStyleNormal} ${fontVariant} ${fontWeightRegular} `;
3707
3707
  const _textFontPartB = `/${fontLineHeight} ${fontFamily}`;
3708
3708
 
3709
- /** @deprecated since v4.0.0, will be removed with next major release. Use proseTextXs instead. */
3709
+ /** @deprecated Use {@link proseTextXsStyle} instead. This API will be removed with the next major release. */
3710
3710
  const textXSmallStyle = {
3711
3711
  font: `${_textFontPartA}${fontSizeTextXSmall}${_textFontPartB}`,
3712
3712
  };
3713
3713
 
3714
- /** @deprecated since v4.0.0, will be removed with next major release. Use proseTextSm instead. */
3714
+ /** @deprecated Use {@link proseTextSmStyle} instead. This API will be removed with the next major release. */
3715
3715
  const textSmallStyle = {
3716
3716
  font: `${_textFontPartA}${fontSizeTextSmall}${_textFontPartB}`,
3717
3717
  };
3718
3718
 
3719
- const parseJSON = (prop) => {
3719
+ const parse = (prop) => {
3720
3720
  if (typeof prop === 'string') {
3721
3721
  try {
3722
3722
  // prop is potentially JSON parsable string, e.g. "{ base: 'block', l: 'inline' }" or "true" or "false"
@@ -3735,6 +3735,20 @@ const parseJSON = (prop) => {
3735
3735
  return prop;
3736
3736
  }
3737
3737
  };
3738
+ // boolean props have to be parsed via parseJSONBoolean(), therefore the parameter type excludes them to make it
3739
+ // impossible to lose the HTML boolean attribute shorthand by accident
3740
+ const parseJSON = (prop) => parse(prop);
3741
+ const parseJSONBoolean = (prop) =>
3742
+ // prop is an HTML boolean attribute used without a value, e.g. <p-input-text hide-label>
3743
+ // Stencil resolves BreakpointCustomizable<T> to "any" and therefore skips its own boolean coercion
3744
+ // TODO: [v5] obsolete once objects can only be set via property, since Stencil coerces booleans itself then, see #4708
3745
+ (prop === '' ? true : parse(prop));
3746
+ // a BreakpointCustomizable value can be true for certain breakpoints only, e.g. { base: false, l: true },
3747
+ // therefore styles which are needed as soon as it is true anywhere have to be determined like this
3748
+ const isTruthyForAnyBreakpoint = (prop) => {
3749
+ const value = parseJSONBoolean(prop);
3750
+ return typeof value === 'object' ? Object.values(value).some(Boolean) : !!value;
3751
+ };
3738
3752
 
3739
3753
  // NOTE: handpicked selection of plugins from jss-preset-default
3740
3754
  const jss = createJss({
@@ -3760,8 +3774,7 @@ const supportsConstructableStylesheets = () => {
3760
3774
  };
3761
3775
  // determine it once
3762
3776
  supportsConstructableStylesheets();
3763
- const buildResponsiveStyles = (rawValue, getJssStyle) => {
3764
- const value = parseJSON(rawValue);
3777
+ const buildStyles = (value, getJssStyle) => {
3765
3778
  return typeof value === 'object'
3766
3779
  ? Object.keys(value)
3767
3780
  // base styles are applied on root object, responsive styles are nested within
@@ -3773,6 +3786,11 @@ const buildResponsiveStyles = (rawValue, getJssStyle) => {
3773
3786
  }), getJssStyle(value.base))
3774
3787
  : getJssStyle(value);
3775
3788
  };
3789
+ // boolean props have to use buildResponsiveBooleanStyles(), therefore the generic excludes them to make it impossible
3790
+ // to lose the HTML boolean attribute shorthand by accident
3791
+ const buildResponsiveStyles = (rawValue, getJssStyle) => buildStyles(parseJSON(rawValue), getJssStyle);
3792
+ // TODO: [v5] can be merged back into buildResponsiveStyles() once objects can only be set via property, see #4708
3793
+ const buildResponsiveBooleanStyles = (rawValue, getJssStyle) => buildStyles(parseJSONBoolean(rawValue), getJssStyle);
3776
3794
  const isObject = (obj) => typeof obj === 'object' && !Array.isArray(obj);
3777
3795
  // NOTE: taken from https://stackoverflow.com/a/48218209
3778
3796
  const mergeDeep = (...objects) => {
@@ -3849,7 +3867,7 @@ const OPTION_LIST_SAFE_ZONE = 6;
3849
3867
 
3850
3868
  const getCDNBaseURL = () => global.PORSCHE_DESIGN_SYSTEM_CDN_URL + "/porsche-design-system";
3851
3869
 
3852
- const prefix = `[Porsche Design System v${"4.7.0-beta.0"}]` // this part isn't covered by unit tests
3870
+ const prefix = `[Porsche Design System v${"4.7.0"}]` // this part isn't covered by unit tests
3853
3871
  ;
3854
3872
  const consoleError = (...messages) => {
3855
3873
  console.error(prefix, ...messages);
@@ -4087,7 +4105,7 @@ const getComponentCss$1a = (alignMarker, background, isCompact, indent, isOpen,
4087
4105
  }),
4088
4106
  '& > div': {
4089
4107
  gridArea: '2/1/auto/-1',
4090
- ...buildResponsiveStyles(indent, (isIndented) => ({
4108
+ ...buildResponsiveBooleanStyles(indent, (isIndented) => ({
4091
4109
  gridColumnStart: isIndented ? summaryColumnStart : 1,
4092
4110
  })),
4093
4111
  zIndex: 0, // ensures stacking to be below the summary section
@@ -4741,7 +4759,7 @@ const getLinkButtonPureStyles = (icon, iconSource, active, isDisabledOrLoading,
4741
4759
  transform: 'translate3d(0,0,0)', // creates new stacking context
4742
4760
  ...hostHiddenStyles,
4743
4761
  }),
4744
- ...buildResponsiveStyles(stretch, (responsiveStretch) => ({
4762
+ ...buildResponsiveBooleanStyles(stretch, (responsiveStretch) => ({
4745
4763
  display: responsiveStretch ? 'block' : 'inline-block',
4746
4764
  width: responsiveStretch ? '100%' : 'auto', // prevents adjusting its size when used as flex or grid child
4747
4765
  ...(!responsiveStretch && { verticalAlign: 'top' }),
@@ -4757,9 +4775,9 @@ const getLinkButtonPureStyles = (icon, iconSource, active, isDisabledOrLoading,
4757
4775
  color: colorMap$3[color],
4758
4776
  textDecoration: underline ? 'underline' : 'none',
4759
4777
  font: `${ref(fontWeightNormal$1)} ${ref(typescaleSm$1)}/${ref(leadingNormal$1)} ${ref(fontPorscheNext$1)}`,
4760
- ...mergeDeep(buildResponsiveStyles(hideLabel, (hidelabelValue) => ({
4778
+ ...mergeDeep(buildResponsiveBooleanStyles(hideLabel, (hidelabelValue) => ({
4761
4779
  gap: hidelabelValue ? 0 : ref(spacingStaticXs$1),
4762
- })), buildResponsiveStyles(stretch, (stretchValue) => ({
4780
+ })), buildResponsiveBooleanStyles(stretch, (stretchValue) => ({
4763
4781
  justifyContent: stretchValue ? 'space-between' : 'flex-start',
4764
4782
  alignItems: stretchValue ? 'center' : 'flex-start',
4765
4783
  })), buildResponsiveStyles(size, (v) => ({
@@ -4776,7 +4794,7 @@ const getLinkButtonPureStyles = (icon, iconSource, active, isDisabledOrLoading,
4776
4794
  position: 'absolute', // mobile Safari -> prevent lagging active state
4777
4795
  top: offsetVertical,
4778
4796
  bottom: offsetVertical,
4779
- ...buildResponsiveStyles(hideLabel, (hideLabelValue) => ({
4797
+ ...buildResponsiveBooleanStyles(hideLabel, (hideLabelValue) => ({
4780
4798
  right: hideLabelValue ? offsetVertical : offsetHorizontal,
4781
4799
  left: hideLabelValue ? offsetVertical : offsetHorizontal,
4782
4800
  borderRadius: hideLabelValue ? ref(radiusFull) : ref(radiusLg),
@@ -4807,7 +4825,7 @@ const getLinkButtonPureStyles = (icon, iconSource, active, isDisabledOrLoading,
4807
4825
  flexShrink: '0',
4808
4826
  },
4809
4827
  label: mergeDeep({ zIndex: '1' }, // fix Firefox bug on :hover (#2583) & pure-link with nested anchor & hidden label (#3349)
4810
- buildResponsiveStyles(hideLabel, getVisibilityJssStyle), buildResponsiveStyles(alignLabel, (alignLabelValue) => ({
4828
+ buildResponsiveBooleanStyles(hideLabel, getVisibilityJssStyle), buildResponsiveStyles(alignLabel, (alignLabelValue) => ({
4811
4829
  order: alignLabelValue === 'start' ? -1 : 0,
4812
4830
  }))),
4813
4831
  }
@@ -4963,7 +4981,7 @@ const getComponentCss$16 = (isDisabledOrLoading, aspectRatio, size, weight, alig
4963
4981
  },
4964
4982
  footer: {
4965
4983
  gridArea: `${isTopAligned ? 2 : 4}/2`,
4966
- ...buildResponsiveStyles(compact, (compactValue) => compactValue
4984
+ ...buildResponsiveBooleanStyles(compact, (compactValue) => compactValue
4967
4985
  ? {
4968
4986
  display: 'grid',
4969
4987
  gridTemplateColumns: 'minmax(0,1fr) auto',
@@ -4980,7 +4998,7 @@ const getComponentCss$16 = (isDisabledOrLoading, aspectRatio, size, weight, alig
4980
4998
  gridColumn: 2,
4981
4999
  gridRow: `1/${hasFooterSlot ? 3 : 2}`,
4982
5000
  alignSelf: isTopAligned ? 'flex-start' : 'flex-end',
4983
- ...buildResponsiveStyles(compact, (compactValue) => ({
5001
+ ...buildResponsiveBooleanStyles(compact, (compactValue) => ({
4984
5002
  display: compactValue ? 'inline-block' : 'none',
4985
5003
  })),
4986
5004
  },
@@ -4988,7 +5006,7 @@ const getComponentCss$16 = (isDisabledOrLoading, aspectRatio, size, weight, alig
4988
5006
  minHeight: '54px', // prevent content shift
4989
5007
  zIndex: 5,
4990
5008
  marginTop: ref(spacingStaticMd),
4991
- ...buildResponsiveStyles(compact, (compactValue) => ({
5009
+ ...buildResponsiveBooleanStyles(compact, (compactValue) => ({
4992
5010
  display: compactValue ? 'none' : 'inline-block',
4993
5011
  })),
4994
5012
  },
@@ -5020,7 +5038,7 @@ const getVariantColors = (variant, cssVariableBackground, cssVariableForeground)
5020
5038
  };
5021
5039
  const getLinkButtonStyles = (icon, iconSource, variant, hideLabel, isDisabledOrLoading, hasSlottedAnchor, isCompact, cssVariableInternalScaling, cssVariableBackground, cssVariableForeground, cssVarPaddingInline, cssVarPaddingBlock, cssVarGap, cssVarRadius) => {
5022
5040
  const { textColor, textColorHover, backgroundColor, backgroundColorHover } = getVariantColors(variant, cssVariableBackground, cssVariableForeground);
5023
- const hasIcon = hasVisibleIcon(icon, iconSource) || hideLabel;
5041
+ const hasIcon = hasVisibleIcon(icon, iconSource) || isTruthyForAnyBreakpoint(hideLabel);
5024
5042
  const paddingBlock = `calc(28px * (${ref(cssVariableInternalScaling)} - 0.64285714) + 6px)`;
5025
5043
  const paddingInline = `calc(33.6px * (${ref(cssVariableInternalScaling)} - 0.64285714) + 16px)`;
5026
5044
  const gap = `calc(11.2px * (${ref(cssVariableInternalScaling)} - 0.64285714) + 4px)`;
@@ -5030,10 +5048,10 @@ const getLinkButtonStyles = (icon, iconSource, variant, hideLabel, isDisabledOrL
5030
5048
  ':host': {
5031
5049
  display: 'inline-block',
5032
5050
  verticalAlign: 'top',
5033
- ...mergeDeep(buildResponsiveStyles(isCompact, (compactValue) => ({
5051
+ ...mergeDeep(buildResponsiveBooleanStyles(isCompact, (compactValue) => ({
5034
5052
  [`${cssVariableInternalScaling}`]: compactValue ? 0.64285714 : 1,
5035
5053
  '--_p-link-button-a': compactValue ? ref(radiusLg) : ref(radiusXl),
5036
- })), buildResponsiveStyles(hideLabel, (hideLabelValue) => ({
5054
+ })), buildResponsiveBooleanStyles(hideLabel, (hideLabelValue) => ({
5037
5055
  borderRadius: addImportantToRule(ref(cssVarRadius, hideLabelValue ? ref(radiusFull) : ref('--_p-link-button-a'))),
5038
5056
  }))),
5039
5057
  ...addImportantToEachRule({
@@ -5058,7 +5076,7 @@ const getLinkButtonStyles = (icon, iconSource, variant, hideLabel, isDisabledOrL
5058
5076
  color: textColor,
5059
5077
  cursor: 'pointer',
5060
5078
  transition: `${getTransition('background-color')}, ${getTransition('border-color')}, ${getTransition('color')}`,
5061
- ...buildResponsiveStyles(hideLabel, (hideLabelValue) => ({
5079
+ ...buildResponsiveBooleanStyles(hideLabel, (hideLabelValue) => ({
5062
5080
  padding: `${ref(cssVarPaddingBlock, paddingBlock)} ${ref(cssVarPaddingInline, hideLabelValue ? paddingBlock : paddingInline)}`,
5063
5081
  gap: ref(cssVarGap, hideLabelValue ? 0 : gap),
5064
5082
  })),
@@ -5086,13 +5104,13 @@ const getLinkButtonStyles = (icon, iconSource, variant, hideLabel, isDisabledOrL
5086
5104
  },
5087
5105
  })),
5088
5106
  },
5089
- label: buildResponsiveStyles(hideLabel, getHiddenTextJssStyle),
5107
+ label: buildResponsiveBooleanStyles(hideLabel, getHiddenTextJssStyle),
5090
5108
  ...(hasIcon && {
5091
5109
  icon: {
5092
5110
  font: `${ref(typescaleSm$1)} ${ref(fontPorscheNext$1)}`, // needed for correct width/height definition based on ex-unit
5093
5111
  width: ref(leadingNormal$1), // ensure space is already reserved until icon component is loaded (ssr)
5094
5112
  height: ref(leadingNormal$1), // ensure space is already reserved until icon component is loaded (ssr)
5095
- ...buildResponsiveStyles(hideLabel, (hideLabelValue) => ({
5113
+ ...buildResponsiveBooleanStyles(hideLabel, (hideLabelValue) => ({
5096
5114
  marginInlineStart: hideLabelValue ? 0 : iconMarginInlineStart, // compensate white space of svg icon and optimize visual alignment
5097
5115
  })),
5098
5116
  },
@@ -5717,7 +5735,7 @@ const getComponentCss$13 = (gradient, hasHeading, hasDescription, hasControlsSlo
5717
5735
  },
5718
5736
  ...(hasPagination && {
5719
5737
  'pagination-container': {
5720
- ...buildResponsiveStyles(hasPagination, (hasPaginationValue) => ({
5738
+ ...buildResponsiveBooleanStyles(hasPagination, (hasPaginationValue) => ({
5721
5739
  display: hasPaginationValue ? 'flex' : 'none',
5722
5740
  })),
5723
5741
  position: 'relative',
@@ -5990,7 +6008,7 @@ const getFunctionalComponentLabelStyles = (isDisabled, isLoading, hideLabel, add
5990
6008
  const isDisabledOrLoading = isDisabled || isLoading;
5991
6009
  return {
5992
6010
  'label-wrapper': {
5993
- ...buildResponsiveStyles(hideLabel, (isHidden) => ({
6011
+ ...buildResponsiveBooleanStyles(hideLabel, (isHidden) => ({
5994
6012
  ...(!isHidden && { minWidth: 'fit-content' }), // ensures label contents don't shrink to zero in grid containers
5995
6013
  ...getHiddenTextJssStyle(isHidden, additionalIsShownJssStyle),
5996
6014
  })),
@@ -6016,7 +6034,7 @@ const getFunctionalComponentLabelStyles = (isDisabled, isLoading, hideLabel, add
6016
6034
  cursor: 'unset',
6017
6035
  fontSize: ref(typescaleXs$1),
6018
6036
  color: ref(colorContrastHigh),
6019
- ...buildResponsiveStyles(hideLabel, (isHidden) => getHiddenTextJssStyle(isHidden, { marginTop: `calc(-1 * ${ref(spacingStaticXs$1)})` })),
6037
+ ...buildResponsiveBooleanStyles(hideLabel, (isHidden) => getHiddenTextJssStyle(isHidden, { marginTop: `calc(-1 * ${ref(spacingStaticXs$1)})` })),
6020
6038
  marginTop: `calc(-1 * ${ref(spacingStaticXs$1)})`,
6021
6039
  },
6022
6040
  '& > slot[name="label"]::slotted(*)': {
@@ -7432,7 +7450,7 @@ const getComponentCss$V = (isOpen, background, backdrop, position, hasHeader, ha
7432
7450
  flyout: {
7433
7451
  ...dialogGridJssStyle(),
7434
7452
  ...getDialogColorJssStyle(),
7435
- ...buildResponsiveStyles(fullscreen, (fullscreenValue) => fullscreenValue
7453
+ ...buildResponsiveBooleanStyles(fullscreen, (fullscreenValue) => fullscreenValue
7436
7454
  ? {
7437
7455
  // fullscreen spans the whole viewport width, so corners are squared and corner clipping is disabled
7438
7456
  width: '100dvw',
@@ -7888,7 +7906,7 @@ const getComponentCss$G = (icon, iconSource, active, stretch, size, color, hideL
7888
7906
  content: '""',
7889
7907
  position: 'fixed',
7890
7908
  insetBlock: offsetVertical,
7891
- ...buildResponsiveStyles(hideLabel, (hideLabelValue) => ({
7909
+ ...buildResponsiveBooleanStyles(hideLabel, (hideLabelValue) => ({
7892
7910
  insetInline: hideLabelValue ? offsetVertical : offsetHorizontal,
7893
7911
  borderRadius: hideLabelValue ? ref(radiusFull) : ref(radiusLg),
7894
7912
  })),
@@ -8152,7 +8170,7 @@ const getComponentCss$E = (aspectRatio, size, weight, align, compact, hasGradien
8152
8170
  },
8153
8171
  footer: {
8154
8172
  gridArea: `${isTopAligned ? 2 : 4}/2`,
8155
- ...buildResponsiveStyles(compact, (compactValue) => compactValue
8173
+ ...buildResponsiveBooleanStyles(compact, (compactValue) => compactValue
8156
8174
  ? {
8157
8175
  display: 'grid',
8158
8176
  gridTemplateColumns: 'minmax(0,1fr) auto',
@@ -8169,7 +8187,7 @@ const getComponentCss$E = (aspectRatio, size, weight, align, compact, hasGradien
8169
8187
  gridColumn: 2,
8170
8188
  gridRow: `1/${hasFooterSlot ? 3 : 2}`,
8171
8189
  alignSelf: isTopAligned ? 'flex-start' : 'flex-end',
8172
- ...buildResponsiveStyles(compact, (compactValue) => ({
8190
+ ...buildResponsiveBooleanStyles(compact, (compactValue) => ({
8173
8191
  display: compactValue ? 'inline-block' : 'none',
8174
8192
  })),
8175
8193
  },
@@ -8177,7 +8195,7 @@ const getComponentCss$E = (aspectRatio, size, weight, align, compact, hasGradien
8177
8195
  minHeight: '54px', // prevent content shift
8178
8196
  zIndex: 5,
8179
8197
  marginTop: ref(spacingStaticMd),
8180
- ...buildResponsiveStyles(compact, (compactValue) => ({
8198
+ ...buildResponsiveBooleanStyles(compact, (compactValue) => ({
8181
8199
  display: compactValue ? 'none' : 'inline-block',
8182
8200
  })),
8183
8201
  },
@@ -8224,9 +8242,9 @@ const getComponentCss$D = (icon, iconSource, variant, hideLabel, hasSlottedAncho
8224
8242
  content: '""',
8225
8243
  position: 'fixed',
8226
8244
  inset: 0,
8227
- ...mergeDeep(buildResponsiveStyles(isCompact, (compactValue) => ({
8245
+ ...mergeDeep(buildResponsiveBooleanStyles(isCompact, (compactValue) => ({
8228
8246
  borderRadius: ref(cssVarRadius$1, compactValue ? ref(radiusLg) : ref(radiusXl)),
8229
- })), buildResponsiveStyles(hideLabel, (hideLabelValue) => ({
8247
+ })), buildResponsiveBooleanStyles(hideLabel, (hideLabelValue) => ({
8230
8248
  ...(hideLabelValue && {
8231
8249
  borderRadius: ref(cssVarRadius$1, ref(radiusFull)),
8232
8250
  }),
@@ -8291,7 +8309,7 @@ const getComponentCss$C = (isOpen, background, backdrop, fullscreen, hasDismissB
8291
8309
  ...dialogGridJssStyle(),
8292
8310
  ...getDialogColorJssStyle(),
8293
8311
  ...getDialogTransitionJssStyle(isOpen, '^'),
8294
- ...buildResponsiveStyles(fullscreen, (fullscreenValue) => fullscreenValue
8312
+ ...buildResponsiveBooleanStyles(fullscreen, (fullscreenValue) => fullscreenValue
8295
8313
  ? {
8296
8314
  width: 'auto',
8297
8315
  minWidth: 'auto',
@@ -9767,7 +9785,7 @@ const getComponentCss$j = (alignLabel, hideLabel, isStretched, isChecked, isDisa
9767
9785
  '@global': {
9768
9786
  ':host': {
9769
9787
  [`${cssVarInternalSwitchScaling}`]: isCompact ? 0.64285714 : 1,
9770
- ...buildResponsiveStyles(isStretched, (stretchValue) => ({
9788
+ ...buildResponsiveBooleanStyles(isStretched, (stretchValue) => ({
9771
9789
  display: stretchValue ? 'flex' : 'inline-flex',
9772
9790
  })),
9773
9791
  ...addImportantToEachRule({
@@ -9776,7 +9794,7 @@ const getComponentCss$j = (alignLabel, hideLabel, isStretched, isChecked, isDisa
9776
9794
  font: `${ref(typescaleSm$1)} ${ref(fontPorscheNext$1)}`, // needed for correct gap definition based on ex-unit
9777
9795
  gap,
9778
9796
  ...hostHiddenStyles,
9779
- ...buildResponsiveStyles(isStretched, (stretchValue) => ({
9797
+ ...buildResponsiveBooleanStyles(isStretched, (stretchValue) => ({
9780
9798
  justifyContent: stretchValue ? 'space-between' : 'flex-start',
9781
9799
  width: stretchValue ? '100%' : 'auto', // prevents adjusting its size when used as flex or grid child
9782
9800
  ...(!stretchValue && { verticalAlign: 'top' }),
@@ -9831,7 +9849,7 @@ const getComponentCss$j = (alignLabel, hideLabel, isStretched, isChecked, isDisa
9831
9849
  })),
9832
9850
  ...mergeDeep(buildResponsiveStyles(alignLabel, (alignLabelValue) => ({
9833
9851
  order: alignLabelValue === 'start' ? -1 : 0,
9834
- })), buildResponsiveStyles(hideLabel, (isHidden) => getHiddenTextJssStyle(isHidden, {
9852
+ })), buildResponsiveBooleanStyles(hideLabel, (isHidden) => getHiddenTextJssStyle(isHidden, {
9835
9853
  paddingTop: labelPaddingTop,
9836
9854
  }))),
9837
9855
  },
@@ -3295,37 +3295,37 @@ const getListboxAriaAttributes = (isRequired, labelId, messageId, descriptionId,
3295
3295
  /** Holds the **Porsche Next** font family along with fallback fonts. */
3296
3296
  const fontPorscheNext = "'Porsche Next','Arial Narrow',Arial,'Heiti SC',SimHei,sans-serif";
3297
3297
 
3298
- /** @deprecated since v4.0.0, will be removed with next major release. Use fontPorscheNext instead. */
3298
+ /** @deprecated Use {@link fontPorscheNext} instead. This API will be removed with the next major release. */
3299
3299
  const fontFamily = fontPorscheNext;
3300
3300
 
3301
3301
  /** Holds a dynamic default line height specifically optimized for the Porsche Next typeface. */
3302
3302
  const leadingNormal$1 = 'calc(6px + 2.125ex)';
3303
3303
 
3304
- /** @deprecated since v4.0.0, will be removed with next major release. Use leadingNormal instead */
3304
+ /** @deprecated Use {@link leadingNormal} instead. This API will be removed with the next major release. */
3305
3305
  const fontLineHeight = leadingNormal$1;
3306
3306
 
3307
3307
  /** Holds the **small** font size optimized for the Porsche Next typeface. */
3308
3308
  const typescaleSm = '1rem';
3309
3309
 
3310
- /** @deprecated since v4.0.0, will be removed with next major release. Use typescaleSm instead. */
3310
+ /** @deprecated Use {@link typescaleSm} instead. This API will be removed with the next major release. */
3311
3311
  const fontSizeTextSmall = typescaleSm;
3312
3312
 
3313
3313
  /** Holds the **x-small** font size optimized for the Porsche Next typeface. */
3314
3314
  const typescaleXs = '.875rem';
3315
3315
 
3316
- /** @deprecated since v4.0.0, will be removed with next major release. Use typescaleXs instead. */
3316
+ /** @deprecated Use {@link typescaleXs} instead. This API will be removed with the next major release. */
3317
3317
  const fontSizeTextXSmall = typescaleXs;
3318
3318
 
3319
- /** @deprecated since v4.0.0, will be removed with next major release. Use 'normal' instead. */
3319
+ /** @deprecated This API will be removed with the next major release. Use 'normal' instead. */
3320
3320
  const fontStyleNormal = 'normal';
3321
3321
 
3322
- /** @deprecated since v4.0.0, will be removed with next major release. Use 'normal' instead. */
3322
+ /** @deprecated This API will be removed with the next major release. Use 'normal' instead. */
3323
3323
  const fontVariant = 'normal';
3324
3324
 
3325
3325
  /** Holds the **normal** font weight optimized for the Porsche Next typeface. */
3326
3326
  const fontWeightNormal = 400;
3327
3327
 
3328
- /** @deprecated since v4.0.0, will be removed with next major release. Use fontWeightNormal instead. */
3328
+ /** @deprecated Use {@link fontWeightNormal} instead. This API will be removed with the next major release. */
3329
3329
  const fontWeightRegular = fontWeightNormal;
3330
3330
 
3331
3331
  const breakpointBase = 0;
@@ -3379,16 +3379,41 @@ const breakpoints = ['base', 'xs', 's', 'm', 'l', 'xl', 'xxl'];
3379
3379
  const _textFontPartA = `${fontStyleNormal} ${fontVariant} ${fontWeightRegular} `;
3380
3380
  const _textFontPartB = `/${fontLineHeight} ${fontFamily}`;
3381
3381
 
3382
- /** @deprecated since v4.0.0, will be removed with next major release. Use proseTextXs instead. */
3382
+ /** @deprecated Use {@link proseTextXsStyle} instead. This API will be removed with the next major release. */
3383
3383
  const textXSmallStyle = {
3384
3384
  font: `${_textFontPartA}${fontSizeTextXSmall}${_textFontPartB}`,
3385
3385
  };
3386
3386
 
3387
- /** @deprecated since v4.0.0, will be removed with next major release. Use proseTextSm instead. */
3387
+ /** @deprecated Use {@link proseTextSmStyle} instead. This API will be removed with the next major release. */
3388
3388
  const textSmallStyle = {
3389
3389
  font: `${_textFontPartA}${fontSizeTextSmall}${_textFontPartB}`,
3390
3390
  };
3391
3391
 
3392
+ const parse = (prop) => {
3393
+ if (typeof prop === 'string') {
3394
+ try {
3395
+ // prop is potentially JSON parsable string, e.g. "{ base: 'block', l: 'inline' }" or "true" or "false"
3396
+ return JSON.parse(prop
3397
+ .replace(/'/g, '"') // convert single quotes to double quotes
3398
+ .replace(/[\s"]?([a-z]+)[\s"]?:([^//])/g, '"$1":$2') // wrap keys in double quotes if they don't have them but ignore potential urls
3399
+ );
3400
+ }
3401
+ catch {
3402
+ // prop is string, e.g. "block" or "inline"
3403
+ return prop;
3404
+ }
3405
+ }
3406
+ else {
3407
+ // prop is object, e.g. { base: 'block', l: 'inline' } or number, e.g. 123 or boolean, e.g. true
3408
+ return prop;
3409
+ }
3410
+ };
3411
+ const parseJSONBoolean = (prop) =>
3412
+ // prop is an HTML boolean attribute used without a value, e.g. <p-input-text hide-label>
3413
+ // Stencil resolves BreakpointCustomizable<T> to "any" and therefore skips its own boolean coercion
3414
+ // TODO: [v5] obsolete once objects can only be set via property, since Stencil coerces booleans itself then, see #4708
3415
+ (prop === '' ? true : parse(prop));
3416
+
3392
3417
  // NOTE: handpicked selection of plugins from jss-preset-default
3393
3418
  createJss({
3394
3419
  plugins: [
@@ -3505,7 +3530,7 @@ const hasShowPickerSupport = () => (hasDocument &&
3505
3530
  'showPicker' in HTMLInputElement.prototype &&
3506
3531
  CSS.supports('selector(::-webkit-calendar-picker-indicator)'));
3507
3532
 
3508
- const prefix = `[Porsche Design System v${"4.7.0-beta.0"}]` // this part isn't covered by unit tests
3533
+ const prefix = `[Porsche Design System v${"4.7.0"}]` // this part isn't covered by unit tests
3509
3534
  ;
3510
3535
  const consoleError$1 = (...messages) => {
3511
3536
  console.error(prefix, ...messages);
@@ -4216,6 +4241,8 @@ const getInlineNotificationAriaAttributes = (state, heading) => {
4216
4241
  'aria-label': heading || null,
4217
4242
  };
4218
4243
  };
4244
+ // both tiles need the parsed value to decide whether only one or both link/button variants have to be rendered
4245
+ const getParsedTileCompact = (compact) => parseJSONBoolean(compact);
4219
4246
  const getSvgUrl = (model) => {
4220
4247
  return `${getCDNBaseURL()}/model-signatures/${MODEL_SIGNATURES_MANIFEST[model].src}`;
4221
4248
  };
@@ -4446,6 +4473,7 @@ exports.getHeadingTagType = getHeadingTagType;
4446
4473
  exports.getInlineNotificationAriaAttributes = getInlineNotificationAriaAttributes;
4447
4474
  exports.getListboxAriaAttributes = getListboxAriaAttributes;
4448
4475
  exports.getMaxTransitionDurationMs = getMaxTransitionDurationMs;
4476
+ exports.getParsedTileCompact = getParsedTileCompact;
4449
4477
  exports.getSanitizedActiveTabIndex = getSanitizedActiveTabIndex;
4450
4478
  exports.getSegmentedControlItemAriaAttributes = getSegmentedControlItemAriaAttributes;
4451
4479
  exports.getStepperHorizontalIconName = getStepperHorizontalIconName;
@@ -4479,6 +4507,7 @@ exports.onCancelDialog = onCancelDialog;
4479
4507
  exports.onClickDialog = onClickDialog;
4480
4508
  exports.parseAndGetAriaAttributes = parseAndGetAriaAttributes;
4481
4509
  exports.parseJSONAttribute = parseJSONAttribute;
4510
+ exports.parseJSONBoolean = parseJSONBoolean;
4482
4511
  exports.resolveAiTagTranslationLanguage = resolveAiTagTranslationLanguage;
4483
4512
  exports.setAriaIDREF = setAriaIDREF;
4484
4513
  exports.showDialog = showDialog;
@@ -19,8 +19,7 @@ class DSRButtonTile extends react.Component {
19
19
  hasFooterSlot = false;
20
20
  render() {
21
21
  splitChildren.splitChildren(this.props.children);
22
- // TODO: BreakpointCustomizable breaks stencils boolean conversion from string to boolean
23
- const parsedCompact = this.props.compact === 'true' ? true : this.props.compact === 'false' ? false : this.props.compact;
22
+ const parsedCompact = utilsEntry.getParsedTileCompact(this.props.compact);
24
23
  const buttonProps = {
25
24
  variant: 'secondary',
26
25
  iconSource: this.props.iconSource,
@@ -3,7 +3,7 @@
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var fcDismissButton = require('./fc-dismiss-button.cjs');
5
5
 
6
- const DialogBase = ({ children, inert, containerClass, ariaAttributes, onMouseDown, dismissable = false, header, footer, subFooter, }) => {
6
+ const DialogBase = ({ children, inert, containerClass, ariaAttributes, dismissable = false, header, footer, subFooter, }) => {
7
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] }) }) }));
8
8
  };
9
9
 
@@ -6,6 +6,7 @@ require('../../provider.cjs');
6
6
  var splitChildren = require('../../splitChildren.cjs');
7
7
  var minifyCss = require('../../minifyCss.cjs');
8
8
  var stylesEntry = require('../../../../../../components/dist/styles/esm/styles-entry.cjs');
9
+ var utilsEntry = require('../../../../../../components/dist/utils/esm/utils-entry.cjs');
9
10
  var link_wrapper = require('../components/link.wrapper.cjs');
10
11
 
11
12
  /**
@@ -18,8 +19,7 @@ class DSRLinkTile extends react.Component {
18
19
  hasFooterSlot = false;
19
20
  render() {
20
21
  splitChildren.splitChildren(this.props.children);
21
- // TODO: BreakpointCustomizable breaks stencils boolean conversion from string to boolean
22
- const parsedCompact = this.props.compact === 'true' ? true : this.props.compact === 'false' ? false : this.props.compact;
22
+ const parsedCompact = utilsEntry.getParsedTileCompact(this.props.compact);
23
23
  const linkProps = {
24
24
  variant: 'secondary',
25
25
  aria: this.props.aria,
@@ -15,7 +15,9 @@ var react = require('react');
15
15
  */
16
16
  const splitChildren = (children) => {
17
17
  children =
18
- typeof children === 'object' && 'type' in children && children.type === react.Fragment
18
+ // `children !== null` is required because `typeof null === 'object'`, which would
19
+ // make the `in` check throw for a single `null` child (e.g. `{cond ? <X/> : null}`).
20
+ typeof children === 'object' && children !== null && 'type' in children && children.type === react.Fragment
19
21
  ? children.props.children // Unpack children of React.Fragment
20
22
  : children;
21
23
  const childrenArray = (Array.isArray(children) ? children : children ? [children] : []).filter((x) => x !== undefined && x !== null // children are filtered due to cases where conditionally rendered children can be undefined.