mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
1a6d427339
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
141 lines
4.0 KiB
TypeScript
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};
|
|
}
|
|
`);
|