Skip to content

Commit 4b7de27

Browse files
authored
feat(angular/directive): export FeatureFlagDirectiveContext (#1346)
## This PR Exports `FeatureFlagDirectiveContext<T>` from the Angular SDK public API. This change enables external consumers (such as the OpenFeature CLI Angular generator) to safely extend `FeatureFlagDirective<T>` while preserving proper template typing. Previously, `FeatureFlagDirectiveContext<T>` was not exported, which made it impossible to correctly type: `TemplateRef<FeatureFlagDirectiveContext<T>>` when extending `FeatureFlagDirective<T>` outside of the SDK. This PR: - Exports `FeatureFlagDirectiveContext<T>` from the `angular-sdk` public API - Does not introduce any breaking changes - Does not modify runtime behavior - Only expands the public surface to support extension use cases This change is required to support the CLI refactor that generates derived structural directives instead of relying on `hostDirectives`. ### Related Issues Fixes #1345 ### Notes - This is a non-breaking change. - No internal logic has been modified. - The export simply makes an already existing type publicly available. ### Follow-up Tasks - Update the OpenFeature CLI Angular generator to extend `FeatureFlagDirective<T>` directly (instead of using `hostDirectives`) see : open-feature/cli#217 ### How to test 1. Build the Angular SDK package. 2. In an external Angular project, create a directive extending: `FeatureFlagDirective<boolean>` 3. Inject: `TemplateRef<FeatureFlagDirectiveContext<boolean>>` 4. Verify: - TypeScript compiles without internal imports - Template typing is preserved - No runtime behavior changes occur --------- Signed-off-by: backtrack5r3 <flennertom@gmail.com>
1 parent e79c06a commit 4b7de27

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

packages/angular/projects/angular-sdk/src/lib/feature-flag.directive.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { TestingProvider } from '../test/test.utils';
77
import { v4 } from 'uuid';
88
import {
99
BooleanFeatureFlagDirective,
10+
FeatureFlagDirectiveContext,
1011
NumberFeatureFlagDirective,
1112
ObjectFeatureFlagDirective,
1213
StringFeatureFlagDirective,
@@ -181,6 +182,22 @@ class TestComponent {
181182
protected readonly JSON = JSON;
182183
}
183184

185+
describe('FeatureFlagDirectiveContext', () => {
186+
it('should initialize $implicit and evaluationDetails from EvaluationDetails', () => {
187+
const mockDetails = {
188+
value: true,
189+
reason: 'STATIC',
190+
flagKey: 'test-flag',
191+
flagMetadata: {},
192+
};
193+
194+
const context = new FeatureFlagDirectiveContext(mockDetails);
195+
196+
expect(context.$implicit).toBe(true);
197+
expect(context.evaluationDetails).toEqual(mockDetails);
198+
});
199+
});
200+
184201
describe('FeatureFlagDirective', () => {
185202
describe('thenTemplate', () => {
186203
it('should not be rendered if disabled by the flag', async () => {

packages/angular/projects/angular-sdk/src/lib/feature-flag.directive.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,37 @@ import {
2121
OpenFeature,
2222
} from '@openfeature/web-sdk';
2323

24-
class FeatureFlagDirectiveContext<T extends FlagValue> {
24+
/**
25+
* Represents the template context provided by feature flag structural directives
26+
* (`*booleanFeatureFlag`, `*numberFeatureFlag`, `*stringFeatureFlag`, `*objectFeatureFlag`).
27+
*
28+
* This class defines the shape of the data available in your templates when using
29+
* feature flag directives. It exposes:
30+
* - **`$implicit`** — The evaluated flag value, bound via `let value` in templates.
31+
* - **`evaluationDetails`** — The full {@link EvaluationDetails} object containing
32+
* metadata such as `flagKey`, `reason`, `variant`, `flagMetadata`, and potential error info.
33+
*
34+
* @usageNotes
35+
*
36+
* If you need to reference a feature flag template programmatically (e.g. with `@ViewChild`),
37+
* use this class as the generic parameter:
38+
*
39+
* ```typescript
40+
* @ViewChild('flagTpl')
41+
* flagTpl!: TemplateRef<FeatureFlagDirectiveContext<boolean>>;
42+
* ```
43+
*
44+
* This is also useful when building custom components or wrappers that accept
45+
* feature flag templates as inputs:
46+
*
47+
* ```typescript
48+
* @Input() customTemplate: TemplateRef<FeatureFlagDirectiveContext<string>>;
49+
* ```
50+
*
51+
* @template T The type of the flag value (`boolean`, `number`, `string`, or `JsonValue`).
52+
*
53+
*/
54+
export class FeatureFlagDirectiveContext<T extends FlagValue> {
2555
$implicit!: T;
2656
evaluationDetails: EvaluationDetails<T>;
2757

0 commit comments

Comments
 (0)