@pradip1995/segment-beauty-category-tiles 0.1.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/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@pradip1995/segment-beauty-category-tiles",
3
+ "version": "0.1.0",
4
+ "license": "MIT",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "sideEffects": [
9
+ "src/segment.css"
10
+ ],
11
+ "files": [
12
+ "src"
13
+ ],
14
+ "exports": {
15
+ ".": "./src/index.ts",
16
+ "./manifest": "./src/manifest.ts"
17
+ },
18
+ "peerDependencies": {
19
+ "@pradip1995/plugin-sdk": "^0.2.0",
20
+ "react": ">=19",
21
+ "react-dom": ">=19",
22
+ "next": ">=15"
23
+ },
24
+ "dependencies": {
25
+ "@pradip1995/segment-primitives": "0.3.0",
26
+ "@pradip1995/segment-tokens": "0.3.2"
27
+ },
28
+ "devDependencies": {
29
+ "@pradip1995/plugin-sdk": "^0.2.0",
30
+ "@types/react": "^19",
31
+ "react": "19.0.3",
32
+ "typescript": "^5.7.2"
33
+ },
34
+ "scripts": {
35
+ "typecheck": "tsc --noEmit",
36
+ "lint": "tsc --noEmit"
37
+ }
38
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { default } from "./segment"
2
+ export { default as manifest } from "./manifest"
@@ -0,0 +1,10 @@
1
+ import type { SegmentManifest } from "@pradip1995/plugin-sdk"
2
+
3
+ const manifest: SegmentManifest = {
4
+ id: "beauty-category-tiles",
5
+ type: "segment",
6
+ version: "0.1.0",
7
+ compatibleFramework: ["^1.0.0"],
8
+ }
9
+
10
+ export default manifest
@@ -0,0 +1,119 @@
1
+ .beauty-categories {
2
+ width: 100%;
3
+ padding: 2.5rem 0 3rem;
4
+ background: var(--color-page-bg);
5
+ }
6
+
7
+ .beauty-categories__inner {
8
+ max-width: var(--container-max);
9
+ margin: 0 auto;
10
+ padding: 0 1rem;
11
+ }
12
+
13
+ .beauty-categories__header {
14
+ text-align: center;
15
+ margin-bottom: 2rem;
16
+ }
17
+
18
+ .beauty-categories__eyebrow {
19
+ margin: 0 0 0.5rem;
20
+ font-size: 0.75rem;
21
+ font-weight: 600;
22
+ letter-spacing: 0.2em;
23
+ text-transform: uppercase;
24
+ color: var(--color-brand-accent);
25
+ }
26
+
27
+ .beauty-categories__title {
28
+ margin: 0;
29
+ font-family: var(--font-heading);
30
+ font-size: clamp(1.75rem, 3vw, 2.5rem);
31
+ font-weight: 500;
32
+ letter-spacing: 0.04em;
33
+ color: var(--color-text-heading);
34
+ }
35
+
36
+ .beauty-categories__featured {
37
+ display: grid;
38
+ grid-template-columns: 1fr;
39
+ gap: 1rem;
40
+ margin-bottom: 1rem;
41
+ }
42
+
43
+ @media (min-width: 768px) {
44
+ .beauty-categories__featured {
45
+ grid-template-columns: repeat(2, minmax(0, 1fr));
46
+ gap: 1.25rem;
47
+ }
48
+ }
49
+
50
+ .beauty-categories__grid {
51
+ display: grid;
52
+ grid-template-columns: repeat(2, minmax(0, 1fr));
53
+ gap: 1rem;
54
+ }
55
+
56
+ @media (min-width: 768px) {
57
+ .beauty-categories__grid {
58
+ grid-template-columns: repeat(4, minmax(0, 1fr));
59
+ gap: 1.25rem;
60
+ }
61
+ }
62
+
63
+ .beauty-categories__tile {
64
+ position: relative;
65
+ display: block;
66
+ overflow: hidden;
67
+ text-decoration: none;
68
+ border-radius: 0;
69
+ background: var(--color-surface-muted);
70
+ }
71
+
72
+ .beauty-categories__tile--large {
73
+ aspect-ratio: 16 / 10;
74
+ }
75
+
76
+ .beauty-categories__tile--small {
77
+ aspect-ratio: 4 / 5;
78
+ }
79
+
80
+ .beauty-categories__image {
81
+ transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
82
+ }
83
+
84
+ .beauty-categories__overlay {
85
+ position: absolute;
86
+ inset: 0;
87
+ background: linear-gradient(
88
+ to top,
89
+ rgba(0, 0, 0, 0.55) 0%,
90
+ rgba(0, 0, 0, 0.08) 55%,
91
+ transparent 100%
92
+ );
93
+ transition: opacity 0.3s ease;
94
+ }
95
+
96
+ .beauty-categories__label {
97
+ position: absolute;
98
+ left: 1.25rem;
99
+ right: 1.25rem;
100
+ bottom: 1.25rem;
101
+ z-index: 1;
102
+ font-size: 0.875rem;
103
+ font-weight: 600;
104
+ letter-spacing: 0.18em;
105
+ text-transform: uppercase;
106
+ color: #ffffff;
107
+ }
108
+
109
+ .beauty-categories__tile--large .beauty-categories__label {
110
+ font-size: 1.125rem;
111
+ }
112
+
113
+ .beauty-categories__tile:hover .beauty-categories__image {
114
+ transform: scale(1.05);
115
+ }
116
+
117
+ .beauty-categories__tile:hover .beauty-categories__overlay {
118
+ opacity: 0.92;
119
+ }
@@ -0,0 +1,83 @@
1
+ import "./segment.css"
2
+ import Image from "next/image"
3
+ import LocalizedLink from "@pradip1995/segment-primitives/localized-link"
4
+
5
+ type BeautyCategory = {
6
+ title: string
7
+ image?: string
8
+ href: string
9
+ size?: "large" | "small"
10
+ }
11
+
12
+ export default function BeautyCategoryTiles({
13
+ categories = [],
14
+ title = "Shop by category",
15
+ eyebrow = "Discover",
16
+ }: {
17
+ categories?: BeautyCategory[]
18
+ title?: string
19
+ eyebrow?: string
20
+ }) {
21
+ const items = categories.filter((item) => item.title?.trim() && item.href?.trim())
22
+ if (items.length === 0) return null
23
+
24
+ const largeTiles = items.filter((item) => item.size !== "small")
25
+ const smallTiles = items.filter((item) => item.size === "small")
26
+
27
+ return (
28
+ <section className="beauty-categories" aria-labelledby="beauty-categories-title">
29
+ <div className="beauty-categories__inner">
30
+ <header className="beauty-categories__header">
31
+ {eyebrow ? <p className="beauty-categories__eyebrow">{eyebrow}</p> : null}
32
+ <h2 id="beauty-categories-title" className="beauty-categories__title">
33
+ {title}
34
+ </h2>
35
+ </header>
36
+
37
+ {largeTiles.length > 0 ? (
38
+ <div className="beauty-categories__featured">
39
+ {largeTiles.map((category) => (
40
+ <CategoryTile key={category.title} category={category} size="large" />
41
+ ))}
42
+ </div>
43
+ ) : null}
44
+
45
+ {smallTiles.length > 0 ? (
46
+ <div className="beauty-categories__grid">
47
+ {smallTiles.map((category) => (
48
+ <CategoryTile key={category.title} category={category} size="small" />
49
+ ))}
50
+ </div>
51
+ ) : null}
52
+ </div>
53
+ </section>
54
+ )
55
+ }
56
+
57
+ function CategoryTile({
58
+ category,
59
+ size,
60
+ }: {
61
+ category: BeautyCategory
62
+ size: "large" | "small"
63
+ }) {
64
+ const imageSrc = category.image?.trim() || "/theme-defaults/cosmetics/makeup.svg"
65
+
66
+ return (
67
+ <LocalizedLink
68
+ href={category.href}
69
+ className={`beauty-categories__tile beauty-categories__tile--${size}`}
70
+ >
71
+ <Image
72
+ src={imageSrc}
73
+ alt=""
74
+ fill
75
+ className="beauty-categories__image object-cover"
76
+ sizes={size === "large" ? "(max-width: 768px) 100vw, 50vw" : "(max-width: 768px) 50vw, 25vw"}
77
+ unoptimized
78
+ />
79
+ <div className="beauty-categories__overlay" aria-hidden />
80
+ <span className="beauty-categories__label">{category.title}</span>
81
+ </LocalizedLink>
82
+ )
83
+ }