@molecule/app-pricing-table-angular 0.0.0-stage → 0.0.1-stage

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/index.js ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Angular side-by-side pricing comparison table.
3
+ *
4
+ * Exports `<PricingTable>` (selector `div[mol-pricing-table]`) and
5
+ * `PricingPlan` / `PricingFeature` types — the Angular counterpart of
6
+ * `@molecule/app-pricing-table-react`, with the same props and the same DOM
7
+ * for the same input.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { Component } from '@angular/core'
12
+ * import { PricingTable } from '@molecule/app-pricing-table-angular'
13
+ *
14
+ * @Component({
15
+ * selector: 'plans',
16
+ * standalone: true,
17
+ * imports: [PricingTable],
18
+ * template: `
19
+ * <div mol-pricing-table [plans]="plans" [features]="features"></div>
20
+ *
21
+ * <ng-template #proName><strong>Pro</strong></ng-template>
22
+ * `,
23
+ * })
24
+ * export class Plans {
25
+ * plans = [
26
+ * { id: 'starter', name: 'Starter', price: '$9', interval: '/mo',
27
+ * cta: { label: 'Get started', onClick: () => this.checkout('starter') } },
28
+ * { id: 'pro', name: this.proName, price: '$29', interval: '/mo', recommended: true,
29
+ * cta: { label: 'Get started', onClick: () => this.checkout('pro') } },
30
+ * ]
31
+ * features = [
32
+ * { label: 'Projects', values: { starter: '3', pro: 'Unlimited' } },
33
+ * { label: 'Team members', values: { starter: false, pro: true } },
34
+ * ]
35
+ * checkout(planId: string): void {
36
+ * window.location.assign(`/checkout?plan=${planId}`)
37
+ * }
38
+ * }
39
+ * ```
40
+ *
41
+ * @remarks
42
+ * All text arrives via inputs — pass pre-translated strings; requires a wired
43
+ * ClassMap bond. Node-valued plan/feature fields are projected templates
44
+ * (`<ng-template #ref>`), not input values; pass the template reference.
45
+ *
46
+ * @module
47
+ */
48
+ export * from './pricing-table.component.js';
49
+ export * from './types.js';
50
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,cAAc,8BAA8B,CAAA;AAC5C,cAAc,YAAY,CAAA"}
@@ -0,0 +1,75 @@
1
+ import { TemplateRef } from '@angular/core';
2
+ import type { UIClassMap } from '@molecule/app-ui';
3
+ import type { PricingFeature, PricingPlan } from './types.js';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * PricingTable component.
7
+ *
8
+ * Side-by-side pricing comparison — features × plans matrix. A header row
9
+ * holds plan cards (name, description, price, interval, CTA); body rows show
10
+ * per-feature availability (`true` → ✓, `false` → —, strings/templates pass
11
+ * through). The wrapper scrolls horizontally when columns overflow.
12
+ *
13
+ * The host IS the outer `<div>` (`div[mol-pricing-table]`), matching React's
14
+ * root exactly. Node-valued fields (`plans[].name`, …) are projected templates
15
+ * in Angular (an input cannot carry a node), rendered through
16
+ * `ngTemplateOutlet`; plain strings render as text.
17
+ */
18
+ export declare class PricingTable {
19
+ /** The plan columns, left to right. */
20
+ plans: PricingPlan[];
21
+ /** The feature rows, top to bottom. */
22
+ features: PricingFeature[];
23
+ /** Extra classes on the outer wrapper. */
24
+ className?: string;
25
+ /**
26
+ * The current class map.
27
+ * @returns The UIClassMap.
28
+ */
29
+ cm(): UIClassMap;
30
+ /**
31
+ * Computes the wrapper class list.
32
+ * @returns The class string.
33
+ */
34
+ classes(): string;
35
+ /**
36
+ * The recommended plan's outline style, in React's shape.
37
+ * @param plan - The plan.
38
+ * @returns The style object, or undefined for a plain column.
39
+ */
40
+ cardStyle(plan: PricingPlan): Record<string, string> | undefined;
41
+ /**
42
+ * Whether a node-valued field arrived as a projected template.
43
+ * @param value - The field value.
44
+ * @returns True for a template.
45
+ */
46
+ isTemplate(value: unknown): value is TemplateRef<unknown>;
47
+ /**
48
+ * A node-valued field as a template (the `@if` above already checked it).
49
+ * @param value - The field value.
50
+ * @returns The template, or null when it is not one.
51
+ */
52
+ asTemplate(value: unknown): TemplateRef<unknown> | null;
53
+ /**
54
+ * A node-valued field as display text.
55
+ * @param value - The field value.
56
+ * @returns Its text, or an empty string when absent.
57
+ */
58
+ text(value: unknown): string;
59
+ /**
60
+ * Renders a feature cell value: `true` → ✓, `false` → —, anything else
61
+ * pass-through.
62
+ * @param value - The per-plan feature value.
63
+ * @returns The content to render.
64
+ */
65
+ renderValue(value: unknown): unknown;
66
+ /**
67
+ * Calls a plan's click handler with the DOM event, as React's `Button` does.
68
+ * @param handler - The plan's `onClick`, when it has one.
69
+ * @param event - The click event.
70
+ */
71
+ invoke(handler: ((event?: MouseEvent) => void) | undefined, event: MouseEvent): void;
72
+ static ɵfac: i0.ɵɵFactoryDeclaration<PricingTable, never>;
73
+ static ɵcmp: i0.ɵɵComponentDeclaration<PricingTable, "div[mol-pricing-table]", never, { "plans": { "alias": "plans"; "required": false; }; "features": { "alias": "features"; "required": false; }; "className": { "alias": "className"; "required": false; }; }, {}, never, never, true, never>;
74
+ }
75
+ //# sourceMappingURL=pricing-table.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing-table.component.d.ts","sourceRoot":"","sources":["../src/pricing-table.component.ts"],"names":[],"mappings":"AAOA,OAAO,EAAa,WAAW,EAAE,MAAM,eAAe,CAAA;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAIlD,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;;AAE7D;;;;;;;;;;;;GAYG;AACH,qBAyIa,YAAY;IACvB,uCAAuC;IACvC,KAAK,EAAE,WAAW,EAAE,CAAK;IACzB,uCAAuC;IACvC,QAAQ,EAAE,cAAc,EAAE,CAAK;IAC/B,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;OAGG;IACH,EAAE,IAAI,UAAU;IAIhB;;;OAGG;IACH,OAAO,IAAI,MAAM;IAIjB;;;;OAIG;IACH,SAAS,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IAMhE;;;;OAIG;IACH,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAAC,OAAO,CAAC;IAIzD;;;;OAIG;IACH,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI;IAIvD;;;;OAIG;IACH,IAAI,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;IAI5B;;;;;OAKG;IACH,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO;IAMpC;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,UAAU,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;yCA/EzE,YAAY;2CAAZ,YAAY;CAkFxB"}
@@ -0,0 +1,526 @@
1
+ /**
2
+ * PricingTable component (React parity).
3
+ *
4
+ * @module
5
+ */
6
+ import { NgTemplateOutlet } from '@angular/common';
7
+ import { Component, TemplateRef } from '@angular/core';
8
+ import { getClassMap } from '@molecule/app-ui';
9
+ import { Button, Card } from '@molecule/app-ui-angular';
10
+ import * as i0 from "@angular/core";
11
+ const _c0 = () => ({ align: "baseline", gap: "xs" });
12
+ const _forTrack0 = ($index, $item) => $item.id;
13
+ function PricingTable_For_5_Conditional_4_Template(rf, ctx) { if (rf & 1) {
14
+ i0.ɵɵelementContainer(0, 4);
15
+ } if (rf & 2) {
16
+ const plan_r1 = i0.ɵɵnextContext().$implicit;
17
+ const ctx_r1 = i0.ɵɵnextContext();
18
+ i0.ɵɵproperty("ngTemplateOutlet", ctx_r1.asTemplate(plan_r1.name));
19
+ } }
20
+ function PricingTable_For_5_Conditional_5_Template(rf, ctx) { if (rf & 1) {
21
+ i0.ɵɵtext(0);
22
+ } if (rf & 2) {
23
+ const plan_r1 = i0.ɵɵnextContext().$implicit;
24
+ const ctx_r1 = i0.ɵɵnextContext();
25
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.text(plan_r1.name), " ");
26
+ } }
27
+ function PricingTable_For_5_Conditional_6_Conditional_1_Template(rf, ctx) { if (rf & 1) {
28
+ i0.ɵɵelementContainer(0, 4);
29
+ } if (rf & 2) {
30
+ const plan_r1 = i0.ɵɵnextContext(2).$implicit;
31
+ const ctx_r1 = i0.ɵɵnextContext();
32
+ i0.ɵɵproperty("ngTemplateOutlet", ctx_r1.asTemplate(plan_r1.description));
33
+ } }
34
+ function PricingTable_For_5_Conditional_6_Conditional_2_Template(rf, ctx) { if (rf & 1) {
35
+ i0.ɵɵtext(0);
36
+ } if (rf & 2) {
37
+ const plan_r1 = i0.ɵɵnextContext(2).$implicit;
38
+ const ctx_r1 = i0.ɵɵnextContext();
39
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.text(plan_r1.description), " ");
40
+ } }
41
+ function PricingTable_For_5_Conditional_6_Template(rf, ctx) { if (rf & 1) {
42
+ i0.ɵɵelementStart(0, "p");
43
+ i0.ɵɵconditionalCreate(1, PricingTable_For_5_Conditional_6_Conditional_1_Template, 1, 1, "ng-container", 4)(2, PricingTable_For_5_Conditional_6_Conditional_2_Template, 1, 1);
44
+ i0.ɵɵelementEnd();
45
+ } if (rf & 2) {
46
+ const plan_r1 = i0.ɵɵnextContext().$implicit;
47
+ const ctx_r1 = i0.ɵɵnextContext();
48
+ i0.ɵɵclassMap(ctx_r1.cm().textSize("sm"));
49
+ i0.ɵɵadvance();
50
+ i0.ɵɵconditional(ctx_r1.isTemplate(plan_r1.description) ? 1 : 2);
51
+ } }
52
+ function PricingTable_For_5_Conditional_9_Template(rf, ctx) { if (rf & 1) {
53
+ i0.ɵɵelementContainer(0, 4);
54
+ } if (rf & 2) {
55
+ const plan_r1 = i0.ɵɵnextContext().$implicit;
56
+ const ctx_r1 = i0.ɵɵnextContext();
57
+ i0.ɵɵproperty("ngTemplateOutlet", ctx_r1.asTemplate(plan_r1.price));
58
+ } }
59
+ function PricingTable_For_5_Conditional_10_Template(rf, ctx) { if (rf & 1) {
60
+ i0.ɵɵtext(0);
61
+ } if (rf & 2) {
62
+ const plan_r1 = i0.ɵɵnextContext().$implicit;
63
+ const ctx_r1 = i0.ɵɵnextContext();
64
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.text(plan_r1.price), " ");
65
+ } }
66
+ function PricingTable_For_5_Conditional_11_Conditional_1_Template(rf, ctx) { if (rf & 1) {
67
+ i0.ɵɵelementContainer(0, 4);
68
+ } if (rf & 2) {
69
+ const plan_r1 = i0.ɵɵnextContext(2).$implicit;
70
+ const ctx_r1 = i0.ɵɵnextContext();
71
+ i0.ɵɵproperty("ngTemplateOutlet", ctx_r1.asTemplate(plan_r1.interval));
72
+ } }
73
+ function PricingTable_For_5_Conditional_11_Conditional_2_Template(rf, ctx) { if (rf & 1) {
74
+ i0.ɵɵtext(0);
75
+ } if (rf & 2) {
76
+ const plan_r1 = i0.ɵɵnextContext(2).$implicit;
77
+ const ctx_r1 = i0.ɵɵnextContext();
78
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.text(plan_r1.interval), " ");
79
+ } }
80
+ function PricingTable_For_5_Conditional_11_Template(rf, ctx) { if (rf & 1) {
81
+ i0.ɵɵelementStart(0, "span");
82
+ i0.ɵɵconditionalCreate(1, PricingTable_For_5_Conditional_11_Conditional_1_Template, 1, 1, "ng-container", 4)(2, PricingTable_For_5_Conditional_11_Conditional_2_Template, 1, 1);
83
+ i0.ɵɵelementEnd();
84
+ } if (rf & 2) {
85
+ const plan_r1 = i0.ɵɵnextContext().$implicit;
86
+ const ctx_r1 = i0.ɵɵnextContext();
87
+ i0.ɵɵclassMap(ctx_r1.cm().textSize("xs"));
88
+ i0.ɵɵadvance();
89
+ i0.ɵɵconditional(ctx_r1.isTemplate(plan_r1.interval) ? 1 : 2);
90
+ } }
91
+ function PricingTable_For_5_Conditional_12_Conditional_0_Conditional_2_Template(rf, ctx) { if (rf & 1) {
92
+ i0.ɵɵelementContainer(0, 4);
93
+ } if (rf & 2) {
94
+ const plan_r1 = i0.ɵɵnextContext(3).$implicit;
95
+ const ctx_r1 = i0.ɵɵnextContext();
96
+ i0.ɵɵproperty("ngTemplateOutlet", ctx_r1.asTemplate(plan_r1.cta.label));
97
+ } }
98
+ function PricingTable_For_5_Conditional_12_Conditional_0_Conditional_3_Template(rf, ctx) { if (rf & 1) {
99
+ i0.ɵɵtext(0);
100
+ } if (rf & 2) {
101
+ const plan_r1 = i0.ɵɵnextContext(3).$implicit;
102
+ const ctx_r1 = i0.ɵɵnextContext();
103
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.text(plan_r1.cta.label), " ");
104
+ } }
105
+ function PricingTable_For_5_Conditional_12_Conditional_0_Template(rf, ctx) { if (rf & 1) {
106
+ i0.ɵɵelementStart(0, "a")(1, "button", 6);
107
+ i0.ɵɵconditionalCreate(2, PricingTable_For_5_Conditional_12_Conditional_0_Conditional_2_Template, 1, 1, "ng-container", 4)(3, PricingTable_For_5_Conditional_12_Conditional_0_Conditional_3_Template, 1, 1);
108
+ i0.ɵɵelementEnd()();
109
+ } if (rf & 2) {
110
+ const plan_r1 = i0.ɵɵnextContext(2).$implicit;
111
+ const ctx_r1 = i0.ɵɵnextContext();
112
+ i0.ɵɵattribute("href", plan_r1.cta.href, i0.ɵɵsanitizeUrl);
113
+ i0.ɵɵadvance();
114
+ i0.ɵɵproperty("variant", "solid")("color", plan_r1.recommended ? "primary" : "secondary");
115
+ i0.ɵɵadvance();
116
+ i0.ɵɵconditional(ctx_r1.isTemplate(plan_r1.cta.label) ? 2 : 3);
117
+ } }
118
+ function PricingTable_For_5_Conditional_12_Conditional_1_Conditional_1_Template(rf, ctx) { if (rf & 1) {
119
+ i0.ɵɵelementContainer(0, 4);
120
+ } if (rf & 2) {
121
+ const plan_r1 = i0.ɵɵnextContext(3).$implicit;
122
+ const ctx_r1 = i0.ɵɵnextContext();
123
+ i0.ɵɵproperty("ngTemplateOutlet", ctx_r1.asTemplate(plan_r1.cta.label));
124
+ } }
125
+ function PricingTable_For_5_Conditional_12_Conditional_1_Conditional_2_Template(rf, ctx) { if (rf & 1) {
126
+ i0.ɵɵtext(0);
127
+ } if (rf & 2) {
128
+ const plan_r1 = i0.ɵɵnextContext(3).$implicit;
129
+ const ctx_r1 = i0.ɵɵnextContext();
130
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.text(plan_r1.cta.label), " ");
131
+ } }
132
+ function PricingTable_For_5_Conditional_12_Conditional_1_Template(rf, ctx) { if (rf & 1) {
133
+ const _r3 = i0.ɵɵgetCurrentView();
134
+ i0.ɵɵelementStart(0, "button", 7);
135
+ i0.ɵɵlistener("click", function PricingTable_For_5_Conditional_12_Conditional_1_Template_button_click_0_listener($event) { i0.ɵɵrestoreView(_r3); const plan_r1 = i0.ɵɵnextContext(2).$implicit; const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.invoke(plan_r1.cta.onClick, $event)); });
136
+ i0.ɵɵconditionalCreate(1, PricingTable_For_5_Conditional_12_Conditional_1_Conditional_1_Template, 1, 1, "ng-container", 4)(2, PricingTable_For_5_Conditional_12_Conditional_1_Conditional_2_Template, 1, 1);
137
+ i0.ɵɵelementEnd();
138
+ } if (rf & 2) {
139
+ const plan_r1 = i0.ɵɵnextContext(2).$implicit;
140
+ const ctx_r1 = i0.ɵɵnextContext();
141
+ i0.ɵɵproperty("variant", "solid")("color", plan_r1.recommended ? "primary" : "secondary");
142
+ i0.ɵɵadvance();
143
+ i0.ɵɵconditional(ctx_r1.isTemplate(plan_r1.cta.label) ? 1 : 2);
144
+ } }
145
+ function PricingTable_For_5_Conditional_12_Template(rf, ctx) { if (rf & 1) {
146
+ i0.ɵɵconditionalCreate(0, PricingTable_For_5_Conditional_12_Conditional_0_Template, 4, 4, "a")(1, PricingTable_For_5_Conditional_12_Conditional_1_Template, 3, 3, "button", 6);
147
+ } if (rf & 2) {
148
+ const plan_r1 = i0.ɵɵnextContext().$implicit;
149
+ i0.ɵɵconditional(plan_r1.cta.href ? 0 : 1);
150
+ } }
151
+ function PricingTable_For_5_Template(rf, ctx) { if (rf & 1) {
152
+ i0.ɵɵelementStart(0, "th", 2)(1, "div", 3)(2, "div")(3, "h3");
153
+ i0.ɵɵconditionalCreate(4, PricingTable_For_5_Conditional_4_Template, 1, 1, "ng-container", 4)(5, PricingTable_For_5_Conditional_5_Template, 1, 1);
154
+ i0.ɵɵelementEnd();
155
+ i0.ɵɵconditionalCreate(6, PricingTable_For_5_Conditional_6_Template, 3, 3, "p", 5);
156
+ i0.ɵɵelementStart(7, "div")(8, "span");
157
+ i0.ɵɵconditionalCreate(9, PricingTable_For_5_Conditional_9_Template, 1, 1, "ng-container", 4)(10, PricingTable_For_5_Conditional_10_Template, 1, 1);
158
+ i0.ɵɵelementEnd();
159
+ i0.ɵɵconditionalCreate(11, PricingTable_For_5_Conditional_11_Template, 3, 3, "span", 5);
160
+ i0.ɵɵelementEnd();
161
+ i0.ɵɵconditionalCreate(12, PricingTable_For_5_Conditional_12_Template, 2, 1);
162
+ i0.ɵɵelementEnd()()();
163
+ } if (rf & 2) {
164
+ const plan_r1 = ctx.$implicit;
165
+ const ctx_r1 = i0.ɵɵnextContext();
166
+ i0.ɵɵadvance();
167
+ i0.ɵɵstyleMap(ctx_r1.cardStyle(plan_r1));
168
+ i0.ɵɵadvance();
169
+ i0.ɵɵclassMap(ctx_r1.cm().stack(2));
170
+ i0.ɵɵadvance();
171
+ i0.ɵɵclassMap(ctx_r1.cm().cn(ctx_r1.cm().textSize("lg"), ctx_r1.cm().fontWeight("bold")));
172
+ i0.ɵɵadvance();
173
+ i0.ɵɵconditional(ctx_r1.isTemplate(plan_r1.name) ? 4 : 5);
174
+ i0.ɵɵadvance(2);
175
+ i0.ɵɵconditional(plan_r1.description ? 6 : -1);
176
+ i0.ɵɵadvance();
177
+ i0.ɵɵclassMap(ctx_r1.cm().flex(i0.ɵɵpureFunction0(15, _c0)));
178
+ i0.ɵɵadvance();
179
+ i0.ɵɵclassMap(ctx_r1.cm().cn(ctx_r1.cm().textSize("2xl"), ctx_r1.cm().fontWeight("bold")));
180
+ i0.ɵɵadvance();
181
+ i0.ɵɵconditional(ctx_r1.isTemplate(plan_r1.price) ? 9 : 10);
182
+ i0.ɵɵadvance(2);
183
+ i0.ɵɵconditional(plan_r1.interval ? 11 : -1);
184
+ i0.ɵɵadvance();
185
+ i0.ɵɵconditional(plan_r1.cta ? 12 : -1);
186
+ } }
187
+ function PricingTable_For_8_Conditional_0_Conditional_3_Template(rf, ctx) { if (rf & 1) {
188
+ i0.ɵɵelementContainer(0, 4);
189
+ } if (rf & 2) {
190
+ const feature_r4 = i0.ɵɵnextContext(2).$implicit;
191
+ const ctx_r1 = i0.ɵɵnextContext();
192
+ i0.ɵɵproperty("ngTemplateOutlet", ctx_r1.asTemplate(feature_r4.groupHeading));
193
+ } }
194
+ function PricingTable_For_8_Conditional_0_Conditional_4_Template(rf, ctx) { if (rf & 1) {
195
+ i0.ɵɵtext(0);
196
+ } if (rf & 2) {
197
+ const feature_r4 = i0.ɵɵnextContext(2).$implicit;
198
+ const ctx_r1 = i0.ɵɵnextContext();
199
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.text(feature_r4.groupHeading), " ");
200
+ } }
201
+ function PricingTable_For_8_Conditional_0_Template(rf, ctx) { if (rf & 1) {
202
+ i0.ɵɵelementStart(0, "tr")(1, "th", 10)(2, "span");
203
+ i0.ɵɵconditionalCreate(3, PricingTable_For_8_Conditional_0_Conditional_3_Template, 1, 1, "ng-container", 4)(4, PricingTable_For_8_Conditional_0_Conditional_4_Template, 1, 1);
204
+ i0.ɵɵelementEnd()()();
205
+ } if (rf & 2) {
206
+ const feature_r4 = i0.ɵɵnextContext().$implicit;
207
+ const ctx_r1 = i0.ɵɵnextContext();
208
+ i0.ɵɵadvance();
209
+ i0.ɵɵattribute("colspan", ctx_r1.plans.length + 1);
210
+ i0.ɵɵadvance();
211
+ i0.ɵɵclassMap(ctx_r1.cm().cn(ctx_r1.cm().textSize("xs"), ctx_r1.cm().fontWeight("semibold")));
212
+ i0.ɵɵadvance();
213
+ i0.ɵɵconditional(ctx_r1.isTemplate(feature_r4.groupHeading) ? 3 : 4);
214
+ } }
215
+ function PricingTable_For_8_Conditional_4_Template(rf, ctx) { if (rf & 1) {
216
+ i0.ɵɵelementContainer(0, 4);
217
+ } if (rf & 2) {
218
+ const feature_r4 = i0.ɵɵnextContext().$implicit;
219
+ const ctx_r1 = i0.ɵɵnextContext();
220
+ i0.ɵɵproperty("ngTemplateOutlet", ctx_r1.asTemplate(feature_r4.label));
221
+ } }
222
+ function PricingTable_For_8_Conditional_5_Template(rf, ctx) { if (rf & 1) {
223
+ i0.ɵɵtext(0);
224
+ } if (rf & 2) {
225
+ const feature_r4 = i0.ɵɵnextContext().$implicit;
226
+ const ctx_r1 = i0.ɵɵnextContext();
227
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.text(feature_r4.label), " ");
228
+ } }
229
+ function PricingTable_For_8_For_7_Conditional_3_Template(rf, ctx) { if (rf & 1) {
230
+ i0.ɵɵelementContainer(0, 4);
231
+ } if (rf & 2) {
232
+ i0.ɵɵnextContext();
233
+ const value_r5 = i0.ɵɵreadContextLet(0);
234
+ const ctx_r1 = i0.ɵɵnextContext(2);
235
+ i0.ɵɵproperty("ngTemplateOutlet", ctx_r1.asTemplate(value_r5));
236
+ } }
237
+ function PricingTable_For_8_For_7_Conditional_4_Template(rf, ctx) { if (rf & 1) {
238
+ i0.ɵɵtext(0);
239
+ } if (rf & 2) {
240
+ i0.ɵɵnextContext();
241
+ const value_r5 = i0.ɵɵreadContextLet(0);
242
+ const ctx_r1 = i0.ɵɵnextContext(2);
243
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.text(value_r5), " ");
244
+ } }
245
+ function PricingTable_For_8_For_7_Template(rf, ctx) { if (rf & 1) {
246
+ i0.ɵɵdeclareLet(0);
247
+ i0.ɵɵelementStart(1, "td", 9)(2, "span");
248
+ i0.ɵɵconditionalCreate(3, PricingTable_For_8_For_7_Conditional_3_Template, 1, 1, "ng-container", 4)(4, PricingTable_For_8_For_7_Conditional_4_Template, 1, 1);
249
+ i0.ɵɵelementEnd()();
250
+ } if (rf & 2) {
251
+ const plan_r6 = ctx.$implicit;
252
+ const feature_r4 = i0.ɵɵnextContext().$implicit;
253
+ const ctx_r1 = i0.ɵɵnextContext();
254
+ const value_r7 = i0.ɵɵstoreLet(ctx_r1.renderValue(feature_r4.values[plan_r6.id]));
255
+ i0.ɵɵadvance(2);
256
+ i0.ɵɵclassMap(ctx_r1.cm().textSize("sm"));
257
+ i0.ɵɵadvance();
258
+ i0.ɵɵconditional(ctx_r1.isTemplate(value_r7) ? 3 : 4);
259
+ } }
260
+ function PricingTable_For_8_Template(rf, ctx) { if (rf & 1) {
261
+ i0.ɵɵconditionalCreate(0, PricingTable_For_8_Conditional_0_Template, 5, 4, "tr");
262
+ i0.ɵɵelementStart(1, "tr")(2, "td", 8)(3, "span");
263
+ i0.ɵɵconditionalCreate(4, PricingTable_For_8_Conditional_4_Template, 1, 1, "ng-container", 4)(5, PricingTable_For_8_Conditional_5_Template, 1, 1);
264
+ i0.ɵɵelementEnd()();
265
+ i0.ɵɵrepeaterCreate(6, PricingTable_For_8_For_7_Template, 5, 4, "td", 9, _forTrack0);
266
+ i0.ɵɵelementEnd();
267
+ } if (rf & 2) {
268
+ const feature_r4 = ctx.$implicit;
269
+ const ctx_r1 = i0.ɵɵnextContext();
270
+ i0.ɵɵconditional(feature_r4.groupHeading ? 0 : -1);
271
+ i0.ɵɵadvance(3);
272
+ i0.ɵɵclassMap(ctx_r1.cm().textSize("sm"));
273
+ i0.ɵɵadvance();
274
+ i0.ɵɵconditional(ctx_r1.isTemplate(feature_r4.label) ? 4 : 5);
275
+ i0.ɵɵadvance(2);
276
+ i0.ɵɵrepeater(ctx_r1.plans);
277
+ } }
278
+ /**
279
+ * PricingTable component.
280
+ *
281
+ * Side-by-side pricing comparison — features × plans matrix. A header row
282
+ * holds plan cards (name, description, price, interval, CTA); body rows show
283
+ * per-feature availability (`true` → ✓, `false` → —, strings/templates pass
284
+ * through). The wrapper scrolls horizontally when columns overflow.
285
+ *
286
+ * The host IS the outer `<div>` (`div[mol-pricing-table]`), matching React's
287
+ * root exactly. Node-valued fields (`plans[].name`, …) are projected templates
288
+ * in Angular (an input cannot carry a node), rendered through
289
+ * `ngTemplateOutlet`; plain strings render as text.
290
+ */
291
+ export class PricingTable {
292
+ /** The plan columns, left to right. */
293
+ plans = [];
294
+ /** The feature rows, top to bottom. */
295
+ features = [];
296
+ /** Extra classes on the outer wrapper. */
297
+ className;
298
+ /**
299
+ * The current class map.
300
+ * @returns The UIClassMap.
301
+ */
302
+ cm() {
303
+ return getClassMap();
304
+ }
305
+ /**
306
+ * Computes the wrapper class list.
307
+ * @returns The class string.
308
+ */
309
+ classes() {
310
+ return this.cm().cn(this.cm().stack(0), this.className);
311
+ }
312
+ /**
313
+ * The recommended plan's outline style, in React's shape.
314
+ * @param plan - The plan.
315
+ * @returns The style object, or undefined for a plain column.
316
+ */
317
+ cardStyle(plan) {
318
+ return plan.recommended
319
+ ? { outline: '2px solid currentColor', outlineOffset: '-2px' }
320
+ : undefined;
321
+ }
322
+ /**
323
+ * Whether a node-valued field arrived as a projected template.
324
+ * @param value - The field value.
325
+ * @returns True for a template.
326
+ */
327
+ isTemplate(value) {
328
+ return value instanceof TemplateRef;
329
+ }
330
+ /**
331
+ * A node-valued field as a template (the `@if` above already checked it).
332
+ * @param value - The field value.
333
+ * @returns The template, or null when it is not one.
334
+ */
335
+ asTemplate(value) {
336
+ return value instanceof TemplateRef ? value : null;
337
+ }
338
+ /**
339
+ * A node-valued field as display text.
340
+ * @param value - The field value.
341
+ * @returns Its text, or an empty string when absent.
342
+ */
343
+ text(value) {
344
+ return value === null || value === undefined ? '' : String(value);
345
+ }
346
+ /**
347
+ * Renders a feature cell value: `true` → ✓, `false` → —, anything else
348
+ * pass-through.
349
+ * @param value - The per-plan feature value.
350
+ * @returns The content to render.
351
+ */
352
+ renderValue(value) {
353
+ if (value === true)
354
+ return '✓';
355
+ if (value === false)
356
+ return '—';
357
+ return value;
358
+ }
359
+ /**
360
+ * Calls a plan's click handler with the DOM event, as React's `Button` does.
361
+ * @param handler - The plan's `onClick`, when it has one.
362
+ * @param event - The click event.
363
+ */
364
+ invoke(handler, event) {
365
+ handler?.(event);
366
+ }
367
+ static ɵfac = function PricingTable_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || PricingTable)(); };
368
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: PricingTable, selectors: [["div", "mol-pricing-table", ""]], hostAttrs: [2, "overflow-x", "auto"], hostVars: 2, hostBindings: function PricingTable_HostBindings(rf, ctx) { if (rf & 2) {
369
+ i0.ɵɵclassMap(ctx.classes());
370
+ } }, inputs: { plans: "plans", features: "features", className: "className" }, decls: 9, vars: 0, consts: [[2, "width", "100%", "border-collapse", "separate", "border-spacing", "0px"], [2, "min-width", "160px", "text-align", "left"], [2, "vertical-align", "top", "padding", "12px"], ["mol-card", ""], [3, "ngTemplateOutlet"], [3, "class"], ["mol-button", "", 3, "variant", "color"], ["mol-button", "", 3, "click", "variant", "color"], [2, "padding", "8px", "text-align", "left"], [2, "padding", "8px", "text-align", "center"], [2, "text-align", "left", "padding", "12px 8px"]], template: function PricingTable_Template(rf, ctx) { if (rf & 1) {
371
+ i0.ɵɵelementStart(0, "table", 0)(1, "thead")(2, "tr");
372
+ i0.ɵɵelement(3, "th", 1);
373
+ i0.ɵɵrepeaterCreate(4, PricingTable_For_5_Template, 13, 16, "th", 2, _forTrack0);
374
+ i0.ɵɵelementEnd()();
375
+ i0.ɵɵelementStart(6, "tbody");
376
+ i0.ɵɵrepeaterCreate(7, PricingTable_For_8_Template, 8, 4, null, null, i0.ɵɵrepeaterTrackByIndex);
377
+ i0.ɵɵelementEnd()();
378
+ } if (rf & 2) {
379
+ i0.ɵɵadvance(4);
380
+ i0.ɵɵrepeater(ctx.plans);
381
+ i0.ɵɵadvance(3);
382
+ i0.ɵɵrepeater(ctx.features);
383
+ } }, dependencies: [Button, Card, NgTemplateOutlet], encapsulation: 2 });
384
+ }
385
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(PricingTable, [{
386
+ type: Component,
387
+ args: [{
388
+ selector: 'div[mol-pricing-table]',
389
+ standalone: true,
390
+ imports: [Button, Card, NgTemplateOutlet],
391
+ inputs: ['plans', 'features', 'className'],
392
+ host: {
393
+ style: 'overflow-x: auto',
394
+ '[class]': 'classes()',
395
+ },
396
+ template: `<table style="width: 100%; border-collapse: separate; border-spacing: 0px">
397
+ <thead>
398
+ <tr>
399
+ <th style="min-width: 160px; text-align: left"></th>
400
+ @for (plan of plans; track plan.id) {
401
+ <th style="vertical-align: top; padding: 12px">
402
+ <div mol-card [style]="cardStyle(plan)">
403
+ <div [class]="cm().stack(2)">
404
+ <h3 [class]="cm().cn(cm().textSize('lg'), cm().fontWeight('bold'))">
405
+ @if (isTemplate(plan.name)) {
406
+ <ng-container [ngTemplateOutlet]="asTemplate(plan.name)"></ng-container>
407
+ } @else {
408
+ {{ text(plan.name) }}
409
+ }
410
+ </h3>
411
+ @if (plan.description) {
412
+ <p [class]="cm().textSize('sm')">
413
+ @if (isTemplate(plan.description)) {
414
+ <ng-container
415
+ [ngTemplateOutlet]="asTemplate(plan.description)"
416
+ ></ng-container>
417
+ } @else {
418
+ {{ text(plan.description) }}
419
+ }
420
+ </p>
421
+ }
422
+ <div [class]="cm().flex({ align: 'baseline', gap: 'xs' })">
423
+ <span [class]="cm().cn(cm().textSize('2xl'), cm().fontWeight('bold'))">
424
+ @if (isTemplate(plan.price)) {
425
+ <ng-container [ngTemplateOutlet]="asTemplate(plan.price)"></ng-container>
426
+ } @else {
427
+ {{ text(plan.price) }}
428
+ }
429
+ </span>
430
+ @if (plan.interval) {
431
+ <span [class]="cm().textSize('xs')">
432
+ @if (isTemplate(plan.interval)) {
433
+ <ng-container [ngTemplateOutlet]="asTemplate(plan.interval)"></ng-container>
434
+ } @else {
435
+ {{ text(plan.interval) }}
436
+ }
437
+ </span>
438
+ }
439
+ </div>
440
+ @if (plan.cta) {
441
+ @if (plan.cta.href) {
442
+ <a [attr.href]="plan.cta.href">
443
+ <button
444
+ mol-button
445
+ [variant]="'solid'"
446
+ [color]="plan.recommended ? 'primary' : 'secondary'"
447
+ >
448
+ @if (isTemplate(plan.cta.label)) {
449
+ <ng-container
450
+ [ngTemplateOutlet]="asTemplate(plan.cta.label)"
451
+ ></ng-container>
452
+ } @else {
453
+ {{ text(plan.cta.label) }}
454
+ }
455
+ </button>
456
+ </a>
457
+ } @else {
458
+ <button
459
+ mol-button
460
+ [variant]="'solid'"
461
+ [color]="plan.recommended ? 'primary' : 'secondary'"
462
+ (click)="invoke(plan.cta.onClick, $event)"
463
+ >
464
+ @if (isTemplate(plan.cta.label)) {
465
+ <ng-container
466
+ [ngTemplateOutlet]="asTemplate(plan.cta.label)"
467
+ ></ng-container>
468
+ } @else {
469
+ {{ text(plan.cta.label) }}
470
+ }
471
+ </button>
472
+ }
473
+ }
474
+ </div>
475
+ </div>
476
+ </th>
477
+ }
478
+ </tr>
479
+ </thead>
480
+ <tbody>
481
+ @for (feature of features; track $index) {
482
+ @if (feature.groupHeading) {
483
+ <tr>
484
+ <th [attr.colspan]="plans.length + 1" style="text-align: left; padding: 12px 8px">
485
+ <span [class]="cm().cn(cm().textSize('xs'), cm().fontWeight('semibold'))">
486
+ @if (isTemplate(feature.groupHeading)) {
487
+ <ng-container
488
+ [ngTemplateOutlet]="asTemplate(feature.groupHeading)"
489
+ ></ng-container>
490
+ } @else {
491
+ {{ text(feature.groupHeading) }}
492
+ }
493
+ </span>
494
+ </th>
495
+ </tr>
496
+ }
497
+ <tr>
498
+ <td style="padding: 8px; text-align: left">
499
+ <span [class]="cm().textSize('sm')">
500
+ @if (isTemplate(feature.label)) {
501
+ <ng-container [ngTemplateOutlet]="asTemplate(feature.label)"></ng-container>
502
+ } @else {
503
+ {{ text(feature.label) }}
504
+ }
505
+ </span>
506
+ </td>
507
+ @for (plan of plans; track plan.id) {
508
+ @let value = renderValue(feature.values[plan.id]);
509
+ <td style="padding: 8px; text-align: center">
510
+ <span [class]="cm().textSize('sm')">
511
+ @if (isTemplate(value)) {
512
+ <ng-container [ngTemplateOutlet]="asTemplate(value)"></ng-container>
513
+ } @else {
514
+ {{ text(value) }}
515
+ }
516
+ </span>
517
+ </td>
518
+ }
519
+ </tr>
520
+ }
521
+ </tbody>
522
+ </table>`,
523
+ }]
524
+ }], null, null); })();
525
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(PricingTable, { className: "PricingTable", filePath: "pricing-table.component.ts", lineNumber: 166 }); })();
526
+ //# sourceMappingURL=pricing-table.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing-table.component.js","sourceRoot":"","sources":["../src/pricing-table.component.ts"],"names":[],"mappings":"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"}