Add logical (yes/no/?) data entry
This commit is contained in:
parent
f931195053
commit
26a91a229e
@ -0,0 +1,100 @@
|
||||
import React from 'react';
|
||||
|
||||
import { BaseDataEntryProps } from '../data-entry';
|
||||
import { DataTitleCopyable } from '../data-title';
|
||||
|
||||
interface ToggleButtonProps {
|
||||
value: string;
|
||||
checked: boolean;
|
||||
disabled: boolean;
|
||||
onChange: React.ChangeEventHandler<HTMLInputElement>;
|
||||
checkedClassName: string;
|
||||
uncheckedClassName: string;
|
||||
}
|
||||
|
||||
const ToggleButton: React.FC<ToggleButtonProps> = ({
|
||||
value,
|
||||
checked,
|
||||
disabled,
|
||||
onChange,
|
||||
checkedClassName,
|
||||
uncheckedClassName,
|
||||
children
|
||||
}) => {
|
||||
|
||||
return (
|
||||
/**
|
||||
* If the toggle button is both checked and disabled, we can't set disabled CSS class
|
||||
* because then Bootstrap makes the button look like it wasn't checked.
|
||||
* So we skip the class and force cursor type manually so it doesn't look clickable.
|
||||
*/
|
||||
<label className={`btn ${checked ? checkedClassName : uncheckedClassName} ${disabled && !checked && 'disabled'}`}
|
||||
{...disabled && checked && {
|
||||
style: { cursor: 'default'}
|
||||
}}
|
||||
>
|
||||
<input type="radio" name="options" value={value + ''}
|
||||
autoComplete="off"
|
||||
checked={checked}
|
||||
onChange={onChange}
|
||||
disabled={disabled}
|
||||
/>
|
||||
{children}
|
||||
</label>
|
||||
);
|
||||
}
|
||||
|
||||
interface LogicalDataEntryProps extends BaseDataEntryProps {
|
||||
value: boolean;
|
||||
disallowTrue?: boolean;
|
||||
disallowFalse?: boolean;
|
||||
disallowNull?: boolean;
|
||||
}
|
||||
|
||||
export const LogicalDataEntry: React.FC<LogicalDataEntryProps> = (props) => {
|
||||
function handleValueChange(e: React.ChangeEvent<HTMLInputElement>) {
|
||||
props.onChange?.(props.slug, e.target.value === 'null' ? null : e.target.value === 'true');
|
||||
}
|
||||
|
||||
const isDisabled = props.mode === 'view' || props.disabled;
|
||||
|
||||
return (
|
||||
<>
|
||||
<DataTitleCopyable
|
||||
slug={props.slug}
|
||||
title={props.title}
|
||||
tooltip={props.tooltip}
|
||||
disabled={props.disabled || props.value == undefined}
|
||||
copy={props.copy}
|
||||
/>
|
||||
<div className="btn-group btn-group-toggle">
|
||||
<ToggleButton
|
||||
value="true"
|
||||
checked={props.value === true}
|
||||
disabled={isDisabled || props.disallowTrue}
|
||||
checkedClassName='btn-outline-dark active'
|
||||
uncheckedClassName='btn-outline-dark'
|
||||
onChange={handleValueChange}
|
||||
>Yes</ToggleButton>
|
||||
|
||||
<ToggleButton
|
||||
value="null"
|
||||
checked={props.value == null}
|
||||
disabled={isDisabled || props.disallowNull}
|
||||
checkedClassName='btn-secondary active'
|
||||
uncheckedClassName='btn-outline-dark'
|
||||
onChange={handleValueChange}
|
||||
>?</ToggleButton>
|
||||
|
||||
<ToggleButton
|
||||
value="false"
|
||||
checked={props.value === false}
|
||||
disabled={isDisabled || props.disallowFalse}
|
||||
checkedClassName='btn-outline-dark active'
|
||||
uncheckedClassName='btn-outline-dark'
|
||||
onChange={handleValueChange}
|
||||
>No</ToggleButton>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
Loading…
Reference in New Issue
Block a user