2022-09-06 01:51:57 +00:00
|
|
|
import {theme, vars} from 'app/client/ui2018/cssVars';
|
2022-12-27 18:35:03 +00:00
|
|
|
import {dom, DomElementArg, IDomArgs, IInputOptions, Observable, styled, subscribe} from 'grainjs';
|
2022-08-22 19:46:25 +00:00
|
|
|
|
|
|
|
export const cssInput = styled('input', `
|
|
|
|
font-size: ${vars.mediumFontSize};
|
|
|
|
height: 48px;
|
|
|
|
line-height: 20px;
|
|
|
|
width: 100%;
|
|
|
|
padding: 14px;
|
2022-09-06 01:51:57 +00:00
|
|
|
border: 1px solid ${theme.inputBorder};
|
2022-08-22 19:46:25 +00:00
|
|
|
border-radius: 4px;
|
|
|
|
outline: none;
|
|
|
|
display: block;
|
2022-09-06 01:51:57 +00:00
|
|
|
color: ${theme.inputFg};
|
|
|
|
background-color: ${theme.inputBg};
|
|
|
|
|
|
|
|
&::placeholder {
|
|
|
|
color: ${theme.inputPlaceholderFg};
|
|
|
|
}
|
2022-08-22 19:46:25 +00:00
|
|
|
|
|
|
|
&[type=number] {
|
|
|
|
-moz-appearance: textfield;
|
|
|
|
}
|
|
|
|
&[type=number]::-webkit-inner-spin-button,
|
|
|
|
&[type=number]::-webkit-outer-spin-button {
|
|
|
|
-webkit-appearance: none;
|
|
|
|
margin: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
&-invalid {
|
2022-09-06 01:51:57 +00:00
|
|
|
border: 1px solid ${theme.inputInvalid};
|
2022-08-22 19:46:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
&-valid {
|
2022-09-06 01:51:57 +00:00
|
|
|
border: 1px solid ${theme.inputValid};
|
2022-08-22 19:46:25 +00:00
|
|
|
}
|
|
|
|
`);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Builds a text input that updates `obs` as you type.
|
|
|
|
*/
|
2023-12-12 09:58:20 +00:00
|
|
|
export function textInput(obs: Observable<string|undefined>, ...args: DomElementArg[]): HTMLInputElement {
|
2022-08-22 19:46:25 +00:00
|
|
|
return cssInput(
|
2023-12-12 09:58:20 +00:00
|
|
|
dom.prop('value', u => u(obs) || ''),
|
2022-08-22 19:46:25 +00:00
|
|
|
dom.on('input', (_e, elem) => obs.set(elem.value)),
|
|
|
|
...args,
|
|
|
|
);
|
|
|
|
}
|
2022-11-28 14:02:32 +00:00
|
|
|
|
|
|
|
export function textarea(
|
|
|
|
obs: Observable<string>, options: IInputOptions, ...args: IDomArgs<HTMLTextAreaElement>
|
|
|
|
): HTMLTextAreaElement {
|
|
|
|
|
|
|
|
const isValid = options.isValid;
|
|
|
|
|
|
|
|
function setValue(elem: HTMLTextAreaElement) {
|
|
|
|
obs.set(elem.value);
|
|
|
|
if (isValid) { isValid.set(elem.validity.valid); }
|
|
|
|
}
|
|
|
|
|
|
|
|
return dom('textarea', ...args,
|
|
|
|
dom.prop('value', obs),
|
|
|
|
(isValid ?
|
|
|
|
(elem) => dom.autoDisposeElem(elem,
|
|
|
|
subscribe(obs, (use) => isValid.set(elem.checkValidity()))) :
|
|
|
|
null),
|
|
|
|
options.onInput ? dom.on('input', (e, elem) => setValue(elem)) : null,
|
|
|
|
dom.on('change', (e, elem) => setValue(elem)),
|
|
|
|
);
|
2023-12-12 09:58:20 +00:00
|
|
|
}
|