@pallamart/pm-core-components 1.0.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/LICENSE +32 -0
- package/README.md +21 -0
- package/dist/auth/microsoft-auth-button.d.ts +6 -0
- package/dist/auth/microsoft-auth-button.js +10 -0
- package/dist/create-element.d.ts +7 -0
- package/dist/create-element.js +34 -0
- package/dist/external/breadcrumb.d.ts +10 -0
- package/dist/external/breadcrumb.js +20 -0
- package/dist/external/index.d.ts +12 -0
- package/dist/external/index.js +9 -0
- package/dist/external/products/product-details.d.ts +8 -0
- package/dist/external/products/product-details.js +12 -0
- package/dist/external/products/product-rail-item.d.ts +9 -0
- package/dist/external/products/product-rail-item.js +22 -0
- package/dist/external/products/product-rail.d.ts +11 -0
- package/dist/external/products/product-rail.js +18 -0
- package/dist/external/products/room-color-step.d.ts +11 -0
- package/dist/external/products/room-color-step.js +36 -0
- package/dist/external/products/wall-color-control.d.ts +8 -0
- package/dist/external/products/wall-color-control.js +25 -0
- package/dist/external/storefront-footer.d.ts +10 -0
- package/dist/external/storefront-footer.js +12 -0
- package/dist/external/storefront-header.d.ts +5 -0
- package/dist/external/storefront-header.js +27 -0
- package/dist/external/types.d.ts +27 -0
- package/dist/external/types.js +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +27 -0
- package/dist/loaders/dot-loader.d.ts +1 -0
- package/dist/loaders/dot-loader.js +7 -0
- package/dist/loaders/inline-loader.d.ts +5 -0
- package/dist/loaders/inline-loader.js +10 -0
- package/dist/root/not-found-ui.d.ts +5 -0
- package/dist/root/not-found-ui.js +25 -0
- package/dist/root/root-error-ui.d.ts +7 -0
- package/dist/root/root-error-ui.js +28 -0
- package/dist/ui/alert.d.ts +8 -0
- package/dist/ui/alert.js +25 -0
- package/dist/ui/app-header.d.ts +21 -0
- package/dist/ui/app-header.js +50 -0
- package/dist/ui/avatar.d.ts +4 -0
- package/dist/ui/avatar.js +20 -0
- package/dist/ui/badge.d.ts +7 -0
- package/dist/ui/badge.js +13 -0
- package/dist/ui/breadcrumb.d.ts +5 -0
- package/dist/ui/breadcrumb.js +29 -0
- package/dist/ui/button.d.ts +15 -0
- package/dist/ui/button.js +26 -0
- package/dist/ui/card.d.ts +7 -0
- package/dist/ui/card.js +38 -0
- package/dist/ui/dialog.d.ts +16 -0
- package/dist/ui/dialog.js +52 -0
- package/dist/ui/dropdown-menu.d.ts +12 -0
- package/dist/ui/dropdown-menu.js +43 -0
- package/dist/ui/empty.d.ts +5 -0
- package/dist/ui/empty.js +26 -0
- package/dist/ui/file-picker.d.ts +20 -0
- package/dist/ui/file-picker.js +49 -0
- package/dist/ui/form.d.ts +15 -0
- package/dist/ui/form.js +67 -0
- package/dist/ui/icon-button.d.ts +11 -0
- package/dist/ui/icon-button.js +18 -0
- package/dist/ui/misc.d.ts +10 -0
- package/dist/ui/misc.js +46 -0
- package/dist/ui/popover.d.ts +6 -0
- package/dist/ui/popover.js +20 -0
- package/dist/ui/progress.d.ts +4 -0
- package/dist/ui/progress.js +16 -0
- package/dist/ui/separator.d.ts +4 -0
- package/dist/ui/separator.js +10 -0
- package/dist/ui/skeleton.d.ts +2 -0
- package/dist/ui/skeleton.js +8 -0
- package/dist/ui/spinner.d.ts +2 -0
- package/dist/ui/spinner.js +26 -0
- package/dist/ui/table.d.ts +7 -0
- package/dist/ui/table.js +41 -0
- package/dist/ui/tabs.d.ts +6 -0
- package/dist/ui/tabs.js +17 -0
- package/dist/ui/tooltip.d.ts +4 -0
- package/dist/ui/tooltip.js +20 -0
- package/dist/utils/cn.d.ts +1 -0
- package/dist/utils/cn.js +3 -0
- package/package.json +80 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Pallamart Proprietary License
|
|
2
|
+
|
|
3
|
+
Version 1.0, 23-Jan-2024
|
|
4
|
+
|
|
5
|
+
1. Grant of License:
|
|
6
|
+
Pallamart grants you a non-exclusive, non-transferable, revocable license to use the software, solely for internal business purposes.
|
|
7
|
+
|
|
8
|
+
2. Restrictions:
|
|
9
|
+
You may not:
|
|
10
|
+
a. Distribute or sublicense the software to third parties.
|
|
11
|
+
b. Reverse engineer, decompile, or disassemble the software.
|
|
12
|
+
c. Remove or alter any proprietary notices or labels on the software.
|
|
13
|
+
|
|
14
|
+
3. Ownership:
|
|
15
|
+
Pallamart retains all right, title, and interest in and to the software, including all intellectual property rights.
|
|
16
|
+
|
|
17
|
+
4. Confidentiality:
|
|
18
|
+
You agree to keep the software confidential and not disclose it to third parties.
|
|
19
|
+
|
|
20
|
+
5. Support and Updates:
|
|
21
|
+
This license does not entitle you to support or updates. Pallamart may, at its discretion, provide support and updates.
|
|
22
|
+
|
|
23
|
+
6. Termination:
|
|
24
|
+
This license is effective until terminated. Pallamart may terminate the license at any time if you breach any terms. Upon termination, you must cease using the software.
|
|
25
|
+
|
|
26
|
+
7. Governing Law:
|
|
27
|
+
This license is governed by the Canadian Laws. Any disputes arising out of this license shall be resolved in the courts of Canada.
|
|
28
|
+
|
|
29
|
+
8. Contact Information:
|
|
30
|
+
For inquiries regarding this license, contact operations@pallamart.com.
|
|
31
|
+
|
|
32
|
+
[End of License]
|
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @pallamart/pm-core-components
|
|
2
|
+
|
|
3
|
+
Pallamart shared React components.
|
|
4
|
+
|
|
5
|
+
## Development
|
|
6
|
+
|
|
7
|
+
Use Node.js from `.nvmrc`, then install dependencies:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Available checks:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm run build
|
|
17
|
+
npm run format:check
|
|
18
|
+
npm run lint
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The package is published from `dist/`. Source code lives in `src/`; do not edit generated output directly.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createElement } from '../create-element.js';
|
|
2
|
+
export default function MicrosoftAuthButton({ redirectTo, authRoutePath, }) {
|
|
3
|
+
return createElement('a', {
|
|
4
|
+
href: `${authRoutePath}?redirectTo=${encodeURIComponent(redirectTo)}`,
|
|
5
|
+
className: 'inline-flex h-10 w-full items-center justify-center gap-2 rounded-md border border-input bg-background px-4 py-2 text-body-3 shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring',
|
|
6
|
+
}, createElement('span', {
|
|
7
|
+
'aria-hidden': 'true',
|
|
8
|
+
className: 'grid h-4 w-4 grid-cols-2 gap-0.5',
|
|
9
|
+
}, createElement('span', { className: 'bg-[#f25022]' }), createElement('span', { className: 'bg-[#7fba00]' }), createElement('span', { className: 'bg-[#00a4ef]' }), createElement('span', { className: 'bg-[#ffb900]' })), createElement('span', null, 'Sign in with Microsoft'));
|
|
10
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type ElementType = string | ((props: Record<string, unknown>) => unknown);
|
|
2
|
+
type ElementProps = Record<string, unknown> & {
|
|
3
|
+
key?: string | number | null;
|
|
4
|
+
ref?: unknown;
|
|
5
|
+
};
|
|
6
|
+
export declare function createElement(type: ElementType, props: ElementProps | null, ...children: unknown[]): any;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
function withFallbackKey(child, index) {
|
|
2
|
+
if (child &&
|
|
3
|
+
typeof child === 'object' &&
|
|
4
|
+
'$$typeof' in child &&
|
|
5
|
+
child.key == null) {
|
|
6
|
+
return {
|
|
7
|
+
...child,
|
|
8
|
+
key: index,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
return child;
|
|
12
|
+
}
|
|
13
|
+
export function createElement(type, props, ...children) {
|
|
14
|
+
const normalizedProps = { ...(props ?? {}) };
|
|
15
|
+
const key = normalizedProps.key ?? null;
|
|
16
|
+
const ref = normalizedProps.ref ?? null;
|
|
17
|
+
delete normalizedProps.key;
|
|
18
|
+
delete normalizedProps.ref;
|
|
19
|
+
if (children.length === 1) {
|
|
20
|
+
normalizedProps.children = children[0];
|
|
21
|
+
}
|
|
22
|
+
else if (children.length > 1) {
|
|
23
|
+
normalizedProps.children = children.map(withFallbackKey);
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
$$typeof: Symbol.for('react.element'),
|
|
27
|
+
type,
|
|
28
|
+
key,
|
|
29
|
+
ref,
|
|
30
|
+
props: normalizedProps,
|
|
31
|
+
_owner: null,
|
|
32
|
+
_store: {},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface StorefrontBreadcrumbItem {
|
|
2
|
+
label: string;
|
|
3
|
+
path?: string;
|
|
4
|
+
}
|
|
5
|
+
interface StorefrontBreadcrumbProps {
|
|
6
|
+
items: StorefrontBreadcrumbItem[];
|
|
7
|
+
websiteUrl: string;
|
|
8
|
+
}
|
|
9
|
+
export default function StorefrontBreadcrumb({ items, websiteUrl, }: StorefrontBreadcrumbProps): any;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { UrlService } from '@pallamart/pm-utilities';
|
|
2
|
+
import { createElement } from '../create-element.js';
|
|
3
|
+
export default function StorefrontBreadcrumb({ items, websiteUrl, }) {
|
|
4
|
+
const websiteBaseUrl = UrlService.trimTrailingSlash(websiteUrl);
|
|
5
|
+
return createElement('nav', {
|
|
6
|
+
'aria-label': 'Breadcrumb',
|
|
7
|
+
className: 'pm-external-breadcrumb',
|
|
8
|
+
}, items.map((item, index) => {
|
|
9
|
+
const isLast = index === items.length - 1;
|
|
10
|
+
const content = item.path
|
|
11
|
+
? createElement('a', {
|
|
12
|
+
className: 'pm-external-breadcrumb-link',
|
|
13
|
+
href: UrlService.join(websiteBaseUrl, item.path),
|
|
14
|
+
}, item.label)
|
|
15
|
+
: createElement('span', null, item.label);
|
|
16
|
+
return createElement('span', { className: 'pm-external-breadcrumb-item', key: item.label }, content, !isLast
|
|
17
|
+
? createElement('span', { className: 'pm-external-breadcrumb-separator' }, '›')
|
|
18
|
+
: null);
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { default as StorefrontBreadcrumb } from './breadcrumb.js';
|
|
2
|
+
export type { StorefrontBreadcrumbItem } from './breadcrumb.js';
|
|
3
|
+
export { IconButton } from '../ui/icon-button.js';
|
|
4
|
+
export { default as ExternalProductDetails } from './products/product-details.js';
|
|
5
|
+
export { default as ExternalProductRail } from './products/product-rail.js';
|
|
6
|
+
export { default as ExternalProductRailItem } from './products/product-rail-item.js';
|
|
7
|
+
export { default as ExternalRoomColorStep } from './products/room-color-step.js';
|
|
8
|
+
export { default as ExternalWallColorControl } from './products/wall-color-control.js';
|
|
9
|
+
export { default as StorefrontFooter } from './storefront-footer.js';
|
|
10
|
+
export type { StorefrontFooterNavigationItem } from './storefront-footer.js';
|
|
11
|
+
export { default as StorefrontHeader } from './storefront-header.js';
|
|
12
|
+
export type { ExternalProductData, ExternalProductImageData, ExternalProductPriceData, ExternalWallColorData, } from './types.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { default as StorefrontBreadcrumb } from './breadcrumb.js';
|
|
2
|
+
export { IconButton } from '../ui/icon-button.js';
|
|
3
|
+
export { default as ExternalProductDetails } from './products/product-details.js';
|
|
4
|
+
export { default as ExternalProductRail } from './products/product-rail.js';
|
|
5
|
+
export { default as ExternalProductRailItem } from './products/product-rail-item.js';
|
|
6
|
+
export { default as ExternalRoomColorStep } from './products/room-color-step.js';
|
|
7
|
+
export { default as ExternalWallColorControl } from './products/wall-color-control.js';
|
|
8
|
+
export { default as StorefrontFooter } from './storefront-footer.js';
|
|
9
|
+
export { default as StorefrontHeader } from './storefront-header.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ExternalProductData } from '../types.js';
|
|
2
|
+
interface ExternalProductDetailsProps {
|
|
3
|
+
product: ExternalProductData;
|
|
4
|
+
roomToneControl?: unknown;
|
|
5
|
+
websiteUrl: string;
|
|
6
|
+
}
|
|
7
|
+
export default function ExternalProductDetails({ product, roomToneControl, websiteUrl, }: ExternalProductDetailsProps): any;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { UrlService } from '@pallamart/pm-utilities';
|
|
2
|
+
import { createElement } from '../../create-element.js';
|
|
3
|
+
export default function ExternalProductDetails({ product, roomToneControl, websiteUrl, }) {
|
|
4
|
+
const description = product.description ||
|
|
5
|
+
'A soft bedding style designed to help your room feel finished, calm, and easy to live in.';
|
|
6
|
+
return createElement('div', { className: 'pm-external-product-summary' }, product.vendor
|
|
7
|
+
? createElement('p', { className: 'pm-external-product-vendor' }, product.vendor)
|
|
8
|
+
: null, createElement('h1', { className: 'pm-external-product-title' }, product.title), roomToneControl, createElement('p', { className: 'pm-external-product-description' }, description), createElement('a', {
|
|
9
|
+
className: 'pm-external-cart-button',
|
|
10
|
+
href: UrlService.join(websiteUrl, `/products/${product.handle}`),
|
|
11
|
+
}, 'Buy Now'));
|
|
12
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ExternalProductData } from '../types.js';
|
|
2
|
+
interface ExternalProductRailItemProps {
|
|
3
|
+
index: number;
|
|
4
|
+
isActive: boolean;
|
|
5
|
+
product: ExternalProductData;
|
|
6
|
+
onSelect: (index: number) => void;
|
|
7
|
+
}
|
|
8
|
+
export default function ExternalProductRailItem({ index, isActive, onSelect, product, }: ExternalProductRailItemProps): any;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CurrencyService } from '@pallamart/pm-utilities';
|
|
2
|
+
import { createElement } from '../../create-element.js';
|
|
3
|
+
export default function ExternalProductRailItem({ index, isActive, onSelect, product, }) {
|
|
4
|
+
return createElement('button', {
|
|
5
|
+
'aria-label': `Preview ${product.title}`,
|
|
6
|
+
'aria-pressed': isActive,
|
|
7
|
+
className: isActive
|
|
8
|
+
? 'pm-external-product-card active'
|
|
9
|
+
: 'pm-external-product-card',
|
|
10
|
+
'data-product-index': index,
|
|
11
|
+
onClick: () => onSelect(index),
|
|
12
|
+
type: 'button',
|
|
13
|
+
}, createElement('span', { className: 'pm-external-product-card-media' }, product.featuredImage
|
|
14
|
+
? createElement('img', {
|
|
15
|
+
alt: product.featuredImage.altText ?? product.title,
|
|
16
|
+
className: 'pm-external-product-card-image',
|
|
17
|
+
src: product.featuredImage.url,
|
|
18
|
+
})
|
|
19
|
+
: null), createElement('span', { className: 'pm-external-product-card-vendor' }, product.vendor || 'Palluva'), createElement('span', { className: 'pm-external-product-card-title' }, product.title), createElement('span', { className: 'pm-external-product-card-price' }, CurrencyService.format(product.minPrice)
|
|
20
|
+
? `From ${CurrencyService.format(product.minPrice)} CAD`
|
|
21
|
+
: product.productType));
|
|
22
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import type { ExternalProductData } from '../types.js';
|
|
3
|
+
interface ExternalProductRailProps {
|
|
4
|
+
activeProductIndex: number;
|
|
5
|
+
products: ExternalProductData[];
|
|
6
|
+
onProductChange: (index: number) => void;
|
|
7
|
+
onScroll?: () => void;
|
|
8
|
+
railRef?: React.RefObject<HTMLDivElement>;
|
|
9
|
+
}
|
|
10
|
+
export default function ExternalProductRail({ activeProductIndex, onProductChange, onScroll, products, railRef, }: ExternalProductRailProps): any;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createElement } from '../../create-element.js';
|
|
2
|
+
import ExternalProductRailItem from './product-rail-item.js';
|
|
3
|
+
export default function ExternalProductRail({ activeProductIndex, onProductChange, onScroll, products, railRef, }) {
|
|
4
|
+
return createElement('section', {
|
|
5
|
+
'aria-label': 'Available bedding styles',
|
|
6
|
+
className: 'pm-external-product-rail',
|
|
7
|
+
}, createElement('div', {
|
|
8
|
+
className: 'pm-external-product-grid',
|
|
9
|
+
onScroll,
|
|
10
|
+
ref: railRef,
|
|
11
|
+
}, products.map((product, index) => createElement(ExternalProductRailItem, {
|
|
12
|
+
index,
|
|
13
|
+
isActive: index === activeProductIndex,
|
|
14
|
+
key: product.id,
|
|
15
|
+
onSelect: onProductChange,
|
|
16
|
+
product,
|
|
17
|
+
}))));
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ExternalWallColorData } from '../types.js';
|
|
2
|
+
interface ExternalRoomColorStepProps {
|
|
3
|
+
activeWallColorHex: string;
|
|
4
|
+
productTitle: string;
|
|
5
|
+
productType: string;
|
|
6
|
+
wallColors: ExternalWallColorData[];
|
|
7
|
+
onColorChange: (colorHex: string) => void;
|
|
8
|
+
onContinue: () => void;
|
|
9
|
+
}
|
|
10
|
+
export default function ExternalRoomColorStep({ activeWallColorHex, productTitle, productType, wallColors, onColorChange, onContinue, }: ExternalRoomColorStepProps): any;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createElement } from '../../create-element.js';
|
|
2
|
+
export default function ExternalRoomColorStep({ activeWallColorHex, productTitle, productType, wallColors, onColorChange, onContinue, }) {
|
|
3
|
+
return createElement('section', {
|
|
4
|
+
className: 'mx-auto flex min-h-[calc(100vh-11rem)] w-full max-w-5xl flex-col justify-center py-8 sm:py-10',
|
|
5
|
+
}, createElement('div', {
|
|
6
|
+
className: 'grid gap-10 lg:grid-cols-[minmax(0,0.85fr)_minmax(0,1.15fr)] lg:items-end',
|
|
7
|
+
}, createElement('div', { className: 'max-w-xl' }, createElement('p', {
|
|
8
|
+
className: 'text-body-3 uppercase tracking-wide text-grey-dark',
|
|
9
|
+
}, `${productType} preview`), createElement('h1', {
|
|
10
|
+
className: 'mt-3 text-header-1 leading-tight text-black',
|
|
11
|
+
}, 'Start with your room.'), createElement('p', { className: 'mt-4 text-body-2 leading-relaxed text-grey-dark' }, 'Pick the closest wall shade, then preview Pallamart styles in a bedroom setting.')), createElement('div', {
|
|
12
|
+
className: 'rounded-[28px] border border-grey/15 bg-white p-4 shadow-sm sm:p-5',
|
|
13
|
+
}, createElement('div', { className: 'grid grid-cols-2 gap-2 sm:grid-cols-3' }, wallColors.map((wallColor) => {
|
|
14
|
+
const isActive = wallColor.colorHex === activeWallColorHex;
|
|
15
|
+
return createElement('button', {
|
|
16
|
+
'aria-pressed': isActive,
|
|
17
|
+
className: isActive
|
|
18
|
+
? 'studio-color-option border-black bg-black text-white'
|
|
19
|
+
: 'studio-color-option border-grey/20 bg-white text-black hover:border-grey/60 hover:bg-grey-light/50',
|
|
20
|
+
key: wallColor.id,
|
|
21
|
+
onClick: () => onColorChange(wallColor.colorHex),
|
|
22
|
+
type: 'button',
|
|
23
|
+
}, createElement('span', {
|
|
24
|
+
className: 'h-7 w-7 shrink-0 rounded-full border border-black/10',
|
|
25
|
+
style: { backgroundColor: wallColor.colorHex },
|
|
26
|
+
}), createElement('span', {
|
|
27
|
+
className: 'min-w-0 truncate text-body-3',
|
|
28
|
+
}, wallColor.label));
|
|
29
|
+
})))), createElement('div', {
|
|
30
|
+
className: 'mt-8 flex flex-col gap-4 border-t border-grey/15 pt-6 sm:flex-row sm:items-center sm:justify-between',
|
|
31
|
+
}, createElement('p', { className: 'min-w-0 truncate text-body-3 text-grey-dark' }, `Previewing ${productTitle}`), createElement('button', {
|
|
32
|
+
className: 'pallamart-btn-primary sm:min-w-56',
|
|
33
|
+
onClick: onContinue,
|
|
34
|
+
type: 'button',
|
|
35
|
+
}, 'Start preview')));
|
|
36
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ExternalWallColorData } from '../types.js';
|
|
2
|
+
interface ExternalWallColorControlProps {
|
|
3
|
+
activeWallColorHex: string;
|
|
4
|
+
wallColors: ExternalWallColorData[];
|
|
5
|
+
onColorChange: (colorHex: string) => void;
|
|
6
|
+
}
|
|
7
|
+
export default function ExternalWallColorControl({ activeWallColorHex, wallColors, onColorChange, }: ExternalWallColorControlProps): any;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createElement } from '../../create-element.js';
|
|
2
|
+
export default function ExternalWallColorControl({ activeWallColorHex, wallColors, onColorChange, }) {
|
|
3
|
+
const activeLabel = wallColors.find((color) => color.colorHex === activeWallColorHex)?.label ??
|
|
4
|
+
'Selected';
|
|
5
|
+
return createElement('div', { className: 'pm-external-room-tone' }, createElement('div', { className: 'pm-external-room-tone-header' }, createElement('span', { className: 'pm-external-room-tone-selected' }, createElement('span', {
|
|
6
|
+
className: 'pm-external-room-tone-preview',
|
|
7
|
+
style: { backgroundColor: activeWallColorHex },
|
|
8
|
+
}), createElement('span', { className: 'pm-external-room-tone-title' }, 'Room color')), createElement('span', { className: 'pm-external-room-tone-value' }, activeLabel)), createElement('div', { className: 'pm-external-room-tone-grid' }, wallColors.map((wallColor) => {
|
|
9
|
+
const isActive = wallColor.colorHex === activeWallColorHex;
|
|
10
|
+
return createElement('button', {
|
|
11
|
+
'aria-label': wallColor.label,
|
|
12
|
+
'aria-pressed': isActive,
|
|
13
|
+
className: isActive
|
|
14
|
+
? 'pm-external-room-tone-swatch active'
|
|
15
|
+
: 'pm-external-room-tone-swatch',
|
|
16
|
+
key: wallColor.id,
|
|
17
|
+
onClick: () => onColorChange(wallColor.colorHex),
|
|
18
|
+
title: wallColor.label,
|
|
19
|
+
type: 'button',
|
|
20
|
+
}, createElement('span', {
|
|
21
|
+
className: 'block h-full w-full rounded-full border border-black/10',
|
|
22
|
+
style: { backgroundColor: wallColor.colorHex },
|
|
23
|
+
}));
|
|
24
|
+
})));
|
|
25
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface StorefrontFooterNavigationItem {
|
|
2
|
+
label: string;
|
|
3
|
+
path: string;
|
|
4
|
+
}
|
|
5
|
+
interface StorefrontFooterProps {
|
|
6
|
+
items: StorefrontFooterNavigationItem[];
|
|
7
|
+
websiteUrl: string;
|
|
8
|
+
}
|
|
9
|
+
export default function StorefrontFooter({ items, websiteUrl, }: StorefrontFooterProps): any;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { UrlService } from '@pallamart/pm-utilities';
|
|
2
|
+
import { createElement } from '../create-element.js';
|
|
3
|
+
export default function StorefrontFooter({ items, websiteUrl, }) {
|
|
4
|
+
const websiteBaseUrl = UrlService.trimTrailingSlash(websiteUrl);
|
|
5
|
+
return createElement('footer', { className: 'mt-auto border-t border-grey/15 py-5' }, createElement('div', {
|
|
6
|
+
className: 'flex flex-wrap items-center justify-between gap-x-4 gap-y-3 text-body-3 text-grey-dark',
|
|
7
|
+
}, createElement('p', null, 'Simple Things, Better Living'), createElement('nav', { className: 'flex flex-wrap items-center gap-x-4 gap-y-2' }, items.map((item) => createElement('a', {
|
|
8
|
+
className: 'hover:text-black',
|
|
9
|
+
href: UrlService.join(websiteBaseUrl, item.path),
|
|
10
|
+
key: item.path,
|
|
11
|
+
}, item.label)))));
|
|
12
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { UrlService } from '@pallamart/pm-utilities';
|
|
2
|
+
import { createElement } from '../create-element.js';
|
|
3
|
+
export default function StorefrontHeader({ websiteUrl }) {
|
|
4
|
+
const websiteBaseUrl = UrlService.trimTrailingSlash(websiteUrl);
|
|
5
|
+
const bedsheetsUrl = UrlService.join(websiteBaseUrl, '/collections/bedsheets');
|
|
6
|
+
return createElement('header', { className: 'py-5 sm:py-7' }, createElement('div', {
|
|
7
|
+
className: 'mx-auto flex w-full max-w-screen-2xl items-center justify-between gap-3 rounded-full bg-white/90 px-2 py-2 shadow-[0_18px_50px_rgba(29,29,32,0.08)] backdrop-blur',
|
|
8
|
+
}, createElement('a', {
|
|
9
|
+
'aria-label': 'Pallamart home',
|
|
10
|
+
className: 'group inline-flex min-w-0 items-center gap-3 rounded-full px-2 py-1.5 transition-colors hover:bg-grey-light sm:px-3',
|
|
11
|
+
href: websiteBaseUrl,
|
|
12
|
+
}, createElement('img', {
|
|
13
|
+
alt: 'Pallamart logo',
|
|
14
|
+
className: 'h-8 w-auto object-contain transition-opacity group-hover:opacity-80 sm:h-9',
|
|
15
|
+
src: '/logo/svg/logo-512x.svg',
|
|
16
|
+
}), createElement('span', {
|
|
17
|
+
className: 'truncate text-body-2 text-black transition-colors group-hover:text-primary',
|
|
18
|
+
}, 'Try It Out')), createElement('nav', {
|
|
19
|
+
className: 'flex min-w-0 items-center justify-end gap-1 text-body-2 text-black sm:gap-2',
|
|
20
|
+
}, createElement('a', {
|
|
21
|
+
className: 'hidden rounded-full px-4 py-2 transition-colors hover:bg-grey-light hover:text-primary sm:inline-flex',
|
|
22
|
+
href: websiteBaseUrl,
|
|
23
|
+
}, 'Pallamart'), createElement('a', {
|
|
24
|
+
className: 'inline-flex min-h-10 items-center justify-center rounded-full bg-primary px-4 py-2 text-white transition-colors hover:bg-primary-hover sm:px-5',
|
|
25
|
+
href: bedsheetsUrl,
|
|
26
|
+
}, 'Shop bedding'))));
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface ExternalProductImageData {
|
|
2
|
+
url: string;
|
|
3
|
+
altText: string | null;
|
|
4
|
+
}
|
|
5
|
+
export interface ExternalProductPriceData {
|
|
6
|
+
amount: string;
|
|
7
|
+
currencyCode: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ExternalProductData {
|
|
10
|
+
id: string;
|
|
11
|
+
handle: string;
|
|
12
|
+
publishedAt: string | null;
|
|
13
|
+
title: string;
|
|
14
|
+
description: string;
|
|
15
|
+
descriptionHtml: string;
|
|
16
|
+
productType: string;
|
|
17
|
+
vendor: string;
|
|
18
|
+
tags: string[];
|
|
19
|
+
featuredImage: ExternalProductImageData | null;
|
|
20
|
+
minPrice: ExternalProductPriceData | null;
|
|
21
|
+
maxPrice: ExternalProductPriceData | null;
|
|
22
|
+
}
|
|
23
|
+
export interface ExternalWallColorData {
|
|
24
|
+
id: string;
|
|
25
|
+
label: string;
|
|
26
|
+
colorHex: string;
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export { default as DotLoader } from './loaders/dot-loader.js';
|
|
2
|
+
export { default as InlineLoader } from './loaders/inline-loader.js';
|
|
3
|
+
export { default as MicrosoftAuthButton } from './auth/microsoft-auth-button.js';
|
|
4
|
+
export { default as NotFoundUI } from './root/not-found-ui.js';
|
|
5
|
+
export { default as RootErrorUI } from './root/root-error-ui.js';
|
|
6
|
+
export { Alert, AlertDescription, AlertTitle } from './ui/alert.js';
|
|
7
|
+
export { Avatar, AvatarFallback, AvatarImage } from './ui/avatar.js';
|
|
8
|
+
export { AppHeader } from './ui/app-header.js';
|
|
9
|
+
export { Badge } from './ui/badge.js';
|
|
10
|
+
export { Breadcrumb, BreadcrumbItem, BreadcrumbList, BreadcrumbSeparator, } from './ui/breadcrumb.js';
|
|
11
|
+
export { Button, buttonVariants } from './ui/button.js';
|
|
12
|
+
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from './ui/card.js';
|
|
13
|
+
export { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogTitle, } from './ui/dialog.js';
|
|
14
|
+
export { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from './ui/dropdown-menu.js';
|
|
15
|
+
export { Empty, EmptyDescription, EmptyPanel, EmptyTitle } from './ui/empty.js';
|
|
16
|
+
export { Checkbox, DatePicker, Field, Input, Label, Radio, RadioGroup, Select, Switch, Textarea, } from './ui/form.js';
|
|
17
|
+
export { FilePicker } from './ui/file-picker.js';
|
|
18
|
+
export { IconButton } from './ui/icon-button.js';
|
|
19
|
+
export { AspectRatio, ButtonGroup, Kbd, Pagination, PaginationContent, PaginationItem, StatusPanel, } from './ui/misc.js';
|
|
20
|
+
export { Popover, PopoverContent, PopoverTrigger } from './ui/popover.js';
|
|
21
|
+
export { Progress } from './ui/progress.js';
|
|
22
|
+
export { Separator } from './ui/separator.js';
|
|
23
|
+
export { Skeleton } from './ui/skeleton.js';
|
|
24
|
+
export { Spinner } from './ui/spinner.js';
|
|
25
|
+
export { TabsList, TabsTrigger } from './ui/tabs.js';
|
|
26
|
+
export { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from './ui/table.js';
|
|
27
|
+
export { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export { default as DotLoader } from './loaders/dot-loader.js';
|
|
2
|
+
export { default as InlineLoader } from './loaders/inline-loader.js';
|
|
3
|
+
export { default as MicrosoftAuthButton } from './auth/microsoft-auth-button.js';
|
|
4
|
+
export { default as NotFoundUI } from './root/not-found-ui.js';
|
|
5
|
+
export { default as RootErrorUI } from './root/root-error-ui.js';
|
|
6
|
+
export { Alert, AlertDescription, AlertTitle } from './ui/alert.js';
|
|
7
|
+
export { Avatar, AvatarFallback, AvatarImage } from './ui/avatar.js';
|
|
8
|
+
export { AppHeader } from './ui/app-header.js';
|
|
9
|
+
export { Badge } from './ui/badge.js';
|
|
10
|
+
export { Breadcrumb, BreadcrumbItem, BreadcrumbList, BreadcrumbSeparator, } from './ui/breadcrumb.js';
|
|
11
|
+
export { Button, buttonVariants } from './ui/button.js';
|
|
12
|
+
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from './ui/card.js';
|
|
13
|
+
export { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogTitle, } from './ui/dialog.js';
|
|
14
|
+
export { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from './ui/dropdown-menu.js';
|
|
15
|
+
export { Empty, EmptyDescription, EmptyPanel, EmptyTitle } from './ui/empty.js';
|
|
16
|
+
export { Checkbox, DatePicker, Field, Input, Label, Radio, RadioGroup, Select, Switch, Textarea, } from './ui/form.js';
|
|
17
|
+
export { FilePicker } from './ui/file-picker.js';
|
|
18
|
+
export { IconButton } from './ui/icon-button.js';
|
|
19
|
+
export { AspectRatio, ButtonGroup, Kbd, Pagination, PaginationContent, PaginationItem, StatusPanel, } from './ui/misc.js';
|
|
20
|
+
export { Popover, PopoverContent, PopoverTrigger } from './ui/popover.js';
|
|
21
|
+
export { Progress } from './ui/progress.js';
|
|
22
|
+
export { Separator } from './ui/separator.js';
|
|
23
|
+
export { Skeleton } from './ui/skeleton.js';
|
|
24
|
+
export { Spinner } from './ui/spinner.js';
|
|
25
|
+
export { TabsList, TabsTrigger } from './ui/tabs.js';
|
|
26
|
+
export { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from './ui/table.js';
|
|
27
|
+
export { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function DotLoader(): any;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createElement } from '../create-element.js';
|
|
2
|
+
export default function DotLoader() {
|
|
3
|
+
return createElement('span', {
|
|
4
|
+
className: 'block h-4 w-4 animate-spin rounded-full border-2 border-muted-foreground border-t-transparent',
|
|
5
|
+
'aria-hidden': 'true',
|
|
6
|
+
});
|
|
7
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createElement } from '../create-element.js';
|
|
2
|
+
import DotLoader from './dot-loader.js';
|
|
3
|
+
export default function InlineLoader(props) {
|
|
4
|
+
return createElement('div', {
|
|
5
|
+
className: 'mt-4 flex items-center gap-4 text-body-3 text-muted-foreground',
|
|
6
|
+
'aria-live': 'polite',
|
|
7
|
+
}, createElement('span', {
|
|
8
|
+
className: 'inline-flex h-7 w-10 shrink-0 items-center justify-center',
|
|
9
|
+
}, createElement(DotLoader, null)), createElement('span', { className: 'min-w-0 leading-relaxed' }, props.label ?? 'Generating images...'));
|
|
10
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createElement } from '../create-element.js';
|
|
2
|
+
export default function NotFoundUI(props) {
|
|
3
|
+
return createElement('section', {
|
|
4
|
+
className: 'flex min-h-[55vh] w-full items-center justify-center px-4 py-10 sm:px-6',
|
|
5
|
+
}, createElement('div', {
|
|
6
|
+
className: 'w-full max-w-xl text-card-foreground',
|
|
7
|
+
}, createElement('p', { className: 'text-body-3 text-muted-foreground' }, '404'), createElement('h1', { className: 'mt-2 text-header-2 tracking-tight text-card-foreground' }, 'This page does not exist'), createElement('p', {
|
|
8
|
+
className: 'mt-3 max-w-xl text-body-3 leading-6 text-muted-foreground',
|
|
9
|
+
}, 'The page you are looking for does not exist or may have moved.'), createElement('div', {
|
|
10
|
+
className: 'mt-6 flex flex-col gap-3 sm:flex-row',
|
|
11
|
+
}, createElement('a', {
|
|
12
|
+
id: 'go-to-home-link',
|
|
13
|
+
href: props.homePath ?? '/',
|
|
14
|
+
'aria-label': 'Go to Home',
|
|
15
|
+
className: 'inline-flex h-10 w-full items-center justify-center rounded-md bg-primary px-4 py-2 text-body-3 text-primary-foreground shadow transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:w-auto',
|
|
16
|
+
}, 'Go to Home'), createElement('button', {
|
|
17
|
+
id: 'go-back-button',
|
|
18
|
+
type: 'button',
|
|
19
|
+
className: 'inline-flex h-10 w-full items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-body-3 shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:w-auto',
|
|
20
|
+
'aria-label': 'Go Back',
|
|
21
|
+
onClick: () => {
|
|
22
|
+
window.history.back();
|
|
23
|
+
},
|
|
24
|
+
}, 'Go Back'))));
|
|
25
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createElement } from '../create-element.js';
|
|
2
|
+
export default function RootErrorUI(props) {
|
|
3
|
+
const refresh = () => {
|
|
4
|
+
window.location.reload();
|
|
5
|
+
};
|
|
6
|
+
return createElement('section', {
|
|
7
|
+
className: 'flex min-h-[55vh] w-full items-center justify-center px-4 py-10 sm:px-6',
|
|
8
|
+
}, createElement('div', {
|
|
9
|
+
className: 'w-full max-w-xl text-card-foreground',
|
|
10
|
+
}, createElement('p', { className: 'text-body-3 text-muted-foreground' }, `Error ${props.code}`), createElement('h1', { className: 'mt-2 text-header-2 tracking-tight text-card-foreground' }, 'Unable to load this screen'), createElement('p', {
|
|
11
|
+
className: 'mt-3 max-w-xl text-body-3 leading-6 text-muted-foreground',
|
|
12
|
+
}, props.message ||
|
|
13
|
+
'Refresh the page. If it keeps happening, return home and try again.'), createElement('div', {
|
|
14
|
+
className: 'mt-6 flex flex-col gap-3 sm:flex-row',
|
|
15
|
+
}, createElement('button', {
|
|
16
|
+
id: 'refresh-button',
|
|
17
|
+
type: 'button',
|
|
18
|
+
onClick: refresh,
|
|
19
|
+
className: 'inline-flex h-10 w-full items-center justify-center rounded-md bg-primary px-4 py-2 text-body-3 text-primary-foreground shadow-sm transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:w-auto',
|
|
20
|
+
}, 'Refresh'), createElement('button', {
|
|
21
|
+
id: 'go-home-button',
|
|
22
|
+
type: 'button',
|
|
23
|
+
onClick: () => {
|
|
24
|
+
window.location.assign(props.homePath ?? '/');
|
|
25
|
+
},
|
|
26
|
+
className: 'inline-flex h-10 w-full items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-body-3 shadow-sm transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring sm:w-auto',
|
|
27
|
+
}, 'Go to Home'))));
|
|
28
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
type AlertVariant = 'default' | 'destructive' | 'success';
|
|
3
|
+
export declare function Alert({ className, variant, ...props }: React.HTMLAttributes<HTMLDivElement> & {
|
|
4
|
+
variant?: AlertVariant;
|
|
5
|
+
}): any;
|
|
6
|
+
export declare function AlertTitle({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>): any;
|
|
7
|
+
export declare function AlertDescription({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): any;
|
|
8
|
+
export {};
|