Skip to content

Commit

Permalink
Fix a number of issues that came up in final review
Browse files Browse the repository at this point in the history
  • Loading branch information
jessepinho committed Aug 17, 2024
1 parent c7ef90e commit b6d68f2
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 23 deletions.
5 changes: 5 additions & 0 deletions packages/ui/.storybook/preview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ const preview = {
);
},
],
argTypes: {
// The `motion` prop is used throughout many Penumbra UI components for
// framer-motion settings, and shouldn't be controlled in Storybook.
motion: { control: false },
},
parameters: {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
Expand Down
6 changes: 6 additions & 0 deletions packages/ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

The Penumbra UI library is a set of UI components purpose-built for the Penumbra ecosystem. Use these components to get rendering of various Penumbra data types out of the box, and to create a UI that is consistent with other Penumbra UIs' look and feel.

## Storybook

All Penumbra UI components (except some deprecated ones) in the latest tagged release can be found at the Penumbra UI Storybook site: https://ui.penumbra.zone/

To view the latest components merged to `main` (even if they are not yet in a tagged release), check out the Storybook Preview site: https://preview.ui.penumbra.zone/

## Set up

First, install the library:
Expand Down
37 changes: 20 additions & 17 deletions packages/ui/src/AccountSelector/AccountSelectorAddress.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,34 @@
import { Address } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/keys/v1/keys_pb';
import { bech32mAddress } from '@penumbra-zone/bech32m/penumbra';
import styled from 'styled-components';
import styled, { DefaultTheme } from 'styled-components';
import { useDensity } from '../hooks/useDensity';
import { Density } from '../types/Density';
import { CopyToClipboardButton } from '../CopyToClipboardButton';
import { Shrink0 } from '../utils/Shrink0';
import { technical, truncate } from '../utils/typography';
import { useAnimationDeferredValue } from '../hooks/useAnimationDeferredValue';
import { Text } from '../Text';

const Root = styled.div<{ $ephemeral: boolean; $loading: boolean; $density: Density }>`
const Root = styled.div<{ $density: Density }>`
border: 1px solid ${props => props.theme.color.other.tonalStroke};
padding: ${props => props.theme.spacing(2)} ${props => props.theme.spacing(3)};
display: flex;
gap: ${props => props.theme.spacing(2)};
color: ${props =>
props.$loading
? props.theme.color.text.muted
: props.$ephemeral
? props.theme.color.text.special
: props.theme.color.text.primary};
${props => props.$density === 'sparse' && 'word-break: break-all;'}
`;

const TextWrapper = styled.div<{ $density: Density }>`
const TextWrapper = styled.div`
flex-grow: 1;
${props => props.$density === 'compact' && truncate}
${technical}
`;

const getAddressColor = (loading: boolean, ephemeral: boolean) => (theme: DefaultTheme) =>
loading
? theme.color.text.muted
: ephemeral
? theme.color.text.special
: theme.color.text.primary;

export interface AccountSelectorAddressProps {
address?: Address;
ephemeral: boolean;
Expand All @@ -47,9 +44,15 @@ export const AccountSelectorAddress = ({
const deferredAddress = useAnimationDeferredValue(address);

return (
<Root $ephemeral={ephemeral} $loading={loading} $density={density}>
<TextWrapper $density={density}>
{deferredAddress ? bech32mAddress(deferredAddress) : `penumbra1...`}
<Root $density={density}>
<TextWrapper>
<Text
technical
truncate={density === 'compact'}
color={getAddressColor(loading, ephemeral)}
>
{deferredAddress ? bech32mAddress(deferredAddress) : `penumbra1...`}
</Text>
</TextWrapper>

<Shrink0>
Expand Down
2 changes: 2 additions & 0 deletions packages/ui/src/Button/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { motion } from 'framer-motion';
const iconOnlyAdornment = css<StyledButtonProps>`
border-radius: ${props => props.theme.borderRadius.full};
padding: ${props => props.theme.spacing(1)};
width: max-content;
`;

const sparse = css<StyledButtonProps>`
Expand All @@ -30,6 +31,7 @@ const compact = css<StyledButtonProps>`
padding-right: ${props => props.theme.spacing(props.$iconOnly ? 2 : 4)};
height: 32px;
min-width: 32px;
width: max-content;
`;

const outlineColorByActionType: Record<ActionType, keyof DefaultTheme['color']['action']> = {
Expand Down
22 changes: 22 additions & 0 deletions packages/ui/src/Dialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,28 @@ export type DialogProps = {
* <Dialog.Content title="Dialog title">Dialog content here</Dialog.Content>
* </Dialog>
* ```
*
* ## Animating a dialog out of its trigger
*
* You can use the `motion` prop with a layout ID to make a dialog appear to
* animate out of the trigger button:
*
* ```tsx
* const layoutId = useId();
*
* return (
* <Dialog>
* <Dialog.Trigger asChild>
* <Button icon={Info} iconOnly='adornment' motion={{ layoutId }}>
* Info
* </Button>
* </Dialog.Trigger>
* <Dialog.Content title='Info' motion={{ layoutId }}>
* ...
* </Dialog.Content>
* </Dialog>
* );
* ```
*/
export const Dialog = ({ children, onClose, isOpen }: DialogProps) => {
const isControlledComponent = isOpen !== undefined;
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/FormField/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ const Root = styled.label`
`;

const HelperText = styled.div<{ $disabled: boolean }>`
${small}
color: ${props =>
props.$disabled ? props.theme.color.text.muted : props.theme.color.text.secondary};
${small}
`;

const LabelText = styled.div<{ $disabled: boolean }>`
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/Pill/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const Root = styled.span<{ $density: Density; $priority: Priority }>`
display: inline-block;
max-width: 100%;
width: max-content;
padding-top: ${props => props.theme.spacing(props.$density === 'sparse' ? 2 : 1)};
padding-bottom: ${props => props.theme.spacing(props.$density === 'sparse' ? 2 : 1)};
Expand Down
2 changes: 2 additions & 0 deletions packages/ui/src/Text/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const meta: Meta<typeof Text> = {
detail: { control: false },
small: { control: false },
technical: { control: false },
detailTechnical: { control: false },

as: {
options: ['span', 'div', 'h1', 'h2', 'h3', 'h4', 'p', 'main', 'section'],
Expand Down Expand Up @@ -47,6 +48,7 @@ const OPTIONS = [
'detail',
'small',
'technical',
'detailTechnical',
] as const;

const Option = ({
Expand Down
12 changes: 8 additions & 4 deletions packages/ui/src/TextInput/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,18 @@ const SampleButton = () => (
</Density>
);

const addressBookIcon = (
<Icon IconComponent={BookUser} size='sm' color={theme => theme.color.text.primary} />
);

const meta: Meta<typeof TextInput> = {
component: TextInput,
tags: ['autodocs', '!dev'],
argTypes: {
startAdornment: {
options: ['Address book icon', 'None'],
mapping: {
'Address book icon': <Icon IconComponent={BookUser} size='sm' />,
'Address book icon': addressBookIcon,
None: undefined,
},
},
Expand All @@ -33,6 +37,8 @@ const meta: Meta<typeof TextInput> = {
None: undefined,
},
},
max: { control: false },
min: { control: false },
},
};
export default meta;
Expand All @@ -46,9 +52,7 @@ export const Basic: Story = {
value: '',
disabled: false,
type: 'text',
startAdornment: (
<Icon IconComponent={BookUser} size='sm' color={theme => theme.color.text.primary} />
),
startAdornment: addressBookIcon,
endAdornment: <SampleButton />,
},

Expand Down

0 comments on commit b6d68f2

Please sign in to comment.