vuetify-labs.esm.js 699 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377
  1. /*!
  2. * Vuetify v3.3.11
  3. * Forged by John Leider
  4. * Released under the MIT License.
  5. */
  6. import { Fragment, reactive, computed, watchEffect, toRefs, capitalize, warn, watch, onScopeDispose, effectScope, ref, unref, provide, shallowRef, inject as inject$1, defineComponent as defineComponent$1, camelize, h, getCurrentInstance as getCurrentInstance$1, onBeforeUnmount, readonly, onDeactivated, onActivated, onMounted, toRaw, createVNode, TransitionGroup, Transition, mergeProps, onBeforeMount, nextTick, withDirectives, resolveDirective, vShow, isRef, toRef, Text, resolveDynamicComponent, Teleport, cloneVNode, createTextVNode, onBeforeUpdate, vModelText, withModifiers } from 'vue';
  7. // Types
  8. // eslint-disable-line vue/prefer-import-from-vue
  9. /**
  10. * Creates a factory function for props definitions.
  11. * This is used to define props in a composable then override
  12. * default values in an implementing component.
  13. *
  14. * @example Simplified signature
  15. * (props: Props) => (defaults?: Record<keyof props, any>) => Props
  16. *
  17. * @example Usage
  18. * const makeProps = propsFactory({
  19. * foo: String,
  20. * })
  21. *
  22. * defineComponent({
  23. * props: {
  24. * ...makeProps({
  25. * foo: 'a',
  26. * }),
  27. * },
  28. * setup (props) {
  29. * // would be "string | undefined", now "string" because a default has been provided
  30. * props.foo
  31. * },
  32. * }
  33. */
  34. function propsFactory(props, source) {
  35. return defaults => {
  36. return Object.keys(props).reduce((obj, prop) => {
  37. const isObjectDefinition = typeof props[prop] === 'object' && props[prop] != null && !Array.isArray(props[prop]);
  38. const definition = isObjectDefinition ? props[prop] : {
  39. type: props[prop]
  40. };
  41. if (defaults && prop in defaults) {
  42. obj[prop] = {
  43. ...definition,
  44. default: defaults[prop]
  45. };
  46. } else {
  47. obj[prop] = definition;
  48. }
  49. if (source && !obj[prop].source) {
  50. obj[prop].source = source;
  51. }
  52. return obj;
  53. }, {});
  54. };
  55. }
  56. // Utilities
  57. // Types
  58. // Composables
  59. const makeComponentProps = propsFactory({
  60. class: [String, Array],
  61. style: {
  62. type: [String, Array, Object],
  63. default: null
  64. }
  65. }, 'component');
  66. const IN_BROWSER = typeof window !== 'undefined';
  67. const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
  68. const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
  69. function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
  70. function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
  71. function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; }
  72. function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } }
  73. function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); }
  74. function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); }
  75. function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; }
  76. // Types
  77. function getNestedValue(obj, path, fallback) {
  78. const last = path.length - 1;
  79. if (last < 0) return obj === undefined ? fallback : obj;
  80. for (let i = 0; i < last; i++) {
  81. if (obj == null) {
  82. return fallback;
  83. }
  84. obj = obj[path[i]];
  85. }
  86. if (obj == null) return fallback;
  87. return obj[path[last]] === undefined ? fallback : obj[path[last]];
  88. }
  89. function deepEqual(a, b) {
  90. if (a === b) return true;
  91. if (a instanceof Date && b instanceof Date && a.getTime() !== b.getTime()) {
  92. // If the values are Date, compare them as timestamps
  93. return false;
  94. }
  95. if (a !== Object(a) || b !== Object(b)) {
  96. // If the values aren't objects, they were already checked for equality
  97. return false;
  98. }
  99. const props = Object.keys(a);
  100. if (props.length !== Object.keys(b).length) {
  101. // Different number of props, don't bother to check
  102. return false;
  103. }
  104. return props.every(p => deepEqual(a[p], b[p]));
  105. }
  106. function getObjectValueByPath(obj, path, fallback) {
  107. // credit: http://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key#comment55278413_6491621
  108. if (obj == null || !path || typeof path !== 'string') return fallback;
  109. if (obj[path] !== undefined) return obj[path];
  110. path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
  111. path = path.replace(/^\./, ''); // strip a leading dot
  112. return getNestedValue(obj, path.split('.'), fallback);
  113. }
  114. function getPropertyFromItem(item, property, fallback) {
  115. if (property == null) return item === undefined ? fallback : item;
  116. if (item !== Object(item)) {
  117. if (typeof property !== 'function') return fallback;
  118. const value = property(item, fallback);
  119. return typeof value === 'undefined' ? fallback : value;
  120. }
  121. if (typeof property === 'string') return getObjectValueByPath(item, property, fallback);
  122. if (Array.isArray(property)) return getNestedValue(item, property, fallback);
  123. if (typeof property !== 'function') return fallback;
  124. const value = property(item, fallback);
  125. return typeof value === 'undefined' ? fallback : value;
  126. }
  127. function createRange(length) {
  128. let start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  129. return Array.from({
  130. length
  131. }, (v, k) => start + k);
  132. }
  133. function convertToUnit(str) {
  134. let unit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'px';
  135. if (str == null || str === '') {
  136. return undefined;
  137. } else if (isNaN(+str)) {
  138. return String(str);
  139. } else if (!isFinite(+str)) {
  140. return undefined;
  141. } else {
  142. return `${Number(str)}${unit}`;
  143. }
  144. }
  145. function isObject(obj) {
  146. return obj !== null && typeof obj === 'object' && !Array.isArray(obj);
  147. }
  148. function refElement(obj) {
  149. return obj && '$el' in obj ? obj.$el : obj;
  150. }
  151. // KeyboardEvent.keyCode aliases
  152. const keyCodes = Object.freeze({
  153. enter: 13,
  154. tab: 9,
  155. delete: 46,
  156. esc: 27,
  157. space: 32,
  158. up: 38,
  159. down: 40,
  160. left: 37,
  161. right: 39,
  162. end: 35,
  163. home: 36,
  164. del: 46,
  165. backspace: 8,
  166. insert: 45,
  167. pageup: 33,
  168. pagedown: 34,
  169. shift: 16
  170. });
  171. const keyValues = Object.freeze({
  172. enter: 'Enter',
  173. tab: 'Tab',
  174. delete: 'Delete',
  175. esc: 'Escape',
  176. space: 'Space',
  177. up: 'ArrowUp',
  178. down: 'ArrowDown',
  179. left: 'ArrowLeft',
  180. right: 'ArrowRight',
  181. end: 'End',
  182. home: 'Home',
  183. del: 'Delete',
  184. backspace: 'Backspace',
  185. insert: 'Insert',
  186. pageup: 'PageUp',
  187. pagedown: 'PageDown',
  188. shift: 'Shift'
  189. });
  190. function keys(o) {
  191. return Object.keys(o);
  192. }
  193. function has(obj, key) {
  194. return key.every(k => obj.hasOwnProperty(k));
  195. }
  196. function pick(obj, paths, exclude) {
  197. const found = Object.create(null);
  198. const rest = Object.create(null);
  199. for (const key in obj) {
  200. if (paths.some(path => path instanceof RegExp ? path.test(key) : path === key) && !exclude?.some(path => path === key)) {
  201. found[key] = obj[key];
  202. } else {
  203. rest[key] = obj[key];
  204. }
  205. }
  206. return [found, rest];
  207. }
  208. function omit(obj, exclude) {
  209. const clone = {
  210. ...obj
  211. };
  212. exclude.forEach(prop => delete clone[prop]);
  213. return clone;
  214. }
  215. function only(obj, include) {
  216. const clone = {};
  217. include.forEach(prop => clone[prop] = obj[prop]);
  218. return clone;
  219. }
  220. /**
  221. * Filter attributes that should be applied to
  222. * the root element of a an input component. Remaining
  223. * attributes should be passed to the <input> element inside.
  224. */
  225. function filterInputAttrs(attrs) {
  226. return pick(attrs, ['class', 'style', 'id', /^data-/]);
  227. }
  228. function wrapInArray(v) {
  229. return v == null ? [] : Array.isArray(v) ? v : [v];
  230. }
  231. function clamp(value) {
  232. let min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  233. let max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
  234. return Math.max(min, Math.min(max, value));
  235. }
  236. function getDecimals(value) {
  237. const trimmedStr = value.toString().trim();
  238. return trimmedStr.includes('.') ? trimmedStr.length - trimmedStr.indexOf('.') - 1 : 0;
  239. }
  240. function padEnd(str, length) {
  241. let char = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '0';
  242. return str + char.repeat(Math.max(0, length - str.length));
  243. }
  244. function chunk(str) {
  245. let size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
  246. const chunked = [];
  247. let index = 0;
  248. while (index < str.length) {
  249. chunked.push(str.substr(index, size));
  250. index += size;
  251. }
  252. return chunked;
  253. }
  254. function humanReadableFileSize(bytes) {
  255. let base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;
  256. if (bytes < base) {
  257. return `${bytes} B`;
  258. }
  259. const prefix = base === 1024 ? ['Ki', 'Mi', 'Gi'] : ['k', 'M', 'G'];
  260. let unit = -1;
  261. while (Math.abs(bytes) >= base && unit < prefix.length - 1) {
  262. bytes /= base;
  263. ++unit;
  264. }
  265. return `${bytes.toFixed(1)} ${prefix[unit]}B`;
  266. }
  267. function mergeDeep() {
  268. let source = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  269. let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  270. let arrayFn = arguments.length > 2 ? arguments[2] : undefined;
  271. const out = {};
  272. for (const key in source) {
  273. out[key] = source[key];
  274. }
  275. for (const key in target) {
  276. const sourceProperty = source[key];
  277. const targetProperty = target[key];
  278. // Only continue deep merging if
  279. // both properties are objects
  280. if (isObject(sourceProperty) && isObject(targetProperty)) {
  281. out[key] = mergeDeep(sourceProperty, targetProperty, arrayFn);
  282. continue;
  283. }
  284. if (Array.isArray(sourceProperty) && Array.isArray(targetProperty) && arrayFn) {
  285. out[key] = arrayFn(sourceProperty, targetProperty);
  286. continue;
  287. }
  288. out[key] = targetProperty;
  289. }
  290. return out;
  291. }
  292. function flattenFragments(nodes) {
  293. return nodes.map(node => {
  294. if (node.type === Fragment) {
  295. return flattenFragments(node.children);
  296. } else {
  297. return node;
  298. }
  299. }).flat();
  300. }
  301. function toKebabCase() {
  302. let str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  303. if (toKebabCase.cache.has(str)) return toKebabCase.cache.get(str);
  304. const kebab = str.replace(/[^a-z]/gi, '-').replace(/\B([A-Z])/g, '-$1').toLowerCase();
  305. toKebabCase.cache.set(str, kebab);
  306. return kebab;
  307. }
  308. toKebabCase.cache = new Map();
  309. function findChildrenWithProvide(key, vnode) {
  310. if (!vnode || typeof vnode !== 'object') return [];
  311. if (Array.isArray(vnode)) {
  312. return vnode.map(child => findChildrenWithProvide(key, child)).flat(1);
  313. } else if (Array.isArray(vnode.children)) {
  314. return vnode.children.map(child => findChildrenWithProvide(key, child)).flat(1);
  315. } else if (vnode.component) {
  316. if (Object.getOwnPropertySymbols(vnode.component.provides).includes(key)) {
  317. return [vnode.component];
  318. } else if (vnode.component.subTree) {
  319. return findChildrenWithProvide(key, vnode.component.subTree).flat(1);
  320. }
  321. }
  322. return [];
  323. }
  324. var _arr = /*#__PURE__*/new WeakMap();
  325. var _pointer = /*#__PURE__*/new WeakMap();
  326. class CircularBuffer {
  327. constructor(size) {
  328. _classPrivateFieldInitSpec(this, _arr, {
  329. writable: true,
  330. value: []
  331. });
  332. _classPrivateFieldInitSpec(this, _pointer, {
  333. writable: true,
  334. value: 0
  335. });
  336. this.size = size;
  337. }
  338. push(val) {
  339. _classPrivateFieldGet(this, _arr)[_classPrivateFieldGet(this, _pointer)] = val;
  340. _classPrivateFieldSet(this, _pointer, (_classPrivateFieldGet(this, _pointer) + 1) % this.size);
  341. }
  342. values() {
  343. return _classPrivateFieldGet(this, _arr).slice(_classPrivateFieldGet(this, _pointer)).concat(_classPrivateFieldGet(this, _arr).slice(0, _classPrivateFieldGet(this, _pointer)));
  344. }
  345. }
  346. function getEventCoordinates(e) {
  347. if ('touches' in e) {
  348. return {
  349. clientX: e.touches[0].clientX,
  350. clientY: e.touches[0].clientY
  351. };
  352. }
  353. return {
  354. clientX: e.clientX,
  355. clientY: e.clientY
  356. };
  357. }
  358. // Only allow a single return type
  359. function destructComputed(getter) {
  360. const refs = reactive({});
  361. const base = computed(getter);
  362. watchEffect(() => {
  363. for (const key in base.value) {
  364. refs[key] = base.value[key];
  365. }
  366. }, {
  367. flush: 'sync'
  368. });
  369. return toRefs(refs);
  370. }
  371. /** Array.includes but value can be any type */
  372. function includes(arr, val) {
  373. return arr.includes(val);
  374. }
  375. const onRE = /^on[^a-z]/;
  376. const isOn = key => onRE.test(key);
  377. function eventName(propName) {
  378. return propName[2].toLowerCase() + propName.slice(3);
  379. }
  380. const EventProp = () => [Function, Array];
  381. function hasEvent(props, name) {
  382. name = 'on' + capitalize(name);
  383. return !!(props[name] || props[`${name}Once`] || props[`${name}Capture`] || props[`${name}OnceCapture`] || props[`${name}CaptureOnce`]);
  384. }
  385. function callEvent(handler) {
  386. for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
  387. args[_key2 - 1] = arguments[_key2];
  388. }
  389. if (Array.isArray(handler)) {
  390. for (const h of handler) {
  391. h(...args);
  392. }
  393. } else if (typeof handler === 'function') {
  394. handler(...args);
  395. }
  396. }
  397. function focusableChildren(el) {
  398. let filterByTabIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  399. const targets = ['button', '[href]', 'input:not([type="hidden"])', 'select', 'textarea', '[tabindex]'].map(s => `${s}${filterByTabIndex ? ':not([tabindex="-1"])' : ''}:not([disabled])`).join(', ');
  400. return [...el.querySelectorAll(targets)];
  401. }
  402. function getNextElement(elements, location, condition) {
  403. let _el;
  404. let idx = elements.indexOf(document.activeElement);
  405. const inc = location === 'next' ? 1 : -1;
  406. do {
  407. idx += inc;
  408. _el = elements[idx];
  409. } while ((!_el || _el.offsetParent == null || !(condition?.(_el) ?? true)) && idx < elements.length && idx >= 0);
  410. return _el;
  411. }
  412. function focusChild(el, location) {
  413. const focusable = focusableChildren(el);
  414. if (!location) {
  415. if (el === document.activeElement || !el.contains(document.activeElement)) {
  416. focusable[0]?.focus();
  417. }
  418. } else if (location === 'first') {
  419. focusable[0]?.focus();
  420. } else if (location === 'last') {
  421. focusable.at(-1)?.focus();
  422. } else if (typeof location === 'number') {
  423. focusable[location]?.focus();
  424. } else {
  425. const _el = getNextElement(focusable, location);
  426. if (_el) _el.focus();else focusChild(el, location === 'next' ? 'first' : 'last');
  427. }
  428. }
  429. function isEmpty(val) {
  430. return val === null || val === undefined || typeof val === 'string' && val.trim() === '';
  431. }
  432. function noop() {}
  433. /** Returns null if the selector is not supported or we can't check */
  434. function matchesSelector(el, selector) {
  435. const supportsSelector = IN_BROWSER && typeof CSS !== 'undefined' && typeof CSS.supports !== 'undefined' && CSS.supports(`selector(${selector})`);
  436. if (!supportsSelector) return null;
  437. try {
  438. return !!el && el.matches(selector);
  439. } catch (err) {
  440. return null;
  441. }
  442. }
  443. // Utilities
  444. const block = ['top', 'bottom'];
  445. const inline = ['start', 'end', 'left', 'right'];
  446. /** Parse a raw anchor string into an object */
  447. function parseAnchor(anchor, isRtl) {
  448. let [side, align] = anchor.split(' ');
  449. if (!align) {
  450. align = includes(block, side) ? 'start' : includes(inline, side) ? 'top' : 'center';
  451. }
  452. return {
  453. side: toPhysical(side, isRtl),
  454. align: toPhysical(align, isRtl)
  455. };
  456. }
  457. function toPhysical(str, isRtl) {
  458. if (str === 'start') return isRtl ? 'right' : 'left';
  459. if (str === 'end') return isRtl ? 'left' : 'right';
  460. return str;
  461. }
  462. function flipSide(anchor) {
  463. return {
  464. side: {
  465. center: 'center',
  466. top: 'bottom',
  467. bottom: 'top',
  468. left: 'right',
  469. right: 'left'
  470. }[anchor.side],
  471. align: anchor.align
  472. };
  473. }
  474. function flipAlign(anchor) {
  475. return {
  476. side: anchor.side,
  477. align: {
  478. center: 'center',
  479. top: 'bottom',
  480. bottom: 'top',
  481. left: 'right',
  482. right: 'left'
  483. }[anchor.align]
  484. };
  485. }
  486. function flipCorner(anchor) {
  487. return {
  488. side: anchor.align,
  489. align: anchor.side
  490. };
  491. }
  492. function getAxis(anchor) {
  493. return includes(block, anchor.side) ? 'y' : 'x';
  494. }
  495. class Box {
  496. constructor(_ref) {
  497. let {
  498. x,
  499. y,
  500. width,
  501. height
  502. } = _ref;
  503. this.x = x;
  504. this.y = y;
  505. this.width = width;
  506. this.height = height;
  507. }
  508. get top() {
  509. return this.y;
  510. }
  511. get bottom() {
  512. return this.y + this.height;
  513. }
  514. get left() {
  515. return this.x;
  516. }
  517. get right() {
  518. return this.x + this.width;
  519. }
  520. }
  521. function getOverflow(a, b) {
  522. return {
  523. x: {
  524. before: Math.max(0, b.left - a.left),
  525. after: Math.max(0, a.right - b.right)
  526. },
  527. y: {
  528. before: Math.max(0, b.top - a.top),
  529. after: Math.max(0, a.bottom - b.bottom)
  530. }
  531. };
  532. }
  533. // Utilities
  534. /** @see https://stackoverflow.com/a/57876601/2074736 */
  535. function nullifyTransforms(el) {
  536. const rect = el.getBoundingClientRect();
  537. const style = getComputedStyle(el);
  538. const tx = style.transform;
  539. if (tx) {
  540. let ta, sx, sy, dx, dy;
  541. if (tx.startsWith('matrix3d(')) {
  542. ta = tx.slice(9, -1).split(/, /);
  543. sx = +ta[0];
  544. sy = +ta[5];
  545. dx = +ta[12];
  546. dy = +ta[13];
  547. } else if (tx.startsWith('matrix(')) {
  548. ta = tx.slice(7, -1).split(/, /);
  549. sx = +ta[0];
  550. sy = +ta[3];
  551. dx = +ta[4];
  552. dy = +ta[5];
  553. } else {
  554. return new Box(rect);
  555. }
  556. const to = style.transformOrigin;
  557. const x = rect.x - dx - (1 - sx) * parseFloat(to);
  558. const y = rect.y - dy - (1 - sy) * parseFloat(to.slice(to.indexOf(' ') + 1));
  559. const w = sx ? rect.width / sx : el.offsetWidth + 1;
  560. const h = sy ? rect.height / sy : el.offsetHeight + 1;
  561. return new Box({
  562. x,
  563. y,
  564. width: w,
  565. height: h
  566. });
  567. } else {
  568. return new Box(rect);
  569. }
  570. }
  571. function animate(el, keyframes, options) {
  572. if (typeof el.animate === 'undefined') return {
  573. finished: Promise.resolve()
  574. };
  575. let animation;
  576. try {
  577. animation = el.animate(keyframes, options);
  578. } catch (err) {
  579. return {
  580. finished: Promise.resolve()
  581. };
  582. }
  583. if (typeof animation.finished === 'undefined') {
  584. animation.finished = new Promise(resolve => {
  585. animation.onfinish = () => {
  586. resolve(animation);
  587. };
  588. });
  589. }
  590. return animation;
  591. }
  592. // Utilities
  593. const handlers = new WeakMap();
  594. function bindProps(el, props) {
  595. Object.keys(props).forEach(k => {
  596. if (isOn(k)) {
  597. const name = eventName(k);
  598. const handler = handlers.get(el);
  599. if (props[k] == null) {
  600. handler?.forEach(v => {
  601. const [n, fn] = v;
  602. if (n === name) {
  603. el.removeEventListener(name, fn);
  604. handler.delete(v);
  605. }
  606. });
  607. } else if (!handler || ![...handler]?.some(v => v[0] === name && v[1] === props[k])) {
  608. el.addEventListener(name, props[k]);
  609. const _handler = handler || new Set();
  610. _handler.add([name, props[k]]);
  611. if (!handlers.has(el)) handlers.set(el, _handler);
  612. }
  613. } else {
  614. if (props[k] == null) {
  615. el.removeAttribute(k);
  616. } else {
  617. el.setAttribute(k, props[k]);
  618. }
  619. }
  620. });
  621. }
  622. function unbindProps(el, props) {
  623. Object.keys(props).forEach(k => {
  624. if (isOn(k)) {
  625. const name = eventName(k);
  626. const handler = handlers.get(el);
  627. handler?.forEach(v => {
  628. const [n, fn] = v;
  629. if (n === name) {
  630. el.removeEventListener(name, fn);
  631. handler.delete(v);
  632. }
  633. });
  634. } else {
  635. el.removeAttribute(k);
  636. }
  637. });
  638. }
  639. /* eslint-disable no-console */
  640. function consoleWarn(message) {
  641. warn(`Vuetify: ${message}`);
  642. }
  643. function consoleError(message) {
  644. warn(`Vuetify error: ${message}`);
  645. }
  646. function deprecate(original, replacement) {
  647. replacement = Array.isArray(replacement) ? replacement.slice(0, -1).map(s => `'${s}'`).join(', ') + ` or '${replacement.at(-1)}'` : `'${replacement}'`;
  648. warn(`[Vuetify UPGRADE] '${original}' is deprecated, use ${replacement} instead.`);
  649. }
  650. // Types
  651. const delta = 0.20689655172413793; // 6÷29
  652. const cielabForwardTransform = t => t > delta ** 3 ? Math.cbrt(t) : t / (3 * delta ** 2) + 4 / 29;
  653. const cielabReverseTransform = t => t > delta ? t ** 3 : 3 * delta ** 2 * (t - 4 / 29);
  654. function fromXYZ$1(xyz) {
  655. const transform = cielabForwardTransform;
  656. const transformedY = transform(xyz[1]);
  657. return [116 * transformedY - 16, 500 * (transform(xyz[0] / 0.95047) - transformedY), 200 * (transformedY - transform(xyz[2] / 1.08883))];
  658. }
  659. function toXYZ$1(lab) {
  660. const transform = cielabReverseTransform;
  661. const Ln = (lab[0] + 16) / 116;
  662. return [transform(Ln + lab[1] / 500) * 0.95047, transform(Ln), transform(Ln - lab[2] / 200) * 1.08883];
  663. }
  664. // Utilities
  665. // Types
  666. // For converting XYZ to sRGB
  667. const srgbForwardMatrix = [[3.2406, -1.5372, -0.4986], [-0.9689, 1.8758, 0.0415], [0.0557, -0.2040, 1.0570]];
  668. // Forward gamma adjust
  669. const srgbForwardTransform = C => C <= 0.0031308 ? C * 12.92 : 1.055 * C ** (1 / 2.4) - 0.055;
  670. // For converting sRGB to XYZ
  671. const srgbReverseMatrix = [[0.4124, 0.3576, 0.1805], [0.2126, 0.7152, 0.0722], [0.0193, 0.1192, 0.9505]];
  672. // Reverse gamma adjust
  673. const srgbReverseTransform = C => C <= 0.04045 ? C / 12.92 : ((C + 0.055) / 1.055) ** 2.4;
  674. function fromXYZ(xyz) {
  675. const rgb = Array(3);
  676. const transform = srgbForwardTransform;
  677. const matrix = srgbForwardMatrix;
  678. // Matrix transform, then gamma adjustment
  679. for (let i = 0; i < 3; ++i) {
  680. // Rescale back to [0, 255]
  681. rgb[i] = Math.round(clamp(transform(matrix[i][0] * xyz[0] + matrix[i][1] * xyz[1] + matrix[i][2] * xyz[2])) * 255);
  682. }
  683. return {
  684. r: rgb[0],
  685. g: rgb[1],
  686. b: rgb[2]
  687. };
  688. }
  689. function toXYZ(_ref) {
  690. let {
  691. r,
  692. g,
  693. b
  694. } = _ref;
  695. const xyz = [0, 0, 0];
  696. const transform = srgbReverseTransform;
  697. const matrix = srgbReverseMatrix;
  698. // Rescale from [0, 255] to [0, 1] then adjust sRGB gamma to linear RGB
  699. r = transform(r / 255);
  700. g = transform(g / 255);
  701. b = transform(b / 255);
  702. // Matrix color space transform
  703. for (let i = 0; i < 3; ++i) {
  704. xyz[i] = matrix[i][0] * r + matrix[i][1] * g + matrix[i][2] * b;
  705. }
  706. return xyz;
  707. }
  708. // Utilities
  709. // Types
  710. function isCssColor(color) {
  711. return !!color && /^(#|var\(--|(rgb|hsl)a?\()/.test(color);
  712. }
  713. const cssColorRe = /^(?<fn>(?:rgb|hsl)a?)\((?<values>.+)\)/;
  714. const mappers = {
  715. rgb: (r, g, b, a) => ({
  716. r,
  717. g,
  718. b,
  719. a
  720. }),
  721. rgba: (r, g, b, a) => ({
  722. r,
  723. g,
  724. b,
  725. a
  726. }),
  727. hsl: (h, s, l, a) => HSLtoRGB({
  728. h,
  729. s,
  730. l,
  731. a
  732. }),
  733. hsla: (h, s, l, a) => HSLtoRGB({
  734. h,
  735. s,
  736. l,
  737. a
  738. }),
  739. hsv: (h, s, v, a) => HSVtoRGB({
  740. h,
  741. s,
  742. v,
  743. a
  744. }),
  745. hsva: (h, s, v, a) => HSVtoRGB({
  746. h,
  747. s,
  748. v,
  749. a
  750. })
  751. };
  752. function parseColor(color) {
  753. if (typeof color === 'number') {
  754. if (isNaN(color) || color < 0 || color > 0xFFFFFF) {
  755. // int can't have opacity
  756. consoleWarn(`'${color}' is not a valid hex color`);
  757. }
  758. return {
  759. r: (color & 0xFF0000) >> 16,
  760. g: (color & 0xFF00) >> 8,
  761. b: color & 0xFF
  762. };
  763. } else if (typeof color === 'string' && cssColorRe.test(color)) {
  764. const {
  765. groups
  766. } = color.match(cssColorRe);
  767. const {
  768. fn,
  769. values
  770. } = groups;
  771. const realValues = values.split(/,\s*/).map(v => {
  772. if (v.endsWith('%') && ['hsl', 'hsla', 'hsv', 'hsva'].includes(fn)) {
  773. return parseFloat(v) / 100;
  774. } else {
  775. return parseFloat(v);
  776. }
  777. });
  778. return mappers[fn](...realValues);
  779. } else if (typeof color === 'string') {
  780. let hex = color.startsWith('#') ? color.slice(1) : color;
  781. if ([3, 4].includes(hex.length)) {
  782. hex = hex.split('').map(char => char + char).join('');
  783. } else if (![6, 8].includes(hex.length)) {
  784. consoleWarn(`'${color}' is not a valid hex(a) color`);
  785. }
  786. const int = parseInt(hex, 16);
  787. if (isNaN(int) || int < 0 || int > 0xFFFFFFFF) {
  788. consoleWarn(`'${color}' is not a valid hex(a) color`);
  789. }
  790. return HexToRGB(hex);
  791. } else if (typeof color === 'object') {
  792. if (has(color, ['r', 'g', 'b'])) {
  793. return color;
  794. } else if (has(color, ['h', 's', 'l'])) {
  795. return HSVtoRGB(HSLtoHSV(color));
  796. } else if (has(color, ['h', 's', 'v'])) {
  797. return HSVtoRGB(color);
  798. }
  799. }
  800. throw new TypeError(`Invalid color: ${color == null ? color : String(color) || color.constructor.name}\nExpected #hex, #hexa, rgb(), rgba(), hsl(), hsla(), object or number`);
  801. }
  802. /** Converts HSVA to RGBA. Based on formula from https://en.wikipedia.org/wiki/HSL_and_HSV */
  803. function HSVtoRGB(hsva) {
  804. const {
  805. h,
  806. s,
  807. v,
  808. a
  809. } = hsva;
  810. const f = n => {
  811. const k = (n + h / 60) % 6;
  812. return v - v * s * Math.max(Math.min(k, 4 - k, 1), 0);
  813. };
  814. const rgb = [f(5), f(3), f(1)].map(v => Math.round(v * 255));
  815. return {
  816. r: rgb[0],
  817. g: rgb[1],
  818. b: rgb[2],
  819. a
  820. };
  821. }
  822. function HSLtoRGB(hsla) {
  823. return HSVtoRGB(HSLtoHSV(hsla));
  824. }
  825. /** Converts RGBA to HSVA. Based on formula from https://en.wikipedia.org/wiki/HSL_and_HSV */
  826. function RGBtoHSV(rgba) {
  827. if (!rgba) return {
  828. h: 0,
  829. s: 1,
  830. v: 1,
  831. a: 1
  832. };
  833. const r = rgba.r / 255;
  834. const g = rgba.g / 255;
  835. const b = rgba.b / 255;
  836. const max = Math.max(r, g, b);
  837. const min = Math.min(r, g, b);
  838. let h = 0;
  839. if (max !== min) {
  840. if (max === r) {
  841. h = 60 * (0 + (g - b) / (max - min));
  842. } else if (max === g) {
  843. h = 60 * (2 + (b - r) / (max - min));
  844. } else if (max === b) {
  845. h = 60 * (4 + (r - g) / (max - min));
  846. }
  847. }
  848. if (h < 0) h = h + 360;
  849. const s = max === 0 ? 0 : (max - min) / max;
  850. const hsv = [h, s, max];
  851. return {
  852. h: hsv[0],
  853. s: hsv[1],
  854. v: hsv[2],
  855. a: rgba.a
  856. };
  857. }
  858. function HSVtoHSL(hsva) {
  859. const {
  860. h,
  861. s,
  862. v,
  863. a
  864. } = hsva;
  865. const l = v - v * s / 2;
  866. const sprime = l === 1 || l === 0 ? 0 : (v - l) / Math.min(l, 1 - l);
  867. return {
  868. h,
  869. s: sprime,
  870. l,
  871. a
  872. };
  873. }
  874. function HSLtoHSV(hsl) {
  875. const {
  876. h,
  877. s,
  878. l,
  879. a
  880. } = hsl;
  881. const v = l + s * Math.min(l, 1 - l);
  882. const sprime = v === 0 ? 0 : 2 - 2 * l / v;
  883. return {
  884. h,
  885. s: sprime,
  886. v,
  887. a
  888. };
  889. }
  890. function RGBtoCSS(_ref) {
  891. let {
  892. r,
  893. g,
  894. b,
  895. a
  896. } = _ref;
  897. return a === undefined ? `rgb(${r}, ${g}, ${b})` : `rgba(${r}, ${g}, ${b}, ${a})`;
  898. }
  899. function HSVtoCSS(hsva) {
  900. return RGBtoCSS(HSVtoRGB(hsva));
  901. }
  902. function toHex(v) {
  903. const h = Math.round(v).toString(16);
  904. return ('00'.substr(0, 2 - h.length) + h).toUpperCase();
  905. }
  906. function RGBtoHex(_ref2) {
  907. let {
  908. r,
  909. g,
  910. b,
  911. a
  912. } = _ref2;
  913. return `#${[toHex(r), toHex(g), toHex(b), a !== undefined ? toHex(Math.round(a * 255)) : ''].join('')}`;
  914. }
  915. function HexToRGB(hex) {
  916. hex = parseHex(hex);
  917. let [r, g, b, a] = chunk(hex, 2).map(c => parseInt(c, 16));
  918. a = a === undefined ? a : a / 255;
  919. return {
  920. r,
  921. g,
  922. b,
  923. a
  924. };
  925. }
  926. function HexToHSV(hex) {
  927. const rgb = HexToRGB(hex);
  928. return RGBtoHSV(rgb);
  929. }
  930. function HSVtoHex(hsva) {
  931. return RGBtoHex(HSVtoRGB(hsva));
  932. }
  933. function parseHex(hex) {
  934. if (hex.startsWith('#')) {
  935. hex = hex.slice(1);
  936. }
  937. hex = hex.replace(/([^0-9a-f])/gi, 'F');
  938. if (hex.length === 3 || hex.length === 4) {
  939. hex = hex.split('').map(x => x + x).join('');
  940. }
  941. if (hex.length !== 6) {
  942. hex = padEnd(padEnd(hex, 6), 8, 'F');
  943. }
  944. return hex;
  945. }
  946. function lighten(value, amount) {
  947. const lab = fromXYZ$1(toXYZ(value));
  948. lab[0] = lab[0] + amount * 10;
  949. return fromXYZ(toXYZ$1(lab));
  950. }
  951. function darken(value, amount) {
  952. const lab = fromXYZ$1(toXYZ(value));
  953. lab[0] = lab[0] - amount * 10;
  954. return fromXYZ(toXYZ$1(lab));
  955. }
  956. /**
  957. * Calculate the relative luminance of a given color
  958. * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef
  959. */
  960. function getLuma(color) {
  961. const rgb = parseColor(color);
  962. return toXYZ(rgb)[1];
  963. }
  964. /**
  965. * Returns the contrast ratio (1-21) between two colors.
  966. * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef
  967. */
  968. function getContrast(first, second) {
  969. const l1 = getLuma(first);
  970. const l2 = getLuma(second);
  971. const light = Math.max(l1, l2);
  972. const dark = Math.min(l1, l2);
  973. return (light + 0.05) / (dark + 0.05);
  974. }
  975. // Utilities
  976. // Types
  977. function useToggleScope(source, fn) {
  978. let scope;
  979. function start() {
  980. scope = effectScope();
  981. scope.run(() => fn.length ? fn(() => {
  982. scope?.stop();
  983. start();
  984. }) : fn());
  985. }
  986. watch(source, active => {
  987. if (active && !scope) {
  988. start();
  989. } else if (!active) {
  990. scope?.stop();
  991. scope = undefined;
  992. }
  993. }, {
  994. immediate: true
  995. });
  996. onScopeDispose(() => {
  997. scope?.stop();
  998. });
  999. }
  1000. // Composables
  1001. // Types
  1002. const DefaultsSymbol = Symbol.for('vuetify:defaults');
  1003. function createDefaults(options) {
  1004. return ref(options);
  1005. }
  1006. function injectDefaults() {
  1007. const defaults = inject$1(DefaultsSymbol);
  1008. if (!defaults) throw new Error('[Vuetify] Could not find defaults instance');
  1009. return defaults;
  1010. }
  1011. function provideDefaults(defaults, options) {
  1012. const injectedDefaults = injectDefaults();
  1013. const providedDefaults = ref(defaults);
  1014. const newDefaults = computed(() => {
  1015. const disabled = unref(options?.disabled);
  1016. if (disabled) return injectedDefaults.value;
  1017. const scoped = unref(options?.scoped);
  1018. const reset = unref(options?.reset);
  1019. const root = unref(options?.root);
  1020. let properties = mergeDeep(providedDefaults.value, {
  1021. prev: injectedDefaults.value
  1022. });
  1023. if (scoped) return properties;
  1024. if (reset || root) {
  1025. const len = Number(reset || Infinity);
  1026. for (let i = 0; i <= len; i++) {
  1027. if (!properties || !('prev' in properties)) {
  1028. break;
  1029. }
  1030. properties = properties.prev;
  1031. }
  1032. if (properties && typeof root === 'string' && root in properties) {
  1033. properties = mergeDeep(mergeDeep(properties, {
  1034. prev: properties
  1035. }), properties[root]);
  1036. }
  1037. return properties;
  1038. }
  1039. return properties.prev ? mergeDeep(properties.prev, properties) : properties;
  1040. });
  1041. provide(DefaultsSymbol, newDefaults);
  1042. return newDefaults;
  1043. }
  1044. function propIsDefined(vnode, prop) {
  1045. return typeof vnode.props?.[prop] !== 'undefined' || typeof vnode.props?.[toKebabCase(prop)] !== 'undefined';
  1046. }
  1047. function internalUseDefaults() {
  1048. let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  1049. let name = arguments.length > 1 ? arguments[1] : undefined;
  1050. let defaults = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : injectDefaults();
  1051. const vm = getCurrentInstance('useDefaults');
  1052. name = name ?? vm.type.name ?? vm.type.__name;
  1053. if (!name) {
  1054. throw new Error('[Vuetify] Could not determine component name');
  1055. }
  1056. const componentDefaults = computed(() => defaults.value?.[props._as ?? name]);
  1057. const _props = new Proxy(props, {
  1058. get(target, prop) {
  1059. const propValue = Reflect.get(target, prop);
  1060. if (prop === 'class' || prop === 'style') {
  1061. return [componentDefaults.value?.[prop], propValue].filter(v => v != null);
  1062. } else if (typeof prop === 'string' && !propIsDefined(vm.vnode, prop)) {
  1063. return componentDefaults.value?.[prop] ?? defaults.value?.global?.[prop] ?? propValue;
  1064. }
  1065. return propValue;
  1066. }
  1067. });
  1068. const _subcomponentDefaults = shallowRef();
  1069. watchEffect(() => {
  1070. if (componentDefaults.value) {
  1071. const subComponents = Object.entries(componentDefaults.value).filter(_ref => {
  1072. let [key] = _ref;
  1073. return key.startsWith(key[0].toUpperCase());
  1074. });
  1075. if (subComponents.length) _subcomponentDefaults.value = Object.fromEntries(subComponents);
  1076. }
  1077. });
  1078. function provideSubDefaults() {
  1079. // If subcomponent defaults are provided, override any
  1080. // subcomponents provided by the component's setup function.
  1081. // This uses injectSelf so must be done after the original setup to work.
  1082. useToggleScope(_subcomponentDefaults, () => {
  1083. provideDefaults(mergeDeep(injectSelf(DefaultsSymbol)?.value ?? {}, _subcomponentDefaults.value));
  1084. });
  1085. }
  1086. return {
  1087. props: _props,
  1088. provideSubDefaults
  1089. };
  1090. }
  1091. function useDefaults() {
  1092. let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  1093. let name = arguments.length > 1 ? arguments[1] : undefined;
  1094. const {
  1095. props: _props,
  1096. provideSubDefaults
  1097. } = internalUseDefaults(props, name);
  1098. provideSubDefaults();
  1099. return _props;
  1100. }
  1101. // Composables
  1102. // Types
  1103. // Implementation
  1104. function defineComponent(options) {
  1105. options._setup = options._setup ?? options.setup;
  1106. if (!options.name) {
  1107. consoleWarn('The component is missing an explicit name, unable to generate default prop value');
  1108. return options;
  1109. }
  1110. if (options._setup) {
  1111. options.props = propsFactory(options.props ?? {}, options.name)();
  1112. const propKeys = Object.keys(options.props);
  1113. options.filterProps = function filterProps(props) {
  1114. return pick(props, propKeys, ['class', 'style']);
  1115. };
  1116. options.props._as = String;
  1117. options.setup = function setup(props, ctx) {
  1118. const defaults = injectDefaults();
  1119. // Skip props proxy if defaults are not provided
  1120. if (!defaults.value) return options._setup(props, ctx);
  1121. const {
  1122. props: _props,
  1123. provideSubDefaults
  1124. } = internalUseDefaults(props, props._as ?? options.name, defaults);
  1125. const setupBindings = options._setup(_props, ctx);
  1126. provideSubDefaults();
  1127. return setupBindings;
  1128. };
  1129. }
  1130. return options;
  1131. }
  1132. // Implementation
  1133. function genericComponent() {
  1134. let exposeDefaults = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
  1135. return options => (exposeDefaults ? defineComponent : defineComponent$1)(options);
  1136. }
  1137. function defineFunctionalComponent(props, render) {
  1138. render.props = props;
  1139. return render;
  1140. }
  1141. // Composables
  1142. function createSimpleFunctional(klass) {
  1143. let tag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'div';
  1144. let name = arguments.length > 2 ? arguments[2] : undefined;
  1145. return genericComponent()({
  1146. name: name ?? capitalize(camelize(klass.replace(/__/g, '-'))),
  1147. props: {
  1148. tag: {
  1149. type: String,
  1150. default: tag
  1151. },
  1152. ...makeComponentProps()
  1153. },
  1154. setup(props, _ref) {
  1155. let {
  1156. slots
  1157. } = _ref;
  1158. return () => {
  1159. return h(props.tag, {
  1160. class: [klass, props.class],
  1161. style: props.style
  1162. }, slots.default?.());
  1163. };
  1164. }
  1165. });
  1166. }
  1167. /**
  1168. * Returns:
  1169. * - 'null' if the node is not attached to the DOM
  1170. * - the root node (HTMLDocument | ShadowRoot) otherwise
  1171. */
  1172. function attachedRoot(node) {
  1173. /* istanbul ignore next */
  1174. if (typeof node.getRootNode !== 'function') {
  1175. // Shadow DOM not supported (IE11), lets find the root of this node
  1176. while (node.parentNode) node = node.parentNode;
  1177. // The root parent is the document if the node is attached to the DOM
  1178. if (node !== document) return null;
  1179. return document;
  1180. }
  1181. const root = node.getRootNode();
  1182. // The composed root node is the document if the node is attached to the DOM
  1183. if (root !== document && root.getRootNode({
  1184. composed: true
  1185. }) !== document) return null;
  1186. return root;
  1187. }
  1188. const standardEasing = 'cubic-bezier(0.4, 0, 0.2, 1)';
  1189. const deceleratedEasing = 'cubic-bezier(0.0, 0, 0.2, 1)'; // Entering
  1190. const acceleratedEasing = 'cubic-bezier(0.4, 0, 1, 1)'; // Leaving
  1191. // Utilities
  1192. // Types
  1193. function getCurrentInstance(name, message) {
  1194. const vm = getCurrentInstance$1();
  1195. if (!vm) {
  1196. throw new Error(`[Vuetify] ${name} ${message || 'must be called from inside a setup function'}`);
  1197. }
  1198. return vm;
  1199. }
  1200. function getCurrentInstanceName() {
  1201. let name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'composables';
  1202. const vm = getCurrentInstance(name).type;
  1203. return toKebabCase(vm?.aliasName || vm?.name);
  1204. }
  1205. let _uid = 0;
  1206. let _map = new WeakMap();
  1207. function getUid() {
  1208. const vm = getCurrentInstance('getUid');
  1209. if (_map.has(vm)) return _map.get(vm);else {
  1210. const uid = _uid++;
  1211. _map.set(vm, uid);
  1212. return uid;
  1213. }
  1214. }
  1215. getUid.reset = () => {
  1216. _uid = 0;
  1217. _map = new WeakMap();
  1218. };
  1219. function getScrollParent(el) {
  1220. let includeHidden = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  1221. while (el) {
  1222. if (includeHidden ? isPotentiallyScrollable(el) : hasScrollbar(el)) return el;
  1223. el = el.parentElement;
  1224. }
  1225. return document.scrollingElement;
  1226. }
  1227. function getScrollParents(el, stopAt) {
  1228. const elements = [];
  1229. if (stopAt && el && !stopAt.contains(el)) return elements;
  1230. while (el) {
  1231. if (hasScrollbar(el)) elements.push(el);
  1232. if (el === stopAt) break;
  1233. el = el.parentElement;
  1234. }
  1235. return elements;
  1236. }
  1237. function hasScrollbar(el) {
  1238. if (!el || el.nodeType !== Node.ELEMENT_NODE) return false;
  1239. const style = window.getComputedStyle(el);
  1240. return style.overflowY === 'scroll' || style.overflowY === 'auto' && el.scrollHeight > el.clientHeight;
  1241. }
  1242. function isPotentiallyScrollable(el) {
  1243. if (!el || el.nodeType !== Node.ELEMENT_NODE) return false;
  1244. const style = window.getComputedStyle(el);
  1245. return ['scroll', 'auto'].includes(style.overflowY);
  1246. }
  1247. // Utilities
  1248. // Types
  1249. function injectSelf(key) {
  1250. const {
  1251. provides
  1252. } = getCurrentInstance('injectSelf');
  1253. if (provides && key in provides) {
  1254. // TS doesn't allow symbol as index type
  1255. return provides[key];
  1256. }
  1257. return undefined;
  1258. }
  1259. function isFixedPosition(el) {
  1260. while (el) {
  1261. if (window.getComputedStyle(el).position === 'fixed') {
  1262. return true;
  1263. }
  1264. el = el.offsetParent;
  1265. }
  1266. return false;
  1267. }
  1268. // Utilities
  1269. // Types
  1270. function useRender(render) {
  1271. const vm = getCurrentInstance('useRender');
  1272. vm.render = render;
  1273. }
  1274. // Utilities
  1275. // Types
  1276. function useResizeObserver(callback) {
  1277. let box = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'content';
  1278. const resizeRef = ref();
  1279. const contentRect = ref();
  1280. if (IN_BROWSER) {
  1281. const observer = new ResizeObserver(entries => {
  1282. callback?.(entries, observer);
  1283. if (!entries.length) return;
  1284. if (box === 'content') {
  1285. contentRect.value = entries[0].contentRect;
  1286. } else {
  1287. contentRect.value = entries[0].target.getBoundingClientRect();
  1288. }
  1289. });
  1290. onBeforeUnmount(() => {
  1291. observer.disconnect();
  1292. });
  1293. watch(resizeRef, (newValue, oldValue) => {
  1294. if (oldValue) {
  1295. observer.unobserve(refElement(oldValue));
  1296. contentRect.value = undefined;
  1297. }
  1298. if (newValue) observer.observe(refElement(newValue));
  1299. }, {
  1300. flush: 'post'
  1301. });
  1302. }
  1303. return {
  1304. resizeRef,
  1305. contentRect: readonly(contentRect)
  1306. };
  1307. }
  1308. // Composables
  1309. // Types
  1310. const VuetifyLayoutKey = Symbol.for('vuetify:layout');
  1311. const VuetifyLayoutItemKey = Symbol.for('vuetify:layout-item');
  1312. const ROOT_ZINDEX = 1000;
  1313. const makeLayoutProps = propsFactory({
  1314. overlaps: {
  1315. type: Array,
  1316. default: () => []
  1317. },
  1318. fullHeight: Boolean
  1319. }, 'layout');
  1320. // Composables
  1321. const makeLayoutItemProps = propsFactory({
  1322. name: {
  1323. type: String
  1324. },
  1325. order: {
  1326. type: [Number, String],
  1327. default: 0
  1328. },
  1329. absolute: Boolean
  1330. }, 'layout-item');
  1331. function useLayout() {
  1332. const layout = inject$1(VuetifyLayoutKey);
  1333. if (!layout) throw new Error('[Vuetify] Could not find injected layout');
  1334. return {
  1335. getLayoutItem: layout.getLayoutItem,
  1336. mainRect: layout.mainRect,
  1337. mainStyles: layout.mainStyles
  1338. };
  1339. }
  1340. function useLayoutItem(options) {
  1341. const layout = inject$1(VuetifyLayoutKey);
  1342. if (!layout) throw new Error('[Vuetify] Could not find injected layout');
  1343. const id = options.id ?? `layout-item-${getUid()}`;
  1344. const vm = getCurrentInstance('useLayoutItem');
  1345. provide(VuetifyLayoutItemKey, {
  1346. id
  1347. });
  1348. const isKeptAlive = shallowRef(false);
  1349. onDeactivated(() => isKeptAlive.value = true);
  1350. onActivated(() => isKeptAlive.value = false);
  1351. const {
  1352. layoutItemStyles,
  1353. layoutItemScrimStyles
  1354. } = layout.register(vm, {
  1355. ...options,
  1356. active: computed(() => isKeptAlive.value ? false : options.active.value),
  1357. id
  1358. });
  1359. onBeforeUnmount(() => layout.unregister(id));
  1360. return {
  1361. layoutItemStyles,
  1362. layoutRect: layout.layoutRect,
  1363. layoutItemScrimStyles
  1364. };
  1365. }
  1366. const generateLayers = (layout, positions, layoutSizes, activeItems) => {
  1367. let previousLayer = {
  1368. top: 0,
  1369. left: 0,
  1370. right: 0,
  1371. bottom: 0
  1372. };
  1373. const layers = [{
  1374. id: '',
  1375. layer: {
  1376. ...previousLayer
  1377. }
  1378. }];
  1379. for (const id of layout) {
  1380. const position = positions.get(id);
  1381. const amount = layoutSizes.get(id);
  1382. const active = activeItems.get(id);
  1383. if (!position || !amount || !active) continue;
  1384. const layer = {
  1385. ...previousLayer,
  1386. [position.value]: parseInt(previousLayer[position.value], 10) + (active.value ? parseInt(amount.value, 10) : 0)
  1387. };
  1388. layers.push({
  1389. id,
  1390. layer
  1391. });
  1392. previousLayer = layer;
  1393. }
  1394. return layers;
  1395. };
  1396. function createLayout(props) {
  1397. const parentLayout = inject$1(VuetifyLayoutKey, null);
  1398. const rootZIndex = computed(() => parentLayout ? parentLayout.rootZIndex.value - 100 : ROOT_ZINDEX);
  1399. const registered = ref([]);
  1400. const positions = reactive(new Map());
  1401. const layoutSizes = reactive(new Map());
  1402. const priorities = reactive(new Map());
  1403. const activeItems = reactive(new Map());
  1404. const disabledTransitions = reactive(new Map());
  1405. const {
  1406. resizeRef,
  1407. contentRect: layoutRect
  1408. } = useResizeObserver();
  1409. const computedOverlaps = computed(() => {
  1410. const map = new Map();
  1411. const overlaps = props.overlaps ?? [];
  1412. for (const overlap of overlaps.filter(item => item.includes(':'))) {
  1413. const [top, bottom] = overlap.split(':');
  1414. if (!registered.value.includes(top) || !registered.value.includes(bottom)) continue;
  1415. const topPosition = positions.get(top);
  1416. const bottomPosition = positions.get(bottom);
  1417. const topAmount = layoutSizes.get(top);
  1418. const bottomAmount = layoutSizes.get(bottom);
  1419. if (!topPosition || !bottomPosition || !topAmount || !bottomAmount) continue;
  1420. map.set(bottom, {
  1421. position: topPosition.value,
  1422. amount: parseInt(topAmount.value, 10)
  1423. });
  1424. map.set(top, {
  1425. position: bottomPosition.value,
  1426. amount: -parseInt(bottomAmount.value, 10)
  1427. });
  1428. }
  1429. return map;
  1430. });
  1431. const layers = computed(() => {
  1432. const uniquePriorities = [...new Set([...priorities.values()].map(p => p.value))].sort((a, b) => a - b);
  1433. const layout = [];
  1434. for (const p of uniquePriorities) {
  1435. const items = registered.value.filter(id => priorities.get(id)?.value === p);
  1436. layout.push(...items);
  1437. }
  1438. return generateLayers(layout, positions, layoutSizes, activeItems);
  1439. });
  1440. const transitionsEnabled = computed(() => {
  1441. return !Array.from(disabledTransitions.values()).some(ref => ref.value);
  1442. });
  1443. const mainRect = computed(() => {
  1444. return layers.value[layers.value.length - 1].layer;
  1445. });
  1446. const mainStyles = computed(() => {
  1447. return {
  1448. '--v-layout-left': convertToUnit(mainRect.value.left),
  1449. '--v-layout-right': convertToUnit(mainRect.value.right),
  1450. '--v-layout-top': convertToUnit(mainRect.value.top),
  1451. '--v-layout-bottom': convertToUnit(mainRect.value.bottom),
  1452. ...(transitionsEnabled.value ? undefined : {
  1453. transition: 'none'
  1454. })
  1455. };
  1456. });
  1457. const items = computed(() => {
  1458. return layers.value.slice(1).map((_ref, index) => {
  1459. let {
  1460. id
  1461. } = _ref;
  1462. const {
  1463. layer
  1464. } = layers.value[index];
  1465. const size = layoutSizes.get(id);
  1466. const position = positions.get(id);
  1467. return {
  1468. id,
  1469. ...layer,
  1470. size: Number(size.value),
  1471. position: position.value
  1472. };
  1473. });
  1474. });
  1475. const getLayoutItem = id => {
  1476. return items.value.find(item => item.id === id);
  1477. };
  1478. const rootVm = getCurrentInstance('createLayout');
  1479. const isMounted = shallowRef(false);
  1480. onMounted(() => {
  1481. isMounted.value = true;
  1482. });
  1483. provide(VuetifyLayoutKey, {
  1484. register: (vm, _ref2) => {
  1485. let {
  1486. id,
  1487. order,
  1488. position,
  1489. layoutSize,
  1490. elementSize,
  1491. active,
  1492. disableTransitions,
  1493. absolute
  1494. } = _ref2;
  1495. priorities.set(id, order);
  1496. positions.set(id, position);
  1497. layoutSizes.set(id, layoutSize);
  1498. activeItems.set(id, active);
  1499. disableTransitions && disabledTransitions.set(id, disableTransitions);
  1500. const instances = findChildrenWithProvide(VuetifyLayoutItemKey, rootVm?.vnode);
  1501. const instanceIndex = instances.indexOf(vm);
  1502. if (instanceIndex > -1) registered.value.splice(instanceIndex, 0, id);else registered.value.push(id);
  1503. const index = computed(() => items.value.findIndex(i => i.id === id));
  1504. const zIndex = computed(() => rootZIndex.value + layers.value.length * 2 - index.value * 2);
  1505. const layoutItemStyles = computed(() => {
  1506. const isHorizontal = position.value === 'left' || position.value === 'right';
  1507. const isOppositeHorizontal = position.value === 'right';
  1508. const isOppositeVertical = position.value === 'bottom';
  1509. const styles = {
  1510. [position.value]: 0,
  1511. zIndex: zIndex.value,
  1512. transform: `translate${isHorizontal ? 'X' : 'Y'}(${(active.value ? 0 : -110) * (isOppositeHorizontal || isOppositeVertical ? -1 : 1)}%)`,
  1513. position: absolute.value || rootZIndex.value !== ROOT_ZINDEX ? 'absolute' : 'fixed',
  1514. ...(transitionsEnabled.value ? undefined : {
  1515. transition: 'none'
  1516. })
  1517. };
  1518. if (!isMounted.value) return styles;
  1519. const item = items.value[index.value];
  1520. if (!item) throw new Error(`[Vuetify] Could not find layout item "${id}"`);
  1521. const overlap = computedOverlaps.value.get(id);
  1522. if (overlap) {
  1523. item[overlap.position] += overlap.amount;
  1524. }
  1525. return {
  1526. ...styles,
  1527. height: isHorizontal ? `calc(100% - ${item.top}px - ${item.bottom}px)` : elementSize.value ? `${elementSize.value}px` : undefined,
  1528. left: isOppositeHorizontal ? undefined : `${item.left}px`,
  1529. right: isOppositeHorizontal ? `${item.right}px` : undefined,
  1530. top: position.value !== 'bottom' ? `${item.top}px` : undefined,
  1531. bottom: position.value !== 'top' ? `${item.bottom}px` : undefined,
  1532. width: !isHorizontal ? `calc(100% - ${item.left}px - ${item.right}px)` : elementSize.value ? `${elementSize.value}px` : undefined
  1533. };
  1534. });
  1535. const layoutItemScrimStyles = computed(() => ({
  1536. zIndex: zIndex.value - 1
  1537. }));
  1538. return {
  1539. layoutItemStyles,
  1540. layoutItemScrimStyles,
  1541. zIndex
  1542. };
  1543. },
  1544. unregister: id => {
  1545. priorities.delete(id);
  1546. positions.delete(id);
  1547. layoutSizes.delete(id);
  1548. activeItems.delete(id);
  1549. disabledTransitions.delete(id);
  1550. registered.value = registered.value.filter(v => v !== id);
  1551. },
  1552. mainRect,
  1553. mainStyles,
  1554. getLayoutItem,
  1555. items,
  1556. layoutRect,
  1557. rootZIndex
  1558. });
  1559. const layoutClasses = computed(() => ['v-layout', {
  1560. 'v-layout--full-height': props.fullHeight
  1561. }]);
  1562. const layoutStyles = computed(() => ({
  1563. zIndex: rootZIndex.value,
  1564. position: parentLayout ? 'relative' : undefined,
  1565. overflow: parentLayout ? 'hidden' : undefined
  1566. }));
  1567. return {
  1568. layoutClasses,
  1569. layoutStyles,
  1570. getLayoutItem,
  1571. items,
  1572. layoutRect,
  1573. layoutRef: resizeRef
  1574. };
  1575. }
  1576. var en = {
  1577. badge: 'Badge',
  1578. close: 'Close',
  1579. dataIterator: {
  1580. noResultsText: 'No matching records found',
  1581. loadingText: 'Loading items...'
  1582. },
  1583. dataTable: {
  1584. itemsPerPageText: 'Rows per page:',
  1585. ariaLabel: {
  1586. sortDescending: 'Sorted descending.',
  1587. sortAscending: 'Sorted ascending.',
  1588. sortNone: 'Not sorted.',
  1589. activateNone: 'Activate to remove sorting.',
  1590. activateDescending: 'Activate to sort descending.',
  1591. activateAscending: 'Activate to sort ascending.'
  1592. },
  1593. sortBy: 'Sort by'
  1594. },
  1595. dataFooter: {
  1596. itemsPerPageText: 'Items per page:',
  1597. itemsPerPageAll: 'All',
  1598. nextPage: 'Next page',
  1599. prevPage: 'Previous page',
  1600. firstPage: 'First page',
  1601. lastPage: 'Last page',
  1602. pageText: '{0}-{1} of {2}'
  1603. },
  1604. dateRangeInput: {
  1605. divider: 'to'
  1606. },
  1607. datePicker: {
  1608. ok: 'OK',
  1609. cancel: 'Cancel',
  1610. range: {
  1611. title: 'Select dates',
  1612. header: 'Enter dates'
  1613. },
  1614. title: 'Select date',
  1615. header: 'Enter date',
  1616. input: {
  1617. placeholder: 'Enter date'
  1618. }
  1619. },
  1620. noDataText: 'No data available',
  1621. carousel: {
  1622. prev: 'Previous visual',
  1623. next: 'Next visual',
  1624. ariaLabel: {
  1625. delimiter: 'Carousel slide {0} of {1}'
  1626. }
  1627. },
  1628. calendar: {
  1629. moreEvents: '{0} more'
  1630. },
  1631. input: {
  1632. clear: 'Clear {0}',
  1633. prependAction: '{0} prepended action',
  1634. appendAction: '{0} appended action',
  1635. otp: 'Please enter OTP character {0}'
  1636. },
  1637. fileInput: {
  1638. counter: '{0} files',
  1639. counterSize: '{0} files ({1} in total)'
  1640. },
  1641. timePicker: {
  1642. am: 'AM',
  1643. pm: 'PM'
  1644. },
  1645. pagination: {
  1646. ariaLabel: {
  1647. root: 'Pagination Navigation',
  1648. next: 'Next page',
  1649. previous: 'Previous page',
  1650. page: 'Go to page {0}',
  1651. currentPage: 'Page {0}, Current page',
  1652. first: 'First page',
  1653. last: 'Last page'
  1654. }
  1655. },
  1656. stepper: {
  1657. next: 'Next',
  1658. prev: 'Previous'
  1659. },
  1660. rating: {
  1661. ariaLabel: {
  1662. item: 'Rating {0} of {1}'
  1663. }
  1664. },
  1665. loading: 'Loading...',
  1666. infiniteScroll: {
  1667. loadMore: 'Load more',
  1668. empty: 'No more'
  1669. }
  1670. };
  1671. const defaultRtl = {
  1672. af: false,
  1673. ar: true,
  1674. bg: false,
  1675. ca: false,
  1676. ckb: false,
  1677. cs: false,
  1678. de: false,
  1679. el: false,
  1680. en: false,
  1681. es: false,
  1682. et: false,
  1683. fa: true,
  1684. fi: false,
  1685. fr: false,
  1686. hr: false,
  1687. hu: false,
  1688. he: true,
  1689. id: false,
  1690. it: false,
  1691. ja: false,
  1692. ko: false,
  1693. lv: false,
  1694. lt: false,
  1695. nl: false,
  1696. no: false,
  1697. pl: false,
  1698. pt: false,
  1699. ro: false,
  1700. ru: false,
  1701. sk: false,
  1702. sl: false,
  1703. srCyrl: false,
  1704. srLatn: false,
  1705. sv: false,
  1706. th: false,
  1707. tr: false,
  1708. az: false,
  1709. uk: false,
  1710. vi: false,
  1711. zhHans: false,
  1712. zhHant: false
  1713. };
  1714. // Composables
  1715. // Types
  1716. // Composables
  1717. function useProxiedModel(props, prop, defaultValue) {
  1718. let transformIn = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : v => v;
  1719. let transformOut = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : v => v;
  1720. const vm = getCurrentInstance('useProxiedModel');
  1721. const internal = ref(props[prop] !== undefined ? props[prop] : defaultValue);
  1722. const kebabProp = toKebabCase(prop);
  1723. const checkKebab = kebabProp !== prop;
  1724. const isControlled = checkKebab ? computed(() => {
  1725. void props[prop];
  1726. return !!((vm.vnode.props?.hasOwnProperty(prop) || vm.vnode.props?.hasOwnProperty(kebabProp)) && (vm.vnode.props?.hasOwnProperty(`onUpdate:${prop}`) || vm.vnode.props?.hasOwnProperty(`onUpdate:${kebabProp}`)));
  1727. }) : computed(() => {
  1728. void props[prop];
  1729. return !!(vm.vnode.props?.hasOwnProperty(prop) && vm.vnode.props?.hasOwnProperty(`onUpdate:${prop}`));
  1730. });
  1731. useToggleScope(() => !isControlled.value, () => {
  1732. watch(() => props[prop], val => {
  1733. internal.value = val;
  1734. });
  1735. });
  1736. const model = computed({
  1737. get() {
  1738. const externalValue = props[prop];
  1739. return transformIn(isControlled.value ? externalValue : internal.value);
  1740. },
  1741. set(internalValue) {
  1742. const newValue = transformOut(internalValue);
  1743. const value = toRaw(isControlled.value ? props[prop] : internal.value);
  1744. if (value === newValue || transformIn(value) === internalValue) {
  1745. return;
  1746. }
  1747. internal.value = newValue;
  1748. vm?.emit(`update:${prop}`, newValue);
  1749. }
  1750. });
  1751. Object.defineProperty(model, 'externalValue', {
  1752. get: () => isControlled.value ? props[prop] : internal.value
  1753. });
  1754. return model;
  1755. }
  1756. // Composables
  1757. // Types
  1758. const LANG_PREFIX = '$vuetify.';
  1759. const replace = (str, params) => {
  1760. return str.replace(/\{(\d+)\}/g, (match, index) => {
  1761. return String(params[+index]);
  1762. });
  1763. };
  1764. const createTranslateFunction = (current, fallback, messages) => {
  1765. return function (key) {
  1766. for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  1767. params[_key - 1] = arguments[_key];
  1768. }
  1769. if (!key.startsWith(LANG_PREFIX)) {
  1770. return replace(key, params);
  1771. }
  1772. const shortKey = key.replace(LANG_PREFIX, '');
  1773. const currentLocale = current.value && messages.value[current.value];
  1774. const fallbackLocale = fallback.value && messages.value[fallback.value];
  1775. let str = getObjectValueByPath(currentLocale, shortKey, null);
  1776. if (!str) {
  1777. consoleWarn(`Translation key "${key}" not found in "${current.value}", trying fallback locale`);
  1778. str = getObjectValueByPath(fallbackLocale, shortKey, null);
  1779. }
  1780. if (!str) {
  1781. consoleError(`Translation key "${key}" not found in fallback`);
  1782. str = key;
  1783. }
  1784. if (typeof str !== 'string') {
  1785. consoleError(`Translation key "${key}" has a non-string value`);
  1786. str = key;
  1787. }
  1788. return replace(str, params);
  1789. };
  1790. };
  1791. function createNumberFunction(current, fallback) {
  1792. return (value, options) => {
  1793. const numberFormat = new Intl.NumberFormat([current.value, fallback.value], options);
  1794. return numberFormat.format(value);
  1795. };
  1796. }
  1797. function useProvided(props, prop, provided) {
  1798. const internal = useProxiedModel(props, prop, props[prop] ?? provided.value);
  1799. // TODO: Remove when defaultValue works
  1800. internal.value = props[prop] ?? provided.value;
  1801. watch(provided, v => {
  1802. if (props[prop] == null) {
  1803. internal.value = provided.value;
  1804. }
  1805. });
  1806. return internal;
  1807. }
  1808. function createProvideFunction(state) {
  1809. return props => {
  1810. const current = useProvided(props, 'locale', state.current);
  1811. const fallback = useProvided(props, 'fallback', state.fallback);
  1812. const messages = useProvided(props, 'messages', state.messages);
  1813. return {
  1814. name: 'vuetify',
  1815. current,
  1816. fallback,
  1817. messages,
  1818. t: createTranslateFunction(current, fallback, messages),
  1819. n: createNumberFunction(current, fallback),
  1820. provide: createProvideFunction({
  1821. current,
  1822. fallback,
  1823. messages
  1824. })
  1825. };
  1826. };
  1827. }
  1828. function createVuetifyAdapter(options) {
  1829. const current = shallowRef(options?.locale ?? 'en');
  1830. const fallback = shallowRef(options?.fallback ?? 'en');
  1831. const messages = ref({
  1832. en,
  1833. ...options?.messages
  1834. });
  1835. return {
  1836. name: 'vuetify',
  1837. current,
  1838. fallback,
  1839. messages,
  1840. t: createTranslateFunction(current, fallback, messages),
  1841. n: createNumberFunction(current, fallback),
  1842. provide: createProvideFunction({
  1843. current,
  1844. fallback,
  1845. messages
  1846. })
  1847. };
  1848. }
  1849. // Utilities
  1850. // Types
  1851. const LocaleSymbol = Symbol.for('vuetify:locale');
  1852. function isLocaleInstance(obj) {
  1853. return obj.name != null;
  1854. }
  1855. function createLocale(options) {
  1856. const i18n = options?.adapter && isLocaleInstance(options?.adapter) ? options?.adapter : createVuetifyAdapter(options);
  1857. const rtl = createRtl(i18n, options);
  1858. return {
  1859. ...i18n,
  1860. ...rtl
  1861. };
  1862. }
  1863. function useLocale() {
  1864. const locale = inject$1(LocaleSymbol);
  1865. if (!locale) throw new Error('[Vuetify] Could not find injected locale instance');
  1866. return locale;
  1867. }
  1868. function provideLocale(props) {
  1869. const locale = inject$1(LocaleSymbol);
  1870. if (!locale) throw new Error('[Vuetify] Could not find injected locale instance');
  1871. const i18n = locale.provide(props);
  1872. const rtl = provideRtl(i18n, locale.rtl, props);
  1873. const data = {
  1874. ...i18n,
  1875. ...rtl
  1876. };
  1877. provide(LocaleSymbol, data);
  1878. return data;
  1879. }
  1880. function createRtl(i18n, options) {
  1881. const rtl = ref(options?.rtl ?? defaultRtl);
  1882. const isRtl = computed(() => rtl.value[i18n.current.value] ?? false);
  1883. return {
  1884. isRtl,
  1885. rtl,
  1886. rtlClasses: computed(() => `v-locale--is-${isRtl.value ? 'rtl' : 'ltr'}`)
  1887. };
  1888. }
  1889. function provideRtl(locale, rtl, props) {
  1890. const isRtl = computed(() => props.rtl ?? rtl.value[locale.current.value] ?? false);
  1891. return {
  1892. isRtl,
  1893. rtl,
  1894. rtlClasses: computed(() => `v-locale--is-${isRtl.value ? 'rtl' : 'ltr'}`)
  1895. };
  1896. }
  1897. function useRtl() {
  1898. const locale = inject$1(LocaleSymbol);
  1899. if (!locale) throw new Error('[Vuetify] Could not find injected rtl instance');
  1900. return {
  1901. isRtl: locale.isRtl,
  1902. rtlClasses: locale.rtlClasses
  1903. };
  1904. }
  1905. /**
  1906. * WCAG 3.0 APCA perceptual contrast algorithm from https://github.com/Myndex/SAPC-APCA
  1907. * @licence https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
  1908. * @see https://www.w3.org/WAI/GL/task-forces/silver/wiki/Visual_Contrast_of_Text_Subgroup
  1909. */
  1910. // Types
  1911. // MAGICAL NUMBERS
  1912. // sRGB Conversion to Relative Luminance (Y)
  1913. // Transfer Curve (aka "Gamma") for sRGB linearization
  1914. // Simple power curve vs piecewise described in docs
  1915. // Essentially, 2.4 best models actual display
  1916. // characteristics in combination with the total method
  1917. const mainTRC = 2.4;
  1918. const Rco = 0.2126729; // sRGB Red Coefficient (from matrix)
  1919. const Gco = 0.7151522; // sRGB Green Coefficient (from matrix)
  1920. const Bco = 0.0721750; // sRGB Blue Coefficient (from matrix)
  1921. // For Finding Raw SAPC Contrast from Relative Luminance (Y)
  1922. // Constants for SAPC Power Curve Exponents
  1923. // One pair for normal text, and one for reverse
  1924. // These are the "beating heart" of SAPC
  1925. const normBG = 0.55;
  1926. const normTXT = 0.58;
  1927. const revTXT = 0.57;
  1928. const revBG = 0.62;
  1929. // For Clamping and Scaling Values
  1930. const blkThrs = 0.03; // Level that triggers the soft black clamp
  1931. const blkClmp = 1.45; // Exponent for the soft black clamp curve
  1932. const deltaYmin = 0.0005; // Lint trap
  1933. const scaleBoW = 1.25; // Scaling for dark text on light
  1934. const scaleWoB = 1.25; // Scaling for light text on dark
  1935. const loConThresh = 0.078; // Threshold for new simple offset scale
  1936. const loConFactor = 12.82051282051282; // = 1/0.078,
  1937. const loConOffset = 0.06; // The simple offset
  1938. const loClip = 0.001; // Output clip (lint trap #2)
  1939. function APCAcontrast(text, background) {
  1940. // Linearize sRGB
  1941. const Rtxt = (text.r / 255) ** mainTRC;
  1942. const Gtxt = (text.g / 255) ** mainTRC;
  1943. const Btxt = (text.b / 255) ** mainTRC;
  1944. const Rbg = (background.r / 255) ** mainTRC;
  1945. const Gbg = (background.g / 255) ** mainTRC;
  1946. const Bbg = (background.b / 255) ** mainTRC;
  1947. // Apply the standard coefficients and sum to Y
  1948. let Ytxt = Rtxt * Rco + Gtxt * Gco + Btxt * Bco;
  1949. let Ybg = Rbg * Rco + Gbg * Gco + Bbg * Bco;
  1950. // Soft clamp Y when near black.
  1951. // Now clamping all colors to prevent crossover errors
  1952. if (Ytxt <= blkThrs) Ytxt += (blkThrs - Ytxt) ** blkClmp;
  1953. if (Ybg <= blkThrs) Ybg += (blkThrs - Ybg) ** blkClmp;
  1954. // Return 0 Early for extremely low ∆Y (lint trap #1)
  1955. if (Math.abs(Ybg - Ytxt) < deltaYmin) return 0.0;
  1956. // SAPC CONTRAST
  1957. let outputContrast; // For weighted final values
  1958. if (Ybg > Ytxt) {
  1959. // For normal polarity, black text on white
  1960. // Calculate the SAPC contrast value and scale
  1961. const SAPC = (Ybg ** normBG - Ytxt ** normTXT) * scaleBoW;
  1962. // NEW! SAPC SmoothScale™
  1963. // Low Contrast Smooth Scale Rollout to prevent polarity reversal
  1964. // and also a low clip for very low contrasts (lint trap #2)
  1965. // much of this is for very low contrasts, less than 10
  1966. // therefore for most reversing needs, only loConOffset is important
  1967. outputContrast = SAPC < loClip ? 0.0 : SAPC < loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC - loConOffset;
  1968. } else {
  1969. // For reverse polarity, light text on dark
  1970. // WoB should always return negative value.
  1971. const SAPC = (Ybg ** revBG - Ytxt ** revTXT) * scaleWoB;
  1972. outputContrast = SAPC > -loClip ? 0.0 : SAPC > -loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC + loConOffset;
  1973. }
  1974. return outputContrast * 100;
  1975. }
  1976. // Utilities
  1977. // Types
  1978. const ThemeSymbol = Symbol.for('vuetify:theme');
  1979. const makeThemeProps = propsFactory({
  1980. theme: String
  1981. }, 'theme');
  1982. const defaultThemeOptions = {
  1983. defaultTheme: 'light',
  1984. variations: {
  1985. colors: [],
  1986. lighten: 0,
  1987. darken: 0
  1988. },
  1989. themes: {
  1990. light: {
  1991. dark: false,
  1992. colors: {
  1993. background: '#FFFFFF',
  1994. surface: '#FFFFFF',
  1995. 'surface-variant': '#424242',
  1996. 'on-surface-variant': '#EEEEEE',
  1997. primary: '#6200EE',
  1998. 'primary-darken-1': '#3700B3',
  1999. secondary: '#03DAC6',
  2000. 'secondary-darken-1': '#018786',
  2001. error: '#B00020',
  2002. info: '#2196F3',
  2003. success: '#4CAF50',
  2004. warning: '#FB8C00'
  2005. },
  2006. variables: {
  2007. 'border-color': '#000000',
  2008. 'border-opacity': 0.12,
  2009. 'high-emphasis-opacity': 0.87,
  2010. 'medium-emphasis-opacity': 0.60,
  2011. 'disabled-opacity': 0.38,
  2012. 'idle-opacity': 0.04,
  2013. 'hover-opacity': 0.04,
  2014. 'focus-opacity': 0.12,
  2015. 'selected-opacity': 0.08,
  2016. 'activated-opacity': 0.12,
  2017. 'pressed-opacity': 0.12,
  2018. 'dragged-opacity': 0.08,
  2019. 'theme-kbd': '#212529',
  2020. 'theme-on-kbd': '#FFFFFF',
  2021. 'theme-code': '#F5F5F5',
  2022. 'theme-on-code': '#000000'
  2023. }
  2024. },
  2025. dark: {
  2026. dark: true,
  2027. colors: {
  2028. background: '#121212',
  2029. surface: '#212121',
  2030. 'surface-variant': '#BDBDBD',
  2031. 'on-surface-variant': '#424242',
  2032. primary: '#BB86FC',
  2033. 'primary-darken-1': '#3700B3',
  2034. secondary: '#03DAC5',
  2035. 'secondary-darken-1': '#03DAC5',
  2036. error: '#CF6679',
  2037. info: '#2196F3',
  2038. success: '#4CAF50',
  2039. warning: '#FB8C00'
  2040. },
  2041. variables: {
  2042. 'border-color': '#FFFFFF',
  2043. 'border-opacity': 0.12,
  2044. 'high-emphasis-opacity': 1,
  2045. 'medium-emphasis-opacity': 0.70,
  2046. 'disabled-opacity': 0.50,
  2047. 'idle-opacity': 0.10,
  2048. 'hover-opacity': 0.04,
  2049. 'focus-opacity': 0.12,
  2050. 'selected-opacity': 0.08,
  2051. 'activated-opacity': 0.12,
  2052. 'pressed-opacity': 0.16,
  2053. 'dragged-opacity': 0.08,
  2054. 'theme-kbd': '#212529',
  2055. 'theme-on-kbd': '#FFFFFF',
  2056. 'theme-code': '#343434',
  2057. 'theme-on-code': '#CCCCCC'
  2058. }
  2059. }
  2060. }
  2061. };
  2062. function parseThemeOptions() {
  2063. let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultThemeOptions;
  2064. if (!options) return {
  2065. ...defaultThemeOptions,
  2066. isDisabled: true
  2067. };
  2068. const themes = {};
  2069. for (const [key, theme] of Object.entries(options.themes ?? {})) {
  2070. const defaultTheme = theme.dark || key === 'dark' ? defaultThemeOptions.themes?.dark : defaultThemeOptions.themes?.light;
  2071. themes[key] = mergeDeep(defaultTheme, theme);
  2072. }
  2073. return mergeDeep(defaultThemeOptions, {
  2074. ...options,
  2075. themes
  2076. });
  2077. }
  2078. // Composables
  2079. function createTheme(options) {
  2080. const parsedOptions = parseThemeOptions(options);
  2081. const name = ref(parsedOptions.defaultTheme);
  2082. const themes = ref(parsedOptions.themes);
  2083. const computedThemes = computed(() => {
  2084. const acc = {};
  2085. for (const [name, original] of Object.entries(themes.value)) {
  2086. const theme = acc[name] = {
  2087. ...original,
  2088. colors: {
  2089. ...original.colors
  2090. }
  2091. };
  2092. if (parsedOptions.variations) {
  2093. for (const name of parsedOptions.variations.colors) {
  2094. const color = theme.colors[name];
  2095. if (!color) continue;
  2096. for (const variation of ['lighten', 'darken']) {
  2097. const fn = variation === 'lighten' ? lighten : darken;
  2098. for (const amount of createRange(parsedOptions.variations[variation], 1)) {
  2099. theme.colors[`${name}-${variation}-${amount}`] = RGBtoHex(fn(parseColor(color), amount));
  2100. }
  2101. }
  2102. }
  2103. }
  2104. for (const color of Object.keys(theme.colors)) {
  2105. if (/^on-[a-z]/.test(color) || theme.colors[`on-${color}`]) continue;
  2106. const onColor = `on-${color}`;
  2107. const colorVal = parseColor(theme.colors[color]);
  2108. const blackContrast = Math.abs(APCAcontrast(parseColor(0), colorVal));
  2109. const whiteContrast = Math.abs(APCAcontrast(parseColor(0xffffff), colorVal));
  2110. // TODO: warn about poor color selections
  2111. // const contrastAsText = Math.abs(APCAcontrast(colorVal, colorToInt(theme.colors.background)))
  2112. // const minContrast = Math.max(blackContrast, whiteContrast)
  2113. // if (minContrast < 60) {
  2114. // consoleInfo(`${key} theme color ${color} has poor contrast (${minContrast.toFixed()}%)`)
  2115. // } else if (contrastAsText < 60 && !['background', 'surface'].includes(color)) {
  2116. // consoleInfo(`${key} theme color ${color} has poor contrast as text (${contrastAsText.toFixed()}%)`)
  2117. // }
  2118. // Prefer white text if both have an acceptable contrast ratio
  2119. theme.colors[onColor] = whiteContrast > Math.min(blackContrast, 50) ? '#fff' : '#000';
  2120. }
  2121. }
  2122. return acc;
  2123. });
  2124. const current = computed(() => computedThemes.value[name.value]);
  2125. const styles = computed(() => {
  2126. const lines = [];
  2127. if (current.value.dark) {
  2128. createCssClass(lines, ':root', ['color-scheme: dark']);
  2129. }
  2130. createCssClass(lines, ':root', genCssVariables(current.value));
  2131. for (const [themeName, theme] of Object.entries(computedThemes.value)) {
  2132. createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)]);
  2133. }
  2134. const bgLines = [];
  2135. const fgLines = [];
  2136. const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
  2137. for (const key of colors) {
  2138. if (/^on-[a-z]/.test(key)) {
  2139. createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`]);
  2140. } else {
  2141. 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`]);
  2142. createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`]);
  2143. createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`]);
  2144. }
  2145. }
  2146. lines.push(...bgLines, ...fgLines);
  2147. return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
  2148. });
  2149. function getHead() {
  2150. return {
  2151. style: [{
  2152. children: styles.value,
  2153. id: 'vuetify-theme-stylesheet',
  2154. nonce: parsedOptions.cspNonce || false
  2155. }]
  2156. };
  2157. }
  2158. function install(app) {
  2159. if (parsedOptions.isDisabled) return;
  2160. const head = app._context.provides.usehead;
  2161. if (head) {
  2162. if (head.push) {
  2163. const entry = head.push(getHead);
  2164. if (IN_BROWSER) {
  2165. watch(styles, () => {
  2166. entry.patch(getHead);
  2167. });
  2168. }
  2169. } else {
  2170. if (IN_BROWSER) {
  2171. head.addHeadObjs(computed(getHead));
  2172. watchEffect(() => head.updateDOM());
  2173. } else {
  2174. head.addHeadObjs(getHead());
  2175. }
  2176. }
  2177. } else {
  2178. let styleEl = IN_BROWSER ? document.getElementById('vuetify-theme-stylesheet') : null;
  2179. if (IN_BROWSER) {
  2180. watch(styles, updateStyles, {
  2181. immediate: true
  2182. });
  2183. } else {
  2184. updateStyles();
  2185. }
  2186. function updateStyles() {
  2187. if (typeof document !== 'undefined' && !styleEl) {
  2188. const el = document.createElement('style');
  2189. el.type = 'text/css';
  2190. el.id = 'vuetify-theme-stylesheet';
  2191. if (parsedOptions.cspNonce) el.setAttribute('nonce', parsedOptions.cspNonce);
  2192. styleEl = el;
  2193. document.head.appendChild(styleEl);
  2194. }
  2195. if (styleEl) styleEl.innerHTML = styles.value;
  2196. }
  2197. }
  2198. }
  2199. const themeClasses = computed(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
  2200. return {
  2201. install,
  2202. isDisabled: parsedOptions.isDisabled,
  2203. name,
  2204. themes,
  2205. current,
  2206. computedThemes,
  2207. themeClasses,
  2208. styles,
  2209. global: {
  2210. name,
  2211. current
  2212. }
  2213. };
  2214. }
  2215. function provideTheme(props) {
  2216. getCurrentInstance('provideTheme');
  2217. const theme = inject$1(ThemeSymbol, null);
  2218. if (!theme) throw new Error('Could not find Vuetify theme injection');
  2219. const name = computed(() => {
  2220. return props.theme ?? theme?.name.value;
  2221. });
  2222. const themeClasses = computed(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
  2223. const newTheme = {
  2224. ...theme,
  2225. name,
  2226. themeClasses
  2227. };
  2228. provide(ThemeSymbol, newTheme);
  2229. return newTheme;
  2230. }
  2231. function useTheme() {
  2232. getCurrentInstance('useTheme');
  2233. const theme = inject$1(ThemeSymbol, null);
  2234. if (!theme) throw new Error('Could not find Vuetify theme injection');
  2235. return theme;
  2236. }
  2237. function createCssClass(lines, selector, content) {
  2238. lines.push(`${selector} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
  2239. }
  2240. function genCssVariables(theme) {
  2241. const lightOverlay = theme.dark ? 2 : 1;
  2242. const darkOverlay = theme.dark ? 1 : 2;
  2243. const variables = [];
  2244. for (const [key, value] of Object.entries(theme.colors)) {
  2245. const rgb = parseColor(value);
  2246. variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
  2247. if (!key.startsWith('on-')) {
  2248. variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
  2249. }
  2250. }
  2251. for (const [key, value] of Object.entries(theme.variables)) {
  2252. const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
  2253. const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
  2254. variables.push(`--v-${key}: ${rgb ?? value}`);
  2255. }
  2256. return variables;
  2257. }
  2258. const makeVAppProps = propsFactory({
  2259. ...makeComponentProps(),
  2260. ...makeLayoutProps({
  2261. fullHeight: true
  2262. }),
  2263. ...makeThemeProps()
  2264. }, 'VApp');
  2265. const VApp = genericComponent()({
  2266. name: 'VApp',
  2267. props: makeVAppProps(),
  2268. setup(props, _ref) {
  2269. let {
  2270. slots
  2271. } = _ref;
  2272. const theme = provideTheme(props);
  2273. const {
  2274. layoutClasses,
  2275. layoutStyles,
  2276. getLayoutItem,
  2277. items,
  2278. layoutRef
  2279. } = createLayout(props);
  2280. const {
  2281. rtlClasses
  2282. } = useRtl();
  2283. useRender(() => createVNode("div", {
  2284. "ref": layoutRef,
  2285. "class": ['v-application', theme.themeClasses.value, layoutClasses.value, rtlClasses.value, props.class],
  2286. "style": [layoutStyles.value, props.style]
  2287. }, [createVNode("div", {
  2288. "class": "v-application__wrap"
  2289. }, [slots.default?.()])]));
  2290. return {
  2291. getLayoutItem,
  2292. items,
  2293. theme
  2294. };
  2295. }
  2296. });
  2297. // Utilities
  2298. // Types
  2299. // Composables
  2300. const makeTagProps = propsFactory({
  2301. tag: {
  2302. type: String,
  2303. default: 'div'
  2304. }
  2305. }, 'tag');
  2306. const makeVToolbarTitleProps = propsFactory({
  2307. text: String,
  2308. ...makeComponentProps(),
  2309. ...makeTagProps()
  2310. }, 'VToolbarTitle');
  2311. const VToolbarTitle = genericComponent()({
  2312. name: 'VToolbarTitle',
  2313. props: makeVToolbarTitleProps(),
  2314. setup(props, _ref) {
  2315. let {
  2316. slots
  2317. } = _ref;
  2318. useRender(() => {
  2319. const hasText = !!(slots.default || slots.text || props.text);
  2320. return createVNode(props.tag, {
  2321. "class": ['v-toolbar-title', props.class],
  2322. "style": props.style
  2323. }, {
  2324. default: () => [hasText && createVNode("div", {
  2325. "class": "v-toolbar-title__placeholder"
  2326. }, [slots.text ? slots.text() : props.text, slots.default?.()])]
  2327. });
  2328. });
  2329. return {};
  2330. }
  2331. });
  2332. // Utilities
  2333. // Types
  2334. const makeTransitionProps$1 = propsFactory({
  2335. disabled: Boolean,
  2336. group: Boolean,
  2337. hideOnLeave: Boolean,
  2338. leaveAbsolute: Boolean,
  2339. mode: String,
  2340. origin: String
  2341. }, 'transition');
  2342. function createCssTransition(name, origin, mode) {
  2343. return genericComponent()({
  2344. name,
  2345. props: makeTransitionProps$1({
  2346. mode,
  2347. origin
  2348. }),
  2349. setup(props, _ref) {
  2350. let {
  2351. slots
  2352. } = _ref;
  2353. const functions = {
  2354. onBeforeEnter(el) {
  2355. if (props.origin) {
  2356. el.style.transformOrigin = props.origin;
  2357. }
  2358. },
  2359. onLeave(el) {
  2360. if (props.leaveAbsolute) {
  2361. const {
  2362. offsetTop,
  2363. offsetLeft,
  2364. offsetWidth,
  2365. offsetHeight
  2366. } = el;
  2367. el._transitionInitialStyles = {
  2368. position: el.style.position,
  2369. top: el.style.top,
  2370. left: el.style.left,
  2371. width: el.style.width,
  2372. height: el.style.height
  2373. };
  2374. el.style.position = 'absolute';
  2375. el.style.top = `${offsetTop}px`;
  2376. el.style.left = `${offsetLeft}px`;
  2377. el.style.width = `${offsetWidth}px`;
  2378. el.style.height = `${offsetHeight}px`;
  2379. }
  2380. if (props.hideOnLeave) {
  2381. el.style.setProperty('display', 'none', 'important');
  2382. }
  2383. },
  2384. onAfterLeave(el) {
  2385. if (props.leaveAbsolute && el?._transitionInitialStyles) {
  2386. const {
  2387. position,
  2388. top,
  2389. left,
  2390. width,
  2391. height
  2392. } = el._transitionInitialStyles;
  2393. delete el._transitionInitialStyles;
  2394. el.style.position = position || '';
  2395. el.style.top = top || '';
  2396. el.style.left = left || '';
  2397. el.style.width = width || '';
  2398. el.style.height = height || '';
  2399. }
  2400. }
  2401. };
  2402. return () => {
  2403. const tag = props.group ? TransitionGroup : Transition;
  2404. return h(tag, {
  2405. name: props.disabled ? '' : name,
  2406. css: !props.disabled,
  2407. ...(props.group ? undefined : {
  2408. mode: props.mode
  2409. }),
  2410. ...(props.disabled ? {} : functions)
  2411. }, slots.default);
  2412. };
  2413. }
  2414. });
  2415. }
  2416. function createJavascriptTransition(name, functions) {
  2417. let mode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'in-out';
  2418. return genericComponent()({
  2419. name,
  2420. props: {
  2421. mode: {
  2422. type: String,
  2423. default: mode
  2424. },
  2425. disabled: Boolean
  2426. },
  2427. setup(props, _ref2) {
  2428. let {
  2429. slots
  2430. } = _ref2;
  2431. return () => {
  2432. return h(Transition, {
  2433. name: props.disabled ? '' : name,
  2434. css: !props.disabled,
  2435. // mode: props.mode, // TODO: vuejs/vue-next#3104
  2436. ...(props.disabled ? {} : functions)
  2437. }, slots.default);
  2438. };
  2439. }
  2440. });
  2441. }
  2442. // Utilities
  2443. function ExpandTransitionGenerator () {
  2444. let expandedParentClass = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  2445. let x = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  2446. const sizeProperty = x ? 'width' : 'height';
  2447. const offsetProperty = camelize(`offset-${sizeProperty}`);
  2448. return {
  2449. onBeforeEnter(el) {
  2450. el._parent = el.parentNode;
  2451. el._initialStyle = {
  2452. transition: el.style.transition,
  2453. overflow: el.style.overflow,
  2454. [sizeProperty]: el.style[sizeProperty]
  2455. };
  2456. },
  2457. onEnter(el) {
  2458. const initialStyle = el._initialStyle;
  2459. el.style.setProperty('transition', 'none', 'important');
  2460. // Hide overflow to account for collapsed margins in the calculated height
  2461. el.style.overflow = 'hidden';
  2462. const offset = `${el[offsetProperty]}px`;
  2463. el.style[sizeProperty] = '0';
  2464. void el.offsetHeight; // force reflow
  2465. el.style.transition = initialStyle.transition;
  2466. if (expandedParentClass && el._parent) {
  2467. el._parent.classList.add(expandedParentClass);
  2468. }
  2469. requestAnimationFrame(() => {
  2470. el.style[sizeProperty] = offset;
  2471. });
  2472. },
  2473. onAfterEnter: resetStyles,
  2474. onEnterCancelled: resetStyles,
  2475. onLeave(el) {
  2476. el._initialStyle = {
  2477. transition: '',
  2478. overflow: el.style.overflow,
  2479. [sizeProperty]: el.style[sizeProperty]
  2480. };
  2481. el.style.overflow = 'hidden';
  2482. el.style[sizeProperty] = `${el[offsetProperty]}px`;
  2483. void el.offsetHeight; // force reflow
  2484. requestAnimationFrame(() => el.style[sizeProperty] = '0');
  2485. },
  2486. onAfterLeave,
  2487. onLeaveCancelled: onAfterLeave
  2488. };
  2489. function onAfterLeave(el) {
  2490. if (expandedParentClass && el._parent) {
  2491. el._parent.classList.remove(expandedParentClass);
  2492. }
  2493. resetStyles(el);
  2494. }
  2495. function resetStyles(el) {
  2496. const size = el._initialStyle[sizeProperty];
  2497. el.style.overflow = el._initialStyle.overflow;
  2498. if (size != null) el.style[sizeProperty] = size;
  2499. delete el._initialStyle;
  2500. }
  2501. }
  2502. // Types
  2503. const makeVDialogTransitionProps = propsFactory({
  2504. target: Object
  2505. }, 'v-dialog-transition');
  2506. const VDialogTransition = genericComponent()({
  2507. name: 'VDialogTransition',
  2508. props: makeVDialogTransitionProps(),
  2509. setup(props, _ref) {
  2510. let {
  2511. slots
  2512. } = _ref;
  2513. const functions = {
  2514. onBeforeEnter(el) {
  2515. el.style.pointerEvents = 'none';
  2516. el.style.visibility = 'hidden';
  2517. },
  2518. async onEnter(el, done) {
  2519. await new Promise(resolve => requestAnimationFrame(resolve));
  2520. await new Promise(resolve => requestAnimationFrame(resolve));
  2521. el.style.visibility = '';
  2522. const {
  2523. x,
  2524. y,
  2525. sx,
  2526. sy,
  2527. speed
  2528. } = getDimensions(props.target, el);
  2529. const animation = animate(el, [{
  2530. transform: `translate(${x}px, ${y}px) scale(${sx}, ${sy})`,
  2531. opacity: 0
  2532. }, {}], {
  2533. duration: 225 * speed,
  2534. easing: deceleratedEasing
  2535. });
  2536. getChildren(el)?.forEach(el => {
  2537. animate(el, [{
  2538. opacity: 0
  2539. }, {
  2540. opacity: 0,
  2541. offset: 0.33
  2542. }, {}], {
  2543. duration: 225 * 2 * speed,
  2544. easing: standardEasing
  2545. });
  2546. });
  2547. animation.finished.then(() => done());
  2548. },
  2549. onAfterEnter(el) {
  2550. el.style.removeProperty('pointer-events');
  2551. },
  2552. onBeforeLeave(el) {
  2553. el.style.pointerEvents = 'none';
  2554. },
  2555. async onLeave(el, done) {
  2556. await new Promise(resolve => requestAnimationFrame(resolve));
  2557. const {
  2558. x,
  2559. y,
  2560. sx,
  2561. sy,
  2562. speed
  2563. } = getDimensions(props.target, el);
  2564. const animation = animate(el, [{}, {
  2565. transform: `translate(${x}px, ${y}px) scale(${sx}, ${sy})`,
  2566. opacity: 0
  2567. }], {
  2568. duration: 125 * speed,
  2569. easing: acceleratedEasing
  2570. });
  2571. animation.finished.then(() => done());
  2572. getChildren(el)?.forEach(el => {
  2573. animate(el, [{}, {
  2574. opacity: 0,
  2575. offset: 0.2
  2576. }, {
  2577. opacity: 0
  2578. }], {
  2579. duration: 125 * 2 * speed,
  2580. easing: standardEasing
  2581. });
  2582. });
  2583. },
  2584. onAfterLeave(el) {
  2585. el.style.removeProperty('pointer-events');
  2586. }
  2587. };
  2588. return () => {
  2589. return props.target ? createVNode(Transition, mergeProps({
  2590. "name": "dialog-transition"
  2591. }, functions, {
  2592. "css": false
  2593. }), slots) : createVNode(Transition, {
  2594. "name": "dialog-transition"
  2595. }, slots);
  2596. };
  2597. }
  2598. });
  2599. /** Animatable children (card, sheet, list) */
  2600. function getChildren(el) {
  2601. const els = el.querySelector(':scope > .v-card, :scope > .v-sheet, :scope > .v-list')?.children;
  2602. return els && [...els];
  2603. }
  2604. function getDimensions(target, el) {
  2605. const targetBox = target.getBoundingClientRect();
  2606. const elBox = nullifyTransforms(el);
  2607. const [originX, originY] = getComputedStyle(el).transformOrigin.split(' ').map(v => parseFloat(v));
  2608. const [anchorSide, anchorOffset] = getComputedStyle(el).getPropertyValue('--v-overlay-anchor-origin').split(' ');
  2609. let offsetX = targetBox.left + targetBox.width / 2;
  2610. if (anchorSide === 'left' || anchorOffset === 'left') {
  2611. offsetX -= targetBox.width / 2;
  2612. } else if (anchorSide === 'right' || anchorOffset === 'right') {
  2613. offsetX += targetBox.width / 2;
  2614. }
  2615. let offsetY = targetBox.top + targetBox.height / 2;
  2616. if (anchorSide === 'top' || anchorOffset === 'top') {
  2617. offsetY -= targetBox.height / 2;
  2618. } else if (anchorSide === 'bottom' || anchorOffset === 'bottom') {
  2619. offsetY += targetBox.height / 2;
  2620. }
  2621. const tsx = targetBox.width / elBox.width;
  2622. const tsy = targetBox.height / elBox.height;
  2623. const maxs = Math.max(1, tsx, tsy);
  2624. const sx = tsx / maxs || 0;
  2625. const sy = tsy / maxs || 0;
  2626. // Animate elements larger than 12% of the screen area up to 1.5x slower
  2627. const asa = elBox.width * elBox.height / (window.innerWidth * window.innerHeight);
  2628. const speed = asa > 0.12 ? Math.min(1.5, (asa - 0.12) * 10 + 1) : 1;
  2629. return {
  2630. x: offsetX - (originX + elBox.left),
  2631. y: offsetY - (originY + elBox.top),
  2632. sx,
  2633. sy,
  2634. speed
  2635. };
  2636. }
  2637. // Component specific transitions
  2638. const VFabTransition = createCssTransition('fab-transition', 'center center', 'out-in');
  2639. // Generic transitions
  2640. const VDialogBottomTransition = createCssTransition('dialog-bottom-transition');
  2641. const VDialogTopTransition = createCssTransition('dialog-top-transition');
  2642. const VFadeTransition = createCssTransition('fade-transition');
  2643. const VScaleTransition = createCssTransition('scale-transition');
  2644. const VScrollXTransition = createCssTransition('scroll-x-transition');
  2645. const VScrollXReverseTransition = createCssTransition('scroll-x-reverse-transition');
  2646. const VScrollYTransition = createCssTransition('scroll-y-transition');
  2647. const VScrollYReverseTransition = createCssTransition('scroll-y-reverse-transition');
  2648. const VSlideXTransition = createCssTransition('slide-x-transition');
  2649. const VSlideXReverseTransition = createCssTransition('slide-x-reverse-transition');
  2650. const VSlideYTransition = createCssTransition('slide-y-transition');
  2651. const VSlideYReverseTransition = createCssTransition('slide-y-reverse-transition');
  2652. // Javascript transitions
  2653. const VExpandTransition = createJavascriptTransition('expand-transition', ExpandTransitionGenerator());
  2654. const VExpandXTransition = createJavascriptTransition('expand-x-transition', ExpandTransitionGenerator('', true));
  2655. // Composables
  2656. // Types
  2657. const makeVDefaultsProviderProps = propsFactory({
  2658. defaults: Object,
  2659. disabled: Boolean,
  2660. reset: [Number, String],
  2661. root: [Boolean, String],
  2662. scoped: Boolean
  2663. }, 'VDefaultsProvider');
  2664. const VDefaultsProvider = genericComponent(false)({
  2665. name: 'VDefaultsProvider',
  2666. props: makeVDefaultsProviderProps(),
  2667. setup(props, _ref) {
  2668. let {
  2669. slots
  2670. } = _ref;
  2671. const {
  2672. defaults,
  2673. disabled,
  2674. reset,
  2675. root,
  2676. scoped
  2677. } = toRefs(props);
  2678. provideDefaults(defaults, {
  2679. reset,
  2680. root,
  2681. scoped,
  2682. disabled
  2683. });
  2684. return () => slots.default?.();
  2685. }
  2686. });
  2687. // Utilities
  2688. // Types
  2689. // Composables
  2690. const makeDimensionProps = propsFactory({
  2691. height: [Number, String],
  2692. maxHeight: [Number, String],
  2693. maxWidth: [Number, String],
  2694. minHeight: [Number, String],
  2695. minWidth: [Number, String],
  2696. width: [Number, String]
  2697. }, 'dimension');
  2698. function useDimension(props) {
  2699. const dimensionStyles = computed(() => ({
  2700. height: convertToUnit(props.height),
  2701. maxHeight: convertToUnit(props.maxHeight),
  2702. maxWidth: convertToUnit(props.maxWidth),
  2703. minHeight: convertToUnit(props.minHeight),
  2704. minWidth: convertToUnit(props.minWidth),
  2705. width: convertToUnit(props.width)
  2706. }));
  2707. return {
  2708. dimensionStyles
  2709. };
  2710. }
  2711. function useAspectStyles(props) {
  2712. return {
  2713. aspectStyles: computed(() => {
  2714. const ratio = Number(props.aspectRatio);
  2715. return ratio ? {
  2716. paddingBottom: String(1 / ratio * 100) + '%'
  2717. } : undefined;
  2718. })
  2719. };
  2720. }
  2721. const makeVResponsiveProps = propsFactory({
  2722. aspectRatio: [String, Number],
  2723. contentClass: String,
  2724. inline: Boolean,
  2725. ...makeComponentProps(),
  2726. ...makeDimensionProps()
  2727. }, 'VResponsive');
  2728. const VResponsive = genericComponent()({
  2729. name: 'VResponsive',
  2730. props: makeVResponsiveProps(),
  2731. setup(props, _ref) {
  2732. let {
  2733. slots
  2734. } = _ref;
  2735. const {
  2736. aspectStyles
  2737. } = useAspectStyles(props);
  2738. const {
  2739. dimensionStyles
  2740. } = useDimension(props);
  2741. useRender(() => createVNode("div", {
  2742. "class": ['v-responsive', {
  2743. 'v-responsive--inline': props.inline
  2744. }, props.class],
  2745. "style": [dimensionStyles.value, props.style]
  2746. }, [createVNode("div", {
  2747. "class": "v-responsive__sizer",
  2748. "style": aspectStyles.value
  2749. }, null), slots.additional?.(), slots.default && createVNode("div", {
  2750. "class": ['v-responsive__content', props.contentClass]
  2751. }, [slots.default()])]));
  2752. return {};
  2753. }
  2754. });
  2755. // Utilities
  2756. // Types
  2757. const makeTransitionProps = propsFactory({
  2758. transition: {
  2759. type: [Boolean, String, Object],
  2760. default: 'fade-transition',
  2761. validator: val => val !== true
  2762. }
  2763. }, 'transition');
  2764. const MaybeTransition = (props, _ref) => {
  2765. let {
  2766. slots
  2767. } = _ref;
  2768. const {
  2769. transition,
  2770. disabled,
  2771. ...rest
  2772. } = props;
  2773. const {
  2774. component = Transition,
  2775. ...customProps
  2776. } = typeof transition === 'object' ? transition : {};
  2777. return h(component, mergeProps(typeof transition === 'string' ? {
  2778. name: disabled ? '' : transition
  2779. } : customProps, rest, {
  2780. disabled
  2781. }), slots);
  2782. };
  2783. // Utilities
  2784. // Types
  2785. function mounted$5(el, binding) {
  2786. if (!SUPPORTS_INTERSECTION) return;
  2787. const modifiers = binding.modifiers || {};
  2788. const value = binding.value;
  2789. const {
  2790. handler,
  2791. options
  2792. } = typeof value === 'object' ? value : {
  2793. handler: value,
  2794. options: {}
  2795. };
  2796. const observer = new IntersectionObserver(function () {
  2797. let entries = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  2798. let observer = arguments.length > 1 ? arguments[1] : undefined;
  2799. const _observe = el._observe?.[binding.instance.$.uid];
  2800. if (!_observe) return; // Just in case, should never fire
  2801. const isIntersecting = entries.some(entry => entry.isIntersecting);
  2802. // If is not quiet or has already been
  2803. // initted, invoke the user callback
  2804. if (handler && (!modifiers.quiet || _observe.init) && (!modifiers.once || isIntersecting || _observe.init)) {
  2805. handler(isIntersecting, entries, observer);
  2806. }
  2807. if (isIntersecting && modifiers.once) unmounted$5(el, binding);else _observe.init = true;
  2808. }, options);
  2809. el._observe = Object(el._observe);
  2810. el._observe[binding.instance.$.uid] = {
  2811. init: false,
  2812. observer
  2813. };
  2814. observer.observe(el);
  2815. }
  2816. function unmounted$5(el, binding) {
  2817. const observe = el._observe?.[binding.instance.$.uid];
  2818. if (!observe) return;
  2819. observe.observer.unobserve(el);
  2820. delete el._observe[binding.instance.$.uid];
  2821. }
  2822. const Intersect = {
  2823. mounted: mounted$5,
  2824. unmounted: unmounted$5
  2825. };
  2826. // Types
  2827. const makeVImgProps = propsFactory({
  2828. alt: String,
  2829. cover: Boolean,
  2830. eager: Boolean,
  2831. gradient: String,
  2832. lazySrc: String,
  2833. options: {
  2834. type: Object,
  2835. // For more information on types, navigate to:
  2836. // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
  2837. default: () => ({
  2838. root: undefined,
  2839. rootMargin: undefined,
  2840. threshold: undefined
  2841. })
  2842. },
  2843. sizes: String,
  2844. src: {
  2845. type: [String, Object],
  2846. default: ''
  2847. },
  2848. srcset: String,
  2849. ...makeVResponsiveProps(),
  2850. ...makeComponentProps(),
  2851. ...makeTransitionProps()
  2852. }, 'VImg');
  2853. const VImg = genericComponent()({
  2854. name: 'VImg',
  2855. directives: {
  2856. intersect: Intersect
  2857. },
  2858. props: makeVImgProps(),
  2859. emits: {
  2860. loadstart: value => true,
  2861. load: value => true,
  2862. error: value => true
  2863. },
  2864. setup(props, _ref) {
  2865. let {
  2866. emit,
  2867. slots
  2868. } = _ref;
  2869. const currentSrc = shallowRef(''); // Set from srcset
  2870. const image = ref();
  2871. const state = shallowRef(props.eager ? 'loading' : 'idle');
  2872. const naturalWidth = shallowRef();
  2873. const naturalHeight = shallowRef();
  2874. const normalisedSrc = computed(() => {
  2875. return props.src && typeof props.src === 'object' ? {
  2876. src: props.src.src,
  2877. srcset: props.srcset || props.src.srcset,
  2878. lazySrc: props.lazySrc || props.src.lazySrc,
  2879. aspect: Number(props.aspectRatio || props.src.aspect || 0)
  2880. } : {
  2881. src: props.src,
  2882. srcset: props.srcset,
  2883. lazySrc: props.lazySrc,
  2884. aspect: Number(props.aspectRatio || 0)
  2885. };
  2886. });
  2887. const aspectRatio = computed(() => {
  2888. return normalisedSrc.value.aspect || naturalWidth.value / naturalHeight.value || 0;
  2889. });
  2890. watch(() => props.src, () => {
  2891. init(state.value !== 'idle');
  2892. });
  2893. watch(aspectRatio, (val, oldVal) => {
  2894. if (!val && oldVal && image.value) {
  2895. pollForSize(image.value);
  2896. }
  2897. });
  2898. // TODO: getSrc when window width changes
  2899. onBeforeMount(() => init());
  2900. function init(isIntersecting) {
  2901. if (props.eager && isIntersecting) return;
  2902. if (SUPPORTS_INTERSECTION && !isIntersecting && !props.eager) return;
  2903. state.value = 'loading';
  2904. if (normalisedSrc.value.lazySrc) {
  2905. const lazyImg = new Image();
  2906. lazyImg.src = normalisedSrc.value.lazySrc;
  2907. pollForSize(lazyImg, null);
  2908. }
  2909. if (!normalisedSrc.value.src) return;
  2910. nextTick(() => {
  2911. emit('loadstart', image.value?.currentSrc || normalisedSrc.value.src);
  2912. if (image.value?.complete) {
  2913. if (!image.value.naturalWidth) {
  2914. onError();
  2915. }
  2916. if (state.value === 'error') return;
  2917. if (!aspectRatio.value) pollForSize(image.value, null);
  2918. onLoad();
  2919. } else {
  2920. if (!aspectRatio.value) pollForSize(image.value);
  2921. getSrc();
  2922. }
  2923. });
  2924. }
  2925. function onLoad() {
  2926. getSrc();
  2927. state.value = 'loaded';
  2928. emit('load', image.value?.currentSrc || normalisedSrc.value.src);
  2929. }
  2930. function onError() {
  2931. state.value = 'error';
  2932. emit('error', image.value?.currentSrc || normalisedSrc.value.src);
  2933. }
  2934. function getSrc() {
  2935. const img = image.value;
  2936. if (img) currentSrc.value = img.currentSrc || img.src;
  2937. }
  2938. let timer = -1;
  2939. function pollForSize(img) {
  2940. let timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100;
  2941. const poll = () => {
  2942. clearTimeout(timer);
  2943. const {
  2944. naturalHeight: imgHeight,
  2945. naturalWidth: imgWidth
  2946. } = img;
  2947. if (imgHeight || imgWidth) {
  2948. naturalWidth.value = imgWidth;
  2949. naturalHeight.value = imgHeight;
  2950. } else if (!img.complete && state.value === 'loading' && timeout != null) {
  2951. timer = window.setTimeout(poll, timeout);
  2952. } else if (img.currentSrc.endsWith('.svg') || img.currentSrc.startsWith('data:image/svg+xml')) {
  2953. naturalWidth.value = 1;
  2954. naturalHeight.value = 1;
  2955. }
  2956. };
  2957. poll();
  2958. }
  2959. const containClasses = computed(() => ({
  2960. 'v-img__img--cover': props.cover,
  2961. 'v-img__img--contain': !props.cover
  2962. }));
  2963. const __image = () => {
  2964. if (!normalisedSrc.value.src || state.value === 'idle') return null;
  2965. const img = createVNode("img", {
  2966. "class": ['v-img__img', containClasses.value],
  2967. "src": normalisedSrc.value.src,
  2968. "srcset": normalisedSrc.value.srcset,
  2969. "alt": props.alt,
  2970. "sizes": props.sizes,
  2971. "ref": image,
  2972. "onLoad": onLoad,
  2973. "onError": onError
  2974. }, null);
  2975. const sources = slots.sources?.();
  2976. return createVNode(MaybeTransition, {
  2977. "transition": props.transition,
  2978. "appear": true
  2979. }, {
  2980. default: () => [withDirectives(sources ? createVNode("picture", {
  2981. "class": "v-img__picture"
  2982. }, [sources, img]) : img, [[vShow, state.value === 'loaded']])]
  2983. });
  2984. };
  2985. const __preloadImage = () => createVNode(MaybeTransition, {
  2986. "transition": props.transition
  2987. }, {
  2988. default: () => [normalisedSrc.value.lazySrc && state.value !== 'loaded' && createVNode("img", {
  2989. "class": ['v-img__img', 'v-img__img--preload', containClasses.value],
  2990. "src": normalisedSrc.value.lazySrc,
  2991. "alt": props.alt
  2992. }, null)]
  2993. });
  2994. const __placeholder = () => {
  2995. if (!slots.placeholder) return null;
  2996. return createVNode(MaybeTransition, {
  2997. "transition": props.transition,
  2998. "appear": true
  2999. }, {
  3000. default: () => [(state.value === 'loading' || state.value === 'error' && !slots.error) && createVNode("div", {
  3001. "class": "v-img__placeholder"
  3002. }, [slots.placeholder()])]
  3003. });
  3004. };
  3005. const __error = () => {
  3006. if (!slots.error) return null;
  3007. return createVNode(MaybeTransition, {
  3008. "transition": props.transition,
  3009. "appear": true
  3010. }, {
  3011. default: () => [state.value === 'error' && createVNode("div", {
  3012. "class": "v-img__error"
  3013. }, [slots.error()])]
  3014. });
  3015. };
  3016. const __gradient = () => {
  3017. if (!props.gradient) return null;
  3018. return createVNode("div", {
  3019. "class": "v-img__gradient",
  3020. "style": {
  3021. backgroundImage: `linear-gradient(${props.gradient})`
  3022. }
  3023. }, null);
  3024. };
  3025. const isBooted = shallowRef(false);
  3026. {
  3027. const stop = watch(aspectRatio, val => {
  3028. if (val) {
  3029. // Doesn't work with nextTick, idk why
  3030. requestAnimationFrame(() => {
  3031. requestAnimationFrame(() => {
  3032. isBooted.value = true;
  3033. });
  3034. });
  3035. stop();
  3036. }
  3037. });
  3038. }
  3039. useRender(() => {
  3040. const [responsiveProps] = VResponsive.filterProps(props);
  3041. return withDirectives(createVNode(VResponsive, mergeProps({
  3042. "class": ['v-img', {
  3043. 'v-img--booting': !isBooted.value
  3044. }, props.class],
  3045. "style": [{
  3046. width: convertToUnit(props.width === 'auto' ? naturalWidth.value : props.width)
  3047. }, props.style]
  3048. }, responsiveProps, {
  3049. "aspectRatio": aspectRatio.value,
  3050. "aria-label": props.alt,
  3051. "role": props.alt ? 'img' : undefined
  3052. }), {
  3053. additional: () => createVNode(Fragment, null, [createVNode(__image, null, null), createVNode(__preloadImage, null, null), createVNode(__gradient, null, null), createVNode(__placeholder, null, null), createVNode(__error, null, null)]),
  3054. default: slots.default
  3055. }), [[resolveDirective("intersect"), {
  3056. handler: init,
  3057. options: props.options
  3058. }, null, {
  3059. once: true
  3060. }]]);
  3061. });
  3062. return {
  3063. currentSrc,
  3064. image,
  3065. state,
  3066. naturalWidth,
  3067. naturalHeight
  3068. };
  3069. }
  3070. });
  3071. // Utilities
  3072. // Types
  3073. // Composables
  3074. const makeBorderProps = propsFactory({
  3075. border: [Boolean, Number, String]
  3076. }, 'border');
  3077. function useBorder(props) {
  3078. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  3079. const borderClasses = computed(() => {
  3080. const border = isRef(props) ? props.value : props.border;
  3081. const classes = [];
  3082. if (border === true || border === '') {
  3083. classes.push(`${name}--border`);
  3084. } else if (typeof border === 'string' || border === 0) {
  3085. for (const value of String(border).split(' ')) {
  3086. classes.push(`border-${value}`);
  3087. }
  3088. }
  3089. return classes;
  3090. });
  3091. return {
  3092. borderClasses
  3093. };
  3094. }
  3095. // Utilities
  3096. // Types
  3097. // Composables
  3098. function useColor(colors) {
  3099. return destructComputed(() => {
  3100. const classes = [];
  3101. const styles = {};
  3102. if (colors.value.background) {
  3103. if (isCssColor(colors.value.background)) {
  3104. styles.backgroundColor = colors.value.background;
  3105. } else {
  3106. classes.push(`bg-${colors.value.background}`);
  3107. }
  3108. }
  3109. if (colors.value.text) {
  3110. if (isCssColor(colors.value.text)) {
  3111. styles.color = colors.value.text;
  3112. styles.caretColor = colors.value.text;
  3113. } else {
  3114. classes.push(`text-${colors.value.text}`);
  3115. }
  3116. }
  3117. return {
  3118. colorClasses: classes,
  3119. colorStyles: styles
  3120. };
  3121. });
  3122. }
  3123. function useTextColor(props, name) {
  3124. const colors = computed(() => ({
  3125. text: isRef(props) ? props.value : name ? props[name] : null
  3126. }));
  3127. const {
  3128. colorClasses: textColorClasses,
  3129. colorStyles: textColorStyles
  3130. } = useColor(colors);
  3131. return {
  3132. textColorClasses,
  3133. textColorStyles
  3134. };
  3135. }
  3136. function useBackgroundColor(props, name) {
  3137. const colors = computed(() => ({
  3138. background: isRef(props) ? props.value : name ? props[name] : null
  3139. }));
  3140. const {
  3141. colorClasses: backgroundColorClasses,
  3142. colorStyles: backgroundColorStyles
  3143. } = useColor(colors);
  3144. return {
  3145. backgroundColorClasses,
  3146. backgroundColorStyles
  3147. };
  3148. }
  3149. // Utilities
  3150. // Types
  3151. // Composables
  3152. const makeElevationProps = propsFactory({
  3153. elevation: {
  3154. type: [Number, String],
  3155. validator(v) {
  3156. const value = parseInt(v);
  3157. return !isNaN(value) && value >= 0 &&
  3158. // Material Design has a maximum elevation of 24
  3159. // https://material.io/design/environment/elevation.html#default-elevations
  3160. value <= 24;
  3161. }
  3162. }
  3163. }, 'elevation');
  3164. function useElevation(props) {
  3165. const elevationClasses = computed(() => {
  3166. const elevation = isRef(props) ? props.value : props.elevation;
  3167. const classes = [];
  3168. if (elevation == null) return classes;
  3169. classes.push(`elevation-${elevation}`);
  3170. return classes;
  3171. });
  3172. return {
  3173. elevationClasses
  3174. };
  3175. }
  3176. // Utilities
  3177. // Types
  3178. // Composables
  3179. const makeRoundedProps = propsFactory({
  3180. rounded: {
  3181. type: [Boolean, Number, String],
  3182. default: undefined
  3183. }
  3184. }, 'rounded');
  3185. function useRounded(props) {
  3186. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  3187. const roundedClasses = computed(() => {
  3188. const rounded = isRef(props) ? props.value : props.rounded;
  3189. const classes = [];
  3190. if (rounded === true || rounded === '') {
  3191. classes.push(`${name}--rounded`);
  3192. } else if (typeof rounded === 'string' || rounded === 0) {
  3193. for (const value of String(rounded).split(' ')) {
  3194. classes.push(`rounded-${value}`);
  3195. }
  3196. }
  3197. return classes;
  3198. });
  3199. return {
  3200. roundedClasses
  3201. };
  3202. }
  3203. // Types
  3204. const allowedDensities$1 = [null, 'prominent', 'default', 'comfortable', 'compact'];
  3205. const makeVToolbarProps = propsFactory({
  3206. absolute: Boolean,
  3207. collapse: Boolean,
  3208. color: String,
  3209. density: {
  3210. type: String,
  3211. default: 'default',
  3212. validator: v => allowedDensities$1.includes(v)
  3213. },
  3214. extended: Boolean,
  3215. extensionHeight: {
  3216. type: [Number, String],
  3217. default: 48
  3218. },
  3219. flat: Boolean,
  3220. floating: Boolean,
  3221. height: {
  3222. type: [Number, String],
  3223. default: 64
  3224. },
  3225. image: String,
  3226. title: String,
  3227. ...makeBorderProps(),
  3228. ...makeComponentProps(),
  3229. ...makeElevationProps(),
  3230. ...makeRoundedProps(),
  3231. ...makeTagProps({
  3232. tag: 'header'
  3233. }),
  3234. ...makeThemeProps()
  3235. }, 'VToolbar');
  3236. const VToolbar = genericComponent()({
  3237. name: 'VToolbar',
  3238. props: makeVToolbarProps(),
  3239. setup(props, _ref) {
  3240. let {
  3241. slots
  3242. } = _ref;
  3243. const {
  3244. backgroundColorClasses,
  3245. backgroundColorStyles
  3246. } = useBackgroundColor(toRef(props, 'color'));
  3247. const {
  3248. borderClasses
  3249. } = useBorder(props);
  3250. const {
  3251. elevationClasses
  3252. } = useElevation(props);
  3253. const {
  3254. roundedClasses
  3255. } = useRounded(props);
  3256. const {
  3257. themeClasses
  3258. } = provideTheme(props);
  3259. const {
  3260. rtlClasses
  3261. } = useRtl();
  3262. const isExtended = shallowRef(!!(props.extended || slots.extension?.()));
  3263. 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));
  3264. 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);
  3265. provideDefaults({
  3266. VBtn: {
  3267. variant: 'text'
  3268. }
  3269. });
  3270. useRender(() => {
  3271. const hasTitle = !!(props.title || slots.title);
  3272. const hasImage = !!(slots.image || props.image);
  3273. const extension = slots.extension?.();
  3274. isExtended.value = !!(props.extended || extension);
  3275. return createVNode(props.tag, {
  3276. "class": ['v-toolbar', {
  3277. 'v-toolbar--absolute': props.absolute,
  3278. 'v-toolbar--collapse': props.collapse,
  3279. 'v-toolbar--flat': props.flat,
  3280. 'v-toolbar--floating': props.floating,
  3281. [`v-toolbar--density-${props.density}`]: true
  3282. }, backgroundColorClasses.value, borderClasses.value, elevationClasses.value, roundedClasses.value, themeClasses.value, rtlClasses.value, props.class],
  3283. "style": [backgroundColorStyles.value, props.style]
  3284. }, {
  3285. default: () => [hasImage && createVNode("div", {
  3286. "key": "image",
  3287. "class": "v-toolbar__image"
  3288. }, [!slots.image ? createVNode(VImg, {
  3289. "key": "image-img",
  3290. "cover": true,
  3291. "src": props.image
  3292. }, null) : createVNode(VDefaultsProvider, {
  3293. "key": "image-defaults",
  3294. "disabled": !props.image,
  3295. "defaults": {
  3296. VImg: {
  3297. cover: true,
  3298. src: props.image
  3299. }
  3300. }
  3301. }, slots.image)]), createVNode(VDefaultsProvider, {
  3302. "defaults": {
  3303. VTabs: {
  3304. height: convertToUnit(contentHeight.value)
  3305. }
  3306. }
  3307. }, {
  3308. default: () => [createVNode("div", {
  3309. "class": "v-toolbar__content",
  3310. "style": {
  3311. height: convertToUnit(contentHeight.value)
  3312. }
  3313. }, [slots.prepend && createVNode("div", {
  3314. "class": "v-toolbar__prepend"
  3315. }, [slots.prepend?.()]), hasTitle && createVNode(VToolbarTitle, {
  3316. "key": "title",
  3317. "text": props.title
  3318. }, {
  3319. text: slots.title
  3320. }), slots.default?.(), slots.append && createVNode("div", {
  3321. "class": "v-toolbar__append"
  3322. }, [slots.append?.()])])]
  3323. }), createVNode(VDefaultsProvider, {
  3324. "defaults": {
  3325. VTabs: {
  3326. height: convertToUnit(extensionHeight.value)
  3327. }
  3328. }
  3329. }, {
  3330. default: () => [createVNode(VExpandTransition, null, {
  3331. default: () => [isExtended.value && createVNode("div", {
  3332. "class": "v-toolbar__extension",
  3333. "style": {
  3334. height: convertToUnit(extensionHeight.value)
  3335. }
  3336. }, [extension])]
  3337. })]
  3338. })]
  3339. });
  3340. });
  3341. return {
  3342. contentHeight,
  3343. extensionHeight
  3344. };
  3345. }
  3346. });
  3347. // Utilities
  3348. // Types
  3349. // Composables
  3350. const makeScrollProps = propsFactory({
  3351. scrollTarget: {
  3352. type: String
  3353. },
  3354. scrollThreshold: {
  3355. type: [String, Number],
  3356. default: 300
  3357. }
  3358. }, 'scroll');
  3359. function useScroll(props) {
  3360. let args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  3361. const {
  3362. canScroll
  3363. } = args;
  3364. let previousScroll = 0;
  3365. const target = ref(null);
  3366. const currentScroll = shallowRef(0);
  3367. const savedScroll = shallowRef(0);
  3368. const currentThreshold = shallowRef(0);
  3369. const isScrollActive = shallowRef(false);
  3370. const isScrollingUp = shallowRef(false);
  3371. const scrollThreshold = computed(() => {
  3372. return Number(props.scrollThreshold);
  3373. });
  3374. /**
  3375. * 1: at top
  3376. * 0: at threshold
  3377. */
  3378. const scrollRatio = computed(() => {
  3379. return clamp((scrollThreshold.value - currentScroll.value) / scrollThreshold.value || 0);
  3380. });
  3381. const onScroll = () => {
  3382. const targetEl = target.value;
  3383. if (!targetEl || canScroll && !canScroll.value) return;
  3384. previousScroll = currentScroll.value;
  3385. currentScroll.value = 'window' in targetEl ? targetEl.pageYOffset : targetEl.scrollTop;
  3386. isScrollingUp.value = currentScroll.value < previousScroll;
  3387. currentThreshold.value = Math.abs(currentScroll.value - scrollThreshold.value);
  3388. };
  3389. watch(isScrollingUp, () => {
  3390. savedScroll.value = savedScroll.value || currentScroll.value;
  3391. });
  3392. watch(isScrollActive, () => {
  3393. savedScroll.value = 0;
  3394. });
  3395. onMounted(() => {
  3396. watch(() => props.scrollTarget, scrollTarget => {
  3397. const newTarget = scrollTarget ? document.querySelector(scrollTarget) : window;
  3398. if (!newTarget) {
  3399. consoleWarn(`Unable to locate element with identifier ${scrollTarget}`);
  3400. return;
  3401. }
  3402. if (newTarget === target.value) return;
  3403. target.value?.removeEventListener('scroll', onScroll);
  3404. target.value = newTarget;
  3405. target.value.addEventListener('scroll', onScroll, {
  3406. passive: true
  3407. });
  3408. }, {
  3409. immediate: true
  3410. });
  3411. });
  3412. onBeforeUnmount(() => {
  3413. target.value?.removeEventListener('scroll', onScroll);
  3414. });
  3415. // Do we need this? If yes - seems that
  3416. // there's no need to expose onScroll
  3417. canScroll && watch(canScroll, onScroll, {
  3418. immediate: true
  3419. });
  3420. return {
  3421. scrollThreshold,
  3422. currentScroll,
  3423. currentThreshold,
  3424. isScrollActive,
  3425. scrollRatio,
  3426. // required only for testing
  3427. // probably can be removed
  3428. // later (2 chars chlng)
  3429. isScrollingUp,
  3430. savedScroll
  3431. };
  3432. }
  3433. // Utilities
  3434. // Composables
  3435. function useSsrBoot() {
  3436. const isBooted = shallowRef(false);
  3437. onMounted(() => {
  3438. window.requestAnimationFrame(() => {
  3439. isBooted.value = true;
  3440. });
  3441. });
  3442. const ssrBootStyles = computed(() => !isBooted.value ? {
  3443. transition: 'none !important'
  3444. } : undefined);
  3445. return {
  3446. ssrBootStyles,
  3447. isBooted: readonly(isBooted)
  3448. };
  3449. }
  3450. // Types
  3451. const makeVAppBarProps = propsFactory({
  3452. scrollBehavior: String,
  3453. modelValue: {
  3454. type: Boolean,
  3455. default: true
  3456. },
  3457. location: {
  3458. type: String,
  3459. default: 'top',
  3460. validator: value => ['top', 'bottom'].includes(value)
  3461. },
  3462. ...makeVToolbarProps(),
  3463. ...makeLayoutItemProps(),
  3464. ...makeScrollProps(),
  3465. height: {
  3466. type: [Number, String],
  3467. default: 64
  3468. }
  3469. }, 'VAppBar');
  3470. const VAppBar = genericComponent()({
  3471. name: 'VAppBar',
  3472. props: makeVAppBarProps(),
  3473. emits: {
  3474. 'update:modelValue': value => true
  3475. },
  3476. setup(props, _ref) {
  3477. let {
  3478. slots
  3479. } = _ref;
  3480. const vToolbarRef = ref();
  3481. const isActive = useProxiedModel(props, 'modelValue');
  3482. const scrollBehavior = computed(() => {
  3483. const behavior = new Set(props.scrollBehavior?.split(' ') ?? []);
  3484. return {
  3485. hide: behavior.has('hide'),
  3486. // fullyHide: behavior.has('fully-hide'),
  3487. inverted: behavior.has('inverted'),
  3488. collapse: behavior.has('collapse'),
  3489. elevate: behavior.has('elevate'),
  3490. fadeImage: behavior.has('fade-image')
  3491. // shrink: behavior.has('shrink'),
  3492. };
  3493. });
  3494. const canScroll = computed(() => {
  3495. const behavior = scrollBehavior.value;
  3496. return behavior.hide ||
  3497. // behavior.fullyHide ||
  3498. behavior.inverted || behavior.collapse || behavior.elevate || behavior.fadeImage ||
  3499. // behavior.shrink ||
  3500. !isActive.value;
  3501. });
  3502. const {
  3503. currentScroll,
  3504. scrollThreshold,
  3505. isScrollingUp,
  3506. scrollRatio
  3507. } = useScroll(props, {
  3508. canScroll
  3509. });
  3510. const isCollapsed = computed(() => props.collapse || scrollBehavior.value.collapse && (scrollBehavior.value.inverted ? scrollRatio.value > 0 : scrollRatio.value === 0));
  3511. const isFlat = computed(() => props.flat || scrollBehavior.value.elevate && (scrollBehavior.value.inverted ? currentScroll.value > 0 : currentScroll.value === 0));
  3512. const opacity = computed(() => scrollBehavior.value.fadeImage ? scrollBehavior.value.inverted ? 1 - scrollRatio.value : scrollRatio.value : undefined);
  3513. const height = computed(() => {
  3514. if (scrollBehavior.value.hide && scrollBehavior.value.inverted) return 0;
  3515. const height = vToolbarRef.value?.contentHeight ?? 0;
  3516. const extensionHeight = vToolbarRef.value?.extensionHeight ?? 0;
  3517. return height + extensionHeight;
  3518. });
  3519. useToggleScope(computed(() => !!props.scrollBehavior), () => {
  3520. watchEffect(() => {
  3521. if (scrollBehavior.value.hide) {
  3522. if (scrollBehavior.value.inverted) {
  3523. isActive.value = currentScroll.value > scrollThreshold.value;
  3524. } else {
  3525. isActive.value = isScrollingUp.value || currentScroll.value < scrollThreshold.value;
  3526. }
  3527. } else {
  3528. isActive.value = true;
  3529. }
  3530. });
  3531. });
  3532. const {
  3533. ssrBootStyles
  3534. } = useSsrBoot();
  3535. const {
  3536. layoutItemStyles
  3537. } = useLayoutItem({
  3538. id: props.name,
  3539. order: computed(() => parseInt(props.order, 10)),
  3540. position: toRef(props, 'location'),
  3541. layoutSize: height,
  3542. elementSize: shallowRef(undefined),
  3543. active: isActive,
  3544. absolute: toRef(props, 'absolute')
  3545. });
  3546. useRender(() => {
  3547. const [toolbarProps] = VToolbar.filterProps(props);
  3548. return createVNode(VToolbar, mergeProps({
  3549. "ref": vToolbarRef,
  3550. "class": ['v-app-bar', {
  3551. 'v-app-bar--bottom': props.location === 'bottom'
  3552. }, props.class],
  3553. "style": [{
  3554. ...layoutItemStyles.value,
  3555. '--v-toolbar-image-opacity': opacity.value,
  3556. height: undefined,
  3557. ...ssrBootStyles.value
  3558. }, props.style]
  3559. }, toolbarProps, {
  3560. "collapse": isCollapsed.value,
  3561. "flat": isFlat.value
  3562. }), slots);
  3563. });
  3564. return {};
  3565. }
  3566. });
  3567. // Utilities
  3568. // Types
  3569. const allowedDensities = [null, 'default', 'comfortable', 'compact'];
  3570. // typeof allowedDensities[number] evalutes to any
  3571. // when generating api types for whatever reason.
  3572. // Composables
  3573. const makeDensityProps = propsFactory({
  3574. density: {
  3575. type: String,
  3576. default: 'default',
  3577. validator: v => allowedDensities.includes(v)
  3578. }
  3579. }, 'density');
  3580. function useDensity(props) {
  3581. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  3582. const densityClasses = computed(() => {
  3583. return `${name}--density-${props.density}`;
  3584. });
  3585. return {
  3586. densityClasses
  3587. };
  3588. }
  3589. // Types
  3590. const allowedVariants$2 = ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain'];
  3591. function genOverlays(isClickable, name) {
  3592. return createVNode(Fragment, null, [isClickable && createVNode("span", {
  3593. "key": "overlay",
  3594. "class": `${name}__overlay`
  3595. }, null), createVNode("span", {
  3596. "key": "underlay",
  3597. "class": `${name}__underlay`
  3598. }, null)]);
  3599. }
  3600. const makeVariantProps = propsFactory({
  3601. color: String,
  3602. variant: {
  3603. type: String,
  3604. default: 'elevated',
  3605. validator: v => allowedVariants$2.includes(v)
  3606. }
  3607. }, 'variant');
  3608. function useVariant(props) {
  3609. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  3610. const variantClasses = computed(() => {
  3611. const {
  3612. variant
  3613. } = unref(props);
  3614. return `${name}--variant-${variant}`;
  3615. });
  3616. const {
  3617. colorClasses,
  3618. colorStyles
  3619. } = useColor(computed(() => {
  3620. const {
  3621. variant,
  3622. color
  3623. } = unref(props);
  3624. return {
  3625. [['elevated', 'flat'].includes(variant) ? 'background' : 'text']: color
  3626. };
  3627. }));
  3628. return {
  3629. colorClasses,
  3630. colorStyles,
  3631. variantClasses
  3632. };
  3633. }
  3634. const makeVBtnGroupProps = propsFactory({
  3635. divided: Boolean,
  3636. ...makeBorderProps(),
  3637. ...makeComponentProps(),
  3638. ...makeDensityProps(),
  3639. ...makeElevationProps(),
  3640. ...makeRoundedProps(),
  3641. ...makeTagProps(),
  3642. ...makeThemeProps(),
  3643. ...makeVariantProps()
  3644. }, 'VBtnGroup');
  3645. const VBtnGroup = genericComponent()({
  3646. name: 'VBtnGroup',
  3647. props: makeVBtnGroupProps(),
  3648. setup(props, _ref) {
  3649. let {
  3650. slots
  3651. } = _ref;
  3652. const {
  3653. themeClasses
  3654. } = provideTheme(props);
  3655. const {
  3656. densityClasses
  3657. } = useDensity(props);
  3658. const {
  3659. borderClasses
  3660. } = useBorder(props);
  3661. const {
  3662. elevationClasses
  3663. } = useElevation(props);
  3664. const {
  3665. roundedClasses
  3666. } = useRounded(props);
  3667. provideDefaults({
  3668. VBtn: {
  3669. height: 'auto',
  3670. color: toRef(props, 'color'),
  3671. density: toRef(props, 'density'),
  3672. flat: true,
  3673. variant: toRef(props, 'variant')
  3674. }
  3675. });
  3676. useRender(() => {
  3677. return createVNode(props.tag, {
  3678. "class": ['v-btn-group', {
  3679. 'v-btn-group--divided': props.divided
  3680. }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  3681. "style": props.style
  3682. }, slots);
  3683. });
  3684. }
  3685. });
  3686. // Composables
  3687. // Types
  3688. const makeGroupProps = propsFactory({
  3689. modelValue: {
  3690. type: null,
  3691. default: undefined
  3692. },
  3693. multiple: Boolean,
  3694. mandatory: [Boolean, String],
  3695. max: Number,
  3696. selectedClass: String,
  3697. disabled: Boolean
  3698. }, 'group');
  3699. const makeGroupItemProps = propsFactory({
  3700. value: null,
  3701. disabled: Boolean,
  3702. selectedClass: String
  3703. }, 'group-item');
  3704. function useGroupItem(props, injectKey) {
  3705. let required = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
  3706. const vm = getCurrentInstance('useGroupItem');
  3707. if (!vm) {
  3708. throw new Error('[Vuetify] useGroupItem composable must be used inside a component setup function');
  3709. }
  3710. const id = getUid();
  3711. provide(Symbol.for(`${injectKey.description}:id`), id);
  3712. const group = inject$1(injectKey, null);
  3713. if (!group) {
  3714. if (!required) return group;
  3715. throw new Error(`[Vuetify] Could not find useGroup injection with symbol ${injectKey.description}`);
  3716. }
  3717. const value = toRef(props, 'value');
  3718. const disabled = computed(() => !!(group.disabled.value || props.disabled));
  3719. group.register({
  3720. id,
  3721. value,
  3722. disabled
  3723. }, vm);
  3724. onBeforeUnmount(() => {
  3725. group.unregister(id);
  3726. });
  3727. const isSelected = computed(() => {
  3728. return group.isSelected(id);
  3729. });
  3730. const selectedClass = computed(() => isSelected.value && [group.selectedClass.value, props.selectedClass]);
  3731. watch(isSelected, value => {
  3732. vm.emit('group:selected', {
  3733. value
  3734. });
  3735. });
  3736. return {
  3737. id,
  3738. isSelected,
  3739. toggle: () => group.select(id, !isSelected.value),
  3740. select: value => group.select(id, value),
  3741. selectedClass,
  3742. value,
  3743. disabled,
  3744. group
  3745. };
  3746. }
  3747. function useGroup(props, injectKey) {
  3748. let isUnmounted = false;
  3749. const items = reactive([]);
  3750. const selected = useProxiedModel(props, 'modelValue', [], v => {
  3751. if (v == null) return [];
  3752. return getIds(items, wrapInArray(v));
  3753. }, v => {
  3754. const arr = getValues(items, v);
  3755. return props.multiple ? arr : arr[0];
  3756. });
  3757. const groupVm = getCurrentInstance('useGroup');
  3758. function register(item, vm) {
  3759. // Is there a better way to fix this typing?
  3760. const unwrapped = item;
  3761. const key = Symbol.for(`${injectKey.description}:id`);
  3762. const children = findChildrenWithProvide(key, groupVm?.vnode);
  3763. const index = children.indexOf(vm);
  3764. if (index > -1) {
  3765. items.splice(index, 0, unwrapped);
  3766. } else {
  3767. items.push(unwrapped);
  3768. }
  3769. }
  3770. function unregister(id) {
  3771. if (isUnmounted) return;
  3772. // TODO: re-evaluate this line's importance in the future
  3773. // should we only modify the model if mandatory is set.
  3774. // selected.value = selected.value.filter(v => v !== id)
  3775. forceMandatoryValue();
  3776. const index = items.findIndex(item => item.id === id);
  3777. items.splice(index, 1);
  3778. }
  3779. // If mandatory and nothing is selected, then select first non-disabled item
  3780. function forceMandatoryValue() {
  3781. const item = items.find(item => !item.disabled);
  3782. if (item && props.mandatory === 'force' && !selected.value.length) {
  3783. selected.value = [item.id];
  3784. }
  3785. }
  3786. onMounted(() => {
  3787. forceMandatoryValue();
  3788. });
  3789. onBeforeUnmount(() => {
  3790. isUnmounted = true;
  3791. });
  3792. function select(id, value) {
  3793. const item = items.find(item => item.id === id);
  3794. if (value && item?.disabled) return;
  3795. if (props.multiple) {
  3796. const internalValue = selected.value.slice();
  3797. const index = internalValue.findIndex(v => v === id);
  3798. const isSelected = ~index;
  3799. value = value ?? !isSelected;
  3800. // We can't remove value if group is
  3801. // mandatory, value already exists,
  3802. // and it is the only value
  3803. if (isSelected && props.mandatory && internalValue.length <= 1) return;
  3804. // We can't add value if it would
  3805. // cause max limit to be exceeded
  3806. if (!isSelected && props.max != null && internalValue.length + 1 > props.max) return;
  3807. if (index < 0 && value) internalValue.push(id);else if (index >= 0 && !value) internalValue.splice(index, 1);
  3808. selected.value = internalValue;
  3809. } else {
  3810. const isSelected = selected.value.includes(id);
  3811. if (props.mandatory && isSelected) return;
  3812. selected.value = value ?? !isSelected ? [id] : [];
  3813. }
  3814. }
  3815. function step(offset) {
  3816. // getting an offset from selected value obviously won't work with multiple values
  3817. if (props.multiple) consoleWarn('This method is not supported when using "multiple" prop');
  3818. if (!selected.value.length) {
  3819. const item = items.find(item => !item.disabled);
  3820. item && (selected.value = [item.id]);
  3821. } else {
  3822. const currentId = selected.value[0];
  3823. const currentIndex = items.findIndex(i => i.id === currentId);
  3824. let newIndex = (currentIndex + offset) % items.length;
  3825. let newItem = items[newIndex];
  3826. while (newItem.disabled && newIndex !== currentIndex) {
  3827. newIndex = (newIndex + offset) % items.length;
  3828. newItem = items[newIndex];
  3829. }
  3830. if (newItem.disabled) return;
  3831. selected.value = [items[newIndex].id];
  3832. }
  3833. }
  3834. const state = {
  3835. register,
  3836. unregister,
  3837. selected,
  3838. select,
  3839. disabled: toRef(props, 'disabled'),
  3840. prev: () => step(items.length - 1),
  3841. next: () => step(1),
  3842. isSelected: id => selected.value.includes(id),
  3843. selectedClass: computed(() => props.selectedClass),
  3844. items: computed(() => items),
  3845. getItemIndex: value => getItemIndex(items, value)
  3846. };
  3847. provide(injectKey, state);
  3848. return state;
  3849. }
  3850. function getItemIndex(items, value) {
  3851. const ids = getIds(items, [value]);
  3852. if (!ids.length) return -1;
  3853. return items.findIndex(item => item.id === ids[0]);
  3854. }
  3855. function getIds(items, modelValue) {
  3856. const ids = [];
  3857. modelValue.forEach(value => {
  3858. const item = items.find(item => deepEqual(value, item.value));
  3859. const itemByIndex = items[value];
  3860. if (item?.value != null) {
  3861. ids.push(item.id);
  3862. } else if (itemByIndex != null) {
  3863. ids.push(itemByIndex.id);
  3864. }
  3865. });
  3866. return ids;
  3867. }
  3868. function getValues(items, ids) {
  3869. const values = [];
  3870. ids.forEach(id => {
  3871. const itemIndex = items.findIndex(item => item.id === id);
  3872. if (~itemIndex) {
  3873. const item = items[itemIndex];
  3874. values.push(item.value != null ? item.value : itemIndex);
  3875. }
  3876. });
  3877. return values;
  3878. }
  3879. // Types
  3880. const VBtnToggleSymbol = Symbol.for('vuetify:v-btn-toggle');
  3881. const makeVBtnToggleProps = propsFactory({
  3882. ...makeVBtnGroupProps(),
  3883. ...makeGroupProps()
  3884. }, 'VBtnToggle');
  3885. const VBtnToggle = genericComponent()({
  3886. name: 'VBtnToggle',
  3887. props: makeVBtnToggleProps(),
  3888. emits: {
  3889. 'update:modelValue': value => true
  3890. },
  3891. setup(props, _ref) {
  3892. let {
  3893. slots
  3894. } = _ref;
  3895. const {
  3896. isSelected,
  3897. next,
  3898. prev,
  3899. select,
  3900. selected
  3901. } = useGroup(props, VBtnToggleSymbol);
  3902. useRender(() => {
  3903. const [btnGroupProps] = VBtnGroup.filterProps(props);
  3904. return createVNode(VBtnGroup, mergeProps({
  3905. "class": ['v-btn-toggle', props.class]
  3906. }, btnGroupProps, {
  3907. "style": props.style
  3908. }), {
  3909. default: () => [slots.default?.({
  3910. isSelected,
  3911. next,
  3912. prev,
  3913. select,
  3914. selected
  3915. })]
  3916. });
  3917. });
  3918. return {
  3919. next,
  3920. prev,
  3921. select
  3922. };
  3923. }
  3924. });
  3925. // Composables
  3926. // Types
  3927. const aliases = {
  3928. collapse: 'mdi-chevron-up',
  3929. complete: 'mdi-check',
  3930. cancel: 'mdi-close-circle',
  3931. close: 'mdi-close',
  3932. delete: 'mdi-close-circle',
  3933. // delete (e.g. v-chip close)
  3934. clear: 'mdi-close-circle',
  3935. success: 'mdi-check-circle',
  3936. info: 'mdi-information',
  3937. warning: 'mdi-alert-circle',
  3938. error: 'mdi-close-circle',
  3939. prev: 'mdi-chevron-left',
  3940. next: 'mdi-chevron-right',
  3941. checkboxOn: 'mdi-checkbox-marked',
  3942. checkboxOff: 'mdi-checkbox-blank-outline',
  3943. checkboxIndeterminate: 'mdi-minus-box',
  3944. delimiter: 'mdi-circle',
  3945. // for carousel
  3946. sortAsc: 'mdi-arrow-up',
  3947. sortDesc: 'mdi-arrow-down',
  3948. expand: 'mdi-chevron-down',
  3949. menu: 'mdi-menu',
  3950. subgroup: 'mdi-menu-down',
  3951. dropdown: 'mdi-menu-down',
  3952. radioOn: 'mdi-radiobox-marked',
  3953. radioOff: 'mdi-radiobox-blank',
  3954. edit: 'mdi-pencil',
  3955. ratingEmpty: 'mdi-star-outline',
  3956. ratingFull: 'mdi-star',
  3957. ratingHalf: 'mdi-star-half-full',
  3958. loading: 'mdi-cached',
  3959. first: 'mdi-page-first',
  3960. last: 'mdi-page-last',
  3961. unfold: 'mdi-unfold-more-horizontal',
  3962. file: 'mdi-paperclip',
  3963. plus: 'mdi-plus',
  3964. minus: 'mdi-minus',
  3965. calendar: 'mdi-calendar'
  3966. };
  3967. const mdi = {
  3968. // Not using mergeProps here, functional components merge props by default (?)
  3969. component: props => h(VClassIcon, {
  3970. ...props,
  3971. class: 'mdi'
  3972. })
  3973. };
  3974. // Types
  3975. const IconValue = [String, Function, Object, Array];
  3976. const IconSymbol = Symbol.for('vuetify:icons');
  3977. const makeIconProps = propsFactory({
  3978. icon: {
  3979. type: IconValue
  3980. },
  3981. // Could not remove this and use makeTagProps, types complained because it is not required
  3982. tag: {
  3983. type: String,
  3984. required: true
  3985. }
  3986. }, 'icon');
  3987. const VComponentIcon = genericComponent()({
  3988. name: 'VComponentIcon',
  3989. props: makeIconProps(),
  3990. setup(props, _ref) {
  3991. let {
  3992. slots
  3993. } = _ref;
  3994. return () => {
  3995. const Icon = props.icon;
  3996. return createVNode(props.tag, null, {
  3997. default: () => [props.icon ? createVNode(Icon, null, null) : slots.default?.()]
  3998. });
  3999. };
  4000. }
  4001. });
  4002. const VSvgIcon = defineComponent({
  4003. name: 'VSvgIcon',
  4004. inheritAttrs: false,
  4005. props: makeIconProps(),
  4006. setup(props, _ref2) {
  4007. let {
  4008. attrs
  4009. } = _ref2;
  4010. return () => {
  4011. return createVNode(props.tag, mergeProps(attrs, {
  4012. "style": null
  4013. }), {
  4014. default: () => [createVNode("svg", {
  4015. "class": "v-icon__svg",
  4016. "xmlns": "http://www.w3.org/2000/svg",
  4017. "viewBox": "0 0 24 24",
  4018. "role": "img",
  4019. "aria-hidden": "true"
  4020. }, [Array.isArray(props.icon) ? props.icon.map(path => Array.isArray(path) ? createVNode("path", {
  4021. "d": path[0],
  4022. "fill-opacity": path[1]
  4023. }, null) : createVNode("path", {
  4024. "d": path
  4025. }, null)) : createVNode("path", {
  4026. "d": props.icon
  4027. }, null)])]
  4028. });
  4029. };
  4030. }
  4031. });
  4032. const VLigatureIcon = defineComponent({
  4033. name: 'VLigatureIcon',
  4034. props: makeIconProps(),
  4035. setup(props) {
  4036. return () => {
  4037. return createVNode(props.tag, null, {
  4038. default: () => [props.icon]
  4039. });
  4040. };
  4041. }
  4042. });
  4043. const VClassIcon = defineComponent({
  4044. name: 'VClassIcon',
  4045. props: makeIconProps(),
  4046. setup(props) {
  4047. return () => {
  4048. return createVNode(props.tag, {
  4049. "class": props.icon
  4050. }, null);
  4051. };
  4052. }
  4053. });
  4054. const defaultSets = {
  4055. svg: {
  4056. component: VSvgIcon
  4057. },
  4058. class: {
  4059. component: VClassIcon
  4060. }
  4061. };
  4062. // Composables
  4063. function createIcons(options) {
  4064. return mergeDeep({
  4065. defaultSet: 'mdi',
  4066. sets: {
  4067. ...defaultSets,
  4068. mdi
  4069. },
  4070. aliases: {
  4071. ...aliases,
  4072. /* eslint-disable max-len */
  4073. 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]],
  4074. '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'
  4075. /* eslint-enable max-len */
  4076. }
  4077. }, options);
  4078. }
  4079. const useIcon = props => {
  4080. const icons = inject$1(IconSymbol);
  4081. if (!icons) throw new Error('Missing Vuetify Icons provide!');
  4082. const iconData = computed(() => {
  4083. const iconAlias = unref(props);
  4084. if (!iconAlias) return {
  4085. component: VComponentIcon
  4086. };
  4087. let icon = iconAlias;
  4088. if (typeof icon === 'string') {
  4089. icon = icon.trim();
  4090. if (icon.startsWith('$')) {
  4091. icon = icons.aliases?.[icon.slice(1)];
  4092. }
  4093. }
  4094. if (!icon) throw new Error(`Could not find aliased icon "${iconAlias}"`);
  4095. if (Array.isArray(icon)) {
  4096. return {
  4097. component: VSvgIcon,
  4098. icon
  4099. };
  4100. } else if (typeof icon !== 'string') {
  4101. return {
  4102. component: VComponentIcon,
  4103. icon
  4104. };
  4105. }
  4106. const iconSetName = Object.keys(icons.sets).find(setName => typeof icon === 'string' && icon.startsWith(`${setName}:`));
  4107. const iconName = iconSetName ? icon.slice(iconSetName.length + 1) : icon;
  4108. const iconSet = icons.sets[iconSetName ?? icons.defaultSet];
  4109. return {
  4110. component: iconSet.component,
  4111. icon: iconName
  4112. };
  4113. });
  4114. return {
  4115. iconData
  4116. };
  4117. };
  4118. // Utilities
  4119. // Types
  4120. const predefinedSizes = ['x-small', 'small', 'default', 'large', 'x-large'];
  4121. // Composables
  4122. const makeSizeProps = propsFactory({
  4123. size: {
  4124. type: [String, Number],
  4125. default: 'default'
  4126. }
  4127. }, 'size');
  4128. function useSize(props) {
  4129. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  4130. return destructComputed(() => {
  4131. let sizeClasses;
  4132. let sizeStyles;
  4133. if (includes(predefinedSizes, props.size)) {
  4134. sizeClasses = `${name}--size-${props.size}`;
  4135. } else if (props.size) {
  4136. sizeStyles = {
  4137. width: convertToUnit(props.size),
  4138. height: convertToUnit(props.size)
  4139. };
  4140. }
  4141. return {
  4142. sizeClasses,
  4143. sizeStyles
  4144. };
  4145. });
  4146. }
  4147. const makeVIconProps = propsFactory({
  4148. color: String,
  4149. start: Boolean,
  4150. end: Boolean,
  4151. icon: IconValue,
  4152. ...makeComponentProps(),
  4153. ...makeSizeProps(),
  4154. ...makeTagProps({
  4155. tag: 'i'
  4156. }),
  4157. ...makeThemeProps()
  4158. }, 'VIcon');
  4159. const VIcon = genericComponent()({
  4160. name: 'VIcon',
  4161. props: makeVIconProps(),
  4162. setup(props, _ref) {
  4163. let {
  4164. attrs,
  4165. slots
  4166. } = _ref;
  4167. const slotIcon = ref();
  4168. const {
  4169. themeClasses
  4170. } = provideTheme(props);
  4171. const {
  4172. iconData
  4173. } = useIcon(computed(() => slotIcon.value || props.icon));
  4174. const {
  4175. sizeClasses
  4176. } = useSize(props);
  4177. const {
  4178. textColorClasses,
  4179. textColorStyles
  4180. } = useTextColor(toRef(props, 'color'));
  4181. useRender(() => {
  4182. const slotValue = slots.default?.();
  4183. if (slotValue) {
  4184. slotIcon.value = flattenFragments(slotValue).filter(node => node.type === Text && node.children && typeof node.children === 'string')[0]?.children;
  4185. }
  4186. return createVNode(iconData.value.component, {
  4187. "tag": props.tag,
  4188. "icon": iconData.value.icon,
  4189. "class": ['v-icon', 'notranslate', themeClasses.value, sizeClasses.value, textColorClasses.value, {
  4190. 'v-icon--clickable': !!attrs.onClick,
  4191. 'v-icon--start': props.start,
  4192. 'v-icon--end': props.end
  4193. }, props.class],
  4194. "style": [!sizeClasses.value ? {
  4195. fontSize: convertToUnit(props.size),
  4196. height: convertToUnit(props.size),
  4197. width: convertToUnit(props.size)
  4198. } : undefined, textColorStyles.value, props.style],
  4199. "role": attrs.onClick ? 'button' : undefined,
  4200. "aria-hidden": !attrs.onClick
  4201. }, {
  4202. default: () => [slotValue]
  4203. });
  4204. });
  4205. return {};
  4206. }
  4207. });
  4208. // Utilities
  4209. function useIntersectionObserver(callback, options) {
  4210. const intersectionRef = ref();
  4211. const isIntersecting = shallowRef(false);
  4212. if (SUPPORTS_INTERSECTION) {
  4213. const observer = new IntersectionObserver(entries => {
  4214. callback?.(entries, observer);
  4215. isIntersecting.value = !!entries.find(entry => entry.isIntersecting);
  4216. }, options);
  4217. onBeforeUnmount(() => {
  4218. observer.disconnect();
  4219. });
  4220. watch(intersectionRef, (newValue, oldValue) => {
  4221. if (oldValue) {
  4222. observer.unobserve(oldValue);
  4223. isIntersecting.value = false;
  4224. }
  4225. if (newValue) observer.observe(newValue);
  4226. }, {
  4227. flush: 'post'
  4228. });
  4229. }
  4230. return {
  4231. intersectionRef,
  4232. isIntersecting
  4233. };
  4234. }
  4235. // Types
  4236. const makeVProgressCircularProps = propsFactory({
  4237. bgColor: String,
  4238. color: String,
  4239. indeterminate: [Boolean, String],
  4240. modelValue: {
  4241. type: [Number, String],
  4242. default: 0
  4243. },
  4244. rotate: {
  4245. type: [Number, String],
  4246. default: 0
  4247. },
  4248. width: {
  4249. type: [Number, String],
  4250. default: 4
  4251. },
  4252. ...makeComponentProps(),
  4253. ...makeSizeProps(),
  4254. ...makeTagProps({
  4255. tag: 'div'
  4256. }),
  4257. ...makeThemeProps()
  4258. }, 'VProgressCircular');
  4259. const VProgressCircular = genericComponent()({
  4260. name: 'VProgressCircular',
  4261. props: makeVProgressCircularProps(),
  4262. setup(props, _ref) {
  4263. let {
  4264. slots
  4265. } = _ref;
  4266. const MAGIC_RADIUS_CONSTANT = 20;
  4267. const CIRCUMFERENCE = 2 * Math.PI * MAGIC_RADIUS_CONSTANT;
  4268. const root = ref();
  4269. const {
  4270. themeClasses
  4271. } = provideTheme(props);
  4272. const {
  4273. sizeClasses,
  4274. sizeStyles
  4275. } = useSize(props);
  4276. const {
  4277. textColorClasses,
  4278. textColorStyles
  4279. } = useTextColor(toRef(props, 'color'));
  4280. const {
  4281. textColorClasses: underlayColorClasses,
  4282. textColorStyles: underlayColorStyles
  4283. } = useTextColor(toRef(props, 'bgColor'));
  4284. const {
  4285. intersectionRef,
  4286. isIntersecting
  4287. } = useIntersectionObserver();
  4288. const {
  4289. resizeRef,
  4290. contentRect
  4291. } = useResizeObserver();
  4292. const normalizedValue = computed(() => Math.max(0, Math.min(100, parseFloat(props.modelValue))));
  4293. const width = computed(() => Number(props.width));
  4294. const size = computed(() => {
  4295. // Get size from element if size prop value is small, large etc
  4296. return sizeStyles.value ? Number(props.size) : contentRect.value ? contentRect.value.width : Math.max(width.value, 32);
  4297. });
  4298. const diameter = computed(() => MAGIC_RADIUS_CONSTANT / (1 - width.value / size.value) * 2);
  4299. const strokeWidth = computed(() => width.value / size.value * diameter.value);
  4300. const strokeDashOffset = computed(() => convertToUnit((100 - normalizedValue.value) / 100 * CIRCUMFERENCE));
  4301. watchEffect(() => {
  4302. intersectionRef.value = root.value;
  4303. resizeRef.value = root.value;
  4304. });
  4305. useRender(() => createVNode(props.tag, {
  4306. "ref": root,
  4307. "class": ['v-progress-circular', {
  4308. 'v-progress-circular--indeterminate': !!props.indeterminate,
  4309. 'v-progress-circular--visible': isIntersecting.value,
  4310. 'v-progress-circular--disable-shrink': props.indeterminate === 'disable-shrink'
  4311. }, themeClasses.value, sizeClasses.value, textColorClasses.value, props.class],
  4312. "style": [sizeStyles.value, textColorStyles.value, props.style],
  4313. "role": "progressbar",
  4314. "aria-valuemin": "0",
  4315. "aria-valuemax": "100",
  4316. "aria-valuenow": props.indeterminate ? undefined : normalizedValue.value
  4317. }, {
  4318. default: () => [createVNode("svg", {
  4319. "style": {
  4320. transform: `rotate(calc(-90deg + ${Number(props.rotate)}deg))`
  4321. },
  4322. "xmlns": "http://www.w3.org/2000/svg",
  4323. "viewBox": `0 0 ${diameter.value} ${diameter.value}`
  4324. }, [createVNode("circle", {
  4325. "class": ['v-progress-circular__underlay', underlayColorClasses.value],
  4326. "style": underlayColorStyles.value,
  4327. "fill": "transparent",
  4328. "cx": "50%",
  4329. "cy": "50%",
  4330. "r": MAGIC_RADIUS_CONSTANT,
  4331. "stroke-width": strokeWidth.value,
  4332. "stroke-dasharray": CIRCUMFERENCE,
  4333. "stroke-dashoffset": 0
  4334. }, null), createVNode("circle", {
  4335. "class": "v-progress-circular__overlay",
  4336. "fill": "transparent",
  4337. "cx": "50%",
  4338. "cy": "50%",
  4339. "r": MAGIC_RADIUS_CONSTANT,
  4340. "stroke-width": strokeWidth.value,
  4341. "stroke-dasharray": CIRCUMFERENCE,
  4342. "stroke-dashoffset": strokeDashOffset.value
  4343. }, null)]), slots.default && createVNode("div", {
  4344. "class": "v-progress-circular__content"
  4345. }, [slots.default({
  4346. value: normalizedValue.value
  4347. })])]
  4348. }));
  4349. return {};
  4350. }
  4351. });
  4352. // Composables
  4353. // Types
  4354. const oppositeMap = {
  4355. center: 'center',
  4356. top: 'bottom',
  4357. bottom: 'top',
  4358. left: 'right',
  4359. right: 'left'
  4360. };
  4361. const makeLocationProps = propsFactory({
  4362. location: String
  4363. }, 'location');
  4364. function useLocation(props) {
  4365. let opposite = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  4366. let offset = arguments.length > 2 ? arguments[2] : undefined;
  4367. const {
  4368. isRtl
  4369. } = useRtl();
  4370. const locationStyles = computed(() => {
  4371. if (!props.location) return {};
  4372. const {
  4373. side,
  4374. align
  4375. } = parseAnchor(props.location.split(' ').length > 1 ? props.location : `${props.location} center`, isRtl.value);
  4376. function getOffset(side) {
  4377. return offset ? offset(side) : 0;
  4378. }
  4379. const styles = {};
  4380. if (side !== 'center') {
  4381. if (opposite) styles[oppositeMap[side]] = `calc(100% - ${getOffset(side)}px)`;else styles[side] = 0;
  4382. }
  4383. if (align !== 'center') {
  4384. if (opposite) styles[oppositeMap[align]] = `calc(100% - ${getOffset(align)}px)`;else styles[align] = 0;
  4385. } else {
  4386. if (side === 'center') styles.top = styles.left = '50%';else {
  4387. styles[{
  4388. top: 'left',
  4389. bottom: 'left',
  4390. left: 'top',
  4391. right: 'top'
  4392. }[side]] = '50%';
  4393. }
  4394. styles.transform = {
  4395. top: 'translateX(-50%)',
  4396. bottom: 'translateX(-50%)',
  4397. left: 'translateY(-50%)',
  4398. right: 'translateY(-50%)',
  4399. center: 'translate(-50%, -50%)'
  4400. }[side];
  4401. }
  4402. return styles;
  4403. });
  4404. return {
  4405. locationStyles
  4406. };
  4407. }
  4408. const makeVProgressLinearProps = propsFactory({
  4409. absolute: Boolean,
  4410. active: {
  4411. type: Boolean,
  4412. default: true
  4413. },
  4414. bgColor: String,
  4415. bgOpacity: [Number, String],
  4416. bufferValue: {
  4417. type: [Number, String],
  4418. default: 0
  4419. },
  4420. clickable: Boolean,
  4421. color: String,
  4422. height: {
  4423. type: [Number, String],
  4424. default: 4
  4425. },
  4426. indeterminate: Boolean,
  4427. max: {
  4428. type: [Number, String],
  4429. default: 100
  4430. },
  4431. modelValue: {
  4432. type: [Number, String],
  4433. default: 0
  4434. },
  4435. reverse: Boolean,
  4436. stream: Boolean,
  4437. striped: Boolean,
  4438. roundedBar: Boolean,
  4439. ...makeComponentProps(),
  4440. ...makeLocationProps({
  4441. location: 'top'
  4442. }),
  4443. ...makeRoundedProps(),
  4444. ...makeTagProps(),
  4445. ...makeThemeProps()
  4446. }, 'VProgressLinear');
  4447. const VProgressLinear = genericComponent()({
  4448. name: 'VProgressLinear',
  4449. props: makeVProgressLinearProps(),
  4450. emits: {
  4451. 'update:modelValue': value => true
  4452. },
  4453. setup(props, _ref) {
  4454. let {
  4455. slots
  4456. } = _ref;
  4457. const progress = useProxiedModel(props, 'modelValue');
  4458. const {
  4459. isRtl,
  4460. rtlClasses
  4461. } = useRtl();
  4462. const {
  4463. themeClasses
  4464. } = provideTheme(props);
  4465. const {
  4466. locationStyles
  4467. } = useLocation(props);
  4468. const {
  4469. textColorClasses,
  4470. textColorStyles
  4471. } = useTextColor(props, 'color');
  4472. const {
  4473. backgroundColorClasses,
  4474. backgroundColorStyles
  4475. } = useBackgroundColor(computed(() => props.bgColor || props.color));
  4476. const {
  4477. backgroundColorClasses: barColorClasses,
  4478. backgroundColorStyles: barColorStyles
  4479. } = useBackgroundColor(props, 'color');
  4480. const {
  4481. roundedClasses
  4482. } = useRounded(props);
  4483. const {
  4484. intersectionRef,
  4485. isIntersecting
  4486. } = useIntersectionObserver();
  4487. const max = computed(() => parseInt(props.max, 10));
  4488. const height = computed(() => parseInt(props.height, 10));
  4489. const normalizedBuffer = computed(() => parseFloat(props.bufferValue) / max.value * 100);
  4490. const normalizedValue = computed(() => parseFloat(progress.value) / max.value * 100);
  4491. const isReversed = computed(() => isRtl.value !== props.reverse);
  4492. const transition = computed(() => props.indeterminate ? 'fade-transition' : 'slide-x-transition');
  4493. const opacity = computed(() => {
  4494. return props.bgOpacity == null ? props.bgOpacity : parseFloat(props.bgOpacity);
  4495. });
  4496. function handleClick(e) {
  4497. if (!intersectionRef.value) return;
  4498. const {
  4499. left,
  4500. right,
  4501. width
  4502. } = intersectionRef.value.getBoundingClientRect();
  4503. const value = isReversed.value ? width - e.clientX + (right - width) : e.clientX - left;
  4504. progress.value = Math.round(value / width * max.value);
  4505. }
  4506. useRender(() => createVNode(props.tag, {
  4507. "ref": intersectionRef,
  4508. "class": ['v-progress-linear', {
  4509. 'v-progress-linear--absolute': props.absolute,
  4510. 'v-progress-linear--active': props.active && isIntersecting.value,
  4511. 'v-progress-linear--reverse': isReversed.value,
  4512. 'v-progress-linear--rounded': props.rounded,
  4513. 'v-progress-linear--rounded-bar': props.roundedBar,
  4514. 'v-progress-linear--striped': props.striped
  4515. }, roundedClasses.value, themeClasses.value, rtlClasses.value, props.class],
  4516. "style": [{
  4517. bottom: props.location === 'bottom' ? 0 : undefined,
  4518. top: props.location === 'top' ? 0 : undefined,
  4519. height: props.active ? convertToUnit(height.value) : 0,
  4520. '--v-progress-linear-height': convertToUnit(height.value),
  4521. ...locationStyles.value
  4522. }, props.style],
  4523. "role": "progressbar",
  4524. "aria-hidden": props.active ? 'false' : 'true',
  4525. "aria-valuemin": "0",
  4526. "aria-valuemax": props.max,
  4527. "aria-valuenow": props.indeterminate ? undefined : normalizedValue.value,
  4528. "onClick": props.clickable && handleClick
  4529. }, {
  4530. default: () => [props.stream && createVNode("div", {
  4531. "key": "stream",
  4532. "class": ['v-progress-linear__stream', textColorClasses.value],
  4533. "style": {
  4534. ...textColorStyles.value,
  4535. [isReversed.value ? 'left' : 'right']: convertToUnit(-height.value),
  4536. borderTop: `${convertToUnit(height.value / 2)} dotted`,
  4537. opacity: opacity.value,
  4538. top: `calc(50% - ${convertToUnit(height.value / 4)})`,
  4539. width: convertToUnit(100 - normalizedBuffer.value, '%'),
  4540. '--v-progress-linear-stream-to': convertToUnit(height.value * (isReversed.value ? 1 : -1))
  4541. }
  4542. }, null), createVNode("div", {
  4543. "class": ['v-progress-linear__background', backgroundColorClasses.value],
  4544. "style": [backgroundColorStyles.value, {
  4545. opacity: opacity.value,
  4546. width: convertToUnit(!props.stream ? 100 : normalizedBuffer.value, '%')
  4547. }]
  4548. }, null), createVNode(Transition, {
  4549. "name": transition.value
  4550. }, {
  4551. default: () => [!props.indeterminate ? createVNode("div", {
  4552. "class": ['v-progress-linear__determinate', barColorClasses.value],
  4553. "style": [barColorStyles.value, {
  4554. width: convertToUnit(normalizedValue.value, '%')
  4555. }]
  4556. }, null) : createVNode("div", {
  4557. "class": "v-progress-linear__indeterminate"
  4558. }, [['long', 'short'].map(bar => createVNode("div", {
  4559. "key": bar,
  4560. "class": ['v-progress-linear__indeterminate', bar, barColorClasses.value],
  4561. "style": barColorStyles.value
  4562. }, null))])]
  4563. }), slots.default && createVNode("div", {
  4564. "class": "v-progress-linear__content"
  4565. }, [slots.default({
  4566. value: normalizedValue.value,
  4567. buffer: normalizedBuffer.value
  4568. })])]
  4569. }));
  4570. return {};
  4571. }
  4572. });
  4573. // Types
  4574. // Composables
  4575. const makeLoaderProps = propsFactory({
  4576. loading: [Boolean, String]
  4577. }, 'loader');
  4578. function useLoader(props) {
  4579. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  4580. const loaderClasses = computed(() => ({
  4581. [`${name}--loading`]: props.loading
  4582. }));
  4583. return {
  4584. loaderClasses
  4585. };
  4586. }
  4587. function LoaderSlot(props, _ref) {
  4588. let {
  4589. slots
  4590. } = _ref;
  4591. return createVNode("div", {
  4592. "class": `${props.name}__loader`
  4593. }, [slots.default?.({
  4594. color: props.color,
  4595. isActive: props.active
  4596. }) || createVNode(VProgressLinear, {
  4597. "active": props.active,
  4598. "color": props.color,
  4599. "height": "2",
  4600. "indeterminate": true
  4601. }, null)]);
  4602. }
  4603. // Utilities
  4604. // Types
  4605. const positionValues = ['static', 'relative', 'fixed', 'absolute', 'sticky'];
  4606. // Composables
  4607. const makePositionProps = propsFactory({
  4608. position: {
  4609. type: String,
  4610. validator: /* istanbul ignore next */v => positionValues.includes(v)
  4611. }
  4612. }, 'position');
  4613. function usePosition(props) {
  4614. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  4615. const positionClasses = computed(() => {
  4616. return props.position ? `${name}--${props.position}` : undefined;
  4617. });
  4618. return {
  4619. positionClasses
  4620. };
  4621. }
  4622. // Utilities
  4623. function useRouter() {
  4624. return getCurrentInstance('useRouter')?.proxy?.$router;
  4625. }
  4626. function useLink(props, attrs) {
  4627. const RouterLink = resolveDynamicComponent('RouterLink');
  4628. const isLink = computed(() => !!(props.href || props.to));
  4629. const isClickable = computed(() => {
  4630. return isLink?.value || hasEvent(attrs, 'click') || hasEvent(props, 'click');
  4631. });
  4632. if (typeof RouterLink === 'string') {
  4633. return {
  4634. isLink,
  4635. isClickable,
  4636. href: toRef(props, 'href')
  4637. };
  4638. }
  4639. const link = props.to ? RouterLink.useLink(props) : undefined;
  4640. return {
  4641. isLink,
  4642. isClickable,
  4643. route: link?.route,
  4644. navigate: link?.navigate,
  4645. isActive: link && computed(() => props.exact ? link.isExactActive?.value : link.isActive?.value),
  4646. href: computed(() => props.to ? link?.route.value.href : props.href)
  4647. };
  4648. }
  4649. const makeRouterProps = propsFactory({
  4650. href: String,
  4651. replace: Boolean,
  4652. to: [String, Object],
  4653. exact: Boolean
  4654. }, 'router');
  4655. let inTransition = false;
  4656. function useBackButton(router, cb) {
  4657. let popped = false;
  4658. let removeBefore;
  4659. let removeAfter;
  4660. if (IN_BROWSER) {
  4661. nextTick(() => {
  4662. window.addEventListener('popstate', onPopstate);
  4663. removeBefore = router?.beforeEach((to, from, next) => {
  4664. if (!inTransition) {
  4665. setTimeout(() => popped ? cb(next) : next());
  4666. } else {
  4667. popped ? cb(next) : next();
  4668. }
  4669. inTransition = true;
  4670. });
  4671. removeAfter = router?.afterEach(() => {
  4672. inTransition = false;
  4673. });
  4674. });
  4675. onScopeDispose(() => {
  4676. window.removeEventListener('popstate', onPopstate);
  4677. removeBefore?.();
  4678. removeAfter?.();
  4679. });
  4680. }
  4681. function onPopstate(e) {
  4682. if (e.state?.replaced) return;
  4683. popped = true;
  4684. setTimeout(() => popped = false);
  4685. }
  4686. }
  4687. // Utilities
  4688. // Types
  4689. function useSelectLink(link, select) {
  4690. watch(() => link.isActive?.value, isActive => {
  4691. if (link.isLink.value && isActive && select) {
  4692. nextTick(() => {
  4693. select(true);
  4694. });
  4695. }
  4696. }, {
  4697. immediate: true
  4698. });
  4699. }
  4700. // Styles
  4701. // Types
  4702. const stopSymbol = Symbol('rippleStop');
  4703. const DELAY_RIPPLE = 80;
  4704. function transform(el, value) {
  4705. el.style.transform = value;
  4706. el.style.webkitTransform = value;
  4707. }
  4708. function isTouchEvent(e) {
  4709. return e.constructor.name === 'TouchEvent';
  4710. }
  4711. function isKeyboardEvent(e) {
  4712. return e.constructor.name === 'KeyboardEvent';
  4713. }
  4714. const calculate = function (e, el) {
  4715. let value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  4716. let localX = 0;
  4717. let localY = 0;
  4718. if (!isKeyboardEvent(e)) {
  4719. const offset = el.getBoundingClientRect();
  4720. const target = isTouchEvent(e) ? e.touches[e.touches.length - 1] : e;
  4721. localX = target.clientX - offset.left;
  4722. localY = target.clientY - offset.top;
  4723. }
  4724. let radius = 0;
  4725. let scale = 0.3;
  4726. if (el._ripple?.circle) {
  4727. scale = 0.15;
  4728. radius = el.clientWidth / 2;
  4729. radius = value.center ? radius : radius + Math.sqrt((localX - radius) ** 2 + (localY - radius) ** 2) / 4;
  4730. } else {
  4731. radius = Math.sqrt(el.clientWidth ** 2 + el.clientHeight ** 2) / 2;
  4732. }
  4733. const centerX = `${(el.clientWidth - radius * 2) / 2}px`;
  4734. const centerY = `${(el.clientHeight - radius * 2) / 2}px`;
  4735. const x = value.center ? centerX : `${localX - radius}px`;
  4736. const y = value.center ? centerY : `${localY - radius}px`;
  4737. return {
  4738. radius,
  4739. scale,
  4740. x,
  4741. y,
  4742. centerX,
  4743. centerY
  4744. };
  4745. };
  4746. const ripples = {
  4747. /* eslint-disable max-statements */
  4748. show(e, el) {
  4749. let value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  4750. if (!el?._ripple?.enabled) {
  4751. return;
  4752. }
  4753. const container = document.createElement('span');
  4754. const animation = document.createElement('span');
  4755. container.appendChild(animation);
  4756. container.className = 'v-ripple__container';
  4757. if (value.class) {
  4758. container.className += ` ${value.class}`;
  4759. }
  4760. const {
  4761. radius,
  4762. scale,
  4763. x,
  4764. y,
  4765. centerX,
  4766. centerY
  4767. } = calculate(e, el, value);
  4768. const size = `${radius * 2}px`;
  4769. animation.className = 'v-ripple__animation';
  4770. animation.style.width = size;
  4771. animation.style.height = size;
  4772. el.appendChild(container);
  4773. const computed = window.getComputedStyle(el);
  4774. if (computed && computed.position === 'static') {
  4775. el.style.position = 'relative';
  4776. el.dataset.previousPosition = 'static';
  4777. }
  4778. animation.classList.add('v-ripple__animation--enter');
  4779. animation.classList.add('v-ripple__animation--visible');
  4780. transform(animation, `translate(${x}, ${y}) scale3d(${scale},${scale},${scale})`);
  4781. animation.dataset.activated = String(performance.now());
  4782. setTimeout(() => {
  4783. animation.classList.remove('v-ripple__animation--enter');
  4784. animation.classList.add('v-ripple__animation--in');
  4785. transform(animation, `translate(${centerX}, ${centerY}) scale3d(1,1,1)`);
  4786. }, 0);
  4787. },
  4788. hide(el) {
  4789. if (!el?._ripple?.enabled) return;
  4790. const ripples = el.getElementsByClassName('v-ripple__animation');
  4791. if (ripples.length === 0) return;
  4792. const animation = ripples[ripples.length - 1];
  4793. if (animation.dataset.isHiding) return;else animation.dataset.isHiding = 'true';
  4794. const diff = performance.now() - Number(animation.dataset.activated);
  4795. const delay = Math.max(250 - diff, 0);
  4796. setTimeout(() => {
  4797. animation.classList.remove('v-ripple__animation--in');
  4798. animation.classList.add('v-ripple__animation--out');
  4799. setTimeout(() => {
  4800. const ripples = el.getElementsByClassName('v-ripple__animation');
  4801. if (ripples.length === 1 && el.dataset.previousPosition) {
  4802. el.style.position = el.dataset.previousPosition;
  4803. delete el.dataset.previousPosition;
  4804. }
  4805. if (animation.parentNode?.parentNode === el) el.removeChild(animation.parentNode);
  4806. }, 300);
  4807. }, delay);
  4808. }
  4809. };
  4810. function isRippleEnabled(value) {
  4811. return typeof value === 'undefined' || !!value;
  4812. }
  4813. function rippleShow(e) {
  4814. const value = {};
  4815. const element = e.currentTarget;
  4816. if (!element?._ripple || element._ripple.touched || e[stopSymbol]) return;
  4817. // Don't allow the event to trigger ripples on any other elements
  4818. e[stopSymbol] = true;
  4819. if (isTouchEvent(e)) {
  4820. element._ripple.touched = true;
  4821. element._ripple.isTouch = true;
  4822. } else {
  4823. // It's possible for touch events to fire
  4824. // as mouse events on Android/iOS, this
  4825. // will skip the event call if it has
  4826. // already been registered as touch
  4827. if (element._ripple.isTouch) return;
  4828. }
  4829. value.center = element._ripple.centered || isKeyboardEvent(e);
  4830. if (element._ripple.class) {
  4831. value.class = element._ripple.class;
  4832. }
  4833. if (isTouchEvent(e)) {
  4834. // already queued that shows or hides the ripple
  4835. if (element._ripple.showTimerCommit) return;
  4836. element._ripple.showTimerCommit = () => {
  4837. ripples.show(e, element, value);
  4838. };
  4839. element._ripple.showTimer = window.setTimeout(() => {
  4840. if (element?._ripple?.showTimerCommit) {
  4841. element._ripple.showTimerCommit();
  4842. element._ripple.showTimerCommit = null;
  4843. }
  4844. }, DELAY_RIPPLE);
  4845. } else {
  4846. ripples.show(e, element, value);
  4847. }
  4848. }
  4849. function rippleStop(e) {
  4850. e[stopSymbol] = true;
  4851. }
  4852. function rippleHide(e) {
  4853. const element = e.currentTarget;
  4854. if (!element?._ripple) return;
  4855. window.clearTimeout(element._ripple.showTimer);
  4856. // The touch interaction occurs before the show timer is triggered.
  4857. // We still want to show ripple effect.
  4858. if (e.type === 'touchend' && element._ripple.showTimerCommit) {
  4859. element._ripple.showTimerCommit();
  4860. element._ripple.showTimerCommit = null;
  4861. // re-queue ripple hiding
  4862. element._ripple.showTimer = window.setTimeout(() => {
  4863. rippleHide(e);
  4864. });
  4865. return;
  4866. }
  4867. window.setTimeout(() => {
  4868. if (element._ripple) {
  4869. element._ripple.touched = false;
  4870. }
  4871. });
  4872. ripples.hide(element);
  4873. }
  4874. function rippleCancelShow(e) {
  4875. const element = e.currentTarget;
  4876. if (!element?._ripple) return;
  4877. if (element._ripple.showTimerCommit) {
  4878. element._ripple.showTimerCommit = null;
  4879. }
  4880. window.clearTimeout(element._ripple.showTimer);
  4881. }
  4882. let keyboardRipple = false;
  4883. function keyboardRippleShow(e) {
  4884. if (!keyboardRipple && (e.keyCode === keyCodes.enter || e.keyCode === keyCodes.space)) {
  4885. keyboardRipple = true;
  4886. rippleShow(e);
  4887. }
  4888. }
  4889. function keyboardRippleHide(e) {
  4890. keyboardRipple = false;
  4891. rippleHide(e);
  4892. }
  4893. function focusRippleHide(e) {
  4894. if (keyboardRipple) {
  4895. keyboardRipple = false;
  4896. rippleHide(e);
  4897. }
  4898. }
  4899. function updateRipple(el, binding, wasEnabled) {
  4900. const {
  4901. value,
  4902. modifiers
  4903. } = binding;
  4904. const enabled = isRippleEnabled(value);
  4905. if (!enabled) {
  4906. ripples.hide(el);
  4907. }
  4908. el._ripple = el._ripple ?? {};
  4909. el._ripple.enabled = enabled;
  4910. el._ripple.centered = modifiers.center;
  4911. el._ripple.circle = modifiers.circle;
  4912. if (isObject(value) && value.class) {
  4913. el._ripple.class = value.class;
  4914. }
  4915. if (enabled && !wasEnabled) {
  4916. if (modifiers.stop) {
  4917. el.addEventListener('touchstart', rippleStop, {
  4918. passive: true
  4919. });
  4920. el.addEventListener('mousedown', rippleStop);
  4921. return;
  4922. }
  4923. el.addEventListener('touchstart', rippleShow, {
  4924. passive: true
  4925. });
  4926. el.addEventListener('touchend', rippleHide, {
  4927. passive: true
  4928. });
  4929. el.addEventListener('touchmove', rippleCancelShow, {
  4930. passive: true
  4931. });
  4932. el.addEventListener('touchcancel', rippleHide);
  4933. el.addEventListener('mousedown', rippleShow);
  4934. el.addEventListener('mouseup', rippleHide);
  4935. el.addEventListener('mouseleave', rippleHide);
  4936. el.addEventListener('keydown', keyboardRippleShow);
  4937. el.addEventListener('keyup', keyboardRippleHide);
  4938. el.addEventListener('blur', focusRippleHide);
  4939. // Anchor tags can be dragged, causes other hides to fail - #1537
  4940. el.addEventListener('dragstart', rippleHide, {
  4941. passive: true
  4942. });
  4943. } else if (!enabled && wasEnabled) {
  4944. removeListeners(el);
  4945. }
  4946. }
  4947. function removeListeners(el) {
  4948. el.removeEventListener('mousedown', rippleShow);
  4949. el.removeEventListener('touchstart', rippleShow);
  4950. el.removeEventListener('touchend', rippleHide);
  4951. el.removeEventListener('touchmove', rippleCancelShow);
  4952. el.removeEventListener('touchcancel', rippleHide);
  4953. el.removeEventListener('mouseup', rippleHide);
  4954. el.removeEventListener('mouseleave', rippleHide);
  4955. el.removeEventListener('keydown', keyboardRippleShow);
  4956. el.removeEventListener('keyup', keyboardRippleHide);
  4957. el.removeEventListener('dragstart', rippleHide);
  4958. el.removeEventListener('blur', focusRippleHide);
  4959. }
  4960. function mounted$4(el, binding) {
  4961. updateRipple(el, binding, false);
  4962. }
  4963. function unmounted$4(el) {
  4964. delete el._ripple;
  4965. removeListeners(el);
  4966. }
  4967. function updated$1(el, binding) {
  4968. if (binding.value === binding.oldValue) {
  4969. return;
  4970. }
  4971. const wasEnabled = isRippleEnabled(binding.oldValue);
  4972. updateRipple(el, binding, wasEnabled);
  4973. }
  4974. const Ripple = {
  4975. mounted: mounted$4,
  4976. unmounted: unmounted$4,
  4977. updated: updated$1
  4978. };
  4979. // Types
  4980. const makeVBtnProps = propsFactory({
  4981. active: {
  4982. type: Boolean,
  4983. default: undefined
  4984. },
  4985. symbol: {
  4986. type: null,
  4987. default: VBtnToggleSymbol
  4988. },
  4989. flat: Boolean,
  4990. icon: [Boolean, String, Function, Object],
  4991. prependIcon: IconValue,
  4992. appendIcon: IconValue,
  4993. block: Boolean,
  4994. stacked: Boolean,
  4995. ripple: {
  4996. type: [Boolean, Object],
  4997. default: true
  4998. },
  4999. text: String,
  5000. ...makeBorderProps(),
  5001. ...makeComponentProps(),
  5002. ...makeDensityProps(),
  5003. ...makeDimensionProps(),
  5004. ...makeElevationProps(),
  5005. ...makeGroupItemProps(),
  5006. ...makeLoaderProps(),
  5007. ...makeLocationProps(),
  5008. ...makePositionProps(),
  5009. ...makeRoundedProps(),
  5010. ...makeRouterProps(),
  5011. ...makeSizeProps(),
  5012. ...makeTagProps({
  5013. tag: 'button'
  5014. }),
  5015. ...makeThemeProps(),
  5016. ...makeVariantProps({
  5017. variant: 'elevated'
  5018. })
  5019. }, 'VBtn');
  5020. const VBtn = genericComponent()({
  5021. name: 'VBtn',
  5022. directives: {
  5023. Ripple
  5024. },
  5025. props: makeVBtnProps(),
  5026. emits: {
  5027. 'group:selected': val => true
  5028. },
  5029. setup(props, _ref) {
  5030. let {
  5031. attrs,
  5032. slots
  5033. } = _ref;
  5034. const {
  5035. themeClasses
  5036. } = provideTheme(props);
  5037. const {
  5038. borderClasses
  5039. } = useBorder(props);
  5040. const {
  5041. colorClasses,
  5042. colorStyles,
  5043. variantClasses
  5044. } = useVariant(props);
  5045. const {
  5046. densityClasses
  5047. } = useDensity(props);
  5048. const {
  5049. dimensionStyles
  5050. } = useDimension(props);
  5051. const {
  5052. elevationClasses
  5053. } = useElevation(props);
  5054. const {
  5055. loaderClasses
  5056. } = useLoader(props);
  5057. const {
  5058. locationStyles
  5059. } = useLocation(props);
  5060. const {
  5061. positionClasses
  5062. } = usePosition(props);
  5063. const {
  5064. roundedClasses
  5065. } = useRounded(props);
  5066. const {
  5067. sizeClasses,
  5068. sizeStyles
  5069. } = useSize(props);
  5070. const group = useGroupItem(props, props.symbol, false);
  5071. const link = useLink(props, attrs);
  5072. const isActive = computed(() => {
  5073. if (props.active !== undefined) {
  5074. return props.active;
  5075. }
  5076. if (link.isLink.value) {
  5077. return link.isActive?.value;
  5078. }
  5079. return group?.isSelected.value;
  5080. });
  5081. const isDisabled = computed(() => group?.disabled.value || props.disabled);
  5082. const isElevated = computed(() => {
  5083. return props.variant === 'elevated' && !(props.disabled || props.flat || props.border);
  5084. });
  5085. const valueAttr = computed(() => {
  5086. if (props.value === undefined) return undefined;
  5087. return Object(props.value) === props.value ? JSON.stringify(props.value, null, 0) : props.value;
  5088. });
  5089. function onClick(e) {
  5090. if (isDisabled.value || link.isLink.value && (e.metaKey || e.ctrlKey || e.shiftKey || e.button !== 0 || attrs.target === '_blank')) return;
  5091. link.navigate?.(e);
  5092. group?.toggle();
  5093. }
  5094. useSelectLink(link, group?.select);
  5095. useRender(() => {
  5096. const Tag = link.isLink.value ? 'a' : props.tag;
  5097. const hasPrepend = !!(props.prependIcon || slots.prepend);
  5098. const hasAppend = !!(props.appendIcon || slots.append);
  5099. const hasIcon = !!(props.icon && props.icon !== true);
  5100. const hasColor = group?.isSelected.value && (!link.isLink.value || link.isActive?.value) || !group || link.isActive?.value;
  5101. return withDirectives(createVNode(Tag, {
  5102. "type": Tag === 'a' ? undefined : 'button',
  5103. "class": ['v-btn', group?.selectedClass.value, {
  5104. 'v-btn--active': isActive.value,
  5105. 'v-btn--block': props.block,
  5106. 'v-btn--disabled': isDisabled.value,
  5107. 'v-btn--elevated': isElevated.value,
  5108. 'v-btn--flat': props.flat,
  5109. 'v-btn--icon': !!props.icon,
  5110. 'v-btn--loading': props.loading,
  5111. 'v-btn--stacked': props.stacked
  5112. }, themeClasses.value, borderClasses.value, hasColor ? colorClasses.value : undefined, densityClasses.value, elevationClasses.value, loaderClasses.value, positionClasses.value, roundedClasses.value, sizeClasses.value, variantClasses.value, props.class],
  5113. "style": [hasColor ? colorStyles.value : undefined, dimensionStyles.value, locationStyles.value, sizeStyles.value, props.style],
  5114. "disabled": isDisabled.value || undefined,
  5115. "href": link.href.value,
  5116. "onClick": onClick,
  5117. "value": valueAttr.value
  5118. }, {
  5119. default: () => [genOverlays(true, 'v-btn'), !props.icon && hasPrepend && createVNode("span", {
  5120. "key": "prepend",
  5121. "class": "v-btn__prepend"
  5122. }, [!slots.prepend ? createVNode(VIcon, {
  5123. "key": "prepend-icon",
  5124. "icon": props.prependIcon
  5125. }, null) : createVNode(VDefaultsProvider, {
  5126. "key": "prepend-defaults",
  5127. "disabled": !props.prependIcon,
  5128. "defaults": {
  5129. VIcon: {
  5130. icon: props.prependIcon
  5131. }
  5132. }
  5133. }, slots.prepend)]), createVNode("span", {
  5134. "class": "v-btn__content",
  5135. "data-no-activator": ""
  5136. }, [!slots.default && hasIcon ? createVNode(VIcon, {
  5137. "key": "content-icon",
  5138. "icon": props.icon
  5139. }, null) : createVNode(VDefaultsProvider, {
  5140. "key": "content-defaults",
  5141. "disabled": !hasIcon,
  5142. "defaults": {
  5143. VIcon: {
  5144. icon: props.icon
  5145. }
  5146. }
  5147. }, {
  5148. default: () => [slots.default?.() ?? props.text]
  5149. })]), !props.icon && hasAppend && createVNode("span", {
  5150. "key": "append",
  5151. "class": "v-btn__append"
  5152. }, [!slots.append ? createVNode(VIcon, {
  5153. "key": "append-icon",
  5154. "icon": props.appendIcon
  5155. }, null) : createVNode(VDefaultsProvider, {
  5156. "key": "append-defaults",
  5157. "disabled": !props.appendIcon,
  5158. "defaults": {
  5159. VIcon: {
  5160. icon: props.appendIcon
  5161. }
  5162. }
  5163. }, slots.append)]), !!props.loading && createVNode("span", {
  5164. "key": "loader",
  5165. "class": "v-btn__loader"
  5166. }, [slots.loader?.() ?? createVNode(VProgressCircular, {
  5167. "color": typeof props.loading === 'boolean' ? undefined : props.loading,
  5168. "indeterminate": true,
  5169. "size": "23",
  5170. "width": "2"
  5171. }, null)])]
  5172. }), [[resolveDirective("ripple"), !isDisabled.value && props.ripple, null]]);
  5173. });
  5174. return {};
  5175. }
  5176. });
  5177. // Types
  5178. const makeVAppBarNavIconProps = propsFactory({
  5179. ...makeVBtnProps({
  5180. icon: '$menu',
  5181. variant: 'text'
  5182. })
  5183. }, 'VAppBarNavIcon');
  5184. const VAppBarNavIcon = genericComponent()({
  5185. name: 'VAppBarNavIcon',
  5186. props: makeVAppBarNavIconProps(),
  5187. setup(props, _ref) {
  5188. let {
  5189. slots
  5190. } = _ref;
  5191. useRender(() => createVNode(VBtn, mergeProps(props, {
  5192. "class": ['v-app-bar-nav-icon']
  5193. }), slots));
  5194. return {};
  5195. }
  5196. });
  5197. // Types
  5198. const VAppBarTitle = genericComponent()({
  5199. name: 'VAppBarTitle',
  5200. props: makeVToolbarTitleProps(),
  5201. setup(props, _ref) {
  5202. let {
  5203. slots
  5204. } = _ref;
  5205. useRender(() => createVNode(VToolbarTitle, mergeProps(props, {
  5206. "class": "v-app-bar-title"
  5207. }), slots));
  5208. return {};
  5209. }
  5210. });
  5211. // Utilities
  5212. const VAlertTitle = createSimpleFunctional('v-alert-title');
  5213. // Types
  5214. const allowedTypes = ['success', 'info', 'warning', 'error'];
  5215. const makeVAlertProps = propsFactory({
  5216. border: {
  5217. type: [Boolean, String],
  5218. validator: val => {
  5219. return typeof val === 'boolean' || ['top', 'end', 'bottom', 'start'].includes(val);
  5220. }
  5221. },
  5222. borderColor: String,
  5223. closable: Boolean,
  5224. closeIcon: {
  5225. type: IconValue,
  5226. default: '$close'
  5227. },
  5228. closeLabel: {
  5229. type: String,
  5230. default: '$vuetify.close'
  5231. },
  5232. icon: {
  5233. type: [Boolean, String, Function, Object],
  5234. default: null
  5235. },
  5236. modelValue: {
  5237. type: Boolean,
  5238. default: true
  5239. },
  5240. prominent: Boolean,
  5241. title: String,
  5242. text: String,
  5243. type: {
  5244. type: String,
  5245. validator: val => allowedTypes.includes(val)
  5246. },
  5247. ...makeComponentProps(),
  5248. ...makeDensityProps(),
  5249. ...makeDimensionProps(),
  5250. ...makeElevationProps(),
  5251. ...makeLocationProps(),
  5252. ...makePositionProps(),
  5253. ...makeRoundedProps(),
  5254. ...makeTagProps(),
  5255. ...makeThemeProps(),
  5256. ...makeVariantProps({
  5257. variant: 'flat'
  5258. })
  5259. }, 'VAlert');
  5260. const VAlert = genericComponent()({
  5261. name: 'VAlert',
  5262. props: makeVAlertProps(),
  5263. emits: {
  5264. 'click:close': e => true,
  5265. 'update:modelValue': value => true
  5266. },
  5267. setup(props, _ref) {
  5268. let {
  5269. emit,
  5270. slots
  5271. } = _ref;
  5272. const isActive = useProxiedModel(props, 'modelValue');
  5273. const icon = computed(() => {
  5274. if (props.icon === false) return undefined;
  5275. if (!props.type) return props.icon;
  5276. return props.icon ?? `$${props.type}`;
  5277. });
  5278. const variantProps = computed(() => ({
  5279. color: props.color ?? props.type,
  5280. variant: props.variant
  5281. }));
  5282. const {
  5283. themeClasses
  5284. } = provideTheme(props);
  5285. const {
  5286. colorClasses,
  5287. colorStyles,
  5288. variantClasses
  5289. } = useVariant(variantProps);
  5290. const {
  5291. densityClasses
  5292. } = useDensity(props);
  5293. const {
  5294. dimensionStyles
  5295. } = useDimension(props);
  5296. const {
  5297. elevationClasses
  5298. } = useElevation(props);
  5299. const {
  5300. locationStyles
  5301. } = useLocation(props);
  5302. const {
  5303. positionClasses
  5304. } = usePosition(props);
  5305. const {
  5306. roundedClasses
  5307. } = useRounded(props);
  5308. const {
  5309. textColorClasses,
  5310. textColorStyles
  5311. } = useTextColor(toRef(props, 'borderColor'));
  5312. const {
  5313. t
  5314. } = useLocale();
  5315. const closeProps = computed(() => ({
  5316. 'aria-label': t(props.closeLabel),
  5317. onClick(e) {
  5318. isActive.value = false;
  5319. emit('click:close', e);
  5320. }
  5321. }));
  5322. return () => {
  5323. const hasPrepend = !!(slots.prepend || icon.value);
  5324. const hasTitle = !!(slots.title || props.title);
  5325. const hasClose = !!(slots.close || props.closable);
  5326. return isActive.value && createVNode(props.tag, {
  5327. "class": ['v-alert', props.border && {
  5328. 'v-alert--border': !!props.border,
  5329. [`v-alert--border-${props.border === true ? 'start' : props.border}`]: true
  5330. }, {
  5331. 'v-alert--prominent': props.prominent
  5332. }, themeClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, positionClasses.value, roundedClasses.value, variantClasses.value, props.class],
  5333. "style": [colorStyles.value, dimensionStyles.value, locationStyles.value, props.style],
  5334. "role": "alert"
  5335. }, {
  5336. default: () => [genOverlays(false, 'v-alert'), props.border && createVNode("div", {
  5337. "key": "border",
  5338. "class": ['v-alert__border', textColorClasses.value],
  5339. "style": textColorStyles.value
  5340. }, null), hasPrepend && createVNode("div", {
  5341. "key": "prepend",
  5342. "class": "v-alert__prepend"
  5343. }, [!slots.prepend ? createVNode(VIcon, {
  5344. "key": "prepend-icon",
  5345. "density": props.density,
  5346. "icon": icon.value,
  5347. "size": props.prominent ? 44 : 28
  5348. }, null) : createVNode(VDefaultsProvider, {
  5349. "key": "prepend-defaults",
  5350. "disabled": !icon.value,
  5351. "defaults": {
  5352. VIcon: {
  5353. density: props.density,
  5354. icon: icon.value,
  5355. size: props.prominent ? 44 : 28
  5356. }
  5357. }
  5358. }, slots.prepend)]), createVNode("div", {
  5359. "class": "v-alert__content"
  5360. }, [hasTitle && createVNode(VAlertTitle, {
  5361. "key": "title"
  5362. }, {
  5363. default: () => [slots.title?.() ?? props.title]
  5364. }), slots.text?.() ?? props.text, slots.default?.()]), slots.append && createVNode("div", {
  5365. "key": "append",
  5366. "class": "v-alert__append"
  5367. }, [slots.append()]), hasClose && createVNode("div", {
  5368. "key": "close",
  5369. "class": "v-alert__close"
  5370. }, [!slots.close ? createVNode(VBtn, mergeProps({
  5371. "key": "close-btn",
  5372. "icon": props.closeIcon,
  5373. "size": "x-small",
  5374. "variant": "text"
  5375. }, closeProps.value), null) : createVNode(VDefaultsProvider, {
  5376. "key": "close-defaults",
  5377. "defaults": {
  5378. VBtn: {
  5379. icon: props.closeIcon,
  5380. size: 'x-small',
  5381. variant: 'text'
  5382. }
  5383. }
  5384. }, {
  5385. default: () => [slots.close?.({
  5386. props: closeProps.value
  5387. })]
  5388. })])]
  5389. });
  5390. };
  5391. }
  5392. });
  5393. const makeVLabelProps = propsFactory({
  5394. text: String,
  5395. clickable: Boolean,
  5396. ...makeComponentProps(),
  5397. ...makeThemeProps()
  5398. }, 'VLabel');
  5399. const VLabel = genericComponent()({
  5400. name: 'VLabel',
  5401. props: makeVLabelProps(),
  5402. setup(props, _ref) {
  5403. let {
  5404. slots
  5405. } = _ref;
  5406. useRender(() => createVNode("label", {
  5407. "class": ['v-label', {
  5408. 'v-label--clickable': props.clickable
  5409. }, props.class],
  5410. "style": props.style
  5411. }, [props.text, slots.default?.()]));
  5412. return {};
  5413. }
  5414. });
  5415. // Types
  5416. const VSelectionControlGroupSymbol = Symbol.for('vuetify:selection-control-group');
  5417. const makeSelectionControlGroupProps = propsFactory({
  5418. color: String,
  5419. disabled: {
  5420. type: Boolean,
  5421. default: null
  5422. },
  5423. defaultsTarget: String,
  5424. error: Boolean,
  5425. id: String,
  5426. inline: Boolean,
  5427. falseIcon: IconValue,
  5428. trueIcon: IconValue,
  5429. ripple: {
  5430. type: Boolean,
  5431. default: true
  5432. },
  5433. multiple: {
  5434. type: Boolean,
  5435. default: null
  5436. },
  5437. name: String,
  5438. readonly: Boolean,
  5439. modelValue: null,
  5440. type: String,
  5441. valueComparator: {
  5442. type: Function,
  5443. default: deepEqual
  5444. },
  5445. ...makeComponentProps(),
  5446. ...makeDensityProps(),
  5447. ...makeThemeProps()
  5448. }, 'SelectionControlGroup');
  5449. const makeVSelectionControlGroupProps = propsFactory({
  5450. ...makeSelectionControlGroupProps({
  5451. defaultsTarget: 'VSelectionControl'
  5452. })
  5453. }, 'VSelectionControlGroup');
  5454. const VSelectionControlGroup = genericComponent()({
  5455. name: 'VSelectionControlGroup',
  5456. props: makeVSelectionControlGroupProps(),
  5457. emits: {
  5458. 'update:modelValue': val => true
  5459. },
  5460. setup(props, _ref) {
  5461. let {
  5462. slots
  5463. } = _ref;
  5464. const modelValue = useProxiedModel(props, 'modelValue');
  5465. const uid = getUid();
  5466. const id = computed(() => props.id || `v-selection-control-group-${uid}`);
  5467. const name = computed(() => props.name || id.value);
  5468. const updateHandlers = new Set();
  5469. provide(VSelectionControlGroupSymbol, {
  5470. modelValue,
  5471. forceUpdate: () => {
  5472. updateHandlers.forEach(fn => fn());
  5473. },
  5474. onForceUpdate: cb => {
  5475. updateHandlers.add(cb);
  5476. onScopeDispose(() => {
  5477. updateHandlers.delete(cb);
  5478. });
  5479. }
  5480. });
  5481. provideDefaults({
  5482. [props.defaultsTarget]: {
  5483. color: toRef(props, 'color'),
  5484. disabled: toRef(props, 'disabled'),
  5485. density: toRef(props, 'density'),
  5486. error: toRef(props, 'error'),
  5487. inline: toRef(props, 'inline'),
  5488. modelValue,
  5489. multiple: computed(() => !!props.multiple || props.multiple == null && Array.isArray(modelValue.value)),
  5490. name,
  5491. falseIcon: toRef(props, 'falseIcon'),
  5492. trueIcon: toRef(props, 'trueIcon'),
  5493. readonly: toRef(props, 'readonly'),
  5494. ripple: toRef(props, 'ripple'),
  5495. type: toRef(props, 'type'),
  5496. valueComparator: toRef(props, 'valueComparator')
  5497. }
  5498. });
  5499. useRender(() => createVNode("div", {
  5500. "class": ['v-selection-control-group', {
  5501. 'v-selection-control-group--inline': props.inline
  5502. }, props.class],
  5503. "style": props.style,
  5504. "role": props.type === 'radio' ? 'radiogroup' : undefined
  5505. }, [slots.default?.()]));
  5506. return {};
  5507. }
  5508. });
  5509. // Types
  5510. const makeVSelectionControlProps = propsFactory({
  5511. label: String,
  5512. trueValue: null,
  5513. falseValue: null,
  5514. value: null,
  5515. ...makeComponentProps(),
  5516. ...makeSelectionControlGroupProps()
  5517. }, 'VSelectionControl');
  5518. function useSelectionControl(props) {
  5519. const group = inject$1(VSelectionControlGroupSymbol, undefined);
  5520. const {
  5521. densityClasses
  5522. } = useDensity(props);
  5523. const modelValue = useProxiedModel(props, 'modelValue');
  5524. const trueValue = computed(() => props.trueValue !== undefined ? props.trueValue : props.value !== undefined ? props.value : true);
  5525. const falseValue = computed(() => props.falseValue !== undefined ? props.falseValue : false);
  5526. const isMultiple = computed(() => !!props.multiple || props.multiple == null && Array.isArray(modelValue.value));
  5527. const model = computed({
  5528. get() {
  5529. const val = group ? group.modelValue.value : modelValue.value;
  5530. return isMultiple.value ? val.some(v => props.valueComparator(v, trueValue.value)) : props.valueComparator(val, trueValue.value);
  5531. },
  5532. set(val) {
  5533. if (props.readonly) return;
  5534. const currentValue = val ? trueValue.value : falseValue.value;
  5535. let newVal = currentValue;
  5536. if (isMultiple.value) {
  5537. newVal = val ? [...wrapInArray(modelValue.value), currentValue] : wrapInArray(modelValue.value).filter(item => !props.valueComparator(item, trueValue.value));
  5538. }
  5539. if (group) {
  5540. group.modelValue.value = newVal;
  5541. } else {
  5542. modelValue.value = newVal;
  5543. }
  5544. }
  5545. });
  5546. const {
  5547. textColorClasses,
  5548. textColorStyles
  5549. } = useTextColor(computed(() => {
  5550. return model.value && !props.error && !props.disabled ? props.color : undefined;
  5551. }));
  5552. const icon = computed(() => model.value ? props.trueIcon : props.falseIcon);
  5553. return {
  5554. group,
  5555. densityClasses,
  5556. trueValue,
  5557. falseValue,
  5558. model,
  5559. textColorClasses,
  5560. textColorStyles,
  5561. icon
  5562. };
  5563. }
  5564. const VSelectionControl = genericComponent()({
  5565. name: 'VSelectionControl',
  5566. directives: {
  5567. Ripple
  5568. },
  5569. inheritAttrs: false,
  5570. props: makeVSelectionControlProps(),
  5571. emits: {
  5572. 'update:modelValue': val => true
  5573. },
  5574. setup(props, _ref) {
  5575. let {
  5576. attrs,
  5577. slots
  5578. } = _ref;
  5579. const {
  5580. group,
  5581. densityClasses,
  5582. icon,
  5583. model,
  5584. textColorClasses,
  5585. textColorStyles,
  5586. trueValue
  5587. } = useSelectionControl(props);
  5588. const uid = getUid();
  5589. const id = computed(() => props.id || `input-${uid}`);
  5590. const isFocused = shallowRef(false);
  5591. const isFocusVisible = shallowRef(false);
  5592. const input = ref();
  5593. group?.onForceUpdate(() => {
  5594. if (input.value) {
  5595. input.value.checked = model.value;
  5596. }
  5597. });
  5598. function onFocus(e) {
  5599. isFocused.value = true;
  5600. if (matchesSelector(e.target, ':focus-visible') !== false) {
  5601. isFocusVisible.value = true;
  5602. }
  5603. }
  5604. function onBlur() {
  5605. isFocused.value = false;
  5606. isFocusVisible.value = false;
  5607. }
  5608. function onInput(e) {
  5609. if (props.readonly && group) {
  5610. nextTick(() => group.forceUpdate());
  5611. }
  5612. model.value = e.target.checked;
  5613. }
  5614. useRender(() => {
  5615. const label = slots.label ? slots.label({
  5616. label: props.label,
  5617. props: {
  5618. for: id.value
  5619. }
  5620. }) : props.label;
  5621. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  5622. return createVNode("div", mergeProps({
  5623. "class": ['v-selection-control', {
  5624. 'v-selection-control--dirty': model.value,
  5625. 'v-selection-control--disabled': props.disabled,
  5626. 'v-selection-control--error': props.error,
  5627. 'v-selection-control--focused': isFocused.value,
  5628. 'v-selection-control--focus-visible': isFocusVisible.value,
  5629. 'v-selection-control--inline': props.inline
  5630. }, densityClasses.value, props.class]
  5631. }, rootAttrs, {
  5632. "style": props.style
  5633. }), [createVNode("div", {
  5634. "class": ['v-selection-control__wrapper', textColorClasses.value],
  5635. "style": textColorStyles.value
  5636. }, [slots.default?.(), withDirectives(createVNode("div", {
  5637. "class": ['v-selection-control__input']
  5638. }, [icon.value && createVNode(VIcon, {
  5639. "key": "icon",
  5640. "icon": icon.value
  5641. }, null), createVNode("input", mergeProps({
  5642. "ref": input,
  5643. "checked": model.value,
  5644. "disabled": !!(props.readonly || props.disabled),
  5645. "id": id.value,
  5646. "onBlur": onBlur,
  5647. "onFocus": onFocus,
  5648. "onInput": onInput,
  5649. "aria-disabled": !!(props.readonly || props.disabled),
  5650. "type": props.type,
  5651. "value": trueValue.value,
  5652. "name": props.name,
  5653. "aria-checked": props.type === 'checkbox' ? model.value : undefined
  5654. }, inputAttrs), null), slots.input?.({
  5655. model,
  5656. textColorClasses,
  5657. textColorStyles,
  5658. props: {
  5659. onFocus,
  5660. onBlur,
  5661. id: id.value
  5662. }
  5663. })]), [[resolveDirective("ripple"), props.ripple && [!props.disabled && !props.readonly, null, ['center', 'circle']]]])]), label && createVNode(VLabel, {
  5664. "for": id.value,
  5665. "clickable": true
  5666. }, {
  5667. default: () => [label]
  5668. })]);
  5669. });
  5670. return {
  5671. isFocused,
  5672. input
  5673. };
  5674. }
  5675. });
  5676. // Types
  5677. const makeVCheckboxBtnProps = propsFactory({
  5678. indeterminate: Boolean,
  5679. indeterminateIcon: {
  5680. type: IconValue,
  5681. default: '$checkboxIndeterminate'
  5682. },
  5683. ...makeVSelectionControlProps({
  5684. falseIcon: '$checkboxOff',
  5685. trueIcon: '$checkboxOn'
  5686. })
  5687. }, 'VCheckboxBtn');
  5688. const VCheckboxBtn = genericComponent()({
  5689. name: 'VCheckboxBtn',
  5690. props: makeVCheckboxBtnProps(),
  5691. emits: {
  5692. 'update:modelValue': value => true,
  5693. 'update:indeterminate': val => true
  5694. },
  5695. setup(props, _ref) {
  5696. let {
  5697. slots
  5698. } = _ref;
  5699. const indeterminate = useProxiedModel(props, 'indeterminate');
  5700. const model = useProxiedModel(props, 'modelValue');
  5701. function onChange(v) {
  5702. if (indeterminate.value) {
  5703. indeterminate.value = false;
  5704. }
  5705. }
  5706. const falseIcon = computed(() => {
  5707. return indeterminate.value ? props.indeterminateIcon : props.falseIcon;
  5708. });
  5709. const trueIcon = computed(() => {
  5710. return indeterminate.value ? props.indeterminateIcon : props.trueIcon;
  5711. });
  5712. useRender(() => createVNode(VSelectionControl, mergeProps(props, {
  5713. "modelValue": model.value,
  5714. "onUpdate:modelValue": [$event => model.value = $event, onChange],
  5715. "class": ['v-checkbox-btn', props.class],
  5716. "style": props.style,
  5717. "type": "checkbox",
  5718. "falseIcon": falseIcon.value,
  5719. "trueIcon": trueIcon.value,
  5720. "aria-checked": indeterminate.value ? 'mixed' : undefined
  5721. }), slots));
  5722. return {};
  5723. }
  5724. });
  5725. // Types
  5726. function useInputIcon(props) {
  5727. const {
  5728. t
  5729. } = useLocale();
  5730. function InputIcon(_ref) {
  5731. let {
  5732. name
  5733. } = _ref;
  5734. const localeKey = {
  5735. prepend: 'prependAction',
  5736. prependInner: 'prependAction',
  5737. append: 'appendAction',
  5738. appendInner: 'appendAction',
  5739. clear: 'clear'
  5740. }[name];
  5741. const listener = props[`onClick:${name}`];
  5742. const label = listener && localeKey ? t(`$vuetify.input.${localeKey}`, props.label ?? '') : undefined;
  5743. return createVNode(VIcon, {
  5744. "icon": props[`${name}Icon`],
  5745. "aria-label": label,
  5746. "onClick": listener
  5747. }, null);
  5748. }
  5749. return {
  5750. InputIcon
  5751. };
  5752. }
  5753. // Types
  5754. const makeVMessagesProps = propsFactory({
  5755. active: Boolean,
  5756. color: String,
  5757. messages: {
  5758. type: [Array, String],
  5759. default: () => []
  5760. },
  5761. ...makeComponentProps(),
  5762. ...makeTransitionProps({
  5763. transition: {
  5764. component: VSlideYTransition,
  5765. leaveAbsolute: true,
  5766. group: true
  5767. }
  5768. })
  5769. }, 'VMessages');
  5770. const VMessages = genericComponent()({
  5771. name: 'VMessages',
  5772. props: makeVMessagesProps(),
  5773. setup(props, _ref) {
  5774. let {
  5775. slots
  5776. } = _ref;
  5777. const messages = computed(() => wrapInArray(props.messages));
  5778. const {
  5779. textColorClasses,
  5780. textColorStyles
  5781. } = useTextColor(computed(() => props.color));
  5782. useRender(() => createVNode(MaybeTransition, {
  5783. "transition": props.transition,
  5784. "tag": "div",
  5785. "class": ['v-messages', textColorClasses.value, props.class],
  5786. "style": [textColorStyles.value, props.style],
  5787. "role": "alert",
  5788. "aria-live": "polite"
  5789. }, {
  5790. default: () => [props.active && messages.value.map((message, i) => createVNode("div", {
  5791. "class": "v-messages__message",
  5792. "key": `${i}-${messages.value}`
  5793. }, [slots.message ? slots.message({
  5794. message
  5795. }) : message]))]
  5796. }));
  5797. return {};
  5798. }
  5799. });
  5800. // Composables
  5801. // Types
  5802. // Composables
  5803. const makeFocusProps = propsFactory({
  5804. focused: Boolean,
  5805. 'onUpdate:focused': EventProp()
  5806. }, 'focus');
  5807. function useFocus(props) {
  5808. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  5809. const isFocused = useProxiedModel(props, 'focused');
  5810. const focusClasses = computed(() => {
  5811. return {
  5812. [`${name}--focused`]: isFocused.value
  5813. };
  5814. });
  5815. function focus() {
  5816. isFocused.value = true;
  5817. }
  5818. function blur() {
  5819. isFocused.value = false;
  5820. }
  5821. return {
  5822. focusClasses,
  5823. isFocused,
  5824. focus,
  5825. blur
  5826. };
  5827. }
  5828. // Composables
  5829. // Types
  5830. const FormKey = Symbol.for('vuetify:form');
  5831. const makeFormProps = propsFactory({
  5832. disabled: Boolean,
  5833. fastFail: Boolean,
  5834. readonly: Boolean,
  5835. modelValue: {
  5836. type: Boolean,
  5837. default: null
  5838. },
  5839. validateOn: {
  5840. type: String,
  5841. default: 'input'
  5842. }
  5843. }, 'form');
  5844. function createForm(props) {
  5845. const model = useProxiedModel(props, 'modelValue');
  5846. const isDisabled = computed(() => props.disabled);
  5847. const isReadonly = computed(() => props.readonly);
  5848. const isValidating = shallowRef(false);
  5849. const items = ref([]);
  5850. const errors = ref([]);
  5851. async function validate() {
  5852. const results = [];
  5853. let valid = true;
  5854. errors.value = [];
  5855. isValidating.value = true;
  5856. for (const item of items.value) {
  5857. const itemErrorMessages = await item.validate();
  5858. if (itemErrorMessages.length > 0) {
  5859. valid = false;
  5860. results.push({
  5861. id: item.id,
  5862. errorMessages: itemErrorMessages
  5863. });
  5864. }
  5865. if (!valid && props.fastFail) break;
  5866. }
  5867. errors.value = results;
  5868. isValidating.value = false;
  5869. return {
  5870. valid,
  5871. errors: errors.value
  5872. };
  5873. }
  5874. function reset() {
  5875. items.value.forEach(item => item.reset());
  5876. }
  5877. function resetValidation() {
  5878. items.value.forEach(item => item.resetValidation());
  5879. }
  5880. watch(items, () => {
  5881. let valid = 0;
  5882. let invalid = 0;
  5883. const results = [];
  5884. for (const item of items.value) {
  5885. if (item.isValid === false) {
  5886. invalid++;
  5887. results.push({
  5888. id: item.id,
  5889. errorMessages: item.errorMessages
  5890. });
  5891. } else if (item.isValid === true) valid++;
  5892. }
  5893. errors.value = results;
  5894. model.value = invalid > 0 ? false : valid === items.value.length ? true : null;
  5895. }, {
  5896. deep: true
  5897. });
  5898. provide(FormKey, {
  5899. register: _ref => {
  5900. let {
  5901. id,
  5902. validate,
  5903. reset,
  5904. resetValidation
  5905. } = _ref;
  5906. if (items.value.some(item => item.id === id)) {
  5907. consoleWarn(`Duplicate input name "${id}"`);
  5908. }
  5909. items.value.push({
  5910. id,
  5911. validate,
  5912. reset,
  5913. resetValidation,
  5914. isValid: null,
  5915. errorMessages: []
  5916. });
  5917. },
  5918. unregister: id => {
  5919. items.value = items.value.filter(item => {
  5920. return item.id !== id;
  5921. });
  5922. },
  5923. update: (id, isValid, errorMessages) => {
  5924. const found = items.value.find(item => item.id === id);
  5925. if (!found) return;
  5926. found.isValid = isValid;
  5927. found.errorMessages = errorMessages;
  5928. },
  5929. isDisabled,
  5930. isReadonly,
  5931. isValidating,
  5932. isValid: model,
  5933. items,
  5934. validateOn: toRef(props, 'validateOn')
  5935. });
  5936. return {
  5937. errors,
  5938. isDisabled,
  5939. isReadonly,
  5940. isValidating,
  5941. isValid: model,
  5942. items,
  5943. validate,
  5944. reset,
  5945. resetValidation
  5946. };
  5947. }
  5948. function useForm() {
  5949. return inject$1(FormKey, null);
  5950. }
  5951. // Composables
  5952. // Types
  5953. const makeValidationProps = propsFactory({
  5954. disabled: {
  5955. type: Boolean,
  5956. default: null
  5957. },
  5958. error: Boolean,
  5959. errorMessages: {
  5960. type: [Array, String],
  5961. default: () => []
  5962. },
  5963. maxErrors: {
  5964. type: [Number, String],
  5965. default: 1
  5966. },
  5967. name: String,
  5968. label: String,
  5969. readonly: {
  5970. type: Boolean,
  5971. default: null
  5972. },
  5973. rules: {
  5974. type: Array,
  5975. default: () => []
  5976. },
  5977. modelValue: null,
  5978. validateOn: String,
  5979. validationValue: null,
  5980. ...makeFocusProps()
  5981. }, 'validation');
  5982. function useValidation(props) {
  5983. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  5984. let id = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getUid();
  5985. const model = useProxiedModel(props, 'modelValue');
  5986. const validationModel = computed(() => props.validationValue === undefined ? model.value : props.validationValue);
  5987. const form = useForm();
  5988. const internalErrorMessages = ref([]);
  5989. const isPristine = shallowRef(true);
  5990. const isDirty = computed(() => !!(wrapInArray(model.value === '' ? null : model.value).length || wrapInArray(validationModel.value === '' ? null : validationModel.value).length));
  5991. const isDisabled = computed(() => !!(props.disabled ?? form?.isDisabled.value));
  5992. const isReadonly = computed(() => !!(props.readonly ?? form?.isReadonly.value));
  5993. const errorMessages = computed(() => {
  5994. return props.errorMessages.length ? wrapInArray(props.errorMessages).slice(0, Math.max(0, +props.maxErrors)) : internalErrorMessages.value;
  5995. });
  5996. const validateOn = computed(() => {
  5997. let value = (props.validateOn ?? form?.validateOn.value) || 'input';
  5998. if (value === 'lazy') value = 'input lazy';
  5999. const set = new Set(value?.split(' ') ?? []);
  6000. return {
  6001. blur: set.has('blur') || set.has('input'),
  6002. input: set.has('input'),
  6003. submit: set.has('submit'),
  6004. lazy: set.has('lazy')
  6005. };
  6006. });
  6007. const isValid = computed(() => {
  6008. if (props.error || props.errorMessages.length) return false;
  6009. if (!props.rules.length) return true;
  6010. if (isPristine.value) {
  6011. return internalErrorMessages.value.length || validateOn.value.lazy ? null : true;
  6012. } else {
  6013. return !internalErrorMessages.value.length;
  6014. }
  6015. });
  6016. const isValidating = shallowRef(false);
  6017. const validationClasses = computed(() => {
  6018. return {
  6019. [`${name}--error`]: isValid.value === false,
  6020. [`${name}--dirty`]: isDirty.value,
  6021. [`${name}--disabled`]: isDisabled.value,
  6022. [`${name}--readonly`]: isReadonly.value
  6023. };
  6024. });
  6025. const uid = computed(() => props.name ?? unref(id));
  6026. onBeforeMount(() => {
  6027. form?.register({
  6028. id: uid.value,
  6029. validate,
  6030. reset,
  6031. resetValidation
  6032. });
  6033. });
  6034. onBeforeUnmount(() => {
  6035. form?.unregister(uid.value);
  6036. });
  6037. onMounted(async () => {
  6038. if (!validateOn.value.lazy) {
  6039. await validate(true);
  6040. }
  6041. form?.update(uid.value, isValid.value, errorMessages.value);
  6042. });
  6043. useToggleScope(() => validateOn.value.input, () => {
  6044. watch(validationModel, () => {
  6045. if (validationModel.value != null) {
  6046. validate();
  6047. } else if (props.focused) {
  6048. const unwatch = watch(() => props.focused, val => {
  6049. if (!val) validate();
  6050. unwatch();
  6051. });
  6052. }
  6053. });
  6054. });
  6055. useToggleScope(() => validateOn.value.blur, () => {
  6056. watch(() => props.focused, val => {
  6057. if (!val) validate();
  6058. });
  6059. });
  6060. watch(isValid, () => {
  6061. form?.update(uid.value, isValid.value, errorMessages.value);
  6062. });
  6063. function reset() {
  6064. model.value = null;
  6065. nextTick(resetValidation);
  6066. }
  6067. function resetValidation() {
  6068. isPristine.value = true;
  6069. if (!validateOn.value.lazy) {
  6070. validate(true);
  6071. } else {
  6072. internalErrorMessages.value = [];
  6073. }
  6074. }
  6075. async function validate() {
  6076. let silent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
  6077. const results = [];
  6078. isValidating.value = true;
  6079. for (const rule of props.rules) {
  6080. if (results.length >= +(props.maxErrors ?? 1)) {
  6081. break;
  6082. }
  6083. const handler = typeof rule === 'function' ? rule : () => rule;
  6084. const result = await handler(validationModel.value);
  6085. if (result === true) continue;
  6086. if (result !== false && typeof result !== 'string') {
  6087. // eslint-disable-next-line no-console
  6088. console.warn(`${result} is not a valid value. Rule functions must return boolean true or a string.`);
  6089. continue;
  6090. }
  6091. results.push(result || '');
  6092. }
  6093. internalErrorMessages.value = results;
  6094. isValidating.value = false;
  6095. isPristine.value = silent;
  6096. return internalErrorMessages.value;
  6097. }
  6098. return {
  6099. errorMessages,
  6100. isDirty,
  6101. isDisabled,
  6102. isReadonly,
  6103. isPristine,
  6104. isValid,
  6105. isValidating,
  6106. reset,
  6107. resetValidation,
  6108. validate,
  6109. validationClasses
  6110. };
  6111. }
  6112. // Types
  6113. const makeVInputProps = propsFactory({
  6114. id: String,
  6115. appendIcon: IconValue,
  6116. centerAffix: {
  6117. type: Boolean,
  6118. default: true
  6119. },
  6120. prependIcon: IconValue,
  6121. hideDetails: [Boolean, String],
  6122. hint: String,
  6123. persistentHint: Boolean,
  6124. messages: {
  6125. type: [Array, String],
  6126. default: () => []
  6127. },
  6128. direction: {
  6129. type: String,
  6130. default: 'horizontal',
  6131. validator: v => ['horizontal', 'vertical'].includes(v)
  6132. },
  6133. 'onClick:prepend': EventProp(),
  6134. 'onClick:append': EventProp(),
  6135. ...makeComponentProps(),
  6136. ...makeDensityProps(),
  6137. ...makeValidationProps()
  6138. }, 'VInput');
  6139. const VInput = genericComponent()({
  6140. name: 'VInput',
  6141. props: {
  6142. ...makeVInputProps()
  6143. },
  6144. emits: {
  6145. 'update:modelValue': val => true
  6146. },
  6147. setup(props, _ref) {
  6148. let {
  6149. attrs,
  6150. slots,
  6151. emit
  6152. } = _ref;
  6153. const {
  6154. densityClasses
  6155. } = useDensity(props);
  6156. const {
  6157. rtlClasses
  6158. } = useRtl();
  6159. const {
  6160. InputIcon
  6161. } = useInputIcon(props);
  6162. const uid = getUid();
  6163. const id = computed(() => props.id || `input-${uid}`);
  6164. const messagesId = computed(() => `${id.value}-messages`);
  6165. const {
  6166. errorMessages,
  6167. isDirty,
  6168. isDisabled,
  6169. isReadonly,
  6170. isPristine,
  6171. isValid,
  6172. isValidating,
  6173. reset,
  6174. resetValidation,
  6175. validate,
  6176. validationClasses
  6177. } = useValidation(props, 'v-input', id);
  6178. const slotProps = computed(() => ({
  6179. id,
  6180. messagesId,
  6181. isDirty,
  6182. isDisabled,
  6183. isReadonly,
  6184. isPristine,
  6185. isValid,
  6186. isValidating,
  6187. reset,
  6188. resetValidation,
  6189. validate
  6190. }));
  6191. const messages = computed(() => {
  6192. if (props.errorMessages?.length || !isPristine.value && errorMessages.value.length) {
  6193. return errorMessages.value;
  6194. } else if (props.hint && (props.persistentHint || props.focused)) {
  6195. return props.hint;
  6196. } else {
  6197. return props.messages;
  6198. }
  6199. });
  6200. useRender(() => {
  6201. const hasPrepend = !!(slots.prepend || props.prependIcon);
  6202. const hasAppend = !!(slots.append || props.appendIcon);
  6203. const hasMessages = messages.value.length > 0;
  6204. const hasDetails = !props.hideDetails || props.hideDetails === 'auto' && (hasMessages || !!slots.details);
  6205. return createVNode("div", {
  6206. "class": ['v-input', `v-input--${props.direction}`, {
  6207. 'v-input--center-affix': props.centerAffix
  6208. }, densityClasses.value, rtlClasses.value, validationClasses.value, props.class],
  6209. "style": props.style
  6210. }, [hasPrepend && createVNode("div", {
  6211. "key": "prepend",
  6212. "class": "v-input__prepend"
  6213. }, [slots.prepend?.(slotProps.value), props.prependIcon && createVNode(InputIcon, {
  6214. "key": "prepend-icon",
  6215. "name": "prepend"
  6216. }, null)]), slots.default && createVNode("div", {
  6217. "class": "v-input__control"
  6218. }, [slots.default?.(slotProps.value)]), hasAppend && createVNode("div", {
  6219. "key": "append",
  6220. "class": "v-input__append"
  6221. }, [props.appendIcon && createVNode(InputIcon, {
  6222. "key": "append-icon",
  6223. "name": "append"
  6224. }, null), slots.append?.(slotProps.value)]), hasDetails && createVNode("div", {
  6225. "class": "v-input__details"
  6226. }, [createVNode(VMessages, {
  6227. "id": messagesId.value,
  6228. "active": hasMessages,
  6229. "messages": messages.value
  6230. }, {
  6231. message: slots.message
  6232. }), slots.details?.(slotProps.value)])]);
  6233. });
  6234. return {
  6235. reset,
  6236. resetValidation,
  6237. validate
  6238. };
  6239. }
  6240. });
  6241. // Types
  6242. const makeVCheckboxProps = propsFactory({
  6243. ...makeVInputProps(),
  6244. ...omit(makeVCheckboxBtnProps(), ['inline'])
  6245. }, 'VCheckbox');
  6246. const VCheckbox = genericComponent()({
  6247. name: 'VCheckbox',
  6248. inheritAttrs: false,
  6249. props: makeVCheckboxProps(),
  6250. emits: {
  6251. 'update:modelValue': value => true,
  6252. 'update:focused': focused => true
  6253. },
  6254. setup(props, _ref) {
  6255. let {
  6256. attrs,
  6257. slots
  6258. } = _ref;
  6259. const model = useProxiedModel(props, 'modelValue');
  6260. const {
  6261. isFocused,
  6262. focus,
  6263. blur
  6264. } = useFocus(props);
  6265. const uid = getUid();
  6266. const id = computed(() => props.id || `checkbox-${uid}`);
  6267. useRender(() => {
  6268. const [inputAttrs, controlAttrs] = filterInputAttrs(attrs);
  6269. const [inputProps, _1] = VInput.filterProps(props);
  6270. const [checkboxProps, _2] = VCheckboxBtn.filterProps(props);
  6271. return createVNode(VInput, mergeProps({
  6272. "class": ['v-checkbox', props.class]
  6273. }, inputAttrs, inputProps, {
  6274. "modelValue": model.value,
  6275. "onUpdate:modelValue": $event => model.value = $event,
  6276. "id": id.value,
  6277. "focused": isFocused.value,
  6278. "style": props.style
  6279. }), {
  6280. ...slots,
  6281. default: _ref2 => {
  6282. let {
  6283. id,
  6284. messagesId,
  6285. isDisabled,
  6286. isReadonly
  6287. } = _ref2;
  6288. return createVNode(VCheckboxBtn, mergeProps(checkboxProps, {
  6289. "id": id.value,
  6290. "aria-describedby": messagesId.value,
  6291. "disabled": isDisabled.value,
  6292. "readonly": isReadonly.value
  6293. }, controlAttrs, {
  6294. "modelValue": model.value,
  6295. "onUpdate:modelValue": $event => model.value = $event,
  6296. "onFocus": focus,
  6297. "onBlur": blur
  6298. }), slots);
  6299. }
  6300. });
  6301. });
  6302. return {};
  6303. }
  6304. });
  6305. const makeVAvatarProps = propsFactory({
  6306. start: Boolean,
  6307. end: Boolean,
  6308. icon: IconValue,
  6309. image: String,
  6310. ...makeComponentProps(),
  6311. ...makeDensityProps(),
  6312. ...makeRoundedProps(),
  6313. ...makeSizeProps(),
  6314. ...makeTagProps(),
  6315. ...makeThemeProps(),
  6316. ...makeVariantProps({
  6317. variant: 'flat'
  6318. })
  6319. }, 'VAvatar');
  6320. const VAvatar = genericComponent()({
  6321. name: 'VAvatar',
  6322. props: makeVAvatarProps(),
  6323. setup(props, _ref) {
  6324. let {
  6325. slots
  6326. } = _ref;
  6327. const {
  6328. themeClasses
  6329. } = provideTheme(props);
  6330. const {
  6331. colorClasses,
  6332. colorStyles,
  6333. variantClasses
  6334. } = useVariant(props);
  6335. const {
  6336. densityClasses
  6337. } = useDensity(props);
  6338. const {
  6339. roundedClasses
  6340. } = useRounded(props);
  6341. const {
  6342. sizeClasses,
  6343. sizeStyles
  6344. } = useSize(props);
  6345. useRender(() => createVNode(props.tag, {
  6346. "class": ['v-avatar', {
  6347. 'v-avatar--start': props.start,
  6348. 'v-avatar--end': props.end
  6349. }, themeClasses.value, colorClasses.value, densityClasses.value, roundedClasses.value, sizeClasses.value, variantClasses.value, props.class],
  6350. "style": [colorStyles.value, sizeStyles.value, props.style]
  6351. }, {
  6352. default: () => [props.image ? createVNode(VImg, {
  6353. "key": "image",
  6354. "src": props.image,
  6355. "alt": "",
  6356. "cover": true
  6357. }, null) : props.icon ? createVNode(VIcon, {
  6358. "key": "icon",
  6359. "icon": props.icon
  6360. }, null) : slots.default?.(), genOverlays(false, 'v-avatar')]
  6361. }));
  6362. return {};
  6363. }
  6364. });
  6365. // Types
  6366. const VChipGroupSymbol = Symbol.for('vuetify:v-chip-group');
  6367. const makeVChipGroupProps = propsFactory({
  6368. column: Boolean,
  6369. filter: Boolean,
  6370. valueComparator: {
  6371. type: Function,
  6372. default: deepEqual
  6373. },
  6374. ...makeComponentProps(),
  6375. ...makeGroupProps({
  6376. selectedClass: 'v-chip--selected'
  6377. }),
  6378. ...makeTagProps(),
  6379. ...makeThemeProps(),
  6380. ...makeVariantProps({
  6381. variant: 'tonal'
  6382. })
  6383. }, 'VChipGroup');
  6384. const VChipGroup = genericComponent()({
  6385. name: 'VChipGroup',
  6386. props: makeVChipGroupProps(),
  6387. emits: {
  6388. 'update:modelValue': value => true
  6389. },
  6390. setup(props, _ref) {
  6391. let {
  6392. slots
  6393. } = _ref;
  6394. const {
  6395. themeClasses
  6396. } = provideTheme(props);
  6397. const {
  6398. isSelected,
  6399. select,
  6400. next,
  6401. prev,
  6402. selected
  6403. } = useGroup(props, VChipGroupSymbol);
  6404. provideDefaults({
  6405. VChip: {
  6406. color: toRef(props, 'color'),
  6407. disabled: toRef(props, 'disabled'),
  6408. filter: toRef(props, 'filter'),
  6409. variant: toRef(props, 'variant')
  6410. }
  6411. });
  6412. useRender(() => createVNode(props.tag, {
  6413. "class": ['v-chip-group', {
  6414. 'v-chip-group--column': props.column
  6415. }, themeClasses.value, props.class],
  6416. "style": props.style
  6417. }, {
  6418. default: () => [slots.default?.({
  6419. isSelected,
  6420. select,
  6421. next,
  6422. prev,
  6423. selected: selected.value
  6424. })]
  6425. }));
  6426. return {};
  6427. }
  6428. });
  6429. // Types
  6430. const makeVChipProps = propsFactory({
  6431. activeClass: String,
  6432. appendAvatar: String,
  6433. appendIcon: IconValue,
  6434. closable: Boolean,
  6435. closeIcon: {
  6436. type: IconValue,
  6437. default: '$delete'
  6438. },
  6439. closeLabel: {
  6440. type: String,
  6441. default: '$vuetify.close'
  6442. },
  6443. draggable: Boolean,
  6444. filter: Boolean,
  6445. filterIcon: {
  6446. type: String,
  6447. default: '$complete'
  6448. },
  6449. label: Boolean,
  6450. link: {
  6451. type: Boolean,
  6452. default: undefined
  6453. },
  6454. pill: Boolean,
  6455. prependAvatar: String,
  6456. prependIcon: IconValue,
  6457. ripple: {
  6458. type: [Boolean, Object],
  6459. default: true
  6460. },
  6461. text: String,
  6462. modelValue: {
  6463. type: Boolean,
  6464. default: true
  6465. },
  6466. onClick: EventProp(),
  6467. onClickOnce: EventProp(),
  6468. ...makeBorderProps(),
  6469. ...makeComponentProps(),
  6470. ...makeDensityProps(),
  6471. ...makeElevationProps(),
  6472. ...makeGroupItemProps(),
  6473. ...makeRoundedProps(),
  6474. ...makeRouterProps(),
  6475. ...makeSizeProps(),
  6476. ...makeTagProps({
  6477. tag: 'span'
  6478. }),
  6479. ...makeThemeProps(),
  6480. ...makeVariantProps({
  6481. variant: 'tonal'
  6482. })
  6483. }, 'VChip');
  6484. const VChip = genericComponent()({
  6485. name: 'VChip',
  6486. directives: {
  6487. Ripple
  6488. },
  6489. props: makeVChipProps(),
  6490. emits: {
  6491. 'click:close': e => true,
  6492. 'update:modelValue': value => true,
  6493. 'group:selected': val => true,
  6494. click: e => true
  6495. },
  6496. setup(props, _ref) {
  6497. let {
  6498. attrs,
  6499. emit,
  6500. slots
  6501. } = _ref;
  6502. const {
  6503. t
  6504. } = useLocale();
  6505. const {
  6506. borderClasses
  6507. } = useBorder(props);
  6508. const {
  6509. colorClasses,
  6510. colorStyles,
  6511. variantClasses
  6512. } = useVariant(props);
  6513. const {
  6514. densityClasses
  6515. } = useDensity(props);
  6516. const {
  6517. elevationClasses
  6518. } = useElevation(props);
  6519. const {
  6520. roundedClasses
  6521. } = useRounded(props);
  6522. const {
  6523. sizeClasses
  6524. } = useSize(props);
  6525. const {
  6526. themeClasses
  6527. } = provideTheme(props);
  6528. const isActive = useProxiedModel(props, 'modelValue');
  6529. const group = useGroupItem(props, VChipGroupSymbol, false);
  6530. const link = useLink(props, attrs);
  6531. const isLink = computed(() => props.link !== false && link.isLink.value);
  6532. const isClickable = computed(() => !props.disabled && props.link !== false && (!!group || props.link || link.isClickable.value));
  6533. const closeProps = computed(() => ({
  6534. 'aria-label': t(props.closeLabel),
  6535. onClick(e) {
  6536. isActive.value = false;
  6537. emit('click:close', e);
  6538. }
  6539. }));
  6540. function onClick(e) {
  6541. emit('click', e);
  6542. if (!isClickable.value) return;
  6543. link.navigate?.(e);
  6544. group?.toggle();
  6545. }
  6546. function onKeyDown(e) {
  6547. if (e.key === 'Enter' || e.key === ' ') {
  6548. e.preventDefault();
  6549. onClick(e);
  6550. }
  6551. }
  6552. return () => {
  6553. const Tag = link.isLink.value ? 'a' : props.tag;
  6554. const hasAppendMedia = !!(props.appendIcon || props.appendAvatar);
  6555. const hasAppend = !!(hasAppendMedia || slots.append);
  6556. const hasClose = !!(slots.close || props.closable);
  6557. const hasFilter = !!(slots.filter || props.filter) && group;
  6558. const hasPrependMedia = !!(props.prependIcon || props.prependAvatar);
  6559. const hasPrepend = !!(hasPrependMedia || slots.prepend);
  6560. const hasColor = !group || group.isSelected.value;
  6561. return isActive.value && withDirectives(createVNode(Tag, {
  6562. "class": ['v-chip', {
  6563. 'v-chip--disabled': props.disabled,
  6564. 'v-chip--label': props.label,
  6565. 'v-chip--link': isClickable.value,
  6566. 'v-chip--filter': hasFilter,
  6567. 'v-chip--pill': props.pill
  6568. }, themeClasses.value, borderClasses.value, hasColor ? colorClasses.value : undefined, densityClasses.value, elevationClasses.value, roundedClasses.value, sizeClasses.value, variantClasses.value, group?.selectedClass.value, props.class],
  6569. "style": [hasColor ? colorStyles.value : undefined, props.style],
  6570. "disabled": props.disabled || undefined,
  6571. "draggable": props.draggable,
  6572. "href": link.href.value,
  6573. "tabindex": isClickable.value ? 0 : undefined,
  6574. "onClick": onClick,
  6575. "onKeydown": isClickable.value && !isLink.value && onKeyDown
  6576. }, {
  6577. default: () => [genOverlays(isClickable.value, 'v-chip'), hasFilter && createVNode(VExpandXTransition, {
  6578. "key": "filter"
  6579. }, {
  6580. default: () => [withDirectives(createVNode("div", {
  6581. "class": "v-chip__filter"
  6582. }, [!slots.filter ? createVNode(VIcon, {
  6583. "key": "filter-icon",
  6584. "icon": props.filterIcon
  6585. }, null) : createVNode(VDefaultsProvider, {
  6586. "key": "filter-defaults",
  6587. "disabled": !props.filterIcon,
  6588. "defaults": {
  6589. VIcon: {
  6590. icon: props.filterIcon
  6591. }
  6592. }
  6593. }, slots.filter)]), [[vShow, group.isSelected.value]])]
  6594. }), hasPrepend && createVNode("div", {
  6595. "key": "prepend",
  6596. "class": "v-chip__prepend"
  6597. }, [!slots.prepend ? createVNode(Fragment, null, [props.prependIcon && createVNode(VIcon, {
  6598. "key": "prepend-icon",
  6599. "icon": props.prependIcon,
  6600. "start": true
  6601. }, null), props.prependAvatar && createVNode(VAvatar, {
  6602. "key": "prepend-avatar",
  6603. "image": props.prependAvatar,
  6604. "start": true
  6605. }, null)]) : createVNode(VDefaultsProvider, {
  6606. "key": "prepend-defaults",
  6607. "disabled": !hasPrependMedia,
  6608. "defaults": {
  6609. VAvatar: {
  6610. image: props.prependAvatar,
  6611. start: true
  6612. },
  6613. VIcon: {
  6614. icon: props.prependIcon,
  6615. start: true
  6616. }
  6617. }
  6618. }, slots.prepend)]), createVNode("div", {
  6619. "class": "v-chip__content"
  6620. }, [slots.default?.({
  6621. isSelected: group?.isSelected.value,
  6622. selectedClass: group?.selectedClass.value,
  6623. select: group?.select,
  6624. toggle: group?.toggle,
  6625. value: group?.value.value,
  6626. disabled: props.disabled
  6627. }) ?? props.text]), hasAppend && createVNode("div", {
  6628. "key": "append",
  6629. "class": "v-chip__append"
  6630. }, [!slots.append ? createVNode(Fragment, null, [props.appendIcon && createVNode(VIcon, {
  6631. "key": "append-icon",
  6632. "end": true,
  6633. "icon": props.appendIcon
  6634. }, null), props.appendAvatar && createVNode(VAvatar, {
  6635. "key": "append-avatar",
  6636. "end": true,
  6637. "image": props.appendAvatar
  6638. }, null)]) : createVNode(VDefaultsProvider, {
  6639. "key": "append-defaults",
  6640. "disabled": !hasAppendMedia,
  6641. "defaults": {
  6642. VAvatar: {
  6643. end: true,
  6644. image: props.appendAvatar
  6645. },
  6646. VIcon: {
  6647. end: true,
  6648. icon: props.appendIcon
  6649. }
  6650. }
  6651. }, slots.append)]), hasClose && createVNode("div", mergeProps({
  6652. "key": "close",
  6653. "class": "v-chip__close"
  6654. }, closeProps.value), [!slots.close ? createVNode(VIcon, {
  6655. "key": "close-icon",
  6656. "icon": props.closeIcon,
  6657. "size": "x-small"
  6658. }, null) : createVNode(VDefaultsProvider, {
  6659. "key": "close-defaults",
  6660. "defaults": {
  6661. VIcon: {
  6662. icon: props.closeIcon,
  6663. size: 'x-small'
  6664. }
  6665. }
  6666. }, slots.close)])]
  6667. }), [[resolveDirective("ripple"), isClickable.value && props.ripple, null]]);
  6668. };
  6669. }
  6670. });
  6671. // Utilities
  6672. // List
  6673. const ListKey = Symbol.for('vuetify:list');
  6674. function createList() {
  6675. const parent = inject$1(ListKey, {
  6676. hasPrepend: shallowRef(false),
  6677. updateHasPrepend: () => null
  6678. });
  6679. const data = {
  6680. hasPrepend: shallowRef(false),
  6681. updateHasPrepend: value => {
  6682. if (value) data.hasPrepend.value = value;
  6683. }
  6684. };
  6685. provide(ListKey, data);
  6686. return parent;
  6687. }
  6688. function useList() {
  6689. return inject$1(ListKey, null);
  6690. }
  6691. const singleOpenStrategy = {
  6692. open: _ref => {
  6693. let {
  6694. id,
  6695. value,
  6696. opened,
  6697. parents
  6698. } = _ref;
  6699. if (value) {
  6700. const newOpened = new Set();
  6701. newOpened.add(id);
  6702. let parent = parents.get(id);
  6703. while (parent != null) {
  6704. newOpened.add(parent);
  6705. parent = parents.get(parent);
  6706. }
  6707. return newOpened;
  6708. } else {
  6709. opened.delete(id);
  6710. return opened;
  6711. }
  6712. },
  6713. select: () => null
  6714. };
  6715. const multipleOpenStrategy = {
  6716. open: _ref2 => {
  6717. let {
  6718. id,
  6719. value,
  6720. opened,
  6721. parents
  6722. } = _ref2;
  6723. if (value) {
  6724. let parent = parents.get(id);
  6725. opened.add(id);
  6726. while (parent != null && parent !== id) {
  6727. opened.add(parent);
  6728. parent = parents.get(parent);
  6729. }
  6730. return opened;
  6731. } else {
  6732. opened.delete(id);
  6733. }
  6734. return opened;
  6735. },
  6736. select: () => null
  6737. };
  6738. const listOpenStrategy = {
  6739. open: multipleOpenStrategy.open,
  6740. select: _ref3 => {
  6741. let {
  6742. id,
  6743. value,
  6744. opened,
  6745. parents
  6746. } = _ref3;
  6747. if (!value) return opened;
  6748. const path = [];
  6749. let parent = parents.get(id);
  6750. while (parent != null) {
  6751. path.push(parent);
  6752. parent = parents.get(parent);
  6753. }
  6754. return new Set(path);
  6755. }
  6756. };
  6757. /* eslint-disable sonarjs/no-identical-functions */
  6758. // Utilities
  6759. const independentSelectStrategy = mandatory => {
  6760. const strategy = {
  6761. select: _ref => {
  6762. let {
  6763. id,
  6764. value,
  6765. selected
  6766. } = _ref;
  6767. id = toRaw(id);
  6768. // When mandatory and we're trying to deselect when id
  6769. // is the only currently selected item then do nothing
  6770. if (mandatory && !value) {
  6771. const on = Array.from(selected.entries()).reduce((arr, _ref2) => {
  6772. let [key, value] = _ref2;
  6773. return value === 'on' ? [...arr, key] : arr;
  6774. }, []);
  6775. if (on.length === 1 && on[0] === id) return selected;
  6776. }
  6777. selected.set(id, value ? 'on' : 'off');
  6778. return selected;
  6779. },
  6780. in: (v, children, parents) => {
  6781. let map = new Map();
  6782. for (const id of v || []) {
  6783. map = strategy.select({
  6784. id,
  6785. value: true,
  6786. selected: new Map(map),
  6787. children,
  6788. parents
  6789. });
  6790. }
  6791. return map;
  6792. },
  6793. out: v => {
  6794. const arr = [];
  6795. for (const [key, value] of v.entries()) {
  6796. if (value === 'on') arr.push(key);
  6797. }
  6798. return arr;
  6799. }
  6800. };
  6801. return strategy;
  6802. };
  6803. const independentSingleSelectStrategy = mandatory => {
  6804. const parentStrategy = independentSelectStrategy(mandatory);
  6805. const strategy = {
  6806. select: _ref3 => {
  6807. let {
  6808. selected,
  6809. id,
  6810. ...rest
  6811. } = _ref3;
  6812. id = toRaw(id);
  6813. const singleSelected = selected.has(id) ? new Map([[id, selected.get(id)]]) : new Map();
  6814. return parentStrategy.select({
  6815. ...rest,
  6816. id,
  6817. selected: singleSelected
  6818. });
  6819. },
  6820. in: (v, children, parents) => {
  6821. let map = new Map();
  6822. if (v?.length) {
  6823. map = parentStrategy.in(v.slice(0, 1), children, parents);
  6824. }
  6825. return map;
  6826. },
  6827. out: (v, children, parents) => {
  6828. return parentStrategy.out(v, children, parents);
  6829. }
  6830. };
  6831. return strategy;
  6832. };
  6833. const leafSelectStrategy = mandatory => {
  6834. const parentStrategy = independentSelectStrategy(mandatory);
  6835. const strategy = {
  6836. select: _ref4 => {
  6837. let {
  6838. id,
  6839. selected,
  6840. children,
  6841. ...rest
  6842. } = _ref4;
  6843. id = toRaw(id);
  6844. if (children.has(id)) return selected;
  6845. return parentStrategy.select({
  6846. id,
  6847. selected,
  6848. children,
  6849. ...rest
  6850. });
  6851. },
  6852. in: parentStrategy.in,
  6853. out: parentStrategy.out
  6854. };
  6855. return strategy;
  6856. };
  6857. const leafSingleSelectStrategy = mandatory => {
  6858. const parentStrategy = independentSingleSelectStrategy(mandatory);
  6859. const strategy = {
  6860. select: _ref5 => {
  6861. let {
  6862. id,
  6863. selected,
  6864. children,
  6865. ...rest
  6866. } = _ref5;
  6867. id = toRaw(id);
  6868. if (children.has(id)) return selected;
  6869. return parentStrategy.select({
  6870. id,
  6871. selected,
  6872. children,
  6873. ...rest
  6874. });
  6875. },
  6876. in: parentStrategy.in,
  6877. out: parentStrategy.out
  6878. };
  6879. return strategy;
  6880. };
  6881. const classicSelectStrategy = mandatory => {
  6882. const strategy = {
  6883. select: _ref6 => {
  6884. let {
  6885. id,
  6886. value,
  6887. selected,
  6888. children,
  6889. parents
  6890. } = _ref6;
  6891. id = toRaw(id);
  6892. const original = new Map(selected);
  6893. const items = [id];
  6894. while (items.length) {
  6895. const item = items.shift();
  6896. selected.set(item, value ? 'on' : 'off');
  6897. if (children.has(item)) {
  6898. items.push(...children.get(item));
  6899. }
  6900. }
  6901. let parent = parents.get(id);
  6902. while (parent) {
  6903. const childrenIds = children.get(parent);
  6904. const everySelected = childrenIds.every(cid => selected.get(cid) === 'on');
  6905. const noneSelected = childrenIds.every(cid => !selected.has(cid) || selected.get(cid) === 'off');
  6906. selected.set(parent, everySelected ? 'on' : noneSelected ? 'off' : 'indeterminate');
  6907. parent = parents.get(parent);
  6908. }
  6909. // If mandatory and planned deselect results in no selected
  6910. // items then we can't do it, so return original state
  6911. if (mandatory && !value) {
  6912. const on = Array.from(selected.entries()).reduce((arr, _ref7) => {
  6913. let [key, value] = _ref7;
  6914. return value === 'on' ? [...arr, key] : arr;
  6915. }, []);
  6916. if (on.length === 0) return original;
  6917. }
  6918. return selected;
  6919. },
  6920. in: (v, children, parents) => {
  6921. let map = new Map();
  6922. for (const id of v || []) {
  6923. map = strategy.select({
  6924. id,
  6925. value: true,
  6926. selected: new Map(map),
  6927. children,
  6928. parents
  6929. });
  6930. }
  6931. return map;
  6932. },
  6933. out: (v, children) => {
  6934. const arr = [];
  6935. for (const [key, value] of v.entries()) {
  6936. if (value === 'on' && !children.has(key)) arr.push(key);
  6937. }
  6938. return arr;
  6939. }
  6940. };
  6941. return strategy;
  6942. };
  6943. // Composables
  6944. // Types
  6945. const VNestedSymbol = Symbol.for('vuetify:nested');
  6946. const emptyNested = {
  6947. id: shallowRef(),
  6948. root: {
  6949. register: () => null,
  6950. unregister: () => null,
  6951. parents: ref(new Map()),
  6952. children: ref(new Map()),
  6953. open: () => null,
  6954. openOnSelect: () => null,
  6955. select: () => null,
  6956. opened: ref(new Set()),
  6957. selected: ref(new Map()),
  6958. selectedValues: ref([])
  6959. }
  6960. };
  6961. const makeNestedProps = propsFactory({
  6962. selectStrategy: [String, Function],
  6963. openStrategy: [String, Object],
  6964. opened: Array,
  6965. selected: Array,
  6966. mandatory: Boolean
  6967. }, 'nested');
  6968. const useNested = props => {
  6969. let isUnmounted = false;
  6970. const children = ref(new Map());
  6971. const parents = ref(new Map());
  6972. const opened = useProxiedModel(props, 'opened', props.opened, v => new Set(v), v => [...v.values()]);
  6973. const selectStrategy = computed(() => {
  6974. if (typeof props.selectStrategy === 'object') return props.selectStrategy;
  6975. switch (props.selectStrategy) {
  6976. case 'single-leaf':
  6977. return leafSingleSelectStrategy(props.mandatory);
  6978. case 'leaf':
  6979. return leafSelectStrategy(props.mandatory);
  6980. case 'independent':
  6981. return independentSelectStrategy(props.mandatory);
  6982. case 'single-independent':
  6983. return independentSingleSelectStrategy(props.mandatory);
  6984. case 'classic':
  6985. default:
  6986. return classicSelectStrategy(props.mandatory);
  6987. }
  6988. });
  6989. const openStrategy = computed(() => {
  6990. if (typeof props.openStrategy === 'object') return props.openStrategy;
  6991. switch (props.openStrategy) {
  6992. case 'list':
  6993. return listOpenStrategy;
  6994. case 'single':
  6995. return singleOpenStrategy;
  6996. case 'multiple':
  6997. default:
  6998. return multipleOpenStrategy;
  6999. }
  7000. });
  7001. 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));
  7002. onBeforeUnmount(() => {
  7003. isUnmounted = true;
  7004. });
  7005. function getPath(id) {
  7006. const path = [];
  7007. let parent = id;
  7008. while (parent != null) {
  7009. path.unshift(parent);
  7010. parent = parents.value.get(parent);
  7011. }
  7012. return path;
  7013. }
  7014. const vm = getCurrentInstance('nested');
  7015. const nested = {
  7016. id: shallowRef(),
  7017. root: {
  7018. opened,
  7019. selected,
  7020. selectedValues: computed(() => {
  7021. const arr = [];
  7022. for (const [key, value] of selected.value.entries()) {
  7023. if (value === 'on') arr.push(key);
  7024. }
  7025. return arr;
  7026. }),
  7027. register: (id, parentId, isGroup) => {
  7028. parentId && id !== parentId && parents.value.set(id, parentId);
  7029. isGroup && children.value.set(id, []);
  7030. if (parentId != null) {
  7031. children.value.set(parentId, [...(children.value.get(parentId) || []), id]);
  7032. }
  7033. },
  7034. unregister: id => {
  7035. if (isUnmounted) return;
  7036. children.value.delete(id);
  7037. const parent = parents.value.get(id);
  7038. if (parent) {
  7039. const list = children.value.get(parent) ?? [];
  7040. children.value.set(parent, list.filter(child => child !== id));
  7041. }
  7042. parents.value.delete(id);
  7043. opened.value.delete(id);
  7044. },
  7045. open: (id, value, event) => {
  7046. vm.emit('click:open', {
  7047. id,
  7048. value,
  7049. path: getPath(id),
  7050. event
  7051. });
  7052. const newOpened = openStrategy.value.open({
  7053. id,
  7054. value,
  7055. opened: new Set(opened.value),
  7056. children: children.value,
  7057. parents: parents.value,
  7058. event
  7059. });
  7060. newOpened && (opened.value = newOpened);
  7061. },
  7062. openOnSelect: (id, value, event) => {
  7063. const newOpened = openStrategy.value.select({
  7064. id,
  7065. value,
  7066. selected: new Map(selected.value),
  7067. opened: new Set(opened.value),
  7068. children: children.value,
  7069. parents: parents.value,
  7070. event
  7071. });
  7072. newOpened && (opened.value = newOpened);
  7073. },
  7074. select: (id, value, event) => {
  7075. vm.emit('click:select', {
  7076. id,
  7077. value,
  7078. path: getPath(id),
  7079. event
  7080. });
  7081. const newSelected = selectStrategy.value.select({
  7082. id,
  7083. value,
  7084. selected: new Map(selected.value),
  7085. children: children.value,
  7086. parents: parents.value,
  7087. event
  7088. });
  7089. newSelected && (selected.value = newSelected);
  7090. nested.root.openOnSelect(id, value, event);
  7091. },
  7092. children,
  7093. parents
  7094. }
  7095. };
  7096. provide(VNestedSymbol, nested);
  7097. return nested.root;
  7098. };
  7099. const useNestedItem = (id, isGroup) => {
  7100. const parent = inject$1(VNestedSymbol, emptyNested);
  7101. const uidSymbol = Symbol(getUid());
  7102. const computedId = computed(() => id.value !== undefined ? id.value : uidSymbol);
  7103. const item = {
  7104. ...parent,
  7105. id: computedId,
  7106. open: (open, e) => parent.root.open(computedId.value, open, e),
  7107. openOnSelect: (open, e) => parent.root.openOnSelect(computedId.value, open, e),
  7108. isOpen: computed(() => parent.root.opened.value.has(computedId.value)),
  7109. parent: computed(() => parent.root.parents.value.get(computedId.value)),
  7110. select: (selected, e) => parent.root.select(computedId.value, selected, e),
  7111. isSelected: computed(() => parent.root.selected.value.get(toRaw(computedId.value)) === 'on'),
  7112. isIndeterminate: computed(() => parent.root.selected.value.get(computedId.value) === 'indeterminate'),
  7113. isLeaf: computed(() => !parent.root.children.value.get(computedId.value)),
  7114. isGroupActivator: parent.isGroupActivator
  7115. };
  7116. !parent.isGroupActivator && parent.root.register(computedId.value, parent.id.value, isGroup);
  7117. onBeforeUnmount(() => {
  7118. !parent.isGroupActivator && parent.root.unregister(computedId.value);
  7119. });
  7120. isGroup && provide(VNestedSymbol, item);
  7121. return item;
  7122. };
  7123. const useNestedGroupActivator = () => {
  7124. const parent = inject$1(VNestedSymbol, emptyNested);
  7125. provide(VNestedSymbol, {
  7126. ...parent,
  7127. isGroupActivator: true
  7128. });
  7129. };
  7130. const VListGroupActivator = defineComponent({
  7131. name: 'VListGroupActivator',
  7132. setup(_, _ref) {
  7133. let {
  7134. slots
  7135. } = _ref;
  7136. useNestedGroupActivator();
  7137. return () => slots.default?.();
  7138. }
  7139. });
  7140. const makeVListGroupProps = propsFactory({
  7141. /* @deprecated */
  7142. activeColor: String,
  7143. baseColor: String,
  7144. color: String,
  7145. collapseIcon: {
  7146. type: IconValue,
  7147. default: '$collapse'
  7148. },
  7149. expandIcon: {
  7150. type: IconValue,
  7151. default: '$expand'
  7152. },
  7153. prependIcon: IconValue,
  7154. appendIcon: IconValue,
  7155. fluid: Boolean,
  7156. subgroup: Boolean,
  7157. title: String,
  7158. value: null,
  7159. ...makeComponentProps(),
  7160. ...makeTagProps()
  7161. }, 'VListGroup');
  7162. const VListGroup = genericComponent()({
  7163. name: 'VListGroup',
  7164. props: makeVListGroupProps(),
  7165. setup(props, _ref2) {
  7166. let {
  7167. slots
  7168. } = _ref2;
  7169. const {
  7170. isOpen,
  7171. open,
  7172. id: _id
  7173. } = useNestedItem(toRef(props, 'value'), true);
  7174. const id = computed(() => `v-list-group--id-${String(_id.value)}`);
  7175. const list = useList();
  7176. const {
  7177. isBooted
  7178. } = useSsrBoot();
  7179. function onClick(e) {
  7180. open(!isOpen.value, e);
  7181. }
  7182. const activatorProps = computed(() => ({
  7183. onClick,
  7184. class: 'v-list-group__header',
  7185. id: id.value
  7186. }));
  7187. const toggleIcon = computed(() => isOpen.value ? props.collapseIcon : props.expandIcon);
  7188. const activatorDefaults = computed(() => ({
  7189. VListItem: {
  7190. active: isOpen.value,
  7191. activeColor: props.activeColor,
  7192. baseColor: props.baseColor,
  7193. color: props.color,
  7194. prependIcon: props.prependIcon || props.subgroup && toggleIcon.value,
  7195. appendIcon: props.appendIcon || !props.subgroup && toggleIcon.value,
  7196. title: props.title,
  7197. value: props.value
  7198. }
  7199. }));
  7200. useRender(() => createVNode(props.tag, {
  7201. "class": ['v-list-group', {
  7202. 'v-list-group--prepend': list?.hasPrepend.value,
  7203. 'v-list-group--fluid': props.fluid,
  7204. 'v-list-group--subgroup': props.subgroup,
  7205. 'v-list-group--open': isOpen.value
  7206. }, props.class],
  7207. "style": props.style
  7208. }, {
  7209. default: () => [slots.activator && createVNode(VDefaultsProvider, {
  7210. "defaults": activatorDefaults.value
  7211. }, {
  7212. default: () => [createVNode(VListGroupActivator, null, {
  7213. default: () => [slots.activator({
  7214. props: activatorProps.value,
  7215. isOpen: isOpen.value
  7216. })]
  7217. })]
  7218. }), createVNode(MaybeTransition, {
  7219. "transition": {
  7220. component: VExpandTransition
  7221. },
  7222. "disabled": !isBooted.value
  7223. }, {
  7224. default: () => [withDirectives(createVNode("div", {
  7225. "class": "v-list-group__items",
  7226. "role": "group",
  7227. "aria-labelledby": id.value
  7228. }, [slots.default?.()]), [[vShow, isOpen.value]])]
  7229. })]
  7230. }));
  7231. return {};
  7232. }
  7233. });
  7234. // Utilities
  7235. const VListItemSubtitle = createSimpleFunctional('v-list-item-subtitle');
  7236. // Utilities
  7237. const VListItemTitle = createSimpleFunctional('v-list-item-title');
  7238. // Types
  7239. const makeVListItemProps = propsFactory({
  7240. active: {
  7241. type: Boolean,
  7242. default: undefined
  7243. },
  7244. activeClass: String,
  7245. /* @deprecated */
  7246. activeColor: String,
  7247. appendAvatar: String,
  7248. appendIcon: IconValue,
  7249. baseColor: String,
  7250. disabled: Boolean,
  7251. lines: String,
  7252. link: {
  7253. type: Boolean,
  7254. default: undefined
  7255. },
  7256. nav: Boolean,
  7257. prependAvatar: String,
  7258. prependIcon: IconValue,
  7259. ripple: {
  7260. type: [Boolean, Object],
  7261. default: true
  7262. },
  7263. subtitle: [String, Number, Boolean],
  7264. title: [String, Number, Boolean],
  7265. value: null,
  7266. onClick: EventProp(),
  7267. onClickOnce: EventProp(),
  7268. ...makeBorderProps(),
  7269. ...makeComponentProps(),
  7270. ...makeDensityProps(),
  7271. ...makeDimensionProps(),
  7272. ...makeElevationProps(),
  7273. ...makeRoundedProps(),
  7274. ...makeRouterProps(),
  7275. ...makeTagProps(),
  7276. ...makeThemeProps(),
  7277. ...makeVariantProps({
  7278. variant: 'text'
  7279. })
  7280. }, 'VListItem');
  7281. const VListItem = genericComponent()({
  7282. name: 'VListItem',
  7283. directives: {
  7284. Ripple
  7285. },
  7286. props: makeVListItemProps(),
  7287. emits: {
  7288. click: e => true
  7289. },
  7290. setup(props, _ref) {
  7291. let {
  7292. attrs,
  7293. slots,
  7294. emit
  7295. } = _ref;
  7296. const link = useLink(props, attrs);
  7297. const id = computed(() => props.value === undefined ? link.href.value : props.value);
  7298. const {
  7299. select,
  7300. isSelected,
  7301. isIndeterminate,
  7302. isGroupActivator,
  7303. root,
  7304. parent,
  7305. openOnSelect
  7306. } = useNestedItem(id, false);
  7307. const list = useList();
  7308. const isActive = computed(() => props.active !== false && (props.active || link.isActive?.value || isSelected.value));
  7309. const isLink = computed(() => props.link !== false && link.isLink.value);
  7310. const isClickable = computed(() => !props.disabled && props.link !== false && (props.link || link.isClickable.value || props.value != null && !!list));
  7311. const roundedProps = computed(() => props.rounded || props.nav);
  7312. const color = computed(() => props.color ?? props.activeColor);
  7313. const variantProps = computed(() => ({
  7314. color: isActive.value ? color.value ?? props.baseColor : props.baseColor,
  7315. variant: props.variant
  7316. }));
  7317. watch(() => link.isActive?.value, val => {
  7318. if (val && parent.value != null) {
  7319. root.open(parent.value, true);
  7320. }
  7321. if (val) {
  7322. openOnSelect(val);
  7323. }
  7324. }, {
  7325. immediate: true
  7326. });
  7327. const {
  7328. themeClasses
  7329. } = provideTheme(props);
  7330. const {
  7331. borderClasses
  7332. } = useBorder(props);
  7333. const {
  7334. colorClasses,
  7335. colorStyles,
  7336. variantClasses
  7337. } = useVariant(variantProps);
  7338. const {
  7339. densityClasses
  7340. } = useDensity(props);
  7341. const {
  7342. dimensionStyles
  7343. } = useDimension(props);
  7344. const {
  7345. elevationClasses
  7346. } = useElevation(props);
  7347. const {
  7348. roundedClasses
  7349. } = useRounded(roundedProps);
  7350. const lineClasses = computed(() => props.lines ? `v-list-item--${props.lines}-line` : undefined);
  7351. const slotProps = computed(() => ({
  7352. isActive: isActive.value,
  7353. select,
  7354. isSelected: isSelected.value,
  7355. isIndeterminate: isIndeterminate.value
  7356. }));
  7357. function onClick(e) {
  7358. emit('click', e);
  7359. if (isGroupActivator || !isClickable.value) return;
  7360. link.navigate?.(e);
  7361. props.value != null && select(!isSelected.value, e);
  7362. }
  7363. function onKeyDown(e) {
  7364. if (e.key === 'Enter' || e.key === ' ') {
  7365. e.preventDefault();
  7366. onClick(e);
  7367. }
  7368. }
  7369. useRender(() => {
  7370. const Tag = isLink.value ? 'a' : props.tag;
  7371. const hasTitle = slots.title || props.title;
  7372. const hasSubtitle = slots.subtitle || props.subtitle;
  7373. const hasAppendMedia = !!(props.appendAvatar || props.appendIcon);
  7374. const hasAppend = !!(hasAppendMedia || slots.append);
  7375. const hasPrependMedia = !!(props.prependAvatar || props.prependIcon);
  7376. const hasPrepend = !!(hasPrependMedia || slots.prepend);
  7377. list?.updateHasPrepend(hasPrepend);
  7378. if (props.activeColor) {
  7379. deprecate('active-color', ['color', 'base-color']);
  7380. }
  7381. return withDirectives(createVNode(Tag, {
  7382. "class": ['v-list-item', {
  7383. 'v-list-item--active': isActive.value,
  7384. 'v-list-item--disabled': props.disabled,
  7385. 'v-list-item--link': isClickable.value,
  7386. 'v-list-item--nav': props.nav,
  7387. 'v-list-item--prepend': !hasPrepend && list?.hasPrepend.value,
  7388. [`${props.activeClass}`]: props.activeClass && isActive.value
  7389. }, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, variantClasses.value, props.class],
  7390. "style": [colorStyles.value, dimensionStyles.value, props.style],
  7391. "href": link.href.value,
  7392. "tabindex": isClickable.value ? list ? -2 : 0 : undefined,
  7393. "onClick": onClick,
  7394. "onKeydown": isClickable.value && !isLink.value && onKeyDown
  7395. }, {
  7396. default: () => [genOverlays(isClickable.value || isActive.value, 'v-list-item'), hasPrepend && createVNode("div", {
  7397. "key": "prepend",
  7398. "class": "v-list-item__prepend"
  7399. }, [!slots.prepend ? createVNode(Fragment, null, [props.prependAvatar && createVNode(VAvatar, {
  7400. "key": "prepend-avatar",
  7401. "density": props.density,
  7402. "image": props.prependAvatar
  7403. }, null), props.prependIcon && createVNode(VIcon, {
  7404. "key": "prepend-icon",
  7405. "density": props.density,
  7406. "icon": props.prependIcon
  7407. }, null)]) : createVNode(VDefaultsProvider, {
  7408. "key": "prepend-defaults",
  7409. "disabled": !hasPrependMedia,
  7410. "defaults": {
  7411. VAvatar: {
  7412. density: props.density,
  7413. image: props.prependAvatar
  7414. },
  7415. VIcon: {
  7416. density: props.density,
  7417. icon: props.prependIcon
  7418. },
  7419. VListItemAction: {
  7420. start: true
  7421. }
  7422. }
  7423. }, {
  7424. default: () => [slots.prepend?.(slotProps.value)]
  7425. })]), createVNode("div", {
  7426. "class": "v-list-item__content",
  7427. "data-no-activator": ""
  7428. }, [hasTitle && createVNode(VListItemTitle, {
  7429. "key": "title"
  7430. }, {
  7431. default: () => [slots.title?.({
  7432. title: props.title
  7433. }) ?? props.title]
  7434. }), hasSubtitle && createVNode(VListItemSubtitle, {
  7435. "key": "subtitle"
  7436. }, {
  7437. default: () => [slots.subtitle?.({
  7438. subtitle: props.subtitle
  7439. }) ?? props.subtitle]
  7440. }), slots.default?.(slotProps.value)]), hasAppend && createVNode("div", {
  7441. "key": "append",
  7442. "class": "v-list-item__append"
  7443. }, [!slots.append ? createVNode(Fragment, null, [props.appendIcon && createVNode(VIcon, {
  7444. "key": "append-icon",
  7445. "density": props.density,
  7446. "icon": props.appendIcon
  7447. }, null), props.appendAvatar && createVNode(VAvatar, {
  7448. "key": "append-avatar",
  7449. "density": props.density,
  7450. "image": props.appendAvatar
  7451. }, null)]) : createVNode(VDefaultsProvider, {
  7452. "key": "append-defaults",
  7453. "disabled": !hasAppendMedia,
  7454. "defaults": {
  7455. VAvatar: {
  7456. density: props.density,
  7457. image: props.appendAvatar
  7458. },
  7459. VIcon: {
  7460. density: props.density,
  7461. icon: props.appendIcon
  7462. },
  7463. VListItemAction: {
  7464. end: true
  7465. }
  7466. }
  7467. }, {
  7468. default: () => [slots.append?.(slotProps.value)]
  7469. })])]
  7470. }), [[resolveDirective("ripple"), isClickable.value && props.ripple]]);
  7471. });
  7472. return {};
  7473. }
  7474. });
  7475. const makeVListSubheaderProps = propsFactory({
  7476. color: String,
  7477. inset: Boolean,
  7478. sticky: Boolean,
  7479. title: String,
  7480. ...makeComponentProps(),
  7481. ...makeTagProps()
  7482. }, 'VListSubheader');
  7483. const VListSubheader = genericComponent()({
  7484. name: 'VListSubheader',
  7485. props: makeVListSubheaderProps(),
  7486. setup(props, _ref) {
  7487. let {
  7488. slots
  7489. } = _ref;
  7490. const {
  7491. textColorClasses,
  7492. textColorStyles
  7493. } = useTextColor(toRef(props, 'color'));
  7494. useRender(() => {
  7495. const hasText = !!(slots.default || props.title);
  7496. return createVNode(props.tag, {
  7497. "class": ['v-list-subheader', {
  7498. 'v-list-subheader--inset': props.inset,
  7499. 'v-list-subheader--sticky': props.sticky
  7500. }, textColorClasses.value, props.class],
  7501. "style": [{
  7502. textColorStyles
  7503. }, props.style]
  7504. }, {
  7505. default: () => [hasText && createVNode("div", {
  7506. "class": "v-list-subheader__text"
  7507. }, [slots.default?.() ?? props.title])]
  7508. });
  7509. });
  7510. return {};
  7511. }
  7512. });
  7513. const makeVDividerProps = propsFactory({
  7514. color: String,
  7515. inset: Boolean,
  7516. length: [Number, String],
  7517. thickness: [Number, String],
  7518. vertical: Boolean,
  7519. ...makeComponentProps(),
  7520. ...makeThemeProps()
  7521. }, 'VDivider');
  7522. const VDivider = genericComponent()({
  7523. name: 'VDivider',
  7524. props: makeVDividerProps(),
  7525. setup(props, _ref) {
  7526. let {
  7527. attrs
  7528. } = _ref;
  7529. const {
  7530. themeClasses
  7531. } = provideTheme(props);
  7532. const {
  7533. textColorClasses,
  7534. textColorStyles
  7535. } = useTextColor(toRef(props, 'color'));
  7536. const dividerStyles = computed(() => {
  7537. const styles = {};
  7538. if (props.length) {
  7539. styles[props.vertical ? 'maxHeight' : 'maxWidth'] = convertToUnit(props.length);
  7540. }
  7541. if (props.thickness) {
  7542. styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
  7543. }
  7544. return styles;
  7545. });
  7546. useRender(() => createVNode("hr", {
  7547. "class": [{
  7548. 'v-divider': true,
  7549. 'v-divider--inset': props.inset,
  7550. 'v-divider--vertical': props.vertical
  7551. }, themeClasses.value, textColorClasses.value, props.class],
  7552. "style": [dividerStyles.value, textColorStyles.value, props.style],
  7553. "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
  7554. "role": `${attrs.role || 'separator'}`
  7555. }, null));
  7556. return {};
  7557. }
  7558. });
  7559. // Types
  7560. const makeVListChildrenProps = propsFactory({
  7561. items: Array
  7562. }, 'VListChildren');
  7563. const VListChildren = genericComponent()({
  7564. name: 'VListChildren',
  7565. props: makeVListChildrenProps(),
  7566. setup(props, _ref) {
  7567. let {
  7568. slots
  7569. } = _ref;
  7570. createList();
  7571. return () => slots.default?.() ?? props.items?.map(_ref2 => {
  7572. let {
  7573. children,
  7574. props: itemProps,
  7575. type,
  7576. raw: item
  7577. } = _ref2;
  7578. if (type === 'divider') {
  7579. return slots.divider?.({
  7580. props: itemProps
  7581. }) ?? createVNode(VDivider, itemProps, null);
  7582. }
  7583. if (type === 'subheader') {
  7584. return slots.subheader?.({
  7585. props: itemProps
  7586. }) ?? createVNode(VListSubheader, itemProps, null);
  7587. }
  7588. const slotsWithItem = {
  7589. subtitle: slots.subtitle ? slotProps => slots.subtitle?.({
  7590. ...slotProps,
  7591. item
  7592. }) : undefined,
  7593. prepend: slots.prepend ? slotProps => slots.prepend?.({
  7594. ...slotProps,
  7595. item
  7596. }) : undefined,
  7597. append: slots.append ? slotProps => slots.append?.({
  7598. ...slotProps,
  7599. item
  7600. }) : undefined,
  7601. title: slots.title ? slotProps => slots.title?.({
  7602. ...slotProps,
  7603. item
  7604. }) : undefined
  7605. };
  7606. const [listGroupProps, _1] = VListGroup.filterProps(itemProps);
  7607. return children ? createVNode(VListGroup, mergeProps({
  7608. "value": itemProps?.value
  7609. }, listGroupProps), {
  7610. activator: _ref3 => {
  7611. let {
  7612. props: activatorProps
  7613. } = _ref3;
  7614. return slots.header ? slots.header({
  7615. props: {
  7616. ...itemProps,
  7617. ...activatorProps
  7618. }
  7619. }) : createVNode(VListItem, mergeProps(itemProps, activatorProps), slotsWithItem);
  7620. },
  7621. default: () => createVNode(VListChildren, {
  7622. "items": children
  7623. }, slots)
  7624. }) : slots.item ? slots.item({
  7625. props: itemProps
  7626. }) : createVNode(VListItem, itemProps, slotsWithItem);
  7627. });
  7628. }
  7629. });
  7630. // Utilities
  7631. // Types
  7632. // Composables
  7633. const makeItemsProps = propsFactory({
  7634. items: {
  7635. type: Array,
  7636. default: () => []
  7637. },
  7638. itemTitle: {
  7639. type: [String, Array, Function],
  7640. default: 'title'
  7641. },
  7642. itemValue: {
  7643. type: [String, Array, Function],
  7644. default: 'value'
  7645. },
  7646. itemChildren: {
  7647. type: [Boolean, String, Array, Function],
  7648. default: 'children'
  7649. },
  7650. itemProps: {
  7651. type: [Boolean, String, Array, Function],
  7652. default: 'props'
  7653. },
  7654. returnObject: Boolean
  7655. }, 'list-items');
  7656. function transformItem$3(props, item) {
  7657. const title = getPropertyFromItem(item, props.itemTitle, item);
  7658. const value = props.returnObject ? item : getPropertyFromItem(item, props.itemValue, title);
  7659. const children = getPropertyFromItem(item, props.itemChildren);
  7660. const itemProps = props.itemProps === true ? typeof item === 'object' && item != null && !Array.isArray(item) ? 'children' in item ? pick(item, ['children'])[1] : item : undefined : getPropertyFromItem(item, props.itemProps);
  7661. const _props = {
  7662. title,
  7663. value,
  7664. ...itemProps
  7665. };
  7666. return {
  7667. title: String(_props.title ?? ''),
  7668. value: _props.value,
  7669. props: _props,
  7670. children: Array.isArray(children) ? transformItems$3(props, children) : undefined,
  7671. raw: item
  7672. };
  7673. }
  7674. function transformItems$3(props, items) {
  7675. const array = [];
  7676. for (const item of items) {
  7677. array.push(transformItem$3(props, item));
  7678. }
  7679. return array;
  7680. }
  7681. function useItems(props) {
  7682. const items = computed(() => transformItems$3(props, props.items));
  7683. return useTransformItems(items, value => transformItem$3(props, value));
  7684. }
  7685. function useTransformItems(items, transform) {
  7686. function transformIn(value) {
  7687. return value
  7688. // When the model value is null, returns an InternalItem based on null
  7689. // only if null is one of the items
  7690. .filter(v => v !== null || items.value.some(item => item.value === null)).map(v => {
  7691. const existingItem = items.value.find(item => deepEqual(v, item.value));
  7692. // Nullish existingItem means value is a custom input value from combobox
  7693. // In this case, use transformItem to create an InternalItem based on value
  7694. return existingItem ?? transform(v);
  7695. });
  7696. }
  7697. function transformOut(value) {
  7698. return value.map(_ref => {
  7699. let {
  7700. value
  7701. } = _ref;
  7702. return value;
  7703. });
  7704. }
  7705. return {
  7706. items,
  7707. transformIn,
  7708. transformOut
  7709. };
  7710. }
  7711. // Types
  7712. function isPrimitive(value) {
  7713. return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean';
  7714. }
  7715. function transformItem$2(props, item) {
  7716. const type = getPropertyFromItem(item, props.itemType, 'item');
  7717. const title = isPrimitive(item) ? item : getPropertyFromItem(item, props.itemTitle);
  7718. const value = getPropertyFromItem(item, props.itemValue, undefined);
  7719. const children = getPropertyFromItem(item, props.itemChildren);
  7720. const itemProps = props.itemProps === true ? pick(item, ['children'])[1] : getPropertyFromItem(item, props.itemProps);
  7721. const _props = {
  7722. title,
  7723. value,
  7724. ...itemProps
  7725. };
  7726. return {
  7727. type,
  7728. title: _props.title,
  7729. value: _props.value,
  7730. props: _props,
  7731. children: type === 'item' && children ? transformItems$2(props, children) : undefined,
  7732. raw: item
  7733. };
  7734. }
  7735. function transformItems$2(props, items) {
  7736. const array = [];
  7737. for (const item of items) {
  7738. array.push(transformItem$2(props, item));
  7739. }
  7740. return array;
  7741. }
  7742. function useListItems(props) {
  7743. const items = computed(() => transformItems$2(props, props.items));
  7744. return {
  7745. items
  7746. };
  7747. }
  7748. const makeVListProps = propsFactory({
  7749. baseColor: String,
  7750. /* @deprecated */
  7751. activeColor: String,
  7752. activeClass: String,
  7753. bgColor: String,
  7754. disabled: Boolean,
  7755. lines: {
  7756. type: [Boolean, String],
  7757. default: 'one'
  7758. },
  7759. nav: Boolean,
  7760. ...makeNestedProps({
  7761. selectStrategy: 'single-leaf',
  7762. openStrategy: 'list'
  7763. }),
  7764. ...makeBorderProps(),
  7765. ...makeComponentProps(),
  7766. ...makeDensityProps(),
  7767. ...makeDimensionProps(),
  7768. ...makeElevationProps(),
  7769. itemType: {
  7770. type: String,
  7771. default: 'type'
  7772. },
  7773. ...makeItemsProps(),
  7774. ...makeRoundedProps(),
  7775. ...makeTagProps(),
  7776. ...makeThemeProps(),
  7777. ...makeVariantProps({
  7778. variant: 'text'
  7779. })
  7780. }, 'VList');
  7781. const VList = genericComponent()({
  7782. name: 'VList',
  7783. props: makeVListProps(),
  7784. emits: {
  7785. 'update:selected': val => true,
  7786. 'update:opened': val => true,
  7787. 'click:open': value => true,
  7788. 'click:select': value => true
  7789. },
  7790. setup(props, _ref) {
  7791. let {
  7792. slots
  7793. } = _ref;
  7794. const {
  7795. items
  7796. } = useListItems(props);
  7797. const {
  7798. themeClasses
  7799. } = provideTheme(props);
  7800. const {
  7801. backgroundColorClasses,
  7802. backgroundColorStyles
  7803. } = useBackgroundColor(toRef(props, 'bgColor'));
  7804. const {
  7805. borderClasses
  7806. } = useBorder(props);
  7807. const {
  7808. densityClasses
  7809. } = useDensity(props);
  7810. const {
  7811. dimensionStyles
  7812. } = useDimension(props);
  7813. const {
  7814. elevationClasses
  7815. } = useElevation(props);
  7816. const {
  7817. roundedClasses
  7818. } = useRounded(props);
  7819. const {
  7820. open,
  7821. select
  7822. } = useNested(props);
  7823. const lineClasses = computed(() => props.lines ? `v-list--${props.lines}-line` : undefined);
  7824. const activeColor = toRef(props, 'activeColor');
  7825. const baseColor = toRef(props, 'baseColor');
  7826. const color = toRef(props, 'color');
  7827. createList();
  7828. provideDefaults({
  7829. VListGroup: {
  7830. activeColor,
  7831. baseColor,
  7832. color
  7833. },
  7834. VListItem: {
  7835. activeClass: toRef(props, 'activeClass'),
  7836. activeColor,
  7837. baseColor,
  7838. color,
  7839. density: toRef(props, 'density'),
  7840. disabled: toRef(props, 'disabled'),
  7841. lines: toRef(props, 'lines'),
  7842. nav: toRef(props, 'nav'),
  7843. variant: toRef(props, 'variant')
  7844. }
  7845. });
  7846. const isFocused = shallowRef(false);
  7847. const contentRef = ref();
  7848. function onFocusin(e) {
  7849. isFocused.value = true;
  7850. }
  7851. function onFocusout(e) {
  7852. isFocused.value = false;
  7853. }
  7854. function onFocus(e) {
  7855. if (!isFocused.value && !(e.relatedTarget && contentRef.value?.contains(e.relatedTarget))) focus();
  7856. }
  7857. function onKeydown(e) {
  7858. if (!contentRef.value) return;
  7859. if (e.key === 'ArrowDown') {
  7860. focus('next');
  7861. } else if (e.key === 'ArrowUp') {
  7862. focus('prev');
  7863. } else if (e.key === 'Home') {
  7864. focus('first');
  7865. } else if (e.key === 'End') {
  7866. focus('last');
  7867. } else {
  7868. return;
  7869. }
  7870. e.preventDefault();
  7871. }
  7872. function focus(location) {
  7873. if (contentRef.value) {
  7874. return focusChild(contentRef.value, location);
  7875. }
  7876. }
  7877. useRender(() => {
  7878. return createVNode(props.tag, {
  7879. "ref": contentRef,
  7880. "class": ['v-list', {
  7881. 'v-list--disabled': props.disabled,
  7882. 'v-list--nav': props.nav
  7883. }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, props.class],
  7884. "style": [backgroundColorStyles.value, dimensionStyles.value, props.style],
  7885. "tabindex": props.disabled || isFocused.value ? -1 : 0,
  7886. "role": "listbox",
  7887. "aria-activedescendant": undefined,
  7888. "onFocusin": onFocusin,
  7889. "onFocusout": onFocusout,
  7890. "onFocus": onFocus,
  7891. "onKeydown": onKeydown
  7892. }, {
  7893. default: () => [createVNode(VListChildren, {
  7894. "items": items.value
  7895. }, slots)]
  7896. });
  7897. });
  7898. return {
  7899. open,
  7900. select,
  7901. focus
  7902. };
  7903. }
  7904. });
  7905. // Utilities
  7906. const VListImg = createSimpleFunctional('v-list-img');
  7907. const makeVListItemActionProps = propsFactory({
  7908. start: Boolean,
  7909. end: Boolean,
  7910. ...makeComponentProps(),
  7911. ...makeTagProps()
  7912. }, 'VListItemAction');
  7913. const VListItemAction = genericComponent()({
  7914. name: 'VListItemAction',
  7915. props: makeVListItemActionProps(),
  7916. setup(props, _ref) {
  7917. let {
  7918. slots
  7919. } = _ref;
  7920. useRender(() => createVNode(props.tag, {
  7921. "class": ['v-list-item-action', {
  7922. 'v-list-item-action--start': props.start,
  7923. 'v-list-item-action--end': props.end
  7924. }, props.class],
  7925. "style": props.style
  7926. }, slots));
  7927. return {};
  7928. }
  7929. });
  7930. const makeVListItemMediaProps = propsFactory({
  7931. start: Boolean,
  7932. end: Boolean,
  7933. ...makeComponentProps(),
  7934. ...makeTagProps()
  7935. }, 'VListItemMedia');
  7936. const VListItemMedia = genericComponent()({
  7937. name: 'VListItemMedia',
  7938. props: makeVListItemMediaProps(),
  7939. setup(props, _ref) {
  7940. let {
  7941. slots
  7942. } = _ref;
  7943. useRender(() => {
  7944. return createVNode(props.tag, {
  7945. "class": ['v-list-item-media', {
  7946. 'v-list-item-media--start': props.start,
  7947. 'v-list-item-media--end': props.end
  7948. }, props.class],
  7949. "style": props.style
  7950. }, slots);
  7951. });
  7952. return {};
  7953. }
  7954. });
  7955. // Types
  7956. /** Convert a point in local space to viewport space */
  7957. function elementToViewport(point, offset) {
  7958. return {
  7959. x: point.x + offset.x,
  7960. y: point.y + offset.y
  7961. };
  7962. }
  7963. /** Get the difference between two points */
  7964. function getOffset$1(a, b) {
  7965. return {
  7966. x: a.x - b.x,
  7967. y: a.y - b.y
  7968. };
  7969. }
  7970. /** Convert an anchor object to a point in local space */
  7971. function anchorToPoint(anchor, box) {
  7972. if (anchor.side === 'top' || anchor.side === 'bottom') {
  7973. const {
  7974. side,
  7975. align
  7976. } = anchor;
  7977. const x = align === 'left' ? 0 : align === 'center' ? box.width / 2 : align === 'right' ? box.width : align;
  7978. const y = side === 'top' ? 0 : side === 'bottom' ? box.height : side;
  7979. return elementToViewport({
  7980. x,
  7981. y
  7982. }, box);
  7983. } else if (anchor.side === 'left' || anchor.side === 'right') {
  7984. const {
  7985. side,
  7986. align
  7987. } = anchor;
  7988. const x = side === 'left' ? 0 : side === 'right' ? box.width : side;
  7989. const y = align === 'top' ? 0 : align === 'center' ? box.height / 2 : align === 'bottom' ? box.height : align;
  7990. return elementToViewport({
  7991. x,
  7992. y
  7993. }, box);
  7994. }
  7995. return elementToViewport({
  7996. x: box.width / 2,
  7997. y: box.height / 2
  7998. }, box);
  7999. }
  8000. // Composables
  8001. // Types
  8002. const locationStrategies = {
  8003. static: staticLocationStrategy,
  8004. // specific viewport position, usually centered
  8005. connected: connectedLocationStrategy // connected to a certain element
  8006. };
  8007. const makeLocationStrategyProps = propsFactory({
  8008. locationStrategy: {
  8009. type: [String, Function],
  8010. default: 'static',
  8011. validator: val => typeof val === 'function' || val in locationStrategies
  8012. },
  8013. location: {
  8014. type: String,
  8015. default: 'bottom'
  8016. },
  8017. origin: {
  8018. type: String,
  8019. default: 'auto'
  8020. },
  8021. offset: [Number, String, Array]
  8022. }, 'VOverlay-location-strategies');
  8023. function useLocationStrategies(props, data) {
  8024. const contentStyles = ref({});
  8025. const updateLocation = ref();
  8026. if (IN_BROWSER) {
  8027. useToggleScope(() => !!(data.isActive.value && props.locationStrategy), reset => {
  8028. watch(() => props.locationStrategy, reset);
  8029. onScopeDispose(() => {
  8030. updateLocation.value = undefined;
  8031. });
  8032. if (typeof props.locationStrategy === 'function') {
  8033. updateLocation.value = props.locationStrategy(data, props, contentStyles)?.updateLocation;
  8034. } else {
  8035. updateLocation.value = locationStrategies[props.locationStrategy](data, props, contentStyles)?.updateLocation;
  8036. }
  8037. });
  8038. window.addEventListener('resize', onResize, {
  8039. passive: true
  8040. });
  8041. onScopeDispose(() => {
  8042. window.removeEventListener('resize', onResize);
  8043. updateLocation.value = undefined;
  8044. });
  8045. }
  8046. function onResize(e) {
  8047. updateLocation.value?.(e);
  8048. }
  8049. return {
  8050. contentStyles,
  8051. updateLocation
  8052. };
  8053. }
  8054. function staticLocationStrategy() {
  8055. // TODO
  8056. }
  8057. /** Get size of element ignoring max-width/max-height */
  8058. function getIntrinsicSize(el, isRtl) {
  8059. // const scrollables = new Map<Element, [number, number]>()
  8060. // el.querySelectorAll('*').forEach(el => {
  8061. // const x = el.scrollLeft
  8062. // const y = el.scrollTop
  8063. // if (x || y) {
  8064. // scrollables.set(el, [x, y])
  8065. // }
  8066. // })
  8067. // const initialMaxWidth = el.style.maxWidth
  8068. // const initialMaxHeight = el.style.maxHeight
  8069. // el.style.removeProperty('max-width')
  8070. // el.style.removeProperty('max-height')
  8071. if (isRtl) {
  8072. el.style.removeProperty('left');
  8073. } else {
  8074. el.style.removeProperty('right');
  8075. }
  8076. /* eslint-disable-next-line sonarjs/prefer-immediate-return */
  8077. const contentBox = nullifyTransforms(el);
  8078. if (isRtl) {
  8079. contentBox.x += parseFloat(el.style.right || 0);
  8080. } else {
  8081. contentBox.x -= parseFloat(el.style.left || 0);
  8082. }
  8083. contentBox.y -= parseFloat(el.style.top || 0);
  8084. // el.style.maxWidth = initialMaxWidth
  8085. // el.style.maxHeight = initialMaxHeight
  8086. // scrollables.forEach((position, el) => {
  8087. // el.scrollTo(...position)
  8088. // })
  8089. return contentBox;
  8090. }
  8091. function connectedLocationStrategy(data, props, contentStyles) {
  8092. const activatorFixed = isFixedPosition(data.activatorEl.value);
  8093. if (activatorFixed) {
  8094. Object.assign(contentStyles.value, {
  8095. position: 'fixed',
  8096. top: 0,
  8097. [data.isRtl.value ? 'right' : 'left']: 0
  8098. });
  8099. }
  8100. const {
  8101. preferredAnchor,
  8102. preferredOrigin
  8103. } = destructComputed(() => {
  8104. const parsedAnchor = parseAnchor(props.location, data.isRtl.value);
  8105. const parsedOrigin = props.origin === 'overlap' ? parsedAnchor : props.origin === 'auto' ? flipSide(parsedAnchor) : parseAnchor(props.origin, data.isRtl.value);
  8106. // Some combinations of props may produce an invalid origin
  8107. if (parsedAnchor.side === parsedOrigin.side && parsedAnchor.align === flipAlign(parsedOrigin).align) {
  8108. return {
  8109. preferredAnchor: flipCorner(parsedAnchor),
  8110. preferredOrigin: flipCorner(parsedOrigin)
  8111. };
  8112. } else {
  8113. return {
  8114. preferredAnchor: parsedAnchor,
  8115. preferredOrigin: parsedOrigin
  8116. };
  8117. }
  8118. });
  8119. const [minWidth, minHeight, maxWidth, maxHeight] = ['minWidth', 'minHeight', 'maxWidth', 'maxHeight'].map(key => {
  8120. return computed(() => {
  8121. const val = parseFloat(props[key]);
  8122. return isNaN(val) ? Infinity : val;
  8123. });
  8124. });
  8125. const offset = computed(() => {
  8126. if (Array.isArray(props.offset)) {
  8127. return props.offset;
  8128. }
  8129. if (typeof props.offset === 'string') {
  8130. const offset = props.offset.split(' ').map(parseFloat);
  8131. if (offset.length < 2) offset.push(0);
  8132. return offset;
  8133. }
  8134. return typeof props.offset === 'number' ? [props.offset, 0] : [0, 0];
  8135. });
  8136. let observe = false;
  8137. const observer = new ResizeObserver(() => {
  8138. if (observe) updateLocation();
  8139. });
  8140. watch([data.activatorEl, data.contentEl], (_ref, _ref2) => {
  8141. let [newActivatorEl, newContentEl] = _ref;
  8142. let [oldActivatorEl, oldContentEl] = _ref2;
  8143. if (oldActivatorEl) observer.unobserve(oldActivatorEl);
  8144. if (newActivatorEl) observer.observe(newActivatorEl);
  8145. if (oldContentEl) observer.unobserve(oldContentEl);
  8146. if (newContentEl) observer.observe(newContentEl);
  8147. }, {
  8148. immediate: true
  8149. });
  8150. onScopeDispose(() => {
  8151. observer.disconnect();
  8152. });
  8153. // eslint-disable-next-line max-statements
  8154. function updateLocation() {
  8155. observe = false;
  8156. requestAnimationFrame(() => {
  8157. requestAnimationFrame(() => observe = true);
  8158. });
  8159. if (!data.activatorEl.value || !data.contentEl.value) return;
  8160. const targetBox = data.activatorEl.value.getBoundingClientRect();
  8161. const contentBox = getIntrinsicSize(data.contentEl.value, data.isRtl.value);
  8162. const scrollParents = getScrollParents(data.contentEl.value);
  8163. const viewportMargin = 12;
  8164. if (!scrollParents.length) {
  8165. scrollParents.push(document.documentElement);
  8166. if (!(data.contentEl.value.style.top && data.contentEl.value.style.left)) {
  8167. contentBox.x -= parseFloat(document.documentElement.style.getPropertyValue('--v-body-scroll-x') || 0);
  8168. contentBox.y -= parseFloat(document.documentElement.style.getPropertyValue('--v-body-scroll-y') || 0);
  8169. }
  8170. }
  8171. const viewport = scrollParents.reduce((box, el) => {
  8172. const rect = el.getBoundingClientRect();
  8173. const scrollBox = new Box({
  8174. x: el === document.documentElement ? 0 : rect.x,
  8175. y: el === document.documentElement ? 0 : rect.y,
  8176. width: el.clientWidth,
  8177. height: el.clientHeight
  8178. });
  8179. if (box) {
  8180. return new Box({
  8181. x: Math.max(box.left, scrollBox.left),
  8182. y: Math.max(box.top, scrollBox.top),
  8183. width: Math.min(box.right, scrollBox.right) - Math.max(box.left, scrollBox.left),
  8184. height: Math.min(box.bottom, scrollBox.bottom) - Math.max(box.top, scrollBox.top)
  8185. });
  8186. }
  8187. return scrollBox;
  8188. }, undefined);
  8189. viewport.x += viewportMargin;
  8190. viewport.y += viewportMargin;
  8191. viewport.width -= viewportMargin * 2;
  8192. viewport.height -= viewportMargin * 2;
  8193. let placement = {
  8194. anchor: preferredAnchor.value,
  8195. origin: preferredOrigin.value
  8196. };
  8197. function checkOverflow(_placement) {
  8198. const box = new Box(contentBox);
  8199. const targetPoint = anchorToPoint(_placement.anchor, targetBox);
  8200. const contentPoint = anchorToPoint(_placement.origin, box);
  8201. let {
  8202. x,
  8203. y
  8204. } = getOffset$1(targetPoint, contentPoint);
  8205. switch (_placement.anchor.side) {
  8206. case 'top':
  8207. y -= offset.value[0];
  8208. break;
  8209. case 'bottom':
  8210. y += offset.value[0];
  8211. break;
  8212. case 'left':
  8213. x -= offset.value[0];
  8214. break;
  8215. case 'right':
  8216. x += offset.value[0];
  8217. break;
  8218. }
  8219. switch (_placement.anchor.align) {
  8220. case 'top':
  8221. y -= offset.value[1];
  8222. break;
  8223. case 'bottom':
  8224. y += offset.value[1];
  8225. break;
  8226. case 'left':
  8227. x -= offset.value[1];
  8228. break;
  8229. case 'right':
  8230. x += offset.value[1];
  8231. break;
  8232. }
  8233. box.x += x;
  8234. box.y += y;
  8235. box.width = Math.min(box.width, maxWidth.value);
  8236. box.height = Math.min(box.height, maxHeight.value);
  8237. const overflows = getOverflow(box, viewport);
  8238. return {
  8239. overflows,
  8240. x,
  8241. y
  8242. };
  8243. }
  8244. let x = 0;
  8245. let y = 0;
  8246. const available = {
  8247. x: 0,
  8248. y: 0
  8249. };
  8250. const flipped = {
  8251. x: false,
  8252. y: false
  8253. };
  8254. let resets = -1;
  8255. while (true) {
  8256. if (resets++ > 10) {
  8257. consoleError('Infinite loop detected in connectedLocationStrategy');
  8258. break;
  8259. }
  8260. const {
  8261. x: _x,
  8262. y: _y,
  8263. overflows
  8264. } = checkOverflow(placement);
  8265. x += _x;
  8266. y += _y;
  8267. contentBox.x += _x;
  8268. contentBox.y += _y;
  8269. // flip
  8270. {
  8271. const axis = getAxis(placement.anchor);
  8272. const hasOverflowX = overflows.x.before || overflows.x.after;
  8273. const hasOverflowY = overflows.y.before || overflows.y.after;
  8274. let reset = false;
  8275. ['x', 'y'].forEach(key => {
  8276. if (key === 'x' && hasOverflowX && !flipped.x || key === 'y' && hasOverflowY && !flipped.y) {
  8277. const newPlacement = {
  8278. anchor: {
  8279. ...placement.anchor
  8280. },
  8281. origin: {
  8282. ...placement.origin
  8283. }
  8284. };
  8285. const flip = key === 'x' ? axis === 'y' ? flipAlign : flipSide : axis === 'y' ? flipSide : flipAlign;
  8286. newPlacement.anchor = flip(newPlacement.anchor);
  8287. newPlacement.origin = flip(newPlacement.origin);
  8288. const {
  8289. overflows: newOverflows
  8290. } = checkOverflow(newPlacement);
  8291. 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) {
  8292. placement = newPlacement;
  8293. reset = flipped[key] = true;
  8294. }
  8295. }
  8296. });
  8297. if (reset) continue;
  8298. }
  8299. // shift
  8300. if (overflows.x.before) {
  8301. x += overflows.x.before;
  8302. contentBox.x += overflows.x.before;
  8303. }
  8304. if (overflows.x.after) {
  8305. x -= overflows.x.after;
  8306. contentBox.x -= overflows.x.after;
  8307. }
  8308. if (overflows.y.before) {
  8309. y += overflows.y.before;
  8310. contentBox.y += overflows.y.before;
  8311. }
  8312. if (overflows.y.after) {
  8313. y -= overflows.y.after;
  8314. contentBox.y -= overflows.y.after;
  8315. }
  8316. // size
  8317. {
  8318. const overflows = getOverflow(contentBox, viewport);
  8319. available.x = viewport.width - overflows.x.before - overflows.x.after;
  8320. available.y = viewport.height - overflows.y.before - overflows.y.after;
  8321. x += overflows.x.before;
  8322. contentBox.x += overflows.x.before;
  8323. y += overflows.y.before;
  8324. contentBox.y += overflows.y.before;
  8325. }
  8326. break;
  8327. }
  8328. const axis = getAxis(placement.anchor);
  8329. Object.assign(contentStyles.value, {
  8330. '--v-overlay-anchor-origin': `${placement.anchor.side} ${placement.anchor.align}`,
  8331. transformOrigin: `${placement.origin.side} ${placement.origin.align}`,
  8332. // transform: `translate(${pixelRound(x)}px, ${pixelRound(y)}px)`,
  8333. top: convertToUnit(pixelRound(y)),
  8334. left: data.isRtl.value ? undefined : convertToUnit(pixelRound(x)),
  8335. right: data.isRtl.value ? convertToUnit(pixelRound(-x)) : undefined,
  8336. minWidth: convertToUnit(axis === 'y' ? Math.min(minWidth.value, targetBox.width) : minWidth.value),
  8337. maxWidth: convertToUnit(pixelCeil(clamp(available.x, minWidth.value === Infinity ? 0 : minWidth.value, maxWidth.value))),
  8338. maxHeight: convertToUnit(pixelCeil(clamp(available.y, minHeight.value === Infinity ? 0 : minHeight.value, maxHeight.value)))
  8339. });
  8340. return {
  8341. available,
  8342. contentBox
  8343. };
  8344. }
  8345. watch(() => [preferredAnchor.value, preferredOrigin.value, props.offset, props.minWidth, props.minHeight, props.maxWidth, props.maxHeight], () => updateLocation());
  8346. nextTick(() => {
  8347. const result = updateLocation();
  8348. // TODO: overflowing content should only require a single updateLocation call
  8349. // Icky hack to make sure the content is positioned consistently
  8350. if (!result) return;
  8351. const {
  8352. available,
  8353. contentBox
  8354. } = result;
  8355. if (contentBox.height > available.y) {
  8356. requestAnimationFrame(() => {
  8357. updateLocation();
  8358. requestAnimationFrame(() => {
  8359. updateLocation();
  8360. });
  8361. });
  8362. }
  8363. });
  8364. return {
  8365. updateLocation
  8366. };
  8367. }
  8368. function pixelRound(val) {
  8369. return Math.round(val * devicePixelRatio) / devicePixelRatio;
  8370. }
  8371. function pixelCeil(val) {
  8372. return Math.ceil(val * devicePixelRatio) / devicePixelRatio;
  8373. }
  8374. let clean = true;
  8375. const frames = [];
  8376. /**
  8377. * Schedule a task to run in an animation frame on its own
  8378. * This is useful for heavy tasks that may cause jank if all ran together
  8379. */
  8380. function requestNewFrame(cb) {
  8381. if (!clean || frames.length) {
  8382. frames.push(cb);
  8383. run();
  8384. } else {
  8385. clean = false;
  8386. cb();
  8387. run();
  8388. }
  8389. }
  8390. let raf = -1;
  8391. function run() {
  8392. cancelAnimationFrame(raf);
  8393. raf = requestAnimationFrame(() => {
  8394. const frame = frames.shift();
  8395. if (frame) frame();
  8396. if (frames.length) run();else clean = true;
  8397. });
  8398. }
  8399. // Utilities
  8400. // Types
  8401. const scrollStrategies = {
  8402. none: null,
  8403. close: closeScrollStrategy,
  8404. block: blockScrollStrategy,
  8405. reposition: repositionScrollStrategy
  8406. };
  8407. const makeScrollStrategyProps = propsFactory({
  8408. scrollStrategy: {
  8409. type: [String, Function],
  8410. default: 'block',
  8411. validator: val => typeof val === 'function' || val in scrollStrategies
  8412. }
  8413. }, 'VOverlay-scroll-strategies');
  8414. function useScrollStrategies(props, data) {
  8415. if (!IN_BROWSER) return;
  8416. let scope;
  8417. watchEffect(async () => {
  8418. scope?.stop();
  8419. if (!(data.isActive.value && props.scrollStrategy)) return;
  8420. scope = effectScope();
  8421. await nextTick();
  8422. scope.active && scope.run(() => {
  8423. if (typeof props.scrollStrategy === 'function') {
  8424. props.scrollStrategy(data, props, scope);
  8425. } else {
  8426. scrollStrategies[props.scrollStrategy]?.(data, props, scope);
  8427. }
  8428. });
  8429. });
  8430. onScopeDispose(() => {
  8431. scope?.stop();
  8432. });
  8433. }
  8434. function closeScrollStrategy(data) {
  8435. function onScroll(e) {
  8436. data.isActive.value = false;
  8437. }
  8438. bindScroll(data.activatorEl.value ?? data.contentEl.value, onScroll);
  8439. }
  8440. function blockScrollStrategy(data, props) {
  8441. const offsetParent = data.root.value?.offsetParent;
  8442. const scrollElements = [...new Set([...getScrollParents(data.activatorEl.value, props.contained ? offsetParent : undefined), ...getScrollParents(data.contentEl.value, props.contained ? offsetParent : undefined)])].filter(el => !el.classList.contains('v-overlay-scroll-blocked'));
  8443. const scrollbarWidth = window.innerWidth - document.documentElement.offsetWidth;
  8444. const scrollableParent = (el => hasScrollbar(el) && el)(offsetParent || document.documentElement);
  8445. if (scrollableParent) {
  8446. data.root.value.classList.add('v-overlay--scroll-blocked');
  8447. }
  8448. scrollElements.forEach((el, i) => {
  8449. el.style.setProperty('--v-body-scroll-x', convertToUnit(-el.scrollLeft));
  8450. el.style.setProperty('--v-body-scroll-y', convertToUnit(-el.scrollTop));
  8451. if (el !== document.documentElement) {
  8452. el.style.setProperty('--v-scrollbar-offset', convertToUnit(scrollbarWidth));
  8453. }
  8454. el.classList.add('v-overlay-scroll-blocked');
  8455. });
  8456. onScopeDispose(() => {
  8457. scrollElements.forEach((el, i) => {
  8458. const x = parseFloat(el.style.getPropertyValue('--v-body-scroll-x'));
  8459. const y = parseFloat(el.style.getPropertyValue('--v-body-scroll-y'));
  8460. el.style.removeProperty('--v-body-scroll-x');
  8461. el.style.removeProperty('--v-body-scroll-y');
  8462. el.style.removeProperty('--v-scrollbar-offset');
  8463. el.classList.remove('v-overlay-scroll-blocked');
  8464. el.scrollLeft = -x;
  8465. el.scrollTop = -y;
  8466. });
  8467. if (scrollableParent) {
  8468. data.root.value.classList.remove('v-overlay--scroll-blocked');
  8469. }
  8470. });
  8471. }
  8472. function repositionScrollStrategy(data, props, scope) {
  8473. let slow = false;
  8474. let raf = -1;
  8475. let ric = -1;
  8476. function update(e) {
  8477. requestNewFrame(() => {
  8478. const start = performance.now();
  8479. data.updateLocation.value?.(e);
  8480. const time = performance.now() - start;
  8481. slow = time / (1000 / 60) > 2;
  8482. });
  8483. }
  8484. ric = (typeof requestIdleCallback === 'undefined' ? cb => cb() : requestIdleCallback)(() => {
  8485. scope.run(() => {
  8486. bindScroll(data.activatorEl.value ?? data.contentEl.value, e => {
  8487. if (slow) {
  8488. // If the position calculation is slow,
  8489. // defer updates until scrolling is finished.
  8490. // Browsers usually fire one scroll event per frame so
  8491. // we just wait until we've got two frames without an event
  8492. cancelAnimationFrame(raf);
  8493. raf = requestAnimationFrame(() => {
  8494. raf = requestAnimationFrame(() => {
  8495. update(e);
  8496. });
  8497. });
  8498. } else {
  8499. update(e);
  8500. }
  8501. });
  8502. });
  8503. });
  8504. onScopeDispose(() => {
  8505. typeof cancelIdleCallback !== 'undefined' && cancelIdleCallback(ric);
  8506. cancelAnimationFrame(raf);
  8507. });
  8508. }
  8509. /** @private */
  8510. function bindScroll(el, onScroll) {
  8511. const scrollElements = [document, ...getScrollParents(el)];
  8512. scrollElements.forEach(el => {
  8513. el.addEventListener('scroll', onScroll, {
  8514. passive: true
  8515. });
  8516. });
  8517. onScopeDispose(() => {
  8518. scrollElements.forEach(el => {
  8519. el.removeEventListener('scroll', onScroll);
  8520. });
  8521. });
  8522. }
  8523. // Types
  8524. const VMenuSymbol = Symbol.for('vuetify:v-menu');
  8525. // Utilities
  8526. // Types
  8527. // Composables
  8528. const makeDelayProps = propsFactory({
  8529. closeDelay: [Number, String],
  8530. openDelay: [Number, String]
  8531. }, 'delay');
  8532. function useDelay(props, cb) {
  8533. const delays = {};
  8534. const runDelayFactory = prop => () => {
  8535. // istanbul ignore next
  8536. if (!IN_BROWSER) return Promise.resolve(true);
  8537. const active = prop === 'openDelay';
  8538. delays.closeDelay && window.clearTimeout(delays.closeDelay);
  8539. delete delays.closeDelay;
  8540. delays.openDelay && window.clearTimeout(delays.openDelay);
  8541. delete delays.openDelay;
  8542. return new Promise(resolve => {
  8543. const delay = parseInt(props[prop] ?? 0, 10);
  8544. delays[prop] = window.setTimeout(() => {
  8545. cb?.(active);
  8546. resolve(active);
  8547. }, delay);
  8548. });
  8549. };
  8550. return {
  8551. runCloseDelay: runDelayFactory('closeDelay'),
  8552. runOpenDelay: runDelayFactory('openDelay')
  8553. };
  8554. }
  8555. // Components
  8556. // Types
  8557. const makeActivatorProps = propsFactory({
  8558. activator: [String, Object],
  8559. activatorProps: {
  8560. type: Object,
  8561. default: () => ({})
  8562. },
  8563. openOnClick: {
  8564. type: Boolean,
  8565. default: undefined
  8566. },
  8567. openOnHover: Boolean,
  8568. openOnFocus: {
  8569. type: Boolean,
  8570. default: undefined
  8571. },
  8572. closeOnContentClick: Boolean,
  8573. ...makeDelayProps()
  8574. }, 'VOverlay-activator');
  8575. function useActivator(props, _ref) {
  8576. let {
  8577. isActive,
  8578. isTop
  8579. } = _ref;
  8580. const activatorEl = ref();
  8581. let isHovered = false;
  8582. let isFocused = false;
  8583. let firstEnter = true;
  8584. const openOnFocus = computed(() => props.openOnFocus || props.openOnFocus == null && props.openOnHover);
  8585. const openOnClick = computed(() => props.openOnClick || props.openOnClick == null && !props.openOnHover && !openOnFocus.value);
  8586. const {
  8587. runOpenDelay,
  8588. runCloseDelay
  8589. } = useDelay(props, value => {
  8590. if (value === (props.openOnHover && isHovered || openOnFocus.value && isFocused) && !(props.openOnHover && isActive.value && !isTop.value)) {
  8591. if (isActive.value !== value) {
  8592. firstEnter = true;
  8593. }
  8594. isActive.value = value;
  8595. }
  8596. });
  8597. const availableEvents = {
  8598. onClick: e => {
  8599. e.stopPropagation();
  8600. activatorEl.value = e.currentTarget || e.target;
  8601. isActive.value = !isActive.value;
  8602. },
  8603. onMouseenter: e => {
  8604. if (e.sourceCapabilities?.firesTouchEvents) return;
  8605. isHovered = true;
  8606. activatorEl.value = e.currentTarget || e.target;
  8607. runOpenDelay();
  8608. },
  8609. onMouseleave: e => {
  8610. isHovered = false;
  8611. runCloseDelay();
  8612. },
  8613. onFocus: e => {
  8614. if (matchesSelector(e.target, ':focus-visible') === false) return;
  8615. isFocused = true;
  8616. e.stopPropagation();
  8617. activatorEl.value = e.currentTarget || e.target;
  8618. runOpenDelay();
  8619. },
  8620. onBlur: e => {
  8621. isFocused = false;
  8622. e.stopPropagation();
  8623. runCloseDelay();
  8624. }
  8625. };
  8626. const activatorEvents = computed(() => {
  8627. const events = {};
  8628. if (openOnClick.value) {
  8629. events.onClick = availableEvents.onClick;
  8630. }
  8631. if (props.openOnHover) {
  8632. events.onMouseenter = availableEvents.onMouseenter;
  8633. events.onMouseleave = availableEvents.onMouseleave;
  8634. }
  8635. if (openOnFocus.value) {
  8636. events.onFocus = availableEvents.onFocus;
  8637. events.onBlur = availableEvents.onBlur;
  8638. }
  8639. return events;
  8640. });
  8641. const contentEvents = computed(() => {
  8642. const events = {};
  8643. if (props.openOnHover) {
  8644. events.onMouseenter = () => {
  8645. isHovered = true;
  8646. runOpenDelay();
  8647. };
  8648. events.onMouseleave = () => {
  8649. isHovered = false;
  8650. runCloseDelay();
  8651. };
  8652. }
  8653. if (openOnFocus.value) {
  8654. events.onFocusin = () => {
  8655. isFocused = true;
  8656. runOpenDelay();
  8657. };
  8658. events.onFocusout = () => {
  8659. isFocused = false;
  8660. runCloseDelay();
  8661. };
  8662. }
  8663. if (props.closeOnContentClick) {
  8664. const menu = inject$1(VMenuSymbol, null);
  8665. events.onClick = () => {
  8666. isActive.value = false;
  8667. menu?.closeParents();
  8668. };
  8669. }
  8670. return events;
  8671. });
  8672. const scrimEvents = computed(() => {
  8673. const events = {};
  8674. if (props.openOnHover) {
  8675. events.onMouseenter = () => {
  8676. if (firstEnter) {
  8677. isHovered = true;
  8678. firstEnter = false;
  8679. runOpenDelay();
  8680. }
  8681. };
  8682. events.onMouseleave = () => {
  8683. isHovered = false;
  8684. runCloseDelay();
  8685. };
  8686. }
  8687. return events;
  8688. });
  8689. watch(isTop, val => {
  8690. if (val && (props.openOnHover && !isHovered && (!openOnFocus.value || !isFocused) || openOnFocus.value && !isFocused && (!props.openOnHover || !isHovered))) {
  8691. isActive.value = false;
  8692. }
  8693. });
  8694. const activatorRef = ref();
  8695. watchEffect(() => {
  8696. if (!activatorRef.value) return;
  8697. nextTick(() => {
  8698. activatorEl.value = refElement(activatorRef.value);
  8699. });
  8700. });
  8701. const vm = getCurrentInstance('useActivator');
  8702. let scope;
  8703. watch(() => !!props.activator, val => {
  8704. if (val && IN_BROWSER) {
  8705. scope = effectScope();
  8706. scope.run(() => {
  8707. _useActivator(props, vm, {
  8708. activatorEl,
  8709. activatorEvents
  8710. });
  8711. });
  8712. } else if (scope) {
  8713. scope.stop();
  8714. }
  8715. }, {
  8716. flush: 'post',
  8717. immediate: true
  8718. });
  8719. onScopeDispose(() => {
  8720. scope?.stop();
  8721. });
  8722. return {
  8723. activatorEl,
  8724. activatorRef,
  8725. activatorEvents,
  8726. contentEvents,
  8727. scrimEvents
  8728. };
  8729. }
  8730. function _useActivator(props, vm, _ref2) {
  8731. let {
  8732. activatorEl,
  8733. activatorEvents
  8734. } = _ref2;
  8735. watch(() => props.activator, (val, oldVal) => {
  8736. if (oldVal && val !== oldVal) {
  8737. const activator = getActivator(oldVal);
  8738. activator && unbindActivatorProps(activator);
  8739. }
  8740. if (val) {
  8741. nextTick(() => bindActivatorProps());
  8742. }
  8743. }, {
  8744. immediate: true
  8745. });
  8746. watch(() => props.activatorProps, () => {
  8747. bindActivatorProps();
  8748. });
  8749. onScopeDispose(() => {
  8750. unbindActivatorProps();
  8751. });
  8752. function bindActivatorProps() {
  8753. let el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getActivator();
  8754. let _props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.activatorProps;
  8755. if (!el) return;
  8756. bindProps(el, mergeProps(activatorEvents.value, _props));
  8757. }
  8758. function unbindActivatorProps() {
  8759. let el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getActivator();
  8760. let _props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.activatorProps;
  8761. if (!el) return;
  8762. unbindProps(el, mergeProps(activatorEvents.value, _props));
  8763. }
  8764. function getActivator() {
  8765. let selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : props.activator;
  8766. let activator;
  8767. if (selector) {
  8768. if (selector === 'parent') {
  8769. let el = vm?.proxy?.$el?.parentNode;
  8770. while (el.hasAttribute('data-no-activator')) {
  8771. el = el.parentNode;
  8772. }
  8773. activator = el;
  8774. } else if (typeof selector === 'string') {
  8775. // Selector
  8776. activator = document.querySelector(selector);
  8777. } else if ('$el' in selector) {
  8778. // Component (ref)
  8779. activator = selector.$el;
  8780. } else {
  8781. // HTMLElement | Element
  8782. activator = selector;
  8783. }
  8784. }
  8785. // The activator should only be a valid element (Ignore comments and text nodes)
  8786. activatorEl.value = activator?.nodeType === Node.ELEMENT_NODE ? activator : null;
  8787. return activatorEl.value;
  8788. }
  8789. }
  8790. // Utilities
  8791. // Types
  8792. const breakpoints = ['sm', 'md', 'lg', 'xl', 'xxl']; // no xs
  8793. const DisplaySymbol = Symbol.for('vuetify:display');
  8794. const defaultDisplayOptions = {
  8795. mobileBreakpoint: 'lg',
  8796. thresholds: {
  8797. xs: 0,
  8798. sm: 600,
  8799. md: 960,
  8800. lg: 1280,
  8801. xl: 1920,
  8802. xxl: 2560
  8803. }
  8804. };
  8805. const parseDisplayOptions = function () {
  8806. let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultDisplayOptions;
  8807. return mergeDeep(defaultDisplayOptions, options);
  8808. };
  8809. function getClientWidth(ssr) {
  8810. return IN_BROWSER && !ssr ? window.innerWidth : typeof ssr === 'object' && ssr.clientWidth || 0;
  8811. }
  8812. function getClientHeight(ssr) {
  8813. return IN_BROWSER && !ssr ? window.innerHeight : typeof ssr === 'object' && ssr.clientHeight || 0;
  8814. }
  8815. function getPlatform(ssr) {
  8816. const userAgent = IN_BROWSER && !ssr ? window.navigator.userAgent : 'ssr';
  8817. function match(regexp) {
  8818. return Boolean(userAgent.match(regexp));
  8819. }
  8820. const android = match(/android/i);
  8821. const ios = match(/iphone|ipad|ipod/i);
  8822. const cordova = match(/cordova/i);
  8823. const electron = match(/electron/i);
  8824. const chrome = match(/chrome/i);
  8825. const edge = match(/edge/i);
  8826. const firefox = match(/firefox/i);
  8827. const opera = match(/opera/i);
  8828. const win = match(/win/i);
  8829. const mac = match(/mac/i);
  8830. const linux = match(/linux/i);
  8831. return {
  8832. android,
  8833. ios,
  8834. cordova,
  8835. electron,
  8836. chrome,
  8837. edge,
  8838. firefox,
  8839. opera,
  8840. win,
  8841. mac,
  8842. linux,
  8843. touch: SUPPORTS_TOUCH,
  8844. ssr: userAgent === 'ssr'
  8845. };
  8846. }
  8847. function createDisplay(options, ssr) {
  8848. const {
  8849. thresholds,
  8850. mobileBreakpoint
  8851. } = parseDisplayOptions(options);
  8852. const height = shallowRef(getClientHeight(ssr));
  8853. const platform = shallowRef(getPlatform(ssr));
  8854. const state = reactive({});
  8855. const width = shallowRef(getClientWidth(ssr));
  8856. function updateSize() {
  8857. height.value = getClientHeight();
  8858. width.value = getClientWidth();
  8859. }
  8860. function update() {
  8861. updateSize();
  8862. platform.value = getPlatform();
  8863. }
  8864. // eslint-disable-next-line max-statements
  8865. watchEffect(() => {
  8866. const xs = width.value < thresholds.sm;
  8867. const sm = width.value < thresholds.md && !xs;
  8868. const md = width.value < thresholds.lg && !(sm || xs);
  8869. const lg = width.value < thresholds.xl && !(md || sm || xs);
  8870. const xl = width.value < thresholds.xxl && !(lg || md || sm || xs);
  8871. const xxl = width.value >= thresholds.xxl;
  8872. const name = xs ? 'xs' : sm ? 'sm' : md ? 'md' : lg ? 'lg' : xl ? 'xl' : 'xxl';
  8873. const breakpointValue = typeof mobileBreakpoint === 'number' ? mobileBreakpoint : thresholds[mobileBreakpoint];
  8874. const mobile = width.value < breakpointValue;
  8875. state.xs = xs;
  8876. state.sm = sm;
  8877. state.md = md;
  8878. state.lg = lg;
  8879. state.xl = xl;
  8880. state.xxl = xxl;
  8881. state.smAndUp = !xs;
  8882. state.mdAndUp = !(xs || sm);
  8883. state.lgAndUp = !(xs || sm || md);
  8884. state.xlAndUp = !(xs || sm || md || lg);
  8885. state.smAndDown = !(md || lg || xl || xxl);
  8886. state.mdAndDown = !(lg || xl || xxl);
  8887. state.lgAndDown = !(xl || xxl);
  8888. state.xlAndDown = !xxl;
  8889. state.name = name;
  8890. state.height = height.value;
  8891. state.width = width.value;
  8892. state.mobile = mobile;
  8893. state.mobileBreakpoint = mobileBreakpoint;
  8894. state.platform = platform.value;
  8895. state.thresholds = thresholds;
  8896. });
  8897. if (IN_BROWSER) {
  8898. window.addEventListener('resize', updateSize, {
  8899. passive: true
  8900. });
  8901. }
  8902. return {
  8903. ...toRefs(state),
  8904. update,
  8905. ssr: !!ssr
  8906. };
  8907. }
  8908. function useDisplay() {
  8909. const display = inject$1(DisplaySymbol);
  8910. if (!display) throw new Error('Could not find Vuetify display injection');
  8911. return display;
  8912. }
  8913. // Composables
  8914. function useHydration() {
  8915. if (!IN_BROWSER) return shallowRef(false);
  8916. const {
  8917. ssr
  8918. } = useDisplay();
  8919. if (ssr) {
  8920. const isMounted = shallowRef(false);
  8921. onMounted(() => {
  8922. isMounted.value = true;
  8923. });
  8924. return isMounted;
  8925. } else {
  8926. return shallowRef(true);
  8927. }
  8928. }
  8929. // Utilities
  8930. // Types
  8931. const makeLazyProps = propsFactory({
  8932. eager: Boolean
  8933. }, 'lazy');
  8934. function useLazy(props, active) {
  8935. const isBooted = shallowRef(false);
  8936. const hasContent = computed(() => isBooted.value || props.eager || active.value);
  8937. watch(active, () => isBooted.value = true);
  8938. function onAfterLeave() {
  8939. if (!props.eager) isBooted.value = false;
  8940. }
  8941. return {
  8942. isBooted,
  8943. hasContent,
  8944. onAfterLeave
  8945. };
  8946. }
  8947. // Utilities
  8948. function useScopeId() {
  8949. const vm = getCurrentInstance('useScopeId');
  8950. const scopeId = vm.vnode.scopeId;
  8951. return {
  8952. scopeId: scopeId ? {
  8953. [scopeId]: ''
  8954. } : undefined
  8955. };
  8956. }
  8957. // Composables
  8958. // Types
  8959. const StackSymbol = Symbol.for('vuetify:stack');
  8960. const globalStack = reactive([]);
  8961. function useStack(isActive, zIndex, disableGlobalStack) {
  8962. const vm = getCurrentInstance('useStack');
  8963. const createStackEntry = !disableGlobalStack;
  8964. const parent = inject$1(StackSymbol, undefined);
  8965. const stack = reactive({
  8966. activeChildren: new Set()
  8967. });
  8968. provide(StackSymbol, stack);
  8969. const _zIndex = shallowRef(+zIndex.value);
  8970. useToggleScope(isActive, () => {
  8971. const lastZIndex = globalStack.at(-1)?.[1];
  8972. _zIndex.value = lastZIndex ? lastZIndex + 10 : +zIndex.value;
  8973. if (createStackEntry) {
  8974. globalStack.push([vm.uid, _zIndex.value]);
  8975. }
  8976. parent?.activeChildren.add(vm.uid);
  8977. onScopeDispose(() => {
  8978. if (createStackEntry) {
  8979. const idx = toRaw(globalStack).findIndex(v => v[0] === vm.uid);
  8980. globalStack.splice(idx, 1);
  8981. }
  8982. parent?.activeChildren.delete(vm.uid);
  8983. });
  8984. });
  8985. const globalTop = shallowRef(true);
  8986. if (createStackEntry) {
  8987. watchEffect(() => {
  8988. const _isTop = globalStack.at(-1)?.[0] === vm.uid;
  8989. setTimeout(() => globalTop.value = _isTop);
  8990. });
  8991. }
  8992. const localTop = computed(() => !stack.activeChildren.size);
  8993. return {
  8994. globalTop: readonly(globalTop),
  8995. localTop,
  8996. stackStyles: computed(() => ({
  8997. zIndex: _zIndex.value
  8998. }))
  8999. };
  9000. }
  9001. // Utilities
  9002. // Types
  9003. function useTeleport(target) {
  9004. const teleportTarget = computed(() => {
  9005. const _target = target.value;
  9006. if (_target === true || !IN_BROWSER) return undefined;
  9007. const targetElement = _target === false ? document.body : typeof _target === 'string' ? document.querySelector(_target) : _target;
  9008. if (targetElement == null) {
  9009. warn(`Unable to locate target ${_target}`);
  9010. return undefined;
  9011. }
  9012. let container = targetElement.querySelector(':scope > .v-overlay-container');
  9013. if (!container) {
  9014. container = document.createElement('div');
  9015. container.className = 'v-overlay-container';
  9016. targetElement.appendChild(container);
  9017. }
  9018. return container;
  9019. });
  9020. return {
  9021. teleportTarget
  9022. };
  9023. }
  9024. // Utilities
  9025. // Types
  9026. function defaultConditional() {
  9027. return true;
  9028. }
  9029. function checkEvent(e, el, binding) {
  9030. // The include element callbacks below can be expensive
  9031. // so we should avoid calling them when we're not active.
  9032. // Explicitly check for false to allow fallback compatibility
  9033. // with non-toggleable components
  9034. if (!e || checkIsActive(e, binding) === false) return false;
  9035. // If we're clicking inside the shadowroot, then the app root doesn't get the same
  9036. // level of introspection as to _what_ we're clicking. We want to check to see if
  9037. // our target is the shadowroot parent container, and if it is, ignore.
  9038. const root = attachedRoot(el);
  9039. if (typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot && root.host === e.target) return false;
  9040. // Check if additional elements were passed to be included in check
  9041. // (click must be outside all included elements, if any)
  9042. const elements = (typeof binding.value === 'object' && binding.value.include || (() => []))();
  9043. // Add the root element for the component this directive was defined on
  9044. elements.push(el);
  9045. // Check if it's a click outside our elements, and then if our callback returns true.
  9046. // Non-toggleable components should take action in their callback and return falsy.
  9047. // Toggleable can return true if it wants to deactivate.
  9048. // Note that, because we're in the capture phase, this callback will occur before
  9049. // the bubbling click event on any outside elements.
  9050. return !elements.some(el => el?.contains(e.target));
  9051. }
  9052. function checkIsActive(e, binding) {
  9053. const isActive = typeof binding.value === 'object' && binding.value.closeConditional || defaultConditional;
  9054. return isActive(e);
  9055. }
  9056. function directive(e, el, binding) {
  9057. const handler = typeof binding.value === 'function' ? binding.value : binding.value.handler;
  9058. el._clickOutside.lastMousedownWasOutside && checkEvent(e, el, binding) && setTimeout(() => {
  9059. checkIsActive(e, binding) && handler && handler(e);
  9060. }, 0);
  9061. }
  9062. function handleShadow(el, callback) {
  9063. const root = attachedRoot(el);
  9064. callback(document);
  9065. if (typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot) {
  9066. callback(root);
  9067. }
  9068. }
  9069. const ClickOutside = {
  9070. // [data-app] may not be found
  9071. // if using bind, inserted makes
  9072. // sure that the root element is
  9073. // available, iOS does not support
  9074. // clicks on body
  9075. mounted(el, binding) {
  9076. const onClick = e => directive(e, el, binding);
  9077. const onMousedown = e => {
  9078. el._clickOutside.lastMousedownWasOutside = checkEvent(e, el, binding);
  9079. };
  9080. handleShadow(el, app => {
  9081. app.addEventListener('click', onClick, true);
  9082. app.addEventListener('mousedown', onMousedown, true);
  9083. });
  9084. if (!el._clickOutside) {
  9085. el._clickOutside = {
  9086. lastMousedownWasOutside: false
  9087. };
  9088. }
  9089. el._clickOutside[binding.instance.$.uid] = {
  9090. onClick,
  9091. onMousedown
  9092. };
  9093. },
  9094. unmounted(el, binding) {
  9095. if (!el._clickOutside) return;
  9096. handleShadow(el, app => {
  9097. if (!app || !el._clickOutside?.[binding.instance.$.uid]) return;
  9098. const {
  9099. onClick,
  9100. onMousedown
  9101. } = el._clickOutside[binding.instance.$.uid];
  9102. app.removeEventListener('click', onClick, true);
  9103. app.removeEventListener('mousedown', onMousedown, true);
  9104. });
  9105. delete el._clickOutside[binding.instance.$.uid];
  9106. }
  9107. };
  9108. // Types
  9109. function Scrim(props) {
  9110. const {
  9111. modelValue,
  9112. color,
  9113. ...rest
  9114. } = props;
  9115. return createVNode(Transition, {
  9116. "name": "fade-transition",
  9117. "appear": true
  9118. }, {
  9119. default: () => [props.modelValue && createVNode("div", mergeProps({
  9120. "class": ['v-overlay__scrim', props.color.backgroundColorClasses.value],
  9121. "style": props.color.backgroundColorStyles.value
  9122. }, rest), null)]
  9123. });
  9124. }
  9125. const makeVOverlayProps = propsFactory({
  9126. absolute: Boolean,
  9127. attach: [Boolean, String, Object],
  9128. closeOnBack: {
  9129. type: Boolean,
  9130. default: true
  9131. },
  9132. contained: Boolean,
  9133. contentClass: null,
  9134. contentProps: null,
  9135. disabled: Boolean,
  9136. noClickAnimation: Boolean,
  9137. modelValue: Boolean,
  9138. persistent: Boolean,
  9139. scrim: {
  9140. type: [Boolean, String],
  9141. default: true
  9142. },
  9143. zIndex: {
  9144. type: [Number, String],
  9145. default: 2000
  9146. },
  9147. ...makeActivatorProps(),
  9148. ...makeComponentProps(),
  9149. ...makeDimensionProps(),
  9150. ...makeLazyProps(),
  9151. ...makeLocationStrategyProps(),
  9152. ...makeScrollStrategyProps(),
  9153. ...makeThemeProps(),
  9154. ...makeTransitionProps()
  9155. }, 'VOverlay');
  9156. const VOverlay = genericComponent()({
  9157. name: 'VOverlay',
  9158. directives: {
  9159. ClickOutside
  9160. },
  9161. inheritAttrs: false,
  9162. props: {
  9163. _disableGlobalStack: Boolean,
  9164. ...makeVOverlayProps()
  9165. },
  9166. emits: {
  9167. 'click:outside': e => true,
  9168. 'update:modelValue': value => true,
  9169. afterLeave: () => true
  9170. },
  9171. setup(props, _ref) {
  9172. let {
  9173. slots,
  9174. attrs,
  9175. emit
  9176. } = _ref;
  9177. const model = useProxiedModel(props, 'modelValue');
  9178. const isActive = computed({
  9179. get: () => model.value,
  9180. set: v => {
  9181. if (!(v && props.disabled)) model.value = v;
  9182. }
  9183. });
  9184. const {
  9185. teleportTarget
  9186. } = useTeleport(computed(() => props.attach || props.contained));
  9187. const {
  9188. themeClasses
  9189. } = provideTheme(props);
  9190. const {
  9191. rtlClasses,
  9192. isRtl
  9193. } = useRtl();
  9194. const {
  9195. hasContent,
  9196. onAfterLeave
  9197. } = useLazy(props, isActive);
  9198. const scrimColor = useBackgroundColor(computed(() => {
  9199. return typeof props.scrim === 'string' ? props.scrim : null;
  9200. }));
  9201. const {
  9202. globalTop,
  9203. localTop,
  9204. stackStyles
  9205. } = useStack(isActive, toRef(props, 'zIndex'), props._disableGlobalStack);
  9206. const {
  9207. activatorEl,
  9208. activatorRef,
  9209. activatorEvents,
  9210. contentEvents,
  9211. scrimEvents
  9212. } = useActivator(props, {
  9213. isActive,
  9214. isTop: localTop
  9215. });
  9216. const {
  9217. dimensionStyles
  9218. } = useDimension(props);
  9219. const isMounted = useHydration();
  9220. const {
  9221. scopeId
  9222. } = useScopeId();
  9223. watch(() => props.disabled, v => {
  9224. if (v) isActive.value = false;
  9225. });
  9226. const root = ref();
  9227. const contentEl = ref();
  9228. const {
  9229. contentStyles,
  9230. updateLocation
  9231. } = useLocationStrategies(props, {
  9232. isRtl,
  9233. contentEl,
  9234. activatorEl,
  9235. isActive
  9236. });
  9237. useScrollStrategies(props, {
  9238. root,
  9239. contentEl,
  9240. activatorEl,
  9241. isActive,
  9242. updateLocation
  9243. });
  9244. function onClickOutside(e) {
  9245. emit('click:outside', e);
  9246. if (!props.persistent) isActive.value = false;else animateClick();
  9247. }
  9248. function closeConditional() {
  9249. return isActive.value && globalTop.value;
  9250. }
  9251. IN_BROWSER && watch(isActive, val => {
  9252. if (val) {
  9253. window.addEventListener('keydown', onKeydown);
  9254. } else {
  9255. window.removeEventListener('keydown', onKeydown);
  9256. }
  9257. }, {
  9258. immediate: true
  9259. });
  9260. function onKeydown(e) {
  9261. if (e.key === 'Escape' && globalTop.value) {
  9262. if (!props.persistent) {
  9263. isActive.value = false;
  9264. if (contentEl.value?.contains(document.activeElement)) {
  9265. activatorEl.value?.focus();
  9266. }
  9267. } else animateClick();
  9268. }
  9269. }
  9270. const router = useRouter();
  9271. useToggleScope(() => props.closeOnBack, () => {
  9272. useBackButton(router, next => {
  9273. if (globalTop.value && isActive.value) {
  9274. next(false);
  9275. if (!props.persistent) isActive.value = false;else animateClick();
  9276. } else {
  9277. next();
  9278. }
  9279. });
  9280. });
  9281. const top = ref();
  9282. watch(() => isActive.value && (props.absolute || props.contained) && teleportTarget.value == null, val => {
  9283. if (val) {
  9284. const scrollParent = getScrollParent(root.value);
  9285. if (scrollParent && scrollParent !== document.scrollingElement) {
  9286. top.value = scrollParent.scrollTop;
  9287. }
  9288. }
  9289. });
  9290. // Add a quick "bounce" animation to the content
  9291. function animateClick() {
  9292. if (props.noClickAnimation) return;
  9293. contentEl.value && animate(contentEl.value, [{
  9294. transformOrigin: 'center'
  9295. }, {
  9296. transform: 'scale(1.03)'
  9297. }, {
  9298. transformOrigin: 'center'
  9299. }], {
  9300. duration: 150,
  9301. easing: standardEasing
  9302. });
  9303. }
  9304. useRender(() => createVNode(Fragment, null, [slots.activator?.({
  9305. isActive: isActive.value,
  9306. props: mergeProps({
  9307. ref: activatorRef
  9308. }, activatorEvents.value, props.activatorProps)
  9309. }), isMounted.value && hasContent.value && createVNode(Teleport, {
  9310. "disabled": !teleportTarget.value,
  9311. "to": teleportTarget.value
  9312. }, {
  9313. default: () => [createVNode("div", mergeProps({
  9314. "class": ['v-overlay', {
  9315. 'v-overlay--absolute': props.absolute || props.contained,
  9316. 'v-overlay--active': isActive.value,
  9317. 'v-overlay--contained': props.contained
  9318. }, themeClasses.value, rtlClasses.value, props.class],
  9319. "style": [stackStyles.value, {
  9320. top: convertToUnit(top.value)
  9321. }, props.style],
  9322. "ref": root
  9323. }, scopeId, attrs), [createVNode(Scrim, mergeProps({
  9324. "color": scrimColor,
  9325. "modelValue": isActive.value && !!props.scrim
  9326. }, scrimEvents.value), null), createVNode(MaybeTransition, {
  9327. "appear": true,
  9328. "persisted": true,
  9329. "transition": props.transition,
  9330. "target": activatorEl.value,
  9331. "onAfterLeave": () => {
  9332. onAfterLeave();
  9333. emit('afterLeave');
  9334. }
  9335. }, {
  9336. default: () => [withDirectives(createVNode("div", mergeProps({
  9337. "ref": contentEl,
  9338. "class": ['v-overlay__content', props.contentClass],
  9339. "style": [dimensionStyles.value, contentStyles.value]
  9340. }, contentEvents.value, props.contentProps), [slots.default?.({
  9341. isActive
  9342. })]), [[vShow, isActive.value], [resolveDirective("click-outside"), {
  9343. handler: onClickOutside,
  9344. closeConditional,
  9345. include: () => [activatorEl.value]
  9346. }]])]
  9347. })])]
  9348. })]));
  9349. return {
  9350. activatorEl,
  9351. animateClick,
  9352. contentEl,
  9353. globalTop,
  9354. localTop,
  9355. updateLocation
  9356. };
  9357. }
  9358. });
  9359. // Types
  9360. const Refs = Symbol('Forwarded refs');
  9361. /** Omit properties starting with P */
  9362. function getDescriptor(obj, key) {
  9363. let currentObj = obj;
  9364. while (currentObj) {
  9365. const descriptor = Reflect.getOwnPropertyDescriptor(currentObj, key);
  9366. if (descriptor) return descriptor;
  9367. currentObj = Object.getPrototypeOf(currentObj);
  9368. }
  9369. return undefined;
  9370. }
  9371. function forwardRefs(target) {
  9372. for (var _len = arguments.length, refs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  9373. refs[_key - 1] = arguments[_key];
  9374. }
  9375. target[Refs] = refs;
  9376. return new Proxy(target, {
  9377. get(target, key) {
  9378. if (Reflect.has(target, key)) {
  9379. return Reflect.get(target, key);
  9380. }
  9381. // Skip internal properties
  9382. if (typeof key === 'symbol' || key.startsWith('__')) return;
  9383. for (const ref of refs) {
  9384. if (ref.value && Reflect.has(ref.value, key)) {
  9385. const val = Reflect.get(ref.value, key);
  9386. return typeof val === 'function' ? val.bind(ref.value) : val;
  9387. }
  9388. }
  9389. },
  9390. has(target, key) {
  9391. if (Reflect.has(target, key)) {
  9392. return true;
  9393. }
  9394. // Skip internal properties
  9395. if (typeof key === 'symbol' || key.startsWith('__')) return false;
  9396. for (const ref of refs) {
  9397. if (ref.value && Reflect.has(ref.value, key)) {
  9398. return true;
  9399. }
  9400. }
  9401. return false;
  9402. },
  9403. set(target, key, value) {
  9404. if (Reflect.has(target, key)) {
  9405. return Reflect.set(target, key, value);
  9406. }
  9407. // Skip internal properties
  9408. if (typeof key === 'symbol' || key.startsWith('__')) return false;
  9409. for (const ref of refs) {
  9410. if (ref.value && Reflect.has(ref.value, key)) {
  9411. return Reflect.set(ref.value, key, value);
  9412. }
  9413. }
  9414. return false;
  9415. },
  9416. getOwnPropertyDescriptor(target, key) {
  9417. const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
  9418. if (descriptor) return descriptor;
  9419. // Skip internal properties
  9420. if (typeof key === 'symbol' || key.startsWith('__')) return;
  9421. // Check each ref's own properties
  9422. for (const ref of refs) {
  9423. if (!ref.value) continue;
  9424. const descriptor = getDescriptor(ref.value, key) ?? ('_' in ref.value ? getDescriptor(ref.value._?.setupState, key) : undefined);
  9425. if (descriptor) return descriptor;
  9426. }
  9427. // Recursive search up each ref's prototype
  9428. for (const ref of refs) {
  9429. const childRefs = ref.value && ref.value[Refs];
  9430. if (!childRefs) continue;
  9431. const queue = childRefs.slice();
  9432. while (queue.length) {
  9433. const ref = queue.shift();
  9434. const descriptor = getDescriptor(ref.value, key);
  9435. if (descriptor) return descriptor;
  9436. const childRefs = ref.value && ref.value[Refs];
  9437. if (childRefs) queue.push(...childRefs);
  9438. }
  9439. }
  9440. return undefined;
  9441. }
  9442. });
  9443. }
  9444. // Types
  9445. const makeVMenuProps = propsFactory({
  9446. // TODO
  9447. // disableKeys: Boolean,
  9448. id: String,
  9449. ...omit(makeVOverlayProps({
  9450. closeDelay: 250,
  9451. closeOnContentClick: true,
  9452. locationStrategy: 'connected',
  9453. openDelay: 300,
  9454. scrim: false,
  9455. scrollStrategy: 'reposition',
  9456. transition: {
  9457. component: VDialogTransition
  9458. }
  9459. }), ['absolute'])
  9460. }, 'VMenu');
  9461. const VMenu = genericComponent()({
  9462. name: 'VMenu',
  9463. props: makeVMenuProps(),
  9464. emits: {
  9465. 'update:modelValue': value => true
  9466. },
  9467. setup(props, _ref) {
  9468. let {
  9469. slots
  9470. } = _ref;
  9471. const isActive = useProxiedModel(props, 'modelValue');
  9472. const {
  9473. scopeId
  9474. } = useScopeId();
  9475. const uid = getUid();
  9476. const id = computed(() => props.id || `v-menu-${uid}`);
  9477. const overlay = ref();
  9478. const parent = inject$1(VMenuSymbol, null);
  9479. const openChildren = shallowRef(0);
  9480. provide(VMenuSymbol, {
  9481. register() {
  9482. ++openChildren.value;
  9483. },
  9484. unregister() {
  9485. --openChildren.value;
  9486. },
  9487. closeParents() {
  9488. setTimeout(() => {
  9489. if (!openChildren.value) {
  9490. isActive.value = false;
  9491. parent?.closeParents();
  9492. }
  9493. }, 40);
  9494. }
  9495. });
  9496. function onFocusIn(e) {
  9497. const before = e.relatedTarget;
  9498. const after = e.target;
  9499. if (before !== after && overlay.value?.contentEl &&
  9500. // We're the topmost menu
  9501. overlay.value?.globalTop &&
  9502. // It isn't the document or the menu body
  9503. ![document, overlay.value.contentEl].includes(after) &&
  9504. // It isn't inside the menu body
  9505. !overlay.value.contentEl.contains(after)) {
  9506. const focusable = focusableChildren(overlay.value.contentEl);
  9507. focusable[0]?.focus();
  9508. }
  9509. }
  9510. watch(isActive, val => {
  9511. if (val) {
  9512. parent?.register();
  9513. document.addEventListener('focusin', onFocusIn, {
  9514. once: true
  9515. });
  9516. } else {
  9517. parent?.unregister();
  9518. document.removeEventListener('focusin', onFocusIn);
  9519. }
  9520. });
  9521. function onClickOutside() {
  9522. parent?.closeParents();
  9523. }
  9524. function onKeydown(e) {
  9525. if (props.disabled) return;
  9526. if (e.key === 'Tab') {
  9527. const nextElement = getNextElement(focusableChildren(overlay.value?.contentEl, false), e.shiftKey ? 'prev' : 'next', el => el.tabIndex >= 0);
  9528. if (!nextElement) {
  9529. isActive.value = false;
  9530. overlay.value?.activatorEl?.focus();
  9531. }
  9532. }
  9533. }
  9534. function onActivatorKeydown(e) {
  9535. if (props.disabled) return;
  9536. const el = overlay.value?.contentEl;
  9537. if (el && isActive.value) {
  9538. if (e.key === 'ArrowDown') {
  9539. e.preventDefault();
  9540. focusChild(el, 'next');
  9541. } else if (e.key === 'ArrowUp') {
  9542. e.preventDefault();
  9543. focusChild(el, 'prev');
  9544. }
  9545. } else if (['ArrowDown', 'ArrowUp'].includes(e.key)) {
  9546. isActive.value = true;
  9547. e.preventDefault();
  9548. setTimeout(() => setTimeout(() => onActivatorKeydown(e)));
  9549. }
  9550. }
  9551. const activatorProps = computed(() => mergeProps({
  9552. 'aria-haspopup': 'menu',
  9553. 'aria-expanded': String(isActive.value),
  9554. 'aria-owns': id.value,
  9555. onKeydown: onActivatorKeydown
  9556. }, props.activatorProps));
  9557. useRender(() => {
  9558. const [overlayProps] = VOverlay.filterProps(props);
  9559. return createVNode(VOverlay, mergeProps({
  9560. "ref": overlay,
  9561. "class": ['v-menu', props.class],
  9562. "style": props.style
  9563. }, overlayProps, {
  9564. "modelValue": isActive.value,
  9565. "onUpdate:modelValue": $event => isActive.value = $event,
  9566. "absolute": true,
  9567. "activatorProps": activatorProps.value,
  9568. "onClick:outside": onClickOutside,
  9569. "onKeydown": onKeydown
  9570. }, scopeId), {
  9571. activator: slots.activator,
  9572. default: function () {
  9573. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  9574. args[_key] = arguments[_key];
  9575. }
  9576. return createVNode(VDefaultsProvider, {
  9577. "root": "VMenu"
  9578. }, {
  9579. default: () => [slots.default?.(...args)]
  9580. });
  9581. }
  9582. });
  9583. });
  9584. return forwardRefs({
  9585. id,
  9586. ΨopenChildren: openChildren
  9587. }, overlay);
  9588. }
  9589. });
  9590. // Types
  9591. const makeVCounterProps = propsFactory({
  9592. active: Boolean,
  9593. max: [Number, String],
  9594. value: {
  9595. type: [Number, String],
  9596. default: 0
  9597. },
  9598. ...makeComponentProps(),
  9599. ...makeTransitionProps({
  9600. transition: {
  9601. component: VSlideYTransition
  9602. }
  9603. })
  9604. }, 'VCounter');
  9605. const VCounter = genericComponent()({
  9606. name: 'VCounter',
  9607. functional: true,
  9608. props: makeVCounterProps(),
  9609. setup(props, _ref) {
  9610. let {
  9611. slots
  9612. } = _ref;
  9613. const counter = computed(() => {
  9614. return props.max ? `${props.value} / ${props.max}` : String(props.value);
  9615. });
  9616. useRender(() => createVNode(MaybeTransition, {
  9617. "transition": props.transition
  9618. }, {
  9619. default: () => [withDirectives(createVNode("div", {
  9620. "class": ['v-counter', props.class],
  9621. "style": props.style
  9622. }, [slots.default ? slots.default({
  9623. counter: counter.value,
  9624. max: props.max,
  9625. value: props.value
  9626. }) : counter.value]), [[vShow, props.active]])]
  9627. }));
  9628. return {};
  9629. }
  9630. });
  9631. const makeVFieldLabelProps = propsFactory({
  9632. floating: Boolean,
  9633. ...makeComponentProps()
  9634. }, 'VFieldLabel');
  9635. const VFieldLabel = genericComponent()({
  9636. name: 'VFieldLabel',
  9637. props: makeVFieldLabelProps(),
  9638. setup(props, _ref) {
  9639. let {
  9640. slots
  9641. } = _ref;
  9642. useRender(() => createVNode(VLabel, {
  9643. "class": ['v-field-label', {
  9644. 'v-field-label--floating': props.floating
  9645. }, props.class],
  9646. "style": props.style,
  9647. "aria-hidden": props.floating || undefined
  9648. }, slots));
  9649. return {};
  9650. }
  9651. });
  9652. // Types
  9653. const allowedVariants$1 = ['underlined', 'outlined', 'filled', 'solo', 'solo-inverted', 'solo-filled', 'plain'];
  9654. const makeVFieldProps = propsFactory({
  9655. appendInnerIcon: IconValue,
  9656. bgColor: String,
  9657. clearable: Boolean,
  9658. clearIcon: {
  9659. type: IconValue,
  9660. default: '$clear'
  9661. },
  9662. active: Boolean,
  9663. centerAffix: {
  9664. type: Boolean,
  9665. default: undefined
  9666. },
  9667. color: String,
  9668. baseColor: String,
  9669. dirty: Boolean,
  9670. disabled: {
  9671. type: Boolean,
  9672. default: null
  9673. },
  9674. error: Boolean,
  9675. flat: Boolean,
  9676. label: String,
  9677. persistentClear: Boolean,
  9678. prependInnerIcon: IconValue,
  9679. reverse: Boolean,
  9680. singleLine: Boolean,
  9681. variant: {
  9682. type: String,
  9683. default: 'filled',
  9684. validator: v => allowedVariants$1.includes(v)
  9685. },
  9686. 'onClick:clear': EventProp(),
  9687. 'onClick:appendInner': EventProp(),
  9688. 'onClick:prependInner': EventProp(),
  9689. ...makeComponentProps(),
  9690. ...makeLoaderProps(),
  9691. ...makeRoundedProps(),
  9692. ...makeThemeProps()
  9693. }, 'VField');
  9694. const VField = genericComponent()({
  9695. name: 'VField',
  9696. inheritAttrs: false,
  9697. props: {
  9698. id: String,
  9699. ...makeFocusProps(),
  9700. ...makeVFieldProps()
  9701. },
  9702. emits: {
  9703. 'update:focused': focused => true,
  9704. 'update:modelValue': val => true
  9705. },
  9706. setup(props, _ref) {
  9707. let {
  9708. attrs,
  9709. emit,
  9710. slots
  9711. } = _ref;
  9712. const {
  9713. themeClasses
  9714. } = provideTheme(props);
  9715. const {
  9716. loaderClasses
  9717. } = useLoader(props);
  9718. const {
  9719. focusClasses,
  9720. isFocused,
  9721. focus,
  9722. blur
  9723. } = useFocus(props);
  9724. const {
  9725. InputIcon
  9726. } = useInputIcon(props);
  9727. const {
  9728. roundedClasses
  9729. } = useRounded(props);
  9730. const {
  9731. rtlClasses
  9732. } = useRtl();
  9733. const isActive = computed(() => props.dirty || props.active);
  9734. const hasLabel = computed(() => !props.singleLine && !!(props.label || slots.label));
  9735. const uid = getUid();
  9736. const id = computed(() => props.id || `input-${uid}`);
  9737. const messagesId = computed(() => `${id.value}-messages`);
  9738. const labelRef = ref();
  9739. const floatingLabelRef = ref();
  9740. const controlRef = ref();
  9741. const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant));
  9742. const {
  9743. backgroundColorClasses,
  9744. backgroundColorStyles
  9745. } = useBackgroundColor(toRef(props, 'bgColor'));
  9746. const {
  9747. textColorClasses,
  9748. textColorStyles
  9749. } = useTextColor(computed(() => {
  9750. return props.error || props.disabled ? undefined : isActive.value && isFocused.value ? props.color : props.baseColor;
  9751. }));
  9752. watch(isActive, val => {
  9753. if (hasLabel.value) {
  9754. const el = labelRef.value.$el;
  9755. const targetEl = floatingLabelRef.value.$el;
  9756. requestAnimationFrame(() => {
  9757. const rect = nullifyTransforms(el);
  9758. const targetRect = targetEl.getBoundingClientRect();
  9759. const x = targetRect.x - rect.x;
  9760. const y = targetRect.y - rect.y - (rect.height / 2 - targetRect.height / 2);
  9761. const targetWidth = targetRect.width / 0.75;
  9762. const width = Math.abs(targetWidth - rect.width) > 1 ? {
  9763. maxWidth: convertToUnit(targetWidth)
  9764. } : undefined;
  9765. const style = getComputedStyle(el);
  9766. const targetStyle = getComputedStyle(targetEl);
  9767. const duration = parseFloat(style.transitionDuration) * 1000 || 150;
  9768. const scale = parseFloat(targetStyle.getPropertyValue('--v-field-label-scale'));
  9769. const color = targetStyle.getPropertyValue('color');
  9770. el.style.visibility = 'visible';
  9771. targetEl.style.visibility = 'hidden';
  9772. animate(el, {
  9773. transform: `translate(${x}px, ${y}px) scale(${scale})`,
  9774. color,
  9775. ...width
  9776. }, {
  9777. duration,
  9778. easing: standardEasing,
  9779. direction: val ? 'normal' : 'reverse'
  9780. }).finished.then(() => {
  9781. el.style.removeProperty('visibility');
  9782. targetEl.style.removeProperty('visibility');
  9783. });
  9784. });
  9785. }
  9786. }, {
  9787. flush: 'post'
  9788. });
  9789. const slotProps = computed(() => ({
  9790. isActive,
  9791. isFocused,
  9792. controlRef,
  9793. blur,
  9794. focus
  9795. }));
  9796. function onClick(e) {
  9797. if (e.target !== document.activeElement) {
  9798. e.preventDefault();
  9799. }
  9800. }
  9801. useRender(() => {
  9802. const isOutlined = props.variant === 'outlined';
  9803. const hasPrepend = slots['prepend-inner'] || props.prependInnerIcon;
  9804. const hasClear = !!(props.clearable || slots.clear);
  9805. const hasAppend = !!(slots['append-inner'] || props.appendInnerIcon || hasClear);
  9806. const label = slots.label ? slots.label({
  9807. ...slotProps.value,
  9808. label: props.label,
  9809. props: {
  9810. for: id.value
  9811. }
  9812. }) : props.label;
  9813. return createVNode("div", mergeProps({
  9814. "class": ['v-field', {
  9815. 'v-field--active': isActive.value,
  9816. 'v-field--appended': hasAppend,
  9817. 'v-field--center-affix': props.centerAffix ?? !isPlainOrUnderlined.value,
  9818. 'v-field--disabled': props.disabled,
  9819. 'v-field--dirty': props.dirty,
  9820. 'v-field--error': props.error,
  9821. 'v-field--flat': props.flat,
  9822. 'v-field--has-background': !!props.bgColor,
  9823. 'v-field--persistent-clear': props.persistentClear,
  9824. 'v-field--prepended': hasPrepend,
  9825. 'v-field--reverse': props.reverse,
  9826. 'v-field--single-line': props.singleLine,
  9827. 'v-field--no-label': !label,
  9828. [`v-field--variant-${props.variant}`]: true
  9829. }, themeClasses.value, backgroundColorClasses.value, focusClasses.value, loaderClasses.value, roundedClasses.value, rtlClasses.value, props.class],
  9830. "style": [backgroundColorStyles.value, textColorStyles.value, props.style],
  9831. "onClick": onClick
  9832. }, attrs), [createVNode("div", {
  9833. "class": "v-field__overlay"
  9834. }, null), createVNode(LoaderSlot, {
  9835. "name": "v-field",
  9836. "active": !!props.loading,
  9837. "color": props.error ? 'error' : typeof props.loading === 'string' ? props.loading : props.color
  9838. }, {
  9839. default: slots.loader
  9840. }), hasPrepend && createVNode("div", {
  9841. "key": "prepend",
  9842. "class": "v-field__prepend-inner"
  9843. }, [props.prependInnerIcon && createVNode(InputIcon, {
  9844. "key": "prepend-icon",
  9845. "name": "prependInner"
  9846. }, null), slots['prepend-inner']?.(slotProps.value)]), createVNode("div", {
  9847. "class": "v-field__field",
  9848. "data-no-activator": ""
  9849. }, [['filled', 'solo', 'solo-inverted', 'solo-filled'].includes(props.variant) && hasLabel.value && createVNode(VFieldLabel, {
  9850. "key": "floating-label",
  9851. "ref": floatingLabelRef,
  9852. "class": [textColorClasses.value],
  9853. "floating": true,
  9854. "for": id.value
  9855. }, {
  9856. default: () => [label]
  9857. }), createVNode(VFieldLabel, {
  9858. "ref": labelRef,
  9859. "for": id.value
  9860. }, {
  9861. default: () => [label]
  9862. }), slots.default?.({
  9863. ...slotProps.value,
  9864. props: {
  9865. id: id.value,
  9866. class: 'v-field__input',
  9867. 'aria-describedby': messagesId.value
  9868. },
  9869. focus,
  9870. blur
  9871. })]), hasClear && createVNode(VExpandXTransition, {
  9872. "key": "clear"
  9873. }, {
  9874. default: () => [withDirectives(createVNode("div", {
  9875. "class": "v-field__clearable",
  9876. "onMousedown": e => {
  9877. e.preventDefault();
  9878. e.stopPropagation();
  9879. }
  9880. }, [slots.clear ? slots.clear() : createVNode(InputIcon, {
  9881. "name": "clear"
  9882. }, null)]), [[vShow, props.dirty]])]
  9883. }), hasAppend && createVNode("div", {
  9884. "key": "append",
  9885. "class": "v-field__append-inner"
  9886. }, [slots['append-inner']?.(slotProps.value), props.appendInnerIcon && createVNode(InputIcon, {
  9887. "key": "append-icon",
  9888. "name": "appendInner"
  9889. }, null)]), createVNode("div", {
  9890. "class": ['v-field__outline', textColorClasses.value]
  9891. }, [isOutlined && createVNode(Fragment, null, [createVNode("div", {
  9892. "class": "v-field__outline__start"
  9893. }, null), hasLabel.value && createVNode("div", {
  9894. "class": "v-field__outline__notch"
  9895. }, [createVNode(VFieldLabel, {
  9896. "ref": floatingLabelRef,
  9897. "floating": true,
  9898. "for": id.value
  9899. }, {
  9900. default: () => [label]
  9901. })]), createVNode("div", {
  9902. "class": "v-field__outline__end"
  9903. }, null)]), isPlainOrUnderlined.value && hasLabel.value && createVNode(VFieldLabel, {
  9904. "ref": floatingLabelRef,
  9905. "floating": true,
  9906. "for": id.value
  9907. }, {
  9908. default: () => [label]
  9909. })])]);
  9910. });
  9911. return {
  9912. controlRef
  9913. };
  9914. }
  9915. });
  9916. // TODO: this is kinda slow, might be better to implicitly inherit props instead
  9917. function filterFieldProps(attrs) {
  9918. const keys = Object.keys(VField.props).filter(k => !isOn(k) && k !== 'class' && k !== 'style');
  9919. return pick(attrs, keys);
  9920. }
  9921. // Types
  9922. const activeTypes = ['color', 'file', 'time', 'date', 'datetime-local', 'week', 'month'];
  9923. const makeVTextFieldProps = propsFactory({
  9924. autofocus: Boolean,
  9925. counter: [Boolean, Number, String],
  9926. counterValue: Function,
  9927. prefix: String,
  9928. placeholder: String,
  9929. persistentPlaceholder: Boolean,
  9930. persistentCounter: Boolean,
  9931. suffix: String,
  9932. type: {
  9933. type: String,
  9934. default: 'text'
  9935. },
  9936. modelModifiers: Object,
  9937. ...makeVInputProps(),
  9938. ...makeVFieldProps()
  9939. }, 'VTextField');
  9940. const VTextField = genericComponent()({
  9941. name: 'VTextField',
  9942. directives: {
  9943. Intersect
  9944. },
  9945. inheritAttrs: false,
  9946. props: makeVTextFieldProps(),
  9947. emits: {
  9948. 'click:control': e => true,
  9949. 'mousedown:control': e => true,
  9950. 'update:focused': focused => true,
  9951. 'update:modelValue': val => true
  9952. },
  9953. setup(props, _ref) {
  9954. let {
  9955. attrs,
  9956. emit,
  9957. slots
  9958. } = _ref;
  9959. const model = useProxiedModel(props, 'modelValue');
  9960. const {
  9961. isFocused,
  9962. focus,
  9963. blur
  9964. } = useFocus(props);
  9965. const counterValue = computed(() => {
  9966. return typeof props.counterValue === 'function' ? props.counterValue(model.value) : (model.value ?? '').toString().length;
  9967. });
  9968. const max = computed(() => {
  9969. if (attrs.maxlength) return attrs.maxlength;
  9970. if (!props.counter || typeof props.counter !== 'number' && typeof props.counter !== 'string') return undefined;
  9971. return props.counter;
  9972. });
  9973. const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant));
  9974. function onIntersect(isIntersecting, entries) {
  9975. if (!props.autofocus || !isIntersecting) return;
  9976. entries[0].target?.focus?.();
  9977. }
  9978. const vInputRef = ref();
  9979. const vFieldRef = ref();
  9980. const inputRef = ref();
  9981. const isActive = computed(() => activeTypes.includes(props.type) || props.persistentPlaceholder || isFocused.value || props.active);
  9982. function onFocus() {
  9983. if (inputRef.value !== document.activeElement) {
  9984. inputRef.value?.focus();
  9985. }
  9986. if (!isFocused.value) focus();
  9987. }
  9988. function onControlMousedown(e) {
  9989. emit('mousedown:control', e);
  9990. if (e.target === inputRef.value) return;
  9991. onFocus();
  9992. e.preventDefault();
  9993. }
  9994. function onControlClick(e) {
  9995. onFocus();
  9996. emit('click:control', e);
  9997. }
  9998. function onClear(e) {
  9999. e.stopPropagation();
  10000. onFocus();
  10001. nextTick(() => {
  10002. model.value = null;
  10003. callEvent(props['onClick:clear'], e);
  10004. });
  10005. }
  10006. function onInput(e) {
  10007. const el = e.target;
  10008. model.value = el.value;
  10009. if (props.modelModifiers?.trim && ['text', 'search', 'password', 'tel', 'url'].includes(props.type)) {
  10010. const caretPosition = [el.selectionStart, el.selectionEnd];
  10011. nextTick(() => {
  10012. el.selectionStart = caretPosition[0];
  10013. el.selectionEnd = caretPosition[1];
  10014. });
  10015. }
  10016. }
  10017. useRender(() => {
  10018. const hasCounter = !!(slots.counter || props.counter || props.counterValue);
  10019. const hasDetails = !!(hasCounter || slots.details);
  10020. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  10021. const [{
  10022. modelValue: _,
  10023. ...inputProps
  10024. }] = VInput.filterProps(props);
  10025. const [fieldProps] = filterFieldProps(props);
  10026. return createVNode(VInput, mergeProps({
  10027. "ref": vInputRef,
  10028. "modelValue": model.value,
  10029. "onUpdate:modelValue": $event => model.value = $event,
  10030. "class": ['v-text-field', {
  10031. 'v-text-field--prefixed': props.prefix,
  10032. 'v-text-field--suffixed': props.suffix,
  10033. 'v-text-field--plain-underlined': ['plain', 'underlined'].includes(props.variant)
  10034. }, props.class],
  10035. "style": props.style
  10036. }, rootAttrs, inputProps, {
  10037. "centerAffix": !isPlainOrUnderlined.value,
  10038. "focused": isFocused.value
  10039. }), {
  10040. ...slots,
  10041. default: _ref2 => {
  10042. let {
  10043. id,
  10044. isDisabled,
  10045. isDirty,
  10046. isReadonly,
  10047. isValid
  10048. } = _ref2;
  10049. return createVNode(VField, mergeProps({
  10050. "ref": vFieldRef,
  10051. "onMousedown": onControlMousedown,
  10052. "onClick": onControlClick,
  10053. "onClick:clear": onClear,
  10054. "onClick:prependInner": props['onClick:prependInner'],
  10055. "onClick:appendInner": props['onClick:appendInner'],
  10056. "role": "textbox"
  10057. }, fieldProps, {
  10058. "id": id.value,
  10059. "active": isActive.value || isDirty.value,
  10060. "dirty": isDirty.value || props.dirty,
  10061. "disabled": isDisabled.value,
  10062. "focused": isFocused.value,
  10063. "error": isValid.value === false
  10064. }), {
  10065. ...slots,
  10066. default: _ref3 => {
  10067. let {
  10068. props: {
  10069. class: fieldClass,
  10070. ...slotProps
  10071. }
  10072. } = _ref3;
  10073. const inputNode = withDirectives(createVNode("input", mergeProps({
  10074. "ref": inputRef,
  10075. "value": model.value,
  10076. "onInput": onInput,
  10077. "autofocus": props.autofocus,
  10078. "readonly": isReadonly.value,
  10079. "disabled": isDisabled.value,
  10080. "name": props.name,
  10081. "placeholder": props.placeholder,
  10082. "size": 1,
  10083. "type": props.type,
  10084. "onFocus": onFocus,
  10085. "onBlur": blur
  10086. }, slotProps, inputAttrs), null), [[resolveDirective("intersect"), {
  10087. handler: onIntersect
  10088. }, null, {
  10089. once: true
  10090. }]]);
  10091. return createVNode(Fragment, null, [props.prefix && createVNode("span", {
  10092. "class": "v-text-field__prefix"
  10093. }, [createVNode("span", {
  10094. "class": "v-text-field__prefix__text"
  10095. }, [props.prefix])]), createVNode("div", {
  10096. "class": fieldClass,
  10097. "data-no-activator": ""
  10098. }, [slots.default ? createVNode(Fragment, null, [slots.default(), inputNode]) : cloneVNode(inputNode)]), props.suffix && createVNode("span", {
  10099. "class": "v-text-field__suffix"
  10100. }, [createVNode("span", {
  10101. "class": "v-text-field__suffix__text"
  10102. }, [props.suffix])])]);
  10103. }
  10104. });
  10105. },
  10106. details: hasDetails ? slotProps => createVNode(Fragment, null, [slots.details?.(slotProps), hasCounter && createVNode(Fragment, null, [createVNode("span", null, null), createVNode(VCounter, {
  10107. "active": props.persistentCounter || isFocused.value,
  10108. "value": counterValue.value,
  10109. "max": max.value
  10110. }, slots.counter)])]) : undefined
  10111. });
  10112. });
  10113. return forwardRefs({}, vInputRef, vFieldRef, inputRef);
  10114. }
  10115. });
  10116. // Types
  10117. const makeVVirtualScrollItemProps = propsFactory({
  10118. renderless: Boolean,
  10119. ...makeComponentProps()
  10120. }, 'VVirtualScrollItem');
  10121. const VVirtualScrollItem = genericComponent()({
  10122. name: 'VVirtualScrollItem',
  10123. inheritAttrs: false,
  10124. props: makeVVirtualScrollItemProps(),
  10125. emits: {
  10126. 'update:height': height => true
  10127. },
  10128. setup(props, _ref) {
  10129. let {
  10130. attrs,
  10131. emit,
  10132. slots
  10133. } = _ref;
  10134. const {
  10135. resizeRef,
  10136. contentRect
  10137. } = useResizeObserver(undefined, 'border');
  10138. watch(() => contentRect.value?.height, height => {
  10139. if (height != null) emit('update:height', height);
  10140. });
  10141. useRender(() => props.renderless ? createVNode(Fragment, null, [slots.default?.({
  10142. itemRef: resizeRef
  10143. })]) : createVNode("div", mergeProps({
  10144. "ref": resizeRef,
  10145. "class": ['v-virtual-scroll__item', props.class],
  10146. "style": props.style
  10147. }, attrs), [slots.default?.()]));
  10148. }
  10149. });
  10150. // Composables
  10151. // Types
  10152. const UP = -1;
  10153. const DOWN = 1;
  10154. const makeVirtualProps = propsFactory({
  10155. itemHeight: {
  10156. type: [Number, String],
  10157. default: 48
  10158. }
  10159. }, 'virtual');
  10160. function useVirtual(props, items, offset) {
  10161. const first = shallowRef(0);
  10162. const baseItemHeight = shallowRef(props.itemHeight);
  10163. const itemHeight = computed({
  10164. get: () => parseInt(baseItemHeight.value ?? 0, 10),
  10165. set(val) {
  10166. baseItemHeight.value = val;
  10167. }
  10168. });
  10169. const containerRef = ref();
  10170. const {
  10171. resizeRef,
  10172. contentRect
  10173. } = useResizeObserver();
  10174. watchEffect(() => {
  10175. resizeRef.value = containerRef.value;
  10176. });
  10177. const display = useDisplay();
  10178. const sizeMap = new Map();
  10179. let sizes = Array.from({
  10180. length: items.value.length
  10181. });
  10182. const visibleItems = computed(() => {
  10183. const height = (!contentRect.value || containerRef.value === document.documentElement ? display.height.value : contentRect.value.height) - (offset?.value ?? 0);
  10184. return Math.ceil(height / itemHeight.value * 1.7 + 1);
  10185. });
  10186. function handleItemResize(index, height) {
  10187. itemHeight.value = Math.max(itemHeight.value, height);
  10188. sizes[index] = height;
  10189. sizeMap.set(items.value[index], height);
  10190. }
  10191. function calculateOffset(index) {
  10192. return sizes.slice(0, index).reduce((acc, val) => acc + (val || itemHeight.value), 0);
  10193. }
  10194. function calculateMidPointIndex(scrollTop) {
  10195. const end = items.value.length;
  10196. let middle = 0;
  10197. let middleOffset = 0;
  10198. while (middleOffset < scrollTop && middle < end) {
  10199. middleOffset += sizes[middle++] || itemHeight.value;
  10200. }
  10201. return middle - 1;
  10202. }
  10203. let lastScrollTop = 0;
  10204. function handleScroll() {
  10205. if (!containerRef.value || !contentRect.value) return;
  10206. const height = contentRect.value.height - 56;
  10207. const scrollTop = containerRef.value.scrollTop;
  10208. const direction = scrollTop < lastScrollTop ? UP : DOWN;
  10209. const midPointIndex = calculateMidPointIndex(scrollTop + height / 2);
  10210. const buffer = Math.round(visibleItems.value / 3);
  10211. const firstIndex = midPointIndex - buffer;
  10212. const lastIndex = first.value + buffer * 2 - 1;
  10213. if (direction === UP && midPointIndex <= lastIndex) {
  10214. first.value = clamp(firstIndex, 0, items.value.length);
  10215. } else if (direction === DOWN && midPointIndex >= lastIndex) {
  10216. first.value = clamp(firstIndex, 0, items.value.length - visibleItems.value);
  10217. }
  10218. lastScrollTop = scrollTop;
  10219. }
  10220. function scrollToIndex(index) {
  10221. if (!containerRef.value) return;
  10222. const offset = calculateOffset(index);
  10223. containerRef.value.scrollTop = offset;
  10224. }
  10225. const last = computed(() => Math.min(items.value.length, first.value + visibleItems.value));
  10226. const computedItems = computed(() => {
  10227. return items.value.slice(first.value, last.value).map((item, index) => ({
  10228. raw: item,
  10229. index: index + first.value
  10230. }));
  10231. });
  10232. const paddingTop = computed(() => calculateOffset(first.value));
  10233. const paddingBottom = computed(() => calculateOffset(items.value.length) - calculateOffset(last.value));
  10234. watch(() => items.value.length, () => {
  10235. sizes = createRange(items.value.length).map(() => itemHeight.value);
  10236. sizeMap.forEach((height, item) => {
  10237. const index = items.value.indexOf(item);
  10238. if (index === -1) {
  10239. sizeMap.delete(item);
  10240. } else {
  10241. sizes[index] = height;
  10242. }
  10243. });
  10244. });
  10245. return {
  10246. containerRef,
  10247. computedItems,
  10248. itemHeight,
  10249. paddingTop,
  10250. paddingBottom,
  10251. scrollToIndex,
  10252. handleScroll,
  10253. handleItemResize
  10254. };
  10255. }
  10256. // Types
  10257. const makeVVirtualScrollProps = propsFactory({
  10258. items: {
  10259. type: Array,
  10260. default: () => []
  10261. },
  10262. renderless: Boolean,
  10263. ...makeVirtualProps(),
  10264. ...makeComponentProps(),
  10265. ...makeDimensionProps()
  10266. }, 'VVirtualScroll');
  10267. const VVirtualScroll = genericComponent()({
  10268. name: 'VVirtualScroll',
  10269. props: makeVVirtualScrollProps(),
  10270. setup(props, _ref) {
  10271. let {
  10272. slots
  10273. } = _ref;
  10274. const vm = getCurrentInstance('VVirtualScroll');
  10275. const {
  10276. dimensionStyles
  10277. } = useDimension(props);
  10278. const {
  10279. containerRef,
  10280. handleScroll,
  10281. handleItemResize,
  10282. scrollToIndex,
  10283. paddingTop,
  10284. paddingBottom,
  10285. computedItems
  10286. } = useVirtual(props, toRef(props, 'items'));
  10287. useToggleScope(() => props.renderless, () => {
  10288. onMounted(() => {
  10289. containerRef.value = getScrollParent(vm.vnode.el, true);
  10290. containerRef.value?.addEventListener('scroll', handleScroll);
  10291. });
  10292. onScopeDispose(() => {
  10293. containerRef.value?.removeEventListener('scroll', handleScroll);
  10294. });
  10295. });
  10296. useRender(() => {
  10297. const children = computedItems.value.map(item => createVNode(VVirtualScrollItem, {
  10298. "key": item.index,
  10299. "renderless": props.renderless,
  10300. "onUpdate:height": height => handleItemResize(item.index, height)
  10301. }, {
  10302. default: slotProps => slots.default?.({
  10303. item: item.raw,
  10304. index: item.index,
  10305. ...slotProps
  10306. })
  10307. }));
  10308. return props.renderless ? createVNode(Fragment, null, [createVNode("div", {
  10309. "class": "v-virtual-scroll__spacer",
  10310. "style": {
  10311. paddingTop: convertToUnit(paddingTop.value)
  10312. }
  10313. }, null), children, createVNode("div", {
  10314. "class": "v-virtual-scroll__spacer",
  10315. "style": {
  10316. paddingBottom: convertToUnit(paddingBottom.value)
  10317. }
  10318. }, null)]) : createVNode("div", {
  10319. "ref": containerRef,
  10320. "class": ['v-virtual-scroll', props.class],
  10321. "onScroll": handleScroll,
  10322. "style": [dimensionStyles.value, props.style]
  10323. }, [createVNode("div", {
  10324. "class": "v-virtual-scroll__container",
  10325. "style": {
  10326. paddingTop: convertToUnit(paddingTop.value),
  10327. paddingBottom: convertToUnit(paddingBottom.value)
  10328. }
  10329. }, [children])]);
  10330. });
  10331. return {
  10332. scrollToIndex
  10333. };
  10334. }
  10335. });
  10336. // Utilities
  10337. // Types
  10338. function useScrolling(listRef, textFieldRef) {
  10339. const isScrolling = shallowRef(false);
  10340. let scrollTimeout;
  10341. function onListScroll(e) {
  10342. cancelAnimationFrame(scrollTimeout);
  10343. isScrolling.value = true;
  10344. scrollTimeout = requestAnimationFrame(() => {
  10345. scrollTimeout = requestAnimationFrame(() => {
  10346. isScrolling.value = false;
  10347. });
  10348. });
  10349. }
  10350. async function finishScrolling() {
  10351. await new Promise(resolve => requestAnimationFrame(resolve));
  10352. await new Promise(resolve => requestAnimationFrame(resolve));
  10353. await new Promise(resolve => requestAnimationFrame(resolve));
  10354. await new Promise(resolve => {
  10355. if (isScrolling.value) {
  10356. const stop = watch(isScrolling, () => {
  10357. stop();
  10358. resolve();
  10359. });
  10360. } else resolve();
  10361. });
  10362. }
  10363. async function onListKeydown(e) {
  10364. if (e.key === 'Tab') {
  10365. textFieldRef.value?.focus();
  10366. }
  10367. if (!['PageDown', 'PageUp', 'Home', 'End'].includes(e.key)) return;
  10368. const el = listRef.value?.$el;
  10369. if (!el) return;
  10370. if (e.key === 'Home' || e.key === 'End') {
  10371. el.scrollTo({
  10372. top: e.key === 'Home' ? 0 : el.scrollHeight,
  10373. behavior: 'smooth'
  10374. });
  10375. }
  10376. await finishScrolling();
  10377. const children = el.querySelectorAll(':scope > :not(.v-virtual-scroll__spacer)');
  10378. if (e.key === 'PageDown' || e.key === 'Home') {
  10379. const top = el.getBoundingClientRect().top;
  10380. for (const child of children) {
  10381. if (child.getBoundingClientRect().top >= top) {
  10382. child.focus();
  10383. break;
  10384. }
  10385. }
  10386. } else {
  10387. const bottom = el.getBoundingClientRect().bottom;
  10388. for (const child of [...children].reverse()) {
  10389. if (child.getBoundingClientRect().bottom <= bottom) {
  10390. child.focus();
  10391. break;
  10392. }
  10393. }
  10394. }
  10395. }
  10396. return {
  10397. onListScroll,
  10398. onListKeydown
  10399. };
  10400. }
  10401. // Types
  10402. const makeSelectProps = propsFactory({
  10403. chips: Boolean,
  10404. closableChips: Boolean,
  10405. eager: Boolean,
  10406. hideNoData: Boolean,
  10407. hideSelected: Boolean,
  10408. menu: Boolean,
  10409. menuIcon: {
  10410. type: IconValue,
  10411. default: '$dropdown'
  10412. },
  10413. menuProps: {
  10414. type: Object
  10415. },
  10416. multiple: Boolean,
  10417. noDataText: {
  10418. type: String,
  10419. default: '$vuetify.noDataText'
  10420. },
  10421. openOnClear: Boolean,
  10422. valueComparator: {
  10423. type: Function,
  10424. default: deepEqual
  10425. },
  10426. itemColor: String,
  10427. ...makeItemsProps({
  10428. itemChildren: false
  10429. })
  10430. }, 'Select');
  10431. const makeVSelectProps = propsFactory({
  10432. ...makeSelectProps(),
  10433. ...omit(makeVTextFieldProps({
  10434. modelValue: null
  10435. }), ['validationValue', 'dirty', 'appendInnerIcon']),
  10436. ...makeTransitionProps({
  10437. transition: {
  10438. component: VDialogTransition
  10439. }
  10440. })
  10441. }, 'VSelect');
  10442. const VSelect = genericComponent()({
  10443. name: 'VSelect',
  10444. props: makeVSelectProps(),
  10445. emits: {
  10446. 'update:focused': focused => true,
  10447. 'update:modelValue': val => true,
  10448. 'update:menu': val => true
  10449. },
  10450. setup(props, _ref) {
  10451. let {
  10452. slots
  10453. } = _ref;
  10454. const {
  10455. t
  10456. } = useLocale();
  10457. const vTextFieldRef = ref();
  10458. const vMenuRef = ref();
  10459. const _menu = useProxiedModel(props, 'menu');
  10460. const menu = computed({
  10461. get: () => _menu.value,
  10462. set: v => {
  10463. if (_menu.value && !v && vMenuRef.value?.ΨopenChildren) return;
  10464. _menu.value = v;
  10465. }
  10466. });
  10467. const {
  10468. items,
  10469. transformIn,
  10470. transformOut
  10471. } = useItems(props);
  10472. const model = useProxiedModel(props, 'modelValue', [], v => transformIn(v === null ? [null] : wrapInArray(v)), v => {
  10473. const transformed = transformOut(v);
  10474. return props.multiple ? transformed : transformed[0] ?? null;
  10475. });
  10476. const form = useForm();
  10477. const selections = computed(() => {
  10478. return model.value.map(v => {
  10479. return items.value.find(item => {
  10480. const itemRawValue = getPropertyFromItem(item.raw, props.itemValue);
  10481. const modelRawValue = getPropertyFromItem(v.raw, props.itemValue);
  10482. if (itemRawValue === undefined || modelRawValue === undefined) return false;
  10483. return props.returnObject ? props.valueComparator(itemRawValue, modelRawValue) : props.valueComparator(item.value, v.value);
  10484. }) || v;
  10485. });
  10486. });
  10487. const selected = computed(() => selections.value.map(selection => selection.props.value));
  10488. const isFocused = shallowRef(false);
  10489. let keyboardLookupPrefix = '';
  10490. let keyboardLookupLastTime;
  10491. const displayItems = computed(() => {
  10492. if (props.hideSelected) {
  10493. return items.value.filter(item => !selections.value.some(s => s === item));
  10494. }
  10495. return items.value;
  10496. });
  10497. const menuDisabled = computed(() => props.hideNoData && !items.value.length || props.readonly || form?.isReadonly.value);
  10498. const listRef = ref();
  10499. const {
  10500. onListScroll,
  10501. onListKeydown
  10502. } = useScrolling(listRef, vTextFieldRef);
  10503. function onClear(e) {
  10504. if (props.openOnClear) {
  10505. menu.value = true;
  10506. }
  10507. }
  10508. function onMousedownControl() {
  10509. if (menuDisabled.value) return;
  10510. menu.value = !menu.value;
  10511. }
  10512. function onKeydown(e) {
  10513. if (!e.key || props.readonly || form?.isReadonly.value) return;
  10514. if (['Enter', ' ', 'ArrowDown', 'ArrowUp', 'Home', 'End'].includes(e.key)) {
  10515. e.preventDefault();
  10516. }
  10517. if (['Enter', 'ArrowDown', ' '].includes(e.key)) {
  10518. menu.value = true;
  10519. }
  10520. if (['Escape', 'Tab'].includes(e.key)) {
  10521. menu.value = false;
  10522. }
  10523. if (e.key === 'Home') {
  10524. listRef.value?.focus('first');
  10525. } else if (e.key === 'End') {
  10526. listRef.value?.focus('last');
  10527. }
  10528. // html select hotkeys
  10529. const KEYBOARD_LOOKUP_THRESHOLD = 1000; // milliseconds
  10530. function checkPrintable(e) {
  10531. const isPrintableChar = e.key.length === 1;
  10532. const noModifier = !e.ctrlKey && !e.metaKey && !e.altKey;
  10533. return isPrintableChar && noModifier;
  10534. }
  10535. if (props.multiple || !checkPrintable(e)) return;
  10536. const now = performance.now();
  10537. if (now - keyboardLookupLastTime > KEYBOARD_LOOKUP_THRESHOLD) {
  10538. keyboardLookupPrefix = '';
  10539. }
  10540. keyboardLookupPrefix += e.key.toLowerCase();
  10541. keyboardLookupLastTime = now;
  10542. const item = items.value.find(item => item.title.toLowerCase().startsWith(keyboardLookupPrefix));
  10543. if (item !== undefined) {
  10544. model.value = [item];
  10545. }
  10546. }
  10547. function select(item) {
  10548. if (props.multiple) {
  10549. const index = selected.value.findIndex(selection => props.valueComparator(selection, item.value));
  10550. if (index === -1) {
  10551. model.value = [...model.value, item];
  10552. } else {
  10553. const value = [...model.value];
  10554. value.splice(index, 1);
  10555. model.value = value;
  10556. }
  10557. } else {
  10558. model.value = [item];
  10559. menu.value = false;
  10560. }
  10561. }
  10562. function onBlur(e) {
  10563. if (!listRef.value?.$el.contains(e.relatedTarget)) {
  10564. menu.value = false;
  10565. }
  10566. }
  10567. function onAfterLeave() {
  10568. if (isFocused.value) {
  10569. vTextFieldRef.value?.focus();
  10570. }
  10571. }
  10572. function onFocusin(e) {
  10573. isFocused.value = true;
  10574. }
  10575. function onModelUpdate(v) {
  10576. if (v == null) model.value = [];else if (matchesSelector(vTextFieldRef.value, ':autofill') || matchesSelector(vTextFieldRef.value, ':-webkit-autofill')) {
  10577. const item = items.value.find(item => item.title === v);
  10578. if (item) {
  10579. select(item);
  10580. }
  10581. } else if (vTextFieldRef.value) {
  10582. vTextFieldRef.value.value = '';
  10583. }
  10584. }
  10585. useRender(() => {
  10586. const hasChips = !!(props.chips || slots.chip);
  10587. const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
  10588. const isDirty = model.value.length > 0;
  10589. const [textFieldProps] = VTextField.filterProps(props);
  10590. const placeholder = isDirty || !isFocused.value && props.label && !props.persistentPlaceholder ? undefined : props.placeholder;
  10591. return createVNode(VTextField, mergeProps({
  10592. "ref": vTextFieldRef
  10593. }, textFieldProps, {
  10594. "modelValue": model.value.map(v => v.props.value).join(', '),
  10595. "onUpdate:modelValue": onModelUpdate,
  10596. "focused": isFocused.value,
  10597. "onUpdate:focused": $event => isFocused.value = $event,
  10598. "validationValue": model.externalValue,
  10599. "dirty": isDirty,
  10600. "class": ['v-select', {
  10601. 'v-select--active-menu': menu.value,
  10602. 'v-select--chips': !!props.chips,
  10603. [`v-select--${props.multiple ? 'multiple' : 'single'}`]: true,
  10604. 'v-select--selected': model.value.length,
  10605. 'v-select--selection-slot': !!slots.selection
  10606. }, props.class],
  10607. "style": props.style,
  10608. "inputmode": "none",
  10609. "placeholder": placeholder,
  10610. "onClick:clear": onClear,
  10611. "onMousedown:control": onMousedownControl,
  10612. "onBlur": onBlur,
  10613. "onKeydown": onKeydown
  10614. }), {
  10615. ...slots,
  10616. default: () => createVNode(Fragment, null, [createVNode(VMenu, mergeProps({
  10617. "ref": vMenuRef,
  10618. "modelValue": menu.value,
  10619. "onUpdate:modelValue": $event => menu.value = $event,
  10620. "activator": "parent",
  10621. "contentClass": "v-select__content",
  10622. "disabled": menuDisabled.value,
  10623. "eager": props.eager,
  10624. "maxHeight": 310,
  10625. "openOnClick": false,
  10626. "closeOnContentClick": false,
  10627. "transition": props.transition,
  10628. "onAfterLeave": onAfterLeave
  10629. }, props.menuProps), {
  10630. default: () => [hasList && createVNode(VList, {
  10631. "ref": listRef,
  10632. "selected": selected.value,
  10633. "selectStrategy": props.multiple ? 'independent' : 'single-independent',
  10634. "onMousedown": e => e.preventDefault(),
  10635. "onKeydown": onListKeydown,
  10636. "onFocusin": onFocusin,
  10637. "onScrollPassive": onListScroll,
  10638. "tabindex": "-1",
  10639. "color": props.itemColor ?? props.color
  10640. }, {
  10641. default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? createVNode(VListItem, {
  10642. "title": t(props.noDataText)
  10643. }, null)), createVNode(VVirtualScroll, {
  10644. "renderless": true,
  10645. "items": displayItems.value
  10646. }, {
  10647. default: _ref2 => {
  10648. let {
  10649. item,
  10650. index,
  10651. itemRef
  10652. } = _ref2;
  10653. const itemProps = mergeProps(item.props, {
  10654. ref: itemRef,
  10655. key: index,
  10656. onClick: () => select(item)
  10657. });
  10658. return slots.item?.({
  10659. item,
  10660. index,
  10661. props: itemProps
  10662. }) ?? createVNode(VListItem, itemProps, {
  10663. prepend: _ref3 => {
  10664. let {
  10665. isSelected
  10666. } = _ref3;
  10667. return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
  10668. "key": item.value,
  10669. "modelValue": isSelected,
  10670. "ripple": false,
  10671. "tabindex": "-1"
  10672. }, null) : undefined, item.props.prependIcon && createVNode(VIcon, {
  10673. "icon": item.props.prependIcon
  10674. }, null)]);
  10675. }
  10676. });
  10677. }
  10678. }), slots['append-item']?.()]
  10679. })]
  10680. }), selections.value.map((item, index) => {
  10681. function onChipClose(e) {
  10682. e.stopPropagation();
  10683. e.preventDefault();
  10684. select(item);
  10685. }
  10686. const slotProps = {
  10687. 'onClick:close': onChipClose,
  10688. onMousedown(e) {
  10689. e.preventDefault();
  10690. e.stopPropagation();
  10691. },
  10692. modelValue: true,
  10693. 'onUpdate:modelValue': undefined
  10694. };
  10695. return createVNode("div", {
  10696. "key": item.value,
  10697. "class": "v-select__selection"
  10698. }, [hasChips ? !slots.chip ? createVNode(VChip, mergeProps({
  10699. "key": "chip",
  10700. "closable": props.closableChips,
  10701. "size": "small",
  10702. "text": item.title
  10703. }, slotProps), null) : createVNode(VDefaultsProvider, {
  10704. "key": "chip-defaults",
  10705. "defaults": {
  10706. VChip: {
  10707. closable: props.closableChips,
  10708. size: 'small',
  10709. text: item.title
  10710. }
  10711. }
  10712. }, {
  10713. default: () => [slots.chip?.({
  10714. item,
  10715. index,
  10716. props: slotProps
  10717. })]
  10718. }) : slots.selection?.({
  10719. item,
  10720. index
  10721. }) ?? createVNode("span", {
  10722. "class": "v-select__selection-text"
  10723. }, [item.title, props.multiple && index < selections.value.length - 1 && createVNode("span", {
  10724. "class": "v-select__selection-comma"
  10725. }, [createTextVNode(",")])])]);
  10726. })]),
  10727. 'append-inner': function () {
  10728. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  10729. args[_key] = arguments[_key];
  10730. }
  10731. return createVNode(Fragment, null, [slots['append-inner']?.(...args), props.menuIcon ? createVNode(VIcon, {
  10732. "class": "v-select__menu-icon",
  10733. "icon": props.menuIcon
  10734. }, null) : undefined]);
  10735. }
  10736. });
  10737. });
  10738. return forwardRefs({
  10739. isFocused,
  10740. menu,
  10741. select
  10742. }, vTextFieldRef);
  10743. }
  10744. });
  10745. /* eslint-disable max-statements */
  10746. /* eslint-disable no-labels */
  10747. // Types
  10748. // Composables
  10749. const defaultFilter = (value, query, item) => {
  10750. if (value == null || query == null) return -1;
  10751. return value.toString().toLocaleLowerCase().indexOf(query.toString().toLocaleLowerCase());
  10752. };
  10753. const makeFilterProps = propsFactory({
  10754. customFilter: Function,
  10755. customKeyFilter: Object,
  10756. filterKeys: [Array, String],
  10757. filterMode: {
  10758. type: String,
  10759. default: 'intersection'
  10760. },
  10761. noFilter: Boolean
  10762. }, 'filter');
  10763. function filterItems(items, query, options) {
  10764. const array = [];
  10765. // always ensure we fall back to a functioning filter
  10766. const filter = options?.default ?? defaultFilter;
  10767. const keys = options?.filterKeys ? wrapInArray(options.filterKeys) : false;
  10768. const customFiltersLength = Object.keys(options?.customKeyFilter ?? {}).length;
  10769. if (!items?.length) return array;
  10770. loop: for (let i = 0; i < items.length; i++) {
  10771. const item = items[i];
  10772. const customMatches = {};
  10773. const defaultMatches = {};
  10774. let match = -1;
  10775. if (query && !options?.noFilter) {
  10776. if (typeof item === 'object') {
  10777. const filterKeys = keys || Object.keys(item);
  10778. for (const key of filterKeys) {
  10779. const value = getPropertyFromItem(item, key, item);
  10780. const keyFilter = options?.customKeyFilter?.[key];
  10781. match = keyFilter ? keyFilter(value, query, item) : filter(value, query, item);
  10782. if (match !== -1 && match !== false) {
  10783. if (keyFilter) customMatches[key] = match;else defaultMatches[key] = match;
  10784. } else if (options?.filterMode === 'every') {
  10785. continue loop;
  10786. }
  10787. }
  10788. } else {
  10789. match = filter(item, query, item);
  10790. if (match !== -1 && match !== false) {
  10791. defaultMatches.title = match;
  10792. }
  10793. }
  10794. const defaultMatchesLength = Object.keys(defaultMatches).length;
  10795. const customMatchesLength = Object.keys(customMatches).length;
  10796. if (!defaultMatchesLength && !customMatchesLength) continue;
  10797. if (options?.filterMode === 'union' && customMatchesLength !== customFiltersLength && !defaultMatchesLength) continue;
  10798. if (options?.filterMode === 'intersection' && (customMatchesLength !== customFiltersLength || !defaultMatchesLength)) continue;
  10799. }
  10800. array.push({
  10801. index: i,
  10802. matches: {
  10803. ...defaultMatches,
  10804. ...customMatches
  10805. }
  10806. });
  10807. }
  10808. return array;
  10809. }
  10810. function useFilter(props, items, query, options) {
  10811. const filteredItems = ref([]);
  10812. const filteredMatches = ref(new Map());
  10813. const transformedItems = computed(() => options?.transform ? unref(items).map(options?.transform) : unref(items));
  10814. watchEffect(() => {
  10815. const _query = typeof query === 'function' ? query() : unref(query);
  10816. const strQuery = typeof _query !== 'string' && typeof _query !== 'number' ? '' : String(_query);
  10817. const results = filterItems(transformedItems.value, strQuery, {
  10818. customKeyFilter: props.customKeyFilter,
  10819. default: props.customFilter,
  10820. filterKeys: props.filterKeys,
  10821. filterMode: props.filterMode,
  10822. noFilter: props.noFilter
  10823. });
  10824. const originalItems = unref(items);
  10825. const _filteredItems = [];
  10826. const _filteredMatches = new Map();
  10827. results.forEach(_ref => {
  10828. let {
  10829. index,
  10830. matches
  10831. } = _ref;
  10832. const item = originalItems[index];
  10833. _filteredItems.push(item);
  10834. _filteredMatches.set(item.value, matches);
  10835. });
  10836. filteredItems.value = _filteredItems;
  10837. filteredMatches.value = _filteredMatches;
  10838. });
  10839. function getMatches(item) {
  10840. return filteredMatches.value.get(item.value);
  10841. }
  10842. return {
  10843. filteredItems,
  10844. filteredMatches,
  10845. getMatches
  10846. };
  10847. }
  10848. // Types
  10849. function highlightResult$1(text, matches, length) {
  10850. if (matches == null) return text;
  10851. if (Array.isArray(matches)) throw new Error('Multiple matches is not implemented');
  10852. return typeof matches === 'number' && ~matches ? createVNode(Fragment, null, [createVNode("span", {
  10853. "class": "v-autocomplete__unmask"
  10854. }, [text.substr(0, matches)]), createVNode("span", {
  10855. "class": "v-autocomplete__mask"
  10856. }, [text.substr(matches, length)]), createVNode("span", {
  10857. "class": "v-autocomplete__unmask"
  10858. }, [text.substr(matches + length)])]) : text;
  10859. }
  10860. const makeVAutocompleteProps = propsFactory({
  10861. autoSelectFirst: {
  10862. type: [Boolean, String]
  10863. },
  10864. search: String,
  10865. ...makeFilterProps({
  10866. filterKeys: ['title']
  10867. }),
  10868. ...makeSelectProps(),
  10869. ...omit(makeVTextFieldProps({
  10870. modelValue: null
  10871. }), ['validationValue', 'dirty', 'appendInnerIcon']),
  10872. ...makeTransitionProps({
  10873. transition: false
  10874. })
  10875. }, 'VAutocomplete');
  10876. const VAutocomplete = genericComponent()({
  10877. name: 'VAutocomplete',
  10878. props: makeVAutocompleteProps(),
  10879. emits: {
  10880. 'update:focused': focused => true,
  10881. 'update:search': val => true,
  10882. 'update:modelValue': val => true,
  10883. 'update:menu': val => true
  10884. },
  10885. setup(props, _ref) {
  10886. let {
  10887. slots
  10888. } = _ref;
  10889. const {
  10890. t
  10891. } = useLocale();
  10892. const vTextFieldRef = ref();
  10893. const isFocused = shallowRef(false);
  10894. const isPristine = shallowRef(true);
  10895. const listHasFocus = shallowRef(false);
  10896. const vMenuRef = ref();
  10897. const _menu = useProxiedModel(props, 'menu');
  10898. const menu = computed({
  10899. get: () => _menu.value,
  10900. set: v => {
  10901. if (_menu.value && !v && vMenuRef.value?.ΨopenChildren) return;
  10902. _menu.value = v;
  10903. }
  10904. });
  10905. const selectionIndex = shallowRef(-1);
  10906. const color = computed(() => vTextFieldRef.value?.color);
  10907. const {
  10908. items,
  10909. transformIn,
  10910. transformOut
  10911. } = useItems(props);
  10912. const {
  10913. textColorClasses,
  10914. textColorStyles
  10915. } = useTextColor(color);
  10916. const search = useProxiedModel(props, 'search', '');
  10917. const model = useProxiedModel(props, 'modelValue', [], v => transformIn(v === null ? [null] : wrapInArray(v)), v => {
  10918. const transformed = transformOut(v);
  10919. return props.multiple ? transformed : transformed[0] ?? null;
  10920. });
  10921. const form = useForm();
  10922. const {
  10923. filteredItems,
  10924. getMatches
  10925. } = useFilter(props, items, () => isPristine.value ? '' : search.value);
  10926. const selections = computed(() => {
  10927. return model.value.map(v => {
  10928. return items.value.find(item => {
  10929. const itemRawValue = getPropertyFromItem(item.raw, props.itemValue);
  10930. const modelRawValue = getPropertyFromItem(v.raw, props.itemValue);
  10931. if (itemRawValue === undefined || modelRawValue === undefined) return false;
  10932. return props.returnObject ? props.valueComparator(itemRawValue, modelRawValue) : props.valueComparator(item.value, v.value);
  10933. }) || v;
  10934. });
  10935. });
  10936. const displayItems = computed(() => {
  10937. if (props.hideSelected) {
  10938. return filteredItems.value.filter(filteredItem => !selections.value.some(s => s.value === filteredItem.value));
  10939. }
  10940. return filteredItems.value;
  10941. });
  10942. const selected = computed(() => selections.value.map(selection => selection.props.value));
  10943. const selection = computed(() => selections.value[selectionIndex.value]);
  10944. const highlightFirst = computed(() => {
  10945. const selectFirst = props.autoSelectFirst === true || props.autoSelectFirst === 'exact' && search.value === displayItems.value[0]?.title;
  10946. return selectFirst && displayItems.value.length > 0 && !isPristine.value && !listHasFocus.value;
  10947. });
  10948. const menuDisabled = computed(() => props.hideNoData && !items.value.length || props.readonly || form?.isReadonly.value);
  10949. const listRef = ref();
  10950. const {
  10951. onListScroll,
  10952. onListKeydown
  10953. } = useScrolling(listRef, vTextFieldRef);
  10954. function onClear(e) {
  10955. if (props.openOnClear) {
  10956. menu.value = true;
  10957. }
  10958. search.value = '';
  10959. }
  10960. function onMousedownControl() {
  10961. if (menuDisabled.value) return;
  10962. menu.value = true;
  10963. }
  10964. function onMousedownMenuIcon(e) {
  10965. if (menuDisabled.value) return;
  10966. if (isFocused.value) {
  10967. e.preventDefault();
  10968. e.stopPropagation();
  10969. }
  10970. menu.value = !menu.value;
  10971. }
  10972. function onKeydown(e) {
  10973. if (props.readonly || form?.isReadonly.value) return;
  10974. const selectionStart = vTextFieldRef.value.selectionStart;
  10975. const length = selected.value.length;
  10976. if (selectionIndex.value > -1 || ['Enter', 'ArrowDown', 'ArrowUp'].includes(e.key)) {
  10977. e.preventDefault();
  10978. }
  10979. if (['Enter', 'ArrowDown'].includes(e.key)) {
  10980. menu.value = true;
  10981. }
  10982. if (['Escape'].includes(e.key)) {
  10983. menu.value = false;
  10984. }
  10985. if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key)) {
  10986. select(filteredItems.value[0]);
  10987. }
  10988. if (e.key === 'ArrowDown' && highlightFirst.value) {
  10989. listRef.value?.focus('next');
  10990. }
  10991. if (!props.multiple) return;
  10992. if (['Backspace', 'Delete'].includes(e.key)) {
  10993. if (selectionIndex.value < 0) {
  10994. if (e.key === 'Backspace' && !search.value) {
  10995. selectionIndex.value = length - 1;
  10996. }
  10997. return;
  10998. }
  10999. const originalSelectionIndex = selectionIndex.value;
  11000. if (selection.value) select(selection.value);
  11001. selectionIndex.value = originalSelectionIndex >= length - 1 ? length - 2 : originalSelectionIndex;
  11002. }
  11003. if (e.key === 'ArrowLeft') {
  11004. if (selectionIndex.value < 0 && selectionStart > 0) return;
  11005. const prev = selectionIndex.value > -1 ? selectionIndex.value - 1 : length - 1;
  11006. if (selections.value[prev]) {
  11007. selectionIndex.value = prev;
  11008. } else {
  11009. selectionIndex.value = -1;
  11010. vTextFieldRef.value.setSelectionRange(search.value?.length, search.value?.length);
  11011. }
  11012. }
  11013. if (e.key === 'ArrowRight') {
  11014. if (selectionIndex.value < 0) return;
  11015. const next = selectionIndex.value + 1;
  11016. if (selections.value[next]) {
  11017. selectionIndex.value = next;
  11018. } else {
  11019. selectionIndex.value = -1;
  11020. vTextFieldRef.value.setSelectionRange(0, 0);
  11021. }
  11022. }
  11023. }
  11024. function onInput(e) {
  11025. search.value = e.target.value;
  11026. }
  11027. function onChange(e) {
  11028. if (matchesSelector(vTextFieldRef.value, ':autofill') || matchesSelector(vTextFieldRef.value, ':-webkit-autofill')) {
  11029. const item = items.value.find(item => item.title === e.target.value);
  11030. if (item) {
  11031. select(item);
  11032. }
  11033. }
  11034. }
  11035. function onAfterLeave() {
  11036. if (isFocused.value) {
  11037. isPristine.value = true;
  11038. vTextFieldRef.value?.focus();
  11039. }
  11040. }
  11041. function onFocusin(e) {
  11042. isFocused.value = true;
  11043. setTimeout(() => {
  11044. listHasFocus.value = true;
  11045. });
  11046. }
  11047. function onFocusout(e) {
  11048. listHasFocus.value = false;
  11049. }
  11050. function onUpdateModelValue(v) {
  11051. if (v == null || v === '' && !props.multiple) model.value = [];
  11052. }
  11053. const isSelecting = shallowRef(false);
  11054. function select(item) {
  11055. if (props.multiple) {
  11056. const index = selected.value.findIndex(selection => props.valueComparator(selection, item.value));
  11057. if (index === -1) {
  11058. model.value = [...model.value, item];
  11059. } else {
  11060. const value = [...model.value];
  11061. value.splice(index, 1);
  11062. model.value = value;
  11063. }
  11064. } else {
  11065. model.value = [item];
  11066. isSelecting.value = true;
  11067. search.value = item.title;
  11068. menu.value = false;
  11069. isPristine.value = true;
  11070. nextTick(() => isSelecting.value = false);
  11071. }
  11072. }
  11073. watch(isFocused, (val, oldVal) => {
  11074. if (val === oldVal) return;
  11075. if (val) {
  11076. isSelecting.value = true;
  11077. search.value = props.multiple ? '' : String(selections.value.at(-1)?.props.title ?? '');
  11078. isPristine.value = true;
  11079. nextTick(() => isSelecting.value = false);
  11080. } else {
  11081. if (!props.multiple && !search.value) model.value = [];else if (highlightFirst.value && !listHasFocus.value && !selections.value.some(_ref2 => {
  11082. let {
  11083. value
  11084. } = _ref2;
  11085. return value === displayItems.value[0].value;
  11086. })) {
  11087. select(displayItems.value[0]);
  11088. }
  11089. menu.value = false;
  11090. search.value = '';
  11091. selectionIndex.value = -1;
  11092. }
  11093. });
  11094. watch(search, val => {
  11095. if (!isFocused.value || isSelecting.value) return;
  11096. if (val) menu.value = true;
  11097. isPristine.value = !val;
  11098. });
  11099. useRender(() => {
  11100. const hasChips = !!(props.chips || slots.chip);
  11101. const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
  11102. const isDirty = model.value.length > 0;
  11103. const [textFieldProps] = VTextField.filterProps(props);
  11104. return createVNode(VTextField, mergeProps({
  11105. "ref": vTextFieldRef
  11106. }, textFieldProps, {
  11107. "modelValue": search.value,
  11108. "onUpdate:modelValue": onUpdateModelValue,
  11109. "focused": isFocused.value,
  11110. "onUpdate:focused": $event => isFocused.value = $event,
  11111. "validationValue": model.externalValue,
  11112. "dirty": isDirty,
  11113. "onInput": onInput,
  11114. "onChange": onChange,
  11115. "class": ['v-autocomplete', `v-autocomplete--${props.multiple ? 'multiple' : 'single'}`, {
  11116. 'v-autocomplete--active-menu': menu.value,
  11117. 'v-autocomplete--chips': !!props.chips,
  11118. 'v-autocomplete--selection-slot': !!slots.selection,
  11119. 'v-autocomplete--selecting-index': selectionIndex.value > -1
  11120. }, props.class],
  11121. "style": props.style,
  11122. "readonly": props.readonly,
  11123. "placeholder": isDirty ? undefined : props.placeholder,
  11124. "onClick:clear": onClear,
  11125. "onMousedown:control": onMousedownControl,
  11126. "onKeydown": onKeydown
  11127. }), {
  11128. ...slots,
  11129. default: () => createVNode(Fragment, null, [createVNode(VMenu, mergeProps({
  11130. "ref": vMenuRef,
  11131. "modelValue": menu.value,
  11132. "onUpdate:modelValue": $event => menu.value = $event,
  11133. "activator": "parent",
  11134. "contentClass": "v-autocomplete__content",
  11135. "disabled": menuDisabled.value,
  11136. "eager": props.eager,
  11137. "maxHeight": 310,
  11138. "openOnClick": false,
  11139. "closeOnContentClick": false,
  11140. "transition": props.transition,
  11141. "onAfterLeave": onAfterLeave
  11142. }, props.menuProps), {
  11143. default: () => [hasList && createVNode(VList, {
  11144. "ref": listRef,
  11145. "selected": selected.value,
  11146. "selectStrategy": props.multiple ? 'independent' : 'single-independent',
  11147. "onMousedown": e => e.preventDefault(),
  11148. "onKeydown": onListKeydown,
  11149. "onFocusin": onFocusin,
  11150. "onFocusout": onFocusout,
  11151. "onScrollPassive": onListScroll,
  11152. "tabindex": "-1",
  11153. "color": props.itemColor ?? props.color
  11154. }, {
  11155. default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? createVNode(VListItem, {
  11156. "title": t(props.noDataText)
  11157. }, null)), createVNode(VVirtualScroll, {
  11158. "renderless": true,
  11159. "items": displayItems.value
  11160. }, {
  11161. default: _ref3 => {
  11162. let {
  11163. item,
  11164. index,
  11165. itemRef
  11166. } = _ref3;
  11167. const itemProps = mergeProps(item.props, {
  11168. ref: itemRef,
  11169. key: index,
  11170. active: highlightFirst.value && index === 0 ? true : undefined,
  11171. onClick: () => select(item)
  11172. });
  11173. return slots.item?.({
  11174. item,
  11175. index,
  11176. props: itemProps
  11177. }) ?? createVNode(VListItem, itemProps, {
  11178. prepend: _ref4 => {
  11179. let {
  11180. isSelected
  11181. } = _ref4;
  11182. return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
  11183. "key": item.value,
  11184. "modelValue": isSelected,
  11185. "ripple": false,
  11186. "tabindex": "-1"
  11187. }, null) : undefined, item.props.prependIcon && createVNode(VIcon, {
  11188. "icon": item.props.prependIcon
  11189. }, null)]);
  11190. },
  11191. title: () => {
  11192. return isPristine.value ? item.title : highlightResult$1(item.title, getMatches(item)?.title, search.value?.length ?? 0);
  11193. }
  11194. });
  11195. }
  11196. }), slots['append-item']?.()]
  11197. })]
  11198. }), selections.value.map((item, index) => {
  11199. function onChipClose(e) {
  11200. e.stopPropagation();
  11201. e.preventDefault();
  11202. select(item);
  11203. }
  11204. const slotProps = {
  11205. 'onClick:close': onChipClose,
  11206. onMousedown(e) {
  11207. e.preventDefault();
  11208. e.stopPropagation();
  11209. },
  11210. modelValue: true,
  11211. 'onUpdate:modelValue': undefined
  11212. };
  11213. return createVNode("div", {
  11214. "key": item.value,
  11215. "class": ['v-autocomplete__selection', index === selectionIndex.value && ['v-autocomplete__selection--selected', textColorClasses.value]],
  11216. "style": index === selectionIndex.value ? textColorStyles.value : {}
  11217. }, [hasChips ? !slots.chip ? createVNode(VChip, mergeProps({
  11218. "key": "chip",
  11219. "closable": props.closableChips,
  11220. "size": "small",
  11221. "text": item.title
  11222. }, slotProps), null) : createVNode(VDefaultsProvider, {
  11223. "key": "chip-defaults",
  11224. "defaults": {
  11225. VChip: {
  11226. closable: props.closableChips,
  11227. size: 'small',
  11228. text: item.title
  11229. }
  11230. }
  11231. }, {
  11232. default: () => [slots.chip?.({
  11233. item,
  11234. index,
  11235. props: slotProps
  11236. })]
  11237. }) : slots.selection?.({
  11238. item,
  11239. index
  11240. }) ?? createVNode("span", {
  11241. "class": "v-autocomplete__selection-text"
  11242. }, [item.title, props.multiple && index < selections.value.length - 1 && createVNode("span", {
  11243. "class": "v-autocomplete__selection-comma"
  11244. }, [createTextVNode(",")])])]);
  11245. })]),
  11246. 'append-inner': function () {
  11247. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  11248. args[_key] = arguments[_key];
  11249. }
  11250. return createVNode(Fragment, null, [slots['append-inner']?.(...args), props.menuIcon ? createVNode(VIcon, {
  11251. "class": "v-autocomplete__menu-icon",
  11252. "icon": props.menuIcon,
  11253. "onMousedown": onMousedownMenuIcon,
  11254. "onClick": noop
  11255. }, null) : undefined]);
  11256. }
  11257. });
  11258. });
  11259. return forwardRefs({
  11260. isFocused,
  11261. isPristine,
  11262. menu,
  11263. search,
  11264. filteredItems,
  11265. select
  11266. }, vTextFieldRef);
  11267. }
  11268. });
  11269. const makeVBadgeProps = propsFactory({
  11270. bordered: Boolean,
  11271. color: String,
  11272. content: [Number, String],
  11273. dot: Boolean,
  11274. floating: Boolean,
  11275. icon: IconValue,
  11276. inline: Boolean,
  11277. label: {
  11278. type: String,
  11279. default: '$vuetify.badge'
  11280. },
  11281. max: [Number, String],
  11282. modelValue: {
  11283. type: Boolean,
  11284. default: true
  11285. },
  11286. offsetX: [Number, String],
  11287. offsetY: [Number, String],
  11288. textColor: String,
  11289. ...makeComponentProps(),
  11290. ...makeLocationProps({
  11291. location: 'top end'
  11292. }),
  11293. ...makeRoundedProps(),
  11294. ...makeTagProps(),
  11295. ...makeThemeProps(),
  11296. ...makeTransitionProps({
  11297. transition: 'scale-rotate-transition'
  11298. })
  11299. }, 'VBadge');
  11300. const VBadge = genericComponent()({
  11301. name: 'VBadge',
  11302. inheritAttrs: false,
  11303. props: makeVBadgeProps(),
  11304. setup(props, ctx) {
  11305. const {
  11306. backgroundColorClasses,
  11307. backgroundColorStyles
  11308. } = useBackgroundColor(toRef(props, 'color'));
  11309. const {
  11310. roundedClasses
  11311. } = useRounded(props);
  11312. const {
  11313. t
  11314. } = useLocale();
  11315. const {
  11316. textColorClasses,
  11317. textColorStyles
  11318. } = useTextColor(toRef(props, 'textColor'));
  11319. const {
  11320. themeClasses
  11321. } = useTheme();
  11322. const {
  11323. locationStyles
  11324. } = useLocation(props, true, side => {
  11325. const base = props.floating ? props.dot ? 2 : 4 : props.dot ? 8 : 12;
  11326. return base + (['top', 'bottom'].includes(side) ? +(props.offsetY ?? 0) : ['left', 'right'].includes(side) ? +(props.offsetX ?? 0) : 0);
  11327. });
  11328. useRender(() => {
  11329. const value = Number(props.content);
  11330. const content = !props.max || isNaN(value) ? props.content : value <= +props.max ? value : `${props.max}+`;
  11331. const [badgeAttrs, attrs] = pick(ctx.attrs, ['aria-atomic', 'aria-label', 'aria-live', 'role', 'title']);
  11332. return createVNode(props.tag, mergeProps({
  11333. "class": ['v-badge', {
  11334. 'v-badge--bordered': props.bordered,
  11335. 'v-badge--dot': props.dot,
  11336. 'v-badge--floating': props.floating,
  11337. 'v-badge--inline': props.inline
  11338. }, props.class]
  11339. }, attrs, {
  11340. "style": props.style
  11341. }), {
  11342. default: () => [createVNode("div", {
  11343. "class": "v-badge__wrapper"
  11344. }, [ctx.slots.default?.(), createVNode(MaybeTransition, {
  11345. "transition": props.transition
  11346. }, {
  11347. default: () => [withDirectives(createVNode("span", mergeProps({
  11348. "class": ['v-badge__badge', themeClasses.value, backgroundColorClasses.value, roundedClasses.value, textColorClasses.value],
  11349. "style": [backgroundColorStyles.value, textColorStyles.value, props.inline ? {} : locationStyles.value],
  11350. "aria-atomic": "true",
  11351. "aria-label": t(props.label, value),
  11352. "aria-live": "polite",
  11353. "role": "status"
  11354. }, badgeAttrs), [props.dot ? undefined : ctx.slots.badge ? ctx.slots.badge?.() : props.icon ? createVNode(VIcon, {
  11355. "icon": props.icon
  11356. }, null) : content]), [[vShow, props.modelValue]])]
  11357. })])]
  11358. });
  11359. });
  11360. return {};
  11361. }
  11362. });
  11363. const makeVBannerActionsProps = propsFactory({
  11364. color: String,
  11365. density: String,
  11366. ...makeComponentProps()
  11367. }, 'VBannerActions');
  11368. const VBannerActions = genericComponent()({
  11369. name: 'VBannerActions',
  11370. props: makeVBannerActionsProps(),
  11371. setup(props, _ref) {
  11372. let {
  11373. slots
  11374. } = _ref;
  11375. provideDefaults({
  11376. VBtn: {
  11377. color: props.color,
  11378. density: props.density,
  11379. variant: 'text'
  11380. }
  11381. });
  11382. useRender(() => createVNode("div", {
  11383. "class": ['v-banner-actions', props.class],
  11384. "style": props.style
  11385. }, [slots.default?.()]));
  11386. return {};
  11387. }
  11388. });
  11389. // Utilities
  11390. const VBannerText = createSimpleFunctional('v-banner-text');
  11391. // Types
  11392. const makeVBannerProps = propsFactory({
  11393. avatar: String,
  11394. color: String,
  11395. icon: IconValue,
  11396. lines: String,
  11397. stacked: Boolean,
  11398. sticky: Boolean,
  11399. text: String,
  11400. ...makeBorderProps(),
  11401. ...makeComponentProps(),
  11402. ...makeDensityProps(),
  11403. ...makeDimensionProps(),
  11404. ...makeElevationProps(),
  11405. ...makeLocationProps(),
  11406. ...makePositionProps(),
  11407. ...makeRoundedProps(),
  11408. ...makeTagProps(),
  11409. ...makeThemeProps()
  11410. }, 'VBanner');
  11411. const VBanner = genericComponent()({
  11412. name: 'VBanner',
  11413. props: makeVBannerProps(),
  11414. setup(props, _ref) {
  11415. let {
  11416. slots
  11417. } = _ref;
  11418. const {
  11419. borderClasses
  11420. } = useBorder(props);
  11421. const {
  11422. densityClasses
  11423. } = useDensity(props);
  11424. const {
  11425. mobile
  11426. } = useDisplay();
  11427. const {
  11428. dimensionStyles
  11429. } = useDimension(props);
  11430. const {
  11431. elevationClasses
  11432. } = useElevation(props);
  11433. const {
  11434. locationStyles
  11435. } = useLocation(props);
  11436. const {
  11437. positionClasses
  11438. } = usePosition(props);
  11439. const {
  11440. roundedClasses
  11441. } = useRounded(props);
  11442. const {
  11443. themeClasses
  11444. } = provideTheme(props);
  11445. const color = toRef(props, 'color');
  11446. const density = toRef(props, 'density');
  11447. provideDefaults({
  11448. VBannerActions: {
  11449. color,
  11450. density
  11451. }
  11452. });
  11453. useRender(() => {
  11454. const hasText = !!(props.text || slots.text);
  11455. const hasPrependMedia = !!(props.avatar || props.icon);
  11456. const hasPrepend = !!(hasPrependMedia || slots.prepend);
  11457. return createVNode(props.tag, {
  11458. "class": ['v-banner', {
  11459. 'v-banner--stacked': props.stacked || mobile.value,
  11460. 'v-banner--sticky': props.sticky,
  11461. [`v-banner--${props.lines}-line`]: !!props.lines
  11462. }, borderClasses.value, densityClasses.value, elevationClasses.value, positionClasses.value, roundedClasses.value, themeClasses.value, props.class],
  11463. "style": [dimensionStyles.value, locationStyles.value, props.style],
  11464. "role": "banner"
  11465. }, {
  11466. default: () => [hasPrepend && createVNode("div", {
  11467. "key": "prepend",
  11468. "class": "v-banner__prepend"
  11469. }, [!slots.prepend ? createVNode(VAvatar, {
  11470. "key": "prepend-avatar",
  11471. "color": color.value,
  11472. "density": density.value,
  11473. "icon": props.icon,
  11474. "image": props.avatar
  11475. }, null) : createVNode(VDefaultsProvider, {
  11476. "key": "prepend-defaults",
  11477. "disabled": !hasPrependMedia,
  11478. "defaults": {
  11479. VAvatar: {
  11480. color: color.value,
  11481. density: density.value,
  11482. icon: props.icon,
  11483. image: props.avatar
  11484. }
  11485. }
  11486. }, slots.prepend)]), createVNode("div", {
  11487. "class": "v-banner__content"
  11488. }, [hasText && createVNode(VBannerText, {
  11489. "key": "text"
  11490. }, {
  11491. default: () => [slots.text?.() ?? props.text]
  11492. }), slots.default?.()]), slots.actions && createVNode(VBannerActions, {
  11493. "key": "actions"
  11494. }, slots.actions)]
  11495. });
  11496. });
  11497. }
  11498. });
  11499. const makeVBottomNavigationProps = propsFactory({
  11500. bgColor: String,
  11501. color: String,
  11502. grow: Boolean,
  11503. mode: {
  11504. type: String,
  11505. validator: v => !v || ['horizontal', 'shift'].includes(v)
  11506. },
  11507. height: {
  11508. type: [Number, String],
  11509. default: 56
  11510. },
  11511. active: {
  11512. type: Boolean,
  11513. default: true
  11514. },
  11515. ...makeBorderProps(),
  11516. ...makeComponentProps(),
  11517. ...makeDensityProps(),
  11518. ...makeElevationProps(),
  11519. ...makeRoundedProps(),
  11520. ...makeLayoutItemProps({
  11521. name: 'bottom-navigation'
  11522. }),
  11523. ...makeTagProps({
  11524. tag: 'header'
  11525. }),
  11526. ...makeGroupProps({
  11527. modelValue: true,
  11528. selectedClass: 'v-btn--selected'
  11529. }),
  11530. ...makeThemeProps()
  11531. }, 'VBottomNavigation');
  11532. const VBottomNavigation = genericComponent()({
  11533. name: 'VBottomNavigation',
  11534. props: makeVBottomNavigationProps(),
  11535. emits: {
  11536. 'update:modelValue': value => true
  11537. },
  11538. setup(props, _ref) {
  11539. let {
  11540. slots
  11541. } = _ref;
  11542. const {
  11543. themeClasses
  11544. } = useTheme();
  11545. const {
  11546. borderClasses
  11547. } = useBorder(props);
  11548. const {
  11549. backgroundColorClasses,
  11550. backgroundColorStyles
  11551. } = useBackgroundColor(toRef(props, 'bgColor'));
  11552. const {
  11553. densityClasses
  11554. } = useDensity(props);
  11555. const {
  11556. elevationClasses
  11557. } = useElevation(props);
  11558. const {
  11559. roundedClasses
  11560. } = useRounded(props);
  11561. const {
  11562. ssrBootStyles
  11563. } = useSsrBoot();
  11564. const height = computed(() => Number(props.height) - (props.density === 'comfortable' ? 8 : 0) - (props.density === 'compact' ? 16 : 0));
  11565. const isActive = toRef(props, 'active');
  11566. const {
  11567. layoutItemStyles
  11568. } = useLayoutItem({
  11569. id: props.name,
  11570. order: computed(() => parseInt(props.order, 10)),
  11571. position: computed(() => 'bottom'),
  11572. layoutSize: computed(() => isActive.value ? height.value : 0),
  11573. elementSize: height,
  11574. active: isActive,
  11575. absolute: toRef(props, 'absolute')
  11576. });
  11577. useGroup(props, VBtnToggleSymbol);
  11578. provideDefaults({
  11579. VBtn: {
  11580. color: toRef(props, 'color'),
  11581. density: toRef(props, 'density'),
  11582. stacked: computed(() => props.mode !== 'horizontal'),
  11583. variant: 'text'
  11584. }
  11585. }, {
  11586. scoped: true
  11587. });
  11588. useRender(() => {
  11589. return createVNode(props.tag, {
  11590. "class": ['v-bottom-navigation', {
  11591. 'v-bottom-navigation--active': isActive.value,
  11592. 'v-bottom-navigation--grow': props.grow,
  11593. 'v-bottom-navigation--shift': props.mode === 'shift'
  11594. }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  11595. "style": [backgroundColorStyles.value, layoutItemStyles.value, {
  11596. height: convertToUnit(height.value),
  11597. transform: `translateY(${convertToUnit(!isActive.value ? 100 : 0, '%')})`
  11598. }, ssrBootStyles.value, props.style]
  11599. }, {
  11600. default: () => [slots.default && createVNode("div", {
  11601. "class": "v-bottom-navigation__content"
  11602. }, [slots.default()])]
  11603. });
  11604. });
  11605. return {};
  11606. }
  11607. });
  11608. const makeVBreadcrumbsDividerProps = propsFactory({
  11609. divider: [Number, String],
  11610. ...makeComponentProps()
  11611. }, 'VBreadcrumbsDivider');
  11612. const VBreadcrumbsDivider = genericComponent()({
  11613. name: 'VBreadcrumbsDivider',
  11614. props: makeVBreadcrumbsDividerProps(),
  11615. setup(props, _ref) {
  11616. let {
  11617. slots
  11618. } = _ref;
  11619. useRender(() => createVNode("li", {
  11620. "class": ['v-breadcrumbs-divider', props.class],
  11621. "style": props.style
  11622. }, [slots?.default?.() ?? props.divider]));
  11623. return {};
  11624. }
  11625. });
  11626. const makeVBreadcrumbsItemProps = propsFactory({
  11627. active: Boolean,
  11628. activeClass: String,
  11629. activeColor: String,
  11630. color: String,
  11631. disabled: Boolean,
  11632. title: String,
  11633. ...makeComponentProps(),
  11634. ...makeRouterProps(),
  11635. ...makeTagProps({
  11636. tag: 'li'
  11637. })
  11638. }, 'VBreadcrumbsItem');
  11639. const VBreadcrumbsItem = genericComponent()({
  11640. name: 'VBreadcrumbsItem',
  11641. props: makeVBreadcrumbsItemProps(),
  11642. setup(props, _ref) {
  11643. let {
  11644. slots,
  11645. attrs
  11646. } = _ref;
  11647. const link = useLink(props, attrs);
  11648. const isActive = computed(() => props.active || link.isActive?.value);
  11649. const color = computed(() => isActive.value ? props.activeColor : props.color);
  11650. const {
  11651. textColorClasses,
  11652. textColorStyles
  11653. } = useTextColor(color);
  11654. useRender(() => {
  11655. return createVNode(props.tag, {
  11656. "class": ['v-breadcrumbs-item', {
  11657. 'v-breadcrumbs-item--active': isActive.value,
  11658. 'v-breadcrumbs-item--disabled': props.disabled,
  11659. [`${props.activeClass}`]: isActive.value && props.activeClass
  11660. }, textColorClasses.value, props.class],
  11661. "style": [textColorStyles.value, props.style],
  11662. "aria-current": isActive.value ? 'page' : undefined
  11663. }, {
  11664. default: () => [!link.isLink.value ? slots.default?.() ?? props.title : createVNode("a", {
  11665. "class": "v-breadcrumbs-item--link",
  11666. "href": link.href.value,
  11667. "aria-current": isActive.value ? 'page' : undefined,
  11668. "onClick": link.navigate
  11669. }, [slots.default?.() ?? props.title])]
  11670. });
  11671. });
  11672. return {};
  11673. }
  11674. });
  11675. // Types
  11676. const makeVBreadcrumbsProps = propsFactory({
  11677. activeClass: String,
  11678. activeColor: String,
  11679. bgColor: String,
  11680. color: String,
  11681. disabled: Boolean,
  11682. divider: {
  11683. type: String,
  11684. default: '/'
  11685. },
  11686. icon: IconValue,
  11687. items: {
  11688. type: Array,
  11689. default: () => []
  11690. },
  11691. ...makeComponentProps(),
  11692. ...makeDensityProps(),
  11693. ...makeRoundedProps(),
  11694. ...makeTagProps({
  11695. tag: 'ul'
  11696. })
  11697. }, 'VBreadcrumbs');
  11698. const VBreadcrumbs = genericComponent()({
  11699. name: 'VBreadcrumbs',
  11700. props: makeVBreadcrumbsProps(),
  11701. setup(props, _ref) {
  11702. let {
  11703. slots
  11704. } = _ref;
  11705. const {
  11706. backgroundColorClasses,
  11707. backgroundColorStyles
  11708. } = useBackgroundColor(toRef(props, 'bgColor'));
  11709. const {
  11710. densityClasses
  11711. } = useDensity(props);
  11712. const {
  11713. roundedClasses
  11714. } = useRounded(props);
  11715. provideDefaults({
  11716. VBreadcrumbsDivider: {
  11717. divider: toRef(props, 'divider')
  11718. },
  11719. VBreadcrumbsItem: {
  11720. activeClass: toRef(props, 'activeClass'),
  11721. activeColor: toRef(props, 'activeColor'),
  11722. color: toRef(props, 'color'),
  11723. disabled: toRef(props, 'disabled')
  11724. }
  11725. });
  11726. const items = computed(() => props.items.map(item => {
  11727. return typeof item === 'string' ? {
  11728. item: {
  11729. title: item
  11730. },
  11731. raw: item
  11732. } : {
  11733. item,
  11734. raw: item
  11735. };
  11736. }));
  11737. useRender(() => {
  11738. const hasPrepend = !!(slots.prepend || props.icon);
  11739. return createVNode(props.tag, {
  11740. "class": ['v-breadcrumbs', backgroundColorClasses.value, densityClasses.value, roundedClasses.value, props.class],
  11741. "style": [backgroundColorStyles.value, props.style]
  11742. }, {
  11743. default: () => [hasPrepend && createVNode("li", {
  11744. "key": "prepend",
  11745. "class": "v-breadcrumbs__prepend"
  11746. }, [!slots.prepend ? createVNode(VIcon, {
  11747. "key": "prepend-icon",
  11748. "start": true,
  11749. "icon": props.icon
  11750. }, null) : createVNode(VDefaultsProvider, {
  11751. "key": "prepend-defaults",
  11752. "disabled": !props.icon,
  11753. "defaults": {
  11754. VIcon: {
  11755. icon: props.icon,
  11756. start: true
  11757. }
  11758. }
  11759. }, slots.prepend)]), items.value.map((_ref2, index, array) => {
  11760. let {
  11761. item,
  11762. raw
  11763. } = _ref2;
  11764. return createVNode(Fragment, null, [createVNode(VBreadcrumbsItem, mergeProps({
  11765. "key": item.title,
  11766. "disabled": index >= array.length - 1
  11767. }, item), {
  11768. default: slots.title ? () => slots.title?.({
  11769. item: raw,
  11770. index
  11771. }) : undefined
  11772. }), index < array.length - 1 && createVNode(VBreadcrumbsDivider, null, {
  11773. default: slots.divider ? () => slots.divider?.({
  11774. item: raw,
  11775. index
  11776. }) : undefined
  11777. })]);
  11778. }), slots.default?.()]
  11779. });
  11780. });
  11781. return {};
  11782. }
  11783. });
  11784. const VCardActions = genericComponent()({
  11785. name: 'VCardActions',
  11786. props: makeComponentProps(),
  11787. setup(props, _ref) {
  11788. let {
  11789. slots
  11790. } = _ref;
  11791. provideDefaults({
  11792. VBtn: {
  11793. variant: 'text'
  11794. }
  11795. });
  11796. useRender(() => createVNode("div", {
  11797. "class": ['v-card-actions', props.class],
  11798. "style": props.style
  11799. }, [slots.default?.()]));
  11800. return {};
  11801. }
  11802. });
  11803. // Utilities
  11804. const VCardSubtitle = createSimpleFunctional('v-card-subtitle');
  11805. // Utilities
  11806. const VCardTitle = createSimpleFunctional('v-card-title');
  11807. const makeCardItemProps = propsFactory({
  11808. appendAvatar: String,
  11809. appendIcon: IconValue,
  11810. prependAvatar: String,
  11811. prependIcon: IconValue,
  11812. subtitle: String,
  11813. title: String,
  11814. ...makeComponentProps(),
  11815. ...makeDensityProps()
  11816. }, 'VCardItem');
  11817. const VCardItem = genericComponent()({
  11818. name: 'VCardItem',
  11819. props: makeCardItemProps(),
  11820. setup(props, _ref) {
  11821. let {
  11822. slots
  11823. } = _ref;
  11824. useRender(() => {
  11825. const hasPrependMedia = !!(props.prependAvatar || props.prependIcon);
  11826. const hasPrepend = !!(hasPrependMedia || slots.prepend);
  11827. const hasAppendMedia = !!(props.appendAvatar || props.appendIcon);
  11828. const hasAppend = !!(hasAppendMedia || slots.append);
  11829. const hasTitle = !!(props.title || slots.title);
  11830. const hasSubtitle = !!(props.subtitle || slots.subtitle);
  11831. return createVNode("div", {
  11832. "class": ['v-card-item', props.class],
  11833. "style": props.style
  11834. }, [hasPrepend && createVNode("div", {
  11835. "key": "prepend",
  11836. "class": "v-card-item__prepend"
  11837. }, [!slots.prepend ? hasPrependMedia && createVNode(VAvatar, {
  11838. "key": "prepend-avatar",
  11839. "density": props.density,
  11840. "icon": props.prependIcon,
  11841. "image": props.prependAvatar
  11842. }, null) : createVNode(VDefaultsProvider, {
  11843. "key": "prepend-defaults",
  11844. "disabled": !hasPrependMedia,
  11845. "defaults": {
  11846. VAvatar: {
  11847. density: props.density,
  11848. icon: props.prependIcon,
  11849. image: props.prependAvatar
  11850. }
  11851. }
  11852. }, slots.prepend)]), createVNode("div", {
  11853. "class": "v-card-item__content"
  11854. }, [hasTitle && createVNode(VCardTitle, {
  11855. "key": "title"
  11856. }, {
  11857. default: () => [slots.title?.() ?? props.title]
  11858. }), hasSubtitle && createVNode(VCardSubtitle, {
  11859. "key": "subtitle"
  11860. }, {
  11861. default: () => [slots.subtitle?.() ?? props.subtitle]
  11862. }), slots.default?.()]), hasAppend && createVNode("div", {
  11863. "key": "append",
  11864. "class": "v-card-item__append"
  11865. }, [!slots.append ? hasAppendMedia && createVNode(VAvatar, {
  11866. "key": "append-avatar",
  11867. "density": props.density,
  11868. "icon": props.appendIcon,
  11869. "image": props.appendAvatar
  11870. }, null) : createVNode(VDefaultsProvider, {
  11871. "key": "append-defaults",
  11872. "disabled": !hasAppendMedia,
  11873. "defaults": {
  11874. VAvatar: {
  11875. density: props.density,
  11876. icon: props.appendIcon,
  11877. image: props.appendAvatar
  11878. }
  11879. }
  11880. }, slots.append)])]);
  11881. });
  11882. return {};
  11883. }
  11884. });
  11885. // Utilities
  11886. const VCardText = createSimpleFunctional('v-card-text');
  11887. // Types
  11888. const makeVCardProps = propsFactory({
  11889. appendAvatar: String,
  11890. appendIcon: IconValue,
  11891. disabled: Boolean,
  11892. flat: Boolean,
  11893. hover: Boolean,
  11894. image: String,
  11895. link: {
  11896. type: Boolean,
  11897. default: undefined
  11898. },
  11899. prependAvatar: String,
  11900. prependIcon: IconValue,
  11901. ripple: {
  11902. type: [Boolean, Object],
  11903. default: true
  11904. },
  11905. subtitle: String,
  11906. text: String,
  11907. title: String,
  11908. ...makeBorderProps(),
  11909. ...makeComponentProps(),
  11910. ...makeDensityProps(),
  11911. ...makeDimensionProps(),
  11912. ...makeElevationProps(),
  11913. ...makeLoaderProps(),
  11914. ...makeLocationProps(),
  11915. ...makePositionProps(),
  11916. ...makeRoundedProps(),
  11917. ...makeRouterProps(),
  11918. ...makeTagProps(),
  11919. ...makeThemeProps(),
  11920. ...makeVariantProps({
  11921. variant: 'elevated'
  11922. })
  11923. }, 'VCard');
  11924. const VCard = genericComponent()({
  11925. name: 'VCard',
  11926. directives: {
  11927. Ripple
  11928. },
  11929. props: makeVCardProps(),
  11930. setup(props, _ref) {
  11931. let {
  11932. attrs,
  11933. slots
  11934. } = _ref;
  11935. const {
  11936. themeClasses
  11937. } = provideTheme(props);
  11938. const {
  11939. borderClasses
  11940. } = useBorder(props);
  11941. const {
  11942. colorClasses,
  11943. colorStyles,
  11944. variantClasses
  11945. } = useVariant(props);
  11946. const {
  11947. densityClasses
  11948. } = useDensity(props);
  11949. const {
  11950. dimensionStyles
  11951. } = useDimension(props);
  11952. const {
  11953. elevationClasses
  11954. } = useElevation(props);
  11955. const {
  11956. loaderClasses
  11957. } = useLoader(props);
  11958. const {
  11959. locationStyles
  11960. } = useLocation(props);
  11961. const {
  11962. positionClasses
  11963. } = usePosition(props);
  11964. const {
  11965. roundedClasses
  11966. } = useRounded(props);
  11967. const link = useLink(props, attrs);
  11968. const isLink = computed(() => props.link !== false && link.isLink.value);
  11969. const isClickable = computed(() => !props.disabled && props.link !== false && (props.link || link.isClickable.value));
  11970. useRender(() => {
  11971. const Tag = isLink.value ? 'a' : props.tag;
  11972. const hasTitle = !!(slots.title || props.title);
  11973. const hasSubtitle = !!(slots.subtitle || props.subtitle);
  11974. const hasHeader = hasTitle || hasSubtitle;
  11975. const hasAppend = !!(slots.append || props.appendAvatar || props.appendIcon);
  11976. const hasPrepend = !!(slots.prepend || props.prependAvatar || props.prependIcon);
  11977. const hasImage = !!(slots.image || props.image);
  11978. const hasCardItem = hasHeader || hasPrepend || hasAppend;
  11979. const hasText = !!(slots.text || props.text);
  11980. return withDirectives(createVNode(Tag, {
  11981. "class": ['v-card', {
  11982. 'v-card--disabled': props.disabled,
  11983. 'v-card--flat': props.flat,
  11984. 'v-card--hover': props.hover && !(props.disabled || props.flat),
  11985. 'v-card--link': isClickable.value
  11986. }, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, loaderClasses.value, positionClasses.value, roundedClasses.value, variantClasses.value, props.class],
  11987. "style": [colorStyles.value, dimensionStyles.value, locationStyles.value, props.style],
  11988. "href": link.href.value,
  11989. "onClick": isClickable.value && link.navigate,
  11990. "tabindex": props.disabled ? -1 : undefined
  11991. }, {
  11992. default: () => [hasImage && createVNode("div", {
  11993. "key": "image",
  11994. "class": "v-card__image"
  11995. }, [!slots.image ? createVNode(VImg, {
  11996. "key": "image-img",
  11997. "cover": true,
  11998. "src": props.image
  11999. }, null) : createVNode(VDefaultsProvider, {
  12000. "key": "image-defaults",
  12001. "disabled": !props.image,
  12002. "defaults": {
  12003. VImg: {
  12004. cover: true,
  12005. src: props.image
  12006. }
  12007. }
  12008. }, slots.image)]), createVNode(LoaderSlot, {
  12009. "name": "v-card",
  12010. "active": !!props.loading,
  12011. "color": typeof props.loading === 'boolean' ? undefined : props.loading
  12012. }, {
  12013. default: slots.loader
  12014. }), hasCardItem && createVNode(VCardItem, {
  12015. "key": "item",
  12016. "prependAvatar": props.prependAvatar,
  12017. "prependIcon": props.prependIcon,
  12018. "title": props.title,
  12019. "subtitle": props.subtitle,
  12020. "appendAvatar": props.appendAvatar,
  12021. "appendIcon": props.appendIcon
  12022. }, {
  12023. default: slots.item,
  12024. prepend: slots.prepend,
  12025. title: slots.title,
  12026. subtitle: slots.subtitle,
  12027. append: slots.append
  12028. }), hasText && createVNode(VCardText, {
  12029. "key": "text"
  12030. }, {
  12031. default: () => [slots.text?.() ?? props.text]
  12032. }), slots.default?.(), slots.actions && createVNode(VCardActions, null, {
  12033. default: slots.actions
  12034. }), genOverlays(isClickable.value, 'v-card')]
  12035. }), [[resolveDirective("ripple"), isClickable.value && props.ripple]]);
  12036. });
  12037. return {};
  12038. }
  12039. });
  12040. // Utilities
  12041. // Types
  12042. const handleGesture = wrapper => {
  12043. const {
  12044. touchstartX,
  12045. touchendX,
  12046. touchstartY,
  12047. touchendY
  12048. } = wrapper;
  12049. const dirRatio = 0.5;
  12050. const minDistance = 16;
  12051. wrapper.offsetX = touchendX - touchstartX;
  12052. wrapper.offsetY = touchendY - touchstartY;
  12053. if (Math.abs(wrapper.offsetY) < dirRatio * Math.abs(wrapper.offsetX)) {
  12054. wrapper.left && touchendX < touchstartX - minDistance && wrapper.left(wrapper);
  12055. wrapper.right && touchendX > touchstartX + minDistance && wrapper.right(wrapper);
  12056. }
  12057. if (Math.abs(wrapper.offsetX) < dirRatio * Math.abs(wrapper.offsetY)) {
  12058. wrapper.up && touchendY < touchstartY - minDistance && wrapper.up(wrapper);
  12059. wrapper.down && touchendY > touchstartY + minDistance && wrapper.down(wrapper);
  12060. }
  12061. };
  12062. function touchstart(event, wrapper) {
  12063. const touch = event.changedTouches[0];
  12064. wrapper.touchstartX = touch.clientX;
  12065. wrapper.touchstartY = touch.clientY;
  12066. wrapper.start?.({
  12067. originalEvent: event,
  12068. ...wrapper
  12069. });
  12070. }
  12071. function touchend(event, wrapper) {
  12072. const touch = event.changedTouches[0];
  12073. wrapper.touchendX = touch.clientX;
  12074. wrapper.touchendY = touch.clientY;
  12075. wrapper.end?.({
  12076. originalEvent: event,
  12077. ...wrapper
  12078. });
  12079. handleGesture(wrapper);
  12080. }
  12081. function touchmove(event, wrapper) {
  12082. const touch = event.changedTouches[0];
  12083. wrapper.touchmoveX = touch.clientX;
  12084. wrapper.touchmoveY = touch.clientY;
  12085. wrapper.move?.({
  12086. originalEvent: event,
  12087. ...wrapper
  12088. });
  12089. }
  12090. function createHandlers() {
  12091. let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  12092. const wrapper = {
  12093. touchstartX: 0,
  12094. touchstartY: 0,
  12095. touchendX: 0,
  12096. touchendY: 0,
  12097. touchmoveX: 0,
  12098. touchmoveY: 0,
  12099. offsetX: 0,
  12100. offsetY: 0,
  12101. left: value.left,
  12102. right: value.right,
  12103. up: value.up,
  12104. down: value.down,
  12105. start: value.start,
  12106. move: value.move,
  12107. end: value.end
  12108. };
  12109. return {
  12110. touchstart: e => touchstart(e, wrapper),
  12111. touchend: e => touchend(e, wrapper),
  12112. touchmove: e => touchmove(e, wrapper)
  12113. };
  12114. }
  12115. function mounted$3(el, binding) {
  12116. const value = binding.value;
  12117. const target = value?.parent ? el.parentElement : el;
  12118. const options = value?.options ?? {
  12119. passive: true
  12120. };
  12121. const uid = binding.instance?.$.uid; // TODO: use custom uid generator
  12122. if (!target || !uid) return;
  12123. const handlers = createHandlers(binding.value);
  12124. target._touchHandlers = target._touchHandlers ?? Object.create(null);
  12125. target._touchHandlers[uid] = handlers;
  12126. keys(handlers).forEach(eventName => {
  12127. target.addEventListener(eventName, handlers[eventName], options);
  12128. });
  12129. }
  12130. function unmounted$3(el, binding) {
  12131. const target = binding.value?.parent ? el.parentElement : el;
  12132. const uid = binding.instance?.$.uid;
  12133. if (!target?._touchHandlers || !uid) return;
  12134. const handlers = target._touchHandlers[uid];
  12135. keys(handlers).forEach(eventName => {
  12136. target.removeEventListener(eventName, handlers[eventName]);
  12137. });
  12138. delete target._touchHandlers[uid];
  12139. }
  12140. const Touch = {
  12141. mounted: mounted$3,
  12142. unmounted: unmounted$3
  12143. };
  12144. // Types
  12145. const VWindowSymbol = Symbol.for('vuetify:v-window');
  12146. const VWindowGroupSymbol = Symbol.for('vuetify:v-window-group');
  12147. const makeVWindowProps = propsFactory({
  12148. continuous: Boolean,
  12149. nextIcon: {
  12150. type: [Boolean, String, Function, Object],
  12151. default: '$next'
  12152. },
  12153. prevIcon: {
  12154. type: [Boolean, String, Function, Object],
  12155. default: '$prev'
  12156. },
  12157. reverse: Boolean,
  12158. showArrows: {
  12159. type: [Boolean, String],
  12160. validator: v => typeof v === 'boolean' || v === 'hover'
  12161. },
  12162. touch: {
  12163. type: [Object, Boolean],
  12164. default: undefined
  12165. },
  12166. direction: {
  12167. type: String,
  12168. default: 'horizontal'
  12169. },
  12170. modelValue: null,
  12171. disabled: Boolean,
  12172. selectedClass: {
  12173. type: String,
  12174. default: 'v-window-item--active'
  12175. },
  12176. // TODO: mandatory should probably not be exposed but do this for now
  12177. mandatory: {
  12178. type: [Boolean, String],
  12179. default: 'force'
  12180. },
  12181. ...makeComponentProps(),
  12182. ...makeTagProps(),
  12183. ...makeThemeProps()
  12184. }, 'VWindow');
  12185. const VWindow = genericComponent()({
  12186. name: 'VWindow',
  12187. directives: {
  12188. Touch
  12189. },
  12190. props: makeVWindowProps(),
  12191. emits: {
  12192. 'update:modelValue': v => true
  12193. },
  12194. setup(props, _ref) {
  12195. let {
  12196. slots
  12197. } = _ref;
  12198. const {
  12199. themeClasses
  12200. } = provideTheme(props);
  12201. const {
  12202. isRtl
  12203. } = useRtl();
  12204. const {
  12205. t
  12206. } = useLocale();
  12207. const group = useGroup(props, VWindowGroupSymbol);
  12208. const rootRef = ref();
  12209. const isRtlReverse = computed(() => isRtl.value ? !props.reverse : props.reverse);
  12210. const isReversed = shallowRef(false);
  12211. const transition = computed(() => {
  12212. const axis = props.direction === 'vertical' ? 'y' : 'x';
  12213. const reverse = isRtlReverse.value ? !isReversed.value : isReversed.value;
  12214. const direction = reverse ? '-reverse' : '';
  12215. return `v-window-${axis}${direction}-transition`;
  12216. });
  12217. const transitionCount = shallowRef(0);
  12218. const transitionHeight = ref(undefined);
  12219. const activeIndex = computed(() => {
  12220. return group.items.value.findIndex(item => group.selected.value.includes(item.id));
  12221. });
  12222. watch(activeIndex, (newVal, oldVal) => {
  12223. const itemsLength = group.items.value.length;
  12224. const lastIndex = itemsLength - 1;
  12225. if (itemsLength <= 2) {
  12226. isReversed.value = newVal < oldVal;
  12227. } else if (newVal === lastIndex && oldVal === 0) {
  12228. isReversed.value = true;
  12229. } else if (newVal === 0 && oldVal === lastIndex) {
  12230. isReversed.value = false;
  12231. } else {
  12232. isReversed.value = newVal < oldVal;
  12233. }
  12234. });
  12235. provide(VWindowSymbol, {
  12236. transition,
  12237. isReversed,
  12238. transitionCount,
  12239. transitionHeight,
  12240. rootRef
  12241. });
  12242. const canMoveBack = computed(() => props.continuous || activeIndex.value !== 0);
  12243. const canMoveForward = computed(() => props.continuous || activeIndex.value !== group.items.value.length - 1);
  12244. function prev() {
  12245. canMoveBack.value && group.prev();
  12246. }
  12247. function next() {
  12248. canMoveForward.value && group.next();
  12249. }
  12250. const arrows = computed(() => {
  12251. const arrows = [];
  12252. const prevProps = {
  12253. icon: isRtl.value ? props.nextIcon : props.prevIcon,
  12254. class: `v-window__${isRtlReverse.value ? 'right' : 'left'}`,
  12255. onClick: group.prev,
  12256. ariaLabel: t('$vuetify.carousel.prev')
  12257. };
  12258. arrows.push(canMoveBack.value ? slots.prev ? slots.prev({
  12259. props: prevProps
  12260. }) : createVNode(VBtn, prevProps, null) : createVNode("div", null, null));
  12261. const nextProps = {
  12262. icon: isRtl.value ? props.prevIcon : props.nextIcon,
  12263. class: `v-window__${isRtlReverse.value ? 'left' : 'right'}`,
  12264. onClick: group.next,
  12265. ariaLabel: t('$vuetify.carousel.next')
  12266. };
  12267. arrows.push(canMoveForward.value ? slots.next ? slots.next({
  12268. props: nextProps
  12269. }) : createVNode(VBtn, nextProps, null) : createVNode("div", null, null));
  12270. return arrows;
  12271. });
  12272. const touchOptions = computed(() => {
  12273. if (props.touch === false) return props.touch;
  12274. const options = {
  12275. left: () => {
  12276. isRtlReverse.value ? prev() : next();
  12277. },
  12278. right: () => {
  12279. isRtlReverse.value ? next() : prev();
  12280. },
  12281. start: _ref2 => {
  12282. let {
  12283. originalEvent
  12284. } = _ref2;
  12285. originalEvent.stopPropagation();
  12286. }
  12287. };
  12288. return {
  12289. ...options,
  12290. ...(props.touch === true ? {} : props.touch)
  12291. };
  12292. });
  12293. useRender(() => withDirectives(createVNode(props.tag, {
  12294. "ref": rootRef,
  12295. "class": ['v-window', {
  12296. 'v-window--show-arrows-on-hover': props.showArrows === 'hover'
  12297. }, themeClasses.value, props.class],
  12298. "style": props.style
  12299. }, {
  12300. default: () => [createVNode("div", {
  12301. "class": "v-window__container",
  12302. "style": {
  12303. height: transitionHeight.value
  12304. }
  12305. }, [slots.default?.({
  12306. group
  12307. }), props.showArrows !== false && createVNode("div", {
  12308. "class": "v-window__controls"
  12309. }, [arrows.value])]), slots.additional?.({
  12310. group
  12311. })]
  12312. }), [[resolveDirective("touch"), touchOptions.value]]));
  12313. return {
  12314. group
  12315. };
  12316. }
  12317. });
  12318. // Types
  12319. const makeVCarouselProps = propsFactory({
  12320. color: String,
  12321. cycle: Boolean,
  12322. delimiterIcon: {
  12323. type: IconValue,
  12324. default: '$delimiter'
  12325. },
  12326. height: {
  12327. type: [Number, String],
  12328. default: 500
  12329. },
  12330. hideDelimiters: Boolean,
  12331. hideDelimiterBackground: Boolean,
  12332. interval: {
  12333. type: [Number, String],
  12334. default: 6000,
  12335. validator: value => Number(value) > 0
  12336. },
  12337. progress: [Boolean, String],
  12338. verticalDelimiters: [Boolean, String],
  12339. ...makeVWindowProps({
  12340. continuous: true,
  12341. mandatory: 'force',
  12342. showArrows: true
  12343. })
  12344. }, 'VCarousel');
  12345. const VCarousel = genericComponent()({
  12346. name: 'VCarousel',
  12347. props: makeVCarouselProps(),
  12348. emits: {
  12349. 'update:modelValue': val => true
  12350. },
  12351. setup(props, _ref) {
  12352. let {
  12353. slots
  12354. } = _ref;
  12355. const model = useProxiedModel(props, 'modelValue');
  12356. const {
  12357. t
  12358. } = useLocale();
  12359. const windowRef = ref();
  12360. let slideTimeout = -1;
  12361. watch(model, restartTimeout);
  12362. watch(() => props.interval, restartTimeout);
  12363. watch(() => props.cycle, val => {
  12364. if (val) restartTimeout();else window.clearTimeout(slideTimeout);
  12365. });
  12366. onMounted(startTimeout);
  12367. function startTimeout() {
  12368. if (!props.cycle || !windowRef.value) return;
  12369. slideTimeout = window.setTimeout(windowRef.value.group.next, +props.interval > 0 ? +props.interval : 6000);
  12370. }
  12371. function restartTimeout() {
  12372. window.clearTimeout(slideTimeout);
  12373. window.requestAnimationFrame(startTimeout);
  12374. }
  12375. useRender(() => {
  12376. const [windowProps] = VWindow.filterProps(props);
  12377. return createVNode(VWindow, mergeProps({
  12378. "ref": windowRef
  12379. }, windowProps, {
  12380. "modelValue": model.value,
  12381. "onUpdate:modelValue": $event => model.value = $event,
  12382. "class": ['v-carousel', {
  12383. 'v-carousel--hide-delimiter-background': props.hideDelimiterBackground,
  12384. 'v-carousel--vertical-delimiters': props.verticalDelimiters
  12385. }, props.class],
  12386. "style": [{
  12387. height: convertToUnit(props.height)
  12388. }, props.style]
  12389. }), {
  12390. default: slots.default,
  12391. additional: _ref2 => {
  12392. let {
  12393. group
  12394. } = _ref2;
  12395. return createVNode(Fragment, null, [!props.hideDelimiters && createVNode("div", {
  12396. "class": "v-carousel__controls",
  12397. "style": {
  12398. left: props.verticalDelimiters === 'left' && props.verticalDelimiters ? 0 : 'auto',
  12399. right: props.verticalDelimiters === 'right' ? 0 : 'auto'
  12400. }
  12401. }, [group.items.value.length > 0 && createVNode(VDefaultsProvider, {
  12402. "defaults": {
  12403. VBtn: {
  12404. color: props.color,
  12405. icon: props.delimiterIcon,
  12406. size: 'x-small',
  12407. variant: 'text'
  12408. }
  12409. },
  12410. "scoped": true
  12411. }, {
  12412. default: () => [group.items.value.map((item, index) => {
  12413. const props = {
  12414. id: `carousel-item-${item.id}`,
  12415. 'aria-label': t('$vuetify.carousel.ariaLabel.delimiter', index + 1, group.items.value.length),
  12416. class: [group.isSelected(item.id) && 'v-btn--active'],
  12417. onClick: () => group.select(item.id, true)
  12418. };
  12419. return slots.item ? slots.item({
  12420. props,
  12421. item
  12422. }) : createVNode(VBtn, mergeProps(item, props), null);
  12423. })]
  12424. })]), props.progress && createVNode(VProgressLinear, {
  12425. "class": "v-carousel__progress",
  12426. "color": typeof props.progress === 'string' ? props.progress : undefined,
  12427. "modelValue": (group.getItemIndex(model.value) + 1) / group.items.value.length * 100
  12428. }, null)]);
  12429. },
  12430. prev: slots.prev,
  12431. next: slots.next
  12432. });
  12433. });
  12434. return {};
  12435. }
  12436. });
  12437. const makeVWindowItemProps = propsFactory({
  12438. reverseTransition: {
  12439. type: [Boolean, String],
  12440. default: undefined
  12441. },
  12442. transition: {
  12443. type: [Boolean, String],
  12444. default: undefined
  12445. },
  12446. ...makeComponentProps(),
  12447. ...makeGroupItemProps(),
  12448. ...makeLazyProps()
  12449. }, 'VWindowItem');
  12450. const VWindowItem = genericComponent()({
  12451. name: 'VWindowItem',
  12452. directives: {
  12453. Touch
  12454. },
  12455. props: makeVWindowItemProps(),
  12456. emits: {
  12457. 'group:selected': val => true
  12458. },
  12459. setup(props, _ref) {
  12460. let {
  12461. slots
  12462. } = _ref;
  12463. const window = inject$1(VWindowSymbol);
  12464. const groupItem = useGroupItem(props, VWindowGroupSymbol);
  12465. const {
  12466. isBooted
  12467. } = useSsrBoot();
  12468. if (!window || !groupItem) throw new Error('[Vuetify] VWindowItem must be used inside VWindow');
  12469. const isTransitioning = shallowRef(false);
  12470. const hasTransition = computed(() => isBooted.value && (window.isReversed.value ? props.reverseTransition !== false : props.transition !== false));
  12471. function onAfterTransition() {
  12472. if (!isTransitioning.value || !window) {
  12473. return;
  12474. }
  12475. // Finalize transition state.
  12476. isTransitioning.value = false;
  12477. if (window.transitionCount.value > 0) {
  12478. window.transitionCount.value -= 1;
  12479. // Remove container height if we are out of transition.
  12480. if (window.transitionCount.value === 0) {
  12481. window.transitionHeight.value = undefined;
  12482. }
  12483. }
  12484. }
  12485. function onBeforeTransition() {
  12486. if (isTransitioning.value || !window) {
  12487. return;
  12488. }
  12489. // Initialize transition state here.
  12490. isTransitioning.value = true;
  12491. if (window.transitionCount.value === 0) {
  12492. // Set initial height for height transition.
  12493. window.transitionHeight.value = convertToUnit(window.rootRef.value?.clientHeight);
  12494. }
  12495. window.transitionCount.value += 1;
  12496. }
  12497. function onTransitionCancelled() {
  12498. onAfterTransition(); // This should have the same path as normal transition end.
  12499. }
  12500. function onEnterTransition(el) {
  12501. if (!isTransitioning.value) {
  12502. return;
  12503. }
  12504. nextTick(() => {
  12505. // Do not set height if no transition or cancelled.
  12506. if (!hasTransition.value || !isTransitioning.value || !window) {
  12507. return;
  12508. }
  12509. // Set transition target height.
  12510. window.transitionHeight.value = convertToUnit(el.clientHeight);
  12511. });
  12512. }
  12513. const transition = computed(() => {
  12514. const name = window.isReversed.value ? props.reverseTransition : props.transition;
  12515. return !hasTransition.value ? false : {
  12516. name: typeof name !== 'string' ? window.transition.value : name,
  12517. onBeforeEnter: onBeforeTransition,
  12518. onAfterEnter: onAfterTransition,
  12519. onEnterCancelled: onTransitionCancelled,
  12520. onBeforeLeave: onBeforeTransition,
  12521. onAfterLeave: onAfterTransition,
  12522. onLeaveCancelled: onTransitionCancelled,
  12523. onEnter: onEnterTransition
  12524. };
  12525. });
  12526. const {
  12527. hasContent
  12528. } = useLazy(props, groupItem.isSelected);
  12529. useRender(() => createVNode(MaybeTransition, {
  12530. "transition": transition.value,
  12531. "disabled": !isBooted.value
  12532. }, {
  12533. default: () => [withDirectives(createVNode("div", {
  12534. "class": ['v-window-item', groupItem.selectedClass.value, props.class],
  12535. "style": props.style
  12536. }, [hasContent.value && slots.default?.()]), [[vShow, groupItem.isSelected.value]])]
  12537. }));
  12538. return {
  12539. groupItem
  12540. };
  12541. }
  12542. });
  12543. // Types
  12544. const makeVCarouselItemProps = propsFactory({
  12545. ...makeVImgProps(),
  12546. ...makeVWindowItemProps()
  12547. }, 'VCarouselItem');
  12548. const VCarouselItem = genericComponent()({
  12549. name: 'VCarouselItem',
  12550. inheritAttrs: false,
  12551. props: makeVCarouselItemProps(),
  12552. setup(props, _ref) {
  12553. let {
  12554. slots,
  12555. attrs
  12556. } = _ref;
  12557. useRender(() => {
  12558. const [imgProps] = VImg.filterProps(props);
  12559. const [windowItemProps] = VWindowItem.filterProps(props);
  12560. return createVNode(VWindowItem, mergeProps({
  12561. "class": "v-carousel-item"
  12562. }, windowItemProps), {
  12563. default: () => [createVNode(VImg, mergeProps(attrs, imgProps), slots)]
  12564. });
  12565. });
  12566. }
  12567. });
  12568. // Styles
  12569. const VCode = createSimpleFunctional('v-code');
  12570. // Types
  12571. const makeVColorPickerCanvasProps = propsFactory({
  12572. color: {
  12573. type: Object
  12574. },
  12575. disabled: Boolean,
  12576. dotSize: {
  12577. type: [Number, String],
  12578. default: 10
  12579. },
  12580. height: {
  12581. type: [Number, String],
  12582. default: 150
  12583. },
  12584. width: {
  12585. type: [Number, String],
  12586. default: 300
  12587. },
  12588. ...makeComponentProps()
  12589. }, 'VColorPickerCanvas');
  12590. const VColorPickerCanvas = defineComponent({
  12591. name: 'VColorPickerCanvas',
  12592. props: makeVColorPickerCanvasProps(),
  12593. emits: {
  12594. 'update:color': color => true,
  12595. 'update:position': hue => true
  12596. },
  12597. setup(props, _ref) {
  12598. let {
  12599. emit
  12600. } = _ref;
  12601. const isInteracting = shallowRef(false);
  12602. const isOutsideUpdate = shallowRef(false);
  12603. const dotPosition = ref({
  12604. x: 0,
  12605. y: 0
  12606. });
  12607. const dotStyles = computed(() => {
  12608. const {
  12609. x,
  12610. y
  12611. } = dotPosition.value;
  12612. const radius = parseInt(props.dotSize, 10) / 2;
  12613. return {
  12614. width: convertToUnit(props.dotSize),
  12615. height: convertToUnit(props.dotSize),
  12616. transform: `translate(${convertToUnit(x - radius)}, ${convertToUnit(y - radius)})`
  12617. };
  12618. });
  12619. const canvasRef = ref();
  12620. const canvasWidth = shallowRef(parseFloat(props.width));
  12621. const canvasHeight = shallowRef(parseFloat(props.height));
  12622. const {
  12623. resizeRef
  12624. } = useResizeObserver(entries => {
  12625. if (!resizeRef.value?.offsetParent) return;
  12626. const {
  12627. width,
  12628. height
  12629. } = entries[0].contentRect;
  12630. canvasWidth.value = width;
  12631. canvasHeight.value = height;
  12632. });
  12633. function updateDotPosition(x, y, rect) {
  12634. const {
  12635. left,
  12636. top,
  12637. width,
  12638. height
  12639. } = rect;
  12640. dotPosition.value = {
  12641. x: clamp(x - left, 0, width),
  12642. y: clamp(y - top, 0, height)
  12643. };
  12644. }
  12645. function handleClick(e) {
  12646. if (props.disabled || !canvasRef.value) return;
  12647. updateDotPosition(e.clientX, e.clientY, canvasRef.value.getBoundingClientRect());
  12648. }
  12649. function handleMouseDown(e) {
  12650. // To prevent selection while moving cursor
  12651. e.preventDefault();
  12652. if (props.disabled) return;
  12653. isInteracting.value = true;
  12654. window.addEventListener('mousemove', handleMouseMove);
  12655. window.addEventListener('mouseup', handleMouseUp);
  12656. window.addEventListener('touchmove', handleMouseMove);
  12657. window.addEventListener('touchend', handleMouseUp);
  12658. }
  12659. function handleMouseMove(e) {
  12660. if (props.disabled || !canvasRef.value) return;
  12661. isInteracting.value = true;
  12662. const coords = getEventCoordinates(e);
  12663. updateDotPosition(coords.clientX, coords.clientY, canvasRef.value.getBoundingClientRect());
  12664. }
  12665. function handleMouseUp() {
  12666. window.removeEventListener('mousemove', handleMouseMove);
  12667. window.removeEventListener('mouseup', handleMouseUp);
  12668. window.removeEventListener('touchmove', handleMouseMove);
  12669. window.removeEventListener('touchend', handleMouseUp);
  12670. }
  12671. watch(dotPosition, () => {
  12672. if (isOutsideUpdate.value) {
  12673. isOutsideUpdate.value = false;
  12674. return;
  12675. }
  12676. if (!canvasRef.value) return;
  12677. const {
  12678. x,
  12679. y
  12680. } = dotPosition.value;
  12681. emit('update:color', {
  12682. h: props.color?.h ?? 0,
  12683. s: clamp(x, 0, canvasWidth.value) / canvasWidth.value,
  12684. v: 1 - clamp(y, 0, canvasHeight.value) / canvasHeight.value,
  12685. a: props.color?.a ?? 1
  12686. });
  12687. });
  12688. function updateCanvas() {
  12689. if (!canvasRef.value) return;
  12690. const canvas = canvasRef.value;
  12691. const ctx = canvas.getContext('2d');
  12692. if (!ctx) return;
  12693. const saturationGradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
  12694. saturationGradient.addColorStop(0, 'hsla(0, 0%, 100%, 1)'); // white
  12695. saturationGradient.addColorStop(1, `hsla(${props.color?.h ?? 0}, 100%, 50%, 1)`);
  12696. ctx.fillStyle = saturationGradient;
  12697. ctx.fillRect(0, 0, canvas.width, canvas.height);
  12698. const valueGradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
  12699. valueGradient.addColorStop(0, 'hsla(0, 0%, 100%, 0)'); // transparent
  12700. valueGradient.addColorStop(1, 'hsla(0, 0%, 0%, 1)'); // black
  12701. ctx.fillStyle = valueGradient;
  12702. ctx.fillRect(0, 0, canvas.width, canvas.height);
  12703. }
  12704. watch(() => props.color?.h, updateCanvas, {
  12705. immediate: true
  12706. });
  12707. watch(() => [canvasWidth.value, canvasHeight.value], (newVal, oldVal) => {
  12708. updateCanvas();
  12709. dotPosition.value = {
  12710. x: dotPosition.value.x * newVal[0] / oldVal[0],
  12711. y: dotPosition.value.y * newVal[1] / oldVal[1]
  12712. };
  12713. }, {
  12714. flush: 'post'
  12715. });
  12716. watch(() => props.color, () => {
  12717. if (isInteracting.value) {
  12718. isInteracting.value = false;
  12719. return;
  12720. }
  12721. isOutsideUpdate.value = true;
  12722. dotPosition.value = props.color ? {
  12723. x: props.color.s * canvasWidth.value,
  12724. y: (1 - props.color.v) * canvasHeight.value
  12725. } : {
  12726. x: 0,
  12727. y: 0
  12728. };
  12729. }, {
  12730. deep: true,
  12731. immediate: true
  12732. });
  12733. onMounted(() => updateCanvas());
  12734. useRender(() => createVNode("div", {
  12735. "ref": resizeRef,
  12736. "class": ['v-color-picker-canvas', props.class],
  12737. "style": props.style,
  12738. "onClick": handleClick,
  12739. "onMousedown": handleMouseDown,
  12740. "onTouchstart": handleMouseDown
  12741. }, [createVNode("canvas", {
  12742. "ref": canvasRef,
  12743. "width": canvasWidth.value,
  12744. "height": canvasHeight.value
  12745. }, null), props.color && createVNode("div", {
  12746. "class": ['v-color-picker-canvas__dot', {
  12747. 'v-color-picker-canvas__dot--disabled': props.disabled
  12748. }],
  12749. "style": dotStyles.value
  12750. }, null)]));
  12751. return {};
  12752. }
  12753. });
  12754. // Utilities
  12755. // Types
  12756. function stripAlpha(color, stripAlpha) {
  12757. if (stripAlpha) {
  12758. const {
  12759. a,
  12760. ...rest
  12761. } = color;
  12762. return rest;
  12763. }
  12764. return color;
  12765. }
  12766. function extractColor(color, input) {
  12767. if (input == null || typeof input === 'string') {
  12768. const hex = HSVtoHex(color);
  12769. if (color.a === 1) return hex.slice(0, 7);else return hex;
  12770. }
  12771. if (typeof input === 'object') {
  12772. let converted;
  12773. 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;
  12774. return stripAlpha(converted, !has(input, ['a']) && color.a === 1);
  12775. }
  12776. return color;
  12777. }
  12778. const nullColor = {
  12779. h: 0,
  12780. s: 0,
  12781. v: 1,
  12782. a: 1
  12783. };
  12784. const rgba = {
  12785. inputProps: {
  12786. type: 'number',
  12787. min: 0
  12788. },
  12789. inputs: [{
  12790. label: 'R',
  12791. max: 255,
  12792. step: 1,
  12793. getValue: c => Math.round(c.r),
  12794. getColor: (c, v) => ({
  12795. ...c,
  12796. r: Number(v)
  12797. })
  12798. }, {
  12799. label: 'G',
  12800. max: 255,
  12801. step: 1,
  12802. getValue: c => Math.round(c.g),
  12803. getColor: (c, v) => ({
  12804. ...c,
  12805. g: Number(v)
  12806. })
  12807. }, {
  12808. label: 'B',
  12809. max: 255,
  12810. step: 1,
  12811. getValue: c => Math.round(c.b),
  12812. getColor: (c, v) => ({
  12813. ...c,
  12814. b: Number(v)
  12815. })
  12816. }, {
  12817. label: 'A',
  12818. max: 1,
  12819. step: 0.01,
  12820. getValue: _ref => {
  12821. let {
  12822. a
  12823. } = _ref;
  12824. return a != null ? Math.round(a * 100) / 100 : 1;
  12825. },
  12826. getColor: (c, v) => ({
  12827. ...c,
  12828. a: Number(v)
  12829. })
  12830. }],
  12831. to: HSVtoRGB,
  12832. from: RGBtoHSV
  12833. };
  12834. const rgb = {
  12835. ...rgba,
  12836. inputs: rgba.inputs?.slice(0, 3)
  12837. };
  12838. const hsla = {
  12839. inputProps: {
  12840. type: 'number',
  12841. min: 0
  12842. },
  12843. inputs: [{
  12844. label: 'H',
  12845. max: 360,
  12846. step: 1,
  12847. getValue: c => Math.round(c.h),
  12848. getColor: (c, v) => ({
  12849. ...c,
  12850. h: Number(v)
  12851. })
  12852. }, {
  12853. label: 'S',
  12854. max: 1,
  12855. step: 0.01,
  12856. getValue: c => Math.round(c.s * 100) / 100,
  12857. getColor: (c, v) => ({
  12858. ...c,
  12859. s: Number(v)
  12860. })
  12861. }, {
  12862. label: 'L',
  12863. max: 1,
  12864. step: 0.01,
  12865. getValue: c => Math.round(c.l * 100) / 100,
  12866. getColor: (c, v) => ({
  12867. ...c,
  12868. l: Number(v)
  12869. })
  12870. }, {
  12871. label: 'A',
  12872. max: 1,
  12873. step: 0.01,
  12874. getValue: _ref2 => {
  12875. let {
  12876. a
  12877. } = _ref2;
  12878. return a != null ? Math.round(a * 100) / 100 : 1;
  12879. },
  12880. getColor: (c, v) => ({
  12881. ...c,
  12882. a: Number(v)
  12883. })
  12884. }],
  12885. to: HSVtoHSL,
  12886. from: HSLtoHSV
  12887. };
  12888. const hsl = {
  12889. ...hsla,
  12890. inputs: hsla.inputs.slice(0, 3)
  12891. };
  12892. const hexa = {
  12893. inputProps: {
  12894. type: 'text'
  12895. },
  12896. inputs: [{
  12897. label: 'HEXA',
  12898. getValue: c => c,
  12899. getColor: (c, v) => v
  12900. }],
  12901. to: HSVtoHex,
  12902. from: HexToHSV
  12903. };
  12904. const hex = {
  12905. ...hexa,
  12906. inputs: [{
  12907. label: 'HEX',
  12908. getValue: c => c.slice(0, 7),
  12909. getColor: (c, v) => v
  12910. }]
  12911. };
  12912. const modes = {
  12913. rgb,
  12914. rgba,
  12915. hsl,
  12916. hsla,
  12917. hex,
  12918. hexa
  12919. };
  12920. // Types
  12921. const VColorPickerInput = _ref => {
  12922. let {
  12923. label,
  12924. ...rest
  12925. } = _ref;
  12926. return createVNode("div", {
  12927. "class": "v-color-picker-edit__input"
  12928. }, [createVNode("input", rest, null), createVNode("span", null, [label])]);
  12929. };
  12930. const makeVColorPickerEditProps = propsFactory({
  12931. color: Object,
  12932. disabled: Boolean,
  12933. mode: {
  12934. type: String,
  12935. default: 'rgba',
  12936. validator: v => Object.keys(modes).includes(v)
  12937. },
  12938. modes: {
  12939. type: Array,
  12940. default: () => Object.keys(modes),
  12941. validator: v => Array.isArray(v) && v.every(m => Object.keys(modes).includes(m))
  12942. },
  12943. ...makeComponentProps()
  12944. }, 'VColorPickerEdit');
  12945. const VColorPickerEdit = defineComponent({
  12946. name: 'VColorPickerEdit',
  12947. props: makeVColorPickerEditProps(),
  12948. emits: {
  12949. 'update:color': color => true,
  12950. 'update:mode': mode => true
  12951. },
  12952. setup(props, _ref2) {
  12953. let {
  12954. emit
  12955. } = _ref2;
  12956. const enabledModes = computed(() => {
  12957. return props.modes.map(key => ({
  12958. ...modes[key],
  12959. name: key
  12960. }));
  12961. });
  12962. const inputs = computed(() => {
  12963. const mode = enabledModes.value.find(m => m.name === props.mode);
  12964. if (!mode) return [];
  12965. const color = props.color ? mode.to(props.color) : null;
  12966. return mode.inputs?.map(_ref3 => {
  12967. let {
  12968. getValue,
  12969. getColor,
  12970. ...inputProps
  12971. } = _ref3;
  12972. return {
  12973. ...mode.inputProps,
  12974. ...inputProps,
  12975. disabled: props.disabled,
  12976. value: color && getValue(color),
  12977. onChange: e => {
  12978. const target = e.target;
  12979. if (!target) return;
  12980. emit('update:color', mode.from(getColor(color ?? nullColor, target.value)));
  12981. }
  12982. };
  12983. });
  12984. });
  12985. useRender(() => createVNode("div", {
  12986. "class": ['v-color-picker-edit', props.class],
  12987. "style": props.style
  12988. }, [inputs.value?.map(props => createVNode(VColorPickerInput, props, null)), enabledModes.value.length > 1 && createVNode(VBtn, {
  12989. "icon": "$unfold",
  12990. "size": "x-small",
  12991. "variant": "plain",
  12992. "onClick": () => {
  12993. const mi = enabledModes.value.findIndex(m => m.name === props.mode);
  12994. emit('update:mode', enabledModes.value[(mi + 1) % enabledModes.value.length].name);
  12995. }
  12996. }, null)]));
  12997. return {};
  12998. }
  12999. });
  13000. /* eslint-disable max-statements */
  13001. // Composables
  13002. // Types
  13003. const VSliderSymbol = Symbol.for('vuetify:v-slider');
  13004. function getOffset(e, el, direction) {
  13005. const vertical = direction === 'vertical';
  13006. const rect = el.getBoundingClientRect();
  13007. const touch = 'touches' in e ? e.touches[0] : e;
  13008. return vertical ? touch.clientY - (rect.top + rect.height / 2) : touch.clientX - (rect.left + rect.width / 2);
  13009. }
  13010. function getPosition(e, position) {
  13011. 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];
  13012. }
  13013. const makeSliderProps = propsFactory({
  13014. disabled: {
  13015. type: Boolean,
  13016. default: null
  13017. },
  13018. error: Boolean,
  13019. readonly: {
  13020. type: Boolean,
  13021. default: null
  13022. },
  13023. max: {
  13024. type: [Number, String],
  13025. default: 100
  13026. },
  13027. min: {
  13028. type: [Number, String],
  13029. default: 0
  13030. },
  13031. step: {
  13032. type: [Number, String],
  13033. default: 0
  13034. },
  13035. thumbColor: String,
  13036. thumbLabel: {
  13037. type: [Boolean, String],
  13038. default: undefined,
  13039. validator: v => typeof v === 'boolean' || v === 'always'
  13040. },
  13041. thumbSize: {
  13042. type: [Number, String],
  13043. default: 20
  13044. },
  13045. showTicks: {
  13046. type: [Boolean, String],
  13047. default: false,
  13048. validator: v => typeof v === 'boolean' || v === 'always'
  13049. },
  13050. ticks: {
  13051. type: [Array, Object]
  13052. },
  13053. tickSize: {
  13054. type: [Number, String],
  13055. default: 2
  13056. },
  13057. color: String,
  13058. trackColor: String,
  13059. trackFillColor: String,
  13060. trackSize: {
  13061. type: [Number, String],
  13062. default: 4
  13063. },
  13064. direction: {
  13065. type: String,
  13066. default: 'horizontal',
  13067. validator: v => ['vertical', 'horizontal'].includes(v)
  13068. },
  13069. reverse: Boolean,
  13070. ...makeRoundedProps(),
  13071. ...makeElevationProps({
  13072. elevation: 2
  13073. })
  13074. }, 'Slider');
  13075. const useSteps = props => {
  13076. const min = computed(() => parseFloat(props.min));
  13077. const max = computed(() => parseFloat(props.max));
  13078. const step = computed(() => +props.step > 0 ? parseFloat(props.step) : 0);
  13079. const decimals = computed(() => Math.max(getDecimals(step.value), getDecimals(min.value)));
  13080. function roundValue(value) {
  13081. value = parseFloat(value);
  13082. if (step.value <= 0) return value;
  13083. const clamped = clamp(value, min.value, max.value);
  13084. const offset = min.value % step.value;
  13085. const newValue = Math.round((clamped - offset) / step.value) * step.value + offset;
  13086. return parseFloat(Math.min(newValue, max.value).toFixed(decimals.value));
  13087. }
  13088. return {
  13089. min,
  13090. max,
  13091. step,
  13092. decimals,
  13093. roundValue
  13094. };
  13095. };
  13096. const useSlider = _ref => {
  13097. let {
  13098. props,
  13099. steps,
  13100. onSliderStart,
  13101. onSliderMove,
  13102. onSliderEnd,
  13103. getActiveThumb
  13104. } = _ref;
  13105. const {
  13106. isRtl
  13107. } = useRtl();
  13108. const isReversed = toRef(props, 'reverse');
  13109. const horizontalDirection = computed(() => {
  13110. let hd = isRtl.value ? 'rtl' : 'ltr';
  13111. if (props.reverse) {
  13112. hd = hd === 'rtl' ? 'ltr' : 'rtl';
  13113. }
  13114. return hd;
  13115. });
  13116. const {
  13117. min,
  13118. max,
  13119. step,
  13120. decimals,
  13121. roundValue
  13122. } = steps;
  13123. const thumbSize = computed(() => parseInt(props.thumbSize, 10));
  13124. const tickSize = computed(() => parseInt(props.tickSize, 10));
  13125. const trackSize = computed(() => parseInt(props.trackSize, 10));
  13126. const numTicks = computed(() => (max.value - min.value) / step.value);
  13127. const disabled = toRef(props, 'disabled');
  13128. const vertical = computed(() => props.direction === 'vertical');
  13129. const thumbColor = computed(() => props.error || props.disabled ? undefined : props.thumbColor ?? props.color);
  13130. const trackColor = computed(() => props.error || props.disabled ? undefined : props.trackColor ?? props.color);
  13131. const trackFillColor = computed(() => props.error || props.disabled ? undefined : props.trackFillColor ?? props.color);
  13132. const mousePressed = shallowRef(false);
  13133. const startOffset = shallowRef(0);
  13134. const trackContainerRef = ref();
  13135. const activeThumbRef = ref();
  13136. function parseMouseMove(e) {
  13137. const vertical = props.direction === 'vertical';
  13138. const start = vertical ? 'top' : 'left';
  13139. const length = vertical ? 'height' : 'width';
  13140. const position = vertical ? 'clientY' : 'clientX';
  13141. const {
  13142. [start]: trackStart,
  13143. [length]: trackLength
  13144. } = trackContainerRef.value?.$el.getBoundingClientRect();
  13145. const clickOffset = getPosition(e, position);
  13146. // It is possible for left to be NaN, force to number
  13147. let clickPos = Math.min(Math.max((clickOffset - trackStart - startOffset.value) / trackLength, 0), 1) || 0;
  13148. if (vertical || horizontalDirection.value === 'rtl') clickPos = 1 - clickPos;
  13149. return roundValue(min.value + clickPos * (max.value - min.value));
  13150. }
  13151. const handleStop = e => {
  13152. onSliderEnd({
  13153. value: parseMouseMove(e)
  13154. });
  13155. mousePressed.value = false;
  13156. startOffset.value = 0;
  13157. };
  13158. const handleStart = e => {
  13159. activeThumbRef.value = getActiveThumb(e);
  13160. if (!activeThumbRef.value) return;
  13161. activeThumbRef.value.focus();
  13162. mousePressed.value = true;
  13163. if (activeThumbRef.value.contains(e.target)) {
  13164. startOffset.value = getOffset(e, activeThumbRef.value, props.direction);
  13165. } else {
  13166. startOffset.value = 0;
  13167. onSliderMove({
  13168. value: parseMouseMove(e)
  13169. });
  13170. }
  13171. onSliderStart({
  13172. value: parseMouseMove(e)
  13173. });
  13174. };
  13175. const moveListenerOptions = {
  13176. passive: true,
  13177. capture: true
  13178. };
  13179. function onMouseMove(e) {
  13180. onSliderMove({
  13181. value: parseMouseMove(e)
  13182. });
  13183. }
  13184. function onSliderMouseUp(e) {
  13185. e.stopPropagation();
  13186. e.preventDefault();
  13187. handleStop(e);
  13188. window.removeEventListener('mousemove', onMouseMove, moveListenerOptions);
  13189. window.removeEventListener('mouseup', onSliderMouseUp);
  13190. }
  13191. function onSliderTouchend(e) {
  13192. handleStop(e);
  13193. window.removeEventListener('touchmove', onMouseMove, moveListenerOptions);
  13194. e.target?.removeEventListener('touchend', onSliderTouchend);
  13195. }
  13196. function onSliderTouchstart(e) {
  13197. handleStart(e);
  13198. window.addEventListener('touchmove', onMouseMove, moveListenerOptions);
  13199. e.target?.addEventListener('touchend', onSliderTouchend, {
  13200. passive: false
  13201. });
  13202. }
  13203. function onSliderMousedown(e) {
  13204. e.preventDefault();
  13205. handleStart(e);
  13206. window.addEventListener('mousemove', onMouseMove, moveListenerOptions);
  13207. window.addEventListener('mouseup', onSliderMouseUp, {
  13208. passive: false
  13209. });
  13210. }
  13211. const position = val => {
  13212. const percentage = (val - min.value) / (max.value - min.value) * 100;
  13213. return clamp(isNaN(percentage) ? 0 : percentage, 0, 100);
  13214. };
  13215. const showTicks = toRef(props, 'showTicks');
  13216. const parsedTicks = computed(() => {
  13217. if (!showTicks.value) return [];
  13218. if (!props.ticks) {
  13219. return numTicks.value !== Infinity ? createRange(numTicks.value + 1).map(t => {
  13220. const value = min.value + t * step.value;
  13221. return {
  13222. value,
  13223. position: position(value)
  13224. };
  13225. }) : [];
  13226. }
  13227. if (Array.isArray(props.ticks)) return props.ticks.map(t => ({
  13228. value: t,
  13229. position: position(t),
  13230. label: t.toString()
  13231. }));
  13232. return Object.keys(props.ticks).map(key => ({
  13233. value: parseFloat(key),
  13234. position: position(parseFloat(key)),
  13235. label: props.ticks[key]
  13236. }));
  13237. });
  13238. const hasLabels = computed(() => parsedTicks.value.some(_ref2 => {
  13239. let {
  13240. label
  13241. } = _ref2;
  13242. return !!label;
  13243. }));
  13244. const data = {
  13245. activeThumbRef,
  13246. color: toRef(props, 'color'),
  13247. decimals,
  13248. disabled,
  13249. direction: toRef(props, 'direction'),
  13250. elevation: toRef(props, 'elevation'),
  13251. hasLabels,
  13252. horizontalDirection,
  13253. isReversed,
  13254. min,
  13255. max,
  13256. mousePressed,
  13257. numTicks,
  13258. onSliderMousedown,
  13259. onSliderTouchstart,
  13260. parsedTicks,
  13261. parseMouseMove,
  13262. position,
  13263. readonly: toRef(props, 'readonly'),
  13264. rounded: toRef(props, 'rounded'),
  13265. roundValue,
  13266. showTicks,
  13267. startOffset,
  13268. step,
  13269. thumbSize,
  13270. thumbColor,
  13271. thumbLabel: toRef(props, 'thumbLabel'),
  13272. ticks: toRef(props, 'ticks'),
  13273. tickSize,
  13274. trackColor,
  13275. trackContainerRef,
  13276. trackFillColor,
  13277. trackSize,
  13278. vertical
  13279. };
  13280. provide(VSliderSymbol, data);
  13281. return data;
  13282. };
  13283. // Types
  13284. const makeVSliderThumbProps = propsFactory({
  13285. focused: Boolean,
  13286. max: {
  13287. type: Number,
  13288. required: true
  13289. },
  13290. min: {
  13291. type: Number,
  13292. required: true
  13293. },
  13294. modelValue: {
  13295. type: Number,
  13296. required: true
  13297. },
  13298. position: {
  13299. type: Number,
  13300. required: true
  13301. },
  13302. ripple: {
  13303. type: [Boolean, Object],
  13304. default: true
  13305. },
  13306. ...makeComponentProps()
  13307. }, 'VSliderThumb');
  13308. const VSliderThumb = genericComponent()({
  13309. name: 'VSliderThumb',
  13310. directives: {
  13311. Ripple
  13312. },
  13313. props: makeVSliderThumbProps(),
  13314. emits: {
  13315. 'update:modelValue': v => true
  13316. },
  13317. setup(props, _ref) {
  13318. let {
  13319. slots,
  13320. emit
  13321. } = _ref;
  13322. const slider = inject$1(VSliderSymbol);
  13323. const {
  13324. rtlClasses
  13325. } = useRtl();
  13326. if (!slider) throw new Error('[Vuetify] v-slider-thumb must be used inside v-slider or v-range-slider');
  13327. const {
  13328. thumbColor,
  13329. step,
  13330. vertical,
  13331. disabled,
  13332. thumbSize,
  13333. thumbLabel,
  13334. direction,
  13335. readonly,
  13336. elevation,
  13337. isReversed,
  13338. horizontalDirection,
  13339. mousePressed,
  13340. decimals
  13341. } = slider;
  13342. const {
  13343. textColorClasses,
  13344. textColorStyles
  13345. } = useTextColor(thumbColor);
  13346. const {
  13347. pageup,
  13348. pagedown,
  13349. end,
  13350. home,
  13351. left,
  13352. right,
  13353. down,
  13354. up
  13355. } = keyValues;
  13356. const relevantKeys = [pageup, pagedown, end, home, left, right, down, up];
  13357. const multipliers = computed(() => {
  13358. if (step.value) return [1, 2, 3];else return [1, 5, 10];
  13359. });
  13360. function parseKeydown(e, value) {
  13361. if (!relevantKeys.includes(e.key)) return;
  13362. e.preventDefault();
  13363. const _step = step.value || 0.1;
  13364. const steps = (props.max - props.min) / _step;
  13365. if ([left, right, down, up].includes(e.key)) {
  13366. const increase = horizontalDirection.value === 'rtl' ? [left, up] : [right, up];
  13367. const direction = increase.includes(e.key) ? 1 : -1;
  13368. const multiplier = e.shiftKey ? 2 : e.ctrlKey ? 1 : 0;
  13369. value = value + direction * _step * multipliers.value[multiplier];
  13370. } else if (e.key === home) {
  13371. value = props.min;
  13372. } else if (e.key === end) {
  13373. value = props.max;
  13374. } else {
  13375. const direction = e.key === pagedown ? 1 : -1;
  13376. value = value - direction * _step * (steps > 100 ? steps / 10 : 10);
  13377. }
  13378. return Math.max(props.min, Math.min(props.max, value));
  13379. }
  13380. function onKeydown(e) {
  13381. const newValue = parseKeydown(e, props.modelValue);
  13382. newValue != null && emit('update:modelValue', newValue);
  13383. }
  13384. useRender(() => {
  13385. const positionPercentage = convertToUnit(vertical.value || isReversed.value ? 100 - props.position : props.position, '%');
  13386. const {
  13387. elevationClasses
  13388. } = useElevation(computed(() => !disabled.value ? elevation.value : undefined));
  13389. return createVNode("div", {
  13390. "class": ['v-slider-thumb', {
  13391. 'v-slider-thumb--focused': props.focused,
  13392. 'v-slider-thumb--pressed': props.focused && mousePressed.value
  13393. }, props.class, rtlClasses.value],
  13394. "style": [{
  13395. '--v-slider-thumb-position': positionPercentage,
  13396. '--v-slider-thumb-size': convertToUnit(thumbSize.value)
  13397. }, props.style],
  13398. "role": "slider",
  13399. "tabindex": disabled.value ? -1 : 0,
  13400. "aria-valuemin": props.min,
  13401. "aria-valuemax": props.max,
  13402. "aria-valuenow": props.modelValue,
  13403. "aria-readonly": !!readonly.value,
  13404. "aria-orientation": direction.value,
  13405. "onKeydown": !readonly.value ? onKeydown : undefined
  13406. }, [createVNode("div", {
  13407. "class": ['v-slider-thumb__surface', textColorClasses.value, elevationClasses.value],
  13408. "style": {
  13409. ...textColorStyles.value
  13410. }
  13411. }, null), withDirectives(createVNode("div", {
  13412. "class": ['v-slider-thumb__ripple', textColorClasses.value],
  13413. "style": textColorStyles.value
  13414. }, null), [[resolveDirective("ripple"), props.ripple, null, {
  13415. circle: true,
  13416. center: true
  13417. }]]), createVNode(VScaleTransition, {
  13418. "origin": "bottom center"
  13419. }, {
  13420. default: () => [withDirectives(createVNode("div", {
  13421. "class": "v-slider-thumb__label-container"
  13422. }, [createVNode("div", {
  13423. "class": ['v-slider-thumb__label']
  13424. }, [createVNode("div", null, [slots['thumb-label']?.({
  13425. modelValue: props.modelValue
  13426. }) ?? props.modelValue.toFixed(step.value ? decimals.value : 1)])])]), [[vShow, thumbLabel.value && props.focused || thumbLabel.value === 'always']])]
  13427. })]);
  13428. });
  13429. return {};
  13430. }
  13431. });
  13432. // Types
  13433. const makeVSliderTrackProps = propsFactory({
  13434. start: {
  13435. type: Number,
  13436. required: true
  13437. },
  13438. stop: {
  13439. type: Number,
  13440. required: true
  13441. },
  13442. ...makeComponentProps()
  13443. }, 'VSliderTrack');
  13444. const VSliderTrack = genericComponent()({
  13445. name: 'VSliderTrack',
  13446. props: makeVSliderTrackProps(),
  13447. emits: {},
  13448. setup(props, _ref) {
  13449. let {
  13450. slots
  13451. } = _ref;
  13452. const slider = inject$1(VSliderSymbol);
  13453. if (!slider) throw new Error('[Vuetify] v-slider-track must be inside v-slider or v-range-slider');
  13454. const {
  13455. color,
  13456. horizontalDirection,
  13457. parsedTicks,
  13458. rounded,
  13459. showTicks,
  13460. tickSize,
  13461. trackColor,
  13462. trackFillColor,
  13463. trackSize,
  13464. vertical,
  13465. min,
  13466. max
  13467. } = slider;
  13468. const {
  13469. roundedClasses
  13470. } = useRounded(rounded);
  13471. const {
  13472. backgroundColorClasses: trackFillColorClasses,
  13473. backgroundColorStyles: trackFillColorStyles
  13474. } = useBackgroundColor(trackFillColor);
  13475. const {
  13476. backgroundColorClasses: trackColorClasses,
  13477. backgroundColorStyles: trackColorStyles
  13478. } = useBackgroundColor(trackColor);
  13479. const startDir = computed(() => `inset-${vertical.value ? 'block-end' : 'inline-start'}`);
  13480. const endDir = computed(() => vertical.value ? 'height' : 'width');
  13481. const backgroundStyles = computed(() => {
  13482. return {
  13483. [startDir.value]: '0%',
  13484. [endDir.value]: '100%'
  13485. };
  13486. });
  13487. const trackFillWidth = computed(() => props.stop - props.start);
  13488. const trackFillStyles = computed(() => {
  13489. return {
  13490. [startDir.value]: convertToUnit(props.start, '%'),
  13491. [endDir.value]: convertToUnit(trackFillWidth.value, '%')
  13492. };
  13493. });
  13494. const computedTicks = computed(() => {
  13495. if (!showTicks.value) return [];
  13496. const ticks = vertical.value ? parsedTicks.value.slice().reverse() : parsedTicks.value;
  13497. return ticks.map((tick, index) => {
  13498. const directionProperty = vertical.value ? 'bottom' : 'margin-inline-start';
  13499. const directionValue = tick.value !== min.value && tick.value !== max.value ? convertToUnit(tick.position, '%') : undefined;
  13500. return createVNode("div", {
  13501. "key": tick.value,
  13502. "class": ['v-slider-track__tick', {
  13503. 'v-slider-track__tick--filled': tick.position >= props.start && tick.position <= props.stop,
  13504. 'v-slider-track__tick--first': tick.value === min.value,
  13505. 'v-slider-track__tick--last': tick.value === max.value
  13506. }],
  13507. "style": {
  13508. [directionProperty]: directionValue
  13509. }
  13510. }, [(tick.label || slots['tick-label']) && createVNode("div", {
  13511. "class": "v-slider-track__tick-label"
  13512. }, [slots['tick-label']?.({
  13513. tick,
  13514. index
  13515. }) ?? tick.label])]);
  13516. });
  13517. });
  13518. useRender(() => {
  13519. return createVNode("div", {
  13520. "class": ['v-slider-track', roundedClasses.value, props.class],
  13521. "style": [{
  13522. '--v-slider-track-size': convertToUnit(trackSize.value),
  13523. '--v-slider-tick-size': convertToUnit(tickSize.value),
  13524. direction: !vertical.value ? horizontalDirection.value : undefined
  13525. }, props.style]
  13526. }, [createVNode("div", {
  13527. "class": ['v-slider-track__background', trackColorClasses.value, {
  13528. 'v-slider-track__background--opacity': !!color.value || !trackFillColor.value
  13529. }],
  13530. "style": {
  13531. ...backgroundStyles.value,
  13532. ...trackColorStyles.value
  13533. }
  13534. }, null), createVNode("div", {
  13535. "class": ['v-slider-track__fill', trackFillColorClasses.value],
  13536. "style": {
  13537. ...trackFillStyles.value,
  13538. ...trackFillColorStyles.value
  13539. }
  13540. }, null), showTicks.value && createVNode("div", {
  13541. "class": ['v-slider-track__ticks', {
  13542. 'v-slider-track__ticks--always-show': showTicks.value === 'always'
  13543. }]
  13544. }, [computedTicks.value])]);
  13545. });
  13546. return {};
  13547. }
  13548. });
  13549. // Types
  13550. const makeVSliderProps = propsFactory({
  13551. ...makeFocusProps(),
  13552. ...makeSliderProps(),
  13553. ...makeVInputProps(),
  13554. modelValue: {
  13555. type: [Number, String],
  13556. default: 0
  13557. }
  13558. }, 'VSlider');
  13559. const VSlider = genericComponent()({
  13560. name: 'VSlider',
  13561. props: makeVSliderProps(),
  13562. emits: {
  13563. 'update:focused': value => true,
  13564. 'update:modelValue': v => true,
  13565. start: value => true,
  13566. end: value => true
  13567. },
  13568. setup(props, _ref) {
  13569. let {
  13570. slots,
  13571. emit
  13572. } = _ref;
  13573. const thumbContainerRef = ref();
  13574. const {
  13575. rtlClasses
  13576. } = useRtl();
  13577. const steps = useSteps(props);
  13578. const model = useProxiedModel(props, 'modelValue', undefined, value => {
  13579. return steps.roundValue(value == null ? steps.min.value : value);
  13580. });
  13581. const {
  13582. min,
  13583. max,
  13584. mousePressed,
  13585. roundValue,
  13586. onSliderMousedown,
  13587. onSliderTouchstart,
  13588. trackContainerRef,
  13589. position,
  13590. hasLabels,
  13591. readonly
  13592. } = useSlider({
  13593. props,
  13594. steps,
  13595. onSliderStart: () => {
  13596. emit('start', model.value);
  13597. },
  13598. onSliderEnd: _ref2 => {
  13599. let {
  13600. value
  13601. } = _ref2;
  13602. const roundedValue = roundValue(value);
  13603. model.value = roundedValue;
  13604. emit('end', roundedValue);
  13605. },
  13606. onSliderMove: _ref3 => {
  13607. let {
  13608. value
  13609. } = _ref3;
  13610. return model.value = roundValue(value);
  13611. },
  13612. getActiveThumb: () => thumbContainerRef.value?.$el
  13613. });
  13614. const {
  13615. isFocused,
  13616. focus,
  13617. blur
  13618. } = useFocus(props);
  13619. const trackStop = computed(() => position(model.value));
  13620. useRender(() => {
  13621. const [inputProps, _] = VInput.filterProps(props);
  13622. const hasPrepend = !!(props.label || slots.label || slots.prepend);
  13623. return createVNode(VInput, mergeProps({
  13624. "class": ['v-slider', {
  13625. 'v-slider--has-labels': !!slots['tick-label'] || hasLabels.value,
  13626. 'v-slider--focused': isFocused.value,
  13627. 'v-slider--pressed': mousePressed.value,
  13628. 'v-slider--disabled': props.disabled
  13629. }, rtlClasses.value, props.class],
  13630. "style": props.style
  13631. }, inputProps, {
  13632. "focused": isFocused.value
  13633. }), {
  13634. ...slots,
  13635. prepend: hasPrepend ? slotProps => createVNode(Fragment, null, [slots.label?.(slotProps) ?? props.label ? createVNode(VLabel, {
  13636. "id": slotProps.id.value,
  13637. "class": "v-slider__label",
  13638. "text": props.label
  13639. }, null) : undefined, slots.prepend?.(slotProps)]) : undefined,
  13640. default: _ref4 => {
  13641. let {
  13642. id,
  13643. messagesId
  13644. } = _ref4;
  13645. return createVNode("div", {
  13646. "class": "v-slider__container",
  13647. "onMousedown": !readonly.value ? onSliderMousedown : undefined,
  13648. "onTouchstartPassive": !readonly.value ? onSliderTouchstart : undefined
  13649. }, [createVNode("input", {
  13650. "id": id.value,
  13651. "name": props.name || id.value,
  13652. "disabled": !!props.disabled,
  13653. "readonly": !!props.readonly,
  13654. "tabindex": "-1",
  13655. "value": model.value
  13656. }, null), createVNode(VSliderTrack, {
  13657. "ref": trackContainerRef,
  13658. "start": 0,
  13659. "stop": trackStop.value
  13660. }, {
  13661. 'tick-label': slots['tick-label']
  13662. }), createVNode(VSliderThumb, {
  13663. "ref": thumbContainerRef,
  13664. "aria-describedby": messagesId.value,
  13665. "focused": isFocused.value,
  13666. "min": min.value,
  13667. "max": max.value,
  13668. "modelValue": model.value,
  13669. "onUpdate:modelValue": v => model.value = v,
  13670. "position": trackStop.value,
  13671. "elevation": props.elevation,
  13672. "onFocus": focus,
  13673. "onBlur": blur
  13674. }, {
  13675. 'thumb-label': slots['thumb-label']
  13676. })]);
  13677. }
  13678. });
  13679. });
  13680. return {};
  13681. }
  13682. });
  13683. // Types
  13684. const makeVColorPickerPreviewProps = propsFactory({
  13685. color: {
  13686. type: Object
  13687. },
  13688. disabled: Boolean,
  13689. hideAlpha: Boolean,
  13690. ...makeComponentProps()
  13691. }, 'VColorPickerPreview');
  13692. const VColorPickerPreview = defineComponent({
  13693. name: 'VColorPickerPreview',
  13694. props: makeVColorPickerPreviewProps(),
  13695. emits: {
  13696. 'update:color': color => true
  13697. },
  13698. setup(props, _ref) {
  13699. let {
  13700. emit
  13701. } = _ref;
  13702. useRender(() => createVNode("div", {
  13703. "class": ['v-color-picker-preview', {
  13704. 'v-color-picker-preview--hide-alpha': props.hideAlpha
  13705. }, props.class],
  13706. "style": props.style
  13707. }, [createVNode("div", {
  13708. "class": "v-color-picker-preview__dot"
  13709. }, [createVNode("div", {
  13710. "style": {
  13711. background: HSVtoCSS(props.color ?? nullColor)
  13712. }
  13713. }, null)]), createVNode("div", {
  13714. "class": "v-color-picker-preview__sliders"
  13715. }, [createVNode(VSlider, {
  13716. "class": "v-color-picker-preview__track v-color-picker-preview__hue",
  13717. "modelValue": props.color?.h,
  13718. "onUpdate:modelValue": h => emit('update:color', {
  13719. ...(props.color ?? nullColor),
  13720. h
  13721. }),
  13722. "step": 0,
  13723. "min": 0,
  13724. "max": 360,
  13725. "disabled": props.disabled,
  13726. "thumbSize": 14,
  13727. "trackSize": 8,
  13728. "trackFillColor": "white",
  13729. "hideDetails": true
  13730. }, null), !props.hideAlpha && createVNode(VSlider, {
  13731. "class": "v-color-picker-preview__track v-color-picker-preview__alpha",
  13732. "modelValue": props.color?.a ?? 1,
  13733. "onUpdate:modelValue": a => emit('update:color', {
  13734. ...(props.color ?? nullColor),
  13735. a
  13736. }),
  13737. "step": 1 / 256,
  13738. "min": 0,
  13739. "max": 1,
  13740. "disabled": props.disabled,
  13741. "thumbSize": 14,
  13742. "trackSize": 8,
  13743. "trackFillColor": "white",
  13744. "hideDetails": true
  13745. }, null)])]));
  13746. return {};
  13747. }
  13748. });
  13749. const red = Object.freeze({
  13750. base: '#f44336',
  13751. lighten5: '#ffebee',
  13752. lighten4: '#ffcdd2',
  13753. lighten3: '#ef9a9a',
  13754. lighten2: '#e57373',
  13755. lighten1: '#ef5350',
  13756. darken1: '#e53935',
  13757. darken2: '#d32f2f',
  13758. darken3: '#c62828',
  13759. darken4: '#b71c1c',
  13760. accent1: '#ff8a80',
  13761. accent2: '#ff5252',
  13762. accent3: '#ff1744',
  13763. accent4: '#d50000'
  13764. });
  13765. const pink = Object.freeze({
  13766. base: '#e91e63',
  13767. lighten5: '#fce4ec',
  13768. lighten4: '#f8bbd0',
  13769. lighten3: '#f48fb1',
  13770. lighten2: '#f06292',
  13771. lighten1: '#ec407a',
  13772. darken1: '#d81b60',
  13773. darken2: '#c2185b',
  13774. darken3: '#ad1457',
  13775. darken4: '#880e4f',
  13776. accent1: '#ff80ab',
  13777. accent2: '#ff4081',
  13778. accent3: '#f50057',
  13779. accent4: '#c51162'
  13780. });
  13781. const purple = Object.freeze({
  13782. base: '#9c27b0',
  13783. lighten5: '#f3e5f5',
  13784. lighten4: '#e1bee7',
  13785. lighten3: '#ce93d8',
  13786. lighten2: '#ba68c8',
  13787. lighten1: '#ab47bc',
  13788. darken1: '#8e24aa',
  13789. darken2: '#7b1fa2',
  13790. darken3: '#6a1b9a',
  13791. darken4: '#4a148c',
  13792. accent1: '#ea80fc',
  13793. accent2: '#e040fb',
  13794. accent3: '#d500f9',
  13795. accent4: '#aa00ff'
  13796. });
  13797. const deepPurple = Object.freeze({
  13798. base: '#673ab7',
  13799. lighten5: '#ede7f6',
  13800. lighten4: '#d1c4e9',
  13801. lighten3: '#b39ddb',
  13802. lighten2: '#9575cd',
  13803. lighten1: '#7e57c2',
  13804. darken1: '#5e35b1',
  13805. darken2: '#512da8',
  13806. darken3: '#4527a0',
  13807. darken4: '#311b92',
  13808. accent1: '#b388ff',
  13809. accent2: '#7c4dff',
  13810. accent3: '#651fff',
  13811. accent4: '#6200ea'
  13812. });
  13813. const indigo = Object.freeze({
  13814. base: '#3f51b5',
  13815. lighten5: '#e8eaf6',
  13816. lighten4: '#c5cae9',
  13817. lighten3: '#9fa8da',
  13818. lighten2: '#7986cb',
  13819. lighten1: '#5c6bc0',
  13820. darken1: '#3949ab',
  13821. darken2: '#303f9f',
  13822. darken3: '#283593',
  13823. darken4: '#1a237e',
  13824. accent1: '#8c9eff',
  13825. accent2: '#536dfe',
  13826. accent3: '#3d5afe',
  13827. accent4: '#304ffe'
  13828. });
  13829. const blue = Object.freeze({
  13830. base: '#2196f3',
  13831. lighten5: '#e3f2fd',
  13832. lighten4: '#bbdefb',
  13833. lighten3: '#90caf9',
  13834. lighten2: '#64b5f6',
  13835. lighten1: '#42a5f5',
  13836. darken1: '#1e88e5',
  13837. darken2: '#1976d2',
  13838. darken3: '#1565c0',
  13839. darken4: '#0d47a1',
  13840. accent1: '#82b1ff',
  13841. accent2: '#448aff',
  13842. accent3: '#2979ff',
  13843. accent4: '#2962ff'
  13844. });
  13845. const lightBlue = Object.freeze({
  13846. base: '#03a9f4',
  13847. lighten5: '#e1f5fe',
  13848. lighten4: '#b3e5fc',
  13849. lighten3: '#81d4fa',
  13850. lighten2: '#4fc3f7',
  13851. lighten1: '#29b6f6',
  13852. darken1: '#039be5',
  13853. darken2: '#0288d1',
  13854. darken3: '#0277bd',
  13855. darken4: '#01579b',
  13856. accent1: '#80d8ff',
  13857. accent2: '#40c4ff',
  13858. accent3: '#00b0ff',
  13859. accent4: '#0091ea'
  13860. });
  13861. const cyan = Object.freeze({
  13862. base: '#00bcd4',
  13863. lighten5: '#e0f7fa',
  13864. lighten4: '#b2ebf2',
  13865. lighten3: '#80deea',
  13866. lighten2: '#4dd0e1',
  13867. lighten1: '#26c6da',
  13868. darken1: '#00acc1',
  13869. darken2: '#0097a7',
  13870. darken3: '#00838f',
  13871. darken4: '#006064',
  13872. accent1: '#84ffff',
  13873. accent2: '#18ffff',
  13874. accent3: '#00e5ff',
  13875. accent4: '#00b8d4'
  13876. });
  13877. const teal = Object.freeze({
  13878. base: '#009688',
  13879. lighten5: '#e0f2f1',
  13880. lighten4: '#b2dfdb',
  13881. lighten3: '#80cbc4',
  13882. lighten2: '#4db6ac',
  13883. lighten1: '#26a69a',
  13884. darken1: '#00897b',
  13885. darken2: '#00796b',
  13886. darken3: '#00695c',
  13887. darken4: '#004d40',
  13888. accent1: '#a7ffeb',
  13889. accent2: '#64ffda',
  13890. accent3: '#1de9b6',
  13891. accent4: '#00bfa5'
  13892. });
  13893. const green = Object.freeze({
  13894. base: '#4caf50',
  13895. lighten5: '#e8f5e9',
  13896. lighten4: '#c8e6c9',
  13897. lighten3: '#a5d6a7',
  13898. lighten2: '#81c784',
  13899. lighten1: '#66bb6a',
  13900. darken1: '#43a047',
  13901. darken2: '#388e3c',
  13902. darken3: '#2e7d32',
  13903. darken4: '#1b5e20',
  13904. accent1: '#b9f6ca',
  13905. accent2: '#69f0ae',
  13906. accent3: '#00e676',
  13907. accent4: '#00c853'
  13908. });
  13909. const lightGreen = Object.freeze({
  13910. base: '#8bc34a',
  13911. lighten5: '#f1f8e9',
  13912. lighten4: '#dcedc8',
  13913. lighten3: '#c5e1a5',
  13914. lighten2: '#aed581',
  13915. lighten1: '#9ccc65',
  13916. darken1: '#7cb342',
  13917. darken2: '#689f38',
  13918. darken3: '#558b2f',
  13919. darken4: '#33691e',
  13920. accent1: '#ccff90',
  13921. accent2: '#b2ff59',
  13922. accent3: '#76ff03',
  13923. accent4: '#64dd17'
  13924. });
  13925. const lime = Object.freeze({
  13926. base: '#cddc39',
  13927. lighten5: '#f9fbe7',
  13928. lighten4: '#f0f4c3',
  13929. lighten3: '#e6ee9c',
  13930. lighten2: '#dce775',
  13931. lighten1: '#d4e157',
  13932. darken1: '#c0ca33',
  13933. darken2: '#afb42b',
  13934. darken3: '#9e9d24',
  13935. darken4: '#827717',
  13936. accent1: '#f4ff81',
  13937. accent2: '#eeff41',
  13938. accent3: '#c6ff00',
  13939. accent4: '#aeea00'
  13940. });
  13941. const yellow = Object.freeze({
  13942. base: '#ffeb3b',
  13943. lighten5: '#fffde7',
  13944. lighten4: '#fff9c4',
  13945. lighten3: '#fff59d',
  13946. lighten2: '#fff176',
  13947. lighten1: '#ffee58',
  13948. darken1: '#fdd835',
  13949. darken2: '#fbc02d',
  13950. darken3: '#f9a825',
  13951. darken4: '#f57f17',
  13952. accent1: '#ffff8d',
  13953. accent2: '#ffff00',
  13954. accent3: '#ffea00',
  13955. accent4: '#ffd600'
  13956. });
  13957. const amber = Object.freeze({
  13958. base: '#ffc107',
  13959. lighten5: '#fff8e1',
  13960. lighten4: '#ffecb3',
  13961. lighten3: '#ffe082',
  13962. lighten2: '#ffd54f',
  13963. lighten1: '#ffca28',
  13964. darken1: '#ffb300',
  13965. darken2: '#ffa000',
  13966. darken3: '#ff8f00',
  13967. darken4: '#ff6f00',
  13968. accent1: '#ffe57f',
  13969. accent2: '#ffd740',
  13970. accent3: '#ffc400',
  13971. accent4: '#ffab00'
  13972. });
  13973. const orange = Object.freeze({
  13974. base: '#ff9800',
  13975. lighten5: '#fff3e0',
  13976. lighten4: '#ffe0b2',
  13977. lighten3: '#ffcc80',
  13978. lighten2: '#ffb74d',
  13979. lighten1: '#ffa726',
  13980. darken1: '#fb8c00',
  13981. darken2: '#f57c00',
  13982. darken3: '#ef6c00',
  13983. darken4: '#e65100',
  13984. accent1: '#ffd180',
  13985. accent2: '#ffab40',
  13986. accent3: '#ff9100',
  13987. accent4: '#ff6d00'
  13988. });
  13989. const deepOrange = Object.freeze({
  13990. base: '#ff5722',
  13991. lighten5: '#fbe9e7',
  13992. lighten4: '#ffccbc',
  13993. lighten3: '#ffab91',
  13994. lighten2: '#ff8a65',
  13995. lighten1: '#ff7043',
  13996. darken1: '#f4511e',
  13997. darken2: '#e64a19',
  13998. darken3: '#d84315',
  13999. darken4: '#bf360c',
  14000. accent1: '#ff9e80',
  14001. accent2: '#ff6e40',
  14002. accent3: '#ff3d00',
  14003. accent4: '#dd2c00'
  14004. });
  14005. const brown = Object.freeze({
  14006. base: '#795548',
  14007. lighten5: '#efebe9',
  14008. lighten4: '#d7ccc8',
  14009. lighten3: '#bcaaa4',
  14010. lighten2: '#a1887f',
  14011. lighten1: '#8d6e63',
  14012. darken1: '#6d4c41',
  14013. darken2: '#5d4037',
  14014. darken3: '#4e342e',
  14015. darken4: '#3e2723'
  14016. });
  14017. const blueGrey = Object.freeze({
  14018. base: '#607d8b',
  14019. lighten5: '#eceff1',
  14020. lighten4: '#cfd8dc',
  14021. lighten3: '#b0bec5',
  14022. lighten2: '#90a4ae',
  14023. lighten1: '#78909c',
  14024. darken1: '#546e7a',
  14025. darken2: '#455a64',
  14026. darken3: '#37474f',
  14027. darken4: '#263238'
  14028. });
  14029. const grey = Object.freeze({
  14030. base: '#9e9e9e',
  14031. lighten5: '#fafafa',
  14032. lighten4: '#f5f5f5',
  14033. lighten3: '#eeeeee',
  14034. lighten2: '#e0e0e0',
  14035. lighten1: '#bdbdbd',
  14036. darken1: '#757575',
  14037. darken2: '#616161',
  14038. darken3: '#424242',
  14039. darken4: '#212121'
  14040. });
  14041. const shades = Object.freeze({
  14042. black: '#000000',
  14043. white: '#ffffff',
  14044. transparent: '#ffffff00'
  14045. });
  14046. var colors = Object.freeze({
  14047. red,
  14048. pink,
  14049. purple,
  14050. deepPurple,
  14051. indigo,
  14052. blue,
  14053. lightBlue,
  14054. cyan,
  14055. teal,
  14056. green,
  14057. lightGreen,
  14058. lime,
  14059. yellow,
  14060. amber,
  14061. orange,
  14062. deepOrange,
  14063. brown,
  14064. blueGrey,
  14065. grey,
  14066. shades
  14067. });
  14068. // Types
  14069. const makeVColorPickerSwatchesProps = propsFactory({
  14070. swatches: {
  14071. type: Array,
  14072. default: () => parseDefaultColors(colors)
  14073. },
  14074. disabled: Boolean,
  14075. color: Object,
  14076. maxHeight: [Number, String],
  14077. ...makeComponentProps()
  14078. }, 'VColorPickerSwatches');
  14079. function parseDefaultColors(colors) {
  14080. return Object.keys(colors).map(key => {
  14081. const color = colors[key];
  14082. 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];
  14083. });
  14084. }
  14085. const VColorPickerSwatches = defineComponent({
  14086. name: 'VColorPickerSwatches',
  14087. props: makeVColorPickerSwatchesProps(),
  14088. emits: {
  14089. 'update:color': color => true
  14090. },
  14091. setup(props, _ref) {
  14092. let {
  14093. emit
  14094. } = _ref;
  14095. useRender(() => createVNode("div", {
  14096. "class": ['v-color-picker-swatches', props.class],
  14097. "style": [{
  14098. maxHeight: convertToUnit(props.maxHeight)
  14099. }, props.style]
  14100. }, [createVNode("div", null, [props.swatches.map(swatch => createVNode("div", {
  14101. "class": "v-color-picker-swatches__swatch"
  14102. }, [swatch.map(color => {
  14103. const rgba = parseColor(color);
  14104. const hsva = RGBtoHSV(rgba);
  14105. const background = RGBtoCSS(rgba);
  14106. return createVNode("div", {
  14107. "class": "v-color-picker-swatches__color",
  14108. "onClick": () => hsva && emit('update:color', hsva)
  14109. }, [createVNode("div", {
  14110. "style": {
  14111. background
  14112. }
  14113. }, [props.color && deepEqual(props.color, hsva) ? createVNode(VIcon, {
  14114. "size": "x-small",
  14115. "icon": "$success",
  14116. "color": getContrast(color, '#FFFFFF') > 2 ? 'white' : 'black'
  14117. }, null) : undefined])]);
  14118. })]))])]));
  14119. return {};
  14120. }
  14121. });
  14122. const makeVSheetProps = propsFactory({
  14123. color: String,
  14124. ...makeBorderProps(),
  14125. ...makeComponentProps(),
  14126. ...makeDimensionProps(),
  14127. ...makeElevationProps(),
  14128. ...makeLocationProps(),
  14129. ...makePositionProps(),
  14130. ...makeRoundedProps(),
  14131. ...makeTagProps(),
  14132. ...makeThemeProps()
  14133. }, 'VSheet');
  14134. const VSheet = genericComponent()({
  14135. name: 'VSheet',
  14136. props: makeVSheetProps(),
  14137. setup(props, _ref) {
  14138. let {
  14139. slots
  14140. } = _ref;
  14141. const {
  14142. themeClasses
  14143. } = provideTheme(props);
  14144. const {
  14145. backgroundColorClasses,
  14146. backgroundColorStyles
  14147. } = useBackgroundColor(toRef(props, 'color'));
  14148. const {
  14149. borderClasses
  14150. } = useBorder(props);
  14151. const {
  14152. dimensionStyles
  14153. } = useDimension(props);
  14154. const {
  14155. elevationClasses
  14156. } = useElevation(props);
  14157. const {
  14158. locationStyles
  14159. } = useLocation(props);
  14160. const {
  14161. positionClasses
  14162. } = usePosition(props);
  14163. const {
  14164. roundedClasses
  14165. } = useRounded(props);
  14166. useRender(() => createVNode(props.tag, {
  14167. "class": ['v-sheet', themeClasses.value, backgroundColorClasses.value, borderClasses.value, elevationClasses.value, positionClasses.value, roundedClasses.value, props.class],
  14168. "style": [backgroundColorStyles.value, dimensionStyles.value, locationStyles.value, props.style]
  14169. }, slots));
  14170. return {};
  14171. }
  14172. });
  14173. // Types
  14174. const makeVColorPickerProps = propsFactory({
  14175. canvasHeight: {
  14176. type: [String, Number],
  14177. default: 150
  14178. },
  14179. disabled: Boolean,
  14180. dotSize: {
  14181. type: [Number, String],
  14182. default: 10
  14183. },
  14184. hideCanvas: Boolean,
  14185. hideSliders: Boolean,
  14186. hideInputs: Boolean,
  14187. mode: {
  14188. type: String,
  14189. default: 'rgba',
  14190. validator: v => Object.keys(modes).includes(v)
  14191. },
  14192. modes: {
  14193. type: Array,
  14194. default: () => Object.keys(modes),
  14195. validator: v => Array.isArray(v) && v.every(m => Object.keys(modes).includes(m))
  14196. },
  14197. showSwatches: Boolean,
  14198. swatches: Array,
  14199. swatchesMaxHeight: {
  14200. type: [Number, String],
  14201. default: 150
  14202. },
  14203. modelValue: {
  14204. type: [Object, String]
  14205. },
  14206. ...omit(makeVSheetProps({
  14207. width: 300
  14208. }), ['height', 'location', 'minHeight', 'maxHeight', 'minWidth', 'maxWidth'])
  14209. }, 'VColorPicker');
  14210. const VColorPicker = defineComponent({
  14211. name: 'VColorPicker',
  14212. props: makeVColorPickerProps(),
  14213. emits: {
  14214. 'update:modelValue': color => true,
  14215. 'update:mode': mode => true
  14216. },
  14217. setup(props) {
  14218. const mode = useProxiedModel(props, 'mode');
  14219. const lastPickedColor = ref(null);
  14220. const currentColor = useProxiedModel(props, 'modelValue', undefined, v => {
  14221. if (v == null || v === '') return null;
  14222. let c;
  14223. try {
  14224. c = RGBtoHSV(parseColor(v));
  14225. } catch (err) {
  14226. consoleWarn(err);
  14227. return null;
  14228. }
  14229. if (lastPickedColor.value) {
  14230. c = {
  14231. ...c,
  14232. h: lastPickedColor.value.h
  14233. };
  14234. lastPickedColor.value = null;
  14235. }
  14236. return c;
  14237. }, v => {
  14238. if (!v) return null;
  14239. return extractColor(v, props.modelValue);
  14240. });
  14241. const {
  14242. rtlClasses
  14243. } = useRtl();
  14244. const updateColor = hsva => {
  14245. currentColor.value = hsva;
  14246. lastPickedColor.value = hsva;
  14247. };
  14248. onMounted(() => {
  14249. if (!props.modes.includes(mode.value)) mode.value = props.modes[0];
  14250. });
  14251. provideDefaults({
  14252. VSlider: {
  14253. color: undefined,
  14254. trackColor: undefined,
  14255. trackFillColor: undefined
  14256. }
  14257. });
  14258. useRender(() => {
  14259. const [sheetProps] = VSheet.filterProps(props);
  14260. return createVNode(VSheet, mergeProps({
  14261. "rounded": props.rounded,
  14262. "elevation": props.elevation,
  14263. "theme": props.theme,
  14264. "class": ['v-color-picker', rtlClasses.value, props.class],
  14265. "style": [{
  14266. '--v-color-picker-color-hsv': HSVtoCSS({
  14267. ...(currentColor.value ?? nullColor),
  14268. a: 1
  14269. })
  14270. }, props.style]
  14271. }, sheetProps, {
  14272. "maxWidth": props.width
  14273. }), {
  14274. default: () => [!props.hideCanvas && createVNode(VColorPickerCanvas, {
  14275. "key": "canvas",
  14276. "color": currentColor.value,
  14277. "onUpdate:color": updateColor,
  14278. "disabled": props.disabled,
  14279. "dotSize": props.dotSize,
  14280. "width": props.width,
  14281. "height": props.canvasHeight
  14282. }, null), (!props.hideSliders || !props.hideInputs) && createVNode("div", {
  14283. "key": "controls",
  14284. "class": "v-color-picker__controls"
  14285. }, [!props.hideSliders && createVNode(VColorPickerPreview, {
  14286. "key": "preview",
  14287. "color": currentColor.value,
  14288. "onUpdate:color": updateColor,
  14289. "hideAlpha": !mode.value.endsWith('a'),
  14290. "disabled": props.disabled
  14291. }, null), !props.hideInputs && createVNode(VColorPickerEdit, {
  14292. "key": "edit",
  14293. "modes": props.modes,
  14294. "mode": mode.value,
  14295. "onUpdate:mode": m => mode.value = m,
  14296. "color": currentColor.value,
  14297. "onUpdate:color": updateColor,
  14298. "disabled": props.disabled
  14299. }, null)]), props.showSwatches && createVNode(VColorPickerSwatches, {
  14300. "key": "swatches",
  14301. "color": currentColor.value,
  14302. "onUpdate:color": updateColor,
  14303. "maxHeight": props.swatchesMaxHeight,
  14304. "swatches": props.swatches,
  14305. "disabled": props.disabled
  14306. }, null)]
  14307. });
  14308. });
  14309. return {};
  14310. }
  14311. });
  14312. // Types
  14313. function highlightResult(text, matches, length) {
  14314. if (matches == null) return text;
  14315. if (Array.isArray(matches)) throw new Error('Multiple matches is not implemented');
  14316. return typeof matches === 'number' && ~matches ? createVNode(Fragment, null, [createVNode("span", {
  14317. "class": "v-combobox__unmask"
  14318. }, [text.substr(0, matches)]), createVNode("span", {
  14319. "class": "v-combobox__mask"
  14320. }, [text.substr(matches, length)]), createVNode("span", {
  14321. "class": "v-combobox__unmask"
  14322. }, [text.substr(matches + length)])]) : text;
  14323. }
  14324. const makeVComboboxProps = propsFactory({
  14325. autoSelectFirst: {
  14326. type: [Boolean, String]
  14327. },
  14328. delimiters: Array,
  14329. ...makeFilterProps({
  14330. filterKeys: ['title']
  14331. }),
  14332. ...makeSelectProps({
  14333. hideNoData: true,
  14334. returnObject: true
  14335. }),
  14336. ...omit(makeVTextFieldProps({
  14337. modelValue: null
  14338. }), ['validationValue', 'dirty', 'appendInnerIcon']),
  14339. ...makeTransitionProps({
  14340. transition: false
  14341. })
  14342. }, 'VCombobox');
  14343. const VCombobox = genericComponent()({
  14344. name: 'VCombobox',
  14345. props: makeVComboboxProps(),
  14346. emits: {
  14347. 'update:focused': focused => true,
  14348. 'update:modelValue': val => true,
  14349. 'update:search': val => true,
  14350. 'update:menu': val => true
  14351. },
  14352. setup(props, _ref) {
  14353. let {
  14354. emit,
  14355. slots
  14356. } = _ref;
  14357. const {
  14358. t
  14359. } = useLocale();
  14360. const vTextFieldRef = ref();
  14361. const isFocused = shallowRef(false);
  14362. const isPristine = shallowRef(true);
  14363. const listHasFocus = shallowRef(false);
  14364. const vMenuRef = ref();
  14365. const _menu = useProxiedModel(props, 'menu');
  14366. const menu = computed({
  14367. get: () => _menu.value,
  14368. set: v => {
  14369. if (_menu.value && !v && vMenuRef.value?.ΨopenChildren) return;
  14370. _menu.value = v;
  14371. }
  14372. });
  14373. const selectionIndex = shallowRef(-1);
  14374. let cleared = false;
  14375. const color = computed(() => vTextFieldRef.value?.color);
  14376. const {
  14377. items,
  14378. transformIn,
  14379. transformOut
  14380. } = useItems(props);
  14381. const {
  14382. textColorClasses,
  14383. textColorStyles
  14384. } = useTextColor(color);
  14385. const model = useProxiedModel(props, 'modelValue', [], v => transformIn(wrapInArray(v)), v => {
  14386. const transformed = transformOut(v);
  14387. return props.multiple ? transformed : transformed[0] ?? null;
  14388. });
  14389. const form = useForm();
  14390. const _search = shallowRef(!props.multiple ? model.value[0]?.title ?? '' : '');
  14391. const search = computed({
  14392. get: () => {
  14393. return _search.value;
  14394. },
  14395. set: val => {
  14396. _search.value = val;
  14397. if (!props.multiple) {
  14398. model.value = [transformItem$3(props, val)];
  14399. }
  14400. if (val && props.multiple && props.delimiters?.length) {
  14401. const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
  14402. if (values.length > 1) {
  14403. values.forEach(v => {
  14404. v = v.trim();
  14405. if (v) select(transformItem$3(props, v));
  14406. });
  14407. _search.value = '';
  14408. }
  14409. }
  14410. if (!val) selectionIndex.value = -1;
  14411. isPristine.value = !val;
  14412. }
  14413. });
  14414. watch(_search, value => {
  14415. if (cleared) {
  14416. // wait for clear to finish, VTextField sets _search to null
  14417. // then search computed triggers and updates _search to ''
  14418. nextTick(() => cleared = false);
  14419. } else if (isFocused.value && !menu.value) {
  14420. menu.value = true;
  14421. }
  14422. emit('update:search', value);
  14423. });
  14424. watch(model, value => {
  14425. if (!props.multiple) {
  14426. _search.value = value[0]?.title ?? '';
  14427. }
  14428. });
  14429. const {
  14430. filteredItems,
  14431. getMatches
  14432. } = useFilter(props, items, () => isPristine.value ? '' : search.value);
  14433. const selections = computed(() => {
  14434. return model.value.map(v => {
  14435. return items.value.find(item => {
  14436. const itemRawValue = getPropertyFromItem(item.raw, props.itemValue);
  14437. const modelRawValue = getPropertyFromItem(v.raw, props.itemValue);
  14438. if (itemRawValue === undefined || modelRawValue === undefined) return false;
  14439. return props.returnObject ? props.valueComparator(itemRawValue, modelRawValue) : props.valueComparator(item.value, v.value);
  14440. }) || v;
  14441. });
  14442. });
  14443. const displayItems = computed(() => {
  14444. if (props.hideSelected) {
  14445. return filteredItems.value.filter(filteredItem => !selections.value.some(s => s.value === filteredItem.value));
  14446. }
  14447. return filteredItems.value;
  14448. });
  14449. const selected = computed(() => selections.value.map(selection => selection.props.value));
  14450. const selection = computed(() => selections.value[selectionIndex.value]);
  14451. const highlightFirst = computed(() => {
  14452. const selectFirst = props.autoSelectFirst === true || props.autoSelectFirst === 'exact' && search.value === displayItems.value[0]?.title;
  14453. return selectFirst && displayItems.value.length > 0 && !isPristine.value && !listHasFocus.value;
  14454. });
  14455. const menuDisabled = computed(() => props.hideNoData && !items.value.length || props.readonly || form?.isReadonly.value);
  14456. const listRef = ref();
  14457. const {
  14458. onListScroll,
  14459. onListKeydown
  14460. } = useScrolling(listRef, vTextFieldRef);
  14461. function onClear(e) {
  14462. cleared = true;
  14463. if (props.openOnClear) {
  14464. menu.value = true;
  14465. }
  14466. }
  14467. function onMousedownControl() {
  14468. if (menuDisabled.value) return;
  14469. menu.value = true;
  14470. }
  14471. function onMousedownMenuIcon(e) {
  14472. if (menuDisabled.value) return;
  14473. if (isFocused.value) {
  14474. e.preventDefault();
  14475. e.stopPropagation();
  14476. }
  14477. menu.value = !menu.value;
  14478. }
  14479. function onKeydown(e) {
  14480. if (props.readonly || form?.isReadonly.value) return;
  14481. const selectionStart = vTextFieldRef.value.selectionStart;
  14482. const length = selected.value.length;
  14483. if (selectionIndex.value > -1 || ['Enter', 'ArrowDown', 'ArrowUp'].includes(e.key)) {
  14484. e.preventDefault();
  14485. }
  14486. if (['Enter', 'ArrowDown'].includes(e.key)) {
  14487. menu.value = true;
  14488. }
  14489. if (['Escape'].includes(e.key)) {
  14490. menu.value = false;
  14491. }
  14492. if (['Enter', 'Escape', 'Tab'].includes(e.key)) {
  14493. if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key)) {
  14494. select(filteredItems.value[0]);
  14495. }
  14496. isPristine.value = true;
  14497. }
  14498. if (e.key === 'ArrowDown' && highlightFirst.value) {
  14499. listRef.value?.focus('next');
  14500. }
  14501. if (!props.multiple) return;
  14502. if (['Backspace', 'Delete'].includes(e.key)) {
  14503. if (selectionIndex.value < 0) {
  14504. if (e.key === 'Backspace' && !search.value) {
  14505. selectionIndex.value = length - 1;
  14506. }
  14507. return;
  14508. }
  14509. const originalSelectionIndex = selectionIndex.value;
  14510. if (selection.value) select(selection.value);
  14511. selectionIndex.value = originalSelectionIndex >= length - 1 ? length - 2 : originalSelectionIndex;
  14512. }
  14513. if (e.key === 'ArrowLeft') {
  14514. if (selectionIndex.value < 0 && selectionStart > 0) return;
  14515. const prev = selectionIndex.value > -1 ? selectionIndex.value - 1 : length - 1;
  14516. if (selections.value[prev]) {
  14517. selectionIndex.value = prev;
  14518. } else {
  14519. selectionIndex.value = -1;
  14520. vTextFieldRef.value.setSelectionRange(search.value.length, search.value.length);
  14521. }
  14522. }
  14523. if (e.key === 'ArrowRight') {
  14524. if (selectionIndex.value < 0) return;
  14525. const next = selectionIndex.value + 1;
  14526. if (selections.value[next]) {
  14527. selectionIndex.value = next;
  14528. } else {
  14529. selectionIndex.value = -1;
  14530. vTextFieldRef.value.setSelectionRange(0, 0);
  14531. }
  14532. }
  14533. if (e.key === 'Enter' && search.value) {
  14534. select(transformItem$3(props, search.value));
  14535. search.value = '';
  14536. }
  14537. }
  14538. function onAfterLeave() {
  14539. if (isFocused.value) {
  14540. isPristine.value = true;
  14541. vTextFieldRef.value?.focus();
  14542. }
  14543. }
  14544. function select(item) {
  14545. if (props.multiple) {
  14546. const index = selected.value.findIndex(selection => props.valueComparator(selection, item.value));
  14547. if (index === -1) {
  14548. model.value = [...model.value, item];
  14549. } else {
  14550. const value = [...model.value];
  14551. value.splice(index, 1);
  14552. model.value = value;
  14553. }
  14554. search.value = '';
  14555. } else {
  14556. model.value = [item];
  14557. _search.value = item.title;
  14558. // watch for search watcher to trigger
  14559. nextTick(() => {
  14560. menu.value = false;
  14561. isPristine.value = true;
  14562. });
  14563. }
  14564. }
  14565. function onFocusin(e) {
  14566. isFocused.value = true;
  14567. setTimeout(() => {
  14568. listHasFocus.value = true;
  14569. });
  14570. }
  14571. function onFocusout(e) {
  14572. listHasFocus.value = false;
  14573. }
  14574. function onUpdateModelValue(v) {
  14575. if (v == null || v === '' && !props.multiple) model.value = [];
  14576. }
  14577. watch(filteredItems, val => {
  14578. if (!val.length && props.hideNoData) menu.value = false;
  14579. });
  14580. watch(isFocused, (val, oldVal) => {
  14581. if (val || val === oldVal) return;
  14582. selectionIndex.value = -1;
  14583. menu.value = false;
  14584. if (highlightFirst.value && !listHasFocus.value && !selections.value.some(_ref2 => {
  14585. let {
  14586. value
  14587. } = _ref2;
  14588. return value === displayItems.value[0].value;
  14589. })) {
  14590. select(displayItems.value[0]);
  14591. } else if (props.multiple && search.value) {
  14592. model.value = [...model.value, transformItem$3(props, search.value)];
  14593. search.value = '';
  14594. }
  14595. });
  14596. useRender(() => {
  14597. const hasChips = !!(props.chips || slots.chip);
  14598. const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
  14599. const isDirty = model.value.length > 0;
  14600. const [textFieldProps] = VTextField.filterProps(props);
  14601. return createVNode(VTextField, mergeProps({
  14602. "ref": vTextFieldRef
  14603. }, textFieldProps, {
  14604. "modelValue": search.value,
  14605. "onUpdate:modelValue": [$event => search.value = $event, onUpdateModelValue],
  14606. "focused": isFocused.value,
  14607. "onUpdate:focused": $event => isFocused.value = $event,
  14608. "validationValue": model.externalValue,
  14609. "dirty": isDirty,
  14610. "class": ['v-combobox', {
  14611. 'v-combobox--active-menu': menu.value,
  14612. 'v-combobox--chips': !!props.chips,
  14613. 'v-combobox--selection-slot': !!slots.selection,
  14614. 'v-combobox--selecting-index': selectionIndex.value > -1,
  14615. [`v-combobox--${props.multiple ? 'multiple' : 'single'}`]: true
  14616. }, props.class],
  14617. "style": props.style,
  14618. "readonly": props.readonly,
  14619. "placeholder": isDirty ? undefined : props.placeholder,
  14620. "onClick:clear": onClear,
  14621. "onMousedown:control": onMousedownControl,
  14622. "onKeydown": onKeydown
  14623. }), {
  14624. ...slots,
  14625. default: () => createVNode(Fragment, null, [createVNode(VMenu, mergeProps({
  14626. "ref": vMenuRef,
  14627. "modelValue": menu.value,
  14628. "onUpdate:modelValue": $event => menu.value = $event,
  14629. "activator": "parent",
  14630. "contentClass": "v-combobox__content",
  14631. "disabled": menuDisabled.value,
  14632. "eager": props.eager,
  14633. "maxHeight": 310,
  14634. "openOnClick": false,
  14635. "closeOnContentClick": false,
  14636. "transition": props.transition,
  14637. "onAfterLeave": onAfterLeave
  14638. }, props.menuProps), {
  14639. default: () => [hasList && createVNode(VList, {
  14640. "ref": listRef,
  14641. "selected": selected.value,
  14642. "selectStrategy": props.multiple ? 'independent' : 'single-independent',
  14643. "onMousedown": e => e.preventDefault(),
  14644. "onKeydown": onListKeydown,
  14645. "onFocusin": onFocusin,
  14646. "onFocusout": onFocusout,
  14647. "onScrollPassive": onListScroll,
  14648. "tabindex": "-1",
  14649. "color": props.itemColor ?? props.color
  14650. }, {
  14651. default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? createVNode(VListItem, {
  14652. "title": t(props.noDataText)
  14653. }, null)), createVNode(VVirtualScroll, {
  14654. "renderless": true,
  14655. "items": displayItems.value
  14656. }, {
  14657. default: _ref3 => {
  14658. let {
  14659. item,
  14660. index,
  14661. itemRef
  14662. } = _ref3;
  14663. const itemProps = mergeProps(item.props, {
  14664. ref: itemRef,
  14665. key: index,
  14666. active: highlightFirst.value && index === 0 ? true : undefined,
  14667. onClick: () => select(item)
  14668. });
  14669. return slots.item?.({
  14670. item,
  14671. index,
  14672. props: itemProps
  14673. }) ?? createVNode(VListItem, itemProps, {
  14674. prepend: _ref4 => {
  14675. let {
  14676. isSelected
  14677. } = _ref4;
  14678. return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
  14679. "key": item.value,
  14680. "modelValue": isSelected,
  14681. "ripple": false,
  14682. "tabindex": "-1"
  14683. }, null) : undefined, item.props.prependIcon && createVNode(VIcon, {
  14684. "icon": item.props.prependIcon
  14685. }, null)]);
  14686. },
  14687. title: () => {
  14688. return isPristine.value ? item.title : highlightResult(item.title, getMatches(item)?.title, search.value?.length ?? 0);
  14689. }
  14690. });
  14691. }
  14692. }), slots['append-item']?.()]
  14693. })]
  14694. }), selections.value.map((item, index) => {
  14695. function onChipClose(e) {
  14696. e.stopPropagation();
  14697. e.preventDefault();
  14698. select(item);
  14699. }
  14700. const slotProps = {
  14701. 'onClick:close': onChipClose,
  14702. onMousedown(e) {
  14703. e.preventDefault();
  14704. e.stopPropagation();
  14705. },
  14706. modelValue: true,
  14707. 'onUpdate:modelValue': undefined
  14708. };
  14709. return createVNode("div", {
  14710. "key": item.value,
  14711. "class": ['v-combobox__selection', index === selectionIndex.value && ['v-combobox__selection--selected', textColorClasses.value]],
  14712. "style": index === selectionIndex.value ? textColorStyles.value : {}
  14713. }, [hasChips ? !slots.chip ? createVNode(VChip, mergeProps({
  14714. "key": "chip",
  14715. "closable": props.closableChips,
  14716. "size": "small",
  14717. "text": item.title
  14718. }, slotProps), null) : createVNode(VDefaultsProvider, {
  14719. "key": "chip-defaults",
  14720. "defaults": {
  14721. VChip: {
  14722. closable: props.closableChips,
  14723. size: 'small',
  14724. text: item.title
  14725. }
  14726. }
  14727. }, {
  14728. default: () => [slots.chip?.({
  14729. item,
  14730. index,
  14731. props: slotProps
  14732. })]
  14733. }) : slots.selection?.({
  14734. item,
  14735. index
  14736. }) ?? createVNode("span", {
  14737. "class": "v-combobox__selection-text"
  14738. }, [item.title, props.multiple && index < selections.value.length - 1 && createVNode("span", {
  14739. "class": "v-combobox__selection-comma"
  14740. }, [createTextVNode(",")])])]);
  14741. })]),
  14742. 'append-inner': function () {
  14743. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  14744. args[_key] = arguments[_key];
  14745. }
  14746. return createVNode(Fragment, null, [slots['append-inner']?.(...args), (!props.hideNoData || props.items.length) && props.menuIcon ? createVNode(VIcon, {
  14747. "class": "v-combobox__menu-icon",
  14748. "icon": props.menuIcon,
  14749. "onMousedown": onMousedownMenuIcon,
  14750. "onClick": noop
  14751. }, null) : undefined]);
  14752. }
  14753. });
  14754. });
  14755. return forwardRefs({
  14756. isFocused,
  14757. isPristine,
  14758. menu,
  14759. search,
  14760. selectionIndex,
  14761. filteredItems,
  14762. select
  14763. }, vTextFieldRef);
  14764. }
  14765. });
  14766. // Types
  14767. const makeVDialogProps = propsFactory({
  14768. fullscreen: Boolean,
  14769. retainFocus: {
  14770. type: Boolean,
  14771. default: true
  14772. },
  14773. scrollable: Boolean,
  14774. ...makeVOverlayProps({
  14775. origin: 'center center',
  14776. scrollStrategy: 'block',
  14777. transition: {
  14778. component: VDialogTransition
  14779. },
  14780. zIndex: 2400
  14781. })
  14782. }, 'VDialog');
  14783. const VDialog = genericComponent()({
  14784. name: 'VDialog',
  14785. props: makeVDialogProps(),
  14786. emits: {
  14787. 'update:modelValue': value => true
  14788. },
  14789. setup(props, _ref) {
  14790. let {
  14791. slots
  14792. } = _ref;
  14793. const isActive = useProxiedModel(props, 'modelValue');
  14794. const {
  14795. scopeId
  14796. } = useScopeId();
  14797. const overlay = ref();
  14798. function onFocusin(e) {
  14799. const before = e.relatedTarget;
  14800. const after = e.target;
  14801. if (before !== after && overlay.value?.contentEl &&
  14802. // We're the topmost dialog
  14803. overlay.value?.globalTop &&
  14804. // It isn't the document or the dialog body
  14805. ![document, overlay.value.contentEl].includes(after) &&
  14806. // It isn't inside the dialog body
  14807. !overlay.value.contentEl.contains(after)) {
  14808. const focusable = focusableChildren(overlay.value.contentEl);
  14809. if (!focusable.length) return;
  14810. const firstElement = focusable[0];
  14811. const lastElement = focusable[focusable.length - 1];
  14812. if (before === firstElement) {
  14813. lastElement.focus();
  14814. } else {
  14815. firstElement.focus();
  14816. }
  14817. }
  14818. }
  14819. if (IN_BROWSER) {
  14820. watch(() => isActive.value && props.retainFocus, val => {
  14821. val ? document.addEventListener('focusin', onFocusin) : document.removeEventListener('focusin', onFocusin);
  14822. }, {
  14823. immediate: true
  14824. });
  14825. }
  14826. watch(isActive, async val => {
  14827. await nextTick();
  14828. if (val) {
  14829. overlay.value.contentEl?.focus({
  14830. preventScroll: true
  14831. });
  14832. } else {
  14833. overlay.value.activatorEl?.focus({
  14834. preventScroll: true
  14835. });
  14836. }
  14837. });
  14838. const activatorProps = computed(() => mergeProps({
  14839. 'aria-haspopup': 'dialog',
  14840. 'aria-expanded': String(isActive.value)
  14841. }, props.activatorProps));
  14842. useRender(() => {
  14843. const [overlayProps] = VOverlay.filterProps(props);
  14844. return createVNode(VOverlay, mergeProps({
  14845. "ref": overlay,
  14846. "class": ['v-dialog', {
  14847. 'v-dialog--fullscreen': props.fullscreen,
  14848. 'v-dialog--scrollable': props.scrollable
  14849. }, props.class],
  14850. "style": props.style
  14851. }, overlayProps, {
  14852. "modelValue": isActive.value,
  14853. "onUpdate:modelValue": $event => isActive.value = $event,
  14854. "aria-modal": "true",
  14855. "activatorProps": activatorProps.value,
  14856. "role": "dialog"
  14857. }, scopeId), {
  14858. activator: slots.activator,
  14859. default: function () {
  14860. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  14861. args[_key] = arguments[_key];
  14862. }
  14863. return createVNode(VDefaultsProvider, {
  14864. "root": "VDialog"
  14865. }, {
  14866. default: () => [slots.default?.(...args)]
  14867. });
  14868. }
  14869. });
  14870. });
  14871. return forwardRefs({}, overlay);
  14872. }
  14873. });
  14874. // Types
  14875. const VExpansionPanelSymbol = Symbol.for('vuetify:v-expansion-panel');
  14876. const allowedVariants = ['default', 'accordion', 'inset', 'popout'];
  14877. const makeVExpansionPanelsProps = propsFactory({
  14878. color: String,
  14879. variant: {
  14880. type: String,
  14881. default: 'default',
  14882. validator: v => allowedVariants.includes(v)
  14883. },
  14884. readonly: Boolean,
  14885. ...makeComponentProps(),
  14886. ...makeGroupProps(),
  14887. ...makeTagProps(),
  14888. ...makeThemeProps()
  14889. }, 'VExpansionPanels');
  14890. const VExpansionPanels = genericComponent()({
  14891. name: 'VExpansionPanels',
  14892. props: makeVExpansionPanelsProps(),
  14893. emits: {
  14894. 'update:modelValue': val => true
  14895. },
  14896. setup(props, _ref) {
  14897. let {
  14898. slots
  14899. } = _ref;
  14900. useGroup(props, VExpansionPanelSymbol);
  14901. const {
  14902. themeClasses
  14903. } = provideTheme(props);
  14904. const variantClass = computed(() => props.variant && `v-expansion-panels--variant-${props.variant}`);
  14905. provideDefaults({
  14906. VExpansionPanel: {
  14907. color: toRef(props, 'color')
  14908. },
  14909. VExpansionPanelTitle: {
  14910. readonly: toRef(props, 'readonly')
  14911. }
  14912. });
  14913. useRender(() => createVNode(props.tag, {
  14914. "class": ['v-expansion-panels', themeClasses.value, variantClass.value, props.class],
  14915. "style": props.style
  14916. }, slots));
  14917. return {};
  14918. }
  14919. });
  14920. const makeVExpansionPanelTextProps = propsFactory({
  14921. ...makeComponentProps(),
  14922. ...makeLazyProps()
  14923. }, 'VExpansionPanelText');
  14924. const VExpansionPanelText = genericComponent()({
  14925. name: 'VExpansionPanelText',
  14926. props: makeVExpansionPanelTextProps(),
  14927. setup(props, _ref) {
  14928. let {
  14929. slots
  14930. } = _ref;
  14931. const expansionPanel = inject$1(VExpansionPanelSymbol);
  14932. if (!expansionPanel) throw new Error('[Vuetify] v-expansion-panel-text needs to be placed inside v-expansion-panel');
  14933. const {
  14934. hasContent,
  14935. onAfterLeave
  14936. } = useLazy(props, expansionPanel.isSelected);
  14937. useRender(() => createVNode(VExpandTransition, {
  14938. "onAfterLeave": onAfterLeave
  14939. }, {
  14940. default: () => [withDirectives(createVNode("div", {
  14941. "class": ['v-expansion-panel-text', props.class],
  14942. "style": props.style
  14943. }, [slots.default && hasContent.value && createVNode("div", {
  14944. "class": "v-expansion-panel-text__wrapper"
  14945. }, [slots.default?.()])]), [[vShow, expansionPanel.isSelected.value]])]
  14946. }));
  14947. return {};
  14948. }
  14949. });
  14950. // Types
  14951. const makeVExpansionPanelTitleProps = propsFactory({
  14952. color: String,
  14953. expandIcon: {
  14954. type: IconValue,
  14955. default: '$expand'
  14956. },
  14957. collapseIcon: {
  14958. type: IconValue,
  14959. default: '$collapse'
  14960. },
  14961. hideActions: Boolean,
  14962. ripple: {
  14963. type: [Boolean, Object],
  14964. default: false
  14965. },
  14966. readonly: Boolean,
  14967. ...makeComponentProps()
  14968. }, 'VExpansionPanelTitle');
  14969. const VExpansionPanelTitle = genericComponent()({
  14970. name: 'VExpansionPanelTitle',
  14971. directives: {
  14972. Ripple
  14973. },
  14974. props: makeVExpansionPanelTitleProps(),
  14975. setup(props, _ref) {
  14976. let {
  14977. slots
  14978. } = _ref;
  14979. const expansionPanel = inject$1(VExpansionPanelSymbol);
  14980. if (!expansionPanel) throw new Error('[Vuetify] v-expansion-panel-title needs to be placed inside v-expansion-panel');
  14981. const {
  14982. backgroundColorClasses,
  14983. backgroundColorStyles
  14984. } = useBackgroundColor(props, 'color');
  14985. const slotProps = computed(() => ({
  14986. collapseIcon: props.collapseIcon,
  14987. disabled: expansionPanel.disabled.value,
  14988. expanded: expansionPanel.isSelected.value,
  14989. expandIcon: props.expandIcon,
  14990. readonly: props.readonly
  14991. }));
  14992. useRender(() => withDirectives(createVNode("button", {
  14993. "class": ['v-expansion-panel-title', {
  14994. 'v-expansion-panel-title--active': expansionPanel.isSelected.value
  14995. }, backgroundColorClasses.value, props.class],
  14996. "style": [backgroundColorStyles.value, props.style],
  14997. "type": "button",
  14998. "tabindex": expansionPanel.disabled.value ? -1 : undefined,
  14999. "disabled": expansionPanel.disabled.value,
  15000. "aria-expanded": expansionPanel.isSelected.value,
  15001. "onClick": !props.readonly ? expansionPanel.toggle : undefined
  15002. }, [createVNode("span", {
  15003. "class": "v-expansion-panel-title__overlay"
  15004. }, null), slots.default?.(slotProps.value), !props.hideActions && createVNode("span", {
  15005. "class": "v-expansion-panel-title__icon"
  15006. }, [slots.actions ? slots.actions(slotProps.value) : createVNode(VIcon, {
  15007. "icon": expansionPanel.isSelected.value ? props.collapseIcon : props.expandIcon
  15008. }, null)])]), [[resolveDirective("ripple"), props.ripple]]));
  15009. return {};
  15010. }
  15011. });
  15012. const makeVExpansionPanelProps = propsFactory({
  15013. title: String,
  15014. text: String,
  15015. bgColor: String,
  15016. ...makeComponentProps(),
  15017. ...makeElevationProps(),
  15018. ...makeGroupItemProps(),
  15019. ...makeLazyProps(),
  15020. ...makeRoundedProps(),
  15021. ...makeTagProps(),
  15022. ...makeVExpansionPanelTitleProps()
  15023. }, 'VExpansionPanel');
  15024. const VExpansionPanel = genericComponent()({
  15025. name: 'VExpansionPanel',
  15026. props: makeVExpansionPanelProps(),
  15027. emits: {
  15028. 'group:selected': val => true
  15029. },
  15030. setup(props, _ref) {
  15031. let {
  15032. slots
  15033. } = _ref;
  15034. const groupItem = useGroupItem(props, VExpansionPanelSymbol);
  15035. const {
  15036. backgroundColorClasses,
  15037. backgroundColorStyles
  15038. } = useBackgroundColor(props, 'bgColor');
  15039. const {
  15040. elevationClasses
  15041. } = useElevation(props);
  15042. const {
  15043. roundedClasses
  15044. } = useRounded(props);
  15045. const isDisabled = computed(() => groupItem?.disabled.value || props.disabled);
  15046. const selectedIndices = computed(() => groupItem.group.items.value.reduce((arr, item, index) => {
  15047. if (groupItem.group.selected.value.includes(item.id)) arr.push(index);
  15048. return arr;
  15049. }, []));
  15050. const isBeforeSelected = computed(() => {
  15051. const index = groupItem.group.items.value.findIndex(item => item.id === groupItem.id);
  15052. return !groupItem.isSelected.value && selectedIndices.value.some(selectedIndex => selectedIndex - index === 1);
  15053. });
  15054. const isAfterSelected = computed(() => {
  15055. const index = groupItem.group.items.value.findIndex(item => item.id === groupItem.id);
  15056. return !groupItem.isSelected.value && selectedIndices.value.some(selectedIndex => selectedIndex - index === -1);
  15057. });
  15058. provide(VExpansionPanelSymbol, groupItem);
  15059. provideDefaults({
  15060. VExpansionPanelText: {
  15061. eager: toRef(props, 'eager')
  15062. }
  15063. });
  15064. useRender(() => {
  15065. const hasText = !!(slots.text || props.text);
  15066. const hasTitle = !!(slots.title || props.title);
  15067. return createVNode(props.tag, {
  15068. "class": ['v-expansion-panel', {
  15069. 'v-expansion-panel--active': groupItem.isSelected.value,
  15070. 'v-expansion-panel--before-active': isBeforeSelected.value,
  15071. 'v-expansion-panel--after-active': isAfterSelected.value,
  15072. 'v-expansion-panel--disabled': isDisabled.value
  15073. }, roundedClasses.value, backgroundColorClasses.value, props.class],
  15074. "style": [backgroundColorStyles.value, props.style]
  15075. }, {
  15076. default: () => [createVNode("div", {
  15077. "class": ['v-expansion-panel__shadow', ...elevationClasses.value]
  15078. }, null), hasTitle && createVNode(VExpansionPanelTitle, {
  15079. "key": "title",
  15080. "collapseIcon": props.collapseIcon,
  15081. "color": props.color,
  15082. "expandIcon": props.expandIcon,
  15083. "hideActions": props.hideActions,
  15084. "ripple": props.ripple
  15085. }, {
  15086. default: () => [slots.title ? slots.title() : props.title]
  15087. }), hasText && createVNode(VExpansionPanelText, {
  15088. "key": "text"
  15089. }, {
  15090. default: () => [slots.text ? slots.text() : props.text]
  15091. }), slots.default?.()]
  15092. });
  15093. });
  15094. return {};
  15095. }
  15096. });
  15097. // Types
  15098. const makeVFileInputProps = propsFactory({
  15099. chips: Boolean,
  15100. counter: Boolean,
  15101. counterSizeString: {
  15102. type: String,
  15103. default: '$vuetify.fileInput.counterSize'
  15104. },
  15105. counterString: {
  15106. type: String,
  15107. default: '$vuetify.fileInput.counter'
  15108. },
  15109. multiple: Boolean,
  15110. showSize: {
  15111. type: [Boolean, Number],
  15112. default: false,
  15113. validator: v => {
  15114. return typeof v === 'boolean' || [1000, 1024].includes(v);
  15115. }
  15116. },
  15117. ...makeVInputProps({
  15118. prependIcon: '$file'
  15119. }),
  15120. modelValue: {
  15121. type: Array,
  15122. default: () => [],
  15123. validator: val => {
  15124. return wrapInArray(val).every(v => v != null && typeof v === 'object');
  15125. }
  15126. },
  15127. ...makeVFieldProps({
  15128. clearable: true
  15129. })
  15130. }, 'VFileInput');
  15131. const VFileInput = genericComponent()({
  15132. name: 'VFileInput',
  15133. inheritAttrs: false,
  15134. props: makeVFileInputProps(),
  15135. emits: {
  15136. 'click:control': e => true,
  15137. 'mousedown:control': e => true,
  15138. 'update:focused': focused => true,
  15139. 'update:modelValue': files => true
  15140. },
  15141. setup(props, _ref) {
  15142. let {
  15143. attrs,
  15144. emit,
  15145. slots
  15146. } = _ref;
  15147. const {
  15148. t
  15149. } = useLocale();
  15150. const model = useProxiedModel(props, 'modelValue');
  15151. const {
  15152. isFocused,
  15153. focus,
  15154. blur
  15155. } = useFocus(props);
  15156. const base = computed(() => typeof props.showSize !== 'boolean' ? props.showSize : undefined);
  15157. const totalBytes = computed(() => (model.value ?? []).reduce((bytes, _ref2) => {
  15158. let {
  15159. size = 0
  15160. } = _ref2;
  15161. return bytes + size;
  15162. }, 0));
  15163. const totalBytesReadable = computed(() => humanReadableFileSize(totalBytes.value, base.value));
  15164. const fileNames = computed(() => (model.value ?? []).map(file => {
  15165. const {
  15166. name = '',
  15167. size = 0
  15168. } = file;
  15169. return !props.showSize ? name : `${name} (${humanReadableFileSize(size, base.value)})`;
  15170. }));
  15171. const counterValue = computed(() => {
  15172. const fileCount = model.value?.length ?? 0;
  15173. if (props.showSize) return t(props.counterSizeString, fileCount, totalBytesReadable.value);else return t(props.counterString, fileCount);
  15174. });
  15175. const vInputRef = ref();
  15176. const vFieldRef = ref();
  15177. const inputRef = ref();
  15178. const isActive = computed(() => isFocused.value || props.active);
  15179. const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant));
  15180. function onFocus() {
  15181. if (inputRef.value !== document.activeElement) {
  15182. inputRef.value?.focus();
  15183. }
  15184. if (!isFocused.value) focus();
  15185. }
  15186. function onClickPrepend(e) {
  15187. onControlClick(e);
  15188. }
  15189. function onControlMousedown(e) {
  15190. emit('mousedown:control', e);
  15191. }
  15192. function onControlClick(e) {
  15193. inputRef.value?.click();
  15194. emit('click:control', e);
  15195. }
  15196. function onClear(e) {
  15197. e.stopPropagation();
  15198. onFocus();
  15199. nextTick(() => {
  15200. model.value = [];
  15201. callEvent(props['onClick:clear'], e);
  15202. });
  15203. }
  15204. watch(model, newValue => {
  15205. const hasModelReset = !Array.isArray(newValue) || !newValue.length;
  15206. if (hasModelReset && inputRef.value) {
  15207. inputRef.value.value = '';
  15208. }
  15209. });
  15210. useRender(() => {
  15211. const hasCounter = !!(slots.counter || props.counter);
  15212. const hasDetails = !!(hasCounter || slots.details);
  15213. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  15214. const [{
  15215. modelValue: _,
  15216. ...inputProps
  15217. }] = VInput.filterProps(props);
  15218. const [fieldProps] = filterFieldProps(props);
  15219. return createVNode(VInput, mergeProps({
  15220. "ref": vInputRef,
  15221. "modelValue": model.value,
  15222. "onUpdate:modelValue": $event => model.value = $event,
  15223. "class": ['v-file-input', {
  15224. 'v-text-field--plain-underlined': isPlainOrUnderlined.value
  15225. }, props.class],
  15226. "style": props.style,
  15227. "onClick:prepend": onClickPrepend
  15228. }, rootAttrs, inputProps, {
  15229. "centerAffix": !isPlainOrUnderlined.value,
  15230. "focused": isFocused.value
  15231. }), {
  15232. ...slots,
  15233. default: _ref3 => {
  15234. let {
  15235. id,
  15236. isDisabled,
  15237. isDirty,
  15238. isReadonly,
  15239. isValid
  15240. } = _ref3;
  15241. return createVNode(VField, mergeProps({
  15242. "ref": vFieldRef,
  15243. "prepend-icon": props.prependIcon,
  15244. "onMousedown": onControlMousedown,
  15245. "onClick": onControlClick,
  15246. "onClick:clear": onClear,
  15247. "onClick:prependInner": props['onClick:prependInner'],
  15248. "onClick:appendInner": props['onClick:appendInner']
  15249. }, fieldProps, {
  15250. "id": id.value,
  15251. "active": isActive.value || isDirty.value,
  15252. "dirty": isDirty.value,
  15253. "disabled": isDisabled.value,
  15254. "focused": isFocused.value,
  15255. "error": isValid.value === false
  15256. }), {
  15257. ...slots,
  15258. default: _ref4 => {
  15259. let {
  15260. props: {
  15261. class: fieldClass,
  15262. ...slotProps
  15263. }
  15264. } = _ref4;
  15265. return createVNode(Fragment, null, [createVNode("input", mergeProps({
  15266. "ref": inputRef,
  15267. "type": "file",
  15268. "readonly": isReadonly.value,
  15269. "disabled": isDisabled.value,
  15270. "multiple": props.multiple,
  15271. "name": props.name,
  15272. "onClick": e => {
  15273. e.stopPropagation();
  15274. if (isReadonly.value) e.preventDefault();
  15275. onFocus();
  15276. },
  15277. "onChange": e => {
  15278. if (!e.target) return;
  15279. const target = e.target;
  15280. model.value = [...(target.files ?? [])];
  15281. },
  15282. "onFocus": onFocus,
  15283. "onBlur": blur
  15284. }, slotProps, inputAttrs), null), createVNode("div", {
  15285. "class": fieldClass
  15286. }, [!!model.value?.length && (slots.selection ? slots.selection({
  15287. fileNames: fileNames.value,
  15288. totalBytes: totalBytes.value,
  15289. totalBytesReadable: totalBytesReadable.value
  15290. }) : props.chips ? fileNames.value.map(text => createVNode(VChip, {
  15291. "key": text,
  15292. "size": "small",
  15293. "color": props.color
  15294. }, {
  15295. default: () => [text]
  15296. })) : fileNames.value.join(', '))])]);
  15297. }
  15298. });
  15299. },
  15300. details: hasDetails ? slotProps => createVNode(Fragment, null, [slots.details?.(slotProps), hasCounter && createVNode(Fragment, null, [createVNode("span", null, null), createVNode(VCounter, {
  15301. "active": !!model.value?.length,
  15302. "value": counterValue.value
  15303. }, slots.counter)])]) : undefined
  15304. });
  15305. });
  15306. return forwardRefs({}, vInputRef, vFieldRef, inputRef);
  15307. }
  15308. });
  15309. const makeVFooterProps = propsFactory({
  15310. app: Boolean,
  15311. color: String,
  15312. height: {
  15313. type: [Number, String],
  15314. default: 'auto'
  15315. },
  15316. ...makeBorderProps(),
  15317. ...makeComponentProps(),
  15318. ...makeElevationProps(),
  15319. ...makeLayoutItemProps(),
  15320. ...makeRoundedProps(),
  15321. ...makeTagProps({
  15322. tag: 'footer'
  15323. }),
  15324. ...makeThemeProps()
  15325. }, 'VFooter');
  15326. const VFooter = genericComponent()({
  15327. name: 'VFooter',
  15328. props: makeVFooterProps(),
  15329. setup(props, _ref) {
  15330. let {
  15331. slots
  15332. } = _ref;
  15333. const {
  15334. themeClasses
  15335. } = provideTheme(props);
  15336. const {
  15337. backgroundColorClasses,
  15338. backgroundColorStyles
  15339. } = useBackgroundColor(toRef(props, 'color'));
  15340. const {
  15341. borderClasses
  15342. } = useBorder(props);
  15343. const {
  15344. elevationClasses
  15345. } = useElevation(props);
  15346. const {
  15347. roundedClasses
  15348. } = useRounded(props);
  15349. const autoHeight = shallowRef(32);
  15350. const {
  15351. resizeRef
  15352. } = useResizeObserver(entries => {
  15353. if (!entries.length) return;
  15354. autoHeight.value = entries[0].target.clientHeight;
  15355. });
  15356. const height = computed(() => props.height === 'auto' ? autoHeight.value : parseInt(props.height, 10));
  15357. const {
  15358. layoutItemStyles
  15359. } = useLayoutItem({
  15360. id: props.name,
  15361. order: computed(() => parseInt(props.order, 10)),
  15362. position: computed(() => 'bottom'),
  15363. layoutSize: height,
  15364. elementSize: computed(() => props.height === 'auto' ? undefined : height.value),
  15365. active: computed(() => props.app),
  15366. absolute: toRef(props, 'absolute')
  15367. });
  15368. useRender(() => createVNode(props.tag, {
  15369. "ref": resizeRef,
  15370. "class": ['v-footer', themeClasses.value, backgroundColorClasses.value, borderClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  15371. "style": [backgroundColorStyles.value, props.app ? layoutItemStyles.value : {
  15372. height: convertToUnit(props.height)
  15373. }, props.style]
  15374. }, slots));
  15375. return {};
  15376. }
  15377. });
  15378. // Types
  15379. const makeVFormProps = propsFactory({
  15380. ...makeComponentProps(),
  15381. ...makeFormProps()
  15382. }, 'VForm');
  15383. const VForm = genericComponent()({
  15384. name: 'VForm',
  15385. props: makeVFormProps(),
  15386. emits: {
  15387. 'update:modelValue': val => true,
  15388. submit: e => true
  15389. },
  15390. setup(props, _ref) {
  15391. let {
  15392. slots,
  15393. emit
  15394. } = _ref;
  15395. const form = createForm(props);
  15396. const formRef = ref();
  15397. function onReset(e) {
  15398. e.preventDefault();
  15399. form.reset();
  15400. }
  15401. function onSubmit(_e) {
  15402. const e = _e;
  15403. const ready = form.validate();
  15404. e.then = ready.then.bind(ready);
  15405. e.catch = ready.catch.bind(ready);
  15406. e.finally = ready.finally.bind(ready);
  15407. emit('submit', e);
  15408. if (!e.defaultPrevented) {
  15409. ready.then(_ref2 => {
  15410. let {
  15411. valid
  15412. } = _ref2;
  15413. if (valid) {
  15414. formRef.value?.submit();
  15415. }
  15416. });
  15417. }
  15418. e.preventDefault();
  15419. }
  15420. useRender(() => createVNode("form", {
  15421. "ref": formRef,
  15422. "class": ['v-form', props.class],
  15423. "style": props.style,
  15424. "novalidate": true,
  15425. "onReset": onReset,
  15426. "onSubmit": onSubmit
  15427. }, [slots.default?.(form)]));
  15428. return forwardRefs(form, formRef);
  15429. }
  15430. });
  15431. const makeVContainerProps = propsFactory({
  15432. fluid: {
  15433. type: Boolean,
  15434. default: false
  15435. },
  15436. ...makeComponentProps(),
  15437. ...makeTagProps()
  15438. }, 'VContainer');
  15439. const VContainer = genericComponent()({
  15440. name: 'VContainer',
  15441. props: makeVContainerProps(),
  15442. setup(props, _ref) {
  15443. let {
  15444. slots
  15445. } = _ref;
  15446. const {
  15447. rtlClasses
  15448. } = useRtl();
  15449. useRender(() => createVNode(props.tag, {
  15450. "class": ['v-container', {
  15451. 'v-container--fluid': props.fluid
  15452. }, rtlClasses.value, props.class],
  15453. "style": props.style
  15454. }, slots));
  15455. return {};
  15456. }
  15457. });
  15458. // Styles
  15459. // Types
  15460. const breakpointProps = (() => {
  15461. return breakpoints.reduce((props, val) => {
  15462. props[val] = {
  15463. type: [Boolean, String, Number],
  15464. default: false
  15465. };
  15466. return props;
  15467. }, {});
  15468. })();
  15469. const offsetProps = (() => {
  15470. return breakpoints.reduce((props, val) => {
  15471. const offsetKey = 'offset' + capitalize(val);
  15472. props[offsetKey] = {
  15473. type: [String, Number],
  15474. default: null
  15475. };
  15476. return props;
  15477. }, {});
  15478. })();
  15479. const orderProps = (() => {
  15480. return breakpoints.reduce((props, val) => {
  15481. const orderKey = 'order' + capitalize(val);
  15482. props[orderKey] = {
  15483. type: [String, Number],
  15484. default: null
  15485. };
  15486. return props;
  15487. }, {});
  15488. })();
  15489. const propMap$1 = {
  15490. col: Object.keys(breakpointProps),
  15491. offset: Object.keys(offsetProps),
  15492. order: Object.keys(orderProps)
  15493. };
  15494. function breakpointClass$1(type, prop, val) {
  15495. let className = type;
  15496. if (val == null || val === false) {
  15497. return undefined;
  15498. }
  15499. if (prop) {
  15500. const breakpoint = prop.replace(type, '');
  15501. className += `-${breakpoint}`;
  15502. }
  15503. if (type === 'col') {
  15504. className = 'v-' + className;
  15505. }
  15506. // Handling the boolean style prop when accepting [Boolean, String, Number]
  15507. // means Vue will not convert <v-col sm></v-col> to sm: true for us.
  15508. // Since the default is false, an empty string indicates the prop's presence.
  15509. if (type === 'col' && (val === '' || val === true)) {
  15510. // .v-col-md
  15511. return className.toLowerCase();
  15512. }
  15513. // .order-md-6
  15514. className += `-${val}`;
  15515. return className.toLowerCase();
  15516. }
  15517. const ALIGN_SELF_VALUES = ['auto', 'start', 'end', 'center', 'baseline', 'stretch'];
  15518. const makeVColProps = propsFactory({
  15519. cols: {
  15520. type: [Boolean, String, Number],
  15521. default: false
  15522. },
  15523. ...breakpointProps,
  15524. offset: {
  15525. type: [String, Number],
  15526. default: null
  15527. },
  15528. ...offsetProps,
  15529. order: {
  15530. type: [String, Number],
  15531. default: null
  15532. },
  15533. ...orderProps,
  15534. alignSelf: {
  15535. type: String,
  15536. default: null,
  15537. validator: str => ALIGN_SELF_VALUES.includes(str)
  15538. },
  15539. ...makeComponentProps(),
  15540. ...makeTagProps()
  15541. }, 'VCol');
  15542. const VCol = genericComponent()({
  15543. name: 'VCol',
  15544. props: makeVColProps(),
  15545. setup(props, _ref) {
  15546. let {
  15547. slots
  15548. } = _ref;
  15549. const classes = computed(() => {
  15550. const classList = [];
  15551. // Loop through `col`, `offset`, `order` breakpoint props
  15552. let type;
  15553. for (type in propMap$1) {
  15554. propMap$1[type].forEach(prop => {
  15555. const value = props[prop];
  15556. const className = breakpointClass$1(type, prop, value);
  15557. if (className) classList.push(className);
  15558. });
  15559. }
  15560. const hasColClasses = classList.some(className => className.startsWith('v-col-'));
  15561. classList.push({
  15562. // Default to .v-col if no other col-{bp}-* classes generated nor `cols` specified.
  15563. 'v-col': !hasColClasses || !props.cols,
  15564. [`v-col-${props.cols}`]: props.cols,
  15565. [`offset-${props.offset}`]: props.offset,
  15566. [`order-${props.order}`]: props.order,
  15567. [`align-self-${props.alignSelf}`]: props.alignSelf
  15568. });
  15569. return classList;
  15570. });
  15571. return () => h(props.tag, {
  15572. class: [classes.value, props.class],
  15573. style: props.style
  15574. }, slots.default?.());
  15575. }
  15576. });
  15577. // Styles
  15578. // Types
  15579. const ALIGNMENT = ['start', 'end', 'center'];
  15580. const SPACE = ['space-between', 'space-around', 'space-evenly'];
  15581. function makeRowProps(prefix, def) {
  15582. return breakpoints.reduce((props, val) => {
  15583. const prefixKey = prefix + capitalize(val);
  15584. props[prefixKey] = def();
  15585. return props;
  15586. }, {});
  15587. }
  15588. const ALIGN_VALUES = [...ALIGNMENT, 'baseline', 'stretch'];
  15589. const alignValidator = str => ALIGN_VALUES.includes(str);
  15590. const alignProps = makeRowProps('align', () => ({
  15591. type: String,
  15592. default: null,
  15593. validator: alignValidator
  15594. }));
  15595. const JUSTIFY_VALUES = [...ALIGNMENT, ...SPACE];
  15596. const justifyValidator = str => JUSTIFY_VALUES.includes(str);
  15597. const justifyProps = makeRowProps('justify', () => ({
  15598. type: String,
  15599. default: null,
  15600. validator: justifyValidator
  15601. }));
  15602. const ALIGN_CONTENT_VALUES = [...ALIGNMENT, ...SPACE, 'stretch'];
  15603. const alignContentValidator = str => ALIGN_CONTENT_VALUES.includes(str);
  15604. const alignContentProps = makeRowProps('alignContent', () => ({
  15605. type: String,
  15606. default: null,
  15607. validator: alignContentValidator
  15608. }));
  15609. const propMap = {
  15610. align: Object.keys(alignProps),
  15611. justify: Object.keys(justifyProps),
  15612. alignContent: Object.keys(alignContentProps)
  15613. };
  15614. const classMap = {
  15615. align: 'align',
  15616. justify: 'justify',
  15617. alignContent: 'align-content'
  15618. };
  15619. function breakpointClass(type, prop, val) {
  15620. let className = classMap[type];
  15621. if (val == null) {
  15622. return undefined;
  15623. }
  15624. if (prop) {
  15625. // alignSm -> Sm
  15626. const breakpoint = prop.replace(type, '');
  15627. className += `-${breakpoint}`;
  15628. }
  15629. // .align-items-sm-center
  15630. className += `-${val}`;
  15631. return className.toLowerCase();
  15632. }
  15633. const makeVRowProps = propsFactory({
  15634. dense: Boolean,
  15635. noGutters: Boolean,
  15636. align: {
  15637. type: String,
  15638. default: null,
  15639. validator: alignValidator
  15640. },
  15641. ...alignProps,
  15642. justify: {
  15643. type: String,
  15644. default: null,
  15645. validator: justifyValidator
  15646. },
  15647. ...justifyProps,
  15648. alignContent: {
  15649. type: String,
  15650. default: null,
  15651. validator: alignContentValidator
  15652. },
  15653. ...alignContentProps,
  15654. ...makeComponentProps(),
  15655. ...makeTagProps()
  15656. }, 'VRow');
  15657. const VRow = genericComponent()({
  15658. name: 'VRow',
  15659. props: makeVRowProps(),
  15660. setup(props, _ref) {
  15661. let {
  15662. slots
  15663. } = _ref;
  15664. const classes = computed(() => {
  15665. const classList = [];
  15666. // Loop through `align`, `justify`, `alignContent` breakpoint props
  15667. let type;
  15668. for (type in propMap) {
  15669. propMap[type].forEach(prop => {
  15670. const value = props[prop];
  15671. const className = breakpointClass(type, prop, value);
  15672. if (className) classList.push(className);
  15673. });
  15674. }
  15675. classList.push({
  15676. 'v-row--no-gutters': props.noGutters,
  15677. 'v-row--dense': props.dense,
  15678. [`align-${props.align}`]: props.align,
  15679. [`justify-${props.justify}`]: props.justify,
  15680. [`align-content-${props.alignContent}`]: props.alignContent
  15681. });
  15682. return classList;
  15683. });
  15684. return () => h(props.tag, {
  15685. class: ['v-row', classes.value, props.class],
  15686. style: props.style
  15687. }, slots.default?.());
  15688. }
  15689. });
  15690. // Utilities
  15691. const VSpacer = createSimpleFunctional('flex-grow-1', 'div', 'VSpacer');
  15692. // Composables
  15693. const makeVHoverProps = propsFactory({
  15694. disabled: Boolean,
  15695. modelValue: {
  15696. type: Boolean,
  15697. default: undefined
  15698. },
  15699. ...makeDelayProps()
  15700. }, 'VHover');
  15701. const VHover = genericComponent()({
  15702. name: 'VHover',
  15703. props: makeVHoverProps(),
  15704. emits: {
  15705. 'update:modelValue': value => true
  15706. },
  15707. setup(props, _ref) {
  15708. let {
  15709. slots
  15710. } = _ref;
  15711. const isHovering = useProxiedModel(props, 'modelValue');
  15712. const {
  15713. runOpenDelay,
  15714. runCloseDelay
  15715. } = useDelay(props, value => !props.disabled && (isHovering.value = value));
  15716. return () => slots.default?.({
  15717. isHovering: isHovering.value,
  15718. props: {
  15719. onMouseenter: runOpenDelay,
  15720. onMouseleave: runCloseDelay
  15721. }
  15722. });
  15723. }
  15724. });
  15725. const VItemGroupSymbol = Symbol.for('vuetify:v-item-group');
  15726. const makeVItemGroupProps = propsFactory({
  15727. ...makeComponentProps(),
  15728. ...makeGroupProps({
  15729. selectedClass: 'v-item--selected'
  15730. }),
  15731. ...makeTagProps(),
  15732. ...makeThemeProps()
  15733. }, 'VItemGroup');
  15734. const VItemGroup = genericComponent()({
  15735. name: 'VItemGroup',
  15736. props: makeVItemGroupProps(),
  15737. emits: {
  15738. 'update:modelValue': value => true
  15739. },
  15740. setup(props, _ref) {
  15741. let {
  15742. slots
  15743. } = _ref;
  15744. const {
  15745. themeClasses
  15746. } = provideTheme(props);
  15747. const {
  15748. isSelected,
  15749. select,
  15750. next,
  15751. prev,
  15752. selected
  15753. } = useGroup(props, VItemGroupSymbol);
  15754. return () => createVNode(props.tag, {
  15755. "class": ['v-item-group', themeClasses.value, props.class],
  15756. "style": props.style
  15757. }, {
  15758. default: () => [slots.default?.({
  15759. isSelected,
  15760. select,
  15761. next,
  15762. prev,
  15763. selected: selected.value
  15764. })]
  15765. });
  15766. }
  15767. });
  15768. // Composables
  15769. const VItem = genericComponent()({
  15770. name: 'VItem',
  15771. props: makeGroupItemProps(),
  15772. emits: {
  15773. 'group:selected': val => true
  15774. },
  15775. setup(props, _ref) {
  15776. let {
  15777. slots
  15778. } = _ref;
  15779. const {
  15780. isSelected,
  15781. select,
  15782. toggle,
  15783. selectedClass,
  15784. value,
  15785. disabled
  15786. } = useGroupItem(props, VItemGroupSymbol);
  15787. return () => slots.default?.({
  15788. isSelected: isSelected.value,
  15789. selectedClass: selectedClass.value,
  15790. select,
  15791. toggle,
  15792. value: value.value,
  15793. disabled: disabled.value
  15794. });
  15795. }
  15796. });
  15797. // Styles
  15798. const VKbd = createSimpleFunctional('v-kbd');
  15799. const makeVLayoutProps = propsFactory({
  15800. ...makeComponentProps(),
  15801. ...makeLayoutProps()
  15802. }, 'VLayout');
  15803. const VLayout = genericComponent()({
  15804. name: 'VLayout',
  15805. props: makeVLayoutProps(),
  15806. setup(props, _ref) {
  15807. let {
  15808. slots
  15809. } = _ref;
  15810. const {
  15811. layoutClasses,
  15812. layoutStyles,
  15813. getLayoutItem,
  15814. items,
  15815. layoutRef
  15816. } = createLayout(props);
  15817. useRender(() => createVNode("div", {
  15818. "ref": layoutRef,
  15819. "class": [layoutClasses.value, props.class],
  15820. "style": [layoutStyles.value, props.style]
  15821. }, [slots.default?.()]));
  15822. return {
  15823. getLayoutItem,
  15824. items
  15825. };
  15826. }
  15827. });
  15828. // Types
  15829. const makeVLayoutItemProps = propsFactory({
  15830. position: {
  15831. type: String,
  15832. required: true
  15833. },
  15834. size: {
  15835. type: [Number, String],
  15836. default: 300
  15837. },
  15838. modelValue: Boolean,
  15839. ...makeComponentProps(),
  15840. ...makeLayoutItemProps()
  15841. }, 'VLayoutItem');
  15842. const VLayoutItem = genericComponent()({
  15843. name: 'VLayoutItem',
  15844. props: makeVLayoutItemProps(),
  15845. setup(props, _ref) {
  15846. let {
  15847. slots
  15848. } = _ref;
  15849. const {
  15850. layoutItemStyles
  15851. } = useLayoutItem({
  15852. id: props.name,
  15853. order: computed(() => parseInt(props.order, 10)),
  15854. position: toRef(props, 'position'),
  15855. elementSize: toRef(props, 'size'),
  15856. layoutSize: toRef(props, 'size'),
  15857. active: toRef(props, 'modelValue'),
  15858. absolute: toRef(props, 'absolute')
  15859. });
  15860. return () => createVNode("div", {
  15861. "class": ['v-layout-item', props.class],
  15862. "style": [layoutItemStyles.value, props.style]
  15863. }, [slots.default?.()]);
  15864. }
  15865. });
  15866. // Types
  15867. const makeVLazyProps = propsFactory({
  15868. modelValue: Boolean,
  15869. options: {
  15870. type: Object,
  15871. // For more information on types, navigate to:
  15872. // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
  15873. default: () => ({
  15874. root: undefined,
  15875. rootMargin: undefined,
  15876. threshold: undefined
  15877. })
  15878. },
  15879. ...makeComponentProps(),
  15880. ...makeDimensionProps(),
  15881. ...makeTagProps(),
  15882. ...makeTransitionProps({
  15883. transition: 'fade-transition'
  15884. })
  15885. }, 'VLazy');
  15886. const VLazy = genericComponent()({
  15887. name: 'VLazy',
  15888. directives: {
  15889. intersect: Intersect
  15890. },
  15891. props: makeVLazyProps(),
  15892. emits: {
  15893. 'update:modelValue': value => true
  15894. },
  15895. setup(props, _ref) {
  15896. let {
  15897. slots
  15898. } = _ref;
  15899. const {
  15900. dimensionStyles
  15901. } = useDimension(props);
  15902. const isActive = useProxiedModel(props, 'modelValue');
  15903. function onIntersect(isIntersecting) {
  15904. if (isActive.value) return;
  15905. isActive.value = isIntersecting;
  15906. }
  15907. useRender(() => withDirectives(createVNode(props.tag, {
  15908. "class": ['v-lazy', props.class],
  15909. "style": [dimensionStyles.value, props.style]
  15910. }, {
  15911. default: () => [isActive.value && createVNode(MaybeTransition, {
  15912. "transition": props.transition,
  15913. "appear": true
  15914. }, {
  15915. default: () => [slots.default?.()]
  15916. })]
  15917. }), [[resolveDirective("intersect"), {
  15918. handler: onIntersect,
  15919. options: props.options
  15920. }, null]]));
  15921. return {};
  15922. }
  15923. });
  15924. const makeVLocaleProviderProps = propsFactory({
  15925. locale: String,
  15926. fallbackLocale: String,
  15927. messages: Object,
  15928. rtl: {
  15929. type: Boolean,
  15930. default: undefined
  15931. },
  15932. ...makeComponentProps()
  15933. }, 'VLocaleProvider');
  15934. const VLocaleProvider = genericComponent()({
  15935. name: 'VLocaleProvider',
  15936. props: makeVLocaleProviderProps(),
  15937. setup(props, _ref) {
  15938. let {
  15939. slots
  15940. } = _ref;
  15941. const {
  15942. rtlClasses
  15943. } = provideLocale(props);
  15944. useRender(() => createVNode("div", {
  15945. "class": ['v-locale-provider', rtlClasses.value, props.class],
  15946. "style": props.style
  15947. }, [slots.default?.()]));
  15948. return {};
  15949. }
  15950. });
  15951. const makeVMainProps = propsFactory({
  15952. scrollable: Boolean,
  15953. ...makeComponentProps(),
  15954. ...makeTagProps({
  15955. tag: 'main'
  15956. })
  15957. }, 'VMain');
  15958. const VMain = genericComponent()({
  15959. name: 'VMain',
  15960. props: makeVMainProps(),
  15961. setup(props, _ref) {
  15962. let {
  15963. slots
  15964. } = _ref;
  15965. const {
  15966. mainStyles
  15967. } = useLayout();
  15968. const {
  15969. ssrBootStyles
  15970. } = useSsrBoot();
  15971. useRender(() => createVNode(props.tag, {
  15972. "class": ['v-main', {
  15973. 'v-main--scrollable': props.scrollable
  15974. }, props.class],
  15975. "style": [mainStyles.value, ssrBootStyles.value, props.style]
  15976. }, {
  15977. default: () => [props.scrollable ? createVNode("div", {
  15978. "class": "v-main__scroller"
  15979. }, [slots.default?.()]) : slots.default?.()]
  15980. }));
  15981. return {};
  15982. }
  15983. });
  15984. // Utilities
  15985. // Types
  15986. function useSticky(_ref) {
  15987. let {
  15988. rootEl,
  15989. isSticky,
  15990. layoutItemStyles
  15991. } = _ref;
  15992. const isStuck = shallowRef(false);
  15993. const stuckPosition = shallowRef(0);
  15994. const stickyStyles = computed(() => {
  15995. const side = typeof isStuck.value === 'boolean' ? 'top' : isStuck.value;
  15996. return [isSticky.value ? {
  15997. top: 'auto',
  15998. bottom: 'auto',
  15999. height: undefined
  16000. } : undefined, isStuck.value ? {
  16001. [side]: convertToUnit(stuckPosition.value)
  16002. } : {
  16003. top: layoutItemStyles.value.top
  16004. }];
  16005. });
  16006. onMounted(() => {
  16007. watch(isSticky, val => {
  16008. if (val) {
  16009. window.addEventListener('scroll', onScroll, {
  16010. passive: true
  16011. });
  16012. } else {
  16013. window.removeEventListener('scroll', onScroll);
  16014. }
  16015. }, {
  16016. immediate: true
  16017. });
  16018. });
  16019. onBeforeUnmount(() => {
  16020. window.removeEventListener('scroll', onScroll);
  16021. });
  16022. let lastScrollTop = 0;
  16023. function onScroll() {
  16024. const direction = lastScrollTop > window.scrollY ? 'up' : 'down';
  16025. const rect = rootEl.value.getBoundingClientRect();
  16026. const layoutTop = parseFloat(layoutItemStyles.value.top ?? 0);
  16027. const top = window.scrollY - Math.max(0, stuckPosition.value - layoutTop);
  16028. const bottom = rect.height + Math.max(stuckPosition.value, layoutTop) - window.scrollY - window.innerHeight;
  16029. const bodyScroll = parseFloat(getComputedStyle(rootEl.value).getPropertyValue('--v-body-scroll-y')) || 0;
  16030. if (rect.height < window.innerHeight - layoutTop) {
  16031. isStuck.value = 'top';
  16032. stuckPosition.value = layoutTop;
  16033. } else if (direction === 'up' && isStuck.value === 'bottom' || direction === 'down' && isStuck.value === 'top') {
  16034. stuckPosition.value = window.scrollY + rect.top - bodyScroll;
  16035. isStuck.value = true;
  16036. } else if (direction === 'down' && bottom <= 0) {
  16037. stuckPosition.value = 0;
  16038. isStuck.value = 'bottom';
  16039. } else if (direction === 'up' && top <= 0) {
  16040. if (!bodyScroll) {
  16041. stuckPosition.value = rect.top + top;
  16042. isStuck.value = 'top';
  16043. } else if (isStuck.value !== 'top') {
  16044. stuckPosition.value = -top + bodyScroll + layoutTop;
  16045. isStuck.value = 'top';
  16046. }
  16047. }
  16048. lastScrollTop = window.scrollY;
  16049. }
  16050. return {
  16051. isStuck,
  16052. stickyStyles
  16053. };
  16054. }
  16055. // Utilities
  16056. const HORIZON = 100; // ms
  16057. const HISTORY = 20; // number of samples to keep
  16058. /** @see https://android.googlesource.com/platform/frameworks/native/+/master/libs/input/VelocityTracker.cpp */
  16059. function kineticEnergyToVelocity(work) {
  16060. const sqrt2 = 1.41421356237;
  16061. return (work < 0 ? -1.0 : 1.0) * Math.sqrt(Math.abs(work)) * sqrt2;
  16062. }
  16063. /**
  16064. * Returns pointer velocity in px/s
  16065. */
  16066. function calculateImpulseVelocity(samples) {
  16067. // The input should be in reversed time order (most recent sample at index i=0)
  16068. if (samples.length < 2) {
  16069. // if 0 or 1 points, velocity is zero
  16070. return 0;
  16071. }
  16072. // if (samples[1].t > samples[0].t) {
  16073. // // Algorithm will still work, but not perfectly
  16074. // consoleWarn('Samples provided to calculateImpulseVelocity in the wrong order')
  16075. // }
  16076. if (samples.length === 2) {
  16077. // if 2 points, basic linear calculation
  16078. if (samples[1].t === samples[0].t) {
  16079. // consoleWarn(`Events have identical time stamps t=${samples[0].t}, setting velocity = 0`)
  16080. return 0;
  16081. }
  16082. return (samples[1].d - samples[0].d) / (samples[1].t - samples[0].t);
  16083. }
  16084. // Guaranteed to have at least 3 points here
  16085. // start with the oldest sample and go forward in time
  16086. let work = 0;
  16087. for (let i = samples.length - 1; i > 0; i--) {
  16088. if (samples[i].t === samples[i - 1].t) {
  16089. // consoleWarn(`Events have identical time stamps t=${samples[i].t}, skipping sample`)
  16090. continue;
  16091. }
  16092. const vprev = kineticEnergyToVelocity(work); // v[i-1]
  16093. const vcurr = (samples[i].d - samples[i - 1].d) / (samples[i].t - samples[i - 1].t); // v[i]
  16094. work += (vcurr - vprev) * Math.abs(vcurr);
  16095. if (i === samples.length - 1) {
  16096. work *= 0.5;
  16097. }
  16098. }
  16099. return kineticEnergyToVelocity(work) * 1000;
  16100. }
  16101. function useVelocity() {
  16102. const touches = {};
  16103. function addMovement(e) {
  16104. Array.from(e.changedTouches).forEach(touch => {
  16105. const samples = touches[touch.identifier] ?? (touches[touch.identifier] = new CircularBuffer(HISTORY));
  16106. samples.push([e.timeStamp, touch]);
  16107. });
  16108. }
  16109. function endTouch(e) {
  16110. Array.from(e.changedTouches).forEach(touch => {
  16111. delete touches[touch.identifier];
  16112. });
  16113. }
  16114. function getVelocity(id) {
  16115. const samples = touches[id]?.values().reverse();
  16116. if (!samples) {
  16117. throw new Error(`No samples for touch id ${id}`);
  16118. }
  16119. const newest = samples[0];
  16120. const x = [];
  16121. const y = [];
  16122. for (const val of samples) {
  16123. if (newest[0] - val[0] > HORIZON) break;
  16124. x.push({
  16125. t: val[0],
  16126. d: val[1].clientX
  16127. });
  16128. y.push({
  16129. t: val[0],
  16130. d: val[1].clientY
  16131. });
  16132. }
  16133. return {
  16134. x: calculateImpulseVelocity(x),
  16135. y: calculateImpulseVelocity(y),
  16136. get direction() {
  16137. const {
  16138. x,
  16139. y
  16140. } = this;
  16141. const [absX, absY] = [Math.abs(x), Math.abs(y)];
  16142. return absX > absY && x >= 0 ? 'right' : absX > absY && x <= 0 ? 'left' : absY > absX && y >= 0 ? 'down' : absY > absX && y <= 0 ? 'up' : oops$1();
  16143. }
  16144. };
  16145. }
  16146. return {
  16147. addMovement,
  16148. endTouch,
  16149. getVelocity
  16150. };
  16151. }
  16152. function oops$1() {
  16153. throw new Error();
  16154. }
  16155. // Composables
  16156. // Types
  16157. function useTouch(_ref) {
  16158. let {
  16159. isActive,
  16160. isTemporary,
  16161. width,
  16162. touchless,
  16163. position
  16164. } = _ref;
  16165. onMounted(() => {
  16166. window.addEventListener('touchstart', onTouchstart, {
  16167. passive: true
  16168. });
  16169. window.addEventListener('touchmove', onTouchmove, {
  16170. passive: false
  16171. });
  16172. window.addEventListener('touchend', onTouchend, {
  16173. passive: true
  16174. });
  16175. });
  16176. onBeforeUnmount(() => {
  16177. window.removeEventListener('touchstart', onTouchstart);
  16178. window.removeEventListener('touchmove', onTouchmove);
  16179. window.removeEventListener('touchend', onTouchend);
  16180. });
  16181. const isHorizontal = computed(() => ['left', 'right'].includes(position.value));
  16182. const {
  16183. addMovement,
  16184. endTouch,
  16185. getVelocity
  16186. } = useVelocity();
  16187. let maybeDragging = false;
  16188. const isDragging = shallowRef(false);
  16189. const dragProgress = shallowRef(0);
  16190. const offset = shallowRef(0);
  16191. let start;
  16192. function getOffset(pos, active) {
  16193. 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);
  16194. }
  16195. function getProgress(pos) {
  16196. let limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  16197. 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();
  16198. return limit ? Math.max(0, Math.min(1, progress)) : progress;
  16199. }
  16200. function onTouchstart(e) {
  16201. if (touchless.value) return;
  16202. const touchX = e.changedTouches[0].clientX;
  16203. const touchY = e.changedTouches[0].clientY;
  16204. const touchZone = 25;
  16205. 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();
  16206. 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());
  16207. if (inTouchZone || inElement || isActive.value && isTemporary.value) {
  16208. maybeDragging = true;
  16209. start = [touchX, touchY];
  16210. offset.value = getOffset(isHorizontal.value ? touchX : touchY, isActive.value);
  16211. dragProgress.value = getProgress(isHorizontal.value ? touchX : touchY);
  16212. endTouch(e);
  16213. addMovement(e);
  16214. }
  16215. }
  16216. function onTouchmove(e) {
  16217. const touchX = e.changedTouches[0].clientX;
  16218. const touchY = e.changedTouches[0].clientY;
  16219. if (maybeDragging) {
  16220. if (!e.cancelable) {
  16221. maybeDragging = false;
  16222. return;
  16223. }
  16224. const dx = Math.abs(touchX - start[0]);
  16225. const dy = Math.abs(touchY - start[1]);
  16226. const thresholdMet = isHorizontal.value ? dx > dy && dx > 3 : dy > dx && dy > 3;
  16227. if (thresholdMet) {
  16228. isDragging.value = true;
  16229. maybeDragging = false;
  16230. } else if ((isHorizontal.value ? dy : dx) > 3) {
  16231. maybeDragging = false;
  16232. }
  16233. }
  16234. if (!isDragging.value) return;
  16235. e.preventDefault();
  16236. addMovement(e);
  16237. const progress = getProgress(isHorizontal.value ? touchX : touchY, false);
  16238. dragProgress.value = Math.max(0, Math.min(1, progress));
  16239. if (progress > 1) {
  16240. offset.value = getOffset(isHorizontal.value ? touchX : touchY, true);
  16241. } else if (progress < 0) {
  16242. offset.value = getOffset(isHorizontal.value ? touchX : touchY, false);
  16243. }
  16244. }
  16245. function onTouchend(e) {
  16246. maybeDragging = false;
  16247. if (!isDragging.value) return;
  16248. addMovement(e);
  16249. isDragging.value = false;
  16250. const velocity = getVelocity(e.changedTouches[0].identifier);
  16251. const vx = Math.abs(velocity.x);
  16252. const vy = Math.abs(velocity.y);
  16253. const thresholdMet = isHorizontal.value ? vx > vy && vx > 400 : vy > vx && vy > 3;
  16254. if (thresholdMet) {
  16255. isActive.value = velocity.direction === ({
  16256. left: 'right',
  16257. right: 'left',
  16258. top: 'down',
  16259. bottom: 'up'
  16260. }[position.value] || oops());
  16261. } else {
  16262. isActive.value = dragProgress.value > 0.5;
  16263. }
  16264. }
  16265. const dragStyles = computed(() => {
  16266. return isDragging.value ? {
  16267. 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(),
  16268. transition: 'none'
  16269. } : undefined;
  16270. });
  16271. return {
  16272. isDragging,
  16273. dragProgress,
  16274. dragStyles
  16275. };
  16276. }
  16277. function oops() {
  16278. throw new Error();
  16279. }
  16280. // Types
  16281. const locations = ['start', 'end', 'left', 'right', 'top', 'bottom'];
  16282. const makeVNavigationDrawerProps = propsFactory({
  16283. color: String,
  16284. disableResizeWatcher: Boolean,
  16285. disableRouteWatcher: Boolean,
  16286. expandOnHover: Boolean,
  16287. floating: Boolean,
  16288. modelValue: {
  16289. type: Boolean,
  16290. default: null
  16291. },
  16292. permanent: Boolean,
  16293. rail: {
  16294. type: Boolean,
  16295. default: null
  16296. },
  16297. railWidth: {
  16298. type: [Number, String],
  16299. default: 56
  16300. },
  16301. scrim: {
  16302. type: [Boolean, String],
  16303. default: true
  16304. },
  16305. image: String,
  16306. temporary: Boolean,
  16307. touchless: Boolean,
  16308. width: {
  16309. type: [Number, String],
  16310. default: 256
  16311. },
  16312. location: {
  16313. type: String,
  16314. default: 'start',
  16315. validator: value => locations.includes(value)
  16316. },
  16317. sticky: Boolean,
  16318. ...makeBorderProps(),
  16319. ...makeComponentProps(),
  16320. ...makeElevationProps(),
  16321. ...makeLayoutItemProps(),
  16322. ...makeRoundedProps(),
  16323. ...makeTagProps({
  16324. tag: 'nav'
  16325. }),
  16326. ...makeThemeProps()
  16327. }, 'VNavigationDrawer');
  16328. const VNavigationDrawer = genericComponent()({
  16329. name: 'VNavigationDrawer',
  16330. props: makeVNavigationDrawerProps(),
  16331. emits: {
  16332. 'update:modelValue': val => true,
  16333. 'update:rail': val => true
  16334. },
  16335. setup(props, _ref) {
  16336. let {
  16337. attrs,
  16338. emit,
  16339. slots
  16340. } = _ref;
  16341. const {
  16342. isRtl
  16343. } = useRtl();
  16344. const {
  16345. themeClasses
  16346. } = provideTheme(props);
  16347. const {
  16348. borderClasses
  16349. } = useBorder(props);
  16350. const {
  16351. backgroundColorClasses,
  16352. backgroundColorStyles
  16353. } = useBackgroundColor(toRef(props, 'color'));
  16354. const {
  16355. elevationClasses
  16356. } = useElevation(props);
  16357. const {
  16358. mobile
  16359. } = useDisplay();
  16360. const {
  16361. roundedClasses
  16362. } = useRounded(props);
  16363. const router = useRouter();
  16364. const isActive = useProxiedModel(props, 'modelValue', null, v => !!v);
  16365. const {
  16366. ssrBootStyles
  16367. } = useSsrBoot();
  16368. const {
  16369. scopeId
  16370. } = useScopeId();
  16371. const rootEl = ref();
  16372. const isHovering = shallowRef(false);
  16373. const width = computed(() => {
  16374. return props.rail && props.expandOnHover && isHovering.value ? Number(props.width) : Number(props.rail ? props.railWidth : props.width);
  16375. });
  16376. const location = computed(() => {
  16377. return toPhysical(props.location, isRtl.value);
  16378. });
  16379. const isTemporary = computed(() => !props.permanent && (mobile.value || props.temporary));
  16380. const isSticky = computed(() => props.sticky && !isTemporary.value && location.value !== 'bottom');
  16381. if (props.expandOnHover && props.rail != null) {
  16382. watch(isHovering, val => emit('update:rail', !val));
  16383. }
  16384. if (!props.disableResizeWatcher) {
  16385. watch(isTemporary, val => !props.permanent && nextTick(() => isActive.value = !val));
  16386. }
  16387. if (!props.disableRouteWatcher && router) {
  16388. watch(router.currentRoute, () => isTemporary.value && (isActive.value = false));
  16389. }
  16390. watch(() => props.permanent, val => {
  16391. if (val) isActive.value = true;
  16392. });
  16393. onBeforeMount(() => {
  16394. if (props.modelValue != null || isTemporary.value) return;
  16395. isActive.value = props.permanent || !mobile.value;
  16396. });
  16397. const {
  16398. isDragging,
  16399. dragProgress,
  16400. dragStyles
  16401. } = useTouch({
  16402. isActive,
  16403. isTemporary,
  16404. width,
  16405. touchless: toRef(props, 'touchless'),
  16406. position: location
  16407. });
  16408. const layoutSize = computed(() => {
  16409. const size = isTemporary.value ? 0 : props.rail && props.expandOnHover ? Number(props.railWidth) : width.value;
  16410. return isDragging.value ? size * dragProgress.value : size;
  16411. });
  16412. const {
  16413. layoutItemStyles,
  16414. layoutItemScrimStyles
  16415. } = useLayoutItem({
  16416. id: props.name,
  16417. order: computed(() => parseInt(props.order, 10)),
  16418. position: location,
  16419. layoutSize,
  16420. elementSize: width,
  16421. active: computed(() => isActive.value || isDragging.value),
  16422. disableTransitions: computed(() => isDragging.value),
  16423. absolute: computed(() =>
  16424. // eslint-disable-next-line @typescript-eslint/no-use-before-define
  16425. props.absolute || isSticky.value && typeof isStuck.value !== 'string')
  16426. });
  16427. const {
  16428. isStuck,
  16429. stickyStyles
  16430. } = useSticky({
  16431. rootEl,
  16432. isSticky,
  16433. layoutItemStyles
  16434. });
  16435. const scrimColor = useBackgroundColor(computed(() => {
  16436. return typeof props.scrim === 'string' ? props.scrim : null;
  16437. }));
  16438. const scrimStyles = computed(() => ({
  16439. ...(isDragging.value ? {
  16440. opacity: dragProgress.value * 0.2,
  16441. transition: 'none'
  16442. } : undefined),
  16443. ...layoutItemScrimStyles.value
  16444. }));
  16445. provideDefaults({
  16446. VList: {
  16447. bgColor: 'transparent'
  16448. }
  16449. });
  16450. function onMouseenter() {
  16451. isHovering.value = true;
  16452. }
  16453. function onMouseleave() {
  16454. isHovering.value = false;
  16455. }
  16456. useRender(() => {
  16457. const hasImage = slots.image || props.image;
  16458. return createVNode(Fragment, null, [createVNode(props.tag, mergeProps({
  16459. "ref": rootEl,
  16460. "onMouseenter": onMouseenter,
  16461. "onMouseleave": onMouseleave,
  16462. "class": ['v-navigation-drawer', `v-navigation-drawer--${location.value}`, {
  16463. 'v-navigation-drawer--expand-on-hover': props.expandOnHover,
  16464. 'v-navigation-drawer--floating': props.floating,
  16465. 'v-navigation-drawer--is-hovering': isHovering.value,
  16466. 'v-navigation-drawer--rail': props.rail,
  16467. 'v-navigation-drawer--temporary': isTemporary.value,
  16468. 'v-navigation-drawer--active': isActive.value,
  16469. 'v-navigation-drawer--sticky': isSticky.value
  16470. }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  16471. "style": [backgroundColorStyles.value, layoutItemStyles.value, dragStyles.value, ssrBootStyles.value, stickyStyles.value, props.style]
  16472. }, scopeId, attrs), {
  16473. default: () => [hasImage && createVNode("div", {
  16474. "key": "image",
  16475. "class": "v-navigation-drawer__img"
  16476. }, [slots.image ? slots.image?.({
  16477. image: props.image
  16478. }) : createVNode("img", {
  16479. "src": props.image,
  16480. "alt": ""
  16481. }, null)]), slots.prepend && createVNode("div", {
  16482. "class": "v-navigation-drawer__prepend"
  16483. }, [slots.prepend?.()]), createVNode("div", {
  16484. "class": "v-navigation-drawer__content"
  16485. }, [slots.default?.()]), slots.append && createVNode("div", {
  16486. "class": "v-navigation-drawer__append"
  16487. }, [slots.append?.()])]
  16488. }), createVNode(Transition, {
  16489. "name": "fade-transition"
  16490. }, {
  16491. default: () => [isTemporary.value && (isDragging.value || isActive.value) && !!props.scrim && createVNode("div", mergeProps({
  16492. "class": ['v-navigation-drawer__scrim', scrimColor.backgroundColorClasses.value],
  16493. "style": [scrimStyles.value, scrimColor.backgroundColorStyles.value],
  16494. "onClick": () => isActive.value = false
  16495. }, scopeId), null)]
  16496. })]);
  16497. });
  16498. return {
  16499. isStuck
  16500. };
  16501. }
  16502. });
  16503. // Composables
  16504. const VNoSsr = defineComponent({
  16505. name: 'VNoSsr',
  16506. setup(_, _ref) {
  16507. let {
  16508. slots
  16509. } = _ref;
  16510. const show = useHydration();
  16511. return () => show.value && slots.default?.();
  16512. }
  16513. });
  16514. // Utilities
  16515. // Types
  16516. function useRefs() {
  16517. const refs = ref([]);
  16518. onBeforeUpdate(() => refs.value = []);
  16519. function updateRef(e, i) {
  16520. refs.value[i] = e;
  16521. }
  16522. return {
  16523. refs,
  16524. updateRef
  16525. };
  16526. }
  16527. // Types
  16528. const makeVPaginationProps = propsFactory({
  16529. activeColor: String,
  16530. start: {
  16531. type: [Number, String],
  16532. default: 1
  16533. },
  16534. modelValue: {
  16535. type: Number,
  16536. default: props => props.start
  16537. },
  16538. disabled: Boolean,
  16539. length: {
  16540. type: [Number, String],
  16541. default: 1,
  16542. validator: val => val % 1 === 0
  16543. },
  16544. totalVisible: [Number, String],
  16545. firstIcon: {
  16546. type: IconValue,
  16547. default: '$first'
  16548. },
  16549. prevIcon: {
  16550. type: IconValue,
  16551. default: '$prev'
  16552. },
  16553. nextIcon: {
  16554. type: IconValue,
  16555. default: '$next'
  16556. },
  16557. lastIcon: {
  16558. type: IconValue,
  16559. default: '$last'
  16560. },
  16561. ariaLabel: {
  16562. type: String,
  16563. default: '$vuetify.pagination.ariaLabel.root'
  16564. },
  16565. pageAriaLabel: {
  16566. type: String,
  16567. default: '$vuetify.pagination.ariaLabel.page'
  16568. },
  16569. currentPageAriaLabel: {
  16570. type: String,
  16571. default: '$vuetify.pagination.ariaLabel.currentPage'
  16572. },
  16573. firstAriaLabel: {
  16574. type: String,
  16575. default: '$vuetify.pagination.ariaLabel.first'
  16576. },
  16577. previousAriaLabel: {
  16578. type: String,
  16579. default: '$vuetify.pagination.ariaLabel.previous'
  16580. },
  16581. nextAriaLabel: {
  16582. type: String,
  16583. default: '$vuetify.pagination.ariaLabel.next'
  16584. },
  16585. lastAriaLabel: {
  16586. type: String,
  16587. default: '$vuetify.pagination.ariaLabel.last'
  16588. },
  16589. ellipsis: {
  16590. type: String,
  16591. default: '...'
  16592. },
  16593. showFirstLastPage: Boolean,
  16594. ...makeBorderProps(),
  16595. ...makeComponentProps(),
  16596. ...makeDensityProps(),
  16597. ...makeElevationProps(),
  16598. ...makeRoundedProps(),
  16599. ...makeSizeProps(),
  16600. ...makeTagProps({
  16601. tag: 'nav'
  16602. }),
  16603. ...makeThemeProps(),
  16604. ...makeVariantProps({
  16605. variant: 'text'
  16606. })
  16607. }, 'VPagination');
  16608. const VPagination = genericComponent()({
  16609. name: 'VPagination',
  16610. props: makeVPaginationProps(),
  16611. emits: {
  16612. 'update:modelValue': value => true,
  16613. first: value => true,
  16614. prev: value => true,
  16615. next: value => true,
  16616. last: value => true
  16617. },
  16618. setup(props, _ref) {
  16619. let {
  16620. slots,
  16621. emit
  16622. } = _ref;
  16623. const page = useProxiedModel(props, 'modelValue');
  16624. const {
  16625. t,
  16626. n
  16627. } = useLocale();
  16628. const {
  16629. isRtl
  16630. } = useRtl();
  16631. const {
  16632. themeClasses
  16633. } = provideTheme(props);
  16634. const {
  16635. width
  16636. } = useDisplay();
  16637. const maxButtons = shallowRef(-1);
  16638. provideDefaults(undefined, {
  16639. scoped: true
  16640. });
  16641. const {
  16642. resizeRef
  16643. } = useResizeObserver(entries => {
  16644. if (!entries.length) return;
  16645. const {
  16646. target,
  16647. contentRect
  16648. } = entries[0];
  16649. const firstItem = target.querySelector('.v-pagination__list > *');
  16650. if (!firstItem) return;
  16651. const totalWidth = contentRect.width;
  16652. const itemWidth = firstItem.offsetWidth + parseFloat(getComputedStyle(firstItem).marginRight) * 2;
  16653. maxButtons.value = getMax(totalWidth, itemWidth);
  16654. });
  16655. const length = computed(() => parseInt(props.length, 10));
  16656. const start = computed(() => parseInt(props.start, 10));
  16657. const totalVisible = computed(() => {
  16658. if (props.totalVisible) return parseInt(props.totalVisible, 10);else if (maxButtons.value >= 0) return maxButtons.value;
  16659. return getMax(width.value, 58);
  16660. });
  16661. function getMax(totalWidth, itemWidth) {
  16662. const minButtons = props.showFirstLastPage ? 5 : 3;
  16663. return Math.max(0, Math.floor(
  16664. // Round to two decimal places to avoid floating point errors
  16665. +((totalWidth - itemWidth * minButtons) / itemWidth).toFixed(2)));
  16666. }
  16667. const range = computed(() => {
  16668. if (length.value <= 0 || isNaN(length.value) || length.value > Number.MAX_SAFE_INTEGER) return [];
  16669. if (totalVisible.value <= 1) return [page.value];
  16670. if (length.value <= totalVisible.value) {
  16671. return createRange(length.value, start.value);
  16672. }
  16673. const even = totalVisible.value % 2 === 0;
  16674. const middle = even ? totalVisible.value / 2 : Math.floor(totalVisible.value / 2);
  16675. const left = even ? middle : middle + 1;
  16676. const right = length.value - middle;
  16677. if (left - page.value >= 0) {
  16678. return [...createRange(Math.max(1, totalVisible.value - 1), start.value), props.ellipsis, length.value];
  16679. } else if (page.value - right >= (even ? 1 : 0)) {
  16680. const rangeLength = totalVisible.value - 1;
  16681. const rangeStart = length.value - rangeLength + start.value;
  16682. return [start.value, props.ellipsis, ...createRange(rangeLength, rangeStart)];
  16683. } else {
  16684. const rangeLength = Math.max(1, totalVisible.value - 3);
  16685. const rangeStart = rangeLength === 1 ? page.value : page.value - Math.ceil(rangeLength / 2) + start.value;
  16686. return [start.value, props.ellipsis, ...createRange(rangeLength, rangeStart), props.ellipsis, length.value];
  16687. }
  16688. });
  16689. // TODO: 'first' | 'prev' | 'next' | 'last' does not work here?
  16690. function setValue(e, value, event) {
  16691. e.preventDefault();
  16692. page.value = value;
  16693. event && emit(event, value);
  16694. }
  16695. const {
  16696. refs,
  16697. updateRef
  16698. } = useRefs();
  16699. provideDefaults({
  16700. VPaginationBtn: {
  16701. color: toRef(props, 'color'),
  16702. border: toRef(props, 'border'),
  16703. density: toRef(props, 'density'),
  16704. size: toRef(props, 'size'),
  16705. variant: toRef(props, 'variant'),
  16706. rounded: toRef(props, 'rounded'),
  16707. elevation: toRef(props, 'elevation')
  16708. }
  16709. });
  16710. const items = computed(() => {
  16711. return range.value.map((item, index) => {
  16712. const ref = e => updateRef(e, index);
  16713. if (typeof item === 'string') {
  16714. return {
  16715. isActive: false,
  16716. key: `ellipsis-${index}`,
  16717. page: item,
  16718. props: {
  16719. ref,
  16720. ellipsis: true,
  16721. icon: true,
  16722. disabled: true
  16723. }
  16724. };
  16725. } else {
  16726. const isActive = item === page.value;
  16727. return {
  16728. isActive,
  16729. key: item,
  16730. page: n(item),
  16731. props: {
  16732. ref,
  16733. ellipsis: false,
  16734. icon: true,
  16735. disabled: !!props.disabled || +props.length < 2,
  16736. color: isActive ? props.activeColor : props.color,
  16737. ariaCurrent: isActive,
  16738. ariaLabel: t(isActive ? props.currentPageAriaLabel : props.pageAriaLabel, item),
  16739. onClick: e => setValue(e, item)
  16740. }
  16741. };
  16742. }
  16743. });
  16744. });
  16745. const controls = computed(() => {
  16746. const prevDisabled = !!props.disabled || page.value <= start.value;
  16747. const nextDisabled = !!props.disabled || page.value >= start.value + length.value - 1;
  16748. return {
  16749. first: props.showFirstLastPage ? {
  16750. icon: isRtl.value ? props.lastIcon : props.firstIcon,
  16751. onClick: e => setValue(e, start.value, 'first'),
  16752. disabled: prevDisabled,
  16753. ariaLabel: t(props.firstAriaLabel),
  16754. ariaDisabled: prevDisabled
  16755. } : undefined,
  16756. prev: {
  16757. icon: isRtl.value ? props.nextIcon : props.prevIcon,
  16758. onClick: e => setValue(e, page.value - 1, 'prev'),
  16759. disabled: prevDisabled,
  16760. ariaLabel: t(props.previousAriaLabel),
  16761. ariaDisabled: prevDisabled
  16762. },
  16763. next: {
  16764. icon: isRtl.value ? props.prevIcon : props.nextIcon,
  16765. onClick: e => setValue(e, page.value + 1, 'next'),
  16766. disabled: nextDisabled,
  16767. ariaLabel: t(props.nextAriaLabel),
  16768. ariaDisabled: nextDisabled
  16769. },
  16770. last: props.showFirstLastPage ? {
  16771. icon: isRtl.value ? props.firstIcon : props.lastIcon,
  16772. onClick: e => setValue(e, start.value + length.value - 1, 'last'),
  16773. disabled: nextDisabled,
  16774. ariaLabel: t(props.lastAriaLabel),
  16775. ariaDisabled: nextDisabled
  16776. } : undefined
  16777. };
  16778. });
  16779. function updateFocus() {
  16780. const currentIndex = page.value - start.value;
  16781. refs.value[currentIndex]?.$el.focus();
  16782. }
  16783. function onKeydown(e) {
  16784. if (e.key === keyValues.left && !props.disabled && page.value > +props.start) {
  16785. page.value = page.value - 1;
  16786. nextTick(updateFocus);
  16787. } else if (e.key === keyValues.right && !props.disabled && page.value < start.value + length.value - 1) {
  16788. page.value = page.value + 1;
  16789. nextTick(updateFocus);
  16790. }
  16791. }
  16792. useRender(() => createVNode(props.tag, {
  16793. "ref": resizeRef,
  16794. "class": ['v-pagination', themeClasses.value, props.class],
  16795. "style": props.style,
  16796. "role": "navigation",
  16797. "aria-label": t(props.ariaLabel),
  16798. "onKeydown": onKeydown,
  16799. "data-test": "v-pagination-root"
  16800. }, {
  16801. default: () => [createVNode("ul", {
  16802. "class": "v-pagination__list"
  16803. }, [props.showFirstLastPage && createVNode("li", {
  16804. "key": "first",
  16805. "class": "v-pagination__first",
  16806. "data-test": "v-pagination-first"
  16807. }, [slots.first ? slots.first(controls.value.first) : createVNode(VBtn, mergeProps({
  16808. "_as": "VPaginationBtn"
  16809. }, controls.value.first), null)]), createVNode("li", {
  16810. "key": "prev",
  16811. "class": "v-pagination__prev",
  16812. "data-test": "v-pagination-prev"
  16813. }, [slots.prev ? slots.prev(controls.value.prev) : createVNode(VBtn, mergeProps({
  16814. "_as": "VPaginationBtn"
  16815. }, controls.value.prev), null)]), items.value.map((item, index) => createVNode("li", {
  16816. "key": item.key,
  16817. "class": ['v-pagination__item', {
  16818. 'v-pagination__item--is-active': item.isActive
  16819. }],
  16820. "data-test": "v-pagination-item"
  16821. }, [slots.item ? slots.item(item) : createVNode(VBtn, mergeProps({
  16822. "_as": "VPaginationBtn"
  16823. }, item.props), {
  16824. default: () => [item.page]
  16825. })])), createVNode("li", {
  16826. "key": "next",
  16827. "class": "v-pagination__next",
  16828. "data-test": "v-pagination-next"
  16829. }, [slots.next ? slots.next(controls.value.next) : createVNode(VBtn, mergeProps({
  16830. "_as": "VPaginationBtn"
  16831. }, controls.value.next), null)]), props.showFirstLastPage && createVNode("li", {
  16832. "key": "last",
  16833. "class": "v-pagination__last",
  16834. "data-test": "v-pagination-last"
  16835. }, [slots.last ? slots.last(controls.value.last) : createVNode(VBtn, mergeProps({
  16836. "_as": "VPaginationBtn"
  16837. }, controls.value.last), null)])])]
  16838. }));
  16839. return {};
  16840. }
  16841. });
  16842. // Types
  16843. function floor(val) {
  16844. return Math.floor(Math.abs(val)) * Math.sign(val);
  16845. }
  16846. const makeVParallaxProps = propsFactory({
  16847. scale: {
  16848. type: [Number, String],
  16849. default: 0.5
  16850. },
  16851. ...makeComponentProps()
  16852. }, 'VParallax');
  16853. const VParallax = genericComponent()({
  16854. name: 'VParallax',
  16855. props: makeVParallaxProps(),
  16856. setup(props, _ref) {
  16857. let {
  16858. slots
  16859. } = _ref;
  16860. const {
  16861. intersectionRef,
  16862. isIntersecting
  16863. } = useIntersectionObserver();
  16864. const {
  16865. resizeRef,
  16866. contentRect
  16867. } = useResizeObserver();
  16868. const {
  16869. height: displayHeight
  16870. } = useDisplay();
  16871. const root = ref();
  16872. watchEffect(() => {
  16873. intersectionRef.value = resizeRef.value = root.value?.$el;
  16874. });
  16875. let scrollParent;
  16876. watch(isIntersecting, val => {
  16877. if (val) {
  16878. scrollParent = getScrollParent(intersectionRef.value);
  16879. scrollParent = scrollParent === document.scrollingElement ? document : scrollParent;
  16880. scrollParent.addEventListener('scroll', onScroll, {
  16881. passive: true
  16882. });
  16883. onScroll();
  16884. } else {
  16885. scrollParent.removeEventListener('scroll', onScroll);
  16886. }
  16887. });
  16888. onBeforeUnmount(() => {
  16889. scrollParent?.removeEventListener('scroll', onScroll);
  16890. });
  16891. watch(displayHeight, onScroll);
  16892. watch(() => contentRect.value?.height, onScroll);
  16893. const scale = computed(() => {
  16894. return 1 - clamp(+props.scale);
  16895. });
  16896. let frame = -1;
  16897. function onScroll() {
  16898. if (!isIntersecting.value) return;
  16899. cancelAnimationFrame(frame);
  16900. frame = requestAnimationFrame(() => {
  16901. const el = (root.value?.$el).querySelector('.v-img__img');
  16902. if (!el) return;
  16903. const scrollHeight = scrollParent instanceof Document ? document.documentElement.clientHeight : scrollParent.clientHeight;
  16904. const scrollPos = scrollParent instanceof Document ? window.scrollY : scrollParent.scrollTop;
  16905. const top = intersectionRef.value.getBoundingClientRect().top + scrollPos;
  16906. const height = contentRect.value.height;
  16907. const center = top + (height - scrollHeight) / 2;
  16908. const translate = floor((scrollPos - center) * scale.value);
  16909. const sizeScale = Math.max(1, (scale.value * (scrollHeight - height) + height) / height);
  16910. el.style.setProperty('transform', `translateY(${translate}px) scale(${sizeScale})`);
  16911. });
  16912. }
  16913. useRender(() => createVNode(VImg, {
  16914. "class": ['v-parallax', {
  16915. 'v-parallax--active': isIntersecting.value
  16916. }, props.class],
  16917. "style": props.style,
  16918. "ref": root,
  16919. "cover": true,
  16920. "onLoadstart": onScroll,
  16921. "onLoad": onScroll
  16922. }, slots));
  16923. return {};
  16924. }
  16925. });
  16926. // Types
  16927. const makeVRadioProps = propsFactory({
  16928. ...makeVSelectionControlProps({
  16929. falseIcon: '$radioOff',
  16930. trueIcon: '$radioOn'
  16931. })
  16932. }, 'VRadio');
  16933. const VRadio = genericComponent()({
  16934. name: 'VRadio',
  16935. props: makeVRadioProps(),
  16936. setup(props, _ref) {
  16937. let {
  16938. slots
  16939. } = _ref;
  16940. useRender(() => createVNode(VSelectionControl, mergeProps(props, {
  16941. "class": ['v-radio', props.class],
  16942. "style": props.style,
  16943. "type": "radio"
  16944. }), slots));
  16945. return {};
  16946. }
  16947. });
  16948. // Types
  16949. const makeVRadioGroupProps = propsFactory({
  16950. height: {
  16951. type: [Number, String],
  16952. default: 'auto'
  16953. },
  16954. ...makeVInputProps(),
  16955. ...omit(makeSelectionControlGroupProps(), ['multiple']),
  16956. trueIcon: {
  16957. type: IconValue,
  16958. default: '$radioOn'
  16959. },
  16960. falseIcon: {
  16961. type: IconValue,
  16962. default: '$radioOff'
  16963. },
  16964. type: {
  16965. type: String,
  16966. default: 'radio'
  16967. }
  16968. }, 'VRadioGroup');
  16969. const VRadioGroup = genericComponent()({
  16970. name: 'VRadioGroup',
  16971. inheritAttrs: false,
  16972. props: makeVRadioGroupProps(),
  16973. emits: {
  16974. 'update:modelValue': val => true
  16975. },
  16976. setup(props, _ref) {
  16977. let {
  16978. attrs,
  16979. slots
  16980. } = _ref;
  16981. const uid = getUid();
  16982. const id = computed(() => props.id || `radio-group-${uid}`);
  16983. const model = useProxiedModel(props, 'modelValue');
  16984. useRender(() => {
  16985. const [inputAttrs, controlAttrs] = filterInputAttrs(attrs);
  16986. const [inputProps, _1] = VInput.filterProps(props);
  16987. const [controlProps, _2] = VSelectionControl.filterProps(props);
  16988. const label = slots.label ? slots.label({
  16989. label: props.label,
  16990. props: {
  16991. for: id.value
  16992. }
  16993. }) : props.label;
  16994. return createVNode(VInput, mergeProps({
  16995. "class": ['v-radio-group', props.class],
  16996. "style": props.style
  16997. }, inputAttrs, inputProps, {
  16998. "modelValue": model.value,
  16999. "onUpdate:modelValue": $event => model.value = $event,
  17000. "id": id.value
  17001. }), {
  17002. ...slots,
  17003. default: _ref2 => {
  17004. let {
  17005. id,
  17006. messagesId,
  17007. isDisabled,
  17008. isReadonly
  17009. } = _ref2;
  17010. return createVNode(Fragment, null, [label && createVNode(VLabel, {
  17011. "id": id.value
  17012. }, {
  17013. default: () => [label]
  17014. }), createVNode(VSelectionControlGroup, mergeProps(controlProps, {
  17015. "id": id.value,
  17016. "aria-describedby": messagesId.value,
  17017. "defaultsTarget": "VRadio",
  17018. "trueIcon": props.trueIcon,
  17019. "falseIcon": props.falseIcon,
  17020. "type": props.type,
  17021. "disabled": isDisabled.value,
  17022. "readonly": isReadonly.value,
  17023. "aria-labelledby": label ? id.value : undefined,
  17024. "multiple": false
  17025. }, controlAttrs, {
  17026. "modelValue": model.value,
  17027. "onUpdate:modelValue": $event => model.value = $event
  17028. }), slots)]);
  17029. }
  17030. });
  17031. });
  17032. return {};
  17033. }
  17034. });
  17035. // Types
  17036. const makeVRangeSliderProps = propsFactory({
  17037. ...makeFocusProps(),
  17038. ...makeVInputProps(),
  17039. ...makeSliderProps(),
  17040. strict: Boolean,
  17041. modelValue: {
  17042. type: Array,
  17043. default: () => [0, 0]
  17044. }
  17045. }, 'VRangeSlider');
  17046. const VRangeSlider = genericComponent()({
  17047. name: 'VRangeSlider',
  17048. props: makeVRangeSliderProps(),
  17049. emits: {
  17050. 'update:focused': value => true,
  17051. 'update:modelValue': value => true,
  17052. end: value => true,
  17053. start: value => true
  17054. },
  17055. setup(props, _ref) {
  17056. let {
  17057. slots,
  17058. emit
  17059. } = _ref;
  17060. const startThumbRef = ref();
  17061. const stopThumbRef = ref();
  17062. const inputRef = ref();
  17063. const {
  17064. rtlClasses
  17065. } = useRtl();
  17066. function getActiveThumb(e) {
  17067. if (!startThumbRef.value || !stopThumbRef.value) return;
  17068. const startOffset = getOffset(e, startThumbRef.value.$el, props.direction);
  17069. const stopOffset = getOffset(e, stopThumbRef.value.$el, props.direction);
  17070. const a = Math.abs(startOffset);
  17071. const b = Math.abs(stopOffset);
  17072. return a < b || a === b && startOffset < 0 ? startThumbRef.value.$el : stopThumbRef.value.$el;
  17073. }
  17074. const steps = useSteps(props);
  17075. const model = useProxiedModel(props, 'modelValue', undefined, arr => {
  17076. if (!arr?.length) return [0, 0];
  17077. return arr.map(value => steps.roundValue(value));
  17078. });
  17079. const {
  17080. activeThumbRef,
  17081. hasLabels,
  17082. max,
  17083. min,
  17084. mousePressed,
  17085. onSliderMousedown,
  17086. onSliderTouchstart,
  17087. position,
  17088. trackContainerRef
  17089. } = useSlider({
  17090. props,
  17091. steps,
  17092. onSliderStart: () => {
  17093. emit('start', model.value);
  17094. },
  17095. onSliderEnd: _ref2 => {
  17096. let {
  17097. value
  17098. } = _ref2;
  17099. const newValue = activeThumbRef.value === startThumbRef.value?.$el ? [value, model.value[1]] : [model.value[0], value];
  17100. if (!props.strict && newValue[0] < newValue[1]) {
  17101. model.value = newValue;
  17102. }
  17103. emit('end', model.value);
  17104. },
  17105. onSliderMove: _ref3 => {
  17106. let {
  17107. value
  17108. } = _ref3;
  17109. const [start, stop] = model.value;
  17110. if (!props.strict && start === stop && start !== min.value) {
  17111. activeThumbRef.value = value > start ? stopThumbRef.value?.$el : startThumbRef.value?.$el;
  17112. activeThumbRef.value?.focus();
  17113. }
  17114. if (activeThumbRef.value === startThumbRef.value?.$el) {
  17115. model.value = [Math.min(value, stop), stop];
  17116. } else {
  17117. model.value = [start, Math.max(start, value)];
  17118. }
  17119. },
  17120. getActiveThumb
  17121. });
  17122. const {
  17123. isFocused,
  17124. focus,
  17125. blur
  17126. } = useFocus(props);
  17127. const trackStart = computed(() => position(model.value[0]));
  17128. const trackStop = computed(() => position(model.value[1]));
  17129. useRender(() => {
  17130. const [inputProps, _] = VInput.filterProps(props);
  17131. const hasPrepend = !!(props.label || slots.label || slots.prepend);
  17132. return createVNode(VInput, mergeProps({
  17133. "class": ['v-slider', 'v-range-slider', {
  17134. 'v-slider--has-labels': !!slots['tick-label'] || hasLabels.value,
  17135. 'v-slider--focused': isFocused.value,
  17136. 'v-slider--pressed': mousePressed.value,
  17137. 'v-slider--disabled': props.disabled
  17138. }, rtlClasses.value, props.class],
  17139. "style": props.style,
  17140. "ref": inputRef
  17141. }, inputProps, {
  17142. "focused": isFocused.value
  17143. }), {
  17144. ...slots,
  17145. prepend: hasPrepend ? slotProps => createVNode(Fragment, null, [slots.label?.(slotProps) ?? props.label ? createVNode(VLabel, {
  17146. "class": "v-slider__label",
  17147. "text": props.label
  17148. }, null) : undefined, slots.prepend?.(slotProps)]) : undefined,
  17149. default: _ref4 => {
  17150. let {
  17151. id,
  17152. messagesId
  17153. } = _ref4;
  17154. return createVNode("div", {
  17155. "class": "v-slider__container",
  17156. "onMousedown": onSliderMousedown,
  17157. "onTouchstartPassive": onSliderTouchstart
  17158. }, [createVNode("input", {
  17159. "id": `${id.value}_start`,
  17160. "name": props.name || id.value,
  17161. "disabled": !!props.disabled,
  17162. "readonly": !!props.readonly,
  17163. "tabindex": "-1",
  17164. "value": model.value[0]
  17165. }, null), createVNode("input", {
  17166. "id": `${id.value}_stop`,
  17167. "name": props.name || id.value,
  17168. "disabled": !!props.disabled,
  17169. "readonly": !!props.readonly,
  17170. "tabindex": "-1",
  17171. "value": model.value[1]
  17172. }, null), createVNode(VSliderTrack, {
  17173. "ref": trackContainerRef,
  17174. "start": trackStart.value,
  17175. "stop": trackStop.value
  17176. }, {
  17177. 'tick-label': slots['tick-label']
  17178. }), createVNode(VSliderThumb, {
  17179. "ref": startThumbRef,
  17180. "aria-describedby": messagesId.value,
  17181. "focused": isFocused && activeThumbRef.value === startThumbRef.value?.$el,
  17182. "modelValue": model.value[0],
  17183. "onUpdate:modelValue": v => model.value = [v, model.value[1]],
  17184. "onFocus": e => {
  17185. focus();
  17186. activeThumbRef.value = startThumbRef.value?.$el;
  17187. // Make sure second thumb is focused if
  17188. // the thumbs are on top of each other
  17189. // and they are both at minimum value
  17190. // but only if focused from outside.
  17191. if (model.value[0] === model.value[1] && model.value[1] === min.value && e.relatedTarget !== stopThumbRef.value?.$el) {
  17192. startThumbRef.value?.$el.blur();
  17193. stopThumbRef.value?.$el.focus();
  17194. }
  17195. },
  17196. "onBlur": () => {
  17197. blur();
  17198. activeThumbRef.value = undefined;
  17199. },
  17200. "min": min.value,
  17201. "max": model.value[1],
  17202. "position": trackStart.value
  17203. }, {
  17204. 'thumb-label': slots['thumb-label']
  17205. }), createVNode(VSliderThumb, {
  17206. "ref": stopThumbRef,
  17207. "aria-describedby": messagesId.value,
  17208. "focused": isFocused && activeThumbRef.value === stopThumbRef.value?.$el,
  17209. "modelValue": model.value[1],
  17210. "onUpdate:modelValue": v => model.value = [model.value[0], v],
  17211. "onFocus": e => {
  17212. focus();
  17213. activeThumbRef.value = stopThumbRef.value?.$el;
  17214. // Make sure first thumb is focused if
  17215. // the thumbs are on top of each other
  17216. // and they are both at maximum value
  17217. // but only if focused from outside.
  17218. if (model.value[0] === model.value[1] && model.value[0] === max.value && e.relatedTarget !== startThumbRef.value?.$el) {
  17219. stopThumbRef.value?.$el.blur();
  17220. startThumbRef.value?.$el.focus();
  17221. }
  17222. },
  17223. "onBlur": () => {
  17224. blur();
  17225. activeThumbRef.value = undefined;
  17226. },
  17227. "min": model.value[0],
  17228. "max": max.value,
  17229. "position": trackStop.value
  17230. }, {
  17231. 'thumb-label': slots['thumb-label']
  17232. })]);
  17233. }
  17234. });
  17235. });
  17236. return {};
  17237. }
  17238. });
  17239. // Types
  17240. const makeVRatingProps = propsFactory({
  17241. name: String,
  17242. itemAriaLabel: {
  17243. type: String,
  17244. default: '$vuetify.rating.ariaLabel.item'
  17245. },
  17246. activeColor: String,
  17247. color: String,
  17248. clearable: Boolean,
  17249. disabled: Boolean,
  17250. emptyIcon: {
  17251. type: IconValue,
  17252. default: '$ratingEmpty'
  17253. },
  17254. fullIcon: {
  17255. type: IconValue,
  17256. default: '$ratingFull'
  17257. },
  17258. halfIncrements: Boolean,
  17259. hover: Boolean,
  17260. length: {
  17261. type: [Number, String],
  17262. default: 5
  17263. },
  17264. readonly: Boolean,
  17265. modelValue: {
  17266. type: [Number, String],
  17267. default: 0
  17268. },
  17269. itemLabels: Array,
  17270. itemLabelPosition: {
  17271. type: String,
  17272. default: 'top',
  17273. validator: v => ['top', 'bottom'].includes(v)
  17274. },
  17275. ripple: Boolean,
  17276. ...makeComponentProps(),
  17277. ...makeDensityProps(),
  17278. ...makeSizeProps(),
  17279. ...makeTagProps(),
  17280. ...makeThemeProps()
  17281. }, 'VRating');
  17282. const VRating = genericComponent()({
  17283. name: 'VRating',
  17284. props: makeVRatingProps(),
  17285. emits: {
  17286. 'update:modelValue': value => true
  17287. },
  17288. setup(props, _ref) {
  17289. let {
  17290. slots
  17291. } = _ref;
  17292. const {
  17293. t
  17294. } = useLocale();
  17295. const {
  17296. themeClasses
  17297. } = provideTheme(props);
  17298. const rating = useProxiedModel(props, 'modelValue');
  17299. const normalizedValue = computed(() => clamp(parseFloat(rating.value), 0, +props.length));
  17300. const range = computed(() => createRange(Number(props.length), 1));
  17301. const increments = computed(() => range.value.flatMap(v => props.halfIncrements ? [v - 0.5, v] : [v]));
  17302. const hoverIndex = shallowRef(-1);
  17303. const itemState = computed(() => increments.value.map(value => {
  17304. const isHovering = props.hover && hoverIndex.value > -1;
  17305. const isFilled = normalizedValue.value >= value;
  17306. const isHovered = hoverIndex.value >= value;
  17307. const isFullIcon = isHovering ? isHovered : isFilled;
  17308. const icon = isFullIcon ? props.fullIcon : props.emptyIcon;
  17309. const activeColor = props.activeColor ?? props.color;
  17310. const color = isFilled || isHovered ? activeColor : props.color;
  17311. return {
  17312. isFilled,
  17313. isHovered,
  17314. icon,
  17315. color
  17316. };
  17317. }));
  17318. const eventState = computed(() => [0, ...increments.value].map(value => {
  17319. function onMouseenter() {
  17320. hoverIndex.value = value;
  17321. }
  17322. function onMouseleave() {
  17323. hoverIndex.value = -1;
  17324. }
  17325. function onClick() {
  17326. if (props.disabled || props.readonly) return;
  17327. rating.value = normalizedValue.value === value && props.clearable ? 0 : value;
  17328. }
  17329. return {
  17330. onMouseenter: props.hover ? onMouseenter : undefined,
  17331. onMouseleave: props.hover ? onMouseleave : undefined,
  17332. onClick
  17333. };
  17334. }));
  17335. const name = computed(() => props.name ?? `v-rating-${getUid()}`);
  17336. function VRatingItem(_ref2) {
  17337. let {
  17338. value,
  17339. index,
  17340. showStar = true
  17341. } = _ref2;
  17342. const {
  17343. onMouseenter,
  17344. onMouseleave,
  17345. onClick
  17346. } = eventState.value[index + 1];
  17347. const id = `${name.value}-${String(value).replace('.', '-')}`;
  17348. const btnProps = {
  17349. color: itemState.value[index]?.color,
  17350. density: props.density,
  17351. disabled: props.disabled,
  17352. icon: itemState.value[index]?.icon,
  17353. ripple: props.ripple,
  17354. size: props.size,
  17355. variant: 'plain'
  17356. };
  17357. return createVNode(Fragment, null, [createVNode("label", {
  17358. "for": id,
  17359. "class": {
  17360. 'v-rating__item--half': props.halfIncrements && value % 1 > 0,
  17361. 'v-rating__item--full': props.halfIncrements && value % 1 === 0
  17362. },
  17363. "onMouseenter": onMouseenter,
  17364. "onMouseleave": onMouseleave,
  17365. "onClick": onClick
  17366. }, [createVNode("span", {
  17367. "class": "v-rating__hidden"
  17368. }, [t(props.itemAriaLabel, value, props.length)]), !showStar ? undefined : slots.item ? slots.item({
  17369. ...itemState.value[index],
  17370. props: btnProps,
  17371. value,
  17372. index,
  17373. rating: normalizedValue.value
  17374. }) : createVNode(VBtn, mergeProps({
  17375. "aria-label": t(props.itemAriaLabel, value, props.length)
  17376. }, btnProps), null)]), createVNode("input", {
  17377. "class": "v-rating__hidden",
  17378. "name": name.value,
  17379. "id": id,
  17380. "type": "radio",
  17381. "value": value,
  17382. "checked": normalizedValue.value === value,
  17383. "tabindex": -1,
  17384. "readonly": props.readonly,
  17385. "disabled": props.disabled
  17386. }, null)]);
  17387. }
  17388. function createLabel(labelProps) {
  17389. if (slots['item-label']) return slots['item-label'](labelProps);
  17390. if (labelProps.label) return createVNode("span", null, [labelProps.label]);
  17391. return createVNode("span", null, [createTextVNode("\xA0")]);
  17392. }
  17393. useRender(() => {
  17394. const hasLabels = !!props.itemLabels?.length || slots['item-label'];
  17395. return createVNode(props.tag, {
  17396. "class": ['v-rating', {
  17397. 'v-rating--hover': props.hover,
  17398. 'v-rating--readonly': props.readonly
  17399. }, themeClasses.value, props.class],
  17400. "style": props.style
  17401. }, {
  17402. default: () => [createVNode(VRatingItem, {
  17403. "value": 0,
  17404. "index": -1,
  17405. "showStar": false
  17406. }, null), range.value.map((value, i) => createVNode("div", {
  17407. "class": "v-rating__wrapper"
  17408. }, [hasLabels && props.itemLabelPosition === 'top' ? createLabel({
  17409. value,
  17410. index: i,
  17411. label: props.itemLabels?.[i]
  17412. }) : undefined, createVNode("div", {
  17413. "class": "v-rating__item"
  17414. }, [props.halfIncrements ? createVNode(Fragment, null, [createVNode(VRatingItem, {
  17415. "value": value - 0.5,
  17416. "index": i * 2
  17417. }, null), createVNode(VRatingItem, {
  17418. "value": value,
  17419. "index": i * 2 + 1
  17420. }, null)]) : createVNode(VRatingItem, {
  17421. "value": value,
  17422. "index": i
  17423. }, null)]), hasLabels && props.itemLabelPosition === 'bottom' ? createLabel({
  17424. value,
  17425. index: i,
  17426. label: props.itemLabels?.[i]
  17427. }) : undefined]))]
  17428. });
  17429. });
  17430. return {};
  17431. }
  17432. });
  17433. function bias(val) {
  17434. const c = 0.501;
  17435. const x = Math.abs(val);
  17436. return Math.sign(val) * (x / ((1 / c - 2) * (1 - x) + 1));
  17437. }
  17438. function calculateUpdatedOffset(_ref) {
  17439. let {
  17440. selectedElement,
  17441. containerSize,
  17442. contentSize,
  17443. isRtl,
  17444. currentScrollOffset,
  17445. isHorizontal
  17446. } = _ref;
  17447. const clientSize = isHorizontal ? selectedElement.clientWidth : selectedElement.clientHeight;
  17448. const offsetStart = isHorizontal ? selectedElement.offsetLeft : selectedElement.offsetTop;
  17449. const adjustedOffsetStart = isRtl && isHorizontal ? contentSize - offsetStart - clientSize : offsetStart;
  17450. const totalSize = containerSize + currentScrollOffset;
  17451. const itemOffset = clientSize + adjustedOffsetStart;
  17452. const additionalOffset = clientSize * 0.4;
  17453. if (adjustedOffsetStart <= currentScrollOffset) {
  17454. currentScrollOffset = Math.max(adjustedOffsetStart - additionalOffset, 0);
  17455. } else if (totalSize <= itemOffset) {
  17456. currentScrollOffset = Math.min(currentScrollOffset - (totalSize - itemOffset - additionalOffset), contentSize - containerSize);
  17457. }
  17458. return currentScrollOffset;
  17459. }
  17460. function calculateCenteredOffset(_ref2) {
  17461. let {
  17462. selectedElement,
  17463. containerSize,
  17464. contentSize,
  17465. isRtl,
  17466. isHorizontal
  17467. } = _ref2;
  17468. const clientSize = isHorizontal ? selectedElement.clientWidth : selectedElement.clientHeight;
  17469. const offsetStart = isHorizontal ? selectedElement.offsetLeft : selectedElement.offsetTop;
  17470. const offsetCentered = isRtl && isHorizontal ? contentSize - offsetStart - clientSize / 2 - containerSize / 2 : offsetStart + clientSize / 2 - containerSize / 2;
  17471. return Math.min(contentSize - containerSize, Math.max(0, offsetCentered));
  17472. }
  17473. // Types
  17474. const VSlideGroupSymbol = Symbol.for('vuetify:v-slide-group');
  17475. const makeVSlideGroupProps = propsFactory({
  17476. centerActive: Boolean,
  17477. direction: {
  17478. type: String,
  17479. default: 'horizontal'
  17480. },
  17481. symbol: {
  17482. type: null,
  17483. default: VSlideGroupSymbol
  17484. },
  17485. nextIcon: {
  17486. type: IconValue,
  17487. default: '$next'
  17488. },
  17489. prevIcon: {
  17490. type: IconValue,
  17491. default: '$prev'
  17492. },
  17493. showArrows: {
  17494. type: [Boolean, String],
  17495. validator: v => typeof v === 'boolean' || ['always', 'desktop', 'mobile'].includes(v)
  17496. },
  17497. ...makeComponentProps(),
  17498. ...makeTagProps(),
  17499. ...makeGroupProps({
  17500. selectedClass: 'v-slide-group-item--active'
  17501. })
  17502. }, 'VSlideGroup');
  17503. const VSlideGroup = genericComponent()({
  17504. name: 'VSlideGroup',
  17505. props: makeVSlideGroupProps(),
  17506. emits: {
  17507. 'update:modelValue': value => true
  17508. },
  17509. setup(props, _ref) {
  17510. let {
  17511. slots
  17512. } = _ref;
  17513. const {
  17514. isRtl
  17515. } = useRtl();
  17516. const {
  17517. mobile
  17518. } = useDisplay();
  17519. const group = useGroup(props, props.symbol);
  17520. const isOverflowing = shallowRef(false);
  17521. const scrollOffset = shallowRef(0);
  17522. const containerSize = shallowRef(0);
  17523. const contentSize = shallowRef(0);
  17524. const isHorizontal = computed(() => props.direction === 'horizontal');
  17525. const {
  17526. resizeRef: containerRef,
  17527. contentRect: containerRect
  17528. } = useResizeObserver();
  17529. const {
  17530. resizeRef: contentRef,
  17531. contentRect
  17532. } = useResizeObserver();
  17533. const firstSelectedIndex = computed(() => {
  17534. if (!group.selected.value.length) return -1;
  17535. return group.items.value.findIndex(item => item.id === group.selected.value[0]);
  17536. });
  17537. const lastSelectedIndex = computed(() => {
  17538. if (!group.selected.value.length) return -1;
  17539. return group.items.value.findIndex(item => item.id === group.selected.value[group.selected.value.length - 1]);
  17540. });
  17541. if (IN_BROWSER) {
  17542. let frame = -1;
  17543. watch(() => [group.selected.value, containerRect.value, contentRect.value, isHorizontal.value], () => {
  17544. cancelAnimationFrame(frame);
  17545. frame = requestAnimationFrame(() => {
  17546. if (containerRect.value && contentRect.value) {
  17547. const sizeProperty = isHorizontal.value ? 'width' : 'height';
  17548. containerSize.value = containerRect.value[sizeProperty];
  17549. contentSize.value = contentRect.value[sizeProperty];
  17550. isOverflowing.value = containerSize.value + 1 < contentSize.value;
  17551. }
  17552. if (firstSelectedIndex.value >= 0 && contentRef.value) {
  17553. // TODO: Is this too naive? Should we store element references in group composable?
  17554. const selectedElement = contentRef.value.children[lastSelectedIndex.value];
  17555. if (firstSelectedIndex.value === 0 || !isOverflowing.value) {
  17556. scrollOffset.value = 0;
  17557. } else if (props.centerActive) {
  17558. scrollOffset.value = calculateCenteredOffset({
  17559. selectedElement,
  17560. containerSize: containerSize.value,
  17561. contentSize: contentSize.value,
  17562. isRtl: isRtl.value,
  17563. isHorizontal: isHorizontal.value
  17564. });
  17565. } else if (isOverflowing.value) {
  17566. scrollOffset.value = calculateUpdatedOffset({
  17567. selectedElement,
  17568. containerSize: containerSize.value,
  17569. contentSize: contentSize.value,
  17570. isRtl: isRtl.value,
  17571. currentScrollOffset: scrollOffset.value,
  17572. isHorizontal: isHorizontal.value
  17573. });
  17574. }
  17575. }
  17576. });
  17577. });
  17578. }
  17579. const disableTransition = shallowRef(false);
  17580. let startTouch = 0;
  17581. let startOffset = 0;
  17582. function onTouchstart(e) {
  17583. const sizeProperty = isHorizontal.value ? 'clientX' : 'clientY';
  17584. const sign = isRtl.value && isHorizontal.value ? -1 : 1;
  17585. startOffset = sign * scrollOffset.value;
  17586. startTouch = e.touches[0][sizeProperty];
  17587. disableTransition.value = true;
  17588. }
  17589. function onTouchmove(e) {
  17590. if (!isOverflowing.value) return;
  17591. const sizeProperty = isHorizontal.value ? 'clientX' : 'clientY';
  17592. const sign = isRtl.value && isHorizontal.value ? -1 : 1;
  17593. scrollOffset.value = sign * (startOffset + startTouch - e.touches[0][sizeProperty]);
  17594. }
  17595. function onTouchend(e) {
  17596. const maxScrollOffset = contentSize.value - containerSize.value;
  17597. if (scrollOffset.value < 0 || !isOverflowing.value) {
  17598. scrollOffset.value = 0;
  17599. } else if (scrollOffset.value >= maxScrollOffset) {
  17600. scrollOffset.value = maxScrollOffset;
  17601. }
  17602. disableTransition.value = false;
  17603. }
  17604. function onScroll() {
  17605. if (!containerRef.value) return;
  17606. containerRef.value[isHorizontal.value ? 'scrollLeft' : 'scrollTop'] = 0;
  17607. }
  17608. const isFocused = shallowRef(false);
  17609. function onFocusin(e) {
  17610. isFocused.value = true;
  17611. if (!isOverflowing.value || !contentRef.value) return;
  17612. // Focused element is likely to be the root of an item, so a
  17613. // breadth-first search will probably find it in the first iteration
  17614. for (const el of e.composedPath()) {
  17615. for (const item of contentRef.value.children) {
  17616. if (item === el) {
  17617. scrollOffset.value = calculateUpdatedOffset({
  17618. selectedElement: item,
  17619. containerSize: containerSize.value,
  17620. contentSize: contentSize.value,
  17621. isRtl: isRtl.value,
  17622. currentScrollOffset: scrollOffset.value,
  17623. isHorizontal: isHorizontal.value
  17624. });
  17625. return;
  17626. }
  17627. }
  17628. }
  17629. }
  17630. function onFocusout(e) {
  17631. isFocused.value = false;
  17632. }
  17633. function onFocus(e) {
  17634. if (!isFocused.value && !(e.relatedTarget && contentRef.value?.contains(e.relatedTarget))) focus();
  17635. }
  17636. function onKeydown(e) {
  17637. if (!contentRef.value) return;
  17638. if (isHorizontal.value) {
  17639. if (e.key === 'ArrowRight') {
  17640. focus(isRtl.value ? 'prev' : 'next');
  17641. } else if (e.key === 'ArrowLeft') {
  17642. focus(isRtl.value ? 'next' : 'prev');
  17643. }
  17644. } else {
  17645. if (e.key === 'ArrowDown') {
  17646. focus('next');
  17647. } else if (e.key === 'ArrowUp') {
  17648. focus('prev');
  17649. }
  17650. }
  17651. if (e.key === 'Home') {
  17652. focus('first');
  17653. } else if (e.key === 'End') {
  17654. focus('last');
  17655. }
  17656. }
  17657. function focus(location) {
  17658. if (!contentRef.value) return;
  17659. if (!location) {
  17660. const focusable = focusableChildren(contentRef.value);
  17661. focusable[0]?.focus();
  17662. } else if (location === 'next') {
  17663. const el = contentRef.value.querySelector(':focus')?.nextElementSibling;
  17664. if (el) el.focus();else focus('first');
  17665. } else if (location === 'prev') {
  17666. const el = contentRef.value.querySelector(':focus')?.previousElementSibling;
  17667. if (el) el.focus();else focus('last');
  17668. } else if (location === 'first') {
  17669. contentRef.value.firstElementChild?.focus();
  17670. } else if (location === 'last') {
  17671. contentRef.value.lastElementChild?.focus();
  17672. }
  17673. }
  17674. function scrollTo(location) {
  17675. const newAbsoluteOffset = scrollOffset.value + (location === 'prev' ? -1 : 1) * containerSize.value;
  17676. scrollOffset.value = clamp(newAbsoluteOffset, 0, contentSize.value - containerSize.value);
  17677. }
  17678. const contentStyles = computed(() => {
  17679. // This adds friction when scrolling the 'wrong' way when at max offset
  17680. let scrollAmount = scrollOffset.value > contentSize.value - containerSize.value ? -(contentSize.value - containerSize.value) + bias(contentSize.value - containerSize.value - scrollOffset.value) : -scrollOffset.value;
  17681. // This adds friction when scrolling the 'wrong' way when at min offset
  17682. if (scrollOffset.value <= 0) {
  17683. scrollAmount = bias(-scrollOffset.value);
  17684. }
  17685. const sign = isRtl.value && isHorizontal.value ? -1 : 1;
  17686. return {
  17687. transform: `translate${isHorizontal.value ? 'X' : 'Y'}(${sign * scrollAmount}px)`,
  17688. transition: disableTransition.value ? 'none' : '',
  17689. willChange: disableTransition.value ? 'transform' : ''
  17690. };
  17691. });
  17692. const slotProps = computed(() => ({
  17693. next: group.next,
  17694. prev: group.prev,
  17695. select: group.select,
  17696. isSelected: group.isSelected
  17697. }));
  17698. const hasAffixes = computed(() => {
  17699. switch (props.showArrows) {
  17700. // Always show arrows on desktop & mobile
  17701. case 'always':
  17702. return true;
  17703. // Always show arrows on desktop
  17704. case 'desktop':
  17705. return !mobile.value;
  17706. // Show arrows on mobile when overflowing.
  17707. // This matches the default 2.2 behavior
  17708. case true:
  17709. return isOverflowing.value || Math.abs(scrollOffset.value) > 0;
  17710. // Always show on mobile
  17711. case 'mobile':
  17712. return mobile.value || isOverflowing.value || Math.abs(scrollOffset.value) > 0;
  17713. // https://material.io/components/tabs#scrollable-tabs
  17714. // Always show arrows when
  17715. // overflowed on desktop
  17716. default:
  17717. return !mobile.value && (isOverflowing.value || Math.abs(scrollOffset.value) > 0);
  17718. }
  17719. });
  17720. const hasPrev = computed(() => {
  17721. return Math.abs(scrollOffset.value) > 0;
  17722. });
  17723. const hasNext = computed(() => {
  17724. // Check one scroll ahead to know the width of right-most item
  17725. return contentSize.value > Math.abs(scrollOffset.value) + containerSize.value;
  17726. });
  17727. useRender(() => createVNode(props.tag, {
  17728. "class": ['v-slide-group', {
  17729. 'v-slide-group--vertical': !isHorizontal.value,
  17730. 'v-slide-group--has-affixes': hasAffixes.value,
  17731. 'v-slide-group--is-overflowing': isOverflowing.value
  17732. }, props.class],
  17733. "style": props.style,
  17734. "tabindex": isFocused.value || group.selected.value.length ? -1 : 0,
  17735. "onFocus": onFocus
  17736. }, {
  17737. default: () => [hasAffixes.value && createVNode("div", {
  17738. "key": "prev",
  17739. "class": ['v-slide-group__prev', {
  17740. 'v-slide-group__prev--disabled': !hasPrev.value
  17741. }],
  17742. "onClick": () => scrollTo('prev')
  17743. }, [slots.prev?.(slotProps.value) ?? createVNode(VFadeTransition, null, {
  17744. default: () => [createVNode(VIcon, {
  17745. "icon": isRtl.value ? props.nextIcon : props.prevIcon
  17746. }, null)]
  17747. })]), createVNode("div", {
  17748. "key": "container",
  17749. "ref": containerRef,
  17750. "class": "v-slide-group__container",
  17751. "onScroll": onScroll
  17752. }, [createVNode("div", {
  17753. "ref": contentRef,
  17754. "class": "v-slide-group__content",
  17755. "style": contentStyles.value,
  17756. "onTouchstartPassive": onTouchstart,
  17757. "onTouchmovePassive": onTouchmove,
  17758. "onTouchendPassive": onTouchend,
  17759. "onFocusin": onFocusin,
  17760. "onFocusout": onFocusout,
  17761. "onKeydown": onKeydown
  17762. }, [slots.default?.(slotProps.value)])]), hasAffixes.value && createVNode("div", {
  17763. "key": "next",
  17764. "class": ['v-slide-group__next', {
  17765. 'v-slide-group__next--disabled': !hasNext.value
  17766. }],
  17767. "onClick": () => scrollTo('next')
  17768. }, [slots.next?.(slotProps.value) ?? createVNode(VFadeTransition, null, {
  17769. default: () => [createVNode(VIcon, {
  17770. "icon": isRtl.value ? props.prevIcon : props.nextIcon
  17771. }, null)]
  17772. })])]
  17773. }));
  17774. return {
  17775. selected: group.selected,
  17776. scrollTo,
  17777. scrollOffset,
  17778. focus
  17779. };
  17780. }
  17781. });
  17782. // Composables
  17783. // Types
  17784. const VSlideGroupItem = genericComponent()({
  17785. name: 'VSlideGroupItem',
  17786. props: makeGroupItemProps(),
  17787. emits: {
  17788. 'group:selected': val => true
  17789. },
  17790. setup(props, _ref) {
  17791. let {
  17792. slots
  17793. } = _ref;
  17794. const slideGroupItem = useGroupItem(props, VSlideGroupSymbol);
  17795. return () => slots.default?.({
  17796. isSelected: slideGroupItem.isSelected.value,
  17797. select: slideGroupItem.select,
  17798. toggle: slideGroupItem.toggle,
  17799. selectedClass: slideGroupItem.selectedClass.value
  17800. });
  17801. }
  17802. });
  17803. const makeVSnackbarProps = propsFactory({
  17804. multiLine: Boolean,
  17805. timeout: {
  17806. type: [Number, String],
  17807. default: 5000
  17808. },
  17809. vertical: Boolean,
  17810. ...makeLocationProps({
  17811. location: 'bottom'
  17812. }),
  17813. ...makePositionProps(),
  17814. ...makeRoundedProps(),
  17815. ...makeVariantProps(),
  17816. ...makeThemeProps(),
  17817. ...omit(makeVOverlayProps({
  17818. transition: 'v-snackbar-transition'
  17819. }), ['persistent', 'noClickAnimation', 'scrim', 'scrollStrategy'])
  17820. }, 'VSnackbar');
  17821. const VSnackbar = genericComponent()({
  17822. name: 'VSnackbar',
  17823. props: makeVSnackbarProps(),
  17824. emits: {
  17825. 'update:modelValue': v => true
  17826. },
  17827. setup(props, _ref) {
  17828. let {
  17829. slots
  17830. } = _ref;
  17831. const isActive = useProxiedModel(props, 'modelValue');
  17832. const {
  17833. locationStyles
  17834. } = useLocation(props);
  17835. const {
  17836. positionClasses
  17837. } = usePosition(props);
  17838. const {
  17839. scopeId
  17840. } = useScopeId();
  17841. const {
  17842. themeClasses
  17843. } = provideTheme(props);
  17844. const {
  17845. colorClasses,
  17846. colorStyles,
  17847. variantClasses
  17848. } = useVariant(props);
  17849. const {
  17850. roundedClasses
  17851. } = useRounded(props);
  17852. const overlay = ref();
  17853. watch(isActive, startTimeout);
  17854. watch(() => props.timeout, startTimeout);
  17855. onMounted(() => {
  17856. if (isActive.value) startTimeout();
  17857. });
  17858. let activeTimeout = -1;
  17859. function startTimeout() {
  17860. window.clearTimeout(activeTimeout);
  17861. const timeout = Number(props.timeout);
  17862. if (!isActive.value || timeout === -1) return;
  17863. activeTimeout = window.setTimeout(() => {
  17864. isActive.value = false;
  17865. }, timeout);
  17866. }
  17867. function onPointerenter() {
  17868. window.clearTimeout(activeTimeout);
  17869. }
  17870. useRender(() => {
  17871. const [overlayProps] = VOverlay.filterProps(props);
  17872. return createVNode(VOverlay, mergeProps({
  17873. "ref": overlay,
  17874. "class": ['v-snackbar', {
  17875. 'v-snackbar--active': isActive.value,
  17876. 'v-snackbar--multi-line': props.multiLine && !props.vertical,
  17877. 'v-snackbar--vertical': props.vertical
  17878. }, positionClasses.value, props.class],
  17879. "style": props.style
  17880. }, overlayProps, {
  17881. "modelValue": isActive.value,
  17882. "onUpdate:modelValue": $event => isActive.value = $event,
  17883. "contentProps": mergeProps({
  17884. class: ['v-snackbar__wrapper', themeClasses.value, colorClasses.value, roundedClasses.value, variantClasses.value],
  17885. style: [locationStyles.value, colorStyles.value],
  17886. onPointerenter,
  17887. onPointerleave: startTimeout
  17888. }, overlayProps.contentProps),
  17889. "persistent": true,
  17890. "noClickAnimation": true,
  17891. "scrim": false,
  17892. "scrollStrategy": "none",
  17893. "_disableGlobalStack": true
  17894. }, scopeId), {
  17895. default: () => [genOverlays(false, 'v-snackbar'), slots.default && createVNode("div", {
  17896. "class": "v-snackbar__content",
  17897. "role": "status",
  17898. "aria-live": "polite"
  17899. }, [slots.default()]), slots.actions && createVNode(VDefaultsProvider, {
  17900. "defaults": {
  17901. VBtn: {
  17902. variant: 'text',
  17903. ripple: false
  17904. }
  17905. }
  17906. }, {
  17907. default: () => [createVNode("div", {
  17908. "class": "v-snackbar__actions"
  17909. }, [slots.actions()])]
  17910. })],
  17911. activator: slots.activator
  17912. });
  17913. });
  17914. return forwardRefs({}, overlay);
  17915. }
  17916. });
  17917. // Types
  17918. const makeVSwitchProps = propsFactory({
  17919. indeterminate: Boolean,
  17920. inset: Boolean,
  17921. flat: Boolean,
  17922. loading: {
  17923. type: [Boolean, String],
  17924. default: false
  17925. },
  17926. ...makeVInputProps(),
  17927. ...makeVSelectionControlProps()
  17928. }, 'VSwitch');
  17929. const VSwitch = genericComponent()({
  17930. name: 'VSwitch',
  17931. inheritAttrs: false,
  17932. props: makeVSwitchProps(),
  17933. emits: {
  17934. 'update:focused': focused => true,
  17935. 'update:modelValue': () => true,
  17936. 'update:indeterminate': val => true
  17937. },
  17938. setup(props, _ref) {
  17939. let {
  17940. attrs,
  17941. slots
  17942. } = _ref;
  17943. const indeterminate = useProxiedModel(props, 'indeterminate');
  17944. const model = useProxiedModel(props, 'modelValue');
  17945. const {
  17946. loaderClasses
  17947. } = useLoader(props);
  17948. const {
  17949. isFocused,
  17950. focus,
  17951. blur
  17952. } = useFocus(props);
  17953. const loaderColor = computed(() => {
  17954. return typeof props.loading === 'string' && props.loading !== '' ? props.loading : props.color;
  17955. });
  17956. const uid = getUid();
  17957. const id = computed(() => props.id || `switch-${uid}`);
  17958. function onChange() {
  17959. if (indeterminate.value) {
  17960. indeterminate.value = false;
  17961. }
  17962. }
  17963. useRender(() => {
  17964. const [inputAttrs, controlAttrs] = filterInputAttrs(attrs);
  17965. const [inputProps, _1] = VInput.filterProps(props);
  17966. const [controlProps, _2] = VSelectionControl.filterProps(props);
  17967. const control = ref();
  17968. function onClick(e) {
  17969. e.stopPropagation();
  17970. e.preventDefault();
  17971. control.value?.input?.click();
  17972. }
  17973. return createVNode(VInput, mergeProps({
  17974. "class": ['v-switch', {
  17975. 'v-switch--inset': props.inset
  17976. }, {
  17977. 'v-switch--indeterminate': indeterminate.value
  17978. }, loaderClasses.value, props.class],
  17979. "style": props.style
  17980. }, inputAttrs, inputProps, {
  17981. "id": id.value,
  17982. "focused": isFocused.value
  17983. }), {
  17984. ...slots,
  17985. default: _ref2 => {
  17986. let {
  17987. id,
  17988. messagesId,
  17989. isDisabled,
  17990. isReadonly,
  17991. isValid
  17992. } = _ref2;
  17993. return createVNode(VSelectionControl, mergeProps({
  17994. "ref": control
  17995. }, controlProps, {
  17996. "modelValue": model.value,
  17997. "onUpdate:modelValue": [$event => model.value = $event, onChange],
  17998. "id": id.value,
  17999. "aria-describedby": messagesId.value,
  18000. "type": "checkbox",
  18001. "aria-checked": indeterminate.value ? 'mixed' : undefined,
  18002. "disabled": isDisabled.value,
  18003. "readonly": isReadonly.value,
  18004. "onFocus": focus,
  18005. "onBlur": blur
  18006. }, controlAttrs), {
  18007. ...slots,
  18008. default: () => createVNode("div", {
  18009. "class": "v-switch__track",
  18010. "onClick": onClick
  18011. }, null),
  18012. input: _ref3 => {
  18013. let {
  18014. textColorClasses,
  18015. textColorStyles
  18016. } = _ref3;
  18017. return createVNode("div", {
  18018. "class": ['v-switch__thumb', textColorClasses.value],
  18019. "style": textColorStyles.value
  18020. }, [props.loading && createVNode(LoaderSlot, {
  18021. "name": "v-switch",
  18022. "active": true,
  18023. "color": isValid.value === false ? undefined : loaderColor.value
  18024. }, {
  18025. default: slotProps => slots.loader ? slots.loader(slotProps) : createVNode(VProgressCircular, {
  18026. "active": slotProps.isActive,
  18027. "color": slotProps.color,
  18028. "indeterminate": true,
  18029. "size": "16",
  18030. "width": "2"
  18031. }, null)
  18032. })]);
  18033. }
  18034. });
  18035. }
  18036. });
  18037. });
  18038. return {};
  18039. }
  18040. });
  18041. const makeVSystemBarProps = propsFactory({
  18042. color: String,
  18043. height: [Number, String],
  18044. window: Boolean,
  18045. ...makeComponentProps(),
  18046. ...makeElevationProps(),
  18047. ...makeLayoutItemProps(),
  18048. ...makeRoundedProps(),
  18049. ...makeTagProps(),
  18050. ...makeThemeProps()
  18051. }, 'VSystemBar');
  18052. const VSystemBar = genericComponent()({
  18053. name: 'VSystemBar',
  18054. props: makeVSystemBarProps(),
  18055. setup(props, _ref) {
  18056. let {
  18057. slots
  18058. } = _ref;
  18059. const {
  18060. themeClasses
  18061. } = provideTheme(props);
  18062. const {
  18063. backgroundColorClasses,
  18064. backgroundColorStyles
  18065. } = useBackgroundColor(toRef(props, 'color'));
  18066. const {
  18067. elevationClasses
  18068. } = useElevation(props);
  18069. const {
  18070. roundedClasses
  18071. } = useRounded(props);
  18072. const {
  18073. ssrBootStyles
  18074. } = useSsrBoot();
  18075. const height = computed(() => props.height ?? (props.window ? 32 : 24));
  18076. const {
  18077. layoutItemStyles
  18078. } = useLayoutItem({
  18079. id: props.name,
  18080. order: computed(() => parseInt(props.order, 10)),
  18081. position: shallowRef('top'),
  18082. layoutSize: height,
  18083. elementSize: height,
  18084. active: computed(() => true),
  18085. absolute: toRef(props, 'absolute')
  18086. });
  18087. useRender(() => createVNode(props.tag, {
  18088. "class": ['v-system-bar', {
  18089. 'v-system-bar--window': props.window
  18090. }, themeClasses.value, backgroundColorClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  18091. "style": [backgroundColorStyles.value, layoutItemStyles.value, ssrBootStyles.value, props.style]
  18092. }, slots));
  18093. return {};
  18094. }
  18095. });
  18096. // Types
  18097. const VTabsSymbol = Symbol.for('vuetify:v-tabs');
  18098. // Types
  18099. const makeVTabProps = propsFactory({
  18100. fixed: Boolean,
  18101. sliderColor: String,
  18102. hideSlider: Boolean,
  18103. direction: {
  18104. type: String,
  18105. default: 'horizontal'
  18106. },
  18107. ...omit(makeVBtnProps({
  18108. selectedClass: 'v-tab--selected',
  18109. variant: 'text'
  18110. }), ['active', 'block', 'flat', 'location', 'position', 'symbol'])
  18111. }, 'VTab');
  18112. const VTab = genericComponent()({
  18113. name: 'VTab',
  18114. props: makeVTabProps(),
  18115. setup(props, _ref) {
  18116. let {
  18117. slots,
  18118. attrs
  18119. } = _ref;
  18120. const {
  18121. textColorClasses: sliderColorClasses,
  18122. textColorStyles: sliderColorStyles
  18123. } = useTextColor(props, 'sliderColor');
  18124. const isHorizontal = computed(() => props.direction === 'horizontal');
  18125. const isSelected = shallowRef(false);
  18126. const rootEl = ref();
  18127. const sliderEl = ref();
  18128. function updateSlider(_ref2) {
  18129. let {
  18130. value
  18131. } = _ref2;
  18132. isSelected.value = value;
  18133. if (value) {
  18134. const prevEl = rootEl.value?.$el.parentElement?.querySelector('.v-tab--selected .v-tab__slider');
  18135. const nextEl = sliderEl.value;
  18136. if (!prevEl || !nextEl) return;
  18137. const color = getComputedStyle(prevEl).color;
  18138. const prevBox = prevEl.getBoundingClientRect();
  18139. const nextBox = nextEl.getBoundingClientRect();
  18140. const xy = isHorizontal.value ? 'x' : 'y';
  18141. const XY = isHorizontal.value ? 'X' : 'Y';
  18142. const rightBottom = isHorizontal.value ? 'right' : 'bottom';
  18143. const widthHeight = isHorizontal.value ? 'width' : 'height';
  18144. const prevPos = prevBox[xy];
  18145. const nextPos = nextBox[xy];
  18146. const delta = prevPos > nextPos ? prevBox[rightBottom] - nextBox[rightBottom] : prevBox[xy] - nextBox[xy];
  18147. const origin = Math.sign(delta) > 0 ? isHorizontal.value ? 'right' : 'bottom' : Math.sign(delta) < 0 ? isHorizontal.value ? 'left' : 'top' : 'center';
  18148. const size = Math.abs(delta) + (Math.sign(delta) < 0 ? prevBox[widthHeight] : nextBox[widthHeight]);
  18149. const scale = size / Math.max(prevBox[widthHeight], nextBox[widthHeight]);
  18150. const initialScale = prevBox[widthHeight] / nextBox[widthHeight];
  18151. const sigma = 1.5;
  18152. animate(nextEl, {
  18153. backgroundColor: [color, 'currentcolor'],
  18154. transform: [`translate${XY}(${delta}px) scale${XY}(${initialScale})`, `translate${XY}(${delta / sigma}px) scale${XY}(${(scale - 1) / sigma + 1})`, 'none'],
  18155. transformOrigin: Array(3).fill(origin)
  18156. }, {
  18157. duration: 225,
  18158. easing: standardEasing
  18159. });
  18160. }
  18161. }
  18162. useRender(() => {
  18163. const [btnProps] = VBtn.filterProps(props);
  18164. return createVNode(VBtn, mergeProps({
  18165. "symbol": VTabsSymbol,
  18166. "ref": rootEl,
  18167. "class": ['v-tab', props.class],
  18168. "style": props.style,
  18169. "tabindex": isSelected.value ? 0 : -1,
  18170. "role": "tab",
  18171. "aria-selected": String(isSelected.value),
  18172. "active": false,
  18173. "block": props.fixed,
  18174. "maxWidth": props.fixed ? 300 : undefined,
  18175. "rounded": 0
  18176. }, btnProps, attrs, {
  18177. "onGroup:selected": updateSlider
  18178. }), {
  18179. default: () => [slots.default?.() ?? props.text, !props.hideSlider && createVNode("div", {
  18180. "ref": sliderEl,
  18181. "class": ['v-tab__slider', sliderColorClasses.value],
  18182. "style": sliderColorStyles.value
  18183. }, null)]
  18184. });
  18185. });
  18186. return {};
  18187. }
  18188. });
  18189. function parseItems(items) {
  18190. if (!items) return [];
  18191. return items.map(item => {
  18192. if (typeof item === 'string') return {
  18193. title: item,
  18194. value: item
  18195. };
  18196. return item;
  18197. });
  18198. }
  18199. const makeVTabsProps = propsFactory({
  18200. alignTabs: {
  18201. type: String,
  18202. default: 'start'
  18203. },
  18204. color: String,
  18205. fixedTabs: Boolean,
  18206. items: {
  18207. type: Array,
  18208. default: () => []
  18209. },
  18210. stacked: Boolean,
  18211. bgColor: String,
  18212. grow: Boolean,
  18213. height: {
  18214. type: [Number, String],
  18215. default: undefined
  18216. },
  18217. hideSlider: Boolean,
  18218. sliderColor: String,
  18219. ...makeVSlideGroupProps({
  18220. mandatory: 'force'
  18221. }),
  18222. ...makeDensityProps(),
  18223. ...makeTagProps()
  18224. }, 'VTabs');
  18225. const VTabs = genericComponent()({
  18226. name: 'VTabs',
  18227. props: makeVTabsProps(),
  18228. emits: {
  18229. 'update:modelValue': v => true
  18230. },
  18231. setup(props, _ref) {
  18232. let {
  18233. slots
  18234. } = _ref;
  18235. const model = useProxiedModel(props, 'modelValue');
  18236. const parsedItems = computed(() => parseItems(props.items));
  18237. const {
  18238. densityClasses
  18239. } = useDensity(props);
  18240. const {
  18241. backgroundColorClasses,
  18242. backgroundColorStyles
  18243. } = useBackgroundColor(toRef(props, 'bgColor'));
  18244. provideDefaults({
  18245. VTab: {
  18246. color: toRef(props, 'color'),
  18247. direction: toRef(props, 'direction'),
  18248. stacked: toRef(props, 'stacked'),
  18249. fixed: toRef(props, 'fixedTabs'),
  18250. sliderColor: toRef(props, 'sliderColor'),
  18251. hideSlider: toRef(props, 'hideSlider')
  18252. }
  18253. });
  18254. useRender(() => {
  18255. const [slideGroupProps] = VSlideGroup.filterProps(props);
  18256. return createVNode(VSlideGroup, mergeProps(slideGroupProps, {
  18257. "modelValue": model.value,
  18258. "onUpdate:modelValue": $event => model.value = $event,
  18259. "class": ['v-tabs', `v-tabs--${props.direction}`, `v-tabs--align-tabs-${props.alignTabs}`, {
  18260. 'v-tabs--fixed-tabs': props.fixedTabs,
  18261. 'v-tabs--grow': props.grow,
  18262. 'v-tabs--stacked': props.stacked
  18263. }, densityClasses.value, backgroundColorClasses.value, props.class],
  18264. "style": [{
  18265. '--v-tabs-height': convertToUnit(props.height)
  18266. }, backgroundColorStyles.value, props.style],
  18267. "role": "tablist",
  18268. "symbol": VTabsSymbol
  18269. }), {
  18270. default: () => [slots.default ? slots.default() : parsedItems.value.map(item => createVNode(VTab, mergeProps(item, {
  18271. "key": item.title
  18272. }), null))]
  18273. });
  18274. });
  18275. return {};
  18276. }
  18277. });
  18278. const makeVTableProps = propsFactory({
  18279. fixedHeader: Boolean,
  18280. fixedFooter: Boolean,
  18281. height: [Number, String],
  18282. hover: Boolean,
  18283. ...makeComponentProps(),
  18284. ...makeDensityProps(),
  18285. ...makeTagProps(),
  18286. ...makeThemeProps()
  18287. }, 'VTable');
  18288. const VTable = genericComponent()({
  18289. name: 'VTable',
  18290. props: makeVTableProps(),
  18291. setup(props, _ref) {
  18292. let {
  18293. slots
  18294. } = _ref;
  18295. const {
  18296. themeClasses
  18297. } = provideTheme(props);
  18298. const {
  18299. densityClasses
  18300. } = useDensity(props);
  18301. useRender(() => createVNode(props.tag, {
  18302. "class": ['v-table', {
  18303. 'v-table--fixed-height': !!props.height,
  18304. 'v-table--fixed-header': props.fixedHeader,
  18305. 'v-table--fixed-footer': props.fixedFooter,
  18306. 'v-table--has-top': !!slots.top,
  18307. 'v-table--has-bottom': !!slots.bottom,
  18308. 'v-table--hover': props.hover
  18309. }, themeClasses.value, densityClasses.value, props.class],
  18310. "style": props.style
  18311. }, {
  18312. default: () => [slots.top?.(), slots.default ? createVNode("div", {
  18313. "class": "v-table__wrapper",
  18314. "style": {
  18315. height: convertToUnit(props.height)
  18316. }
  18317. }, [createVNode("table", null, [slots.default()])]) : slots.wrapper?.(), slots.bottom?.()]
  18318. }));
  18319. return {};
  18320. }
  18321. });
  18322. // Types
  18323. const makeVTextareaProps = propsFactory({
  18324. autoGrow: Boolean,
  18325. autofocus: Boolean,
  18326. counter: [Boolean, Number, String],
  18327. counterValue: Function,
  18328. prefix: String,
  18329. placeholder: String,
  18330. persistentPlaceholder: Boolean,
  18331. persistentCounter: Boolean,
  18332. noResize: Boolean,
  18333. rows: {
  18334. type: [Number, String],
  18335. default: 5,
  18336. validator: v => !isNaN(parseFloat(v))
  18337. },
  18338. maxRows: {
  18339. type: [Number, String],
  18340. validator: v => !isNaN(parseFloat(v))
  18341. },
  18342. suffix: String,
  18343. modelModifiers: Object,
  18344. ...makeVInputProps(),
  18345. ...makeVFieldProps()
  18346. }, 'VTextarea');
  18347. const VTextarea = genericComponent()({
  18348. name: 'VTextarea',
  18349. directives: {
  18350. Intersect
  18351. },
  18352. inheritAttrs: false,
  18353. props: makeVTextareaProps(),
  18354. emits: {
  18355. 'click:control': e => true,
  18356. 'mousedown:control': e => true,
  18357. 'update:focused': focused => true,
  18358. 'update:modelValue': val => true
  18359. },
  18360. setup(props, _ref) {
  18361. let {
  18362. attrs,
  18363. emit,
  18364. slots
  18365. } = _ref;
  18366. const model = useProxiedModel(props, 'modelValue');
  18367. const {
  18368. isFocused,
  18369. focus,
  18370. blur
  18371. } = useFocus(props);
  18372. const counterValue = computed(() => {
  18373. return typeof props.counterValue === 'function' ? props.counterValue(model.value) : (model.value || '').toString().length;
  18374. });
  18375. const max = computed(() => {
  18376. if (attrs.maxlength) return attrs.maxlength;
  18377. if (!props.counter || typeof props.counter !== 'number' && typeof props.counter !== 'string') return undefined;
  18378. return props.counter;
  18379. });
  18380. function onIntersect(isIntersecting, entries) {
  18381. if (!props.autofocus || !isIntersecting) return;
  18382. entries[0].target?.focus?.();
  18383. }
  18384. const vInputRef = ref();
  18385. const vFieldRef = ref();
  18386. const controlHeight = shallowRef('');
  18387. const textareaRef = ref();
  18388. const isActive = computed(() => props.persistentPlaceholder || isFocused.value || props.active);
  18389. function onFocus() {
  18390. if (textareaRef.value !== document.activeElement) {
  18391. textareaRef.value?.focus();
  18392. }
  18393. if (!isFocused.value) focus();
  18394. }
  18395. function onControlClick(e) {
  18396. onFocus();
  18397. emit('click:control', e);
  18398. }
  18399. function onControlMousedown(e) {
  18400. emit('mousedown:control', e);
  18401. }
  18402. function onClear(e) {
  18403. e.stopPropagation();
  18404. onFocus();
  18405. nextTick(() => {
  18406. model.value = '';
  18407. callEvent(props['onClick:clear'], e);
  18408. });
  18409. }
  18410. function onInput(e) {
  18411. const el = e.target;
  18412. model.value = el.value;
  18413. if (props.modelModifiers?.trim) {
  18414. const caretPosition = [el.selectionStart, el.selectionEnd];
  18415. nextTick(() => {
  18416. el.selectionStart = caretPosition[0];
  18417. el.selectionEnd = caretPosition[1];
  18418. });
  18419. }
  18420. }
  18421. const sizerRef = ref();
  18422. const rows = ref(+props.rows);
  18423. const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant));
  18424. watchEffect(() => {
  18425. if (!props.autoGrow) rows.value = +props.rows;
  18426. });
  18427. function calculateInputHeight() {
  18428. if (!props.autoGrow) return;
  18429. nextTick(() => {
  18430. if (!sizerRef.value || !vFieldRef.value) return;
  18431. const style = getComputedStyle(sizerRef.value);
  18432. const fieldStyle = getComputedStyle(vFieldRef.value.$el);
  18433. const padding = parseFloat(style.getPropertyValue('--v-field-padding-top')) + parseFloat(style.getPropertyValue('--v-input-padding-top')) + parseFloat(style.getPropertyValue('--v-field-padding-bottom'));
  18434. const height = sizerRef.value.scrollHeight;
  18435. const lineHeight = parseFloat(style.lineHeight);
  18436. const minHeight = Math.max(parseFloat(props.rows) * lineHeight + padding, parseFloat(fieldStyle.getPropertyValue('--v-input-control-height')));
  18437. const maxHeight = parseFloat(props.maxRows) * lineHeight + padding || Infinity;
  18438. const newHeight = clamp(height ?? 0, minHeight, maxHeight);
  18439. rows.value = Math.floor((newHeight - padding) / lineHeight);
  18440. controlHeight.value = convertToUnit(newHeight);
  18441. });
  18442. }
  18443. onMounted(calculateInputHeight);
  18444. watch(model, calculateInputHeight);
  18445. watch(() => props.rows, calculateInputHeight);
  18446. watch(() => props.maxRows, calculateInputHeight);
  18447. watch(() => props.density, calculateInputHeight);
  18448. let observer;
  18449. watch(sizerRef, val => {
  18450. if (val) {
  18451. observer = new ResizeObserver(calculateInputHeight);
  18452. observer.observe(sizerRef.value);
  18453. } else {
  18454. observer?.disconnect();
  18455. }
  18456. });
  18457. onBeforeUnmount(() => {
  18458. observer?.disconnect();
  18459. });
  18460. useRender(() => {
  18461. const hasCounter = !!(slots.counter || props.counter || props.counterValue);
  18462. const hasDetails = !!(hasCounter || slots.details);
  18463. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  18464. const [{
  18465. modelValue: _,
  18466. ...inputProps
  18467. }] = VInput.filterProps(props);
  18468. const [fieldProps] = filterFieldProps(props);
  18469. return createVNode(VInput, mergeProps({
  18470. "ref": vInputRef,
  18471. "modelValue": model.value,
  18472. "onUpdate:modelValue": $event => model.value = $event,
  18473. "class": ['v-textarea v-text-field', {
  18474. 'v-textarea--prefixed': props.prefix,
  18475. 'v-textarea--suffixed': props.suffix,
  18476. 'v-text-field--prefixed': props.prefix,
  18477. 'v-text-field--suffixed': props.suffix,
  18478. 'v-textarea--auto-grow': props.autoGrow,
  18479. 'v-textarea--no-resize': props.noResize || props.autoGrow,
  18480. 'v-text-field--plain-underlined': isPlainOrUnderlined.value
  18481. }, props.class],
  18482. "style": props.style
  18483. }, rootAttrs, inputProps, {
  18484. "centerAffix": rows.value === 1 && !isPlainOrUnderlined.value,
  18485. "focused": isFocused.value
  18486. }), {
  18487. ...slots,
  18488. default: _ref2 => {
  18489. let {
  18490. isDisabled,
  18491. isDirty,
  18492. isReadonly,
  18493. isValid
  18494. } = _ref2;
  18495. return createVNode(VField, mergeProps({
  18496. "ref": vFieldRef,
  18497. "style": {
  18498. '--v-textarea-control-height': controlHeight.value
  18499. },
  18500. "onClick": onControlClick,
  18501. "onMousedown": onControlMousedown,
  18502. "onClick:clear": onClear,
  18503. "onClick:prependInner": props['onClick:prependInner'],
  18504. "onClick:appendInner": props['onClick:appendInner'],
  18505. "role": "textbox"
  18506. }, fieldProps, {
  18507. "active": isActive.value || isDirty.value,
  18508. "centerAffix": rows.value === 1 && !isPlainOrUnderlined.value,
  18509. "dirty": isDirty.value || props.dirty,
  18510. "disabled": isDisabled.value,
  18511. "focused": isFocused.value,
  18512. "error": isValid.value === false
  18513. }), {
  18514. ...slots,
  18515. default: _ref3 => {
  18516. let {
  18517. props: {
  18518. class: fieldClass,
  18519. ...slotProps
  18520. }
  18521. } = _ref3;
  18522. return createVNode(Fragment, null, [props.prefix && createVNode("span", {
  18523. "class": "v-text-field__prefix"
  18524. }, [props.prefix]), withDirectives(createVNode("textarea", mergeProps({
  18525. "ref": textareaRef,
  18526. "class": fieldClass,
  18527. "value": model.value,
  18528. "onInput": onInput,
  18529. "autofocus": props.autofocus,
  18530. "readonly": isReadonly.value,
  18531. "disabled": isDisabled.value,
  18532. "placeholder": props.placeholder,
  18533. "rows": props.rows,
  18534. "name": props.name,
  18535. "onFocus": onFocus,
  18536. "onBlur": blur
  18537. }, slotProps, inputAttrs), null), [[resolveDirective("intersect"), {
  18538. handler: onIntersect
  18539. }, null, {
  18540. once: true
  18541. }]]), props.autoGrow && withDirectives(createVNode("textarea", {
  18542. "class": [fieldClass, 'v-textarea__sizer'],
  18543. "onUpdate:modelValue": $event => model.value = $event,
  18544. "ref": sizerRef,
  18545. "readonly": true,
  18546. "aria-hidden": "true"
  18547. }, null), [[vModelText, model.value]]), props.suffix && createVNode("span", {
  18548. "class": "v-text-field__suffix"
  18549. }, [props.suffix])]);
  18550. }
  18551. });
  18552. },
  18553. details: hasDetails ? slotProps => createVNode(Fragment, null, [slots.details?.(slotProps), hasCounter && createVNode(Fragment, null, [createVNode("span", null, null), createVNode(VCounter, {
  18554. "active": props.persistentCounter || isFocused.value,
  18555. "value": counterValue.value,
  18556. "max": max.value
  18557. }, slots.counter)])]) : undefined
  18558. });
  18559. });
  18560. return forwardRefs({}, vInputRef, vFieldRef, textareaRef);
  18561. }
  18562. });
  18563. const makeVThemeProviderProps = propsFactory({
  18564. withBackground: Boolean,
  18565. ...makeComponentProps(),
  18566. ...makeThemeProps(),
  18567. ...makeTagProps()
  18568. }, 'VThemeProvider');
  18569. const VThemeProvider = genericComponent()({
  18570. name: 'VThemeProvider',
  18571. props: makeVThemeProviderProps(),
  18572. setup(props, _ref) {
  18573. let {
  18574. slots
  18575. } = _ref;
  18576. const {
  18577. themeClasses
  18578. } = provideTheme(props);
  18579. return () => {
  18580. if (!props.withBackground) return slots.default?.();
  18581. return createVNode(props.tag, {
  18582. "class": ['v-theme-provider', themeClasses.value, props.class],
  18583. "style": props.style
  18584. }, {
  18585. default: () => [slots.default?.()]
  18586. });
  18587. };
  18588. }
  18589. });
  18590. // Types
  18591. const makeVTimelineProps = propsFactory({
  18592. align: {
  18593. type: String,
  18594. default: 'center',
  18595. validator: v => ['center', 'start'].includes(v)
  18596. },
  18597. direction: {
  18598. type: String,
  18599. default: 'vertical',
  18600. validator: v => ['vertical', 'horizontal'].includes(v)
  18601. },
  18602. justify: {
  18603. type: String,
  18604. default: 'auto',
  18605. validator: v => ['auto', 'center'].includes(v)
  18606. },
  18607. side: {
  18608. type: String,
  18609. validator: v => v == null || ['start', 'end'].includes(v)
  18610. },
  18611. lineInset: {
  18612. type: [String, Number],
  18613. default: 0
  18614. },
  18615. lineThickness: {
  18616. type: [String, Number],
  18617. default: 2
  18618. },
  18619. lineColor: String,
  18620. truncateLine: {
  18621. type: String,
  18622. validator: v => ['start', 'end', 'both'].includes(v)
  18623. },
  18624. ...makeComponentProps(),
  18625. ...makeDensityProps(),
  18626. ...makeTagProps(),
  18627. ...makeThemeProps()
  18628. }, 'VTimeline');
  18629. const VTimeline = genericComponent()({
  18630. name: 'VTimeline',
  18631. props: makeVTimelineProps(),
  18632. setup(props, _ref) {
  18633. let {
  18634. slots
  18635. } = _ref;
  18636. const {
  18637. themeClasses
  18638. } = provideTheme(props);
  18639. const {
  18640. densityClasses
  18641. } = useDensity(props);
  18642. const {
  18643. rtlClasses
  18644. } = useRtl();
  18645. provideDefaults({
  18646. VTimelineDivider: {
  18647. lineColor: toRef(props, 'lineColor')
  18648. },
  18649. VTimelineItem: {
  18650. density: toRef(props, 'density'),
  18651. lineInset: toRef(props, 'lineInset')
  18652. }
  18653. });
  18654. const sideClasses = computed(() => {
  18655. const side = props.side ? props.side : props.density !== 'default' ? 'end' : null;
  18656. return side && `v-timeline--side-${side}`;
  18657. });
  18658. const truncateClasses = computed(() => {
  18659. const classes = ['v-timeline--truncate-line-start', 'v-timeline--truncate-line-end'];
  18660. switch (props.truncateLine) {
  18661. case 'both':
  18662. return classes;
  18663. case 'start':
  18664. return classes[0];
  18665. case 'end':
  18666. return classes[1];
  18667. default:
  18668. return null;
  18669. }
  18670. });
  18671. useRender(() => createVNode(props.tag, {
  18672. "class": ['v-timeline', `v-timeline--${props.direction}`, `v-timeline--align-${props.align}`, `v-timeline--justify-${props.justify}`, truncateClasses.value, {
  18673. 'v-timeline--inset-line': !!props.lineInset
  18674. }, themeClasses.value, densityClasses.value, sideClasses.value, rtlClasses.value, props.class],
  18675. "style": [{
  18676. '--v-timeline-line-thickness': convertToUnit(props.lineThickness)
  18677. }, props.style]
  18678. }, slots));
  18679. return {};
  18680. }
  18681. });
  18682. const makeVTimelineDividerProps = propsFactory({
  18683. dotColor: String,
  18684. fillDot: Boolean,
  18685. hideDot: Boolean,
  18686. icon: IconValue,
  18687. iconColor: String,
  18688. lineColor: String,
  18689. ...makeComponentProps(),
  18690. ...makeRoundedProps(),
  18691. ...makeSizeProps(),
  18692. ...makeElevationProps()
  18693. }, 'VTimelineDivider');
  18694. const VTimelineDivider = genericComponent()({
  18695. name: 'VTimelineDivider',
  18696. props: makeVTimelineDividerProps(),
  18697. setup(props, _ref) {
  18698. let {
  18699. slots
  18700. } = _ref;
  18701. const {
  18702. sizeClasses,
  18703. sizeStyles
  18704. } = useSize(props, 'v-timeline-divider__dot');
  18705. const {
  18706. backgroundColorStyles,
  18707. backgroundColorClasses
  18708. } = useBackgroundColor(toRef(props, 'dotColor'));
  18709. const {
  18710. roundedClasses
  18711. } = useRounded(props, 'v-timeline-divider__dot');
  18712. const {
  18713. elevationClasses
  18714. } = useElevation(props);
  18715. const {
  18716. backgroundColorClasses: lineColorClasses,
  18717. backgroundColorStyles: lineColorStyles
  18718. } = useBackgroundColor(toRef(props, 'lineColor'));
  18719. useRender(() => createVNode("div", {
  18720. "class": ['v-timeline-divider', {
  18721. 'v-timeline-divider--fill-dot': props.fillDot
  18722. }, props.class],
  18723. "style": props.style
  18724. }, [createVNode("div", {
  18725. "class": ['v-timeline-divider__before', lineColorClasses.value],
  18726. "style": lineColorStyles.value
  18727. }, null), !props.hideDot && createVNode("div", {
  18728. "key": "dot",
  18729. "class": ['v-timeline-divider__dot', elevationClasses.value, roundedClasses.value, sizeClasses.value],
  18730. "style": sizeStyles.value
  18731. }, [createVNode("div", {
  18732. "class": ['v-timeline-divider__inner-dot', backgroundColorClasses.value, roundedClasses.value],
  18733. "style": backgroundColorStyles.value
  18734. }, [!slots.default ? createVNode(VIcon, {
  18735. "key": "icon",
  18736. "color": props.iconColor,
  18737. "icon": props.icon,
  18738. "size": props.size
  18739. }, null) : createVNode(VDefaultsProvider, {
  18740. "key": "icon-defaults",
  18741. "disabled": !props.icon,
  18742. "defaults": {
  18743. VIcon: {
  18744. color: props.iconColor,
  18745. icon: props.icon,
  18746. size: props.size
  18747. }
  18748. }
  18749. }, slots.default)])]), createVNode("div", {
  18750. "class": ['v-timeline-divider__after', lineColorClasses.value],
  18751. "style": lineColorStyles.value
  18752. }, null)]));
  18753. return {};
  18754. }
  18755. });
  18756. // Types
  18757. const makeVTimelineItemProps = propsFactory({
  18758. density: String,
  18759. dotColor: String,
  18760. fillDot: Boolean,
  18761. hideDot: Boolean,
  18762. hideOpposite: {
  18763. type: Boolean,
  18764. default: undefined
  18765. },
  18766. icon: IconValue,
  18767. iconColor: String,
  18768. lineInset: [Number, String],
  18769. ...makeComponentProps(),
  18770. ...makeDimensionProps(),
  18771. ...makeElevationProps(),
  18772. ...makeRoundedProps(),
  18773. ...makeSizeProps(),
  18774. ...makeTagProps()
  18775. }, 'VTimelineItem');
  18776. const VTimelineItem = genericComponent()({
  18777. name: 'VTimelineItem',
  18778. props: makeVTimelineItemProps(),
  18779. setup(props, _ref) {
  18780. let {
  18781. slots
  18782. } = _ref;
  18783. const {
  18784. dimensionStyles
  18785. } = useDimension(props);
  18786. const dotSize = shallowRef(0);
  18787. const dotRef = ref();
  18788. watch(dotRef, newValue => {
  18789. if (!newValue) return;
  18790. dotSize.value = newValue.$el.querySelector('.v-timeline-divider__dot')?.getBoundingClientRect().width ?? 0;
  18791. }, {
  18792. flush: 'post'
  18793. });
  18794. useRender(() => createVNode("div", {
  18795. "class": ['v-timeline-item', {
  18796. 'v-timeline-item--fill-dot': props.fillDot
  18797. }, props.class],
  18798. "style": [{
  18799. '--v-timeline-dot-size': convertToUnit(dotSize.value),
  18800. '--v-timeline-line-inset': props.lineInset ? `calc(var(--v-timeline-dot-size) / 2 + ${convertToUnit(props.lineInset)})` : convertToUnit(0)
  18801. }, props.style]
  18802. }, [createVNode("div", {
  18803. "class": "v-timeline-item__body",
  18804. "style": dimensionStyles.value
  18805. }, [slots.default?.()]), createVNode(VTimelineDivider, {
  18806. "ref": dotRef,
  18807. "hideDot": props.hideDot,
  18808. "icon": props.icon,
  18809. "iconColor": props.iconColor,
  18810. "size": props.size,
  18811. "elevation": props.elevation,
  18812. "dotColor": props.dotColor,
  18813. "fillDot": props.fillDot,
  18814. "rounded": props.rounded
  18815. }, {
  18816. default: slots.icon
  18817. }), props.density !== 'compact' && createVNode("div", {
  18818. "class": "v-timeline-item__opposite"
  18819. }, [!props.hideOpposite && slots.opposite?.()])]));
  18820. return {};
  18821. }
  18822. });
  18823. const makeVToolbarItemsProps = propsFactory({
  18824. ...makeComponentProps(),
  18825. ...makeVariantProps({
  18826. variant: 'text'
  18827. })
  18828. }, 'VToolbarItems');
  18829. const VToolbarItems = genericComponent()({
  18830. name: 'VToolbarItems',
  18831. props: makeVToolbarItemsProps(),
  18832. setup(props, _ref) {
  18833. let {
  18834. slots
  18835. } = _ref;
  18836. provideDefaults({
  18837. VBtn: {
  18838. color: toRef(props, 'color'),
  18839. height: 'inherit',
  18840. variant: toRef(props, 'variant')
  18841. }
  18842. });
  18843. useRender(() => createVNode("div", {
  18844. "class": ['v-toolbar-items', props.class],
  18845. "style": props.style
  18846. }, [slots.default?.()]));
  18847. return {};
  18848. }
  18849. });
  18850. // Types
  18851. const makeVTooltipProps = propsFactory({
  18852. id: String,
  18853. text: String,
  18854. ...omit(makeVOverlayProps({
  18855. closeOnBack: false,
  18856. location: 'end',
  18857. locationStrategy: 'connected',
  18858. eager: true,
  18859. minWidth: 0,
  18860. offset: 10,
  18861. openOnClick: false,
  18862. openOnHover: true,
  18863. origin: 'auto',
  18864. scrim: false,
  18865. scrollStrategy: 'reposition',
  18866. transition: false
  18867. }), ['absolute', 'persistent'])
  18868. }, 'VTooltip');
  18869. const VTooltip = genericComponent()({
  18870. name: 'VTooltip',
  18871. props: makeVTooltipProps(),
  18872. emits: {
  18873. 'update:modelValue': value => true
  18874. },
  18875. setup(props, _ref) {
  18876. let {
  18877. slots
  18878. } = _ref;
  18879. const isActive = useProxiedModel(props, 'modelValue');
  18880. const {
  18881. scopeId
  18882. } = useScopeId();
  18883. const uid = getUid();
  18884. const id = computed(() => props.id || `v-tooltip-${uid}`);
  18885. const overlay = ref();
  18886. const location = computed(() => {
  18887. return props.location.split(' ').length > 1 ? props.location : props.location + ' center';
  18888. });
  18889. const origin = computed(() => {
  18890. return props.origin === 'auto' || props.origin === 'overlap' || props.origin.split(' ').length > 1 || props.location.split(' ').length > 1 ? props.origin : props.origin + ' center';
  18891. });
  18892. const transition = computed(() => {
  18893. if (props.transition) return props.transition;
  18894. return isActive.value ? 'scale-transition' : 'fade-transition';
  18895. });
  18896. const activatorProps = computed(() => mergeProps({
  18897. 'aria-describedby': id.value
  18898. }, props.activatorProps));
  18899. useRender(() => {
  18900. const [overlayProps] = VOverlay.filterProps(props);
  18901. return createVNode(VOverlay, mergeProps({
  18902. "ref": overlay,
  18903. "class": ['v-tooltip', props.class],
  18904. "style": props.style,
  18905. "id": id.value
  18906. }, overlayProps, {
  18907. "modelValue": isActive.value,
  18908. "onUpdate:modelValue": $event => isActive.value = $event,
  18909. "transition": transition.value,
  18910. "absolute": true,
  18911. "location": location.value,
  18912. "origin": origin.value,
  18913. "persistent": true,
  18914. "role": "tooltip",
  18915. "activatorProps": activatorProps.value,
  18916. "_disableGlobalStack": true
  18917. }, scopeId), {
  18918. activator: slots.activator,
  18919. default: function () {
  18920. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  18921. args[_key] = arguments[_key];
  18922. }
  18923. return slots.default?.(...args) ?? props.text;
  18924. }
  18925. });
  18926. });
  18927. return forwardRefs({}, overlay);
  18928. }
  18929. });
  18930. // Composables
  18931. const VValidation = genericComponent()({
  18932. name: 'VValidation',
  18933. props: makeValidationProps(),
  18934. emits: {
  18935. 'update:modelValue': val => true
  18936. },
  18937. setup(props, _ref) {
  18938. let {
  18939. slots
  18940. } = _ref;
  18941. const validation = useValidation(props, 'validation');
  18942. return () => slots.default?.(validation);
  18943. }
  18944. });
  18945. // Types
  18946. const makeVBottomSheetProps = propsFactory({
  18947. inset: Boolean,
  18948. ...makeVDialogProps({
  18949. contentClass: 'v-bottom-sheet__content',
  18950. transition: 'bottom-sheet-transition'
  18951. })
  18952. }, 'VBottomSheet');
  18953. const VBottomSheet = genericComponent()({
  18954. name: 'VBottomSheet',
  18955. props: makeVBottomSheetProps(),
  18956. emits: {
  18957. 'update:modelValue': value => true
  18958. },
  18959. setup(props, _ref) {
  18960. let {
  18961. slots
  18962. } = _ref;
  18963. const isActive = useProxiedModel(props, 'modelValue');
  18964. useRender(() => {
  18965. const [dialogProps] = VDialog.filterProps(props);
  18966. return createVNode(VDialog, mergeProps(dialogProps, {
  18967. "modelValue": isActive.value,
  18968. "onUpdate:modelValue": $event => isActive.value = $event,
  18969. "class": ['v-bottom-sheet', {
  18970. 'v-bottom-sheet--inset': props.inset
  18971. }]
  18972. }), slots);
  18973. });
  18974. return {};
  18975. }
  18976. });
  18977. // Utilities
  18978. // Types
  18979. // Composables
  18980. const makeDataIteratorItemsProps = propsFactory({
  18981. items: {
  18982. type: Array,
  18983. default: () => []
  18984. },
  18985. itemValue: {
  18986. type: [String, Array, Function],
  18987. default: 'id'
  18988. },
  18989. itemSelectable: {
  18990. type: [String, Array, Function],
  18991. default: null
  18992. },
  18993. returnObject: Boolean
  18994. }, 'DataIterator-items');
  18995. function transformItem$1(props, item) {
  18996. const value = props.returnObject ? item : getPropertyFromItem(item, props.itemValue);
  18997. const selectable = getPropertyFromItem(item, props.itemSelectable, true);
  18998. return {
  18999. type: 'item',
  19000. value,
  19001. selectable,
  19002. raw: item
  19003. };
  19004. }
  19005. function transformItems$1(props, items) {
  19006. const array = [];
  19007. for (const item of items) {
  19008. array.push(transformItem$1(props, item));
  19009. }
  19010. return array;
  19011. }
  19012. function useDataIteratorItems(props) {
  19013. const items = computed(() => transformItems$1(props, props.items));
  19014. return {
  19015. items
  19016. };
  19017. }
  19018. // Composables
  19019. // Types
  19020. const makeDataTableExpandProps = propsFactory({
  19021. expandOnClick: Boolean,
  19022. showExpand: Boolean,
  19023. expanded: {
  19024. type: Array,
  19025. default: () => []
  19026. }
  19027. }, 'DataTable-expand');
  19028. const VDataTableExpandedKey = Symbol.for('vuetify:datatable:expanded');
  19029. function provideExpanded(props) {
  19030. const expandOnClick = toRef(props, 'expandOnClick');
  19031. const expanded = useProxiedModel(props, 'expanded', props.expanded, v => {
  19032. return new Set(v);
  19033. }, v => {
  19034. return [...v.values()];
  19035. });
  19036. function expand(item, value) {
  19037. const newExpanded = new Set(expanded.value);
  19038. if (!value) {
  19039. newExpanded.delete(item.value);
  19040. } else {
  19041. newExpanded.add(item.value);
  19042. }
  19043. expanded.value = newExpanded;
  19044. }
  19045. function isExpanded(item) {
  19046. return expanded.value.has(item.value);
  19047. }
  19048. function toggleExpand(item) {
  19049. expand(item, !isExpanded(item));
  19050. }
  19051. const data = {
  19052. expand,
  19053. expanded,
  19054. expandOnClick,
  19055. isExpanded,
  19056. toggleExpand
  19057. };
  19058. provide(VDataTableExpandedKey, data);
  19059. return data;
  19060. }
  19061. function useExpanded() {
  19062. const data = inject$1(VDataTableExpandedKey);
  19063. if (!data) throw new Error('foo');
  19064. return data;
  19065. }
  19066. // Composables
  19067. // Types
  19068. const makeDataTableGroupProps = propsFactory({
  19069. groupBy: {
  19070. type: Array,
  19071. default: () => []
  19072. }
  19073. }, 'DataTable-group');
  19074. const VDataTableGroupSymbol = Symbol.for('vuetify:data-table-group');
  19075. function createGroupBy(props) {
  19076. const groupBy = useProxiedModel(props, 'groupBy');
  19077. return {
  19078. groupBy
  19079. };
  19080. }
  19081. function provideGroupBy(options) {
  19082. const {
  19083. groupBy,
  19084. sortBy
  19085. } = options;
  19086. const opened = ref(new Set());
  19087. const sortByWithGroups = computed(() => {
  19088. return groupBy.value.map(val => ({
  19089. ...val,
  19090. order: val.order ?? false
  19091. })).concat(sortBy.value);
  19092. });
  19093. function isGroupOpen(group) {
  19094. return opened.value.has(group.id);
  19095. }
  19096. function toggleGroup(group) {
  19097. const newOpened = new Set(opened.value);
  19098. if (!isGroupOpen(group)) newOpened.add(group.id);else newOpened.delete(group.id);
  19099. opened.value = newOpened;
  19100. }
  19101. function extractRows(items) {
  19102. function dive(group) {
  19103. const arr = [];
  19104. for (const item of group.items) {
  19105. if ('type' in item && item.type === 'group') {
  19106. arr.push(...dive(item));
  19107. } else {
  19108. arr.push(item);
  19109. }
  19110. }
  19111. return arr;
  19112. }
  19113. return dive({
  19114. type: 'group',
  19115. items,
  19116. id: 'dummy',
  19117. key: 'dummy',
  19118. value: 'dummy',
  19119. depth: 0
  19120. });
  19121. }
  19122. // onBeforeMount(() => {
  19123. // for (const key of groupedItems.value.keys()) {
  19124. // opened.value.add(key)
  19125. // }
  19126. // })
  19127. const data = {
  19128. sortByWithGroups,
  19129. toggleGroup,
  19130. opened,
  19131. groupBy,
  19132. extractRows,
  19133. isGroupOpen
  19134. };
  19135. provide(VDataTableGroupSymbol, data);
  19136. return data;
  19137. }
  19138. function useGroupBy() {
  19139. const data = inject$1(VDataTableGroupSymbol);
  19140. if (!data) throw new Error('Missing group!');
  19141. return data;
  19142. }
  19143. function groupItemsByProperty(items, groupBy) {
  19144. if (!items.length) return [];
  19145. const groups = new Map();
  19146. for (const item of items) {
  19147. const value = getObjectValueByPath(item.raw, groupBy);
  19148. if (!groups.has(value)) {
  19149. groups.set(value, []);
  19150. }
  19151. groups.get(value).push(item);
  19152. }
  19153. return groups;
  19154. }
  19155. function groupItems(items, groupBy) {
  19156. let depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
  19157. let prefix = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'root';
  19158. if (!groupBy.length) return [];
  19159. const groupedItems = groupItemsByProperty(items, groupBy[0]);
  19160. const groups = [];
  19161. const rest = groupBy.slice(1);
  19162. groupedItems.forEach((items, value) => {
  19163. const key = groupBy[0];
  19164. const id = `${prefix}_${key}_${value}`;
  19165. groups.push({
  19166. depth,
  19167. id,
  19168. key,
  19169. value,
  19170. items: rest.length ? groupItems(items, rest, depth + 1, id) : items,
  19171. type: 'group'
  19172. });
  19173. });
  19174. return groups;
  19175. }
  19176. function flattenItems(items, opened) {
  19177. const flatItems = [];
  19178. for (const item of items) {
  19179. // TODO: make this better
  19180. if ('type' in item && item.type === 'group') {
  19181. if (item.value != null) {
  19182. flatItems.push(item);
  19183. }
  19184. if (opened.has(item.id) || item.value == null) {
  19185. flatItems.push(...flattenItems(item.items, opened));
  19186. }
  19187. } else {
  19188. flatItems.push(item);
  19189. }
  19190. }
  19191. return flatItems;
  19192. }
  19193. function useGroupedItems(items, groupBy, opened) {
  19194. const flatItems = computed(() => {
  19195. if (!groupBy.value.length) return items.value;
  19196. const groupedItems = groupItems(items.value, groupBy.value.map(item => item.key));
  19197. return flattenItems(groupedItems, opened.value);
  19198. });
  19199. return {
  19200. flatItems
  19201. };
  19202. }
  19203. // Utilities
  19204. // Types
  19205. function useOptions(_ref) {
  19206. let {
  19207. page,
  19208. itemsPerPage,
  19209. sortBy,
  19210. groupBy,
  19211. search
  19212. } = _ref;
  19213. const vm = getCurrentInstance('VDataTable');
  19214. const options = computed(() => ({
  19215. page: page.value,
  19216. itemsPerPage: itemsPerPage.value,
  19217. sortBy: sortBy.value,
  19218. groupBy: groupBy.value,
  19219. search: search.value
  19220. }));
  19221. // Reset page when searching
  19222. watch(() => search?.value, () => {
  19223. page.value = 1;
  19224. });
  19225. let oldOptions = null;
  19226. watch(options, () => {
  19227. if (deepEqual(oldOptions, options.value)) return;
  19228. vm.emit('update:options', options.value);
  19229. oldOptions = options.value;
  19230. }, {
  19231. deep: true,
  19232. immediate: true
  19233. });
  19234. }
  19235. // Composables
  19236. // Types
  19237. const makeDataTablePaginateProps = propsFactory({
  19238. page: {
  19239. type: [Number, String],
  19240. default: 1
  19241. },
  19242. itemsPerPage: {
  19243. type: [Number, String],
  19244. default: 10
  19245. }
  19246. }, 'DataTable-paginate');
  19247. const VDataTablePaginationSymbol = Symbol.for('vuetify:data-table-pagination');
  19248. function createPagination(props) {
  19249. const page = useProxiedModel(props, 'page', undefined, value => +(value ?? 1));
  19250. const itemsPerPage = useProxiedModel(props, 'itemsPerPage', undefined, value => +(value ?? 10));
  19251. return {
  19252. page,
  19253. itemsPerPage
  19254. };
  19255. }
  19256. function providePagination(options) {
  19257. const {
  19258. page,
  19259. itemsPerPage,
  19260. itemsLength
  19261. } = options;
  19262. const startIndex = computed(() => {
  19263. if (itemsPerPage.value === -1) return 0;
  19264. return itemsPerPage.value * (page.value - 1);
  19265. });
  19266. const stopIndex = computed(() => {
  19267. if (itemsPerPage.value === -1) return itemsLength.value;
  19268. return Math.min(itemsLength.value, startIndex.value + itemsPerPage.value);
  19269. });
  19270. const pageCount = computed(() => {
  19271. if (itemsPerPage.value === -1 || itemsLength.value === 0) return 1;
  19272. return Math.ceil(itemsLength.value / itemsPerPage.value);
  19273. });
  19274. watchEffect(() => {
  19275. if (page.value > pageCount.value) {
  19276. page.value = pageCount.value;
  19277. }
  19278. });
  19279. function setItemsPerPage(value) {
  19280. itemsPerPage.value = value;
  19281. page.value = 1;
  19282. }
  19283. function nextPage() {
  19284. page.value = clamp(page.value + 1, 1, pageCount.value);
  19285. }
  19286. function prevPage() {
  19287. page.value = clamp(page.value - 1, 1, pageCount.value);
  19288. }
  19289. function setPage(value) {
  19290. page.value = clamp(value, 1, pageCount.value);
  19291. }
  19292. const data = {
  19293. page,
  19294. itemsPerPage,
  19295. startIndex,
  19296. stopIndex,
  19297. pageCount,
  19298. itemsLength,
  19299. nextPage,
  19300. prevPage,
  19301. setPage,
  19302. setItemsPerPage
  19303. };
  19304. provide(VDataTablePaginationSymbol, data);
  19305. return data;
  19306. }
  19307. function usePagination() {
  19308. const data = inject$1(VDataTablePaginationSymbol);
  19309. if (!data) throw new Error('Missing pagination!');
  19310. return data;
  19311. }
  19312. function usePaginatedItems(options) {
  19313. const {
  19314. items,
  19315. startIndex,
  19316. stopIndex,
  19317. itemsPerPage
  19318. } = options;
  19319. const paginatedItems = computed(() => {
  19320. if (itemsPerPage.value <= 0) return items.value;
  19321. return items.value.slice(startIndex.value, stopIndex.value);
  19322. });
  19323. return {
  19324. paginatedItems
  19325. };
  19326. }
  19327. // Composables
  19328. // Types
  19329. const singleSelectStrategy = {
  19330. showSelectAll: false,
  19331. allSelected: () => [],
  19332. select: _ref => {
  19333. let {
  19334. items,
  19335. value
  19336. } = _ref;
  19337. return new Set(value ? [items[0]?.value] : []);
  19338. },
  19339. selectAll: _ref2 => {
  19340. let {
  19341. selected
  19342. } = _ref2;
  19343. return selected;
  19344. }
  19345. };
  19346. const pageSelectStrategy = {
  19347. showSelectAll: true,
  19348. allSelected: _ref3 => {
  19349. let {
  19350. currentPage
  19351. } = _ref3;
  19352. return currentPage;
  19353. },
  19354. select: _ref4 => {
  19355. let {
  19356. items,
  19357. value,
  19358. selected
  19359. } = _ref4;
  19360. for (const item of items) {
  19361. if (value) selected.add(item.value);else selected.delete(item.value);
  19362. }
  19363. return selected;
  19364. },
  19365. selectAll: _ref5 => {
  19366. let {
  19367. value,
  19368. currentPage,
  19369. selected
  19370. } = _ref5;
  19371. return pageSelectStrategy.select({
  19372. items: currentPage,
  19373. value,
  19374. selected
  19375. });
  19376. }
  19377. };
  19378. const allSelectStrategy = {
  19379. showSelectAll: true,
  19380. allSelected: _ref6 => {
  19381. let {
  19382. allItems
  19383. } = _ref6;
  19384. return allItems;
  19385. },
  19386. select: _ref7 => {
  19387. let {
  19388. items,
  19389. value,
  19390. selected
  19391. } = _ref7;
  19392. for (const item of items) {
  19393. if (value) selected.add(item.value);else selected.delete(item.value);
  19394. }
  19395. return selected;
  19396. },
  19397. selectAll: _ref8 => {
  19398. let {
  19399. value,
  19400. allItems,
  19401. selected
  19402. } = _ref8;
  19403. return allSelectStrategy.select({
  19404. items: allItems,
  19405. value,
  19406. selected
  19407. });
  19408. }
  19409. };
  19410. const makeDataTableSelectProps = propsFactory({
  19411. showSelect: Boolean,
  19412. selectStrategy: {
  19413. type: [String, Object],
  19414. default: 'page'
  19415. },
  19416. modelValue: {
  19417. type: Array,
  19418. default: () => []
  19419. }
  19420. }, 'DataTable-select');
  19421. const VDataTableSelectionSymbol = Symbol.for('vuetify:data-table-selection');
  19422. function provideSelection(props, _ref9) {
  19423. let {
  19424. allItems,
  19425. currentPage
  19426. } = _ref9;
  19427. const selected = useProxiedModel(props, 'modelValue', props.modelValue, v => {
  19428. return new Set(v);
  19429. }, v => {
  19430. return [...v.values()];
  19431. });
  19432. const allSelectable = computed(() => allItems.value.filter(item => item.selectable));
  19433. const currentPageSelectable = computed(() => currentPage.value.filter(item => item.selectable));
  19434. const selectStrategy = computed(() => {
  19435. if (typeof props.selectStrategy === 'object') return props.selectStrategy;
  19436. switch (props.selectStrategy) {
  19437. case 'single':
  19438. return singleSelectStrategy;
  19439. case 'all':
  19440. return allSelectStrategy;
  19441. case 'page':
  19442. default:
  19443. return pageSelectStrategy;
  19444. }
  19445. });
  19446. function isSelected(items) {
  19447. return wrapInArray(items).every(item => selected.value.has(item.value));
  19448. }
  19449. function isSomeSelected(items) {
  19450. return wrapInArray(items).some(item => selected.value.has(item.value));
  19451. }
  19452. function select(items, value) {
  19453. const newSelected = selectStrategy.value.select({
  19454. items,
  19455. value,
  19456. selected: new Set(selected.value)
  19457. });
  19458. selected.value = newSelected;
  19459. }
  19460. function toggleSelect(item) {
  19461. select([item], !isSelected([item]));
  19462. }
  19463. function selectAll(value) {
  19464. const newSelected = selectStrategy.value.selectAll({
  19465. value,
  19466. allItems: allSelectable.value,
  19467. currentPage: currentPageSelectable.value,
  19468. selected: new Set(selected.value)
  19469. });
  19470. selected.value = newSelected;
  19471. }
  19472. const someSelected = computed(() => selected.value.size > 0);
  19473. const allSelected = computed(() => {
  19474. const items = selectStrategy.value.allSelected({
  19475. allItems: allSelectable.value,
  19476. currentPage: currentPageSelectable.value
  19477. });
  19478. return isSelected(items);
  19479. });
  19480. const data = {
  19481. toggleSelect,
  19482. select,
  19483. selectAll,
  19484. isSelected,
  19485. isSomeSelected,
  19486. someSelected,
  19487. allSelected,
  19488. showSelectAll: selectStrategy.value.showSelectAll
  19489. };
  19490. provide(VDataTableSelectionSymbol, data);
  19491. return data;
  19492. }
  19493. function useSelection() {
  19494. const data = inject$1(VDataTableSelectionSymbol);
  19495. if (!data) throw new Error('Missing selection!');
  19496. return data;
  19497. }
  19498. // Composables
  19499. // Types
  19500. const makeDataTableSortProps = propsFactory({
  19501. sortBy: {
  19502. type: Array,
  19503. default: () => []
  19504. },
  19505. customKeySort: Object,
  19506. multiSort: Boolean,
  19507. mustSort: Boolean
  19508. }, 'DataTable-sort');
  19509. const VDataTableSortSymbol = Symbol.for('vuetify:data-table-sort');
  19510. function createSort(props) {
  19511. const sortBy = useProxiedModel(props, 'sortBy');
  19512. const mustSort = toRef(props, 'mustSort');
  19513. const multiSort = toRef(props, 'multiSort');
  19514. return {
  19515. sortBy,
  19516. mustSort,
  19517. multiSort
  19518. };
  19519. }
  19520. function provideSort(options) {
  19521. const {
  19522. sortBy,
  19523. mustSort,
  19524. multiSort,
  19525. page
  19526. } = options;
  19527. const toggleSort = column => {
  19528. let newSortBy = sortBy.value.map(x => ({
  19529. ...x
  19530. })) ?? [];
  19531. const item = newSortBy.find(x => x.key === column.key);
  19532. if (!item) {
  19533. if (multiSort.value) newSortBy = [...newSortBy, {
  19534. key: column.key,
  19535. order: 'asc'
  19536. }];else newSortBy = [{
  19537. key: column.key,
  19538. order: 'asc'
  19539. }];
  19540. } else if (item.order === 'desc') {
  19541. if (mustSort.value) {
  19542. item.order = 'asc';
  19543. } else {
  19544. newSortBy = newSortBy.filter(x => x.key !== column.key);
  19545. }
  19546. } else {
  19547. item.order = 'desc';
  19548. }
  19549. sortBy.value = newSortBy;
  19550. if (page) page.value = 1;
  19551. };
  19552. function isSorted(column) {
  19553. return !!sortBy.value.find(item => item.key === column.key);
  19554. }
  19555. const data = {
  19556. sortBy,
  19557. toggleSort,
  19558. isSorted
  19559. };
  19560. provide(VDataTableSortSymbol, data);
  19561. return data;
  19562. }
  19563. function useSort() {
  19564. const data = inject$1(VDataTableSortSymbol);
  19565. if (!data) throw new Error('Missing sort!');
  19566. return data;
  19567. }
  19568. function useSortedItems(props, items, sortBy) {
  19569. const locale = useLocale();
  19570. const sortedItems = computed(() => {
  19571. if (!sortBy.value.length) return items.value;
  19572. return sortItems(items.value, sortBy.value, locale.current.value, props.customKeySort);
  19573. });
  19574. return {
  19575. sortedItems
  19576. };
  19577. }
  19578. function sortItems(items, sortByItems, locale, customSorters) {
  19579. const stringCollator = new Intl.Collator(locale, {
  19580. sensitivity: 'accent',
  19581. usage: 'sort'
  19582. });
  19583. return [...items].sort((a, b) => {
  19584. for (let i = 0; i < sortByItems.length; i++) {
  19585. const sortKey = sortByItems[i].key;
  19586. const sortOrder = sortByItems[i].order ?? 'asc';
  19587. if (sortOrder === false) continue;
  19588. let sortA = getObjectValueByPath(a.raw, sortKey);
  19589. let sortB = getObjectValueByPath(b.raw, sortKey);
  19590. if (sortOrder === 'desc') {
  19591. [sortA, sortB] = [sortB, sortA];
  19592. }
  19593. if (customSorters?.[sortKey]) {
  19594. const customResult = customSorters[sortKey](sortA, sortB);
  19595. if (!customResult) continue;
  19596. return customResult;
  19597. }
  19598. // Dates should be compared numerically
  19599. if (sortA instanceof Date && sortB instanceof Date) {
  19600. return sortA.getTime() - sortB.getTime();
  19601. }
  19602. [sortA, sortB] = [sortA, sortB].map(s => s != null ? s.toString().toLocaleLowerCase() : s);
  19603. if (sortA !== sortB) {
  19604. if (isEmpty(sortA) && isEmpty(sortB)) return 0;
  19605. if (isEmpty(sortA)) return -1;
  19606. if (isEmpty(sortB)) return 1;
  19607. if (!isNaN(sortA) && !isNaN(sortB)) return Number(sortA) - Number(sortB);
  19608. return stringCollator.compare(sortA, sortB);
  19609. }
  19610. }
  19611. return 0;
  19612. });
  19613. }
  19614. // Types
  19615. const makeVDataIteratorProps = propsFactory({
  19616. search: String,
  19617. loading: Boolean,
  19618. ...makeComponentProps(),
  19619. ...makeDataIteratorItemsProps(),
  19620. ...makeDataTableSelectProps(),
  19621. ...makeDataTableSortProps(),
  19622. ...makeDataTablePaginateProps({
  19623. itemsPerPage: 5
  19624. }),
  19625. ...makeDataTableExpandProps(),
  19626. ...makeDataTableGroupProps(),
  19627. ...makeFilterProps(),
  19628. ...makeTagProps()
  19629. }, 'VDataIterator');
  19630. const VDataIterator = genericComponent()({
  19631. name: 'VDataIterator',
  19632. props: makeVDataIteratorProps(),
  19633. emits: {
  19634. 'update:modelValue': value => true,
  19635. 'update:groupBy': value => true,
  19636. 'update:page': value => true,
  19637. 'update:itemsPerPage': value => true,
  19638. 'update:sortBy': value => true,
  19639. 'update:options': value => true,
  19640. 'update:expanded': value => true
  19641. },
  19642. setup(props, _ref) {
  19643. let {
  19644. slots
  19645. } = _ref;
  19646. const groupBy = useProxiedModel(props, 'groupBy');
  19647. const search = toRef(props, 'search');
  19648. const {
  19649. items
  19650. } = useDataIteratorItems(props);
  19651. const {
  19652. filteredItems
  19653. } = useFilter(props, items, search, {
  19654. transform: item => item.raw
  19655. });
  19656. const {
  19657. sortBy,
  19658. multiSort,
  19659. mustSort
  19660. } = createSort(props);
  19661. const {
  19662. page,
  19663. itemsPerPage
  19664. } = createPagination(props);
  19665. const {
  19666. toggleSort
  19667. } = provideSort({
  19668. sortBy,
  19669. multiSort,
  19670. mustSort,
  19671. page
  19672. });
  19673. const {
  19674. sortByWithGroups,
  19675. opened,
  19676. extractRows,
  19677. isGroupOpen,
  19678. toggleGroup
  19679. } = provideGroupBy({
  19680. groupBy,
  19681. sortBy
  19682. });
  19683. const {
  19684. sortedItems
  19685. } = useSortedItems(props, filteredItems, sortByWithGroups);
  19686. const {
  19687. flatItems
  19688. } = useGroupedItems(sortedItems, groupBy, opened);
  19689. const itemsLength = computed(() => flatItems.value.length);
  19690. const {
  19691. startIndex,
  19692. stopIndex,
  19693. pageCount,
  19694. prevPage,
  19695. nextPage,
  19696. setItemsPerPage,
  19697. setPage
  19698. } = providePagination({
  19699. page,
  19700. itemsPerPage,
  19701. itemsLength
  19702. });
  19703. const {
  19704. paginatedItems
  19705. } = usePaginatedItems({
  19706. items: flatItems,
  19707. startIndex,
  19708. stopIndex,
  19709. itemsPerPage
  19710. });
  19711. const paginatedItemsWithoutGroups = computed(() => extractRows(paginatedItems.value));
  19712. const {
  19713. isSelected,
  19714. select,
  19715. selectAll,
  19716. toggleSelect
  19717. } = provideSelection(props, {
  19718. allItems: items,
  19719. currentPage: paginatedItemsWithoutGroups
  19720. });
  19721. const {
  19722. isExpanded,
  19723. toggleExpand
  19724. } = provideExpanded(props);
  19725. useOptions({
  19726. page,
  19727. itemsPerPage,
  19728. sortBy,
  19729. groupBy,
  19730. search
  19731. });
  19732. const slotProps = computed(() => ({
  19733. page: page.value,
  19734. itemsPerPage: itemsPerPage.value,
  19735. sortBy: sortBy.value,
  19736. pageCount: pageCount.value,
  19737. toggleSort,
  19738. prevPage,
  19739. nextPage,
  19740. setPage,
  19741. setItemsPerPage,
  19742. isSelected,
  19743. select,
  19744. selectAll,
  19745. toggleSelect,
  19746. isExpanded,
  19747. toggleExpand,
  19748. isGroupOpen,
  19749. toggleGroup,
  19750. items: paginatedItemsWithoutGroups.value,
  19751. groupedItems: paginatedItems.value
  19752. }));
  19753. useRender(() => createVNode(props.tag, {
  19754. "class": ['v-data-iterator', props.class],
  19755. "style": props.style
  19756. }, {
  19757. default: () => [slots.header?.(slotProps.value), !paginatedItems.value.length ? slots['no-data']?.() : slots.default?.(slotProps.value), slots.footer?.(slotProps.value)]
  19758. }));
  19759. return {};
  19760. }
  19761. });
  19762. // Types
  19763. const makeVDataTableFooterProps = propsFactory({
  19764. prevIcon: {
  19765. type: String,
  19766. default: '$prev'
  19767. },
  19768. nextIcon: {
  19769. type: String,
  19770. default: '$next'
  19771. },
  19772. firstIcon: {
  19773. type: String,
  19774. default: '$first'
  19775. },
  19776. lastIcon: {
  19777. type: String,
  19778. default: '$last'
  19779. },
  19780. itemsPerPageText: {
  19781. type: String,
  19782. default: '$vuetify.dataFooter.itemsPerPageText'
  19783. },
  19784. pageText: {
  19785. type: String,
  19786. default: '$vuetify.dataFooter.pageText'
  19787. },
  19788. firstPageLabel: {
  19789. type: String,
  19790. default: '$vuetify.dataFooter.firstPage'
  19791. },
  19792. prevPageLabel: {
  19793. type: String,
  19794. default: '$vuetify.dataFooter.prevPage'
  19795. },
  19796. nextPageLabel: {
  19797. type: String,
  19798. default: '$vuetify.dataFooter.nextPage'
  19799. },
  19800. lastPageLabel: {
  19801. type: String,
  19802. default: '$vuetify.dataFooter.lastPage'
  19803. },
  19804. itemsPerPageOptions: {
  19805. type: Array,
  19806. default: () => [{
  19807. value: 10,
  19808. title: '10'
  19809. }, {
  19810. value: 25,
  19811. title: '25'
  19812. }, {
  19813. value: 50,
  19814. title: '50'
  19815. }, {
  19816. value: 100,
  19817. title: '100'
  19818. }, {
  19819. value: -1,
  19820. title: '$vuetify.dataFooter.itemsPerPageAll'
  19821. }]
  19822. },
  19823. showCurrentPage: Boolean
  19824. }, 'VDataTableFooter');
  19825. const VDataTableFooter = genericComponent()({
  19826. name: 'VDataTableFooter',
  19827. props: makeVDataTableFooterProps(),
  19828. setup(props, _ref) {
  19829. let {
  19830. slots
  19831. } = _ref;
  19832. const {
  19833. t
  19834. } = useLocale();
  19835. const {
  19836. page,
  19837. pageCount,
  19838. startIndex,
  19839. stopIndex,
  19840. itemsLength,
  19841. itemsPerPage,
  19842. setItemsPerPage
  19843. } = usePagination();
  19844. const itemsPerPageOptions = computed(() => props.itemsPerPageOptions.map(option => ({
  19845. ...option,
  19846. title: t(option.title)
  19847. })));
  19848. return () => createVNode("div", {
  19849. "class": "v-data-table-footer"
  19850. }, [slots.prepend?.(), createVNode("div", {
  19851. "class": "v-data-table-footer__items-per-page"
  19852. }, [createVNode("span", null, [t(props.itemsPerPageText)]), createVNode(VSelect, {
  19853. "items": itemsPerPageOptions.value,
  19854. "modelValue": itemsPerPage.value,
  19855. "onUpdate:modelValue": v => setItemsPerPage(Number(v)),
  19856. "density": "compact",
  19857. "variant": "outlined",
  19858. "hide-details": true
  19859. }, null)]), createVNode("div", {
  19860. "class": "v-data-table-footer__info"
  19861. }, [createVNode("div", null, [t(props.pageText, !itemsLength.value ? 0 : startIndex.value + 1, stopIndex.value, itemsLength.value)])]), createVNode("div", {
  19862. "class": "v-data-table-footer__pagination"
  19863. }, [createVNode(VBtn, {
  19864. "icon": props.firstIcon,
  19865. "variant": "plain",
  19866. "onClick": () => page.value = 1,
  19867. "disabled": page.value === 1,
  19868. "aria-label": t(props.firstPageLabel)
  19869. }, null), createVNode(VBtn, {
  19870. "icon": props.prevIcon,
  19871. "variant": "plain",
  19872. "onClick": () => page.value = Math.max(1, page.value - 1),
  19873. "disabled": page.value === 1,
  19874. "aria-label": t(props.prevPageLabel)
  19875. }, null), props.showCurrentPage && createVNode("span", {
  19876. "key": "page",
  19877. "class": "v-data-table-footer__page"
  19878. }, [page.value]), createVNode(VBtn, {
  19879. "icon": props.nextIcon,
  19880. "variant": "plain",
  19881. "onClick": () => page.value = Math.min(pageCount.value, page.value + 1),
  19882. "disabled": page.value === pageCount.value,
  19883. "aria-label": t(props.nextPageLabel)
  19884. }, null), createVNode(VBtn, {
  19885. "icon": props.lastIcon,
  19886. "variant": "plain",
  19887. "onClick": () => page.value = pageCount.value,
  19888. "disabled": page.value === pageCount.value,
  19889. "aria-label": t(props.lastPageLabel)
  19890. }, null)])]);
  19891. }
  19892. });
  19893. // Types
  19894. const VDataTableColumn = defineFunctionalComponent({
  19895. align: {
  19896. type: String,
  19897. default: 'start'
  19898. },
  19899. fixed: Boolean,
  19900. fixedOffset: [Number, String],
  19901. height: [Number, String],
  19902. lastFixed: Boolean,
  19903. noPadding: Boolean,
  19904. tag: String,
  19905. width: [Number, String]
  19906. }, (props, _ref) => {
  19907. let {
  19908. slots,
  19909. attrs
  19910. } = _ref;
  19911. const Tag = props.tag ?? 'td';
  19912. return createVNode(Tag, mergeProps({
  19913. "class": ['v-data-table__td', {
  19914. 'v-data-table-column--fixed': props.fixed,
  19915. 'v-data-table-column--last-fixed': props.lastFixed,
  19916. 'v-data-table-column--no-padding': props.noPadding
  19917. }, `v-data-table-column--align-${props.align}`],
  19918. "style": {
  19919. height: convertToUnit(props.height),
  19920. width: convertToUnit(props.width),
  19921. left: convertToUnit(props.fixedOffset || null)
  19922. }
  19923. }, attrs), {
  19924. default: () => [slots.default?.()]
  19925. });
  19926. });
  19927. // Utilities
  19928. // Types
  19929. const makeDataTableHeaderProps = propsFactory({
  19930. headers: {
  19931. type: Array,
  19932. default: () => []
  19933. }
  19934. }, 'DataTable-header');
  19935. const VDataTableHeadersSymbol = Symbol.for('vuetify:data-table-headers');
  19936. function createHeaders(props, options) {
  19937. const headers = ref([]);
  19938. const columns = ref([]);
  19939. watchEffect(() => {
  19940. const wrapped = !props.headers.length ? [] : Array.isArray(props.headers[0]) ? props.headers : [props.headers];
  19941. const flat = wrapped.flatMap((row, index) => row.map(column => ({
  19942. column,
  19943. row: index
  19944. })));
  19945. const rowCount = wrapped.length;
  19946. const defaultHeader = {
  19947. title: '',
  19948. sortable: false
  19949. };
  19950. const defaultActionHeader = {
  19951. ...defaultHeader,
  19952. width: 48
  19953. };
  19954. if (options?.groupBy?.value.length) {
  19955. const index = flat.findIndex(_ref => {
  19956. let {
  19957. column
  19958. } = _ref;
  19959. return column.key === 'data-table-group';
  19960. });
  19961. if (index < 0) flat.unshift({
  19962. column: {
  19963. ...defaultHeader,
  19964. key: 'data-table-group',
  19965. title: 'Group',
  19966. rowspan: rowCount
  19967. },
  19968. row: 0
  19969. });else flat.splice(index, 1, {
  19970. column: {
  19971. ...defaultHeader,
  19972. ...flat[index].column
  19973. },
  19974. row: flat[index].row
  19975. });
  19976. }
  19977. if (options?.showSelect?.value) {
  19978. const index = flat.findIndex(_ref2 => {
  19979. let {
  19980. column
  19981. } = _ref2;
  19982. return column.key === 'data-table-select';
  19983. });
  19984. if (index < 0) flat.unshift({
  19985. column: {
  19986. ...defaultActionHeader,
  19987. key: 'data-table-select',
  19988. rowspan: rowCount
  19989. },
  19990. row: 0
  19991. });else flat.splice(index, 1, {
  19992. column: {
  19993. ...defaultActionHeader,
  19994. ...flat[index].column
  19995. },
  19996. row: flat[index].row
  19997. });
  19998. }
  19999. if (options?.showExpand?.value) {
  20000. const index = flat.findIndex(_ref3 => {
  20001. let {
  20002. column
  20003. } = _ref3;
  20004. return column.key === 'data-table-expand';
  20005. });
  20006. if (index < 0) flat.push({
  20007. column: {
  20008. ...defaultActionHeader,
  20009. key: 'data-table-expand',
  20010. rowspan: rowCount
  20011. },
  20012. row: 0
  20013. });else flat.splice(index, 1, {
  20014. column: {
  20015. ...defaultActionHeader,
  20016. ...flat[index].column
  20017. },
  20018. row: flat[index].row
  20019. });
  20020. }
  20021. const fixedRows = createRange(rowCount).map(() => []);
  20022. const fixedOffsets = createRange(rowCount).fill(0);
  20023. flat.forEach(_ref4 => {
  20024. let {
  20025. column,
  20026. row
  20027. } = _ref4;
  20028. let key = column.key;
  20029. if (key == null) {
  20030. consoleWarn('The header key value must not be null or undefined');
  20031. key = '';
  20032. }
  20033. for (let i = row; i <= row + (column.rowspan ?? 1) - 1; i++) {
  20034. fixedRows[i].push({
  20035. ...column,
  20036. key,
  20037. fixedOffset: fixedOffsets[i],
  20038. sortable: column.sortable ?? !!column.key
  20039. });
  20040. fixedOffsets[i] += Number(column.width ?? 0);
  20041. }
  20042. });
  20043. fixedRows.forEach(row => {
  20044. for (let i = row.length; i--; i >= 0) {
  20045. if (row[i].fixed) {
  20046. row[i].lastFixed = true;
  20047. return;
  20048. }
  20049. }
  20050. });
  20051. const seen = new Set();
  20052. headers.value = fixedRows.map(row => {
  20053. const filtered = [];
  20054. for (const column of row) {
  20055. if (!seen.has(column.key)) {
  20056. seen.add(column.key);
  20057. filtered.push(column);
  20058. }
  20059. }
  20060. return filtered;
  20061. });
  20062. columns.value = fixedRows.at(-1) ?? [];
  20063. });
  20064. const data = {
  20065. headers,
  20066. columns
  20067. };
  20068. provide(VDataTableHeadersSymbol, data);
  20069. return data;
  20070. }
  20071. function useHeaders() {
  20072. const data = inject$1(VDataTableHeadersSymbol);
  20073. if (!data) throw new Error('Missing headers!');
  20074. return data;
  20075. }
  20076. // Types
  20077. const makeVDataTableHeadersProps = propsFactory({
  20078. color: String,
  20079. sticky: Boolean,
  20080. multiSort: Boolean,
  20081. sortAscIcon: {
  20082. type: IconValue,
  20083. default: '$sortAsc'
  20084. },
  20085. sortDescIcon: {
  20086. type: IconValue,
  20087. default: '$sortDesc'
  20088. },
  20089. ...makeLoaderProps()
  20090. }, 'VDataTableHeaders');
  20091. const VDataTableHeaders = genericComponent()({
  20092. name: 'VDataTableHeaders',
  20093. props: makeVDataTableHeadersProps(),
  20094. setup(props, _ref) {
  20095. let {
  20096. slots,
  20097. emit
  20098. } = _ref;
  20099. const {
  20100. toggleSort,
  20101. sortBy,
  20102. isSorted
  20103. } = useSort();
  20104. const {
  20105. someSelected,
  20106. allSelected,
  20107. selectAll,
  20108. showSelectAll
  20109. } = useSelection();
  20110. const {
  20111. columns,
  20112. headers
  20113. } = useHeaders();
  20114. const {
  20115. loaderClasses
  20116. } = useLoader(props);
  20117. const getFixedStyles = (column, y) => {
  20118. if (!props.sticky && !column.fixed) return undefined;
  20119. return {
  20120. position: 'sticky',
  20121. zIndex: column.fixed ? 4 : props.sticky ? 3 : undefined,
  20122. // TODO: This needs to account for possible previous fixed columns.
  20123. left: column.fixed ? convertToUnit(column.fixedOffset) : undefined,
  20124. // TODO: This needs to account for possible row/colspan of previous columns
  20125. top: props.sticky ? `calc(var(--v-table-header-height) * ${y})` : undefined
  20126. };
  20127. };
  20128. function getSortIcon(column) {
  20129. const item = sortBy.value.find(item => item.key === column.key);
  20130. if (!item) return props.sortAscIcon;
  20131. return item.order === 'asc' ? props.sortAscIcon : props.sortDescIcon;
  20132. }
  20133. const {
  20134. backgroundColorClasses,
  20135. backgroundColorStyles
  20136. } = useBackgroundColor(props, 'color');
  20137. const slotProps = computed(() => ({
  20138. headers: headers.value,
  20139. columns: columns.value,
  20140. toggleSort,
  20141. isSorted,
  20142. sortBy: sortBy.value,
  20143. someSelected: someSelected.value,
  20144. allSelected: allSelected.value,
  20145. selectAll,
  20146. getSortIcon,
  20147. getFixedStyles
  20148. }));
  20149. const VDataTableHeaderCell = _ref2 => {
  20150. let {
  20151. column,
  20152. x,
  20153. y
  20154. } = _ref2;
  20155. const noPadding = column.key === 'data-table-select' || column.key === 'data-table-expand';
  20156. return createVNode(VDataTableColumn, {
  20157. "tag": "th",
  20158. "align": column.align,
  20159. "class": ['v-data-table__th', {
  20160. 'v-data-table__th--sortable': column.sortable,
  20161. 'v-data-table__th--sorted': isSorted(column)
  20162. }, loaderClasses.value],
  20163. "style": {
  20164. width: convertToUnit(column.width),
  20165. minWidth: convertToUnit(column.width),
  20166. ...getFixedStyles(column, y)
  20167. },
  20168. "colspan": column.colspan,
  20169. "rowspan": column.rowspan,
  20170. "onClick": column.sortable ? () => toggleSort(column) : undefined,
  20171. "lastFixed": column.lastFixed,
  20172. "noPadding": noPadding
  20173. }, {
  20174. default: () => {
  20175. const columnSlotName = `column.${column.key}`;
  20176. const columnSlotProps = {
  20177. column,
  20178. selectAll,
  20179. isSorted,
  20180. toggleSort,
  20181. sortBy: sortBy.value,
  20182. someSelected: someSelected.value,
  20183. allSelected: allSelected.value,
  20184. getSortIcon
  20185. };
  20186. if (slots[columnSlotName]) return slots[columnSlotName](columnSlotProps);
  20187. if (column.key === 'data-table-select') {
  20188. return slots['column.data-table-select']?.(columnSlotProps) ?? (showSelectAll && createVNode(VCheckboxBtn, {
  20189. "modelValue": allSelected.value,
  20190. "indeterminate": someSelected.value && !allSelected.value,
  20191. "onUpdate:modelValue": selectAll
  20192. }, null));
  20193. }
  20194. return createVNode("div", {
  20195. "class": "v-data-table-header__content"
  20196. }, [createVNode("span", null, [column.title]), column.sortable && createVNode(VIcon, {
  20197. "key": "icon",
  20198. "class": "v-data-table-header__sort-icon",
  20199. "icon": getSortIcon(column)
  20200. }, null), props.multiSort && isSorted(column) && createVNode("div", {
  20201. "key": "badge",
  20202. "class": ['v-data-table-header__sort-badge', ...backgroundColorClasses.value],
  20203. "style": backgroundColorStyles.value
  20204. }, [sortBy.value.findIndex(x => x.key === column.key) + 1])]);
  20205. }
  20206. });
  20207. };
  20208. useRender(() => {
  20209. return createVNode(Fragment, null, [slots.headers ? slots.headers(slotProps.value) : headers.value.map((row, y) => createVNode("tr", null, [row.map((column, x) => createVNode(VDataTableHeaderCell, {
  20210. "column": column,
  20211. "x": x,
  20212. "y": y
  20213. }, null))])), props.loading && createVNode("tr", {
  20214. "class": "v-data-table-progress"
  20215. }, [createVNode("th", {
  20216. "colspan": columns.value.length
  20217. }, [createVNode(LoaderSlot, {
  20218. "name": "v-data-table-progress",
  20219. "active": true,
  20220. "color": typeof props.loading === 'boolean' ? undefined : props.loading,
  20221. "indeterminate": true
  20222. }, {
  20223. default: slots.loader
  20224. })])])]);
  20225. });
  20226. }
  20227. });
  20228. // Types
  20229. const makeVDataTableGroupHeaderRowProps = propsFactory({
  20230. item: {
  20231. type: Object,
  20232. required: true
  20233. }
  20234. }, 'VDataTableGroupHeaderRow');
  20235. const VDataTableGroupHeaderRow = genericComponent()({
  20236. name: 'VDataTableGroupHeaderRow',
  20237. props: makeVDataTableGroupHeaderRowProps(),
  20238. setup(props, _ref) {
  20239. let {
  20240. slots
  20241. } = _ref;
  20242. const {
  20243. isGroupOpen,
  20244. toggleGroup,
  20245. extractRows
  20246. } = useGroupBy();
  20247. const {
  20248. isSelected,
  20249. isSomeSelected,
  20250. select
  20251. } = useSelection();
  20252. const {
  20253. columns
  20254. } = useHeaders();
  20255. const rows = computed(() => {
  20256. return extractRows([props.item]);
  20257. });
  20258. return () => createVNode("tr", {
  20259. "class": "v-data-table-group-header-row",
  20260. "style": {
  20261. '--v-data-table-group-header-row-depth': props.item.depth
  20262. }
  20263. }, [columns.value.map(column => {
  20264. if (column.key === 'data-table-group') {
  20265. const icon = isGroupOpen(props.item) ? '$expand' : '$next';
  20266. const onClick = () => toggleGroup(props.item);
  20267. return slots['data-table-group']?.({
  20268. item: props.item,
  20269. count: rows.value.length,
  20270. props: {
  20271. icon,
  20272. onClick
  20273. }
  20274. }) ?? createVNode(VDataTableColumn, {
  20275. "class": "v-data-table-group-header-row__column"
  20276. }, {
  20277. default: () => [createVNode(VBtn, {
  20278. "size": "small",
  20279. "variant": "text",
  20280. "icon": icon,
  20281. "onClick": onClick
  20282. }, null), createVNode("span", null, [props.item.value]), createVNode("span", null, [createTextVNode("("), rows.value.length, createTextVNode(")")])]
  20283. });
  20284. }
  20285. if (column.key === 'data-table-select') {
  20286. const modelValue = isSelected(rows.value);
  20287. const indeterminate = isSomeSelected(rows.value) && !modelValue;
  20288. const selectGroup = v => select(rows.value, v);
  20289. return slots['data-table-select']?.({
  20290. props: {
  20291. modelValue,
  20292. indeterminate,
  20293. 'onUpdate:modelValue': selectGroup
  20294. }
  20295. }) ?? createVNode("td", null, [createVNode(VCheckboxBtn, {
  20296. "modelValue": modelValue,
  20297. "indeterminate": indeterminate,
  20298. "onUpdate:modelValue": selectGroup
  20299. }, null)]);
  20300. }
  20301. return createVNode("td", null, null);
  20302. })]);
  20303. }
  20304. });
  20305. // Types
  20306. const makeVDataTableRowProps = propsFactory({
  20307. index: Number,
  20308. item: Object,
  20309. onClick: Function
  20310. }, 'VDataTableRow');
  20311. const VDataTableRow = defineComponent({
  20312. name: 'VDataTableRow',
  20313. props: makeVDataTableRowProps(),
  20314. setup(props, _ref) {
  20315. let {
  20316. slots
  20317. } = _ref;
  20318. const {
  20319. isSelected,
  20320. toggleSelect
  20321. } = useSelection();
  20322. const {
  20323. isExpanded,
  20324. toggleExpand
  20325. } = useExpanded();
  20326. const {
  20327. columns
  20328. } = useHeaders();
  20329. useRender(() => createVNode("tr", {
  20330. "class": ['v-data-table__tr', {
  20331. 'v-data-table__tr--clickable': !!props.onClick
  20332. }],
  20333. "onClick": props.onClick
  20334. }, [props.item && columns.value.map((column, i) => createVNode(VDataTableColumn, {
  20335. "align": column.align,
  20336. "fixed": column.fixed,
  20337. "fixedOffset": column.fixedOffset,
  20338. "lastFixed": column.lastFixed,
  20339. "noPadding": column.key === 'data-table-select' || column.key === 'data-table-expand',
  20340. "width": column.width
  20341. }, {
  20342. default: () => {
  20343. const item = props.item;
  20344. const slotName = `item.${column.key}`;
  20345. const slotProps = {
  20346. index: props.index,
  20347. item: props.item,
  20348. columns: columns.value,
  20349. isSelected,
  20350. toggleSelect,
  20351. isExpanded,
  20352. toggleExpand
  20353. };
  20354. if (slots[slotName]) return slots[slotName](slotProps);
  20355. if (column.key === 'data-table-select') {
  20356. return slots['item.data-table-select']?.(slotProps) ?? createVNode(VCheckboxBtn, {
  20357. "disabled": !item.selectable,
  20358. "modelValue": isSelected([item]),
  20359. "onClick": withModifiers(() => toggleSelect(item), ['stop'])
  20360. }, null);
  20361. }
  20362. if (column.key === 'data-table-expand') {
  20363. return slots['item.data-table-expand']?.(slotProps) ?? createVNode(VBtn, {
  20364. "icon": isExpanded(item) ? '$collapse' : '$expand',
  20365. "size": "small",
  20366. "variant": "text",
  20367. "onClick": withModifiers(() => toggleExpand(item), ['stop'])
  20368. }, null);
  20369. }
  20370. return getPropertyFromItem(item.columns, column.key);
  20371. }
  20372. }))]));
  20373. }
  20374. });
  20375. // Types
  20376. const makeVDataTableRowsProps = propsFactory({
  20377. loading: [Boolean, String],
  20378. loadingText: {
  20379. type: String,
  20380. default: '$vuetify.dataIterator.loadingText'
  20381. },
  20382. hideNoData: Boolean,
  20383. items: {
  20384. type: Array,
  20385. default: () => []
  20386. },
  20387. noDataText: {
  20388. type: String,
  20389. default: '$vuetify.noDataText'
  20390. },
  20391. rowHeight: Number,
  20392. 'onClick:row': Function
  20393. }, 'VDataTableRows');
  20394. const VDataTableRows = genericComponent()({
  20395. name: 'VDataTableRows',
  20396. props: makeVDataTableRowsProps(),
  20397. setup(props, _ref) {
  20398. let {
  20399. emit,
  20400. slots
  20401. } = _ref;
  20402. const {
  20403. columns
  20404. } = useHeaders();
  20405. const {
  20406. expandOnClick,
  20407. toggleExpand,
  20408. isExpanded
  20409. } = useExpanded();
  20410. const {
  20411. isSelected,
  20412. toggleSelect
  20413. } = useSelection();
  20414. const {
  20415. toggleGroup,
  20416. isGroupOpen
  20417. } = useGroupBy();
  20418. const {
  20419. t
  20420. } = useLocale();
  20421. useRender(() => {
  20422. if (props.loading && slots.loading) {
  20423. return createVNode("tr", {
  20424. "class": "v-data-table-rows-loading",
  20425. "key": "loading"
  20426. }, [createVNode("td", {
  20427. "colspan": columns.value.length
  20428. }, [slots.loading()])]);
  20429. }
  20430. if (!props.loading && !props.items.length && !props.hideNoData) {
  20431. return createVNode("tr", {
  20432. "class": "v-data-table-rows-no-data",
  20433. "key": "no-data"
  20434. }, [createVNode("td", {
  20435. "colspan": columns.value.length
  20436. }, [slots['no-data']?.() ?? t(props.noDataText)])]);
  20437. }
  20438. return createVNode(Fragment, null, [props.items.map((item, index) => {
  20439. if (item.type === 'group') {
  20440. return slots['group-header'] ? slots['group-header']({
  20441. index,
  20442. item,
  20443. columns: columns.value,
  20444. isExpanded,
  20445. toggleExpand,
  20446. isSelected,
  20447. toggleSelect,
  20448. toggleGroup,
  20449. isGroupOpen
  20450. }) : createVNode(VDataTableGroupHeaderRow, {
  20451. "key": `group-header_${item.id}`,
  20452. "item": item
  20453. }, slots);
  20454. }
  20455. const slotProps = {
  20456. index,
  20457. item,
  20458. columns: columns.value,
  20459. isExpanded,
  20460. toggleExpand,
  20461. isSelected,
  20462. toggleSelect
  20463. };
  20464. const itemSlotProps = {
  20465. ...slotProps,
  20466. props: {
  20467. key: `item_${item.key ?? item.index}`,
  20468. onClick: expandOnClick.value || props['onClick:row'] ? event => {
  20469. if (expandOnClick.value) {
  20470. toggleExpand(item);
  20471. }
  20472. props['onClick:row']?.(event, {
  20473. item
  20474. });
  20475. } : undefined,
  20476. index,
  20477. item
  20478. }
  20479. };
  20480. return createVNode(Fragment, null, [slots.item ? slots.item(itemSlotProps) : createVNode(VDataTableRow, itemSlotProps.props, slots), isExpanded(item) && slots['expanded-row']?.(slotProps)]);
  20481. })]);
  20482. });
  20483. return {};
  20484. }
  20485. });
  20486. // Utilities
  20487. // Types
  20488. // Composables
  20489. const makeDataTableItemsProps = propsFactory({
  20490. items: {
  20491. type: Array,
  20492. default: () => []
  20493. },
  20494. itemValue: {
  20495. type: [String, Array, Function],
  20496. default: 'id'
  20497. },
  20498. itemSelectable: {
  20499. type: [String, Array, Function],
  20500. default: null
  20501. },
  20502. returnObject: Boolean
  20503. }, 'DataTable-items');
  20504. function transformItem(props, item, index, columns) {
  20505. const value = props.returnObject ? item : getPropertyFromItem(item, props.itemValue);
  20506. const selectable = getPropertyFromItem(item, props.itemSelectable, true);
  20507. const itemColumns = columns.reduce((obj, column) => {
  20508. obj[column.key] = getPropertyFromItem(item, column.value ?? column.key);
  20509. return obj;
  20510. }, {});
  20511. return {
  20512. type: 'item',
  20513. key: props.returnObject ? getPropertyFromItem(item, props.itemValue) : value,
  20514. index,
  20515. value,
  20516. selectable,
  20517. columns: itemColumns,
  20518. raw: item
  20519. };
  20520. }
  20521. function transformItems(props, items, columns) {
  20522. return items.map((item, index) => transformItem(props, item, index, columns));
  20523. }
  20524. function useDataTableItems(props, columns) {
  20525. const items = computed(() => transformItems(props, props.items, columns.value));
  20526. return {
  20527. items
  20528. };
  20529. }
  20530. // Types
  20531. const makeDataTableProps = propsFactory({
  20532. ...makeVDataTableRowsProps(),
  20533. width: [String, Number],
  20534. search: String,
  20535. ...makeDataTableExpandProps(),
  20536. ...makeDataTableGroupProps(),
  20537. ...makeDataTableHeaderProps(),
  20538. ...makeDataTableItemsProps(),
  20539. ...makeDataTableSelectProps(),
  20540. ...makeDataTableSortProps(),
  20541. ...makeVDataTableHeadersProps(),
  20542. ...makeVTableProps()
  20543. }, 'DataTable');
  20544. const makeVDataTableProps = propsFactory({
  20545. ...makeDataTablePaginateProps(),
  20546. ...makeDataTableProps(),
  20547. ...makeFilterProps(),
  20548. ...makeVDataTableFooterProps()
  20549. }, 'VDataTable');
  20550. const VDataTable = genericComponent()({
  20551. name: 'VDataTable',
  20552. props: makeVDataTableProps(),
  20553. emits: {
  20554. 'update:modelValue': value => true,
  20555. 'update:page': value => true,
  20556. 'update:itemsPerPage': value => true,
  20557. 'update:sortBy': value => true,
  20558. 'update:options': value => true,
  20559. 'update:groupBy': value => true,
  20560. 'update:expanded': value => true
  20561. },
  20562. setup(props, _ref) {
  20563. let {
  20564. emit,
  20565. slots
  20566. } = _ref;
  20567. const {
  20568. groupBy
  20569. } = createGroupBy(props);
  20570. const {
  20571. sortBy,
  20572. multiSort,
  20573. mustSort
  20574. } = createSort(props);
  20575. const {
  20576. page,
  20577. itemsPerPage
  20578. } = createPagination(props);
  20579. const {
  20580. columns,
  20581. headers
  20582. } = createHeaders(props, {
  20583. groupBy,
  20584. showSelect: toRef(props, 'showSelect'),
  20585. showExpand: toRef(props, 'showExpand')
  20586. });
  20587. const {
  20588. items
  20589. } = useDataTableItems(props, columns);
  20590. const search = toRef(props, 'search');
  20591. const {
  20592. filteredItems
  20593. } = useFilter(props, items, search, {
  20594. transform: item => item.columns
  20595. });
  20596. const {
  20597. toggleSort
  20598. } = provideSort({
  20599. sortBy,
  20600. multiSort,
  20601. mustSort,
  20602. page
  20603. });
  20604. const {
  20605. sortByWithGroups,
  20606. opened,
  20607. extractRows,
  20608. isGroupOpen,
  20609. toggleGroup
  20610. } = provideGroupBy({
  20611. groupBy,
  20612. sortBy
  20613. });
  20614. const {
  20615. sortedItems
  20616. } = useSortedItems(props, filteredItems, sortByWithGroups);
  20617. const {
  20618. flatItems
  20619. } = useGroupedItems(sortedItems, groupBy, opened);
  20620. const itemsLength = computed(() => flatItems.value.length);
  20621. const {
  20622. startIndex,
  20623. stopIndex,
  20624. pageCount,
  20625. setItemsPerPage
  20626. } = providePagination({
  20627. page,
  20628. itemsPerPage,
  20629. itemsLength
  20630. });
  20631. const {
  20632. paginatedItems
  20633. } = usePaginatedItems({
  20634. items: flatItems,
  20635. startIndex,
  20636. stopIndex,
  20637. itemsPerPage
  20638. });
  20639. const paginatedItemsWithoutGroups = computed(() => extractRows(paginatedItems.value));
  20640. const {
  20641. isSelected,
  20642. select,
  20643. selectAll,
  20644. toggleSelect,
  20645. someSelected,
  20646. allSelected
  20647. } = provideSelection(props, {
  20648. allItems: items,
  20649. currentPage: paginatedItemsWithoutGroups
  20650. });
  20651. const {
  20652. isExpanded,
  20653. toggleExpand
  20654. } = provideExpanded(props);
  20655. useOptions({
  20656. page,
  20657. itemsPerPage,
  20658. sortBy,
  20659. groupBy,
  20660. search
  20661. });
  20662. provideDefaults({
  20663. VDataTableRows: {
  20664. hideNoData: toRef(props, 'hideNoData'),
  20665. noDataText: toRef(props, 'noDataText'),
  20666. loading: toRef(props, 'loading'),
  20667. loadingText: toRef(props, 'loadingText')
  20668. }
  20669. });
  20670. const slotProps = computed(() => ({
  20671. page: page.value,
  20672. itemsPerPage: itemsPerPage.value,
  20673. sortBy: sortBy.value,
  20674. pageCount: pageCount.value,
  20675. toggleSort,
  20676. setItemsPerPage,
  20677. someSelected: someSelected.value,
  20678. allSelected: allSelected.value,
  20679. isSelected,
  20680. select,
  20681. selectAll,
  20682. toggleSelect,
  20683. isExpanded,
  20684. toggleExpand,
  20685. isGroupOpen,
  20686. toggleGroup,
  20687. items: paginatedItemsWithoutGroups.value,
  20688. groupedItems: paginatedItems.value,
  20689. columns: columns.value,
  20690. headers: headers.value
  20691. }));
  20692. useRender(() => {
  20693. const [dataTableFooterProps] = VDataTableFooter.filterProps(props);
  20694. const [dataTableHeadersProps] = VDataTableHeaders.filterProps(props);
  20695. const [dataTableRowsProps] = VDataTableRows.filterProps(props);
  20696. const [tableProps] = VTable.filterProps(props);
  20697. return createVNode(VTable, mergeProps({
  20698. "class": ['v-data-table', {
  20699. 'v-data-table--show-select': props.showSelect,
  20700. 'v-data-table--loading': props.loading
  20701. }, props.class],
  20702. "style": props.style
  20703. }, tableProps), {
  20704. top: () => slots.top?.(slotProps.value),
  20705. default: () => slots.default ? slots.default(slotProps.value) : createVNode(Fragment, null, [slots.colgroup?.(slotProps.value), createVNode("thead", null, [createVNode(VDataTableHeaders, dataTableHeadersProps, slots)]), slots.thead?.(slotProps.value), createVNode("tbody", null, [slots.body ? slots.body(slotProps.value) : createVNode(VDataTableRows, mergeProps(dataTableRowsProps, {
  20706. "items": paginatedItems.value
  20707. }), slots)]), slots.tbody?.(slotProps.value), slots.tfoot?.(slotProps.value)]),
  20708. bottom: () => slots.bottom ? slots.bottom(slotProps.value) : createVNode(Fragment, null, [createVNode(VDataTableFooter, dataTableFooterProps, {
  20709. prepend: slots['footer.prepend']
  20710. })])
  20711. });
  20712. });
  20713. return {};
  20714. }
  20715. });
  20716. // Types
  20717. const makeVDataTableVirtualProps = propsFactory({
  20718. ...makeDataTableProps(),
  20719. ...makeDataTableGroupProps(),
  20720. ...makeVirtualProps(),
  20721. ...makeFilterProps()
  20722. }, 'VDataTableVirtual');
  20723. const VDataTableVirtual = genericComponent()({
  20724. name: 'VDataTableVirtual',
  20725. props: makeVDataTableVirtualProps(),
  20726. emits: {
  20727. 'update:modelValue': value => true,
  20728. 'update:sortBy': value => true,
  20729. 'update:options': value => true,
  20730. 'update:groupBy': value => true,
  20731. 'update:expanded': value => true,
  20732. 'click:row': (e, value) => true
  20733. },
  20734. setup(props, _ref) {
  20735. let {
  20736. emit,
  20737. slots
  20738. } = _ref;
  20739. const {
  20740. groupBy
  20741. } = createGroupBy(props);
  20742. const {
  20743. sortBy,
  20744. multiSort,
  20745. mustSort
  20746. } = createSort(props);
  20747. const {
  20748. columns,
  20749. headers
  20750. } = createHeaders(props, {
  20751. groupBy,
  20752. showSelect: toRef(props, 'showSelect'),
  20753. showExpand: toRef(props, 'showExpand')
  20754. });
  20755. const {
  20756. items
  20757. } = useDataTableItems(props, columns);
  20758. const search = toRef(props, 'search');
  20759. const {
  20760. filteredItems
  20761. } = useFilter(props, items, search, {
  20762. transform: item => item.columns
  20763. });
  20764. const {
  20765. toggleSort
  20766. } = provideSort({
  20767. sortBy,
  20768. multiSort,
  20769. mustSort
  20770. });
  20771. const {
  20772. sortByWithGroups,
  20773. opened,
  20774. extractRows,
  20775. isGroupOpen,
  20776. toggleGroup
  20777. } = provideGroupBy({
  20778. groupBy,
  20779. sortBy
  20780. });
  20781. const {
  20782. sortedItems
  20783. } = useSortedItems(props, filteredItems, sortByWithGroups);
  20784. const {
  20785. flatItems
  20786. } = useGroupedItems(sortedItems, groupBy, opened);
  20787. const allItems = computed(() => extractRows(flatItems.value));
  20788. const {
  20789. isSelected,
  20790. select,
  20791. selectAll,
  20792. toggleSelect,
  20793. someSelected,
  20794. allSelected
  20795. } = provideSelection(props, {
  20796. allItems,
  20797. currentPage: allItems
  20798. });
  20799. const {
  20800. isExpanded,
  20801. toggleExpand
  20802. } = provideExpanded(props);
  20803. const headerHeight = computed(() => headers.value.length * 56);
  20804. const {
  20805. containerRef,
  20806. paddingTop,
  20807. paddingBottom,
  20808. computedItems,
  20809. handleItemResize,
  20810. handleScroll
  20811. } = useVirtual(props, flatItems, headerHeight);
  20812. const displayItems = computed(() => computedItems.value.map(item => item.raw));
  20813. useOptions({
  20814. sortBy,
  20815. page: shallowRef(1),
  20816. itemsPerPage: shallowRef(-1),
  20817. groupBy,
  20818. search
  20819. });
  20820. provideDefaults({
  20821. VDataTableRows: {
  20822. hideNoData: toRef(props, 'hideNoData'),
  20823. noDataText: toRef(props, 'noDataText'),
  20824. loading: toRef(props, 'loading'),
  20825. loadingText: toRef(props, 'loadingText')
  20826. }
  20827. });
  20828. const slotProps = computed(() => ({
  20829. sortBy: sortBy.value,
  20830. toggleSort,
  20831. someSelected: someSelected.value,
  20832. allSelected: allSelected.value,
  20833. isSelected,
  20834. select,
  20835. selectAll,
  20836. toggleSelect,
  20837. isExpanded,
  20838. toggleExpand,
  20839. isGroupOpen,
  20840. toggleGroup,
  20841. items: allItems.value,
  20842. groupedItems: flatItems.value,
  20843. columns: columns.value,
  20844. headers: headers.value
  20845. }));
  20846. useRender(() => {
  20847. const [dataTableHeadersProps] = VDataTableHeaders.filterProps(props);
  20848. const [dataTableRowsProps] = VDataTableRows.filterProps(props);
  20849. const [tableProps] = VTable.filterProps(props);
  20850. return createVNode(VTable, mergeProps({
  20851. "class": ['v-data-table', {
  20852. 'v-data-table--loading': props.loading
  20853. }, props.class],
  20854. "style": props.style
  20855. }, tableProps), {
  20856. top: () => slots.top?.(slotProps.value),
  20857. wrapper: () => createVNode("div", {
  20858. "ref": containerRef,
  20859. "onScroll": handleScroll,
  20860. "class": "v-table__wrapper",
  20861. "style": {
  20862. height: convertToUnit(props.height)
  20863. }
  20864. }, [createVNode("table", null, [createVNode("thead", null, [createVNode(VDataTableHeaders, mergeProps(dataTableHeadersProps, {
  20865. "sticky": props.fixedHeader
  20866. }), slots)]), createVNode("tbody", null, [createVNode("tr", {
  20867. "style": {
  20868. height: convertToUnit(paddingTop.value),
  20869. border: 0
  20870. }
  20871. }, [createVNode("td", {
  20872. "colspan": columns.value.length,
  20873. "style": {
  20874. height: convertToUnit(paddingTop.value),
  20875. border: 0
  20876. }
  20877. }, null)]), createVNode(VDataTableRows, mergeProps(dataTableRowsProps, {
  20878. "items": displayItems.value
  20879. }), {
  20880. ...slots,
  20881. item: itemSlotProps => createVNode(VVirtualScrollItem, {
  20882. "key": itemSlotProps.item.index,
  20883. "renderless": true,
  20884. "onUpdate:height": height => handleItemResize(itemSlotProps.item.index, height)
  20885. }, {
  20886. default: _ref2 => {
  20887. let {
  20888. itemRef
  20889. } = _ref2;
  20890. return slots.item?.({
  20891. ...itemSlotProps,
  20892. itemRef
  20893. }) ?? createVNode(VDataTableRow, mergeProps(itemSlotProps.props, {
  20894. "ref": itemRef,
  20895. "key": itemSlotProps.item.index
  20896. }), slots);
  20897. }
  20898. })
  20899. }), createVNode("tr", {
  20900. "style": {
  20901. height: convertToUnit(paddingBottom.value),
  20902. border: 0
  20903. }
  20904. }, [createVNode("td", {
  20905. "colspan": columns.value.length,
  20906. "style": {
  20907. height: convertToUnit(paddingBottom.value),
  20908. border: 0
  20909. }
  20910. }, null)])])])]),
  20911. bottom: () => slots.bottom?.(slotProps.value)
  20912. });
  20913. });
  20914. }
  20915. });
  20916. // Types
  20917. const makeVDataTableServerProps = propsFactory({
  20918. itemsLength: {
  20919. type: [Number, String],
  20920. required: true
  20921. },
  20922. ...makeDataTablePaginateProps(),
  20923. ...makeDataTableProps(),
  20924. ...makeVDataTableFooterProps()
  20925. }, 'VDataTableServer');
  20926. const VDataTableServer = genericComponent()({
  20927. name: 'VDataTableServer',
  20928. props: makeVDataTableServerProps(),
  20929. emits: {
  20930. 'update:modelValue': value => true,
  20931. 'update:page': page => true,
  20932. 'update:itemsPerPage': page => true,
  20933. 'update:sortBy': sortBy => true,
  20934. 'update:options': options => true,
  20935. 'update:expanded': options => true,
  20936. 'update:groupBy': value => true,
  20937. 'click:row': (e, value) => true
  20938. },
  20939. setup(props, _ref) {
  20940. let {
  20941. emit,
  20942. slots
  20943. } = _ref;
  20944. const {
  20945. groupBy
  20946. } = createGroupBy(props);
  20947. const {
  20948. sortBy,
  20949. multiSort,
  20950. mustSort
  20951. } = createSort(props);
  20952. const {
  20953. page,
  20954. itemsPerPage
  20955. } = createPagination(props);
  20956. const itemsLength = computed(() => parseInt(props.itemsLength, 10));
  20957. const {
  20958. columns,
  20959. headers
  20960. } = createHeaders(props, {
  20961. groupBy,
  20962. showSelect: toRef(props, 'showSelect'),
  20963. showExpand: toRef(props, 'showExpand')
  20964. });
  20965. const {
  20966. items
  20967. } = useDataTableItems(props, columns);
  20968. const {
  20969. toggleSort
  20970. } = provideSort({
  20971. sortBy,
  20972. multiSort,
  20973. mustSort,
  20974. page
  20975. });
  20976. const {
  20977. opened,
  20978. isGroupOpen,
  20979. toggleGroup,
  20980. extractRows
  20981. } = provideGroupBy({
  20982. groupBy,
  20983. sortBy
  20984. });
  20985. const {
  20986. pageCount,
  20987. setItemsPerPage
  20988. } = providePagination({
  20989. page,
  20990. itemsPerPage,
  20991. itemsLength
  20992. });
  20993. const {
  20994. flatItems
  20995. } = useGroupedItems(items, groupBy, opened);
  20996. const {
  20997. isSelected,
  20998. select,
  20999. selectAll,
  21000. toggleSelect,
  21001. someSelected,
  21002. allSelected
  21003. } = provideSelection(props, {
  21004. allItems: items,
  21005. currentPage: items
  21006. });
  21007. const {
  21008. isExpanded,
  21009. toggleExpand
  21010. } = provideExpanded(props);
  21011. const itemsWithoutGroups = computed(() => extractRows(items.value));
  21012. useOptions({
  21013. page,
  21014. itemsPerPage,
  21015. sortBy,
  21016. groupBy,
  21017. search: toRef(props, 'search')
  21018. });
  21019. provide('v-data-table', {
  21020. toggleSort,
  21021. sortBy
  21022. });
  21023. provideDefaults({
  21024. VDataTableRows: {
  21025. hideNoData: toRef(props, 'hideNoData'),
  21026. noDataText: toRef(props, 'noDataText'),
  21027. loading: toRef(props, 'loading'),
  21028. loadingText: toRef(props, 'loadingText')
  21029. }
  21030. });
  21031. const slotProps = computed(() => ({
  21032. page: page.value,
  21033. itemsPerPage: itemsPerPage.value,
  21034. sortBy: sortBy.value,
  21035. pageCount: pageCount.value,
  21036. toggleSort,
  21037. setItemsPerPage,
  21038. someSelected: someSelected.value,
  21039. allSelected: allSelected.value,
  21040. isSelected,
  21041. select,
  21042. selectAll,
  21043. toggleSelect,
  21044. isExpanded,
  21045. toggleExpand,
  21046. isGroupOpen,
  21047. toggleGroup,
  21048. items: itemsWithoutGroups.value,
  21049. groupedItems: flatItems.value,
  21050. columns: columns.value,
  21051. headers: headers.value
  21052. }));
  21053. useRender(() => {
  21054. const [dataTableFooterProps] = VDataTableFooter.filterProps(props);
  21055. const [dataTableHeadersProps] = VDataTableHeaders.filterProps(props);
  21056. const [dataTableRowsProps] = VDataTableRows.filterProps(props);
  21057. const [tableProps] = VTable.filterProps(props);
  21058. return createVNode(VTable, mergeProps({
  21059. "class": ['v-data-table', {
  21060. 'v-data-table--loading': props.loading
  21061. }, props.class],
  21062. "style": props.style
  21063. }, tableProps), {
  21064. top: () => slots.top?.(slotProps.value),
  21065. default: () => slots.default ? slots.default(slotProps.value) : createVNode(Fragment, null, [slots.colgroup?.(slotProps.value), createVNode("thead", {
  21066. "class": "v-data-table__thead",
  21067. "role": "rowgroup"
  21068. }, [createVNode(VDataTableHeaders, mergeProps(dataTableHeadersProps, {
  21069. "sticky": props.fixedHeader
  21070. }), slots)]), slots.thead?.(slotProps.value), createVNode("tbody", {
  21071. "class": "v-data-table__tbody",
  21072. "role": "rowgroup"
  21073. }, [slots.body ? slots.body(slotProps.value) : createVNode(VDataTableRows, mergeProps(dataTableRowsProps, {
  21074. "items": flatItems.value
  21075. }), slots)]), slots.tbody?.(slotProps.value), slots.tfoot?.(slotProps.value)]),
  21076. bottom: () => slots.bottom ? slots.bottom(slotProps.value) : createVNode(VDataTableFooter, dataTableFooterProps, {
  21077. prepend: slots['footer.prepend']
  21078. })
  21079. });
  21080. });
  21081. }
  21082. });
  21083. // Utilities
  21084. // Types
  21085. const firstDay = {
  21086. '001': 1,
  21087. AD: 1,
  21088. AE: 6,
  21089. AF: 6,
  21090. AG: 0,
  21091. AI: 1,
  21092. AL: 1,
  21093. AM: 1,
  21094. AN: 1,
  21095. AR: 1,
  21096. AS: 0,
  21097. AT: 1,
  21098. AU: 1,
  21099. AX: 1,
  21100. AZ: 1,
  21101. BA: 1,
  21102. BD: 0,
  21103. BE: 1,
  21104. BG: 1,
  21105. BH: 6,
  21106. BM: 1,
  21107. BN: 1,
  21108. BR: 0,
  21109. BS: 0,
  21110. BT: 0,
  21111. BW: 0,
  21112. BY: 1,
  21113. BZ: 0,
  21114. CA: 0,
  21115. CH: 1,
  21116. CL: 1,
  21117. CM: 1,
  21118. CN: 1,
  21119. CO: 0,
  21120. CR: 1,
  21121. CY: 1,
  21122. CZ: 1,
  21123. DE: 1,
  21124. DJ: 6,
  21125. DK: 1,
  21126. DM: 0,
  21127. DO: 0,
  21128. DZ: 6,
  21129. EC: 1,
  21130. EE: 1,
  21131. EG: 6,
  21132. ES: 1,
  21133. ET: 0,
  21134. FI: 1,
  21135. FJ: 1,
  21136. FO: 1,
  21137. FR: 1,
  21138. GB: 1,
  21139. 'GB-alt-variant': 0,
  21140. GE: 1,
  21141. GF: 1,
  21142. GP: 1,
  21143. GR: 1,
  21144. GT: 0,
  21145. GU: 0,
  21146. HK: 0,
  21147. HN: 0,
  21148. HR: 1,
  21149. HU: 1,
  21150. ID: 0,
  21151. IE: 1,
  21152. IL: 0,
  21153. IN: 0,
  21154. IQ: 6,
  21155. IR: 6,
  21156. IS: 1,
  21157. IT: 1,
  21158. JM: 0,
  21159. JO: 6,
  21160. JP: 0,
  21161. KE: 0,
  21162. KG: 1,
  21163. KH: 0,
  21164. KR: 0,
  21165. KW: 6,
  21166. KZ: 1,
  21167. LA: 0,
  21168. LB: 1,
  21169. LI: 1,
  21170. LK: 1,
  21171. LT: 1,
  21172. LU: 1,
  21173. LV: 1,
  21174. LY: 6,
  21175. MC: 1,
  21176. MD: 1,
  21177. ME: 1,
  21178. MH: 0,
  21179. MK: 1,
  21180. MM: 0,
  21181. MN: 1,
  21182. MO: 0,
  21183. MQ: 1,
  21184. MT: 0,
  21185. MV: 5,
  21186. MX: 0,
  21187. MY: 1,
  21188. MZ: 0,
  21189. NI: 0,
  21190. NL: 1,
  21191. NO: 1,
  21192. NP: 0,
  21193. NZ: 1,
  21194. OM: 6,
  21195. PA: 0,
  21196. PE: 0,
  21197. PH: 0,
  21198. PK: 0,
  21199. PL: 1,
  21200. PR: 0,
  21201. PT: 0,
  21202. PY: 0,
  21203. QA: 6,
  21204. RE: 1,
  21205. RO: 1,
  21206. RS: 1,
  21207. RU: 1,
  21208. SA: 0,
  21209. SD: 6,
  21210. SE: 1,
  21211. SG: 0,
  21212. SI: 1,
  21213. SK: 1,
  21214. SM: 1,
  21215. SV: 0,
  21216. SY: 6,
  21217. TH: 0,
  21218. TJ: 1,
  21219. TM: 1,
  21220. TR: 1,
  21221. TT: 0,
  21222. TW: 0,
  21223. UA: 1,
  21224. UM: 0,
  21225. US: 0,
  21226. UY: 1,
  21227. UZ: 1,
  21228. VA: 1,
  21229. VE: 0,
  21230. VI: 0,
  21231. VN: 1,
  21232. WS: 0,
  21233. XK: 1,
  21234. YE: 0,
  21235. ZA: 0,
  21236. ZW: 0
  21237. };
  21238. function getWeekArray(date, locale) {
  21239. const weeks = [];
  21240. let currentWeek = [];
  21241. const firstDayOfMonth = startOfMonth(date);
  21242. const lastDayOfMonth = endOfMonth(date);
  21243. const firstDayWeekIndex = firstDayOfMonth.getDay() - firstDay[locale.slice(-2).toUpperCase()];
  21244. const lastDayWeekIndex = lastDayOfMonth.getDay() - firstDay[locale.slice(-2).toUpperCase()];
  21245. for (let i = 0; i < firstDayWeekIndex; i++) {
  21246. const adjacentDay = new Date(firstDayOfMonth);
  21247. adjacentDay.setDate(adjacentDay.getDate() - (firstDayWeekIndex - i));
  21248. currentWeek.push(adjacentDay);
  21249. }
  21250. for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {
  21251. const day = new Date(date.getFullYear(), date.getMonth(), i);
  21252. // Add the day to the current week
  21253. currentWeek.push(day);
  21254. // If the current week has 7 days, add it to the weeks array and start a new week
  21255. if (currentWeek.length === 7) {
  21256. weeks.push(currentWeek);
  21257. currentWeek = [];
  21258. }
  21259. }
  21260. for (let i = 1; i < 7 - lastDayWeekIndex; i++) {
  21261. const adjacentDay = new Date(lastDayOfMonth);
  21262. adjacentDay.setDate(adjacentDay.getDate() + i);
  21263. currentWeek.push(adjacentDay);
  21264. }
  21265. weeks.push(currentWeek);
  21266. return weeks;
  21267. }
  21268. function startOfMonth(date) {
  21269. return new Date(date.getFullYear(), date.getMonth(), 1);
  21270. }
  21271. function endOfMonth(date) {
  21272. return new Date(date.getFullYear(), date.getMonth() + 1, 0);
  21273. }
  21274. function parseLocalDate(value) {
  21275. const parts = value.split('-').map(Number);
  21276. // new Date() uses local time zone when passing individual date component values
  21277. return new Date(parts[0], parts[1] - 1, parts[2]);
  21278. }
  21279. const _YYYMMDD = /([12]\d{3}-([1-9]|0[1-9]|1[0-2])-([1-9]|0[1-9]|[12]\d|3[01]))/;
  21280. function date(value) {
  21281. if (value == null) return new Date();
  21282. if (value instanceof Date) return value;
  21283. if (typeof value === 'string') {
  21284. let parsed;
  21285. if (_YYYMMDD.test(value)) {
  21286. return parseLocalDate(value);
  21287. } else {
  21288. parsed = Date.parse(value);
  21289. }
  21290. if (!isNaN(parsed)) return new Date(parsed);
  21291. }
  21292. return null;
  21293. }
  21294. const sundayJanuarySecond2000 = new Date(2000, 0, 2);
  21295. function getWeekdays(locale) {
  21296. const daysFromSunday = firstDay[locale.slice(-2).toUpperCase()];
  21297. return createRange(7).map(i => {
  21298. const weekday = new Date(sundayJanuarySecond2000);
  21299. weekday.setDate(sundayJanuarySecond2000.getDate() + daysFromSunday + i);
  21300. return new Intl.DateTimeFormat(locale, {
  21301. weekday: 'short'
  21302. }).format(weekday);
  21303. });
  21304. }
  21305. function format(value, formatString, locale) {
  21306. const date = new Date(value);
  21307. let options = {};
  21308. switch (formatString) {
  21309. case 'fullDateWithWeekday':
  21310. options = {
  21311. weekday: 'long',
  21312. day: 'numeric',
  21313. month: 'long',
  21314. year: 'numeric'
  21315. };
  21316. break;
  21317. case 'normalDateWithWeekday':
  21318. options = {
  21319. weekday: 'short',
  21320. day: 'numeric',
  21321. month: 'short'
  21322. };
  21323. break;
  21324. case 'keyboardDate':
  21325. options = {};
  21326. break;
  21327. case 'monthAndDate':
  21328. options = {
  21329. month: 'long',
  21330. day: 'numeric'
  21331. };
  21332. break;
  21333. case 'monthAndYear':
  21334. options = {
  21335. month: 'long',
  21336. year: 'numeric'
  21337. };
  21338. break;
  21339. case 'dayOfMonth':
  21340. options = {
  21341. day: 'numeric'
  21342. };
  21343. break;
  21344. default:
  21345. options = {
  21346. timeZone: 'UTC',
  21347. timeZoneName: 'short'
  21348. };
  21349. }
  21350. return new Intl.DateTimeFormat(locale, options).format(date);
  21351. }
  21352. function addDays(date, amount) {
  21353. const d = new Date(date);
  21354. d.setDate(d.getDate() + amount);
  21355. return d;
  21356. }
  21357. function addMonths(date, amount) {
  21358. const d = new Date(date);
  21359. d.setMonth(d.getMonth() + amount);
  21360. return d;
  21361. }
  21362. function getYear(date) {
  21363. return date.getFullYear();
  21364. }
  21365. function getMonth(date) {
  21366. return date.getMonth();
  21367. }
  21368. function startOfYear(date) {
  21369. return new Date(date.getFullYear(), 0, 1);
  21370. }
  21371. function endOfYear(date) {
  21372. return new Date(date.getFullYear(), 11, 31);
  21373. }
  21374. function isWithinRange(date, range) {
  21375. return isAfter(date, range[0]) && isBefore(date, range[1]);
  21376. }
  21377. function isValid(date) {
  21378. const d = new Date(date);
  21379. return d instanceof Date && !isNaN(d.getTime());
  21380. }
  21381. function isAfter(date, comparing) {
  21382. return date.getTime() > comparing.getTime();
  21383. }
  21384. function isBefore(date, comparing) {
  21385. return date.getTime() < comparing.getTime();
  21386. }
  21387. function isEqual(date, comparing) {
  21388. return date.getTime() === comparing.getTime();
  21389. }
  21390. function isSameDay(date, comparing) {
  21391. return date.getDate() === comparing.getDate() && date.getMonth() === comparing.getMonth() && date.getFullYear() === comparing.getFullYear();
  21392. }
  21393. function isSameMonth(date, comparing) {
  21394. return date.getMonth() === comparing.getMonth() && date.getFullYear() === comparing.getFullYear();
  21395. }
  21396. function getDiff(date, comparing, unit) {
  21397. const d = new Date(date);
  21398. const c = new Date(comparing);
  21399. if (unit === 'month') {
  21400. return d.getMonth() - c.getMonth() + (d.getFullYear() - c.getFullYear()) * 12;
  21401. }
  21402. return Math.floor((d.getTime() - c.getTime()) / (1000 * 60 * 60 * 24));
  21403. }
  21404. function setYear(date, year) {
  21405. const d = new Date(date);
  21406. d.setFullYear(year);
  21407. return d;
  21408. }
  21409. class VuetifyDateAdapter {
  21410. constructor(options) {
  21411. this.locale = options.locale;
  21412. }
  21413. date(value) {
  21414. return date(value);
  21415. }
  21416. toJsDate(date) {
  21417. return date;
  21418. }
  21419. addDays(date, amount) {
  21420. return addDays(date, amount);
  21421. }
  21422. addMonths(date, amount) {
  21423. return addMonths(date, amount);
  21424. }
  21425. getWeekArray(date) {
  21426. return getWeekArray(date, this.locale);
  21427. }
  21428. startOfMonth(date) {
  21429. return startOfMonth(date);
  21430. }
  21431. endOfMonth(date) {
  21432. return endOfMonth(date);
  21433. }
  21434. format(date, formatString) {
  21435. return format(date, formatString, this.locale);
  21436. }
  21437. isEqual(date, comparing) {
  21438. return isEqual(date, comparing);
  21439. }
  21440. isValid(date) {
  21441. return isValid(date);
  21442. }
  21443. isWithinRange(date, range) {
  21444. return isWithinRange(date, range);
  21445. }
  21446. isAfter(date, comparing) {
  21447. return isAfter(date, comparing);
  21448. }
  21449. isBefore(date, comparing) {
  21450. return !isAfter(date, comparing) && !isEqual(date, comparing);
  21451. }
  21452. isSameDay(date, comparing) {
  21453. return isSameDay(date, comparing);
  21454. }
  21455. isSameMonth(date, comparing) {
  21456. return isSameMonth(date, comparing);
  21457. }
  21458. setYear(date, year) {
  21459. return setYear(date, year);
  21460. }
  21461. getDiff(date, comparing, unit) {
  21462. return getDiff(date, comparing, unit);
  21463. }
  21464. getWeekdays() {
  21465. return getWeekdays(this.locale);
  21466. }
  21467. getYear(date) {
  21468. return getYear(date);
  21469. }
  21470. getMonth(date) {
  21471. return getMonth(date);
  21472. }
  21473. startOfYear(date) {
  21474. return startOfYear(date);
  21475. }
  21476. endOfYear(date) {
  21477. return endOfYear(date);
  21478. }
  21479. }
  21480. // Composables
  21481. // Types
  21482. const DateAdapterSymbol = Symbol.for('vuetify:date-adapter');
  21483. function createDate(options) {
  21484. return mergeDeep({
  21485. adapter: VuetifyDateAdapter,
  21486. locale: {
  21487. af: 'af-ZA',
  21488. // ar: '', # not the same value for all variants
  21489. bg: 'bg-BG',
  21490. ca: 'ca-ES',
  21491. ckb: '',
  21492. cs: '',
  21493. de: 'de-DE',
  21494. el: 'el-GR',
  21495. en: 'en-US',
  21496. // es: '', # not the same value for all variants
  21497. et: 'et-EE',
  21498. fa: 'fa-IR',
  21499. fi: 'fi-FI',
  21500. // fr: '', #not the same value for all variants
  21501. hr: 'hr-HR',
  21502. hu: 'hu-HU',
  21503. he: 'he-IL',
  21504. id: 'id-ID',
  21505. it: 'it-IT',
  21506. ja: 'ja-JP',
  21507. ko: 'ko-KR',
  21508. lv: 'lv-LV',
  21509. lt: 'lt-LT',
  21510. nl: 'nl-NL',
  21511. no: 'nn-NO',
  21512. pl: 'pl-PL',
  21513. pt: 'pt-PT',
  21514. ro: 'ro-RO',
  21515. ru: 'ru-RU',
  21516. sk: 'sk-SK',
  21517. sl: 'sl-SI',
  21518. srCyrl: 'sr-SP',
  21519. srLatn: 'sr-SP',
  21520. sv: 'sv-SE',
  21521. th: 'th-TH',
  21522. tr: 'tr-TR',
  21523. az: 'az-AZ',
  21524. uk: 'uk-UA',
  21525. vi: 'vi-VN',
  21526. zhHans: 'zh-CN',
  21527. zhHant: 'zh-TW'
  21528. }
  21529. }, options);
  21530. }
  21531. function useDate() {
  21532. const date = inject$1(DateAdapterSymbol);
  21533. const locale = useLocale();
  21534. if (!date) throw new Error('[Vuetify] Could not find injected date');
  21535. const instance = reactive(typeof date.adapter === 'function'
  21536. // eslint-disable-next-line new-cap
  21537. ? new date.adapter({
  21538. locale: date.locale?.[locale.current.value] ?? locale.current.value
  21539. }) : date.adapter);
  21540. watch(locale.current, value => {
  21541. const newLocale = date.locale ? date.locale[value] : value;
  21542. instance.locale = newLocale ?? instance.locale;
  21543. });
  21544. return instance;
  21545. }
  21546. function toIso(adapter, value) {
  21547. const date = adapter.toJsDate(value);
  21548. return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
  21549. }
  21550. function getMondayOfFirstWeekOfYear(year) {
  21551. return new Date(year, 0, 1);
  21552. }
  21553. // https://stackoverflow.com/questions/274861/how-do-i-calculate-the-week-number-given-a-date/275024#275024
  21554. function getWeek(adapter, value) {
  21555. const date = adapter.toJsDate(value);
  21556. let year = date.getFullYear();
  21557. let d1w1 = getMondayOfFirstWeekOfYear(year);
  21558. if (date < d1w1) {
  21559. year = year - 1;
  21560. d1w1 = getMondayOfFirstWeekOfYear(year);
  21561. } else {
  21562. const tv = getMondayOfFirstWeekOfYear(year + 1);
  21563. if (date >= tv) {
  21564. year = year + 1;
  21565. d1w1 = tv;
  21566. }
  21567. }
  21568. const diffTime = Math.abs(date.getTime() - d1w1.getTime());
  21569. const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
  21570. return Math.floor(diffDays / 7) + 1;
  21571. }
  21572. // Composables
  21573. // Types
  21574. const makeDateProps = propsFactory({
  21575. modelValue: {
  21576. type: null,
  21577. default: () => []
  21578. },
  21579. displayDate: {
  21580. type: null,
  21581. default: null
  21582. },
  21583. inputMode: {
  21584. type: String,
  21585. default: 'calendar'
  21586. },
  21587. viewMode: {
  21588. type: String,
  21589. default: 'month'
  21590. },
  21591. format: String
  21592. }, 'date');
  21593. const dateEmits = {
  21594. 'update:modelValue': date => true,
  21595. 'update:displayDate': date => true,
  21596. 'update:focused': focused => true,
  21597. 'update:inputMode': inputMode => true,
  21598. 'update:viewMode': viewMode => true
  21599. };
  21600. function createDateInput(props, isRange) {
  21601. const adapter = useDate();
  21602. const model = useProxiedModel(props, 'modelValue', [], v => {
  21603. if (v == null) return [];
  21604. const arr = wrapInArray(v).filter(v => !!v);
  21605. return arr.map(adapter.date);
  21606. }, v => {
  21607. const arr = wrapInArray(v);
  21608. const formatted = props.format ? arr.map(d => adapter.format(d, props.format)) : arr;
  21609. if (isRange) return formatted;
  21610. return formatted[0];
  21611. });
  21612. const inputMode = useProxiedModel(props, 'inputMode');
  21613. const viewMode = useProxiedModel(props, 'viewMode');
  21614. const displayDate = useProxiedModel(props, 'displayDate', model.value.length ? model.value[0] : adapter.date());
  21615. function parseKeyboardDate(input, fallback) {
  21616. const date = adapter.date(input);
  21617. return adapter.isValid(date) ? date : fallback;
  21618. }
  21619. return {
  21620. model,
  21621. adapter,
  21622. inputMode,
  21623. viewMode,
  21624. displayDate,
  21625. parseKeyboardDate
  21626. };
  21627. }
  21628. const makeVDatePickerControlsProps = propsFactory({
  21629. nextIcon: {
  21630. type: [String],
  21631. default: '$next'
  21632. },
  21633. prevIcon: {
  21634. type: [String],
  21635. default: '$prev'
  21636. },
  21637. expandIcon: {
  21638. type: [String],
  21639. default: '$expand'
  21640. },
  21641. collapseIcon: {
  21642. type: [String],
  21643. default: '$collapse'
  21644. },
  21645. range: {
  21646. default: false,
  21647. type: [Boolean, String],
  21648. validator: v => v === false || ['start', 'end'].includes(v)
  21649. },
  21650. ...omit(makeDateProps(), ['modelValue', 'inputMode'])
  21651. }, 'VDatePickerControls');
  21652. const VDatePickerControls = genericComponent()({
  21653. name: 'VDatePickerControls',
  21654. props: makeVDatePickerControlsProps(),
  21655. emits: {
  21656. ...omit(dateEmits, ['update:modelValue', 'update:inputMode'])
  21657. },
  21658. setup(props, _ref) {
  21659. let {
  21660. emit
  21661. } = _ref;
  21662. const adapter = useDate();
  21663. const monthAndYear = computed(() => {
  21664. const month = props.range === 'end' ? adapter.addMonths(props.displayDate, 1) : props.displayDate;
  21665. return adapter.format(month, 'monthAndYear');
  21666. });
  21667. useRender(() => {
  21668. const prevBtn = createVNode(VBtn, {
  21669. "variant": "text",
  21670. "icon": props.prevIcon,
  21671. "onClick": () => emit('update:displayDate', adapter.addMonths(props.displayDate, -1))
  21672. }, null);
  21673. const nextBtn = createVNode(VBtn, {
  21674. "variant": "text",
  21675. "icon": props.nextIcon,
  21676. "onClick": () => emit('update:displayDate', adapter.addMonths(props.displayDate, 1))
  21677. }, null);
  21678. return createVNode("div", {
  21679. "class": "v-date-picker-controls"
  21680. }, [props.viewMode === 'month' && props.range === 'start' && prevBtn, !!props.range && createVNode(VSpacer, {
  21681. "key": "range-spacer"
  21682. }, null), createVNode("div", {
  21683. "class": "v-date-picker-controls__date"
  21684. }, [monthAndYear.value]), createVNode(VBtn, {
  21685. "key": "expand-btn",
  21686. "variant": "text",
  21687. "icon": props.viewMode === 'month' ? props.expandIcon : props.collapseIcon,
  21688. "onClick": () => emit('update:viewMode', props.viewMode === 'month' ? 'year' : 'month')
  21689. }, null), createVNode(VSpacer, null, null), props.viewMode === 'month' && !props.range && createVNode("div", {
  21690. "class": "v-date-picker-controls__month",
  21691. "key": "month-buttons"
  21692. }, [prevBtn, nextBtn]), props.viewMode === 'month' && props.range === 'end' && nextBtn]);
  21693. });
  21694. return {};
  21695. }
  21696. });
  21697. // Composables
  21698. // Types
  21699. const DatePickerSymbol = Symbol.for('vuetify:date-picker');
  21700. function createDatePicker(props) {
  21701. const hoverDate = ref();
  21702. const hoverMonth = ref();
  21703. const isDragging = ref(false);
  21704. const dragHandle = ref(null);
  21705. const hasScrolled = ref(false);
  21706. provide(DatePickerSymbol, {
  21707. hoverDate,
  21708. hoverMonth,
  21709. isDragging,
  21710. dragHandle,
  21711. hasScrolled
  21712. });
  21713. // TODO: This composable should probably not live in DateInput
  21714. const {
  21715. model,
  21716. displayDate,
  21717. viewMode,
  21718. inputMode
  21719. } = createDateInput(props, !!props.multiple);
  21720. return {
  21721. hoverDate,
  21722. hoverMonth,
  21723. isDragging,
  21724. dragHandle,
  21725. hasScrolled,
  21726. model,
  21727. displayDate,
  21728. viewMode,
  21729. inputMode
  21730. };
  21731. }
  21732. function useDatePicker() {
  21733. const datePicker = inject$1(DatePickerSymbol);
  21734. if (!datePicker) throw new Error('foo');
  21735. return datePicker;
  21736. }
  21737. const makeVDatePickerMonthProps = propsFactory({
  21738. color: String,
  21739. showAdjacentMonths: Boolean,
  21740. hideWeekdays: Boolean,
  21741. showWeek: Boolean,
  21742. hoverDate: null,
  21743. multiple: Boolean,
  21744. side: {
  21745. type: String
  21746. },
  21747. ...omit(makeDateProps(), ['inputMode', 'viewMode'])
  21748. }, 'VDatePickerMonth');
  21749. const VDatePickerMonth = genericComponent()({
  21750. name: 'VDatePickerMonth',
  21751. props: makeVDatePickerMonthProps({
  21752. color: 'surface-variant'
  21753. }),
  21754. emits: {
  21755. ...omit(dateEmits, ['update:inputMode', 'update:viewMode']),
  21756. 'update:hoverDate': date => true
  21757. },
  21758. setup(props, _ref) {
  21759. let {
  21760. emit,
  21761. slots
  21762. } = _ref;
  21763. const adapter = useDate();
  21764. const {
  21765. isDragging,
  21766. dragHandle,
  21767. hasScrolled
  21768. } = useDatePicker();
  21769. const month = computed(() => props.displayDate);
  21770. const findClosestDate = (date, dates) => {
  21771. const {
  21772. isSameDay,
  21773. getDiff
  21774. } = adapter;
  21775. const [startDate, endDate] = dates;
  21776. if (isSameDay(startDate, endDate)) {
  21777. return getDiff(date, startDate, 'days') > 0 ? endDate : startDate;
  21778. }
  21779. const distStart = Math.abs(getDiff(date, startDate));
  21780. const distEnd = Math.abs(getDiff(date, endDate));
  21781. return distStart < distEnd ? startDate : endDate;
  21782. };
  21783. // const hoverRange = computed<[any, any] | null>(() => {
  21784. // if (!props.hoverDate) return null
  21785. // const closestDate = findClosestDate(props.hoverDate, props.modelValue)
  21786. // if (!closestDate) return null
  21787. // return adapter.isAfter(props.hoverDate, closestDate) ? [closestDate, props.hoverDate] : [props.hoverDate, closestDate]
  21788. // })
  21789. const weeksInMonth = computed(() => {
  21790. const weeks = adapter.getWeekArray(month.value);
  21791. const days = weeks.flat();
  21792. // Make sure there's always 6 weeks in month (6 * 7 days)
  21793. // But only do it if we're not hiding adjacent months?
  21794. const daysInMonth = 6 * 7;
  21795. if (days.length < daysInMonth && props.showAdjacentMonths) {
  21796. const lastDay = days[days.length - 1];
  21797. let week = [];
  21798. for (let day = 1; day <= daysInMonth - days.length; day++) {
  21799. week.push(adapter.addDays(lastDay, day));
  21800. if (day % 7 === 0) {
  21801. weeks.push(week);
  21802. week = [];
  21803. }
  21804. }
  21805. }
  21806. return weeks;
  21807. });
  21808. const daysInMonth = computed(() => {
  21809. const validDates = props.modelValue.filter(v => !!v);
  21810. const isRange = validDates.length > 1;
  21811. const days = weeksInMonth.value.flat();
  21812. const today = adapter.date();
  21813. const startDate = validDates[0];
  21814. const endDate = validDates[1];
  21815. return days.map((date, index) => {
  21816. const isStart = startDate && adapter.isSameDay(date, startDate);
  21817. const isEnd = endDate && adapter.isSameDay(date, endDate);
  21818. const isAdjacent = !adapter.isSameMonth(date, month.value);
  21819. const isSame = validDates.length === 2 && adapter.isSameDay(startDate, endDate);
  21820. return {
  21821. date,
  21822. isoDate: toIso(adapter, date),
  21823. formatted: adapter.format(date, 'keyboardDate'),
  21824. year: adapter.getYear(date),
  21825. month: adapter.getMonth(date),
  21826. isWeekStart: index % 7 === 0,
  21827. isWeekEnd: index % 7 === 6,
  21828. isSelected: isStart || isEnd,
  21829. isStart,
  21830. isEnd,
  21831. isToday: adapter.isSameDay(date, today),
  21832. isAdjacent,
  21833. isHidden: isAdjacent && !props.showAdjacentMonths,
  21834. inRange: isRange && !isSame && (isStart || isEnd || validDates.length === 2 && adapter.isWithinRange(date, validDates)),
  21835. // isHovered: props.hoverDate === date,
  21836. // inHover: hoverRange.value && isWithinRange(date, hoverRange.value),
  21837. isHovered: false,
  21838. inHover: false,
  21839. localized: adapter.format(date, 'dayOfMonth')
  21840. };
  21841. });
  21842. });
  21843. const weeks = computed(() => {
  21844. return weeksInMonth.value.map(week => {
  21845. return getWeek(adapter, week[0]);
  21846. });
  21847. });
  21848. const {
  21849. backgroundColorClasses,
  21850. backgroundColorStyles
  21851. } = useBackgroundColor(props, 'color');
  21852. function selectDate(date) {
  21853. let newModel = props.modelValue.slice();
  21854. if (props.multiple) {
  21855. if (isDragging.value && dragHandle.value != null) {
  21856. const otherIndex = (dragHandle.value + 1) % 2;
  21857. const fn = otherIndex === 0 ? 'isBefore' : 'isAfter';
  21858. if (adapter[fn](date, newModel[otherIndex])) {
  21859. newModel[dragHandle.value] = newModel[otherIndex];
  21860. newModel[otherIndex] = date;
  21861. dragHandle.value = otherIndex;
  21862. } else {
  21863. newModel[dragHandle.value] = date;
  21864. }
  21865. } else {
  21866. if (newModel.find(d => adapter.isSameDay(d, date))) {
  21867. newModel = newModel.filter(v => !adapter.isSameDay(v, date));
  21868. } else if (newModel.length === 2) {
  21869. let index;
  21870. if (!props.side || adapter.isSameMonth(newModel[0], newModel[1])) {
  21871. const closest = findClosestDate(date, newModel);
  21872. index = newModel.indexOf(closest);
  21873. } else {
  21874. index = props.side === 'start' ? 0 : props.side === 'end' ? 1 : undefined;
  21875. }
  21876. newModel = newModel.map((v, i) => i === index ? date : v);
  21877. } else {
  21878. if (newModel[0] && adapter.isBefore(newModel[0], date)) {
  21879. newModel = [newModel[0], date];
  21880. } else {
  21881. newModel = [date, newModel[0]];
  21882. }
  21883. }
  21884. }
  21885. } else {
  21886. newModel = [date];
  21887. }
  21888. emit('update:modelValue', newModel.filter(v => !!v));
  21889. }
  21890. const daysRef = ref();
  21891. function findElement(el) {
  21892. if (!el || el === daysRef.value) return null;
  21893. if ('vDate' in el.dataset) {
  21894. return adapter.date(el.dataset.vDate);
  21895. }
  21896. return findElement(el.parentElement);
  21897. }
  21898. function findDate(e) {
  21899. const x = 'changedTouches' in e ? e.changedTouches[0]?.clientX : e.clientX;
  21900. const y = 'changedTouches' in e ? e.changedTouches[0]?.clientY : e.clientY;
  21901. const el = document.elementFromPoint(x, y);
  21902. return findElement(el);
  21903. }
  21904. let canDrag = false;
  21905. function handleMousedown(e) {
  21906. hasScrolled.value = false;
  21907. const selected = findDate(e);
  21908. if (!selected) return;
  21909. const modelIndex = props.modelValue.findIndex(d => adapter.isEqual(d, selected));
  21910. if (modelIndex >= 0) {
  21911. canDrag = true;
  21912. dragHandle.value = modelIndex;
  21913. window.addEventListener('touchmove', handleTouchmove, {
  21914. passive: false
  21915. });
  21916. window.addEventListener('mousemove', handleTouchmove, {
  21917. passive: false
  21918. });
  21919. e.preventDefault();
  21920. }
  21921. window.addEventListener('touchend', handleTouchend, {
  21922. passive: false
  21923. });
  21924. window.addEventListener('mouseup', handleTouchend, {
  21925. passive: false
  21926. });
  21927. }
  21928. function handleTouchmove(e) {
  21929. if (!canDrag) return;
  21930. e.preventDefault();
  21931. isDragging.value = true;
  21932. const over = findDate(e);
  21933. if (!over) return;
  21934. selectDate(over);
  21935. }
  21936. function handleTouchend(e) {
  21937. if (e.cancelable) e.preventDefault();
  21938. window.removeEventListener('touchmove', handleTouchmove);
  21939. window.removeEventListener('mousemove', handleTouchmove);
  21940. window.removeEventListener('touchend', handleTouchend);
  21941. window.removeEventListener('mouseup', handleTouchend);
  21942. const end = findDate(e);
  21943. if (!end) return;
  21944. if (!hasScrolled.value) {
  21945. selectDate(end);
  21946. }
  21947. isDragging.value = false;
  21948. dragHandle.value = null;
  21949. canDrag = false;
  21950. }
  21951. return () => createVNode("div", {
  21952. "class": "v-date-picker-month"
  21953. }, [props.showWeek && createVNode("div", {
  21954. "key": "weeks",
  21955. "class": "v-date-picker-month__weeks"
  21956. }, [!props.hideWeekdays && createVNode("div", {
  21957. "key": "hide-week-days",
  21958. "class": "v-date-picker-month__day"
  21959. }, [createTextVNode("\xA0")]), weeks.value.map(week => createVNode("div", {
  21960. "class": ['v-date-picker-month__day', 'v-date-picker-month__day--adjacent']
  21961. }, [week]))]), createVNode("div", {
  21962. "ref": daysRef,
  21963. "class": "v-date-picker-month__days",
  21964. "onMousedown": handleMousedown,
  21965. "onTouchstart": handleMousedown
  21966. }, [!props.hideWeekdays && adapter.getWeekdays().map(weekDay => createVNode("div", {
  21967. "class": ['v-date-picker-month__day', 'v-date-picker-month__weekday']
  21968. }, [weekDay.charAt(0)])), daysInMonth.value.map((item, index) => createVNode("div", {
  21969. "class": ['v-date-picker-month__day', {
  21970. 'v-date-picker-month__day--selected': item.isSelected,
  21971. 'v-date-picker-month__day--start': item.isStart,
  21972. 'v-date-picker-month__day--end': item.isEnd,
  21973. 'v-date-picker-month__day--adjacent': item.isAdjacent,
  21974. 'v-date-picker-month__day--hide-adjacent': item.isHidden,
  21975. 'v-date-picker-month__day--week-start': item.isWeekStart,
  21976. 'v-date-picker-month__day--week-end': item.isWeekEnd,
  21977. 'v-date-picker-month__day--hovered': item.isHovered
  21978. }],
  21979. "data-v-date": !item.isHidden ? item.isoDate : undefined
  21980. }, [item.inRange && createVNode("div", {
  21981. "key": "in-range",
  21982. "class": ['v-date-picker-month__day--range', backgroundColorClasses.value],
  21983. "style": backgroundColorStyles.value
  21984. }, null), item.inHover && !item.isStart && !item.isEnd && !item.isHovered && !item.inRange && createVNode("div", {
  21985. "key": "in-hover",
  21986. "class": "v-date-picker-month__day--hover"
  21987. }, null), (props.showAdjacentMonths || !item.isAdjacent) && createVNode(VBtn, {
  21988. "icon": true,
  21989. "ripple": false,
  21990. "variant": (item.isToday || item.isHovered) && !item.isSelected ? 'outlined' : 'flat',
  21991. "active": item.isSelected,
  21992. "color": item.isSelected || item.isToday ? props.color : item.isHovered ? undefined : 'transparent'
  21993. }, {
  21994. default: () => [item.localized]
  21995. })]))])]);
  21996. }
  21997. });
  21998. const makeVDatePickerYearsProps = propsFactory({
  21999. color: String,
  22000. min: Number,
  22001. max: Number,
  22002. height: [String, Number],
  22003. displayDate: null
  22004. }, 'VDatePickerYears');
  22005. const VDatePickerYears = genericComponent()({
  22006. name: 'VDatePickerYears',
  22007. props: makeVDatePickerYearsProps(),
  22008. emits: {
  22009. 'update:displayDate': date => true,
  22010. 'update:viewMode': date => true
  22011. },
  22012. setup(props, _ref) {
  22013. let {
  22014. emit
  22015. } = _ref;
  22016. const adapter = useDate();
  22017. const displayYear = computed(() => adapter.getYear(props.displayDate ?? new Date()));
  22018. const years = computed(() => {
  22019. const min = props.min ?? displayYear.value - 50 - 2;
  22020. const max = props.max ?? displayYear.value + 50;
  22021. return createRange(max - min, min);
  22022. });
  22023. const yearRef = ref();
  22024. onMounted(() => {
  22025. yearRef.value?.$el.scrollIntoView({
  22026. block: 'center'
  22027. });
  22028. });
  22029. useRender(() => createVNode("div", {
  22030. "class": "v-date-picker-years",
  22031. "style": {
  22032. height: convertToUnit(props.height)
  22033. }
  22034. }, [createVNode("div", {
  22035. "class": "v-date-picker-years__content"
  22036. }, [years.value.map(year => createVNode(VBtn, {
  22037. "ref": year === displayYear.value ? yearRef : undefined,
  22038. "variant": year === displayYear.value ? 'flat' : 'text',
  22039. "rounded": "xl",
  22040. "active": year === displayYear.value,
  22041. "color": year === displayYear.value ? props.color : undefined,
  22042. "onClick": () => {
  22043. emit('update:displayDate', adapter.setYear(props.displayDate, year));
  22044. emit('update:viewMode', 'month');
  22045. }
  22046. }, {
  22047. default: () => [year]
  22048. }))])]));
  22049. return {};
  22050. }
  22051. });
  22052. // Types
  22053. const makeVDateCardProps = propsFactory({
  22054. cancelText: {
  22055. type: String,
  22056. default: '$vuetify.datePicker.cancel'
  22057. },
  22058. okText: {
  22059. type: String,
  22060. default: '$vuetify.datePicker.ok'
  22061. },
  22062. inputMode: {
  22063. type: String,
  22064. default: 'calendar'
  22065. },
  22066. hideActions: Boolean,
  22067. ...makeVDatePickerControlsProps(),
  22068. ...makeVDatePickerMonthProps(),
  22069. ...makeVDatePickerYearsProps(),
  22070. ...makeTransitionProps({
  22071. transition: {
  22072. component: VFadeTransition,
  22073. leaveAbsolute: true
  22074. }
  22075. })
  22076. }, 'VDateCard');
  22077. const VDateCard = genericComponent()({
  22078. name: 'VDateCard',
  22079. props: makeVDateCardProps(),
  22080. emits: {
  22081. save: () => true,
  22082. cancel: () => true,
  22083. 'update:displayDate': value => true,
  22084. 'update:inputMode': value => true,
  22085. 'update:modelValue': value => true,
  22086. 'update:viewMode': mode => true
  22087. },
  22088. setup(props, _ref) {
  22089. let {
  22090. emit,
  22091. slots
  22092. } = _ref;
  22093. const model = useProxiedModel(props, 'modelValue');
  22094. const {
  22095. t
  22096. } = useLocale();
  22097. createDatePicker(props);
  22098. function onDisplayUpdate(val) {
  22099. emit('update:displayDate', val);
  22100. }
  22101. function onViewModeUpdate(val) {
  22102. emit('update:viewMode', val);
  22103. }
  22104. function onSave() {
  22105. emit('update:modelValue', model.value);
  22106. emit('save');
  22107. }
  22108. function onCancel() {
  22109. emit('cancel');
  22110. }
  22111. useRender(() => {
  22112. const [cardProps] = VCard.filterProps(props);
  22113. const [datePickerControlsProps] = VDatePickerControls.filterProps(props);
  22114. const [datePickerMonthProps] = VDatePickerMonth.filterProps(props);
  22115. const [datePickerYearsProps] = VDatePickerYears.filterProps(props);
  22116. const hasActions = !props.hideActions || !!slots.actions;
  22117. return createVNode(VCard, mergeProps(cardProps, {
  22118. "class": "v-date-card"
  22119. }), {
  22120. ...slots,
  22121. default: () => createVNode(Fragment, null, [createVNode(VDatePickerControls, mergeProps(datePickerControlsProps, {
  22122. "onUpdate:displayDate": onDisplayUpdate,
  22123. "onUpdate:viewMode": onViewModeUpdate
  22124. }), null), createVNode(MaybeTransition, {
  22125. "transition": props.transition
  22126. }, {
  22127. default: () => [props.viewMode === 'month' ? createVNode(VDatePickerMonth, mergeProps(datePickerMonthProps, {
  22128. "modelValue": model.value,
  22129. "onUpdate:modelValue": $event => model.value = $event,
  22130. "onUpdate:displayDate": onDisplayUpdate
  22131. }), null) : createVNode(VDatePickerYears, mergeProps(datePickerYearsProps, {
  22132. "onUpdate:displayDate": onDisplayUpdate,
  22133. "onUpdate:viewMode": onViewModeUpdate
  22134. }), null)]
  22135. })]),
  22136. actions: !hasActions ? undefined : () => createVNode(Fragment, null, [slots.actions?.() ?? createVNode(Fragment, null, [createVNode(VBtn, {
  22137. "onClick": onCancel,
  22138. "text": t(props.cancelText)
  22139. }, null), createVNode(VBtn, {
  22140. "onClick": onSave,
  22141. "text": t(props.okText)
  22142. }, null)])])
  22143. });
  22144. });
  22145. return {};
  22146. }
  22147. });
  22148. // Types
  22149. const makeVDatePickerHeaderProps = propsFactory({
  22150. appendIcon: String,
  22151. color: String,
  22152. header: String,
  22153. transition: String
  22154. }, 'VDatePickerHeader');
  22155. const VDatePickerHeader = genericComponent()({
  22156. name: 'VDatePickerHeader',
  22157. props: makeVDatePickerHeaderProps(),
  22158. emits: {
  22159. 'click:append': () => true
  22160. },
  22161. setup(props, _ref) {
  22162. let {
  22163. emit,
  22164. slots
  22165. } = _ref;
  22166. const {
  22167. backgroundColorClasses,
  22168. backgroundColorStyles
  22169. } = useBackgroundColor(props, 'color');
  22170. function onClickAppend() {
  22171. emit('click:append');
  22172. }
  22173. useRender(() => {
  22174. const hasContent = !!(slots.default || props.header);
  22175. const hasAppend = !!(slots.append || props.appendIcon);
  22176. return createVNode("div", {
  22177. "class": ['v-date-picker-header', backgroundColorClasses.value],
  22178. "style": backgroundColorStyles.value
  22179. }, [slots.prepend && createVNode("div", {
  22180. "key": "prepend",
  22181. "class": "v-date-picker-header__prepend"
  22182. }, [slots.prepend()]), hasContent && createVNode(MaybeTransition, {
  22183. "key": "content",
  22184. "name": props.transition
  22185. }, {
  22186. default: () => [createVNode("div", {
  22187. "key": props.header,
  22188. "class": "v-date-picker-header__content"
  22189. }, [slots.default?.() ?? props.header])]
  22190. }), hasAppend && createVNode("div", {
  22191. "class": "v-date-picker-header__append"
  22192. }, [!slots.append ? createVNode(VBtn, {
  22193. "key": "append-btn",
  22194. "icon": props.appendIcon,
  22195. "variant": "text",
  22196. "onClick": onClickAppend
  22197. }, null) : createVNode(VDefaultsProvider, {
  22198. "key": "append-defaults",
  22199. "disabled": !props.appendIcon,
  22200. "defaults": {
  22201. VBtn: {
  22202. icon: props.appendIcon,
  22203. variant: 'text'
  22204. }
  22205. }
  22206. }, {
  22207. default: () => [slots.append?.()]
  22208. })])]);
  22209. });
  22210. return {};
  22211. }
  22212. });
  22213. // Utilities
  22214. const VPickerTitle = createSimpleFunctional('v-picker-title');
  22215. // Types
  22216. const makeVPickerProps = propsFactory({
  22217. landscape: Boolean,
  22218. title: String,
  22219. ...omit(makeVSheetProps(), ['color'])
  22220. }, 'VPicker');
  22221. const VPicker = genericComponent()({
  22222. name: 'VPicker',
  22223. props: makeVPickerProps(),
  22224. setup(props, _ref) {
  22225. let {
  22226. slots
  22227. } = _ref;
  22228. useRender(() => {
  22229. const [sheetProps] = VSheet.filterProps(props);
  22230. const hasTitle = !!(props.title || slots.title);
  22231. return createVNode(VSheet, mergeProps(sheetProps, {
  22232. "class": ['v-picker', {
  22233. 'v-picker--landscape': props.landscape,
  22234. 'v-picker--with-actions': !!slots.actions
  22235. }, props.class],
  22236. "style": props.style
  22237. }), {
  22238. default: () => [hasTitle && createVNode(VPickerTitle, {
  22239. "key": "picker-title"
  22240. }, {
  22241. default: () => [slots.title?.() ?? props.title]
  22242. }), slots.header && createVNode("div", {
  22243. "class": "v-picker__header"
  22244. }, [slots.header()]), createVNode("div", {
  22245. "class": "v-picker__body"
  22246. }, [slots.default?.()]), slots.actions?.()[0]?.children && createVNode("div", {
  22247. "class": "v-picker__actions"
  22248. }, [slots.actions()])]
  22249. });
  22250. });
  22251. return {};
  22252. }
  22253. });
  22254. // Types
  22255. const makeVDatePickerProps = propsFactory({
  22256. calendarIcon: {
  22257. type: String,
  22258. default: '$calendar'
  22259. },
  22260. keyboardIcon: {
  22261. type: String,
  22262. default: '$edit'
  22263. },
  22264. cancelText: {
  22265. type: String,
  22266. default: '$vuetify.datePicker.cancel'
  22267. },
  22268. okText: {
  22269. type: String,
  22270. default: '$vuetify.datePicker.ok'
  22271. },
  22272. inputText: {
  22273. type: String,
  22274. default: '$vuetify.datePicker.input.placeholder'
  22275. },
  22276. header: {
  22277. type: String,
  22278. default: '$vuetify.datePicker.header'
  22279. },
  22280. hideActions: Boolean,
  22281. ...makeDateProps(),
  22282. ...makeVDatePickerControlsProps(),
  22283. ...makeVDatePickerMonthProps(),
  22284. ...makeVDatePickerYearsProps(),
  22285. ...makeVPickerProps({
  22286. title: '$vuetify.datePicker.title'
  22287. })
  22288. }, 'VDatePicker');
  22289. const VDatePicker = genericComponent()({
  22290. name: 'VDatePicker',
  22291. props: makeVDatePickerProps(),
  22292. emits: {
  22293. 'click:cancel': () => true,
  22294. 'click:save': () => true,
  22295. ...dateEmits
  22296. },
  22297. setup(props, _ref) {
  22298. let {
  22299. emit,
  22300. slots
  22301. } = _ref;
  22302. const adapter = useDate();
  22303. const {
  22304. t
  22305. } = useLocale();
  22306. const {
  22307. model,
  22308. displayDate,
  22309. viewMode,
  22310. inputMode
  22311. } = createDatePicker(props);
  22312. const isReversing = shallowRef(false);
  22313. const inputModel = computed(() => model.value.length ? adapter.format(model.value[0], 'keyboardDate') : '');
  22314. const title = computed(() => t(props.title));
  22315. const header = computed(() => model.value.length ? adapter.format(model.value[0], 'normalDateWithWeekday') : t(props.header));
  22316. const headerIcon = computed(() => inputMode.value === 'calendar' ? props.keyboardIcon : props.calendarIcon);
  22317. const headerTransition = computed(() => `date-picker-header${isReversing.value ? '-reverse' : ''}-transition`);
  22318. watch(inputModel, () => {
  22319. const {
  22320. isValid,
  22321. date
  22322. } = adapter;
  22323. model.value = isValid(inputModel.value) ? [date(inputModel.value)] : [];
  22324. });
  22325. watch(model, (val, oldVal) => {
  22326. if (props.hideActions) {
  22327. emit('update:modelValue', val);
  22328. }
  22329. if (val[0] && oldVal[0]) {
  22330. isReversing.value = adapter.isBefore(val[0], oldVal[0]);
  22331. }
  22332. });
  22333. function onClickCancel() {
  22334. emit('click:cancel');
  22335. }
  22336. function onClickSave() {
  22337. emit('click:save');
  22338. emit('update:modelValue', model.value);
  22339. }
  22340. function onClickAppend() {
  22341. inputMode.value = inputMode.value === 'calendar' ? 'keyboard' : 'calendar';
  22342. }
  22343. const headerSlotProps = computed(() => ({
  22344. header: header.value,
  22345. appendIcon: headerIcon.value,
  22346. transition: headerTransition.value,
  22347. 'onClick:append': onClickAppend
  22348. }));
  22349. useRender(() => {
  22350. const [pickerProps] = VPicker.filterProps(props);
  22351. const [datePickerControlsProps] = VDatePickerControls.filterProps(props);
  22352. const [datePickerMonthProps] = VDatePickerMonth.filterProps(props);
  22353. const [datePickerYearsProps] = VDatePickerYears.filterProps(props);
  22354. return createVNode(VPicker, mergeProps(pickerProps, {
  22355. "class": ['v-date-picker', props.class],
  22356. "style": props.style,
  22357. "title": title.value,
  22358. "width": props.showWeek ? 408 : 360
  22359. }), {
  22360. header: () => slots.header?.(headerSlotProps.value) ?? createVNode(VDatePickerHeader, mergeProps({
  22361. "key": "header"
  22362. }, headerSlotProps.value), null),
  22363. default: () => inputMode.value === 'calendar' ? createVNode(Fragment, null, [createVNode(VDatePickerControls, mergeProps(datePickerControlsProps, {
  22364. "displayDate": displayDate.value,
  22365. "onUpdate:displayDate": $event => displayDate.value = $event,
  22366. "viewMode": viewMode.value,
  22367. "onUpdate:viewMode": $event => viewMode.value = $event
  22368. }), null), createVNode(VFadeTransition, {
  22369. "hideOnLeave": true
  22370. }, {
  22371. default: () => [viewMode.value === 'month' ? createVNode(VDatePickerMonth, mergeProps({
  22372. "key": "date-picker-month"
  22373. }, datePickerMonthProps, {
  22374. "modelValue": model.value,
  22375. "onUpdate:modelValue": $event => model.value = $event,
  22376. "displayDate": displayDate.value,
  22377. "onUpdate:displayDate": $event => displayDate.value = $event
  22378. }), null) : createVNode(VDatePickerYears, mergeProps({
  22379. "key": "date-picker-years"
  22380. }, datePickerYearsProps, {
  22381. "displayDate": displayDate.value,
  22382. "onUpdate:displayDate": $event => displayDate.value = $event,
  22383. "viewMode": viewMode.value,
  22384. "onUpdate:viewMode": $event => viewMode.value = $event
  22385. }), null)]
  22386. })]) : createVNode("div", {
  22387. "class": "v-date-picker__input"
  22388. }, [createVNode(VTextField, {
  22389. "modelValue": inputModel.value,
  22390. "onUpdate:modelValue": $event => inputModel.value = $event,
  22391. "label": t(props.inputText),
  22392. "placeholder": "dd/mm/yyyy"
  22393. }, null)]),
  22394. actions: () => !props.hideActions ? createVNode("div", null, [createVNode(VBtn, {
  22395. "variant": "text",
  22396. "color": props.color,
  22397. "onClick": onClickCancel,
  22398. "text": t(props.cancelText)
  22399. }, null), createVNode(VBtn, {
  22400. "variant": "text",
  22401. "color": props.color,
  22402. "onClick": onClickSave,
  22403. "text": t(props.okText)
  22404. }, null)]) : undefined
  22405. });
  22406. });
  22407. return {};
  22408. }
  22409. });
  22410. // Types
  22411. const makeVInfiniteScrollProps = propsFactory({
  22412. color: String,
  22413. direction: {
  22414. type: String,
  22415. default: 'vertical',
  22416. validator: v => ['vertical', 'horizontal'].includes(v)
  22417. },
  22418. side: {
  22419. type: String,
  22420. default: 'end',
  22421. validator: v => ['start', 'end', 'both'].includes(v)
  22422. },
  22423. mode: {
  22424. type: String,
  22425. default: 'intersect',
  22426. validator: v => ['intersect', 'manual'].includes(v)
  22427. },
  22428. margin: [Number, String],
  22429. loadMoreText: {
  22430. type: String,
  22431. default: '$vuetify.infiniteScroll.loadMore'
  22432. },
  22433. emptyText: {
  22434. type: String,
  22435. default: '$vuetify.infiniteScroll.empty'
  22436. },
  22437. ...makeDimensionProps(),
  22438. ...makeTagProps()
  22439. }, 'VInfiniteScroll');
  22440. const VInfiniteScrollIntersect = defineComponent({
  22441. name: 'VInfiniteScrollIntersect',
  22442. props: {
  22443. side: {
  22444. type: String,
  22445. required: true
  22446. },
  22447. rootRef: null,
  22448. rootMargin: String
  22449. },
  22450. emits: {
  22451. intersect: (side, isIntersecting) => true
  22452. },
  22453. setup(props, _ref) {
  22454. let {
  22455. emit
  22456. } = _ref;
  22457. const {
  22458. intersectionRef,
  22459. isIntersecting
  22460. } = useIntersectionObserver(entries => {}, props.rootMargin ? {
  22461. rootMargin: props.rootMargin
  22462. } : undefined);
  22463. watch(isIntersecting, async val => {
  22464. emit('intersect', props.side, val);
  22465. });
  22466. useRender(() => createVNode("div", {
  22467. "class": "v-infinite-scroll-intersect",
  22468. "ref": intersectionRef
  22469. }, [createTextVNode("\xA0")]));
  22470. return {};
  22471. }
  22472. });
  22473. const VInfiniteScroll = genericComponent()({
  22474. name: 'VInfiniteScroll',
  22475. props: makeVInfiniteScrollProps(),
  22476. emits: {
  22477. load: options => true
  22478. },
  22479. setup(props, _ref2) {
  22480. let {
  22481. slots,
  22482. emit
  22483. } = _ref2;
  22484. const rootEl = ref();
  22485. const startStatus = shallowRef('ok');
  22486. const endStatus = shallowRef('ok');
  22487. const margin = computed(() => convertToUnit(props.margin));
  22488. const isIntersecting = shallowRef(false);
  22489. function setScrollAmount(amount) {
  22490. if (!rootEl.value) return;
  22491. const property = props.direction === 'vertical' ? 'scrollTop' : 'scrollLeft';
  22492. rootEl.value[property] = amount;
  22493. }
  22494. function getScrollAmount() {
  22495. if (!rootEl.value) return 0;
  22496. const property = props.direction === 'vertical' ? 'scrollTop' : 'scrollLeft';
  22497. return rootEl.value[property];
  22498. }
  22499. function getScrollSize() {
  22500. if (!rootEl.value) return 0;
  22501. const property = props.direction === 'vertical' ? 'scrollHeight' : 'scrollWidth';
  22502. return rootEl.value[property];
  22503. }
  22504. function getContainerSize() {
  22505. if (!rootEl.value) return 0;
  22506. const property = props.direction === 'vertical' ? 'clientHeight' : 'clientWidth';
  22507. return rootEl.value[property];
  22508. }
  22509. onMounted(() => {
  22510. if (!rootEl.value) return;
  22511. if (props.side === 'start') {
  22512. setScrollAmount(getScrollSize());
  22513. } else if (props.side === 'both') {
  22514. setScrollAmount(getScrollSize() / 2 - getContainerSize() / 2);
  22515. }
  22516. });
  22517. function setStatus(side, status) {
  22518. if (side === 'start') {
  22519. startStatus.value = status;
  22520. } else if (side === 'end') {
  22521. endStatus.value = status;
  22522. }
  22523. }
  22524. function getStatus(side) {
  22525. return side === 'start' ? startStatus.value : endStatus.value;
  22526. }
  22527. let previousScrollSize = 0;
  22528. function handleIntersect(side, _isIntersecting) {
  22529. isIntersecting.value = _isIntersecting;
  22530. if (isIntersecting.value) {
  22531. intersecting(side);
  22532. }
  22533. }
  22534. function intersecting(side) {
  22535. if (props.mode !== 'manual' && !isIntersecting.value) return;
  22536. const status = getStatus(side);
  22537. if (!rootEl.value || status === 'loading') return;
  22538. previousScrollSize = getScrollSize();
  22539. setStatus(side, 'loading');
  22540. function done(status) {
  22541. setStatus(side, status);
  22542. nextTick(() => {
  22543. if (status === 'empty' || status === 'error') return;
  22544. if (status === 'ok' && side === 'start') {
  22545. setScrollAmount(getScrollSize() - previousScrollSize + getScrollAmount());
  22546. }
  22547. if (props.mode !== 'manual') {
  22548. nextTick(() => {
  22549. window.requestAnimationFrame(() => {
  22550. window.requestAnimationFrame(() => {
  22551. window.requestAnimationFrame(() => {
  22552. intersecting(side);
  22553. });
  22554. });
  22555. });
  22556. });
  22557. }
  22558. });
  22559. }
  22560. emit('load', {
  22561. side,
  22562. done
  22563. });
  22564. }
  22565. const {
  22566. t
  22567. } = useLocale();
  22568. function renderSide(side, status) {
  22569. if (props.side !== side && props.side !== 'both') return;
  22570. const onClick = () => intersecting(side);
  22571. const slotProps = {
  22572. side,
  22573. props: {
  22574. onClick,
  22575. color: props.color
  22576. }
  22577. };
  22578. if (status === 'error') return slots.error?.(slotProps);
  22579. if (status === 'empty') return slots.empty?.(slotProps) ?? createVNode("div", null, [t(props.emptyText)]);
  22580. if (props.mode === 'manual') {
  22581. if (status === 'loading') {
  22582. return slots.loading?.(slotProps) ?? createVNode(VProgressCircular, {
  22583. "indeterminate": true,
  22584. "color": props.color
  22585. }, null);
  22586. }
  22587. return slots['load-more']?.(slotProps) ?? createVNode(VBtn, {
  22588. "variant": "outlined",
  22589. "color": props.color,
  22590. "onClick": onClick
  22591. }, {
  22592. default: () => [t(props.loadMoreText)]
  22593. });
  22594. }
  22595. return slots.loading?.(slotProps) ?? createVNode(VProgressCircular, {
  22596. "indeterminate": true,
  22597. "color": props.color
  22598. }, null);
  22599. }
  22600. const {
  22601. dimensionStyles
  22602. } = useDimension(props);
  22603. useRender(() => {
  22604. const Tag = props.tag;
  22605. const hasStartIntersect = props.side === 'start' || props.side === 'both';
  22606. const hasEndIntersect = props.side === 'end' || props.side === 'both';
  22607. const intersectMode = props.mode === 'intersect';
  22608. return createVNode(Tag, {
  22609. "ref": rootEl,
  22610. "class": ['v-infinite-scroll', `v-infinite-scroll--${props.direction}`, {
  22611. 'v-infinite-scroll--start': hasStartIntersect,
  22612. 'v-infinite-scroll--end': hasEndIntersect
  22613. }],
  22614. "style": dimensionStyles.value
  22615. }, {
  22616. default: () => [createVNode("div", {
  22617. "class": "v-infinite-scroll__side"
  22618. }, [renderSide('start', startStatus.value)]), rootEl.value && hasStartIntersect && intersectMode && createVNode(VInfiniteScrollIntersect, {
  22619. "key": "start",
  22620. "side": "start",
  22621. "onIntersect": handleIntersect,
  22622. "rootRef": rootEl.value,
  22623. "rootMargin": margin.value
  22624. }, null), slots.default?.(), rootEl.value && hasEndIntersect && intersectMode && createVNode(VInfiniteScrollIntersect, {
  22625. "key": "end",
  22626. "side": "end",
  22627. "onIntersect": handleIntersect,
  22628. "rootRef": rootEl.value,
  22629. "rootMargin": margin.value
  22630. }, null), createVNode("div", {
  22631. "class": "v-infinite-scroll__side"
  22632. }, [renderSide('end', endStatus.value)])]
  22633. });
  22634. });
  22635. }
  22636. });
  22637. // Types
  22638. const makeVOtpInputProps = propsFactory({
  22639. autofocus: Boolean,
  22640. divider: String,
  22641. focusAll: Boolean,
  22642. label: {
  22643. type: String,
  22644. default: '$vuetify.input.otp'
  22645. },
  22646. length: {
  22647. type: [Number, String],
  22648. default: 6
  22649. },
  22650. modelValue: {
  22651. type: [Number, String],
  22652. default: undefined
  22653. },
  22654. placeholder: String,
  22655. type: {
  22656. type: String,
  22657. default: 'text'
  22658. },
  22659. ...makeDimensionProps(),
  22660. ...makeFocusProps(),
  22661. ...only(makeVFieldProps({
  22662. variant: 'outlined'
  22663. }), ['baseColor', 'bgColor', 'class', 'color', 'disabled', 'error', 'loading', 'rounded', 'style', 'theme', 'variant'])
  22664. }, 'VOtpInput');
  22665. const VOtpInput = genericComponent()({
  22666. name: 'VOtpInput',
  22667. props: makeVOtpInputProps(),
  22668. emits: {
  22669. finish: val => true,
  22670. 'update:focused': val => true,
  22671. 'update:modelValue': val => true
  22672. },
  22673. setup(props, _ref) {
  22674. let {
  22675. emit,
  22676. slots
  22677. } = _ref;
  22678. const {
  22679. dimensionStyles
  22680. } = useDimension(props);
  22681. const {
  22682. isFocused,
  22683. focus,
  22684. blur
  22685. } = useFocus(props);
  22686. const model = useProxiedModel(props, 'modelValue', '', val => String(val).split(''), val => val.join(''));
  22687. const {
  22688. t
  22689. } = useLocale();
  22690. const fields = computed(() => Array(Number(props.length)).fill(0));
  22691. const focusIndex = ref(-1);
  22692. const contentRef = ref();
  22693. const inputRef = ref([]);
  22694. const current = computed(() => inputRef.value[focusIndex.value]);
  22695. function onInput() {
  22696. const array = model.value.slice();
  22697. const value = current.value.value;
  22698. array[focusIndex.value] = value;
  22699. model.value = array;
  22700. }
  22701. function onKeydown(e) {
  22702. const array = model.value.slice();
  22703. const index = focusIndex.value;
  22704. let target = null;
  22705. if (e.key === 'ArrowLeft') {
  22706. target = 'prev';
  22707. } else if (e.key === 'ArrowRight') {
  22708. target = 'next';
  22709. } else if (e.key === 'Backspace') {
  22710. if (focusIndex.value > 0) {
  22711. target = 'prev';
  22712. }
  22713. } else if (e.key === 'Delete') {
  22714. array[focusIndex.value] = '';
  22715. model.value = array;
  22716. requestAnimationFrame(() => {
  22717. inputRef.value[index].select();
  22718. });
  22719. } else if (props.type === 'number' && isNaN(parseInt(e.key))) {
  22720. return;
  22721. } else if (focusIndex.value > model.value.length) {
  22722. target = model.value.length + 1;
  22723. } else if (focusIndex.value + 1 !== Number(props.length)) {
  22724. target = 'next';
  22725. } else {
  22726. requestAnimationFrame(() => current.value?.blur());
  22727. return;
  22728. }
  22729. requestAnimationFrame(() => {
  22730. if (target != null) {
  22731. focusChild(contentRef.value, target);
  22732. }
  22733. });
  22734. }
  22735. function onPaste(index, e) {
  22736. e.preventDefault();
  22737. e.stopPropagation();
  22738. model.value = (e?.clipboardData?.getData('Text') ?? '').split('');
  22739. inputRef.value?.[index].blur();
  22740. }
  22741. function reset() {
  22742. model.value = [];
  22743. }
  22744. function onFocus(e, index) {
  22745. focus();
  22746. focusIndex.value = index;
  22747. }
  22748. function onBlur() {
  22749. blur();
  22750. focusIndex.value = -1;
  22751. }
  22752. provideDefaults({
  22753. VField: {
  22754. disabled: computed(() => props.disabled),
  22755. error: computed(() => props.error),
  22756. variant: computed(() => props.variant)
  22757. }
  22758. }, {
  22759. scoped: true
  22760. });
  22761. watch(model, val => {
  22762. if (val.length === props.length) emit('finish', val.join(''));
  22763. }, {
  22764. deep: true
  22765. });
  22766. watch(focusIndex, val => {
  22767. if (val < 0) return;
  22768. IN_BROWSER && window.requestAnimationFrame(() => {
  22769. inputRef.value[val].select();
  22770. });
  22771. });
  22772. useRender(() => {
  22773. return createVNode("div", {
  22774. "class": ['v-otp-input', {
  22775. 'v-otp-input--divided': !!props.divider
  22776. }, props.class],
  22777. "style": [props.style]
  22778. }, [createVNode("div", {
  22779. "ref": contentRef,
  22780. "class": "v-otp-input__content",
  22781. "style": [dimensionStyles.value]
  22782. }, [fields.value.map((_, i) => createVNode(Fragment, null, [props.divider && i !== 0 && createVNode("span", {
  22783. "class": "v-otp-input__divider"
  22784. }, [props.divider]), createVNode(VField, {
  22785. "focused": isFocused.value && props.focusAll || focusIndex.value === i,
  22786. "key": i
  22787. }, {
  22788. ...slots,
  22789. default: () => {
  22790. return createVNode("input", {
  22791. "ref": val => inputRef.value[i] = val,
  22792. "aria-label": t(props.label, i + 1),
  22793. "autofocus": i === 0 && props.autofocus,
  22794. "autocomplete": "one-time-code",
  22795. "class": ['v-otp-input__field'],
  22796. "inputmode": "text",
  22797. "min": props.type === 'number' ? 0 : undefined,
  22798. "maxlength": "1",
  22799. "placeholder": props.placeholder,
  22800. "type": props.type,
  22801. "value": model.value[i],
  22802. "onInput": onInput,
  22803. "onFocus": e => onFocus(e, i),
  22804. "onBlur": onBlur,
  22805. "onKeydown": onKeydown,
  22806. "onPaste": event => onPaste(i, event)
  22807. }, null);
  22808. }
  22809. })])), createVNode(VOverlay, {
  22810. "contained": true,
  22811. "content-class": "v-otp-input__loader",
  22812. "model-value": !!props.loading,
  22813. "persistent": true
  22814. }, {
  22815. default: () => [slots.loader?.() ?? createVNode(VProgressCircular, {
  22816. "color": typeof props.loading === 'boolean' ? undefined : props.loading,
  22817. "indeterminate": true,
  22818. "size": "24",
  22819. "width": "2"
  22820. }, null)]
  22821. }), slots.default?.()])]);
  22822. });
  22823. return {
  22824. blur: () => {
  22825. inputRef.value?.some(input => input.blur());
  22826. },
  22827. focus: () => {
  22828. inputRef.value?.[0].focus();
  22829. },
  22830. reset,
  22831. isFocused
  22832. };
  22833. }
  22834. });
  22835. // Types
  22836. const rootTypes = {
  22837. actions: 'button@2',
  22838. article: 'heading, paragraph',
  22839. avatar: 'avatar',
  22840. button: 'button',
  22841. card: 'image, heading',
  22842. 'card-avatar': 'image, list-item-avatar',
  22843. chip: 'chip',
  22844. 'date-picker': 'list-item, heading, divider, date-picker-options, date-picker-days, actions',
  22845. 'date-picker-options': 'text, avatar@2',
  22846. 'date-picker-days': 'avatar@28',
  22847. divider: 'divider',
  22848. heading: 'heading',
  22849. image: 'image',
  22850. 'list-item': 'text',
  22851. 'list-item-avatar': 'avatar, text',
  22852. 'list-item-two-line': 'sentences',
  22853. 'list-item-avatar-two-line': 'avatar, sentences',
  22854. 'list-item-three-line': 'paragraph',
  22855. 'list-item-avatar-three-line': 'avatar, paragraph',
  22856. paragraph: 'text@3',
  22857. sentences: 'text@2',
  22858. subtitle: 'text',
  22859. table: 'table-heading, table-thead, table-tbody, table-tfoot',
  22860. 'table-heading': 'chip, text',
  22861. 'table-thead': 'heading@6',
  22862. 'table-tbody': 'table-row-divider@6',
  22863. 'table-row-divider': 'table-row, divider',
  22864. 'table-row': 'text@6',
  22865. 'table-tfoot': 'text@2, avatar@2',
  22866. text: 'text'
  22867. };
  22868. function genBone(type) {
  22869. let children = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  22870. return createVNode("div", {
  22871. "class": ['v-skeleton-loader__bone', `v-skeleton-loader__${type}`]
  22872. }, [children]);
  22873. }
  22874. function genBones(bone) {
  22875. // e.g. 'text@3'
  22876. const [type, length] = bone.split('@');
  22877. // Generate a length array based upon
  22878. // value after @ in the bone string
  22879. return Array.from({
  22880. length
  22881. }).map(() => genStructure(type));
  22882. }
  22883. function genStructure(type) {
  22884. let children = [];
  22885. if (!type) return children;
  22886. // TODO: figure out a better way to type this
  22887. const bone = rootTypes[type];
  22888. // End of recursion, do nothing
  22889. /* eslint-disable-next-line no-empty, brace-style */
  22890. if (type === bone) ;
  22891. // Array of values - e.g. 'heading, paragraph, text@2'
  22892. else if (type.includes(',')) return mapBones(type);
  22893. // Array of values - e.g. 'paragraph@4'
  22894. else if (type.includes('@')) return genBones(type);
  22895. // Array of values - e.g. 'card@2'
  22896. else if (bone.includes(',')) children = mapBones(bone);
  22897. // Array of values - e.g. 'list-item@2'
  22898. else if (bone.includes('@')) children = genBones(bone);
  22899. // Single value - e.g. 'card-heading'
  22900. else if (bone) children.push(genStructure(bone));
  22901. return [genBone(type, children)];
  22902. }
  22903. function mapBones(bones) {
  22904. // Remove spaces and return array of structures
  22905. return bones.replace(/\s/g, '').split(',').map(genStructure);
  22906. }
  22907. const makeVSkeletonLoaderProps = propsFactory({
  22908. boilerplate: Boolean,
  22909. color: String,
  22910. loading: Boolean,
  22911. loadingText: {
  22912. type: String,
  22913. default: '$vuetify.loading'
  22914. },
  22915. type: {
  22916. type: [String, Array],
  22917. default: 'image'
  22918. },
  22919. ...makeDimensionProps(),
  22920. ...makeElevationProps(),
  22921. ...makeThemeProps()
  22922. }, 'VSkeletonLoader');
  22923. const VSkeletonLoader = genericComponent()({
  22924. name: 'VSkeletonLoader',
  22925. props: makeVSkeletonLoaderProps(),
  22926. setup(props, _ref) {
  22927. let {
  22928. slots
  22929. } = _ref;
  22930. const {
  22931. backgroundColorClasses,
  22932. backgroundColorStyles
  22933. } = useBackgroundColor(toRef(props, 'color'));
  22934. const {
  22935. dimensionStyles
  22936. } = useDimension(props);
  22937. const {
  22938. elevationClasses
  22939. } = useElevation(props);
  22940. const {
  22941. themeClasses
  22942. } = provideTheme(props);
  22943. const {
  22944. t
  22945. } = useLocale();
  22946. const items = computed(() => genStructure(wrapInArray(props.type).join(',')));
  22947. useRender(() => {
  22948. const isLoading = !slots.default || props.loading;
  22949. return createVNode("div", {
  22950. "class": ['v-skeleton-loader', {
  22951. 'v-skeleton-loader--boilerplate': props.boilerplate
  22952. }, themeClasses.value, backgroundColorClasses.value, elevationClasses.value],
  22953. "style": [backgroundColorStyles.value, isLoading ? dimensionStyles.value : {}],
  22954. "aria-busy": !props.boilerplate ? isLoading : undefined,
  22955. "aria-live": !props.boilerplate ? 'polite' : undefined,
  22956. "aria-label": !props.boilerplate ? t(props.loadingText) : undefined,
  22957. "role": !props.boilerplate ? 'alert' : undefined
  22958. }, [isLoading ? items.value : slots.default?.()]);
  22959. });
  22960. return {};
  22961. }
  22962. });
  22963. // Types
  22964. const makeVStepperActionsProps = propsFactory({
  22965. color: String,
  22966. disabled: {
  22967. type: [Boolean, String],
  22968. default: false
  22969. },
  22970. prevText: {
  22971. type: String,
  22972. default: '$vuetify.stepper.prev'
  22973. },
  22974. nextText: {
  22975. type: String,
  22976. default: '$vuetify.stepper.next'
  22977. }
  22978. }, 'VStepperActions');
  22979. const VStepperActions = genericComponent()({
  22980. name: 'VStepperActions',
  22981. props: makeVStepperActionsProps(),
  22982. emits: {
  22983. 'click:prev': () => true,
  22984. 'click:next': () => true
  22985. },
  22986. setup(props, _ref) {
  22987. let {
  22988. emit,
  22989. slots
  22990. } = _ref;
  22991. const {
  22992. t
  22993. } = useLocale();
  22994. function onClickPrev() {
  22995. emit('click:prev');
  22996. }
  22997. function onClickNext() {
  22998. emit('click:next');
  22999. }
  23000. useRender(() => {
  23001. return createVNode("div", {
  23002. "class": "v-stepper-actions"
  23003. }, [createVNode(VBtn, {
  23004. "disabled": ['prev', true].includes(props.disabled),
  23005. "text": t(props.prevText),
  23006. "variant": "text",
  23007. "onClick": onClickPrev
  23008. }, null), createVNode(VBtn, {
  23009. "disabled": ['next', true].includes(props.disabled),
  23010. "color": props.color,
  23011. "text": t(props.nextText),
  23012. "variant": "tonal",
  23013. "onClick": onClickNext
  23014. }, null)]);
  23015. });
  23016. return {};
  23017. }
  23018. });
  23019. // Utilities
  23020. const VStepperHeader = createSimpleFunctional('v-stepper-header');
  23021. // Types
  23022. const makeVStepperItemProps = propsFactory({
  23023. color: String,
  23024. title: String,
  23025. subtitle: String,
  23026. complete: Boolean,
  23027. completeIcon: {
  23028. type: String,
  23029. default: '$complete'
  23030. },
  23031. editable: Boolean,
  23032. editIcon: {
  23033. type: String,
  23034. default: '$edit'
  23035. },
  23036. error: Boolean,
  23037. errorIcon: {
  23038. type: String,
  23039. default: '$error'
  23040. },
  23041. icon: String,
  23042. ripple: {
  23043. type: [Boolean, Object],
  23044. default: true
  23045. },
  23046. rules: {
  23047. type: Array,
  23048. default: () => []
  23049. },
  23050. ...makeGroupItemProps()
  23051. }, 'VStepperItem');
  23052. const VStepperItem = genericComponent()({
  23053. name: 'VStepperItem',
  23054. directives: {
  23055. Ripple
  23056. },
  23057. props: makeVStepperItemProps(),
  23058. emits: {
  23059. 'group:selected': val => true
  23060. },
  23061. setup(props, _ref) {
  23062. let {
  23063. slots
  23064. } = _ref;
  23065. const group = useGroupItem(props, VStepperSymbol, true);
  23066. const step = computed(() => group?.value.value ?? props.value);
  23067. const isValid = computed(() => props.rules.every(handler => handler() === true));
  23068. const canEdit = computed(() => !props.disabled && props.editable);
  23069. const hasError = computed(() => props.error || !isValid.value);
  23070. const hasCompleted = computed(() => props.complete || props.rules.length > 0 && isValid.value);
  23071. const icon = computed(() => {
  23072. if (hasError.value) return props.errorIcon;
  23073. if (hasCompleted.value) return props.completeIcon;
  23074. if (props.editable) return props.editIcon;
  23075. return props.icon;
  23076. });
  23077. const slotProps = computed(() => ({
  23078. canEdit: canEdit.value,
  23079. hasError: hasError.value,
  23080. hasCompleted: hasCompleted.value,
  23081. title: props.title,
  23082. subtitle: props.subtitle,
  23083. step: step.value,
  23084. value: props.value
  23085. }));
  23086. useRender(() => {
  23087. const hasColor = (!group || group.isSelected.value || hasCompleted.value || canEdit.value) && !hasError.value && !props.disabled;
  23088. const hasTitle = !!(props.title || slots.title);
  23089. const hasSubtitle = !!(props.subtitle || slots.subtitle);
  23090. function onClick() {
  23091. group?.toggle();
  23092. }
  23093. return withDirectives(createVNode("button", {
  23094. "class": ['v-stepper-item', {
  23095. 'v-stepper-item--complete': hasCompleted.value,
  23096. 'v-stepper-item--disabled': props.disabled,
  23097. 'v-stepper-item--error': hasError.value
  23098. }, group?.selectedClass.value],
  23099. "disabled": !props.editable,
  23100. "onClick": onClick
  23101. }, [createVNode(VAvatar, {
  23102. "key": "stepper-avatar",
  23103. "class": "v-stepper-item__avatar",
  23104. "color": hasColor ? props.color : undefined,
  23105. "size": 24
  23106. }, {
  23107. default: () => [slots.icon?.(slotProps.value) ?? (icon.value ? createVNode(VIcon, {
  23108. "icon": icon.value
  23109. }, null) : step.value)]
  23110. }), createVNode("div", {
  23111. "class": "v-stepper-item__content"
  23112. }, [hasTitle && createVNode("div", {
  23113. "key": "title",
  23114. "class": "v-stepper-item__title"
  23115. }, [slots.title?.(slotProps.value) ?? props.title]), hasSubtitle && createVNode("div", {
  23116. "key": "subtitle",
  23117. "class": "v-stepper-item__subtitle"
  23118. }, [slots.subtitle?.(slotProps.value) ?? props.subtitle]), slots.default?.(slotProps.value)])]), [[resolveDirective("ripple"), props.ripple && props.editable, null]]);
  23119. });
  23120. return {};
  23121. }
  23122. });
  23123. // Types
  23124. const VStepperSymbol$1 = Symbol.for('vuetify:v-stepper');
  23125. const makeVStepperWindowProps = propsFactory({
  23126. ...makeVWindowProps({
  23127. mandatory: false
  23128. })
  23129. }, 'VStepperWindow');
  23130. const VStepperWindow = genericComponent()({
  23131. name: 'VStepperWindow',
  23132. props: makeVStepperWindowProps(),
  23133. emits: {
  23134. 'update:modelValue': v => true
  23135. },
  23136. setup(props, _ref) {
  23137. let {
  23138. slots
  23139. } = _ref;
  23140. const group = inject$1(VStepperSymbol$1, null);
  23141. const _model = useProxiedModel(props, 'modelValue');
  23142. const model = computed({
  23143. get() {
  23144. // Always return modelValue if defined
  23145. // or if not within a VStepper group
  23146. if (_model.value != null || !group) return _model.value;
  23147. // If inside of a VStepper, find the currently selected
  23148. // item by id. Item value may be assigned by its index
  23149. return group.items.value.find(item => group.selected.value.includes(item.id))?.value;
  23150. },
  23151. set(val) {
  23152. _model.value = val;
  23153. }
  23154. });
  23155. useRender(() => {
  23156. const [windowProps] = VWindow.filterProps(props);
  23157. return createVNode(VWindow, mergeProps(windowProps, {
  23158. "modelValue": model.value,
  23159. "onUpdate:modelValue": $event => model.value = $event,
  23160. "class": "v-stepper-window"
  23161. }), slots);
  23162. });
  23163. return {};
  23164. }
  23165. });
  23166. const makeVStepperWindowItemProps = propsFactory({
  23167. ...makeVWindowItemProps()
  23168. }, 'VStepperWindowItem');
  23169. const VStepperWindowItem = genericComponent()({
  23170. name: 'VStepperWindowItem',
  23171. props: makeVStepperWindowItemProps(),
  23172. setup(props, _ref) {
  23173. let {
  23174. slots
  23175. } = _ref;
  23176. useRender(() => {
  23177. const [windowItemProps] = VWindowItem.filterProps(props);
  23178. return createVNode(VWindowItem, mergeProps(windowItemProps, {
  23179. "class": "v-stepper-window-item"
  23180. }), slots);
  23181. });
  23182. return {};
  23183. }
  23184. });
  23185. // Types
  23186. const VStepperSymbol = Symbol.for('vuetify:v-stepper');
  23187. const makeVStepperProps = propsFactory({
  23188. altLabels: Boolean,
  23189. bgColor: String,
  23190. editable: Boolean,
  23191. hideActions: Boolean,
  23192. items: {
  23193. type: Array,
  23194. default: () => []
  23195. },
  23196. itemTitle: {
  23197. type: String,
  23198. default: 'title'
  23199. },
  23200. itemValue: {
  23201. type: String,
  23202. default: 'value'
  23203. },
  23204. mobile: Boolean,
  23205. nonLinear: Boolean,
  23206. flat: Boolean,
  23207. ...makeGroupProps({
  23208. mandatory: 'force',
  23209. selectedClass: 'v-stepper-item--selected'
  23210. }),
  23211. ...omit(makeVSheetProps(), ['color']),
  23212. ...makeVStepperActionsProps()
  23213. }, 'VStepper');
  23214. const VStepper = genericComponent()({
  23215. name: 'VStepper',
  23216. props: makeVStepperProps(),
  23217. emits: {
  23218. 'update:modelValue': v => true
  23219. },
  23220. setup(props, _ref) {
  23221. let {
  23222. slots
  23223. } = _ref;
  23224. // TODO: fix typing
  23225. const {
  23226. items: _items,
  23227. next,
  23228. prev,
  23229. selected
  23230. } = useGroup(props, VStepperSymbol);
  23231. const {
  23232. editable,
  23233. prevText,
  23234. nextText
  23235. } = toRefs(props);
  23236. const items = computed(() => props.items.map((item, index) => {
  23237. const title = getPropertyFromItem(item, props.itemTitle, item);
  23238. const value = getPropertyFromItem(item, props.itemValue, index + 1);
  23239. return {
  23240. title,
  23241. value,
  23242. raw: item
  23243. };
  23244. }));
  23245. const activeIndex = computed(() => {
  23246. return _items.value.findIndex(item => selected.value.includes(item.id));
  23247. });
  23248. const disabled = computed(() => {
  23249. if (props.disabled) return props.disabled;
  23250. if (activeIndex.value === 0) return 'prev';
  23251. if (activeIndex.value === _items.value.length - 1) return 'next';
  23252. return false;
  23253. });
  23254. provideDefaults({
  23255. VStepperItem: {
  23256. editable,
  23257. prevText,
  23258. nextText
  23259. },
  23260. VStepperActions: {
  23261. disabled
  23262. }
  23263. });
  23264. useRender(() => {
  23265. const [sheetProps] = VSheet.filterProps(props);
  23266. const [stepperActionProps] = VStepperActions.filterProps(props);
  23267. const hasHeader = !!(slots.header || props.items.length);
  23268. const hasWindow = props.items.length > 0;
  23269. const hasActions = !props.hideActions && !!(hasWindow || slots.actions);
  23270. return createVNode(VSheet, mergeProps(sheetProps, {
  23271. "class": ['v-stepper', {
  23272. 'v-stepper--alt-labels': props.altLabels,
  23273. 'v-stepper--flat': props.flat,
  23274. 'v-stepper--non-linear': props.nonLinear,
  23275. 'v-stepper--mobile': props.mobile
  23276. }, props.class],
  23277. "style": props.style
  23278. }), {
  23279. default: () => [hasHeader && createVNode(VStepperHeader, {
  23280. "key": "stepper-header"
  23281. }, {
  23282. default: () => [items.value.map((item, index) => createVNode(Fragment, null, [!!index && createVNode(VDivider, null, null), createVNode(VStepperItem, item, {
  23283. default: slots[`header-item.${item.value}`] ?? slots.header,
  23284. icon: slots.icon,
  23285. title: slots.title,
  23286. subtitle: slots.subtitle
  23287. })]))]
  23288. }), hasWindow && createVNode(VStepperWindow, {
  23289. "key": "stepper-window"
  23290. }, {
  23291. default: () => [items.value.map(item => createVNode(VStepperWindowItem, {
  23292. "value": item.value
  23293. }, {
  23294. default: () => slots[`item.${item.value}`]?.(item) ?? slots.item?.(item)
  23295. }))]
  23296. }), slots.default?.({
  23297. prev,
  23298. next
  23299. }), hasActions && (slots.actions?.({
  23300. next,
  23301. prev
  23302. }) ?? createVNode(VStepperActions, mergeProps({
  23303. "key": "stepper-actions"
  23304. }, stepperActionProps, {
  23305. "onClick:prev": prev,
  23306. "onClick:next": next
  23307. }), null))]
  23308. });
  23309. });
  23310. return {
  23311. prev,
  23312. next
  23313. };
  23314. }
  23315. });
  23316. var components = /*#__PURE__*/Object.freeze({
  23317. __proto__: null,
  23318. VAlert: VAlert,
  23319. VAlertTitle: VAlertTitle,
  23320. VApp: VApp,
  23321. VAppBar: VAppBar,
  23322. VAppBarNavIcon: VAppBarNavIcon,
  23323. VAppBarTitle: VAppBarTitle,
  23324. VAutocomplete: VAutocomplete,
  23325. VAvatar: VAvatar,
  23326. VBadge: VBadge,
  23327. VBanner: VBanner,
  23328. VBannerActions: VBannerActions,
  23329. VBannerText: VBannerText,
  23330. VBottomNavigation: VBottomNavigation,
  23331. VBottomSheet: VBottomSheet,
  23332. VBreadcrumbs: VBreadcrumbs,
  23333. VBreadcrumbsDivider: VBreadcrumbsDivider,
  23334. VBreadcrumbsItem: VBreadcrumbsItem,
  23335. VBtn: VBtn,
  23336. VBtnGroup: VBtnGroup,
  23337. VBtnToggle: VBtnToggle,
  23338. VCard: VCard,
  23339. VCardActions: VCardActions,
  23340. VCardItem: VCardItem,
  23341. VCardSubtitle: VCardSubtitle,
  23342. VCardText: VCardText,
  23343. VCardTitle: VCardTitle,
  23344. VCarousel: VCarousel,
  23345. VCarouselItem: VCarouselItem,
  23346. VCheckbox: VCheckbox,
  23347. VCheckboxBtn: VCheckboxBtn,
  23348. VChip: VChip,
  23349. VChipGroup: VChipGroup,
  23350. VClassIcon: VClassIcon,
  23351. VCode: VCode,
  23352. VCol: VCol,
  23353. VColorPicker: VColorPicker,
  23354. VCombobox: VCombobox,
  23355. VComponentIcon: VComponentIcon,
  23356. VContainer: VContainer,
  23357. VCounter: VCounter,
  23358. VDataIterator: VDataIterator,
  23359. VDataTable: VDataTable,
  23360. VDataTableFooter: VDataTableFooter,
  23361. VDataTableRow: VDataTableRow,
  23362. VDataTableRows: VDataTableRows,
  23363. VDataTableServer: VDataTableServer,
  23364. VDataTableVirtual: VDataTableVirtual,
  23365. VDateCard: VDateCard,
  23366. VDatePicker: VDatePicker,
  23367. VDatePickerControls: VDatePickerControls,
  23368. VDatePickerHeader: VDatePickerHeader,
  23369. VDatePickerMonth: VDatePickerMonth,
  23370. VDatePickerYears: VDatePickerYears,
  23371. VDefaultsProvider: VDefaultsProvider,
  23372. VDialog: VDialog,
  23373. VDialogBottomTransition: VDialogBottomTransition,
  23374. VDialogTopTransition: VDialogTopTransition,
  23375. VDialogTransition: VDialogTransition,
  23376. VDivider: VDivider,
  23377. VExpandTransition: VExpandTransition,
  23378. VExpandXTransition: VExpandXTransition,
  23379. VExpansionPanel: VExpansionPanel,
  23380. VExpansionPanelText: VExpansionPanelText,
  23381. VExpansionPanelTitle: VExpansionPanelTitle,
  23382. VExpansionPanels: VExpansionPanels,
  23383. VFabTransition: VFabTransition,
  23384. VFadeTransition: VFadeTransition,
  23385. VField: VField,
  23386. VFieldLabel: VFieldLabel,
  23387. VFileInput: VFileInput,
  23388. VFooter: VFooter,
  23389. VForm: VForm,
  23390. VHover: VHover,
  23391. VIcon: VIcon,
  23392. VImg: VImg,
  23393. VInfiniteScroll: VInfiniteScroll,
  23394. VInput: VInput,
  23395. VItem: VItem,
  23396. VItemGroup: VItemGroup,
  23397. VKbd: VKbd,
  23398. VLabel: VLabel,
  23399. VLayout: VLayout,
  23400. VLayoutItem: VLayoutItem,
  23401. VLazy: VLazy,
  23402. VLigatureIcon: VLigatureIcon,
  23403. VList: VList,
  23404. VListGroup: VListGroup,
  23405. VListImg: VListImg,
  23406. VListItem: VListItem,
  23407. VListItemAction: VListItemAction,
  23408. VListItemMedia: VListItemMedia,
  23409. VListItemSubtitle: VListItemSubtitle,
  23410. VListItemTitle: VListItemTitle,
  23411. VListSubheader: VListSubheader,
  23412. VLocaleProvider: VLocaleProvider,
  23413. VMain: VMain,
  23414. VMenu: VMenu,
  23415. VMessages: VMessages,
  23416. VNavigationDrawer: VNavigationDrawer,
  23417. VNoSsr: VNoSsr,
  23418. VOtpInput: VOtpInput,
  23419. VOverlay: VOverlay,
  23420. VPagination: VPagination,
  23421. VParallax: VParallax,
  23422. VPicker: VPicker,
  23423. VPickerTitle: VPickerTitle,
  23424. VProgressCircular: VProgressCircular,
  23425. VProgressLinear: VProgressLinear,
  23426. VRadio: VRadio,
  23427. VRadioGroup: VRadioGroup,
  23428. VRangeSlider: VRangeSlider,
  23429. VRating: VRating,
  23430. VResponsive: VResponsive,
  23431. VRow: VRow,
  23432. VScaleTransition: VScaleTransition,
  23433. VScrollXReverseTransition: VScrollXReverseTransition,
  23434. VScrollXTransition: VScrollXTransition,
  23435. VScrollYReverseTransition: VScrollYReverseTransition,
  23436. VScrollYTransition: VScrollYTransition,
  23437. VSelect: VSelect,
  23438. VSelectionControl: VSelectionControl,
  23439. VSelectionControlGroup: VSelectionControlGroup,
  23440. VSheet: VSheet,
  23441. VSkeletonLoader: VSkeletonLoader,
  23442. VSlideGroup: VSlideGroup,
  23443. VSlideGroupItem: VSlideGroupItem,
  23444. VSlideXReverseTransition: VSlideXReverseTransition,
  23445. VSlideXTransition: VSlideXTransition,
  23446. VSlideYReverseTransition: VSlideYReverseTransition,
  23447. VSlideYTransition: VSlideYTransition,
  23448. VSlider: VSlider,
  23449. VSnackbar: VSnackbar,
  23450. VSpacer: VSpacer,
  23451. VStepper: VStepper,
  23452. VStepperActions: VStepperActions,
  23453. VStepperHeader: VStepperHeader,
  23454. VStepperItem: VStepperItem,
  23455. VStepperWindow: VStepperWindow,
  23456. VStepperWindowItem: VStepperWindowItem,
  23457. VSvgIcon: VSvgIcon,
  23458. VSwitch: VSwitch,
  23459. VSystemBar: VSystemBar,
  23460. VTab: VTab,
  23461. VTable: VTable,
  23462. VTabs: VTabs,
  23463. VTextField: VTextField,
  23464. VTextarea: VTextarea,
  23465. VThemeProvider: VThemeProvider,
  23466. VTimeline: VTimeline,
  23467. VTimelineItem: VTimelineItem,
  23468. VToolbar: VToolbar,
  23469. VToolbarItems: VToolbarItems,
  23470. VToolbarTitle: VToolbarTitle,
  23471. VTooltip: VTooltip,
  23472. VValidation: VValidation,
  23473. VVirtualScroll: VVirtualScroll,
  23474. VWindow: VWindow,
  23475. VWindowItem: VWindowItem
  23476. });
  23477. // Types
  23478. function mounted$2(el, binding) {
  23479. const modifiers = binding.modifiers || {};
  23480. const value = binding.value;
  23481. const {
  23482. once,
  23483. immediate,
  23484. ...modifierKeys
  23485. } = modifiers;
  23486. const defaultValue = !Object.keys(modifierKeys).length;
  23487. const {
  23488. handler,
  23489. options
  23490. } = typeof value === 'object' ? value : {
  23491. handler: value,
  23492. options: {
  23493. attributes: modifierKeys?.attr ?? defaultValue,
  23494. characterData: modifierKeys?.char ?? defaultValue,
  23495. childList: modifierKeys?.child ?? defaultValue,
  23496. subtree: modifierKeys?.sub ?? defaultValue
  23497. }
  23498. };
  23499. const observer = new MutationObserver(function () {
  23500. let mutations = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  23501. let observer = arguments.length > 1 ? arguments[1] : undefined;
  23502. handler?.(mutations, observer);
  23503. if (once) unmounted$2(el, binding);
  23504. });
  23505. if (immediate) handler?.([], observer);
  23506. el._mutate = Object(el._mutate);
  23507. el._mutate[binding.instance.$.uid] = {
  23508. observer
  23509. };
  23510. observer.observe(el, options);
  23511. }
  23512. function unmounted$2(el, binding) {
  23513. if (!el._mutate?.[binding.instance.$.uid]) return;
  23514. el._mutate[binding.instance.$.uid].observer.disconnect();
  23515. delete el._mutate[binding.instance.$.uid];
  23516. }
  23517. const Mutate = {
  23518. mounted: mounted$2,
  23519. unmounted: unmounted$2
  23520. };
  23521. // Types
  23522. function mounted$1(el, binding) {
  23523. const handler = binding.value;
  23524. const options = {
  23525. passive: !binding.modifiers?.active
  23526. };
  23527. window.addEventListener('resize', handler, options);
  23528. el._onResize = Object(el._onResize);
  23529. el._onResize[binding.instance.$.uid] = {
  23530. handler,
  23531. options
  23532. };
  23533. if (!binding.modifiers?.quiet) {
  23534. handler();
  23535. }
  23536. }
  23537. function unmounted$1(el, binding) {
  23538. if (!el._onResize?.[binding.instance.$.uid]) return;
  23539. const {
  23540. handler,
  23541. options
  23542. } = el._onResize[binding.instance.$.uid];
  23543. window.removeEventListener('resize', handler, options);
  23544. delete el._onResize[binding.instance.$.uid];
  23545. }
  23546. const Resize = {
  23547. mounted: mounted$1,
  23548. unmounted: unmounted$1
  23549. };
  23550. // Types
  23551. function mounted(el, binding) {
  23552. const {
  23553. self = false
  23554. } = binding.modifiers ?? {};
  23555. const value = binding.value;
  23556. const options = typeof value === 'object' && value.options || {
  23557. passive: true
  23558. };
  23559. const handler = typeof value === 'function' || 'handleEvent' in value ? value : value.handler;
  23560. const target = self ? el : binding.arg ? document.querySelector(binding.arg) : window;
  23561. if (!target) return;
  23562. target.addEventListener('scroll', handler, options);
  23563. el._onScroll = Object(el._onScroll);
  23564. el._onScroll[binding.instance.$.uid] = {
  23565. handler,
  23566. options,
  23567. // Don't reference self
  23568. target: self ? undefined : target
  23569. };
  23570. }
  23571. function unmounted(el, binding) {
  23572. if (!el._onScroll?.[binding.instance.$.uid]) return;
  23573. const {
  23574. handler,
  23575. options,
  23576. target = el
  23577. } = el._onScroll[binding.instance.$.uid];
  23578. target.removeEventListener('scroll', handler, options);
  23579. delete el._onScroll[binding.instance.$.uid];
  23580. }
  23581. function updated(el, binding) {
  23582. if (binding.value === binding.oldValue) return;
  23583. unmounted(el, binding);
  23584. mounted(el, binding);
  23585. }
  23586. const Scroll = {
  23587. mounted,
  23588. unmounted,
  23589. updated
  23590. };
  23591. var directives = /*#__PURE__*/Object.freeze({
  23592. __proto__: null,
  23593. ClickOutside: ClickOutside,
  23594. Intersect: Intersect,
  23595. Mutate: Mutate,
  23596. Resize: Resize,
  23597. Ripple: Ripple,
  23598. Scroll: Scroll,
  23599. Touch: Touch
  23600. });
  23601. // Composables
  23602. function createVuetify$1() {
  23603. let vuetify = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  23604. const {
  23605. blueprint,
  23606. ...rest
  23607. } = vuetify;
  23608. const options = mergeDeep(blueprint, rest);
  23609. const {
  23610. aliases = {},
  23611. components = {},
  23612. directives = {}
  23613. } = options;
  23614. const defaults = createDefaults(options.defaults);
  23615. const display = createDisplay(options.display, options.ssr);
  23616. const theme = createTheme(options.theme);
  23617. const icons = createIcons(options.icons);
  23618. const locale = createLocale(options.locale);
  23619. const date = createDate(options.date);
  23620. const install = app => {
  23621. for (const key in directives) {
  23622. app.directive(key, directives[key]);
  23623. }
  23624. for (const key in components) {
  23625. app.component(key, components[key]);
  23626. }
  23627. for (const key in aliases) {
  23628. app.component(key, defineComponent({
  23629. ...aliases[key],
  23630. name: key,
  23631. aliasName: aliases[key].name
  23632. }));
  23633. }
  23634. theme.install(app);
  23635. app.provide(DefaultsSymbol, defaults);
  23636. app.provide(DisplaySymbol, display);
  23637. app.provide(ThemeSymbol, theme);
  23638. app.provide(IconSymbol, icons);
  23639. app.provide(LocaleSymbol, locale);
  23640. app.provide(DateAdapterSymbol, date);
  23641. if (IN_BROWSER && options.ssr) {
  23642. if (app.$nuxt) {
  23643. app.$nuxt.hook('app:suspense:resolve', () => {
  23644. display.update();
  23645. });
  23646. } else {
  23647. const {
  23648. mount
  23649. } = app;
  23650. app.mount = function () {
  23651. const vm = mount(...arguments);
  23652. nextTick(() => display.update());
  23653. app.mount = mount;
  23654. return vm;
  23655. };
  23656. }
  23657. }
  23658. getUid.reset();
  23659. if (typeof __VUE_OPTIONS_API__ !== 'boolean' || __VUE_OPTIONS_API__) {
  23660. app.mixin({
  23661. computed: {
  23662. $vuetify() {
  23663. return reactive({
  23664. defaults: inject.call(this, DefaultsSymbol),
  23665. display: inject.call(this, DisplaySymbol),
  23666. theme: inject.call(this, ThemeSymbol),
  23667. icons: inject.call(this, IconSymbol),
  23668. locale: inject.call(this, LocaleSymbol),
  23669. date: inject.call(this, DateAdapterSymbol)
  23670. });
  23671. }
  23672. }
  23673. });
  23674. }
  23675. };
  23676. return {
  23677. install,
  23678. defaults,
  23679. display,
  23680. theme,
  23681. icons,
  23682. locale,
  23683. date
  23684. };
  23685. }
  23686. const version$1 = "3.3.11";
  23687. createVuetify$1.version = version$1;
  23688. // Vue's inject() can only be used in setup
  23689. function inject(key) {
  23690. const vm = this.$;
  23691. const provides = vm.parent?.provides ?? vm.vnode.appContext?.provides;
  23692. if (provides && key in provides) {
  23693. return provides[key];
  23694. }
  23695. }
  23696. /* eslint-disable local-rules/sort-imports */
  23697. const version = "3.3.11";
  23698. /* eslint-disable local-rules/sort-imports */
  23699. const createVuetify = function () {
  23700. let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  23701. return createVuetify$1({
  23702. components,
  23703. directives,
  23704. ...options
  23705. });
  23706. };
  23707. export { components, createVuetify, directives, useDefaults, useDisplay, useLayout, useLocale, useRtl, useTheme, version };
  23708. //# sourceMappingURL=vuetify-labs.esm.js.map