@akinon/pz-theme 2.0.119-rc.0 → 2.0.120-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,40 +1,20 @@
1
1
  # @akinon/pz-theme
2
2
 
3
- ## 2.0.119-rc.0
4
-
5
- ### Patch Changes
6
-
7
- - Updated dependencies [86187b1c2]
8
- - Updated dependencies [0cf9ea239]
9
- - Updated dependencies [324f97d55]
10
- - Updated dependencies [51ea06888]
11
- - Updated dependencies
12
- - Updated dependencies [2fea41430]
13
- - Updated dependencies [b55acb768]
14
- - Updated dependencies [760258c1c]
15
- - Updated dependencies [143be2b9d]
16
- - Updated dependencies [7889b08fe]
17
- - Updated dependencies [9f8cd3bc5]
18
- - Updated dependencies [bfafa3f49]
19
- - Updated dependencies [57d7eb305]
20
- - Updated dependencies [d99a6a7d5]
21
- - Updated dependencies [9db81a714]
22
- - Updated dependencies [591e345e1]
23
- - Updated dependencies [4de5303c5]
24
- - Updated dependencies [95b139dc1]
25
- - Updated dependencies [1d00f2d06]
26
- - Updated dependencies [4ac7b2a1e]
27
- - Updated dependencies [e9598c71d]
28
- - Updated dependencies [4998a9631]
29
- - Updated dependencies [804d2bd6c]
30
- - Updated dependencies [3909d3224]
31
- - Updated dependencies [6a3d8a631]
32
- - Updated dependencies [e18836b20]
33
- - Updated dependencies [b1111d7b1]
34
- - Updated dependencies [1595d45]
35
- - Updated dependencies [dca1281]
36
- - @akinon/next@2.0.119-rc.0
37
- - @akinon/theme-contract@2.0.119-rc.0
3
+ ## 2.0.120-beta.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [cbbbfd757]
8
+ - @akinon/next@2.0.120-beta.0
9
+ - @akinon/theme-contract@2.0.120-beta.0
10
+
11
+ ## 2.0.119
12
+
13
+ ### Patch Changes
14
+
15
+ - 322f3bd: Let a slider actually turn at the autoplay speed the merchant set: the value is stored per breakpoint like every other slider option, so reading it without resolving the breakpoint produced no number at all and every slider silently kept the three-second default
16
+ - @akinon/next@2.0.119
17
+ - @akinon/theme-contract@2.0.119
38
18
 
39
19
  ## 2.0.118
40
20
 
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@akinon/pz-theme",
3
3
  "description": "Theme package for Project Zero Next — ThemePlaceholder system and theme editor infrastructure",
4
- "version": "2.0.119-rc.0",
4
+ "version": "2.0.120-beta.0",
5
5
  "license": "MIT",
6
6
  "main": "src/index.ts",
7
7
  "scripts": {
8
8
  "test": "jest"
9
9
  },
10
10
  "peerDependencies": {
11
- "@akinon/next": "2.0.119-rc.0",
11
+ "@akinon/next": "2.0.120-beta.0",
12
12
  "react": "^18.0.0 || ^19.0.0",
13
13
  "react-dom": "^18.0.0 || ^19.0.0"
14
14
  },
15
15
  "dependencies": {
16
- "@akinon/theme-contract": "2.0.119-rc.0",
16
+ "@akinon/theme-contract": "2.0.120-beta.0",
17
17
  "clsx": "2.1.1",
18
18
  "lottie-web": "^5.13.0",
19
19
  "react-multi-carousel": "2.8.4",
@@ -21,7 +21,7 @@
21
21
  "zod": "4.4.1"
22
22
  },
23
23
  "devDependencies": {
24
- "@akinon/next": "2.0.119-rc.0",
24
+ "@akinon/next": "2.0.120-beta.0",
25
25
  "@testing-library/jest-dom": "5.16.4",
26
26
  "@testing-library/react": "16.3.2",
27
27
  "@testing-library/user-event": "14.1.1",
@@ -4,11 +4,13 @@ import { fireEvent, render } from '@testing-library/react';
4
4
  // react-multi-carousel is an ESM/DOM-heavy dependency. Replace its default
5
5
  // export with a passthrough that simply renders its children so we can assert
6
6
  // on the slides the SliderBlock produces.
7
+ const mockCarouselProps: Record<string, any>[] = [];
7
8
  jest.mock('react-multi-carousel', () => ({
8
9
  __esModule: true,
9
- default: ({ children }: { children: React.ReactNode }) => (
10
- <div data-testid="carousel">{children}</div>
11
- )
10
+ default: (carouselProps: any) => {
11
+ mockCarouselProps.push(carouselProps);
12
+ return <div data-testid="carousel">{carouselProps.children}</div>;
13
+ }
12
14
  }));
13
15
 
14
16
  // Stub the recursive ThemeBlock (default export) with a countable marker so we
@@ -53,6 +55,9 @@ const props = (over: Record<string, unknown> = {}) =>
53
55
  ...over
54
56
  } as any);
55
57
 
58
+ /** The props the carousel was handed by the most recent render. */
59
+ const lastCarouselProps = () => mockCarouselProps[mockCarouselProps.length - 1];
60
+
56
61
  const markers = (container: HTMLElement) =>
57
62
  Array.from(container.querySelectorAll('[data-testid="tb"]')).map((el) =>
58
63
  el.getAttribute('data-id')
@@ -629,3 +634,56 @@ describe('SliderBlock — arrow rotate and reveal-on-hover', () => {
629
634
  expect(buttons(container)[0].style.transition).toBe('');
630
635
  });
631
636
  });
637
+
638
+
639
+ describe('SliderBlock — autoplay speed', () => {
640
+ beforeEach(() => {
641
+ mockCarouselProps.length = 0;
642
+ });
643
+
644
+ const renderWithSpeed = (speed: unknown, currentBreakpoint = 'desktop') =>
645
+ render(
646
+ <SliderBlock
647
+ {...props({
648
+ currentBreakpoint,
649
+ block: {
650
+ ...props().block,
651
+ properties: { autoplay: true, 'autoplay-speed': speed },
652
+ blocks: [child('a'), child('b')]
653
+ }
654
+ })}
655
+ />
656
+ );
657
+
658
+ it('honours a speed the editor stored per breakpoint', () => {
659
+ // THE DEFECT. Every sibling entry is read through the breakpoint, this one
660
+ // was read raw — and the editor writes `{ desktop: '15000' }` for all of
661
+ // them. `Number({...})` is NaN, so the parse fell through to its own 3000
662
+ // and a merchant who typed 15000 got a slider that still turned every three
663
+ // seconds, with the value they typed still sitting in the panel.
664
+ renderWithSpeed({ desktop: '15000' });
665
+ expect(lastCarouselProps().autoPlaySpeed).toBe(15000);
666
+ });
667
+
668
+ it('gives a phone the phone value when the two differ', () => {
669
+ renderWithSpeed({ desktop: '15000', mobile: '4000' }, 'mobile');
670
+ expect(lastCarouselProps().autoPlaySpeed).toBe(4000);
671
+ });
672
+
673
+ it('falls through to the desktop value on a breakpoint that authored none', () => {
674
+ // The live composition stores the key under `desktop` only, so a phone has
675
+ // to inherit it rather than drop to the default.
676
+ renderWithSpeed({ desktop: '15000' }, 'mobile');
677
+ expect(lastCarouselProps().autoPlaySpeed).toBe(15000);
678
+ });
679
+
680
+ it('keeps reading the plain number older compositions hold', () => {
681
+ renderWithSpeed(3000);
682
+ expect(lastCarouselProps().autoPlaySpeed).toBe(3000);
683
+ });
684
+
685
+ it('defaults to 3000 when nothing was authored', () => {
686
+ renderWithSpeed(undefined);
687
+ expect(lastCarouselProps().autoPlaySpeed).toBe(3000);
688
+ });
689
+ });
@@ -234,7 +234,21 @@ const SliderBlock: React.FC<BlockRendererProps> = ({
234
234
 
235
235
  const useInfinite = useAutoPlay;
236
236
 
237
- const autoPlaySpeedRaw = getConfigEntry('autoplay-speed');
237
+ /*
238
+ * Read through the breakpoint like every other entry above it.
239
+ *
240
+ * This one was asked for raw, and the editor stores it the same way it
241
+ * stores the rest — `{ desktop: '15000' }`. `Number({...})` is `NaN`, so
242
+ * `parseNumber` fell through to its own fallback and every slider ran at
243
+ * 3000ms whatever the merchant typed. The value was written, saved and shown
244
+ * back in the panel, which is why it looked like the control simply did
245
+ * nothing.
246
+ */
247
+ const autoPlaySpeedRaw = getResponsiveValue(
248
+ getConfigEntry('autoplay-speed'),
249
+ currentBreakpoint,
250
+ 3000
251
+ );
238
252
  const autoPlaySpeed = parseNumber(autoPlaySpeedRaw, 3000);
239
253
 
240
254
  const slideGap = parseNumber(getConfigEntry('slide-gap'), 16);