Skip to content

Commit b3eed0d

Browse files
Pollepsjoepio
authored andcommitted
#243 Add parent scoping to search
1 parent 1b4855f commit b3eed0d

29 files changed

+787
-326
lines changed

data-browser/src/components/Button.tsx

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import styled from 'styled-components';
3+
import { transition } from '../helpers/transition';
34
import { Spinner } from './Spinner';
45

56
export interface ButtonProps
@@ -44,12 +45,6 @@ export const Button = React.forwardRef<
4445

4546
Button.displayName = 'Button';
4647

47-
// /** Style-only props */
48-
// interface ButtonProps {
49-
// // Less visually agressive button. Show only borders in color, instead of entire button
50-
// subtle?: boolean;
51-
// }
52-
5348
/** Extremly minimal set of button properties */
5449
export const ButtonClean = styled.button<ButtonProps>`
5550
cursor: pointer;
@@ -61,7 +56,7 @@ export const ButtonClean = styled.button<ButtonProps>`
6156
margin: 0;
6257
-webkit-appearance: none;
6358
background-color: initial;
64-
-webkit-tap-highlight-color: transparent; /** Remove the tap / click effect on touch devices */
59+
-webkit-tap-highlight-color: transparent; /* Remove the tap / click effect on touch devices */
6560
`;
6661

6762
/** Base button style. You're likely to want to use ButtonMargin in most places */
@@ -73,10 +68,11 @@ export const ButtonBase = styled(ButtonClean)`
7368
background-color: ${props => props.theme.colors.main};
7469
color: ${props => props.theme.colors.bg};
7570
white-space: nowrap;
76-
transition: 0.1s transform, 0.1s background-color, 0.1s box-shadow, 0.1s color;
71+
transition: ${() =>
72+
transition('background-color', 'box-shadow', 'transform', 'color')};
7773
margin-bottom: ${p => (p.gutter ? `${p.theme.margin}rem` : '')};
7874
79-
/** Prevent sticky hover buttons on touch devices */
75+
// Prevent sticky hover buttons on touch devices
8076
@media (hover: hover) and (pointer: fine) {
8177
&:hover:not([disabled]),
8278
&:focus-visible:not([disabled]) {

data-browser/src/components/Details/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export function Details({
3636
<>
3737
<SummaryWrapper>
3838
<IconButton
39+
type='button'
3940
onClick={toggleOpen}
4041
turn={!!isOpen}
4142
hide={!!disabled}

data-browser/src/components/Dropdown/DefaultTrigger.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
import React from 'react';
2-
import { Button } from '../Button';
2+
import { IconButton } from '../IconButton';
33
import { DropdownTriggerRenderFunction } from './DropdownTrigger';
44

55
export const buildDefaultTrigger = (
66
icon: React.ReactNode,
7-
ButtonComp: typeof Button = Button,
87
title = 'Open menu',
8+
ButtonComp: typeof IconButton = IconButton,
99
): DropdownTriggerRenderFunction => {
1010
const Comp = ({ onClick, menuId }, ref: React.Ref<HTMLButtonElement>) => (
1111
<ButtonComp
1212
aria-controls={menuId}
13-
icon
14-
subtle
1513
onClick={onClick}
1614
ref={ref}
1715
title={title}

data-browser/src/components/EditableTitle.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ export function EditableTitle({
2222
}: EditableTitleProps): JSX.Element {
2323
const [text, setText] = useTitle(resource, Infinity, opts);
2424
const [isEditing, setIsEditing] = useState(false);
25-
2625
const innerRef = useRef<HTMLInputElement>(null);
2726
const ref = parentRef || innerRef;
2827

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { IconButton, IconButtonVariant } from './index';
2+
import { Row } from '../Row';
3+
import { FaPoo } from 'react-icons/fa';
4+
5+
# IconButton
6+
7+
## Demo
8+
9+
### Default
10+
11+
<IconButton title='Poopy button'>
12+
<FaPoo />
13+
</IconButton>
14+
15+
### Color
16+
17+
<IconButton color='main' title='Poopy button'>
18+
<FaPoo />
19+
</IconButton>
20+
21+
### Size
22+
23+
<IconButton size='2rem' title='Poopy button'>
24+
<FaPoo />
25+
</IconButton>
26+
27+
### HTML Button attributes
28+
29+
IconButton accepts all html button attributes
30+
31+
<IconButton title='Poopy button' disabled type='submit'>
32+
<FaPoo />
33+
</IconButton>
34+
35+
### Variants
36+
37+
IconButton has the following variants:
38+
39+
```ts
40+
IconButtonVariant.Simple;
41+
IconButtonVariant.Outline;
42+
IconButtonVariant.Fill;
43+
```
44+
45+
<Row>
46+
<IconButton title='Poopy button'>
47+
<FaPoo />
48+
</IconButton>
49+
<IconButton title='Poopy button' variant={IconButtonVariant.Outline}>
50+
<FaPoo />
51+
</IconButton>
52+
<IconButton title='Poopy button' variant={IconButtonVariant.Fill}>
53+
<FaPoo />
54+
</IconButton>
55+
</Row>
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import React from 'react';
2+
import styled, { DefaultTheme } from 'styled-components';
3+
import { transition } from '../../helpers/transition';
4+
5+
export enum IconButtonVariant {
6+
Simple,
7+
Outline,
8+
Fill,
9+
}
10+
11+
type ColorProp = keyof DefaultTheme['colors'] | 'inherit';
12+
13+
interface BaseProps {
14+
className?: string;
15+
variant?: IconButtonVariant;
16+
color?: ColorProp;
17+
size?: string;
18+
title: string;
19+
}
20+
21+
export type IconButtonProps = BaseProps &
22+
React.ButtonHTMLAttributes<HTMLButtonElement>;
23+
24+
export const IconButton = React.forwardRef<
25+
HTMLButtonElement,
26+
React.PropsWithChildren<IconButtonProps>
27+
>(({ variant, children, color, ...props }, ref) => {
28+
const Comp = ComponentMap.get(variant!) ?? SimpleIconButton;
29+
30+
return (
31+
<Comp ref={ref} color={color!} {...props}>
32+
{children}
33+
</Comp>
34+
);
35+
});
36+
37+
IconButton.displayName = 'IconButton';
38+
39+
const defaultProps = {
40+
variant: IconButtonVariant.Simple,
41+
color: 'inherit',
42+
size: '1em',
43+
} as IconButtonProps;
44+
45+
IconButton.defaultProps = defaultProps;
46+
47+
export type IconButtonLinkProps = BaseProps &
48+
React.AnchorHTMLAttributes<HTMLAnchorElement> & {
49+
href: string;
50+
};
51+
52+
export const IconButtonLink = React.forwardRef<
53+
HTMLAnchorElement,
54+
React.PropsWithChildren<IconButtonLinkProps>
55+
>(({ variant, children, color, ...props }, ref) => {
56+
const Comp = ComponentMap.get(variant!) ?? SimpleIconButton;
57+
58+
return (
59+
<Comp ref={ref} color={color!} as='a' {...props}>
60+
{children}
61+
</Comp>
62+
);
63+
});
64+
65+
IconButtonLink.displayName = 'IconButtonLink';
66+
67+
IconButtonLink.defaultProps = defaultProps as IconButtonLinkProps;
68+
69+
interface BaseProps {
70+
size?: string;
71+
}
72+
73+
const IconButtonBase = styled.button<BaseProps>`
74+
--button-padding: 0.4em;
75+
cursor: pointer;
76+
display: inline-grid;
77+
place-items: center;
78+
transition: ${() => transition('background-color', 'color', 'box-shadow')};
79+
color: ${p => p.theme.colors.text};
80+
font-size: ${p => p.size ?? '1em'};
81+
border: none;
82+
83+
padding: var(--button-padding);
84+
width: calc(1em + var(--button-padding) * 2);
85+
height: calc(1em + var(--button-padding) * 2);
86+
87+
&[disabled] {
88+
opacity: 0.5;
89+
cursor: not-allowed;
90+
}
91+
`;
92+
93+
interface ButtonStyleProps {
94+
color: ColorProp;
95+
}
96+
97+
const SimpleIconButton = styled(IconButtonBase)<ButtonStyleProps>`
98+
color: ${p => (p.color === 'inherit' ? 'inherit' : p.theme.colors[p.color])};
99+
background-color: transparent;
100+
border-radius: ${p => p.theme.radius};
101+
102+
&:not([disabled]) {
103+
&:hover,
104+
&:focus {
105+
background-color: ${p => p.theme.colors.bg1};
106+
}
107+
108+
:active {
109+
background-color: ${p => p.theme.colors.bg2};
110+
}
111+
}
112+
`;
113+
114+
const OutlineIconButton = styled(IconButtonBase)<ButtonStyleProps>`
115+
color: ${p => (p.color === 'inherit' ? 'inherit' : p.theme.colors[p.color])};
116+
background-color: ${p => p.theme.colors.bg};
117+
border-radius: 50%;
118+
119+
&:not([disabled]) {
120+
&:hover,
121+
&:focus {
122+
color: ${p => p.theme.colors.main};
123+
box-shadow: 0px 0px 0px 1.5px ${p => p.theme.colors.main},
124+
${p => p.theme.boxShadowSoft};
125+
}
126+
}
127+
128+
&&:active {
129+
background-color: ${p => p.theme.colors.main};
130+
color: white;
131+
}
132+
`;
133+
134+
const FillIconButton = styled(IconButtonBase)<ButtonStyleProps>`
135+
color: ${p => (p.color === 'inherit' ? 'inherit' : p.theme.colors[p.color])};
136+
background-color: unset;
137+
border-radius: 50%;
138+
&:hover,
139+
&:focus {
140+
color: white;
141+
background-color: ${p => p.theme.colors.main};
142+
box-shadow: ${p => p.theme.boxShadowSoft};
143+
}
144+
`;
145+
146+
const ComponentMap = new Map([
147+
[IconButtonVariant.Simple, SimpleIconButton],
148+
[IconButtonVariant.Outline, OutlineIconButton],
149+
[IconButtonVariant.Fill, FillIconButton],
150+
]);

0 commit comments

Comments
 (0)