Skip to content

Commit

Permalink
feat: animated status line
Browse files Browse the repository at this point in the history
  • Loading branch information
kyranjamie committed Apr 1, 2024
1 parent 3807fac commit d54ded8
Show file tree
Hide file tree
Showing 23 changed files with 188 additions and 33 deletions.
59 changes: 59 additions & 0 deletions build-storybook.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

> @leather-wallet/extension@6.32.1 build-storybook /Users/kyranjamie/dev/leather/wallet
> storybook build "--output-dir" "/var/folders/n2/ds19zkvd5q52dtfnyyb_qdbr0000gn/T/chromatic--27829-yOY4NVX7fkQl" "--webpack-stats-json" "/var/folders/n2/ds19zkvd5q52dtfnyyb_qdbr0000gn/T/chromatic--27829-yOY4NVX7fkQl"

@storybook/cli v8.0.1

info => Cleaning outputDir: ../../../../../var/folders/n2/ds19zkvd5q52dtfnyyb_qdbr0000gn/T/chromatic--27829-yOY4NVX7fkQl
info => Loading presets
WARN The "@storybook/addon-mdx-gfm" addon is meant as a migration assistant for Storybook 8.0; and will likely be removed in a future version.
WARN It's recommended you read this document:
WARN https://storybook.js.org/docs/react/writing-docs/mdx#lack-of-github-flavored-markdown-gfm
WARN
WARN Once you've made the necessary changes, you can remove the addon from your package.json and storybook config.
info Found existing addon {"name":"@storybook/addon-docs","options":{"csfPluginOptions":null,"mdxPluginOptions":{},"transcludeMarkdown":true}}, skipping.
info Found existing addon {"name":"@storybook/addon-docs","options":{"csfPluginOptions":null,"mdxPluginOptions":{},"transcludeMarkdown":true}}, skipping.
info => Building manager..
info => Manager built (116 ms)
info => Building preview..
info => Copying static files: public at ../../../../../var/folders/n2/ds19zkvd5q52dtfnyyb_qdbr0000gn/T/chromatic--27829-yOY4NVX7fkQl
info => Using implicit CSS loaders
info => [@storybook/addon-styling-webpack] Applying custom Storybook webpack configuration styling.
info => [@storybook/addon-styling-webpack] Replacing Storybook's webpack rules for styles with given rules.
info => Using default Webpack5 setup
🐼 warn [token] Reference not found: `colors.focus` in "3px solid {colors.focus}"
🐼 warn [token] Reference not found: `colors.focus` in "3px solid {colors.focus}"
🐼 warn [token] Reference not found: `focus` in "3px solid {focus}"
🐼 info [hrtime] Extracted in (1132.02ms)
WARN Module Warning (from ./node_modules/.pnpm/esbuild-loader@4.0.3_webpack@5.90.3/node_modules/esbuild-loader/dist/index.cjs):
WARN [esbuild-loader] The specified tsconfig at "/Users/kyranjamie/dev/leather/wallet/tsconfig.json" was applied to the file "/Users/kyranjamie/dev/leather/wallet/node_modules/.pnpm/@leather-wallet+tokens@0.0.14/node_modules/@leather-wallet/tokens/src/breakpoints.ts" but does not match its "include" patterns
WARN Module Warning (from ./node_modules/.pnpm/esbuild-loader@4.0.3_webpack@5.90.3/node_modules/esbuild-loader/dist/index.cjs):
WARN [esbuild-loader] The specified tsconfig at "/Users/kyranjamie/dev/leather/wallet/tsconfig.json" was applied to the file "/Users/kyranjamie/dev/leather/wallet/node_modules/.pnpm/@leather-wallet+tokens@0.0.14/node_modules/@leather-wallet/tokens/src/colors.ts" but does not match its "include" patterns
WARN Module Warning (from ./node_modules/.pnpm/esbuild-loader@4.0.3_webpack@5.90.3/node_modules/esbuild-loader/dist/index.cjs):
WARN [esbuild-loader] The specified tsconfig at "/Users/kyranjamie/dev/leather/wallet/tsconfig.json" was applied to the file "/Users/kyranjamie/dev/leather/wallet/node_modules/.pnpm/@leather-wallet+tokens@0.0.14/node_modules/@leather-wallet/tokens/src/index.ts" but does not match its "include" patterns
WARN Module Warning (from ./node_modules/.pnpm/esbuild-loader@4.0.3_webpack@5.90.3/node_modules/esbuild-loader/dist/index.cjs):
WARN [esbuild-loader] The specified tsconfig at "/Users/kyranjamie/dev/leather/wallet/tsconfig.json" was applied to the file "/Users/kyranjamie/dev/leather/wallet/node_modules/.pnpm/@leather-wallet+tokens@0.0.14/node_modules/@leather-wallet/tokens/src/keyframes.ts" but does not match its "include" patterns
WARN Module Warning (from ./node_modules/.pnpm/esbuild-loader@4.0.3_webpack@5.90.3/node_modules/esbuild-loader/dist/index.cjs):
WARN [esbuild-loader] The specified tsconfig at "/Users/kyranjamie/dev/leather/wallet/tsconfig.json" was applied to the file "/Users/kyranjamie/dev/leather/wallet/node_modules/.pnpm/@leather-wallet+tokens@0.0.14/node_modules/@leather-wallet/tokens/src/semantic-tokens.ts" but does not match its "include" patterns
WARN Module Warning (from ./node_modules/.pnpm/esbuild-loader@4.0.3_webpack@5.90.3/node_modules/esbuild-loader/dist/index.cjs):
WARN [esbuild-loader] The specified tsconfig at "/Users/kyranjamie/dev/leather/wallet/tsconfig.json" was applied to the file "/Users/kyranjamie/dev/leather/wallet/node_modules/.pnpm/@leather-wallet+tokens@0.0.14/node_modules/@leather-wallet/tokens/src/tokens.ts" but does not match its "include" patterns
WARN Module Warning (from ./node_modules/.pnpm/esbuild-loader@4.0.3_webpack@5.90.3/node_modules/esbuild-loader/dist/index.cjs):
WARN [esbuild-loader] The specified tsconfig at "/Users/kyranjamie/dev/leather/wallet/tsconfig.json" was applied to the file "/Users/kyranjamie/dev/leather/wallet/node_modules/.pnpm/@leather-wallet+tokens@0.0.14/node_modules/@leather-wallet/tokens/src/typography.ts" but does not match its "include" patterns
WARN Module Warning (from ./node_modules/.pnpm/esbuild-loader@4.0.3_webpack@5.90.3/node_modules/esbuild-loader/dist/index.cjs):
WARN [esbuild-loader] The specified tsconfig at "/Users/kyranjamie/dev/leather/wallet/tsconfig.json" was applied to the file "/Users/kyranjamie/dev/leather/wallet/.storybook/preview.ts" but does not match its "include" patterns
WARN Module Warning (from ./node_modules/.pnpm/esbuild-loader@4.0.3_webpack@5.90.3/node_modules/esbuild-loader/dist/index.cjs):
WARN [esbuild-loader] The specified tsconfig at "/Users/kyranjamie/dev/leather/wallet/tsconfig.json" was applied to the file "/Users/kyranjamie/dev/leather/wallet/.storybook/viewports.ts" but does not match its "include" patterns
WARN asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
WARN This can impact web performance.
WARN Assets:
WARN 8510.0add2d64.iframe.bundle.js (769 KiB)
WARN entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
WARN Entrypoints:
WARN main (1010 KiB)
WARN runtime~main.57e1694f.iframe.bundle.js
WARN 8510.0add2d64.iframe.bundle.js
WARN main.d66cdef4.iframe.bundle.js
WARN
info => Preview built (6.26 s)
info => preview stats written to /var/folders/n2/ds19zkvd5q52dtfnyyb_qdbr0000gn/T/chromatic--27829-yOY4NVX7fkQl/preview-stats.json
info => Output directory: /var/folders/n2/ds19zkvd5q52dtfnyyb_qdbr0000gn/T/chromatic--27829-yOY4NVX7fkQl
6 changes: 6 additions & 0 deletions src/app/common/date-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import dayjs from 'dayjs';
import advancedFormat from 'dayjs/plugin/advancedFormat';
import isToday from 'dayjs/plugin/isToday';
import isYesterday from 'dayjs/plugin/isYesterday';
import localizedFormat from 'dayjs/plugin/localizedFormat';
import timezone from 'dayjs/plugin/timezone';
import utc from 'dayjs/plugin/utc';

Expand All @@ -10,6 +11,7 @@ dayjs.extend(isYesterday);
dayjs.extend(advancedFormat);
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.extend(localizedFormat);

export function todaysIsoDate() {
return new Date().toISOString().split('T')[0];
Expand All @@ -20,6 +22,10 @@ export function isoDateToLocalDate(isoDate: string): string {
return dayjs.tz(isoDate).format('YYYY-MM-DD');
}

export function toLocalizedDateFormat(date: dayjs.Dayjs) {
return date.format('lll');
}

// txDate is of the form YYYY-MM-DD
export function displayDate(txDate: string): string {
const date = dayjs(txDate);
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/account/account-list-item.layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { ReactNode } from 'react';
import { SettingsSelectors } from '@tests/selectors/settings.selectors';

import { ItemLayout } from '@app/ui/components/item-layout/item-layout';
import { Pressable } from '@app/ui/components/pressable/pressable';
import { Spinner } from '@app/ui/components/spinner';
import { Pressable } from '@app/ui/pressable/pressable';

interface AccountListItemLayoutProps {
accountAddresses: ReactNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { formatBalance } from '@app/common/format-balance';
import { Brc20Token } from '@app/query/bitcoin/bitcoin-client';
import { Brc20AvatarIcon } from '@app/ui/components/avatar/brc20-avatar-icon';
import { ItemLayout } from '@app/ui/components/item-layout/item-layout';
import { Pressable } from '@app/ui/components/pressable/pressable';
import { BasicTooltip } from '@app/ui/components/tooltip/basic-tooltip';
import { Pressable } from '@app/ui/pressable/pressable';

interface Brc20TokenAssetItemLayoutProps {
token: Brc20Token;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { AllCryptoCurrencyAssetBalances } from '@shared/models/crypto-asset-bala

import { BulletSeparator } from '@app/ui/components/bullet-separator/bullet-separator';
import { ItemLayout } from '@app/ui/components/item-layout/item-layout';
import { Pressable } from '@app/ui/components/pressable/pressable';
import { BasicTooltip } from '@app/ui/components/tooltip/basic-tooltip';
import { Caption } from '@app/ui/components/typography/caption';
import { Pressable } from '@app/ui/pressable/pressable';

import { parseCryptoCurrencyAssetBalance } from './crypto-currency-asset.utils';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { StacksFungibleTokenAssetBalance } from '@shared/models/crypto-asset-bal

import { StacksAssetAvatar } from '@app/components/crypto-assets/stacks/components/stacks-asset-avatar';
import { ItemLayout } from '@app/ui/components/item-layout/item-layout';
import { Pressable } from '@app/ui/components/pressable/pressable';
import { BasicTooltip } from '@app/ui/components/tooltip/basic-tooltip';
import { Pressable } from '@app/ui/pressable/pressable';

import { parseStacksFungibleTokenAssetBalance } from './fungible-token-asset.utils';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { ReactNode } from 'react';
import { HStack, styled } from 'leather-styles/jsx';

import { ItemLayout } from '@app/ui/components/item-layout/item-layout';
import { Pressable } from '@app/ui/components/pressable/pressable';
import { Caption } from '@app/ui/components/typography/caption';
import { Pressable } from '@app/ui/pressable/pressable';

interface TransactionItemLayoutProps {
openTxLink(): void;
Expand Down
2 changes: 1 addition & 1 deletion src/app/features/approver/approver-demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { Button } from '@app/ui/components/button/button';
import { Callout } from '@app/ui/components/callout/callout';
import { Flag } from '@app/ui/components/flag/flag';
import { ItemLayout } from '@app/ui/components/item-layout/item-layout';
import { Pressable } from '@app/ui/components/pressable/pressable';
import { BasicTooltip } from '@app/ui/components/tooltip/basic-tooltip';
import { TooltipProvider } from '@app/ui/components/tooltip/tooltip';
import { InfoCircleIcon } from '@app/ui/icons';
import { Pressable } from '@app/ui/pressable/pressable';

import { Approver } from './approver';

Expand Down
4 changes: 2 additions & 2 deletions src/app/features/approver/approver.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { Button } from '@app/ui/components/button/button';
import { Callout } from '@app/ui/components/callout/callout';

Check failure on line 5 in src/app/features/approver/approver.stories.tsx

View workflow job for this annotation

GitHub Actions / typecheck

'Callout' is declared but its value is never read.
import { Flag } from '@app/ui/components/flag/flag';
import { ItemLayout } from '@app/ui/components/item-layout/item-layout';
import { Pressable } from '@app/ui/components/pressable/pressable';
import { ZapIcon } from '@app/ui/icons';
import { Pressable } from '@app/ui/pressable/pressable';

import { Approver } from './approver';

Expand All @@ -31,7 +31,7 @@ export const ExampleOne: Story = {
children: (
<>
<Approver.Header title="Some prompt that breaks two lines" requester="gamma.io" />
<Callout title="Some callout">Hey watch out for this sketchy app</Callout>
<Approver.Status status="pending"></Approver.Status>
<Approver.Section>
<Approver.Subheader>
Subheader with icon <ZapIcon variant="small" />
Expand Down
2 changes: 2 additions & 0 deletions src/app/features/approver/approver.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ApproverAdvanced } from './components/approver-advanced';
import { ApproverContainer } from './components/approver-container';
import { ApproverHeader } from './components/approver-header';
import { ApproverSection } from './components/approver-section';
import { ApproverStatus } from './components/approver-status';
import { ApproverSubheader } from './components/approver-subheader';

function Approver(props: HasChildren) {
Expand All @@ -24,6 +25,7 @@ function Approver(props: HasChildren) {
}

Approver.Header = ApproverHeader;
Approver.Status = ApproverStatus;
Approver.Subheader = ApproverSubheader;
Approver.Section = ApproverSection;
Approver.Advanced = ApproverAdvanced;
Expand Down
42 changes: 36 additions & 6 deletions src/app/features/approver/components/approver-status.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,48 @@
import dayjs from 'dayjs';
import { styled } from 'leather-styles/jsx';

import { toLocalizedDateFormat } from '@app/common/date-utils';
import { capitalize } from '@app/common/utils';
import { loadingStripedGradient } from '@app/ui/animations/loading-striped-gradient';
import { BulletSeparator } from '@app/ui/components/bullet-separator/bullet-separator';

type ApproverStatus = 'completed' | 'error' | 'pending';

interface StatusIndicatorLineProps {
status: ApproverStatus;
}
function StatusIndicatorLine({ status }: StatusIndicatorLineProps) {
switch (status) {
case 'pending':
return <styled.div height="4px" className={loadingStripedGradient} />;
case 'error':
return <styled.div height="4px" bg="red.action-primary-default" />;
case 'completed':
return <styled.div height="4px" bg="green.action-primary-default" />;
default:
return null;
}
}

interface ApproverStatusProps {
status: 'completed' | 'error' | 'pending';
status: ApproverStatus;
}
export function ApproverStatus({ status }: ApproverStatusProps) {
return (
<styled.div>
<BulletSeparator>
{status}
<styled.span>{dayjs(new Date()).format()}</styled.span>
</BulletSeparator>
<styled.div pos="relative">
<StatusIndicatorLine status={status} />
<styled.div
mt="4px"
textStyle="label.03"
background="ink.background-primary"
px="space.05"
py="space.03"
>
<BulletSeparator spacing="space.01">
<styled.span>{capitalize(status)}</styled.span>
<styled.span>{toLocalizedDateFormat(dayjs())}</styled.span>
</BulletSeparator>
</styled.div>
</styled.div>
);
}
2 changes: 1 addition & 1 deletion src/app/pages/receive/components/receive-item.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { IconButton } from '@app/ui/components/icon-button/icon-button';
import { ItemLayoutWithButtons } from '@app/ui/components/item-layout/item-layout-with-buttons';
import { Pressable } from '@app/ui/components/pressable/pressable';
import { CopyIcon } from '@app/ui/icons/copy-icon';
import { QrCodeIcon } from '@app/ui/icons/qr-code-icon';
import { Pressable } from '@app/ui/pressable/pressable';
import { truncateMiddle } from '@app/ui/utils/truncate-middle';

interface ReceiveItemProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useGetFungibleTokenMetadataQuery } from '@app/query/stacks/tokens/fungi
import { isFtAsset } from '@app/query/stacks/tokens/token-metadata.utils';
import { Avatar, defaultFallbackDelay, getAvatarFallback } from '@app/ui/components/avatar/avatar';
import { ItemLayout } from '@app/ui/components/item-layout/item-layout';
import { Pressable } from '@app/ui/pressable/pressable';
import { Pressable } from '@app/ui/components/pressable/pressable';

import { useAlexSdkBalanceAsFiat } from '../../../hooks/use-alex-sdk-fiat-price';
import { SwapAsset } from '../../../hooks/use-swap-form';
Expand Down
21 changes: 21 additions & 0 deletions src/app/ui/animations/loading-striped-gradient.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Meta, StoryObj } from '@storybook/react';
import { styled } from 'leather-styles/jsx';

import { loadingStripedGradient } from './loading-striped-gradient';

function LoadingStripedGradient() {
return <styled.div className={loadingStripedGradient} width="280px" height="20px" />;
}

const meta: Meta<typeof LoadingStripedGradient> = {
component: LoadingStripedGradient,
tags: ['autodocs'],
title: 'Animation/LoadingStripedGradient',
};

export default meta;
type Story = StoryObj<typeof LoadingStripedGradient>;

export const Item: Story = {
render: () => <LoadingStripedGradient />,
};
16 changes: 16 additions & 0 deletions src/app/ui/animations/loading-striped-gradient.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { css } from 'leather-styles/css';

export const loadingStripedGradient = css({
pos: 'relative',
overflow: 'hidden',
content: '""',
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundImage:
'repeating-linear-gradient(45deg, #F07D12, #F07D12 16px, #FFB977 16px, #FFB977 32px)',
animation: 'barberpole 30s linear infinite',
backgroundSize: '193% 100%',
});
9 changes: 7 additions & 2 deletions src/app/ui/components/bullet-separator/bullet-separator.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { cloneElement, isValidElement } from 'react';

import { Circle, CircleProps } from 'leather-styles/jsx';
import type { SpacingToken } from 'leather-styles/tokens';

export function BulletOperator(props: CircleProps) {
return (
Expand All @@ -18,13 +19,17 @@ export function BulletOperator(props: CircleProps) {

interface BulletSeparatorSeparatorProps {
children: React.ReactNode;
spacing?: SpacingToken;
}
export function BulletSeparator({ children }: BulletSeparatorSeparatorProps) {
export function BulletSeparator({ children, spacing }: BulletSeparatorSeparatorProps) {
const parsedChildren = Array.isArray(children) ? children : [children];
const content = parsedChildren
.flatMap((child, index) => {
if (!isValidElement(child)) return null;
return [cloneElement(child, { key: index }), <BulletOperator key={index + 'dot'} />];
return [
cloneElement(child, { key: index }),
<BulletOperator key={index + 'dot'} mx={spacing} />,
];
})
.filter(val => val !== null)
.slice(0, -1);
Expand Down
2 changes: 1 addition & 1 deletion src/app/ui/components/dropdown-menu/dropdown-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import * as RadixDropdownMenu from '@radix-ui/react-dropdown-menu';
import { css } from 'leather-styles/css';
import { type HTMLStyledProps, styled } from 'leather-styles/jsx';

import { pressableBaseStyles, pressableStyles } from '@app/ui/components/pressable/pressable';
import { ChevronDownIcon } from '@app/ui/icons';
import { pressableBaseStyles, pressableStyles } from '@app/ui/pressable/pressable';

import { Flag } from '../flag/flag';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ReactNode } from 'react';

import { Flex, HStack, Stack, styled } from 'leather-styles/jsx';

import { pressableCaptionStyles } from '@app/ui/pressable/pressable';
import { pressableCaptionStyles } from '@app/ui/components/pressable/pressable';

import { Flag } from '../flag/flag';

Expand Down
Loading

0 comments on commit d54ded8

Please sign in to comment.