Skip to content

Commit 517a974

Browse files
authored
Merge branch 'Weaverse:main' into main
2 parents 3e33b68 + ab464c9 commit 517a974

File tree

25 files changed

+587
-502
lines changed

25 files changed

+587
-502
lines changed

.github/workflows/claude.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
4848
Please review this pull request and provide feedback on:
4949
- Code quality and adherence to project conventions (check CLAUDE.md for guidelines)
50-
- Weaverse section implementation (must use forwardRef and export schema)
50+
- Weaverse section implementation (must use ref as a prop and export schema)
5151
- GraphQL usage and type safety
5252
- Performance considerations (especially parallel data loading)
5353
- Biome linting compliance

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pnpm-lock.yaml
1717
.DS_Store
1818
.react-router
1919
.claude/
20+
.github/copilot-instructions.md
2021
memory/
2122
scripts/
2223
templates/

CHANGELOG.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,56 @@
11
# @weaverse/pilot
22

3+
## 6.0.3
4+
5+
### Patch Changes
6+
7+
- **Component refactoring**: Migrated from forwardRef pattern to ref as props for Weaverse sections and components, improving API consistency
8+
- **UI/UX improvements**:
9+
- Enhanced ProductCard and ProductMedia components with view transition effects for smoother user experience
10+
- Refactored PredictiveSearchButton layout and repositioned PopularKeywords component
11+
- Updated JudgemeStarsRating component with improved loading state styling
12+
- Added variant prices display in SingleProduct component
13+
- **Code cleanup**:
14+
- Removed unused NavLink component
15+
- Cleaned up SingleProduct component by removing unused children prop and childTypes from schema
16+
- Updated default onClickEvent value to "scroll-to-section" in JudgemeStarsRating schema
17+
- Removed unused imports across multiple components
18+
- **Developer experience**:
19+
- Updated CLAUDE.md documentation with improved project guidance
20+
- Added .github/copilot-instructions.md to .gitignore
21+
- Updated GitHub workflow configuration
22+
23+
## 6.0.2
24+
25+
### Patch Changes
26+
27+
- Updated dependencies [3720e74]
28+
- Updated dependencies [469f291]
29+
- Updated dependencies [9ee3be2]
30+
- @weaverse/hydrogen@5.5.0
31+
32+
## 6.0.2-beta.0
33+
34+
### Patch Changes
35+
36+
- @weaverse/hydrogen@5.5.1-beta.0
37+
38+
## 6.0.1
39+
40+
### Patch Changes
41+
42+
- Updated dependencies [21ba4ed]
43+
- Updated dependencies [5c6060b]
44+
- Updated dependencies [2468404]
45+
- @weaverse/hydrogen@5.5.0
46+
47+
## 6.0.1-beta.0
48+
49+
### Patch Changes
50+
51+
- Updated dependencies
52+
- @weaverse/hydrogen@5.5.0-beta.0
53+
354
## 6.0.0
455

556
### Major Changes

CLAUDE.md

Lines changed: 76 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
44

55
## Project Overview
66

7-
This is **Pilot**, a Shopify Hydrogen theme powered by Weaverse - a visual page builder for Hydrogen storefronts. The project is built with React, TypeScript, React Router 7, and Tailwind CSS v4. It runs on Node.js 20+ and uses Biome for linting/formatting.
7+
This is **Pilot**, a Shopify Hydrogen theme powered by Weaverse - a visual page builder for Hydrogen storefronts. The project is built with React, TypeScript, React Router 7, and Tailwind CSS v4. It runs on Node.js 20+ and uses Biome for linting/formatting. Current version: 5.6.0 with upcoming 5.7.0 release.
88

99
## Essential Commands
1010

@@ -89,6 +89,7 @@ All routes follow the pattern `($locale).{route}.tsx` to support internationaliz
8989

9090
- **Weaverse**: Visual page builder - sections must be registered in `/app/weaverse/components.ts`
9191
- **Judge.me**: Product reviews integration via utilities in `/app/utils/judgeme.ts`
92+
- **Combined Listings**: Intelligent product grouping system via utilities in `/app/utils/combined-listings.ts`
9293
- **Analytics**: Shopify Analytics integrated throughout components
9394
- **Customer Accounts**: New Shopify Customer Account API support (OAuth-based)
9495
- **Radix UI**: For accessible UI primitives (accordion, dialog, dropdown, etc.)
@@ -97,32 +98,33 @@ All routes follow the pattern `($locale).{route}.tsx` to support internationaliz
9798
### Weaverse Section Development
9899

99100
1. **Creating a New Section**:
100-
```typescript
101-
// app/sections/my-section/index.tsx
102-
import { createSchema, type HydrogenComponentProps } from '@weaverse/hydrogen';
103-
import { forwardRef } from 'react';
104-
105-
interface MyProps extends HydrogenComponentProps {
106-
heading: string;
107-
}
108-
109-
const MySection = forwardRef<HTMLElement, MyProps>((props, ref) => {
110-
// Component implementation
111-
});
112-
113-
export default MySection;
114-
115-
export const schema = createSchema({
116-
type: 'my-section',
117-
title: 'My Section',
118-
settings: [/* ... */]
119-
});
120-
121-
// Optional loader for server-side data fetching
122-
export const loader = async ({ weaverse, data }) => {
123-
// Fetch data
124-
};
125-
```
101+
```typescript
102+
// app/sections/my-section/index.tsx
103+
import { createSchema, type HydrogenComponentProps } from '@weaverse/hydrogen';
104+
import type { ComponentRef } from 'react';
105+
106+
interface MyProps extends HydrogenComponentProps {
107+
heading: string;
108+
ref?: React.Ref<HTMLDivElement>;
109+
}
110+
111+
const MySection = ({ ref, ...props }: MyProps) => {
112+
// Component implementation
113+
};
114+
115+
export default MySection;
116+
117+
export const schema = createSchema({
118+
type: 'my-section',
119+
title: 'My Section',
120+
settings: [/* ... */]
121+
});
122+
123+
// Optional loader for server-side data fetching
124+
export const loader = async ({ weaverse, data }) => {
125+
// Fetch data
126+
};
127+
```
126128

127129
2. **Register in `/app/weaverse/components.ts`**:
128130
```typescript
@@ -139,21 +141,21 @@ All routes follow the pattern `($locale).{route}.tsx` to support internationaliz
139141
export async function loader({ params, request, context }: LoaderFunctionArgs) {
140142
const { handle } = params;
141143
invariant(handle, "Missing handle param");
142-
144+
143145
const { storefront, weaverse } = context;
144-
146+
145147
// Parallel data loading
146148
const [shopifyData, weaverseData, thirdPartyData] = await Promise.all([
147149
storefront.query(QUERY, { variables }),
148150
weaverse.loadPage({ type: "PAGE_TYPE", handle }),
149151
fetchThirdPartyData(),
150152
]);
151-
153+
152154
// Handle errors
153155
if (!shopifyData.resource) {
154156
throw new Response("Not found", { status: 404 });
155157
}
156-
158+
157159
return data({
158160
shopifyData,
159161
weaverseData,
@@ -162,14 +164,40 @@ export async function loader({ params, request, context }: LoaderFunctionArgs) {
162164
}
163165
```
164166

167+
### Combined Listings Integration
168+
169+
Combined Listings allow intelligent product grouping and filtering:
170+
171+
```typescript
172+
// Use utility functions from app/utils/combined-listings.ts
173+
import { isCombinedListing, shouldFilterCombinedListings } from '~/utils/combined-listings';
174+
175+
// In product queries and loaders
176+
const filteredProducts = products.filter(product =>
177+
!shouldFilterCombinedListings(product, settings)
178+
);
179+
180+
// In components
181+
if (isCombinedListing(product)) {
182+
// Handle combined listing display differently
183+
}
184+
```
185+
186+
Key integration points:
187+
- Product loaders filter combined listings based on settings
188+
- Cart functionality handles combined products specially
189+
- Product display components check for combined listing status
190+
- Featured products support both collection-based and manual selection
191+
165192
### Environment Configuration
166193

167194
Required environment variables are defined in `env.d.ts`. The project uses `@shopify/hydrogen` and `@shopify/remix-oxygen` for environment handling.
168195

169196
### Testing Strategy
170197

171198
- E2E tests use Playwright and are located in `/tests/`
172-
- Tests run against `localhost:3456` (same as dev server)
199+
- Tests run against `localhost:3000` using production build (`npm run preview`)
200+
- Playwright automatically starts the preview server before running tests
173201
- Focus on critical user flows: cart operations, checkout process
174202
- Run individual tests: `npx playwright test tests/cart.test.ts`
175203

@@ -199,3 +227,19 @@ The project extends from `ultracite` and `@weaverse/biome` configurations with t
199227
4. **Customer Account Queries**: Only use in `*.account*.{ts,tsx}` files
200228
5. **Parallel Loading**: Always use `Promise.all()` for multiple data fetches in loaders
201229
6. **Type Safety**: Never use `any` type, properly type all Weaverse section props
230+
7. **Combined Listings**: Use utility functions from `/app/utils/combined-listings.ts` for product filtering and grouping logic
231+
8. **Package Manager**: Use npm (not pnpm) - the project is configured for npm package management
232+
233+
## Development Setup Requirements
234+
235+
### Node.js and Dependencies
236+
- **Node.js**: Version 20.0.0 or higher required
237+
- **Package Manager**: npm (configured in package.json, don't use pnpm)
238+
- **Environment**: Copy `.env.example` to `.env` and configure Shopify store credentials
239+
240+
### Key Configuration Files
241+
- **react-router.config.ts**: React Router v7 configuration (SSR enabled, app directory structure)
242+
- **vite.config.ts**: Includes Hydrogen, Oxygen, Tailwind CSS v4, and development server warmup
243+
- **biome.json**: Code quality configuration extending from `ultracite` and `@weaverse/biome`
244+
- **codegen.ts**: GraphQL code generation for Shopify Storefront and Customer Account APIs
245+
- **tsconfig.json**: TypeScript config with `~/` path alias, strict mode disabled for compatibility

app/components/button.tsx

Lines changed: 55 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { CircleNotchIcon } from "@phosphor-icons/react";
22
import type { VariantProps } from "class-variance-authority";
33
import { cva } from "class-variance-authority";
44
import type { HTMLAttributes } from "react";
5-
import { forwardRef } from "react";
65
import { cn } from "~/utils/cn";
76

87
export const variants = cva(
@@ -78,6 +77,7 @@ export interface ButtonProps
7877
extends VariantProps<typeof variants>,
7978
Omit<HTMLAttributes<HTMLButtonElement>, "type">,
8079
Partial<ButtonStyleProps> {
80+
ref?: React.Ref<HTMLButtonElement>;
8181
type?: "button" | "reset" | "submit";
8282
className?: string;
8383
disabled?: boolean;
@@ -86,65 +86,64 @@ export interface ButtonProps
8686
animate?: boolean;
8787
}
8888

89-
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
90-
(props, ref) => {
91-
let {
92-
type = "button",
93-
variant,
94-
loading,
95-
className,
96-
textColor,
97-
backgroundColor,
98-
borderColor,
99-
textColorHover,
100-
backgroundColorHover,
101-
borderColorHover,
102-
style = {},
103-
animate = true,
104-
children,
105-
...rest
106-
} = props;
107-
if (variant === "custom") {
108-
style = {
109-
...style,
110-
"--btn-text": textColor,
111-
"--btn-bg": backgroundColor,
112-
"--btn-border": borderColor,
113-
"--btn-text-hover": textColorHover,
114-
"--btn-bg-hover": backgroundColorHover,
115-
"--btn-border-hover": borderColorHover,
116-
} as React.CSSProperties;
117-
}
89+
export function Button(props: ButtonProps) {
90+
let {
91+
ref,
92+
type = "button",
93+
variant,
94+
loading,
95+
className,
96+
textColor,
97+
backgroundColor,
98+
borderColor,
99+
textColorHover,
100+
backgroundColorHover,
101+
borderColorHover,
102+
style = {},
103+
animate = true,
104+
children,
105+
...rest
106+
} = props;
107+
if (variant === "custom") {
108+
style = {
109+
...style,
110+
"--btn-text": textColor,
111+
"--btn-bg": backgroundColor,
112+
"--btn-border": borderColor,
113+
"--btn-text-hover": textColorHover,
114+
"--btn-bg-hover": backgroundColorHover,
115+
"--btn-border-hover": borderColorHover,
116+
} as React.CSSProperties;
117+
}
118118

119-
if (!children) {
120-
return null;
121-
}
119+
if (!children) {
120+
return null;
121+
}
122122

123-
let content: React.ReactNode;
124-
if (typeof children === "string") {
125-
content = <span>{children}</span>;
126-
} else {
127-
content = children;
128-
}
123+
let content: React.ReactNode;
124+
if (typeof children === "string") {
125+
content = <span>{children}</span>;
126+
} else {
127+
content = children;
128+
}
129129

130-
if (animate) {
131-
rest["data-motion"] = "fade-up";
132-
}
130+
if (animate) {
131+
rest["data-motion"] = "fade-up";
132+
}
133133

134-
return (
135-
<button
136-
ref={ref}
137-
style={style}
138-
type={type}
139-
{...rest}
140-
className={cn(variants({ variant, className }))}
141-
>
142-
{loading && <Spinner />}
143-
{content}
144-
</button>
145-
);
146-
},
147-
);
134+
return (
135+
<button
136+
ref={ref}
137+
style={style}
138+
type={type}
139+
{...rest}
140+
className={cn(variants({ variant, className }))}
141+
>
142+
{loading && <Spinner />}
143+
{content}
144+
</button>
145+
);
146+
}
148147

149148
function Spinner() {
150149
const style = { "--duration": "500ms" } as React.CSSProperties;

0 commit comments

Comments
 (0)