@pradip1995/theme-impulse 1.1.4

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.
Files changed (47) hide show
  1. package/README.md +31 -0
  2. package/assets/hero-desktop.svg +10 -0
  3. package/assets/hero-mobile.svg +9 -0
  4. package/assets/logo.svg +3 -0
  5. package/package.json +60 -0
  6. package/src/blocks/home/Features/index.tsx +37 -0
  7. package/src/blocks/home/Hero/index.tsx +102 -0
  8. package/src/blocks/home/LovedByMoms/index.tsx +59 -0
  9. package/src/blocks/home/NewArrivals/index.tsx +57 -0
  10. package/src/blocks/home/ShopByAge/index.tsx +82 -0
  11. package/src/blocks/home/ShopByCategory/index.tsx +92 -0
  12. package/src/blocks/home/Testimonials/index.tsx +130 -0
  13. package/src/blocks/home/WhyChooseUs/index.tsx +46 -0
  14. package/src/layouts/MainLayoutShell.tsx +14 -0
  15. package/src/primitives/Button.tsx +31 -0
  16. package/src/primitives/Card.tsx +32 -0
  17. package/src/primitives/index.ts +2 -0
  18. package/src/slots/account/ForgotPassword/index.tsx +1 -0
  19. package/src/slots/account/Login/index.tsx +1 -0
  20. package/src/slots/account/LoginTemplate/index.tsx +44 -0
  21. package/src/slots/account/Register/index.tsx +1 -0
  22. package/src/slots/cart/CartItem/index.tsx +11 -0
  23. package/src/slots/cart/CartSummary/index.tsx +13 -0
  24. package/src/slots/checkout/CheckoutForm/index.tsx +1 -0
  25. package/src/slots/checkout/CheckoutSummary/index.tsx +1 -0
  26. package/src/slots/layout/Footer/index.tsx +103 -0
  27. package/src/slots/layout/Nav/index.tsx +97 -0
  28. package/src/slots/layout/PromoBar/index.tsx +19 -0
  29. package/src/slots/layout/PromoBar/promo-bar-content.tsx +174 -0
  30. package/src/slots/order/OrderDetails/index.tsx +12 -0
  31. package/src/slots/product/ProductActions/ProductCTASection.tsx +191 -0
  32. package/src/slots/product/ProductActions/ProductDetailsSection.tsx +137 -0
  33. package/src/slots/product/ProductActions/ProductFeaturePanel.tsx +245 -0
  34. package/src/slots/product/ProductActions/ProductHighlightsSection.tsx +99 -0
  35. package/src/slots/product/ProductActions/ProductOptionsSection.tsx +234 -0
  36. package/src/slots/product/ProductActions/ProductPriceSection.tsx +53 -0
  37. package/src/slots/product/ProductActions/ProductTrustSection.tsx +84 -0
  38. package/src/slots/product/ProductActions/index.tsx +161 -0
  39. package/src/slots/product/ProductCard/index.tsx +132 -0
  40. package/src/slots/product/ProductInfo/index.tsx +40 -0
  41. package/src/templates/StorePage/index.tsx +154 -0
  42. package/src/tokens/colors.js +16 -0
  43. package/src/tokens/colors.ts +21 -0
  44. package/src/tokens/fonts.ts +13 -0
  45. package/src/tokens/index.ts +3 -0
  46. package/src/tokens/spacing.ts +9 -0
  47. package/src/tokens/theme.css +89 -0
@@ -0,0 +1,40 @@
1
+ import { HttpTypes } from "@medusajs/types"
2
+ import ProductRating from "@modules/common/components/product/product-rating"
3
+ import ShareButton from "@modules/common/components/product/share-button"
4
+ import WishlistIcon from "@modules/common/components/product/wishlist-icon"
5
+
6
+ type ProductInfoProps = {
7
+ product: HttpTypes.StoreProduct
8
+ region: HttpTypes.StoreRegion
9
+ }
10
+
11
+ export default function ProductInfo({ product }: ProductInfoProps) {
12
+ const metadataBrand = product.metadata?.brand as string | undefined
13
+ const brand = metadataBrand || product.collection?.title || "Valero"
14
+
15
+ return (
16
+ <div id="product-info" className="flex flex-col gap-4 w-full">
17
+ <p className="text-[11px] font-semibold uppercase tracking-[var(--letter-spacing-nav)] text-[var(--color-text-muted)]">
18
+ {brand}
19
+ </p>
20
+
21
+ <div className="flex items-start justify-between gap-4">
22
+ <h1
23
+ className="font-display text-2xl sm:text-3xl lg:text-4xl text-heading leading-heading flex-1"
24
+ data-testid="product-title"
25
+ >
26
+ {product.title}
27
+ </h1>
28
+ <div className="flex items-center gap-2 flex-shrink-0 pt-1">
29
+ {product.id && <WishlistIcon productId={product.id} />}
30
+ <ShareButton
31
+ productTitle={product.title ?? ""}
32
+ productHandle={product.handle ?? ""}
33
+ />
34
+ </div>
35
+ </div>
36
+
37
+ <ProductRating product={product} showButton={false} />
38
+ </div>
39
+ )
40
+ }
@@ -0,0 +1,154 @@
1
+ import { Suspense } from "react"
2
+ import SkeletonProductGrid from "@modules/skeletons/templates/skeleton-product-grid"
3
+ import RefinementList from "@modules/store/components/refinement-list"
4
+ import { SortOptions } from "@modules/store/components/refinement-list/sort-products"
5
+ import MobileFilters from "@modules/store/components/mobile-filters"
6
+ import PaginatedProducts from "@modules/store/templates/paginated-products"
7
+ import { HttpTypes } from "@medusajs/types"
8
+ import LocalizedClientLink from "@modules/common/components/localized-client-link"
9
+
10
+ type StorePageProps = {
11
+ sortBy?: SortOptions
12
+ page?: string
13
+ countryCode: string
14
+ collections?: HttpTypes.StoreCollection[]
15
+ collection?: string | string[]
16
+ category?: string | string[]
17
+ gender?: string | string[]
18
+ type?: string | string[]
19
+ material?: string | string[]
20
+ color?: string | string[]
21
+ minPrice?: string
22
+ maxPrice?: string
23
+ genderOptions?: { value: string; label: string }[]
24
+ typeOptions?: { value: string; label: string }[]
25
+ materialOptions?: { value: string; label: string }[]
26
+ colorOptions?: { value: string; label: string }[]
27
+ categoryOptions?: { value: string; label: string }[]
28
+ q?: string
29
+ }
30
+
31
+ export default function StorePage({
32
+ sortBy,
33
+ page,
34
+ countryCode,
35
+ collections,
36
+ collection,
37
+ category,
38
+ gender,
39
+ type,
40
+ material,
41
+ color,
42
+ minPrice,
43
+ maxPrice,
44
+ genderOptions,
45
+ typeOptions,
46
+ materialOptions,
47
+ colorOptions,
48
+ categoryOptions,
49
+ q,
50
+ }: StorePageProps) {
51
+ const pageNumber = page ? parseInt(page, 10) : 1
52
+ const sort = sortBy || "created_at_desc"
53
+
54
+ const filterProps = {
55
+ sortBy: sort,
56
+ collections,
57
+ collectionValue: collection,
58
+ categoryValue: category,
59
+ categoryOptions,
60
+ genderValue: gender,
61
+ typeValue: type,
62
+ materialValue: material,
63
+ colorValue: color,
64
+ minPrice,
65
+ maxPrice,
66
+ genderOptions,
67
+ typeOptions,
68
+ materialOptions,
69
+ colorOptions,
70
+ q,
71
+ }
72
+
73
+ return (
74
+ <div className="bg-page-bg min-h-screen">
75
+ {/* Collection banner — Impulse style */}
76
+ <div className="bg-surface-alt border-b border-[var(--color-header-border)]">
77
+ <div
78
+ className="mx-auto px-4 sm:px-6 py-10 md:py-14 text-center"
79
+ style={{ maxWidth: "var(--container-max)" }}
80
+ >
81
+ <nav className="text-xs uppercase tracking-[var(--letter-spacing-nav)] text-[var(--color-text-muted)] mb-4">
82
+ <LocalizedClientLink href="/" className="hover:text-heading">
83
+ Home
84
+ </LocalizedClientLink>
85
+ <span className="mx-2">/</span>
86
+ <span className="text-heading">Shop</span>
87
+ </nav>
88
+ <h1 className="font-display text-3xl md:text-4xl lg:text-5xl text-heading">
89
+ {q ? `Results for “${q}”` : "All products"}
90
+ </h1>
91
+ <p className="mt-3 text-sm text-[var(--color-text-muted)] max-w-lg mx-auto">
92
+ Browse our full collection. Filter by category, price, and more.
93
+ </p>
94
+ </div>
95
+ </div>
96
+
97
+ <div
98
+ className="mx-auto px-4 sm:px-6 py-8 lg:py-12"
99
+ style={{ maxWidth: "var(--container-max)" }}
100
+ >
101
+ <div className="flex flex-col lg:flex-row gap-8 lg:gap-12">
102
+ <aside className="hidden lg:block w-64 flex-shrink-0 lg:sticky lg:top-28 lg:self-start lg:max-h-[calc(100vh-8rem)] lg:overflow-y-auto">
103
+ <h2 className="text-xs font-semibold uppercase tracking-[var(--letter-spacing-nav)] text-heading mb-6 pb-2 border-b border-[var(--color-header-border)]">
104
+ Filter
105
+ </h2>
106
+ <RefinementList {...filterProps} />
107
+ </aside>
108
+
109
+ <div className="flex-1 min-w-0">
110
+ <div className="flex items-center justify-between gap-4 mb-6 lg:hidden">
111
+ <MobileFilters {...filterProps} />
112
+ </div>
113
+
114
+ {q && (
115
+ <div className="mb-6 flex items-center justify-between gap-4 p-4 bg-surface-muted border border-[var(--color-header-border)]">
116
+ <span className="text-sm text-[var(--color-text-muted)]">
117
+ Showing results for <strong className="text-heading">"{q}"</strong>
118
+ </span>
119
+ <LocalizedClientLink
120
+ href="/store"
121
+ className="text-xs uppercase tracking-[var(--letter-spacing-nav)] font-semibold text-heading hover:underline"
122
+ >
123
+ Clear
124
+ </LocalizedClientLink>
125
+ </div>
126
+ )}
127
+
128
+ <Suspense fallback={<SkeletonProductGrid />}>
129
+ <PaginatedProducts
130
+ sortBy={sort}
131
+ page={pageNumber}
132
+ countryCode={countryCode}
133
+ collectionId={
134
+ Array.isArray(collection) ? collection.join(",") : collection
135
+ }
136
+ categoryId={
137
+ Array.isArray(category) ? category.join(",") : category
138
+ }
139
+ gender={Array.isArray(gender) ? gender.join(",") : gender}
140
+ type={Array.isArray(type) ? type.join(",") : type}
141
+ material={Array.isArray(material) ? material.join(",") : material}
142
+ color={Array.isArray(color) ? color.join(",") : color}
143
+ min_price={minPrice}
144
+ max_price={maxPrice}
145
+ q={q}
146
+ filterProps={filterProps}
147
+ />
148
+ </Suspense>
149
+ </div>
150
+ </div>
151
+ </div>
152
+ </div>
153
+ )
154
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @deprecated Use theme.css CSS variables as the source of truth.
3
+ * Kept for tooling that reads JS token files during migration.
4
+ */
5
+ module.exports = {
6
+ colors: {
7
+ pageBg: "var(--color-page-bg)",
8
+ brand: {
9
+ accent: "var(--color-brand-accent)",
10
+ accentHover: "var(--color-brand-accent-hover)",
11
+ accentLight: "var(--color-brand-accent-light)",
12
+ pink: "var(--color-brand-pink)",
13
+ primary: "var(--color-brand-primary)",
14
+ },
15
+ },
16
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Semantic Tailwind classes mapped to CSS variables in theme.css.
3
+ * Do not hardcode hex values here — edit theme.css instead.
4
+ */
5
+ export const colorClasses = {
6
+ pageBg: "bg-page-bg",
7
+ surface: "bg-surface",
8
+ surfaceMuted: "bg-surface-muted",
9
+ brandAccent: "bg-brand-accent text-inverse",
10
+ brandAccentText: "text-brand-accent",
11
+ brandAccentBorder: "border-brand-accent",
12
+ brandAccentMuted: "bg-brand-accent-muted",
13
+ heading: "text-heading",
14
+ headingSub: "text-heading-sub",
15
+ body: "text-body",
16
+ muted: "text-muted",
17
+ inverse: "text-inverse",
18
+ footerBg: "bg-brand-footer",
19
+ promoGradient: "bg-promo-gradient",
20
+ cartBorder: "bg-cart-border",
21
+ } as const
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Semantic Tailwind font classes mapped to CSS variables in theme.css.
3
+ * Do not hardcode font families here — edit theme.css instead.
4
+ */
5
+ export const fontClasses = {
6
+ sans: "font-sans",
7
+ heading: "font-heading",
8
+ display: "font-display",
9
+ quote: "font-quote",
10
+ mono: "font-mono",
11
+ body: "font-sans leading-body tracking-body",
12
+ pageTitle: "font-heading font-bold leading-heading tracking-heading",
13
+ } as const
@@ -0,0 +1,3 @@
1
+ export * from "./colors"
2
+ export * from "./fonts"
3
+ export * from "./spacing"
@@ -0,0 +1,9 @@
1
+ export const spacing = {
2
+ sectionY: {
3
+ sm: "py-8",
4
+ md: "py-12",
5
+ lg: "py-16",
6
+ },
7
+ container: "max-w-[1440px] mx-auto",
8
+ content: "max-w-[1360px] mx-auto",
9
+ } as const
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Impulse theme — Shopify Impulse preset design tokens.
3
+ * Reference: https://themes.shopify.com/themes/impulse/presets/impulse
4
+ */
5
+ @import url("https://fonts.googleapis.com/css2?family=Karla:ital,wght@0,400;0,500;0,600;0,700;1,400&family=Playfair+Display:ital,wght@0,400;0,500;0,600;0,700;1,400&display=swap");
6
+
7
+ :root {
8
+ /* Typography — Karla body, Playfair display (Impulse editorial feel) */
9
+ --font-sans: "Karla", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
10
+ sans-serif;
11
+ --font-heading: "Karla", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
12
+ sans-serif;
13
+ --font-display: "Playfair Display", Georgia, "Times New Roman", serif;
14
+ --font-quote: "Playfair Display", Georgia, serif;
15
+ --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
16
+
17
+ --font-weight-normal: 400;
18
+ --font-weight-medium: 500;
19
+ --font-weight-semibold: 600;
20
+ --font-weight-bold: 700;
21
+ --font-weight-extrabold: 700;
22
+
23
+ --line-height-body: 1.65;
24
+ --line-height-heading: 1.2;
25
+ --letter-spacing-heading: 0.02em;
26
+ --letter-spacing-body: 0;
27
+ --letter-spacing-nav: 0.14em;
28
+
29
+ /* Surfaces */
30
+ --color-page-bg: #ffffff;
31
+ --color-surface: #ffffff;
32
+ --color-surface-muted: #f6f6f6;
33
+ --color-surface-alt: #efefef;
34
+ --color-hero-fallback: #e5e5e5;
35
+ --color-footer-bg: #1a1a1a;
36
+ --color-header-bg: #ffffff;
37
+ --color-header-border: #e5e5e5;
38
+
39
+ /* Brand — Impulse preset: monochrome + sale red */
40
+ --color-brand-accent: #1a1a1a;
41
+ --color-brand-accent-hover: #404040;
42
+ --color-brand-accent-light: #525252;
43
+ --color-brand-accent-border: #d4d4d4;
44
+ --color-brand-accent-muted: #f5f5f5;
45
+ --color-brand-accent-rgb: 26, 26, 26;
46
+
47
+ --color-brand-pink: #c1272d;
48
+ --color-brand-primary: #1a1a1a;
49
+ --color-brand-sale: #c1272d;
50
+ --color-brand-success: #2d6a4f;
51
+
52
+ /* Text */
53
+ --color-text-heading: #1a1a1a;
54
+ --color-text-subheading: #333333;
55
+ --color-text-body: #4d4d4d;
56
+ --color-text-muted: #737373;
57
+ --color-text-inverse: #ffffff;
58
+
59
+ /* Navigation & panels */
60
+ --color-nav-active: var(--color-brand-accent);
61
+ --color-nav-active-bg: var(--color-brand-accent-muted);
62
+ --color-cart-panel-bg: var(--color-page-bg);
63
+ --color-border: var(--color-header-border);
64
+
65
+ /* Layout */
66
+ --header-height: 4rem;
67
+ --container-max: 1440px;
68
+
69
+ /* Effects */
70
+ --shadow-brand: 0 16px 40px rgba(0, 0, 0, 0.1);
71
+ --shadow-brand-sm: 0 4px 12px rgba(0, 0, 0, 0.06);
72
+ --shadow-card: 0 1px 4px rgba(0, 0, 0, 0.04);
73
+ --gradient-promo: linear-gradient(
74
+ 135deg,
75
+ var(--color-brand-accent),
76
+ var(--color-brand-accent-light)
77
+ );
78
+ --gradient-cart-border: linear-gradient(
79
+ to bottom right,
80
+ var(--color-brand-accent),
81
+ var(--color-brand-accent-light)
82
+ );
83
+ --gradient-hero: linear-gradient(
84
+ to top,
85
+ rgba(0, 0, 0, 0.5) 0%,
86
+ rgba(0, 0, 0, 0.12) 50%,
87
+ rgba(0, 0, 0, 0) 100%
88
+ );
89
+ }