From 71fbd49ba2ea4c71c715f85dda99ddf3a66e7add Mon Sep 17 00:00:00 2001 From: dan13ram Date: Wed, 6 May 2026 16:10:17 +0530 Subject: [PATCH 01/10] fix: standardize focus rings and keyboard interaction --- .../DefaultLayout/NavMenu/ChainMenu.tsx | 8 +++++++ .../src/modules/explore/SearchInput.css.ts | 2 +- .../components/PlaygroundLanding.css.ts | 6 ++--- apps/web/src/styles/flatpickr-theme.css | 9 +++++++ apps/web/src/styles/globals.css | 2 ++ apps/web/src/styles/react-mde-theme.css | 10 ++++++++ .../src/components/DaoCard/DaoCard.css.ts | 2 +- packages/feed-ui/src/SearchInput.css.ts | 2 +- packages/ui/src/Artwork/Artwork.css.ts | 2 +- packages/ui/src/Fields/styles.css.ts | 14 +++++------ .../SingleImageUpload.css.ts | 24 +++++++++++++++++++ .../SingleImageUpload/SingleImageUpload.tsx | 12 ++++++---- .../SingleMediaUpload.css.ts | 6 +++++ .../SingleMediaUpload/SingleMediaUpload.tsx | 8 +++++-- .../WalletProfilePreview.css.ts | 4 ++-- packages/zord/src/components/PopUp.tsx | 11 +++++++++ packages/zord/src/elements/Button.css.ts | 2 +- packages/zord/src/theme.css.ts | 1 + packages/zord/src/tokens/color.ts | 1 + packages/zord/src/utils/color-theme.ts | 2 ++ 20 files changed, 104 insertions(+), 24 deletions(-) diff --git a/apps/web/src/layouts/DefaultLayout/NavMenu/ChainMenu.tsx b/apps/web/src/layouts/DefaultLayout/NavMenu/ChainMenu.tsx index 4dddd5603..fec20e974 100644 --- a/apps/web/src/layouts/DefaultLayout/NavMenu/ChainMenu.tsx +++ b/apps/web/src/layouts/DefaultLayout/NavMenu/ChainMenu.tsx @@ -175,6 +175,8 @@ export const ChainMenu: React.FC = ({ {isWrongNetwork && selectedChain && ( = ({ mb="x2" align={'center'} justify={'center'} + style={{ borderRadius: '8px' }} > {`Switch to ${selectedChain.name}`} )} {PUBLIC_DEFAULT_CHAINS.map((chain, i, chains) => ( = ({ mb={i !== chains.length - 1 ? 'x2' : undefined} align={'center'} justify={'space-between'} + disabled={hasNetwork && !isSelectedChain(chain.id)} + aria-current={selectedChain.id === chain.id ? 'true' : undefined} + style={{ border: 0, width: '100%', textAlign: 'left' }} > 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/components/PlaygroundLanding.css.ts b/apps/web/src/modules/playground/components/PlaygroundLanding.css.ts index b129fc71c..3978be097 100644 --- a/apps/web/src/modules/playground/components/PlaygroundLanding.css.ts +++ b/apps/web/src/modules/playground/components/PlaygroundLanding.css.ts @@ -1,4 +1,4 @@ -import { atoms } from '@buildeross/zord' +import { atoms, vars } from '@buildeross/zord' import { style } from '@vanilla-extract/css' export const landingContainer = style([ @@ -81,12 +81,12 @@ export const card = style([ gap: '16px', minHeight: '240px', ':hover': { - outlineColor: 'var(--zord-colors-border-primary)', + outlineColor: vars.color.focusRing, transform: 'translateY(-4px)', boxShadow: '0 8px 16px rgba(0, 0, 0, 0.1)', }, ':focus-visible': { - outlineColor: 'var(--zord-colors-border-primary)', + outlineColor: vars.color.focusRing, outlineOffset: '2px', }, }, diff --git a/apps/web/src/styles/flatpickr-theme.css b/apps/web/src/styles/flatpickr-theme.css index 390d37861..4f22b7dab 100644 --- a/apps/web/src/styles/flatpickr-theme.css +++ b/apps/web/src/styles/flatpickr-theme.css @@ -85,3 +85,12 @@ span.flatpickr-weekday, .flatpickr-time .flatpickr-am-pm:focus { background: var(--flatpickr-hover); } + +.flatpickr-day:focus-visible, +.flatpickr-time input:focus-visible, +.flatpickr-time .flatpickr-am-pm:focus-visible, +.flatpickr-months .flatpickr-prev-month:focus-visible, +.flatpickr-months .flatpickr-next-month:focus-visible { + outline: 2px solid var(--focus-ring-color); + outline-offset: 2px; +} diff --git a/apps/web/src/styles/globals.css b/apps/web/src/styles/globals.css index 14bfcbd8d..e03dd548c 100644 --- a/apps/web/src/styles/globals.css +++ b/apps/web/src/styles/globals.css @@ -44,6 +44,7 @@ body { --flatpickr-selected-bg: #000; --flatpickr-selected-text: #fff; --flatpickr-backdrop-shadow: 0 12px 28px rgba(0, 0, 0, 0.15); + --focus-ring-color: #0085ff; --mde-border: #c8ccd0; --mde-header-bg: #f9f9f9; --mde-surface: #fff; @@ -70,6 +71,7 @@ html[data-theme-mode='dark'] { --flatpickr-selected-bg: #fff; --flatpickr-selected-text: #1f2024; --flatpickr-backdrop-shadow: 0 12px 28px rgba(0, 0, 0, 0.45); + --focus-ring-color: #0085ff; --mde-border: #3f4047; --mde-header-bg: #2a2b30; --mde-surface: #1f2024; diff --git a/apps/web/src/styles/react-mde-theme.css b/apps/web/src/styles/react-mde-theme.css index ee027d950..a06723717 100644 --- a/apps/web/src/styles/react-mde-theme.css +++ b/apps/web/src/styles/react-mde-theme.css @@ -44,6 +44,16 @@ outline: none; } +.markdown-editor-wrapper .mde-textarea-wrapper:focus-within { + box-shadow: inset 0 0 0 2px var(--focus-ring-color); +} + +.markdown-editor-wrapper .mde-tabs button:focus-visible, +.markdown-editor-wrapper ul.mde-header-group li.mde-header-item button:focus-visible { + outline: 2px solid var(--focus-ring-color); + outline-offset: 2px; +} + .markdown-editor-wrapper .mde-preview .mde-preview-content { background: var(--mde-surface); color: var(--mde-text); diff --git a/packages/dao-ui/src/components/DaoCard/DaoCard.css.ts b/packages/dao-ui/src/components/DaoCard/DaoCard.css.ts index bc5b45a6f..9974d2b59 100644 --- a/packages/dao-ui/src/components/DaoCard/DaoCard.css.ts +++ b/packages/dao-ui/src/components/DaoCard/DaoCard.css.ts @@ -92,7 +92,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/feed-ui/src/SearchInput.css.ts b/packages/feed-ui/src/SearchInput.css.ts index 932bbc02d..b23ecb226 100644 --- a/packages/feed-ui/src/SearchInput.css.ts +++ b/packages/feed-ui/src/SearchInput.css.ts @@ -26,7 +26,7 @@ export const searchInputStyle = style([ borderColor: vars.color.primary, }, '&:focus-visible': { - outline: `2px solid ${vars.color.accent}`, + outline: `2px solid ${vars.color.focusRing}`, outlineOffset: '2px', }, }, diff --git a/packages/ui/src/Artwork/Artwork.css.ts b/packages/ui/src/Artwork/Artwork.css.ts index 2a8be77cf..d70b48425 100644 --- a/packages/ui/src/Artwork/Artwork.css.ts +++ b/packages/ui/src/Artwork/Artwork.css.ts @@ -115,7 +115,7 @@ globalStyle(`html[data-theme-mode='dark'] ${layerSelectStyle}`, { globalStyle(`html[data-theme-mode='dark'] ${layerSelectStyle}:focus-visible`, { color: `${vars.color.text1} !important`, - outline: `2px solid ${vars.color.text1}`, + outline: `2px solid ${vars.color.focusRing}`, outlineOffset: '2px', }) diff --git a/packages/ui/src/Fields/styles.css.ts b/packages/ui/src/Fields/styles.css.ts index 59611f363..77ef4ae04 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': { 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.tsx b/packages/ui/src/SingleImageUpload/SingleImageUpload.tsx index a89dd888e..797932b3c 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 && } @@ -110,11 +113,12 @@ export const SingleImageUpload: React.FC = ({ { handleFileUpload(event.currentTarget.files) }} 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..401eb1c00 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) @@ -104,12 +105,14 @@ export const SingleMediaUpload: React.FC = ({ fileInputRef.current?.click()} + aria-label={typeof inputLabel === 'string' ? inputLabel : 'Upload media'} > {!isUploading && isMounted && !value && ( @@ -153,6 +156,7 @@ export const SingleMediaUpload: React.FC = ({ data-testid={`file-upload-${id}`} name="file" type="file" + ref={fileInputRef} multiple={false} onChange={(event) => { handleFileUpload(event.currentTarget.files) 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..5476628e2 100644 --- a/packages/zord/src/components/PopUp.tsx +++ b/packages/zord/src/components/PopUp.tsx @@ -96,10 +96,21 @@ export function PopUp({ <> {triggerRef === undefined && ( { e.stopPropagation() setOpenState(!openState) }} + onKeyDown={(e: React.KeyboardEvent) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault() + e.stopPropagation() + setOpenState((prev) => !prev) + } + }} ref={setTriggerElement} className={[triggerClassName]} > diff --git a/packages/zord/src/elements/Button.css.ts b/packages/zord/src/elements/Button.css.ts index a50695c48..4307852c6 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': { 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, From ad3d8b46c21526e00d11903b1af05377cdfe084b Mon Sep 17 00:00:00 2001 From: dan13ram Date: Wed, 6 May 2026 16:14:43 +0530 Subject: [PATCH 02/10] fix: make custom checkbox controls keyboard accessible --- .../AuctionSettingsForm.tsx | 5 +++++ .../ReviewAndDeploy/ReviewAndDeploy.tsx | 20 +++++++++++++++++++ .../AddArtwork/AddArtworkForm.tsx | 5 +++++ .../Migration/PauseAuctionsForm.tsx | 5 +++++ .../ReplaceArtwork/ReplaceArtworkForm.tsx | 5 +++++ packages/ui/src/Fields/Radio.tsx | 4 ++++ packages/ui/src/Fields/StickySave.tsx | 5 +++++ 7 files changed, 49 insertions(+) diff --git a/packages/create-dao-ui/src/components/AuctionSettingsForm/AuctionSettingsForm.tsx b/packages/create-dao-ui/src/components/AuctionSettingsForm/AuctionSettingsForm.tsx index d5e9d54b5..fb7315dbe 100644 --- a/packages/create-dao-ui/src/components/AuctionSettingsForm/AuctionSettingsForm.tsx +++ b/packages/create-dao-ui/src/components/AuctionSettingsForm/AuctionSettingsForm.tsx @@ -205,12 +205,17 @@ export const AuctionSettingsForm: React.FC = ({ title handleFastDAOToggle(formik)} + aria-pressed={enableFastDAO} + aria-label="Enable Fast DAO" + style={{ borderWidth: 0, padding: 0 }} > {enableFastDAO && } diff --git a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx index 4aa4266e9..03dbb2f12 100644 --- a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx +++ b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx @@ -472,6 +472,8 @@ export const ReviewAndDeploy: React.FC = ({ = ({ ] } onClick={() => setHasConfirmedTerms((bool) => !bool)} + aria-pressed={hasConfirmedTerms} + aria-label="Confirm terms of service" + style={{ borderWidth: 0, padding: 0 }} > {hasConfirmedTerms && } @@ -502,6 +507,8 @@ export const ReviewAndDeploy: React.FC = ({ = ({ ] } onClick={() => setHasConfirmedChain((bool) => !bool)} + aria-pressed={hasConfirmedChain} + aria-label="Confirm deployment chain" + style={{ borderWidth: 0, padding: 0 }} > {hasConfirmedChain && } @@ -524,6 +534,8 @@ export const ReviewAndDeploy: React.FC = ({ = ({ ] } onClick={() => setHasConfirmedRewards((bool) => !bool)} + aria-pressed={hasConfirmedRewards} + aria-label="Confirm rewards documentation" + style={{ borderWidth: 0, padding: 0 }} > {hasConfirmedRewards && } @@ -556,6 +571,8 @@ export const ReviewAndDeploy: React.FC = ({ = ({ ] } onClick={() => setHasConfirmedFastDAO((bool) => !bool)} + aria-pressed={hasConfirmedFastDAO} + aria-label="Confirm fast DAO timings" + style={{ borderWidth: 0, padding: 0 }} > {hasConfirmedFastDAO && } diff --git a/packages/create-proposal-ui/src/components/TransactionForm/AddArtwork/AddArtworkForm.tsx b/packages/create-proposal-ui/src/components/TransactionForm/AddArtwork/AddArtworkForm.tsx index bc4366aee..750ea96b8 100644 --- a/packages/create-proposal-ui/src/components/TransactionForm/AddArtwork/AddArtworkForm.tsx +++ b/packages/create-proposal-ui/src/components/TransactionForm/AddArtwork/AddArtworkForm.tsx @@ -132,12 +132,17 @@ export const AddArtworkForm: React.FC = ({ {!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..c66b595d2 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,15 @@ export const PauseAuctionsForm: React.FC = () => { )} setReduceDelay((bool) => !bool)} + aria-pressed={reduceDelay} + aria-label="Reduce voting delay and period" + style={{ borderWidth: 0, padding: 0 }} > {reduceDelay && } 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/ui/src/Fields/Radio.tsx b/packages/ui/src/Fields/Radio.tsx index 58573bfe0..fbd3e2845 100644 --- a/packages/ui/src/Fields/Radio.tsx +++ b/packages/ui/src/Fields/Radio.tsx @@ -31,6 +31,8 @@ export function Radio({ {options.map((option) => ( ({ ] } onClick={() => handleSelection(option.value)} + aria-pressed={value !== undefined && option.value === value} + style={{ borderWidth: 0, padding: 0 }} > {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 && } From f201afae490aa15e4ca43cff80a8d4f41fed60b9 Mon Sep 17 00:00:00 2001 From: dan13ram Date: Wed, 6 May 2026 16:21:10 +0530 Subject: [PATCH 03/10] fix: improve disabled button contrast across themes --- packages/zord/src/elements/Button.css.ts | 30 +++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/zord/src/elements/Button.css.ts b/packages/zord/src/elements/Button.css.ts index 4307852c6..a7cf5b51e 100644 --- a/packages/zord/src/elements/Button.css.ts +++ b/packages/zord/src/elements/Button.css.ts @@ -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, From d4a6e21a3bda52f6befc0c5472091024f1758b04 Mon Sep 17 00:00:00 2001 From: dan13ram Date: Wed, 6 May 2026 16:26:27 +0530 Subject: [PATCH 04/10] fix: keep create sidebar nav contrast consistent across themes --- .../CreateNavigation/NavSection.css.ts | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) 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, From 16b8554ec251788f2b2057bfa026f0451a1d4ba0 Mon Sep 17 00:00:00 2001 From: dan13ram Date: Wed, 6 May 2026 16:30:56 +0530 Subject: [PATCH 05/10] feat: add mobile sticky action bar for create dao forms --- apps/web/src/pages/create.tsx | 3 +- .../FormNavButtons/FormNavButtons.css.ts | 36 ++++ .../FormNavButtons/FormNavButtons.tsx | 187 +++++++++++++----- .../ReviewAndDeploy/ReviewAndDeploy.tsx | 30 ++- 4 files changed, 186 insertions(+), 70 deletions(-) diff --git a/apps/web/src/pages/create.tsx b/apps/web/src/pages/create.tsx index 8def3a02b..8cc94a661 100644 --- a/apps/web/src/pages/create.tsx +++ b/apps/web/src/pages/create.tsx @@ -32,6 +32,7 @@ const CreatePage: NextPageWithLayout = () => { 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: ( = ({ onAfterReset, }) => { 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 + } + + document.querySelector('form')?.requestSubmit() + } + return ( <> {showReset && ( @@ -53,61 +74,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/ReviewAndDeploy.tsx b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx index 03dbb2f12..bf343633f 100644 --- a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx +++ b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx @@ -490,7 +490,7 @@ export const ReviewAndDeploy: React.FC = ({ - [I have reviewed and acknowledge and agree to the{' '} + I have reviewed and acknowledge and agree to the{' '} = ({ > Nouns Builder Terms of Service - ] @@ -606,21 +605,20 @@ export const ReviewAndDeploy: React.FC = ({ {deploymentError} )} - - - - {`${isPendingTransaction ? 'Deploying' : 'Deploy'} Contracts (1 of 2)`} - - + + + {`${isPendingTransaction ? 'Deploying' : 'Deploy'} Contracts (1 of 2)`} + + ) : ( From e1b9c428121ae27a10594d47f724ac066c4b0930 Mon Sep 17 00:00:00 2001 From: dan13ram Date: Wed, 6 May 2026 17:36:19 +0530 Subject: [PATCH 06/10] fix: improve accessibility and remove invalid HTML patterns --- .../layouts/DefaultLayout/Nav.styles.css.ts | 9 +++++++ .../DefaultLayout/NavMenu/ChainMenu.tsx | 7 +++-- apps/web/src/styles/globals.css | 4 +-- .../AuctionSettingsForm.tsx | 1 - .../FormNavButtons/FormNavButtons.tsx | 11 ++++++-- .../ReviewAndDeploy/ReviewAndDeploy.css.ts | 1 + .../ReviewAndDeploy/ReviewAndDeploy.tsx | 6 +---- .../ReviewAndDeploy/ReviewSection.css.ts | 5 ---- .../Migration/PauseAuctionsForm.tsx | 1 - .../ReplaceArtwork/ReplaceArtworkForm.css.ts | 1 + packages/ui/src/Fields/Radio.tsx | 1 - packages/ui/src/Fields/styles.css.ts | 1 + .../SingleImageUpload/SingleImageUpload.tsx | 26 +++++++++---------- .../SingleMediaUpload/SingleMediaUpload.tsx | 26 +++++++++---------- packages/zord/src/components/PopUp.tsx | 4 ++- 15 files changed, 56 insertions(+), 48 deletions(-) diff --git a/apps/web/src/layouts/DefaultLayout/Nav.styles.css.ts b/apps/web/src/layouts/DefaultLayout/Nav.styles.css.ts index 95d196159..d9458a64e 100644 --- a/apps/web/src/layouts/DefaultLayout/Nav.styles.css.ts +++ b/apps/web/src/layouts/DefaultLayout/Nav.styles.css.ts @@ -273,6 +273,14 @@ export const chainPopUpButton = style({ }, }) +export const chainPopUpItem = style({ + border: 0, + width: '100%', + textAlign: 'left', + font: 'inherit', + appearance: 'none', +}) + export const themeToggleButton = style([ atoms({ borderStyle: 'solid', @@ -318,6 +326,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 fec20e974..674402f15 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'} @@ -187,7 +188,6 @@ export const ChainMenu: React.FC = ({ mb="x2" align={'center'} justify={'center'} - style={{ borderRadius: '8px' }} > {`Switch to ${selectedChain.name}`} @@ -197,7 +197,7 @@ export const ChainMenu: React.FC = ({ as="button" type="button" key={chain.id} - className={chainPopUpButton} + className={[chainPopUpButton, chainPopUpItem]} borderRadius="normal" onClick={() => onChainChange(chain.id)} cursor={ @@ -214,7 +214,6 @@ export const ChainMenu: React.FC = ({ justify={'space-between'} disabled={hasNetwork && !isSelectedChain(chain.id)} aria-current={selectedChain.id === chain.id ? 'true' : undefined} - style={{ border: 0, width: '100%', textAlign: 'left' }} > diff --git a/apps/web/src/styles/globals.css b/apps/web/src/styles/globals.css index e03dd548c..dadf04834 100644 --- a/apps/web/src/styles/globals.css +++ b/apps/web/src/styles/globals.css @@ -44,7 +44,7 @@ body { --flatpickr-selected-bg: #000; --flatpickr-selected-text: #fff; --flatpickr-backdrop-shadow: 0 12px 28px rgba(0, 0, 0, 0.15); - --focus-ring-color: #0085ff; + --focus-ring-color: #0085ff; /* vars.color.focusRing holds the canonical tokenized value; update both in sync */ --mde-border: #c8ccd0; --mde-header-bg: #f9f9f9; --mde-surface: #fff; @@ -71,7 +71,7 @@ html[data-theme-mode='dark'] { --flatpickr-selected-bg: #fff; --flatpickr-selected-text: #1f2024; --flatpickr-backdrop-shadow: 0 12px 28px rgba(0, 0, 0, 0.45); - --focus-ring-color: #0085ff; + --focus-ring-color: #0085ff; /* vars.color.focusRing holds the canonical tokenized value; update both in sync */ --mde-border: #3f4047; --mde-header-bg: #2a2b30; --mde-surface: #1f2024; diff --git a/packages/create-dao-ui/src/components/AuctionSettingsForm/AuctionSettingsForm.tsx b/packages/create-dao-ui/src/components/AuctionSettingsForm/AuctionSettingsForm.tsx index fb7315dbe..200f9711f 100644 --- a/packages/create-dao-ui/src/components/AuctionSettingsForm/AuctionSettingsForm.tsx +++ b/packages/create-dao-ui/src/components/AuctionSettingsForm/AuctionSettingsForm.tsx @@ -215,7 +215,6 @@ export const AuctionSettingsForm: React.FC = ({ title onClick={() => handleFastDAOToggle(formik)} aria-pressed={enableFastDAO} aria-label="Enable Fast DAO" - style={{ borderWidth: 0, padding: 0 }} > {enableFastDAO && } diff --git a/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.tsx b/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.tsx index 2e9b51d02..839b94f6a 100644 --- a/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.tsx +++ b/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.tsx @@ -23,6 +23,7 @@ interface FormNavButtonsProps { children?: React.ReactNode showReset?: boolean onAfterReset?: () => void + formId?: string } export const FormNavButtons: React.FC = ({ @@ -35,12 +36,13 @@ 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(() => { + React.useLayoutEffect(() => { setIsMounted(true) }, []) @@ -56,7 +58,12 @@ export const FormNavButtons: React.FC = ({ return } - document.querySelector('form')?.requestSubmit() + if (formId) { + ;(document.getElementById(formId) as HTMLFormElement)?.requestSubmit() + } else { + const form = document.querySelector('form') + if (form) (form as HTMLFormElement).requestSubmit() + } } return ( 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 bf343633f..b889588d3 100644 --- a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx +++ b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx @@ -484,13 +484,12 @@ export const ReviewAndDeploy: React.FC = ({ onClick={() => setHasConfirmedTerms((bool) => !bool)} aria-pressed={hasConfirmedTerms} aria-label="Confirm terms of service" - style={{ borderWidth: 0, padding: 0 }} > {hasConfirmedTerms && } - I have reviewed and acknowledge and agree to the{' '} + I have reviewed, acknowledge, and agree to the{' '} = ({ onClick={() => setHasConfirmedChain((bool) => !bool)} aria-pressed={hasConfirmedChain} aria-label="Confirm deployment chain" - style={{ borderWidth: 0, padding: 0 }} > {hasConfirmedChain && } @@ -545,7 +543,6 @@ export const ReviewAndDeploy: React.FC = ({ onClick={() => setHasConfirmedRewards((bool) => !bool)} aria-pressed={hasConfirmedRewards} aria-label="Confirm rewards documentation" - style={{ borderWidth: 0, padding: 0 }} > {hasConfirmedRewards && } @@ -582,7 +579,6 @@ export const ReviewAndDeploy: React.FC = ({ onClick={() => setHasConfirmedFastDAO((bool) => !bool)} aria-pressed={hasConfirmedFastDAO} aria-label="Confirm fast DAO timings" - style={{ borderWidth: 0, padding: 0 }} > {hasConfirmedFastDAO && } 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-proposal-ui/src/components/TransactionForm/Migration/PauseAuctionsForm.tsx b/packages/create-proposal-ui/src/components/TransactionForm/Migration/PauseAuctionsForm.tsx index c66b595d2..bc7b24807 100644 --- a/packages/create-proposal-ui/src/components/TransactionForm/Migration/PauseAuctionsForm.tsx +++ b/packages/create-proposal-ui/src/components/TransactionForm/Migration/PauseAuctionsForm.tsx @@ -114,7 +114,6 @@ export const PauseAuctionsForm: React.FC = () => { onClick={() => setReduceDelay((bool) => !bool)} aria-pressed={reduceDelay} aria-label="Reduce voting delay and period" - style={{ borderWidth: 0, padding: 0 }} > {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/ui/src/Fields/Radio.tsx b/packages/ui/src/Fields/Radio.tsx index fbd3e2845..3811b2d01 100644 --- a/packages/ui/src/Fields/Radio.tsx +++ b/packages/ui/src/Fields/Radio.tsx @@ -49,7 +49,6 @@ export function Radio({ } onClick={() => handleSelection(option.value)} aria-pressed={value !== undefined && option.value === value} - style={{ borderWidth: 0, padding: 0 }} > {option.label} diff --git a/packages/ui/src/Fields/styles.css.ts b/packages/ui/src/Fields/styles.css.ts index 77ef4ae04..92dd8a55f 100644 --- a/packages/ui/src/Fields/styles.css.ts +++ b/packages/ui/src/Fields/styles.css.ts @@ -348,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.tsx b/packages/ui/src/SingleImageUpload/SingleImageUpload.tsx index 797932b3c..2caaf2b8c 100644 --- a/packages/ui/src/SingleImageUpload/SingleImageUpload.tsx +++ b/packages/ui/src/SingleImageUpload/SingleImageUpload.tsx @@ -110,21 +110,21 @@ export const SingleImageUpload: React.FC = ({ )} - - { - handleFileUpload(event.currentTarget.files) - }} - /> + { + handleFileUpload(event.currentTarget.files) + }} + /> + {uploadArtworkError && ( diff --git a/packages/ui/src/SingleMediaUpload/SingleMediaUpload.tsx b/packages/ui/src/SingleMediaUpload/SingleMediaUpload.tsx index 401eb1c00..83962d61d 100644 --- a/packages/ui/src/SingleMediaUpload/SingleMediaUpload.tsx +++ b/packages/ui/src/SingleMediaUpload/SingleMediaUpload.tsx @@ -149,20 +149,20 @@ export const SingleMediaUpload: React.FC = ({ )} - - { - handleFileUpload(event.currentTarget.files) - }} - /> + + { + handleFileUpload(event.currentTarget.files) + }} + /> {helperText && !uploadMediaError && ( {helperText} )} diff --git a/packages/zord/src/components/PopUp.tsx b/packages/zord/src/components/PopUp.tsx index 5476628e2..952223529 100644 --- a/packages/zord/src/components/PopUp.tsx +++ b/packages/zord/src/components/PopUp.tsx @@ -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) @@ -99,7 +101,7 @@ export function PopUp({ role="button" tabIndex={0} aria-expanded={openState} - aria-haspopup="menu" + aria-haspopup={ariaHasPopup} onClick={(e: React.MouseEvent) => { e.stopPropagation() setOpenState(!openState) From b1f1c55802d383ae2dffb4be5dd6da8e7b1d9f1e Mon Sep 17 00:00:00 2001 From: dan13ram Date: Wed, 6 May 2026 18:12:43 +0530 Subject: [PATCH 07/10] fix: remove preview artwork and replace with static artwork metadata --- .../ReviewAndDeploy/PreviewArtwork.tsx | 70 ++++++------------- .../ReviewAndDeploy/ReviewAndDeploy.tsx | 12 ++-- .../ReviewAndDeploy/ReviewSection.tsx | 2 +- 3 files changed, 26 insertions(+), 58 deletions(-) diff --git a/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx b/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx index 36e359f9d..b8dc0b93b 100644 --- a/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx +++ b/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx @@ -1,62 +1,32 @@ -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 React from 'react' 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 - }, []) + const filesCount = React.useMemo(() => { + if (!ipfsUpload) return 0 + return Object.keys(ipfsUpload).length }, [ipfsUpload]) - const [isOpenModal, setIsOpenModal] = React.useState(false) + const traitCategoriesCount = React.useMemo(() => { + return orderedLayers?.length || 0 + }, [orderedLayers]) + + const totalTraitOptions = React.useMemo(() => { + if (!orderedLayers) return 0 + return orderedLayers.reduce((acc, layer) => { + return acc + (layer.properties?.length || 0) + }, 0) + }, [orderedLayers]) 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.tsx b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx index b889588d3..ae25eb6dd 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, @@ -295,7 +294,7 @@ export const ReviewAndDeploy: React.FC = ({ topics: deployEvent?.topics ?? [], data: deployEvent?.data ?? '0x', }) - } catch {} + } catch { } const deployedAddresses = parsedEvent?.args @@ -465,7 +464,6 @@ export const ReviewAndDeploy: React.FC = ({ } /> - @@ -478,7 +476,7 @@ export const ReviewAndDeploy: React.FC = ({ justify={'center'} className={ deployCheckboxStyleVariants[ - hasConfirmedTerms ? 'confirmed' : 'default' + hasConfirmedTerms ? 'confirmed' : 'default' ] } onClick={() => setHasConfirmedTerms((bool) => !bool)} @@ -511,7 +509,7 @@ export const ReviewAndDeploy: React.FC = ({ justify={'center'} className={ deployCheckboxStyleVariants[ - hasConfirmedChain ? 'confirmed' : 'default' + hasConfirmedChain ? 'confirmed' : 'default' ] } onClick={() => setHasConfirmedChain((bool) => !bool)} @@ -537,7 +535,7 @@ export const ReviewAndDeploy: React.FC = ({ justify={'center'} className={ deployCheckboxStyleVariants[ - hasConfirmedRewards ? 'confirmed' : 'default' + hasConfirmedRewards ? 'confirmed' : 'default' ] } onClick={() => setHasConfirmedRewards((bool) => !bool)} @@ -573,7 +571,7 @@ export const ReviewAndDeploy: React.FC = ({ justify={'center'} className={ deployCheckboxStyleVariants[ - hasConfirmedFastDAO ? 'confirmed' : 'default' + hasConfirmedFastDAO ? 'confirmed' : 'default' ] } onClick={() => setHasConfirmedFastDAO((bool) => !bool)} diff --git a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewSection.tsx b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewSection.tsx index 4ba2df7bd..2d59738a1 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 = { From 226585ae19d7fafc826c8c2471928954a766f70a Mon Sep 17 00:00:00 2001 From: dan13ram Date: Wed, 6 May 2026 18:47:51 +0530 Subject: [PATCH 08/10] fix: misc fixes for dark mode --- apps/web/src/modules/dashboard/Dashboard.tsx | 2 +- .../src/modules/explore/ExploreSortMenu.tsx | 2 ++ .../src/modules/explore/ExploreToolbar.tsx | 2 +- .../FormNavButtons/FormNavButtons.tsx | 2 +- .../ReviewAndDeploy/PreviewArtwork.tsx | 2 +- .../ReviewAndDeploy/ReviewAndDeploy.tsx | 10 +++--- .../ReviewAndDeploy/ReviewItem.css.ts | 2 +- .../src/components/DaoCard/DaoCard.css.ts | 32 ++++--------------- .../dao-ui/src/components/DaoCard/DaoCard.tsx | 1 + .../src/DropdownSelect/DropdownSelect.css.ts | 1 - .../ui/src/DropdownSelect/DropdownSelect.tsx | 15 +++++++-- packages/ui/src/Fields/Radio.tsx | 19 +++++++++-- .../SingleImageUpload/SingleImageUpload.tsx | 1 + .../SingleMediaUpload/SingleMediaUpload.tsx | 5 ++- packages/zord/src/components/PopUp.tsx | 17 +++++----- 15 files changed, 63 insertions(+), 50 deletions(-) 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/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/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.tsx b/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.tsx index 839b94f6a..6c77a7cbf 100644 --- a/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.tsx +++ b/packages/create-dao-ui/src/components/FormNavButtons/FormNavButtons.tsx @@ -42,7 +42,7 @@ export const FormNavButtons: React.FC = ({ const [isMounted, setIsMounted] = useState(false) const { resetForm } = useFormStore() - React.useLayoutEffect(() => { + React.useEffect(() => { setIsMounted(true) }, []) diff --git a/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx b/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx index b8dc0b93b..d19aacd92 100644 --- a/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx +++ b/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx @@ -23,7 +23,7 @@ export const PreviewArtwork: React.FC = () => { }, [orderedLayers]) return ( - + {filesCount} PNG files {traitCategoriesCount} trait categories {totalTraitOptions} total trait options diff --git a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx index ae25eb6dd..9fcf7c6c0 100644 --- a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx +++ b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewAndDeploy.tsx @@ -294,7 +294,7 @@ export const ReviewAndDeploy: React.FC = ({ topics: deployEvent?.topics ?? [], data: deployEvent?.data ?? '0x', }) - } catch { } + } catch {} const deployedAddresses = parsedEvent?.args @@ -476,7 +476,7 @@ export const ReviewAndDeploy: React.FC = ({ justify={'center'} className={ deployCheckboxStyleVariants[ - hasConfirmedTerms ? 'confirmed' : 'default' + hasConfirmedTerms ? 'confirmed' : 'default' ] } onClick={() => setHasConfirmedTerms((bool) => !bool)} @@ -509,7 +509,7 @@ export const ReviewAndDeploy: React.FC = ({ justify={'center'} className={ deployCheckboxStyleVariants[ - hasConfirmedChain ? 'confirmed' : 'default' + hasConfirmedChain ? 'confirmed' : 'default' ] } onClick={() => setHasConfirmedChain((bool) => !bool)} @@ -535,7 +535,7 @@ export const ReviewAndDeploy: React.FC = ({ justify={'center'} className={ deployCheckboxStyleVariants[ - hasConfirmedRewards ? 'confirmed' : 'default' + hasConfirmedRewards ? 'confirmed' : 'default' ] } onClick={() => setHasConfirmedRewards((bool) => !bool)} @@ -571,7 +571,7 @@ export const ReviewAndDeploy: React.FC = ({ justify={'center'} className={ deployCheckboxStyleVariants[ - hasConfirmedFastDAO ? 'confirmed' : 'default' + hasConfirmedFastDAO ? 'confirmed' : 'default' ] } onClick={() => setHasConfirmedFastDAO((bool) => !bool)} 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/dao-ui/src/components/DaoCard/DaoCard.css.ts b/packages/dao-ui/src/components/DaoCard/DaoCard.css.ts index 9974d2b59..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]) 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 3811b2d01..750664c0d 100644 --- a/packages/ui/src/Fields/Radio.tsx +++ b/packages/ui/src/Fields/Radio.tsx @@ -25,10 +25,23 @@ 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)} - aria-pressed={value !== undefined && option.value === 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/SingleImageUpload/SingleImageUpload.tsx b/packages/ui/src/SingleImageUpload/SingleImageUpload.tsx index 2caaf2b8c..9e0db58f6 100644 --- a/packages/ui/src/SingleImageUpload/SingleImageUpload.tsx +++ b/packages/ui/src/SingleImageUpload/SingleImageUpload.tsx @@ -118,6 +118,7 @@ export const SingleImageUpload: React.FC = ({ data-testid="file-upload" name="file" type="file" + accept={acceptableMIME.join(',')} ref={fileInputRef} multiple={false} onChange={(event) => { diff --git a/packages/ui/src/SingleMediaUpload/SingleMediaUpload.tsx b/packages/ui/src/SingleMediaUpload/SingleMediaUpload.tsx index 83962d61d..5c226fc31 100644 --- a/packages/ui/src/SingleMediaUpload/SingleMediaUpload.tsx +++ b/packages/ui/src/SingleMediaUpload/SingleMediaUpload.tsx @@ -103,7 +103,9 @@ export const SingleMediaUpload: React.FC = ({ return ( - + = ({ data-testid={`file-upload-${id}`} name="file" type="file" + accept={acceptableMIME.join(',')} ref={fileInputRef} multiple={false} onChange={(event) => { diff --git a/packages/zord/src/components/PopUp.tsx b/packages/zord/src/components/PopUp.tsx index 952223529..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 { @@ -98,13 +98,15 @@ export function PopUp({ <> {triggerRef === undefined && ( { e.stopPropagation() - setOpenState(!openState) + setOpenState((prev) => !prev) }} onKeyDown={(e: React.KeyboardEvent) => { if (e.key === 'Enter' || e.key === ' ') { @@ -113,19 +115,18 @@ export function PopUp({ setOpenState((prev) => !prev) } }} - ref={setTriggerElement} - className={[triggerClassName]} > {trigger || ( - + )} )} From ab76e7d12de0d82120ee412bf6cf22fd2be7c14f Mon Sep 17 00:00:00 2001 From: dan13ram Date: Thu, 7 May 2026 18:51:00 +0530 Subject: [PATCH 09/10] fix focus styling and related UI test regressions --- .../dashboard/SingleDaoSelector.css.ts | 2 +- .../src/modules/playground/PlaygroundPage.tsx | 2 +- .../src/components/AllBids/AllBids.tsx | 6 +++- .../src/components/AllBids/BidCard.tsx | 35 +++++++++++++------ .../auction-ui/src/components/Auction.css.ts | 6 ++++ .../SingleImageUpload.test.tsx | 9 +++-- .../ui/src/WalletIdentity/WalletIdentity.tsx | 17 ++++++++- 7 files changed, 60 insertions(+), 17 deletions(-) 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/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 ( - + = ({ 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 ? ( + + ) : ( + + )} { }) 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/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 } From 50c61f6d02e41d2911ca5f2faf81ba590248a868 Mon Sep 17 00:00:00 2001 From: dan13ram Date: Thu, 7 May 2026 22:50:07 +0530 Subject: [PATCH 10/10] fix: misc fixes to dark mode --- .../layouts/DefaultLayout/Nav.styles.css.ts | 6 +++++ .../DefaultLayout/NavMenu/ChainMenu.tsx | 9 +------- .../auction-ui/src/components/Auction.css.ts | 2 -- .../ReviewAndDeploy/PreviewArtwork.tsx | 23 ++++++------------- .../ReviewAndDeploy/ReviewSection.tsx | 9 ++++++++ 5 files changed, 23 insertions(+), 26 deletions(-) diff --git a/apps/web/src/layouts/DefaultLayout/Nav.styles.css.ts b/apps/web/src/layouts/DefaultLayout/Nav.styles.css.ts index d9458a64e..83b982fa9 100644 --- a/apps/web/src/layouts/DefaultLayout/Nav.styles.css.ts +++ b/apps/web/src/layouts/DefaultLayout/Nav.styles.css.ts @@ -279,6 +279,12 @@ export const chainPopUpItem = style({ textAlign: 'left', font: 'inherit', appearance: 'none', + selectors: { + '&:disabled': { + pointerEvents: 'auto', + cursor: 'not-allowed', + }, + }, }) export const themeToggleButton = style([ diff --git a/apps/web/src/layouts/DefaultLayout/NavMenu/ChainMenu.tsx b/apps/web/src/layouts/DefaultLayout/NavMenu/ChainMenu.tsx index 674402f15..11c641a71 100644 --- a/apps/web/src/layouts/DefaultLayout/NavMenu/ChainMenu.tsx +++ b/apps/web/src/layouts/DefaultLayout/NavMenu/ChainMenu.tsx @@ -200,20 +200,13 @@ export const ChainMenu: React.FC = ({ className={[chainPopUpButton, chainPopUpItem]} borderRadius="normal" onClick={() => 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 ? 'true' : undefined} + aria-current={selectedChain.id === chain.id ? 'location' : undefined} > diff --git a/packages/auction-ui/src/components/Auction.css.ts b/packages/auction-ui/src/components/Auction.css.ts index 10bafc8eb..eec0e5a07 100644 --- a/packages/auction-ui/src/components/Auction.css.ts +++ b/packages/auction-ui/src/components/Auction.css.ts @@ -202,7 +202,6 @@ export const bidInput = style([ }, '&:focus': { outline: `2px solid ${vars.color.focusRing}`, - outlineStyle: 'auto', }, }, }, @@ -231,7 +230,6 @@ export const bidCommentInput = style([ borderColor: vars.color.accent, backgroundColor: vars.color.background1, outline: `2px solid ${vars.color.focusRing}`, - outlineStyle: 'auto', }, }, }, diff --git a/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx b/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx index d19aacd92..114af18b6 100644 --- a/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx +++ b/packages/create-dao-ui/src/components/ReviewAndDeploy/PreviewArtwork.tsx @@ -1,26 +1,17 @@ import { Box, Flex } from '@buildeross/zord' -import React from 'react' import { useFormStore } from '../../stores' export const PreviewArtwork: React.FC = () => { const { ipfsUpload, orderedLayers } = useFormStore() - const filesCount = React.useMemo(() => { - if (!ipfsUpload) return 0 - return Object.keys(ipfsUpload).length - }, [ipfsUpload]) - - const traitCategoriesCount = React.useMemo(() => { - return orderedLayers?.length || 0 - }, [orderedLayers]) - - const totalTraitOptions = React.useMemo(() => { - if (!orderedLayers) return 0 - return orderedLayers.reduce((acc, layer) => { - return acc + (layer.properties?.length || 0) - }, 0) - }, [orderedLayers]) + 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 ( diff --git a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewSection.tsx b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewSection.tsx index 2d59738a1..ce7d09d48 100644 --- a/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewSection.tsx +++ b/packages/create-dao-ui/src/components/ReviewAndDeploy/ReviewSection.tsx @@ -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} >