Skip to content

Commit

Permalink
Misc small Admin UI new interfaces changes (#3939)
Browse files Browse the repository at this point in the history
* Misc small Admin UI new interfaces changes

* Fix linting and arrow on popover

* Fix a thing
  • Loading branch information
emmatown committed Oct 13, 2020
1 parent f7306dc commit b6fea2c
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 50 deletions.
7 changes: 2 additions & 5 deletions design-system/packages/core/src/components/Core.tsx
@@ -1,7 +1,7 @@
/* @jsx jsx */

import { jsx, Global } from '../emotion';
import { Fragment, ReactNode, memo } from 'react';
import { Fragment, ReactNode } from 'react';

import { normalize } from '../normalize';
import { useTheme } from '../theme';
Expand All @@ -15,9 +15,6 @@ type CoreProps = {
optimizeLegibility?: boolean;
};

// only re-render leaf nodes that listen to theme changes
const App = memo(props => <Fragment {...props} />);

export const Core = ({
children,
includeNormalize = true,
Expand All @@ -26,7 +23,7 @@ export const Core = ({
return (
<Fragment>
<BaseCSS includeNormalize={includeNormalize} optimizeLegibility={optimizeLegibility} />
<App>{children}</App>
{children}
</Fragment>
);
};
Expand Down
2 changes: 2 additions & 0 deletions design-system/packages/fields/src/index.ts
Expand Up @@ -15,3 +15,5 @@ export { Switch } from './Switch';
export { TextArea } from './TextArea';
export { TextInput } from './TextInput';
export { SelectInput } from './SelectInput';
export { useIndicatorTokens, useIndicatorStyles } from './hooks/indicators';
export { useInputTokens, useInputStyles } from './hooks/inputs';
1 change: 1 addition & 0 deletions design-system/packages/options/package.json
Expand Up @@ -14,6 +14,7 @@
"dependencies": {
"@babel/runtime": "^7.11.2",
"@keystone-ui/core": "*",
"@keystone-ui/fields": "*",
"@keystone-ui/icons": "*",
"@types/react-select": "^3.0.22",
"react-select": "^3.1.0"
Expand Down
68 changes: 42 additions & 26 deletions design-system/packages/options/src/index.tsx
@@ -1,5 +1,6 @@
/** @jsx jsx */
import { jsx, useTheme } from '@keystone-ui/core';
import { useIndicatorTokens } from '@keystone-ui/fields';
import { CheckIcon } from '@keystone-ui/icons/icons/CheckIcon';
import { ComponentProps, useMemo } from 'react';
import ReactSelect, { components as reactSelectComponents, Props } from 'react-select';
Expand All @@ -13,40 +14,55 @@ export const CheckMark = ({
isFocused?: boolean;
isSelected?: boolean;
}) => {
let bg;
let fg;
let border;
let size = 24;

const theme = useTheme();

if (isDisabled) {
bg = theme.fields.disabled.controlForeground;
fg = isSelected ? 'white' : theme.fields.disabled.controlForeground;
border = theme.fields.disabled.controlForeground;
} else if (isSelected) {
bg = isFocused ? 'white' : theme.fields.selected.controlBorderColor;
fg = isFocused ? theme.fields.selected.controlBorderColor : 'white';
border = theme.fields.selected.controlBorderColor;
} else {
border = isFocused ? theme.fields.focus.controlBorderColor : theme.fields.controlBorderColor;
bg = 'white';
fg = 'white';
}
const tokens = useIndicatorTokens({
size: 'medium',
type: 'radio',
});

return (
<div
className={`${isDisabled ? 'disabled ' : ''}${isFocused ? 'focus ' : ''}${
isSelected ? 'selected' : ''
}`}
css={{
alignItems: 'center',
backgroundColor: bg,
border: `2px solid ${border}`,
borderRadius: size,
backgroundColor: tokens.background,
borderColor: tokens.borderColor,
borderRadius: tokens.borderRadius,
borderStyle: 'solid',
borderWidth: tokens.borderWidth,
boxSizing: 'border-box',
color: fg,
color: tokens.foreground,
cursor: 'pointer',
display: 'flex',
height: size,
flexShrink: 0,
height: tokens.boxSize,
justifyContent: 'center',
width: size,
transition: tokens.transition,
width: tokens.boxSize,

'&.focus': {
backgroundColor: tokens.focus.background,
borderColor: tokens.focus.borderColor,
boxShadow: tokens.focus.shadow,
color: tokens.focus.foreground,
},
'&.selected': {
backgroundColor: tokens.selected.background,
borderColor: tokens.selected.borderColor,
boxShadow: tokens.selected.shadow,
color: tokens.selected.foreground,
},
'&.disabled': {
backgroundColor: tokens.disabled.background,
borderColor: tokens.disabled.borderColor,
boxShadow: tokens.disabled.shadow,
color: tokens.disabled.background,
cursor: 'default',
},
'&.selected.disabled': {
color: tokens.disabled.foreground,
},
}}
>
<CheckIcon size="small" />
Expand Down
79 changes: 75 additions & 4 deletions design-system/packages/popover/src/Popover.tsx
Expand Up @@ -9,6 +9,7 @@ import {
useEffect,
useState,
useCallback,
CSSProperties,
} from 'react';
import { Options, Placement } from '@popperjs/core';
import { usePopper } from 'react-popper';
Expand Down Expand Up @@ -113,7 +114,7 @@ type Props = {
};

export const Popover = ({ placement = 'bottom', triggerRenderer, ...props }: Props) => {
const { isOpen, setOpen, trigger, dialog } = usePopover({
const { isOpen, setOpen, trigger, dialog, arrow } = usePopover({
placement,
modifiers: [
{
Expand All @@ -135,7 +136,13 @@ export const Popover = ({ placement = 'bottom', triggerRenderer, ...props }: Pro
onClick: () => setOpen(true),
},
})}
<PopoverDialog isVisible={isOpen} ref={dialog.ref} {...dialog.props} {...props} />
<PopoverDialog
isVisible={isOpen}
arrow={arrow}
ref={dialog.ref}
{...dialog.props}
{...props}
/>
</Fragment>
);
};
Expand All @@ -148,10 +155,16 @@ type DialogProps = {
children: ReactNode;
/** When true, the popover will be visible. */
isVisible: boolean;
arrow: {
ref: (element: HTMLDivElement) => void;
props: {
style: CSSProperties;
};
};
};

export const PopoverDialog = forwardRef<HTMLDivElement, DialogProps>(
({ isVisible, ...props }, consumerRef) => {
({ isVisible, children, arrow, ...props }, consumerRef) => {
const { elevation, radii, shadow, colors } = useTheme();

return (
Expand All @@ -165,9 +178,14 @@ export const PopoverDialog = forwardRef<HTMLDivElement, DialogProps>(
opacity: isVisible ? 1 : 0,
pointerEvents: isVisible ? undefined : 'none',
zIndex: elevation.e500, // on top of drawers
...useArrowStyles(),
}}
{...props}
/>
>
<div data-popper-arrow ref={arrow.ref} className="tooltipArrow" {...arrow.props} />

{children}
</div>
</Portal>
);
}
Expand Down Expand Up @@ -258,3 +276,56 @@ const useKeyPress = ({

return keyPressed;
};

const useArrowStyles = () => {
const theme = useTheme();
const size = 16;
return {
'& [data-popper-arrow]': {
position: 'absolute',
overflow: 'hidden',
pointerEvents: 'none',
height: size * 2,
width: size * 2,
'&::after': {
content: '""',
position: 'absolute',
background: theme.colors.background,
width: size,
height: size,
transform: 'translateX(-50%) translateY(-50%) rotate(45deg)',
boxShadow: theme.shadow.s200,
},
},
"&[data-popper-placement^='left'] > [data-popper-arrow]": {
left: '100%',
'&::after': {
top: '50%',
left: '0',
},
},
"&[data-popper-placement^='right'] > [data-popper-arrow]": {
right: '100%',
'&::after': {
top: '50%',
left: '100%',
},
},
"&[data-popper-placement^='top'] > [data-popper-arrow]": {
top: '100%',
'&::after': {
top: 0,
bottom: '-50%',
left: '50%',
},
},
"&[data-popper-placement^='bottom'] > [data-popper-arrow]": {
bottom: '100%',
right: 'unset',
'&::after': {
bottom: '-50%',
left: '50%',
},
},
} as const;
};
27 changes: 25 additions & 2 deletions design-system/website/next.config.js
@@ -1,3 +1,26 @@
const withPreconstruct = require('@preconstruct/next');
module.exports = {
webpack(config, { isServer, defaultLoaders }) {
let hasFoundRule = false;
defaultLoaders.babel.options.rootMode = 'upward-optional';
config.module.rules.forEach(rule => {
if (
rule.use === defaultLoaders.babel ||
(Array.isArray(rule.use) && rule.use.includes(defaultLoaders.babel))
) {
hasFoundRule = true;
delete rule.include;
}
});
if (!hasFoundRule) {
throw new Error('The Next Babel loader could not be found');
}
if (isServer) {
config.externals = ['react', 'react-dom', 'next/router'];
config.resolve.mainFields = ['browser', 'module', 'main'];
} else {
config.resolve.mainFields = ['module', 'main'];
}

module.exports = withPreconstruct();
return config;
},
};
9 changes: 9 additions & 0 deletions packages-next/admin-ui/src/components/CreateItemDrawer.tsx
Expand Up @@ -7,6 +7,7 @@ import isDeepEqual from 'fast-deep-equal';
import { useList } from '../context';
import { Notice } from '@keystone-ui/notice';
import { Drawer } from '@keystone-ui/modals';
import { useToasts } from '@keystone-ui/toast';

export function CreateItemDrawer({
listKey,
Expand All @@ -21,10 +22,13 @@ export function CreateItemDrawer({
}) {
const list = useList(listKey);

const toasts = useToasts();

const [createItem, { loading, error }] = useMutation(
gql`mutation($data: ${list.gqlNames.createInputName}!) {
item: ${list.gqlNames.createMutationName}(data: $data) {
id
_label_
}
}`
);
Expand Down Expand Up @@ -81,6 +85,11 @@ export function CreateItemDrawer({
})
.then(({ data }) => {
onCreate(data.item.id);
toasts.addToast({
title: data.item._label_,
message: 'Created Successfully',
tone: 'positive',
});
})
.catch(() => {});
},
Expand Down
15 changes: 3 additions & 12 deletions packages-next/admin-ui/src/pages/ListPage/FilterList.tsx
Expand Up @@ -5,7 +5,6 @@ import { Filter } from './useFilters';
import { useRouter } from '../../router';
import { Button } from '@keystone-ui/button';
import { usePopover, PopoverDialog } from '@keystone-ui/popover';
import { tabbable } from 'tabbable';
import { FormEvent, Fragment, useState } from 'react';
import { Pill } from '@keystone-ui/pill';

Expand All @@ -22,7 +21,7 @@ export function FilterList({ filters, list }: { filters: Filter[]; list: ListMet

function FilterPill({ filter, field }: { filter: Filter; field: FieldMeta }) {
const router = useRouter();
const { isOpen, setOpen, trigger, dialog } = usePopover({
const { isOpen, setOpen, trigger, dialog, arrow } = usePopover({
placement: 'bottom',
modifiers: [
{
Expand Down Expand Up @@ -56,7 +55,7 @@ function FilterPill({ filter, field }: { filter: Filter; field: FieldMeta }) {
})
.toLowerCase()}
</Pill>
<PopoverDialog {...dialog.props} ref={dialog.ref} isVisible={isOpen}>
<PopoverDialog arrow={arrow} {...dialog.props} ref={dialog.ref} isVisible={isOpen}>
<EditDialog
onClose={() => {
setOpen(false);
Expand Down Expand Up @@ -97,15 +96,7 @@ function EditDialog({
onClose();
}}
>
<div
ref={node => {
if (node) {
tabbable(node)[0]?.focus();
}
}}
>
<Filter type={filter.type} value={value} onChange={setValue} />
</div>
<Filter autoFocus type={filter.type} value={value} onChange={setValue} />
<div css={{ display: 'flex', justifyContent: 'space-between' }}>
<Button onClick={onClose}>Cancel</Button>
<Button type="submit">Save</Button>
Expand Down

0 comments on commit b6fea2c

Please sign in to comment.