gristlabs_grist-core/app/client/ui2018/buttons.ts
George Gevoian 1a6d427339 (core) Update sort and filter UI
Summary:
The sort and filter UI now has a more unified UI, with similar
capabilities that are accessible from different parts of Grist.
It's now also possible to pin individual filters to the filter bar,
which replaces the old toggle for showing all filters in the
filter bar.

Test Plan: Various tests (browser, migration, project).

Reviewers: jarek, dsagal

Reviewed By: jarek, dsagal

Subscribers: dsagal

Differential Revision: https://phab.getgrist.com/D3669
2022-11-17 15:33:45 -05:00

141 lines
4.0 KiB
TypeScript

/**
* UI 2018 Buttons
*
* Four styles are include: basicButton, primaryButton, bigBasicButton, bigPrimaryButton.
*
* Buttons support passing in DomElementArgs, which can be used to register click handlers, set
* the disabled property, and other HTML <button> element behaviors.
*
* Examples:
*
* `basicButton('Basic button', dom.on('click', () => alert('Basic button')))`
* `primaryButton('Primary button', dom.prop('disabled', true))`
*/
import { theme, vars } from 'app/client/ui2018/cssVars';
import { tbind } from 'app/common/tbind';
import { dom, DomElementArg, styled } from 'grainjs';
export const cssButton = styled('button', `
/* Resets */
position: relative;
outline: none;
border-style: none;
line-height: normal;
user-select: none;
/* Vars */
font-size: ${vars.mediumFontSize};
letter-spacing: -0.08px;
padding: 4px 8px;
background-color: transparent;
color: ${theme.controlFg};
--icon-color: ${theme.controlFg};
border: ${vars.controlBorder};
border-radius: ${vars.controlBorderRadius};
border-color: ${theme.controlBorder};
cursor: pointer;
&-large {
font-weight: 500;
padding: 10px 24px;
min-height: 40px;
}
&-primary {
background-color: ${theme.controlPrimaryBg};
color: ${theme.controlPrimaryFg};
--icon-color: ${theme.controlPrimaryFg};
border-color: ${theme.controlPrimaryBg};
}
&:hover {
color: ${theme.controlHoverFg};
--icon-color: ${theme.controlHoverFg};
border-color: ${theme.controlHoverFg};
}
&-primary:hover {
color: ${theme.controlPrimaryFg};
--icon-color: ${theme.controlPrimaryFg};
background-color: ${theme.controlPrimaryHoverBg};
border-color: ${theme.controlPrimaryHoverBg};
}
&:disabled {
cursor: not-allowed;
color: ${theme.controlDisabledFg};
--icon-color: ${theme.controlDisabledFg};
background-color: ${theme.controlDisabledBg};
border-color: ${theme.controlDisabledBg};
}
`);
interface IButtonProps {
large?: boolean;
primary?: boolean;
link?: boolean;
}
/**
* Helper to create a button or button-like link with requested properties.
*/
function button(props: IButtonProps, ...domArgs: DomElementArg[]) {
const elem = props.link ? cssButtonLink(dom.cls(cssButton.className)) : cssButton();
return dom.update(elem,
cssButton.cls('-large', Boolean(props.large)),
cssButton.cls('-primary', Boolean(props.primary)),
...domArgs
);
}
// Button-creating functions, each taking ...DomElementArg arguments.
export const basicButton = tbind(button, null, {});
export const bigBasicButton = tbind(button, null, {large: true});
export const primaryButton = tbind(button, null, {primary: true});
export const bigPrimaryButton = tbind(button, null, {large: true, primary: true});
// Functions that create button-like <a> links, each taking ...DomElementArg arguments.
export const basicButtonLink = tbind(button, null, {link: true});
export const bigBasicButtonLink = tbind(button, null, {link: true, large: true});
export const primaryButtonLink = tbind(button, null, {link: true, primary: true});
export const bigPrimaryButtonLink = tbind(button, null, {link: true, large: true, primary: true});
// Button that looks like a link (have no background and no border).
export const textButton = styled(cssButton, `
border: none;
padding: 0px;
background-color: inherit !important;
&:disabled {
color: ${theme.controlPrimaryDisabled};
}
`);
const cssButtonLink = styled('a', `
display: inline-block;
&, &:hover, &:focus {
text-decoration: none;
}
`);
export const cssButtonGroup = styled('div', `
display: flex;
flex-direction: row;
& > .${cssButton.className} {
border-radius: 0;
}
& > .${cssButton.className}:first-child {
border-top-left-radius: ${vars.controlBorderRadius};
border-bottom-left-radius: ${vars.controlBorderRadius};
}
& > .${cssButton.className}:last-child {
border-top-right-radius: ${vars.controlBorderRadius};
border-bottom-right-radius: ${vars.controlBorderRadius};
}
`);