Skip to content

Commit

Permalink
Merge pull request #75 from patternfly/password_components
Browse files Browse the repository at this point in the history
feat: Add PasswordInput and PasswordHiddenText components
  • Loading branch information
nicolethoen authored Dec 9, 2024
2 parents e218945 + 1470936 commit ff8f672
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';
import { PasswordHiddenText } from "@patternfly/ai-infra-ui-components";


export const PasswordHiddenTextExample: React.FunctionComponent = () => (
<PasswordHiddenText password="Password123!"/>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
# Sidenav top-level section
# should be the same for all markdown files
section: AI-infra-ui-components
# Sidenav secondary level section
# should be the same for all markdown files
id: PasswordInput
# Tab (react | react-demos | html | html-demos | design-guidelines | accessibility)
source: react
# If you use typescript, the name of the interface to display props for
# These are found through the sourceProps function provided in patternfly-docs.source.js
propComponents: ['PasswordInput, PasswordHiddenText']
---

import { PasswordInput, PasswordHiddenText } from "@patternfly/ai-infra-ui-components";

Note: these component document the API and enhance the [existing PasswordInput](https://github.com/opendatahub-io/odh-dashboard/blob/main/frontend/src/components/PasswordInput.tsx) component and [existing PasswordHiddenText](https://github.com/opendatahub-io/odh-dashboard/blob/main/frontend/src/components/PasswordHiddenText.tsx) components from odh-dashboard. It can be imported from [@patternfly/ai-infra-ui-components](https://www.npmjs.com/package/@patternfly/AI-infra-ui-components). Alternatively, they can be used within the odh-dashboard via the `~/components/PasswordInput` and `~/components/PasswordHiddenText` imports.

### Password input example

```js file="./PasswordInputExample.tsx"

```

### Password hidden text example

```js file="./PasswordHiddenTextExample.tsx"

```
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import React from 'react';
import { PasswordInput } from "@patternfly/ai-infra-ui-components";


export const PasswordInputExample: React.FunctionComponent = () => (
<PasswordInput value="Password123!" />
);
43 changes: 43 additions & 0 deletions packages/module/src/PasswordInput/PasswordHiddenText.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Button, Flex, FlexItem, Content } from '@patternfly/react-core';
import { EyeIcon, EyeSlashIcon } from '@patternfly/react-icons';
import React from 'react';

export type PasswordHiddenTextProps = {
/** Read only password text to display */
password: string;
/** Test id to pass to the view password toggle button */
testId: string;
};

export const PasswordHiddenText: React.FunctionComponent<PasswordHiddenTextProps> = ({
password,
testId
}: PasswordHiddenTextProps) => {
const [isHidden, setIsHidden] = React.useState(true);

const passwordText = isHidden ? Array(password.length).fill('\u25CF').join('') : password;

return (
<Flex
spaceItems={{ default: 'spaceItemsXs' }}
spacer={{ default: 'spacerNone' }}
alignItems={{ default: 'alignItemsCenter' }}
flexWrap={{ default: 'nowrap' }}
>
<FlexItem>
<Content>{passwordText}</Content>
</FlexItem>
<FlexItem>
<Button
variant="plain"
onClick={() => setIsHidden(!isHidden)}
data-testid={testId}
>
{isHidden ? <EyeSlashIcon /> : <EyeIcon />}
</Button>
</FlexItem>
</Flex>
);
};

export default PasswordHiddenText;
37 changes: 37 additions & 0 deletions packages/module/src/PasswordInput/PasswordInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import * as React from 'react';
import { Button, InputGroup, TextInput, TextInputProps, InputGroupItem } from '@patternfly/react-core';
import { EyeIcon, EyeSlashIcon } from '@patternfly/react-icons';

export type PasswordInputProps = TextInputProps & {
/** Aria label to display on the view password toggle while the password is hidden */
ariaLabelShow?: string;
/** Aria label to display on the view password toggle while the password is visible */
ariaLabelHide?: string;
};

export const PasswordInput: React.FunctionComponent<PasswordInputProps> = ({
ariaLabelShow = 'Show password',
ariaLabelHide = 'Hide password',
...props
}: PasswordInputProps) => {
const [isPasswordHidden, setPasswordHidden] = React.useState(true);

return (
<InputGroup>
<InputGroupItem isFill>
<TextInput {...props} type={isPasswordHidden ? 'password' : 'text'} />
</InputGroupItem>
<InputGroupItem>
<Button
aria-label={isPasswordHidden ? ariaLabelShow : ariaLabelHide}
variant="control"
onClick={() => setPasswordHidden(!isPasswordHidden)}
>
{isPasswordHidden ? <EyeSlashIcon /> : <EyeIcon />}
</Button>
</InputGroupItem>
</InputGroup>
);
};

export default PasswordInput;
2 changes: 2 additions & 0 deletions packages/module/src/PasswordInput/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './PasswordInput';
export * from './PasswordHiddenText';
1 change: 1 addition & 0 deletions packages/module/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './IndentSection';
export * from './K8sNameDescriptionField';
export * from './TruncatedText';
export * from './EmptyStateErrorMessage';
export * from './PasswordInput'

0 comments on commit ff8f672

Please sign in to comment.