From 6c567bffba802778d256c1887f64cc164a11ba3a Mon Sep 17 00:00:00 2001 From: marcozabel Date: Fri, 5 Dec 2025 14:47:48 +0100 Subject: [PATCH 1/3] Use isEqual to compare flags Signed-off-by: marcozabel --- packages/react/src/declarative/FeatureFlag.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react/src/declarative/FeatureFlag.tsx b/packages/react/src/declarative/FeatureFlag.tsx index f1cd967b9..d31a0d15b 100644 --- a/packages/react/src/declarative/FeatureFlag.tsx +++ b/packages/react/src/declarative/FeatureFlag.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { useFlag } from '../evaluation'; import type { FlagQuery } from '../query'; import type { FlagValue, EvaluationDetails } from '@openfeature/core'; +import { isEqual } from '../internal'; /** * Default predicate function that checks if the expected value equals the actual flag value. @@ -10,7 +11,7 @@ import type { FlagValue, EvaluationDetails } from '@openfeature/core'; * @returns {boolean} true if the values match, false otherwise */ function equals(expected: T, actual: EvaluationDetails): boolean { - return expected === actual.value; + return isEqual(expected, actual.value); } /** From 2f186b7f2cbcdfbbd8f9582885ace9daaa0db9d5 Mon Sep 17 00:00:00 2001 From: marcozabel Date: Fri, 5 Dec 2025 14:48:30 +0100 Subject: [PATCH 2/3] Don't render flags if they are non-boolean and have no match provided Signed-off-by: marcozabel --- .../react/src/declarative/FeatureFlag.tsx | 4 +++- packages/react/test/declarative.spec.tsx | 20 +++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/react/src/declarative/FeatureFlag.tsx b/packages/react/src/declarative/FeatureFlag.tsx index d31a0d15b..f2f7143e6 100644 --- a/packages/react/src/declarative/FeatureFlag.tsx +++ b/packages/react/src/declarative/FeatureFlag.tsx @@ -90,9 +90,11 @@ export function FeatureFlag({ } else if (match !== undefined) { // Default behavior: check if match value equals flag value shouldRender = equals(match, details.details as EvaluationDetails); - } else { + } else if (details.type === 'boolean') { // If no match value is provided, render if flag is truthy shouldRender = Boolean(details.value); + } else { + shouldRender = false; } if (shouldRender) { diff --git a/packages/react/test/declarative.spec.tsx b/packages/react/test/declarative.spec.tsx index fcc803631..9744f4dfe 100644 --- a/packages/react/test/declarative.spec.tsx +++ b/packages/react/test/declarative.spec.tsx @@ -69,6 +69,18 @@ describe('Feature Component', () => { expect(screen.queryByText(childText)).toBeInTheDocument(); }); + it('should not show a non-boolean feature flag without match', async () => { + render( + + + + + , + ); + + expect(screen.queryByText(childText)).not.toBeInTheDocument(); + }); + it('should fallback when provided', () => { render( @@ -138,7 +150,7 @@ describe('Feature Component', () => { it('should support function-based fallback with EvaluationDetails', () => { const fallbackFunction = jest.fn((details: EvaluationDetails) =>
Fallback: {details.flagKey}
); - + render( @@ -158,7 +170,7 @@ describe('Feature Component', () => { const fallbackFunction = jest.fn((details: EvaluationDetails) => { return
Flag: {details.flagKey}, Value: {String(details.value)}, Reason: {details.reason}
; }); - + render( @@ -178,9 +190,9 @@ describe('Feature Component', () => { // Create a provider that will cause an error const errorProvider = new InMemoryProvider({}); OpenFeature.setProvider('error-test', errorProvider); - + const fallbackFunction = jest.fn((details: EvaluationDetails) =>
Error fallback: {details.reason}
); - + render( From ea2a96cae24605462c30ad62f3e9f0d5c5d1d6a2 Mon Sep 17 00:00:00 2001 From: marcozabel Date: Fri, 5 Dec 2025 14:56:43 +0100 Subject: [PATCH 3/3] Remove leftover async definition Signed-off-by: marcozabel --- packages/react/test/declarative.spec.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/test/declarative.spec.tsx b/packages/react/test/declarative.spec.tsx index 9744f4dfe..dd9be5ffd 100644 --- a/packages/react/test/declarative.spec.tsx +++ b/packages/react/test/declarative.spec.tsx @@ -69,7 +69,7 @@ describe('Feature Component', () => { expect(screen.queryByText(childText)).toBeInTheDocument(); }); - it('should not show a non-boolean feature flag without match', async () => { + it('should not show a non-boolean feature flag without match', () => { render(