@porsche-design-system/components-react 3.15.0-rc.4 → 3.15.0-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -14,6 +14,24 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0),
14
14
 
15
15
  ### [Unreleased]
16
16
 
17
+ ### [3.15.0-rc.5] - 2024-05-16
18
+
19
+ #### Added
20
+
21
+ - `Button Pure`: Prop `underline` to show an underline for the label
22
+ ([#3212](https://github.com/porsche-design-system/porsche-design-system/pull/3212))
23
+
24
+ #### Changed
25
+
26
+ - Banner: Refactor Banner to use native `popover`
27
+ ([#3196](https://github.com/porsche-design-system/porsche-design-system/pull/3196))
28
+
29
+ #### Fixed
30
+
31
+ - `aria` property now supports escaped single quotes inside JSON strings, e.g.
32
+ `aria="{ 'aria-label': 'You can\'t do that? yes you can!' }"`
33
+ ([#3217](https://github.com/porsche-design-system/porsche-design-system/pull/3217))
34
+
17
35
  ### [3.15.0-rc.4] - 2024-05-06
18
36
 
19
37
  #### Added
@@ -6,13 +6,13 @@ var react = require('react');
6
6
  var hooks = require('../../hooks.cjs');
7
7
  var utils = require('../../utils.cjs');
8
8
 
9
- const PButtonPure = react.forwardRef(({ active = false, alignLabel = 'end', aria, disabled = false, hideLabel = false, icon = 'arrow-right', iconSource, loading = false, name, size = 'small', stretch = false, theme, type = 'submit', value, weight = 'regular', className, ...rest }, ref) => {
9
+ const PButtonPure = react.forwardRef(({ active = false, alignLabel = 'end', aria, disabled = false, hideLabel = false, icon = 'arrow-right', iconSource, loading = false, name, size = 'small', stretch = false, theme, type = 'submit', underline = false, value, weight = 'regular', className, ...rest }, ref) => {
10
10
  const elementRef = react.useRef();
11
11
  const WebComponentTag = hooks.usePrefix('p-button-pure');
12
- const propsToSync = [active, alignLabel, aria, disabled, hideLabel, icon, iconSource, loading, name, size, stretch, theme || hooks.useTheme(), type, value, weight];
12
+ const propsToSync = [active, alignLabel, aria, disabled, hideLabel, icon, iconSource, loading, name, size, stretch, theme || hooks.useTheme(), type, underline, value, weight];
13
13
  hooks.useBrowserLayoutEffect(() => {
14
14
  const { current } = elementRef;
15
- ['active', 'alignLabel', 'aria', 'disabled', 'hideLabel', 'icon', 'iconSource', 'loading', 'name', 'size', 'stretch', 'theme', 'type', 'value', 'weight'].forEach((propName, i) => (current[propName] = propsToSync[i]));
15
+ ['active', 'alignLabel', 'aria', 'disabled', 'hideLabel', 'icon', 'iconSource', 'loading', 'name', 'size', 'stretch', 'theme', 'type', 'underline', 'value', 'weight'].forEach((propName, i) => (current[propName] = propsToSync[i]));
16
16
  }, propsToSync);
17
17
  const props = {
18
18
  ...rest,
@@ -53,6 +53,10 @@ export type PButtonPureProps = Omit<HTMLAttributes<{}>, 'color'> & {
53
53
  * Specifies the type of the button.
54
54
  */
55
55
  type?: ButtonPureType;
56
+ /**
57
+ * Shows an underline under the label.
58
+ */
59
+ underline?: boolean;
56
60
  /**
57
61
  * Defines the value associated with the button's name when it's submitted with the form data. This value is passed to the server in params when the form is submitted using this button.
58
62
  */
@@ -116,6 +120,10 @@ export declare const PButtonPure: import("react").ForwardRefExoticComponent<Omit
116
120
  * Specifies the type of the button.
117
121
  */
118
122
  type?: "button" | "reset" | "submit" | undefined;
123
+ /**
124
+ * Shows an underline under the label.
125
+ */
126
+ underline?: boolean | undefined;
119
127
  /**
120
128
  * Defines the value associated with the button's name when it's submitted with the form data. This value is passed to the server in params when the form is submitted using this button.
121
129
  */
@@ -4,13 +4,13 @@ import { forwardRef, useRef } from 'react';
4
4
  import { usePrefix, useTheme, useBrowserLayoutEffect, useMergedClass } from '../../hooks.mjs';
5
5
  import { syncRef } from '../../utils.mjs';
6
6
 
7
- const PButtonPure = forwardRef(({ active = false, alignLabel = 'end', aria, disabled = false, hideLabel = false, icon = 'arrow-right', iconSource, loading = false, name, size = 'small', stretch = false, theme, type = 'submit', value, weight = 'regular', className, ...rest }, ref) => {
7
+ const PButtonPure = forwardRef(({ active = false, alignLabel = 'end', aria, disabled = false, hideLabel = false, icon = 'arrow-right', iconSource, loading = false, name, size = 'small', stretch = false, theme, type = 'submit', underline = false, value, weight = 'regular', className, ...rest }, ref) => {
8
8
  const elementRef = useRef();
9
9
  const WebComponentTag = usePrefix('p-button-pure');
10
- const propsToSync = [active, alignLabel, aria, disabled, hideLabel, icon, iconSource, loading, name, size, stretch, theme || useTheme(), type, value, weight];
10
+ const propsToSync = [active, alignLabel, aria, disabled, hideLabel, icon, iconSource, loading, name, size, stretch, theme || useTheme(), type, underline, value, weight];
11
11
  useBrowserLayoutEffect(() => {
12
12
  const { current } = elementRef;
13
- ['active', 'alignLabel', 'aria', 'disabled', 'hideLabel', 'icon', 'iconSource', 'loading', 'name', 'size', 'stretch', 'theme', 'type', 'value', 'weight'].forEach((propName, i) => (current[propName] = propsToSync[i]));
13
+ ['active', 'alignLabel', 'aria', 'disabled', 'hideLabel', 'icon', 'iconSource', 'loading', 'name', 'size', 'stretch', 'theme', 'type', 'underline', 'value', 'weight'].forEach((propName, i) => (current[propName] = propsToSync[i]));
14
14
  }, propsToSync);
15
15
  const props = {
16
16
  ...rest,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@porsche-design-system/components-react",
3
- "version": "3.15.0-rc.4",
3
+ "version": "3.15.0-rc.5",
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",
@@ -17,7 +17,7 @@
17
17
  "license": "SEE LICENSE IN LICENSE",
18
18
  "homepage": "https://designsystem.porsche.com",
19
19
  "dependencies": {
20
- "@porsche-design-system/components-js": "3.15.0-rc.4"
20
+ "@porsche-design-system/components-js": "3.15.0-rc.5"
21
21
  },
22
22
  "peerDependencies": {
23
23
  "react": ">=18.0.0 <19.0.0",
@@ -4232,6 +4232,20 @@ const FLYOUT_Z_INDEX = 99998;
4232
4232
  const POPOVER_Z_INDEX = 9999;
4233
4233
  const BANNER_Z_INDEX = 99;
4234
4234
 
4235
+ const getBannerPopoverResetStyles = () => {
4236
+ return {
4237
+ position: 'fixed',
4238
+ margin: 0,
4239
+ padding: 0,
4240
+ width: 'auto', // ua popover reset
4241
+ height: 'auto', // ua popover reset
4242
+ maxWidth: '100%', // If component is wrapped in container with maxWidth
4243
+ border: '0', // ua popover reset
4244
+ outline: '0', // ua popover reset
4245
+ overflow: 'visible', // ua popover reset
4246
+ };
4247
+ };
4248
+
4235
4249
  const cssVariableTop = '--p-banner-position-top';
4236
4250
  const cssVariableBottom = '--p-banner-position-bottom';
4237
4251
  const cssVariableZIndex = '--p-internal-banner-z-index';
@@ -4239,48 +4253,53 @@ const topBottomFallback = '56px';
4239
4253
  const getComponentCss$14 = (isOpen) => {
4240
4254
  return getCss({
4241
4255
  '@global': {
4242
- ':host': addImportantToEachRule({
4243
- position: 'fixed',
4244
- bottom: `var(${cssVariableBottom},${topBottomFallback})`,
4245
- left: gridExtendedOffsetBase,
4246
- right: gridExtendedOffsetBase,
4247
- margin: 0,
4248
- padding: 0,
4249
- width: 'auto',
4250
- maxWidth: '100%', // If component is wrapped in container with maxWidth
4251
- zIndex: `var(${cssVariableZIndex},${BANNER_Z_INDEX})`,
4252
- ...dropShadowHighStyle,
4253
- borderRadius: borderRadiusSmall, // needed for rounded box-shadow
4254
- ...(isOpen
4255
- ? {
4256
- opacity: 1,
4257
- visibility: 'inherit',
4258
- transform: 'translate3d(0,0,0)',
4259
- transition: `transform var(${cssVariableAnimationDuration}, ${motionDurationModerate}) ${motionEasingIn}, opacity var(${cssVariableAnimationDuration}, ${motionDurationModerate}) ${motionEasingIn}`,
4260
- }
4261
- : {
4262
- opacity: 0,
4263
- visibility: 'hidden',
4264
- transform: `translate3d(0,calc(var(${cssVariableBottom},${topBottomFallback}) + 100%),0)`,
4265
- '&(.hydrated),&(.ssr)': {
4266
- transition: `visibility 0s linear var(${cssVariableAnimationDuration}, ${motionDurationLong}), transform var(${cssVariableAnimationDuration}, ${motionDurationModerate}) ${motionEasingOut}, opacity var(${cssVariableAnimationDuration}, ${motionDurationModerate}) ${motionEasingOut}`,
4267
- },
4268
- }),
4269
- [getMediaQueryMin('s')]: {
4270
- top: `var(${cssVariableTop},${topBottomFallback})`,
4271
- bottom: 'auto',
4272
- left: gridExtendedOffsetS,
4273
- right: gridExtendedOffsetS,
4274
- // space before and after "-" is crucial)
4275
- ...(!isOpen && { transform: `translate3d(0,calc(-100% - var(${cssVariableTop},${topBottomFallback})),0)` }),
4276
- },
4277
- [getMediaQueryMin('xxl')]: {
4278
- left: gridExtendedOffsetXXL,
4279
- right: gridExtendedOffsetXXL,
4280
- },
4281
- ...colorSchemeStyles,
4282
- ...hostHiddenStyles,
4283
- }),
4256
+ ':host': {
4257
+ display: 'block',
4258
+ ...addImportantToEachRule({
4259
+ ...getBannerPopoverResetStyles(),
4260
+ bottom: `var(${cssVariableBottom},${topBottomFallback})`,
4261
+ left: gridExtendedOffsetBase,
4262
+ right: gridExtendedOffsetBase,
4263
+ zIndex: `var(${cssVariableZIndex},${BANNER_Z_INDEX})`,
4264
+ ...dropShadowHighStyle,
4265
+ borderRadius: borderRadiusSmall, // needed for rounded box-shadow
4266
+ ...(isOpen
4267
+ ? {
4268
+ opacity: 1,
4269
+ visibility: 'inherit',
4270
+ pointerEvents: 'inherit',
4271
+ transform: 'translate3d(0,0,0)',
4272
+ transition: `${getTransition('transform', 'moderate', 'in')}, ${getTransition('opacity', 'moderate', 'in')}`,
4273
+ }
4274
+ : {
4275
+ opacity: 0,
4276
+ visibility: 'hidden',
4277
+ pointerEvents: 'none',
4278
+ transform: `translate3d(0,calc(var(${cssVariableBottom},${topBottomFallback}) + 100%),0)`,
4279
+ '&(.hydrated),&(.ssr)': {
4280
+ transition: `visibility 0s linear var(${cssVariableTransitionDuration}, ${motionDurationLong}), ${getTransition('transform', 'moderate', 'out')}, ${getTransition('opacity', 'moderate', 'out')}`,
4281
+ // during transition the element will be removed from top-layer immediately, resulting in other elements laying over (as of Mai 2024 only Chrome is fixed by this)
4282
+ '@supports (transition-behavior: allow-discrete)': {
4283
+ transition: `visibility 0s linear var(${cssVariableTransitionDuration}, ${motionDurationLong}), ${getTransition('transform', 'moderate', 'out')}, ${getTransition('opacity', 'moderate', 'out')}, overlay var(${cssVariableTransitionDuration}, ${motionDurationModerate}) ${motionEasingOut} allow-discrete`,
4284
+ },
4285
+ },
4286
+ }),
4287
+ [getMediaQueryMin('s')]: {
4288
+ top: `var(${cssVariableTop},${topBottomFallback})`,
4289
+ bottom: 'auto',
4290
+ left: gridExtendedOffsetS,
4291
+ right: gridExtendedOffsetS,
4292
+ // space before and after "-" is crucial)
4293
+ ...(!isOpen && { transform: `translate3d(0,calc(-100% - var(${cssVariableTop},${topBottomFallback})),0)` }),
4294
+ },
4295
+ [getMediaQueryMin('xxl')]: {
4296
+ left: gridExtendedOffsetXXL,
4297
+ right: gridExtendedOffsetXXL,
4298
+ },
4299
+ ...colorSchemeStyles,
4300
+ ...hostHiddenStyles,
4301
+ }),
4302
+ },
4284
4303
  },
4285
4304
  });
4286
4305
  };
@@ -4348,7 +4367,7 @@ const getVisibilityJssStyle = (hideLabel) => {
4348
4367
  };
4349
4368
  const offsetVertical = '-2px';
4350
4369
  const offsetHorizontal = '-4px';
4351
- const getLinkButtonPureStyles = (icon, iconSource, active, isDisabledOrLoading, stretch, size, hideLabel, alignLabel, hasSlottedAnchor, theme) => {
4370
+ const getLinkButtonPureStyles = (icon, iconSource, active, isDisabledOrLoading, stretch, size, hideLabel, alignLabel, underline, hasSlottedAnchor, theme) => {
4352
4371
  const { primaryColor, disabledColor, hoverColor } = getThemedColors(theme);
4353
4372
  const { primaryColor: primaryColorDark, disabledColor: disabledColorDark, hoverColor: hoverColorDark, } = getThemedColors('dark');
4354
4373
  const hasIcon = hasVisibleIcon(icon, iconSource);
@@ -4374,6 +4393,7 @@ const getLinkButtonPureStyles = (icon, iconSource, active, isDisabledOrLoading,
4374
4393
  padding: 0,
4375
4394
  margin: 0, // Removes default button margin on safari 15
4376
4395
  color: isDisabledOrLoading ? disabledColor : primaryColor,
4396
+ textDecoration: underline ? 'underline' : 'none',
4377
4397
  ...prefersColorSchemeDarkMediaQuery(theme, {
4378
4398
  color: isDisabledOrLoading ? disabledColorDark : primaryColorDark,
4379
4399
  }),
@@ -4450,9 +4470,9 @@ const getFunctionalComponentLoadingMessageStyles = () => {
4450
4470
  };
4451
4471
  };
4452
4472
 
4453
- const getComponentCss$12 = (icon, iconSource, active, isLoading, isDisabledOrLoading, stretch, size, hideLabel, alignLabel, theme) => {
4473
+ const getComponentCss$12 = (icon, iconSource, active, isLoading, isDisabledOrLoading, stretch, size, hideLabel, alignLabel, underline, theme) => {
4454
4474
  const hasIcon = hasVisibleIcon(icon, iconSource);
4455
- return getCss(mergeDeep(getLinkButtonPureStyles(icon, iconSource, active, isDisabledOrLoading, stretch, size, hideLabel, alignLabel, false, theme), {
4475
+ return getCss(mergeDeep(getLinkButtonPureStyles(icon, iconSource, active, isDisabledOrLoading, stretch, size, hideLabel, alignLabel, underline, false, theme), {
4456
4476
  root: {
4457
4477
  WebkitAppearance: 'none', // iOS safari
4458
4478
  appearance: 'none',
@@ -6501,11 +6521,7 @@ const getComponentCss$J = (state, hasAction, hasClose, theme) => {
6501
6521
  };
6502
6522
 
6503
6523
  const getComponentCss$I = (icon, iconSource, active, stretch, size, hideLabel, alignLabel, underline, hasSlottedAnchor, theme) => {
6504
- return getCss(mergeDeep(getLinkButtonPureStyles(icon, iconSource, active, false, stretch, size, hideLabel, alignLabel, hasSlottedAnchor, theme), {
6505
- root: {
6506
- textDecoration: underline ? 'underline' : 'none',
6507
- },
6508
- }, hasSlottedAnchor && {
6524
+ return getCss(mergeDeep(getLinkButtonPureStyles(icon, iconSource, active, false, stretch, size, hideLabel, alignLabel, underline, hasSlottedAnchor, theme), hasSlottedAnchor && {
6509
6525
  '@global': addImportantToEachRule({
6510
6526
  '::slotted': {
6511
6527
  '&(a)': {
@@ -3193,12 +3193,13 @@ const isDisabledOrLoading = (disabled, loading) => {
3193
3193
 
3194
3194
  const parseJSONAttribute = (attribute) => {
3195
3195
  return typeof attribute === 'string'
3196
- ? // input is potentially JSON parsable string, e.g. "{ aria-label: 'Some label' }"
3196
+ ? // input is potentially JSON parsable string, e.g. "{ 'aria-label': 'Some label' }"
3197
3197
  JSON.parse(attribute
3198
- .replace(/'/g, '"') // convert single quotes to double quotes
3198
+ .replace(/(?<!\\)'/g, '"') // convert single quotes to double quotes except the ones which are escaped by backslash
3199
+ .replace(/\\(?!u0027)/g, '') // remove string escapes except the ones followed by unicode u0027
3199
3200
  .replace(/[\s"]?([\w-]+)[\s"]?:/g, '"$1":') // wrap keys in double quotes
3200
3201
  )
3201
- : // input is object, e.g. { aria-label: 'Some label' }
3202
+ : // input is object, e.g. { 'aria-label': 'Some label' }
3202
3203
  attribute;
3203
3204
  };
3204
3205
 
@@ -25,6 +25,7 @@ const PBanner = react.forwardRef(({ description = '', dismissButton = true, head
25
25
  // @ts-ignore
26
26
  ...(!process.browser
27
27
  ? {
28
+ ...{ "popover": "manual" },
28
29
  children: (jsxRuntime.jsx(banner.DSRBanner, { description, dismissButton, heading, headingTag, open, persistent, state, theme: theme || hooks.useTheme(), width, children })),
29
30
  }
30
31
  : {
@@ -7,13 +7,13 @@ var hooks = require('../../hooks.cjs');
7
7
  var utils = require('../../utils.cjs');
8
8
  var buttonPure = require('../dsr-components/button-pure.cjs');
9
9
 
10
- const PButtonPure = react.forwardRef(({ active = false, alignLabel = 'end', aria, disabled = false, hideLabel = false, icon = 'arrow-right', iconSource, loading = false, name, size = 'small', stretch = false, theme, type = 'submit', value, weight = 'regular', className, children, ...rest }, ref) => {
10
+ const PButtonPure = react.forwardRef(({ active = false, alignLabel = 'end', aria, disabled = false, hideLabel = false, icon = 'arrow-right', iconSource, loading = false, name, size = 'small', stretch = false, theme, type = 'submit', underline = false, value, weight = 'regular', className, children, ...rest }, ref) => {
11
11
  const elementRef = react.useRef();
12
12
  const WebComponentTag = hooks.usePrefix('p-button-pure');
13
- const propsToSync = [active, alignLabel, aria, disabled, hideLabel, icon, iconSource, loading, name, size, stretch, theme || hooks.useTheme(), type, value, weight];
13
+ const propsToSync = [active, alignLabel, aria, disabled, hideLabel, icon, iconSource, loading, name, size, stretch, theme || hooks.useTheme(), type, underline, value, weight];
14
14
  hooks.useBrowserLayoutEffect(() => {
15
15
  const { current } = elementRef;
16
- ['active', 'alignLabel', 'aria', 'disabled', 'hideLabel', 'icon', 'iconSource', 'loading', 'name', 'size', 'stretch', 'theme', 'type', 'value', 'weight'].forEach((propName, i) => (current[propName] = propsToSync[i]));
16
+ ['active', 'alignLabel', 'aria', 'disabled', 'hideLabel', 'icon', 'iconSource', 'loading', 'name', 'size', 'stretch', 'theme', 'type', 'underline', 'value', 'weight'].forEach((propName, i) => (current[propName] = propsToSync[i]));
17
17
  }, propsToSync);
18
18
  // @ts-ignore
19
19
  if (!process.browser) {
@@ -24,7 +24,7 @@ const PButtonPure = react.forwardRef(({ active = false, alignLabel = 'end', aria
24
24
  // @ts-ignore
25
25
  ...(!process.browser
26
26
  ? {
27
- children: (jsxRuntime.jsx(buttonPure.DSRButtonPure, { active, alignLabel, aria, disabled, hideLabel, icon, iconSource, loading, name, size, stretch, theme: theme || hooks.useTheme(), type, value, weight, children })),
27
+ children: (jsxRuntime.jsx(buttonPure.DSRButtonPure, { active, alignLabel, aria, disabled, hideLabel, icon, iconSource, loading, name, size, stretch, theme: theme || hooks.useTheme(), type, underline, value, weight, children })),
28
28
  }
29
29
  : {
30
30
  children,
@@ -87,7 +87,7 @@ class DSRBanner extends react.Component {
87
87
  const { children, namedSlotChildren, otherChildren } = splitChildren.splitChildren(this.props.children);
88
88
  const hasTitleSlot = namedSlotChildren.filter(({ props: { slot } }) => slot === 'title').length > 0;
89
89
  const style = minifyCss.minifyCss(stripFocusAndHoverStyles.stripFocusAndHoverStyles(stylesEntry.getBannerCss(this.props.open)));
90
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("template", { shadowroot: "open", shadowrootmode: "open", children: [jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: style } }), jsxRuntime.jsxs(inlineNotification_wrapper.PInlineNotification, { heading: this.props.heading, headingTag: this.props.headingTag, description: this.props.description, state: this.props.state, dismissButton: this.hasDismissButton, theme: this.props.theme, "aria-hidden": !this.props.open ? 'true' : 'false', children: [namedSlotChildren.filter(({ props: { slot } }) => slot === 'heading').length > 0 ? (jsxRuntime.jsx("slot", { name: "heading", slot: "heading" })) : (hasTitleSlot && jsxRuntime.jsx("slot", { name: "title", slot: "heading" })), namedSlotChildren.filter(({ props: { slot } }) => slot === 'description').length > 0 && jsxRuntime.jsx("slot", { name: "description" })] })] }), this.props.children] }));
90
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("template", { shadowroot: "open", shadowrootmode: "open", children: [jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: style } }), jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs(inlineNotification_wrapper.PInlineNotification, { heading: this.props.heading, headingTag: this.props.headingTag, description: this.props.description, state: this.props.state, dismissButton: this.hasDismissButton, theme: this.props.theme, "aria-hidden": !this.props.open ? 'true' : 'false', children: [namedSlotChildren.filter(({ props: { slot } }) => slot === 'heading').length > 0 ? (jsxRuntime.jsx("slot", { name: "heading", slot: "heading" })) : (hasTitleSlot && jsxRuntime.jsx("slot", { name: "title", slot: "heading" })), namedSlotChildren.filter(({ props: { slot } }) => slot === 'description').length > 0 && jsxRuntime.jsx("slot", { name: "description" })] }) })] }), this.props.children] }));
91
91
  }
92
92
  }
93
93
 
@@ -92,7 +92,7 @@ class DSRButtonPure extends react.Component {
92
92
  size: 'inherit',
93
93
  theme: this.props.theme,
94
94
  };
95
- const style = minifyCss.minifyCss(stripFocusAndHoverStyles.stripFocusAndHoverStyles(stylesEntry.getButtonPureCss(this.props.icon, this.props.iconSource, this.props.active, this.props.loading, this.isDisabledOrLoading, this.props.stretch, this.props.size, this.props.hideLabel, this.props.alignLabel, this.props.theme)));
95
+ const style = minifyCss.minifyCss(stripFocusAndHoverStyles.stripFocusAndHoverStyles(stylesEntry.getButtonPureCss(this.props.icon, this.props.iconSource, this.props.active, this.props.loading, this.isDisabledOrLoading, this.props.stretch, this.props.size, this.props.hideLabel, this.props.alignLabel, this.props.underline, this.props.theme)));
96
96
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("template", { shadowroot: "open", shadowrootmode: "open", shadowrootdelegatesfocus: "true", children: [jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: style } }), jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("button", { ...utilsEntry.getButtonPureAriaAttributes(this.props.disabled, this.props.loading, this.props.aria), className: "root", type: this.props.type, name: this.props.name, value: this.props.value, "aria-describedby": this.props.loading ? loadingMessage.loadingId : undefined, children: [this.props.loading ? (jsxRuntime.jsx(spinner_wrapper.PSpinner, { ...iconProps, "aria-hidden": "true" })) : (hasIcon && (jsxRuntime.jsx(icon_wrapper.PIcon, { ...iconProps, name: this.props.icon, source: this.props.iconSource, color: this.isDisabledOrLoading ? 'state-disabled' : 'primary', theme: this.props.theme, "aria-hidden": "true" }))), jsxRuntime.jsx("span", { className: "label", children: jsxRuntime.jsx("slot", {}) })] }), jsxRuntime.jsx(loadingMessage.LoadingMessage, { loading: this.props.loading, initialLoading: false })] })] }), this.props.children] }));
97
97
  }
98
98
  }
@@ -4230,6 +4230,20 @@ const FLYOUT_Z_INDEX = 99998;
4230
4230
  const POPOVER_Z_INDEX = 9999;
4231
4231
  const BANNER_Z_INDEX = 99;
4232
4232
 
4233
+ const getBannerPopoverResetStyles = () => {
4234
+ return {
4235
+ position: 'fixed',
4236
+ margin: 0,
4237
+ padding: 0,
4238
+ width: 'auto', // ua popover reset
4239
+ height: 'auto', // ua popover reset
4240
+ maxWidth: '100%', // If component is wrapped in container with maxWidth
4241
+ border: '0', // ua popover reset
4242
+ outline: '0', // ua popover reset
4243
+ overflow: 'visible', // ua popover reset
4244
+ };
4245
+ };
4246
+
4233
4247
  const cssVariableTop = '--p-banner-position-top';
4234
4248
  const cssVariableBottom = '--p-banner-position-bottom';
4235
4249
  const cssVariableZIndex = '--p-internal-banner-z-index';
@@ -4237,48 +4251,53 @@ const topBottomFallback = '56px';
4237
4251
  const getComponentCss$14 = (isOpen) => {
4238
4252
  return getCss({
4239
4253
  '@global': {
4240
- ':host': addImportantToEachRule({
4241
- position: 'fixed',
4242
- bottom: `var(${cssVariableBottom},${topBottomFallback})`,
4243
- left: gridExtendedOffsetBase,
4244
- right: gridExtendedOffsetBase,
4245
- margin: 0,
4246
- padding: 0,
4247
- width: 'auto',
4248
- maxWidth: '100%', // If component is wrapped in container with maxWidth
4249
- zIndex: `var(${cssVariableZIndex},${BANNER_Z_INDEX})`,
4250
- ...dropShadowHighStyle,
4251
- borderRadius: borderRadiusSmall, // needed for rounded box-shadow
4252
- ...(isOpen
4253
- ? {
4254
- opacity: 1,
4255
- visibility: 'inherit',
4256
- transform: 'translate3d(0,0,0)',
4257
- transition: `transform var(${cssVariableAnimationDuration}, ${motionDurationModerate}) ${motionEasingIn}, opacity var(${cssVariableAnimationDuration}, ${motionDurationModerate}) ${motionEasingIn}`,
4258
- }
4259
- : {
4260
- opacity: 0,
4261
- visibility: 'hidden',
4262
- transform: `translate3d(0,calc(var(${cssVariableBottom},${topBottomFallback}) + 100%),0)`,
4263
- '&(.hydrated),&(.ssr)': {
4264
- transition: `visibility 0s linear var(${cssVariableAnimationDuration}, ${motionDurationLong}), transform var(${cssVariableAnimationDuration}, ${motionDurationModerate}) ${motionEasingOut}, opacity var(${cssVariableAnimationDuration}, ${motionDurationModerate}) ${motionEasingOut}`,
4265
- },
4266
- }),
4267
- [getMediaQueryMin('s')]: {
4268
- top: `var(${cssVariableTop},${topBottomFallback})`,
4269
- bottom: 'auto',
4270
- left: gridExtendedOffsetS,
4271
- right: gridExtendedOffsetS,
4272
- // space before and after "-" is crucial)
4273
- ...(!isOpen && { transform: `translate3d(0,calc(-100% - var(${cssVariableTop},${topBottomFallback})),0)` }),
4274
- },
4275
- [getMediaQueryMin('xxl')]: {
4276
- left: gridExtendedOffsetXXL,
4277
- right: gridExtendedOffsetXXL,
4278
- },
4279
- ...colorSchemeStyles,
4280
- ...hostHiddenStyles,
4281
- }),
4254
+ ':host': {
4255
+ display: 'block',
4256
+ ...addImportantToEachRule({
4257
+ ...getBannerPopoverResetStyles(),
4258
+ bottom: `var(${cssVariableBottom},${topBottomFallback})`,
4259
+ left: gridExtendedOffsetBase,
4260
+ right: gridExtendedOffsetBase,
4261
+ zIndex: `var(${cssVariableZIndex},${BANNER_Z_INDEX})`,
4262
+ ...dropShadowHighStyle,
4263
+ borderRadius: borderRadiusSmall, // needed for rounded box-shadow
4264
+ ...(isOpen
4265
+ ? {
4266
+ opacity: 1,
4267
+ visibility: 'inherit',
4268
+ pointerEvents: 'inherit',
4269
+ transform: 'translate3d(0,0,0)',
4270
+ transition: `${getTransition('transform', 'moderate', 'in')}, ${getTransition('opacity', 'moderate', 'in')}`,
4271
+ }
4272
+ : {
4273
+ opacity: 0,
4274
+ visibility: 'hidden',
4275
+ pointerEvents: 'none',
4276
+ transform: `translate3d(0,calc(var(${cssVariableBottom},${topBottomFallback}) + 100%),0)`,
4277
+ '&(.hydrated),&(.ssr)': {
4278
+ transition: `visibility 0s linear var(${cssVariableTransitionDuration}, ${motionDurationLong}), ${getTransition('transform', 'moderate', 'out')}, ${getTransition('opacity', 'moderate', 'out')}`,
4279
+ // during transition the element will be removed from top-layer immediately, resulting in other elements laying over (as of Mai 2024 only Chrome is fixed by this)
4280
+ '@supports (transition-behavior: allow-discrete)': {
4281
+ transition: `visibility 0s linear var(${cssVariableTransitionDuration}, ${motionDurationLong}), ${getTransition('transform', 'moderate', 'out')}, ${getTransition('opacity', 'moderate', 'out')}, overlay var(${cssVariableTransitionDuration}, ${motionDurationModerate}) ${motionEasingOut} allow-discrete`,
4282
+ },
4283
+ },
4284
+ }),
4285
+ [getMediaQueryMin('s')]: {
4286
+ top: `var(${cssVariableTop},${topBottomFallback})`,
4287
+ bottom: 'auto',
4288
+ left: gridExtendedOffsetS,
4289
+ right: gridExtendedOffsetS,
4290
+ // space before and after "-" is crucial)
4291
+ ...(!isOpen && { transform: `translate3d(0,calc(-100% - var(${cssVariableTop},${topBottomFallback})),0)` }),
4292
+ },
4293
+ [getMediaQueryMin('xxl')]: {
4294
+ left: gridExtendedOffsetXXL,
4295
+ right: gridExtendedOffsetXXL,
4296
+ },
4297
+ ...colorSchemeStyles,
4298
+ ...hostHiddenStyles,
4299
+ }),
4300
+ },
4282
4301
  },
4283
4302
  });
4284
4303
  };
@@ -4346,7 +4365,7 @@ const getVisibilityJssStyle = (hideLabel) => {
4346
4365
  };
4347
4366
  const offsetVertical = '-2px';
4348
4367
  const offsetHorizontal = '-4px';
4349
- const getLinkButtonPureStyles = (icon, iconSource, active, isDisabledOrLoading, stretch, size, hideLabel, alignLabel, hasSlottedAnchor, theme) => {
4368
+ const getLinkButtonPureStyles = (icon, iconSource, active, isDisabledOrLoading, stretch, size, hideLabel, alignLabel, underline, hasSlottedAnchor, theme) => {
4350
4369
  const { primaryColor, disabledColor, hoverColor } = getThemedColors(theme);
4351
4370
  const { primaryColor: primaryColorDark, disabledColor: disabledColorDark, hoverColor: hoverColorDark, } = getThemedColors('dark');
4352
4371
  const hasIcon = hasVisibleIcon(icon, iconSource);
@@ -4372,6 +4391,7 @@ const getLinkButtonPureStyles = (icon, iconSource, active, isDisabledOrLoading,
4372
4391
  padding: 0,
4373
4392
  margin: 0, // Removes default button margin on safari 15
4374
4393
  color: isDisabledOrLoading ? disabledColor : primaryColor,
4394
+ textDecoration: underline ? 'underline' : 'none',
4375
4395
  ...prefersColorSchemeDarkMediaQuery(theme, {
4376
4396
  color: isDisabledOrLoading ? disabledColorDark : primaryColorDark,
4377
4397
  }),
@@ -4448,9 +4468,9 @@ const getFunctionalComponentLoadingMessageStyles = () => {
4448
4468
  };
4449
4469
  };
4450
4470
 
4451
- const getComponentCss$12 = (icon, iconSource, active, isLoading, isDisabledOrLoading, stretch, size, hideLabel, alignLabel, theme) => {
4471
+ const getComponentCss$12 = (icon, iconSource, active, isLoading, isDisabledOrLoading, stretch, size, hideLabel, alignLabel, underline, theme) => {
4452
4472
  const hasIcon = hasVisibleIcon(icon, iconSource);
4453
- return getCss(mergeDeep(getLinkButtonPureStyles(icon, iconSource, active, isDisabledOrLoading, stretch, size, hideLabel, alignLabel, false, theme), {
4473
+ return getCss(mergeDeep(getLinkButtonPureStyles(icon, iconSource, active, isDisabledOrLoading, stretch, size, hideLabel, alignLabel, underline, false, theme), {
4454
4474
  root: {
4455
4475
  WebkitAppearance: 'none', // iOS safari
4456
4476
  appearance: 'none',
@@ -6499,11 +6519,7 @@ const getComponentCss$J = (state, hasAction, hasClose, theme) => {
6499
6519
  };
6500
6520
 
6501
6521
  const getComponentCss$I = (icon, iconSource, active, stretch, size, hideLabel, alignLabel, underline, hasSlottedAnchor, theme) => {
6502
- return getCss(mergeDeep(getLinkButtonPureStyles(icon, iconSource, active, false, stretch, size, hideLabel, alignLabel, hasSlottedAnchor, theme), {
6503
- root: {
6504
- textDecoration: underline ? 'underline' : 'none',
6505
- },
6506
- }, hasSlottedAnchor && {
6522
+ return getCss(mergeDeep(getLinkButtonPureStyles(icon, iconSource, active, false, stretch, size, hideLabel, alignLabel, underline, hasSlottedAnchor, theme), hasSlottedAnchor && {
6507
6523
  '@global': addImportantToEachRule({
6508
6524
  '::slotted': {
6509
6525
  '&(a)': {
@@ -3191,12 +3191,13 @@ const isDisabledOrLoading = (disabled, loading) => {
3191
3191
 
3192
3192
  const parseJSONAttribute = (attribute) => {
3193
3193
  return typeof attribute === 'string'
3194
- ? // input is potentially JSON parsable string, e.g. "{ aria-label: 'Some label' }"
3194
+ ? // input is potentially JSON parsable string, e.g. "{ 'aria-label': 'Some label' }"
3195
3195
  JSON.parse(attribute
3196
- .replace(/'/g, '"') // convert single quotes to double quotes
3196
+ .replace(/(?<!\\)'/g, '"') // convert single quotes to double quotes except the ones which are escaped by backslash
3197
+ .replace(/\\(?!u0027)/g, '') // remove string escapes except the ones followed by unicode u0027
3197
3198
  .replace(/[\s"]?([\w-]+)[\s"]?:/g, '"$1":') // wrap keys in double quotes
3198
3199
  )
3199
- : // input is object, e.g. { aria-label: 'Some label' }
3200
+ : // input is object, e.g. { 'aria-label': 'Some label' }
3200
3201
  attribute;
3201
3202
  };
3202
3203
 
@@ -23,6 +23,7 @@ const PBanner = forwardRef(({ description = '', dismissButton = true, heading =
23
23
  // @ts-ignore
24
24
  ...(!process.browser
25
25
  ? {
26
+ ...{ "popover": "manual" },
26
27
  children: (jsx(DSRBanner, { description, dismissButton, heading, headingTag, open, persistent, state, theme: theme || useTheme(), width, children })),
27
28
  }
28
29
  : {
@@ -5,13 +5,13 @@ import { usePrefix, useTheme, useBrowserLayoutEffect, useMergedClass } from '../
5
5
  import { syncRef } from '../../utils.mjs';
6
6
  import { DSRButtonPure } from '../dsr-components/button-pure.mjs';
7
7
 
8
- const PButtonPure = forwardRef(({ active = false, alignLabel = 'end', aria, disabled = false, hideLabel = false, icon = 'arrow-right', iconSource, loading = false, name, size = 'small', stretch = false, theme, type = 'submit', value, weight = 'regular', className, children, ...rest }, ref) => {
8
+ const PButtonPure = forwardRef(({ active = false, alignLabel = 'end', aria, disabled = false, hideLabel = false, icon = 'arrow-right', iconSource, loading = false, name, size = 'small', stretch = false, theme, type = 'submit', underline = false, value, weight = 'regular', className, children, ...rest }, ref) => {
9
9
  const elementRef = useRef();
10
10
  const WebComponentTag = usePrefix('p-button-pure');
11
- const propsToSync = [active, alignLabel, aria, disabled, hideLabel, icon, iconSource, loading, name, size, stretch, theme || useTheme(), type, value, weight];
11
+ const propsToSync = [active, alignLabel, aria, disabled, hideLabel, icon, iconSource, loading, name, size, stretch, theme || useTheme(), type, underline, value, weight];
12
12
  useBrowserLayoutEffect(() => {
13
13
  const { current } = elementRef;
14
- ['active', 'alignLabel', 'aria', 'disabled', 'hideLabel', 'icon', 'iconSource', 'loading', 'name', 'size', 'stretch', 'theme', 'type', 'value', 'weight'].forEach((propName, i) => (current[propName] = propsToSync[i]));
14
+ ['active', 'alignLabel', 'aria', 'disabled', 'hideLabel', 'icon', 'iconSource', 'loading', 'name', 'size', 'stretch', 'theme', 'type', 'underline', 'value', 'weight'].forEach((propName, i) => (current[propName] = propsToSync[i]));
15
15
  }, propsToSync);
16
16
  // @ts-ignore
17
17
  if (!process.browser) {
@@ -22,7 +22,7 @@ const PButtonPure = forwardRef(({ active = false, alignLabel = 'end', aria, disa
22
22
  // @ts-ignore
23
23
  ...(!process.browser
24
24
  ? {
25
- children: (jsx(DSRButtonPure, { active, alignLabel, aria, disabled, hideLabel, icon, iconSource, loading, name, size, stretch, theme: theme || useTheme(), type, value, weight, children })),
25
+ children: (jsx(DSRButtonPure, { active, alignLabel, aria, disabled, hideLabel, icon, iconSource, loading, name, size, stretch, theme: theme || useTheme(), type, underline, value, weight, children })),
26
26
  }
27
27
  : {
28
28
  children,
@@ -85,7 +85,7 @@ class DSRBanner extends Component {
85
85
  const { children, namedSlotChildren, otherChildren } = splitChildren(this.props.children);
86
86
  const hasTitleSlot = namedSlotChildren.filter(({ props: { slot } }) => slot === 'title').length > 0;
87
87
  const style = minifyCss(stripFocusAndHoverStyles(getComponentCss$14(this.props.open)));
88
- return (jsxs(Fragment, { children: [jsxs("template", { shadowroot: "open", shadowrootmode: "open", children: [jsx("style", { dangerouslySetInnerHTML: { __html: style } }), jsxs(PInlineNotification, { heading: this.props.heading, headingTag: this.props.headingTag, description: this.props.description, state: this.props.state, dismissButton: this.hasDismissButton, theme: this.props.theme, "aria-hidden": !this.props.open ? 'true' : 'false', children: [namedSlotChildren.filter(({ props: { slot } }) => slot === 'heading').length > 0 ? (jsx("slot", { name: "heading", slot: "heading" })) : (hasTitleSlot && jsx("slot", { name: "title", slot: "heading" })), namedSlotChildren.filter(({ props: { slot } }) => slot === 'description').length > 0 && jsx("slot", { name: "description" })] })] }), this.props.children] }));
88
+ return (jsxs(Fragment, { children: [jsxs("template", { shadowroot: "open", shadowrootmode: "open", children: [jsx("style", { dangerouslySetInnerHTML: { __html: style } }), jsx(Fragment, { children: jsxs(PInlineNotification, { heading: this.props.heading, headingTag: this.props.headingTag, description: this.props.description, state: this.props.state, dismissButton: this.hasDismissButton, theme: this.props.theme, "aria-hidden": !this.props.open ? 'true' : 'false', children: [namedSlotChildren.filter(({ props: { slot } }) => slot === 'heading').length > 0 ? (jsx("slot", { name: "heading", slot: "heading" })) : (hasTitleSlot && jsx("slot", { name: "title", slot: "heading" })), namedSlotChildren.filter(({ props: { slot } }) => slot === 'description').length > 0 && jsx("slot", { name: "description" })] }) })] }), this.props.children] }));
89
89
  }
90
90
  }
91
91
 
@@ -90,7 +90,7 @@ class DSRButtonPure extends Component {
90
90
  size: 'inherit',
91
91
  theme: this.props.theme,
92
92
  };
93
- const style = minifyCss(stripFocusAndHoverStyles(getComponentCss$12(this.props.icon, this.props.iconSource, this.props.active, this.props.loading, this.isDisabledOrLoading, this.props.stretch, this.props.size, this.props.hideLabel, this.props.alignLabel, this.props.theme)));
93
+ const style = minifyCss(stripFocusAndHoverStyles(getComponentCss$12(this.props.icon, this.props.iconSource, this.props.active, this.props.loading, this.isDisabledOrLoading, this.props.stretch, this.props.size, this.props.hideLabel, this.props.alignLabel, this.props.underline, this.props.theme)));
94
94
  return (jsxs(Fragment, { children: [jsxs("template", { shadowroot: "open", shadowrootmode: "open", shadowrootdelegatesfocus: "true", children: [jsx("style", { dangerouslySetInnerHTML: { __html: style } }), jsxs(Fragment, { children: [jsxs("button", { ...getButtonPureAriaAttributes(this.props.disabled, this.props.loading, this.props.aria), className: "root", type: this.props.type, name: this.props.name, value: this.props.value, "aria-describedby": this.props.loading ? loadingId : undefined, children: [this.props.loading ? (jsx(PSpinner, { ...iconProps, "aria-hidden": "true" })) : (hasIcon && (jsx(PIcon, { ...iconProps, name: this.props.icon, source: this.props.iconSource, color: this.isDisabledOrLoading ? 'state-disabled' : 'primary', theme: this.props.theme, "aria-hidden": "true" }))), jsx("span", { className: "label", children: jsx("slot", {}) })] }), jsx(LoadingMessage, { loading: this.props.loading, initialLoading: false })] })] }), this.props.children] }));
95
95
  }
96
96
  }
@@ -53,6 +53,10 @@ export type PButtonPureProps = Omit<HTMLAttributes<{}>, 'color'> & {
53
53
  * Specifies the type of the button.
54
54
  */
55
55
  type?: ButtonPureType;
56
+ /**
57
+ * Shows an underline under the label.
58
+ */
59
+ underline?: boolean;
56
60
  /**
57
61
  * Defines the value associated with the button's name when it's submitted with the form data. This value is passed to the server in params when the form is submitted using this button.
58
62
  */
@@ -116,6 +120,10 @@ export declare const PButtonPure: import("react").ForwardRefExoticComponent<Omit
116
120
  * Specifies the type of the button.
117
121
  */
118
122
  type?: ButtonPureType;
123
+ /**
124
+ * Shows an underline under the label.
125
+ */
126
+ underline?: boolean;
119
127
  /**
120
128
  * Defines the value associated with the button's name when it's submitted with the form data. This value is passed to the server in params when the form is submitted using this button.
121
129
  */
@@ -1,8 +0,0 @@
1
- import { Component } from 'react';
2
- export declare class DSRBanner extends Component<any> {
3
- host: HTMLElement;
4
- private inlineNotificationElement;
5
- private closeBtn;
6
- private get hasDismissButton();
7
- render(): JSX.Element;
8
- }