diff --git a/app/assets/icons/ic-check.svg b/app/assets/icons/ic-check.svg new file mode 100644 index 000000000..93a4a4a42 --- /dev/null +++ b/app/assets/icons/ic-check.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/assets/javascripts/components/DecoratedInput.tsx b/app/assets/javascripts/components/DecoratedInput.tsx index e9058b6dd..fed3ded66 100644 --- a/app/assets/javascripts/components/DecoratedInput.tsx +++ b/app/assets/javascripts/components/DecoratedInput.tsx @@ -10,6 +10,7 @@ interface Props { text?: string; placeholder?: string; onChange?: (text: string) => void; + autocomplete?: boolean; } /** @@ -24,30 +25,47 @@ export const DecoratedInput: FunctionalComponent = ({ text, placeholder = '', onChange, + autocomplete = false, }) => { - const base = - 'rounded py-1.5 px-3 text-input my-1 h-8 flex flex-row items-center gap-4'; + const baseClasses = + 'rounded py-1.5 px-3 text-input my-1 h-8 flex flex-row items-center'; const stateClasses = disabled ? 'no-border bg-grey-5' : 'border-solid border-1 border-gray-300'; - const classes = `${base} ${stateClasses} ${className}`; + const classes = `${baseClasses} ${stateClasses} ${className}`; + const inputBaseClasses = 'w-full no-border color-black focus:shadow-none'; + const inputStateClasses = disabled ? 'overflow-ellipsis' : ''; return (
- {left} + {left?.map((leftChild, idx, arr) => ( + <> + {leftChild} + {idx < arr.length - 1 &&
} + + ))} + {left !== undefined &&
}
onChange && onChange((e.target as HTMLInputElement).value) } + data-lpignore={type !== 'password' ? true : false} + autocomplete={autocomplete ? 'on' : 'off'} />
- {right} + {right !== undefined &&
} + {right?.map((rightChild, idx, arr) => ( + <> + {rightChild} + {idx < arr.length - 1 &&
} + + ))}
); }; diff --git a/app/assets/javascripts/components/Icon.tsx b/app/assets/javascripts/components/Icon.tsx index 1a30ee761..7814ba9b6 100644 --- a/app/assets/javascripts/components/Icon.tsx +++ b/app/assets/javascripts/components/Icon.tsx @@ -26,6 +26,7 @@ import UserIcon from '../../icons/ic-user.svg'; import CopyIcon from '../../icons/ic-copy.svg'; import DownloadIcon from '../../icons/ic-download.svg'; import InfoIcon from '../../icons/ic-info.svg'; +import CheckIcon from '../../icons/ic-check.svg'; import { toDirective } from './utils'; import { FunctionalComponent } from 'preact'; @@ -58,6 +59,7 @@ const ICONS = { copy: CopyIcon, download: DownloadIcon, info: InfoIcon, + check: CheckIcon }; export type IconType = keyof typeof ICONS; diff --git a/app/assets/javascripts/components/IconButton.tsx b/app/assets/javascripts/components/IconButton.tsx index e15517419..e229a23ae 100644 --- a/app/assets/javascripts/components/IconButton.tsx +++ b/app/assets/javascripts/components/IconButton.tsx @@ -10,6 +10,15 @@ interface Props { className?: string; icon: IconType; + + iconClassName?: string; + + /** + * Button tooltip + */ + title: string; + + focusable: boolean; } /** @@ -18,18 +27,20 @@ interface Props { */ export const IconButton: FunctionComponent = ({ onClick, - className, + className = '', icon, + title, + focusable, }) => { const click = (e: MouseEvent) => { e.preventDefault(); onClick(); }; + const focusableClass = focusable ? '' : 'focus:shadow-none'; return (