pricing-renderer 0.1.0 → 0.2.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/CHANGELOG.md +133 -0
- package/README.md +142 -25
- package/THIRD_PARTY_NOTICES.md +84 -6
- package/custom-elements.json +233 -3
- package/dist/core/apply-selection.d.ts +8 -0
- package/dist/core/apply-selection.d.ts.map +1 -0
- package/dist/core/apply-selection.js +76 -0
- package/dist/core/apply-selection.js.map +1 -0
- package/dist/core/breakdown.d.ts +13 -0
- package/dist/core/breakdown.d.ts.map +1 -0
- package/dist/core/breakdown.js +56 -0
- package/dist/core/breakdown.js.map +1 -0
- package/dist/core/compare-sides.d.ts +16 -0
- package/dist/core/compare-sides.d.ts.map +1 -0
- package/dist/core/compare-sides.js +73 -0
- package/dist/core/compare-sides.js.map +1 -0
- package/dist/core/compare-values.d.ts +13 -0
- package/dist/core/compare-values.d.ts.map +1 -0
- package/dist/core/compare-values.js +100 -0
- package/dist/core/compare-values.js.map +1 -0
- package/dist/core/compare.d.ts +7 -0
- package/dist/core/compare.d.ts.map +1 -0
- package/dist/core/compare.js +301 -0
- package/dist/core/compare.js.map +1 -0
- package/dist/core/expression.js +2 -2
- package/dist/core/expression.js.map +1 -1
- package/dist/core/i18n.d.ts.map +1 -1
- package/dist/core/i18n.js +136 -2
- package/dist/core/i18n.js.map +1 -1
- package/dist/core/index.d.ts +9 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +6 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/normalize.d.ts.map +1 -1
- package/dist/core/normalize.js +70 -9
- package/dist/core/normalize.js.map +1 -1
- package/dist/core/plan-relation.d.ts +8 -0
- package/dist/core/plan-relation.d.ts.map +1 -0
- package/dist/core/plan-relation.js +15 -0
- package/dist/core/plan-relation.js.map +1 -0
- package/dist/core/price-stabilizer.d.ts +3 -0
- package/dist/core/price-stabilizer.d.ts.map +1 -0
- package/dist/core/price-stabilizer.js +73 -0
- package/dist/core/price-stabilizer.js.map +1 -0
- package/dist/core/resolve.d.ts +7 -1
- package/dist/core/resolve.d.ts.map +1 -1
- package/dist/core/resolve.js +66 -21
- package/dist/core/resolve.js.map +1 -1
- package/dist/core/search-params.d.ts +15 -0
- package/dist/core/search-params.d.ts.map +1 -0
- package/dist/core/search-params.js +175 -0
- package/dist/core/search-params.js.map +1 -0
- package/dist/core/selection-change.d.ts +10 -0
- package/dist/core/selection-change.d.ts.map +1 -0
- package/dist/core/selection-change.js +124 -0
- package/dist/core/selection-change.js.map +1 -0
- package/dist/core/types.d.ts +209 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/units.d.ts +13 -0
- package/dist/core/units.d.ts.map +1 -0
- package/dist/core/units.js +84 -0
- package/dist/core/units.js.map +1 -0
- package/dist/core/utils.d.ts.map +1 -1
- package/dist/core/utils.js +91 -32
- package/dist/core/utils.js.map +1 -1
- package/dist/core/view-model.d.ts +3 -1
- package/dist/core/view-model.d.ts.map +1 -1
- package/dist/core/view-model.js +113 -7
- package/dist/core/view-model.js.map +1 -1
- package/dist/element/change-review-define.d.ts +4 -0
- package/dist/element/change-review-define.d.ts.map +1 -0
- package/dist/element/change-review-define.js +17 -0
- package/dist/element/change-review-define.js.map +1 -0
- package/dist/element/change-review-element.d.ts +53 -0
- package/dist/element/change-review-element.d.ts.map +1 -0
- package/dist/element/change-review-element.js +104 -0
- package/dist/element/change-review-element.js.map +1 -0
- package/dist/element/change-review-events.d.ts +10 -0
- package/dist/element/change-review-events.d.ts.map +1 -0
- package/dist/element/change-review-events.js +2 -0
- package/dist/element/change-review-events.js.map +1 -0
- package/dist/element/change-review-renderers.d.ts +23 -0
- package/dist/element/change-review-renderers.d.ts.map +1 -0
- package/dist/element/change-review-renderers.js +391 -0
- package/dist/element/change-review-renderers.js.map +1 -0
- package/dist/element/cta.d.ts +45 -0
- package/dist/element/cta.d.ts.map +1 -0
- package/dist/element/cta.js +90 -0
- package/dist/element/cta.js.map +1 -0
- package/dist/element/current-selection.d.ts +13 -0
- package/dist/element/current-selection.d.ts.map +1 -0
- package/dist/element/current-selection.js +57 -0
- package/dist/element/current-selection.js.map +1 -0
- package/dist/element/define-change-review.d.ts +2 -0
- package/dist/element/define-change-review.d.ts.map +1 -0
- package/dist/element/define-change-review.js +7 -0
- package/dist/element/define-change-review.js.map +1 -0
- package/dist/element/events.d.ts +32 -6
- package/dist/element/events.d.ts.map +1 -1
- package/dist/element/hide-sections.d.ts +6 -0
- package/dist/element/hide-sections.d.ts.map +1 -0
- package/dist/element/hide-sections.js +26 -0
- package/dist/element/hide-sections.js.map +1 -0
- package/dist/element/index.d.ts +8 -1
- package/dist/element/index.d.ts.map +1 -1
- package/dist/element/index.js +3 -0
- package/dist/element/index.js.map +1 -1
- package/dist/element/pricing-renderer-element.d.ts +95 -7
- package/dist/element/pricing-renderer-element.d.ts.map +1 -1
- package/dist/element/pricing-renderer-element.js +563 -217
- package/dist/element/pricing-renderer-element.js.map +1 -1
- package/dist/element/renderers.d.ts +49 -4
- package/dist/element/renderers.d.ts.map +1 -1
- package/dist/element/renderers.js +795 -263
- package/dist/element/renderers.js.map +1 -1
- package/dist/element/same-input.d.ts +3 -0
- package/dist/element/same-input.d.ts.map +1 -0
- package/dist/element/same-input.js +56 -0
- package/dist/element/same-input.js.map +1 -0
- package/dist/react/headless.d.ts +9 -0
- package/dist/react/headless.d.ts.map +1 -0
- package/dist/react/headless.js +8 -0
- package/dist/react/headless.js.map +1 -0
- package/dist/react/index.d.ts +54 -4
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +156 -6
- package/dist/react/index.js.map +1 -1
- package/dist/react/provider.d.ts +17 -0
- package/dist/react/provider.d.ts.map +1 -0
- package/dist/react/provider.js +38 -0
- package/dist/react/provider.js.map +1 -0
- package/dist/react/selection-store.d.ts +51 -0
- package/dist/react/selection-store.d.ts.map +1 -0
- package/dist/react/selection-store.js +239 -0
- package/dist/react/selection-store.js.map +1 -0
- package/dist/react/slots-types.d.ts +38 -0
- package/dist/react/slots-types.d.ts.map +1 -0
- package/dist/react/slots-types.js +2 -0
- package/dist/react/slots-types.js.map +1 -0
- package/dist/react/slots.d.ts +40 -0
- package/dist/react/slots.d.ts.map +1 -0
- package/dist/react/slots.js +165 -0
- package/dist/react/slots.js.map +1 -0
- package/dist/react/use-pricing-selection.d.ts +10 -0
- package/dist/react/use-pricing-selection.d.ts.map +1 -0
- package/dist/react/use-pricing-selection.js +44 -0
- package/dist/react/use-pricing-selection.js.map +1 -0
- package/dist/react/use-pricing-source.d.ts +34 -0
- package/dist/react/use-pricing-source.d.ts.map +1 -0
- package/dist/react/use-pricing-source.js +186 -0
- package/dist/react/use-pricing-source.js.map +1 -0
- package/dist/react/use-renderer-state.d.ts +22 -0
- package/dist/react/use-renderer-state.d.ts.map +1 -0
- package/dist/react/use-renderer-state.js +112 -0
- package/dist/react/use-renderer-state.js.map +1 -0
- package/dist/space/index.d.ts +26 -0
- package/dist/space/index.d.ts.map +1 -0
- package/dist/space/index.js +71 -0
- package/dist/space/index.js.map +1 -0
- package/dist/styles/base.css +1030 -76
- package/dist/styles/theme-minimal.css +103 -0
- package/dist/styles/theme.css +22 -3
- package/dist/styles/tokens-shadcn.css +40 -0
- package/dist/yaml/index.d.ts +2 -0
- package/dist/yaml/index.d.ts.map +1 -1
- package/dist/yaml/index.js +1 -0
- package/dist/yaml/index.js.map +1 -1
- package/dist/yaml/load.d.ts.map +1 -1
- package/dist/yaml/load.js +106 -17
- package/dist/yaml/load.js.map +1 -1
- package/dist/yaml/source.d.ts +18 -0
- package/dist/yaml/source.d.ts.map +1 -0
- package/dist/yaml/source.js +46 -0
- package/dist/yaml/source.js.map +1 -0
- package/package.json +25 -13
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { createContext, createElement, useMemo } from 'react';
|
|
3
|
+
export const PricingRendererContext = createContext(undefined);
|
|
4
|
+
function originOf(url) {
|
|
5
|
+
try {
|
|
6
|
+
const parsed = new URL(url);
|
|
7
|
+
return parsed.protocol === 'http:' || parsed.protocol === 'https:' ? parsed.origin : undefined;
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
// Headers and credentials of a provider request only go to the page origin or a listed origin.
|
|
14
|
+
export function filterProviderRequest(request, src, requestOrigins) {
|
|
15
|
+
if (request === undefined)
|
|
16
|
+
return undefined;
|
|
17
|
+
const origin = src === undefined ? undefined : originOf(src);
|
|
18
|
+
if (origin !== undefined && origin !== 'null') {
|
|
19
|
+
const pageOrigin = globalThis.location?.origin;
|
|
20
|
+
if (origin === pageOrigin)
|
|
21
|
+
return request;
|
|
22
|
+
for (const entry of requestOrigins ?? []) {
|
|
23
|
+
if (originOf(entry) === origin)
|
|
24
|
+
return request;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const rest = { ...request };
|
|
28
|
+
delete rest.headers;
|
|
29
|
+
delete rest.credentials;
|
|
30
|
+
return rest;
|
|
31
|
+
}
|
|
32
|
+
// The provider only publishes its props to its tree; it never writes the global configuration.
|
|
33
|
+
export function PricingRendererProvider(props) {
|
|
34
|
+
const { children, config, messages, presentation, request, requestOrigins, loadPricing } = props;
|
|
35
|
+
const value = useMemo(() => ({ config, messages, presentation, request, requestOrigins, loadPricing }), [config, messages, presentation, request, requestOrigins, loadPricing]);
|
|
36
|
+
return createElement(PricingRendererContext.Provider, { value }, children);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/react/provider.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,OAAO,EAAqC,MAAM,OAAO,CAAC;AAiBjG,MAAM,CAAC,MAAM,sBAAsB,GAAG,aAAa,CACjD,SAAS,CACV,CAAC;AAEF,SAAS,QAAQ,CAAC,GAAW;IAC3B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IACjG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,qBAAqB,CACnC,OAA0C,EAC1C,GAAuB,EACvB,cAAkC;IAElC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC5C,MAAM,MAAM,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC7D,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QAC9C,MAAM,UAAU,GAAI,UAAiD,CAAC,QAAQ,EAAE,MAAM,CAAC;QACvF,IAAI,MAAM,KAAK,UAAU;YAAE,OAAO,OAAO,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,cAAc,IAAI,EAAE,EAAE,CAAC;YACzC,IAAI,QAAQ,CAAC,KAAK,CAAC,KAAK,MAAM;gBAAE,OAAO,OAAO,CAAC;QACjD,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;IAC5B,OAAO,IAAI,CAAC,OAAO,CAAC;IACpB,OAAO,IAAI,CAAC,WAAW,CAAC;IACxB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,uBAAuB,CAAC,KAAmC;IACzE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC;IACjG,MAAM,KAAK,GAAG,OAAO,CACnB,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC,EAChF,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,CAAC,CACvE,CAAC;IACF,OAAO,aAAa,CAAC,sBAAsB,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC7E,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ApplySelectionInputResult, ExpressionOptions, MessageCatalog, NormalizedPricing, PendingAddOnChange, PricingMode, PricingPresentation, PricingSelection, PricingViewModel, PricingVisibility, ResolvedPricing, SelectionComparison, SelectionRelation } from '../core/index.js';
|
|
2
|
+
import type { CurrentContext } from '../element/current-selection.js';
|
|
3
|
+
/** What `onSelectionChange` receives: the next selection and its stabilized prices. */
|
|
4
|
+
export interface SelectionStoreChange {
|
|
5
|
+
selection: PricingSelection;
|
|
6
|
+
resolved: ResolvedPricing;
|
|
7
|
+
}
|
|
8
|
+
/** The resolved options of `usePricingSelection`, already merged by the hook. */
|
|
9
|
+
export interface SelectionStoreOptions {
|
|
10
|
+
selection?: PricingSelection | undefined;
|
|
11
|
+
onSelectionChange?: ((detail: SelectionStoreChange) => void) | undefined;
|
|
12
|
+
defaultSelection?: Partial<PricingSelection> | undefined;
|
|
13
|
+
currentSelection?: Partial<PricingSelection> | undefined;
|
|
14
|
+
locale?: string | undefined;
|
|
15
|
+
mode?: PricingMode | undefined;
|
|
16
|
+
visibility?: PricingVisibility | undefined;
|
|
17
|
+
messages?: MessageCatalog | undefined;
|
|
18
|
+
presentation?: PricingPresentation | undefined;
|
|
19
|
+
expressionOptions?: ExpressionOptions | undefined;
|
|
20
|
+
variablesEnabled?: boolean | undefined;
|
|
21
|
+
}
|
|
22
|
+
/** Every field is `undefined` while the store has no pricing. */
|
|
23
|
+
export interface SelectionStoreSnapshot {
|
|
24
|
+
selection: PricingSelection | undefined;
|
|
25
|
+
viewModel: PricingViewModel | undefined;
|
|
26
|
+
resolved: ResolvedPricing | undefined;
|
|
27
|
+
pending: PendingAddOnChange | undefined;
|
|
28
|
+
current: CurrentContext | undefined;
|
|
29
|
+
}
|
|
30
|
+
export interface SelectionStore {
|
|
31
|
+
subscribe: (listener: () => void) => () => void;
|
|
32
|
+
getSnapshot: () => SelectionStoreSnapshot;
|
|
33
|
+
setInput: (pricing: NormalizedPricing | undefined, options: SelectionStoreOptions) => void;
|
|
34
|
+
selectPlan: (planId: string) => void;
|
|
35
|
+
toggleAddOn: (addOnId: string, selected: boolean) => void;
|
|
36
|
+
setVariable: (path: string, value: unknown) => void;
|
|
37
|
+
setAddOnQuantity: (addOnId: string, quantity: number) => void;
|
|
38
|
+
setBillingPeriod: (billingPeriodId: string) => void;
|
|
39
|
+
resetVariables: () => void;
|
|
40
|
+
confirm: () => void;
|
|
41
|
+
cancel: () => void;
|
|
42
|
+
apply: (input: Partial<PricingSelection>) => ApplySelectionInputResult | undefined;
|
|
43
|
+
relationOf: (planId: string) => SelectionRelation | undefined;
|
|
44
|
+
compareWithCurrent: () => SelectionComparison | undefined;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The framework-free store behind `usePricingSelection`: one per hook instance, with its own
|
|
48
|
+
* price stabilizer. `getSnapshot` gives the identical object until the state changes.
|
|
49
|
+
*/
|
|
50
|
+
export declare function createSelectionStore(): SelectionStore;
|
|
51
|
+
//# sourceMappingURL=selection-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection-store.d.ts","sourceRoot":"","sources":["../../src/react/selection-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { applySelectionChange, applySelectionInput, cloneValue, compareSelections, createPriceStabilizer, createPricingViewModel, deepEqual, mergeSelection, planSelectionChange, reconcileSelection, selectionInEffect, selectionWithAddOnQuantity, selectionWithVariable, } from '../core/index.js';
|
|
2
|
+
import { planRelation } from '../core/plan-relation.js';
|
|
3
|
+
import { deriveCurrentContext } from '../element/current-selection.js';
|
|
4
|
+
function emptySnapshot() {
|
|
5
|
+
return {
|
|
6
|
+
selection: undefined,
|
|
7
|
+
viewModel: undefined,
|
|
8
|
+
resolved: undefined,
|
|
9
|
+
pending: undefined,
|
|
10
|
+
current: undefined,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
function viewModelOptions(options) {
|
|
14
|
+
return {
|
|
15
|
+
...(options.locale !== undefined ? { locale: options.locale } : {}),
|
|
16
|
+
...(options.mode !== undefined ? { mode: options.mode } : {}),
|
|
17
|
+
...(options.visibility !== undefined ? { visibility: options.visibility } : {}),
|
|
18
|
+
...(options.messages ? { messages: options.messages } : {}),
|
|
19
|
+
...(options.presentation ? { presentation: options.presentation } : {}),
|
|
20
|
+
...(options.expressionOptions ? { expression: options.expressionOptions } : {}),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function withoutCallback(options) {
|
|
24
|
+
const rest = { ...options };
|
|
25
|
+
delete rest.onSelectionChange;
|
|
26
|
+
return rest;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The framework-free store behind `usePricingSelection`: one per hook instance, with its own
|
|
30
|
+
* price stabilizer. `getSnapshot` gives the identical object until the state changes.
|
|
31
|
+
*/
|
|
32
|
+
export function createSelectionStore() {
|
|
33
|
+
// the stabilizer belongs to this store, never to the module
|
|
34
|
+
const stabilizer = createPriceStabilizer();
|
|
35
|
+
const listeners = new Set();
|
|
36
|
+
let pricing;
|
|
37
|
+
let options = {};
|
|
38
|
+
// the selection of an uncontrolled store; unused while `options.selection` is defined
|
|
39
|
+
let internal;
|
|
40
|
+
let pending;
|
|
41
|
+
let snapshot = emptySnapshot();
|
|
42
|
+
let builtFrom;
|
|
43
|
+
const heldSelection = () => options.selection ?? internal;
|
|
44
|
+
// the not reconciled selection in effect (design D1)
|
|
45
|
+
const inEffect = (current, held) => selectionInEffect(current, held, {
|
|
46
|
+
...(options.variablesEnabled !== undefined
|
|
47
|
+
? { variablesEnabled: options.variablesEnabled }
|
|
48
|
+
: {}),
|
|
49
|
+
});
|
|
50
|
+
// The pricing and the selection in effect for an action, or undefined while there is no pricing.
|
|
51
|
+
const target = () => {
|
|
52
|
+
const held = heldSelection();
|
|
53
|
+
if (!pricing || !held)
|
|
54
|
+
return undefined;
|
|
55
|
+
return { pricing, selection: inEffect(pricing, held) };
|
|
56
|
+
};
|
|
57
|
+
// Rebuilds the snapshot when an input differs (structural compare); true when it was replaced.
|
|
58
|
+
const refresh = () => {
|
|
59
|
+
const held = heldSelection();
|
|
60
|
+
if (!pricing || !held) {
|
|
61
|
+
builtFrom = undefined;
|
|
62
|
+
if (snapshot.selection === undefined)
|
|
63
|
+
return false;
|
|
64
|
+
snapshot = emptySnapshot();
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
const rest = withoutCallback(options);
|
|
68
|
+
if (builtFrom &&
|
|
69
|
+
Object.is(builtFrom.pricing, pricing) &&
|
|
70
|
+
deepEqual(builtFrom.held, held) &&
|
|
71
|
+
deepEqual(builtFrom.pending, pending) &&
|
|
72
|
+
deepEqual(builtFrom.rest, rest)) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
// a copy, so an in-place change of the held object by the host is seen by the next compare
|
|
76
|
+
builtFrom = { pricing, held: cloneValue(held), pending, rest };
|
|
77
|
+
const selection = reconcileSelection(pricing, inEffect(pricing, held)).selection;
|
|
78
|
+
const viewModel = stabilizer.stabilize(createPricingViewModel(pricing, selection, viewModelOptions(options)));
|
|
79
|
+
snapshot = {
|
|
80
|
+
selection,
|
|
81
|
+
viewModel,
|
|
82
|
+
resolved: viewModel.resolved,
|
|
83
|
+
pending,
|
|
84
|
+
current: deriveCurrentContext(pricing, options.currentSelection),
|
|
85
|
+
};
|
|
86
|
+
return true;
|
|
87
|
+
};
|
|
88
|
+
// A change that yields a new snapshot calls every listener once.
|
|
89
|
+
const publish = () => {
|
|
90
|
+
if (!refresh())
|
|
91
|
+
return;
|
|
92
|
+
for (const listener of [...listeners])
|
|
93
|
+
listener();
|
|
94
|
+
};
|
|
95
|
+
// Holds the next selection when uncontrolled, then reports it, also when it equals the previous.
|
|
96
|
+
const commit = (next) => {
|
|
97
|
+
if (!pricing)
|
|
98
|
+
return;
|
|
99
|
+
pending = undefined;
|
|
100
|
+
const { onSelectionChange } = options;
|
|
101
|
+
const selection = reconcileSelection(pricing, next).selection;
|
|
102
|
+
if (options.selection === undefined)
|
|
103
|
+
internal = selection;
|
|
104
|
+
const { resolved } = stabilizer.stabilize(createPricingViewModel(pricing, selection, viewModelOptions(options)));
|
|
105
|
+
publish();
|
|
106
|
+
onSelectionChange?.({ selection, resolved });
|
|
107
|
+
};
|
|
108
|
+
const setInput = (nextPricing, nextOptions) => {
|
|
109
|
+
options = nextOptions;
|
|
110
|
+
if (!Object.is(nextPricing, pricing)) {
|
|
111
|
+
pricing = nextPricing;
|
|
112
|
+
stabilizer.reset();
|
|
113
|
+
pending = undefined;
|
|
114
|
+
internal = nextPricing
|
|
115
|
+
? reconcileSelection(nextPricing, mergeSelection(nextPricing, options.defaultSelection))
|
|
116
|
+
.selection
|
|
117
|
+
: undefined;
|
|
118
|
+
}
|
|
119
|
+
refresh();
|
|
120
|
+
};
|
|
121
|
+
const selectPlan = (planId) => {
|
|
122
|
+
const state = target();
|
|
123
|
+
if (!state)
|
|
124
|
+
return;
|
|
125
|
+
const change = planSelectionChange(state.pricing, state.selection, { type: 'plan', planId });
|
|
126
|
+
if (change.kind === 'apply') {
|
|
127
|
+
commit(change.selection);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
pending = change.pending;
|
|
131
|
+
publish();
|
|
132
|
+
};
|
|
133
|
+
const toggleAddOn = (addOnId, selected) => {
|
|
134
|
+
const state = target();
|
|
135
|
+
if (!state)
|
|
136
|
+
return;
|
|
137
|
+
const change = planSelectionChange(state.pricing, state.selection, {
|
|
138
|
+
type: 'addOn',
|
|
139
|
+
addOnId,
|
|
140
|
+
selected,
|
|
141
|
+
});
|
|
142
|
+
if (change.kind === 'apply') {
|
|
143
|
+
commit(change.selection);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
pending = change.pending;
|
|
147
|
+
publish();
|
|
148
|
+
};
|
|
149
|
+
const setVariable = (path, value) => {
|
|
150
|
+
const state = target();
|
|
151
|
+
if (!state)
|
|
152
|
+
return;
|
|
153
|
+
commit(selectionWithVariable(state.selection, path, value));
|
|
154
|
+
};
|
|
155
|
+
const setAddOnQuantity = (addOnId, quantity) => {
|
|
156
|
+
const state = target();
|
|
157
|
+
if (!state)
|
|
158
|
+
return;
|
|
159
|
+
commit(selectionWithAddOnQuantity(state.pricing, state.selection, addOnId, quantity));
|
|
160
|
+
};
|
|
161
|
+
const setBillingPeriod = (billingPeriodId) => {
|
|
162
|
+
const state = target();
|
|
163
|
+
if (!state)
|
|
164
|
+
return;
|
|
165
|
+
commit({ ...state.selection, billingPeriod: billingPeriodId });
|
|
166
|
+
};
|
|
167
|
+
const resetVariables = () => {
|
|
168
|
+
const state = target();
|
|
169
|
+
if (!state)
|
|
170
|
+
return;
|
|
171
|
+
commit({ ...state.selection, variables: cloneValue(state.pricing.variables) });
|
|
172
|
+
};
|
|
173
|
+
// The selection in effect is read now, not when the change became pending.
|
|
174
|
+
const confirm = () => {
|
|
175
|
+
const state = target();
|
|
176
|
+
if (!state || !pending)
|
|
177
|
+
return;
|
|
178
|
+
const change = pending;
|
|
179
|
+
pending = undefined;
|
|
180
|
+
commit(applySelectionChange(state.pricing, state.selection, change));
|
|
181
|
+
};
|
|
182
|
+
const cancel = () => {
|
|
183
|
+
if (!pricing || !pending)
|
|
184
|
+
return;
|
|
185
|
+
pending = undefined;
|
|
186
|
+
publish();
|
|
187
|
+
};
|
|
188
|
+
const apply = (input) => {
|
|
189
|
+
const state = target();
|
|
190
|
+
if (!state)
|
|
191
|
+
return undefined;
|
|
192
|
+
const current = reconcileSelection(state.pricing, state.selection).selection;
|
|
193
|
+
const result = applySelectionInput(state.pricing, current, input);
|
|
194
|
+
pending = undefined;
|
|
195
|
+
commit(result.selection);
|
|
196
|
+
return result;
|
|
197
|
+
};
|
|
198
|
+
const relationOf = (planId) => {
|
|
199
|
+
const { current } = snapshot;
|
|
200
|
+
if (!pricing || !current)
|
|
201
|
+
return undefined;
|
|
202
|
+
return planRelation(pricing, current.planId, planId);
|
|
203
|
+
};
|
|
204
|
+
const compareWithCurrent = () => {
|
|
205
|
+
const { current, selection } = snapshot;
|
|
206
|
+
const currentSelection = options.currentSelection;
|
|
207
|
+
if (!pricing || !current || !selection || !currentSelection)
|
|
208
|
+
return undefined;
|
|
209
|
+
return compareSelections({
|
|
210
|
+
before: { pricing, selection: currentSelection },
|
|
211
|
+
after: { pricing, selection },
|
|
212
|
+
...(options.expressionOptions ? { expression: options.expressionOptions } : {}),
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
return {
|
|
216
|
+
subscribe(listener) {
|
|
217
|
+
// a wrapper per call, so the same function subscribed twice is removed one at a time
|
|
218
|
+
const entry = () => listener();
|
|
219
|
+
listeners.add(entry);
|
|
220
|
+
return () => {
|
|
221
|
+
listeners.delete(entry);
|
|
222
|
+
};
|
|
223
|
+
},
|
|
224
|
+
getSnapshot: () => snapshot,
|
|
225
|
+
setInput,
|
|
226
|
+
selectPlan,
|
|
227
|
+
toggleAddOn,
|
|
228
|
+
setVariable,
|
|
229
|
+
setAddOnQuantity,
|
|
230
|
+
setBillingPeriod,
|
|
231
|
+
resetVariables,
|
|
232
|
+
confirm,
|
|
233
|
+
cancel,
|
|
234
|
+
apply,
|
|
235
|
+
relationOf,
|
|
236
|
+
compareWithCurrent,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=selection-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection-store.js","sourceRoot":"","sources":["../../src/react/selection-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { PricingDiagnostic, SelectionRelation } from '../core/index.js';
|
|
2
|
+
import type { PricingSelectionChangeDetail } from '../element/index.js';
|
|
3
|
+
export interface PricingPlanCtaContext {
|
|
4
|
+
planId: string;
|
|
5
|
+
/** Plain text that may carry text from the pricing document: render it as text, never as HTML. */
|
|
6
|
+
planName: string;
|
|
7
|
+
/**
|
|
8
|
+
* The label of the built-in CTA. Plain text that may carry text from the pricing document:
|
|
9
|
+
* render it as text, never as HTML.
|
|
10
|
+
*/
|
|
11
|
+
label: string;
|
|
12
|
+
/** The safe link of the built-in CTA; absent for a button. */
|
|
13
|
+
href?: string;
|
|
14
|
+
/** Absent without a current plan. */
|
|
15
|
+
relation?: SelectionRelation;
|
|
16
|
+
selected: boolean;
|
|
17
|
+
current: boolean;
|
|
18
|
+
/** This CTA's action is the pending one. */
|
|
19
|
+
pending: boolean;
|
|
20
|
+
/** Any action is pending, whichever it names. */
|
|
21
|
+
anyPending: boolean;
|
|
22
|
+
/** Dispatches the `pricing-action` of the built-in CTA; false when the element ignores it. */
|
|
23
|
+
trigger(): boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface PricingSummaryActionsContext {
|
|
26
|
+
selection: PricingSelectionChangeDetail['selection'];
|
|
27
|
+
resolved: PricingSelectionChangeDetail['resolved'];
|
|
28
|
+
/** Absent without a current plan. */
|
|
29
|
+
relation?: SelectionRelation;
|
|
30
|
+
/** Any action is pending, whichever it names. */
|
|
31
|
+
pending: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface PricingErrorContext {
|
|
34
|
+
/** Messages are plain text that may carry text from the pricing document: render them as text. */
|
|
35
|
+
diagnostics: readonly PricingDiagnostic[];
|
|
36
|
+
reload(): Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=slots-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slots-types.d.ts","sourceRoot":"","sources":["../../src/react/slots-types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAExE,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,kGAAkG;IAClG,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,iDAAiD;IACjD,UAAU,EAAE,OAAO,CAAC;IACpB,8FAA8F;IAC9F,OAAO,IAAI,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,4BAA4B,CAAC,WAAW,CAAC,CAAC;IACrD,QAAQ,EAAE,4BAA4B,CAAC,UAAU,CAAC,CAAC;IACnD,qCAAqC;IACrC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,kGAAkG;IAClG,WAAW,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC1C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slots-types.js","sourceRoot":"","sources":["../../src/react/slots-types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { PricingDiagnostic } from '../core/index.js';
|
|
2
|
+
import type { PricingRendererElement, PricingSelectionChangeDetail, PricingSlotName, PricingSlotsChangeDetail } from '../element/index.js';
|
|
3
|
+
import type { PricingErrorContext, PricingPlanCtaContext, PricingSummaryActionsContext } from './slots-types.js';
|
|
4
|
+
export declare function slotNamesOf(props: {
|
|
5
|
+
renderPlanCta?: unknown;
|
|
6
|
+
renderSummaryActions?: unknown;
|
|
7
|
+
renderLoading?: unknown;
|
|
8
|
+
renderError?: unknown;
|
|
9
|
+
}): PricingSlotName[] | undefined;
|
|
10
|
+
export declare function acceptedSlotNodes(element: HTMLElement, event: {
|
|
11
|
+
target: EventTarget | null;
|
|
12
|
+
detail: PricingSlotsChangeDetail;
|
|
13
|
+
}): HTMLElement[] | undefined;
|
|
14
|
+
export declare function currentSlotNodes(element: HTMLElement): HTMLElement[];
|
|
15
|
+
export declare function planCtaContextOf(element: Pick<PricingRendererElement, 'triggerPlanAction'>, node: HTMLElement): PricingPlanCtaContext;
|
|
16
|
+
export declare function summaryActionsContextOf(node: HTMLElement, state: Pick<PricingSelectionChangeDetail, 'selection' | 'resolved'>): PricingSummaryActionsContext;
|
|
17
|
+
export declare function errorContextOf(element: Pick<PricingRendererElement, 'reload'>, diagnostics: readonly PricingDiagnostic[]): PricingErrorContext;
|
|
18
|
+
export declare function errorDiagnosticsOf(node: HTMLElement): PricingDiagnostic[];
|
|
19
|
+
export type SlotEntry = {
|
|
20
|
+
slot: 'plan-cta';
|
|
21
|
+
node: HTMLElement;
|
|
22
|
+
key: string;
|
|
23
|
+
context: PricingPlanCtaContext;
|
|
24
|
+
} | {
|
|
25
|
+
slot: 'summary-actions';
|
|
26
|
+
node: HTMLElement;
|
|
27
|
+
key: string;
|
|
28
|
+
context: PricingSummaryActionsContext;
|
|
29
|
+
} | {
|
|
30
|
+
slot: 'loading';
|
|
31
|
+
node: HTMLElement;
|
|
32
|
+
key: string;
|
|
33
|
+
} | {
|
|
34
|
+
slot: 'error';
|
|
35
|
+
node: HTMLElement;
|
|
36
|
+
key: string;
|
|
37
|
+
context: PricingErrorContext;
|
|
38
|
+
};
|
|
39
|
+
export declare function slotEntriesOf(element: Pick<PricingRendererElement, 'triggerPlanAction' | 'reload'>, nodes: readonly HTMLElement[], state: Pick<PricingSelectionChangeDetail, 'selection' | 'resolved'> | undefined): SlotEntry[];
|
|
40
|
+
//# sourceMappingURL=slots.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slots.d.ts","sourceRoot":"","sources":["../../src/react/slots.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAqB,MAAM,kBAAkB,CAAC;AAC7E,OAAO,KAAK,EACV,sBAAsB,EACtB,4BAA4B,EAC5B,eAAe,EACf,wBAAwB,EACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EACV,mBAAmB,EACnB,qBAAqB,EACrB,4BAA4B,EAC7B,MAAM,kBAAkB,CAAC;AAM1B,wBAAgB,WAAW,CAAC,KAAK,EAAE;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,GAAG,eAAe,EAAE,GAAG,SAAS,CAOhC;AAUD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE;IAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,wBAAwB,CAAA;CAAE,GACtE,WAAW,EAAE,GAAG,SAAS,CAc3B;AAWD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW,EAAE,CAGpE;AAQD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,IAAI,CAAC,sBAAsB,EAAE,mBAAmB,CAAC,EAC1D,IAAI,EAAE,WAAW,GAChB,qBAAqB,CAiBvB;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,IAAI,CAAC,4BAA4B,EAAE,WAAW,GAAG,UAAU,CAAC,GAClE,4BAA4B,CAQ9B;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,IAAI,CAAC,sBAAsB,EAAE,QAAQ,CAAC,EAC/C,WAAW,EAAE,SAAS,iBAAiB,EAAE,GACxC,mBAAmB,CAErB;AAkBD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,GAAG,iBAAiB,EAAE,CAWzE;AAID,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,qBAAqB,CAAA;CAAE,GACpF;IACE,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,WAAW,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,4BAA4B,CAAC;CACvC,GACD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAIpF,wBAAgB,aAAa,CAC3B,OAAO,EAAE,IAAI,CAAC,sBAAsB,EAAE,mBAAmB,GAAG,QAAQ,CAAC,EACrE,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,KAAK,EAAE,IAAI,CAAC,4BAA4B,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG,SAAS,GAC9E,SAAS,EAAE,CAsCb"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// The pure helpers behind the render props of PricingRenderer: they read slot nodes and build the
|
|
2
|
+
// contexts. They use no React and touch no DOM global, so a node unit test runs them with
|
|
3
|
+
// stand-in nodes.
|
|
4
|
+
import { isSafeLink } from '../core/index.js';
|
|
5
|
+
// No constant lives at module scope: the allow-list scan of the React modules refuses it.
|
|
6
|
+
// The slot names of the render props given as functions, in the fixed order of `slots`, or
|
|
7
|
+
// undefined when there is none.
|
|
8
|
+
export function slotNamesOf(props) {
|
|
9
|
+
const names = [];
|
|
10
|
+
if (typeof props.renderPlanCta === 'function')
|
|
11
|
+
names.push('plan-cta');
|
|
12
|
+
if (typeof props.renderSummaryActions === 'function')
|
|
13
|
+
names.push('summary-actions');
|
|
14
|
+
if (typeof props.renderLoading === 'function')
|
|
15
|
+
names.push('loading');
|
|
16
|
+
if (typeof props.renderError === 'function')
|
|
17
|
+
names.push('error');
|
|
18
|
+
return names.length > 0 ? names : undefined;
|
|
19
|
+
}
|
|
20
|
+
function isSlotName(value) {
|
|
21
|
+
const names = ['plan-cta', 'summary-actions', 'loading', 'error'];
|
|
22
|
+
return value !== undefined && names.includes(value);
|
|
23
|
+
}
|
|
24
|
+
// The nodes of the event that this wrapper's element owns, in their order; undefined for the event
|
|
25
|
+
// of another element. A node is left out when it is detached, is not a known slot, is a plan node
|
|
26
|
+
// without a plan id, or sits in a nested renderer or inside another slot node.
|
|
27
|
+
export function acceptedSlotNodes(element, event) {
|
|
28
|
+
if (event.target !== element)
|
|
29
|
+
return undefined;
|
|
30
|
+
const nodes = event.detail?.nodes;
|
|
31
|
+
if (!Array.isArray(nodes))
|
|
32
|
+
return [];
|
|
33
|
+
return nodes.filter((node) => isElementLike(node) &&
|
|
34
|
+
node.isConnected &&
|
|
35
|
+
(node.parentElement === null ||
|
|
36
|
+
typeof node.parentElement?.closest === 'function') &&
|
|
37
|
+
isSlotName(node.dataset.prSlot) &&
|
|
38
|
+
(node.dataset.prSlot !== 'plan-cta' || (node.dataset.planId ?? '') !== '') &&
|
|
39
|
+
node.parentElement?.closest('[data-pr-root], [data-pr-slot]') === element);
|
|
40
|
+
}
|
|
41
|
+
// An event detail is untrusted: an item that carries no dataset (null, a string, a text node) is
|
|
42
|
+
// not a slot node.
|
|
43
|
+
function isElementLike(node) {
|
|
44
|
+
if (typeof node !== 'object' || node === null)
|
|
45
|
+
return false;
|
|
46
|
+
const dataset = node.dataset;
|
|
47
|
+
return typeof dataset === 'object' && dataset !== null;
|
|
48
|
+
}
|
|
49
|
+
// The slot nodes that exist now, for an event that fired before the wrapper listened.
|
|
50
|
+
export function currentSlotNodes(element) {
|
|
51
|
+
const nodes = [...element.querySelectorAll('[data-pr-slot]')];
|
|
52
|
+
return acceptedSlotNodes(element, { target: element, detail: { nodes } }) ?? [];
|
|
53
|
+
}
|
|
54
|
+
function relationOf(value) {
|
|
55
|
+
const relations = ['current', 'upgrade', 'downgrade', 'change'];
|
|
56
|
+
if (value === undefined || !relations.includes(value))
|
|
57
|
+
return undefined;
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
export function planCtaContextOf(element, node) {
|
|
61
|
+
const data = node.dataset;
|
|
62
|
+
const planId = data.planId ?? '';
|
|
63
|
+
const href = isSafeLink(data.href) ? data.href : undefined;
|
|
64
|
+
const relation = relationOf(data.relation);
|
|
65
|
+
return {
|
|
66
|
+
planId,
|
|
67
|
+
planName: data.planName ?? '',
|
|
68
|
+
label: data.label ?? '',
|
|
69
|
+
...(href !== undefined ? { href } : {}),
|
|
70
|
+
...(relation !== undefined ? { relation } : {}),
|
|
71
|
+
selected: data.selected === 'true',
|
|
72
|
+
current: data.current === 'true',
|
|
73
|
+
pending: data.pending === 'true',
|
|
74
|
+
anyPending: data.anyPending === 'true',
|
|
75
|
+
trigger: () => element.triggerPlanAction(planId),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export function summaryActionsContextOf(node, state) {
|
|
79
|
+
const relation = relationOf(node.dataset.relation);
|
|
80
|
+
return {
|
|
81
|
+
selection: state.selection,
|
|
82
|
+
resolved: state.resolved,
|
|
83
|
+
...(relation !== undefined ? { relation } : {}),
|
|
84
|
+
pending: node.dataset.pending === 'true',
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export function errorContextOf(element, diagnostics) {
|
|
88
|
+
return { diagnostics, reload: () => element.reload() };
|
|
89
|
+
}
|
|
90
|
+
function diagnosticOf(value) {
|
|
91
|
+
if (typeof value !== 'object' || value === null)
|
|
92
|
+
return undefined;
|
|
93
|
+
const { code, severity, message, path } = value;
|
|
94
|
+
if (typeof code !== 'string' || typeof message !== 'string')
|
|
95
|
+
return undefined;
|
|
96
|
+
const severities = ['error', 'warning', 'info'];
|
|
97
|
+
if (typeof severity !== 'string' || !severities.includes(severity))
|
|
98
|
+
return undefined;
|
|
99
|
+
if (path !== undefined && typeof path !== 'string')
|
|
100
|
+
return undefined;
|
|
101
|
+
return {
|
|
102
|
+
code,
|
|
103
|
+
severity: severity,
|
|
104
|
+
message,
|
|
105
|
+
...(path !== undefined ? { path } : {}),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// The diagnostics of the failed load come from the error slot node only.
|
|
109
|
+
export function errorDiagnosticsOf(node) {
|
|
110
|
+
const text = node.dataset.diagnostics;
|
|
111
|
+
if (text === undefined)
|
|
112
|
+
return [];
|
|
113
|
+
let parsed;
|
|
114
|
+
try {
|
|
115
|
+
parsed = JSON.parse(text);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return [];
|
|
119
|
+
}
|
|
120
|
+
if (!Array.isArray(parsed))
|
|
121
|
+
return [];
|
|
122
|
+
return parsed.flatMap((entry) => diagnosticOf(entry) ?? []);
|
|
123
|
+
}
|
|
124
|
+
// The summary context needs the state read when the event fired; without a state (the element is
|
|
125
|
+
// not ready) a summary node gets no entry.
|
|
126
|
+
export function slotEntriesOf(element, nodes, state) {
|
|
127
|
+
return nodes.flatMap((node) => {
|
|
128
|
+
switch (node.dataset.prSlot) {
|
|
129
|
+
case 'plan-cta':
|
|
130
|
+
return [
|
|
131
|
+
{
|
|
132
|
+
slot: 'plan-cta',
|
|
133
|
+
node,
|
|
134
|
+
key: `plan:${node.dataset.planId ?? ''}`,
|
|
135
|
+
context: planCtaContextOf(element, node),
|
|
136
|
+
},
|
|
137
|
+
];
|
|
138
|
+
case 'summary-actions':
|
|
139
|
+
return state
|
|
140
|
+
? [
|
|
141
|
+
{
|
|
142
|
+
slot: 'summary-actions',
|
|
143
|
+
node,
|
|
144
|
+
key: 'slot:summary-actions',
|
|
145
|
+
context: summaryActionsContextOf(node, state),
|
|
146
|
+
},
|
|
147
|
+
]
|
|
148
|
+
: [];
|
|
149
|
+
case 'loading':
|
|
150
|
+
return [{ slot: 'loading', node, key: 'slot:loading' }];
|
|
151
|
+
case 'error':
|
|
152
|
+
return [
|
|
153
|
+
{
|
|
154
|
+
slot: 'error',
|
|
155
|
+
node,
|
|
156
|
+
key: 'slot:error',
|
|
157
|
+
context: errorContextOf(element, errorDiagnosticsOf(node)),
|
|
158
|
+
},
|
|
159
|
+
];
|
|
160
|
+
default:
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=slots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slots.js","sourceRoot":"","sources":["../../src/react/slots.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { NormalizedPricing } from '../core/index.js';
|
|
2
|
+
import type { SelectionStore, SelectionStoreChange, SelectionStoreOptions, SelectionStoreSnapshot } from './selection-store.js';
|
|
3
|
+
/** The options of `usePricingSelection`: the instance layer, above the provider and the global one. */
|
|
4
|
+
export type UsePricingSelectionOptions = SelectionStoreOptions;
|
|
5
|
+
/** What `onSelectionChange` of `usePricingSelection` receives. */
|
|
6
|
+
export type UsePricingSelectionChange = SelectionStoreChange;
|
|
7
|
+
/** The snapshot fields and the stable actions and queries of `usePricingSelection`. */
|
|
8
|
+
export type UsePricingSelectionResult = SelectionStoreSnapshot & Omit<SelectionStore, 'subscribe' | 'getSnapshot' | 'setInput'>;
|
|
9
|
+
export declare function usePricingSelection(pricing: NormalizedPricing | undefined, options?: UsePricingSelectionOptions): UsePricingSelectionResult;
|
|
10
|
+
//# sourceMappingURL=use-pricing-selection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-pricing-selection.d.ts","sourceRoot":"","sources":["../../src/react/use-pricing-selection.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG1D,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,sBAAsB,CAAC;AAE9B,uGAAuG;AACvG,MAAM,MAAM,0BAA0B,GAAG,qBAAqB,CAAC;AAE/D,kEAAkE;AAClE,MAAM,MAAM,yBAAyB,GAAG,oBAAoB,CAAC;AAE7D,uFAAuF;AACvF,MAAM,MAAM,yBAAyB,GAAG,sBAAsB,GAC5D,IAAI,CAAC,cAAc,EAAE,WAAW,GAAG,aAAa,GAAG,UAAU,CAAC,CAAC;AAgCjE,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,GAAG,SAAS,EACtC,OAAO,GAAE,0BAA+B,GACvC,yBAAyB,CAmB3B"}
|