react-raffle-picker 0.3.0 → 0.3.1

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/README.md CHANGED
@@ -15,11 +15,14 @@
15
15
  <a href="https://kirilinsky.github.io/react-raffle-picker/">
16
16
  <img src="https://img.shields.io/badge/storybook-live-ff4785?logo=storybook&logoColor=white" alt="Storybook" />
17
17
  </a>
18
- <a href="https://codecov.io/gh/kirilinsky/react-raffle-picker">
19
- <img src="https://codecov.io/gh/kirilinsky/react-raffle-picker/branch/main/graph/badge.svg" alt="Codecov coverage" />
18
+ <a href="https://app.codecov.io/gh/kirilinsky/react-raffle-picker">
19
+ <img src="https://img.shields.io/codecov/c/github/kirilinsky/react-raffle-picker?label=coverage" alt="Codecov coverage" />
20
20
  </a>
21
- <a href="https://bundlephobia.com/package/react-raffle-picker">
22
- <img src="https://img.shields.io/bundlephobia/minzip/react-raffle-picker?label=gzip" alt="Gzip bundle size" />
21
+ <a href="https://www.npmjs.com/package/react-raffle-picker">
22
+ <img src="https://img.shields.io/npm/v/react-raffle-picker" alt="npm version" />
23
+ </a>
24
+ <a href="https://www.npmjs.com/package/react-raffle-picker">
25
+ <img src="https://img.shields.io/npm/dm/react-raffle-picker" alt="npm downloads" />
23
26
  </a>
24
27
  </p>
25
28
  </div>
package/dist/index.cjs CHANGED
@@ -534,10 +534,14 @@ const SLOT_BASE_CSS = `
534
534
  .rrp-slot{display:inline-block;position:relative;overflow:hidden;vertical-align:baseline}
535
535
  .rrp-slot__col{position:absolute;top:0;left:0;right:0;height:300%;transform:translate3d(0,-33.3333%,0);animation:rrp-slot-reel var(--rrp-tick,80ms) linear infinite;will-change:transform}
536
536
  .rrp-slot__cell{height:33.3333%;display:grid;place-items:center;padding:0;margin:0;box-sizing:border-box;text-align:center}
537
- .rrp-slot[data-stopped] .rrp-slot__col{animation:none;transform:translate3d(0,-33.3333%,0)}
537
+ .rrp-slot[data-stopped] .rrp-slot__col{animation:rrp-slot-settle 320ms cubic-bezier(0.2,1.4,0.4,1) forwards}
538
538
  @keyframes rrp-slot-reel{from{transform:translate3d(0,-33.3333%,0)}to{transform:translate3d(0,-66.6666%,0)}}
539
+ @keyframes rrp-slot-settle{0%{transform:translate3d(0,-38%,0)}60%{transform:translate3d(0,-31%,0)}100%{transform:translate3d(0,-33.3333%,0)}}
540
+ @media (prefers-reduced-motion: reduce) {
541
+ .rrp-slot__col { animation: none !important; }
542
+ }
539
543
  `;
540
- const SLOT_STYLES_VERSION = "4";
544
+ const SLOT_STYLES_VERSION = "5";
541
545
  const injectSlotStyles = () => {
542
546
  if (typeof document === "undefined") return;
543
547
  const existing = document.querySelector("style[data-rrp-slot-base]");
package/dist/index.mjs CHANGED
@@ -533,10 +533,14 @@ const SLOT_BASE_CSS = `
533
533
  .rrp-slot{display:inline-block;position:relative;overflow:hidden;vertical-align:baseline}
534
534
  .rrp-slot__col{position:absolute;top:0;left:0;right:0;height:300%;transform:translate3d(0,-33.3333%,0);animation:rrp-slot-reel var(--rrp-tick,80ms) linear infinite;will-change:transform}
535
535
  .rrp-slot__cell{height:33.3333%;display:grid;place-items:center;padding:0;margin:0;box-sizing:border-box;text-align:center}
536
- .rrp-slot[data-stopped] .rrp-slot__col{animation:none;transform:translate3d(0,-33.3333%,0)}
536
+ .rrp-slot[data-stopped] .rrp-slot__col{animation:rrp-slot-settle 320ms cubic-bezier(0.2,1.4,0.4,1) forwards}
537
537
  @keyframes rrp-slot-reel{from{transform:translate3d(0,-33.3333%,0)}to{transform:translate3d(0,-66.6666%,0)}}
538
+ @keyframes rrp-slot-settle{0%{transform:translate3d(0,-38%,0)}60%{transform:translate3d(0,-31%,0)}100%{transform:translate3d(0,-33.3333%,0)}}
539
+ @media (prefers-reduced-motion: reduce) {
540
+ .rrp-slot__col { animation: none !important; }
541
+ }
538
542
  `;
539
- const SLOT_STYLES_VERSION = "4";
543
+ const SLOT_STYLES_VERSION = "5";
540
544
  const injectSlotStyles = () => {
541
545
  if (typeof document === "undefined") return;
542
546
  const existing = document.querySelector("style[data-rrp-slot-base]");
package/dist/styles.css CHANGED
@@ -27,9 +27,9 @@
27
27
  box-sizing: border-box;
28
28
  text-align: center;
29
29
  }
30
+ /* Stop = quick decelerate-and-settle bounce, not an instant snap. */
30
31
  .rrp-slot[data-stopped] .rrp-slot__col {
31
- animation: none;
32
- transform: translate3d(0, -33.3333%, 0);
32
+ animation: rrp-slot-settle 320ms cubic-bezier(0.2, 1.4, 0.4, 1) forwards;
33
33
  }
34
34
  @keyframes rrp-slot-reel {
35
35
  from {
@@ -39,16 +39,27 @@
39
39
  transform: translate3d(0, -66.6666%, 0);
40
40
  }
41
41
  }
42
+ @keyframes rrp-slot-settle {
43
+ 0% {
44
+ transform: translate3d(0, -38%, 0);
45
+ }
46
+ 60% {
47
+ transform: translate3d(0, -31%, 0);
48
+ }
49
+ 100% {
50
+ transform: translate3d(0, -33.3333%, 0);
51
+ }
52
+ }
42
53
 
43
54
  /* Value animations: opt-in via <RafflePick.Value animation="..." /> */
44
55
  .rrp-value {
45
56
  display: inline-block;
46
57
  }
47
58
  .rrp-value[data-animation='roll'][data-phase='running'] {
48
- animation: rrp-value-roll var(--rrp-tick, 100ms) linear;
59
+ animation: rrp-value-roll var(--rrp-tick, 100ms) cubic-bezier(0.22, 1, 0.36, 1);
49
60
  }
50
61
  .rrp-value[data-animation='fade'][data-phase='running'] {
51
- animation: rrp-value-fade var(--rrp-tick, 100ms) linear;
62
+ animation: rrp-value-fade var(--rrp-tick, 100ms) cubic-bezier(0.16, 1, 0.3, 1);
52
63
  }
53
64
  .rrp-value[data-animation='blur'][data-phase='running'] {
54
65
  animation: rrp-value-blur var(--rrp-tick, 100ms) linear;
@@ -56,21 +67,25 @@
56
67
  .rrp-value[data-animation='reel'][data-phase='running'] {
57
68
  animation: rrp-value-reel var(--rrp-tick, 100ms) linear;
58
69
  }
70
+ /* Freeze = one settle pop shared by every animation type — the "winner" beat. */
71
+ .rrp-value[data-animation][data-phase='frozen'] {
72
+ animation: rrp-value-settle 420ms cubic-bezier(0.2, 1.4, 0.4, 1);
73
+ }
59
74
  @keyframes rrp-value-roll {
60
- from {
75
+ 0% {
61
76
  transform: translateY(-0.4em);
62
- opacity: 0.4;
77
+ opacity: 0.45;
63
78
  }
64
- to {
79
+ 100% {
65
80
  transform: translateY(0);
66
81
  opacity: 1;
67
82
  }
68
83
  }
69
84
  @keyframes rrp-value-fade {
70
- from {
71
- opacity: 0.2;
85
+ 0% {
86
+ opacity: 0.25;
72
87
  }
73
- to {
88
+ 100% {
74
89
  opacity: 1;
75
90
  }
76
91
  }
@@ -92,13 +107,28 @@
92
107
  opacity: 1;
93
108
  }
94
109
  }
110
+ @keyframes rrp-value-settle {
111
+ 0% {
112
+ transform: scale(0.84);
113
+ opacity: 0.7;
114
+ }
115
+ 55% {
116
+ transform: scale(1.07);
117
+ opacity: 1;
118
+ }
119
+ 100% {
120
+ transform: scale(1);
121
+ }
122
+ }
95
123
 
96
- /* Respect vestibular disorders — kill all motion, keep instant value swaps. */
124
+ /* Respect vestibular disorders — kill all motion, keep instant value swaps.
125
+ !important: these must always win, regardless of the specificity of
126
+ whatever running/settle rule above (or added later) also matches. */
97
127
  @media (prefers-reduced-motion: reduce) {
98
128
  .rrp-slot__col {
99
- animation: none;
129
+ animation: none !important;
100
130
  }
101
131
  .rrp-value[data-animation] {
102
- animation: none;
132
+ animation: none !important;
103
133
  }
104
134
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-raffle-picker",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Headless React raffle picker for giveaways, winner draws, countdowns, and slot-machine UIs.",
5
5
  "type": "module",
6
6
  "publishConfig": {