diff --git a/striker-ui/components/Text/InlineMonoText.tsx b/striker-ui/components/Text/InlineMonoText.tsx index 2032152f..85823d5c 100644 --- a/striker-ui/components/Text/InlineMonoText.tsx +++ b/striker-ui/components/Text/InlineMonoText.tsx @@ -3,12 +3,7 @@ import { FC } from 'react'; import { BodyTextProps } from './BodyText'; import SmallText from './SmallText'; -type InlineMonoTextProps = BodyTextProps; - -const InlineMonoText: FC = ({ - sx, - ...bodyTextRestProps -}) => ( +const InlineMonoText: FC = ({ sx, ...bodyTextRestProps }) => ( = ({ /> ); -export type { InlineMonoTextProps }; - export default InlineMonoText; diff --git a/striker-ui/components/Text/MonoText.tsx b/striker-ui/components/Text/MonoText.tsx index 2c409219..c2cffa45 100644 --- a/striker-ui/components/Text/MonoText.tsx +++ b/striker-ui/components/Text/MonoText.tsx @@ -3,9 +3,7 @@ import { FC } from 'react'; import { BodyTextProps } from './BodyText'; import SmallText from './SmallText'; -type MonoTextProps = BodyTextProps; - -const MonoText: FC = ({ sx, ...bodyTextRestProps }) => ( +const MonoText: FC = ({ sx, ...bodyTextRestProps }) => ( = ({ sx, ...bodyTextRestProps }) => ( /> ); -export type { MonoTextProps }; - export default MonoText; diff --git a/striker-ui/components/Text/SensitiveText.tsx b/striker-ui/components/Text/SensitiveText.tsx new file mode 100644 index 00000000..16aa3509 --- /dev/null +++ b/striker-ui/components/Text/SensitiveText.tsx @@ -0,0 +1,64 @@ +import { createElement, FC, ReactNode, useMemo, useState } from 'react'; + +import BodyText from './BodyText'; +import FlexBox from '../FlexBox'; +import IconButton from '../IconButton'; +import MonoText from './MonoText'; + +const SensitiveText: FC = ({ + children, + monospaced: isMonospaced = false, + revealInitially: isRevealInitially = false, + textProps, +}) => { + const [isReveal, setIsReveal] = useState(isRevealInitially); + + const textElementType = useMemo( + () => (isMonospaced ? MonoText : BodyText), + [isMonospaced], + ); + const contentElement = useMemo(() => { + let content: ReactNode; + + if (isReveal) { + content = + typeof children === 'string' + ? createElement( + textElementType, + { + sx: { + lineHeight: 2.8, + maxWidth: '20em', + overflowY: 'scroll', + whiteSpace: 'nowrap', + }, + ...textProps, + }, + children, + ) + : children; + } else { + content = createElement(textElementType, textProps, '*****'); + } + + return content; + }, [children, isReveal, textElementType, textProps]); + + return ( + + {contentElement} + { + setIsReveal((previous) => !previous); + }} + state={String(isReveal)} + sx={{ marginRight: '-.2em', padding: '.2em' }} + variant="normal" + /> + + ); +}; + +export default SensitiveText; diff --git a/striker-ui/components/Text/SmallText.tsx b/striker-ui/components/Text/SmallText.tsx index 9fdc7bb1..bfe56ee7 100644 --- a/striker-ui/components/Text/SmallText.tsx +++ b/striker-ui/components/Text/SmallText.tsx @@ -2,12 +2,8 @@ import { FC } from 'react'; import BodyText, { BodyTextProps } from './BodyText'; -type SmallTextProps = BodyTextProps; - -const SmallText: FC = ({ ...bodyTextRestProps }) => ( +const SmallText: FC = ({ ...bodyTextRestProps }) => ( ); -export type { SmallTextProps }; - export default SmallText; diff --git a/striker-ui/components/Text/index.tsx b/striker-ui/components/Text/index.tsx index 13f0260b..f72cbbb2 100644 --- a/striker-ui/components/Text/index.tsx +++ b/striker-ui/components/Text/index.tsx @@ -2,8 +2,16 @@ import BodyText, { BodyTextProps } from './BodyText'; import HeaderText from './HeaderText'; import InlineMonoText from './InlineMonoText'; import MonoText from './MonoText'; +import SensitiveText from './SensitiveText'; import SmallText from './SmallText'; export type { BodyTextProps }; -export { BodyText, HeaderText, InlineMonoText, MonoText, SmallText }; +export { + BodyText, + HeaderText, + InlineMonoText, + MonoText, + SensitiveText, + SmallText, +}; diff --git a/striker-ui/types/SensitiveText.d.ts b/striker-ui/types/SensitiveText.d.ts new file mode 100644 index 00000000..2a7921cb --- /dev/null +++ b/striker-ui/types/SensitiveText.d.ts @@ -0,0 +1,7 @@ +type SensitiveTextOptionalProps = { + monospaced?: boolean; + revealInitially?: boolean; + textProps?: import('../components/Text').BodyTextProps; +}; + +type SensitiveTextProps = SensitiveTextOptionalProps;