diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 0d8613ee9..dc8ccae7d 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -764,7 +764,7 @@ "message": "Custom derivation path" }, "mnemonicInputLabel": { - "message": "Seed phrase" + "message": "Seed Phrase" }, "mnemonicInputWarning": { "message": "We don't store your seed phrase. Don't lose it!" diff --git a/public/_locales/en_GB/messages.json b/public/_locales/en_GB/messages.json index cdf963bfb..a9c1e9c8f 100644 --- a/public/_locales/en_GB/messages.json +++ b/public/_locales/en_GB/messages.json @@ -616,7 +616,7 @@ "message": "Custom derivation path" }, "mnemonicInputLabel": { - "message": "Seed phrase" + "message": "Seed Phrase" }, "passwordInputDescription": { "message": "That is NOT a wallet password.\nUsed for additional mnemonic derivation." diff --git a/src/app/pages/ImportAccount/constants.ts b/src/app/pages/ImportAccount/constants.ts index 198385fe7..7f27a0ad6 100644 --- a/src/app/pages/ImportAccount/constants.ts +++ b/src/app/pages/ImportAccount/constants.ts @@ -1,2050 +1 @@ -export const bip39WordList = `abandon -ability -able -about -above -absent -absorb -abstract -absurd -abuse -access -accident -account -accuse -achieve -acid -acoustic -acquire -across -act -action -actor -actress -actual -adapt -add -addict -address -adjust -admit -adult -advance -advice -aerobic -affair -afford -afraid -again -age -agent -agree -ahead -aim -air -airport -aisle -alarm -album -alcohol -alert -alien -all -alley -allow -almost -alone -alpha -already -also -alter -always -amateur -amazing -among -amount -amused -analyst -anchor -ancient -anger -angle -angry -animal -ankle -announce -annual -another -answer -antenna -antique -anxiety -any -apart -apology -appear -apple -approve -april -arch -arctic -area -arena -argue -arm -armed -armor -army -around -arrange -arrest -arrive -arrow -art -artefact -artist -artwork -ask -aspect -assault -asset -assist -assume -asthma -athlete -atom -attack -attend -attitude -attract -auction -audit -august -aunt -author -auto -autumn -average -avocado -avoid -awake -aware -away -awesome -awful -awkward -axis -baby -bachelor -bacon -badge -bag -balance -balcony -ball -bamboo -banana -banner -bar -barely -bargain -barrel -base -basic -basket -battle -beach -bean -beauty -because -become -beef -before -begin -behave -behind -believe -below -belt -bench -benefit -best -betray -better -between -beyond -bicycle -bid -bike -bind -biology -bird -birth -bitter -black -blade -blame -blanket -blast -bleak -bless -blind -blood -blossom -blouse -blue -blur -blush -board -boat -body -boil -bomb -bone -bonus -book -boost -border -boring -borrow -boss -bottom -bounce -box -boy -bracket -brain -brand -brass -brave -bread -breeze -brick -bridge -brief -bright -bring -brisk -broccoli -broken -bronze -broom -brother -brown -brush -bubble -buddy -budget -buffalo -build -bulb -bulk -bullet -bundle -bunker -burden -burger -burst -bus -business -busy -butter -buyer -buzz -cabbage -cabin -cable -cactus -cage -cake -call -calm -camera -camp -can -canal -cancel -candy -cannon -canoe -canvas -canyon -capable -capital -captain -car -carbon -card -cargo -carpet -carry -cart -case -cash -casino -castle -casual -cat -catalog -catch -category -cattle -caught -cause -caution -cave -ceiling -celery -cement -census -century -cereal -certain -chair -chalk -champion -change -chaos -chapter -charge -chase -chat -cheap -check -cheese -chef -cherry -chest -chicken -chief -child -chimney -choice -choose -chronic -chuckle -chunk -churn -cigar -cinnamon -circle -citizen -city -civil -claim -clap -clarify -claw -clay -clean -clerk -clever -click -client -cliff -climb -clinic -clip -clock -clog -close -cloth -cloud -clown -club -clump -cluster -clutch -coach -coast -coconut -code -coffee -coil -coin -collect -color -column -combine -come -comfort -comic -common -company -concert -conduct -confirm -congress -connect -consider -control -convince -cook -cool -copper -copy -coral -core -corn -correct -cost -cotton -couch -country -couple -course -cousin -cover -coyote -crack -cradle -craft -cram -crane -crash -crater -crawl -crazy -cream -credit -creek -crew -cricket -crime -crisp -critic -crop -cross -crouch -crowd -crucial -cruel -cruise -crumble -crunch -crush -cry -crystal -cube -culture -cup -cupboard -curious -current -curtain -curve -cushion -custom -cute -cycle -dad -damage -damp -dance -danger -daring -dash -daughter -dawn -day -deal -debate -debris -decade -december -decide -decline -decorate -decrease -deer -defense -define -defy -degree -delay -deliver -demand -demise -denial -dentist -deny -depart -depend -deposit -depth -deputy -derive -describe -desert -design -desk -despair -destroy -detail -detect -develop -device -devote -diagram -dial -diamond -diary -dice -diesel -diet -differ -digital -dignity -dilemma -dinner -dinosaur -direct -dirt -disagree -discover -disease -dish -dismiss -disorder -display -distance -divert -divide -divorce -dizzy -doctor -document -dog -doll -dolphin -domain -donate -donkey -donor -door -dose -double -dove -draft -dragon -drama -drastic -draw -dream -dress -drift -drill -drink -drip -drive -drop -drum -dry -duck -dumb -dune -during -dust -dutch -duty -dwarf -dynamic -eager -eagle -early -earn -earth -easily -east -easy -echo -ecology -economy -edge -edit -educate -effort -egg -eight -either -elbow -elder -electric -elegant -element -elephant -elevator -elite -else -embark -embody -embrace -emerge -emotion -employ -empower -empty -enable -enact -end -endless -endorse -enemy -energy -enforce -engage -engine -enhance -enjoy -enlist -enough -enrich -enroll -ensure -enter -entire -entry -envelope -episode -equal -equip -era -erase -erode -erosion -error -erupt -escape -essay -essence -estate -eternal -ethics -evidence -evil -evoke -evolve -exact -example -excess -exchange -excite -exclude -excuse -execute -exercise -exhaust -exhibit -exile -exist -exit -exotic -expand -expect -expire -explain -expose -express -extend -extra -eye -eyebrow -fabric -face -faculty -fade -faint -faith -fall -false -fame -family -famous -fan -fancy -fantasy -farm -fashion -fat -fatal -father -fatigue -fault -favorite -feature -february -federal -fee -feed -feel -female -fence -festival -fetch -fever -few -fiber -fiction -field -figure -file -film -filter -final -find -fine -finger -finish -fire -firm -first -fiscal -fish -fit -fitness -fix -flag -flame -flash -flat -flavor -flee -flight -flip -float -flock -floor -flower -fluid -flush -fly -foam -focus -fog -foil -fold -follow -food -foot -force -forest -forget -fork -fortune -forum -forward -fossil -foster -found -fox -fragile -frame -frequent -fresh -friend -fringe -frog -front -frost -frown -frozen -fruit -fuel -fun -funny -furnace -fury -future -gadget -gain -galaxy -gallery -game -gap -garage -garbage -garden -garlic -garment -gas -gasp -gate -gather -gauge -gaze -general -genius -genre -gentle -genuine -gesture -ghost -giant -gift -giggle -ginger -giraffe -girl -give -glad -glance -glare -glass -glide -glimpse -globe -gloom -glory -glove -glow -glue -goat -goddess -gold -good -goose -gorilla -gospel -gossip -govern -gown -grab -grace -grain -grant -grape -grass -gravity -great -green -grid -grief -grit -grocery -group -grow -grunt -guard -guess -guide -guilt -guitar -gun -gym -habit -hair -half -hammer -hamster -hand -happy -harbor -hard -harsh -harvest -hat -have -hawk -hazard -head -health -heart -heavy -hedgehog -height -hello -helmet -help -hen -hero -hidden -high -hill -hint -hip -hire -history -hobby -hockey -hold -hole -holiday -hollow -home -honey -hood -hope -horn -horror -horse -hospital -host -hotel -hour -hover -hub -huge -human -humble -humor -hundred -hungry -hunt -hurdle -hurry -hurt -husband -hybrid -ice -icon -idea -identify -idle -ignore -ill -illegal -illness -image -imitate -immense -immune -impact -impose -improve -impulse -inch -include -income -increase -index -indicate -indoor -industry -infant -inflict -inform -inhale -inherit -initial -inject -injury -inmate -inner -innocent -input -inquiry -insane -insect -inside -inspire -install -intact -interest -into -invest -invite -involve -iron -island -isolate -issue -item -ivory -jacket -jaguar -jar -jazz -jealous -jeans -jelly -jewel -job -join -joke -journey -joy -judge -juice -jump -jungle -junior -junk -just -kangaroo -keen -keep -ketchup -key -kick -kid -kidney -kind -kingdom -kiss -kit -kitchen -kite -kitten -kiwi -knee -knife -knock -know -lab -label -labor -ladder -lady -lake -lamp -language -laptop -large -later -latin -laugh -laundry -lava -law -lawn -lawsuit -layer -lazy -leader -leaf -learn -leave -lecture -left -leg -legal -legend -leisure -lemon -lend -length -lens -leopard -lesson -letter -level -liar -liberty -library -license -life -lift -light -like -limb -limit -link -lion -liquid -list -little -live -lizard -load -loan -lobster -local -lock -logic -lonely -long -loop -lottery -loud -lounge -love -loyal -lucky -luggage -lumber -lunar -lunch -luxury -lyrics -machine -mad -magic -magnet -maid -mail -main -major -make -mammal -man -manage -mandate -mango -mansion -manual -maple -marble -march -margin -marine -market -marriage -mask -mass -master -match -material -math -matrix -matter -maximum -maze -meadow -mean -measure -meat -mechanic -medal -media -melody -melt -member -memory -mention -menu -mercy -merge -merit -merry -mesh -message -metal -method -middle -midnight -milk -million -mimic -mind -minimum -minor -minute -miracle -mirror -misery -miss -mistake -mix -mixed -mixture -mobile -model -modify -mom -moment -monitor -monkey -monster -month -moon -moral -more -morning -mosquito -mother -motion -motor -mountain -mouse -move -movie -much -muffin -mule -multiply -muscle -museum -mushroom -music -must -mutual -myself -mystery -myth -naive -name -napkin -narrow -nasty -nation -nature -near -neck -need -negative -neglect -neither -nephew -nerve -nest -net -network -neutral -never -news -next -nice -night -noble -noise -nominee -noodle -normal -north -nose -notable -note -nothing -notice -novel -now -nuclear -number -nurse -nut -oak -obey -object -oblige -obscure -observe -obtain -obvious -occur -ocean -october -odor -off -offer -office -often -oil -okay -old -olive -olympic -omit -once -one -onion -online -only -open -opera -opinion -oppose -option -orange -orbit -orchard -order -ordinary -organ -orient -original -orphan -ostrich -other -outdoor -outer -output -outside -oval -oven -over -own -owner -oxygen -oyster -ozone -pact -paddle -page -pair -palace -palm -panda -panel -panic -panther -paper -parade -parent -park -parrot -party -pass -patch -path -patient -patrol -pattern -pause -pave -payment -peace -peanut -pear -peasant -pelican -pen -penalty -pencil -people -pepper -perfect -permit -person -pet -phone -photo -phrase -physical -piano -picnic -picture -piece -pig -pigeon -pill -pilot -pink -pioneer -pipe -pistol -pitch -pizza -place -planet -plastic -plate -play -please -pledge -pluck -plug -plunge -poem -poet -point -polar -pole -police -pond -pony -pool -popular -portion -position -possible -post -potato -pottery -poverty -powder -power -practice -praise -predict -prefer -prepare -present -pretty -prevent -price -pride -primary -print -priority -prison -private -prize -problem -process -produce -profit -program -project -promote -proof -property -prosper -protect -proud -provide -public -pudding -pull -pulp -pulse -pumpkin -punch -pupil -puppy -purchase -purity -purpose -purse -push -put -puzzle -pyramid -quality -quantum -quarter -question -quick -quit -quiz -quote -rabbit -raccoon -race -rack -radar -radio -rail -rain -raise -rally -ramp -ranch -random -range -rapid -rare -rate -rather -raven -raw -razor -ready -real -reason -rebel -rebuild -recall -receive -recipe -record -recycle -reduce -reflect -reform -refuse -region -regret -regular -reject -relax -release -relief -rely -remain -remember -remind -remove -render -renew -rent -reopen -repair -repeat -replace -report -require -rescue -resemble -resist -resource -response -result -retire -retreat -return -reunion -reveal -review -reward -rhythm -rib -ribbon -rice -rich -ride -ridge -rifle -right -rigid -ring -riot -ripple -risk -ritual -rival -river -road -roast -robot -robust -rocket -romance -roof -rookie -room -rose -rotate -rough -round -route -royal -rubber -rude -rug -rule -run -runway -rural -sad -saddle -sadness -safe -sail -salad -salmon -salon -salt -salute -same -sample -sand -satisfy -satoshi -sauce -sausage -save -say -scale -scan -scare -scatter -scene -scheme -school -science -scissors -scorpion -scout -scrap -screen -script -scrub -sea -search -season -seat -second -secret -section -security -seed -seek -segment -select -sell -seminar -senior -sense -sentence -series -service -session -settle -setup -seven -shadow -shaft -shallow -share -shed -shell -sheriff -shield -shift -shine -ship -shiver -shock -shoe -shoot -shop -short -shoulder -shove -shrimp -shrug -shuffle -shy -sibling -sick -side -siege -sight -sign -silent -silk -silly -silver -similar -simple -since -sing -siren -sister -situate -six -size -skate -sketch -ski -skill -skin -skirt -skull -slab -slam -sleep -slender -slice -slide -slight -slim -slogan -slot -slow -slush -small -smart -smile -smoke -smooth -snack -snake -snap -sniff -snow -soap -soccer -social -sock -soda -soft -solar -soldier -solid -solution -solve -someone -song -soon -sorry -sort -soul -sound -soup -source -south -space -spare -spatial -spawn -speak -special -speed -spell -spend -sphere -spice -spider -spike -spin -spirit -split -spoil -sponsor -spoon -sport -spot -spray -spread -spring -spy -square -squeeze -squirrel -stable -stadium -staff -stage -stairs -stamp -stand -start -state -stay -steak -steel -stem -step -stereo -stick -still -sting -stock -stomach -stone -stool -story -stove -strategy -street -strike -strong -struggle -student -stuff -stumble -style -subject -submit -subway -success -such -sudden -suffer -sugar -suggest -suit -summer -sun -sunny -sunset -super -supply -supreme -sure -surface -surge -surprise -surround -survey -suspect -sustain -swallow -swamp -swap -swarm -swear -sweet -swift -swim -swing -switch -sword -symbol -symptom -syrup -system -table -tackle -tag -tail -talent -talk -tank -tape -target -task -taste -tattoo -taxi -teach -team -tell -ten -tenant -tennis -tent -term -test -text -thank -that -theme -then -theory -there -they -thing -this -thought -three -thrive -throw -thumb -thunder -ticket -tide -tiger -tilt -timber -time -tiny -tip -tired -tissue -title -toast -tobacco -today -toddler -toe -together -toilet -token -tomato -tomorrow -tone -tongue -tonight -tool -tooth -top -topic -topple -torch -tornado -tortoise -toss -total -tourist -toward -tower -town -toy -track -trade -traffic -tragic -train -transfer -trap -trash -travel -tray -treat -tree -trend -trial -tribe -trick -trigger -trim -trip -trophy -trouble -truck -true -truly -trumpet -trust -truth -try -tube -tuition -tumble -tuna -tunnel -turkey -turn -turtle -twelve -twenty -twice -twin -twist -two -type -typical -ugly -umbrella -unable -unaware -uncle -uncover -under -undo -unfair -unfold -unhappy -uniform -unique -unit -universe -unknown -unlock -until -unusual -unveil -update -upgrade -uphold -upon -upper -upset -urban -urge -usage -use -used -useful -useless -usual -utility -vacant -vacuum -vague -valid -valley -valve -van -vanish -vapor -various -vast -vault -vehicle -velvet -vendor -venture -venue -verb -verify -version -very -vessel -veteran -viable -vibrant -vicious -victory -video -view -village -vintage -violin -virtual -virus -visa -visit -visual -vital -vivid -vocal -voice -void -volcano -volume -vote -voyage -wage -wagon -wait -walk -wall -walnut -want -warfare -warm -warrior -wash -wasp -waste -water -wave -way -wealth -weapon -wear -weasel -weather -web -wedding -weekend -weird -welcome -west -wet -whale -what -wheat -wheel -when -where -whip -whisper -wide -width -wife -wild -will -win -window -wine -wing -wink -winner -winter -wire -wisdom -wise -wish -witness -wolf -woman -wonder -wood -wool -word -work -world -worry -worth -wrap -wreck -wrestle -wrist -write -wrong -yard -year -yellow -you -young -youth -zebra -zero -zone -zoo`.split(/\r?\n/); - export const defaultNumberOfWords = 12; diff --git a/src/app/templates/SeedPhraseInput/SeedLengthSelect.tsx b/src/app/templates/SeedPhraseInput/SeedLengthSelect.tsx index e2ee18b94..81bd142f0 100644 --- a/src/app/templates/SeedPhraseInput/SeedLengthSelect.tsx +++ b/src/app/templates/SeedPhraseInput/SeedLengthSelect.tsx @@ -1,6 +1,6 @@ import React, { FC, useCallback, useEffect, useRef, useState } from 'react'; -import './seedLength.css'; +import './seedLength.module.css'; import classNames from 'clsx'; diff --git a/src/app/templates/SeedPhraseInput/SeedWordInput.tsx b/src/app/templates/SeedPhraseInput/SeedWordInput.tsx index 6b457e98e..f873dfadc 100644 --- a/src/app/templates/SeedPhraseInput/SeedWordInput.tsx +++ b/src/app/templates/SeedPhraseInput/SeedWordInput.tsx @@ -1,9 +1,9 @@ import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import bip39WordList from 'bip39/src/wordlists/english.json'; import clsx from 'clsx'; import { FormField, FormFieldElement, FORM_FIELD_CLASS_NAME } from 'app/atoms/FormField'; -import { bip39WordList } from 'app/pages/ImportAccount/constants'; import type { TestIDProperty } from 'lib/analytics'; import { t } from 'lib/i18n'; @@ -33,7 +33,7 @@ export const SeedWordInput: FC = ({ }) => { const inputRef = useRef(null); const isError = submitted ? !value : false; - const [onBlur, setOnBlur] = useState(true); + const [isBlur, setIsBlur] = useState(true); const errorCheckRef = useRef(undefined); const [showAutocomplete, setShowAutocomplete] = useState(false); @@ -48,22 +48,22 @@ export const SeedWordInput: FC = ({ ); useEffect(() => { - if (value && !bip39WordList.includes(value) && onBlur) { + if (value && !bip39WordList.includes(value) && isBlur) { setWordSpellingError(t('mnemonicWordsError')); errorCheckRef.current = true; } else { errorCheckRef.current = undefined; setWordSpellingError(''); } - }, [value, onBlur, errorCheckRef, setWordSpellingError]); + }, [value, isBlur, errorCheckRef, setWordSpellingError]); useEffect(() => { - if (!onBlur && value && value.length > 1) { + if (!isBlur && value && value.length > 1) { setShowAutocomplete(true); } else { setShowAutocomplete(false); } - }, [showAutocomplete, value, onBlur]); + }, [showAutocomplete, value, isBlur]); const autocompleteVariants = useMemo( () => (value ? bip39WordList.filter(word => word.startsWith(value)) : null), @@ -77,7 +77,13 @@ export const SeedWordInput: FC = ({ setWordSpellingError(''); inputRef.current.value = variant; } - setOnBlur(true); + setIsBlur(true); + }; + + const handleBlur = (e: React.FocusEvent) => { + if (e.relatedTarget === null) { + setIsBlur(true); + } }; return ( @@ -91,14 +97,9 @@ export const SeedWordInput: FC = ({ type="password" id={id.toString()} onChange={onChange} - // delay for ref update works properly - onBlur={e => { - if (e.relatedTarget === null) { - setOnBlur(true); - } - }} + onBlur={handleBlur} value={value} - onFocus={() => setOnBlur(false)} + onFocus={() => setIsBlur(false)} onPaste={handlePaste} revealRef={revealRef} onReveal={onReveal} @@ -116,17 +117,9 @@ export const SeedWordInput: FC = ({ 'absolute left-0 z-50 px-2 items-center top-18 shadow-lg flex flex-col' )} > - {autocompleteVariants?.map((variant, index) => ( -
-
diff --git a/src/app/templates/SeedPhraseInput/index.tsx b/src/app/templates/SeedPhraseInput/index.tsx index 22427aa90..5799f4932 100644 --- a/src/app/templates/SeedPhraseInput/index.tsx +++ b/src/app/templates/SeedPhraseInput/index.tsx @@ -1,11 +1,12 @@ import React, { FC, useCallback, useMemo, useState } from 'react'; import { validateMnemonic } from 'bip39'; +import bip39WordList from 'bip39/src/wordlists/english.json'; import classNames from 'clsx'; +import { FormFieldElement } from 'app/atoms/FormField'; import { formatMnemonic } from 'app/defaults'; import { useAppEnv } from 'app/env'; -import { bip39WordList } from 'app/pages/ImportAccount/constants'; import { TestIDProperty } from 'lib/analytics'; import { T, t } from 'lib/i18n'; import { clearClipboard } from 'lib/ui/utils'; @@ -28,8 +29,6 @@ interface SeedPhraseInputProps extends TestIDProperty { const defaultNumberOfWords = 12; -const checkWordExist = (word: string) => word !== ''; - export const SeedPhraseInput: FC = ({ isFirstAccount, submitted, @@ -56,13 +55,12 @@ export const SeedPhraseInput: FC = ({ let newSeedError = ''; const joinedDraftSeed = newDraftSeed.join(' '); - if (newDraftSeed.some(word => checkWordExist(word))) { + if (newDraftSeed.some(Boolean)) { if (newDraftSeed.some(word => word === '')) { - const availableWords = newDraftSeed.filter(word => checkWordExist(word)); - if (!availableWords.some(word => bip39WordList.includes(word))) { - newSeedError = t('mnemonicWordsAmountConstraint', [numberOfWords]) as string; - } else { + if (newDraftSeed.some(word => word !== '' && bip39WordList.includes(word))) { newSeedError = ''; + } else { + newSeedError = t('mnemonicWordsAmountConstraint', [numberOfWords]) as string; } } else if (!validateMnemonic(formatMnemonic(joinedDraftSeed))) { newSeedError = t('justValidPreGeneratedMnemonic'); @@ -187,16 +185,18 @@ export const SeedPhraseInput: FC = ({ {[...Array(numberOfWords).keys()].map(index => { const key = `import-seed-word-${index}`; + const handleChange = (event: React.ChangeEvent) => { + event.preventDefault(); + onSeedWordChange(index, event.target.value); + setWordSpellingError(''); + }; + return ( { - event.preventDefault(); - onSeedWordChange(index, event.target.value); - setWordSpellingError(''); - }} + onChange={handleChange} revealRef={getRevealRef(index)} onReveal={() => onReveal(index)} value={draftSeed[index]} diff --git a/src/app/templates/SeedPhraseInput/seedLength.css b/src/app/templates/SeedPhraseInput/seedLength.module.css similarity index 100% rename from src/app/templates/SeedPhraseInput/seedLength.css rename to src/app/templates/SeedPhraseInput/seedLength.module.css diff --git a/tailwind.config.js b/tailwind.config.js index 228b3df31..2f8a889f1 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -293,30 +293,6 @@ module.exports = { extrabold: '800', black: '900' }, - height: theme => ({ - auto: 'auto', - ...theme('spacing'), - 2.25: '2.25rem', - 12: '3rem', - 18: '4.5rem', - 700: '700px', - full: '100%', - screen: '100vh' - }), - inset: { - '2px': '2px', - 0: '0', - 1: '0.25rem', - 2: '0.5rem', - 3: '0.75rem', - 4: '1rem', - 5: '1.25rem', - 8: '2rem', - 12: '3rem', - 18: '4.5rem', - '1/2': '50%', - auto: 'auto' - }, letterSpacing: { tighter: '-0.05em', tight: '-0.025em', @@ -674,6 +650,7 @@ module.exports = { inset: { '2px': '2px', '1/2': '50%', + 18: '4.5rem', }, space: (theme, { negative }) => ({ ...theme('spacing'),