vuetify.esm.js 819 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316
  1. /*!
  2. * Vuetify v3.7.6
  3. * Forged by John Leider
  4. * Released under the MIT License.
  5. */
  6. import { shallowRef, Fragment, reactive, computed, watchEffect, toRefs, capitalize, isVNode, Comment, unref, warn, getCurrentInstance as getCurrentInstance$1, ref, provide, inject as inject$1, defineComponent as defineComponent$1, camelize, h, createVNode, mergeProps, onBeforeUnmount, watch, readonly, onDeactivated, onActivated, onMounted, onScopeDispose, effectScope, toRaw, TransitionGroup, Transition, isRef, toRef, onBeforeMount, nextTick, withDirectives, resolveDirective, vShow, onUpdated, Text, resolveDynamicComponent, markRaw, Teleport, cloneVNode, createTextVNode, onUnmounted, onBeforeUpdate, withModifiers, toDisplayString, vModelText, resolveComponent, render } from 'vue';
  7. const IN_BROWSER = typeof window !== 'undefined';
  8. const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
  9. const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
  10. const SUPPORTS_EYE_DROPPER = IN_BROWSER && 'EyeDropper' in window;
  11. function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
  12. function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
  13. function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
  14. function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
  15. function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
  16. // Types
  17. function getNestedValue(obj, path, fallback) {
  18. const last = path.length - 1;
  19. if (last < 0) return obj === undefined ? fallback : obj;
  20. for (let i = 0; i < last; i++) {
  21. if (obj == null) {
  22. return fallback;
  23. }
  24. obj = obj[path[i]];
  25. }
  26. if (obj == null) return fallback;
  27. return obj[path[last]] === undefined ? fallback : obj[path[last]];
  28. }
  29. function deepEqual(a, b) {
  30. if (a === b) return true;
  31. if (a instanceof Date && b instanceof Date && a.getTime() !== b.getTime()) {
  32. // If the values are Date, compare them as timestamps
  33. return false;
  34. }
  35. if (a !== Object(a) || b !== Object(b)) {
  36. // If the values aren't objects, they were already checked for equality
  37. return false;
  38. }
  39. const props = Object.keys(a);
  40. if (props.length !== Object.keys(b).length) {
  41. // Different number of props, don't bother to check
  42. return false;
  43. }
  44. return props.every(p => deepEqual(a[p], b[p]));
  45. }
  46. function getObjectValueByPath(obj, path, fallback) {
  47. // credit: http://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key#comment55278413_6491621
  48. if (obj == null || !path || typeof path !== 'string') return fallback;
  49. if (obj[path] !== undefined) return obj[path];
  50. path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
  51. path = path.replace(/^\./, ''); // strip a leading dot
  52. return getNestedValue(obj, path.split('.'), fallback);
  53. }
  54. function getPropertyFromItem(item, property, fallback) {
  55. if (property === true) return item === undefined ? fallback : item;
  56. if (property == null || typeof property === 'boolean') return fallback;
  57. if (item !== Object(item)) {
  58. if (typeof property !== 'function') return fallback;
  59. const value = property(item, fallback);
  60. return typeof value === 'undefined' ? fallback : value;
  61. }
  62. if (typeof property === 'string') return getObjectValueByPath(item, property, fallback);
  63. if (Array.isArray(property)) return getNestedValue(item, property, fallback);
  64. if (typeof property !== 'function') return fallback;
  65. const value = property(item, fallback);
  66. return typeof value === 'undefined' ? fallback : value;
  67. }
  68. function createRange(length) {
  69. let start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  70. return Array.from({
  71. length
  72. }, (v, k) => start + k);
  73. }
  74. function convertToUnit(str) {
  75. let unit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'px';
  76. if (str == null || str === '') {
  77. return undefined;
  78. } else if (isNaN(+str)) {
  79. return String(str);
  80. } else if (!isFinite(+str)) {
  81. return undefined;
  82. } else {
  83. return `${Number(str)}${unit}`;
  84. }
  85. }
  86. function isObject(obj) {
  87. return obj !== null && typeof obj === 'object' && !Array.isArray(obj);
  88. }
  89. function isPlainObject(obj) {
  90. let proto;
  91. return obj !== null && typeof obj === 'object' && ((proto = Object.getPrototypeOf(obj)) === Object.prototype || proto === null);
  92. }
  93. function refElement(obj) {
  94. if (obj && '$el' in obj) {
  95. const el = obj.$el;
  96. if (el?.nodeType === Node.TEXT_NODE) {
  97. // Multi-root component, use the first element
  98. return el.nextElementSibling;
  99. }
  100. return el;
  101. }
  102. return obj;
  103. }
  104. // KeyboardEvent.keyCode aliases
  105. const keyCodes = Object.freeze({
  106. enter: 13,
  107. tab: 9,
  108. delete: 46,
  109. esc: 27,
  110. space: 32,
  111. up: 38,
  112. down: 40,
  113. left: 37,
  114. right: 39,
  115. end: 35,
  116. home: 36,
  117. del: 46,
  118. backspace: 8,
  119. insert: 45,
  120. pageup: 33,
  121. pagedown: 34,
  122. shift: 16
  123. });
  124. const keyValues = Object.freeze({
  125. enter: 'Enter',
  126. tab: 'Tab',
  127. delete: 'Delete',
  128. esc: 'Escape',
  129. space: 'Space',
  130. up: 'ArrowUp',
  131. down: 'ArrowDown',
  132. left: 'ArrowLeft',
  133. right: 'ArrowRight',
  134. end: 'End',
  135. home: 'Home',
  136. del: 'Delete',
  137. backspace: 'Backspace',
  138. insert: 'Insert',
  139. pageup: 'PageUp',
  140. pagedown: 'PageDown',
  141. shift: 'Shift'
  142. });
  143. function keys(o) {
  144. return Object.keys(o);
  145. }
  146. function has(obj, key) {
  147. return key.every(k => obj.hasOwnProperty(k));
  148. }
  149. // Array of keys
  150. function pick(obj, paths) {
  151. const found = {};
  152. const keys = new Set(Object.keys(obj));
  153. for (const path of paths) {
  154. if (keys.has(path)) {
  155. found[path] = obj[path];
  156. }
  157. }
  158. return found;
  159. }
  160. // Array of keys
  161. // Array of keys or RegExp to test keys against
  162. function pickWithRest(obj, paths, exclude) {
  163. const found = Object.create(null);
  164. const rest = Object.create(null);
  165. for (const key in obj) {
  166. if (paths.some(path => path instanceof RegExp ? path.test(key) : path === key) && !exclude?.some(path => path === key)) {
  167. found[key] = obj[key];
  168. } else {
  169. rest[key] = obj[key];
  170. }
  171. }
  172. return [found, rest];
  173. }
  174. function omit(obj, exclude) {
  175. const clone = {
  176. ...obj
  177. };
  178. exclude.forEach(prop => delete clone[prop]);
  179. return clone;
  180. }
  181. function only(obj, include) {
  182. const clone = {};
  183. include.forEach(prop => clone[prop] = obj[prop]);
  184. return clone;
  185. }
  186. const onRE = /^on[^a-z]/;
  187. const isOn = key => onRE.test(key);
  188. const bubblingEvents = ['onAfterscriptexecute', 'onAnimationcancel', 'onAnimationend', 'onAnimationiteration', 'onAnimationstart', 'onAuxclick', 'onBeforeinput', 'onBeforescriptexecute', 'onChange', 'onClick', 'onCompositionend', 'onCompositionstart', 'onCompositionupdate', 'onContextmenu', 'onCopy', 'onCut', 'onDblclick', 'onFocusin', 'onFocusout', 'onFullscreenchange', 'onFullscreenerror', 'onGesturechange', 'onGestureend', 'onGesturestart', 'onGotpointercapture', 'onInput', 'onKeydown', 'onKeypress', 'onKeyup', 'onLostpointercapture', 'onMousedown', 'onMousemove', 'onMouseout', 'onMouseover', 'onMouseup', 'onMousewheel', 'onPaste', 'onPointercancel', 'onPointerdown', 'onPointerenter', 'onPointerleave', 'onPointermove', 'onPointerout', 'onPointerover', 'onPointerup', 'onReset', 'onSelect', 'onSubmit', 'onTouchcancel', 'onTouchend', 'onTouchmove', 'onTouchstart', 'onTransitioncancel', 'onTransitionend', 'onTransitionrun', 'onTransitionstart', 'onWheel'];
  189. const compositionIgnoreKeys = ['ArrowUp', 'ArrowDown', 'ArrowRight', 'ArrowLeft', 'Enter', 'Escape', 'Tab', ' '];
  190. function isComposingIgnoreKey(e) {
  191. return e.isComposing && compositionIgnoreKeys.includes(e.key);
  192. }
  193. /**
  194. * Filter attributes that should be applied to
  195. * the root element of an input component. Remaining
  196. * attributes should be passed to the <input> element inside.
  197. */
  198. function filterInputAttrs(attrs) {
  199. const [events, props] = pickWithRest(attrs, [onRE]);
  200. const inputEvents = omit(events, bubblingEvents);
  201. const [rootAttrs, inputAttrs] = pickWithRest(props, ['class', 'style', 'id', /^data-/]);
  202. Object.assign(rootAttrs, events);
  203. Object.assign(inputAttrs, inputEvents);
  204. return [rootAttrs, inputAttrs];
  205. }
  206. function wrapInArray(v) {
  207. return v == null ? [] : Array.isArray(v) ? v : [v];
  208. }
  209. function debounce(fn, delay) {
  210. let timeoutId = 0;
  211. const wrap = function () {
  212. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  213. args[_key] = arguments[_key];
  214. }
  215. clearTimeout(timeoutId);
  216. timeoutId = setTimeout(() => fn(...args), unref(delay));
  217. };
  218. wrap.clear = () => {
  219. clearTimeout(timeoutId);
  220. };
  221. wrap.immediate = fn;
  222. return wrap;
  223. }
  224. function clamp(value) {
  225. let min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  226. let max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
  227. return Math.max(min, Math.min(max, value));
  228. }
  229. function getDecimals(value) {
  230. const trimmedStr = value.toString().trim();
  231. return trimmedStr.includes('.') ? trimmedStr.length - trimmedStr.indexOf('.') - 1 : 0;
  232. }
  233. function padEnd(str, length) {
  234. let char = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '0';
  235. return str + char.repeat(Math.max(0, length - str.length));
  236. }
  237. function padStart(str, length) {
  238. let char = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '0';
  239. return char.repeat(Math.max(0, length - str.length)) + str;
  240. }
  241. function chunk(str) {
  242. let size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
  243. const chunked = [];
  244. let index = 0;
  245. while (index < str.length) {
  246. chunked.push(str.substr(index, size));
  247. index += size;
  248. }
  249. return chunked;
  250. }
  251. function humanReadableFileSize(bytes) {
  252. let base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;
  253. if (bytes < base) {
  254. return `${bytes} B`;
  255. }
  256. const prefix = base === 1024 ? ['Ki', 'Mi', 'Gi'] : ['k', 'M', 'G'];
  257. let unit = -1;
  258. while (Math.abs(bytes) >= base && unit < prefix.length - 1) {
  259. bytes /= base;
  260. ++unit;
  261. }
  262. return `${bytes.toFixed(1)} ${prefix[unit]}B`;
  263. }
  264. function mergeDeep() {
  265. let source = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  266. let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  267. let arrayFn = arguments.length > 2 ? arguments[2] : undefined;
  268. const out = {};
  269. for (const key in source) {
  270. out[key] = source[key];
  271. }
  272. for (const key in target) {
  273. const sourceProperty = source[key];
  274. const targetProperty = target[key];
  275. // Only continue deep merging if
  276. // both properties are plain objects
  277. if (isPlainObject(sourceProperty) && isPlainObject(targetProperty)) {
  278. out[key] = mergeDeep(sourceProperty, targetProperty, arrayFn);
  279. continue;
  280. }
  281. if (arrayFn && Array.isArray(sourceProperty) && Array.isArray(targetProperty)) {
  282. out[key] = arrayFn(sourceProperty, targetProperty);
  283. continue;
  284. }
  285. out[key] = targetProperty;
  286. }
  287. return out;
  288. }
  289. function flattenFragments(nodes) {
  290. return nodes.map(node => {
  291. if (node.type === Fragment) {
  292. return flattenFragments(node.children);
  293. } else {
  294. return node;
  295. }
  296. }).flat();
  297. }
  298. function toKebabCase() {
  299. let str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  300. if (toKebabCase.cache.has(str)) return toKebabCase.cache.get(str);
  301. const kebab = str.replace(/[^a-z]/gi, '-').replace(/\B([A-Z])/g, '-$1').toLowerCase();
  302. toKebabCase.cache.set(str, kebab);
  303. return kebab;
  304. }
  305. toKebabCase.cache = new Map();
  306. function findChildrenWithProvide(key, vnode) {
  307. if (!vnode || typeof vnode !== 'object') return [];
  308. if (Array.isArray(vnode)) {
  309. return vnode.map(child => findChildrenWithProvide(key, child)).flat(1);
  310. } else if (vnode.suspense) {
  311. return findChildrenWithProvide(key, vnode.ssContent);
  312. } else if (Array.isArray(vnode.children)) {
  313. return vnode.children.map(child => findChildrenWithProvide(key, child)).flat(1);
  314. } else if (vnode.component) {
  315. if (Object.getOwnPropertySymbols(vnode.component.provides).includes(key)) {
  316. return [vnode.component];
  317. } else if (vnode.component.subTree) {
  318. return findChildrenWithProvide(key, vnode.component.subTree).flat(1);
  319. }
  320. }
  321. return [];
  322. }
  323. var _arr = /*#__PURE__*/new WeakMap();
  324. var _pointer = /*#__PURE__*/new WeakMap();
  325. class CircularBuffer {
  326. constructor(size) {
  327. _classPrivateFieldInitSpec(this, _arr, []);
  328. _classPrivateFieldInitSpec(this, _pointer, 0);
  329. this.size = size;
  330. }
  331. push(val) {
  332. _classPrivateFieldGet(_arr, this)[_classPrivateFieldGet(_pointer, this)] = val;
  333. _classPrivateFieldSet(_pointer, this, (_classPrivateFieldGet(_pointer, this) + 1) % this.size);
  334. }
  335. values() {
  336. return _classPrivateFieldGet(_arr, this).slice(_classPrivateFieldGet(_pointer, this)).concat(_classPrivateFieldGet(_arr, this).slice(0, _classPrivateFieldGet(_pointer, this)));
  337. }
  338. }
  339. function getEventCoordinates(e) {
  340. if ('touches' in e) {
  341. return {
  342. clientX: e.touches[0].clientX,
  343. clientY: e.touches[0].clientY
  344. };
  345. }
  346. return {
  347. clientX: e.clientX,
  348. clientY: e.clientY
  349. };
  350. }
  351. // Only allow a single return type
  352. /**
  353. * Convert a computed ref to a record of refs.
  354. * The getter function must always return an object with the same keys.
  355. */
  356. function destructComputed(getter) {
  357. const refs = reactive({});
  358. const base = computed(getter);
  359. watchEffect(() => {
  360. for (const key in base.value) {
  361. refs[key] = base.value[key];
  362. }
  363. }, {
  364. flush: 'sync'
  365. });
  366. return toRefs(refs);
  367. }
  368. /** Array.includes but value can be any type */
  369. function includes(arr, val) {
  370. return arr.includes(val);
  371. }
  372. function eventName(propName) {
  373. return propName[2].toLowerCase() + propName.slice(3);
  374. }
  375. const EventProp = () => [Function, Array];
  376. function hasEvent(props, name) {
  377. name = 'on' + capitalize(name);
  378. return !!(props[name] || props[`${name}Once`] || props[`${name}Capture`] || props[`${name}OnceCapture`] || props[`${name}CaptureOnce`]);
  379. }
  380. function callEvent(handler) {
  381. for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
  382. args[_key2 - 1] = arguments[_key2];
  383. }
  384. if (Array.isArray(handler)) {
  385. for (const h of handler) {
  386. h(...args);
  387. }
  388. } else if (typeof handler === 'function') {
  389. handler(...args);
  390. }
  391. }
  392. function focusableChildren(el) {
  393. let filterByTabIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  394. const targets = ['button', '[href]', 'input:not([type="hidden"])', 'select', 'textarea', '[tabindex]'].map(s => `${s}${filterByTabIndex ? ':not([tabindex="-1"])' : ''}:not([disabled])`).join(', ');
  395. return [...el.querySelectorAll(targets)];
  396. }
  397. function getNextElement(elements, location, condition) {
  398. let _el;
  399. let idx = elements.indexOf(document.activeElement);
  400. const inc = location === 'next' ? 1 : -1;
  401. do {
  402. idx += inc;
  403. _el = elements[idx];
  404. } while ((!_el || _el.offsetParent == null || !(condition?.(_el) ?? true)) && idx < elements.length && idx >= 0);
  405. return _el;
  406. }
  407. function focusChild(el, location) {
  408. const focusable = focusableChildren(el);
  409. if (!location) {
  410. if (el === document.activeElement || !el.contains(document.activeElement)) {
  411. focusable[0]?.focus();
  412. }
  413. } else if (location === 'first') {
  414. focusable[0]?.focus();
  415. } else if (location === 'last') {
  416. focusable.at(-1)?.focus();
  417. } else if (typeof location === 'number') {
  418. focusable[location]?.focus();
  419. } else {
  420. const _el = getNextElement(focusable, location);
  421. if (_el) _el.focus();else focusChild(el, location === 'next' ? 'first' : 'last');
  422. }
  423. }
  424. function isEmpty(val) {
  425. return val === null || val === undefined || typeof val === 'string' && val.trim() === '';
  426. }
  427. function noop() {}
  428. /** Returns null if the selector is not supported or we can't check */
  429. function matchesSelector(el, selector) {
  430. const supportsSelector = IN_BROWSER && typeof CSS !== 'undefined' && typeof CSS.supports !== 'undefined' && CSS.supports(`selector(${selector})`);
  431. if (!supportsSelector) return null;
  432. try {
  433. return !!el && el.matches(selector);
  434. } catch (err) {
  435. return null;
  436. }
  437. }
  438. function ensureValidVNode(vnodes) {
  439. return vnodes.some(child => {
  440. if (!isVNode(child)) return true;
  441. if (child.type === Comment) return false;
  442. return child.type !== Fragment || ensureValidVNode(child.children);
  443. }) ? vnodes : null;
  444. }
  445. function defer(timeout, cb) {
  446. if (!IN_BROWSER || timeout === 0) {
  447. cb();
  448. return () => {};
  449. }
  450. const timeoutId = window.setTimeout(cb, timeout);
  451. return () => window.clearTimeout(timeoutId);
  452. }
  453. function isClickInsideElement(event, targetDiv) {
  454. const mouseX = event.clientX;
  455. const mouseY = event.clientY;
  456. const divRect = targetDiv.getBoundingClientRect();
  457. const divLeft = divRect.left;
  458. const divTop = divRect.top;
  459. const divRight = divRect.right;
  460. const divBottom = divRect.bottom;
  461. return mouseX >= divLeft && mouseX <= divRight && mouseY >= divTop && mouseY <= divBottom;
  462. }
  463. function templateRef() {
  464. const el = shallowRef();
  465. const fn = target => {
  466. el.value = target;
  467. };
  468. Object.defineProperty(fn, 'value', {
  469. enumerable: true,
  470. get: () => el.value,
  471. set: val => el.value = val
  472. });
  473. Object.defineProperty(fn, 'el', {
  474. enumerable: true,
  475. get: () => refElement(el.value)
  476. });
  477. return fn;
  478. }
  479. function checkPrintable(e) {
  480. const isPrintableChar = e.key.length === 1;
  481. const noModifier = !e.ctrlKey && !e.metaKey && !e.altKey;
  482. return isPrintableChar && noModifier;
  483. }
  484. // Utilities
  485. const block = ['top', 'bottom'];
  486. const inline = ['start', 'end', 'left', 'right'];
  487. /** Parse a raw anchor string into an object */
  488. function parseAnchor(anchor, isRtl) {
  489. let [side, align] = anchor.split(' ');
  490. if (!align) {
  491. align = includes(block, side) ? 'start' : includes(inline, side) ? 'top' : 'center';
  492. }
  493. return {
  494. side: toPhysical(side, isRtl),
  495. align: toPhysical(align, isRtl)
  496. };
  497. }
  498. function toPhysical(str, isRtl) {
  499. if (str === 'start') return isRtl ? 'right' : 'left';
  500. if (str === 'end') return isRtl ? 'left' : 'right';
  501. return str;
  502. }
  503. function flipSide(anchor) {
  504. return {
  505. side: {
  506. center: 'center',
  507. top: 'bottom',
  508. bottom: 'top',
  509. left: 'right',
  510. right: 'left'
  511. }[anchor.side],
  512. align: anchor.align
  513. };
  514. }
  515. function flipAlign(anchor) {
  516. return {
  517. side: anchor.side,
  518. align: {
  519. center: 'center',
  520. top: 'bottom',
  521. bottom: 'top',
  522. left: 'right',
  523. right: 'left'
  524. }[anchor.align]
  525. };
  526. }
  527. function flipCorner(anchor) {
  528. return {
  529. side: anchor.align,
  530. align: anchor.side
  531. };
  532. }
  533. function getAxis(anchor) {
  534. return includes(block, anchor.side) ? 'y' : 'x';
  535. }
  536. class Box {
  537. constructor(_ref) {
  538. let {
  539. x,
  540. y,
  541. width,
  542. height
  543. } = _ref;
  544. this.x = x;
  545. this.y = y;
  546. this.width = width;
  547. this.height = height;
  548. }
  549. get top() {
  550. return this.y;
  551. }
  552. get bottom() {
  553. return this.y + this.height;
  554. }
  555. get left() {
  556. return this.x;
  557. }
  558. get right() {
  559. return this.x + this.width;
  560. }
  561. }
  562. function getOverflow(a, b) {
  563. return {
  564. x: {
  565. before: Math.max(0, b.left - a.left),
  566. after: Math.max(0, a.right - b.right)
  567. },
  568. y: {
  569. before: Math.max(0, b.top - a.top),
  570. after: Math.max(0, a.bottom - b.bottom)
  571. }
  572. };
  573. }
  574. function getTargetBox(target) {
  575. if (Array.isArray(target)) {
  576. return new Box({
  577. x: target[0],
  578. y: target[1],
  579. width: 0,
  580. height: 0
  581. });
  582. } else {
  583. return target.getBoundingClientRect();
  584. }
  585. }
  586. // Utilities
  587. /** @see https://stackoverflow.com/a/57876601/2074736 */
  588. function nullifyTransforms(el) {
  589. const rect = el.getBoundingClientRect();
  590. const style = getComputedStyle(el);
  591. const tx = style.transform;
  592. if (tx) {
  593. let ta, sx, sy, dx, dy;
  594. if (tx.startsWith('matrix3d(')) {
  595. ta = tx.slice(9, -1).split(/, /);
  596. sx = +ta[0];
  597. sy = +ta[5];
  598. dx = +ta[12];
  599. dy = +ta[13];
  600. } else if (tx.startsWith('matrix(')) {
  601. ta = tx.slice(7, -1).split(/, /);
  602. sx = +ta[0];
  603. sy = +ta[3];
  604. dx = +ta[4];
  605. dy = +ta[5];
  606. } else {
  607. return new Box(rect);
  608. }
  609. const to = style.transformOrigin;
  610. const x = rect.x - dx - (1 - sx) * parseFloat(to);
  611. const y = rect.y - dy - (1 - sy) * parseFloat(to.slice(to.indexOf(' ') + 1));
  612. const w = sx ? rect.width / sx : el.offsetWidth + 1;
  613. const h = sy ? rect.height / sy : el.offsetHeight + 1;
  614. return new Box({
  615. x,
  616. y,
  617. width: w,
  618. height: h
  619. });
  620. } else {
  621. return new Box(rect);
  622. }
  623. }
  624. function animate(el, keyframes, options) {
  625. if (typeof el.animate === 'undefined') return {
  626. finished: Promise.resolve()
  627. };
  628. let animation;
  629. try {
  630. animation = el.animate(keyframes, options);
  631. } catch (err) {
  632. return {
  633. finished: Promise.resolve()
  634. };
  635. }
  636. if (typeof animation.finished === 'undefined') {
  637. animation.finished = new Promise(resolve => {
  638. animation.onfinish = () => {
  639. resolve(animation);
  640. };
  641. });
  642. }
  643. return animation;
  644. }
  645. // Utilities
  646. const handlers = new WeakMap();
  647. function bindProps(el, props) {
  648. Object.keys(props).forEach(k => {
  649. if (isOn(k)) {
  650. const name = eventName(k);
  651. const handler = handlers.get(el);
  652. if (props[k] == null) {
  653. handler?.forEach(v => {
  654. const [n, fn] = v;
  655. if (n === name) {
  656. el.removeEventListener(name, fn);
  657. handler.delete(v);
  658. }
  659. });
  660. } else if (!handler || ![...handler]?.some(v => v[0] === name && v[1] === props[k])) {
  661. el.addEventListener(name, props[k]);
  662. const _handler = handler || new Set();
  663. _handler.add([name, props[k]]);
  664. if (!handlers.has(el)) handlers.set(el, _handler);
  665. }
  666. } else {
  667. if (props[k] == null) {
  668. el.removeAttribute(k);
  669. } else {
  670. el.setAttribute(k, props[k]);
  671. }
  672. }
  673. });
  674. }
  675. function unbindProps(el, props) {
  676. Object.keys(props).forEach(k => {
  677. if (isOn(k)) {
  678. const name = eventName(k);
  679. const handler = handlers.get(el);
  680. handler?.forEach(v => {
  681. const [n, fn] = v;
  682. if (n === name) {
  683. el.removeEventListener(name, fn);
  684. handler.delete(v);
  685. }
  686. });
  687. } else {
  688. el.removeAttribute(k);
  689. }
  690. });
  691. }
  692. /**
  693. * WCAG 3.0 APCA perceptual contrast algorithm from https://github.com/Myndex/SAPC-APCA
  694. * @licence https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
  695. * @see https://www.w3.org/WAI/GL/task-forces/silver/wiki/Visual_Contrast_of_Text_Subgroup
  696. */
  697. // Types
  698. // MAGICAL NUMBERS
  699. // sRGB Conversion to Relative Luminance (Y)
  700. // Transfer Curve (aka "Gamma") for sRGB linearization
  701. // Simple power curve vs piecewise described in docs
  702. // Essentially, 2.4 best models actual display
  703. // characteristics in combination with the total method
  704. const mainTRC = 2.4;
  705. const Rco = 0.2126729; // sRGB Red Coefficient (from matrix)
  706. const Gco = 0.7151522; // sRGB Green Coefficient (from matrix)
  707. const Bco = 0.0721750; // sRGB Blue Coefficient (from matrix)
  708. // For Finding Raw SAPC Contrast from Relative Luminance (Y)
  709. // Constants for SAPC Power Curve Exponents
  710. // One pair for normal text, and one for reverse
  711. // These are the "beating heart" of SAPC
  712. const normBG = 0.55;
  713. const normTXT = 0.58;
  714. const revTXT = 0.57;
  715. const revBG = 0.62;
  716. // For Clamping and Scaling Values
  717. const blkThrs = 0.03; // Level that triggers the soft black clamp
  718. const blkClmp = 1.45; // Exponent for the soft black clamp curve
  719. const deltaYmin = 0.0005; // Lint trap
  720. const scaleBoW = 1.25; // Scaling for dark text on light
  721. const scaleWoB = 1.25; // Scaling for light text on dark
  722. const loConThresh = 0.078; // Threshold for new simple offset scale
  723. const loConFactor = 12.82051282051282; // = 1/0.078,
  724. const loConOffset = 0.06; // The simple offset
  725. const loClip = 0.001; // Output clip (lint trap #2)
  726. function APCAcontrast(text, background) {
  727. // Linearize sRGB
  728. const Rtxt = (text.r / 255) ** mainTRC;
  729. const Gtxt = (text.g / 255) ** mainTRC;
  730. const Btxt = (text.b / 255) ** mainTRC;
  731. const Rbg = (background.r / 255) ** mainTRC;
  732. const Gbg = (background.g / 255) ** mainTRC;
  733. const Bbg = (background.b / 255) ** mainTRC;
  734. // Apply the standard coefficients and sum to Y
  735. let Ytxt = Rtxt * Rco + Gtxt * Gco + Btxt * Bco;
  736. let Ybg = Rbg * Rco + Gbg * Gco + Bbg * Bco;
  737. // Soft clamp Y when near black.
  738. // Now clamping all colors to prevent crossover errors
  739. if (Ytxt <= blkThrs) Ytxt += (blkThrs - Ytxt) ** blkClmp;
  740. if (Ybg <= blkThrs) Ybg += (blkThrs - Ybg) ** blkClmp;
  741. // Return 0 Early for extremely low ∆Y (lint trap #1)
  742. if (Math.abs(Ybg - Ytxt) < deltaYmin) return 0.0;
  743. // SAPC CONTRAST
  744. let outputContrast; // For weighted final values
  745. if (Ybg > Ytxt) {
  746. // For normal polarity, black text on white
  747. // Calculate the SAPC contrast value and scale
  748. const SAPC = (Ybg ** normBG - Ytxt ** normTXT) * scaleBoW;
  749. // NEW! SAPC SmoothScale™
  750. // Low Contrast Smooth Scale Rollout to prevent polarity reversal
  751. // and also a low clip for very low contrasts (lint trap #2)
  752. // much of this is for very low contrasts, less than 10
  753. // therefore for most reversing needs, only loConOffset is important
  754. outputContrast = SAPC < loClip ? 0.0 : SAPC < loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC - loConOffset;
  755. } else {
  756. // For reverse polarity, light text on dark
  757. // WoB should always return negative value.
  758. const SAPC = (Ybg ** revBG - Ytxt ** revTXT) * scaleWoB;
  759. outputContrast = SAPC > -loClip ? 0.0 : SAPC > -loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC + loConOffset;
  760. }
  761. return outputContrast * 100;
  762. }
  763. /* eslint-disable no-console */
  764. function consoleWarn(message) {
  765. warn(`Vuetify: ${message}`);
  766. }
  767. function consoleError(message) {
  768. warn(`Vuetify error: ${message}`);
  769. }
  770. function deprecate(original, replacement) {
  771. replacement = Array.isArray(replacement) ? replacement.slice(0, -1).map(s => `'${s}'`).join(', ') + ` or '${replacement.at(-1)}'` : `'${replacement}'`;
  772. warn(`[Vuetify UPGRADE] '${original}' is deprecated, use ${replacement} instead.`);
  773. }
  774. // Types
  775. const delta = 0.20689655172413793; // 6÷29
  776. const cielabForwardTransform = t => t > delta ** 3 ? Math.cbrt(t) : t / (3 * delta ** 2) + 4 / 29;
  777. const cielabReverseTransform = t => t > delta ? t ** 3 : 3 * delta ** 2 * (t - 4 / 29);
  778. function fromXYZ$1(xyz) {
  779. const transform = cielabForwardTransform;
  780. const transformedY = transform(xyz[1]);
  781. return [116 * transformedY - 16, 500 * (transform(xyz[0] / 0.95047) - transformedY), 200 * (transformedY - transform(xyz[2] / 1.08883))];
  782. }
  783. function toXYZ$1(lab) {
  784. const transform = cielabReverseTransform;
  785. const Ln = (lab[0] + 16) / 116;
  786. return [transform(Ln + lab[1] / 500) * 0.95047, transform(Ln), transform(Ln - lab[2] / 200) * 1.08883];
  787. }
  788. // Utilities
  789. // Types
  790. // For converting XYZ to sRGB
  791. const srgbForwardMatrix = [[3.2406, -1.5372, -0.4986], [-0.9689, 1.8758, 0.0415], [0.0557, -0.2040, 1.0570]];
  792. // Forward gamma adjust
  793. const srgbForwardTransform = C => C <= 0.0031308 ? C * 12.92 : 1.055 * C ** (1 / 2.4) - 0.055;
  794. // For converting sRGB to XYZ
  795. const srgbReverseMatrix = [[0.4124, 0.3576, 0.1805], [0.2126, 0.7152, 0.0722], [0.0193, 0.1192, 0.9505]];
  796. // Reverse gamma adjust
  797. const srgbReverseTransform = C => C <= 0.04045 ? C / 12.92 : ((C + 0.055) / 1.055) ** 2.4;
  798. function fromXYZ(xyz) {
  799. const rgb = Array(3);
  800. const transform = srgbForwardTransform;
  801. const matrix = srgbForwardMatrix;
  802. // Matrix transform, then gamma adjustment
  803. for (let i = 0; i < 3; ++i) {
  804. // Rescale back to [0, 255]
  805. rgb[i] = Math.round(clamp(transform(matrix[i][0] * xyz[0] + matrix[i][1] * xyz[1] + matrix[i][2] * xyz[2])) * 255);
  806. }
  807. return {
  808. r: rgb[0],
  809. g: rgb[1],
  810. b: rgb[2]
  811. };
  812. }
  813. function toXYZ(_ref) {
  814. let {
  815. r,
  816. g,
  817. b
  818. } = _ref;
  819. const xyz = [0, 0, 0];
  820. const transform = srgbReverseTransform;
  821. const matrix = srgbReverseMatrix;
  822. // Rescale from [0, 255] to [0, 1] then adjust sRGB gamma to linear RGB
  823. r = transform(r / 255);
  824. g = transform(g / 255);
  825. b = transform(b / 255);
  826. // Matrix color space transform
  827. for (let i = 0; i < 3; ++i) {
  828. xyz[i] = matrix[i][0] * r + matrix[i][1] * g + matrix[i][2] * b;
  829. }
  830. return xyz;
  831. }
  832. // Utilities
  833. // Types
  834. function isCssColor(color) {
  835. return !!color && /^(#|var\(--|(rgb|hsl)a?\()/.test(color);
  836. }
  837. function isParsableColor(color) {
  838. return isCssColor(color) && !/^((rgb|hsl)a?\()?var\(--/.test(color);
  839. }
  840. const cssColorRe = /^(?<fn>(?:rgb|hsl)a?)\((?<values>.+)\)/;
  841. const mappers = {
  842. rgb: (r, g, b, a) => ({
  843. r,
  844. g,
  845. b,
  846. a
  847. }),
  848. rgba: (r, g, b, a) => ({
  849. r,
  850. g,
  851. b,
  852. a
  853. }),
  854. hsl: (h, s, l, a) => HSLtoRGB({
  855. h,
  856. s,
  857. l,
  858. a
  859. }),
  860. hsla: (h, s, l, a) => HSLtoRGB({
  861. h,
  862. s,
  863. l,
  864. a
  865. }),
  866. hsv: (h, s, v, a) => HSVtoRGB({
  867. h,
  868. s,
  869. v,
  870. a
  871. }),
  872. hsva: (h, s, v, a) => HSVtoRGB({
  873. h,
  874. s,
  875. v,
  876. a
  877. })
  878. };
  879. function parseColor(color) {
  880. if (typeof color === 'number') {
  881. if (isNaN(color) || color < 0 || color > 0xFFFFFF) {
  882. // int can't have opacity
  883. consoleWarn(`'${color}' is not a valid hex color`);
  884. }
  885. return {
  886. r: (color & 0xFF0000) >> 16,
  887. g: (color & 0xFF00) >> 8,
  888. b: color & 0xFF
  889. };
  890. } else if (typeof color === 'string' && cssColorRe.test(color)) {
  891. const {
  892. groups
  893. } = color.match(cssColorRe);
  894. const {
  895. fn,
  896. values
  897. } = groups;
  898. const realValues = values.split(/,\s*/).map(v => {
  899. if (v.endsWith('%') && ['hsl', 'hsla', 'hsv', 'hsva'].includes(fn)) {
  900. return parseFloat(v) / 100;
  901. } else {
  902. return parseFloat(v);
  903. }
  904. });
  905. return mappers[fn](...realValues);
  906. } else if (typeof color === 'string') {
  907. let hex = color.startsWith('#') ? color.slice(1) : color;
  908. if ([3, 4].includes(hex.length)) {
  909. hex = hex.split('').map(char => char + char).join('');
  910. } else if (![6, 8].includes(hex.length)) {
  911. consoleWarn(`'${color}' is not a valid hex(a) color`);
  912. }
  913. const int = parseInt(hex, 16);
  914. if (isNaN(int) || int < 0 || int > 0xFFFFFFFF) {
  915. consoleWarn(`'${color}' is not a valid hex(a) color`);
  916. }
  917. return HexToRGB(hex);
  918. } else if (typeof color === 'object') {
  919. if (has(color, ['r', 'g', 'b'])) {
  920. return color;
  921. } else if (has(color, ['h', 's', 'l'])) {
  922. return HSVtoRGB(HSLtoHSV(color));
  923. } else if (has(color, ['h', 's', 'v'])) {
  924. return HSVtoRGB(color);
  925. }
  926. }
  927. throw new TypeError(`Invalid color: ${color == null ? color : String(color) || color.constructor.name}\nExpected #hex, #hexa, rgb(), rgba(), hsl(), hsla(), object or number`);
  928. }
  929. /** Converts HSVA to RGBA. Based on formula from https://en.wikipedia.org/wiki/HSL_and_HSV */
  930. function HSVtoRGB(hsva) {
  931. const {
  932. h,
  933. s,
  934. v,
  935. a
  936. } = hsva;
  937. const f = n => {
  938. const k = (n + h / 60) % 6;
  939. return v - v * s * Math.max(Math.min(k, 4 - k, 1), 0);
  940. };
  941. const rgb = [f(5), f(3), f(1)].map(v => Math.round(v * 255));
  942. return {
  943. r: rgb[0],
  944. g: rgb[1],
  945. b: rgb[2],
  946. a
  947. };
  948. }
  949. function HSLtoRGB(hsla) {
  950. return HSVtoRGB(HSLtoHSV(hsla));
  951. }
  952. /** Converts RGBA to HSVA. Based on formula from https://en.wikipedia.org/wiki/HSL_and_HSV */
  953. function RGBtoHSV(rgba) {
  954. if (!rgba) return {
  955. h: 0,
  956. s: 1,
  957. v: 1,
  958. a: 1
  959. };
  960. const r = rgba.r / 255;
  961. const g = rgba.g / 255;
  962. const b = rgba.b / 255;
  963. const max = Math.max(r, g, b);
  964. const min = Math.min(r, g, b);
  965. let h = 0;
  966. if (max !== min) {
  967. if (max === r) {
  968. h = 60 * (0 + (g - b) / (max - min));
  969. } else if (max === g) {
  970. h = 60 * (2 + (b - r) / (max - min));
  971. } else if (max === b) {
  972. h = 60 * (4 + (r - g) / (max - min));
  973. }
  974. }
  975. if (h < 0) h = h + 360;
  976. const s = max === 0 ? 0 : (max - min) / max;
  977. const hsv = [h, s, max];
  978. return {
  979. h: hsv[0],
  980. s: hsv[1],
  981. v: hsv[2],
  982. a: rgba.a
  983. };
  984. }
  985. function HSVtoHSL(hsva) {
  986. const {
  987. h,
  988. s,
  989. v,
  990. a
  991. } = hsva;
  992. const l = v - v * s / 2;
  993. const sprime = l === 1 || l === 0 ? 0 : (v - l) / Math.min(l, 1 - l);
  994. return {
  995. h,
  996. s: sprime,
  997. l,
  998. a
  999. };
  1000. }
  1001. function HSLtoHSV(hsl) {
  1002. const {
  1003. h,
  1004. s,
  1005. l,
  1006. a
  1007. } = hsl;
  1008. const v = l + s * Math.min(l, 1 - l);
  1009. const sprime = v === 0 ? 0 : 2 - 2 * l / v;
  1010. return {
  1011. h,
  1012. s: sprime,
  1013. v,
  1014. a
  1015. };
  1016. }
  1017. function RGBtoCSS(_ref) {
  1018. let {
  1019. r,
  1020. g,
  1021. b,
  1022. a
  1023. } = _ref;
  1024. return a === undefined ? `rgb(${r}, ${g}, ${b})` : `rgba(${r}, ${g}, ${b}, ${a})`;
  1025. }
  1026. function HSVtoCSS(hsva) {
  1027. return RGBtoCSS(HSVtoRGB(hsva));
  1028. }
  1029. function toHex(v) {
  1030. const h = Math.round(v).toString(16);
  1031. return ('00'.substr(0, 2 - h.length) + h).toUpperCase();
  1032. }
  1033. function RGBtoHex(_ref2) {
  1034. let {
  1035. r,
  1036. g,
  1037. b,
  1038. a
  1039. } = _ref2;
  1040. return `#${[toHex(r), toHex(g), toHex(b), a !== undefined ? toHex(Math.round(a * 255)) : ''].join('')}`;
  1041. }
  1042. function HexToRGB(hex) {
  1043. hex = parseHex(hex);
  1044. let [r, g, b, a] = chunk(hex, 2).map(c => parseInt(c, 16));
  1045. a = a === undefined ? a : a / 255;
  1046. return {
  1047. r,
  1048. g,
  1049. b,
  1050. a
  1051. };
  1052. }
  1053. function HexToHSV(hex) {
  1054. const rgb = HexToRGB(hex);
  1055. return RGBtoHSV(rgb);
  1056. }
  1057. function HSVtoHex(hsva) {
  1058. return RGBtoHex(HSVtoRGB(hsva));
  1059. }
  1060. function parseHex(hex) {
  1061. if (hex.startsWith('#')) {
  1062. hex = hex.slice(1);
  1063. }
  1064. hex = hex.replace(/([^0-9a-f])/gi, 'F');
  1065. if (hex.length === 3 || hex.length === 4) {
  1066. hex = hex.split('').map(x => x + x).join('');
  1067. }
  1068. if (hex.length !== 6) {
  1069. hex = padEnd(padEnd(hex, 6), 8, 'F');
  1070. }
  1071. return hex;
  1072. }
  1073. function lighten(value, amount) {
  1074. const lab = fromXYZ$1(toXYZ(value));
  1075. lab[0] = lab[0] + amount * 10;
  1076. return fromXYZ(toXYZ$1(lab));
  1077. }
  1078. function darken(value, amount) {
  1079. const lab = fromXYZ$1(toXYZ(value));
  1080. lab[0] = lab[0] - amount * 10;
  1081. return fromXYZ(toXYZ$1(lab));
  1082. }
  1083. /**
  1084. * Calculate the relative luminance of a given color
  1085. * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef
  1086. */
  1087. function getLuma(color) {
  1088. const rgb = parseColor(color);
  1089. return toXYZ(rgb)[1];
  1090. }
  1091. /**
  1092. * Returns the contrast ratio (1-21) between two colors.
  1093. * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef
  1094. */
  1095. function getContrast(first, second) {
  1096. const l1 = getLuma(first);
  1097. const l2 = getLuma(second);
  1098. const light = Math.max(l1, l2);
  1099. const dark = Math.min(l1, l2);
  1100. return (light + 0.05) / (dark + 0.05);
  1101. }
  1102. function getForeground(color) {
  1103. const blackContrast = Math.abs(APCAcontrast(parseColor(0), parseColor(color)));
  1104. const whiteContrast = Math.abs(APCAcontrast(parseColor(0xffffff), parseColor(color)));
  1105. // TODO: warn about poor color selections
  1106. // const contrastAsText = Math.abs(APCAcontrast(colorVal, colorToInt(theme.colors.background)))
  1107. // const minContrast = Math.max(blackContrast, whiteContrast)
  1108. // if (minContrast < 60) {
  1109. // consoleInfo(`${key} theme color ${color} has poor contrast (${minContrast.toFixed()}%)`)
  1110. // } else if (contrastAsText < 60 && !['background', 'surface'].includes(color)) {
  1111. // consoleInfo(`${key} theme color ${color} has poor contrast as text (${contrastAsText.toFixed()}%)`)
  1112. // }
  1113. // Prefer white text if both have an acceptable contrast ratio
  1114. return whiteContrast > Math.min(blackContrast, 50) ? '#fff' : '#000';
  1115. }
  1116. // Types
  1117. // eslint-disable-line vue/prefer-import-from-vue
  1118. /**
  1119. * Creates a factory function for props definitions.
  1120. * This is used to define props in a composable then override
  1121. * default values in an implementing component.
  1122. *
  1123. * @example Simplified signature
  1124. * (props: Props) => (defaults?: Record<keyof props, any>) => Props
  1125. *
  1126. * @example Usage
  1127. * const makeProps = propsFactory({
  1128. * foo: String,
  1129. * })
  1130. *
  1131. * defineComponent({
  1132. * props: {
  1133. * ...makeProps({
  1134. * foo: 'a',
  1135. * }),
  1136. * },
  1137. * setup (props) {
  1138. * // would be "string | undefined", now "string" because a default has been provided
  1139. * props.foo
  1140. * },
  1141. * }
  1142. */
  1143. function propsFactory(props, source) {
  1144. return defaults => {
  1145. return Object.keys(props).reduce((obj, prop) => {
  1146. const isObjectDefinition = typeof props[prop] === 'object' && props[prop] != null && !Array.isArray(props[prop]);
  1147. const definition = isObjectDefinition ? props[prop] : {
  1148. type: props[prop]
  1149. };
  1150. if (defaults && prop in defaults) {
  1151. obj[prop] = {
  1152. ...definition,
  1153. default: defaults[prop]
  1154. };
  1155. } else {
  1156. obj[prop] = definition;
  1157. }
  1158. if (source && !obj[prop].source) {
  1159. obj[prop].source = source;
  1160. }
  1161. return obj;
  1162. }, {});
  1163. };
  1164. }
  1165. /**
  1166. * Like `Partial<T>` but doesn't care what the value is
  1167. */
  1168. // Copied from Vue
  1169. // Utilities
  1170. // Types
  1171. // Composables
  1172. const makeComponentProps = propsFactory({
  1173. class: [String, Array, Object],
  1174. style: {
  1175. type: [String, Array, Object],
  1176. default: null
  1177. }
  1178. }, 'component');
  1179. // Utilities
  1180. // Types
  1181. function getCurrentInstance(name, message) {
  1182. const vm = getCurrentInstance$1();
  1183. if (!vm) {
  1184. throw new Error(`[Vuetify] ${name} ${message || 'must be called from inside a setup function'}`);
  1185. }
  1186. return vm;
  1187. }
  1188. function getCurrentInstanceName() {
  1189. let name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'composables';
  1190. const vm = getCurrentInstance(name).type;
  1191. return toKebabCase(vm?.aliasName || vm?.name);
  1192. }
  1193. let _uid = 0;
  1194. let _map = new WeakMap();
  1195. function getUid() {
  1196. const vm = getCurrentInstance('getUid');
  1197. if (_map.has(vm)) return _map.get(vm);else {
  1198. const uid = _uid++;
  1199. _map.set(vm, uid);
  1200. return uid;
  1201. }
  1202. }
  1203. getUid.reset = () => {
  1204. _uid = 0;
  1205. _map = new WeakMap();
  1206. };
  1207. // Utilities
  1208. // Types
  1209. function injectSelf(key) {
  1210. let vm = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstance('injectSelf');
  1211. const {
  1212. provides
  1213. } = vm;
  1214. if (provides && key in provides) {
  1215. // TS doesn't allow symbol as index type
  1216. return provides[key];
  1217. }
  1218. return undefined;
  1219. }
  1220. // Utilities
  1221. // Types
  1222. const DefaultsSymbol = Symbol.for('vuetify:defaults');
  1223. function createDefaults(options) {
  1224. return ref(options);
  1225. }
  1226. function injectDefaults() {
  1227. const defaults = inject$1(DefaultsSymbol);
  1228. if (!defaults) throw new Error('[Vuetify] Could not find defaults instance');
  1229. return defaults;
  1230. }
  1231. function provideDefaults(defaults, options) {
  1232. const injectedDefaults = injectDefaults();
  1233. const providedDefaults = ref(defaults);
  1234. const newDefaults = computed(() => {
  1235. const disabled = unref(options?.disabled);
  1236. if (disabled) return injectedDefaults.value;
  1237. const scoped = unref(options?.scoped);
  1238. const reset = unref(options?.reset);
  1239. const root = unref(options?.root);
  1240. if (providedDefaults.value == null && !(scoped || reset || root)) return injectedDefaults.value;
  1241. let properties = mergeDeep(providedDefaults.value, {
  1242. prev: injectedDefaults.value
  1243. });
  1244. if (scoped) return properties;
  1245. if (reset || root) {
  1246. const len = Number(reset || Infinity);
  1247. for (let i = 0; i <= len; i++) {
  1248. if (!properties || !('prev' in properties)) {
  1249. break;
  1250. }
  1251. properties = properties.prev;
  1252. }
  1253. if (properties && typeof root === 'string' && root in properties) {
  1254. properties = mergeDeep(mergeDeep(properties, {
  1255. prev: properties
  1256. }), properties[root]);
  1257. }
  1258. return properties;
  1259. }
  1260. return properties.prev ? mergeDeep(properties.prev, properties) : properties;
  1261. });
  1262. provide(DefaultsSymbol, newDefaults);
  1263. return newDefaults;
  1264. }
  1265. function propIsDefined(vnode, prop) {
  1266. return typeof vnode.props?.[prop] !== 'undefined' || typeof vnode.props?.[toKebabCase(prop)] !== 'undefined';
  1267. }
  1268. function internalUseDefaults() {
  1269. let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  1270. let name = arguments.length > 1 ? arguments[1] : undefined;
  1271. let defaults = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : injectDefaults();
  1272. const vm = getCurrentInstance('useDefaults');
  1273. name = name ?? vm.type.name ?? vm.type.__name;
  1274. if (!name) {
  1275. throw new Error('[Vuetify] Could not determine component name');
  1276. }
  1277. const componentDefaults = computed(() => defaults.value?.[props._as ?? name]);
  1278. const _props = new Proxy(props, {
  1279. get(target, prop) {
  1280. const propValue = Reflect.get(target, prop);
  1281. if (prop === 'class' || prop === 'style') {
  1282. return [componentDefaults.value?.[prop], propValue].filter(v => v != null);
  1283. } else if (typeof prop === 'string' && !propIsDefined(vm.vnode, prop)) {
  1284. return componentDefaults.value?.[prop] !== undefined ? componentDefaults.value?.[prop] : defaults.value?.global?.[prop] !== undefined ? defaults.value?.global?.[prop] : propValue;
  1285. }
  1286. return propValue;
  1287. }
  1288. });
  1289. const _subcomponentDefaults = shallowRef();
  1290. watchEffect(() => {
  1291. if (componentDefaults.value) {
  1292. const subComponents = Object.entries(componentDefaults.value).filter(_ref => {
  1293. let [key] = _ref;
  1294. return key.startsWith(key[0].toUpperCase());
  1295. });
  1296. _subcomponentDefaults.value = subComponents.length ? Object.fromEntries(subComponents) : undefined;
  1297. } else {
  1298. _subcomponentDefaults.value = undefined;
  1299. }
  1300. });
  1301. function provideSubDefaults() {
  1302. const injected = injectSelf(DefaultsSymbol, vm);
  1303. provide(DefaultsSymbol, computed(() => {
  1304. return _subcomponentDefaults.value ? mergeDeep(injected?.value ?? {}, _subcomponentDefaults.value) : injected?.value;
  1305. }));
  1306. }
  1307. return {
  1308. props: _props,
  1309. provideSubDefaults
  1310. };
  1311. }
  1312. function useDefaults() {
  1313. let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  1314. let name = arguments.length > 1 ? arguments[1] : undefined;
  1315. const {
  1316. props: _props,
  1317. provideSubDefaults
  1318. } = internalUseDefaults(props, name);
  1319. provideSubDefaults();
  1320. return _props;
  1321. }
  1322. // Composables
  1323. // Types
  1324. // No props
  1325. // Object Props
  1326. // Implementation
  1327. function defineComponent(options) {
  1328. options._setup = options._setup ?? options.setup;
  1329. if (!options.name) {
  1330. consoleWarn('The component is missing an explicit name, unable to generate default prop value');
  1331. return options;
  1332. }
  1333. if (options._setup) {
  1334. options.props = propsFactory(options.props ?? {}, options.name)();
  1335. const propKeys = Object.keys(options.props).filter(key => key !== 'class' && key !== 'style');
  1336. options.filterProps = function filterProps(props) {
  1337. return pick(props, propKeys);
  1338. };
  1339. options.props._as = String;
  1340. options.setup = function setup(props, ctx) {
  1341. const defaults = injectDefaults();
  1342. // Skip props proxy if defaults are not provided
  1343. if (!defaults.value) return options._setup(props, ctx);
  1344. const {
  1345. props: _props,
  1346. provideSubDefaults
  1347. } = internalUseDefaults(props, props._as ?? options.name, defaults);
  1348. const setupBindings = options._setup(_props, ctx);
  1349. provideSubDefaults();
  1350. return setupBindings;
  1351. };
  1352. }
  1353. return options;
  1354. }
  1355. // No argument - simple default slot
  1356. // Generic constructor argument - generic props and slots
  1357. // Slots argument - simple slots
  1358. // Implementation
  1359. function genericComponent() {
  1360. let exposeDefaults = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
  1361. return options => (exposeDefaults ? defineComponent : defineComponent$1)(options);
  1362. }
  1363. function defineFunctionalComponent(props, render) {
  1364. render.props = props;
  1365. return render;
  1366. }
  1367. // Adds a filterProps method to the component options
  1368. // https://github.com/vuejs/core/pull/10557
  1369. // not a vue Component
  1370. // Composables
  1371. function createSimpleFunctional(klass) {
  1372. let tag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'div';
  1373. let name = arguments.length > 2 ? arguments[2] : undefined;
  1374. return genericComponent()({
  1375. name: name ?? capitalize(camelize(klass.replace(/__/g, '-'))),
  1376. props: {
  1377. tag: {
  1378. type: String,
  1379. default: tag
  1380. },
  1381. ...makeComponentProps()
  1382. },
  1383. setup(props, _ref) {
  1384. let {
  1385. slots
  1386. } = _ref;
  1387. return () => {
  1388. return h(props.tag, {
  1389. class: [klass, props.class],
  1390. style: props.style
  1391. }, slots.default?.());
  1392. };
  1393. }
  1394. });
  1395. }
  1396. /**
  1397. * Returns:
  1398. * - 'null' if the node is not attached to the DOM
  1399. * - the root node (HTMLDocument | ShadowRoot) otherwise
  1400. */
  1401. function attachedRoot(node) {
  1402. /* istanbul ignore next */
  1403. if (typeof node.getRootNode !== 'function') {
  1404. // Shadow DOM not supported (IE11), lets find the root of this node
  1405. while (node.parentNode) node = node.parentNode;
  1406. // The root parent is the document if the node is attached to the DOM
  1407. if (node !== document) return null;
  1408. return document;
  1409. }
  1410. const root = node.getRootNode();
  1411. // The composed root node is the document if the node is attached to the DOM
  1412. if (root !== document && root.getRootNode({
  1413. composed: true
  1414. }) !== document) return null;
  1415. return root;
  1416. }
  1417. const standardEasing = 'cubic-bezier(0.4, 0, 0.2, 1)';
  1418. const deceleratedEasing = 'cubic-bezier(0.0, 0, 0.2, 1)'; // Entering
  1419. const acceleratedEasing = 'cubic-bezier(0.4, 0, 1, 1)'; // Leaving
  1420. // Utilities
  1421. function getPrefixedEventHandlers(attrs, suffix, getData) {
  1422. return Object.keys(attrs).filter(key => isOn(key) && key.endsWith(suffix)).reduce((acc, key) => {
  1423. acc[key.slice(0, -suffix.length)] = event => attrs[key](event, getData(event));
  1424. return acc;
  1425. }, {});
  1426. }
  1427. function getScrollParent(el) {
  1428. let includeHidden = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  1429. while (el) {
  1430. if (includeHidden ? isPotentiallyScrollable(el) : hasScrollbar(el)) return el;
  1431. el = el.parentElement;
  1432. }
  1433. return document.scrollingElement;
  1434. }
  1435. function getScrollParents(el, stopAt) {
  1436. const elements = [];
  1437. if (stopAt && el && !stopAt.contains(el)) return elements;
  1438. while (el) {
  1439. if (hasScrollbar(el)) elements.push(el);
  1440. if (el === stopAt) break;
  1441. el = el.parentElement;
  1442. }
  1443. return elements;
  1444. }
  1445. function hasScrollbar(el) {
  1446. if (!el || el.nodeType !== Node.ELEMENT_NODE) return false;
  1447. const style = window.getComputedStyle(el);
  1448. return style.overflowY === 'scroll' || style.overflowY === 'auto' && el.scrollHeight > el.clientHeight;
  1449. }
  1450. function isPotentiallyScrollable(el) {
  1451. if (!el || el.nodeType !== Node.ELEMENT_NODE) return false;
  1452. const style = window.getComputedStyle(el);
  1453. return ['scroll', 'auto'].includes(style.overflowY);
  1454. }
  1455. function isFixedPosition(el) {
  1456. while (el) {
  1457. if (window.getComputedStyle(el).position === 'fixed') {
  1458. return true;
  1459. }
  1460. el = el.offsetParent;
  1461. }
  1462. return false;
  1463. }
  1464. // Utilities
  1465. // Types
  1466. function useRender(render) {
  1467. const vm = getCurrentInstance('useRender');
  1468. vm.render = render;
  1469. }
  1470. // Types
  1471. const IconValue = [String, Function, Object, Array];
  1472. const IconSymbol = Symbol.for('vuetify:icons');
  1473. const makeIconProps = propsFactory({
  1474. icon: {
  1475. type: IconValue
  1476. },
  1477. // Could not remove this and use makeTagProps, types complained because it is not required
  1478. tag: {
  1479. type: String,
  1480. required: true
  1481. }
  1482. }, 'icon');
  1483. const VComponentIcon = genericComponent()({
  1484. name: 'VComponentIcon',
  1485. props: makeIconProps(),
  1486. setup(props, _ref) {
  1487. let {
  1488. slots
  1489. } = _ref;
  1490. return () => {
  1491. const Icon = props.icon;
  1492. return createVNode(props.tag, null, {
  1493. default: () => [props.icon ? createVNode(Icon, null, null) : slots.default?.()]
  1494. });
  1495. };
  1496. }
  1497. });
  1498. const VSvgIcon = defineComponent({
  1499. name: 'VSvgIcon',
  1500. inheritAttrs: false,
  1501. props: makeIconProps(),
  1502. setup(props, _ref2) {
  1503. let {
  1504. attrs
  1505. } = _ref2;
  1506. return () => {
  1507. return createVNode(props.tag, mergeProps(attrs, {
  1508. "style": null
  1509. }), {
  1510. default: () => [createVNode("svg", {
  1511. "class": "v-icon__svg",
  1512. "xmlns": "http://www.w3.org/2000/svg",
  1513. "viewBox": "0 0 24 24",
  1514. "role": "img",
  1515. "aria-hidden": "true"
  1516. }, [Array.isArray(props.icon) ? props.icon.map(path => Array.isArray(path) ? createVNode("path", {
  1517. "d": path[0],
  1518. "fill-opacity": path[1]
  1519. }, null) : createVNode("path", {
  1520. "d": path
  1521. }, null)) : createVNode("path", {
  1522. "d": props.icon
  1523. }, null)])]
  1524. });
  1525. };
  1526. }
  1527. });
  1528. const VLigatureIcon = defineComponent({
  1529. name: 'VLigatureIcon',
  1530. props: makeIconProps(),
  1531. setup(props) {
  1532. return () => {
  1533. return createVNode(props.tag, null, {
  1534. default: () => [props.icon]
  1535. });
  1536. };
  1537. }
  1538. });
  1539. const VClassIcon = defineComponent({
  1540. name: 'VClassIcon',
  1541. props: makeIconProps(),
  1542. setup(props) {
  1543. return () => {
  1544. return createVNode(props.tag, {
  1545. "class": props.icon
  1546. }, null);
  1547. };
  1548. }
  1549. });
  1550. function genDefaults$3() {
  1551. return {
  1552. svg: {
  1553. component: VSvgIcon
  1554. },
  1555. class: {
  1556. component: VClassIcon
  1557. }
  1558. };
  1559. }
  1560. // Composables
  1561. function createIcons(options) {
  1562. const sets = genDefaults$3();
  1563. const defaultSet = options?.defaultSet ?? 'mdi';
  1564. if (defaultSet === 'mdi' && !sets.mdi) {
  1565. sets.mdi = mdi;
  1566. }
  1567. return mergeDeep({
  1568. defaultSet,
  1569. sets,
  1570. aliases: {
  1571. ...aliases,
  1572. /* eslint-disable max-len */
  1573. vuetify: ['M8.2241 14.2009L12 21L22 3H14.4459L8.2241 14.2009Z', ['M7.26303 12.4733L7.00113 12L2 3H12.5261C12.5261 3 12.5261 3 12.5261 3L7.26303 12.4733Z', 0.6]],
  1574. 'vuetify-outline': 'svg:M7.26 12.47 12.53 3H2L7.26 12.47ZM14.45 3 8.22 14.2 12 21 22 3H14.45ZM18.6 5 12 16.88 10.51 14.2 15.62 5ZM7.26 8.35 5.4 5H9.13L7.26 8.35Z',
  1575. 'vuetify-play': ['m6.376 13.184-4.11-7.192C1.505 4.66 2.467 3 4.003 3h8.532l-.953 1.576-.006.01-.396.677c-.429.732-.214 1.507.194 2.015.404.503 1.092.878 1.869.806a3.72 3.72 0 0 1 1.005.022c.276.053.434.143.523.237.138.146.38.635-.25 2.09-.893 1.63-1.553 1.722-1.847 1.677-.213-.033-.468-.158-.756-.406a4.95 4.95 0 0 1-.8-.927c-.39-.564-1.04-.84-1.66-.846-.625-.006-1.316.27-1.693.921l-.478.826-.911 1.506Z', ['M9.093 11.552c.046-.079.144-.15.32-.148a.53.53 0 0 1 .43.207c.285.414.636.847 1.046 1.2.405.35.914.662 1.516.754 1.334.205 2.502-.698 3.48-2.495l.014-.028.013-.03c.687-1.574.774-2.852-.005-3.675-.37-.391-.861-.586-1.333-.676a5.243 5.243 0 0 0-1.447-.044c-.173.016-.393-.073-.54-.257-.145-.18-.127-.316-.082-.392l.393-.672L14.287 3h5.71c1.536 0 2.499 1.659 1.737 2.992l-7.997 13.996c-.768 1.344-2.706 1.344-3.473 0l-3.037-5.314 1.377-2.278.004-.006.004-.007.481-.831Z', 0.6]]
  1576. /* eslint-enable max-len */
  1577. }
  1578. }, options);
  1579. }
  1580. const useIcon = props => {
  1581. const icons = inject$1(IconSymbol);
  1582. if (!icons) throw new Error('Missing Vuetify Icons provide!');
  1583. const iconData = computed(() => {
  1584. const iconAlias = unref(props);
  1585. if (!iconAlias) return {
  1586. component: VComponentIcon
  1587. };
  1588. let icon = iconAlias;
  1589. if (typeof icon === 'string') {
  1590. icon = icon.trim();
  1591. if (icon.startsWith('$')) {
  1592. icon = icons.aliases?.[icon.slice(1)];
  1593. }
  1594. }
  1595. if (!icon) consoleWarn(`Could not find aliased icon "${iconAlias}"`);
  1596. if (Array.isArray(icon)) {
  1597. return {
  1598. component: VSvgIcon,
  1599. icon
  1600. };
  1601. } else if (typeof icon !== 'string') {
  1602. return {
  1603. component: VComponentIcon,
  1604. icon
  1605. };
  1606. }
  1607. const iconSetName = Object.keys(icons.sets).find(setName => typeof icon === 'string' && icon.startsWith(`${setName}:`));
  1608. const iconName = iconSetName ? icon.slice(iconSetName.length + 1) : icon;
  1609. const iconSet = icons.sets[iconSetName ?? icons.defaultSet];
  1610. return {
  1611. component: iconSet.component,
  1612. icon: iconName
  1613. };
  1614. });
  1615. return {
  1616. iconData
  1617. };
  1618. };
  1619. // Composables
  1620. // Types
  1621. const aliases = {
  1622. collapse: 'mdi-chevron-up',
  1623. complete: 'mdi-check',
  1624. cancel: 'mdi-close-circle',
  1625. close: 'mdi-close',
  1626. delete: 'mdi-close-circle',
  1627. // delete (e.g. v-chip close)
  1628. clear: 'mdi-close-circle',
  1629. success: 'mdi-check-circle',
  1630. info: 'mdi-information',
  1631. warning: 'mdi-alert-circle',
  1632. error: 'mdi-close-circle',
  1633. prev: 'mdi-chevron-left',
  1634. next: 'mdi-chevron-right',
  1635. checkboxOn: 'mdi-checkbox-marked',
  1636. checkboxOff: 'mdi-checkbox-blank-outline',
  1637. checkboxIndeterminate: 'mdi-minus-box',
  1638. delimiter: 'mdi-circle',
  1639. // for carousel
  1640. sortAsc: 'mdi-arrow-up',
  1641. sortDesc: 'mdi-arrow-down',
  1642. expand: 'mdi-chevron-down',
  1643. menu: 'mdi-menu',
  1644. subgroup: 'mdi-menu-down',
  1645. dropdown: 'mdi-menu-down',
  1646. radioOn: 'mdi-radiobox-marked',
  1647. radioOff: 'mdi-radiobox-blank',
  1648. edit: 'mdi-pencil',
  1649. ratingEmpty: 'mdi-star-outline',
  1650. ratingFull: 'mdi-star',
  1651. ratingHalf: 'mdi-star-half-full',
  1652. loading: 'mdi-cached',
  1653. first: 'mdi-page-first',
  1654. last: 'mdi-page-last',
  1655. unfold: 'mdi-unfold-more-horizontal',
  1656. file: 'mdi-paperclip',
  1657. plus: 'mdi-plus',
  1658. minus: 'mdi-minus',
  1659. calendar: 'mdi-calendar',
  1660. treeviewCollapse: 'mdi-menu-down',
  1661. treeviewExpand: 'mdi-menu-right',
  1662. eyeDropper: 'mdi-eyedropper',
  1663. upload: 'mdi-cloud-upload'
  1664. };
  1665. const mdi = {
  1666. // Not using mergeProps here, functional components merge props by default (?)
  1667. component: props => h(VClassIcon, {
  1668. ...props,
  1669. class: 'mdi'
  1670. })
  1671. };
  1672. // Icons
  1673. // Types
  1674. const md1 = {
  1675. defaults: {
  1676. global: {
  1677. rounded: 'sm'
  1678. },
  1679. VAvatar: {
  1680. rounded: 'circle'
  1681. },
  1682. VAutocomplete: {
  1683. variant: 'underlined'
  1684. },
  1685. VBanner: {
  1686. color: 'primary'
  1687. },
  1688. VBtn: {
  1689. color: 'primary',
  1690. rounded: 0
  1691. },
  1692. VCheckbox: {
  1693. color: 'secondary'
  1694. },
  1695. VCombobox: {
  1696. variant: 'underlined'
  1697. },
  1698. VSelect: {
  1699. variant: 'underlined'
  1700. },
  1701. VSlider: {
  1702. color: 'primary'
  1703. },
  1704. VTabs: {
  1705. color: 'primary'
  1706. },
  1707. VTextarea: {
  1708. variant: 'underlined'
  1709. },
  1710. VTextField: {
  1711. variant: 'underlined'
  1712. },
  1713. VToolbar: {
  1714. VBtn: {
  1715. color: null
  1716. }
  1717. }
  1718. },
  1719. icons: {
  1720. defaultSet: 'mdi',
  1721. sets: {
  1722. mdi
  1723. }
  1724. },
  1725. theme: {
  1726. themes: {
  1727. light: {
  1728. colors: {
  1729. primary: '#3F51B5',
  1730. 'primary-darken-1': '#303F9F',
  1731. 'primary-lighten-1': '#C5CAE9',
  1732. secondary: '#FF4081',
  1733. 'secondary-darken-1': '#F50057',
  1734. 'secondary-lighten-1': '#FF80AB',
  1735. accent: '#009688'
  1736. }
  1737. }
  1738. }
  1739. }
  1740. };
  1741. // Icons
  1742. // Types
  1743. const md2 = {
  1744. defaults: {
  1745. global: {
  1746. rounded: 'md'
  1747. },
  1748. VAvatar: {
  1749. rounded: 'circle'
  1750. },
  1751. VAutocomplete: {
  1752. variant: 'filled'
  1753. },
  1754. VBanner: {
  1755. color: 'primary'
  1756. },
  1757. VBtn: {
  1758. color: 'primary'
  1759. },
  1760. VCheckbox: {
  1761. color: 'secondary'
  1762. },
  1763. VCombobox: {
  1764. variant: 'filled'
  1765. },
  1766. VSelect: {
  1767. variant: 'filled'
  1768. },
  1769. VSlider: {
  1770. color: 'primary'
  1771. },
  1772. VTabs: {
  1773. color: 'primary'
  1774. },
  1775. VTextarea: {
  1776. variant: 'filled'
  1777. },
  1778. VTextField: {
  1779. variant: 'filled'
  1780. },
  1781. VToolbar: {
  1782. VBtn: {
  1783. color: null
  1784. }
  1785. }
  1786. },
  1787. icons: {
  1788. defaultSet: 'mdi',
  1789. sets: {
  1790. mdi
  1791. }
  1792. },
  1793. theme: {
  1794. themes: {
  1795. light: {
  1796. colors: {
  1797. primary: '#6200EE',
  1798. 'primary-darken-1': '#3700B3',
  1799. secondary: '#03DAC6',
  1800. 'secondary-darken-1': '#018786',
  1801. error: '#B00020'
  1802. }
  1803. }
  1804. }
  1805. }
  1806. };
  1807. // Icons
  1808. // Types
  1809. const md3 = {
  1810. defaults: {
  1811. VAppBar: {
  1812. flat: true
  1813. },
  1814. VAutocomplete: {
  1815. variant: 'filled'
  1816. },
  1817. VBanner: {
  1818. color: 'primary'
  1819. },
  1820. VBottomSheet: {
  1821. contentClass: 'rounded-t-xl overflow-hidden'
  1822. },
  1823. VBtn: {
  1824. color: 'primary',
  1825. rounded: 'xl'
  1826. },
  1827. VBtnGroup: {
  1828. rounded: 'xl',
  1829. VBtn: {
  1830. rounded: null
  1831. }
  1832. },
  1833. VCard: {
  1834. rounded: 'lg'
  1835. },
  1836. VCheckbox: {
  1837. color: 'secondary',
  1838. inset: true
  1839. },
  1840. VChip: {
  1841. rounded: 'sm'
  1842. },
  1843. VCombobox: {
  1844. variant: 'filled'
  1845. },
  1846. VNavigationDrawer: {
  1847. // VList: {
  1848. // nav: true,
  1849. // VListItem: {
  1850. // rounded: 'xl',
  1851. // },
  1852. // },
  1853. },
  1854. VSelect: {
  1855. variant: 'filled'
  1856. },
  1857. VSlider: {
  1858. color: 'primary'
  1859. },
  1860. VTabs: {
  1861. color: 'primary'
  1862. },
  1863. VTextarea: {
  1864. variant: 'filled'
  1865. },
  1866. VTextField: {
  1867. variant: 'filled'
  1868. },
  1869. VToolbar: {
  1870. VBtn: {
  1871. color: null
  1872. }
  1873. }
  1874. },
  1875. icons: {
  1876. defaultSet: 'mdi',
  1877. sets: {
  1878. mdi
  1879. }
  1880. },
  1881. theme: {
  1882. themes: {
  1883. light: {
  1884. colors: {
  1885. primary: '#6750a4',
  1886. secondary: '#b4b0bb',
  1887. tertiary: '#7d5260',
  1888. error: '#b3261e',
  1889. surface: '#fffbfe'
  1890. }
  1891. }
  1892. }
  1893. }
  1894. };
  1895. var index = /*#__PURE__*/Object.freeze({
  1896. __proto__: null,
  1897. md1: md1,
  1898. md2: md2,
  1899. md3: md3
  1900. });
  1901. // Utilities
  1902. // Types
  1903. function useResizeObserver(callback) {
  1904. let box = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'content';
  1905. const resizeRef = templateRef();
  1906. const contentRect = ref();
  1907. if (IN_BROWSER) {
  1908. const observer = new ResizeObserver(entries => {
  1909. callback?.(entries, observer);
  1910. if (!entries.length) return;
  1911. if (box === 'content') {
  1912. contentRect.value = entries[0].contentRect;
  1913. } else {
  1914. contentRect.value = entries[0].target.getBoundingClientRect();
  1915. }
  1916. });
  1917. onBeforeUnmount(() => {
  1918. observer.disconnect();
  1919. });
  1920. watch(() => resizeRef.el, (newValue, oldValue) => {
  1921. if (oldValue) {
  1922. observer.unobserve(oldValue);
  1923. contentRect.value = undefined;
  1924. }
  1925. if (newValue) observer.observe(newValue);
  1926. }, {
  1927. flush: 'post'
  1928. });
  1929. }
  1930. return {
  1931. resizeRef,
  1932. contentRect: readonly(contentRect)
  1933. };
  1934. }
  1935. // Composables
  1936. // Types
  1937. const VuetifyLayoutKey = Symbol.for('vuetify:layout');
  1938. const VuetifyLayoutItemKey = Symbol.for('vuetify:layout-item');
  1939. const ROOT_ZINDEX = 1000;
  1940. const makeLayoutProps = propsFactory({
  1941. overlaps: {
  1942. type: Array,
  1943. default: () => []
  1944. },
  1945. fullHeight: Boolean
  1946. }, 'layout');
  1947. // Composables
  1948. const makeLayoutItemProps = propsFactory({
  1949. name: {
  1950. type: String
  1951. },
  1952. order: {
  1953. type: [Number, String],
  1954. default: 0
  1955. },
  1956. absolute: Boolean
  1957. }, 'layout-item');
  1958. function useLayout() {
  1959. const layout = inject$1(VuetifyLayoutKey);
  1960. if (!layout) throw new Error('[Vuetify] Could not find injected layout');
  1961. return {
  1962. getLayoutItem: layout.getLayoutItem,
  1963. mainRect: layout.mainRect,
  1964. mainStyles: layout.mainStyles
  1965. };
  1966. }
  1967. function useLayoutItem(options) {
  1968. const layout = inject$1(VuetifyLayoutKey);
  1969. if (!layout) throw new Error('[Vuetify] Could not find injected layout');
  1970. const id = options.id ?? `layout-item-${getUid()}`;
  1971. const vm = getCurrentInstance('useLayoutItem');
  1972. provide(VuetifyLayoutItemKey, {
  1973. id
  1974. });
  1975. const isKeptAlive = shallowRef(false);
  1976. onDeactivated(() => isKeptAlive.value = true);
  1977. onActivated(() => isKeptAlive.value = false);
  1978. const {
  1979. layoutItemStyles,
  1980. layoutItemScrimStyles
  1981. } = layout.register(vm, {
  1982. ...options,
  1983. active: computed(() => isKeptAlive.value ? false : options.active.value),
  1984. id
  1985. });
  1986. onBeforeUnmount(() => layout.unregister(id));
  1987. return {
  1988. layoutItemStyles,
  1989. layoutRect: layout.layoutRect,
  1990. layoutItemScrimStyles
  1991. };
  1992. }
  1993. const generateLayers = (layout, positions, layoutSizes, activeItems) => {
  1994. let previousLayer = {
  1995. top: 0,
  1996. left: 0,
  1997. right: 0,
  1998. bottom: 0
  1999. };
  2000. const layers = [{
  2001. id: '',
  2002. layer: {
  2003. ...previousLayer
  2004. }
  2005. }];
  2006. for (const id of layout) {
  2007. const position = positions.get(id);
  2008. const amount = layoutSizes.get(id);
  2009. const active = activeItems.get(id);
  2010. if (!position || !amount || !active) continue;
  2011. const layer = {
  2012. ...previousLayer,
  2013. [position.value]: parseInt(previousLayer[position.value], 10) + (active.value ? parseInt(amount.value, 10) : 0)
  2014. };
  2015. layers.push({
  2016. id,
  2017. layer
  2018. });
  2019. previousLayer = layer;
  2020. }
  2021. return layers;
  2022. };
  2023. function createLayout(props) {
  2024. const parentLayout = inject$1(VuetifyLayoutKey, null);
  2025. const rootZIndex = computed(() => parentLayout ? parentLayout.rootZIndex.value - 100 : ROOT_ZINDEX);
  2026. const registered = ref([]);
  2027. const positions = reactive(new Map());
  2028. const layoutSizes = reactive(new Map());
  2029. const priorities = reactive(new Map());
  2030. const activeItems = reactive(new Map());
  2031. const disabledTransitions = reactive(new Map());
  2032. const {
  2033. resizeRef,
  2034. contentRect: layoutRect
  2035. } = useResizeObserver();
  2036. const computedOverlaps = computed(() => {
  2037. const map = new Map();
  2038. const overlaps = props.overlaps ?? [];
  2039. for (const overlap of overlaps.filter(item => item.includes(':'))) {
  2040. const [top, bottom] = overlap.split(':');
  2041. if (!registered.value.includes(top) || !registered.value.includes(bottom)) continue;
  2042. const topPosition = positions.get(top);
  2043. const bottomPosition = positions.get(bottom);
  2044. const topAmount = layoutSizes.get(top);
  2045. const bottomAmount = layoutSizes.get(bottom);
  2046. if (!topPosition || !bottomPosition || !topAmount || !bottomAmount) continue;
  2047. map.set(bottom, {
  2048. position: topPosition.value,
  2049. amount: parseInt(topAmount.value, 10)
  2050. });
  2051. map.set(top, {
  2052. position: bottomPosition.value,
  2053. amount: -parseInt(bottomAmount.value, 10)
  2054. });
  2055. }
  2056. return map;
  2057. });
  2058. const layers = computed(() => {
  2059. const uniquePriorities = [...new Set([...priorities.values()].map(p => p.value))].sort((a, b) => a - b);
  2060. const layout = [];
  2061. for (const p of uniquePriorities) {
  2062. const items = registered.value.filter(id => priorities.get(id)?.value === p);
  2063. layout.push(...items);
  2064. }
  2065. return generateLayers(layout, positions, layoutSizes, activeItems);
  2066. });
  2067. const transitionsEnabled = computed(() => {
  2068. return !Array.from(disabledTransitions.values()).some(ref => ref.value);
  2069. });
  2070. const mainRect = computed(() => {
  2071. return layers.value[layers.value.length - 1].layer;
  2072. });
  2073. const mainStyles = computed(() => {
  2074. return {
  2075. '--v-layout-left': convertToUnit(mainRect.value.left),
  2076. '--v-layout-right': convertToUnit(mainRect.value.right),
  2077. '--v-layout-top': convertToUnit(mainRect.value.top),
  2078. '--v-layout-bottom': convertToUnit(mainRect.value.bottom),
  2079. ...(transitionsEnabled.value ? undefined : {
  2080. transition: 'none'
  2081. })
  2082. };
  2083. });
  2084. const items = computed(() => {
  2085. return layers.value.slice(1).map((_ref, index) => {
  2086. let {
  2087. id
  2088. } = _ref;
  2089. const {
  2090. layer
  2091. } = layers.value[index];
  2092. const size = layoutSizes.get(id);
  2093. const position = positions.get(id);
  2094. return {
  2095. id,
  2096. ...layer,
  2097. size: Number(size.value),
  2098. position: position.value
  2099. };
  2100. });
  2101. });
  2102. const getLayoutItem = id => {
  2103. return items.value.find(item => item.id === id);
  2104. };
  2105. const rootVm = getCurrentInstance('createLayout');
  2106. const isMounted = shallowRef(false);
  2107. onMounted(() => {
  2108. isMounted.value = true;
  2109. });
  2110. provide(VuetifyLayoutKey, {
  2111. register: (vm, _ref2) => {
  2112. let {
  2113. id,
  2114. order,
  2115. position,
  2116. layoutSize,
  2117. elementSize,
  2118. active,
  2119. disableTransitions,
  2120. absolute
  2121. } = _ref2;
  2122. priorities.set(id, order);
  2123. positions.set(id, position);
  2124. layoutSizes.set(id, layoutSize);
  2125. activeItems.set(id, active);
  2126. disableTransitions && disabledTransitions.set(id, disableTransitions);
  2127. const instances = findChildrenWithProvide(VuetifyLayoutItemKey, rootVm?.vnode);
  2128. const instanceIndex = instances.indexOf(vm);
  2129. if (instanceIndex > -1) registered.value.splice(instanceIndex, 0, id);else registered.value.push(id);
  2130. const index = computed(() => items.value.findIndex(i => i.id === id));
  2131. const zIndex = computed(() => rootZIndex.value + layers.value.length * 2 - index.value * 2);
  2132. const layoutItemStyles = computed(() => {
  2133. const isHorizontal = position.value === 'left' || position.value === 'right';
  2134. const isOppositeHorizontal = position.value === 'right';
  2135. const isOppositeVertical = position.value === 'bottom';
  2136. const size = elementSize.value ?? layoutSize.value;
  2137. const unit = size === 0 ? '%' : 'px';
  2138. const styles = {
  2139. [position.value]: 0,
  2140. zIndex: zIndex.value,
  2141. transform: `translate${isHorizontal ? 'X' : 'Y'}(${(active.value ? 0 : -(size === 0 ? 100 : size)) * (isOppositeHorizontal || isOppositeVertical ? -1 : 1)}${unit})`,
  2142. position: absolute.value || rootZIndex.value !== ROOT_ZINDEX ? 'absolute' : 'fixed',
  2143. ...(transitionsEnabled.value ? undefined : {
  2144. transition: 'none'
  2145. })
  2146. };
  2147. if (!isMounted.value) return styles;
  2148. const item = items.value[index.value];
  2149. if (!item) throw new Error(`[Vuetify] Could not find layout item "${id}"`);
  2150. const overlap = computedOverlaps.value.get(id);
  2151. if (overlap) {
  2152. item[overlap.position] += overlap.amount;
  2153. }
  2154. return {
  2155. ...styles,
  2156. height: isHorizontal ? `calc(100% - ${item.top}px - ${item.bottom}px)` : elementSize.value ? `${elementSize.value}px` : undefined,
  2157. left: isOppositeHorizontal ? undefined : `${item.left}px`,
  2158. right: isOppositeHorizontal ? `${item.right}px` : undefined,
  2159. top: position.value !== 'bottom' ? `${item.top}px` : undefined,
  2160. bottom: position.value !== 'top' ? `${item.bottom}px` : undefined,
  2161. width: !isHorizontal ? `calc(100% - ${item.left}px - ${item.right}px)` : elementSize.value ? `${elementSize.value}px` : undefined
  2162. };
  2163. });
  2164. const layoutItemScrimStyles = computed(() => ({
  2165. zIndex: zIndex.value - 1
  2166. }));
  2167. return {
  2168. layoutItemStyles,
  2169. layoutItemScrimStyles,
  2170. zIndex
  2171. };
  2172. },
  2173. unregister: id => {
  2174. priorities.delete(id);
  2175. positions.delete(id);
  2176. layoutSizes.delete(id);
  2177. activeItems.delete(id);
  2178. disabledTransitions.delete(id);
  2179. registered.value = registered.value.filter(v => v !== id);
  2180. },
  2181. mainRect,
  2182. mainStyles,
  2183. getLayoutItem,
  2184. items,
  2185. layoutRect,
  2186. rootZIndex
  2187. });
  2188. const layoutClasses = computed(() => ['v-layout', {
  2189. 'v-layout--full-height': props.fullHeight
  2190. }]);
  2191. const layoutStyles = computed(() => ({
  2192. zIndex: parentLayout ? rootZIndex.value : undefined,
  2193. position: parentLayout ? 'relative' : undefined,
  2194. overflow: parentLayout ? 'hidden' : undefined
  2195. }));
  2196. return {
  2197. layoutClasses,
  2198. layoutStyles,
  2199. getLayoutItem,
  2200. items,
  2201. layoutRect,
  2202. layoutRef: resizeRef
  2203. };
  2204. }
  2205. // Utilities
  2206. // Types
  2207. function useToggleScope(source, fn) {
  2208. let scope;
  2209. function start() {
  2210. scope = effectScope();
  2211. scope.run(() => fn.length ? fn(() => {
  2212. scope?.stop();
  2213. start();
  2214. }) : fn());
  2215. }
  2216. watch(source, active => {
  2217. if (active && !scope) {
  2218. start();
  2219. } else if (!active) {
  2220. scope?.stop();
  2221. scope = undefined;
  2222. }
  2223. }, {
  2224. immediate: true
  2225. });
  2226. onScopeDispose(() => {
  2227. scope?.stop();
  2228. });
  2229. }
  2230. // Composables
  2231. // Types
  2232. // Composables
  2233. function useProxiedModel(props, prop, defaultValue) {
  2234. let transformIn = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : v => v;
  2235. let transformOut = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : v => v;
  2236. const vm = getCurrentInstance('useProxiedModel');
  2237. const internal = ref(props[prop] !== undefined ? props[prop] : defaultValue);
  2238. const kebabProp = toKebabCase(prop);
  2239. const checkKebab = kebabProp !== prop;
  2240. const isControlled = checkKebab ? computed(() => {
  2241. void props[prop];
  2242. return !!((vm.vnode.props?.hasOwnProperty(prop) || vm.vnode.props?.hasOwnProperty(kebabProp)) && (vm.vnode.props?.hasOwnProperty(`onUpdate:${prop}`) || vm.vnode.props?.hasOwnProperty(`onUpdate:${kebabProp}`)));
  2243. }) : computed(() => {
  2244. void props[prop];
  2245. return !!(vm.vnode.props?.hasOwnProperty(prop) && vm.vnode.props?.hasOwnProperty(`onUpdate:${prop}`));
  2246. });
  2247. useToggleScope(() => !isControlled.value, () => {
  2248. watch(() => props[prop], val => {
  2249. internal.value = val;
  2250. });
  2251. });
  2252. const model = computed({
  2253. get() {
  2254. const externalValue = props[prop];
  2255. return transformIn(isControlled.value ? externalValue : internal.value);
  2256. },
  2257. set(internalValue) {
  2258. const newValue = transformOut(internalValue);
  2259. const value = toRaw(isControlled.value ? props[prop] : internal.value);
  2260. if (value === newValue || transformIn(value) === internalValue) {
  2261. return;
  2262. }
  2263. internal.value = newValue;
  2264. vm?.emit(`update:${prop}`, newValue);
  2265. }
  2266. });
  2267. Object.defineProperty(model, 'externalValue', {
  2268. get: () => isControlled.value ? props[prop] : internal.value
  2269. });
  2270. return model;
  2271. }
  2272. var en = {
  2273. badge: 'Badge',
  2274. open: 'Open',
  2275. close: 'Close',
  2276. dismiss: 'Dismiss',
  2277. confirmEdit: {
  2278. ok: 'OK',
  2279. cancel: 'Cancel'
  2280. },
  2281. dataIterator: {
  2282. noResultsText: 'No matching records found',
  2283. loadingText: 'Loading items...'
  2284. },
  2285. dataTable: {
  2286. itemsPerPageText: 'Rows per page:',
  2287. ariaLabel: {
  2288. sortDescending: 'Sorted descending.',
  2289. sortAscending: 'Sorted ascending.',
  2290. sortNone: 'Not sorted.',
  2291. activateNone: 'Activate to remove sorting.',
  2292. activateDescending: 'Activate to sort descending.',
  2293. activateAscending: 'Activate to sort ascending.'
  2294. },
  2295. sortBy: 'Sort by'
  2296. },
  2297. dataFooter: {
  2298. itemsPerPageText: 'Items per page:',
  2299. itemsPerPageAll: 'All',
  2300. nextPage: 'Next page',
  2301. prevPage: 'Previous page',
  2302. firstPage: 'First page',
  2303. lastPage: 'Last page',
  2304. pageText: '{0}-{1} of {2}'
  2305. },
  2306. dateRangeInput: {
  2307. divider: 'to'
  2308. },
  2309. datePicker: {
  2310. itemsSelected: '{0} selected',
  2311. range: {
  2312. title: 'Select dates',
  2313. header: 'Enter dates'
  2314. },
  2315. title: 'Select date',
  2316. header: 'Enter date',
  2317. input: {
  2318. placeholder: 'Enter date'
  2319. }
  2320. },
  2321. noDataText: 'No data available',
  2322. carousel: {
  2323. prev: 'Previous visual',
  2324. next: 'Next visual',
  2325. ariaLabel: {
  2326. delimiter: 'Carousel slide {0} of {1}'
  2327. }
  2328. },
  2329. calendar: {
  2330. moreEvents: '{0} more',
  2331. today: 'Today'
  2332. },
  2333. input: {
  2334. clear: 'Clear {0}',
  2335. prependAction: '{0} prepended action',
  2336. appendAction: '{0} appended action',
  2337. otp: 'Please enter OTP character {0}'
  2338. },
  2339. fileInput: {
  2340. counter: '{0} files',
  2341. counterSize: '{0} files ({1} in total)'
  2342. },
  2343. fileUpload: {
  2344. title: 'Drag and drop files here',
  2345. divider: 'or',
  2346. browse: 'Browse Files'
  2347. },
  2348. timePicker: {
  2349. am: 'AM',
  2350. pm: 'PM',
  2351. title: 'Select Time'
  2352. },
  2353. pagination: {
  2354. ariaLabel: {
  2355. root: 'Pagination Navigation',
  2356. next: 'Next page',
  2357. previous: 'Previous page',
  2358. page: 'Go to page {0}',
  2359. currentPage: 'Page {0}, Current page',
  2360. first: 'First page',
  2361. last: 'Last page'
  2362. }
  2363. },
  2364. stepper: {
  2365. next: 'Next',
  2366. prev: 'Previous'
  2367. },
  2368. rating: {
  2369. ariaLabel: {
  2370. item: 'Rating {0} of {1}'
  2371. }
  2372. },
  2373. loading: 'Loading...',
  2374. infiniteScroll: {
  2375. loadMore: 'Load more',
  2376. empty: 'No more'
  2377. }
  2378. };
  2379. // Composables
  2380. // Types
  2381. const LANG_PREFIX = '$vuetify.';
  2382. const replace = (str, params) => {
  2383. return str.replace(/\{(\d+)\}/g, (match, index) => {
  2384. return String(params[+index]);
  2385. });
  2386. };
  2387. const createTranslateFunction = (current, fallback, messages) => {
  2388. return function (key) {
  2389. for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  2390. params[_key - 1] = arguments[_key];
  2391. }
  2392. if (!key.startsWith(LANG_PREFIX)) {
  2393. return replace(key, params);
  2394. }
  2395. const shortKey = key.replace(LANG_PREFIX, '');
  2396. const currentLocale = current.value && messages.value[current.value];
  2397. const fallbackLocale = fallback.value && messages.value[fallback.value];
  2398. let str = getObjectValueByPath(currentLocale, shortKey, null);
  2399. if (!str) {
  2400. consoleWarn(`Translation key "${key}" not found in "${current.value}", trying fallback locale`);
  2401. str = getObjectValueByPath(fallbackLocale, shortKey, null);
  2402. }
  2403. if (!str) {
  2404. consoleError(`Translation key "${key}" not found in fallback`);
  2405. str = key;
  2406. }
  2407. if (typeof str !== 'string') {
  2408. consoleError(`Translation key "${key}" has a non-string value`);
  2409. str = key;
  2410. }
  2411. return replace(str, params);
  2412. };
  2413. };
  2414. function createNumberFunction(current, fallback) {
  2415. return (value, options) => {
  2416. const numberFormat = new Intl.NumberFormat([current.value, fallback.value], options);
  2417. return numberFormat.format(value);
  2418. };
  2419. }
  2420. function useProvided(props, prop, provided) {
  2421. const internal = useProxiedModel(props, prop, props[prop] ?? provided.value);
  2422. // TODO: Remove when defaultValue works
  2423. internal.value = props[prop] ?? provided.value;
  2424. watch(provided, v => {
  2425. if (props[prop] == null) {
  2426. internal.value = provided.value;
  2427. }
  2428. });
  2429. return internal;
  2430. }
  2431. function createProvideFunction(state) {
  2432. return props => {
  2433. const current = useProvided(props, 'locale', state.current);
  2434. const fallback = useProvided(props, 'fallback', state.fallback);
  2435. const messages = useProvided(props, 'messages', state.messages);
  2436. return {
  2437. name: 'vuetify',
  2438. current,
  2439. fallback,
  2440. messages,
  2441. t: createTranslateFunction(current, fallback, messages),
  2442. n: createNumberFunction(current, fallback),
  2443. provide: createProvideFunction({
  2444. current,
  2445. fallback,
  2446. messages
  2447. })
  2448. };
  2449. };
  2450. }
  2451. function createVuetifyAdapter(options) {
  2452. const current = shallowRef(options?.locale ?? 'en');
  2453. const fallback = shallowRef(options?.fallback ?? 'en');
  2454. const messages = ref({
  2455. en,
  2456. ...options?.messages
  2457. });
  2458. return {
  2459. name: 'vuetify',
  2460. current,
  2461. fallback,
  2462. messages,
  2463. t: createTranslateFunction(current, fallback, messages),
  2464. n: createNumberFunction(current, fallback),
  2465. provide: createProvideFunction({
  2466. current,
  2467. fallback,
  2468. messages
  2469. })
  2470. };
  2471. }
  2472. // Utilities
  2473. // Types
  2474. const LocaleSymbol = Symbol.for('vuetify:locale');
  2475. function isLocaleInstance(obj) {
  2476. return obj.name != null;
  2477. }
  2478. function createLocale(options) {
  2479. const i18n = options?.adapter && isLocaleInstance(options?.adapter) ? options?.adapter : createVuetifyAdapter(options);
  2480. const rtl = createRtl(i18n, options);
  2481. return {
  2482. ...i18n,
  2483. ...rtl
  2484. };
  2485. }
  2486. function useLocale() {
  2487. const locale = inject$1(LocaleSymbol);
  2488. if (!locale) throw new Error('[Vuetify] Could not find injected locale instance');
  2489. return locale;
  2490. }
  2491. function provideLocale(props) {
  2492. const locale = inject$1(LocaleSymbol);
  2493. if (!locale) throw new Error('[Vuetify] Could not find injected locale instance');
  2494. const i18n = locale.provide(props);
  2495. const rtl = provideRtl(i18n, locale.rtl, props);
  2496. const data = {
  2497. ...i18n,
  2498. ...rtl
  2499. };
  2500. provide(LocaleSymbol, data);
  2501. return data;
  2502. }
  2503. function genDefaults$2() {
  2504. return {
  2505. af: false,
  2506. ar: true,
  2507. bg: false,
  2508. ca: false,
  2509. ckb: false,
  2510. cs: false,
  2511. de: false,
  2512. el: false,
  2513. en: false,
  2514. es: false,
  2515. et: false,
  2516. fa: true,
  2517. fi: false,
  2518. fr: false,
  2519. hr: false,
  2520. hu: false,
  2521. he: true,
  2522. id: false,
  2523. it: false,
  2524. ja: false,
  2525. km: false,
  2526. ko: false,
  2527. lv: false,
  2528. lt: false,
  2529. nl: false,
  2530. no: false,
  2531. pl: false,
  2532. pt: false,
  2533. ro: false,
  2534. ru: false,
  2535. sk: false,
  2536. sl: false,
  2537. srCyrl: false,
  2538. srLatn: false,
  2539. sv: false,
  2540. th: false,
  2541. tr: false,
  2542. az: false,
  2543. uk: false,
  2544. vi: false,
  2545. zhHans: false,
  2546. zhHant: false
  2547. };
  2548. }
  2549. function createRtl(i18n, options) {
  2550. const rtl = ref(options?.rtl ?? genDefaults$2());
  2551. const isRtl = computed(() => rtl.value[i18n.current.value] ?? false);
  2552. return {
  2553. isRtl,
  2554. rtl,
  2555. rtlClasses: computed(() => `v-locale--is-${isRtl.value ? 'rtl' : 'ltr'}`)
  2556. };
  2557. }
  2558. function provideRtl(locale, rtl, props) {
  2559. const isRtl = computed(() => props.rtl ?? rtl.value[locale.current.value] ?? false);
  2560. return {
  2561. isRtl,
  2562. rtl,
  2563. rtlClasses: computed(() => `v-locale--is-${isRtl.value ? 'rtl' : 'ltr'}`)
  2564. };
  2565. }
  2566. function useRtl() {
  2567. const locale = inject$1(LocaleSymbol);
  2568. if (!locale) throw new Error('[Vuetify] Could not find injected rtl instance');
  2569. return {
  2570. isRtl: locale.isRtl,
  2571. rtlClasses: locale.rtlClasses
  2572. };
  2573. }
  2574. // Utilities
  2575. // Types
  2576. const ThemeSymbol = Symbol.for('vuetify:theme');
  2577. const makeThemeProps = propsFactory({
  2578. theme: String
  2579. }, 'theme');
  2580. function genDefaults$1() {
  2581. return {
  2582. defaultTheme: 'light',
  2583. variations: {
  2584. colors: [],
  2585. lighten: 0,
  2586. darken: 0
  2587. },
  2588. themes: {
  2589. light: {
  2590. dark: false,
  2591. colors: {
  2592. background: '#FFFFFF',
  2593. surface: '#FFFFFF',
  2594. 'surface-bright': '#FFFFFF',
  2595. 'surface-light': '#EEEEEE',
  2596. 'surface-variant': '#424242',
  2597. 'on-surface-variant': '#EEEEEE',
  2598. primary: '#1867C0',
  2599. 'primary-darken-1': '#1F5592',
  2600. secondary: '#48A9A6',
  2601. 'secondary-darken-1': '#018786',
  2602. error: '#B00020',
  2603. info: '#2196F3',
  2604. success: '#4CAF50',
  2605. warning: '#FB8C00'
  2606. },
  2607. variables: {
  2608. 'border-color': '#000000',
  2609. 'border-opacity': 0.12,
  2610. 'high-emphasis-opacity': 0.87,
  2611. 'medium-emphasis-opacity': 0.60,
  2612. 'disabled-opacity': 0.38,
  2613. 'idle-opacity': 0.04,
  2614. 'hover-opacity': 0.04,
  2615. 'focus-opacity': 0.12,
  2616. 'selected-opacity': 0.08,
  2617. 'activated-opacity': 0.12,
  2618. 'pressed-opacity': 0.12,
  2619. 'dragged-opacity': 0.08,
  2620. 'theme-kbd': '#212529',
  2621. 'theme-on-kbd': '#FFFFFF',
  2622. 'theme-code': '#F5F5F5',
  2623. 'theme-on-code': '#000000'
  2624. }
  2625. },
  2626. dark: {
  2627. dark: true,
  2628. colors: {
  2629. background: '#121212',
  2630. surface: '#212121',
  2631. 'surface-bright': '#ccbfd6',
  2632. 'surface-light': '#424242',
  2633. 'surface-variant': '#a3a3a3',
  2634. 'on-surface-variant': '#424242',
  2635. primary: '#2196F3',
  2636. 'primary-darken-1': '#277CC1',
  2637. secondary: '#54B6B2',
  2638. 'secondary-darken-1': '#48A9A6',
  2639. error: '#CF6679',
  2640. info: '#2196F3',
  2641. success: '#4CAF50',
  2642. warning: '#FB8C00'
  2643. },
  2644. variables: {
  2645. 'border-color': '#FFFFFF',
  2646. 'border-opacity': 0.12,
  2647. 'high-emphasis-opacity': 1,
  2648. 'medium-emphasis-opacity': 0.70,
  2649. 'disabled-opacity': 0.50,
  2650. 'idle-opacity': 0.10,
  2651. 'hover-opacity': 0.04,
  2652. 'focus-opacity': 0.12,
  2653. 'selected-opacity': 0.08,
  2654. 'activated-opacity': 0.12,
  2655. 'pressed-opacity': 0.16,
  2656. 'dragged-opacity': 0.08,
  2657. 'theme-kbd': '#212529',
  2658. 'theme-on-kbd': '#FFFFFF',
  2659. 'theme-code': '#343434',
  2660. 'theme-on-code': '#CCCCCC'
  2661. }
  2662. }
  2663. }
  2664. };
  2665. }
  2666. function parseThemeOptions() {
  2667. let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : genDefaults$1();
  2668. const defaults = genDefaults$1();
  2669. if (!options) return {
  2670. ...defaults,
  2671. isDisabled: true
  2672. };
  2673. const themes = {};
  2674. for (const [key, theme] of Object.entries(options.themes ?? {})) {
  2675. const defaultTheme = theme.dark || key === 'dark' ? defaults.themes?.dark : defaults.themes?.light;
  2676. themes[key] = mergeDeep(defaultTheme, theme);
  2677. }
  2678. return mergeDeep(defaults, {
  2679. ...options,
  2680. themes
  2681. });
  2682. }
  2683. // Composables
  2684. function createTheme(options) {
  2685. const parsedOptions = parseThemeOptions(options);
  2686. const name = ref(parsedOptions.defaultTheme);
  2687. const themes = ref(parsedOptions.themes);
  2688. const computedThemes = computed(() => {
  2689. const acc = {};
  2690. for (const [name, original] of Object.entries(themes.value)) {
  2691. const theme = acc[name] = {
  2692. ...original,
  2693. colors: {
  2694. ...original.colors
  2695. }
  2696. };
  2697. if (parsedOptions.variations) {
  2698. for (const name of parsedOptions.variations.colors) {
  2699. const color = theme.colors[name];
  2700. if (!color) continue;
  2701. for (const variation of ['lighten', 'darken']) {
  2702. const fn = variation === 'lighten' ? lighten : darken;
  2703. for (const amount of createRange(parsedOptions.variations[variation], 1)) {
  2704. theme.colors[`${name}-${variation}-${amount}`] = RGBtoHex(fn(parseColor(color), amount));
  2705. }
  2706. }
  2707. }
  2708. }
  2709. for (const color of Object.keys(theme.colors)) {
  2710. if (/^on-[a-z]/.test(color) || theme.colors[`on-${color}`]) continue;
  2711. const onColor = `on-${color}`;
  2712. const colorVal = parseColor(theme.colors[color]);
  2713. theme.colors[onColor] = getForeground(colorVal);
  2714. }
  2715. }
  2716. return acc;
  2717. });
  2718. const current = computed(() => computedThemes.value[name.value]);
  2719. const styles = computed(() => {
  2720. const lines = [];
  2721. if (current.value?.dark) {
  2722. createCssClass(lines, ':root', ['color-scheme: dark']);
  2723. }
  2724. createCssClass(lines, ':root', genCssVariables(current.value));
  2725. for (const [themeName, theme] of Object.entries(computedThemes.value)) {
  2726. createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)]);
  2727. }
  2728. const bgLines = [];
  2729. const fgLines = [];
  2730. const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
  2731. for (const key of colors) {
  2732. if (/^on-[a-z]/.test(key)) {
  2733. createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`]);
  2734. } else {
  2735. createCssClass(bgLines, `.bg-${key}`, [`--v-theme-overlay-multiplier: var(--v-theme-${key}-overlay-multiplier)`, `background-color: rgb(var(--v-theme-${key})) !important`, `color: rgb(var(--v-theme-on-${key})) !important`]);
  2736. createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`]);
  2737. createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`]);
  2738. }
  2739. }
  2740. lines.push(...bgLines, ...fgLines);
  2741. return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
  2742. });
  2743. function getHead() {
  2744. return {
  2745. style: [{
  2746. children: styles.value,
  2747. id: 'vuetify-theme-stylesheet',
  2748. nonce: parsedOptions.cspNonce || false
  2749. }]
  2750. };
  2751. }
  2752. function install(app) {
  2753. if (parsedOptions.isDisabled) return;
  2754. const head = app._context.provides.usehead;
  2755. if (head) {
  2756. if (head.push) {
  2757. const entry = head.push(getHead);
  2758. if (IN_BROWSER) {
  2759. watch(styles, () => {
  2760. entry.patch(getHead);
  2761. });
  2762. }
  2763. } else {
  2764. if (IN_BROWSER) {
  2765. head.addHeadObjs(computed(getHead));
  2766. watchEffect(() => head.updateDOM());
  2767. } else {
  2768. head.addHeadObjs(getHead());
  2769. }
  2770. }
  2771. } else {
  2772. let styleEl = IN_BROWSER ? document.getElementById('vuetify-theme-stylesheet') : null;
  2773. if (IN_BROWSER) {
  2774. watch(styles, updateStyles, {
  2775. immediate: true
  2776. });
  2777. } else {
  2778. updateStyles();
  2779. }
  2780. function updateStyles() {
  2781. if (typeof document !== 'undefined' && !styleEl) {
  2782. const el = document.createElement('style');
  2783. el.type = 'text/css';
  2784. el.id = 'vuetify-theme-stylesheet';
  2785. if (parsedOptions.cspNonce) el.setAttribute('nonce', parsedOptions.cspNonce);
  2786. styleEl = el;
  2787. document.head.appendChild(styleEl);
  2788. }
  2789. if (styleEl) styleEl.innerHTML = styles.value;
  2790. }
  2791. }
  2792. }
  2793. const themeClasses = computed(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
  2794. return {
  2795. install,
  2796. isDisabled: parsedOptions.isDisabled,
  2797. name,
  2798. themes,
  2799. current,
  2800. computedThemes,
  2801. themeClasses,
  2802. styles,
  2803. global: {
  2804. name,
  2805. current
  2806. }
  2807. };
  2808. }
  2809. function provideTheme(props) {
  2810. getCurrentInstance('provideTheme');
  2811. const theme = inject$1(ThemeSymbol, null);
  2812. if (!theme) throw new Error('Could not find Vuetify theme injection');
  2813. const name = computed(() => {
  2814. return props.theme ?? theme.name.value;
  2815. });
  2816. const current = computed(() => theme.themes.value[name.value]);
  2817. const themeClasses = computed(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
  2818. const newTheme = {
  2819. ...theme,
  2820. name,
  2821. current,
  2822. themeClasses
  2823. };
  2824. provide(ThemeSymbol, newTheme);
  2825. return newTheme;
  2826. }
  2827. function useTheme() {
  2828. getCurrentInstance('useTheme');
  2829. const theme = inject$1(ThemeSymbol, null);
  2830. if (!theme) throw new Error('Could not find Vuetify theme injection');
  2831. return theme;
  2832. }
  2833. function createCssClass(lines, selector, content) {
  2834. lines.push(`${selector} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
  2835. }
  2836. function genCssVariables(theme) {
  2837. const lightOverlay = theme.dark ? 2 : 1;
  2838. const darkOverlay = theme.dark ? 1 : 2;
  2839. const variables = [];
  2840. for (const [key, value] of Object.entries(theme.colors)) {
  2841. const rgb = parseColor(value);
  2842. variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
  2843. if (!key.startsWith('on-')) {
  2844. variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
  2845. }
  2846. }
  2847. for (const [key, value] of Object.entries(theme.variables)) {
  2848. const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
  2849. const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
  2850. variables.push(`--v-${key}: ${rgb ?? value}`);
  2851. }
  2852. return variables;
  2853. }
  2854. const makeVAppProps = propsFactory({
  2855. ...makeComponentProps(),
  2856. ...makeLayoutProps({
  2857. fullHeight: true
  2858. }),
  2859. ...makeThemeProps()
  2860. }, 'VApp');
  2861. const VApp = genericComponent()({
  2862. name: 'VApp',
  2863. props: makeVAppProps(),
  2864. setup(props, _ref) {
  2865. let {
  2866. slots
  2867. } = _ref;
  2868. const theme = provideTheme(props);
  2869. const {
  2870. layoutClasses,
  2871. getLayoutItem,
  2872. items,
  2873. layoutRef
  2874. } = createLayout(props);
  2875. const {
  2876. rtlClasses
  2877. } = useRtl();
  2878. useRender(() => createVNode("div", {
  2879. "ref": layoutRef,
  2880. "class": ['v-application', theme.themeClasses.value, layoutClasses.value, rtlClasses.value, props.class],
  2881. "style": [props.style]
  2882. }, [createVNode("div", {
  2883. "class": "v-application__wrap"
  2884. }, [slots.default?.()])]));
  2885. return {
  2886. getLayoutItem,
  2887. items,
  2888. theme
  2889. };
  2890. }
  2891. });
  2892. // Utilities
  2893. // Types
  2894. // Composables
  2895. const makeTagProps = propsFactory({
  2896. tag: {
  2897. type: String,
  2898. default: 'div'
  2899. }
  2900. }, 'tag');
  2901. const makeVToolbarTitleProps = propsFactory({
  2902. text: String,
  2903. ...makeComponentProps(),
  2904. ...makeTagProps()
  2905. }, 'VToolbarTitle');
  2906. const VToolbarTitle = genericComponent()({
  2907. name: 'VToolbarTitle',
  2908. props: makeVToolbarTitleProps(),
  2909. setup(props, _ref) {
  2910. let {
  2911. slots
  2912. } = _ref;
  2913. useRender(() => {
  2914. const hasText = !!(slots.default || slots.text || props.text);
  2915. return createVNode(props.tag, {
  2916. "class": ['v-toolbar-title', props.class],
  2917. "style": props.style
  2918. }, {
  2919. default: () => [hasText && createVNode("div", {
  2920. "class": "v-toolbar-title__placeholder"
  2921. }, [slots.text ? slots.text() : props.text, slots.default?.()])]
  2922. });
  2923. });
  2924. return {};
  2925. }
  2926. });
  2927. // Utilities
  2928. // Types
  2929. const makeTransitionProps$1 = propsFactory({
  2930. disabled: Boolean,
  2931. group: Boolean,
  2932. hideOnLeave: Boolean,
  2933. leaveAbsolute: Boolean,
  2934. mode: String,
  2935. origin: String
  2936. }, 'transition');
  2937. function createCssTransition(name, origin, mode) {
  2938. return genericComponent()({
  2939. name,
  2940. props: makeTransitionProps$1({
  2941. mode,
  2942. origin
  2943. }),
  2944. setup(props, _ref) {
  2945. let {
  2946. slots
  2947. } = _ref;
  2948. const functions = {
  2949. onBeforeEnter(el) {
  2950. if (props.origin) {
  2951. el.style.transformOrigin = props.origin;
  2952. }
  2953. },
  2954. onLeave(el) {
  2955. if (props.leaveAbsolute) {
  2956. const {
  2957. offsetTop,
  2958. offsetLeft,
  2959. offsetWidth,
  2960. offsetHeight
  2961. } = el;
  2962. el._transitionInitialStyles = {
  2963. position: el.style.position,
  2964. top: el.style.top,
  2965. left: el.style.left,
  2966. width: el.style.width,
  2967. height: el.style.height
  2968. };
  2969. el.style.position = 'absolute';
  2970. el.style.top = `${offsetTop}px`;
  2971. el.style.left = `${offsetLeft}px`;
  2972. el.style.width = `${offsetWidth}px`;
  2973. el.style.height = `${offsetHeight}px`;
  2974. }
  2975. if (props.hideOnLeave) {
  2976. el.style.setProperty('display', 'none', 'important');
  2977. }
  2978. },
  2979. onAfterLeave(el) {
  2980. if (props.leaveAbsolute && el?._transitionInitialStyles) {
  2981. const {
  2982. position,
  2983. top,
  2984. left,
  2985. width,
  2986. height
  2987. } = el._transitionInitialStyles;
  2988. delete el._transitionInitialStyles;
  2989. el.style.position = position || '';
  2990. el.style.top = top || '';
  2991. el.style.left = left || '';
  2992. el.style.width = width || '';
  2993. el.style.height = height || '';
  2994. }
  2995. }
  2996. };
  2997. return () => {
  2998. const tag = props.group ? TransitionGroup : Transition;
  2999. return h(tag, {
  3000. name: props.disabled ? '' : name,
  3001. css: !props.disabled,
  3002. ...(props.group ? undefined : {
  3003. mode: props.mode
  3004. }),
  3005. ...(props.disabled ? {} : functions)
  3006. }, slots.default);
  3007. };
  3008. }
  3009. });
  3010. }
  3011. function createJavascriptTransition(name, functions) {
  3012. let mode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'in-out';
  3013. return genericComponent()({
  3014. name,
  3015. props: {
  3016. mode: {
  3017. type: String,
  3018. default: mode
  3019. },
  3020. disabled: Boolean,
  3021. group: Boolean
  3022. },
  3023. setup(props, _ref2) {
  3024. let {
  3025. slots
  3026. } = _ref2;
  3027. const tag = props.group ? TransitionGroup : Transition;
  3028. return () => {
  3029. return h(tag, {
  3030. name: props.disabled ? '' : name,
  3031. css: !props.disabled,
  3032. // mode: props.mode, // TODO: vuejs/vue-next#3104
  3033. ...(props.disabled ? {} : functions)
  3034. }, slots.default);
  3035. };
  3036. }
  3037. });
  3038. }
  3039. // Utilities
  3040. function ExpandTransitionGenerator () {
  3041. let expandedParentClass = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  3042. let x = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  3043. const sizeProperty = x ? 'width' : 'height';
  3044. const offsetProperty = camelize(`offset-${sizeProperty}`);
  3045. return {
  3046. onBeforeEnter(el) {
  3047. el._parent = el.parentNode;
  3048. el._initialStyle = {
  3049. transition: el.style.transition,
  3050. overflow: el.style.overflow,
  3051. [sizeProperty]: el.style[sizeProperty]
  3052. };
  3053. },
  3054. onEnter(el) {
  3055. const initialStyle = el._initialStyle;
  3056. el.style.setProperty('transition', 'none', 'important');
  3057. // Hide overflow to account for collapsed margins in the calculated height
  3058. el.style.overflow = 'hidden';
  3059. const offset = `${el[offsetProperty]}px`;
  3060. el.style[sizeProperty] = '0';
  3061. void el.offsetHeight; // force reflow
  3062. el.style.transition = initialStyle.transition;
  3063. if (expandedParentClass && el._parent) {
  3064. el._parent.classList.add(expandedParentClass);
  3065. }
  3066. requestAnimationFrame(() => {
  3067. el.style[sizeProperty] = offset;
  3068. });
  3069. },
  3070. onAfterEnter: resetStyles,
  3071. onEnterCancelled: resetStyles,
  3072. onLeave(el) {
  3073. el._initialStyle = {
  3074. transition: '',
  3075. overflow: el.style.overflow,
  3076. [sizeProperty]: el.style[sizeProperty]
  3077. };
  3078. el.style.overflow = 'hidden';
  3079. el.style[sizeProperty] = `${el[offsetProperty]}px`;
  3080. void el.offsetHeight; // force reflow
  3081. requestAnimationFrame(() => el.style[sizeProperty] = '0');
  3082. },
  3083. onAfterLeave,
  3084. onLeaveCancelled: onAfterLeave
  3085. };
  3086. function onAfterLeave(el) {
  3087. if (expandedParentClass && el._parent) {
  3088. el._parent.classList.remove(expandedParentClass);
  3089. }
  3090. resetStyles(el);
  3091. }
  3092. function resetStyles(el) {
  3093. const size = el._initialStyle[sizeProperty];
  3094. el.style.overflow = el._initialStyle.overflow;
  3095. if (size != null) el.style[sizeProperty] = size;
  3096. delete el._initialStyle;
  3097. }
  3098. }
  3099. // Types
  3100. const makeVDialogTransitionProps = propsFactory({
  3101. target: [Object, Array]
  3102. }, 'v-dialog-transition');
  3103. const VDialogTransition = genericComponent()({
  3104. name: 'VDialogTransition',
  3105. props: makeVDialogTransitionProps(),
  3106. setup(props, _ref) {
  3107. let {
  3108. slots
  3109. } = _ref;
  3110. const functions = {
  3111. onBeforeEnter(el) {
  3112. el.style.pointerEvents = 'none';
  3113. el.style.visibility = 'hidden';
  3114. },
  3115. async onEnter(el, done) {
  3116. await new Promise(resolve => requestAnimationFrame(resolve));
  3117. await new Promise(resolve => requestAnimationFrame(resolve));
  3118. el.style.visibility = '';
  3119. const {
  3120. x,
  3121. y,
  3122. sx,
  3123. sy,
  3124. speed
  3125. } = getDimensions(props.target, el);
  3126. const animation = animate(el, [{
  3127. transform: `translate(${x}px, ${y}px) scale(${sx}, ${sy})`,
  3128. opacity: 0
  3129. }, {}], {
  3130. duration: 225 * speed,
  3131. easing: deceleratedEasing
  3132. });
  3133. getChildren(el)?.forEach(el => {
  3134. animate(el, [{
  3135. opacity: 0
  3136. }, {
  3137. opacity: 0,
  3138. offset: 0.33
  3139. }, {}], {
  3140. duration: 225 * 2 * speed,
  3141. easing: standardEasing
  3142. });
  3143. });
  3144. animation.finished.then(() => done());
  3145. },
  3146. onAfterEnter(el) {
  3147. el.style.removeProperty('pointer-events');
  3148. },
  3149. onBeforeLeave(el) {
  3150. el.style.pointerEvents = 'none';
  3151. },
  3152. async onLeave(el, done) {
  3153. await new Promise(resolve => requestAnimationFrame(resolve));
  3154. const {
  3155. x,
  3156. y,
  3157. sx,
  3158. sy,
  3159. speed
  3160. } = getDimensions(props.target, el);
  3161. const animation = animate(el, [{}, {
  3162. transform: `translate(${x}px, ${y}px) scale(${sx}, ${sy})`,
  3163. opacity: 0
  3164. }], {
  3165. duration: 125 * speed,
  3166. easing: acceleratedEasing
  3167. });
  3168. animation.finished.then(() => done());
  3169. getChildren(el)?.forEach(el => {
  3170. animate(el, [{}, {
  3171. opacity: 0,
  3172. offset: 0.2
  3173. }, {
  3174. opacity: 0
  3175. }], {
  3176. duration: 125 * 2 * speed,
  3177. easing: standardEasing
  3178. });
  3179. });
  3180. },
  3181. onAfterLeave(el) {
  3182. el.style.removeProperty('pointer-events');
  3183. }
  3184. };
  3185. return () => {
  3186. return props.target ? createVNode(Transition, mergeProps({
  3187. "name": "dialog-transition"
  3188. }, functions, {
  3189. "css": false
  3190. }), slots) : createVNode(Transition, {
  3191. "name": "dialog-transition"
  3192. }, slots);
  3193. };
  3194. }
  3195. });
  3196. /** Animatable children (card, sheet, list) */
  3197. function getChildren(el) {
  3198. const els = el.querySelector(':scope > .v-card, :scope > .v-sheet, :scope > .v-list')?.children;
  3199. return els && [...els];
  3200. }
  3201. function getDimensions(target, el) {
  3202. const targetBox = getTargetBox(target);
  3203. const elBox = nullifyTransforms(el);
  3204. const [originX, originY] = getComputedStyle(el).transformOrigin.split(' ').map(v => parseFloat(v));
  3205. const [anchorSide, anchorOffset] = getComputedStyle(el).getPropertyValue('--v-overlay-anchor-origin').split(' ');
  3206. let offsetX = targetBox.left + targetBox.width / 2;
  3207. if (anchorSide === 'left' || anchorOffset === 'left') {
  3208. offsetX -= targetBox.width / 2;
  3209. } else if (anchorSide === 'right' || anchorOffset === 'right') {
  3210. offsetX += targetBox.width / 2;
  3211. }
  3212. let offsetY = targetBox.top + targetBox.height / 2;
  3213. if (anchorSide === 'top' || anchorOffset === 'top') {
  3214. offsetY -= targetBox.height / 2;
  3215. } else if (anchorSide === 'bottom' || anchorOffset === 'bottom') {
  3216. offsetY += targetBox.height / 2;
  3217. }
  3218. const tsx = targetBox.width / elBox.width;
  3219. const tsy = targetBox.height / elBox.height;
  3220. const maxs = Math.max(1, tsx, tsy);
  3221. const sx = tsx / maxs || 0;
  3222. const sy = tsy / maxs || 0;
  3223. // Animate elements larger than 12% of the screen area up to 1.5x slower
  3224. const asa = elBox.width * elBox.height / (window.innerWidth * window.innerHeight);
  3225. const speed = asa > 0.12 ? Math.min(1.5, (asa - 0.12) * 10 + 1) : 1;
  3226. return {
  3227. x: offsetX - (originX + elBox.left),
  3228. y: offsetY - (originY + elBox.top),
  3229. sx,
  3230. sy,
  3231. speed
  3232. };
  3233. }
  3234. // Component specific transitions
  3235. const VFabTransition = createCssTransition('fab-transition', 'center center', 'out-in');
  3236. // Generic transitions
  3237. const VDialogBottomTransition = createCssTransition('dialog-bottom-transition');
  3238. const VDialogTopTransition = createCssTransition('dialog-top-transition');
  3239. const VFadeTransition = createCssTransition('fade-transition');
  3240. const VScaleTransition = createCssTransition('scale-transition');
  3241. const VScrollXTransition = createCssTransition('scroll-x-transition');
  3242. const VScrollXReverseTransition = createCssTransition('scroll-x-reverse-transition');
  3243. const VScrollYTransition = createCssTransition('scroll-y-transition');
  3244. const VScrollYReverseTransition = createCssTransition('scroll-y-reverse-transition');
  3245. const VSlideXTransition = createCssTransition('slide-x-transition');
  3246. const VSlideXReverseTransition = createCssTransition('slide-x-reverse-transition');
  3247. const VSlideYTransition = createCssTransition('slide-y-transition');
  3248. const VSlideYReverseTransition = createCssTransition('slide-y-reverse-transition');
  3249. // Javascript transitions
  3250. const VExpandTransition = createJavascriptTransition('expand-transition', ExpandTransitionGenerator());
  3251. const VExpandXTransition = createJavascriptTransition('expand-x-transition', ExpandTransitionGenerator('', true));
  3252. // Composables
  3253. // Types
  3254. const makeVDefaultsProviderProps = propsFactory({
  3255. defaults: Object,
  3256. disabled: Boolean,
  3257. reset: [Number, String],
  3258. root: [Boolean, String],
  3259. scoped: Boolean
  3260. }, 'VDefaultsProvider');
  3261. const VDefaultsProvider = genericComponent(false)({
  3262. name: 'VDefaultsProvider',
  3263. props: makeVDefaultsProviderProps(),
  3264. setup(props, _ref) {
  3265. let {
  3266. slots
  3267. } = _ref;
  3268. const {
  3269. defaults,
  3270. disabled,
  3271. reset,
  3272. root,
  3273. scoped
  3274. } = toRefs(props);
  3275. provideDefaults(defaults, {
  3276. reset,
  3277. root,
  3278. scoped,
  3279. disabled
  3280. });
  3281. return () => slots.default?.();
  3282. }
  3283. });
  3284. // Utilities
  3285. // Types
  3286. // Composables
  3287. const makeDimensionProps = propsFactory({
  3288. height: [Number, String],
  3289. maxHeight: [Number, String],
  3290. maxWidth: [Number, String],
  3291. minHeight: [Number, String],
  3292. minWidth: [Number, String],
  3293. width: [Number, String]
  3294. }, 'dimension');
  3295. function useDimension(props) {
  3296. const dimensionStyles = computed(() => {
  3297. const styles = {};
  3298. const height = convertToUnit(props.height);
  3299. const maxHeight = convertToUnit(props.maxHeight);
  3300. const maxWidth = convertToUnit(props.maxWidth);
  3301. const minHeight = convertToUnit(props.minHeight);
  3302. const minWidth = convertToUnit(props.minWidth);
  3303. const width = convertToUnit(props.width);
  3304. if (height != null) styles.height = height;
  3305. if (maxHeight != null) styles.maxHeight = maxHeight;
  3306. if (maxWidth != null) styles.maxWidth = maxWidth;
  3307. if (minHeight != null) styles.minHeight = minHeight;
  3308. if (minWidth != null) styles.minWidth = minWidth;
  3309. if (width != null) styles.width = width;
  3310. return styles;
  3311. });
  3312. return {
  3313. dimensionStyles
  3314. };
  3315. }
  3316. function useAspectStyles(props) {
  3317. return {
  3318. aspectStyles: computed(() => {
  3319. const ratio = Number(props.aspectRatio);
  3320. return ratio ? {
  3321. paddingBottom: String(1 / ratio * 100) + '%'
  3322. } : undefined;
  3323. })
  3324. };
  3325. }
  3326. const makeVResponsiveProps = propsFactory({
  3327. aspectRatio: [String, Number],
  3328. contentClass: null,
  3329. inline: Boolean,
  3330. ...makeComponentProps(),
  3331. ...makeDimensionProps()
  3332. }, 'VResponsive');
  3333. const VResponsive = genericComponent()({
  3334. name: 'VResponsive',
  3335. props: makeVResponsiveProps(),
  3336. setup(props, _ref) {
  3337. let {
  3338. slots
  3339. } = _ref;
  3340. const {
  3341. aspectStyles
  3342. } = useAspectStyles(props);
  3343. const {
  3344. dimensionStyles
  3345. } = useDimension(props);
  3346. useRender(() => createVNode("div", {
  3347. "class": ['v-responsive', {
  3348. 'v-responsive--inline': props.inline
  3349. }, props.class],
  3350. "style": [dimensionStyles.value, props.style]
  3351. }, [createVNode("div", {
  3352. "class": "v-responsive__sizer",
  3353. "style": aspectStyles.value
  3354. }, null), slots.additional?.(), slots.default && createVNode("div", {
  3355. "class": ['v-responsive__content', props.contentClass]
  3356. }, [slots.default()])]));
  3357. return {};
  3358. }
  3359. });
  3360. // Utilities
  3361. // Types
  3362. // Composables
  3363. function useColor(colors) {
  3364. return destructComputed(() => {
  3365. const classes = [];
  3366. const styles = {};
  3367. if (colors.value.background) {
  3368. if (isCssColor(colors.value.background)) {
  3369. styles.backgroundColor = colors.value.background;
  3370. if (!colors.value.text && isParsableColor(colors.value.background)) {
  3371. const backgroundColor = parseColor(colors.value.background);
  3372. if (backgroundColor.a == null || backgroundColor.a === 1) {
  3373. const textColor = getForeground(backgroundColor);
  3374. styles.color = textColor;
  3375. styles.caretColor = textColor;
  3376. }
  3377. }
  3378. } else {
  3379. classes.push(`bg-${colors.value.background}`);
  3380. }
  3381. }
  3382. if (colors.value.text) {
  3383. if (isCssColor(colors.value.text)) {
  3384. styles.color = colors.value.text;
  3385. styles.caretColor = colors.value.text;
  3386. } else {
  3387. classes.push(`text-${colors.value.text}`);
  3388. }
  3389. }
  3390. return {
  3391. colorClasses: classes,
  3392. colorStyles: styles
  3393. };
  3394. });
  3395. }
  3396. function useTextColor(props, name) {
  3397. const colors = computed(() => ({
  3398. text: isRef(props) ? props.value : name ? props[name] : null
  3399. }));
  3400. const {
  3401. colorClasses: textColorClasses,
  3402. colorStyles: textColorStyles
  3403. } = useColor(colors);
  3404. return {
  3405. textColorClasses,
  3406. textColorStyles
  3407. };
  3408. }
  3409. function useBackgroundColor(props, name) {
  3410. const colors = computed(() => ({
  3411. background: isRef(props) ? props.value : name ? props[name] : null
  3412. }));
  3413. const {
  3414. colorClasses: backgroundColorClasses,
  3415. colorStyles: backgroundColorStyles
  3416. } = useColor(colors);
  3417. return {
  3418. backgroundColorClasses,
  3419. backgroundColorStyles
  3420. };
  3421. }
  3422. // Utilities
  3423. // Types
  3424. // Composables
  3425. const makeRoundedProps = propsFactory({
  3426. rounded: {
  3427. type: [Boolean, Number, String],
  3428. default: undefined
  3429. },
  3430. tile: Boolean
  3431. }, 'rounded');
  3432. function useRounded(props) {
  3433. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  3434. const roundedClasses = computed(() => {
  3435. const rounded = isRef(props) ? props.value : props.rounded;
  3436. const tile = isRef(props) ? props.value : props.tile;
  3437. const classes = [];
  3438. if (rounded === true || rounded === '') {
  3439. classes.push(`${name}--rounded`);
  3440. } else if (typeof rounded === 'string' || rounded === 0) {
  3441. for (const value of String(rounded).split(' ')) {
  3442. classes.push(`rounded-${value}`);
  3443. }
  3444. } else if (tile || rounded === false) {
  3445. classes.push('rounded-0');
  3446. }
  3447. return classes;
  3448. });
  3449. return {
  3450. roundedClasses
  3451. };
  3452. }
  3453. // Utilities
  3454. // Types
  3455. const makeTransitionProps = propsFactory({
  3456. transition: {
  3457. type: [Boolean, String, Object],
  3458. default: 'fade-transition',
  3459. validator: val => val !== true
  3460. }
  3461. }, 'transition');
  3462. const MaybeTransition = (props, _ref) => {
  3463. let {
  3464. slots
  3465. } = _ref;
  3466. const {
  3467. transition,
  3468. disabled,
  3469. group,
  3470. ...rest
  3471. } = props;
  3472. const {
  3473. component = group ? TransitionGroup : Transition,
  3474. ...customProps
  3475. } = typeof transition === 'object' ? transition : {};
  3476. return h(component, mergeProps(typeof transition === 'string' ? {
  3477. name: disabled ? '' : transition
  3478. } : customProps, typeof transition === 'string' ? {} : Object.fromEntries(Object.entries({
  3479. disabled,
  3480. group
  3481. }).filter(_ref2 => {
  3482. let [_, v] = _ref2;
  3483. return v !== undefined;
  3484. })), rest), slots);
  3485. };
  3486. // Utilities
  3487. // Types
  3488. function mounted$5(el, binding) {
  3489. if (!SUPPORTS_INTERSECTION) return;
  3490. const modifiers = binding.modifiers || {};
  3491. const value = binding.value;
  3492. const {
  3493. handler,
  3494. options
  3495. } = typeof value === 'object' ? value : {
  3496. handler: value,
  3497. options: {}
  3498. };
  3499. const observer = new IntersectionObserver(function () {
  3500. let entries = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  3501. let observer = arguments.length > 1 ? arguments[1] : undefined;
  3502. const _observe = el._observe?.[binding.instance.$.uid];
  3503. if (!_observe) return; // Just in case, should never fire
  3504. const isIntersecting = entries.some(entry => entry.isIntersecting);
  3505. // If is not quiet or has already been
  3506. // initted, invoke the user callback
  3507. if (handler && (!modifiers.quiet || _observe.init) && (!modifiers.once || isIntersecting || _observe.init)) {
  3508. handler(isIntersecting, entries, observer);
  3509. }
  3510. if (isIntersecting && modifiers.once) unmounted$5(el, binding);else _observe.init = true;
  3511. }, options);
  3512. el._observe = Object(el._observe);
  3513. el._observe[binding.instance.$.uid] = {
  3514. init: false,
  3515. observer
  3516. };
  3517. observer.observe(el);
  3518. }
  3519. function unmounted$5(el, binding) {
  3520. const observe = el._observe?.[binding.instance.$.uid];
  3521. if (!observe) return;
  3522. observe.observer.unobserve(el);
  3523. delete el._observe[binding.instance.$.uid];
  3524. }
  3525. const Intersect = {
  3526. mounted: mounted$5,
  3527. unmounted: unmounted$5
  3528. };
  3529. // Types
  3530. // not intended for public use, this is passed in by vuetify-loader
  3531. const makeVImgProps = propsFactory({
  3532. absolute: Boolean,
  3533. alt: String,
  3534. cover: Boolean,
  3535. color: String,
  3536. draggable: {
  3537. type: [Boolean, String],
  3538. default: undefined
  3539. },
  3540. eager: Boolean,
  3541. gradient: String,
  3542. lazySrc: String,
  3543. options: {
  3544. type: Object,
  3545. // For more information on types, navigate to:
  3546. // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
  3547. default: () => ({
  3548. root: undefined,
  3549. rootMargin: undefined,
  3550. threshold: undefined
  3551. })
  3552. },
  3553. sizes: String,
  3554. src: {
  3555. type: [String, Object],
  3556. default: ''
  3557. },
  3558. crossorigin: String,
  3559. referrerpolicy: String,
  3560. srcset: String,
  3561. position: String,
  3562. ...makeVResponsiveProps(),
  3563. ...makeComponentProps(),
  3564. ...makeRoundedProps(),
  3565. ...makeTransitionProps()
  3566. }, 'VImg');
  3567. const VImg = genericComponent()({
  3568. name: 'VImg',
  3569. directives: {
  3570. intersect: Intersect
  3571. },
  3572. props: makeVImgProps(),
  3573. emits: {
  3574. loadstart: value => true,
  3575. load: value => true,
  3576. error: value => true
  3577. },
  3578. setup(props, _ref) {
  3579. let {
  3580. emit,
  3581. slots
  3582. } = _ref;
  3583. const {
  3584. backgroundColorClasses,
  3585. backgroundColorStyles
  3586. } = useBackgroundColor(toRef(props, 'color'));
  3587. const {
  3588. roundedClasses
  3589. } = useRounded(props);
  3590. const vm = getCurrentInstance('VImg');
  3591. const currentSrc = shallowRef(''); // Set from srcset
  3592. const image = ref();
  3593. const state = shallowRef(props.eager ? 'loading' : 'idle');
  3594. const naturalWidth = shallowRef();
  3595. const naturalHeight = shallowRef();
  3596. const normalisedSrc = computed(() => {
  3597. return props.src && typeof props.src === 'object' ? {
  3598. src: props.src.src,
  3599. srcset: props.srcset || props.src.srcset,
  3600. lazySrc: props.lazySrc || props.src.lazySrc,
  3601. aspect: Number(props.aspectRatio || props.src.aspect || 0)
  3602. } : {
  3603. src: props.src,
  3604. srcset: props.srcset,
  3605. lazySrc: props.lazySrc,
  3606. aspect: Number(props.aspectRatio || 0)
  3607. };
  3608. });
  3609. const aspectRatio = computed(() => {
  3610. return normalisedSrc.value.aspect || naturalWidth.value / naturalHeight.value || 0;
  3611. });
  3612. watch(() => props.src, () => {
  3613. init(state.value !== 'idle');
  3614. });
  3615. watch(aspectRatio, (val, oldVal) => {
  3616. if (!val && oldVal && image.value) {
  3617. pollForSize(image.value);
  3618. }
  3619. });
  3620. // TODO: getSrc when window width changes
  3621. onBeforeMount(() => init());
  3622. function init(isIntersecting) {
  3623. if (props.eager && isIntersecting) return;
  3624. if (SUPPORTS_INTERSECTION && !isIntersecting && !props.eager) return;
  3625. state.value = 'loading';
  3626. if (normalisedSrc.value.lazySrc) {
  3627. const lazyImg = new Image();
  3628. lazyImg.src = normalisedSrc.value.lazySrc;
  3629. pollForSize(lazyImg, null);
  3630. }
  3631. if (!normalisedSrc.value.src) return;
  3632. nextTick(() => {
  3633. emit('loadstart', image.value?.currentSrc || normalisedSrc.value.src);
  3634. setTimeout(() => {
  3635. if (vm.isUnmounted) return;
  3636. if (image.value?.complete) {
  3637. if (!image.value.naturalWidth) {
  3638. onError();
  3639. }
  3640. if (state.value === 'error') return;
  3641. if (!aspectRatio.value) pollForSize(image.value, null);
  3642. if (state.value === 'loading') onLoad();
  3643. } else {
  3644. if (!aspectRatio.value) pollForSize(image.value);
  3645. getSrc();
  3646. }
  3647. });
  3648. });
  3649. }
  3650. function onLoad() {
  3651. if (vm.isUnmounted) return;
  3652. getSrc();
  3653. pollForSize(image.value);
  3654. state.value = 'loaded';
  3655. emit('load', image.value?.currentSrc || normalisedSrc.value.src);
  3656. }
  3657. function onError() {
  3658. if (vm.isUnmounted) return;
  3659. state.value = 'error';
  3660. emit('error', image.value?.currentSrc || normalisedSrc.value.src);
  3661. }
  3662. function getSrc() {
  3663. const img = image.value;
  3664. if (img) currentSrc.value = img.currentSrc || img.src;
  3665. }
  3666. let timer = -1;
  3667. onBeforeUnmount(() => {
  3668. clearTimeout(timer);
  3669. });
  3670. function pollForSize(img) {
  3671. let timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100;
  3672. const poll = () => {
  3673. clearTimeout(timer);
  3674. if (vm.isUnmounted) return;
  3675. const {
  3676. naturalHeight: imgHeight,
  3677. naturalWidth: imgWidth
  3678. } = img;
  3679. if (imgHeight || imgWidth) {
  3680. naturalWidth.value = imgWidth;
  3681. naturalHeight.value = imgHeight;
  3682. } else if (!img.complete && state.value === 'loading' && timeout != null) {
  3683. timer = window.setTimeout(poll, timeout);
  3684. } else if (img.currentSrc.endsWith('.svg') || img.currentSrc.startsWith('data:image/svg+xml')) {
  3685. naturalWidth.value = 1;
  3686. naturalHeight.value = 1;
  3687. }
  3688. };
  3689. poll();
  3690. }
  3691. const containClasses = computed(() => ({
  3692. 'v-img__img--cover': props.cover,
  3693. 'v-img__img--contain': !props.cover
  3694. }));
  3695. const __image = () => {
  3696. if (!normalisedSrc.value.src || state.value === 'idle') return null;
  3697. const img = createVNode("img", {
  3698. "class": ['v-img__img', containClasses.value],
  3699. "style": {
  3700. objectPosition: props.position
  3701. },
  3702. "src": normalisedSrc.value.src,
  3703. "srcset": normalisedSrc.value.srcset,
  3704. "alt": props.alt,
  3705. "crossorigin": props.crossorigin,
  3706. "referrerpolicy": props.referrerpolicy,
  3707. "draggable": props.draggable,
  3708. "sizes": props.sizes,
  3709. "ref": image,
  3710. "onLoad": onLoad,
  3711. "onError": onError
  3712. }, null);
  3713. const sources = slots.sources?.();
  3714. return createVNode(MaybeTransition, {
  3715. "transition": props.transition,
  3716. "appear": true
  3717. }, {
  3718. default: () => [withDirectives(sources ? createVNode("picture", {
  3719. "class": "v-img__picture"
  3720. }, [sources, img]) : img, [[vShow, state.value === 'loaded']])]
  3721. });
  3722. };
  3723. const __preloadImage = () => createVNode(MaybeTransition, {
  3724. "transition": props.transition
  3725. }, {
  3726. default: () => [normalisedSrc.value.lazySrc && state.value !== 'loaded' && createVNode("img", {
  3727. "class": ['v-img__img', 'v-img__img--preload', containClasses.value],
  3728. "style": {
  3729. objectPosition: props.position
  3730. },
  3731. "src": normalisedSrc.value.lazySrc,
  3732. "alt": props.alt,
  3733. "crossorigin": props.crossorigin,
  3734. "referrerpolicy": props.referrerpolicy,
  3735. "draggable": props.draggable
  3736. }, null)]
  3737. });
  3738. const __placeholder = () => {
  3739. if (!slots.placeholder) return null;
  3740. return createVNode(MaybeTransition, {
  3741. "transition": props.transition,
  3742. "appear": true
  3743. }, {
  3744. default: () => [(state.value === 'loading' || state.value === 'error' && !slots.error) && createVNode("div", {
  3745. "class": "v-img__placeholder"
  3746. }, [slots.placeholder()])]
  3747. });
  3748. };
  3749. const __error = () => {
  3750. if (!slots.error) return null;
  3751. return createVNode(MaybeTransition, {
  3752. "transition": props.transition,
  3753. "appear": true
  3754. }, {
  3755. default: () => [state.value === 'error' && createVNode("div", {
  3756. "class": "v-img__error"
  3757. }, [slots.error()])]
  3758. });
  3759. };
  3760. const __gradient = () => {
  3761. if (!props.gradient) return null;
  3762. return createVNode("div", {
  3763. "class": "v-img__gradient",
  3764. "style": {
  3765. backgroundImage: `linear-gradient(${props.gradient})`
  3766. }
  3767. }, null);
  3768. };
  3769. const isBooted = shallowRef(false);
  3770. {
  3771. const stop = watch(aspectRatio, val => {
  3772. if (val) {
  3773. // Doesn't work with nextTick, idk why
  3774. requestAnimationFrame(() => {
  3775. requestAnimationFrame(() => {
  3776. isBooted.value = true;
  3777. });
  3778. });
  3779. stop();
  3780. }
  3781. });
  3782. }
  3783. useRender(() => {
  3784. const responsiveProps = VResponsive.filterProps(props);
  3785. return withDirectives(createVNode(VResponsive, mergeProps({
  3786. "class": ['v-img', {
  3787. 'v-img--absolute': props.absolute,
  3788. 'v-img--booting': !isBooted.value
  3789. }, backgroundColorClasses.value, roundedClasses.value, props.class],
  3790. "style": [{
  3791. width: convertToUnit(props.width === 'auto' ? naturalWidth.value : props.width)
  3792. }, backgroundColorStyles.value, props.style]
  3793. }, responsiveProps, {
  3794. "aspectRatio": aspectRatio.value,
  3795. "aria-label": props.alt,
  3796. "role": props.alt ? 'img' : undefined
  3797. }), {
  3798. additional: () => createVNode(Fragment, null, [createVNode(__image, null, null), createVNode(__preloadImage, null, null), createVNode(__gradient, null, null), createVNode(__placeholder, null, null), createVNode(__error, null, null)]),
  3799. default: slots.default
  3800. }), [[resolveDirective("intersect"), {
  3801. handler: init,
  3802. options: props.options
  3803. }, null, {
  3804. once: true
  3805. }]]);
  3806. });
  3807. return {
  3808. currentSrc,
  3809. image,
  3810. state,
  3811. naturalWidth,
  3812. naturalHeight
  3813. };
  3814. }
  3815. });
  3816. // Utilities
  3817. // Types
  3818. // Composables
  3819. const makeBorderProps = propsFactory({
  3820. border: [Boolean, Number, String]
  3821. }, 'border');
  3822. function useBorder(props) {
  3823. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  3824. const borderClasses = computed(() => {
  3825. const border = isRef(props) ? props.value : props.border;
  3826. const classes = [];
  3827. if (border === true || border === '') {
  3828. classes.push(`${name}--border`);
  3829. } else if (typeof border === 'string' || border === 0) {
  3830. for (const value of String(border).split(' ')) {
  3831. classes.push(`border-${value}`);
  3832. }
  3833. }
  3834. return classes;
  3835. });
  3836. return {
  3837. borderClasses
  3838. };
  3839. }
  3840. // Utilities
  3841. // Types
  3842. // Composables
  3843. const makeElevationProps = propsFactory({
  3844. elevation: {
  3845. type: [Number, String],
  3846. validator(v) {
  3847. const value = parseInt(v);
  3848. return !isNaN(value) && value >= 0 &&
  3849. // Material Design has a maximum elevation of 24
  3850. // https://material.io/design/environment/elevation.html#default-elevations
  3851. value <= 24;
  3852. }
  3853. }
  3854. }, 'elevation');
  3855. function useElevation(props) {
  3856. const elevationClasses = computed(() => {
  3857. const elevation = isRef(props) ? props.value : props.elevation;
  3858. const classes = [];
  3859. if (elevation == null) return classes;
  3860. classes.push(`elevation-${elevation}`);
  3861. return classes;
  3862. });
  3863. return {
  3864. elevationClasses
  3865. };
  3866. }
  3867. // Types
  3868. const allowedDensities$1 = [null, 'prominent', 'default', 'comfortable', 'compact'];
  3869. const makeVToolbarProps = propsFactory({
  3870. absolute: Boolean,
  3871. collapse: Boolean,
  3872. color: String,
  3873. density: {
  3874. type: String,
  3875. default: 'default',
  3876. validator: v => allowedDensities$1.includes(v)
  3877. },
  3878. extended: Boolean,
  3879. extensionHeight: {
  3880. type: [Number, String],
  3881. default: 48
  3882. },
  3883. flat: Boolean,
  3884. floating: Boolean,
  3885. height: {
  3886. type: [Number, String],
  3887. default: 64
  3888. },
  3889. image: String,
  3890. title: String,
  3891. ...makeBorderProps(),
  3892. ...makeComponentProps(),
  3893. ...makeElevationProps(),
  3894. ...makeRoundedProps(),
  3895. ...makeTagProps({
  3896. tag: 'header'
  3897. }),
  3898. ...makeThemeProps()
  3899. }, 'VToolbar');
  3900. const VToolbar = genericComponent()({
  3901. name: 'VToolbar',
  3902. props: makeVToolbarProps(),
  3903. setup(props, _ref) {
  3904. let {
  3905. slots
  3906. } = _ref;
  3907. const {
  3908. backgroundColorClasses,
  3909. backgroundColorStyles
  3910. } = useBackgroundColor(toRef(props, 'color'));
  3911. const {
  3912. borderClasses
  3913. } = useBorder(props);
  3914. const {
  3915. elevationClasses
  3916. } = useElevation(props);
  3917. const {
  3918. roundedClasses
  3919. } = useRounded(props);
  3920. const {
  3921. themeClasses
  3922. } = provideTheme(props);
  3923. const {
  3924. rtlClasses
  3925. } = useRtl();
  3926. const isExtended = shallowRef(!!(props.extended || slots.extension?.()));
  3927. const contentHeight = computed(() => parseInt(Number(props.height) + (props.density === 'prominent' ? Number(props.height) : 0) - (props.density === 'comfortable' ? 8 : 0) - (props.density === 'compact' ? 16 : 0), 10));
  3928. const extensionHeight = computed(() => isExtended.value ? parseInt(Number(props.extensionHeight) + (props.density === 'prominent' ? Number(props.extensionHeight) : 0) - (props.density === 'comfortable' ? 4 : 0) - (props.density === 'compact' ? 8 : 0), 10) : 0);
  3929. provideDefaults({
  3930. VBtn: {
  3931. variant: 'text'
  3932. }
  3933. });
  3934. useRender(() => {
  3935. const hasTitle = !!(props.title || slots.title);
  3936. const hasImage = !!(slots.image || props.image);
  3937. const extension = slots.extension?.();
  3938. isExtended.value = !!(props.extended || extension);
  3939. return createVNode(props.tag, {
  3940. "class": ['v-toolbar', {
  3941. 'v-toolbar--absolute': props.absolute,
  3942. 'v-toolbar--collapse': props.collapse,
  3943. 'v-toolbar--flat': props.flat,
  3944. 'v-toolbar--floating': props.floating,
  3945. [`v-toolbar--density-${props.density}`]: true
  3946. }, backgroundColorClasses.value, borderClasses.value, elevationClasses.value, roundedClasses.value, themeClasses.value, rtlClasses.value, props.class],
  3947. "style": [backgroundColorStyles.value, props.style]
  3948. }, {
  3949. default: () => [hasImage && createVNode("div", {
  3950. "key": "image",
  3951. "class": "v-toolbar__image"
  3952. }, [!slots.image ? createVNode(VImg, {
  3953. "key": "image-img",
  3954. "cover": true,
  3955. "src": props.image
  3956. }, null) : createVNode(VDefaultsProvider, {
  3957. "key": "image-defaults",
  3958. "disabled": !props.image,
  3959. "defaults": {
  3960. VImg: {
  3961. cover: true,
  3962. src: props.image
  3963. }
  3964. }
  3965. }, slots.image)]), createVNode(VDefaultsProvider, {
  3966. "defaults": {
  3967. VTabs: {
  3968. height: convertToUnit(contentHeight.value)
  3969. }
  3970. }
  3971. }, {
  3972. default: () => [createVNode("div", {
  3973. "class": "v-toolbar__content",
  3974. "style": {
  3975. height: convertToUnit(contentHeight.value)
  3976. }
  3977. }, [slots.prepend && createVNode("div", {
  3978. "class": "v-toolbar__prepend"
  3979. }, [slots.prepend?.()]), hasTitle && createVNode(VToolbarTitle, {
  3980. "key": "title",
  3981. "text": props.title
  3982. }, {
  3983. text: slots.title
  3984. }), slots.default?.(), slots.append && createVNode("div", {
  3985. "class": "v-toolbar__append"
  3986. }, [slots.append?.()])])]
  3987. }), createVNode(VDefaultsProvider, {
  3988. "defaults": {
  3989. VTabs: {
  3990. height: convertToUnit(extensionHeight.value)
  3991. }
  3992. }
  3993. }, {
  3994. default: () => [createVNode(VExpandTransition, null, {
  3995. default: () => [isExtended.value && createVNode("div", {
  3996. "class": "v-toolbar__extension",
  3997. "style": {
  3998. height: convertToUnit(extensionHeight.value)
  3999. }
  4000. }, [extension])]
  4001. })]
  4002. })]
  4003. });
  4004. });
  4005. return {
  4006. contentHeight,
  4007. extensionHeight
  4008. };
  4009. }
  4010. });
  4011. // Utilities
  4012. // Types
  4013. // Composables
  4014. const makeScrollProps = propsFactory({
  4015. scrollTarget: {
  4016. type: String
  4017. },
  4018. scrollThreshold: {
  4019. type: [String, Number],
  4020. default: 300
  4021. }
  4022. }, 'scroll');
  4023. function useScroll(props) {
  4024. let args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  4025. const {
  4026. canScroll
  4027. } = args;
  4028. let previousScroll = 0;
  4029. let previousScrollHeight = 0;
  4030. const target = ref(null);
  4031. const currentScroll = shallowRef(0);
  4032. const savedScroll = shallowRef(0);
  4033. const currentThreshold = shallowRef(0);
  4034. const isScrollActive = shallowRef(false);
  4035. const isScrollingUp = shallowRef(false);
  4036. const scrollThreshold = computed(() => {
  4037. return Number(props.scrollThreshold);
  4038. });
  4039. /**
  4040. * 1: at top
  4041. * 0: at threshold
  4042. */
  4043. const scrollRatio = computed(() => {
  4044. return clamp((scrollThreshold.value - currentScroll.value) / scrollThreshold.value || 0);
  4045. });
  4046. const onScroll = () => {
  4047. const targetEl = target.value;
  4048. if (!targetEl || canScroll && !canScroll.value) return;
  4049. previousScroll = currentScroll.value;
  4050. currentScroll.value = 'window' in targetEl ? targetEl.pageYOffset : targetEl.scrollTop;
  4051. const currentScrollHeight = targetEl instanceof Window ? document.documentElement.scrollHeight : targetEl.scrollHeight;
  4052. if (previousScrollHeight !== currentScrollHeight) {
  4053. previousScrollHeight = currentScrollHeight;
  4054. return;
  4055. }
  4056. isScrollingUp.value = currentScroll.value < previousScroll;
  4057. currentThreshold.value = Math.abs(currentScroll.value - scrollThreshold.value);
  4058. };
  4059. watch(isScrollingUp, () => {
  4060. savedScroll.value = savedScroll.value || currentScroll.value;
  4061. });
  4062. watch(isScrollActive, () => {
  4063. savedScroll.value = 0;
  4064. });
  4065. onMounted(() => {
  4066. watch(() => props.scrollTarget, scrollTarget => {
  4067. const newTarget = scrollTarget ? document.querySelector(scrollTarget) : window;
  4068. if (!newTarget) {
  4069. consoleWarn(`Unable to locate element with identifier ${scrollTarget}`);
  4070. return;
  4071. }
  4072. if (newTarget === target.value) return;
  4073. target.value?.removeEventListener('scroll', onScroll);
  4074. target.value = newTarget;
  4075. target.value.addEventListener('scroll', onScroll, {
  4076. passive: true
  4077. });
  4078. }, {
  4079. immediate: true
  4080. });
  4081. });
  4082. onBeforeUnmount(() => {
  4083. target.value?.removeEventListener('scroll', onScroll);
  4084. });
  4085. // Do we need this? If yes - seems that
  4086. // there's no need to expose onScroll
  4087. canScroll && watch(canScroll, onScroll, {
  4088. immediate: true
  4089. });
  4090. return {
  4091. scrollThreshold,
  4092. currentScroll,
  4093. currentThreshold,
  4094. isScrollActive,
  4095. scrollRatio,
  4096. // required only for testing
  4097. // probably can be removed
  4098. // later (2 chars chlng)
  4099. isScrollingUp,
  4100. savedScroll
  4101. };
  4102. }
  4103. // Utilities
  4104. // Composables
  4105. function useSsrBoot() {
  4106. const isBooted = shallowRef(false);
  4107. onMounted(() => {
  4108. window.requestAnimationFrame(() => {
  4109. isBooted.value = true;
  4110. });
  4111. });
  4112. const ssrBootStyles = computed(() => !isBooted.value ? {
  4113. transition: 'none !important'
  4114. } : undefined);
  4115. return {
  4116. ssrBootStyles,
  4117. isBooted: readonly(isBooted)
  4118. };
  4119. }
  4120. // Types
  4121. const makeVAppBarProps = propsFactory({
  4122. scrollBehavior: String,
  4123. modelValue: {
  4124. type: Boolean,
  4125. default: true
  4126. },
  4127. location: {
  4128. type: String,
  4129. default: 'top',
  4130. validator: value => ['top', 'bottom'].includes(value)
  4131. },
  4132. ...makeVToolbarProps(),
  4133. ...makeLayoutItemProps(),
  4134. ...makeScrollProps(),
  4135. height: {
  4136. type: [Number, String],
  4137. default: 64
  4138. }
  4139. }, 'VAppBar');
  4140. const VAppBar = genericComponent()({
  4141. name: 'VAppBar',
  4142. props: makeVAppBarProps(),
  4143. emits: {
  4144. 'update:modelValue': value => true
  4145. },
  4146. setup(props, _ref) {
  4147. let {
  4148. slots
  4149. } = _ref;
  4150. const vToolbarRef = ref();
  4151. const isActive = useProxiedModel(props, 'modelValue');
  4152. const scrollBehavior = computed(() => {
  4153. const behavior = new Set(props.scrollBehavior?.split(' ') ?? []);
  4154. return {
  4155. hide: behavior.has('hide'),
  4156. fullyHide: behavior.has('fully-hide'),
  4157. inverted: behavior.has('inverted'),
  4158. collapse: behavior.has('collapse'),
  4159. elevate: behavior.has('elevate'),
  4160. fadeImage: behavior.has('fade-image')
  4161. // shrink: behavior.has('shrink'),
  4162. };
  4163. });
  4164. const canScroll = computed(() => {
  4165. const behavior = scrollBehavior.value;
  4166. return behavior.hide || behavior.fullyHide || behavior.inverted || behavior.collapse || behavior.elevate || behavior.fadeImage ||
  4167. // behavior.shrink ||
  4168. !isActive.value;
  4169. });
  4170. const {
  4171. currentScroll,
  4172. scrollThreshold,
  4173. isScrollingUp,
  4174. scrollRatio
  4175. } = useScroll(props, {
  4176. canScroll
  4177. });
  4178. const canHide = computed(() => scrollBehavior.value.hide || scrollBehavior.value.fullyHide);
  4179. const isCollapsed = computed(() => props.collapse || scrollBehavior.value.collapse && (scrollBehavior.value.inverted ? scrollRatio.value > 0 : scrollRatio.value === 0));
  4180. const isFlat = computed(() => props.flat || scrollBehavior.value.fullyHide && !isActive.value || scrollBehavior.value.elevate && (scrollBehavior.value.inverted ? currentScroll.value > 0 : currentScroll.value === 0));
  4181. const opacity = computed(() => scrollBehavior.value.fadeImage ? scrollBehavior.value.inverted ? 1 - scrollRatio.value : scrollRatio.value : undefined);
  4182. const height = computed(() => {
  4183. if (scrollBehavior.value.hide && scrollBehavior.value.inverted) return 0;
  4184. const height = vToolbarRef.value?.contentHeight ?? 0;
  4185. const extensionHeight = vToolbarRef.value?.extensionHeight ?? 0;
  4186. if (!canHide.value) return height + extensionHeight;
  4187. return currentScroll.value < scrollThreshold.value || scrollBehavior.value.fullyHide ? height + extensionHeight : height;
  4188. });
  4189. useToggleScope(computed(() => !!props.scrollBehavior), () => {
  4190. watchEffect(() => {
  4191. if (canHide.value) {
  4192. if (scrollBehavior.value.inverted) {
  4193. isActive.value = currentScroll.value > scrollThreshold.value;
  4194. } else {
  4195. isActive.value = isScrollingUp.value || currentScroll.value < scrollThreshold.value;
  4196. }
  4197. } else {
  4198. isActive.value = true;
  4199. }
  4200. });
  4201. });
  4202. const {
  4203. ssrBootStyles
  4204. } = useSsrBoot();
  4205. const {
  4206. layoutItemStyles
  4207. } = useLayoutItem({
  4208. id: props.name,
  4209. order: computed(() => parseInt(props.order, 10)),
  4210. position: toRef(props, 'location'),
  4211. layoutSize: height,
  4212. elementSize: shallowRef(undefined),
  4213. active: isActive,
  4214. absolute: toRef(props, 'absolute')
  4215. });
  4216. useRender(() => {
  4217. const toolbarProps = VToolbar.filterProps(props);
  4218. return createVNode(VToolbar, mergeProps({
  4219. "ref": vToolbarRef,
  4220. "class": ['v-app-bar', {
  4221. 'v-app-bar--bottom': props.location === 'bottom'
  4222. }, props.class],
  4223. "style": [{
  4224. ...layoutItemStyles.value,
  4225. '--v-toolbar-image-opacity': opacity.value,
  4226. height: undefined,
  4227. ...ssrBootStyles.value
  4228. }, props.style]
  4229. }, toolbarProps, {
  4230. "collapse": isCollapsed.value,
  4231. "flat": isFlat.value
  4232. }), slots);
  4233. });
  4234. return {};
  4235. }
  4236. });
  4237. // Utilities
  4238. // Types
  4239. const allowedDensities = [null, 'default', 'comfortable', 'compact'];
  4240. // typeof allowedDensities[number] evalutes to any
  4241. // when generating api types for whatever reason.
  4242. // Composables
  4243. const makeDensityProps = propsFactory({
  4244. density: {
  4245. type: String,
  4246. default: 'default',
  4247. validator: v => allowedDensities.includes(v)
  4248. }
  4249. }, 'density');
  4250. function useDensity(props) {
  4251. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  4252. const densityClasses = computed(() => {
  4253. return `${name}--density-${props.density}`;
  4254. });
  4255. return {
  4256. densityClasses
  4257. };
  4258. }
  4259. // Types
  4260. const allowedVariants$2 = ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain'];
  4261. function genOverlays(isClickable, name) {
  4262. return createVNode(Fragment, null, [isClickable && createVNode("span", {
  4263. "key": "overlay",
  4264. "class": `${name}__overlay`
  4265. }, null), createVNode("span", {
  4266. "key": "underlay",
  4267. "class": `${name}__underlay`
  4268. }, null)]);
  4269. }
  4270. const makeVariantProps = propsFactory({
  4271. color: String,
  4272. variant: {
  4273. type: String,
  4274. default: 'elevated',
  4275. validator: v => allowedVariants$2.includes(v)
  4276. }
  4277. }, 'variant');
  4278. function useVariant(props) {
  4279. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  4280. const variantClasses = computed(() => {
  4281. const {
  4282. variant
  4283. } = unref(props);
  4284. return `${name}--variant-${variant}`;
  4285. });
  4286. const {
  4287. colorClasses,
  4288. colorStyles
  4289. } = useColor(computed(() => {
  4290. const {
  4291. variant,
  4292. color
  4293. } = unref(props);
  4294. return {
  4295. [['elevated', 'flat'].includes(variant) ? 'background' : 'text']: color
  4296. };
  4297. }));
  4298. return {
  4299. colorClasses,
  4300. colorStyles,
  4301. variantClasses
  4302. };
  4303. }
  4304. const makeVBtnGroupProps = propsFactory({
  4305. baseColor: String,
  4306. divided: Boolean,
  4307. ...makeBorderProps(),
  4308. ...makeComponentProps(),
  4309. ...makeDensityProps(),
  4310. ...makeElevationProps(),
  4311. ...makeRoundedProps(),
  4312. ...makeTagProps(),
  4313. ...makeThemeProps(),
  4314. ...makeVariantProps()
  4315. }, 'VBtnGroup');
  4316. const VBtnGroup = genericComponent()({
  4317. name: 'VBtnGroup',
  4318. props: makeVBtnGroupProps(),
  4319. setup(props, _ref) {
  4320. let {
  4321. slots
  4322. } = _ref;
  4323. const {
  4324. themeClasses
  4325. } = provideTheme(props);
  4326. const {
  4327. densityClasses
  4328. } = useDensity(props);
  4329. const {
  4330. borderClasses
  4331. } = useBorder(props);
  4332. const {
  4333. elevationClasses
  4334. } = useElevation(props);
  4335. const {
  4336. roundedClasses
  4337. } = useRounded(props);
  4338. provideDefaults({
  4339. VBtn: {
  4340. height: 'auto',
  4341. baseColor: toRef(props, 'baseColor'),
  4342. color: toRef(props, 'color'),
  4343. density: toRef(props, 'density'),
  4344. flat: true,
  4345. variant: toRef(props, 'variant')
  4346. }
  4347. });
  4348. useRender(() => {
  4349. return createVNode(props.tag, {
  4350. "class": ['v-btn-group', {
  4351. 'v-btn-group--divided': props.divided
  4352. }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  4353. "style": props.style
  4354. }, slots);
  4355. });
  4356. }
  4357. });
  4358. // Composables
  4359. // Types
  4360. const makeGroupProps = propsFactory({
  4361. modelValue: {
  4362. type: null,
  4363. default: undefined
  4364. },
  4365. multiple: Boolean,
  4366. mandatory: [Boolean, String],
  4367. max: Number,
  4368. selectedClass: String,
  4369. disabled: Boolean
  4370. }, 'group');
  4371. const makeGroupItemProps = propsFactory({
  4372. value: null,
  4373. disabled: Boolean,
  4374. selectedClass: String
  4375. }, 'group-item');
  4376. // Composables
  4377. function useGroupItem(props, injectKey) {
  4378. let required = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
  4379. const vm = getCurrentInstance('useGroupItem');
  4380. if (!vm) {
  4381. throw new Error('[Vuetify] useGroupItem composable must be used inside a component setup function');
  4382. }
  4383. const id = getUid();
  4384. provide(Symbol.for(`${injectKey.description}:id`), id);
  4385. const group = inject$1(injectKey, null);
  4386. if (!group) {
  4387. if (!required) return group;
  4388. throw new Error(`[Vuetify] Could not find useGroup injection with symbol ${injectKey.description}`);
  4389. }
  4390. const value = toRef(props, 'value');
  4391. const disabled = computed(() => !!(group.disabled.value || props.disabled));
  4392. group.register({
  4393. id,
  4394. value,
  4395. disabled
  4396. }, vm);
  4397. onBeforeUnmount(() => {
  4398. group.unregister(id);
  4399. });
  4400. const isSelected = computed(() => {
  4401. return group.isSelected(id);
  4402. });
  4403. const isFirst = computed(() => {
  4404. return group.items.value[0].id === id;
  4405. });
  4406. const isLast = computed(() => {
  4407. return group.items.value[group.items.value.length - 1].id === id;
  4408. });
  4409. const selectedClass = computed(() => isSelected.value && [group.selectedClass.value, props.selectedClass]);
  4410. watch(isSelected, value => {
  4411. vm.emit('group:selected', {
  4412. value
  4413. });
  4414. }, {
  4415. flush: 'sync'
  4416. });
  4417. return {
  4418. id,
  4419. isSelected,
  4420. isFirst,
  4421. isLast,
  4422. toggle: () => group.select(id, !isSelected.value),
  4423. select: value => group.select(id, value),
  4424. selectedClass,
  4425. value,
  4426. disabled,
  4427. group
  4428. };
  4429. }
  4430. function useGroup(props, injectKey) {
  4431. let isUnmounted = false;
  4432. const items = reactive([]);
  4433. const selected = useProxiedModel(props, 'modelValue', [], v => {
  4434. if (v == null) return [];
  4435. return getIds(items, wrapInArray(v));
  4436. }, v => {
  4437. const arr = getValues(items, v);
  4438. return props.multiple ? arr : arr[0];
  4439. });
  4440. const groupVm = getCurrentInstance('useGroup');
  4441. function register(item, vm) {
  4442. // Is there a better way to fix this typing?
  4443. const unwrapped = item;
  4444. const key = Symbol.for(`${injectKey.description}:id`);
  4445. const children = findChildrenWithProvide(key, groupVm?.vnode);
  4446. const index = children.indexOf(vm);
  4447. if (unref(unwrapped.value) == null) {
  4448. unwrapped.value = index;
  4449. unwrapped.useIndexAsValue = true;
  4450. }
  4451. if (index > -1) {
  4452. items.splice(index, 0, unwrapped);
  4453. } else {
  4454. items.push(unwrapped);
  4455. }
  4456. }
  4457. function unregister(id) {
  4458. if (isUnmounted) return;
  4459. // TODO: re-evaluate this line's importance in the future
  4460. // should we only modify the model if mandatory is set.
  4461. // selected.value = selected.value.filter(v => v !== id)
  4462. forceMandatoryValue();
  4463. const index = items.findIndex(item => item.id === id);
  4464. items.splice(index, 1);
  4465. }
  4466. // If mandatory and nothing is selected, then select first non-disabled item
  4467. function forceMandatoryValue() {
  4468. const item = items.find(item => !item.disabled);
  4469. if (item && props.mandatory === 'force' && !selected.value.length) {
  4470. selected.value = [item.id];
  4471. }
  4472. }
  4473. onMounted(() => {
  4474. forceMandatoryValue();
  4475. });
  4476. onBeforeUnmount(() => {
  4477. isUnmounted = true;
  4478. });
  4479. onUpdated(() => {
  4480. // #19655 update the items that use the index as the value.
  4481. for (let i = 0; i < items.length; i++) {
  4482. if (items[i].useIndexAsValue) {
  4483. items[i].value = i;
  4484. }
  4485. }
  4486. });
  4487. function select(id, value) {
  4488. const item = items.find(item => item.id === id);
  4489. if (value && item?.disabled) return;
  4490. if (props.multiple) {
  4491. const internalValue = selected.value.slice();
  4492. const index = internalValue.findIndex(v => v === id);
  4493. const isSelected = ~index;
  4494. value = value ?? !isSelected;
  4495. // We can't remove value if group is
  4496. // mandatory, value already exists,
  4497. // and it is the only value
  4498. if (isSelected && props.mandatory && internalValue.length <= 1) return;
  4499. // We can't add value if it would
  4500. // cause max limit to be exceeded
  4501. if (!isSelected && props.max != null && internalValue.length + 1 > props.max) return;
  4502. if (index < 0 && value) internalValue.push(id);else if (index >= 0 && !value) internalValue.splice(index, 1);
  4503. selected.value = internalValue;
  4504. } else {
  4505. const isSelected = selected.value.includes(id);
  4506. if (props.mandatory && isSelected) return;
  4507. selected.value = value ?? !isSelected ? [id] : [];
  4508. }
  4509. }
  4510. function step(offset) {
  4511. // getting an offset from selected value obviously won't work with multiple values
  4512. if (props.multiple) consoleWarn('This method is not supported when using "multiple" prop');
  4513. if (!selected.value.length) {
  4514. const item = items.find(item => !item.disabled);
  4515. item && (selected.value = [item.id]);
  4516. } else {
  4517. const currentId = selected.value[0];
  4518. const currentIndex = items.findIndex(i => i.id === currentId);
  4519. let newIndex = (currentIndex + offset) % items.length;
  4520. let newItem = items[newIndex];
  4521. while (newItem.disabled && newIndex !== currentIndex) {
  4522. newIndex = (newIndex + offset) % items.length;
  4523. newItem = items[newIndex];
  4524. }
  4525. if (newItem.disabled) return;
  4526. selected.value = [items[newIndex].id];
  4527. }
  4528. }
  4529. const state = {
  4530. register,
  4531. unregister,
  4532. selected,
  4533. select,
  4534. disabled: toRef(props, 'disabled'),
  4535. prev: () => step(items.length - 1),
  4536. next: () => step(1),
  4537. isSelected: id => selected.value.includes(id),
  4538. selectedClass: computed(() => props.selectedClass),
  4539. items: computed(() => items),
  4540. getItemIndex: value => getItemIndex(items, value)
  4541. };
  4542. provide(injectKey, state);
  4543. return state;
  4544. }
  4545. function getItemIndex(items, value) {
  4546. const ids = getIds(items, [value]);
  4547. if (!ids.length) return -1;
  4548. return items.findIndex(item => item.id === ids[0]);
  4549. }
  4550. function getIds(items, modelValue) {
  4551. const ids = [];
  4552. modelValue.forEach(value => {
  4553. const item = items.find(item => deepEqual(value, item.value));
  4554. const itemByIndex = items[value];
  4555. if (item?.value != null) {
  4556. ids.push(item.id);
  4557. } else if (itemByIndex != null) {
  4558. ids.push(itemByIndex.id);
  4559. }
  4560. });
  4561. return ids;
  4562. }
  4563. function getValues(items, ids) {
  4564. const values = [];
  4565. ids.forEach(id => {
  4566. const itemIndex = items.findIndex(item => item.id === id);
  4567. if (~itemIndex) {
  4568. const item = items[itemIndex];
  4569. values.push(item.value != null ? item.value : itemIndex);
  4570. }
  4571. });
  4572. return values;
  4573. }
  4574. // Types
  4575. const VBtnToggleSymbol = Symbol.for('vuetify:v-btn-toggle');
  4576. const makeVBtnToggleProps = propsFactory({
  4577. ...makeVBtnGroupProps(),
  4578. ...makeGroupProps()
  4579. }, 'VBtnToggle');
  4580. const VBtnToggle = genericComponent()({
  4581. name: 'VBtnToggle',
  4582. props: makeVBtnToggleProps(),
  4583. emits: {
  4584. 'update:modelValue': value => true
  4585. },
  4586. setup(props, _ref) {
  4587. let {
  4588. slots
  4589. } = _ref;
  4590. const {
  4591. isSelected,
  4592. next,
  4593. prev,
  4594. select,
  4595. selected
  4596. } = useGroup(props, VBtnToggleSymbol);
  4597. useRender(() => {
  4598. const btnGroupProps = VBtnGroup.filterProps(props);
  4599. return createVNode(VBtnGroup, mergeProps({
  4600. "class": ['v-btn-toggle', props.class]
  4601. }, btnGroupProps, {
  4602. "style": props.style
  4603. }), {
  4604. default: () => [slots.default?.({
  4605. isSelected,
  4606. next,
  4607. prev,
  4608. select,
  4609. selected
  4610. })]
  4611. });
  4612. });
  4613. return {
  4614. next,
  4615. prev,
  4616. select
  4617. };
  4618. }
  4619. });
  4620. // Utilities
  4621. // Types
  4622. const predefinedSizes = ['x-small', 'small', 'default', 'large', 'x-large'];
  4623. // Composables
  4624. const makeSizeProps = propsFactory({
  4625. size: {
  4626. type: [String, Number],
  4627. default: 'default'
  4628. }
  4629. }, 'size');
  4630. function useSize(props) {
  4631. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  4632. return destructComputed(() => {
  4633. let sizeClasses;
  4634. let sizeStyles;
  4635. if (includes(predefinedSizes, props.size)) {
  4636. sizeClasses = `${name}--size-${props.size}`;
  4637. } else if (props.size) {
  4638. sizeStyles = {
  4639. width: convertToUnit(props.size),
  4640. height: convertToUnit(props.size)
  4641. };
  4642. }
  4643. return {
  4644. sizeClasses,
  4645. sizeStyles
  4646. };
  4647. });
  4648. }
  4649. const makeVIconProps = propsFactory({
  4650. color: String,
  4651. disabled: Boolean,
  4652. start: Boolean,
  4653. end: Boolean,
  4654. icon: IconValue,
  4655. ...makeComponentProps(),
  4656. ...makeSizeProps(),
  4657. ...makeTagProps({
  4658. tag: 'i'
  4659. }),
  4660. ...makeThemeProps()
  4661. }, 'VIcon');
  4662. const VIcon = genericComponent()({
  4663. name: 'VIcon',
  4664. props: makeVIconProps(),
  4665. setup(props, _ref) {
  4666. let {
  4667. attrs,
  4668. slots
  4669. } = _ref;
  4670. const slotIcon = ref();
  4671. const {
  4672. themeClasses
  4673. } = provideTheme(props);
  4674. const {
  4675. iconData
  4676. } = useIcon(computed(() => slotIcon.value || props.icon));
  4677. const {
  4678. sizeClasses
  4679. } = useSize(props);
  4680. const {
  4681. textColorClasses,
  4682. textColorStyles
  4683. } = useTextColor(toRef(props, 'color'));
  4684. useRender(() => {
  4685. const slotValue = slots.default?.();
  4686. if (slotValue) {
  4687. slotIcon.value = flattenFragments(slotValue).filter(node => node.type === Text && node.children && typeof node.children === 'string')[0]?.children;
  4688. }
  4689. const hasClick = !!(attrs.onClick || attrs.onClickOnce);
  4690. return createVNode(iconData.value.component, {
  4691. "tag": props.tag,
  4692. "icon": iconData.value.icon,
  4693. "class": ['v-icon', 'notranslate', themeClasses.value, sizeClasses.value, textColorClasses.value, {
  4694. 'v-icon--clickable': hasClick,
  4695. 'v-icon--disabled': props.disabled,
  4696. 'v-icon--start': props.start,
  4697. 'v-icon--end': props.end
  4698. }, props.class],
  4699. "style": [!sizeClasses.value ? {
  4700. fontSize: convertToUnit(props.size),
  4701. height: convertToUnit(props.size),
  4702. width: convertToUnit(props.size)
  4703. } : undefined, textColorStyles.value, props.style],
  4704. "role": hasClick ? 'button' : undefined,
  4705. "aria-hidden": !hasClick,
  4706. "tabindex": hasClick ? props.disabled ? -1 : 0 : undefined
  4707. }, {
  4708. default: () => [slotValue]
  4709. });
  4710. });
  4711. return {};
  4712. }
  4713. });
  4714. // Utilities
  4715. function useIntersectionObserver(callback, options) {
  4716. const intersectionRef = ref();
  4717. const isIntersecting = shallowRef(false);
  4718. if (SUPPORTS_INTERSECTION) {
  4719. const observer = new IntersectionObserver(entries => {
  4720. callback?.(entries, observer);
  4721. isIntersecting.value = !!entries.find(entry => entry.isIntersecting);
  4722. }, options);
  4723. onBeforeUnmount(() => {
  4724. observer.disconnect();
  4725. });
  4726. watch(intersectionRef, (newValue, oldValue) => {
  4727. if (oldValue) {
  4728. observer.unobserve(oldValue);
  4729. isIntersecting.value = false;
  4730. }
  4731. if (newValue) observer.observe(newValue);
  4732. }, {
  4733. flush: 'post'
  4734. });
  4735. }
  4736. return {
  4737. intersectionRef,
  4738. isIntersecting
  4739. };
  4740. }
  4741. // Types
  4742. const makeVProgressCircularProps = propsFactory({
  4743. bgColor: String,
  4744. color: String,
  4745. indeterminate: [Boolean, String],
  4746. modelValue: {
  4747. type: [Number, String],
  4748. default: 0
  4749. },
  4750. rotate: {
  4751. type: [Number, String],
  4752. default: 0
  4753. },
  4754. width: {
  4755. type: [Number, String],
  4756. default: 4
  4757. },
  4758. ...makeComponentProps(),
  4759. ...makeSizeProps(),
  4760. ...makeTagProps({
  4761. tag: 'div'
  4762. }),
  4763. ...makeThemeProps()
  4764. }, 'VProgressCircular');
  4765. const VProgressCircular = genericComponent()({
  4766. name: 'VProgressCircular',
  4767. props: makeVProgressCircularProps(),
  4768. setup(props, _ref) {
  4769. let {
  4770. slots
  4771. } = _ref;
  4772. const MAGIC_RADIUS_CONSTANT = 20;
  4773. const CIRCUMFERENCE = 2 * Math.PI * MAGIC_RADIUS_CONSTANT;
  4774. const root = ref();
  4775. const {
  4776. themeClasses
  4777. } = provideTheme(props);
  4778. const {
  4779. sizeClasses,
  4780. sizeStyles
  4781. } = useSize(props);
  4782. const {
  4783. textColorClasses,
  4784. textColorStyles
  4785. } = useTextColor(toRef(props, 'color'));
  4786. const {
  4787. textColorClasses: underlayColorClasses,
  4788. textColorStyles: underlayColorStyles
  4789. } = useTextColor(toRef(props, 'bgColor'));
  4790. const {
  4791. intersectionRef,
  4792. isIntersecting
  4793. } = useIntersectionObserver();
  4794. const {
  4795. resizeRef,
  4796. contentRect
  4797. } = useResizeObserver();
  4798. const normalizedValue = computed(() => Math.max(0, Math.min(100, parseFloat(props.modelValue))));
  4799. const width = computed(() => Number(props.width));
  4800. const size = computed(() => {
  4801. // Get size from element if size prop value is small, large etc
  4802. return sizeStyles.value ? Number(props.size) : contentRect.value ? contentRect.value.width : Math.max(width.value, 32);
  4803. });
  4804. const diameter = computed(() => MAGIC_RADIUS_CONSTANT / (1 - width.value / size.value) * 2);
  4805. const strokeWidth = computed(() => width.value / size.value * diameter.value);
  4806. const strokeDashOffset = computed(() => convertToUnit((100 - normalizedValue.value) / 100 * CIRCUMFERENCE));
  4807. watchEffect(() => {
  4808. intersectionRef.value = root.value;
  4809. resizeRef.value = root.value;
  4810. });
  4811. useRender(() => createVNode(props.tag, {
  4812. "ref": root,
  4813. "class": ['v-progress-circular', {
  4814. 'v-progress-circular--indeterminate': !!props.indeterminate,
  4815. 'v-progress-circular--visible': isIntersecting.value,
  4816. 'v-progress-circular--disable-shrink': props.indeterminate === 'disable-shrink'
  4817. }, themeClasses.value, sizeClasses.value, textColorClasses.value, props.class],
  4818. "style": [sizeStyles.value, textColorStyles.value, props.style],
  4819. "role": "progressbar",
  4820. "aria-valuemin": "0",
  4821. "aria-valuemax": "100",
  4822. "aria-valuenow": props.indeterminate ? undefined : normalizedValue.value
  4823. }, {
  4824. default: () => [createVNode("svg", {
  4825. "style": {
  4826. transform: `rotate(calc(-90deg + ${Number(props.rotate)}deg))`
  4827. },
  4828. "xmlns": "http://www.w3.org/2000/svg",
  4829. "viewBox": `0 0 ${diameter.value} ${diameter.value}`
  4830. }, [createVNode("circle", {
  4831. "class": ['v-progress-circular__underlay', underlayColorClasses.value],
  4832. "style": underlayColorStyles.value,
  4833. "fill": "transparent",
  4834. "cx": "50%",
  4835. "cy": "50%",
  4836. "r": MAGIC_RADIUS_CONSTANT,
  4837. "stroke-width": strokeWidth.value,
  4838. "stroke-dasharray": CIRCUMFERENCE,
  4839. "stroke-dashoffset": 0
  4840. }, null), createVNode("circle", {
  4841. "class": "v-progress-circular__overlay",
  4842. "fill": "transparent",
  4843. "cx": "50%",
  4844. "cy": "50%",
  4845. "r": MAGIC_RADIUS_CONSTANT,
  4846. "stroke-width": strokeWidth.value,
  4847. "stroke-dasharray": CIRCUMFERENCE,
  4848. "stroke-dashoffset": strokeDashOffset.value
  4849. }, null)]), slots.default && createVNode("div", {
  4850. "class": "v-progress-circular__content"
  4851. }, [slots.default({
  4852. value: normalizedValue.value
  4853. })])]
  4854. }));
  4855. return {};
  4856. }
  4857. });
  4858. // Composables
  4859. // Types
  4860. const oppositeMap = {
  4861. center: 'center',
  4862. top: 'bottom',
  4863. bottom: 'top',
  4864. left: 'right',
  4865. right: 'left'
  4866. };
  4867. const makeLocationProps = propsFactory({
  4868. location: String
  4869. }, 'location');
  4870. function useLocation(props) {
  4871. let opposite = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  4872. let offset = arguments.length > 2 ? arguments[2] : undefined;
  4873. const {
  4874. isRtl
  4875. } = useRtl();
  4876. const locationStyles = computed(() => {
  4877. if (!props.location) return {};
  4878. const {
  4879. side,
  4880. align
  4881. } = parseAnchor(props.location.split(' ').length > 1 ? props.location : `${props.location} center`, isRtl.value);
  4882. function getOffset(side) {
  4883. return offset ? offset(side) : 0;
  4884. }
  4885. const styles = {};
  4886. if (side !== 'center') {
  4887. if (opposite) styles[oppositeMap[side]] = `calc(100% - ${getOffset(side)}px)`;else styles[side] = 0;
  4888. }
  4889. if (align !== 'center') {
  4890. if (opposite) styles[oppositeMap[align]] = `calc(100% - ${getOffset(align)}px)`;else styles[align] = 0;
  4891. } else {
  4892. if (side === 'center') styles.top = styles.left = '50%';else {
  4893. styles[{
  4894. top: 'left',
  4895. bottom: 'left',
  4896. left: 'top',
  4897. right: 'top'
  4898. }[side]] = '50%';
  4899. }
  4900. styles.transform = {
  4901. top: 'translateX(-50%)',
  4902. bottom: 'translateX(-50%)',
  4903. left: 'translateY(-50%)',
  4904. right: 'translateY(-50%)',
  4905. center: 'translate(-50%, -50%)'
  4906. }[side];
  4907. }
  4908. return styles;
  4909. });
  4910. return {
  4911. locationStyles
  4912. };
  4913. }
  4914. const makeVProgressLinearProps = propsFactory({
  4915. absolute: Boolean,
  4916. active: {
  4917. type: Boolean,
  4918. default: true
  4919. },
  4920. bgColor: String,
  4921. bgOpacity: [Number, String],
  4922. bufferValue: {
  4923. type: [Number, String],
  4924. default: 0
  4925. },
  4926. bufferColor: String,
  4927. bufferOpacity: [Number, String],
  4928. clickable: Boolean,
  4929. color: String,
  4930. height: {
  4931. type: [Number, String],
  4932. default: 4
  4933. },
  4934. indeterminate: Boolean,
  4935. max: {
  4936. type: [Number, String],
  4937. default: 100
  4938. },
  4939. modelValue: {
  4940. type: [Number, String],
  4941. default: 0
  4942. },
  4943. opacity: [Number, String],
  4944. reverse: Boolean,
  4945. stream: Boolean,
  4946. striped: Boolean,
  4947. roundedBar: Boolean,
  4948. ...makeComponentProps(),
  4949. ...makeLocationProps({
  4950. location: 'top'
  4951. }),
  4952. ...makeRoundedProps(),
  4953. ...makeTagProps(),
  4954. ...makeThemeProps()
  4955. }, 'VProgressLinear');
  4956. const VProgressLinear = genericComponent()({
  4957. name: 'VProgressLinear',
  4958. props: makeVProgressLinearProps(),
  4959. emits: {
  4960. 'update:modelValue': value => true
  4961. },
  4962. setup(props, _ref) {
  4963. let {
  4964. slots
  4965. } = _ref;
  4966. const progress = useProxiedModel(props, 'modelValue');
  4967. const {
  4968. isRtl,
  4969. rtlClasses
  4970. } = useRtl();
  4971. const {
  4972. themeClasses
  4973. } = provideTheme(props);
  4974. const {
  4975. locationStyles
  4976. } = useLocation(props);
  4977. const {
  4978. textColorClasses,
  4979. textColorStyles
  4980. } = useTextColor(props, 'color');
  4981. const {
  4982. backgroundColorClasses,
  4983. backgroundColorStyles
  4984. } = useBackgroundColor(computed(() => props.bgColor || props.color));
  4985. const {
  4986. backgroundColorClasses: bufferColorClasses,
  4987. backgroundColorStyles: bufferColorStyles
  4988. } = useBackgroundColor(computed(() => props.bufferColor || props.bgColor || props.color));
  4989. const {
  4990. backgroundColorClasses: barColorClasses,
  4991. backgroundColorStyles: barColorStyles
  4992. } = useBackgroundColor(props, 'color');
  4993. const {
  4994. roundedClasses
  4995. } = useRounded(props);
  4996. const {
  4997. intersectionRef,
  4998. isIntersecting
  4999. } = useIntersectionObserver();
  5000. const max = computed(() => parseFloat(props.max));
  5001. const height = computed(() => parseFloat(props.height));
  5002. const normalizedBuffer = computed(() => clamp(parseFloat(props.bufferValue) / max.value * 100, 0, 100));
  5003. const normalizedValue = computed(() => clamp(parseFloat(progress.value) / max.value * 100, 0, 100));
  5004. const isReversed = computed(() => isRtl.value !== props.reverse);
  5005. const transition = computed(() => props.indeterminate ? 'fade-transition' : 'slide-x-transition');
  5006. const isForcedColorsModeActive = IN_BROWSER && window.matchMedia?.('(forced-colors: active)').matches;
  5007. function handleClick(e) {
  5008. if (!intersectionRef.value) return;
  5009. const {
  5010. left,
  5011. right,
  5012. width
  5013. } = intersectionRef.value.getBoundingClientRect();
  5014. const value = isReversed.value ? width - e.clientX + (right - width) : e.clientX - left;
  5015. progress.value = Math.round(value / width * max.value);
  5016. }
  5017. useRender(() => createVNode(props.tag, {
  5018. "ref": intersectionRef,
  5019. "class": ['v-progress-linear', {
  5020. 'v-progress-linear--absolute': props.absolute,
  5021. 'v-progress-linear--active': props.active && isIntersecting.value,
  5022. 'v-progress-linear--reverse': isReversed.value,
  5023. 'v-progress-linear--rounded': props.rounded,
  5024. 'v-progress-linear--rounded-bar': props.roundedBar,
  5025. 'v-progress-linear--striped': props.striped
  5026. }, roundedClasses.value, themeClasses.value, rtlClasses.value, props.class],
  5027. "style": [{
  5028. bottom: props.location === 'bottom' ? 0 : undefined,
  5029. top: props.location === 'top' ? 0 : undefined,
  5030. height: props.active ? convertToUnit(height.value) : 0,
  5031. '--v-progress-linear-height': convertToUnit(height.value),
  5032. ...(props.absolute ? locationStyles.value : {})
  5033. }, props.style],
  5034. "role": "progressbar",
  5035. "aria-hidden": props.active ? 'false' : 'true',
  5036. "aria-valuemin": "0",
  5037. "aria-valuemax": props.max,
  5038. "aria-valuenow": props.indeterminate ? undefined : normalizedValue.value,
  5039. "onClick": props.clickable && handleClick
  5040. }, {
  5041. default: () => [props.stream && createVNode("div", {
  5042. "key": "stream",
  5043. "class": ['v-progress-linear__stream', textColorClasses.value],
  5044. "style": {
  5045. ...textColorStyles.value,
  5046. [isReversed.value ? 'left' : 'right']: convertToUnit(-height.value),
  5047. borderTop: `${convertToUnit(height.value / 2)} dotted`,
  5048. opacity: parseFloat(props.bufferOpacity),
  5049. top: `calc(50% - ${convertToUnit(height.value / 4)})`,
  5050. width: convertToUnit(100 - normalizedBuffer.value, '%'),
  5051. '--v-progress-linear-stream-to': convertToUnit(height.value * (isReversed.value ? 1 : -1))
  5052. }
  5053. }, null), createVNode("div", {
  5054. "class": ['v-progress-linear__background', !isForcedColorsModeActive ? backgroundColorClasses.value : undefined],
  5055. "style": [backgroundColorStyles.value, {
  5056. opacity: parseFloat(props.bgOpacity),
  5057. width: props.stream ? 0 : undefined
  5058. }]
  5059. }, null), createVNode("div", {
  5060. "class": ['v-progress-linear__buffer', !isForcedColorsModeActive ? bufferColorClasses.value : undefined],
  5061. "style": [bufferColorStyles.value, {
  5062. opacity: parseFloat(props.bufferOpacity),
  5063. width: convertToUnit(normalizedBuffer.value, '%')
  5064. }]
  5065. }, null), createVNode(Transition, {
  5066. "name": transition.value
  5067. }, {
  5068. default: () => [!props.indeterminate ? createVNode("div", {
  5069. "class": ['v-progress-linear__determinate', !isForcedColorsModeActive ? barColorClasses.value : undefined],
  5070. "style": [barColorStyles.value, {
  5071. width: convertToUnit(normalizedValue.value, '%')
  5072. }]
  5073. }, null) : createVNode("div", {
  5074. "class": "v-progress-linear__indeterminate"
  5075. }, [['long', 'short'].map(bar => createVNode("div", {
  5076. "key": bar,
  5077. "class": ['v-progress-linear__indeterminate', bar, !isForcedColorsModeActive ? barColorClasses.value : undefined],
  5078. "style": barColorStyles.value
  5079. }, null))])]
  5080. }), slots.default && createVNode("div", {
  5081. "class": "v-progress-linear__content"
  5082. }, [slots.default({
  5083. value: normalizedValue.value,
  5084. buffer: normalizedBuffer.value
  5085. })])]
  5086. }));
  5087. return {};
  5088. }
  5089. });
  5090. // Types
  5091. // Composables
  5092. const makeLoaderProps = propsFactory({
  5093. loading: [Boolean, String]
  5094. }, 'loader');
  5095. function useLoader(props) {
  5096. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  5097. const loaderClasses = computed(() => ({
  5098. [`${name}--loading`]: props.loading
  5099. }));
  5100. return {
  5101. loaderClasses
  5102. };
  5103. }
  5104. function LoaderSlot(props, _ref) {
  5105. let {
  5106. slots
  5107. } = _ref;
  5108. return createVNode("div", {
  5109. "class": `${props.name}__loader`
  5110. }, [slots.default?.({
  5111. color: props.color,
  5112. isActive: props.active
  5113. }) || createVNode(VProgressLinear, {
  5114. "absolute": props.absolute,
  5115. "active": props.active,
  5116. "color": props.color,
  5117. "height": "2",
  5118. "indeterminate": true
  5119. }, null)]);
  5120. }
  5121. // Utilities
  5122. // Types
  5123. const positionValues = ['static', 'relative', 'fixed', 'absolute', 'sticky'];
  5124. // Composables
  5125. const makePositionProps = propsFactory({
  5126. position: {
  5127. type: String,
  5128. validator: /* istanbul ignore next */v => positionValues.includes(v)
  5129. }
  5130. }, 'position');
  5131. function usePosition(props) {
  5132. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  5133. const positionClasses = computed(() => {
  5134. return props.position ? `${name}--${props.position}` : undefined;
  5135. });
  5136. return {
  5137. positionClasses
  5138. };
  5139. }
  5140. // Utilities
  5141. // Types
  5142. function useRoute() {
  5143. const vm = getCurrentInstance('useRoute');
  5144. return computed(() => vm?.proxy?.$route);
  5145. }
  5146. function useRouter() {
  5147. return getCurrentInstance('useRouter')?.proxy?.$router;
  5148. }
  5149. function useLink(props, attrs) {
  5150. const RouterLink = resolveDynamicComponent('RouterLink');
  5151. const isLink = computed(() => !!(props.href || props.to));
  5152. const isClickable = computed(() => {
  5153. return isLink?.value || hasEvent(attrs, 'click') || hasEvent(props, 'click');
  5154. });
  5155. if (typeof RouterLink === 'string' || !('useLink' in RouterLink)) {
  5156. const href = toRef(props, 'href');
  5157. return {
  5158. isLink,
  5159. isClickable,
  5160. href,
  5161. linkProps: reactive({
  5162. href
  5163. })
  5164. };
  5165. }
  5166. // vue-router useLink `to` prop needs to be reactive and useLink will crash if undefined
  5167. const linkProps = computed(() => ({
  5168. ...props,
  5169. to: toRef(() => props.to || '')
  5170. }));
  5171. const routerLink = RouterLink.useLink(linkProps.value);
  5172. // Actual link needs to be undefined when to prop is not used
  5173. const link = computed(() => props.to ? routerLink : undefined);
  5174. const route = useRoute();
  5175. const isActive = computed(() => {
  5176. if (!link.value) return false;
  5177. if (!props.exact) return link.value.isActive?.value ?? false;
  5178. if (!route.value) return link.value.isExactActive?.value ?? false;
  5179. return link.value.isExactActive?.value && deepEqual(link.value.route.value.query, route.value.query);
  5180. });
  5181. const href = computed(() => props.to ? link.value?.route.value.href : props.href);
  5182. return {
  5183. isLink,
  5184. isClickable,
  5185. isActive,
  5186. route: link.value?.route,
  5187. navigate: link.value?.navigate,
  5188. href,
  5189. linkProps: reactive({
  5190. href,
  5191. 'aria-current': computed(() => isActive.value ? 'page' : undefined)
  5192. })
  5193. };
  5194. }
  5195. const makeRouterProps = propsFactory({
  5196. href: String,
  5197. replace: Boolean,
  5198. to: [String, Object],
  5199. exact: Boolean
  5200. }, 'router');
  5201. let inTransition = false;
  5202. function useBackButton(router, cb) {
  5203. let popped = false;
  5204. let removeBefore;
  5205. let removeAfter;
  5206. if (IN_BROWSER) {
  5207. nextTick(() => {
  5208. window.addEventListener('popstate', onPopstate);
  5209. removeBefore = router?.beforeEach((to, from, next) => {
  5210. if (!inTransition) {
  5211. setTimeout(() => popped ? cb(next) : next());
  5212. } else {
  5213. popped ? cb(next) : next();
  5214. }
  5215. inTransition = true;
  5216. });
  5217. removeAfter = router?.afterEach(() => {
  5218. inTransition = false;
  5219. });
  5220. });
  5221. onScopeDispose(() => {
  5222. window.removeEventListener('popstate', onPopstate);
  5223. removeBefore?.();
  5224. removeAfter?.();
  5225. });
  5226. }
  5227. function onPopstate(e) {
  5228. if (e.state?.replaced) return;
  5229. popped = true;
  5230. setTimeout(() => popped = false);
  5231. }
  5232. }
  5233. // Utilities
  5234. // Types
  5235. function useSelectLink(link, select) {
  5236. watch(() => link.isActive?.value, isActive => {
  5237. if (link.isLink.value && isActive && select) {
  5238. nextTick(() => {
  5239. select(true);
  5240. });
  5241. }
  5242. }, {
  5243. immediate: true
  5244. });
  5245. }
  5246. // Styles
  5247. // Types
  5248. const stopSymbol = Symbol('rippleStop');
  5249. const DELAY_RIPPLE = 80;
  5250. function transform(el, value) {
  5251. el.style.transform = value;
  5252. el.style.webkitTransform = value;
  5253. }
  5254. function isTouchEvent(e) {
  5255. return e.constructor.name === 'TouchEvent';
  5256. }
  5257. function isKeyboardEvent(e) {
  5258. return e.constructor.name === 'KeyboardEvent';
  5259. }
  5260. const calculate = function (e, el) {
  5261. let value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  5262. let localX = 0;
  5263. let localY = 0;
  5264. if (!isKeyboardEvent(e)) {
  5265. const offset = el.getBoundingClientRect();
  5266. const target = isTouchEvent(e) ? e.touches[e.touches.length - 1] : e;
  5267. localX = target.clientX - offset.left;
  5268. localY = target.clientY - offset.top;
  5269. }
  5270. let radius = 0;
  5271. let scale = 0.3;
  5272. if (el._ripple?.circle) {
  5273. scale = 0.15;
  5274. radius = el.clientWidth / 2;
  5275. radius = value.center ? radius : radius + Math.sqrt((localX - radius) ** 2 + (localY - radius) ** 2) / 4;
  5276. } else {
  5277. radius = Math.sqrt(el.clientWidth ** 2 + el.clientHeight ** 2) / 2;
  5278. }
  5279. const centerX = `${(el.clientWidth - radius * 2) / 2}px`;
  5280. const centerY = `${(el.clientHeight - radius * 2) / 2}px`;
  5281. const x = value.center ? centerX : `${localX - radius}px`;
  5282. const y = value.center ? centerY : `${localY - radius}px`;
  5283. return {
  5284. radius,
  5285. scale,
  5286. x,
  5287. y,
  5288. centerX,
  5289. centerY
  5290. };
  5291. };
  5292. const ripples = {
  5293. /* eslint-disable max-statements */
  5294. show(e, el) {
  5295. let value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  5296. if (!el?._ripple?.enabled) {
  5297. return;
  5298. }
  5299. const container = document.createElement('span');
  5300. const animation = document.createElement('span');
  5301. container.appendChild(animation);
  5302. container.className = 'v-ripple__container';
  5303. if (value.class) {
  5304. container.className += ` ${value.class}`;
  5305. }
  5306. const {
  5307. radius,
  5308. scale,
  5309. x,
  5310. y,
  5311. centerX,
  5312. centerY
  5313. } = calculate(e, el, value);
  5314. const size = `${radius * 2}px`;
  5315. animation.className = 'v-ripple__animation';
  5316. animation.style.width = size;
  5317. animation.style.height = size;
  5318. el.appendChild(container);
  5319. const computed = window.getComputedStyle(el);
  5320. if (computed && computed.position === 'static') {
  5321. el.style.position = 'relative';
  5322. el.dataset.previousPosition = 'static';
  5323. }
  5324. animation.classList.add('v-ripple__animation--enter');
  5325. animation.classList.add('v-ripple__animation--visible');
  5326. transform(animation, `translate(${x}, ${y}) scale3d(${scale},${scale},${scale})`);
  5327. animation.dataset.activated = String(performance.now());
  5328. setTimeout(() => {
  5329. animation.classList.remove('v-ripple__animation--enter');
  5330. animation.classList.add('v-ripple__animation--in');
  5331. transform(animation, `translate(${centerX}, ${centerY}) scale3d(1,1,1)`);
  5332. }, 0);
  5333. },
  5334. hide(el) {
  5335. if (!el?._ripple?.enabled) return;
  5336. const ripples = el.getElementsByClassName('v-ripple__animation');
  5337. if (ripples.length === 0) return;
  5338. const animation = ripples[ripples.length - 1];
  5339. if (animation.dataset.isHiding) return;else animation.dataset.isHiding = 'true';
  5340. const diff = performance.now() - Number(animation.dataset.activated);
  5341. const delay = Math.max(250 - diff, 0);
  5342. setTimeout(() => {
  5343. animation.classList.remove('v-ripple__animation--in');
  5344. animation.classList.add('v-ripple__animation--out');
  5345. setTimeout(() => {
  5346. const ripples = el.getElementsByClassName('v-ripple__animation');
  5347. if (ripples.length === 1 && el.dataset.previousPosition) {
  5348. el.style.position = el.dataset.previousPosition;
  5349. delete el.dataset.previousPosition;
  5350. }
  5351. if (animation.parentNode?.parentNode === el) el.removeChild(animation.parentNode);
  5352. }, 300);
  5353. }, delay);
  5354. }
  5355. };
  5356. function isRippleEnabled(value) {
  5357. return typeof value === 'undefined' || !!value;
  5358. }
  5359. function rippleShow(e) {
  5360. const value = {};
  5361. const element = e.currentTarget;
  5362. if (!element?._ripple || element._ripple.touched || e[stopSymbol]) return;
  5363. // Don't allow the event to trigger ripples on any other elements
  5364. e[stopSymbol] = true;
  5365. if (isTouchEvent(e)) {
  5366. element._ripple.touched = true;
  5367. element._ripple.isTouch = true;
  5368. } else {
  5369. // It's possible for touch events to fire
  5370. // as mouse events on Android/iOS, this
  5371. // will skip the event call if it has
  5372. // already been registered as touch
  5373. if (element._ripple.isTouch) return;
  5374. }
  5375. value.center = element._ripple.centered || isKeyboardEvent(e);
  5376. if (element._ripple.class) {
  5377. value.class = element._ripple.class;
  5378. }
  5379. if (isTouchEvent(e)) {
  5380. // already queued that shows or hides the ripple
  5381. if (element._ripple.showTimerCommit) return;
  5382. element._ripple.showTimerCommit = () => {
  5383. ripples.show(e, element, value);
  5384. };
  5385. element._ripple.showTimer = window.setTimeout(() => {
  5386. if (element?._ripple?.showTimerCommit) {
  5387. element._ripple.showTimerCommit();
  5388. element._ripple.showTimerCommit = null;
  5389. }
  5390. }, DELAY_RIPPLE);
  5391. } else {
  5392. ripples.show(e, element, value);
  5393. }
  5394. }
  5395. function rippleStop(e) {
  5396. e[stopSymbol] = true;
  5397. }
  5398. function rippleHide(e) {
  5399. const element = e.currentTarget;
  5400. if (!element?._ripple) return;
  5401. window.clearTimeout(element._ripple.showTimer);
  5402. // The touch interaction occurs before the show timer is triggered.
  5403. // We still want to show ripple effect.
  5404. if (e.type === 'touchend' && element._ripple.showTimerCommit) {
  5405. element._ripple.showTimerCommit();
  5406. element._ripple.showTimerCommit = null;
  5407. // re-queue ripple hiding
  5408. element._ripple.showTimer = window.setTimeout(() => {
  5409. rippleHide(e);
  5410. });
  5411. return;
  5412. }
  5413. window.setTimeout(() => {
  5414. if (element._ripple) {
  5415. element._ripple.touched = false;
  5416. }
  5417. });
  5418. ripples.hide(element);
  5419. }
  5420. function rippleCancelShow(e) {
  5421. const element = e.currentTarget;
  5422. if (!element?._ripple) return;
  5423. if (element._ripple.showTimerCommit) {
  5424. element._ripple.showTimerCommit = null;
  5425. }
  5426. window.clearTimeout(element._ripple.showTimer);
  5427. }
  5428. let keyboardRipple = false;
  5429. function keyboardRippleShow(e) {
  5430. if (!keyboardRipple && (e.keyCode === keyCodes.enter || e.keyCode === keyCodes.space)) {
  5431. keyboardRipple = true;
  5432. rippleShow(e);
  5433. }
  5434. }
  5435. function keyboardRippleHide(e) {
  5436. keyboardRipple = false;
  5437. rippleHide(e);
  5438. }
  5439. function focusRippleHide(e) {
  5440. if (keyboardRipple) {
  5441. keyboardRipple = false;
  5442. rippleHide(e);
  5443. }
  5444. }
  5445. function updateRipple(el, binding, wasEnabled) {
  5446. const {
  5447. value,
  5448. modifiers
  5449. } = binding;
  5450. const enabled = isRippleEnabled(value);
  5451. if (!enabled) {
  5452. ripples.hide(el);
  5453. }
  5454. el._ripple = el._ripple ?? {};
  5455. el._ripple.enabled = enabled;
  5456. el._ripple.centered = modifiers.center;
  5457. el._ripple.circle = modifiers.circle;
  5458. if (isObject(value) && value.class) {
  5459. el._ripple.class = value.class;
  5460. }
  5461. if (enabled && !wasEnabled) {
  5462. if (modifiers.stop) {
  5463. el.addEventListener('touchstart', rippleStop, {
  5464. passive: true
  5465. });
  5466. el.addEventListener('mousedown', rippleStop);
  5467. return;
  5468. }
  5469. el.addEventListener('touchstart', rippleShow, {
  5470. passive: true
  5471. });
  5472. el.addEventListener('touchend', rippleHide, {
  5473. passive: true
  5474. });
  5475. el.addEventListener('touchmove', rippleCancelShow, {
  5476. passive: true
  5477. });
  5478. el.addEventListener('touchcancel', rippleHide);
  5479. el.addEventListener('mousedown', rippleShow);
  5480. el.addEventListener('mouseup', rippleHide);
  5481. el.addEventListener('mouseleave', rippleHide);
  5482. el.addEventListener('keydown', keyboardRippleShow);
  5483. el.addEventListener('keyup', keyboardRippleHide);
  5484. el.addEventListener('blur', focusRippleHide);
  5485. // Anchor tags can be dragged, causes other hides to fail - #1537
  5486. el.addEventListener('dragstart', rippleHide, {
  5487. passive: true
  5488. });
  5489. } else if (!enabled && wasEnabled) {
  5490. removeListeners(el);
  5491. }
  5492. }
  5493. function removeListeners(el) {
  5494. el.removeEventListener('mousedown', rippleShow);
  5495. el.removeEventListener('touchstart', rippleShow);
  5496. el.removeEventListener('touchend', rippleHide);
  5497. el.removeEventListener('touchmove', rippleCancelShow);
  5498. el.removeEventListener('touchcancel', rippleHide);
  5499. el.removeEventListener('mouseup', rippleHide);
  5500. el.removeEventListener('mouseleave', rippleHide);
  5501. el.removeEventListener('keydown', keyboardRippleShow);
  5502. el.removeEventListener('keyup', keyboardRippleHide);
  5503. el.removeEventListener('dragstart', rippleHide);
  5504. el.removeEventListener('blur', focusRippleHide);
  5505. }
  5506. function mounted$4(el, binding) {
  5507. updateRipple(el, binding, false);
  5508. }
  5509. function unmounted$4(el) {
  5510. delete el._ripple;
  5511. removeListeners(el);
  5512. }
  5513. function updated$1(el, binding) {
  5514. if (binding.value === binding.oldValue) {
  5515. return;
  5516. }
  5517. const wasEnabled = isRippleEnabled(binding.oldValue);
  5518. updateRipple(el, binding, wasEnabled);
  5519. }
  5520. const Ripple = {
  5521. mounted: mounted$4,
  5522. unmounted: unmounted$4,
  5523. updated: updated$1
  5524. };
  5525. // Types
  5526. const makeVBtnProps = propsFactory({
  5527. active: {
  5528. type: Boolean,
  5529. default: undefined
  5530. },
  5531. activeColor: String,
  5532. baseColor: String,
  5533. symbol: {
  5534. type: null,
  5535. default: VBtnToggleSymbol
  5536. },
  5537. flat: Boolean,
  5538. icon: [Boolean, String, Function, Object],
  5539. prependIcon: IconValue,
  5540. appendIcon: IconValue,
  5541. block: Boolean,
  5542. readonly: Boolean,
  5543. slim: Boolean,
  5544. stacked: Boolean,
  5545. ripple: {
  5546. type: [Boolean, Object],
  5547. default: true
  5548. },
  5549. text: String,
  5550. ...makeBorderProps(),
  5551. ...makeComponentProps(),
  5552. ...makeDensityProps(),
  5553. ...makeDimensionProps(),
  5554. ...makeElevationProps(),
  5555. ...makeGroupItemProps(),
  5556. ...makeLoaderProps(),
  5557. ...makeLocationProps(),
  5558. ...makePositionProps(),
  5559. ...makeRoundedProps(),
  5560. ...makeRouterProps(),
  5561. ...makeSizeProps(),
  5562. ...makeTagProps({
  5563. tag: 'button'
  5564. }),
  5565. ...makeThemeProps(),
  5566. ...makeVariantProps({
  5567. variant: 'elevated'
  5568. })
  5569. }, 'VBtn');
  5570. const VBtn = genericComponent()({
  5571. name: 'VBtn',
  5572. props: makeVBtnProps(),
  5573. emits: {
  5574. 'group:selected': val => true
  5575. },
  5576. setup(props, _ref) {
  5577. let {
  5578. attrs,
  5579. slots
  5580. } = _ref;
  5581. const {
  5582. themeClasses
  5583. } = provideTheme(props);
  5584. const {
  5585. borderClasses
  5586. } = useBorder(props);
  5587. const {
  5588. densityClasses
  5589. } = useDensity(props);
  5590. const {
  5591. dimensionStyles
  5592. } = useDimension(props);
  5593. const {
  5594. elevationClasses
  5595. } = useElevation(props);
  5596. const {
  5597. loaderClasses
  5598. } = useLoader(props);
  5599. const {
  5600. locationStyles
  5601. } = useLocation(props);
  5602. const {
  5603. positionClasses
  5604. } = usePosition(props);
  5605. const {
  5606. roundedClasses
  5607. } = useRounded(props);
  5608. const {
  5609. sizeClasses,
  5610. sizeStyles
  5611. } = useSize(props);
  5612. const group = useGroupItem(props, props.symbol, false);
  5613. const link = useLink(props, attrs);
  5614. const isActive = computed(() => {
  5615. if (props.active !== undefined) {
  5616. return props.active;
  5617. }
  5618. if (link.isLink.value) {
  5619. return link.isActive?.value;
  5620. }
  5621. return group?.isSelected.value;
  5622. });
  5623. const color = computed(() => isActive.value ? props.activeColor ?? props.color : props.color);
  5624. const variantProps = computed(() => {
  5625. const showColor = group?.isSelected.value && (!link.isLink.value || link.isActive?.value) || !group || link.isActive?.value;
  5626. return {
  5627. color: showColor ? color.value ?? props.baseColor : props.baseColor,
  5628. variant: props.variant
  5629. };
  5630. });
  5631. const {
  5632. colorClasses,
  5633. colorStyles,
  5634. variantClasses
  5635. } = useVariant(variantProps);
  5636. const isDisabled = computed(() => group?.disabled.value || props.disabled);
  5637. const isElevated = computed(() => {
  5638. return props.variant === 'elevated' && !(props.disabled || props.flat || props.border);
  5639. });
  5640. const valueAttr = computed(() => {
  5641. if (props.value === undefined || typeof props.value === 'symbol') return undefined;
  5642. return Object(props.value) === props.value ? JSON.stringify(props.value, null, 0) : props.value;
  5643. });
  5644. function onClick(e) {
  5645. if (isDisabled.value || link.isLink.value && (e.metaKey || e.ctrlKey || e.shiftKey || e.button !== 0 || attrs.target === '_blank')) return;
  5646. link.navigate?.(e);
  5647. group?.toggle();
  5648. }
  5649. useSelectLink(link, group?.select);
  5650. useRender(() => {
  5651. const Tag = link.isLink.value ? 'a' : props.tag;
  5652. const hasPrepend = !!(props.prependIcon || slots.prepend);
  5653. const hasAppend = !!(props.appendIcon || slots.append);
  5654. const hasIcon = !!(props.icon && props.icon !== true);
  5655. return withDirectives(createVNode(Tag, mergeProps({
  5656. "type": Tag === 'a' ? undefined : 'button',
  5657. "class": ['v-btn', group?.selectedClass.value, {
  5658. 'v-btn--active': isActive.value,
  5659. 'v-btn--block': props.block,
  5660. 'v-btn--disabled': isDisabled.value,
  5661. 'v-btn--elevated': isElevated.value,
  5662. 'v-btn--flat': props.flat,
  5663. 'v-btn--icon': !!props.icon,
  5664. 'v-btn--loading': props.loading,
  5665. 'v-btn--readonly': props.readonly,
  5666. 'v-btn--slim': props.slim,
  5667. 'v-btn--stacked': props.stacked
  5668. }, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, loaderClasses.value, positionClasses.value, roundedClasses.value, sizeClasses.value, variantClasses.value, props.class],
  5669. "style": [colorStyles.value, dimensionStyles.value, locationStyles.value, sizeStyles.value, props.style],
  5670. "aria-busy": props.loading ? true : undefined,
  5671. "disabled": isDisabled.value || undefined,
  5672. "tabindex": props.loading || props.readonly ? -1 : undefined,
  5673. "onClick": onClick,
  5674. "value": valueAttr.value
  5675. }, link.linkProps), {
  5676. default: () => [genOverlays(true, 'v-btn'), !props.icon && hasPrepend && createVNode("span", {
  5677. "key": "prepend",
  5678. "class": "v-btn__prepend"
  5679. }, [!slots.prepend ? createVNode(VIcon, {
  5680. "key": "prepend-icon",
  5681. "icon": props.prependIcon
  5682. }, null) : createVNode(VDefaultsProvider, {
  5683. "key": "prepend-defaults",
  5684. "disabled": !props.prependIcon,
  5685. "defaults": {
  5686. VIcon: {
  5687. icon: props.prependIcon
  5688. }
  5689. }
  5690. }, slots.prepend)]), createVNode("span", {
  5691. "class": "v-btn__content",
  5692. "data-no-activator": ""
  5693. }, [!slots.default && hasIcon ? createVNode(VIcon, {
  5694. "key": "content-icon",
  5695. "icon": props.icon
  5696. }, null) : createVNode(VDefaultsProvider, {
  5697. "key": "content-defaults",
  5698. "disabled": !hasIcon,
  5699. "defaults": {
  5700. VIcon: {
  5701. icon: props.icon
  5702. }
  5703. }
  5704. }, {
  5705. default: () => [slots.default?.() ?? props.text]
  5706. })]), !props.icon && hasAppend && createVNode("span", {
  5707. "key": "append",
  5708. "class": "v-btn__append"
  5709. }, [!slots.append ? createVNode(VIcon, {
  5710. "key": "append-icon",
  5711. "icon": props.appendIcon
  5712. }, null) : createVNode(VDefaultsProvider, {
  5713. "key": "append-defaults",
  5714. "disabled": !props.appendIcon,
  5715. "defaults": {
  5716. VIcon: {
  5717. icon: props.appendIcon
  5718. }
  5719. }
  5720. }, slots.append)]), !!props.loading && createVNode("span", {
  5721. "key": "loader",
  5722. "class": "v-btn__loader"
  5723. }, [slots.loader?.() ?? createVNode(VProgressCircular, {
  5724. "color": typeof props.loading === 'boolean' ? undefined : props.loading,
  5725. "indeterminate": true,
  5726. "width": "2"
  5727. }, null)])]
  5728. }), [[Ripple, !isDisabled.value && props.ripple, '', {
  5729. center: !!props.icon
  5730. }]]);
  5731. });
  5732. return {
  5733. group
  5734. };
  5735. }
  5736. });
  5737. // Types
  5738. const makeVAppBarNavIconProps = propsFactory({
  5739. ...makeVBtnProps({
  5740. icon: '$menu',
  5741. variant: 'text'
  5742. })
  5743. }, 'VAppBarNavIcon');
  5744. const VAppBarNavIcon = genericComponent()({
  5745. name: 'VAppBarNavIcon',
  5746. props: makeVAppBarNavIconProps(),
  5747. setup(props, _ref) {
  5748. let {
  5749. slots
  5750. } = _ref;
  5751. useRender(() => createVNode(VBtn, mergeProps(props, {
  5752. "class": ['v-app-bar-nav-icon']
  5753. }), slots));
  5754. return {};
  5755. }
  5756. });
  5757. // Types
  5758. const VAppBarTitle = genericComponent()({
  5759. name: 'VAppBarTitle',
  5760. props: makeVToolbarTitleProps(),
  5761. setup(props, _ref) {
  5762. let {
  5763. slots
  5764. } = _ref;
  5765. useRender(() => createVNode(VToolbarTitle, mergeProps(props, {
  5766. "class": "v-app-bar-title"
  5767. }), slots));
  5768. return {};
  5769. }
  5770. });
  5771. // Utilities
  5772. const VAlertTitle = createSimpleFunctional('v-alert-title');
  5773. // Types
  5774. const allowedTypes = ['success', 'info', 'warning', 'error'];
  5775. const makeVAlertProps = propsFactory({
  5776. border: {
  5777. type: [Boolean, String],
  5778. validator: val => {
  5779. return typeof val === 'boolean' || ['top', 'end', 'bottom', 'start'].includes(val);
  5780. }
  5781. },
  5782. borderColor: String,
  5783. closable: Boolean,
  5784. closeIcon: {
  5785. type: IconValue,
  5786. default: '$close'
  5787. },
  5788. closeLabel: {
  5789. type: String,
  5790. default: '$vuetify.close'
  5791. },
  5792. icon: {
  5793. type: [Boolean, String, Function, Object],
  5794. default: null
  5795. },
  5796. modelValue: {
  5797. type: Boolean,
  5798. default: true
  5799. },
  5800. prominent: Boolean,
  5801. title: String,
  5802. text: String,
  5803. type: {
  5804. type: String,
  5805. validator: val => allowedTypes.includes(val)
  5806. },
  5807. ...makeComponentProps(),
  5808. ...makeDensityProps(),
  5809. ...makeDimensionProps(),
  5810. ...makeElevationProps(),
  5811. ...makeLocationProps(),
  5812. ...makePositionProps(),
  5813. ...makeRoundedProps(),
  5814. ...makeTagProps(),
  5815. ...makeThemeProps(),
  5816. ...makeVariantProps({
  5817. variant: 'flat'
  5818. })
  5819. }, 'VAlert');
  5820. const VAlert = genericComponent()({
  5821. name: 'VAlert',
  5822. props: makeVAlertProps(),
  5823. emits: {
  5824. 'click:close': e => true,
  5825. 'update:modelValue': value => true
  5826. },
  5827. setup(props, _ref) {
  5828. let {
  5829. emit,
  5830. slots
  5831. } = _ref;
  5832. const isActive = useProxiedModel(props, 'modelValue');
  5833. const icon = computed(() => {
  5834. if (props.icon === false) return undefined;
  5835. if (!props.type) return props.icon;
  5836. return props.icon ?? `$${props.type}`;
  5837. });
  5838. const variantProps = computed(() => ({
  5839. color: props.color ?? props.type,
  5840. variant: props.variant
  5841. }));
  5842. const {
  5843. themeClasses
  5844. } = provideTheme(props);
  5845. const {
  5846. colorClasses,
  5847. colorStyles,
  5848. variantClasses
  5849. } = useVariant(variantProps);
  5850. const {
  5851. densityClasses
  5852. } = useDensity(props);
  5853. const {
  5854. dimensionStyles
  5855. } = useDimension(props);
  5856. const {
  5857. elevationClasses
  5858. } = useElevation(props);
  5859. const {
  5860. locationStyles
  5861. } = useLocation(props);
  5862. const {
  5863. positionClasses
  5864. } = usePosition(props);
  5865. const {
  5866. roundedClasses
  5867. } = useRounded(props);
  5868. const {
  5869. textColorClasses,
  5870. textColorStyles
  5871. } = useTextColor(toRef(props, 'borderColor'));
  5872. const {
  5873. t
  5874. } = useLocale();
  5875. const closeProps = computed(() => ({
  5876. 'aria-label': t(props.closeLabel),
  5877. onClick(e) {
  5878. isActive.value = false;
  5879. emit('click:close', e);
  5880. }
  5881. }));
  5882. return () => {
  5883. const hasPrepend = !!(slots.prepend || icon.value);
  5884. const hasTitle = !!(slots.title || props.title);
  5885. const hasClose = !!(slots.close || props.closable);
  5886. return isActive.value && createVNode(props.tag, {
  5887. "class": ['v-alert', props.border && {
  5888. 'v-alert--border': !!props.border,
  5889. [`v-alert--border-${props.border === true ? 'start' : props.border}`]: true
  5890. }, {
  5891. 'v-alert--prominent': props.prominent
  5892. }, themeClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, positionClasses.value, roundedClasses.value, variantClasses.value, props.class],
  5893. "style": [colorStyles.value, dimensionStyles.value, locationStyles.value, props.style],
  5894. "role": "alert"
  5895. }, {
  5896. default: () => [genOverlays(false, 'v-alert'), props.border && createVNode("div", {
  5897. "key": "border",
  5898. "class": ['v-alert__border', textColorClasses.value],
  5899. "style": textColorStyles.value
  5900. }, null), hasPrepend && createVNode("div", {
  5901. "key": "prepend",
  5902. "class": "v-alert__prepend"
  5903. }, [!slots.prepend ? createVNode(VIcon, {
  5904. "key": "prepend-icon",
  5905. "density": props.density,
  5906. "icon": icon.value,
  5907. "size": props.prominent ? 44 : 28
  5908. }, null) : createVNode(VDefaultsProvider, {
  5909. "key": "prepend-defaults",
  5910. "disabled": !icon.value,
  5911. "defaults": {
  5912. VIcon: {
  5913. density: props.density,
  5914. icon: icon.value,
  5915. size: props.prominent ? 44 : 28
  5916. }
  5917. }
  5918. }, slots.prepend)]), createVNode("div", {
  5919. "class": "v-alert__content"
  5920. }, [hasTitle && createVNode(VAlertTitle, {
  5921. "key": "title"
  5922. }, {
  5923. default: () => [slots.title?.() ?? props.title]
  5924. }), slots.text?.() ?? props.text, slots.default?.()]), slots.append && createVNode("div", {
  5925. "key": "append",
  5926. "class": "v-alert__append"
  5927. }, [slots.append()]), hasClose && createVNode("div", {
  5928. "key": "close",
  5929. "class": "v-alert__close"
  5930. }, [!slots.close ? createVNode(VBtn, mergeProps({
  5931. "key": "close-btn",
  5932. "icon": props.closeIcon,
  5933. "size": "x-small",
  5934. "variant": "text"
  5935. }, closeProps.value), null) : createVNode(VDefaultsProvider, {
  5936. "key": "close-defaults",
  5937. "defaults": {
  5938. VBtn: {
  5939. icon: props.closeIcon,
  5940. size: 'x-small',
  5941. variant: 'text'
  5942. }
  5943. }
  5944. }, {
  5945. default: () => [slots.close?.({
  5946. props: closeProps.value
  5947. })]
  5948. })])]
  5949. });
  5950. };
  5951. }
  5952. });
  5953. const makeVAvatarProps = propsFactory({
  5954. start: Boolean,
  5955. end: Boolean,
  5956. icon: IconValue,
  5957. image: String,
  5958. text: String,
  5959. ...makeBorderProps(),
  5960. ...makeComponentProps(),
  5961. ...makeDensityProps(),
  5962. ...makeRoundedProps(),
  5963. ...makeSizeProps(),
  5964. ...makeTagProps(),
  5965. ...makeThemeProps(),
  5966. ...makeVariantProps({
  5967. variant: 'flat'
  5968. })
  5969. }, 'VAvatar');
  5970. const VAvatar = genericComponent()({
  5971. name: 'VAvatar',
  5972. props: makeVAvatarProps(),
  5973. setup(props, _ref) {
  5974. let {
  5975. slots
  5976. } = _ref;
  5977. const {
  5978. themeClasses
  5979. } = provideTheme(props);
  5980. const {
  5981. borderClasses
  5982. } = useBorder(props);
  5983. const {
  5984. colorClasses,
  5985. colorStyles,
  5986. variantClasses
  5987. } = useVariant(props);
  5988. const {
  5989. densityClasses
  5990. } = useDensity(props);
  5991. const {
  5992. roundedClasses
  5993. } = useRounded(props);
  5994. const {
  5995. sizeClasses,
  5996. sizeStyles
  5997. } = useSize(props);
  5998. useRender(() => createVNode(props.tag, {
  5999. "class": ['v-avatar', {
  6000. 'v-avatar--start': props.start,
  6001. 'v-avatar--end': props.end
  6002. }, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, roundedClasses.value, sizeClasses.value, variantClasses.value, props.class],
  6003. "style": [colorStyles.value, sizeStyles.value, props.style]
  6004. }, {
  6005. default: () => [!slots.default ? props.image ? createVNode(VImg, {
  6006. "key": "image",
  6007. "src": props.image,
  6008. "alt": "",
  6009. "cover": true
  6010. }, null) : props.icon ? createVNode(VIcon, {
  6011. "key": "icon",
  6012. "icon": props.icon
  6013. }, null) : props.text : createVNode(VDefaultsProvider, {
  6014. "key": "content-defaults",
  6015. "defaults": {
  6016. VImg: {
  6017. cover: true,
  6018. src: props.image
  6019. },
  6020. VIcon: {
  6021. icon: props.icon
  6022. }
  6023. }
  6024. }, {
  6025. default: () => [slots.default()]
  6026. }), genOverlays(false, 'v-avatar')]
  6027. }));
  6028. return {};
  6029. }
  6030. });
  6031. const makeVLabelProps = propsFactory({
  6032. text: String,
  6033. onClick: EventProp(),
  6034. ...makeComponentProps(),
  6035. ...makeThemeProps()
  6036. }, 'VLabel');
  6037. const VLabel = genericComponent()({
  6038. name: 'VLabel',
  6039. props: makeVLabelProps(),
  6040. setup(props, _ref) {
  6041. let {
  6042. slots
  6043. } = _ref;
  6044. useRender(() => createVNode("label", {
  6045. "class": ['v-label', {
  6046. 'v-label--clickable': !!props.onClick
  6047. }, props.class],
  6048. "style": props.style,
  6049. "onClick": props.onClick
  6050. }, [props.text, slots.default?.()]));
  6051. return {};
  6052. }
  6053. });
  6054. // Types
  6055. const VSelectionControlGroupSymbol = Symbol.for('vuetify:selection-control-group');
  6056. const makeSelectionControlGroupProps = propsFactory({
  6057. color: String,
  6058. disabled: {
  6059. type: Boolean,
  6060. default: null
  6061. },
  6062. defaultsTarget: String,
  6063. error: Boolean,
  6064. id: String,
  6065. inline: Boolean,
  6066. falseIcon: IconValue,
  6067. trueIcon: IconValue,
  6068. ripple: {
  6069. type: [Boolean, Object],
  6070. default: true
  6071. },
  6072. multiple: {
  6073. type: Boolean,
  6074. default: null
  6075. },
  6076. name: String,
  6077. readonly: {
  6078. type: Boolean,
  6079. default: null
  6080. },
  6081. modelValue: null,
  6082. type: String,
  6083. valueComparator: {
  6084. type: Function,
  6085. default: deepEqual
  6086. },
  6087. ...makeComponentProps(),
  6088. ...makeDensityProps(),
  6089. ...makeThemeProps()
  6090. }, 'SelectionControlGroup');
  6091. const makeVSelectionControlGroupProps = propsFactory({
  6092. ...makeSelectionControlGroupProps({
  6093. defaultsTarget: 'VSelectionControl'
  6094. })
  6095. }, 'VSelectionControlGroup');
  6096. const VSelectionControlGroup = genericComponent()({
  6097. name: 'VSelectionControlGroup',
  6098. props: makeVSelectionControlGroupProps(),
  6099. emits: {
  6100. 'update:modelValue': value => true
  6101. },
  6102. setup(props, _ref) {
  6103. let {
  6104. slots
  6105. } = _ref;
  6106. const modelValue = useProxiedModel(props, 'modelValue');
  6107. const uid = getUid();
  6108. const id = computed(() => props.id || `v-selection-control-group-${uid}`);
  6109. const name = computed(() => props.name || id.value);
  6110. const updateHandlers = new Set();
  6111. provide(VSelectionControlGroupSymbol, {
  6112. modelValue,
  6113. forceUpdate: () => {
  6114. updateHandlers.forEach(fn => fn());
  6115. },
  6116. onForceUpdate: cb => {
  6117. updateHandlers.add(cb);
  6118. onScopeDispose(() => {
  6119. updateHandlers.delete(cb);
  6120. });
  6121. }
  6122. });
  6123. provideDefaults({
  6124. [props.defaultsTarget]: {
  6125. color: toRef(props, 'color'),
  6126. disabled: toRef(props, 'disabled'),
  6127. density: toRef(props, 'density'),
  6128. error: toRef(props, 'error'),
  6129. inline: toRef(props, 'inline'),
  6130. modelValue,
  6131. multiple: computed(() => !!props.multiple || props.multiple == null && Array.isArray(modelValue.value)),
  6132. name,
  6133. falseIcon: toRef(props, 'falseIcon'),
  6134. trueIcon: toRef(props, 'trueIcon'),
  6135. readonly: toRef(props, 'readonly'),
  6136. ripple: toRef(props, 'ripple'),
  6137. type: toRef(props, 'type'),
  6138. valueComparator: toRef(props, 'valueComparator')
  6139. }
  6140. });
  6141. useRender(() => createVNode("div", {
  6142. "class": ['v-selection-control-group', {
  6143. 'v-selection-control-group--inline': props.inline
  6144. }, props.class],
  6145. "style": props.style,
  6146. "role": props.type === 'radio' ? 'radiogroup' : undefined
  6147. }, [slots.default?.()]));
  6148. return {};
  6149. }
  6150. });
  6151. // Types
  6152. const makeVSelectionControlProps = propsFactory({
  6153. label: String,
  6154. baseColor: String,
  6155. trueValue: null,
  6156. falseValue: null,
  6157. value: null,
  6158. ...makeComponentProps(),
  6159. ...makeSelectionControlGroupProps()
  6160. }, 'VSelectionControl');
  6161. function useSelectionControl(props) {
  6162. const group = inject$1(VSelectionControlGroupSymbol, undefined);
  6163. const {
  6164. densityClasses
  6165. } = useDensity(props);
  6166. const modelValue = useProxiedModel(props, 'modelValue');
  6167. const trueValue = computed(() => props.trueValue !== undefined ? props.trueValue : props.value !== undefined ? props.value : true);
  6168. const falseValue = computed(() => props.falseValue !== undefined ? props.falseValue : false);
  6169. const isMultiple = computed(() => !!props.multiple || props.multiple == null && Array.isArray(modelValue.value));
  6170. const model = computed({
  6171. get() {
  6172. const val = group ? group.modelValue.value : modelValue.value;
  6173. return isMultiple.value ? wrapInArray(val).some(v => props.valueComparator(v, trueValue.value)) : props.valueComparator(val, trueValue.value);
  6174. },
  6175. set(val) {
  6176. if (props.readonly) return;
  6177. const currentValue = val ? trueValue.value : falseValue.value;
  6178. let newVal = currentValue;
  6179. if (isMultiple.value) {
  6180. newVal = val ? [...wrapInArray(modelValue.value), currentValue] : wrapInArray(modelValue.value).filter(item => !props.valueComparator(item, trueValue.value));
  6181. }
  6182. if (group) {
  6183. group.modelValue.value = newVal;
  6184. } else {
  6185. modelValue.value = newVal;
  6186. }
  6187. }
  6188. });
  6189. const {
  6190. textColorClasses,
  6191. textColorStyles
  6192. } = useTextColor(computed(() => {
  6193. if (props.error || props.disabled) return undefined;
  6194. return model.value ? props.color : props.baseColor;
  6195. }));
  6196. const {
  6197. backgroundColorClasses,
  6198. backgroundColorStyles
  6199. } = useBackgroundColor(computed(() => {
  6200. return model.value && !props.error && !props.disabled ? props.color : props.baseColor;
  6201. }));
  6202. const icon = computed(() => model.value ? props.trueIcon : props.falseIcon);
  6203. return {
  6204. group,
  6205. densityClasses,
  6206. trueValue,
  6207. falseValue,
  6208. model,
  6209. textColorClasses,
  6210. textColorStyles,
  6211. backgroundColorClasses,
  6212. backgroundColorStyles,
  6213. icon
  6214. };
  6215. }
  6216. const VSelectionControl = genericComponent()({
  6217. name: 'VSelectionControl',
  6218. directives: {
  6219. Ripple
  6220. },
  6221. inheritAttrs: false,
  6222. props: makeVSelectionControlProps(),
  6223. emits: {
  6224. 'update:modelValue': value => true
  6225. },
  6226. setup(props, _ref) {
  6227. let {
  6228. attrs,
  6229. slots
  6230. } = _ref;
  6231. const {
  6232. group,
  6233. densityClasses,
  6234. icon,
  6235. model,
  6236. textColorClasses,
  6237. textColorStyles,
  6238. backgroundColorClasses,
  6239. backgroundColorStyles,
  6240. trueValue
  6241. } = useSelectionControl(props);
  6242. const uid = getUid();
  6243. const isFocused = shallowRef(false);
  6244. const isFocusVisible = shallowRef(false);
  6245. const input = ref();
  6246. const id = computed(() => props.id || `input-${uid}`);
  6247. const isInteractive = computed(() => !props.disabled && !props.readonly);
  6248. group?.onForceUpdate(() => {
  6249. if (input.value) {
  6250. input.value.checked = model.value;
  6251. }
  6252. });
  6253. function onFocus(e) {
  6254. if (!isInteractive.value) return;
  6255. isFocused.value = true;
  6256. if (matchesSelector(e.target, ':focus-visible') !== false) {
  6257. isFocusVisible.value = true;
  6258. }
  6259. }
  6260. function onBlur() {
  6261. isFocused.value = false;
  6262. isFocusVisible.value = false;
  6263. }
  6264. function onClickLabel(e) {
  6265. e.stopPropagation();
  6266. }
  6267. function onInput(e) {
  6268. if (!isInteractive.value) {
  6269. if (input.value) {
  6270. // model value is not updated when input is not interactive
  6271. // but the internal checked state of the input is still updated,
  6272. // so here it's value is restored
  6273. input.value.checked = model.value;
  6274. }
  6275. return;
  6276. }
  6277. if (props.readonly && group) {
  6278. nextTick(() => group.forceUpdate());
  6279. }
  6280. model.value = e.target.checked;
  6281. }
  6282. useRender(() => {
  6283. const label = slots.label ? slots.label({
  6284. label: props.label,
  6285. props: {
  6286. for: id.value
  6287. }
  6288. }) : props.label;
  6289. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  6290. const inputNode = createVNode("input", mergeProps({
  6291. "ref": input,
  6292. "checked": model.value,
  6293. "disabled": !!props.disabled,
  6294. "id": id.value,
  6295. "onBlur": onBlur,
  6296. "onFocus": onFocus,
  6297. "onInput": onInput,
  6298. "aria-disabled": !!props.disabled,
  6299. "aria-label": props.label,
  6300. "type": props.type,
  6301. "value": trueValue.value,
  6302. "name": props.name,
  6303. "aria-checked": props.type === 'checkbox' ? model.value : undefined
  6304. }, inputAttrs), null);
  6305. return createVNode("div", mergeProps({
  6306. "class": ['v-selection-control', {
  6307. 'v-selection-control--dirty': model.value,
  6308. 'v-selection-control--disabled': props.disabled,
  6309. 'v-selection-control--error': props.error,
  6310. 'v-selection-control--focused': isFocused.value,
  6311. 'v-selection-control--focus-visible': isFocusVisible.value,
  6312. 'v-selection-control--inline': props.inline
  6313. }, densityClasses.value, props.class]
  6314. }, rootAttrs, {
  6315. "style": props.style
  6316. }), [createVNode("div", {
  6317. "class": ['v-selection-control__wrapper', textColorClasses.value],
  6318. "style": textColorStyles.value
  6319. }, [slots.default?.({
  6320. backgroundColorClasses,
  6321. backgroundColorStyles
  6322. }), withDirectives(createVNode("div", {
  6323. "class": ['v-selection-control__input']
  6324. }, [slots.input?.({
  6325. model,
  6326. textColorClasses,
  6327. textColorStyles,
  6328. backgroundColorClasses,
  6329. backgroundColorStyles,
  6330. inputNode,
  6331. icon: icon.value,
  6332. props: {
  6333. onFocus,
  6334. onBlur,
  6335. id: id.value
  6336. }
  6337. }) ?? createVNode(Fragment, null, [icon.value && createVNode(VIcon, {
  6338. "key": "icon",
  6339. "icon": icon.value
  6340. }, null), inputNode])]), [[resolveDirective("ripple"), props.ripple && [!props.disabled && !props.readonly, null, ['center', 'circle']]]])]), label && createVNode(VLabel, {
  6341. "for": id.value,
  6342. "onClick": onClickLabel
  6343. }, {
  6344. default: () => [label]
  6345. })]);
  6346. });
  6347. return {
  6348. isFocused,
  6349. input
  6350. };
  6351. }
  6352. });
  6353. // Types
  6354. const makeVCheckboxBtnProps = propsFactory({
  6355. indeterminate: Boolean,
  6356. indeterminateIcon: {
  6357. type: IconValue,
  6358. default: '$checkboxIndeterminate'
  6359. },
  6360. ...makeVSelectionControlProps({
  6361. falseIcon: '$checkboxOff',
  6362. trueIcon: '$checkboxOn'
  6363. })
  6364. }, 'VCheckboxBtn');
  6365. const VCheckboxBtn = genericComponent()({
  6366. name: 'VCheckboxBtn',
  6367. props: makeVCheckboxBtnProps(),
  6368. emits: {
  6369. 'update:modelValue': value => true,
  6370. 'update:indeterminate': value => true
  6371. },
  6372. setup(props, _ref) {
  6373. let {
  6374. slots
  6375. } = _ref;
  6376. const indeterminate = useProxiedModel(props, 'indeterminate');
  6377. const model = useProxiedModel(props, 'modelValue');
  6378. function onChange(v) {
  6379. if (indeterminate.value) {
  6380. indeterminate.value = false;
  6381. }
  6382. }
  6383. const falseIcon = computed(() => {
  6384. return indeterminate.value ? props.indeterminateIcon : props.falseIcon;
  6385. });
  6386. const trueIcon = computed(() => {
  6387. return indeterminate.value ? props.indeterminateIcon : props.trueIcon;
  6388. });
  6389. useRender(() => {
  6390. const controlProps = omit(VSelectionControl.filterProps(props), ['modelValue']);
  6391. return createVNode(VSelectionControl, mergeProps(controlProps, {
  6392. "modelValue": model.value,
  6393. "onUpdate:modelValue": [$event => model.value = $event, onChange],
  6394. "class": ['v-checkbox-btn', props.class],
  6395. "style": props.style,
  6396. "type": "checkbox",
  6397. "falseIcon": falseIcon.value,
  6398. "trueIcon": trueIcon.value,
  6399. "aria-checked": indeterminate.value ? 'mixed' : undefined
  6400. }), slots);
  6401. });
  6402. return {};
  6403. }
  6404. });
  6405. // Types
  6406. function useInputIcon(props) {
  6407. const {
  6408. t
  6409. } = useLocale();
  6410. function InputIcon(_ref) {
  6411. let {
  6412. name
  6413. } = _ref;
  6414. const localeKey = {
  6415. prepend: 'prependAction',
  6416. prependInner: 'prependAction',
  6417. append: 'appendAction',
  6418. appendInner: 'appendAction',
  6419. clear: 'clear'
  6420. }[name];
  6421. const listener = props[`onClick:${name}`];
  6422. const label = listener && localeKey ? t(`$vuetify.input.${localeKey}`, props.label ?? '') : undefined;
  6423. return createVNode(VIcon, {
  6424. "icon": props[`${name}Icon`],
  6425. "aria-label": label,
  6426. "onClick": listener
  6427. }, null);
  6428. }
  6429. return {
  6430. InputIcon
  6431. };
  6432. }
  6433. // Types
  6434. const makeVMessagesProps = propsFactory({
  6435. active: Boolean,
  6436. color: String,
  6437. messages: {
  6438. type: [Array, String],
  6439. default: () => []
  6440. },
  6441. ...makeComponentProps(),
  6442. ...makeTransitionProps({
  6443. transition: {
  6444. component: VSlideYTransition,
  6445. leaveAbsolute: true,
  6446. group: true
  6447. }
  6448. })
  6449. }, 'VMessages');
  6450. const VMessages = genericComponent()({
  6451. name: 'VMessages',
  6452. props: makeVMessagesProps(),
  6453. setup(props, _ref) {
  6454. let {
  6455. slots
  6456. } = _ref;
  6457. const messages = computed(() => wrapInArray(props.messages));
  6458. const {
  6459. textColorClasses,
  6460. textColorStyles
  6461. } = useTextColor(computed(() => props.color));
  6462. useRender(() => createVNode(MaybeTransition, {
  6463. "transition": props.transition,
  6464. "tag": "div",
  6465. "class": ['v-messages', textColorClasses.value, props.class],
  6466. "style": [textColorStyles.value, props.style],
  6467. "role": "alert",
  6468. "aria-live": "polite"
  6469. }, {
  6470. default: () => [props.active && messages.value.map((message, i) => createVNode("div", {
  6471. "class": "v-messages__message",
  6472. "key": `${i}-${messages.value}`
  6473. }, [slots.message ? slots.message({
  6474. message
  6475. }) : message]))]
  6476. }));
  6477. return {};
  6478. }
  6479. });
  6480. // Composables
  6481. // Types
  6482. // Composables
  6483. const makeFocusProps = propsFactory({
  6484. focused: Boolean,
  6485. 'onUpdate:focused': EventProp()
  6486. }, 'focus');
  6487. function useFocus(props) {
  6488. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  6489. const isFocused = useProxiedModel(props, 'focused');
  6490. const focusClasses = computed(() => {
  6491. return {
  6492. [`${name}--focused`]: isFocused.value
  6493. };
  6494. });
  6495. function focus() {
  6496. isFocused.value = true;
  6497. }
  6498. function blur() {
  6499. isFocused.value = false;
  6500. }
  6501. return {
  6502. focusClasses,
  6503. isFocused,
  6504. focus,
  6505. blur
  6506. };
  6507. }
  6508. // Composables
  6509. // Types
  6510. const FormKey = Symbol.for('vuetify:form');
  6511. const makeFormProps = propsFactory({
  6512. disabled: Boolean,
  6513. fastFail: Boolean,
  6514. readonly: Boolean,
  6515. modelValue: {
  6516. type: Boolean,
  6517. default: null
  6518. },
  6519. validateOn: {
  6520. type: String,
  6521. default: 'input'
  6522. }
  6523. }, 'form');
  6524. function createForm(props) {
  6525. const model = useProxiedModel(props, 'modelValue');
  6526. const isDisabled = computed(() => props.disabled);
  6527. const isReadonly = computed(() => props.readonly);
  6528. const isValidating = shallowRef(false);
  6529. const items = ref([]);
  6530. const errors = ref([]);
  6531. async function validate() {
  6532. const results = [];
  6533. let valid = true;
  6534. errors.value = [];
  6535. isValidating.value = true;
  6536. for (const item of items.value) {
  6537. const itemErrorMessages = await item.validate();
  6538. if (itemErrorMessages.length > 0) {
  6539. valid = false;
  6540. results.push({
  6541. id: item.id,
  6542. errorMessages: itemErrorMessages
  6543. });
  6544. }
  6545. if (!valid && props.fastFail) break;
  6546. }
  6547. errors.value = results;
  6548. isValidating.value = false;
  6549. return {
  6550. valid,
  6551. errors: errors.value
  6552. };
  6553. }
  6554. function reset() {
  6555. items.value.forEach(item => item.reset());
  6556. }
  6557. function resetValidation() {
  6558. items.value.forEach(item => item.resetValidation());
  6559. }
  6560. watch(items, () => {
  6561. let valid = 0;
  6562. let invalid = 0;
  6563. const results = [];
  6564. for (const item of items.value) {
  6565. if (item.isValid === false) {
  6566. invalid++;
  6567. results.push({
  6568. id: item.id,
  6569. errorMessages: item.errorMessages
  6570. });
  6571. } else if (item.isValid === true) valid++;
  6572. }
  6573. errors.value = results;
  6574. model.value = invalid > 0 ? false : valid === items.value.length ? true : null;
  6575. }, {
  6576. deep: true,
  6577. flush: 'post'
  6578. });
  6579. provide(FormKey, {
  6580. register: _ref => {
  6581. let {
  6582. id,
  6583. vm,
  6584. validate,
  6585. reset,
  6586. resetValidation
  6587. } = _ref;
  6588. if (items.value.some(item => item.id === id)) {
  6589. consoleWarn(`Duplicate input name "${id}"`);
  6590. }
  6591. items.value.push({
  6592. id,
  6593. validate,
  6594. reset,
  6595. resetValidation,
  6596. vm: markRaw(vm),
  6597. isValid: null,
  6598. errorMessages: []
  6599. });
  6600. },
  6601. unregister: id => {
  6602. items.value = items.value.filter(item => {
  6603. return item.id !== id;
  6604. });
  6605. },
  6606. update: (id, isValid, errorMessages) => {
  6607. const found = items.value.find(item => item.id === id);
  6608. if (!found) return;
  6609. found.isValid = isValid;
  6610. found.errorMessages = errorMessages;
  6611. },
  6612. isDisabled,
  6613. isReadonly,
  6614. isValidating,
  6615. isValid: model,
  6616. items,
  6617. validateOn: toRef(props, 'validateOn')
  6618. });
  6619. return {
  6620. errors,
  6621. isDisabled,
  6622. isReadonly,
  6623. isValidating,
  6624. isValid: model,
  6625. items,
  6626. validate,
  6627. reset,
  6628. resetValidation
  6629. };
  6630. }
  6631. function useForm(props) {
  6632. const form = inject$1(FormKey, null);
  6633. return {
  6634. ...form,
  6635. isReadonly: computed(() => !!(props?.readonly ?? form?.isReadonly.value)),
  6636. isDisabled: computed(() => !!(props?.disabled ?? form?.isDisabled.value))
  6637. };
  6638. }
  6639. // Composables
  6640. // Types
  6641. const makeValidationProps = propsFactory({
  6642. disabled: {
  6643. type: Boolean,
  6644. default: null
  6645. },
  6646. error: Boolean,
  6647. errorMessages: {
  6648. type: [Array, String],
  6649. default: () => []
  6650. },
  6651. maxErrors: {
  6652. type: [Number, String],
  6653. default: 1
  6654. },
  6655. name: String,
  6656. label: String,
  6657. readonly: {
  6658. type: Boolean,
  6659. default: null
  6660. },
  6661. rules: {
  6662. type: Array,
  6663. default: () => []
  6664. },
  6665. modelValue: null,
  6666. validateOn: String,
  6667. validationValue: null,
  6668. ...makeFocusProps()
  6669. }, 'validation');
  6670. function useValidation(props) {
  6671. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  6672. let id = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getUid();
  6673. const model = useProxiedModel(props, 'modelValue');
  6674. const validationModel = computed(() => props.validationValue === undefined ? model.value : props.validationValue);
  6675. const form = useForm(props);
  6676. const internalErrorMessages = ref([]);
  6677. const isPristine = shallowRef(true);
  6678. const isDirty = computed(() => !!(wrapInArray(model.value === '' ? null : model.value).length || wrapInArray(validationModel.value === '' ? null : validationModel.value).length));
  6679. const errorMessages = computed(() => {
  6680. return props.errorMessages?.length ? wrapInArray(props.errorMessages).concat(internalErrorMessages.value).slice(0, Math.max(0, +props.maxErrors)) : internalErrorMessages.value;
  6681. });
  6682. const validateOn = computed(() => {
  6683. let value = (props.validateOn ?? form.validateOn?.value) || 'input';
  6684. if (value === 'lazy') value = 'input lazy';
  6685. if (value === 'eager') value = 'input eager';
  6686. const set = new Set(value?.split(' ') ?? []);
  6687. return {
  6688. input: set.has('input'),
  6689. blur: set.has('blur') || set.has('input') || set.has('invalid-input'),
  6690. invalidInput: set.has('invalid-input'),
  6691. lazy: set.has('lazy'),
  6692. eager: set.has('eager')
  6693. };
  6694. });
  6695. const isValid = computed(() => {
  6696. if (props.error || props.errorMessages?.length) return false;
  6697. if (!props.rules.length) return true;
  6698. if (isPristine.value) {
  6699. return internalErrorMessages.value.length || validateOn.value.lazy ? null : true;
  6700. } else {
  6701. return !internalErrorMessages.value.length;
  6702. }
  6703. });
  6704. const isValidating = shallowRef(false);
  6705. const validationClasses = computed(() => {
  6706. return {
  6707. [`${name}--error`]: isValid.value === false,
  6708. [`${name}--dirty`]: isDirty.value,
  6709. [`${name}--disabled`]: form.isDisabled.value,
  6710. [`${name}--readonly`]: form.isReadonly.value
  6711. };
  6712. });
  6713. const vm = getCurrentInstance('validation');
  6714. const uid = computed(() => props.name ?? unref(id));
  6715. onBeforeMount(() => {
  6716. form.register?.({
  6717. id: uid.value,
  6718. vm,
  6719. validate,
  6720. reset,
  6721. resetValidation
  6722. });
  6723. });
  6724. onBeforeUnmount(() => {
  6725. form.unregister?.(uid.value);
  6726. });
  6727. onMounted(async () => {
  6728. if (!validateOn.value.lazy) {
  6729. await validate(!validateOn.value.eager);
  6730. }
  6731. form.update?.(uid.value, isValid.value, errorMessages.value);
  6732. });
  6733. useToggleScope(() => validateOn.value.input || validateOn.value.invalidInput && isValid.value === false, () => {
  6734. watch(validationModel, () => {
  6735. if (validationModel.value != null) {
  6736. validate();
  6737. } else if (props.focused) {
  6738. const unwatch = watch(() => props.focused, val => {
  6739. if (!val) validate();
  6740. unwatch();
  6741. });
  6742. }
  6743. });
  6744. });
  6745. useToggleScope(() => validateOn.value.blur, () => {
  6746. watch(() => props.focused, val => {
  6747. if (!val) validate();
  6748. });
  6749. });
  6750. watch([isValid, errorMessages], () => {
  6751. form.update?.(uid.value, isValid.value, errorMessages.value);
  6752. });
  6753. async function reset() {
  6754. model.value = null;
  6755. await nextTick();
  6756. await resetValidation();
  6757. }
  6758. async function resetValidation() {
  6759. isPristine.value = true;
  6760. if (!validateOn.value.lazy) {
  6761. await validate(!validateOn.value.eager);
  6762. } else {
  6763. internalErrorMessages.value = [];
  6764. }
  6765. }
  6766. async function validate() {
  6767. let silent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
  6768. const results = [];
  6769. isValidating.value = true;
  6770. for (const rule of props.rules) {
  6771. if (results.length >= +(props.maxErrors ?? 1)) {
  6772. break;
  6773. }
  6774. const handler = typeof rule === 'function' ? rule : () => rule;
  6775. const result = await handler(validationModel.value);
  6776. if (result === true) continue;
  6777. if (result !== false && typeof result !== 'string') {
  6778. // eslint-disable-next-line no-console
  6779. console.warn(`${result} is not a valid value. Rule functions must return boolean true or a string.`);
  6780. continue;
  6781. }
  6782. results.push(result || '');
  6783. }
  6784. internalErrorMessages.value = results;
  6785. isValidating.value = false;
  6786. isPristine.value = silent;
  6787. return internalErrorMessages.value;
  6788. }
  6789. return {
  6790. errorMessages,
  6791. isDirty,
  6792. isDisabled: form.isDisabled,
  6793. isReadonly: form.isReadonly,
  6794. isPristine,
  6795. isValid,
  6796. isValidating,
  6797. reset,
  6798. resetValidation,
  6799. validate,
  6800. validationClasses
  6801. };
  6802. }
  6803. // Types
  6804. const makeVInputProps = propsFactory({
  6805. id: String,
  6806. appendIcon: IconValue,
  6807. centerAffix: {
  6808. type: Boolean,
  6809. default: true
  6810. },
  6811. prependIcon: IconValue,
  6812. hideDetails: [Boolean, String],
  6813. hideSpinButtons: Boolean,
  6814. hint: String,
  6815. persistentHint: Boolean,
  6816. messages: {
  6817. type: [Array, String],
  6818. default: () => []
  6819. },
  6820. direction: {
  6821. type: String,
  6822. default: 'horizontal',
  6823. validator: v => ['horizontal', 'vertical'].includes(v)
  6824. },
  6825. 'onClick:prepend': EventProp(),
  6826. 'onClick:append': EventProp(),
  6827. ...makeComponentProps(),
  6828. ...makeDensityProps(),
  6829. ...only(makeDimensionProps(), ['maxWidth', 'minWidth', 'width']),
  6830. ...makeThemeProps(),
  6831. ...makeValidationProps()
  6832. }, 'VInput');
  6833. const VInput = genericComponent()({
  6834. name: 'VInput',
  6835. props: {
  6836. ...makeVInputProps()
  6837. },
  6838. emits: {
  6839. 'update:modelValue': value => true
  6840. },
  6841. setup(props, _ref) {
  6842. let {
  6843. attrs,
  6844. slots,
  6845. emit
  6846. } = _ref;
  6847. const {
  6848. densityClasses
  6849. } = useDensity(props);
  6850. const {
  6851. dimensionStyles
  6852. } = useDimension(props);
  6853. const {
  6854. themeClasses
  6855. } = provideTheme(props);
  6856. const {
  6857. rtlClasses
  6858. } = useRtl();
  6859. const {
  6860. InputIcon
  6861. } = useInputIcon(props);
  6862. const uid = getUid();
  6863. const id = computed(() => props.id || `input-${uid}`);
  6864. const messagesId = computed(() => `${id.value}-messages`);
  6865. const {
  6866. errorMessages,
  6867. isDirty,
  6868. isDisabled,
  6869. isReadonly,
  6870. isPristine,
  6871. isValid,
  6872. isValidating,
  6873. reset,
  6874. resetValidation,
  6875. validate,
  6876. validationClasses
  6877. } = useValidation(props, 'v-input', id);
  6878. const slotProps = computed(() => ({
  6879. id,
  6880. messagesId,
  6881. isDirty,
  6882. isDisabled,
  6883. isReadonly,
  6884. isPristine,
  6885. isValid,
  6886. isValidating,
  6887. reset,
  6888. resetValidation,
  6889. validate
  6890. }));
  6891. const messages = computed(() => {
  6892. if (props.errorMessages?.length || !isPristine.value && errorMessages.value.length) {
  6893. return errorMessages.value;
  6894. } else if (props.hint && (props.persistentHint || props.focused)) {
  6895. return props.hint;
  6896. } else {
  6897. return props.messages;
  6898. }
  6899. });
  6900. useRender(() => {
  6901. const hasPrepend = !!(slots.prepend || props.prependIcon);
  6902. const hasAppend = !!(slots.append || props.appendIcon);
  6903. const hasMessages = messages.value.length > 0;
  6904. const hasDetails = !props.hideDetails || props.hideDetails === 'auto' && (hasMessages || !!slots.details);
  6905. return createVNode("div", {
  6906. "class": ['v-input', `v-input--${props.direction}`, {
  6907. 'v-input--center-affix': props.centerAffix,
  6908. 'v-input--hide-spin-buttons': props.hideSpinButtons
  6909. }, densityClasses.value, themeClasses.value, rtlClasses.value, validationClasses.value, props.class],
  6910. "style": [dimensionStyles.value, props.style]
  6911. }, [hasPrepend && createVNode("div", {
  6912. "key": "prepend",
  6913. "class": "v-input__prepend"
  6914. }, [slots.prepend?.(slotProps.value), props.prependIcon && createVNode(InputIcon, {
  6915. "key": "prepend-icon",
  6916. "name": "prepend"
  6917. }, null)]), slots.default && createVNode("div", {
  6918. "class": "v-input__control"
  6919. }, [slots.default?.(slotProps.value)]), hasAppend && createVNode("div", {
  6920. "key": "append",
  6921. "class": "v-input__append"
  6922. }, [props.appendIcon && createVNode(InputIcon, {
  6923. "key": "append-icon",
  6924. "name": "append"
  6925. }, null), slots.append?.(slotProps.value)]), hasDetails && createVNode("div", {
  6926. "class": "v-input__details"
  6927. }, [createVNode(VMessages, {
  6928. "id": messagesId.value,
  6929. "active": hasMessages,
  6930. "messages": messages.value
  6931. }, {
  6932. message: slots.message
  6933. }), slots.details?.(slotProps.value)])]);
  6934. });
  6935. return {
  6936. reset,
  6937. resetValidation,
  6938. validate,
  6939. isValid,
  6940. errorMessages
  6941. };
  6942. }
  6943. });
  6944. // Types
  6945. const makeVCheckboxProps = propsFactory({
  6946. ...makeVInputProps(),
  6947. ...omit(makeVCheckboxBtnProps(), ['inline'])
  6948. }, 'VCheckbox');
  6949. const VCheckbox = genericComponent()({
  6950. name: 'VCheckbox',
  6951. inheritAttrs: false,
  6952. props: makeVCheckboxProps(),
  6953. emits: {
  6954. 'update:modelValue': value => true,
  6955. 'update:focused': focused => true
  6956. },
  6957. setup(props, _ref) {
  6958. let {
  6959. attrs,
  6960. slots
  6961. } = _ref;
  6962. const model = useProxiedModel(props, 'modelValue');
  6963. const {
  6964. isFocused,
  6965. focus,
  6966. blur
  6967. } = useFocus(props);
  6968. const uid = getUid();
  6969. const id = computed(() => props.id || `checkbox-${uid}`);
  6970. useRender(() => {
  6971. const [rootAttrs, controlAttrs] = filterInputAttrs(attrs);
  6972. const inputProps = VInput.filterProps(props);
  6973. const checkboxProps = VCheckboxBtn.filterProps(props);
  6974. return createVNode(VInput, mergeProps({
  6975. "class": ['v-checkbox', props.class]
  6976. }, rootAttrs, inputProps, {
  6977. "modelValue": model.value,
  6978. "onUpdate:modelValue": $event => model.value = $event,
  6979. "id": id.value,
  6980. "focused": isFocused.value,
  6981. "style": props.style
  6982. }), {
  6983. ...slots,
  6984. default: _ref2 => {
  6985. let {
  6986. id,
  6987. messagesId,
  6988. isDisabled,
  6989. isReadonly,
  6990. isValid
  6991. } = _ref2;
  6992. return createVNode(VCheckboxBtn, mergeProps(checkboxProps, {
  6993. "id": id.value,
  6994. "aria-describedby": messagesId.value,
  6995. "disabled": isDisabled.value,
  6996. "readonly": isReadonly.value
  6997. }, controlAttrs, {
  6998. "error": isValid.value === false,
  6999. "modelValue": model.value,
  7000. "onUpdate:modelValue": $event => model.value = $event,
  7001. "onFocus": focus,
  7002. "onBlur": blur
  7003. }), slots);
  7004. }
  7005. });
  7006. });
  7007. return {};
  7008. }
  7009. });
  7010. // Utilities
  7011. // Types
  7012. const breakpoints = ['sm', 'md', 'lg', 'xl', 'xxl']; // no xs
  7013. const DisplaySymbol = Symbol.for('vuetify:display');
  7014. const defaultDisplayOptions = {
  7015. mobileBreakpoint: 'lg',
  7016. thresholds: {
  7017. xs: 0,
  7018. sm: 600,
  7019. md: 960,
  7020. lg: 1280,
  7021. xl: 1920,
  7022. xxl: 2560
  7023. }
  7024. };
  7025. const parseDisplayOptions = function () {
  7026. let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultDisplayOptions;
  7027. return mergeDeep(defaultDisplayOptions, options);
  7028. };
  7029. function getClientWidth(ssr) {
  7030. return IN_BROWSER && !ssr ? window.innerWidth : typeof ssr === 'object' && ssr.clientWidth || 0;
  7031. }
  7032. function getClientHeight(ssr) {
  7033. return IN_BROWSER && !ssr ? window.innerHeight : typeof ssr === 'object' && ssr.clientHeight || 0;
  7034. }
  7035. function getPlatform(ssr) {
  7036. const userAgent = IN_BROWSER && !ssr ? window.navigator.userAgent : 'ssr';
  7037. function match(regexp) {
  7038. return Boolean(userAgent.match(regexp));
  7039. }
  7040. const android = match(/android/i);
  7041. const ios = match(/iphone|ipad|ipod/i);
  7042. const cordova = match(/cordova/i);
  7043. const electron = match(/electron/i);
  7044. const chrome = match(/chrome/i);
  7045. const edge = match(/edge/i);
  7046. const firefox = match(/firefox/i);
  7047. const opera = match(/opera/i);
  7048. const win = match(/win/i);
  7049. const mac = match(/mac/i);
  7050. const linux = match(/linux/i);
  7051. return {
  7052. android,
  7053. ios,
  7054. cordova,
  7055. electron,
  7056. chrome,
  7057. edge,
  7058. firefox,
  7059. opera,
  7060. win,
  7061. mac,
  7062. linux,
  7063. touch: SUPPORTS_TOUCH,
  7064. ssr: userAgent === 'ssr'
  7065. };
  7066. }
  7067. function createDisplay(options, ssr) {
  7068. const {
  7069. thresholds,
  7070. mobileBreakpoint
  7071. } = parseDisplayOptions(options);
  7072. const height = shallowRef(getClientHeight(ssr));
  7073. const platform = shallowRef(getPlatform(ssr));
  7074. const state = reactive({});
  7075. const width = shallowRef(getClientWidth(ssr));
  7076. function updateSize() {
  7077. height.value = getClientHeight();
  7078. width.value = getClientWidth();
  7079. }
  7080. function update() {
  7081. updateSize();
  7082. platform.value = getPlatform();
  7083. }
  7084. // eslint-disable-next-line max-statements
  7085. watchEffect(() => {
  7086. const xs = width.value < thresholds.sm;
  7087. const sm = width.value < thresholds.md && !xs;
  7088. const md = width.value < thresholds.lg && !(sm || xs);
  7089. const lg = width.value < thresholds.xl && !(md || sm || xs);
  7090. const xl = width.value < thresholds.xxl && !(lg || md || sm || xs);
  7091. const xxl = width.value >= thresholds.xxl;
  7092. const name = xs ? 'xs' : sm ? 'sm' : md ? 'md' : lg ? 'lg' : xl ? 'xl' : 'xxl';
  7093. const breakpointValue = typeof mobileBreakpoint === 'number' ? mobileBreakpoint : thresholds[mobileBreakpoint];
  7094. const mobile = width.value < breakpointValue;
  7095. state.xs = xs;
  7096. state.sm = sm;
  7097. state.md = md;
  7098. state.lg = lg;
  7099. state.xl = xl;
  7100. state.xxl = xxl;
  7101. state.smAndUp = !xs;
  7102. state.mdAndUp = !(xs || sm);
  7103. state.lgAndUp = !(xs || sm || md);
  7104. state.xlAndUp = !(xs || sm || md || lg);
  7105. state.smAndDown = !(md || lg || xl || xxl);
  7106. state.mdAndDown = !(lg || xl || xxl);
  7107. state.lgAndDown = !(xl || xxl);
  7108. state.xlAndDown = !xxl;
  7109. state.name = name;
  7110. state.height = height.value;
  7111. state.width = width.value;
  7112. state.mobile = mobile;
  7113. state.mobileBreakpoint = mobileBreakpoint;
  7114. state.platform = platform.value;
  7115. state.thresholds = thresholds;
  7116. });
  7117. if (IN_BROWSER) {
  7118. window.addEventListener('resize', updateSize, {
  7119. passive: true
  7120. });
  7121. }
  7122. return {
  7123. ...toRefs(state),
  7124. update,
  7125. ssr: !!ssr
  7126. };
  7127. }
  7128. const makeDisplayProps = propsFactory({
  7129. mobile: {
  7130. type: Boolean,
  7131. default: false
  7132. },
  7133. mobileBreakpoint: [Number, String]
  7134. }, 'display');
  7135. function useDisplay() {
  7136. let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  7137. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  7138. const display = inject$1(DisplaySymbol);
  7139. if (!display) throw new Error('Could not find Vuetify display injection');
  7140. const mobile = computed(() => {
  7141. if (props.mobile != null) return props.mobile;
  7142. if (!props.mobileBreakpoint) return display.mobile.value;
  7143. const breakpointValue = typeof props.mobileBreakpoint === 'number' ? props.mobileBreakpoint : display.thresholds.value[props.mobileBreakpoint];
  7144. return display.width.value < breakpointValue;
  7145. });
  7146. const displayClasses = computed(() => {
  7147. if (!name) return {};
  7148. return {
  7149. [`${name}--mobile`]: mobile.value
  7150. };
  7151. });
  7152. return {
  7153. ...display,
  7154. displayClasses,
  7155. mobile
  7156. };
  7157. }
  7158. // Utilities
  7159. // Types
  7160. const GoToSymbol = Symbol.for('vuetify:goto');
  7161. function genDefaults() {
  7162. return {
  7163. container: undefined,
  7164. duration: 300,
  7165. layout: false,
  7166. offset: 0,
  7167. easing: 'easeInOutCubic',
  7168. patterns: {
  7169. linear: t => t,
  7170. easeInQuad: t => t ** 2,
  7171. easeOutQuad: t => t * (2 - t),
  7172. easeInOutQuad: t => t < 0.5 ? 2 * t ** 2 : -1 + (4 - 2 * t) * t,
  7173. easeInCubic: t => t ** 3,
  7174. easeOutCubic: t => --t ** 3 + 1,
  7175. easeInOutCubic: t => t < 0.5 ? 4 * t ** 3 : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
  7176. easeInQuart: t => t ** 4,
  7177. easeOutQuart: t => 1 - --t ** 4,
  7178. easeInOutQuart: t => t < 0.5 ? 8 * t ** 4 : 1 - 8 * --t ** 4,
  7179. easeInQuint: t => t ** 5,
  7180. easeOutQuint: t => 1 + --t ** 5,
  7181. easeInOutQuint: t => t < 0.5 ? 16 * t ** 5 : 1 + 16 * --t ** 5
  7182. }
  7183. };
  7184. }
  7185. function getContainer(el) {
  7186. return getTarget$1(el) ?? (document.scrollingElement || document.body);
  7187. }
  7188. function getTarget$1(el) {
  7189. return typeof el === 'string' ? document.querySelector(el) : refElement(el);
  7190. }
  7191. function getOffset$2(target, horizontal, rtl) {
  7192. if (typeof target === 'number') return horizontal && rtl ? -target : target;
  7193. let el = getTarget$1(target);
  7194. let totalOffset = 0;
  7195. while (el) {
  7196. totalOffset += horizontal ? el.offsetLeft : el.offsetTop;
  7197. el = el.offsetParent;
  7198. }
  7199. return totalOffset;
  7200. }
  7201. function createGoTo(options, locale) {
  7202. return {
  7203. rtl: locale.isRtl,
  7204. options: mergeDeep(genDefaults(), options)
  7205. };
  7206. }
  7207. async function scrollTo(_target, _options, horizontal, goTo) {
  7208. const property = horizontal ? 'scrollLeft' : 'scrollTop';
  7209. const options = mergeDeep(goTo?.options ?? genDefaults(), _options);
  7210. const rtl = goTo?.rtl.value;
  7211. const target = (typeof _target === 'number' ? _target : getTarget$1(_target)) ?? 0;
  7212. const container = options.container === 'parent' && target instanceof HTMLElement ? target.parentElement : getContainer(options.container);
  7213. const ease = typeof options.easing === 'function' ? options.easing : options.patterns[options.easing];
  7214. if (!ease) throw new TypeError(`Easing function "${options.easing}" not found.`);
  7215. let targetLocation;
  7216. if (typeof target === 'number') {
  7217. targetLocation = getOffset$2(target, horizontal, rtl);
  7218. } else {
  7219. targetLocation = getOffset$2(target, horizontal, rtl) - getOffset$2(container, horizontal, rtl);
  7220. if (options.layout) {
  7221. const styles = window.getComputedStyle(target);
  7222. const layoutOffset = styles.getPropertyValue('--v-layout-top');
  7223. if (layoutOffset) targetLocation -= parseInt(layoutOffset, 10);
  7224. }
  7225. }
  7226. targetLocation += options.offset;
  7227. targetLocation = clampTarget(container, targetLocation, !!rtl, !!horizontal);
  7228. const startLocation = container[property] ?? 0;
  7229. if (targetLocation === startLocation) return Promise.resolve(targetLocation);
  7230. const startTime = performance.now();
  7231. return new Promise(resolve => requestAnimationFrame(function step(currentTime) {
  7232. const timeElapsed = currentTime - startTime;
  7233. const progress = timeElapsed / options.duration;
  7234. const location = Math.floor(startLocation + (targetLocation - startLocation) * ease(clamp(progress, 0, 1)));
  7235. container[property] = location;
  7236. // Allow for some jitter if target time has elapsed
  7237. if (progress >= 1 && Math.abs(location - container[property]) < 10) {
  7238. return resolve(targetLocation);
  7239. } else if (progress > 2) {
  7240. // The target might not be reachable
  7241. consoleWarn('Scroll target is not reachable');
  7242. return resolve(container[property]);
  7243. }
  7244. requestAnimationFrame(step);
  7245. }));
  7246. }
  7247. function useGoTo() {
  7248. let _options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  7249. const goToInstance = inject$1(GoToSymbol);
  7250. const {
  7251. isRtl
  7252. } = useRtl();
  7253. if (!goToInstance) throw new Error('[Vuetify] Could not find injected goto instance');
  7254. const goTo = {
  7255. ...goToInstance,
  7256. // can be set via VLocaleProvider
  7257. rtl: computed(() => goToInstance.rtl.value || isRtl.value)
  7258. };
  7259. async function go(target, options) {
  7260. return scrollTo(target, mergeDeep(_options, options), false, goTo);
  7261. }
  7262. go.horizontal = async (target, options) => {
  7263. return scrollTo(target, mergeDeep(_options, options), true, goTo);
  7264. };
  7265. return go;
  7266. }
  7267. /**
  7268. * Clamp target value to achieve a smooth scroll animation
  7269. * when the value goes outside the scroll container size
  7270. */
  7271. function clampTarget(container, value, rtl, horizontal) {
  7272. const {
  7273. scrollWidth,
  7274. scrollHeight
  7275. } = container;
  7276. const [containerWidth, containerHeight] = container === document.scrollingElement ? [window.innerWidth, window.innerHeight] : [container.offsetWidth, container.offsetHeight];
  7277. let min;
  7278. let max;
  7279. if (horizontal) {
  7280. if (rtl) {
  7281. min = -(scrollWidth - containerWidth);
  7282. max = 0;
  7283. } else {
  7284. min = 0;
  7285. max = scrollWidth - containerWidth;
  7286. }
  7287. } else {
  7288. min = 0;
  7289. max = scrollHeight + -containerHeight;
  7290. }
  7291. return Math.max(Math.min(value, max), min);
  7292. }
  7293. function calculateUpdatedTarget(_ref) {
  7294. let {
  7295. selectedElement,
  7296. containerElement,
  7297. isRtl,
  7298. isHorizontal
  7299. } = _ref;
  7300. const containerSize = getOffsetSize(isHorizontal, containerElement);
  7301. const scrollPosition = getScrollPosition(isHorizontal, isRtl, containerElement);
  7302. const childrenSize = getOffsetSize(isHorizontal, selectedElement);
  7303. const childrenStartPosition = getOffsetPosition(isHorizontal, selectedElement);
  7304. const additionalOffset = childrenSize * 0.4;
  7305. if (scrollPosition > childrenStartPosition) {
  7306. return childrenStartPosition - additionalOffset;
  7307. } else if (scrollPosition + containerSize < childrenStartPosition + childrenSize) {
  7308. return childrenStartPosition - containerSize + childrenSize + additionalOffset;
  7309. }
  7310. return scrollPosition;
  7311. }
  7312. function calculateCenteredTarget(_ref2) {
  7313. let {
  7314. selectedElement,
  7315. containerElement,
  7316. isHorizontal
  7317. } = _ref2;
  7318. const containerOffsetSize = getOffsetSize(isHorizontal, containerElement);
  7319. const childrenOffsetPosition = getOffsetPosition(isHorizontal, selectedElement);
  7320. const childrenOffsetSize = getOffsetSize(isHorizontal, selectedElement);
  7321. return childrenOffsetPosition - containerOffsetSize / 2 + childrenOffsetSize / 2;
  7322. }
  7323. function getScrollSize(isHorizontal, element) {
  7324. const key = isHorizontal ? 'scrollWidth' : 'scrollHeight';
  7325. return element?.[key] || 0;
  7326. }
  7327. function getClientSize(isHorizontal, element) {
  7328. const key = isHorizontal ? 'clientWidth' : 'clientHeight';
  7329. return element?.[key] || 0;
  7330. }
  7331. function getScrollPosition(isHorizontal, rtl, element) {
  7332. if (!element) {
  7333. return 0;
  7334. }
  7335. const {
  7336. scrollLeft,
  7337. offsetWidth,
  7338. scrollWidth
  7339. } = element;
  7340. if (isHorizontal) {
  7341. return rtl ? scrollWidth - offsetWidth + scrollLeft : scrollLeft;
  7342. }
  7343. return element.scrollTop;
  7344. }
  7345. function getOffsetSize(isHorizontal, element) {
  7346. const key = isHorizontal ? 'offsetWidth' : 'offsetHeight';
  7347. return element?.[key] || 0;
  7348. }
  7349. function getOffsetPosition(isHorizontal, element) {
  7350. const key = isHorizontal ? 'offsetLeft' : 'offsetTop';
  7351. return element?.[key] || 0;
  7352. }
  7353. // Types
  7354. const VSlideGroupSymbol = Symbol.for('vuetify:v-slide-group');
  7355. const makeVSlideGroupProps = propsFactory({
  7356. centerActive: Boolean,
  7357. direction: {
  7358. type: String,
  7359. default: 'horizontal'
  7360. },
  7361. symbol: {
  7362. type: null,
  7363. default: VSlideGroupSymbol
  7364. },
  7365. nextIcon: {
  7366. type: IconValue,
  7367. default: '$next'
  7368. },
  7369. prevIcon: {
  7370. type: IconValue,
  7371. default: '$prev'
  7372. },
  7373. showArrows: {
  7374. type: [Boolean, String],
  7375. validator: v => typeof v === 'boolean' || ['always', 'desktop', 'mobile'].includes(v)
  7376. },
  7377. ...makeComponentProps(),
  7378. ...makeDisplayProps({
  7379. mobile: null
  7380. }),
  7381. ...makeTagProps(),
  7382. ...makeGroupProps({
  7383. selectedClass: 'v-slide-group-item--active'
  7384. })
  7385. }, 'VSlideGroup');
  7386. const VSlideGroup = genericComponent()({
  7387. name: 'VSlideGroup',
  7388. props: makeVSlideGroupProps(),
  7389. emits: {
  7390. 'update:modelValue': value => true
  7391. },
  7392. setup(props, _ref) {
  7393. let {
  7394. slots
  7395. } = _ref;
  7396. const {
  7397. isRtl
  7398. } = useRtl();
  7399. const {
  7400. displayClasses,
  7401. mobile
  7402. } = useDisplay(props);
  7403. const group = useGroup(props, props.symbol);
  7404. const isOverflowing = shallowRef(false);
  7405. const scrollOffset = shallowRef(0);
  7406. const containerSize = shallowRef(0);
  7407. const contentSize = shallowRef(0);
  7408. const isHorizontal = computed(() => props.direction === 'horizontal');
  7409. const {
  7410. resizeRef: containerRef,
  7411. contentRect: containerRect
  7412. } = useResizeObserver();
  7413. const {
  7414. resizeRef: contentRef,
  7415. contentRect
  7416. } = useResizeObserver();
  7417. const goTo = useGoTo();
  7418. const goToOptions = computed(() => {
  7419. return {
  7420. container: containerRef.el,
  7421. duration: 200,
  7422. easing: 'easeOutQuart'
  7423. };
  7424. });
  7425. const firstSelectedIndex = computed(() => {
  7426. if (!group.selected.value.length) return -1;
  7427. return group.items.value.findIndex(item => item.id === group.selected.value[0]);
  7428. });
  7429. const lastSelectedIndex = computed(() => {
  7430. if (!group.selected.value.length) return -1;
  7431. return group.items.value.findIndex(item => item.id === group.selected.value[group.selected.value.length - 1]);
  7432. });
  7433. if (IN_BROWSER) {
  7434. let frame = -1;
  7435. watch(() => [group.selected.value, containerRect.value, contentRect.value, isHorizontal.value], () => {
  7436. cancelAnimationFrame(frame);
  7437. frame = requestAnimationFrame(() => {
  7438. if (containerRect.value && contentRect.value) {
  7439. const sizeProperty = isHorizontal.value ? 'width' : 'height';
  7440. containerSize.value = containerRect.value[sizeProperty];
  7441. contentSize.value = contentRect.value[sizeProperty];
  7442. isOverflowing.value = containerSize.value + 1 < contentSize.value;
  7443. }
  7444. if (firstSelectedIndex.value >= 0 && contentRef.el) {
  7445. // TODO: Is this too naive? Should we store element references in group composable?
  7446. const selectedElement = contentRef.el.children[lastSelectedIndex.value];
  7447. scrollToChildren(selectedElement, props.centerActive);
  7448. }
  7449. });
  7450. });
  7451. }
  7452. const isFocused = shallowRef(false);
  7453. function scrollToChildren(children, center) {
  7454. let target = 0;
  7455. if (center) {
  7456. target = calculateCenteredTarget({
  7457. containerElement: containerRef.el,
  7458. isHorizontal: isHorizontal.value,
  7459. selectedElement: children
  7460. });
  7461. } else {
  7462. target = calculateUpdatedTarget({
  7463. containerElement: containerRef.el,
  7464. isHorizontal: isHorizontal.value,
  7465. isRtl: isRtl.value,
  7466. selectedElement: children
  7467. });
  7468. }
  7469. scrollToPosition(target);
  7470. }
  7471. function scrollToPosition(newPosition) {
  7472. if (!IN_BROWSER || !containerRef.el) return;
  7473. const offsetSize = getOffsetSize(isHorizontal.value, containerRef.el);
  7474. const scrollPosition = getScrollPosition(isHorizontal.value, isRtl.value, containerRef.el);
  7475. const scrollSize = getScrollSize(isHorizontal.value, containerRef.el);
  7476. if (scrollSize <= offsetSize ||
  7477. // Prevent scrolling by only a couple of pixels, which doesn't look smooth
  7478. Math.abs(newPosition - scrollPosition) < 16) return;
  7479. if (isHorizontal.value && isRtl.value && containerRef.el) {
  7480. const {
  7481. scrollWidth,
  7482. offsetWidth: containerWidth
  7483. } = containerRef.el;
  7484. newPosition = scrollWidth - containerWidth - newPosition;
  7485. }
  7486. if (isHorizontal.value) {
  7487. goTo.horizontal(newPosition, goToOptions.value);
  7488. } else {
  7489. goTo(newPosition, goToOptions.value);
  7490. }
  7491. }
  7492. function onScroll(e) {
  7493. const {
  7494. scrollTop,
  7495. scrollLeft
  7496. } = e.target;
  7497. scrollOffset.value = isHorizontal.value ? scrollLeft : scrollTop;
  7498. }
  7499. function onFocusin(e) {
  7500. isFocused.value = true;
  7501. if (!isOverflowing.value || !contentRef.el) return;
  7502. // Focused element is likely to be the root of an item, so a
  7503. // breadth-first search will probably find it in the first iteration
  7504. for (const el of e.composedPath()) {
  7505. for (const item of contentRef.el.children) {
  7506. if (item === el) {
  7507. scrollToChildren(item);
  7508. return;
  7509. }
  7510. }
  7511. }
  7512. }
  7513. function onFocusout(e) {
  7514. isFocused.value = false;
  7515. }
  7516. // Affix clicks produce onFocus that we have to ignore to avoid extra scrollToChildren
  7517. let ignoreFocusEvent = false;
  7518. function onFocus(e) {
  7519. if (!ignoreFocusEvent && !isFocused.value && !(e.relatedTarget && contentRef.el?.contains(e.relatedTarget))) focus();
  7520. ignoreFocusEvent = false;
  7521. }
  7522. function onFocusAffixes() {
  7523. ignoreFocusEvent = true;
  7524. }
  7525. function onKeydown(e) {
  7526. if (!contentRef.el) return;
  7527. function toFocus(location) {
  7528. e.preventDefault();
  7529. focus(location);
  7530. }
  7531. if (isHorizontal.value) {
  7532. if (e.key === 'ArrowRight') {
  7533. toFocus(isRtl.value ? 'prev' : 'next');
  7534. } else if (e.key === 'ArrowLeft') {
  7535. toFocus(isRtl.value ? 'next' : 'prev');
  7536. }
  7537. } else {
  7538. if (e.key === 'ArrowDown') {
  7539. toFocus('next');
  7540. } else if (e.key === 'ArrowUp') {
  7541. toFocus('prev');
  7542. }
  7543. }
  7544. if (e.key === 'Home') {
  7545. toFocus('first');
  7546. } else if (e.key === 'End') {
  7547. toFocus('last');
  7548. }
  7549. }
  7550. function focus(location) {
  7551. if (!contentRef.el) return;
  7552. let el;
  7553. if (!location) {
  7554. const focusable = focusableChildren(contentRef.el);
  7555. el = focusable[0];
  7556. } else if (location === 'next') {
  7557. el = contentRef.el.querySelector(':focus')?.nextElementSibling;
  7558. if (!el) return focus('first');
  7559. } else if (location === 'prev') {
  7560. el = contentRef.el.querySelector(':focus')?.previousElementSibling;
  7561. if (!el) return focus('last');
  7562. } else if (location === 'first') {
  7563. el = contentRef.el.firstElementChild;
  7564. } else if (location === 'last') {
  7565. el = contentRef.el.lastElementChild;
  7566. }
  7567. if (el) {
  7568. el.focus({
  7569. preventScroll: true
  7570. });
  7571. }
  7572. }
  7573. function scrollTo(location) {
  7574. const direction = isHorizontal.value && isRtl.value ? -1 : 1;
  7575. const offsetStep = (location === 'prev' ? -direction : direction) * containerSize.value;
  7576. let newPosition = scrollOffset.value + offsetStep;
  7577. // TODO: improve it
  7578. if (isHorizontal.value && isRtl.value && containerRef.el) {
  7579. const {
  7580. scrollWidth,
  7581. offsetWidth: containerWidth
  7582. } = containerRef.el;
  7583. newPosition += scrollWidth - containerWidth;
  7584. }
  7585. scrollToPosition(newPosition);
  7586. }
  7587. const slotProps = computed(() => ({
  7588. next: group.next,
  7589. prev: group.prev,
  7590. select: group.select,
  7591. isSelected: group.isSelected
  7592. }));
  7593. const hasAffixes = computed(() => {
  7594. switch (props.showArrows) {
  7595. // Always show arrows on desktop & mobile
  7596. case 'always':
  7597. return true;
  7598. // Always show arrows on desktop
  7599. case 'desktop':
  7600. return !mobile.value;
  7601. // Show arrows on mobile when overflowing.
  7602. // This matches the default 2.2 behavior
  7603. case true:
  7604. return isOverflowing.value || Math.abs(scrollOffset.value) > 0;
  7605. // Always show on mobile
  7606. case 'mobile':
  7607. return mobile.value || isOverflowing.value || Math.abs(scrollOffset.value) > 0;
  7608. // https://material.io/components/tabs#scrollable-tabs
  7609. // Always show arrows when
  7610. // overflowed on desktop
  7611. default:
  7612. return !mobile.value && (isOverflowing.value || Math.abs(scrollOffset.value) > 0);
  7613. }
  7614. });
  7615. const hasPrev = computed(() => {
  7616. // 1 pixel in reserve, may be lost after rounding
  7617. return Math.abs(scrollOffset.value) > 1;
  7618. });
  7619. const hasNext = computed(() => {
  7620. if (!containerRef.value) return false;
  7621. const scrollSize = getScrollSize(isHorizontal.value, containerRef.el);
  7622. const clientSize = getClientSize(isHorizontal.value, containerRef.el);
  7623. const scrollSizeMax = scrollSize - clientSize;
  7624. // 1 pixel in reserve, may be lost after rounding
  7625. return scrollSizeMax - Math.abs(scrollOffset.value) > 1;
  7626. });
  7627. useRender(() => createVNode(props.tag, {
  7628. "class": ['v-slide-group', {
  7629. 'v-slide-group--vertical': !isHorizontal.value,
  7630. 'v-slide-group--has-affixes': hasAffixes.value,
  7631. 'v-slide-group--is-overflowing': isOverflowing.value
  7632. }, displayClasses.value, props.class],
  7633. "style": props.style,
  7634. "tabindex": isFocused.value || group.selected.value.length ? -1 : 0,
  7635. "onFocus": onFocus
  7636. }, {
  7637. default: () => [hasAffixes.value && createVNode("div", {
  7638. "key": "prev",
  7639. "class": ['v-slide-group__prev', {
  7640. 'v-slide-group__prev--disabled': !hasPrev.value
  7641. }],
  7642. "onMousedown": onFocusAffixes,
  7643. "onClick": () => hasPrev.value && scrollTo('prev')
  7644. }, [slots.prev?.(slotProps.value) ?? createVNode(VFadeTransition, null, {
  7645. default: () => [createVNode(VIcon, {
  7646. "icon": isRtl.value ? props.nextIcon : props.prevIcon
  7647. }, null)]
  7648. })]), createVNode("div", {
  7649. "key": "container",
  7650. "ref": containerRef,
  7651. "class": "v-slide-group__container",
  7652. "onScroll": onScroll
  7653. }, [createVNode("div", {
  7654. "ref": contentRef,
  7655. "class": "v-slide-group__content",
  7656. "onFocusin": onFocusin,
  7657. "onFocusout": onFocusout,
  7658. "onKeydown": onKeydown
  7659. }, [slots.default?.(slotProps.value)])]), hasAffixes.value && createVNode("div", {
  7660. "key": "next",
  7661. "class": ['v-slide-group__next', {
  7662. 'v-slide-group__next--disabled': !hasNext.value
  7663. }],
  7664. "onMousedown": onFocusAffixes,
  7665. "onClick": () => hasNext.value && scrollTo('next')
  7666. }, [slots.next?.(slotProps.value) ?? createVNode(VFadeTransition, null, {
  7667. default: () => [createVNode(VIcon, {
  7668. "icon": isRtl.value ? props.prevIcon : props.nextIcon
  7669. }, null)]
  7670. })])]
  7671. }));
  7672. return {
  7673. selected: group.selected,
  7674. scrollTo,
  7675. scrollOffset,
  7676. focus,
  7677. hasPrev,
  7678. hasNext
  7679. };
  7680. }
  7681. });
  7682. // Types
  7683. const VChipGroupSymbol = Symbol.for('vuetify:v-chip-group');
  7684. const makeVChipGroupProps = propsFactory({
  7685. column: Boolean,
  7686. filter: Boolean,
  7687. valueComparator: {
  7688. type: Function,
  7689. default: deepEqual
  7690. },
  7691. ...makeVSlideGroupProps(),
  7692. ...makeComponentProps(),
  7693. ...makeGroupProps({
  7694. selectedClass: 'v-chip--selected'
  7695. }),
  7696. ...makeTagProps(),
  7697. ...makeThemeProps(),
  7698. ...makeVariantProps({
  7699. variant: 'tonal'
  7700. })
  7701. }, 'VChipGroup');
  7702. const VChipGroup = genericComponent()({
  7703. name: 'VChipGroup',
  7704. props: makeVChipGroupProps(),
  7705. emits: {
  7706. 'update:modelValue': value => true
  7707. },
  7708. setup(props, _ref) {
  7709. let {
  7710. slots
  7711. } = _ref;
  7712. const {
  7713. themeClasses
  7714. } = provideTheme(props);
  7715. const {
  7716. isSelected,
  7717. select,
  7718. next,
  7719. prev,
  7720. selected
  7721. } = useGroup(props, VChipGroupSymbol);
  7722. provideDefaults({
  7723. VChip: {
  7724. color: toRef(props, 'color'),
  7725. disabled: toRef(props, 'disabled'),
  7726. filter: toRef(props, 'filter'),
  7727. variant: toRef(props, 'variant')
  7728. }
  7729. });
  7730. useRender(() => {
  7731. const slideGroupProps = VSlideGroup.filterProps(props);
  7732. return createVNode(VSlideGroup, mergeProps(slideGroupProps, {
  7733. "class": ['v-chip-group', {
  7734. 'v-chip-group--column': props.column
  7735. }, themeClasses.value, props.class],
  7736. "style": props.style
  7737. }), {
  7738. default: () => [slots.default?.({
  7739. isSelected,
  7740. select,
  7741. next,
  7742. prev,
  7743. selected: selected.value
  7744. })]
  7745. });
  7746. });
  7747. return {};
  7748. }
  7749. });
  7750. // Types
  7751. const makeVChipProps = propsFactory({
  7752. activeClass: String,
  7753. appendAvatar: String,
  7754. appendIcon: IconValue,
  7755. closable: Boolean,
  7756. closeIcon: {
  7757. type: IconValue,
  7758. default: '$delete'
  7759. },
  7760. closeLabel: {
  7761. type: String,
  7762. default: '$vuetify.close'
  7763. },
  7764. draggable: Boolean,
  7765. filter: Boolean,
  7766. filterIcon: {
  7767. type: IconValue,
  7768. default: '$complete'
  7769. },
  7770. label: Boolean,
  7771. link: {
  7772. type: Boolean,
  7773. default: undefined
  7774. },
  7775. pill: Boolean,
  7776. prependAvatar: String,
  7777. prependIcon: IconValue,
  7778. ripple: {
  7779. type: [Boolean, Object],
  7780. default: true
  7781. },
  7782. text: String,
  7783. modelValue: {
  7784. type: Boolean,
  7785. default: true
  7786. },
  7787. onClick: EventProp(),
  7788. onClickOnce: EventProp(),
  7789. ...makeBorderProps(),
  7790. ...makeComponentProps(),
  7791. ...makeDensityProps(),
  7792. ...makeElevationProps(),
  7793. ...makeGroupItemProps(),
  7794. ...makeRoundedProps(),
  7795. ...makeRouterProps(),
  7796. ...makeSizeProps(),
  7797. ...makeTagProps({
  7798. tag: 'span'
  7799. }),
  7800. ...makeThemeProps(),
  7801. ...makeVariantProps({
  7802. variant: 'tonal'
  7803. })
  7804. }, 'VChip');
  7805. const VChip = genericComponent()({
  7806. name: 'VChip',
  7807. directives: {
  7808. Ripple
  7809. },
  7810. props: makeVChipProps(),
  7811. emits: {
  7812. 'click:close': e => true,
  7813. 'update:modelValue': value => true,
  7814. 'group:selected': val => true,
  7815. click: e => true
  7816. },
  7817. setup(props, _ref) {
  7818. let {
  7819. attrs,
  7820. emit,
  7821. slots
  7822. } = _ref;
  7823. const {
  7824. t
  7825. } = useLocale();
  7826. const {
  7827. borderClasses
  7828. } = useBorder(props);
  7829. const {
  7830. colorClasses,
  7831. colorStyles,
  7832. variantClasses
  7833. } = useVariant(props);
  7834. const {
  7835. densityClasses
  7836. } = useDensity(props);
  7837. const {
  7838. elevationClasses
  7839. } = useElevation(props);
  7840. const {
  7841. roundedClasses
  7842. } = useRounded(props);
  7843. const {
  7844. sizeClasses
  7845. } = useSize(props);
  7846. const {
  7847. themeClasses
  7848. } = provideTheme(props);
  7849. const isActive = useProxiedModel(props, 'modelValue');
  7850. const group = useGroupItem(props, VChipGroupSymbol, false);
  7851. const link = useLink(props, attrs);
  7852. const isLink = computed(() => props.link !== false && link.isLink.value);
  7853. const isClickable = computed(() => !props.disabled && props.link !== false && (!!group || props.link || link.isClickable.value));
  7854. const closeProps = computed(() => ({
  7855. 'aria-label': t(props.closeLabel),
  7856. onClick(e) {
  7857. e.preventDefault();
  7858. e.stopPropagation();
  7859. isActive.value = false;
  7860. emit('click:close', e);
  7861. }
  7862. }));
  7863. function onClick(e) {
  7864. emit('click', e);
  7865. if (!isClickable.value) return;
  7866. link.navigate?.(e);
  7867. group?.toggle();
  7868. }
  7869. function onKeyDown(e) {
  7870. if (e.key === 'Enter' || e.key === ' ') {
  7871. e.preventDefault();
  7872. onClick(e);
  7873. }
  7874. }
  7875. return () => {
  7876. const Tag = link.isLink.value ? 'a' : props.tag;
  7877. const hasAppendMedia = !!(props.appendIcon || props.appendAvatar);
  7878. const hasAppend = !!(hasAppendMedia || slots.append);
  7879. const hasClose = !!(slots.close || props.closable);
  7880. const hasFilter = !!(slots.filter || props.filter) && group;
  7881. const hasPrependMedia = !!(props.prependIcon || props.prependAvatar);
  7882. const hasPrepend = !!(hasPrependMedia || slots.prepend);
  7883. const hasColor = !group || group.isSelected.value;
  7884. return isActive.value && withDirectives(createVNode(Tag, mergeProps({
  7885. "class": ['v-chip', {
  7886. 'v-chip--disabled': props.disabled,
  7887. 'v-chip--label': props.label,
  7888. 'v-chip--link': isClickable.value,
  7889. 'v-chip--filter': hasFilter,
  7890. 'v-chip--pill': props.pill,
  7891. [`${props.activeClass}`]: props.activeClass && link.isActive?.value
  7892. }, themeClasses.value, borderClasses.value, hasColor ? colorClasses.value : undefined, densityClasses.value, elevationClasses.value, roundedClasses.value, sizeClasses.value, variantClasses.value, group?.selectedClass.value, props.class],
  7893. "style": [hasColor ? colorStyles.value : undefined, props.style],
  7894. "disabled": props.disabled || undefined,
  7895. "draggable": props.draggable,
  7896. "tabindex": isClickable.value ? 0 : undefined,
  7897. "onClick": onClick,
  7898. "onKeydown": isClickable.value && !isLink.value && onKeyDown
  7899. }, link.linkProps), {
  7900. default: () => [genOverlays(isClickable.value, 'v-chip'), hasFilter && createVNode(VExpandXTransition, {
  7901. "key": "filter"
  7902. }, {
  7903. default: () => [withDirectives(createVNode("div", {
  7904. "class": "v-chip__filter"
  7905. }, [!slots.filter ? createVNode(VIcon, {
  7906. "key": "filter-icon",
  7907. "icon": props.filterIcon
  7908. }, null) : createVNode(VDefaultsProvider, {
  7909. "key": "filter-defaults",
  7910. "disabled": !props.filterIcon,
  7911. "defaults": {
  7912. VIcon: {
  7913. icon: props.filterIcon
  7914. }
  7915. }
  7916. }, slots.filter)]), [[vShow, group.isSelected.value]])]
  7917. }), hasPrepend && createVNode("div", {
  7918. "key": "prepend",
  7919. "class": "v-chip__prepend"
  7920. }, [!slots.prepend ? createVNode(Fragment, null, [props.prependIcon && createVNode(VIcon, {
  7921. "key": "prepend-icon",
  7922. "icon": props.prependIcon,
  7923. "start": true
  7924. }, null), props.prependAvatar && createVNode(VAvatar, {
  7925. "key": "prepend-avatar",
  7926. "image": props.prependAvatar,
  7927. "start": true
  7928. }, null)]) : createVNode(VDefaultsProvider, {
  7929. "key": "prepend-defaults",
  7930. "disabled": !hasPrependMedia,
  7931. "defaults": {
  7932. VAvatar: {
  7933. image: props.prependAvatar,
  7934. start: true
  7935. },
  7936. VIcon: {
  7937. icon: props.prependIcon,
  7938. start: true
  7939. }
  7940. }
  7941. }, slots.prepend)]), createVNode("div", {
  7942. "class": "v-chip__content",
  7943. "data-no-activator": ""
  7944. }, [slots.default?.({
  7945. isSelected: group?.isSelected.value,
  7946. selectedClass: group?.selectedClass.value,
  7947. select: group?.select,
  7948. toggle: group?.toggle,
  7949. value: group?.value.value,
  7950. disabled: props.disabled
  7951. }) ?? props.text]), hasAppend && createVNode("div", {
  7952. "key": "append",
  7953. "class": "v-chip__append"
  7954. }, [!slots.append ? createVNode(Fragment, null, [props.appendIcon && createVNode(VIcon, {
  7955. "key": "append-icon",
  7956. "end": true,
  7957. "icon": props.appendIcon
  7958. }, null), props.appendAvatar && createVNode(VAvatar, {
  7959. "key": "append-avatar",
  7960. "end": true,
  7961. "image": props.appendAvatar
  7962. }, null)]) : createVNode(VDefaultsProvider, {
  7963. "key": "append-defaults",
  7964. "disabled": !hasAppendMedia,
  7965. "defaults": {
  7966. VAvatar: {
  7967. end: true,
  7968. image: props.appendAvatar
  7969. },
  7970. VIcon: {
  7971. end: true,
  7972. icon: props.appendIcon
  7973. }
  7974. }
  7975. }, slots.append)]), hasClose && createVNode("button", mergeProps({
  7976. "key": "close",
  7977. "class": "v-chip__close",
  7978. "type": "button",
  7979. "data-testid": "close-chip"
  7980. }, closeProps.value), [!slots.close ? createVNode(VIcon, {
  7981. "key": "close-icon",
  7982. "icon": props.closeIcon,
  7983. "size": "x-small"
  7984. }, null) : createVNode(VDefaultsProvider, {
  7985. "key": "close-defaults",
  7986. "defaults": {
  7987. VIcon: {
  7988. icon: props.closeIcon,
  7989. size: 'x-small'
  7990. }
  7991. }
  7992. }, slots.close)])]
  7993. }), [[resolveDirective("ripple"), isClickable.value && props.ripple, null]]);
  7994. };
  7995. }
  7996. });
  7997. // Utilities
  7998. // List
  7999. const ListKey = Symbol.for('vuetify:list');
  8000. function createList() {
  8001. const parent = inject$1(ListKey, {
  8002. hasPrepend: shallowRef(false),
  8003. updateHasPrepend: () => null
  8004. });
  8005. const data = {
  8006. hasPrepend: shallowRef(false),
  8007. updateHasPrepend: value => {
  8008. if (value) data.hasPrepend.value = value;
  8009. }
  8010. };
  8011. provide(ListKey, data);
  8012. return parent;
  8013. }
  8014. function useList() {
  8015. return inject$1(ListKey, null);
  8016. }
  8017. /* eslint-disable sonarjs/no-identical-functions */
  8018. // Utilities
  8019. const independentActiveStrategy = mandatory => {
  8020. const strategy = {
  8021. activate: _ref => {
  8022. let {
  8023. id,
  8024. value,
  8025. activated
  8026. } = _ref;
  8027. id = toRaw(id);
  8028. // When mandatory and we're trying to deselect when id
  8029. // is the only currently selected item then do nothing
  8030. if (mandatory && !value && activated.size === 1 && activated.has(id)) return activated;
  8031. if (value) {
  8032. activated.add(id);
  8033. } else {
  8034. activated.delete(id);
  8035. }
  8036. return activated;
  8037. },
  8038. in: (v, children, parents) => {
  8039. let set = new Set();
  8040. if (v != null) {
  8041. for (const id of wrapInArray(v)) {
  8042. set = strategy.activate({
  8043. id,
  8044. value: true,
  8045. activated: new Set(set),
  8046. children,
  8047. parents
  8048. });
  8049. }
  8050. }
  8051. return set;
  8052. },
  8053. out: v => {
  8054. return Array.from(v);
  8055. }
  8056. };
  8057. return strategy;
  8058. };
  8059. const independentSingleActiveStrategy = mandatory => {
  8060. const parentStrategy = independentActiveStrategy(mandatory);
  8061. const strategy = {
  8062. activate: _ref2 => {
  8063. let {
  8064. activated,
  8065. id,
  8066. ...rest
  8067. } = _ref2;
  8068. id = toRaw(id);
  8069. const singleSelected = activated.has(id) ? new Set([id]) : new Set();
  8070. return parentStrategy.activate({
  8071. ...rest,
  8072. id,
  8073. activated: singleSelected
  8074. });
  8075. },
  8076. in: (v, children, parents) => {
  8077. let set = new Set();
  8078. if (v != null) {
  8079. const arr = wrapInArray(v);
  8080. if (arr.length) {
  8081. set = parentStrategy.in(arr.slice(0, 1), children, parents);
  8082. }
  8083. }
  8084. return set;
  8085. },
  8086. out: (v, children, parents) => {
  8087. return parentStrategy.out(v, children, parents);
  8088. }
  8089. };
  8090. return strategy;
  8091. };
  8092. const leafActiveStrategy = mandatory => {
  8093. const parentStrategy = independentActiveStrategy(mandatory);
  8094. const strategy = {
  8095. activate: _ref3 => {
  8096. let {
  8097. id,
  8098. activated,
  8099. children,
  8100. ...rest
  8101. } = _ref3;
  8102. id = toRaw(id);
  8103. if (children.has(id)) return activated;
  8104. return parentStrategy.activate({
  8105. id,
  8106. activated,
  8107. children,
  8108. ...rest
  8109. });
  8110. },
  8111. in: parentStrategy.in,
  8112. out: parentStrategy.out
  8113. };
  8114. return strategy;
  8115. };
  8116. const leafSingleActiveStrategy = mandatory => {
  8117. const parentStrategy = independentSingleActiveStrategy(mandatory);
  8118. const strategy = {
  8119. activate: _ref4 => {
  8120. let {
  8121. id,
  8122. activated,
  8123. children,
  8124. ...rest
  8125. } = _ref4;
  8126. id = toRaw(id);
  8127. if (children.has(id)) return activated;
  8128. return parentStrategy.activate({
  8129. id,
  8130. activated,
  8131. children,
  8132. ...rest
  8133. });
  8134. },
  8135. in: parentStrategy.in,
  8136. out: parentStrategy.out
  8137. };
  8138. return strategy;
  8139. };
  8140. const singleOpenStrategy = {
  8141. open: _ref => {
  8142. let {
  8143. id,
  8144. value,
  8145. opened,
  8146. parents
  8147. } = _ref;
  8148. if (value) {
  8149. const newOpened = new Set();
  8150. newOpened.add(id);
  8151. let parent = parents.get(id);
  8152. while (parent != null) {
  8153. newOpened.add(parent);
  8154. parent = parents.get(parent);
  8155. }
  8156. return newOpened;
  8157. } else {
  8158. opened.delete(id);
  8159. return opened;
  8160. }
  8161. },
  8162. select: () => null
  8163. };
  8164. const multipleOpenStrategy = {
  8165. open: _ref2 => {
  8166. let {
  8167. id,
  8168. value,
  8169. opened,
  8170. parents
  8171. } = _ref2;
  8172. if (value) {
  8173. let parent = parents.get(id);
  8174. opened.add(id);
  8175. while (parent != null && parent !== id) {
  8176. opened.add(parent);
  8177. parent = parents.get(parent);
  8178. }
  8179. return opened;
  8180. } else {
  8181. opened.delete(id);
  8182. }
  8183. return opened;
  8184. },
  8185. select: () => null
  8186. };
  8187. const listOpenStrategy = {
  8188. open: multipleOpenStrategy.open,
  8189. select: _ref3 => {
  8190. let {
  8191. id,
  8192. value,
  8193. opened,
  8194. parents
  8195. } = _ref3;
  8196. if (!value) return opened;
  8197. const path = [];
  8198. let parent = parents.get(id);
  8199. while (parent != null) {
  8200. path.push(parent);
  8201. parent = parents.get(parent);
  8202. }
  8203. return new Set(path);
  8204. }
  8205. };
  8206. /* eslint-disable sonarjs/no-identical-functions */
  8207. // Utilities
  8208. const independentSelectStrategy = mandatory => {
  8209. const strategy = {
  8210. select: _ref => {
  8211. let {
  8212. id,
  8213. value,
  8214. selected
  8215. } = _ref;
  8216. id = toRaw(id);
  8217. // When mandatory and we're trying to deselect when id
  8218. // is the only currently selected item then do nothing
  8219. if (mandatory && !value) {
  8220. const on = Array.from(selected.entries()).reduce((arr, _ref2) => {
  8221. let [key, value] = _ref2;
  8222. if (value === 'on') arr.push(key);
  8223. return arr;
  8224. }, []);
  8225. if (on.length === 1 && on[0] === id) return selected;
  8226. }
  8227. selected.set(id, value ? 'on' : 'off');
  8228. return selected;
  8229. },
  8230. in: (v, children, parents) => {
  8231. let map = new Map();
  8232. for (const id of v || []) {
  8233. map = strategy.select({
  8234. id,
  8235. value: true,
  8236. selected: new Map(map),
  8237. children,
  8238. parents
  8239. });
  8240. }
  8241. return map;
  8242. },
  8243. out: v => {
  8244. const arr = [];
  8245. for (const [key, value] of v.entries()) {
  8246. if (value === 'on') arr.push(key);
  8247. }
  8248. return arr;
  8249. }
  8250. };
  8251. return strategy;
  8252. };
  8253. const independentSingleSelectStrategy = mandatory => {
  8254. const parentStrategy = independentSelectStrategy(mandatory);
  8255. const strategy = {
  8256. select: _ref3 => {
  8257. let {
  8258. selected,
  8259. id,
  8260. ...rest
  8261. } = _ref3;
  8262. id = toRaw(id);
  8263. const singleSelected = selected.has(id) ? new Map([[id, selected.get(id)]]) : new Map();
  8264. return parentStrategy.select({
  8265. ...rest,
  8266. id,
  8267. selected: singleSelected
  8268. });
  8269. },
  8270. in: (v, children, parents) => {
  8271. let map = new Map();
  8272. if (v?.length) {
  8273. map = parentStrategy.in(v.slice(0, 1), children, parents);
  8274. }
  8275. return map;
  8276. },
  8277. out: (v, children, parents) => {
  8278. return parentStrategy.out(v, children, parents);
  8279. }
  8280. };
  8281. return strategy;
  8282. };
  8283. const leafSelectStrategy = mandatory => {
  8284. const parentStrategy = independentSelectStrategy(mandatory);
  8285. const strategy = {
  8286. select: _ref4 => {
  8287. let {
  8288. id,
  8289. selected,
  8290. children,
  8291. ...rest
  8292. } = _ref4;
  8293. id = toRaw(id);
  8294. if (children.has(id)) return selected;
  8295. return parentStrategy.select({
  8296. id,
  8297. selected,
  8298. children,
  8299. ...rest
  8300. });
  8301. },
  8302. in: parentStrategy.in,
  8303. out: parentStrategy.out
  8304. };
  8305. return strategy;
  8306. };
  8307. const leafSingleSelectStrategy = mandatory => {
  8308. const parentStrategy = independentSingleSelectStrategy(mandatory);
  8309. const strategy = {
  8310. select: _ref5 => {
  8311. let {
  8312. id,
  8313. selected,
  8314. children,
  8315. ...rest
  8316. } = _ref5;
  8317. id = toRaw(id);
  8318. if (children.has(id)) return selected;
  8319. return parentStrategy.select({
  8320. id,
  8321. selected,
  8322. children,
  8323. ...rest
  8324. });
  8325. },
  8326. in: parentStrategy.in,
  8327. out: parentStrategy.out
  8328. };
  8329. return strategy;
  8330. };
  8331. const classicSelectStrategy = mandatory => {
  8332. const strategy = {
  8333. select: _ref6 => {
  8334. let {
  8335. id,
  8336. value,
  8337. selected,
  8338. children,
  8339. parents
  8340. } = _ref6;
  8341. id = toRaw(id);
  8342. const original = new Map(selected);
  8343. const items = [id];
  8344. while (items.length) {
  8345. const item = items.shift();
  8346. selected.set(toRaw(item), value ? 'on' : 'off');
  8347. if (children.has(item)) {
  8348. items.push(...children.get(item));
  8349. }
  8350. }
  8351. let parent = toRaw(parents.get(id));
  8352. while (parent) {
  8353. const childrenIds = children.get(parent);
  8354. const everySelected = childrenIds.every(cid => selected.get(toRaw(cid)) === 'on');
  8355. const noneSelected = childrenIds.every(cid => !selected.has(toRaw(cid)) || selected.get(toRaw(cid)) === 'off');
  8356. selected.set(parent, everySelected ? 'on' : noneSelected ? 'off' : 'indeterminate');
  8357. parent = toRaw(parents.get(parent));
  8358. }
  8359. // If mandatory and planned deselect results in no selected
  8360. // items then we can't do it, so return original state
  8361. if (mandatory && !value) {
  8362. const on = Array.from(selected.entries()).reduce((arr, _ref7) => {
  8363. let [key, value] = _ref7;
  8364. if (value === 'on') arr.push(key);
  8365. return arr;
  8366. }, []);
  8367. if (on.length === 0) return original;
  8368. }
  8369. return selected;
  8370. },
  8371. in: (v, children, parents) => {
  8372. let map = new Map();
  8373. for (const id of v || []) {
  8374. map = strategy.select({
  8375. id,
  8376. value: true,
  8377. selected: new Map(map),
  8378. children,
  8379. parents
  8380. });
  8381. }
  8382. return map;
  8383. },
  8384. out: (v, children) => {
  8385. const arr = [];
  8386. for (const [key, value] of v.entries()) {
  8387. if (value === 'on' && !children.has(key)) arr.push(key);
  8388. }
  8389. return arr;
  8390. }
  8391. };
  8392. return strategy;
  8393. };
  8394. // Composables
  8395. // Types
  8396. const VNestedSymbol = Symbol.for('vuetify:nested');
  8397. const emptyNested = {
  8398. id: shallowRef(),
  8399. root: {
  8400. register: () => null,
  8401. unregister: () => null,
  8402. parents: ref(new Map()),
  8403. children: ref(new Map()),
  8404. open: () => null,
  8405. openOnSelect: () => null,
  8406. activate: () => null,
  8407. select: () => null,
  8408. activatable: ref(false),
  8409. selectable: ref(false),
  8410. opened: ref(new Set()),
  8411. activated: ref(new Set()),
  8412. selected: ref(new Map()),
  8413. selectedValues: ref([]),
  8414. getPath: () => []
  8415. }
  8416. };
  8417. const makeNestedProps = propsFactory({
  8418. activatable: Boolean,
  8419. selectable: Boolean,
  8420. activeStrategy: [String, Function, Object],
  8421. selectStrategy: [String, Function, Object],
  8422. openStrategy: [String, Object],
  8423. opened: null,
  8424. activated: null,
  8425. selected: null,
  8426. mandatory: Boolean
  8427. }, 'nested');
  8428. const useNested = props => {
  8429. let isUnmounted = false;
  8430. const children = ref(new Map());
  8431. const parents = ref(new Map());
  8432. const opened = useProxiedModel(props, 'opened', props.opened, v => new Set(v), v => [...v.values()]);
  8433. const activeStrategy = computed(() => {
  8434. if (typeof props.activeStrategy === 'object') return props.activeStrategy;
  8435. if (typeof props.activeStrategy === 'function') return props.activeStrategy(props.mandatory);
  8436. switch (props.activeStrategy) {
  8437. case 'leaf':
  8438. return leafActiveStrategy(props.mandatory);
  8439. case 'single-leaf':
  8440. return leafSingleActiveStrategy(props.mandatory);
  8441. case 'independent':
  8442. return independentActiveStrategy(props.mandatory);
  8443. case 'single-independent':
  8444. default:
  8445. return independentSingleActiveStrategy(props.mandatory);
  8446. }
  8447. });
  8448. const selectStrategy = computed(() => {
  8449. if (typeof props.selectStrategy === 'object') return props.selectStrategy;
  8450. if (typeof props.selectStrategy === 'function') return props.selectStrategy(props.mandatory);
  8451. switch (props.selectStrategy) {
  8452. case 'single-leaf':
  8453. return leafSingleSelectStrategy(props.mandatory);
  8454. case 'leaf':
  8455. return leafSelectStrategy(props.mandatory);
  8456. case 'independent':
  8457. return independentSelectStrategy(props.mandatory);
  8458. case 'single-independent':
  8459. return independentSingleSelectStrategy(props.mandatory);
  8460. case 'classic':
  8461. default:
  8462. return classicSelectStrategy(props.mandatory);
  8463. }
  8464. });
  8465. const openStrategy = computed(() => {
  8466. if (typeof props.openStrategy === 'object') return props.openStrategy;
  8467. switch (props.openStrategy) {
  8468. case 'list':
  8469. return listOpenStrategy;
  8470. case 'single':
  8471. return singleOpenStrategy;
  8472. case 'multiple':
  8473. default:
  8474. return multipleOpenStrategy;
  8475. }
  8476. });
  8477. const activated = useProxiedModel(props, 'activated', props.activated, v => activeStrategy.value.in(v, children.value, parents.value), v => activeStrategy.value.out(v, children.value, parents.value));
  8478. const selected = useProxiedModel(props, 'selected', props.selected, v => selectStrategy.value.in(v, children.value, parents.value), v => selectStrategy.value.out(v, children.value, parents.value));
  8479. onBeforeUnmount(() => {
  8480. isUnmounted = true;
  8481. });
  8482. function getPath(id) {
  8483. const path = [];
  8484. let parent = id;
  8485. while (parent != null) {
  8486. path.unshift(parent);
  8487. parent = parents.value.get(parent);
  8488. }
  8489. return path;
  8490. }
  8491. const vm = getCurrentInstance('nested');
  8492. const nodeIds = new Set();
  8493. const nested = {
  8494. id: shallowRef(),
  8495. root: {
  8496. opened,
  8497. activatable: toRef(props, 'activatable'),
  8498. selectable: toRef(props, 'selectable'),
  8499. activated,
  8500. selected,
  8501. selectedValues: computed(() => {
  8502. const arr = [];
  8503. for (const [key, value] of selected.value.entries()) {
  8504. if (value === 'on') arr.push(key);
  8505. }
  8506. return arr;
  8507. }),
  8508. register: (id, parentId, isGroup) => {
  8509. if (nodeIds.has(id)) {
  8510. const path = getPath(id).map(String).join(' -> ');
  8511. const newPath = getPath(parentId).concat(id).map(String).join(' -> ');
  8512. consoleError(`Multiple nodes with the same ID\n\t${path}\n\t${newPath}`);
  8513. return;
  8514. } else {
  8515. nodeIds.add(id);
  8516. }
  8517. parentId && id !== parentId && parents.value.set(id, parentId);
  8518. isGroup && children.value.set(id, []);
  8519. if (parentId != null) {
  8520. children.value.set(parentId, [...(children.value.get(parentId) || []), id]);
  8521. }
  8522. },
  8523. unregister: id => {
  8524. if (isUnmounted) return;
  8525. nodeIds.delete(id);
  8526. children.value.delete(id);
  8527. const parent = parents.value.get(id);
  8528. if (parent) {
  8529. const list = children.value.get(parent) ?? [];
  8530. children.value.set(parent, list.filter(child => child !== id));
  8531. }
  8532. parents.value.delete(id);
  8533. },
  8534. open: (id, value, event) => {
  8535. vm.emit('click:open', {
  8536. id,
  8537. value,
  8538. path: getPath(id),
  8539. event
  8540. });
  8541. const newOpened = openStrategy.value.open({
  8542. id,
  8543. value,
  8544. opened: new Set(opened.value),
  8545. children: children.value,
  8546. parents: parents.value,
  8547. event
  8548. });
  8549. newOpened && (opened.value = newOpened);
  8550. },
  8551. openOnSelect: (id, value, event) => {
  8552. const newOpened = openStrategy.value.select({
  8553. id,
  8554. value,
  8555. selected: new Map(selected.value),
  8556. opened: new Set(opened.value),
  8557. children: children.value,
  8558. parents: parents.value,
  8559. event
  8560. });
  8561. newOpened && (opened.value = newOpened);
  8562. },
  8563. select: (id, value, event) => {
  8564. vm.emit('click:select', {
  8565. id,
  8566. value,
  8567. path: getPath(id),
  8568. event
  8569. });
  8570. const newSelected = selectStrategy.value.select({
  8571. id,
  8572. value,
  8573. selected: new Map(selected.value),
  8574. children: children.value,
  8575. parents: parents.value,
  8576. event
  8577. });
  8578. newSelected && (selected.value = newSelected);
  8579. nested.root.openOnSelect(id, value, event);
  8580. },
  8581. activate: (id, value, event) => {
  8582. if (!props.activatable) {
  8583. return nested.root.select(id, true, event);
  8584. }
  8585. vm.emit('click:activate', {
  8586. id,
  8587. value,
  8588. path: getPath(id),
  8589. event
  8590. });
  8591. const newActivated = activeStrategy.value.activate({
  8592. id,
  8593. value,
  8594. activated: new Set(activated.value),
  8595. children: children.value,
  8596. parents: parents.value,
  8597. event
  8598. });
  8599. newActivated && (activated.value = newActivated);
  8600. },
  8601. children,
  8602. parents,
  8603. getPath
  8604. }
  8605. };
  8606. provide(VNestedSymbol, nested);
  8607. return nested.root;
  8608. };
  8609. const useNestedItem = (id, isGroup) => {
  8610. const parent = inject$1(VNestedSymbol, emptyNested);
  8611. const uidSymbol = Symbol(getUid());
  8612. const computedId = computed(() => id.value !== undefined ? id.value : uidSymbol);
  8613. const item = {
  8614. ...parent,
  8615. id: computedId,
  8616. open: (open, e) => parent.root.open(computedId.value, open, e),
  8617. openOnSelect: (open, e) => parent.root.openOnSelect(computedId.value, open, e),
  8618. isOpen: computed(() => parent.root.opened.value.has(computedId.value)),
  8619. parent: computed(() => parent.root.parents.value.get(computedId.value)),
  8620. activate: (activated, e) => parent.root.activate(computedId.value, activated, e),
  8621. isActivated: computed(() => parent.root.activated.value.has(toRaw(computedId.value))),
  8622. select: (selected, e) => parent.root.select(computedId.value, selected, e),
  8623. isSelected: computed(() => parent.root.selected.value.get(toRaw(computedId.value)) === 'on'),
  8624. isIndeterminate: computed(() => parent.root.selected.value.get(computedId.value) === 'indeterminate'),
  8625. isLeaf: computed(() => !parent.root.children.value.get(computedId.value)),
  8626. isGroupActivator: parent.isGroupActivator
  8627. };
  8628. onBeforeMount(() => {
  8629. !parent.isGroupActivator && parent.root.register(computedId.value, parent.id.value, isGroup);
  8630. });
  8631. onBeforeUnmount(() => {
  8632. !parent.isGroupActivator && parent.root.unregister(computedId.value);
  8633. });
  8634. isGroup && provide(VNestedSymbol, item);
  8635. return item;
  8636. };
  8637. const useNestedGroupActivator = () => {
  8638. const parent = inject$1(VNestedSymbol, emptyNested);
  8639. provide(VNestedSymbol, {
  8640. ...parent,
  8641. isGroupActivator: true
  8642. });
  8643. };
  8644. const VListGroupActivator = defineComponent({
  8645. name: 'VListGroupActivator',
  8646. setup(_, _ref) {
  8647. let {
  8648. slots
  8649. } = _ref;
  8650. useNestedGroupActivator();
  8651. return () => slots.default?.();
  8652. }
  8653. });
  8654. const makeVListGroupProps = propsFactory({
  8655. /* @deprecated */
  8656. activeColor: String,
  8657. baseColor: String,
  8658. color: String,
  8659. collapseIcon: {
  8660. type: IconValue,
  8661. default: '$collapse'
  8662. },
  8663. expandIcon: {
  8664. type: IconValue,
  8665. default: '$expand'
  8666. },
  8667. prependIcon: IconValue,
  8668. appendIcon: IconValue,
  8669. fluid: Boolean,
  8670. subgroup: Boolean,
  8671. title: String,
  8672. value: null,
  8673. ...makeComponentProps(),
  8674. ...makeTagProps()
  8675. }, 'VListGroup');
  8676. const VListGroup = genericComponent()({
  8677. name: 'VListGroup',
  8678. props: makeVListGroupProps(),
  8679. setup(props, _ref2) {
  8680. let {
  8681. slots
  8682. } = _ref2;
  8683. const {
  8684. isOpen,
  8685. open,
  8686. id: _id
  8687. } = useNestedItem(toRef(props, 'value'), true);
  8688. const id = computed(() => `v-list-group--id-${String(_id.value)}`);
  8689. const list = useList();
  8690. const {
  8691. isBooted
  8692. } = useSsrBoot();
  8693. function onClick(e) {
  8694. e.stopPropagation();
  8695. open(!isOpen.value, e);
  8696. }
  8697. const activatorProps = computed(() => ({
  8698. onClick,
  8699. class: 'v-list-group__header',
  8700. id: id.value
  8701. }));
  8702. const toggleIcon = computed(() => isOpen.value ? props.collapseIcon : props.expandIcon);
  8703. const activatorDefaults = computed(() => ({
  8704. VListItem: {
  8705. active: isOpen.value,
  8706. activeColor: props.activeColor,
  8707. baseColor: props.baseColor,
  8708. color: props.color,
  8709. prependIcon: props.prependIcon || props.subgroup && toggleIcon.value,
  8710. appendIcon: props.appendIcon || !props.subgroup && toggleIcon.value,
  8711. title: props.title,
  8712. value: props.value
  8713. }
  8714. }));
  8715. useRender(() => createVNode(props.tag, {
  8716. "class": ['v-list-group', {
  8717. 'v-list-group--prepend': list?.hasPrepend.value,
  8718. 'v-list-group--fluid': props.fluid,
  8719. 'v-list-group--subgroup': props.subgroup,
  8720. 'v-list-group--open': isOpen.value
  8721. }, props.class],
  8722. "style": props.style
  8723. }, {
  8724. default: () => [slots.activator && createVNode(VDefaultsProvider, {
  8725. "defaults": activatorDefaults.value
  8726. }, {
  8727. default: () => [createVNode(VListGroupActivator, null, {
  8728. default: () => [slots.activator({
  8729. props: activatorProps.value,
  8730. isOpen: isOpen.value
  8731. })]
  8732. })]
  8733. }), createVNode(MaybeTransition, {
  8734. "transition": {
  8735. component: VExpandTransition
  8736. },
  8737. "disabled": !isBooted.value
  8738. }, {
  8739. default: () => [withDirectives(createVNode("div", {
  8740. "class": "v-list-group__items",
  8741. "role": "group",
  8742. "aria-labelledby": id.value
  8743. }, [slots.default?.()]), [[vShow, isOpen.value]])]
  8744. })]
  8745. }));
  8746. return {
  8747. isOpen
  8748. };
  8749. }
  8750. });
  8751. const makeVListItemSubtitleProps = propsFactory({
  8752. opacity: [Number, String],
  8753. ...makeComponentProps(),
  8754. ...makeTagProps()
  8755. }, 'VListItemSubtitle');
  8756. const VListItemSubtitle = genericComponent()({
  8757. name: 'VListItemSubtitle',
  8758. props: makeVListItemSubtitleProps(),
  8759. setup(props, _ref) {
  8760. let {
  8761. slots
  8762. } = _ref;
  8763. useRender(() => createVNode(props.tag, {
  8764. "class": ['v-list-item-subtitle', props.class],
  8765. "style": [{
  8766. '--v-list-item-subtitle-opacity': props.opacity
  8767. }, props.style]
  8768. }, slots));
  8769. return {};
  8770. }
  8771. });
  8772. // Utilities
  8773. const VListItemTitle = createSimpleFunctional('v-list-item-title');
  8774. // Types
  8775. const makeVListItemProps = propsFactory({
  8776. active: {
  8777. type: Boolean,
  8778. default: undefined
  8779. },
  8780. activeClass: String,
  8781. /* @deprecated */
  8782. activeColor: String,
  8783. appendAvatar: String,
  8784. appendIcon: IconValue,
  8785. baseColor: String,
  8786. disabled: Boolean,
  8787. lines: [Boolean, String],
  8788. link: {
  8789. type: Boolean,
  8790. default: undefined
  8791. },
  8792. nav: Boolean,
  8793. prependAvatar: String,
  8794. prependIcon: IconValue,
  8795. ripple: {
  8796. type: [Boolean, Object],
  8797. default: true
  8798. },
  8799. slim: Boolean,
  8800. subtitle: [String, Number],
  8801. title: [String, Number],
  8802. value: null,
  8803. onClick: EventProp(),
  8804. onClickOnce: EventProp(),
  8805. ...makeBorderProps(),
  8806. ...makeComponentProps(),
  8807. ...makeDensityProps(),
  8808. ...makeDimensionProps(),
  8809. ...makeElevationProps(),
  8810. ...makeRoundedProps(),
  8811. ...makeRouterProps(),
  8812. ...makeTagProps(),
  8813. ...makeThemeProps(),
  8814. ...makeVariantProps({
  8815. variant: 'text'
  8816. })
  8817. }, 'VListItem');
  8818. const VListItem = genericComponent()({
  8819. name: 'VListItem',
  8820. directives: {
  8821. Ripple
  8822. },
  8823. props: makeVListItemProps(),
  8824. emits: {
  8825. click: e => true
  8826. },
  8827. setup(props, _ref) {
  8828. let {
  8829. attrs,
  8830. slots,
  8831. emit
  8832. } = _ref;
  8833. const link = useLink(props, attrs);
  8834. const id = computed(() => props.value === undefined ? link.href.value : props.value);
  8835. const {
  8836. activate,
  8837. isActivated,
  8838. select,
  8839. isOpen,
  8840. isSelected,
  8841. isIndeterminate,
  8842. isGroupActivator,
  8843. root,
  8844. parent,
  8845. openOnSelect,
  8846. id: uid
  8847. } = useNestedItem(id, false);
  8848. const list = useList();
  8849. const isActive = computed(() => props.active !== false && (props.active || link.isActive?.value || (root.activatable.value ? isActivated.value : isSelected.value)));
  8850. const isLink = computed(() => props.link !== false && link.isLink.value);
  8851. const isSelectable = computed(() => !!list && (root.selectable.value || root.activatable.value || props.value != null));
  8852. const isClickable = computed(() => !props.disabled && props.link !== false && (props.link || link.isClickable.value || isSelectable.value));
  8853. const roundedProps = computed(() => props.rounded || props.nav);
  8854. const color = computed(() => props.color ?? props.activeColor);
  8855. const variantProps = computed(() => ({
  8856. color: isActive.value ? color.value ?? props.baseColor : props.baseColor,
  8857. variant: props.variant
  8858. }));
  8859. // useNestedItem doesn't call register until beforeMount,
  8860. // so this can't be an immediate watcher as we don't know parent yet
  8861. watch(() => link.isActive?.value, val => {
  8862. if (!val) return;
  8863. handleActiveLink();
  8864. });
  8865. onBeforeMount(() => {
  8866. if (link.isActive?.value) handleActiveLink();
  8867. });
  8868. function handleActiveLink() {
  8869. if (parent.value != null) {
  8870. root.open(parent.value, true);
  8871. }
  8872. openOnSelect(true);
  8873. }
  8874. const {
  8875. themeClasses
  8876. } = provideTheme(props);
  8877. const {
  8878. borderClasses
  8879. } = useBorder(props);
  8880. const {
  8881. colorClasses,
  8882. colorStyles,
  8883. variantClasses
  8884. } = useVariant(variantProps);
  8885. const {
  8886. densityClasses
  8887. } = useDensity(props);
  8888. const {
  8889. dimensionStyles
  8890. } = useDimension(props);
  8891. const {
  8892. elevationClasses
  8893. } = useElevation(props);
  8894. const {
  8895. roundedClasses
  8896. } = useRounded(roundedProps);
  8897. const lineClasses = computed(() => props.lines ? `v-list-item--${props.lines}-line` : undefined);
  8898. const slotProps = computed(() => ({
  8899. isActive: isActive.value,
  8900. select,
  8901. isOpen: isOpen.value,
  8902. isSelected: isSelected.value,
  8903. isIndeterminate: isIndeterminate.value
  8904. }));
  8905. function onClick(e) {
  8906. emit('click', e);
  8907. if (!isClickable.value) return;
  8908. link.navigate?.(e);
  8909. if (isGroupActivator) return;
  8910. if (root.activatable.value) {
  8911. activate(!isActivated.value, e);
  8912. } else if (root.selectable.value) {
  8913. select(!isSelected.value, e);
  8914. } else if (props.value != null) {
  8915. select(!isSelected.value, e);
  8916. }
  8917. }
  8918. function onKeyDown(e) {
  8919. if (e.key === 'Enter' || e.key === ' ') {
  8920. e.preventDefault();
  8921. e.target.dispatchEvent(new MouseEvent('click', e));
  8922. }
  8923. }
  8924. useRender(() => {
  8925. const Tag = isLink.value ? 'a' : props.tag;
  8926. const hasTitle = slots.title || props.title != null;
  8927. const hasSubtitle = slots.subtitle || props.subtitle != null;
  8928. const hasAppendMedia = !!(props.appendAvatar || props.appendIcon);
  8929. const hasAppend = !!(hasAppendMedia || slots.append);
  8930. const hasPrependMedia = !!(props.prependAvatar || props.prependIcon);
  8931. const hasPrepend = !!(hasPrependMedia || slots.prepend);
  8932. list?.updateHasPrepend(hasPrepend);
  8933. if (props.activeColor) {
  8934. deprecate('active-color', ['color', 'base-color']);
  8935. }
  8936. return withDirectives(createVNode(Tag, mergeProps({
  8937. "class": ['v-list-item', {
  8938. 'v-list-item--active': isActive.value,
  8939. 'v-list-item--disabled': props.disabled,
  8940. 'v-list-item--link': isClickable.value,
  8941. 'v-list-item--nav': props.nav,
  8942. 'v-list-item--prepend': !hasPrepend && list?.hasPrepend.value,
  8943. 'v-list-item--slim': props.slim,
  8944. [`${props.activeClass}`]: props.activeClass && isActive.value
  8945. }, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, variantClasses.value, props.class],
  8946. "style": [colorStyles.value, dimensionStyles.value, props.style],
  8947. "tabindex": isClickable.value ? list ? -2 : 0 : undefined,
  8948. "aria-selected": isSelectable.value ? root.activatable.value ? isActivated.value : root.selectable.value ? isSelected.value : isActive.value : undefined,
  8949. "onClick": onClick,
  8950. "onKeydown": isClickable.value && !isLink.value && onKeyDown
  8951. }, link.linkProps), {
  8952. default: () => [genOverlays(isClickable.value || isActive.value, 'v-list-item'), hasPrepend && createVNode("div", {
  8953. "key": "prepend",
  8954. "class": "v-list-item__prepend"
  8955. }, [!slots.prepend ? createVNode(Fragment, null, [props.prependAvatar && createVNode(VAvatar, {
  8956. "key": "prepend-avatar",
  8957. "density": props.density,
  8958. "image": props.prependAvatar
  8959. }, null), props.prependIcon && createVNode(VIcon, {
  8960. "key": "prepend-icon",
  8961. "density": props.density,
  8962. "icon": props.prependIcon
  8963. }, null)]) : createVNode(VDefaultsProvider, {
  8964. "key": "prepend-defaults",
  8965. "disabled": !hasPrependMedia,
  8966. "defaults": {
  8967. VAvatar: {
  8968. density: props.density,
  8969. image: props.prependAvatar
  8970. },
  8971. VIcon: {
  8972. density: props.density,
  8973. icon: props.prependIcon
  8974. },
  8975. VListItemAction: {
  8976. start: true
  8977. }
  8978. }
  8979. }, {
  8980. default: () => [slots.prepend?.(slotProps.value)]
  8981. }), createVNode("div", {
  8982. "class": "v-list-item__spacer"
  8983. }, null)]), createVNode("div", {
  8984. "class": "v-list-item__content",
  8985. "data-no-activator": ""
  8986. }, [hasTitle && createVNode(VListItemTitle, {
  8987. "key": "title"
  8988. }, {
  8989. default: () => [slots.title?.({
  8990. title: props.title
  8991. }) ?? props.title]
  8992. }), hasSubtitle && createVNode(VListItemSubtitle, {
  8993. "key": "subtitle"
  8994. }, {
  8995. default: () => [slots.subtitle?.({
  8996. subtitle: props.subtitle
  8997. }) ?? props.subtitle]
  8998. }), slots.default?.(slotProps.value)]), hasAppend && createVNode("div", {
  8999. "key": "append",
  9000. "class": "v-list-item__append"
  9001. }, [!slots.append ? createVNode(Fragment, null, [props.appendIcon && createVNode(VIcon, {
  9002. "key": "append-icon",
  9003. "density": props.density,
  9004. "icon": props.appendIcon
  9005. }, null), props.appendAvatar && createVNode(VAvatar, {
  9006. "key": "append-avatar",
  9007. "density": props.density,
  9008. "image": props.appendAvatar
  9009. }, null)]) : createVNode(VDefaultsProvider, {
  9010. "key": "append-defaults",
  9011. "disabled": !hasAppendMedia,
  9012. "defaults": {
  9013. VAvatar: {
  9014. density: props.density,
  9015. image: props.appendAvatar
  9016. },
  9017. VIcon: {
  9018. density: props.density,
  9019. icon: props.appendIcon
  9020. },
  9021. VListItemAction: {
  9022. end: true
  9023. }
  9024. }
  9025. }, {
  9026. default: () => [slots.append?.(slotProps.value)]
  9027. }), createVNode("div", {
  9028. "class": "v-list-item__spacer"
  9029. }, null)])]
  9030. }), [[resolveDirective("ripple"), isClickable.value && props.ripple]]);
  9031. });
  9032. return {
  9033. activate,
  9034. isActivated,
  9035. isGroupActivator,
  9036. isSelected,
  9037. list,
  9038. select,
  9039. root,
  9040. id: uid
  9041. };
  9042. }
  9043. });
  9044. const makeVListSubheaderProps = propsFactory({
  9045. color: String,
  9046. inset: Boolean,
  9047. sticky: Boolean,
  9048. title: String,
  9049. ...makeComponentProps(),
  9050. ...makeTagProps()
  9051. }, 'VListSubheader');
  9052. const VListSubheader = genericComponent()({
  9053. name: 'VListSubheader',
  9054. props: makeVListSubheaderProps(),
  9055. setup(props, _ref) {
  9056. let {
  9057. slots
  9058. } = _ref;
  9059. const {
  9060. textColorClasses,
  9061. textColorStyles
  9062. } = useTextColor(toRef(props, 'color'));
  9063. useRender(() => {
  9064. const hasText = !!(slots.default || props.title);
  9065. return createVNode(props.tag, {
  9066. "class": ['v-list-subheader', {
  9067. 'v-list-subheader--inset': props.inset,
  9068. 'v-list-subheader--sticky': props.sticky
  9069. }, textColorClasses.value, props.class],
  9070. "style": [{
  9071. textColorStyles
  9072. }, props.style]
  9073. }, {
  9074. default: () => [hasText && createVNode("div", {
  9075. "class": "v-list-subheader__text"
  9076. }, [slots.default?.() ?? props.title])]
  9077. });
  9078. });
  9079. return {};
  9080. }
  9081. });
  9082. const makeVDividerProps = propsFactory({
  9083. color: String,
  9084. inset: Boolean,
  9085. length: [Number, String],
  9086. opacity: [Number, String],
  9087. thickness: [Number, String],
  9088. vertical: Boolean,
  9089. ...makeComponentProps(),
  9090. ...makeThemeProps()
  9091. }, 'VDivider');
  9092. const VDivider = genericComponent()({
  9093. name: 'VDivider',
  9094. props: makeVDividerProps(),
  9095. setup(props, _ref) {
  9096. let {
  9097. attrs,
  9098. slots
  9099. } = _ref;
  9100. const {
  9101. themeClasses
  9102. } = provideTheme(props);
  9103. const {
  9104. textColorClasses,
  9105. textColorStyles
  9106. } = useTextColor(toRef(props, 'color'));
  9107. const dividerStyles = computed(() => {
  9108. const styles = {};
  9109. if (props.length) {
  9110. styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
  9111. }
  9112. if (props.thickness) {
  9113. styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
  9114. }
  9115. return styles;
  9116. });
  9117. useRender(() => {
  9118. const divider = createVNode("hr", {
  9119. "class": [{
  9120. 'v-divider': true,
  9121. 'v-divider--inset': props.inset,
  9122. 'v-divider--vertical': props.vertical
  9123. }, themeClasses.value, textColorClasses.value, props.class],
  9124. "style": [dividerStyles.value, textColorStyles.value, {
  9125. '--v-border-opacity': props.opacity
  9126. }, props.style],
  9127. "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
  9128. "role": `${attrs.role || 'separator'}`
  9129. }, null);
  9130. if (!slots.default) return divider;
  9131. return createVNode("div", {
  9132. "class": ['v-divider__wrapper', {
  9133. 'v-divider__wrapper--vertical': props.vertical,
  9134. 'v-divider__wrapper--inset': props.inset
  9135. }]
  9136. }, [divider, createVNode("div", {
  9137. "class": "v-divider__content"
  9138. }, [slots.default()]), divider]);
  9139. });
  9140. return {};
  9141. }
  9142. });
  9143. // Types
  9144. const makeVListChildrenProps = propsFactory({
  9145. items: Array,
  9146. returnObject: Boolean
  9147. }, 'VListChildren');
  9148. const VListChildren = genericComponent()({
  9149. name: 'VListChildren',
  9150. props: makeVListChildrenProps(),
  9151. setup(props, _ref) {
  9152. let {
  9153. slots
  9154. } = _ref;
  9155. createList();
  9156. return () => slots.default?.() ?? props.items?.map(_ref2 => {
  9157. let {
  9158. children,
  9159. props: itemProps,
  9160. type,
  9161. raw: item
  9162. } = _ref2;
  9163. if (type === 'divider') {
  9164. return slots.divider?.({
  9165. props: itemProps
  9166. }) ?? createVNode(VDivider, itemProps, null);
  9167. }
  9168. if (type === 'subheader') {
  9169. return slots.subheader?.({
  9170. props: itemProps
  9171. }) ?? createVNode(VListSubheader, itemProps, null);
  9172. }
  9173. const slotsWithItem = {
  9174. subtitle: slots.subtitle ? slotProps => slots.subtitle?.({
  9175. ...slotProps,
  9176. item
  9177. }) : undefined,
  9178. prepend: slots.prepend ? slotProps => slots.prepend?.({
  9179. ...slotProps,
  9180. item
  9181. }) : undefined,
  9182. append: slots.append ? slotProps => slots.append?.({
  9183. ...slotProps,
  9184. item
  9185. }) : undefined,
  9186. title: slots.title ? slotProps => slots.title?.({
  9187. ...slotProps,
  9188. item
  9189. }) : undefined
  9190. };
  9191. const listGroupProps = VListGroup.filterProps(itemProps);
  9192. return children ? createVNode(VListGroup, mergeProps({
  9193. "value": itemProps?.value
  9194. }, listGroupProps), {
  9195. activator: _ref3 => {
  9196. let {
  9197. props: activatorProps
  9198. } = _ref3;
  9199. const listItemProps = {
  9200. ...itemProps,
  9201. ...activatorProps,
  9202. value: props.returnObject ? item : itemProps.value
  9203. };
  9204. return slots.header ? slots.header({
  9205. props: listItemProps
  9206. }) : createVNode(VListItem, listItemProps, slotsWithItem);
  9207. },
  9208. default: () => createVNode(VListChildren, {
  9209. "items": children,
  9210. "returnObject": props.returnObject
  9211. }, slots)
  9212. }) : slots.item ? slots.item({
  9213. props: itemProps
  9214. }) : createVNode(VListItem, mergeProps(itemProps, {
  9215. "value": props.returnObject ? item : itemProps.value
  9216. }), slotsWithItem);
  9217. });
  9218. }
  9219. });
  9220. // Utilities
  9221. // Types
  9222. // Composables
  9223. const makeItemsProps = propsFactory({
  9224. items: {
  9225. type: Array,
  9226. default: () => []
  9227. },
  9228. itemTitle: {
  9229. type: [String, Array, Function],
  9230. default: 'title'
  9231. },
  9232. itemValue: {
  9233. type: [String, Array, Function],
  9234. default: 'value'
  9235. },
  9236. itemChildren: {
  9237. type: [Boolean, String, Array, Function],
  9238. default: 'children'
  9239. },
  9240. itemProps: {
  9241. type: [Boolean, String, Array, Function],
  9242. default: 'props'
  9243. },
  9244. returnObject: Boolean,
  9245. valueComparator: {
  9246. type: Function,
  9247. default: deepEqual
  9248. }
  9249. }, 'list-items');
  9250. function transformItem$3(props, item) {
  9251. const title = getPropertyFromItem(item, props.itemTitle, item);
  9252. const value = getPropertyFromItem(item, props.itemValue, title);
  9253. const children = getPropertyFromItem(item, props.itemChildren);
  9254. const itemProps = props.itemProps === true ? typeof item === 'object' && item != null && !Array.isArray(item) ? 'children' in item ? omit(item, ['children']) : item : undefined : getPropertyFromItem(item, props.itemProps);
  9255. const _props = {
  9256. title,
  9257. value,
  9258. ...itemProps
  9259. };
  9260. return {
  9261. title: String(_props.title ?? ''),
  9262. value: _props.value,
  9263. props: _props,
  9264. children: Array.isArray(children) ? transformItems$3(props, children) : undefined,
  9265. raw: item
  9266. };
  9267. }
  9268. function transformItems$3(props, items) {
  9269. const array = [];
  9270. for (const item of items) {
  9271. array.push(transformItem$3(props, item));
  9272. }
  9273. return array;
  9274. }
  9275. function useItems(props) {
  9276. const items = computed(() => transformItems$3(props, props.items));
  9277. const hasNullItem = computed(() => items.value.some(item => item.value === null));
  9278. function transformIn(value) {
  9279. if (!hasNullItem.value) {
  9280. // When the model value is null, return an InternalItem
  9281. // based on null only if null is one of the items
  9282. value = value.filter(v => v !== null);
  9283. }
  9284. return value.map(v => {
  9285. if (props.returnObject && typeof v === 'string') {
  9286. // String model value means value is a custom input value from combobox
  9287. // Don't look up existing items if the model value is a string
  9288. return transformItem$3(props, v);
  9289. }
  9290. return items.value.find(item => props.valueComparator(v, item.value)) || transformItem$3(props, v);
  9291. });
  9292. }
  9293. function transformOut(value) {
  9294. return props.returnObject ? value.map(_ref => {
  9295. let {
  9296. raw
  9297. } = _ref;
  9298. return raw;
  9299. }) : value.map(_ref2 => {
  9300. let {
  9301. value
  9302. } = _ref2;
  9303. return value;
  9304. });
  9305. }
  9306. return {
  9307. items,
  9308. transformIn,
  9309. transformOut
  9310. };
  9311. }
  9312. // Types
  9313. function isPrimitive(value) {
  9314. return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean';
  9315. }
  9316. function transformItem$2(props, item) {
  9317. const type = getPropertyFromItem(item, props.itemType, 'item');
  9318. const title = isPrimitive(item) ? item : getPropertyFromItem(item, props.itemTitle);
  9319. const value = getPropertyFromItem(item, props.itemValue, undefined);
  9320. const children = getPropertyFromItem(item, props.itemChildren);
  9321. const itemProps = props.itemProps === true ? omit(item, ['children']) : getPropertyFromItem(item, props.itemProps);
  9322. const _props = {
  9323. title,
  9324. value,
  9325. ...itemProps
  9326. };
  9327. return {
  9328. type,
  9329. title: _props.title,
  9330. value: _props.value,
  9331. props: _props,
  9332. children: type === 'item' && children ? transformItems$2(props, children) : undefined,
  9333. raw: item
  9334. };
  9335. }
  9336. function transformItems$2(props, items) {
  9337. const array = [];
  9338. for (const item of items) {
  9339. array.push(transformItem$2(props, item));
  9340. }
  9341. return array;
  9342. }
  9343. function useListItems(props) {
  9344. const items = computed(() => transformItems$2(props, props.items));
  9345. return {
  9346. items
  9347. };
  9348. }
  9349. const makeVListProps = propsFactory({
  9350. baseColor: String,
  9351. /* @deprecated */
  9352. activeColor: String,
  9353. activeClass: String,
  9354. bgColor: String,
  9355. disabled: Boolean,
  9356. expandIcon: IconValue,
  9357. collapseIcon: IconValue,
  9358. lines: {
  9359. type: [Boolean, String],
  9360. default: 'one'
  9361. },
  9362. slim: Boolean,
  9363. nav: Boolean,
  9364. 'onClick:open': EventProp(),
  9365. 'onClick:select': EventProp(),
  9366. 'onUpdate:opened': EventProp(),
  9367. ...makeNestedProps({
  9368. selectStrategy: 'single-leaf',
  9369. openStrategy: 'list'
  9370. }),
  9371. ...makeBorderProps(),
  9372. ...makeComponentProps(),
  9373. ...makeDensityProps(),
  9374. ...makeDimensionProps(),
  9375. ...makeElevationProps(),
  9376. itemType: {
  9377. type: String,
  9378. default: 'type'
  9379. },
  9380. ...makeItemsProps(),
  9381. ...makeRoundedProps(),
  9382. ...makeTagProps(),
  9383. ...makeThemeProps(),
  9384. ...makeVariantProps({
  9385. variant: 'text'
  9386. })
  9387. }, 'VList');
  9388. const VList = genericComponent()({
  9389. name: 'VList',
  9390. props: makeVListProps(),
  9391. emits: {
  9392. 'update:selected': value => true,
  9393. 'update:activated': value => true,
  9394. 'update:opened': value => true,
  9395. 'click:open': value => true,
  9396. 'click:activate': value => true,
  9397. 'click:select': value => true
  9398. },
  9399. setup(props, _ref) {
  9400. let {
  9401. slots
  9402. } = _ref;
  9403. const {
  9404. items
  9405. } = useListItems(props);
  9406. const {
  9407. themeClasses
  9408. } = provideTheme(props);
  9409. const {
  9410. backgroundColorClasses,
  9411. backgroundColorStyles
  9412. } = useBackgroundColor(toRef(props, 'bgColor'));
  9413. const {
  9414. borderClasses
  9415. } = useBorder(props);
  9416. const {
  9417. densityClasses
  9418. } = useDensity(props);
  9419. const {
  9420. dimensionStyles
  9421. } = useDimension(props);
  9422. const {
  9423. elevationClasses
  9424. } = useElevation(props);
  9425. const {
  9426. roundedClasses
  9427. } = useRounded(props);
  9428. const {
  9429. children,
  9430. open,
  9431. parents,
  9432. select,
  9433. getPath
  9434. } = useNested(props);
  9435. const lineClasses = computed(() => props.lines ? `v-list--${props.lines}-line` : undefined);
  9436. const activeColor = toRef(props, 'activeColor');
  9437. const baseColor = toRef(props, 'baseColor');
  9438. const color = toRef(props, 'color');
  9439. createList();
  9440. provideDefaults({
  9441. VListGroup: {
  9442. activeColor,
  9443. baseColor,
  9444. color,
  9445. expandIcon: toRef(props, 'expandIcon'),
  9446. collapseIcon: toRef(props, 'collapseIcon')
  9447. },
  9448. VListItem: {
  9449. activeClass: toRef(props, 'activeClass'),
  9450. activeColor,
  9451. baseColor,
  9452. color,
  9453. density: toRef(props, 'density'),
  9454. disabled: toRef(props, 'disabled'),
  9455. lines: toRef(props, 'lines'),
  9456. nav: toRef(props, 'nav'),
  9457. slim: toRef(props, 'slim'),
  9458. variant: toRef(props, 'variant')
  9459. }
  9460. });
  9461. const isFocused = shallowRef(false);
  9462. const contentRef = ref();
  9463. function onFocusin(e) {
  9464. isFocused.value = true;
  9465. }
  9466. function onFocusout(e) {
  9467. isFocused.value = false;
  9468. }
  9469. function onFocus(e) {
  9470. if (!isFocused.value && !(e.relatedTarget && contentRef.value?.contains(e.relatedTarget))) focus();
  9471. }
  9472. function onKeydown(e) {
  9473. const target = e.target;
  9474. if (!contentRef.value || ['INPUT', 'TEXTAREA'].includes(target.tagName)) return;
  9475. if (e.key === 'ArrowDown') {
  9476. focus('next');
  9477. } else if (e.key === 'ArrowUp') {
  9478. focus('prev');
  9479. } else if (e.key === 'Home') {
  9480. focus('first');
  9481. } else if (e.key === 'End') {
  9482. focus('last');
  9483. } else {
  9484. return;
  9485. }
  9486. e.preventDefault();
  9487. }
  9488. function onMousedown(e) {
  9489. isFocused.value = true;
  9490. }
  9491. function focus(location) {
  9492. if (contentRef.value) {
  9493. return focusChild(contentRef.value, location);
  9494. }
  9495. }
  9496. useRender(() => {
  9497. return createVNode(props.tag, {
  9498. "ref": contentRef,
  9499. "class": ['v-list', {
  9500. 'v-list--disabled': props.disabled,
  9501. 'v-list--nav': props.nav,
  9502. 'v-list--slim': props.slim
  9503. }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, props.class],
  9504. "style": [backgroundColorStyles.value, dimensionStyles.value, props.style],
  9505. "tabindex": props.disabled || isFocused.value ? -1 : 0,
  9506. "role": "listbox",
  9507. "aria-activedescendant": undefined,
  9508. "onFocusin": onFocusin,
  9509. "onFocusout": onFocusout,
  9510. "onFocus": onFocus,
  9511. "onKeydown": onKeydown,
  9512. "onMousedown": onMousedown
  9513. }, {
  9514. default: () => [createVNode(VListChildren, {
  9515. "items": items.value,
  9516. "returnObject": props.returnObject
  9517. }, slots)]
  9518. });
  9519. });
  9520. return {
  9521. open,
  9522. select,
  9523. focus,
  9524. children,
  9525. parents,
  9526. getPath
  9527. };
  9528. }
  9529. });
  9530. // Utilities
  9531. const VListImg = createSimpleFunctional('v-list-img');
  9532. const makeVListItemActionProps = propsFactory({
  9533. start: Boolean,
  9534. end: Boolean,
  9535. ...makeComponentProps(),
  9536. ...makeTagProps()
  9537. }, 'VListItemAction');
  9538. const VListItemAction = genericComponent()({
  9539. name: 'VListItemAction',
  9540. props: makeVListItemActionProps(),
  9541. setup(props, _ref) {
  9542. let {
  9543. slots
  9544. } = _ref;
  9545. useRender(() => createVNode(props.tag, {
  9546. "class": ['v-list-item-action', {
  9547. 'v-list-item-action--start': props.start,
  9548. 'v-list-item-action--end': props.end
  9549. }, props.class],
  9550. "style": props.style
  9551. }, slots));
  9552. return {};
  9553. }
  9554. });
  9555. const makeVListItemMediaProps = propsFactory({
  9556. start: Boolean,
  9557. end: Boolean,
  9558. ...makeComponentProps(),
  9559. ...makeTagProps()
  9560. }, 'VListItemMedia');
  9561. const VListItemMedia = genericComponent()({
  9562. name: 'VListItemMedia',
  9563. props: makeVListItemMediaProps(),
  9564. setup(props, _ref) {
  9565. let {
  9566. slots
  9567. } = _ref;
  9568. useRender(() => {
  9569. return createVNode(props.tag, {
  9570. "class": ['v-list-item-media', {
  9571. 'v-list-item-media--start': props.start,
  9572. 'v-list-item-media--end': props.end
  9573. }, props.class],
  9574. "style": props.style
  9575. }, slots);
  9576. });
  9577. return {};
  9578. }
  9579. });
  9580. // Types
  9581. /** Convert a point in local space to viewport space */
  9582. function elementToViewport(point, offset) {
  9583. return {
  9584. x: point.x + offset.x,
  9585. y: point.y + offset.y
  9586. };
  9587. }
  9588. /** Get the difference between two points */
  9589. function getOffset$1(a, b) {
  9590. return {
  9591. x: a.x - b.x,
  9592. y: a.y - b.y
  9593. };
  9594. }
  9595. /** Convert an anchor object to a point in local space */
  9596. function anchorToPoint(anchor, box) {
  9597. if (anchor.side === 'top' || anchor.side === 'bottom') {
  9598. const {
  9599. side,
  9600. align
  9601. } = anchor;
  9602. const x = align === 'left' ? 0 : align === 'center' ? box.width / 2 : align === 'right' ? box.width : align;
  9603. const y = side === 'top' ? 0 : side === 'bottom' ? box.height : side;
  9604. return elementToViewport({
  9605. x,
  9606. y
  9607. }, box);
  9608. } else if (anchor.side === 'left' || anchor.side === 'right') {
  9609. const {
  9610. side,
  9611. align
  9612. } = anchor;
  9613. const x = side === 'left' ? 0 : side === 'right' ? box.width : side;
  9614. const y = align === 'top' ? 0 : align === 'center' ? box.height / 2 : align === 'bottom' ? box.height : align;
  9615. return elementToViewport({
  9616. x,
  9617. y
  9618. }, box);
  9619. }
  9620. return elementToViewport({
  9621. x: box.width / 2,
  9622. y: box.height / 2
  9623. }, box);
  9624. }
  9625. // Composables
  9626. // Types
  9627. const locationStrategies = {
  9628. static: staticLocationStrategy,
  9629. // specific viewport position, usually centered
  9630. connected: connectedLocationStrategy // connected to a certain element
  9631. };
  9632. const makeLocationStrategyProps = propsFactory({
  9633. locationStrategy: {
  9634. type: [String, Function],
  9635. default: 'static',
  9636. validator: val => typeof val === 'function' || val in locationStrategies
  9637. },
  9638. location: {
  9639. type: String,
  9640. default: 'bottom'
  9641. },
  9642. origin: {
  9643. type: String,
  9644. default: 'auto'
  9645. },
  9646. offset: [Number, String, Array]
  9647. }, 'VOverlay-location-strategies');
  9648. function useLocationStrategies(props, data) {
  9649. const contentStyles = ref({});
  9650. const updateLocation = ref();
  9651. if (IN_BROWSER) {
  9652. useToggleScope(() => !!(data.isActive.value && props.locationStrategy), reset => {
  9653. watch(() => props.locationStrategy, reset);
  9654. onScopeDispose(() => {
  9655. window.removeEventListener('resize', onResize);
  9656. updateLocation.value = undefined;
  9657. });
  9658. window.addEventListener('resize', onResize, {
  9659. passive: true
  9660. });
  9661. if (typeof props.locationStrategy === 'function') {
  9662. updateLocation.value = props.locationStrategy(data, props, contentStyles)?.updateLocation;
  9663. } else {
  9664. updateLocation.value = locationStrategies[props.locationStrategy](data, props, contentStyles)?.updateLocation;
  9665. }
  9666. });
  9667. }
  9668. function onResize(e) {
  9669. updateLocation.value?.(e);
  9670. }
  9671. return {
  9672. contentStyles,
  9673. updateLocation
  9674. };
  9675. }
  9676. function staticLocationStrategy() {
  9677. // TODO
  9678. }
  9679. /** Get size of element ignoring max-width/max-height */
  9680. function getIntrinsicSize(el, isRtl) {
  9681. // const scrollables = new Map<Element, [number, number]>()
  9682. // el.querySelectorAll('*').forEach(el => {
  9683. // const x = el.scrollLeft
  9684. // const y = el.scrollTop
  9685. // if (x || y) {
  9686. // scrollables.set(el, [x, y])
  9687. // }
  9688. // })
  9689. // const initialMaxWidth = el.style.maxWidth
  9690. // const initialMaxHeight = el.style.maxHeight
  9691. // el.style.removeProperty('max-width')
  9692. // el.style.removeProperty('max-height')
  9693. /* eslint-disable-next-line sonarjs/prefer-immediate-return */
  9694. const contentBox = nullifyTransforms(el);
  9695. if (isRtl) {
  9696. contentBox.x += parseFloat(el.style.right || 0);
  9697. } else {
  9698. contentBox.x -= parseFloat(el.style.left || 0);
  9699. }
  9700. contentBox.y -= parseFloat(el.style.top || 0);
  9701. // el.style.maxWidth = initialMaxWidth
  9702. // el.style.maxHeight = initialMaxHeight
  9703. // scrollables.forEach((position, el) => {
  9704. // el.scrollTo(...position)
  9705. // })
  9706. return contentBox;
  9707. }
  9708. function connectedLocationStrategy(data, props, contentStyles) {
  9709. const activatorFixed = Array.isArray(data.target.value) || isFixedPosition(data.target.value);
  9710. if (activatorFixed) {
  9711. Object.assign(contentStyles.value, {
  9712. position: 'fixed',
  9713. top: 0,
  9714. [data.isRtl.value ? 'right' : 'left']: 0
  9715. });
  9716. }
  9717. const {
  9718. preferredAnchor,
  9719. preferredOrigin
  9720. } = destructComputed(() => {
  9721. const parsedAnchor = parseAnchor(props.location, data.isRtl.value);
  9722. const parsedOrigin = props.origin === 'overlap' ? parsedAnchor : props.origin === 'auto' ? flipSide(parsedAnchor) : parseAnchor(props.origin, data.isRtl.value);
  9723. // Some combinations of props may produce an invalid origin
  9724. if (parsedAnchor.side === parsedOrigin.side && parsedAnchor.align === flipAlign(parsedOrigin).align) {
  9725. return {
  9726. preferredAnchor: flipCorner(parsedAnchor),
  9727. preferredOrigin: flipCorner(parsedOrigin)
  9728. };
  9729. } else {
  9730. return {
  9731. preferredAnchor: parsedAnchor,
  9732. preferredOrigin: parsedOrigin
  9733. };
  9734. }
  9735. });
  9736. const [minWidth, minHeight, maxWidth, maxHeight] = ['minWidth', 'minHeight', 'maxWidth', 'maxHeight'].map(key => {
  9737. return computed(() => {
  9738. const val = parseFloat(props[key]);
  9739. return isNaN(val) ? Infinity : val;
  9740. });
  9741. });
  9742. const offset = computed(() => {
  9743. if (Array.isArray(props.offset)) {
  9744. return props.offset;
  9745. }
  9746. if (typeof props.offset === 'string') {
  9747. const offset = props.offset.split(' ').map(parseFloat);
  9748. if (offset.length < 2) offset.push(0);
  9749. return offset;
  9750. }
  9751. return typeof props.offset === 'number' ? [props.offset, 0] : [0, 0];
  9752. });
  9753. let observe = false;
  9754. const observer = new ResizeObserver(() => {
  9755. if (observe) updateLocation();
  9756. });
  9757. watch([data.target, data.contentEl], (_ref, _ref2) => {
  9758. let [newTarget, newContentEl] = _ref;
  9759. let [oldTarget, oldContentEl] = _ref2;
  9760. if (oldTarget && !Array.isArray(oldTarget)) observer.unobserve(oldTarget);
  9761. if (newTarget && !Array.isArray(newTarget)) observer.observe(newTarget);
  9762. if (oldContentEl) observer.unobserve(oldContentEl);
  9763. if (newContentEl) observer.observe(newContentEl);
  9764. }, {
  9765. immediate: true
  9766. });
  9767. onScopeDispose(() => {
  9768. observer.disconnect();
  9769. });
  9770. // eslint-disable-next-line max-statements
  9771. function updateLocation() {
  9772. observe = false;
  9773. requestAnimationFrame(() => observe = true);
  9774. if (!data.target.value || !data.contentEl.value) return;
  9775. const targetBox = getTargetBox(data.target.value);
  9776. const contentBox = getIntrinsicSize(data.contentEl.value, data.isRtl.value);
  9777. const scrollParents = getScrollParents(data.contentEl.value);
  9778. const viewportMargin = 12;
  9779. if (!scrollParents.length) {
  9780. scrollParents.push(document.documentElement);
  9781. if (!(data.contentEl.value.style.top && data.contentEl.value.style.left)) {
  9782. contentBox.x -= parseFloat(document.documentElement.style.getPropertyValue('--v-body-scroll-x') || 0);
  9783. contentBox.y -= parseFloat(document.documentElement.style.getPropertyValue('--v-body-scroll-y') || 0);
  9784. }
  9785. }
  9786. const viewport = scrollParents.reduce((box, el) => {
  9787. const rect = el.getBoundingClientRect();
  9788. const scrollBox = new Box({
  9789. x: el === document.documentElement ? 0 : rect.x,
  9790. y: el === document.documentElement ? 0 : rect.y,
  9791. width: el.clientWidth,
  9792. height: el.clientHeight
  9793. });
  9794. if (box) {
  9795. return new Box({
  9796. x: Math.max(box.left, scrollBox.left),
  9797. y: Math.max(box.top, scrollBox.top),
  9798. width: Math.min(box.right, scrollBox.right) - Math.max(box.left, scrollBox.left),
  9799. height: Math.min(box.bottom, scrollBox.bottom) - Math.max(box.top, scrollBox.top)
  9800. });
  9801. }
  9802. return scrollBox;
  9803. }, undefined);
  9804. viewport.x += viewportMargin;
  9805. viewport.y += viewportMargin;
  9806. viewport.width -= viewportMargin * 2;
  9807. viewport.height -= viewportMargin * 2;
  9808. let placement = {
  9809. anchor: preferredAnchor.value,
  9810. origin: preferredOrigin.value
  9811. };
  9812. function checkOverflow(_placement) {
  9813. const box = new Box(contentBox);
  9814. const targetPoint = anchorToPoint(_placement.anchor, targetBox);
  9815. const contentPoint = anchorToPoint(_placement.origin, box);
  9816. let {
  9817. x,
  9818. y
  9819. } = getOffset$1(targetPoint, contentPoint);
  9820. switch (_placement.anchor.side) {
  9821. case 'top':
  9822. y -= offset.value[0];
  9823. break;
  9824. case 'bottom':
  9825. y += offset.value[0];
  9826. break;
  9827. case 'left':
  9828. x -= offset.value[0];
  9829. break;
  9830. case 'right':
  9831. x += offset.value[0];
  9832. break;
  9833. }
  9834. switch (_placement.anchor.align) {
  9835. case 'top':
  9836. y -= offset.value[1];
  9837. break;
  9838. case 'bottom':
  9839. y += offset.value[1];
  9840. break;
  9841. case 'left':
  9842. x -= offset.value[1];
  9843. break;
  9844. case 'right':
  9845. x += offset.value[1];
  9846. break;
  9847. }
  9848. box.x += x;
  9849. box.y += y;
  9850. box.width = Math.min(box.width, maxWidth.value);
  9851. box.height = Math.min(box.height, maxHeight.value);
  9852. const overflows = getOverflow(box, viewport);
  9853. return {
  9854. overflows,
  9855. x,
  9856. y
  9857. };
  9858. }
  9859. let x = 0;
  9860. let y = 0;
  9861. const available = {
  9862. x: 0,
  9863. y: 0
  9864. };
  9865. const flipped = {
  9866. x: false,
  9867. y: false
  9868. };
  9869. let resets = -1;
  9870. while (true) {
  9871. if (resets++ > 10) {
  9872. consoleError('Infinite loop detected in connectedLocationStrategy');
  9873. break;
  9874. }
  9875. const {
  9876. x: _x,
  9877. y: _y,
  9878. overflows
  9879. } = checkOverflow(placement);
  9880. x += _x;
  9881. y += _y;
  9882. contentBox.x += _x;
  9883. contentBox.y += _y;
  9884. // flip
  9885. {
  9886. const axis = getAxis(placement.anchor);
  9887. const hasOverflowX = overflows.x.before || overflows.x.after;
  9888. const hasOverflowY = overflows.y.before || overflows.y.after;
  9889. let reset = false;
  9890. ['x', 'y'].forEach(key => {
  9891. if (key === 'x' && hasOverflowX && !flipped.x || key === 'y' && hasOverflowY && !flipped.y) {
  9892. const newPlacement = {
  9893. anchor: {
  9894. ...placement.anchor
  9895. },
  9896. origin: {
  9897. ...placement.origin
  9898. }
  9899. };
  9900. const flip = key === 'x' ? axis === 'y' ? flipAlign : flipSide : axis === 'y' ? flipSide : flipAlign;
  9901. newPlacement.anchor = flip(newPlacement.anchor);
  9902. newPlacement.origin = flip(newPlacement.origin);
  9903. const {
  9904. overflows: newOverflows
  9905. } = checkOverflow(newPlacement);
  9906. if (newOverflows[key].before <= overflows[key].before && newOverflows[key].after <= overflows[key].after || newOverflows[key].before + newOverflows[key].after < (overflows[key].before + overflows[key].after) / 2) {
  9907. placement = newPlacement;
  9908. reset = flipped[key] = true;
  9909. }
  9910. }
  9911. });
  9912. if (reset) continue;
  9913. }
  9914. // shift
  9915. if (overflows.x.before) {
  9916. x += overflows.x.before;
  9917. contentBox.x += overflows.x.before;
  9918. }
  9919. if (overflows.x.after) {
  9920. x -= overflows.x.after;
  9921. contentBox.x -= overflows.x.after;
  9922. }
  9923. if (overflows.y.before) {
  9924. y += overflows.y.before;
  9925. contentBox.y += overflows.y.before;
  9926. }
  9927. if (overflows.y.after) {
  9928. y -= overflows.y.after;
  9929. contentBox.y -= overflows.y.after;
  9930. }
  9931. // size
  9932. {
  9933. const overflows = getOverflow(contentBox, viewport);
  9934. available.x = viewport.width - overflows.x.before - overflows.x.after;
  9935. available.y = viewport.height - overflows.y.before - overflows.y.after;
  9936. x += overflows.x.before;
  9937. contentBox.x += overflows.x.before;
  9938. y += overflows.y.before;
  9939. contentBox.y += overflows.y.before;
  9940. }
  9941. break;
  9942. }
  9943. const axis = getAxis(placement.anchor);
  9944. Object.assign(contentStyles.value, {
  9945. '--v-overlay-anchor-origin': `${placement.anchor.side} ${placement.anchor.align}`,
  9946. transformOrigin: `${placement.origin.side} ${placement.origin.align}`,
  9947. // transform: `translate(${pixelRound(x)}px, ${pixelRound(y)}px)`,
  9948. top: convertToUnit(pixelRound(y)),
  9949. left: data.isRtl.value ? undefined : convertToUnit(pixelRound(x)),
  9950. right: data.isRtl.value ? convertToUnit(pixelRound(-x)) : undefined,
  9951. minWidth: convertToUnit(axis === 'y' ? Math.min(minWidth.value, targetBox.width) : minWidth.value),
  9952. maxWidth: convertToUnit(pixelCeil(clamp(available.x, minWidth.value === Infinity ? 0 : minWidth.value, maxWidth.value))),
  9953. maxHeight: convertToUnit(pixelCeil(clamp(available.y, minHeight.value === Infinity ? 0 : minHeight.value, maxHeight.value)))
  9954. });
  9955. return {
  9956. available,
  9957. contentBox
  9958. };
  9959. }
  9960. watch(() => [preferredAnchor.value, preferredOrigin.value, props.offset, props.minWidth, props.minHeight, props.maxWidth, props.maxHeight], () => updateLocation());
  9961. nextTick(() => {
  9962. const result = updateLocation();
  9963. // TODO: overflowing content should only require a single updateLocation call
  9964. // Icky hack to make sure the content is positioned consistently
  9965. if (!result) return;
  9966. const {
  9967. available,
  9968. contentBox
  9969. } = result;
  9970. if (contentBox.height > available.y) {
  9971. requestAnimationFrame(() => {
  9972. updateLocation();
  9973. requestAnimationFrame(() => {
  9974. updateLocation();
  9975. });
  9976. });
  9977. }
  9978. });
  9979. return {
  9980. updateLocation
  9981. };
  9982. }
  9983. function pixelRound(val) {
  9984. return Math.round(val * devicePixelRatio) / devicePixelRatio;
  9985. }
  9986. function pixelCeil(val) {
  9987. return Math.ceil(val * devicePixelRatio) / devicePixelRatio;
  9988. }
  9989. let clean = true;
  9990. const frames = [];
  9991. /**
  9992. * Schedule a task to run in an animation frame on its own
  9993. * This is useful for heavy tasks that may cause jank if all ran together
  9994. */
  9995. function requestNewFrame(cb) {
  9996. if (!clean || frames.length) {
  9997. frames.push(cb);
  9998. run();
  9999. } else {
  10000. clean = false;
  10001. cb();
  10002. run();
  10003. }
  10004. }
  10005. let raf = -1;
  10006. function run() {
  10007. cancelAnimationFrame(raf);
  10008. raf = requestAnimationFrame(() => {
  10009. const frame = frames.shift();
  10010. if (frame) frame();
  10011. if (frames.length) run();else clean = true;
  10012. });
  10013. }
  10014. // Utilities
  10015. // Types
  10016. const scrollStrategies = {
  10017. none: null,
  10018. close: closeScrollStrategy,
  10019. block: blockScrollStrategy,
  10020. reposition: repositionScrollStrategy
  10021. };
  10022. const makeScrollStrategyProps = propsFactory({
  10023. scrollStrategy: {
  10024. type: [String, Function],
  10025. default: 'block',
  10026. validator: val => typeof val === 'function' || val in scrollStrategies
  10027. }
  10028. }, 'VOverlay-scroll-strategies');
  10029. function useScrollStrategies(props, data) {
  10030. if (!IN_BROWSER) return;
  10031. let scope;
  10032. watchEffect(async () => {
  10033. scope?.stop();
  10034. if (!(data.isActive.value && props.scrollStrategy)) return;
  10035. scope = effectScope();
  10036. await new Promise(resolve => setTimeout(resolve));
  10037. scope.active && scope.run(() => {
  10038. if (typeof props.scrollStrategy === 'function') {
  10039. props.scrollStrategy(data, props, scope);
  10040. } else {
  10041. scrollStrategies[props.scrollStrategy]?.(data, props, scope);
  10042. }
  10043. });
  10044. });
  10045. onScopeDispose(() => {
  10046. scope?.stop();
  10047. });
  10048. }
  10049. function closeScrollStrategy(data) {
  10050. function onScroll(e) {
  10051. data.isActive.value = false;
  10052. }
  10053. bindScroll(data.targetEl.value ?? data.contentEl.value, onScroll);
  10054. }
  10055. function blockScrollStrategy(data, props) {
  10056. const offsetParent = data.root.value?.offsetParent;
  10057. const scrollElements = [...new Set([...getScrollParents(data.targetEl.value, props.contained ? offsetParent : undefined), ...getScrollParents(data.contentEl.value, props.contained ? offsetParent : undefined)])].filter(el => !el.classList.contains('v-overlay-scroll-blocked'));
  10058. const scrollbarWidth = window.innerWidth - document.documentElement.offsetWidth;
  10059. const scrollableParent = (el => hasScrollbar(el) && el)(offsetParent || document.documentElement);
  10060. if (scrollableParent) {
  10061. data.root.value.classList.add('v-overlay--scroll-blocked');
  10062. }
  10063. scrollElements.forEach((el, i) => {
  10064. el.style.setProperty('--v-body-scroll-x', convertToUnit(-el.scrollLeft));
  10065. el.style.setProperty('--v-body-scroll-y', convertToUnit(-el.scrollTop));
  10066. if (el !== document.documentElement) {
  10067. el.style.setProperty('--v-scrollbar-offset', convertToUnit(scrollbarWidth));
  10068. }
  10069. el.classList.add('v-overlay-scroll-blocked');
  10070. });
  10071. onScopeDispose(() => {
  10072. scrollElements.forEach((el, i) => {
  10073. const x = parseFloat(el.style.getPropertyValue('--v-body-scroll-x'));
  10074. const y = parseFloat(el.style.getPropertyValue('--v-body-scroll-y'));
  10075. const scrollBehavior = el.style.scrollBehavior;
  10076. el.style.scrollBehavior = 'auto';
  10077. el.style.removeProperty('--v-body-scroll-x');
  10078. el.style.removeProperty('--v-body-scroll-y');
  10079. el.style.removeProperty('--v-scrollbar-offset');
  10080. el.classList.remove('v-overlay-scroll-blocked');
  10081. el.scrollLeft = -x;
  10082. el.scrollTop = -y;
  10083. el.style.scrollBehavior = scrollBehavior;
  10084. });
  10085. if (scrollableParent) {
  10086. data.root.value.classList.remove('v-overlay--scroll-blocked');
  10087. }
  10088. });
  10089. }
  10090. function repositionScrollStrategy(data, props, scope) {
  10091. let slow = false;
  10092. let raf = -1;
  10093. let ric = -1;
  10094. function update(e) {
  10095. requestNewFrame(() => {
  10096. const start = performance.now();
  10097. data.updateLocation.value?.(e);
  10098. const time = performance.now() - start;
  10099. slow = time / (1000 / 60) > 2;
  10100. });
  10101. }
  10102. ric = (typeof requestIdleCallback === 'undefined' ? cb => cb() : requestIdleCallback)(() => {
  10103. scope.run(() => {
  10104. bindScroll(data.targetEl.value ?? data.contentEl.value, e => {
  10105. if (slow) {
  10106. // If the position calculation is slow,
  10107. // defer updates until scrolling is finished.
  10108. // Browsers usually fire one scroll event per frame so
  10109. // we just wait until we've got two frames without an event
  10110. cancelAnimationFrame(raf);
  10111. raf = requestAnimationFrame(() => {
  10112. raf = requestAnimationFrame(() => {
  10113. update(e);
  10114. });
  10115. });
  10116. } else {
  10117. update(e);
  10118. }
  10119. });
  10120. });
  10121. });
  10122. onScopeDispose(() => {
  10123. typeof cancelIdleCallback !== 'undefined' && cancelIdleCallback(ric);
  10124. cancelAnimationFrame(raf);
  10125. });
  10126. }
  10127. /** @private */
  10128. function bindScroll(el, onScroll) {
  10129. const scrollElements = [document, ...getScrollParents(el)];
  10130. scrollElements.forEach(el => {
  10131. el.addEventListener('scroll', onScroll, {
  10132. passive: true
  10133. });
  10134. });
  10135. onScopeDispose(() => {
  10136. scrollElements.forEach(el => {
  10137. el.removeEventListener('scroll', onScroll);
  10138. });
  10139. });
  10140. }
  10141. // Types
  10142. const VMenuSymbol = Symbol.for('vuetify:v-menu');
  10143. // Utilities
  10144. // Types
  10145. // Composables
  10146. const makeDelayProps = propsFactory({
  10147. closeDelay: [Number, String],
  10148. openDelay: [Number, String]
  10149. }, 'delay');
  10150. function useDelay(props, cb) {
  10151. let clearDelay = () => {};
  10152. function runDelay(isOpening) {
  10153. clearDelay?.();
  10154. const delay = Number(isOpening ? props.openDelay : props.closeDelay);
  10155. return new Promise(resolve => {
  10156. clearDelay = defer(delay, () => {
  10157. cb?.(isOpening);
  10158. resolve(isOpening);
  10159. });
  10160. });
  10161. }
  10162. function runOpenDelay() {
  10163. return runDelay(true);
  10164. }
  10165. function runCloseDelay() {
  10166. return runDelay(false);
  10167. }
  10168. return {
  10169. clearDelay,
  10170. runOpenDelay,
  10171. runCloseDelay
  10172. };
  10173. }
  10174. // Components
  10175. // Types
  10176. const makeActivatorProps = propsFactory({
  10177. target: [String, Object],
  10178. activator: [String, Object],
  10179. activatorProps: {
  10180. type: Object,
  10181. default: () => ({})
  10182. },
  10183. openOnClick: {
  10184. type: Boolean,
  10185. default: undefined
  10186. },
  10187. openOnHover: Boolean,
  10188. openOnFocus: {
  10189. type: Boolean,
  10190. default: undefined
  10191. },
  10192. closeOnContentClick: Boolean,
  10193. ...makeDelayProps()
  10194. }, 'VOverlay-activator');
  10195. function useActivator(props, _ref) {
  10196. let {
  10197. isActive,
  10198. isTop,
  10199. contentEl
  10200. } = _ref;
  10201. const vm = getCurrentInstance('useActivator');
  10202. const activatorEl = ref();
  10203. let isHovered = false;
  10204. let isFocused = false;
  10205. let firstEnter = true;
  10206. const openOnFocus = computed(() => props.openOnFocus || props.openOnFocus == null && props.openOnHover);
  10207. const openOnClick = computed(() => props.openOnClick || props.openOnClick == null && !props.openOnHover && !openOnFocus.value);
  10208. const {
  10209. runOpenDelay,
  10210. runCloseDelay
  10211. } = useDelay(props, value => {
  10212. if (value === (props.openOnHover && isHovered || openOnFocus.value && isFocused) && !(props.openOnHover && isActive.value && !isTop.value)) {
  10213. if (isActive.value !== value) {
  10214. firstEnter = true;
  10215. }
  10216. isActive.value = value;
  10217. }
  10218. });
  10219. const cursorTarget = ref();
  10220. const availableEvents = {
  10221. onClick: e => {
  10222. e.stopPropagation();
  10223. activatorEl.value = e.currentTarget || e.target;
  10224. if (!isActive.value) {
  10225. cursorTarget.value = [e.clientX, e.clientY];
  10226. }
  10227. isActive.value = !isActive.value;
  10228. },
  10229. onMouseenter: e => {
  10230. if (e.sourceCapabilities?.firesTouchEvents) return;
  10231. isHovered = true;
  10232. activatorEl.value = e.currentTarget || e.target;
  10233. runOpenDelay();
  10234. },
  10235. onMouseleave: e => {
  10236. isHovered = false;
  10237. runCloseDelay();
  10238. },
  10239. onFocus: e => {
  10240. if (matchesSelector(e.target, ':focus-visible') === false) return;
  10241. isFocused = true;
  10242. e.stopPropagation();
  10243. activatorEl.value = e.currentTarget || e.target;
  10244. runOpenDelay();
  10245. },
  10246. onBlur: e => {
  10247. isFocused = false;
  10248. e.stopPropagation();
  10249. runCloseDelay();
  10250. }
  10251. };
  10252. const activatorEvents = computed(() => {
  10253. const events = {};
  10254. if (openOnClick.value) {
  10255. events.onClick = availableEvents.onClick;
  10256. }
  10257. if (props.openOnHover) {
  10258. events.onMouseenter = availableEvents.onMouseenter;
  10259. events.onMouseleave = availableEvents.onMouseleave;
  10260. }
  10261. if (openOnFocus.value) {
  10262. events.onFocus = availableEvents.onFocus;
  10263. events.onBlur = availableEvents.onBlur;
  10264. }
  10265. return events;
  10266. });
  10267. const contentEvents = computed(() => {
  10268. const events = {};
  10269. if (props.openOnHover) {
  10270. events.onMouseenter = () => {
  10271. isHovered = true;
  10272. runOpenDelay();
  10273. };
  10274. events.onMouseleave = () => {
  10275. isHovered = false;
  10276. runCloseDelay();
  10277. };
  10278. }
  10279. if (openOnFocus.value) {
  10280. events.onFocusin = () => {
  10281. isFocused = true;
  10282. runOpenDelay();
  10283. };
  10284. events.onFocusout = () => {
  10285. isFocused = false;
  10286. runCloseDelay();
  10287. };
  10288. }
  10289. if (props.closeOnContentClick) {
  10290. const menu = inject$1(VMenuSymbol, null);
  10291. events.onClick = () => {
  10292. isActive.value = false;
  10293. menu?.closeParents();
  10294. };
  10295. }
  10296. return events;
  10297. });
  10298. const scrimEvents = computed(() => {
  10299. const events = {};
  10300. if (props.openOnHover) {
  10301. events.onMouseenter = () => {
  10302. if (firstEnter) {
  10303. isHovered = true;
  10304. firstEnter = false;
  10305. runOpenDelay();
  10306. }
  10307. };
  10308. events.onMouseleave = () => {
  10309. isHovered = false;
  10310. runCloseDelay();
  10311. };
  10312. }
  10313. return events;
  10314. });
  10315. watch(isTop, val => {
  10316. if (val && (props.openOnHover && !isHovered && (!openOnFocus.value || !isFocused) || openOnFocus.value && !isFocused && (!props.openOnHover || !isHovered)) && !contentEl.value?.contains(document.activeElement)) {
  10317. isActive.value = false;
  10318. }
  10319. });
  10320. watch(isActive, val => {
  10321. if (!val) {
  10322. setTimeout(() => {
  10323. cursorTarget.value = undefined;
  10324. });
  10325. }
  10326. }, {
  10327. flush: 'post'
  10328. });
  10329. const activatorRef = templateRef();
  10330. watchEffect(() => {
  10331. if (!activatorRef.value) return;
  10332. nextTick(() => {
  10333. activatorEl.value = activatorRef.el;
  10334. });
  10335. });
  10336. const targetRef = templateRef();
  10337. const target = computed(() => {
  10338. if (props.target === 'cursor' && cursorTarget.value) return cursorTarget.value;
  10339. if (targetRef.value) return targetRef.el;
  10340. return getTarget(props.target, vm) || activatorEl.value;
  10341. });
  10342. const targetEl = computed(() => {
  10343. return Array.isArray(target.value) ? undefined : target.value;
  10344. });
  10345. let scope;
  10346. watch(() => !!props.activator, val => {
  10347. if (val && IN_BROWSER) {
  10348. scope = effectScope();
  10349. scope.run(() => {
  10350. _useActivator(props, vm, {
  10351. activatorEl,
  10352. activatorEvents
  10353. });
  10354. });
  10355. } else if (scope) {
  10356. scope.stop();
  10357. }
  10358. }, {
  10359. flush: 'post',
  10360. immediate: true
  10361. });
  10362. onScopeDispose(() => {
  10363. scope?.stop();
  10364. });
  10365. return {
  10366. activatorEl,
  10367. activatorRef,
  10368. target,
  10369. targetEl,
  10370. targetRef,
  10371. activatorEvents,
  10372. contentEvents,
  10373. scrimEvents
  10374. };
  10375. }
  10376. function _useActivator(props, vm, _ref2) {
  10377. let {
  10378. activatorEl,
  10379. activatorEvents
  10380. } = _ref2;
  10381. watch(() => props.activator, (val, oldVal) => {
  10382. if (oldVal && val !== oldVal) {
  10383. const activator = getActivator(oldVal);
  10384. activator && unbindActivatorProps(activator);
  10385. }
  10386. if (val) {
  10387. nextTick(() => bindActivatorProps());
  10388. }
  10389. }, {
  10390. immediate: true
  10391. });
  10392. watch(() => props.activatorProps, () => {
  10393. bindActivatorProps();
  10394. });
  10395. onScopeDispose(() => {
  10396. unbindActivatorProps();
  10397. });
  10398. function bindActivatorProps() {
  10399. let el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getActivator();
  10400. let _props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.activatorProps;
  10401. if (!el) return;
  10402. bindProps(el, mergeProps(activatorEvents.value, _props));
  10403. }
  10404. function unbindActivatorProps() {
  10405. let el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getActivator();
  10406. let _props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.activatorProps;
  10407. if (!el) return;
  10408. unbindProps(el, mergeProps(activatorEvents.value, _props));
  10409. }
  10410. function getActivator() {
  10411. let selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : props.activator;
  10412. const activator = getTarget(selector, vm);
  10413. // The activator should only be a valid element (Ignore comments and text nodes)
  10414. activatorEl.value = activator?.nodeType === Node.ELEMENT_NODE ? activator : undefined;
  10415. return activatorEl.value;
  10416. }
  10417. }
  10418. function getTarget(selector, vm) {
  10419. if (!selector) return;
  10420. let target;
  10421. if (selector === 'parent') {
  10422. let el = vm?.proxy?.$el?.parentNode;
  10423. while (el?.hasAttribute('data-no-activator')) {
  10424. el = el.parentNode;
  10425. }
  10426. target = el;
  10427. } else if (typeof selector === 'string') {
  10428. // Selector
  10429. target = document.querySelector(selector);
  10430. } else if ('$el' in selector) {
  10431. // Component (ref)
  10432. target = selector.$el;
  10433. } else {
  10434. // HTMLElement | Element | [x, y]
  10435. target = selector;
  10436. }
  10437. return target;
  10438. }
  10439. // Composables
  10440. function useHydration() {
  10441. if (!IN_BROWSER) return shallowRef(false);
  10442. const {
  10443. ssr
  10444. } = useDisplay();
  10445. if (ssr) {
  10446. const isMounted = shallowRef(false);
  10447. onMounted(() => {
  10448. isMounted.value = true;
  10449. });
  10450. return isMounted;
  10451. } else {
  10452. return shallowRef(true);
  10453. }
  10454. }
  10455. // Utilities
  10456. // Types
  10457. const makeLazyProps = propsFactory({
  10458. eager: Boolean
  10459. }, 'lazy');
  10460. function useLazy(props, active) {
  10461. const isBooted = shallowRef(false);
  10462. const hasContent = computed(() => isBooted.value || props.eager || active.value);
  10463. watch(active, () => isBooted.value = true);
  10464. function onAfterLeave() {
  10465. if (!props.eager) isBooted.value = false;
  10466. }
  10467. return {
  10468. isBooted,
  10469. hasContent,
  10470. onAfterLeave
  10471. };
  10472. }
  10473. // Utilities
  10474. function useScopeId() {
  10475. const vm = getCurrentInstance('useScopeId');
  10476. const scopeId = vm.vnode.scopeId;
  10477. return {
  10478. scopeId: scopeId ? {
  10479. [scopeId]: ''
  10480. } : undefined
  10481. };
  10482. }
  10483. // Composables
  10484. // Types
  10485. const StackSymbol = Symbol.for('vuetify:stack');
  10486. const globalStack = reactive([]);
  10487. function useStack(isActive, zIndex, disableGlobalStack) {
  10488. const vm = getCurrentInstance('useStack');
  10489. const createStackEntry = !disableGlobalStack;
  10490. const parent = inject$1(StackSymbol, undefined);
  10491. const stack = reactive({
  10492. activeChildren: new Set()
  10493. });
  10494. provide(StackSymbol, stack);
  10495. const _zIndex = shallowRef(+zIndex.value);
  10496. useToggleScope(isActive, () => {
  10497. const lastZIndex = globalStack.at(-1)?.[1];
  10498. _zIndex.value = lastZIndex ? lastZIndex + 10 : +zIndex.value;
  10499. if (createStackEntry) {
  10500. globalStack.push([vm.uid, _zIndex.value]);
  10501. }
  10502. parent?.activeChildren.add(vm.uid);
  10503. onScopeDispose(() => {
  10504. if (createStackEntry) {
  10505. const idx = toRaw(globalStack).findIndex(v => v[0] === vm.uid);
  10506. globalStack.splice(idx, 1);
  10507. }
  10508. parent?.activeChildren.delete(vm.uid);
  10509. });
  10510. });
  10511. const globalTop = shallowRef(true);
  10512. if (createStackEntry) {
  10513. watchEffect(() => {
  10514. const _isTop = globalStack.at(-1)?.[0] === vm.uid;
  10515. setTimeout(() => globalTop.value = _isTop);
  10516. });
  10517. }
  10518. const localTop = computed(() => !stack.activeChildren.size);
  10519. return {
  10520. globalTop: readonly(globalTop),
  10521. localTop,
  10522. stackStyles: computed(() => ({
  10523. zIndex: _zIndex.value
  10524. }))
  10525. };
  10526. }
  10527. // Utilities
  10528. function useTeleport(target) {
  10529. const teleportTarget = computed(() => {
  10530. const _target = target();
  10531. if (_target === true || !IN_BROWSER) return undefined;
  10532. const targetElement = _target === false ? document.body : typeof _target === 'string' ? document.querySelector(_target) : _target;
  10533. if (targetElement == null) {
  10534. warn(`Unable to locate target ${_target}`);
  10535. return undefined;
  10536. }
  10537. let container = [...targetElement.children].find(el => el.matches('.v-overlay-container'));
  10538. if (!container) {
  10539. container = document.createElement('div');
  10540. container.className = 'v-overlay-container';
  10541. targetElement.appendChild(container);
  10542. }
  10543. return container;
  10544. });
  10545. return {
  10546. teleportTarget
  10547. };
  10548. }
  10549. // Utilities
  10550. // Types
  10551. function defaultConditional() {
  10552. return true;
  10553. }
  10554. function checkEvent(e, el, binding) {
  10555. // The include element callbacks below can be expensive
  10556. // so we should avoid calling them when we're not active.
  10557. // Explicitly check for false to allow fallback compatibility
  10558. // with non-toggleable components
  10559. if (!e || checkIsActive(e, binding) === false) return false;
  10560. // If we're clicking inside the shadowroot, then the app root doesn't get the same
  10561. // level of introspection as to _what_ we're clicking. We want to check to see if
  10562. // our target is the shadowroot parent container, and if it is, ignore.
  10563. const root = attachedRoot(el);
  10564. if (typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot && root.host === e.target) return false;
  10565. // Check if additional elements were passed to be included in check
  10566. // (click must be outside all included elements, if any)
  10567. const elements = (typeof binding.value === 'object' && binding.value.include || (() => []))();
  10568. // Add the root element for the component this directive was defined on
  10569. elements.push(el);
  10570. // Check if it's a click outside our elements, and then if our callback returns true.
  10571. // Non-toggleable components should take action in their callback and return falsy.
  10572. // Toggleable can return true if it wants to deactivate.
  10573. // Note that, because we're in the capture phase, this callback will occur before
  10574. // the bubbling click event on any outside elements.
  10575. return !elements.some(el => el?.contains(e.target));
  10576. }
  10577. function checkIsActive(e, binding) {
  10578. const isActive = typeof binding.value === 'object' && binding.value.closeConditional || defaultConditional;
  10579. return isActive(e);
  10580. }
  10581. function directive(e, el, binding) {
  10582. const handler = typeof binding.value === 'function' ? binding.value : binding.value.handler;
  10583. // Clicks in the Shadow DOM change their target while using setTimeout, so the original target is saved here
  10584. e.shadowTarget = e.target;
  10585. el._clickOutside.lastMousedownWasOutside && checkEvent(e, el, binding) && setTimeout(() => {
  10586. checkIsActive(e, binding) && handler && handler(e);
  10587. }, 0);
  10588. }
  10589. function handleShadow(el, callback) {
  10590. const root = attachedRoot(el);
  10591. callback(document);
  10592. if (typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot) {
  10593. callback(root);
  10594. }
  10595. }
  10596. const ClickOutside = {
  10597. // [data-app] may not be found
  10598. // if using bind, inserted makes
  10599. // sure that the root element is
  10600. // available, iOS does not support
  10601. // clicks on body
  10602. mounted(el, binding) {
  10603. const onClick = e => directive(e, el, binding);
  10604. const onMousedown = e => {
  10605. el._clickOutside.lastMousedownWasOutside = checkEvent(e, el, binding);
  10606. };
  10607. handleShadow(el, app => {
  10608. app.addEventListener('click', onClick, true);
  10609. app.addEventListener('mousedown', onMousedown, true);
  10610. });
  10611. if (!el._clickOutside) {
  10612. el._clickOutside = {
  10613. lastMousedownWasOutside: false
  10614. };
  10615. }
  10616. el._clickOutside[binding.instance.$.uid] = {
  10617. onClick,
  10618. onMousedown
  10619. };
  10620. },
  10621. beforeUnmount(el, binding) {
  10622. if (!el._clickOutside) return;
  10623. handleShadow(el, app => {
  10624. if (!app || !el._clickOutside?.[binding.instance.$.uid]) return;
  10625. const {
  10626. onClick,
  10627. onMousedown
  10628. } = el._clickOutside[binding.instance.$.uid];
  10629. app.removeEventListener('click', onClick, true);
  10630. app.removeEventListener('mousedown', onMousedown, true);
  10631. });
  10632. delete el._clickOutside[binding.instance.$.uid];
  10633. }
  10634. };
  10635. // Types
  10636. function Scrim(props) {
  10637. const {
  10638. modelValue,
  10639. color,
  10640. ...rest
  10641. } = props;
  10642. return createVNode(Transition, {
  10643. "name": "fade-transition",
  10644. "appear": true
  10645. }, {
  10646. default: () => [props.modelValue && createVNode("div", mergeProps({
  10647. "class": ['v-overlay__scrim', props.color.backgroundColorClasses.value],
  10648. "style": props.color.backgroundColorStyles.value
  10649. }, rest), null)]
  10650. });
  10651. }
  10652. const makeVOverlayProps = propsFactory({
  10653. absolute: Boolean,
  10654. attach: [Boolean, String, Object],
  10655. closeOnBack: {
  10656. type: Boolean,
  10657. default: true
  10658. },
  10659. contained: Boolean,
  10660. contentClass: null,
  10661. contentProps: null,
  10662. disabled: Boolean,
  10663. opacity: [Number, String],
  10664. noClickAnimation: Boolean,
  10665. modelValue: Boolean,
  10666. persistent: Boolean,
  10667. scrim: {
  10668. type: [Boolean, String],
  10669. default: true
  10670. },
  10671. zIndex: {
  10672. type: [Number, String],
  10673. default: 2000
  10674. },
  10675. ...makeActivatorProps(),
  10676. ...makeComponentProps(),
  10677. ...makeDimensionProps(),
  10678. ...makeLazyProps(),
  10679. ...makeLocationStrategyProps(),
  10680. ...makeScrollStrategyProps(),
  10681. ...makeThemeProps(),
  10682. ...makeTransitionProps()
  10683. }, 'VOverlay');
  10684. const VOverlay = genericComponent()({
  10685. name: 'VOverlay',
  10686. directives: {
  10687. ClickOutside
  10688. },
  10689. inheritAttrs: false,
  10690. props: {
  10691. _disableGlobalStack: Boolean,
  10692. ...makeVOverlayProps()
  10693. },
  10694. emits: {
  10695. 'click:outside': e => true,
  10696. 'update:modelValue': value => true,
  10697. afterEnter: () => true,
  10698. afterLeave: () => true
  10699. },
  10700. setup(props, _ref) {
  10701. let {
  10702. slots,
  10703. attrs,
  10704. emit
  10705. } = _ref;
  10706. const vm = getCurrentInstance('VOverlay');
  10707. const root = ref();
  10708. const scrimEl = ref();
  10709. const contentEl = ref();
  10710. const model = useProxiedModel(props, 'modelValue');
  10711. const isActive = computed({
  10712. get: () => model.value,
  10713. set: v => {
  10714. if (!(v && props.disabled)) model.value = v;
  10715. }
  10716. });
  10717. const {
  10718. themeClasses
  10719. } = provideTheme(props);
  10720. const {
  10721. rtlClasses,
  10722. isRtl
  10723. } = useRtl();
  10724. const {
  10725. hasContent,
  10726. onAfterLeave: _onAfterLeave
  10727. } = useLazy(props, isActive);
  10728. const scrimColor = useBackgroundColor(computed(() => {
  10729. return typeof props.scrim === 'string' ? props.scrim : null;
  10730. }));
  10731. const {
  10732. globalTop,
  10733. localTop,
  10734. stackStyles
  10735. } = useStack(isActive, toRef(props, 'zIndex'), props._disableGlobalStack);
  10736. const {
  10737. activatorEl,
  10738. activatorRef,
  10739. target,
  10740. targetEl,
  10741. targetRef,
  10742. activatorEvents,
  10743. contentEvents,
  10744. scrimEvents
  10745. } = useActivator(props, {
  10746. isActive,
  10747. isTop: localTop,
  10748. contentEl
  10749. });
  10750. const {
  10751. teleportTarget
  10752. } = useTeleport(() => {
  10753. const target = props.attach || props.contained;
  10754. if (target) return target;
  10755. const rootNode = activatorEl?.value?.getRootNode() || vm.proxy?.$el?.getRootNode();
  10756. if (rootNode instanceof ShadowRoot) return rootNode;
  10757. return false;
  10758. });
  10759. const {
  10760. dimensionStyles
  10761. } = useDimension(props);
  10762. const isMounted = useHydration();
  10763. const {
  10764. scopeId
  10765. } = useScopeId();
  10766. watch(() => props.disabled, v => {
  10767. if (v) isActive.value = false;
  10768. });
  10769. const {
  10770. contentStyles,
  10771. updateLocation
  10772. } = useLocationStrategies(props, {
  10773. isRtl,
  10774. contentEl,
  10775. target,
  10776. isActive
  10777. });
  10778. useScrollStrategies(props, {
  10779. root,
  10780. contentEl,
  10781. targetEl,
  10782. isActive,
  10783. updateLocation
  10784. });
  10785. function onClickOutside(e) {
  10786. emit('click:outside', e);
  10787. if (!props.persistent) isActive.value = false;else animateClick();
  10788. }
  10789. function closeConditional(e) {
  10790. return isActive.value && globalTop.value && (
  10791. // If using scrim, only close if clicking on it rather than anything opened on top
  10792. !props.scrim || e.target === scrimEl.value || e instanceof MouseEvent && e.shadowTarget === scrimEl.value);
  10793. }
  10794. IN_BROWSER && watch(isActive, val => {
  10795. if (val) {
  10796. window.addEventListener('keydown', onKeydown);
  10797. } else {
  10798. window.removeEventListener('keydown', onKeydown);
  10799. }
  10800. }, {
  10801. immediate: true
  10802. });
  10803. onBeforeUnmount(() => {
  10804. if (!IN_BROWSER) return;
  10805. window.removeEventListener('keydown', onKeydown);
  10806. });
  10807. function onKeydown(e) {
  10808. if (e.key === 'Escape' && globalTop.value) {
  10809. if (!props.persistent) {
  10810. isActive.value = false;
  10811. if (contentEl.value?.contains(document.activeElement)) {
  10812. activatorEl.value?.focus();
  10813. }
  10814. } else animateClick();
  10815. }
  10816. }
  10817. const router = useRouter();
  10818. useToggleScope(() => props.closeOnBack, () => {
  10819. useBackButton(router, next => {
  10820. if (globalTop.value && isActive.value) {
  10821. next(false);
  10822. if (!props.persistent) isActive.value = false;else animateClick();
  10823. } else {
  10824. next();
  10825. }
  10826. });
  10827. });
  10828. const top = ref();
  10829. watch(() => isActive.value && (props.absolute || props.contained) && teleportTarget.value == null, val => {
  10830. if (val) {
  10831. const scrollParent = getScrollParent(root.value);
  10832. if (scrollParent && scrollParent !== document.scrollingElement) {
  10833. top.value = scrollParent.scrollTop;
  10834. }
  10835. }
  10836. });
  10837. // Add a quick "bounce" animation to the content
  10838. function animateClick() {
  10839. if (props.noClickAnimation) return;
  10840. contentEl.value && animate(contentEl.value, [{
  10841. transformOrigin: 'center'
  10842. }, {
  10843. transform: 'scale(1.03)'
  10844. }, {
  10845. transformOrigin: 'center'
  10846. }], {
  10847. duration: 150,
  10848. easing: standardEasing
  10849. });
  10850. }
  10851. function onAfterEnter() {
  10852. emit('afterEnter');
  10853. }
  10854. function onAfterLeave() {
  10855. _onAfterLeave();
  10856. emit('afterLeave');
  10857. }
  10858. useRender(() => createVNode(Fragment, null, [slots.activator?.({
  10859. isActive: isActive.value,
  10860. targetRef,
  10861. props: mergeProps({
  10862. ref: activatorRef
  10863. }, activatorEvents.value, props.activatorProps)
  10864. }), isMounted.value && hasContent.value && createVNode(Teleport, {
  10865. "disabled": !teleportTarget.value,
  10866. "to": teleportTarget.value
  10867. }, {
  10868. default: () => [createVNode("div", mergeProps({
  10869. "class": ['v-overlay', {
  10870. 'v-overlay--absolute': props.absolute || props.contained,
  10871. 'v-overlay--active': isActive.value,
  10872. 'v-overlay--contained': props.contained
  10873. }, themeClasses.value, rtlClasses.value, props.class],
  10874. "style": [stackStyles.value, {
  10875. '--v-overlay-opacity': props.opacity,
  10876. top: convertToUnit(top.value)
  10877. }, props.style],
  10878. "ref": root
  10879. }, scopeId, attrs), [createVNode(Scrim, mergeProps({
  10880. "color": scrimColor,
  10881. "modelValue": isActive.value && !!props.scrim,
  10882. "ref": scrimEl
  10883. }, scrimEvents.value), null), createVNode(MaybeTransition, {
  10884. "appear": true,
  10885. "persisted": true,
  10886. "transition": props.transition,
  10887. "target": target.value,
  10888. "onAfterEnter": onAfterEnter,
  10889. "onAfterLeave": onAfterLeave
  10890. }, {
  10891. default: () => [withDirectives(createVNode("div", mergeProps({
  10892. "ref": contentEl,
  10893. "class": ['v-overlay__content', props.contentClass],
  10894. "style": [dimensionStyles.value, contentStyles.value]
  10895. }, contentEvents.value, props.contentProps), [slots.default?.({
  10896. isActive
  10897. })]), [[vShow, isActive.value], [resolveDirective("click-outside"), {
  10898. handler: onClickOutside,
  10899. closeConditional,
  10900. include: () => [activatorEl.value]
  10901. }]])]
  10902. })])]
  10903. })]));
  10904. return {
  10905. activatorEl,
  10906. scrimEl,
  10907. target,
  10908. animateClick,
  10909. contentEl,
  10910. globalTop,
  10911. localTop,
  10912. updateLocation
  10913. };
  10914. }
  10915. });
  10916. // Types
  10917. const Refs = Symbol('Forwarded refs');
  10918. /** Omit properties starting with P */
  10919. /** Omit keyof $props from T */
  10920. function getDescriptor(obj, key) {
  10921. let currentObj = obj;
  10922. while (currentObj) {
  10923. const descriptor = Reflect.getOwnPropertyDescriptor(currentObj, key);
  10924. if (descriptor) return descriptor;
  10925. currentObj = Object.getPrototypeOf(currentObj);
  10926. }
  10927. return undefined;
  10928. }
  10929. function forwardRefs(target) {
  10930. for (var _len = arguments.length, refs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  10931. refs[_key - 1] = arguments[_key];
  10932. }
  10933. target[Refs] = refs;
  10934. return new Proxy(target, {
  10935. get(target, key) {
  10936. if (Reflect.has(target, key)) {
  10937. return Reflect.get(target, key);
  10938. }
  10939. // Skip internal properties
  10940. if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return;
  10941. for (const ref of refs) {
  10942. if (ref.value && Reflect.has(ref.value, key)) {
  10943. const val = Reflect.get(ref.value, key);
  10944. return typeof val === 'function' ? val.bind(ref.value) : val;
  10945. }
  10946. }
  10947. },
  10948. has(target, key) {
  10949. if (Reflect.has(target, key)) {
  10950. return true;
  10951. }
  10952. // Skip internal properties
  10953. if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return false;
  10954. for (const ref of refs) {
  10955. if (ref.value && Reflect.has(ref.value, key)) {
  10956. return true;
  10957. }
  10958. }
  10959. return false;
  10960. },
  10961. set(target, key, value) {
  10962. if (Reflect.has(target, key)) {
  10963. return Reflect.set(target, key, value);
  10964. }
  10965. // Skip internal properties
  10966. if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return false;
  10967. for (const ref of refs) {
  10968. if (ref.value && Reflect.has(ref.value, key)) {
  10969. return Reflect.set(ref.value, key, value);
  10970. }
  10971. }
  10972. return false;
  10973. },
  10974. getOwnPropertyDescriptor(target, key) {
  10975. const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
  10976. if (descriptor) return descriptor;
  10977. // Skip internal properties
  10978. if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return;
  10979. // Check each ref's own properties
  10980. for (const ref of refs) {
  10981. if (!ref.value) continue;
  10982. const descriptor = getDescriptor(ref.value, key) ?? ('_' in ref.value ? getDescriptor(ref.value._?.setupState, key) : undefined);
  10983. if (descriptor) return descriptor;
  10984. }
  10985. // Recursive search up each ref's prototype
  10986. for (const ref of refs) {
  10987. const childRefs = ref.value && ref.value[Refs];
  10988. if (!childRefs) continue;
  10989. const queue = childRefs.slice();
  10990. while (queue.length) {
  10991. const ref = queue.shift();
  10992. const descriptor = getDescriptor(ref.value, key);
  10993. if (descriptor) return descriptor;
  10994. const childRefs = ref.value && ref.value[Refs];
  10995. if (childRefs) queue.push(...childRefs);
  10996. }
  10997. }
  10998. return undefined;
  10999. }
  11000. });
  11001. }
  11002. // Types
  11003. const makeVMenuProps = propsFactory({
  11004. // TODO
  11005. // disableKeys: Boolean,
  11006. id: String,
  11007. submenu: Boolean,
  11008. ...omit(makeVOverlayProps({
  11009. closeDelay: 250,
  11010. closeOnContentClick: true,
  11011. locationStrategy: 'connected',
  11012. location: undefined,
  11013. openDelay: 300,
  11014. scrim: false,
  11015. scrollStrategy: 'reposition',
  11016. transition: {
  11017. component: VDialogTransition
  11018. }
  11019. }), ['absolute'])
  11020. }, 'VMenu');
  11021. const VMenu = genericComponent()({
  11022. name: 'VMenu',
  11023. props: makeVMenuProps(),
  11024. emits: {
  11025. 'update:modelValue': value => true
  11026. },
  11027. setup(props, _ref) {
  11028. let {
  11029. slots
  11030. } = _ref;
  11031. const isActive = useProxiedModel(props, 'modelValue');
  11032. const {
  11033. scopeId
  11034. } = useScopeId();
  11035. const {
  11036. isRtl
  11037. } = useRtl();
  11038. const uid = getUid();
  11039. const id = computed(() => props.id || `v-menu-${uid}`);
  11040. const overlay = ref();
  11041. const parent = inject$1(VMenuSymbol, null);
  11042. const openChildren = shallowRef(new Set());
  11043. provide(VMenuSymbol, {
  11044. register() {
  11045. openChildren.value.add(uid);
  11046. },
  11047. unregister() {
  11048. openChildren.value.delete(uid);
  11049. },
  11050. closeParents(e) {
  11051. setTimeout(() => {
  11052. if (!openChildren.value.size && !props.persistent && (e == null || overlay.value?.contentEl && !isClickInsideElement(e, overlay.value.contentEl))) {
  11053. isActive.value = false;
  11054. parent?.closeParents();
  11055. }
  11056. }, 40);
  11057. }
  11058. });
  11059. onBeforeUnmount(() => {
  11060. parent?.unregister();
  11061. document.removeEventListener('focusin', onFocusIn);
  11062. });
  11063. onDeactivated(() => isActive.value = false);
  11064. async function onFocusIn(e) {
  11065. const before = e.relatedTarget;
  11066. const after = e.target;
  11067. await nextTick();
  11068. if (isActive.value && before !== after && overlay.value?.contentEl &&
  11069. // We're the topmost menu
  11070. overlay.value?.globalTop &&
  11071. // It isn't the document or the menu body
  11072. ![document, overlay.value.contentEl].includes(after) &&
  11073. // It isn't inside the menu body
  11074. !overlay.value.contentEl.contains(after)) {
  11075. const focusable = focusableChildren(overlay.value.contentEl);
  11076. focusable[0]?.focus();
  11077. }
  11078. }
  11079. watch(isActive, val => {
  11080. if (val) {
  11081. parent?.register();
  11082. if (IN_BROWSER) {
  11083. document.addEventListener('focusin', onFocusIn, {
  11084. once: true
  11085. });
  11086. }
  11087. } else {
  11088. parent?.unregister();
  11089. if (IN_BROWSER) {
  11090. document.removeEventListener('focusin', onFocusIn);
  11091. }
  11092. }
  11093. }, {
  11094. immediate: true
  11095. });
  11096. function onClickOutside(e) {
  11097. parent?.closeParents(e);
  11098. }
  11099. function onKeydown(e) {
  11100. if (props.disabled) return;
  11101. if (e.key === 'Tab' || e.key === 'Enter' && !props.closeOnContentClick) {
  11102. if (e.key === 'Enter' && (e.target instanceof HTMLTextAreaElement || e.target instanceof HTMLInputElement && !!e.target.closest('form'))) return;
  11103. if (e.key === 'Enter') e.preventDefault();
  11104. const nextElement = getNextElement(focusableChildren(overlay.value?.contentEl, false), e.shiftKey ? 'prev' : 'next', el => el.tabIndex >= 0);
  11105. if (!nextElement) {
  11106. isActive.value = false;
  11107. overlay.value?.activatorEl?.focus();
  11108. }
  11109. } else if (props.submenu && e.key === (isRtl.value ? 'ArrowRight' : 'ArrowLeft')) {
  11110. isActive.value = false;
  11111. overlay.value?.activatorEl?.focus();
  11112. }
  11113. }
  11114. function onActivatorKeydown(e) {
  11115. if (props.disabled) return;
  11116. const el = overlay.value?.contentEl;
  11117. if (el && isActive.value) {
  11118. if (e.key === 'ArrowDown') {
  11119. e.preventDefault();
  11120. e.stopImmediatePropagation();
  11121. focusChild(el, 'next');
  11122. } else if (e.key === 'ArrowUp') {
  11123. e.preventDefault();
  11124. e.stopImmediatePropagation();
  11125. focusChild(el, 'prev');
  11126. } else if (props.submenu) {
  11127. if (e.key === (isRtl.value ? 'ArrowRight' : 'ArrowLeft')) {
  11128. isActive.value = false;
  11129. } else if (e.key === (isRtl.value ? 'ArrowLeft' : 'ArrowRight')) {
  11130. e.preventDefault();
  11131. focusChild(el, 'first');
  11132. }
  11133. }
  11134. } else if (props.submenu ? e.key === (isRtl.value ? 'ArrowLeft' : 'ArrowRight') : ['ArrowDown', 'ArrowUp'].includes(e.key)) {
  11135. isActive.value = true;
  11136. e.preventDefault();
  11137. setTimeout(() => setTimeout(() => onActivatorKeydown(e)));
  11138. }
  11139. }
  11140. const activatorProps = computed(() => mergeProps({
  11141. 'aria-haspopup': 'menu',
  11142. 'aria-expanded': String(isActive.value),
  11143. 'aria-owns': id.value,
  11144. onKeydown: onActivatorKeydown
  11145. }, props.activatorProps));
  11146. useRender(() => {
  11147. const overlayProps = VOverlay.filterProps(props);
  11148. return createVNode(VOverlay, mergeProps({
  11149. "ref": overlay,
  11150. "id": id.value,
  11151. "class": ['v-menu', props.class],
  11152. "style": props.style
  11153. }, overlayProps, {
  11154. "modelValue": isActive.value,
  11155. "onUpdate:modelValue": $event => isActive.value = $event,
  11156. "absolute": true,
  11157. "activatorProps": activatorProps.value,
  11158. "location": props.location ?? (props.submenu ? 'end' : 'bottom'),
  11159. "onClick:outside": onClickOutside,
  11160. "onKeydown": onKeydown
  11161. }, scopeId), {
  11162. activator: slots.activator,
  11163. default: function () {
  11164. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  11165. args[_key] = arguments[_key];
  11166. }
  11167. return createVNode(VDefaultsProvider, {
  11168. "root": "VMenu"
  11169. }, {
  11170. default: () => [slots.default?.(...args)]
  11171. });
  11172. }
  11173. });
  11174. });
  11175. return forwardRefs({
  11176. id,
  11177. ΨopenChildren: openChildren
  11178. }, overlay);
  11179. }
  11180. });
  11181. // Types
  11182. const makeVCounterProps = propsFactory({
  11183. active: Boolean,
  11184. disabled: Boolean,
  11185. max: [Number, String],
  11186. value: {
  11187. type: [Number, String],
  11188. default: 0
  11189. },
  11190. ...makeComponentProps(),
  11191. ...makeTransitionProps({
  11192. transition: {
  11193. component: VSlideYTransition
  11194. }
  11195. })
  11196. }, 'VCounter');
  11197. const VCounter = genericComponent()({
  11198. name: 'VCounter',
  11199. functional: true,
  11200. props: makeVCounterProps(),
  11201. setup(props, _ref) {
  11202. let {
  11203. slots
  11204. } = _ref;
  11205. const counter = computed(() => {
  11206. return props.max ? `${props.value} / ${props.max}` : String(props.value);
  11207. });
  11208. useRender(() => createVNode(MaybeTransition, {
  11209. "transition": props.transition
  11210. }, {
  11211. default: () => [withDirectives(createVNode("div", {
  11212. "class": ['v-counter', {
  11213. 'text-error': props.max && !props.disabled && parseFloat(props.value) > parseFloat(props.max)
  11214. }, props.class],
  11215. "style": props.style
  11216. }, [slots.default ? slots.default({
  11217. counter: counter.value,
  11218. max: props.max,
  11219. value: props.value
  11220. }) : counter.value]), [[vShow, props.active]])]
  11221. }));
  11222. return {};
  11223. }
  11224. });
  11225. const makeVFieldLabelProps = propsFactory({
  11226. floating: Boolean,
  11227. ...makeComponentProps()
  11228. }, 'VFieldLabel');
  11229. const VFieldLabel = genericComponent()({
  11230. name: 'VFieldLabel',
  11231. props: makeVFieldLabelProps(),
  11232. setup(props, _ref) {
  11233. let {
  11234. slots
  11235. } = _ref;
  11236. useRender(() => createVNode(VLabel, {
  11237. "class": ['v-field-label', {
  11238. 'v-field-label--floating': props.floating
  11239. }, props.class],
  11240. "style": props.style,
  11241. "aria-hidden": props.floating || undefined
  11242. }, slots));
  11243. return {};
  11244. }
  11245. });
  11246. // Types
  11247. const allowedVariants$1 = ['underlined', 'outlined', 'filled', 'solo', 'solo-inverted', 'solo-filled', 'plain'];
  11248. const makeVFieldProps = propsFactory({
  11249. appendInnerIcon: IconValue,
  11250. bgColor: String,
  11251. clearable: Boolean,
  11252. clearIcon: {
  11253. type: IconValue,
  11254. default: '$clear'
  11255. },
  11256. active: Boolean,
  11257. centerAffix: {
  11258. type: Boolean,
  11259. default: undefined
  11260. },
  11261. color: String,
  11262. baseColor: String,
  11263. dirty: Boolean,
  11264. disabled: {
  11265. type: Boolean,
  11266. default: null
  11267. },
  11268. error: Boolean,
  11269. flat: Boolean,
  11270. label: String,
  11271. persistentClear: Boolean,
  11272. prependInnerIcon: IconValue,
  11273. reverse: Boolean,
  11274. singleLine: Boolean,
  11275. variant: {
  11276. type: String,
  11277. default: 'filled',
  11278. validator: v => allowedVariants$1.includes(v)
  11279. },
  11280. 'onClick:clear': EventProp(),
  11281. 'onClick:appendInner': EventProp(),
  11282. 'onClick:prependInner': EventProp(),
  11283. ...makeComponentProps(),
  11284. ...makeLoaderProps(),
  11285. ...makeRoundedProps(),
  11286. ...makeThemeProps()
  11287. }, 'VField');
  11288. const VField = genericComponent()({
  11289. name: 'VField',
  11290. inheritAttrs: false,
  11291. props: {
  11292. id: String,
  11293. ...makeFocusProps(),
  11294. ...makeVFieldProps()
  11295. },
  11296. emits: {
  11297. 'update:focused': focused => true,
  11298. 'update:modelValue': value => true
  11299. },
  11300. setup(props, _ref) {
  11301. let {
  11302. attrs,
  11303. emit,
  11304. slots
  11305. } = _ref;
  11306. const {
  11307. themeClasses
  11308. } = provideTheme(props);
  11309. const {
  11310. loaderClasses
  11311. } = useLoader(props);
  11312. const {
  11313. focusClasses,
  11314. isFocused,
  11315. focus,
  11316. blur
  11317. } = useFocus(props);
  11318. const {
  11319. InputIcon
  11320. } = useInputIcon(props);
  11321. const {
  11322. roundedClasses
  11323. } = useRounded(props);
  11324. const {
  11325. rtlClasses
  11326. } = useRtl();
  11327. const isActive = computed(() => props.dirty || props.active);
  11328. const hasLabel = computed(() => !props.singleLine && !!(props.label || slots.label));
  11329. const uid = getUid();
  11330. const id = computed(() => props.id || `input-${uid}`);
  11331. const messagesId = computed(() => `${id.value}-messages`);
  11332. const labelRef = ref();
  11333. const floatingLabelRef = ref();
  11334. const controlRef = ref();
  11335. const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant));
  11336. const {
  11337. backgroundColorClasses,
  11338. backgroundColorStyles
  11339. } = useBackgroundColor(toRef(props, 'bgColor'));
  11340. const {
  11341. textColorClasses,
  11342. textColorStyles
  11343. } = useTextColor(computed(() => {
  11344. return props.error || props.disabled ? undefined : isActive.value && isFocused.value ? props.color : props.baseColor;
  11345. }));
  11346. watch(isActive, val => {
  11347. if (hasLabel.value) {
  11348. const el = labelRef.value.$el;
  11349. const targetEl = floatingLabelRef.value.$el;
  11350. requestAnimationFrame(() => {
  11351. const rect = nullifyTransforms(el);
  11352. const targetRect = targetEl.getBoundingClientRect();
  11353. const x = targetRect.x - rect.x;
  11354. const y = targetRect.y - rect.y - (rect.height / 2 - targetRect.height / 2);
  11355. const targetWidth = targetRect.width / 0.75;
  11356. const width = Math.abs(targetWidth - rect.width) > 1 ? {
  11357. maxWidth: convertToUnit(targetWidth)
  11358. } : undefined;
  11359. const style = getComputedStyle(el);
  11360. const targetStyle = getComputedStyle(targetEl);
  11361. const duration = parseFloat(style.transitionDuration) * 1000 || 150;
  11362. const scale = parseFloat(targetStyle.getPropertyValue('--v-field-label-scale'));
  11363. const color = targetStyle.getPropertyValue('color');
  11364. el.style.visibility = 'visible';
  11365. targetEl.style.visibility = 'hidden';
  11366. animate(el, {
  11367. transform: `translate(${x}px, ${y}px) scale(${scale})`,
  11368. color,
  11369. ...width
  11370. }, {
  11371. duration,
  11372. easing: standardEasing,
  11373. direction: val ? 'normal' : 'reverse'
  11374. }).finished.then(() => {
  11375. el.style.removeProperty('visibility');
  11376. targetEl.style.removeProperty('visibility');
  11377. });
  11378. });
  11379. }
  11380. }, {
  11381. flush: 'post'
  11382. });
  11383. const slotProps = computed(() => ({
  11384. isActive,
  11385. isFocused,
  11386. controlRef,
  11387. blur,
  11388. focus
  11389. }));
  11390. function onClick(e) {
  11391. if (e.target !== document.activeElement) {
  11392. e.preventDefault();
  11393. }
  11394. }
  11395. function onKeydownClear(e) {
  11396. if (e.key !== 'Enter' && e.key !== ' ') return;
  11397. e.preventDefault();
  11398. e.stopPropagation();
  11399. props['onClick:clear']?.(new MouseEvent('click'));
  11400. }
  11401. useRender(() => {
  11402. const isOutlined = props.variant === 'outlined';
  11403. const hasPrepend = !!(slots['prepend-inner'] || props.prependInnerIcon);
  11404. const hasClear = !!(props.clearable || slots.clear);
  11405. const hasAppend = !!(slots['append-inner'] || props.appendInnerIcon || hasClear);
  11406. const label = () => slots.label ? slots.label({
  11407. ...slotProps.value,
  11408. label: props.label,
  11409. props: {
  11410. for: id.value
  11411. }
  11412. }) : props.label;
  11413. return createVNode("div", mergeProps({
  11414. "class": ['v-field', {
  11415. 'v-field--active': isActive.value,
  11416. 'v-field--appended': hasAppend,
  11417. 'v-field--center-affix': props.centerAffix ?? !isPlainOrUnderlined.value,
  11418. 'v-field--disabled': props.disabled,
  11419. 'v-field--dirty': props.dirty,
  11420. 'v-field--error': props.error,
  11421. 'v-field--flat': props.flat,
  11422. 'v-field--has-background': !!props.bgColor,
  11423. 'v-field--persistent-clear': props.persistentClear,
  11424. 'v-field--prepended': hasPrepend,
  11425. 'v-field--reverse': props.reverse,
  11426. 'v-field--single-line': props.singleLine,
  11427. 'v-field--no-label': !label(),
  11428. [`v-field--variant-${props.variant}`]: true
  11429. }, themeClasses.value, backgroundColorClasses.value, focusClasses.value, loaderClasses.value, roundedClasses.value, rtlClasses.value, props.class],
  11430. "style": [backgroundColorStyles.value, props.style],
  11431. "onClick": onClick
  11432. }, attrs), [createVNode("div", {
  11433. "class": "v-field__overlay"
  11434. }, null), createVNode(LoaderSlot, {
  11435. "name": "v-field",
  11436. "active": !!props.loading,
  11437. "color": props.error ? 'error' : typeof props.loading === 'string' ? props.loading : props.color
  11438. }, {
  11439. default: slots.loader
  11440. }), hasPrepend && createVNode("div", {
  11441. "key": "prepend",
  11442. "class": "v-field__prepend-inner"
  11443. }, [props.prependInnerIcon && createVNode(InputIcon, {
  11444. "key": "prepend-icon",
  11445. "name": "prependInner"
  11446. }, null), slots['prepend-inner']?.(slotProps.value)]), createVNode("div", {
  11447. "class": "v-field__field",
  11448. "data-no-activator": ""
  11449. }, [['filled', 'solo', 'solo-inverted', 'solo-filled'].includes(props.variant) && hasLabel.value && createVNode(VFieldLabel, {
  11450. "key": "floating-label",
  11451. "ref": floatingLabelRef,
  11452. "class": [textColorClasses.value],
  11453. "floating": true,
  11454. "for": id.value,
  11455. "style": textColorStyles.value
  11456. }, {
  11457. default: () => [label()]
  11458. }), hasLabel.value && createVNode(VFieldLabel, {
  11459. "key": "label",
  11460. "ref": labelRef,
  11461. "for": id.value
  11462. }, {
  11463. default: () => [label()]
  11464. }), slots.default?.({
  11465. ...slotProps.value,
  11466. props: {
  11467. id: id.value,
  11468. class: 'v-field__input',
  11469. 'aria-describedby': messagesId.value
  11470. },
  11471. focus,
  11472. blur
  11473. })]), hasClear && createVNode(VExpandXTransition, {
  11474. "key": "clear"
  11475. }, {
  11476. default: () => [withDirectives(createVNode("div", {
  11477. "class": "v-field__clearable",
  11478. "onMousedown": e => {
  11479. e.preventDefault();
  11480. e.stopPropagation();
  11481. }
  11482. }, [createVNode(VDefaultsProvider, {
  11483. "defaults": {
  11484. VIcon: {
  11485. icon: props.clearIcon
  11486. }
  11487. }
  11488. }, {
  11489. default: () => [slots.clear ? slots.clear({
  11490. ...slotProps.value,
  11491. props: {
  11492. onKeydown: onKeydownClear,
  11493. onFocus: focus,
  11494. onBlur: blur,
  11495. onClick: props['onClick:clear']
  11496. }
  11497. }) : createVNode(InputIcon, {
  11498. "name": "clear",
  11499. "onKeydown": onKeydownClear,
  11500. "onFocus": focus,
  11501. "onBlur": blur
  11502. }, null)]
  11503. })]), [[vShow, props.dirty]])]
  11504. }), hasAppend && createVNode("div", {
  11505. "key": "append",
  11506. "class": "v-field__append-inner"
  11507. }, [slots['append-inner']?.(slotProps.value), props.appendInnerIcon && createVNode(InputIcon, {
  11508. "key": "append-icon",
  11509. "name": "appendInner"
  11510. }, null)]), createVNode("div", {
  11511. "class": ['v-field__outline', textColorClasses.value],
  11512. "style": textColorStyles.value
  11513. }, [isOutlined && createVNode(Fragment, null, [createVNode("div", {
  11514. "class": "v-field__outline__start"
  11515. }, null), hasLabel.value && createVNode("div", {
  11516. "class": "v-field__outline__notch"
  11517. }, [createVNode(VFieldLabel, {
  11518. "ref": floatingLabelRef,
  11519. "floating": true,
  11520. "for": id.value
  11521. }, {
  11522. default: () => [label()]
  11523. })]), createVNode("div", {
  11524. "class": "v-field__outline__end"
  11525. }, null)]), isPlainOrUnderlined.value && hasLabel.value && createVNode(VFieldLabel, {
  11526. "ref": floatingLabelRef,
  11527. "floating": true,
  11528. "for": id.value
  11529. }, {
  11530. default: () => [label()]
  11531. })])]);
  11532. });
  11533. return {
  11534. controlRef
  11535. };
  11536. }
  11537. });
  11538. // TODO: this is kinda slow, might be better to implicitly inherit props instead
  11539. function filterFieldProps(attrs) {
  11540. const keys = Object.keys(VField.props).filter(k => !isOn(k) && k !== 'class' && k !== 'style');
  11541. return pick(attrs, keys);
  11542. }
  11543. // Types
  11544. const activeTypes = ['color', 'file', 'time', 'date', 'datetime-local', 'week', 'month'];
  11545. const makeVTextFieldProps = propsFactory({
  11546. autofocus: Boolean,
  11547. counter: [Boolean, Number, String],
  11548. counterValue: [Number, Function],
  11549. prefix: String,
  11550. placeholder: String,
  11551. persistentPlaceholder: Boolean,
  11552. persistentCounter: Boolean,
  11553. suffix: String,
  11554. role: String,
  11555. type: {
  11556. type: String,
  11557. default: 'text'
  11558. },
  11559. modelModifiers: Object,
  11560. ...makeVInputProps(),
  11561. ...makeVFieldProps()
  11562. }, 'VTextField');
  11563. const VTextField = genericComponent()({
  11564. name: 'VTextField',
  11565. directives: {
  11566. Intersect
  11567. },
  11568. inheritAttrs: false,
  11569. props: makeVTextFieldProps(),
  11570. emits: {
  11571. 'click:control': e => true,
  11572. 'mousedown:control': e => true,
  11573. 'update:focused': focused => true,
  11574. 'update:modelValue': val => true
  11575. },
  11576. setup(props, _ref) {
  11577. let {
  11578. attrs,
  11579. emit,
  11580. slots
  11581. } = _ref;
  11582. const model = useProxiedModel(props, 'modelValue');
  11583. const {
  11584. isFocused,
  11585. focus,
  11586. blur
  11587. } = useFocus(props);
  11588. const counterValue = computed(() => {
  11589. return typeof props.counterValue === 'function' ? props.counterValue(model.value) : typeof props.counterValue === 'number' ? props.counterValue : (model.value ?? '').toString().length;
  11590. });
  11591. const max = computed(() => {
  11592. if (attrs.maxlength) return attrs.maxlength;
  11593. if (!props.counter || typeof props.counter !== 'number' && typeof props.counter !== 'string') return undefined;
  11594. return props.counter;
  11595. });
  11596. const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant));
  11597. function onIntersect(isIntersecting, entries) {
  11598. if (!props.autofocus || !isIntersecting) return;
  11599. entries[0].target?.focus?.();
  11600. }
  11601. const vInputRef = ref();
  11602. const vFieldRef = ref();
  11603. const inputRef = ref();
  11604. const isActive = computed(() => activeTypes.includes(props.type) || props.persistentPlaceholder || isFocused.value || props.active);
  11605. function onFocus() {
  11606. if (inputRef.value !== document.activeElement) {
  11607. inputRef.value?.focus();
  11608. }
  11609. if (!isFocused.value) focus();
  11610. }
  11611. function onControlMousedown(e) {
  11612. emit('mousedown:control', e);
  11613. if (e.target === inputRef.value) return;
  11614. onFocus();
  11615. e.preventDefault();
  11616. }
  11617. function onControlClick(e) {
  11618. onFocus();
  11619. emit('click:control', e);
  11620. }
  11621. function onClear(e) {
  11622. e.stopPropagation();
  11623. onFocus();
  11624. nextTick(() => {
  11625. model.value = null;
  11626. callEvent(props['onClick:clear'], e);
  11627. });
  11628. }
  11629. function onInput(e) {
  11630. const el = e.target;
  11631. model.value = el.value;
  11632. if (props.modelModifiers?.trim && ['text', 'search', 'password', 'tel', 'url'].includes(props.type)) {
  11633. const caretPosition = [el.selectionStart, el.selectionEnd];
  11634. nextTick(() => {
  11635. el.selectionStart = caretPosition[0];
  11636. el.selectionEnd = caretPosition[1];
  11637. });
  11638. }
  11639. }
  11640. useRender(() => {
  11641. const hasCounter = !!(slots.counter || props.counter !== false && props.counter != null);
  11642. const hasDetails = !!(hasCounter || slots.details);
  11643. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  11644. const {
  11645. modelValue: _,
  11646. ...inputProps
  11647. } = VInput.filterProps(props);
  11648. const fieldProps = filterFieldProps(props);
  11649. return createVNode(VInput, mergeProps({
  11650. "ref": vInputRef,
  11651. "modelValue": model.value,
  11652. "onUpdate:modelValue": $event => model.value = $event,
  11653. "class": ['v-text-field', {
  11654. 'v-text-field--prefixed': props.prefix,
  11655. 'v-text-field--suffixed': props.suffix,
  11656. 'v-input--plain-underlined': isPlainOrUnderlined.value
  11657. }, props.class],
  11658. "style": props.style
  11659. }, rootAttrs, inputProps, {
  11660. "centerAffix": !isPlainOrUnderlined.value,
  11661. "focused": isFocused.value
  11662. }), {
  11663. ...slots,
  11664. default: _ref2 => {
  11665. let {
  11666. id,
  11667. isDisabled,
  11668. isDirty,
  11669. isReadonly,
  11670. isValid
  11671. } = _ref2;
  11672. return createVNode(VField, mergeProps({
  11673. "ref": vFieldRef,
  11674. "onMousedown": onControlMousedown,
  11675. "onClick": onControlClick,
  11676. "onClick:clear": onClear,
  11677. "onClick:prependInner": props['onClick:prependInner'],
  11678. "onClick:appendInner": props['onClick:appendInner'],
  11679. "role": props.role
  11680. }, fieldProps, {
  11681. "id": id.value,
  11682. "active": isActive.value || isDirty.value,
  11683. "dirty": isDirty.value || props.dirty,
  11684. "disabled": isDisabled.value,
  11685. "focused": isFocused.value,
  11686. "error": isValid.value === false
  11687. }), {
  11688. ...slots,
  11689. default: _ref3 => {
  11690. let {
  11691. props: {
  11692. class: fieldClass,
  11693. ...slotProps
  11694. }
  11695. } = _ref3;
  11696. const inputNode = withDirectives(createVNode("input", mergeProps({
  11697. "ref": inputRef,
  11698. "value": model.value,
  11699. "onInput": onInput,
  11700. "autofocus": props.autofocus,
  11701. "readonly": isReadonly.value,
  11702. "disabled": isDisabled.value,
  11703. "name": props.name,
  11704. "placeholder": props.placeholder,
  11705. "size": 1,
  11706. "type": props.type,
  11707. "onFocus": onFocus,
  11708. "onBlur": blur
  11709. }, slotProps, inputAttrs), null), [[resolveDirective("intersect"), {
  11710. handler: onIntersect
  11711. }, null, {
  11712. once: true
  11713. }]]);
  11714. return createVNode(Fragment, null, [props.prefix && createVNode("span", {
  11715. "class": "v-text-field__prefix"
  11716. }, [createVNode("span", {
  11717. "class": "v-text-field__prefix__text"
  11718. }, [props.prefix])]), slots.default ? createVNode("div", {
  11719. "class": fieldClass,
  11720. "data-no-activator": ""
  11721. }, [slots.default(), inputNode]) : cloneVNode(inputNode, {
  11722. class: fieldClass
  11723. }), props.suffix && createVNode("span", {
  11724. "class": "v-text-field__suffix"
  11725. }, [createVNode("span", {
  11726. "class": "v-text-field__suffix__text"
  11727. }, [props.suffix])])]);
  11728. }
  11729. });
  11730. },
  11731. details: hasDetails ? slotProps => createVNode(Fragment, null, [slots.details?.(slotProps), hasCounter && createVNode(Fragment, null, [createVNode("span", null, null), createVNode(VCounter, {
  11732. "active": props.persistentCounter || isFocused.value,
  11733. "value": counterValue.value,
  11734. "max": max.value,
  11735. "disabled": props.disabled
  11736. }, slots.counter)])]) : undefined
  11737. });
  11738. });
  11739. return forwardRefs({}, vInputRef, vFieldRef, inputRef);
  11740. }
  11741. });
  11742. // Types
  11743. const makeVVirtualScrollItemProps = propsFactory({
  11744. renderless: Boolean,
  11745. ...makeComponentProps()
  11746. }, 'VVirtualScrollItem');
  11747. const VVirtualScrollItem = genericComponent()({
  11748. name: 'VVirtualScrollItem',
  11749. inheritAttrs: false,
  11750. props: makeVVirtualScrollItemProps(),
  11751. emits: {
  11752. 'update:height': height => true
  11753. },
  11754. setup(props, _ref) {
  11755. let {
  11756. attrs,
  11757. emit,
  11758. slots
  11759. } = _ref;
  11760. const {
  11761. resizeRef,
  11762. contentRect
  11763. } = useResizeObserver(undefined, 'border');
  11764. watch(() => contentRect.value?.height, height => {
  11765. if (height != null) emit('update:height', height);
  11766. });
  11767. useRender(() => props.renderless ? createVNode(Fragment, null, [slots.default?.({
  11768. itemRef: resizeRef
  11769. })]) : createVNode("div", mergeProps({
  11770. "ref": resizeRef,
  11771. "class": ['v-virtual-scroll__item', props.class],
  11772. "style": props.style
  11773. }, attrs), [slots.default?.()]));
  11774. }
  11775. });
  11776. // Composables
  11777. // Types
  11778. const UP = -1;
  11779. const DOWN = 1;
  11780. /** Determines how large each batch of items should be */
  11781. const BUFFER_PX = 100;
  11782. const makeVirtualProps = propsFactory({
  11783. itemHeight: {
  11784. type: [Number, String],
  11785. default: null
  11786. },
  11787. height: [Number, String]
  11788. }, 'virtual');
  11789. function useVirtual(props, items) {
  11790. const display = useDisplay();
  11791. const itemHeight = shallowRef(0);
  11792. watchEffect(() => {
  11793. itemHeight.value = parseFloat(props.itemHeight || 0);
  11794. });
  11795. const first = shallowRef(0);
  11796. const last = shallowRef(Math.ceil(
  11797. // Assume 16px items filling the entire screen height if
  11798. // not provided. This is probably incorrect but it minimises
  11799. // the chance of ending up with empty space at the bottom.
  11800. // The default value is set here to avoid poisoning getSize()
  11801. (parseInt(props.height) || display.height.value) / (itemHeight.value || 16)) || 1);
  11802. const paddingTop = shallowRef(0);
  11803. const paddingBottom = shallowRef(0);
  11804. /** The scrollable element */
  11805. const containerRef = ref();
  11806. /** An element marking the top of the scrollable area,
  11807. * used to add an offset if there's padding or other elements above the virtual list */
  11808. const markerRef = ref();
  11809. /** markerRef's offsetTop, lazily evaluated */
  11810. let markerOffset = 0;
  11811. const {
  11812. resizeRef,
  11813. contentRect
  11814. } = useResizeObserver();
  11815. watchEffect(() => {
  11816. resizeRef.value = containerRef.value;
  11817. });
  11818. const viewportHeight = computed(() => {
  11819. return containerRef.value === document.documentElement ? display.height.value : contentRect.value?.height || parseInt(props.height) || 0;
  11820. });
  11821. /** All static elements have been rendered and we have an assumed item height */
  11822. const hasInitialRender = computed(() => {
  11823. return !!(containerRef.value && markerRef.value && viewportHeight.value && itemHeight.value);
  11824. });
  11825. let sizes = Array.from({
  11826. length: items.value.length
  11827. });
  11828. let offsets = Array.from({
  11829. length: items.value.length
  11830. });
  11831. const updateTime = shallowRef(0);
  11832. let targetScrollIndex = -1;
  11833. function getSize(index) {
  11834. return sizes[index] || itemHeight.value;
  11835. }
  11836. const updateOffsets = debounce(() => {
  11837. const start = performance.now();
  11838. offsets[0] = 0;
  11839. const length = items.value.length;
  11840. for (let i = 1; i <= length - 1; i++) {
  11841. offsets[i] = (offsets[i - 1] || 0) + getSize(i - 1);
  11842. }
  11843. updateTime.value = Math.max(updateTime.value, performance.now() - start);
  11844. }, updateTime);
  11845. const unwatch = watch(hasInitialRender, v => {
  11846. if (!v) return;
  11847. // First render is complete, update offsets and visible
  11848. // items in case our assumed item height was incorrect
  11849. unwatch();
  11850. markerOffset = markerRef.value.offsetTop;
  11851. updateOffsets.immediate();
  11852. calculateVisibleItems();
  11853. if (!~targetScrollIndex) return;
  11854. nextTick(() => {
  11855. IN_BROWSER && window.requestAnimationFrame(() => {
  11856. scrollToIndex(targetScrollIndex);
  11857. targetScrollIndex = -1;
  11858. });
  11859. });
  11860. });
  11861. onScopeDispose(() => {
  11862. updateOffsets.clear();
  11863. });
  11864. function handleItemResize(index, height) {
  11865. const prevHeight = sizes[index];
  11866. const prevMinHeight = itemHeight.value;
  11867. itemHeight.value = prevMinHeight ? Math.min(itemHeight.value, height) : height;
  11868. if (prevHeight !== height || prevMinHeight !== itemHeight.value) {
  11869. sizes[index] = height;
  11870. updateOffsets();
  11871. }
  11872. }
  11873. function calculateOffset(index) {
  11874. index = clamp(index, 0, items.value.length - 1);
  11875. return offsets[index] || 0;
  11876. }
  11877. function calculateIndex(scrollTop) {
  11878. return binaryClosest(offsets, scrollTop);
  11879. }
  11880. let lastScrollTop = 0;
  11881. let scrollVelocity = 0;
  11882. let lastScrollTime = 0;
  11883. watch(viewportHeight, (val, oldVal) => {
  11884. if (oldVal) {
  11885. calculateVisibleItems();
  11886. if (val < oldVal) {
  11887. requestAnimationFrame(() => {
  11888. scrollVelocity = 0;
  11889. calculateVisibleItems();
  11890. });
  11891. }
  11892. }
  11893. });
  11894. let scrollTimeout = -1;
  11895. function handleScroll() {
  11896. if (!containerRef.value || !markerRef.value) return;
  11897. const scrollTop = containerRef.value.scrollTop;
  11898. const scrollTime = performance.now();
  11899. const scrollDeltaT = scrollTime - lastScrollTime;
  11900. if (scrollDeltaT > 500) {
  11901. scrollVelocity = Math.sign(scrollTop - lastScrollTop);
  11902. // Not super important, only update at the
  11903. // start of a scroll sequence to avoid reflows
  11904. markerOffset = markerRef.value.offsetTop;
  11905. } else {
  11906. scrollVelocity = scrollTop - lastScrollTop;
  11907. }
  11908. lastScrollTop = scrollTop;
  11909. lastScrollTime = scrollTime;
  11910. window.clearTimeout(scrollTimeout);
  11911. scrollTimeout = window.setTimeout(handleScrollend, 500);
  11912. calculateVisibleItems();
  11913. }
  11914. function handleScrollend() {
  11915. if (!containerRef.value || !markerRef.value) return;
  11916. scrollVelocity = 0;
  11917. lastScrollTime = 0;
  11918. window.clearTimeout(scrollTimeout);
  11919. calculateVisibleItems();
  11920. }
  11921. let raf = -1;
  11922. function calculateVisibleItems() {
  11923. cancelAnimationFrame(raf);
  11924. raf = requestAnimationFrame(_calculateVisibleItems);
  11925. }
  11926. function _calculateVisibleItems() {
  11927. if (!containerRef.value || !viewportHeight.value) return;
  11928. const scrollTop = lastScrollTop - markerOffset;
  11929. const direction = Math.sign(scrollVelocity);
  11930. const startPx = Math.max(0, scrollTop - BUFFER_PX);
  11931. const start = clamp(calculateIndex(startPx), 0, items.value.length);
  11932. const endPx = scrollTop + viewportHeight.value + BUFFER_PX;
  11933. const end = clamp(calculateIndex(endPx) + 1, start + 1, items.value.length);
  11934. if (
  11935. // Only update the side we're scrolling towards,
  11936. // the other side will be updated incidentally
  11937. (direction !== UP || start < first.value) && (direction !== DOWN || end > last.value)) {
  11938. const topOverflow = calculateOffset(first.value) - calculateOffset(start);
  11939. const bottomOverflow = calculateOffset(end) - calculateOffset(last.value);
  11940. const bufferOverflow = Math.max(topOverflow, bottomOverflow);
  11941. if (bufferOverflow > BUFFER_PX) {
  11942. first.value = start;
  11943. last.value = end;
  11944. } else {
  11945. // Only update the side that's reached its limit if there's still buffer left
  11946. if (start <= 0) first.value = start;
  11947. if (end >= items.value.length) last.value = end;
  11948. }
  11949. }
  11950. paddingTop.value = calculateOffset(first.value);
  11951. paddingBottom.value = calculateOffset(items.value.length) - calculateOffset(last.value);
  11952. }
  11953. function scrollToIndex(index) {
  11954. const offset = calculateOffset(index);
  11955. if (!containerRef.value || index && !offset) {
  11956. targetScrollIndex = index;
  11957. } else {
  11958. containerRef.value.scrollTop = offset;
  11959. }
  11960. }
  11961. const computedItems = computed(() => {
  11962. return items.value.slice(first.value, last.value).map((item, index) => ({
  11963. raw: item,
  11964. index: index + first.value,
  11965. key: isObject(item) && 'value' in item ? item.value : index + first.value
  11966. }));
  11967. });
  11968. watch(items, () => {
  11969. sizes = Array.from({
  11970. length: items.value.length
  11971. });
  11972. offsets = Array.from({
  11973. length: items.value.length
  11974. });
  11975. updateOffsets.immediate();
  11976. calculateVisibleItems();
  11977. }, {
  11978. deep: true
  11979. });
  11980. return {
  11981. calculateVisibleItems,
  11982. containerRef,
  11983. markerRef,
  11984. computedItems,
  11985. paddingTop,
  11986. paddingBottom,
  11987. scrollToIndex,
  11988. handleScroll,
  11989. handleScrollend,
  11990. handleItemResize
  11991. };
  11992. }
  11993. // https://gist.github.com/robertleeplummerjr/1cc657191d34ecd0a324
  11994. function binaryClosest(arr, val) {
  11995. let high = arr.length - 1;
  11996. let low = 0;
  11997. let mid = 0;
  11998. let item = null;
  11999. let target = -1;
  12000. if (arr[high] < val) {
  12001. return high;
  12002. }
  12003. while (low <= high) {
  12004. mid = low + high >> 1;
  12005. item = arr[mid];
  12006. if (item > val) {
  12007. high = mid - 1;
  12008. } else if (item < val) {
  12009. target = mid;
  12010. low = mid + 1;
  12011. } else if (item === val) {
  12012. return mid;
  12013. } else {
  12014. return low;
  12015. }
  12016. }
  12017. return target;
  12018. }
  12019. // Types
  12020. const makeVVirtualScrollProps = propsFactory({
  12021. items: {
  12022. type: Array,
  12023. default: () => []
  12024. },
  12025. renderless: Boolean,
  12026. ...makeVirtualProps(),
  12027. ...makeComponentProps(),
  12028. ...makeDimensionProps()
  12029. }, 'VVirtualScroll');
  12030. const VVirtualScroll = genericComponent()({
  12031. name: 'VVirtualScroll',
  12032. props: makeVVirtualScrollProps(),
  12033. setup(props, _ref) {
  12034. let {
  12035. slots
  12036. } = _ref;
  12037. const vm = getCurrentInstance('VVirtualScroll');
  12038. const {
  12039. dimensionStyles
  12040. } = useDimension(props);
  12041. const {
  12042. calculateVisibleItems,
  12043. containerRef,
  12044. markerRef,
  12045. handleScroll,
  12046. handleScrollend,
  12047. handleItemResize,
  12048. scrollToIndex,
  12049. paddingTop,
  12050. paddingBottom,
  12051. computedItems
  12052. } = useVirtual(props, toRef(props, 'items'));
  12053. useToggleScope(() => props.renderless, () => {
  12054. function handleListeners() {
  12055. let add = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
  12056. const method = add ? 'addEventListener' : 'removeEventListener';
  12057. if (containerRef.value === document.documentElement) {
  12058. document[method]('scroll', handleScroll, {
  12059. passive: true
  12060. });
  12061. document[method]('scrollend', handleScrollend);
  12062. } else {
  12063. containerRef.value?.[method]('scroll', handleScroll, {
  12064. passive: true
  12065. });
  12066. containerRef.value?.[method]('scrollend', handleScrollend);
  12067. }
  12068. }
  12069. onMounted(() => {
  12070. containerRef.value = getScrollParent(vm.vnode.el, true);
  12071. handleListeners(true);
  12072. });
  12073. onScopeDispose(handleListeners);
  12074. });
  12075. useRender(() => {
  12076. const children = computedItems.value.map(item => createVNode(VVirtualScrollItem, {
  12077. "key": item.key,
  12078. "renderless": props.renderless,
  12079. "onUpdate:height": height => handleItemResize(item.index, height)
  12080. }, {
  12081. default: slotProps => slots.default?.({
  12082. item: item.raw,
  12083. index: item.index,
  12084. ...slotProps
  12085. })
  12086. }));
  12087. return props.renderless ? createVNode(Fragment, null, [createVNode("div", {
  12088. "ref": markerRef,
  12089. "class": "v-virtual-scroll__spacer",
  12090. "style": {
  12091. paddingTop: convertToUnit(paddingTop.value)
  12092. }
  12093. }, null), children, createVNode("div", {
  12094. "class": "v-virtual-scroll__spacer",
  12095. "style": {
  12096. paddingBottom: convertToUnit(paddingBottom.value)
  12097. }
  12098. }, null)]) : createVNode("div", {
  12099. "ref": containerRef,
  12100. "class": ['v-virtual-scroll', props.class],
  12101. "onScrollPassive": handleScroll,
  12102. "onScrollend": handleScrollend,
  12103. "style": [dimensionStyles.value, props.style]
  12104. }, [createVNode("div", {
  12105. "ref": markerRef,
  12106. "class": "v-virtual-scroll__container",
  12107. "style": {
  12108. paddingTop: convertToUnit(paddingTop.value),
  12109. paddingBottom: convertToUnit(paddingBottom.value)
  12110. }
  12111. }, [children])]);
  12112. });
  12113. return {
  12114. calculateVisibleItems,
  12115. scrollToIndex
  12116. };
  12117. }
  12118. });
  12119. // Utilities
  12120. // Types
  12121. function useScrolling(listRef, textFieldRef) {
  12122. const isScrolling = shallowRef(false);
  12123. let scrollTimeout;
  12124. function onListScroll(e) {
  12125. cancelAnimationFrame(scrollTimeout);
  12126. isScrolling.value = true;
  12127. scrollTimeout = requestAnimationFrame(() => {
  12128. scrollTimeout = requestAnimationFrame(() => {
  12129. isScrolling.value = false;
  12130. });
  12131. });
  12132. }
  12133. async function finishScrolling() {
  12134. await new Promise(resolve => requestAnimationFrame(resolve));
  12135. await new Promise(resolve => requestAnimationFrame(resolve));
  12136. await new Promise(resolve => requestAnimationFrame(resolve));
  12137. await new Promise(resolve => {
  12138. if (isScrolling.value) {
  12139. const stop = watch(isScrolling, () => {
  12140. stop();
  12141. resolve();
  12142. });
  12143. } else resolve();
  12144. });
  12145. }
  12146. async function onListKeydown(e) {
  12147. if (e.key === 'Tab') {
  12148. textFieldRef.value?.focus();
  12149. }
  12150. if (!['PageDown', 'PageUp', 'Home', 'End'].includes(e.key)) return;
  12151. const el = listRef.value?.$el;
  12152. if (!el) return;
  12153. if (e.key === 'Home' || e.key === 'End') {
  12154. el.scrollTo({
  12155. top: e.key === 'Home' ? 0 : el.scrollHeight,
  12156. behavior: 'smooth'
  12157. });
  12158. }
  12159. await finishScrolling();
  12160. const children = el.querySelectorAll(':scope > :not(.v-virtual-scroll__spacer)');
  12161. if (e.key === 'PageDown' || e.key === 'Home') {
  12162. const top = el.getBoundingClientRect().top;
  12163. for (const child of children) {
  12164. if (child.getBoundingClientRect().top >= top) {
  12165. child.focus();
  12166. break;
  12167. }
  12168. }
  12169. } else {
  12170. const bottom = el.getBoundingClientRect().bottom;
  12171. for (const child of [...children].reverse()) {
  12172. if (child.getBoundingClientRect().bottom <= bottom) {
  12173. child.focus();
  12174. break;
  12175. }
  12176. }
  12177. }
  12178. }
  12179. return {
  12180. onScrollPassive: onListScroll,
  12181. onKeydown: onListKeydown
  12182. }; // typescript doesn't know about vue's event merging
  12183. }
  12184. // Types
  12185. const makeSelectProps = propsFactory({
  12186. chips: Boolean,
  12187. closableChips: Boolean,
  12188. closeText: {
  12189. type: String,
  12190. default: '$vuetify.close'
  12191. },
  12192. openText: {
  12193. type: String,
  12194. default: '$vuetify.open'
  12195. },
  12196. eager: Boolean,
  12197. hideNoData: Boolean,
  12198. hideSelected: Boolean,
  12199. listProps: {
  12200. type: Object
  12201. },
  12202. menu: Boolean,
  12203. menuIcon: {
  12204. type: IconValue,
  12205. default: '$dropdown'
  12206. },
  12207. menuProps: {
  12208. type: Object
  12209. },
  12210. multiple: Boolean,
  12211. noDataText: {
  12212. type: String,
  12213. default: '$vuetify.noDataText'
  12214. },
  12215. openOnClear: Boolean,
  12216. itemColor: String,
  12217. ...makeItemsProps({
  12218. itemChildren: false
  12219. })
  12220. }, 'Select');
  12221. const makeVSelectProps = propsFactory({
  12222. ...makeSelectProps(),
  12223. ...omit(makeVTextFieldProps({
  12224. modelValue: null,
  12225. role: 'combobox'
  12226. }), ['validationValue', 'dirty', 'appendInnerIcon']),
  12227. ...makeTransitionProps({
  12228. transition: {
  12229. component: VDialogTransition
  12230. }
  12231. })
  12232. }, 'VSelect');
  12233. const VSelect = genericComponent()({
  12234. name: 'VSelect',
  12235. props: makeVSelectProps(),
  12236. emits: {
  12237. 'update:focused': focused => true,
  12238. 'update:modelValue': value => true,
  12239. 'update:menu': ue => true
  12240. },
  12241. setup(props, _ref) {
  12242. let {
  12243. slots
  12244. } = _ref;
  12245. const {
  12246. t
  12247. } = useLocale();
  12248. const vTextFieldRef = ref();
  12249. const vMenuRef = ref();
  12250. const vVirtualScrollRef = ref();
  12251. const _menu = useProxiedModel(props, 'menu');
  12252. const menu = computed({
  12253. get: () => _menu.value,
  12254. set: v => {
  12255. if (_menu.value && !v && vMenuRef.value?.ΨopenChildren.size) return;
  12256. _menu.value = v;
  12257. }
  12258. });
  12259. const {
  12260. items,
  12261. transformIn,
  12262. transformOut
  12263. } = useItems(props);
  12264. const model = useProxiedModel(props, 'modelValue', [], v => transformIn(v === null ? [null] : wrapInArray(v)), v => {
  12265. const transformed = transformOut(v);
  12266. return props.multiple ? transformed : transformed[0] ?? null;
  12267. });
  12268. const counterValue = computed(() => {
  12269. return typeof props.counterValue === 'function' ? props.counterValue(model.value) : typeof props.counterValue === 'number' ? props.counterValue : model.value.length;
  12270. });
  12271. const form = useForm(props);
  12272. const selectedValues = computed(() => model.value.map(selection => selection.value));
  12273. const isFocused = shallowRef(false);
  12274. const label = computed(() => menu.value ? props.closeText : props.openText);
  12275. let keyboardLookupPrefix = '';
  12276. let keyboardLookupLastTime;
  12277. const displayItems = computed(() => {
  12278. if (props.hideSelected) {
  12279. return items.value.filter(item => !model.value.some(s => props.valueComparator(s, item)));
  12280. }
  12281. return items.value;
  12282. });
  12283. const menuDisabled = computed(() => props.hideNoData && !displayItems.value.length || form.isReadonly.value || form.isDisabled.value);
  12284. const computedMenuProps = computed(() => {
  12285. return {
  12286. ...props.menuProps,
  12287. activatorProps: {
  12288. ...(props.menuProps?.activatorProps || {}),
  12289. 'aria-haspopup': 'listbox' // Set aria-haspopup to 'listbox'
  12290. }
  12291. };
  12292. });
  12293. const listRef = ref();
  12294. const listEvents = useScrolling(listRef, vTextFieldRef);
  12295. function onClear(e) {
  12296. if (props.openOnClear) {
  12297. menu.value = true;
  12298. }
  12299. }
  12300. function onMousedownControl() {
  12301. if (menuDisabled.value) return;
  12302. menu.value = !menu.value;
  12303. }
  12304. function onListKeydown(e) {
  12305. if (checkPrintable(e)) {
  12306. onKeydown(e);
  12307. }
  12308. }
  12309. function onKeydown(e) {
  12310. if (!e.key || form.isReadonly.value) return;
  12311. if (['Enter', ' ', 'ArrowDown', 'ArrowUp', 'Home', 'End'].includes(e.key)) {
  12312. e.preventDefault();
  12313. }
  12314. if (['Enter', 'ArrowDown', ' '].includes(e.key)) {
  12315. menu.value = true;
  12316. }
  12317. if (['Escape', 'Tab'].includes(e.key)) {
  12318. menu.value = false;
  12319. }
  12320. if (e.key === 'Home') {
  12321. listRef.value?.focus('first');
  12322. } else if (e.key === 'End') {
  12323. listRef.value?.focus('last');
  12324. }
  12325. // html select hotkeys
  12326. const KEYBOARD_LOOKUP_THRESHOLD = 1000; // milliseconds
  12327. if (props.multiple || !checkPrintable(e)) return;
  12328. const now = performance.now();
  12329. if (now - keyboardLookupLastTime > KEYBOARD_LOOKUP_THRESHOLD) {
  12330. keyboardLookupPrefix = '';
  12331. }
  12332. keyboardLookupPrefix += e.key.toLowerCase();
  12333. keyboardLookupLastTime = now;
  12334. const item = items.value.find(item => item.title.toLowerCase().startsWith(keyboardLookupPrefix));
  12335. if (item !== undefined) {
  12336. model.value = [item];
  12337. const index = displayItems.value.indexOf(item);
  12338. IN_BROWSER && window.requestAnimationFrame(() => {
  12339. index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
  12340. });
  12341. }
  12342. }
  12343. /** @param set - null means toggle */
  12344. function select(item) {
  12345. let set = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  12346. if (item.props.disabled) return;
  12347. if (props.multiple) {
  12348. const index = model.value.findIndex(selection => props.valueComparator(selection.value, item.value));
  12349. const add = set == null ? !~index : set;
  12350. if (~index) {
  12351. const value = add ? [...model.value, item] : [...model.value];
  12352. value.splice(index, 1);
  12353. model.value = value;
  12354. } else if (add) {
  12355. model.value = [...model.value, item];
  12356. }
  12357. } else {
  12358. const add = set !== false;
  12359. model.value = add ? [item] : [];
  12360. nextTick(() => {
  12361. menu.value = false;
  12362. });
  12363. }
  12364. }
  12365. function onBlur(e) {
  12366. if (!listRef.value?.$el.contains(e.relatedTarget)) {
  12367. menu.value = false;
  12368. }
  12369. }
  12370. function onAfterEnter() {
  12371. if (props.eager) {
  12372. vVirtualScrollRef.value?.calculateVisibleItems();
  12373. }
  12374. }
  12375. function onAfterLeave() {
  12376. if (isFocused.value) {
  12377. vTextFieldRef.value?.focus();
  12378. }
  12379. }
  12380. function onFocusin(e) {
  12381. isFocused.value = true;
  12382. }
  12383. function onModelUpdate(v) {
  12384. if (v == null) model.value = [];else if (matchesSelector(vTextFieldRef.value, ':autofill') || matchesSelector(vTextFieldRef.value, ':-webkit-autofill')) {
  12385. const item = items.value.find(item => item.title === v);
  12386. if (item) {
  12387. select(item);
  12388. }
  12389. } else if (vTextFieldRef.value) {
  12390. vTextFieldRef.value.value = '';
  12391. }
  12392. }
  12393. watch(menu, () => {
  12394. if (!props.hideSelected && menu.value && model.value.length) {
  12395. const index = displayItems.value.findIndex(item => model.value.some(s => props.valueComparator(s.value, item.value)));
  12396. IN_BROWSER && window.requestAnimationFrame(() => {
  12397. index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
  12398. });
  12399. }
  12400. });
  12401. watch(() => props.items, (newVal, oldVal) => {
  12402. if (menu.value) return;
  12403. if (isFocused.value && !oldVal.length && newVal.length) {
  12404. menu.value = true;
  12405. }
  12406. });
  12407. useRender(() => {
  12408. const hasChips = !!(props.chips || slots.chip);
  12409. const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
  12410. const isDirty = model.value.length > 0;
  12411. const textFieldProps = VTextField.filterProps(props);
  12412. const placeholder = isDirty || !isFocused.value && props.label && !props.persistentPlaceholder ? undefined : props.placeholder;
  12413. return createVNode(VTextField, mergeProps({
  12414. "ref": vTextFieldRef
  12415. }, textFieldProps, {
  12416. "modelValue": model.value.map(v => v.props.value).join(', '),
  12417. "onUpdate:modelValue": onModelUpdate,
  12418. "focused": isFocused.value,
  12419. "onUpdate:focused": $event => isFocused.value = $event,
  12420. "validationValue": model.externalValue,
  12421. "counterValue": counterValue.value,
  12422. "dirty": isDirty,
  12423. "class": ['v-select', {
  12424. 'v-select--active-menu': menu.value,
  12425. 'v-select--chips': !!props.chips,
  12426. [`v-select--${props.multiple ? 'multiple' : 'single'}`]: true,
  12427. 'v-select--selected': model.value.length,
  12428. 'v-select--selection-slot': !!slots.selection
  12429. }, props.class],
  12430. "style": props.style,
  12431. "inputmode": "none",
  12432. "placeholder": placeholder,
  12433. "onClick:clear": onClear,
  12434. "onMousedown:control": onMousedownControl,
  12435. "onBlur": onBlur,
  12436. "onKeydown": onKeydown,
  12437. "aria-label": t(label.value),
  12438. "title": t(label.value)
  12439. }), {
  12440. ...slots,
  12441. default: () => createVNode(Fragment, null, [createVNode(VMenu, mergeProps({
  12442. "ref": vMenuRef,
  12443. "modelValue": menu.value,
  12444. "onUpdate:modelValue": $event => menu.value = $event,
  12445. "activator": "parent",
  12446. "contentClass": "v-select__content",
  12447. "disabled": menuDisabled.value,
  12448. "eager": props.eager,
  12449. "maxHeight": 310,
  12450. "openOnClick": false,
  12451. "closeOnContentClick": false,
  12452. "transition": props.transition,
  12453. "onAfterEnter": onAfterEnter,
  12454. "onAfterLeave": onAfterLeave
  12455. }, computedMenuProps.value), {
  12456. default: () => [hasList && createVNode(VList, mergeProps({
  12457. "ref": listRef,
  12458. "selected": selectedValues.value,
  12459. "selectStrategy": props.multiple ? 'independent' : 'single-independent',
  12460. "onMousedown": e => e.preventDefault(),
  12461. "onKeydown": onListKeydown,
  12462. "onFocusin": onFocusin,
  12463. "tabindex": "-1",
  12464. "aria-live": "polite",
  12465. "color": props.itemColor ?? props.color
  12466. }, listEvents, props.listProps), {
  12467. default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? createVNode(VListItem, {
  12468. "key": "no-data",
  12469. "title": t(props.noDataText)
  12470. }, null)), createVNode(VVirtualScroll, {
  12471. "ref": vVirtualScrollRef,
  12472. "renderless": true,
  12473. "items": displayItems.value
  12474. }, {
  12475. default: _ref2 => {
  12476. let {
  12477. item,
  12478. index,
  12479. itemRef
  12480. } = _ref2;
  12481. const itemProps = mergeProps(item.props, {
  12482. ref: itemRef,
  12483. key: item.value,
  12484. onClick: () => select(item, null)
  12485. });
  12486. return slots.item?.({
  12487. item,
  12488. index,
  12489. props: itemProps
  12490. }) ?? createVNode(VListItem, mergeProps(itemProps, {
  12491. "role": "option"
  12492. }), {
  12493. prepend: _ref3 => {
  12494. let {
  12495. isSelected
  12496. } = _ref3;
  12497. return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
  12498. "key": item.value,
  12499. "modelValue": isSelected,
  12500. "ripple": false,
  12501. "tabindex": "-1"
  12502. }, null) : undefined, item.props.prependAvatar && createVNode(VAvatar, {
  12503. "image": item.props.prependAvatar
  12504. }, null), item.props.prependIcon && createVNode(VIcon, {
  12505. "icon": item.props.prependIcon
  12506. }, null)]);
  12507. }
  12508. });
  12509. }
  12510. }), slots['append-item']?.()]
  12511. })]
  12512. }), model.value.map((item, index) => {
  12513. function onChipClose(e) {
  12514. e.stopPropagation();
  12515. e.preventDefault();
  12516. select(item, false);
  12517. }
  12518. const slotProps = {
  12519. 'onClick:close': onChipClose,
  12520. onKeydown(e) {
  12521. if (e.key !== 'Enter' && e.key !== ' ') return;
  12522. e.preventDefault();
  12523. e.stopPropagation();
  12524. onChipClose(e);
  12525. },
  12526. onMousedown(e) {
  12527. e.preventDefault();
  12528. e.stopPropagation();
  12529. },
  12530. modelValue: true,
  12531. 'onUpdate:modelValue': undefined
  12532. };
  12533. const hasSlot = hasChips ? !!slots.chip : !!slots.selection;
  12534. const slotContent = hasSlot ? ensureValidVNode(hasChips ? slots.chip({
  12535. item,
  12536. index,
  12537. props: slotProps
  12538. }) : slots.selection({
  12539. item,
  12540. index
  12541. })) : undefined;
  12542. if (hasSlot && !slotContent) return undefined;
  12543. return createVNode("div", {
  12544. "key": item.value,
  12545. "class": "v-select__selection"
  12546. }, [hasChips ? !slots.chip ? createVNode(VChip, mergeProps({
  12547. "key": "chip",
  12548. "closable": props.closableChips,
  12549. "size": "small",
  12550. "text": item.title,
  12551. "disabled": item.props.disabled
  12552. }, slotProps), null) : createVNode(VDefaultsProvider, {
  12553. "key": "chip-defaults",
  12554. "defaults": {
  12555. VChip: {
  12556. closable: props.closableChips,
  12557. size: 'small',
  12558. text: item.title
  12559. }
  12560. }
  12561. }, {
  12562. default: () => [slotContent]
  12563. }) : slotContent ?? createVNode("span", {
  12564. "class": "v-select__selection-text"
  12565. }, [item.title, props.multiple && index < model.value.length - 1 && createVNode("span", {
  12566. "class": "v-select__selection-comma"
  12567. }, [createTextVNode(",")])])]);
  12568. })]),
  12569. 'append-inner': function () {
  12570. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  12571. args[_key] = arguments[_key];
  12572. }
  12573. return createVNode(Fragment, null, [slots['append-inner']?.(...args), props.menuIcon ? createVNode(VIcon, {
  12574. "class": "v-select__menu-icon",
  12575. "icon": props.menuIcon
  12576. }, null) : undefined]);
  12577. }
  12578. });
  12579. });
  12580. return forwardRefs({
  12581. isFocused,
  12582. menu,
  12583. select
  12584. }, vTextFieldRef);
  12585. }
  12586. });
  12587. /* eslint-disable max-statements */
  12588. /* eslint-disable no-labels */
  12589. // Types
  12590. /**
  12591. * - match without highlight
  12592. * - single match (index), length already known
  12593. * - single match (start, end)
  12594. * - multiple matches (start, end), probably shouldn't overlap
  12595. */
  12596. // Composables
  12597. const defaultFilter = (value, query, item) => {
  12598. if (value == null || query == null) return -1;
  12599. return value.toString().toLocaleLowerCase().indexOf(query.toString().toLocaleLowerCase());
  12600. };
  12601. const makeFilterProps = propsFactory({
  12602. customFilter: Function,
  12603. customKeyFilter: Object,
  12604. filterKeys: [Array, String],
  12605. filterMode: {
  12606. type: String,
  12607. default: 'intersection'
  12608. },
  12609. noFilter: Boolean
  12610. }, 'filter');
  12611. function filterItems(items, query, options) {
  12612. const array = [];
  12613. // always ensure we fall back to a functioning filter
  12614. const filter = options?.default ?? defaultFilter;
  12615. const keys = options?.filterKeys ? wrapInArray(options.filterKeys) : false;
  12616. const customFiltersLength = Object.keys(options?.customKeyFilter ?? {}).length;
  12617. if (!items?.length) return array;
  12618. loop: for (let i = 0; i < items.length; i++) {
  12619. const [item, transformed = item] = wrapInArray(items[i]);
  12620. const customMatches = {};
  12621. const defaultMatches = {};
  12622. let match = -1;
  12623. if ((query || customFiltersLength > 0) && !options?.noFilter) {
  12624. if (typeof item === 'object') {
  12625. const filterKeys = keys || Object.keys(transformed);
  12626. for (const key of filterKeys) {
  12627. const value = getPropertyFromItem(transformed, key);
  12628. const keyFilter = options?.customKeyFilter?.[key];
  12629. match = keyFilter ? keyFilter(value, query, item) : filter(value, query, item);
  12630. if (match !== -1 && match !== false) {
  12631. if (keyFilter) customMatches[key] = match;else defaultMatches[key] = match;
  12632. } else if (options?.filterMode === 'every') {
  12633. continue loop;
  12634. }
  12635. }
  12636. } else {
  12637. match = filter(item, query, item);
  12638. if (match !== -1 && match !== false) {
  12639. defaultMatches.title = match;
  12640. }
  12641. }
  12642. const defaultMatchesLength = Object.keys(defaultMatches).length;
  12643. const customMatchesLength = Object.keys(customMatches).length;
  12644. if (!defaultMatchesLength && !customMatchesLength) continue;
  12645. if (options?.filterMode === 'union' && customMatchesLength !== customFiltersLength && !defaultMatchesLength) continue;
  12646. if (options?.filterMode === 'intersection' && (customMatchesLength !== customFiltersLength || !defaultMatchesLength)) continue;
  12647. }
  12648. array.push({
  12649. index: i,
  12650. matches: {
  12651. ...defaultMatches,
  12652. ...customMatches
  12653. }
  12654. });
  12655. }
  12656. return array;
  12657. }
  12658. function useFilter(props, items, query, options) {
  12659. const filteredItems = ref([]);
  12660. const filteredMatches = ref(new Map());
  12661. const transformedItems = computed(() => options?.transform ? unref(items).map(item => [item, options.transform(item)]) : unref(items));
  12662. watchEffect(() => {
  12663. const _query = typeof query === 'function' ? query() : unref(query);
  12664. const strQuery = typeof _query !== 'string' && typeof _query !== 'number' ? '' : String(_query);
  12665. const results = filterItems(transformedItems.value, strQuery, {
  12666. customKeyFilter: {
  12667. ...props.customKeyFilter,
  12668. ...unref(options?.customKeyFilter)
  12669. },
  12670. default: props.customFilter,
  12671. filterKeys: props.filterKeys,
  12672. filterMode: props.filterMode,
  12673. noFilter: props.noFilter
  12674. });
  12675. const originalItems = unref(items);
  12676. const _filteredItems = [];
  12677. const _filteredMatches = new Map();
  12678. results.forEach(_ref => {
  12679. let {
  12680. index,
  12681. matches
  12682. } = _ref;
  12683. const item = originalItems[index];
  12684. _filteredItems.push(item);
  12685. _filteredMatches.set(item.value, matches);
  12686. });
  12687. filteredItems.value = _filteredItems;
  12688. filteredMatches.value = _filteredMatches;
  12689. });
  12690. function getMatches(item) {
  12691. return filteredMatches.value.get(item.value);
  12692. }
  12693. return {
  12694. filteredItems,
  12695. filteredMatches,
  12696. getMatches
  12697. };
  12698. }
  12699. // Types
  12700. function highlightResult$1(text, matches, length) {
  12701. if (matches == null) return text;
  12702. if (Array.isArray(matches)) throw new Error('Multiple matches is not implemented');
  12703. return typeof matches === 'number' && ~matches ? createVNode(Fragment, null, [createVNode("span", {
  12704. "class": "v-autocomplete__unmask"
  12705. }, [text.substr(0, matches)]), createVNode("span", {
  12706. "class": "v-autocomplete__mask"
  12707. }, [text.substr(matches, length)]), createVNode("span", {
  12708. "class": "v-autocomplete__unmask"
  12709. }, [text.substr(matches + length)])]) : text;
  12710. }
  12711. const makeVAutocompleteProps = propsFactory({
  12712. autoSelectFirst: {
  12713. type: [Boolean, String]
  12714. },
  12715. clearOnSelect: Boolean,
  12716. search: String,
  12717. ...makeFilterProps({
  12718. filterKeys: ['title']
  12719. }),
  12720. ...makeSelectProps(),
  12721. ...omit(makeVTextFieldProps({
  12722. modelValue: null,
  12723. role: 'combobox'
  12724. }), ['validationValue', 'dirty', 'appendInnerIcon']),
  12725. ...makeTransitionProps({
  12726. transition: false
  12727. })
  12728. }, 'VAutocomplete');
  12729. const VAutocomplete = genericComponent()({
  12730. name: 'VAutocomplete',
  12731. props: makeVAutocompleteProps(),
  12732. emits: {
  12733. 'update:focused': focused => true,
  12734. 'update:search': value => true,
  12735. 'update:modelValue': value => true,
  12736. 'update:menu': value => true
  12737. },
  12738. setup(props, _ref) {
  12739. let {
  12740. slots
  12741. } = _ref;
  12742. const {
  12743. t
  12744. } = useLocale();
  12745. const vTextFieldRef = ref();
  12746. const isFocused = shallowRef(false);
  12747. const isPristine = shallowRef(true);
  12748. const listHasFocus = shallowRef(false);
  12749. const vMenuRef = ref();
  12750. const vVirtualScrollRef = ref();
  12751. const _menu = useProxiedModel(props, 'menu');
  12752. const menu = computed({
  12753. get: () => _menu.value,
  12754. set: v => {
  12755. if (_menu.value && !v && vMenuRef.value?.ΨopenChildren.size) return;
  12756. _menu.value = v;
  12757. }
  12758. });
  12759. const selectionIndex = shallowRef(-1);
  12760. const color = computed(() => vTextFieldRef.value?.color);
  12761. const label = computed(() => menu.value ? props.closeText : props.openText);
  12762. const {
  12763. items,
  12764. transformIn,
  12765. transformOut
  12766. } = useItems(props);
  12767. const {
  12768. textColorClasses,
  12769. textColorStyles
  12770. } = useTextColor(color);
  12771. const search = useProxiedModel(props, 'search', '');
  12772. const model = useProxiedModel(props, 'modelValue', [], v => transformIn(v === null ? [null] : wrapInArray(v)), v => {
  12773. const transformed = transformOut(v);
  12774. return props.multiple ? transformed : transformed[0] ?? null;
  12775. });
  12776. const counterValue = computed(() => {
  12777. return typeof props.counterValue === 'function' ? props.counterValue(model.value) : typeof props.counterValue === 'number' ? props.counterValue : model.value.length;
  12778. });
  12779. const form = useForm(props);
  12780. const {
  12781. filteredItems,
  12782. getMatches
  12783. } = useFilter(props, items, () => isPristine.value ? '' : search.value);
  12784. const displayItems = computed(() => {
  12785. if (props.hideSelected) {
  12786. return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value));
  12787. }
  12788. return filteredItems.value;
  12789. });
  12790. const hasChips = computed(() => !!(props.chips || slots.chip));
  12791. const hasSelectionSlot = computed(() => hasChips.value || !!slots.selection);
  12792. const selectedValues = computed(() => model.value.map(selection => selection.props.value));
  12793. const highlightFirst = computed(() => {
  12794. const selectFirst = props.autoSelectFirst === true || props.autoSelectFirst === 'exact' && search.value === displayItems.value[0]?.title;
  12795. return selectFirst && displayItems.value.length > 0 && !isPristine.value && !listHasFocus.value;
  12796. });
  12797. const menuDisabled = computed(() => props.hideNoData && !displayItems.value.length || form.isReadonly.value || form.isDisabled.value);
  12798. const listRef = ref();
  12799. const listEvents = useScrolling(listRef, vTextFieldRef);
  12800. function onClear(e) {
  12801. if (props.openOnClear) {
  12802. menu.value = true;
  12803. }
  12804. search.value = '';
  12805. }
  12806. function onMousedownControl() {
  12807. if (menuDisabled.value) return;
  12808. menu.value = true;
  12809. }
  12810. function onMousedownMenuIcon(e) {
  12811. if (menuDisabled.value) return;
  12812. if (isFocused.value) {
  12813. e.preventDefault();
  12814. e.stopPropagation();
  12815. }
  12816. menu.value = !menu.value;
  12817. }
  12818. function onListKeydown(e) {
  12819. if (checkPrintable(e)) {
  12820. vTextFieldRef.value?.focus();
  12821. }
  12822. }
  12823. function onKeydown(e) {
  12824. if (form.isReadonly.value) return;
  12825. const selectionStart = vTextFieldRef.value.selectionStart;
  12826. const length = model.value.length;
  12827. if (selectionIndex.value > -1 || ['Enter', 'ArrowDown', 'ArrowUp'].includes(e.key)) {
  12828. e.preventDefault();
  12829. }
  12830. if (['Enter', 'ArrowDown'].includes(e.key)) {
  12831. menu.value = true;
  12832. }
  12833. if (['Escape'].includes(e.key)) {
  12834. menu.value = false;
  12835. }
  12836. if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key) && !model.value.some(_ref2 => {
  12837. let {
  12838. value
  12839. } = _ref2;
  12840. return value === displayItems.value[0].value;
  12841. })) {
  12842. select(displayItems.value[0]);
  12843. }
  12844. if (e.key === 'ArrowDown' && highlightFirst.value) {
  12845. listRef.value?.focus('next');
  12846. }
  12847. if (['Backspace', 'Delete'].includes(e.key)) {
  12848. if (!props.multiple && hasSelectionSlot.value && model.value.length > 0 && !search.value) return select(model.value[0], false);
  12849. if (~selectionIndex.value) {
  12850. const originalSelectionIndex = selectionIndex.value;
  12851. select(model.value[selectionIndex.value], false);
  12852. selectionIndex.value = originalSelectionIndex >= length - 1 ? length - 2 : originalSelectionIndex;
  12853. } else if (e.key === 'Backspace' && !search.value) {
  12854. selectionIndex.value = length - 1;
  12855. }
  12856. }
  12857. if (!props.multiple) return;
  12858. if (e.key === 'ArrowLeft') {
  12859. if (selectionIndex.value < 0 && selectionStart > 0) return;
  12860. const prev = selectionIndex.value > -1 ? selectionIndex.value - 1 : length - 1;
  12861. if (model.value[prev]) {
  12862. selectionIndex.value = prev;
  12863. } else {
  12864. selectionIndex.value = -1;
  12865. vTextFieldRef.value.setSelectionRange(search.value?.length, search.value?.length);
  12866. }
  12867. }
  12868. if (e.key === 'ArrowRight') {
  12869. if (selectionIndex.value < 0) return;
  12870. const next = selectionIndex.value + 1;
  12871. if (model.value[next]) {
  12872. selectionIndex.value = next;
  12873. } else {
  12874. selectionIndex.value = -1;
  12875. vTextFieldRef.value.setSelectionRange(0, 0);
  12876. }
  12877. }
  12878. }
  12879. function onChange(e) {
  12880. if (matchesSelector(vTextFieldRef.value, ':autofill') || matchesSelector(vTextFieldRef.value, ':-webkit-autofill')) {
  12881. const item = items.value.find(item => item.title === e.target.value);
  12882. if (item) {
  12883. select(item);
  12884. }
  12885. }
  12886. }
  12887. function onAfterEnter() {
  12888. if (props.eager) {
  12889. vVirtualScrollRef.value?.calculateVisibleItems();
  12890. }
  12891. }
  12892. function onAfterLeave() {
  12893. if (isFocused.value) {
  12894. isPristine.value = true;
  12895. vTextFieldRef.value?.focus();
  12896. }
  12897. }
  12898. function onFocusin(e) {
  12899. isFocused.value = true;
  12900. setTimeout(() => {
  12901. listHasFocus.value = true;
  12902. });
  12903. }
  12904. function onFocusout(e) {
  12905. listHasFocus.value = false;
  12906. }
  12907. function onUpdateModelValue(v) {
  12908. if (v == null || v === '' && !props.multiple && !hasSelectionSlot.value) model.value = [];
  12909. }
  12910. const isSelecting = shallowRef(false);
  12911. /** @param set - null means toggle */
  12912. function select(item) {
  12913. let set = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  12914. if (!item || item.props.disabled) return;
  12915. if (props.multiple) {
  12916. const index = model.value.findIndex(selection => props.valueComparator(selection.value, item.value));
  12917. const add = set == null ? !~index : set;
  12918. if (~index) {
  12919. const value = add ? [...model.value, item] : [...model.value];
  12920. value.splice(index, 1);
  12921. model.value = value;
  12922. } else if (add) {
  12923. model.value = [...model.value, item];
  12924. }
  12925. if (props.clearOnSelect) {
  12926. search.value = '';
  12927. }
  12928. } else {
  12929. const add = set !== false;
  12930. model.value = add ? [item] : [];
  12931. search.value = add && !hasSelectionSlot.value ? item.title : '';
  12932. // watch for search watcher to trigger
  12933. nextTick(() => {
  12934. menu.value = false;
  12935. isPristine.value = true;
  12936. });
  12937. }
  12938. }
  12939. watch(isFocused, (val, oldVal) => {
  12940. if (val === oldVal) return;
  12941. if (val) {
  12942. isSelecting.value = true;
  12943. search.value = props.multiple || hasSelectionSlot.value ? '' : String(model.value.at(-1)?.props.title ?? '');
  12944. isPristine.value = true;
  12945. nextTick(() => isSelecting.value = false);
  12946. } else {
  12947. if (!props.multiple && search.value == null) model.value = [];
  12948. menu.value = false;
  12949. if (!model.value.some(_ref3 => {
  12950. let {
  12951. title
  12952. } = _ref3;
  12953. return title === search.value;
  12954. })) search.value = '';
  12955. selectionIndex.value = -1;
  12956. }
  12957. });
  12958. watch(search, val => {
  12959. if (!isFocused.value || isSelecting.value) return;
  12960. if (val) menu.value = true;
  12961. isPristine.value = !val;
  12962. });
  12963. watch(menu, () => {
  12964. if (!props.hideSelected && menu.value && model.value.length) {
  12965. const index = displayItems.value.findIndex(item => model.value.some(s => item.value === s.value));
  12966. IN_BROWSER && window.requestAnimationFrame(() => {
  12967. index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
  12968. });
  12969. }
  12970. });
  12971. watch(() => props.items, (newVal, oldVal) => {
  12972. if (menu.value) return;
  12973. if (isFocused.value && !oldVal.length && newVal.length) {
  12974. menu.value = true;
  12975. }
  12976. });
  12977. useRender(() => {
  12978. const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
  12979. const isDirty = model.value.length > 0;
  12980. const textFieldProps = VTextField.filterProps(props);
  12981. return createVNode(VTextField, mergeProps({
  12982. "ref": vTextFieldRef
  12983. }, textFieldProps, {
  12984. "modelValue": search.value,
  12985. "onUpdate:modelValue": [$event => search.value = $event, onUpdateModelValue],
  12986. "focused": isFocused.value,
  12987. "onUpdate:focused": $event => isFocused.value = $event,
  12988. "validationValue": model.externalValue,
  12989. "counterValue": counterValue.value,
  12990. "dirty": isDirty,
  12991. "onChange": onChange,
  12992. "class": ['v-autocomplete', `v-autocomplete--${props.multiple ? 'multiple' : 'single'}`, {
  12993. 'v-autocomplete--active-menu': menu.value,
  12994. 'v-autocomplete--chips': !!props.chips,
  12995. 'v-autocomplete--selection-slot': !!hasSelectionSlot.value,
  12996. 'v-autocomplete--selecting-index': selectionIndex.value > -1
  12997. }, props.class],
  12998. "style": props.style,
  12999. "readonly": form.isReadonly.value,
  13000. "placeholder": isDirty ? undefined : props.placeholder,
  13001. "onClick:clear": onClear,
  13002. "onMousedown:control": onMousedownControl,
  13003. "onKeydown": onKeydown
  13004. }), {
  13005. ...slots,
  13006. default: () => createVNode(Fragment, null, [createVNode(VMenu, mergeProps({
  13007. "ref": vMenuRef,
  13008. "modelValue": menu.value,
  13009. "onUpdate:modelValue": $event => menu.value = $event,
  13010. "activator": "parent",
  13011. "contentClass": "v-autocomplete__content",
  13012. "disabled": menuDisabled.value,
  13013. "eager": props.eager,
  13014. "maxHeight": 310,
  13015. "openOnClick": false,
  13016. "closeOnContentClick": false,
  13017. "transition": props.transition,
  13018. "onAfterEnter": onAfterEnter,
  13019. "onAfterLeave": onAfterLeave
  13020. }, props.menuProps), {
  13021. default: () => [hasList && createVNode(VList, mergeProps({
  13022. "ref": listRef,
  13023. "selected": selectedValues.value,
  13024. "selectStrategy": props.multiple ? 'independent' : 'single-independent',
  13025. "onMousedown": e => e.preventDefault(),
  13026. "onKeydown": onListKeydown,
  13027. "onFocusin": onFocusin,
  13028. "onFocusout": onFocusout,
  13029. "tabindex": "-1",
  13030. "aria-live": "polite",
  13031. "color": props.itemColor ?? props.color
  13032. }, listEvents, props.listProps), {
  13033. default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? createVNode(VListItem, {
  13034. "key": "no-data",
  13035. "title": t(props.noDataText)
  13036. }, null)), createVNode(VVirtualScroll, {
  13037. "ref": vVirtualScrollRef,
  13038. "renderless": true,
  13039. "items": displayItems.value
  13040. }, {
  13041. default: _ref4 => {
  13042. let {
  13043. item,
  13044. index,
  13045. itemRef
  13046. } = _ref4;
  13047. const itemProps = mergeProps(item.props, {
  13048. ref: itemRef,
  13049. key: item.value,
  13050. active: highlightFirst.value && index === 0 ? true : undefined,
  13051. onClick: () => select(item, null)
  13052. });
  13053. return slots.item?.({
  13054. item,
  13055. index,
  13056. props: itemProps
  13057. }) ?? createVNode(VListItem, mergeProps(itemProps, {
  13058. "role": "option"
  13059. }), {
  13060. prepend: _ref5 => {
  13061. let {
  13062. isSelected
  13063. } = _ref5;
  13064. return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
  13065. "key": item.value,
  13066. "modelValue": isSelected,
  13067. "ripple": false,
  13068. "tabindex": "-1"
  13069. }, null) : undefined, item.props.prependAvatar && createVNode(VAvatar, {
  13070. "image": item.props.prependAvatar
  13071. }, null), item.props.prependIcon && createVNode(VIcon, {
  13072. "icon": item.props.prependIcon
  13073. }, null)]);
  13074. },
  13075. title: () => {
  13076. return isPristine.value ? item.title : highlightResult$1(item.title, getMatches(item)?.title, search.value?.length ?? 0);
  13077. }
  13078. });
  13079. }
  13080. }), slots['append-item']?.()]
  13081. })]
  13082. }), model.value.map((item, index) => {
  13083. function onChipClose(e) {
  13084. e.stopPropagation();
  13085. e.preventDefault();
  13086. select(item, false);
  13087. }
  13088. const slotProps = {
  13089. 'onClick:close': onChipClose,
  13090. onKeydown(e) {
  13091. if (e.key !== 'Enter' && e.key !== ' ') return;
  13092. e.preventDefault();
  13093. e.stopPropagation();
  13094. onChipClose(e);
  13095. },
  13096. onMousedown(e) {
  13097. e.preventDefault();
  13098. e.stopPropagation();
  13099. },
  13100. modelValue: true,
  13101. 'onUpdate:modelValue': undefined
  13102. };
  13103. const hasSlot = hasChips.value ? !!slots.chip : !!slots.selection;
  13104. const slotContent = hasSlot ? ensureValidVNode(hasChips.value ? slots.chip({
  13105. item,
  13106. index,
  13107. props: slotProps
  13108. }) : slots.selection({
  13109. item,
  13110. index
  13111. })) : undefined;
  13112. if (hasSlot && !slotContent) return undefined;
  13113. return createVNode("div", {
  13114. "key": item.value,
  13115. "class": ['v-autocomplete__selection', index === selectionIndex.value && ['v-autocomplete__selection--selected', textColorClasses.value]],
  13116. "style": index === selectionIndex.value ? textColorStyles.value : {}
  13117. }, [hasChips.value ? !slots.chip ? createVNode(VChip, mergeProps({
  13118. "key": "chip",
  13119. "closable": props.closableChips,
  13120. "size": "small",
  13121. "text": item.title,
  13122. "disabled": item.props.disabled
  13123. }, slotProps), null) : createVNode(VDefaultsProvider, {
  13124. "key": "chip-defaults",
  13125. "defaults": {
  13126. VChip: {
  13127. closable: props.closableChips,
  13128. size: 'small',
  13129. text: item.title
  13130. }
  13131. }
  13132. }, {
  13133. default: () => [slotContent]
  13134. }) : slotContent ?? createVNode("span", {
  13135. "class": "v-autocomplete__selection-text"
  13136. }, [item.title, props.multiple && index < model.value.length - 1 && createVNode("span", {
  13137. "class": "v-autocomplete__selection-comma"
  13138. }, [createTextVNode(",")])])]);
  13139. })]),
  13140. 'append-inner': function () {
  13141. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  13142. args[_key] = arguments[_key];
  13143. }
  13144. return createVNode(Fragment, null, [slots['append-inner']?.(...args), props.menuIcon ? createVNode(VIcon, {
  13145. "class": "v-autocomplete__menu-icon",
  13146. "icon": props.menuIcon,
  13147. "onMousedown": onMousedownMenuIcon,
  13148. "onClick": noop,
  13149. "aria-label": t(label.value),
  13150. "title": t(label.value),
  13151. "tabindex": "-1"
  13152. }, null) : undefined]);
  13153. }
  13154. });
  13155. });
  13156. return forwardRefs({
  13157. isFocused,
  13158. isPristine,
  13159. menu,
  13160. search,
  13161. filteredItems,
  13162. select
  13163. }, vTextFieldRef);
  13164. }
  13165. });
  13166. const makeVBadgeProps = propsFactory({
  13167. bordered: Boolean,
  13168. color: String,
  13169. content: [Number, String],
  13170. dot: Boolean,
  13171. floating: Boolean,
  13172. icon: IconValue,
  13173. inline: Boolean,
  13174. label: {
  13175. type: String,
  13176. default: '$vuetify.badge'
  13177. },
  13178. max: [Number, String],
  13179. modelValue: {
  13180. type: Boolean,
  13181. default: true
  13182. },
  13183. offsetX: [Number, String],
  13184. offsetY: [Number, String],
  13185. textColor: String,
  13186. ...makeComponentProps(),
  13187. ...makeLocationProps({
  13188. location: 'top end'
  13189. }),
  13190. ...makeRoundedProps(),
  13191. ...makeTagProps(),
  13192. ...makeThemeProps(),
  13193. ...makeTransitionProps({
  13194. transition: 'scale-rotate-transition'
  13195. })
  13196. }, 'VBadge');
  13197. const VBadge = genericComponent()({
  13198. name: 'VBadge',
  13199. inheritAttrs: false,
  13200. props: makeVBadgeProps(),
  13201. setup(props, ctx) {
  13202. const {
  13203. backgroundColorClasses,
  13204. backgroundColorStyles
  13205. } = useBackgroundColor(toRef(props, 'color'));
  13206. const {
  13207. roundedClasses
  13208. } = useRounded(props);
  13209. const {
  13210. t
  13211. } = useLocale();
  13212. const {
  13213. textColorClasses,
  13214. textColorStyles
  13215. } = useTextColor(toRef(props, 'textColor'));
  13216. const {
  13217. themeClasses
  13218. } = useTheme();
  13219. const {
  13220. locationStyles
  13221. } = useLocation(props, true, side => {
  13222. const base = props.floating ? props.dot ? 2 : 4 : props.dot ? 8 : 12;
  13223. return base + (['top', 'bottom'].includes(side) ? +(props.offsetY ?? 0) : ['left', 'right'].includes(side) ? +(props.offsetX ?? 0) : 0);
  13224. });
  13225. useRender(() => {
  13226. const value = Number(props.content);
  13227. const content = !props.max || isNaN(value) ? props.content : value <= +props.max ? value : `${props.max}+`;
  13228. const [badgeAttrs, attrs] = pickWithRest(ctx.attrs, ['aria-atomic', 'aria-label', 'aria-live', 'role', 'title']);
  13229. return createVNode(props.tag, mergeProps({
  13230. "class": ['v-badge', {
  13231. 'v-badge--bordered': props.bordered,
  13232. 'v-badge--dot': props.dot,
  13233. 'v-badge--floating': props.floating,
  13234. 'v-badge--inline': props.inline
  13235. }, props.class]
  13236. }, attrs, {
  13237. "style": props.style
  13238. }), {
  13239. default: () => [createVNode("div", {
  13240. "class": "v-badge__wrapper"
  13241. }, [ctx.slots.default?.(), createVNode(MaybeTransition, {
  13242. "transition": props.transition
  13243. }, {
  13244. default: () => [withDirectives(createVNode("span", mergeProps({
  13245. "class": ['v-badge__badge', themeClasses.value, backgroundColorClasses.value, roundedClasses.value, textColorClasses.value],
  13246. "style": [backgroundColorStyles.value, textColorStyles.value, props.inline ? {} : locationStyles.value],
  13247. "aria-atomic": "true",
  13248. "aria-label": t(props.label, value),
  13249. "aria-live": "polite",
  13250. "role": "status"
  13251. }, badgeAttrs), [props.dot ? undefined : ctx.slots.badge ? ctx.slots.badge?.() : props.icon ? createVNode(VIcon, {
  13252. "icon": props.icon
  13253. }, null) : content]), [[vShow, props.modelValue]])]
  13254. })])]
  13255. });
  13256. });
  13257. return {};
  13258. }
  13259. });
  13260. const makeVBannerActionsProps = propsFactory({
  13261. color: String,
  13262. density: String,
  13263. ...makeComponentProps()
  13264. }, 'VBannerActions');
  13265. const VBannerActions = genericComponent()({
  13266. name: 'VBannerActions',
  13267. props: makeVBannerActionsProps(),
  13268. setup(props, _ref) {
  13269. let {
  13270. slots
  13271. } = _ref;
  13272. provideDefaults({
  13273. VBtn: {
  13274. color: props.color,
  13275. density: props.density,
  13276. slim: true,
  13277. variant: 'text'
  13278. }
  13279. });
  13280. useRender(() => createVNode("div", {
  13281. "class": ['v-banner-actions', props.class],
  13282. "style": props.style
  13283. }, [slots.default?.()]));
  13284. return {};
  13285. }
  13286. });
  13287. // Utilities
  13288. const VBannerText = createSimpleFunctional('v-banner-text');
  13289. // Types
  13290. const makeVBannerProps = propsFactory({
  13291. avatar: String,
  13292. bgColor: String,
  13293. color: String,
  13294. icon: IconValue,
  13295. lines: String,
  13296. stacked: Boolean,
  13297. sticky: Boolean,
  13298. text: String,
  13299. ...makeBorderProps(),
  13300. ...makeComponentProps(),
  13301. ...makeDensityProps(),
  13302. ...makeDimensionProps(),
  13303. ...makeDisplayProps({
  13304. mobile: null
  13305. }),
  13306. ...makeElevationProps(),
  13307. ...makeLocationProps(),
  13308. ...makePositionProps(),
  13309. ...makeRoundedProps(),
  13310. ...makeTagProps(),
  13311. ...makeThemeProps()
  13312. }, 'VBanner');
  13313. const VBanner = genericComponent()({
  13314. name: 'VBanner',
  13315. props: makeVBannerProps(),
  13316. setup(props, _ref) {
  13317. let {
  13318. slots
  13319. } = _ref;
  13320. const {
  13321. backgroundColorClasses,
  13322. backgroundColorStyles
  13323. } = useBackgroundColor(props, 'bgColor');
  13324. const {
  13325. borderClasses
  13326. } = useBorder(props);
  13327. const {
  13328. densityClasses
  13329. } = useDensity(props);
  13330. const {
  13331. displayClasses,
  13332. mobile
  13333. } = useDisplay(props);
  13334. const {
  13335. dimensionStyles
  13336. } = useDimension(props);
  13337. const {
  13338. elevationClasses
  13339. } = useElevation(props);
  13340. const {
  13341. locationStyles
  13342. } = useLocation(props);
  13343. const {
  13344. positionClasses
  13345. } = usePosition(props);
  13346. const {
  13347. roundedClasses
  13348. } = useRounded(props);
  13349. const {
  13350. themeClasses
  13351. } = provideTheme(props);
  13352. const color = toRef(props, 'color');
  13353. const density = toRef(props, 'density');
  13354. provideDefaults({
  13355. VBannerActions: {
  13356. color,
  13357. density
  13358. }
  13359. });
  13360. useRender(() => {
  13361. const hasText = !!(props.text || slots.text);
  13362. const hasPrependMedia = !!(props.avatar || props.icon);
  13363. const hasPrepend = !!(hasPrependMedia || slots.prepend);
  13364. return createVNode(props.tag, {
  13365. "class": ['v-banner', {
  13366. 'v-banner--stacked': props.stacked || mobile.value,
  13367. 'v-banner--sticky': props.sticky,
  13368. [`v-banner--${props.lines}-line`]: !!props.lines
  13369. }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, densityClasses.value, displayClasses.value, elevationClasses.value, positionClasses.value, roundedClasses.value, props.class],
  13370. "style": [backgroundColorStyles.value, dimensionStyles.value, locationStyles.value, props.style],
  13371. "role": "banner"
  13372. }, {
  13373. default: () => [hasPrepend && createVNode("div", {
  13374. "key": "prepend",
  13375. "class": "v-banner__prepend"
  13376. }, [!slots.prepend ? createVNode(VAvatar, {
  13377. "key": "prepend-avatar",
  13378. "color": color.value,
  13379. "density": density.value,
  13380. "icon": props.icon,
  13381. "image": props.avatar
  13382. }, null) : createVNode(VDefaultsProvider, {
  13383. "key": "prepend-defaults",
  13384. "disabled": !hasPrependMedia,
  13385. "defaults": {
  13386. VAvatar: {
  13387. color: color.value,
  13388. density: density.value,
  13389. icon: props.icon,
  13390. image: props.avatar
  13391. }
  13392. }
  13393. }, slots.prepend)]), createVNode("div", {
  13394. "class": "v-banner__content"
  13395. }, [hasText && createVNode(VBannerText, {
  13396. "key": "text"
  13397. }, {
  13398. default: () => [slots.text?.() ?? props.text]
  13399. }), slots.default?.()]), slots.actions && createVNode(VBannerActions, {
  13400. "key": "actions"
  13401. }, slots.actions)]
  13402. });
  13403. });
  13404. }
  13405. });
  13406. // Types
  13407. const makeVBottomNavigationProps = propsFactory({
  13408. baseColor: String,
  13409. bgColor: String,
  13410. color: String,
  13411. grow: Boolean,
  13412. mode: {
  13413. type: String,
  13414. validator: v => !v || ['horizontal', 'shift'].includes(v)
  13415. },
  13416. height: {
  13417. type: [Number, String],
  13418. default: 56
  13419. },
  13420. active: {
  13421. type: Boolean,
  13422. default: true
  13423. },
  13424. ...makeBorderProps(),
  13425. ...makeComponentProps(),
  13426. ...makeDensityProps(),
  13427. ...makeElevationProps(),
  13428. ...makeRoundedProps(),
  13429. ...makeLayoutItemProps({
  13430. name: 'bottom-navigation'
  13431. }),
  13432. ...makeTagProps({
  13433. tag: 'header'
  13434. }),
  13435. ...makeGroupProps({
  13436. selectedClass: 'v-btn--selected'
  13437. }),
  13438. ...makeThemeProps()
  13439. }, 'VBottomNavigation');
  13440. const VBottomNavigation = genericComponent()({
  13441. name: 'VBottomNavigation',
  13442. props: makeVBottomNavigationProps(),
  13443. emits: {
  13444. 'update:active': value => true,
  13445. 'update:modelValue': value => true
  13446. },
  13447. setup(props, _ref) {
  13448. let {
  13449. slots
  13450. } = _ref;
  13451. const {
  13452. themeClasses
  13453. } = useTheme();
  13454. const {
  13455. borderClasses
  13456. } = useBorder(props);
  13457. const {
  13458. backgroundColorClasses,
  13459. backgroundColorStyles
  13460. } = useBackgroundColor(toRef(props, 'bgColor'));
  13461. const {
  13462. densityClasses
  13463. } = useDensity(props);
  13464. const {
  13465. elevationClasses
  13466. } = useElevation(props);
  13467. const {
  13468. roundedClasses
  13469. } = useRounded(props);
  13470. const {
  13471. ssrBootStyles
  13472. } = useSsrBoot();
  13473. const height = computed(() => Number(props.height) - (props.density === 'comfortable' ? 8 : 0) - (props.density === 'compact' ? 16 : 0));
  13474. const isActive = useProxiedModel(props, 'active', props.active);
  13475. const {
  13476. layoutItemStyles
  13477. } = useLayoutItem({
  13478. id: props.name,
  13479. order: computed(() => parseInt(props.order, 10)),
  13480. position: computed(() => 'bottom'),
  13481. layoutSize: computed(() => isActive.value ? height.value : 0),
  13482. elementSize: height,
  13483. active: isActive,
  13484. absolute: toRef(props, 'absolute')
  13485. });
  13486. useGroup(props, VBtnToggleSymbol);
  13487. provideDefaults({
  13488. VBtn: {
  13489. baseColor: toRef(props, 'baseColor'),
  13490. color: toRef(props, 'color'),
  13491. density: toRef(props, 'density'),
  13492. stacked: computed(() => props.mode !== 'horizontal'),
  13493. variant: 'text'
  13494. }
  13495. }, {
  13496. scoped: true
  13497. });
  13498. useRender(() => {
  13499. return createVNode(props.tag, {
  13500. "class": ['v-bottom-navigation', {
  13501. 'v-bottom-navigation--active': isActive.value,
  13502. 'v-bottom-navigation--grow': props.grow,
  13503. 'v-bottom-navigation--shift': props.mode === 'shift'
  13504. }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  13505. "style": [backgroundColorStyles.value, layoutItemStyles.value, {
  13506. height: convertToUnit(height.value)
  13507. }, ssrBootStyles.value, props.style]
  13508. }, {
  13509. default: () => [slots.default && createVNode("div", {
  13510. "class": "v-bottom-navigation__content"
  13511. }, [slots.default()])]
  13512. });
  13513. });
  13514. return {};
  13515. }
  13516. });
  13517. // Types
  13518. const makeVDialogProps = propsFactory({
  13519. fullscreen: Boolean,
  13520. retainFocus: {
  13521. type: Boolean,
  13522. default: true
  13523. },
  13524. scrollable: Boolean,
  13525. ...makeVOverlayProps({
  13526. origin: 'center center',
  13527. scrollStrategy: 'block',
  13528. transition: {
  13529. component: VDialogTransition
  13530. },
  13531. zIndex: 2400
  13532. })
  13533. }, 'VDialog');
  13534. const VDialog = genericComponent()({
  13535. name: 'VDialog',
  13536. props: makeVDialogProps(),
  13537. emits: {
  13538. 'update:modelValue': value => true,
  13539. afterEnter: () => true,
  13540. afterLeave: () => true
  13541. },
  13542. setup(props, _ref) {
  13543. let {
  13544. emit,
  13545. slots
  13546. } = _ref;
  13547. const isActive = useProxiedModel(props, 'modelValue');
  13548. const {
  13549. scopeId
  13550. } = useScopeId();
  13551. const overlay = ref();
  13552. function onFocusin(e) {
  13553. const before = e.relatedTarget;
  13554. const after = e.target;
  13555. if (before !== after && overlay.value?.contentEl &&
  13556. // We're the topmost dialog
  13557. overlay.value?.globalTop &&
  13558. // It isn't the document or the dialog body
  13559. ![document, overlay.value.contentEl].includes(after) &&
  13560. // It isn't inside the dialog body
  13561. !overlay.value.contentEl.contains(after)) {
  13562. const focusable = focusableChildren(overlay.value.contentEl);
  13563. if (!focusable.length) return;
  13564. const firstElement = focusable[0];
  13565. const lastElement = focusable[focusable.length - 1];
  13566. if (before === firstElement) {
  13567. lastElement.focus();
  13568. } else {
  13569. firstElement.focus();
  13570. }
  13571. }
  13572. }
  13573. onBeforeUnmount(() => {
  13574. document.removeEventListener('focusin', onFocusin);
  13575. });
  13576. if (IN_BROWSER) {
  13577. watch(() => isActive.value && props.retainFocus, val => {
  13578. val ? document.addEventListener('focusin', onFocusin) : document.removeEventListener('focusin', onFocusin);
  13579. }, {
  13580. immediate: true
  13581. });
  13582. }
  13583. function onAfterEnter() {
  13584. emit('afterEnter');
  13585. if (overlay.value?.contentEl && !overlay.value.contentEl.contains(document.activeElement)) {
  13586. overlay.value.contentEl.focus({
  13587. preventScroll: true
  13588. });
  13589. }
  13590. }
  13591. function onAfterLeave() {
  13592. emit('afterLeave');
  13593. }
  13594. watch(isActive, async val => {
  13595. if (!val) {
  13596. await nextTick();
  13597. overlay.value.activatorEl?.focus({
  13598. preventScroll: true
  13599. });
  13600. }
  13601. });
  13602. useRender(() => {
  13603. const overlayProps = VOverlay.filterProps(props);
  13604. const activatorProps = mergeProps({
  13605. 'aria-haspopup': 'dialog'
  13606. }, props.activatorProps);
  13607. const contentProps = mergeProps({
  13608. tabindex: -1
  13609. }, props.contentProps);
  13610. return createVNode(VOverlay, mergeProps({
  13611. "ref": overlay,
  13612. "class": ['v-dialog', {
  13613. 'v-dialog--fullscreen': props.fullscreen,
  13614. 'v-dialog--scrollable': props.scrollable
  13615. }, props.class],
  13616. "style": props.style
  13617. }, overlayProps, {
  13618. "modelValue": isActive.value,
  13619. "onUpdate:modelValue": $event => isActive.value = $event,
  13620. "aria-modal": "true",
  13621. "activatorProps": activatorProps,
  13622. "contentProps": contentProps,
  13623. "height": !props.fullscreen ? props.height : undefined,
  13624. "width": !props.fullscreen ? props.width : undefined,
  13625. "maxHeight": !props.fullscreen ? props.maxHeight : undefined,
  13626. "maxWidth": !props.fullscreen ? props.maxWidth : undefined,
  13627. "role": "dialog",
  13628. "onAfterEnter": onAfterEnter,
  13629. "onAfterLeave": onAfterLeave
  13630. }, scopeId), {
  13631. activator: slots.activator,
  13632. default: function () {
  13633. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  13634. args[_key] = arguments[_key];
  13635. }
  13636. return createVNode(VDefaultsProvider, {
  13637. "root": "VDialog"
  13638. }, {
  13639. default: () => [slots.default?.(...args)]
  13640. });
  13641. }
  13642. });
  13643. });
  13644. return forwardRefs({}, overlay);
  13645. }
  13646. });
  13647. // Types
  13648. const makeVBottomSheetProps = propsFactory({
  13649. inset: Boolean,
  13650. ...makeVDialogProps({
  13651. transition: 'bottom-sheet-transition'
  13652. })
  13653. }, 'VBottomSheet');
  13654. const VBottomSheet = genericComponent()({
  13655. name: 'VBottomSheet',
  13656. props: makeVBottomSheetProps(),
  13657. emits: {
  13658. 'update:modelValue': value => true
  13659. },
  13660. setup(props, _ref) {
  13661. let {
  13662. slots
  13663. } = _ref;
  13664. const isActive = useProxiedModel(props, 'modelValue');
  13665. useRender(() => {
  13666. const dialogProps = VDialog.filterProps(props);
  13667. return createVNode(VDialog, mergeProps(dialogProps, {
  13668. "contentClass": ['v-bottom-sheet__content', props.contentClass],
  13669. "modelValue": isActive.value,
  13670. "onUpdate:modelValue": $event => isActive.value = $event,
  13671. "class": ['v-bottom-sheet', {
  13672. 'v-bottom-sheet--inset': props.inset
  13673. }, props.class],
  13674. "style": props.style
  13675. }), slots);
  13676. });
  13677. return {};
  13678. }
  13679. });
  13680. const makeVBreadcrumbsDividerProps = propsFactory({
  13681. divider: [Number, String],
  13682. ...makeComponentProps()
  13683. }, 'VBreadcrumbsDivider');
  13684. const VBreadcrumbsDivider = genericComponent()({
  13685. name: 'VBreadcrumbsDivider',
  13686. props: makeVBreadcrumbsDividerProps(),
  13687. setup(props, _ref) {
  13688. let {
  13689. slots
  13690. } = _ref;
  13691. useRender(() => createVNode("li", {
  13692. "class": ['v-breadcrumbs-divider', props.class],
  13693. "style": props.style
  13694. }, [slots?.default?.() ?? props.divider]));
  13695. return {};
  13696. }
  13697. });
  13698. const makeVBreadcrumbsItemProps = propsFactory({
  13699. active: Boolean,
  13700. activeClass: String,
  13701. activeColor: String,
  13702. color: String,
  13703. disabled: Boolean,
  13704. title: String,
  13705. ...makeComponentProps(),
  13706. ...makeRouterProps(),
  13707. ...makeTagProps({
  13708. tag: 'li'
  13709. })
  13710. }, 'VBreadcrumbsItem');
  13711. const VBreadcrumbsItem = genericComponent()({
  13712. name: 'VBreadcrumbsItem',
  13713. props: makeVBreadcrumbsItemProps(),
  13714. setup(props, _ref) {
  13715. let {
  13716. slots,
  13717. attrs
  13718. } = _ref;
  13719. const link = useLink(props, attrs);
  13720. const isActive = computed(() => props.active || link.isActive?.value);
  13721. const color = computed(() => isActive.value ? props.activeColor : props.color);
  13722. const {
  13723. textColorClasses,
  13724. textColorStyles
  13725. } = useTextColor(color);
  13726. useRender(() => {
  13727. return createVNode(props.tag, {
  13728. "class": ['v-breadcrumbs-item', {
  13729. 'v-breadcrumbs-item--active': isActive.value,
  13730. 'v-breadcrumbs-item--disabled': props.disabled,
  13731. [`${props.activeClass}`]: isActive.value && props.activeClass
  13732. }, textColorClasses.value, props.class],
  13733. "style": [textColorStyles.value, props.style],
  13734. "aria-current": isActive.value ? 'page' : undefined
  13735. }, {
  13736. default: () => [!link.isLink.value ? slots.default?.() ?? props.title : createVNode("a", mergeProps({
  13737. "class": "v-breadcrumbs-item--link",
  13738. "onClick": link.navigate
  13739. }, link.linkProps), [slots.default?.() ?? props.title])]
  13740. });
  13741. });
  13742. return {};
  13743. }
  13744. });
  13745. // Types
  13746. const makeVBreadcrumbsProps = propsFactory({
  13747. activeClass: String,
  13748. activeColor: String,
  13749. bgColor: String,
  13750. color: String,
  13751. disabled: Boolean,
  13752. divider: {
  13753. type: String,
  13754. default: '/'
  13755. },
  13756. icon: IconValue,
  13757. items: {
  13758. type: Array,
  13759. default: () => []
  13760. },
  13761. ...makeComponentProps(),
  13762. ...makeDensityProps(),
  13763. ...makeRoundedProps(),
  13764. ...makeTagProps({
  13765. tag: 'ul'
  13766. })
  13767. }, 'VBreadcrumbs');
  13768. const VBreadcrumbs = genericComponent()({
  13769. name: 'VBreadcrumbs',
  13770. props: makeVBreadcrumbsProps(),
  13771. setup(props, _ref) {
  13772. let {
  13773. slots
  13774. } = _ref;
  13775. const {
  13776. backgroundColorClasses,
  13777. backgroundColorStyles
  13778. } = useBackgroundColor(toRef(props, 'bgColor'));
  13779. const {
  13780. densityClasses
  13781. } = useDensity(props);
  13782. const {
  13783. roundedClasses
  13784. } = useRounded(props);
  13785. provideDefaults({
  13786. VBreadcrumbsDivider: {
  13787. divider: toRef(props, 'divider')
  13788. },
  13789. VBreadcrumbsItem: {
  13790. activeClass: toRef(props, 'activeClass'),
  13791. activeColor: toRef(props, 'activeColor'),
  13792. color: toRef(props, 'color'),
  13793. disabled: toRef(props, 'disabled')
  13794. }
  13795. });
  13796. const items = computed(() => props.items.map(item => {
  13797. return typeof item === 'string' ? {
  13798. item: {
  13799. title: item
  13800. },
  13801. raw: item
  13802. } : {
  13803. item,
  13804. raw: item
  13805. };
  13806. }));
  13807. useRender(() => {
  13808. const hasPrepend = !!(slots.prepend || props.icon);
  13809. return createVNode(props.tag, {
  13810. "class": ['v-breadcrumbs', backgroundColorClasses.value, densityClasses.value, roundedClasses.value, props.class],
  13811. "style": [backgroundColorStyles.value, props.style]
  13812. }, {
  13813. default: () => [hasPrepend && createVNode("li", {
  13814. "key": "prepend",
  13815. "class": "v-breadcrumbs__prepend"
  13816. }, [!slots.prepend ? createVNode(VIcon, {
  13817. "key": "prepend-icon",
  13818. "start": true,
  13819. "icon": props.icon
  13820. }, null) : createVNode(VDefaultsProvider, {
  13821. "key": "prepend-defaults",
  13822. "disabled": !props.icon,
  13823. "defaults": {
  13824. VIcon: {
  13825. icon: props.icon,
  13826. start: true
  13827. }
  13828. }
  13829. }, slots.prepend)]), items.value.map((_ref2, index, array) => {
  13830. let {
  13831. item,
  13832. raw
  13833. } = _ref2;
  13834. return createVNode(Fragment, null, [slots.item?.({
  13835. item,
  13836. index
  13837. }) ?? createVNode(VBreadcrumbsItem, mergeProps({
  13838. "key": index,
  13839. "disabled": index >= array.length - 1
  13840. }, typeof item === 'string' ? {
  13841. title: item
  13842. } : item), {
  13843. default: slots.title ? () => slots.title?.({
  13844. item,
  13845. index
  13846. }) : undefined
  13847. }), index < array.length - 1 && createVNode(VBreadcrumbsDivider, null, {
  13848. default: slots.divider ? () => slots.divider?.({
  13849. item: raw,
  13850. index
  13851. }) : undefined
  13852. })]);
  13853. }), slots.default?.()]
  13854. });
  13855. });
  13856. return {};
  13857. }
  13858. });
  13859. const VCardActions = genericComponent()({
  13860. name: 'VCardActions',
  13861. props: makeComponentProps(),
  13862. setup(props, _ref) {
  13863. let {
  13864. slots
  13865. } = _ref;
  13866. provideDefaults({
  13867. VBtn: {
  13868. slim: true,
  13869. variant: 'text'
  13870. }
  13871. });
  13872. useRender(() => createVNode("div", {
  13873. "class": ['v-card-actions', props.class],
  13874. "style": props.style
  13875. }, [slots.default?.()]));
  13876. return {};
  13877. }
  13878. });
  13879. const makeVCardSubtitleProps = propsFactory({
  13880. opacity: [Number, String],
  13881. ...makeComponentProps(),
  13882. ...makeTagProps()
  13883. }, 'VCardSubtitle');
  13884. const VCardSubtitle = genericComponent()({
  13885. name: 'VCardSubtitle',
  13886. props: makeVCardSubtitleProps(),
  13887. setup(props, _ref) {
  13888. let {
  13889. slots
  13890. } = _ref;
  13891. useRender(() => createVNode(props.tag, {
  13892. "class": ['v-card-subtitle', props.class],
  13893. "style": [{
  13894. '--v-card-subtitle-opacity': props.opacity
  13895. }, props.style]
  13896. }, slots));
  13897. return {};
  13898. }
  13899. });
  13900. // Utilities
  13901. const VCardTitle = createSimpleFunctional('v-card-title');
  13902. const makeCardItemProps = propsFactory({
  13903. appendAvatar: String,
  13904. appendIcon: IconValue,
  13905. prependAvatar: String,
  13906. prependIcon: IconValue,
  13907. subtitle: [String, Number],
  13908. title: [String, Number],
  13909. ...makeComponentProps(),
  13910. ...makeDensityProps()
  13911. }, 'VCardItem');
  13912. const VCardItem = genericComponent()({
  13913. name: 'VCardItem',
  13914. props: makeCardItemProps(),
  13915. setup(props, _ref) {
  13916. let {
  13917. slots
  13918. } = _ref;
  13919. useRender(() => {
  13920. const hasPrependMedia = !!(props.prependAvatar || props.prependIcon);
  13921. const hasPrepend = !!(hasPrependMedia || slots.prepend);
  13922. const hasAppendMedia = !!(props.appendAvatar || props.appendIcon);
  13923. const hasAppend = !!(hasAppendMedia || slots.append);
  13924. const hasTitle = !!(props.title != null || slots.title);
  13925. const hasSubtitle = !!(props.subtitle != null || slots.subtitle);
  13926. return createVNode("div", {
  13927. "class": ['v-card-item', props.class],
  13928. "style": props.style
  13929. }, [hasPrepend && createVNode("div", {
  13930. "key": "prepend",
  13931. "class": "v-card-item__prepend"
  13932. }, [!slots.prepend ? createVNode(Fragment, null, [props.prependAvatar && createVNode(VAvatar, {
  13933. "key": "prepend-avatar",
  13934. "density": props.density,
  13935. "image": props.prependAvatar
  13936. }, null), props.prependIcon && createVNode(VIcon, {
  13937. "key": "prepend-icon",
  13938. "density": props.density,
  13939. "icon": props.prependIcon
  13940. }, null)]) : createVNode(VDefaultsProvider, {
  13941. "key": "prepend-defaults",
  13942. "disabled": !hasPrependMedia,
  13943. "defaults": {
  13944. VAvatar: {
  13945. density: props.density,
  13946. image: props.prependAvatar
  13947. },
  13948. VIcon: {
  13949. density: props.density,
  13950. icon: props.prependIcon
  13951. }
  13952. }
  13953. }, slots.prepend)]), createVNode("div", {
  13954. "class": "v-card-item__content"
  13955. }, [hasTitle && createVNode(VCardTitle, {
  13956. "key": "title"
  13957. }, {
  13958. default: () => [slots.title?.() ?? props.title]
  13959. }), hasSubtitle && createVNode(VCardSubtitle, {
  13960. "key": "subtitle"
  13961. }, {
  13962. default: () => [slots.subtitle?.() ?? props.subtitle]
  13963. }), slots.default?.()]), hasAppend && createVNode("div", {
  13964. "key": "append",
  13965. "class": "v-card-item__append"
  13966. }, [!slots.append ? createVNode(Fragment, null, [props.appendIcon && createVNode(VIcon, {
  13967. "key": "append-icon",
  13968. "density": props.density,
  13969. "icon": props.appendIcon
  13970. }, null), props.appendAvatar && createVNode(VAvatar, {
  13971. "key": "append-avatar",
  13972. "density": props.density,
  13973. "image": props.appendAvatar
  13974. }, null)]) : createVNode(VDefaultsProvider, {
  13975. "key": "append-defaults",
  13976. "disabled": !hasAppendMedia,
  13977. "defaults": {
  13978. VAvatar: {
  13979. density: props.density,
  13980. image: props.appendAvatar
  13981. },
  13982. VIcon: {
  13983. density: props.density,
  13984. icon: props.appendIcon
  13985. }
  13986. }
  13987. }, slots.append)])]);
  13988. });
  13989. return {};
  13990. }
  13991. });
  13992. const makeVCardTextProps = propsFactory({
  13993. opacity: [Number, String],
  13994. ...makeComponentProps(),
  13995. ...makeTagProps()
  13996. }, 'VCardText');
  13997. const VCardText = genericComponent()({
  13998. name: 'VCardText',
  13999. props: makeVCardTextProps(),
  14000. setup(props, _ref) {
  14001. let {
  14002. slots
  14003. } = _ref;
  14004. useRender(() => createVNode(props.tag, {
  14005. "class": ['v-card-text', props.class],
  14006. "style": [{
  14007. '--v-card-text-opacity': props.opacity
  14008. }, props.style]
  14009. }, slots));
  14010. return {};
  14011. }
  14012. });
  14013. // Types
  14014. const makeVCardProps = propsFactory({
  14015. appendAvatar: String,
  14016. appendIcon: IconValue,
  14017. disabled: Boolean,
  14018. flat: Boolean,
  14019. hover: Boolean,
  14020. image: String,
  14021. link: {
  14022. type: Boolean,
  14023. default: undefined
  14024. },
  14025. prependAvatar: String,
  14026. prependIcon: IconValue,
  14027. ripple: {
  14028. type: [Boolean, Object],
  14029. default: true
  14030. },
  14031. subtitle: [String, Number],
  14032. text: [String, Number],
  14033. title: [String, Number],
  14034. ...makeBorderProps(),
  14035. ...makeComponentProps(),
  14036. ...makeDensityProps(),
  14037. ...makeDimensionProps(),
  14038. ...makeElevationProps(),
  14039. ...makeLoaderProps(),
  14040. ...makeLocationProps(),
  14041. ...makePositionProps(),
  14042. ...makeRoundedProps(),
  14043. ...makeRouterProps(),
  14044. ...makeTagProps(),
  14045. ...makeThemeProps(),
  14046. ...makeVariantProps({
  14047. variant: 'elevated'
  14048. })
  14049. }, 'VCard');
  14050. const VCard = genericComponent()({
  14051. name: 'VCard',
  14052. directives: {
  14053. Ripple
  14054. },
  14055. props: makeVCardProps(),
  14056. setup(props, _ref) {
  14057. let {
  14058. attrs,
  14059. slots
  14060. } = _ref;
  14061. const {
  14062. themeClasses
  14063. } = provideTheme(props);
  14064. const {
  14065. borderClasses
  14066. } = useBorder(props);
  14067. const {
  14068. colorClasses,
  14069. colorStyles,
  14070. variantClasses
  14071. } = useVariant(props);
  14072. const {
  14073. densityClasses
  14074. } = useDensity(props);
  14075. const {
  14076. dimensionStyles
  14077. } = useDimension(props);
  14078. const {
  14079. elevationClasses
  14080. } = useElevation(props);
  14081. const {
  14082. loaderClasses
  14083. } = useLoader(props);
  14084. const {
  14085. locationStyles
  14086. } = useLocation(props);
  14087. const {
  14088. positionClasses
  14089. } = usePosition(props);
  14090. const {
  14091. roundedClasses
  14092. } = useRounded(props);
  14093. const link = useLink(props, attrs);
  14094. const isLink = computed(() => props.link !== false && link.isLink.value);
  14095. const isClickable = computed(() => !props.disabled && props.link !== false && (props.link || link.isClickable.value));
  14096. useRender(() => {
  14097. const Tag = isLink.value ? 'a' : props.tag;
  14098. const hasTitle = !!(slots.title || props.title != null);
  14099. const hasSubtitle = !!(slots.subtitle || props.subtitle != null);
  14100. const hasHeader = hasTitle || hasSubtitle;
  14101. const hasAppend = !!(slots.append || props.appendAvatar || props.appendIcon);
  14102. const hasPrepend = !!(slots.prepend || props.prependAvatar || props.prependIcon);
  14103. const hasImage = !!(slots.image || props.image);
  14104. const hasCardItem = hasHeader || hasPrepend || hasAppend;
  14105. const hasText = !!(slots.text || props.text != null);
  14106. return withDirectives(createVNode(Tag, mergeProps({
  14107. "class": ['v-card', {
  14108. 'v-card--disabled': props.disabled,
  14109. 'v-card--flat': props.flat,
  14110. 'v-card--hover': props.hover && !(props.disabled || props.flat),
  14111. 'v-card--link': isClickable.value
  14112. }, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, loaderClasses.value, positionClasses.value, roundedClasses.value, variantClasses.value, props.class],
  14113. "style": [colorStyles.value, dimensionStyles.value, locationStyles.value, props.style],
  14114. "onClick": isClickable.value && link.navigate,
  14115. "tabindex": props.disabled ? -1 : undefined
  14116. }, link.linkProps), {
  14117. default: () => [hasImage && createVNode("div", {
  14118. "key": "image",
  14119. "class": "v-card__image"
  14120. }, [!slots.image ? createVNode(VImg, {
  14121. "key": "image-img",
  14122. "cover": true,
  14123. "src": props.image
  14124. }, null) : createVNode(VDefaultsProvider, {
  14125. "key": "image-defaults",
  14126. "disabled": !props.image,
  14127. "defaults": {
  14128. VImg: {
  14129. cover: true,
  14130. src: props.image
  14131. }
  14132. }
  14133. }, slots.image)]), createVNode(LoaderSlot, {
  14134. "name": "v-card",
  14135. "active": !!props.loading,
  14136. "color": typeof props.loading === 'boolean' ? undefined : props.loading
  14137. }, {
  14138. default: slots.loader
  14139. }), hasCardItem && createVNode(VCardItem, {
  14140. "key": "item",
  14141. "prependAvatar": props.prependAvatar,
  14142. "prependIcon": props.prependIcon,
  14143. "title": props.title,
  14144. "subtitle": props.subtitle,
  14145. "appendAvatar": props.appendAvatar,
  14146. "appendIcon": props.appendIcon
  14147. }, {
  14148. default: slots.item,
  14149. prepend: slots.prepend,
  14150. title: slots.title,
  14151. subtitle: slots.subtitle,
  14152. append: slots.append
  14153. }), hasText && createVNode(VCardText, {
  14154. "key": "text"
  14155. }, {
  14156. default: () => [slots.text?.() ?? props.text]
  14157. }), slots.default?.(), slots.actions && createVNode(VCardActions, null, {
  14158. default: slots.actions
  14159. }), genOverlays(isClickable.value, 'v-card')]
  14160. }), [[resolveDirective("ripple"), isClickable.value && props.ripple]]);
  14161. });
  14162. return {};
  14163. }
  14164. });
  14165. // Utilities
  14166. // Types
  14167. const handleGesture = wrapper => {
  14168. const {
  14169. touchstartX,
  14170. touchendX,
  14171. touchstartY,
  14172. touchendY
  14173. } = wrapper;
  14174. const dirRatio = 0.5;
  14175. const minDistance = 16;
  14176. wrapper.offsetX = touchendX - touchstartX;
  14177. wrapper.offsetY = touchendY - touchstartY;
  14178. if (Math.abs(wrapper.offsetY) < dirRatio * Math.abs(wrapper.offsetX)) {
  14179. wrapper.left && touchendX < touchstartX - minDistance && wrapper.left(wrapper);
  14180. wrapper.right && touchendX > touchstartX + minDistance && wrapper.right(wrapper);
  14181. }
  14182. if (Math.abs(wrapper.offsetX) < dirRatio * Math.abs(wrapper.offsetY)) {
  14183. wrapper.up && touchendY < touchstartY - minDistance && wrapper.up(wrapper);
  14184. wrapper.down && touchendY > touchstartY + minDistance && wrapper.down(wrapper);
  14185. }
  14186. };
  14187. function touchstart(event, wrapper) {
  14188. const touch = event.changedTouches[0];
  14189. wrapper.touchstartX = touch.clientX;
  14190. wrapper.touchstartY = touch.clientY;
  14191. wrapper.start?.({
  14192. originalEvent: event,
  14193. ...wrapper
  14194. });
  14195. }
  14196. function touchend(event, wrapper) {
  14197. const touch = event.changedTouches[0];
  14198. wrapper.touchendX = touch.clientX;
  14199. wrapper.touchendY = touch.clientY;
  14200. wrapper.end?.({
  14201. originalEvent: event,
  14202. ...wrapper
  14203. });
  14204. handleGesture(wrapper);
  14205. }
  14206. function touchmove(event, wrapper) {
  14207. const touch = event.changedTouches[0];
  14208. wrapper.touchmoveX = touch.clientX;
  14209. wrapper.touchmoveY = touch.clientY;
  14210. wrapper.move?.({
  14211. originalEvent: event,
  14212. ...wrapper
  14213. });
  14214. }
  14215. function createHandlers() {
  14216. let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  14217. const wrapper = {
  14218. touchstartX: 0,
  14219. touchstartY: 0,
  14220. touchendX: 0,
  14221. touchendY: 0,
  14222. touchmoveX: 0,
  14223. touchmoveY: 0,
  14224. offsetX: 0,
  14225. offsetY: 0,
  14226. left: value.left,
  14227. right: value.right,
  14228. up: value.up,
  14229. down: value.down,
  14230. start: value.start,
  14231. move: value.move,
  14232. end: value.end
  14233. };
  14234. return {
  14235. touchstart: e => touchstart(e, wrapper),
  14236. touchend: e => touchend(e, wrapper),
  14237. touchmove: e => touchmove(e, wrapper)
  14238. };
  14239. }
  14240. function mounted$3(el, binding) {
  14241. const value = binding.value;
  14242. const target = value?.parent ? el.parentElement : el;
  14243. const options = value?.options ?? {
  14244. passive: true
  14245. };
  14246. const uid = binding.instance?.$.uid; // TODO: use custom uid generator
  14247. if (!target || !uid) return;
  14248. const handlers = createHandlers(binding.value);
  14249. target._touchHandlers = target._touchHandlers ?? Object.create(null);
  14250. target._touchHandlers[uid] = handlers;
  14251. keys(handlers).forEach(eventName => {
  14252. target.addEventListener(eventName, handlers[eventName], options);
  14253. });
  14254. }
  14255. function unmounted$3(el, binding) {
  14256. const target = binding.value?.parent ? el.parentElement : el;
  14257. const uid = binding.instance?.$.uid;
  14258. if (!target?._touchHandlers || !uid) return;
  14259. const handlers = target._touchHandlers[uid];
  14260. keys(handlers).forEach(eventName => {
  14261. target.removeEventListener(eventName, handlers[eventName]);
  14262. });
  14263. delete target._touchHandlers[uid];
  14264. }
  14265. const Touch = {
  14266. mounted: mounted$3,
  14267. unmounted: unmounted$3
  14268. };
  14269. // Types
  14270. const VWindowSymbol = Symbol.for('vuetify:v-window');
  14271. const VWindowGroupSymbol = Symbol.for('vuetify:v-window-group');
  14272. const makeVWindowProps = propsFactory({
  14273. continuous: Boolean,
  14274. nextIcon: {
  14275. type: [Boolean, String, Function, Object],
  14276. default: '$next'
  14277. },
  14278. prevIcon: {
  14279. type: [Boolean, String, Function, Object],
  14280. default: '$prev'
  14281. },
  14282. reverse: Boolean,
  14283. showArrows: {
  14284. type: [Boolean, String],
  14285. validator: v => typeof v === 'boolean' || v === 'hover'
  14286. },
  14287. touch: {
  14288. type: [Object, Boolean],
  14289. default: undefined
  14290. },
  14291. direction: {
  14292. type: String,
  14293. default: 'horizontal'
  14294. },
  14295. modelValue: null,
  14296. disabled: Boolean,
  14297. selectedClass: {
  14298. type: String,
  14299. default: 'v-window-item--active'
  14300. },
  14301. // TODO: mandatory should probably not be exposed but do this for now
  14302. mandatory: {
  14303. type: [Boolean, String],
  14304. default: 'force'
  14305. },
  14306. ...makeComponentProps(),
  14307. ...makeTagProps(),
  14308. ...makeThemeProps()
  14309. }, 'VWindow');
  14310. const VWindow = genericComponent()({
  14311. name: 'VWindow',
  14312. directives: {
  14313. Touch
  14314. },
  14315. props: makeVWindowProps(),
  14316. emits: {
  14317. 'update:modelValue': value => true
  14318. },
  14319. setup(props, _ref) {
  14320. let {
  14321. slots
  14322. } = _ref;
  14323. const {
  14324. themeClasses
  14325. } = provideTheme(props);
  14326. const {
  14327. isRtl
  14328. } = useRtl();
  14329. const {
  14330. t
  14331. } = useLocale();
  14332. const group = useGroup(props, VWindowGroupSymbol);
  14333. const rootRef = ref();
  14334. const isRtlReverse = computed(() => isRtl.value ? !props.reverse : props.reverse);
  14335. const isReversed = shallowRef(false);
  14336. const transition = computed(() => {
  14337. const axis = props.direction === 'vertical' ? 'y' : 'x';
  14338. const reverse = isRtlReverse.value ? !isReversed.value : isReversed.value;
  14339. const direction = reverse ? '-reverse' : '';
  14340. return `v-window-${axis}${direction}-transition`;
  14341. });
  14342. const transitionCount = shallowRef(0);
  14343. const transitionHeight = ref(undefined);
  14344. const activeIndex = computed(() => {
  14345. return group.items.value.findIndex(item => group.selected.value.includes(item.id));
  14346. });
  14347. watch(activeIndex, (newVal, oldVal) => {
  14348. const itemsLength = group.items.value.length;
  14349. const lastIndex = itemsLength - 1;
  14350. if (itemsLength <= 2) {
  14351. isReversed.value = newVal < oldVal;
  14352. } else if (newVal === lastIndex && oldVal === 0) {
  14353. isReversed.value = true;
  14354. } else if (newVal === 0 && oldVal === lastIndex) {
  14355. isReversed.value = false;
  14356. } else {
  14357. isReversed.value = newVal < oldVal;
  14358. }
  14359. });
  14360. provide(VWindowSymbol, {
  14361. transition,
  14362. isReversed,
  14363. transitionCount,
  14364. transitionHeight,
  14365. rootRef
  14366. });
  14367. const canMoveBack = computed(() => props.continuous || activeIndex.value !== 0);
  14368. const canMoveForward = computed(() => props.continuous || activeIndex.value !== group.items.value.length - 1);
  14369. function prev() {
  14370. canMoveBack.value && group.prev();
  14371. }
  14372. function next() {
  14373. canMoveForward.value && group.next();
  14374. }
  14375. const arrows = computed(() => {
  14376. const arrows = [];
  14377. const prevProps = {
  14378. icon: isRtl.value ? props.nextIcon : props.prevIcon,
  14379. class: `v-window__${isRtlReverse.value ? 'right' : 'left'}`,
  14380. onClick: group.prev,
  14381. 'aria-label': t('$vuetify.carousel.prev')
  14382. };
  14383. arrows.push(canMoveBack.value ? slots.prev ? slots.prev({
  14384. props: prevProps
  14385. }) : createVNode(VBtn, prevProps, null) : createVNode("div", null, null));
  14386. const nextProps = {
  14387. icon: isRtl.value ? props.prevIcon : props.nextIcon,
  14388. class: `v-window__${isRtlReverse.value ? 'left' : 'right'}`,
  14389. onClick: group.next,
  14390. 'aria-label': t('$vuetify.carousel.next')
  14391. };
  14392. arrows.push(canMoveForward.value ? slots.next ? slots.next({
  14393. props: nextProps
  14394. }) : createVNode(VBtn, nextProps, null) : createVNode("div", null, null));
  14395. return arrows;
  14396. });
  14397. const touchOptions = computed(() => {
  14398. if (props.touch === false) return props.touch;
  14399. const options = {
  14400. left: () => {
  14401. isRtlReverse.value ? prev() : next();
  14402. },
  14403. right: () => {
  14404. isRtlReverse.value ? next() : prev();
  14405. },
  14406. start: _ref2 => {
  14407. let {
  14408. originalEvent
  14409. } = _ref2;
  14410. originalEvent.stopPropagation();
  14411. }
  14412. };
  14413. return {
  14414. ...options,
  14415. ...(props.touch === true ? {} : props.touch)
  14416. };
  14417. });
  14418. useRender(() => withDirectives(createVNode(props.tag, {
  14419. "ref": rootRef,
  14420. "class": ['v-window', {
  14421. 'v-window--show-arrows-on-hover': props.showArrows === 'hover'
  14422. }, themeClasses.value, props.class],
  14423. "style": props.style
  14424. }, {
  14425. default: () => [createVNode("div", {
  14426. "class": "v-window__container",
  14427. "style": {
  14428. height: transitionHeight.value
  14429. }
  14430. }, [slots.default?.({
  14431. group
  14432. }), props.showArrows !== false && createVNode("div", {
  14433. "class": "v-window__controls"
  14434. }, [arrows.value])]), slots.additional?.({
  14435. group
  14436. })]
  14437. }), [[resolveDirective("touch"), touchOptions.value]]));
  14438. return {
  14439. group
  14440. };
  14441. }
  14442. });
  14443. // Types
  14444. const makeVCarouselProps = propsFactory({
  14445. color: String,
  14446. cycle: Boolean,
  14447. delimiterIcon: {
  14448. type: IconValue,
  14449. default: '$delimiter'
  14450. },
  14451. height: {
  14452. type: [Number, String],
  14453. default: 500
  14454. },
  14455. hideDelimiters: Boolean,
  14456. hideDelimiterBackground: Boolean,
  14457. interval: {
  14458. type: [Number, String],
  14459. default: 6000,
  14460. validator: value => Number(value) > 0
  14461. },
  14462. progress: [Boolean, String],
  14463. verticalDelimiters: [Boolean, String],
  14464. ...makeVWindowProps({
  14465. continuous: true,
  14466. mandatory: 'force',
  14467. showArrows: true
  14468. })
  14469. }, 'VCarousel');
  14470. const VCarousel = genericComponent()({
  14471. name: 'VCarousel',
  14472. props: makeVCarouselProps(),
  14473. emits: {
  14474. 'update:modelValue': value => true
  14475. },
  14476. setup(props, _ref) {
  14477. let {
  14478. slots
  14479. } = _ref;
  14480. const model = useProxiedModel(props, 'modelValue');
  14481. const {
  14482. t
  14483. } = useLocale();
  14484. const windowRef = ref();
  14485. let slideTimeout = -1;
  14486. watch(model, restartTimeout);
  14487. watch(() => props.interval, restartTimeout);
  14488. watch(() => props.cycle, val => {
  14489. if (val) restartTimeout();else window.clearTimeout(slideTimeout);
  14490. });
  14491. onMounted(startTimeout);
  14492. function startTimeout() {
  14493. if (!props.cycle || !windowRef.value) return;
  14494. slideTimeout = window.setTimeout(windowRef.value.group.next, +props.interval > 0 ? +props.interval : 6000);
  14495. }
  14496. function restartTimeout() {
  14497. window.clearTimeout(slideTimeout);
  14498. window.requestAnimationFrame(startTimeout);
  14499. }
  14500. useRender(() => {
  14501. const windowProps = VWindow.filterProps(props);
  14502. return createVNode(VWindow, mergeProps({
  14503. "ref": windowRef
  14504. }, windowProps, {
  14505. "modelValue": model.value,
  14506. "onUpdate:modelValue": $event => model.value = $event,
  14507. "class": ['v-carousel', {
  14508. 'v-carousel--hide-delimiter-background': props.hideDelimiterBackground,
  14509. 'v-carousel--vertical-delimiters': props.verticalDelimiters
  14510. }, props.class],
  14511. "style": [{
  14512. height: convertToUnit(props.height)
  14513. }, props.style]
  14514. }), {
  14515. default: slots.default,
  14516. additional: _ref2 => {
  14517. let {
  14518. group
  14519. } = _ref2;
  14520. return createVNode(Fragment, null, [!props.hideDelimiters && createVNode("div", {
  14521. "class": "v-carousel__controls",
  14522. "style": {
  14523. left: props.verticalDelimiters === 'left' && props.verticalDelimiters ? 0 : 'auto',
  14524. right: props.verticalDelimiters === 'right' ? 0 : 'auto'
  14525. }
  14526. }, [group.items.value.length > 0 && createVNode(VDefaultsProvider, {
  14527. "defaults": {
  14528. VBtn: {
  14529. color: props.color,
  14530. icon: props.delimiterIcon,
  14531. size: 'x-small',
  14532. variant: 'text'
  14533. }
  14534. },
  14535. "scoped": true
  14536. }, {
  14537. default: () => [group.items.value.map((item, index) => {
  14538. const props = {
  14539. id: `carousel-item-${item.id}`,
  14540. 'aria-label': t('$vuetify.carousel.ariaLabel.delimiter', index + 1, group.items.value.length),
  14541. class: ['v-carousel__controls__item', group.isSelected(item.id) && 'v-btn--active'],
  14542. onClick: () => group.select(item.id, true)
  14543. };
  14544. return slots.item ? slots.item({
  14545. props,
  14546. item
  14547. }) : createVNode(VBtn, mergeProps(item, props), null);
  14548. })]
  14549. })]), props.progress && createVNode(VProgressLinear, {
  14550. "class": "v-carousel__progress",
  14551. "color": typeof props.progress === 'string' ? props.progress : undefined,
  14552. "modelValue": (group.getItemIndex(model.value) + 1) / group.items.value.length * 100
  14553. }, null)]);
  14554. },
  14555. prev: slots.prev,
  14556. next: slots.next
  14557. });
  14558. });
  14559. return {};
  14560. }
  14561. });
  14562. const makeVWindowItemProps = propsFactory({
  14563. reverseTransition: {
  14564. type: [Boolean, String],
  14565. default: undefined
  14566. },
  14567. transition: {
  14568. type: [Boolean, String],
  14569. default: undefined
  14570. },
  14571. ...makeComponentProps(),
  14572. ...makeGroupItemProps(),
  14573. ...makeLazyProps()
  14574. }, 'VWindowItem');
  14575. const VWindowItem = genericComponent()({
  14576. name: 'VWindowItem',
  14577. directives: {
  14578. Touch
  14579. },
  14580. props: makeVWindowItemProps(),
  14581. emits: {
  14582. 'group:selected': val => true
  14583. },
  14584. setup(props, _ref) {
  14585. let {
  14586. slots
  14587. } = _ref;
  14588. const window = inject$1(VWindowSymbol);
  14589. const groupItem = useGroupItem(props, VWindowGroupSymbol);
  14590. const {
  14591. isBooted
  14592. } = useSsrBoot();
  14593. if (!window || !groupItem) throw new Error('[Vuetify] VWindowItem must be used inside VWindow');
  14594. const isTransitioning = shallowRef(false);
  14595. const hasTransition = computed(() => isBooted.value && (window.isReversed.value ? props.reverseTransition !== false : props.transition !== false));
  14596. function onAfterTransition() {
  14597. if (!isTransitioning.value || !window) {
  14598. return;
  14599. }
  14600. // Finalize transition state.
  14601. isTransitioning.value = false;
  14602. if (window.transitionCount.value > 0) {
  14603. window.transitionCount.value -= 1;
  14604. // Remove container height if we are out of transition.
  14605. if (window.transitionCount.value === 0) {
  14606. window.transitionHeight.value = undefined;
  14607. }
  14608. }
  14609. }
  14610. function onBeforeTransition() {
  14611. if (isTransitioning.value || !window) {
  14612. return;
  14613. }
  14614. // Initialize transition state here.
  14615. isTransitioning.value = true;
  14616. if (window.transitionCount.value === 0) {
  14617. // Set initial height for height transition.
  14618. window.transitionHeight.value = convertToUnit(window.rootRef.value?.clientHeight);
  14619. }
  14620. window.transitionCount.value += 1;
  14621. }
  14622. function onTransitionCancelled() {
  14623. onAfterTransition(); // This should have the same path as normal transition end.
  14624. }
  14625. function onEnterTransition(el) {
  14626. if (!isTransitioning.value) {
  14627. return;
  14628. }
  14629. nextTick(() => {
  14630. // Do not set height if no transition or cancelled.
  14631. if (!hasTransition.value || !isTransitioning.value || !window) {
  14632. return;
  14633. }
  14634. // Set transition target height.
  14635. window.transitionHeight.value = convertToUnit(el.clientHeight);
  14636. });
  14637. }
  14638. const transition = computed(() => {
  14639. const name = window.isReversed.value ? props.reverseTransition : props.transition;
  14640. return !hasTransition.value ? false : {
  14641. name: typeof name !== 'string' ? window.transition.value : name,
  14642. onBeforeEnter: onBeforeTransition,
  14643. onAfterEnter: onAfterTransition,
  14644. onEnterCancelled: onTransitionCancelled,
  14645. onBeforeLeave: onBeforeTransition,
  14646. onAfterLeave: onAfterTransition,
  14647. onLeaveCancelled: onTransitionCancelled,
  14648. onEnter: onEnterTransition
  14649. };
  14650. });
  14651. const {
  14652. hasContent
  14653. } = useLazy(props, groupItem.isSelected);
  14654. useRender(() => createVNode(MaybeTransition, {
  14655. "transition": transition.value,
  14656. "disabled": !isBooted.value
  14657. }, {
  14658. default: () => [withDirectives(createVNode("div", {
  14659. "class": ['v-window-item', groupItem.selectedClass.value, props.class],
  14660. "style": props.style
  14661. }, [hasContent.value && slots.default?.()]), [[vShow, groupItem.isSelected.value]])]
  14662. }));
  14663. return {
  14664. groupItem
  14665. };
  14666. }
  14667. });
  14668. // Types
  14669. const makeVCarouselItemProps = propsFactory({
  14670. ...makeVImgProps(),
  14671. ...makeVWindowItemProps()
  14672. }, 'VCarouselItem');
  14673. const VCarouselItem = genericComponent()({
  14674. name: 'VCarouselItem',
  14675. inheritAttrs: false,
  14676. props: makeVCarouselItemProps(),
  14677. setup(props, _ref) {
  14678. let {
  14679. slots,
  14680. attrs
  14681. } = _ref;
  14682. useRender(() => {
  14683. const imgProps = VImg.filterProps(props);
  14684. const windowItemProps = VWindowItem.filterProps(props);
  14685. return createVNode(VWindowItem, mergeProps({
  14686. "class": ['v-carousel-item', props.class]
  14687. }, windowItemProps), {
  14688. default: () => [createVNode(VImg, mergeProps(attrs, imgProps), slots)]
  14689. });
  14690. });
  14691. }
  14692. });
  14693. // Styles
  14694. const VCode = createSimpleFunctional('v-code', 'code');
  14695. // Types
  14696. const makeVColorPickerCanvasProps = propsFactory({
  14697. color: {
  14698. type: Object
  14699. },
  14700. disabled: Boolean,
  14701. dotSize: {
  14702. type: [Number, String],
  14703. default: 10
  14704. },
  14705. height: {
  14706. type: [Number, String],
  14707. default: 150
  14708. },
  14709. width: {
  14710. type: [Number, String],
  14711. default: 300
  14712. },
  14713. ...makeComponentProps()
  14714. }, 'VColorPickerCanvas');
  14715. const VColorPickerCanvas = defineComponent({
  14716. name: 'VColorPickerCanvas',
  14717. props: makeVColorPickerCanvasProps(),
  14718. emits: {
  14719. 'update:color': color => true,
  14720. 'update:position': hue => true
  14721. },
  14722. setup(props, _ref) {
  14723. let {
  14724. emit
  14725. } = _ref;
  14726. const isInteracting = shallowRef(false);
  14727. const canvasRef = ref();
  14728. const canvasWidth = shallowRef(parseFloat(props.width));
  14729. const canvasHeight = shallowRef(parseFloat(props.height));
  14730. const _dotPosition = ref({
  14731. x: 0,
  14732. y: 0
  14733. });
  14734. const dotPosition = computed({
  14735. get: () => _dotPosition.value,
  14736. set(val) {
  14737. if (!canvasRef.value) return;
  14738. const {
  14739. x,
  14740. y
  14741. } = val;
  14742. _dotPosition.value = val;
  14743. emit('update:color', {
  14744. h: props.color?.h ?? 0,
  14745. s: clamp(x, 0, canvasWidth.value) / canvasWidth.value,
  14746. v: 1 - clamp(y, 0, canvasHeight.value) / canvasHeight.value,
  14747. a: props.color?.a ?? 1
  14748. });
  14749. }
  14750. });
  14751. const dotStyles = computed(() => {
  14752. const {
  14753. x,
  14754. y
  14755. } = dotPosition.value;
  14756. const radius = parseInt(props.dotSize, 10) / 2;
  14757. return {
  14758. width: convertToUnit(props.dotSize),
  14759. height: convertToUnit(props.dotSize),
  14760. transform: `translate(${convertToUnit(x - radius)}, ${convertToUnit(y - radius)})`
  14761. };
  14762. });
  14763. const {
  14764. resizeRef
  14765. } = useResizeObserver(entries => {
  14766. if (!resizeRef.el?.offsetParent) return;
  14767. const {
  14768. width,
  14769. height
  14770. } = entries[0].contentRect;
  14771. canvasWidth.value = width;
  14772. canvasHeight.value = height;
  14773. });
  14774. function updateDotPosition(x, y, rect) {
  14775. const {
  14776. left,
  14777. top,
  14778. width,
  14779. height
  14780. } = rect;
  14781. dotPosition.value = {
  14782. x: clamp(x - left, 0, width),
  14783. y: clamp(y - top, 0, height)
  14784. };
  14785. }
  14786. function handleMouseDown(e) {
  14787. if (e.type === 'mousedown') {
  14788. // Prevent text selection while dragging
  14789. e.preventDefault();
  14790. }
  14791. if (props.disabled) return;
  14792. handleMouseMove(e);
  14793. window.addEventListener('mousemove', handleMouseMove);
  14794. window.addEventListener('mouseup', handleMouseUp);
  14795. window.addEventListener('touchmove', handleMouseMove);
  14796. window.addEventListener('touchend', handleMouseUp);
  14797. }
  14798. function handleMouseMove(e) {
  14799. if (props.disabled || !canvasRef.value) return;
  14800. isInteracting.value = true;
  14801. const coords = getEventCoordinates(e);
  14802. updateDotPosition(coords.clientX, coords.clientY, canvasRef.value.getBoundingClientRect());
  14803. }
  14804. function handleMouseUp() {
  14805. window.removeEventListener('mousemove', handleMouseMove);
  14806. window.removeEventListener('mouseup', handleMouseUp);
  14807. window.removeEventListener('touchmove', handleMouseMove);
  14808. window.removeEventListener('touchend', handleMouseUp);
  14809. }
  14810. function updateCanvas() {
  14811. if (!canvasRef.value) return;
  14812. const canvas = canvasRef.value;
  14813. const ctx = canvas.getContext('2d');
  14814. if (!ctx) return;
  14815. const saturationGradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
  14816. saturationGradient.addColorStop(0, 'hsla(0, 0%, 100%, 1)'); // white
  14817. saturationGradient.addColorStop(1, `hsla(${props.color?.h ?? 0}, 100%, 50%, 1)`);
  14818. ctx.fillStyle = saturationGradient;
  14819. ctx.fillRect(0, 0, canvas.width, canvas.height);
  14820. const valueGradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
  14821. valueGradient.addColorStop(0, 'hsla(0, 0%, 0%, 0)'); // transparent
  14822. valueGradient.addColorStop(1, 'hsla(0, 0%, 0%, 1)'); // black
  14823. ctx.fillStyle = valueGradient;
  14824. ctx.fillRect(0, 0, canvas.width, canvas.height);
  14825. }
  14826. watch(() => props.color?.h, updateCanvas, {
  14827. immediate: true
  14828. });
  14829. watch(() => [canvasWidth.value, canvasHeight.value], (newVal, oldVal) => {
  14830. updateCanvas();
  14831. _dotPosition.value = {
  14832. x: dotPosition.value.x * newVal[0] / oldVal[0],
  14833. y: dotPosition.value.y * newVal[1] / oldVal[1]
  14834. };
  14835. }, {
  14836. flush: 'post'
  14837. });
  14838. watch(() => props.color, () => {
  14839. if (isInteracting.value) {
  14840. isInteracting.value = false;
  14841. return;
  14842. }
  14843. _dotPosition.value = props.color ? {
  14844. x: props.color.s * canvasWidth.value,
  14845. y: (1 - props.color.v) * canvasHeight.value
  14846. } : {
  14847. x: 0,
  14848. y: 0
  14849. };
  14850. }, {
  14851. deep: true,
  14852. immediate: true
  14853. });
  14854. onMounted(() => updateCanvas());
  14855. useRender(() => createVNode("div", {
  14856. "ref": resizeRef,
  14857. "class": ['v-color-picker-canvas', props.class],
  14858. "style": props.style,
  14859. "onMousedown": handleMouseDown,
  14860. "onTouchstartPassive": handleMouseDown
  14861. }, [createVNode("canvas", {
  14862. "ref": canvasRef,
  14863. "width": canvasWidth.value,
  14864. "height": canvasHeight.value
  14865. }, null), props.color && createVNode("div", {
  14866. "class": ['v-color-picker-canvas__dot', {
  14867. 'v-color-picker-canvas__dot--disabled': props.disabled
  14868. }],
  14869. "style": dotStyles.value
  14870. }, null)]));
  14871. return {};
  14872. }
  14873. });
  14874. // Utilities
  14875. // Types
  14876. function stripAlpha(color, stripAlpha) {
  14877. if (stripAlpha) {
  14878. const {
  14879. a,
  14880. ...rest
  14881. } = color;
  14882. return rest;
  14883. }
  14884. return color;
  14885. }
  14886. function extractColor(color, input) {
  14887. if (input == null || typeof input === 'string') {
  14888. const hex = HSVtoHex(color);
  14889. if (color.a === 1) return hex.slice(0, 7);else return hex;
  14890. }
  14891. if (typeof input === 'object') {
  14892. let converted;
  14893. if (has(input, ['r', 'g', 'b'])) converted = HSVtoRGB(color);else if (has(input, ['h', 's', 'l'])) converted = HSVtoHSL(color);else if (has(input, ['h', 's', 'v'])) converted = color;
  14894. return stripAlpha(converted, !has(input, ['a']) && color.a === 1);
  14895. }
  14896. return color;
  14897. }
  14898. const nullColor = {
  14899. h: 0,
  14900. s: 0,
  14901. v: 0,
  14902. a: 1
  14903. };
  14904. const rgba = {
  14905. inputProps: {
  14906. type: 'number',
  14907. min: 0
  14908. },
  14909. inputs: [{
  14910. label: 'R',
  14911. max: 255,
  14912. step: 1,
  14913. getValue: c => Math.round(c.r),
  14914. getColor: (c, v) => ({
  14915. ...c,
  14916. r: Number(v)
  14917. })
  14918. }, {
  14919. label: 'G',
  14920. max: 255,
  14921. step: 1,
  14922. getValue: c => Math.round(c.g),
  14923. getColor: (c, v) => ({
  14924. ...c,
  14925. g: Number(v)
  14926. })
  14927. }, {
  14928. label: 'B',
  14929. max: 255,
  14930. step: 1,
  14931. getValue: c => Math.round(c.b),
  14932. getColor: (c, v) => ({
  14933. ...c,
  14934. b: Number(v)
  14935. })
  14936. }, {
  14937. label: 'A',
  14938. max: 1,
  14939. step: 0.01,
  14940. getValue: _ref => {
  14941. let {
  14942. a
  14943. } = _ref;
  14944. return a != null ? Math.round(a * 100) / 100 : 1;
  14945. },
  14946. getColor: (c, v) => ({
  14947. ...c,
  14948. a: Number(v)
  14949. })
  14950. }],
  14951. to: HSVtoRGB,
  14952. from: RGBtoHSV
  14953. };
  14954. const rgb = {
  14955. ...rgba,
  14956. inputs: rgba.inputs?.slice(0, 3)
  14957. };
  14958. const hsla = {
  14959. inputProps: {
  14960. type: 'number',
  14961. min: 0
  14962. },
  14963. inputs: [{
  14964. label: 'H',
  14965. max: 360,
  14966. step: 1,
  14967. getValue: c => Math.round(c.h),
  14968. getColor: (c, v) => ({
  14969. ...c,
  14970. h: Number(v)
  14971. })
  14972. }, {
  14973. label: 'S',
  14974. max: 1,
  14975. step: 0.01,
  14976. getValue: c => Math.round(c.s * 100) / 100,
  14977. getColor: (c, v) => ({
  14978. ...c,
  14979. s: Number(v)
  14980. })
  14981. }, {
  14982. label: 'L',
  14983. max: 1,
  14984. step: 0.01,
  14985. getValue: c => Math.round(c.l * 100) / 100,
  14986. getColor: (c, v) => ({
  14987. ...c,
  14988. l: Number(v)
  14989. })
  14990. }, {
  14991. label: 'A',
  14992. max: 1,
  14993. step: 0.01,
  14994. getValue: _ref2 => {
  14995. let {
  14996. a
  14997. } = _ref2;
  14998. return a != null ? Math.round(a * 100) / 100 : 1;
  14999. },
  15000. getColor: (c, v) => ({
  15001. ...c,
  15002. a: Number(v)
  15003. })
  15004. }],
  15005. to: HSVtoHSL,
  15006. from: HSLtoHSV
  15007. };
  15008. const hsl = {
  15009. ...hsla,
  15010. inputs: hsla.inputs.slice(0, 3)
  15011. };
  15012. const hexa = {
  15013. inputProps: {
  15014. type: 'text'
  15015. },
  15016. inputs: [{
  15017. label: 'HEXA',
  15018. getValue: c => c,
  15019. getColor: (c, v) => v
  15020. }],
  15021. to: HSVtoHex,
  15022. from: HexToHSV
  15023. };
  15024. const hex = {
  15025. ...hexa,
  15026. inputs: [{
  15027. label: 'HEX',
  15028. getValue: c => c.slice(0, 7),
  15029. getColor: (c, v) => v
  15030. }]
  15031. };
  15032. const modes = {
  15033. rgb,
  15034. rgba,
  15035. hsl,
  15036. hsla,
  15037. hex,
  15038. hexa
  15039. };
  15040. // Types
  15041. const VColorPickerInput = _ref => {
  15042. let {
  15043. label,
  15044. ...rest
  15045. } = _ref;
  15046. return createVNode("div", {
  15047. "class": "v-color-picker-edit__input"
  15048. }, [createVNode("input", rest, null), createVNode("span", null, [label])]);
  15049. };
  15050. const makeVColorPickerEditProps = propsFactory({
  15051. color: Object,
  15052. disabled: Boolean,
  15053. mode: {
  15054. type: String,
  15055. default: 'rgba',
  15056. validator: v => Object.keys(modes).includes(v)
  15057. },
  15058. modes: {
  15059. type: Array,
  15060. default: () => Object.keys(modes),
  15061. validator: v => Array.isArray(v) && v.every(m => Object.keys(modes).includes(m))
  15062. },
  15063. ...makeComponentProps()
  15064. }, 'VColorPickerEdit');
  15065. const VColorPickerEdit = defineComponent({
  15066. name: 'VColorPickerEdit',
  15067. props: makeVColorPickerEditProps(),
  15068. emits: {
  15069. 'update:color': color => true,
  15070. 'update:mode': mode => true
  15071. },
  15072. setup(props, _ref2) {
  15073. let {
  15074. emit
  15075. } = _ref2;
  15076. const enabledModes = computed(() => {
  15077. return props.modes.map(key => ({
  15078. ...modes[key],
  15079. name: key
  15080. }));
  15081. });
  15082. const inputs = computed(() => {
  15083. const mode = enabledModes.value.find(m => m.name === props.mode);
  15084. if (!mode) return [];
  15085. const color = props.color ? mode.to(props.color) : null;
  15086. return mode.inputs?.map(_ref3 => {
  15087. let {
  15088. getValue,
  15089. getColor,
  15090. ...inputProps
  15091. } = _ref3;
  15092. return {
  15093. ...mode.inputProps,
  15094. ...inputProps,
  15095. disabled: props.disabled,
  15096. value: color && getValue(color),
  15097. onChange: e => {
  15098. const target = e.target;
  15099. if (!target) return;
  15100. emit('update:color', mode.from(getColor(color ?? mode.to(nullColor), target.value)));
  15101. }
  15102. };
  15103. });
  15104. });
  15105. useRender(() => createVNode("div", {
  15106. "class": ['v-color-picker-edit', props.class],
  15107. "style": props.style
  15108. }, [inputs.value?.map(props => createVNode(VColorPickerInput, props, null)), enabledModes.value.length > 1 && createVNode(VBtn, {
  15109. "icon": "$unfold",
  15110. "size": "x-small",
  15111. "variant": "plain",
  15112. "onClick": () => {
  15113. const mi = enabledModes.value.findIndex(m => m.name === props.mode);
  15114. emit('update:mode', enabledModes.value[(mi + 1) % enabledModes.value.length].name);
  15115. }
  15116. }, null)]));
  15117. return {};
  15118. }
  15119. });
  15120. /* eslint-disable max-statements */
  15121. // Composables
  15122. // Types
  15123. const VSliderSymbol = Symbol.for('vuetify:v-slider');
  15124. function getOffset(e, el, direction) {
  15125. const vertical = direction === 'vertical';
  15126. const rect = el.getBoundingClientRect();
  15127. const touch = 'touches' in e ? e.touches[0] : e;
  15128. return vertical ? touch.clientY - (rect.top + rect.height / 2) : touch.clientX - (rect.left + rect.width / 2);
  15129. }
  15130. function getPosition(e, position) {
  15131. if ('touches' in e && e.touches.length) return e.touches[0][position];else if ('changedTouches' in e && e.changedTouches.length) return e.changedTouches[0][position];else return e[position];
  15132. }
  15133. const makeSliderProps = propsFactory({
  15134. disabled: {
  15135. type: Boolean,
  15136. default: null
  15137. },
  15138. error: Boolean,
  15139. readonly: {
  15140. type: Boolean,
  15141. default: null
  15142. },
  15143. max: {
  15144. type: [Number, String],
  15145. default: 100
  15146. },
  15147. min: {
  15148. type: [Number, String],
  15149. default: 0
  15150. },
  15151. step: {
  15152. type: [Number, String],
  15153. default: 0
  15154. },
  15155. thumbColor: String,
  15156. thumbLabel: {
  15157. type: [Boolean, String],
  15158. default: undefined,
  15159. validator: v => typeof v === 'boolean' || v === 'always'
  15160. },
  15161. thumbSize: {
  15162. type: [Number, String],
  15163. default: 20
  15164. },
  15165. showTicks: {
  15166. type: [Boolean, String],
  15167. default: false,
  15168. validator: v => typeof v === 'boolean' || v === 'always'
  15169. },
  15170. ticks: {
  15171. type: [Array, Object]
  15172. },
  15173. tickSize: {
  15174. type: [Number, String],
  15175. default: 2
  15176. },
  15177. color: String,
  15178. trackColor: String,
  15179. trackFillColor: String,
  15180. trackSize: {
  15181. type: [Number, String],
  15182. default: 4
  15183. },
  15184. direction: {
  15185. type: String,
  15186. default: 'horizontal',
  15187. validator: v => ['vertical', 'horizontal'].includes(v)
  15188. },
  15189. reverse: Boolean,
  15190. ...makeRoundedProps(),
  15191. ...makeElevationProps({
  15192. elevation: 2
  15193. }),
  15194. ripple: {
  15195. type: Boolean,
  15196. default: true
  15197. }
  15198. }, 'Slider');
  15199. const useSteps = props => {
  15200. const min = computed(() => parseFloat(props.min));
  15201. const max = computed(() => parseFloat(props.max));
  15202. const step = computed(() => +props.step > 0 ? parseFloat(props.step) : 0);
  15203. const decimals = computed(() => Math.max(getDecimals(step.value), getDecimals(min.value)));
  15204. function roundValue(value) {
  15205. value = parseFloat(value);
  15206. if (step.value <= 0) return value;
  15207. const clamped = clamp(value, min.value, max.value);
  15208. const offset = min.value % step.value;
  15209. const newValue = Math.round((clamped - offset) / step.value) * step.value + offset;
  15210. return parseFloat(Math.min(newValue, max.value).toFixed(decimals.value));
  15211. }
  15212. return {
  15213. min,
  15214. max,
  15215. step,
  15216. decimals,
  15217. roundValue
  15218. };
  15219. };
  15220. const useSlider = _ref => {
  15221. let {
  15222. props,
  15223. steps,
  15224. onSliderStart,
  15225. onSliderMove,
  15226. onSliderEnd,
  15227. getActiveThumb
  15228. } = _ref;
  15229. const {
  15230. isRtl
  15231. } = useRtl();
  15232. const isReversed = toRef(props, 'reverse');
  15233. const vertical = computed(() => props.direction === 'vertical');
  15234. const indexFromEnd = computed(() => vertical.value !== isReversed.value);
  15235. const {
  15236. min,
  15237. max,
  15238. step,
  15239. decimals,
  15240. roundValue
  15241. } = steps;
  15242. const thumbSize = computed(() => parseInt(props.thumbSize, 10));
  15243. const tickSize = computed(() => parseInt(props.tickSize, 10));
  15244. const trackSize = computed(() => parseInt(props.trackSize, 10));
  15245. const numTicks = computed(() => (max.value - min.value) / step.value);
  15246. const disabled = toRef(props, 'disabled');
  15247. const thumbColor = computed(() => props.error || props.disabled ? undefined : props.thumbColor ?? props.color);
  15248. const trackColor = computed(() => props.error || props.disabled ? undefined : props.trackColor ?? props.color);
  15249. const trackFillColor = computed(() => props.error || props.disabled ? undefined : props.trackFillColor ?? props.color);
  15250. const mousePressed = shallowRef(false);
  15251. const startOffset = shallowRef(0);
  15252. const trackContainerRef = ref();
  15253. const activeThumbRef = ref();
  15254. function parseMouseMove(e) {
  15255. const vertical = props.direction === 'vertical';
  15256. const start = vertical ? 'top' : 'left';
  15257. const length = vertical ? 'height' : 'width';
  15258. const position = vertical ? 'clientY' : 'clientX';
  15259. const {
  15260. [start]: trackStart,
  15261. [length]: trackLength
  15262. } = trackContainerRef.value?.$el.getBoundingClientRect();
  15263. const clickOffset = getPosition(e, position);
  15264. // It is possible for left to be NaN, force to number
  15265. let clickPos = Math.min(Math.max((clickOffset - trackStart - startOffset.value) / trackLength, 0), 1) || 0;
  15266. if (vertical ? indexFromEnd.value : indexFromEnd.value !== isRtl.value) clickPos = 1 - clickPos;
  15267. return roundValue(min.value + clickPos * (max.value - min.value));
  15268. }
  15269. const handleStop = e => {
  15270. onSliderEnd({
  15271. value: parseMouseMove(e)
  15272. });
  15273. mousePressed.value = false;
  15274. startOffset.value = 0;
  15275. };
  15276. const handleStart = e => {
  15277. activeThumbRef.value = getActiveThumb(e);
  15278. if (!activeThumbRef.value) return;
  15279. activeThumbRef.value.focus();
  15280. mousePressed.value = true;
  15281. if (activeThumbRef.value.contains(e.target)) {
  15282. startOffset.value = getOffset(e, activeThumbRef.value, props.direction);
  15283. } else {
  15284. startOffset.value = 0;
  15285. onSliderMove({
  15286. value: parseMouseMove(e)
  15287. });
  15288. }
  15289. onSliderStart({
  15290. value: parseMouseMove(e)
  15291. });
  15292. };
  15293. const moveListenerOptions = {
  15294. passive: true,
  15295. capture: true
  15296. };
  15297. function onMouseMove(e) {
  15298. onSliderMove({
  15299. value: parseMouseMove(e)
  15300. });
  15301. }
  15302. function onSliderMouseUp(e) {
  15303. e.stopPropagation();
  15304. e.preventDefault();
  15305. handleStop(e);
  15306. window.removeEventListener('mousemove', onMouseMove, moveListenerOptions);
  15307. window.removeEventListener('mouseup', onSliderMouseUp);
  15308. }
  15309. function onSliderTouchend(e) {
  15310. handleStop(e);
  15311. window.removeEventListener('touchmove', onMouseMove, moveListenerOptions);
  15312. e.target?.removeEventListener('touchend', onSliderTouchend);
  15313. }
  15314. function onSliderTouchstart(e) {
  15315. handleStart(e);
  15316. window.addEventListener('touchmove', onMouseMove, moveListenerOptions);
  15317. e.target?.addEventListener('touchend', onSliderTouchend, {
  15318. passive: false
  15319. });
  15320. }
  15321. function onSliderMousedown(e) {
  15322. e.preventDefault();
  15323. handleStart(e);
  15324. window.addEventListener('mousemove', onMouseMove, moveListenerOptions);
  15325. window.addEventListener('mouseup', onSliderMouseUp, {
  15326. passive: false
  15327. });
  15328. }
  15329. const position = val => {
  15330. const percentage = (val - min.value) / (max.value - min.value) * 100;
  15331. return clamp(isNaN(percentage) ? 0 : percentage, 0, 100);
  15332. };
  15333. const showTicks = toRef(props, 'showTicks');
  15334. const parsedTicks = computed(() => {
  15335. if (!showTicks.value) return [];
  15336. if (!props.ticks) {
  15337. return numTicks.value !== Infinity ? createRange(numTicks.value + 1).map(t => {
  15338. const value = min.value + t * step.value;
  15339. return {
  15340. value,
  15341. position: position(value)
  15342. };
  15343. }) : [];
  15344. }
  15345. if (Array.isArray(props.ticks)) return props.ticks.map(t => ({
  15346. value: t,
  15347. position: position(t),
  15348. label: t.toString()
  15349. }));
  15350. return Object.keys(props.ticks).map(key => ({
  15351. value: parseFloat(key),
  15352. position: position(parseFloat(key)),
  15353. label: props.ticks[key]
  15354. }));
  15355. });
  15356. const hasLabels = computed(() => parsedTicks.value.some(_ref2 => {
  15357. let {
  15358. label
  15359. } = _ref2;
  15360. return !!label;
  15361. }));
  15362. const data = {
  15363. activeThumbRef,
  15364. color: toRef(props, 'color'),
  15365. decimals,
  15366. disabled,
  15367. direction: toRef(props, 'direction'),
  15368. elevation: toRef(props, 'elevation'),
  15369. hasLabels,
  15370. isReversed,
  15371. indexFromEnd,
  15372. min,
  15373. max,
  15374. mousePressed,
  15375. numTicks,
  15376. onSliderMousedown,
  15377. onSliderTouchstart,
  15378. parsedTicks,
  15379. parseMouseMove,
  15380. position,
  15381. readonly: toRef(props, 'readonly'),
  15382. rounded: toRef(props, 'rounded'),
  15383. roundValue,
  15384. showTicks,
  15385. startOffset,
  15386. step,
  15387. thumbSize,
  15388. thumbColor,
  15389. thumbLabel: toRef(props, 'thumbLabel'),
  15390. ticks: toRef(props, 'ticks'),
  15391. tickSize,
  15392. trackColor,
  15393. trackContainerRef,
  15394. trackFillColor,
  15395. trackSize,
  15396. vertical
  15397. };
  15398. provide(VSliderSymbol, data);
  15399. return data;
  15400. };
  15401. // Types
  15402. const makeVSliderThumbProps = propsFactory({
  15403. focused: Boolean,
  15404. max: {
  15405. type: Number,
  15406. required: true
  15407. },
  15408. min: {
  15409. type: Number,
  15410. required: true
  15411. },
  15412. modelValue: {
  15413. type: Number,
  15414. required: true
  15415. },
  15416. position: {
  15417. type: Number,
  15418. required: true
  15419. },
  15420. ripple: {
  15421. type: [Boolean, Object],
  15422. default: true
  15423. },
  15424. name: String,
  15425. ...makeComponentProps()
  15426. }, 'VSliderThumb');
  15427. const VSliderThumb = genericComponent()({
  15428. name: 'VSliderThumb',
  15429. directives: {
  15430. Ripple
  15431. },
  15432. props: makeVSliderThumbProps(),
  15433. emits: {
  15434. 'update:modelValue': v => true
  15435. },
  15436. setup(props, _ref) {
  15437. let {
  15438. slots,
  15439. emit
  15440. } = _ref;
  15441. const slider = inject$1(VSliderSymbol);
  15442. const {
  15443. isRtl,
  15444. rtlClasses
  15445. } = useRtl();
  15446. if (!slider) throw new Error('[Vuetify] v-slider-thumb must be used inside v-slider or v-range-slider');
  15447. const {
  15448. thumbColor,
  15449. step,
  15450. disabled,
  15451. thumbSize,
  15452. thumbLabel,
  15453. direction,
  15454. isReversed,
  15455. vertical,
  15456. readonly,
  15457. elevation,
  15458. mousePressed,
  15459. decimals,
  15460. indexFromEnd
  15461. } = slider;
  15462. const elevationProps = computed(() => !disabled.value ? elevation.value : undefined);
  15463. const {
  15464. elevationClasses
  15465. } = useElevation(elevationProps);
  15466. const {
  15467. textColorClasses,
  15468. textColorStyles
  15469. } = useTextColor(thumbColor);
  15470. const {
  15471. pageup,
  15472. pagedown,
  15473. end,
  15474. home,
  15475. left,
  15476. right,
  15477. down,
  15478. up
  15479. } = keyValues;
  15480. const relevantKeys = [pageup, pagedown, end, home, left, right, down, up];
  15481. const multipliers = computed(() => {
  15482. if (step.value) return [1, 2, 3];else return [1, 5, 10];
  15483. });
  15484. function parseKeydown(e, value) {
  15485. if (!relevantKeys.includes(e.key)) return;
  15486. e.preventDefault();
  15487. const _step = step.value || 0.1;
  15488. const steps = (props.max - props.min) / _step;
  15489. if ([left, right, down, up].includes(e.key)) {
  15490. const increase = vertical.value ? [isRtl.value ? left : right, isReversed.value ? down : up] : indexFromEnd.value !== isRtl.value ? [left, up] : [right, up];
  15491. const direction = increase.includes(e.key) ? 1 : -1;
  15492. const multiplier = e.shiftKey ? 2 : e.ctrlKey ? 1 : 0;
  15493. value = value + direction * _step * multipliers.value[multiplier];
  15494. } else if (e.key === home) {
  15495. value = props.min;
  15496. } else if (e.key === end) {
  15497. value = props.max;
  15498. } else {
  15499. const direction = e.key === pagedown ? 1 : -1;
  15500. value = value - direction * _step * (steps > 100 ? steps / 10 : 10);
  15501. }
  15502. return Math.max(props.min, Math.min(props.max, value));
  15503. }
  15504. function onKeydown(e) {
  15505. const newValue = parseKeydown(e, props.modelValue);
  15506. newValue != null && emit('update:modelValue', newValue);
  15507. }
  15508. useRender(() => {
  15509. const positionPercentage = convertToUnit(indexFromEnd.value ? 100 - props.position : props.position, '%');
  15510. return createVNode("div", {
  15511. "class": ['v-slider-thumb', {
  15512. 'v-slider-thumb--focused': props.focused,
  15513. 'v-slider-thumb--pressed': props.focused && mousePressed.value
  15514. }, props.class, rtlClasses.value],
  15515. "style": [{
  15516. '--v-slider-thumb-position': positionPercentage,
  15517. '--v-slider-thumb-size': convertToUnit(thumbSize.value)
  15518. }, props.style],
  15519. "role": "slider",
  15520. "tabindex": disabled.value ? -1 : 0,
  15521. "aria-label": props.name,
  15522. "aria-valuemin": props.min,
  15523. "aria-valuemax": props.max,
  15524. "aria-valuenow": props.modelValue,
  15525. "aria-readonly": !!readonly.value,
  15526. "aria-orientation": direction.value,
  15527. "onKeydown": !readonly.value ? onKeydown : undefined
  15528. }, [createVNode("div", {
  15529. "class": ['v-slider-thumb__surface', textColorClasses.value, elevationClasses.value],
  15530. "style": {
  15531. ...textColorStyles.value
  15532. }
  15533. }, null), withDirectives(createVNode("div", {
  15534. "class": ['v-slider-thumb__ripple', textColorClasses.value],
  15535. "style": textColorStyles.value
  15536. }, null), [[resolveDirective("ripple"), props.ripple, null, {
  15537. circle: true,
  15538. center: true
  15539. }]]), createVNode(VScaleTransition, {
  15540. "origin": "bottom center"
  15541. }, {
  15542. default: () => [withDirectives(createVNode("div", {
  15543. "class": "v-slider-thumb__label-container"
  15544. }, [createVNode("div", {
  15545. "class": ['v-slider-thumb__label']
  15546. }, [createVNode("div", null, [slots['thumb-label']?.({
  15547. modelValue: props.modelValue
  15548. }) ?? props.modelValue.toFixed(step.value ? decimals.value : 1)])])]), [[vShow, thumbLabel.value && props.focused || thumbLabel.value === 'always']])]
  15549. })]);
  15550. });
  15551. return {};
  15552. }
  15553. });
  15554. // Types
  15555. const makeVSliderTrackProps = propsFactory({
  15556. start: {
  15557. type: Number,
  15558. required: true
  15559. },
  15560. stop: {
  15561. type: Number,
  15562. required: true
  15563. },
  15564. ...makeComponentProps()
  15565. }, 'VSliderTrack');
  15566. const VSliderTrack = genericComponent()({
  15567. name: 'VSliderTrack',
  15568. props: makeVSliderTrackProps(),
  15569. emits: {},
  15570. setup(props, _ref) {
  15571. let {
  15572. slots
  15573. } = _ref;
  15574. const slider = inject$1(VSliderSymbol);
  15575. if (!slider) throw new Error('[Vuetify] v-slider-track must be inside v-slider or v-range-slider');
  15576. const {
  15577. color,
  15578. parsedTicks,
  15579. rounded,
  15580. showTicks,
  15581. tickSize,
  15582. trackColor,
  15583. trackFillColor,
  15584. trackSize,
  15585. vertical,
  15586. min,
  15587. max,
  15588. indexFromEnd
  15589. } = slider;
  15590. const {
  15591. roundedClasses
  15592. } = useRounded(rounded);
  15593. const {
  15594. backgroundColorClasses: trackFillColorClasses,
  15595. backgroundColorStyles: trackFillColorStyles
  15596. } = useBackgroundColor(trackFillColor);
  15597. const {
  15598. backgroundColorClasses: trackColorClasses,
  15599. backgroundColorStyles: trackColorStyles
  15600. } = useBackgroundColor(trackColor);
  15601. const startDir = computed(() => `inset-${vertical.value ? 'block' : 'inline'}-${indexFromEnd.value ? 'end' : 'start'}`);
  15602. const endDir = computed(() => vertical.value ? 'height' : 'width');
  15603. const backgroundStyles = computed(() => {
  15604. return {
  15605. [startDir.value]: '0%',
  15606. [endDir.value]: '100%'
  15607. };
  15608. });
  15609. const trackFillWidth = computed(() => props.stop - props.start);
  15610. const trackFillStyles = computed(() => {
  15611. return {
  15612. [startDir.value]: convertToUnit(props.start, '%'),
  15613. [endDir.value]: convertToUnit(trackFillWidth.value, '%')
  15614. };
  15615. });
  15616. const computedTicks = computed(() => {
  15617. if (!showTicks.value) return [];
  15618. const ticks = vertical.value ? parsedTicks.value.slice().reverse() : parsedTicks.value;
  15619. return ticks.map((tick, index) => {
  15620. const directionValue = tick.value !== min.value && tick.value !== max.value ? convertToUnit(tick.position, '%') : undefined;
  15621. return createVNode("div", {
  15622. "key": tick.value,
  15623. "class": ['v-slider-track__tick', {
  15624. 'v-slider-track__tick--filled': tick.position >= props.start && tick.position <= props.stop,
  15625. 'v-slider-track__tick--first': tick.value === min.value,
  15626. 'v-slider-track__tick--last': tick.value === max.value
  15627. }],
  15628. "style": {
  15629. [startDir.value]: directionValue
  15630. }
  15631. }, [(tick.label || slots['tick-label']) && createVNode("div", {
  15632. "class": "v-slider-track__tick-label"
  15633. }, [slots['tick-label']?.({
  15634. tick,
  15635. index
  15636. }) ?? tick.label])]);
  15637. });
  15638. });
  15639. useRender(() => {
  15640. return createVNode("div", {
  15641. "class": ['v-slider-track', roundedClasses.value, props.class],
  15642. "style": [{
  15643. '--v-slider-track-size': convertToUnit(trackSize.value),
  15644. '--v-slider-tick-size': convertToUnit(tickSize.value)
  15645. }, props.style]
  15646. }, [createVNode("div", {
  15647. "class": ['v-slider-track__background', trackColorClasses.value, {
  15648. 'v-slider-track__background--opacity': !!color.value || !trackFillColor.value
  15649. }],
  15650. "style": {
  15651. ...backgroundStyles.value,
  15652. ...trackColorStyles.value
  15653. }
  15654. }, null), createVNode("div", {
  15655. "class": ['v-slider-track__fill', trackFillColorClasses.value],
  15656. "style": {
  15657. ...trackFillStyles.value,
  15658. ...trackFillColorStyles.value
  15659. }
  15660. }, null), showTicks.value && createVNode("div", {
  15661. "class": ['v-slider-track__ticks', {
  15662. 'v-slider-track__ticks--always-show': showTicks.value === 'always'
  15663. }]
  15664. }, [computedTicks.value])]);
  15665. });
  15666. return {};
  15667. }
  15668. });
  15669. // Types
  15670. const makeVSliderProps = propsFactory({
  15671. ...makeFocusProps(),
  15672. ...makeSliderProps(),
  15673. ...makeVInputProps(),
  15674. modelValue: {
  15675. type: [Number, String],
  15676. default: 0
  15677. }
  15678. }, 'VSlider');
  15679. const VSlider = genericComponent()({
  15680. name: 'VSlider',
  15681. props: makeVSliderProps(),
  15682. emits: {
  15683. 'update:focused': value => true,
  15684. 'update:modelValue': v => true,
  15685. start: value => true,
  15686. end: value => true
  15687. },
  15688. setup(props, _ref) {
  15689. let {
  15690. slots,
  15691. emit
  15692. } = _ref;
  15693. const thumbContainerRef = ref();
  15694. const {
  15695. rtlClasses
  15696. } = useRtl();
  15697. const steps = useSteps(props);
  15698. const model = useProxiedModel(props, 'modelValue', undefined, value => {
  15699. return steps.roundValue(value == null ? steps.min.value : value);
  15700. });
  15701. const {
  15702. min,
  15703. max,
  15704. mousePressed,
  15705. roundValue,
  15706. onSliderMousedown,
  15707. onSliderTouchstart,
  15708. trackContainerRef,
  15709. position,
  15710. hasLabels,
  15711. readonly
  15712. } = useSlider({
  15713. props,
  15714. steps,
  15715. onSliderStart: () => {
  15716. emit('start', model.value);
  15717. },
  15718. onSliderEnd: _ref2 => {
  15719. let {
  15720. value
  15721. } = _ref2;
  15722. const roundedValue = roundValue(value);
  15723. model.value = roundedValue;
  15724. emit('end', roundedValue);
  15725. },
  15726. onSliderMove: _ref3 => {
  15727. let {
  15728. value
  15729. } = _ref3;
  15730. return model.value = roundValue(value);
  15731. },
  15732. getActiveThumb: () => thumbContainerRef.value?.$el
  15733. });
  15734. const {
  15735. isFocused,
  15736. focus,
  15737. blur
  15738. } = useFocus(props);
  15739. const trackStop = computed(() => position(model.value));
  15740. useRender(() => {
  15741. const inputProps = VInput.filterProps(props);
  15742. const hasPrepend = !!(props.label || slots.label || slots.prepend);
  15743. return createVNode(VInput, mergeProps({
  15744. "class": ['v-slider', {
  15745. 'v-slider--has-labels': !!slots['tick-label'] || hasLabels.value,
  15746. 'v-slider--focused': isFocused.value,
  15747. 'v-slider--pressed': mousePressed.value,
  15748. 'v-slider--disabled': props.disabled
  15749. }, rtlClasses.value, props.class],
  15750. "style": props.style
  15751. }, inputProps, {
  15752. "focused": isFocused.value
  15753. }), {
  15754. ...slots,
  15755. prepend: hasPrepend ? slotProps => createVNode(Fragment, null, [slots.label?.(slotProps) ?? (props.label ? createVNode(VLabel, {
  15756. "id": slotProps.id.value,
  15757. "class": "v-slider__label",
  15758. "text": props.label
  15759. }, null) : undefined), slots.prepend?.(slotProps)]) : undefined,
  15760. default: _ref4 => {
  15761. let {
  15762. id,
  15763. messagesId
  15764. } = _ref4;
  15765. return createVNode("div", {
  15766. "class": "v-slider__container",
  15767. "onMousedown": !readonly.value ? onSliderMousedown : undefined,
  15768. "onTouchstartPassive": !readonly.value ? onSliderTouchstart : undefined
  15769. }, [createVNode("input", {
  15770. "id": id.value,
  15771. "name": props.name || id.value,
  15772. "disabled": !!props.disabled,
  15773. "readonly": !!props.readonly,
  15774. "tabindex": "-1",
  15775. "value": model.value
  15776. }, null), createVNode(VSliderTrack, {
  15777. "ref": trackContainerRef,
  15778. "start": 0,
  15779. "stop": trackStop.value
  15780. }, {
  15781. 'tick-label': slots['tick-label']
  15782. }), createVNode(VSliderThumb, {
  15783. "ref": thumbContainerRef,
  15784. "aria-describedby": messagesId.value,
  15785. "focused": isFocused.value,
  15786. "min": min.value,
  15787. "max": max.value,
  15788. "modelValue": model.value,
  15789. "onUpdate:modelValue": v => model.value = v,
  15790. "position": trackStop.value,
  15791. "elevation": props.elevation,
  15792. "onFocus": focus,
  15793. "onBlur": blur,
  15794. "ripple": props.ripple,
  15795. "name": props.name
  15796. }, {
  15797. 'thumb-label': slots['thumb-label']
  15798. })]);
  15799. }
  15800. });
  15801. });
  15802. return {};
  15803. }
  15804. });
  15805. // Types
  15806. const makeVColorPickerPreviewProps = propsFactory({
  15807. color: {
  15808. type: Object
  15809. },
  15810. disabled: Boolean,
  15811. hideAlpha: Boolean,
  15812. ...makeComponentProps()
  15813. }, 'VColorPickerPreview');
  15814. const VColorPickerPreview = defineComponent({
  15815. name: 'VColorPickerPreview',
  15816. props: makeVColorPickerPreviewProps(),
  15817. emits: {
  15818. 'update:color': color => true
  15819. },
  15820. setup(props, _ref) {
  15821. let {
  15822. emit
  15823. } = _ref;
  15824. const abortController = new AbortController();
  15825. onUnmounted(() => abortController.abort());
  15826. async function openEyeDropper() {
  15827. if (!SUPPORTS_EYE_DROPPER) return;
  15828. const eyeDropper = new window.EyeDropper();
  15829. try {
  15830. const result = await eyeDropper.open({
  15831. signal: abortController.signal
  15832. });
  15833. const colorHexValue = HexToHSV(result.sRGBHex);
  15834. emit('update:color', {
  15835. ...(props.color ?? nullColor),
  15836. ...colorHexValue
  15837. });
  15838. } catch (e) {}
  15839. }
  15840. useRender(() => createVNode("div", {
  15841. "class": ['v-color-picker-preview', {
  15842. 'v-color-picker-preview--hide-alpha': props.hideAlpha
  15843. }, props.class],
  15844. "style": props.style
  15845. }, [SUPPORTS_EYE_DROPPER && createVNode("div", {
  15846. "class": "v-color-picker-preview__eye-dropper",
  15847. "key": "eyeDropper"
  15848. }, [createVNode(VBtn, {
  15849. "onClick": openEyeDropper,
  15850. "icon": "$eyeDropper",
  15851. "variant": "plain",
  15852. "density": "comfortable"
  15853. }, null)]), createVNode("div", {
  15854. "class": "v-color-picker-preview__dot"
  15855. }, [createVNode("div", {
  15856. "style": {
  15857. background: HSVtoCSS(props.color ?? nullColor)
  15858. }
  15859. }, null)]), createVNode("div", {
  15860. "class": "v-color-picker-preview__sliders"
  15861. }, [createVNode(VSlider, {
  15862. "class": "v-color-picker-preview__track v-color-picker-preview__hue",
  15863. "modelValue": props.color?.h,
  15864. "onUpdate:modelValue": h => emit('update:color', {
  15865. ...(props.color ?? nullColor),
  15866. h
  15867. }),
  15868. "step": 0,
  15869. "min": 0,
  15870. "max": 360,
  15871. "disabled": props.disabled,
  15872. "thumbSize": 14,
  15873. "trackSize": 8,
  15874. "trackFillColor": "white",
  15875. "hideDetails": true
  15876. }, null), !props.hideAlpha && createVNode(VSlider, {
  15877. "class": "v-color-picker-preview__track v-color-picker-preview__alpha",
  15878. "modelValue": props.color?.a ?? 1,
  15879. "onUpdate:modelValue": a => emit('update:color', {
  15880. ...(props.color ?? nullColor),
  15881. a
  15882. }),
  15883. "step": 1 / 256,
  15884. "min": 0,
  15885. "max": 1,
  15886. "disabled": props.disabled,
  15887. "thumbSize": 14,
  15888. "trackSize": 8,
  15889. "trackFillColor": "white",
  15890. "hideDetails": true
  15891. }, null)])]));
  15892. return {};
  15893. }
  15894. });
  15895. const red = {
  15896. base: '#f44336',
  15897. lighten5: '#ffebee',
  15898. lighten4: '#ffcdd2',
  15899. lighten3: '#ef9a9a',
  15900. lighten2: '#e57373',
  15901. lighten1: '#ef5350',
  15902. darken1: '#e53935',
  15903. darken2: '#d32f2f',
  15904. darken3: '#c62828',
  15905. darken4: '#b71c1c',
  15906. accent1: '#ff8a80',
  15907. accent2: '#ff5252',
  15908. accent3: '#ff1744',
  15909. accent4: '#d50000'
  15910. };
  15911. const pink = {
  15912. base: '#e91e63',
  15913. lighten5: '#fce4ec',
  15914. lighten4: '#f8bbd0',
  15915. lighten3: '#f48fb1',
  15916. lighten2: '#f06292',
  15917. lighten1: '#ec407a',
  15918. darken1: '#d81b60',
  15919. darken2: '#c2185b',
  15920. darken3: '#ad1457',
  15921. darken4: '#880e4f',
  15922. accent1: '#ff80ab',
  15923. accent2: '#ff4081',
  15924. accent3: '#f50057',
  15925. accent4: '#c51162'
  15926. };
  15927. const purple = {
  15928. base: '#9c27b0',
  15929. lighten5: '#f3e5f5',
  15930. lighten4: '#e1bee7',
  15931. lighten3: '#ce93d8',
  15932. lighten2: '#ba68c8',
  15933. lighten1: '#ab47bc',
  15934. darken1: '#8e24aa',
  15935. darken2: '#7b1fa2',
  15936. darken3: '#6a1b9a',
  15937. darken4: '#4a148c',
  15938. accent1: '#ea80fc',
  15939. accent2: '#e040fb',
  15940. accent3: '#d500f9',
  15941. accent4: '#aa00ff'
  15942. };
  15943. const deepPurple = {
  15944. base: '#673ab7',
  15945. lighten5: '#ede7f6',
  15946. lighten4: '#d1c4e9',
  15947. lighten3: '#b39ddb',
  15948. lighten2: '#9575cd',
  15949. lighten1: '#7e57c2',
  15950. darken1: '#5e35b1',
  15951. darken2: '#512da8',
  15952. darken3: '#4527a0',
  15953. darken4: '#311b92',
  15954. accent1: '#b388ff',
  15955. accent2: '#7c4dff',
  15956. accent3: '#651fff',
  15957. accent4: '#6200ea'
  15958. };
  15959. const indigo = {
  15960. base: '#3f51b5',
  15961. lighten5: '#e8eaf6',
  15962. lighten4: '#c5cae9',
  15963. lighten3: '#9fa8da',
  15964. lighten2: '#7986cb',
  15965. lighten1: '#5c6bc0',
  15966. darken1: '#3949ab',
  15967. darken2: '#303f9f',
  15968. darken3: '#283593',
  15969. darken4: '#1a237e',
  15970. accent1: '#8c9eff',
  15971. accent2: '#536dfe',
  15972. accent3: '#3d5afe',
  15973. accent4: '#304ffe'
  15974. };
  15975. const blue = {
  15976. base: '#2196f3',
  15977. lighten5: '#e3f2fd',
  15978. lighten4: '#bbdefb',
  15979. lighten3: '#90caf9',
  15980. lighten2: '#64b5f6',
  15981. lighten1: '#42a5f5',
  15982. darken1: '#1e88e5',
  15983. darken2: '#1976d2',
  15984. darken3: '#1565c0',
  15985. darken4: '#0d47a1',
  15986. accent1: '#82b1ff',
  15987. accent2: '#448aff',
  15988. accent3: '#2979ff',
  15989. accent4: '#2962ff'
  15990. };
  15991. const lightBlue = {
  15992. base: '#03a9f4',
  15993. lighten5: '#e1f5fe',
  15994. lighten4: '#b3e5fc',
  15995. lighten3: '#81d4fa',
  15996. lighten2: '#4fc3f7',
  15997. lighten1: '#29b6f6',
  15998. darken1: '#039be5',
  15999. darken2: '#0288d1',
  16000. darken3: '#0277bd',
  16001. darken4: '#01579b',
  16002. accent1: '#80d8ff',
  16003. accent2: '#40c4ff',
  16004. accent3: '#00b0ff',
  16005. accent4: '#0091ea'
  16006. };
  16007. const cyan = {
  16008. base: '#00bcd4',
  16009. lighten5: '#e0f7fa',
  16010. lighten4: '#b2ebf2',
  16011. lighten3: '#80deea',
  16012. lighten2: '#4dd0e1',
  16013. lighten1: '#26c6da',
  16014. darken1: '#00acc1',
  16015. darken2: '#0097a7',
  16016. darken3: '#00838f',
  16017. darken4: '#006064',
  16018. accent1: '#84ffff',
  16019. accent2: '#18ffff',
  16020. accent3: '#00e5ff',
  16021. accent4: '#00b8d4'
  16022. };
  16023. const teal = {
  16024. base: '#009688',
  16025. lighten5: '#e0f2f1',
  16026. lighten4: '#b2dfdb',
  16027. lighten3: '#80cbc4',
  16028. lighten2: '#4db6ac',
  16029. lighten1: '#26a69a',
  16030. darken1: '#00897b',
  16031. darken2: '#00796b',
  16032. darken3: '#00695c',
  16033. darken4: '#004d40',
  16034. accent1: '#a7ffeb',
  16035. accent2: '#64ffda',
  16036. accent3: '#1de9b6',
  16037. accent4: '#00bfa5'
  16038. };
  16039. const green = {
  16040. base: '#4caf50',
  16041. lighten5: '#e8f5e9',
  16042. lighten4: '#c8e6c9',
  16043. lighten3: '#a5d6a7',
  16044. lighten2: '#81c784',
  16045. lighten1: '#66bb6a',
  16046. darken1: '#43a047',
  16047. darken2: '#388e3c',
  16048. darken3: '#2e7d32',
  16049. darken4: '#1b5e20',
  16050. accent1: '#b9f6ca',
  16051. accent2: '#69f0ae',
  16052. accent3: '#00e676',
  16053. accent4: '#00c853'
  16054. };
  16055. const lightGreen = {
  16056. base: '#8bc34a',
  16057. lighten5: '#f1f8e9',
  16058. lighten4: '#dcedc8',
  16059. lighten3: '#c5e1a5',
  16060. lighten2: '#aed581',
  16061. lighten1: '#9ccc65',
  16062. darken1: '#7cb342',
  16063. darken2: '#689f38',
  16064. darken3: '#558b2f',
  16065. darken4: '#33691e',
  16066. accent1: '#ccff90',
  16067. accent2: '#b2ff59',
  16068. accent3: '#76ff03',
  16069. accent4: '#64dd17'
  16070. };
  16071. const lime = {
  16072. base: '#cddc39',
  16073. lighten5: '#f9fbe7',
  16074. lighten4: '#f0f4c3',
  16075. lighten3: '#e6ee9c',
  16076. lighten2: '#dce775',
  16077. lighten1: '#d4e157',
  16078. darken1: '#c0ca33',
  16079. darken2: '#afb42b',
  16080. darken3: '#9e9d24',
  16081. darken4: '#827717',
  16082. accent1: '#f4ff81',
  16083. accent2: '#eeff41',
  16084. accent3: '#c6ff00',
  16085. accent4: '#aeea00'
  16086. };
  16087. const yellow = {
  16088. base: '#ffeb3b',
  16089. lighten5: '#fffde7',
  16090. lighten4: '#fff9c4',
  16091. lighten3: '#fff59d',
  16092. lighten2: '#fff176',
  16093. lighten1: '#ffee58',
  16094. darken1: '#fdd835',
  16095. darken2: '#fbc02d',
  16096. darken3: '#f9a825',
  16097. darken4: '#f57f17',
  16098. accent1: '#ffff8d',
  16099. accent2: '#ffff00',
  16100. accent3: '#ffea00',
  16101. accent4: '#ffd600'
  16102. };
  16103. const amber = {
  16104. base: '#ffc107',
  16105. lighten5: '#fff8e1',
  16106. lighten4: '#ffecb3',
  16107. lighten3: '#ffe082',
  16108. lighten2: '#ffd54f',
  16109. lighten1: '#ffca28',
  16110. darken1: '#ffb300',
  16111. darken2: '#ffa000',
  16112. darken3: '#ff8f00',
  16113. darken4: '#ff6f00',
  16114. accent1: '#ffe57f',
  16115. accent2: '#ffd740',
  16116. accent3: '#ffc400',
  16117. accent4: '#ffab00'
  16118. };
  16119. const orange = {
  16120. base: '#ff9800',
  16121. lighten5: '#fff3e0',
  16122. lighten4: '#ffe0b2',
  16123. lighten3: '#ffcc80',
  16124. lighten2: '#ffb74d',
  16125. lighten1: '#ffa726',
  16126. darken1: '#fb8c00',
  16127. darken2: '#f57c00',
  16128. darken3: '#ef6c00',
  16129. darken4: '#e65100',
  16130. accent1: '#ffd180',
  16131. accent2: '#ffab40',
  16132. accent3: '#ff9100',
  16133. accent4: '#ff6d00'
  16134. };
  16135. const deepOrange = {
  16136. base: '#ff5722',
  16137. lighten5: '#fbe9e7',
  16138. lighten4: '#ffccbc',
  16139. lighten3: '#ffab91',
  16140. lighten2: '#ff8a65',
  16141. lighten1: '#ff7043',
  16142. darken1: '#f4511e',
  16143. darken2: '#e64a19',
  16144. darken3: '#d84315',
  16145. darken4: '#bf360c',
  16146. accent1: '#ff9e80',
  16147. accent2: '#ff6e40',
  16148. accent3: '#ff3d00',
  16149. accent4: '#dd2c00'
  16150. };
  16151. const brown = {
  16152. base: '#795548',
  16153. lighten5: '#efebe9',
  16154. lighten4: '#d7ccc8',
  16155. lighten3: '#bcaaa4',
  16156. lighten2: '#a1887f',
  16157. lighten1: '#8d6e63',
  16158. darken1: '#6d4c41',
  16159. darken2: '#5d4037',
  16160. darken3: '#4e342e',
  16161. darken4: '#3e2723'
  16162. };
  16163. const blueGrey = {
  16164. base: '#607d8b',
  16165. lighten5: '#eceff1',
  16166. lighten4: '#cfd8dc',
  16167. lighten3: '#b0bec5',
  16168. lighten2: '#90a4ae',
  16169. lighten1: '#78909c',
  16170. darken1: '#546e7a',
  16171. darken2: '#455a64',
  16172. darken3: '#37474f',
  16173. darken4: '#263238'
  16174. };
  16175. const grey = {
  16176. base: '#9e9e9e',
  16177. lighten5: '#fafafa',
  16178. lighten4: '#f5f5f5',
  16179. lighten3: '#eeeeee',
  16180. lighten2: '#e0e0e0',
  16181. lighten1: '#bdbdbd',
  16182. darken1: '#757575',
  16183. darken2: '#616161',
  16184. darken3: '#424242',
  16185. darken4: '#212121'
  16186. };
  16187. const shades = {
  16188. black: '#000000',
  16189. white: '#ffffff',
  16190. transparent: '#ffffff00'
  16191. };
  16192. var colors = {
  16193. red,
  16194. pink,
  16195. purple,
  16196. deepPurple,
  16197. indigo,
  16198. blue,
  16199. lightBlue,
  16200. cyan,
  16201. teal,
  16202. green,
  16203. lightGreen,
  16204. lime,
  16205. yellow,
  16206. amber,
  16207. orange,
  16208. deepOrange,
  16209. brown,
  16210. blueGrey,
  16211. grey,
  16212. shades
  16213. };
  16214. // Types
  16215. const makeVColorPickerSwatchesProps = propsFactory({
  16216. swatches: {
  16217. type: Array,
  16218. default: () => parseDefaultColors(colors)
  16219. },
  16220. disabled: Boolean,
  16221. color: Object,
  16222. maxHeight: [Number, String],
  16223. ...makeComponentProps()
  16224. }, 'VColorPickerSwatches');
  16225. function parseDefaultColors(colors) {
  16226. return Object.keys(colors).map(key => {
  16227. const color = colors[key];
  16228. return color.base ? [color.base, color.darken4, color.darken3, color.darken2, color.darken1, color.lighten1, color.lighten2, color.lighten3, color.lighten4, color.lighten5] : [color.black, color.white, color.transparent];
  16229. });
  16230. }
  16231. const VColorPickerSwatches = defineComponent({
  16232. name: 'VColorPickerSwatches',
  16233. props: makeVColorPickerSwatchesProps(),
  16234. emits: {
  16235. 'update:color': color => true
  16236. },
  16237. setup(props, _ref) {
  16238. let {
  16239. emit
  16240. } = _ref;
  16241. useRender(() => createVNode("div", {
  16242. "class": ['v-color-picker-swatches', props.class],
  16243. "style": [{
  16244. maxHeight: convertToUnit(props.maxHeight)
  16245. }, props.style]
  16246. }, [createVNode("div", null, [props.swatches.map(swatch => createVNode("div", {
  16247. "class": "v-color-picker-swatches__swatch"
  16248. }, [swatch.map(color => {
  16249. const rgba = parseColor(color);
  16250. const hsva = RGBtoHSV(rgba);
  16251. const background = RGBtoCSS(rgba);
  16252. return createVNode("div", {
  16253. "class": "v-color-picker-swatches__color",
  16254. "onClick": () => hsva && emit('update:color', hsva)
  16255. }, [createVNode("div", {
  16256. "style": {
  16257. background
  16258. }
  16259. }, [props.color && deepEqual(props.color, hsva) ? createVNode(VIcon, {
  16260. "size": "x-small",
  16261. "icon": "$success",
  16262. "color": getContrast(color, '#FFFFFF') > 2 ? 'white' : 'black'
  16263. }, null) : undefined])]);
  16264. })]))])]));
  16265. return {};
  16266. }
  16267. });
  16268. const makeVSheetProps = propsFactory({
  16269. color: String,
  16270. ...makeBorderProps(),
  16271. ...makeComponentProps(),
  16272. ...makeDimensionProps(),
  16273. ...makeElevationProps(),
  16274. ...makeLocationProps(),
  16275. ...makePositionProps(),
  16276. ...makeRoundedProps(),
  16277. ...makeTagProps(),
  16278. ...makeThemeProps()
  16279. }, 'VSheet');
  16280. const VSheet = genericComponent()({
  16281. name: 'VSheet',
  16282. props: makeVSheetProps(),
  16283. setup(props, _ref) {
  16284. let {
  16285. slots
  16286. } = _ref;
  16287. const {
  16288. themeClasses
  16289. } = provideTheme(props);
  16290. const {
  16291. backgroundColorClasses,
  16292. backgroundColorStyles
  16293. } = useBackgroundColor(toRef(props, 'color'));
  16294. const {
  16295. borderClasses
  16296. } = useBorder(props);
  16297. const {
  16298. dimensionStyles
  16299. } = useDimension(props);
  16300. const {
  16301. elevationClasses
  16302. } = useElevation(props);
  16303. const {
  16304. locationStyles
  16305. } = useLocation(props);
  16306. const {
  16307. positionClasses
  16308. } = usePosition(props);
  16309. const {
  16310. roundedClasses
  16311. } = useRounded(props);
  16312. useRender(() => createVNode(props.tag, {
  16313. "class": ['v-sheet', themeClasses.value, backgroundColorClasses.value, borderClasses.value, elevationClasses.value, positionClasses.value, roundedClasses.value, props.class],
  16314. "style": [backgroundColorStyles.value, dimensionStyles.value, locationStyles.value, props.style]
  16315. }, slots));
  16316. return {};
  16317. }
  16318. });
  16319. // Types
  16320. const makeVColorPickerProps = propsFactory({
  16321. canvasHeight: {
  16322. type: [String, Number],
  16323. default: 150
  16324. },
  16325. disabled: Boolean,
  16326. dotSize: {
  16327. type: [Number, String],
  16328. default: 10
  16329. },
  16330. hideCanvas: Boolean,
  16331. hideSliders: Boolean,
  16332. hideInputs: Boolean,
  16333. mode: {
  16334. type: String,
  16335. default: 'rgba',
  16336. validator: v => Object.keys(modes).includes(v)
  16337. },
  16338. modes: {
  16339. type: Array,
  16340. default: () => Object.keys(modes),
  16341. validator: v => Array.isArray(v) && v.every(m => Object.keys(modes).includes(m))
  16342. },
  16343. showSwatches: Boolean,
  16344. swatches: Array,
  16345. swatchesMaxHeight: {
  16346. type: [Number, String],
  16347. default: 150
  16348. },
  16349. modelValue: {
  16350. type: [Object, String]
  16351. },
  16352. ...omit(makeVSheetProps({
  16353. width: 300
  16354. }), ['height', 'location', 'minHeight', 'maxHeight', 'minWidth', 'maxWidth'])
  16355. }, 'VColorPicker');
  16356. const VColorPicker = defineComponent({
  16357. name: 'VColorPicker',
  16358. props: makeVColorPickerProps(),
  16359. emits: {
  16360. 'update:modelValue': color => true,
  16361. 'update:mode': mode => true
  16362. },
  16363. setup(props) {
  16364. const mode = useProxiedModel(props, 'mode');
  16365. const hue = ref(null);
  16366. const model = useProxiedModel(props, 'modelValue', undefined, v => {
  16367. if (v == null || v === '') return null;
  16368. let c;
  16369. try {
  16370. c = RGBtoHSV(parseColor(v));
  16371. } catch (err) {
  16372. consoleWarn(err);
  16373. return null;
  16374. }
  16375. return c;
  16376. }, v => {
  16377. if (!v) return null;
  16378. return extractColor(v, props.modelValue);
  16379. });
  16380. const currentColor = computed(() => {
  16381. return model.value ? {
  16382. ...model.value,
  16383. h: hue.value ?? model.value.h
  16384. } : null;
  16385. });
  16386. const {
  16387. rtlClasses
  16388. } = useRtl();
  16389. let externalChange = true;
  16390. watch(model, v => {
  16391. if (!externalChange) {
  16392. // prevent hue shift from rgb conversion inaccuracy
  16393. externalChange = true;
  16394. return;
  16395. }
  16396. if (!v) return;
  16397. hue.value = v.h;
  16398. }, {
  16399. immediate: true
  16400. });
  16401. const updateColor = hsva => {
  16402. externalChange = false;
  16403. hue.value = hsva.h;
  16404. model.value = hsva;
  16405. };
  16406. onBeforeMount(() => {
  16407. if (!props.modes.includes(mode.value)) mode.value = props.modes[0];
  16408. });
  16409. provideDefaults({
  16410. VSlider: {
  16411. color: undefined,
  16412. trackColor: undefined,
  16413. trackFillColor: undefined
  16414. }
  16415. });
  16416. useRender(() => {
  16417. const sheetProps = VSheet.filterProps(props);
  16418. return createVNode(VSheet, mergeProps({
  16419. "rounded": props.rounded,
  16420. "elevation": props.elevation,
  16421. "theme": props.theme,
  16422. "class": ['v-color-picker', rtlClasses.value, props.class],
  16423. "style": [{
  16424. '--v-color-picker-color-hsv': HSVtoCSS({
  16425. ...(currentColor.value ?? nullColor),
  16426. a: 1
  16427. })
  16428. }, props.style]
  16429. }, sheetProps, {
  16430. "maxWidth": props.width
  16431. }), {
  16432. default: () => [!props.hideCanvas && createVNode(VColorPickerCanvas, {
  16433. "key": "canvas",
  16434. "color": currentColor.value,
  16435. "onUpdate:color": updateColor,
  16436. "disabled": props.disabled,
  16437. "dotSize": props.dotSize,
  16438. "width": props.width,
  16439. "height": props.canvasHeight
  16440. }, null), (!props.hideSliders || !props.hideInputs) && createVNode("div", {
  16441. "key": "controls",
  16442. "class": "v-color-picker__controls"
  16443. }, [!props.hideSliders && createVNode(VColorPickerPreview, {
  16444. "key": "preview",
  16445. "color": currentColor.value,
  16446. "onUpdate:color": updateColor,
  16447. "hideAlpha": !mode.value.endsWith('a'),
  16448. "disabled": props.disabled
  16449. }, null), !props.hideInputs && createVNode(VColorPickerEdit, {
  16450. "key": "edit",
  16451. "modes": props.modes,
  16452. "mode": mode.value,
  16453. "onUpdate:mode": m => mode.value = m,
  16454. "color": currentColor.value,
  16455. "onUpdate:color": updateColor,
  16456. "disabled": props.disabled
  16457. }, null)]), props.showSwatches && createVNode(VColorPickerSwatches, {
  16458. "key": "swatches",
  16459. "color": currentColor.value,
  16460. "onUpdate:color": updateColor,
  16461. "maxHeight": props.swatchesMaxHeight,
  16462. "swatches": props.swatches,
  16463. "disabled": props.disabled
  16464. }, null)]
  16465. });
  16466. });
  16467. return {};
  16468. }
  16469. });
  16470. // Types
  16471. function highlightResult(text, matches, length) {
  16472. if (matches == null) return text;
  16473. if (Array.isArray(matches)) throw new Error('Multiple matches is not implemented');
  16474. return typeof matches === 'number' && ~matches ? createVNode(Fragment, null, [createVNode("span", {
  16475. "class": "v-combobox__unmask"
  16476. }, [text.substr(0, matches)]), createVNode("span", {
  16477. "class": "v-combobox__mask"
  16478. }, [text.substr(matches, length)]), createVNode("span", {
  16479. "class": "v-combobox__unmask"
  16480. }, [text.substr(matches + length)])]) : text;
  16481. }
  16482. const makeVComboboxProps = propsFactory({
  16483. autoSelectFirst: {
  16484. type: [Boolean, String]
  16485. },
  16486. clearOnSelect: {
  16487. type: Boolean,
  16488. default: true
  16489. },
  16490. delimiters: Array,
  16491. ...makeFilterProps({
  16492. filterKeys: ['title']
  16493. }),
  16494. ...makeSelectProps({
  16495. hideNoData: true,
  16496. returnObject: true
  16497. }),
  16498. ...omit(makeVTextFieldProps({
  16499. modelValue: null,
  16500. role: 'combobox'
  16501. }), ['validationValue', 'dirty', 'appendInnerIcon']),
  16502. ...makeTransitionProps({
  16503. transition: false
  16504. })
  16505. }, 'VCombobox');
  16506. const VCombobox = genericComponent()({
  16507. name: 'VCombobox',
  16508. props: makeVComboboxProps(),
  16509. emits: {
  16510. 'update:focused': focused => true,
  16511. 'update:modelValue': value => true,
  16512. 'update:search': value => true,
  16513. 'update:menu': value => true
  16514. },
  16515. setup(props, _ref) {
  16516. let {
  16517. emit,
  16518. slots
  16519. } = _ref;
  16520. const {
  16521. t
  16522. } = useLocale();
  16523. const vTextFieldRef = ref();
  16524. const isFocused = shallowRef(false);
  16525. const isPristine = shallowRef(true);
  16526. const listHasFocus = shallowRef(false);
  16527. const vMenuRef = ref();
  16528. const vVirtualScrollRef = ref();
  16529. const _menu = useProxiedModel(props, 'menu');
  16530. const menu = computed({
  16531. get: () => _menu.value,
  16532. set: v => {
  16533. if (_menu.value && !v && vMenuRef.value?.ΨopenChildren.size) return;
  16534. _menu.value = v;
  16535. }
  16536. });
  16537. const selectionIndex = shallowRef(-1);
  16538. let cleared = false;
  16539. const color = computed(() => vTextFieldRef.value?.color);
  16540. const label = computed(() => menu.value ? props.closeText : props.openText);
  16541. const {
  16542. items,
  16543. transformIn,
  16544. transformOut
  16545. } = useItems(props);
  16546. const {
  16547. textColorClasses,
  16548. textColorStyles
  16549. } = useTextColor(color);
  16550. const model = useProxiedModel(props, 'modelValue', [], v => transformIn(wrapInArray(v)), v => {
  16551. const transformed = transformOut(v);
  16552. return props.multiple ? transformed : transformed[0] ?? null;
  16553. });
  16554. const form = useForm(props);
  16555. const hasChips = computed(() => !!(props.chips || slots.chip));
  16556. const hasSelectionSlot = computed(() => hasChips.value || !!slots.selection);
  16557. const _search = shallowRef(!props.multiple && !hasSelectionSlot.value ? model.value[0]?.title ?? '' : '');
  16558. const search = computed({
  16559. get: () => {
  16560. return _search.value;
  16561. },
  16562. set: val => {
  16563. _search.value = val ?? '';
  16564. if (!props.multiple && !hasSelectionSlot.value) {
  16565. model.value = [transformItem$3(props, val)];
  16566. }
  16567. if (val && props.multiple && props.delimiters?.length) {
  16568. const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
  16569. if (values.length > 1) {
  16570. values.forEach(v => {
  16571. v = v.trim();
  16572. if (v) select(transformItem$3(props, v));
  16573. });
  16574. _search.value = '';
  16575. }
  16576. }
  16577. if (!val) selectionIndex.value = -1;
  16578. isPristine.value = !val;
  16579. }
  16580. });
  16581. const counterValue = computed(() => {
  16582. return typeof props.counterValue === 'function' ? props.counterValue(model.value) : typeof props.counterValue === 'number' ? props.counterValue : props.multiple ? model.value.length : search.value.length;
  16583. });
  16584. watch(_search, value => {
  16585. if (cleared) {
  16586. // wait for clear to finish, VTextField sets _search to null
  16587. // then search computed triggers and updates _search to ''
  16588. nextTick(() => cleared = false);
  16589. } else if (isFocused.value && !menu.value) {
  16590. menu.value = true;
  16591. }
  16592. emit('update:search', value);
  16593. });
  16594. watch(model, value => {
  16595. if (!props.multiple && !hasSelectionSlot.value) {
  16596. _search.value = value[0]?.title ?? '';
  16597. }
  16598. });
  16599. const {
  16600. filteredItems,
  16601. getMatches
  16602. } = useFilter(props, items, () => isPristine.value ? '' : search.value);
  16603. const displayItems = computed(() => {
  16604. if (props.hideSelected) {
  16605. return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value));
  16606. }
  16607. return filteredItems.value;
  16608. });
  16609. const selectedValues = computed(() => model.value.map(selection => selection.value));
  16610. const highlightFirst = computed(() => {
  16611. const selectFirst = props.autoSelectFirst === true || props.autoSelectFirst === 'exact' && search.value === displayItems.value[0]?.title;
  16612. return selectFirst && displayItems.value.length > 0 && !isPristine.value && !listHasFocus.value;
  16613. });
  16614. const menuDisabled = computed(() => props.hideNoData && !displayItems.value.length || form.isReadonly.value || form.isDisabled.value);
  16615. const listRef = ref();
  16616. const listEvents = useScrolling(listRef, vTextFieldRef);
  16617. function onClear(e) {
  16618. cleared = true;
  16619. if (props.openOnClear) {
  16620. menu.value = true;
  16621. }
  16622. }
  16623. function onMousedownControl() {
  16624. if (menuDisabled.value) return;
  16625. menu.value = true;
  16626. }
  16627. function onMousedownMenuIcon(e) {
  16628. if (menuDisabled.value) return;
  16629. if (isFocused.value) {
  16630. e.preventDefault();
  16631. e.stopPropagation();
  16632. }
  16633. menu.value = !menu.value;
  16634. }
  16635. function onListKeydown(e) {
  16636. if (checkPrintable(e)) {
  16637. vTextFieldRef.value?.focus();
  16638. }
  16639. }
  16640. // eslint-disable-next-line complexity
  16641. function onKeydown(e) {
  16642. if (isComposingIgnoreKey(e) || form.isReadonly.value) return;
  16643. const selectionStart = vTextFieldRef.value.selectionStart;
  16644. const length = model.value.length;
  16645. if (selectionIndex.value > -1 || ['Enter', 'ArrowDown', 'ArrowUp'].includes(e.key)) {
  16646. e.preventDefault();
  16647. }
  16648. if (['Enter', 'ArrowDown'].includes(e.key)) {
  16649. menu.value = true;
  16650. }
  16651. if (['Escape'].includes(e.key)) {
  16652. menu.value = false;
  16653. }
  16654. if (['Enter', 'Escape', 'Tab'].includes(e.key)) {
  16655. if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key) && !model.value.some(_ref2 => {
  16656. let {
  16657. value
  16658. } = _ref2;
  16659. return value === displayItems.value[0].value;
  16660. })) {
  16661. select(filteredItems.value[0]);
  16662. }
  16663. isPristine.value = true;
  16664. }
  16665. if (e.key === 'ArrowDown' && highlightFirst.value) {
  16666. listRef.value?.focus('next');
  16667. }
  16668. if (e.key === 'Enter' && search.value) {
  16669. select(transformItem$3(props, search.value));
  16670. if (hasSelectionSlot.value) _search.value = '';
  16671. }
  16672. if (['Backspace', 'Delete'].includes(e.key)) {
  16673. if (!props.multiple && hasSelectionSlot.value && model.value.length > 0 && !search.value) return select(model.value[0], false);
  16674. if (~selectionIndex.value) {
  16675. const originalSelectionIndex = selectionIndex.value;
  16676. select(model.value[selectionIndex.value], false);
  16677. selectionIndex.value = originalSelectionIndex >= length - 1 ? length - 2 : originalSelectionIndex;
  16678. } else if (e.key === 'Backspace' && !search.value) {
  16679. selectionIndex.value = length - 1;
  16680. }
  16681. }
  16682. if (!props.multiple) return;
  16683. if (e.key === 'ArrowLeft') {
  16684. if (selectionIndex.value < 0 && selectionStart > 0) return;
  16685. const prev = selectionIndex.value > -1 ? selectionIndex.value - 1 : length - 1;
  16686. if (model.value[prev]) {
  16687. selectionIndex.value = prev;
  16688. } else {
  16689. selectionIndex.value = -1;
  16690. vTextFieldRef.value.setSelectionRange(search.value.length, search.value.length);
  16691. }
  16692. }
  16693. if (e.key === 'ArrowRight') {
  16694. if (selectionIndex.value < 0) return;
  16695. const next = selectionIndex.value + 1;
  16696. if (model.value[next]) {
  16697. selectionIndex.value = next;
  16698. } else {
  16699. selectionIndex.value = -1;
  16700. vTextFieldRef.value.setSelectionRange(0, 0);
  16701. }
  16702. }
  16703. }
  16704. function onAfterEnter() {
  16705. if (props.eager) {
  16706. vVirtualScrollRef.value?.calculateVisibleItems();
  16707. }
  16708. }
  16709. function onAfterLeave() {
  16710. if (isFocused.value) {
  16711. isPristine.value = true;
  16712. vTextFieldRef.value?.focus();
  16713. }
  16714. }
  16715. /** @param set - null means toggle */
  16716. function select(item) {
  16717. let set = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  16718. if (!item || item.props.disabled) return;
  16719. if (props.multiple) {
  16720. const index = model.value.findIndex(selection => props.valueComparator(selection.value, item.value));
  16721. const add = set == null ? !~index : set;
  16722. if (~index) {
  16723. const value = add ? [...model.value, item] : [...model.value];
  16724. value.splice(index, 1);
  16725. model.value = value;
  16726. } else if (add) {
  16727. model.value = [...model.value, item];
  16728. }
  16729. if (props.clearOnSelect) {
  16730. search.value = '';
  16731. }
  16732. } else {
  16733. const add = set !== false;
  16734. model.value = add ? [item] : [];
  16735. _search.value = add && !hasSelectionSlot.value ? item.title : '';
  16736. // watch for search watcher to trigger
  16737. nextTick(() => {
  16738. menu.value = false;
  16739. isPristine.value = true;
  16740. });
  16741. }
  16742. }
  16743. function onFocusin(e) {
  16744. isFocused.value = true;
  16745. setTimeout(() => {
  16746. listHasFocus.value = true;
  16747. });
  16748. }
  16749. function onFocusout(e) {
  16750. listHasFocus.value = false;
  16751. }
  16752. function onUpdateModelValue(v) {
  16753. if (v == null || v === '' && !props.multiple && !hasSelectionSlot.value) model.value = [];
  16754. }
  16755. watch(isFocused, (val, oldVal) => {
  16756. if (val || val === oldVal) return;
  16757. selectionIndex.value = -1;
  16758. menu.value = false;
  16759. if (search.value) {
  16760. if (props.multiple) {
  16761. select(transformItem$3(props, search.value));
  16762. return;
  16763. }
  16764. if (!hasSelectionSlot.value) return;
  16765. if (model.value.some(_ref3 => {
  16766. let {
  16767. title
  16768. } = _ref3;
  16769. return title === search.value;
  16770. })) {
  16771. _search.value = '';
  16772. } else {
  16773. select(transformItem$3(props, search.value));
  16774. }
  16775. }
  16776. });
  16777. watch(menu, () => {
  16778. if (!props.hideSelected && menu.value && model.value.length) {
  16779. const index = displayItems.value.findIndex(item => model.value.some(s => props.valueComparator(s.value, item.value)));
  16780. IN_BROWSER && window.requestAnimationFrame(() => {
  16781. index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
  16782. });
  16783. }
  16784. });
  16785. watch(() => props.items, (newVal, oldVal) => {
  16786. if (menu.value) return;
  16787. if (isFocused.value && !oldVal.length && newVal.length) {
  16788. menu.value = true;
  16789. }
  16790. });
  16791. useRender(() => {
  16792. const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
  16793. const isDirty = model.value.length > 0;
  16794. const textFieldProps = VTextField.filterProps(props);
  16795. return createVNode(VTextField, mergeProps({
  16796. "ref": vTextFieldRef
  16797. }, textFieldProps, {
  16798. "modelValue": search.value,
  16799. "onUpdate:modelValue": [$event => search.value = $event, onUpdateModelValue],
  16800. "focused": isFocused.value,
  16801. "onUpdate:focused": $event => isFocused.value = $event,
  16802. "validationValue": model.externalValue,
  16803. "counterValue": counterValue.value,
  16804. "dirty": isDirty,
  16805. "class": ['v-combobox', {
  16806. 'v-combobox--active-menu': menu.value,
  16807. 'v-combobox--chips': !!props.chips,
  16808. 'v-combobox--selection-slot': !!hasSelectionSlot.value,
  16809. 'v-combobox--selecting-index': selectionIndex.value > -1,
  16810. [`v-combobox--${props.multiple ? 'multiple' : 'single'}`]: true
  16811. }, props.class],
  16812. "style": props.style,
  16813. "readonly": form.isReadonly.value,
  16814. "placeholder": isDirty ? undefined : props.placeholder,
  16815. "onClick:clear": onClear,
  16816. "onMousedown:control": onMousedownControl,
  16817. "onKeydown": onKeydown
  16818. }), {
  16819. ...slots,
  16820. default: () => createVNode(Fragment, null, [createVNode(VMenu, mergeProps({
  16821. "ref": vMenuRef,
  16822. "modelValue": menu.value,
  16823. "onUpdate:modelValue": $event => menu.value = $event,
  16824. "activator": "parent",
  16825. "contentClass": "v-combobox__content",
  16826. "disabled": menuDisabled.value,
  16827. "eager": props.eager,
  16828. "maxHeight": 310,
  16829. "openOnClick": false,
  16830. "closeOnContentClick": false,
  16831. "transition": props.transition,
  16832. "onAfterEnter": onAfterEnter,
  16833. "onAfterLeave": onAfterLeave
  16834. }, props.menuProps), {
  16835. default: () => [hasList && createVNode(VList, mergeProps({
  16836. "ref": listRef,
  16837. "selected": selectedValues.value,
  16838. "selectStrategy": props.multiple ? 'independent' : 'single-independent',
  16839. "onMousedown": e => e.preventDefault(),
  16840. "onKeydown": onListKeydown,
  16841. "onFocusin": onFocusin,
  16842. "onFocusout": onFocusout,
  16843. "tabindex": "-1",
  16844. "aria-live": "polite",
  16845. "color": props.itemColor ?? props.color
  16846. }, listEvents, props.listProps), {
  16847. default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? createVNode(VListItem, {
  16848. "key": "no-data",
  16849. "title": t(props.noDataText)
  16850. }, null)), createVNode(VVirtualScroll, {
  16851. "ref": vVirtualScrollRef,
  16852. "renderless": true,
  16853. "items": displayItems.value
  16854. }, {
  16855. default: _ref4 => {
  16856. let {
  16857. item,
  16858. index,
  16859. itemRef
  16860. } = _ref4;
  16861. const itemProps = mergeProps(item.props, {
  16862. ref: itemRef,
  16863. key: item.value,
  16864. active: highlightFirst.value && index === 0 ? true : undefined,
  16865. onClick: () => select(item, null)
  16866. });
  16867. return slots.item?.({
  16868. item,
  16869. index,
  16870. props: itemProps
  16871. }) ?? createVNode(VListItem, mergeProps(itemProps, {
  16872. "role": "option"
  16873. }), {
  16874. prepend: _ref5 => {
  16875. let {
  16876. isSelected
  16877. } = _ref5;
  16878. return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
  16879. "key": item.value,
  16880. "modelValue": isSelected,
  16881. "ripple": false,
  16882. "tabindex": "-1"
  16883. }, null) : undefined, item.props.prependAvatar && createVNode(VAvatar, {
  16884. "image": item.props.prependAvatar
  16885. }, null), item.props.prependIcon && createVNode(VIcon, {
  16886. "icon": item.props.prependIcon
  16887. }, null)]);
  16888. },
  16889. title: () => {
  16890. return isPristine.value ? item.title : highlightResult(item.title, getMatches(item)?.title, search.value?.length ?? 0);
  16891. }
  16892. });
  16893. }
  16894. }), slots['append-item']?.()]
  16895. })]
  16896. }), model.value.map((item, index) => {
  16897. function onChipClose(e) {
  16898. e.stopPropagation();
  16899. e.preventDefault();
  16900. select(item, false);
  16901. }
  16902. const slotProps = {
  16903. 'onClick:close': onChipClose,
  16904. onKeydown(e) {
  16905. if (e.key !== 'Enter' && e.key !== ' ') return;
  16906. e.preventDefault();
  16907. e.stopPropagation();
  16908. onChipClose(e);
  16909. },
  16910. onMousedown(e) {
  16911. e.preventDefault();
  16912. e.stopPropagation();
  16913. },
  16914. modelValue: true,
  16915. 'onUpdate:modelValue': undefined
  16916. };
  16917. const hasSlot = hasChips.value ? !!slots.chip : !!slots.selection;
  16918. const slotContent = hasSlot ? ensureValidVNode(hasChips.value ? slots.chip({
  16919. item,
  16920. index,
  16921. props: slotProps
  16922. }) : slots.selection({
  16923. item,
  16924. index
  16925. })) : undefined;
  16926. if (hasSlot && !slotContent) return undefined;
  16927. return createVNode("div", {
  16928. "key": item.value,
  16929. "class": ['v-combobox__selection', index === selectionIndex.value && ['v-combobox__selection--selected', textColorClasses.value]],
  16930. "style": index === selectionIndex.value ? textColorStyles.value : {}
  16931. }, [hasChips.value ? !slots.chip ? createVNode(VChip, mergeProps({
  16932. "key": "chip",
  16933. "closable": props.closableChips,
  16934. "size": "small",
  16935. "text": item.title,
  16936. "disabled": item.props.disabled
  16937. }, slotProps), null) : createVNode(VDefaultsProvider, {
  16938. "key": "chip-defaults",
  16939. "defaults": {
  16940. VChip: {
  16941. closable: props.closableChips,
  16942. size: 'small',
  16943. text: item.title
  16944. }
  16945. }
  16946. }, {
  16947. default: () => [slotContent]
  16948. }) : slotContent ?? createVNode("span", {
  16949. "class": "v-combobox__selection-text"
  16950. }, [item.title, props.multiple && index < model.value.length - 1 && createVNode("span", {
  16951. "class": "v-combobox__selection-comma"
  16952. }, [createTextVNode(",")])])]);
  16953. })]),
  16954. 'append-inner': function () {
  16955. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  16956. args[_key] = arguments[_key];
  16957. }
  16958. return createVNode(Fragment, null, [slots['append-inner']?.(...args), (!props.hideNoData || props.items.length) && props.menuIcon ? createVNode(VIcon, {
  16959. "class": "v-combobox__menu-icon",
  16960. "icon": props.menuIcon,
  16961. "onMousedown": onMousedownMenuIcon,
  16962. "onClick": noop,
  16963. "aria-label": t(label.value),
  16964. "title": t(label.value),
  16965. "tabindex": "-1"
  16966. }, null) : undefined]);
  16967. }
  16968. });
  16969. });
  16970. return forwardRefs({
  16971. isFocused,
  16972. isPristine,
  16973. menu,
  16974. search,
  16975. selectionIndex,
  16976. filteredItems,
  16977. select
  16978. }, vTextFieldRef);
  16979. }
  16980. });
  16981. // Utilities
  16982. // Types
  16983. const firstDay = {
  16984. '001': 1,
  16985. AD: 1,
  16986. AE: 6,
  16987. AF: 6,
  16988. AG: 0,
  16989. AI: 1,
  16990. AL: 1,
  16991. AM: 1,
  16992. AN: 1,
  16993. AR: 1,
  16994. AS: 0,
  16995. AT: 1,
  16996. AU: 1,
  16997. AX: 1,
  16998. AZ: 1,
  16999. BA: 1,
  17000. BD: 0,
  17001. BE: 1,
  17002. BG: 1,
  17003. BH: 6,
  17004. BM: 1,
  17005. BN: 1,
  17006. BR: 0,
  17007. BS: 0,
  17008. BT: 0,
  17009. BW: 0,
  17010. BY: 1,
  17011. BZ: 0,
  17012. CA: 0,
  17013. CH: 1,
  17014. CL: 1,
  17015. CM: 1,
  17016. CN: 1,
  17017. CO: 0,
  17018. CR: 1,
  17019. CY: 1,
  17020. CZ: 1,
  17021. DE: 1,
  17022. DJ: 6,
  17023. DK: 1,
  17024. DM: 0,
  17025. DO: 0,
  17026. DZ: 6,
  17027. EC: 1,
  17028. EE: 1,
  17029. EG: 6,
  17030. ES: 1,
  17031. ET: 0,
  17032. FI: 1,
  17033. FJ: 1,
  17034. FO: 1,
  17035. FR: 1,
  17036. GB: 1,
  17037. 'GB-alt-variant': 0,
  17038. GE: 1,
  17039. GF: 1,
  17040. GP: 1,
  17041. GR: 1,
  17042. GT: 0,
  17043. GU: 0,
  17044. HK: 0,
  17045. HN: 0,
  17046. HR: 1,
  17047. HU: 1,
  17048. ID: 0,
  17049. IE: 1,
  17050. IL: 0,
  17051. IN: 0,
  17052. IQ: 6,
  17053. IR: 6,
  17054. IS: 1,
  17055. IT: 1,
  17056. JM: 0,
  17057. JO: 6,
  17058. JP: 0,
  17059. KE: 0,
  17060. KG: 1,
  17061. KH: 0,
  17062. KR: 0,
  17063. KW: 6,
  17064. KZ: 1,
  17065. LA: 0,
  17066. LB: 1,
  17067. LI: 1,
  17068. LK: 1,
  17069. LT: 1,
  17070. LU: 1,
  17071. LV: 1,
  17072. LY: 6,
  17073. MC: 1,
  17074. MD: 1,
  17075. ME: 1,
  17076. MH: 0,
  17077. MK: 1,
  17078. MM: 0,
  17079. MN: 1,
  17080. MO: 0,
  17081. MQ: 1,
  17082. MT: 0,
  17083. MV: 5,
  17084. MX: 0,
  17085. MY: 1,
  17086. MZ: 0,
  17087. NI: 0,
  17088. NL: 1,
  17089. NO: 1,
  17090. NP: 0,
  17091. NZ: 1,
  17092. OM: 6,
  17093. PA: 0,
  17094. PE: 0,
  17095. PH: 0,
  17096. PK: 0,
  17097. PL: 1,
  17098. PR: 0,
  17099. PT: 0,
  17100. PY: 0,
  17101. QA: 6,
  17102. RE: 1,
  17103. RO: 1,
  17104. RS: 1,
  17105. RU: 1,
  17106. SA: 0,
  17107. SD: 6,
  17108. SE: 1,
  17109. SG: 0,
  17110. SI: 1,
  17111. SK: 1,
  17112. SM: 1,
  17113. SV: 0,
  17114. SY: 6,
  17115. TH: 0,
  17116. TJ: 1,
  17117. TM: 1,
  17118. TR: 1,
  17119. TT: 0,
  17120. TW: 0,
  17121. UA: 1,
  17122. UM: 0,
  17123. US: 0,
  17124. UY: 1,
  17125. UZ: 1,
  17126. VA: 1,
  17127. VE: 0,
  17128. VI: 0,
  17129. VN: 1,
  17130. WS: 0,
  17131. XK: 1,
  17132. YE: 0,
  17133. ZA: 0,
  17134. ZW: 0
  17135. };
  17136. function getWeekArray(date, locale, firstDayOfWeek) {
  17137. const weeks = [];
  17138. let currentWeek = [];
  17139. const firstDayOfMonth = startOfMonth(date);
  17140. const lastDayOfMonth = endOfMonth(date);
  17141. const first = firstDayOfWeek ?? firstDay[locale.slice(-2).toUpperCase()] ?? 0;
  17142. const firstDayWeekIndex = (firstDayOfMonth.getDay() - first + 7) % 7;
  17143. const lastDayWeekIndex = (lastDayOfMonth.getDay() - first + 7) % 7;
  17144. for (let i = 0; i < firstDayWeekIndex; i++) {
  17145. const adjacentDay = new Date(firstDayOfMonth);
  17146. adjacentDay.setDate(adjacentDay.getDate() - (firstDayWeekIndex - i));
  17147. currentWeek.push(adjacentDay);
  17148. }
  17149. for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {
  17150. const day = new Date(date.getFullYear(), date.getMonth(), i);
  17151. // Add the day to the current week
  17152. currentWeek.push(day);
  17153. // If the current week has 7 days, add it to the weeks array and start a new week
  17154. if (currentWeek.length === 7) {
  17155. weeks.push(currentWeek);
  17156. currentWeek = [];
  17157. }
  17158. }
  17159. for (let i = 1; i < 7 - lastDayWeekIndex; i++) {
  17160. const adjacentDay = new Date(lastDayOfMonth);
  17161. adjacentDay.setDate(adjacentDay.getDate() + i);
  17162. currentWeek.push(adjacentDay);
  17163. }
  17164. if (currentWeek.length > 0) {
  17165. weeks.push(currentWeek);
  17166. }
  17167. return weeks;
  17168. }
  17169. function startOfWeek(date, locale, firstDayOfWeek) {
  17170. const day = firstDayOfWeek ?? firstDay[locale.slice(-2).toUpperCase()] ?? 0;
  17171. const d = new Date(date);
  17172. while (d.getDay() !== day) {
  17173. d.setDate(d.getDate() - 1);
  17174. }
  17175. return d;
  17176. }
  17177. function endOfWeek(date, locale) {
  17178. const d = new Date(date);
  17179. const lastDay = ((firstDay[locale.slice(-2).toUpperCase()] ?? 0) + 6) % 7;
  17180. while (d.getDay() !== lastDay) {
  17181. d.setDate(d.getDate() + 1);
  17182. }
  17183. return d;
  17184. }
  17185. function startOfMonth(date) {
  17186. return new Date(date.getFullYear(), date.getMonth(), 1);
  17187. }
  17188. function endOfMonth(date) {
  17189. return new Date(date.getFullYear(), date.getMonth() + 1, 0);
  17190. }
  17191. function parseLocalDate(value) {
  17192. const parts = value.split('-').map(Number);
  17193. // new Date() uses local time zone when passing individual date component values
  17194. return new Date(parts[0], parts[1] - 1, parts[2]);
  17195. }
  17196. const _YYYMMDD = /^([12]\d{3}-([1-9]|0[1-9]|1[0-2])-([1-9]|0[1-9]|[12]\d|3[01]))$/;
  17197. function date(value) {
  17198. if (value == null) return new Date();
  17199. if (value instanceof Date) return value;
  17200. if (typeof value === 'string') {
  17201. let parsed;
  17202. if (_YYYMMDD.test(value)) {
  17203. return parseLocalDate(value);
  17204. } else {
  17205. parsed = Date.parse(value);
  17206. }
  17207. if (!isNaN(parsed)) return new Date(parsed);
  17208. }
  17209. return null;
  17210. }
  17211. const sundayJanuarySecond2000 = new Date(2000, 0, 2);
  17212. function getWeekdays(locale, firstDayOfWeek) {
  17213. const daysFromSunday = firstDayOfWeek ?? firstDay[locale.slice(-2).toUpperCase()] ?? 0;
  17214. return createRange(7).map(i => {
  17215. const weekday = new Date(sundayJanuarySecond2000);
  17216. weekday.setDate(sundayJanuarySecond2000.getDate() + daysFromSunday + i);
  17217. return new Intl.DateTimeFormat(locale, {
  17218. weekday: 'narrow'
  17219. }).format(weekday);
  17220. });
  17221. }
  17222. function format(value, formatString, locale, formats) {
  17223. const newDate = date(value) ?? new Date();
  17224. const customFormat = formats?.[formatString];
  17225. if (typeof customFormat === 'function') {
  17226. return customFormat(newDate, formatString, locale);
  17227. }
  17228. let options = {};
  17229. switch (formatString) {
  17230. case 'fullDate':
  17231. options = {
  17232. year: 'numeric',
  17233. month: 'long',
  17234. day: 'numeric'
  17235. };
  17236. break;
  17237. case 'fullDateWithWeekday':
  17238. options = {
  17239. weekday: 'long',
  17240. year: 'numeric',
  17241. month: 'long',
  17242. day: 'numeric'
  17243. };
  17244. break;
  17245. case 'normalDate':
  17246. const day = newDate.getDate();
  17247. const month = new Intl.DateTimeFormat(locale, {
  17248. month: 'long'
  17249. }).format(newDate);
  17250. return `${day} ${month}`;
  17251. case 'normalDateWithWeekday':
  17252. options = {
  17253. weekday: 'short',
  17254. day: 'numeric',
  17255. month: 'short'
  17256. };
  17257. break;
  17258. case 'shortDate':
  17259. options = {
  17260. month: 'short',
  17261. day: 'numeric'
  17262. };
  17263. break;
  17264. case 'year':
  17265. options = {
  17266. year: 'numeric'
  17267. };
  17268. break;
  17269. case 'month':
  17270. options = {
  17271. month: 'long'
  17272. };
  17273. break;
  17274. case 'monthShort':
  17275. options = {
  17276. month: 'short'
  17277. };
  17278. break;
  17279. case 'monthAndYear':
  17280. options = {
  17281. month: 'long',
  17282. year: 'numeric'
  17283. };
  17284. break;
  17285. case 'monthAndDate':
  17286. options = {
  17287. month: 'long',
  17288. day: 'numeric'
  17289. };
  17290. break;
  17291. case 'weekday':
  17292. options = {
  17293. weekday: 'long'
  17294. };
  17295. break;
  17296. case 'weekdayShort':
  17297. options = {
  17298. weekday: 'short'
  17299. };
  17300. break;
  17301. case 'dayOfMonth':
  17302. return new Intl.NumberFormat(locale).format(newDate.getDate());
  17303. case 'hours12h':
  17304. options = {
  17305. hour: 'numeric',
  17306. hour12: true
  17307. };
  17308. break;
  17309. case 'hours24h':
  17310. options = {
  17311. hour: 'numeric',
  17312. hour12: false
  17313. };
  17314. break;
  17315. case 'minutes':
  17316. options = {
  17317. minute: 'numeric'
  17318. };
  17319. break;
  17320. case 'seconds':
  17321. options = {
  17322. second: 'numeric'
  17323. };
  17324. break;
  17325. case 'fullTime':
  17326. options = {
  17327. hour: 'numeric',
  17328. minute: 'numeric',
  17329. second: 'numeric',
  17330. hour12: true
  17331. };
  17332. break;
  17333. case 'fullTime12h':
  17334. options = {
  17335. hour: 'numeric',
  17336. minute: 'numeric',
  17337. second: 'numeric',
  17338. hour12: true
  17339. };
  17340. break;
  17341. case 'fullTime24h':
  17342. options = {
  17343. hour: 'numeric',
  17344. minute: 'numeric',
  17345. second: 'numeric',
  17346. hour12: false
  17347. };
  17348. break;
  17349. case 'fullDateTime':
  17350. options = {
  17351. year: 'numeric',
  17352. month: 'long',
  17353. day: 'numeric',
  17354. hour: 'numeric',
  17355. minute: 'numeric',
  17356. second: 'numeric',
  17357. hour12: true
  17358. };
  17359. break;
  17360. case 'fullDateTime12h':
  17361. options = {
  17362. year: 'numeric',
  17363. month: 'long',
  17364. day: 'numeric',
  17365. hour: 'numeric',
  17366. minute: 'numeric',
  17367. second: 'numeric',
  17368. hour12: true
  17369. };
  17370. break;
  17371. case 'fullDateTime24h':
  17372. options = {
  17373. year: 'numeric',
  17374. month: 'long',
  17375. day: 'numeric',
  17376. hour: 'numeric',
  17377. minute: 'numeric',
  17378. second: 'numeric',
  17379. hour12: false
  17380. };
  17381. break;
  17382. case 'keyboardDate':
  17383. options = {
  17384. year: 'numeric',
  17385. month: '2-digit',
  17386. day: '2-digit'
  17387. };
  17388. break;
  17389. case 'keyboardDateTime':
  17390. options = {
  17391. year: 'numeric',
  17392. month: '2-digit',
  17393. day: '2-digit',
  17394. hour: 'numeric',
  17395. minute: 'numeric',
  17396. second: 'numeric',
  17397. hour12: false
  17398. };
  17399. break;
  17400. case 'keyboardDateTime12h':
  17401. options = {
  17402. year: 'numeric',
  17403. month: '2-digit',
  17404. day: '2-digit',
  17405. hour: 'numeric',
  17406. minute: 'numeric',
  17407. second: 'numeric',
  17408. hour12: true
  17409. };
  17410. break;
  17411. case 'keyboardDateTime24h':
  17412. options = {
  17413. year: 'numeric',
  17414. month: '2-digit',
  17415. day: '2-digit',
  17416. hour: 'numeric',
  17417. minute: 'numeric',
  17418. second: 'numeric',
  17419. hour12: false
  17420. };
  17421. break;
  17422. default:
  17423. options = customFormat ?? {
  17424. timeZone: 'UTC',
  17425. timeZoneName: 'short'
  17426. };
  17427. }
  17428. return new Intl.DateTimeFormat(locale, options).format(newDate);
  17429. }
  17430. function toISO(adapter, value) {
  17431. const date = adapter.toJsDate(value);
  17432. const year = date.getFullYear();
  17433. const month = padStart(String(date.getMonth() + 1), 2, '0');
  17434. const day = padStart(String(date.getDate()), 2, '0');
  17435. return `${year}-${month}-${day}`;
  17436. }
  17437. function parseISO(value) {
  17438. const [year, month, day] = value.split('-').map(Number);
  17439. return new Date(year, month - 1, day);
  17440. }
  17441. function addMinutes(date, amount) {
  17442. const d = new Date(date);
  17443. d.setMinutes(d.getMinutes() + amount);
  17444. return d;
  17445. }
  17446. function addHours(date, amount) {
  17447. const d = new Date(date);
  17448. d.setHours(d.getHours() + amount);
  17449. return d;
  17450. }
  17451. function addDays(date, amount) {
  17452. const d = new Date(date);
  17453. d.setDate(d.getDate() + amount);
  17454. return d;
  17455. }
  17456. function addWeeks(date, amount) {
  17457. const d = new Date(date);
  17458. d.setDate(d.getDate() + amount * 7);
  17459. return d;
  17460. }
  17461. function addMonths(date, amount) {
  17462. const d = new Date(date);
  17463. d.setDate(1);
  17464. d.setMonth(d.getMonth() + amount);
  17465. return d;
  17466. }
  17467. function getYear(date) {
  17468. return date.getFullYear();
  17469. }
  17470. function getMonth(date) {
  17471. return date.getMonth();
  17472. }
  17473. function getDate(date) {
  17474. return date.getDate();
  17475. }
  17476. function getNextMonth(date) {
  17477. return new Date(date.getFullYear(), date.getMonth() + 1, 1);
  17478. }
  17479. function getPreviousMonth(date) {
  17480. return new Date(date.getFullYear(), date.getMonth() - 1, 1);
  17481. }
  17482. function getHours(date) {
  17483. return date.getHours();
  17484. }
  17485. function getMinutes(date) {
  17486. return date.getMinutes();
  17487. }
  17488. function startOfYear(date) {
  17489. return new Date(date.getFullYear(), 0, 1);
  17490. }
  17491. function endOfYear(date) {
  17492. return new Date(date.getFullYear(), 11, 31);
  17493. }
  17494. function isWithinRange(date, range) {
  17495. return isAfter(date, range[0]) && isBefore(date, range[1]);
  17496. }
  17497. function isValid(date) {
  17498. const d = new Date(date);
  17499. return d instanceof Date && !isNaN(d.getTime());
  17500. }
  17501. function isAfter(date, comparing) {
  17502. return date.getTime() > comparing.getTime();
  17503. }
  17504. function isAfterDay(date, comparing) {
  17505. return isAfter(startOfDay(date), startOfDay(comparing));
  17506. }
  17507. function isBefore(date, comparing) {
  17508. return date.getTime() < comparing.getTime();
  17509. }
  17510. function isEqual(date, comparing) {
  17511. return date.getTime() === comparing.getTime();
  17512. }
  17513. function isSameDay(date, comparing) {
  17514. return date.getDate() === comparing.getDate() && date.getMonth() === comparing.getMonth() && date.getFullYear() === comparing.getFullYear();
  17515. }
  17516. function isSameMonth(date, comparing) {
  17517. return date.getMonth() === comparing.getMonth() && date.getFullYear() === comparing.getFullYear();
  17518. }
  17519. function isSameYear(date, comparing) {
  17520. return date.getFullYear() === comparing.getFullYear();
  17521. }
  17522. function getDiff(date, comparing, unit) {
  17523. const d = new Date(date);
  17524. const c = new Date(comparing);
  17525. switch (unit) {
  17526. case 'years':
  17527. return d.getFullYear() - c.getFullYear();
  17528. case 'quarters':
  17529. return Math.floor((d.getMonth() - c.getMonth() + (d.getFullYear() - c.getFullYear()) * 12) / 4);
  17530. case 'months':
  17531. return d.getMonth() - c.getMonth() + (d.getFullYear() - c.getFullYear()) * 12;
  17532. case 'weeks':
  17533. return Math.floor((d.getTime() - c.getTime()) / (1000 * 60 * 60 * 24 * 7));
  17534. case 'days':
  17535. return Math.floor((d.getTime() - c.getTime()) / (1000 * 60 * 60 * 24));
  17536. case 'hours':
  17537. return Math.floor((d.getTime() - c.getTime()) / (1000 * 60 * 60));
  17538. case 'minutes':
  17539. return Math.floor((d.getTime() - c.getTime()) / (1000 * 60));
  17540. case 'seconds':
  17541. return Math.floor((d.getTime() - c.getTime()) / 1000);
  17542. default:
  17543. {
  17544. return d.getTime() - c.getTime();
  17545. }
  17546. }
  17547. }
  17548. function setHours(date, count) {
  17549. const d = new Date(date);
  17550. d.setHours(count);
  17551. return d;
  17552. }
  17553. function setMinutes(date, count) {
  17554. const d = new Date(date);
  17555. d.setMinutes(count);
  17556. return d;
  17557. }
  17558. function setMonth(date, count) {
  17559. const d = new Date(date);
  17560. d.setMonth(count);
  17561. return d;
  17562. }
  17563. function setDate(date, day) {
  17564. const d = new Date(date);
  17565. d.setDate(day);
  17566. return d;
  17567. }
  17568. function setYear(date, year) {
  17569. const d = new Date(date);
  17570. d.setFullYear(year);
  17571. return d;
  17572. }
  17573. function startOfDay(date) {
  17574. return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0);
  17575. }
  17576. function endOfDay(date) {
  17577. return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999);
  17578. }
  17579. class VuetifyDateAdapter {
  17580. constructor(options) {
  17581. this.locale = options.locale;
  17582. this.formats = options.formats;
  17583. }
  17584. date(value) {
  17585. return date(value);
  17586. }
  17587. toJsDate(date) {
  17588. return date;
  17589. }
  17590. toISO(date) {
  17591. return toISO(this, date);
  17592. }
  17593. parseISO(date) {
  17594. return parseISO(date);
  17595. }
  17596. addMinutes(date, amount) {
  17597. return addMinutes(date, amount);
  17598. }
  17599. addHours(date, amount) {
  17600. return addHours(date, amount);
  17601. }
  17602. addDays(date, amount) {
  17603. return addDays(date, amount);
  17604. }
  17605. addWeeks(date, amount) {
  17606. return addWeeks(date, amount);
  17607. }
  17608. addMonths(date, amount) {
  17609. return addMonths(date, amount);
  17610. }
  17611. getWeekArray(date, firstDayOfWeek) {
  17612. return getWeekArray(date, this.locale, firstDayOfWeek ? Number(firstDayOfWeek) : undefined);
  17613. }
  17614. startOfWeek(date, firstDayOfWeek) {
  17615. return startOfWeek(date, this.locale, firstDayOfWeek ? Number(firstDayOfWeek) : undefined);
  17616. }
  17617. endOfWeek(date) {
  17618. return endOfWeek(date, this.locale);
  17619. }
  17620. startOfMonth(date) {
  17621. return startOfMonth(date);
  17622. }
  17623. endOfMonth(date) {
  17624. return endOfMonth(date);
  17625. }
  17626. format(date, formatString) {
  17627. return format(date, formatString, this.locale, this.formats);
  17628. }
  17629. isEqual(date, comparing) {
  17630. return isEqual(date, comparing);
  17631. }
  17632. isValid(date) {
  17633. return isValid(date);
  17634. }
  17635. isWithinRange(date, range) {
  17636. return isWithinRange(date, range);
  17637. }
  17638. isAfter(date, comparing) {
  17639. return isAfter(date, comparing);
  17640. }
  17641. isAfterDay(date, comparing) {
  17642. return isAfterDay(date, comparing);
  17643. }
  17644. isBefore(date, comparing) {
  17645. return !isAfter(date, comparing) && !isEqual(date, comparing);
  17646. }
  17647. isSameDay(date, comparing) {
  17648. return isSameDay(date, comparing);
  17649. }
  17650. isSameMonth(date, comparing) {
  17651. return isSameMonth(date, comparing);
  17652. }
  17653. isSameYear(date, comparing) {
  17654. return isSameYear(date, comparing);
  17655. }
  17656. setMinutes(date, count) {
  17657. return setMinutes(date, count);
  17658. }
  17659. setHours(date, count) {
  17660. return setHours(date, count);
  17661. }
  17662. setMonth(date, count) {
  17663. return setMonth(date, count);
  17664. }
  17665. setDate(date, day) {
  17666. return setDate(date, day);
  17667. }
  17668. setYear(date, year) {
  17669. return setYear(date, year);
  17670. }
  17671. getDiff(date, comparing, unit) {
  17672. return getDiff(date, comparing, unit);
  17673. }
  17674. getWeekdays(firstDayOfWeek) {
  17675. return getWeekdays(this.locale, firstDayOfWeek ? Number(firstDayOfWeek) : undefined);
  17676. }
  17677. getYear(date) {
  17678. return getYear(date);
  17679. }
  17680. getMonth(date) {
  17681. return getMonth(date);
  17682. }
  17683. getDate(date) {
  17684. return getDate(date);
  17685. }
  17686. getNextMonth(date) {
  17687. return getNextMonth(date);
  17688. }
  17689. getPreviousMonth(date) {
  17690. return getPreviousMonth(date);
  17691. }
  17692. getHours(date) {
  17693. return getHours(date);
  17694. }
  17695. getMinutes(date) {
  17696. return getMinutes(date);
  17697. }
  17698. startOfDay(date) {
  17699. return startOfDay(date);
  17700. }
  17701. endOfDay(date) {
  17702. return endOfDay(date);
  17703. }
  17704. startOfYear(date) {
  17705. return startOfYear(date);
  17706. }
  17707. endOfYear(date) {
  17708. return endOfYear(date);
  17709. }
  17710. }
  17711. // Composables
  17712. const DateOptionsSymbol = Symbol.for('vuetify:date-options');
  17713. const DateAdapterSymbol = Symbol.for('vuetify:date-adapter');
  17714. function createDate(options, locale) {
  17715. const _options = mergeDeep({
  17716. adapter: VuetifyDateAdapter,
  17717. locale: {
  17718. af: 'af-ZA',
  17719. // ar: '', # not the same value for all variants
  17720. bg: 'bg-BG',
  17721. ca: 'ca-ES',
  17722. ckb: '',
  17723. cs: 'cs-CZ',
  17724. de: 'de-DE',
  17725. el: 'el-GR',
  17726. en: 'en-US',
  17727. // es: '', # not the same value for all variants
  17728. et: 'et-EE',
  17729. fa: 'fa-IR',
  17730. fi: 'fi-FI',
  17731. // fr: '', #not the same value for all variants
  17732. hr: 'hr-HR',
  17733. hu: 'hu-HU',
  17734. he: 'he-IL',
  17735. id: 'id-ID',
  17736. it: 'it-IT',
  17737. ja: 'ja-JP',
  17738. ko: 'ko-KR',
  17739. lv: 'lv-LV',
  17740. lt: 'lt-LT',
  17741. nl: 'nl-NL',
  17742. no: 'no-NO',
  17743. pl: 'pl-PL',
  17744. pt: 'pt-PT',
  17745. ro: 'ro-RO',
  17746. ru: 'ru-RU',
  17747. sk: 'sk-SK',
  17748. sl: 'sl-SI',
  17749. srCyrl: 'sr-SP',
  17750. srLatn: 'sr-SP',
  17751. sv: 'sv-SE',
  17752. th: 'th-TH',
  17753. tr: 'tr-TR',
  17754. az: 'az-AZ',
  17755. uk: 'uk-UA',
  17756. vi: 'vi-VN',
  17757. zhHans: 'zh-CN',
  17758. zhHant: 'zh-TW'
  17759. }
  17760. }, options);
  17761. return {
  17762. options: _options,
  17763. instance: createInstance(_options, locale)
  17764. };
  17765. }
  17766. function createInstance(options, locale) {
  17767. const instance = reactive(typeof options.adapter === 'function'
  17768. // eslint-disable-next-line new-cap
  17769. ? new options.adapter({
  17770. locale: options.locale[locale.current.value] ?? locale.current.value,
  17771. formats: options.formats
  17772. }) : options.adapter);
  17773. watch(locale.current, value => {
  17774. instance.locale = options.locale[value] ?? value ?? instance.locale;
  17775. });
  17776. return instance;
  17777. }
  17778. function useDate() {
  17779. const options = inject$1(DateOptionsSymbol);
  17780. if (!options) throw new Error('[Vuetify] Could not find injected date options');
  17781. const locale = useLocale();
  17782. return createInstance(options, locale);
  17783. }
  17784. // https://stackoverflow.com/questions/274861/how-do-i-calculate-the-week-number-given-a-date/275024#275024
  17785. function getWeek(adapter, value) {
  17786. const date = adapter.toJsDate(value);
  17787. let year = date.getFullYear();
  17788. let d1w1 = new Date(year, 0, 1);
  17789. if (date < d1w1) {
  17790. year = year - 1;
  17791. d1w1 = new Date(year, 0, 1);
  17792. } else {
  17793. const tv = new Date(year + 1, 0, 1);
  17794. if (date >= tv) {
  17795. year = year + 1;
  17796. d1w1 = tv;
  17797. }
  17798. }
  17799. const diffTime = Math.abs(date.getTime() - d1w1.getTime());
  17800. const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
  17801. return Math.floor(diffDays / 7) + 1;
  17802. }
  17803. // Types
  17804. const makeVConfirmEditProps = propsFactory({
  17805. modelValue: null,
  17806. color: String,
  17807. cancelText: {
  17808. type: String,
  17809. default: '$vuetify.confirmEdit.cancel'
  17810. },
  17811. okText: {
  17812. type: String,
  17813. default: '$vuetify.confirmEdit.ok'
  17814. }
  17815. }, 'VConfirmEdit');
  17816. const VConfirmEdit = genericComponent()({
  17817. name: 'VConfirmEdit',
  17818. props: makeVConfirmEditProps(),
  17819. emits: {
  17820. cancel: () => true,
  17821. save: value => true,
  17822. 'update:modelValue': value => true
  17823. },
  17824. setup(props, _ref) {
  17825. let {
  17826. emit,
  17827. slots
  17828. } = _ref;
  17829. const model = useProxiedModel(props, 'modelValue');
  17830. const internalModel = ref();
  17831. watchEffect(() => {
  17832. internalModel.value = structuredClone(toRaw(model.value));
  17833. });
  17834. const {
  17835. t
  17836. } = useLocale();
  17837. const isPristine = computed(() => {
  17838. return deepEqual(model.value, internalModel.value);
  17839. });
  17840. function save() {
  17841. model.value = internalModel.value;
  17842. emit('save', internalModel.value);
  17843. }
  17844. function cancel() {
  17845. internalModel.value = structuredClone(toRaw(model.value));
  17846. emit('cancel');
  17847. }
  17848. function actions(actionsProps) {
  17849. return createVNode(Fragment, null, [createVNode(VBtn, mergeProps({
  17850. "disabled": isPristine.value,
  17851. "variant": "text",
  17852. "color": props.color,
  17853. "onClick": cancel,
  17854. "text": t(props.cancelText)
  17855. }, actionsProps), null), createVNode(VBtn, mergeProps({
  17856. "disabled": isPristine.value,
  17857. "variant": "text",
  17858. "color": props.color,
  17859. "onClick": save,
  17860. "text": t(props.okText)
  17861. }, actionsProps), null)]);
  17862. }
  17863. let actionsUsed = false;
  17864. useRender(() => {
  17865. return createVNode(Fragment, null, [slots.default?.({
  17866. model: internalModel,
  17867. save,
  17868. cancel,
  17869. isPristine: isPristine.value,
  17870. get actions() {
  17871. actionsUsed = true;
  17872. return actions;
  17873. }
  17874. }), !actionsUsed && actions()]);
  17875. });
  17876. return {
  17877. save,
  17878. cancel,
  17879. isPristine
  17880. };
  17881. }
  17882. });
  17883. // Composables
  17884. // Types
  17885. const makeDataTableExpandProps = propsFactory({
  17886. expandOnClick: Boolean,
  17887. showExpand: Boolean,
  17888. expanded: {
  17889. type: Array,
  17890. default: () => []
  17891. }
  17892. }, 'DataTable-expand');
  17893. const VDataTableExpandedKey = Symbol.for('vuetify:datatable:expanded');
  17894. function provideExpanded(props) {
  17895. const expandOnClick = toRef(props, 'expandOnClick');
  17896. const expanded = useProxiedModel(props, 'expanded', props.expanded, v => {
  17897. return new Set(v);
  17898. }, v => {
  17899. return [...v.values()];
  17900. });
  17901. function expand(item, value) {
  17902. const newExpanded = new Set(expanded.value);
  17903. if (!value) {
  17904. newExpanded.delete(item.value);
  17905. } else {
  17906. newExpanded.add(item.value);
  17907. }
  17908. expanded.value = newExpanded;
  17909. }
  17910. function isExpanded(item) {
  17911. return expanded.value.has(item.value);
  17912. }
  17913. function toggleExpand(item) {
  17914. expand(item, !isExpanded(item));
  17915. }
  17916. const data = {
  17917. expand,
  17918. expanded,
  17919. expandOnClick,
  17920. isExpanded,
  17921. toggleExpand
  17922. };
  17923. provide(VDataTableExpandedKey, data);
  17924. return data;
  17925. }
  17926. function useExpanded() {
  17927. const data = inject$1(VDataTableExpandedKey);
  17928. if (!data) throw new Error('foo');
  17929. return data;
  17930. }
  17931. // Composables
  17932. // Types
  17933. const makeDataTableGroupProps = propsFactory({
  17934. groupBy: {
  17935. type: Array,
  17936. default: () => []
  17937. }
  17938. }, 'DataTable-group');
  17939. const VDataTableGroupSymbol = Symbol.for('vuetify:data-table-group');
  17940. function createGroupBy(props) {
  17941. const groupBy = useProxiedModel(props, 'groupBy');
  17942. return {
  17943. groupBy
  17944. };
  17945. }
  17946. function provideGroupBy(options) {
  17947. const {
  17948. disableSort,
  17949. groupBy,
  17950. sortBy
  17951. } = options;
  17952. const opened = ref(new Set());
  17953. const sortByWithGroups = computed(() => {
  17954. return groupBy.value.map(val => ({
  17955. ...val,
  17956. order: val.order ?? false
  17957. })).concat(disableSort?.value ? [] : sortBy.value);
  17958. });
  17959. function isGroupOpen(group) {
  17960. return opened.value.has(group.id);
  17961. }
  17962. function toggleGroup(group) {
  17963. const newOpened = new Set(opened.value);
  17964. if (!isGroupOpen(group)) newOpened.add(group.id);else newOpened.delete(group.id);
  17965. opened.value = newOpened;
  17966. }
  17967. function extractRows(items) {
  17968. function dive(group) {
  17969. const arr = [];
  17970. for (const item of group.items) {
  17971. if ('type' in item && item.type === 'group') {
  17972. arr.push(...dive(item));
  17973. } else {
  17974. arr.push(item);
  17975. }
  17976. }
  17977. return arr;
  17978. }
  17979. return dive({
  17980. type: 'group',
  17981. items,
  17982. id: 'dummy',
  17983. key: 'dummy',
  17984. value: 'dummy',
  17985. depth: 0
  17986. });
  17987. }
  17988. // onBeforeMount(() => {
  17989. // for (const key of groupedItems.value.keys()) {
  17990. // opened.value.add(key)
  17991. // }
  17992. // })
  17993. const data = {
  17994. sortByWithGroups,
  17995. toggleGroup,
  17996. opened,
  17997. groupBy,
  17998. extractRows,
  17999. isGroupOpen
  18000. };
  18001. provide(VDataTableGroupSymbol, data);
  18002. return data;
  18003. }
  18004. function useGroupBy() {
  18005. const data = inject$1(VDataTableGroupSymbol);
  18006. if (!data) throw new Error('Missing group!');
  18007. return data;
  18008. }
  18009. function groupItemsByProperty(items, groupBy) {
  18010. if (!items.length) return [];
  18011. const groups = new Map();
  18012. for (const item of items) {
  18013. const value = getObjectValueByPath(item.raw, groupBy);
  18014. if (!groups.has(value)) {
  18015. groups.set(value, []);
  18016. }
  18017. groups.get(value).push(item);
  18018. }
  18019. return groups;
  18020. }
  18021. function groupItems(items, groupBy) {
  18022. let depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
  18023. let prefix = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'root';
  18024. if (!groupBy.length) return [];
  18025. const groupedItems = groupItemsByProperty(items, groupBy[0]);
  18026. const groups = [];
  18027. const rest = groupBy.slice(1);
  18028. groupedItems.forEach((items, value) => {
  18029. const key = groupBy[0];
  18030. const id = `${prefix}_${key}_${value}`;
  18031. groups.push({
  18032. depth,
  18033. id,
  18034. key,
  18035. value,
  18036. items: rest.length ? groupItems(items, rest, depth + 1, id) : items,
  18037. type: 'group'
  18038. });
  18039. });
  18040. return groups;
  18041. }
  18042. function flattenItems(items, opened) {
  18043. const flatItems = [];
  18044. for (const item of items) {
  18045. // TODO: make this better
  18046. if ('type' in item && item.type === 'group') {
  18047. if (item.value != null) {
  18048. flatItems.push(item);
  18049. }
  18050. if (opened.has(item.id) || item.value == null) {
  18051. flatItems.push(...flattenItems(item.items, opened));
  18052. }
  18053. } else {
  18054. flatItems.push(item);
  18055. }
  18056. }
  18057. return flatItems;
  18058. }
  18059. function useGroupedItems(items, groupBy, opened) {
  18060. const flatItems = computed(() => {
  18061. if (!groupBy.value.length) return items.value;
  18062. const groupedItems = groupItems(items.value, groupBy.value.map(item => item.key));
  18063. return flattenItems(groupedItems, opened.value);
  18064. });
  18065. return {
  18066. flatItems
  18067. };
  18068. }
  18069. // Utilities
  18070. // Types
  18071. function useOptions(_ref) {
  18072. let {
  18073. page,
  18074. itemsPerPage,
  18075. sortBy,
  18076. groupBy,
  18077. search
  18078. } = _ref;
  18079. const vm = getCurrentInstance('VDataTable');
  18080. const options = computed(() => ({
  18081. page: page.value,
  18082. itemsPerPage: itemsPerPage.value,
  18083. sortBy: sortBy.value,
  18084. groupBy: groupBy.value,
  18085. search: search.value
  18086. }));
  18087. let oldOptions = null;
  18088. watch(options, () => {
  18089. if (deepEqual(oldOptions, options.value)) return;
  18090. // Reset page when searching
  18091. if (oldOptions && oldOptions.search !== options.value.search) {
  18092. page.value = 1;
  18093. }
  18094. vm.emit('update:options', options.value);
  18095. oldOptions = options.value;
  18096. }, {
  18097. deep: true,
  18098. immediate: true
  18099. });
  18100. }
  18101. // Composables
  18102. // Types
  18103. const makeDataTablePaginateProps = propsFactory({
  18104. page: {
  18105. type: [Number, String],
  18106. default: 1
  18107. },
  18108. itemsPerPage: {
  18109. type: [Number, String],
  18110. default: 10
  18111. }
  18112. }, 'DataTable-paginate');
  18113. const VDataTablePaginationSymbol = Symbol.for('vuetify:data-table-pagination');
  18114. function createPagination(props) {
  18115. const page = useProxiedModel(props, 'page', undefined, value => +(value ?? 1));
  18116. const itemsPerPage = useProxiedModel(props, 'itemsPerPage', undefined, value => +(value ?? 10));
  18117. return {
  18118. page,
  18119. itemsPerPage
  18120. };
  18121. }
  18122. function providePagination(options) {
  18123. const {
  18124. page,
  18125. itemsPerPage,
  18126. itemsLength
  18127. } = options;
  18128. const startIndex = computed(() => {
  18129. if (itemsPerPage.value === -1) return 0;
  18130. return itemsPerPage.value * (page.value - 1);
  18131. });
  18132. const stopIndex = computed(() => {
  18133. if (itemsPerPage.value === -1) return itemsLength.value;
  18134. return Math.min(itemsLength.value, startIndex.value + itemsPerPage.value);
  18135. });
  18136. const pageCount = computed(() => {
  18137. if (itemsPerPage.value === -1 || itemsLength.value === 0) return 1;
  18138. return Math.ceil(itemsLength.value / itemsPerPage.value);
  18139. });
  18140. // Don't run immediately, items may not have been loaded yet: #17966
  18141. watch([page, pageCount], () => {
  18142. if (page.value > pageCount.value) {
  18143. page.value = pageCount.value;
  18144. }
  18145. });
  18146. function setItemsPerPage(value) {
  18147. itemsPerPage.value = value;
  18148. page.value = 1;
  18149. }
  18150. function nextPage() {
  18151. page.value = clamp(page.value + 1, 1, pageCount.value);
  18152. }
  18153. function prevPage() {
  18154. page.value = clamp(page.value - 1, 1, pageCount.value);
  18155. }
  18156. function setPage(value) {
  18157. page.value = clamp(value, 1, pageCount.value);
  18158. }
  18159. const data = {
  18160. page,
  18161. itemsPerPage,
  18162. startIndex,
  18163. stopIndex,
  18164. pageCount,
  18165. itemsLength,
  18166. nextPage,
  18167. prevPage,
  18168. setPage,
  18169. setItemsPerPage
  18170. };
  18171. provide(VDataTablePaginationSymbol, data);
  18172. return data;
  18173. }
  18174. function usePagination() {
  18175. const data = inject$1(VDataTablePaginationSymbol);
  18176. if (!data) throw new Error('Missing pagination!');
  18177. return data;
  18178. }
  18179. function usePaginatedItems(options) {
  18180. const vm = getCurrentInstance('usePaginatedItems');
  18181. const {
  18182. items,
  18183. startIndex,
  18184. stopIndex,
  18185. itemsPerPage
  18186. } = options;
  18187. const paginatedItems = computed(() => {
  18188. if (itemsPerPage.value <= 0) return items.value;
  18189. return items.value.slice(startIndex.value, stopIndex.value);
  18190. });
  18191. watch(paginatedItems, val => {
  18192. vm.emit('update:currentItems', val);
  18193. });
  18194. return {
  18195. paginatedItems
  18196. };
  18197. }
  18198. // Composables
  18199. // Types
  18200. const singleSelectStrategy = {
  18201. showSelectAll: false,
  18202. allSelected: () => [],
  18203. select: _ref => {
  18204. let {
  18205. items,
  18206. value
  18207. } = _ref;
  18208. return new Set(value ? [items[0]?.value] : []);
  18209. },
  18210. selectAll: _ref2 => {
  18211. let {
  18212. selected
  18213. } = _ref2;
  18214. return selected;
  18215. }
  18216. };
  18217. const pageSelectStrategy = {
  18218. showSelectAll: true,
  18219. allSelected: _ref3 => {
  18220. let {
  18221. currentPage
  18222. } = _ref3;
  18223. return currentPage;
  18224. },
  18225. select: _ref4 => {
  18226. let {
  18227. items,
  18228. value,
  18229. selected
  18230. } = _ref4;
  18231. for (const item of items) {
  18232. if (value) selected.add(item.value);else selected.delete(item.value);
  18233. }
  18234. return selected;
  18235. },
  18236. selectAll: _ref5 => {
  18237. let {
  18238. value,
  18239. currentPage,
  18240. selected
  18241. } = _ref5;
  18242. return pageSelectStrategy.select({
  18243. items: currentPage,
  18244. value,
  18245. selected
  18246. });
  18247. }
  18248. };
  18249. const allSelectStrategy = {
  18250. showSelectAll: true,
  18251. allSelected: _ref6 => {
  18252. let {
  18253. allItems
  18254. } = _ref6;
  18255. return allItems;
  18256. },
  18257. select: _ref7 => {
  18258. let {
  18259. items,
  18260. value,
  18261. selected
  18262. } = _ref7;
  18263. for (const item of items) {
  18264. if (value) selected.add(item.value);else selected.delete(item.value);
  18265. }
  18266. return selected;
  18267. },
  18268. selectAll: _ref8 => {
  18269. let {
  18270. value,
  18271. allItems,
  18272. selected
  18273. } = _ref8;
  18274. return allSelectStrategy.select({
  18275. items: allItems,
  18276. value,
  18277. selected
  18278. });
  18279. }
  18280. };
  18281. const makeDataTableSelectProps = propsFactory({
  18282. showSelect: Boolean,
  18283. selectStrategy: {
  18284. type: [String, Object],
  18285. default: 'page'
  18286. },
  18287. modelValue: {
  18288. type: Array,
  18289. default: () => []
  18290. },
  18291. valueComparator: {
  18292. type: Function,
  18293. default: deepEqual
  18294. }
  18295. }, 'DataTable-select');
  18296. const VDataTableSelectionSymbol = Symbol.for('vuetify:data-table-selection');
  18297. function provideSelection(props, _ref9) {
  18298. let {
  18299. allItems,
  18300. currentPage
  18301. } = _ref9;
  18302. const selected = useProxiedModel(props, 'modelValue', props.modelValue, v => {
  18303. return new Set(wrapInArray(v).map(v => {
  18304. return allItems.value.find(item => props.valueComparator(v, item.value))?.value ?? v;
  18305. }));
  18306. }, v => {
  18307. return [...v.values()];
  18308. });
  18309. const allSelectable = computed(() => allItems.value.filter(item => item.selectable));
  18310. const currentPageSelectable = computed(() => currentPage.value.filter(item => item.selectable));
  18311. const selectStrategy = computed(() => {
  18312. if (typeof props.selectStrategy === 'object') return props.selectStrategy;
  18313. switch (props.selectStrategy) {
  18314. case 'single':
  18315. return singleSelectStrategy;
  18316. case 'all':
  18317. return allSelectStrategy;
  18318. case 'page':
  18319. default:
  18320. return pageSelectStrategy;
  18321. }
  18322. });
  18323. function isSelected(items) {
  18324. return wrapInArray(items).every(item => selected.value.has(item.value));
  18325. }
  18326. function isSomeSelected(items) {
  18327. return wrapInArray(items).some(item => selected.value.has(item.value));
  18328. }
  18329. function select(items, value) {
  18330. const newSelected = selectStrategy.value.select({
  18331. items,
  18332. value,
  18333. selected: new Set(selected.value)
  18334. });
  18335. selected.value = newSelected;
  18336. }
  18337. function toggleSelect(item) {
  18338. select([item], !isSelected([item]));
  18339. }
  18340. function selectAll(value) {
  18341. const newSelected = selectStrategy.value.selectAll({
  18342. value,
  18343. allItems: allSelectable.value,
  18344. currentPage: currentPageSelectable.value,
  18345. selected: new Set(selected.value)
  18346. });
  18347. selected.value = newSelected;
  18348. }
  18349. const someSelected = computed(() => selected.value.size > 0);
  18350. const allSelected = computed(() => {
  18351. const items = selectStrategy.value.allSelected({
  18352. allItems: allSelectable.value,
  18353. currentPage: currentPageSelectable.value
  18354. });
  18355. return !!items.length && isSelected(items);
  18356. });
  18357. const showSelectAll = computed(() => selectStrategy.value.showSelectAll);
  18358. const data = {
  18359. toggleSelect,
  18360. select,
  18361. selectAll,
  18362. isSelected,
  18363. isSomeSelected,
  18364. someSelected,
  18365. allSelected,
  18366. showSelectAll
  18367. };
  18368. provide(VDataTableSelectionSymbol, data);
  18369. return data;
  18370. }
  18371. function useSelection() {
  18372. const data = inject$1(VDataTableSelectionSymbol);
  18373. if (!data) throw new Error('Missing selection!');
  18374. return data;
  18375. }
  18376. // Composables
  18377. // Types
  18378. const makeDataTableSortProps = propsFactory({
  18379. sortBy: {
  18380. type: Array,
  18381. default: () => []
  18382. },
  18383. customKeySort: Object,
  18384. multiSort: Boolean,
  18385. mustSort: Boolean
  18386. }, 'DataTable-sort');
  18387. const VDataTableSortSymbol = Symbol.for('vuetify:data-table-sort');
  18388. function createSort(props) {
  18389. const sortBy = useProxiedModel(props, 'sortBy');
  18390. const mustSort = toRef(props, 'mustSort');
  18391. const multiSort = toRef(props, 'multiSort');
  18392. return {
  18393. sortBy,
  18394. mustSort,
  18395. multiSort
  18396. };
  18397. }
  18398. function provideSort(options) {
  18399. const {
  18400. sortBy,
  18401. mustSort,
  18402. multiSort,
  18403. page
  18404. } = options;
  18405. const toggleSort = column => {
  18406. if (column.key == null) return;
  18407. let newSortBy = sortBy.value.map(x => ({
  18408. ...x
  18409. })) ?? [];
  18410. const item = newSortBy.find(x => x.key === column.key);
  18411. if (!item) {
  18412. if (multiSort.value) newSortBy = [...newSortBy, {
  18413. key: column.key,
  18414. order: 'asc'
  18415. }];else newSortBy = [{
  18416. key: column.key,
  18417. order: 'asc'
  18418. }];
  18419. } else if (item.order === 'desc') {
  18420. if (mustSort.value) {
  18421. item.order = 'asc';
  18422. } else {
  18423. newSortBy = newSortBy.filter(x => x.key !== column.key);
  18424. }
  18425. } else {
  18426. item.order = 'desc';
  18427. }
  18428. sortBy.value = newSortBy;
  18429. if (page) page.value = 1;
  18430. };
  18431. function isSorted(column) {
  18432. return !!sortBy.value.find(item => item.key === column.key);
  18433. }
  18434. const data = {
  18435. sortBy,
  18436. toggleSort,
  18437. isSorted
  18438. };
  18439. provide(VDataTableSortSymbol, data);
  18440. return data;
  18441. }
  18442. function useSort() {
  18443. const data = inject$1(VDataTableSortSymbol);
  18444. if (!data) throw new Error('Missing sort!');
  18445. return data;
  18446. }
  18447. // TODO: abstract into project composable
  18448. function useSortedItems(props, items, sortBy, options) {
  18449. const locale = useLocale();
  18450. const sortedItems = computed(() => {
  18451. if (!sortBy.value.length) return items.value;
  18452. return sortItems(items.value, sortBy.value, locale.current.value, {
  18453. transform: options?.transform,
  18454. sortFunctions: {
  18455. ...props.customKeySort,
  18456. ...options?.sortFunctions?.value
  18457. },
  18458. sortRawFunctions: options?.sortRawFunctions?.value
  18459. });
  18460. });
  18461. return {
  18462. sortedItems
  18463. };
  18464. }
  18465. function sortItems(items, sortByItems, locale, options) {
  18466. const stringCollator = new Intl.Collator(locale, {
  18467. sensitivity: 'accent',
  18468. usage: 'sort'
  18469. });
  18470. const transformedItems = items.map(item => [item, options?.transform ? options.transform(item) : item]);
  18471. return transformedItems.sort((a, b) => {
  18472. for (let i = 0; i < sortByItems.length; i++) {
  18473. let hasCustomResult = false;
  18474. const sortKey = sortByItems[i].key;
  18475. const sortOrder = sortByItems[i].order ?? 'asc';
  18476. if (sortOrder === false) continue;
  18477. let sortA = getObjectValueByPath(a[1], sortKey);
  18478. let sortB = getObjectValueByPath(b[1], sortKey);
  18479. let sortARaw = a[0].raw;
  18480. let sortBRaw = b[0].raw;
  18481. if (sortOrder === 'desc') {
  18482. [sortA, sortB] = [sortB, sortA];
  18483. [sortARaw, sortBRaw] = [sortBRaw, sortARaw];
  18484. }
  18485. if (options?.sortRawFunctions?.[sortKey]) {
  18486. const customResult = options.sortRawFunctions[sortKey](sortARaw, sortBRaw);
  18487. if (customResult == null) continue;
  18488. hasCustomResult = true;
  18489. if (customResult) return customResult;
  18490. }
  18491. if (options?.sortFunctions?.[sortKey]) {
  18492. const customResult = options.sortFunctions[sortKey](sortA, sortB);
  18493. if (customResult == null) continue;
  18494. hasCustomResult = true;
  18495. if (customResult) return customResult;
  18496. }
  18497. if (hasCustomResult) continue;
  18498. // Dates should be compared numerically
  18499. if (sortA instanceof Date && sortB instanceof Date) {
  18500. return sortA.getTime() - sortB.getTime();
  18501. }
  18502. [sortA, sortB] = [sortA, sortB].map(s => s != null ? s.toString().toLocaleLowerCase() : s);
  18503. if (sortA !== sortB) {
  18504. if (isEmpty(sortA) && isEmpty(sortB)) return 0;
  18505. if (isEmpty(sortA)) return -1;
  18506. if (isEmpty(sortB)) return 1;
  18507. if (!isNaN(sortA) && !isNaN(sortB)) return Number(sortA) - Number(sortB);
  18508. return stringCollator.compare(sortA, sortB);
  18509. }
  18510. }
  18511. return 0;
  18512. }).map(_ref => {
  18513. let [item] = _ref;
  18514. return item;
  18515. });
  18516. }
  18517. // Utilities
  18518. // Types
  18519. // Composables
  18520. const makeDataIteratorItemsProps = propsFactory({
  18521. items: {
  18522. type: Array,
  18523. default: () => []
  18524. },
  18525. itemValue: {
  18526. type: [String, Array, Function],
  18527. default: 'id'
  18528. },
  18529. itemSelectable: {
  18530. type: [String, Array, Function],
  18531. default: null
  18532. },
  18533. returnObject: Boolean
  18534. }, 'DataIterator-items');
  18535. function transformItem$1(props, item) {
  18536. const value = props.returnObject ? item : getPropertyFromItem(item, props.itemValue);
  18537. const selectable = getPropertyFromItem(item, props.itemSelectable, true);
  18538. return {
  18539. type: 'item',
  18540. value,
  18541. selectable,
  18542. raw: item
  18543. };
  18544. }
  18545. function transformItems$1(props, items) {
  18546. const array = [];
  18547. for (const item of items) {
  18548. array.push(transformItem$1(props, item));
  18549. }
  18550. return array;
  18551. }
  18552. function useDataIteratorItems(props) {
  18553. const items = computed(() => transformItems$1(props, props.items));
  18554. return {
  18555. items
  18556. };
  18557. }
  18558. // Types
  18559. const makeVDataIteratorProps = propsFactory({
  18560. search: String,
  18561. loading: Boolean,
  18562. ...makeComponentProps(),
  18563. ...makeDataIteratorItemsProps(),
  18564. ...makeDataTableSelectProps(),
  18565. ...makeDataTableSortProps(),
  18566. ...makeDataTablePaginateProps({
  18567. itemsPerPage: 5
  18568. }),
  18569. ...makeDataTableExpandProps(),
  18570. ...makeDataTableGroupProps(),
  18571. ...makeFilterProps(),
  18572. ...makeTagProps(),
  18573. ...makeTransitionProps({
  18574. transition: {
  18575. component: VFadeTransition,
  18576. hideOnLeave: true
  18577. }
  18578. })
  18579. }, 'VDataIterator');
  18580. const VDataIterator = genericComponent()({
  18581. name: 'VDataIterator',
  18582. props: makeVDataIteratorProps(),
  18583. emits: {
  18584. 'update:modelValue': value => true,
  18585. 'update:groupBy': value => true,
  18586. 'update:page': value => true,
  18587. 'update:itemsPerPage': value => true,
  18588. 'update:sortBy': value => true,
  18589. 'update:options': value => true,
  18590. 'update:expanded': value => true,
  18591. 'update:currentItems': value => true
  18592. },
  18593. setup(props, _ref) {
  18594. let {
  18595. slots
  18596. } = _ref;
  18597. const groupBy = useProxiedModel(props, 'groupBy');
  18598. const search = toRef(props, 'search');
  18599. const {
  18600. items
  18601. } = useDataIteratorItems(props);
  18602. const {
  18603. filteredItems
  18604. } = useFilter(props, items, search, {
  18605. transform: item => item.raw
  18606. });
  18607. const {
  18608. sortBy,
  18609. multiSort,
  18610. mustSort
  18611. } = createSort(props);
  18612. const {
  18613. page,
  18614. itemsPerPage
  18615. } = createPagination(props);
  18616. const {
  18617. toggleSort
  18618. } = provideSort({
  18619. sortBy,
  18620. multiSort,
  18621. mustSort,
  18622. page
  18623. });
  18624. const {
  18625. sortByWithGroups,
  18626. opened,
  18627. extractRows,
  18628. isGroupOpen,
  18629. toggleGroup
  18630. } = provideGroupBy({
  18631. groupBy,
  18632. sortBy
  18633. });
  18634. const {
  18635. sortedItems
  18636. } = useSortedItems(props, filteredItems, sortByWithGroups, {
  18637. transform: item => item.raw
  18638. });
  18639. const {
  18640. flatItems
  18641. } = useGroupedItems(sortedItems, groupBy, opened);
  18642. const itemsLength = computed(() => flatItems.value.length);
  18643. const {
  18644. startIndex,
  18645. stopIndex,
  18646. pageCount,
  18647. prevPage,
  18648. nextPage,
  18649. setItemsPerPage,
  18650. setPage
  18651. } = providePagination({
  18652. page,
  18653. itemsPerPage,
  18654. itemsLength
  18655. });
  18656. const {
  18657. paginatedItems
  18658. } = usePaginatedItems({
  18659. items: flatItems,
  18660. startIndex,
  18661. stopIndex,
  18662. itemsPerPage
  18663. });
  18664. const paginatedItemsWithoutGroups = computed(() => extractRows(paginatedItems.value));
  18665. const {
  18666. isSelected,
  18667. select,
  18668. selectAll,
  18669. toggleSelect
  18670. } = provideSelection(props, {
  18671. allItems: items,
  18672. currentPage: paginatedItemsWithoutGroups
  18673. });
  18674. const {
  18675. isExpanded,
  18676. toggleExpand
  18677. } = provideExpanded(props);
  18678. useOptions({
  18679. page,
  18680. itemsPerPage,
  18681. sortBy,
  18682. groupBy,
  18683. search
  18684. });
  18685. const slotProps = computed(() => ({
  18686. page: page.value,
  18687. itemsPerPage: itemsPerPage.value,
  18688. sortBy: sortBy.value,
  18689. pageCount: pageCount.value,
  18690. toggleSort,
  18691. prevPage,
  18692. nextPage,
  18693. setPage,
  18694. setItemsPerPage,
  18695. isSelected,
  18696. select,
  18697. selectAll,
  18698. toggleSelect,
  18699. isExpanded,
  18700. toggleExpand,
  18701. isGroupOpen,
  18702. toggleGroup,
  18703. items: paginatedItemsWithoutGroups.value,
  18704. groupedItems: paginatedItems.value
  18705. }));
  18706. useRender(() => createVNode(props.tag, {
  18707. "class": ['v-data-iterator', {
  18708. 'v-data-iterator--loading': props.loading
  18709. }, props.class],
  18710. "style": props.style
  18711. }, {
  18712. default: () => [slots.header?.(slotProps.value), createVNode(MaybeTransition, {
  18713. "transition": props.transition
  18714. }, {
  18715. default: () => [props.loading ? createVNode(LoaderSlot, {
  18716. "key": "loader",
  18717. "name": "v-data-iterator",
  18718. "active": true
  18719. }, {
  18720. default: slotProps => slots.loader?.(slotProps)
  18721. }) : createVNode("div", {
  18722. "key": "items"
  18723. }, [!paginatedItems.value.length ? slots['no-data']?.() : slots.default?.(slotProps.value)])]
  18724. }), slots.footer?.(slotProps.value)]
  18725. }));
  18726. return {};
  18727. }
  18728. });
  18729. // Utilities
  18730. // Types
  18731. function useRefs() {
  18732. const refs = ref([]);
  18733. onBeforeUpdate(() => refs.value = []);
  18734. function updateRef(e, i) {
  18735. refs.value[i] = e;
  18736. }
  18737. return {
  18738. refs,
  18739. updateRef
  18740. };
  18741. }
  18742. // Types
  18743. const makeVPaginationProps = propsFactory({
  18744. activeColor: String,
  18745. start: {
  18746. type: [Number, String],
  18747. default: 1
  18748. },
  18749. modelValue: {
  18750. type: Number,
  18751. default: props => props.start
  18752. },
  18753. disabled: Boolean,
  18754. length: {
  18755. type: [Number, String],
  18756. default: 1,
  18757. validator: val => val % 1 === 0
  18758. },
  18759. totalVisible: [Number, String],
  18760. firstIcon: {
  18761. type: IconValue,
  18762. default: '$first'
  18763. },
  18764. prevIcon: {
  18765. type: IconValue,
  18766. default: '$prev'
  18767. },
  18768. nextIcon: {
  18769. type: IconValue,
  18770. default: '$next'
  18771. },
  18772. lastIcon: {
  18773. type: IconValue,
  18774. default: '$last'
  18775. },
  18776. ariaLabel: {
  18777. type: String,
  18778. default: '$vuetify.pagination.ariaLabel.root'
  18779. },
  18780. pageAriaLabel: {
  18781. type: String,
  18782. default: '$vuetify.pagination.ariaLabel.page'
  18783. },
  18784. currentPageAriaLabel: {
  18785. type: String,
  18786. default: '$vuetify.pagination.ariaLabel.currentPage'
  18787. },
  18788. firstAriaLabel: {
  18789. type: String,
  18790. default: '$vuetify.pagination.ariaLabel.first'
  18791. },
  18792. previousAriaLabel: {
  18793. type: String,
  18794. default: '$vuetify.pagination.ariaLabel.previous'
  18795. },
  18796. nextAriaLabel: {
  18797. type: String,
  18798. default: '$vuetify.pagination.ariaLabel.next'
  18799. },
  18800. lastAriaLabel: {
  18801. type: String,
  18802. default: '$vuetify.pagination.ariaLabel.last'
  18803. },
  18804. ellipsis: {
  18805. type: String,
  18806. default: '...'
  18807. },
  18808. showFirstLastPage: Boolean,
  18809. ...makeBorderProps(),
  18810. ...makeComponentProps(),
  18811. ...makeDensityProps(),
  18812. ...makeElevationProps(),
  18813. ...makeRoundedProps(),
  18814. ...makeSizeProps(),
  18815. ...makeTagProps({
  18816. tag: 'nav'
  18817. }),
  18818. ...makeThemeProps(),
  18819. ...makeVariantProps({
  18820. variant: 'text'
  18821. })
  18822. }, 'VPagination');
  18823. const VPagination = genericComponent()({
  18824. name: 'VPagination',
  18825. props: makeVPaginationProps(),
  18826. emits: {
  18827. 'update:modelValue': value => true,
  18828. first: value => true,
  18829. prev: value => true,
  18830. next: value => true,
  18831. last: value => true
  18832. },
  18833. setup(props, _ref) {
  18834. let {
  18835. slots,
  18836. emit
  18837. } = _ref;
  18838. const page = useProxiedModel(props, 'modelValue');
  18839. const {
  18840. t,
  18841. n
  18842. } = useLocale();
  18843. const {
  18844. isRtl
  18845. } = useRtl();
  18846. const {
  18847. themeClasses
  18848. } = provideTheme(props);
  18849. const {
  18850. width
  18851. } = useDisplay();
  18852. const maxButtons = shallowRef(-1);
  18853. provideDefaults(undefined, {
  18854. scoped: true
  18855. });
  18856. const {
  18857. resizeRef
  18858. } = useResizeObserver(entries => {
  18859. if (!entries.length) return;
  18860. const {
  18861. target,
  18862. contentRect
  18863. } = entries[0];
  18864. const firstItem = target.querySelector('.v-pagination__list > *');
  18865. if (!firstItem) return;
  18866. const totalWidth = contentRect.width;
  18867. const itemWidth = firstItem.offsetWidth + parseFloat(getComputedStyle(firstItem).marginRight) * 2;
  18868. maxButtons.value = getMax(totalWidth, itemWidth);
  18869. });
  18870. const length = computed(() => parseInt(props.length, 10));
  18871. const start = computed(() => parseInt(props.start, 10));
  18872. const totalVisible = computed(() => {
  18873. if (props.totalVisible != null) return parseInt(props.totalVisible, 10);else if (maxButtons.value >= 0) return maxButtons.value;
  18874. return getMax(width.value, 58);
  18875. });
  18876. function getMax(totalWidth, itemWidth) {
  18877. const minButtons = props.showFirstLastPage ? 5 : 3;
  18878. return Math.max(0, Math.floor(
  18879. // Round to two decimal places to avoid floating point errors
  18880. +((totalWidth - itemWidth * minButtons) / itemWidth).toFixed(2)));
  18881. }
  18882. const range = computed(() => {
  18883. if (length.value <= 0 || isNaN(length.value) || length.value > Number.MAX_SAFE_INTEGER) return [];
  18884. if (totalVisible.value <= 0) return [];else if (totalVisible.value === 1) return [page.value];
  18885. if (length.value <= totalVisible.value) {
  18886. return createRange(length.value, start.value);
  18887. }
  18888. const even = totalVisible.value % 2 === 0;
  18889. const middle = even ? totalVisible.value / 2 : Math.floor(totalVisible.value / 2);
  18890. const left = even ? middle : middle + 1;
  18891. const right = length.value - middle;
  18892. if (left - page.value >= 0) {
  18893. return [...createRange(Math.max(1, totalVisible.value - 1), start.value), props.ellipsis, length.value];
  18894. } else if (page.value - right >= (even ? 1 : 0)) {
  18895. const rangeLength = totalVisible.value - 1;
  18896. const rangeStart = length.value - rangeLength + start.value;
  18897. return [start.value, props.ellipsis, ...createRange(rangeLength, rangeStart)];
  18898. } else {
  18899. const rangeLength = Math.max(1, totalVisible.value - 3);
  18900. const rangeStart = rangeLength === 1 ? page.value : page.value - Math.ceil(rangeLength / 2) + start.value;
  18901. return [start.value, props.ellipsis, ...createRange(rangeLength, rangeStart), props.ellipsis, length.value];
  18902. }
  18903. });
  18904. // TODO: 'first' | 'prev' | 'next' | 'last' does not work here?
  18905. function setValue(e, value, event) {
  18906. e.preventDefault();
  18907. page.value = value;
  18908. event && emit(event, value);
  18909. }
  18910. const {
  18911. refs,
  18912. updateRef
  18913. } = useRefs();
  18914. provideDefaults({
  18915. VPaginationBtn: {
  18916. color: toRef(props, 'color'),
  18917. border: toRef(props, 'border'),
  18918. density: toRef(props, 'density'),
  18919. size: toRef(props, 'size'),
  18920. variant: toRef(props, 'variant'),
  18921. rounded: toRef(props, 'rounded'),
  18922. elevation: toRef(props, 'elevation')
  18923. }
  18924. });
  18925. const items = computed(() => {
  18926. return range.value.map((item, index) => {
  18927. const ref = e => updateRef(e, index);
  18928. if (typeof item === 'string') {
  18929. return {
  18930. isActive: false,
  18931. key: `ellipsis-${index}`,
  18932. page: item,
  18933. props: {
  18934. ref,
  18935. ellipsis: true,
  18936. icon: true,
  18937. disabled: true
  18938. }
  18939. };
  18940. } else {
  18941. const isActive = item === page.value;
  18942. return {
  18943. isActive,
  18944. key: item,
  18945. page: n(item),
  18946. props: {
  18947. ref,
  18948. ellipsis: false,
  18949. icon: true,
  18950. disabled: !!props.disabled || +props.length < 2,
  18951. color: isActive ? props.activeColor : props.color,
  18952. 'aria-current': isActive,
  18953. 'aria-label': t(isActive ? props.currentPageAriaLabel : props.pageAriaLabel, item),
  18954. onClick: e => setValue(e, item)
  18955. }
  18956. };
  18957. }
  18958. });
  18959. });
  18960. const controls = computed(() => {
  18961. const prevDisabled = !!props.disabled || page.value <= start.value;
  18962. const nextDisabled = !!props.disabled || page.value >= start.value + length.value - 1;
  18963. return {
  18964. first: props.showFirstLastPage ? {
  18965. icon: isRtl.value ? props.lastIcon : props.firstIcon,
  18966. onClick: e => setValue(e, start.value, 'first'),
  18967. disabled: prevDisabled,
  18968. 'aria-label': t(props.firstAriaLabel),
  18969. 'aria-disabled': prevDisabled
  18970. } : undefined,
  18971. prev: {
  18972. icon: isRtl.value ? props.nextIcon : props.prevIcon,
  18973. onClick: e => setValue(e, page.value - 1, 'prev'),
  18974. disabled: prevDisabled,
  18975. 'aria-label': t(props.previousAriaLabel),
  18976. 'aria-disabled': prevDisabled
  18977. },
  18978. next: {
  18979. icon: isRtl.value ? props.prevIcon : props.nextIcon,
  18980. onClick: e => setValue(e, page.value + 1, 'next'),
  18981. disabled: nextDisabled,
  18982. 'aria-label': t(props.nextAriaLabel),
  18983. 'aria-disabled': nextDisabled
  18984. },
  18985. last: props.showFirstLastPage ? {
  18986. icon: isRtl.value ? props.firstIcon : props.lastIcon,
  18987. onClick: e => setValue(e, start.value + length.value - 1, 'last'),
  18988. disabled: nextDisabled,
  18989. 'aria-label': t(props.lastAriaLabel),
  18990. 'aria-disabled': nextDisabled
  18991. } : undefined
  18992. };
  18993. });
  18994. function updateFocus() {
  18995. const currentIndex = page.value - start.value;
  18996. refs.value[currentIndex]?.$el.focus();
  18997. }
  18998. function onKeydown(e) {
  18999. if (e.key === keyValues.left && !props.disabled && page.value > +props.start) {
  19000. page.value = page.value - 1;
  19001. nextTick(updateFocus);
  19002. } else if (e.key === keyValues.right && !props.disabled && page.value < start.value + length.value - 1) {
  19003. page.value = page.value + 1;
  19004. nextTick(updateFocus);
  19005. }
  19006. }
  19007. useRender(() => createVNode(props.tag, {
  19008. "ref": resizeRef,
  19009. "class": ['v-pagination', themeClasses.value, props.class],
  19010. "style": props.style,
  19011. "role": "navigation",
  19012. "aria-label": t(props.ariaLabel),
  19013. "onKeydown": onKeydown,
  19014. "data-test": "v-pagination-root"
  19015. }, {
  19016. default: () => [createVNode("ul", {
  19017. "class": "v-pagination__list"
  19018. }, [props.showFirstLastPage && createVNode("li", {
  19019. "key": "first",
  19020. "class": "v-pagination__first",
  19021. "data-test": "v-pagination-first"
  19022. }, [slots.first ? slots.first(controls.value.first) : createVNode(VBtn, mergeProps({
  19023. "_as": "VPaginationBtn"
  19024. }, controls.value.first), null)]), createVNode("li", {
  19025. "key": "prev",
  19026. "class": "v-pagination__prev",
  19027. "data-test": "v-pagination-prev"
  19028. }, [slots.prev ? slots.prev(controls.value.prev) : createVNode(VBtn, mergeProps({
  19029. "_as": "VPaginationBtn"
  19030. }, controls.value.prev), null)]), items.value.map((item, index) => createVNode("li", {
  19031. "key": item.key,
  19032. "class": ['v-pagination__item', {
  19033. 'v-pagination__item--is-active': item.isActive
  19034. }],
  19035. "data-test": "v-pagination-item"
  19036. }, [slots.item ? slots.item(item) : createVNode(VBtn, mergeProps({
  19037. "_as": "VPaginationBtn"
  19038. }, item.props), {
  19039. default: () => [item.page]
  19040. })])), createVNode("li", {
  19041. "key": "next",
  19042. "class": "v-pagination__next",
  19043. "data-test": "v-pagination-next"
  19044. }, [slots.next ? slots.next(controls.value.next) : createVNode(VBtn, mergeProps({
  19045. "_as": "VPaginationBtn"
  19046. }, controls.value.next), null)]), props.showFirstLastPage && createVNode("li", {
  19047. "key": "last",
  19048. "class": "v-pagination__last",
  19049. "data-test": "v-pagination-last"
  19050. }, [slots.last ? slots.last(controls.value.last) : createVNode(VBtn, mergeProps({
  19051. "_as": "VPaginationBtn"
  19052. }, controls.value.last), null)])])]
  19053. }));
  19054. return {};
  19055. }
  19056. });
  19057. // Types
  19058. const makeVDataTableFooterProps = propsFactory({
  19059. prevIcon: {
  19060. type: IconValue,
  19061. default: '$prev'
  19062. },
  19063. nextIcon: {
  19064. type: IconValue,
  19065. default: '$next'
  19066. },
  19067. firstIcon: {
  19068. type: IconValue,
  19069. default: '$first'
  19070. },
  19071. lastIcon: {
  19072. type: IconValue,
  19073. default: '$last'
  19074. },
  19075. itemsPerPageText: {
  19076. type: String,
  19077. default: '$vuetify.dataFooter.itemsPerPageText'
  19078. },
  19079. pageText: {
  19080. type: String,
  19081. default: '$vuetify.dataFooter.pageText'
  19082. },
  19083. firstPageLabel: {
  19084. type: String,
  19085. default: '$vuetify.dataFooter.firstPage'
  19086. },
  19087. prevPageLabel: {
  19088. type: String,
  19089. default: '$vuetify.dataFooter.prevPage'
  19090. },
  19091. nextPageLabel: {
  19092. type: String,
  19093. default: '$vuetify.dataFooter.nextPage'
  19094. },
  19095. lastPageLabel: {
  19096. type: String,
  19097. default: '$vuetify.dataFooter.lastPage'
  19098. },
  19099. itemsPerPageOptions: {
  19100. type: Array,
  19101. default: () => [{
  19102. value: 10,
  19103. title: '10'
  19104. }, {
  19105. value: 25,
  19106. title: '25'
  19107. }, {
  19108. value: 50,
  19109. title: '50'
  19110. }, {
  19111. value: 100,
  19112. title: '100'
  19113. }, {
  19114. value: -1,
  19115. title: '$vuetify.dataFooter.itemsPerPageAll'
  19116. }]
  19117. },
  19118. showCurrentPage: Boolean
  19119. }, 'VDataTableFooter');
  19120. const VDataTableFooter = genericComponent()({
  19121. name: 'VDataTableFooter',
  19122. props: makeVDataTableFooterProps(),
  19123. setup(props, _ref) {
  19124. let {
  19125. slots
  19126. } = _ref;
  19127. const {
  19128. t
  19129. } = useLocale();
  19130. const {
  19131. page,
  19132. pageCount,
  19133. startIndex,
  19134. stopIndex,
  19135. itemsLength,
  19136. itemsPerPage,
  19137. setItemsPerPage
  19138. } = usePagination();
  19139. const itemsPerPageOptions = computed(() => props.itemsPerPageOptions.map(option => {
  19140. if (typeof option === 'number') {
  19141. return {
  19142. value: option,
  19143. title: option === -1 ? t('$vuetify.dataFooter.itemsPerPageAll') : String(option)
  19144. };
  19145. }
  19146. return {
  19147. ...option,
  19148. title: !isNaN(Number(option.title)) ? option.title : t(option.title)
  19149. };
  19150. }));
  19151. useRender(() => {
  19152. const paginationProps = VPagination.filterProps(props);
  19153. return createVNode("div", {
  19154. "class": "v-data-table-footer"
  19155. }, [slots.prepend?.(), createVNode("div", {
  19156. "class": "v-data-table-footer__items-per-page"
  19157. }, [createVNode("span", null, [t(props.itemsPerPageText)]), createVNode(VSelect, {
  19158. "items": itemsPerPageOptions.value,
  19159. "modelValue": itemsPerPage.value,
  19160. "onUpdate:modelValue": v => setItemsPerPage(Number(v)),
  19161. "density": "compact",
  19162. "variant": "outlined",
  19163. "hide-details": true
  19164. }, null)]), createVNode("div", {
  19165. "class": "v-data-table-footer__info"
  19166. }, [createVNode("div", null, [t(props.pageText, !itemsLength.value ? 0 : startIndex.value + 1, stopIndex.value, itemsLength.value)])]), createVNode("div", {
  19167. "class": "v-data-table-footer__pagination"
  19168. }, [createVNode(VPagination, mergeProps({
  19169. "modelValue": page.value,
  19170. "onUpdate:modelValue": $event => page.value = $event,
  19171. "density": "comfortable",
  19172. "first-aria-label": props.firstPageLabel,
  19173. "last-aria-label": props.lastPageLabel,
  19174. "length": pageCount.value,
  19175. "next-aria-label": props.nextPageLabel,
  19176. "previous-aria-label": props.prevPageLabel,
  19177. "rounded": true,
  19178. "show-first-last-page": true,
  19179. "total-visible": props.showCurrentPage ? 1 : 0,
  19180. "variant": "plain"
  19181. }, paginationProps), null)])]);
  19182. });
  19183. return {};
  19184. }
  19185. });
  19186. // Types
  19187. const VDataTableColumn = defineFunctionalComponent({
  19188. align: {
  19189. type: String,
  19190. default: 'start'
  19191. },
  19192. fixed: Boolean,
  19193. fixedOffset: [Number, String],
  19194. height: [Number, String],
  19195. lastFixed: Boolean,
  19196. noPadding: Boolean,
  19197. tag: String,
  19198. width: [Number, String],
  19199. maxWidth: [Number, String],
  19200. nowrap: Boolean
  19201. }, (props, _ref) => {
  19202. let {
  19203. slots
  19204. } = _ref;
  19205. const Tag = props.tag ?? 'td';
  19206. return createVNode(Tag, {
  19207. "class": ['v-data-table__td', {
  19208. 'v-data-table-column--fixed': props.fixed,
  19209. 'v-data-table-column--last-fixed': props.lastFixed,
  19210. 'v-data-table-column--no-padding': props.noPadding,
  19211. 'v-data-table-column--nowrap': props.nowrap
  19212. }, `v-data-table-column--align-${props.align}`],
  19213. "style": {
  19214. height: convertToUnit(props.height),
  19215. width: convertToUnit(props.width),
  19216. maxWidth: convertToUnit(props.maxWidth),
  19217. left: convertToUnit(props.fixedOffset || null)
  19218. }
  19219. }, {
  19220. default: () => [slots.default?.()]
  19221. });
  19222. });
  19223. // Utilities
  19224. // Types
  19225. const makeDataTableHeaderProps = propsFactory({
  19226. headers: Array
  19227. }, 'DataTable-header');
  19228. const VDataTableHeadersSymbol = Symbol.for('vuetify:data-table-headers');
  19229. const defaultHeader = {
  19230. title: '',
  19231. sortable: false
  19232. };
  19233. const defaultActionHeader = {
  19234. ...defaultHeader,
  19235. width: 48
  19236. };
  19237. function priorityQueue() {
  19238. let arr = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  19239. const queue = arr.map(element => ({
  19240. element,
  19241. priority: 0
  19242. }));
  19243. return {
  19244. enqueue: (element, priority) => {
  19245. let added = false;
  19246. for (let i = 0; i < queue.length; i++) {
  19247. const item = queue[i];
  19248. if (item.priority > priority) {
  19249. queue.splice(i, 0, {
  19250. element,
  19251. priority
  19252. });
  19253. added = true;
  19254. break;
  19255. }
  19256. }
  19257. if (!added) queue.push({
  19258. element,
  19259. priority
  19260. });
  19261. },
  19262. size: () => queue.length,
  19263. count: () => {
  19264. let count = 0;
  19265. if (!queue.length) return 0;
  19266. const whole = Math.floor(queue[0].priority);
  19267. for (let i = 0; i < queue.length; i++) {
  19268. if (Math.floor(queue[i].priority) === whole) count += 1;
  19269. }
  19270. return count;
  19271. },
  19272. dequeue: () => {
  19273. return queue.shift();
  19274. }
  19275. };
  19276. }
  19277. function extractLeaves(item) {
  19278. let columns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  19279. if (!item.children) {
  19280. columns.push(item);
  19281. } else {
  19282. for (const child of item.children) {
  19283. extractLeaves(child, columns);
  19284. }
  19285. }
  19286. return columns;
  19287. }
  19288. function extractKeys(headers) {
  19289. let keys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Set();
  19290. for (const item of headers) {
  19291. if (item.key) keys.add(item.key);
  19292. if (item.children) {
  19293. extractKeys(item.children, keys);
  19294. }
  19295. }
  19296. return keys;
  19297. }
  19298. function getDefaultItem(item) {
  19299. if (!item.key) return undefined;
  19300. if (item.key === 'data-table-group') return defaultHeader;
  19301. if (['data-table-expand', 'data-table-select'].includes(item.key)) return defaultActionHeader;
  19302. return undefined;
  19303. }
  19304. function getDepth(item) {
  19305. let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  19306. if (!item.children) return depth;
  19307. return Math.max(depth, ...item.children.map(child => getDepth(child, depth + 1)));
  19308. }
  19309. function parseFixedColumns(items) {
  19310. let seenFixed = false;
  19311. function setFixed(item) {
  19312. let parentFixed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  19313. if (!item) return;
  19314. if (parentFixed) {
  19315. item.fixed = true;
  19316. }
  19317. if (item.fixed) {
  19318. if (item.children) {
  19319. for (let i = item.children.length - 1; i >= 0; i--) {
  19320. setFixed(item.children[i], true);
  19321. }
  19322. } else {
  19323. if (!seenFixed) {
  19324. item.lastFixed = true;
  19325. } else if (isNaN(+item.width)) {
  19326. consoleError(`Multiple fixed columns should have a static width (key: ${item.key})`);
  19327. }
  19328. seenFixed = true;
  19329. }
  19330. } else {
  19331. if (item.children) {
  19332. for (let i = item.children.length - 1; i >= 0; i--) {
  19333. setFixed(item.children[i]);
  19334. }
  19335. } else {
  19336. seenFixed = false;
  19337. }
  19338. }
  19339. }
  19340. for (let i = items.length - 1; i >= 0; i--) {
  19341. setFixed(items[i]);
  19342. }
  19343. function setFixedOffset(item) {
  19344. let fixedOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  19345. if (!item) return fixedOffset;
  19346. if (item.children) {
  19347. item.fixedOffset = fixedOffset;
  19348. for (const child of item.children) {
  19349. fixedOffset = setFixedOffset(child, fixedOffset);
  19350. }
  19351. } else if (item.fixed) {
  19352. item.fixedOffset = fixedOffset;
  19353. fixedOffset += parseFloat(item.width || '0') || 0;
  19354. }
  19355. return fixedOffset;
  19356. }
  19357. let fixedOffset = 0;
  19358. for (const item of items) {
  19359. fixedOffset = setFixedOffset(item, fixedOffset);
  19360. }
  19361. }
  19362. function parse(items, maxDepth) {
  19363. const headers = [];
  19364. let currentDepth = 0;
  19365. const queue = priorityQueue(items);
  19366. while (queue.size() > 0) {
  19367. let rowSize = queue.count();
  19368. const row = [];
  19369. let fraction = 1;
  19370. while (rowSize > 0) {
  19371. const {
  19372. element: item,
  19373. priority
  19374. } = queue.dequeue();
  19375. const diff = maxDepth - currentDepth - getDepth(item);
  19376. row.push({
  19377. ...item,
  19378. rowspan: diff ?? 1,
  19379. colspan: item.children ? extractLeaves(item).length : 1
  19380. });
  19381. if (item.children) {
  19382. for (const child of item.children) {
  19383. // This internally sorts items that are on the same priority "row"
  19384. const sort = priority % 1 + fraction / Math.pow(10, currentDepth + 2);
  19385. queue.enqueue(child, currentDepth + diff + sort);
  19386. }
  19387. }
  19388. fraction += 1;
  19389. rowSize -= 1;
  19390. }
  19391. currentDepth += 1;
  19392. headers.push(row);
  19393. }
  19394. const columns = items.map(item => extractLeaves(item)).flat();
  19395. return {
  19396. columns,
  19397. headers
  19398. };
  19399. }
  19400. function convertToInternalHeaders(items) {
  19401. const internalHeaders = [];
  19402. for (const item of items) {
  19403. const defaultItem = {
  19404. ...getDefaultItem(item),
  19405. ...item
  19406. };
  19407. const key = defaultItem.key ?? (typeof defaultItem.value === 'string' ? defaultItem.value : null);
  19408. const value = defaultItem.value ?? key ?? null;
  19409. const internalItem = {
  19410. ...defaultItem,
  19411. key,
  19412. value,
  19413. sortable: defaultItem.sortable ?? (defaultItem.key != null || !!defaultItem.sort),
  19414. children: defaultItem.children ? convertToInternalHeaders(defaultItem.children) : undefined
  19415. };
  19416. internalHeaders.push(internalItem);
  19417. }
  19418. return internalHeaders;
  19419. }
  19420. function createHeaders(props, options) {
  19421. const headers = ref([]);
  19422. const columns = ref([]);
  19423. const sortFunctions = ref({});
  19424. const sortRawFunctions = ref({});
  19425. const filterFunctions = ref({});
  19426. watchEffect(() => {
  19427. const _headers = props.headers || Object.keys(props.items[0] ?? {}).map(key => ({
  19428. key,
  19429. title: capitalize(key)
  19430. }));
  19431. const items = _headers.slice();
  19432. const keys = extractKeys(items);
  19433. if (options?.groupBy?.value.length && !keys.has('data-table-group')) {
  19434. items.unshift({
  19435. key: 'data-table-group',
  19436. title: 'Group'
  19437. });
  19438. }
  19439. if (options?.showSelect?.value && !keys.has('data-table-select')) {
  19440. items.unshift({
  19441. key: 'data-table-select'
  19442. });
  19443. }
  19444. if (options?.showExpand?.value && !keys.has('data-table-expand')) {
  19445. items.push({
  19446. key: 'data-table-expand'
  19447. });
  19448. }
  19449. const internalHeaders = convertToInternalHeaders(items);
  19450. parseFixedColumns(internalHeaders);
  19451. const maxDepth = Math.max(...internalHeaders.map(item => getDepth(item))) + 1;
  19452. const parsed = parse(internalHeaders, maxDepth);
  19453. headers.value = parsed.headers;
  19454. columns.value = parsed.columns;
  19455. const flatHeaders = parsed.headers.flat(1);
  19456. for (const header of flatHeaders) {
  19457. if (!header.key) continue;
  19458. if (header.sortable) {
  19459. if (header.sort) {
  19460. sortFunctions.value[header.key] = header.sort;
  19461. }
  19462. if (header.sortRaw) {
  19463. sortRawFunctions.value[header.key] = header.sortRaw;
  19464. }
  19465. }
  19466. if (header.filter) {
  19467. filterFunctions.value[header.key] = header.filter;
  19468. }
  19469. }
  19470. });
  19471. const data = {
  19472. headers,
  19473. columns,
  19474. sortFunctions,
  19475. sortRawFunctions,
  19476. filterFunctions
  19477. };
  19478. provide(VDataTableHeadersSymbol, data);
  19479. return data;
  19480. }
  19481. function useHeaders() {
  19482. const data = inject$1(VDataTableHeadersSymbol);
  19483. if (!data) throw new Error('Missing headers!');
  19484. return data;
  19485. }
  19486. // Types
  19487. const makeVDataTableHeadersProps = propsFactory({
  19488. color: String,
  19489. sticky: Boolean,
  19490. disableSort: Boolean,
  19491. multiSort: Boolean,
  19492. sortAscIcon: {
  19493. type: IconValue,
  19494. default: '$sortAsc'
  19495. },
  19496. sortDescIcon: {
  19497. type: IconValue,
  19498. default: '$sortDesc'
  19499. },
  19500. headerProps: {
  19501. type: Object
  19502. },
  19503. ...makeDisplayProps(),
  19504. ...makeLoaderProps()
  19505. }, 'VDataTableHeaders');
  19506. const VDataTableHeaders = genericComponent()({
  19507. name: 'VDataTableHeaders',
  19508. props: makeVDataTableHeadersProps(),
  19509. setup(props, _ref) {
  19510. let {
  19511. slots
  19512. } = _ref;
  19513. const {
  19514. t
  19515. } = useLocale();
  19516. const {
  19517. toggleSort,
  19518. sortBy,
  19519. isSorted
  19520. } = useSort();
  19521. const {
  19522. someSelected,
  19523. allSelected,
  19524. selectAll,
  19525. showSelectAll
  19526. } = useSelection();
  19527. const {
  19528. columns,
  19529. headers
  19530. } = useHeaders();
  19531. const {
  19532. loaderClasses
  19533. } = useLoader(props);
  19534. function getFixedStyles(column, y) {
  19535. if (!props.sticky && !column.fixed) return undefined;
  19536. return {
  19537. position: 'sticky',
  19538. left: column.fixed ? convertToUnit(column.fixedOffset) : undefined,
  19539. top: props.sticky ? `calc(var(--v-table-header-height) * ${y})` : undefined
  19540. };
  19541. }
  19542. function getSortIcon(column) {
  19543. const item = sortBy.value.find(item => item.key === column.key);
  19544. if (!item) return props.sortAscIcon;
  19545. return item.order === 'asc' ? props.sortAscIcon : props.sortDescIcon;
  19546. }
  19547. const {
  19548. backgroundColorClasses,
  19549. backgroundColorStyles
  19550. } = useBackgroundColor(props, 'color');
  19551. const {
  19552. displayClasses,
  19553. mobile
  19554. } = useDisplay(props);
  19555. const slotProps = computed(() => ({
  19556. headers: headers.value,
  19557. columns: columns.value,
  19558. toggleSort,
  19559. isSorted,
  19560. sortBy: sortBy.value,
  19561. someSelected: someSelected.value,
  19562. allSelected: allSelected.value,
  19563. selectAll,
  19564. getSortIcon
  19565. }));
  19566. const headerCellClasses = computed(() => ['v-data-table__th', {
  19567. 'v-data-table__th--sticky': props.sticky
  19568. }, displayClasses.value, loaderClasses.value]);
  19569. const VDataTableHeaderCell = _ref2 => {
  19570. let {
  19571. column,
  19572. x,
  19573. y
  19574. } = _ref2;
  19575. const noPadding = column.key === 'data-table-select' || column.key === 'data-table-expand';
  19576. const headerProps = mergeProps(props.headerProps ?? {}, column.headerProps ?? {});
  19577. return createVNode(VDataTableColumn, mergeProps({
  19578. "tag": "th",
  19579. "align": column.align,
  19580. "class": [{
  19581. 'v-data-table__th--sortable': column.sortable && !props.disableSort,
  19582. 'v-data-table__th--sorted': isSorted(column),
  19583. 'v-data-table__th--fixed': column.fixed
  19584. }, ...headerCellClasses.value],
  19585. "style": {
  19586. width: convertToUnit(column.width),
  19587. minWidth: convertToUnit(column.minWidth),
  19588. maxWidth: convertToUnit(column.maxWidth),
  19589. ...getFixedStyles(column, y)
  19590. },
  19591. "colspan": column.colspan,
  19592. "rowspan": column.rowspan,
  19593. "onClick": column.sortable ? () => toggleSort(column) : undefined,
  19594. "fixed": column.fixed,
  19595. "nowrap": column.nowrap,
  19596. "lastFixed": column.lastFixed,
  19597. "noPadding": noPadding
  19598. }, headerProps), {
  19599. default: () => {
  19600. const columnSlotName = `header.${column.key}`;
  19601. const columnSlotProps = {
  19602. column,
  19603. selectAll,
  19604. isSorted,
  19605. toggleSort,
  19606. sortBy: sortBy.value,
  19607. someSelected: someSelected.value,
  19608. allSelected: allSelected.value,
  19609. getSortIcon
  19610. };
  19611. if (slots[columnSlotName]) return slots[columnSlotName](columnSlotProps);
  19612. if (column.key === 'data-table-select') {
  19613. return slots['header.data-table-select']?.(columnSlotProps) ?? (showSelectAll.value && createVNode(VCheckboxBtn, {
  19614. "modelValue": allSelected.value,
  19615. "indeterminate": someSelected.value && !allSelected.value,
  19616. "onUpdate:modelValue": selectAll
  19617. }, null));
  19618. }
  19619. return createVNode("div", {
  19620. "class": "v-data-table-header__content"
  19621. }, [createVNode("span", null, [column.title]), column.sortable && !props.disableSort && createVNode(VIcon, {
  19622. "key": "icon",
  19623. "class": "v-data-table-header__sort-icon",
  19624. "icon": getSortIcon(column)
  19625. }, null), props.multiSort && isSorted(column) && createVNode("div", {
  19626. "key": "badge",
  19627. "class": ['v-data-table-header__sort-badge', ...backgroundColorClasses.value],
  19628. "style": backgroundColorStyles.value
  19629. }, [sortBy.value.findIndex(x => x.key === column.key) + 1])]);
  19630. }
  19631. });
  19632. };
  19633. const VDataTableMobileHeaderCell = () => {
  19634. const headerProps = mergeProps(props.headerProps ?? {} ?? {});
  19635. const displayItems = computed(() => {
  19636. return columns.value.filter(column => column?.sortable && !props.disableSort);
  19637. });
  19638. const appendIcon = computed(() => {
  19639. const showSelectColumn = columns.value.find(column => column.key === 'data-table-select');
  19640. if (showSelectColumn == null) return;
  19641. return allSelected.value ? '$checkboxOn' : someSelected.value ? '$checkboxIndeterminate' : '$checkboxOff';
  19642. });
  19643. return createVNode(VDataTableColumn, mergeProps({
  19644. "tag": "th",
  19645. "class": [...headerCellClasses.value],
  19646. "colspan": headers.value.length + 1
  19647. }, headerProps), {
  19648. default: () => [createVNode("div", {
  19649. "class": "v-data-table-header__content"
  19650. }, [createVNode(VSelect, {
  19651. "chips": true,
  19652. "class": "v-data-table__td-sort-select",
  19653. "clearable": true,
  19654. "density": "default",
  19655. "items": displayItems.value,
  19656. "label": t('$vuetify.dataTable.sortBy'),
  19657. "multiple": props.multiSort,
  19658. "variant": "underlined",
  19659. "onClick:clear": () => sortBy.value = [],
  19660. "appendIcon": appendIcon.value,
  19661. "onClick:append": () => selectAll(!allSelected.value)
  19662. }, {
  19663. ...slots,
  19664. chip: props => createVNode(VChip, {
  19665. "onClick": props.item.raw?.sortable ? () => toggleSort(props.item.raw) : undefined,
  19666. "onMousedown": e => {
  19667. e.preventDefault();
  19668. e.stopPropagation();
  19669. }
  19670. }, {
  19671. default: () => [props.item.title, createVNode(VIcon, {
  19672. "class": ['v-data-table__td-sort-icon', isSorted(props.item.raw) && 'v-data-table__td-sort-icon-active'],
  19673. "icon": getSortIcon(props.item.raw),
  19674. "size": "small"
  19675. }, null)]
  19676. })
  19677. })])]
  19678. });
  19679. };
  19680. useRender(() => {
  19681. return mobile.value ? createVNode("tr", null, [createVNode(VDataTableMobileHeaderCell, null, null)]) : createVNode(Fragment, null, [slots.headers ? slots.headers(slotProps.value) : headers.value.map((row, y) => createVNode("tr", null, [row.map((column, x) => createVNode(VDataTableHeaderCell, {
  19682. "column": column,
  19683. "x": x,
  19684. "y": y
  19685. }, null))])), props.loading && createVNode("tr", {
  19686. "class": "v-data-table-progress"
  19687. }, [createVNode("th", {
  19688. "colspan": columns.value.length
  19689. }, [createVNode(LoaderSlot, {
  19690. "name": "v-data-table-progress",
  19691. "absolute": true,
  19692. "active": true,
  19693. "color": typeof props.loading === 'boolean' ? undefined : props.loading,
  19694. "indeterminate": true
  19695. }, {
  19696. default: slots.loader
  19697. })])])]);
  19698. });
  19699. }
  19700. });
  19701. // Types
  19702. const makeVDataTableGroupHeaderRowProps = propsFactory({
  19703. item: {
  19704. type: Object,
  19705. required: true
  19706. }
  19707. }, 'VDataTableGroupHeaderRow');
  19708. const VDataTableGroupHeaderRow = genericComponent()({
  19709. name: 'VDataTableGroupHeaderRow',
  19710. props: makeVDataTableGroupHeaderRowProps(),
  19711. setup(props, _ref) {
  19712. let {
  19713. slots
  19714. } = _ref;
  19715. const {
  19716. isGroupOpen,
  19717. toggleGroup,
  19718. extractRows
  19719. } = useGroupBy();
  19720. const {
  19721. isSelected,
  19722. isSomeSelected,
  19723. select
  19724. } = useSelection();
  19725. const {
  19726. columns
  19727. } = useHeaders();
  19728. const rows = computed(() => {
  19729. return extractRows([props.item]);
  19730. });
  19731. return () => createVNode("tr", {
  19732. "class": "v-data-table-group-header-row",
  19733. "style": {
  19734. '--v-data-table-group-header-row-depth': props.item.depth
  19735. }
  19736. }, [columns.value.map(column => {
  19737. if (column.key === 'data-table-group') {
  19738. const icon = isGroupOpen(props.item) ? '$expand' : '$next';
  19739. const onClick = () => toggleGroup(props.item);
  19740. return slots['data-table-group']?.({
  19741. item: props.item,
  19742. count: rows.value.length,
  19743. props: {
  19744. icon,
  19745. onClick
  19746. }
  19747. }) ?? createVNode(VDataTableColumn, {
  19748. "class": "v-data-table-group-header-row__column"
  19749. }, {
  19750. default: () => [createVNode(VBtn, {
  19751. "size": "small",
  19752. "variant": "text",
  19753. "icon": icon,
  19754. "onClick": onClick
  19755. }, null), createVNode("span", null, [props.item.value]), createVNode("span", null, [createTextVNode("("), rows.value.length, createTextVNode(")")])]
  19756. });
  19757. }
  19758. if (column.key === 'data-table-select') {
  19759. const modelValue = isSelected(rows.value);
  19760. const indeterminate = isSomeSelected(rows.value) && !modelValue;
  19761. const selectGroup = v => select(rows.value, v);
  19762. return slots['data-table-select']?.({
  19763. props: {
  19764. modelValue,
  19765. indeterminate,
  19766. 'onUpdate:modelValue': selectGroup
  19767. }
  19768. }) ?? createVNode("td", null, [createVNode(VCheckboxBtn, {
  19769. "modelValue": modelValue,
  19770. "indeterminate": indeterminate,
  19771. "onUpdate:modelValue": selectGroup
  19772. }, null)]);
  19773. }
  19774. return createVNode("td", null, null);
  19775. })]);
  19776. }
  19777. });
  19778. // Types
  19779. const makeVDataTableRowProps = propsFactory({
  19780. index: Number,
  19781. item: Object,
  19782. cellProps: [Object, Function],
  19783. onClick: EventProp(),
  19784. onContextmenu: EventProp(),
  19785. onDblclick: EventProp(),
  19786. ...makeDisplayProps()
  19787. }, 'VDataTableRow');
  19788. const VDataTableRow = genericComponent()({
  19789. name: 'VDataTableRow',
  19790. props: makeVDataTableRowProps(),
  19791. setup(props, _ref) {
  19792. let {
  19793. slots
  19794. } = _ref;
  19795. const {
  19796. displayClasses,
  19797. mobile
  19798. } = useDisplay(props, 'v-data-table__tr');
  19799. const {
  19800. isSelected,
  19801. toggleSelect,
  19802. someSelected,
  19803. allSelected,
  19804. selectAll
  19805. } = useSelection();
  19806. const {
  19807. isExpanded,
  19808. toggleExpand
  19809. } = useExpanded();
  19810. const {
  19811. toggleSort,
  19812. sortBy,
  19813. isSorted
  19814. } = useSort();
  19815. const {
  19816. columns
  19817. } = useHeaders();
  19818. useRender(() => createVNode("tr", {
  19819. "class": ['v-data-table__tr', {
  19820. 'v-data-table__tr--clickable': !!(props.onClick || props.onContextmenu || props.onDblclick)
  19821. }, displayClasses.value],
  19822. "onClick": props.onClick,
  19823. "onContextmenu": props.onContextmenu,
  19824. "onDblclick": props.onDblclick
  19825. }, [props.item && columns.value.map((column, i) => {
  19826. const item = props.item;
  19827. const slotName = `item.${column.key}`;
  19828. const headerSlotName = `header.${column.key}`;
  19829. const slotProps = {
  19830. index: props.index,
  19831. item: item.raw,
  19832. internalItem: item,
  19833. value: getObjectValueByPath(item.columns, column.key),
  19834. column,
  19835. isSelected,
  19836. toggleSelect,
  19837. isExpanded,
  19838. toggleExpand
  19839. };
  19840. const columnSlotProps = {
  19841. column,
  19842. selectAll,
  19843. isSorted,
  19844. toggleSort,
  19845. sortBy: sortBy.value,
  19846. someSelected: someSelected.value,
  19847. allSelected: allSelected.value,
  19848. getSortIcon: () => ''
  19849. };
  19850. const cellProps = typeof props.cellProps === 'function' ? props.cellProps({
  19851. index: slotProps.index,
  19852. item: slotProps.item,
  19853. internalItem: slotProps.internalItem,
  19854. value: slotProps.value,
  19855. column
  19856. }) : props.cellProps;
  19857. const columnCellProps = typeof column.cellProps === 'function' ? column.cellProps({
  19858. index: slotProps.index,
  19859. item: slotProps.item,
  19860. internalItem: slotProps.internalItem,
  19861. value: slotProps.value
  19862. }) : column.cellProps;
  19863. return createVNode(VDataTableColumn, mergeProps({
  19864. "align": column.align,
  19865. "class": {
  19866. 'v-data-table__td--expanded-row': column.key === 'data-table-expand',
  19867. 'v-data-table__td--select-row': column.key === 'data-table-select'
  19868. },
  19869. "fixed": column.fixed,
  19870. "fixedOffset": column.fixedOffset,
  19871. "lastFixed": column.lastFixed,
  19872. "maxWidth": !mobile.value ? column.maxWidth : undefined,
  19873. "noPadding": column.key === 'data-table-select' || column.key === 'data-table-expand',
  19874. "nowrap": column.nowrap,
  19875. "width": !mobile.value ? column.width : undefined
  19876. }, cellProps, columnCellProps), {
  19877. default: () => {
  19878. if (slots[slotName] && !mobile.value) return slots[slotName]?.(slotProps);
  19879. if (column.key === 'data-table-select') {
  19880. return slots['item.data-table-select']?.(slotProps) ?? createVNode(VCheckboxBtn, {
  19881. "disabled": !item.selectable,
  19882. "modelValue": isSelected([item]),
  19883. "onClick": withModifiers(() => toggleSelect(item), ['stop'])
  19884. }, null);
  19885. }
  19886. if (column.key === 'data-table-expand') {
  19887. return slots['item.data-table-expand']?.(slotProps) ?? createVNode(VBtn, {
  19888. "icon": isExpanded(item) ? '$collapse' : '$expand',
  19889. "size": "small",
  19890. "variant": "text",
  19891. "onClick": withModifiers(() => toggleExpand(item), ['stop'])
  19892. }, null);
  19893. }
  19894. const displayValue = toDisplayString(slotProps.value);
  19895. return !mobile.value ? displayValue : createVNode(Fragment, null, [createVNode("div", {
  19896. "class": "v-data-table__td-title"
  19897. }, [slots[headerSlotName]?.(columnSlotProps) ?? column.title]), createVNode("div", {
  19898. "class": "v-data-table__td-value"
  19899. }, [slots[slotName]?.(slotProps) ?? displayValue])]);
  19900. }
  19901. });
  19902. })]));
  19903. }
  19904. });
  19905. // Types
  19906. const makeVDataTableRowsProps = propsFactory({
  19907. loading: [Boolean, String],
  19908. loadingText: {
  19909. type: String,
  19910. default: '$vuetify.dataIterator.loadingText'
  19911. },
  19912. hideNoData: Boolean,
  19913. items: {
  19914. type: Array,
  19915. default: () => []
  19916. },
  19917. noDataText: {
  19918. type: String,
  19919. default: '$vuetify.noDataText'
  19920. },
  19921. rowProps: [Object, Function],
  19922. cellProps: [Object, Function],
  19923. ...makeDisplayProps()
  19924. }, 'VDataTableRows');
  19925. const VDataTableRows = genericComponent()({
  19926. name: 'VDataTableRows',
  19927. inheritAttrs: false,
  19928. props: makeVDataTableRowsProps(),
  19929. setup(props, _ref) {
  19930. let {
  19931. attrs,
  19932. slots
  19933. } = _ref;
  19934. const {
  19935. columns
  19936. } = useHeaders();
  19937. const {
  19938. expandOnClick,
  19939. toggleExpand,
  19940. isExpanded
  19941. } = useExpanded();
  19942. const {
  19943. isSelected,
  19944. toggleSelect
  19945. } = useSelection();
  19946. const {
  19947. toggleGroup,
  19948. isGroupOpen
  19949. } = useGroupBy();
  19950. const {
  19951. t
  19952. } = useLocale();
  19953. const {
  19954. mobile
  19955. } = useDisplay(props);
  19956. useRender(() => {
  19957. if (props.loading && (!props.items.length || slots.loading)) {
  19958. return createVNode("tr", {
  19959. "class": "v-data-table-rows-loading",
  19960. "key": "loading"
  19961. }, [createVNode("td", {
  19962. "colspan": columns.value.length
  19963. }, [slots.loading?.() ?? t(props.loadingText)])]);
  19964. }
  19965. if (!props.loading && !props.items.length && !props.hideNoData) {
  19966. return createVNode("tr", {
  19967. "class": "v-data-table-rows-no-data",
  19968. "key": "no-data"
  19969. }, [createVNode("td", {
  19970. "colspan": columns.value.length
  19971. }, [slots['no-data']?.() ?? t(props.noDataText)])]);
  19972. }
  19973. return createVNode(Fragment, null, [props.items.map((item, index) => {
  19974. if (item.type === 'group') {
  19975. const slotProps = {
  19976. index,
  19977. item,
  19978. columns: columns.value,
  19979. isExpanded,
  19980. toggleExpand,
  19981. isSelected,
  19982. toggleSelect,
  19983. toggleGroup,
  19984. isGroupOpen
  19985. };
  19986. return slots['group-header'] ? slots['group-header'](slotProps) : createVNode(VDataTableGroupHeaderRow, mergeProps({
  19987. "key": `group-header_${item.id}`,
  19988. "item": item
  19989. }, getPrefixedEventHandlers(attrs, ':group-header', () => slotProps)), slots);
  19990. }
  19991. const slotProps = {
  19992. index,
  19993. item: item.raw,
  19994. internalItem: item,
  19995. columns: columns.value,
  19996. isExpanded,
  19997. toggleExpand,
  19998. isSelected,
  19999. toggleSelect
  20000. };
  20001. const itemSlotProps = {
  20002. ...slotProps,
  20003. props: mergeProps({
  20004. key: `item_${item.key ?? item.index}`,
  20005. onClick: expandOnClick.value ? () => {
  20006. toggleExpand(item);
  20007. } : undefined,
  20008. index,
  20009. item,
  20010. cellProps: props.cellProps,
  20011. mobile: mobile.value
  20012. }, getPrefixedEventHandlers(attrs, ':row', () => slotProps), typeof props.rowProps === 'function' ? props.rowProps({
  20013. item: slotProps.item,
  20014. index: slotProps.index,
  20015. internalItem: slotProps.internalItem
  20016. }) : props.rowProps)
  20017. };
  20018. return createVNode(Fragment, {
  20019. "key": itemSlotProps.props.key
  20020. }, [slots.item ? slots.item(itemSlotProps) : createVNode(VDataTableRow, itemSlotProps.props, slots), isExpanded(item) && slots['expanded-row']?.(slotProps)]);
  20021. })]);
  20022. });
  20023. return {};
  20024. }
  20025. });
  20026. const makeVTableProps = propsFactory({
  20027. fixedHeader: Boolean,
  20028. fixedFooter: Boolean,
  20029. height: [Number, String],
  20030. hover: Boolean,
  20031. ...makeComponentProps(),
  20032. ...makeDensityProps(),
  20033. ...makeTagProps(),
  20034. ...makeThemeProps()
  20035. }, 'VTable');
  20036. const VTable = genericComponent()({
  20037. name: 'VTable',
  20038. props: makeVTableProps(),
  20039. setup(props, _ref) {
  20040. let {
  20041. slots,
  20042. emit
  20043. } = _ref;
  20044. const {
  20045. themeClasses
  20046. } = provideTheme(props);
  20047. const {
  20048. densityClasses
  20049. } = useDensity(props);
  20050. useRender(() => createVNode(props.tag, {
  20051. "class": ['v-table', {
  20052. 'v-table--fixed-height': !!props.height,
  20053. 'v-table--fixed-header': props.fixedHeader,
  20054. 'v-table--fixed-footer': props.fixedFooter,
  20055. 'v-table--has-top': !!slots.top,
  20056. 'v-table--has-bottom': !!slots.bottom,
  20057. 'v-table--hover': props.hover
  20058. }, themeClasses.value, densityClasses.value, props.class],
  20059. "style": props.style
  20060. }, {
  20061. default: () => [slots.top?.(), slots.default ? createVNode("div", {
  20062. "class": "v-table__wrapper",
  20063. "style": {
  20064. height: convertToUnit(props.height)
  20065. }
  20066. }, [createVNode("table", null, [slots.default()])]) : slots.wrapper?.(), slots.bottom?.()]
  20067. }));
  20068. return {};
  20069. }
  20070. });
  20071. // Utilities
  20072. // Types
  20073. // Composables
  20074. const makeDataTableItemsProps = propsFactory({
  20075. items: {
  20076. type: Array,
  20077. default: () => []
  20078. },
  20079. itemValue: {
  20080. type: [String, Array, Function],
  20081. default: 'id'
  20082. },
  20083. itemSelectable: {
  20084. type: [String, Array, Function],
  20085. default: null
  20086. },
  20087. rowProps: [Object, Function],
  20088. cellProps: [Object, Function],
  20089. returnObject: Boolean
  20090. }, 'DataTable-items');
  20091. function transformItem(props, item, index, columns) {
  20092. const value = props.returnObject ? item : getPropertyFromItem(item, props.itemValue);
  20093. const selectable = getPropertyFromItem(item, props.itemSelectable, true);
  20094. const itemColumns = columns.reduce((obj, column) => {
  20095. if (column.key != null) obj[column.key] = getPropertyFromItem(item, column.value);
  20096. return obj;
  20097. }, {});
  20098. return {
  20099. type: 'item',
  20100. key: props.returnObject ? getPropertyFromItem(item, props.itemValue) : value,
  20101. index,
  20102. value,
  20103. selectable,
  20104. columns: itemColumns,
  20105. raw: item
  20106. };
  20107. }
  20108. function transformItems(props, items, columns) {
  20109. return items.map((item, index) => transformItem(props, item, index, columns));
  20110. }
  20111. function useDataTableItems(props, columns) {
  20112. const items = computed(() => transformItems(props, props.items, columns.value));
  20113. return {
  20114. items
  20115. };
  20116. }
  20117. // Types
  20118. const makeDataTableProps = propsFactory({
  20119. ...makeVDataTableRowsProps(),
  20120. hideDefaultBody: Boolean,
  20121. hideDefaultFooter: Boolean,
  20122. hideDefaultHeader: Boolean,
  20123. width: [String, Number],
  20124. search: String,
  20125. ...makeDataTableExpandProps(),
  20126. ...makeDataTableGroupProps(),
  20127. ...makeDataTableHeaderProps(),
  20128. ...makeDataTableItemsProps(),
  20129. ...makeDataTableSelectProps(),
  20130. ...makeDataTableSortProps(),
  20131. ...makeVDataTableHeadersProps(),
  20132. ...makeVTableProps()
  20133. }, 'DataTable');
  20134. const makeVDataTableProps = propsFactory({
  20135. ...makeDataTablePaginateProps(),
  20136. ...makeDataTableProps(),
  20137. ...makeFilterProps(),
  20138. ...makeVDataTableFooterProps()
  20139. }, 'VDataTable');
  20140. const VDataTable = genericComponent()({
  20141. name: 'VDataTable',
  20142. props: makeVDataTableProps(),
  20143. emits: {
  20144. 'update:modelValue': value => true,
  20145. 'update:page': value => true,
  20146. 'update:itemsPerPage': value => true,
  20147. 'update:sortBy': value => true,
  20148. 'update:options': value => true,
  20149. 'update:groupBy': value => true,
  20150. 'update:expanded': value => true,
  20151. 'update:currentItems': value => true
  20152. },
  20153. setup(props, _ref) {
  20154. let {
  20155. attrs,
  20156. slots
  20157. } = _ref;
  20158. const {
  20159. groupBy
  20160. } = createGroupBy(props);
  20161. const {
  20162. sortBy,
  20163. multiSort,
  20164. mustSort
  20165. } = createSort(props);
  20166. const {
  20167. page,
  20168. itemsPerPage
  20169. } = createPagination(props);
  20170. const {
  20171. disableSort
  20172. } = toRefs(props);
  20173. const {
  20174. columns,
  20175. headers,
  20176. sortFunctions,
  20177. sortRawFunctions,
  20178. filterFunctions
  20179. } = createHeaders(props, {
  20180. groupBy,
  20181. showSelect: toRef(props, 'showSelect'),
  20182. showExpand: toRef(props, 'showExpand')
  20183. });
  20184. const {
  20185. items
  20186. } = useDataTableItems(props, columns);
  20187. const search = toRef(props, 'search');
  20188. const {
  20189. filteredItems
  20190. } = useFilter(props, items, search, {
  20191. transform: item => item.columns,
  20192. customKeyFilter: filterFunctions
  20193. });
  20194. const {
  20195. toggleSort
  20196. } = provideSort({
  20197. sortBy,
  20198. multiSort,
  20199. mustSort,
  20200. page
  20201. });
  20202. const {
  20203. sortByWithGroups,
  20204. opened,
  20205. extractRows,
  20206. isGroupOpen,
  20207. toggleGroup
  20208. } = provideGroupBy({
  20209. groupBy,
  20210. sortBy,
  20211. disableSort
  20212. });
  20213. const {
  20214. sortedItems
  20215. } = useSortedItems(props, filteredItems, sortByWithGroups, {
  20216. transform: item => ({
  20217. ...item.raw,
  20218. ...item.columns
  20219. }),
  20220. sortFunctions,
  20221. sortRawFunctions
  20222. });
  20223. const {
  20224. flatItems
  20225. } = useGroupedItems(sortedItems, groupBy, opened);
  20226. const itemsLength = computed(() => flatItems.value.length);
  20227. const {
  20228. startIndex,
  20229. stopIndex,
  20230. pageCount,
  20231. setItemsPerPage
  20232. } = providePagination({
  20233. page,
  20234. itemsPerPage,
  20235. itemsLength
  20236. });
  20237. const {
  20238. paginatedItems
  20239. } = usePaginatedItems({
  20240. items: flatItems,
  20241. startIndex,
  20242. stopIndex,
  20243. itemsPerPage
  20244. });
  20245. const paginatedItemsWithoutGroups = computed(() => extractRows(paginatedItems.value));
  20246. const {
  20247. isSelected,
  20248. select,
  20249. selectAll,
  20250. toggleSelect,
  20251. someSelected,
  20252. allSelected
  20253. } = provideSelection(props, {
  20254. allItems: items,
  20255. currentPage: paginatedItemsWithoutGroups
  20256. });
  20257. const {
  20258. isExpanded,
  20259. toggleExpand
  20260. } = provideExpanded(props);
  20261. useOptions({
  20262. page,
  20263. itemsPerPage,
  20264. sortBy,
  20265. groupBy,
  20266. search
  20267. });
  20268. provideDefaults({
  20269. VDataTableRows: {
  20270. hideNoData: toRef(props, 'hideNoData'),
  20271. noDataText: toRef(props, 'noDataText'),
  20272. loading: toRef(props, 'loading'),
  20273. loadingText: toRef(props, 'loadingText')
  20274. }
  20275. });
  20276. const slotProps = computed(() => ({
  20277. page: page.value,
  20278. itemsPerPage: itemsPerPage.value,
  20279. sortBy: sortBy.value,
  20280. pageCount: pageCount.value,
  20281. toggleSort,
  20282. setItemsPerPage,
  20283. someSelected: someSelected.value,
  20284. allSelected: allSelected.value,
  20285. isSelected,
  20286. select,
  20287. selectAll,
  20288. toggleSelect,
  20289. isExpanded,
  20290. toggleExpand,
  20291. isGroupOpen,
  20292. toggleGroup,
  20293. items: paginatedItemsWithoutGroups.value.map(item => item.raw),
  20294. internalItems: paginatedItemsWithoutGroups.value,
  20295. groupedItems: paginatedItems.value,
  20296. columns: columns.value,
  20297. headers: headers.value
  20298. }));
  20299. useRender(() => {
  20300. const dataTableFooterProps = VDataTableFooter.filterProps(props);
  20301. const dataTableHeadersProps = VDataTableHeaders.filterProps(props);
  20302. const dataTableRowsProps = VDataTableRows.filterProps(props);
  20303. const tableProps = VTable.filterProps(props);
  20304. return createVNode(VTable, mergeProps({
  20305. "class": ['v-data-table', {
  20306. 'v-data-table--show-select': props.showSelect,
  20307. 'v-data-table--loading': props.loading
  20308. }, props.class],
  20309. "style": props.style
  20310. }, tableProps), {
  20311. top: () => slots.top?.(slotProps.value),
  20312. default: () => slots.default ? slots.default(slotProps.value) : createVNode(Fragment, null, [slots.colgroup?.(slotProps.value), !props.hideDefaultHeader && createVNode("thead", {
  20313. "key": "thead"
  20314. }, [createVNode(VDataTableHeaders, dataTableHeadersProps, slots)]), slots.thead?.(slotProps.value), !props.hideDefaultBody && createVNode("tbody", null, [slots['body.prepend']?.(slotProps.value), slots.body ? slots.body(slotProps.value) : createVNode(VDataTableRows, mergeProps(attrs, dataTableRowsProps, {
  20315. "items": paginatedItems.value
  20316. }), slots), slots['body.append']?.(slotProps.value)]), slots.tbody?.(slotProps.value), slots.tfoot?.(slotProps.value)]),
  20317. bottom: () => slots.bottom ? slots.bottom(slotProps.value) : !props.hideDefaultFooter && createVNode(Fragment, null, [createVNode(VDivider, null, null), createVNode(VDataTableFooter, dataTableFooterProps, {
  20318. prepend: slots['footer.prepend']
  20319. })])
  20320. });
  20321. });
  20322. return {};
  20323. }
  20324. });
  20325. // Types
  20326. const makeVDataTableVirtualProps = propsFactory({
  20327. ...makeDataTableProps(),
  20328. ...makeDataTableGroupProps(),
  20329. ...makeVirtualProps(),
  20330. ...makeFilterProps()
  20331. }, 'VDataTableVirtual');
  20332. const VDataTableVirtual = genericComponent()({
  20333. name: 'VDataTableVirtual',
  20334. props: makeVDataTableVirtualProps(),
  20335. emits: {
  20336. 'update:modelValue': value => true,
  20337. 'update:sortBy': value => true,
  20338. 'update:options': value => true,
  20339. 'update:groupBy': value => true,
  20340. 'update:expanded': value => true
  20341. },
  20342. setup(props, _ref) {
  20343. let {
  20344. attrs,
  20345. slots
  20346. } = _ref;
  20347. const {
  20348. groupBy
  20349. } = createGroupBy(props);
  20350. const {
  20351. sortBy,
  20352. multiSort,
  20353. mustSort
  20354. } = createSort(props);
  20355. const {
  20356. disableSort
  20357. } = toRefs(props);
  20358. const {
  20359. columns,
  20360. headers,
  20361. filterFunctions,
  20362. sortFunctions,
  20363. sortRawFunctions
  20364. } = createHeaders(props, {
  20365. groupBy,
  20366. showSelect: toRef(props, 'showSelect'),
  20367. showExpand: toRef(props, 'showExpand')
  20368. });
  20369. const {
  20370. items
  20371. } = useDataTableItems(props, columns);
  20372. const search = toRef(props, 'search');
  20373. const {
  20374. filteredItems
  20375. } = useFilter(props, items, search, {
  20376. transform: item => item.columns,
  20377. customKeyFilter: filterFunctions
  20378. });
  20379. const {
  20380. toggleSort
  20381. } = provideSort({
  20382. sortBy,
  20383. multiSort,
  20384. mustSort
  20385. });
  20386. const {
  20387. sortByWithGroups,
  20388. opened,
  20389. extractRows,
  20390. isGroupOpen,
  20391. toggleGroup
  20392. } = provideGroupBy({
  20393. groupBy,
  20394. sortBy,
  20395. disableSort
  20396. });
  20397. const {
  20398. sortedItems
  20399. } = useSortedItems(props, filteredItems, sortByWithGroups, {
  20400. transform: item => ({
  20401. ...item.raw,
  20402. ...item.columns
  20403. }),
  20404. sortFunctions,
  20405. sortRawFunctions
  20406. });
  20407. const {
  20408. flatItems
  20409. } = useGroupedItems(sortedItems, groupBy, opened);
  20410. const allItems = computed(() => extractRows(flatItems.value));
  20411. const {
  20412. isSelected,
  20413. select,
  20414. selectAll,
  20415. toggleSelect,
  20416. someSelected,
  20417. allSelected
  20418. } = provideSelection(props, {
  20419. allItems,
  20420. currentPage: allItems
  20421. });
  20422. const {
  20423. isExpanded,
  20424. toggleExpand
  20425. } = provideExpanded(props);
  20426. const {
  20427. containerRef,
  20428. markerRef,
  20429. paddingTop,
  20430. paddingBottom,
  20431. computedItems,
  20432. handleItemResize,
  20433. handleScroll,
  20434. handleScrollend
  20435. } = useVirtual(props, flatItems);
  20436. const displayItems = computed(() => computedItems.value.map(item => item.raw));
  20437. useOptions({
  20438. sortBy,
  20439. page: shallowRef(1),
  20440. itemsPerPage: shallowRef(-1),
  20441. groupBy,
  20442. search
  20443. });
  20444. provideDefaults({
  20445. VDataTableRows: {
  20446. hideNoData: toRef(props, 'hideNoData'),
  20447. noDataText: toRef(props, 'noDataText'),
  20448. loading: toRef(props, 'loading'),
  20449. loadingText: toRef(props, 'loadingText')
  20450. }
  20451. });
  20452. const slotProps = computed(() => ({
  20453. sortBy: sortBy.value,
  20454. toggleSort,
  20455. someSelected: someSelected.value,
  20456. allSelected: allSelected.value,
  20457. isSelected,
  20458. select,
  20459. selectAll,
  20460. toggleSelect,
  20461. isExpanded,
  20462. toggleExpand,
  20463. isGroupOpen,
  20464. toggleGroup,
  20465. items: allItems.value.map(item => item.raw),
  20466. internalItems: allItems.value,
  20467. groupedItems: flatItems.value,
  20468. columns: columns.value,
  20469. headers: headers.value
  20470. }));
  20471. useRender(() => {
  20472. const dataTableHeadersProps = VDataTableHeaders.filterProps(props);
  20473. const dataTableRowsProps = VDataTableRows.filterProps(props);
  20474. const tableProps = VTable.filterProps(props);
  20475. return createVNode(VTable, mergeProps({
  20476. "class": ['v-data-table', {
  20477. 'v-data-table--loading': props.loading
  20478. }, props.class],
  20479. "style": props.style
  20480. }, tableProps), {
  20481. top: () => slots.top?.(slotProps.value),
  20482. wrapper: () => createVNode("div", {
  20483. "ref": containerRef,
  20484. "onScrollPassive": handleScroll,
  20485. "onScrollend": handleScrollend,
  20486. "class": "v-table__wrapper",
  20487. "style": {
  20488. height: convertToUnit(props.height)
  20489. }
  20490. }, [createVNode("table", null, [slots.colgroup?.(slotProps.value), !props.hideDefaultHeader && createVNode("thead", {
  20491. "key": "thead"
  20492. }, [createVNode(VDataTableHeaders, mergeProps(dataTableHeadersProps, {
  20493. "sticky": props.fixedHeader
  20494. }), slots)]), !props.hideDefaultBody && createVNode("tbody", null, [createVNode("tr", {
  20495. "ref": markerRef,
  20496. "style": {
  20497. height: convertToUnit(paddingTop.value),
  20498. border: 0
  20499. }
  20500. }, [createVNode("td", {
  20501. "colspan": columns.value.length,
  20502. "style": {
  20503. height: 0,
  20504. border: 0
  20505. }
  20506. }, null)]), slots['body.prepend']?.(slotProps.value), createVNode(VDataTableRows, mergeProps(attrs, dataTableRowsProps, {
  20507. "items": displayItems.value
  20508. }), {
  20509. ...slots,
  20510. item: itemSlotProps => createVNode(VVirtualScrollItem, {
  20511. "key": itemSlotProps.internalItem.index,
  20512. "renderless": true,
  20513. "onUpdate:height": height => handleItemResize(itemSlotProps.internalItem.index, height)
  20514. }, {
  20515. default: _ref2 => {
  20516. let {
  20517. itemRef
  20518. } = _ref2;
  20519. return slots.item?.({
  20520. ...itemSlotProps,
  20521. itemRef
  20522. }) ?? createVNode(VDataTableRow, mergeProps(itemSlotProps.props, {
  20523. "ref": itemRef,
  20524. "key": itemSlotProps.internalItem.index,
  20525. "index": itemSlotProps.internalItem.index
  20526. }), slots);
  20527. }
  20528. })
  20529. }), slots['body.append']?.(slotProps.value), createVNode("tr", {
  20530. "style": {
  20531. height: convertToUnit(paddingBottom.value),
  20532. border: 0
  20533. }
  20534. }, [createVNode("td", {
  20535. "colspan": columns.value.length,
  20536. "style": {
  20537. height: 0,
  20538. border: 0
  20539. }
  20540. }, null)])])])]),
  20541. bottom: () => slots.bottom?.(slotProps.value)
  20542. });
  20543. });
  20544. }
  20545. });
  20546. // Types
  20547. const makeVDataTableServerProps = propsFactory({
  20548. itemsLength: {
  20549. type: [Number, String],
  20550. required: true
  20551. },
  20552. ...makeDataTablePaginateProps(),
  20553. ...makeDataTableProps(),
  20554. ...makeVDataTableFooterProps()
  20555. }, 'VDataTableServer');
  20556. const VDataTableServer = genericComponent()({
  20557. name: 'VDataTableServer',
  20558. props: makeVDataTableServerProps(),
  20559. emits: {
  20560. 'update:modelValue': value => true,
  20561. 'update:page': page => true,
  20562. 'update:itemsPerPage': page => true,
  20563. 'update:sortBy': sortBy => true,
  20564. 'update:options': options => true,
  20565. 'update:expanded': options => true,
  20566. 'update:groupBy': value => true
  20567. },
  20568. setup(props, _ref) {
  20569. let {
  20570. attrs,
  20571. slots
  20572. } = _ref;
  20573. const {
  20574. groupBy
  20575. } = createGroupBy(props);
  20576. const {
  20577. sortBy,
  20578. multiSort,
  20579. mustSort
  20580. } = createSort(props);
  20581. const {
  20582. page,
  20583. itemsPerPage
  20584. } = createPagination(props);
  20585. const {
  20586. disableSort
  20587. } = toRefs(props);
  20588. const itemsLength = computed(() => parseInt(props.itemsLength, 10));
  20589. const {
  20590. columns,
  20591. headers
  20592. } = createHeaders(props, {
  20593. groupBy,
  20594. showSelect: toRef(props, 'showSelect'),
  20595. showExpand: toRef(props, 'showExpand')
  20596. });
  20597. const {
  20598. items
  20599. } = useDataTableItems(props, columns);
  20600. const {
  20601. toggleSort
  20602. } = provideSort({
  20603. sortBy,
  20604. multiSort,
  20605. mustSort,
  20606. page
  20607. });
  20608. const {
  20609. opened,
  20610. isGroupOpen,
  20611. toggleGroup,
  20612. extractRows
  20613. } = provideGroupBy({
  20614. groupBy,
  20615. sortBy,
  20616. disableSort
  20617. });
  20618. const {
  20619. pageCount,
  20620. setItemsPerPage
  20621. } = providePagination({
  20622. page,
  20623. itemsPerPage,
  20624. itemsLength
  20625. });
  20626. const {
  20627. flatItems
  20628. } = useGroupedItems(items, groupBy, opened);
  20629. const {
  20630. isSelected,
  20631. select,
  20632. selectAll,
  20633. toggleSelect,
  20634. someSelected,
  20635. allSelected
  20636. } = provideSelection(props, {
  20637. allItems: items,
  20638. currentPage: items
  20639. });
  20640. const {
  20641. isExpanded,
  20642. toggleExpand
  20643. } = provideExpanded(props);
  20644. const itemsWithoutGroups = computed(() => extractRows(items.value));
  20645. useOptions({
  20646. page,
  20647. itemsPerPage,
  20648. sortBy,
  20649. groupBy,
  20650. search: toRef(props, 'search')
  20651. });
  20652. provide('v-data-table', {
  20653. toggleSort,
  20654. sortBy
  20655. });
  20656. provideDefaults({
  20657. VDataTableRows: {
  20658. hideNoData: toRef(props, 'hideNoData'),
  20659. noDataText: toRef(props, 'noDataText'),
  20660. loading: toRef(props, 'loading'),
  20661. loadingText: toRef(props, 'loadingText')
  20662. }
  20663. });
  20664. const slotProps = computed(() => ({
  20665. page: page.value,
  20666. itemsPerPage: itemsPerPage.value,
  20667. sortBy: sortBy.value,
  20668. pageCount: pageCount.value,
  20669. toggleSort,
  20670. setItemsPerPage,
  20671. someSelected: someSelected.value,
  20672. allSelected: allSelected.value,
  20673. isSelected,
  20674. select,
  20675. selectAll,
  20676. toggleSelect,
  20677. isExpanded,
  20678. toggleExpand,
  20679. isGroupOpen,
  20680. toggleGroup,
  20681. items: itemsWithoutGroups.value.map(item => item.raw),
  20682. internalItems: itemsWithoutGroups.value,
  20683. groupedItems: flatItems.value,
  20684. columns: columns.value,
  20685. headers: headers.value
  20686. }));
  20687. useRender(() => {
  20688. const dataTableFooterProps = VDataTableFooter.filterProps(props);
  20689. const dataTableHeadersProps = VDataTableHeaders.filterProps(props);
  20690. const dataTableRowsProps = VDataTableRows.filterProps(props);
  20691. const tableProps = VTable.filterProps(props);
  20692. return createVNode(VTable, mergeProps({
  20693. "class": ['v-data-table', {
  20694. 'v-data-table--loading': props.loading
  20695. }, props.class],
  20696. "style": props.style
  20697. }, tableProps), {
  20698. top: () => slots.top?.(slotProps.value),
  20699. default: () => slots.default ? slots.default(slotProps.value) : createVNode(Fragment, null, [slots.colgroup?.(slotProps.value), !props.hideDefaultHeader && createVNode("thead", {
  20700. "key": "thead",
  20701. "class": "v-data-table__thead",
  20702. "role": "rowgroup"
  20703. }, [createVNode(VDataTableHeaders, mergeProps(dataTableHeadersProps, {
  20704. "sticky": props.fixedHeader
  20705. }), slots)]), slots.thead?.(slotProps.value), !props.hideDefaultBody && createVNode("tbody", {
  20706. "class": "v-data-table__tbody",
  20707. "role": "rowgroup"
  20708. }, [slots['body.prepend']?.(slotProps.value), slots.body ? slots.body(slotProps.value) : createVNode(VDataTableRows, mergeProps(attrs, dataTableRowsProps, {
  20709. "items": flatItems.value
  20710. }), slots), slots['body.append']?.(slotProps.value)]), slots.tbody?.(slotProps.value), slots.tfoot?.(slotProps.value)]),
  20711. bottom: () => slots.bottom ? slots.bottom(slotProps.value) : !props.hideDefaultFooter && createVNode(Fragment, null, [createVNode(VDivider, null, null), createVNode(VDataTableFooter, dataTableFooterProps, {
  20712. prepend: slots['footer.prepend']
  20713. })])
  20714. });
  20715. });
  20716. }
  20717. });
  20718. const makeVContainerProps = propsFactory({
  20719. fluid: {
  20720. type: Boolean,
  20721. default: false
  20722. },
  20723. ...makeComponentProps(),
  20724. ...makeDimensionProps(),
  20725. ...makeTagProps()
  20726. }, 'VContainer');
  20727. const VContainer = genericComponent()({
  20728. name: 'VContainer',
  20729. props: makeVContainerProps(),
  20730. setup(props, _ref) {
  20731. let {
  20732. slots
  20733. } = _ref;
  20734. const {
  20735. rtlClasses
  20736. } = useRtl();
  20737. const {
  20738. dimensionStyles
  20739. } = useDimension(props);
  20740. useRender(() => createVNode(props.tag, {
  20741. "class": ['v-container', {
  20742. 'v-container--fluid': props.fluid
  20743. }, rtlClasses.value, props.class],
  20744. "style": [dimensionStyles.value, props.style]
  20745. }, slots));
  20746. return {};
  20747. }
  20748. });
  20749. // Styles
  20750. // Types
  20751. const breakpointProps = (() => {
  20752. return breakpoints.reduce((props, val) => {
  20753. props[val] = {
  20754. type: [Boolean, String, Number],
  20755. default: false
  20756. };
  20757. return props;
  20758. }, {});
  20759. })();
  20760. const offsetProps = (() => {
  20761. return breakpoints.reduce((props, val) => {
  20762. const offsetKey = 'offset' + capitalize(val);
  20763. props[offsetKey] = {
  20764. type: [String, Number],
  20765. default: null
  20766. };
  20767. return props;
  20768. }, {});
  20769. })();
  20770. const orderProps = (() => {
  20771. return breakpoints.reduce((props, val) => {
  20772. const orderKey = 'order' + capitalize(val);
  20773. props[orderKey] = {
  20774. type: [String, Number],
  20775. default: null
  20776. };
  20777. return props;
  20778. }, {});
  20779. })();
  20780. const propMap$1 = {
  20781. col: Object.keys(breakpointProps),
  20782. offset: Object.keys(offsetProps),
  20783. order: Object.keys(orderProps)
  20784. };
  20785. function breakpointClass$1(type, prop, val) {
  20786. let className = type;
  20787. if (val == null || val === false) {
  20788. return undefined;
  20789. }
  20790. if (prop) {
  20791. const breakpoint = prop.replace(type, '');
  20792. className += `-${breakpoint}`;
  20793. }
  20794. if (type === 'col') {
  20795. className = 'v-' + className;
  20796. }
  20797. // Handling the boolean style prop when accepting [Boolean, String, Number]
  20798. // means Vue will not convert <v-col sm></v-col> to sm: true for us.
  20799. // Since the default is false, an empty string indicates the prop's presence.
  20800. if (type === 'col' && (val === '' || val === true)) {
  20801. // .v-col-md
  20802. return className.toLowerCase();
  20803. }
  20804. // .order-md-6
  20805. className += `-${val}`;
  20806. return className.toLowerCase();
  20807. }
  20808. const ALIGN_SELF_VALUES = ['auto', 'start', 'end', 'center', 'baseline', 'stretch'];
  20809. const makeVColProps = propsFactory({
  20810. cols: {
  20811. type: [Boolean, String, Number],
  20812. default: false
  20813. },
  20814. ...breakpointProps,
  20815. offset: {
  20816. type: [String, Number],
  20817. default: null
  20818. },
  20819. ...offsetProps,
  20820. order: {
  20821. type: [String, Number],
  20822. default: null
  20823. },
  20824. ...orderProps,
  20825. alignSelf: {
  20826. type: String,
  20827. default: null,
  20828. validator: str => ALIGN_SELF_VALUES.includes(str)
  20829. },
  20830. ...makeComponentProps(),
  20831. ...makeTagProps()
  20832. }, 'VCol');
  20833. const VCol = genericComponent()({
  20834. name: 'VCol',
  20835. props: makeVColProps(),
  20836. setup(props, _ref) {
  20837. let {
  20838. slots
  20839. } = _ref;
  20840. const classes = computed(() => {
  20841. const classList = [];
  20842. // Loop through `col`, `offset`, `order` breakpoint props
  20843. let type;
  20844. for (type in propMap$1) {
  20845. propMap$1[type].forEach(prop => {
  20846. const value = props[prop];
  20847. const className = breakpointClass$1(type, prop, value);
  20848. if (className) classList.push(className);
  20849. });
  20850. }
  20851. const hasColClasses = classList.some(className => className.startsWith('v-col-'));
  20852. classList.push({
  20853. // Default to .v-col if no other col-{bp}-* classes generated nor `cols` specified.
  20854. 'v-col': !hasColClasses || !props.cols,
  20855. [`v-col-${props.cols}`]: props.cols,
  20856. [`offset-${props.offset}`]: props.offset,
  20857. [`order-${props.order}`]: props.order,
  20858. [`align-self-${props.alignSelf}`]: props.alignSelf
  20859. });
  20860. return classList;
  20861. });
  20862. return () => h(props.tag, {
  20863. class: [classes.value, props.class],
  20864. style: props.style
  20865. }, slots.default?.());
  20866. }
  20867. });
  20868. // Styles
  20869. // Types
  20870. const ALIGNMENT = ['start', 'end', 'center'];
  20871. const SPACE = ['space-between', 'space-around', 'space-evenly'];
  20872. function makeRowProps(prefix, def) {
  20873. return breakpoints.reduce((props, val) => {
  20874. const prefixKey = prefix + capitalize(val);
  20875. props[prefixKey] = def();
  20876. return props;
  20877. }, {});
  20878. }
  20879. const ALIGN_VALUES = [...ALIGNMENT, 'baseline', 'stretch'];
  20880. const alignValidator = str => ALIGN_VALUES.includes(str);
  20881. const alignProps = makeRowProps('align', () => ({
  20882. type: String,
  20883. default: null,
  20884. validator: alignValidator
  20885. }));
  20886. const JUSTIFY_VALUES = [...ALIGNMENT, ...SPACE];
  20887. const justifyValidator = str => JUSTIFY_VALUES.includes(str);
  20888. const justifyProps = makeRowProps('justify', () => ({
  20889. type: String,
  20890. default: null,
  20891. validator: justifyValidator
  20892. }));
  20893. const ALIGN_CONTENT_VALUES = [...ALIGNMENT, ...SPACE, 'stretch'];
  20894. const alignContentValidator = str => ALIGN_CONTENT_VALUES.includes(str);
  20895. const alignContentProps = makeRowProps('alignContent', () => ({
  20896. type: String,
  20897. default: null,
  20898. validator: alignContentValidator
  20899. }));
  20900. const propMap = {
  20901. align: Object.keys(alignProps),
  20902. justify: Object.keys(justifyProps),
  20903. alignContent: Object.keys(alignContentProps)
  20904. };
  20905. const classMap = {
  20906. align: 'align',
  20907. justify: 'justify',
  20908. alignContent: 'align-content'
  20909. };
  20910. function breakpointClass(type, prop, val) {
  20911. let className = classMap[type];
  20912. if (val == null) {
  20913. return undefined;
  20914. }
  20915. if (prop) {
  20916. // alignSm -> Sm
  20917. const breakpoint = prop.replace(type, '');
  20918. className += `-${breakpoint}`;
  20919. }
  20920. // .align-items-sm-center
  20921. className += `-${val}`;
  20922. return className.toLowerCase();
  20923. }
  20924. const makeVRowProps = propsFactory({
  20925. dense: Boolean,
  20926. noGutters: Boolean,
  20927. align: {
  20928. type: String,
  20929. default: null,
  20930. validator: alignValidator
  20931. },
  20932. ...alignProps,
  20933. justify: {
  20934. type: String,
  20935. default: null,
  20936. validator: justifyValidator
  20937. },
  20938. ...justifyProps,
  20939. alignContent: {
  20940. type: String,
  20941. default: null,
  20942. validator: alignContentValidator
  20943. },
  20944. ...alignContentProps,
  20945. ...makeComponentProps(),
  20946. ...makeTagProps()
  20947. }, 'VRow');
  20948. const VRow = genericComponent()({
  20949. name: 'VRow',
  20950. props: makeVRowProps(),
  20951. setup(props, _ref) {
  20952. let {
  20953. slots
  20954. } = _ref;
  20955. const classes = computed(() => {
  20956. const classList = [];
  20957. // Loop through `align`, `justify`, `alignContent` breakpoint props
  20958. let type;
  20959. for (type in propMap) {
  20960. propMap[type].forEach(prop => {
  20961. const value = props[prop];
  20962. const className = breakpointClass(type, prop, value);
  20963. if (className) classList.push(className);
  20964. });
  20965. }
  20966. classList.push({
  20967. 'v-row--no-gutters': props.noGutters,
  20968. 'v-row--dense': props.dense,
  20969. [`align-${props.align}`]: props.align,
  20970. [`justify-${props.justify}`]: props.justify,
  20971. [`align-content-${props.alignContent}`]: props.alignContent
  20972. });
  20973. return classList;
  20974. });
  20975. return () => h(props.tag, {
  20976. class: ['v-row', classes.value, props.class],
  20977. style: props.style
  20978. }, slots.default?.());
  20979. }
  20980. });
  20981. // Styles
  20982. const VSpacer = createSimpleFunctional('v-spacer', 'div', 'VSpacer');
  20983. // Types
  20984. const makeVDatePickerControlsProps = propsFactory({
  20985. active: {
  20986. type: [String, Array],
  20987. default: undefined
  20988. },
  20989. disabled: {
  20990. type: [Boolean, String, Array],
  20991. default: false
  20992. },
  20993. nextIcon: {
  20994. type: IconValue,
  20995. default: '$next'
  20996. },
  20997. prevIcon: {
  20998. type: IconValue,
  20999. default: '$prev'
  21000. },
  21001. modeIcon: {
  21002. type: IconValue,
  21003. default: '$subgroup'
  21004. },
  21005. text: String,
  21006. viewMode: {
  21007. type: String,
  21008. default: 'month'
  21009. }
  21010. }, 'VDatePickerControls');
  21011. const VDatePickerControls = genericComponent()({
  21012. name: 'VDatePickerControls',
  21013. props: makeVDatePickerControlsProps(),
  21014. emits: {
  21015. 'click:year': () => true,
  21016. 'click:month': () => true,
  21017. 'click:prev': () => true,
  21018. 'click:next': () => true,
  21019. 'click:text': () => true
  21020. },
  21021. setup(props, _ref) {
  21022. let {
  21023. emit
  21024. } = _ref;
  21025. const disableMonth = computed(() => {
  21026. return Array.isArray(props.disabled) ? props.disabled.includes('text') : !!props.disabled;
  21027. });
  21028. const disableYear = computed(() => {
  21029. return Array.isArray(props.disabled) ? props.disabled.includes('mode') : !!props.disabled;
  21030. });
  21031. const disablePrev = computed(() => {
  21032. return Array.isArray(props.disabled) ? props.disabled.includes('prev') : !!props.disabled;
  21033. });
  21034. const disableNext = computed(() => {
  21035. return Array.isArray(props.disabled) ? props.disabled.includes('next') : !!props.disabled;
  21036. });
  21037. function onClickPrev() {
  21038. emit('click:prev');
  21039. }
  21040. function onClickNext() {
  21041. emit('click:next');
  21042. }
  21043. function onClickYear() {
  21044. emit('click:year');
  21045. }
  21046. function onClickMonth() {
  21047. emit('click:month');
  21048. }
  21049. useRender(() => {
  21050. // TODO: add slot support and scope defaults
  21051. return createVNode("div", {
  21052. "class": ['v-date-picker-controls']
  21053. }, [createVNode(VBtn, {
  21054. "class": "v-date-picker-controls__month-btn",
  21055. "disabled": disableMonth.value,
  21056. "text": props.text,
  21057. "variant": "text",
  21058. "rounded": true,
  21059. "onClick": onClickMonth
  21060. }, null), createVNode(VBtn, {
  21061. "key": "mode-btn",
  21062. "class": "v-date-picker-controls__mode-btn",
  21063. "disabled": disableYear.value,
  21064. "density": "comfortable",
  21065. "icon": props.modeIcon,
  21066. "variant": "text",
  21067. "onClick": onClickYear
  21068. }, null), createVNode(VSpacer, {
  21069. "key": "mode-spacer"
  21070. }, null), createVNode("div", {
  21071. "key": "month-buttons",
  21072. "class": "v-date-picker-controls__month"
  21073. }, [createVNode(VBtn, {
  21074. "disabled": disablePrev.value,
  21075. "icon": props.prevIcon,
  21076. "variant": "text",
  21077. "onClick": onClickPrev
  21078. }, null), createVNode(VBtn, {
  21079. "disabled": disableNext.value,
  21080. "icon": props.nextIcon,
  21081. "variant": "text",
  21082. "onClick": onClickNext
  21083. }, null)])]);
  21084. });
  21085. return {};
  21086. }
  21087. });
  21088. // Types
  21089. const makeVDatePickerHeaderProps = propsFactory({
  21090. appendIcon: IconValue,
  21091. color: String,
  21092. header: String,
  21093. transition: String,
  21094. onClick: EventProp()
  21095. }, 'VDatePickerHeader');
  21096. const VDatePickerHeader = genericComponent()({
  21097. name: 'VDatePickerHeader',
  21098. props: makeVDatePickerHeaderProps(),
  21099. emits: {
  21100. click: () => true,
  21101. 'click:append': () => true
  21102. },
  21103. setup(props, _ref) {
  21104. let {
  21105. emit,
  21106. slots
  21107. } = _ref;
  21108. const {
  21109. backgroundColorClasses,
  21110. backgroundColorStyles
  21111. } = useBackgroundColor(props, 'color');
  21112. function onClick() {
  21113. emit('click');
  21114. }
  21115. function onClickAppend() {
  21116. emit('click:append');
  21117. }
  21118. useRender(() => {
  21119. const hasContent = !!(slots.default || props.header);
  21120. const hasAppend = !!(slots.append || props.appendIcon);
  21121. return createVNode("div", {
  21122. "class": ['v-date-picker-header', {
  21123. 'v-date-picker-header--clickable': !!props.onClick
  21124. }, backgroundColorClasses.value],
  21125. "style": backgroundColorStyles.value,
  21126. "onClick": onClick
  21127. }, [slots.prepend && createVNode("div", {
  21128. "key": "prepend",
  21129. "class": "v-date-picker-header__prepend"
  21130. }, [slots.prepend()]), hasContent && createVNode(MaybeTransition, {
  21131. "key": "content",
  21132. "name": props.transition
  21133. }, {
  21134. default: () => [createVNode("div", {
  21135. "key": props.header,
  21136. "class": "v-date-picker-header__content"
  21137. }, [slots.default?.() ?? props.header])]
  21138. }), hasAppend && createVNode("div", {
  21139. "class": "v-date-picker-header__append"
  21140. }, [!slots.append ? createVNode(VBtn, {
  21141. "key": "append-btn",
  21142. "icon": props.appendIcon,
  21143. "variant": "text",
  21144. "onClick": onClickAppend
  21145. }, null) : createVNode(VDefaultsProvider, {
  21146. "key": "append-defaults",
  21147. "disabled": !props.appendIcon,
  21148. "defaults": {
  21149. VBtn: {
  21150. icon: props.appendIcon,
  21151. variant: 'text'
  21152. }
  21153. }
  21154. }, {
  21155. default: () => [slots.append?.()]
  21156. })])]);
  21157. });
  21158. return {};
  21159. }
  21160. });
  21161. // Composables
  21162. // Types
  21163. // Types
  21164. // Composables
  21165. const makeCalendarProps = propsFactory({
  21166. allowedDates: [Array, Function],
  21167. disabled: Boolean,
  21168. displayValue: null,
  21169. modelValue: Array,
  21170. month: [Number, String],
  21171. max: null,
  21172. min: null,
  21173. showAdjacentMonths: Boolean,
  21174. year: [Number, String],
  21175. weekdays: {
  21176. type: Array,
  21177. default: () => [0, 1, 2, 3, 4, 5, 6]
  21178. },
  21179. weeksInMonth: {
  21180. type: String,
  21181. default: 'dynamic'
  21182. },
  21183. firstDayOfWeek: [Number, String]
  21184. }, 'calendar');
  21185. function useCalendar(props) {
  21186. const adapter = useDate();
  21187. const model = useProxiedModel(props, 'modelValue', [], v => wrapInArray(v));
  21188. const displayValue = computed(() => {
  21189. if (props.displayValue) return adapter.date(props.displayValue);
  21190. if (model.value.length > 0) return adapter.date(model.value[0]);
  21191. if (props.min) return adapter.date(props.min);
  21192. if (Array.isArray(props.allowedDates)) return adapter.date(props.allowedDates[0]);
  21193. return adapter.date();
  21194. });
  21195. const year = useProxiedModel(props, 'year', undefined, v => {
  21196. const value = v != null ? Number(v) : adapter.getYear(displayValue.value);
  21197. return adapter.startOfYear(adapter.setYear(adapter.date(), value));
  21198. }, v => adapter.getYear(v));
  21199. const month = useProxiedModel(props, 'month', undefined, v => {
  21200. const value = v != null ? Number(v) : adapter.getMonth(displayValue.value);
  21201. const date = adapter.setYear(adapter.startOfMonth(adapter.date()), adapter.getYear(year.value));
  21202. return adapter.setMonth(date, value);
  21203. }, v => adapter.getMonth(v));
  21204. const weekDays = computed(() => {
  21205. const firstDayOfWeek = Number(props.firstDayOfWeek ?? 0);
  21206. return props.weekdays.map(day => (day + firstDayOfWeek) % 7);
  21207. });
  21208. const weeksInMonth = computed(() => {
  21209. const weeks = adapter.getWeekArray(month.value, props.firstDayOfWeek);
  21210. const days = weeks.flat();
  21211. // Make sure there's always 6 weeks in month (6 * 7 days)
  21212. // if weeksInMonth is 'static'
  21213. const daysInMonth = 6 * 7;
  21214. if (props.weeksInMonth === 'static' && days.length < daysInMonth) {
  21215. const lastDay = days[days.length - 1];
  21216. let week = [];
  21217. for (let day = 1; day <= daysInMonth - days.length; day++) {
  21218. week.push(adapter.addDays(lastDay, day));
  21219. if (day % 7 === 0) {
  21220. weeks.push(week);
  21221. week = [];
  21222. }
  21223. }
  21224. }
  21225. return weeks;
  21226. });
  21227. function genDays(days, today) {
  21228. return days.filter(date => {
  21229. return weekDays.value.includes(adapter.toJsDate(date).getDay());
  21230. }).map((date, index) => {
  21231. const isoDate = adapter.toISO(date);
  21232. const isAdjacent = !adapter.isSameMonth(date, month.value);
  21233. const isStart = adapter.isSameDay(date, adapter.startOfMonth(month.value));
  21234. const isEnd = adapter.isSameDay(date, adapter.endOfMonth(month.value));
  21235. const isSame = adapter.isSameDay(date, month.value);
  21236. return {
  21237. date,
  21238. isoDate,
  21239. formatted: adapter.format(date, 'keyboardDate'),
  21240. year: adapter.getYear(date),
  21241. month: adapter.getMonth(date),
  21242. isDisabled: isDisabled(date),
  21243. isWeekStart: index % 7 === 0,
  21244. isWeekEnd: index % 7 === 6,
  21245. isToday: adapter.isSameDay(date, today),
  21246. isAdjacent,
  21247. isHidden: isAdjacent && !props.showAdjacentMonths,
  21248. isStart,
  21249. isSelected: model.value.some(value => adapter.isSameDay(date, value)),
  21250. isEnd,
  21251. isSame,
  21252. localized: adapter.format(date, 'dayOfMonth')
  21253. };
  21254. });
  21255. }
  21256. const daysInWeek = computed(() => {
  21257. const lastDay = adapter.startOfWeek(displayValue.value, props.firstDayOfWeek);
  21258. const week = [];
  21259. for (let day = 0; day <= 6; day++) {
  21260. week.push(adapter.addDays(lastDay, day));
  21261. }
  21262. const today = adapter.date();
  21263. return genDays(week, today);
  21264. });
  21265. const daysInMonth = computed(() => {
  21266. const days = weeksInMonth.value.flat();
  21267. const today = adapter.date();
  21268. return genDays(days, today);
  21269. });
  21270. const weekNumbers = computed(() => {
  21271. return weeksInMonth.value.map(week => {
  21272. return week.length ? getWeek(adapter, week[0]) : null;
  21273. });
  21274. });
  21275. function isDisabled(value) {
  21276. if (props.disabled) return true;
  21277. const date = adapter.date(value);
  21278. if (props.min && adapter.isAfter(adapter.date(props.min), date)) return true;
  21279. if (props.max && adapter.isAfter(date, adapter.date(props.max))) return true;
  21280. if (Array.isArray(props.allowedDates) && props.allowedDates.length > 0) {
  21281. return !props.allowedDates.some(d => adapter.isSameDay(adapter.date(d), date));
  21282. }
  21283. if (typeof props.allowedDates === 'function') {
  21284. return !props.allowedDates(date);
  21285. }
  21286. return false;
  21287. }
  21288. return {
  21289. displayValue,
  21290. daysInMonth,
  21291. daysInWeek,
  21292. genDays,
  21293. model,
  21294. weeksInMonth,
  21295. weekDays,
  21296. weekNumbers
  21297. };
  21298. }
  21299. // Types
  21300. const makeVDatePickerMonthProps = propsFactory({
  21301. color: String,
  21302. hideWeekdays: Boolean,
  21303. multiple: [Boolean, Number, String],
  21304. showWeek: Boolean,
  21305. transition: {
  21306. type: String,
  21307. default: 'picker-transition'
  21308. },
  21309. reverseTransition: {
  21310. type: String,
  21311. default: 'picker-reverse-transition'
  21312. },
  21313. ...makeCalendarProps()
  21314. }, 'VDatePickerMonth');
  21315. const VDatePickerMonth = genericComponent()({
  21316. name: 'VDatePickerMonth',
  21317. props: makeVDatePickerMonthProps(),
  21318. emits: {
  21319. 'update:modelValue': date => true,
  21320. 'update:month': date => true,
  21321. 'update:year': date => true
  21322. },
  21323. setup(props, _ref) {
  21324. let {
  21325. emit,
  21326. slots
  21327. } = _ref;
  21328. const daysRef = ref();
  21329. const {
  21330. daysInMonth,
  21331. model,
  21332. weekNumbers
  21333. } = useCalendar(props);
  21334. const adapter = useDate();
  21335. const rangeStart = shallowRef();
  21336. const rangeStop = shallowRef();
  21337. const isReverse = shallowRef(false);
  21338. const transition = computed(() => {
  21339. return !isReverse.value ? props.transition : props.reverseTransition;
  21340. });
  21341. if (props.multiple === 'range' && model.value.length > 0) {
  21342. rangeStart.value = model.value[0];
  21343. if (model.value.length > 1) {
  21344. rangeStop.value = model.value[model.value.length - 1];
  21345. }
  21346. }
  21347. const atMax = computed(() => {
  21348. const max = ['number', 'string'].includes(typeof props.multiple) ? Number(props.multiple) : Infinity;
  21349. return model.value.length >= max;
  21350. });
  21351. watch(daysInMonth, (val, oldVal) => {
  21352. if (!oldVal) return;
  21353. isReverse.value = adapter.isBefore(val[0].date, oldVal[0].date);
  21354. });
  21355. function onRangeClick(value) {
  21356. const _value = adapter.startOfDay(value);
  21357. if (model.value.length === 0) {
  21358. rangeStart.value = undefined;
  21359. } else if (model.value.length === 1) {
  21360. rangeStart.value = model.value[0];
  21361. rangeStop.value = undefined;
  21362. }
  21363. if (!rangeStart.value) {
  21364. rangeStart.value = _value;
  21365. model.value = [rangeStart.value];
  21366. } else if (!rangeStop.value) {
  21367. if (adapter.isSameDay(_value, rangeStart.value)) {
  21368. rangeStart.value = undefined;
  21369. model.value = [];
  21370. return;
  21371. } else if (adapter.isBefore(_value, rangeStart.value)) {
  21372. rangeStop.value = adapter.endOfDay(rangeStart.value);
  21373. rangeStart.value = _value;
  21374. } else {
  21375. rangeStop.value = adapter.endOfDay(_value);
  21376. }
  21377. const diff = adapter.getDiff(rangeStop.value, rangeStart.value, 'days');
  21378. const datesInRange = [rangeStart.value];
  21379. for (let i = 1; i < diff; i++) {
  21380. const nextDate = adapter.addDays(rangeStart.value, i);
  21381. datesInRange.push(nextDate);
  21382. }
  21383. datesInRange.push(rangeStop.value);
  21384. model.value = datesInRange;
  21385. } else {
  21386. rangeStart.value = value;
  21387. rangeStop.value = undefined;
  21388. model.value = [rangeStart.value];
  21389. }
  21390. }
  21391. function onMultipleClick(value) {
  21392. const index = model.value.findIndex(selection => adapter.isSameDay(selection, value));
  21393. if (index === -1) {
  21394. model.value = [...model.value, value];
  21395. } else {
  21396. const value = [...model.value];
  21397. value.splice(index, 1);
  21398. model.value = value;
  21399. }
  21400. }
  21401. function onClick(value) {
  21402. if (props.multiple === 'range') {
  21403. onRangeClick(value);
  21404. } else if (props.multiple) {
  21405. onMultipleClick(value);
  21406. } else {
  21407. model.value = [value];
  21408. }
  21409. }
  21410. return () => createVNode("div", {
  21411. "class": "v-date-picker-month"
  21412. }, [props.showWeek && createVNode("div", {
  21413. "key": "weeks",
  21414. "class": "v-date-picker-month__weeks"
  21415. }, [!props.hideWeekdays && createVNode("div", {
  21416. "key": "hide-week-days",
  21417. "class": "v-date-picker-month__day"
  21418. }, [createTextVNode("\xA0")]), weekNumbers.value.map(week => createVNode("div", {
  21419. "class": ['v-date-picker-month__day', 'v-date-picker-month__day--adjacent']
  21420. }, [week]))]), createVNode(MaybeTransition, {
  21421. "name": transition.value
  21422. }, {
  21423. default: () => [createVNode("div", {
  21424. "ref": daysRef,
  21425. "key": daysInMonth.value[0].date?.toString(),
  21426. "class": "v-date-picker-month__days"
  21427. }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek).map(weekDay => createVNode("div", {
  21428. "class": ['v-date-picker-month__day', 'v-date-picker-month__weekday']
  21429. }, [weekDay])), daysInMonth.value.map((item, i) => {
  21430. const slotProps = {
  21431. props: {
  21432. onClick: () => onClick(item.date)
  21433. },
  21434. item,
  21435. i
  21436. };
  21437. if (atMax.value && !item.isSelected) {
  21438. item.isDisabled = true;
  21439. }
  21440. return createVNode("div", {
  21441. "class": ['v-date-picker-month__day', {
  21442. 'v-date-picker-month__day--adjacent': item.isAdjacent,
  21443. 'v-date-picker-month__day--hide-adjacent': item.isHidden,
  21444. 'v-date-picker-month__day--selected': item.isSelected,
  21445. 'v-date-picker-month__day--week-end': item.isWeekEnd,
  21446. 'v-date-picker-month__day--week-start': item.isWeekStart
  21447. }],
  21448. "data-v-date": !item.isDisabled ? item.isoDate : undefined
  21449. }, [(props.showAdjacentMonths || !item.isAdjacent) && createVNode(VDefaultsProvider, {
  21450. "defaults": {
  21451. VBtn: {
  21452. class: 'v-date-picker-month__day-btn',
  21453. color: (item.isSelected || item.isToday) && !item.isDisabled ? props.color : undefined,
  21454. disabled: item.isDisabled,
  21455. icon: true,
  21456. ripple: false,
  21457. text: item.localized,
  21458. variant: item.isDisabled ? item.isToday ? 'outlined' : 'text' : item.isToday && !item.isSelected ? 'outlined' : 'flat',
  21459. onClick: () => onClick(item.date)
  21460. }
  21461. }
  21462. }, {
  21463. default: () => [slots.day?.(slotProps) ?? createVNode(VBtn, slotProps.props, null)]
  21464. })]);
  21465. })])]
  21466. })]);
  21467. }
  21468. });
  21469. // Types
  21470. const makeVDatePickerMonthsProps = propsFactory({
  21471. color: String,
  21472. height: [String, Number],
  21473. min: null,
  21474. max: null,
  21475. modelValue: Number,
  21476. year: Number
  21477. }, 'VDatePickerMonths');
  21478. const VDatePickerMonths = genericComponent()({
  21479. name: 'VDatePickerMonths',
  21480. props: makeVDatePickerMonthsProps(),
  21481. emits: {
  21482. 'update:modelValue': date => true
  21483. },
  21484. setup(props, _ref) {
  21485. let {
  21486. emit,
  21487. slots
  21488. } = _ref;
  21489. const adapter = useDate();
  21490. const model = useProxiedModel(props, 'modelValue');
  21491. const months = computed(() => {
  21492. let date = adapter.startOfYear(adapter.date());
  21493. if (props.year) {
  21494. date = adapter.setYear(date, props.year);
  21495. }
  21496. return createRange(12).map(i => {
  21497. const text = adapter.format(date, 'monthShort');
  21498. const isDisabled = !!(props.min && adapter.isAfter(adapter.startOfMonth(adapter.date(props.min)), date) || props.max && adapter.isAfter(date, adapter.startOfMonth(adapter.date(props.max))));
  21499. date = adapter.getNextMonth(date);
  21500. return {
  21501. isDisabled,
  21502. text,
  21503. value: i
  21504. };
  21505. });
  21506. });
  21507. watchEffect(() => {
  21508. model.value = model.value ?? adapter.getMonth(adapter.date());
  21509. });
  21510. useRender(() => createVNode("div", {
  21511. "class": "v-date-picker-months",
  21512. "style": {
  21513. height: convertToUnit(props.height)
  21514. }
  21515. }, [createVNode("div", {
  21516. "class": "v-date-picker-months__content"
  21517. }, [months.value.map((month, i) => {
  21518. const btnProps = {
  21519. active: model.value === i,
  21520. color: model.value === i ? props.color : undefined,
  21521. disabled: month.isDisabled,
  21522. rounded: true,
  21523. text: month.text,
  21524. variant: model.value === month.value ? 'flat' : 'text',
  21525. onClick: () => onClick(i)
  21526. };
  21527. function onClick(i) {
  21528. if (model.value === i) {
  21529. emit('update:modelValue', model.value);
  21530. return;
  21531. }
  21532. model.value = i;
  21533. }
  21534. return slots.month?.({
  21535. month,
  21536. i,
  21537. props: btnProps
  21538. }) ?? createVNode(VBtn, mergeProps({
  21539. "key": "month"
  21540. }, btnProps), null);
  21541. })])]));
  21542. return {};
  21543. }
  21544. });
  21545. // Types
  21546. // Types
  21547. const makeVDatePickerYearsProps = propsFactory({
  21548. color: String,
  21549. height: [String, Number],
  21550. min: null,
  21551. max: null,
  21552. modelValue: Number
  21553. }, 'VDatePickerYears');
  21554. const VDatePickerYears = genericComponent()({
  21555. name: 'VDatePickerYears',
  21556. props: makeVDatePickerYearsProps(),
  21557. emits: {
  21558. 'update:modelValue': year => true
  21559. },
  21560. setup(props, _ref) {
  21561. let {
  21562. emit,
  21563. slots
  21564. } = _ref;
  21565. const adapter = useDate();
  21566. const model = useProxiedModel(props, 'modelValue');
  21567. const years = computed(() => {
  21568. const year = adapter.getYear(adapter.date());
  21569. let min = year - 100;
  21570. let max = year + 52;
  21571. if (props.min) {
  21572. min = adapter.getYear(adapter.date(props.min));
  21573. }
  21574. if (props.max) {
  21575. max = adapter.getYear(adapter.date(props.max));
  21576. }
  21577. let date = adapter.startOfYear(adapter.date());
  21578. date = adapter.setYear(date, min);
  21579. return createRange(max - min + 1, min).map(i => {
  21580. const text = adapter.format(date, 'year');
  21581. date = adapter.setYear(date, adapter.getYear(date) + 1);
  21582. return {
  21583. text,
  21584. value: i
  21585. };
  21586. });
  21587. });
  21588. watchEffect(() => {
  21589. model.value = model.value ?? adapter.getYear(adapter.date());
  21590. });
  21591. const yearRef = templateRef();
  21592. onMounted(async () => {
  21593. await nextTick();
  21594. yearRef.el?.scrollIntoView({
  21595. block: 'center'
  21596. });
  21597. });
  21598. useRender(() => createVNode("div", {
  21599. "class": "v-date-picker-years",
  21600. "style": {
  21601. height: convertToUnit(props.height)
  21602. }
  21603. }, [createVNode("div", {
  21604. "class": "v-date-picker-years__content"
  21605. }, [years.value.map((year, i) => {
  21606. const btnProps = {
  21607. ref: model.value === year.value ? yearRef : undefined,
  21608. active: model.value === year.value,
  21609. color: model.value === year.value ? props.color : undefined,
  21610. rounded: true,
  21611. text: year.text,
  21612. variant: model.value === year.value ? 'flat' : 'text',
  21613. onClick: () => {
  21614. if (model.value === year.value) {
  21615. emit('update:modelValue', model.value);
  21616. return;
  21617. }
  21618. model.value = year.value;
  21619. }
  21620. };
  21621. return slots.year?.({
  21622. year,
  21623. i,
  21624. props: btnProps
  21625. }) ?? createVNode(VBtn, mergeProps({
  21626. "key": "month"
  21627. }, btnProps), null);
  21628. })])]));
  21629. return {};
  21630. }
  21631. });
  21632. // Utilities
  21633. const VPickerTitle = createSimpleFunctional('v-picker-title');
  21634. // Types
  21635. const makeVPickerProps = propsFactory({
  21636. bgColor: String,
  21637. landscape: Boolean,
  21638. title: String,
  21639. hideHeader: Boolean,
  21640. ...makeVSheetProps()
  21641. }, 'VPicker');
  21642. const VPicker = genericComponent()({
  21643. name: 'VPicker',
  21644. props: makeVPickerProps(),
  21645. setup(props, _ref) {
  21646. let {
  21647. slots
  21648. } = _ref;
  21649. const {
  21650. backgroundColorClasses,
  21651. backgroundColorStyles
  21652. } = useBackgroundColor(toRef(props, 'color'));
  21653. useRender(() => {
  21654. const sheetProps = VSheet.filterProps(props);
  21655. const hasTitle = !!(props.title || slots.title);
  21656. return createVNode(VSheet, mergeProps(sheetProps, {
  21657. "color": props.bgColor,
  21658. "class": ['v-picker', {
  21659. 'v-picker--landscape': props.landscape,
  21660. 'v-picker--with-actions': !!slots.actions
  21661. }, props.class],
  21662. "style": props.style
  21663. }), {
  21664. default: () => [!props.hideHeader && createVNode("div", {
  21665. "key": "header",
  21666. "class": [backgroundColorClasses.value],
  21667. "style": [backgroundColorStyles.value]
  21668. }, [hasTitle && createVNode(VPickerTitle, {
  21669. "key": "picker-title"
  21670. }, {
  21671. default: () => [slots.title?.() ?? props.title]
  21672. }), slots.header && createVNode("div", {
  21673. "class": "v-picker__header"
  21674. }, [slots.header()])]), createVNode("div", {
  21675. "class": "v-picker__body"
  21676. }, [slots.default?.()]), slots.actions && createVNode(VDefaultsProvider, {
  21677. "defaults": {
  21678. VBtn: {
  21679. slim: true,
  21680. variant: 'text'
  21681. }
  21682. }
  21683. }, {
  21684. default: () => [createVNode("div", {
  21685. "class": "v-picker__actions"
  21686. }, [slots.actions()])]
  21687. })]
  21688. });
  21689. });
  21690. return {};
  21691. }
  21692. });
  21693. // Types
  21694. // Types
  21695. const makeVDatePickerProps = propsFactory({
  21696. // TODO: implement in v3.5
  21697. // calendarIcon: {
  21698. // type: String,
  21699. // default: '$calendar',
  21700. // },
  21701. // keyboardIcon: {
  21702. // type: String,
  21703. // default: '$edit',
  21704. // },
  21705. // inputMode: {
  21706. // type: String as PropType<'calendar' | 'keyboard'>,
  21707. // default: 'calendar',
  21708. // },
  21709. // inputText: {
  21710. // type: String,
  21711. // default: '$vuetify.datePicker.input.placeholder',
  21712. // },
  21713. // inputPlaceholder: {
  21714. // type: String,
  21715. // default: 'dd/mm/yyyy',
  21716. // },
  21717. header: {
  21718. type: String,
  21719. default: '$vuetify.datePicker.header'
  21720. },
  21721. ...makeVDatePickerControlsProps(),
  21722. ...makeVDatePickerMonthProps({
  21723. weeksInMonth: 'static'
  21724. }),
  21725. ...omit(makeVDatePickerMonthsProps(), ['modelValue']),
  21726. ...omit(makeVDatePickerYearsProps(), ['modelValue']),
  21727. ...makeVPickerProps({
  21728. title: '$vuetify.datePicker.title'
  21729. }),
  21730. modelValue: null
  21731. }, 'VDatePicker');
  21732. const VDatePicker = genericComponent()({
  21733. name: 'VDatePicker',
  21734. props: makeVDatePickerProps(),
  21735. emits: {
  21736. 'update:modelValue': date => true,
  21737. 'update:month': date => true,
  21738. 'update:year': date => true,
  21739. // 'update:inputMode': (date: any) => true,
  21740. 'update:viewMode': date => true
  21741. },
  21742. setup(props, _ref) {
  21743. let {
  21744. emit,
  21745. slots
  21746. } = _ref;
  21747. const adapter = useDate();
  21748. const {
  21749. t
  21750. } = useLocale();
  21751. const model = useProxiedModel(props, 'modelValue', undefined, v => wrapInArray(v), v => props.multiple ? v : v[0]);
  21752. const viewMode = useProxiedModel(props, 'viewMode');
  21753. // const inputMode = useProxiedModel(props, 'inputMode')
  21754. const internal = computed(() => {
  21755. const value = adapter.date(model.value?.[0]);
  21756. return value && adapter.isValid(value) ? value : adapter.date();
  21757. });
  21758. const month = ref(Number(props.month ?? adapter.getMonth(adapter.startOfMonth(internal.value))));
  21759. const year = ref(Number(props.year ?? adapter.getYear(adapter.startOfYear(adapter.setMonth(internal.value, month.value)))));
  21760. const isReversing = shallowRef(false);
  21761. const header = computed(() => {
  21762. if (props.multiple && model.value.length > 1) {
  21763. return t('$vuetify.datePicker.itemsSelected', model.value.length);
  21764. }
  21765. return model.value[0] && adapter.isValid(model.value[0]) ? adapter.format(adapter.date(model.value[0]), 'normalDateWithWeekday') : t(props.header);
  21766. });
  21767. const text = computed(() => {
  21768. let date = adapter.date();
  21769. date = adapter.setDate(date, 1);
  21770. date = adapter.setMonth(date, month.value);
  21771. date = adapter.setYear(date, year.value);
  21772. return adapter.format(date, 'monthAndYear');
  21773. });
  21774. // const headerIcon = computed(() => props.inputMode === 'calendar' ? props.keyboardIcon : props.calendarIcon)
  21775. const headerTransition = computed(() => `date-picker-header${isReversing.value ? '-reverse' : ''}-transition`);
  21776. const minDate = computed(() => {
  21777. const date = adapter.date(props.min);
  21778. return props.min && adapter.isValid(date) ? date : null;
  21779. });
  21780. const maxDate = computed(() => {
  21781. const date = adapter.date(props.max);
  21782. return props.max && adapter.isValid(date) ? date : null;
  21783. });
  21784. const disabled = computed(() => {
  21785. if (props.disabled) return true;
  21786. const targets = [];
  21787. if (viewMode.value !== 'month') {
  21788. targets.push(...['prev', 'next']);
  21789. } else {
  21790. let _date = adapter.date();
  21791. _date = adapter.setYear(_date, year.value);
  21792. _date = adapter.setMonth(_date, month.value);
  21793. if (minDate.value) {
  21794. const date = adapter.addDays(adapter.startOfMonth(_date), -1);
  21795. adapter.isAfter(minDate.value, date) && targets.push('prev');
  21796. }
  21797. if (maxDate.value) {
  21798. const date = adapter.addDays(adapter.endOfMonth(_date), 1);
  21799. adapter.isAfter(date, maxDate.value) && targets.push('next');
  21800. }
  21801. }
  21802. return targets;
  21803. });
  21804. // function onClickAppend () {
  21805. // inputMode.value = inputMode.value === 'calendar' ? 'keyboard' : 'calendar'
  21806. // }
  21807. function onClickNext() {
  21808. if (month.value < 11) {
  21809. month.value++;
  21810. } else {
  21811. year.value++;
  21812. month.value = 0;
  21813. onUpdateYear(year.value);
  21814. }
  21815. onUpdateMonth(month.value);
  21816. }
  21817. function onClickPrev() {
  21818. if (month.value > 0) {
  21819. month.value--;
  21820. } else {
  21821. year.value--;
  21822. month.value = 11;
  21823. onUpdateYear(year.value);
  21824. }
  21825. onUpdateMonth(month.value);
  21826. }
  21827. function onClickDate() {
  21828. viewMode.value = 'month';
  21829. }
  21830. function onClickMonth() {
  21831. viewMode.value = viewMode.value === 'months' ? 'month' : 'months';
  21832. }
  21833. function onClickYear() {
  21834. viewMode.value = viewMode.value === 'year' ? 'month' : 'year';
  21835. }
  21836. function onUpdateMonth(value) {
  21837. if (viewMode.value === 'months') onClickMonth();
  21838. emit('update:month', value);
  21839. }
  21840. function onUpdateYear(value) {
  21841. if (viewMode.value === 'year') onClickYear();
  21842. emit('update:year', value);
  21843. }
  21844. watch(model, (val, oldVal) => {
  21845. const arrBefore = wrapInArray(oldVal);
  21846. const arrAfter = wrapInArray(val);
  21847. if (!arrAfter.length) return;
  21848. const before = adapter.date(arrBefore[arrBefore.length - 1]);
  21849. const after = adapter.date(arrAfter[arrAfter.length - 1]);
  21850. const newMonth = adapter.getMonth(after);
  21851. const newYear = adapter.getYear(after);
  21852. if (newMonth !== month.value) {
  21853. month.value = newMonth;
  21854. onUpdateMonth(month.value);
  21855. }
  21856. if (newYear !== year.value) {
  21857. year.value = newYear;
  21858. onUpdateYear(year.value);
  21859. }
  21860. isReversing.value = adapter.isBefore(before, after);
  21861. });
  21862. useRender(() => {
  21863. const pickerProps = VPicker.filterProps(props);
  21864. const datePickerControlsProps = VDatePickerControls.filterProps(props);
  21865. const datePickerHeaderProps = VDatePickerHeader.filterProps(props);
  21866. const datePickerMonthProps = VDatePickerMonth.filterProps(props);
  21867. const datePickerMonthsProps = omit(VDatePickerMonths.filterProps(props), ['modelValue']);
  21868. const datePickerYearsProps = omit(VDatePickerYears.filterProps(props), ['modelValue']);
  21869. const headerProps = {
  21870. header: header.value,
  21871. transition: headerTransition.value
  21872. };
  21873. return createVNode(VPicker, mergeProps(pickerProps, {
  21874. "class": ['v-date-picker', `v-date-picker--${viewMode.value}`, {
  21875. 'v-date-picker--show-week': props.showWeek
  21876. }, props.class],
  21877. "style": props.style
  21878. }), {
  21879. title: () => slots.title?.() ?? createVNode("div", {
  21880. "class": "v-date-picker__title"
  21881. }, [t(props.title)]),
  21882. header: () => slots.header ? createVNode(VDefaultsProvider, {
  21883. "defaults": {
  21884. VDatePickerHeader: {
  21885. ...headerProps
  21886. }
  21887. }
  21888. }, {
  21889. default: () => [slots.header?.(headerProps)]
  21890. }) : createVNode(VDatePickerHeader, mergeProps({
  21891. "key": "header"
  21892. }, datePickerHeaderProps, headerProps, {
  21893. "onClick": viewMode.value !== 'month' ? onClickDate : undefined
  21894. }), {
  21895. ...slots,
  21896. default: undefined
  21897. }),
  21898. default: () => createVNode(Fragment, null, [createVNode(VDatePickerControls, mergeProps(datePickerControlsProps, {
  21899. "disabled": disabled.value,
  21900. "text": text.value,
  21901. "onClick:next": onClickNext,
  21902. "onClick:prev": onClickPrev,
  21903. "onClick:month": onClickMonth,
  21904. "onClick:year": onClickYear
  21905. }), null), createVNode(VFadeTransition, {
  21906. "hideOnLeave": true
  21907. }, {
  21908. default: () => [viewMode.value === 'months' ? createVNode(VDatePickerMonths, mergeProps({
  21909. "key": "date-picker-months"
  21910. }, datePickerMonthsProps, {
  21911. "modelValue": month.value,
  21912. "onUpdate:modelValue": [$event => month.value = $event, onUpdateMonth],
  21913. "min": minDate.value,
  21914. "max": maxDate.value,
  21915. "year": year.value
  21916. }), null) : viewMode.value === 'year' ? createVNode(VDatePickerYears, mergeProps({
  21917. "key": "date-picker-years"
  21918. }, datePickerYearsProps, {
  21919. "modelValue": year.value,
  21920. "onUpdate:modelValue": [$event => year.value = $event, onUpdateYear],
  21921. "min": minDate.value,
  21922. "max": maxDate.value
  21923. }), null) : createVNode(VDatePickerMonth, mergeProps({
  21924. "key": "date-picker-month"
  21925. }, datePickerMonthProps, {
  21926. "modelValue": model.value,
  21927. "onUpdate:modelValue": $event => model.value = $event,
  21928. "month": month.value,
  21929. "onUpdate:month": [$event => month.value = $event, onUpdateMonth],
  21930. "year": year.value,
  21931. "onUpdate:year": [$event => year.value = $event, onUpdateYear],
  21932. "min": minDate.value,
  21933. "max": maxDate.value
  21934. }), null)]
  21935. })]),
  21936. actions: slots.actions
  21937. });
  21938. });
  21939. return {};
  21940. }
  21941. });
  21942. // Types
  21943. // Types
  21944. const makeVEmptyStateProps = propsFactory({
  21945. actionText: String,
  21946. bgColor: String,
  21947. color: String,
  21948. icon: IconValue,
  21949. image: String,
  21950. justify: {
  21951. type: String,
  21952. default: 'center'
  21953. },
  21954. headline: String,
  21955. title: String,
  21956. text: String,
  21957. textWidth: {
  21958. type: [Number, String],
  21959. default: 500
  21960. },
  21961. href: String,
  21962. to: String,
  21963. ...makeComponentProps(),
  21964. ...makeDimensionProps(),
  21965. ...makeSizeProps({
  21966. size: undefined
  21967. }),
  21968. ...makeThemeProps()
  21969. }, 'VEmptyState');
  21970. const VEmptyState = genericComponent()({
  21971. name: 'VEmptyState',
  21972. props: makeVEmptyStateProps(),
  21973. emits: {
  21974. 'click:action': e => true
  21975. },
  21976. setup(props, _ref) {
  21977. let {
  21978. emit,
  21979. slots
  21980. } = _ref;
  21981. const {
  21982. themeClasses
  21983. } = provideTheme(props);
  21984. const {
  21985. backgroundColorClasses,
  21986. backgroundColorStyles
  21987. } = useBackgroundColor(toRef(props, 'bgColor'));
  21988. const {
  21989. dimensionStyles
  21990. } = useDimension(props);
  21991. const {
  21992. displayClasses
  21993. } = useDisplay();
  21994. function onClickAction(e) {
  21995. emit('click:action', e);
  21996. }
  21997. useRender(() => {
  21998. const hasActions = !!(slots.actions || props.actionText);
  21999. const hasHeadline = !!(slots.headline || props.headline);
  22000. const hasTitle = !!(slots.title || props.title);
  22001. const hasText = !!(slots.text || props.text);
  22002. const hasMedia = !!(slots.media || props.image || props.icon);
  22003. const size = props.size || (props.image ? 200 : 96);
  22004. return createVNode("div", {
  22005. "class": ['v-empty-state', {
  22006. [`v-empty-state--${props.justify}`]: true
  22007. }, themeClasses.value, backgroundColorClasses.value, displayClasses.value, props.class],
  22008. "style": [backgroundColorStyles.value, dimensionStyles.value, props.style]
  22009. }, [hasMedia && createVNode("div", {
  22010. "key": "media",
  22011. "class": "v-empty-state__media"
  22012. }, [!slots.media ? createVNode(Fragment, null, [props.image ? createVNode(VImg, {
  22013. "key": "image",
  22014. "src": props.image,
  22015. "height": size
  22016. }, null) : props.icon ? createVNode(VIcon, {
  22017. "key": "icon",
  22018. "color": props.color,
  22019. "size": size,
  22020. "icon": props.icon
  22021. }, null) : undefined]) : createVNode(VDefaultsProvider, {
  22022. "key": "media-defaults",
  22023. "defaults": {
  22024. VImg: {
  22025. src: props.image,
  22026. height: size
  22027. },
  22028. VIcon: {
  22029. size,
  22030. icon: props.icon
  22031. }
  22032. }
  22033. }, {
  22034. default: () => [slots.media()]
  22035. })]), hasHeadline && createVNode("div", {
  22036. "key": "headline",
  22037. "class": "v-empty-state__headline"
  22038. }, [slots.headline?.() ?? props.headline]), hasTitle && createVNode("div", {
  22039. "key": "title",
  22040. "class": "v-empty-state__title"
  22041. }, [slots.title?.() ?? props.title]), hasText && createVNode("div", {
  22042. "key": "text",
  22043. "class": "v-empty-state__text",
  22044. "style": {
  22045. maxWidth: convertToUnit(props.textWidth)
  22046. }
  22047. }, [slots.text?.() ?? props.text]), slots.default && createVNode("div", {
  22048. "key": "content",
  22049. "class": "v-empty-state__content"
  22050. }, [slots.default()]), hasActions && createVNode("div", {
  22051. "key": "actions",
  22052. "class": "v-empty-state__actions"
  22053. }, [createVNode(VDefaultsProvider, {
  22054. "defaults": {
  22055. VBtn: {
  22056. class: 'v-empty-state__action-btn',
  22057. color: props.color ?? 'surface-variant',
  22058. text: props.actionText
  22059. }
  22060. }
  22061. }, {
  22062. default: () => [slots.actions?.({
  22063. props: {
  22064. onClick: onClickAction
  22065. }
  22066. }) ?? createVNode(VBtn, {
  22067. "onClick": onClickAction
  22068. }, null)]
  22069. })])]);
  22070. });
  22071. return {};
  22072. }
  22073. });
  22074. // Types
  22075. const VExpansionPanelSymbol = Symbol.for('vuetify:v-expansion-panel');
  22076. const makeVExpansionPanelTextProps = propsFactory({
  22077. ...makeComponentProps(),
  22078. ...makeLazyProps()
  22079. }, 'VExpansionPanelText');
  22080. const VExpansionPanelText = genericComponent()({
  22081. name: 'VExpansionPanelText',
  22082. props: makeVExpansionPanelTextProps(),
  22083. setup(props, _ref) {
  22084. let {
  22085. slots
  22086. } = _ref;
  22087. const expansionPanel = inject$1(VExpansionPanelSymbol);
  22088. if (!expansionPanel) throw new Error('[Vuetify] v-expansion-panel-text needs to be placed inside v-expansion-panel');
  22089. const {
  22090. hasContent,
  22091. onAfterLeave
  22092. } = useLazy(props, expansionPanel.isSelected);
  22093. useRender(() => createVNode(VExpandTransition, {
  22094. "onAfterLeave": onAfterLeave
  22095. }, {
  22096. default: () => [withDirectives(createVNode("div", {
  22097. "class": ['v-expansion-panel-text', props.class],
  22098. "style": props.style
  22099. }, [slots.default && hasContent.value && createVNode("div", {
  22100. "class": "v-expansion-panel-text__wrapper"
  22101. }, [slots.default?.()])]), [[vShow, expansionPanel.isSelected.value]])]
  22102. }));
  22103. return {};
  22104. }
  22105. });
  22106. // Types
  22107. const makeVExpansionPanelTitleProps = propsFactory({
  22108. color: String,
  22109. expandIcon: {
  22110. type: IconValue,
  22111. default: '$expand'
  22112. },
  22113. collapseIcon: {
  22114. type: IconValue,
  22115. default: '$collapse'
  22116. },
  22117. hideActions: Boolean,
  22118. focusable: Boolean,
  22119. static: Boolean,
  22120. ripple: {
  22121. type: [Boolean, Object],
  22122. default: false
  22123. },
  22124. readonly: Boolean,
  22125. ...makeComponentProps(),
  22126. ...makeDimensionProps()
  22127. }, 'VExpansionPanelTitle');
  22128. const VExpansionPanelTitle = genericComponent()({
  22129. name: 'VExpansionPanelTitle',
  22130. directives: {
  22131. Ripple
  22132. },
  22133. props: makeVExpansionPanelTitleProps(),
  22134. setup(props, _ref) {
  22135. let {
  22136. slots
  22137. } = _ref;
  22138. const expansionPanel = inject$1(VExpansionPanelSymbol);
  22139. if (!expansionPanel) throw new Error('[Vuetify] v-expansion-panel-title needs to be placed inside v-expansion-panel');
  22140. const {
  22141. backgroundColorClasses,
  22142. backgroundColorStyles
  22143. } = useBackgroundColor(props, 'color');
  22144. const {
  22145. dimensionStyles
  22146. } = useDimension(props);
  22147. const slotProps = computed(() => ({
  22148. collapseIcon: props.collapseIcon,
  22149. disabled: expansionPanel.disabled.value,
  22150. expanded: expansionPanel.isSelected.value,
  22151. expandIcon: props.expandIcon,
  22152. readonly: props.readonly
  22153. }));
  22154. const icon = computed(() => expansionPanel.isSelected.value ? props.collapseIcon : props.expandIcon);
  22155. useRender(() => withDirectives(createVNode("button", {
  22156. "class": ['v-expansion-panel-title', {
  22157. 'v-expansion-panel-title--active': expansionPanel.isSelected.value,
  22158. 'v-expansion-panel-title--focusable': props.focusable,
  22159. 'v-expansion-panel-title--static': props.static
  22160. }, backgroundColorClasses.value, props.class],
  22161. "style": [backgroundColorStyles.value, dimensionStyles.value, props.style],
  22162. "type": "button",
  22163. "tabindex": expansionPanel.disabled.value ? -1 : undefined,
  22164. "disabled": expansionPanel.disabled.value,
  22165. "aria-expanded": expansionPanel.isSelected.value,
  22166. "onClick": !props.readonly ? expansionPanel.toggle : undefined
  22167. }, [createVNode("span", {
  22168. "class": "v-expansion-panel-title__overlay"
  22169. }, null), slots.default?.(slotProps.value), !props.hideActions && createVNode(VDefaultsProvider, {
  22170. "defaults": {
  22171. VIcon: {
  22172. icon: icon.value
  22173. }
  22174. }
  22175. }, {
  22176. default: () => [createVNode("span", {
  22177. "class": "v-expansion-panel-title__icon"
  22178. }, [slots.actions?.(slotProps.value) ?? createVNode(VIcon, null, null)])]
  22179. })]), [[resolveDirective("ripple"), props.ripple]]));
  22180. return {};
  22181. }
  22182. });
  22183. const makeVExpansionPanelProps = propsFactory({
  22184. title: String,
  22185. text: String,
  22186. bgColor: String,
  22187. ...makeElevationProps(),
  22188. ...makeGroupItemProps(),
  22189. ...makeRoundedProps(),
  22190. ...makeTagProps(),
  22191. ...makeVExpansionPanelTitleProps(),
  22192. ...makeVExpansionPanelTextProps()
  22193. }, 'VExpansionPanel');
  22194. const VExpansionPanel = genericComponent()({
  22195. name: 'VExpansionPanel',
  22196. props: makeVExpansionPanelProps(),
  22197. emits: {
  22198. 'group:selected': val => true
  22199. },
  22200. setup(props, _ref) {
  22201. let {
  22202. slots
  22203. } = _ref;
  22204. const groupItem = useGroupItem(props, VExpansionPanelSymbol);
  22205. const {
  22206. backgroundColorClasses,
  22207. backgroundColorStyles
  22208. } = useBackgroundColor(props, 'bgColor');
  22209. const {
  22210. elevationClasses
  22211. } = useElevation(props);
  22212. const {
  22213. roundedClasses
  22214. } = useRounded(props);
  22215. const isDisabled = computed(() => groupItem?.disabled.value || props.disabled);
  22216. const selectedIndices = computed(() => groupItem.group.items.value.reduce((arr, item, index) => {
  22217. if (groupItem.group.selected.value.includes(item.id)) arr.push(index);
  22218. return arr;
  22219. }, []));
  22220. const isBeforeSelected = computed(() => {
  22221. const index = groupItem.group.items.value.findIndex(item => item.id === groupItem.id);
  22222. return !groupItem.isSelected.value && selectedIndices.value.some(selectedIndex => selectedIndex - index === 1);
  22223. });
  22224. const isAfterSelected = computed(() => {
  22225. const index = groupItem.group.items.value.findIndex(item => item.id === groupItem.id);
  22226. return !groupItem.isSelected.value && selectedIndices.value.some(selectedIndex => selectedIndex - index === -1);
  22227. });
  22228. provide(VExpansionPanelSymbol, groupItem);
  22229. useRender(() => {
  22230. const hasText = !!(slots.text || props.text);
  22231. const hasTitle = !!(slots.title || props.title);
  22232. const expansionPanelTitleProps = VExpansionPanelTitle.filterProps(props);
  22233. const expansionPanelTextProps = VExpansionPanelText.filterProps(props);
  22234. return createVNode(props.tag, {
  22235. "class": ['v-expansion-panel', {
  22236. 'v-expansion-panel--active': groupItem.isSelected.value,
  22237. 'v-expansion-panel--before-active': isBeforeSelected.value,
  22238. 'v-expansion-panel--after-active': isAfterSelected.value,
  22239. 'v-expansion-panel--disabled': isDisabled.value
  22240. }, roundedClasses.value, backgroundColorClasses.value, props.class],
  22241. "style": [backgroundColorStyles.value, props.style]
  22242. }, {
  22243. default: () => [createVNode("div", {
  22244. "class": ['v-expansion-panel__shadow', ...elevationClasses.value]
  22245. }, null), createVNode(VDefaultsProvider, {
  22246. "defaults": {
  22247. VExpansionPanelTitle: {
  22248. ...expansionPanelTitleProps
  22249. },
  22250. VExpansionPanelText: {
  22251. ...expansionPanelTextProps
  22252. }
  22253. }
  22254. }, {
  22255. default: () => [hasTitle && createVNode(VExpansionPanelTitle, {
  22256. "key": "title"
  22257. }, {
  22258. default: () => [slots.title ? slots.title() : props.title]
  22259. }), hasText && createVNode(VExpansionPanelText, {
  22260. "key": "text"
  22261. }, {
  22262. default: () => [slots.text ? slots.text() : props.text]
  22263. }), slots.default?.()]
  22264. })]
  22265. });
  22266. });
  22267. return {
  22268. groupItem
  22269. };
  22270. }
  22271. });
  22272. // Types
  22273. const allowedVariants = ['default', 'accordion', 'inset', 'popout'];
  22274. const makeVExpansionPanelsProps = propsFactory({
  22275. flat: Boolean,
  22276. ...makeGroupProps(),
  22277. ...pick(makeVExpansionPanelProps(), ['bgColor', 'collapseIcon', 'color', 'eager', 'elevation', 'expandIcon', 'focusable', 'hideActions', 'readonly', 'ripple', 'rounded', 'tile', 'static']),
  22278. ...makeThemeProps(),
  22279. ...makeComponentProps(),
  22280. ...makeTagProps(),
  22281. variant: {
  22282. type: String,
  22283. default: 'default',
  22284. validator: v => allowedVariants.includes(v)
  22285. }
  22286. }, 'VExpansionPanels');
  22287. const VExpansionPanels = genericComponent()({
  22288. name: 'VExpansionPanels',
  22289. props: makeVExpansionPanelsProps(),
  22290. emits: {
  22291. 'update:modelValue': val => true
  22292. },
  22293. setup(props, _ref) {
  22294. let {
  22295. slots
  22296. } = _ref;
  22297. const {
  22298. next,
  22299. prev
  22300. } = useGroup(props, VExpansionPanelSymbol);
  22301. const {
  22302. themeClasses
  22303. } = provideTheme(props);
  22304. const variantClass = computed(() => props.variant && `v-expansion-panels--variant-${props.variant}`);
  22305. provideDefaults({
  22306. VExpansionPanel: {
  22307. bgColor: toRef(props, 'bgColor'),
  22308. collapseIcon: toRef(props, 'collapseIcon'),
  22309. color: toRef(props, 'color'),
  22310. eager: toRef(props, 'eager'),
  22311. elevation: toRef(props, 'elevation'),
  22312. expandIcon: toRef(props, 'expandIcon'),
  22313. focusable: toRef(props, 'focusable'),
  22314. hideActions: toRef(props, 'hideActions'),
  22315. readonly: toRef(props, 'readonly'),
  22316. ripple: toRef(props, 'ripple'),
  22317. rounded: toRef(props, 'rounded'),
  22318. static: toRef(props, 'static')
  22319. }
  22320. });
  22321. useRender(() => createVNode(props.tag, {
  22322. "class": ['v-expansion-panels', {
  22323. 'v-expansion-panels--flat': props.flat,
  22324. 'v-expansion-panels--tile': props.tile
  22325. }, themeClasses.value, variantClass.value, props.class],
  22326. "style": props.style
  22327. }, {
  22328. default: () => [slots.default?.({
  22329. prev,
  22330. next
  22331. })]
  22332. }));
  22333. return {
  22334. next,
  22335. prev
  22336. };
  22337. }
  22338. });
  22339. // Types
  22340. const makeVFabProps = propsFactory({
  22341. app: Boolean,
  22342. appear: Boolean,
  22343. extended: Boolean,
  22344. layout: Boolean,
  22345. offset: Boolean,
  22346. modelValue: {
  22347. type: Boolean,
  22348. default: true
  22349. },
  22350. ...omit(makeVBtnProps({
  22351. active: true
  22352. }), ['location']),
  22353. ...makeLayoutItemProps(),
  22354. ...makeLocationProps(),
  22355. ...makeTransitionProps({
  22356. transition: 'fab-transition'
  22357. })
  22358. }, 'VFab');
  22359. const VFab = genericComponent()({
  22360. name: 'VFab',
  22361. props: makeVFabProps(),
  22362. emits: {
  22363. 'update:modelValue': value => true
  22364. },
  22365. setup(props, _ref) {
  22366. let {
  22367. slots
  22368. } = _ref;
  22369. const model = useProxiedModel(props, 'modelValue');
  22370. const height = shallowRef(56);
  22371. const layoutItemStyles = ref();
  22372. const {
  22373. resizeRef
  22374. } = useResizeObserver(entries => {
  22375. if (!entries.length) return;
  22376. height.value = entries[0].target.clientHeight;
  22377. });
  22378. const hasPosition = computed(() => props.app || props.absolute);
  22379. const position = computed(() => {
  22380. if (!hasPosition.value) return false;
  22381. return props.location?.split(' ').shift() ?? 'bottom';
  22382. });
  22383. const orientation = computed(() => {
  22384. if (!hasPosition.value) return false;
  22385. return props.location?.split(' ')[1] ?? 'end';
  22386. });
  22387. useToggleScope(() => props.app, () => {
  22388. const layout = useLayoutItem({
  22389. id: props.name,
  22390. order: computed(() => parseInt(props.order, 10)),
  22391. position,
  22392. layoutSize: computed(() => props.layout ? height.value + 24 : 0),
  22393. elementSize: computed(() => height.value + 24),
  22394. active: computed(() => props.app && model.value),
  22395. absolute: toRef(props, 'absolute')
  22396. });
  22397. watchEffect(() => {
  22398. layoutItemStyles.value = layout.layoutItemStyles.value;
  22399. });
  22400. });
  22401. const vFabRef = ref();
  22402. useRender(() => {
  22403. const btnProps = VBtn.filterProps(props);
  22404. return createVNode("div", {
  22405. "ref": vFabRef,
  22406. "class": ['v-fab', {
  22407. 'v-fab--absolute': props.absolute,
  22408. 'v-fab--app': !!props.app,
  22409. 'v-fab--extended': props.extended,
  22410. 'v-fab--offset': props.offset,
  22411. [`v-fab--${position.value}`]: hasPosition.value,
  22412. [`v-fab--${orientation.value}`]: hasPosition.value
  22413. }, props.class],
  22414. "style": [props.app ? {
  22415. ...layoutItemStyles.value
  22416. } : {
  22417. height: 'inherit',
  22418. width: undefined
  22419. }, props.style]
  22420. }, [createVNode("div", {
  22421. "class": "v-fab__container"
  22422. }, [createVNode(MaybeTransition, {
  22423. "appear": props.appear,
  22424. "transition": props.transition
  22425. }, {
  22426. default: () => [withDirectives(createVNode(VBtn, mergeProps({
  22427. "ref": resizeRef
  22428. }, btnProps, {
  22429. "active": undefined,
  22430. "location": undefined
  22431. }), slots), [[vShow, props.active]])]
  22432. })])]);
  22433. });
  22434. return {};
  22435. }
  22436. });
  22437. // Types
  22438. const makeVFileInputProps = propsFactory({
  22439. chips: Boolean,
  22440. counter: Boolean,
  22441. counterSizeString: {
  22442. type: String,
  22443. default: '$vuetify.fileInput.counterSize'
  22444. },
  22445. counterString: {
  22446. type: String,
  22447. default: '$vuetify.fileInput.counter'
  22448. },
  22449. hideInput: Boolean,
  22450. multiple: Boolean,
  22451. showSize: {
  22452. type: [Boolean, Number, String],
  22453. default: false,
  22454. validator: v => {
  22455. return typeof v === 'boolean' || [1000, 1024].includes(Number(v));
  22456. }
  22457. },
  22458. ...makeVInputProps({
  22459. prependIcon: '$file'
  22460. }),
  22461. modelValue: {
  22462. type: [Array, Object],
  22463. default: props => props.multiple ? [] : null,
  22464. validator: val => {
  22465. return wrapInArray(val).every(v => v != null && typeof v === 'object');
  22466. }
  22467. },
  22468. ...makeVFieldProps({
  22469. clearable: true
  22470. })
  22471. }, 'VFileInput');
  22472. const VFileInput = genericComponent()({
  22473. name: 'VFileInput',
  22474. inheritAttrs: false,
  22475. props: makeVFileInputProps(),
  22476. emits: {
  22477. 'click:control': e => true,
  22478. 'mousedown:control': e => true,
  22479. 'update:focused': focused => true,
  22480. 'update:modelValue': files => true
  22481. },
  22482. setup(props, _ref) {
  22483. let {
  22484. attrs,
  22485. emit,
  22486. slots
  22487. } = _ref;
  22488. const {
  22489. t
  22490. } = useLocale();
  22491. const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => !props.multiple && Array.isArray(val) ? val[0] : val);
  22492. const {
  22493. isFocused,
  22494. focus,
  22495. blur
  22496. } = useFocus(props);
  22497. const base = computed(() => typeof props.showSize !== 'boolean' ? props.showSize : undefined);
  22498. const totalBytes = computed(() => (model.value ?? []).reduce((bytes, _ref2) => {
  22499. let {
  22500. size = 0
  22501. } = _ref2;
  22502. return bytes + size;
  22503. }, 0));
  22504. const totalBytesReadable = computed(() => humanReadableFileSize(totalBytes.value, base.value));
  22505. const fileNames = computed(() => (model.value ?? []).map(file => {
  22506. const {
  22507. name = '',
  22508. size = 0
  22509. } = file;
  22510. return !props.showSize ? name : `${name} (${humanReadableFileSize(size, base.value)})`;
  22511. }));
  22512. const counterValue = computed(() => {
  22513. const fileCount = model.value?.length ?? 0;
  22514. if (props.showSize) return t(props.counterSizeString, fileCount, totalBytesReadable.value);else return t(props.counterString, fileCount);
  22515. });
  22516. const vInputRef = ref();
  22517. const vFieldRef = ref();
  22518. const inputRef = ref();
  22519. const isActive = computed(() => isFocused.value || props.active);
  22520. const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant));
  22521. function onFocus() {
  22522. if (inputRef.value !== document.activeElement) {
  22523. inputRef.value?.focus();
  22524. }
  22525. if (!isFocused.value) focus();
  22526. }
  22527. function onClickPrepend(e) {
  22528. inputRef.value?.click();
  22529. }
  22530. function onControlMousedown(e) {
  22531. emit('mousedown:control', e);
  22532. }
  22533. function onControlClick(e) {
  22534. inputRef.value?.click();
  22535. emit('click:control', e);
  22536. }
  22537. function onClear(e) {
  22538. e.stopPropagation();
  22539. onFocus();
  22540. nextTick(() => {
  22541. model.value = [];
  22542. callEvent(props['onClick:clear'], e);
  22543. });
  22544. }
  22545. watch(model, newValue => {
  22546. const hasModelReset = !Array.isArray(newValue) || !newValue.length;
  22547. if (hasModelReset && inputRef.value) {
  22548. inputRef.value.value = '';
  22549. }
  22550. });
  22551. useRender(() => {
  22552. const hasCounter = !!(slots.counter || props.counter);
  22553. const hasDetails = !!(hasCounter || slots.details);
  22554. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  22555. const {
  22556. modelValue: _,
  22557. ...inputProps
  22558. } = VInput.filterProps(props);
  22559. const fieldProps = filterFieldProps(props);
  22560. return createVNode(VInput, mergeProps({
  22561. "ref": vInputRef,
  22562. "modelValue": model.value,
  22563. "onUpdate:modelValue": $event => model.value = $event,
  22564. "class": ['v-file-input', {
  22565. 'v-file-input--chips': !!props.chips,
  22566. 'v-file-input--hide': props.hideInput,
  22567. 'v-input--plain-underlined': isPlainOrUnderlined.value
  22568. }, props.class],
  22569. "style": props.style,
  22570. "onClick:prepend": onClickPrepend
  22571. }, rootAttrs, inputProps, {
  22572. "centerAffix": !isPlainOrUnderlined.value,
  22573. "focused": isFocused.value
  22574. }), {
  22575. ...slots,
  22576. default: _ref3 => {
  22577. let {
  22578. id,
  22579. isDisabled,
  22580. isDirty,
  22581. isReadonly,
  22582. isValid
  22583. } = _ref3;
  22584. return createVNode(VField, mergeProps({
  22585. "ref": vFieldRef,
  22586. "prepend-icon": props.prependIcon,
  22587. "onMousedown": onControlMousedown,
  22588. "onClick": onControlClick,
  22589. "onClick:clear": onClear,
  22590. "onClick:prependInner": props['onClick:prependInner'],
  22591. "onClick:appendInner": props['onClick:appendInner']
  22592. }, fieldProps, {
  22593. "id": id.value,
  22594. "active": isActive.value || isDirty.value,
  22595. "dirty": isDirty.value || props.dirty,
  22596. "disabled": isDisabled.value,
  22597. "focused": isFocused.value,
  22598. "error": isValid.value === false
  22599. }), {
  22600. ...slots,
  22601. default: _ref4 => {
  22602. let {
  22603. props: {
  22604. class: fieldClass,
  22605. ...slotProps
  22606. }
  22607. } = _ref4;
  22608. return createVNode(Fragment, null, [createVNode("input", mergeProps({
  22609. "ref": inputRef,
  22610. "type": "file",
  22611. "readonly": isReadonly.value,
  22612. "disabled": isDisabled.value,
  22613. "multiple": props.multiple,
  22614. "name": props.name,
  22615. "onClick": e => {
  22616. e.stopPropagation();
  22617. if (isReadonly.value) e.preventDefault();
  22618. onFocus();
  22619. },
  22620. "onChange": e => {
  22621. if (!e.target) return;
  22622. const target = e.target;
  22623. model.value = [...(target.files ?? [])];
  22624. },
  22625. "onFocus": onFocus,
  22626. "onBlur": blur
  22627. }, slotProps, inputAttrs), null), createVNode("div", {
  22628. "class": fieldClass
  22629. }, [!!model.value?.length && !props.hideInput && (slots.selection ? slots.selection({
  22630. fileNames: fileNames.value,
  22631. totalBytes: totalBytes.value,
  22632. totalBytesReadable: totalBytesReadable.value
  22633. }) : props.chips ? fileNames.value.map(text => createVNode(VChip, {
  22634. "key": text,
  22635. "size": "small",
  22636. "text": text
  22637. }, null)) : fileNames.value.join(', '))])]);
  22638. }
  22639. });
  22640. },
  22641. details: hasDetails ? slotProps => createVNode(Fragment, null, [slots.details?.(slotProps), hasCounter && createVNode(Fragment, null, [createVNode("span", null, null), createVNode(VCounter, {
  22642. "active": !!model.value?.length,
  22643. "value": counterValue.value,
  22644. "disabled": props.disabled
  22645. }, slots.counter)])]) : undefined
  22646. });
  22647. });
  22648. return forwardRefs({}, vInputRef, vFieldRef, inputRef);
  22649. }
  22650. });
  22651. const makeVFooterProps = propsFactory({
  22652. app: Boolean,
  22653. color: String,
  22654. height: {
  22655. type: [Number, String],
  22656. default: 'auto'
  22657. },
  22658. ...makeBorderProps(),
  22659. ...makeComponentProps(),
  22660. ...makeElevationProps(),
  22661. ...makeLayoutItemProps(),
  22662. ...makeRoundedProps(),
  22663. ...makeTagProps({
  22664. tag: 'footer'
  22665. }),
  22666. ...makeThemeProps()
  22667. }, 'VFooter');
  22668. const VFooter = genericComponent()({
  22669. name: 'VFooter',
  22670. props: makeVFooterProps(),
  22671. setup(props, _ref) {
  22672. let {
  22673. slots
  22674. } = _ref;
  22675. const layoutItemStyles = ref();
  22676. const {
  22677. themeClasses
  22678. } = provideTheme(props);
  22679. const {
  22680. backgroundColorClasses,
  22681. backgroundColorStyles
  22682. } = useBackgroundColor(toRef(props, 'color'));
  22683. const {
  22684. borderClasses
  22685. } = useBorder(props);
  22686. const {
  22687. elevationClasses
  22688. } = useElevation(props);
  22689. const {
  22690. roundedClasses
  22691. } = useRounded(props);
  22692. const autoHeight = shallowRef(32);
  22693. const {
  22694. resizeRef
  22695. } = useResizeObserver(entries => {
  22696. if (!entries.length) return;
  22697. autoHeight.value = entries[0].target.clientHeight;
  22698. });
  22699. const height = computed(() => props.height === 'auto' ? autoHeight.value : parseInt(props.height, 10));
  22700. useToggleScope(() => props.app, () => {
  22701. const layout = useLayoutItem({
  22702. id: props.name,
  22703. order: computed(() => parseInt(props.order, 10)),
  22704. position: computed(() => 'bottom'),
  22705. layoutSize: height,
  22706. elementSize: computed(() => props.height === 'auto' ? undefined : height.value),
  22707. active: computed(() => props.app),
  22708. absolute: toRef(props, 'absolute')
  22709. });
  22710. watchEffect(() => {
  22711. layoutItemStyles.value = layout.layoutItemStyles.value;
  22712. });
  22713. });
  22714. useRender(() => createVNode(props.tag, {
  22715. "ref": resizeRef,
  22716. "class": ['v-footer', themeClasses.value, backgroundColorClasses.value, borderClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  22717. "style": [backgroundColorStyles.value, props.app ? layoutItemStyles.value : {
  22718. height: convertToUnit(props.height)
  22719. }, props.style]
  22720. }, slots));
  22721. return {};
  22722. }
  22723. });
  22724. // Types
  22725. const makeVFormProps = propsFactory({
  22726. ...makeComponentProps(),
  22727. ...makeFormProps()
  22728. }, 'VForm');
  22729. const VForm = genericComponent()({
  22730. name: 'VForm',
  22731. props: makeVFormProps(),
  22732. emits: {
  22733. 'update:modelValue': val => true,
  22734. submit: e => true
  22735. },
  22736. setup(props, _ref) {
  22737. let {
  22738. slots,
  22739. emit
  22740. } = _ref;
  22741. const form = createForm(props);
  22742. const formRef = ref();
  22743. function onReset(e) {
  22744. e.preventDefault();
  22745. form.reset();
  22746. }
  22747. function onSubmit(_e) {
  22748. const e = _e;
  22749. const ready = form.validate();
  22750. e.then = ready.then.bind(ready);
  22751. e.catch = ready.catch.bind(ready);
  22752. e.finally = ready.finally.bind(ready);
  22753. emit('submit', e);
  22754. if (!e.defaultPrevented) {
  22755. ready.then(_ref2 => {
  22756. let {
  22757. valid
  22758. } = _ref2;
  22759. if (valid) {
  22760. formRef.value?.submit();
  22761. }
  22762. });
  22763. }
  22764. e.preventDefault();
  22765. }
  22766. useRender(() => createVNode("form", {
  22767. "ref": formRef,
  22768. "class": ['v-form', props.class],
  22769. "style": props.style,
  22770. "novalidate": true,
  22771. "onReset": onReset,
  22772. "onSubmit": onSubmit
  22773. }, [slots.default?.(form)]));
  22774. return forwardRefs(form, formRef);
  22775. }
  22776. });
  22777. // Composables
  22778. const makeVHoverProps = propsFactory({
  22779. disabled: Boolean,
  22780. modelValue: {
  22781. type: Boolean,
  22782. default: null
  22783. },
  22784. ...makeDelayProps()
  22785. }, 'VHover');
  22786. const VHover = genericComponent()({
  22787. name: 'VHover',
  22788. props: makeVHoverProps(),
  22789. emits: {
  22790. 'update:modelValue': value => true
  22791. },
  22792. setup(props, _ref) {
  22793. let {
  22794. slots
  22795. } = _ref;
  22796. const isHovering = useProxiedModel(props, 'modelValue');
  22797. const {
  22798. runOpenDelay,
  22799. runCloseDelay
  22800. } = useDelay(props, value => !props.disabled && (isHovering.value = value));
  22801. return () => slots.default?.({
  22802. isHovering: isHovering.value,
  22803. props: {
  22804. onMouseenter: runOpenDelay,
  22805. onMouseleave: runCloseDelay
  22806. }
  22807. });
  22808. }
  22809. });
  22810. // Types
  22811. const makeVInfiniteScrollProps = propsFactory({
  22812. color: String,
  22813. direction: {
  22814. type: String,
  22815. default: 'vertical',
  22816. validator: v => ['vertical', 'horizontal'].includes(v)
  22817. },
  22818. side: {
  22819. type: String,
  22820. default: 'end',
  22821. validator: v => ['start', 'end', 'both'].includes(v)
  22822. },
  22823. mode: {
  22824. type: String,
  22825. default: 'intersect',
  22826. validator: v => ['intersect', 'manual'].includes(v)
  22827. },
  22828. margin: [Number, String],
  22829. loadMoreText: {
  22830. type: String,
  22831. default: '$vuetify.infiniteScroll.loadMore'
  22832. },
  22833. emptyText: {
  22834. type: String,
  22835. default: '$vuetify.infiniteScroll.empty'
  22836. },
  22837. ...makeDimensionProps(),
  22838. ...makeTagProps()
  22839. }, 'VInfiniteScroll');
  22840. const VInfiniteScrollIntersect = defineComponent({
  22841. name: 'VInfiniteScrollIntersect',
  22842. props: {
  22843. side: {
  22844. type: String,
  22845. required: true
  22846. },
  22847. rootMargin: String
  22848. },
  22849. emits: {
  22850. intersect: (side, isIntersecting) => true
  22851. },
  22852. setup(props, _ref) {
  22853. let {
  22854. emit
  22855. } = _ref;
  22856. const {
  22857. intersectionRef,
  22858. isIntersecting
  22859. } = useIntersectionObserver();
  22860. watch(isIntersecting, async val => {
  22861. emit('intersect', props.side, val);
  22862. });
  22863. useRender(() => createVNode("div", {
  22864. "class": "v-infinite-scroll-intersect",
  22865. "style": {
  22866. '--v-infinite-margin-size': props.rootMargin
  22867. },
  22868. "ref": intersectionRef
  22869. }, [createTextVNode("\xA0")]));
  22870. return {};
  22871. }
  22872. });
  22873. const VInfiniteScroll = genericComponent()({
  22874. name: 'VInfiniteScroll',
  22875. props: makeVInfiniteScrollProps(),
  22876. emits: {
  22877. load: options => true
  22878. },
  22879. setup(props, _ref2) {
  22880. let {
  22881. slots,
  22882. emit
  22883. } = _ref2;
  22884. const rootEl = ref();
  22885. const startStatus = shallowRef('ok');
  22886. const endStatus = shallowRef('ok');
  22887. const margin = computed(() => convertToUnit(props.margin));
  22888. const isIntersecting = shallowRef(false);
  22889. function setScrollAmount(amount) {
  22890. if (!rootEl.value) return;
  22891. const property = props.direction === 'vertical' ? 'scrollTop' : 'scrollLeft';
  22892. rootEl.value[property] = amount;
  22893. }
  22894. function getScrollAmount() {
  22895. if (!rootEl.value) return 0;
  22896. const property = props.direction === 'vertical' ? 'scrollTop' : 'scrollLeft';
  22897. return rootEl.value[property];
  22898. }
  22899. function getScrollSize() {
  22900. if (!rootEl.value) return 0;
  22901. const property = props.direction === 'vertical' ? 'scrollHeight' : 'scrollWidth';
  22902. return rootEl.value[property];
  22903. }
  22904. function getContainerSize() {
  22905. if (!rootEl.value) return 0;
  22906. const property = props.direction === 'vertical' ? 'clientHeight' : 'clientWidth';
  22907. return rootEl.value[property];
  22908. }
  22909. onMounted(() => {
  22910. if (!rootEl.value) return;
  22911. if (props.side === 'start') {
  22912. setScrollAmount(getScrollSize());
  22913. } else if (props.side === 'both') {
  22914. setScrollAmount(getScrollSize() / 2 - getContainerSize() / 2);
  22915. }
  22916. });
  22917. function setStatus(side, status) {
  22918. if (side === 'start') {
  22919. startStatus.value = status;
  22920. } else if (side === 'end') {
  22921. endStatus.value = status;
  22922. }
  22923. }
  22924. function getStatus(side) {
  22925. return side === 'start' ? startStatus.value : endStatus.value;
  22926. }
  22927. let previousScrollSize = 0;
  22928. function handleIntersect(side, _isIntersecting) {
  22929. isIntersecting.value = _isIntersecting;
  22930. if (isIntersecting.value) {
  22931. intersecting(side);
  22932. }
  22933. }
  22934. function intersecting(side) {
  22935. if (props.mode !== 'manual' && !isIntersecting.value) return;
  22936. const status = getStatus(side);
  22937. if (!rootEl.value || ['empty', 'loading'].includes(status)) return;
  22938. previousScrollSize = getScrollSize();
  22939. setStatus(side, 'loading');
  22940. function done(status) {
  22941. setStatus(side, status);
  22942. nextTick(() => {
  22943. if (status === 'empty' || status === 'error') return;
  22944. if (status === 'ok' && side === 'start') {
  22945. setScrollAmount(getScrollSize() - previousScrollSize + getScrollAmount());
  22946. }
  22947. if (props.mode !== 'manual') {
  22948. nextTick(() => {
  22949. window.requestAnimationFrame(() => {
  22950. window.requestAnimationFrame(() => {
  22951. window.requestAnimationFrame(() => {
  22952. intersecting(side);
  22953. });
  22954. });
  22955. });
  22956. });
  22957. }
  22958. });
  22959. }
  22960. emit('load', {
  22961. side,
  22962. done
  22963. });
  22964. }
  22965. const {
  22966. t
  22967. } = useLocale();
  22968. function renderSide(side, status) {
  22969. if (props.side !== side && props.side !== 'both') return;
  22970. const onClick = () => intersecting(side);
  22971. const slotProps = {
  22972. side,
  22973. props: {
  22974. onClick,
  22975. color: props.color
  22976. }
  22977. };
  22978. if (status === 'error') return slots.error?.(slotProps);
  22979. if (status === 'empty') return slots.empty?.(slotProps) ?? createVNode("div", null, [t(props.emptyText)]);
  22980. if (props.mode === 'manual') {
  22981. if (status === 'loading') {
  22982. return slots.loading?.(slotProps) ?? createVNode(VProgressCircular, {
  22983. "indeterminate": true,
  22984. "color": props.color
  22985. }, null);
  22986. }
  22987. return slots['load-more']?.(slotProps) ?? createVNode(VBtn, {
  22988. "variant": "outlined",
  22989. "color": props.color,
  22990. "onClick": onClick
  22991. }, {
  22992. default: () => [t(props.loadMoreText)]
  22993. });
  22994. }
  22995. return slots.loading?.(slotProps) ?? createVNode(VProgressCircular, {
  22996. "indeterminate": true,
  22997. "color": props.color
  22998. }, null);
  22999. }
  23000. const {
  23001. dimensionStyles
  23002. } = useDimension(props);
  23003. useRender(() => {
  23004. const Tag = props.tag;
  23005. const hasStartIntersect = props.side === 'start' || props.side === 'both';
  23006. const hasEndIntersect = props.side === 'end' || props.side === 'both';
  23007. const intersectMode = props.mode === 'intersect';
  23008. return createVNode(Tag, {
  23009. "ref": rootEl,
  23010. "class": ['v-infinite-scroll', `v-infinite-scroll--${props.direction}`, {
  23011. 'v-infinite-scroll--start': hasStartIntersect,
  23012. 'v-infinite-scroll--end': hasEndIntersect
  23013. }],
  23014. "style": dimensionStyles.value
  23015. }, {
  23016. default: () => [createVNode("div", {
  23017. "class": "v-infinite-scroll__side"
  23018. }, [renderSide('start', startStatus.value)]), hasStartIntersect && intersectMode && createVNode(VInfiniteScrollIntersect, {
  23019. "key": "start",
  23020. "side": "start",
  23021. "onIntersect": handleIntersect,
  23022. "rootMargin": margin.value
  23023. }, null), slots.default?.(), hasEndIntersect && intersectMode && createVNode(VInfiniteScrollIntersect, {
  23024. "key": "end",
  23025. "side": "end",
  23026. "onIntersect": handleIntersect,
  23027. "rootMargin": margin.value
  23028. }, null), createVNode("div", {
  23029. "class": "v-infinite-scroll__side"
  23030. }, [renderSide('end', endStatus.value)])]
  23031. });
  23032. });
  23033. }
  23034. });
  23035. // Types
  23036. const VItemGroupSymbol = Symbol.for('vuetify:v-item-group');
  23037. const makeVItemGroupProps = propsFactory({
  23038. ...makeComponentProps(),
  23039. ...makeGroupProps({
  23040. selectedClass: 'v-item--selected'
  23041. }),
  23042. ...makeTagProps(),
  23043. ...makeThemeProps()
  23044. }, 'VItemGroup');
  23045. const VItemGroup = genericComponent()({
  23046. name: 'VItemGroup',
  23047. props: makeVItemGroupProps(),
  23048. emits: {
  23049. 'update:modelValue': value => true
  23050. },
  23051. setup(props, _ref) {
  23052. let {
  23053. slots
  23054. } = _ref;
  23055. const {
  23056. themeClasses
  23057. } = provideTheme(props);
  23058. const {
  23059. isSelected,
  23060. select,
  23061. next,
  23062. prev,
  23063. selected
  23064. } = useGroup(props, VItemGroupSymbol);
  23065. return () => createVNode(props.tag, {
  23066. "class": ['v-item-group', themeClasses.value, props.class],
  23067. "style": props.style
  23068. }, {
  23069. default: () => [slots.default?.({
  23070. isSelected,
  23071. select,
  23072. next,
  23073. prev,
  23074. selected: selected.value
  23075. })]
  23076. });
  23077. }
  23078. });
  23079. // Composables
  23080. const VItem = genericComponent()({
  23081. name: 'VItem',
  23082. props: makeGroupItemProps(),
  23083. emits: {
  23084. 'group:selected': val => true
  23085. },
  23086. setup(props, _ref) {
  23087. let {
  23088. slots
  23089. } = _ref;
  23090. const {
  23091. isSelected,
  23092. select,
  23093. toggle,
  23094. selectedClass,
  23095. value,
  23096. disabled
  23097. } = useGroupItem(props, VItemGroupSymbol);
  23098. return () => slots.default?.({
  23099. isSelected: isSelected.value,
  23100. selectedClass: selectedClass.value,
  23101. select,
  23102. toggle,
  23103. value: value.value,
  23104. disabled: disabled.value
  23105. });
  23106. }
  23107. });
  23108. // Styles
  23109. const VKbd = createSimpleFunctional('v-kbd', 'kbd');
  23110. const makeVLayoutProps = propsFactory({
  23111. ...makeComponentProps(),
  23112. ...makeDimensionProps(),
  23113. ...makeLayoutProps()
  23114. }, 'VLayout');
  23115. const VLayout = genericComponent()({
  23116. name: 'VLayout',
  23117. props: makeVLayoutProps(),
  23118. setup(props, _ref) {
  23119. let {
  23120. slots
  23121. } = _ref;
  23122. const {
  23123. layoutClasses,
  23124. layoutStyles,
  23125. getLayoutItem,
  23126. items,
  23127. layoutRef
  23128. } = createLayout(props);
  23129. const {
  23130. dimensionStyles
  23131. } = useDimension(props);
  23132. useRender(() => createVNode("div", {
  23133. "ref": layoutRef,
  23134. "class": [layoutClasses.value, props.class],
  23135. "style": [dimensionStyles.value, layoutStyles.value, props.style]
  23136. }, [slots.default?.()]));
  23137. return {
  23138. getLayoutItem,
  23139. items
  23140. };
  23141. }
  23142. });
  23143. // Types
  23144. const makeVLayoutItemProps = propsFactory({
  23145. position: {
  23146. type: String,
  23147. required: true
  23148. },
  23149. size: {
  23150. type: [Number, String],
  23151. default: 300
  23152. },
  23153. modelValue: Boolean,
  23154. ...makeComponentProps(),
  23155. ...makeLayoutItemProps()
  23156. }, 'VLayoutItem');
  23157. const VLayoutItem = genericComponent()({
  23158. name: 'VLayoutItem',
  23159. props: makeVLayoutItemProps(),
  23160. setup(props, _ref) {
  23161. let {
  23162. slots
  23163. } = _ref;
  23164. const {
  23165. layoutItemStyles
  23166. } = useLayoutItem({
  23167. id: props.name,
  23168. order: computed(() => parseInt(props.order, 10)),
  23169. position: toRef(props, 'position'),
  23170. elementSize: toRef(props, 'size'),
  23171. layoutSize: toRef(props, 'size'),
  23172. active: toRef(props, 'modelValue'),
  23173. absolute: toRef(props, 'absolute')
  23174. });
  23175. return () => createVNode("div", {
  23176. "class": ['v-layout-item', props.class],
  23177. "style": [layoutItemStyles.value, props.style]
  23178. }, [slots.default?.()]);
  23179. }
  23180. });
  23181. // Types
  23182. const makeVLazyProps = propsFactory({
  23183. modelValue: Boolean,
  23184. options: {
  23185. type: Object,
  23186. // For more information on types, navigate to:
  23187. // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
  23188. default: () => ({
  23189. root: undefined,
  23190. rootMargin: undefined,
  23191. threshold: undefined
  23192. })
  23193. },
  23194. ...makeComponentProps(),
  23195. ...makeDimensionProps(),
  23196. ...makeTagProps(),
  23197. ...makeTransitionProps({
  23198. transition: 'fade-transition'
  23199. })
  23200. }, 'VLazy');
  23201. const VLazy = genericComponent()({
  23202. name: 'VLazy',
  23203. directives: {
  23204. intersect: Intersect
  23205. },
  23206. props: makeVLazyProps(),
  23207. emits: {
  23208. 'update:modelValue': value => true
  23209. },
  23210. setup(props, _ref) {
  23211. let {
  23212. slots
  23213. } = _ref;
  23214. const {
  23215. dimensionStyles
  23216. } = useDimension(props);
  23217. const isActive = useProxiedModel(props, 'modelValue');
  23218. function onIntersect(isIntersecting) {
  23219. if (isActive.value) return;
  23220. isActive.value = isIntersecting;
  23221. }
  23222. useRender(() => withDirectives(createVNode(props.tag, {
  23223. "class": ['v-lazy', props.class],
  23224. "style": [dimensionStyles.value, props.style]
  23225. }, {
  23226. default: () => [isActive.value && createVNode(MaybeTransition, {
  23227. "transition": props.transition,
  23228. "appear": true
  23229. }, {
  23230. default: () => [slots.default?.()]
  23231. })]
  23232. }), [[resolveDirective("intersect"), {
  23233. handler: onIntersect,
  23234. options: props.options
  23235. }, null]]));
  23236. return {};
  23237. }
  23238. });
  23239. const makeVLocaleProviderProps = propsFactory({
  23240. locale: String,
  23241. fallbackLocale: String,
  23242. messages: Object,
  23243. rtl: {
  23244. type: Boolean,
  23245. default: undefined
  23246. },
  23247. ...makeComponentProps()
  23248. }, 'VLocaleProvider');
  23249. const VLocaleProvider = genericComponent()({
  23250. name: 'VLocaleProvider',
  23251. props: makeVLocaleProviderProps(),
  23252. setup(props, _ref) {
  23253. let {
  23254. slots
  23255. } = _ref;
  23256. const {
  23257. rtlClasses
  23258. } = provideLocale(props);
  23259. useRender(() => createVNode("div", {
  23260. "class": ['v-locale-provider', rtlClasses.value, props.class],
  23261. "style": props.style
  23262. }, [slots.default?.()]));
  23263. return {};
  23264. }
  23265. });
  23266. const makeVMainProps = propsFactory({
  23267. scrollable: Boolean,
  23268. ...makeComponentProps(),
  23269. ...makeDimensionProps(),
  23270. ...makeTagProps({
  23271. tag: 'main'
  23272. })
  23273. }, 'VMain');
  23274. const VMain = genericComponent()({
  23275. name: 'VMain',
  23276. props: makeVMainProps(),
  23277. setup(props, _ref) {
  23278. let {
  23279. slots
  23280. } = _ref;
  23281. const {
  23282. dimensionStyles
  23283. } = useDimension(props);
  23284. const {
  23285. mainStyles
  23286. } = useLayout();
  23287. const {
  23288. ssrBootStyles
  23289. } = useSsrBoot();
  23290. useRender(() => createVNode(props.tag, {
  23291. "class": ['v-main', {
  23292. 'v-main--scrollable': props.scrollable
  23293. }, props.class],
  23294. "style": [mainStyles.value, ssrBootStyles.value, dimensionStyles.value, props.style]
  23295. }, {
  23296. default: () => [props.scrollable ? createVNode("div", {
  23297. "class": "v-main__scroller"
  23298. }, [slots.default?.()]) : slots.default?.()]
  23299. }));
  23300. return {};
  23301. }
  23302. });
  23303. // Utilities
  23304. // Types
  23305. function useSticky(_ref) {
  23306. let {
  23307. rootEl,
  23308. isSticky,
  23309. layoutItemStyles
  23310. } = _ref;
  23311. const isStuck = shallowRef(false);
  23312. const stuckPosition = shallowRef(0);
  23313. const stickyStyles = computed(() => {
  23314. const side = typeof isStuck.value === 'boolean' ? 'top' : isStuck.value;
  23315. return [isSticky.value ? {
  23316. top: 'auto',
  23317. bottom: 'auto',
  23318. height: undefined
  23319. } : undefined, isStuck.value ? {
  23320. [side]: convertToUnit(stuckPosition.value)
  23321. } : {
  23322. top: layoutItemStyles.value.top
  23323. }];
  23324. });
  23325. onMounted(() => {
  23326. watch(isSticky, val => {
  23327. if (val) {
  23328. window.addEventListener('scroll', onScroll, {
  23329. passive: true
  23330. });
  23331. } else {
  23332. window.removeEventListener('scroll', onScroll);
  23333. }
  23334. }, {
  23335. immediate: true
  23336. });
  23337. });
  23338. onBeforeUnmount(() => {
  23339. window.removeEventListener('scroll', onScroll);
  23340. });
  23341. let lastScrollTop = 0;
  23342. function onScroll() {
  23343. const direction = lastScrollTop > window.scrollY ? 'up' : 'down';
  23344. const rect = rootEl.value.getBoundingClientRect();
  23345. const layoutTop = parseFloat(layoutItemStyles.value.top ?? 0);
  23346. const top = window.scrollY - Math.max(0, stuckPosition.value - layoutTop);
  23347. const bottom = rect.height + Math.max(stuckPosition.value, layoutTop) - window.scrollY - window.innerHeight;
  23348. const bodyScroll = parseFloat(getComputedStyle(rootEl.value).getPropertyValue('--v-body-scroll-y')) || 0;
  23349. if (rect.height < window.innerHeight - layoutTop) {
  23350. isStuck.value = 'top';
  23351. stuckPosition.value = layoutTop;
  23352. } else if (direction === 'up' && isStuck.value === 'bottom' || direction === 'down' && isStuck.value === 'top') {
  23353. stuckPosition.value = window.scrollY + rect.top - bodyScroll;
  23354. isStuck.value = true;
  23355. } else if (direction === 'down' && bottom <= 0) {
  23356. stuckPosition.value = 0;
  23357. isStuck.value = 'bottom';
  23358. } else if (direction === 'up' && top <= 0) {
  23359. if (!bodyScroll) {
  23360. stuckPosition.value = rect.top + top;
  23361. isStuck.value = 'top';
  23362. } else if (isStuck.value !== 'top') {
  23363. stuckPosition.value = -top + bodyScroll + layoutTop;
  23364. isStuck.value = 'top';
  23365. }
  23366. }
  23367. lastScrollTop = window.scrollY;
  23368. }
  23369. return {
  23370. isStuck,
  23371. stickyStyles
  23372. };
  23373. }
  23374. // Utilities
  23375. const HORIZON = 100; // ms
  23376. const HISTORY = 20; // number of samples to keep
  23377. /** @see https://android.googlesource.com/platform/frameworks/native/+/master/libs/input/VelocityTracker.cpp */
  23378. function kineticEnergyToVelocity(work) {
  23379. const sqrt2 = 1.41421356237;
  23380. return (work < 0 ? -1.0 : 1.0) * Math.sqrt(Math.abs(work)) * sqrt2;
  23381. }
  23382. /**
  23383. * Returns pointer velocity in px/s
  23384. */
  23385. function calculateImpulseVelocity(samples) {
  23386. // The input should be in reversed time order (most recent sample at index i=0)
  23387. if (samples.length < 2) {
  23388. // if 0 or 1 points, velocity is zero
  23389. return 0;
  23390. }
  23391. // if (samples[1].t > samples[0].t) {
  23392. // // Algorithm will still work, but not perfectly
  23393. // consoleWarn('Samples provided to calculateImpulseVelocity in the wrong order')
  23394. // }
  23395. if (samples.length === 2) {
  23396. // if 2 points, basic linear calculation
  23397. if (samples[1].t === samples[0].t) {
  23398. // consoleWarn(`Events have identical time stamps t=${samples[0].t}, setting velocity = 0`)
  23399. return 0;
  23400. }
  23401. return (samples[1].d - samples[0].d) / (samples[1].t - samples[0].t);
  23402. }
  23403. // Guaranteed to have at least 3 points here
  23404. // start with the oldest sample and go forward in time
  23405. let work = 0;
  23406. for (let i = samples.length - 1; i > 0; i--) {
  23407. if (samples[i].t === samples[i - 1].t) {
  23408. // consoleWarn(`Events have identical time stamps t=${samples[i].t}, skipping sample`)
  23409. continue;
  23410. }
  23411. const vprev = kineticEnergyToVelocity(work); // v[i-1]
  23412. const vcurr = (samples[i].d - samples[i - 1].d) / (samples[i].t - samples[i - 1].t); // v[i]
  23413. work += (vcurr - vprev) * Math.abs(vcurr);
  23414. if (i === samples.length - 1) {
  23415. work *= 0.5;
  23416. }
  23417. }
  23418. return kineticEnergyToVelocity(work) * 1000;
  23419. }
  23420. function useVelocity() {
  23421. const touches = {};
  23422. function addMovement(e) {
  23423. Array.from(e.changedTouches).forEach(touch => {
  23424. const samples = touches[touch.identifier] ?? (touches[touch.identifier] = new CircularBuffer(HISTORY));
  23425. samples.push([e.timeStamp, touch]);
  23426. });
  23427. }
  23428. function endTouch(e) {
  23429. Array.from(e.changedTouches).forEach(touch => {
  23430. delete touches[touch.identifier];
  23431. });
  23432. }
  23433. function getVelocity(id) {
  23434. const samples = touches[id]?.values().reverse();
  23435. if (!samples) {
  23436. throw new Error(`No samples for touch id ${id}`);
  23437. }
  23438. const newest = samples[0];
  23439. const x = [];
  23440. const y = [];
  23441. for (const val of samples) {
  23442. if (newest[0] - val[0] > HORIZON) break;
  23443. x.push({
  23444. t: val[0],
  23445. d: val[1].clientX
  23446. });
  23447. y.push({
  23448. t: val[0],
  23449. d: val[1].clientY
  23450. });
  23451. }
  23452. return {
  23453. x: calculateImpulseVelocity(x),
  23454. y: calculateImpulseVelocity(y),
  23455. get direction() {
  23456. const {
  23457. x,
  23458. y
  23459. } = this;
  23460. const [absX, absY] = [Math.abs(x), Math.abs(y)];
  23461. return absX > absY && x >= 0 ? 'right' : absX > absY && x <= 0 ? 'left' : absY > absX && y >= 0 ? 'down' : absY > absX && y <= 0 ? 'up' : oops$1();
  23462. }
  23463. };
  23464. }
  23465. return {
  23466. addMovement,
  23467. endTouch,
  23468. getVelocity
  23469. };
  23470. }
  23471. function oops$1() {
  23472. throw new Error();
  23473. }
  23474. // Composables
  23475. // Types
  23476. function useTouch(_ref) {
  23477. let {
  23478. el,
  23479. isActive,
  23480. isTemporary,
  23481. width,
  23482. touchless,
  23483. position
  23484. } = _ref;
  23485. onMounted(() => {
  23486. window.addEventListener('touchstart', onTouchstart, {
  23487. passive: true
  23488. });
  23489. window.addEventListener('touchmove', onTouchmove, {
  23490. passive: false
  23491. });
  23492. window.addEventListener('touchend', onTouchend, {
  23493. passive: true
  23494. });
  23495. });
  23496. onBeforeUnmount(() => {
  23497. window.removeEventListener('touchstart', onTouchstart);
  23498. window.removeEventListener('touchmove', onTouchmove);
  23499. window.removeEventListener('touchend', onTouchend);
  23500. });
  23501. const isHorizontal = computed(() => ['left', 'right'].includes(position.value));
  23502. const {
  23503. addMovement,
  23504. endTouch,
  23505. getVelocity
  23506. } = useVelocity();
  23507. let maybeDragging = false;
  23508. const isDragging = shallowRef(false);
  23509. const dragProgress = shallowRef(0);
  23510. const offset = shallowRef(0);
  23511. let start;
  23512. function getOffset(pos, active) {
  23513. return (position.value === 'left' ? pos : position.value === 'right' ? document.documentElement.clientWidth - pos : position.value === 'top' ? pos : position.value === 'bottom' ? document.documentElement.clientHeight - pos : oops()) - (active ? width.value : 0);
  23514. }
  23515. function getProgress(pos) {
  23516. let limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  23517. const progress = position.value === 'left' ? (pos - offset.value) / width.value : position.value === 'right' ? (document.documentElement.clientWidth - pos - offset.value) / width.value : position.value === 'top' ? (pos - offset.value) / width.value : position.value === 'bottom' ? (document.documentElement.clientHeight - pos - offset.value) / width.value : oops();
  23518. return limit ? Math.max(0, Math.min(1, progress)) : progress;
  23519. }
  23520. function onTouchstart(e) {
  23521. if (touchless.value) return;
  23522. const touchX = e.changedTouches[0].clientX;
  23523. const touchY = e.changedTouches[0].clientY;
  23524. const touchZone = 25;
  23525. const inTouchZone = position.value === 'left' ? touchX < touchZone : position.value === 'right' ? touchX > document.documentElement.clientWidth - touchZone : position.value === 'top' ? touchY < touchZone : position.value === 'bottom' ? touchY > document.documentElement.clientHeight - touchZone : oops();
  23526. const inElement = isActive.value && (position.value === 'left' ? touchX < width.value : position.value === 'right' ? touchX > document.documentElement.clientWidth - width.value : position.value === 'top' ? touchY < width.value : position.value === 'bottom' ? touchY > document.documentElement.clientHeight - width.value : oops());
  23527. if (inTouchZone || inElement || isActive.value && isTemporary.value) {
  23528. start = [touchX, touchY];
  23529. offset.value = getOffset(isHorizontal.value ? touchX : touchY, isActive.value);
  23530. dragProgress.value = getProgress(isHorizontal.value ? touchX : touchY);
  23531. maybeDragging = offset.value > -20 && offset.value < 80;
  23532. endTouch(e);
  23533. addMovement(e);
  23534. }
  23535. }
  23536. function onTouchmove(e) {
  23537. const touchX = e.changedTouches[0].clientX;
  23538. const touchY = e.changedTouches[0].clientY;
  23539. if (maybeDragging) {
  23540. if (!e.cancelable) {
  23541. maybeDragging = false;
  23542. return;
  23543. }
  23544. const dx = Math.abs(touchX - start[0]);
  23545. const dy = Math.abs(touchY - start[1]);
  23546. const thresholdMet = isHorizontal.value ? dx > dy && dx > 3 : dy > dx && dy > 3;
  23547. if (thresholdMet) {
  23548. isDragging.value = true;
  23549. maybeDragging = false;
  23550. } else if ((isHorizontal.value ? dy : dx) > 3) {
  23551. maybeDragging = false;
  23552. }
  23553. }
  23554. if (!isDragging.value) return;
  23555. e.preventDefault();
  23556. addMovement(e);
  23557. const progress = getProgress(isHorizontal.value ? touchX : touchY, false);
  23558. dragProgress.value = Math.max(0, Math.min(1, progress));
  23559. if (progress > 1) {
  23560. offset.value = getOffset(isHorizontal.value ? touchX : touchY, true);
  23561. } else if (progress < 0) {
  23562. offset.value = getOffset(isHorizontal.value ? touchX : touchY, false);
  23563. }
  23564. }
  23565. function onTouchend(e) {
  23566. maybeDragging = false;
  23567. if (!isDragging.value) return;
  23568. addMovement(e);
  23569. isDragging.value = false;
  23570. const velocity = getVelocity(e.changedTouches[0].identifier);
  23571. const vx = Math.abs(velocity.x);
  23572. const vy = Math.abs(velocity.y);
  23573. const thresholdMet = isHorizontal.value ? vx > vy && vx > 400 : vy > vx && vy > 3;
  23574. if (thresholdMet) {
  23575. isActive.value = velocity.direction === ({
  23576. left: 'right',
  23577. right: 'left',
  23578. top: 'down',
  23579. bottom: 'up'
  23580. }[position.value] || oops());
  23581. } else {
  23582. isActive.value = dragProgress.value > 0.5;
  23583. }
  23584. }
  23585. const dragStyles = computed(() => {
  23586. return isDragging.value ? {
  23587. transform: position.value === 'left' ? `translateX(calc(-100% + ${dragProgress.value * width.value}px))` : position.value === 'right' ? `translateX(calc(100% - ${dragProgress.value * width.value}px))` : position.value === 'top' ? `translateY(calc(-100% + ${dragProgress.value * width.value}px))` : position.value === 'bottom' ? `translateY(calc(100% - ${dragProgress.value * width.value}px))` : oops(),
  23588. transition: 'none'
  23589. } : undefined;
  23590. });
  23591. useToggleScope(isDragging, () => {
  23592. const transform = el.value?.style.transform ?? null;
  23593. const transition = el.value?.style.transition ?? null;
  23594. watchEffect(() => {
  23595. el.value?.style.setProperty('transform', dragStyles.value?.transform || 'none');
  23596. el.value?.style.setProperty('transition', dragStyles.value?.transition || null);
  23597. });
  23598. onScopeDispose(() => {
  23599. el.value?.style.setProperty('transform', transform);
  23600. el.value?.style.setProperty('transition', transition);
  23601. });
  23602. });
  23603. return {
  23604. isDragging,
  23605. dragProgress,
  23606. dragStyles
  23607. };
  23608. }
  23609. function oops() {
  23610. throw new Error();
  23611. }
  23612. // Types
  23613. const locations = ['start', 'end', 'left', 'right', 'top', 'bottom'];
  23614. const makeVNavigationDrawerProps = propsFactory({
  23615. color: String,
  23616. disableResizeWatcher: Boolean,
  23617. disableRouteWatcher: Boolean,
  23618. expandOnHover: Boolean,
  23619. floating: Boolean,
  23620. modelValue: {
  23621. type: Boolean,
  23622. default: null
  23623. },
  23624. permanent: Boolean,
  23625. rail: {
  23626. type: Boolean,
  23627. default: null
  23628. },
  23629. railWidth: {
  23630. type: [Number, String],
  23631. default: 56
  23632. },
  23633. scrim: {
  23634. type: [Boolean, String],
  23635. default: true
  23636. },
  23637. image: String,
  23638. temporary: Boolean,
  23639. persistent: Boolean,
  23640. touchless: Boolean,
  23641. width: {
  23642. type: [Number, String],
  23643. default: 256
  23644. },
  23645. location: {
  23646. type: String,
  23647. default: 'start',
  23648. validator: value => locations.includes(value)
  23649. },
  23650. sticky: Boolean,
  23651. ...makeBorderProps(),
  23652. ...makeComponentProps(),
  23653. ...makeDelayProps(),
  23654. ...makeDisplayProps({
  23655. mobile: null
  23656. }),
  23657. ...makeElevationProps(),
  23658. ...makeLayoutItemProps(),
  23659. ...makeRoundedProps(),
  23660. ...makeTagProps({
  23661. tag: 'nav'
  23662. }),
  23663. ...makeThemeProps()
  23664. }, 'VNavigationDrawer');
  23665. const VNavigationDrawer = genericComponent()({
  23666. name: 'VNavigationDrawer',
  23667. props: makeVNavigationDrawerProps(),
  23668. emits: {
  23669. 'update:modelValue': val => true,
  23670. 'update:rail': val => true
  23671. },
  23672. setup(props, _ref) {
  23673. let {
  23674. attrs,
  23675. emit,
  23676. slots
  23677. } = _ref;
  23678. const {
  23679. isRtl
  23680. } = useRtl();
  23681. const {
  23682. themeClasses
  23683. } = provideTheme(props);
  23684. const {
  23685. borderClasses
  23686. } = useBorder(props);
  23687. const {
  23688. backgroundColorClasses,
  23689. backgroundColorStyles
  23690. } = useBackgroundColor(toRef(props, 'color'));
  23691. const {
  23692. elevationClasses
  23693. } = useElevation(props);
  23694. const {
  23695. displayClasses,
  23696. mobile
  23697. } = useDisplay(props);
  23698. const {
  23699. roundedClasses
  23700. } = useRounded(props);
  23701. const router = useRouter();
  23702. const isActive = useProxiedModel(props, 'modelValue', null, v => !!v);
  23703. const {
  23704. ssrBootStyles
  23705. } = useSsrBoot();
  23706. const {
  23707. scopeId
  23708. } = useScopeId();
  23709. const rootEl = ref();
  23710. const isHovering = shallowRef(false);
  23711. const {
  23712. runOpenDelay,
  23713. runCloseDelay
  23714. } = useDelay(props, value => {
  23715. isHovering.value = value;
  23716. });
  23717. const width = computed(() => {
  23718. return props.rail && props.expandOnHover && isHovering.value ? Number(props.width) : Number(props.rail ? props.railWidth : props.width);
  23719. });
  23720. const location = computed(() => {
  23721. return toPhysical(props.location, isRtl.value);
  23722. });
  23723. const isPersistent = computed(() => props.persistent);
  23724. const isTemporary = computed(() => !props.permanent && (mobile.value || props.temporary));
  23725. const isSticky = computed(() => props.sticky && !isTemporary.value && location.value !== 'bottom');
  23726. useToggleScope(() => props.expandOnHover && props.rail != null, () => {
  23727. watch(isHovering, val => emit('update:rail', !val));
  23728. });
  23729. useToggleScope(() => !props.disableResizeWatcher, () => {
  23730. watch(isTemporary, val => !props.permanent && nextTick(() => isActive.value = !val));
  23731. });
  23732. useToggleScope(() => !props.disableRouteWatcher && !!router, () => {
  23733. watch(router.currentRoute, () => isTemporary.value && (isActive.value = false));
  23734. });
  23735. watch(() => props.permanent, val => {
  23736. if (val) isActive.value = true;
  23737. });
  23738. if (props.modelValue == null && !isTemporary.value) {
  23739. isActive.value = props.permanent || !mobile.value;
  23740. }
  23741. const {
  23742. isDragging,
  23743. dragProgress
  23744. } = useTouch({
  23745. el: rootEl,
  23746. isActive,
  23747. isTemporary,
  23748. width,
  23749. touchless: toRef(props, 'touchless'),
  23750. position: location
  23751. });
  23752. const layoutSize = computed(() => {
  23753. const size = isTemporary.value ? 0 : props.rail && props.expandOnHover ? Number(props.railWidth) : width.value;
  23754. return isDragging.value ? size * dragProgress.value : size;
  23755. });
  23756. const elementSize = computed(() => ['top', 'bottom'].includes(props.location) ? 0 : width.value);
  23757. const {
  23758. layoutItemStyles,
  23759. layoutItemScrimStyles
  23760. } = useLayoutItem({
  23761. id: props.name,
  23762. order: computed(() => parseInt(props.order, 10)),
  23763. position: location,
  23764. layoutSize,
  23765. elementSize,
  23766. active: computed(() => isActive.value || isDragging.value),
  23767. disableTransitions: computed(() => isDragging.value),
  23768. absolute: computed(() =>
  23769. // eslint-disable-next-line @typescript-eslint/no-use-before-define
  23770. props.absolute || isSticky.value && typeof isStuck.value !== 'string')
  23771. });
  23772. const {
  23773. isStuck,
  23774. stickyStyles
  23775. } = useSticky({
  23776. rootEl,
  23777. isSticky,
  23778. layoutItemStyles
  23779. });
  23780. const scrimColor = useBackgroundColor(computed(() => {
  23781. return typeof props.scrim === 'string' ? props.scrim : null;
  23782. }));
  23783. const scrimStyles = computed(() => ({
  23784. ...(isDragging.value ? {
  23785. opacity: dragProgress.value * 0.2,
  23786. transition: 'none'
  23787. } : undefined),
  23788. ...layoutItemScrimStyles.value
  23789. }));
  23790. provideDefaults({
  23791. VList: {
  23792. bgColor: 'transparent'
  23793. }
  23794. });
  23795. useRender(() => {
  23796. const hasImage = slots.image || props.image;
  23797. return createVNode(Fragment, null, [createVNode(props.tag, mergeProps({
  23798. "ref": rootEl,
  23799. "onMouseenter": runOpenDelay,
  23800. "onMouseleave": runCloseDelay,
  23801. "class": ['v-navigation-drawer', `v-navigation-drawer--${location.value}`, {
  23802. 'v-navigation-drawer--expand-on-hover': props.expandOnHover,
  23803. 'v-navigation-drawer--floating': props.floating,
  23804. 'v-navigation-drawer--is-hovering': isHovering.value,
  23805. 'v-navigation-drawer--rail': props.rail,
  23806. 'v-navigation-drawer--temporary': isTemporary.value,
  23807. 'v-navigation-drawer--persistent': isPersistent.value,
  23808. 'v-navigation-drawer--active': isActive.value,
  23809. 'v-navigation-drawer--sticky': isSticky.value
  23810. }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, displayClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  23811. "style": [backgroundColorStyles.value, layoutItemStyles.value, ssrBootStyles.value, stickyStyles.value, props.style, ['top', 'bottom'].includes(location.value) ? {
  23812. height: 'auto'
  23813. } : {}]
  23814. }, scopeId, attrs), {
  23815. default: () => [hasImage && createVNode("div", {
  23816. "key": "image",
  23817. "class": "v-navigation-drawer__img"
  23818. }, [!slots.image ? createVNode(VImg, {
  23819. "key": "image-img",
  23820. "alt": "",
  23821. "cover": true,
  23822. "height": "inherit",
  23823. "src": props.image
  23824. }, null) : createVNode(VDefaultsProvider, {
  23825. "key": "image-defaults",
  23826. "disabled": !props.image,
  23827. "defaults": {
  23828. VImg: {
  23829. alt: '',
  23830. cover: true,
  23831. height: 'inherit',
  23832. src: props.image
  23833. }
  23834. }
  23835. }, slots.image)]), slots.prepend && createVNode("div", {
  23836. "class": "v-navigation-drawer__prepend"
  23837. }, [slots.prepend?.()]), createVNode("div", {
  23838. "class": "v-navigation-drawer__content"
  23839. }, [slots.default?.()]), slots.append && createVNode("div", {
  23840. "class": "v-navigation-drawer__append"
  23841. }, [slots.append?.()])]
  23842. }), createVNode(Transition, {
  23843. "name": "fade-transition"
  23844. }, {
  23845. default: () => [isTemporary.value && (isDragging.value || isActive.value) && !!props.scrim && createVNode("div", mergeProps({
  23846. "class": ['v-navigation-drawer__scrim', scrimColor.backgroundColorClasses.value],
  23847. "style": [scrimStyles.value, scrimColor.backgroundColorStyles.value],
  23848. "onClick": () => {
  23849. if (isPersistent.value) return;
  23850. isActive.value = false;
  23851. }
  23852. }, scopeId), null)]
  23853. })]);
  23854. });
  23855. return {
  23856. isStuck
  23857. };
  23858. }
  23859. });
  23860. // Composables
  23861. const VNoSsr = defineComponent({
  23862. name: 'VNoSsr',
  23863. setup(_, _ref) {
  23864. let {
  23865. slots
  23866. } = _ref;
  23867. const show = useHydration();
  23868. return () => show.value && slots.default?.();
  23869. }
  23870. });
  23871. // Types
  23872. // Types
  23873. const makeVOtpInputProps = propsFactory({
  23874. autofocus: Boolean,
  23875. divider: String,
  23876. focusAll: Boolean,
  23877. label: {
  23878. type: String,
  23879. default: '$vuetify.input.otp'
  23880. },
  23881. length: {
  23882. type: [Number, String],
  23883. default: 6
  23884. },
  23885. modelValue: {
  23886. type: [Number, String],
  23887. default: undefined
  23888. },
  23889. placeholder: String,
  23890. type: {
  23891. type: String,
  23892. default: 'number'
  23893. },
  23894. ...makeDimensionProps(),
  23895. ...makeFocusProps(),
  23896. ...only(makeVFieldProps({
  23897. variant: 'outlined'
  23898. }), ['baseColor', 'bgColor', 'class', 'color', 'disabled', 'error', 'loading', 'rounded', 'style', 'theme', 'variant'])
  23899. }, 'VOtpInput');
  23900. const VOtpInput = genericComponent()({
  23901. name: 'VOtpInput',
  23902. props: makeVOtpInputProps(),
  23903. emits: {
  23904. finish: val => true,
  23905. 'update:focused': val => true,
  23906. 'update:modelValue': val => true
  23907. },
  23908. setup(props, _ref) {
  23909. let {
  23910. attrs,
  23911. emit,
  23912. slots
  23913. } = _ref;
  23914. const {
  23915. dimensionStyles
  23916. } = useDimension(props);
  23917. const {
  23918. isFocused,
  23919. focus,
  23920. blur
  23921. } = useFocus(props);
  23922. const model = useProxiedModel(props, 'modelValue', '', val => val == null ? [] : String(val).split(''), val => val.join(''));
  23923. const {
  23924. t
  23925. } = useLocale();
  23926. const length = computed(() => Number(props.length));
  23927. const fields = computed(() => Array(length.value).fill(0));
  23928. const focusIndex = ref(-1);
  23929. const contentRef = ref();
  23930. const inputRef = ref([]);
  23931. const current = computed(() => inputRef.value[focusIndex.value]);
  23932. function onInput() {
  23933. // The maxlength attribute doesn't work for the number type input, so the text type is used.
  23934. // The following logic simulates the behavior of a number input.
  23935. if (isValidNumber(current.value.value)) {
  23936. current.value.value = '';
  23937. return;
  23938. }
  23939. const array = model.value.slice();
  23940. const value = current.value.value;
  23941. array[focusIndex.value] = value;
  23942. let target = null;
  23943. if (focusIndex.value > model.value.length) {
  23944. target = model.value.length + 1;
  23945. } else if (focusIndex.value + 1 !== length.value) {
  23946. target = 'next';
  23947. }
  23948. model.value = array;
  23949. if (target) focusChild(contentRef.value, target);
  23950. }
  23951. function onKeydown(e) {
  23952. const array = model.value.slice();
  23953. const index = focusIndex.value;
  23954. let target = null;
  23955. if (!['ArrowLeft', 'ArrowRight', 'Backspace', 'Delete'].includes(e.key)) return;
  23956. e.preventDefault();
  23957. if (e.key === 'ArrowLeft') {
  23958. target = 'prev';
  23959. } else if (e.key === 'ArrowRight') {
  23960. target = 'next';
  23961. } else if (['Backspace', 'Delete'].includes(e.key)) {
  23962. array[focusIndex.value] = '';
  23963. model.value = array;
  23964. if (focusIndex.value > 0 && e.key === 'Backspace') {
  23965. target = 'prev';
  23966. } else {
  23967. requestAnimationFrame(() => {
  23968. inputRef.value[index]?.select();
  23969. });
  23970. }
  23971. }
  23972. requestAnimationFrame(() => {
  23973. if (target != null) {
  23974. focusChild(contentRef.value, target);
  23975. }
  23976. });
  23977. }
  23978. function onPaste(index, e) {
  23979. e.preventDefault();
  23980. e.stopPropagation();
  23981. const clipboardText = e?.clipboardData?.getData('Text').slice(0, length.value) ?? '';
  23982. if (isValidNumber(clipboardText)) return;
  23983. model.value = clipboardText.split('');
  23984. inputRef.value?.[index].blur();
  23985. }
  23986. function reset() {
  23987. model.value = [];
  23988. }
  23989. function onFocus(e, index) {
  23990. focus();
  23991. focusIndex.value = index;
  23992. }
  23993. function onBlur() {
  23994. blur();
  23995. focusIndex.value = -1;
  23996. }
  23997. function isValidNumber(value) {
  23998. return props.type === 'number' && /[^0-9]/g.test(value);
  23999. }
  24000. provideDefaults({
  24001. VField: {
  24002. color: computed(() => props.color),
  24003. bgColor: computed(() => props.color),
  24004. baseColor: computed(() => props.baseColor),
  24005. disabled: computed(() => props.disabled),
  24006. error: computed(() => props.error),
  24007. variant: computed(() => props.variant)
  24008. }
  24009. }, {
  24010. scoped: true
  24011. });
  24012. watch(model, val => {
  24013. if (val.length === length.value) emit('finish', val.join(''));
  24014. }, {
  24015. deep: true
  24016. });
  24017. watch(focusIndex, val => {
  24018. if (val < 0) return;
  24019. nextTick(() => {
  24020. inputRef.value[val]?.select();
  24021. });
  24022. });
  24023. useRender(() => {
  24024. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  24025. return createVNode("div", mergeProps({
  24026. "class": ['v-otp-input', {
  24027. 'v-otp-input--divided': !!props.divider
  24028. }, props.class],
  24029. "style": [props.style]
  24030. }, rootAttrs), [createVNode("div", {
  24031. "ref": contentRef,
  24032. "class": "v-otp-input__content",
  24033. "style": [dimensionStyles.value]
  24034. }, [fields.value.map((_, i) => createVNode(Fragment, null, [props.divider && i !== 0 && createVNode("span", {
  24035. "class": "v-otp-input__divider"
  24036. }, [props.divider]), createVNode(VField, {
  24037. "focused": isFocused.value && props.focusAll || focusIndex.value === i,
  24038. "key": i
  24039. }, {
  24040. ...slots,
  24041. loader: undefined,
  24042. default: () => {
  24043. return createVNode("input", {
  24044. "ref": val => inputRef.value[i] = val,
  24045. "aria-label": t(props.label, i + 1),
  24046. "autofocus": i === 0 && props.autofocus,
  24047. "autocomplete": "one-time-code",
  24048. "class": ['v-otp-input__field'],
  24049. "disabled": props.disabled,
  24050. "inputmode": props.type === 'number' ? 'numeric' : 'text',
  24051. "min": props.type === 'number' ? 0 : undefined,
  24052. "maxlength": "1",
  24053. "placeholder": props.placeholder,
  24054. "type": props.type === 'number' ? 'text' : props.type,
  24055. "value": model.value[i],
  24056. "onInput": onInput,
  24057. "onFocus": e => onFocus(e, i),
  24058. "onBlur": onBlur,
  24059. "onKeydown": onKeydown,
  24060. "onPaste": event => onPaste(i, event)
  24061. }, null);
  24062. }
  24063. })])), createVNode("input", mergeProps({
  24064. "class": "v-otp-input-input",
  24065. "type": "hidden"
  24066. }, inputAttrs, {
  24067. "value": model.value.join('')
  24068. }), null), createVNode(VOverlay, {
  24069. "contained": true,
  24070. "content-class": "v-otp-input__loader",
  24071. "model-value": !!props.loading,
  24072. "persistent": true
  24073. }, {
  24074. default: () => [slots.loader?.() ?? createVNode(VProgressCircular, {
  24075. "color": typeof props.loading === 'boolean' ? undefined : props.loading,
  24076. "indeterminate": true,
  24077. "size": "24",
  24078. "width": "2"
  24079. }, null)]
  24080. }), slots.default?.()])]);
  24081. });
  24082. return {
  24083. blur: () => {
  24084. inputRef.value?.some(input => input.blur());
  24085. },
  24086. focus: () => {
  24087. inputRef.value?.[0].focus();
  24088. },
  24089. reset,
  24090. isFocused
  24091. };
  24092. }
  24093. });
  24094. // Types
  24095. function floor(val) {
  24096. return Math.floor(Math.abs(val)) * Math.sign(val);
  24097. }
  24098. const makeVParallaxProps = propsFactory({
  24099. scale: {
  24100. type: [Number, String],
  24101. default: 0.5
  24102. },
  24103. ...makeComponentProps()
  24104. }, 'VParallax');
  24105. const VParallax = genericComponent()({
  24106. name: 'VParallax',
  24107. props: makeVParallaxProps(),
  24108. setup(props, _ref) {
  24109. let {
  24110. slots
  24111. } = _ref;
  24112. const {
  24113. intersectionRef,
  24114. isIntersecting
  24115. } = useIntersectionObserver();
  24116. const {
  24117. resizeRef,
  24118. contentRect
  24119. } = useResizeObserver();
  24120. const {
  24121. height: displayHeight
  24122. } = useDisplay();
  24123. const root = ref();
  24124. watchEffect(() => {
  24125. intersectionRef.value = resizeRef.value = root.value?.$el;
  24126. });
  24127. let scrollParent;
  24128. watch(isIntersecting, val => {
  24129. if (val) {
  24130. scrollParent = getScrollParent(intersectionRef.value);
  24131. scrollParent = scrollParent === document.scrollingElement ? document : scrollParent;
  24132. scrollParent.addEventListener('scroll', onScroll, {
  24133. passive: true
  24134. });
  24135. onScroll();
  24136. } else {
  24137. scrollParent.removeEventListener('scroll', onScroll);
  24138. }
  24139. });
  24140. onBeforeUnmount(() => {
  24141. scrollParent?.removeEventListener('scroll', onScroll);
  24142. });
  24143. watch(displayHeight, onScroll);
  24144. watch(() => contentRect.value?.height, onScroll);
  24145. const scale = computed(() => {
  24146. return 1 - clamp(+props.scale);
  24147. });
  24148. let frame = -1;
  24149. function onScroll() {
  24150. if (!isIntersecting.value) return;
  24151. cancelAnimationFrame(frame);
  24152. frame = requestAnimationFrame(() => {
  24153. const el = (root.value?.$el).querySelector('.v-img__img');
  24154. if (!el) return;
  24155. const scrollHeight = scrollParent instanceof Document ? document.documentElement.clientHeight : scrollParent.clientHeight;
  24156. const scrollPos = scrollParent instanceof Document ? window.scrollY : scrollParent.scrollTop;
  24157. const top = intersectionRef.value.getBoundingClientRect().top + scrollPos;
  24158. const height = contentRect.value.height;
  24159. const center = top + (height - scrollHeight) / 2;
  24160. const translate = floor((scrollPos - center) * scale.value);
  24161. const sizeScale = Math.max(1, (scale.value * (scrollHeight - height) + height) / height);
  24162. el.style.setProperty('transform', `translateY(${translate}px) scale(${sizeScale})`);
  24163. });
  24164. }
  24165. useRender(() => createVNode(VImg, {
  24166. "class": ['v-parallax', {
  24167. 'v-parallax--active': isIntersecting.value
  24168. }, props.class],
  24169. "style": props.style,
  24170. "ref": root,
  24171. "cover": true,
  24172. "onLoadstart": onScroll,
  24173. "onLoad": onScroll
  24174. }, slots));
  24175. return {};
  24176. }
  24177. });
  24178. // Types
  24179. const makeVRadioProps = propsFactory({
  24180. ...makeVSelectionControlProps({
  24181. falseIcon: '$radioOff',
  24182. trueIcon: '$radioOn'
  24183. })
  24184. }, 'VRadio');
  24185. const VRadio = genericComponent()({
  24186. name: 'VRadio',
  24187. props: makeVRadioProps(),
  24188. setup(props, _ref) {
  24189. let {
  24190. slots
  24191. } = _ref;
  24192. useRender(() => {
  24193. const controlProps = VSelectionControl.filterProps(props);
  24194. return createVNode(VSelectionControl, mergeProps(controlProps, {
  24195. "class": ['v-radio', props.class],
  24196. "style": props.style,
  24197. "type": "radio"
  24198. }), slots);
  24199. });
  24200. return {};
  24201. }
  24202. });
  24203. // Types
  24204. const makeVRadioGroupProps = propsFactory({
  24205. height: {
  24206. type: [Number, String],
  24207. default: 'auto'
  24208. },
  24209. ...makeVInputProps(),
  24210. ...omit(makeSelectionControlGroupProps(), ['multiple']),
  24211. trueIcon: {
  24212. type: IconValue,
  24213. default: '$radioOn'
  24214. },
  24215. falseIcon: {
  24216. type: IconValue,
  24217. default: '$radioOff'
  24218. },
  24219. type: {
  24220. type: String,
  24221. default: 'radio'
  24222. }
  24223. }, 'VRadioGroup');
  24224. const VRadioGroup = genericComponent()({
  24225. name: 'VRadioGroup',
  24226. inheritAttrs: false,
  24227. props: makeVRadioGroupProps(),
  24228. emits: {
  24229. 'update:modelValue': value => true
  24230. },
  24231. setup(props, _ref) {
  24232. let {
  24233. attrs,
  24234. slots
  24235. } = _ref;
  24236. const uid = getUid();
  24237. const id = computed(() => props.id || `radio-group-${uid}`);
  24238. const model = useProxiedModel(props, 'modelValue');
  24239. useRender(() => {
  24240. const [rootAttrs, controlAttrs] = filterInputAttrs(attrs);
  24241. const inputProps = VInput.filterProps(props);
  24242. const controlProps = VSelectionControl.filterProps(props);
  24243. const label = slots.label ? slots.label({
  24244. label: props.label,
  24245. props: {
  24246. for: id.value
  24247. }
  24248. }) : props.label;
  24249. return createVNode(VInput, mergeProps({
  24250. "class": ['v-radio-group', props.class],
  24251. "style": props.style
  24252. }, rootAttrs, inputProps, {
  24253. "modelValue": model.value,
  24254. "onUpdate:modelValue": $event => model.value = $event,
  24255. "id": id.value
  24256. }), {
  24257. ...slots,
  24258. default: _ref2 => {
  24259. let {
  24260. id,
  24261. messagesId,
  24262. isDisabled,
  24263. isReadonly
  24264. } = _ref2;
  24265. return createVNode(Fragment, null, [label && createVNode(VLabel, {
  24266. "id": id.value
  24267. }, {
  24268. default: () => [label]
  24269. }), createVNode(VSelectionControlGroup, mergeProps(controlProps, {
  24270. "id": id.value,
  24271. "aria-describedby": messagesId.value,
  24272. "defaultsTarget": "VRadio",
  24273. "trueIcon": props.trueIcon,
  24274. "falseIcon": props.falseIcon,
  24275. "type": props.type,
  24276. "disabled": isDisabled.value,
  24277. "readonly": isReadonly.value,
  24278. "aria-labelledby": label ? id.value : undefined,
  24279. "multiple": false
  24280. }, controlAttrs, {
  24281. "modelValue": model.value,
  24282. "onUpdate:modelValue": $event => model.value = $event
  24283. }), slots)]);
  24284. }
  24285. });
  24286. });
  24287. return {};
  24288. }
  24289. });
  24290. // Types
  24291. const makeVRangeSliderProps = propsFactory({
  24292. ...makeFocusProps(),
  24293. ...makeVInputProps(),
  24294. ...makeSliderProps(),
  24295. strict: Boolean,
  24296. modelValue: {
  24297. type: Array,
  24298. default: () => [0, 0]
  24299. }
  24300. }, 'VRangeSlider');
  24301. const VRangeSlider = genericComponent()({
  24302. name: 'VRangeSlider',
  24303. props: makeVRangeSliderProps(),
  24304. emits: {
  24305. 'update:focused': value => true,
  24306. 'update:modelValue': value => true,
  24307. end: value => true,
  24308. start: value => true
  24309. },
  24310. setup(props, _ref) {
  24311. let {
  24312. slots,
  24313. emit
  24314. } = _ref;
  24315. const startThumbRef = ref();
  24316. const stopThumbRef = ref();
  24317. const inputRef = ref();
  24318. const {
  24319. rtlClasses
  24320. } = useRtl();
  24321. function getActiveThumb(e) {
  24322. if (!startThumbRef.value || !stopThumbRef.value) return;
  24323. const startOffset = getOffset(e, startThumbRef.value.$el, props.direction);
  24324. const stopOffset = getOffset(e, stopThumbRef.value.$el, props.direction);
  24325. const a = Math.abs(startOffset);
  24326. const b = Math.abs(stopOffset);
  24327. return a < b || a === b && startOffset < 0 ? startThumbRef.value.$el : stopThumbRef.value.$el;
  24328. }
  24329. const steps = useSteps(props);
  24330. const model = useProxiedModel(props, 'modelValue', undefined, arr => {
  24331. if (!arr?.length) return [0, 0];
  24332. return arr.map(value => steps.roundValue(value));
  24333. });
  24334. const {
  24335. activeThumbRef,
  24336. hasLabels,
  24337. max,
  24338. min,
  24339. mousePressed,
  24340. onSliderMousedown,
  24341. onSliderTouchstart,
  24342. position,
  24343. trackContainerRef,
  24344. readonly
  24345. } = useSlider({
  24346. props,
  24347. steps,
  24348. onSliderStart: () => {
  24349. emit('start', model.value);
  24350. },
  24351. onSliderEnd: _ref2 => {
  24352. let {
  24353. value
  24354. } = _ref2;
  24355. const newValue = activeThumbRef.value === startThumbRef.value?.$el ? [value, model.value[1]] : [model.value[0], value];
  24356. if (!props.strict && newValue[0] < newValue[1]) {
  24357. model.value = newValue;
  24358. }
  24359. emit('end', model.value);
  24360. },
  24361. onSliderMove: _ref3 => {
  24362. let {
  24363. value
  24364. } = _ref3;
  24365. const [start, stop] = model.value;
  24366. if (!props.strict && start === stop && start !== min.value) {
  24367. activeThumbRef.value = value > start ? stopThumbRef.value?.$el : startThumbRef.value?.$el;
  24368. activeThumbRef.value?.focus();
  24369. }
  24370. if (activeThumbRef.value === startThumbRef.value?.$el) {
  24371. model.value = [Math.min(value, stop), stop];
  24372. } else {
  24373. model.value = [start, Math.max(start, value)];
  24374. }
  24375. },
  24376. getActiveThumb
  24377. });
  24378. const {
  24379. isFocused,
  24380. focus,
  24381. blur
  24382. } = useFocus(props);
  24383. const trackStart = computed(() => position(model.value[0]));
  24384. const trackStop = computed(() => position(model.value[1]));
  24385. useRender(() => {
  24386. const inputProps = VInput.filterProps(props);
  24387. const hasPrepend = !!(props.label || slots.label || slots.prepend);
  24388. return createVNode(VInput, mergeProps({
  24389. "class": ['v-slider', 'v-range-slider', {
  24390. 'v-slider--has-labels': !!slots['tick-label'] || hasLabels.value,
  24391. 'v-slider--focused': isFocused.value,
  24392. 'v-slider--pressed': mousePressed.value,
  24393. 'v-slider--disabled': props.disabled
  24394. }, rtlClasses.value, props.class],
  24395. "style": props.style,
  24396. "ref": inputRef
  24397. }, inputProps, {
  24398. "focused": isFocused.value
  24399. }), {
  24400. ...slots,
  24401. prepend: hasPrepend ? slotProps => createVNode(Fragment, null, [slots.label?.(slotProps) ?? (props.label ? createVNode(VLabel, {
  24402. "class": "v-slider__label",
  24403. "text": props.label
  24404. }, null) : undefined), slots.prepend?.(slotProps)]) : undefined,
  24405. default: _ref4 => {
  24406. let {
  24407. id,
  24408. messagesId
  24409. } = _ref4;
  24410. return createVNode("div", {
  24411. "class": "v-slider__container",
  24412. "onMousedown": !readonly.value ? onSliderMousedown : undefined,
  24413. "onTouchstartPassive": !readonly.value ? onSliderTouchstart : undefined
  24414. }, [createVNode("input", {
  24415. "id": `${id.value}_start`,
  24416. "name": props.name || id.value,
  24417. "disabled": !!props.disabled,
  24418. "readonly": !!props.readonly,
  24419. "tabindex": "-1",
  24420. "value": model.value[0]
  24421. }, null), createVNode("input", {
  24422. "id": `${id.value}_stop`,
  24423. "name": props.name || id.value,
  24424. "disabled": !!props.disabled,
  24425. "readonly": !!props.readonly,
  24426. "tabindex": "-1",
  24427. "value": model.value[1]
  24428. }, null), createVNode(VSliderTrack, {
  24429. "ref": trackContainerRef,
  24430. "start": trackStart.value,
  24431. "stop": trackStop.value
  24432. }, {
  24433. 'tick-label': slots['tick-label']
  24434. }), createVNode(VSliderThumb, {
  24435. "ref": startThumbRef,
  24436. "aria-describedby": messagesId.value,
  24437. "focused": isFocused && activeThumbRef.value === startThumbRef.value?.$el,
  24438. "modelValue": model.value[0],
  24439. "onUpdate:modelValue": v => model.value = [v, model.value[1]],
  24440. "onFocus": e => {
  24441. focus();
  24442. activeThumbRef.value = startThumbRef.value?.$el;
  24443. // Make sure second thumb is focused if
  24444. // the thumbs are on top of each other
  24445. // and they are both at minimum value
  24446. // but only if focused from outside.
  24447. if (max.value !== min.value && model.value[0] === model.value[1] && model.value[1] === min.value && e.relatedTarget !== stopThumbRef.value?.$el) {
  24448. startThumbRef.value?.$el.blur();
  24449. stopThumbRef.value?.$el.focus();
  24450. }
  24451. },
  24452. "onBlur": () => {
  24453. blur();
  24454. activeThumbRef.value = undefined;
  24455. },
  24456. "min": min.value,
  24457. "max": model.value[1],
  24458. "position": trackStart.value,
  24459. "ripple": props.ripple
  24460. }, {
  24461. 'thumb-label': slots['thumb-label']
  24462. }), createVNode(VSliderThumb, {
  24463. "ref": stopThumbRef,
  24464. "aria-describedby": messagesId.value,
  24465. "focused": isFocused && activeThumbRef.value === stopThumbRef.value?.$el,
  24466. "modelValue": model.value[1],
  24467. "onUpdate:modelValue": v => model.value = [model.value[0], v],
  24468. "onFocus": e => {
  24469. focus();
  24470. activeThumbRef.value = stopThumbRef.value?.$el;
  24471. // Make sure first thumb is focused if
  24472. // the thumbs are on top of each other
  24473. // and they are both at maximum value
  24474. // but only if focused from outside.
  24475. if (max.value !== min.value && model.value[0] === model.value[1] && model.value[0] === max.value && e.relatedTarget !== startThumbRef.value?.$el) {
  24476. stopThumbRef.value?.$el.blur();
  24477. startThumbRef.value?.$el.focus();
  24478. }
  24479. },
  24480. "onBlur": () => {
  24481. blur();
  24482. activeThumbRef.value = undefined;
  24483. },
  24484. "min": model.value[0],
  24485. "max": max.value,
  24486. "position": trackStop.value,
  24487. "ripple": props.ripple
  24488. }, {
  24489. 'thumb-label': slots['thumb-label']
  24490. })]);
  24491. }
  24492. });
  24493. });
  24494. return {};
  24495. }
  24496. });
  24497. // Types
  24498. const makeVRatingProps = propsFactory({
  24499. name: String,
  24500. itemAriaLabel: {
  24501. type: String,
  24502. default: '$vuetify.rating.ariaLabel.item'
  24503. },
  24504. activeColor: String,
  24505. color: String,
  24506. clearable: Boolean,
  24507. disabled: Boolean,
  24508. emptyIcon: {
  24509. type: IconValue,
  24510. default: '$ratingEmpty'
  24511. },
  24512. fullIcon: {
  24513. type: IconValue,
  24514. default: '$ratingFull'
  24515. },
  24516. halfIncrements: Boolean,
  24517. hover: Boolean,
  24518. length: {
  24519. type: [Number, String],
  24520. default: 5
  24521. },
  24522. readonly: Boolean,
  24523. modelValue: {
  24524. type: [Number, String],
  24525. default: 0
  24526. },
  24527. itemLabels: Array,
  24528. itemLabelPosition: {
  24529. type: String,
  24530. default: 'top',
  24531. validator: v => ['top', 'bottom'].includes(v)
  24532. },
  24533. ripple: Boolean,
  24534. ...makeComponentProps(),
  24535. ...makeDensityProps(),
  24536. ...makeSizeProps(),
  24537. ...makeTagProps(),
  24538. ...makeThemeProps()
  24539. }, 'VRating');
  24540. const VRating = genericComponent()({
  24541. name: 'VRating',
  24542. props: makeVRatingProps(),
  24543. emits: {
  24544. 'update:modelValue': value => true
  24545. },
  24546. setup(props, _ref) {
  24547. let {
  24548. slots
  24549. } = _ref;
  24550. const {
  24551. t
  24552. } = useLocale();
  24553. const {
  24554. themeClasses
  24555. } = provideTheme(props);
  24556. const rating = useProxiedModel(props, 'modelValue');
  24557. const normalizedValue = computed(() => clamp(parseFloat(rating.value), 0, +props.length));
  24558. const range = computed(() => createRange(Number(props.length), 1));
  24559. const increments = computed(() => range.value.flatMap(v => props.halfIncrements ? [v - 0.5, v] : [v]));
  24560. const hoverIndex = shallowRef(-1);
  24561. const itemState = computed(() => increments.value.map(value => {
  24562. const isHovering = props.hover && hoverIndex.value > -1;
  24563. const isFilled = normalizedValue.value >= value;
  24564. const isHovered = hoverIndex.value >= value;
  24565. const isFullIcon = isHovering ? isHovered : isFilled;
  24566. const icon = isFullIcon ? props.fullIcon : props.emptyIcon;
  24567. const activeColor = props.activeColor ?? props.color;
  24568. const color = isFilled || isHovered ? activeColor : props.color;
  24569. return {
  24570. isFilled,
  24571. isHovered,
  24572. icon,
  24573. color
  24574. };
  24575. }));
  24576. const eventState = computed(() => [0, ...increments.value].map(value => {
  24577. function onMouseenter() {
  24578. hoverIndex.value = value;
  24579. }
  24580. function onMouseleave() {
  24581. hoverIndex.value = -1;
  24582. }
  24583. function onClick() {
  24584. if (props.disabled || props.readonly) return;
  24585. rating.value = normalizedValue.value === value && props.clearable ? 0 : value;
  24586. }
  24587. return {
  24588. onMouseenter: props.hover ? onMouseenter : undefined,
  24589. onMouseleave: props.hover ? onMouseleave : undefined,
  24590. onClick
  24591. };
  24592. }));
  24593. const name = computed(() => props.name ?? `v-rating-${getUid()}`);
  24594. function VRatingItem(_ref2) {
  24595. let {
  24596. value,
  24597. index,
  24598. showStar = true
  24599. } = _ref2;
  24600. const {
  24601. onMouseenter,
  24602. onMouseleave,
  24603. onClick
  24604. } = eventState.value[index + 1];
  24605. const id = `${name.value}-${String(value).replace('.', '-')}`;
  24606. const btnProps = {
  24607. color: itemState.value[index]?.color,
  24608. density: props.density,
  24609. disabled: props.disabled,
  24610. icon: itemState.value[index]?.icon,
  24611. ripple: props.ripple,
  24612. size: props.size,
  24613. variant: 'plain'
  24614. };
  24615. return createVNode(Fragment, null, [createVNode("label", {
  24616. "for": id,
  24617. "class": {
  24618. 'v-rating__item--half': props.halfIncrements && value % 1 > 0,
  24619. 'v-rating__item--full': props.halfIncrements && value % 1 === 0
  24620. },
  24621. "onMouseenter": onMouseenter,
  24622. "onMouseleave": onMouseleave,
  24623. "onClick": onClick
  24624. }, [createVNode("span", {
  24625. "class": "v-rating__hidden"
  24626. }, [t(props.itemAriaLabel, value, props.length)]), !showStar ? undefined : slots.item ? slots.item({
  24627. ...itemState.value[index],
  24628. props: btnProps,
  24629. value,
  24630. index,
  24631. rating: normalizedValue.value
  24632. }) : createVNode(VBtn, mergeProps({
  24633. "aria-label": t(props.itemAriaLabel, value, props.length)
  24634. }, btnProps), null)]), createVNode("input", {
  24635. "class": "v-rating__hidden",
  24636. "name": name.value,
  24637. "id": id,
  24638. "type": "radio",
  24639. "value": value,
  24640. "checked": normalizedValue.value === value,
  24641. "tabindex": -1,
  24642. "readonly": props.readonly,
  24643. "disabled": props.disabled
  24644. }, null)]);
  24645. }
  24646. function createLabel(labelProps) {
  24647. if (slots['item-label']) return slots['item-label'](labelProps);
  24648. if (labelProps.label) return createVNode("span", null, [labelProps.label]);
  24649. return createVNode("span", null, [createTextVNode("\xA0")]);
  24650. }
  24651. useRender(() => {
  24652. const hasLabels = !!props.itemLabels?.length || slots['item-label'];
  24653. return createVNode(props.tag, {
  24654. "class": ['v-rating', {
  24655. 'v-rating--hover': props.hover,
  24656. 'v-rating--readonly': props.readonly
  24657. }, themeClasses.value, props.class],
  24658. "style": props.style
  24659. }, {
  24660. default: () => [createVNode(VRatingItem, {
  24661. "value": 0,
  24662. "index": -1,
  24663. "showStar": false
  24664. }, null), range.value.map((value, i) => createVNode("div", {
  24665. "class": "v-rating__wrapper"
  24666. }, [hasLabels && props.itemLabelPosition === 'top' ? createLabel({
  24667. value,
  24668. index: i,
  24669. label: props.itemLabels?.[i]
  24670. }) : undefined, createVNode("div", {
  24671. "class": "v-rating__item"
  24672. }, [props.halfIncrements ? createVNode(Fragment, null, [createVNode(VRatingItem, {
  24673. "value": value - 0.5,
  24674. "index": i * 2
  24675. }, null), createVNode(VRatingItem, {
  24676. "value": value,
  24677. "index": i * 2 + 1
  24678. }, null)]) : createVNode(VRatingItem, {
  24679. "value": value,
  24680. "index": i
  24681. }, null)]), hasLabels && props.itemLabelPosition === 'bottom' ? createLabel({
  24682. value,
  24683. index: i,
  24684. label: props.itemLabels?.[i]
  24685. }) : undefined]))]
  24686. });
  24687. });
  24688. return {};
  24689. }
  24690. });
  24691. // Types
  24692. const rootTypes = {
  24693. actions: 'button@2',
  24694. article: 'heading, paragraph',
  24695. avatar: 'avatar',
  24696. button: 'button',
  24697. card: 'image, heading',
  24698. 'card-avatar': 'image, list-item-avatar',
  24699. chip: 'chip',
  24700. 'date-picker': 'list-item, heading, divider, date-picker-options, date-picker-days, actions',
  24701. 'date-picker-options': 'text, avatar@2',
  24702. 'date-picker-days': 'avatar@28',
  24703. divider: 'divider',
  24704. heading: 'heading',
  24705. image: 'image',
  24706. 'list-item': 'text',
  24707. 'list-item-avatar': 'avatar, text',
  24708. 'list-item-two-line': 'sentences',
  24709. 'list-item-avatar-two-line': 'avatar, sentences',
  24710. 'list-item-three-line': 'paragraph',
  24711. 'list-item-avatar-three-line': 'avatar, paragraph',
  24712. ossein: 'ossein',
  24713. paragraph: 'text@3',
  24714. sentences: 'text@2',
  24715. subtitle: 'text',
  24716. table: 'table-heading, table-thead, table-tbody, table-tfoot',
  24717. 'table-heading': 'chip, text',
  24718. 'table-thead': 'heading@6',
  24719. 'table-tbody': 'table-row-divider@6',
  24720. 'table-row-divider': 'table-row, divider',
  24721. 'table-row': 'text@6',
  24722. 'table-tfoot': 'text@2, avatar@2',
  24723. text: 'text'
  24724. };
  24725. function genBone(type) {
  24726. let children = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  24727. return createVNode("div", {
  24728. "class": ['v-skeleton-loader__bone', `v-skeleton-loader__${type}`]
  24729. }, [children]);
  24730. }
  24731. function genBones(bone) {
  24732. // e.g. 'text@3'
  24733. const [type, length] = bone.split('@');
  24734. // Generate a length array based upon
  24735. // value after @ in the bone string
  24736. return Array.from({
  24737. length
  24738. }).map(() => genStructure(type));
  24739. }
  24740. function genStructure(type) {
  24741. let children = [];
  24742. if (!type) return children;
  24743. // TODO: figure out a better way to type this
  24744. const bone = rootTypes[type];
  24745. // End of recursion, do nothing
  24746. /* eslint-disable-next-line no-empty, brace-style */
  24747. if (type === bone) ;
  24748. // Array of values - e.g. 'heading, paragraph, text@2'
  24749. else if (type.includes(',')) return mapBones(type);
  24750. // Array of values - e.g. 'paragraph@4'
  24751. else if (type.includes('@')) return genBones(type);
  24752. // Array of values - e.g. 'card@2'
  24753. else if (bone.includes(',')) children = mapBones(bone);
  24754. // Array of values - e.g. 'list-item@2'
  24755. else if (bone.includes('@')) children = genBones(bone);
  24756. // Single value - e.g. 'card-heading'
  24757. else if (bone) children.push(genStructure(bone));
  24758. return [genBone(type, children)];
  24759. }
  24760. function mapBones(bones) {
  24761. // Remove spaces and return array of structures
  24762. return bones.replace(/\s/g, '').split(',').map(genStructure);
  24763. }
  24764. const makeVSkeletonLoaderProps = propsFactory({
  24765. boilerplate: Boolean,
  24766. color: String,
  24767. loading: Boolean,
  24768. loadingText: {
  24769. type: String,
  24770. default: '$vuetify.loading'
  24771. },
  24772. type: {
  24773. type: [String, Array],
  24774. default: 'ossein'
  24775. },
  24776. ...makeDimensionProps(),
  24777. ...makeElevationProps(),
  24778. ...makeThemeProps()
  24779. }, 'VSkeletonLoader');
  24780. const VSkeletonLoader = genericComponent()({
  24781. name: 'VSkeletonLoader',
  24782. props: makeVSkeletonLoaderProps(),
  24783. setup(props, _ref) {
  24784. let {
  24785. slots
  24786. } = _ref;
  24787. const {
  24788. backgroundColorClasses,
  24789. backgroundColorStyles
  24790. } = useBackgroundColor(toRef(props, 'color'));
  24791. const {
  24792. dimensionStyles
  24793. } = useDimension(props);
  24794. const {
  24795. elevationClasses
  24796. } = useElevation(props);
  24797. const {
  24798. themeClasses
  24799. } = provideTheme(props);
  24800. const {
  24801. t
  24802. } = useLocale();
  24803. const items = computed(() => genStructure(wrapInArray(props.type).join(',')));
  24804. useRender(() => {
  24805. const isLoading = !slots.default || props.loading;
  24806. const loadingProps = props.boilerplate || !isLoading ? {} : {
  24807. ariaLive: 'polite',
  24808. ariaLabel: t(props.loadingText),
  24809. role: 'alert'
  24810. };
  24811. return createVNode("div", mergeProps({
  24812. "class": ['v-skeleton-loader', {
  24813. 'v-skeleton-loader--boilerplate': props.boilerplate
  24814. }, themeClasses.value, backgroundColorClasses.value, elevationClasses.value],
  24815. "style": [backgroundColorStyles.value, isLoading ? dimensionStyles.value : {}]
  24816. }, loadingProps), [isLoading ? items.value : slots.default?.()]);
  24817. });
  24818. return {};
  24819. }
  24820. });
  24821. // Composables
  24822. // Types
  24823. const VSlideGroupItem = genericComponent()({
  24824. name: 'VSlideGroupItem',
  24825. props: makeGroupItemProps(),
  24826. emits: {
  24827. 'group:selected': val => true
  24828. },
  24829. setup(props, _ref) {
  24830. let {
  24831. slots
  24832. } = _ref;
  24833. const slideGroupItem = useGroupItem(props, VSlideGroupSymbol);
  24834. return () => slots.default?.({
  24835. isSelected: slideGroupItem.isSelected.value,
  24836. select: slideGroupItem.select,
  24837. toggle: slideGroupItem.toggle,
  24838. selectedClass: slideGroupItem.selectedClass.value
  24839. });
  24840. }
  24841. });
  24842. // Types
  24843. function useCountdown(milliseconds) {
  24844. const time = shallowRef(milliseconds());
  24845. let timer = -1;
  24846. function clear() {
  24847. clearInterval(timer);
  24848. }
  24849. function reset() {
  24850. clear();
  24851. nextTick(() => time.value = milliseconds());
  24852. }
  24853. function start(el) {
  24854. const style = el ? getComputedStyle(el) : {
  24855. transitionDuration: 0.2
  24856. };
  24857. const interval = parseFloat(style.transitionDuration) * 1000 || 200;
  24858. clear();
  24859. if (time.value <= 0) return;
  24860. const startTime = performance.now();
  24861. timer = window.setInterval(() => {
  24862. const elapsed = performance.now() - startTime + interval;
  24863. time.value = Math.max(milliseconds() - elapsed, 0);
  24864. if (time.value <= 0) clear();
  24865. }, interval);
  24866. }
  24867. onScopeDispose(clear);
  24868. return {
  24869. clear,
  24870. time,
  24871. start,
  24872. reset
  24873. };
  24874. }
  24875. const makeVSnackbarProps = propsFactory({
  24876. multiLine: Boolean,
  24877. text: String,
  24878. timer: [Boolean, String],
  24879. timeout: {
  24880. type: [Number, String],
  24881. default: 5000
  24882. },
  24883. vertical: Boolean,
  24884. ...makeLocationProps({
  24885. location: 'bottom'
  24886. }),
  24887. ...makePositionProps(),
  24888. ...makeRoundedProps(),
  24889. ...makeVariantProps(),
  24890. ...makeThemeProps(),
  24891. ...omit(makeVOverlayProps({
  24892. transition: 'v-snackbar-transition'
  24893. }), ['persistent', 'noClickAnimation', 'scrim', 'scrollStrategy'])
  24894. }, 'VSnackbar');
  24895. const VSnackbar = genericComponent()({
  24896. name: 'VSnackbar',
  24897. props: makeVSnackbarProps(),
  24898. emits: {
  24899. 'update:modelValue': v => true
  24900. },
  24901. setup(props, _ref) {
  24902. let {
  24903. slots
  24904. } = _ref;
  24905. const isActive = useProxiedModel(props, 'modelValue');
  24906. const {
  24907. positionClasses
  24908. } = usePosition(props);
  24909. const {
  24910. scopeId
  24911. } = useScopeId();
  24912. const {
  24913. themeClasses
  24914. } = provideTheme(props);
  24915. const {
  24916. colorClasses,
  24917. colorStyles,
  24918. variantClasses
  24919. } = useVariant(props);
  24920. const {
  24921. roundedClasses
  24922. } = useRounded(props);
  24923. const countdown = useCountdown(() => Number(props.timeout));
  24924. const overlay = ref();
  24925. const timerRef = ref();
  24926. const isHovering = shallowRef(false);
  24927. const startY = shallowRef(0);
  24928. const mainStyles = ref();
  24929. const hasLayout = inject$1(VuetifyLayoutKey, undefined);
  24930. useToggleScope(() => !!hasLayout, () => {
  24931. const layout = useLayout();
  24932. watchEffect(() => {
  24933. mainStyles.value = layout.mainStyles.value;
  24934. });
  24935. });
  24936. watch(isActive, startTimeout);
  24937. watch(() => props.timeout, startTimeout);
  24938. onMounted(() => {
  24939. if (isActive.value) startTimeout();
  24940. });
  24941. let activeTimeout = -1;
  24942. function startTimeout() {
  24943. countdown.reset();
  24944. window.clearTimeout(activeTimeout);
  24945. const timeout = Number(props.timeout);
  24946. if (!isActive.value || timeout === -1) return;
  24947. const element = refElement(timerRef.value);
  24948. countdown.start(element);
  24949. activeTimeout = window.setTimeout(() => {
  24950. isActive.value = false;
  24951. }, timeout);
  24952. }
  24953. function clearTimeout() {
  24954. countdown.reset();
  24955. window.clearTimeout(activeTimeout);
  24956. }
  24957. function onPointerenter() {
  24958. isHovering.value = true;
  24959. clearTimeout();
  24960. }
  24961. function onPointerleave() {
  24962. isHovering.value = false;
  24963. startTimeout();
  24964. }
  24965. function onTouchstart(event) {
  24966. startY.value = event.touches[0].clientY;
  24967. }
  24968. function onTouchend(event) {
  24969. if (Math.abs(startY.value - event.changedTouches[0].clientY) > 50) {
  24970. isActive.value = false;
  24971. }
  24972. }
  24973. function onAfterLeave() {
  24974. if (isHovering.value) onPointerleave();
  24975. }
  24976. const locationClasses = computed(() => {
  24977. return props.location.split(' ').reduce((acc, loc) => {
  24978. acc[`v-snackbar--${loc}`] = true;
  24979. return acc;
  24980. }, {});
  24981. });
  24982. useRender(() => {
  24983. const overlayProps = VOverlay.filterProps(props);
  24984. const hasContent = !!(slots.default || slots.text || props.text);
  24985. return createVNode(VOverlay, mergeProps({
  24986. "ref": overlay,
  24987. "class": ['v-snackbar', {
  24988. 'v-snackbar--active': isActive.value,
  24989. 'v-snackbar--multi-line': props.multiLine && !props.vertical,
  24990. 'v-snackbar--timer': !!props.timer,
  24991. 'v-snackbar--vertical': props.vertical
  24992. }, locationClasses.value, positionClasses.value, props.class],
  24993. "style": [mainStyles.value, props.style]
  24994. }, overlayProps, {
  24995. "modelValue": isActive.value,
  24996. "onUpdate:modelValue": $event => isActive.value = $event,
  24997. "contentProps": mergeProps({
  24998. class: ['v-snackbar__wrapper', themeClasses.value, colorClasses.value, roundedClasses.value, variantClasses.value],
  24999. style: [colorStyles.value],
  25000. onPointerenter,
  25001. onPointerleave
  25002. }, overlayProps.contentProps),
  25003. "persistent": true,
  25004. "noClickAnimation": true,
  25005. "scrim": false,
  25006. "scrollStrategy": "none",
  25007. "_disableGlobalStack": true,
  25008. "onTouchstartPassive": onTouchstart,
  25009. "onTouchend": onTouchend,
  25010. "onAfterLeave": onAfterLeave
  25011. }, scopeId), {
  25012. default: () => [genOverlays(false, 'v-snackbar'), props.timer && !isHovering.value && createVNode("div", {
  25013. "key": "timer",
  25014. "class": "v-snackbar__timer"
  25015. }, [createVNode(VProgressLinear, {
  25016. "ref": timerRef,
  25017. "color": typeof props.timer === 'string' ? props.timer : 'info',
  25018. "max": props.timeout,
  25019. "model-value": countdown.time.value
  25020. }, null)]), hasContent && createVNode("div", {
  25021. "key": "content",
  25022. "class": "v-snackbar__content",
  25023. "role": "status",
  25024. "aria-live": "polite"
  25025. }, [slots.text?.() ?? props.text, slots.default?.()]), slots.actions && createVNode(VDefaultsProvider, {
  25026. "defaults": {
  25027. VBtn: {
  25028. variant: 'text',
  25029. ripple: false,
  25030. slim: true
  25031. }
  25032. }
  25033. }, {
  25034. default: () => [createVNode("div", {
  25035. "class": "v-snackbar__actions"
  25036. }, [slots.actions({
  25037. isActive
  25038. })])]
  25039. })],
  25040. activator: slots.activator
  25041. });
  25042. });
  25043. return forwardRefs({}, overlay);
  25044. }
  25045. });
  25046. // Utilities
  25047. // Types
  25048. const makeLineProps = propsFactory({
  25049. autoDraw: Boolean,
  25050. autoDrawDuration: [Number, String],
  25051. autoDrawEasing: {
  25052. type: String,
  25053. default: 'ease'
  25054. },
  25055. color: String,
  25056. gradient: {
  25057. type: Array,
  25058. default: () => []
  25059. },
  25060. gradientDirection: {
  25061. type: String,
  25062. validator: val => ['top', 'bottom', 'left', 'right'].includes(val),
  25063. default: 'top'
  25064. },
  25065. height: {
  25066. type: [String, Number],
  25067. default: 75
  25068. },
  25069. labels: {
  25070. type: Array,
  25071. default: () => []
  25072. },
  25073. labelSize: {
  25074. type: [Number, String],
  25075. default: 7
  25076. },
  25077. lineWidth: {
  25078. type: [String, Number],
  25079. default: 4
  25080. },
  25081. id: String,
  25082. itemValue: {
  25083. type: String,
  25084. default: 'value'
  25085. },
  25086. modelValue: {
  25087. type: Array,
  25088. default: () => []
  25089. },
  25090. min: [String, Number],
  25091. max: [String, Number],
  25092. padding: {
  25093. type: [String, Number],
  25094. default: 8
  25095. },
  25096. showLabels: Boolean,
  25097. smooth: Boolean,
  25098. width: {
  25099. type: [Number, String],
  25100. default: 300
  25101. }
  25102. }, 'Line');
  25103. // Types
  25104. const makeVBarlineProps = propsFactory({
  25105. autoLineWidth: Boolean,
  25106. ...makeLineProps()
  25107. }, 'VBarline');
  25108. const VBarline = genericComponent()({
  25109. name: 'VBarline',
  25110. props: makeVBarlineProps(),
  25111. setup(props, _ref) {
  25112. let {
  25113. slots
  25114. } = _ref;
  25115. const uid = getUid();
  25116. const id = computed(() => props.id || `barline-${uid}`);
  25117. const autoDrawDuration = computed(() => Number(props.autoDrawDuration) || 500);
  25118. const hasLabels = computed(() => {
  25119. return Boolean(props.showLabels || props.labels.length > 0 || !!slots?.label);
  25120. });
  25121. const lineWidth = computed(() => parseFloat(props.lineWidth) || 4);
  25122. const totalWidth = computed(() => Math.max(props.modelValue.length * lineWidth.value, Number(props.width)));
  25123. const boundary = computed(() => {
  25124. return {
  25125. minX: 0,
  25126. maxX: totalWidth.value,
  25127. minY: 0,
  25128. maxY: parseInt(props.height, 10)
  25129. };
  25130. });
  25131. const items = computed(() => props.modelValue.map(item => getPropertyFromItem(item, props.itemValue, item)));
  25132. function genBars(values, boundary) {
  25133. const {
  25134. minX,
  25135. maxX,
  25136. minY,
  25137. maxY
  25138. } = boundary;
  25139. const totalValues = values.length;
  25140. let maxValue = props.max != null ? Number(props.max) : Math.max(...values);
  25141. let minValue = props.min != null ? Number(props.min) : Math.min(...values);
  25142. if (minValue > 0 && props.min == null) minValue = 0;
  25143. if (maxValue < 0 && props.max == null) maxValue = 0;
  25144. const gridX = maxX / totalValues;
  25145. const gridY = (maxY - minY) / (maxValue - minValue || 1);
  25146. const horizonY = maxY - Math.abs(minValue * gridY);
  25147. return values.map((value, index) => {
  25148. const height = Math.abs(gridY * value);
  25149. return {
  25150. x: minX + index * gridX,
  25151. y: horizonY - height + +(value < 0) * height,
  25152. height,
  25153. value
  25154. };
  25155. });
  25156. }
  25157. const parsedLabels = computed(() => {
  25158. const labels = [];
  25159. const points = genBars(items.value, boundary.value);
  25160. const len = points.length;
  25161. for (let i = 0; labels.length < len; i++) {
  25162. const item = points[i];
  25163. let value = props.labels[i];
  25164. if (!value) {
  25165. value = typeof item === 'object' ? item.value : item;
  25166. }
  25167. labels.push({
  25168. x: item.x,
  25169. value: String(value)
  25170. });
  25171. }
  25172. return labels;
  25173. });
  25174. const bars = computed(() => genBars(items.value, boundary.value));
  25175. const offsetX = computed(() => (Math.abs(bars.value[0].x - bars.value[1].x) - lineWidth.value) / 2);
  25176. useRender(() => {
  25177. const gradientData = !props.gradient.slice().length ? [''] : props.gradient.slice().reverse();
  25178. return createVNode("svg", {
  25179. "display": "block"
  25180. }, [createVNode("defs", null, [createVNode("linearGradient", {
  25181. "id": id.value,
  25182. "gradientUnits": "userSpaceOnUse",
  25183. "x1": props.gradientDirection === 'left' ? '100%' : '0',
  25184. "y1": props.gradientDirection === 'top' ? '100%' : '0',
  25185. "x2": props.gradientDirection === 'right' ? '100%' : '0',
  25186. "y2": props.gradientDirection === 'bottom' ? '100%' : '0'
  25187. }, [gradientData.map((color, index) => createVNode("stop", {
  25188. "offset": index / Math.max(gradientData.length - 1, 1),
  25189. "stop-color": color || 'currentColor'
  25190. }, null))])]), createVNode("clipPath", {
  25191. "id": `${id.value}-clip`
  25192. }, [bars.value.map(item => createVNode("rect", {
  25193. "x": item.x + offsetX.value,
  25194. "y": item.y,
  25195. "width": lineWidth.value,
  25196. "height": item.height,
  25197. "rx": typeof props.smooth === 'number' ? props.smooth : props.smooth ? 2 : 0,
  25198. "ry": typeof props.smooth === 'number' ? props.smooth : props.smooth ? 2 : 0
  25199. }, [props.autoDraw && createVNode(Fragment, null, [createVNode("animate", {
  25200. "attributeName": "y",
  25201. "from": item.y + item.height,
  25202. "to": item.y,
  25203. "dur": `${autoDrawDuration.value}ms`,
  25204. "fill": "freeze"
  25205. }, null), createVNode("animate", {
  25206. "attributeName": "height",
  25207. "from": "0",
  25208. "to": item.height,
  25209. "dur": `${autoDrawDuration.value}ms`,
  25210. "fill": "freeze"
  25211. }, null)])]))]), hasLabels.value && createVNode("g", {
  25212. "key": "labels",
  25213. "style": {
  25214. textAnchor: 'middle',
  25215. dominantBaseline: 'mathematical',
  25216. fill: 'currentColor'
  25217. }
  25218. }, [parsedLabels.value.map((item, i) => createVNode("text", {
  25219. "x": item.x + offsetX.value + lineWidth.value / 2,
  25220. "y": parseInt(props.height, 10) - 2 + (parseInt(props.labelSize, 10) || 7 * 0.75),
  25221. "font-size": Number(props.labelSize) || 7
  25222. }, [slots.label?.({
  25223. index: i,
  25224. value: item.value
  25225. }) ?? item.value]))]), createVNode("g", {
  25226. "clip-path": `url(#${id.value}-clip)`,
  25227. "fill": `url(#${id.value})`
  25228. }, [createVNode("rect", {
  25229. "x": 0,
  25230. "y": 0,
  25231. "width": Math.max(props.modelValue.length * lineWidth.value, Number(props.width)),
  25232. "height": props.height
  25233. }, null)])]);
  25234. });
  25235. }
  25236. });
  25237. // @ts-nocheck
  25238. /* eslint-disable */
  25239. // import { checkCollinear, getDistance, moveTo } from './math'
  25240. /**
  25241. * From https://github.com/unsplash/react-trend/blob/master/src/helpers/DOM.helpers.js#L18
  25242. */
  25243. function genPath(points, radius) {
  25244. let fill = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  25245. let height = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 75;
  25246. if (points.length === 0) return '';
  25247. const start = points.shift();
  25248. const end = points[points.length - 1];
  25249. return (fill ? `M${start.x} ${height - start.x + 2} L${start.x} ${start.y}` : `M${start.x} ${start.y}`) + points.map((point, index) => {
  25250. const next = points[index + 1];
  25251. const prev = points[index - 1] || start;
  25252. const isCollinear = next && checkCollinear(next, point, prev);
  25253. if (!next || isCollinear) {
  25254. return `L${point.x} ${point.y}`;
  25255. }
  25256. const threshold = Math.min(getDistance(prev, point), getDistance(next, point));
  25257. const isTooCloseForRadius = threshold / 2 < radius;
  25258. const radiusForPoint = isTooCloseForRadius ? threshold / 2 : radius;
  25259. const before = moveTo(prev, point, radiusForPoint);
  25260. const after = moveTo(next, point, radiusForPoint);
  25261. return `L${before.x} ${before.y}S${point.x} ${point.y} ${after.x} ${after.y}`;
  25262. }).join('') + (fill ? `L${end.x} ${height - start.x + 2} Z` : '');
  25263. }
  25264. function int(value) {
  25265. return parseInt(value, 10);
  25266. }
  25267. /**
  25268. * https://en.wikipedia.org/wiki/Collinearity
  25269. * x=(x1+x2)/2
  25270. * y=(y1+y2)/2
  25271. */
  25272. function checkCollinear(p0, p1, p2) {
  25273. return int(p0.x + p2.x) === int(2 * p1.x) && int(p0.y + p2.y) === int(2 * p1.y);
  25274. }
  25275. function getDistance(p1, p2) {
  25276. return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
  25277. }
  25278. function moveTo(to, from, radius) {
  25279. const vector = {
  25280. x: to.x - from.x,
  25281. y: to.y - from.y
  25282. };
  25283. const length = Math.sqrt(vector.x * vector.x + vector.y * vector.y);
  25284. const unitVector = {
  25285. x: vector.x / length,
  25286. y: vector.y / length
  25287. };
  25288. return {
  25289. x: from.x + unitVector.x * radius,
  25290. y: from.y + unitVector.y * radius
  25291. };
  25292. }
  25293. // Types
  25294. const makeVTrendlineProps = propsFactory({
  25295. fill: Boolean,
  25296. ...makeLineProps()
  25297. }, 'VTrendline');
  25298. const VTrendline = genericComponent()({
  25299. name: 'VTrendline',
  25300. props: makeVTrendlineProps(),
  25301. setup(props, _ref) {
  25302. let {
  25303. slots
  25304. } = _ref;
  25305. const uid = getUid();
  25306. const id = computed(() => props.id || `trendline-${uid}`);
  25307. const autoDrawDuration = computed(() => Number(props.autoDrawDuration) || (props.fill ? 500 : 2000));
  25308. const lastLength = ref(0);
  25309. const path = ref(null);
  25310. function genPoints(values, boundary) {
  25311. const {
  25312. minX,
  25313. maxX,
  25314. minY,
  25315. maxY
  25316. } = boundary;
  25317. const totalValues = values.length;
  25318. const maxValue = props.max != null ? Number(props.max) : Math.max(...values);
  25319. const minValue = props.min != null ? Number(props.min) : Math.min(...values);
  25320. const gridX = (maxX - minX) / (totalValues - 1);
  25321. const gridY = (maxY - minY) / (maxValue - minValue || 1);
  25322. return values.map((value, index) => {
  25323. return {
  25324. x: minX + index * gridX,
  25325. y: maxY - (value - minValue) * gridY,
  25326. value
  25327. };
  25328. });
  25329. }
  25330. const hasLabels = computed(() => {
  25331. return Boolean(props.showLabels || props.labels.length > 0 || !!slots?.label);
  25332. });
  25333. const lineWidth = computed(() => {
  25334. return parseFloat(props.lineWidth) || 4;
  25335. });
  25336. const totalWidth = computed(() => Number(props.width));
  25337. const boundary = computed(() => {
  25338. const padding = Number(props.padding);
  25339. return {
  25340. minX: padding,
  25341. maxX: totalWidth.value - padding,
  25342. minY: padding,
  25343. maxY: parseInt(props.height, 10) - padding
  25344. };
  25345. });
  25346. const items = computed(() => props.modelValue.map(item => getPropertyFromItem(item, props.itemValue, item)));
  25347. const parsedLabels = computed(() => {
  25348. const labels = [];
  25349. const points = genPoints(items.value, boundary.value);
  25350. const len = points.length;
  25351. for (let i = 0; labels.length < len; i++) {
  25352. const item = points[i];
  25353. let value = props.labels[i];
  25354. if (!value) {
  25355. value = typeof item === 'object' ? item.value : item;
  25356. }
  25357. labels.push({
  25358. x: item.x,
  25359. value: String(value)
  25360. });
  25361. }
  25362. return labels;
  25363. });
  25364. watch(() => props.modelValue, async () => {
  25365. await nextTick();
  25366. if (!props.autoDraw || !path.value) return;
  25367. const pathRef = path.value;
  25368. const length = pathRef.getTotalLength();
  25369. if (!props.fill) {
  25370. // Initial setup to "hide" the line by using the stroke dash array
  25371. pathRef.style.strokeDasharray = `${length}`;
  25372. pathRef.style.strokeDashoffset = `${length}`;
  25373. // Force reflow to ensure the transition starts from this state
  25374. pathRef.getBoundingClientRect();
  25375. // Animate the stroke dash offset to "draw" the line
  25376. pathRef.style.transition = `stroke-dashoffset ${autoDrawDuration.value}ms ${props.autoDrawEasing}`;
  25377. pathRef.style.strokeDashoffset = '0';
  25378. } else {
  25379. // Your existing logic for filled paths remains the same
  25380. pathRef.style.transformOrigin = 'bottom center';
  25381. pathRef.style.transition = 'none';
  25382. pathRef.style.transform = `scaleY(0)`;
  25383. pathRef.getBoundingClientRect();
  25384. pathRef.style.transition = `transform ${autoDrawDuration.value}ms ${props.autoDrawEasing}`;
  25385. pathRef.style.transform = `scaleY(1)`;
  25386. }
  25387. lastLength.value = length;
  25388. }, {
  25389. immediate: true
  25390. });
  25391. function genPath$1(fill) {
  25392. return genPath(genPoints(items.value, boundary.value), props.smooth ? 8 : Number(props.smooth), fill, parseInt(props.height, 10));
  25393. }
  25394. useRender(() => {
  25395. const gradientData = !props.gradient.slice().length ? [''] : props.gradient.slice().reverse();
  25396. return createVNode("svg", {
  25397. "display": "block",
  25398. "stroke-width": parseFloat(props.lineWidth) ?? 4
  25399. }, [createVNode("defs", null, [createVNode("linearGradient", {
  25400. "id": id.value,
  25401. "gradientUnits": "userSpaceOnUse",
  25402. "x1": props.gradientDirection === 'left' ? '100%' : '0',
  25403. "y1": props.gradientDirection === 'top' ? '100%' : '0',
  25404. "x2": props.gradientDirection === 'right' ? '100%' : '0',
  25405. "y2": props.gradientDirection === 'bottom' ? '100%' : '0'
  25406. }, [gradientData.map((color, index) => createVNode("stop", {
  25407. "offset": index / Math.max(gradientData.length - 1, 1),
  25408. "stop-color": color || 'currentColor'
  25409. }, null))])]), hasLabels.value && createVNode("g", {
  25410. "key": "labels",
  25411. "style": {
  25412. textAnchor: 'middle',
  25413. dominantBaseline: 'mathematical',
  25414. fill: 'currentColor'
  25415. }
  25416. }, [parsedLabels.value.map((item, i) => createVNode("text", {
  25417. "x": item.x + lineWidth.value / 2 + lineWidth.value / 2,
  25418. "y": parseInt(props.height, 10) - 4 + (parseInt(props.labelSize, 10) || 7 * 0.75),
  25419. "font-size": Number(props.labelSize) || 7
  25420. }, [slots.label?.({
  25421. index: i,
  25422. value: item.value
  25423. }) ?? item.value]))]), createVNode("path", {
  25424. "ref": path,
  25425. "d": genPath$1(props.fill),
  25426. "fill": props.fill ? `url(#${id.value})` : 'none',
  25427. "stroke": props.fill ? 'none' : `url(#${id.value})`
  25428. }, null), props.fill && createVNode("path", {
  25429. "d": genPath$1(false),
  25430. "fill": "none",
  25431. "stroke": props.color ?? props.gradient?.[0]
  25432. }, null)]);
  25433. });
  25434. }
  25435. });
  25436. // Types
  25437. // Types
  25438. const makeVSparklineProps = propsFactory({
  25439. type: {
  25440. type: String,
  25441. default: 'trend'
  25442. },
  25443. ...makeVBarlineProps(),
  25444. ...makeVTrendlineProps()
  25445. }, 'VSparkline');
  25446. const VSparkline = genericComponent()({
  25447. name: 'VSparkline',
  25448. props: makeVSparklineProps(),
  25449. setup(props, _ref) {
  25450. let {
  25451. slots
  25452. } = _ref;
  25453. const {
  25454. textColorClasses,
  25455. textColorStyles
  25456. } = useTextColor(toRef(props, 'color'));
  25457. const hasLabels = computed(() => {
  25458. return Boolean(props.showLabels || props.labels.length > 0 || !!slots?.label);
  25459. });
  25460. const totalHeight = computed(() => {
  25461. let height = parseInt(props.height, 10);
  25462. if (hasLabels.value) height += parseInt(props.labelSize, 10) * 1.5;
  25463. return height;
  25464. });
  25465. useRender(() => {
  25466. const Tag = props.type === 'trend' ? VTrendline : VBarline;
  25467. const lineProps = props.type === 'trend' ? VTrendline.filterProps(props) : VBarline.filterProps(props);
  25468. return createVNode(Tag, mergeProps({
  25469. "key": props.type,
  25470. "class": textColorClasses.value,
  25471. "style": textColorStyles.value,
  25472. "viewBox": `0 0 ${props.width} ${parseInt(totalHeight.value, 10)}`
  25473. }, lineProps), slots);
  25474. });
  25475. }
  25476. });
  25477. // Types
  25478. const makeVSpeedDialProps = propsFactory({
  25479. ...makeComponentProps(),
  25480. ...makeVMenuProps({
  25481. offset: 8,
  25482. minWidth: 0,
  25483. openDelay: 0,
  25484. closeDelay: 100,
  25485. location: 'top center',
  25486. transition: 'scale-transition'
  25487. })
  25488. }, 'VSpeedDial');
  25489. const VSpeedDial = genericComponent()({
  25490. name: 'VSpeedDial',
  25491. props: makeVSpeedDialProps(),
  25492. emits: {
  25493. 'update:modelValue': value => true
  25494. },
  25495. setup(props, _ref) {
  25496. let {
  25497. slots
  25498. } = _ref;
  25499. const model = useProxiedModel(props, 'modelValue');
  25500. const menuRef = ref();
  25501. const location = computed(() => {
  25502. const [y, x = 'center'] = props.location?.split(' ') ?? [];
  25503. return `${y} ${x}`;
  25504. });
  25505. const locationClasses = computed(() => ({
  25506. [`v-speed-dial__content--${location.value.replace(' ', '-')}`]: true
  25507. }));
  25508. useRender(() => {
  25509. const menuProps = VMenu.filterProps(props);
  25510. return createVNode(VMenu, mergeProps(menuProps, {
  25511. "modelValue": model.value,
  25512. "onUpdate:modelValue": $event => model.value = $event,
  25513. "class": props.class,
  25514. "style": props.style,
  25515. "contentClass": ['v-speed-dial__content', locationClasses.value, props.contentClass],
  25516. "location": location.value,
  25517. "ref": menuRef,
  25518. "transition": "fade-transition"
  25519. }), {
  25520. ...slots,
  25521. default: slotProps => createVNode(VDefaultsProvider, {
  25522. "defaults": {
  25523. VBtn: {
  25524. size: 'small'
  25525. }
  25526. }
  25527. }, {
  25528. default: () => [createVNode(MaybeTransition, {
  25529. "appear": true,
  25530. "group": true,
  25531. "transition": props.transition
  25532. }, {
  25533. default: () => [slots.default?.(slotProps)]
  25534. })]
  25535. })
  25536. });
  25537. });
  25538. return {};
  25539. }
  25540. });
  25541. // Types
  25542. const VStepperSymbol = Symbol.for('vuetify:v-stepper');
  25543. // Types
  25544. const makeVStepperActionsProps = propsFactory({
  25545. color: String,
  25546. disabled: {
  25547. type: [Boolean, String],
  25548. default: false
  25549. },
  25550. prevText: {
  25551. type: String,
  25552. default: '$vuetify.stepper.prev'
  25553. },
  25554. nextText: {
  25555. type: String,
  25556. default: '$vuetify.stepper.next'
  25557. }
  25558. }, 'VStepperActions');
  25559. const VStepperActions = genericComponent()({
  25560. name: 'VStepperActions',
  25561. props: makeVStepperActionsProps(),
  25562. emits: {
  25563. 'click:prev': () => true,
  25564. 'click:next': () => true
  25565. },
  25566. setup(props, _ref) {
  25567. let {
  25568. emit,
  25569. slots
  25570. } = _ref;
  25571. const {
  25572. t
  25573. } = useLocale();
  25574. function onClickPrev() {
  25575. emit('click:prev');
  25576. }
  25577. function onClickNext() {
  25578. emit('click:next');
  25579. }
  25580. useRender(() => {
  25581. const prevSlotProps = {
  25582. onClick: onClickPrev
  25583. };
  25584. const nextSlotProps = {
  25585. onClick: onClickNext
  25586. };
  25587. return createVNode("div", {
  25588. "class": "v-stepper-actions"
  25589. }, [createVNode(VDefaultsProvider, {
  25590. "defaults": {
  25591. VBtn: {
  25592. disabled: ['prev', true].includes(props.disabled),
  25593. text: t(props.prevText),
  25594. variant: 'text'
  25595. }
  25596. }
  25597. }, {
  25598. default: () => [slots.prev?.({
  25599. props: prevSlotProps
  25600. }) ?? createVNode(VBtn, prevSlotProps, null)]
  25601. }), createVNode(VDefaultsProvider, {
  25602. "defaults": {
  25603. VBtn: {
  25604. color: props.color,
  25605. disabled: ['next', true].includes(props.disabled),
  25606. text: t(props.nextText),
  25607. variant: 'tonal'
  25608. }
  25609. }
  25610. }, {
  25611. default: () => [slots.next?.({
  25612. props: nextSlotProps
  25613. }) ?? createVNode(VBtn, nextSlotProps, null)]
  25614. })]);
  25615. });
  25616. return {};
  25617. }
  25618. });
  25619. // Utilities
  25620. const VStepperHeader = createSimpleFunctional('v-stepper-header');
  25621. // Types
  25622. const makeStepperItemProps = propsFactory({
  25623. color: String,
  25624. title: String,
  25625. subtitle: String,
  25626. complete: Boolean,
  25627. completeIcon: {
  25628. type: IconValue,
  25629. default: '$complete'
  25630. },
  25631. editable: Boolean,
  25632. editIcon: {
  25633. type: IconValue,
  25634. default: '$edit'
  25635. },
  25636. error: Boolean,
  25637. errorIcon: {
  25638. type: IconValue,
  25639. default: '$error'
  25640. },
  25641. icon: IconValue,
  25642. ripple: {
  25643. type: [Boolean, Object],
  25644. default: true
  25645. },
  25646. rules: {
  25647. type: Array,
  25648. default: () => []
  25649. }
  25650. }, 'StepperItem');
  25651. const makeVStepperItemProps = propsFactory({
  25652. ...makeStepperItemProps(),
  25653. ...makeGroupItemProps()
  25654. }, 'VStepperItem');
  25655. const VStepperItem = genericComponent()({
  25656. name: 'VStepperItem',
  25657. directives: {
  25658. Ripple
  25659. },
  25660. props: makeVStepperItemProps(),
  25661. emits: {
  25662. 'group:selected': val => true
  25663. },
  25664. setup(props, _ref) {
  25665. let {
  25666. slots
  25667. } = _ref;
  25668. const group = useGroupItem(props, VStepperSymbol, true);
  25669. const step = computed(() => group?.value.value ?? props.value);
  25670. const isValid = computed(() => props.rules.every(handler => handler() === true));
  25671. const isClickable = computed(() => !props.disabled && props.editable);
  25672. const canEdit = computed(() => !props.disabled && props.editable);
  25673. const hasError = computed(() => props.error || !isValid.value);
  25674. const hasCompleted = computed(() => props.complete || props.rules.length > 0 && isValid.value);
  25675. const icon = computed(() => {
  25676. if (hasError.value) return props.errorIcon;
  25677. if (hasCompleted.value) return props.completeIcon;
  25678. if (group.isSelected.value && props.editable) return props.editIcon;
  25679. return props.icon;
  25680. });
  25681. const slotProps = computed(() => ({
  25682. canEdit: canEdit.value,
  25683. hasError: hasError.value,
  25684. hasCompleted: hasCompleted.value,
  25685. title: props.title,
  25686. subtitle: props.subtitle,
  25687. step: step.value,
  25688. value: props.value
  25689. }));
  25690. useRender(() => {
  25691. const hasColor = (!group || group.isSelected.value || hasCompleted.value || canEdit.value) && !hasError.value && !props.disabled;
  25692. const hasTitle = !!(props.title != null || slots.title);
  25693. const hasSubtitle = !!(props.subtitle != null || slots.subtitle);
  25694. function onClick() {
  25695. group?.toggle();
  25696. }
  25697. return withDirectives(createVNode("button", {
  25698. "class": ['v-stepper-item', {
  25699. 'v-stepper-item--complete': hasCompleted.value,
  25700. 'v-stepper-item--disabled': props.disabled,
  25701. 'v-stepper-item--error': hasError.value
  25702. }, group?.selectedClass.value],
  25703. "disabled": !props.editable,
  25704. "onClick": onClick
  25705. }, [isClickable.value && genOverlays(true, 'v-stepper-item'), createVNode(VAvatar, {
  25706. "key": "stepper-avatar",
  25707. "class": "v-stepper-item__avatar",
  25708. "color": hasColor ? props.color : undefined,
  25709. "size": 24
  25710. }, {
  25711. default: () => [slots.icon?.(slotProps.value) ?? (icon.value ? createVNode(VIcon, {
  25712. "icon": icon.value
  25713. }, null) : step.value)]
  25714. }), createVNode("div", {
  25715. "class": "v-stepper-item__content"
  25716. }, [hasTitle && createVNode("div", {
  25717. "key": "title",
  25718. "class": "v-stepper-item__title"
  25719. }, [slots.title?.(slotProps.value) ?? props.title]), hasSubtitle && createVNode("div", {
  25720. "key": "subtitle",
  25721. "class": "v-stepper-item__subtitle"
  25722. }, [slots.subtitle?.(slotProps.value) ?? props.subtitle]), slots.default?.(slotProps.value)])]), [[resolveDirective("ripple"), props.ripple && props.editable, null]]);
  25723. });
  25724. return {};
  25725. }
  25726. });
  25727. const makeVStepperWindowProps = propsFactory({
  25728. ...omit(makeVWindowProps(), ['continuous', 'nextIcon', 'prevIcon', 'showArrows', 'touch', 'mandatory'])
  25729. }, 'VStepperWindow');
  25730. const VStepperWindow = genericComponent()({
  25731. name: 'VStepperWindow',
  25732. props: makeVStepperWindowProps(),
  25733. emits: {
  25734. 'update:modelValue': v => true
  25735. },
  25736. setup(props, _ref) {
  25737. let {
  25738. slots
  25739. } = _ref;
  25740. const group = inject$1(VStepperSymbol, null);
  25741. const _model = useProxiedModel(props, 'modelValue');
  25742. const model = computed({
  25743. get() {
  25744. // Always return modelValue if defined
  25745. // or if not within a VStepper group
  25746. if (_model.value != null || !group) return _model.value;
  25747. // If inside of a VStepper, find the currently selected
  25748. // item by id. Item value may be assigned by its index
  25749. return group.items.value.find(item => group.selected.value.includes(item.id))?.value;
  25750. },
  25751. set(val) {
  25752. _model.value = val;
  25753. }
  25754. });
  25755. useRender(() => {
  25756. const windowProps = VWindow.filterProps(props);
  25757. return createVNode(VWindow, mergeProps({
  25758. "_as": "VStepperWindow"
  25759. }, windowProps, {
  25760. "modelValue": model.value,
  25761. "onUpdate:modelValue": $event => model.value = $event,
  25762. "class": ['v-stepper-window', props.class],
  25763. "style": props.style,
  25764. "mandatory": false,
  25765. "touch": false
  25766. }), slots);
  25767. });
  25768. return {};
  25769. }
  25770. });
  25771. const makeVStepperWindowItemProps = propsFactory({
  25772. ...makeVWindowItemProps()
  25773. }, 'VStepperWindowItem');
  25774. const VStepperWindowItem = genericComponent()({
  25775. name: 'VStepperWindowItem',
  25776. props: makeVStepperWindowItemProps(),
  25777. setup(props, _ref) {
  25778. let {
  25779. slots
  25780. } = _ref;
  25781. useRender(() => {
  25782. const windowItemProps = VWindowItem.filterProps(props);
  25783. return createVNode(VWindowItem, mergeProps({
  25784. "_as": "VStepperWindowItem"
  25785. }, windowItemProps, {
  25786. "class": ['v-stepper-window-item', props.class],
  25787. "style": props.style
  25788. }), slots);
  25789. });
  25790. return {};
  25791. }
  25792. });
  25793. // Types
  25794. const makeStepperProps = propsFactory({
  25795. altLabels: Boolean,
  25796. bgColor: String,
  25797. completeIcon: IconValue,
  25798. editIcon: IconValue,
  25799. editable: Boolean,
  25800. errorIcon: IconValue,
  25801. hideActions: Boolean,
  25802. items: {
  25803. type: Array,
  25804. default: () => []
  25805. },
  25806. itemTitle: {
  25807. type: String,
  25808. default: 'title'
  25809. },
  25810. itemValue: {
  25811. type: String,
  25812. default: 'value'
  25813. },
  25814. nonLinear: Boolean,
  25815. flat: Boolean,
  25816. ...makeDisplayProps()
  25817. }, 'Stepper');
  25818. const makeVStepperProps = propsFactory({
  25819. ...makeStepperProps(),
  25820. ...makeGroupProps({
  25821. mandatory: 'force',
  25822. selectedClass: 'v-stepper-item--selected'
  25823. }),
  25824. ...makeVSheetProps(),
  25825. ...only(makeVStepperActionsProps(), ['prevText', 'nextText'])
  25826. }, 'VStepper');
  25827. const VStepper = genericComponent()({
  25828. name: 'VStepper',
  25829. props: makeVStepperProps(),
  25830. emits: {
  25831. 'update:modelValue': v => true
  25832. },
  25833. setup(props, _ref) {
  25834. let {
  25835. slots
  25836. } = _ref;
  25837. const {
  25838. items: _items,
  25839. next,
  25840. prev,
  25841. selected
  25842. } = useGroup(props, VStepperSymbol);
  25843. const {
  25844. displayClasses,
  25845. mobile
  25846. } = useDisplay(props);
  25847. const {
  25848. completeIcon,
  25849. editIcon,
  25850. errorIcon,
  25851. color,
  25852. editable,
  25853. prevText,
  25854. nextText
  25855. } = toRefs(props);
  25856. const items = computed(() => props.items.map((item, index) => {
  25857. const title = getPropertyFromItem(item, props.itemTitle, item);
  25858. const value = getPropertyFromItem(item, props.itemValue, index + 1);
  25859. return {
  25860. title,
  25861. value,
  25862. raw: item
  25863. };
  25864. }));
  25865. const activeIndex = computed(() => {
  25866. return _items.value.findIndex(item => selected.value.includes(item.id));
  25867. });
  25868. const disabled = computed(() => {
  25869. if (props.disabled) return props.disabled;
  25870. if (activeIndex.value === 0) return 'prev';
  25871. if (activeIndex.value === _items.value.length - 1) return 'next';
  25872. return false;
  25873. });
  25874. provideDefaults({
  25875. VStepperItem: {
  25876. editable,
  25877. errorIcon,
  25878. completeIcon,
  25879. editIcon,
  25880. prevText,
  25881. nextText
  25882. },
  25883. VStepperActions: {
  25884. color,
  25885. disabled,
  25886. prevText,
  25887. nextText
  25888. }
  25889. });
  25890. useRender(() => {
  25891. const sheetProps = VSheet.filterProps(props);
  25892. const hasHeader = !!(slots.header || props.items.length);
  25893. const hasWindow = props.items.length > 0;
  25894. const hasActions = !props.hideActions && !!(hasWindow || slots.actions);
  25895. return createVNode(VSheet, mergeProps(sheetProps, {
  25896. "color": props.bgColor,
  25897. "class": ['v-stepper', {
  25898. 'v-stepper--alt-labels': props.altLabels,
  25899. 'v-stepper--flat': props.flat,
  25900. 'v-stepper--non-linear': props.nonLinear,
  25901. 'v-stepper--mobile': mobile.value
  25902. }, displayClasses.value, props.class],
  25903. "style": props.style
  25904. }), {
  25905. default: () => [hasHeader && createVNode(VStepperHeader, {
  25906. "key": "stepper-header"
  25907. }, {
  25908. default: () => [items.value.map((_ref2, index) => {
  25909. let {
  25910. raw,
  25911. ...item
  25912. } = _ref2;
  25913. return createVNode(Fragment, null, [!!index && createVNode(VDivider, null, null), createVNode(VStepperItem, item, {
  25914. default: slots[`header-item.${item.value}`] ?? slots.header,
  25915. icon: slots.icon,
  25916. title: slots.title,
  25917. subtitle: slots.subtitle
  25918. })]);
  25919. })]
  25920. }), hasWindow && createVNode(VStepperWindow, {
  25921. "key": "stepper-window"
  25922. }, {
  25923. default: () => [items.value.map(item => createVNode(VStepperWindowItem, {
  25924. "value": item.value
  25925. }, {
  25926. default: () => slots[`item.${item.value}`]?.(item) ?? slots.item?.(item)
  25927. }))]
  25928. }), slots.default?.({
  25929. prev,
  25930. next
  25931. }), hasActions && (slots.actions?.({
  25932. next,
  25933. prev
  25934. }) ?? createVNode(VStepperActions, {
  25935. "key": "stepper-actions",
  25936. "onClick:prev": prev,
  25937. "onClick:next": next
  25938. }, slots))]
  25939. });
  25940. });
  25941. return {
  25942. prev,
  25943. next
  25944. };
  25945. }
  25946. });
  25947. // Types
  25948. const makeVSwitchProps = propsFactory({
  25949. indeterminate: Boolean,
  25950. inset: Boolean,
  25951. flat: Boolean,
  25952. loading: {
  25953. type: [Boolean, String],
  25954. default: false
  25955. },
  25956. ...makeVInputProps(),
  25957. ...makeVSelectionControlProps()
  25958. }, 'VSwitch');
  25959. const VSwitch = genericComponent()({
  25960. name: 'VSwitch',
  25961. inheritAttrs: false,
  25962. props: makeVSwitchProps(),
  25963. emits: {
  25964. 'update:focused': focused => true,
  25965. 'update:modelValue': value => true,
  25966. 'update:indeterminate': value => true
  25967. },
  25968. setup(props, _ref) {
  25969. let {
  25970. attrs,
  25971. slots
  25972. } = _ref;
  25973. const indeterminate = useProxiedModel(props, 'indeterminate');
  25974. const model = useProxiedModel(props, 'modelValue');
  25975. const {
  25976. loaderClasses
  25977. } = useLoader(props);
  25978. const {
  25979. isFocused,
  25980. focus,
  25981. blur
  25982. } = useFocus(props);
  25983. const control = ref();
  25984. const isForcedColorsModeActive = IN_BROWSER && window.matchMedia('(forced-colors: active)').matches;
  25985. const loaderColor = computed(() => {
  25986. return typeof props.loading === 'string' && props.loading !== '' ? props.loading : props.color;
  25987. });
  25988. const uid = getUid();
  25989. const id = computed(() => props.id || `switch-${uid}`);
  25990. function onChange() {
  25991. if (indeterminate.value) {
  25992. indeterminate.value = false;
  25993. }
  25994. }
  25995. function onTrackClick(e) {
  25996. e.stopPropagation();
  25997. e.preventDefault();
  25998. control.value?.input?.click();
  25999. }
  26000. useRender(() => {
  26001. const [rootAttrs, controlAttrs] = filterInputAttrs(attrs);
  26002. const inputProps = VInput.filterProps(props);
  26003. const controlProps = VSelectionControl.filterProps(props);
  26004. return createVNode(VInput, mergeProps({
  26005. "class": ['v-switch', {
  26006. 'v-switch--flat': props.flat
  26007. }, {
  26008. 'v-switch--inset': props.inset
  26009. }, {
  26010. 'v-switch--indeterminate': indeterminate.value
  26011. }, loaderClasses.value, props.class]
  26012. }, rootAttrs, inputProps, {
  26013. "modelValue": model.value,
  26014. "onUpdate:modelValue": $event => model.value = $event,
  26015. "id": id.value,
  26016. "focused": isFocused.value,
  26017. "style": props.style
  26018. }), {
  26019. ...slots,
  26020. default: _ref2 => {
  26021. let {
  26022. id,
  26023. messagesId,
  26024. isDisabled,
  26025. isReadonly,
  26026. isValid
  26027. } = _ref2;
  26028. const slotProps = {
  26029. model,
  26030. isValid
  26031. };
  26032. return createVNode(VSelectionControl, mergeProps({
  26033. "ref": control
  26034. }, controlProps, {
  26035. "modelValue": model.value,
  26036. "onUpdate:modelValue": [$event => model.value = $event, onChange],
  26037. "id": id.value,
  26038. "aria-describedby": messagesId.value,
  26039. "type": "checkbox",
  26040. "aria-checked": indeterminate.value ? 'mixed' : undefined,
  26041. "disabled": isDisabled.value,
  26042. "readonly": isReadonly.value,
  26043. "onFocus": focus,
  26044. "onBlur": blur
  26045. }, controlAttrs), {
  26046. ...slots,
  26047. default: _ref3 => {
  26048. let {
  26049. backgroundColorClasses,
  26050. backgroundColorStyles
  26051. } = _ref3;
  26052. return createVNode("div", {
  26053. "class": ['v-switch__track', !isForcedColorsModeActive ? backgroundColorClasses.value : undefined],
  26054. "style": backgroundColorStyles.value,
  26055. "onClick": onTrackClick
  26056. }, [slots['track-true'] && createVNode("div", {
  26057. "key": "prepend",
  26058. "class": "v-switch__track-true"
  26059. }, [slots['track-true'](slotProps)]), slots['track-false'] && createVNode("div", {
  26060. "key": "append",
  26061. "class": "v-switch__track-false"
  26062. }, [slots['track-false'](slotProps)])]);
  26063. },
  26064. input: _ref4 => {
  26065. let {
  26066. inputNode,
  26067. icon,
  26068. backgroundColorClasses,
  26069. backgroundColorStyles
  26070. } = _ref4;
  26071. return createVNode(Fragment, null, [inputNode, createVNode("div", {
  26072. "class": ['v-switch__thumb', {
  26073. 'v-switch__thumb--filled': icon || props.loading
  26074. }, props.inset || isForcedColorsModeActive ? undefined : backgroundColorClasses.value],
  26075. "style": props.inset ? undefined : backgroundColorStyles.value
  26076. }, [slots.thumb ? createVNode(VDefaultsProvider, {
  26077. "defaults": {
  26078. VIcon: {
  26079. icon,
  26080. size: 'x-small'
  26081. }
  26082. }
  26083. }, {
  26084. default: () => [slots.thumb({
  26085. ...slotProps,
  26086. icon
  26087. })]
  26088. }) : createVNode(VScaleTransition, null, {
  26089. default: () => [!props.loading ? icon && createVNode(VIcon, {
  26090. "key": String(icon),
  26091. "icon": icon,
  26092. "size": "x-small"
  26093. }, null) : createVNode(LoaderSlot, {
  26094. "name": "v-switch",
  26095. "active": true,
  26096. "color": isValid.value === false ? undefined : loaderColor.value
  26097. }, {
  26098. default: slotProps => slots.loader ? slots.loader(slotProps) : createVNode(VProgressCircular, {
  26099. "active": slotProps.isActive,
  26100. "color": slotProps.color,
  26101. "indeterminate": true,
  26102. "size": "16",
  26103. "width": "2"
  26104. }, null)
  26105. })]
  26106. })])]);
  26107. }
  26108. });
  26109. }
  26110. });
  26111. });
  26112. return {};
  26113. }
  26114. });
  26115. const makeVSystemBarProps = propsFactory({
  26116. color: String,
  26117. height: [Number, String],
  26118. window: Boolean,
  26119. ...makeComponentProps(),
  26120. ...makeElevationProps(),
  26121. ...makeLayoutItemProps(),
  26122. ...makeRoundedProps(),
  26123. ...makeTagProps(),
  26124. ...makeThemeProps()
  26125. }, 'VSystemBar');
  26126. const VSystemBar = genericComponent()({
  26127. name: 'VSystemBar',
  26128. props: makeVSystemBarProps(),
  26129. setup(props, _ref) {
  26130. let {
  26131. slots
  26132. } = _ref;
  26133. const {
  26134. themeClasses
  26135. } = provideTheme(props);
  26136. const {
  26137. backgroundColorClasses,
  26138. backgroundColorStyles
  26139. } = useBackgroundColor(toRef(props, 'color'));
  26140. const {
  26141. elevationClasses
  26142. } = useElevation(props);
  26143. const {
  26144. roundedClasses
  26145. } = useRounded(props);
  26146. const {
  26147. ssrBootStyles
  26148. } = useSsrBoot();
  26149. const height = computed(() => props.height ?? (props.window ? 32 : 24));
  26150. const {
  26151. layoutItemStyles
  26152. } = useLayoutItem({
  26153. id: props.name,
  26154. order: computed(() => parseInt(props.order, 10)),
  26155. position: shallowRef('top'),
  26156. layoutSize: height,
  26157. elementSize: height,
  26158. active: computed(() => true),
  26159. absolute: toRef(props, 'absolute')
  26160. });
  26161. useRender(() => createVNode(props.tag, {
  26162. "class": ['v-system-bar', {
  26163. 'v-system-bar--window': props.window
  26164. }, themeClasses.value, backgroundColorClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  26165. "style": [backgroundColorStyles.value, layoutItemStyles.value, ssrBootStyles.value, props.style]
  26166. }, slots));
  26167. return {};
  26168. }
  26169. });
  26170. // Types
  26171. const VTabsSymbol = Symbol.for('vuetify:v-tabs');
  26172. // Types
  26173. const makeVTabProps = propsFactory({
  26174. fixed: Boolean,
  26175. sliderColor: String,
  26176. hideSlider: Boolean,
  26177. direction: {
  26178. type: String,
  26179. default: 'horizontal'
  26180. },
  26181. ...omit(makeVBtnProps({
  26182. selectedClass: 'v-tab--selected',
  26183. variant: 'text'
  26184. }), ['active', 'block', 'flat', 'location', 'position', 'symbol'])
  26185. }, 'VTab');
  26186. const VTab = genericComponent()({
  26187. name: 'VTab',
  26188. props: makeVTabProps(),
  26189. setup(props, _ref) {
  26190. let {
  26191. slots,
  26192. attrs
  26193. } = _ref;
  26194. const {
  26195. textColorClasses: sliderColorClasses,
  26196. textColorStyles: sliderColorStyles
  26197. } = useTextColor(props, 'sliderColor');
  26198. const rootEl = ref();
  26199. const sliderEl = ref();
  26200. const isHorizontal = computed(() => props.direction === 'horizontal');
  26201. const isSelected = computed(() => rootEl.value?.group?.isSelected.value ?? false);
  26202. function updateSlider(_ref2) {
  26203. let {
  26204. value
  26205. } = _ref2;
  26206. if (value) {
  26207. const prevEl = rootEl.value?.$el.parentElement?.querySelector('.v-tab--selected .v-tab__slider');
  26208. const nextEl = sliderEl.value;
  26209. if (!prevEl || !nextEl) return;
  26210. const color = getComputedStyle(prevEl).color;
  26211. const prevBox = prevEl.getBoundingClientRect();
  26212. const nextBox = nextEl.getBoundingClientRect();
  26213. const xy = isHorizontal.value ? 'x' : 'y';
  26214. const XY = isHorizontal.value ? 'X' : 'Y';
  26215. const rightBottom = isHorizontal.value ? 'right' : 'bottom';
  26216. const widthHeight = isHorizontal.value ? 'width' : 'height';
  26217. const prevPos = prevBox[xy];
  26218. const nextPos = nextBox[xy];
  26219. const delta = prevPos > nextPos ? prevBox[rightBottom] - nextBox[rightBottom] : prevBox[xy] - nextBox[xy];
  26220. const origin = Math.sign(delta) > 0 ? isHorizontal.value ? 'right' : 'bottom' : Math.sign(delta) < 0 ? isHorizontal.value ? 'left' : 'top' : 'center';
  26221. const size = Math.abs(delta) + (Math.sign(delta) < 0 ? prevBox[widthHeight] : nextBox[widthHeight]);
  26222. const scale = size / Math.max(prevBox[widthHeight], nextBox[widthHeight]) || 0;
  26223. const initialScale = prevBox[widthHeight] / nextBox[widthHeight] || 0;
  26224. const sigma = 1.5;
  26225. animate(nextEl, {
  26226. backgroundColor: [color, 'currentcolor'],
  26227. transform: [`translate${XY}(${delta}px) scale${XY}(${initialScale})`, `translate${XY}(${delta / sigma}px) scale${XY}(${(scale - 1) / sigma + 1})`, 'none'],
  26228. transformOrigin: Array(3).fill(origin)
  26229. }, {
  26230. duration: 225,
  26231. easing: standardEasing
  26232. });
  26233. }
  26234. }
  26235. useRender(() => {
  26236. const btnProps = VBtn.filterProps(props);
  26237. return createVNode(VBtn, mergeProps({
  26238. "symbol": VTabsSymbol,
  26239. "ref": rootEl,
  26240. "class": ['v-tab', props.class],
  26241. "style": props.style,
  26242. "tabindex": isSelected.value ? 0 : -1,
  26243. "role": "tab",
  26244. "aria-selected": String(isSelected.value),
  26245. "active": false
  26246. }, btnProps, attrs, {
  26247. "block": props.fixed,
  26248. "maxWidth": props.fixed ? 300 : undefined,
  26249. "onGroup:selected": updateSlider
  26250. }), {
  26251. ...slots,
  26252. default: () => createVNode(Fragment, null, [slots.default?.() ?? props.text, !props.hideSlider && createVNode("div", {
  26253. "ref": sliderEl,
  26254. "class": ['v-tab__slider', sliderColorClasses.value],
  26255. "style": sliderColorStyles.value
  26256. }, null)])
  26257. });
  26258. });
  26259. return forwardRefs({}, rootEl);
  26260. }
  26261. });
  26262. const makeVTabsWindowProps = propsFactory({
  26263. ...omit(makeVWindowProps(), ['continuous', 'nextIcon', 'prevIcon', 'showArrows', 'touch', 'mandatory'])
  26264. }, 'VTabsWindow');
  26265. const VTabsWindow = genericComponent()({
  26266. name: 'VTabsWindow',
  26267. props: makeVTabsWindowProps(),
  26268. emits: {
  26269. 'update:modelValue': v => true
  26270. },
  26271. setup(props, _ref) {
  26272. let {
  26273. slots
  26274. } = _ref;
  26275. const group = inject$1(VTabsSymbol, null);
  26276. const _model = useProxiedModel(props, 'modelValue');
  26277. const model = computed({
  26278. get() {
  26279. // Always return modelValue if defined
  26280. // or if not within a VTabs group
  26281. if (_model.value != null || !group) return _model.value;
  26282. // If inside of a VTabs, find the currently selected
  26283. // item by id. Item value may be assigned by its index
  26284. return group.items.value.find(item => group.selected.value.includes(item.id))?.value;
  26285. },
  26286. set(val) {
  26287. _model.value = val;
  26288. }
  26289. });
  26290. useRender(() => {
  26291. const windowProps = VWindow.filterProps(props);
  26292. return createVNode(VWindow, mergeProps({
  26293. "_as": "VTabsWindow"
  26294. }, windowProps, {
  26295. "modelValue": model.value,
  26296. "onUpdate:modelValue": $event => model.value = $event,
  26297. "class": ['v-tabs-window', props.class],
  26298. "style": props.style,
  26299. "mandatory": false,
  26300. "touch": false
  26301. }), slots);
  26302. });
  26303. return {};
  26304. }
  26305. });
  26306. const makeVTabsWindowItemProps = propsFactory({
  26307. ...makeVWindowItemProps()
  26308. }, 'VTabsWindowItem');
  26309. const VTabsWindowItem = genericComponent()({
  26310. name: 'VTabsWindowItem',
  26311. props: makeVTabsWindowItemProps(),
  26312. setup(props, _ref) {
  26313. let {
  26314. slots
  26315. } = _ref;
  26316. useRender(() => {
  26317. const windowItemProps = VWindowItem.filterProps(props);
  26318. return createVNode(VWindowItem, mergeProps({
  26319. "_as": "VTabsWindowItem"
  26320. }, windowItemProps, {
  26321. "class": ['v-tabs-window-item', props.class],
  26322. "style": props.style
  26323. }), slots);
  26324. });
  26325. return {};
  26326. }
  26327. });
  26328. function parseItems(items) {
  26329. if (!items) return [];
  26330. return items.map(item => {
  26331. if (!isObject(item)) return {
  26332. text: item,
  26333. value: item
  26334. };
  26335. return item;
  26336. });
  26337. }
  26338. const makeVTabsProps = propsFactory({
  26339. alignTabs: {
  26340. type: String,
  26341. default: 'start'
  26342. },
  26343. color: String,
  26344. fixedTabs: Boolean,
  26345. items: {
  26346. type: Array,
  26347. default: () => []
  26348. },
  26349. stacked: Boolean,
  26350. bgColor: String,
  26351. grow: Boolean,
  26352. height: {
  26353. type: [Number, String],
  26354. default: undefined
  26355. },
  26356. hideSlider: Boolean,
  26357. sliderColor: String,
  26358. ...makeVSlideGroupProps({
  26359. mandatory: 'force',
  26360. selectedClass: 'v-tab-item--selected'
  26361. }),
  26362. ...makeDensityProps(),
  26363. ...makeTagProps()
  26364. }, 'VTabs');
  26365. const VTabs = genericComponent()({
  26366. name: 'VTabs',
  26367. props: makeVTabsProps(),
  26368. emits: {
  26369. 'update:modelValue': v => true
  26370. },
  26371. setup(props, _ref) {
  26372. let {
  26373. attrs,
  26374. slots
  26375. } = _ref;
  26376. const model = useProxiedModel(props, 'modelValue');
  26377. const items = computed(() => parseItems(props.items));
  26378. const {
  26379. densityClasses
  26380. } = useDensity(props);
  26381. const {
  26382. backgroundColorClasses,
  26383. backgroundColorStyles
  26384. } = useBackgroundColor(toRef(props, 'bgColor'));
  26385. const {
  26386. scopeId
  26387. } = useScopeId();
  26388. provideDefaults({
  26389. VTab: {
  26390. color: toRef(props, 'color'),
  26391. direction: toRef(props, 'direction'),
  26392. stacked: toRef(props, 'stacked'),
  26393. fixed: toRef(props, 'fixedTabs'),
  26394. sliderColor: toRef(props, 'sliderColor'),
  26395. hideSlider: toRef(props, 'hideSlider')
  26396. }
  26397. });
  26398. useRender(() => {
  26399. const slideGroupProps = VSlideGroup.filterProps(props);
  26400. const hasWindow = !!(slots.window || props.items.length > 0);
  26401. return createVNode(Fragment, null, [createVNode(VSlideGroup, mergeProps(slideGroupProps, {
  26402. "modelValue": model.value,
  26403. "onUpdate:modelValue": $event => model.value = $event,
  26404. "class": ['v-tabs', `v-tabs--${props.direction}`, `v-tabs--align-tabs-${props.alignTabs}`, {
  26405. 'v-tabs--fixed-tabs': props.fixedTabs,
  26406. 'v-tabs--grow': props.grow,
  26407. 'v-tabs--stacked': props.stacked
  26408. }, densityClasses.value, backgroundColorClasses.value, props.class],
  26409. "style": [{
  26410. '--v-tabs-height': convertToUnit(props.height)
  26411. }, backgroundColorStyles.value, props.style],
  26412. "role": "tablist",
  26413. "symbol": VTabsSymbol
  26414. }, scopeId, attrs), {
  26415. default: () => [slots.default?.() ?? items.value.map(item => slots.tab?.({
  26416. item
  26417. }) ?? createVNode(VTab, mergeProps(item, {
  26418. "key": item.text,
  26419. "value": item.value
  26420. }), {
  26421. default: slots[`tab.${item.value}`] ? () => slots[`tab.${item.value}`]?.({
  26422. item
  26423. }) : undefined
  26424. }))]
  26425. }), hasWindow && createVNode(VTabsWindow, mergeProps({
  26426. "modelValue": model.value,
  26427. "onUpdate:modelValue": $event => model.value = $event,
  26428. "key": "tabs-window"
  26429. }, scopeId), {
  26430. default: () => [items.value.map(item => slots.item?.({
  26431. item
  26432. }) ?? createVNode(VTabsWindowItem, {
  26433. "value": item.value
  26434. }, {
  26435. default: () => slots[`item.${item.value}`]?.({
  26436. item
  26437. })
  26438. })), slots.window?.()]
  26439. })]);
  26440. });
  26441. return {};
  26442. }
  26443. });
  26444. // Types
  26445. const makeVTextareaProps = propsFactory({
  26446. autoGrow: Boolean,
  26447. autofocus: Boolean,
  26448. counter: [Boolean, Number, String],
  26449. counterValue: Function,
  26450. prefix: String,
  26451. placeholder: String,
  26452. persistentPlaceholder: Boolean,
  26453. persistentCounter: Boolean,
  26454. noResize: Boolean,
  26455. rows: {
  26456. type: [Number, String],
  26457. default: 5,
  26458. validator: v => !isNaN(parseFloat(v))
  26459. },
  26460. maxRows: {
  26461. type: [Number, String],
  26462. validator: v => !isNaN(parseFloat(v))
  26463. },
  26464. suffix: String,
  26465. modelModifiers: Object,
  26466. ...makeVInputProps(),
  26467. ...makeVFieldProps()
  26468. }, 'VTextarea');
  26469. const VTextarea = genericComponent()({
  26470. name: 'VTextarea',
  26471. directives: {
  26472. Intersect
  26473. },
  26474. inheritAttrs: false,
  26475. props: makeVTextareaProps(),
  26476. emits: {
  26477. 'click:control': e => true,
  26478. 'mousedown:control': e => true,
  26479. 'update:focused': focused => true,
  26480. 'update:modelValue': val => true
  26481. },
  26482. setup(props, _ref) {
  26483. let {
  26484. attrs,
  26485. emit,
  26486. slots
  26487. } = _ref;
  26488. const model = useProxiedModel(props, 'modelValue');
  26489. const {
  26490. isFocused,
  26491. focus,
  26492. blur
  26493. } = useFocus(props);
  26494. const counterValue = computed(() => {
  26495. return typeof props.counterValue === 'function' ? props.counterValue(model.value) : (model.value || '').toString().length;
  26496. });
  26497. const max = computed(() => {
  26498. if (attrs.maxlength) return attrs.maxlength;
  26499. if (!props.counter || typeof props.counter !== 'number' && typeof props.counter !== 'string') return undefined;
  26500. return props.counter;
  26501. });
  26502. function onIntersect(isIntersecting, entries) {
  26503. if (!props.autofocus || !isIntersecting) return;
  26504. entries[0].target?.focus?.();
  26505. }
  26506. const vInputRef = ref();
  26507. const vFieldRef = ref();
  26508. const controlHeight = shallowRef('');
  26509. const textareaRef = ref();
  26510. const isActive = computed(() => props.persistentPlaceholder || isFocused.value || props.active);
  26511. function onFocus() {
  26512. if (textareaRef.value !== document.activeElement) {
  26513. textareaRef.value?.focus();
  26514. }
  26515. if (!isFocused.value) focus();
  26516. }
  26517. function onControlClick(e) {
  26518. onFocus();
  26519. emit('click:control', e);
  26520. }
  26521. function onControlMousedown(e) {
  26522. emit('mousedown:control', e);
  26523. }
  26524. function onClear(e) {
  26525. e.stopPropagation();
  26526. onFocus();
  26527. nextTick(() => {
  26528. model.value = '';
  26529. callEvent(props['onClick:clear'], e);
  26530. });
  26531. }
  26532. function onInput(e) {
  26533. const el = e.target;
  26534. model.value = el.value;
  26535. if (props.modelModifiers?.trim) {
  26536. const caretPosition = [el.selectionStart, el.selectionEnd];
  26537. nextTick(() => {
  26538. el.selectionStart = caretPosition[0];
  26539. el.selectionEnd = caretPosition[1];
  26540. });
  26541. }
  26542. }
  26543. const sizerRef = ref();
  26544. const rows = ref(+props.rows);
  26545. const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant));
  26546. watchEffect(() => {
  26547. if (!props.autoGrow) rows.value = +props.rows;
  26548. });
  26549. function calculateInputHeight() {
  26550. if (!props.autoGrow) return;
  26551. nextTick(() => {
  26552. if (!sizerRef.value || !vFieldRef.value) return;
  26553. const style = getComputedStyle(sizerRef.value);
  26554. const fieldStyle = getComputedStyle(vFieldRef.value.$el);
  26555. const padding = parseFloat(style.getPropertyValue('--v-field-padding-top')) + parseFloat(style.getPropertyValue('--v-input-padding-top')) + parseFloat(style.getPropertyValue('--v-field-padding-bottom'));
  26556. const height = sizerRef.value.scrollHeight;
  26557. const lineHeight = parseFloat(style.lineHeight);
  26558. const minHeight = Math.max(parseFloat(props.rows) * lineHeight + padding, parseFloat(fieldStyle.getPropertyValue('--v-input-control-height')));
  26559. const maxHeight = parseFloat(props.maxRows) * lineHeight + padding || Infinity;
  26560. const newHeight = clamp(height ?? 0, minHeight, maxHeight);
  26561. rows.value = Math.floor((newHeight - padding) / lineHeight);
  26562. controlHeight.value = convertToUnit(newHeight);
  26563. });
  26564. }
  26565. onMounted(calculateInputHeight);
  26566. watch(model, calculateInputHeight);
  26567. watch(() => props.rows, calculateInputHeight);
  26568. watch(() => props.maxRows, calculateInputHeight);
  26569. watch(() => props.density, calculateInputHeight);
  26570. let observer;
  26571. watch(sizerRef, val => {
  26572. if (val) {
  26573. observer = new ResizeObserver(calculateInputHeight);
  26574. observer.observe(sizerRef.value);
  26575. } else {
  26576. observer?.disconnect();
  26577. }
  26578. });
  26579. onBeforeUnmount(() => {
  26580. observer?.disconnect();
  26581. });
  26582. useRender(() => {
  26583. const hasCounter = !!(slots.counter || props.counter || props.counterValue);
  26584. const hasDetails = !!(hasCounter || slots.details);
  26585. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  26586. const {
  26587. modelValue: _,
  26588. ...inputProps
  26589. } = VInput.filterProps(props);
  26590. const fieldProps = filterFieldProps(props);
  26591. return createVNode(VInput, mergeProps({
  26592. "ref": vInputRef,
  26593. "modelValue": model.value,
  26594. "onUpdate:modelValue": $event => model.value = $event,
  26595. "class": ['v-textarea v-text-field', {
  26596. 'v-textarea--prefixed': props.prefix,
  26597. 'v-textarea--suffixed': props.suffix,
  26598. 'v-text-field--prefixed': props.prefix,
  26599. 'v-text-field--suffixed': props.suffix,
  26600. 'v-textarea--auto-grow': props.autoGrow,
  26601. 'v-textarea--no-resize': props.noResize || props.autoGrow,
  26602. 'v-input--plain-underlined': isPlainOrUnderlined.value
  26603. }, props.class],
  26604. "style": props.style
  26605. }, rootAttrs, inputProps, {
  26606. "centerAffix": rows.value === 1 && !isPlainOrUnderlined.value,
  26607. "focused": isFocused.value
  26608. }), {
  26609. ...slots,
  26610. default: _ref2 => {
  26611. let {
  26612. id,
  26613. isDisabled,
  26614. isDirty,
  26615. isReadonly,
  26616. isValid
  26617. } = _ref2;
  26618. return createVNode(VField, mergeProps({
  26619. "ref": vFieldRef,
  26620. "style": {
  26621. '--v-textarea-control-height': controlHeight.value
  26622. },
  26623. "onClick": onControlClick,
  26624. "onMousedown": onControlMousedown,
  26625. "onClick:clear": onClear,
  26626. "onClick:prependInner": props['onClick:prependInner'],
  26627. "onClick:appendInner": props['onClick:appendInner']
  26628. }, fieldProps, {
  26629. "id": id.value,
  26630. "active": isActive.value || isDirty.value,
  26631. "centerAffix": rows.value === 1 && !isPlainOrUnderlined.value,
  26632. "dirty": isDirty.value || props.dirty,
  26633. "disabled": isDisabled.value,
  26634. "focused": isFocused.value,
  26635. "error": isValid.value === false
  26636. }), {
  26637. ...slots,
  26638. default: _ref3 => {
  26639. let {
  26640. props: {
  26641. class: fieldClass,
  26642. ...slotProps
  26643. }
  26644. } = _ref3;
  26645. return createVNode(Fragment, null, [props.prefix && createVNode("span", {
  26646. "class": "v-text-field__prefix"
  26647. }, [props.prefix]), withDirectives(createVNode("textarea", mergeProps({
  26648. "ref": textareaRef,
  26649. "class": fieldClass,
  26650. "value": model.value,
  26651. "onInput": onInput,
  26652. "autofocus": props.autofocus,
  26653. "readonly": isReadonly.value,
  26654. "disabled": isDisabled.value,
  26655. "placeholder": props.placeholder,
  26656. "rows": props.rows,
  26657. "name": props.name,
  26658. "onFocus": onFocus,
  26659. "onBlur": blur
  26660. }, slotProps, inputAttrs), null), [[resolveDirective("intersect"), {
  26661. handler: onIntersect
  26662. }, null, {
  26663. once: true
  26664. }]]), props.autoGrow && withDirectives(createVNode("textarea", {
  26665. "class": [fieldClass, 'v-textarea__sizer'],
  26666. "id": `${slotProps.id}-sizer`,
  26667. "onUpdate:modelValue": $event => model.value = $event,
  26668. "ref": sizerRef,
  26669. "readonly": true,
  26670. "aria-hidden": "true"
  26671. }, null), [[vModelText, model.value]]), props.suffix && createVNode("span", {
  26672. "class": "v-text-field__suffix"
  26673. }, [props.suffix])]);
  26674. }
  26675. });
  26676. },
  26677. details: hasDetails ? slotProps => createVNode(Fragment, null, [slots.details?.(slotProps), hasCounter && createVNode(Fragment, null, [createVNode("span", null, null), createVNode(VCounter, {
  26678. "active": props.persistentCounter || isFocused.value,
  26679. "value": counterValue.value,
  26680. "max": max.value,
  26681. "disabled": props.disabled
  26682. }, slots.counter)])]) : undefined
  26683. });
  26684. });
  26685. return forwardRefs({}, vInputRef, vFieldRef, textareaRef);
  26686. }
  26687. });
  26688. const makeVThemeProviderProps = propsFactory({
  26689. withBackground: Boolean,
  26690. ...makeComponentProps(),
  26691. ...makeThemeProps(),
  26692. ...makeTagProps()
  26693. }, 'VThemeProvider');
  26694. const VThemeProvider = genericComponent()({
  26695. name: 'VThemeProvider',
  26696. props: makeVThemeProviderProps(),
  26697. setup(props, _ref) {
  26698. let {
  26699. slots
  26700. } = _ref;
  26701. const {
  26702. themeClasses
  26703. } = provideTheme(props);
  26704. return () => {
  26705. if (!props.withBackground) return slots.default?.();
  26706. return createVNode(props.tag, {
  26707. "class": ['v-theme-provider', themeClasses.value, props.class],
  26708. "style": props.style
  26709. }, {
  26710. default: () => [slots.default?.()]
  26711. });
  26712. };
  26713. }
  26714. });
  26715. const makeVTimelineDividerProps = propsFactory({
  26716. dotColor: String,
  26717. fillDot: Boolean,
  26718. hideDot: Boolean,
  26719. icon: IconValue,
  26720. iconColor: String,
  26721. lineColor: String,
  26722. ...makeComponentProps(),
  26723. ...makeRoundedProps(),
  26724. ...makeSizeProps(),
  26725. ...makeElevationProps()
  26726. }, 'VTimelineDivider');
  26727. const VTimelineDivider = genericComponent()({
  26728. name: 'VTimelineDivider',
  26729. props: makeVTimelineDividerProps(),
  26730. setup(props, _ref) {
  26731. let {
  26732. slots
  26733. } = _ref;
  26734. const {
  26735. sizeClasses,
  26736. sizeStyles
  26737. } = useSize(props, 'v-timeline-divider__dot');
  26738. const {
  26739. backgroundColorStyles,
  26740. backgroundColorClasses
  26741. } = useBackgroundColor(toRef(props, 'dotColor'));
  26742. const {
  26743. roundedClasses
  26744. } = useRounded(props, 'v-timeline-divider__dot');
  26745. const {
  26746. elevationClasses
  26747. } = useElevation(props);
  26748. const {
  26749. backgroundColorClasses: lineColorClasses,
  26750. backgroundColorStyles: lineColorStyles
  26751. } = useBackgroundColor(toRef(props, 'lineColor'));
  26752. useRender(() => createVNode("div", {
  26753. "class": ['v-timeline-divider', {
  26754. 'v-timeline-divider--fill-dot': props.fillDot
  26755. }, props.class],
  26756. "style": props.style
  26757. }, [createVNode("div", {
  26758. "class": ['v-timeline-divider__before', lineColorClasses.value],
  26759. "style": lineColorStyles.value
  26760. }, null), !props.hideDot && createVNode("div", {
  26761. "key": "dot",
  26762. "class": ['v-timeline-divider__dot', elevationClasses.value, roundedClasses.value, sizeClasses.value],
  26763. "style": sizeStyles.value
  26764. }, [createVNode("div", {
  26765. "class": ['v-timeline-divider__inner-dot', backgroundColorClasses.value, roundedClasses.value],
  26766. "style": backgroundColorStyles.value
  26767. }, [!slots.default ? createVNode(VIcon, {
  26768. "key": "icon",
  26769. "color": props.iconColor,
  26770. "icon": props.icon,
  26771. "size": props.size
  26772. }, null) : createVNode(VDefaultsProvider, {
  26773. "key": "icon-defaults",
  26774. "disabled": !props.icon,
  26775. "defaults": {
  26776. VIcon: {
  26777. color: props.iconColor,
  26778. icon: props.icon,
  26779. size: props.size
  26780. }
  26781. }
  26782. }, slots.default)])]), createVNode("div", {
  26783. "class": ['v-timeline-divider__after', lineColorClasses.value],
  26784. "style": lineColorStyles.value
  26785. }, null)]));
  26786. return {};
  26787. }
  26788. });
  26789. // Types
  26790. // Types
  26791. const makeVTimelineItemProps = propsFactory({
  26792. density: String,
  26793. dotColor: String,
  26794. fillDot: Boolean,
  26795. hideDot: Boolean,
  26796. hideOpposite: {
  26797. type: Boolean,
  26798. default: undefined
  26799. },
  26800. icon: IconValue,
  26801. iconColor: String,
  26802. lineInset: [Number, String],
  26803. ...makeComponentProps(),
  26804. ...makeDimensionProps(),
  26805. ...makeElevationProps(),
  26806. ...makeRoundedProps(),
  26807. ...makeSizeProps(),
  26808. ...makeTagProps()
  26809. }, 'VTimelineItem');
  26810. const VTimelineItem = genericComponent()({
  26811. name: 'VTimelineItem',
  26812. props: makeVTimelineItemProps(),
  26813. setup(props, _ref) {
  26814. let {
  26815. slots
  26816. } = _ref;
  26817. const {
  26818. dimensionStyles
  26819. } = useDimension(props);
  26820. const dotSize = shallowRef(0);
  26821. const dotRef = ref();
  26822. watch(dotRef, newValue => {
  26823. if (!newValue) return;
  26824. dotSize.value = newValue.$el.querySelector('.v-timeline-divider__dot')?.getBoundingClientRect().width ?? 0;
  26825. }, {
  26826. flush: 'post'
  26827. });
  26828. useRender(() => createVNode("div", {
  26829. "class": ['v-timeline-item', {
  26830. 'v-timeline-item--fill-dot': props.fillDot
  26831. }, props.class],
  26832. "style": [{
  26833. '--v-timeline-dot-size': convertToUnit(dotSize.value),
  26834. '--v-timeline-line-inset': props.lineInset ? `calc(var(--v-timeline-dot-size) / 2 + ${convertToUnit(props.lineInset)})` : convertToUnit(0)
  26835. }, props.style]
  26836. }, [createVNode("div", {
  26837. "class": "v-timeline-item__body",
  26838. "style": dimensionStyles.value
  26839. }, [slots.default?.()]), createVNode(VTimelineDivider, {
  26840. "ref": dotRef,
  26841. "hideDot": props.hideDot,
  26842. "icon": props.icon,
  26843. "iconColor": props.iconColor,
  26844. "size": props.size,
  26845. "elevation": props.elevation,
  26846. "dotColor": props.dotColor,
  26847. "fillDot": props.fillDot,
  26848. "rounded": props.rounded
  26849. }, {
  26850. default: slots.icon
  26851. }), props.density !== 'compact' && createVNode("div", {
  26852. "class": "v-timeline-item__opposite"
  26853. }, [!props.hideOpposite && slots.opposite?.()])]));
  26854. return {};
  26855. }
  26856. });
  26857. const makeVTimelineProps = propsFactory({
  26858. align: {
  26859. type: String,
  26860. default: 'center',
  26861. validator: v => ['center', 'start'].includes(v)
  26862. },
  26863. direction: {
  26864. type: String,
  26865. default: 'vertical',
  26866. validator: v => ['vertical', 'horizontal'].includes(v)
  26867. },
  26868. justify: {
  26869. type: String,
  26870. default: 'auto',
  26871. validator: v => ['auto', 'center'].includes(v)
  26872. },
  26873. side: {
  26874. type: String,
  26875. validator: v => v == null || ['start', 'end'].includes(v)
  26876. },
  26877. lineThickness: {
  26878. type: [String, Number],
  26879. default: 2
  26880. },
  26881. lineColor: String,
  26882. truncateLine: {
  26883. type: String,
  26884. validator: v => ['start', 'end', 'both'].includes(v)
  26885. },
  26886. ...only(makeVTimelineItemProps({
  26887. lineInset: 0
  26888. }), ['dotColor', 'fillDot', 'hideOpposite', 'iconColor', 'lineInset', 'size']),
  26889. ...makeComponentProps(),
  26890. ...makeDensityProps(),
  26891. ...makeTagProps(),
  26892. ...makeThemeProps()
  26893. }, 'VTimeline');
  26894. const VTimeline = genericComponent()({
  26895. name: 'VTimeline',
  26896. props: makeVTimelineProps(),
  26897. setup(props, _ref) {
  26898. let {
  26899. slots
  26900. } = _ref;
  26901. const {
  26902. themeClasses
  26903. } = provideTheme(props);
  26904. const {
  26905. densityClasses
  26906. } = useDensity(props);
  26907. const {
  26908. rtlClasses
  26909. } = useRtl();
  26910. provideDefaults({
  26911. VTimelineDivider: {
  26912. lineColor: toRef(props, 'lineColor')
  26913. },
  26914. VTimelineItem: {
  26915. density: toRef(props, 'density'),
  26916. dotColor: toRef(props, 'dotColor'),
  26917. fillDot: toRef(props, 'fillDot'),
  26918. hideOpposite: toRef(props, 'hideOpposite'),
  26919. iconColor: toRef(props, 'iconColor'),
  26920. lineColor: toRef(props, 'lineColor'),
  26921. lineInset: toRef(props, 'lineInset'),
  26922. size: toRef(props, 'size')
  26923. }
  26924. });
  26925. const sideClasses = computed(() => {
  26926. const side = props.side ? props.side : props.density !== 'default' ? 'end' : null;
  26927. return side && `v-timeline--side-${side}`;
  26928. });
  26929. const truncateClasses = computed(() => {
  26930. const classes = ['v-timeline--truncate-line-start', 'v-timeline--truncate-line-end'];
  26931. switch (props.truncateLine) {
  26932. case 'both':
  26933. return classes;
  26934. case 'start':
  26935. return classes[0];
  26936. case 'end':
  26937. return classes[1];
  26938. default:
  26939. return null;
  26940. }
  26941. });
  26942. useRender(() => createVNode(props.tag, {
  26943. "class": ['v-timeline', `v-timeline--${props.direction}`, `v-timeline--align-${props.align}`, `v-timeline--justify-${props.justify}`, truncateClasses.value, {
  26944. 'v-timeline--inset-line': !!props.lineInset
  26945. }, themeClasses.value, densityClasses.value, sideClasses.value, rtlClasses.value, props.class],
  26946. "style": [{
  26947. '--v-timeline-line-thickness': convertToUnit(props.lineThickness)
  26948. }, props.style]
  26949. }, slots));
  26950. return {};
  26951. }
  26952. });
  26953. const makeVToolbarItemsProps = propsFactory({
  26954. ...makeComponentProps(),
  26955. ...makeVariantProps({
  26956. variant: 'text'
  26957. })
  26958. }, 'VToolbarItems');
  26959. const VToolbarItems = genericComponent()({
  26960. name: 'VToolbarItems',
  26961. props: makeVToolbarItemsProps(),
  26962. setup(props, _ref) {
  26963. let {
  26964. slots
  26965. } = _ref;
  26966. provideDefaults({
  26967. VBtn: {
  26968. color: toRef(props, 'color'),
  26969. height: 'inherit',
  26970. variant: toRef(props, 'variant')
  26971. }
  26972. });
  26973. useRender(() => createVNode("div", {
  26974. "class": ['v-toolbar-items', props.class],
  26975. "style": props.style
  26976. }, [slots.default?.()]));
  26977. return {};
  26978. }
  26979. });
  26980. // Types
  26981. const makeVTooltipProps = propsFactory({
  26982. id: String,
  26983. text: String,
  26984. ...omit(makeVOverlayProps({
  26985. closeOnBack: false,
  26986. location: 'end',
  26987. locationStrategy: 'connected',
  26988. eager: true,
  26989. minWidth: 0,
  26990. offset: 10,
  26991. openOnClick: false,
  26992. openOnHover: true,
  26993. origin: 'auto',
  26994. scrim: false,
  26995. scrollStrategy: 'reposition',
  26996. transition: false
  26997. }), ['absolute', 'persistent'])
  26998. }, 'VTooltip');
  26999. const VTooltip = genericComponent()({
  27000. name: 'VTooltip',
  27001. props: makeVTooltipProps(),
  27002. emits: {
  27003. 'update:modelValue': value => true
  27004. },
  27005. setup(props, _ref) {
  27006. let {
  27007. slots
  27008. } = _ref;
  27009. const isActive = useProxiedModel(props, 'modelValue');
  27010. const {
  27011. scopeId
  27012. } = useScopeId();
  27013. const uid = getUid();
  27014. const id = computed(() => props.id || `v-tooltip-${uid}`);
  27015. const overlay = ref();
  27016. const location = computed(() => {
  27017. return props.location.split(' ').length > 1 ? props.location : props.location + ' center';
  27018. });
  27019. const origin = computed(() => {
  27020. return props.origin === 'auto' || props.origin === 'overlap' || props.origin.split(' ').length > 1 || props.location.split(' ').length > 1 ? props.origin : props.origin + ' center';
  27021. });
  27022. const transition = computed(() => {
  27023. if (props.transition) return props.transition;
  27024. return isActive.value ? 'scale-transition' : 'fade-transition';
  27025. });
  27026. const activatorProps = computed(() => mergeProps({
  27027. 'aria-describedby': id.value
  27028. }, props.activatorProps));
  27029. useRender(() => {
  27030. const overlayProps = VOverlay.filterProps(props);
  27031. return createVNode(VOverlay, mergeProps({
  27032. "ref": overlay,
  27033. "class": ['v-tooltip', props.class],
  27034. "style": props.style,
  27035. "id": id.value
  27036. }, overlayProps, {
  27037. "modelValue": isActive.value,
  27038. "onUpdate:modelValue": $event => isActive.value = $event,
  27039. "transition": transition.value,
  27040. "absolute": true,
  27041. "location": location.value,
  27042. "origin": origin.value,
  27043. "persistent": true,
  27044. "role": "tooltip",
  27045. "activatorProps": activatorProps.value,
  27046. "_disableGlobalStack": true
  27047. }, scopeId), {
  27048. activator: slots.activator,
  27049. default: function () {
  27050. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  27051. args[_key] = arguments[_key];
  27052. }
  27053. return slots.default?.(...args) ?? props.text;
  27054. }
  27055. });
  27056. });
  27057. return forwardRefs({}, overlay);
  27058. }
  27059. });
  27060. // Composables
  27061. // Types
  27062. const VValidation = genericComponent()({
  27063. name: 'VValidation',
  27064. props: makeValidationProps(),
  27065. emits: {
  27066. 'update:modelValue': value => true
  27067. },
  27068. setup(props, _ref) {
  27069. let {
  27070. slots
  27071. } = _ref;
  27072. const validation = useValidation(props, 'validation');
  27073. return () => slots.default?.(validation);
  27074. }
  27075. });
  27076. var components = /*#__PURE__*/Object.freeze({
  27077. __proto__: null,
  27078. VAlert: VAlert,
  27079. VAlertTitle: VAlertTitle,
  27080. VApp: VApp,
  27081. VAppBar: VAppBar,
  27082. VAppBarNavIcon: VAppBarNavIcon,
  27083. VAppBarTitle: VAppBarTitle,
  27084. VAutocomplete: VAutocomplete,
  27085. VAvatar: VAvatar,
  27086. VBadge: VBadge,
  27087. VBanner: VBanner,
  27088. VBannerActions: VBannerActions,
  27089. VBannerText: VBannerText,
  27090. VBottomNavigation: VBottomNavigation,
  27091. VBottomSheet: VBottomSheet,
  27092. VBreadcrumbs: VBreadcrumbs,
  27093. VBreadcrumbsDivider: VBreadcrumbsDivider,
  27094. VBreadcrumbsItem: VBreadcrumbsItem,
  27095. VBtn: VBtn,
  27096. VBtnGroup: VBtnGroup,
  27097. VBtnToggle: VBtnToggle,
  27098. VCard: VCard,
  27099. VCardActions: VCardActions,
  27100. VCardItem: VCardItem,
  27101. VCardSubtitle: VCardSubtitle,
  27102. VCardText: VCardText,
  27103. VCardTitle: VCardTitle,
  27104. VCarousel: VCarousel,
  27105. VCarouselItem: VCarouselItem,
  27106. VCheckbox: VCheckbox,
  27107. VCheckboxBtn: VCheckboxBtn,
  27108. VChip: VChip,
  27109. VChipGroup: VChipGroup,
  27110. VClassIcon: VClassIcon,
  27111. VCode: VCode,
  27112. VCol: VCol,
  27113. VColorPicker: VColorPicker,
  27114. VCombobox: VCombobox,
  27115. VComponentIcon: VComponentIcon,
  27116. VConfirmEdit: VConfirmEdit,
  27117. VContainer: VContainer,
  27118. VCounter: VCounter,
  27119. VDataIterator: VDataIterator,
  27120. VDataTable: VDataTable,
  27121. VDataTableFooter: VDataTableFooter,
  27122. VDataTableHeaders: VDataTableHeaders,
  27123. VDataTableRow: VDataTableRow,
  27124. VDataTableRows: VDataTableRows,
  27125. VDataTableServer: VDataTableServer,
  27126. VDataTableVirtual: VDataTableVirtual,
  27127. VDatePicker: VDatePicker,
  27128. VDatePickerControls: VDatePickerControls,
  27129. VDatePickerHeader: VDatePickerHeader,
  27130. VDatePickerMonth: VDatePickerMonth,
  27131. VDatePickerMonths: VDatePickerMonths,
  27132. VDatePickerYears: VDatePickerYears,
  27133. VDefaultsProvider: VDefaultsProvider,
  27134. VDialog: VDialog,
  27135. VDialogBottomTransition: VDialogBottomTransition,
  27136. VDialogTopTransition: VDialogTopTransition,
  27137. VDialogTransition: VDialogTransition,
  27138. VDivider: VDivider,
  27139. VEmptyState: VEmptyState,
  27140. VExpandTransition: VExpandTransition,
  27141. VExpandXTransition: VExpandXTransition,
  27142. VExpansionPanel: VExpansionPanel,
  27143. VExpansionPanelText: VExpansionPanelText,
  27144. VExpansionPanelTitle: VExpansionPanelTitle,
  27145. VExpansionPanels: VExpansionPanels,
  27146. VFab: VFab,
  27147. VFabTransition: VFabTransition,
  27148. VFadeTransition: VFadeTransition,
  27149. VField: VField,
  27150. VFieldLabel: VFieldLabel,
  27151. VFileInput: VFileInput,
  27152. VFooter: VFooter,
  27153. VForm: VForm,
  27154. VHover: VHover,
  27155. VIcon: VIcon,
  27156. VImg: VImg,
  27157. VInfiniteScroll: VInfiniteScroll,
  27158. VInput: VInput,
  27159. VItem: VItem,
  27160. VItemGroup: VItemGroup,
  27161. VKbd: VKbd,
  27162. VLabel: VLabel,
  27163. VLayout: VLayout,
  27164. VLayoutItem: VLayoutItem,
  27165. VLazy: VLazy,
  27166. VLigatureIcon: VLigatureIcon,
  27167. VList: VList,
  27168. VListGroup: VListGroup,
  27169. VListImg: VListImg,
  27170. VListItem: VListItem,
  27171. VListItemAction: VListItemAction,
  27172. VListItemMedia: VListItemMedia,
  27173. VListItemSubtitle: VListItemSubtitle,
  27174. VListItemTitle: VListItemTitle,
  27175. VListSubheader: VListSubheader,
  27176. VLocaleProvider: VLocaleProvider,
  27177. VMain: VMain,
  27178. VMenu: VMenu,
  27179. VMessages: VMessages,
  27180. VNavigationDrawer: VNavigationDrawer,
  27181. VNoSsr: VNoSsr,
  27182. VOtpInput: VOtpInput,
  27183. VOverlay: VOverlay,
  27184. VPagination: VPagination,
  27185. VParallax: VParallax,
  27186. VProgressCircular: VProgressCircular,
  27187. VProgressLinear: VProgressLinear,
  27188. VRadio: VRadio,
  27189. VRadioGroup: VRadioGroup,
  27190. VRangeSlider: VRangeSlider,
  27191. VRating: VRating,
  27192. VResponsive: VResponsive,
  27193. VRow: VRow,
  27194. VScaleTransition: VScaleTransition,
  27195. VScrollXReverseTransition: VScrollXReverseTransition,
  27196. VScrollXTransition: VScrollXTransition,
  27197. VScrollYReverseTransition: VScrollYReverseTransition,
  27198. VScrollYTransition: VScrollYTransition,
  27199. VSelect: VSelect,
  27200. VSelectionControl: VSelectionControl,
  27201. VSelectionControlGroup: VSelectionControlGroup,
  27202. VSheet: VSheet,
  27203. VSkeletonLoader: VSkeletonLoader,
  27204. VSlideGroup: VSlideGroup,
  27205. VSlideGroupItem: VSlideGroupItem,
  27206. VSlideXReverseTransition: VSlideXReverseTransition,
  27207. VSlideXTransition: VSlideXTransition,
  27208. VSlideYReverseTransition: VSlideYReverseTransition,
  27209. VSlideYTransition: VSlideYTransition,
  27210. VSlider: VSlider,
  27211. VSnackbar: VSnackbar,
  27212. VSpacer: VSpacer,
  27213. VSparkline: VSparkline,
  27214. VSpeedDial: VSpeedDial,
  27215. VStepper: VStepper,
  27216. VStepperActions: VStepperActions,
  27217. VStepperHeader: VStepperHeader,
  27218. VStepperItem: VStepperItem,
  27219. VStepperWindow: VStepperWindow,
  27220. VStepperWindowItem: VStepperWindowItem,
  27221. VSvgIcon: VSvgIcon,
  27222. VSwitch: VSwitch,
  27223. VSystemBar: VSystemBar,
  27224. VTab: VTab,
  27225. VTable: VTable,
  27226. VTabs: VTabs,
  27227. VTabsWindow: VTabsWindow,
  27228. VTabsWindowItem: VTabsWindowItem,
  27229. VTextField: VTextField,
  27230. VTextarea: VTextarea,
  27231. VThemeProvider: VThemeProvider,
  27232. VTimeline: VTimeline,
  27233. VTimelineItem: VTimelineItem,
  27234. VToolbar: VToolbar,
  27235. VToolbarItems: VToolbarItems,
  27236. VToolbarTitle: VToolbarTitle,
  27237. VTooltip: VTooltip,
  27238. VValidation: VValidation,
  27239. VVirtualScroll: VVirtualScroll,
  27240. VWindow: VWindow,
  27241. VWindowItem: VWindowItem
  27242. });
  27243. // Types
  27244. function mounted$2(el, binding) {
  27245. const modifiers = binding.modifiers || {};
  27246. const value = binding.value;
  27247. const {
  27248. once,
  27249. immediate,
  27250. ...modifierKeys
  27251. } = modifiers;
  27252. const defaultValue = !Object.keys(modifierKeys).length;
  27253. const {
  27254. handler,
  27255. options
  27256. } = typeof value === 'object' ? value : {
  27257. handler: value,
  27258. options: {
  27259. attributes: modifierKeys?.attr ?? defaultValue,
  27260. characterData: modifierKeys?.char ?? defaultValue,
  27261. childList: modifierKeys?.child ?? defaultValue,
  27262. subtree: modifierKeys?.sub ?? defaultValue
  27263. }
  27264. };
  27265. const observer = new MutationObserver(function () {
  27266. let mutations = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  27267. let observer = arguments.length > 1 ? arguments[1] : undefined;
  27268. handler?.(mutations, observer);
  27269. if (once) unmounted$2(el, binding);
  27270. });
  27271. if (immediate) handler?.([], observer);
  27272. el._mutate = Object(el._mutate);
  27273. el._mutate[binding.instance.$.uid] = {
  27274. observer
  27275. };
  27276. observer.observe(el, options);
  27277. }
  27278. function unmounted$2(el, binding) {
  27279. if (!el._mutate?.[binding.instance.$.uid]) return;
  27280. el._mutate[binding.instance.$.uid].observer.disconnect();
  27281. delete el._mutate[binding.instance.$.uid];
  27282. }
  27283. const Mutate = {
  27284. mounted: mounted$2,
  27285. unmounted: unmounted$2
  27286. };
  27287. // Types
  27288. function mounted$1(el, binding) {
  27289. const handler = binding.value;
  27290. const options = {
  27291. passive: !binding.modifiers?.active
  27292. };
  27293. window.addEventListener('resize', handler, options);
  27294. el._onResize = Object(el._onResize);
  27295. el._onResize[binding.instance.$.uid] = {
  27296. handler,
  27297. options
  27298. };
  27299. if (!binding.modifiers?.quiet) {
  27300. handler();
  27301. }
  27302. }
  27303. function unmounted$1(el, binding) {
  27304. if (!el._onResize?.[binding.instance.$.uid]) return;
  27305. const {
  27306. handler,
  27307. options
  27308. } = el._onResize[binding.instance.$.uid];
  27309. window.removeEventListener('resize', handler, options);
  27310. delete el._onResize[binding.instance.$.uid];
  27311. }
  27312. const Resize = {
  27313. mounted: mounted$1,
  27314. unmounted: unmounted$1
  27315. };
  27316. // Types
  27317. function mounted(el, binding) {
  27318. const {
  27319. self = false
  27320. } = binding.modifiers ?? {};
  27321. const value = binding.value;
  27322. const options = typeof value === 'object' && value.options || {
  27323. passive: true
  27324. };
  27325. const handler = typeof value === 'function' || 'handleEvent' in value ? value : value.handler;
  27326. const target = self ? el : binding.arg ? document.querySelector(binding.arg) : window;
  27327. if (!target) return;
  27328. target.addEventListener('scroll', handler, options);
  27329. el._onScroll = Object(el._onScroll);
  27330. el._onScroll[binding.instance.$.uid] = {
  27331. handler,
  27332. options,
  27333. // Don't reference self
  27334. target: self ? undefined : target
  27335. };
  27336. }
  27337. function unmounted(el, binding) {
  27338. if (!el._onScroll?.[binding.instance.$.uid]) return;
  27339. const {
  27340. handler,
  27341. options,
  27342. target = el
  27343. } = el._onScroll[binding.instance.$.uid];
  27344. target.removeEventListener('scroll', handler, options);
  27345. delete el._onScroll[binding.instance.$.uid];
  27346. }
  27347. function updated(el, binding) {
  27348. if (binding.value === binding.oldValue) return;
  27349. unmounted(el, binding);
  27350. mounted(el, binding);
  27351. }
  27352. const Scroll = {
  27353. mounted,
  27354. unmounted,
  27355. updated
  27356. };
  27357. // Utilities
  27358. // Types
  27359. function useDirectiveComponent(component, props) {
  27360. const concreteComponent = typeof component === 'string' ? resolveComponent(component) : component;
  27361. const hook = mountComponent(concreteComponent, props);
  27362. return {
  27363. mounted: hook,
  27364. updated: hook,
  27365. unmounted(el) {
  27366. render(null, el);
  27367. }
  27368. };
  27369. }
  27370. function mountComponent(component, props) {
  27371. return function (el, binding, vnode) {
  27372. const _props = typeof props === 'function' ? props(binding) : props;
  27373. const text = binding.value?.text ?? binding.value ?? _props?.text;
  27374. const value = isObject(binding.value) ? binding.value : {};
  27375. // Get the children from the props or directive value, or the element's children
  27376. const children = () => text ?? el.textContent;
  27377. // If vnode.ctx is the same as the instance, then we're bound to a plain element
  27378. // and need to find the nearest parent component instance to inherit provides from
  27379. const provides = (vnode.ctx === binding.instance.$ ? findComponentParent(vnode, binding.instance.$)?.provides : vnode.ctx?.provides) ?? binding.instance.$.provides;
  27380. const node = h(component, mergeProps(_props, value), children);
  27381. node.appContext = Object.assign(Object.create(null), binding.instance.$.appContext, {
  27382. provides
  27383. });
  27384. render(node, el);
  27385. };
  27386. }
  27387. function findComponentParent(vnode, root) {
  27388. // Walk the tree from root until we find the child vnode
  27389. const stack = new Set();
  27390. const walk = children => {
  27391. for (const child of children) {
  27392. if (!child) continue;
  27393. if (child === vnode || child.el && vnode.el && child.el === vnode.el) {
  27394. return true;
  27395. }
  27396. stack.add(child);
  27397. let result;
  27398. if (child.suspense) {
  27399. result = walk([child.ssContent]);
  27400. } else if (Array.isArray(child.children)) {
  27401. result = walk(child.children);
  27402. } else if (child.component?.vnode) {
  27403. result = walk([child.component?.subTree]);
  27404. }
  27405. if (result) {
  27406. return result;
  27407. }
  27408. stack.delete(child);
  27409. }
  27410. return false;
  27411. };
  27412. if (!walk([root.subTree])) {
  27413. consoleError('Could not find original vnode, component will not inherit provides');
  27414. return root;
  27415. }
  27416. // Return the first component parent
  27417. const result = Array.from(stack).reverse();
  27418. for (const child of result) {
  27419. if (child.component) {
  27420. return child.component;
  27421. }
  27422. }
  27423. return root;
  27424. }
  27425. // Components
  27426. // Types
  27427. const Tooltip = useDirectiveComponent(VTooltip, binding => {
  27428. return {
  27429. activator: 'parent',
  27430. location: binding.arg?.replace('-', ' '),
  27431. text: typeof binding.value === 'boolean' ? undefined : binding.value
  27432. };
  27433. });
  27434. var directives = /*#__PURE__*/Object.freeze({
  27435. __proto__: null,
  27436. ClickOutside: ClickOutside,
  27437. Intersect: Intersect,
  27438. Mutate: Mutate,
  27439. Resize: Resize,
  27440. Ripple: Ripple,
  27441. Scroll: Scroll,
  27442. Tooltip: Tooltip,
  27443. Touch: Touch
  27444. });
  27445. // Composables
  27446. function createVuetify$1() {
  27447. let vuetify = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  27448. const {
  27449. blueprint,
  27450. ...rest
  27451. } = vuetify;
  27452. const options = mergeDeep(blueprint, rest);
  27453. const {
  27454. aliases = {},
  27455. components = {},
  27456. directives = {}
  27457. } = options;
  27458. const defaults = createDefaults(options.defaults);
  27459. const display = createDisplay(options.display, options.ssr);
  27460. const theme = createTheme(options.theme);
  27461. const icons = createIcons(options.icons);
  27462. const locale = createLocale(options.locale);
  27463. const date = createDate(options.date, locale);
  27464. const goTo = createGoTo(options.goTo, locale);
  27465. const install = app => {
  27466. for (const key in directives) {
  27467. app.directive(key, directives[key]);
  27468. }
  27469. for (const key in components) {
  27470. app.component(key, components[key]);
  27471. }
  27472. for (const key in aliases) {
  27473. app.component(key, defineComponent({
  27474. ...aliases[key],
  27475. name: key,
  27476. aliasName: aliases[key].name
  27477. }));
  27478. }
  27479. theme.install(app);
  27480. app.provide(DefaultsSymbol, defaults);
  27481. app.provide(DisplaySymbol, display);
  27482. app.provide(ThemeSymbol, theme);
  27483. app.provide(IconSymbol, icons);
  27484. app.provide(LocaleSymbol, locale);
  27485. app.provide(DateOptionsSymbol, date.options);
  27486. app.provide(DateAdapterSymbol, date.instance);
  27487. app.provide(GoToSymbol, goTo);
  27488. if (IN_BROWSER && options.ssr) {
  27489. if (app.$nuxt) {
  27490. app.$nuxt.hook('app:suspense:resolve', () => {
  27491. display.update();
  27492. });
  27493. } else {
  27494. const {
  27495. mount
  27496. } = app;
  27497. app.mount = function () {
  27498. const vm = mount(...arguments);
  27499. nextTick(() => display.update());
  27500. app.mount = mount;
  27501. return vm;
  27502. };
  27503. }
  27504. }
  27505. getUid.reset();
  27506. if (typeof __VUE_OPTIONS_API__ !== 'boolean' || __VUE_OPTIONS_API__) {
  27507. app.mixin({
  27508. computed: {
  27509. $vuetify() {
  27510. return reactive({
  27511. defaults: inject.call(this, DefaultsSymbol),
  27512. display: inject.call(this, DisplaySymbol),
  27513. theme: inject.call(this, ThemeSymbol),
  27514. icons: inject.call(this, IconSymbol),
  27515. locale: inject.call(this, LocaleSymbol),
  27516. date: inject.call(this, DateAdapterSymbol)
  27517. });
  27518. }
  27519. }
  27520. });
  27521. }
  27522. };
  27523. return {
  27524. install,
  27525. defaults,
  27526. display,
  27527. theme,
  27528. icons,
  27529. locale,
  27530. date,
  27531. goTo
  27532. };
  27533. }
  27534. const version$1 = "3.7.6";
  27535. createVuetify$1.version = version$1;
  27536. // Vue's inject() can only be used in setup
  27537. function inject(key) {
  27538. const vm = this.$;
  27539. const provides = vm.parent?.provides ?? vm.vnode.appContext?.provides;
  27540. if (provides && key in provides) {
  27541. return provides[key];
  27542. }
  27543. }
  27544. /* eslint-disable local-rules/sort-imports */
  27545. // Types
  27546. const createVuetify = function () {
  27547. let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  27548. return createVuetify$1({
  27549. components,
  27550. directives,
  27551. ...options
  27552. });
  27553. };
  27554. const version = "3.7.6";
  27555. createVuetify.version = version;
  27556. export { index as blueprints, components, createVuetify, directives, useDate, useDefaults, useDisplay, useGoTo, useLayout, useLocale, useRtl, useTheme, version };
  27557. //# sourceMappingURL=vuetify.esm.js.map