Skip to content

Commit

Permalink
Add some padding to the story
Browse files Browse the repository at this point in the history
Add section styles

v0.6.0

Inc

WIP

v0.6.1

WIP

v0.6.2
  • Loading branch information
mikeldking committed Oct 11, 2022
1 parent f105db2 commit 6952c65
Show file tree
Hide file tree
Showing 22 changed files with 2,372 additions and 2,823 deletions.
22 changes: 12 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.6.4",
"version": "0.6.2",
"license": "MIT",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
Expand Down Expand Up @@ -65,9 +65,9 @@
"devDependencies": {
"@babel/core": "^7.12.3",
"@emotion/babel-plugin": "^11.2.0",
"@emotion/babel-preset-css-prop": "^10.0.27",
"@emotion/core": "^10.0.35",
"@size-limit/preset-small-lib": "^4.6.2",
"@emotion/babel-preset-css-prop": "10.0.27",
"@emotion/core": "10.0.35",
"@size-limit/preset-small-lib": "^8.1.0",
"@storybook/addon-a11y": "^6.1.21",
"@storybook/addon-essentials": "^6.0.26",
"@storybook/addon-info": "^5.3.21",
Expand All @@ -79,14 +79,14 @@
"babel-loader": "^8.1.0",
"babel-plugin-polished": "^1.1.0",
"chromatic": "^6.5.1",
"husky": "^4.3.0",
"husky": "^8.0.1",
"polished": "^4.2.2",
"react": "18",
"react-dom": "18",
"react-hook-form": "^7.27.1",
"react-is": "^17.0.1",
"size-limit": "^4.6.2",
"storybook-addon-designs": "^5.4.5",
"react-is": "^18.2.0",
"size-limit": "^8.1.0",
"storybook-addon-designs": "^6.3.1",
"tslib": "^2.0.3",
"typescript": "^4.0.3"
},
Expand All @@ -112,9 +112,9 @@
"@react-aria/utils": "^3.14.0",
"@react-aria/virtualizer": "^3.3.4",
"@react-aria/visually-hidden": "^3.5.0",
"@react-stately/collections": "^3.4.4",
"@react-stately/collections": "3.3.4",
"@react-stately/layout": "^3.8.0",
"@react-stately/list": "^3.5.4",
"@react-stately/list": "3.3.0",
"@react-stately/overlays": "^3.4.2",
"@react-stately/radio": "^3.6.0",
"@react-stately/select": "^3.3.2",
Expand All @@ -124,6 +124,8 @@
"@react-types/shared": "^3.15.0",
"@storybook/addon-measure": "^6.5.10",
"@types/react-transition-group": "^4.4.5",
"@typescript-eslint/eslint-plugin": "^5.39.0",
"@typescript-eslint/parser": "^5.39.0",
"clsx": "^1.1.1",
"react-transition-group": "^4.4.5",
"tsdx": "^0.14.1"
Expand Down
2 changes: 1 addition & 1 deletion src/button/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const buttonCSS = css`
display: flex;
justify-content: center;
align-items: center;
box-sizing: content-box;
box-sizing: border-box;
border-radius: ${theme.borderRadius.medium}px;
color: ${theme.textColors.white90};
cursor: pointer;
Expand Down
22 changes: 16 additions & 6 deletions src/dropdown/DropdownMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { ReactNode, CSSProperties } from 'react';
import React, { ReactNode, CSSProperties, ReactElement } from 'react';
import { css } from '@emotion/core';
import theme from '../theme';
import { DOMRef } from '../types';

interface DropdownMenuProps {
children: ReactNode;
Expand All @@ -12,11 +13,10 @@ interface DropdownMenuProps {
style?: CSSProperties;
}

export function DropdownMenu({
children,
isPadded = false,
style,
}: DropdownMenuProps) {
function DropdownMenu(
{ children, isPadded = false, style }: DropdownMenuProps,
_ref: DOMRef<HTMLDivElement>
) {
return (
<div
css={css`
Expand All @@ -34,3 +34,13 @@ export function DropdownMenu({
</div>
);
}

/**
* Menus display a list of actions or options that a user can choose.
*/
// forwardRef doesn't support generic parameters, so cast the result to the correct type
// https://stackoverflow.com/questions/58469229/react-with-typescript-generics-while-using-react-forwardref
const _DropdownMenu = React.forwardRef(DropdownMenu) as (
props: DropdownMenuProps & { ref?: DOMRef<HTMLUListElement> }
) => ReactElement;
export { _DropdownMenu as DropdownMenu };
13 changes: 13 additions & 0 deletions src/icon/Icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -476,3 +476,16 @@ export const CloseCircleOutline = () => (
</g>
</svg>
);

export const MoreHorizontalOutline = () => (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g data-name="Layer 2">
<g data-name="more-horizotnal">
<rect width="24" height="24" opacity="0" />
<circle cx="12" cy="12" r="2" />
<circle cx="19" cy="12" r="2" />
<circle cx="5" cy="12" r="2" />
</g>
</g>
</svg>
);
1 change: 1 addition & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export * from './search';
export * from './overlays';
export * from './dialog';
export * from './view';
export * from './menu';
export { theme } from './theme';
// export interface Props extends HTMLAttributes<HTMLDivElement> {
// /** custom content, defaults to 'the snozzberries taste like snozzberries' */
Expand Down
41 changes: 3 additions & 38 deletions src/listbox/ListBoxOption.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Icon, CheckmarkOutline } from '../icon';
import { css } from '@emotion/core';
import { classNames } from '../utils';
import { FocusRing } from '@react-aria/focus';
import { isFocusVisible, useHover } from '@react-aria/interactions';
Expand All @@ -10,7 +9,7 @@ import React, { useContext } from 'react';
import { Text } from '../content';
import { useOption } from '@react-aria/listbox';
import { useRef } from 'react';
import theme from '../theme';
import { menuItemCSS } from '../menu/styles';

interface OptionProps<T> {
item: Node<T>;
Expand All @@ -19,23 +18,6 @@ interface OptionProps<T> {
shouldUseVirtualFocus?: boolean;
}

const menuItemCSS = css`
&.is-selected {
i {
color: ${theme.colors.arizeLightBlue};
}
}
&.is-hovered,
&.focus-ring {
background-color: ${theme.colors.hoverBgColor};
}
&.is-selectable {
cursor: pointer;
}
/* show focus in other ways */
outline: none;
`;

/** @private */
export function ListBoxOption<T>(props: OptionProps<T>) {
let {
Expand Down Expand Up @@ -94,25 +76,8 @@ export function ListBoxOption<T>(props: OptionProps<T>) {
})}
css={menuItemCSS}
>
<div
className="ac-menu-item"
css={css`
display: flex;
justify-content: space-between;
align-items: flex-start;
color: ${theme.textColors.white90};
padding: ${theme.spacing.padding8}px ${theme.spacing.padding16}px;
position: relative;
& > .ac-icon-wrap {
position: absolute;
top: ${theme.spacing.padding8}px;
right: ${theme.spacing.padding8}px;
}
`}
>
{contents}
{isSelected && <Icon svg={<CheckmarkOutline />} />}
</div>
{contents}
{isSelected && <Icon svg={<CheckmarkOutline />} />}
</div>
</FocusRing>
);
Expand Down
52 changes: 52 additions & 0 deletions src/menu/ActionMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Button } from '../button';
import { filterDOMProps } from '@react-aria/utils';
import { FocusableRef } from '@react-types/shared';
import { Menu } from './Menu';
import { MenuTrigger } from './MenuTrigger';
import { Icon, MoreHorizontalOutline } from '../icon';
import React, { forwardRef, ReactElement } from 'react';
import { ActionMenuProps } from '../types';

function ActionMenu<T extends object>(
props: ActionMenuProps<T>,
ref: FocusableRef<HTMLButtonElement>
) {
const { children, buttonText, icon } = props;
const buttonProps = filterDOMProps(props, { labelable: true });
if (buttonProps['aria-label'] === undefined) {
buttonProps['aria-label'] = 'actions';
}

return (
<MenuTrigger
isOpen={props.isOpen}
defaultOpen={props.defaultOpen}
onOpenChange={props.onOpenChange}
align={props.align}
direction={props.direction}
shouldFlip={props.shouldFlip}
>
<Button
variant="default"
icon={icon ?? <Icon svg={<MoreHorizontalOutline />} />}
ref={ref}
{...buttonProps}
children={buttonText}
/>
<Menu
children={children}
items={props.items}
disabledKeys={props.disabledKeys}
onAction={props.onAction}
/>
</MenuTrigger>
);
}

/**
* ActionMenu combines an ActionButton with a Menu for simple "more actions" use cases.
*/
const _ActionMenu = forwardRef(ActionMenu) as <T>(
props: ActionMenuProps<T> & { ref?: FocusableRef<HTMLButtonElement> }
) => ReactElement;
export { _ActionMenu as ActionMenu };
105 changes: 105 additions & 0 deletions src/menu/Menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { useDOMRef } from '../utils';
import {
AriaLabelingProps,
CollectionBase,
DOMProps,
DOMRef,
FocusStrategy,
MultipleSelection,
} from '../types';
import { MenuContext } from './context';
import { MenuItem } from './MenuItem';
import { MenuSection } from './MenuSection';
import { mergeProps, useSyncRef } from '@react-aria/utils';
import React, { Key, ReactElement, useContext } from 'react';
import { useMenu } from '@react-aria/menu';
import { useTreeState } from '@react-stately/tree';
import theme from '../theme';
import { css } from '@emotion/core';

export interface MenuProps<T> extends CollectionBase<T>, MultipleSelection {
/** Where the focus should be set. */
autoFocus?: boolean | FocusStrategy;
/** Whether keyboard navigation is circular. */
shouldFocusWrap?: boolean;
/** Handler that is called when an item is selected. */
onAction?: (key: Key) => void;
/** Handler that is called when the menu should close after selecting an item. */
onClose?: () => void;
}

export interface AriaMenuProps<T>
extends MenuProps<T>,
DOMProps,
AriaLabelingProps {}

export interface MenuComponentProps<T> extends AriaMenuProps<T> {}

const menuULCSS = css`
background-color: ${theme.colors.gray500};
border-radius: 4px;
color: ${theme.textColors.white90};
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.4);
outline: none;
border: 1px solid ${theme.components.dropdown.borderColor};
max-height: inherit;
list-style: none;
margin: 0;
padding: ${theme.spacing.padding4}px 0;
`;
function Menu<T extends object>(
props: MenuComponentProps<T>,
ref: DOMRef<HTMLUListElement>
) {
let contextProps = useContext(MenuContext);
let completeProps = {
...mergeProps(contextProps, props),
};

let domRef = useDOMRef(ref);
let state = useTreeState(completeProps);
let { menuProps } = useMenu(completeProps, state, domRef);
useSyncRef(contextProps, domRef);

return (
<ul {...menuProps} ref={domRef} className={'ac-menu'} css={menuULCSS}>
{[...state.collection].map(item => {
if (item.type === 'section') {
return (
<MenuSection
key={item.key}
item={item}
state={state}
onAction={completeProps.onAction}
/>
);
}

let menuItem = (
<MenuItem
key={item.key}
item={item}
state={state}
onAction={completeProps.onAction}
/>
);

if (item.wrapper) {
menuItem = item.wrapper(menuItem);
}

return menuItem;
})}
</ul>
);
}

/**
* Menus display a list of actions or options that a user can choose.
*/
// forwardRef doesn't support generic parameters, so cast the result to the correct type
// https://stackoverflow.com/questions/58469229/react-with-typescript-generics-while-using-react-forwardref
const _Menu = React.forwardRef(Menu) as <T>(
props: MenuComponentProps<T> & { ref?: DOMRef<HTMLUListElement> }
) => ReactElement;
export { _Menu as Menu };
Loading

0 comments on commit 6952c65

Please sign in to comment.