@vrugd/ui 0.1.6 → 0.1.8
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/index.d.ts +25 -1
- package/dist/index.js +98 -0
- package/package.json +1 -1
- package/src/components/Heading.tsx +52 -0
- package/src/components/Reveal.tsx +84 -0
- package/src/index.ts +2 -0
package/dist/index.d.ts
CHANGED
|
@@ -56,4 +56,28 @@ type SectionProps = React.HTMLAttributes<HTMLElement> & {
|
|
|
56
56
|
};
|
|
57
57
|
declare function Section({ size, className, children, ...props }: SectionProps): React.JSX.Element;
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
type RevealVariant = "fade" | "up" | "down" | "scale";
|
|
60
|
+
type RevealProps = {
|
|
61
|
+
as?: keyof React.JSX.IntrinsicElements;
|
|
62
|
+
variant?: RevealVariant;
|
|
63
|
+
delayMs?: number;
|
|
64
|
+
once?: boolean;
|
|
65
|
+
className?: string;
|
|
66
|
+
children: React.ReactNode;
|
|
67
|
+
};
|
|
68
|
+
declare function Reveal({ as, variant, delayMs, once, className, children, }: RevealProps): React.JSX.Element;
|
|
69
|
+
|
|
70
|
+
type HeadingAs = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
|
71
|
+
type HeadingSize = "display" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
|
72
|
+
type HeadingTone = "default" | "muted";
|
|
73
|
+
type HeadingProps = {
|
|
74
|
+
as?: HeadingAs;
|
|
75
|
+
size?: HeadingSize;
|
|
76
|
+
tone?: HeadingTone;
|
|
77
|
+
balance?: boolean;
|
|
78
|
+
className?: string;
|
|
79
|
+
children: React.ReactNode;
|
|
80
|
+
};
|
|
81
|
+
declare function Heading({ as, size, tone, balance, className, children, }: HeadingProps): React.JSX.Element;
|
|
82
|
+
|
|
83
|
+
export { Button, type ButtonProps, Card, type CardProps, Container, type ContainerProps, Glass, type GlassProps, Heading, type HeadingProps, Hero, type HeroProps, type NavItem, Navbar, type NavbarProps, Reveal, type RevealProps, Section, type SectionProps, Text, type TextProps, cn };
|
package/dist/index.js
CHANGED
|
@@ -171,13 +171,111 @@ function Section({
|
|
|
171
171
|
}) {
|
|
172
172
|
return /* @__PURE__ */ jsx8("section", { className: cn(sizeMap2[size], className), ...props, children: /* @__PURE__ */ jsx8(Container, { size: "xl", children }) });
|
|
173
173
|
}
|
|
174
|
+
|
|
175
|
+
// src/components/Reveal.tsx
|
|
176
|
+
import * as React from "react";
|
|
177
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
178
|
+
function useInView(opts) {
|
|
179
|
+
const ref = React.useRef(null);
|
|
180
|
+
const [inView, setInView] = React.useState(false);
|
|
181
|
+
React.useEffect(() => {
|
|
182
|
+
const el = ref.current;
|
|
183
|
+
if (!el) return;
|
|
184
|
+
const io = new IntersectionObserver(
|
|
185
|
+
(entries) => {
|
|
186
|
+
const hit = entries.some((e) => e.isIntersecting);
|
|
187
|
+
if (hit) {
|
|
188
|
+
setInView(true);
|
|
189
|
+
if (opts.once) io.disconnect();
|
|
190
|
+
} else if (!opts.once) {
|
|
191
|
+
setInView(false);
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
root: opts.root ?? null,
|
|
196
|
+
rootMargin: opts.rootMargin ?? "0px",
|
|
197
|
+
threshold: opts.threshold ?? 0.15
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
io.observe(el);
|
|
201
|
+
return () => io.disconnect();
|
|
202
|
+
}, [opts.once, opts.root, opts.rootMargin, opts.threshold]);
|
|
203
|
+
return [ref, inView];
|
|
204
|
+
}
|
|
205
|
+
var variantClass = {
|
|
206
|
+
fade: { base: "uikit-reveal uikit-reveal--fade", shown: "uikit-reveal--shown" },
|
|
207
|
+
up: { base: "uikit-reveal uikit-reveal--up", shown: "uikit-reveal--shown" },
|
|
208
|
+
down: { base: "uikit-reveal uikit-reveal--down", shown: "uikit-reveal--shown" },
|
|
209
|
+
scale: { base: "uikit-reveal uikit-reveal--scale", shown: "uikit-reveal--shown" }
|
|
210
|
+
};
|
|
211
|
+
function Reveal({
|
|
212
|
+
as = "div",
|
|
213
|
+
variant = "up",
|
|
214
|
+
delayMs = 0,
|
|
215
|
+
once = true,
|
|
216
|
+
className,
|
|
217
|
+
children
|
|
218
|
+
}) {
|
|
219
|
+
const [ref, inView] = useInView({ once, threshold: 0.18 });
|
|
220
|
+
const Tag = as;
|
|
221
|
+
return /* @__PURE__ */ jsx9(
|
|
222
|
+
Tag,
|
|
223
|
+
{
|
|
224
|
+
ref,
|
|
225
|
+
className: cn(
|
|
226
|
+
variantClass[variant].base,
|
|
227
|
+
inView && variantClass[variant].shown,
|
|
228
|
+
className
|
|
229
|
+
),
|
|
230
|
+
style: { ["--uikit-delay"]: `${Math.max(0, delayMs)}ms` },
|
|
231
|
+
children
|
|
232
|
+
}
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// src/components/Heading.tsx
|
|
237
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
238
|
+
var sizeClass = {
|
|
239
|
+
display: "text-[44px] leading-[1.06] sm:text-[64px] font-[780] tracking-[-0.03em]",
|
|
240
|
+
h1: "text-[36px] leading-[1.08] sm:text-[48px] font-[760] tracking-[-0.02em]",
|
|
241
|
+
h2: "text-[28px] leading-[1.12] sm:text-[36px] font-[740] tracking-[-0.02em]",
|
|
242
|
+
h3: "text-[22px] leading-[1.2] sm:text-[28px] font-[720] tracking-[-0.01em]",
|
|
243
|
+
h4: "text-[18px] leading-[1.25] sm:text-[22px] font-[700]",
|
|
244
|
+
h5: "text-[16px] leading-[1.35] font-[700]",
|
|
245
|
+
h6: "text-[14px] leading-[1.35] font-[700] uppercase tracking-[0.12em]"
|
|
246
|
+
};
|
|
247
|
+
function Heading({
|
|
248
|
+
as,
|
|
249
|
+
size = "h2",
|
|
250
|
+
tone = "default",
|
|
251
|
+
balance = true,
|
|
252
|
+
className,
|
|
253
|
+
children
|
|
254
|
+
}) {
|
|
255
|
+
const Tag = as ?? (size === "display" ? "h1" : size);
|
|
256
|
+
return /* @__PURE__ */ jsx10(
|
|
257
|
+
Tag,
|
|
258
|
+
{
|
|
259
|
+
className: cn(
|
|
260
|
+
"text-[rgb(var(--fg))]",
|
|
261
|
+
tone === "muted" && "text-[rgb(var(--muted))]",
|
|
262
|
+
balance && "uikit-balance",
|
|
263
|
+
sizeClass[size],
|
|
264
|
+
className
|
|
265
|
+
),
|
|
266
|
+
children
|
|
267
|
+
}
|
|
268
|
+
);
|
|
269
|
+
}
|
|
174
270
|
export {
|
|
175
271
|
Button,
|
|
176
272
|
Card,
|
|
177
273
|
Container,
|
|
178
274
|
Glass,
|
|
275
|
+
Heading,
|
|
179
276
|
Hero,
|
|
180
277
|
Navbar,
|
|
278
|
+
Reveal,
|
|
181
279
|
Section,
|
|
182
280
|
Text,
|
|
183
281
|
cn
|
package/package.json
CHANGED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../utils/cn";
|
|
4
|
+
|
|
5
|
+
type HeadingAs = "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
|
6
|
+
type HeadingSize = "display" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
|
7
|
+
type HeadingTone = "default" | "muted";
|
|
8
|
+
|
|
9
|
+
export type HeadingProps = {
|
|
10
|
+
as?: HeadingAs;
|
|
11
|
+
size?: HeadingSize;
|
|
12
|
+
tone?: HeadingTone;
|
|
13
|
+
balance?: boolean; // 見出しの折り返しを綺麗に(対応ブラウザで)
|
|
14
|
+
className?: string;
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const sizeClass: Record<HeadingSize, string> = {
|
|
19
|
+
display:
|
|
20
|
+
"text-[44px] leading-[1.06] sm:text-[64px] font-[780] tracking-[-0.03em]",
|
|
21
|
+
h1: "text-[36px] leading-[1.08] sm:text-[48px] font-[760] tracking-[-0.02em]",
|
|
22
|
+
h2: "text-[28px] leading-[1.12] sm:text-[36px] font-[740] tracking-[-0.02em]",
|
|
23
|
+
h3: "text-[22px] leading-[1.2] sm:text-[28px] font-[720] tracking-[-0.01em]",
|
|
24
|
+
h4: "text-[18px] leading-[1.25] sm:text-[22px] font-[700]",
|
|
25
|
+
h5: "text-[16px] leading-[1.35] font-[700]",
|
|
26
|
+
h6: "text-[14px] leading-[1.35] font-[700] uppercase tracking-[0.12em]",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export function Heading({
|
|
30
|
+
as,
|
|
31
|
+
size = "h2",
|
|
32
|
+
tone = "default",
|
|
33
|
+
balance = true,
|
|
34
|
+
className,
|
|
35
|
+
children,
|
|
36
|
+
}: HeadingProps): React.JSX.Element {
|
|
37
|
+
const Tag: HeadingAs = as ?? (size === "display" ? "h1" : size);
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<Tag
|
|
41
|
+
className={cn(
|
|
42
|
+
"text-[rgb(var(--fg))]",
|
|
43
|
+
tone === "muted" && "text-[rgb(var(--muted))]",
|
|
44
|
+
balance && "uikit-balance",
|
|
45
|
+
sizeClass[size],
|
|
46
|
+
className,
|
|
47
|
+
)}
|
|
48
|
+
>
|
|
49
|
+
{children}
|
|
50
|
+
</Tag>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../utils/cn";
|
|
6
|
+
|
|
7
|
+
type RevealVariant = "fade" | "up" | "down" | "scale";
|
|
8
|
+
|
|
9
|
+
export type RevealProps = {
|
|
10
|
+
as?: keyof React.JSX.IntrinsicElements;
|
|
11
|
+
variant?: RevealVariant;
|
|
12
|
+
delayMs?: number;
|
|
13
|
+
once?: boolean;
|
|
14
|
+
className?: string;
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
function useInView<T extends Element>(
|
|
19
|
+
opts: IntersectionObserverInit & { once: boolean },
|
|
20
|
+
): [React.RefObject<T | null>, boolean] {
|
|
21
|
+
const ref = React.useRef<T | null>(null);
|
|
22
|
+
const [inView, setInView] = React.useState(false);
|
|
23
|
+
|
|
24
|
+
React.useEffect(() => {
|
|
25
|
+
const el = ref.current;
|
|
26
|
+
if (!el) return;
|
|
27
|
+
|
|
28
|
+
const io = new IntersectionObserver(
|
|
29
|
+
(entries) => {
|
|
30
|
+
const hit = entries.some((e) => e.isIntersecting);
|
|
31
|
+
if (hit) {
|
|
32
|
+
setInView(true);
|
|
33
|
+
if (opts.once) io.disconnect();
|
|
34
|
+
} else if (!opts.once) {
|
|
35
|
+
setInView(false);
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
root: opts.root ?? null,
|
|
40
|
+
rootMargin: opts.rootMargin ?? "0px",
|
|
41
|
+
threshold: opts.threshold ?? 0.15,
|
|
42
|
+
},
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
io.observe(el);
|
|
46
|
+
return () => io.disconnect();
|
|
47
|
+
}, [opts.once, opts.root, opts.rootMargin, opts.threshold]);
|
|
48
|
+
|
|
49
|
+
return [ref, inView];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const variantClass: Record<RevealVariant, { base: string; shown: string }> = {
|
|
53
|
+
fade: { base: "uikit-reveal uikit-reveal--fade", shown: "uikit-reveal--shown" },
|
|
54
|
+
up: { base: "uikit-reveal uikit-reveal--up", shown: "uikit-reveal--shown" },
|
|
55
|
+
down: { base: "uikit-reveal uikit-reveal--down", shown: "uikit-reveal--shown" },
|
|
56
|
+
scale: { base: "uikit-reveal uikit-reveal--scale", shown: "uikit-reveal--shown" },
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export function Reveal({
|
|
60
|
+
as = "div",
|
|
61
|
+
variant = "up",
|
|
62
|
+
delayMs = 0,
|
|
63
|
+
once = true,
|
|
64
|
+
className,
|
|
65
|
+
children,
|
|
66
|
+
}: RevealProps): React.JSX.Element {
|
|
67
|
+
const [ref, inView] = useInView<HTMLElement>({ once, threshold: 0.18 });
|
|
68
|
+
|
|
69
|
+
const Tag = as as unknown as React.ElementType;
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<Tag
|
|
73
|
+
ref={ref}
|
|
74
|
+
className={cn(
|
|
75
|
+
variantClass[variant].base,
|
|
76
|
+
inView && variantClass[variant].shown,
|
|
77
|
+
className,
|
|
78
|
+
)}
|
|
79
|
+
style={{ ["--uikit-delay" as never]: `${Math.max(0, delayMs)}ms` } as React.CSSProperties}
|
|
80
|
+
>
|
|
81
|
+
{children}
|
|
82
|
+
</Tag>
|
|
83
|
+
);
|
|
84
|
+
}
|