(null);
+
+export interface InjectedOuiaProps {
+ ouiaContext?: OuiaContextProps;
+ ouiaId?: number | string;
+}
+
+export interface OuiaContextProps {
+ isOuia?: boolean;
+ ouiaId?: number | string;
+}
+
+export function withOuiaContext>(
+ WrappedComponent: React.ComponentClass
| React.FunctionComponent
+): React.FunctionComponent {
+ return (props: R) => (
+
+ {(value: OuiaContextProps) => }
+
+ );
+}
+
+interface OuiaProps {
+ component: any;
+ componentProps: any;
+ consumerContext?: OuiaContextProps;
+}
+
+interface OuiaState {
+ isOuia?: boolean;
+ ouiaId?: number | string;
+}
+
+class ComponentWithOuia extends React.Component {
+
+ constructor(props: OuiaProps) {
+ super(props);
+
+ this.state = {
+ isOuia: false,
+ ouiaId: null
+ };
+ }
+
+ /**
+ * if either consumer set isOuia through context or local storage
+ * then force a re-render
+ */
+ componentDidMount() {
+ const { isOuia, ouiaId } = this.state;
+ const { consumerContext } = this.props;
+ const isOuiaEnv = isOUIAEnvironment();
+ if ((consumerContext && consumerContext.isOuia !== undefined && consumerContext.isOuia !== isOuia) || isOuiaEnv !== isOuia ) {
+ this.setState({
+ isOuia: consumerContext && consumerContext.isOuia !== undefined ? consumerContext.isOuia : isOuiaEnv,
+ ouiaId: consumerContext && consumerContext.ouiaId !== undefined ? consumerContext.ouiaId : (generateOUIAId() ? getUniqueId() : ouiaId)
+ });
+ }
+ }
+
+ render() {
+ const { isOuia, ouiaId } = this.state;
+ const { component: WrappedComponent, componentProps, consumerContext } = this.props;
+ return (
+
+
+ {(value: OuiaContextProps) => }
+
+
+ )
+ }
+}
diff --git a/packages/patternfly-4/react-core/src/helpers/ouia.ts b/packages/patternfly-4/react-core/src/helpers/ouia.ts
deleted file mode 100644
index 4d52610207f..00000000000
--- a/packages/patternfly-4/react-core/src/helpers/ouia.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export const isOUIAEnvironment = (): boolean => typeof window !== 'undefined' && window.localStorage.ouia;
-
-let id = 0;
-export const getUniqueId = (): number => id++;
diff --git a/packages/patternfly-4/react-integration/cypress/integration/ouia.spec.ts b/packages/patternfly-4/react-integration/cypress/integration/ouia.spec.ts
new file mode 100644
index 00000000000..64021b11bd1
--- /dev/null
+++ b/packages/patternfly-4/react-integration/cypress/integration/ouia.spec.ts
@@ -0,0 +1,19 @@
+describe('Switch Demo Test', () => {
+ it('Navigate to demo section', () => {
+ cy.visit('http://localhost:3000/');
+ cy.get('#ouia-demo-nav-item-link').click();
+ cy.url().should('eq', 'http://localhost:3000/ouia-demo-nav-link')
+ });
+
+ it('Verify Switches exist', () => {
+ cy.get('.pf-c-switch[for="simple-switch"]').should('exist');
+ cy.get('.pf-c-switch[for="disabled-switch-off"]').should('exist');
+ });
+
+ it('Verify OUIA attributes exist', () => {
+ cy.get('.pf-c-switch[for="simple-switch"]').should('have.attr', 'data-ouia-component-type', 'Switch');
+ cy.get('.pf-c-switch[for="simple-switch"]').should('have.attr', 'data-ouia-component-id', 'first_switch');
+ cy.get('.pf-c-switch[for="disabled-switch-off"]').should('have.attr', 'data-ouia-component-type', 'Switch');
+ cy.get('.pf-c-switch[for="disabled-switch-off"]').should('not.have.attr', 'data-ouia-component-id');
+ });
+});
\ No newline at end of file
diff --git a/packages/patternfly-4/react-integration/demo-app-ts/src/Demos.ts b/packages/patternfly-4/react-integration/demo-app-ts/src/Demos.ts
index 42373caae04..923e12977e9 100644
--- a/packages/patternfly-4/react-integration/demo-app-ts/src/Demos.ts
+++ b/packages/patternfly-4/react-integration/demo-app-ts/src/Demos.ts
@@ -321,6 +321,11 @@ export const Demos: DemoInterface[] = [
name: 'Options Menu Demo',
componentType: Examples.OptionsMenuDemo
},
+ {
+ id: 'ouia-demo',
+ name: 'Ouia Demo',
+ componentType: Examples.OuiaDemo
+ },
{
id: 'page-demo',
name: 'Page Demo',
diff --git a/packages/patternfly-4/react-integration/demo-app-ts/src/components/demos/OuiaDemo/OuiaDemo.tsx b/packages/patternfly-4/react-integration/demo-app-ts/src/components/demos/OuiaDemo/OuiaDemo.tsx
new file mode 100644
index 00000000000..f4f5a2fa436
--- /dev/null
+++ b/packages/patternfly-4/react-integration/demo-app-ts/src/components/demos/OuiaDemo/OuiaDemo.tsx
@@ -0,0 +1,39 @@
+import React, { Fragment } from 'react';
+import { Switch, SwitchProps, OuiaContext } from '@patternfly/react-core';
+
+interface SwitchState {
+ isChecked: boolean
+};
+export class OuiaDemo extends React.Component {
+ constructor(props: SwitchProps) {
+ super(props);
+ this.state = {
+ isChecked: true
+ };
+ }
+ handleChange = (isChecked: boolean) => {
+ this.setState({
+ isChecked
+ });
+ };
+
+ render() {
+ const { isChecked } = this.state;
+ return (
+
+
+
+
+
+
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/packages/patternfly-4/react-integration/demo-app-ts/src/components/demos/index.ts b/packages/patternfly-4/react-integration/demo-app-ts/src/components/demos/index.ts
index a3e107713fc..5ef7192cfd6 100644
--- a/packages/patternfly-4/react-integration/demo-app-ts/src/components/demos/index.ts
+++ b/packages/patternfly-4/react-integration/demo-app-ts/src/components/demos/index.ts
@@ -62,6 +62,7 @@ export * from './ModalDemo/ModalDemo';
export * from './NavDemo/NavDemo';
export * from './NotificationBadgeDemo/NotificationBadgeDemo';
export * from './OptionsMenuDemo/OptionsMenuDemo';
+export * from './OuiaDemo/OuiaDemo';
export * from './PieChartDemo/PieBlueDemo';
export * from './PieChartDemo/PieColorDemo';
export * from './PieChartDemo/PieOrangeDemo';