@orangecheck/app-design 0.4.0 → 0.4.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/dist/components.d.mts +2 -1
- package/dist/components.d.ts +2 -1
- package/dist/components.js +139 -146
- package/dist/components.js.map +1 -1
- package/dist/components.mjs +140 -147
- package/dist/components.mjs.map +1 -1
- package/dist/index.js +139 -146
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +139 -146
- package/dist/index.mjs.map +1 -1
- package/dist/styles/motion.css +21 -0
- package/package.json +1 -1
package/dist/components.d.mts
CHANGED
|
@@ -310,8 +310,9 @@ interface SectionProps extends HTMLAttributes<HTMLElement>, VariantProps<typeof
|
|
|
310
310
|
}
|
|
311
311
|
declare function Section({ tone, space, contained, className, children, ...props }: SectionProps): react.JSX.Element;
|
|
312
312
|
declare function Container({ className, ...props }: HTMLAttributes<HTMLDivElement>): react.JSX.Element;
|
|
313
|
-
declare function SectionIntro({ className, align,
|
|
313
|
+
declare function SectionIntro({ className, align, reveal, children, style, }: Pick<HTMLAttributes<HTMLDivElement>, 'className' | 'style' | 'children'> & {
|
|
314
314
|
align?: 'start' | 'center';
|
|
315
|
+
reveal?: boolean;
|
|
315
316
|
}): react.JSX.Element;
|
|
316
317
|
|
|
317
318
|
interface PageHeroProps {
|
package/dist/components.d.ts
CHANGED
|
@@ -310,8 +310,9 @@ interface SectionProps extends HTMLAttributes<HTMLElement>, VariantProps<typeof
|
|
|
310
310
|
}
|
|
311
311
|
declare function Section({ tone, space, contained, className, children, ...props }: SectionProps): react.JSX.Element;
|
|
312
312
|
declare function Container({ className, ...props }: HTMLAttributes<HTMLDivElement>): react.JSX.Element;
|
|
313
|
-
declare function SectionIntro({ className, align,
|
|
313
|
+
declare function SectionIntro({ className, align, reveal, children, style, }: Pick<HTMLAttributes<HTMLDivElement>, 'className' | 'style' | 'children'> & {
|
|
314
314
|
align?: 'start' | 'center';
|
|
315
|
+
reveal?: boolean;
|
|
315
316
|
}): react.JSX.Element;
|
|
316
317
|
|
|
317
318
|
interface PageHeroProps {
|
package/dist/components.js
CHANGED
|
@@ -83,6 +83,131 @@ function Prose({ className, ...props }) {
|
|
|
83
83
|
}
|
|
84
84
|
);
|
|
85
85
|
}
|
|
86
|
+
function prefersStill() {
|
|
87
|
+
return typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
88
|
+
}
|
|
89
|
+
function useInView(rootMargin = "0px 0px -12% 0px") {
|
|
90
|
+
const ref = react.useRef(null);
|
|
91
|
+
const [seen, setSeen] = react.useState(false);
|
|
92
|
+
react.useEffect(() => {
|
|
93
|
+
const el = ref.current;
|
|
94
|
+
if (!el || seen) return;
|
|
95
|
+
if (typeof IntersectionObserver === "undefined") {
|
|
96
|
+
setSeen(true);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const io = new IntersectionObserver(
|
|
100
|
+
([e]) => {
|
|
101
|
+
if (e?.isIntersecting) {
|
|
102
|
+
setSeen(true);
|
|
103
|
+
io.disconnect();
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
{ rootMargin }
|
|
107
|
+
);
|
|
108
|
+
io.observe(el);
|
|
109
|
+
return () => io.disconnect();
|
|
110
|
+
}, [rootMargin, seen]);
|
|
111
|
+
return [ref, seen];
|
|
112
|
+
}
|
|
113
|
+
function Reveal({
|
|
114
|
+
as = "div",
|
|
115
|
+
delay = 0,
|
|
116
|
+
className,
|
|
117
|
+
style,
|
|
118
|
+
children
|
|
119
|
+
}) {
|
|
120
|
+
const ref = react.useRef(null);
|
|
121
|
+
react.useEffect(() => {
|
|
122
|
+
const el = ref.current;
|
|
123
|
+
if (!el || prefersStill() || typeof IntersectionObserver === "undefined") return;
|
|
124
|
+
if (el.getBoundingClientRect().top < window.innerHeight * 0.92) return;
|
|
125
|
+
el.dataset.reveal = "pending";
|
|
126
|
+
const io = new IntersectionObserver(
|
|
127
|
+
([e]) => {
|
|
128
|
+
if (e?.isIntersecting) {
|
|
129
|
+
el.dataset.reveal = "shown";
|
|
130
|
+
io.disconnect();
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
{ rootMargin: "0px 0px -10% 0px" }
|
|
134
|
+
);
|
|
135
|
+
io.observe(el);
|
|
136
|
+
return () => io.disconnect();
|
|
137
|
+
}, []);
|
|
138
|
+
return react.createElement(
|
|
139
|
+
as,
|
|
140
|
+
{ ref, className, style: { ...style, "--reveal-delay": `${delay}ms` } },
|
|
141
|
+
children
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
function ScrollStory({
|
|
145
|
+
length = 2,
|
|
146
|
+
className,
|
|
147
|
+
innerClassName,
|
|
148
|
+
children
|
|
149
|
+
}) {
|
|
150
|
+
const ref = react.useRef(null);
|
|
151
|
+
const [pinned, setPinned] = react.useState(false);
|
|
152
|
+
react.useEffect(() => {
|
|
153
|
+
const el = ref.current;
|
|
154
|
+
if (!el || prefersStill()) return;
|
|
155
|
+
setPinned(true);
|
|
156
|
+
let raf = 0;
|
|
157
|
+
const update = () => {
|
|
158
|
+
raf = 0;
|
|
159
|
+
const r = el.getBoundingClientRect();
|
|
160
|
+
const travel = r.height - window.innerHeight;
|
|
161
|
+
const p = travel > 0 ? Math.min(1, Math.max(0, -r.top / travel)) : 0;
|
|
162
|
+
el.style.setProperty("--p", p.toFixed(4));
|
|
163
|
+
};
|
|
164
|
+
const on = () => {
|
|
165
|
+
if (!raf) raf = requestAnimationFrame(update);
|
|
166
|
+
};
|
|
167
|
+
update();
|
|
168
|
+
window.addEventListener("scroll", on, { passive: true });
|
|
169
|
+
window.addEventListener("resize", on);
|
|
170
|
+
return () => {
|
|
171
|
+
cancelAnimationFrame(raf);
|
|
172
|
+
window.removeEventListener("scroll", on);
|
|
173
|
+
window.removeEventListener("resize", on);
|
|
174
|
+
};
|
|
175
|
+
}, []);
|
|
176
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("relative", className), style: pinned ? { height: `${length * 100}svh` } : void 0, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(pinned && "sticky top-0 flex min-h-svh items-center", innerClassName), children }) });
|
|
177
|
+
}
|
|
178
|
+
function Ticker({
|
|
179
|
+
value,
|
|
180
|
+
duration = 1200,
|
|
181
|
+
format = (n) => Math.round(n).toLocaleString("en-US"),
|
|
182
|
+
className
|
|
183
|
+
}) {
|
|
184
|
+
const [ref, seen] = useInView();
|
|
185
|
+
const [shown, setShown] = react.useState(value);
|
|
186
|
+
const animate = react.useRef(null);
|
|
187
|
+
react.useEffect(() => {
|
|
188
|
+
const el = ref.current;
|
|
189
|
+
if (!el || animate.current !== null) return;
|
|
190
|
+
animate.current = !prefersStill() && el.getBoundingClientRect().top > window.innerHeight * 0.9;
|
|
191
|
+
if (animate.current) setShown(0);
|
|
192
|
+
}, [ref]);
|
|
193
|
+
react.useEffect(() => {
|
|
194
|
+
if (!seen) return;
|
|
195
|
+
if (!animate.current) {
|
|
196
|
+
setShown(value);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
let raf = 0;
|
|
200
|
+
const t0 = performance.now();
|
|
201
|
+
const step = (now) => {
|
|
202
|
+
const k = Math.min(1, (now - t0) / duration);
|
|
203
|
+
setShown(value * (1 - Math.pow(1 - k, 3)));
|
|
204
|
+
if (k < 1) raf = requestAnimationFrame(step);
|
|
205
|
+
};
|
|
206
|
+
raf = requestAnimationFrame(step);
|
|
207
|
+
return () => cancelAnimationFrame(raf);
|
|
208
|
+
}, [seen, value, duration]);
|
|
209
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { ref, className: cn("oca-tabular", className), children: format(shown) });
|
|
210
|
+
}
|
|
86
211
|
var sectionVariants = classVarianceAuthority.cva("relative w-full overflow-x-clip", {
|
|
87
212
|
variants: {
|
|
88
213
|
tone: {
|
|
@@ -111,19 +236,12 @@ function Container({ className, ...props }) {
|
|
|
111
236
|
function SectionIntro({
|
|
112
237
|
className,
|
|
113
238
|
align = "start",
|
|
114
|
-
|
|
239
|
+
reveal = true,
|
|
240
|
+
children,
|
|
241
|
+
style
|
|
115
242
|
}) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
{
|
|
119
|
-
className: cn(
|
|
120
|
-
"flex flex-col gap-4 md:gap-5",
|
|
121
|
-
align === "center" && "mx-auto items-center text-center",
|
|
122
|
-
className
|
|
123
|
-
),
|
|
124
|
-
...props
|
|
125
|
-
}
|
|
126
|
-
);
|
|
243
|
+
const cls = cn("flex flex-col gap-4 md:gap-5", align === "center" && "mx-auto items-center text-center", className);
|
|
244
|
+
return reveal ? /* @__PURE__ */ jsxRuntime.jsx(Reveal, { className: cls, style, children }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cls, style, children });
|
|
127
245
|
}
|
|
128
246
|
function PageHero({
|
|
129
247
|
eyebrow,
|
|
@@ -142,14 +260,14 @@ function PageHero({
|
|
|
142
260
|
}
|
|
143
261
|
return /* @__PURE__ */ jsxRuntime.jsx(Section, { space: "none", className: cn("pb-14 pt-12 md:pb-20 md:pt-20", className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("grid grid-cols-1 gap-10", art && "items-center md:grid-cols-12"), children: [
|
|
144
262
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col items-start gap-6", art ? "md:col-span-7" : "max-w-[52rem]"), children: [
|
|
145
|
-
eyebrow ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-eyebrow", children: eyebrow }) : null,
|
|
146
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: size === "xl" ? "oca-display-1" : "oca-display-2", children: title }),
|
|
147
|
-
lead ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-lead max-w-[38rem]", children: lead }) : null,
|
|
148
|
-
meta ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] text-muted-foreground", children: meta }) : null,
|
|
149
|
-
actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-3", children: actions }) : null,
|
|
150
|
-
children
|
|
263
|
+
eyebrow ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-eyebrow oca-enter", children: eyebrow }) : null,
|
|
264
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: cn(size === "xl" ? "oca-display-1" : "oca-display-2", "oca-enter [--enter-delay:70ms]"), children: title }),
|
|
265
|
+
lead ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-lead oca-enter max-w-[38rem] [--enter-delay:150ms]", children: lead }) : null,
|
|
266
|
+
meta ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-enter text-[0.875rem] text-muted-foreground [--enter-delay:190ms]", children: meta }) : null,
|
|
267
|
+
actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oca-enter flex flex-wrap gap-3 [--enter-delay:230ms]", children: actions }) : null,
|
|
268
|
+
children ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oca-enter w-full [--enter-delay:270ms]", children }) : null
|
|
151
269
|
] }),
|
|
152
|
-
art ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "md:col-span-5", children: art }) : null
|
|
270
|
+
art ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "oca-enter md:col-span-5 [--enter-delay:120ms]", children: art }) : null
|
|
153
271
|
] }) });
|
|
154
272
|
}
|
|
155
273
|
function DocHeader({
|
|
@@ -162,8 +280,8 @@ function DocHeader({
|
|
|
162
280
|
className
|
|
163
281
|
}) {
|
|
164
282
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-col gap-5", className), children: [
|
|
165
|
-
eyebrow ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-eyebrow", children: eyebrow }) : null,
|
|
166
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "oca-display-2", children: title }),
|
|
283
|
+
eyebrow ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-eyebrow oca-enter", children: eyebrow }) : null,
|
|
284
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "oca-display-2 oca-enter [--enter-delay:70ms]", children: title }),
|
|
167
285
|
lead ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "oca-lead", children: lead }) : null,
|
|
168
286
|
meta ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[0.875rem] text-muted-foreground", children: meta }) : null,
|
|
169
287
|
actions ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-1 flex flex-wrap gap-3", children: actions }) : null,
|
|
@@ -1118,131 +1236,6 @@ function SatsFigure({
|
|
|
1118
1236
|
hint ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[0.875rem] text-muted-foreground", children: hint }) : null
|
|
1119
1237
|
] });
|
|
1120
1238
|
}
|
|
1121
|
-
function prefersStill() {
|
|
1122
|
-
return typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1123
|
-
}
|
|
1124
|
-
function useInView(rootMargin = "0px 0px -12% 0px") {
|
|
1125
|
-
const ref = react.useRef(null);
|
|
1126
|
-
const [seen, setSeen] = react.useState(false);
|
|
1127
|
-
react.useEffect(() => {
|
|
1128
|
-
const el = ref.current;
|
|
1129
|
-
if (!el || seen) return;
|
|
1130
|
-
if (typeof IntersectionObserver === "undefined") {
|
|
1131
|
-
setSeen(true);
|
|
1132
|
-
return;
|
|
1133
|
-
}
|
|
1134
|
-
const io = new IntersectionObserver(
|
|
1135
|
-
([e]) => {
|
|
1136
|
-
if (e?.isIntersecting) {
|
|
1137
|
-
setSeen(true);
|
|
1138
|
-
io.disconnect();
|
|
1139
|
-
}
|
|
1140
|
-
},
|
|
1141
|
-
{ rootMargin }
|
|
1142
|
-
);
|
|
1143
|
-
io.observe(el);
|
|
1144
|
-
return () => io.disconnect();
|
|
1145
|
-
}, [rootMargin, seen]);
|
|
1146
|
-
return [ref, seen];
|
|
1147
|
-
}
|
|
1148
|
-
function Reveal({
|
|
1149
|
-
as = "div",
|
|
1150
|
-
delay = 0,
|
|
1151
|
-
className,
|
|
1152
|
-
style,
|
|
1153
|
-
children
|
|
1154
|
-
}) {
|
|
1155
|
-
const ref = react.useRef(null);
|
|
1156
|
-
react.useEffect(() => {
|
|
1157
|
-
const el = ref.current;
|
|
1158
|
-
if (!el || prefersStill() || typeof IntersectionObserver === "undefined") return;
|
|
1159
|
-
if (el.getBoundingClientRect().top < window.innerHeight * 0.92) return;
|
|
1160
|
-
el.dataset.reveal = "pending";
|
|
1161
|
-
const io = new IntersectionObserver(
|
|
1162
|
-
([e]) => {
|
|
1163
|
-
if (e?.isIntersecting) {
|
|
1164
|
-
el.dataset.reveal = "shown";
|
|
1165
|
-
io.disconnect();
|
|
1166
|
-
}
|
|
1167
|
-
},
|
|
1168
|
-
{ rootMargin: "0px 0px -10% 0px" }
|
|
1169
|
-
);
|
|
1170
|
-
io.observe(el);
|
|
1171
|
-
return () => io.disconnect();
|
|
1172
|
-
}, []);
|
|
1173
|
-
return react.createElement(
|
|
1174
|
-
as,
|
|
1175
|
-
{ ref, className, style: { ...style, "--reveal-delay": `${delay}ms` } },
|
|
1176
|
-
children
|
|
1177
|
-
);
|
|
1178
|
-
}
|
|
1179
|
-
function ScrollStory({
|
|
1180
|
-
length = 2,
|
|
1181
|
-
className,
|
|
1182
|
-
innerClassName,
|
|
1183
|
-
children
|
|
1184
|
-
}) {
|
|
1185
|
-
const ref = react.useRef(null);
|
|
1186
|
-
const [pinned, setPinned] = react.useState(false);
|
|
1187
|
-
react.useEffect(() => {
|
|
1188
|
-
const el = ref.current;
|
|
1189
|
-
if (!el || prefersStill()) return;
|
|
1190
|
-
setPinned(true);
|
|
1191
|
-
let raf = 0;
|
|
1192
|
-
const update = () => {
|
|
1193
|
-
raf = 0;
|
|
1194
|
-
const r = el.getBoundingClientRect();
|
|
1195
|
-
const travel = r.height - window.innerHeight;
|
|
1196
|
-
const p = travel > 0 ? Math.min(1, Math.max(0, -r.top / travel)) : 0;
|
|
1197
|
-
el.style.setProperty("--p", p.toFixed(4));
|
|
1198
|
-
};
|
|
1199
|
-
const on = () => {
|
|
1200
|
-
if (!raf) raf = requestAnimationFrame(update);
|
|
1201
|
-
};
|
|
1202
|
-
update();
|
|
1203
|
-
window.addEventListener("scroll", on, { passive: true });
|
|
1204
|
-
window.addEventListener("resize", on);
|
|
1205
|
-
return () => {
|
|
1206
|
-
cancelAnimationFrame(raf);
|
|
1207
|
-
window.removeEventListener("scroll", on);
|
|
1208
|
-
window.removeEventListener("resize", on);
|
|
1209
|
-
};
|
|
1210
|
-
}, []);
|
|
1211
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cn("relative", className), style: pinned ? { height: `${length * 100}svh` } : void 0, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(pinned && "sticky top-0 flex min-h-svh items-center", innerClassName), children }) });
|
|
1212
|
-
}
|
|
1213
|
-
function Ticker({
|
|
1214
|
-
value,
|
|
1215
|
-
duration = 1200,
|
|
1216
|
-
format = (n) => Math.round(n).toLocaleString("en-US"),
|
|
1217
|
-
className
|
|
1218
|
-
}) {
|
|
1219
|
-
const [ref, seen] = useInView();
|
|
1220
|
-
const [shown, setShown] = react.useState(value);
|
|
1221
|
-
const animate = react.useRef(null);
|
|
1222
|
-
react.useEffect(() => {
|
|
1223
|
-
const el = ref.current;
|
|
1224
|
-
if (!el || animate.current !== null) return;
|
|
1225
|
-
animate.current = !prefersStill() && el.getBoundingClientRect().top > window.innerHeight * 0.9;
|
|
1226
|
-
if (animate.current) setShown(0);
|
|
1227
|
-
}, [ref]);
|
|
1228
|
-
react.useEffect(() => {
|
|
1229
|
-
if (!seen) return;
|
|
1230
|
-
if (!animate.current) {
|
|
1231
|
-
setShown(value);
|
|
1232
|
-
return;
|
|
1233
|
-
}
|
|
1234
|
-
let raf = 0;
|
|
1235
|
-
const t0 = performance.now();
|
|
1236
|
-
const step = (now) => {
|
|
1237
|
-
const k = Math.min(1, (now - t0) / duration);
|
|
1238
|
-
setShown(value * (1 - Math.pow(1 - k, 3)));
|
|
1239
|
-
if (k < 1) raf = requestAnimationFrame(step);
|
|
1240
|
-
};
|
|
1241
|
-
raf = requestAnimationFrame(step);
|
|
1242
|
-
return () => cancelAnimationFrame(raf);
|
|
1243
|
-
}, [seen, value, duration]);
|
|
1244
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { ref, className: cn("oca-tabular", className), children: format(shown) });
|
|
1245
|
-
}
|
|
1246
1239
|
function PhoneFrame({ className, style, children }) {
|
|
1247
1240
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1248
1241
|
"div",
|