diff --git a/apps/web/src/layouts/DefaultLayout/Nav.styles.css.ts b/apps/web/src/layouts/DefaultLayout/Nav.styles.css.ts index 95d196159..83b982fa9 100644 --- a/apps/web/src/layouts/DefaultLayout/Nav.styles.css.ts +++ b/apps/web/src/layouts/DefaultLayout/Nav.styles.css.ts @@ -273,6 +273,20 @@ export const chainPopUpButton = style({ }, }) +export const chainPopUpItem = style({ + border: 0, + width: '100%', + textAlign: 'left', + font: 'inherit', + appearance: 'none', + selectors: { + '&:disabled': { + pointerEvents: 'auto', + cursor: 'not-allowed', + }, + }, +}) + export const themeToggleButton = style([ atoms({ borderStyle: 'solid', @@ -318,6 +332,7 @@ export const wrongNetworkButton = style({ 'border 0.1s ease-in-out, background 0.1s ease-in-out, transform 0.1s ease-out', borderWidth: 'normal', borderStyle: 'solid', + background: 'transparent', borderColor: vars.color.negative, color: vars.color.negative, selectors: { diff --git a/apps/web/src/layouts/DefaultLayout/NavMenu/ChainMenu.tsx b/apps/web/src/layouts/DefaultLayout/NavMenu/ChainMenu.tsx index 4dddd5603..11c641a71 100644 --- a/apps/web/src/layouts/DefaultLayout/NavMenu/ChainMenu.tsx +++ b/apps/web/src/layouts/DefaultLayout/NavMenu/ChainMenu.tsx @@ -10,6 +10,7 @@ import { useAccount, useSwitchChain } from 'wagmi' import { chainPopUpButton, + chainPopUpItem, navButton, navPopUpWrapper, wrongNetworkButton, @@ -140,7 +141,7 @@ export const ChainMenu: React.FC = ({ borderColor="border" borderStyle="solid" borderWidth="normal" - backgroundColor="background1" + backgroundColor="transparent" borderRadius="curved" cursor={'pointer'} align={'center'} @@ -175,6 +176,8 @@ export const ChainMenu: React.FC = ({ {isWrongNetwork && selectedChain && ( = ({ )} {PUBLIC_DEFAULT_CHAINS.map((chain, i, chains) => ( onChainChange(chain.id)} - cursor={ - hasNetwork - ? isSelectedChain(chain.id) - ? undefined - : 'not-allowed' - : 'pointer' - } height={'x10'} px="x4" mb={i !== chains.length - 1 ? 'x2' : undefined} align={'center'} justify={'space-between'} + disabled={hasNetwork && !isSelectedChain(chain.id)} + aria-current={selectedChain.id === chain.id ? 'location' : undefined} > diff --git a/apps/web/src/modules/dashboard/Dashboard.tsx b/apps/web/src/modules/dashboard/Dashboard.tsx index 39fab8b6c..7791dc145 100644 --- a/apps/web/src/modules/dashboard/Dashboard.tsx +++ b/apps/web/src/modules/dashboard/Dashboard.tsx @@ -315,7 +315,7 @@ export const Dashboard: React.FC = () => { ? `${totalProposals} active proposal${totalProposals !== 1 ? 's' : ''}` : 'No active proposals' } - description={{proposalList}} + description={{proposalList}} titleFontSize={18} mb={'x0'} showWarning={hasProposalsNeedingVote} diff --git a/apps/web/src/modules/dashboard/SingleDaoSelector.css.ts b/apps/web/src/modules/dashboard/SingleDaoSelector.css.ts index 6fefe0888..092d2b506 100644 --- a/apps/web/src/modules/dashboard/SingleDaoSelector.css.ts +++ b/apps/web/src/modules/dashboard/SingleDaoSelector.css.ts @@ -14,7 +14,7 @@ export const sectionTitle = style({ fontSize: '14px', fontWeight: 600, marginBottom: space.x3, - color: color.text2, + color: color.text1, }) export const daoItem = style([ diff --git a/apps/web/src/modules/explore/ExploreSortMenu.tsx b/apps/web/src/modules/explore/ExploreSortMenu.tsx index 17336d3bb..9c98d3189 100644 --- a/apps/web/src/modules/explore/ExploreSortMenu.tsx +++ b/apps/web/src/modules/explore/ExploreSortMenu.tsx @@ -67,6 +67,8 @@ export const ExploreSortMenu: React.FC = () => { onChange={handleSortChange} customLabel={defaultSort} positioning="absolute" + height="x10" + minWidth="120px" /> ) diff --git a/apps/web/src/modules/explore/ExploreToolbar.tsx b/apps/web/src/modules/explore/ExploreToolbar.tsx index 090ec52da..17b052294 100644 --- a/apps/web/src/modules/explore/ExploreToolbar.tsx +++ b/apps/web/src/modules/explore/ExploreToolbar.tsx @@ -28,7 +28,7 @@ export const ExploreToolbar: React.FC = ({ align={'center'} style={{ maxWidth: 912 }} > - + {title} diff --git a/apps/web/src/modules/explore/SearchInput.css.ts b/apps/web/src/modules/explore/SearchInput.css.ts index 1b5d8b75b..5fcb3ea3e 100644 --- a/apps/web/src/modules/explore/SearchInput.css.ts +++ b/apps/web/src/modules/explore/SearchInput.css.ts @@ -25,7 +25,7 @@ export const searchInputStyle = style({ borderColor: vars.color.border, }, '&:focus-visible': { - outline: `2px solid ${vars.color.accent}`, + outline: `2px solid ${vars.color.focusRing}`, outlineOffset: '2px', }, '&::placeholder': { diff --git a/apps/web/src/modules/playground/PlaygroundPage.tsx b/apps/web/src/modules/playground/PlaygroundPage.tsx index 396502ee5..33bfb79e7 100644 --- a/apps/web/src/modules/playground/PlaygroundPage.tsx +++ b/apps/web/src/modules/playground/PlaygroundPage.tsx @@ -49,7 +49,7 @@ export const PlaygroundPage: React.FC = () => { const isCustomView = view === 'custom' return ( - + { const { isGnosisSafe } = useIsGnosisSafe(address, chain.id) const { push } = useRouter() + const handleSuccessfulDeploy = React.useCallback( async (token: string) => { await push({ @@ -86,7 +87,7 @@ const CreatePage: NextPageWithLayout = () => { const reviewAndDeploy: CreateFormSection = { title: 'Deploy', - subHeading: '[Confirm your contract settings before deploying your DAO]', + subHeading: 'Confirm your contract settings before deploying your DAO', form: ( = ({ bids, onClose }) => { style={{ maxHeight: 'min(70vh, 640px)' }} > {bids.map((bid: AuctionBidFragment) => ( - + ))} diff --git a/packages/auction-ui/src/components/AllBids/BidCard.tsx b/packages/auction-ui/src/components/AllBids/BidCard.tsx index 09c2256b1..949e93aa2 100644 --- a/packages/auction-ui/src/components/AllBids/BidCard.tsx +++ b/packages/auction-ui/src/components/AllBids/BidCard.tsx @@ -1,12 +1,17 @@ import { useEnsData } from '@buildeross/hooks/useEnsData' import { AuctionBidFragment } from '@buildeross/sdk/subgraph' -import { WalletIdentityWithPreview } from '@buildeross/ui' +import { WalletIdentity, WalletIdentityWithPreview } from '@buildeross/ui' import { walletSnippet } from '@buildeross/utils/helpers' import { formatCryptoVal } from '@buildeross/utils/numbers' import { Box, Flex, Icon, Text, vars } from '@buildeross/zord' -import React from 'react' -export const BidCard = ({ bid }: { bid: AuctionBidFragment }) => { +export const BidCard = ({ + bid, + walletPreview = true, +}: { + bid: AuctionBidFragment + walletPreview?: boolean +}) => { const { displayName, ensAvatar } = useEnsData(bid?.bidder) const resolvedDisplayName = displayName || walletSnippet(bid.bidder as `0x${string}`) const comment = bid.comment?.trim() @@ -14,13 +19,23 @@ export const BidCard = ({ bid }: { bid: AuctionBidFragment }) => { return ( - + {walletPreview ? ( + + ) : ( + + )} = ({ title handleFastDAOToggle(formik)} + aria-pressed={enableFastDAO} + aria-label="Enable Fast DAO" > {enableFastDAO && } diff --git a/packages/create-dao-ui/src/components/CreateNavigation/NavSection.css.ts b/packages/create-dao-ui/src/components/CreateNavigation/NavSection.css.ts index 4fa804e0d..2ad6582d3 100644 --- a/packages/create-dao-ui/src/components/CreateNavigation/NavSection.css.ts +++ b/packages/create-dao-ui/src/components/CreateNavigation/NavSection.css.ts @@ -1,9 +1,13 @@ import { vars } from '@buildeross/zord' import { style, styleVariants } from '@vanilla-extract/css' +const lhsPrimary = 'rgba(255, 255, 255, 1)' +const lhsDefault = 'rgba(255, 255, 255, 0.8)' +const lhsMuted = 'rgba(255, 255, 255, 0.55)' + const circleBackgroundBorder = { - backgroundColor: vars.color.background1, - border: `2px solid ${vars.color.background1}`, + backgroundColor: lhsPrimary, + border: `2px solid ${lhsPrimary}`, } const circleBorderMobile = { @@ -26,7 +30,7 @@ const flowTitleBase = style({ position: 'absolute', fontSize: 18, fontWeight: 700, - color: vars.color.onAccent, + color: lhsPrimary, top: 30, opacity: 0.8, '@media': { @@ -43,8 +47,8 @@ export const flowTitleVariant = styleVariants({ active: [flowTitleBase, { opacity: 1 }], default: [flowTitleBase], fulfilled: [flowTitleBase, { opacity: 1 }], - preview: [flowTitleBase, { color: vars.color.text4 }], - previewActive: [flowTitleBase, { color: vars.color.text1 }], + preview: [flowTitleBase, { color: lhsMuted }], + previewActive: [flowTitleBase, { color: lhsPrimary }], }) const flowFulfilledCircle = style({ @@ -71,10 +75,10 @@ const flowFulfilledCircleLast = style({ const flowCircle = style({ backgroundColor: 'transparent', - border: `2px solid ${vars.color.background1}`, + border: `2px solid ${lhsPrimary}`, '@media': { 'screen and (max-width: 768px)': { - backgroundColor: vars.color.background1, + backgroundColor: lhsPrimary, border: `2px solid ${vars.color.background2}`, }, }, @@ -82,10 +86,10 @@ const flowCircle = style({ const flowCircleLast = style({ backgroundColor: 'transparent', - border: `2px solid ${vars.color.background1}`, + border: `2px solid ${lhsPrimary}`, '@media': { 'screen and (max-width: 768px)': { - backgroundColor: vars.color.background1, + backgroundColor: lhsPrimary, border: `2px solid ${vars.color.background2}`, }, }, @@ -116,8 +120,8 @@ export const circleVariant = styleVariants({ flowCircleActiveLast: [circleBase, flowCircleActiveLast], flowFulfilledCircle: [circleBase, flowFulfilledCircle], flowFulfilledCircleLast: [circleBase, flowFulfilledCircleLast], - preview: [circleBase, { backgroundColor: vars.color.text4 }], - previewActive: [circleBase, { backgroundColor: vars.color.text1 }], + preview: [circleBase, { backgroundColor: lhsMuted }], + previewActive: [circleBase, { backgroundColor: lhsPrimary }], }) const flowSectionWrapper = style({ @@ -132,7 +136,7 @@ const flowSectionWrapper = style({ top: '50%', marginTop: -1, width: 516, - border: `1px dashed ${vars.color.background1}`, + border: `1px dashed ${lhsDefault}`, opacity: 0.7, '@media': { '(max-width: 1080px)': { @@ -163,7 +167,7 @@ export const flowSectionWrapperVariants = styleVariants({ top: '50%', marginTop: -1, width: 516, - border: `1px dashed ${vars.color.text4}`, + border: `1px dashed ${lhsMuted}`, '@media': { '(max-width: 1080px)': { width: 368, diff --git a/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.css.ts b/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.css.ts index 4ba87b793..18fc0400e 100644 --- a/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.css.ts +++ b/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.css.ts @@ -1,3 +1,4 @@ +import { vars } from '@buildeross/zord' import { style } from '@vanilla-extract/css' export const formNavResetButton = style({ @@ -9,3 +10,38 @@ export const formNavContinueButton = style({ height: 60, marginLeft: 8, }) + +export const formNavMobileBar = style({ + position: 'fixed', + left: 0, + right: 0, + bottom: 0, + zIndex: 25, + padding: 16, + paddingBottom: 'calc(16px + env(safe-area-inset-bottom))', + background: vars.color.background1, + borderTop: `1px solid ${vars.color.border}`, + '@media': { + '(min-width: 768px)': { + display: 'none', + }, + }, +}) + +export const formNavMobileBarSpacer = style({ + height: 'calc(92px + env(safe-area-inset-bottom))', + '@media': { + '(min-width: 768px)': { + display: 'none', + }, + }, +}) + +export const formNavDesktopRow = style({ + display: 'none', + '@media': { + '(min-width: 768px)': { + display: 'block', + }, + }, +}) diff --git a/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.tsx b/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.tsx index eb5cc4c2f..6c77a7cbf 100644 --- a/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.tsx +++ b/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.tsx @@ -1,10 +1,17 @@ import { AnimatedModal } from '@buildeross/ui/Modal' import { Button, Flex, Icon } from '@buildeross/zord' import React, { useState } from 'react' +import { createPortal } from 'react-dom' import { useFormStore } from '../../stores' import { ConfirmReset } from '../ConfirmReset/ConfirmReset' -import { formNavContinueButton, formNavResetButton } from './FormNavButtons.css' +import { + formNavContinueButton, + formNavDesktopRow, + formNavMobileBar, + formNavMobileBarSpacer, + formNavResetButton, +} from './FormNavButtons.css' interface FormNavButtonsProps { hasPrev?: boolean @@ -16,6 +23,7 @@ interface FormNavButtonsProps { children?: React.ReactNode showReset?: boolean onAfterReset?: () => void + formId?: string } export const FormNavButtons: React.FC = ({ @@ -28,16 +36,36 @@ export const FormNavButtons: React.FC = ({ children, showReset = true, onAfterReset, + formId, }) => { const [isModalOpen, setIsModalOpen] = useState(false) + const [isMounted, setIsMounted] = useState(false) const { resetForm } = useFormStore() + React.useEffect(() => { + setIsMounted(true) + }, []) + const handleReset = () => { resetForm() setIsModalOpen(false) onAfterReset?.() } + const handleMobileContinue = () => { + if (!isSubmit) { + onNext?.() + return + } + + if (formId) { + ;(document.getElementById(formId) as HTMLFormElement)?.requestSubmit() + } else { + const form = document.querySelector('form') + if (form) (form as HTMLFormElement).requestSubmit() + } + } + return ( <> {showReset && ( @@ -53,61 +81,121 @@ export const FormNavButtons: React.FC = ({ )} - - {showReset && ( - - )} +
+ + {showReset && ( + + )} - {hasPrev && ( - - )} + {hasPrev && ( + + )} + + {children ? ( + children + ) : ( + + )} + +
+ +
+ {isMounted && + createPortal( +
+ + {showReset && ( + + )} + + {hasPrev && ( + + )} - {children ? ( - children - ) : ( - + {children ? ( + children + ) : ( + + )} + +
, + document.body )} - ) } diff --git a/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx b/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx index 36e359f9d..114af18b6 100644 --- a/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx +++ b/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx @@ -1,62 +1,23 @@ -import { AnimatedModal } from '@buildeross/ui/Modal' -import { Playground } from '@buildeross/ui/Playground' -import { flatten } from '@buildeross/utils/helpers' -import { Button } from '@buildeross/zord' -import React, { BaseSyntheticEvent } from 'react' +import { Box, Flex } from '@buildeross/zord' import { useFormStore } from '../../stores' export const PreviewArtwork: React.FC = () => { const { ipfsUpload, orderedLayers } = useFormStore() - const images = React.useMemo(() => { - if (!ipfsUpload) return - - const entries = Object.entries(ipfsUpload) - const uploads = entries.reduce((acc: any[] = [], cv) => { - acc.push(cv[1]) - - return acc - }, []) - - return uploads.reduce((acc: any[] = [], cv) => { - if (!cv || typeof cv !== 'object') return - const image = flatten(cv) - acc.push({ - cid: image.cid, - name: image.name, - trait: image.trait, - uri: image.uri, - url: image.url, - content: cv.content, - }) - - return acc - }, []) - }, [ipfsUpload]) - - const [isOpenModal, setIsOpenModal] = React.useState(false) + const filesCount = ipfsUpload ? ipfsUpload.length : 0 + const traitCategoriesCount = orderedLayers?.length || 0 + const totalTraitOptions = orderedLayers + ? orderedLayers.reduce((acc, layer) => { + return acc + (layer.properties?.length || 0) + }, 0) + : 0 return ( - <> - - {images && orderedLayers && ( - setIsOpenModal(false)} - size={'large'} - > - - - )} - + + {filesCount} PNG files + {traitCategoriesCount} trait categories + {totalTraitOptions} total trait options + ) } diff --git a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.css.ts b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.css.ts index edcf5690f..8ef7bfa51 100644 --- a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.css.ts +++ b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.css.ts @@ -38,6 +38,7 @@ export const deployCheckboxStyle = style({ minWidth: 26, border: `1px solid ${vars.color.text1}`, borderRadius: '5px', + padding: 0, selectors: { '&:hover': { cursor: 'pointer', background: vars.color.text1 }, }, diff --git a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx index 4aa4266e9..9fcf7c6c0 100644 --- a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx +++ b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx @@ -98,7 +98,6 @@ export const ReviewAndDeploy: React.FC = ({ contributionAllocation, general, auctionSettings, - setUpArtwork, setActiveSection, activeSection, fulfilledSections, @@ -465,13 +464,14 @@ export const ReviewAndDeploy: React.FC = ({ } /> - = ({ ] } onClick={() => setHasConfirmedTerms((bool) => !bool)} + aria-pressed={hasConfirmedTerms} + aria-label="Confirm terms of service" > {hasConfirmedTerms && } - [I have reviewed and acknowledge and agree to the{' '} + I have reviewed, acknowledge, and agree to the{' '} = ({ > Nouns Builder Terms of Service - ] @@ -502,6 +503,8 @@ export const ReviewAndDeploy: React.FC = ({ = ({ ] } onClick={() => setHasConfirmedChain((bool) => !bool)} + aria-pressed={hasConfirmedChain} + aria-label="Confirm deployment chain" > {hasConfirmedChain && } @@ -524,6 +529,8 @@ export const ReviewAndDeploy: React.FC = ({ = ({ ] } onClick={() => setHasConfirmedRewards((bool) => !bool)} + aria-pressed={hasConfirmedRewards} + aria-label="Confirm rewards documentation" > {hasConfirmedRewards && } @@ -556,6 +565,8 @@ export const ReviewAndDeploy: React.FC = ({ = ({ ] } onClick={() => setHasConfirmedFastDAO((bool) => !bool)} + aria-pressed={hasConfirmedFastDAO} + aria-label="Confirm fast DAO timings" > {hasConfirmedFastDAO && } @@ -586,21 +599,20 @@ export const ReviewAndDeploy: React.FC = ({ {deploymentError} )} - - - - {`${isPendingTransaction ? 'Deploying' : 'Deploy'} Contracts (1 of 2)`} - - + + + {`${isPendingTransaction ? 'Deploying' : 'Deploy'} Contracts (1 of 2)`} + + ) : ( diff --git a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewItem.css.ts b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewItem.css.ts index 51a678446..b61fd5d43 100644 --- a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewItem.css.ts +++ b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewItem.css.ts @@ -33,7 +33,7 @@ export const infoSectionLabelStyle = style({ fontWeight: 500, textTransform: 'uppercase', letterSpacing: '.05em', - color: vars.color.text2, + color: vars.color.text3, }) export const infoSectionValueStyle = style({ diff --git a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewSection.css.ts b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewSection.css.ts index a82e90e66..ac681543e 100644 --- a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewSection.css.ts +++ b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewSection.css.ts @@ -11,11 +11,6 @@ const reviewSectionStyle = style({ borderColor: vars.color.text1, }, }, - '@media': { - '(max-width: 768px)': { - padding: '10px', - }, - }, }) export const reviewSectionStyleVariants = styleVariants({ diff --git a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewSection.tsx b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewSection.tsx index 4ba2df7bd..ce7d09d48 100644 --- a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewSection.tsx +++ b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewSection.tsx @@ -6,7 +6,7 @@ import { reviewSectionStyleVariants, reviewSectionSubHeading } from './ReviewSec export const ReviewSection: React.FC<{ subHeading: string - children: ReactNode[] + children: ReactNode }> = ({ subHeading, children }) => { const [isOpen, setIsOpen] = React.useState(false) const variants = { @@ -31,6 +31,15 @@ export const ReviewSection: React.FC<{ borderColor={'primary'} className={reviewSectionStyleVariants[isOpen ? 'open' : 'default']} onClick={() => setIsOpen((bool) => !bool)} + role="button" + tabIndex={0} + onKeyDown={(e: React.KeyboardEvent) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault() + setIsOpen((bool) => !bool) + } + }} + aria-expanded={isOpen} > = ({ {!isTestnetDAO && ( setHasConfirmed((bool) => !bool)} + aria-pressed={hasConfirmed} + aria-label="Confirm testnet artwork addition" + style={{ borderWidth: 0, padding: 0 }} > {hasConfirmed && } diff --git a/packages/create-proposal-ui/src/components/TransactionForm/Migration/PauseAuctionsForm.tsx b/packages/create-proposal-ui/src/components/TransactionForm/Migration/PauseAuctionsForm.tsx index f2a14d9aa..bc7b24807 100644 --- a/packages/create-proposal-ui/src/components/TransactionForm/Migration/PauseAuctionsForm.tsx +++ b/packages/create-proposal-ui/src/components/TransactionForm/Migration/PauseAuctionsForm.tsx @@ -106,10 +106,14 @@ export const PauseAuctionsForm: React.FC = () => { )} setReduceDelay((bool) => !bool)} + aria-pressed={reduceDelay} + aria-label="Reduce voting delay and period" > {reduceDelay && } diff --git a/packages/create-proposal-ui/src/components/TransactionForm/ReplaceArtwork/ReplaceArtworkForm.css.ts b/packages/create-proposal-ui/src/components/TransactionForm/ReplaceArtwork/ReplaceArtworkForm.css.ts index 38e74c111..6cce78e02 100644 --- a/packages/create-proposal-ui/src/components/TransactionForm/ReplaceArtwork/ReplaceArtworkForm.css.ts +++ b/packages/create-proposal-ui/src/components/TransactionForm/ReplaceArtwork/ReplaceArtworkForm.css.ts @@ -13,6 +13,7 @@ export const checkboxStyle = style({ minWidth: 26, border: `1px solid ${vars.color.text1}`, borderRadius: '5px', + padding: 0, selectors: { '&:hover, &:focus-visible': { cursor: 'pointer', background: vars.color.text1 }, }, diff --git a/packages/create-proposal-ui/src/components/TransactionForm/ReplaceArtwork/ReplaceArtworkForm.tsx b/packages/create-proposal-ui/src/components/TransactionForm/ReplaceArtwork/ReplaceArtworkForm.tsx index c7fffa10d..881a85d1e 100644 --- a/packages/create-proposal-ui/src/components/TransactionForm/ReplaceArtwork/ReplaceArtworkForm.tsx +++ b/packages/create-proposal-ui/src/components/TransactionForm/ReplaceArtwork/ReplaceArtworkForm.tsx @@ -115,12 +115,17 @@ export const ReplaceArtworkForm: React.FC = ({ {!isTestnetDAO && ( setHasConfirmed((bool) => !bool)} + aria-pressed={hasConfirmed} + aria-label="Confirm testnet artwork replacement" + style={{ borderWidth: 0, padding: 0 }} > {hasConfirmed && } diff --git a/packages/dao-ui/src/components/DaoCard/DaoCard.css.ts b/packages/dao-ui/src/components/DaoCard/DaoCard.css.ts index bc5b45a6f..57790bf1d 100644 --- a/packages/dao-ui/src/components/DaoCard/DaoCard.css.ts +++ b/packages/dao-ui/src/components/DaoCard/DaoCard.css.ts @@ -1,4 +1,4 @@ -import { atoms, theme, vars } from '@buildeross/zord' +import { atoms, theme } from '@buildeross/zord' import { style } from '@vanilla-extract/css' export const card = style({ @@ -15,35 +15,17 @@ export const cardWrapper = style({ export const daoImage = style({ position: 'relative', - '::after': { - boxShadow: `0px 0px 0px 2px color-mix(in srgb, ${vars.color.text1} 4%, transparent) inset`, - content: '', - display: 'block', - height: '100%', - position: 'absolute', - top: 0, - width: '100%', - borderTopRightRadius: 12, - borderTopLeftRadius: 12, - pointerEvents: 'none', - transition: 'all 0.15s ease-in-out', - }, - selectors: { - [`${card}:hover &::after`]: { - boxShadow: `0px 0px 0px 2px color-mix(in srgb, ${vars.color.text1} 8%, transparent) inset`, - }, - }, + border: `2px solid ${theme.colors.border}`, + transition: 'border 0.15s ease-in-out', + borderBottom: 'none', + borderBottomLeftRadius: 0, + borderBottomRightRadius: 0, }) export const border = style({ border: `2px solid ${theme.colors.border}`, - transition: 'all 0.15s ease-in-out', + transition: 'border 0.15s ease-in-out', borderTop: 'none', - selectors: { - [`${card}:hover &`]: { - borderColor: theme.colors.border, - }, - }, }) export const title = style([border]) @@ -92,7 +74,7 @@ export const favoriteButton = style({ boxShadow: `0 10px 28px ${theme.colors.ghostHover}`, }, ':focus-visible': { - outline: `2px solid ${theme.colors.text1}`, + outline: `2px solid ${theme.colors.focusRing}`, outlineOffset: 2, }, ':disabled': { diff --git a/packages/dao-ui/src/components/DaoCard/DaoCard.tsx b/packages/dao-ui/src/components/DaoCard/DaoCard.tsx index d50b886d4..ca0048e5f 100644 --- a/packages/dao-ui/src/components/DaoCard/DaoCard.tsx +++ b/packages/dao-ui/src/components/DaoCard/DaoCard.tsx @@ -87,6 +87,7 @@ export const DaoCard = ({ aspectRatio={1 / 1} position="relative" overflow={'hidden'} + borderRadius={'curved'} className={daoImage} > { icon?: ReactNode } +type DropdownHeight = 'x18' | 'x14' | 'x12' | 'x10' + interface DropdownSelectProps { id?: string value?: T @@ -84,6 +86,8 @@ interface DropdownSelectProps { buttonVariant?: ButtonProps['variant'] buttonSize?: ButtonProps['size'] align?: 'left' | 'right' + height?: DropdownHeight + minWidth?: string } export function DropdownSelect({ @@ -101,6 +105,8 @@ export function DropdownSelect({ buttonVariant = 'primary', buttonSize = 'md', align = 'left', + height = 'x18', + minWidth = '200px', }: React.PropsWithChildren>) { const [showOptions, setShowOptions] = useState(false) const [activeIndex, setActiveIndex] = useState(-1) @@ -229,8 +235,8 @@ export function DropdownSelect({ direction={'row'} align={'center'} py={option.description ? 'x3' : undefined} - height={option.description ? undefined : 'x18'} - minHeight={'x18'} + height={option.description ? undefined : height} + minHeight={height} width={'100%'} gap={option.description ? 'x3' : undefined} fontSize={option.description ? undefined : 16} @@ -370,7 +376,7 @@ export function DropdownSelect({ pl={'x4'} direction={'row'} align={'center'} - height={'x18'} + height={height} fontSize={16} fontWeight={'display'} > @@ -432,6 +438,9 @@ export function DropdownSelect({ exit={'init'} variants={absoluteVariants} className={absoluteDropdownMenu[align]} + style={{ + minWidth: minWidth, + }} > {renderOptions(dropdownOption)} diff --git a/packages/ui/src/Fields/Radio.tsx b/packages/ui/src/Fields/Radio.tsx index 58573bfe0..750664c0d 100644 --- a/packages/ui/src/Fields/Radio.tsx +++ b/packages/ui/src/Fields/Radio.tsx @@ -25,12 +25,27 @@ export function Radio({ formik.setFieldValue(id, val) } + const handleKeyDown = (e: React.KeyboardEvent) => { + const currentIndex = options.findIndex((opt) => opt.value === value) + if (e.key === 'ArrowRight' || e.key === 'ArrowDown') { + e.preventDefault() + const nextIndex = (currentIndex + 1) % options.length + handleSelection(options[nextIndex].value) + } else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') { + e.preventDefault() + const prevIndex = currentIndex <= 0 ? options.length - 1 : currentIndex - 1 + handleSelection(options[prevIndex].value) + } + } + return ( {inputLabel && } - + {options.map((option) => ( ({ ] } onClick={() => handleSelection(option.value)} + role="radio" + aria-checked={value !== undefined && option.value === value} + tabIndex={value !== undefined && option.value === value ? 0 : -1} > {option.label} diff --git a/packages/ui/src/Fields/StickySave.tsx b/packages/ui/src/Fields/StickySave.tsx index 001ed311b..8e8e66322 100644 --- a/packages/ui/src/Fields/StickySave.tsx +++ b/packages/ui/src/Fields/StickySave.tsx @@ -92,12 +92,17 @@ const StickySave: React.FC = ({ {hasConfirmed && } diff --git a/packages/ui/src/Fields/styles.css.ts b/packages/ui/src/Fields/styles.css.ts index 59611f363..92dd8a55f 100644 --- a/packages/ui/src/Fields/styles.css.ts +++ b/packages/ui/src/Fields/styles.css.ts @@ -29,7 +29,6 @@ export const defaultFieldsetStyle = style({ position: 'relative', border: 0, padding: 0, - overflow: 'hidden', }) export const defaultTextAreaStyle = style({ @@ -51,7 +50,7 @@ export const defaultTextAreaStyle = style({ borderColor: vars.color.border, }, '&:focus-visible': { - outline: `2px solid ${vars.color.accent}`, + outline: `2px solid ${vars.color.focusRing}`, outlineOffset: '2px', }, }, @@ -74,7 +73,7 @@ export const defaultTextAreaErrorStyle = style({ borderColor: vars.color.negative, }, '&:focus-visible': { - outline: `2px solid ${vars.color.accent}`, + outline: `2px solid ${vars.color.focusRing}`, outlineOffset: '2px', }, }, @@ -96,7 +95,7 @@ export const defaultInputStyle = style({ borderColor: vars.color.border, }, '&:focus-visible': { - outline: `2px solid ${vars.color.accent}`, + outline: `2px solid ${vars.color.focusRing}`, outlineOffset: '2px', }, '&::placeholder': { @@ -125,7 +124,7 @@ export const defaultInputErrorStyle = style({ borderColor: vars.color.negative, }, '&:focus-visible': { - outline: `2px solid ${vars.color.accent}`, + outline: `2px solid ${vars.color.focusRing}`, outlineOffset: '2px', }, '&:disabled': { @@ -213,7 +212,6 @@ export const numberInputStyle = style({ paddingRight: 25, boxSizing: 'border-box', border: `2px solid ${vars.color.background1}`, - overflow: 'hidden', selectors: { '&:focus': { outline: 'none', @@ -221,7 +219,7 @@ export const numberInputStyle = style({ borderColor: vars.color.border, }, '&:focus-visible': { - outline: `2px solid ${vars.color.accent}`, + outline: `2px solid ${vars.color.focusRing}`, outlineOffset: '2px', }, '&::-webkit-input-placeholder': { @@ -258,7 +256,7 @@ export const numberInputErrorStyle = style({ borderColor: vars.color.negative, }, '&:focus-visible': { - outline: `2px solid ${vars.color.accent}`, + outline: `2px solid ${vars.color.focusRing}`, outlineOffset: '2px', }, '&::-webkit-input-placeholder': { @@ -350,6 +348,7 @@ export const confirmRemoveHelper = style({ }) const pointer = style({ + padding: 0, background: vars.color.background2, border: `2px solid ${vars.color.background2}`, selectors: { diff --git a/packages/ui/src/SingleImageUpload/SingleImageUpload.css.ts b/packages/ui/src/SingleImageUpload/SingleImageUpload.css.ts index c436b9be2..483ec13ca 100644 --- a/packages/ui/src/SingleImageUpload/SingleImageUpload.css.ts +++ b/packages/ui/src/SingleImageUpload/SingleImageUpload.css.ts @@ -12,6 +12,8 @@ export const uploadErrorBox = style({ export const singleImageUploadWrapperVariants = styleVariants({ sm: { + border: 0, + padding: 0, height: 80, width: 80, borderRadius: 40, @@ -21,9 +23,15 @@ export const singleImageUploadWrapperVariants = styleVariants({ '&:hover': { cursor: 'pointer', }, + '&:focus-visible': { + outline: `2px solid ${vars.color.focusRing}`, + outlineOffset: '2px', + }, }, }, md: { + border: 0, + padding: 0, height: 160, width: 160, borderRadius: 80, @@ -33,9 +41,15 @@ export const singleImageUploadWrapperVariants = styleVariants({ '&:hover': { cursor: 'pointer', }, + '&:focus-visible': { + outline: `2px solid ${vars.color.focusRing}`, + outlineOffset: '2px', + }, }, }, lg: { + border: 0, + padding: 0, height: 240, width: 240, borderRadius: 120, @@ -45,9 +59,15 @@ export const singleImageUploadWrapperVariants = styleVariants({ '&:hover': { cursor: 'pointer', }, + '&:focus-visible': { + outline: `2px solid ${vars.color.focusRing}`, + outlineOffset: '2px', + }, }, }, xl: { + border: 0, + padding: 0, height: 320, width: 320, borderRadius: 160, @@ -57,6 +77,10 @@ export const singleImageUploadWrapperVariants = styleVariants({ '&:hover': { cursor: 'pointer', }, + '&:focus-visible': { + outline: `2px solid ${vars.color.focusRing}`, + outlineOffset: '2px', + }, }, }, }) diff --git a/packages/ui/src/SingleImageUpload/SingleImageUpload.test.tsx b/packages/ui/src/SingleImageUpload/SingleImageUpload.test.tsx index 98e5f6c57..b7c832f18 100644 --- a/packages/ui/src/SingleImageUpload/SingleImageUpload.test.tsx +++ b/packages/ui/src/SingleImageUpload/SingleImageUpload.test.tsx @@ -24,6 +24,7 @@ describe('Single image upload', () => { }) it('should upload a file successfully', async () => { + const user = userEvent.setup() mockUploadFn.mockResolvedValueOnce({ cid: '1234' }) const file = new File(['hello'], 'hello.png', { type: 'image/png' }) @@ -50,7 +51,7 @@ describe('Single image upload', () => { expect(screen.queryByText(/Upload/)).toBeInTheDocument() const input = screen.getByTestId('file-upload') as HTMLInputElement - userEvent.upload(input, file) + await user.upload(input, file) await waitFor(() => { expect(input.files).toHaveLength(1) @@ -61,6 +62,7 @@ describe('Single image upload', () => { }) it('should render an error message given a rejected file upload', async () => { + const user = userEvent.setup() mockUploadFn.mockRejectedValueOnce(new Error('Error')) const file = new File(['hello'], 'hello.png', { type: 'image/png' }) @@ -87,9 +89,9 @@ describe('Single image upload', () => { expect(screen.queryByText(/Upload/)).toBeInTheDocument() const input = screen.getByTestId('file-upload') as HTMLInputElement + await user.upload(input, file) await waitFor(() => { - userEvent.upload(input, file) expect(input.files).toHaveLength(1) }) @@ -98,6 +100,7 @@ describe('Single image upload', () => { }) it('should reject an unsupported file type', async () => { + const user = userEvent.setup({ applyAccept: false }) const mockSubmitFn = vi.fn() const file = new File(['hello'], 'hello.txt', { type: 'text/plain' }) @@ -123,7 +126,7 @@ describe('Single image upload', () => { expect(screen.queryByText(/Upload/)).toBeInTheDocument() const input = screen.getByTestId('file-upload') as HTMLInputElement - userEvent.upload(input, file) + await user.upload(input, file) await waitFor(() => { expect(input.files).toHaveLength(1) diff --git a/packages/ui/src/SingleImageUpload/SingleImageUpload.tsx b/packages/ui/src/SingleImageUpload/SingleImageUpload.tsx index a89dd888e..9e0db58f6 100644 --- a/packages/ui/src/SingleImageUpload/SingleImageUpload.tsx +++ b/packages/ui/src/SingleImageUpload/SingleImageUpload.tsx @@ -32,6 +32,7 @@ export const SingleImageUpload: React.FC = ({ const [isMounted, setIsMounted] = useState(false) const [uploadArtworkError, setUploadArtworkError] = React.useState() const [isUploading, setIsUploading] = React.useState(false) + const fileInputRef = React.useRef(null) useEffect(() => { setIsMounted(true) @@ -75,13 +76,15 @@ export const SingleImageUpload: React.FC = ({ fileInputRef.current?.click()} + aria-label={typeof inputLabel === 'string' ? inputLabel : 'Upload image'} > {isUploading && } @@ -107,20 +110,22 @@ export const SingleImageUpload: React.FC = ({ )} - - { - handleFileUpload(event.currentTarget.files) - }} - /> + { + handleFileUpload(event.currentTarget.files) + }} + /> + {uploadArtworkError && ( diff --git a/packages/ui/src/SingleMediaUpload/SingleMediaUpload.css.ts b/packages/ui/src/SingleMediaUpload/SingleMediaUpload.css.ts index 4162ad6c3..a286605fa 100644 --- a/packages/ui/src/SingleMediaUpload/SingleMediaUpload.css.ts +++ b/packages/ui/src/SingleMediaUpload/SingleMediaUpload.css.ts @@ -11,6 +11,8 @@ export const uploadErrorBox = style({ }) export const singleMediaUploadWrapper = style({ + border: 0, + padding: 0, height: 64, width: '100%', borderRadius: 15, @@ -20,5 +22,9 @@ export const singleMediaUploadWrapper = style({ '&:hover': { cursor: 'pointer', }, + '&:focus-visible': { + outline: `2px solid ${vars.color.focusRing}`, + outlineOffset: '2px', + }, }, }) diff --git a/packages/ui/src/SingleMediaUpload/SingleMediaUpload.tsx b/packages/ui/src/SingleMediaUpload/SingleMediaUpload.tsx index ed0dce3cd..5c226fc31 100644 --- a/packages/ui/src/SingleMediaUpload/SingleMediaUpload.tsx +++ b/packages/ui/src/SingleMediaUpload/SingleMediaUpload.tsx @@ -41,6 +41,7 @@ export const SingleMediaUpload: React.FC = ({ const [isUploading, setIsUploading] = React.useState(false) const [fileName, setFileName] = React.useState() const [progress, setProgress] = React.useState(0) + const fileInputRef = React.useRef(null) useEffect(() => { setIsMounted(true) @@ -102,14 +103,18 @@ export const SingleMediaUpload: React.FC = ({ return ( - + fileInputRef.current?.click()} + aria-label={typeof inputLabel === 'string' ? inputLabel : 'Upload media'} > {!isUploading && isMounted && !value && ( @@ -146,19 +151,21 @@ export const SingleMediaUpload: React.FC = ({ )} - - { - handleFileUpload(event.currentTarget.files) - }} - /> + + { + handleFileUpload(event.currentTarget.files) + }} + /> {helperText && !uploadMediaError && ( {helperText} )} diff --git a/packages/ui/src/WalletIdentity/WalletIdentity.tsx b/packages/ui/src/WalletIdentity/WalletIdentity.tsx index 657876e95..eb35ec3b0 100644 --- a/packages/ui/src/WalletIdentity/WalletIdentity.tsx +++ b/packages/ui/src/WalletIdentity/WalletIdentity.tsx @@ -3,6 +3,8 @@ import { Flex, Text } from '@buildeross/zord' import { type ComponentProps, type CSSProperties } from 'react' import { Avatar, type AvatarProps } from '../Avatar' +import { useLinks } from '../LinksProvider' +import { LinkWrapper as Link } from '../LinkWrapper' export interface WalletIdentityProps { address: `0x${string}` @@ -15,6 +17,7 @@ export interface WalletIdentityProps { nameStyle?: CSSProperties nameWeight?: ComponentProps['fontWeight'] gap?: ComponentProps['gap'] + asLink?: boolean } export const WalletIdentity = ({ @@ -28,8 +31,10 @@ export const WalletIdentity = ({ nameStyle, nameWeight = 'display', gap = 'x2', + asLink = false, }: WalletIdentityProps) => { - return ( + const { getProfileLink } = useLinks() + const inner = ( ) + + if (asLink) { + return ( + + {inner}{' '} + + ) + } + + return inner } diff --git a/packages/ui/src/WalletProfilePreview/WalletProfilePreview.css.ts b/packages/ui/src/WalletProfilePreview/WalletProfilePreview.css.ts index 83336ff71..339b27b3e 100644 --- a/packages/ui/src/WalletProfilePreview/WalletProfilePreview.css.ts +++ b/packages/ui/src/WalletProfilePreview/WalletProfilePreview.css.ts @@ -17,7 +17,7 @@ export const profileHeaderLink = style([ backgroundColor: theme.colors.background2, }, ':focus-visible': { - outline: `2px solid ${theme.colors.accent}`, + outline: `2px solid ${theme.colors.focusRing}`, outlineOffset: '2px', }, }, @@ -37,7 +37,7 @@ export const daoLink = style([ backgroundColor: theme.colors.background2, }, ':focus-visible': { - outline: `2px solid ${theme.colors.accent}`, + outline: `2px solid ${theme.colors.focusRing}`, outlineOffset: '2px', }, }, diff --git a/packages/zord/src/components/PopUp.tsx b/packages/zord/src/components/PopUp.tsx index b3053572d..c071cc684 100644 --- a/packages/zord/src/components/PopUp.tsx +++ b/packages/zord/src/components/PopUp.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react' import { usePopper } from 'react-popper' import { Atoms } from '../atoms.css' -import { Box, Button, Icon } from '../elements' +import { Box, Flex, Icon } from '../elements' import { container } from './PopUp.css' interface BasePopUpProps { @@ -20,6 +20,7 @@ interface BasePopUpProps { showBackdrop?: boolean viewportPadding?: number allowFlip?: boolean + ariaHasPopup?: 'menu' | 'listbox' | 'dialog' | 'tree' | 'grid' | true | false } export type PopUpProps = BasePopUpProps & @@ -50,6 +51,7 @@ export function PopUp({ showBackdrop = true, viewportPadding = 0, allowFlip = true, + ariaHasPopup = 'menu', }: PopUpProps) { const [triggerElement, setTriggerElement] = useState(null) const [popperElement, setPopperElement] = useState(null) @@ -96,23 +98,35 @@ export function PopUp({ <> {triggerRef === undefined && ( { e.stopPropagation() - setOpenState(!openState) + setOpenState((prev) => !prev) + }} + onKeyDown={(e: React.KeyboardEvent) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault() + e.stopPropagation() + setOpenState((prev) => !prev) + } }} - ref={setTriggerElement} - className={[triggerClassName]} > {trigger || ( - + )} )} diff --git a/packages/zord/src/elements/Button.css.ts b/packages/zord/src/elements/Button.css.ts index a50695c48..a7cf5b51e 100644 --- a/packages/zord/src/elements/Button.css.ts +++ b/packages/zord/src/elements/Button.css.ts @@ -20,7 +20,7 @@ export const baseButton = style([ userSelect: 'none', selectors: { '&:focus-visible': { - outline: `2px solid ${vars.color.accent}`, + outline: `2px solid ${vars.color.focusRing}`, outlineStyle: 'auto', }, '&:active': { @@ -29,7 +29,6 @@ export const baseButton = style([ '&[disabled]': { cursor: 'not-allowed', pointerEvents: 'none', - opacity: 0.6, }, '&[disabled]:active': { transform: 'unset', @@ -109,6 +108,10 @@ export const buttonVariants = { primary: style([ { selectors: { + '&[disabled]': { + backgroundColor: vars.color.accentDisabled, + color: vars.color.onAccent, + }, '&:not([disabled]):hover': { cursor: 'pointer', backgroundColor: vars.color.accentHover, @@ -123,6 +126,10 @@ export const buttonVariants = { secondary: style([ { selectors: { + '&[disabled]': { + backgroundColor: vars.color.neutralDisabled, + color: vars.color.onNeutralDisabled, + }, '&:not([disabled]):hover': { cursor: 'pointer', backgroundColor: vars.color.neutralHover, @@ -137,6 +144,10 @@ export const buttonVariants = { secondaryAccent: style([ { selectors: { + '&[disabled]': { + backgroundColor: vars.color.neutralDisabled, + color: vars.color.onNeutralDisabled, + }, '&:not([disabled]):hover': { cursor: 'pointer', backgroundColor: vars.color.neutralHover, @@ -151,6 +162,10 @@ export const buttonVariants = { positive: style([ { selectors: { + '&[disabled]': { + backgroundColor: vars.color.positiveDisabled, + color: vars.color.onPositive, + }, '&:not([disabled]):hover': { cursor: 'pointer', backgroundColor: vars.color.positiveHover, @@ -165,6 +180,10 @@ export const buttonVariants = { destructive: style([ { selectors: { + '&[disabled]': { + backgroundColor: vars.color.negativeDisabled, + color: vars.color.onNegative, + }, '&:not([disabled]):hover': { cursor: 'pointer', backgroundColor: vars.color.negativeHover, @@ -179,6 +198,10 @@ export const buttonVariants = { outline: style([ { selectors: { + '&[disabled]': { + color: vars.color.onNeutralDisabled, + borderColor: vars.color.neutralDisabled, + }, '&:not([disabled]):hover': { cursor: 'pointer', backgroundColor: vars.color.background2, @@ -250,6 +273,11 @@ export const buttonVariants = { ghost: style([ { selectors: { + '&[disabled]': { + color: vars.color.onGhostDisabled, + backgroundColor: vars.color.ghostDisabled, + borderColor: vars.color.ghostDisabled, + }, '&:hover, &:not([disabled]):hover': { cursor: 'pointer', backgroundColor: vars.color.ghostHover, diff --git a/packages/zord/src/theme.css.ts b/packages/zord/src/theme.css.ts index 8215c4f53..3fcec0df3 100644 --- a/packages/zord/src/theme.css.ts +++ b/packages/zord/src/theme.css.ts @@ -181,6 +181,7 @@ export const theme = createThemeContract({ accentHover: '', accentActive: '', accentDisabled: '', + focusRing: '', onAccent: '', onAccentDisabled: '', positive: '', diff --git a/packages/zord/src/tokens/color.ts b/packages/zord/src/tokens/color.ts index c5abf0dc5..6a458f5e4 100644 --- a/packages/zord/src/tokens/color.ts +++ b/packages/zord/src/tokens/color.ts @@ -22,6 +22,7 @@ export const color = { accentHover: '#282828', accentActive: '#333333', accentDisabled: '#505050', + focusRing: '#0085FF', onAccent: '#FFFFFF', onAccentDisabled: '#ABABAB', diff --git a/packages/zord/src/utils/color-theme.ts b/packages/zord/src/utils/color-theme.ts index 4e1eafd91..541459191 100644 --- a/packages/zord/src/utils/color-theme.ts +++ b/packages/zord/src/utils/color-theme.ts @@ -69,6 +69,7 @@ export function colorThemeVars({ accentHover: mix(0.2, accent, background), accentActive: mix(0.3, accent, background), accentDisabled: mix(0.4, accent, background), + focusRing: '#0085FF', onAccent: background, onAccentDisabled: mix(0.6, accent, background), @@ -140,6 +141,7 @@ export function colorTheme(colorProps: { [x: string]: string }) { accentHover: tokens.accentHover, accentActive: tokens.accentActive, accentDisabled: tokens.accentDisabled, + focusRing: tokens.focusRing, onAccent: tokens.onAccent, onAccentDisabled: tokens.onAccentDisabled,