@porsche-design-system/components-react 3.1.0 → 3.2.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 (25) hide show
  1. package/CHANGELOG.md +42 -9
  2. package/esm/lib/components/carousel.wrapper.js +3 -3
  3. package/esm/lib/components/pagination.wrapper.js +3 -3
  4. package/lib/components/carousel.wrapper.d.ts +8 -0
  5. package/lib/components/carousel.wrapper.js +3 -3
  6. package/lib/components/pagination.wrapper.d.ts +10 -2
  7. package/lib/components/pagination.wrapper.js +3 -3
  8. package/lib/types.d.ts +199 -199
  9. package/package.json +2 -2
  10. package/ssr/components/dist/styles/esm/styles-entry.js +80 -37
  11. package/ssr/components/dist/utils/esm/utils-entry.js +55 -89
  12. package/ssr/components-react/projects/react-ssr-wrapper/src/lib/components/carousel.wrapper.js +4 -4
  13. package/ssr/components-react/projects/react-ssr-wrapper/src/lib/components/pagination.wrapper.js +4 -4
  14. package/ssr/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/carousel.js +5 -4
  15. package/ssr/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/pagination.js +7 -6
  16. package/ssr/esm/components/dist/styles/esm/styles-entry.js +80 -37
  17. package/ssr/esm/components/dist/utils/esm/utils-entry.js +55 -89
  18. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/components/carousel.wrapper.js +4 -4
  19. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/components/pagination.wrapper.js +4 -4
  20. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/carousel.js +5 -4
  21. package/ssr/esm/components-react/projects/react-ssr-wrapper/src/lib/dsr-components/pagination.js +8 -7
  22. package/ssr/lib/components/carousel.wrapper.d.ts +8 -0
  23. package/ssr/lib/components/pagination.wrapper.d.ts +10 -2
  24. package/ssr/lib/dsr-components/pagination.d.ts +0 -1
  25. package/ssr/lib/types.d.ts +199 -199
@@ -315,14 +315,17 @@ const hasVisibleIcon = (iconName, iconSource) => {
315
315
  };
316
316
 
317
317
  const childrenMutationMap = new Map();
318
- const getObservedNode = (mutatedNode) => childrenMutationMap.has(mutatedNode) ? mutatedNode : getObservedNode(mutatedNode.parentNode);
319
318
  hasWindow &&
320
319
  new MutationObserver((mutations) => {
321
- mutations
322
- // remove duplicates so we execute callback only once per node
323
- .filter((mutation, idx, arr) => arr.findIndex((m) => m.target === mutation.target) === idx)
324
- .map((mutation) => getObservedNode(mutation.target)) // recursively find root node that is initially observed
325
- .forEach((node) => childrenMutationMap.get(node)());
320
+ // there may be race conditions in jsdom-polyfill tests where the map is already empty when a mutation happens
321
+ if (childrenMutationMap.size) {
322
+ const mapKeys = Array.from(childrenMutationMap.keys());
323
+ mutations
324
+ // remove duplicates so we execute callback only once per node
325
+ .filter((mutation, idx, arr) => arr.findIndex((m) => m.target === mutation.target) === idx)
326
+ // find node in map that contains the mutated element to find and invoke its callback
327
+ .forEach((mutation) => { var _a; return (_a = childrenMutationMap.get(mapKeys.find((node) => node.contains(mutation.target)))) === null || _a === void 0 ? void 0 : _a(); });
328
+ }
326
329
  });
327
330
 
328
331
  /* eslint-disable no-undefined,no-param-reassign,no-shadow */
@@ -4352,6 +4355,11 @@ const getComponentCss$U = (icon, iconSource, variant, hideLabel, disabled, loadi
4352
4355
 
4353
4356
  const carouselTransitionDuration = 400;
4354
4357
  const bulletActiveClass = 'bullet--active';
4358
+ const paginationInfiniteStartCaseClass = 'pagination--infinite';
4359
+ const bulletInfiniteClass = 'bullet--infinite';
4360
+ const paginationBulletSize = '8px';
4361
+ const paginationInfiniteBulletSize = '4px';
4362
+ const paginationActiveBulletSize = '20px';
4355
4363
  const selectorHeading = 'h2,::slotted([slot=heading])';
4356
4364
  const selectorDescription = 'p,::slotted([slot=description])';
4357
4365
  const mediaQueryS = getMediaQueryMin('s');
@@ -4359,13 +4367,13 @@ const mediaQueryXXL = getMediaQueryMin('xxl');
4359
4367
  // we need an explicit grid template, therefor we need to calculate the button group width
4360
4368
  const buttonSize$1 = `calc(${spacingStaticSmall} * 2 + ${fontLineHeight})`;
4361
4369
  // + 2px, compensates hover offset of button-pure
4362
- const buttonGroupWidth = `calc(${buttonSize$1} * 2 + ${spacingStaticXSmall} + 2px)`;
4370
+ const buttonGroupWidth = `calc(${buttonSize$1} * 3 + ${spacingStaticXSmall} + 2px)`;
4363
4371
  const spacingMap = {
4364
4372
  basic: gridBasicOffset,
4365
4373
  extended: gridExtendedOffset,
4366
4374
  };
4367
- const getComponentCss$T = (width, hasPagination, alignHeader, theme) => {
4368
- const { primaryColor, contrastMediumColor } = getThemedColors(theme);
4375
+ const getComponentCss$T = (width, hasPagination, isInfinitePagination, alignHeader, theme) => {
4376
+ const { primaryColor, contrastMediumColor, focusColor } = getThemedColors(theme);
4369
4377
  const { canvasTextColor } = getHighContrastColors();
4370
4378
  const isHeaderAlignCenter = alignHeader === 'center';
4371
4379
  return getCss(Object.assign({ '@global': {
@@ -4395,12 +4403,23 @@ const getComponentCss$T = (width, hasPagination, alignHeader, theme) => {
4395
4403
  gap: spacingStaticXSmall,
4396
4404
  gridArea: '1 / 3 / 3 / auto',
4397
4405
  alignItems: 'end',
4406
+ justifyContent: 'end',
4407
+ justifySelf: 'end',
4398
4408
  },
4399
4409
  }, btn: {
4400
4410
  padding: spacingStaticSmall,
4411
+ }, 'skip-link': {
4412
+ opacity: 0,
4413
+ pointerEvents: 'none',
4414
+ '&:focus': {
4415
+ opacity: 1,
4416
+ pointerEvents: 'all',
4417
+ },
4401
4418
  }, splide: {
4402
4419
  overflow: 'hidden',
4403
4420
  // visibility: 'hidden',
4421
+ padding: '4px 0',
4422
+ margin: '-4px 0',
4404
4423
  '&__track': Object.assign(Object.assign({ cursor: 'grab' }, addImportantToEachRule({
4405
4424
  padding: `0 ${spacingMap[width].base}`,
4406
4425
  [getMediaQueryMax('xs')]: {
@@ -4417,26 +4436,58 @@ const getComponentCss$T = (width, hasPagination, alignHeader, theme) => {
4417
4436
  WebkitUserSelect: 'none',
4418
4437
  WebkitTouchCallout: 'none',
4419
4438
  } }),
4420
- '&__list': Object.assign({ display: 'flex', height: '100%' }, getBackfaceVisibilityJssStyle()),
4421
- '&__slide': Object.assign(Object.assign({ position: 'relative', flexShrink: 0 }, getBackfaceVisibilityJssStyle()), { transform: 'translateZ(0)' }),
4439
+ '&__list': Object.assign({ display: 'flex' }, getBackfaceVisibilityJssStyle()),
4440
+ '&__slide': Object.assign(Object.assign({ position: 'relative', flexShrink: 0 }, getBackfaceVisibilityJssStyle()), { transform: 'translateZ(0)', borderRadius: borderRadiusLarge, overflow: 'hidden', '&:focus-visible': {
4441
+ outline: `${borderWidthBase} solid ${focusColor}`,
4442
+ outlineOffset: '2px',
4443
+ } }),
4422
4444
  '&__sr': getHiddenTextJssStyle(), // appears in the DOM when sliding
4423
- } }, (hasPagination && {
4424
- pagination: Object.assign(Object.assign({}, buildResponsiveStyles(hasPagination, (hasPaginationValue) => ({
4445
+ } }, (hasPagination && Object.assign(Object.assign({ ['pagination-container']: Object.assign(Object.assign({}, buildResponsiveStyles(hasPagination, (hasPaginationValue) => ({
4425
4446
  display: hasPaginationValue ? 'flex' : 'none',
4426
- }))), { justifyContent: 'center', gap: spacingStaticSmall }),
4427
- bullet: {
4428
- borderRadius: borderRadiusSmall,
4429
- background: isHighContrastMode ? canvasTextColor : contrastMediumColor,
4430
- // set transition to have the same speed as switching slides in splide
4431
- transition: `background-color ${carouselTransitionDuration}ms, width ${carouselTransitionDuration}ms`,
4432
- width: '8px',
4433
- height: '8px',
4434
- },
4435
- [bulletActiveClass]: {
4436
- background: isHighContrastMode ? canvasTextColor : primaryColor,
4437
- width: '20px',
4447
+ }))), { position: 'relative', justifyContent: isInfinitePagination ? 'flex-start' : 'center', width: `calc(${paginationActiveBulletSize} + ${paginationBulletSize} * 4 + ${spacingStaticSmall} * 4)`, left: 'calc(50% - 42px)', overflowX: 'hidden' }), pagination: {
4448
+ display: 'flex',
4449
+ alignItems: 'center',
4450
+ width: 'fit-content',
4451
+ height: paginationBulletSize,
4452
+ gap: spacingStaticSmall,
4453
+ transition: `transform ${carouselTransitionDuration}ms`,
4454
+ }, bullet: Object.assign({ borderRadius: borderRadiusSmall, background: isHighContrastMode ? canvasTextColor : contrastMediumColor }, (isInfinitePagination
4455
+ ? {
4456
+ width: '0px',
4457
+ height: '0px',
4458
+ transition: `background-color ${carouselTransitionDuration}ms, width ${carouselTransitionDuration}ms, height ${carouselTransitionDuration}ms`,
4459
+ }
4460
+ : {
4461
+ width: paginationBulletSize,
4462
+ height: paginationBulletSize,
4463
+ transition: `background-color ${carouselTransitionDuration}ms, width ${carouselTransitionDuration}ms`,
4464
+ })) }, (isInfinitePagination && {
4465
+ [`${paginationInfiniteStartCaseClass}`]: {
4466
+ ['& > .bullet:nth-child(-n+4)']: {
4467
+ width: paginationBulletSize,
4468
+ height: paginationBulletSize,
4469
+ },
4438
4470
  },
4439
- })));
4471
+ [`${bulletInfiniteClass}`]: Object.assign(Object.assign({}, addImportantToEachRule({
4472
+ width: paginationInfiniteBulletSize,
4473
+ height: paginationInfiniteBulletSize,
4474
+ })), { '& ~ span': {
4475
+ width: paginationBulletSize,
4476
+ height: paginationBulletSize,
4477
+ }, [`& ~ .${bulletInfiniteClass} ~ span`]: {
4478
+ width: '0px',
4479
+ height: '0px',
4480
+ } }),
4481
+ })), { [`${bulletActiveClass}`]: Object.assign({ background: isHighContrastMode ? canvasTextColor : primaryColor, height: paginationBulletSize, width: addImportantToRule(paginationActiveBulletSize) }, (isInfinitePagination && {
4482
+ '& ~ span': {
4483
+ width: paginationBulletSize,
4484
+ height: paginationBulletSize,
4485
+ },
4486
+ [`& ~ .${bulletInfiniteClass} ~ span`]: {
4487
+ width: '0px',
4488
+ height: '0px',
4489
+ },
4490
+ })) }))));
4440
4491
  };
4441
4492
 
4442
4493
  const getThemedFormStateColors = (theme, state) => {
@@ -5330,7 +5381,7 @@ const getComponentCss$v = (maxNumberOfPageLinks, theme) => {
5330
5381
  return getCss({
5331
5382
  '@global': {
5332
5383
  ':host': Object.assign({ display: 'block' }, addImportantToEachRule(hostHiddenStyles)),
5333
- nav: Object.assign({ display: 'flex', justifyContent: 'center' }, buildResponsiveStyles(maxNumberOfPageLinks, (n) => ({
5384
+ nav: Object.assign({ display: 'flex', justifyContent: 'center', userSelect: 'none' }, buildResponsiveStyles(maxNumberOfPageLinks, (n) => ({
5334
5385
  counterReset: `size ${n}`,
5335
5386
  }))),
5336
5387
  ul: {
@@ -5354,16 +5405,8 @@ const getComponentCss$v = (maxNumberOfPageLinks, theme) => {
5354
5405
  },
5355
5406
  },
5356
5407
  span: Object.assign(Object.assign(Object.assign(Object.assign({ display: 'flex', justifyContent: 'center', alignItems: 'center', transition: ['color', 'border-color', 'background-color'].map(getTransition).join(), position: 'relative', width: buttonSize, height: buttonSize, boxSizing: 'border-box' }, textSmallStyle), { whiteSpace: 'nowrap', cursor: 'pointer', color: primaryColor, outline: 0, borderRadius: borderRadiusSmall, borderColor: 'transparent' }), hoverMediaQuery({
5357
- '&:not([aria-disabled]):not(.ellipsis):hover': Object.assign(Object.assign({}, frostedGlassStyle), { backgroundColor: hoverColor }),
5358
- })), { '&:not(.ellipsis):focus::before': Object.assign(Object.assign({ content: '""', position: 'absolute' }, getInsetJssStyle(-4)), { border: `${borderWidthBase} solid ${focusColor}`, borderRadius: borderRadiusMedium }), '&:focus:not(:focus-visible)::before': {
5359
- borderColor: 'transparent',
5360
- }, '&[aria-current]': {
5361
- disabledCursorStyle,
5362
- color: primaryColor,
5363
- border: `${borderWidthBase} solid ${primaryColor}`,
5364
- borderRadius: borderRadiusSmall,
5365
- '&:not(.ellipsis):focus::before': Object.assign({}, getInsetJssStyle(-6)),
5366
- }, '&[aria-disabled]': Object.assign(Object.assign({}, disabledCursorStyle), { color: disabledColor }) }),
5408
+ '&:not([aria-disabled]):not(.ellipsis):hover': Object.assign(Object.assign({}, frostedGlassStyle), { background: hoverColor }),
5409
+ })), { '&:not(.ellipsis):focus:focus-visible::before': Object.assign(Object.assign({ content: '""', position: 'absolute' }, getInsetJssStyle(-4)), { border: `${borderWidthBase} solid ${focusColor}`, borderRadius: borderRadiusMedium }), '&[aria-current]': Object.assign(Object.assign({}, disabledCursorStyle), { color: primaryColor, border: `${borderWidthBase} solid ${primaryColor}`, '&:not(.ellipsis):focus::before': getInsetJssStyle(-6) }), '&[aria-disabled]': Object.assign(Object.assign({}, disabledCursorStyle), { color: disabledColor }) }),
5367
5410
  },
5368
5411
  ellipsis: Object.assign(Object.assign({}, disabledCursorStyle), { '&::after': {
5369
5412
  content: '"…"',
@@ -158,14 +158,17 @@ const hasVisibleIcon = (iconName, iconSource) => {
158
158
  };
159
159
 
160
160
  const childrenMutationMap = new Map();
161
- const getObservedNode = (mutatedNode) => childrenMutationMap.has(mutatedNode) ? mutatedNode : getObservedNode(mutatedNode.parentNode);
162
161
  hasWindow &&
163
162
  new MutationObserver((mutations) => {
164
- mutations
165
- // remove duplicates so we execute callback only once per node
166
- .filter((mutation, idx, arr) => arr.findIndex((m) => m.target === mutation.target) === idx)
167
- .map((mutation) => getObservedNode(mutation.target)) // recursively find root node that is initially observed
168
- .forEach((node) => childrenMutationMap.get(node)());
163
+ // there may be race conditions in jsdom-polyfill tests where the map is already empty when a mutation happens
164
+ if (childrenMutationMap.size) {
165
+ const mapKeys = Array.from(childrenMutationMap.keys());
166
+ mutations
167
+ // remove duplicates so we execute callback only once per node
168
+ .filter((mutation, idx, arr) => arr.findIndex((m) => m.target === mutation.target) === idx)
169
+ // find node in map that contains the mutated element to find and invoke its callback
170
+ .forEach((mutation) => { var _a; return (_a = childrenMutationMap.get(mapKeys.find((node) => node.contains(mutation.target)))) === null || _a === void 0 ? void 0 : _a(); });
171
+ }
169
172
  });
170
173
 
171
174
  const isTouchDevice = () => {
@@ -2759,7 +2762,7 @@ function convertCase(style) {
2759
2762
  */
2760
2763
 
2761
2764
 
2762
- function camelCase$1() {
2765
+ function camelCase() {
2763
2766
  function onProcessStyle(style) {
2764
2767
  if (Array.isArray(style)) {
2765
2768
  // Handle rules like @font-face, which can have multiple styles in an array
@@ -3629,7 +3632,7 @@ createJss({
3629
3632
  plugins: [
3630
3633
  jssGlobal(),
3631
3634
  jssNested(),
3632
- camelCase$1(),
3635
+ camelCase(),
3633
3636
  jssPluginSortMediaQueries({ combineMediaQueries: true }),
3634
3637
  ],
3635
3638
  });
@@ -3683,7 +3686,11 @@ const getButtonAriaAttributes = (isDisabled, isLoading, aria) => {
3683
3686
  };
3684
3687
  getMediaQueryMin('s');
3685
3688
  getMediaQueryMin('xxl');
3686
- typeof HTMLElement !== 'undefined' && HTMLElement.prototype.hasOwnProperty('inert');
3689
+ // Infinite bullets will be shown if the total number of bullets is greater than this value
3690
+ const INFINITE_BULLET_THRESHOLD = 5;
3691
+ const isInfinitePagination = (amountOfPages) => {
3692
+ return amountOfPages > INFINITE_BULLET_THRESHOLD;
3693
+ };
3687
3694
 
3688
3695
  const CDN_BASE_URL$3 = (typeof window !== 'undefined' && window.PORSCHE_DESIGN_SYSTEM_CDN === 'cn' ? 'https://cdn.ui.porsche.cn' : 'https://cdn.ui.porsche.com') + '/porsche-design-system/crest';
3689
3696
  const CRESTS_MANIFEST = { "porscheCrest": { "1x": { "png": "porsche-crest.min.d76137cf8cf94822b7aedb534ba88418@1x.png", "webp": "porsche-crest.min.0d0cc89ae5ee57c4c15bd0dbbcbfe5d0@1x.webp" }, "2x": { "png": "porsche-crest.min.8a292fbd35a5155789ddd011585e05c4@2x.png", "webp": "porsche-crest.min.2245c45e99be5a46b4b56e73c43d5c63@2x.webp" }, "3x": { "png": "porsche-crest.min.18d6f02003b0829bac939fade88fd4e6@3x.png", "webp": "porsche-crest.min.19b429278b158b5cb5aa6ce80751e3fe@3x.webp" } } };
@@ -3812,38 +3819,21 @@ const getSvgUrl = (model) => {
3812
3819
  return `${cdnBaseUrl}/${MODEL_SIGNATURES_MANIFEST[model]}`;
3813
3820
  };
3814
3821
  const modelSignatureHeight = 36;
3815
- // TODO: create enum
3816
- const itemTypes = {
3817
- PAGE: 'PAGE',
3818
- ELLIPSIS: 'ELLIPSIS',
3819
- PREVIOUS_PAGE_LINK: 'PREVIOUS_PAGE_LINK',
3820
- NEXT_PAGE_LINK: 'NEXT_PAGE_LINK',
3821
- };
3822
- // TODO: unused?
3823
- const itemKeys = {
3824
- FIRST_ELLIPSIS: -1,
3825
- SECOND_ELLIPSIS: -2,
3826
- PREVIOUS_PAGE_LINK: -4,
3827
- NEXT_PAGE_LINK: -5,
3828
- };
3829
- // TODO: merge factories
3830
- const createFirstEllipsis = (pageNumber) => ({
3831
- type: itemTypes.ELLIPSIS,
3832
- key: itemKeys.FIRST_ELLIPSIS,
3833
- value: pageNumber,
3834
- isActive: false,
3835
- });
3836
- const createSecondEllipsis = (pageNumber) => ({
3837
- type: itemTypes.ELLIPSIS,
3838
- key: itemKeys.SECOND_ELLIPSIS,
3839
- value: pageNumber,
3822
+ exports.ItemType = void 0;
3823
+ (function (ItemType) {
3824
+ ItemType[ItemType["PAGE"] = 0] = "PAGE";
3825
+ ItemType[ItemType["ELLIPSIS"] = 1] = "ELLIPSIS";
3826
+ ItemType[ItemType["PREVIOUS"] = 2] = "PREVIOUS";
3827
+ ItemType[ItemType["NEXT"] = 3] = "NEXT";
3828
+ })(exports.ItemType || (exports.ItemType = {}));
3829
+ const ellipsisItem = {
3830
+ type: exports.ItemType.ELLIPSIS,
3840
3831
  isActive: false,
3841
- });
3832
+ };
3842
3833
  const createPreviousPageLink = (options) => {
3843
3834
  const { activePage } = options;
3844
3835
  return {
3845
- type: itemTypes.PREVIOUS_PAGE_LINK,
3846
- key: itemKeys.PREVIOUS_PAGE_LINK,
3836
+ type: exports.ItemType.PREVIOUS,
3847
3837
  value: Math.max(1, activePage - 1),
3848
3838
  isActive: activePage > 1,
3849
3839
  };
@@ -3851,78 +3841,58 @@ const createPreviousPageLink = (options) => {
3851
3841
  const createNextPageLink = (options) => {
3852
3842
  const { activePage, pageTotal } = options;
3853
3843
  return {
3854
- type: itemTypes.NEXT_PAGE_LINK,
3855
- key: itemKeys.NEXT_PAGE_LINK,
3844
+ type: exports.ItemType.NEXT,
3856
3845
  value: Math.min(pageTotal, activePage + 1),
3857
3846
  isActive: activePage < pageTotal,
3858
3847
  };
3859
3848
  };
3860
3849
  const createPageFunctionFactory = (options) => {
3861
- const { activePage } = options;
3862
3850
  return (pageNumber) => ({
3863
- type: itemTypes.PAGE,
3864
- key: pageNumber,
3851
+ type: exports.ItemType.PAGE,
3865
3852
  value: pageNumber,
3866
- isActive: pageNumber === activePage,
3853
+ isActive: pageNumber === options.activePage,
3867
3854
  });
3868
3855
  };
3869
3856
  const createRange = (start, end) => Array.from(Array(end - start + 1)).map((_, i) => i + start);
3870
3857
  const createPaginationModel = (options) => {
3871
- // exception tests
3872
- if (options == null) {
3873
- throw new Error('createPaginationModel(): options object should be a passed');
3874
- }
3875
- const { pageTotal, activePage, pageRange } = options;
3858
+ const { pageTotal, activePage, pageRange, showLastPage } = options;
3876
3859
  const boundaryPagesRange = 1;
3877
3860
  const ellipsisSize = 1;
3878
- const paginationModel = [];
3861
+ const paginationModel = [createPreviousPageLink(options)];
3879
3862
  const createPage = createPageFunctionFactory(options);
3880
- paginationModel.push(createPreviousPageLink(options));
3881
3863
  // Simplify generation of pages if number of available items is equal or greater than total pages to show
3882
3864
  if (1 + 2 * ellipsisSize + 2 * pageRange + 2 * boundaryPagesRange >= pageTotal) {
3883
3865
  const allPages = createRange(1, pageTotal).map(createPage);
3884
3866
  paginationModel.push(...allPages);
3885
3867
  }
3886
3868
  else {
3887
- // Calculate group of first pages
3888
- const firstPagesStart = 1;
3889
- const firstPagesEnd = boundaryPagesRange;
3890
- const firstPages = createRange(firstPagesStart, firstPagesEnd).map(createPage);
3891
- // Calculate group of last pages
3892
- const lastPagesStart = pageTotal + 1 - boundaryPagesRange;
3893
- const lastPagesEnd = pageTotal;
3894
- const lastPages = createRange(lastPagesStart, lastPagesEnd).map(createPage);
3895
- // Calculate group of main pages
3896
- const mainPagesStart = Math.min(Math.max(activePage - pageRange, firstPagesEnd + ellipsisSize + 1), lastPagesStart - ellipsisSize - 2 * pageRange - 1);
3897
- const mainPagesEnd = mainPagesStart + 2 * pageRange;
3898
- const mainPages = createRange(mainPagesStart, mainPagesEnd).map(createPage);
3899
- // Add group of first pages
3900
- paginationModel.push(...firstPages);
3901
- // Calculate and add ellipsis before group of main pages
3902
- const firstEllipsisPageNumber = mainPagesStart - 1;
3903
- const showPageInsteadOfFirstEllipsis = firstEllipsisPageNumber === firstPagesEnd + 1;
3904
- const createFirstEllipsisOrPage = showPageInsteadOfFirstEllipsis ? createPage : createFirstEllipsis;
3905
- const firstEllipsis = createFirstEllipsisOrPage(firstEllipsisPageNumber);
3906
- paginationModel.push(firstEllipsis);
3907
- // Add group of main pages
3908
- paginationModel.push(...mainPages);
3909
- // Calculate and add ellipsis after group of main pages
3910
- const secondEllipsisPageNumber = mainPagesEnd + 1;
3911
- const showPageInsteadOfSecondEllipsis = secondEllipsisPageNumber === lastPagesStart - 1;
3912
- const createSecondEllipsisOrPage = showPageInsteadOfSecondEllipsis ? createPage : createSecondEllipsis;
3913
- const secondEllipsis = createSecondEllipsisOrPage(secondEllipsisPageNumber);
3914
- paginationModel.push(secondEllipsis);
3915
- // Add group of last pages
3916
- paginationModel.push(...lastPages);
3869
+ // Add first page
3870
+ paginationModel.push(createPage(1));
3871
+ // Calculate group of middle pages
3872
+ const middlePagesStart = Math.min(Math.max(activePage - pageRange, 2 + ellipsisSize), pageTotal - ellipsisSize - 2 * pageRange - (showLastPage ? 1 : 0));
3873
+ const middlePagesEnd = middlePagesStart + 2 * pageRange;
3874
+ const middlePages = createRange(middlePagesStart, middlePagesEnd).map(createPage);
3875
+ // Calculate and add ellipsis before group of middle pages
3876
+ const firstEllipsisPageNumber = middlePagesStart - 1;
3877
+ const showPageInsteadOfFirstEllipsis = firstEllipsisPageNumber === 2;
3878
+ const firstEllipsisOrPage = showPageInsteadOfFirstEllipsis ? createPage(firstEllipsisPageNumber) : ellipsisItem;
3879
+ paginationModel.push(firstEllipsisOrPage);
3880
+ // Add group of middle pages
3881
+ paginationModel.push(...middlePages);
3882
+ // Calculate and add ellipsis after group of middle pages
3883
+ const lastEllipsisPageNumber = middlePagesEnd + 1;
3884
+ const showPageInsteadOfLastEllipsis = lastEllipsisPageNumber === pageTotal - (showLastPage ? 1 : 0);
3885
+ const lastEllipsisOrPage = showPageInsteadOfLastEllipsis ? createPage(lastEllipsisPageNumber) : ellipsisItem;
3886
+ paginationModel.push(lastEllipsisOrPage);
3887
+ // Add last page
3888
+ if (showLastPage) {
3889
+ paginationModel.push(createPage(pageTotal));
3890
+ }
3917
3891
  }
3918
3892
  paginationModel.push(createNextPageLink(options));
3919
3893
  return paginationModel;
3920
3894
  };
3921
3895
  const getCurrentActivePage = (activePage, totalPages) => {
3922
- // exception tests
3923
- if (activePage === undefined || totalPages === undefined) {
3924
- throw new Error('getCurrentActivePage(): activePage and totalPages props must be provided');
3925
- }
3926
3896
  // Obviously we can't be on a negative or 0 page.
3927
3897
  if (activePage < 1) {
3928
3898
  activePage = 1;
@@ -3934,10 +3904,6 @@ const getCurrentActivePage = (activePage, totalPages) => {
3934
3904
  return activePage;
3935
3905
  };
3936
3906
  const getTotalPages = (totalItemsCount, itemsPerPage) => {
3937
- // exception test
3938
- if (totalItemsCount === undefined || itemsPerPage === undefined) {
3939
- throw new Error('getTotalPages(): totalItemsCount and itemsPerPage props must be provided');
3940
- }
3941
3907
  if (totalItemsCount < 1) {
3942
3908
  totalItemsCount = 1;
3943
3909
  }
@@ -4140,6 +4106,7 @@ exports.hasWindow = hasWindow;
4140
4106
  exports.isCustomDropdown = isCustomDropdown;
4141
4107
  exports.isDisabledOrLoading = isDisabledOrLoading;
4142
4108
  exports.isHighContrastMode = isHighContrastMode;
4109
+ exports.isInfinitePagination = isInfinitePagination;
4143
4110
  exports.isListTypeOrdered = isListTypeOrdered;
4144
4111
  exports.isScrollable = isScrollable;
4145
4112
  exports.isSortable = isSortable;
@@ -4149,7 +4116,6 @@ exports.isTouchDevice = isTouchDevice;
4149
4116
  exports.isType = isType;
4150
4117
  exports.isUrl = isUrl;
4151
4118
  exports.isWithinForm = isWithinForm;
4152
- exports.itemTypes = itemTypes;
4153
4119
  exports.modelSignatureHeight = modelSignatureHeight;
4154
4120
  exports.parseAndGetAriaAttributes = parseAndGetAriaAttributes;
4155
4121
  exports.parseJSONAttribute = parseJSONAttribute;
@@ -6,15 +6,15 @@ var hooks = require('../../hooks.js');
6
6
  var utils = require('../../utils.js');
7
7
  var carousel = require('../dsr-components/carousel.js');
8
8
 
9
- const PCarousel = react.forwardRef(({ activeSlideIndex = 0, alignHeader = 'left', description, disablePagination, heading, intl, onCarouselChange, onUpdate, pagination = true, rewind = true, slidesPerPage = 1, theme = 'light', width = 'basic', wrapContent, className, children, ...rest }, ref) => {
9
+ const PCarousel = react.forwardRef(({ activeSlideIndex = 0, alignHeader = 'left', description, disablePagination, heading, intl, onCarouselChange, onUpdate, pagination = true, rewind = true, skipLinkTarget, slidesPerPage = 1, theme = 'light', width = 'basic', wrapContent, className, children, ...rest }, ref) => {
10
10
  const elementRef = react.useRef();
11
11
  hooks.useEventCallback(elementRef, 'carouselChange', onCarouselChange);
12
12
  hooks.useEventCallback(elementRef, 'update', onUpdate);
13
13
  const WebComponentTag = hooks.usePrefix('p-carousel');
14
- const propsToSync = [activeSlideIndex, alignHeader, description, disablePagination, heading, intl, pagination, rewind, slidesPerPage, theme, width, wrapContent];
14
+ const propsToSync = [activeSlideIndex, alignHeader, description, disablePagination, heading, intl, pagination, rewind, skipLinkTarget, slidesPerPage, theme, width, wrapContent];
15
15
  hooks.useBrowserLayoutEffect(() => {
16
16
  const { current } = elementRef;
17
- ['activeSlideIndex', 'alignHeader', 'description', 'disablePagination', 'heading', 'intl', 'pagination', 'rewind', 'slidesPerPage', 'theme', 'width', 'wrapContent'].forEach((propName, i) => (current[propName] = propsToSync[i]));
17
+ ['activeSlideIndex', 'alignHeader', 'description', 'disablePagination', 'heading', 'intl', 'pagination', 'rewind', 'skipLinkTarget', 'slidesPerPage', 'theme', 'width', 'wrapContent'].forEach((propName, i) => (current[propName] = propsToSync[i]));
18
18
  }, propsToSync);
19
19
  // @ts-ignore
20
20
  if (!process.browser) {
@@ -25,7 +25,7 @@ const PCarousel = react.forwardRef(({ activeSlideIndex = 0, alignHeader = 'left'
25
25
  // @ts-ignore
26
26
  ...(!process.browser
27
27
  ? {
28
- children: (jsxRuntime.jsx(carousel.DSRCarousel, { ...{ activeSlideIndex, alignHeader, description, disablePagination, heading, intl, pagination, rewind, slidesPerPage, theme, width, wrapContent, children } })),
28
+ children: (jsxRuntime.jsx(carousel.DSRCarousel, { ...{ activeSlideIndex, alignHeader, description, disablePagination, heading, intl, pagination, rewind, skipLinkTarget, slidesPerPage, theme, width, wrapContent, children } })),
29
29
  }
30
30
  : {
31
31
  children,
@@ -6,15 +6,15 @@ var hooks = require('../../hooks.js');
6
6
  var utils = require('../../utils.js');
7
7
  var pagination = require('../dsr-components/pagination.js');
8
8
 
9
- const PPagination = react.forwardRef(({ activePage = 1, allyLabel, allyLabelNext, allyLabelPage, allyLabelPrev, intl = { root: 'Pagination', prev: 'Previous page', next: 'Next page', page: 'Page', }, itemsPerPage = 1, maxNumberOfPageLinks = { base: 5, xs: 7, }, onPageChange, onUpdate, theme = 'light', totalItemsCount = 1, className, ...rest }, ref) => {
9
+ const PPagination = react.forwardRef(({ activePage = 1, allyLabel, allyLabelNext, allyLabelPage, allyLabelPrev, intl = { root: 'Pagination', prev: 'Previous page', next: 'Next page', page: 'Page', }, itemsPerPage = 1, maxNumberOfPageLinks = { base: 5, xs: 7, }, onPageChange, onUpdate, showLastPage = true, theme = 'light', totalItemsCount = 1, className, ...rest }, ref) => {
10
10
  const elementRef = react.useRef();
11
11
  hooks.useEventCallback(elementRef, 'pageChange', onPageChange);
12
12
  hooks.useEventCallback(elementRef, 'update', onUpdate);
13
13
  const WebComponentTag = hooks.usePrefix('p-pagination');
14
- const propsToSync = [activePage, allyLabel, allyLabelNext, allyLabelPage, allyLabelPrev, intl, itemsPerPage, maxNumberOfPageLinks, theme, totalItemsCount];
14
+ const propsToSync = [activePage, allyLabel, allyLabelNext, allyLabelPage, allyLabelPrev, intl, itemsPerPage, maxNumberOfPageLinks, showLastPage, theme, totalItemsCount];
15
15
  hooks.useBrowserLayoutEffect(() => {
16
16
  const { current } = elementRef;
17
- ['activePage', 'allyLabel', 'allyLabelNext', 'allyLabelPage', 'allyLabelPrev', 'intl', 'itemsPerPage', 'maxNumberOfPageLinks', 'theme', 'totalItemsCount'].forEach((propName, i) => (current[propName] = propsToSync[i]));
17
+ ['activePage', 'allyLabel', 'allyLabelNext', 'allyLabelPage', 'allyLabelPrev', 'intl', 'itemsPerPage', 'maxNumberOfPageLinks', 'showLastPage', 'theme', 'totalItemsCount'].forEach((propName, i) => (current[propName] = propsToSync[i]));
18
18
  }, propsToSync);
19
19
  // @ts-ignore
20
20
  if (!process.browser) {
@@ -25,7 +25,7 @@ const PPagination = react.forwardRef(({ activePage = 1, allyLabel, allyLabelNext
25
25
  // @ts-ignore
26
26
  ...(!process.browser
27
27
  ? {
28
- children: (jsxRuntime.jsx(pagination.DSRPagination, { ...{ activePage, allyLabel, allyLabelNext, allyLabelPage, allyLabelPrev, intl, itemsPerPage, maxNumberOfPageLinks, theme, totalItemsCount } })),
28
+ children: (jsxRuntime.jsx(pagination.DSRPagination, { ...{ activePage, allyLabel, allyLabelNext, allyLabelPage, allyLabelPrev, intl, itemsPerPage, maxNumberOfPageLinks, showLastPage, theme, totalItemsCount } })),
29
29
  }
30
30
  : {
31
31
  suppressHydrationWarning: true,
@@ -25,7 +25,7 @@ require('../components/headline.wrapper.js');
25
25
  require('../components/icon.wrapper.js');
26
26
  require('../components/inline-notification.wrapper.js');
27
27
  require('../components/link.wrapper.js');
28
- require('../components/link-pure.wrapper.js');
28
+ var linkPure_wrapper = require('../components/link-pure.wrapper.js');
29
29
  require('../components/link-social.wrapper.js');
30
30
  require('../components/link-tile.wrapper.js');
31
31
  require('../components/link-tile-model-signature.wrapper.js');
@@ -67,6 +67,7 @@ var react = require('react');
67
67
  var minifyCss = require('../../minifyCss.js');
68
68
  var stripFocusAndHoverStyles = require('../../stripFocusAndHoverStyles.js');
69
69
  var stylesEntry = require('../../../../../../components/dist/styles/esm/styles-entry.js');
70
+ var utilsEntry = require('../../../../../../components/dist/utils/esm/utils-entry.js');
70
71
 
71
72
  class DSRCarousel extends react.Component {
72
73
  constructor() {
@@ -89,9 +90,9 @@ class DSRCarousel extends react.Component {
89
90
  ? typeof this.props.disablePagination === 'object'
90
91
  ? Object.fromEntries(Object.entries(this.props.disablePagination).map(([key, value]) => [key, !value]))
91
92
  : !this.props.disablePagination
92
- : this.props.pagination, this.props.alignHeader, this.props.theme)));
93
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("template", { shadowroot: "open", shadowrootmode: "open", children: [jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: style } }), jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "header", children: [this.props.heading ? jsxRuntime.jsx("h2", { children: this.props.heading }) : jsxRuntime.jsx("slot", { name: "heading" }), (this.props.description || namedSlotChildren.filter(({ props: { slot } }) => slot === 'description').length > 0) &&
94
- ((this.props.description && jsxRuntime.jsx("p", { children: this.props.description })) || jsxRuntime.jsx("slot", { name: "description" })), jsxRuntime.jsxs("div", { className: "nav", children: [jsxRuntime.jsx(buttonPure_wrapper.PButtonPure, { ...btnProps, icon: "arrow-left" }), jsxRuntime.jsx(buttonPure_wrapper.PButtonPure, { ...btnProps, icon: "arrow-right" })] })] }), jsxRuntime.jsx("div", { id: "splide", className: "splide", "aria-label": this.props.heading || ((_a = namedSlotChildren.find(({ props: { slot } }) => slot === 'heading')) === null || _a === void 0 ? void 0 : _a.props.children), children: jsxRuntime.jsx("div", { className: "splide__track", children: jsxRuntime.jsx("div", { className: "splide__list", children: otherChildren.map((_, i) => (jsxRuntime.jsx("div", { className: "splide__slide", children: jsxRuntime.jsx("slot", { name: `slide-${i}` }) }, i))) }) }) }), (this.props.disablePagination ? this.props.disablePagination !== true : this.props.pagination) && (jsxRuntime.jsx("div", { className: "pagination" }))] })] }), this.props.children] }));
93
+ : this.props.pagination, utilsEntry.isInfinitePagination(this.props.amountOfPages), this.props.alignHeader, this.props.theme)));
94
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("template", { shadowroot: "open", shadowrootmode: "open", children: [jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: style } }), jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { className: "header", children: [this.props.heading ? jsxRuntime.jsx("h2", { id: "heading", children: this.props.heading }) : jsxRuntime.jsx("slot", { name: "heading" }), (this.props.description || namedSlotChildren.filter(({ props: { slot } }) => slot === 'description').length > 0) &&
95
+ ((this.props.description && jsxRuntime.jsx("p", { children: this.props.description })) || jsxRuntime.jsx("slot", { name: "description" })), jsxRuntime.jsxs("div", { className: "nav", children: [this.props.skipLinkTarget && (jsxRuntime.jsx(linkPure_wrapper.PLinkPure, { href: this.props.skipLinkTarget, theme: this.props.theme, icon: "arrow-last", className: "btn skip-link", alignLabel: "left", hideLabel: true, "aria-describedby": this.props.heading ? 'heading' : null, children: "Skip carousel entries" })), jsxRuntime.jsx(buttonPure_wrapper.PButtonPure, { ...btnProps, icon: "arrow-left" }), jsxRuntime.jsx(buttonPure_wrapper.PButtonPure, { ...btnProps, icon: "arrow-right" })] })] }), jsxRuntime.jsx("div", { id: "splide", className: "splide", "aria-label": this.props.heading || ((_a = namedSlotChildren.find(({ props: { slot } }) => slot === 'heading')) === null || _a === void 0 ? void 0 : _a.props.children), children: jsxRuntime.jsx("div", { className: "splide__track", children: jsxRuntime.jsx("div", { className: "splide__list", children: otherChildren.map((_, i) => (jsxRuntime.jsx("div", { className: "splide__slide", tabIndex: 0, children: jsxRuntime.jsx("slot", { name: `slide-${i}` }) }, i))) }) }) }), (this.props.disablePagination ? this.props.disablePagination !== true : this.props.pagination) && (jsxRuntime.jsx("div", { className: "pagination-container", children: jsxRuntime.jsx("div", { className: "pagination" }) }))] })] }), this.props.children] }));
95
96
  }
96
97
  }
97
98
 
@@ -79,6 +79,7 @@ class DSRPagination extends react.Component {
79
79
  activePage: utilsEntry.getCurrentActivePage(this.props.activePage, pageTotal),
80
80
  pageTotal,
81
81
  pageRange: this.props.breakpointMaxNumberOfPageLinks === 7 ? 1 : 0,
82
+ showLastPage: this.props.showLastPage,
82
83
  });
83
84
  const style = minifyCss.minifyCss(stripFocusAndHoverStyles.stripFocusAndHoverStyles(stylesEntry.getPaginationCss(this.props.maxNumberOfPageLinks, this.props.theme)));
84
85
  return (jsxRuntime.jsx(jsxRuntime.Fragment, { children: jsxRuntime.jsxs("template", { shadowroot: "open", shadowrootmode: "open", shadowrootdelegatesfocus: "true", children: [jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: style } }), jsxRuntime.jsx("nav", { role: "navigation", "aria-label": this.props.allyLabel || this.props.intl.root, children: jsxRuntime.jsx("ul", { children: paginationModel.map((pageModel) => {
@@ -93,14 +94,14 @@ class DSRPagination extends react.Component {
93
94
  'aria-hidden': 'true',
94
95
  };
95
96
  switch (type) {
96
- case utilsEntry.itemTypes.PREVIOUS_PAGE_LINK:
97
- return (jsxRuntime.jsx("li", { children: jsxRuntime.jsx("span", { ...spanProps, "aria-disabled": isActive ? null : 'true', "aria-label": this.props.allyLabelPrev || this.props.intl.prev, children: jsxRuntime.jsx(icon_wrapper.PIcon, { name: "arrow-left", ...iconProps }) }) }, "prev"));
98
- case utilsEntry.itemTypes.ELLIPSIS:
97
+ case utilsEntry.ItemType.PREVIOUS:
98
+ return (jsxRuntime.jsx("li", { children: jsxRuntime.jsx("span", { ...spanProps, "aria-label": this.props.allyLabelPrev || this.props.intl.prev, "aria-disabled": isActive ? null : 'true', children: jsxRuntime.jsx(icon_wrapper.PIcon, { name: "arrow-left", ...iconProps }) }) }, "prev"));
99
+ case utilsEntry.ItemType.ELLIPSIS:
99
100
  return (jsxRuntime.jsx("li", { children: jsxRuntime.jsx("span", { className: "ellipsis" }) }, "ellipsis"));
100
- case utilsEntry.itemTypes.PAGE:
101
+ case utilsEntry.ItemType.PAGE:
101
102
  return (jsxRuntime.jsx("li", { children: jsxRuntime.jsx("span", { ...spanProps, tabIndex: 0, "aria-label": `${this.props.allyLabelPage || this.props.intl.page} ${value}`, "aria-current": isActive ? 'page' : null, children: value }) }, value));
102
- case utilsEntry.itemTypes.NEXT_PAGE_LINK:
103
- return (jsxRuntime.jsx("li", { children: jsxRuntime.jsx("span", { ...spanProps, "aria-disabled": isActive ? null : 'true', "aria-label": this.props.allyLabelNext || this.props.intl.next, children: jsxRuntime.jsx(icon_wrapper.PIcon, { name: "arrow-right", ...iconProps }) }) }, "next"));
103
+ case utilsEntry.ItemType.NEXT:
104
+ return (jsxRuntime.jsx("li", { children: jsxRuntime.jsx("span", { ...spanProps, "aria-label": this.props.allyLabelNext || this.props.intl.next, "aria-disabled": isActive ? null : 'true', children: jsxRuntime.jsx(icon_wrapper.PIcon, { name: "arrow-right", ...iconProps }) }) }, "next"));
104
105
  }
105
106
  }) }) })] }) }));
106
107
  }