@lasterp/shared 1.0.0-alpha.11 → 1.0.0-alpha.13
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/dist/node/index.d.ts +112 -67
- package/dist/node/index.js +81 -0
- package/dist/rn/index.d.ts +112 -67
- package/dist/rn/index.js +81 -0
- package/package.json +1 -1
package/dist/node/index.d.ts
CHANGED
|
@@ -24,6 +24,79 @@ interface Colour {
|
|
|
24
24
|
hex: string;
|
|
25
25
|
color_system: string;
|
|
26
26
|
}
|
|
27
|
+
interface Globals {
|
|
28
|
+
header: Header;
|
|
29
|
+
footer: Footer;
|
|
30
|
+
}
|
|
31
|
+
interface Brand {
|
|
32
|
+
brandImage?: string;
|
|
33
|
+
}
|
|
34
|
+
interface NavbarItem {
|
|
35
|
+
label: string;
|
|
36
|
+
enableDropdown: boolean;
|
|
37
|
+
enableLink: boolean;
|
|
38
|
+
link?: string;
|
|
39
|
+
dropdownDescription?: string;
|
|
40
|
+
dropdownCTALabel?: string;
|
|
41
|
+
dropdownCTALink?: string;
|
|
42
|
+
groups?: NavbarSubItemGroup[];
|
|
43
|
+
}
|
|
44
|
+
interface NavbarSubItemGroup {
|
|
45
|
+
title: string;
|
|
46
|
+
items: NavbarSubItem[];
|
|
47
|
+
}
|
|
48
|
+
interface NavbarSubItem {
|
|
49
|
+
label: string;
|
|
50
|
+
description?: string;
|
|
51
|
+
image?: string;
|
|
52
|
+
link?: string;
|
|
53
|
+
}
|
|
54
|
+
interface Topbar {
|
|
55
|
+
enabled: boolean;
|
|
56
|
+
layout: string;
|
|
57
|
+
items: TopbarItem[];
|
|
58
|
+
}
|
|
59
|
+
interface TopbarItem {
|
|
60
|
+
icon?: string;
|
|
61
|
+
label: string;
|
|
62
|
+
link?: string;
|
|
63
|
+
}
|
|
64
|
+
interface Header {
|
|
65
|
+
headerType?: string;
|
|
66
|
+
brand: Brand;
|
|
67
|
+
tabs: NavbarItem[];
|
|
68
|
+
topbar: Topbar;
|
|
69
|
+
}
|
|
70
|
+
interface FooterItemGroup {
|
|
71
|
+
title: string;
|
|
72
|
+
items: FooterItem[];
|
|
73
|
+
}
|
|
74
|
+
interface FooterItem {
|
|
75
|
+
label: string;
|
|
76
|
+
link?: string;
|
|
77
|
+
}
|
|
78
|
+
interface Footer {
|
|
79
|
+
footerType?: string;
|
|
80
|
+
groups: FooterItemGroup[];
|
|
81
|
+
copyright?: string;
|
|
82
|
+
address?: string;
|
|
83
|
+
country?: string;
|
|
84
|
+
phone?: string;
|
|
85
|
+
email?: string;
|
|
86
|
+
}
|
|
87
|
+
interface Hero {
|
|
88
|
+
type: string;
|
|
89
|
+
data: Record<string, unknown>;
|
|
90
|
+
}
|
|
91
|
+
interface Block {
|
|
92
|
+
type: string;
|
|
93
|
+
data: Record<string, unknown>;
|
|
94
|
+
}
|
|
95
|
+
interface Page {
|
|
96
|
+
slug: string;
|
|
97
|
+
hero?: Hero;
|
|
98
|
+
blocks: Block[];
|
|
99
|
+
}
|
|
27
100
|
import { FrappeApp, FrappeAuth, FrappeCall } from "frappe-js-sdk";
|
|
28
101
|
import { FrappeDB } from "frappe-js-sdk/lib/db";
|
|
29
102
|
import { FrappeFileUpload } from "frappe-js-sdk/lib/file";
|
|
@@ -513,79 +586,51 @@ declare const useFrappeUpdateDoc: <T = any>() => {
|
|
|
513
586
|
isCompleted: boolean;
|
|
514
587
|
reset: () => void;
|
|
515
588
|
};
|
|
516
|
-
interface
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
enableLink: boolean;
|
|
527
|
-
link?: string;
|
|
528
|
-
dropdownDescription?: string;
|
|
529
|
-
dropdownCTALabel?: string;
|
|
530
|
-
dropdownCTALink?: string;
|
|
531
|
-
groups?: NavbarSubItemGroup[];
|
|
532
|
-
}
|
|
533
|
-
interface NavbarSubItemGroup {
|
|
534
|
-
title: string;
|
|
535
|
-
items: NavbarSubItem[];
|
|
536
|
-
}
|
|
537
|
-
interface NavbarSubItem {
|
|
538
|
-
label: string;
|
|
539
|
-
description?: string;
|
|
540
|
-
image?: string;
|
|
541
|
-
link?: string;
|
|
589
|
+
interface VariantSelectorProps<T extends {
|
|
590
|
+
id: string;
|
|
591
|
+
specs: Record<string, string>;
|
|
592
|
+
}> {
|
|
593
|
+
variants: T[];
|
|
594
|
+
attributes: {
|
|
595
|
+
key: string;
|
|
596
|
+
values: string[];
|
|
597
|
+
}[];
|
|
598
|
+
defaultId?: string;
|
|
542
599
|
}
|
|
543
|
-
interface
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
}
|
|
548
|
-
interface TopbarItem {
|
|
549
|
-
icon?: string;
|
|
550
|
-
label: string;
|
|
551
|
-
link?: string;
|
|
552
|
-
}
|
|
553
|
-
interface Header {
|
|
554
|
-
headerType?: string;
|
|
555
|
-
brand: Brand;
|
|
556
|
-
tabs: NavbarItem[];
|
|
557
|
-
topbar: Topbar;
|
|
558
|
-
}
|
|
559
|
-
interface FooterItemGroup {
|
|
560
|
-
title: string;
|
|
561
|
-
items: FooterItem[];
|
|
600
|
+
interface VariantSelectorOption {
|
|
601
|
+
key: string;
|
|
602
|
+
value: string;
|
|
603
|
+
state: "selected" | "available" | "unavailable";
|
|
562
604
|
}
|
|
563
|
-
interface
|
|
564
|
-
|
|
565
|
-
|
|
605
|
+
interface VariantSelectorResult {
|
|
606
|
+
variantId?: string;
|
|
607
|
+
onOptionSelect: (option: VariantSelectorOption) => void;
|
|
608
|
+
getOptions: (key: string) => VariantSelectorOption[];
|
|
566
609
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
phone?: string;
|
|
574
|
-
email?: string;
|
|
610
|
+
declare const useVariantSelector: <T extends {
|
|
611
|
+
id: string;
|
|
612
|
+
specs: Record<string, string>;
|
|
613
|
+
}>(props: VariantSelectorProps<T>) => VariantSelectorResult;
|
|
614
|
+
interface Category {
|
|
615
|
+
name: string;
|
|
575
616
|
}
|
|
576
|
-
interface
|
|
577
|
-
|
|
578
|
-
|
|
617
|
+
interface Product {
|
|
618
|
+
item_code: string;
|
|
619
|
+
description: string;
|
|
579
620
|
}
|
|
580
|
-
interface
|
|
581
|
-
|
|
582
|
-
|
|
621
|
+
interface ProductVariant extends ItemVariant {
|
|
622
|
+
product: string;
|
|
623
|
+
currency: string;
|
|
624
|
+
rate: number;
|
|
625
|
+
qty: number;
|
|
583
626
|
}
|
|
584
|
-
interface
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
627
|
+
interface ShopContext {
|
|
628
|
+
categories: Category[];
|
|
629
|
+
grades: string[];
|
|
630
|
+
selected_category?: Category;
|
|
631
|
+
selected_grade?: string;
|
|
632
|
+
products: Product[];
|
|
588
633
|
}
|
|
589
634
|
import { camelize, decamelize, camelizeKeys, decamelizeKeys } from "humps";
|
|
590
635
|
declare function equalsIgnoreCase(str1: string, str2: string): boolean;
|
|
591
|
-
export { useSearch, useFrappeUpdateDoc, useFrappePutCall, useFrappePrefetchDoc, useFrappePostCall, useFrappeGetDocList, useFrappeGetDocCount, useFrappeGetDoc, useFrappeGetCall, useFrappeFileUpload, useFrappeEventListener, useFrappeDocumentEventListener, useFrappeDocTypeEventListener, useFrappeDeleteDoc, useFrappeDeleteCall, useFrappeCreateDoc, useFrappeAuth, equalsIgnoreCase, decamelizeKeys, decamelize, camelizeKeys, camelize, ViewerEventData, UseFrappeFileUploadReturnType, TopbarItem, Topbar, TokenParams, SearchResult, Page, NavbarSubItemGroup, NavbarSubItem, NavbarItem, Model, ItemVariant, Item, Hero, Header, Globals, FrappeProviderProps, FrappeProvider, FrappeMutationResult, FrappeFileUploadResponse, FrappeError, FrappeContext, FrappeConfig, FooterItemGroup, FooterItem, Footer, DocumentUpdateEventData, DocTypeListUpdateEventData, Colour, Brand, Block };
|
|
636
|
+
export { useVariantSelector, useSearch, useFrappeUpdateDoc, useFrappePutCall, useFrappePrefetchDoc, useFrappePostCall, useFrappeGetDocList, useFrappeGetDocCount, useFrappeGetDoc, useFrappeGetCall, useFrappeFileUpload, useFrappeEventListener, useFrappeDocumentEventListener, useFrappeDocTypeEventListener, useFrappeDeleteDoc, useFrappeDeleteCall, useFrappeCreateDoc, useFrappeAuth, equalsIgnoreCase, decamelizeKeys, decamelize, camelizeKeys, camelize, ViewerEventData, VariantSelectorResult, VariantSelectorProps, VariantSelectorOption, UseFrappeFileUploadReturnType, TopbarItem, Topbar, TokenParams, ShopContext, SearchResult, ProductVariant, Product, Page, NavbarSubItemGroup, NavbarSubItem, NavbarItem, Model, ItemVariant, Item, Hero, Header, Globals, FrappeProviderProps, FrappeProvider, FrappeMutationResult, FrappeFileUploadResponse, FrappeError, FrappeContext, FrappeConfig, FooterItemGroup, FooterItem, Footer, DocumentUpdateEventData, DocTypeListUpdateEventData, Colour, Category, Brand, Block };
|
package/dist/node/index.js
CHANGED
|
@@ -465,12 +465,93 @@ var useFrappeUpdateDoc = () => {
|
|
|
465
465
|
reset
|
|
466
466
|
};
|
|
467
467
|
};
|
|
468
|
+
// src/hooks/use-variant-selector/hook.ts
|
|
469
|
+
import { useCallback as useCallback4, useMemo as useMemo2, useState as useState5 } from "react";
|
|
470
|
+
|
|
471
|
+
// src/hooks/use-variant-selector/utils.ts
|
|
472
|
+
function findVariant(variants, specs, caseInsensitive) {
|
|
473
|
+
return variants.find((variant) => {
|
|
474
|
+
return Object.entries(specs).every(([key, value]) => {
|
|
475
|
+
const vv = variant.specs[key];
|
|
476
|
+
if (!vv)
|
|
477
|
+
return false;
|
|
478
|
+
if (caseInsensitive) {
|
|
479
|
+
return vv.toLowerCase() === value.toLowerCase();
|
|
480
|
+
}
|
|
481
|
+
return vv === value;
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
function findVariants(variants, specs, caseInsensitive) {
|
|
486
|
+
return variants.filter((variant) => {
|
|
487
|
+
return Object.entries(specs).every(([key, value]) => {
|
|
488
|
+
const vv = variant.specs[key];
|
|
489
|
+
if (!vv)
|
|
490
|
+
return false;
|
|
491
|
+
if (caseInsensitive) {
|
|
492
|
+
return vv.toLowerCase() === value.toLowerCase();
|
|
493
|
+
}
|
|
494
|
+
return vv === value;
|
|
495
|
+
});
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// src/hooks/use-variant-selector/hook.ts
|
|
500
|
+
var useVariantSelector = (props) => {
|
|
501
|
+
const { variants, attributes, defaultId } = props;
|
|
502
|
+
const [selectedSpecs, setSelectedSpecs] = useState5(() => {
|
|
503
|
+
if (defaultId) {
|
|
504
|
+
const variant = variants.find((v) => v.id === defaultId);
|
|
505
|
+
return variant?.specs || {};
|
|
506
|
+
}
|
|
507
|
+
return {};
|
|
508
|
+
});
|
|
509
|
+
const variantId = useMemo2(() => {
|
|
510
|
+
const complete = attributes.every((attr) => selectedSpecs[attr.key]);
|
|
511
|
+
if (!complete)
|
|
512
|
+
return;
|
|
513
|
+
const variant = findVariant(variants, selectedSpecs);
|
|
514
|
+
return variant?.id;
|
|
515
|
+
}, [variants, selectedSpecs, attributes]);
|
|
516
|
+
const options = useMemo2(() => {
|
|
517
|
+
const result = {};
|
|
518
|
+
attributes.forEach((attr) => {
|
|
519
|
+
result[attr.key] = attr.values.map((value) => {
|
|
520
|
+
const isSelected = selectedSpecs[attr.key] === value;
|
|
521
|
+
const specs = { ...selectedSpecs };
|
|
522
|
+
delete specs[attr.key];
|
|
523
|
+
const matchingVariants = findVariants(variants, specs);
|
|
524
|
+
const availableValuesForAttr = new Set(matchingVariants.map((v) => v.specs[attr.key]));
|
|
525
|
+
const isAvailable = availableValuesForAttr.has(value);
|
|
526
|
+
return {
|
|
527
|
+
key: attr.key,
|
|
528
|
+
value,
|
|
529
|
+
state: isSelected ? "selected" : isAvailable ? "available" : "unavailable"
|
|
530
|
+
};
|
|
531
|
+
});
|
|
532
|
+
});
|
|
533
|
+
return result;
|
|
534
|
+
}, [variants, attributes, selectedSpecs]);
|
|
535
|
+
const onOptionSelect = useCallback4((option) => {
|
|
536
|
+
setSelectedSpecs((prev) => {
|
|
537
|
+
const specs = { ...prev };
|
|
538
|
+
specs[option.key] = option.value;
|
|
539
|
+
return specs;
|
|
540
|
+
});
|
|
541
|
+
}, []);
|
|
542
|
+
return {
|
|
543
|
+
variantId,
|
|
544
|
+
onOptionSelect,
|
|
545
|
+
getOptions: (key) => options[key] || []
|
|
546
|
+
};
|
|
547
|
+
};
|
|
468
548
|
// src/utils/char.ts
|
|
469
549
|
import { camelize, decamelize, camelizeKeys, decamelizeKeys } from "humps";
|
|
470
550
|
function equalsIgnoreCase(str1, str2) {
|
|
471
551
|
return str1.localeCompare(str2, undefined, { sensitivity: "accent" }) === 0;
|
|
472
552
|
}
|
|
473
553
|
export {
|
|
554
|
+
useVariantSelector,
|
|
474
555
|
useSearch,
|
|
475
556
|
useFrappeUpdateDoc,
|
|
476
557
|
useFrappePutCall,
|
package/dist/rn/index.d.ts
CHANGED
|
@@ -24,6 +24,79 @@ interface Colour {
|
|
|
24
24
|
hex: string;
|
|
25
25
|
color_system: string;
|
|
26
26
|
}
|
|
27
|
+
interface Globals {
|
|
28
|
+
header: Header;
|
|
29
|
+
footer: Footer;
|
|
30
|
+
}
|
|
31
|
+
interface Brand {
|
|
32
|
+
brandImage?: string;
|
|
33
|
+
}
|
|
34
|
+
interface NavbarItem {
|
|
35
|
+
label: string;
|
|
36
|
+
enableDropdown: boolean;
|
|
37
|
+
enableLink: boolean;
|
|
38
|
+
link?: string;
|
|
39
|
+
dropdownDescription?: string;
|
|
40
|
+
dropdownCTALabel?: string;
|
|
41
|
+
dropdownCTALink?: string;
|
|
42
|
+
groups?: NavbarSubItemGroup[];
|
|
43
|
+
}
|
|
44
|
+
interface NavbarSubItemGroup {
|
|
45
|
+
title: string;
|
|
46
|
+
items: NavbarSubItem[];
|
|
47
|
+
}
|
|
48
|
+
interface NavbarSubItem {
|
|
49
|
+
label: string;
|
|
50
|
+
description?: string;
|
|
51
|
+
image?: string;
|
|
52
|
+
link?: string;
|
|
53
|
+
}
|
|
54
|
+
interface Topbar {
|
|
55
|
+
enabled: boolean;
|
|
56
|
+
layout: string;
|
|
57
|
+
items: TopbarItem[];
|
|
58
|
+
}
|
|
59
|
+
interface TopbarItem {
|
|
60
|
+
icon?: string;
|
|
61
|
+
label: string;
|
|
62
|
+
link?: string;
|
|
63
|
+
}
|
|
64
|
+
interface Header {
|
|
65
|
+
headerType?: string;
|
|
66
|
+
brand: Brand;
|
|
67
|
+
tabs: NavbarItem[];
|
|
68
|
+
topbar: Topbar;
|
|
69
|
+
}
|
|
70
|
+
interface FooterItemGroup {
|
|
71
|
+
title: string;
|
|
72
|
+
items: FooterItem[];
|
|
73
|
+
}
|
|
74
|
+
interface FooterItem {
|
|
75
|
+
label: string;
|
|
76
|
+
link?: string;
|
|
77
|
+
}
|
|
78
|
+
interface Footer {
|
|
79
|
+
footerType?: string;
|
|
80
|
+
groups: FooterItemGroup[];
|
|
81
|
+
copyright?: string;
|
|
82
|
+
address?: string;
|
|
83
|
+
country?: string;
|
|
84
|
+
phone?: string;
|
|
85
|
+
email?: string;
|
|
86
|
+
}
|
|
87
|
+
interface Hero {
|
|
88
|
+
type: string;
|
|
89
|
+
data: Record<string, unknown>;
|
|
90
|
+
}
|
|
91
|
+
interface Block {
|
|
92
|
+
type: string;
|
|
93
|
+
data: Record<string, unknown>;
|
|
94
|
+
}
|
|
95
|
+
interface Page {
|
|
96
|
+
slug: string;
|
|
97
|
+
hero?: Hero;
|
|
98
|
+
blocks: Block[];
|
|
99
|
+
}
|
|
27
100
|
import { FrappeApp, FrappeAuth, FrappeCall } from "frappe-js-sdk";
|
|
28
101
|
import { FrappeDB } from "frappe-js-sdk/lib/db";
|
|
29
102
|
import { FrappeFileUpload } from "frappe-js-sdk/lib/file";
|
|
@@ -513,79 +586,51 @@ declare const useFrappeUpdateDoc: <T = any>() => {
|
|
|
513
586
|
isCompleted: boolean;
|
|
514
587
|
reset: () => void;
|
|
515
588
|
};
|
|
516
|
-
interface
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
enableLink: boolean;
|
|
527
|
-
link?: string;
|
|
528
|
-
dropdownDescription?: string;
|
|
529
|
-
dropdownCTALabel?: string;
|
|
530
|
-
dropdownCTALink?: string;
|
|
531
|
-
groups?: NavbarSubItemGroup[];
|
|
532
|
-
}
|
|
533
|
-
interface NavbarSubItemGroup {
|
|
534
|
-
title: string;
|
|
535
|
-
items: NavbarSubItem[];
|
|
536
|
-
}
|
|
537
|
-
interface NavbarSubItem {
|
|
538
|
-
label: string;
|
|
539
|
-
description?: string;
|
|
540
|
-
image?: string;
|
|
541
|
-
link?: string;
|
|
589
|
+
interface VariantSelectorProps<T extends {
|
|
590
|
+
id: string;
|
|
591
|
+
specs: Record<string, string>;
|
|
592
|
+
}> {
|
|
593
|
+
variants: T[];
|
|
594
|
+
attributes: {
|
|
595
|
+
key: string;
|
|
596
|
+
values: string[];
|
|
597
|
+
}[];
|
|
598
|
+
defaultId?: string;
|
|
542
599
|
}
|
|
543
|
-
interface
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
}
|
|
548
|
-
interface TopbarItem {
|
|
549
|
-
icon?: string;
|
|
550
|
-
label: string;
|
|
551
|
-
link?: string;
|
|
552
|
-
}
|
|
553
|
-
interface Header {
|
|
554
|
-
headerType?: string;
|
|
555
|
-
brand: Brand;
|
|
556
|
-
tabs: NavbarItem[];
|
|
557
|
-
topbar: Topbar;
|
|
558
|
-
}
|
|
559
|
-
interface FooterItemGroup {
|
|
560
|
-
title: string;
|
|
561
|
-
items: FooterItem[];
|
|
600
|
+
interface VariantSelectorOption {
|
|
601
|
+
key: string;
|
|
602
|
+
value: string;
|
|
603
|
+
state: "selected" | "available" | "unavailable";
|
|
562
604
|
}
|
|
563
|
-
interface
|
|
564
|
-
|
|
565
|
-
|
|
605
|
+
interface VariantSelectorResult {
|
|
606
|
+
variantId?: string;
|
|
607
|
+
onOptionSelect: (option: VariantSelectorOption) => void;
|
|
608
|
+
getOptions: (key: string) => VariantSelectorOption[];
|
|
566
609
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
phone?: string;
|
|
574
|
-
email?: string;
|
|
610
|
+
declare const useVariantSelector: <T extends {
|
|
611
|
+
id: string;
|
|
612
|
+
specs: Record<string, string>;
|
|
613
|
+
}>(props: VariantSelectorProps<T>) => VariantSelectorResult;
|
|
614
|
+
interface Category {
|
|
615
|
+
name: string;
|
|
575
616
|
}
|
|
576
|
-
interface
|
|
577
|
-
|
|
578
|
-
|
|
617
|
+
interface Product {
|
|
618
|
+
item_code: string;
|
|
619
|
+
description: string;
|
|
579
620
|
}
|
|
580
|
-
interface
|
|
581
|
-
|
|
582
|
-
|
|
621
|
+
interface ProductVariant extends ItemVariant {
|
|
622
|
+
product: string;
|
|
623
|
+
currency: string;
|
|
624
|
+
rate: number;
|
|
625
|
+
qty: number;
|
|
583
626
|
}
|
|
584
|
-
interface
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
627
|
+
interface ShopContext {
|
|
628
|
+
categories: Category[];
|
|
629
|
+
grades: string[];
|
|
630
|
+
selected_category?: Category;
|
|
631
|
+
selected_grade?: string;
|
|
632
|
+
products: Product[];
|
|
588
633
|
}
|
|
589
634
|
import { camelize, decamelize, camelizeKeys, decamelizeKeys } from "humps";
|
|
590
635
|
declare function equalsIgnoreCase(str1: string, str2: string): boolean;
|
|
591
|
-
export { useSearch, useFrappeUpdateDoc, useFrappePutCall, useFrappePrefetchDoc, useFrappePostCall, useFrappeGetDocList, useFrappeGetDocCount, useFrappeGetDoc, useFrappeGetCall, useFrappeFileUpload, useFrappeEventListener, useFrappeDocumentEventListener, useFrappeDocTypeEventListener, useFrappeDeleteDoc, useFrappeDeleteCall, useFrappeCreateDoc, useFrappeAuth, equalsIgnoreCase, decamelizeKeys, decamelize, camelizeKeys, camelize, ViewerEventData, UseFrappeFileUploadReturnType, TopbarItem, Topbar, TokenParams, SearchResult, Page, NavbarSubItemGroup, NavbarSubItem, NavbarItem, Model, ItemVariant, Item, Hero, Header, Globals, FrappeProviderProps, FrappeProvider, FrappeMutationResult, FrappeFileUploadResponse, FrappeError, FrappeContext, FrappeConfig, FooterItemGroup, FooterItem, Footer, DocumentUpdateEventData, DocTypeListUpdateEventData, Colour, Brand, Block };
|
|
636
|
+
export { useVariantSelector, useSearch, useFrappeUpdateDoc, useFrappePutCall, useFrappePrefetchDoc, useFrappePostCall, useFrappeGetDocList, useFrappeGetDocCount, useFrappeGetDoc, useFrappeGetCall, useFrappeFileUpload, useFrappeEventListener, useFrappeDocumentEventListener, useFrappeDocTypeEventListener, useFrappeDeleteDoc, useFrappeDeleteCall, useFrappeCreateDoc, useFrappeAuth, equalsIgnoreCase, decamelizeKeys, decamelize, camelizeKeys, camelize, ViewerEventData, VariantSelectorResult, VariantSelectorProps, VariantSelectorOption, UseFrappeFileUploadReturnType, TopbarItem, Topbar, TokenParams, ShopContext, SearchResult, ProductVariant, Product, Page, NavbarSubItemGroup, NavbarSubItem, NavbarItem, Model, ItemVariant, Item, Hero, Header, Globals, FrappeProviderProps, FrappeProvider, FrappeMutationResult, FrappeFileUploadResponse, FrappeError, FrappeContext, FrappeConfig, FooterItemGroup, FooterItem, Footer, DocumentUpdateEventData, DocTypeListUpdateEventData, Colour, Category, Brand, Block };
|
package/dist/rn/index.js
CHANGED
|
@@ -465,12 +465,93 @@ var useFrappeUpdateDoc = () => {
|
|
|
465
465
|
reset
|
|
466
466
|
};
|
|
467
467
|
};
|
|
468
|
+
// src/hooks/use-variant-selector/hook.ts
|
|
469
|
+
import { useCallback as useCallback4, useMemo as useMemo2, useState as useState5 } from "react";
|
|
470
|
+
|
|
471
|
+
// src/hooks/use-variant-selector/utils.ts
|
|
472
|
+
function findVariant(variants, specs, caseInsensitive) {
|
|
473
|
+
return variants.find((variant) => {
|
|
474
|
+
return Object.entries(specs).every(([key, value]) => {
|
|
475
|
+
const vv = variant.specs[key];
|
|
476
|
+
if (!vv)
|
|
477
|
+
return false;
|
|
478
|
+
if (caseInsensitive) {
|
|
479
|
+
return vv.toLowerCase() === value.toLowerCase();
|
|
480
|
+
}
|
|
481
|
+
return vv === value;
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
function findVariants(variants, specs, caseInsensitive) {
|
|
486
|
+
return variants.filter((variant) => {
|
|
487
|
+
return Object.entries(specs).every(([key, value]) => {
|
|
488
|
+
const vv = variant.specs[key];
|
|
489
|
+
if (!vv)
|
|
490
|
+
return false;
|
|
491
|
+
if (caseInsensitive) {
|
|
492
|
+
return vv.toLowerCase() === value.toLowerCase();
|
|
493
|
+
}
|
|
494
|
+
return vv === value;
|
|
495
|
+
});
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// src/hooks/use-variant-selector/hook.ts
|
|
500
|
+
var useVariantSelector = (props) => {
|
|
501
|
+
const { variants, attributes, defaultId } = props;
|
|
502
|
+
const [selectedSpecs, setSelectedSpecs] = useState5(() => {
|
|
503
|
+
if (defaultId) {
|
|
504
|
+
const variant = variants.find((v) => v.id === defaultId);
|
|
505
|
+
return variant?.specs || {};
|
|
506
|
+
}
|
|
507
|
+
return {};
|
|
508
|
+
});
|
|
509
|
+
const variantId = useMemo2(() => {
|
|
510
|
+
const complete = attributes.every((attr) => selectedSpecs[attr.key]);
|
|
511
|
+
if (!complete)
|
|
512
|
+
return;
|
|
513
|
+
const variant = findVariant(variants, selectedSpecs);
|
|
514
|
+
return variant?.id;
|
|
515
|
+
}, [variants, selectedSpecs, attributes]);
|
|
516
|
+
const options = useMemo2(() => {
|
|
517
|
+
const result = {};
|
|
518
|
+
attributes.forEach((attr) => {
|
|
519
|
+
result[attr.key] = attr.values.map((value) => {
|
|
520
|
+
const isSelected = selectedSpecs[attr.key] === value;
|
|
521
|
+
const specs = { ...selectedSpecs };
|
|
522
|
+
delete specs[attr.key];
|
|
523
|
+
const matchingVariants = findVariants(variants, specs);
|
|
524
|
+
const availableValuesForAttr = new Set(matchingVariants.map((v) => v.specs[attr.key]));
|
|
525
|
+
const isAvailable = availableValuesForAttr.has(value);
|
|
526
|
+
return {
|
|
527
|
+
key: attr.key,
|
|
528
|
+
value,
|
|
529
|
+
state: isSelected ? "selected" : isAvailable ? "available" : "unavailable"
|
|
530
|
+
};
|
|
531
|
+
});
|
|
532
|
+
});
|
|
533
|
+
return result;
|
|
534
|
+
}, [variants, attributes, selectedSpecs]);
|
|
535
|
+
const onOptionSelect = useCallback4((option) => {
|
|
536
|
+
setSelectedSpecs((prev) => {
|
|
537
|
+
const specs = { ...prev };
|
|
538
|
+
specs[option.key] = option.value;
|
|
539
|
+
return specs;
|
|
540
|
+
});
|
|
541
|
+
}, []);
|
|
542
|
+
return {
|
|
543
|
+
variantId,
|
|
544
|
+
onOptionSelect,
|
|
545
|
+
getOptions: (key) => options[key] || []
|
|
546
|
+
};
|
|
547
|
+
};
|
|
468
548
|
// src/utils/char.ts
|
|
469
549
|
import { camelize, decamelize, camelizeKeys, decamelizeKeys } from "humps";
|
|
470
550
|
function equalsIgnoreCase(str1, str2) {
|
|
471
551
|
return str1.localeCompare(str2, undefined, { sensitivity: "accent" }) === 0;
|
|
472
552
|
}
|
|
473
553
|
export {
|
|
554
|
+
useVariantSelector,
|
|
474
555
|
useSearch,
|
|
475
556
|
useFrappeUpdateDoc,
|
|
476
557
|
useFrappePutCall,
|