Skip to content

Commit dd42e42

Browse files
committed
chore: cherry-pick additional interfaces
1 parent 95ecab7 commit dd42e42

File tree

14 files changed

+730
-0
lines changed

14 files changed

+730
-0
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import { type SubmissionResult } from '@conform-to/react';
2+
3+
type Action<State, Payload> = (state: Awaited<State>, payload: Payload) => State | Promise<State>;
4+
5+
interface FormField {
6+
name: string;
7+
label?: string;
8+
errors?: string[];
9+
required?: boolean;
10+
id?: string;
11+
}
12+
13+
type RadioField = {
14+
type: 'radio-group';
15+
options: Array<{ label: string; value: string }>;
16+
defaultValue?: string;
17+
} & FormField;
18+
19+
type CheckboxField = {
20+
type: 'checkbox';
21+
defaultValue?: string;
22+
} & FormField;
23+
24+
type CheckboxGroupField = {
25+
type: 'checkbox-group';
26+
options: Array<{ label: string; value: string }>;
27+
defaultValue?: string[];
28+
} & FormField;
29+
30+
type NumberInputField = {
31+
type: 'number';
32+
defaultValue?: string;
33+
min?: number;
34+
max?: number;
35+
step?: number;
36+
incrementLabel?: string;
37+
decrementLabel?: string;
38+
} & FormField;
39+
40+
type TextInputField = {
41+
type: 'text';
42+
defaultValue?: string;
43+
} & FormField;
44+
45+
type TextAreaField = {
46+
type: 'textarea';
47+
defaultValue?: string;
48+
} & FormField;
49+
50+
type DateField = {
51+
type: 'date';
52+
defaultValue?: string;
53+
minDate?: string;
54+
maxDate?: string;
55+
} & FormField;
56+
57+
type SwatchRadioFieldOption =
58+
| {
59+
type: 'color';
60+
value: string;
61+
label: string;
62+
color: string;
63+
disabled?: boolean;
64+
}
65+
| {
66+
type: 'image';
67+
value: string;
68+
label: string;
69+
image: { src: string; alt: string };
70+
disabled?: boolean;
71+
};
72+
73+
type SwatchRadioField = {
74+
type: 'swatch-radio-group';
75+
defaultValue?: string;
76+
options: SwatchRadioFieldOption[];
77+
} & FormField;
78+
79+
type CardRadioField = {
80+
type: 'card-radio-group';
81+
defaultValue?: string;
82+
options: Array<{
83+
value: string;
84+
label: string;
85+
image: { src: string; alt: string };
86+
disabled?: boolean;
87+
}>;
88+
} & FormField;
89+
90+
type ButtonRadioField = {
91+
type: 'button-radio-group';
92+
defaultValue?: string;
93+
pattern?: string;
94+
options: Array<{
95+
value: string;
96+
label: string;
97+
disabled?: boolean;
98+
}>;
99+
} & FormField;
100+
101+
type SelectField = {
102+
type: 'select';
103+
options: Array<{ label: string; value: string }>;
104+
defaultValue?: string;
105+
} & FormField;
106+
107+
type PasswordField = {
108+
type: 'password';
109+
} & FormField;
110+
111+
type ConfirmPasswordField = {
112+
type: 'confirm-password';
113+
} & FormField;
114+
115+
type EmailInputField = {
116+
type: 'email';
117+
defaultValue?: string;
118+
} & FormField;
119+
120+
type HiddenInputField = {
121+
type: 'hidden';
122+
defaultValue?: string;
123+
} & FormField;
124+
125+
type Field =
126+
| RadioField
127+
| CheckboxField
128+
| CheckboxGroupField
129+
| NumberInputField
130+
| TextInputField
131+
| TextAreaField
132+
| DateField
133+
| SwatchRadioField
134+
| CardRadioField
135+
| ButtonRadioField
136+
| SelectField
137+
| PasswordField
138+
| ConfirmPasswordField
139+
| EmailInputField
140+
| HiddenInputField;
141+
142+
type FieldGroup<F> = F[];
143+
144+
interface Address {
145+
[key: string]: unknown;
146+
id: string;
147+
firstName: string;
148+
lastName: string;
149+
company?: string | undefined;
150+
address1: string;
151+
address2?: string | undefined;
152+
city: string;
153+
stateOrProvince?: string | undefined;
154+
postalCode?: string | undefined;
155+
phone?: string | undefined;
156+
countryCode: string;
157+
}
158+
159+
interface DefaultAddressConfiguration {
160+
id: string | null;
161+
}
162+
163+
interface AddressListState<A extends Address, F extends Field> {
164+
addresses: A[];
165+
defaultAddress?: DefaultAddressConfiguration;
166+
lastResult: SubmissionResult | null;
167+
fields: Array<F | FieldGroup<F>>;
168+
}
169+
170+
export interface AddressListData<A extends Address, F extends Field> {
171+
addresses: A[];
172+
fields: Array<F | FieldGroup<F>>;
173+
defaultAddress?: DefaultAddressConfiguration;
174+
addressAction: Action<AddressListState<A, F>, FormData>;
175+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { type Streamable } from '@/vibes/soul/lib/streamable';
2+
3+
interface Breadcrumb {
4+
label: string;
5+
href: string;
6+
}
7+
8+
interface Tag {
9+
label: string;
10+
link: {
11+
href: string;
12+
target?: string;
13+
};
14+
}
15+
16+
interface Image {
17+
src: string;
18+
alt: string;
19+
}
20+
21+
interface BlogPostContentBlogPost {
22+
title: string;
23+
author?: string;
24+
date: string;
25+
tags?: Tag[];
26+
content: string;
27+
image?: Image;
28+
}
29+
30+
export interface BlogPostContentData {
31+
blogPost: Streamable<BlogPostContentBlogPost>;
32+
breadcrumbs?: Streamable<Breadcrumb[]>;
33+
}

core/ui/blog-post-list/index.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { type Streamable } from '@/vibes/soul/lib/streamable';
2+
3+
interface BlogPostCardBlogPost {
4+
id: string;
5+
author?: string | null;
6+
content: string;
7+
date: string;
8+
image?: {
9+
src: string;
10+
alt: string;
11+
};
12+
href: string;
13+
title: string;
14+
}
15+
16+
export interface BlogPostListData {
17+
posts: Streamable<BlogPostCardBlogPost[]>;
18+
}

core/ui/breadcrumbs/index.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { type Streamable } from '@/vibes/soul/lib/streamable';
2+
3+
interface Breadcrumb {
4+
label: string;
5+
href: string;
6+
}
7+
8+
export interface BreadcrumbsData {
9+
breadcrumbs: Streamable<Breadcrumb[]>;
10+
}

core/ui/cart/index.tsx

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { type SubmissionResult } from '@conform-to/react';
2+
3+
import { type Streamable } from '@/vibes/soul/lib/streamable';
4+
5+
type Action<State, Payload> = (state: Awaited<State>, payload: Payload) => State | Promise<State>;
6+
7+
interface CartLineItem {
8+
id: string;
9+
image: { alt: string; src: string };
10+
title: string;
11+
subtitle: string;
12+
quantity: number;
13+
price: string;
14+
}
15+
16+
interface CartSummaryItem {
17+
label: string;
18+
value: string;
19+
}
20+
21+
interface CartDataData<LineItem extends CartLineItem = CartLineItem> {
22+
lineItems: LineItem[];
23+
summaryItems: CartSummaryItem[];
24+
total: string;
25+
}
26+
27+
interface CartState<LineItem extends CartLineItem = CartLineItem> {
28+
lineItems: LineItem[];
29+
lastResult: SubmissionResult | null;
30+
}
31+
32+
interface CouponCodeState {
33+
couponCodes: string[];
34+
lastResult: SubmissionResult | null;
35+
}
36+
37+
interface CouponCode {
38+
action: Action<CouponCodeState, FormData>;
39+
couponCodes?: string[];
40+
}
41+
42+
interface Address {
43+
country: string;
44+
city?: string;
45+
state?: string;
46+
postalCode?: string;
47+
}
48+
49+
interface ShippingOption {
50+
label: string;
51+
value: string;
52+
price: string;
53+
}
54+
55+
interface ShippingState {
56+
lastResult: SubmissionResult | null;
57+
address: Address | null;
58+
shippingOptions: ShippingOption[] | null;
59+
shippingOption: ShippingOption | null;
60+
form: 'address' | 'shipping' | null;
61+
}
62+
63+
interface Country {
64+
label: string;
65+
value: string;
66+
}
67+
68+
interface States {
69+
country: string;
70+
states: Array<{
71+
label: string;
72+
value: string;
73+
}>;
74+
}
75+
76+
interface Shipping {
77+
action: Action<ShippingState, FormData>;
78+
countries: Country[];
79+
states: States[];
80+
address?: Address;
81+
shippingOptions?: ShippingOption[];
82+
shippingOption?: ShippingOption;
83+
}
84+
85+
export interface CartData<
86+
LineItem extends CartLineItem = CartLineItem,
87+
Data extends CartDataData<LineItem> = CartDataData<LineItem>,
88+
Coupon extends CouponCode = CouponCode,
89+
ShippingInfo extends Shipping = Shipping,
90+
> {
91+
lineItemAction: Action<CartState<LineItem>, FormData>;
92+
checkoutAction: Action<SubmissionResult | null, FormData>;
93+
cart: Streamable<Data>;
94+
couponCode?: Coupon;
95+
shipping?: ShippingInfo;
96+
}

core/ui/compare-section/index.tsx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { type SubmissionResult } from '@conform-to/react';
2+
import { type ReactNode } from 'react';
3+
4+
import { type Streamable } from '@/vibes/soul/lib/streamable';
5+
6+
type Action<State, Payload> = (state: Awaited<State>, payload: Payload) => State | Promise<State>;
7+
8+
interface PriceRange {
9+
type: 'range';
10+
minValue: string;
11+
maxValue: string;
12+
}
13+
14+
interface PriceSale {
15+
type: 'sale';
16+
previousValue: string;
17+
currentValue: string;
18+
}
19+
20+
type Price = string | PriceRange | PriceSale;
21+
22+
interface Product {
23+
id: string;
24+
title: string;
25+
href: string;
26+
image?: { src: string; alt: string };
27+
price?: Price;
28+
subtitle?: string;
29+
badge?: string;
30+
rating?: number;
31+
}
32+
33+
interface CompareCardWithId extends Product {
34+
description?: string | React.ReactNode;
35+
customFields?: Array<{ name: string; value: string }>;
36+
hasVariants?: boolean;
37+
disabled?: boolean;
38+
isPreorder?: boolean;
39+
}
40+
41+
interface CompareAddToCartState {
42+
lastResult: SubmissionResult | null;
43+
successMessage?: ReactNode;
44+
}
45+
46+
type CompareAddToCartAction = Action<CompareAddToCartState, FormData>;
47+
48+
export interface CompareSectionData {
49+
products: Streamable<CompareCardWithId[]>;
50+
addToCartAction: CompareAddToCartAction;
51+
}

0 commit comments

Comments
 (0)