vuetify-labs.esm.js 908 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016
  1. /*!
  2. * Vuetify v3.7.6
  3. * Forged by John Leider
  4. * Released under the MIT License.
  5. */
  6. import { shallowRef, Fragment, reactive, computed, watchEffect, toRefs, capitalize, isVNode, Comment, unref, warn, getCurrentInstance as getCurrentInstance$1, ref, provide, inject as inject$1, defineComponent as defineComponent$1, camelize, h, onBeforeUnmount, watch, readonly, onDeactivated, onActivated, onMounted, onScopeDispose, effectScope, toRaw, createVNode, TransitionGroup, Transition, mergeProps, isRef, toRef, onBeforeMount, nextTick, withDirectives, resolveDirective, vShow, onUpdated, Text, resolveDynamicComponent, markRaw, Teleport, cloneVNode, createTextVNode, onUnmounted, onBeforeUpdate, withModifiers, toDisplayString, vModelText, resolveComponent, render } 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. /**
  57. * Like `Partial<T>` but doesn't care what the value is
  58. */
  59. // Copied from Vue
  60. // Utilities
  61. // Types
  62. // Composables
  63. const makeComponentProps = propsFactory({
  64. class: [String, Array, Object],
  65. style: {
  66. type: [String, Array, Object],
  67. default: null
  68. }
  69. }, 'component');
  70. const IN_BROWSER = typeof window !== 'undefined';
  71. const SUPPORTS_INTERSECTION = IN_BROWSER && 'IntersectionObserver' in window;
  72. const SUPPORTS_TOUCH = IN_BROWSER && ('ontouchstart' in window || window.navigator.maxTouchPoints > 0);
  73. const SUPPORTS_EYE_DROPPER = IN_BROWSER && 'EyeDropper' in window;
  74. function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
  75. function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
  76. function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
  77. function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
  78. function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
  79. // Types
  80. function getNestedValue(obj, path, fallback) {
  81. const last = path.length - 1;
  82. if (last < 0) return obj === undefined ? fallback : obj;
  83. for (let i = 0; i < last; i++) {
  84. if (obj == null) {
  85. return fallback;
  86. }
  87. obj = obj[path[i]];
  88. }
  89. if (obj == null) return fallback;
  90. return obj[path[last]] === undefined ? fallback : obj[path[last]];
  91. }
  92. function deepEqual(a, b) {
  93. if (a === b) return true;
  94. if (a instanceof Date && b instanceof Date && a.getTime() !== b.getTime()) {
  95. // If the values are Date, compare them as timestamps
  96. return false;
  97. }
  98. if (a !== Object(a) || b !== Object(b)) {
  99. // If the values aren't objects, they were already checked for equality
  100. return false;
  101. }
  102. const props = Object.keys(a);
  103. if (props.length !== Object.keys(b).length) {
  104. // Different number of props, don't bother to check
  105. return false;
  106. }
  107. return props.every(p => deepEqual(a[p], b[p]));
  108. }
  109. function getObjectValueByPath(obj, path, fallback) {
  110. // credit: http://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key#comment55278413_6491621
  111. if (obj == null || !path || typeof path !== 'string') return fallback;
  112. if (obj[path] !== undefined) return obj[path];
  113. path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
  114. path = path.replace(/^\./, ''); // strip a leading dot
  115. return getNestedValue(obj, path.split('.'), fallback);
  116. }
  117. function getPropertyFromItem(item, property, fallback) {
  118. if (property === true) return item === undefined ? fallback : item;
  119. if (property == null || typeof property === 'boolean') return fallback;
  120. if (item !== Object(item)) {
  121. if (typeof property !== 'function') return fallback;
  122. const value = property(item, fallback);
  123. return typeof value === 'undefined' ? fallback : value;
  124. }
  125. if (typeof property === 'string') return getObjectValueByPath(item, property, fallback);
  126. if (Array.isArray(property)) return getNestedValue(item, property, fallback);
  127. if (typeof property !== 'function') return fallback;
  128. const value = property(item, fallback);
  129. return typeof value === 'undefined' ? fallback : value;
  130. }
  131. function createRange(length) {
  132. let start = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  133. return Array.from({
  134. length
  135. }, (v, k) => start + k);
  136. }
  137. function convertToUnit(str) {
  138. let unit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'px';
  139. if (str == null || str === '') {
  140. return undefined;
  141. } else if (isNaN(+str)) {
  142. return String(str);
  143. } else if (!isFinite(+str)) {
  144. return undefined;
  145. } else {
  146. return `${Number(str)}${unit}`;
  147. }
  148. }
  149. function isObject(obj) {
  150. return obj !== null && typeof obj === 'object' && !Array.isArray(obj);
  151. }
  152. function isPlainObject(obj) {
  153. let proto;
  154. return obj !== null && typeof obj === 'object' && ((proto = Object.getPrototypeOf(obj)) === Object.prototype || proto === null);
  155. }
  156. function refElement(obj) {
  157. if (obj && '$el' in obj) {
  158. const el = obj.$el;
  159. if (el?.nodeType === Node.TEXT_NODE) {
  160. // Multi-root component, use the first element
  161. return el.nextElementSibling;
  162. }
  163. return el;
  164. }
  165. return obj;
  166. }
  167. // KeyboardEvent.keyCode aliases
  168. const keyCodes = Object.freeze({
  169. enter: 13,
  170. tab: 9,
  171. delete: 46,
  172. esc: 27,
  173. space: 32,
  174. up: 38,
  175. down: 40,
  176. left: 37,
  177. right: 39,
  178. end: 35,
  179. home: 36,
  180. del: 46,
  181. backspace: 8,
  182. insert: 45,
  183. pageup: 33,
  184. pagedown: 34,
  185. shift: 16
  186. });
  187. const keyValues = Object.freeze({
  188. enter: 'Enter',
  189. tab: 'Tab',
  190. delete: 'Delete',
  191. esc: 'Escape',
  192. space: 'Space',
  193. up: 'ArrowUp',
  194. down: 'ArrowDown',
  195. left: 'ArrowLeft',
  196. right: 'ArrowRight',
  197. end: 'End',
  198. home: 'Home',
  199. del: 'Delete',
  200. backspace: 'Backspace',
  201. insert: 'Insert',
  202. pageup: 'PageUp',
  203. pagedown: 'PageDown',
  204. shift: 'Shift'
  205. });
  206. function keys(o) {
  207. return Object.keys(o);
  208. }
  209. function has(obj, key) {
  210. return key.every(k => obj.hasOwnProperty(k));
  211. }
  212. // Array of keys
  213. function pick(obj, paths) {
  214. const found = {};
  215. const keys = new Set(Object.keys(obj));
  216. for (const path of paths) {
  217. if (keys.has(path)) {
  218. found[path] = obj[path];
  219. }
  220. }
  221. return found;
  222. }
  223. // Array of keys
  224. // Array of keys or RegExp to test keys against
  225. function pickWithRest(obj, paths, exclude) {
  226. const found = Object.create(null);
  227. const rest = Object.create(null);
  228. for (const key in obj) {
  229. if (paths.some(path => path instanceof RegExp ? path.test(key) : path === key) && !exclude?.some(path => path === key)) {
  230. found[key] = obj[key];
  231. } else {
  232. rest[key] = obj[key];
  233. }
  234. }
  235. return [found, rest];
  236. }
  237. function omit(obj, exclude) {
  238. const clone = {
  239. ...obj
  240. };
  241. exclude.forEach(prop => delete clone[prop]);
  242. return clone;
  243. }
  244. function only(obj, include) {
  245. const clone = {};
  246. include.forEach(prop => clone[prop] = obj[prop]);
  247. return clone;
  248. }
  249. const onRE = /^on[^a-z]/;
  250. const isOn = key => onRE.test(key);
  251. const bubblingEvents = ['onAfterscriptexecute', 'onAnimationcancel', 'onAnimationend', 'onAnimationiteration', 'onAnimationstart', 'onAuxclick', 'onBeforeinput', 'onBeforescriptexecute', 'onChange', 'onClick', 'onCompositionend', 'onCompositionstart', 'onCompositionupdate', 'onContextmenu', 'onCopy', 'onCut', 'onDblclick', 'onFocusin', 'onFocusout', 'onFullscreenchange', 'onFullscreenerror', 'onGesturechange', 'onGestureend', 'onGesturestart', 'onGotpointercapture', 'onInput', 'onKeydown', 'onKeypress', 'onKeyup', 'onLostpointercapture', 'onMousedown', 'onMousemove', 'onMouseout', 'onMouseover', 'onMouseup', 'onMousewheel', 'onPaste', 'onPointercancel', 'onPointerdown', 'onPointerenter', 'onPointerleave', 'onPointermove', 'onPointerout', 'onPointerover', 'onPointerup', 'onReset', 'onSelect', 'onSubmit', 'onTouchcancel', 'onTouchend', 'onTouchmove', 'onTouchstart', 'onTransitioncancel', 'onTransitionend', 'onTransitionrun', 'onTransitionstart', 'onWheel'];
  252. const compositionIgnoreKeys = ['ArrowUp', 'ArrowDown', 'ArrowRight', 'ArrowLeft', 'Enter', 'Escape', 'Tab', ' '];
  253. function isComposingIgnoreKey(e) {
  254. return e.isComposing && compositionIgnoreKeys.includes(e.key);
  255. }
  256. /**
  257. * Filter attributes that should be applied to
  258. * the root element of an input component. Remaining
  259. * attributes should be passed to the <input> element inside.
  260. */
  261. function filterInputAttrs(attrs) {
  262. const [events, props] = pickWithRest(attrs, [onRE]);
  263. const inputEvents = omit(events, bubblingEvents);
  264. const [rootAttrs, inputAttrs] = pickWithRest(props, ['class', 'style', 'id', /^data-/]);
  265. Object.assign(rootAttrs, events);
  266. Object.assign(inputAttrs, inputEvents);
  267. return [rootAttrs, inputAttrs];
  268. }
  269. function wrapInArray(v) {
  270. return v == null ? [] : Array.isArray(v) ? v : [v];
  271. }
  272. function debounce(fn, delay) {
  273. let timeoutId = 0;
  274. const wrap = function () {
  275. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  276. args[_key] = arguments[_key];
  277. }
  278. clearTimeout(timeoutId);
  279. timeoutId = setTimeout(() => fn(...args), unref(delay));
  280. };
  281. wrap.clear = () => {
  282. clearTimeout(timeoutId);
  283. };
  284. wrap.immediate = fn;
  285. return wrap;
  286. }
  287. function clamp(value) {
  288. let min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  289. let max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
  290. return Math.max(min, Math.min(max, value));
  291. }
  292. function getDecimals(value) {
  293. const trimmedStr = value.toString().trim();
  294. return trimmedStr.includes('.') ? trimmedStr.length - trimmedStr.indexOf('.') - 1 : 0;
  295. }
  296. function padEnd(str, length) {
  297. let char = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '0';
  298. return str + char.repeat(Math.max(0, length - str.length));
  299. }
  300. function padStart(str, length) {
  301. let char = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '0';
  302. return char.repeat(Math.max(0, length - str.length)) + str;
  303. }
  304. function chunk(str) {
  305. let size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
  306. const chunked = [];
  307. let index = 0;
  308. while (index < str.length) {
  309. chunked.push(str.substr(index, size));
  310. index += size;
  311. }
  312. return chunked;
  313. }
  314. function chunkArray(array) {
  315. let size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
  316. return Array.from({
  317. length: Math.ceil(array.length / size)
  318. }, (v, i) => array.slice(i * size, i * size + size));
  319. }
  320. function humanReadableFileSize(bytes) {
  321. let base = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;
  322. if (bytes < base) {
  323. return `${bytes} B`;
  324. }
  325. const prefix = base === 1024 ? ['Ki', 'Mi', 'Gi'] : ['k', 'M', 'G'];
  326. let unit = -1;
  327. while (Math.abs(bytes) >= base && unit < prefix.length - 1) {
  328. bytes /= base;
  329. ++unit;
  330. }
  331. return `${bytes.toFixed(1)} ${prefix[unit]}B`;
  332. }
  333. function mergeDeep() {
  334. let source = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  335. let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  336. let arrayFn = arguments.length > 2 ? arguments[2] : undefined;
  337. const out = {};
  338. for (const key in source) {
  339. out[key] = source[key];
  340. }
  341. for (const key in target) {
  342. const sourceProperty = source[key];
  343. const targetProperty = target[key];
  344. // Only continue deep merging if
  345. // both properties are plain objects
  346. if (isPlainObject(sourceProperty) && isPlainObject(targetProperty)) {
  347. out[key] = mergeDeep(sourceProperty, targetProperty, arrayFn);
  348. continue;
  349. }
  350. if (arrayFn && Array.isArray(sourceProperty) && Array.isArray(targetProperty)) {
  351. out[key] = arrayFn(sourceProperty, targetProperty);
  352. continue;
  353. }
  354. out[key] = targetProperty;
  355. }
  356. return out;
  357. }
  358. function flattenFragments(nodes) {
  359. return nodes.map(node => {
  360. if (node.type === Fragment) {
  361. return flattenFragments(node.children);
  362. } else {
  363. return node;
  364. }
  365. }).flat();
  366. }
  367. function toKebabCase() {
  368. let str = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  369. if (toKebabCase.cache.has(str)) return toKebabCase.cache.get(str);
  370. const kebab = str.replace(/[^a-z]/gi, '-').replace(/\B([A-Z])/g, '-$1').toLowerCase();
  371. toKebabCase.cache.set(str, kebab);
  372. return kebab;
  373. }
  374. toKebabCase.cache = new Map();
  375. function findChildrenWithProvide(key, vnode) {
  376. if (!vnode || typeof vnode !== 'object') return [];
  377. if (Array.isArray(vnode)) {
  378. return vnode.map(child => findChildrenWithProvide(key, child)).flat(1);
  379. } else if (vnode.suspense) {
  380. return findChildrenWithProvide(key, vnode.ssContent);
  381. } else if (Array.isArray(vnode.children)) {
  382. return vnode.children.map(child => findChildrenWithProvide(key, child)).flat(1);
  383. } else if (vnode.component) {
  384. if (Object.getOwnPropertySymbols(vnode.component.provides).includes(key)) {
  385. return [vnode.component];
  386. } else if (vnode.component.subTree) {
  387. return findChildrenWithProvide(key, vnode.component.subTree).flat(1);
  388. }
  389. }
  390. return [];
  391. }
  392. var _arr = /*#__PURE__*/new WeakMap();
  393. var _pointer = /*#__PURE__*/new WeakMap();
  394. class CircularBuffer {
  395. constructor(size) {
  396. _classPrivateFieldInitSpec(this, _arr, []);
  397. _classPrivateFieldInitSpec(this, _pointer, 0);
  398. this.size = size;
  399. }
  400. push(val) {
  401. _classPrivateFieldGet(_arr, this)[_classPrivateFieldGet(_pointer, this)] = val;
  402. _classPrivateFieldSet(_pointer, this, (_classPrivateFieldGet(_pointer, this) + 1) % this.size);
  403. }
  404. values() {
  405. return _classPrivateFieldGet(_arr, this).slice(_classPrivateFieldGet(_pointer, this)).concat(_classPrivateFieldGet(_arr, this).slice(0, _classPrivateFieldGet(_pointer, this)));
  406. }
  407. }
  408. function getEventCoordinates(e) {
  409. if ('touches' in e) {
  410. return {
  411. clientX: e.touches[0].clientX,
  412. clientY: e.touches[0].clientY
  413. };
  414. }
  415. return {
  416. clientX: e.clientX,
  417. clientY: e.clientY
  418. };
  419. }
  420. // Only allow a single return type
  421. /**
  422. * Convert a computed ref to a record of refs.
  423. * The getter function must always return an object with the same keys.
  424. */
  425. function destructComputed(getter) {
  426. const refs = reactive({});
  427. const base = computed(getter);
  428. watchEffect(() => {
  429. for (const key in base.value) {
  430. refs[key] = base.value[key];
  431. }
  432. }, {
  433. flush: 'sync'
  434. });
  435. return toRefs(refs);
  436. }
  437. /** Array.includes but value can be any type */
  438. function includes(arr, val) {
  439. return arr.includes(val);
  440. }
  441. function eventName(propName) {
  442. return propName[2].toLowerCase() + propName.slice(3);
  443. }
  444. const EventProp = () => [Function, Array];
  445. function hasEvent(props, name) {
  446. name = 'on' + capitalize(name);
  447. return !!(props[name] || props[`${name}Once`] || props[`${name}Capture`] || props[`${name}OnceCapture`] || props[`${name}CaptureOnce`]);
  448. }
  449. function callEvent(handler) {
  450. for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
  451. args[_key2 - 1] = arguments[_key2];
  452. }
  453. if (Array.isArray(handler)) {
  454. for (const h of handler) {
  455. h(...args);
  456. }
  457. } else if (typeof handler === 'function') {
  458. handler(...args);
  459. }
  460. }
  461. function focusableChildren(el) {
  462. let filterByTabIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  463. const targets = ['button', '[href]', 'input:not([type="hidden"])', 'select', 'textarea', '[tabindex]'].map(s => `${s}${filterByTabIndex ? ':not([tabindex="-1"])' : ''}:not([disabled])`).join(', ');
  464. return [...el.querySelectorAll(targets)];
  465. }
  466. function getNextElement(elements, location, condition) {
  467. let _el;
  468. let idx = elements.indexOf(document.activeElement);
  469. const inc = location === 'next' ? 1 : -1;
  470. do {
  471. idx += inc;
  472. _el = elements[idx];
  473. } while ((!_el || _el.offsetParent == null || !(condition?.(_el) ?? true)) && idx < elements.length && idx >= 0);
  474. return _el;
  475. }
  476. function focusChild(el, location) {
  477. const focusable = focusableChildren(el);
  478. if (!location) {
  479. if (el === document.activeElement || !el.contains(document.activeElement)) {
  480. focusable[0]?.focus();
  481. }
  482. } else if (location === 'first') {
  483. focusable[0]?.focus();
  484. } else if (location === 'last') {
  485. focusable.at(-1)?.focus();
  486. } else if (typeof location === 'number') {
  487. focusable[location]?.focus();
  488. } else {
  489. const _el = getNextElement(focusable, location);
  490. if (_el) _el.focus();else focusChild(el, location === 'next' ? 'first' : 'last');
  491. }
  492. }
  493. function isEmpty(val) {
  494. return val === null || val === undefined || typeof val === 'string' && val.trim() === '';
  495. }
  496. function noop() {}
  497. /** Returns null if the selector is not supported or we can't check */
  498. function matchesSelector(el, selector) {
  499. const supportsSelector = IN_BROWSER && typeof CSS !== 'undefined' && typeof CSS.supports !== 'undefined' && CSS.supports(`selector(${selector})`);
  500. if (!supportsSelector) return null;
  501. try {
  502. return !!el && el.matches(selector);
  503. } catch (err) {
  504. return null;
  505. }
  506. }
  507. function ensureValidVNode(vnodes) {
  508. return vnodes.some(child => {
  509. if (!isVNode(child)) return true;
  510. if (child.type === Comment) return false;
  511. return child.type !== Fragment || ensureValidVNode(child.children);
  512. }) ? vnodes : null;
  513. }
  514. function defer(timeout, cb) {
  515. if (!IN_BROWSER || timeout === 0) {
  516. cb();
  517. return () => {};
  518. }
  519. const timeoutId = window.setTimeout(cb, timeout);
  520. return () => window.clearTimeout(timeoutId);
  521. }
  522. function isClickInsideElement(event, targetDiv) {
  523. const mouseX = event.clientX;
  524. const mouseY = event.clientY;
  525. const divRect = targetDiv.getBoundingClientRect();
  526. const divLeft = divRect.left;
  527. const divTop = divRect.top;
  528. const divRight = divRect.right;
  529. const divBottom = divRect.bottom;
  530. return mouseX >= divLeft && mouseX <= divRight && mouseY >= divTop && mouseY <= divBottom;
  531. }
  532. function templateRef() {
  533. const el = shallowRef();
  534. const fn = target => {
  535. el.value = target;
  536. };
  537. Object.defineProperty(fn, 'value', {
  538. enumerable: true,
  539. get: () => el.value,
  540. set: val => el.value = val
  541. });
  542. Object.defineProperty(fn, 'el', {
  543. enumerable: true,
  544. get: () => refElement(el.value)
  545. });
  546. return fn;
  547. }
  548. function checkPrintable(e) {
  549. const isPrintableChar = e.key.length === 1;
  550. const noModifier = !e.ctrlKey && !e.metaKey && !e.altKey;
  551. return isPrintableChar && noModifier;
  552. }
  553. // Utilities
  554. const block = ['top', 'bottom'];
  555. const inline = ['start', 'end', 'left', 'right'];
  556. /** Parse a raw anchor string into an object */
  557. function parseAnchor(anchor, isRtl) {
  558. let [side, align] = anchor.split(' ');
  559. if (!align) {
  560. align = includes(block, side) ? 'start' : includes(inline, side) ? 'top' : 'center';
  561. }
  562. return {
  563. side: toPhysical(side, isRtl),
  564. align: toPhysical(align, isRtl)
  565. };
  566. }
  567. function toPhysical(str, isRtl) {
  568. if (str === 'start') return isRtl ? 'right' : 'left';
  569. if (str === 'end') return isRtl ? 'left' : 'right';
  570. return str;
  571. }
  572. function flipSide(anchor) {
  573. return {
  574. side: {
  575. center: 'center',
  576. top: 'bottom',
  577. bottom: 'top',
  578. left: 'right',
  579. right: 'left'
  580. }[anchor.side],
  581. align: anchor.align
  582. };
  583. }
  584. function flipAlign(anchor) {
  585. return {
  586. side: anchor.side,
  587. align: {
  588. center: 'center',
  589. top: 'bottom',
  590. bottom: 'top',
  591. left: 'right',
  592. right: 'left'
  593. }[anchor.align]
  594. };
  595. }
  596. function flipCorner(anchor) {
  597. return {
  598. side: anchor.align,
  599. align: anchor.side
  600. };
  601. }
  602. function getAxis(anchor) {
  603. return includes(block, anchor.side) ? 'y' : 'x';
  604. }
  605. class Box {
  606. constructor(_ref) {
  607. let {
  608. x,
  609. y,
  610. width,
  611. height
  612. } = _ref;
  613. this.x = x;
  614. this.y = y;
  615. this.width = width;
  616. this.height = height;
  617. }
  618. get top() {
  619. return this.y;
  620. }
  621. get bottom() {
  622. return this.y + this.height;
  623. }
  624. get left() {
  625. return this.x;
  626. }
  627. get right() {
  628. return this.x + this.width;
  629. }
  630. }
  631. function getOverflow(a, b) {
  632. return {
  633. x: {
  634. before: Math.max(0, b.left - a.left),
  635. after: Math.max(0, a.right - b.right)
  636. },
  637. y: {
  638. before: Math.max(0, b.top - a.top),
  639. after: Math.max(0, a.bottom - b.bottom)
  640. }
  641. };
  642. }
  643. function getTargetBox(target) {
  644. if (Array.isArray(target)) {
  645. return new Box({
  646. x: target[0],
  647. y: target[1],
  648. width: 0,
  649. height: 0
  650. });
  651. } else {
  652. return target.getBoundingClientRect();
  653. }
  654. }
  655. // Utilities
  656. /** @see https://stackoverflow.com/a/57876601/2074736 */
  657. function nullifyTransforms(el) {
  658. const rect = el.getBoundingClientRect();
  659. const style = getComputedStyle(el);
  660. const tx = style.transform;
  661. if (tx) {
  662. let ta, sx, sy, dx, dy;
  663. if (tx.startsWith('matrix3d(')) {
  664. ta = tx.slice(9, -1).split(/, /);
  665. sx = +ta[0];
  666. sy = +ta[5];
  667. dx = +ta[12];
  668. dy = +ta[13];
  669. } else if (tx.startsWith('matrix(')) {
  670. ta = tx.slice(7, -1).split(/, /);
  671. sx = +ta[0];
  672. sy = +ta[3];
  673. dx = +ta[4];
  674. dy = +ta[5];
  675. } else {
  676. return new Box(rect);
  677. }
  678. const to = style.transformOrigin;
  679. const x = rect.x - dx - (1 - sx) * parseFloat(to);
  680. const y = rect.y - dy - (1 - sy) * parseFloat(to.slice(to.indexOf(' ') + 1));
  681. const w = sx ? rect.width / sx : el.offsetWidth + 1;
  682. const h = sy ? rect.height / sy : el.offsetHeight + 1;
  683. return new Box({
  684. x,
  685. y,
  686. width: w,
  687. height: h
  688. });
  689. } else {
  690. return new Box(rect);
  691. }
  692. }
  693. function animate(el, keyframes, options) {
  694. if (typeof el.animate === 'undefined') return {
  695. finished: Promise.resolve()
  696. };
  697. let animation;
  698. try {
  699. animation = el.animate(keyframes, options);
  700. } catch (err) {
  701. return {
  702. finished: Promise.resolve()
  703. };
  704. }
  705. if (typeof animation.finished === 'undefined') {
  706. animation.finished = new Promise(resolve => {
  707. animation.onfinish = () => {
  708. resolve(animation);
  709. };
  710. });
  711. }
  712. return animation;
  713. }
  714. // Utilities
  715. const handlers = new WeakMap();
  716. function bindProps(el, props) {
  717. Object.keys(props).forEach(k => {
  718. if (isOn(k)) {
  719. const name = eventName(k);
  720. const handler = handlers.get(el);
  721. if (props[k] == null) {
  722. handler?.forEach(v => {
  723. const [n, fn] = v;
  724. if (n === name) {
  725. el.removeEventListener(name, fn);
  726. handler.delete(v);
  727. }
  728. });
  729. } else if (!handler || ![...handler]?.some(v => v[0] === name && v[1] === props[k])) {
  730. el.addEventListener(name, props[k]);
  731. const _handler = handler || new Set();
  732. _handler.add([name, props[k]]);
  733. if (!handlers.has(el)) handlers.set(el, _handler);
  734. }
  735. } else {
  736. if (props[k] == null) {
  737. el.removeAttribute(k);
  738. } else {
  739. el.setAttribute(k, props[k]);
  740. }
  741. }
  742. });
  743. }
  744. function unbindProps(el, props) {
  745. Object.keys(props).forEach(k => {
  746. if (isOn(k)) {
  747. const name = eventName(k);
  748. const handler = handlers.get(el);
  749. handler?.forEach(v => {
  750. const [n, fn] = v;
  751. if (n === name) {
  752. el.removeEventListener(name, fn);
  753. handler.delete(v);
  754. }
  755. });
  756. } else {
  757. el.removeAttribute(k);
  758. }
  759. });
  760. }
  761. /**
  762. * WCAG 3.0 APCA perceptual contrast algorithm from https://github.com/Myndex/SAPC-APCA
  763. * @licence https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document
  764. * @see https://www.w3.org/WAI/GL/task-forces/silver/wiki/Visual_Contrast_of_Text_Subgroup
  765. */
  766. // Types
  767. // MAGICAL NUMBERS
  768. // sRGB Conversion to Relative Luminance (Y)
  769. // Transfer Curve (aka "Gamma") for sRGB linearization
  770. // Simple power curve vs piecewise described in docs
  771. // Essentially, 2.4 best models actual display
  772. // characteristics in combination with the total method
  773. const mainTRC = 2.4;
  774. const Rco = 0.2126729; // sRGB Red Coefficient (from matrix)
  775. const Gco = 0.7151522; // sRGB Green Coefficient (from matrix)
  776. const Bco = 0.0721750; // sRGB Blue Coefficient (from matrix)
  777. // For Finding Raw SAPC Contrast from Relative Luminance (Y)
  778. // Constants for SAPC Power Curve Exponents
  779. // One pair for normal text, and one for reverse
  780. // These are the "beating heart" of SAPC
  781. const normBG = 0.55;
  782. const normTXT = 0.58;
  783. const revTXT = 0.57;
  784. const revBG = 0.62;
  785. // For Clamping and Scaling Values
  786. const blkThrs = 0.03; // Level that triggers the soft black clamp
  787. const blkClmp = 1.45; // Exponent for the soft black clamp curve
  788. const deltaYmin = 0.0005; // Lint trap
  789. const scaleBoW = 1.25; // Scaling for dark text on light
  790. const scaleWoB = 1.25; // Scaling for light text on dark
  791. const loConThresh = 0.078; // Threshold for new simple offset scale
  792. const loConFactor = 12.82051282051282; // = 1/0.078,
  793. const loConOffset = 0.06; // The simple offset
  794. const loClip = 0.001; // Output clip (lint trap #2)
  795. function APCAcontrast(text, background) {
  796. // Linearize sRGB
  797. const Rtxt = (text.r / 255) ** mainTRC;
  798. const Gtxt = (text.g / 255) ** mainTRC;
  799. const Btxt = (text.b / 255) ** mainTRC;
  800. const Rbg = (background.r / 255) ** mainTRC;
  801. const Gbg = (background.g / 255) ** mainTRC;
  802. const Bbg = (background.b / 255) ** mainTRC;
  803. // Apply the standard coefficients and sum to Y
  804. let Ytxt = Rtxt * Rco + Gtxt * Gco + Btxt * Bco;
  805. let Ybg = Rbg * Rco + Gbg * Gco + Bbg * Bco;
  806. // Soft clamp Y when near black.
  807. // Now clamping all colors to prevent crossover errors
  808. if (Ytxt <= blkThrs) Ytxt += (blkThrs - Ytxt) ** blkClmp;
  809. if (Ybg <= blkThrs) Ybg += (blkThrs - Ybg) ** blkClmp;
  810. // Return 0 Early for extremely low ∆Y (lint trap #1)
  811. if (Math.abs(Ybg - Ytxt) < deltaYmin) return 0.0;
  812. // SAPC CONTRAST
  813. let outputContrast; // For weighted final values
  814. if (Ybg > Ytxt) {
  815. // For normal polarity, black text on white
  816. // Calculate the SAPC contrast value and scale
  817. const SAPC = (Ybg ** normBG - Ytxt ** normTXT) * scaleBoW;
  818. // NEW! SAPC SmoothScale™
  819. // Low Contrast Smooth Scale Rollout to prevent polarity reversal
  820. // and also a low clip for very low contrasts (lint trap #2)
  821. // much of this is for very low contrasts, less than 10
  822. // therefore for most reversing needs, only loConOffset is important
  823. outputContrast = SAPC < loClip ? 0.0 : SAPC < loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC - loConOffset;
  824. } else {
  825. // For reverse polarity, light text on dark
  826. // WoB should always return negative value.
  827. const SAPC = (Ybg ** revBG - Ytxt ** revTXT) * scaleWoB;
  828. outputContrast = SAPC > -loClip ? 0.0 : SAPC > -loConThresh ? SAPC - SAPC * loConFactor * loConOffset : SAPC + loConOffset;
  829. }
  830. return outputContrast * 100;
  831. }
  832. /* eslint-disable no-console */
  833. function consoleWarn(message) {
  834. warn(`Vuetify: ${message}`);
  835. }
  836. function consoleError(message) {
  837. warn(`Vuetify error: ${message}`);
  838. }
  839. function deprecate(original, replacement) {
  840. replacement = Array.isArray(replacement) ? replacement.slice(0, -1).map(s => `'${s}'`).join(', ') + ` or '${replacement.at(-1)}'` : `'${replacement}'`;
  841. warn(`[Vuetify UPGRADE] '${original}' is deprecated, use ${replacement} instead.`);
  842. }
  843. // Types
  844. const delta = 0.20689655172413793; // 6÷29
  845. const cielabForwardTransform = t => t > delta ** 3 ? Math.cbrt(t) : t / (3 * delta ** 2) + 4 / 29;
  846. const cielabReverseTransform = t => t > delta ? t ** 3 : 3 * delta ** 2 * (t - 4 / 29);
  847. function fromXYZ$1(xyz) {
  848. const transform = cielabForwardTransform;
  849. const transformedY = transform(xyz[1]);
  850. return [116 * transformedY - 16, 500 * (transform(xyz[0] / 0.95047) - transformedY), 200 * (transformedY - transform(xyz[2] / 1.08883))];
  851. }
  852. function toXYZ$1(lab) {
  853. const transform = cielabReverseTransform;
  854. const Ln = (lab[0] + 16) / 116;
  855. return [transform(Ln + lab[1] / 500) * 0.95047, transform(Ln), transform(Ln - lab[2] / 200) * 1.08883];
  856. }
  857. // Utilities
  858. // Types
  859. // For converting XYZ to sRGB
  860. const srgbForwardMatrix = [[3.2406, -1.5372, -0.4986], [-0.9689, 1.8758, 0.0415], [0.0557, -0.2040, 1.0570]];
  861. // Forward gamma adjust
  862. const srgbForwardTransform = C => C <= 0.0031308 ? C * 12.92 : 1.055 * C ** (1 / 2.4) - 0.055;
  863. // For converting sRGB to XYZ
  864. const srgbReverseMatrix = [[0.4124, 0.3576, 0.1805], [0.2126, 0.7152, 0.0722], [0.0193, 0.1192, 0.9505]];
  865. // Reverse gamma adjust
  866. const srgbReverseTransform = C => C <= 0.04045 ? C / 12.92 : ((C + 0.055) / 1.055) ** 2.4;
  867. function fromXYZ(xyz) {
  868. const rgb = Array(3);
  869. const transform = srgbForwardTransform;
  870. const matrix = srgbForwardMatrix;
  871. // Matrix transform, then gamma adjustment
  872. for (let i = 0; i < 3; ++i) {
  873. // Rescale back to [0, 255]
  874. rgb[i] = Math.round(clamp(transform(matrix[i][0] * xyz[0] + matrix[i][1] * xyz[1] + matrix[i][2] * xyz[2])) * 255);
  875. }
  876. return {
  877. r: rgb[0],
  878. g: rgb[1],
  879. b: rgb[2]
  880. };
  881. }
  882. function toXYZ(_ref) {
  883. let {
  884. r,
  885. g,
  886. b
  887. } = _ref;
  888. const xyz = [0, 0, 0];
  889. const transform = srgbReverseTransform;
  890. const matrix = srgbReverseMatrix;
  891. // Rescale from [0, 255] to [0, 1] then adjust sRGB gamma to linear RGB
  892. r = transform(r / 255);
  893. g = transform(g / 255);
  894. b = transform(b / 255);
  895. // Matrix color space transform
  896. for (let i = 0; i < 3; ++i) {
  897. xyz[i] = matrix[i][0] * r + matrix[i][1] * g + matrix[i][2] * b;
  898. }
  899. return xyz;
  900. }
  901. // Utilities
  902. // Types
  903. function isCssColor(color) {
  904. return !!color && /^(#|var\(--|(rgb|hsl)a?\()/.test(color);
  905. }
  906. function isParsableColor(color) {
  907. return isCssColor(color) && !/^((rgb|hsl)a?\()?var\(--/.test(color);
  908. }
  909. const cssColorRe = /^(?<fn>(?:rgb|hsl)a?)\((?<values>.+)\)/;
  910. const mappers = {
  911. rgb: (r, g, b, a) => ({
  912. r,
  913. g,
  914. b,
  915. a
  916. }),
  917. rgba: (r, g, b, a) => ({
  918. r,
  919. g,
  920. b,
  921. a
  922. }),
  923. hsl: (h, s, l, a) => HSLtoRGB({
  924. h,
  925. s,
  926. l,
  927. a
  928. }),
  929. hsla: (h, s, l, a) => HSLtoRGB({
  930. h,
  931. s,
  932. l,
  933. a
  934. }),
  935. hsv: (h, s, v, a) => HSVtoRGB({
  936. h,
  937. s,
  938. v,
  939. a
  940. }),
  941. hsva: (h, s, v, a) => HSVtoRGB({
  942. h,
  943. s,
  944. v,
  945. a
  946. })
  947. };
  948. function parseColor(color) {
  949. if (typeof color === 'number') {
  950. if (isNaN(color) || color < 0 || color > 0xFFFFFF) {
  951. // int can't have opacity
  952. consoleWarn(`'${color}' is not a valid hex color`);
  953. }
  954. return {
  955. r: (color & 0xFF0000) >> 16,
  956. g: (color & 0xFF00) >> 8,
  957. b: color & 0xFF
  958. };
  959. } else if (typeof color === 'string' && cssColorRe.test(color)) {
  960. const {
  961. groups
  962. } = color.match(cssColorRe);
  963. const {
  964. fn,
  965. values
  966. } = groups;
  967. const realValues = values.split(/,\s*/).map(v => {
  968. if (v.endsWith('%') && ['hsl', 'hsla', 'hsv', 'hsva'].includes(fn)) {
  969. return parseFloat(v) / 100;
  970. } else {
  971. return parseFloat(v);
  972. }
  973. });
  974. return mappers[fn](...realValues);
  975. } else if (typeof color === 'string') {
  976. let hex = color.startsWith('#') ? color.slice(1) : color;
  977. if ([3, 4].includes(hex.length)) {
  978. hex = hex.split('').map(char => char + char).join('');
  979. } else if (![6, 8].includes(hex.length)) {
  980. consoleWarn(`'${color}' is not a valid hex(a) color`);
  981. }
  982. const int = parseInt(hex, 16);
  983. if (isNaN(int) || int < 0 || int > 0xFFFFFFFF) {
  984. consoleWarn(`'${color}' is not a valid hex(a) color`);
  985. }
  986. return HexToRGB(hex);
  987. } else if (typeof color === 'object') {
  988. if (has(color, ['r', 'g', 'b'])) {
  989. return color;
  990. } else if (has(color, ['h', 's', 'l'])) {
  991. return HSVtoRGB(HSLtoHSV(color));
  992. } else if (has(color, ['h', 's', 'v'])) {
  993. return HSVtoRGB(color);
  994. }
  995. }
  996. throw new TypeError(`Invalid color: ${color == null ? color : String(color) || color.constructor.name}\nExpected #hex, #hexa, rgb(), rgba(), hsl(), hsla(), object or number`);
  997. }
  998. /** Converts HSVA to RGBA. Based on formula from https://en.wikipedia.org/wiki/HSL_and_HSV */
  999. function HSVtoRGB(hsva) {
  1000. const {
  1001. h,
  1002. s,
  1003. v,
  1004. a
  1005. } = hsva;
  1006. const f = n => {
  1007. const k = (n + h / 60) % 6;
  1008. return v - v * s * Math.max(Math.min(k, 4 - k, 1), 0);
  1009. };
  1010. const rgb = [f(5), f(3), f(1)].map(v => Math.round(v * 255));
  1011. return {
  1012. r: rgb[0],
  1013. g: rgb[1],
  1014. b: rgb[2],
  1015. a
  1016. };
  1017. }
  1018. function HSLtoRGB(hsla) {
  1019. return HSVtoRGB(HSLtoHSV(hsla));
  1020. }
  1021. /** Converts RGBA to HSVA. Based on formula from https://en.wikipedia.org/wiki/HSL_and_HSV */
  1022. function RGBtoHSV(rgba) {
  1023. if (!rgba) return {
  1024. h: 0,
  1025. s: 1,
  1026. v: 1,
  1027. a: 1
  1028. };
  1029. const r = rgba.r / 255;
  1030. const g = rgba.g / 255;
  1031. const b = rgba.b / 255;
  1032. const max = Math.max(r, g, b);
  1033. const min = Math.min(r, g, b);
  1034. let h = 0;
  1035. if (max !== min) {
  1036. if (max === r) {
  1037. h = 60 * (0 + (g - b) / (max - min));
  1038. } else if (max === g) {
  1039. h = 60 * (2 + (b - r) / (max - min));
  1040. } else if (max === b) {
  1041. h = 60 * (4 + (r - g) / (max - min));
  1042. }
  1043. }
  1044. if (h < 0) h = h + 360;
  1045. const s = max === 0 ? 0 : (max - min) / max;
  1046. const hsv = [h, s, max];
  1047. return {
  1048. h: hsv[0],
  1049. s: hsv[1],
  1050. v: hsv[2],
  1051. a: rgba.a
  1052. };
  1053. }
  1054. function HSVtoHSL(hsva) {
  1055. const {
  1056. h,
  1057. s,
  1058. v,
  1059. a
  1060. } = hsva;
  1061. const l = v - v * s / 2;
  1062. const sprime = l === 1 || l === 0 ? 0 : (v - l) / Math.min(l, 1 - l);
  1063. return {
  1064. h,
  1065. s: sprime,
  1066. l,
  1067. a
  1068. };
  1069. }
  1070. function HSLtoHSV(hsl) {
  1071. const {
  1072. h,
  1073. s,
  1074. l,
  1075. a
  1076. } = hsl;
  1077. const v = l + s * Math.min(l, 1 - l);
  1078. const sprime = v === 0 ? 0 : 2 - 2 * l / v;
  1079. return {
  1080. h,
  1081. s: sprime,
  1082. v,
  1083. a
  1084. };
  1085. }
  1086. function RGBtoCSS(_ref) {
  1087. let {
  1088. r,
  1089. g,
  1090. b,
  1091. a
  1092. } = _ref;
  1093. return a === undefined ? `rgb(${r}, ${g}, ${b})` : `rgba(${r}, ${g}, ${b}, ${a})`;
  1094. }
  1095. function HSVtoCSS(hsva) {
  1096. return RGBtoCSS(HSVtoRGB(hsva));
  1097. }
  1098. function toHex(v) {
  1099. const h = Math.round(v).toString(16);
  1100. return ('00'.substr(0, 2 - h.length) + h).toUpperCase();
  1101. }
  1102. function RGBtoHex(_ref2) {
  1103. let {
  1104. r,
  1105. g,
  1106. b,
  1107. a
  1108. } = _ref2;
  1109. return `#${[toHex(r), toHex(g), toHex(b), a !== undefined ? toHex(Math.round(a * 255)) : ''].join('')}`;
  1110. }
  1111. function HexToRGB(hex) {
  1112. hex = parseHex(hex);
  1113. let [r, g, b, a] = chunk(hex, 2).map(c => parseInt(c, 16));
  1114. a = a === undefined ? a : a / 255;
  1115. return {
  1116. r,
  1117. g,
  1118. b,
  1119. a
  1120. };
  1121. }
  1122. function HexToHSV(hex) {
  1123. const rgb = HexToRGB(hex);
  1124. return RGBtoHSV(rgb);
  1125. }
  1126. function HSVtoHex(hsva) {
  1127. return RGBtoHex(HSVtoRGB(hsva));
  1128. }
  1129. function parseHex(hex) {
  1130. if (hex.startsWith('#')) {
  1131. hex = hex.slice(1);
  1132. }
  1133. hex = hex.replace(/([^0-9a-f])/gi, 'F');
  1134. if (hex.length === 3 || hex.length === 4) {
  1135. hex = hex.split('').map(x => x + x).join('');
  1136. }
  1137. if (hex.length !== 6) {
  1138. hex = padEnd(padEnd(hex, 6), 8, 'F');
  1139. }
  1140. return hex;
  1141. }
  1142. function lighten(value, amount) {
  1143. const lab = fromXYZ$1(toXYZ(value));
  1144. lab[0] = lab[0] + amount * 10;
  1145. return fromXYZ(toXYZ$1(lab));
  1146. }
  1147. function darken(value, amount) {
  1148. const lab = fromXYZ$1(toXYZ(value));
  1149. lab[0] = lab[0] - amount * 10;
  1150. return fromXYZ(toXYZ$1(lab));
  1151. }
  1152. /**
  1153. * Calculate the relative luminance of a given color
  1154. * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef
  1155. */
  1156. function getLuma(color) {
  1157. const rgb = parseColor(color);
  1158. return toXYZ(rgb)[1];
  1159. }
  1160. /**
  1161. * Returns the contrast ratio (1-21) between two colors.
  1162. * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef
  1163. */
  1164. function getContrast(first, second) {
  1165. const l1 = getLuma(first);
  1166. const l2 = getLuma(second);
  1167. const light = Math.max(l1, l2);
  1168. const dark = Math.min(l1, l2);
  1169. return (light + 0.05) / (dark + 0.05);
  1170. }
  1171. function getForeground(color) {
  1172. const blackContrast = Math.abs(APCAcontrast(parseColor(0), parseColor(color)));
  1173. const whiteContrast = Math.abs(APCAcontrast(parseColor(0xffffff), parseColor(color)));
  1174. // TODO: warn about poor color selections
  1175. // const contrastAsText = Math.abs(APCAcontrast(colorVal, colorToInt(theme.colors.background)))
  1176. // const minContrast = Math.max(blackContrast, whiteContrast)
  1177. // if (minContrast < 60) {
  1178. // consoleInfo(`${key} theme color ${color} has poor contrast (${minContrast.toFixed()}%)`)
  1179. // } else if (contrastAsText < 60 && !['background', 'surface'].includes(color)) {
  1180. // consoleInfo(`${key} theme color ${color} has poor contrast as text (${contrastAsText.toFixed()}%)`)
  1181. // }
  1182. // Prefer white text if both have an acceptable contrast ratio
  1183. return whiteContrast > Math.min(blackContrast, 50) ? '#fff' : '#000';
  1184. }
  1185. // Utilities
  1186. // Types
  1187. function getCurrentInstance(name, message) {
  1188. const vm = getCurrentInstance$1();
  1189. if (!vm) {
  1190. throw new Error(`[Vuetify] ${name} ${message || 'must be called from inside a setup function'}`);
  1191. }
  1192. return vm;
  1193. }
  1194. function getCurrentInstanceName() {
  1195. let name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'composables';
  1196. const vm = getCurrentInstance(name).type;
  1197. return toKebabCase(vm?.aliasName || vm?.name);
  1198. }
  1199. let _uid = 0;
  1200. let _map = new WeakMap();
  1201. function getUid() {
  1202. const vm = getCurrentInstance('getUid');
  1203. if (_map.has(vm)) return _map.get(vm);else {
  1204. const uid = _uid++;
  1205. _map.set(vm, uid);
  1206. return uid;
  1207. }
  1208. }
  1209. getUid.reset = () => {
  1210. _uid = 0;
  1211. _map = new WeakMap();
  1212. };
  1213. // Utilities
  1214. // Types
  1215. function injectSelf(key) {
  1216. let vm = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstance('injectSelf');
  1217. const {
  1218. provides
  1219. } = vm;
  1220. if (provides && key in provides) {
  1221. // TS doesn't allow symbol as index type
  1222. return provides[key];
  1223. }
  1224. return undefined;
  1225. }
  1226. // Utilities
  1227. // Types
  1228. const DefaultsSymbol = Symbol.for('vuetify:defaults');
  1229. function createDefaults(options) {
  1230. return ref(options);
  1231. }
  1232. function injectDefaults() {
  1233. const defaults = inject$1(DefaultsSymbol);
  1234. if (!defaults) throw new Error('[Vuetify] Could not find defaults instance');
  1235. return defaults;
  1236. }
  1237. function provideDefaults(defaults, options) {
  1238. const injectedDefaults = injectDefaults();
  1239. const providedDefaults = ref(defaults);
  1240. const newDefaults = computed(() => {
  1241. const disabled = unref(options?.disabled);
  1242. if (disabled) return injectedDefaults.value;
  1243. const scoped = unref(options?.scoped);
  1244. const reset = unref(options?.reset);
  1245. const root = unref(options?.root);
  1246. if (providedDefaults.value == null && !(scoped || reset || root)) return injectedDefaults.value;
  1247. let properties = mergeDeep(providedDefaults.value, {
  1248. prev: injectedDefaults.value
  1249. });
  1250. if (scoped) return properties;
  1251. if (reset || root) {
  1252. const len = Number(reset || Infinity);
  1253. for (let i = 0; i <= len; i++) {
  1254. if (!properties || !('prev' in properties)) {
  1255. break;
  1256. }
  1257. properties = properties.prev;
  1258. }
  1259. if (properties && typeof root === 'string' && root in properties) {
  1260. properties = mergeDeep(mergeDeep(properties, {
  1261. prev: properties
  1262. }), properties[root]);
  1263. }
  1264. return properties;
  1265. }
  1266. return properties.prev ? mergeDeep(properties.prev, properties) : properties;
  1267. });
  1268. provide(DefaultsSymbol, newDefaults);
  1269. return newDefaults;
  1270. }
  1271. function propIsDefined(vnode, prop) {
  1272. return typeof vnode.props?.[prop] !== 'undefined' || typeof vnode.props?.[toKebabCase(prop)] !== 'undefined';
  1273. }
  1274. function internalUseDefaults() {
  1275. let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  1276. let name = arguments.length > 1 ? arguments[1] : undefined;
  1277. let defaults = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : injectDefaults();
  1278. const vm = getCurrentInstance('useDefaults');
  1279. name = name ?? vm.type.name ?? vm.type.__name;
  1280. if (!name) {
  1281. throw new Error('[Vuetify] Could not determine component name');
  1282. }
  1283. const componentDefaults = computed(() => defaults.value?.[props._as ?? name]);
  1284. const _props = new Proxy(props, {
  1285. get(target, prop) {
  1286. const propValue = Reflect.get(target, prop);
  1287. if (prop === 'class' || prop === 'style') {
  1288. return [componentDefaults.value?.[prop], propValue].filter(v => v != null);
  1289. } else if (typeof prop === 'string' && !propIsDefined(vm.vnode, prop)) {
  1290. return componentDefaults.value?.[prop] !== undefined ? componentDefaults.value?.[prop] : defaults.value?.global?.[prop] !== undefined ? defaults.value?.global?.[prop] : propValue;
  1291. }
  1292. return propValue;
  1293. }
  1294. });
  1295. const _subcomponentDefaults = shallowRef();
  1296. watchEffect(() => {
  1297. if (componentDefaults.value) {
  1298. const subComponents = Object.entries(componentDefaults.value).filter(_ref => {
  1299. let [key] = _ref;
  1300. return key.startsWith(key[0].toUpperCase());
  1301. });
  1302. _subcomponentDefaults.value = subComponents.length ? Object.fromEntries(subComponents) : undefined;
  1303. } else {
  1304. _subcomponentDefaults.value = undefined;
  1305. }
  1306. });
  1307. function provideSubDefaults() {
  1308. const injected = injectSelf(DefaultsSymbol, vm);
  1309. provide(DefaultsSymbol, computed(() => {
  1310. return _subcomponentDefaults.value ? mergeDeep(injected?.value ?? {}, _subcomponentDefaults.value) : injected?.value;
  1311. }));
  1312. }
  1313. return {
  1314. props: _props,
  1315. provideSubDefaults
  1316. };
  1317. }
  1318. function useDefaults() {
  1319. let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  1320. let name = arguments.length > 1 ? arguments[1] : undefined;
  1321. const {
  1322. props: _props,
  1323. provideSubDefaults
  1324. } = internalUseDefaults(props, name);
  1325. provideSubDefaults();
  1326. return _props;
  1327. }
  1328. // Composables
  1329. // Types
  1330. // No props
  1331. // Object Props
  1332. // Implementation
  1333. function defineComponent(options) {
  1334. options._setup = options._setup ?? options.setup;
  1335. if (!options.name) {
  1336. consoleWarn('The component is missing an explicit name, unable to generate default prop value');
  1337. return options;
  1338. }
  1339. if (options._setup) {
  1340. options.props = propsFactory(options.props ?? {}, options.name)();
  1341. const propKeys = Object.keys(options.props).filter(key => key !== 'class' && key !== 'style');
  1342. options.filterProps = function filterProps(props) {
  1343. return pick(props, propKeys);
  1344. };
  1345. options.props._as = String;
  1346. options.setup = function setup(props, ctx) {
  1347. const defaults = injectDefaults();
  1348. // Skip props proxy if defaults are not provided
  1349. if (!defaults.value) return options._setup(props, ctx);
  1350. const {
  1351. props: _props,
  1352. provideSubDefaults
  1353. } = internalUseDefaults(props, props._as ?? options.name, defaults);
  1354. const setupBindings = options._setup(_props, ctx);
  1355. provideSubDefaults();
  1356. return setupBindings;
  1357. };
  1358. }
  1359. return options;
  1360. }
  1361. // No argument - simple default slot
  1362. // Generic constructor argument - generic props and slots
  1363. // Slots argument - simple slots
  1364. // Implementation
  1365. function genericComponent() {
  1366. let exposeDefaults = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
  1367. return options => (exposeDefaults ? defineComponent : defineComponent$1)(options);
  1368. }
  1369. function defineFunctionalComponent(props, render) {
  1370. render.props = props;
  1371. return render;
  1372. }
  1373. // Adds a filterProps method to the component options
  1374. // https://github.com/vuejs/core/pull/10557
  1375. // not a vue Component
  1376. // Composables
  1377. function createSimpleFunctional(klass) {
  1378. let tag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'div';
  1379. let name = arguments.length > 2 ? arguments[2] : undefined;
  1380. return genericComponent()({
  1381. name: name ?? capitalize(camelize(klass.replace(/__/g, '-'))),
  1382. props: {
  1383. tag: {
  1384. type: String,
  1385. default: tag
  1386. },
  1387. ...makeComponentProps()
  1388. },
  1389. setup(props, _ref) {
  1390. let {
  1391. slots
  1392. } = _ref;
  1393. return () => {
  1394. return h(props.tag, {
  1395. class: [klass, props.class],
  1396. style: props.style
  1397. }, slots.default?.());
  1398. };
  1399. }
  1400. });
  1401. }
  1402. /**
  1403. * Returns:
  1404. * - 'null' if the node is not attached to the DOM
  1405. * - the root node (HTMLDocument | ShadowRoot) otherwise
  1406. */
  1407. function attachedRoot(node) {
  1408. /* istanbul ignore next */
  1409. if (typeof node.getRootNode !== 'function') {
  1410. // Shadow DOM not supported (IE11), lets find the root of this node
  1411. while (node.parentNode) node = node.parentNode;
  1412. // The root parent is the document if the node is attached to the DOM
  1413. if (node !== document) return null;
  1414. return document;
  1415. }
  1416. const root = node.getRootNode();
  1417. // The composed root node is the document if the node is attached to the DOM
  1418. if (root !== document && root.getRootNode({
  1419. composed: true
  1420. }) !== document) return null;
  1421. return root;
  1422. }
  1423. const standardEasing = 'cubic-bezier(0.4, 0, 0.2, 1)';
  1424. const deceleratedEasing = 'cubic-bezier(0.0, 0, 0.2, 1)'; // Entering
  1425. const acceleratedEasing = 'cubic-bezier(0.4, 0, 1, 1)'; // Leaving
  1426. // Utilities
  1427. function getPrefixedEventHandlers(attrs, suffix, getData) {
  1428. return Object.keys(attrs).filter(key => isOn(key) && key.endsWith(suffix)).reduce((acc, key) => {
  1429. acc[key.slice(0, -suffix.length)] = event => attrs[key](event, getData(event));
  1430. return acc;
  1431. }, {});
  1432. }
  1433. function getScrollParent(el) {
  1434. let includeHidden = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  1435. while (el) {
  1436. if (includeHidden ? isPotentiallyScrollable(el) : hasScrollbar(el)) return el;
  1437. el = el.parentElement;
  1438. }
  1439. return document.scrollingElement;
  1440. }
  1441. function getScrollParents(el, stopAt) {
  1442. const elements = [];
  1443. if (stopAt && el && !stopAt.contains(el)) return elements;
  1444. while (el) {
  1445. if (hasScrollbar(el)) elements.push(el);
  1446. if (el === stopAt) break;
  1447. el = el.parentElement;
  1448. }
  1449. return elements;
  1450. }
  1451. function hasScrollbar(el) {
  1452. if (!el || el.nodeType !== Node.ELEMENT_NODE) return false;
  1453. const style = window.getComputedStyle(el);
  1454. return style.overflowY === 'scroll' || style.overflowY === 'auto' && el.scrollHeight > el.clientHeight;
  1455. }
  1456. function isPotentiallyScrollable(el) {
  1457. if (!el || el.nodeType !== Node.ELEMENT_NODE) return false;
  1458. const style = window.getComputedStyle(el);
  1459. return ['scroll', 'auto'].includes(style.overflowY);
  1460. }
  1461. function isFixedPosition(el) {
  1462. while (el) {
  1463. if (window.getComputedStyle(el).position === 'fixed') {
  1464. return true;
  1465. }
  1466. el = el.offsetParent;
  1467. }
  1468. return false;
  1469. }
  1470. // Utilities
  1471. // Types
  1472. function useRender(render) {
  1473. const vm = getCurrentInstance('useRender');
  1474. vm.render = render;
  1475. }
  1476. // Utilities
  1477. // Types
  1478. function useResizeObserver(callback) {
  1479. let box = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'content';
  1480. const resizeRef = templateRef();
  1481. const contentRect = ref();
  1482. if (IN_BROWSER) {
  1483. const observer = new ResizeObserver(entries => {
  1484. callback?.(entries, observer);
  1485. if (!entries.length) return;
  1486. if (box === 'content') {
  1487. contentRect.value = entries[0].contentRect;
  1488. } else {
  1489. contentRect.value = entries[0].target.getBoundingClientRect();
  1490. }
  1491. });
  1492. onBeforeUnmount(() => {
  1493. observer.disconnect();
  1494. });
  1495. watch(() => resizeRef.el, (newValue, oldValue) => {
  1496. if (oldValue) {
  1497. observer.unobserve(oldValue);
  1498. contentRect.value = undefined;
  1499. }
  1500. if (newValue) observer.observe(newValue);
  1501. }, {
  1502. flush: 'post'
  1503. });
  1504. }
  1505. return {
  1506. resizeRef,
  1507. contentRect: readonly(contentRect)
  1508. };
  1509. }
  1510. // Composables
  1511. // Types
  1512. const VuetifyLayoutKey = Symbol.for('vuetify:layout');
  1513. const VuetifyLayoutItemKey = Symbol.for('vuetify:layout-item');
  1514. const ROOT_ZINDEX = 1000;
  1515. const makeLayoutProps = propsFactory({
  1516. overlaps: {
  1517. type: Array,
  1518. default: () => []
  1519. },
  1520. fullHeight: Boolean
  1521. }, 'layout');
  1522. // Composables
  1523. const makeLayoutItemProps = propsFactory({
  1524. name: {
  1525. type: String
  1526. },
  1527. order: {
  1528. type: [Number, String],
  1529. default: 0
  1530. },
  1531. absolute: Boolean
  1532. }, 'layout-item');
  1533. function useLayout() {
  1534. const layout = inject$1(VuetifyLayoutKey);
  1535. if (!layout) throw new Error('[Vuetify] Could not find injected layout');
  1536. return {
  1537. getLayoutItem: layout.getLayoutItem,
  1538. mainRect: layout.mainRect,
  1539. mainStyles: layout.mainStyles
  1540. };
  1541. }
  1542. function useLayoutItem(options) {
  1543. const layout = inject$1(VuetifyLayoutKey);
  1544. if (!layout) throw new Error('[Vuetify] Could not find injected layout');
  1545. const id = options.id ?? `layout-item-${getUid()}`;
  1546. const vm = getCurrentInstance('useLayoutItem');
  1547. provide(VuetifyLayoutItemKey, {
  1548. id
  1549. });
  1550. const isKeptAlive = shallowRef(false);
  1551. onDeactivated(() => isKeptAlive.value = true);
  1552. onActivated(() => isKeptAlive.value = false);
  1553. const {
  1554. layoutItemStyles,
  1555. layoutItemScrimStyles
  1556. } = layout.register(vm, {
  1557. ...options,
  1558. active: computed(() => isKeptAlive.value ? false : options.active.value),
  1559. id
  1560. });
  1561. onBeforeUnmount(() => layout.unregister(id));
  1562. return {
  1563. layoutItemStyles,
  1564. layoutRect: layout.layoutRect,
  1565. layoutItemScrimStyles
  1566. };
  1567. }
  1568. const generateLayers = (layout, positions, layoutSizes, activeItems) => {
  1569. let previousLayer = {
  1570. top: 0,
  1571. left: 0,
  1572. right: 0,
  1573. bottom: 0
  1574. };
  1575. const layers = [{
  1576. id: '',
  1577. layer: {
  1578. ...previousLayer
  1579. }
  1580. }];
  1581. for (const id of layout) {
  1582. const position = positions.get(id);
  1583. const amount = layoutSizes.get(id);
  1584. const active = activeItems.get(id);
  1585. if (!position || !amount || !active) continue;
  1586. const layer = {
  1587. ...previousLayer,
  1588. [position.value]: parseInt(previousLayer[position.value], 10) + (active.value ? parseInt(amount.value, 10) : 0)
  1589. };
  1590. layers.push({
  1591. id,
  1592. layer
  1593. });
  1594. previousLayer = layer;
  1595. }
  1596. return layers;
  1597. };
  1598. function createLayout(props) {
  1599. const parentLayout = inject$1(VuetifyLayoutKey, null);
  1600. const rootZIndex = computed(() => parentLayout ? parentLayout.rootZIndex.value - 100 : ROOT_ZINDEX);
  1601. const registered = ref([]);
  1602. const positions = reactive(new Map());
  1603. const layoutSizes = reactive(new Map());
  1604. const priorities = reactive(new Map());
  1605. const activeItems = reactive(new Map());
  1606. const disabledTransitions = reactive(new Map());
  1607. const {
  1608. resizeRef,
  1609. contentRect: layoutRect
  1610. } = useResizeObserver();
  1611. const computedOverlaps = computed(() => {
  1612. const map = new Map();
  1613. const overlaps = props.overlaps ?? [];
  1614. for (const overlap of overlaps.filter(item => item.includes(':'))) {
  1615. const [top, bottom] = overlap.split(':');
  1616. if (!registered.value.includes(top) || !registered.value.includes(bottom)) continue;
  1617. const topPosition = positions.get(top);
  1618. const bottomPosition = positions.get(bottom);
  1619. const topAmount = layoutSizes.get(top);
  1620. const bottomAmount = layoutSizes.get(bottom);
  1621. if (!topPosition || !bottomPosition || !topAmount || !bottomAmount) continue;
  1622. map.set(bottom, {
  1623. position: topPosition.value,
  1624. amount: parseInt(topAmount.value, 10)
  1625. });
  1626. map.set(top, {
  1627. position: bottomPosition.value,
  1628. amount: -parseInt(bottomAmount.value, 10)
  1629. });
  1630. }
  1631. return map;
  1632. });
  1633. const layers = computed(() => {
  1634. const uniquePriorities = [...new Set([...priorities.values()].map(p => p.value))].sort((a, b) => a - b);
  1635. const layout = [];
  1636. for (const p of uniquePriorities) {
  1637. const items = registered.value.filter(id => priorities.get(id)?.value === p);
  1638. layout.push(...items);
  1639. }
  1640. return generateLayers(layout, positions, layoutSizes, activeItems);
  1641. });
  1642. const transitionsEnabled = computed(() => {
  1643. return !Array.from(disabledTransitions.values()).some(ref => ref.value);
  1644. });
  1645. const mainRect = computed(() => {
  1646. return layers.value[layers.value.length - 1].layer;
  1647. });
  1648. const mainStyles = computed(() => {
  1649. return {
  1650. '--v-layout-left': convertToUnit(mainRect.value.left),
  1651. '--v-layout-right': convertToUnit(mainRect.value.right),
  1652. '--v-layout-top': convertToUnit(mainRect.value.top),
  1653. '--v-layout-bottom': convertToUnit(mainRect.value.bottom),
  1654. ...(transitionsEnabled.value ? undefined : {
  1655. transition: 'none'
  1656. })
  1657. };
  1658. });
  1659. const items = computed(() => {
  1660. return layers.value.slice(1).map((_ref, index) => {
  1661. let {
  1662. id
  1663. } = _ref;
  1664. const {
  1665. layer
  1666. } = layers.value[index];
  1667. const size = layoutSizes.get(id);
  1668. const position = positions.get(id);
  1669. return {
  1670. id,
  1671. ...layer,
  1672. size: Number(size.value),
  1673. position: position.value
  1674. };
  1675. });
  1676. });
  1677. const getLayoutItem = id => {
  1678. return items.value.find(item => item.id === id);
  1679. };
  1680. const rootVm = getCurrentInstance('createLayout');
  1681. const isMounted = shallowRef(false);
  1682. onMounted(() => {
  1683. isMounted.value = true;
  1684. });
  1685. provide(VuetifyLayoutKey, {
  1686. register: (vm, _ref2) => {
  1687. let {
  1688. id,
  1689. order,
  1690. position,
  1691. layoutSize,
  1692. elementSize,
  1693. active,
  1694. disableTransitions,
  1695. absolute
  1696. } = _ref2;
  1697. priorities.set(id, order);
  1698. positions.set(id, position);
  1699. layoutSizes.set(id, layoutSize);
  1700. activeItems.set(id, active);
  1701. disableTransitions && disabledTransitions.set(id, disableTransitions);
  1702. const instances = findChildrenWithProvide(VuetifyLayoutItemKey, rootVm?.vnode);
  1703. const instanceIndex = instances.indexOf(vm);
  1704. if (instanceIndex > -1) registered.value.splice(instanceIndex, 0, id);else registered.value.push(id);
  1705. const index = computed(() => items.value.findIndex(i => i.id === id));
  1706. const zIndex = computed(() => rootZIndex.value + layers.value.length * 2 - index.value * 2);
  1707. const layoutItemStyles = computed(() => {
  1708. const isHorizontal = position.value === 'left' || position.value === 'right';
  1709. const isOppositeHorizontal = position.value === 'right';
  1710. const isOppositeVertical = position.value === 'bottom';
  1711. const size = elementSize.value ?? layoutSize.value;
  1712. const unit = size === 0 ? '%' : 'px';
  1713. const styles = {
  1714. [position.value]: 0,
  1715. zIndex: zIndex.value,
  1716. transform: `translate${isHorizontal ? 'X' : 'Y'}(${(active.value ? 0 : -(size === 0 ? 100 : size)) * (isOppositeHorizontal || isOppositeVertical ? -1 : 1)}${unit})`,
  1717. position: absolute.value || rootZIndex.value !== ROOT_ZINDEX ? 'absolute' : 'fixed',
  1718. ...(transitionsEnabled.value ? undefined : {
  1719. transition: 'none'
  1720. })
  1721. };
  1722. if (!isMounted.value) return styles;
  1723. const item = items.value[index.value];
  1724. if (!item) throw new Error(`[Vuetify] Could not find layout item "${id}"`);
  1725. const overlap = computedOverlaps.value.get(id);
  1726. if (overlap) {
  1727. item[overlap.position] += overlap.amount;
  1728. }
  1729. return {
  1730. ...styles,
  1731. height: isHorizontal ? `calc(100% - ${item.top}px - ${item.bottom}px)` : elementSize.value ? `${elementSize.value}px` : undefined,
  1732. left: isOppositeHorizontal ? undefined : `${item.left}px`,
  1733. right: isOppositeHorizontal ? `${item.right}px` : undefined,
  1734. top: position.value !== 'bottom' ? `${item.top}px` : undefined,
  1735. bottom: position.value !== 'top' ? `${item.bottom}px` : undefined,
  1736. width: !isHorizontal ? `calc(100% - ${item.left}px - ${item.right}px)` : elementSize.value ? `${elementSize.value}px` : undefined
  1737. };
  1738. });
  1739. const layoutItemScrimStyles = computed(() => ({
  1740. zIndex: zIndex.value - 1
  1741. }));
  1742. return {
  1743. layoutItemStyles,
  1744. layoutItemScrimStyles,
  1745. zIndex
  1746. };
  1747. },
  1748. unregister: id => {
  1749. priorities.delete(id);
  1750. positions.delete(id);
  1751. layoutSizes.delete(id);
  1752. activeItems.delete(id);
  1753. disabledTransitions.delete(id);
  1754. registered.value = registered.value.filter(v => v !== id);
  1755. },
  1756. mainRect,
  1757. mainStyles,
  1758. getLayoutItem,
  1759. items,
  1760. layoutRect,
  1761. rootZIndex
  1762. });
  1763. const layoutClasses = computed(() => ['v-layout', {
  1764. 'v-layout--full-height': props.fullHeight
  1765. }]);
  1766. const layoutStyles = computed(() => ({
  1767. zIndex: parentLayout ? rootZIndex.value : undefined,
  1768. position: parentLayout ? 'relative' : undefined,
  1769. overflow: parentLayout ? 'hidden' : undefined
  1770. }));
  1771. return {
  1772. layoutClasses,
  1773. layoutStyles,
  1774. getLayoutItem,
  1775. items,
  1776. layoutRect,
  1777. layoutRef: resizeRef
  1778. };
  1779. }
  1780. // Utilities
  1781. // Types
  1782. function useToggleScope(source, fn) {
  1783. let scope;
  1784. function start() {
  1785. scope = effectScope();
  1786. scope.run(() => fn.length ? fn(() => {
  1787. scope?.stop();
  1788. start();
  1789. }) : fn());
  1790. }
  1791. watch(source, active => {
  1792. if (active && !scope) {
  1793. start();
  1794. } else if (!active) {
  1795. scope?.stop();
  1796. scope = undefined;
  1797. }
  1798. }, {
  1799. immediate: true
  1800. });
  1801. onScopeDispose(() => {
  1802. scope?.stop();
  1803. });
  1804. }
  1805. // Composables
  1806. // Types
  1807. // Composables
  1808. function useProxiedModel(props, prop, defaultValue) {
  1809. let transformIn = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : v => v;
  1810. let transformOut = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : v => v;
  1811. const vm = getCurrentInstance('useProxiedModel');
  1812. const internal = ref(props[prop] !== undefined ? props[prop] : defaultValue);
  1813. const kebabProp = toKebabCase(prop);
  1814. const checkKebab = kebabProp !== prop;
  1815. const isControlled = checkKebab ? computed(() => {
  1816. void props[prop];
  1817. return !!((vm.vnode.props?.hasOwnProperty(prop) || vm.vnode.props?.hasOwnProperty(kebabProp)) && (vm.vnode.props?.hasOwnProperty(`onUpdate:${prop}`) || vm.vnode.props?.hasOwnProperty(`onUpdate:${kebabProp}`)));
  1818. }) : computed(() => {
  1819. void props[prop];
  1820. return !!(vm.vnode.props?.hasOwnProperty(prop) && vm.vnode.props?.hasOwnProperty(`onUpdate:${prop}`));
  1821. });
  1822. useToggleScope(() => !isControlled.value, () => {
  1823. watch(() => props[prop], val => {
  1824. internal.value = val;
  1825. });
  1826. });
  1827. const model = computed({
  1828. get() {
  1829. const externalValue = props[prop];
  1830. return transformIn(isControlled.value ? externalValue : internal.value);
  1831. },
  1832. set(internalValue) {
  1833. const newValue = transformOut(internalValue);
  1834. const value = toRaw(isControlled.value ? props[prop] : internal.value);
  1835. if (value === newValue || transformIn(value) === internalValue) {
  1836. return;
  1837. }
  1838. internal.value = newValue;
  1839. vm?.emit(`update:${prop}`, newValue);
  1840. }
  1841. });
  1842. Object.defineProperty(model, 'externalValue', {
  1843. get: () => isControlled.value ? props[prop] : internal.value
  1844. });
  1845. return model;
  1846. }
  1847. var en = {
  1848. badge: 'Badge',
  1849. open: 'Open',
  1850. close: 'Close',
  1851. dismiss: 'Dismiss',
  1852. confirmEdit: {
  1853. ok: 'OK',
  1854. cancel: 'Cancel'
  1855. },
  1856. dataIterator: {
  1857. noResultsText: 'No matching records found',
  1858. loadingText: 'Loading items...'
  1859. },
  1860. dataTable: {
  1861. itemsPerPageText: 'Rows per page:',
  1862. ariaLabel: {
  1863. sortDescending: 'Sorted descending.',
  1864. sortAscending: 'Sorted ascending.',
  1865. sortNone: 'Not sorted.',
  1866. activateNone: 'Activate to remove sorting.',
  1867. activateDescending: 'Activate to sort descending.',
  1868. activateAscending: 'Activate to sort ascending.'
  1869. },
  1870. sortBy: 'Sort by'
  1871. },
  1872. dataFooter: {
  1873. itemsPerPageText: 'Items per page:',
  1874. itemsPerPageAll: 'All',
  1875. nextPage: 'Next page',
  1876. prevPage: 'Previous page',
  1877. firstPage: 'First page',
  1878. lastPage: 'Last page',
  1879. pageText: '{0}-{1} of {2}'
  1880. },
  1881. dateRangeInput: {
  1882. divider: 'to'
  1883. },
  1884. datePicker: {
  1885. itemsSelected: '{0} selected',
  1886. range: {
  1887. title: 'Select dates',
  1888. header: 'Enter dates'
  1889. },
  1890. title: 'Select date',
  1891. header: 'Enter date',
  1892. input: {
  1893. placeholder: 'Enter date'
  1894. }
  1895. },
  1896. noDataText: 'No data available',
  1897. carousel: {
  1898. prev: 'Previous visual',
  1899. next: 'Next visual',
  1900. ariaLabel: {
  1901. delimiter: 'Carousel slide {0} of {1}'
  1902. }
  1903. },
  1904. calendar: {
  1905. moreEvents: '{0} more',
  1906. today: 'Today'
  1907. },
  1908. input: {
  1909. clear: 'Clear {0}',
  1910. prependAction: '{0} prepended action',
  1911. appendAction: '{0} appended action',
  1912. otp: 'Please enter OTP character {0}'
  1913. },
  1914. fileInput: {
  1915. counter: '{0} files',
  1916. counterSize: '{0} files ({1} in total)'
  1917. },
  1918. fileUpload: {
  1919. title: 'Drag and drop files here',
  1920. divider: 'or',
  1921. browse: 'Browse Files'
  1922. },
  1923. timePicker: {
  1924. am: 'AM',
  1925. pm: 'PM',
  1926. title: 'Select Time'
  1927. },
  1928. pagination: {
  1929. ariaLabel: {
  1930. root: 'Pagination Navigation',
  1931. next: 'Next page',
  1932. previous: 'Previous page',
  1933. page: 'Go to page {0}',
  1934. currentPage: 'Page {0}, Current page',
  1935. first: 'First page',
  1936. last: 'Last page'
  1937. }
  1938. },
  1939. stepper: {
  1940. next: 'Next',
  1941. prev: 'Previous'
  1942. },
  1943. rating: {
  1944. ariaLabel: {
  1945. item: 'Rating {0} of {1}'
  1946. }
  1947. },
  1948. loading: 'Loading...',
  1949. infiniteScroll: {
  1950. loadMore: 'Load more',
  1951. empty: 'No more'
  1952. }
  1953. };
  1954. // Composables
  1955. // Types
  1956. const LANG_PREFIX = '$vuetify.';
  1957. const replace = (str, params) => {
  1958. return str.replace(/\{(\d+)\}/g, (match, index) => {
  1959. return String(params[+index]);
  1960. });
  1961. };
  1962. const createTranslateFunction = (current, fallback, messages) => {
  1963. return function (key) {
  1964. for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  1965. params[_key - 1] = arguments[_key];
  1966. }
  1967. if (!key.startsWith(LANG_PREFIX)) {
  1968. return replace(key, params);
  1969. }
  1970. const shortKey = key.replace(LANG_PREFIX, '');
  1971. const currentLocale = current.value && messages.value[current.value];
  1972. const fallbackLocale = fallback.value && messages.value[fallback.value];
  1973. let str = getObjectValueByPath(currentLocale, shortKey, null);
  1974. if (!str) {
  1975. consoleWarn(`Translation key "${key}" not found in "${current.value}", trying fallback locale`);
  1976. str = getObjectValueByPath(fallbackLocale, shortKey, null);
  1977. }
  1978. if (!str) {
  1979. consoleError(`Translation key "${key}" not found in fallback`);
  1980. str = key;
  1981. }
  1982. if (typeof str !== 'string') {
  1983. consoleError(`Translation key "${key}" has a non-string value`);
  1984. str = key;
  1985. }
  1986. return replace(str, params);
  1987. };
  1988. };
  1989. function createNumberFunction(current, fallback) {
  1990. return (value, options) => {
  1991. const numberFormat = new Intl.NumberFormat([current.value, fallback.value], options);
  1992. return numberFormat.format(value);
  1993. };
  1994. }
  1995. function useProvided(props, prop, provided) {
  1996. const internal = useProxiedModel(props, prop, props[prop] ?? provided.value);
  1997. // TODO: Remove when defaultValue works
  1998. internal.value = props[prop] ?? provided.value;
  1999. watch(provided, v => {
  2000. if (props[prop] == null) {
  2001. internal.value = provided.value;
  2002. }
  2003. });
  2004. return internal;
  2005. }
  2006. function createProvideFunction(state) {
  2007. return props => {
  2008. const current = useProvided(props, 'locale', state.current);
  2009. const fallback = useProvided(props, 'fallback', state.fallback);
  2010. const messages = useProvided(props, 'messages', state.messages);
  2011. return {
  2012. name: 'vuetify',
  2013. current,
  2014. fallback,
  2015. messages,
  2016. t: createTranslateFunction(current, fallback, messages),
  2017. n: createNumberFunction(current, fallback),
  2018. provide: createProvideFunction({
  2019. current,
  2020. fallback,
  2021. messages
  2022. })
  2023. };
  2024. };
  2025. }
  2026. function createVuetifyAdapter(options) {
  2027. const current = shallowRef(options?.locale ?? 'en');
  2028. const fallback = shallowRef(options?.fallback ?? 'en');
  2029. const messages = ref({
  2030. en,
  2031. ...options?.messages
  2032. });
  2033. return {
  2034. name: 'vuetify',
  2035. current,
  2036. fallback,
  2037. messages,
  2038. t: createTranslateFunction(current, fallback, messages),
  2039. n: createNumberFunction(current, fallback),
  2040. provide: createProvideFunction({
  2041. current,
  2042. fallback,
  2043. messages
  2044. })
  2045. };
  2046. }
  2047. // Utilities
  2048. // Types
  2049. const LocaleSymbol = Symbol.for('vuetify:locale');
  2050. function isLocaleInstance(obj) {
  2051. return obj.name != null;
  2052. }
  2053. function createLocale(options) {
  2054. const i18n = options?.adapter && isLocaleInstance(options?.adapter) ? options?.adapter : createVuetifyAdapter(options);
  2055. const rtl = createRtl(i18n, options);
  2056. return {
  2057. ...i18n,
  2058. ...rtl
  2059. };
  2060. }
  2061. function useLocale() {
  2062. const locale = inject$1(LocaleSymbol);
  2063. if (!locale) throw new Error('[Vuetify] Could not find injected locale instance');
  2064. return locale;
  2065. }
  2066. function provideLocale(props) {
  2067. const locale = inject$1(LocaleSymbol);
  2068. if (!locale) throw new Error('[Vuetify] Could not find injected locale instance');
  2069. const i18n = locale.provide(props);
  2070. const rtl = provideRtl(i18n, locale.rtl, props);
  2071. const data = {
  2072. ...i18n,
  2073. ...rtl
  2074. };
  2075. provide(LocaleSymbol, data);
  2076. return data;
  2077. }
  2078. function genDefaults$3() {
  2079. return {
  2080. af: false,
  2081. ar: true,
  2082. bg: false,
  2083. ca: false,
  2084. ckb: false,
  2085. cs: false,
  2086. de: false,
  2087. el: false,
  2088. en: false,
  2089. es: false,
  2090. et: false,
  2091. fa: true,
  2092. fi: false,
  2093. fr: false,
  2094. hr: false,
  2095. hu: false,
  2096. he: true,
  2097. id: false,
  2098. it: false,
  2099. ja: false,
  2100. km: false,
  2101. ko: false,
  2102. lv: false,
  2103. lt: false,
  2104. nl: false,
  2105. no: false,
  2106. pl: false,
  2107. pt: false,
  2108. ro: false,
  2109. ru: false,
  2110. sk: false,
  2111. sl: false,
  2112. srCyrl: false,
  2113. srLatn: false,
  2114. sv: false,
  2115. th: false,
  2116. tr: false,
  2117. az: false,
  2118. uk: false,
  2119. vi: false,
  2120. zhHans: false,
  2121. zhHant: false
  2122. };
  2123. }
  2124. function createRtl(i18n, options) {
  2125. const rtl = ref(options?.rtl ?? genDefaults$3());
  2126. const isRtl = computed(() => rtl.value[i18n.current.value] ?? false);
  2127. return {
  2128. isRtl,
  2129. rtl,
  2130. rtlClasses: computed(() => `v-locale--is-${isRtl.value ? 'rtl' : 'ltr'}`)
  2131. };
  2132. }
  2133. function provideRtl(locale, rtl, props) {
  2134. const isRtl = computed(() => props.rtl ?? rtl.value[locale.current.value] ?? false);
  2135. return {
  2136. isRtl,
  2137. rtl,
  2138. rtlClasses: computed(() => `v-locale--is-${isRtl.value ? 'rtl' : 'ltr'}`)
  2139. };
  2140. }
  2141. function useRtl() {
  2142. const locale = inject$1(LocaleSymbol);
  2143. if (!locale) throw new Error('[Vuetify] Could not find injected rtl instance');
  2144. return {
  2145. isRtl: locale.isRtl,
  2146. rtlClasses: locale.rtlClasses
  2147. };
  2148. }
  2149. // Utilities
  2150. // Types
  2151. const ThemeSymbol = Symbol.for('vuetify:theme');
  2152. const makeThemeProps = propsFactory({
  2153. theme: String
  2154. }, 'theme');
  2155. function genDefaults$2() {
  2156. return {
  2157. defaultTheme: 'light',
  2158. variations: {
  2159. colors: [],
  2160. lighten: 0,
  2161. darken: 0
  2162. },
  2163. themes: {
  2164. light: {
  2165. dark: false,
  2166. colors: {
  2167. background: '#FFFFFF',
  2168. surface: '#FFFFFF',
  2169. 'surface-bright': '#FFFFFF',
  2170. 'surface-light': '#EEEEEE',
  2171. 'surface-variant': '#424242',
  2172. 'on-surface-variant': '#EEEEEE',
  2173. primary: '#1867C0',
  2174. 'primary-darken-1': '#1F5592',
  2175. secondary: '#48A9A6',
  2176. 'secondary-darken-1': '#018786',
  2177. error: '#B00020',
  2178. info: '#2196F3',
  2179. success: '#4CAF50',
  2180. warning: '#FB8C00'
  2181. },
  2182. variables: {
  2183. 'border-color': '#000000',
  2184. 'border-opacity': 0.12,
  2185. 'high-emphasis-opacity': 0.87,
  2186. 'medium-emphasis-opacity': 0.60,
  2187. 'disabled-opacity': 0.38,
  2188. 'idle-opacity': 0.04,
  2189. 'hover-opacity': 0.04,
  2190. 'focus-opacity': 0.12,
  2191. 'selected-opacity': 0.08,
  2192. 'activated-opacity': 0.12,
  2193. 'pressed-opacity': 0.12,
  2194. 'dragged-opacity': 0.08,
  2195. 'theme-kbd': '#212529',
  2196. 'theme-on-kbd': '#FFFFFF',
  2197. 'theme-code': '#F5F5F5',
  2198. 'theme-on-code': '#000000'
  2199. }
  2200. },
  2201. dark: {
  2202. dark: true,
  2203. colors: {
  2204. background: '#121212',
  2205. surface: '#212121',
  2206. 'surface-bright': '#ccbfd6',
  2207. 'surface-light': '#424242',
  2208. 'surface-variant': '#a3a3a3',
  2209. 'on-surface-variant': '#424242',
  2210. primary: '#2196F3',
  2211. 'primary-darken-1': '#277CC1',
  2212. secondary: '#54B6B2',
  2213. 'secondary-darken-1': '#48A9A6',
  2214. error: '#CF6679',
  2215. info: '#2196F3',
  2216. success: '#4CAF50',
  2217. warning: '#FB8C00'
  2218. },
  2219. variables: {
  2220. 'border-color': '#FFFFFF',
  2221. 'border-opacity': 0.12,
  2222. 'high-emphasis-opacity': 1,
  2223. 'medium-emphasis-opacity': 0.70,
  2224. 'disabled-opacity': 0.50,
  2225. 'idle-opacity': 0.10,
  2226. 'hover-opacity': 0.04,
  2227. 'focus-opacity': 0.12,
  2228. 'selected-opacity': 0.08,
  2229. 'activated-opacity': 0.12,
  2230. 'pressed-opacity': 0.16,
  2231. 'dragged-opacity': 0.08,
  2232. 'theme-kbd': '#212529',
  2233. 'theme-on-kbd': '#FFFFFF',
  2234. 'theme-code': '#343434',
  2235. 'theme-on-code': '#CCCCCC'
  2236. }
  2237. }
  2238. }
  2239. };
  2240. }
  2241. function parseThemeOptions() {
  2242. let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : genDefaults$2();
  2243. const defaults = genDefaults$2();
  2244. if (!options) return {
  2245. ...defaults,
  2246. isDisabled: true
  2247. };
  2248. const themes = {};
  2249. for (const [key, theme] of Object.entries(options.themes ?? {})) {
  2250. const defaultTheme = theme.dark || key === 'dark' ? defaults.themes?.dark : defaults.themes?.light;
  2251. themes[key] = mergeDeep(defaultTheme, theme);
  2252. }
  2253. return mergeDeep(defaults, {
  2254. ...options,
  2255. themes
  2256. });
  2257. }
  2258. // Composables
  2259. function createTheme(options) {
  2260. const parsedOptions = parseThemeOptions(options);
  2261. const name = ref(parsedOptions.defaultTheme);
  2262. const themes = ref(parsedOptions.themes);
  2263. const computedThemes = computed(() => {
  2264. const acc = {};
  2265. for (const [name, original] of Object.entries(themes.value)) {
  2266. const theme = acc[name] = {
  2267. ...original,
  2268. colors: {
  2269. ...original.colors
  2270. }
  2271. };
  2272. if (parsedOptions.variations) {
  2273. for (const name of parsedOptions.variations.colors) {
  2274. const color = theme.colors[name];
  2275. if (!color) continue;
  2276. for (const variation of ['lighten', 'darken']) {
  2277. const fn = variation === 'lighten' ? lighten : darken;
  2278. for (const amount of createRange(parsedOptions.variations[variation], 1)) {
  2279. theme.colors[`${name}-${variation}-${amount}`] = RGBtoHex(fn(parseColor(color), amount));
  2280. }
  2281. }
  2282. }
  2283. }
  2284. for (const color of Object.keys(theme.colors)) {
  2285. if (/^on-[a-z]/.test(color) || theme.colors[`on-${color}`]) continue;
  2286. const onColor = `on-${color}`;
  2287. const colorVal = parseColor(theme.colors[color]);
  2288. theme.colors[onColor] = getForeground(colorVal);
  2289. }
  2290. }
  2291. return acc;
  2292. });
  2293. const current = computed(() => computedThemes.value[name.value]);
  2294. const styles = computed(() => {
  2295. const lines = [];
  2296. if (current.value?.dark) {
  2297. createCssClass(lines, ':root', ['color-scheme: dark']);
  2298. }
  2299. createCssClass(lines, ':root', genCssVariables(current.value));
  2300. for (const [themeName, theme] of Object.entries(computedThemes.value)) {
  2301. createCssClass(lines, `.v-theme--${themeName}`, [`color-scheme: ${theme.dark ? 'dark' : 'normal'}`, ...genCssVariables(theme)]);
  2302. }
  2303. const bgLines = [];
  2304. const fgLines = [];
  2305. const colors = new Set(Object.values(computedThemes.value).flatMap(theme => Object.keys(theme.colors)));
  2306. for (const key of colors) {
  2307. if (/^on-[a-z]/.test(key)) {
  2308. createCssClass(fgLines, `.${key}`, [`color: rgb(var(--v-theme-${key})) !important`]);
  2309. } else {
  2310. 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`]);
  2311. createCssClass(fgLines, `.text-${key}`, [`color: rgb(var(--v-theme-${key})) !important`]);
  2312. createCssClass(fgLines, `.border-${key}`, [`--v-border-color: var(--v-theme-${key})`]);
  2313. }
  2314. }
  2315. lines.push(...bgLines, ...fgLines);
  2316. return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('');
  2317. });
  2318. function getHead() {
  2319. return {
  2320. style: [{
  2321. children: styles.value,
  2322. id: 'vuetify-theme-stylesheet',
  2323. nonce: parsedOptions.cspNonce || false
  2324. }]
  2325. };
  2326. }
  2327. function install(app) {
  2328. if (parsedOptions.isDisabled) return;
  2329. const head = app._context.provides.usehead;
  2330. if (head) {
  2331. if (head.push) {
  2332. const entry = head.push(getHead);
  2333. if (IN_BROWSER) {
  2334. watch(styles, () => {
  2335. entry.patch(getHead);
  2336. });
  2337. }
  2338. } else {
  2339. if (IN_BROWSER) {
  2340. head.addHeadObjs(computed(getHead));
  2341. watchEffect(() => head.updateDOM());
  2342. } else {
  2343. head.addHeadObjs(getHead());
  2344. }
  2345. }
  2346. } else {
  2347. let styleEl = IN_BROWSER ? document.getElementById('vuetify-theme-stylesheet') : null;
  2348. if (IN_BROWSER) {
  2349. watch(styles, updateStyles, {
  2350. immediate: true
  2351. });
  2352. } else {
  2353. updateStyles();
  2354. }
  2355. function updateStyles() {
  2356. if (typeof document !== 'undefined' && !styleEl) {
  2357. const el = document.createElement('style');
  2358. el.type = 'text/css';
  2359. el.id = 'vuetify-theme-stylesheet';
  2360. if (parsedOptions.cspNonce) el.setAttribute('nonce', parsedOptions.cspNonce);
  2361. styleEl = el;
  2362. document.head.appendChild(styleEl);
  2363. }
  2364. if (styleEl) styleEl.innerHTML = styles.value;
  2365. }
  2366. }
  2367. }
  2368. const themeClasses = computed(() => parsedOptions.isDisabled ? undefined : `v-theme--${name.value}`);
  2369. return {
  2370. install,
  2371. isDisabled: parsedOptions.isDisabled,
  2372. name,
  2373. themes,
  2374. current,
  2375. computedThemes,
  2376. themeClasses,
  2377. styles,
  2378. global: {
  2379. name,
  2380. current
  2381. }
  2382. };
  2383. }
  2384. function provideTheme(props) {
  2385. getCurrentInstance('provideTheme');
  2386. const theme = inject$1(ThemeSymbol, null);
  2387. if (!theme) throw new Error('Could not find Vuetify theme injection');
  2388. const name = computed(() => {
  2389. return props.theme ?? theme.name.value;
  2390. });
  2391. const current = computed(() => theme.themes.value[name.value]);
  2392. const themeClasses = computed(() => theme.isDisabled ? undefined : `v-theme--${name.value}`);
  2393. const newTheme = {
  2394. ...theme,
  2395. name,
  2396. current,
  2397. themeClasses
  2398. };
  2399. provide(ThemeSymbol, newTheme);
  2400. return newTheme;
  2401. }
  2402. function useTheme() {
  2403. getCurrentInstance('useTheme');
  2404. const theme = inject$1(ThemeSymbol, null);
  2405. if (!theme) throw new Error('Could not find Vuetify theme injection');
  2406. return theme;
  2407. }
  2408. function createCssClass(lines, selector, content) {
  2409. lines.push(`${selector} {\n`, ...content.map(line => ` ${line};\n`), '}\n');
  2410. }
  2411. function genCssVariables(theme) {
  2412. const lightOverlay = theme.dark ? 2 : 1;
  2413. const darkOverlay = theme.dark ? 1 : 2;
  2414. const variables = [];
  2415. for (const [key, value] of Object.entries(theme.colors)) {
  2416. const rgb = parseColor(value);
  2417. variables.push(`--v-theme-${key}: ${rgb.r},${rgb.g},${rgb.b}`);
  2418. if (!key.startsWith('on-')) {
  2419. variables.push(`--v-theme-${key}-overlay-multiplier: ${getLuma(value) > 0.18 ? lightOverlay : darkOverlay}`);
  2420. }
  2421. }
  2422. for (const [key, value] of Object.entries(theme.variables)) {
  2423. const color = typeof value === 'string' && value.startsWith('#') ? parseColor(value) : undefined;
  2424. const rgb = color ? `${color.r}, ${color.g}, ${color.b}` : undefined;
  2425. variables.push(`--v-${key}: ${rgb ?? value}`);
  2426. }
  2427. return variables;
  2428. }
  2429. const makeVAppProps = propsFactory({
  2430. ...makeComponentProps(),
  2431. ...makeLayoutProps({
  2432. fullHeight: true
  2433. }),
  2434. ...makeThemeProps()
  2435. }, 'VApp');
  2436. const VApp = genericComponent()({
  2437. name: 'VApp',
  2438. props: makeVAppProps(),
  2439. setup(props, _ref) {
  2440. let {
  2441. slots
  2442. } = _ref;
  2443. const theme = provideTheme(props);
  2444. const {
  2445. layoutClasses,
  2446. getLayoutItem,
  2447. items,
  2448. layoutRef
  2449. } = createLayout(props);
  2450. const {
  2451. rtlClasses
  2452. } = useRtl();
  2453. useRender(() => createVNode("div", {
  2454. "ref": layoutRef,
  2455. "class": ['v-application', theme.themeClasses.value, layoutClasses.value, rtlClasses.value, props.class],
  2456. "style": [props.style]
  2457. }, [createVNode("div", {
  2458. "class": "v-application__wrap"
  2459. }, [slots.default?.()])]));
  2460. return {
  2461. getLayoutItem,
  2462. items,
  2463. theme
  2464. };
  2465. }
  2466. });
  2467. // Utilities
  2468. // Types
  2469. // Composables
  2470. const makeTagProps = propsFactory({
  2471. tag: {
  2472. type: String,
  2473. default: 'div'
  2474. }
  2475. }, 'tag');
  2476. const makeVToolbarTitleProps = propsFactory({
  2477. text: String,
  2478. ...makeComponentProps(),
  2479. ...makeTagProps()
  2480. }, 'VToolbarTitle');
  2481. const VToolbarTitle = genericComponent()({
  2482. name: 'VToolbarTitle',
  2483. props: makeVToolbarTitleProps(),
  2484. setup(props, _ref) {
  2485. let {
  2486. slots
  2487. } = _ref;
  2488. useRender(() => {
  2489. const hasText = !!(slots.default || slots.text || props.text);
  2490. return createVNode(props.tag, {
  2491. "class": ['v-toolbar-title', props.class],
  2492. "style": props.style
  2493. }, {
  2494. default: () => [hasText && createVNode("div", {
  2495. "class": "v-toolbar-title__placeholder"
  2496. }, [slots.text ? slots.text() : props.text, slots.default?.()])]
  2497. });
  2498. });
  2499. return {};
  2500. }
  2501. });
  2502. // Utilities
  2503. // Types
  2504. const makeTransitionProps$1 = propsFactory({
  2505. disabled: Boolean,
  2506. group: Boolean,
  2507. hideOnLeave: Boolean,
  2508. leaveAbsolute: Boolean,
  2509. mode: String,
  2510. origin: String
  2511. }, 'transition');
  2512. function createCssTransition(name, origin, mode) {
  2513. return genericComponent()({
  2514. name,
  2515. props: makeTransitionProps$1({
  2516. mode,
  2517. origin
  2518. }),
  2519. setup(props, _ref) {
  2520. let {
  2521. slots
  2522. } = _ref;
  2523. const functions = {
  2524. onBeforeEnter(el) {
  2525. if (props.origin) {
  2526. el.style.transformOrigin = props.origin;
  2527. }
  2528. },
  2529. onLeave(el) {
  2530. if (props.leaveAbsolute) {
  2531. const {
  2532. offsetTop,
  2533. offsetLeft,
  2534. offsetWidth,
  2535. offsetHeight
  2536. } = el;
  2537. el._transitionInitialStyles = {
  2538. position: el.style.position,
  2539. top: el.style.top,
  2540. left: el.style.left,
  2541. width: el.style.width,
  2542. height: el.style.height
  2543. };
  2544. el.style.position = 'absolute';
  2545. el.style.top = `${offsetTop}px`;
  2546. el.style.left = `${offsetLeft}px`;
  2547. el.style.width = `${offsetWidth}px`;
  2548. el.style.height = `${offsetHeight}px`;
  2549. }
  2550. if (props.hideOnLeave) {
  2551. el.style.setProperty('display', 'none', 'important');
  2552. }
  2553. },
  2554. onAfterLeave(el) {
  2555. if (props.leaveAbsolute && el?._transitionInitialStyles) {
  2556. const {
  2557. position,
  2558. top,
  2559. left,
  2560. width,
  2561. height
  2562. } = el._transitionInitialStyles;
  2563. delete el._transitionInitialStyles;
  2564. el.style.position = position || '';
  2565. el.style.top = top || '';
  2566. el.style.left = left || '';
  2567. el.style.width = width || '';
  2568. el.style.height = height || '';
  2569. }
  2570. }
  2571. };
  2572. return () => {
  2573. const tag = props.group ? TransitionGroup : Transition;
  2574. return h(tag, {
  2575. name: props.disabled ? '' : name,
  2576. css: !props.disabled,
  2577. ...(props.group ? undefined : {
  2578. mode: props.mode
  2579. }),
  2580. ...(props.disabled ? {} : functions)
  2581. }, slots.default);
  2582. };
  2583. }
  2584. });
  2585. }
  2586. function createJavascriptTransition(name, functions) {
  2587. let mode = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'in-out';
  2588. return genericComponent()({
  2589. name,
  2590. props: {
  2591. mode: {
  2592. type: String,
  2593. default: mode
  2594. },
  2595. disabled: Boolean,
  2596. group: Boolean
  2597. },
  2598. setup(props, _ref2) {
  2599. let {
  2600. slots
  2601. } = _ref2;
  2602. const tag = props.group ? TransitionGroup : Transition;
  2603. return () => {
  2604. return h(tag, {
  2605. name: props.disabled ? '' : name,
  2606. css: !props.disabled,
  2607. // mode: props.mode, // TODO: vuejs/vue-next#3104
  2608. ...(props.disabled ? {} : functions)
  2609. }, slots.default);
  2610. };
  2611. }
  2612. });
  2613. }
  2614. // Utilities
  2615. function ExpandTransitionGenerator () {
  2616. let expandedParentClass = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
  2617. let x = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  2618. const sizeProperty = x ? 'width' : 'height';
  2619. const offsetProperty = camelize(`offset-${sizeProperty}`);
  2620. return {
  2621. onBeforeEnter(el) {
  2622. el._parent = el.parentNode;
  2623. el._initialStyle = {
  2624. transition: el.style.transition,
  2625. overflow: el.style.overflow,
  2626. [sizeProperty]: el.style[sizeProperty]
  2627. };
  2628. },
  2629. onEnter(el) {
  2630. const initialStyle = el._initialStyle;
  2631. el.style.setProperty('transition', 'none', 'important');
  2632. // Hide overflow to account for collapsed margins in the calculated height
  2633. el.style.overflow = 'hidden';
  2634. const offset = `${el[offsetProperty]}px`;
  2635. el.style[sizeProperty] = '0';
  2636. void el.offsetHeight; // force reflow
  2637. el.style.transition = initialStyle.transition;
  2638. if (expandedParentClass && el._parent) {
  2639. el._parent.classList.add(expandedParentClass);
  2640. }
  2641. requestAnimationFrame(() => {
  2642. el.style[sizeProperty] = offset;
  2643. });
  2644. },
  2645. onAfterEnter: resetStyles,
  2646. onEnterCancelled: resetStyles,
  2647. onLeave(el) {
  2648. el._initialStyle = {
  2649. transition: '',
  2650. overflow: el.style.overflow,
  2651. [sizeProperty]: el.style[sizeProperty]
  2652. };
  2653. el.style.overflow = 'hidden';
  2654. el.style[sizeProperty] = `${el[offsetProperty]}px`;
  2655. void el.offsetHeight; // force reflow
  2656. requestAnimationFrame(() => el.style[sizeProperty] = '0');
  2657. },
  2658. onAfterLeave,
  2659. onLeaveCancelled: onAfterLeave
  2660. };
  2661. function onAfterLeave(el) {
  2662. if (expandedParentClass && el._parent) {
  2663. el._parent.classList.remove(expandedParentClass);
  2664. }
  2665. resetStyles(el);
  2666. }
  2667. function resetStyles(el) {
  2668. const size = el._initialStyle[sizeProperty];
  2669. el.style.overflow = el._initialStyle.overflow;
  2670. if (size != null) el.style[sizeProperty] = size;
  2671. delete el._initialStyle;
  2672. }
  2673. }
  2674. // Types
  2675. const makeVDialogTransitionProps = propsFactory({
  2676. target: [Object, Array]
  2677. }, 'v-dialog-transition');
  2678. const VDialogTransition = genericComponent()({
  2679. name: 'VDialogTransition',
  2680. props: makeVDialogTransitionProps(),
  2681. setup(props, _ref) {
  2682. let {
  2683. slots
  2684. } = _ref;
  2685. const functions = {
  2686. onBeforeEnter(el) {
  2687. el.style.pointerEvents = 'none';
  2688. el.style.visibility = 'hidden';
  2689. },
  2690. async onEnter(el, done) {
  2691. await new Promise(resolve => requestAnimationFrame(resolve));
  2692. await new Promise(resolve => requestAnimationFrame(resolve));
  2693. el.style.visibility = '';
  2694. const {
  2695. x,
  2696. y,
  2697. sx,
  2698. sy,
  2699. speed
  2700. } = getDimensions(props.target, el);
  2701. const animation = animate(el, [{
  2702. transform: `translate(${x}px, ${y}px) scale(${sx}, ${sy})`,
  2703. opacity: 0
  2704. }, {}], {
  2705. duration: 225 * speed,
  2706. easing: deceleratedEasing
  2707. });
  2708. getChildren(el)?.forEach(el => {
  2709. animate(el, [{
  2710. opacity: 0
  2711. }, {
  2712. opacity: 0,
  2713. offset: 0.33
  2714. }, {}], {
  2715. duration: 225 * 2 * speed,
  2716. easing: standardEasing
  2717. });
  2718. });
  2719. animation.finished.then(() => done());
  2720. },
  2721. onAfterEnter(el) {
  2722. el.style.removeProperty('pointer-events');
  2723. },
  2724. onBeforeLeave(el) {
  2725. el.style.pointerEvents = 'none';
  2726. },
  2727. async onLeave(el, done) {
  2728. await new Promise(resolve => requestAnimationFrame(resolve));
  2729. const {
  2730. x,
  2731. y,
  2732. sx,
  2733. sy,
  2734. speed
  2735. } = getDimensions(props.target, el);
  2736. const animation = animate(el, [{}, {
  2737. transform: `translate(${x}px, ${y}px) scale(${sx}, ${sy})`,
  2738. opacity: 0
  2739. }], {
  2740. duration: 125 * speed,
  2741. easing: acceleratedEasing
  2742. });
  2743. animation.finished.then(() => done());
  2744. getChildren(el)?.forEach(el => {
  2745. animate(el, [{}, {
  2746. opacity: 0,
  2747. offset: 0.2
  2748. }, {
  2749. opacity: 0
  2750. }], {
  2751. duration: 125 * 2 * speed,
  2752. easing: standardEasing
  2753. });
  2754. });
  2755. },
  2756. onAfterLeave(el) {
  2757. el.style.removeProperty('pointer-events');
  2758. }
  2759. };
  2760. return () => {
  2761. return props.target ? createVNode(Transition, mergeProps({
  2762. "name": "dialog-transition"
  2763. }, functions, {
  2764. "css": false
  2765. }), slots) : createVNode(Transition, {
  2766. "name": "dialog-transition"
  2767. }, slots);
  2768. };
  2769. }
  2770. });
  2771. /** Animatable children (card, sheet, list) */
  2772. function getChildren(el) {
  2773. const els = el.querySelector(':scope > .v-card, :scope > .v-sheet, :scope > .v-list')?.children;
  2774. return els && [...els];
  2775. }
  2776. function getDimensions(target, el) {
  2777. const targetBox = getTargetBox(target);
  2778. const elBox = nullifyTransforms(el);
  2779. const [originX, originY] = getComputedStyle(el).transformOrigin.split(' ').map(v => parseFloat(v));
  2780. const [anchorSide, anchorOffset] = getComputedStyle(el).getPropertyValue('--v-overlay-anchor-origin').split(' ');
  2781. let offsetX = targetBox.left + targetBox.width / 2;
  2782. if (anchorSide === 'left' || anchorOffset === 'left') {
  2783. offsetX -= targetBox.width / 2;
  2784. } else if (anchorSide === 'right' || anchorOffset === 'right') {
  2785. offsetX += targetBox.width / 2;
  2786. }
  2787. let offsetY = targetBox.top + targetBox.height / 2;
  2788. if (anchorSide === 'top' || anchorOffset === 'top') {
  2789. offsetY -= targetBox.height / 2;
  2790. } else if (anchorSide === 'bottom' || anchorOffset === 'bottom') {
  2791. offsetY += targetBox.height / 2;
  2792. }
  2793. const tsx = targetBox.width / elBox.width;
  2794. const tsy = targetBox.height / elBox.height;
  2795. const maxs = Math.max(1, tsx, tsy);
  2796. const sx = tsx / maxs || 0;
  2797. const sy = tsy / maxs || 0;
  2798. // Animate elements larger than 12% of the screen area up to 1.5x slower
  2799. const asa = elBox.width * elBox.height / (window.innerWidth * window.innerHeight);
  2800. const speed = asa > 0.12 ? Math.min(1.5, (asa - 0.12) * 10 + 1) : 1;
  2801. return {
  2802. x: offsetX - (originX + elBox.left),
  2803. y: offsetY - (originY + elBox.top),
  2804. sx,
  2805. sy,
  2806. speed
  2807. };
  2808. }
  2809. // Component specific transitions
  2810. const VFabTransition = createCssTransition('fab-transition', 'center center', 'out-in');
  2811. // Generic transitions
  2812. const VDialogBottomTransition = createCssTransition('dialog-bottom-transition');
  2813. const VDialogTopTransition = createCssTransition('dialog-top-transition');
  2814. const VFadeTransition = createCssTransition('fade-transition');
  2815. const VScaleTransition = createCssTransition('scale-transition');
  2816. const VScrollXTransition = createCssTransition('scroll-x-transition');
  2817. const VScrollXReverseTransition = createCssTransition('scroll-x-reverse-transition');
  2818. const VScrollYTransition = createCssTransition('scroll-y-transition');
  2819. const VScrollYReverseTransition = createCssTransition('scroll-y-reverse-transition');
  2820. const VSlideXTransition = createCssTransition('slide-x-transition');
  2821. const VSlideXReverseTransition = createCssTransition('slide-x-reverse-transition');
  2822. const VSlideYTransition = createCssTransition('slide-y-transition');
  2823. const VSlideYReverseTransition = createCssTransition('slide-y-reverse-transition');
  2824. // Javascript transitions
  2825. const VExpandTransition = createJavascriptTransition('expand-transition', ExpandTransitionGenerator());
  2826. const VExpandXTransition = createJavascriptTransition('expand-x-transition', ExpandTransitionGenerator('', true));
  2827. // Composables
  2828. // Types
  2829. const makeVDefaultsProviderProps = propsFactory({
  2830. defaults: Object,
  2831. disabled: Boolean,
  2832. reset: [Number, String],
  2833. root: [Boolean, String],
  2834. scoped: Boolean
  2835. }, 'VDefaultsProvider');
  2836. const VDefaultsProvider = genericComponent(false)({
  2837. name: 'VDefaultsProvider',
  2838. props: makeVDefaultsProviderProps(),
  2839. setup(props, _ref) {
  2840. let {
  2841. slots
  2842. } = _ref;
  2843. const {
  2844. defaults,
  2845. disabled,
  2846. reset,
  2847. root,
  2848. scoped
  2849. } = toRefs(props);
  2850. provideDefaults(defaults, {
  2851. reset,
  2852. root,
  2853. scoped,
  2854. disabled
  2855. });
  2856. return () => slots.default?.();
  2857. }
  2858. });
  2859. // Utilities
  2860. // Types
  2861. // Composables
  2862. const makeDimensionProps = propsFactory({
  2863. height: [Number, String],
  2864. maxHeight: [Number, String],
  2865. maxWidth: [Number, String],
  2866. minHeight: [Number, String],
  2867. minWidth: [Number, String],
  2868. width: [Number, String]
  2869. }, 'dimension');
  2870. function useDimension(props) {
  2871. const dimensionStyles = computed(() => {
  2872. const styles = {};
  2873. const height = convertToUnit(props.height);
  2874. const maxHeight = convertToUnit(props.maxHeight);
  2875. const maxWidth = convertToUnit(props.maxWidth);
  2876. const minHeight = convertToUnit(props.minHeight);
  2877. const minWidth = convertToUnit(props.minWidth);
  2878. const width = convertToUnit(props.width);
  2879. if (height != null) styles.height = height;
  2880. if (maxHeight != null) styles.maxHeight = maxHeight;
  2881. if (maxWidth != null) styles.maxWidth = maxWidth;
  2882. if (minHeight != null) styles.minHeight = minHeight;
  2883. if (minWidth != null) styles.minWidth = minWidth;
  2884. if (width != null) styles.width = width;
  2885. return styles;
  2886. });
  2887. return {
  2888. dimensionStyles
  2889. };
  2890. }
  2891. function useAspectStyles(props) {
  2892. return {
  2893. aspectStyles: computed(() => {
  2894. const ratio = Number(props.aspectRatio);
  2895. return ratio ? {
  2896. paddingBottom: String(1 / ratio * 100) + '%'
  2897. } : undefined;
  2898. })
  2899. };
  2900. }
  2901. const makeVResponsiveProps = propsFactory({
  2902. aspectRatio: [String, Number],
  2903. contentClass: null,
  2904. inline: Boolean,
  2905. ...makeComponentProps(),
  2906. ...makeDimensionProps()
  2907. }, 'VResponsive');
  2908. const VResponsive = genericComponent()({
  2909. name: 'VResponsive',
  2910. props: makeVResponsiveProps(),
  2911. setup(props, _ref) {
  2912. let {
  2913. slots
  2914. } = _ref;
  2915. const {
  2916. aspectStyles
  2917. } = useAspectStyles(props);
  2918. const {
  2919. dimensionStyles
  2920. } = useDimension(props);
  2921. useRender(() => createVNode("div", {
  2922. "class": ['v-responsive', {
  2923. 'v-responsive--inline': props.inline
  2924. }, props.class],
  2925. "style": [dimensionStyles.value, props.style]
  2926. }, [createVNode("div", {
  2927. "class": "v-responsive__sizer",
  2928. "style": aspectStyles.value
  2929. }, null), slots.additional?.(), slots.default && createVNode("div", {
  2930. "class": ['v-responsive__content', props.contentClass]
  2931. }, [slots.default()])]));
  2932. return {};
  2933. }
  2934. });
  2935. // Utilities
  2936. // Types
  2937. // Composables
  2938. function useColor(colors) {
  2939. return destructComputed(() => {
  2940. const classes = [];
  2941. const styles = {};
  2942. if (colors.value.background) {
  2943. if (isCssColor(colors.value.background)) {
  2944. styles.backgroundColor = colors.value.background;
  2945. if (!colors.value.text && isParsableColor(colors.value.background)) {
  2946. const backgroundColor = parseColor(colors.value.background);
  2947. if (backgroundColor.a == null || backgroundColor.a === 1) {
  2948. const textColor = getForeground(backgroundColor);
  2949. styles.color = textColor;
  2950. styles.caretColor = textColor;
  2951. }
  2952. }
  2953. } else {
  2954. classes.push(`bg-${colors.value.background}`);
  2955. }
  2956. }
  2957. if (colors.value.text) {
  2958. if (isCssColor(colors.value.text)) {
  2959. styles.color = colors.value.text;
  2960. styles.caretColor = colors.value.text;
  2961. } else {
  2962. classes.push(`text-${colors.value.text}`);
  2963. }
  2964. }
  2965. return {
  2966. colorClasses: classes,
  2967. colorStyles: styles
  2968. };
  2969. });
  2970. }
  2971. function useTextColor(props, name) {
  2972. const colors = computed(() => ({
  2973. text: isRef(props) ? props.value : name ? props[name] : null
  2974. }));
  2975. const {
  2976. colorClasses: textColorClasses,
  2977. colorStyles: textColorStyles
  2978. } = useColor(colors);
  2979. return {
  2980. textColorClasses,
  2981. textColorStyles
  2982. };
  2983. }
  2984. function useBackgroundColor(props, name) {
  2985. const colors = computed(() => ({
  2986. background: isRef(props) ? props.value : name ? props[name] : null
  2987. }));
  2988. const {
  2989. colorClasses: backgroundColorClasses,
  2990. colorStyles: backgroundColorStyles
  2991. } = useColor(colors);
  2992. return {
  2993. backgroundColorClasses,
  2994. backgroundColorStyles
  2995. };
  2996. }
  2997. // Utilities
  2998. // Types
  2999. // Composables
  3000. const makeRoundedProps = propsFactory({
  3001. rounded: {
  3002. type: [Boolean, Number, String],
  3003. default: undefined
  3004. },
  3005. tile: Boolean
  3006. }, 'rounded');
  3007. function useRounded(props) {
  3008. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  3009. const roundedClasses = computed(() => {
  3010. const rounded = isRef(props) ? props.value : props.rounded;
  3011. const tile = isRef(props) ? props.value : props.tile;
  3012. const classes = [];
  3013. if (rounded === true || rounded === '') {
  3014. classes.push(`${name}--rounded`);
  3015. } else if (typeof rounded === 'string' || rounded === 0) {
  3016. for (const value of String(rounded).split(' ')) {
  3017. classes.push(`rounded-${value}`);
  3018. }
  3019. } else if (tile || rounded === false) {
  3020. classes.push('rounded-0');
  3021. }
  3022. return classes;
  3023. });
  3024. return {
  3025. roundedClasses
  3026. };
  3027. }
  3028. // Utilities
  3029. // Types
  3030. const makeTransitionProps = propsFactory({
  3031. transition: {
  3032. type: [Boolean, String, Object],
  3033. default: 'fade-transition',
  3034. validator: val => val !== true
  3035. }
  3036. }, 'transition');
  3037. const MaybeTransition = (props, _ref) => {
  3038. let {
  3039. slots
  3040. } = _ref;
  3041. const {
  3042. transition,
  3043. disabled,
  3044. group,
  3045. ...rest
  3046. } = props;
  3047. const {
  3048. component = group ? TransitionGroup : Transition,
  3049. ...customProps
  3050. } = typeof transition === 'object' ? transition : {};
  3051. return h(component, mergeProps(typeof transition === 'string' ? {
  3052. name: disabled ? '' : transition
  3053. } : customProps, typeof transition === 'string' ? {} : Object.fromEntries(Object.entries({
  3054. disabled,
  3055. group
  3056. }).filter(_ref2 => {
  3057. let [_, v] = _ref2;
  3058. return v !== undefined;
  3059. })), rest), slots);
  3060. };
  3061. // Utilities
  3062. // Types
  3063. function mounted$5(el, binding) {
  3064. if (!SUPPORTS_INTERSECTION) return;
  3065. const modifiers = binding.modifiers || {};
  3066. const value = binding.value;
  3067. const {
  3068. handler,
  3069. options
  3070. } = typeof value === 'object' ? value : {
  3071. handler: value,
  3072. options: {}
  3073. };
  3074. const observer = new IntersectionObserver(function () {
  3075. let entries = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  3076. let observer = arguments.length > 1 ? arguments[1] : undefined;
  3077. const _observe = el._observe?.[binding.instance.$.uid];
  3078. if (!_observe) return; // Just in case, should never fire
  3079. const isIntersecting = entries.some(entry => entry.isIntersecting);
  3080. // If is not quiet or has already been
  3081. // initted, invoke the user callback
  3082. if (handler && (!modifiers.quiet || _observe.init) && (!modifiers.once || isIntersecting || _observe.init)) {
  3083. handler(isIntersecting, entries, observer);
  3084. }
  3085. if (isIntersecting && modifiers.once) unmounted$5(el, binding);else _observe.init = true;
  3086. }, options);
  3087. el._observe = Object(el._observe);
  3088. el._observe[binding.instance.$.uid] = {
  3089. init: false,
  3090. observer
  3091. };
  3092. observer.observe(el);
  3093. }
  3094. function unmounted$5(el, binding) {
  3095. const observe = el._observe?.[binding.instance.$.uid];
  3096. if (!observe) return;
  3097. observe.observer.unobserve(el);
  3098. delete el._observe[binding.instance.$.uid];
  3099. }
  3100. const Intersect = {
  3101. mounted: mounted$5,
  3102. unmounted: unmounted$5
  3103. };
  3104. // Types
  3105. // not intended for public use, this is passed in by vuetify-loader
  3106. const makeVImgProps = propsFactory({
  3107. absolute: Boolean,
  3108. alt: String,
  3109. cover: Boolean,
  3110. color: String,
  3111. draggable: {
  3112. type: [Boolean, String],
  3113. default: undefined
  3114. },
  3115. eager: Boolean,
  3116. gradient: String,
  3117. lazySrc: String,
  3118. options: {
  3119. type: Object,
  3120. // For more information on types, navigate to:
  3121. // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
  3122. default: () => ({
  3123. root: undefined,
  3124. rootMargin: undefined,
  3125. threshold: undefined
  3126. })
  3127. },
  3128. sizes: String,
  3129. src: {
  3130. type: [String, Object],
  3131. default: ''
  3132. },
  3133. crossorigin: String,
  3134. referrerpolicy: String,
  3135. srcset: String,
  3136. position: String,
  3137. ...makeVResponsiveProps(),
  3138. ...makeComponentProps(),
  3139. ...makeRoundedProps(),
  3140. ...makeTransitionProps()
  3141. }, 'VImg');
  3142. const VImg = genericComponent()({
  3143. name: 'VImg',
  3144. directives: {
  3145. intersect: Intersect
  3146. },
  3147. props: makeVImgProps(),
  3148. emits: {
  3149. loadstart: value => true,
  3150. load: value => true,
  3151. error: value => true
  3152. },
  3153. setup(props, _ref) {
  3154. let {
  3155. emit,
  3156. slots
  3157. } = _ref;
  3158. const {
  3159. backgroundColorClasses,
  3160. backgroundColorStyles
  3161. } = useBackgroundColor(toRef(props, 'color'));
  3162. const {
  3163. roundedClasses
  3164. } = useRounded(props);
  3165. const vm = getCurrentInstance('VImg');
  3166. const currentSrc = shallowRef(''); // Set from srcset
  3167. const image = ref();
  3168. const state = shallowRef(props.eager ? 'loading' : 'idle');
  3169. const naturalWidth = shallowRef();
  3170. const naturalHeight = shallowRef();
  3171. const normalisedSrc = computed(() => {
  3172. return props.src && typeof props.src === 'object' ? {
  3173. src: props.src.src,
  3174. srcset: props.srcset || props.src.srcset,
  3175. lazySrc: props.lazySrc || props.src.lazySrc,
  3176. aspect: Number(props.aspectRatio || props.src.aspect || 0)
  3177. } : {
  3178. src: props.src,
  3179. srcset: props.srcset,
  3180. lazySrc: props.lazySrc,
  3181. aspect: Number(props.aspectRatio || 0)
  3182. };
  3183. });
  3184. const aspectRatio = computed(() => {
  3185. return normalisedSrc.value.aspect || naturalWidth.value / naturalHeight.value || 0;
  3186. });
  3187. watch(() => props.src, () => {
  3188. init(state.value !== 'idle');
  3189. });
  3190. watch(aspectRatio, (val, oldVal) => {
  3191. if (!val && oldVal && image.value) {
  3192. pollForSize(image.value);
  3193. }
  3194. });
  3195. // TODO: getSrc when window width changes
  3196. onBeforeMount(() => init());
  3197. function init(isIntersecting) {
  3198. if (props.eager && isIntersecting) return;
  3199. if (SUPPORTS_INTERSECTION && !isIntersecting && !props.eager) return;
  3200. state.value = 'loading';
  3201. if (normalisedSrc.value.lazySrc) {
  3202. const lazyImg = new Image();
  3203. lazyImg.src = normalisedSrc.value.lazySrc;
  3204. pollForSize(lazyImg, null);
  3205. }
  3206. if (!normalisedSrc.value.src) return;
  3207. nextTick(() => {
  3208. emit('loadstart', image.value?.currentSrc || normalisedSrc.value.src);
  3209. setTimeout(() => {
  3210. if (vm.isUnmounted) return;
  3211. if (image.value?.complete) {
  3212. if (!image.value.naturalWidth) {
  3213. onError();
  3214. }
  3215. if (state.value === 'error') return;
  3216. if (!aspectRatio.value) pollForSize(image.value, null);
  3217. if (state.value === 'loading') onLoad();
  3218. } else {
  3219. if (!aspectRatio.value) pollForSize(image.value);
  3220. getSrc();
  3221. }
  3222. });
  3223. });
  3224. }
  3225. function onLoad() {
  3226. if (vm.isUnmounted) return;
  3227. getSrc();
  3228. pollForSize(image.value);
  3229. state.value = 'loaded';
  3230. emit('load', image.value?.currentSrc || normalisedSrc.value.src);
  3231. }
  3232. function onError() {
  3233. if (vm.isUnmounted) return;
  3234. state.value = 'error';
  3235. emit('error', image.value?.currentSrc || normalisedSrc.value.src);
  3236. }
  3237. function getSrc() {
  3238. const img = image.value;
  3239. if (img) currentSrc.value = img.currentSrc || img.src;
  3240. }
  3241. let timer = -1;
  3242. onBeforeUnmount(() => {
  3243. clearTimeout(timer);
  3244. });
  3245. function pollForSize(img) {
  3246. let timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100;
  3247. const poll = () => {
  3248. clearTimeout(timer);
  3249. if (vm.isUnmounted) return;
  3250. const {
  3251. naturalHeight: imgHeight,
  3252. naturalWidth: imgWidth
  3253. } = img;
  3254. if (imgHeight || imgWidth) {
  3255. naturalWidth.value = imgWidth;
  3256. naturalHeight.value = imgHeight;
  3257. } else if (!img.complete && state.value === 'loading' && timeout != null) {
  3258. timer = window.setTimeout(poll, timeout);
  3259. } else if (img.currentSrc.endsWith('.svg') || img.currentSrc.startsWith('data:image/svg+xml')) {
  3260. naturalWidth.value = 1;
  3261. naturalHeight.value = 1;
  3262. }
  3263. };
  3264. poll();
  3265. }
  3266. const containClasses = computed(() => ({
  3267. 'v-img__img--cover': props.cover,
  3268. 'v-img__img--contain': !props.cover
  3269. }));
  3270. const __image = () => {
  3271. if (!normalisedSrc.value.src || state.value === 'idle') return null;
  3272. const img = createVNode("img", {
  3273. "class": ['v-img__img', containClasses.value],
  3274. "style": {
  3275. objectPosition: props.position
  3276. },
  3277. "src": normalisedSrc.value.src,
  3278. "srcset": normalisedSrc.value.srcset,
  3279. "alt": props.alt,
  3280. "crossorigin": props.crossorigin,
  3281. "referrerpolicy": props.referrerpolicy,
  3282. "draggable": props.draggable,
  3283. "sizes": props.sizes,
  3284. "ref": image,
  3285. "onLoad": onLoad,
  3286. "onError": onError
  3287. }, null);
  3288. const sources = slots.sources?.();
  3289. return createVNode(MaybeTransition, {
  3290. "transition": props.transition,
  3291. "appear": true
  3292. }, {
  3293. default: () => [withDirectives(sources ? createVNode("picture", {
  3294. "class": "v-img__picture"
  3295. }, [sources, img]) : img, [[vShow, state.value === 'loaded']])]
  3296. });
  3297. };
  3298. const __preloadImage = () => createVNode(MaybeTransition, {
  3299. "transition": props.transition
  3300. }, {
  3301. default: () => [normalisedSrc.value.lazySrc && state.value !== 'loaded' && createVNode("img", {
  3302. "class": ['v-img__img', 'v-img__img--preload', containClasses.value],
  3303. "style": {
  3304. objectPosition: props.position
  3305. },
  3306. "src": normalisedSrc.value.lazySrc,
  3307. "alt": props.alt,
  3308. "crossorigin": props.crossorigin,
  3309. "referrerpolicy": props.referrerpolicy,
  3310. "draggable": props.draggable
  3311. }, null)]
  3312. });
  3313. const __placeholder = () => {
  3314. if (!slots.placeholder) return null;
  3315. return createVNode(MaybeTransition, {
  3316. "transition": props.transition,
  3317. "appear": true
  3318. }, {
  3319. default: () => [(state.value === 'loading' || state.value === 'error' && !slots.error) && createVNode("div", {
  3320. "class": "v-img__placeholder"
  3321. }, [slots.placeholder()])]
  3322. });
  3323. };
  3324. const __error = () => {
  3325. if (!slots.error) return null;
  3326. return createVNode(MaybeTransition, {
  3327. "transition": props.transition,
  3328. "appear": true
  3329. }, {
  3330. default: () => [state.value === 'error' && createVNode("div", {
  3331. "class": "v-img__error"
  3332. }, [slots.error()])]
  3333. });
  3334. };
  3335. const __gradient = () => {
  3336. if (!props.gradient) return null;
  3337. return createVNode("div", {
  3338. "class": "v-img__gradient",
  3339. "style": {
  3340. backgroundImage: `linear-gradient(${props.gradient})`
  3341. }
  3342. }, null);
  3343. };
  3344. const isBooted = shallowRef(false);
  3345. {
  3346. const stop = watch(aspectRatio, val => {
  3347. if (val) {
  3348. // Doesn't work with nextTick, idk why
  3349. requestAnimationFrame(() => {
  3350. requestAnimationFrame(() => {
  3351. isBooted.value = true;
  3352. });
  3353. });
  3354. stop();
  3355. }
  3356. });
  3357. }
  3358. useRender(() => {
  3359. const responsiveProps = VResponsive.filterProps(props);
  3360. return withDirectives(createVNode(VResponsive, mergeProps({
  3361. "class": ['v-img', {
  3362. 'v-img--absolute': props.absolute,
  3363. 'v-img--booting': !isBooted.value
  3364. }, backgroundColorClasses.value, roundedClasses.value, props.class],
  3365. "style": [{
  3366. width: convertToUnit(props.width === 'auto' ? naturalWidth.value : props.width)
  3367. }, backgroundColorStyles.value, props.style]
  3368. }, responsiveProps, {
  3369. "aspectRatio": aspectRatio.value,
  3370. "aria-label": props.alt,
  3371. "role": props.alt ? 'img' : undefined
  3372. }), {
  3373. additional: () => createVNode(Fragment, null, [createVNode(__image, null, null), createVNode(__preloadImage, null, null), createVNode(__gradient, null, null), createVNode(__placeholder, null, null), createVNode(__error, null, null)]),
  3374. default: slots.default
  3375. }), [[resolveDirective("intersect"), {
  3376. handler: init,
  3377. options: props.options
  3378. }, null, {
  3379. once: true
  3380. }]]);
  3381. });
  3382. return {
  3383. currentSrc,
  3384. image,
  3385. state,
  3386. naturalWidth,
  3387. naturalHeight
  3388. };
  3389. }
  3390. });
  3391. // Utilities
  3392. // Types
  3393. // Composables
  3394. const makeBorderProps = propsFactory({
  3395. border: [Boolean, Number, String]
  3396. }, 'border');
  3397. function useBorder(props) {
  3398. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  3399. const borderClasses = computed(() => {
  3400. const border = isRef(props) ? props.value : props.border;
  3401. const classes = [];
  3402. if (border === true || border === '') {
  3403. classes.push(`${name}--border`);
  3404. } else if (typeof border === 'string' || border === 0) {
  3405. for (const value of String(border).split(' ')) {
  3406. classes.push(`border-${value}`);
  3407. }
  3408. }
  3409. return classes;
  3410. });
  3411. return {
  3412. borderClasses
  3413. };
  3414. }
  3415. // Utilities
  3416. // Types
  3417. // Composables
  3418. const makeElevationProps = propsFactory({
  3419. elevation: {
  3420. type: [Number, String],
  3421. validator(v) {
  3422. const value = parseInt(v);
  3423. return !isNaN(value) && value >= 0 &&
  3424. // Material Design has a maximum elevation of 24
  3425. // https://material.io/design/environment/elevation.html#default-elevations
  3426. value <= 24;
  3427. }
  3428. }
  3429. }, 'elevation');
  3430. function useElevation(props) {
  3431. const elevationClasses = computed(() => {
  3432. const elevation = isRef(props) ? props.value : props.elevation;
  3433. const classes = [];
  3434. if (elevation == null) return classes;
  3435. classes.push(`elevation-${elevation}`);
  3436. return classes;
  3437. });
  3438. return {
  3439. elevationClasses
  3440. };
  3441. }
  3442. // Types
  3443. const allowedDensities$1 = [null, 'prominent', 'default', 'comfortable', 'compact'];
  3444. const makeVToolbarProps = propsFactory({
  3445. absolute: Boolean,
  3446. collapse: Boolean,
  3447. color: String,
  3448. density: {
  3449. type: String,
  3450. default: 'default',
  3451. validator: v => allowedDensities$1.includes(v)
  3452. },
  3453. extended: Boolean,
  3454. extensionHeight: {
  3455. type: [Number, String],
  3456. default: 48
  3457. },
  3458. flat: Boolean,
  3459. floating: Boolean,
  3460. height: {
  3461. type: [Number, String],
  3462. default: 64
  3463. },
  3464. image: String,
  3465. title: String,
  3466. ...makeBorderProps(),
  3467. ...makeComponentProps(),
  3468. ...makeElevationProps(),
  3469. ...makeRoundedProps(),
  3470. ...makeTagProps({
  3471. tag: 'header'
  3472. }),
  3473. ...makeThemeProps()
  3474. }, 'VToolbar');
  3475. const VToolbar = genericComponent()({
  3476. name: 'VToolbar',
  3477. props: makeVToolbarProps(),
  3478. setup(props, _ref) {
  3479. let {
  3480. slots
  3481. } = _ref;
  3482. const {
  3483. backgroundColorClasses,
  3484. backgroundColorStyles
  3485. } = useBackgroundColor(toRef(props, 'color'));
  3486. const {
  3487. borderClasses
  3488. } = useBorder(props);
  3489. const {
  3490. elevationClasses
  3491. } = useElevation(props);
  3492. const {
  3493. roundedClasses
  3494. } = useRounded(props);
  3495. const {
  3496. themeClasses
  3497. } = provideTheme(props);
  3498. const {
  3499. rtlClasses
  3500. } = useRtl();
  3501. const isExtended = shallowRef(!!(props.extended || slots.extension?.()));
  3502. 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));
  3503. 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);
  3504. provideDefaults({
  3505. VBtn: {
  3506. variant: 'text'
  3507. }
  3508. });
  3509. useRender(() => {
  3510. const hasTitle = !!(props.title || slots.title);
  3511. const hasImage = !!(slots.image || props.image);
  3512. const extension = slots.extension?.();
  3513. isExtended.value = !!(props.extended || extension);
  3514. return createVNode(props.tag, {
  3515. "class": ['v-toolbar', {
  3516. 'v-toolbar--absolute': props.absolute,
  3517. 'v-toolbar--collapse': props.collapse,
  3518. 'v-toolbar--flat': props.flat,
  3519. 'v-toolbar--floating': props.floating,
  3520. [`v-toolbar--density-${props.density}`]: true
  3521. }, backgroundColorClasses.value, borderClasses.value, elevationClasses.value, roundedClasses.value, themeClasses.value, rtlClasses.value, props.class],
  3522. "style": [backgroundColorStyles.value, props.style]
  3523. }, {
  3524. default: () => [hasImage && createVNode("div", {
  3525. "key": "image",
  3526. "class": "v-toolbar__image"
  3527. }, [!slots.image ? createVNode(VImg, {
  3528. "key": "image-img",
  3529. "cover": true,
  3530. "src": props.image
  3531. }, null) : createVNode(VDefaultsProvider, {
  3532. "key": "image-defaults",
  3533. "disabled": !props.image,
  3534. "defaults": {
  3535. VImg: {
  3536. cover: true,
  3537. src: props.image
  3538. }
  3539. }
  3540. }, slots.image)]), createVNode(VDefaultsProvider, {
  3541. "defaults": {
  3542. VTabs: {
  3543. height: convertToUnit(contentHeight.value)
  3544. }
  3545. }
  3546. }, {
  3547. default: () => [createVNode("div", {
  3548. "class": "v-toolbar__content",
  3549. "style": {
  3550. height: convertToUnit(contentHeight.value)
  3551. }
  3552. }, [slots.prepend && createVNode("div", {
  3553. "class": "v-toolbar__prepend"
  3554. }, [slots.prepend?.()]), hasTitle && createVNode(VToolbarTitle, {
  3555. "key": "title",
  3556. "text": props.title
  3557. }, {
  3558. text: slots.title
  3559. }), slots.default?.(), slots.append && createVNode("div", {
  3560. "class": "v-toolbar__append"
  3561. }, [slots.append?.()])])]
  3562. }), createVNode(VDefaultsProvider, {
  3563. "defaults": {
  3564. VTabs: {
  3565. height: convertToUnit(extensionHeight.value)
  3566. }
  3567. }
  3568. }, {
  3569. default: () => [createVNode(VExpandTransition, null, {
  3570. default: () => [isExtended.value && createVNode("div", {
  3571. "class": "v-toolbar__extension",
  3572. "style": {
  3573. height: convertToUnit(extensionHeight.value)
  3574. }
  3575. }, [extension])]
  3576. })]
  3577. })]
  3578. });
  3579. });
  3580. return {
  3581. contentHeight,
  3582. extensionHeight
  3583. };
  3584. }
  3585. });
  3586. // Utilities
  3587. // Types
  3588. // Composables
  3589. const makeScrollProps = propsFactory({
  3590. scrollTarget: {
  3591. type: String
  3592. },
  3593. scrollThreshold: {
  3594. type: [String, Number],
  3595. default: 300
  3596. }
  3597. }, 'scroll');
  3598. function useScroll(props) {
  3599. let args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  3600. const {
  3601. canScroll
  3602. } = args;
  3603. let previousScroll = 0;
  3604. let previousScrollHeight = 0;
  3605. const target = ref(null);
  3606. const currentScroll = shallowRef(0);
  3607. const savedScroll = shallowRef(0);
  3608. const currentThreshold = shallowRef(0);
  3609. const isScrollActive = shallowRef(false);
  3610. const isScrollingUp = shallowRef(false);
  3611. const scrollThreshold = computed(() => {
  3612. return Number(props.scrollThreshold);
  3613. });
  3614. /**
  3615. * 1: at top
  3616. * 0: at threshold
  3617. */
  3618. const scrollRatio = computed(() => {
  3619. return clamp((scrollThreshold.value - currentScroll.value) / scrollThreshold.value || 0);
  3620. });
  3621. const onScroll = () => {
  3622. const targetEl = target.value;
  3623. if (!targetEl || canScroll && !canScroll.value) return;
  3624. previousScroll = currentScroll.value;
  3625. currentScroll.value = 'window' in targetEl ? targetEl.pageYOffset : targetEl.scrollTop;
  3626. const currentScrollHeight = targetEl instanceof Window ? document.documentElement.scrollHeight : targetEl.scrollHeight;
  3627. if (previousScrollHeight !== currentScrollHeight) {
  3628. previousScrollHeight = currentScrollHeight;
  3629. return;
  3630. }
  3631. isScrollingUp.value = currentScroll.value < previousScroll;
  3632. currentThreshold.value = Math.abs(currentScroll.value - scrollThreshold.value);
  3633. };
  3634. watch(isScrollingUp, () => {
  3635. savedScroll.value = savedScroll.value || currentScroll.value;
  3636. });
  3637. watch(isScrollActive, () => {
  3638. savedScroll.value = 0;
  3639. });
  3640. onMounted(() => {
  3641. watch(() => props.scrollTarget, scrollTarget => {
  3642. const newTarget = scrollTarget ? document.querySelector(scrollTarget) : window;
  3643. if (!newTarget) {
  3644. consoleWarn(`Unable to locate element with identifier ${scrollTarget}`);
  3645. return;
  3646. }
  3647. if (newTarget === target.value) return;
  3648. target.value?.removeEventListener('scroll', onScroll);
  3649. target.value = newTarget;
  3650. target.value.addEventListener('scroll', onScroll, {
  3651. passive: true
  3652. });
  3653. }, {
  3654. immediate: true
  3655. });
  3656. });
  3657. onBeforeUnmount(() => {
  3658. target.value?.removeEventListener('scroll', onScroll);
  3659. });
  3660. // Do we need this? If yes - seems that
  3661. // there's no need to expose onScroll
  3662. canScroll && watch(canScroll, onScroll, {
  3663. immediate: true
  3664. });
  3665. return {
  3666. scrollThreshold,
  3667. currentScroll,
  3668. currentThreshold,
  3669. isScrollActive,
  3670. scrollRatio,
  3671. // required only for testing
  3672. // probably can be removed
  3673. // later (2 chars chlng)
  3674. isScrollingUp,
  3675. savedScroll
  3676. };
  3677. }
  3678. // Utilities
  3679. // Composables
  3680. function useSsrBoot() {
  3681. const isBooted = shallowRef(false);
  3682. onMounted(() => {
  3683. window.requestAnimationFrame(() => {
  3684. isBooted.value = true;
  3685. });
  3686. });
  3687. const ssrBootStyles = computed(() => !isBooted.value ? {
  3688. transition: 'none !important'
  3689. } : undefined);
  3690. return {
  3691. ssrBootStyles,
  3692. isBooted: readonly(isBooted)
  3693. };
  3694. }
  3695. // Types
  3696. const makeVAppBarProps = propsFactory({
  3697. scrollBehavior: String,
  3698. modelValue: {
  3699. type: Boolean,
  3700. default: true
  3701. },
  3702. location: {
  3703. type: String,
  3704. default: 'top',
  3705. validator: value => ['top', 'bottom'].includes(value)
  3706. },
  3707. ...makeVToolbarProps(),
  3708. ...makeLayoutItemProps(),
  3709. ...makeScrollProps(),
  3710. height: {
  3711. type: [Number, String],
  3712. default: 64
  3713. }
  3714. }, 'VAppBar');
  3715. const VAppBar = genericComponent()({
  3716. name: 'VAppBar',
  3717. props: makeVAppBarProps(),
  3718. emits: {
  3719. 'update:modelValue': value => true
  3720. },
  3721. setup(props, _ref) {
  3722. let {
  3723. slots
  3724. } = _ref;
  3725. const vToolbarRef = ref();
  3726. const isActive = useProxiedModel(props, 'modelValue');
  3727. const scrollBehavior = computed(() => {
  3728. const behavior = new Set(props.scrollBehavior?.split(' ') ?? []);
  3729. return {
  3730. hide: behavior.has('hide'),
  3731. fullyHide: behavior.has('fully-hide'),
  3732. inverted: behavior.has('inverted'),
  3733. collapse: behavior.has('collapse'),
  3734. elevate: behavior.has('elevate'),
  3735. fadeImage: behavior.has('fade-image')
  3736. // shrink: behavior.has('shrink'),
  3737. };
  3738. });
  3739. const canScroll = computed(() => {
  3740. const behavior = scrollBehavior.value;
  3741. return behavior.hide || behavior.fullyHide || behavior.inverted || behavior.collapse || behavior.elevate || behavior.fadeImage ||
  3742. // behavior.shrink ||
  3743. !isActive.value;
  3744. });
  3745. const {
  3746. currentScroll,
  3747. scrollThreshold,
  3748. isScrollingUp,
  3749. scrollRatio
  3750. } = useScroll(props, {
  3751. canScroll
  3752. });
  3753. const canHide = computed(() => scrollBehavior.value.hide || scrollBehavior.value.fullyHide);
  3754. const isCollapsed = computed(() => props.collapse || scrollBehavior.value.collapse && (scrollBehavior.value.inverted ? scrollRatio.value > 0 : scrollRatio.value === 0));
  3755. const isFlat = computed(() => props.flat || scrollBehavior.value.fullyHide && !isActive.value || scrollBehavior.value.elevate && (scrollBehavior.value.inverted ? currentScroll.value > 0 : currentScroll.value === 0));
  3756. const opacity = computed(() => scrollBehavior.value.fadeImage ? scrollBehavior.value.inverted ? 1 - scrollRatio.value : scrollRatio.value : undefined);
  3757. const height = computed(() => {
  3758. if (scrollBehavior.value.hide && scrollBehavior.value.inverted) return 0;
  3759. const height = vToolbarRef.value?.contentHeight ?? 0;
  3760. const extensionHeight = vToolbarRef.value?.extensionHeight ?? 0;
  3761. if (!canHide.value) return height + extensionHeight;
  3762. return currentScroll.value < scrollThreshold.value || scrollBehavior.value.fullyHide ? height + extensionHeight : height;
  3763. });
  3764. useToggleScope(computed(() => !!props.scrollBehavior), () => {
  3765. watchEffect(() => {
  3766. if (canHide.value) {
  3767. if (scrollBehavior.value.inverted) {
  3768. isActive.value = currentScroll.value > scrollThreshold.value;
  3769. } else {
  3770. isActive.value = isScrollingUp.value || currentScroll.value < scrollThreshold.value;
  3771. }
  3772. } else {
  3773. isActive.value = true;
  3774. }
  3775. });
  3776. });
  3777. const {
  3778. ssrBootStyles
  3779. } = useSsrBoot();
  3780. const {
  3781. layoutItemStyles
  3782. } = useLayoutItem({
  3783. id: props.name,
  3784. order: computed(() => parseInt(props.order, 10)),
  3785. position: toRef(props, 'location'),
  3786. layoutSize: height,
  3787. elementSize: shallowRef(undefined),
  3788. active: isActive,
  3789. absolute: toRef(props, 'absolute')
  3790. });
  3791. useRender(() => {
  3792. const toolbarProps = VToolbar.filterProps(props);
  3793. return createVNode(VToolbar, mergeProps({
  3794. "ref": vToolbarRef,
  3795. "class": ['v-app-bar', {
  3796. 'v-app-bar--bottom': props.location === 'bottom'
  3797. }, props.class],
  3798. "style": [{
  3799. ...layoutItemStyles.value,
  3800. '--v-toolbar-image-opacity': opacity.value,
  3801. height: undefined,
  3802. ...ssrBootStyles.value
  3803. }, props.style]
  3804. }, toolbarProps, {
  3805. "collapse": isCollapsed.value,
  3806. "flat": isFlat.value
  3807. }), slots);
  3808. });
  3809. return {};
  3810. }
  3811. });
  3812. // Utilities
  3813. // Types
  3814. const allowedDensities = [null, 'default', 'comfortable', 'compact'];
  3815. // typeof allowedDensities[number] evalutes to any
  3816. // when generating api types for whatever reason.
  3817. // Composables
  3818. const makeDensityProps = propsFactory({
  3819. density: {
  3820. type: String,
  3821. default: 'default',
  3822. validator: v => allowedDensities.includes(v)
  3823. }
  3824. }, 'density');
  3825. function useDensity(props) {
  3826. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  3827. const densityClasses = computed(() => {
  3828. return `${name}--density-${props.density}`;
  3829. });
  3830. return {
  3831. densityClasses
  3832. };
  3833. }
  3834. // Types
  3835. const allowedVariants$2 = ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain'];
  3836. function genOverlays(isClickable, name) {
  3837. return createVNode(Fragment, null, [isClickable && createVNode("span", {
  3838. "key": "overlay",
  3839. "class": `${name}__overlay`
  3840. }, null), createVNode("span", {
  3841. "key": "underlay",
  3842. "class": `${name}__underlay`
  3843. }, null)]);
  3844. }
  3845. const makeVariantProps = propsFactory({
  3846. color: String,
  3847. variant: {
  3848. type: String,
  3849. default: 'elevated',
  3850. validator: v => allowedVariants$2.includes(v)
  3851. }
  3852. }, 'variant');
  3853. function useVariant(props) {
  3854. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  3855. const variantClasses = computed(() => {
  3856. const {
  3857. variant
  3858. } = unref(props);
  3859. return `${name}--variant-${variant}`;
  3860. });
  3861. const {
  3862. colorClasses,
  3863. colorStyles
  3864. } = useColor(computed(() => {
  3865. const {
  3866. variant,
  3867. color
  3868. } = unref(props);
  3869. return {
  3870. [['elevated', 'flat'].includes(variant) ? 'background' : 'text']: color
  3871. };
  3872. }));
  3873. return {
  3874. colorClasses,
  3875. colorStyles,
  3876. variantClasses
  3877. };
  3878. }
  3879. const makeVBtnGroupProps = propsFactory({
  3880. baseColor: String,
  3881. divided: Boolean,
  3882. ...makeBorderProps(),
  3883. ...makeComponentProps(),
  3884. ...makeDensityProps(),
  3885. ...makeElevationProps(),
  3886. ...makeRoundedProps(),
  3887. ...makeTagProps(),
  3888. ...makeThemeProps(),
  3889. ...makeVariantProps()
  3890. }, 'VBtnGroup');
  3891. const VBtnGroup = genericComponent()({
  3892. name: 'VBtnGroup',
  3893. props: makeVBtnGroupProps(),
  3894. setup(props, _ref) {
  3895. let {
  3896. slots
  3897. } = _ref;
  3898. const {
  3899. themeClasses
  3900. } = provideTheme(props);
  3901. const {
  3902. densityClasses
  3903. } = useDensity(props);
  3904. const {
  3905. borderClasses
  3906. } = useBorder(props);
  3907. const {
  3908. elevationClasses
  3909. } = useElevation(props);
  3910. const {
  3911. roundedClasses
  3912. } = useRounded(props);
  3913. provideDefaults({
  3914. VBtn: {
  3915. height: 'auto',
  3916. baseColor: toRef(props, 'baseColor'),
  3917. color: toRef(props, 'color'),
  3918. density: toRef(props, 'density'),
  3919. flat: true,
  3920. variant: toRef(props, 'variant')
  3921. }
  3922. });
  3923. useRender(() => {
  3924. return createVNode(props.tag, {
  3925. "class": ['v-btn-group', {
  3926. 'v-btn-group--divided': props.divided
  3927. }, themeClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  3928. "style": props.style
  3929. }, slots);
  3930. });
  3931. }
  3932. });
  3933. // Composables
  3934. // Types
  3935. const makeGroupProps = propsFactory({
  3936. modelValue: {
  3937. type: null,
  3938. default: undefined
  3939. },
  3940. multiple: Boolean,
  3941. mandatory: [Boolean, String],
  3942. max: Number,
  3943. selectedClass: String,
  3944. disabled: Boolean
  3945. }, 'group');
  3946. const makeGroupItemProps = propsFactory({
  3947. value: null,
  3948. disabled: Boolean,
  3949. selectedClass: String
  3950. }, 'group-item');
  3951. // Composables
  3952. function useGroupItem(props, injectKey) {
  3953. let required = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
  3954. const vm = getCurrentInstance('useGroupItem');
  3955. if (!vm) {
  3956. throw new Error('[Vuetify] useGroupItem composable must be used inside a component setup function');
  3957. }
  3958. const id = getUid();
  3959. provide(Symbol.for(`${injectKey.description}:id`), id);
  3960. const group = inject$1(injectKey, null);
  3961. if (!group) {
  3962. if (!required) return group;
  3963. throw new Error(`[Vuetify] Could not find useGroup injection with symbol ${injectKey.description}`);
  3964. }
  3965. const value = toRef(props, 'value');
  3966. const disabled = computed(() => !!(group.disabled.value || props.disabled));
  3967. group.register({
  3968. id,
  3969. value,
  3970. disabled
  3971. }, vm);
  3972. onBeforeUnmount(() => {
  3973. group.unregister(id);
  3974. });
  3975. const isSelected = computed(() => {
  3976. return group.isSelected(id);
  3977. });
  3978. const isFirst = computed(() => {
  3979. return group.items.value[0].id === id;
  3980. });
  3981. const isLast = computed(() => {
  3982. return group.items.value[group.items.value.length - 1].id === id;
  3983. });
  3984. const selectedClass = computed(() => isSelected.value && [group.selectedClass.value, props.selectedClass]);
  3985. watch(isSelected, value => {
  3986. vm.emit('group:selected', {
  3987. value
  3988. });
  3989. }, {
  3990. flush: 'sync'
  3991. });
  3992. return {
  3993. id,
  3994. isSelected,
  3995. isFirst,
  3996. isLast,
  3997. toggle: () => group.select(id, !isSelected.value),
  3998. select: value => group.select(id, value),
  3999. selectedClass,
  4000. value,
  4001. disabled,
  4002. group
  4003. };
  4004. }
  4005. function useGroup(props, injectKey) {
  4006. let isUnmounted = false;
  4007. const items = reactive([]);
  4008. const selected = useProxiedModel(props, 'modelValue', [], v => {
  4009. if (v == null) return [];
  4010. return getIds(items, wrapInArray(v));
  4011. }, v => {
  4012. const arr = getValues(items, v);
  4013. return props.multiple ? arr : arr[0];
  4014. });
  4015. const groupVm = getCurrentInstance('useGroup');
  4016. function register(item, vm) {
  4017. // Is there a better way to fix this typing?
  4018. const unwrapped = item;
  4019. const key = Symbol.for(`${injectKey.description}:id`);
  4020. const children = findChildrenWithProvide(key, groupVm?.vnode);
  4021. const index = children.indexOf(vm);
  4022. if (unref(unwrapped.value) == null) {
  4023. unwrapped.value = index;
  4024. unwrapped.useIndexAsValue = true;
  4025. }
  4026. if (index > -1) {
  4027. items.splice(index, 0, unwrapped);
  4028. } else {
  4029. items.push(unwrapped);
  4030. }
  4031. }
  4032. function unregister(id) {
  4033. if (isUnmounted) return;
  4034. // TODO: re-evaluate this line's importance in the future
  4035. // should we only modify the model if mandatory is set.
  4036. // selected.value = selected.value.filter(v => v !== id)
  4037. forceMandatoryValue();
  4038. const index = items.findIndex(item => item.id === id);
  4039. items.splice(index, 1);
  4040. }
  4041. // If mandatory and nothing is selected, then select first non-disabled item
  4042. function forceMandatoryValue() {
  4043. const item = items.find(item => !item.disabled);
  4044. if (item && props.mandatory === 'force' && !selected.value.length) {
  4045. selected.value = [item.id];
  4046. }
  4047. }
  4048. onMounted(() => {
  4049. forceMandatoryValue();
  4050. });
  4051. onBeforeUnmount(() => {
  4052. isUnmounted = true;
  4053. });
  4054. onUpdated(() => {
  4055. // #19655 update the items that use the index as the value.
  4056. for (let i = 0; i < items.length; i++) {
  4057. if (items[i].useIndexAsValue) {
  4058. items[i].value = i;
  4059. }
  4060. }
  4061. });
  4062. function select(id, value) {
  4063. const item = items.find(item => item.id === id);
  4064. if (value && item?.disabled) return;
  4065. if (props.multiple) {
  4066. const internalValue = selected.value.slice();
  4067. const index = internalValue.findIndex(v => v === id);
  4068. const isSelected = ~index;
  4069. value = value ?? !isSelected;
  4070. // We can't remove value if group is
  4071. // mandatory, value already exists,
  4072. // and it is the only value
  4073. if (isSelected && props.mandatory && internalValue.length <= 1) return;
  4074. // We can't add value if it would
  4075. // cause max limit to be exceeded
  4076. if (!isSelected && props.max != null && internalValue.length + 1 > props.max) return;
  4077. if (index < 0 && value) internalValue.push(id);else if (index >= 0 && !value) internalValue.splice(index, 1);
  4078. selected.value = internalValue;
  4079. } else {
  4080. const isSelected = selected.value.includes(id);
  4081. if (props.mandatory && isSelected) return;
  4082. selected.value = value ?? !isSelected ? [id] : [];
  4083. }
  4084. }
  4085. function step(offset) {
  4086. // getting an offset from selected value obviously won't work with multiple values
  4087. if (props.multiple) consoleWarn('This method is not supported when using "multiple" prop');
  4088. if (!selected.value.length) {
  4089. const item = items.find(item => !item.disabled);
  4090. item && (selected.value = [item.id]);
  4091. } else {
  4092. const currentId = selected.value[0];
  4093. const currentIndex = items.findIndex(i => i.id === currentId);
  4094. let newIndex = (currentIndex + offset) % items.length;
  4095. let newItem = items[newIndex];
  4096. while (newItem.disabled && newIndex !== currentIndex) {
  4097. newIndex = (newIndex + offset) % items.length;
  4098. newItem = items[newIndex];
  4099. }
  4100. if (newItem.disabled) return;
  4101. selected.value = [items[newIndex].id];
  4102. }
  4103. }
  4104. const state = {
  4105. register,
  4106. unregister,
  4107. selected,
  4108. select,
  4109. disabled: toRef(props, 'disabled'),
  4110. prev: () => step(items.length - 1),
  4111. next: () => step(1),
  4112. isSelected: id => selected.value.includes(id),
  4113. selectedClass: computed(() => props.selectedClass),
  4114. items: computed(() => items),
  4115. getItemIndex: value => getItemIndex(items, value)
  4116. };
  4117. provide(injectKey, state);
  4118. return state;
  4119. }
  4120. function getItemIndex(items, value) {
  4121. const ids = getIds(items, [value]);
  4122. if (!ids.length) return -1;
  4123. return items.findIndex(item => item.id === ids[0]);
  4124. }
  4125. function getIds(items, modelValue) {
  4126. const ids = [];
  4127. modelValue.forEach(value => {
  4128. const item = items.find(item => deepEqual(value, item.value));
  4129. const itemByIndex = items[value];
  4130. if (item?.value != null) {
  4131. ids.push(item.id);
  4132. } else if (itemByIndex != null) {
  4133. ids.push(itemByIndex.id);
  4134. }
  4135. });
  4136. return ids;
  4137. }
  4138. function getValues(items, ids) {
  4139. const values = [];
  4140. ids.forEach(id => {
  4141. const itemIndex = items.findIndex(item => item.id === id);
  4142. if (~itemIndex) {
  4143. const item = items[itemIndex];
  4144. values.push(item.value != null ? item.value : itemIndex);
  4145. }
  4146. });
  4147. return values;
  4148. }
  4149. // Types
  4150. const VBtnToggleSymbol = Symbol.for('vuetify:v-btn-toggle');
  4151. const makeVBtnToggleProps = propsFactory({
  4152. ...makeVBtnGroupProps(),
  4153. ...makeGroupProps()
  4154. }, 'VBtnToggle');
  4155. const VBtnToggle = genericComponent()({
  4156. name: 'VBtnToggle',
  4157. props: makeVBtnToggleProps(),
  4158. emits: {
  4159. 'update:modelValue': value => true
  4160. },
  4161. setup(props, _ref) {
  4162. let {
  4163. slots
  4164. } = _ref;
  4165. const {
  4166. isSelected,
  4167. next,
  4168. prev,
  4169. select,
  4170. selected
  4171. } = useGroup(props, VBtnToggleSymbol);
  4172. useRender(() => {
  4173. const btnGroupProps = VBtnGroup.filterProps(props);
  4174. return createVNode(VBtnGroup, mergeProps({
  4175. "class": ['v-btn-toggle', props.class]
  4176. }, btnGroupProps, {
  4177. "style": props.style
  4178. }), {
  4179. default: () => [slots.default?.({
  4180. isSelected,
  4181. next,
  4182. prev,
  4183. select,
  4184. selected
  4185. })]
  4186. });
  4187. });
  4188. return {
  4189. next,
  4190. prev,
  4191. select
  4192. };
  4193. }
  4194. });
  4195. // Composables
  4196. // Types
  4197. const aliases = {
  4198. collapse: 'mdi-chevron-up',
  4199. complete: 'mdi-check',
  4200. cancel: 'mdi-close-circle',
  4201. close: 'mdi-close',
  4202. delete: 'mdi-close-circle',
  4203. // delete (e.g. v-chip close)
  4204. clear: 'mdi-close-circle',
  4205. success: 'mdi-check-circle',
  4206. info: 'mdi-information',
  4207. warning: 'mdi-alert-circle',
  4208. error: 'mdi-close-circle',
  4209. prev: 'mdi-chevron-left',
  4210. next: 'mdi-chevron-right',
  4211. checkboxOn: 'mdi-checkbox-marked',
  4212. checkboxOff: 'mdi-checkbox-blank-outline',
  4213. checkboxIndeterminate: 'mdi-minus-box',
  4214. delimiter: 'mdi-circle',
  4215. // for carousel
  4216. sortAsc: 'mdi-arrow-up',
  4217. sortDesc: 'mdi-arrow-down',
  4218. expand: 'mdi-chevron-down',
  4219. menu: 'mdi-menu',
  4220. subgroup: 'mdi-menu-down',
  4221. dropdown: 'mdi-menu-down',
  4222. radioOn: 'mdi-radiobox-marked',
  4223. radioOff: 'mdi-radiobox-blank',
  4224. edit: 'mdi-pencil',
  4225. ratingEmpty: 'mdi-star-outline',
  4226. ratingFull: 'mdi-star',
  4227. ratingHalf: 'mdi-star-half-full',
  4228. loading: 'mdi-cached',
  4229. first: 'mdi-page-first',
  4230. last: 'mdi-page-last',
  4231. unfold: 'mdi-unfold-more-horizontal',
  4232. file: 'mdi-paperclip',
  4233. plus: 'mdi-plus',
  4234. minus: 'mdi-minus',
  4235. calendar: 'mdi-calendar',
  4236. treeviewCollapse: 'mdi-menu-down',
  4237. treeviewExpand: 'mdi-menu-right',
  4238. eyeDropper: 'mdi-eyedropper',
  4239. upload: 'mdi-cloud-upload'
  4240. };
  4241. const mdi = {
  4242. // Not using mergeProps here, functional components merge props by default (?)
  4243. component: props => h(VClassIcon, {
  4244. ...props,
  4245. class: 'mdi'
  4246. })
  4247. };
  4248. // Types
  4249. const IconValue = [String, Function, Object, Array];
  4250. const IconSymbol = Symbol.for('vuetify:icons');
  4251. const makeIconProps = propsFactory({
  4252. icon: {
  4253. type: IconValue
  4254. },
  4255. // Could not remove this and use makeTagProps, types complained because it is not required
  4256. tag: {
  4257. type: String,
  4258. required: true
  4259. }
  4260. }, 'icon');
  4261. const VComponentIcon = genericComponent()({
  4262. name: 'VComponentIcon',
  4263. props: makeIconProps(),
  4264. setup(props, _ref) {
  4265. let {
  4266. slots
  4267. } = _ref;
  4268. return () => {
  4269. const Icon = props.icon;
  4270. return createVNode(props.tag, null, {
  4271. default: () => [props.icon ? createVNode(Icon, null, null) : slots.default?.()]
  4272. });
  4273. };
  4274. }
  4275. });
  4276. const VSvgIcon = defineComponent({
  4277. name: 'VSvgIcon',
  4278. inheritAttrs: false,
  4279. props: makeIconProps(),
  4280. setup(props, _ref2) {
  4281. let {
  4282. attrs
  4283. } = _ref2;
  4284. return () => {
  4285. return createVNode(props.tag, mergeProps(attrs, {
  4286. "style": null
  4287. }), {
  4288. default: () => [createVNode("svg", {
  4289. "class": "v-icon__svg",
  4290. "xmlns": "http://www.w3.org/2000/svg",
  4291. "viewBox": "0 0 24 24",
  4292. "role": "img",
  4293. "aria-hidden": "true"
  4294. }, [Array.isArray(props.icon) ? props.icon.map(path => Array.isArray(path) ? createVNode("path", {
  4295. "d": path[0],
  4296. "fill-opacity": path[1]
  4297. }, null) : createVNode("path", {
  4298. "d": path
  4299. }, null)) : createVNode("path", {
  4300. "d": props.icon
  4301. }, null)])]
  4302. });
  4303. };
  4304. }
  4305. });
  4306. const VLigatureIcon = defineComponent({
  4307. name: 'VLigatureIcon',
  4308. props: makeIconProps(),
  4309. setup(props) {
  4310. return () => {
  4311. return createVNode(props.tag, null, {
  4312. default: () => [props.icon]
  4313. });
  4314. };
  4315. }
  4316. });
  4317. const VClassIcon = defineComponent({
  4318. name: 'VClassIcon',
  4319. props: makeIconProps(),
  4320. setup(props) {
  4321. return () => {
  4322. return createVNode(props.tag, {
  4323. "class": props.icon
  4324. }, null);
  4325. };
  4326. }
  4327. });
  4328. function genDefaults$1() {
  4329. return {
  4330. svg: {
  4331. component: VSvgIcon
  4332. },
  4333. class: {
  4334. component: VClassIcon
  4335. }
  4336. };
  4337. }
  4338. // Composables
  4339. function createIcons(options) {
  4340. const sets = genDefaults$1();
  4341. const defaultSet = options?.defaultSet ?? 'mdi';
  4342. if (defaultSet === 'mdi' && !sets.mdi) {
  4343. sets.mdi = mdi;
  4344. }
  4345. return mergeDeep({
  4346. defaultSet,
  4347. sets,
  4348. aliases: {
  4349. ...aliases,
  4350. /* eslint-disable max-len */
  4351. 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]],
  4352. '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',
  4353. 'vuetify-play': ['m6.376 13.184-4.11-7.192C1.505 4.66 2.467 3 4.003 3h8.532l-.953 1.576-.006.01-.396.677c-.429.732-.214 1.507.194 2.015.404.503 1.092.878 1.869.806a3.72 3.72 0 0 1 1.005.022c.276.053.434.143.523.237.138.146.38.635-.25 2.09-.893 1.63-1.553 1.722-1.847 1.677-.213-.033-.468-.158-.756-.406a4.95 4.95 0 0 1-.8-.927c-.39-.564-1.04-.84-1.66-.846-.625-.006-1.316.27-1.693.921l-.478.826-.911 1.506Z', ['M9.093 11.552c.046-.079.144-.15.32-.148a.53.53 0 0 1 .43.207c.285.414.636.847 1.046 1.2.405.35.914.662 1.516.754 1.334.205 2.502-.698 3.48-2.495l.014-.028.013-.03c.687-1.574.774-2.852-.005-3.675-.37-.391-.861-.586-1.333-.676a5.243 5.243 0 0 0-1.447-.044c-.173.016-.393-.073-.54-.257-.145-.18-.127-.316-.082-.392l.393-.672L14.287 3h5.71c1.536 0 2.499 1.659 1.737 2.992l-7.997 13.996c-.768 1.344-2.706 1.344-3.473 0l-3.037-5.314 1.377-2.278.004-.006.004-.007.481-.831Z', 0.6]]
  4354. /* eslint-enable max-len */
  4355. }
  4356. }, options);
  4357. }
  4358. const useIcon = props => {
  4359. const icons = inject$1(IconSymbol);
  4360. if (!icons) throw new Error('Missing Vuetify Icons provide!');
  4361. const iconData = computed(() => {
  4362. const iconAlias = unref(props);
  4363. if (!iconAlias) return {
  4364. component: VComponentIcon
  4365. };
  4366. let icon = iconAlias;
  4367. if (typeof icon === 'string') {
  4368. icon = icon.trim();
  4369. if (icon.startsWith('$')) {
  4370. icon = icons.aliases?.[icon.slice(1)];
  4371. }
  4372. }
  4373. if (!icon) consoleWarn(`Could not find aliased icon "${iconAlias}"`);
  4374. if (Array.isArray(icon)) {
  4375. return {
  4376. component: VSvgIcon,
  4377. icon
  4378. };
  4379. } else if (typeof icon !== 'string') {
  4380. return {
  4381. component: VComponentIcon,
  4382. icon
  4383. };
  4384. }
  4385. const iconSetName = Object.keys(icons.sets).find(setName => typeof icon === 'string' && icon.startsWith(`${setName}:`));
  4386. const iconName = iconSetName ? icon.slice(iconSetName.length + 1) : icon;
  4387. const iconSet = icons.sets[iconSetName ?? icons.defaultSet];
  4388. return {
  4389. component: iconSet.component,
  4390. icon: iconName
  4391. };
  4392. });
  4393. return {
  4394. iconData
  4395. };
  4396. };
  4397. // Utilities
  4398. // Types
  4399. const predefinedSizes = ['x-small', 'small', 'default', 'large', 'x-large'];
  4400. // Composables
  4401. const makeSizeProps = propsFactory({
  4402. size: {
  4403. type: [String, Number],
  4404. default: 'default'
  4405. }
  4406. }, 'size');
  4407. function useSize(props) {
  4408. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  4409. return destructComputed(() => {
  4410. let sizeClasses;
  4411. let sizeStyles;
  4412. if (includes(predefinedSizes, props.size)) {
  4413. sizeClasses = `${name}--size-${props.size}`;
  4414. } else if (props.size) {
  4415. sizeStyles = {
  4416. width: convertToUnit(props.size),
  4417. height: convertToUnit(props.size)
  4418. };
  4419. }
  4420. return {
  4421. sizeClasses,
  4422. sizeStyles
  4423. };
  4424. });
  4425. }
  4426. const makeVIconProps = propsFactory({
  4427. color: String,
  4428. disabled: Boolean,
  4429. start: Boolean,
  4430. end: Boolean,
  4431. icon: IconValue,
  4432. ...makeComponentProps(),
  4433. ...makeSizeProps(),
  4434. ...makeTagProps({
  4435. tag: 'i'
  4436. }),
  4437. ...makeThemeProps()
  4438. }, 'VIcon');
  4439. const VIcon = genericComponent()({
  4440. name: 'VIcon',
  4441. props: makeVIconProps(),
  4442. setup(props, _ref) {
  4443. let {
  4444. attrs,
  4445. slots
  4446. } = _ref;
  4447. const slotIcon = ref();
  4448. const {
  4449. themeClasses
  4450. } = provideTheme(props);
  4451. const {
  4452. iconData
  4453. } = useIcon(computed(() => slotIcon.value || props.icon));
  4454. const {
  4455. sizeClasses
  4456. } = useSize(props);
  4457. const {
  4458. textColorClasses,
  4459. textColorStyles
  4460. } = useTextColor(toRef(props, 'color'));
  4461. useRender(() => {
  4462. const slotValue = slots.default?.();
  4463. if (slotValue) {
  4464. slotIcon.value = flattenFragments(slotValue).filter(node => node.type === Text && node.children && typeof node.children === 'string')[0]?.children;
  4465. }
  4466. const hasClick = !!(attrs.onClick || attrs.onClickOnce);
  4467. return createVNode(iconData.value.component, {
  4468. "tag": props.tag,
  4469. "icon": iconData.value.icon,
  4470. "class": ['v-icon', 'notranslate', themeClasses.value, sizeClasses.value, textColorClasses.value, {
  4471. 'v-icon--clickable': hasClick,
  4472. 'v-icon--disabled': props.disabled,
  4473. 'v-icon--start': props.start,
  4474. 'v-icon--end': props.end
  4475. }, props.class],
  4476. "style": [!sizeClasses.value ? {
  4477. fontSize: convertToUnit(props.size),
  4478. height: convertToUnit(props.size),
  4479. width: convertToUnit(props.size)
  4480. } : undefined, textColorStyles.value, props.style],
  4481. "role": hasClick ? 'button' : undefined,
  4482. "aria-hidden": !hasClick,
  4483. "tabindex": hasClick ? props.disabled ? -1 : 0 : undefined
  4484. }, {
  4485. default: () => [slotValue]
  4486. });
  4487. });
  4488. return {};
  4489. }
  4490. });
  4491. // Utilities
  4492. function useIntersectionObserver(callback, options) {
  4493. const intersectionRef = ref();
  4494. const isIntersecting = shallowRef(false);
  4495. if (SUPPORTS_INTERSECTION) {
  4496. const observer = new IntersectionObserver(entries => {
  4497. callback?.(entries, observer);
  4498. isIntersecting.value = !!entries.find(entry => entry.isIntersecting);
  4499. }, options);
  4500. onBeforeUnmount(() => {
  4501. observer.disconnect();
  4502. });
  4503. watch(intersectionRef, (newValue, oldValue) => {
  4504. if (oldValue) {
  4505. observer.unobserve(oldValue);
  4506. isIntersecting.value = false;
  4507. }
  4508. if (newValue) observer.observe(newValue);
  4509. }, {
  4510. flush: 'post'
  4511. });
  4512. }
  4513. return {
  4514. intersectionRef,
  4515. isIntersecting
  4516. };
  4517. }
  4518. // Types
  4519. const makeVProgressCircularProps = propsFactory({
  4520. bgColor: String,
  4521. color: String,
  4522. indeterminate: [Boolean, String],
  4523. modelValue: {
  4524. type: [Number, String],
  4525. default: 0
  4526. },
  4527. rotate: {
  4528. type: [Number, String],
  4529. default: 0
  4530. },
  4531. width: {
  4532. type: [Number, String],
  4533. default: 4
  4534. },
  4535. ...makeComponentProps(),
  4536. ...makeSizeProps(),
  4537. ...makeTagProps({
  4538. tag: 'div'
  4539. }),
  4540. ...makeThemeProps()
  4541. }, 'VProgressCircular');
  4542. const VProgressCircular = genericComponent()({
  4543. name: 'VProgressCircular',
  4544. props: makeVProgressCircularProps(),
  4545. setup(props, _ref) {
  4546. let {
  4547. slots
  4548. } = _ref;
  4549. const MAGIC_RADIUS_CONSTANT = 20;
  4550. const CIRCUMFERENCE = 2 * Math.PI * MAGIC_RADIUS_CONSTANT;
  4551. const root = ref();
  4552. const {
  4553. themeClasses
  4554. } = provideTheme(props);
  4555. const {
  4556. sizeClasses,
  4557. sizeStyles
  4558. } = useSize(props);
  4559. const {
  4560. textColorClasses,
  4561. textColorStyles
  4562. } = useTextColor(toRef(props, 'color'));
  4563. const {
  4564. textColorClasses: underlayColorClasses,
  4565. textColorStyles: underlayColorStyles
  4566. } = useTextColor(toRef(props, 'bgColor'));
  4567. const {
  4568. intersectionRef,
  4569. isIntersecting
  4570. } = useIntersectionObserver();
  4571. const {
  4572. resizeRef,
  4573. contentRect
  4574. } = useResizeObserver();
  4575. const normalizedValue = computed(() => Math.max(0, Math.min(100, parseFloat(props.modelValue))));
  4576. const width = computed(() => Number(props.width));
  4577. const size = computed(() => {
  4578. // Get size from element if size prop value is small, large etc
  4579. return sizeStyles.value ? Number(props.size) : contentRect.value ? contentRect.value.width : Math.max(width.value, 32);
  4580. });
  4581. const diameter = computed(() => MAGIC_RADIUS_CONSTANT / (1 - width.value / size.value) * 2);
  4582. const strokeWidth = computed(() => width.value / size.value * diameter.value);
  4583. const strokeDashOffset = computed(() => convertToUnit((100 - normalizedValue.value) / 100 * CIRCUMFERENCE));
  4584. watchEffect(() => {
  4585. intersectionRef.value = root.value;
  4586. resizeRef.value = root.value;
  4587. });
  4588. useRender(() => createVNode(props.tag, {
  4589. "ref": root,
  4590. "class": ['v-progress-circular', {
  4591. 'v-progress-circular--indeterminate': !!props.indeterminate,
  4592. 'v-progress-circular--visible': isIntersecting.value,
  4593. 'v-progress-circular--disable-shrink': props.indeterminate === 'disable-shrink'
  4594. }, themeClasses.value, sizeClasses.value, textColorClasses.value, props.class],
  4595. "style": [sizeStyles.value, textColorStyles.value, props.style],
  4596. "role": "progressbar",
  4597. "aria-valuemin": "0",
  4598. "aria-valuemax": "100",
  4599. "aria-valuenow": props.indeterminate ? undefined : normalizedValue.value
  4600. }, {
  4601. default: () => [createVNode("svg", {
  4602. "style": {
  4603. transform: `rotate(calc(-90deg + ${Number(props.rotate)}deg))`
  4604. },
  4605. "xmlns": "http://www.w3.org/2000/svg",
  4606. "viewBox": `0 0 ${diameter.value} ${diameter.value}`
  4607. }, [createVNode("circle", {
  4608. "class": ['v-progress-circular__underlay', underlayColorClasses.value],
  4609. "style": underlayColorStyles.value,
  4610. "fill": "transparent",
  4611. "cx": "50%",
  4612. "cy": "50%",
  4613. "r": MAGIC_RADIUS_CONSTANT,
  4614. "stroke-width": strokeWidth.value,
  4615. "stroke-dasharray": CIRCUMFERENCE,
  4616. "stroke-dashoffset": 0
  4617. }, null), createVNode("circle", {
  4618. "class": "v-progress-circular__overlay",
  4619. "fill": "transparent",
  4620. "cx": "50%",
  4621. "cy": "50%",
  4622. "r": MAGIC_RADIUS_CONSTANT,
  4623. "stroke-width": strokeWidth.value,
  4624. "stroke-dasharray": CIRCUMFERENCE,
  4625. "stroke-dashoffset": strokeDashOffset.value
  4626. }, null)]), slots.default && createVNode("div", {
  4627. "class": "v-progress-circular__content"
  4628. }, [slots.default({
  4629. value: normalizedValue.value
  4630. })])]
  4631. }));
  4632. return {};
  4633. }
  4634. });
  4635. // Composables
  4636. // Types
  4637. const oppositeMap = {
  4638. center: 'center',
  4639. top: 'bottom',
  4640. bottom: 'top',
  4641. left: 'right',
  4642. right: 'left'
  4643. };
  4644. const makeLocationProps = propsFactory({
  4645. location: String
  4646. }, 'location');
  4647. function useLocation(props) {
  4648. let opposite = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  4649. let offset = arguments.length > 2 ? arguments[2] : undefined;
  4650. const {
  4651. isRtl
  4652. } = useRtl();
  4653. const locationStyles = computed(() => {
  4654. if (!props.location) return {};
  4655. const {
  4656. side,
  4657. align
  4658. } = parseAnchor(props.location.split(' ').length > 1 ? props.location : `${props.location} center`, isRtl.value);
  4659. function getOffset(side) {
  4660. return offset ? offset(side) : 0;
  4661. }
  4662. const styles = {};
  4663. if (side !== 'center') {
  4664. if (opposite) styles[oppositeMap[side]] = `calc(100% - ${getOffset(side)}px)`;else styles[side] = 0;
  4665. }
  4666. if (align !== 'center') {
  4667. if (opposite) styles[oppositeMap[align]] = `calc(100% - ${getOffset(align)}px)`;else styles[align] = 0;
  4668. } else {
  4669. if (side === 'center') styles.top = styles.left = '50%';else {
  4670. styles[{
  4671. top: 'left',
  4672. bottom: 'left',
  4673. left: 'top',
  4674. right: 'top'
  4675. }[side]] = '50%';
  4676. }
  4677. styles.transform = {
  4678. top: 'translateX(-50%)',
  4679. bottom: 'translateX(-50%)',
  4680. left: 'translateY(-50%)',
  4681. right: 'translateY(-50%)',
  4682. center: 'translate(-50%, -50%)'
  4683. }[side];
  4684. }
  4685. return styles;
  4686. });
  4687. return {
  4688. locationStyles
  4689. };
  4690. }
  4691. const makeVProgressLinearProps = propsFactory({
  4692. absolute: Boolean,
  4693. active: {
  4694. type: Boolean,
  4695. default: true
  4696. },
  4697. bgColor: String,
  4698. bgOpacity: [Number, String],
  4699. bufferValue: {
  4700. type: [Number, String],
  4701. default: 0
  4702. },
  4703. bufferColor: String,
  4704. bufferOpacity: [Number, String],
  4705. clickable: Boolean,
  4706. color: String,
  4707. height: {
  4708. type: [Number, String],
  4709. default: 4
  4710. },
  4711. indeterminate: Boolean,
  4712. max: {
  4713. type: [Number, String],
  4714. default: 100
  4715. },
  4716. modelValue: {
  4717. type: [Number, String],
  4718. default: 0
  4719. },
  4720. opacity: [Number, String],
  4721. reverse: Boolean,
  4722. stream: Boolean,
  4723. striped: Boolean,
  4724. roundedBar: Boolean,
  4725. ...makeComponentProps(),
  4726. ...makeLocationProps({
  4727. location: 'top'
  4728. }),
  4729. ...makeRoundedProps(),
  4730. ...makeTagProps(),
  4731. ...makeThemeProps()
  4732. }, 'VProgressLinear');
  4733. const VProgressLinear = genericComponent()({
  4734. name: 'VProgressLinear',
  4735. props: makeVProgressLinearProps(),
  4736. emits: {
  4737. 'update:modelValue': value => true
  4738. },
  4739. setup(props, _ref) {
  4740. let {
  4741. slots
  4742. } = _ref;
  4743. const progress = useProxiedModel(props, 'modelValue');
  4744. const {
  4745. isRtl,
  4746. rtlClasses
  4747. } = useRtl();
  4748. const {
  4749. themeClasses
  4750. } = provideTheme(props);
  4751. const {
  4752. locationStyles
  4753. } = useLocation(props);
  4754. const {
  4755. textColorClasses,
  4756. textColorStyles
  4757. } = useTextColor(props, 'color');
  4758. const {
  4759. backgroundColorClasses,
  4760. backgroundColorStyles
  4761. } = useBackgroundColor(computed(() => props.bgColor || props.color));
  4762. const {
  4763. backgroundColorClasses: bufferColorClasses,
  4764. backgroundColorStyles: bufferColorStyles
  4765. } = useBackgroundColor(computed(() => props.bufferColor || props.bgColor || props.color));
  4766. const {
  4767. backgroundColorClasses: barColorClasses,
  4768. backgroundColorStyles: barColorStyles
  4769. } = useBackgroundColor(props, 'color');
  4770. const {
  4771. roundedClasses
  4772. } = useRounded(props);
  4773. const {
  4774. intersectionRef,
  4775. isIntersecting
  4776. } = useIntersectionObserver();
  4777. const max = computed(() => parseFloat(props.max));
  4778. const height = computed(() => parseFloat(props.height));
  4779. const normalizedBuffer = computed(() => clamp(parseFloat(props.bufferValue) / max.value * 100, 0, 100));
  4780. const normalizedValue = computed(() => clamp(parseFloat(progress.value) / max.value * 100, 0, 100));
  4781. const isReversed = computed(() => isRtl.value !== props.reverse);
  4782. const transition = computed(() => props.indeterminate ? 'fade-transition' : 'slide-x-transition');
  4783. const isForcedColorsModeActive = IN_BROWSER && window.matchMedia?.('(forced-colors: active)').matches;
  4784. function handleClick(e) {
  4785. if (!intersectionRef.value) return;
  4786. const {
  4787. left,
  4788. right,
  4789. width
  4790. } = intersectionRef.value.getBoundingClientRect();
  4791. const value = isReversed.value ? width - e.clientX + (right - width) : e.clientX - left;
  4792. progress.value = Math.round(value / width * max.value);
  4793. }
  4794. useRender(() => createVNode(props.tag, {
  4795. "ref": intersectionRef,
  4796. "class": ['v-progress-linear', {
  4797. 'v-progress-linear--absolute': props.absolute,
  4798. 'v-progress-linear--active': props.active && isIntersecting.value,
  4799. 'v-progress-linear--reverse': isReversed.value,
  4800. 'v-progress-linear--rounded': props.rounded,
  4801. 'v-progress-linear--rounded-bar': props.roundedBar,
  4802. 'v-progress-linear--striped': props.striped
  4803. }, roundedClasses.value, themeClasses.value, rtlClasses.value, props.class],
  4804. "style": [{
  4805. bottom: props.location === 'bottom' ? 0 : undefined,
  4806. top: props.location === 'top' ? 0 : undefined,
  4807. height: props.active ? convertToUnit(height.value) : 0,
  4808. '--v-progress-linear-height': convertToUnit(height.value),
  4809. ...(props.absolute ? locationStyles.value : {})
  4810. }, props.style],
  4811. "role": "progressbar",
  4812. "aria-hidden": props.active ? 'false' : 'true',
  4813. "aria-valuemin": "0",
  4814. "aria-valuemax": props.max,
  4815. "aria-valuenow": props.indeterminate ? undefined : normalizedValue.value,
  4816. "onClick": props.clickable && handleClick
  4817. }, {
  4818. default: () => [props.stream && createVNode("div", {
  4819. "key": "stream",
  4820. "class": ['v-progress-linear__stream', textColorClasses.value],
  4821. "style": {
  4822. ...textColorStyles.value,
  4823. [isReversed.value ? 'left' : 'right']: convertToUnit(-height.value),
  4824. borderTop: `${convertToUnit(height.value / 2)} dotted`,
  4825. opacity: parseFloat(props.bufferOpacity),
  4826. top: `calc(50% - ${convertToUnit(height.value / 4)})`,
  4827. width: convertToUnit(100 - normalizedBuffer.value, '%'),
  4828. '--v-progress-linear-stream-to': convertToUnit(height.value * (isReversed.value ? 1 : -1))
  4829. }
  4830. }, null), createVNode("div", {
  4831. "class": ['v-progress-linear__background', !isForcedColorsModeActive ? backgroundColorClasses.value : undefined],
  4832. "style": [backgroundColorStyles.value, {
  4833. opacity: parseFloat(props.bgOpacity),
  4834. width: props.stream ? 0 : undefined
  4835. }]
  4836. }, null), createVNode("div", {
  4837. "class": ['v-progress-linear__buffer', !isForcedColorsModeActive ? bufferColorClasses.value : undefined],
  4838. "style": [bufferColorStyles.value, {
  4839. opacity: parseFloat(props.bufferOpacity),
  4840. width: convertToUnit(normalizedBuffer.value, '%')
  4841. }]
  4842. }, null), createVNode(Transition, {
  4843. "name": transition.value
  4844. }, {
  4845. default: () => [!props.indeterminate ? createVNode("div", {
  4846. "class": ['v-progress-linear__determinate', !isForcedColorsModeActive ? barColorClasses.value : undefined],
  4847. "style": [barColorStyles.value, {
  4848. width: convertToUnit(normalizedValue.value, '%')
  4849. }]
  4850. }, null) : createVNode("div", {
  4851. "class": "v-progress-linear__indeterminate"
  4852. }, [['long', 'short'].map(bar => createVNode("div", {
  4853. "key": bar,
  4854. "class": ['v-progress-linear__indeterminate', bar, !isForcedColorsModeActive ? barColorClasses.value : undefined],
  4855. "style": barColorStyles.value
  4856. }, null))])]
  4857. }), slots.default && createVNode("div", {
  4858. "class": "v-progress-linear__content"
  4859. }, [slots.default({
  4860. value: normalizedValue.value,
  4861. buffer: normalizedBuffer.value
  4862. })])]
  4863. }));
  4864. return {};
  4865. }
  4866. });
  4867. // Types
  4868. // Composables
  4869. const makeLoaderProps = propsFactory({
  4870. loading: [Boolean, String]
  4871. }, 'loader');
  4872. function useLoader(props) {
  4873. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  4874. const loaderClasses = computed(() => ({
  4875. [`${name}--loading`]: props.loading
  4876. }));
  4877. return {
  4878. loaderClasses
  4879. };
  4880. }
  4881. function LoaderSlot(props, _ref) {
  4882. let {
  4883. slots
  4884. } = _ref;
  4885. return createVNode("div", {
  4886. "class": `${props.name}__loader`
  4887. }, [slots.default?.({
  4888. color: props.color,
  4889. isActive: props.active
  4890. }) || createVNode(VProgressLinear, {
  4891. "absolute": props.absolute,
  4892. "active": props.active,
  4893. "color": props.color,
  4894. "height": "2",
  4895. "indeterminate": true
  4896. }, null)]);
  4897. }
  4898. // Utilities
  4899. // Types
  4900. const positionValues = ['static', 'relative', 'fixed', 'absolute', 'sticky'];
  4901. // Composables
  4902. const makePositionProps = propsFactory({
  4903. position: {
  4904. type: String,
  4905. validator: /* istanbul ignore next */v => positionValues.includes(v)
  4906. }
  4907. }, 'position');
  4908. function usePosition(props) {
  4909. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  4910. const positionClasses = computed(() => {
  4911. return props.position ? `${name}--${props.position}` : undefined;
  4912. });
  4913. return {
  4914. positionClasses
  4915. };
  4916. }
  4917. // Utilities
  4918. // Types
  4919. function useRoute() {
  4920. const vm = getCurrentInstance('useRoute');
  4921. return computed(() => vm?.proxy?.$route);
  4922. }
  4923. function useRouter() {
  4924. return getCurrentInstance('useRouter')?.proxy?.$router;
  4925. }
  4926. function useLink(props, attrs) {
  4927. const RouterLink = resolveDynamicComponent('RouterLink');
  4928. const isLink = computed(() => !!(props.href || props.to));
  4929. const isClickable = computed(() => {
  4930. return isLink?.value || hasEvent(attrs, 'click') || hasEvent(props, 'click');
  4931. });
  4932. if (typeof RouterLink === 'string' || !('useLink' in RouterLink)) {
  4933. const href = toRef(props, 'href');
  4934. return {
  4935. isLink,
  4936. isClickable,
  4937. href,
  4938. linkProps: reactive({
  4939. href
  4940. })
  4941. };
  4942. }
  4943. // vue-router useLink `to` prop needs to be reactive and useLink will crash if undefined
  4944. const linkProps = computed(() => ({
  4945. ...props,
  4946. to: toRef(() => props.to || '')
  4947. }));
  4948. const routerLink = RouterLink.useLink(linkProps.value);
  4949. // Actual link needs to be undefined when to prop is not used
  4950. const link = computed(() => props.to ? routerLink : undefined);
  4951. const route = useRoute();
  4952. const isActive = computed(() => {
  4953. if (!link.value) return false;
  4954. if (!props.exact) return link.value.isActive?.value ?? false;
  4955. if (!route.value) return link.value.isExactActive?.value ?? false;
  4956. return link.value.isExactActive?.value && deepEqual(link.value.route.value.query, route.value.query);
  4957. });
  4958. const href = computed(() => props.to ? link.value?.route.value.href : props.href);
  4959. return {
  4960. isLink,
  4961. isClickable,
  4962. isActive,
  4963. route: link.value?.route,
  4964. navigate: link.value?.navigate,
  4965. href,
  4966. linkProps: reactive({
  4967. href,
  4968. 'aria-current': computed(() => isActive.value ? 'page' : undefined)
  4969. })
  4970. };
  4971. }
  4972. const makeRouterProps = propsFactory({
  4973. href: String,
  4974. replace: Boolean,
  4975. to: [String, Object],
  4976. exact: Boolean
  4977. }, 'router');
  4978. let inTransition = false;
  4979. function useBackButton(router, cb) {
  4980. let popped = false;
  4981. let removeBefore;
  4982. let removeAfter;
  4983. if (IN_BROWSER) {
  4984. nextTick(() => {
  4985. window.addEventListener('popstate', onPopstate);
  4986. removeBefore = router?.beforeEach((to, from, next) => {
  4987. if (!inTransition) {
  4988. setTimeout(() => popped ? cb(next) : next());
  4989. } else {
  4990. popped ? cb(next) : next();
  4991. }
  4992. inTransition = true;
  4993. });
  4994. removeAfter = router?.afterEach(() => {
  4995. inTransition = false;
  4996. });
  4997. });
  4998. onScopeDispose(() => {
  4999. window.removeEventListener('popstate', onPopstate);
  5000. removeBefore?.();
  5001. removeAfter?.();
  5002. });
  5003. }
  5004. function onPopstate(e) {
  5005. if (e.state?.replaced) return;
  5006. popped = true;
  5007. setTimeout(() => popped = false);
  5008. }
  5009. }
  5010. // Utilities
  5011. // Types
  5012. function useSelectLink(link, select) {
  5013. watch(() => link.isActive?.value, isActive => {
  5014. if (link.isLink.value && isActive && select) {
  5015. nextTick(() => {
  5016. select(true);
  5017. });
  5018. }
  5019. }, {
  5020. immediate: true
  5021. });
  5022. }
  5023. // Styles
  5024. // Types
  5025. const stopSymbol = Symbol('rippleStop');
  5026. const DELAY_RIPPLE = 80;
  5027. function transform(el, value) {
  5028. el.style.transform = value;
  5029. el.style.webkitTransform = value;
  5030. }
  5031. function isTouchEvent(e) {
  5032. return e.constructor.name === 'TouchEvent';
  5033. }
  5034. function isKeyboardEvent(e) {
  5035. return e.constructor.name === 'KeyboardEvent';
  5036. }
  5037. const calculate = function (e, el) {
  5038. let value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  5039. let localX = 0;
  5040. let localY = 0;
  5041. if (!isKeyboardEvent(e)) {
  5042. const offset = el.getBoundingClientRect();
  5043. const target = isTouchEvent(e) ? e.touches[e.touches.length - 1] : e;
  5044. localX = target.clientX - offset.left;
  5045. localY = target.clientY - offset.top;
  5046. }
  5047. let radius = 0;
  5048. let scale = 0.3;
  5049. if (el._ripple?.circle) {
  5050. scale = 0.15;
  5051. radius = el.clientWidth / 2;
  5052. radius = value.center ? radius : radius + Math.sqrt((localX - radius) ** 2 + (localY - radius) ** 2) / 4;
  5053. } else {
  5054. radius = Math.sqrt(el.clientWidth ** 2 + el.clientHeight ** 2) / 2;
  5055. }
  5056. const centerX = `${(el.clientWidth - radius * 2) / 2}px`;
  5057. const centerY = `${(el.clientHeight - radius * 2) / 2}px`;
  5058. const x = value.center ? centerX : `${localX - radius}px`;
  5059. const y = value.center ? centerY : `${localY - radius}px`;
  5060. return {
  5061. radius,
  5062. scale,
  5063. x,
  5064. y,
  5065. centerX,
  5066. centerY
  5067. };
  5068. };
  5069. const ripples = {
  5070. /* eslint-disable max-statements */
  5071. show(e, el) {
  5072. let value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
  5073. if (!el?._ripple?.enabled) {
  5074. return;
  5075. }
  5076. const container = document.createElement('span');
  5077. const animation = document.createElement('span');
  5078. container.appendChild(animation);
  5079. container.className = 'v-ripple__container';
  5080. if (value.class) {
  5081. container.className += ` ${value.class}`;
  5082. }
  5083. const {
  5084. radius,
  5085. scale,
  5086. x,
  5087. y,
  5088. centerX,
  5089. centerY
  5090. } = calculate(e, el, value);
  5091. const size = `${radius * 2}px`;
  5092. animation.className = 'v-ripple__animation';
  5093. animation.style.width = size;
  5094. animation.style.height = size;
  5095. el.appendChild(container);
  5096. const computed = window.getComputedStyle(el);
  5097. if (computed && computed.position === 'static') {
  5098. el.style.position = 'relative';
  5099. el.dataset.previousPosition = 'static';
  5100. }
  5101. animation.classList.add('v-ripple__animation--enter');
  5102. animation.classList.add('v-ripple__animation--visible');
  5103. transform(animation, `translate(${x}, ${y}) scale3d(${scale},${scale},${scale})`);
  5104. animation.dataset.activated = String(performance.now());
  5105. setTimeout(() => {
  5106. animation.classList.remove('v-ripple__animation--enter');
  5107. animation.classList.add('v-ripple__animation--in');
  5108. transform(animation, `translate(${centerX}, ${centerY}) scale3d(1,1,1)`);
  5109. }, 0);
  5110. },
  5111. hide(el) {
  5112. if (!el?._ripple?.enabled) return;
  5113. const ripples = el.getElementsByClassName('v-ripple__animation');
  5114. if (ripples.length === 0) return;
  5115. const animation = ripples[ripples.length - 1];
  5116. if (animation.dataset.isHiding) return;else animation.dataset.isHiding = 'true';
  5117. const diff = performance.now() - Number(animation.dataset.activated);
  5118. const delay = Math.max(250 - diff, 0);
  5119. setTimeout(() => {
  5120. animation.classList.remove('v-ripple__animation--in');
  5121. animation.classList.add('v-ripple__animation--out');
  5122. setTimeout(() => {
  5123. const ripples = el.getElementsByClassName('v-ripple__animation');
  5124. if (ripples.length === 1 && el.dataset.previousPosition) {
  5125. el.style.position = el.dataset.previousPosition;
  5126. delete el.dataset.previousPosition;
  5127. }
  5128. if (animation.parentNode?.parentNode === el) el.removeChild(animation.parentNode);
  5129. }, 300);
  5130. }, delay);
  5131. }
  5132. };
  5133. function isRippleEnabled(value) {
  5134. return typeof value === 'undefined' || !!value;
  5135. }
  5136. function rippleShow(e) {
  5137. const value = {};
  5138. const element = e.currentTarget;
  5139. if (!element?._ripple || element._ripple.touched || e[stopSymbol]) return;
  5140. // Don't allow the event to trigger ripples on any other elements
  5141. e[stopSymbol] = true;
  5142. if (isTouchEvent(e)) {
  5143. element._ripple.touched = true;
  5144. element._ripple.isTouch = true;
  5145. } else {
  5146. // It's possible for touch events to fire
  5147. // as mouse events on Android/iOS, this
  5148. // will skip the event call if it has
  5149. // already been registered as touch
  5150. if (element._ripple.isTouch) return;
  5151. }
  5152. value.center = element._ripple.centered || isKeyboardEvent(e);
  5153. if (element._ripple.class) {
  5154. value.class = element._ripple.class;
  5155. }
  5156. if (isTouchEvent(e)) {
  5157. // already queued that shows or hides the ripple
  5158. if (element._ripple.showTimerCommit) return;
  5159. element._ripple.showTimerCommit = () => {
  5160. ripples.show(e, element, value);
  5161. };
  5162. element._ripple.showTimer = window.setTimeout(() => {
  5163. if (element?._ripple?.showTimerCommit) {
  5164. element._ripple.showTimerCommit();
  5165. element._ripple.showTimerCommit = null;
  5166. }
  5167. }, DELAY_RIPPLE);
  5168. } else {
  5169. ripples.show(e, element, value);
  5170. }
  5171. }
  5172. function rippleStop(e) {
  5173. e[stopSymbol] = true;
  5174. }
  5175. function rippleHide(e) {
  5176. const element = e.currentTarget;
  5177. if (!element?._ripple) return;
  5178. window.clearTimeout(element._ripple.showTimer);
  5179. // The touch interaction occurs before the show timer is triggered.
  5180. // We still want to show ripple effect.
  5181. if (e.type === 'touchend' && element._ripple.showTimerCommit) {
  5182. element._ripple.showTimerCommit();
  5183. element._ripple.showTimerCommit = null;
  5184. // re-queue ripple hiding
  5185. element._ripple.showTimer = window.setTimeout(() => {
  5186. rippleHide(e);
  5187. });
  5188. return;
  5189. }
  5190. window.setTimeout(() => {
  5191. if (element._ripple) {
  5192. element._ripple.touched = false;
  5193. }
  5194. });
  5195. ripples.hide(element);
  5196. }
  5197. function rippleCancelShow(e) {
  5198. const element = e.currentTarget;
  5199. if (!element?._ripple) return;
  5200. if (element._ripple.showTimerCommit) {
  5201. element._ripple.showTimerCommit = null;
  5202. }
  5203. window.clearTimeout(element._ripple.showTimer);
  5204. }
  5205. let keyboardRipple = false;
  5206. function keyboardRippleShow(e) {
  5207. if (!keyboardRipple && (e.keyCode === keyCodes.enter || e.keyCode === keyCodes.space)) {
  5208. keyboardRipple = true;
  5209. rippleShow(e);
  5210. }
  5211. }
  5212. function keyboardRippleHide(e) {
  5213. keyboardRipple = false;
  5214. rippleHide(e);
  5215. }
  5216. function focusRippleHide(e) {
  5217. if (keyboardRipple) {
  5218. keyboardRipple = false;
  5219. rippleHide(e);
  5220. }
  5221. }
  5222. function updateRipple(el, binding, wasEnabled) {
  5223. const {
  5224. value,
  5225. modifiers
  5226. } = binding;
  5227. const enabled = isRippleEnabled(value);
  5228. if (!enabled) {
  5229. ripples.hide(el);
  5230. }
  5231. el._ripple = el._ripple ?? {};
  5232. el._ripple.enabled = enabled;
  5233. el._ripple.centered = modifiers.center;
  5234. el._ripple.circle = modifiers.circle;
  5235. if (isObject(value) && value.class) {
  5236. el._ripple.class = value.class;
  5237. }
  5238. if (enabled && !wasEnabled) {
  5239. if (modifiers.stop) {
  5240. el.addEventListener('touchstart', rippleStop, {
  5241. passive: true
  5242. });
  5243. el.addEventListener('mousedown', rippleStop);
  5244. return;
  5245. }
  5246. el.addEventListener('touchstart', rippleShow, {
  5247. passive: true
  5248. });
  5249. el.addEventListener('touchend', rippleHide, {
  5250. passive: true
  5251. });
  5252. el.addEventListener('touchmove', rippleCancelShow, {
  5253. passive: true
  5254. });
  5255. el.addEventListener('touchcancel', rippleHide);
  5256. el.addEventListener('mousedown', rippleShow);
  5257. el.addEventListener('mouseup', rippleHide);
  5258. el.addEventListener('mouseleave', rippleHide);
  5259. el.addEventListener('keydown', keyboardRippleShow);
  5260. el.addEventListener('keyup', keyboardRippleHide);
  5261. el.addEventListener('blur', focusRippleHide);
  5262. // Anchor tags can be dragged, causes other hides to fail - #1537
  5263. el.addEventListener('dragstart', rippleHide, {
  5264. passive: true
  5265. });
  5266. } else if (!enabled && wasEnabled) {
  5267. removeListeners(el);
  5268. }
  5269. }
  5270. function removeListeners(el) {
  5271. el.removeEventListener('mousedown', rippleShow);
  5272. el.removeEventListener('touchstart', rippleShow);
  5273. el.removeEventListener('touchend', rippleHide);
  5274. el.removeEventListener('touchmove', rippleCancelShow);
  5275. el.removeEventListener('touchcancel', rippleHide);
  5276. el.removeEventListener('mouseup', rippleHide);
  5277. el.removeEventListener('mouseleave', rippleHide);
  5278. el.removeEventListener('keydown', keyboardRippleShow);
  5279. el.removeEventListener('keyup', keyboardRippleHide);
  5280. el.removeEventListener('dragstart', rippleHide);
  5281. el.removeEventListener('blur', focusRippleHide);
  5282. }
  5283. function mounted$4(el, binding) {
  5284. updateRipple(el, binding, false);
  5285. }
  5286. function unmounted$4(el) {
  5287. delete el._ripple;
  5288. removeListeners(el);
  5289. }
  5290. function updated$1(el, binding) {
  5291. if (binding.value === binding.oldValue) {
  5292. return;
  5293. }
  5294. const wasEnabled = isRippleEnabled(binding.oldValue);
  5295. updateRipple(el, binding, wasEnabled);
  5296. }
  5297. const Ripple = {
  5298. mounted: mounted$4,
  5299. unmounted: unmounted$4,
  5300. updated: updated$1
  5301. };
  5302. // Types
  5303. const makeVBtnProps = propsFactory({
  5304. active: {
  5305. type: Boolean,
  5306. default: undefined
  5307. },
  5308. activeColor: String,
  5309. baseColor: String,
  5310. symbol: {
  5311. type: null,
  5312. default: VBtnToggleSymbol
  5313. },
  5314. flat: Boolean,
  5315. icon: [Boolean, String, Function, Object],
  5316. prependIcon: IconValue,
  5317. appendIcon: IconValue,
  5318. block: Boolean,
  5319. readonly: Boolean,
  5320. slim: Boolean,
  5321. stacked: Boolean,
  5322. ripple: {
  5323. type: [Boolean, Object],
  5324. default: true
  5325. },
  5326. text: String,
  5327. ...makeBorderProps(),
  5328. ...makeComponentProps(),
  5329. ...makeDensityProps(),
  5330. ...makeDimensionProps(),
  5331. ...makeElevationProps(),
  5332. ...makeGroupItemProps(),
  5333. ...makeLoaderProps(),
  5334. ...makeLocationProps(),
  5335. ...makePositionProps(),
  5336. ...makeRoundedProps(),
  5337. ...makeRouterProps(),
  5338. ...makeSizeProps(),
  5339. ...makeTagProps({
  5340. tag: 'button'
  5341. }),
  5342. ...makeThemeProps(),
  5343. ...makeVariantProps({
  5344. variant: 'elevated'
  5345. })
  5346. }, 'VBtn');
  5347. const VBtn = genericComponent()({
  5348. name: 'VBtn',
  5349. props: makeVBtnProps(),
  5350. emits: {
  5351. 'group:selected': val => true
  5352. },
  5353. setup(props, _ref) {
  5354. let {
  5355. attrs,
  5356. slots
  5357. } = _ref;
  5358. const {
  5359. themeClasses
  5360. } = provideTheme(props);
  5361. const {
  5362. borderClasses
  5363. } = useBorder(props);
  5364. const {
  5365. densityClasses
  5366. } = useDensity(props);
  5367. const {
  5368. dimensionStyles
  5369. } = useDimension(props);
  5370. const {
  5371. elevationClasses
  5372. } = useElevation(props);
  5373. const {
  5374. loaderClasses
  5375. } = useLoader(props);
  5376. const {
  5377. locationStyles
  5378. } = useLocation(props);
  5379. const {
  5380. positionClasses
  5381. } = usePosition(props);
  5382. const {
  5383. roundedClasses
  5384. } = useRounded(props);
  5385. const {
  5386. sizeClasses,
  5387. sizeStyles
  5388. } = useSize(props);
  5389. const group = useGroupItem(props, props.symbol, false);
  5390. const link = useLink(props, attrs);
  5391. const isActive = computed(() => {
  5392. if (props.active !== undefined) {
  5393. return props.active;
  5394. }
  5395. if (link.isLink.value) {
  5396. return link.isActive?.value;
  5397. }
  5398. return group?.isSelected.value;
  5399. });
  5400. const color = computed(() => isActive.value ? props.activeColor ?? props.color : props.color);
  5401. const variantProps = computed(() => {
  5402. const showColor = group?.isSelected.value && (!link.isLink.value || link.isActive?.value) || !group || link.isActive?.value;
  5403. return {
  5404. color: showColor ? color.value ?? props.baseColor : props.baseColor,
  5405. variant: props.variant
  5406. };
  5407. });
  5408. const {
  5409. colorClasses,
  5410. colorStyles,
  5411. variantClasses
  5412. } = useVariant(variantProps);
  5413. const isDisabled = computed(() => group?.disabled.value || props.disabled);
  5414. const isElevated = computed(() => {
  5415. return props.variant === 'elevated' && !(props.disabled || props.flat || props.border);
  5416. });
  5417. const valueAttr = computed(() => {
  5418. if (props.value === undefined || typeof props.value === 'symbol') return undefined;
  5419. return Object(props.value) === props.value ? JSON.stringify(props.value, null, 0) : props.value;
  5420. });
  5421. function onClick(e) {
  5422. if (isDisabled.value || link.isLink.value && (e.metaKey || e.ctrlKey || e.shiftKey || e.button !== 0 || attrs.target === '_blank')) return;
  5423. link.navigate?.(e);
  5424. group?.toggle();
  5425. }
  5426. useSelectLink(link, group?.select);
  5427. useRender(() => {
  5428. const Tag = link.isLink.value ? 'a' : props.tag;
  5429. const hasPrepend = !!(props.prependIcon || slots.prepend);
  5430. const hasAppend = !!(props.appendIcon || slots.append);
  5431. const hasIcon = !!(props.icon && props.icon !== true);
  5432. return withDirectives(createVNode(Tag, mergeProps({
  5433. "type": Tag === 'a' ? undefined : 'button',
  5434. "class": ['v-btn', group?.selectedClass.value, {
  5435. 'v-btn--active': isActive.value,
  5436. 'v-btn--block': props.block,
  5437. 'v-btn--disabled': isDisabled.value,
  5438. 'v-btn--elevated': isElevated.value,
  5439. 'v-btn--flat': props.flat,
  5440. 'v-btn--icon': !!props.icon,
  5441. 'v-btn--loading': props.loading,
  5442. 'v-btn--readonly': props.readonly,
  5443. 'v-btn--slim': props.slim,
  5444. 'v-btn--stacked': props.stacked
  5445. }, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, loaderClasses.value, positionClasses.value, roundedClasses.value, sizeClasses.value, variantClasses.value, props.class],
  5446. "style": [colorStyles.value, dimensionStyles.value, locationStyles.value, sizeStyles.value, props.style],
  5447. "aria-busy": props.loading ? true : undefined,
  5448. "disabled": isDisabled.value || undefined,
  5449. "tabindex": props.loading || props.readonly ? -1 : undefined,
  5450. "onClick": onClick,
  5451. "value": valueAttr.value
  5452. }, link.linkProps), {
  5453. default: () => [genOverlays(true, 'v-btn'), !props.icon && hasPrepend && createVNode("span", {
  5454. "key": "prepend",
  5455. "class": "v-btn__prepend"
  5456. }, [!slots.prepend ? createVNode(VIcon, {
  5457. "key": "prepend-icon",
  5458. "icon": props.prependIcon
  5459. }, null) : createVNode(VDefaultsProvider, {
  5460. "key": "prepend-defaults",
  5461. "disabled": !props.prependIcon,
  5462. "defaults": {
  5463. VIcon: {
  5464. icon: props.prependIcon
  5465. }
  5466. }
  5467. }, slots.prepend)]), createVNode("span", {
  5468. "class": "v-btn__content",
  5469. "data-no-activator": ""
  5470. }, [!slots.default && hasIcon ? createVNode(VIcon, {
  5471. "key": "content-icon",
  5472. "icon": props.icon
  5473. }, null) : createVNode(VDefaultsProvider, {
  5474. "key": "content-defaults",
  5475. "disabled": !hasIcon,
  5476. "defaults": {
  5477. VIcon: {
  5478. icon: props.icon
  5479. }
  5480. }
  5481. }, {
  5482. default: () => [slots.default?.() ?? props.text]
  5483. })]), !props.icon && hasAppend && createVNode("span", {
  5484. "key": "append",
  5485. "class": "v-btn__append"
  5486. }, [!slots.append ? createVNode(VIcon, {
  5487. "key": "append-icon",
  5488. "icon": props.appendIcon
  5489. }, null) : createVNode(VDefaultsProvider, {
  5490. "key": "append-defaults",
  5491. "disabled": !props.appendIcon,
  5492. "defaults": {
  5493. VIcon: {
  5494. icon: props.appendIcon
  5495. }
  5496. }
  5497. }, slots.append)]), !!props.loading && createVNode("span", {
  5498. "key": "loader",
  5499. "class": "v-btn__loader"
  5500. }, [slots.loader?.() ?? createVNode(VProgressCircular, {
  5501. "color": typeof props.loading === 'boolean' ? undefined : props.loading,
  5502. "indeterminate": true,
  5503. "width": "2"
  5504. }, null)])]
  5505. }), [[Ripple, !isDisabled.value && props.ripple, '', {
  5506. center: !!props.icon
  5507. }]]);
  5508. });
  5509. return {
  5510. group
  5511. };
  5512. }
  5513. });
  5514. // Types
  5515. const makeVAppBarNavIconProps = propsFactory({
  5516. ...makeVBtnProps({
  5517. icon: '$menu',
  5518. variant: 'text'
  5519. })
  5520. }, 'VAppBarNavIcon');
  5521. const VAppBarNavIcon = genericComponent()({
  5522. name: 'VAppBarNavIcon',
  5523. props: makeVAppBarNavIconProps(),
  5524. setup(props, _ref) {
  5525. let {
  5526. slots
  5527. } = _ref;
  5528. useRender(() => createVNode(VBtn, mergeProps(props, {
  5529. "class": ['v-app-bar-nav-icon']
  5530. }), slots));
  5531. return {};
  5532. }
  5533. });
  5534. // Types
  5535. const VAppBarTitle = genericComponent()({
  5536. name: 'VAppBarTitle',
  5537. props: makeVToolbarTitleProps(),
  5538. setup(props, _ref) {
  5539. let {
  5540. slots
  5541. } = _ref;
  5542. useRender(() => createVNode(VToolbarTitle, mergeProps(props, {
  5543. "class": "v-app-bar-title"
  5544. }), slots));
  5545. return {};
  5546. }
  5547. });
  5548. // Utilities
  5549. const VAlertTitle = createSimpleFunctional('v-alert-title');
  5550. // Types
  5551. const allowedTypes = ['success', 'info', 'warning', 'error'];
  5552. const makeVAlertProps = propsFactory({
  5553. border: {
  5554. type: [Boolean, String],
  5555. validator: val => {
  5556. return typeof val === 'boolean' || ['top', 'end', 'bottom', 'start'].includes(val);
  5557. }
  5558. },
  5559. borderColor: String,
  5560. closable: Boolean,
  5561. closeIcon: {
  5562. type: IconValue,
  5563. default: '$close'
  5564. },
  5565. closeLabel: {
  5566. type: String,
  5567. default: '$vuetify.close'
  5568. },
  5569. icon: {
  5570. type: [Boolean, String, Function, Object],
  5571. default: null
  5572. },
  5573. modelValue: {
  5574. type: Boolean,
  5575. default: true
  5576. },
  5577. prominent: Boolean,
  5578. title: String,
  5579. text: String,
  5580. type: {
  5581. type: String,
  5582. validator: val => allowedTypes.includes(val)
  5583. },
  5584. ...makeComponentProps(),
  5585. ...makeDensityProps(),
  5586. ...makeDimensionProps(),
  5587. ...makeElevationProps(),
  5588. ...makeLocationProps(),
  5589. ...makePositionProps(),
  5590. ...makeRoundedProps(),
  5591. ...makeTagProps(),
  5592. ...makeThemeProps(),
  5593. ...makeVariantProps({
  5594. variant: 'flat'
  5595. })
  5596. }, 'VAlert');
  5597. const VAlert = genericComponent()({
  5598. name: 'VAlert',
  5599. props: makeVAlertProps(),
  5600. emits: {
  5601. 'click:close': e => true,
  5602. 'update:modelValue': value => true
  5603. },
  5604. setup(props, _ref) {
  5605. let {
  5606. emit,
  5607. slots
  5608. } = _ref;
  5609. const isActive = useProxiedModel(props, 'modelValue');
  5610. const icon = computed(() => {
  5611. if (props.icon === false) return undefined;
  5612. if (!props.type) return props.icon;
  5613. return props.icon ?? `$${props.type}`;
  5614. });
  5615. const variantProps = computed(() => ({
  5616. color: props.color ?? props.type,
  5617. variant: props.variant
  5618. }));
  5619. const {
  5620. themeClasses
  5621. } = provideTheme(props);
  5622. const {
  5623. colorClasses,
  5624. colorStyles,
  5625. variantClasses
  5626. } = useVariant(variantProps);
  5627. const {
  5628. densityClasses
  5629. } = useDensity(props);
  5630. const {
  5631. dimensionStyles
  5632. } = useDimension(props);
  5633. const {
  5634. elevationClasses
  5635. } = useElevation(props);
  5636. const {
  5637. locationStyles
  5638. } = useLocation(props);
  5639. const {
  5640. positionClasses
  5641. } = usePosition(props);
  5642. const {
  5643. roundedClasses
  5644. } = useRounded(props);
  5645. const {
  5646. textColorClasses,
  5647. textColorStyles
  5648. } = useTextColor(toRef(props, 'borderColor'));
  5649. const {
  5650. t
  5651. } = useLocale();
  5652. const closeProps = computed(() => ({
  5653. 'aria-label': t(props.closeLabel),
  5654. onClick(e) {
  5655. isActive.value = false;
  5656. emit('click:close', e);
  5657. }
  5658. }));
  5659. return () => {
  5660. const hasPrepend = !!(slots.prepend || icon.value);
  5661. const hasTitle = !!(slots.title || props.title);
  5662. const hasClose = !!(slots.close || props.closable);
  5663. return isActive.value && createVNode(props.tag, {
  5664. "class": ['v-alert', props.border && {
  5665. 'v-alert--border': !!props.border,
  5666. [`v-alert--border-${props.border === true ? 'start' : props.border}`]: true
  5667. }, {
  5668. 'v-alert--prominent': props.prominent
  5669. }, themeClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, positionClasses.value, roundedClasses.value, variantClasses.value, props.class],
  5670. "style": [colorStyles.value, dimensionStyles.value, locationStyles.value, props.style],
  5671. "role": "alert"
  5672. }, {
  5673. default: () => [genOverlays(false, 'v-alert'), props.border && createVNode("div", {
  5674. "key": "border",
  5675. "class": ['v-alert__border', textColorClasses.value],
  5676. "style": textColorStyles.value
  5677. }, null), hasPrepend && createVNode("div", {
  5678. "key": "prepend",
  5679. "class": "v-alert__prepend"
  5680. }, [!slots.prepend ? createVNode(VIcon, {
  5681. "key": "prepend-icon",
  5682. "density": props.density,
  5683. "icon": icon.value,
  5684. "size": props.prominent ? 44 : 28
  5685. }, null) : createVNode(VDefaultsProvider, {
  5686. "key": "prepend-defaults",
  5687. "disabled": !icon.value,
  5688. "defaults": {
  5689. VIcon: {
  5690. density: props.density,
  5691. icon: icon.value,
  5692. size: props.prominent ? 44 : 28
  5693. }
  5694. }
  5695. }, slots.prepend)]), createVNode("div", {
  5696. "class": "v-alert__content"
  5697. }, [hasTitle && createVNode(VAlertTitle, {
  5698. "key": "title"
  5699. }, {
  5700. default: () => [slots.title?.() ?? props.title]
  5701. }), slots.text?.() ?? props.text, slots.default?.()]), slots.append && createVNode("div", {
  5702. "key": "append",
  5703. "class": "v-alert__append"
  5704. }, [slots.append()]), hasClose && createVNode("div", {
  5705. "key": "close",
  5706. "class": "v-alert__close"
  5707. }, [!slots.close ? createVNode(VBtn, mergeProps({
  5708. "key": "close-btn",
  5709. "icon": props.closeIcon,
  5710. "size": "x-small",
  5711. "variant": "text"
  5712. }, closeProps.value), null) : createVNode(VDefaultsProvider, {
  5713. "key": "close-defaults",
  5714. "defaults": {
  5715. VBtn: {
  5716. icon: props.closeIcon,
  5717. size: 'x-small',
  5718. variant: 'text'
  5719. }
  5720. }
  5721. }, {
  5722. default: () => [slots.close?.({
  5723. props: closeProps.value
  5724. })]
  5725. })])]
  5726. });
  5727. };
  5728. }
  5729. });
  5730. const makeVAvatarProps = propsFactory({
  5731. start: Boolean,
  5732. end: Boolean,
  5733. icon: IconValue,
  5734. image: String,
  5735. text: String,
  5736. ...makeBorderProps(),
  5737. ...makeComponentProps(),
  5738. ...makeDensityProps(),
  5739. ...makeRoundedProps(),
  5740. ...makeSizeProps(),
  5741. ...makeTagProps(),
  5742. ...makeThemeProps(),
  5743. ...makeVariantProps({
  5744. variant: 'flat'
  5745. })
  5746. }, 'VAvatar');
  5747. const VAvatar = genericComponent()({
  5748. name: 'VAvatar',
  5749. props: makeVAvatarProps(),
  5750. setup(props, _ref) {
  5751. let {
  5752. slots
  5753. } = _ref;
  5754. const {
  5755. themeClasses
  5756. } = provideTheme(props);
  5757. const {
  5758. borderClasses
  5759. } = useBorder(props);
  5760. const {
  5761. colorClasses,
  5762. colorStyles,
  5763. variantClasses
  5764. } = useVariant(props);
  5765. const {
  5766. densityClasses
  5767. } = useDensity(props);
  5768. const {
  5769. roundedClasses
  5770. } = useRounded(props);
  5771. const {
  5772. sizeClasses,
  5773. sizeStyles
  5774. } = useSize(props);
  5775. useRender(() => createVNode(props.tag, {
  5776. "class": ['v-avatar', {
  5777. 'v-avatar--start': props.start,
  5778. 'v-avatar--end': props.end
  5779. }, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, roundedClasses.value, sizeClasses.value, variantClasses.value, props.class],
  5780. "style": [colorStyles.value, sizeStyles.value, props.style]
  5781. }, {
  5782. default: () => [!slots.default ? props.image ? createVNode(VImg, {
  5783. "key": "image",
  5784. "src": props.image,
  5785. "alt": "",
  5786. "cover": true
  5787. }, null) : props.icon ? createVNode(VIcon, {
  5788. "key": "icon",
  5789. "icon": props.icon
  5790. }, null) : props.text : createVNode(VDefaultsProvider, {
  5791. "key": "content-defaults",
  5792. "defaults": {
  5793. VImg: {
  5794. cover: true,
  5795. src: props.image
  5796. },
  5797. VIcon: {
  5798. icon: props.icon
  5799. }
  5800. }
  5801. }, {
  5802. default: () => [slots.default()]
  5803. }), genOverlays(false, 'v-avatar')]
  5804. }));
  5805. return {};
  5806. }
  5807. });
  5808. const makeVLabelProps = propsFactory({
  5809. text: String,
  5810. onClick: EventProp(),
  5811. ...makeComponentProps(),
  5812. ...makeThemeProps()
  5813. }, 'VLabel');
  5814. const VLabel = genericComponent()({
  5815. name: 'VLabel',
  5816. props: makeVLabelProps(),
  5817. setup(props, _ref) {
  5818. let {
  5819. slots
  5820. } = _ref;
  5821. useRender(() => createVNode("label", {
  5822. "class": ['v-label', {
  5823. 'v-label--clickable': !!props.onClick
  5824. }, props.class],
  5825. "style": props.style,
  5826. "onClick": props.onClick
  5827. }, [props.text, slots.default?.()]));
  5828. return {};
  5829. }
  5830. });
  5831. // Types
  5832. const VSelectionControlGroupSymbol = Symbol.for('vuetify:selection-control-group');
  5833. const makeSelectionControlGroupProps = propsFactory({
  5834. color: String,
  5835. disabled: {
  5836. type: Boolean,
  5837. default: null
  5838. },
  5839. defaultsTarget: String,
  5840. error: Boolean,
  5841. id: String,
  5842. inline: Boolean,
  5843. falseIcon: IconValue,
  5844. trueIcon: IconValue,
  5845. ripple: {
  5846. type: [Boolean, Object],
  5847. default: true
  5848. },
  5849. multiple: {
  5850. type: Boolean,
  5851. default: null
  5852. },
  5853. name: String,
  5854. readonly: {
  5855. type: Boolean,
  5856. default: null
  5857. },
  5858. modelValue: null,
  5859. type: String,
  5860. valueComparator: {
  5861. type: Function,
  5862. default: deepEqual
  5863. },
  5864. ...makeComponentProps(),
  5865. ...makeDensityProps(),
  5866. ...makeThemeProps()
  5867. }, 'SelectionControlGroup');
  5868. const makeVSelectionControlGroupProps = propsFactory({
  5869. ...makeSelectionControlGroupProps({
  5870. defaultsTarget: 'VSelectionControl'
  5871. })
  5872. }, 'VSelectionControlGroup');
  5873. const VSelectionControlGroup = genericComponent()({
  5874. name: 'VSelectionControlGroup',
  5875. props: makeVSelectionControlGroupProps(),
  5876. emits: {
  5877. 'update:modelValue': value => true
  5878. },
  5879. setup(props, _ref) {
  5880. let {
  5881. slots
  5882. } = _ref;
  5883. const modelValue = useProxiedModel(props, 'modelValue');
  5884. const uid = getUid();
  5885. const id = computed(() => props.id || `v-selection-control-group-${uid}`);
  5886. const name = computed(() => props.name || id.value);
  5887. const updateHandlers = new Set();
  5888. provide(VSelectionControlGroupSymbol, {
  5889. modelValue,
  5890. forceUpdate: () => {
  5891. updateHandlers.forEach(fn => fn());
  5892. },
  5893. onForceUpdate: cb => {
  5894. updateHandlers.add(cb);
  5895. onScopeDispose(() => {
  5896. updateHandlers.delete(cb);
  5897. });
  5898. }
  5899. });
  5900. provideDefaults({
  5901. [props.defaultsTarget]: {
  5902. color: toRef(props, 'color'),
  5903. disabled: toRef(props, 'disabled'),
  5904. density: toRef(props, 'density'),
  5905. error: toRef(props, 'error'),
  5906. inline: toRef(props, 'inline'),
  5907. modelValue,
  5908. multiple: computed(() => !!props.multiple || props.multiple == null && Array.isArray(modelValue.value)),
  5909. name,
  5910. falseIcon: toRef(props, 'falseIcon'),
  5911. trueIcon: toRef(props, 'trueIcon'),
  5912. readonly: toRef(props, 'readonly'),
  5913. ripple: toRef(props, 'ripple'),
  5914. type: toRef(props, 'type'),
  5915. valueComparator: toRef(props, 'valueComparator')
  5916. }
  5917. });
  5918. useRender(() => createVNode("div", {
  5919. "class": ['v-selection-control-group', {
  5920. 'v-selection-control-group--inline': props.inline
  5921. }, props.class],
  5922. "style": props.style,
  5923. "role": props.type === 'radio' ? 'radiogroup' : undefined
  5924. }, [slots.default?.()]));
  5925. return {};
  5926. }
  5927. });
  5928. // Types
  5929. const makeVSelectionControlProps = propsFactory({
  5930. label: String,
  5931. baseColor: String,
  5932. trueValue: null,
  5933. falseValue: null,
  5934. value: null,
  5935. ...makeComponentProps(),
  5936. ...makeSelectionControlGroupProps()
  5937. }, 'VSelectionControl');
  5938. function useSelectionControl(props) {
  5939. const group = inject$1(VSelectionControlGroupSymbol, undefined);
  5940. const {
  5941. densityClasses
  5942. } = useDensity(props);
  5943. const modelValue = useProxiedModel(props, 'modelValue');
  5944. const trueValue = computed(() => props.trueValue !== undefined ? props.trueValue : props.value !== undefined ? props.value : true);
  5945. const falseValue = computed(() => props.falseValue !== undefined ? props.falseValue : false);
  5946. const isMultiple = computed(() => !!props.multiple || props.multiple == null && Array.isArray(modelValue.value));
  5947. const model = computed({
  5948. get() {
  5949. const val = group ? group.modelValue.value : modelValue.value;
  5950. return isMultiple.value ? wrapInArray(val).some(v => props.valueComparator(v, trueValue.value)) : props.valueComparator(val, trueValue.value);
  5951. },
  5952. set(val) {
  5953. if (props.readonly) return;
  5954. const currentValue = val ? trueValue.value : falseValue.value;
  5955. let newVal = currentValue;
  5956. if (isMultiple.value) {
  5957. newVal = val ? [...wrapInArray(modelValue.value), currentValue] : wrapInArray(modelValue.value).filter(item => !props.valueComparator(item, trueValue.value));
  5958. }
  5959. if (group) {
  5960. group.modelValue.value = newVal;
  5961. } else {
  5962. modelValue.value = newVal;
  5963. }
  5964. }
  5965. });
  5966. const {
  5967. textColorClasses,
  5968. textColorStyles
  5969. } = useTextColor(computed(() => {
  5970. if (props.error || props.disabled) return undefined;
  5971. return model.value ? props.color : props.baseColor;
  5972. }));
  5973. const {
  5974. backgroundColorClasses,
  5975. backgroundColorStyles
  5976. } = useBackgroundColor(computed(() => {
  5977. return model.value && !props.error && !props.disabled ? props.color : props.baseColor;
  5978. }));
  5979. const icon = computed(() => model.value ? props.trueIcon : props.falseIcon);
  5980. return {
  5981. group,
  5982. densityClasses,
  5983. trueValue,
  5984. falseValue,
  5985. model,
  5986. textColorClasses,
  5987. textColorStyles,
  5988. backgroundColorClasses,
  5989. backgroundColorStyles,
  5990. icon
  5991. };
  5992. }
  5993. const VSelectionControl = genericComponent()({
  5994. name: 'VSelectionControl',
  5995. directives: {
  5996. Ripple
  5997. },
  5998. inheritAttrs: false,
  5999. props: makeVSelectionControlProps(),
  6000. emits: {
  6001. 'update:modelValue': value => true
  6002. },
  6003. setup(props, _ref) {
  6004. let {
  6005. attrs,
  6006. slots
  6007. } = _ref;
  6008. const {
  6009. group,
  6010. densityClasses,
  6011. icon,
  6012. model,
  6013. textColorClasses,
  6014. textColorStyles,
  6015. backgroundColorClasses,
  6016. backgroundColorStyles,
  6017. trueValue
  6018. } = useSelectionControl(props);
  6019. const uid = getUid();
  6020. const isFocused = shallowRef(false);
  6021. const isFocusVisible = shallowRef(false);
  6022. const input = ref();
  6023. const id = computed(() => props.id || `input-${uid}`);
  6024. const isInteractive = computed(() => !props.disabled && !props.readonly);
  6025. group?.onForceUpdate(() => {
  6026. if (input.value) {
  6027. input.value.checked = model.value;
  6028. }
  6029. });
  6030. function onFocus(e) {
  6031. if (!isInteractive.value) return;
  6032. isFocused.value = true;
  6033. if (matchesSelector(e.target, ':focus-visible') !== false) {
  6034. isFocusVisible.value = true;
  6035. }
  6036. }
  6037. function onBlur() {
  6038. isFocused.value = false;
  6039. isFocusVisible.value = false;
  6040. }
  6041. function onClickLabel(e) {
  6042. e.stopPropagation();
  6043. }
  6044. function onInput(e) {
  6045. if (!isInteractive.value) {
  6046. if (input.value) {
  6047. // model value is not updated when input is not interactive
  6048. // but the internal checked state of the input is still updated,
  6049. // so here it's value is restored
  6050. input.value.checked = model.value;
  6051. }
  6052. return;
  6053. }
  6054. if (props.readonly && group) {
  6055. nextTick(() => group.forceUpdate());
  6056. }
  6057. model.value = e.target.checked;
  6058. }
  6059. useRender(() => {
  6060. const label = slots.label ? slots.label({
  6061. label: props.label,
  6062. props: {
  6063. for: id.value
  6064. }
  6065. }) : props.label;
  6066. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  6067. const inputNode = createVNode("input", mergeProps({
  6068. "ref": input,
  6069. "checked": model.value,
  6070. "disabled": !!props.disabled,
  6071. "id": id.value,
  6072. "onBlur": onBlur,
  6073. "onFocus": onFocus,
  6074. "onInput": onInput,
  6075. "aria-disabled": !!props.disabled,
  6076. "aria-label": props.label,
  6077. "type": props.type,
  6078. "value": trueValue.value,
  6079. "name": props.name,
  6080. "aria-checked": props.type === 'checkbox' ? model.value : undefined
  6081. }, inputAttrs), null);
  6082. return createVNode("div", mergeProps({
  6083. "class": ['v-selection-control', {
  6084. 'v-selection-control--dirty': model.value,
  6085. 'v-selection-control--disabled': props.disabled,
  6086. 'v-selection-control--error': props.error,
  6087. 'v-selection-control--focused': isFocused.value,
  6088. 'v-selection-control--focus-visible': isFocusVisible.value,
  6089. 'v-selection-control--inline': props.inline
  6090. }, densityClasses.value, props.class]
  6091. }, rootAttrs, {
  6092. "style": props.style
  6093. }), [createVNode("div", {
  6094. "class": ['v-selection-control__wrapper', textColorClasses.value],
  6095. "style": textColorStyles.value
  6096. }, [slots.default?.({
  6097. backgroundColorClasses,
  6098. backgroundColorStyles
  6099. }), withDirectives(createVNode("div", {
  6100. "class": ['v-selection-control__input']
  6101. }, [slots.input?.({
  6102. model,
  6103. textColorClasses,
  6104. textColorStyles,
  6105. backgroundColorClasses,
  6106. backgroundColorStyles,
  6107. inputNode,
  6108. icon: icon.value,
  6109. props: {
  6110. onFocus,
  6111. onBlur,
  6112. id: id.value
  6113. }
  6114. }) ?? createVNode(Fragment, null, [icon.value && createVNode(VIcon, {
  6115. "key": "icon",
  6116. "icon": icon.value
  6117. }, null), inputNode])]), [[resolveDirective("ripple"), props.ripple && [!props.disabled && !props.readonly, null, ['center', 'circle']]]])]), label && createVNode(VLabel, {
  6118. "for": id.value,
  6119. "onClick": onClickLabel
  6120. }, {
  6121. default: () => [label]
  6122. })]);
  6123. });
  6124. return {
  6125. isFocused,
  6126. input
  6127. };
  6128. }
  6129. });
  6130. // Types
  6131. const makeVCheckboxBtnProps = propsFactory({
  6132. indeterminate: Boolean,
  6133. indeterminateIcon: {
  6134. type: IconValue,
  6135. default: '$checkboxIndeterminate'
  6136. },
  6137. ...makeVSelectionControlProps({
  6138. falseIcon: '$checkboxOff',
  6139. trueIcon: '$checkboxOn'
  6140. })
  6141. }, 'VCheckboxBtn');
  6142. const VCheckboxBtn = genericComponent()({
  6143. name: 'VCheckboxBtn',
  6144. props: makeVCheckboxBtnProps(),
  6145. emits: {
  6146. 'update:modelValue': value => true,
  6147. 'update:indeterminate': value => true
  6148. },
  6149. setup(props, _ref) {
  6150. let {
  6151. slots
  6152. } = _ref;
  6153. const indeterminate = useProxiedModel(props, 'indeterminate');
  6154. const model = useProxiedModel(props, 'modelValue');
  6155. function onChange(v) {
  6156. if (indeterminate.value) {
  6157. indeterminate.value = false;
  6158. }
  6159. }
  6160. const falseIcon = computed(() => {
  6161. return indeterminate.value ? props.indeterminateIcon : props.falseIcon;
  6162. });
  6163. const trueIcon = computed(() => {
  6164. return indeterminate.value ? props.indeterminateIcon : props.trueIcon;
  6165. });
  6166. useRender(() => {
  6167. const controlProps = omit(VSelectionControl.filterProps(props), ['modelValue']);
  6168. return createVNode(VSelectionControl, mergeProps(controlProps, {
  6169. "modelValue": model.value,
  6170. "onUpdate:modelValue": [$event => model.value = $event, onChange],
  6171. "class": ['v-checkbox-btn', props.class],
  6172. "style": props.style,
  6173. "type": "checkbox",
  6174. "falseIcon": falseIcon.value,
  6175. "trueIcon": trueIcon.value,
  6176. "aria-checked": indeterminate.value ? 'mixed' : undefined
  6177. }), slots);
  6178. });
  6179. return {};
  6180. }
  6181. });
  6182. // Types
  6183. function useInputIcon(props) {
  6184. const {
  6185. t
  6186. } = useLocale();
  6187. function InputIcon(_ref) {
  6188. let {
  6189. name
  6190. } = _ref;
  6191. const localeKey = {
  6192. prepend: 'prependAction',
  6193. prependInner: 'prependAction',
  6194. append: 'appendAction',
  6195. appendInner: 'appendAction',
  6196. clear: 'clear'
  6197. }[name];
  6198. const listener = props[`onClick:${name}`];
  6199. const label = listener && localeKey ? t(`$vuetify.input.${localeKey}`, props.label ?? '') : undefined;
  6200. return createVNode(VIcon, {
  6201. "icon": props[`${name}Icon`],
  6202. "aria-label": label,
  6203. "onClick": listener
  6204. }, null);
  6205. }
  6206. return {
  6207. InputIcon
  6208. };
  6209. }
  6210. // Types
  6211. const makeVMessagesProps = propsFactory({
  6212. active: Boolean,
  6213. color: String,
  6214. messages: {
  6215. type: [Array, String],
  6216. default: () => []
  6217. },
  6218. ...makeComponentProps(),
  6219. ...makeTransitionProps({
  6220. transition: {
  6221. component: VSlideYTransition,
  6222. leaveAbsolute: true,
  6223. group: true
  6224. }
  6225. })
  6226. }, 'VMessages');
  6227. const VMessages = genericComponent()({
  6228. name: 'VMessages',
  6229. props: makeVMessagesProps(),
  6230. setup(props, _ref) {
  6231. let {
  6232. slots
  6233. } = _ref;
  6234. const messages = computed(() => wrapInArray(props.messages));
  6235. const {
  6236. textColorClasses,
  6237. textColorStyles
  6238. } = useTextColor(computed(() => props.color));
  6239. useRender(() => createVNode(MaybeTransition, {
  6240. "transition": props.transition,
  6241. "tag": "div",
  6242. "class": ['v-messages', textColorClasses.value, props.class],
  6243. "style": [textColorStyles.value, props.style],
  6244. "role": "alert",
  6245. "aria-live": "polite"
  6246. }, {
  6247. default: () => [props.active && messages.value.map((message, i) => createVNode("div", {
  6248. "class": "v-messages__message",
  6249. "key": `${i}-${messages.value}`
  6250. }, [slots.message ? slots.message({
  6251. message
  6252. }) : message]))]
  6253. }));
  6254. return {};
  6255. }
  6256. });
  6257. // Composables
  6258. // Types
  6259. // Composables
  6260. const makeFocusProps = propsFactory({
  6261. focused: Boolean,
  6262. 'onUpdate:focused': EventProp()
  6263. }, 'focus');
  6264. function useFocus(props) {
  6265. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  6266. const isFocused = useProxiedModel(props, 'focused');
  6267. const focusClasses = computed(() => {
  6268. return {
  6269. [`${name}--focused`]: isFocused.value
  6270. };
  6271. });
  6272. function focus() {
  6273. isFocused.value = true;
  6274. }
  6275. function blur() {
  6276. isFocused.value = false;
  6277. }
  6278. return {
  6279. focusClasses,
  6280. isFocused,
  6281. focus,
  6282. blur
  6283. };
  6284. }
  6285. // Composables
  6286. // Types
  6287. const FormKey = Symbol.for('vuetify:form');
  6288. const makeFormProps = propsFactory({
  6289. disabled: Boolean,
  6290. fastFail: Boolean,
  6291. readonly: Boolean,
  6292. modelValue: {
  6293. type: Boolean,
  6294. default: null
  6295. },
  6296. validateOn: {
  6297. type: String,
  6298. default: 'input'
  6299. }
  6300. }, 'form');
  6301. function createForm(props) {
  6302. const model = useProxiedModel(props, 'modelValue');
  6303. const isDisabled = computed(() => props.disabled);
  6304. const isReadonly = computed(() => props.readonly);
  6305. const isValidating = shallowRef(false);
  6306. const items = ref([]);
  6307. const errors = ref([]);
  6308. async function validate() {
  6309. const results = [];
  6310. let valid = true;
  6311. errors.value = [];
  6312. isValidating.value = true;
  6313. for (const item of items.value) {
  6314. const itemErrorMessages = await item.validate();
  6315. if (itemErrorMessages.length > 0) {
  6316. valid = false;
  6317. results.push({
  6318. id: item.id,
  6319. errorMessages: itemErrorMessages
  6320. });
  6321. }
  6322. if (!valid && props.fastFail) break;
  6323. }
  6324. errors.value = results;
  6325. isValidating.value = false;
  6326. return {
  6327. valid,
  6328. errors: errors.value
  6329. };
  6330. }
  6331. function reset() {
  6332. items.value.forEach(item => item.reset());
  6333. }
  6334. function resetValidation() {
  6335. items.value.forEach(item => item.resetValidation());
  6336. }
  6337. watch(items, () => {
  6338. let valid = 0;
  6339. let invalid = 0;
  6340. const results = [];
  6341. for (const item of items.value) {
  6342. if (item.isValid === false) {
  6343. invalid++;
  6344. results.push({
  6345. id: item.id,
  6346. errorMessages: item.errorMessages
  6347. });
  6348. } else if (item.isValid === true) valid++;
  6349. }
  6350. errors.value = results;
  6351. model.value = invalid > 0 ? false : valid === items.value.length ? true : null;
  6352. }, {
  6353. deep: true,
  6354. flush: 'post'
  6355. });
  6356. provide(FormKey, {
  6357. register: _ref => {
  6358. let {
  6359. id,
  6360. vm,
  6361. validate,
  6362. reset,
  6363. resetValidation
  6364. } = _ref;
  6365. if (items.value.some(item => item.id === id)) {
  6366. consoleWarn(`Duplicate input name "${id}"`);
  6367. }
  6368. items.value.push({
  6369. id,
  6370. validate,
  6371. reset,
  6372. resetValidation,
  6373. vm: markRaw(vm),
  6374. isValid: null,
  6375. errorMessages: []
  6376. });
  6377. },
  6378. unregister: id => {
  6379. items.value = items.value.filter(item => {
  6380. return item.id !== id;
  6381. });
  6382. },
  6383. update: (id, isValid, errorMessages) => {
  6384. const found = items.value.find(item => item.id === id);
  6385. if (!found) return;
  6386. found.isValid = isValid;
  6387. found.errorMessages = errorMessages;
  6388. },
  6389. isDisabled,
  6390. isReadonly,
  6391. isValidating,
  6392. isValid: model,
  6393. items,
  6394. validateOn: toRef(props, 'validateOn')
  6395. });
  6396. return {
  6397. errors,
  6398. isDisabled,
  6399. isReadonly,
  6400. isValidating,
  6401. isValid: model,
  6402. items,
  6403. validate,
  6404. reset,
  6405. resetValidation
  6406. };
  6407. }
  6408. function useForm(props) {
  6409. const form = inject$1(FormKey, null);
  6410. return {
  6411. ...form,
  6412. isReadonly: computed(() => !!(props?.readonly ?? form?.isReadonly.value)),
  6413. isDisabled: computed(() => !!(props?.disabled ?? form?.isDisabled.value))
  6414. };
  6415. }
  6416. // Composables
  6417. // Types
  6418. const makeValidationProps = propsFactory({
  6419. disabled: {
  6420. type: Boolean,
  6421. default: null
  6422. },
  6423. error: Boolean,
  6424. errorMessages: {
  6425. type: [Array, String],
  6426. default: () => []
  6427. },
  6428. maxErrors: {
  6429. type: [Number, String],
  6430. default: 1
  6431. },
  6432. name: String,
  6433. label: String,
  6434. readonly: {
  6435. type: Boolean,
  6436. default: null
  6437. },
  6438. rules: {
  6439. type: Array,
  6440. default: () => []
  6441. },
  6442. modelValue: null,
  6443. validateOn: String,
  6444. validationValue: null,
  6445. ...makeFocusProps()
  6446. }, 'validation');
  6447. function useValidation(props) {
  6448. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  6449. let id = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getUid();
  6450. const model = useProxiedModel(props, 'modelValue');
  6451. const validationModel = computed(() => props.validationValue === undefined ? model.value : props.validationValue);
  6452. const form = useForm(props);
  6453. const internalErrorMessages = ref([]);
  6454. const isPristine = shallowRef(true);
  6455. const isDirty = computed(() => !!(wrapInArray(model.value === '' ? null : model.value).length || wrapInArray(validationModel.value === '' ? null : validationModel.value).length));
  6456. const errorMessages = computed(() => {
  6457. return props.errorMessages?.length ? wrapInArray(props.errorMessages).concat(internalErrorMessages.value).slice(0, Math.max(0, +props.maxErrors)) : internalErrorMessages.value;
  6458. });
  6459. const validateOn = computed(() => {
  6460. let value = (props.validateOn ?? form.validateOn?.value) || 'input';
  6461. if (value === 'lazy') value = 'input lazy';
  6462. if (value === 'eager') value = 'input eager';
  6463. const set = new Set(value?.split(' ') ?? []);
  6464. return {
  6465. input: set.has('input'),
  6466. blur: set.has('blur') || set.has('input') || set.has('invalid-input'),
  6467. invalidInput: set.has('invalid-input'),
  6468. lazy: set.has('lazy'),
  6469. eager: set.has('eager')
  6470. };
  6471. });
  6472. const isValid = computed(() => {
  6473. if (props.error || props.errorMessages?.length) return false;
  6474. if (!props.rules.length) return true;
  6475. if (isPristine.value) {
  6476. return internalErrorMessages.value.length || validateOn.value.lazy ? null : true;
  6477. } else {
  6478. return !internalErrorMessages.value.length;
  6479. }
  6480. });
  6481. const isValidating = shallowRef(false);
  6482. const validationClasses = computed(() => {
  6483. return {
  6484. [`${name}--error`]: isValid.value === false,
  6485. [`${name}--dirty`]: isDirty.value,
  6486. [`${name}--disabled`]: form.isDisabled.value,
  6487. [`${name}--readonly`]: form.isReadonly.value
  6488. };
  6489. });
  6490. const vm = getCurrentInstance('validation');
  6491. const uid = computed(() => props.name ?? unref(id));
  6492. onBeforeMount(() => {
  6493. form.register?.({
  6494. id: uid.value,
  6495. vm,
  6496. validate,
  6497. reset,
  6498. resetValidation
  6499. });
  6500. });
  6501. onBeforeUnmount(() => {
  6502. form.unregister?.(uid.value);
  6503. });
  6504. onMounted(async () => {
  6505. if (!validateOn.value.lazy) {
  6506. await validate(!validateOn.value.eager);
  6507. }
  6508. form.update?.(uid.value, isValid.value, errorMessages.value);
  6509. });
  6510. useToggleScope(() => validateOn.value.input || validateOn.value.invalidInput && isValid.value === false, () => {
  6511. watch(validationModel, () => {
  6512. if (validationModel.value != null) {
  6513. validate();
  6514. } else if (props.focused) {
  6515. const unwatch = watch(() => props.focused, val => {
  6516. if (!val) validate();
  6517. unwatch();
  6518. });
  6519. }
  6520. });
  6521. });
  6522. useToggleScope(() => validateOn.value.blur, () => {
  6523. watch(() => props.focused, val => {
  6524. if (!val) validate();
  6525. });
  6526. });
  6527. watch([isValid, errorMessages], () => {
  6528. form.update?.(uid.value, isValid.value, errorMessages.value);
  6529. });
  6530. async function reset() {
  6531. model.value = null;
  6532. await nextTick();
  6533. await resetValidation();
  6534. }
  6535. async function resetValidation() {
  6536. isPristine.value = true;
  6537. if (!validateOn.value.lazy) {
  6538. await validate(!validateOn.value.eager);
  6539. } else {
  6540. internalErrorMessages.value = [];
  6541. }
  6542. }
  6543. async function validate() {
  6544. let silent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
  6545. const results = [];
  6546. isValidating.value = true;
  6547. for (const rule of props.rules) {
  6548. if (results.length >= +(props.maxErrors ?? 1)) {
  6549. break;
  6550. }
  6551. const handler = typeof rule === 'function' ? rule : () => rule;
  6552. const result = await handler(validationModel.value);
  6553. if (result === true) continue;
  6554. if (result !== false && typeof result !== 'string') {
  6555. // eslint-disable-next-line no-console
  6556. console.warn(`${result} is not a valid value. Rule functions must return boolean true or a string.`);
  6557. continue;
  6558. }
  6559. results.push(result || '');
  6560. }
  6561. internalErrorMessages.value = results;
  6562. isValidating.value = false;
  6563. isPristine.value = silent;
  6564. return internalErrorMessages.value;
  6565. }
  6566. return {
  6567. errorMessages,
  6568. isDirty,
  6569. isDisabled: form.isDisabled,
  6570. isReadonly: form.isReadonly,
  6571. isPristine,
  6572. isValid,
  6573. isValidating,
  6574. reset,
  6575. resetValidation,
  6576. validate,
  6577. validationClasses
  6578. };
  6579. }
  6580. // Types
  6581. const makeVInputProps = propsFactory({
  6582. id: String,
  6583. appendIcon: IconValue,
  6584. centerAffix: {
  6585. type: Boolean,
  6586. default: true
  6587. },
  6588. prependIcon: IconValue,
  6589. hideDetails: [Boolean, String],
  6590. hideSpinButtons: Boolean,
  6591. hint: String,
  6592. persistentHint: Boolean,
  6593. messages: {
  6594. type: [Array, String],
  6595. default: () => []
  6596. },
  6597. direction: {
  6598. type: String,
  6599. default: 'horizontal',
  6600. validator: v => ['horizontal', 'vertical'].includes(v)
  6601. },
  6602. 'onClick:prepend': EventProp(),
  6603. 'onClick:append': EventProp(),
  6604. ...makeComponentProps(),
  6605. ...makeDensityProps(),
  6606. ...only(makeDimensionProps(), ['maxWidth', 'minWidth', 'width']),
  6607. ...makeThemeProps(),
  6608. ...makeValidationProps()
  6609. }, 'VInput');
  6610. const VInput = genericComponent()({
  6611. name: 'VInput',
  6612. props: {
  6613. ...makeVInputProps()
  6614. },
  6615. emits: {
  6616. 'update:modelValue': value => true
  6617. },
  6618. setup(props, _ref) {
  6619. let {
  6620. attrs,
  6621. slots,
  6622. emit
  6623. } = _ref;
  6624. const {
  6625. densityClasses
  6626. } = useDensity(props);
  6627. const {
  6628. dimensionStyles
  6629. } = useDimension(props);
  6630. const {
  6631. themeClasses
  6632. } = provideTheme(props);
  6633. const {
  6634. rtlClasses
  6635. } = useRtl();
  6636. const {
  6637. InputIcon
  6638. } = useInputIcon(props);
  6639. const uid = getUid();
  6640. const id = computed(() => props.id || `input-${uid}`);
  6641. const messagesId = computed(() => `${id.value}-messages`);
  6642. const {
  6643. errorMessages,
  6644. isDirty,
  6645. isDisabled,
  6646. isReadonly,
  6647. isPristine,
  6648. isValid,
  6649. isValidating,
  6650. reset,
  6651. resetValidation,
  6652. validate,
  6653. validationClasses
  6654. } = useValidation(props, 'v-input', id);
  6655. const slotProps = computed(() => ({
  6656. id,
  6657. messagesId,
  6658. isDirty,
  6659. isDisabled,
  6660. isReadonly,
  6661. isPristine,
  6662. isValid,
  6663. isValidating,
  6664. reset,
  6665. resetValidation,
  6666. validate
  6667. }));
  6668. const messages = computed(() => {
  6669. if (props.errorMessages?.length || !isPristine.value && errorMessages.value.length) {
  6670. return errorMessages.value;
  6671. } else if (props.hint && (props.persistentHint || props.focused)) {
  6672. return props.hint;
  6673. } else {
  6674. return props.messages;
  6675. }
  6676. });
  6677. useRender(() => {
  6678. const hasPrepend = !!(slots.prepend || props.prependIcon);
  6679. const hasAppend = !!(slots.append || props.appendIcon);
  6680. const hasMessages = messages.value.length > 0;
  6681. const hasDetails = !props.hideDetails || props.hideDetails === 'auto' && (hasMessages || !!slots.details);
  6682. return createVNode("div", {
  6683. "class": ['v-input', `v-input--${props.direction}`, {
  6684. 'v-input--center-affix': props.centerAffix,
  6685. 'v-input--hide-spin-buttons': props.hideSpinButtons
  6686. }, densityClasses.value, themeClasses.value, rtlClasses.value, validationClasses.value, props.class],
  6687. "style": [dimensionStyles.value, props.style]
  6688. }, [hasPrepend && createVNode("div", {
  6689. "key": "prepend",
  6690. "class": "v-input__prepend"
  6691. }, [slots.prepend?.(slotProps.value), props.prependIcon && createVNode(InputIcon, {
  6692. "key": "prepend-icon",
  6693. "name": "prepend"
  6694. }, null)]), slots.default && createVNode("div", {
  6695. "class": "v-input__control"
  6696. }, [slots.default?.(slotProps.value)]), hasAppend && createVNode("div", {
  6697. "key": "append",
  6698. "class": "v-input__append"
  6699. }, [props.appendIcon && createVNode(InputIcon, {
  6700. "key": "append-icon",
  6701. "name": "append"
  6702. }, null), slots.append?.(slotProps.value)]), hasDetails && createVNode("div", {
  6703. "class": "v-input__details"
  6704. }, [createVNode(VMessages, {
  6705. "id": messagesId.value,
  6706. "active": hasMessages,
  6707. "messages": messages.value
  6708. }, {
  6709. message: slots.message
  6710. }), slots.details?.(slotProps.value)])]);
  6711. });
  6712. return {
  6713. reset,
  6714. resetValidation,
  6715. validate,
  6716. isValid,
  6717. errorMessages
  6718. };
  6719. }
  6720. });
  6721. // Types
  6722. const makeVCheckboxProps = propsFactory({
  6723. ...makeVInputProps(),
  6724. ...omit(makeVCheckboxBtnProps(), ['inline'])
  6725. }, 'VCheckbox');
  6726. const VCheckbox = genericComponent()({
  6727. name: 'VCheckbox',
  6728. inheritAttrs: false,
  6729. props: makeVCheckboxProps(),
  6730. emits: {
  6731. 'update:modelValue': value => true,
  6732. 'update:focused': focused => true
  6733. },
  6734. setup(props, _ref) {
  6735. let {
  6736. attrs,
  6737. slots
  6738. } = _ref;
  6739. const model = useProxiedModel(props, 'modelValue');
  6740. const {
  6741. isFocused,
  6742. focus,
  6743. blur
  6744. } = useFocus(props);
  6745. const uid = getUid();
  6746. const id = computed(() => props.id || `checkbox-${uid}`);
  6747. useRender(() => {
  6748. const [rootAttrs, controlAttrs] = filterInputAttrs(attrs);
  6749. const inputProps = VInput.filterProps(props);
  6750. const checkboxProps = VCheckboxBtn.filterProps(props);
  6751. return createVNode(VInput, mergeProps({
  6752. "class": ['v-checkbox', props.class]
  6753. }, rootAttrs, inputProps, {
  6754. "modelValue": model.value,
  6755. "onUpdate:modelValue": $event => model.value = $event,
  6756. "id": id.value,
  6757. "focused": isFocused.value,
  6758. "style": props.style
  6759. }), {
  6760. ...slots,
  6761. default: _ref2 => {
  6762. let {
  6763. id,
  6764. messagesId,
  6765. isDisabled,
  6766. isReadonly,
  6767. isValid
  6768. } = _ref2;
  6769. return createVNode(VCheckboxBtn, mergeProps(checkboxProps, {
  6770. "id": id.value,
  6771. "aria-describedby": messagesId.value,
  6772. "disabled": isDisabled.value,
  6773. "readonly": isReadonly.value
  6774. }, controlAttrs, {
  6775. "error": isValid.value === false,
  6776. "modelValue": model.value,
  6777. "onUpdate:modelValue": $event => model.value = $event,
  6778. "onFocus": focus,
  6779. "onBlur": blur
  6780. }), slots);
  6781. }
  6782. });
  6783. });
  6784. return {};
  6785. }
  6786. });
  6787. // Utilities
  6788. // Types
  6789. const breakpoints = ['sm', 'md', 'lg', 'xl', 'xxl']; // no xs
  6790. const DisplaySymbol = Symbol.for('vuetify:display');
  6791. const defaultDisplayOptions = {
  6792. mobileBreakpoint: 'lg',
  6793. thresholds: {
  6794. xs: 0,
  6795. sm: 600,
  6796. md: 960,
  6797. lg: 1280,
  6798. xl: 1920,
  6799. xxl: 2560
  6800. }
  6801. };
  6802. const parseDisplayOptions = function () {
  6803. let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultDisplayOptions;
  6804. return mergeDeep(defaultDisplayOptions, options);
  6805. };
  6806. function getClientWidth(ssr) {
  6807. return IN_BROWSER && !ssr ? window.innerWidth : typeof ssr === 'object' && ssr.clientWidth || 0;
  6808. }
  6809. function getClientHeight(ssr) {
  6810. return IN_BROWSER && !ssr ? window.innerHeight : typeof ssr === 'object' && ssr.clientHeight || 0;
  6811. }
  6812. function getPlatform(ssr) {
  6813. const userAgent = IN_BROWSER && !ssr ? window.navigator.userAgent : 'ssr';
  6814. function match(regexp) {
  6815. return Boolean(userAgent.match(regexp));
  6816. }
  6817. const android = match(/android/i);
  6818. const ios = match(/iphone|ipad|ipod/i);
  6819. const cordova = match(/cordova/i);
  6820. const electron = match(/electron/i);
  6821. const chrome = match(/chrome/i);
  6822. const edge = match(/edge/i);
  6823. const firefox = match(/firefox/i);
  6824. const opera = match(/opera/i);
  6825. const win = match(/win/i);
  6826. const mac = match(/mac/i);
  6827. const linux = match(/linux/i);
  6828. return {
  6829. android,
  6830. ios,
  6831. cordova,
  6832. electron,
  6833. chrome,
  6834. edge,
  6835. firefox,
  6836. opera,
  6837. win,
  6838. mac,
  6839. linux,
  6840. touch: SUPPORTS_TOUCH,
  6841. ssr: userAgent === 'ssr'
  6842. };
  6843. }
  6844. function createDisplay(options, ssr) {
  6845. const {
  6846. thresholds,
  6847. mobileBreakpoint
  6848. } = parseDisplayOptions(options);
  6849. const height = shallowRef(getClientHeight(ssr));
  6850. const platform = shallowRef(getPlatform(ssr));
  6851. const state = reactive({});
  6852. const width = shallowRef(getClientWidth(ssr));
  6853. function updateSize() {
  6854. height.value = getClientHeight();
  6855. width.value = getClientWidth();
  6856. }
  6857. function update() {
  6858. updateSize();
  6859. platform.value = getPlatform();
  6860. }
  6861. // eslint-disable-next-line max-statements
  6862. watchEffect(() => {
  6863. const xs = width.value < thresholds.sm;
  6864. const sm = width.value < thresholds.md && !xs;
  6865. const md = width.value < thresholds.lg && !(sm || xs);
  6866. const lg = width.value < thresholds.xl && !(md || sm || xs);
  6867. const xl = width.value < thresholds.xxl && !(lg || md || sm || xs);
  6868. const xxl = width.value >= thresholds.xxl;
  6869. const name = xs ? 'xs' : sm ? 'sm' : md ? 'md' : lg ? 'lg' : xl ? 'xl' : 'xxl';
  6870. const breakpointValue = typeof mobileBreakpoint === 'number' ? mobileBreakpoint : thresholds[mobileBreakpoint];
  6871. const mobile = width.value < breakpointValue;
  6872. state.xs = xs;
  6873. state.sm = sm;
  6874. state.md = md;
  6875. state.lg = lg;
  6876. state.xl = xl;
  6877. state.xxl = xxl;
  6878. state.smAndUp = !xs;
  6879. state.mdAndUp = !(xs || sm);
  6880. state.lgAndUp = !(xs || sm || md);
  6881. state.xlAndUp = !(xs || sm || md || lg);
  6882. state.smAndDown = !(md || lg || xl || xxl);
  6883. state.mdAndDown = !(lg || xl || xxl);
  6884. state.lgAndDown = !(xl || xxl);
  6885. state.xlAndDown = !xxl;
  6886. state.name = name;
  6887. state.height = height.value;
  6888. state.width = width.value;
  6889. state.mobile = mobile;
  6890. state.mobileBreakpoint = mobileBreakpoint;
  6891. state.platform = platform.value;
  6892. state.thresholds = thresholds;
  6893. });
  6894. if (IN_BROWSER) {
  6895. window.addEventListener('resize', updateSize, {
  6896. passive: true
  6897. });
  6898. }
  6899. return {
  6900. ...toRefs(state),
  6901. update,
  6902. ssr: !!ssr
  6903. };
  6904. }
  6905. const makeDisplayProps = propsFactory({
  6906. mobile: {
  6907. type: Boolean,
  6908. default: false
  6909. },
  6910. mobileBreakpoint: [Number, String]
  6911. }, 'display');
  6912. function useDisplay() {
  6913. let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  6914. let name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getCurrentInstanceName();
  6915. const display = inject$1(DisplaySymbol);
  6916. if (!display) throw new Error('Could not find Vuetify display injection');
  6917. const mobile = computed(() => {
  6918. if (props.mobile != null) return props.mobile;
  6919. if (!props.mobileBreakpoint) return display.mobile.value;
  6920. const breakpointValue = typeof props.mobileBreakpoint === 'number' ? props.mobileBreakpoint : display.thresholds.value[props.mobileBreakpoint];
  6921. return display.width.value < breakpointValue;
  6922. });
  6923. const displayClasses = computed(() => {
  6924. if (!name) return {};
  6925. return {
  6926. [`${name}--mobile`]: mobile.value
  6927. };
  6928. });
  6929. return {
  6930. ...display,
  6931. displayClasses,
  6932. mobile
  6933. };
  6934. }
  6935. // Utilities
  6936. // Types
  6937. const GoToSymbol = Symbol.for('vuetify:goto');
  6938. function genDefaults() {
  6939. return {
  6940. container: undefined,
  6941. duration: 300,
  6942. layout: false,
  6943. offset: 0,
  6944. easing: 'easeInOutCubic',
  6945. patterns: {
  6946. linear: t => t,
  6947. easeInQuad: t => t ** 2,
  6948. easeOutQuad: t => t * (2 - t),
  6949. easeInOutQuad: t => t < 0.5 ? 2 * t ** 2 : -1 + (4 - 2 * t) * t,
  6950. easeInCubic: t => t ** 3,
  6951. easeOutCubic: t => --t ** 3 + 1,
  6952. easeInOutCubic: t => t < 0.5 ? 4 * t ** 3 : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
  6953. easeInQuart: t => t ** 4,
  6954. easeOutQuart: t => 1 - --t ** 4,
  6955. easeInOutQuart: t => t < 0.5 ? 8 * t ** 4 : 1 - 8 * --t ** 4,
  6956. easeInQuint: t => t ** 5,
  6957. easeOutQuint: t => 1 + --t ** 5,
  6958. easeInOutQuint: t => t < 0.5 ? 16 * t ** 5 : 1 + 16 * --t ** 5
  6959. }
  6960. };
  6961. }
  6962. function getContainer(el) {
  6963. return getTarget$1(el) ?? (document.scrollingElement || document.body);
  6964. }
  6965. function getTarget$1(el) {
  6966. return typeof el === 'string' ? document.querySelector(el) : refElement(el);
  6967. }
  6968. function getOffset$2(target, horizontal, rtl) {
  6969. if (typeof target === 'number') return horizontal && rtl ? -target : target;
  6970. let el = getTarget$1(target);
  6971. let totalOffset = 0;
  6972. while (el) {
  6973. totalOffset += horizontal ? el.offsetLeft : el.offsetTop;
  6974. el = el.offsetParent;
  6975. }
  6976. return totalOffset;
  6977. }
  6978. function createGoTo(options, locale) {
  6979. return {
  6980. rtl: locale.isRtl,
  6981. options: mergeDeep(genDefaults(), options)
  6982. };
  6983. }
  6984. async function scrollTo(_target, _options, horizontal, goTo) {
  6985. const property = horizontal ? 'scrollLeft' : 'scrollTop';
  6986. const options = mergeDeep(goTo?.options ?? genDefaults(), _options);
  6987. const rtl = goTo?.rtl.value;
  6988. const target = (typeof _target === 'number' ? _target : getTarget$1(_target)) ?? 0;
  6989. const container = options.container === 'parent' && target instanceof HTMLElement ? target.parentElement : getContainer(options.container);
  6990. const ease = typeof options.easing === 'function' ? options.easing : options.patterns[options.easing];
  6991. if (!ease) throw new TypeError(`Easing function "${options.easing}" not found.`);
  6992. let targetLocation;
  6993. if (typeof target === 'number') {
  6994. targetLocation = getOffset$2(target, horizontal, rtl);
  6995. } else {
  6996. targetLocation = getOffset$2(target, horizontal, rtl) - getOffset$2(container, horizontal, rtl);
  6997. if (options.layout) {
  6998. const styles = window.getComputedStyle(target);
  6999. const layoutOffset = styles.getPropertyValue('--v-layout-top');
  7000. if (layoutOffset) targetLocation -= parseInt(layoutOffset, 10);
  7001. }
  7002. }
  7003. targetLocation += options.offset;
  7004. targetLocation = clampTarget(container, targetLocation, !!rtl, !!horizontal);
  7005. const startLocation = container[property] ?? 0;
  7006. if (targetLocation === startLocation) return Promise.resolve(targetLocation);
  7007. const startTime = performance.now();
  7008. return new Promise(resolve => requestAnimationFrame(function step(currentTime) {
  7009. const timeElapsed = currentTime - startTime;
  7010. const progress = timeElapsed / options.duration;
  7011. const location = Math.floor(startLocation + (targetLocation - startLocation) * ease(clamp(progress, 0, 1)));
  7012. container[property] = location;
  7013. // Allow for some jitter if target time has elapsed
  7014. if (progress >= 1 && Math.abs(location - container[property]) < 10) {
  7015. return resolve(targetLocation);
  7016. } else if (progress > 2) {
  7017. // The target might not be reachable
  7018. consoleWarn('Scroll target is not reachable');
  7019. return resolve(container[property]);
  7020. }
  7021. requestAnimationFrame(step);
  7022. }));
  7023. }
  7024. function useGoTo() {
  7025. let _options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  7026. const goToInstance = inject$1(GoToSymbol);
  7027. const {
  7028. isRtl
  7029. } = useRtl();
  7030. if (!goToInstance) throw new Error('[Vuetify] Could not find injected goto instance');
  7031. const goTo = {
  7032. ...goToInstance,
  7033. // can be set via VLocaleProvider
  7034. rtl: computed(() => goToInstance.rtl.value || isRtl.value)
  7035. };
  7036. async function go(target, options) {
  7037. return scrollTo(target, mergeDeep(_options, options), false, goTo);
  7038. }
  7039. go.horizontal = async (target, options) => {
  7040. return scrollTo(target, mergeDeep(_options, options), true, goTo);
  7041. };
  7042. return go;
  7043. }
  7044. /**
  7045. * Clamp target value to achieve a smooth scroll animation
  7046. * when the value goes outside the scroll container size
  7047. */
  7048. function clampTarget(container, value, rtl, horizontal) {
  7049. const {
  7050. scrollWidth,
  7051. scrollHeight
  7052. } = container;
  7053. const [containerWidth, containerHeight] = container === document.scrollingElement ? [window.innerWidth, window.innerHeight] : [container.offsetWidth, container.offsetHeight];
  7054. let min;
  7055. let max;
  7056. if (horizontal) {
  7057. if (rtl) {
  7058. min = -(scrollWidth - containerWidth);
  7059. max = 0;
  7060. } else {
  7061. min = 0;
  7062. max = scrollWidth - containerWidth;
  7063. }
  7064. } else {
  7065. min = 0;
  7066. max = scrollHeight + -containerHeight;
  7067. }
  7068. return Math.max(Math.min(value, max), min);
  7069. }
  7070. function calculateUpdatedTarget(_ref) {
  7071. let {
  7072. selectedElement,
  7073. containerElement,
  7074. isRtl,
  7075. isHorizontal
  7076. } = _ref;
  7077. const containerSize = getOffsetSize(isHorizontal, containerElement);
  7078. const scrollPosition = getScrollPosition(isHorizontal, isRtl, containerElement);
  7079. const childrenSize = getOffsetSize(isHorizontal, selectedElement);
  7080. const childrenStartPosition = getOffsetPosition(isHorizontal, selectedElement);
  7081. const additionalOffset = childrenSize * 0.4;
  7082. if (scrollPosition > childrenStartPosition) {
  7083. return childrenStartPosition - additionalOffset;
  7084. } else if (scrollPosition + containerSize < childrenStartPosition + childrenSize) {
  7085. return childrenStartPosition - containerSize + childrenSize + additionalOffset;
  7086. }
  7087. return scrollPosition;
  7088. }
  7089. function calculateCenteredTarget(_ref2) {
  7090. let {
  7091. selectedElement,
  7092. containerElement,
  7093. isHorizontal
  7094. } = _ref2;
  7095. const containerOffsetSize = getOffsetSize(isHorizontal, containerElement);
  7096. const childrenOffsetPosition = getOffsetPosition(isHorizontal, selectedElement);
  7097. const childrenOffsetSize = getOffsetSize(isHorizontal, selectedElement);
  7098. return childrenOffsetPosition - containerOffsetSize / 2 + childrenOffsetSize / 2;
  7099. }
  7100. function getScrollSize(isHorizontal, element) {
  7101. const key = isHorizontal ? 'scrollWidth' : 'scrollHeight';
  7102. return element?.[key] || 0;
  7103. }
  7104. function getClientSize(isHorizontal, element) {
  7105. const key = isHorizontal ? 'clientWidth' : 'clientHeight';
  7106. return element?.[key] || 0;
  7107. }
  7108. function getScrollPosition(isHorizontal, rtl, element) {
  7109. if (!element) {
  7110. return 0;
  7111. }
  7112. const {
  7113. scrollLeft,
  7114. offsetWidth,
  7115. scrollWidth
  7116. } = element;
  7117. if (isHorizontal) {
  7118. return rtl ? scrollWidth - offsetWidth + scrollLeft : scrollLeft;
  7119. }
  7120. return element.scrollTop;
  7121. }
  7122. function getOffsetSize(isHorizontal, element) {
  7123. const key = isHorizontal ? 'offsetWidth' : 'offsetHeight';
  7124. return element?.[key] || 0;
  7125. }
  7126. function getOffsetPosition(isHorizontal, element) {
  7127. const key = isHorizontal ? 'offsetLeft' : 'offsetTop';
  7128. return element?.[key] || 0;
  7129. }
  7130. // Types
  7131. const VSlideGroupSymbol = Symbol.for('vuetify:v-slide-group');
  7132. const makeVSlideGroupProps = propsFactory({
  7133. centerActive: Boolean,
  7134. direction: {
  7135. type: String,
  7136. default: 'horizontal'
  7137. },
  7138. symbol: {
  7139. type: null,
  7140. default: VSlideGroupSymbol
  7141. },
  7142. nextIcon: {
  7143. type: IconValue,
  7144. default: '$next'
  7145. },
  7146. prevIcon: {
  7147. type: IconValue,
  7148. default: '$prev'
  7149. },
  7150. showArrows: {
  7151. type: [Boolean, String],
  7152. validator: v => typeof v === 'boolean' || ['always', 'desktop', 'mobile'].includes(v)
  7153. },
  7154. ...makeComponentProps(),
  7155. ...makeDisplayProps({
  7156. mobile: null
  7157. }),
  7158. ...makeTagProps(),
  7159. ...makeGroupProps({
  7160. selectedClass: 'v-slide-group-item--active'
  7161. })
  7162. }, 'VSlideGroup');
  7163. const VSlideGroup = genericComponent()({
  7164. name: 'VSlideGroup',
  7165. props: makeVSlideGroupProps(),
  7166. emits: {
  7167. 'update:modelValue': value => true
  7168. },
  7169. setup(props, _ref) {
  7170. let {
  7171. slots
  7172. } = _ref;
  7173. const {
  7174. isRtl
  7175. } = useRtl();
  7176. const {
  7177. displayClasses,
  7178. mobile
  7179. } = useDisplay(props);
  7180. const group = useGroup(props, props.symbol);
  7181. const isOverflowing = shallowRef(false);
  7182. const scrollOffset = shallowRef(0);
  7183. const containerSize = shallowRef(0);
  7184. const contentSize = shallowRef(0);
  7185. const isHorizontal = computed(() => props.direction === 'horizontal');
  7186. const {
  7187. resizeRef: containerRef,
  7188. contentRect: containerRect
  7189. } = useResizeObserver();
  7190. const {
  7191. resizeRef: contentRef,
  7192. contentRect
  7193. } = useResizeObserver();
  7194. const goTo = useGoTo();
  7195. const goToOptions = computed(() => {
  7196. return {
  7197. container: containerRef.el,
  7198. duration: 200,
  7199. easing: 'easeOutQuart'
  7200. };
  7201. });
  7202. const firstSelectedIndex = computed(() => {
  7203. if (!group.selected.value.length) return -1;
  7204. return group.items.value.findIndex(item => item.id === group.selected.value[0]);
  7205. });
  7206. const lastSelectedIndex = computed(() => {
  7207. if (!group.selected.value.length) return -1;
  7208. return group.items.value.findIndex(item => item.id === group.selected.value[group.selected.value.length - 1]);
  7209. });
  7210. if (IN_BROWSER) {
  7211. let frame = -1;
  7212. watch(() => [group.selected.value, containerRect.value, contentRect.value, isHorizontal.value], () => {
  7213. cancelAnimationFrame(frame);
  7214. frame = requestAnimationFrame(() => {
  7215. if (containerRect.value && contentRect.value) {
  7216. const sizeProperty = isHorizontal.value ? 'width' : 'height';
  7217. containerSize.value = containerRect.value[sizeProperty];
  7218. contentSize.value = contentRect.value[sizeProperty];
  7219. isOverflowing.value = containerSize.value + 1 < contentSize.value;
  7220. }
  7221. if (firstSelectedIndex.value >= 0 && contentRef.el) {
  7222. // TODO: Is this too naive? Should we store element references in group composable?
  7223. const selectedElement = contentRef.el.children[lastSelectedIndex.value];
  7224. scrollToChildren(selectedElement, props.centerActive);
  7225. }
  7226. });
  7227. });
  7228. }
  7229. const isFocused = shallowRef(false);
  7230. function scrollToChildren(children, center) {
  7231. let target = 0;
  7232. if (center) {
  7233. target = calculateCenteredTarget({
  7234. containerElement: containerRef.el,
  7235. isHorizontal: isHorizontal.value,
  7236. selectedElement: children
  7237. });
  7238. } else {
  7239. target = calculateUpdatedTarget({
  7240. containerElement: containerRef.el,
  7241. isHorizontal: isHorizontal.value,
  7242. isRtl: isRtl.value,
  7243. selectedElement: children
  7244. });
  7245. }
  7246. scrollToPosition(target);
  7247. }
  7248. function scrollToPosition(newPosition) {
  7249. if (!IN_BROWSER || !containerRef.el) return;
  7250. const offsetSize = getOffsetSize(isHorizontal.value, containerRef.el);
  7251. const scrollPosition = getScrollPosition(isHorizontal.value, isRtl.value, containerRef.el);
  7252. const scrollSize = getScrollSize(isHorizontal.value, containerRef.el);
  7253. if (scrollSize <= offsetSize ||
  7254. // Prevent scrolling by only a couple of pixels, which doesn't look smooth
  7255. Math.abs(newPosition - scrollPosition) < 16) return;
  7256. if (isHorizontal.value && isRtl.value && containerRef.el) {
  7257. const {
  7258. scrollWidth,
  7259. offsetWidth: containerWidth
  7260. } = containerRef.el;
  7261. newPosition = scrollWidth - containerWidth - newPosition;
  7262. }
  7263. if (isHorizontal.value) {
  7264. goTo.horizontal(newPosition, goToOptions.value);
  7265. } else {
  7266. goTo(newPosition, goToOptions.value);
  7267. }
  7268. }
  7269. function onScroll(e) {
  7270. const {
  7271. scrollTop,
  7272. scrollLeft
  7273. } = e.target;
  7274. scrollOffset.value = isHorizontal.value ? scrollLeft : scrollTop;
  7275. }
  7276. function onFocusin(e) {
  7277. isFocused.value = true;
  7278. if (!isOverflowing.value || !contentRef.el) return;
  7279. // Focused element is likely to be the root of an item, so a
  7280. // breadth-first search will probably find it in the first iteration
  7281. for (const el of e.composedPath()) {
  7282. for (const item of contentRef.el.children) {
  7283. if (item === el) {
  7284. scrollToChildren(item);
  7285. return;
  7286. }
  7287. }
  7288. }
  7289. }
  7290. function onFocusout(e) {
  7291. isFocused.value = false;
  7292. }
  7293. // Affix clicks produce onFocus that we have to ignore to avoid extra scrollToChildren
  7294. let ignoreFocusEvent = false;
  7295. function onFocus(e) {
  7296. if (!ignoreFocusEvent && !isFocused.value && !(e.relatedTarget && contentRef.el?.contains(e.relatedTarget))) focus();
  7297. ignoreFocusEvent = false;
  7298. }
  7299. function onFocusAffixes() {
  7300. ignoreFocusEvent = true;
  7301. }
  7302. function onKeydown(e) {
  7303. if (!contentRef.el) return;
  7304. function toFocus(location) {
  7305. e.preventDefault();
  7306. focus(location);
  7307. }
  7308. if (isHorizontal.value) {
  7309. if (e.key === 'ArrowRight') {
  7310. toFocus(isRtl.value ? 'prev' : 'next');
  7311. } else if (e.key === 'ArrowLeft') {
  7312. toFocus(isRtl.value ? 'next' : 'prev');
  7313. }
  7314. } else {
  7315. if (e.key === 'ArrowDown') {
  7316. toFocus('next');
  7317. } else if (e.key === 'ArrowUp') {
  7318. toFocus('prev');
  7319. }
  7320. }
  7321. if (e.key === 'Home') {
  7322. toFocus('first');
  7323. } else if (e.key === 'End') {
  7324. toFocus('last');
  7325. }
  7326. }
  7327. function focus(location) {
  7328. if (!contentRef.el) return;
  7329. let el;
  7330. if (!location) {
  7331. const focusable = focusableChildren(contentRef.el);
  7332. el = focusable[0];
  7333. } else if (location === 'next') {
  7334. el = contentRef.el.querySelector(':focus')?.nextElementSibling;
  7335. if (!el) return focus('first');
  7336. } else if (location === 'prev') {
  7337. el = contentRef.el.querySelector(':focus')?.previousElementSibling;
  7338. if (!el) return focus('last');
  7339. } else if (location === 'first') {
  7340. el = contentRef.el.firstElementChild;
  7341. } else if (location === 'last') {
  7342. el = contentRef.el.lastElementChild;
  7343. }
  7344. if (el) {
  7345. el.focus({
  7346. preventScroll: true
  7347. });
  7348. }
  7349. }
  7350. function scrollTo(location) {
  7351. const direction = isHorizontal.value && isRtl.value ? -1 : 1;
  7352. const offsetStep = (location === 'prev' ? -direction : direction) * containerSize.value;
  7353. let newPosition = scrollOffset.value + offsetStep;
  7354. // TODO: improve it
  7355. if (isHorizontal.value && isRtl.value && containerRef.el) {
  7356. const {
  7357. scrollWidth,
  7358. offsetWidth: containerWidth
  7359. } = containerRef.el;
  7360. newPosition += scrollWidth - containerWidth;
  7361. }
  7362. scrollToPosition(newPosition);
  7363. }
  7364. const slotProps = computed(() => ({
  7365. next: group.next,
  7366. prev: group.prev,
  7367. select: group.select,
  7368. isSelected: group.isSelected
  7369. }));
  7370. const hasAffixes = computed(() => {
  7371. switch (props.showArrows) {
  7372. // Always show arrows on desktop & mobile
  7373. case 'always':
  7374. return true;
  7375. // Always show arrows on desktop
  7376. case 'desktop':
  7377. return !mobile.value;
  7378. // Show arrows on mobile when overflowing.
  7379. // This matches the default 2.2 behavior
  7380. case true:
  7381. return isOverflowing.value || Math.abs(scrollOffset.value) > 0;
  7382. // Always show on mobile
  7383. case 'mobile':
  7384. return mobile.value || isOverflowing.value || Math.abs(scrollOffset.value) > 0;
  7385. // https://material.io/components/tabs#scrollable-tabs
  7386. // Always show arrows when
  7387. // overflowed on desktop
  7388. default:
  7389. return !mobile.value && (isOverflowing.value || Math.abs(scrollOffset.value) > 0);
  7390. }
  7391. });
  7392. const hasPrev = computed(() => {
  7393. // 1 pixel in reserve, may be lost after rounding
  7394. return Math.abs(scrollOffset.value) > 1;
  7395. });
  7396. const hasNext = computed(() => {
  7397. if (!containerRef.value) return false;
  7398. const scrollSize = getScrollSize(isHorizontal.value, containerRef.el);
  7399. const clientSize = getClientSize(isHorizontal.value, containerRef.el);
  7400. const scrollSizeMax = scrollSize - clientSize;
  7401. // 1 pixel in reserve, may be lost after rounding
  7402. return scrollSizeMax - Math.abs(scrollOffset.value) > 1;
  7403. });
  7404. useRender(() => createVNode(props.tag, {
  7405. "class": ['v-slide-group', {
  7406. 'v-slide-group--vertical': !isHorizontal.value,
  7407. 'v-slide-group--has-affixes': hasAffixes.value,
  7408. 'v-slide-group--is-overflowing': isOverflowing.value
  7409. }, displayClasses.value, props.class],
  7410. "style": props.style,
  7411. "tabindex": isFocused.value || group.selected.value.length ? -1 : 0,
  7412. "onFocus": onFocus
  7413. }, {
  7414. default: () => [hasAffixes.value && createVNode("div", {
  7415. "key": "prev",
  7416. "class": ['v-slide-group__prev', {
  7417. 'v-slide-group__prev--disabled': !hasPrev.value
  7418. }],
  7419. "onMousedown": onFocusAffixes,
  7420. "onClick": () => hasPrev.value && scrollTo('prev')
  7421. }, [slots.prev?.(slotProps.value) ?? createVNode(VFadeTransition, null, {
  7422. default: () => [createVNode(VIcon, {
  7423. "icon": isRtl.value ? props.nextIcon : props.prevIcon
  7424. }, null)]
  7425. })]), createVNode("div", {
  7426. "key": "container",
  7427. "ref": containerRef,
  7428. "class": "v-slide-group__container",
  7429. "onScroll": onScroll
  7430. }, [createVNode("div", {
  7431. "ref": contentRef,
  7432. "class": "v-slide-group__content",
  7433. "onFocusin": onFocusin,
  7434. "onFocusout": onFocusout,
  7435. "onKeydown": onKeydown
  7436. }, [slots.default?.(slotProps.value)])]), hasAffixes.value && createVNode("div", {
  7437. "key": "next",
  7438. "class": ['v-slide-group__next', {
  7439. 'v-slide-group__next--disabled': !hasNext.value
  7440. }],
  7441. "onMousedown": onFocusAffixes,
  7442. "onClick": () => hasNext.value && scrollTo('next')
  7443. }, [slots.next?.(slotProps.value) ?? createVNode(VFadeTransition, null, {
  7444. default: () => [createVNode(VIcon, {
  7445. "icon": isRtl.value ? props.prevIcon : props.nextIcon
  7446. }, null)]
  7447. })])]
  7448. }));
  7449. return {
  7450. selected: group.selected,
  7451. scrollTo,
  7452. scrollOffset,
  7453. focus,
  7454. hasPrev,
  7455. hasNext
  7456. };
  7457. }
  7458. });
  7459. // Types
  7460. const VChipGroupSymbol = Symbol.for('vuetify:v-chip-group');
  7461. const makeVChipGroupProps = propsFactory({
  7462. column: Boolean,
  7463. filter: Boolean,
  7464. valueComparator: {
  7465. type: Function,
  7466. default: deepEqual
  7467. },
  7468. ...makeVSlideGroupProps(),
  7469. ...makeComponentProps(),
  7470. ...makeGroupProps({
  7471. selectedClass: 'v-chip--selected'
  7472. }),
  7473. ...makeTagProps(),
  7474. ...makeThemeProps(),
  7475. ...makeVariantProps({
  7476. variant: 'tonal'
  7477. })
  7478. }, 'VChipGroup');
  7479. const VChipGroup = genericComponent()({
  7480. name: 'VChipGroup',
  7481. props: makeVChipGroupProps(),
  7482. emits: {
  7483. 'update:modelValue': value => true
  7484. },
  7485. setup(props, _ref) {
  7486. let {
  7487. slots
  7488. } = _ref;
  7489. const {
  7490. themeClasses
  7491. } = provideTheme(props);
  7492. const {
  7493. isSelected,
  7494. select,
  7495. next,
  7496. prev,
  7497. selected
  7498. } = useGroup(props, VChipGroupSymbol);
  7499. provideDefaults({
  7500. VChip: {
  7501. color: toRef(props, 'color'),
  7502. disabled: toRef(props, 'disabled'),
  7503. filter: toRef(props, 'filter'),
  7504. variant: toRef(props, 'variant')
  7505. }
  7506. });
  7507. useRender(() => {
  7508. const slideGroupProps = VSlideGroup.filterProps(props);
  7509. return createVNode(VSlideGroup, mergeProps(slideGroupProps, {
  7510. "class": ['v-chip-group', {
  7511. 'v-chip-group--column': props.column
  7512. }, themeClasses.value, props.class],
  7513. "style": props.style
  7514. }), {
  7515. default: () => [slots.default?.({
  7516. isSelected,
  7517. select,
  7518. next,
  7519. prev,
  7520. selected: selected.value
  7521. })]
  7522. });
  7523. });
  7524. return {};
  7525. }
  7526. });
  7527. // Types
  7528. const makeVChipProps = propsFactory({
  7529. activeClass: String,
  7530. appendAvatar: String,
  7531. appendIcon: IconValue,
  7532. closable: Boolean,
  7533. closeIcon: {
  7534. type: IconValue,
  7535. default: '$delete'
  7536. },
  7537. closeLabel: {
  7538. type: String,
  7539. default: '$vuetify.close'
  7540. },
  7541. draggable: Boolean,
  7542. filter: Boolean,
  7543. filterIcon: {
  7544. type: IconValue,
  7545. default: '$complete'
  7546. },
  7547. label: Boolean,
  7548. link: {
  7549. type: Boolean,
  7550. default: undefined
  7551. },
  7552. pill: Boolean,
  7553. prependAvatar: String,
  7554. prependIcon: IconValue,
  7555. ripple: {
  7556. type: [Boolean, Object],
  7557. default: true
  7558. },
  7559. text: String,
  7560. modelValue: {
  7561. type: Boolean,
  7562. default: true
  7563. },
  7564. onClick: EventProp(),
  7565. onClickOnce: EventProp(),
  7566. ...makeBorderProps(),
  7567. ...makeComponentProps(),
  7568. ...makeDensityProps(),
  7569. ...makeElevationProps(),
  7570. ...makeGroupItemProps(),
  7571. ...makeRoundedProps(),
  7572. ...makeRouterProps(),
  7573. ...makeSizeProps(),
  7574. ...makeTagProps({
  7575. tag: 'span'
  7576. }),
  7577. ...makeThemeProps(),
  7578. ...makeVariantProps({
  7579. variant: 'tonal'
  7580. })
  7581. }, 'VChip');
  7582. const VChip = genericComponent()({
  7583. name: 'VChip',
  7584. directives: {
  7585. Ripple
  7586. },
  7587. props: makeVChipProps(),
  7588. emits: {
  7589. 'click:close': e => true,
  7590. 'update:modelValue': value => true,
  7591. 'group:selected': val => true,
  7592. click: e => true
  7593. },
  7594. setup(props, _ref) {
  7595. let {
  7596. attrs,
  7597. emit,
  7598. slots
  7599. } = _ref;
  7600. const {
  7601. t
  7602. } = useLocale();
  7603. const {
  7604. borderClasses
  7605. } = useBorder(props);
  7606. const {
  7607. colorClasses,
  7608. colorStyles,
  7609. variantClasses
  7610. } = useVariant(props);
  7611. const {
  7612. densityClasses
  7613. } = useDensity(props);
  7614. const {
  7615. elevationClasses
  7616. } = useElevation(props);
  7617. const {
  7618. roundedClasses
  7619. } = useRounded(props);
  7620. const {
  7621. sizeClasses
  7622. } = useSize(props);
  7623. const {
  7624. themeClasses
  7625. } = provideTheme(props);
  7626. const isActive = useProxiedModel(props, 'modelValue');
  7627. const group = useGroupItem(props, VChipGroupSymbol, false);
  7628. const link = useLink(props, attrs);
  7629. const isLink = computed(() => props.link !== false && link.isLink.value);
  7630. const isClickable = computed(() => !props.disabled && props.link !== false && (!!group || props.link || link.isClickable.value));
  7631. const closeProps = computed(() => ({
  7632. 'aria-label': t(props.closeLabel),
  7633. onClick(e) {
  7634. e.preventDefault();
  7635. e.stopPropagation();
  7636. isActive.value = false;
  7637. emit('click:close', e);
  7638. }
  7639. }));
  7640. function onClick(e) {
  7641. emit('click', e);
  7642. if (!isClickable.value) return;
  7643. link.navigate?.(e);
  7644. group?.toggle();
  7645. }
  7646. function onKeyDown(e) {
  7647. if (e.key === 'Enter' || e.key === ' ') {
  7648. e.preventDefault();
  7649. onClick(e);
  7650. }
  7651. }
  7652. return () => {
  7653. const Tag = link.isLink.value ? 'a' : props.tag;
  7654. const hasAppendMedia = !!(props.appendIcon || props.appendAvatar);
  7655. const hasAppend = !!(hasAppendMedia || slots.append);
  7656. const hasClose = !!(slots.close || props.closable);
  7657. const hasFilter = !!(slots.filter || props.filter) && group;
  7658. const hasPrependMedia = !!(props.prependIcon || props.prependAvatar);
  7659. const hasPrepend = !!(hasPrependMedia || slots.prepend);
  7660. const hasColor = !group || group.isSelected.value;
  7661. return isActive.value && withDirectives(createVNode(Tag, mergeProps({
  7662. "class": ['v-chip', {
  7663. 'v-chip--disabled': props.disabled,
  7664. 'v-chip--label': props.label,
  7665. 'v-chip--link': isClickable.value,
  7666. 'v-chip--filter': hasFilter,
  7667. 'v-chip--pill': props.pill,
  7668. [`${props.activeClass}`]: props.activeClass && link.isActive?.value
  7669. }, themeClasses.value, borderClasses.value, hasColor ? colorClasses.value : undefined, densityClasses.value, elevationClasses.value, roundedClasses.value, sizeClasses.value, variantClasses.value, group?.selectedClass.value, props.class],
  7670. "style": [hasColor ? colorStyles.value : undefined, props.style],
  7671. "disabled": props.disabled || undefined,
  7672. "draggable": props.draggable,
  7673. "tabindex": isClickable.value ? 0 : undefined,
  7674. "onClick": onClick,
  7675. "onKeydown": isClickable.value && !isLink.value && onKeyDown
  7676. }, link.linkProps), {
  7677. default: () => [genOverlays(isClickable.value, 'v-chip'), hasFilter && createVNode(VExpandXTransition, {
  7678. "key": "filter"
  7679. }, {
  7680. default: () => [withDirectives(createVNode("div", {
  7681. "class": "v-chip__filter"
  7682. }, [!slots.filter ? createVNode(VIcon, {
  7683. "key": "filter-icon",
  7684. "icon": props.filterIcon
  7685. }, null) : createVNode(VDefaultsProvider, {
  7686. "key": "filter-defaults",
  7687. "disabled": !props.filterIcon,
  7688. "defaults": {
  7689. VIcon: {
  7690. icon: props.filterIcon
  7691. }
  7692. }
  7693. }, slots.filter)]), [[vShow, group.isSelected.value]])]
  7694. }), hasPrepend && createVNode("div", {
  7695. "key": "prepend",
  7696. "class": "v-chip__prepend"
  7697. }, [!slots.prepend ? createVNode(Fragment, null, [props.prependIcon && createVNode(VIcon, {
  7698. "key": "prepend-icon",
  7699. "icon": props.prependIcon,
  7700. "start": true
  7701. }, null), props.prependAvatar && createVNode(VAvatar, {
  7702. "key": "prepend-avatar",
  7703. "image": props.prependAvatar,
  7704. "start": true
  7705. }, null)]) : createVNode(VDefaultsProvider, {
  7706. "key": "prepend-defaults",
  7707. "disabled": !hasPrependMedia,
  7708. "defaults": {
  7709. VAvatar: {
  7710. image: props.prependAvatar,
  7711. start: true
  7712. },
  7713. VIcon: {
  7714. icon: props.prependIcon,
  7715. start: true
  7716. }
  7717. }
  7718. }, slots.prepend)]), createVNode("div", {
  7719. "class": "v-chip__content",
  7720. "data-no-activator": ""
  7721. }, [slots.default?.({
  7722. isSelected: group?.isSelected.value,
  7723. selectedClass: group?.selectedClass.value,
  7724. select: group?.select,
  7725. toggle: group?.toggle,
  7726. value: group?.value.value,
  7727. disabled: props.disabled
  7728. }) ?? props.text]), hasAppend && createVNode("div", {
  7729. "key": "append",
  7730. "class": "v-chip__append"
  7731. }, [!slots.append ? createVNode(Fragment, null, [props.appendIcon && createVNode(VIcon, {
  7732. "key": "append-icon",
  7733. "end": true,
  7734. "icon": props.appendIcon
  7735. }, null), props.appendAvatar && createVNode(VAvatar, {
  7736. "key": "append-avatar",
  7737. "end": true,
  7738. "image": props.appendAvatar
  7739. }, null)]) : createVNode(VDefaultsProvider, {
  7740. "key": "append-defaults",
  7741. "disabled": !hasAppendMedia,
  7742. "defaults": {
  7743. VAvatar: {
  7744. end: true,
  7745. image: props.appendAvatar
  7746. },
  7747. VIcon: {
  7748. end: true,
  7749. icon: props.appendIcon
  7750. }
  7751. }
  7752. }, slots.append)]), hasClose && createVNode("button", mergeProps({
  7753. "key": "close",
  7754. "class": "v-chip__close",
  7755. "type": "button",
  7756. "data-testid": "close-chip"
  7757. }, closeProps.value), [!slots.close ? createVNode(VIcon, {
  7758. "key": "close-icon",
  7759. "icon": props.closeIcon,
  7760. "size": "x-small"
  7761. }, null) : createVNode(VDefaultsProvider, {
  7762. "key": "close-defaults",
  7763. "defaults": {
  7764. VIcon: {
  7765. icon: props.closeIcon,
  7766. size: 'x-small'
  7767. }
  7768. }
  7769. }, slots.close)])]
  7770. }), [[resolveDirective("ripple"), isClickable.value && props.ripple, null]]);
  7771. };
  7772. }
  7773. });
  7774. // Utilities
  7775. // List
  7776. const ListKey = Symbol.for('vuetify:list');
  7777. function createList() {
  7778. const parent = inject$1(ListKey, {
  7779. hasPrepend: shallowRef(false),
  7780. updateHasPrepend: () => null
  7781. });
  7782. const data = {
  7783. hasPrepend: shallowRef(false),
  7784. updateHasPrepend: value => {
  7785. if (value) data.hasPrepend.value = value;
  7786. }
  7787. };
  7788. provide(ListKey, data);
  7789. return parent;
  7790. }
  7791. function useList() {
  7792. return inject$1(ListKey, null);
  7793. }
  7794. /* eslint-disable sonarjs/no-identical-functions */
  7795. // Utilities
  7796. const independentActiveStrategy = mandatory => {
  7797. const strategy = {
  7798. activate: _ref => {
  7799. let {
  7800. id,
  7801. value,
  7802. activated
  7803. } = _ref;
  7804. id = toRaw(id);
  7805. // When mandatory and we're trying to deselect when id
  7806. // is the only currently selected item then do nothing
  7807. if (mandatory && !value && activated.size === 1 && activated.has(id)) return activated;
  7808. if (value) {
  7809. activated.add(id);
  7810. } else {
  7811. activated.delete(id);
  7812. }
  7813. return activated;
  7814. },
  7815. in: (v, children, parents) => {
  7816. let set = new Set();
  7817. if (v != null) {
  7818. for (const id of wrapInArray(v)) {
  7819. set = strategy.activate({
  7820. id,
  7821. value: true,
  7822. activated: new Set(set),
  7823. children,
  7824. parents
  7825. });
  7826. }
  7827. }
  7828. return set;
  7829. },
  7830. out: v => {
  7831. return Array.from(v);
  7832. }
  7833. };
  7834. return strategy;
  7835. };
  7836. const independentSingleActiveStrategy = mandatory => {
  7837. const parentStrategy = independentActiveStrategy(mandatory);
  7838. const strategy = {
  7839. activate: _ref2 => {
  7840. let {
  7841. activated,
  7842. id,
  7843. ...rest
  7844. } = _ref2;
  7845. id = toRaw(id);
  7846. const singleSelected = activated.has(id) ? new Set([id]) : new Set();
  7847. return parentStrategy.activate({
  7848. ...rest,
  7849. id,
  7850. activated: singleSelected
  7851. });
  7852. },
  7853. in: (v, children, parents) => {
  7854. let set = new Set();
  7855. if (v != null) {
  7856. const arr = wrapInArray(v);
  7857. if (arr.length) {
  7858. set = parentStrategy.in(arr.slice(0, 1), children, parents);
  7859. }
  7860. }
  7861. return set;
  7862. },
  7863. out: (v, children, parents) => {
  7864. return parentStrategy.out(v, children, parents);
  7865. }
  7866. };
  7867. return strategy;
  7868. };
  7869. const leafActiveStrategy = mandatory => {
  7870. const parentStrategy = independentActiveStrategy(mandatory);
  7871. const strategy = {
  7872. activate: _ref3 => {
  7873. let {
  7874. id,
  7875. activated,
  7876. children,
  7877. ...rest
  7878. } = _ref3;
  7879. id = toRaw(id);
  7880. if (children.has(id)) return activated;
  7881. return parentStrategy.activate({
  7882. id,
  7883. activated,
  7884. children,
  7885. ...rest
  7886. });
  7887. },
  7888. in: parentStrategy.in,
  7889. out: parentStrategy.out
  7890. };
  7891. return strategy;
  7892. };
  7893. const leafSingleActiveStrategy = mandatory => {
  7894. const parentStrategy = independentSingleActiveStrategy(mandatory);
  7895. const strategy = {
  7896. activate: _ref4 => {
  7897. let {
  7898. id,
  7899. activated,
  7900. children,
  7901. ...rest
  7902. } = _ref4;
  7903. id = toRaw(id);
  7904. if (children.has(id)) return activated;
  7905. return parentStrategy.activate({
  7906. id,
  7907. activated,
  7908. children,
  7909. ...rest
  7910. });
  7911. },
  7912. in: parentStrategy.in,
  7913. out: parentStrategy.out
  7914. };
  7915. return strategy;
  7916. };
  7917. const singleOpenStrategy = {
  7918. open: _ref => {
  7919. let {
  7920. id,
  7921. value,
  7922. opened,
  7923. parents
  7924. } = _ref;
  7925. if (value) {
  7926. const newOpened = new Set();
  7927. newOpened.add(id);
  7928. let parent = parents.get(id);
  7929. while (parent != null) {
  7930. newOpened.add(parent);
  7931. parent = parents.get(parent);
  7932. }
  7933. return newOpened;
  7934. } else {
  7935. opened.delete(id);
  7936. return opened;
  7937. }
  7938. },
  7939. select: () => null
  7940. };
  7941. const multipleOpenStrategy = {
  7942. open: _ref2 => {
  7943. let {
  7944. id,
  7945. value,
  7946. opened,
  7947. parents
  7948. } = _ref2;
  7949. if (value) {
  7950. let parent = parents.get(id);
  7951. opened.add(id);
  7952. while (parent != null && parent !== id) {
  7953. opened.add(parent);
  7954. parent = parents.get(parent);
  7955. }
  7956. return opened;
  7957. } else {
  7958. opened.delete(id);
  7959. }
  7960. return opened;
  7961. },
  7962. select: () => null
  7963. };
  7964. const listOpenStrategy = {
  7965. open: multipleOpenStrategy.open,
  7966. select: _ref3 => {
  7967. let {
  7968. id,
  7969. value,
  7970. opened,
  7971. parents
  7972. } = _ref3;
  7973. if (!value) return opened;
  7974. const path = [];
  7975. let parent = parents.get(id);
  7976. while (parent != null) {
  7977. path.push(parent);
  7978. parent = parents.get(parent);
  7979. }
  7980. return new Set(path);
  7981. }
  7982. };
  7983. /* eslint-disable sonarjs/no-identical-functions */
  7984. // Utilities
  7985. const independentSelectStrategy = mandatory => {
  7986. const strategy = {
  7987. select: _ref => {
  7988. let {
  7989. id,
  7990. value,
  7991. selected
  7992. } = _ref;
  7993. id = toRaw(id);
  7994. // When mandatory and we're trying to deselect when id
  7995. // is the only currently selected item then do nothing
  7996. if (mandatory && !value) {
  7997. const on = Array.from(selected.entries()).reduce((arr, _ref2) => {
  7998. let [key, value] = _ref2;
  7999. if (value === 'on') arr.push(key);
  8000. return arr;
  8001. }, []);
  8002. if (on.length === 1 && on[0] === id) return selected;
  8003. }
  8004. selected.set(id, value ? 'on' : 'off');
  8005. return selected;
  8006. },
  8007. in: (v, children, parents) => {
  8008. let map = new Map();
  8009. for (const id of v || []) {
  8010. map = strategy.select({
  8011. id,
  8012. value: true,
  8013. selected: new Map(map),
  8014. children,
  8015. parents
  8016. });
  8017. }
  8018. return map;
  8019. },
  8020. out: v => {
  8021. const arr = [];
  8022. for (const [key, value] of v.entries()) {
  8023. if (value === 'on') arr.push(key);
  8024. }
  8025. return arr;
  8026. }
  8027. };
  8028. return strategy;
  8029. };
  8030. const independentSingleSelectStrategy = mandatory => {
  8031. const parentStrategy = independentSelectStrategy(mandatory);
  8032. const strategy = {
  8033. select: _ref3 => {
  8034. let {
  8035. selected,
  8036. id,
  8037. ...rest
  8038. } = _ref3;
  8039. id = toRaw(id);
  8040. const singleSelected = selected.has(id) ? new Map([[id, selected.get(id)]]) : new Map();
  8041. return parentStrategy.select({
  8042. ...rest,
  8043. id,
  8044. selected: singleSelected
  8045. });
  8046. },
  8047. in: (v, children, parents) => {
  8048. let map = new Map();
  8049. if (v?.length) {
  8050. map = parentStrategy.in(v.slice(0, 1), children, parents);
  8051. }
  8052. return map;
  8053. },
  8054. out: (v, children, parents) => {
  8055. return parentStrategy.out(v, children, parents);
  8056. }
  8057. };
  8058. return strategy;
  8059. };
  8060. const leafSelectStrategy = mandatory => {
  8061. const parentStrategy = independentSelectStrategy(mandatory);
  8062. const strategy = {
  8063. select: _ref4 => {
  8064. let {
  8065. id,
  8066. selected,
  8067. children,
  8068. ...rest
  8069. } = _ref4;
  8070. id = toRaw(id);
  8071. if (children.has(id)) return selected;
  8072. return parentStrategy.select({
  8073. id,
  8074. selected,
  8075. children,
  8076. ...rest
  8077. });
  8078. },
  8079. in: parentStrategy.in,
  8080. out: parentStrategy.out
  8081. };
  8082. return strategy;
  8083. };
  8084. const leafSingleSelectStrategy = mandatory => {
  8085. const parentStrategy = independentSingleSelectStrategy(mandatory);
  8086. const strategy = {
  8087. select: _ref5 => {
  8088. let {
  8089. id,
  8090. selected,
  8091. children,
  8092. ...rest
  8093. } = _ref5;
  8094. id = toRaw(id);
  8095. if (children.has(id)) return selected;
  8096. return parentStrategy.select({
  8097. id,
  8098. selected,
  8099. children,
  8100. ...rest
  8101. });
  8102. },
  8103. in: parentStrategy.in,
  8104. out: parentStrategy.out
  8105. };
  8106. return strategy;
  8107. };
  8108. const classicSelectStrategy = mandatory => {
  8109. const strategy = {
  8110. select: _ref6 => {
  8111. let {
  8112. id,
  8113. value,
  8114. selected,
  8115. children,
  8116. parents
  8117. } = _ref6;
  8118. id = toRaw(id);
  8119. const original = new Map(selected);
  8120. const items = [id];
  8121. while (items.length) {
  8122. const item = items.shift();
  8123. selected.set(toRaw(item), value ? 'on' : 'off');
  8124. if (children.has(item)) {
  8125. items.push(...children.get(item));
  8126. }
  8127. }
  8128. let parent = toRaw(parents.get(id));
  8129. while (parent) {
  8130. const childrenIds = children.get(parent);
  8131. const everySelected = childrenIds.every(cid => selected.get(toRaw(cid)) === 'on');
  8132. const noneSelected = childrenIds.every(cid => !selected.has(toRaw(cid)) || selected.get(toRaw(cid)) === 'off');
  8133. selected.set(parent, everySelected ? 'on' : noneSelected ? 'off' : 'indeterminate');
  8134. parent = toRaw(parents.get(parent));
  8135. }
  8136. // If mandatory and planned deselect results in no selected
  8137. // items then we can't do it, so return original state
  8138. if (mandatory && !value) {
  8139. const on = Array.from(selected.entries()).reduce((arr, _ref7) => {
  8140. let [key, value] = _ref7;
  8141. if (value === 'on') arr.push(key);
  8142. return arr;
  8143. }, []);
  8144. if (on.length === 0) return original;
  8145. }
  8146. return selected;
  8147. },
  8148. in: (v, children, parents) => {
  8149. let map = new Map();
  8150. for (const id of v || []) {
  8151. map = strategy.select({
  8152. id,
  8153. value: true,
  8154. selected: new Map(map),
  8155. children,
  8156. parents
  8157. });
  8158. }
  8159. return map;
  8160. },
  8161. out: (v, children) => {
  8162. const arr = [];
  8163. for (const [key, value] of v.entries()) {
  8164. if (value === 'on' && !children.has(key)) arr.push(key);
  8165. }
  8166. return arr;
  8167. }
  8168. };
  8169. return strategy;
  8170. };
  8171. // Composables
  8172. // Types
  8173. const VNestedSymbol = Symbol.for('vuetify:nested');
  8174. const emptyNested = {
  8175. id: shallowRef(),
  8176. root: {
  8177. register: () => null,
  8178. unregister: () => null,
  8179. parents: ref(new Map()),
  8180. children: ref(new Map()),
  8181. open: () => null,
  8182. openOnSelect: () => null,
  8183. activate: () => null,
  8184. select: () => null,
  8185. activatable: ref(false),
  8186. selectable: ref(false),
  8187. opened: ref(new Set()),
  8188. activated: ref(new Set()),
  8189. selected: ref(new Map()),
  8190. selectedValues: ref([]),
  8191. getPath: () => []
  8192. }
  8193. };
  8194. const makeNestedProps = propsFactory({
  8195. activatable: Boolean,
  8196. selectable: Boolean,
  8197. activeStrategy: [String, Function, Object],
  8198. selectStrategy: [String, Function, Object],
  8199. openStrategy: [String, Object],
  8200. opened: null,
  8201. activated: null,
  8202. selected: null,
  8203. mandatory: Boolean
  8204. }, 'nested');
  8205. const useNested = props => {
  8206. let isUnmounted = false;
  8207. const children = ref(new Map());
  8208. const parents = ref(new Map());
  8209. const opened = useProxiedModel(props, 'opened', props.opened, v => new Set(v), v => [...v.values()]);
  8210. const activeStrategy = computed(() => {
  8211. if (typeof props.activeStrategy === 'object') return props.activeStrategy;
  8212. if (typeof props.activeStrategy === 'function') return props.activeStrategy(props.mandatory);
  8213. switch (props.activeStrategy) {
  8214. case 'leaf':
  8215. return leafActiveStrategy(props.mandatory);
  8216. case 'single-leaf':
  8217. return leafSingleActiveStrategy(props.mandatory);
  8218. case 'independent':
  8219. return independentActiveStrategy(props.mandatory);
  8220. case 'single-independent':
  8221. default:
  8222. return independentSingleActiveStrategy(props.mandatory);
  8223. }
  8224. });
  8225. const selectStrategy = computed(() => {
  8226. if (typeof props.selectStrategy === 'object') return props.selectStrategy;
  8227. if (typeof props.selectStrategy === 'function') return props.selectStrategy(props.mandatory);
  8228. switch (props.selectStrategy) {
  8229. case 'single-leaf':
  8230. return leafSingleSelectStrategy(props.mandatory);
  8231. case 'leaf':
  8232. return leafSelectStrategy(props.mandatory);
  8233. case 'independent':
  8234. return independentSelectStrategy(props.mandatory);
  8235. case 'single-independent':
  8236. return independentSingleSelectStrategy(props.mandatory);
  8237. case 'classic':
  8238. default:
  8239. return classicSelectStrategy(props.mandatory);
  8240. }
  8241. });
  8242. const openStrategy = computed(() => {
  8243. if (typeof props.openStrategy === 'object') return props.openStrategy;
  8244. switch (props.openStrategy) {
  8245. case 'list':
  8246. return listOpenStrategy;
  8247. case 'single':
  8248. return singleOpenStrategy;
  8249. case 'multiple':
  8250. default:
  8251. return multipleOpenStrategy;
  8252. }
  8253. });
  8254. const activated = useProxiedModel(props, 'activated', props.activated, v => activeStrategy.value.in(v, children.value, parents.value), v => activeStrategy.value.out(v, children.value, parents.value));
  8255. 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));
  8256. onBeforeUnmount(() => {
  8257. isUnmounted = true;
  8258. });
  8259. function getPath(id) {
  8260. const path = [];
  8261. let parent = id;
  8262. while (parent != null) {
  8263. path.unshift(parent);
  8264. parent = parents.value.get(parent);
  8265. }
  8266. return path;
  8267. }
  8268. const vm = getCurrentInstance('nested');
  8269. const nodeIds = new Set();
  8270. const nested = {
  8271. id: shallowRef(),
  8272. root: {
  8273. opened,
  8274. activatable: toRef(props, 'activatable'),
  8275. selectable: toRef(props, 'selectable'),
  8276. activated,
  8277. selected,
  8278. selectedValues: computed(() => {
  8279. const arr = [];
  8280. for (const [key, value] of selected.value.entries()) {
  8281. if (value === 'on') arr.push(key);
  8282. }
  8283. return arr;
  8284. }),
  8285. register: (id, parentId, isGroup) => {
  8286. if (nodeIds.has(id)) {
  8287. const path = getPath(id).map(String).join(' -> ');
  8288. const newPath = getPath(parentId).concat(id).map(String).join(' -> ');
  8289. consoleError(`Multiple nodes with the same ID\n\t${path}\n\t${newPath}`);
  8290. return;
  8291. } else {
  8292. nodeIds.add(id);
  8293. }
  8294. parentId && id !== parentId && parents.value.set(id, parentId);
  8295. isGroup && children.value.set(id, []);
  8296. if (parentId != null) {
  8297. children.value.set(parentId, [...(children.value.get(parentId) || []), id]);
  8298. }
  8299. },
  8300. unregister: id => {
  8301. if (isUnmounted) return;
  8302. nodeIds.delete(id);
  8303. children.value.delete(id);
  8304. const parent = parents.value.get(id);
  8305. if (parent) {
  8306. const list = children.value.get(parent) ?? [];
  8307. children.value.set(parent, list.filter(child => child !== id));
  8308. }
  8309. parents.value.delete(id);
  8310. },
  8311. open: (id, value, event) => {
  8312. vm.emit('click:open', {
  8313. id,
  8314. value,
  8315. path: getPath(id),
  8316. event
  8317. });
  8318. const newOpened = openStrategy.value.open({
  8319. id,
  8320. value,
  8321. opened: new Set(opened.value),
  8322. children: children.value,
  8323. parents: parents.value,
  8324. event
  8325. });
  8326. newOpened && (opened.value = newOpened);
  8327. },
  8328. openOnSelect: (id, value, event) => {
  8329. const newOpened = openStrategy.value.select({
  8330. id,
  8331. value,
  8332. selected: new Map(selected.value),
  8333. opened: new Set(opened.value),
  8334. children: children.value,
  8335. parents: parents.value,
  8336. event
  8337. });
  8338. newOpened && (opened.value = newOpened);
  8339. },
  8340. select: (id, value, event) => {
  8341. vm.emit('click:select', {
  8342. id,
  8343. value,
  8344. path: getPath(id),
  8345. event
  8346. });
  8347. const newSelected = selectStrategy.value.select({
  8348. id,
  8349. value,
  8350. selected: new Map(selected.value),
  8351. children: children.value,
  8352. parents: parents.value,
  8353. event
  8354. });
  8355. newSelected && (selected.value = newSelected);
  8356. nested.root.openOnSelect(id, value, event);
  8357. },
  8358. activate: (id, value, event) => {
  8359. if (!props.activatable) {
  8360. return nested.root.select(id, true, event);
  8361. }
  8362. vm.emit('click:activate', {
  8363. id,
  8364. value,
  8365. path: getPath(id),
  8366. event
  8367. });
  8368. const newActivated = activeStrategy.value.activate({
  8369. id,
  8370. value,
  8371. activated: new Set(activated.value),
  8372. children: children.value,
  8373. parents: parents.value,
  8374. event
  8375. });
  8376. newActivated && (activated.value = newActivated);
  8377. },
  8378. children,
  8379. parents,
  8380. getPath
  8381. }
  8382. };
  8383. provide(VNestedSymbol, nested);
  8384. return nested.root;
  8385. };
  8386. const useNestedItem = (id, isGroup) => {
  8387. const parent = inject$1(VNestedSymbol, emptyNested);
  8388. const uidSymbol = Symbol(getUid());
  8389. const computedId = computed(() => id.value !== undefined ? id.value : uidSymbol);
  8390. const item = {
  8391. ...parent,
  8392. id: computedId,
  8393. open: (open, e) => parent.root.open(computedId.value, open, e),
  8394. openOnSelect: (open, e) => parent.root.openOnSelect(computedId.value, open, e),
  8395. isOpen: computed(() => parent.root.opened.value.has(computedId.value)),
  8396. parent: computed(() => parent.root.parents.value.get(computedId.value)),
  8397. activate: (activated, e) => parent.root.activate(computedId.value, activated, e),
  8398. isActivated: computed(() => parent.root.activated.value.has(toRaw(computedId.value))),
  8399. select: (selected, e) => parent.root.select(computedId.value, selected, e),
  8400. isSelected: computed(() => parent.root.selected.value.get(toRaw(computedId.value)) === 'on'),
  8401. isIndeterminate: computed(() => parent.root.selected.value.get(computedId.value) === 'indeterminate'),
  8402. isLeaf: computed(() => !parent.root.children.value.get(computedId.value)),
  8403. isGroupActivator: parent.isGroupActivator
  8404. };
  8405. onBeforeMount(() => {
  8406. !parent.isGroupActivator && parent.root.register(computedId.value, parent.id.value, isGroup);
  8407. });
  8408. onBeforeUnmount(() => {
  8409. !parent.isGroupActivator && parent.root.unregister(computedId.value);
  8410. });
  8411. isGroup && provide(VNestedSymbol, item);
  8412. return item;
  8413. };
  8414. const useNestedGroupActivator = () => {
  8415. const parent = inject$1(VNestedSymbol, emptyNested);
  8416. provide(VNestedSymbol, {
  8417. ...parent,
  8418. isGroupActivator: true
  8419. });
  8420. };
  8421. const VListGroupActivator = defineComponent({
  8422. name: 'VListGroupActivator',
  8423. setup(_, _ref) {
  8424. let {
  8425. slots
  8426. } = _ref;
  8427. useNestedGroupActivator();
  8428. return () => slots.default?.();
  8429. }
  8430. });
  8431. const makeVListGroupProps = propsFactory({
  8432. /* @deprecated */
  8433. activeColor: String,
  8434. baseColor: String,
  8435. color: String,
  8436. collapseIcon: {
  8437. type: IconValue,
  8438. default: '$collapse'
  8439. },
  8440. expandIcon: {
  8441. type: IconValue,
  8442. default: '$expand'
  8443. },
  8444. prependIcon: IconValue,
  8445. appendIcon: IconValue,
  8446. fluid: Boolean,
  8447. subgroup: Boolean,
  8448. title: String,
  8449. value: null,
  8450. ...makeComponentProps(),
  8451. ...makeTagProps()
  8452. }, 'VListGroup');
  8453. const VListGroup = genericComponent()({
  8454. name: 'VListGroup',
  8455. props: makeVListGroupProps(),
  8456. setup(props, _ref2) {
  8457. let {
  8458. slots
  8459. } = _ref2;
  8460. const {
  8461. isOpen,
  8462. open,
  8463. id: _id
  8464. } = useNestedItem(toRef(props, 'value'), true);
  8465. const id = computed(() => `v-list-group--id-${String(_id.value)}`);
  8466. const list = useList();
  8467. const {
  8468. isBooted
  8469. } = useSsrBoot();
  8470. function onClick(e) {
  8471. e.stopPropagation();
  8472. open(!isOpen.value, e);
  8473. }
  8474. const activatorProps = computed(() => ({
  8475. onClick,
  8476. class: 'v-list-group__header',
  8477. id: id.value
  8478. }));
  8479. const toggleIcon = computed(() => isOpen.value ? props.collapseIcon : props.expandIcon);
  8480. const activatorDefaults = computed(() => ({
  8481. VListItem: {
  8482. active: isOpen.value,
  8483. activeColor: props.activeColor,
  8484. baseColor: props.baseColor,
  8485. color: props.color,
  8486. prependIcon: props.prependIcon || props.subgroup && toggleIcon.value,
  8487. appendIcon: props.appendIcon || !props.subgroup && toggleIcon.value,
  8488. title: props.title,
  8489. value: props.value
  8490. }
  8491. }));
  8492. useRender(() => createVNode(props.tag, {
  8493. "class": ['v-list-group', {
  8494. 'v-list-group--prepend': list?.hasPrepend.value,
  8495. 'v-list-group--fluid': props.fluid,
  8496. 'v-list-group--subgroup': props.subgroup,
  8497. 'v-list-group--open': isOpen.value
  8498. }, props.class],
  8499. "style": props.style
  8500. }, {
  8501. default: () => [slots.activator && createVNode(VDefaultsProvider, {
  8502. "defaults": activatorDefaults.value
  8503. }, {
  8504. default: () => [createVNode(VListGroupActivator, null, {
  8505. default: () => [slots.activator({
  8506. props: activatorProps.value,
  8507. isOpen: isOpen.value
  8508. })]
  8509. })]
  8510. }), createVNode(MaybeTransition, {
  8511. "transition": {
  8512. component: VExpandTransition
  8513. },
  8514. "disabled": !isBooted.value
  8515. }, {
  8516. default: () => [withDirectives(createVNode("div", {
  8517. "class": "v-list-group__items",
  8518. "role": "group",
  8519. "aria-labelledby": id.value
  8520. }, [slots.default?.()]), [[vShow, isOpen.value]])]
  8521. })]
  8522. }));
  8523. return {
  8524. isOpen
  8525. };
  8526. }
  8527. });
  8528. const makeVListItemSubtitleProps = propsFactory({
  8529. opacity: [Number, String],
  8530. ...makeComponentProps(),
  8531. ...makeTagProps()
  8532. }, 'VListItemSubtitle');
  8533. const VListItemSubtitle = genericComponent()({
  8534. name: 'VListItemSubtitle',
  8535. props: makeVListItemSubtitleProps(),
  8536. setup(props, _ref) {
  8537. let {
  8538. slots
  8539. } = _ref;
  8540. useRender(() => createVNode(props.tag, {
  8541. "class": ['v-list-item-subtitle', props.class],
  8542. "style": [{
  8543. '--v-list-item-subtitle-opacity': props.opacity
  8544. }, props.style]
  8545. }, slots));
  8546. return {};
  8547. }
  8548. });
  8549. // Utilities
  8550. const VListItemTitle = createSimpleFunctional('v-list-item-title');
  8551. // Types
  8552. const makeVListItemProps = propsFactory({
  8553. active: {
  8554. type: Boolean,
  8555. default: undefined
  8556. },
  8557. activeClass: String,
  8558. /* @deprecated */
  8559. activeColor: String,
  8560. appendAvatar: String,
  8561. appendIcon: IconValue,
  8562. baseColor: String,
  8563. disabled: Boolean,
  8564. lines: [Boolean, String],
  8565. link: {
  8566. type: Boolean,
  8567. default: undefined
  8568. },
  8569. nav: Boolean,
  8570. prependAvatar: String,
  8571. prependIcon: IconValue,
  8572. ripple: {
  8573. type: [Boolean, Object],
  8574. default: true
  8575. },
  8576. slim: Boolean,
  8577. subtitle: [String, Number],
  8578. title: [String, Number],
  8579. value: null,
  8580. onClick: EventProp(),
  8581. onClickOnce: EventProp(),
  8582. ...makeBorderProps(),
  8583. ...makeComponentProps(),
  8584. ...makeDensityProps(),
  8585. ...makeDimensionProps(),
  8586. ...makeElevationProps(),
  8587. ...makeRoundedProps(),
  8588. ...makeRouterProps(),
  8589. ...makeTagProps(),
  8590. ...makeThemeProps(),
  8591. ...makeVariantProps({
  8592. variant: 'text'
  8593. })
  8594. }, 'VListItem');
  8595. const VListItem = genericComponent()({
  8596. name: 'VListItem',
  8597. directives: {
  8598. Ripple
  8599. },
  8600. props: makeVListItemProps(),
  8601. emits: {
  8602. click: e => true
  8603. },
  8604. setup(props, _ref) {
  8605. let {
  8606. attrs,
  8607. slots,
  8608. emit
  8609. } = _ref;
  8610. const link = useLink(props, attrs);
  8611. const id = computed(() => props.value === undefined ? link.href.value : props.value);
  8612. const {
  8613. activate,
  8614. isActivated,
  8615. select,
  8616. isOpen,
  8617. isSelected,
  8618. isIndeterminate,
  8619. isGroupActivator,
  8620. root,
  8621. parent,
  8622. openOnSelect,
  8623. id: uid
  8624. } = useNestedItem(id, false);
  8625. const list = useList();
  8626. const isActive = computed(() => props.active !== false && (props.active || link.isActive?.value || (root.activatable.value ? isActivated.value : isSelected.value)));
  8627. const isLink = computed(() => props.link !== false && link.isLink.value);
  8628. const isSelectable = computed(() => !!list && (root.selectable.value || root.activatable.value || props.value != null));
  8629. const isClickable = computed(() => !props.disabled && props.link !== false && (props.link || link.isClickable.value || isSelectable.value));
  8630. const roundedProps = computed(() => props.rounded || props.nav);
  8631. const color = computed(() => props.color ?? props.activeColor);
  8632. const variantProps = computed(() => ({
  8633. color: isActive.value ? color.value ?? props.baseColor : props.baseColor,
  8634. variant: props.variant
  8635. }));
  8636. // useNestedItem doesn't call register until beforeMount,
  8637. // so this can't be an immediate watcher as we don't know parent yet
  8638. watch(() => link.isActive?.value, val => {
  8639. if (!val) return;
  8640. handleActiveLink();
  8641. });
  8642. onBeforeMount(() => {
  8643. if (link.isActive?.value) handleActiveLink();
  8644. });
  8645. function handleActiveLink() {
  8646. if (parent.value != null) {
  8647. root.open(parent.value, true);
  8648. }
  8649. openOnSelect(true);
  8650. }
  8651. const {
  8652. themeClasses
  8653. } = provideTheme(props);
  8654. const {
  8655. borderClasses
  8656. } = useBorder(props);
  8657. const {
  8658. colorClasses,
  8659. colorStyles,
  8660. variantClasses
  8661. } = useVariant(variantProps);
  8662. const {
  8663. densityClasses
  8664. } = useDensity(props);
  8665. const {
  8666. dimensionStyles
  8667. } = useDimension(props);
  8668. const {
  8669. elevationClasses
  8670. } = useElevation(props);
  8671. const {
  8672. roundedClasses
  8673. } = useRounded(roundedProps);
  8674. const lineClasses = computed(() => props.lines ? `v-list-item--${props.lines}-line` : undefined);
  8675. const slotProps = computed(() => ({
  8676. isActive: isActive.value,
  8677. select,
  8678. isOpen: isOpen.value,
  8679. isSelected: isSelected.value,
  8680. isIndeterminate: isIndeterminate.value
  8681. }));
  8682. function onClick(e) {
  8683. emit('click', e);
  8684. if (!isClickable.value) return;
  8685. link.navigate?.(e);
  8686. if (isGroupActivator) return;
  8687. if (root.activatable.value) {
  8688. activate(!isActivated.value, e);
  8689. } else if (root.selectable.value) {
  8690. select(!isSelected.value, e);
  8691. } else if (props.value != null) {
  8692. select(!isSelected.value, e);
  8693. }
  8694. }
  8695. function onKeyDown(e) {
  8696. if (e.key === 'Enter' || e.key === ' ') {
  8697. e.preventDefault();
  8698. e.target.dispatchEvent(new MouseEvent('click', e));
  8699. }
  8700. }
  8701. useRender(() => {
  8702. const Tag = isLink.value ? 'a' : props.tag;
  8703. const hasTitle = slots.title || props.title != null;
  8704. const hasSubtitle = slots.subtitle || props.subtitle != null;
  8705. const hasAppendMedia = !!(props.appendAvatar || props.appendIcon);
  8706. const hasAppend = !!(hasAppendMedia || slots.append);
  8707. const hasPrependMedia = !!(props.prependAvatar || props.prependIcon);
  8708. const hasPrepend = !!(hasPrependMedia || slots.prepend);
  8709. list?.updateHasPrepend(hasPrepend);
  8710. if (props.activeColor) {
  8711. deprecate('active-color', ['color', 'base-color']);
  8712. }
  8713. return withDirectives(createVNode(Tag, mergeProps({
  8714. "class": ['v-list-item', {
  8715. 'v-list-item--active': isActive.value,
  8716. 'v-list-item--disabled': props.disabled,
  8717. 'v-list-item--link': isClickable.value,
  8718. 'v-list-item--nav': props.nav,
  8719. 'v-list-item--prepend': !hasPrepend && list?.hasPrepend.value,
  8720. 'v-list-item--slim': props.slim,
  8721. [`${props.activeClass}`]: props.activeClass && isActive.value
  8722. }, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, variantClasses.value, props.class],
  8723. "style": [colorStyles.value, dimensionStyles.value, props.style],
  8724. "tabindex": isClickable.value ? list ? -2 : 0 : undefined,
  8725. "aria-selected": isSelectable.value ? root.activatable.value ? isActivated.value : root.selectable.value ? isSelected.value : isActive.value : undefined,
  8726. "onClick": onClick,
  8727. "onKeydown": isClickable.value && !isLink.value && onKeyDown
  8728. }, link.linkProps), {
  8729. default: () => [genOverlays(isClickable.value || isActive.value, 'v-list-item'), hasPrepend && createVNode("div", {
  8730. "key": "prepend",
  8731. "class": "v-list-item__prepend"
  8732. }, [!slots.prepend ? createVNode(Fragment, null, [props.prependAvatar && createVNode(VAvatar, {
  8733. "key": "prepend-avatar",
  8734. "density": props.density,
  8735. "image": props.prependAvatar
  8736. }, null), props.prependIcon && createVNode(VIcon, {
  8737. "key": "prepend-icon",
  8738. "density": props.density,
  8739. "icon": props.prependIcon
  8740. }, null)]) : createVNode(VDefaultsProvider, {
  8741. "key": "prepend-defaults",
  8742. "disabled": !hasPrependMedia,
  8743. "defaults": {
  8744. VAvatar: {
  8745. density: props.density,
  8746. image: props.prependAvatar
  8747. },
  8748. VIcon: {
  8749. density: props.density,
  8750. icon: props.prependIcon
  8751. },
  8752. VListItemAction: {
  8753. start: true
  8754. }
  8755. }
  8756. }, {
  8757. default: () => [slots.prepend?.(slotProps.value)]
  8758. }), createVNode("div", {
  8759. "class": "v-list-item__spacer"
  8760. }, null)]), createVNode("div", {
  8761. "class": "v-list-item__content",
  8762. "data-no-activator": ""
  8763. }, [hasTitle && createVNode(VListItemTitle, {
  8764. "key": "title"
  8765. }, {
  8766. default: () => [slots.title?.({
  8767. title: props.title
  8768. }) ?? props.title]
  8769. }), hasSubtitle && createVNode(VListItemSubtitle, {
  8770. "key": "subtitle"
  8771. }, {
  8772. default: () => [slots.subtitle?.({
  8773. subtitle: props.subtitle
  8774. }) ?? props.subtitle]
  8775. }), slots.default?.(slotProps.value)]), hasAppend && createVNode("div", {
  8776. "key": "append",
  8777. "class": "v-list-item__append"
  8778. }, [!slots.append ? createVNode(Fragment, null, [props.appendIcon && createVNode(VIcon, {
  8779. "key": "append-icon",
  8780. "density": props.density,
  8781. "icon": props.appendIcon
  8782. }, null), props.appendAvatar && createVNode(VAvatar, {
  8783. "key": "append-avatar",
  8784. "density": props.density,
  8785. "image": props.appendAvatar
  8786. }, null)]) : createVNode(VDefaultsProvider, {
  8787. "key": "append-defaults",
  8788. "disabled": !hasAppendMedia,
  8789. "defaults": {
  8790. VAvatar: {
  8791. density: props.density,
  8792. image: props.appendAvatar
  8793. },
  8794. VIcon: {
  8795. density: props.density,
  8796. icon: props.appendIcon
  8797. },
  8798. VListItemAction: {
  8799. end: true
  8800. }
  8801. }
  8802. }, {
  8803. default: () => [slots.append?.(slotProps.value)]
  8804. }), createVNode("div", {
  8805. "class": "v-list-item__spacer"
  8806. }, null)])]
  8807. }), [[resolveDirective("ripple"), isClickable.value && props.ripple]]);
  8808. });
  8809. return {
  8810. activate,
  8811. isActivated,
  8812. isGroupActivator,
  8813. isSelected,
  8814. list,
  8815. select,
  8816. root,
  8817. id: uid
  8818. };
  8819. }
  8820. });
  8821. const makeVListSubheaderProps = propsFactory({
  8822. color: String,
  8823. inset: Boolean,
  8824. sticky: Boolean,
  8825. title: String,
  8826. ...makeComponentProps(),
  8827. ...makeTagProps()
  8828. }, 'VListSubheader');
  8829. const VListSubheader = genericComponent()({
  8830. name: 'VListSubheader',
  8831. props: makeVListSubheaderProps(),
  8832. setup(props, _ref) {
  8833. let {
  8834. slots
  8835. } = _ref;
  8836. const {
  8837. textColorClasses,
  8838. textColorStyles
  8839. } = useTextColor(toRef(props, 'color'));
  8840. useRender(() => {
  8841. const hasText = !!(slots.default || props.title);
  8842. return createVNode(props.tag, {
  8843. "class": ['v-list-subheader', {
  8844. 'v-list-subheader--inset': props.inset,
  8845. 'v-list-subheader--sticky': props.sticky
  8846. }, textColorClasses.value, props.class],
  8847. "style": [{
  8848. textColorStyles
  8849. }, props.style]
  8850. }, {
  8851. default: () => [hasText && createVNode("div", {
  8852. "class": "v-list-subheader__text"
  8853. }, [slots.default?.() ?? props.title])]
  8854. });
  8855. });
  8856. return {};
  8857. }
  8858. });
  8859. const makeVDividerProps = propsFactory({
  8860. color: String,
  8861. inset: Boolean,
  8862. length: [Number, String],
  8863. opacity: [Number, String],
  8864. thickness: [Number, String],
  8865. vertical: Boolean,
  8866. ...makeComponentProps(),
  8867. ...makeThemeProps()
  8868. }, 'VDivider');
  8869. const VDivider = genericComponent()({
  8870. name: 'VDivider',
  8871. props: makeVDividerProps(),
  8872. setup(props, _ref) {
  8873. let {
  8874. attrs,
  8875. slots
  8876. } = _ref;
  8877. const {
  8878. themeClasses
  8879. } = provideTheme(props);
  8880. const {
  8881. textColorClasses,
  8882. textColorStyles
  8883. } = useTextColor(toRef(props, 'color'));
  8884. const dividerStyles = computed(() => {
  8885. const styles = {};
  8886. if (props.length) {
  8887. styles[props.vertical ? 'height' : 'width'] = convertToUnit(props.length);
  8888. }
  8889. if (props.thickness) {
  8890. styles[props.vertical ? 'borderRightWidth' : 'borderTopWidth'] = convertToUnit(props.thickness);
  8891. }
  8892. return styles;
  8893. });
  8894. useRender(() => {
  8895. const divider = createVNode("hr", {
  8896. "class": [{
  8897. 'v-divider': true,
  8898. 'v-divider--inset': props.inset,
  8899. 'v-divider--vertical': props.vertical
  8900. }, themeClasses.value, textColorClasses.value, props.class],
  8901. "style": [dividerStyles.value, textColorStyles.value, {
  8902. '--v-border-opacity': props.opacity
  8903. }, props.style],
  8904. "aria-orientation": !attrs.role || attrs.role === 'separator' ? props.vertical ? 'vertical' : 'horizontal' : undefined,
  8905. "role": `${attrs.role || 'separator'}`
  8906. }, null);
  8907. if (!slots.default) return divider;
  8908. return createVNode("div", {
  8909. "class": ['v-divider__wrapper', {
  8910. 'v-divider__wrapper--vertical': props.vertical,
  8911. 'v-divider__wrapper--inset': props.inset
  8912. }]
  8913. }, [divider, createVNode("div", {
  8914. "class": "v-divider__content"
  8915. }, [slots.default()]), divider]);
  8916. });
  8917. return {};
  8918. }
  8919. });
  8920. // Types
  8921. const makeVListChildrenProps = propsFactory({
  8922. items: Array,
  8923. returnObject: Boolean
  8924. }, 'VListChildren');
  8925. const VListChildren = genericComponent()({
  8926. name: 'VListChildren',
  8927. props: makeVListChildrenProps(),
  8928. setup(props, _ref) {
  8929. let {
  8930. slots
  8931. } = _ref;
  8932. createList();
  8933. return () => slots.default?.() ?? props.items?.map(_ref2 => {
  8934. let {
  8935. children,
  8936. props: itemProps,
  8937. type,
  8938. raw: item
  8939. } = _ref2;
  8940. if (type === 'divider') {
  8941. return slots.divider?.({
  8942. props: itemProps
  8943. }) ?? createVNode(VDivider, itemProps, null);
  8944. }
  8945. if (type === 'subheader') {
  8946. return slots.subheader?.({
  8947. props: itemProps
  8948. }) ?? createVNode(VListSubheader, itemProps, null);
  8949. }
  8950. const slotsWithItem = {
  8951. subtitle: slots.subtitle ? slotProps => slots.subtitle?.({
  8952. ...slotProps,
  8953. item
  8954. }) : undefined,
  8955. prepend: slots.prepend ? slotProps => slots.prepend?.({
  8956. ...slotProps,
  8957. item
  8958. }) : undefined,
  8959. append: slots.append ? slotProps => slots.append?.({
  8960. ...slotProps,
  8961. item
  8962. }) : undefined,
  8963. title: slots.title ? slotProps => slots.title?.({
  8964. ...slotProps,
  8965. item
  8966. }) : undefined
  8967. };
  8968. const listGroupProps = VListGroup.filterProps(itemProps);
  8969. return children ? createVNode(VListGroup, mergeProps({
  8970. "value": itemProps?.value
  8971. }, listGroupProps), {
  8972. activator: _ref3 => {
  8973. let {
  8974. props: activatorProps
  8975. } = _ref3;
  8976. const listItemProps = {
  8977. ...itemProps,
  8978. ...activatorProps,
  8979. value: props.returnObject ? item : itemProps.value
  8980. };
  8981. return slots.header ? slots.header({
  8982. props: listItemProps
  8983. }) : createVNode(VListItem, listItemProps, slotsWithItem);
  8984. },
  8985. default: () => createVNode(VListChildren, {
  8986. "items": children,
  8987. "returnObject": props.returnObject
  8988. }, slots)
  8989. }) : slots.item ? slots.item({
  8990. props: itemProps
  8991. }) : createVNode(VListItem, mergeProps(itemProps, {
  8992. "value": props.returnObject ? item : itemProps.value
  8993. }), slotsWithItem);
  8994. });
  8995. }
  8996. });
  8997. // Utilities
  8998. // Types
  8999. // Composables
  9000. const makeItemsProps = propsFactory({
  9001. items: {
  9002. type: Array,
  9003. default: () => []
  9004. },
  9005. itemTitle: {
  9006. type: [String, Array, Function],
  9007. default: 'title'
  9008. },
  9009. itemValue: {
  9010. type: [String, Array, Function],
  9011. default: 'value'
  9012. },
  9013. itemChildren: {
  9014. type: [Boolean, String, Array, Function],
  9015. default: 'children'
  9016. },
  9017. itemProps: {
  9018. type: [Boolean, String, Array, Function],
  9019. default: 'props'
  9020. },
  9021. returnObject: Boolean,
  9022. valueComparator: {
  9023. type: Function,
  9024. default: deepEqual
  9025. }
  9026. }, 'list-items');
  9027. function transformItem$3(props, item) {
  9028. const title = getPropertyFromItem(item, props.itemTitle, item);
  9029. const value = getPropertyFromItem(item, props.itemValue, title);
  9030. const children = getPropertyFromItem(item, props.itemChildren);
  9031. const itemProps = props.itemProps === true ? typeof item === 'object' && item != null && !Array.isArray(item) ? 'children' in item ? omit(item, ['children']) : item : undefined : getPropertyFromItem(item, props.itemProps);
  9032. const _props = {
  9033. title,
  9034. value,
  9035. ...itemProps
  9036. };
  9037. return {
  9038. title: String(_props.title ?? ''),
  9039. value: _props.value,
  9040. props: _props,
  9041. children: Array.isArray(children) ? transformItems$3(props, children) : undefined,
  9042. raw: item
  9043. };
  9044. }
  9045. function transformItems$3(props, items) {
  9046. const array = [];
  9047. for (const item of items) {
  9048. array.push(transformItem$3(props, item));
  9049. }
  9050. return array;
  9051. }
  9052. function useItems(props) {
  9053. const items = computed(() => transformItems$3(props, props.items));
  9054. const hasNullItem = computed(() => items.value.some(item => item.value === null));
  9055. function transformIn(value) {
  9056. if (!hasNullItem.value) {
  9057. // When the model value is null, return an InternalItem
  9058. // based on null only if null is one of the items
  9059. value = value.filter(v => v !== null);
  9060. }
  9061. return value.map(v => {
  9062. if (props.returnObject && typeof v === 'string') {
  9063. // String model value means value is a custom input value from combobox
  9064. // Don't look up existing items if the model value is a string
  9065. return transformItem$3(props, v);
  9066. }
  9067. return items.value.find(item => props.valueComparator(v, item.value)) || transformItem$3(props, v);
  9068. });
  9069. }
  9070. function transformOut(value) {
  9071. return props.returnObject ? value.map(_ref => {
  9072. let {
  9073. raw
  9074. } = _ref;
  9075. return raw;
  9076. }) : value.map(_ref2 => {
  9077. let {
  9078. value
  9079. } = _ref2;
  9080. return value;
  9081. });
  9082. }
  9083. return {
  9084. items,
  9085. transformIn,
  9086. transformOut
  9087. };
  9088. }
  9089. // Types
  9090. function isPrimitive(value) {
  9091. return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean';
  9092. }
  9093. function transformItem$2(props, item) {
  9094. const type = getPropertyFromItem(item, props.itemType, 'item');
  9095. const title = isPrimitive(item) ? item : getPropertyFromItem(item, props.itemTitle);
  9096. const value = getPropertyFromItem(item, props.itemValue, undefined);
  9097. const children = getPropertyFromItem(item, props.itemChildren);
  9098. const itemProps = props.itemProps === true ? omit(item, ['children']) : getPropertyFromItem(item, props.itemProps);
  9099. const _props = {
  9100. title,
  9101. value,
  9102. ...itemProps
  9103. };
  9104. return {
  9105. type,
  9106. title: _props.title,
  9107. value: _props.value,
  9108. props: _props,
  9109. children: type === 'item' && children ? transformItems$2(props, children) : undefined,
  9110. raw: item
  9111. };
  9112. }
  9113. function transformItems$2(props, items) {
  9114. const array = [];
  9115. for (const item of items) {
  9116. array.push(transformItem$2(props, item));
  9117. }
  9118. return array;
  9119. }
  9120. function useListItems(props) {
  9121. const items = computed(() => transformItems$2(props, props.items));
  9122. return {
  9123. items
  9124. };
  9125. }
  9126. const makeVListProps = propsFactory({
  9127. baseColor: String,
  9128. /* @deprecated */
  9129. activeColor: String,
  9130. activeClass: String,
  9131. bgColor: String,
  9132. disabled: Boolean,
  9133. expandIcon: IconValue,
  9134. collapseIcon: IconValue,
  9135. lines: {
  9136. type: [Boolean, String],
  9137. default: 'one'
  9138. },
  9139. slim: Boolean,
  9140. nav: Boolean,
  9141. 'onClick:open': EventProp(),
  9142. 'onClick:select': EventProp(),
  9143. 'onUpdate:opened': EventProp(),
  9144. ...makeNestedProps({
  9145. selectStrategy: 'single-leaf',
  9146. openStrategy: 'list'
  9147. }),
  9148. ...makeBorderProps(),
  9149. ...makeComponentProps(),
  9150. ...makeDensityProps(),
  9151. ...makeDimensionProps(),
  9152. ...makeElevationProps(),
  9153. itemType: {
  9154. type: String,
  9155. default: 'type'
  9156. },
  9157. ...makeItemsProps(),
  9158. ...makeRoundedProps(),
  9159. ...makeTagProps(),
  9160. ...makeThemeProps(),
  9161. ...makeVariantProps({
  9162. variant: 'text'
  9163. })
  9164. }, 'VList');
  9165. const VList = genericComponent()({
  9166. name: 'VList',
  9167. props: makeVListProps(),
  9168. emits: {
  9169. 'update:selected': value => true,
  9170. 'update:activated': value => true,
  9171. 'update:opened': value => true,
  9172. 'click:open': value => true,
  9173. 'click:activate': value => true,
  9174. 'click:select': value => true
  9175. },
  9176. setup(props, _ref) {
  9177. let {
  9178. slots
  9179. } = _ref;
  9180. const {
  9181. items
  9182. } = useListItems(props);
  9183. const {
  9184. themeClasses
  9185. } = provideTheme(props);
  9186. const {
  9187. backgroundColorClasses,
  9188. backgroundColorStyles
  9189. } = useBackgroundColor(toRef(props, 'bgColor'));
  9190. const {
  9191. borderClasses
  9192. } = useBorder(props);
  9193. const {
  9194. densityClasses
  9195. } = useDensity(props);
  9196. const {
  9197. dimensionStyles
  9198. } = useDimension(props);
  9199. const {
  9200. elevationClasses
  9201. } = useElevation(props);
  9202. const {
  9203. roundedClasses
  9204. } = useRounded(props);
  9205. const {
  9206. children,
  9207. open,
  9208. parents,
  9209. select,
  9210. getPath
  9211. } = useNested(props);
  9212. const lineClasses = computed(() => props.lines ? `v-list--${props.lines}-line` : undefined);
  9213. const activeColor = toRef(props, 'activeColor');
  9214. const baseColor = toRef(props, 'baseColor');
  9215. const color = toRef(props, 'color');
  9216. createList();
  9217. provideDefaults({
  9218. VListGroup: {
  9219. activeColor,
  9220. baseColor,
  9221. color,
  9222. expandIcon: toRef(props, 'expandIcon'),
  9223. collapseIcon: toRef(props, 'collapseIcon')
  9224. },
  9225. VListItem: {
  9226. activeClass: toRef(props, 'activeClass'),
  9227. activeColor,
  9228. baseColor,
  9229. color,
  9230. density: toRef(props, 'density'),
  9231. disabled: toRef(props, 'disabled'),
  9232. lines: toRef(props, 'lines'),
  9233. nav: toRef(props, 'nav'),
  9234. slim: toRef(props, 'slim'),
  9235. variant: toRef(props, 'variant')
  9236. }
  9237. });
  9238. const isFocused = shallowRef(false);
  9239. const contentRef = ref();
  9240. function onFocusin(e) {
  9241. isFocused.value = true;
  9242. }
  9243. function onFocusout(e) {
  9244. isFocused.value = false;
  9245. }
  9246. function onFocus(e) {
  9247. if (!isFocused.value && !(e.relatedTarget && contentRef.value?.contains(e.relatedTarget))) focus();
  9248. }
  9249. function onKeydown(e) {
  9250. const target = e.target;
  9251. if (!contentRef.value || ['INPUT', 'TEXTAREA'].includes(target.tagName)) return;
  9252. if (e.key === 'ArrowDown') {
  9253. focus('next');
  9254. } else if (e.key === 'ArrowUp') {
  9255. focus('prev');
  9256. } else if (e.key === 'Home') {
  9257. focus('first');
  9258. } else if (e.key === 'End') {
  9259. focus('last');
  9260. } else {
  9261. return;
  9262. }
  9263. e.preventDefault();
  9264. }
  9265. function onMousedown(e) {
  9266. isFocused.value = true;
  9267. }
  9268. function focus(location) {
  9269. if (contentRef.value) {
  9270. return focusChild(contentRef.value, location);
  9271. }
  9272. }
  9273. useRender(() => {
  9274. return createVNode(props.tag, {
  9275. "ref": contentRef,
  9276. "class": ['v-list', {
  9277. 'v-list--disabled': props.disabled,
  9278. 'v-list--nav': props.nav,
  9279. 'v-list--slim': props.slim
  9280. }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, lineClasses.value, roundedClasses.value, props.class],
  9281. "style": [backgroundColorStyles.value, dimensionStyles.value, props.style],
  9282. "tabindex": props.disabled || isFocused.value ? -1 : 0,
  9283. "role": "listbox",
  9284. "aria-activedescendant": undefined,
  9285. "onFocusin": onFocusin,
  9286. "onFocusout": onFocusout,
  9287. "onFocus": onFocus,
  9288. "onKeydown": onKeydown,
  9289. "onMousedown": onMousedown
  9290. }, {
  9291. default: () => [createVNode(VListChildren, {
  9292. "items": items.value,
  9293. "returnObject": props.returnObject
  9294. }, slots)]
  9295. });
  9296. });
  9297. return {
  9298. open,
  9299. select,
  9300. focus,
  9301. children,
  9302. parents,
  9303. getPath
  9304. };
  9305. }
  9306. });
  9307. // Utilities
  9308. const VListImg = createSimpleFunctional('v-list-img');
  9309. const makeVListItemActionProps = propsFactory({
  9310. start: Boolean,
  9311. end: Boolean,
  9312. ...makeComponentProps(),
  9313. ...makeTagProps()
  9314. }, 'VListItemAction');
  9315. const VListItemAction = genericComponent()({
  9316. name: 'VListItemAction',
  9317. props: makeVListItemActionProps(),
  9318. setup(props, _ref) {
  9319. let {
  9320. slots
  9321. } = _ref;
  9322. useRender(() => createVNode(props.tag, {
  9323. "class": ['v-list-item-action', {
  9324. 'v-list-item-action--start': props.start,
  9325. 'v-list-item-action--end': props.end
  9326. }, props.class],
  9327. "style": props.style
  9328. }, slots));
  9329. return {};
  9330. }
  9331. });
  9332. const makeVListItemMediaProps = propsFactory({
  9333. start: Boolean,
  9334. end: Boolean,
  9335. ...makeComponentProps(),
  9336. ...makeTagProps()
  9337. }, 'VListItemMedia');
  9338. const VListItemMedia = genericComponent()({
  9339. name: 'VListItemMedia',
  9340. props: makeVListItemMediaProps(),
  9341. setup(props, _ref) {
  9342. let {
  9343. slots
  9344. } = _ref;
  9345. useRender(() => {
  9346. return createVNode(props.tag, {
  9347. "class": ['v-list-item-media', {
  9348. 'v-list-item-media--start': props.start,
  9349. 'v-list-item-media--end': props.end
  9350. }, props.class],
  9351. "style": props.style
  9352. }, slots);
  9353. });
  9354. return {};
  9355. }
  9356. });
  9357. // Types
  9358. /** Convert a point in local space to viewport space */
  9359. function elementToViewport(point, offset) {
  9360. return {
  9361. x: point.x + offset.x,
  9362. y: point.y + offset.y
  9363. };
  9364. }
  9365. /** Get the difference between two points */
  9366. function getOffset$1(a, b) {
  9367. return {
  9368. x: a.x - b.x,
  9369. y: a.y - b.y
  9370. };
  9371. }
  9372. /** Convert an anchor object to a point in local space */
  9373. function anchorToPoint(anchor, box) {
  9374. if (anchor.side === 'top' || anchor.side === 'bottom') {
  9375. const {
  9376. side,
  9377. align
  9378. } = anchor;
  9379. const x = align === 'left' ? 0 : align === 'center' ? box.width / 2 : align === 'right' ? box.width : align;
  9380. const y = side === 'top' ? 0 : side === 'bottom' ? box.height : side;
  9381. return elementToViewport({
  9382. x,
  9383. y
  9384. }, box);
  9385. } else if (anchor.side === 'left' || anchor.side === 'right') {
  9386. const {
  9387. side,
  9388. align
  9389. } = anchor;
  9390. const x = side === 'left' ? 0 : side === 'right' ? box.width : side;
  9391. const y = align === 'top' ? 0 : align === 'center' ? box.height / 2 : align === 'bottom' ? box.height : align;
  9392. return elementToViewport({
  9393. x,
  9394. y
  9395. }, box);
  9396. }
  9397. return elementToViewport({
  9398. x: box.width / 2,
  9399. y: box.height / 2
  9400. }, box);
  9401. }
  9402. // Composables
  9403. // Types
  9404. const locationStrategies = {
  9405. static: staticLocationStrategy,
  9406. // specific viewport position, usually centered
  9407. connected: connectedLocationStrategy // connected to a certain element
  9408. };
  9409. const makeLocationStrategyProps = propsFactory({
  9410. locationStrategy: {
  9411. type: [String, Function],
  9412. default: 'static',
  9413. validator: val => typeof val === 'function' || val in locationStrategies
  9414. },
  9415. location: {
  9416. type: String,
  9417. default: 'bottom'
  9418. },
  9419. origin: {
  9420. type: String,
  9421. default: 'auto'
  9422. },
  9423. offset: [Number, String, Array]
  9424. }, 'VOverlay-location-strategies');
  9425. function useLocationStrategies(props, data) {
  9426. const contentStyles = ref({});
  9427. const updateLocation = ref();
  9428. if (IN_BROWSER) {
  9429. useToggleScope(() => !!(data.isActive.value && props.locationStrategy), reset => {
  9430. watch(() => props.locationStrategy, reset);
  9431. onScopeDispose(() => {
  9432. window.removeEventListener('resize', onResize);
  9433. updateLocation.value = undefined;
  9434. });
  9435. window.addEventListener('resize', onResize, {
  9436. passive: true
  9437. });
  9438. if (typeof props.locationStrategy === 'function') {
  9439. updateLocation.value = props.locationStrategy(data, props, contentStyles)?.updateLocation;
  9440. } else {
  9441. updateLocation.value = locationStrategies[props.locationStrategy](data, props, contentStyles)?.updateLocation;
  9442. }
  9443. });
  9444. }
  9445. function onResize(e) {
  9446. updateLocation.value?.(e);
  9447. }
  9448. return {
  9449. contentStyles,
  9450. updateLocation
  9451. };
  9452. }
  9453. function staticLocationStrategy() {
  9454. // TODO
  9455. }
  9456. /** Get size of element ignoring max-width/max-height */
  9457. function getIntrinsicSize(el, isRtl) {
  9458. // const scrollables = new Map<Element, [number, number]>()
  9459. // el.querySelectorAll('*').forEach(el => {
  9460. // const x = el.scrollLeft
  9461. // const y = el.scrollTop
  9462. // if (x || y) {
  9463. // scrollables.set(el, [x, y])
  9464. // }
  9465. // })
  9466. // const initialMaxWidth = el.style.maxWidth
  9467. // const initialMaxHeight = el.style.maxHeight
  9468. // el.style.removeProperty('max-width')
  9469. // el.style.removeProperty('max-height')
  9470. /* eslint-disable-next-line sonarjs/prefer-immediate-return */
  9471. const contentBox = nullifyTransforms(el);
  9472. if (isRtl) {
  9473. contentBox.x += parseFloat(el.style.right || 0);
  9474. } else {
  9475. contentBox.x -= parseFloat(el.style.left || 0);
  9476. }
  9477. contentBox.y -= parseFloat(el.style.top || 0);
  9478. // el.style.maxWidth = initialMaxWidth
  9479. // el.style.maxHeight = initialMaxHeight
  9480. // scrollables.forEach((position, el) => {
  9481. // el.scrollTo(...position)
  9482. // })
  9483. return contentBox;
  9484. }
  9485. function connectedLocationStrategy(data, props, contentStyles) {
  9486. const activatorFixed = Array.isArray(data.target.value) || isFixedPosition(data.target.value);
  9487. if (activatorFixed) {
  9488. Object.assign(contentStyles.value, {
  9489. position: 'fixed',
  9490. top: 0,
  9491. [data.isRtl.value ? 'right' : 'left']: 0
  9492. });
  9493. }
  9494. const {
  9495. preferredAnchor,
  9496. preferredOrigin
  9497. } = destructComputed(() => {
  9498. const parsedAnchor = parseAnchor(props.location, data.isRtl.value);
  9499. const parsedOrigin = props.origin === 'overlap' ? parsedAnchor : props.origin === 'auto' ? flipSide(parsedAnchor) : parseAnchor(props.origin, data.isRtl.value);
  9500. // Some combinations of props may produce an invalid origin
  9501. if (parsedAnchor.side === parsedOrigin.side && parsedAnchor.align === flipAlign(parsedOrigin).align) {
  9502. return {
  9503. preferredAnchor: flipCorner(parsedAnchor),
  9504. preferredOrigin: flipCorner(parsedOrigin)
  9505. };
  9506. } else {
  9507. return {
  9508. preferredAnchor: parsedAnchor,
  9509. preferredOrigin: parsedOrigin
  9510. };
  9511. }
  9512. });
  9513. const [minWidth, minHeight, maxWidth, maxHeight] = ['minWidth', 'minHeight', 'maxWidth', 'maxHeight'].map(key => {
  9514. return computed(() => {
  9515. const val = parseFloat(props[key]);
  9516. return isNaN(val) ? Infinity : val;
  9517. });
  9518. });
  9519. const offset = computed(() => {
  9520. if (Array.isArray(props.offset)) {
  9521. return props.offset;
  9522. }
  9523. if (typeof props.offset === 'string') {
  9524. const offset = props.offset.split(' ').map(parseFloat);
  9525. if (offset.length < 2) offset.push(0);
  9526. return offset;
  9527. }
  9528. return typeof props.offset === 'number' ? [props.offset, 0] : [0, 0];
  9529. });
  9530. let observe = false;
  9531. const observer = new ResizeObserver(() => {
  9532. if (observe) updateLocation();
  9533. });
  9534. watch([data.target, data.contentEl], (_ref, _ref2) => {
  9535. let [newTarget, newContentEl] = _ref;
  9536. let [oldTarget, oldContentEl] = _ref2;
  9537. if (oldTarget && !Array.isArray(oldTarget)) observer.unobserve(oldTarget);
  9538. if (newTarget && !Array.isArray(newTarget)) observer.observe(newTarget);
  9539. if (oldContentEl) observer.unobserve(oldContentEl);
  9540. if (newContentEl) observer.observe(newContentEl);
  9541. }, {
  9542. immediate: true
  9543. });
  9544. onScopeDispose(() => {
  9545. observer.disconnect();
  9546. });
  9547. // eslint-disable-next-line max-statements
  9548. function updateLocation() {
  9549. observe = false;
  9550. requestAnimationFrame(() => observe = true);
  9551. if (!data.target.value || !data.contentEl.value) return;
  9552. const targetBox = getTargetBox(data.target.value);
  9553. const contentBox = getIntrinsicSize(data.contentEl.value, data.isRtl.value);
  9554. const scrollParents = getScrollParents(data.contentEl.value);
  9555. const viewportMargin = 12;
  9556. if (!scrollParents.length) {
  9557. scrollParents.push(document.documentElement);
  9558. if (!(data.contentEl.value.style.top && data.contentEl.value.style.left)) {
  9559. contentBox.x -= parseFloat(document.documentElement.style.getPropertyValue('--v-body-scroll-x') || 0);
  9560. contentBox.y -= parseFloat(document.documentElement.style.getPropertyValue('--v-body-scroll-y') || 0);
  9561. }
  9562. }
  9563. const viewport = scrollParents.reduce((box, el) => {
  9564. const rect = el.getBoundingClientRect();
  9565. const scrollBox = new Box({
  9566. x: el === document.documentElement ? 0 : rect.x,
  9567. y: el === document.documentElement ? 0 : rect.y,
  9568. width: el.clientWidth,
  9569. height: el.clientHeight
  9570. });
  9571. if (box) {
  9572. return new Box({
  9573. x: Math.max(box.left, scrollBox.left),
  9574. y: Math.max(box.top, scrollBox.top),
  9575. width: Math.min(box.right, scrollBox.right) - Math.max(box.left, scrollBox.left),
  9576. height: Math.min(box.bottom, scrollBox.bottom) - Math.max(box.top, scrollBox.top)
  9577. });
  9578. }
  9579. return scrollBox;
  9580. }, undefined);
  9581. viewport.x += viewportMargin;
  9582. viewport.y += viewportMargin;
  9583. viewport.width -= viewportMargin * 2;
  9584. viewport.height -= viewportMargin * 2;
  9585. let placement = {
  9586. anchor: preferredAnchor.value,
  9587. origin: preferredOrigin.value
  9588. };
  9589. function checkOverflow(_placement) {
  9590. const box = new Box(contentBox);
  9591. const targetPoint = anchorToPoint(_placement.anchor, targetBox);
  9592. const contentPoint = anchorToPoint(_placement.origin, box);
  9593. let {
  9594. x,
  9595. y
  9596. } = getOffset$1(targetPoint, contentPoint);
  9597. switch (_placement.anchor.side) {
  9598. case 'top':
  9599. y -= offset.value[0];
  9600. break;
  9601. case 'bottom':
  9602. y += offset.value[0];
  9603. break;
  9604. case 'left':
  9605. x -= offset.value[0];
  9606. break;
  9607. case 'right':
  9608. x += offset.value[0];
  9609. break;
  9610. }
  9611. switch (_placement.anchor.align) {
  9612. case 'top':
  9613. y -= offset.value[1];
  9614. break;
  9615. case 'bottom':
  9616. y += offset.value[1];
  9617. break;
  9618. case 'left':
  9619. x -= offset.value[1];
  9620. break;
  9621. case 'right':
  9622. x += offset.value[1];
  9623. break;
  9624. }
  9625. box.x += x;
  9626. box.y += y;
  9627. box.width = Math.min(box.width, maxWidth.value);
  9628. box.height = Math.min(box.height, maxHeight.value);
  9629. const overflows = getOverflow(box, viewport);
  9630. return {
  9631. overflows,
  9632. x,
  9633. y
  9634. };
  9635. }
  9636. let x = 0;
  9637. let y = 0;
  9638. const available = {
  9639. x: 0,
  9640. y: 0
  9641. };
  9642. const flipped = {
  9643. x: false,
  9644. y: false
  9645. };
  9646. let resets = -1;
  9647. while (true) {
  9648. if (resets++ > 10) {
  9649. consoleError('Infinite loop detected in connectedLocationStrategy');
  9650. break;
  9651. }
  9652. const {
  9653. x: _x,
  9654. y: _y,
  9655. overflows
  9656. } = checkOverflow(placement);
  9657. x += _x;
  9658. y += _y;
  9659. contentBox.x += _x;
  9660. contentBox.y += _y;
  9661. // flip
  9662. {
  9663. const axis = getAxis(placement.anchor);
  9664. const hasOverflowX = overflows.x.before || overflows.x.after;
  9665. const hasOverflowY = overflows.y.before || overflows.y.after;
  9666. let reset = false;
  9667. ['x', 'y'].forEach(key => {
  9668. if (key === 'x' && hasOverflowX && !flipped.x || key === 'y' && hasOverflowY && !flipped.y) {
  9669. const newPlacement = {
  9670. anchor: {
  9671. ...placement.anchor
  9672. },
  9673. origin: {
  9674. ...placement.origin
  9675. }
  9676. };
  9677. const flip = key === 'x' ? axis === 'y' ? flipAlign : flipSide : axis === 'y' ? flipSide : flipAlign;
  9678. newPlacement.anchor = flip(newPlacement.anchor);
  9679. newPlacement.origin = flip(newPlacement.origin);
  9680. const {
  9681. overflows: newOverflows
  9682. } = checkOverflow(newPlacement);
  9683. 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) {
  9684. placement = newPlacement;
  9685. reset = flipped[key] = true;
  9686. }
  9687. }
  9688. });
  9689. if (reset) continue;
  9690. }
  9691. // shift
  9692. if (overflows.x.before) {
  9693. x += overflows.x.before;
  9694. contentBox.x += overflows.x.before;
  9695. }
  9696. if (overflows.x.after) {
  9697. x -= overflows.x.after;
  9698. contentBox.x -= overflows.x.after;
  9699. }
  9700. if (overflows.y.before) {
  9701. y += overflows.y.before;
  9702. contentBox.y += overflows.y.before;
  9703. }
  9704. if (overflows.y.after) {
  9705. y -= overflows.y.after;
  9706. contentBox.y -= overflows.y.after;
  9707. }
  9708. // size
  9709. {
  9710. const overflows = getOverflow(contentBox, viewport);
  9711. available.x = viewport.width - overflows.x.before - overflows.x.after;
  9712. available.y = viewport.height - overflows.y.before - overflows.y.after;
  9713. x += overflows.x.before;
  9714. contentBox.x += overflows.x.before;
  9715. y += overflows.y.before;
  9716. contentBox.y += overflows.y.before;
  9717. }
  9718. break;
  9719. }
  9720. const axis = getAxis(placement.anchor);
  9721. Object.assign(contentStyles.value, {
  9722. '--v-overlay-anchor-origin': `${placement.anchor.side} ${placement.anchor.align}`,
  9723. transformOrigin: `${placement.origin.side} ${placement.origin.align}`,
  9724. // transform: `translate(${pixelRound(x)}px, ${pixelRound(y)}px)`,
  9725. top: convertToUnit(pixelRound(y)),
  9726. left: data.isRtl.value ? undefined : convertToUnit(pixelRound(x)),
  9727. right: data.isRtl.value ? convertToUnit(pixelRound(-x)) : undefined,
  9728. minWidth: convertToUnit(axis === 'y' ? Math.min(minWidth.value, targetBox.width) : minWidth.value),
  9729. maxWidth: convertToUnit(pixelCeil(clamp(available.x, minWidth.value === Infinity ? 0 : minWidth.value, maxWidth.value))),
  9730. maxHeight: convertToUnit(pixelCeil(clamp(available.y, minHeight.value === Infinity ? 0 : minHeight.value, maxHeight.value)))
  9731. });
  9732. return {
  9733. available,
  9734. contentBox
  9735. };
  9736. }
  9737. watch(() => [preferredAnchor.value, preferredOrigin.value, props.offset, props.minWidth, props.minHeight, props.maxWidth, props.maxHeight], () => updateLocation());
  9738. nextTick(() => {
  9739. const result = updateLocation();
  9740. // TODO: overflowing content should only require a single updateLocation call
  9741. // Icky hack to make sure the content is positioned consistently
  9742. if (!result) return;
  9743. const {
  9744. available,
  9745. contentBox
  9746. } = result;
  9747. if (contentBox.height > available.y) {
  9748. requestAnimationFrame(() => {
  9749. updateLocation();
  9750. requestAnimationFrame(() => {
  9751. updateLocation();
  9752. });
  9753. });
  9754. }
  9755. });
  9756. return {
  9757. updateLocation
  9758. };
  9759. }
  9760. function pixelRound(val) {
  9761. return Math.round(val * devicePixelRatio) / devicePixelRatio;
  9762. }
  9763. function pixelCeil(val) {
  9764. return Math.ceil(val * devicePixelRatio) / devicePixelRatio;
  9765. }
  9766. let clean = true;
  9767. const frames = [];
  9768. /**
  9769. * Schedule a task to run in an animation frame on its own
  9770. * This is useful for heavy tasks that may cause jank if all ran together
  9771. */
  9772. function requestNewFrame(cb) {
  9773. if (!clean || frames.length) {
  9774. frames.push(cb);
  9775. run();
  9776. } else {
  9777. clean = false;
  9778. cb();
  9779. run();
  9780. }
  9781. }
  9782. let raf = -1;
  9783. function run() {
  9784. cancelAnimationFrame(raf);
  9785. raf = requestAnimationFrame(() => {
  9786. const frame = frames.shift();
  9787. if (frame) frame();
  9788. if (frames.length) run();else clean = true;
  9789. });
  9790. }
  9791. // Utilities
  9792. // Types
  9793. const scrollStrategies = {
  9794. none: null,
  9795. close: closeScrollStrategy,
  9796. block: blockScrollStrategy,
  9797. reposition: repositionScrollStrategy
  9798. };
  9799. const makeScrollStrategyProps = propsFactory({
  9800. scrollStrategy: {
  9801. type: [String, Function],
  9802. default: 'block',
  9803. validator: val => typeof val === 'function' || val in scrollStrategies
  9804. }
  9805. }, 'VOverlay-scroll-strategies');
  9806. function useScrollStrategies(props, data) {
  9807. if (!IN_BROWSER) return;
  9808. let scope;
  9809. watchEffect(async () => {
  9810. scope?.stop();
  9811. if (!(data.isActive.value && props.scrollStrategy)) return;
  9812. scope = effectScope();
  9813. await new Promise(resolve => setTimeout(resolve));
  9814. scope.active && scope.run(() => {
  9815. if (typeof props.scrollStrategy === 'function') {
  9816. props.scrollStrategy(data, props, scope);
  9817. } else {
  9818. scrollStrategies[props.scrollStrategy]?.(data, props, scope);
  9819. }
  9820. });
  9821. });
  9822. onScopeDispose(() => {
  9823. scope?.stop();
  9824. });
  9825. }
  9826. function closeScrollStrategy(data) {
  9827. function onScroll(e) {
  9828. data.isActive.value = false;
  9829. }
  9830. bindScroll(data.targetEl.value ?? data.contentEl.value, onScroll);
  9831. }
  9832. function blockScrollStrategy(data, props) {
  9833. const offsetParent = data.root.value?.offsetParent;
  9834. const scrollElements = [...new Set([...getScrollParents(data.targetEl.value, props.contained ? offsetParent : undefined), ...getScrollParents(data.contentEl.value, props.contained ? offsetParent : undefined)])].filter(el => !el.classList.contains('v-overlay-scroll-blocked'));
  9835. const scrollbarWidth = window.innerWidth - document.documentElement.offsetWidth;
  9836. const scrollableParent = (el => hasScrollbar(el) && el)(offsetParent || document.documentElement);
  9837. if (scrollableParent) {
  9838. data.root.value.classList.add('v-overlay--scroll-blocked');
  9839. }
  9840. scrollElements.forEach((el, i) => {
  9841. el.style.setProperty('--v-body-scroll-x', convertToUnit(-el.scrollLeft));
  9842. el.style.setProperty('--v-body-scroll-y', convertToUnit(-el.scrollTop));
  9843. if (el !== document.documentElement) {
  9844. el.style.setProperty('--v-scrollbar-offset', convertToUnit(scrollbarWidth));
  9845. }
  9846. el.classList.add('v-overlay-scroll-blocked');
  9847. });
  9848. onScopeDispose(() => {
  9849. scrollElements.forEach((el, i) => {
  9850. const x = parseFloat(el.style.getPropertyValue('--v-body-scroll-x'));
  9851. const y = parseFloat(el.style.getPropertyValue('--v-body-scroll-y'));
  9852. const scrollBehavior = el.style.scrollBehavior;
  9853. el.style.scrollBehavior = 'auto';
  9854. el.style.removeProperty('--v-body-scroll-x');
  9855. el.style.removeProperty('--v-body-scroll-y');
  9856. el.style.removeProperty('--v-scrollbar-offset');
  9857. el.classList.remove('v-overlay-scroll-blocked');
  9858. el.scrollLeft = -x;
  9859. el.scrollTop = -y;
  9860. el.style.scrollBehavior = scrollBehavior;
  9861. });
  9862. if (scrollableParent) {
  9863. data.root.value.classList.remove('v-overlay--scroll-blocked');
  9864. }
  9865. });
  9866. }
  9867. function repositionScrollStrategy(data, props, scope) {
  9868. let slow = false;
  9869. let raf = -1;
  9870. let ric = -1;
  9871. function update(e) {
  9872. requestNewFrame(() => {
  9873. const start = performance.now();
  9874. data.updateLocation.value?.(e);
  9875. const time = performance.now() - start;
  9876. slow = time / (1000 / 60) > 2;
  9877. });
  9878. }
  9879. ric = (typeof requestIdleCallback === 'undefined' ? cb => cb() : requestIdleCallback)(() => {
  9880. scope.run(() => {
  9881. bindScroll(data.targetEl.value ?? data.contentEl.value, e => {
  9882. if (slow) {
  9883. // If the position calculation is slow,
  9884. // defer updates until scrolling is finished.
  9885. // Browsers usually fire one scroll event per frame so
  9886. // we just wait until we've got two frames without an event
  9887. cancelAnimationFrame(raf);
  9888. raf = requestAnimationFrame(() => {
  9889. raf = requestAnimationFrame(() => {
  9890. update(e);
  9891. });
  9892. });
  9893. } else {
  9894. update(e);
  9895. }
  9896. });
  9897. });
  9898. });
  9899. onScopeDispose(() => {
  9900. typeof cancelIdleCallback !== 'undefined' && cancelIdleCallback(ric);
  9901. cancelAnimationFrame(raf);
  9902. });
  9903. }
  9904. /** @private */
  9905. function bindScroll(el, onScroll) {
  9906. const scrollElements = [document, ...getScrollParents(el)];
  9907. scrollElements.forEach(el => {
  9908. el.addEventListener('scroll', onScroll, {
  9909. passive: true
  9910. });
  9911. });
  9912. onScopeDispose(() => {
  9913. scrollElements.forEach(el => {
  9914. el.removeEventListener('scroll', onScroll);
  9915. });
  9916. });
  9917. }
  9918. // Types
  9919. const VMenuSymbol = Symbol.for('vuetify:v-menu');
  9920. // Utilities
  9921. // Types
  9922. // Composables
  9923. const makeDelayProps = propsFactory({
  9924. closeDelay: [Number, String],
  9925. openDelay: [Number, String]
  9926. }, 'delay');
  9927. function useDelay(props, cb) {
  9928. let clearDelay = () => {};
  9929. function runDelay(isOpening) {
  9930. clearDelay?.();
  9931. const delay = Number(isOpening ? props.openDelay : props.closeDelay);
  9932. return new Promise(resolve => {
  9933. clearDelay = defer(delay, () => {
  9934. cb?.(isOpening);
  9935. resolve(isOpening);
  9936. });
  9937. });
  9938. }
  9939. function runOpenDelay() {
  9940. return runDelay(true);
  9941. }
  9942. function runCloseDelay() {
  9943. return runDelay(false);
  9944. }
  9945. return {
  9946. clearDelay,
  9947. runOpenDelay,
  9948. runCloseDelay
  9949. };
  9950. }
  9951. // Components
  9952. // Types
  9953. const makeActivatorProps = propsFactory({
  9954. target: [String, Object],
  9955. activator: [String, Object],
  9956. activatorProps: {
  9957. type: Object,
  9958. default: () => ({})
  9959. },
  9960. openOnClick: {
  9961. type: Boolean,
  9962. default: undefined
  9963. },
  9964. openOnHover: Boolean,
  9965. openOnFocus: {
  9966. type: Boolean,
  9967. default: undefined
  9968. },
  9969. closeOnContentClick: Boolean,
  9970. ...makeDelayProps()
  9971. }, 'VOverlay-activator');
  9972. function useActivator(props, _ref) {
  9973. let {
  9974. isActive,
  9975. isTop,
  9976. contentEl
  9977. } = _ref;
  9978. const vm = getCurrentInstance('useActivator');
  9979. const activatorEl = ref();
  9980. let isHovered = false;
  9981. let isFocused = false;
  9982. let firstEnter = true;
  9983. const openOnFocus = computed(() => props.openOnFocus || props.openOnFocus == null && props.openOnHover);
  9984. const openOnClick = computed(() => props.openOnClick || props.openOnClick == null && !props.openOnHover && !openOnFocus.value);
  9985. const {
  9986. runOpenDelay,
  9987. runCloseDelay
  9988. } = useDelay(props, value => {
  9989. if (value === (props.openOnHover && isHovered || openOnFocus.value && isFocused) && !(props.openOnHover && isActive.value && !isTop.value)) {
  9990. if (isActive.value !== value) {
  9991. firstEnter = true;
  9992. }
  9993. isActive.value = value;
  9994. }
  9995. });
  9996. const cursorTarget = ref();
  9997. const availableEvents = {
  9998. onClick: e => {
  9999. e.stopPropagation();
  10000. activatorEl.value = e.currentTarget || e.target;
  10001. if (!isActive.value) {
  10002. cursorTarget.value = [e.clientX, e.clientY];
  10003. }
  10004. isActive.value = !isActive.value;
  10005. },
  10006. onMouseenter: e => {
  10007. if (e.sourceCapabilities?.firesTouchEvents) return;
  10008. isHovered = true;
  10009. activatorEl.value = e.currentTarget || e.target;
  10010. runOpenDelay();
  10011. },
  10012. onMouseleave: e => {
  10013. isHovered = false;
  10014. runCloseDelay();
  10015. },
  10016. onFocus: e => {
  10017. if (matchesSelector(e.target, ':focus-visible') === false) return;
  10018. isFocused = true;
  10019. e.stopPropagation();
  10020. activatorEl.value = e.currentTarget || e.target;
  10021. runOpenDelay();
  10022. },
  10023. onBlur: e => {
  10024. isFocused = false;
  10025. e.stopPropagation();
  10026. runCloseDelay();
  10027. }
  10028. };
  10029. const activatorEvents = computed(() => {
  10030. const events = {};
  10031. if (openOnClick.value) {
  10032. events.onClick = availableEvents.onClick;
  10033. }
  10034. if (props.openOnHover) {
  10035. events.onMouseenter = availableEvents.onMouseenter;
  10036. events.onMouseleave = availableEvents.onMouseleave;
  10037. }
  10038. if (openOnFocus.value) {
  10039. events.onFocus = availableEvents.onFocus;
  10040. events.onBlur = availableEvents.onBlur;
  10041. }
  10042. return events;
  10043. });
  10044. const contentEvents = computed(() => {
  10045. const events = {};
  10046. if (props.openOnHover) {
  10047. events.onMouseenter = () => {
  10048. isHovered = true;
  10049. runOpenDelay();
  10050. };
  10051. events.onMouseleave = () => {
  10052. isHovered = false;
  10053. runCloseDelay();
  10054. };
  10055. }
  10056. if (openOnFocus.value) {
  10057. events.onFocusin = () => {
  10058. isFocused = true;
  10059. runOpenDelay();
  10060. };
  10061. events.onFocusout = () => {
  10062. isFocused = false;
  10063. runCloseDelay();
  10064. };
  10065. }
  10066. if (props.closeOnContentClick) {
  10067. const menu = inject$1(VMenuSymbol, null);
  10068. events.onClick = () => {
  10069. isActive.value = false;
  10070. menu?.closeParents();
  10071. };
  10072. }
  10073. return events;
  10074. });
  10075. const scrimEvents = computed(() => {
  10076. const events = {};
  10077. if (props.openOnHover) {
  10078. events.onMouseenter = () => {
  10079. if (firstEnter) {
  10080. isHovered = true;
  10081. firstEnter = false;
  10082. runOpenDelay();
  10083. }
  10084. };
  10085. events.onMouseleave = () => {
  10086. isHovered = false;
  10087. runCloseDelay();
  10088. };
  10089. }
  10090. return events;
  10091. });
  10092. watch(isTop, val => {
  10093. if (val && (props.openOnHover && !isHovered && (!openOnFocus.value || !isFocused) || openOnFocus.value && !isFocused && (!props.openOnHover || !isHovered)) && !contentEl.value?.contains(document.activeElement)) {
  10094. isActive.value = false;
  10095. }
  10096. });
  10097. watch(isActive, val => {
  10098. if (!val) {
  10099. setTimeout(() => {
  10100. cursorTarget.value = undefined;
  10101. });
  10102. }
  10103. }, {
  10104. flush: 'post'
  10105. });
  10106. const activatorRef = templateRef();
  10107. watchEffect(() => {
  10108. if (!activatorRef.value) return;
  10109. nextTick(() => {
  10110. activatorEl.value = activatorRef.el;
  10111. });
  10112. });
  10113. const targetRef = templateRef();
  10114. const target = computed(() => {
  10115. if (props.target === 'cursor' && cursorTarget.value) return cursorTarget.value;
  10116. if (targetRef.value) return targetRef.el;
  10117. return getTarget(props.target, vm) || activatorEl.value;
  10118. });
  10119. const targetEl = computed(() => {
  10120. return Array.isArray(target.value) ? undefined : target.value;
  10121. });
  10122. let scope;
  10123. watch(() => !!props.activator, val => {
  10124. if (val && IN_BROWSER) {
  10125. scope = effectScope();
  10126. scope.run(() => {
  10127. _useActivator(props, vm, {
  10128. activatorEl,
  10129. activatorEvents
  10130. });
  10131. });
  10132. } else if (scope) {
  10133. scope.stop();
  10134. }
  10135. }, {
  10136. flush: 'post',
  10137. immediate: true
  10138. });
  10139. onScopeDispose(() => {
  10140. scope?.stop();
  10141. });
  10142. return {
  10143. activatorEl,
  10144. activatorRef,
  10145. target,
  10146. targetEl,
  10147. targetRef,
  10148. activatorEvents,
  10149. contentEvents,
  10150. scrimEvents
  10151. };
  10152. }
  10153. function _useActivator(props, vm, _ref2) {
  10154. let {
  10155. activatorEl,
  10156. activatorEvents
  10157. } = _ref2;
  10158. watch(() => props.activator, (val, oldVal) => {
  10159. if (oldVal && val !== oldVal) {
  10160. const activator = getActivator(oldVal);
  10161. activator && unbindActivatorProps(activator);
  10162. }
  10163. if (val) {
  10164. nextTick(() => bindActivatorProps());
  10165. }
  10166. }, {
  10167. immediate: true
  10168. });
  10169. watch(() => props.activatorProps, () => {
  10170. bindActivatorProps();
  10171. });
  10172. onScopeDispose(() => {
  10173. unbindActivatorProps();
  10174. });
  10175. function bindActivatorProps() {
  10176. let el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getActivator();
  10177. let _props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.activatorProps;
  10178. if (!el) return;
  10179. bindProps(el, mergeProps(activatorEvents.value, _props));
  10180. }
  10181. function unbindActivatorProps() {
  10182. let el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getActivator();
  10183. let _props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.activatorProps;
  10184. if (!el) return;
  10185. unbindProps(el, mergeProps(activatorEvents.value, _props));
  10186. }
  10187. function getActivator() {
  10188. let selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : props.activator;
  10189. const activator = getTarget(selector, vm);
  10190. // The activator should only be a valid element (Ignore comments and text nodes)
  10191. activatorEl.value = activator?.nodeType === Node.ELEMENT_NODE ? activator : undefined;
  10192. return activatorEl.value;
  10193. }
  10194. }
  10195. function getTarget(selector, vm) {
  10196. if (!selector) return;
  10197. let target;
  10198. if (selector === 'parent') {
  10199. let el = vm?.proxy?.$el?.parentNode;
  10200. while (el?.hasAttribute('data-no-activator')) {
  10201. el = el.parentNode;
  10202. }
  10203. target = el;
  10204. } else if (typeof selector === 'string') {
  10205. // Selector
  10206. target = document.querySelector(selector);
  10207. } else if ('$el' in selector) {
  10208. // Component (ref)
  10209. target = selector.$el;
  10210. } else {
  10211. // HTMLElement | Element | [x, y]
  10212. target = selector;
  10213. }
  10214. return target;
  10215. }
  10216. // Composables
  10217. function useHydration() {
  10218. if (!IN_BROWSER) return shallowRef(false);
  10219. const {
  10220. ssr
  10221. } = useDisplay();
  10222. if (ssr) {
  10223. const isMounted = shallowRef(false);
  10224. onMounted(() => {
  10225. isMounted.value = true;
  10226. });
  10227. return isMounted;
  10228. } else {
  10229. return shallowRef(true);
  10230. }
  10231. }
  10232. // Utilities
  10233. // Types
  10234. const makeLazyProps = propsFactory({
  10235. eager: Boolean
  10236. }, 'lazy');
  10237. function useLazy(props, active) {
  10238. const isBooted = shallowRef(false);
  10239. const hasContent = computed(() => isBooted.value || props.eager || active.value);
  10240. watch(active, () => isBooted.value = true);
  10241. function onAfterLeave() {
  10242. if (!props.eager) isBooted.value = false;
  10243. }
  10244. return {
  10245. isBooted,
  10246. hasContent,
  10247. onAfterLeave
  10248. };
  10249. }
  10250. // Utilities
  10251. function useScopeId() {
  10252. const vm = getCurrentInstance('useScopeId');
  10253. const scopeId = vm.vnode.scopeId;
  10254. return {
  10255. scopeId: scopeId ? {
  10256. [scopeId]: ''
  10257. } : undefined
  10258. };
  10259. }
  10260. // Composables
  10261. // Types
  10262. const StackSymbol = Symbol.for('vuetify:stack');
  10263. const globalStack = reactive([]);
  10264. function useStack(isActive, zIndex, disableGlobalStack) {
  10265. const vm = getCurrentInstance('useStack');
  10266. const createStackEntry = !disableGlobalStack;
  10267. const parent = inject$1(StackSymbol, undefined);
  10268. const stack = reactive({
  10269. activeChildren: new Set()
  10270. });
  10271. provide(StackSymbol, stack);
  10272. const _zIndex = shallowRef(+zIndex.value);
  10273. useToggleScope(isActive, () => {
  10274. const lastZIndex = globalStack.at(-1)?.[1];
  10275. _zIndex.value = lastZIndex ? lastZIndex + 10 : +zIndex.value;
  10276. if (createStackEntry) {
  10277. globalStack.push([vm.uid, _zIndex.value]);
  10278. }
  10279. parent?.activeChildren.add(vm.uid);
  10280. onScopeDispose(() => {
  10281. if (createStackEntry) {
  10282. const idx = toRaw(globalStack).findIndex(v => v[0] === vm.uid);
  10283. globalStack.splice(idx, 1);
  10284. }
  10285. parent?.activeChildren.delete(vm.uid);
  10286. });
  10287. });
  10288. const globalTop = shallowRef(true);
  10289. if (createStackEntry) {
  10290. watchEffect(() => {
  10291. const _isTop = globalStack.at(-1)?.[0] === vm.uid;
  10292. setTimeout(() => globalTop.value = _isTop);
  10293. });
  10294. }
  10295. const localTop = computed(() => !stack.activeChildren.size);
  10296. return {
  10297. globalTop: readonly(globalTop),
  10298. localTop,
  10299. stackStyles: computed(() => ({
  10300. zIndex: _zIndex.value
  10301. }))
  10302. };
  10303. }
  10304. // Utilities
  10305. function useTeleport(target) {
  10306. const teleportTarget = computed(() => {
  10307. const _target = target();
  10308. if (_target === true || !IN_BROWSER) return undefined;
  10309. const targetElement = _target === false ? document.body : typeof _target === 'string' ? document.querySelector(_target) : _target;
  10310. if (targetElement == null) {
  10311. warn(`Unable to locate target ${_target}`);
  10312. return undefined;
  10313. }
  10314. let container = [...targetElement.children].find(el => el.matches('.v-overlay-container'));
  10315. if (!container) {
  10316. container = document.createElement('div');
  10317. container.className = 'v-overlay-container';
  10318. targetElement.appendChild(container);
  10319. }
  10320. return container;
  10321. });
  10322. return {
  10323. teleportTarget
  10324. };
  10325. }
  10326. // Utilities
  10327. // Types
  10328. function defaultConditional() {
  10329. return true;
  10330. }
  10331. function checkEvent(e, el, binding) {
  10332. // The include element callbacks below can be expensive
  10333. // so we should avoid calling them when we're not active.
  10334. // Explicitly check for false to allow fallback compatibility
  10335. // with non-toggleable components
  10336. if (!e || checkIsActive(e, binding) === false) return false;
  10337. // If we're clicking inside the shadowroot, then the app root doesn't get the same
  10338. // level of introspection as to _what_ we're clicking. We want to check to see if
  10339. // our target is the shadowroot parent container, and if it is, ignore.
  10340. const root = attachedRoot(el);
  10341. if (typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot && root.host === e.target) return false;
  10342. // Check if additional elements were passed to be included in check
  10343. // (click must be outside all included elements, if any)
  10344. const elements = (typeof binding.value === 'object' && binding.value.include || (() => []))();
  10345. // Add the root element for the component this directive was defined on
  10346. elements.push(el);
  10347. // Check if it's a click outside our elements, and then if our callback returns true.
  10348. // Non-toggleable components should take action in their callback and return falsy.
  10349. // Toggleable can return true if it wants to deactivate.
  10350. // Note that, because we're in the capture phase, this callback will occur before
  10351. // the bubbling click event on any outside elements.
  10352. return !elements.some(el => el?.contains(e.target));
  10353. }
  10354. function checkIsActive(e, binding) {
  10355. const isActive = typeof binding.value === 'object' && binding.value.closeConditional || defaultConditional;
  10356. return isActive(e);
  10357. }
  10358. function directive(e, el, binding) {
  10359. const handler = typeof binding.value === 'function' ? binding.value : binding.value.handler;
  10360. // Clicks in the Shadow DOM change their target while using setTimeout, so the original target is saved here
  10361. e.shadowTarget = e.target;
  10362. el._clickOutside.lastMousedownWasOutside && checkEvent(e, el, binding) && setTimeout(() => {
  10363. checkIsActive(e, binding) && handler && handler(e);
  10364. }, 0);
  10365. }
  10366. function handleShadow(el, callback) {
  10367. const root = attachedRoot(el);
  10368. callback(document);
  10369. if (typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot) {
  10370. callback(root);
  10371. }
  10372. }
  10373. const ClickOutside = {
  10374. // [data-app] may not be found
  10375. // if using bind, inserted makes
  10376. // sure that the root element is
  10377. // available, iOS does not support
  10378. // clicks on body
  10379. mounted(el, binding) {
  10380. const onClick = e => directive(e, el, binding);
  10381. const onMousedown = e => {
  10382. el._clickOutside.lastMousedownWasOutside = checkEvent(e, el, binding);
  10383. };
  10384. handleShadow(el, app => {
  10385. app.addEventListener('click', onClick, true);
  10386. app.addEventListener('mousedown', onMousedown, true);
  10387. });
  10388. if (!el._clickOutside) {
  10389. el._clickOutside = {
  10390. lastMousedownWasOutside: false
  10391. };
  10392. }
  10393. el._clickOutside[binding.instance.$.uid] = {
  10394. onClick,
  10395. onMousedown
  10396. };
  10397. },
  10398. beforeUnmount(el, binding) {
  10399. if (!el._clickOutside) return;
  10400. handleShadow(el, app => {
  10401. if (!app || !el._clickOutside?.[binding.instance.$.uid]) return;
  10402. const {
  10403. onClick,
  10404. onMousedown
  10405. } = el._clickOutside[binding.instance.$.uid];
  10406. app.removeEventListener('click', onClick, true);
  10407. app.removeEventListener('mousedown', onMousedown, true);
  10408. });
  10409. delete el._clickOutside[binding.instance.$.uid];
  10410. }
  10411. };
  10412. // Types
  10413. function Scrim(props) {
  10414. const {
  10415. modelValue,
  10416. color,
  10417. ...rest
  10418. } = props;
  10419. return createVNode(Transition, {
  10420. "name": "fade-transition",
  10421. "appear": true
  10422. }, {
  10423. default: () => [props.modelValue && createVNode("div", mergeProps({
  10424. "class": ['v-overlay__scrim', props.color.backgroundColorClasses.value],
  10425. "style": props.color.backgroundColorStyles.value
  10426. }, rest), null)]
  10427. });
  10428. }
  10429. const makeVOverlayProps = propsFactory({
  10430. absolute: Boolean,
  10431. attach: [Boolean, String, Object],
  10432. closeOnBack: {
  10433. type: Boolean,
  10434. default: true
  10435. },
  10436. contained: Boolean,
  10437. contentClass: null,
  10438. contentProps: null,
  10439. disabled: Boolean,
  10440. opacity: [Number, String],
  10441. noClickAnimation: Boolean,
  10442. modelValue: Boolean,
  10443. persistent: Boolean,
  10444. scrim: {
  10445. type: [Boolean, String],
  10446. default: true
  10447. },
  10448. zIndex: {
  10449. type: [Number, String],
  10450. default: 2000
  10451. },
  10452. ...makeActivatorProps(),
  10453. ...makeComponentProps(),
  10454. ...makeDimensionProps(),
  10455. ...makeLazyProps(),
  10456. ...makeLocationStrategyProps(),
  10457. ...makeScrollStrategyProps(),
  10458. ...makeThemeProps(),
  10459. ...makeTransitionProps()
  10460. }, 'VOverlay');
  10461. const VOverlay = genericComponent()({
  10462. name: 'VOverlay',
  10463. directives: {
  10464. ClickOutside
  10465. },
  10466. inheritAttrs: false,
  10467. props: {
  10468. _disableGlobalStack: Boolean,
  10469. ...makeVOverlayProps()
  10470. },
  10471. emits: {
  10472. 'click:outside': e => true,
  10473. 'update:modelValue': value => true,
  10474. afterEnter: () => true,
  10475. afterLeave: () => true
  10476. },
  10477. setup(props, _ref) {
  10478. let {
  10479. slots,
  10480. attrs,
  10481. emit
  10482. } = _ref;
  10483. const vm = getCurrentInstance('VOverlay');
  10484. const root = ref();
  10485. const scrimEl = ref();
  10486. const contentEl = ref();
  10487. const model = useProxiedModel(props, 'modelValue');
  10488. const isActive = computed({
  10489. get: () => model.value,
  10490. set: v => {
  10491. if (!(v && props.disabled)) model.value = v;
  10492. }
  10493. });
  10494. const {
  10495. themeClasses
  10496. } = provideTheme(props);
  10497. const {
  10498. rtlClasses,
  10499. isRtl
  10500. } = useRtl();
  10501. const {
  10502. hasContent,
  10503. onAfterLeave: _onAfterLeave
  10504. } = useLazy(props, isActive);
  10505. const scrimColor = useBackgroundColor(computed(() => {
  10506. return typeof props.scrim === 'string' ? props.scrim : null;
  10507. }));
  10508. const {
  10509. globalTop,
  10510. localTop,
  10511. stackStyles
  10512. } = useStack(isActive, toRef(props, 'zIndex'), props._disableGlobalStack);
  10513. const {
  10514. activatorEl,
  10515. activatorRef,
  10516. target,
  10517. targetEl,
  10518. targetRef,
  10519. activatorEvents,
  10520. contentEvents,
  10521. scrimEvents
  10522. } = useActivator(props, {
  10523. isActive,
  10524. isTop: localTop,
  10525. contentEl
  10526. });
  10527. const {
  10528. teleportTarget
  10529. } = useTeleport(() => {
  10530. const target = props.attach || props.contained;
  10531. if (target) return target;
  10532. const rootNode = activatorEl?.value?.getRootNode() || vm.proxy?.$el?.getRootNode();
  10533. if (rootNode instanceof ShadowRoot) return rootNode;
  10534. return false;
  10535. });
  10536. const {
  10537. dimensionStyles
  10538. } = useDimension(props);
  10539. const isMounted = useHydration();
  10540. const {
  10541. scopeId
  10542. } = useScopeId();
  10543. watch(() => props.disabled, v => {
  10544. if (v) isActive.value = false;
  10545. });
  10546. const {
  10547. contentStyles,
  10548. updateLocation
  10549. } = useLocationStrategies(props, {
  10550. isRtl,
  10551. contentEl,
  10552. target,
  10553. isActive
  10554. });
  10555. useScrollStrategies(props, {
  10556. root,
  10557. contentEl,
  10558. targetEl,
  10559. isActive,
  10560. updateLocation
  10561. });
  10562. function onClickOutside(e) {
  10563. emit('click:outside', e);
  10564. if (!props.persistent) isActive.value = false;else animateClick();
  10565. }
  10566. function closeConditional(e) {
  10567. return isActive.value && globalTop.value && (
  10568. // If using scrim, only close if clicking on it rather than anything opened on top
  10569. !props.scrim || e.target === scrimEl.value || e instanceof MouseEvent && e.shadowTarget === scrimEl.value);
  10570. }
  10571. IN_BROWSER && watch(isActive, val => {
  10572. if (val) {
  10573. window.addEventListener('keydown', onKeydown);
  10574. } else {
  10575. window.removeEventListener('keydown', onKeydown);
  10576. }
  10577. }, {
  10578. immediate: true
  10579. });
  10580. onBeforeUnmount(() => {
  10581. if (!IN_BROWSER) return;
  10582. window.removeEventListener('keydown', onKeydown);
  10583. });
  10584. function onKeydown(e) {
  10585. if (e.key === 'Escape' && globalTop.value) {
  10586. if (!props.persistent) {
  10587. isActive.value = false;
  10588. if (contentEl.value?.contains(document.activeElement)) {
  10589. activatorEl.value?.focus();
  10590. }
  10591. } else animateClick();
  10592. }
  10593. }
  10594. const router = useRouter();
  10595. useToggleScope(() => props.closeOnBack, () => {
  10596. useBackButton(router, next => {
  10597. if (globalTop.value && isActive.value) {
  10598. next(false);
  10599. if (!props.persistent) isActive.value = false;else animateClick();
  10600. } else {
  10601. next();
  10602. }
  10603. });
  10604. });
  10605. const top = ref();
  10606. watch(() => isActive.value && (props.absolute || props.contained) && teleportTarget.value == null, val => {
  10607. if (val) {
  10608. const scrollParent = getScrollParent(root.value);
  10609. if (scrollParent && scrollParent !== document.scrollingElement) {
  10610. top.value = scrollParent.scrollTop;
  10611. }
  10612. }
  10613. });
  10614. // Add a quick "bounce" animation to the content
  10615. function animateClick() {
  10616. if (props.noClickAnimation) return;
  10617. contentEl.value && animate(contentEl.value, [{
  10618. transformOrigin: 'center'
  10619. }, {
  10620. transform: 'scale(1.03)'
  10621. }, {
  10622. transformOrigin: 'center'
  10623. }], {
  10624. duration: 150,
  10625. easing: standardEasing
  10626. });
  10627. }
  10628. function onAfterEnter() {
  10629. emit('afterEnter');
  10630. }
  10631. function onAfterLeave() {
  10632. _onAfterLeave();
  10633. emit('afterLeave');
  10634. }
  10635. useRender(() => createVNode(Fragment, null, [slots.activator?.({
  10636. isActive: isActive.value,
  10637. targetRef,
  10638. props: mergeProps({
  10639. ref: activatorRef
  10640. }, activatorEvents.value, props.activatorProps)
  10641. }), isMounted.value && hasContent.value && createVNode(Teleport, {
  10642. "disabled": !teleportTarget.value,
  10643. "to": teleportTarget.value
  10644. }, {
  10645. default: () => [createVNode("div", mergeProps({
  10646. "class": ['v-overlay', {
  10647. 'v-overlay--absolute': props.absolute || props.contained,
  10648. 'v-overlay--active': isActive.value,
  10649. 'v-overlay--contained': props.contained
  10650. }, themeClasses.value, rtlClasses.value, props.class],
  10651. "style": [stackStyles.value, {
  10652. '--v-overlay-opacity': props.opacity,
  10653. top: convertToUnit(top.value)
  10654. }, props.style],
  10655. "ref": root
  10656. }, scopeId, attrs), [createVNode(Scrim, mergeProps({
  10657. "color": scrimColor,
  10658. "modelValue": isActive.value && !!props.scrim,
  10659. "ref": scrimEl
  10660. }, scrimEvents.value), null), createVNode(MaybeTransition, {
  10661. "appear": true,
  10662. "persisted": true,
  10663. "transition": props.transition,
  10664. "target": target.value,
  10665. "onAfterEnter": onAfterEnter,
  10666. "onAfterLeave": onAfterLeave
  10667. }, {
  10668. default: () => [withDirectives(createVNode("div", mergeProps({
  10669. "ref": contentEl,
  10670. "class": ['v-overlay__content', props.contentClass],
  10671. "style": [dimensionStyles.value, contentStyles.value]
  10672. }, contentEvents.value, props.contentProps), [slots.default?.({
  10673. isActive
  10674. })]), [[vShow, isActive.value], [resolveDirective("click-outside"), {
  10675. handler: onClickOutside,
  10676. closeConditional,
  10677. include: () => [activatorEl.value]
  10678. }]])]
  10679. })])]
  10680. })]));
  10681. return {
  10682. activatorEl,
  10683. scrimEl,
  10684. target,
  10685. animateClick,
  10686. contentEl,
  10687. globalTop,
  10688. localTop,
  10689. updateLocation
  10690. };
  10691. }
  10692. });
  10693. // Types
  10694. const Refs = Symbol('Forwarded refs');
  10695. /** Omit properties starting with P */
  10696. /** Omit keyof $props from T */
  10697. function getDescriptor(obj, key) {
  10698. let currentObj = obj;
  10699. while (currentObj) {
  10700. const descriptor = Reflect.getOwnPropertyDescriptor(currentObj, key);
  10701. if (descriptor) return descriptor;
  10702. currentObj = Object.getPrototypeOf(currentObj);
  10703. }
  10704. return undefined;
  10705. }
  10706. function forwardRefs(target) {
  10707. for (var _len = arguments.length, refs = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  10708. refs[_key - 1] = arguments[_key];
  10709. }
  10710. target[Refs] = refs;
  10711. return new Proxy(target, {
  10712. get(target, key) {
  10713. if (Reflect.has(target, key)) {
  10714. return Reflect.get(target, key);
  10715. }
  10716. // Skip internal properties
  10717. if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return;
  10718. for (const ref of refs) {
  10719. if (ref.value && Reflect.has(ref.value, key)) {
  10720. const val = Reflect.get(ref.value, key);
  10721. return typeof val === 'function' ? val.bind(ref.value) : val;
  10722. }
  10723. }
  10724. },
  10725. has(target, key) {
  10726. if (Reflect.has(target, key)) {
  10727. return true;
  10728. }
  10729. // Skip internal properties
  10730. if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return false;
  10731. for (const ref of refs) {
  10732. if (ref.value && Reflect.has(ref.value, key)) {
  10733. return true;
  10734. }
  10735. }
  10736. return false;
  10737. },
  10738. set(target, key, value) {
  10739. if (Reflect.has(target, key)) {
  10740. return Reflect.set(target, key, value);
  10741. }
  10742. // Skip internal properties
  10743. if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return false;
  10744. for (const ref of refs) {
  10745. if (ref.value && Reflect.has(ref.value, key)) {
  10746. return Reflect.set(ref.value, key, value);
  10747. }
  10748. }
  10749. return false;
  10750. },
  10751. getOwnPropertyDescriptor(target, key) {
  10752. const descriptor = Reflect.getOwnPropertyDescriptor(target, key);
  10753. if (descriptor) return descriptor;
  10754. // Skip internal properties
  10755. if (typeof key === 'symbol' || key.startsWith('$') || key.startsWith('__')) return;
  10756. // Check each ref's own properties
  10757. for (const ref of refs) {
  10758. if (!ref.value) continue;
  10759. const descriptor = getDescriptor(ref.value, key) ?? ('_' in ref.value ? getDescriptor(ref.value._?.setupState, key) : undefined);
  10760. if (descriptor) return descriptor;
  10761. }
  10762. // Recursive search up each ref's prototype
  10763. for (const ref of refs) {
  10764. const childRefs = ref.value && ref.value[Refs];
  10765. if (!childRefs) continue;
  10766. const queue = childRefs.slice();
  10767. while (queue.length) {
  10768. const ref = queue.shift();
  10769. const descriptor = getDescriptor(ref.value, key);
  10770. if (descriptor) return descriptor;
  10771. const childRefs = ref.value && ref.value[Refs];
  10772. if (childRefs) queue.push(...childRefs);
  10773. }
  10774. }
  10775. return undefined;
  10776. }
  10777. });
  10778. }
  10779. // Types
  10780. const makeVMenuProps = propsFactory({
  10781. // TODO
  10782. // disableKeys: Boolean,
  10783. id: String,
  10784. submenu: Boolean,
  10785. ...omit(makeVOverlayProps({
  10786. closeDelay: 250,
  10787. closeOnContentClick: true,
  10788. locationStrategy: 'connected',
  10789. location: undefined,
  10790. openDelay: 300,
  10791. scrim: false,
  10792. scrollStrategy: 'reposition',
  10793. transition: {
  10794. component: VDialogTransition
  10795. }
  10796. }), ['absolute'])
  10797. }, 'VMenu');
  10798. const VMenu = genericComponent()({
  10799. name: 'VMenu',
  10800. props: makeVMenuProps(),
  10801. emits: {
  10802. 'update:modelValue': value => true
  10803. },
  10804. setup(props, _ref) {
  10805. let {
  10806. slots
  10807. } = _ref;
  10808. const isActive = useProxiedModel(props, 'modelValue');
  10809. const {
  10810. scopeId
  10811. } = useScopeId();
  10812. const {
  10813. isRtl
  10814. } = useRtl();
  10815. const uid = getUid();
  10816. const id = computed(() => props.id || `v-menu-${uid}`);
  10817. const overlay = ref();
  10818. const parent = inject$1(VMenuSymbol, null);
  10819. const openChildren = shallowRef(new Set());
  10820. provide(VMenuSymbol, {
  10821. register() {
  10822. openChildren.value.add(uid);
  10823. },
  10824. unregister() {
  10825. openChildren.value.delete(uid);
  10826. },
  10827. closeParents(e) {
  10828. setTimeout(() => {
  10829. if (!openChildren.value.size && !props.persistent && (e == null || overlay.value?.contentEl && !isClickInsideElement(e, overlay.value.contentEl))) {
  10830. isActive.value = false;
  10831. parent?.closeParents();
  10832. }
  10833. }, 40);
  10834. }
  10835. });
  10836. onBeforeUnmount(() => {
  10837. parent?.unregister();
  10838. document.removeEventListener('focusin', onFocusIn);
  10839. });
  10840. onDeactivated(() => isActive.value = false);
  10841. async function onFocusIn(e) {
  10842. const before = e.relatedTarget;
  10843. const after = e.target;
  10844. await nextTick();
  10845. if (isActive.value && before !== after && overlay.value?.contentEl &&
  10846. // We're the topmost menu
  10847. overlay.value?.globalTop &&
  10848. // It isn't the document or the menu body
  10849. ![document, overlay.value.contentEl].includes(after) &&
  10850. // It isn't inside the menu body
  10851. !overlay.value.contentEl.contains(after)) {
  10852. const focusable = focusableChildren(overlay.value.contentEl);
  10853. focusable[0]?.focus();
  10854. }
  10855. }
  10856. watch(isActive, val => {
  10857. if (val) {
  10858. parent?.register();
  10859. if (IN_BROWSER) {
  10860. document.addEventListener('focusin', onFocusIn, {
  10861. once: true
  10862. });
  10863. }
  10864. } else {
  10865. parent?.unregister();
  10866. if (IN_BROWSER) {
  10867. document.removeEventListener('focusin', onFocusIn);
  10868. }
  10869. }
  10870. }, {
  10871. immediate: true
  10872. });
  10873. function onClickOutside(e) {
  10874. parent?.closeParents(e);
  10875. }
  10876. function onKeydown(e) {
  10877. if (props.disabled) return;
  10878. if (e.key === 'Tab' || e.key === 'Enter' && !props.closeOnContentClick) {
  10879. if (e.key === 'Enter' && (e.target instanceof HTMLTextAreaElement || e.target instanceof HTMLInputElement && !!e.target.closest('form'))) return;
  10880. if (e.key === 'Enter') e.preventDefault();
  10881. const nextElement = getNextElement(focusableChildren(overlay.value?.contentEl, false), e.shiftKey ? 'prev' : 'next', el => el.tabIndex >= 0);
  10882. if (!nextElement) {
  10883. isActive.value = false;
  10884. overlay.value?.activatorEl?.focus();
  10885. }
  10886. } else if (props.submenu && e.key === (isRtl.value ? 'ArrowRight' : 'ArrowLeft')) {
  10887. isActive.value = false;
  10888. overlay.value?.activatorEl?.focus();
  10889. }
  10890. }
  10891. function onActivatorKeydown(e) {
  10892. if (props.disabled) return;
  10893. const el = overlay.value?.contentEl;
  10894. if (el && isActive.value) {
  10895. if (e.key === 'ArrowDown') {
  10896. e.preventDefault();
  10897. e.stopImmediatePropagation();
  10898. focusChild(el, 'next');
  10899. } else if (e.key === 'ArrowUp') {
  10900. e.preventDefault();
  10901. e.stopImmediatePropagation();
  10902. focusChild(el, 'prev');
  10903. } else if (props.submenu) {
  10904. if (e.key === (isRtl.value ? 'ArrowRight' : 'ArrowLeft')) {
  10905. isActive.value = false;
  10906. } else if (e.key === (isRtl.value ? 'ArrowLeft' : 'ArrowRight')) {
  10907. e.preventDefault();
  10908. focusChild(el, 'first');
  10909. }
  10910. }
  10911. } else if (props.submenu ? e.key === (isRtl.value ? 'ArrowLeft' : 'ArrowRight') : ['ArrowDown', 'ArrowUp'].includes(e.key)) {
  10912. isActive.value = true;
  10913. e.preventDefault();
  10914. setTimeout(() => setTimeout(() => onActivatorKeydown(e)));
  10915. }
  10916. }
  10917. const activatorProps = computed(() => mergeProps({
  10918. 'aria-haspopup': 'menu',
  10919. 'aria-expanded': String(isActive.value),
  10920. 'aria-owns': id.value,
  10921. onKeydown: onActivatorKeydown
  10922. }, props.activatorProps));
  10923. useRender(() => {
  10924. const overlayProps = VOverlay.filterProps(props);
  10925. return createVNode(VOverlay, mergeProps({
  10926. "ref": overlay,
  10927. "id": id.value,
  10928. "class": ['v-menu', props.class],
  10929. "style": props.style
  10930. }, overlayProps, {
  10931. "modelValue": isActive.value,
  10932. "onUpdate:modelValue": $event => isActive.value = $event,
  10933. "absolute": true,
  10934. "activatorProps": activatorProps.value,
  10935. "location": props.location ?? (props.submenu ? 'end' : 'bottom'),
  10936. "onClick:outside": onClickOutside,
  10937. "onKeydown": onKeydown
  10938. }, scopeId), {
  10939. activator: slots.activator,
  10940. default: function () {
  10941. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  10942. args[_key] = arguments[_key];
  10943. }
  10944. return createVNode(VDefaultsProvider, {
  10945. "root": "VMenu"
  10946. }, {
  10947. default: () => [slots.default?.(...args)]
  10948. });
  10949. }
  10950. });
  10951. });
  10952. return forwardRefs({
  10953. id,
  10954. ΨopenChildren: openChildren
  10955. }, overlay);
  10956. }
  10957. });
  10958. // Types
  10959. const makeVCounterProps = propsFactory({
  10960. active: Boolean,
  10961. disabled: Boolean,
  10962. max: [Number, String],
  10963. value: {
  10964. type: [Number, String],
  10965. default: 0
  10966. },
  10967. ...makeComponentProps(),
  10968. ...makeTransitionProps({
  10969. transition: {
  10970. component: VSlideYTransition
  10971. }
  10972. })
  10973. }, 'VCounter');
  10974. const VCounter = genericComponent()({
  10975. name: 'VCounter',
  10976. functional: true,
  10977. props: makeVCounterProps(),
  10978. setup(props, _ref) {
  10979. let {
  10980. slots
  10981. } = _ref;
  10982. const counter = computed(() => {
  10983. return props.max ? `${props.value} / ${props.max}` : String(props.value);
  10984. });
  10985. useRender(() => createVNode(MaybeTransition, {
  10986. "transition": props.transition
  10987. }, {
  10988. default: () => [withDirectives(createVNode("div", {
  10989. "class": ['v-counter', {
  10990. 'text-error': props.max && !props.disabled && parseFloat(props.value) > parseFloat(props.max)
  10991. }, props.class],
  10992. "style": props.style
  10993. }, [slots.default ? slots.default({
  10994. counter: counter.value,
  10995. max: props.max,
  10996. value: props.value
  10997. }) : counter.value]), [[vShow, props.active]])]
  10998. }));
  10999. return {};
  11000. }
  11001. });
  11002. const makeVFieldLabelProps = propsFactory({
  11003. floating: Boolean,
  11004. ...makeComponentProps()
  11005. }, 'VFieldLabel');
  11006. const VFieldLabel = genericComponent()({
  11007. name: 'VFieldLabel',
  11008. props: makeVFieldLabelProps(),
  11009. setup(props, _ref) {
  11010. let {
  11011. slots
  11012. } = _ref;
  11013. useRender(() => createVNode(VLabel, {
  11014. "class": ['v-field-label', {
  11015. 'v-field-label--floating': props.floating
  11016. }, props.class],
  11017. "style": props.style,
  11018. "aria-hidden": props.floating || undefined
  11019. }, slots));
  11020. return {};
  11021. }
  11022. });
  11023. // Types
  11024. const allowedVariants$1 = ['underlined', 'outlined', 'filled', 'solo', 'solo-inverted', 'solo-filled', 'plain'];
  11025. const makeVFieldProps = propsFactory({
  11026. appendInnerIcon: IconValue,
  11027. bgColor: String,
  11028. clearable: Boolean,
  11029. clearIcon: {
  11030. type: IconValue,
  11031. default: '$clear'
  11032. },
  11033. active: Boolean,
  11034. centerAffix: {
  11035. type: Boolean,
  11036. default: undefined
  11037. },
  11038. color: String,
  11039. baseColor: String,
  11040. dirty: Boolean,
  11041. disabled: {
  11042. type: Boolean,
  11043. default: null
  11044. },
  11045. error: Boolean,
  11046. flat: Boolean,
  11047. label: String,
  11048. persistentClear: Boolean,
  11049. prependInnerIcon: IconValue,
  11050. reverse: Boolean,
  11051. singleLine: Boolean,
  11052. variant: {
  11053. type: String,
  11054. default: 'filled',
  11055. validator: v => allowedVariants$1.includes(v)
  11056. },
  11057. 'onClick:clear': EventProp(),
  11058. 'onClick:appendInner': EventProp(),
  11059. 'onClick:prependInner': EventProp(),
  11060. ...makeComponentProps(),
  11061. ...makeLoaderProps(),
  11062. ...makeRoundedProps(),
  11063. ...makeThemeProps()
  11064. }, 'VField');
  11065. const VField = genericComponent()({
  11066. name: 'VField',
  11067. inheritAttrs: false,
  11068. props: {
  11069. id: String,
  11070. ...makeFocusProps(),
  11071. ...makeVFieldProps()
  11072. },
  11073. emits: {
  11074. 'update:focused': focused => true,
  11075. 'update:modelValue': value => true
  11076. },
  11077. setup(props, _ref) {
  11078. let {
  11079. attrs,
  11080. emit,
  11081. slots
  11082. } = _ref;
  11083. const {
  11084. themeClasses
  11085. } = provideTheme(props);
  11086. const {
  11087. loaderClasses
  11088. } = useLoader(props);
  11089. const {
  11090. focusClasses,
  11091. isFocused,
  11092. focus,
  11093. blur
  11094. } = useFocus(props);
  11095. const {
  11096. InputIcon
  11097. } = useInputIcon(props);
  11098. const {
  11099. roundedClasses
  11100. } = useRounded(props);
  11101. const {
  11102. rtlClasses
  11103. } = useRtl();
  11104. const isActive = computed(() => props.dirty || props.active);
  11105. const hasLabel = computed(() => !props.singleLine && !!(props.label || slots.label));
  11106. const uid = getUid();
  11107. const id = computed(() => props.id || `input-${uid}`);
  11108. const messagesId = computed(() => `${id.value}-messages`);
  11109. const labelRef = ref();
  11110. const floatingLabelRef = ref();
  11111. const controlRef = ref();
  11112. const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant));
  11113. const {
  11114. backgroundColorClasses,
  11115. backgroundColorStyles
  11116. } = useBackgroundColor(toRef(props, 'bgColor'));
  11117. const {
  11118. textColorClasses,
  11119. textColorStyles
  11120. } = useTextColor(computed(() => {
  11121. return props.error || props.disabled ? undefined : isActive.value && isFocused.value ? props.color : props.baseColor;
  11122. }));
  11123. watch(isActive, val => {
  11124. if (hasLabel.value) {
  11125. const el = labelRef.value.$el;
  11126. const targetEl = floatingLabelRef.value.$el;
  11127. requestAnimationFrame(() => {
  11128. const rect = nullifyTransforms(el);
  11129. const targetRect = targetEl.getBoundingClientRect();
  11130. const x = targetRect.x - rect.x;
  11131. const y = targetRect.y - rect.y - (rect.height / 2 - targetRect.height / 2);
  11132. const targetWidth = targetRect.width / 0.75;
  11133. const width = Math.abs(targetWidth - rect.width) > 1 ? {
  11134. maxWidth: convertToUnit(targetWidth)
  11135. } : undefined;
  11136. const style = getComputedStyle(el);
  11137. const targetStyle = getComputedStyle(targetEl);
  11138. const duration = parseFloat(style.transitionDuration) * 1000 || 150;
  11139. const scale = parseFloat(targetStyle.getPropertyValue('--v-field-label-scale'));
  11140. const color = targetStyle.getPropertyValue('color');
  11141. el.style.visibility = 'visible';
  11142. targetEl.style.visibility = 'hidden';
  11143. animate(el, {
  11144. transform: `translate(${x}px, ${y}px) scale(${scale})`,
  11145. color,
  11146. ...width
  11147. }, {
  11148. duration,
  11149. easing: standardEasing,
  11150. direction: val ? 'normal' : 'reverse'
  11151. }).finished.then(() => {
  11152. el.style.removeProperty('visibility');
  11153. targetEl.style.removeProperty('visibility');
  11154. });
  11155. });
  11156. }
  11157. }, {
  11158. flush: 'post'
  11159. });
  11160. const slotProps = computed(() => ({
  11161. isActive,
  11162. isFocused,
  11163. controlRef,
  11164. blur,
  11165. focus
  11166. }));
  11167. function onClick(e) {
  11168. if (e.target !== document.activeElement) {
  11169. e.preventDefault();
  11170. }
  11171. }
  11172. function onKeydownClear(e) {
  11173. if (e.key !== 'Enter' && e.key !== ' ') return;
  11174. e.preventDefault();
  11175. e.stopPropagation();
  11176. props['onClick:clear']?.(new MouseEvent('click'));
  11177. }
  11178. useRender(() => {
  11179. const isOutlined = props.variant === 'outlined';
  11180. const hasPrepend = !!(slots['prepend-inner'] || props.prependInnerIcon);
  11181. const hasClear = !!(props.clearable || slots.clear);
  11182. const hasAppend = !!(slots['append-inner'] || props.appendInnerIcon || hasClear);
  11183. const label = () => slots.label ? slots.label({
  11184. ...slotProps.value,
  11185. label: props.label,
  11186. props: {
  11187. for: id.value
  11188. }
  11189. }) : props.label;
  11190. return createVNode("div", mergeProps({
  11191. "class": ['v-field', {
  11192. 'v-field--active': isActive.value,
  11193. 'v-field--appended': hasAppend,
  11194. 'v-field--center-affix': props.centerAffix ?? !isPlainOrUnderlined.value,
  11195. 'v-field--disabled': props.disabled,
  11196. 'v-field--dirty': props.dirty,
  11197. 'v-field--error': props.error,
  11198. 'v-field--flat': props.flat,
  11199. 'v-field--has-background': !!props.bgColor,
  11200. 'v-field--persistent-clear': props.persistentClear,
  11201. 'v-field--prepended': hasPrepend,
  11202. 'v-field--reverse': props.reverse,
  11203. 'v-field--single-line': props.singleLine,
  11204. 'v-field--no-label': !label(),
  11205. [`v-field--variant-${props.variant}`]: true
  11206. }, themeClasses.value, backgroundColorClasses.value, focusClasses.value, loaderClasses.value, roundedClasses.value, rtlClasses.value, props.class],
  11207. "style": [backgroundColorStyles.value, props.style],
  11208. "onClick": onClick
  11209. }, attrs), [createVNode("div", {
  11210. "class": "v-field__overlay"
  11211. }, null), createVNode(LoaderSlot, {
  11212. "name": "v-field",
  11213. "active": !!props.loading,
  11214. "color": props.error ? 'error' : typeof props.loading === 'string' ? props.loading : props.color
  11215. }, {
  11216. default: slots.loader
  11217. }), hasPrepend && createVNode("div", {
  11218. "key": "prepend",
  11219. "class": "v-field__prepend-inner"
  11220. }, [props.prependInnerIcon && createVNode(InputIcon, {
  11221. "key": "prepend-icon",
  11222. "name": "prependInner"
  11223. }, null), slots['prepend-inner']?.(slotProps.value)]), createVNode("div", {
  11224. "class": "v-field__field",
  11225. "data-no-activator": ""
  11226. }, [['filled', 'solo', 'solo-inverted', 'solo-filled'].includes(props.variant) && hasLabel.value && createVNode(VFieldLabel, {
  11227. "key": "floating-label",
  11228. "ref": floatingLabelRef,
  11229. "class": [textColorClasses.value],
  11230. "floating": true,
  11231. "for": id.value,
  11232. "style": textColorStyles.value
  11233. }, {
  11234. default: () => [label()]
  11235. }), hasLabel.value && createVNode(VFieldLabel, {
  11236. "key": "label",
  11237. "ref": labelRef,
  11238. "for": id.value
  11239. }, {
  11240. default: () => [label()]
  11241. }), slots.default?.({
  11242. ...slotProps.value,
  11243. props: {
  11244. id: id.value,
  11245. class: 'v-field__input',
  11246. 'aria-describedby': messagesId.value
  11247. },
  11248. focus,
  11249. blur
  11250. })]), hasClear && createVNode(VExpandXTransition, {
  11251. "key": "clear"
  11252. }, {
  11253. default: () => [withDirectives(createVNode("div", {
  11254. "class": "v-field__clearable",
  11255. "onMousedown": e => {
  11256. e.preventDefault();
  11257. e.stopPropagation();
  11258. }
  11259. }, [createVNode(VDefaultsProvider, {
  11260. "defaults": {
  11261. VIcon: {
  11262. icon: props.clearIcon
  11263. }
  11264. }
  11265. }, {
  11266. default: () => [slots.clear ? slots.clear({
  11267. ...slotProps.value,
  11268. props: {
  11269. onKeydown: onKeydownClear,
  11270. onFocus: focus,
  11271. onBlur: blur,
  11272. onClick: props['onClick:clear']
  11273. }
  11274. }) : createVNode(InputIcon, {
  11275. "name": "clear",
  11276. "onKeydown": onKeydownClear,
  11277. "onFocus": focus,
  11278. "onBlur": blur
  11279. }, null)]
  11280. })]), [[vShow, props.dirty]])]
  11281. }), hasAppend && createVNode("div", {
  11282. "key": "append",
  11283. "class": "v-field__append-inner"
  11284. }, [slots['append-inner']?.(slotProps.value), props.appendInnerIcon && createVNode(InputIcon, {
  11285. "key": "append-icon",
  11286. "name": "appendInner"
  11287. }, null)]), createVNode("div", {
  11288. "class": ['v-field__outline', textColorClasses.value],
  11289. "style": textColorStyles.value
  11290. }, [isOutlined && createVNode(Fragment, null, [createVNode("div", {
  11291. "class": "v-field__outline__start"
  11292. }, null), hasLabel.value && createVNode("div", {
  11293. "class": "v-field__outline__notch"
  11294. }, [createVNode(VFieldLabel, {
  11295. "ref": floatingLabelRef,
  11296. "floating": true,
  11297. "for": id.value
  11298. }, {
  11299. default: () => [label()]
  11300. })]), createVNode("div", {
  11301. "class": "v-field__outline__end"
  11302. }, null)]), isPlainOrUnderlined.value && hasLabel.value && createVNode(VFieldLabel, {
  11303. "ref": floatingLabelRef,
  11304. "floating": true,
  11305. "for": id.value
  11306. }, {
  11307. default: () => [label()]
  11308. })])]);
  11309. });
  11310. return {
  11311. controlRef
  11312. };
  11313. }
  11314. });
  11315. // TODO: this is kinda slow, might be better to implicitly inherit props instead
  11316. function filterFieldProps(attrs) {
  11317. const keys = Object.keys(VField.props).filter(k => !isOn(k) && k !== 'class' && k !== 'style');
  11318. return pick(attrs, keys);
  11319. }
  11320. // Types
  11321. const activeTypes = ['color', 'file', 'time', 'date', 'datetime-local', 'week', 'month'];
  11322. const makeVTextFieldProps = propsFactory({
  11323. autofocus: Boolean,
  11324. counter: [Boolean, Number, String],
  11325. counterValue: [Number, Function],
  11326. prefix: String,
  11327. placeholder: String,
  11328. persistentPlaceholder: Boolean,
  11329. persistentCounter: Boolean,
  11330. suffix: String,
  11331. role: String,
  11332. type: {
  11333. type: String,
  11334. default: 'text'
  11335. },
  11336. modelModifiers: Object,
  11337. ...makeVInputProps(),
  11338. ...makeVFieldProps()
  11339. }, 'VTextField');
  11340. const VTextField = genericComponent()({
  11341. name: 'VTextField',
  11342. directives: {
  11343. Intersect
  11344. },
  11345. inheritAttrs: false,
  11346. props: makeVTextFieldProps(),
  11347. emits: {
  11348. 'click:control': e => true,
  11349. 'mousedown:control': e => true,
  11350. 'update:focused': focused => true,
  11351. 'update:modelValue': val => true
  11352. },
  11353. setup(props, _ref) {
  11354. let {
  11355. attrs,
  11356. emit,
  11357. slots
  11358. } = _ref;
  11359. const model = useProxiedModel(props, 'modelValue');
  11360. const {
  11361. isFocused,
  11362. focus,
  11363. blur
  11364. } = useFocus(props);
  11365. const counterValue = computed(() => {
  11366. return typeof props.counterValue === 'function' ? props.counterValue(model.value) : typeof props.counterValue === 'number' ? props.counterValue : (model.value ?? '').toString().length;
  11367. });
  11368. const max = computed(() => {
  11369. if (attrs.maxlength) return attrs.maxlength;
  11370. if (!props.counter || typeof props.counter !== 'number' && typeof props.counter !== 'string') return undefined;
  11371. return props.counter;
  11372. });
  11373. const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant));
  11374. function onIntersect(isIntersecting, entries) {
  11375. if (!props.autofocus || !isIntersecting) return;
  11376. entries[0].target?.focus?.();
  11377. }
  11378. const vInputRef = ref();
  11379. const vFieldRef = ref();
  11380. const inputRef = ref();
  11381. const isActive = computed(() => activeTypes.includes(props.type) || props.persistentPlaceholder || isFocused.value || props.active);
  11382. function onFocus() {
  11383. if (inputRef.value !== document.activeElement) {
  11384. inputRef.value?.focus();
  11385. }
  11386. if (!isFocused.value) focus();
  11387. }
  11388. function onControlMousedown(e) {
  11389. emit('mousedown:control', e);
  11390. if (e.target === inputRef.value) return;
  11391. onFocus();
  11392. e.preventDefault();
  11393. }
  11394. function onControlClick(e) {
  11395. onFocus();
  11396. emit('click:control', e);
  11397. }
  11398. function onClear(e) {
  11399. e.stopPropagation();
  11400. onFocus();
  11401. nextTick(() => {
  11402. model.value = null;
  11403. callEvent(props['onClick:clear'], e);
  11404. });
  11405. }
  11406. function onInput(e) {
  11407. const el = e.target;
  11408. model.value = el.value;
  11409. if (props.modelModifiers?.trim && ['text', 'search', 'password', 'tel', 'url'].includes(props.type)) {
  11410. const caretPosition = [el.selectionStart, el.selectionEnd];
  11411. nextTick(() => {
  11412. el.selectionStart = caretPosition[0];
  11413. el.selectionEnd = caretPosition[1];
  11414. });
  11415. }
  11416. }
  11417. useRender(() => {
  11418. const hasCounter = !!(slots.counter || props.counter !== false && props.counter != null);
  11419. const hasDetails = !!(hasCounter || slots.details);
  11420. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  11421. const {
  11422. modelValue: _,
  11423. ...inputProps
  11424. } = VInput.filterProps(props);
  11425. const fieldProps = filterFieldProps(props);
  11426. return createVNode(VInput, mergeProps({
  11427. "ref": vInputRef,
  11428. "modelValue": model.value,
  11429. "onUpdate:modelValue": $event => model.value = $event,
  11430. "class": ['v-text-field', {
  11431. 'v-text-field--prefixed': props.prefix,
  11432. 'v-text-field--suffixed': props.suffix,
  11433. 'v-input--plain-underlined': isPlainOrUnderlined.value
  11434. }, props.class],
  11435. "style": props.style
  11436. }, rootAttrs, inputProps, {
  11437. "centerAffix": !isPlainOrUnderlined.value,
  11438. "focused": isFocused.value
  11439. }), {
  11440. ...slots,
  11441. default: _ref2 => {
  11442. let {
  11443. id,
  11444. isDisabled,
  11445. isDirty,
  11446. isReadonly,
  11447. isValid
  11448. } = _ref2;
  11449. return createVNode(VField, mergeProps({
  11450. "ref": vFieldRef,
  11451. "onMousedown": onControlMousedown,
  11452. "onClick": onControlClick,
  11453. "onClick:clear": onClear,
  11454. "onClick:prependInner": props['onClick:prependInner'],
  11455. "onClick:appendInner": props['onClick:appendInner'],
  11456. "role": props.role
  11457. }, fieldProps, {
  11458. "id": id.value,
  11459. "active": isActive.value || isDirty.value,
  11460. "dirty": isDirty.value || props.dirty,
  11461. "disabled": isDisabled.value,
  11462. "focused": isFocused.value,
  11463. "error": isValid.value === false
  11464. }), {
  11465. ...slots,
  11466. default: _ref3 => {
  11467. let {
  11468. props: {
  11469. class: fieldClass,
  11470. ...slotProps
  11471. }
  11472. } = _ref3;
  11473. const inputNode = withDirectives(createVNode("input", mergeProps({
  11474. "ref": inputRef,
  11475. "value": model.value,
  11476. "onInput": onInput,
  11477. "autofocus": props.autofocus,
  11478. "readonly": isReadonly.value,
  11479. "disabled": isDisabled.value,
  11480. "name": props.name,
  11481. "placeholder": props.placeholder,
  11482. "size": 1,
  11483. "type": props.type,
  11484. "onFocus": onFocus,
  11485. "onBlur": blur
  11486. }, slotProps, inputAttrs), null), [[resolveDirective("intersect"), {
  11487. handler: onIntersect
  11488. }, null, {
  11489. once: true
  11490. }]]);
  11491. return createVNode(Fragment, null, [props.prefix && createVNode("span", {
  11492. "class": "v-text-field__prefix"
  11493. }, [createVNode("span", {
  11494. "class": "v-text-field__prefix__text"
  11495. }, [props.prefix])]), slots.default ? createVNode("div", {
  11496. "class": fieldClass,
  11497. "data-no-activator": ""
  11498. }, [slots.default(), inputNode]) : cloneVNode(inputNode, {
  11499. class: fieldClass
  11500. }), props.suffix && createVNode("span", {
  11501. "class": "v-text-field__suffix"
  11502. }, [createVNode("span", {
  11503. "class": "v-text-field__suffix__text"
  11504. }, [props.suffix])])]);
  11505. }
  11506. });
  11507. },
  11508. details: hasDetails ? slotProps => createVNode(Fragment, null, [slots.details?.(slotProps), hasCounter && createVNode(Fragment, null, [createVNode("span", null, null), createVNode(VCounter, {
  11509. "active": props.persistentCounter || isFocused.value,
  11510. "value": counterValue.value,
  11511. "max": max.value,
  11512. "disabled": props.disabled
  11513. }, slots.counter)])]) : undefined
  11514. });
  11515. });
  11516. return forwardRefs({}, vInputRef, vFieldRef, inputRef);
  11517. }
  11518. });
  11519. // Types
  11520. const makeVVirtualScrollItemProps = propsFactory({
  11521. renderless: Boolean,
  11522. ...makeComponentProps()
  11523. }, 'VVirtualScrollItem');
  11524. const VVirtualScrollItem = genericComponent()({
  11525. name: 'VVirtualScrollItem',
  11526. inheritAttrs: false,
  11527. props: makeVVirtualScrollItemProps(),
  11528. emits: {
  11529. 'update:height': height => true
  11530. },
  11531. setup(props, _ref) {
  11532. let {
  11533. attrs,
  11534. emit,
  11535. slots
  11536. } = _ref;
  11537. const {
  11538. resizeRef,
  11539. contentRect
  11540. } = useResizeObserver(undefined, 'border');
  11541. watch(() => contentRect.value?.height, height => {
  11542. if (height != null) emit('update:height', height);
  11543. });
  11544. useRender(() => props.renderless ? createVNode(Fragment, null, [slots.default?.({
  11545. itemRef: resizeRef
  11546. })]) : createVNode("div", mergeProps({
  11547. "ref": resizeRef,
  11548. "class": ['v-virtual-scroll__item', props.class],
  11549. "style": props.style
  11550. }, attrs), [slots.default?.()]));
  11551. }
  11552. });
  11553. // Composables
  11554. // Types
  11555. const UP = -1;
  11556. const DOWN = 1;
  11557. /** Determines how large each batch of items should be */
  11558. const BUFFER_PX = 100;
  11559. const makeVirtualProps = propsFactory({
  11560. itemHeight: {
  11561. type: [Number, String],
  11562. default: null
  11563. },
  11564. height: [Number, String]
  11565. }, 'virtual');
  11566. function useVirtual(props, items) {
  11567. const display = useDisplay();
  11568. const itemHeight = shallowRef(0);
  11569. watchEffect(() => {
  11570. itemHeight.value = parseFloat(props.itemHeight || 0);
  11571. });
  11572. const first = shallowRef(0);
  11573. const last = shallowRef(Math.ceil(
  11574. // Assume 16px items filling the entire screen height if
  11575. // not provided. This is probably incorrect but it minimises
  11576. // the chance of ending up with empty space at the bottom.
  11577. // The default value is set here to avoid poisoning getSize()
  11578. (parseInt(props.height) || display.height.value) / (itemHeight.value || 16)) || 1);
  11579. const paddingTop = shallowRef(0);
  11580. const paddingBottom = shallowRef(0);
  11581. /** The scrollable element */
  11582. const containerRef = ref();
  11583. /** An element marking the top of the scrollable area,
  11584. * used to add an offset if there's padding or other elements above the virtual list */
  11585. const markerRef = ref();
  11586. /** markerRef's offsetTop, lazily evaluated */
  11587. let markerOffset = 0;
  11588. const {
  11589. resizeRef,
  11590. contentRect
  11591. } = useResizeObserver();
  11592. watchEffect(() => {
  11593. resizeRef.value = containerRef.value;
  11594. });
  11595. const viewportHeight = computed(() => {
  11596. return containerRef.value === document.documentElement ? display.height.value : contentRect.value?.height || parseInt(props.height) || 0;
  11597. });
  11598. /** All static elements have been rendered and we have an assumed item height */
  11599. const hasInitialRender = computed(() => {
  11600. return !!(containerRef.value && markerRef.value && viewportHeight.value && itemHeight.value);
  11601. });
  11602. let sizes = Array.from({
  11603. length: items.value.length
  11604. });
  11605. let offsets = Array.from({
  11606. length: items.value.length
  11607. });
  11608. const updateTime = shallowRef(0);
  11609. let targetScrollIndex = -1;
  11610. function getSize(index) {
  11611. return sizes[index] || itemHeight.value;
  11612. }
  11613. const updateOffsets = debounce(() => {
  11614. const start = performance.now();
  11615. offsets[0] = 0;
  11616. const length = items.value.length;
  11617. for (let i = 1; i <= length - 1; i++) {
  11618. offsets[i] = (offsets[i - 1] || 0) + getSize(i - 1);
  11619. }
  11620. updateTime.value = Math.max(updateTime.value, performance.now() - start);
  11621. }, updateTime);
  11622. const unwatch = watch(hasInitialRender, v => {
  11623. if (!v) return;
  11624. // First render is complete, update offsets and visible
  11625. // items in case our assumed item height was incorrect
  11626. unwatch();
  11627. markerOffset = markerRef.value.offsetTop;
  11628. updateOffsets.immediate();
  11629. calculateVisibleItems();
  11630. if (!~targetScrollIndex) return;
  11631. nextTick(() => {
  11632. IN_BROWSER && window.requestAnimationFrame(() => {
  11633. scrollToIndex(targetScrollIndex);
  11634. targetScrollIndex = -1;
  11635. });
  11636. });
  11637. });
  11638. onScopeDispose(() => {
  11639. updateOffsets.clear();
  11640. });
  11641. function handleItemResize(index, height) {
  11642. const prevHeight = sizes[index];
  11643. const prevMinHeight = itemHeight.value;
  11644. itemHeight.value = prevMinHeight ? Math.min(itemHeight.value, height) : height;
  11645. if (prevHeight !== height || prevMinHeight !== itemHeight.value) {
  11646. sizes[index] = height;
  11647. updateOffsets();
  11648. }
  11649. }
  11650. function calculateOffset(index) {
  11651. index = clamp(index, 0, items.value.length - 1);
  11652. return offsets[index] || 0;
  11653. }
  11654. function calculateIndex(scrollTop) {
  11655. return binaryClosest(offsets, scrollTop);
  11656. }
  11657. let lastScrollTop = 0;
  11658. let scrollVelocity = 0;
  11659. let lastScrollTime = 0;
  11660. watch(viewportHeight, (val, oldVal) => {
  11661. if (oldVal) {
  11662. calculateVisibleItems();
  11663. if (val < oldVal) {
  11664. requestAnimationFrame(() => {
  11665. scrollVelocity = 0;
  11666. calculateVisibleItems();
  11667. });
  11668. }
  11669. }
  11670. });
  11671. let scrollTimeout = -1;
  11672. function handleScroll() {
  11673. if (!containerRef.value || !markerRef.value) return;
  11674. const scrollTop = containerRef.value.scrollTop;
  11675. const scrollTime = performance.now();
  11676. const scrollDeltaT = scrollTime - lastScrollTime;
  11677. if (scrollDeltaT > 500) {
  11678. scrollVelocity = Math.sign(scrollTop - lastScrollTop);
  11679. // Not super important, only update at the
  11680. // start of a scroll sequence to avoid reflows
  11681. markerOffset = markerRef.value.offsetTop;
  11682. } else {
  11683. scrollVelocity = scrollTop - lastScrollTop;
  11684. }
  11685. lastScrollTop = scrollTop;
  11686. lastScrollTime = scrollTime;
  11687. window.clearTimeout(scrollTimeout);
  11688. scrollTimeout = window.setTimeout(handleScrollend, 500);
  11689. calculateVisibleItems();
  11690. }
  11691. function handleScrollend() {
  11692. if (!containerRef.value || !markerRef.value) return;
  11693. scrollVelocity = 0;
  11694. lastScrollTime = 0;
  11695. window.clearTimeout(scrollTimeout);
  11696. calculateVisibleItems();
  11697. }
  11698. let raf = -1;
  11699. function calculateVisibleItems() {
  11700. cancelAnimationFrame(raf);
  11701. raf = requestAnimationFrame(_calculateVisibleItems);
  11702. }
  11703. function _calculateVisibleItems() {
  11704. if (!containerRef.value || !viewportHeight.value) return;
  11705. const scrollTop = lastScrollTop - markerOffset;
  11706. const direction = Math.sign(scrollVelocity);
  11707. const startPx = Math.max(0, scrollTop - BUFFER_PX);
  11708. const start = clamp(calculateIndex(startPx), 0, items.value.length);
  11709. const endPx = scrollTop + viewportHeight.value + BUFFER_PX;
  11710. const end = clamp(calculateIndex(endPx) + 1, start + 1, items.value.length);
  11711. if (
  11712. // Only update the side we're scrolling towards,
  11713. // the other side will be updated incidentally
  11714. (direction !== UP || start < first.value) && (direction !== DOWN || end > last.value)) {
  11715. const topOverflow = calculateOffset(first.value) - calculateOffset(start);
  11716. const bottomOverflow = calculateOffset(end) - calculateOffset(last.value);
  11717. const bufferOverflow = Math.max(topOverflow, bottomOverflow);
  11718. if (bufferOverflow > BUFFER_PX) {
  11719. first.value = start;
  11720. last.value = end;
  11721. } else {
  11722. // Only update the side that's reached its limit if there's still buffer left
  11723. if (start <= 0) first.value = start;
  11724. if (end >= items.value.length) last.value = end;
  11725. }
  11726. }
  11727. paddingTop.value = calculateOffset(first.value);
  11728. paddingBottom.value = calculateOffset(items.value.length) - calculateOffset(last.value);
  11729. }
  11730. function scrollToIndex(index) {
  11731. const offset = calculateOffset(index);
  11732. if (!containerRef.value || index && !offset) {
  11733. targetScrollIndex = index;
  11734. } else {
  11735. containerRef.value.scrollTop = offset;
  11736. }
  11737. }
  11738. const computedItems = computed(() => {
  11739. return items.value.slice(first.value, last.value).map((item, index) => ({
  11740. raw: item,
  11741. index: index + first.value,
  11742. key: isObject(item) && 'value' in item ? item.value : index + first.value
  11743. }));
  11744. });
  11745. watch(items, () => {
  11746. sizes = Array.from({
  11747. length: items.value.length
  11748. });
  11749. offsets = Array.from({
  11750. length: items.value.length
  11751. });
  11752. updateOffsets.immediate();
  11753. calculateVisibleItems();
  11754. }, {
  11755. deep: true
  11756. });
  11757. return {
  11758. calculateVisibleItems,
  11759. containerRef,
  11760. markerRef,
  11761. computedItems,
  11762. paddingTop,
  11763. paddingBottom,
  11764. scrollToIndex,
  11765. handleScroll,
  11766. handleScrollend,
  11767. handleItemResize
  11768. };
  11769. }
  11770. // https://gist.github.com/robertleeplummerjr/1cc657191d34ecd0a324
  11771. function binaryClosest(arr, val) {
  11772. let high = arr.length - 1;
  11773. let low = 0;
  11774. let mid = 0;
  11775. let item = null;
  11776. let target = -1;
  11777. if (arr[high] < val) {
  11778. return high;
  11779. }
  11780. while (low <= high) {
  11781. mid = low + high >> 1;
  11782. item = arr[mid];
  11783. if (item > val) {
  11784. high = mid - 1;
  11785. } else if (item < val) {
  11786. target = mid;
  11787. low = mid + 1;
  11788. } else if (item === val) {
  11789. return mid;
  11790. } else {
  11791. return low;
  11792. }
  11793. }
  11794. return target;
  11795. }
  11796. // Types
  11797. const makeVVirtualScrollProps = propsFactory({
  11798. items: {
  11799. type: Array,
  11800. default: () => []
  11801. },
  11802. renderless: Boolean,
  11803. ...makeVirtualProps(),
  11804. ...makeComponentProps(),
  11805. ...makeDimensionProps()
  11806. }, 'VVirtualScroll');
  11807. const VVirtualScroll = genericComponent()({
  11808. name: 'VVirtualScroll',
  11809. props: makeVVirtualScrollProps(),
  11810. setup(props, _ref) {
  11811. let {
  11812. slots
  11813. } = _ref;
  11814. const vm = getCurrentInstance('VVirtualScroll');
  11815. const {
  11816. dimensionStyles
  11817. } = useDimension(props);
  11818. const {
  11819. calculateVisibleItems,
  11820. containerRef,
  11821. markerRef,
  11822. handleScroll,
  11823. handleScrollend,
  11824. handleItemResize,
  11825. scrollToIndex,
  11826. paddingTop,
  11827. paddingBottom,
  11828. computedItems
  11829. } = useVirtual(props, toRef(props, 'items'));
  11830. useToggleScope(() => props.renderless, () => {
  11831. function handleListeners() {
  11832. let add = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
  11833. const method = add ? 'addEventListener' : 'removeEventListener';
  11834. if (containerRef.value === document.documentElement) {
  11835. document[method]('scroll', handleScroll, {
  11836. passive: true
  11837. });
  11838. document[method]('scrollend', handleScrollend);
  11839. } else {
  11840. containerRef.value?.[method]('scroll', handleScroll, {
  11841. passive: true
  11842. });
  11843. containerRef.value?.[method]('scrollend', handleScrollend);
  11844. }
  11845. }
  11846. onMounted(() => {
  11847. containerRef.value = getScrollParent(vm.vnode.el, true);
  11848. handleListeners(true);
  11849. });
  11850. onScopeDispose(handleListeners);
  11851. });
  11852. useRender(() => {
  11853. const children = computedItems.value.map(item => createVNode(VVirtualScrollItem, {
  11854. "key": item.key,
  11855. "renderless": props.renderless,
  11856. "onUpdate:height": height => handleItemResize(item.index, height)
  11857. }, {
  11858. default: slotProps => slots.default?.({
  11859. item: item.raw,
  11860. index: item.index,
  11861. ...slotProps
  11862. })
  11863. }));
  11864. return props.renderless ? createVNode(Fragment, null, [createVNode("div", {
  11865. "ref": markerRef,
  11866. "class": "v-virtual-scroll__spacer",
  11867. "style": {
  11868. paddingTop: convertToUnit(paddingTop.value)
  11869. }
  11870. }, null), children, createVNode("div", {
  11871. "class": "v-virtual-scroll__spacer",
  11872. "style": {
  11873. paddingBottom: convertToUnit(paddingBottom.value)
  11874. }
  11875. }, null)]) : createVNode("div", {
  11876. "ref": containerRef,
  11877. "class": ['v-virtual-scroll', props.class],
  11878. "onScrollPassive": handleScroll,
  11879. "onScrollend": handleScrollend,
  11880. "style": [dimensionStyles.value, props.style]
  11881. }, [createVNode("div", {
  11882. "ref": markerRef,
  11883. "class": "v-virtual-scroll__container",
  11884. "style": {
  11885. paddingTop: convertToUnit(paddingTop.value),
  11886. paddingBottom: convertToUnit(paddingBottom.value)
  11887. }
  11888. }, [children])]);
  11889. });
  11890. return {
  11891. calculateVisibleItems,
  11892. scrollToIndex
  11893. };
  11894. }
  11895. });
  11896. // Utilities
  11897. // Types
  11898. function useScrolling(listRef, textFieldRef) {
  11899. const isScrolling = shallowRef(false);
  11900. let scrollTimeout;
  11901. function onListScroll(e) {
  11902. cancelAnimationFrame(scrollTimeout);
  11903. isScrolling.value = true;
  11904. scrollTimeout = requestAnimationFrame(() => {
  11905. scrollTimeout = requestAnimationFrame(() => {
  11906. isScrolling.value = false;
  11907. });
  11908. });
  11909. }
  11910. async function finishScrolling() {
  11911. await new Promise(resolve => requestAnimationFrame(resolve));
  11912. await new Promise(resolve => requestAnimationFrame(resolve));
  11913. await new Promise(resolve => requestAnimationFrame(resolve));
  11914. await new Promise(resolve => {
  11915. if (isScrolling.value) {
  11916. const stop = watch(isScrolling, () => {
  11917. stop();
  11918. resolve();
  11919. });
  11920. } else resolve();
  11921. });
  11922. }
  11923. async function onListKeydown(e) {
  11924. if (e.key === 'Tab') {
  11925. textFieldRef.value?.focus();
  11926. }
  11927. if (!['PageDown', 'PageUp', 'Home', 'End'].includes(e.key)) return;
  11928. const el = listRef.value?.$el;
  11929. if (!el) return;
  11930. if (e.key === 'Home' || e.key === 'End') {
  11931. el.scrollTo({
  11932. top: e.key === 'Home' ? 0 : el.scrollHeight,
  11933. behavior: 'smooth'
  11934. });
  11935. }
  11936. await finishScrolling();
  11937. const children = el.querySelectorAll(':scope > :not(.v-virtual-scroll__spacer)');
  11938. if (e.key === 'PageDown' || e.key === 'Home') {
  11939. const top = el.getBoundingClientRect().top;
  11940. for (const child of children) {
  11941. if (child.getBoundingClientRect().top >= top) {
  11942. child.focus();
  11943. break;
  11944. }
  11945. }
  11946. } else {
  11947. const bottom = el.getBoundingClientRect().bottom;
  11948. for (const child of [...children].reverse()) {
  11949. if (child.getBoundingClientRect().bottom <= bottom) {
  11950. child.focus();
  11951. break;
  11952. }
  11953. }
  11954. }
  11955. }
  11956. return {
  11957. onScrollPassive: onListScroll,
  11958. onKeydown: onListKeydown
  11959. }; // typescript doesn't know about vue's event merging
  11960. }
  11961. // Types
  11962. const makeSelectProps = propsFactory({
  11963. chips: Boolean,
  11964. closableChips: Boolean,
  11965. closeText: {
  11966. type: String,
  11967. default: '$vuetify.close'
  11968. },
  11969. openText: {
  11970. type: String,
  11971. default: '$vuetify.open'
  11972. },
  11973. eager: Boolean,
  11974. hideNoData: Boolean,
  11975. hideSelected: Boolean,
  11976. listProps: {
  11977. type: Object
  11978. },
  11979. menu: Boolean,
  11980. menuIcon: {
  11981. type: IconValue,
  11982. default: '$dropdown'
  11983. },
  11984. menuProps: {
  11985. type: Object
  11986. },
  11987. multiple: Boolean,
  11988. noDataText: {
  11989. type: String,
  11990. default: '$vuetify.noDataText'
  11991. },
  11992. openOnClear: Boolean,
  11993. itemColor: String,
  11994. ...makeItemsProps({
  11995. itemChildren: false
  11996. })
  11997. }, 'Select');
  11998. const makeVSelectProps = propsFactory({
  11999. ...makeSelectProps(),
  12000. ...omit(makeVTextFieldProps({
  12001. modelValue: null,
  12002. role: 'combobox'
  12003. }), ['validationValue', 'dirty', 'appendInnerIcon']),
  12004. ...makeTransitionProps({
  12005. transition: {
  12006. component: VDialogTransition
  12007. }
  12008. })
  12009. }, 'VSelect');
  12010. const VSelect = genericComponent()({
  12011. name: 'VSelect',
  12012. props: makeVSelectProps(),
  12013. emits: {
  12014. 'update:focused': focused => true,
  12015. 'update:modelValue': value => true,
  12016. 'update:menu': ue => true
  12017. },
  12018. setup(props, _ref) {
  12019. let {
  12020. slots
  12021. } = _ref;
  12022. const {
  12023. t
  12024. } = useLocale();
  12025. const vTextFieldRef = ref();
  12026. const vMenuRef = ref();
  12027. const vVirtualScrollRef = ref();
  12028. const _menu = useProxiedModel(props, 'menu');
  12029. const menu = computed({
  12030. get: () => _menu.value,
  12031. set: v => {
  12032. if (_menu.value && !v && vMenuRef.value?.ΨopenChildren.size) return;
  12033. _menu.value = v;
  12034. }
  12035. });
  12036. const {
  12037. items,
  12038. transformIn,
  12039. transformOut
  12040. } = useItems(props);
  12041. const model = useProxiedModel(props, 'modelValue', [], v => transformIn(v === null ? [null] : wrapInArray(v)), v => {
  12042. const transformed = transformOut(v);
  12043. return props.multiple ? transformed : transformed[0] ?? null;
  12044. });
  12045. const counterValue = computed(() => {
  12046. return typeof props.counterValue === 'function' ? props.counterValue(model.value) : typeof props.counterValue === 'number' ? props.counterValue : model.value.length;
  12047. });
  12048. const form = useForm(props);
  12049. const selectedValues = computed(() => model.value.map(selection => selection.value));
  12050. const isFocused = shallowRef(false);
  12051. const label = computed(() => menu.value ? props.closeText : props.openText);
  12052. let keyboardLookupPrefix = '';
  12053. let keyboardLookupLastTime;
  12054. const displayItems = computed(() => {
  12055. if (props.hideSelected) {
  12056. return items.value.filter(item => !model.value.some(s => props.valueComparator(s, item)));
  12057. }
  12058. return items.value;
  12059. });
  12060. const menuDisabled = computed(() => props.hideNoData && !displayItems.value.length || form.isReadonly.value || form.isDisabled.value);
  12061. const computedMenuProps = computed(() => {
  12062. return {
  12063. ...props.menuProps,
  12064. activatorProps: {
  12065. ...(props.menuProps?.activatorProps || {}),
  12066. 'aria-haspopup': 'listbox' // Set aria-haspopup to 'listbox'
  12067. }
  12068. };
  12069. });
  12070. const listRef = ref();
  12071. const listEvents = useScrolling(listRef, vTextFieldRef);
  12072. function onClear(e) {
  12073. if (props.openOnClear) {
  12074. menu.value = true;
  12075. }
  12076. }
  12077. function onMousedownControl() {
  12078. if (menuDisabled.value) return;
  12079. menu.value = !menu.value;
  12080. }
  12081. function onListKeydown(e) {
  12082. if (checkPrintable(e)) {
  12083. onKeydown(e);
  12084. }
  12085. }
  12086. function onKeydown(e) {
  12087. if (!e.key || form.isReadonly.value) return;
  12088. if (['Enter', ' ', 'ArrowDown', 'ArrowUp', 'Home', 'End'].includes(e.key)) {
  12089. e.preventDefault();
  12090. }
  12091. if (['Enter', 'ArrowDown', ' '].includes(e.key)) {
  12092. menu.value = true;
  12093. }
  12094. if (['Escape', 'Tab'].includes(e.key)) {
  12095. menu.value = false;
  12096. }
  12097. if (e.key === 'Home') {
  12098. listRef.value?.focus('first');
  12099. } else if (e.key === 'End') {
  12100. listRef.value?.focus('last');
  12101. }
  12102. // html select hotkeys
  12103. const KEYBOARD_LOOKUP_THRESHOLD = 1000; // milliseconds
  12104. if (props.multiple || !checkPrintable(e)) return;
  12105. const now = performance.now();
  12106. if (now - keyboardLookupLastTime > KEYBOARD_LOOKUP_THRESHOLD) {
  12107. keyboardLookupPrefix = '';
  12108. }
  12109. keyboardLookupPrefix += e.key.toLowerCase();
  12110. keyboardLookupLastTime = now;
  12111. const item = items.value.find(item => item.title.toLowerCase().startsWith(keyboardLookupPrefix));
  12112. if (item !== undefined) {
  12113. model.value = [item];
  12114. const index = displayItems.value.indexOf(item);
  12115. IN_BROWSER && window.requestAnimationFrame(() => {
  12116. index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
  12117. });
  12118. }
  12119. }
  12120. /** @param set - null means toggle */
  12121. function select(item) {
  12122. let set = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  12123. if (item.props.disabled) return;
  12124. if (props.multiple) {
  12125. const index = model.value.findIndex(selection => props.valueComparator(selection.value, item.value));
  12126. const add = set == null ? !~index : set;
  12127. if (~index) {
  12128. const value = add ? [...model.value, item] : [...model.value];
  12129. value.splice(index, 1);
  12130. model.value = value;
  12131. } else if (add) {
  12132. model.value = [...model.value, item];
  12133. }
  12134. } else {
  12135. const add = set !== false;
  12136. model.value = add ? [item] : [];
  12137. nextTick(() => {
  12138. menu.value = false;
  12139. });
  12140. }
  12141. }
  12142. function onBlur(e) {
  12143. if (!listRef.value?.$el.contains(e.relatedTarget)) {
  12144. menu.value = false;
  12145. }
  12146. }
  12147. function onAfterEnter() {
  12148. if (props.eager) {
  12149. vVirtualScrollRef.value?.calculateVisibleItems();
  12150. }
  12151. }
  12152. function onAfterLeave() {
  12153. if (isFocused.value) {
  12154. vTextFieldRef.value?.focus();
  12155. }
  12156. }
  12157. function onFocusin(e) {
  12158. isFocused.value = true;
  12159. }
  12160. function onModelUpdate(v) {
  12161. if (v == null) model.value = [];else if (matchesSelector(vTextFieldRef.value, ':autofill') || matchesSelector(vTextFieldRef.value, ':-webkit-autofill')) {
  12162. const item = items.value.find(item => item.title === v);
  12163. if (item) {
  12164. select(item);
  12165. }
  12166. } else if (vTextFieldRef.value) {
  12167. vTextFieldRef.value.value = '';
  12168. }
  12169. }
  12170. watch(menu, () => {
  12171. if (!props.hideSelected && menu.value && model.value.length) {
  12172. const index = displayItems.value.findIndex(item => model.value.some(s => props.valueComparator(s.value, item.value)));
  12173. IN_BROWSER && window.requestAnimationFrame(() => {
  12174. index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
  12175. });
  12176. }
  12177. });
  12178. watch(() => props.items, (newVal, oldVal) => {
  12179. if (menu.value) return;
  12180. if (isFocused.value && !oldVal.length && newVal.length) {
  12181. menu.value = true;
  12182. }
  12183. });
  12184. useRender(() => {
  12185. const hasChips = !!(props.chips || slots.chip);
  12186. const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
  12187. const isDirty = model.value.length > 0;
  12188. const textFieldProps = VTextField.filterProps(props);
  12189. const placeholder = isDirty || !isFocused.value && props.label && !props.persistentPlaceholder ? undefined : props.placeholder;
  12190. return createVNode(VTextField, mergeProps({
  12191. "ref": vTextFieldRef
  12192. }, textFieldProps, {
  12193. "modelValue": model.value.map(v => v.props.value).join(', '),
  12194. "onUpdate:modelValue": onModelUpdate,
  12195. "focused": isFocused.value,
  12196. "onUpdate:focused": $event => isFocused.value = $event,
  12197. "validationValue": model.externalValue,
  12198. "counterValue": counterValue.value,
  12199. "dirty": isDirty,
  12200. "class": ['v-select', {
  12201. 'v-select--active-menu': menu.value,
  12202. 'v-select--chips': !!props.chips,
  12203. [`v-select--${props.multiple ? 'multiple' : 'single'}`]: true,
  12204. 'v-select--selected': model.value.length,
  12205. 'v-select--selection-slot': !!slots.selection
  12206. }, props.class],
  12207. "style": props.style,
  12208. "inputmode": "none",
  12209. "placeholder": placeholder,
  12210. "onClick:clear": onClear,
  12211. "onMousedown:control": onMousedownControl,
  12212. "onBlur": onBlur,
  12213. "onKeydown": onKeydown,
  12214. "aria-label": t(label.value),
  12215. "title": t(label.value)
  12216. }), {
  12217. ...slots,
  12218. default: () => createVNode(Fragment, null, [createVNode(VMenu, mergeProps({
  12219. "ref": vMenuRef,
  12220. "modelValue": menu.value,
  12221. "onUpdate:modelValue": $event => menu.value = $event,
  12222. "activator": "parent",
  12223. "contentClass": "v-select__content",
  12224. "disabled": menuDisabled.value,
  12225. "eager": props.eager,
  12226. "maxHeight": 310,
  12227. "openOnClick": false,
  12228. "closeOnContentClick": false,
  12229. "transition": props.transition,
  12230. "onAfterEnter": onAfterEnter,
  12231. "onAfterLeave": onAfterLeave
  12232. }, computedMenuProps.value), {
  12233. default: () => [hasList && createVNode(VList, mergeProps({
  12234. "ref": listRef,
  12235. "selected": selectedValues.value,
  12236. "selectStrategy": props.multiple ? 'independent' : 'single-independent',
  12237. "onMousedown": e => e.preventDefault(),
  12238. "onKeydown": onListKeydown,
  12239. "onFocusin": onFocusin,
  12240. "tabindex": "-1",
  12241. "aria-live": "polite",
  12242. "color": props.itemColor ?? props.color
  12243. }, listEvents, props.listProps), {
  12244. default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? createVNode(VListItem, {
  12245. "key": "no-data",
  12246. "title": t(props.noDataText)
  12247. }, null)), createVNode(VVirtualScroll, {
  12248. "ref": vVirtualScrollRef,
  12249. "renderless": true,
  12250. "items": displayItems.value
  12251. }, {
  12252. default: _ref2 => {
  12253. let {
  12254. item,
  12255. index,
  12256. itemRef
  12257. } = _ref2;
  12258. const itemProps = mergeProps(item.props, {
  12259. ref: itemRef,
  12260. key: item.value,
  12261. onClick: () => select(item, null)
  12262. });
  12263. return slots.item?.({
  12264. item,
  12265. index,
  12266. props: itemProps
  12267. }) ?? createVNode(VListItem, mergeProps(itemProps, {
  12268. "role": "option"
  12269. }), {
  12270. prepend: _ref3 => {
  12271. let {
  12272. isSelected
  12273. } = _ref3;
  12274. return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
  12275. "key": item.value,
  12276. "modelValue": isSelected,
  12277. "ripple": false,
  12278. "tabindex": "-1"
  12279. }, null) : undefined, item.props.prependAvatar && createVNode(VAvatar, {
  12280. "image": item.props.prependAvatar
  12281. }, null), item.props.prependIcon && createVNode(VIcon, {
  12282. "icon": item.props.prependIcon
  12283. }, null)]);
  12284. }
  12285. });
  12286. }
  12287. }), slots['append-item']?.()]
  12288. })]
  12289. }), model.value.map((item, index) => {
  12290. function onChipClose(e) {
  12291. e.stopPropagation();
  12292. e.preventDefault();
  12293. select(item, false);
  12294. }
  12295. const slotProps = {
  12296. 'onClick:close': onChipClose,
  12297. onKeydown(e) {
  12298. if (e.key !== 'Enter' && e.key !== ' ') return;
  12299. e.preventDefault();
  12300. e.stopPropagation();
  12301. onChipClose(e);
  12302. },
  12303. onMousedown(e) {
  12304. e.preventDefault();
  12305. e.stopPropagation();
  12306. },
  12307. modelValue: true,
  12308. 'onUpdate:modelValue': undefined
  12309. };
  12310. const hasSlot = hasChips ? !!slots.chip : !!slots.selection;
  12311. const slotContent = hasSlot ? ensureValidVNode(hasChips ? slots.chip({
  12312. item,
  12313. index,
  12314. props: slotProps
  12315. }) : slots.selection({
  12316. item,
  12317. index
  12318. })) : undefined;
  12319. if (hasSlot && !slotContent) return undefined;
  12320. return createVNode("div", {
  12321. "key": item.value,
  12322. "class": "v-select__selection"
  12323. }, [hasChips ? !slots.chip ? createVNode(VChip, mergeProps({
  12324. "key": "chip",
  12325. "closable": props.closableChips,
  12326. "size": "small",
  12327. "text": item.title,
  12328. "disabled": item.props.disabled
  12329. }, slotProps), null) : createVNode(VDefaultsProvider, {
  12330. "key": "chip-defaults",
  12331. "defaults": {
  12332. VChip: {
  12333. closable: props.closableChips,
  12334. size: 'small',
  12335. text: item.title
  12336. }
  12337. }
  12338. }, {
  12339. default: () => [slotContent]
  12340. }) : slotContent ?? createVNode("span", {
  12341. "class": "v-select__selection-text"
  12342. }, [item.title, props.multiple && index < model.value.length - 1 && createVNode("span", {
  12343. "class": "v-select__selection-comma"
  12344. }, [createTextVNode(",")])])]);
  12345. })]),
  12346. 'append-inner': function () {
  12347. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  12348. args[_key] = arguments[_key];
  12349. }
  12350. return createVNode(Fragment, null, [slots['append-inner']?.(...args), props.menuIcon ? createVNode(VIcon, {
  12351. "class": "v-select__menu-icon",
  12352. "icon": props.menuIcon
  12353. }, null) : undefined]);
  12354. }
  12355. });
  12356. });
  12357. return forwardRefs({
  12358. isFocused,
  12359. menu,
  12360. select
  12361. }, vTextFieldRef);
  12362. }
  12363. });
  12364. /* eslint-disable max-statements */
  12365. /* eslint-disable no-labels */
  12366. // Types
  12367. /**
  12368. * - match without highlight
  12369. * - single match (index), length already known
  12370. * - single match (start, end)
  12371. * - multiple matches (start, end), probably shouldn't overlap
  12372. */
  12373. // Composables
  12374. const defaultFilter = (value, query, item) => {
  12375. if (value == null || query == null) return -1;
  12376. return value.toString().toLocaleLowerCase().indexOf(query.toString().toLocaleLowerCase());
  12377. };
  12378. const makeFilterProps = propsFactory({
  12379. customFilter: Function,
  12380. customKeyFilter: Object,
  12381. filterKeys: [Array, String],
  12382. filterMode: {
  12383. type: String,
  12384. default: 'intersection'
  12385. },
  12386. noFilter: Boolean
  12387. }, 'filter');
  12388. function filterItems(items, query, options) {
  12389. const array = [];
  12390. // always ensure we fall back to a functioning filter
  12391. const filter = options?.default ?? defaultFilter;
  12392. const keys = options?.filterKeys ? wrapInArray(options.filterKeys) : false;
  12393. const customFiltersLength = Object.keys(options?.customKeyFilter ?? {}).length;
  12394. if (!items?.length) return array;
  12395. loop: for (let i = 0; i < items.length; i++) {
  12396. const [item, transformed = item] = wrapInArray(items[i]);
  12397. const customMatches = {};
  12398. const defaultMatches = {};
  12399. let match = -1;
  12400. if ((query || customFiltersLength > 0) && !options?.noFilter) {
  12401. if (typeof item === 'object') {
  12402. const filterKeys = keys || Object.keys(transformed);
  12403. for (const key of filterKeys) {
  12404. const value = getPropertyFromItem(transformed, key);
  12405. const keyFilter = options?.customKeyFilter?.[key];
  12406. match = keyFilter ? keyFilter(value, query, item) : filter(value, query, item);
  12407. if (match !== -1 && match !== false) {
  12408. if (keyFilter) customMatches[key] = match;else defaultMatches[key] = match;
  12409. } else if (options?.filterMode === 'every') {
  12410. continue loop;
  12411. }
  12412. }
  12413. } else {
  12414. match = filter(item, query, item);
  12415. if (match !== -1 && match !== false) {
  12416. defaultMatches.title = match;
  12417. }
  12418. }
  12419. const defaultMatchesLength = Object.keys(defaultMatches).length;
  12420. const customMatchesLength = Object.keys(customMatches).length;
  12421. if (!defaultMatchesLength && !customMatchesLength) continue;
  12422. if (options?.filterMode === 'union' && customMatchesLength !== customFiltersLength && !defaultMatchesLength) continue;
  12423. if (options?.filterMode === 'intersection' && (customMatchesLength !== customFiltersLength || !defaultMatchesLength)) continue;
  12424. }
  12425. array.push({
  12426. index: i,
  12427. matches: {
  12428. ...defaultMatches,
  12429. ...customMatches
  12430. }
  12431. });
  12432. }
  12433. return array;
  12434. }
  12435. function useFilter(props, items, query, options) {
  12436. const filteredItems = ref([]);
  12437. const filteredMatches = ref(new Map());
  12438. const transformedItems = computed(() => options?.transform ? unref(items).map(item => [item, options.transform(item)]) : unref(items));
  12439. watchEffect(() => {
  12440. const _query = typeof query === 'function' ? query() : unref(query);
  12441. const strQuery = typeof _query !== 'string' && typeof _query !== 'number' ? '' : String(_query);
  12442. const results = filterItems(transformedItems.value, strQuery, {
  12443. customKeyFilter: {
  12444. ...props.customKeyFilter,
  12445. ...unref(options?.customKeyFilter)
  12446. },
  12447. default: props.customFilter,
  12448. filterKeys: props.filterKeys,
  12449. filterMode: props.filterMode,
  12450. noFilter: props.noFilter
  12451. });
  12452. const originalItems = unref(items);
  12453. const _filteredItems = [];
  12454. const _filteredMatches = new Map();
  12455. results.forEach(_ref => {
  12456. let {
  12457. index,
  12458. matches
  12459. } = _ref;
  12460. const item = originalItems[index];
  12461. _filteredItems.push(item);
  12462. _filteredMatches.set(item.value, matches);
  12463. });
  12464. filteredItems.value = _filteredItems;
  12465. filteredMatches.value = _filteredMatches;
  12466. });
  12467. function getMatches(item) {
  12468. return filteredMatches.value.get(item.value);
  12469. }
  12470. return {
  12471. filteredItems,
  12472. filteredMatches,
  12473. getMatches
  12474. };
  12475. }
  12476. // Types
  12477. function highlightResult$1(text, matches, length) {
  12478. if (matches == null) return text;
  12479. if (Array.isArray(matches)) throw new Error('Multiple matches is not implemented');
  12480. return typeof matches === 'number' && ~matches ? createVNode(Fragment, null, [createVNode("span", {
  12481. "class": "v-autocomplete__unmask"
  12482. }, [text.substr(0, matches)]), createVNode("span", {
  12483. "class": "v-autocomplete__mask"
  12484. }, [text.substr(matches, length)]), createVNode("span", {
  12485. "class": "v-autocomplete__unmask"
  12486. }, [text.substr(matches + length)])]) : text;
  12487. }
  12488. const makeVAutocompleteProps = propsFactory({
  12489. autoSelectFirst: {
  12490. type: [Boolean, String]
  12491. },
  12492. clearOnSelect: Boolean,
  12493. search: String,
  12494. ...makeFilterProps({
  12495. filterKeys: ['title']
  12496. }),
  12497. ...makeSelectProps(),
  12498. ...omit(makeVTextFieldProps({
  12499. modelValue: null,
  12500. role: 'combobox'
  12501. }), ['validationValue', 'dirty', 'appendInnerIcon']),
  12502. ...makeTransitionProps({
  12503. transition: false
  12504. })
  12505. }, 'VAutocomplete');
  12506. const VAutocomplete = genericComponent()({
  12507. name: 'VAutocomplete',
  12508. props: makeVAutocompleteProps(),
  12509. emits: {
  12510. 'update:focused': focused => true,
  12511. 'update:search': value => true,
  12512. 'update:modelValue': value => true,
  12513. 'update:menu': value => true
  12514. },
  12515. setup(props, _ref) {
  12516. let {
  12517. slots
  12518. } = _ref;
  12519. const {
  12520. t
  12521. } = useLocale();
  12522. const vTextFieldRef = ref();
  12523. const isFocused = shallowRef(false);
  12524. const isPristine = shallowRef(true);
  12525. const listHasFocus = shallowRef(false);
  12526. const vMenuRef = ref();
  12527. const vVirtualScrollRef = ref();
  12528. const _menu = useProxiedModel(props, 'menu');
  12529. const menu = computed({
  12530. get: () => _menu.value,
  12531. set: v => {
  12532. if (_menu.value && !v && vMenuRef.value?.ΨopenChildren.size) return;
  12533. _menu.value = v;
  12534. }
  12535. });
  12536. const selectionIndex = shallowRef(-1);
  12537. const color = computed(() => vTextFieldRef.value?.color);
  12538. const label = computed(() => menu.value ? props.closeText : props.openText);
  12539. const {
  12540. items,
  12541. transformIn,
  12542. transformOut
  12543. } = useItems(props);
  12544. const {
  12545. textColorClasses,
  12546. textColorStyles
  12547. } = useTextColor(color);
  12548. const search = useProxiedModel(props, 'search', '');
  12549. const model = useProxiedModel(props, 'modelValue', [], v => transformIn(v === null ? [null] : wrapInArray(v)), v => {
  12550. const transformed = transformOut(v);
  12551. return props.multiple ? transformed : transformed[0] ?? null;
  12552. });
  12553. const counterValue = computed(() => {
  12554. return typeof props.counterValue === 'function' ? props.counterValue(model.value) : typeof props.counterValue === 'number' ? props.counterValue : model.value.length;
  12555. });
  12556. const form = useForm(props);
  12557. const {
  12558. filteredItems,
  12559. getMatches
  12560. } = useFilter(props, items, () => isPristine.value ? '' : search.value);
  12561. const displayItems = computed(() => {
  12562. if (props.hideSelected) {
  12563. return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value));
  12564. }
  12565. return filteredItems.value;
  12566. });
  12567. const hasChips = computed(() => !!(props.chips || slots.chip));
  12568. const hasSelectionSlot = computed(() => hasChips.value || !!slots.selection);
  12569. const selectedValues = computed(() => model.value.map(selection => selection.props.value));
  12570. const highlightFirst = computed(() => {
  12571. const selectFirst = props.autoSelectFirst === true || props.autoSelectFirst === 'exact' && search.value === displayItems.value[0]?.title;
  12572. return selectFirst && displayItems.value.length > 0 && !isPristine.value && !listHasFocus.value;
  12573. });
  12574. const menuDisabled = computed(() => props.hideNoData && !displayItems.value.length || form.isReadonly.value || form.isDisabled.value);
  12575. const listRef = ref();
  12576. const listEvents = useScrolling(listRef, vTextFieldRef);
  12577. function onClear(e) {
  12578. if (props.openOnClear) {
  12579. menu.value = true;
  12580. }
  12581. search.value = '';
  12582. }
  12583. function onMousedownControl() {
  12584. if (menuDisabled.value) return;
  12585. menu.value = true;
  12586. }
  12587. function onMousedownMenuIcon(e) {
  12588. if (menuDisabled.value) return;
  12589. if (isFocused.value) {
  12590. e.preventDefault();
  12591. e.stopPropagation();
  12592. }
  12593. menu.value = !menu.value;
  12594. }
  12595. function onListKeydown(e) {
  12596. if (checkPrintable(e)) {
  12597. vTextFieldRef.value?.focus();
  12598. }
  12599. }
  12600. function onKeydown(e) {
  12601. if (form.isReadonly.value) return;
  12602. const selectionStart = vTextFieldRef.value.selectionStart;
  12603. const length = model.value.length;
  12604. if (selectionIndex.value > -1 || ['Enter', 'ArrowDown', 'ArrowUp'].includes(e.key)) {
  12605. e.preventDefault();
  12606. }
  12607. if (['Enter', 'ArrowDown'].includes(e.key)) {
  12608. menu.value = true;
  12609. }
  12610. if (['Escape'].includes(e.key)) {
  12611. menu.value = false;
  12612. }
  12613. if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key) && !model.value.some(_ref2 => {
  12614. let {
  12615. value
  12616. } = _ref2;
  12617. return value === displayItems.value[0].value;
  12618. })) {
  12619. select(displayItems.value[0]);
  12620. }
  12621. if (e.key === 'ArrowDown' && highlightFirst.value) {
  12622. listRef.value?.focus('next');
  12623. }
  12624. if (['Backspace', 'Delete'].includes(e.key)) {
  12625. if (!props.multiple && hasSelectionSlot.value && model.value.length > 0 && !search.value) return select(model.value[0], false);
  12626. if (~selectionIndex.value) {
  12627. const originalSelectionIndex = selectionIndex.value;
  12628. select(model.value[selectionIndex.value], false);
  12629. selectionIndex.value = originalSelectionIndex >= length - 1 ? length - 2 : originalSelectionIndex;
  12630. } else if (e.key === 'Backspace' && !search.value) {
  12631. selectionIndex.value = length - 1;
  12632. }
  12633. }
  12634. if (!props.multiple) return;
  12635. if (e.key === 'ArrowLeft') {
  12636. if (selectionIndex.value < 0 && selectionStart > 0) return;
  12637. const prev = selectionIndex.value > -1 ? selectionIndex.value - 1 : length - 1;
  12638. if (model.value[prev]) {
  12639. selectionIndex.value = prev;
  12640. } else {
  12641. selectionIndex.value = -1;
  12642. vTextFieldRef.value.setSelectionRange(search.value?.length, search.value?.length);
  12643. }
  12644. }
  12645. if (e.key === 'ArrowRight') {
  12646. if (selectionIndex.value < 0) return;
  12647. const next = selectionIndex.value + 1;
  12648. if (model.value[next]) {
  12649. selectionIndex.value = next;
  12650. } else {
  12651. selectionIndex.value = -1;
  12652. vTextFieldRef.value.setSelectionRange(0, 0);
  12653. }
  12654. }
  12655. }
  12656. function onChange(e) {
  12657. if (matchesSelector(vTextFieldRef.value, ':autofill') || matchesSelector(vTextFieldRef.value, ':-webkit-autofill')) {
  12658. const item = items.value.find(item => item.title === e.target.value);
  12659. if (item) {
  12660. select(item);
  12661. }
  12662. }
  12663. }
  12664. function onAfterEnter() {
  12665. if (props.eager) {
  12666. vVirtualScrollRef.value?.calculateVisibleItems();
  12667. }
  12668. }
  12669. function onAfterLeave() {
  12670. if (isFocused.value) {
  12671. isPristine.value = true;
  12672. vTextFieldRef.value?.focus();
  12673. }
  12674. }
  12675. function onFocusin(e) {
  12676. isFocused.value = true;
  12677. setTimeout(() => {
  12678. listHasFocus.value = true;
  12679. });
  12680. }
  12681. function onFocusout(e) {
  12682. listHasFocus.value = false;
  12683. }
  12684. function onUpdateModelValue(v) {
  12685. if (v == null || v === '' && !props.multiple && !hasSelectionSlot.value) model.value = [];
  12686. }
  12687. const isSelecting = shallowRef(false);
  12688. /** @param set - null means toggle */
  12689. function select(item) {
  12690. let set = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  12691. if (!item || item.props.disabled) return;
  12692. if (props.multiple) {
  12693. const index = model.value.findIndex(selection => props.valueComparator(selection.value, item.value));
  12694. const add = set == null ? !~index : set;
  12695. if (~index) {
  12696. const value = add ? [...model.value, item] : [...model.value];
  12697. value.splice(index, 1);
  12698. model.value = value;
  12699. } else if (add) {
  12700. model.value = [...model.value, item];
  12701. }
  12702. if (props.clearOnSelect) {
  12703. search.value = '';
  12704. }
  12705. } else {
  12706. const add = set !== false;
  12707. model.value = add ? [item] : [];
  12708. search.value = add && !hasSelectionSlot.value ? item.title : '';
  12709. // watch for search watcher to trigger
  12710. nextTick(() => {
  12711. menu.value = false;
  12712. isPristine.value = true;
  12713. });
  12714. }
  12715. }
  12716. watch(isFocused, (val, oldVal) => {
  12717. if (val === oldVal) return;
  12718. if (val) {
  12719. isSelecting.value = true;
  12720. search.value = props.multiple || hasSelectionSlot.value ? '' : String(model.value.at(-1)?.props.title ?? '');
  12721. isPristine.value = true;
  12722. nextTick(() => isSelecting.value = false);
  12723. } else {
  12724. if (!props.multiple && search.value == null) model.value = [];
  12725. menu.value = false;
  12726. if (!model.value.some(_ref3 => {
  12727. let {
  12728. title
  12729. } = _ref3;
  12730. return title === search.value;
  12731. })) search.value = '';
  12732. selectionIndex.value = -1;
  12733. }
  12734. });
  12735. watch(search, val => {
  12736. if (!isFocused.value || isSelecting.value) return;
  12737. if (val) menu.value = true;
  12738. isPristine.value = !val;
  12739. });
  12740. watch(menu, () => {
  12741. if (!props.hideSelected && menu.value && model.value.length) {
  12742. const index = displayItems.value.findIndex(item => model.value.some(s => item.value === s.value));
  12743. IN_BROWSER && window.requestAnimationFrame(() => {
  12744. index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
  12745. });
  12746. }
  12747. });
  12748. watch(() => props.items, (newVal, oldVal) => {
  12749. if (menu.value) return;
  12750. if (isFocused.value && !oldVal.length && newVal.length) {
  12751. menu.value = true;
  12752. }
  12753. });
  12754. useRender(() => {
  12755. const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
  12756. const isDirty = model.value.length > 0;
  12757. const textFieldProps = VTextField.filterProps(props);
  12758. return createVNode(VTextField, mergeProps({
  12759. "ref": vTextFieldRef
  12760. }, textFieldProps, {
  12761. "modelValue": search.value,
  12762. "onUpdate:modelValue": [$event => search.value = $event, onUpdateModelValue],
  12763. "focused": isFocused.value,
  12764. "onUpdate:focused": $event => isFocused.value = $event,
  12765. "validationValue": model.externalValue,
  12766. "counterValue": counterValue.value,
  12767. "dirty": isDirty,
  12768. "onChange": onChange,
  12769. "class": ['v-autocomplete', `v-autocomplete--${props.multiple ? 'multiple' : 'single'}`, {
  12770. 'v-autocomplete--active-menu': menu.value,
  12771. 'v-autocomplete--chips': !!props.chips,
  12772. 'v-autocomplete--selection-slot': !!hasSelectionSlot.value,
  12773. 'v-autocomplete--selecting-index': selectionIndex.value > -1
  12774. }, props.class],
  12775. "style": props.style,
  12776. "readonly": form.isReadonly.value,
  12777. "placeholder": isDirty ? undefined : props.placeholder,
  12778. "onClick:clear": onClear,
  12779. "onMousedown:control": onMousedownControl,
  12780. "onKeydown": onKeydown
  12781. }), {
  12782. ...slots,
  12783. default: () => createVNode(Fragment, null, [createVNode(VMenu, mergeProps({
  12784. "ref": vMenuRef,
  12785. "modelValue": menu.value,
  12786. "onUpdate:modelValue": $event => menu.value = $event,
  12787. "activator": "parent",
  12788. "contentClass": "v-autocomplete__content",
  12789. "disabled": menuDisabled.value,
  12790. "eager": props.eager,
  12791. "maxHeight": 310,
  12792. "openOnClick": false,
  12793. "closeOnContentClick": false,
  12794. "transition": props.transition,
  12795. "onAfterEnter": onAfterEnter,
  12796. "onAfterLeave": onAfterLeave
  12797. }, props.menuProps), {
  12798. default: () => [hasList && createVNode(VList, mergeProps({
  12799. "ref": listRef,
  12800. "selected": selectedValues.value,
  12801. "selectStrategy": props.multiple ? 'independent' : 'single-independent',
  12802. "onMousedown": e => e.preventDefault(),
  12803. "onKeydown": onListKeydown,
  12804. "onFocusin": onFocusin,
  12805. "onFocusout": onFocusout,
  12806. "tabindex": "-1",
  12807. "aria-live": "polite",
  12808. "color": props.itemColor ?? props.color
  12809. }, listEvents, props.listProps), {
  12810. default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? createVNode(VListItem, {
  12811. "key": "no-data",
  12812. "title": t(props.noDataText)
  12813. }, null)), createVNode(VVirtualScroll, {
  12814. "ref": vVirtualScrollRef,
  12815. "renderless": true,
  12816. "items": displayItems.value
  12817. }, {
  12818. default: _ref4 => {
  12819. let {
  12820. item,
  12821. index,
  12822. itemRef
  12823. } = _ref4;
  12824. const itemProps = mergeProps(item.props, {
  12825. ref: itemRef,
  12826. key: item.value,
  12827. active: highlightFirst.value && index === 0 ? true : undefined,
  12828. onClick: () => select(item, null)
  12829. });
  12830. return slots.item?.({
  12831. item,
  12832. index,
  12833. props: itemProps
  12834. }) ?? createVNode(VListItem, mergeProps(itemProps, {
  12835. "role": "option"
  12836. }), {
  12837. prepend: _ref5 => {
  12838. let {
  12839. isSelected
  12840. } = _ref5;
  12841. return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
  12842. "key": item.value,
  12843. "modelValue": isSelected,
  12844. "ripple": false,
  12845. "tabindex": "-1"
  12846. }, null) : undefined, item.props.prependAvatar && createVNode(VAvatar, {
  12847. "image": item.props.prependAvatar
  12848. }, null), item.props.prependIcon && createVNode(VIcon, {
  12849. "icon": item.props.prependIcon
  12850. }, null)]);
  12851. },
  12852. title: () => {
  12853. return isPristine.value ? item.title : highlightResult$1(item.title, getMatches(item)?.title, search.value?.length ?? 0);
  12854. }
  12855. });
  12856. }
  12857. }), slots['append-item']?.()]
  12858. })]
  12859. }), model.value.map((item, index) => {
  12860. function onChipClose(e) {
  12861. e.stopPropagation();
  12862. e.preventDefault();
  12863. select(item, false);
  12864. }
  12865. const slotProps = {
  12866. 'onClick:close': onChipClose,
  12867. onKeydown(e) {
  12868. if (e.key !== 'Enter' && e.key !== ' ') return;
  12869. e.preventDefault();
  12870. e.stopPropagation();
  12871. onChipClose(e);
  12872. },
  12873. onMousedown(e) {
  12874. e.preventDefault();
  12875. e.stopPropagation();
  12876. },
  12877. modelValue: true,
  12878. 'onUpdate:modelValue': undefined
  12879. };
  12880. const hasSlot = hasChips.value ? !!slots.chip : !!slots.selection;
  12881. const slotContent = hasSlot ? ensureValidVNode(hasChips.value ? slots.chip({
  12882. item,
  12883. index,
  12884. props: slotProps
  12885. }) : slots.selection({
  12886. item,
  12887. index
  12888. })) : undefined;
  12889. if (hasSlot && !slotContent) return undefined;
  12890. return createVNode("div", {
  12891. "key": item.value,
  12892. "class": ['v-autocomplete__selection', index === selectionIndex.value && ['v-autocomplete__selection--selected', textColorClasses.value]],
  12893. "style": index === selectionIndex.value ? textColorStyles.value : {}
  12894. }, [hasChips.value ? !slots.chip ? createVNode(VChip, mergeProps({
  12895. "key": "chip",
  12896. "closable": props.closableChips,
  12897. "size": "small",
  12898. "text": item.title,
  12899. "disabled": item.props.disabled
  12900. }, slotProps), null) : createVNode(VDefaultsProvider, {
  12901. "key": "chip-defaults",
  12902. "defaults": {
  12903. VChip: {
  12904. closable: props.closableChips,
  12905. size: 'small',
  12906. text: item.title
  12907. }
  12908. }
  12909. }, {
  12910. default: () => [slotContent]
  12911. }) : slotContent ?? createVNode("span", {
  12912. "class": "v-autocomplete__selection-text"
  12913. }, [item.title, props.multiple && index < model.value.length - 1 && createVNode("span", {
  12914. "class": "v-autocomplete__selection-comma"
  12915. }, [createTextVNode(",")])])]);
  12916. })]),
  12917. 'append-inner': function () {
  12918. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  12919. args[_key] = arguments[_key];
  12920. }
  12921. return createVNode(Fragment, null, [slots['append-inner']?.(...args), props.menuIcon ? createVNode(VIcon, {
  12922. "class": "v-autocomplete__menu-icon",
  12923. "icon": props.menuIcon,
  12924. "onMousedown": onMousedownMenuIcon,
  12925. "onClick": noop,
  12926. "aria-label": t(label.value),
  12927. "title": t(label.value),
  12928. "tabindex": "-1"
  12929. }, null) : undefined]);
  12930. }
  12931. });
  12932. });
  12933. return forwardRefs({
  12934. isFocused,
  12935. isPristine,
  12936. menu,
  12937. search,
  12938. filteredItems,
  12939. select
  12940. }, vTextFieldRef);
  12941. }
  12942. });
  12943. const makeVBadgeProps = propsFactory({
  12944. bordered: Boolean,
  12945. color: String,
  12946. content: [Number, String],
  12947. dot: Boolean,
  12948. floating: Boolean,
  12949. icon: IconValue,
  12950. inline: Boolean,
  12951. label: {
  12952. type: String,
  12953. default: '$vuetify.badge'
  12954. },
  12955. max: [Number, String],
  12956. modelValue: {
  12957. type: Boolean,
  12958. default: true
  12959. },
  12960. offsetX: [Number, String],
  12961. offsetY: [Number, String],
  12962. textColor: String,
  12963. ...makeComponentProps(),
  12964. ...makeLocationProps({
  12965. location: 'top end'
  12966. }),
  12967. ...makeRoundedProps(),
  12968. ...makeTagProps(),
  12969. ...makeThemeProps(),
  12970. ...makeTransitionProps({
  12971. transition: 'scale-rotate-transition'
  12972. })
  12973. }, 'VBadge');
  12974. const VBadge = genericComponent()({
  12975. name: 'VBadge',
  12976. inheritAttrs: false,
  12977. props: makeVBadgeProps(),
  12978. setup(props, ctx) {
  12979. const {
  12980. backgroundColorClasses,
  12981. backgroundColorStyles
  12982. } = useBackgroundColor(toRef(props, 'color'));
  12983. const {
  12984. roundedClasses
  12985. } = useRounded(props);
  12986. const {
  12987. t
  12988. } = useLocale();
  12989. const {
  12990. textColorClasses,
  12991. textColorStyles
  12992. } = useTextColor(toRef(props, 'textColor'));
  12993. const {
  12994. themeClasses
  12995. } = useTheme();
  12996. const {
  12997. locationStyles
  12998. } = useLocation(props, true, side => {
  12999. const base = props.floating ? props.dot ? 2 : 4 : props.dot ? 8 : 12;
  13000. return base + (['top', 'bottom'].includes(side) ? +(props.offsetY ?? 0) : ['left', 'right'].includes(side) ? +(props.offsetX ?? 0) : 0);
  13001. });
  13002. useRender(() => {
  13003. const value = Number(props.content);
  13004. const content = !props.max || isNaN(value) ? props.content : value <= +props.max ? value : `${props.max}+`;
  13005. const [badgeAttrs, attrs] = pickWithRest(ctx.attrs, ['aria-atomic', 'aria-label', 'aria-live', 'role', 'title']);
  13006. return createVNode(props.tag, mergeProps({
  13007. "class": ['v-badge', {
  13008. 'v-badge--bordered': props.bordered,
  13009. 'v-badge--dot': props.dot,
  13010. 'v-badge--floating': props.floating,
  13011. 'v-badge--inline': props.inline
  13012. }, props.class]
  13013. }, attrs, {
  13014. "style": props.style
  13015. }), {
  13016. default: () => [createVNode("div", {
  13017. "class": "v-badge__wrapper"
  13018. }, [ctx.slots.default?.(), createVNode(MaybeTransition, {
  13019. "transition": props.transition
  13020. }, {
  13021. default: () => [withDirectives(createVNode("span", mergeProps({
  13022. "class": ['v-badge__badge', themeClasses.value, backgroundColorClasses.value, roundedClasses.value, textColorClasses.value],
  13023. "style": [backgroundColorStyles.value, textColorStyles.value, props.inline ? {} : locationStyles.value],
  13024. "aria-atomic": "true",
  13025. "aria-label": t(props.label, value),
  13026. "aria-live": "polite",
  13027. "role": "status"
  13028. }, badgeAttrs), [props.dot ? undefined : ctx.slots.badge ? ctx.slots.badge?.() : props.icon ? createVNode(VIcon, {
  13029. "icon": props.icon
  13030. }, null) : content]), [[vShow, props.modelValue]])]
  13031. })])]
  13032. });
  13033. });
  13034. return {};
  13035. }
  13036. });
  13037. const makeVBannerActionsProps = propsFactory({
  13038. color: String,
  13039. density: String,
  13040. ...makeComponentProps()
  13041. }, 'VBannerActions');
  13042. const VBannerActions = genericComponent()({
  13043. name: 'VBannerActions',
  13044. props: makeVBannerActionsProps(),
  13045. setup(props, _ref) {
  13046. let {
  13047. slots
  13048. } = _ref;
  13049. provideDefaults({
  13050. VBtn: {
  13051. color: props.color,
  13052. density: props.density,
  13053. slim: true,
  13054. variant: 'text'
  13055. }
  13056. });
  13057. useRender(() => createVNode("div", {
  13058. "class": ['v-banner-actions', props.class],
  13059. "style": props.style
  13060. }, [slots.default?.()]));
  13061. return {};
  13062. }
  13063. });
  13064. // Utilities
  13065. const VBannerText = createSimpleFunctional('v-banner-text');
  13066. // Types
  13067. const makeVBannerProps = propsFactory({
  13068. avatar: String,
  13069. bgColor: String,
  13070. color: String,
  13071. icon: IconValue,
  13072. lines: String,
  13073. stacked: Boolean,
  13074. sticky: Boolean,
  13075. text: String,
  13076. ...makeBorderProps(),
  13077. ...makeComponentProps(),
  13078. ...makeDensityProps(),
  13079. ...makeDimensionProps(),
  13080. ...makeDisplayProps({
  13081. mobile: null
  13082. }),
  13083. ...makeElevationProps(),
  13084. ...makeLocationProps(),
  13085. ...makePositionProps(),
  13086. ...makeRoundedProps(),
  13087. ...makeTagProps(),
  13088. ...makeThemeProps()
  13089. }, 'VBanner');
  13090. const VBanner = genericComponent()({
  13091. name: 'VBanner',
  13092. props: makeVBannerProps(),
  13093. setup(props, _ref) {
  13094. let {
  13095. slots
  13096. } = _ref;
  13097. const {
  13098. backgroundColorClasses,
  13099. backgroundColorStyles
  13100. } = useBackgroundColor(props, 'bgColor');
  13101. const {
  13102. borderClasses
  13103. } = useBorder(props);
  13104. const {
  13105. densityClasses
  13106. } = useDensity(props);
  13107. const {
  13108. displayClasses,
  13109. mobile
  13110. } = useDisplay(props);
  13111. const {
  13112. dimensionStyles
  13113. } = useDimension(props);
  13114. const {
  13115. elevationClasses
  13116. } = useElevation(props);
  13117. const {
  13118. locationStyles
  13119. } = useLocation(props);
  13120. const {
  13121. positionClasses
  13122. } = usePosition(props);
  13123. const {
  13124. roundedClasses
  13125. } = useRounded(props);
  13126. const {
  13127. themeClasses
  13128. } = provideTheme(props);
  13129. const color = toRef(props, 'color');
  13130. const density = toRef(props, 'density');
  13131. provideDefaults({
  13132. VBannerActions: {
  13133. color,
  13134. density
  13135. }
  13136. });
  13137. useRender(() => {
  13138. const hasText = !!(props.text || slots.text);
  13139. const hasPrependMedia = !!(props.avatar || props.icon);
  13140. const hasPrepend = !!(hasPrependMedia || slots.prepend);
  13141. return createVNode(props.tag, {
  13142. "class": ['v-banner', {
  13143. 'v-banner--stacked': props.stacked || mobile.value,
  13144. 'v-banner--sticky': props.sticky,
  13145. [`v-banner--${props.lines}-line`]: !!props.lines
  13146. }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, densityClasses.value, displayClasses.value, elevationClasses.value, positionClasses.value, roundedClasses.value, props.class],
  13147. "style": [backgroundColorStyles.value, dimensionStyles.value, locationStyles.value, props.style],
  13148. "role": "banner"
  13149. }, {
  13150. default: () => [hasPrepend && createVNode("div", {
  13151. "key": "prepend",
  13152. "class": "v-banner__prepend"
  13153. }, [!slots.prepend ? createVNode(VAvatar, {
  13154. "key": "prepend-avatar",
  13155. "color": color.value,
  13156. "density": density.value,
  13157. "icon": props.icon,
  13158. "image": props.avatar
  13159. }, null) : createVNode(VDefaultsProvider, {
  13160. "key": "prepend-defaults",
  13161. "disabled": !hasPrependMedia,
  13162. "defaults": {
  13163. VAvatar: {
  13164. color: color.value,
  13165. density: density.value,
  13166. icon: props.icon,
  13167. image: props.avatar
  13168. }
  13169. }
  13170. }, slots.prepend)]), createVNode("div", {
  13171. "class": "v-banner__content"
  13172. }, [hasText && createVNode(VBannerText, {
  13173. "key": "text"
  13174. }, {
  13175. default: () => [slots.text?.() ?? props.text]
  13176. }), slots.default?.()]), slots.actions && createVNode(VBannerActions, {
  13177. "key": "actions"
  13178. }, slots.actions)]
  13179. });
  13180. });
  13181. }
  13182. });
  13183. // Types
  13184. const makeVBottomNavigationProps = propsFactory({
  13185. baseColor: String,
  13186. bgColor: String,
  13187. color: String,
  13188. grow: Boolean,
  13189. mode: {
  13190. type: String,
  13191. validator: v => !v || ['horizontal', 'shift'].includes(v)
  13192. },
  13193. height: {
  13194. type: [Number, String],
  13195. default: 56
  13196. },
  13197. active: {
  13198. type: Boolean,
  13199. default: true
  13200. },
  13201. ...makeBorderProps(),
  13202. ...makeComponentProps(),
  13203. ...makeDensityProps(),
  13204. ...makeElevationProps(),
  13205. ...makeRoundedProps(),
  13206. ...makeLayoutItemProps({
  13207. name: 'bottom-navigation'
  13208. }),
  13209. ...makeTagProps({
  13210. tag: 'header'
  13211. }),
  13212. ...makeGroupProps({
  13213. selectedClass: 'v-btn--selected'
  13214. }),
  13215. ...makeThemeProps()
  13216. }, 'VBottomNavigation');
  13217. const VBottomNavigation = genericComponent()({
  13218. name: 'VBottomNavigation',
  13219. props: makeVBottomNavigationProps(),
  13220. emits: {
  13221. 'update:active': value => true,
  13222. 'update:modelValue': value => true
  13223. },
  13224. setup(props, _ref) {
  13225. let {
  13226. slots
  13227. } = _ref;
  13228. const {
  13229. themeClasses
  13230. } = useTheme();
  13231. const {
  13232. borderClasses
  13233. } = useBorder(props);
  13234. const {
  13235. backgroundColorClasses,
  13236. backgroundColorStyles
  13237. } = useBackgroundColor(toRef(props, 'bgColor'));
  13238. const {
  13239. densityClasses
  13240. } = useDensity(props);
  13241. const {
  13242. elevationClasses
  13243. } = useElevation(props);
  13244. const {
  13245. roundedClasses
  13246. } = useRounded(props);
  13247. const {
  13248. ssrBootStyles
  13249. } = useSsrBoot();
  13250. const height = computed(() => Number(props.height) - (props.density === 'comfortable' ? 8 : 0) - (props.density === 'compact' ? 16 : 0));
  13251. const isActive = useProxiedModel(props, 'active', props.active);
  13252. const {
  13253. layoutItemStyles
  13254. } = useLayoutItem({
  13255. id: props.name,
  13256. order: computed(() => parseInt(props.order, 10)),
  13257. position: computed(() => 'bottom'),
  13258. layoutSize: computed(() => isActive.value ? height.value : 0),
  13259. elementSize: height,
  13260. active: isActive,
  13261. absolute: toRef(props, 'absolute')
  13262. });
  13263. useGroup(props, VBtnToggleSymbol);
  13264. provideDefaults({
  13265. VBtn: {
  13266. baseColor: toRef(props, 'baseColor'),
  13267. color: toRef(props, 'color'),
  13268. density: toRef(props, 'density'),
  13269. stacked: computed(() => props.mode !== 'horizontal'),
  13270. variant: 'text'
  13271. }
  13272. }, {
  13273. scoped: true
  13274. });
  13275. useRender(() => {
  13276. return createVNode(props.tag, {
  13277. "class": ['v-bottom-navigation', {
  13278. 'v-bottom-navigation--active': isActive.value,
  13279. 'v-bottom-navigation--grow': props.grow,
  13280. 'v-bottom-navigation--shift': props.mode === 'shift'
  13281. }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, densityClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  13282. "style": [backgroundColorStyles.value, layoutItemStyles.value, {
  13283. height: convertToUnit(height.value)
  13284. }, ssrBootStyles.value, props.style]
  13285. }, {
  13286. default: () => [slots.default && createVNode("div", {
  13287. "class": "v-bottom-navigation__content"
  13288. }, [slots.default()])]
  13289. });
  13290. });
  13291. return {};
  13292. }
  13293. });
  13294. // Types
  13295. const makeVDialogProps = propsFactory({
  13296. fullscreen: Boolean,
  13297. retainFocus: {
  13298. type: Boolean,
  13299. default: true
  13300. },
  13301. scrollable: Boolean,
  13302. ...makeVOverlayProps({
  13303. origin: 'center center',
  13304. scrollStrategy: 'block',
  13305. transition: {
  13306. component: VDialogTransition
  13307. },
  13308. zIndex: 2400
  13309. })
  13310. }, 'VDialog');
  13311. const VDialog = genericComponent()({
  13312. name: 'VDialog',
  13313. props: makeVDialogProps(),
  13314. emits: {
  13315. 'update:modelValue': value => true,
  13316. afterEnter: () => true,
  13317. afterLeave: () => true
  13318. },
  13319. setup(props, _ref) {
  13320. let {
  13321. emit,
  13322. slots
  13323. } = _ref;
  13324. const isActive = useProxiedModel(props, 'modelValue');
  13325. const {
  13326. scopeId
  13327. } = useScopeId();
  13328. const overlay = ref();
  13329. function onFocusin(e) {
  13330. const before = e.relatedTarget;
  13331. const after = e.target;
  13332. if (before !== after && overlay.value?.contentEl &&
  13333. // We're the topmost dialog
  13334. overlay.value?.globalTop &&
  13335. // It isn't the document or the dialog body
  13336. ![document, overlay.value.contentEl].includes(after) &&
  13337. // It isn't inside the dialog body
  13338. !overlay.value.contentEl.contains(after)) {
  13339. const focusable = focusableChildren(overlay.value.contentEl);
  13340. if (!focusable.length) return;
  13341. const firstElement = focusable[0];
  13342. const lastElement = focusable[focusable.length - 1];
  13343. if (before === firstElement) {
  13344. lastElement.focus();
  13345. } else {
  13346. firstElement.focus();
  13347. }
  13348. }
  13349. }
  13350. onBeforeUnmount(() => {
  13351. document.removeEventListener('focusin', onFocusin);
  13352. });
  13353. if (IN_BROWSER) {
  13354. watch(() => isActive.value && props.retainFocus, val => {
  13355. val ? document.addEventListener('focusin', onFocusin) : document.removeEventListener('focusin', onFocusin);
  13356. }, {
  13357. immediate: true
  13358. });
  13359. }
  13360. function onAfterEnter() {
  13361. emit('afterEnter');
  13362. if (overlay.value?.contentEl && !overlay.value.contentEl.contains(document.activeElement)) {
  13363. overlay.value.contentEl.focus({
  13364. preventScroll: true
  13365. });
  13366. }
  13367. }
  13368. function onAfterLeave() {
  13369. emit('afterLeave');
  13370. }
  13371. watch(isActive, async val => {
  13372. if (!val) {
  13373. await nextTick();
  13374. overlay.value.activatorEl?.focus({
  13375. preventScroll: true
  13376. });
  13377. }
  13378. });
  13379. useRender(() => {
  13380. const overlayProps = VOverlay.filterProps(props);
  13381. const activatorProps = mergeProps({
  13382. 'aria-haspopup': 'dialog'
  13383. }, props.activatorProps);
  13384. const contentProps = mergeProps({
  13385. tabindex: -1
  13386. }, props.contentProps);
  13387. return createVNode(VOverlay, mergeProps({
  13388. "ref": overlay,
  13389. "class": ['v-dialog', {
  13390. 'v-dialog--fullscreen': props.fullscreen,
  13391. 'v-dialog--scrollable': props.scrollable
  13392. }, props.class],
  13393. "style": props.style
  13394. }, overlayProps, {
  13395. "modelValue": isActive.value,
  13396. "onUpdate:modelValue": $event => isActive.value = $event,
  13397. "aria-modal": "true",
  13398. "activatorProps": activatorProps,
  13399. "contentProps": contentProps,
  13400. "height": !props.fullscreen ? props.height : undefined,
  13401. "width": !props.fullscreen ? props.width : undefined,
  13402. "maxHeight": !props.fullscreen ? props.maxHeight : undefined,
  13403. "maxWidth": !props.fullscreen ? props.maxWidth : undefined,
  13404. "role": "dialog",
  13405. "onAfterEnter": onAfterEnter,
  13406. "onAfterLeave": onAfterLeave
  13407. }, scopeId), {
  13408. activator: slots.activator,
  13409. default: function () {
  13410. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  13411. args[_key] = arguments[_key];
  13412. }
  13413. return createVNode(VDefaultsProvider, {
  13414. "root": "VDialog"
  13415. }, {
  13416. default: () => [slots.default?.(...args)]
  13417. });
  13418. }
  13419. });
  13420. });
  13421. return forwardRefs({}, overlay);
  13422. }
  13423. });
  13424. // Types
  13425. const makeVBottomSheetProps = propsFactory({
  13426. inset: Boolean,
  13427. ...makeVDialogProps({
  13428. transition: 'bottom-sheet-transition'
  13429. })
  13430. }, 'VBottomSheet');
  13431. const VBottomSheet = genericComponent()({
  13432. name: 'VBottomSheet',
  13433. props: makeVBottomSheetProps(),
  13434. emits: {
  13435. 'update:modelValue': value => true
  13436. },
  13437. setup(props, _ref) {
  13438. let {
  13439. slots
  13440. } = _ref;
  13441. const isActive = useProxiedModel(props, 'modelValue');
  13442. useRender(() => {
  13443. const dialogProps = VDialog.filterProps(props);
  13444. return createVNode(VDialog, mergeProps(dialogProps, {
  13445. "contentClass": ['v-bottom-sheet__content', props.contentClass],
  13446. "modelValue": isActive.value,
  13447. "onUpdate:modelValue": $event => isActive.value = $event,
  13448. "class": ['v-bottom-sheet', {
  13449. 'v-bottom-sheet--inset': props.inset
  13450. }, props.class],
  13451. "style": props.style
  13452. }), slots);
  13453. });
  13454. return {};
  13455. }
  13456. });
  13457. const makeVBreadcrumbsDividerProps = propsFactory({
  13458. divider: [Number, String],
  13459. ...makeComponentProps()
  13460. }, 'VBreadcrumbsDivider');
  13461. const VBreadcrumbsDivider = genericComponent()({
  13462. name: 'VBreadcrumbsDivider',
  13463. props: makeVBreadcrumbsDividerProps(),
  13464. setup(props, _ref) {
  13465. let {
  13466. slots
  13467. } = _ref;
  13468. useRender(() => createVNode("li", {
  13469. "class": ['v-breadcrumbs-divider', props.class],
  13470. "style": props.style
  13471. }, [slots?.default?.() ?? props.divider]));
  13472. return {};
  13473. }
  13474. });
  13475. const makeVBreadcrumbsItemProps = propsFactory({
  13476. active: Boolean,
  13477. activeClass: String,
  13478. activeColor: String,
  13479. color: String,
  13480. disabled: Boolean,
  13481. title: String,
  13482. ...makeComponentProps(),
  13483. ...makeRouterProps(),
  13484. ...makeTagProps({
  13485. tag: 'li'
  13486. })
  13487. }, 'VBreadcrumbsItem');
  13488. const VBreadcrumbsItem = genericComponent()({
  13489. name: 'VBreadcrumbsItem',
  13490. props: makeVBreadcrumbsItemProps(),
  13491. setup(props, _ref) {
  13492. let {
  13493. slots,
  13494. attrs
  13495. } = _ref;
  13496. const link = useLink(props, attrs);
  13497. const isActive = computed(() => props.active || link.isActive?.value);
  13498. const color = computed(() => isActive.value ? props.activeColor : props.color);
  13499. const {
  13500. textColorClasses,
  13501. textColorStyles
  13502. } = useTextColor(color);
  13503. useRender(() => {
  13504. return createVNode(props.tag, {
  13505. "class": ['v-breadcrumbs-item', {
  13506. 'v-breadcrumbs-item--active': isActive.value,
  13507. 'v-breadcrumbs-item--disabled': props.disabled,
  13508. [`${props.activeClass}`]: isActive.value && props.activeClass
  13509. }, textColorClasses.value, props.class],
  13510. "style": [textColorStyles.value, props.style],
  13511. "aria-current": isActive.value ? 'page' : undefined
  13512. }, {
  13513. default: () => [!link.isLink.value ? slots.default?.() ?? props.title : createVNode("a", mergeProps({
  13514. "class": "v-breadcrumbs-item--link",
  13515. "onClick": link.navigate
  13516. }, link.linkProps), [slots.default?.() ?? props.title])]
  13517. });
  13518. });
  13519. return {};
  13520. }
  13521. });
  13522. // Types
  13523. const makeVBreadcrumbsProps = propsFactory({
  13524. activeClass: String,
  13525. activeColor: String,
  13526. bgColor: String,
  13527. color: String,
  13528. disabled: Boolean,
  13529. divider: {
  13530. type: String,
  13531. default: '/'
  13532. },
  13533. icon: IconValue,
  13534. items: {
  13535. type: Array,
  13536. default: () => []
  13537. },
  13538. ...makeComponentProps(),
  13539. ...makeDensityProps(),
  13540. ...makeRoundedProps(),
  13541. ...makeTagProps({
  13542. tag: 'ul'
  13543. })
  13544. }, 'VBreadcrumbs');
  13545. const VBreadcrumbs = genericComponent()({
  13546. name: 'VBreadcrumbs',
  13547. props: makeVBreadcrumbsProps(),
  13548. setup(props, _ref) {
  13549. let {
  13550. slots
  13551. } = _ref;
  13552. const {
  13553. backgroundColorClasses,
  13554. backgroundColorStyles
  13555. } = useBackgroundColor(toRef(props, 'bgColor'));
  13556. const {
  13557. densityClasses
  13558. } = useDensity(props);
  13559. const {
  13560. roundedClasses
  13561. } = useRounded(props);
  13562. provideDefaults({
  13563. VBreadcrumbsDivider: {
  13564. divider: toRef(props, 'divider')
  13565. },
  13566. VBreadcrumbsItem: {
  13567. activeClass: toRef(props, 'activeClass'),
  13568. activeColor: toRef(props, 'activeColor'),
  13569. color: toRef(props, 'color'),
  13570. disabled: toRef(props, 'disabled')
  13571. }
  13572. });
  13573. const items = computed(() => props.items.map(item => {
  13574. return typeof item === 'string' ? {
  13575. item: {
  13576. title: item
  13577. },
  13578. raw: item
  13579. } : {
  13580. item,
  13581. raw: item
  13582. };
  13583. }));
  13584. useRender(() => {
  13585. const hasPrepend = !!(slots.prepend || props.icon);
  13586. return createVNode(props.tag, {
  13587. "class": ['v-breadcrumbs', backgroundColorClasses.value, densityClasses.value, roundedClasses.value, props.class],
  13588. "style": [backgroundColorStyles.value, props.style]
  13589. }, {
  13590. default: () => [hasPrepend && createVNode("li", {
  13591. "key": "prepend",
  13592. "class": "v-breadcrumbs__prepend"
  13593. }, [!slots.prepend ? createVNode(VIcon, {
  13594. "key": "prepend-icon",
  13595. "start": true,
  13596. "icon": props.icon
  13597. }, null) : createVNode(VDefaultsProvider, {
  13598. "key": "prepend-defaults",
  13599. "disabled": !props.icon,
  13600. "defaults": {
  13601. VIcon: {
  13602. icon: props.icon,
  13603. start: true
  13604. }
  13605. }
  13606. }, slots.prepend)]), items.value.map((_ref2, index, array) => {
  13607. let {
  13608. item,
  13609. raw
  13610. } = _ref2;
  13611. return createVNode(Fragment, null, [slots.item?.({
  13612. item,
  13613. index
  13614. }) ?? createVNode(VBreadcrumbsItem, mergeProps({
  13615. "key": index,
  13616. "disabled": index >= array.length - 1
  13617. }, typeof item === 'string' ? {
  13618. title: item
  13619. } : item), {
  13620. default: slots.title ? () => slots.title?.({
  13621. item,
  13622. index
  13623. }) : undefined
  13624. }), index < array.length - 1 && createVNode(VBreadcrumbsDivider, null, {
  13625. default: slots.divider ? () => slots.divider?.({
  13626. item: raw,
  13627. index
  13628. }) : undefined
  13629. })]);
  13630. }), slots.default?.()]
  13631. });
  13632. });
  13633. return {};
  13634. }
  13635. });
  13636. const VCardActions = genericComponent()({
  13637. name: 'VCardActions',
  13638. props: makeComponentProps(),
  13639. setup(props, _ref) {
  13640. let {
  13641. slots
  13642. } = _ref;
  13643. provideDefaults({
  13644. VBtn: {
  13645. slim: true,
  13646. variant: 'text'
  13647. }
  13648. });
  13649. useRender(() => createVNode("div", {
  13650. "class": ['v-card-actions', props.class],
  13651. "style": props.style
  13652. }, [slots.default?.()]));
  13653. return {};
  13654. }
  13655. });
  13656. const makeVCardSubtitleProps = propsFactory({
  13657. opacity: [Number, String],
  13658. ...makeComponentProps(),
  13659. ...makeTagProps()
  13660. }, 'VCardSubtitle');
  13661. const VCardSubtitle = genericComponent()({
  13662. name: 'VCardSubtitle',
  13663. props: makeVCardSubtitleProps(),
  13664. setup(props, _ref) {
  13665. let {
  13666. slots
  13667. } = _ref;
  13668. useRender(() => createVNode(props.tag, {
  13669. "class": ['v-card-subtitle', props.class],
  13670. "style": [{
  13671. '--v-card-subtitle-opacity': props.opacity
  13672. }, props.style]
  13673. }, slots));
  13674. return {};
  13675. }
  13676. });
  13677. // Utilities
  13678. const VCardTitle = createSimpleFunctional('v-card-title');
  13679. const makeCardItemProps = propsFactory({
  13680. appendAvatar: String,
  13681. appendIcon: IconValue,
  13682. prependAvatar: String,
  13683. prependIcon: IconValue,
  13684. subtitle: [String, Number],
  13685. title: [String, Number],
  13686. ...makeComponentProps(),
  13687. ...makeDensityProps()
  13688. }, 'VCardItem');
  13689. const VCardItem = genericComponent()({
  13690. name: 'VCardItem',
  13691. props: makeCardItemProps(),
  13692. setup(props, _ref) {
  13693. let {
  13694. slots
  13695. } = _ref;
  13696. useRender(() => {
  13697. const hasPrependMedia = !!(props.prependAvatar || props.prependIcon);
  13698. const hasPrepend = !!(hasPrependMedia || slots.prepend);
  13699. const hasAppendMedia = !!(props.appendAvatar || props.appendIcon);
  13700. const hasAppend = !!(hasAppendMedia || slots.append);
  13701. const hasTitle = !!(props.title != null || slots.title);
  13702. const hasSubtitle = !!(props.subtitle != null || slots.subtitle);
  13703. return createVNode("div", {
  13704. "class": ['v-card-item', props.class],
  13705. "style": props.style
  13706. }, [hasPrepend && createVNode("div", {
  13707. "key": "prepend",
  13708. "class": "v-card-item__prepend"
  13709. }, [!slots.prepend ? createVNode(Fragment, null, [props.prependAvatar && createVNode(VAvatar, {
  13710. "key": "prepend-avatar",
  13711. "density": props.density,
  13712. "image": props.prependAvatar
  13713. }, null), props.prependIcon && createVNode(VIcon, {
  13714. "key": "prepend-icon",
  13715. "density": props.density,
  13716. "icon": props.prependIcon
  13717. }, null)]) : createVNode(VDefaultsProvider, {
  13718. "key": "prepend-defaults",
  13719. "disabled": !hasPrependMedia,
  13720. "defaults": {
  13721. VAvatar: {
  13722. density: props.density,
  13723. image: props.prependAvatar
  13724. },
  13725. VIcon: {
  13726. density: props.density,
  13727. icon: props.prependIcon
  13728. }
  13729. }
  13730. }, slots.prepend)]), createVNode("div", {
  13731. "class": "v-card-item__content"
  13732. }, [hasTitle && createVNode(VCardTitle, {
  13733. "key": "title"
  13734. }, {
  13735. default: () => [slots.title?.() ?? props.title]
  13736. }), hasSubtitle && createVNode(VCardSubtitle, {
  13737. "key": "subtitle"
  13738. }, {
  13739. default: () => [slots.subtitle?.() ?? props.subtitle]
  13740. }), slots.default?.()]), hasAppend && createVNode("div", {
  13741. "key": "append",
  13742. "class": "v-card-item__append"
  13743. }, [!slots.append ? createVNode(Fragment, null, [props.appendIcon && createVNode(VIcon, {
  13744. "key": "append-icon",
  13745. "density": props.density,
  13746. "icon": props.appendIcon
  13747. }, null), props.appendAvatar && createVNode(VAvatar, {
  13748. "key": "append-avatar",
  13749. "density": props.density,
  13750. "image": props.appendAvatar
  13751. }, null)]) : createVNode(VDefaultsProvider, {
  13752. "key": "append-defaults",
  13753. "disabled": !hasAppendMedia,
  13754. "defaults": {
  13755. VAvatar: {
  13756. density: props.density,
  13757. image: props.appendAvatar
  13758. },
  13759. VIcon: {
  13760. density: props.density,
  13761. icon: props.appendIcon
  13762. }
  13763. }
  13764. }, slots.append)])]);
  13765. });
  13766. return {};
  13767. }
  13768. });
  13769. const makeVCardTextProps = propsFactory({
  13770. opacity: [Number, String],
  13771. ...makeComponentProps(),
  13772. ...makeTagProps()
  13773. }, 'VCardText');
  13774. const VCardText = genericComponent()({
  13775. name: 'VCardText',
  13776. props: makeVCardTextProps(),
  13777. setup(props, _ref) {
  13778. let {
  13779. slots
  13780. } = _ref;
  13781. useRender(() => createVNode(props.tag, {
  13782. "class": ['v-card-text', props.class],
  13783. "style": [{
  13784. '--v-card-text-opacity': props.opacity
  13785. }, props.style]
  13786. }, slots));
  13787. return {};
  13788. }
  13789. });
  13790. // Types
  13791. const makeVCardProps = propsFactory({
  13792. appendAvatar: String,
  13793. appendIcon: IconValue,
  13794. disabled: Boolean,
  13795. flat: Boolean,
  13796. hover: Boolean,
  13797. image: String,
  13798. link: {
  13799. type: Boolean,
  13800. default: undefined
  13801. },
  13802. prependAvatar: String,
  13803. prependIcon: IconValue,
  13804. ripple: {
  13805. type: [Boolean, Object],
  13806. default: true
  13807. },
  13808. subtitle: [String, Number],
  13809. text: [String, Number],
  13810. title: [String, Number],
  13811. ...makeBorderProps(),
  13812. ...makeComponentProps(),
  13813. ...makeDensityProps(),
  13814. ...makeDimensionProps(),
  13815. ...makeElevationProps(),
  13816. ...makeLoaderProps(),
  13817. ...makeLocationProps(),
  13818. ...makePositionProps(),
  13819. ...makeRoundedProps(),
  13820. ...makeRouterProps(),
  13821. ...makeTagProps(),
  13822. ...makeThemeProps(),
  13823. ...makeVariantProps({
  13824. variant: 'elevated'
  13825. })
  13826. }, 'VCard');
  13827. const VCard = genericComponent()({
  13828. name: 'VCard',
  13829. directives: {
  13830. Ripple
  13831. },
  13832. props: makeVCardProps(),
  13833. setup(props, _ref) {
  13834. let {
  13835. attrs,
  13836. slots
  13837. } = _ref;
  13838. const {
  13839. themeClasses
  13840. } = provideTheme(props);
  13841. const {
  13842. borderClasses
  13843. } = useBorder(props);
  13844. const {
  13845. colorClasses,
  13846. colorStyles,
  13847. variantClasses
  13848. } = useVariant(props);
  13849. const {
  13850. densityClasses
  13851. } = useDensity(props);
  13852. const {
  13853. dimensionStyles
  13854. } = useDimension(props);
  13855. const {
  13856. elevationClasses
  13857. } = useElevation(props);
  13858. const {
  13859. loaderClasses
  13860. } = useLoader(props);
  13861. const {
  13862. locationStyles
  13863. } = useLocation(props);
  13864. const {
  13865. positionClasses
  13866. } = usePosition(props);
  13867. const {
  13868. roundedClasses
  13869. } = useRounded(props);
  13870. const link = useLink(props, attrs);
  13871. const isLink = computed(() => props.link !== false && link.isLink.value);
  13872. const isClickable = computed(() => !props.disabled && props.link !== false && (props.link || link.isClickable.value));
  13873. useRender(() => {
  13874. const Tag = isLink.value ? 'a' : props.tag;
  13875. const hasTitle = !!(slots.title || props.title != null);
  13876. const hasSubtitle = !!(slots.subtitle || props.subtitle != null);
  13877. const hasHeader = hasTitle || hasSubtitle;
  13878. const hasAppend = !!(slots.append || props.appendAvatar || props.appendIcon);
  13879. const hasPrepend = !!(slots.prepend || props.prependAvatar || props.prependIcon);
  13880. const hasImage = !!(slots.image || props.image);
  13881. const hasCardItem = hasHeader || hasPrepend || hasAppend;
  13882. const hasText = !!(slots.text || props.text != null);
  13883. return withDirectives(createVNode(Tag, mergeProps({
  13884. "class": ['v-card', {
  13885. 'v-card--disabled': props.disabled,
  13886. 'v-card--flat': props.flat,
  13887. 'v-card--hover': props.hover && !(props.disabled || props.flat),
  13888. 'v-card--link': isClickable.value
  13889. }, themeClasses.value, borderClasses.value, colorClasses.value, densityClasses.value, elevationClasses.value, loaderClasses.value, positionClasses.value, roundedClasses.value, variantClasses.value, props.class],
  13890. "style": [colorStyles.value, dimensionStyles.value, locationStyles.value, props.style],
  13891. "onClick": isClickable.value && link.navigate,
  13892. "tabindex": props.disabled ? -1 : undefined
  13893. }, link.linkProps), {
  13894. default: () => [hasImage && createVNode("div", {
  13895. "key": "image",
  13896. "class": "v-card__image"
  13897. }, [!slots.image ? createVNode(VImg, {
  13898. "key": "image-img",
  13899. "cover": true,
  13900. "src": props.image
  13901. }, null) : createVNode(VDefaultsProvider, {
  13902. "key": "image-defaults",
  13903. "disabled": !props.image,
  13904. "defaults": {
  13905. VImg: {
  13906. cover: true,
  13907. src: props.image
  13908. }
  13909. }
  13910. }, slots.image)]), createVNode(LoaderSlot, {
  13911. "name": "v-card",
  13912. "active": !!props.loading,
  13913. "color": typeof props.loading === 'boolean' ? undefined : props.loading
  13914. }, {
  13915. default: slots.loader
  13916. }), hasCardItem && createVNode(VCardItem, {
  13917. "key": "item",
  13918. "prependAvatar": props.prependAvatar,
  13919. "prependIcon": props.prependIcon,
  13920. "title": props.title,
  13921. "subtitle": props.subtitle,
  13922. "appendAvatar": props.appendAvatar,
  13923. "appendIcon": props.appendIcon
  13924. }, {
  13925. default: slots.item,
  13926. prepend: slots.prepend,
  13927. title: slots.title,
  13928. subtitle: slots.subtitle,
  13929. append: slots.append
  13930. }), hasText && createVNode(VCardText, {
  13931. "key": "text"
  13932. }, {
  13933. default: () => [slots.text?.() ?? props.text]
  13934. }), slots.default?.(), slots.actions && createVNode(VCardActions, null, {
  13935. default: slots.actions
  13936. }), genOverlays(isClickable.value, 'v-card')]
  13937. }), [[resolveDirective("ripple"), isClickable.value && props.ripple]]);
  13938. });
  13939. return {};
  13940. }
  13941. });
  13942. // Utilities
  13943. // Types
  13944. const handleGesture = wrapper => {
  13945. const {
  13946. touchstartX,
  13947. touchendX,
  13948. touchstartY,
  13949. touchendY
  13950. } = wrapper;
  13951. const dirRatio = 0.5;
  13952. const minDistance = 16;
  13953. wrapper.offsetX = touchendX - touchstartX;
  13954. wrapper.offsetY = touchendY - touchstartY;
  13955. if (Math.abs(wrapper.offsetY) < dirRatio * Math.abs(wrapper.offsetX)) {
  13956. wrapper.left && touchendX < touchstartX - minDistance && wrapper.left(wrapper);
  13957. wrapper.right && touchendX > touchstartX + minDistance && wrapper.right(wrapper);
  13958. }
  13959. if (Math.abs(wrapper.offsetX) < dirRatio * Math.abs(wrapper.offsetY)) {
  13960. wrapper.up && touchendY < touchstartY - minDistance && wrapper.up(wrapper);
  13961. wrapper.down && touchendY > touchstartY + minDistance && wrapper.down(wrapper);
  13962. }
  13963. };
  13964. function touchstart(event, wrapper) {
  13965. const touch = event.changedTouches[0];
  13966. wrapper.touchstartX = touch.clientX;
  13967. wrapper.touchstartY = touch.clientY;
  13968. wrapper.start?.({
  13969. originalEvent: event,
  13970. ...wrapper
  13971. });
  13972. }
  13973. function touchend(event, wrapper) {
  13974. const touch = event.changedTouches[0];
  13975. wrapper.touchendX = touch.clientX;
  13976. wrapper.touchendY = touch.clientY;
  13977. wrapper.end?.({
  13978. originalEvent: event,
  13979. ...wrapper
  13980. });
  13981. handleGesture(wrapper);
  13982. }
  13983. function touchmove(event, wrapper) {
  13984. const touch = event.changedTouches[0];
  13985. wrapper.touchmoveX = touch.clientX;
  13986. wrapper.touchmoveY = touch.clientY;
  13987. wrapper.move?.({
  13988. originalEvent: event,
  13989. ...wrapper
  13990. });
  13991. }
  13992. function createHandlers() {
  13993. let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  13994. const wrapper = {
  13995. touchstartX: 0,
  13996. touchstartY: 0,
  13997. touchendX: 0,
  13998. touchendY: 0,
  13999. touchmoveX: 0,
  14000. touchmoveY: 0,
  14001. offsetX: 0,
  14002. offsetY: 0,
  14003. left: value.left,
  14004. right: value.right,
  14005. up: value.up,
  14006. down: value.down,
  14007. start: value.start,
  14008. move: value.move,
  14009. end: value.end
  14010. };
  14011. return {
  14012. touchstart: e => touchstart(e, wrapper),
  14013. touchend: e => touchend(e, wrapper),
  14014. touchmove: e => touchmove(e, wrapper)
  14015. };
  14016. }
  14017. function mounted$3(el, binding) {
  14018. const value = binding.value;
  14019. const target = value?.parent ? el.parentElement : el;
  14020. const options = value?.options ?? {
  14021. passive: true
  14022. };
  14023. const uid = binding.instance?.$.uid; // TODO: use custom uid generator
  14024. if (!target || !uid) return;
  14025. const handlers = createHandlers(binding.value);
  14026. target._touchHandlers = target._touchHandlers ?? Object.create(null);
  14027. target._touchHandlers[uid] = handlers;
  14028. keys(handlers).forEach(eventName => {
  14029. target.addEventListener(eventName, handlers[eventName], options);
  14030. });
  14031. }
  14032. function unmounted$3(el, binding) {
  14033. const target = binding.value?.parent ? el.parentElement : el;
  14034. const uid = binding.instance?.$.uid;
  14035. if (!target?._touchHandlers || !uid) return;
  14036. const handlers = target._touchHandlers[uid];
  14037. keys(handlers).forEach(eventName => {
  14038. target.removeEventListener(eventName, handlers[eventName]);
  14039. });
  14040. delete target._touchHandlers[uid];
  14041. }
  14042. const Touch = {
  14043. mounted: mounted$3,
  14044. unmounted: unmounted$3
  14045. };
  14046. // Types
  14047. const VWindowSymbol = Symbol.for('vuetify:v-window');
  14048. const VWindowGroupSymbol = Symbol.for('vuetify:v-window-group');
  14049. const makeVWindowProps = propsFactory({
  14050. continuous: Boolean,
  14051. nextIcon: {
  14052. type: [Boolean, String, Function, Object],
  14053. default: '$next'
  14054. },
  14055. prevIcon: {
  14056. type: [Boolean, String, Function, Object],
  14057. default: '$prev'
  14058. },
  14059. reverse: Boolean,
  14060. showArrows: {
  14061. type: [Boolean, String],
  14062. validator: v => typeof v === 'boolean' || v === 'hover'
  14063. },
  14064. touch: {
  14065. type: [Object, Boolean],
  14066. default: undefined
  14067. },
  14068. direction: {
  14069. type: String,
  14070. default: 'horizontal'
  14071. },
  14072. modelValue: null,
  14073. disabled: Boolean,
  14074. selectedClass: {
  14075. type: String,
  14076. default: 'v-window-item--active'
  14077. },
  14078. // TODO: mandatory should probably not be exposed but do this for now
  14079. mandatory: {
  14080. type: [Boolean, String],
  14081. default: 'force'
  14082. },
  14083. ...makeComponentProps(),
  14084. ...makeTagProps(),
  14085. ...makeThemeProps()
  14086. }, 'VWindow');
  14087. const VWindow = genericComponent()({
  14088. name: 'VWindow',
  14089. directives: {
  14090. Touch
  14091. },
  14092. props: makeVWindowProps(),
  14093. emits: {
  14094. 'update:modelValue': value => true
  14095. },
  14096. setup(props, _ref) {
  14097. let {
  14098. slots
  14099. } = _ref;
  14100. const {
  14101. themeClasses
  14102. } = provideTheme(props);
  14103. const {
  14104. isRtl
  14105. } = useRtl();
  14106. const {
  14107. t
  14108. } = useLocale();
  14109. const group = useGroup(props, VWindowGroupSymbol);
  14110. const rootRef = ref();
  14111. const isRtlReverse = computed(() => isRtl.value ? !props.reverse : props.reverse);
  14112. const isReversed = shallowRef(false);
  14113. const transition = computed(() => {
  14114. const axis = props.direction === 'vertical' ? 'y' : 'x';
  14115. const reverse = isRtlReverse.value ? !isReversed.value : isReversed.value;
  14116. const direction = reverse ? '-reverse' : '';
  14117. return `v-window-${axis}${direction}-transition`;
  14118. });
  14119. const transitionCount = shallowRef(0);
  14120. const transitionHeight = ref(undefined);
  14121. const activeIndex = computed(() => {
  14122. return group.items.value.findIndex(item => group.selected.value.includes(item.id));
  14123. });
  14124. watch(activeIndex, (newVal, oldVal) => {
  14125. const itemsLength = group.items.value.length;
  14126. const lastIndex = itemsLength - 1;
  14127. if (itemsLength <= 2) {
  14128. isReversed.value = newVal < oldVal;
  14129. } else if (newVal === lastIndex && oldVal === 0) {
  14130. isReversed.value = true;
  14131. } else if (newVal === 0 && oldVal === lastIndex) {
  14132. isReversed.value = false;
  14133. } else {
  14134. isReversed.value = newVal < oldVal;
  14135. }
  14136. });
  14137. provide(VWindowSymbol, {
  14138. transition,
  14139. isReversed,
  14140. transitionCount,
  14141. transitionHeight,
  14142. rootRef
  14143. });
  14144. const canMoveBack = computed(() => props.continuous || activeIndex.value !== 0);
  14145. const canMoveForward = computed(() => props.continuous || activeIndex.value !== group.items.value.length - 1);
  14146. function prev() {
  14147. canMoveBack.value && group.prev();
  14148. }
  14149. function next() {
  14150. canMoveForward.value && group.next();
  14151. }
  14152. const arrows = computed(() => {
  14153. const arrows = [];
  14154. const prevProps = {
  14155. icon: isRtl.value ? props.nextIcon : props.prevIcon,
  14156. class: `v-window__${isRtlReverse.value ? 'right' : 'left'}`,
  14157. onClick: group.prev,
  14158. 'aria-label': t('$vuetify.carousel.prev')
  14159. };
  14160. arrows.push(canMoveBack.value ? slots.prev ? slots.prev({
  14161. props: prevProps
  14162. }) : createVNode(VBtn, prevProps, null) : createVNode("div", null, null));
  14163. const nextProps = {
  14164. icon: isRtl.value ? props.prevIcon : props.nextIcon,
  14165. class: `v-window__${isRtlReverse.value ? 'left' : 'right'}`,
  14166. onClick: group.next,
  14167. 'aria-label': t('$vuetify.carousel.next')
  14168. };
  14169. arrows.push(canMoveForward.value ? slots.next ? slots.next({
  14170. props: nextProps
  14171. }) : createVNode(VBtn, nextProps, null) : createVNode("div", null, null));
  14172. return arrows;
  14173. });
  14174. const touchOptions = computed(() => {
  14175. if (props.touch === false) return props.touch;
  14176. const options = {
  14177. left: () => {
  14178. isRtlReverse.value ? prev() : next();
  14179. },
  14180. right: () => {
  14181. isRtlReverse.value ? next() : prev();
  14182. },
  14183. start: _ref2 => {
  14184. let {
  14185. originalEvent
  14186. } = _ref2;
  14187. originalEvent.stopPropagation();
  14188. }
  14189. };
  14190. return {
  14191. ...options,
  14192. ...(props.touch === true ? {} : props.touch)
  14193. };
  14194. });
  14195. useRender(() => withDirectives(createVNode(props.tag, {
  14196. "ref": rootRef,
  14197. "class": ['v-window', {
  14198. 'v-window--show-arrows-on-hover': props.showArrows === 'hover'
  14199. }, themeClasses.value, props.class],
  14200. "style": props.style
  14201. }, {
  14202. default: () => [createVNode("div", {
  14203. "class": "v-window__container",
  14204. "style": {
  14205. height: transitionHeight.value
  14206. }
  14207. }, [slots.default?.({
  14208. group
  14209. }), props.showArrows !== false && createVNode("div", {
  14210. "class": "v-window__controls"
  14211. }, [arrows.value])]), slots.additional?.({
  14212. group
  14213. })]
  14214. }), [[resolveDirective("touch"), touchOptions.value]]));
  14215. return {
  14216. group
  14217. };
  14218. }
  14219. });
  14220. // Types
  14221. const makeVCarouselProps = propsFactory({
  14222. color: String,
  14223. cycle: Boolean,
  14224. delimiterIcon: {
  14225. type: IconValue,
  14226. default: '$delimiter'
  14227. },
  14228. height: {
  14229. type: [Number, String],
  14230. default: 500
  14231. },
  14232. hideDelimiters: Boolean,
  14233. hideDelimiterBackground: Boolean,
  14234. interval: {
  14235. type: [Number, String],
  14236. default: 6000,
  14237. validator: value => Number(value) > 0
  14238. },
  14239. progress: [Boolean, String],
  14240. verticalDelimiters: [Boolean, String],
  14241. ...makeVWindowProps({
  14242. continuous: true,
  14243. mandatory: 'force',
  14244. showArrows: true
  14245. })
  14246. }, 'VCarousel');
  14247. const VCarousel = genericComponent()({
  14248. name: 'VCarousel',
  14249. props: makeVCarouselProps(),
  14250. emits: {
  14251. 'update:modelValue': value => true
  14252. },
  14253. setup(props, _ref) {
  14254. let {
  14255. slots
  14256. } = _ref;
  14257. const model = useProxiedModel(props, 'modelValue');
  14258. const {
  14259. t
  14260. } = useLocale();
  14261. const windowRef = ref();
  14262. let slideTimeout = -1;
  14263. watch(model, restartTimeout);
  14264. watch(() => props.interval, restartTimeout);
  14265. watch(() => props.cycle, val => {
  14266. if (val) restartTimeout();else window.clearTimeout(slideTimeout);
  14267. });
  14268. onMounted(startTimeout);
  14269. function startTimeout() {
  14270. if (!props.cycle || !windowRef.value) return;
  14271. slideTimeout = window.setTimeout(windowRef.value.group.next, +props.interval > 0 ? +props.interval : 6000);
  14272. }
  14273. function restartTimeout() {
  14274. window.clearTimeout(slideTimeout);
  14275. window.requestAnimationFrame(startTimeout);
  14276. }
  14277. useRender(() => {
  14278. const windowProps = VWindow.filterProps(props);
  14279. return createVNode(VWindow, mergeProps({
  14280. "ref": windowRef
  14281. }, windowProps, {
  14282. "modelValue": model.value,
  14283. "onUpdate:modelValue": $event => model.value = $event,
  14284. "class": ['v-carousel', {
  14285. 'v-carousel--hide-delimiter-background': props.hideDelimiterBackground,
  14286. 'v-carousel--vertical-delimiters': props.verticalDelimiters
  14287. }, props.class],
  14288. "style": [{
  14289. height: convertToUnit(props.height)
  14290. }, props.style]
  14291. }), {
  14292. default: slots.default,
  14293. additional: _ref2 => {
  14294. let {
  14295. group
  14296. } = _ref2;
  14297. return createVNode(Fragment, null, [!props.hideDelimiters && createVNode("div", {
  14298. "class": "v-carousel__controls",
  14299. "style": {
  14300. left: props.verticalDelimiters === 'left' && props.verticalDelimiters ? 0 : 'auto',
  14301. right: props.verticalDelimiters === 'right' ? 0 : 'auto'
  14302. }
  14303. }, [group.items.value.length > 0 && createVNode(VDefaultsProvider, {
  14304. "defaults": {
  14305. VBtn: {
  14306. color: props.color,
  14307. icon: props.delimiterIcon,
  14308. size: 'x-small',
  14309. variant: 'text'
  14310. }
  14311. },
  14312. "scoped": true
  14313. }, {
  14314. default: () => [group.items.value.map((item, index) => {
  14315. const props = {
  14316. id: `carousel-item-${item.id}`,
  14317. 'aria-label': t('$vuetify.carousel.ariaLabel.delimiter', index + 1, group.items.value.length),
  14318. class: ['v-carousel__controls__item', group.isSelected(item.id) && 'v-btn--active'],
  14319. onClick: () => group.select(item.id, true)
  14320. };
  14321. return slots.item ? slots.item({
  14322. props,
  14323. item
  14324. }) : createVNode(VBtn, mergeProps(item, props), null);
  14325. })]
  14326. })]), props.progress && createVNode(VProgressLinear, {
  14327. "class": "v-carousel__progress",
  14328. "color": typeof props.progress === 'string' ? props.progress : undefined,
  14329. "modelValue": (group.getItemIndex(model.value) + 1) / group.items.value.length * 100
  14330. }, null)]);
  14331. },
  14332. prev: slots.prev,
  14333. next: slots.next
  14334. });
  14335. });
  14336. return {};
  14337. }
  14338. });
  14339. const makeVWindowItemProps = propsFactory({
  14340. reverseTransition: {
  14341. type: [Boolean, String],
  14342. default: undefined
  14343. },
  14344. transition: {
  14345. type: [Boolean, String],
  14346. default: undefined
  14347. },
  14348. ...makeComponentProps(),
  14349. ...makeGroupItemProps(),
  14350. ...makeLazyProps()
  14351. }, 'VWindowItem');
  14352. const VWindowItem = genericComponent()({
  14353. name: 'VWindowItem',
  14354. directives: {
  14355. Touch
  14356. },
  14357. props: makeVWindowItemProps(),
  14358. emits: {
  14359. 'group:selected': val => true
  14360. },
  14361. setup(props, _ref) {
  14362. let {
  14363. slots
  14364. } = _ref;
  14365. const window = inject$1(VWindowSymbol);
  14366. const groupItem = useGroupItem(props, VWindowGroupSymbol);
  14367. const {
  14368. isBooted
  14369. } = useSsrBoot();
  14370. if (!window || !groupItem) throw new Error('[Vuetify] VWindowItem must be used inside VWindow');
  14371. const isTransitioning = shallowRef(false);
  14372. const hasTransition = computed(() => isBooted.value && (window.isReversed.value ? props.reverseTransition !== false : props.transition !== false));
  14373. function onAfterTransition() {
  14374. if (!isTransitioning.value || !window) {
  14375. return;
  14376. }
  14377. // Finalize transition state.
  14378. isTransitioning.value = false;
  14379. if (window.transitionCount.value > 0) {
  14380. window.transitionCount.value -= 1;
  14381. // Remove container height if we are out of transition.
  14382. if (window.transitionCount.value === 0) {
  14383. window.transitionHeight.value = undefined;
  14384. }
  14385. }
  14386. }
  14387. function onBeforeTransition() {
  14388. if (isTransitioning.value || !window) {
  14389. return;
  14390. }
  14391. // Initialize transition state here.
  14392. isTransitioning.value = true;
  14393. if (window.transitionCount.value === 0) {
  14394. // Set initial height for height transition.
  14395. window.transitionHeight.value = convertToUnit(window.rootRef.value?.clientHeight);
  14396. }
  14397. window.transitionCount.value += 1;
  14398. }
  14399. function onTransitionCancelled() {
  14400. onAfterTransition(); // This should have the same path as normal transition end.
  14401. }
  14402. function onEnterTransition(el) {
  14403. if (!isTransitioning.value) {
  14404. return;
  14405. }
  14406. nextTick(() => {
  14407. // Do not set height if no transition or cancelled.
  14408. if (!hasTransition.value || !isTransitioning.value || !window) {
  14409. return;
  14410. }
  14411. // Set transition target height.
  14412. window.transitionHeight.value = convertToUnit(el.clientHeight);
  14413. });
  14414. }
  14415. const transition = computed(() => {
  14416. const name = window.isReversed.value ? props.reverseTransition : props.transition;
  14417. return !hasTransition.value ? false : {
  14418. name: typeof name !== 'string' ? window.transition.value : name,
  14419. onBeforeEnter: onBeforeTransition,
  14420. onAfterEnter: onAfterTransition,
  14421. onEnterCancelled: onTransitionCancelled,
  14422. onBeforeLeave: onBeforeTransition,
  14423. onAfterLeave: onAfterTransition,
  14424. onLeaveCancelled: onTransitionCancelled,
  14425. onEnter: onEnterTransition
  14426. };
  14427. });
  14428. const {
  14429. hasContent
  14430. } = useLazy(props, groupItem.isSelected);
  14431. useRender(() => createVNode(MaybeTransition, {
  14432. "transition": transition.value,
  14433. "disabled": !isBooted.value
  14434. }, {
  14435. default: () => [withDirectives(createVNode("div", {
  14436. "class": ['v-window-item', groupItem.selectedClass.value, props.class],
  14437. "style": props.style
  14438. }, [hasContent.value && slots.default?.()]), [[vShow, groupItem.isSelected.value]])]
  14439. }));
  14440. return {
  14441. groupItem
  14442. };
  14443. }
  14444. });
  14445. // Types
  14446. const makeVCarouselItemProps = propsFactory({
  14447. ...makeVImgProps(),
  14448. ...makeVWindowItemProps()
  14449. }, 'VCarouselItem');
  14450. const VCarouselItem = genericComponent()({
  14451. name: 'VCarouselItem',
  14452. inheritAttrs: false,
  14453. props: makeVCarouselItemProps(),
  14454. setup(props, _ref) {
  14455. let {
  14456. slots,
  14457. attrs
  14458. } = _ref;
  14459. useRender(() => {
  14460. const imgProps = VImg.filterProps(props);
  14461. const windowItemProps = VWindowItem.filterProps(props);
  14462. return createVNode(VWindowItem, mergeProps({
  14463. "class": ['v-carousel-item', props.class]
  14464. }, windowItemProps), {
  14465. default: () => [createVNode(VImg, mergeProps(attrs, imgProps), slots)]
  14466. });
  14467. });
  14468. }
  14469. });
  14470. // Styles
  14471. const VCode = createSimpleFunctional('v-code', 'code');
  14472. // Types
  14473. const makeVColorPickerCanvasProps = propsFactory({
  14474. color: {
  14475. type: Object
  14476. },
  14477. disabled: Boolean,
  14478. dotSize: {
  14479. type: [Number, String],
  14480. default: 10
  14481. },
  14482. height: {
  14483. type: [Number, String],
  14484. default: 150
  14485. },
  14486. width: {
  14487. type: [Number, String],
  14488. default: 300
  14489. },
  14490. ...makeComponentProps()
  14491. }, 'VColorPickerCanvas');
  14492. const VColorPickerCanvas = defineComponent({
  14493. name: 'VColorPickerCanvas',
  14494. props: makeVColorPickerCanvasProps(),
  14495. emits: {
  14496. 'update:color': color => true,
  14497. 'update:position': hue => true
  14498. },
  14499. setup(props, _ref) {
  14500. let {
  14501. emit
  14502. } = _ref;
  14503. const isInteracting = shallowRef(false);
  14504. const canvasRef = ref();
  14505. const canvasWidth = shallowRef(parseFloat(props.width));
  14506. const canvasHeight = shallowRef(parseFloat(props.height));
  14507. const _dotPosition = ref({
  14508. x: 0,
  14509. y: 0
  14510. });
  14511. const dotPosition = computed({
  14512. get: () => _dotPosition.value,
  14513. set(val) {
  14514. if (!canvasRef.value) return;
  14515. const {
  14516. x,
  14517. y
  14518. } = val;
  14519. _dotPosition.value = val;
  14520. emit('update:color', {
  14521. h: props.color?.h ?? 0,
  14522. s: clamp(x, 0, canvasWidth.value) / canvasWidth.value,
  14523. v: 1 - clamp(y, 0, canvasHeight.value) / canvasHeight.value,
  14524. a: props.color?.a ?? 1
  14525. });
  14526. }
  14527. });
  14528. const dotStyles = computed(() => {
  14529. const {
  14530. x,
  14531. y
  14532. } = dotPosition.value;
  14533. const radius = parseInt(props.dotSize, 10) / 2;
  14534. return {
  14535. width: convertToUnit(props.dotSize),
  14536. height: convertToUnit(props.dotSize),
  14537. transform: `translate(${convertToUnit(x - radius)}, ${convertToUnit(y - radius)})`
  14538. };
  14539. });
  14540. const {
  14541. resizeRef
  14542. } = useResizeObserver(entries => {
  14543. if (!resizeRef.el?.offsetParent) return;
  14544. const {
  14545. width,
  14546. height
  14547. } = entries[0].contentRect;
  14548. canvasWidth.value = width;
  14549. canvasHeight.value = height;
  14550. });
  14551. function updateDotPosition(x, y, rect) {
  14552. const {
  14553. left,
  14554. top,
  14555. width,
  14556. height
  14557. } = rect;
  14558. dotPosition.value = {
  14559. x: clamp(x - left, 0, width),
  14560. y: clamp(y - top, 0, height)
  14561. };
  14562. }
  14563. function handleMouseDown(e) {
  14564. if (e.type === 'mousedown') {
  14565. // Prevent text selection while dragging
  14566. e.preventDefault();
  14567. }
  14568. if (props.disabled) return;
  14569. handleMouseMove(e);
  14570. window.addEventListener('mousemove', handleMouseMove);
  14571. window.addEventListener('mouseup', handleMouseUp);
  14572. window.addEventListener('touchmove', handleMouseMove);
  14573. window.addEventListener('touchend', handleMouseUp);
  14574. }
  14575. function handleMouseMove(e) {
  14576. if (props.disabled || !canvasRef.value) return;
  14577. isInteracting.value = true;
  14578. const coords = getEventCoordinates(e);
  14579. updateDotPosition(coords.clientX, coords.clientY, canvasRef.value.getBoundingClientRect());
  14580. }
  14581. function handleMouseUp() {
  14582. window.removeEventListener('mousemove', handleMouseMove);
  14583. window.removeEventListener('mouseup', handleMouseUp);
  14584. window.removeEventListener('touchmove', handleMouseMove);
  14585. window.removeEventListener('touchend', handleMouseUp);
  14586. }
  14587. function updateCanvas() {
  14588. if (!canvasRef.value) return;
  14589. const canvas = canvasRef.value;
  14590. const ctx = canvas.getContext('2d');
  14591. if (!ctx) return;
  14592. const saturationGradient = ctx.createLinearGradient(0, 0, canvas.width, 0);
  14593. saturationGradient.addColorStop(0, 'hsla(0, 0%, 100%, 1)'); // white
  14594. saturationGradient.addColorStop(1, `hsla(${props.color?.h ?? 0}, 100%, 50%, 1)`);
  14595. ctx.fillStyle = saturationGradient;
  14596. ctx.fillRect(0, 0, canvas.width, canvas.height);
  14597. const valueGradient = ctx.createLinearGradient(0, 0, 0, canvas.height);
  14598. valueGradient.addColorStop(0, 'hsla(0, 0%, 0%, 0)'); // transparent
  14599. valueGradient.addColorStop(1, 'hsla(0, 0%, 0%, 1)'); // black
  14600. ctx.fillStyle = valueGradient;
  14601. ctx.fillRect(0, 0, canvas.width, canvas.height);
  14602. }
  14603. watch(() => props.color?.h, updateCanvas, {
  14604. immediate: true
  14605. });
  14606. watch(() => [canvasWidth.value, canvasHeight.value], (newVal, oldVal) => {
  14607. updateCanvas();
  14608. _dotPosition.value = {
  14609. x: dotPosition.value.x * newVal[0] / oldVal[0],
  14610. y: dotPosition.value.y * newVal[1] / oldVal[1]
  14611. };
  14612. }, {
  14613. flush: 'post'
  14614. });
  14615. watch(() => props.color, () => {
  14616. if (isInteracting.value) {
  14617. isInteracting.value = false;
  14618. return;
  14619. }
  14620. _dotPosition.value = props.color ? {
  14621. x: props.color.s * canvasWidth.value,
  14622. y: (1 - props.color.v) * canvasHeight.value
  14623. } : {
  14624. x: 0,
  14625. y: 0
  14626. };
  14627. }, {
  14628. deep: true,
  14629. immediate: true
  14630. });
  14631. onMounted(() => updateCanvas());
  14632. useRender(() => createVNode("div", {
  14633. "ref": resizeRef,
  14634. "class": ['v-color-picker-canvas', props.class],
  14635. "style": props.style,
  14636. "onMousedown": handleMouseDown,
  14637. "onTouchstartPassive": handleMouseDown
  14638. }, [createVNode("canvas", {
  14639. "ref": canvasRef,
  14640. "width": canvasWidth.value,
  14641. "height": canvasHeight.value
  14642. }, null), props.color && createVNode("div", {
  14643. "class": ['v-color-picker-canvas__dot', {
  14644. 'v-color-picker-canvas__dot--disabled': props.disabled
  14645. }],
  14646. "style": dotStyles.value
  14647. }, null)]));
  14648. return {};
  14649. }
  14650. });
  14651. // Utilities
  14652. // Types
  14653. function stripAlpha(color, stripAlpha) {
  14654. if (stripAlpha) {
  14655. const {
  14656. a,
  14657. ...rest
  14658. } = color;
  14659. return rest;
  14660. }
  14661. return color;
  14662. }
  14663. function extractColor(color, input) {
  14664. if (input == null || typeof input === 'string') {
  14665. const hex = HSVtoHex(color);
  14666. if (color.a === 1) return hex.slice(0, 7);else return hex;
  14667. }
  14668. if (typeof input === 'object') {
  14669. let converted;
  14670. 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;
  14671. return stripAlpha(converted, !has(input, ['a']) && color.a === 1);
  14672. }
  14673. return color;
  14674. }
  14675. const nullColor = {
  14676. h: 0,
  14677. s: 0,
  14678. v: 0,
  14679. a: 1
  14680. };
  14681. const rgba = {
  14682. inputProps: {
  14683. type: 'number',
  14684. min: 0
  14685. },
  14686. inputs: [{
  14687. label: 'R',
  14688. max: 255,
  14689. step: 1,
  14690. getValue: c => Math.round(c.r),
  14691. getColor: (c, v) => ({
  14692. ...c,
  14693. r: Number(v)
  14694. })
  14695. }, {
  14696. label: 'G',
  14697. max: 255,
  14698. step: 1,
  14699. getValue: c => Math.round(c.g),
  14700. getColor: (c, v) => ({
  14701. ...c,
  14702. g: Number(v)
  14703. })
  14704. }, {
  14705. label: 'B',
  14706. max: 255,
  14707. step: 1,
  14708. getValue: c => Math.round(c.b),
  14709. getColor: (c, v) => ({
  14710. ...c,
  14711. b: Number(v)
  14712. })
  14713. }, {
  14714. label: 'A',
  14715. max: 1,
  14716. step: 0.01,
  14717. getValue: _ref => {
  14718. let {
  14719. a
  14720. } = _ref;
  14721. return a != null ? Math.round(a * 100) / 100 : 1;
  14722. },
  14723. getColor: (c, v) => ({
  14724. ...c,
  14725. a: Number(v)
  14726. })
  14727. }],
  14728. to: HSVtoRGB,
  14729. from: RGBtoHSV
  14730. };
  14731. const rgb = {
  14732. ...rgba,
  14733. inputs: rgba.inputs?.slice(0, 3)
  14734. };
  14735. const hsla = {
  14736. inputProps: {
  14737. type: 'number',
  14738. min: 0
  14739. },
  14740. inputs: [{
  14741. label: 'H',
  14742. max: 360,
  14743. step: 1,
  14744. getValue: c => Math.round(c.h),
  14745. getColor: (c, v) => ({
  14746. ...c,
  14747. h: Number(v)
  14748. })
  14749. }, {
  14750. label: 'S',
  14751. max: 1,
  14752. step: 0.01,
  14753. getValue: c => Math.round(c.s * 100) / 100,
  14754. getColor: (c, v) => ({
  14755. ...c,
  14756. s: Number(v)
  14757. })
  14758. }, {
  14759. label: 'L',
  14760. max: 1,
  14761. step: 0.01,
  14762. getValue: c => Math.round(c.l * 100) / 100,
  14763. getColor: (c, v) => ({
  14764. ...c,
  14765. l: Number(v)
  14766. })
  14767. }, {
  14768. label: 'A',
  14769. max: 1,
  14770. step: 0.01,
  14771. getValue: _ref2 => {
  14772. let {
  14773. a
  14774. } = _ref2;
  14775. return a != null ? Math.round(a * 100) / 100 : 1;
  14776. },
  14777. getColor: (c, v) => ({
  14778. ...c,
  14779. a: Number(v)
  14780. })
  14781. }],
  14782. to: HSVtoHSL,
  14783. from: HSLtoHSV
  14784. };
  14785. const hsl = {
  14786. ...hsla,
  14787. inputs: hsla.inputs.slice(0, 3)
  14788. };
  14789. const hexa = {
  14790. inputProps: {
  14791. type: 'text'
  14792. },
  14793. inputs: [{
  14794. label: 'HEXA',
  14795. getValue: c => c,
  14796. getColor: (c, v) => v
  14797. }],
  14798. to: HSVtoHex,
  14799. from: HexToHSV
  14800. };
  14801. const hex = {
  14802. ...hexa,
  14803. inputs: [{
  14804. label: 'HEX',
  14805. getValue: c => c.slice(0, 7),
  14806. getColor: (c, v) => v
  14807. }]
  14808. };
  14809. const modes = {
  14810. rgb,
  14811. rgba,
  14812. hsl,
  14813. hsla,
  14814. hex,
  14815. hexa
  14816. };
  14817. // Types
  14818. const VColorPickerInput = _ref => {
  14819. let {
  14820. label,
  14821. ...rest
  14822. } = _ref;
  14823. return createVNode("div", {
  14824. "class": "v-color-picker-edit__input"
  14825. }, [createVNode("input", rest, null), createVNode("span", null, [label])]);
  14826. };
  14827. const makeVColorPickerEditProps = propsFactory({
  14828. color: Object,
  14829. disabled: Boolean,
  14830. mode: {
  14831. type: String,
  14832. default: 'rgba',
  14833. validator: v => Object.keys(modes).includes(v)
  14834. },
  14835. modes: {
  14836. type: Array,
  14837. default: () => Object.keys(modes),
  14838. validator: v => Array.isArray(v) && v.every(m => Object.keys(modes).includes(m))
  14839. },
  14840. ...makeComponentProps()
  14841. }, 'VColorPickerEdit');
  14842. const VColorPickerEdit = defineComponent({
  14843. name: 'VColorPickerEdit',
  14844. props: makeVColorPickerEditProps(),
  14845. emits: {
  14846. 'update:color': color => true,
  14847. 'update:mode': mode => true
  14848. },
  14849. setup(props, _ref2) {
  14850. let {
  14851. emit
  14852. } = _ref2;
  14853. const enabledModes = computed(() => {
  14854. return props.modes.map(key => ({
  14855. ...modes[key],
  14856. name: key
  14857. }));
  14858. });
  14859. const inputs = computed(() => {
  14860. const mode = enabledModes.value.find(m => m.name === props.mode);
  14861. if (!mode) return [];
  14862. const color = props.color ? mode.to(props.color) : null;
  14863. return mode.inputs?.map(_ref3 => {
  14864. let {
  14865. getValue,
  14866. getColor,
  14867. ...inputProps
  14868. } = _ref3;
  14869. return {
  14870. ...mode.inputProps,
  14871. ...inputProps,
  14872. disabled: props.disabled,
  14873. value: color && getValue(color),
  14874. onChange: e => {
  14875. const target = e.target;
  14876. if (!target) return;
  14877. emit('update:color', mode.from(getColor(color ?? mode.to(nullColor), target.value)));
  14878. }
  14879. };
  14880. });
  14881. });
  14882. useRender(() => createVNode("div", {
  14883. "class": ['v-color-picker-edit', props.class],
  14884. "style": props.style
  14885. }, [inputs.value?.map(props => createVNode(VColorPickerInput, props, null)), enabledModes.value.length > 1 && createVNode(VBtn, {
  14886. "icon": "$unfold",
  14887. "size": "x-small",
  14888. "variant": "plain",
  14889. "onClick": () => {
  14890. const mi = enabledModes.value.findIndex(m => m.name === props.mode);
  14891. emit('update:mode', enabledModes.value[(mi + 1) % enabledModes.value.length].name);
  14892. }
  14893. }, null)]));
  14894. return {};
  14895. }
  14896. });
  14897. /* eslint-disable max-statements */
  14898. // Composables
  14899. // Types
  14900. const VSliderSymbol = Symbol.for('vuetify:v-slider');
  14901. function getOffset(e, el, direction) {
  14902. const vertical = direction === 'vertical';
  14903. const rect = el.getBoundingClientRect();
  14904. const touch = 'touches' in e ? e.touches[0] : e;
  14905. return vertical ? touch.clientY - (rect.top + rect.height / 2) : touch.clientX - (rect.left + rect.width / 2);
  14906. }
  14907. function getPosition(e, position) {
  14908. 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];
  14909. }
  14910. const makeSliderProps = propsFactory({
  14911. disabled: {
  14912. type: Boolean,
  14913. default: null
  14914. },
  14915. error: Boolean,
  14916. readonly: {
  14917. type: Boolean,
  14918. default: null
  14919. },
  14920. max: {
  14921. type: [Number, String],
  14922. default: 100
  14923. },
  14924. min: {
  14925. type: [Number, String],
  14926. default: 0
  14927. },
  14928. step: {
  14929. type: [Number, String],
  14930. default: 0
  14931. },
  14932. thumbColor: String,
  14933. thumbLabel: {
  14934. type: [Boolean, String],
  14935. default: undefined,
  14936. validator: v => typeof v === 'boolean' || v === 'always'
  14937. },
  14938. thumbSize: {
  14939. type: [Number, String],
  14940. default: 20
  14941. },
  14942. showTicks: {
  14943. type: [Boolean, String],
  14944. default: false,
  14945. validator: v => typeof v === 'boolean' || v === 'always'
  14946. },
  14947. ticks: {
  14948. type: [Array, Object]
  14949. },
  14950. tickSize: {
  14951. type: [Number, String],
  14952. default: 2
  14953. },
  14954. color: String,
  14955. trackColor: String,
  14956. trackFillColor: String,
  14957. trackSize: {
  14958. type: [Number, String],
  14959. default: 4
  14960. },
  14961. direction: {
  14962. type: String,
  14963. default: 'horizontal',
  14964. validator: v => ['vertical', 'horizontal'].includes(v)
  14965. },
  14966. reverse: Boolean,
  14967. ...makeRoundedProps(),
  14968. ...makeElevationProps({
  14969. elevation: 2
  14970. }),
  14971. ripple: {
  14972. type: Boolean,
  14973. default: true
  14974. }
  14975. }, 'Slider');
  14976. const useSteps = props => {
  14977. const min = computed(() => parseFloat(props.min));
  14978. const max = computed(() => parseFloat(props.max));
  14979. const step = computed(() => +props.step > 0 ? parseFloat(props.step) : 0);
  14980. const decimals = computed(() => Math.max(getDecimals(step.value), getDecimals(min.value)));
  14981. function roundValue(value) {
  14982. value = parseFloat(value);
  14983. if (step.value <= 0) return value;
  14984. const clamped = clamp(value, min.value, max.value);
  14985. const offset = min.value % step.value;
  14986. const newValue = Math.round((clamped - offset) / step.value) * step.value + offset;
  14987. return parseFloat(Math.min(newValue, max.value).toFixed(decimals.value));
  14988. }
  14989. return {
  14990. min,
  14991. max,
  14992. step,
  14993. decimals,
  14994. roundValue
  14995. };
  14996. };
  14997. const useSlider = _ref => {
  14998. let {
  14999. props,
  15000. steps,
  15001. onSliderStart,
  15002. onSliderMove,
  15003. onSliderEnd,
  15004. getActiveThumb
  15005. } = _ref;
  15006. const {
  15007. isRtl
  15008. } = useRtl();
  15009. const isReversed = toRef(props, 'reverse');
  15010. const vertical = computed(() => props.direction === 'vertical');
  15011. const indexFromEnd = computed(() => vertical.value !== isReversed.value);
  15012. const {
  15013. min,
  15014. max,
  15015. step,
  15016. decimals,
  15017. roundValue
  15018. } = steps;
  15019. const thumbSize = computed(() => parseInt(props.thumbSize, 10));
  15020. const tickSize = computed(() => parseInt(props.tickSize, 10));
  15021. const trackSize = computed(() => parseInt(props.trackSize, 10));
  15022. const numTicks = computed(() => (max.value - min.value) / step.value);
  15023. const disabled = toRef(props, 'disabled');
  15024. const thumbColor = computed(() => props.error || props.disabled ? undefined : props.thumbColor ?? props.color);
  15025. const trackColor = computed(() => props.error || props.disabled ? undefined : props.trackColor ?? props.color);
  15026. const trackFillColor = computed(() => props.error || props.disabled ? undefined : props.trackFillColor ?? props.color);
  15027. const mousePressed = shallowRef(false);
  15028. const startOffset = shallowRef(0);
  15029. const trackContainerRef = ref();
  15030. const activeThumbRef = ref();
  15031. function parseMouseMove(e) {
  15032. const vertical = props.direction === 'vertical';
  15033. const start = vertical ? 'top' : 'left';
  15034. const length = vertical ? 'height' : 'width';
  15035. const position = vertical ? 'clientY' : 'clientX';
  15036. const {
  15037. [start]: trackStart,
  15038. [length]: trackLength
  15039. } = trackContainerRef.value?.$el.getBoundingClientRect();
  15040. const clickOffset = getPosition(e, position);
  15041. // It is possible for left to be NaN, force to number
  15042. let clickPos = Math.min(Math.max((clickOffset - trackStart - startOffset.value) / trackLength, 0), 1) || 0;
  15043. if (vertical ? indexFromEnd.value : indexFromEnd.value !== isRtl.value) clickPos = 1 - clickPos;
  15044. return roundValue(min.value + clickPos * (max.value - min.value));
  15045. }
  15046. const handleStop = e => {
  15047. onSliderEnd({
  15048. value: parseMouseMove(e)
  15049. });
  15050. mousePressed.value = false;
  15051. startOffset.value = 0;
  15052. };
  15053. const handleStart = e => {
  15054. activeThumbRef.value = getActiveThumb(e);
  15055. if (!activeThumbRef.value) return;
  15056. activeThumbRef.value.focus();
  15057. mousePressed.value = true;
  15058. if (activeThumbRef.value.contains(e.target)) {
  15059. startOffset.value = getOffset(e, activeThumbRef.value, props.direction);
  15060. } else {
  15061. startOffset.value = 0;
  15062. onSliderMove({
  15063. value: parseMouseMove(e)
  15064. });
  15065. }
  15066. onSliderStart({
  15067. value: parseMouseMove(e)
  15068. });
  15069. };
  15070. const moveListenerOptions = {
  15071. passive: true,
  15072. capture: true
  15073. };
  15074. function onMouseMove(e) {
  15075. onSliderMove({
  15076. value: parseMouseMove(e)
  15077. });
  15078. }
  15079. function onSliderMouseUp(e) {
  15080. e.stopPropagation();
  15081. e.preventDefault();
  15082. handleStop(e);
  15083. window.removeEventListener('mousemove', onMouseMove, moveListenerOptions);
  15084. window.removeEventListener('mouseup', onSliderMouseUp);
  15085. }
  15086. function onSliderTouchend(e) {
  15087. handleStop(e);
  15088. window.removeEventListener('touchmove', onMouseMove, moveListenerOptions);
  15089. e.target?.removeEventListener('touchend', onSliderTouchend);
  15090. }
  15091. function onSliderTouchstart(e) {
  15092. handleStart(e);
  15093. window.addEventListener('touchmove', onMouseMove, moveListenerOptions);
  15094. e.target?.addEventListener('touchend', onSliderTouchend, {
  15095. passive: false
  15096. });
  15097. }
  15098. function onSliderMousedown(e) {
  15099. e.preventDefault();
  15100. handleStart(e);
  15101. window.addEventListener('mousemove', onMouseMove, moveListenerOptions);
  15102. window.addEventListener('mouseup', onSliderMouseUp, {
  15103. passive: false
  15104. });
  15105. }
  15106. const position = val => {
  15107. const percentage = (val - min.value) / (max.value - min.value) * 100;
  15108. return clamp(isNaN(percentage) ? 0 : percentage, 0, 100);
  15109. };
  15110. const showTicks = toRef(props, 'showTicks');
  15111. const parsedTicks = computed(() => {
  15112. if (!showTicks.value) return [];
  15113. if (!props.ticks) {
  15114. return numTicks.value !== Infinity ? createRange(numTicks.value + 1).map(t => {
  15115. const value = min.value + t * step.value;
  15116. return {
  15117. value,
  15118. position: position(value)
  15119. };
  15120. }) : [];
  15121. }
  15122. if (Array.isArray(props.ticks)) return props.ticks.map(t => ({
  15123. value: t,
  15124. position: position(t),
  15125. label: t.toString()
  15126. }));
  15127. return Object.keys(props.ticks).map(key => ({
  15128. value: parseFloat(key),
  15129. position: position(parseFloat(key)),
  15130. label: props.ticks[key]
  15131. }));
  15132. });
  15133. const hasLabels = computed(() => parsedTicks.value.some(_ref2 => {
  15134. let {
  15135. label
  15136. } = _ref2;
  15137. return !!label;
  15138. }));
  15139. const data = {
  15140. activeThumbRef,
  15141. color: toRef(props, 'color'),
  15142. decimals,
  15143. disabled,
  15144. direction: toRef(props, 'direction'),
  15145. elevation: toRef(props, 'elevation'),
  15146. hasLabels,
  15147. isReversed,
  15148. indexFromEnd,
  15149. min,
  15150. max,
  15151. mousePressed,
  15152. numTicks,
  15153. onSliderMousedown,
  15154. onSliderTouchstart,
  15155. parsedTicks,
  15156. parseMouseMove,
  15157. position,
  15158. readonly: toRef(props, 'readonly'),
  15159. rounded: toRef(props, 'rounded'),
  15160. roundValue,
  15161. showTicks,
  15162. startOffset,
  15163. step,
  15164. thumbSize,
  15165. thumbColor,
  15166. thumbLabel: toRef(props, 'thumbLabel'),
  15167. ticks: toRef(props, 'ticks'),
  15168. tickSize,
  15169. trackColor,
  15170. trackContainerRef,
  15171. trackFillColor,
  15172. trackSize,
  15173. vertical
  15174. };
  15175. provide(VSliderSymbol, data);
  15176. return data;
  15177. };
  15178. // Types
  15179. const makeVSliderThumbProps = propsFactory({
  15180. focused: Boolean,
  15181. max: {
  15182. type: Number,
  15183. required: true
  15184. },
  15185. min: {
  15186. type: Number,
  15187. required: true
  15188. },
  15189. modelValue: {
  15190. type: Number,
  15191. required: true
  15192. },
  15193. position: {
  15194. type: Number,
  15195. required: true
  15196. },
  15197. ripple: {
  15198. type: [Boolean, Object],
  15199. default: true
  15200. },
  15201. name: String,
  15202. ...makeComponentProps()
  15203. }, 'VSliderThumb');
  15204. const VSliderThumb = genericComponent()({
  15205. name: 'VSliderThumb',
  15206. directives: {
  15207. Ripple
  15208. },
  15209. props: makeVSliderThumbProps(),
  15210. emits: {
  15211. 'update:modelValue': v => true
  15212. },
  15213. setup(props, _ref) {
  15214. let {
  15215. slots,
  15216. emit
  15217. } = _ref;
  15218. const slider = inject$1(VSliderSymbol);
  15219. const {
  15220. isRtl,
  15221. rtlClasses
  15222. } = useRtl();
  15223. if (!slider) throw new Error('[Vuetify] v-slider-thumb must be used inside v-slider or v-range-slider');
  15224. const {
  15225. thumbColor,
  15226. step,
  15227. disabled,
  15228. thumbSize,
  15229. thumbLabel,
  15230. direction,
  15231. isReversed,
  15232. vertical,
  15233. readonly,
  15234. elevation,
  15235. mousePressed,
  15236. decimals,
  15237. indexFromEnd
  15238. } = slider;
  15239. const elevationProps = computed(() => !disabled.value ? elevation.value : undefined);
  15240. const {
  15241. elevationClasses
  15242. } = useElevation(elevationProps);
  15243. const {
  15244. textColorClasses,
  15245. textColorStyles
  15246. } = useTextColor(thumbColor);
  15247. const {
  15248. pageup,
  15249. pagedown,
  15250. end,
  15251. home,
  15252. left,
  15253. right,
  15254. down,
  15255. up
  15256. } = keyValues;
  15257. const relevantKeys = [pageup, pagedown, end, home, left, right, down, up];
  15258. const multipliers = computed(() => {
  15259. if (step.value) return [1, 2, 3];else return [1, 5, 10];
  15260. });
  15261. function parseKeydown(e, value) {
  15262. if (!relevantKeys.includes(e.key)) return;
  15263. e.preventDefault();
  15264. const _step = step.value || 0.1;
  15265. const steps = (props.max - props.min) / _step;
  15266. if ([left, right, down, up].includes(e.key)) {
  15267. const increase = vertical.value ? [isRtl.value ? left : right, isReversed.value ? down : up] : indexFromEnd.value !== isRtl.value ? [left, up] : [right, up];
  15268. const direction = increase.includes(e.key) ? 1 : -1;
  15269. const multiplier = e.shiftKey ? 2 : e.ctrlKey ? 1 : 0;
  15270. value = value + direction * _step * multipliers.value[multiplier];
  15271. } else if (e.key === home) {
  15272. value = props.min;
  15273. } else if (e.key === end) {
  15274. value = props.max;
  15275. } else {
  15276. const direction = e.key === pagedown ? 1 : -1;
  15277. value = value - direction * _step * (steps > 100 ? steps / 10 : 10);
  15278. }
  15279. return Math.max(props.min, Math.min(props.max, value));
  15280. }
  15281. function onKeydown(e) {
  15282. const newValue = parseKeydown(e, props.modelValue);
  15283. newValue != null && emit('update:modelValue', newValue);
  15284. }
  15285. useRender(() => {
  15286. const positionPercentage = convertToUnit(indexFromEnd.value ? 100 - props.position : props.position, '%');
  15287. return createVNode("div", {
  15288. "class": ['v-slider-thumb', {
  15289. 'v-slider-thumb--focused': props.focused,
  15290. 'v-slider-thumb--pressed': props.focused && mousePressed.value
  15291. }, props.class, rtlClasses.value],
  15292. "style": [{
  15293. '--v-slider-thumb-position': positionPercentage,
  15294. '--v-slider-thumb-size': convertToUnit(thumbSize.value)
  15295. }, props.style],
  15296. "role": "slider",
  15297. "tabindex": disabled.value ? -1 : 0,
  15298. "aria-label": props.name,
  15299. "aria-valuemin": props.min,
  15300. "aria-valuemax": props.max,
  15301. "aria-valuenow": props.modelValue,
  15302. "aria-readonly": !!readonly.value,
  15303. "aria-orientation": direction.value,
  15304. "onKeydown": !readonly.value ? onKeydown : undefined
  15305. }, [createVNode("div", {
  15306. "class": ['v-slider-thumb__surface', textColorClasses.value, elevationClasses.value],
  15307. "style": {
  15308. ...textColorStyles.value
  15309. }
  15310. }, null), withDirectives(createVNode("div", {
  15311. "class": ['v-slider-thumb__ripple', textColorClasses.value],
  15312. "style": textColorStyles.value
  15313. }, null), [[resolveDirective("ripple"), props.ripple, null, {
  15314. circle: true,
  15315. center: true
  15316. }]]), createVNode(VScaleTransition, {
  15317. "origin": "bottom center"
  15318. }, {
  15319. default: () => [withDirectives(createVNode("div", {
  15320. "class": "v-slider-thumb__label-container"
  15321. }, [createVNode("div", {
  15322. "class": ['v-slider-thumb__label']
  15323. }, [createVNode("div", null, [slots['thumb-label']?.({
  15324. modelValue: props.modelValue
  15325. }) ?? props.modelValue.toFixed(step.value ? decimals.value : 1)])])]), [[vShow, thumbLabel.value && props.focused || thumbLabel.value === 'always']])]
  15326. })]);
  15327. });
  15328. return {};
  15329. }
  15330. });
  15331. // Types
  15332. const makeVSliderTrackProps = propsFactory({
  15333. start: {
  15334. type: Number,
  15335. required: true
  15336. },
  15337. stop: {
  15338. type: Number,
  15339. required: true
  15340. },
  15341. ...makeComponentProps()
  15342. }, 'VSliderTrack');
  15343. const VSliderTrack = genericComponent()({
  15344. name: 'VSliderTrack',
  15345. props: makeVSliderTrackProps(),
  15346. emits: {},
  15347. setup(props, _ref) {
  15348. let {
  15349. slots
  15350. } = _ref;
  15351. const slider = inject$1(VSliderSymbol);
  15352. if (!slider) throw new Error('[Vuetify] v-slider-track must be inside v-slider or v-range-slider');
  15353. const {
  15354. color,
  15355. parsedTicks,
  15356. rounded,
  15357. showTicks,
  15358. tickSize,
  15359. trackColor,
  15360. trackFillColor,
  15361. trackSize,
  15362. vertical,
  15363. min,
  15364. max,
  15365. indexFromEnd
  15366. } = slider;
  15367. const {
  15368. roundedClasses
  15369. } = useRounded(rounded);
  15370. const {
  15371. backgroundColorClasses: trackFillColorClasses,
  15372. backgroundColorStyles: trackFillColorStyles
  15373. } = useBackgroundColor(trackFillColor);
  15374. const {
  15375. backgroundColorClasses: trackColorClasses,
  15376. backgroundColorStyles: trackColorStyles
  15377. } = useBackgroundColor(trackColor);
  15378. const startDir = computed(() => `inset-${vertical.value ? 'block' : 'inline'}-${indexFromEnd.value ? 'end' : 'start'}`);
  15379. const endDir = computed(() => vertical.value ? 'height' : 'width');
  15380. const backgroundStyles = computed(() => {
  15381. return {
  15382. [startDir.value]: '0%',
  15383. [endDir.value]: '100%'
  15384. };
  15385. });
  15386. const trackFillWidth = computed(() => props.stop - props.start);
  15387. const trackFillStyles = computed(() => {
  15388. return {
  15389. [startDir.value]: convertToUnit(props.start, '%'),
  15390. [endDir.value]: convertToUnit(trackFillWidth.value, '%')
  15391. };
  15392. });
  15393. const computedTicks = computed(() => {
  15394. if (!showTicks.value) return [];
  15395. const ticks = vertical.value ? parsedTicks.value.slice().reverse() : parsedTicks.value;
  15396. return ticks.map((tick, index) => {
  15397. const directionValue = tick.value !== min.value && tick.value !== max.value ? convertToUnit(tick.position, '%') : undefined;
  15398. return createVNode("div", {
  15399. "key": tick.value,
  15400. "class": ['v-slider-track__tick', {
  15401. 'v-slider-track__tick--filled': tick.position >= props.start && tick.position <= props.stop,
  15402. 'v-slider-track__tick--first': tick.value === min.value,
  15403. 'v-slider-track__tick--last': tick.value === max.value
  15404. }],
  15405. "style": {
  15406. [startDir.value]: directionValue
  15407. }
  15408. }, [(tick.label || slots['tick-label']) && createVNode("div", {
  15409. "class": "v-slider-track__tick-label"
  15410. }, [slots['tick-label']?.({
  15411. tick,
  15412. index
  15413. }) ?? tick.label])]);
  15414. });
  15415. });
  15416. useRender(() => {
  15417. return createVNode("div", {
  15418. "class": ['v-slider-track', roundedClasses.value, props.class],
  15419. "style": [{
  15420. '--v-slider-track-size': convertToUnit(trackSize.value),
  15421. '--v-slider-tick-size': convertToUnit(tickSize.value)
  15422. }, props.style]
  15423. }, [createVNode("div", {
  15424. "class": ['v-slider-track__background', trackColorClasses.value, {
  15425. 'v-slider-track__background--opacity': !!color.value || !trackFillColor.value
  15426. }],
  15427. "style": {
  15428. ...backgroundStyles.value,
  15429. ...trackColorStyles.value
  15430. }
  15431. }, null), createVNode("div", {
  15432. "class": ['v-slider-track__fill', trackFillColorClasses.value],
  15433. "style": {
  15434. ...trackFillStyles.value,
  15435. ...trackFillColorStyles.value
  15436. }
  15437. }, null), showTicks.value && createVNode("div", {
  15438. "class": ['v-slider-track__ticks', {
  15439. 'v-slider-track__ticks--always-show': showTicks.value === 'always'
  15440. }]
  15441. }, [computedTicks.value])]);
  15442. });
  15443. return {};
  15444. }
  15445. });
  15446. // Types
  15447. const makeVSliderProps = propsFactory({
  15448. ...makeFocusProps(),
  15449. ...makeSliderProps(),
  15450. ...makeVInputProps(),
  15451. modelValue: {
  15452. type: [Number, String],
  15453. default: 0
  15454. }
  15455. }, 'VSlider');
  15456. const VSlider = genericComponent()({
  15457. name: 'VSlider',
  15458. props: makeVSliderProps(),
  15459. emits: {
  15460. 'update:focused': value => true,
  15461. 'update:modelValue': v => true,
  15462. start: value => true,
  15463. end: value => true
  15464. },
  15465. setup(props, _ref) {
  15466. let {
  15467. slots,
  15468. emit
  15469. } = _ref;
  15470. const thumbContainerRef = ref();
  15471. const {
  15472. rtlClasses
  15473. } = useRtl();
  15474. const steps = useSteps(props);
  15475. const model = useProxiedModel(props, 'modelValue', undefined, value => {
  15476. return steps.roundValue(value == null ? steps.min.value : value);
  15477. });
  15478. const {
  15479. min,
  15480. max,
  15481. mousePressed,
  15482. roundValue,
  15483. onSliderMousedown,
  15484. onSliderTouchstart,
  15485. trackContainerRef,
  15486. position,
  15487. hasLabels,
  15488. readonly
  15489. } = useSlider({
  15490. props,
  15491. steps,
  15492. onSliderStart: () => {
  15493. emit('start', model.value);
  15494. },
  15495. onSliderEnd: _ref2 => {
  15496. let {
  15497. value
  15498. } = _ref2;
  15499. const roundedValue = roundValue(value);
  15500. model.value = roundedValue;
  15501. emit('end', roundedValue);
  15502. },
  15503. onSliderMove: _ref3 => {
  15504. let {
  15505. value
  15506. } = _ref3;
  15507. return model.value = roundValue(value);
  15508. },
  15509. getActiveThumb: () => thumbContainerRef.value?.$el
  15510. });
  15511. const {
  15512. isFocused,
  15513. focus,
  15514. blur
  15515. } = useFocus(props);
  15516. const trackStop = computed(() => position(model.value));
  15517. useRender(() => {
  15518. const inputProps = VInput.filterProps(props);
  15519. const hasPrepend = !!(props.label || slots.label || slots.prepend);
  15520. return createVNode(VInput, mergeProps({
  15521. "class": ['v-slider', {
  15522. 'v-slider--has-labels': !!slots['tick-label'] || hasLabels.value,
  15523. 'v-slider--focused': isFocused.value,
  15524. 'v-slider--pressed': mousePressed.value,
  15525. 'v-slider--disabled': props.disabled
  15526. }, rtlClasses.value, props.class],
  15527. "style": props.style
  15528. }, inputProps, {
  15529. "focused": isFocused.value
  15530. }), {
  15531. ...slots,
  15532. prepend: hasPrepend ? slotProps => createVNode(Fragment, null, [slots.label?.(slotProps) ?? (props.label ? createVNode(VLabel, {
  15533. "id": slotProps.id.value,
  15534. "class": "v-slider__label",
  15535. "text": props.label
  15536. }, null) : undefined), slots.prepend?.(slotProps)]) : undefined,
  15537. default: _ref4 => {
  15538. let {
  15539. id,
  15540. messagesId
  15541. } = _ref4;
  15542. return createVNode("div", {
  15543. "class": "v-slider__container",
  15544. "onMousedown": !readonly.value ? onSliderMousedown : undefined,
  15545. "onTouchstartPassive": !readonly.value ? onSliderTouchstart : undefined
  15546. }, [createVNode("input", {
  15547. "id": id.value,
  15548. "name": props.name || id.value,
  15549. "disabled": !!props.disabled,
  15550. "readonly": !!props.readonly,
  15551. "tabindex": "-1",
  15552. "value": model.value
  15553. }, null), createVNode(VSliderTrack, {
  15554. "ref": trackContainerRef,
  15555. "start": 0,
  15556. "stop": trackStop.value
  15557. }, {
  15558. 'tick-label': slots['tick-label']
  15559. }), createVNode(VSliderThumb, {
  15560. "ref": thumbContainerRef,
  15561. "aria-describedby": messagesId.value,
  15562. "focused": isFocused.value,
  15563. "min": min.value,
  15564. "max": max.value,
  15565. "modelValue": model.value,
  15566. "onUpdate:modelValue": v => model.value = v,
  15567. "position": trackStop.value,
  15568. "elevation": props.elevation,
  15569. "onFocus": focus,
  15570. "onBlur": blur,
  15571. "ripple": props.ripple,
  15572. "name": props.name
  15573. }, {
  15574. 'thumb-label': slots['thumb-label']
  15575. })]);
  15576. }
  15577. });
  15578. });
  15579. return {};
  15580. }
  15581. });
  15582. // Types
  15583. const makeVColorPickerPreviewProps = propsFactory({
  15584. color: {
  15585. type: Object
  15586. },
  15587. disabled: Boolean,
  15588. hideAlpha: Boolean,
  15589. ...makeComponentProps()
  15590. }, 'VColorPickerPreview');
  15591. const VColorPickerPreview = defineComponent({
  15592. name: 'VColorPickerPreview',
  15593. props: makeVColorPickerPreviewProps(),
  15594. emits: {
  15595. 'update:color': color => true
  15596. },
  15597. setup(props, _ref) {
  15598. let {
  15599. emit
  15600. } = _ref;
  15601. const abortController = new AbortController();
  15602. onUnmounted(() => abortController.abort());
  15603. async function openEyeDropper() {
  15604. if (!SUPPORTS_EYE_DROPPER) return;
  15605. const eyeDropper = new window.EyeDropper();
  15606. try {
  15607. const result = await eyeDropper.open({
  15608. signal: abortController.signal
  15609. });
  15610. const colorHexValue = HexToHSV(result.sRGBHex);
  15611. emit('update:color', {
  15612. ...(props.color ?? nullColor),
  15613. ...colorHexValue
  15614. });
  15615. } catch (e) {}
  15616. }
  15617. useRender(() => createVNode("div", {
  15618. "class": ['v-color-picker-preview', {
  15619. 'v-color-picker-preview--hide-alpha': props.hideAlpha
  15620. }, props.class],
  15621. "style": props.style
  15622. }, [SUPPORTS_EYE_DROPPER && createVNode("div", {
  15623. "class": "v-color-picker-preview__eye-dropper",
  15624. "key": "eyeDropper"
  15625. }, [createVNode(VBtn, {
  15626. "onClick": openEyeDropper,
  15627. "icon": "$eyeDropper",
  15628. "variant": "plain",
  15629. "density": "comfortable"
  15630. }, null)]), createVNode("div", {
  15631. "class": "v-color-picker-preview__dot"
  15632. }, [createVNode("div", {
  15633. "style": {
  15634. background: HSVtoCSS(props.color ?? nullColor)
  15635. }
  15636. }, null)]), createVNode("div", {
  15637. "class": "v-color-picker-preview__sliders"
  15638. }, [createVNode(VSlider, {
  15639. "class": "v-color-picker-preview__track v-color-picker-preview__hue",
  15640. "modelValue": props.color?.h,
  15641. "onUpdate:modelValue": h => emit('update:color', {
  15642. ...(props.color ?? nullColor),
  15643. h
  15644. }),
  15645. "step": 0,
  15646. "min": 0,
  15647. "max": 360,
  15648. "disabled": props.disabled,
  15649. "thumbSize": 14,
  15650. "trackSize": 8,
  15651. "trackFillColor": "white",
  15652. "hideDetails": true
  15653. }, null), !props.hideAlpha && createVNode(VSlider, {
  15654. "class": "v-color-picker-preview__track v-color-picker-preview__alpha",
  15655. "modelValue": props.color?.a ?? 1,
  15656. "onUpdate:modelValue": a => emit('update:color', {
  15657. ...(props.color ?? nullColor),
  15658. a
  15659. }),
  15660. "step": 1 / 256,
  15661. "min": 0,
  15662. "max": 1,
  15663. "disabled": props.disabled,
  15664. "thumbSize": 14,
  15665. "trackSize": 8,
  15666. "trackFillColor": "white",
  15667. "hideDetails": true
  15668. }, null)])]));
  15669. return {};
  15670. }
  15671. });
  15672. const red = {
  15673. base: '#f44336',
  15674. lighten5: '#ffebee',
  15675. lighten4: '#ffcdd2',
  15676. lighten3: '#ef9a9a',
  15677. lighten2: '#e57373',
  15678. lighten1: '#ef5350',
  15679. darken1: '#e53935',
  15680. darken2: '#d32f2f',
  15681. darken3: '#c62828',
  15682. darken4: '#b71c1c',
  15683. accent1: '#ff8a80',
  15684. accent2: '#ff5252',
  15685. accent3: '#ff1744',
  15686. accent4: '#d50000'
  15687. };
  15688. const pink = {
  15689. base: '#e91e63',
  15690. lighten5: '#fce4ec',
  15691. lighten4: '#f8bbd0',
  15692. lighten3: '#f48fb1',
  15693. lighten2: '#f06292',
  15694. lighten1: '#ec407a',
  15695. darken1: '#d81b60',
  15696. darken2: '#c2185b',
  15697. darken3: '#ad1457',
  15698. darken4: '#880e4f',
  15699. accent1: '#ff80ab',
  15700. accent2: '#ff4081',
  15701. accent3: '#f50057',
  15702. accent4: '#c51162'
  15703. };
  15704. const purple = {
  15705. base: '#9c27b0',
  15706. lighten5: '#f3e5f5',
  15707. lighten4: '#e1bee7',
  15708. lighten3: '#ce93d8',
  15709. lighten2: '#ba68c8',
  15710. lighten1: '#ab47bc',
  15711. darken1: '#8e24aa',
  15712. darken2: '#7b1fa2',
  15713. darken3: '#6a1b9a',
  15714. darken4: '#4a148c',
  15715. accent1: '#ea80fc',
  15716. accent2: '#e040fb',
  15717. accent3: '#d500f9',
  15718. accent4: '#aa00ff'
  15719. };
  15720. const deepPurple = {
  15721. base: '#673ab7',
  15722. lighten5: '#ede7f6',
  15723. lighten4: '#d1c4e9',
  15724. lighten3: '#b39ddb',
  15725. lighten2: '#9575cd',
  15726. lighten1: '#7e57c2',
  15727. darken1: '#5e35b1',
  15728. darken2: '#512da8',
  15729. darken3: '#4527a0',
  15730. darken4: '#311b92',
  15731. accent1: '#b388ff',
  15732. accent2: '#7c4dff',
  15733. accent3: '#651fff',
  15734. accent4: '#6200ea'
  15735. };
  15736. const indigo = {
  15737. base: '#3f51b5',
  15738. lighten5: '#e8eaf6',
  15739. lighten4: '#c5cae9',
  15740. lighten3: '#9fa8da',
  15741. lighten2: '#7986cb',
  15742. lighten1: '#5c6bc0',
  15743. darken1: '#3949ab',
  15744. darken2: '#303f9f',
  15745. darken3: '#283593',
  15746. darken4: '#1a237e',
  15747. accent1: '#8c9eff',
  15748. accent2: '#536dfe',
  15749. accent3: '#3d5afe',
  15750. accent4: '#304ffe'
  15751. };
  15752. const blue = {
  15753. base: '#2196f3',
  15754. lighten5: '#e3f2fd',
  15755. lighten4: '#bbdefb',
  15756. lighten3: '#90caf9',
  15757. lighten2: '#64b5f6',
  15758. lighten1: '#42a5f5',
  15759. darken1: '#1e88e5',
  15760. darken2: '#1976d2',
  15761. darken3: '#1565c0',
  15762. darken4: '#0d47a1',
  15763. accent1: '#82b1ff',
  15764. accent2: '#448aff',
  15765. accent3: '#2979ff',
  15766. accent4: '#2962ff'
  15767. };
  15768. const lightBlue = {
  15769. base: '#03a9f4',
  15770. lighten5: '#e1f5fe',
  15771. lighten4: '#b3e5fc',
  15772. lighten3: '#81d4fa',
  15773. lighten2: '#4fc3f7',
  15774. lighten1: '#29b6f6',
  15775. darken1: '#039be5',
  15776. darken2: '#0288d1',
  15777. darken3: '#0277bd',
  15778. darken4: '#01579b',
  15779. accent1: '#80d8ff',
  15780. accent2: '#40c4ff',
  15781. accent3: '#00b0ff',
  15782. accent4: '#0091ea'
  15783. };
  15784. const cyan = {
  15785. base: '#00bcd4',
  15786. lighten5: '#e0f7fa',
  15787. lighten4: '#b2ebf2',
  15788. lighten3: '#80deea',
  15789. lighten2: '#4dd0e1',
  15790. lighten1: '#26c6da',
  15791. darken1: '#00acc1',
  15792. darken2: '#0097a7',
  15793. darken3: '#00838f',
  15794. darken4: '#006064',
  15795. accent1: '#84ffff',
  15796. accent2: '#18ffff',
  15797. accent3: '#00e5ff',
  15798. accent4: '#00b8d4'
  15799. };
  15800. const teal = {
  15801. base: '#009688',
  15802. lighten5: '#e0f2f1',
  15803. lighten4: '#b2dfdb',
  15804. lighten3: '#80cbc4',
  15805. lighten2: '#4db6ac',
  15806. lighten1: '#26a69a',
  15807. darken1: '#00897b',
  15808. darken2: '#00796b',
  15809. darken3: '#00695c',
  15810. darken4: '#004d40',
  15811. accent1: '#a7ffeb',
  15812. accent2: '#64ffda',
  15813. accent3: '#1de9b6',
  15814. accent4: '#00bfa5'
  15815. };
  15816. const green = {
  15817. base: '#4caf50',
  15818. lighten5: '#e8f5e9',
  15819. lighten4: '#c8e6c9',
  15820. lighten3: '#a5d6a7',
  15821. lighten2: '#81c784',
  15822. lighten1: '#66bb6a',
  15823. darken1: '#43a047',
  15824. darken2: '#388e3c',
  15825. darken3: '#2e7d32',
  15826. darken4: '#1b5e20',
  15827. accent1: '#b9f6ca',
  15828. accent2: '#69f0ae',
  15829. accent3: '#00e676',
  15830. accent4: '#00c853'
  15831. };
  15832. const lightGreen = {
  15833. base: '#8bc34a',
  15834. lighten5: '#f1f8e9',
  15835. lighten4: '#dcedc8',
  15836. lighten3: '#c5e1a5',
  15837. lighten2: '#aed581',
  15838. lighten1: '#9ccc65',
  15839. darken1: '#7cb342',
  15840. darken2: '#689f38',
  15841. darken3: '#558b2f',
  15842. darken4: '#33691e',
  15843. accent1: '#ccff90',
  15844. accent2: '#b2ff59',
  15845. accent3: '#76ff03',
  15846. accent4: '#64dd17'
  15847. };
  15848. const lime = {
  15849. base: '#cddc39',
  15850. lighten5: '#f9fbe7',
  15851. lighten4: '#f0f4c3',
  15852. lighten3: '#e6ee9c',
  15853. lighten2: '#dce775',
  15854. lighten1: '#d4e157',
  15855. darken1: '#c0ca33',
  15856. darken2: '#afb42b',
  15857. darken3: '#9e9d24',
  15858. darken4: '#827717',
  15859. accent1: '#f4ff81',
  15860. accent2: '#eeff41',
  15861. accent3: '#c6ff00',
  15862. accent4: '#aeea00'
  15863. };
  15864. const yellow = {
  15865. base: '#ffeb3b',
  15866. lighten5: '#fffde7',
  15867. lighten4: '#fff9c4',
  15868. lighten3: '#fff59d',
  15869. lighten2: '#fff176',
  15870. lighten1: '#ffee58',
  15871. darken1: '#fdd835',
  15872. darken2: '#fbc02d',
  15873. darken3: '#f9a825',
  15874. darken4: '#f57f17',
  15875. accent1: '#ffff8d',
  15876. accent2: '#ffff00',
  15877. accent3: '#ffea00',
  15878. accent4: '#ffd600'
  15879. };
  15880. const amber = {
  15881. base: '#ffc107',
  15882. lighten5: '#fff8e1',
  15883. lighten4: '#ffecb3',
  15884. lighten3: '#ffe082',
  15885. lighten2: '#ffd54f',
  15886. lighten1: '#ffca28',
  15887. darken1: '#ffb300',
  15888. darken2: '#ffa000',
  15889. darken3: '#ff8f00',
  15890. darken4: '#ff6f00',
  15891. accent1: '#ffe57f',
  15892. accent2: '#ffd740',
  15893. accent3: '#ffc400',
  15894. accent4: '#ffab00'
  15895. };
  15896. const orange = {
  15897. base: '#ff9800',
  15898. lighten5: '#fff3e0',
  15899. lighten4: '#ffe0b2',
  15900. lighten3: '#ffcc80',
  15901. lighten2: '#ffb74d',
  15902. lighten1: '#ffa726',
  15903. darken1: '#fb8c00',
  15904. darken2: '#f57c00',
  15905. darken3: '#ef6c00',
  15906. darken4: '#e65100',
  15907. accent1: '#ffd180',
  15908. accent2: '#ffab40',
  15909. accent3: '#ff9100',
  15910. accent4: '#ff6d00'
  15911. };
  15912. const deepOrange = {
  15913. base: '#ff5722',
  15914. lighten5: '#fbe9e7',
  15915. lighten4: '#ffccbc',
  15916. lighten3: '#ffab91',
  15917. lighten2: '#ff8a65',
  15918. lighten1: '#ff7043',
  15919. darken1: '#f4511e',
  15920. darken2: '#e64a19',
  15921. darken3: '#d84315',
  15922. darken4: '#bf360c',
  15923. accent1: '#ff9e80',
  15924. accent2: '#ff6e40',
  15925. accent3: '#ff3d00',
  15926. accent4: '#dd2c00'
  15927. };
  15928. const brown = {
  15929. base: '#795548',
  15930. lighten5: '#efebe9',
  15931. lighten4: '#d7ccc8',
  15932. lighten3: '#bcaaa4',
  15933. lighten2: '#a1887f',
  15934. lighten1: '#8d6e63',
  15935. darken1: '#6d4c41',
  15936. darken2: '#5d4037',
  15937. darken3: '#4e342e',
  15938. darken4: '#3e2723'
  15939. };
  15940. const blueGrey = {
  15941. base: '#607d8b',
  15942. lighten5: '#eceff1',
  15943. lighten4: '#cfd8dc',
  15944. lighten3: '#b0bec5',
  15945. lighten2: '#90a4ae',
  15946. lighten1: '#78909c',
  15947. darken1: '#546e7a',
  15948. darken2: '#455a64',
  15949. darken3: '#37474f',
  15950. darken4: '#263238'
  15951. };
  15952. const grey = {
  15953. base: '#9e9e9e',
  15954. lighten5: '#fafafa',
  15955. lighten4: '#f5f5f5',
  15956. lighten3: '#eeeeee',
  15957. lighten2: '#e0e0e0',
  15958. lighten1: '#bdbdbd',
  15959. darken1: '#757575',
  15960. darken2: '#616161',
  15961. darken3: '#424242',
  15962. darken4: '#212121'
  15963. };
  15964. const shades = {
  15965. black: '#000000',
  15966. white: '#ffffff',
  15967. transparent: '#ffffff00'
  15968. };
  15969. var colors = {
  15970. red,
  15971. pink,
  15972. purple,
  15973. deepPurple,
  15974. indigo,
  15975. blue,
  15976. lightBlue,
  15977. cyan,
  15978. teal,
  15979. green,
  15980. lightGreen,
  15981. lime,
  15982. yellow,
  15983. amber,
  15984. orange,
  15985. deepOrange,
  15986. brown,
  15987. blueGrey,
  15988. grey,
  15989. shades
  15990. };
  15991. // Types
  15992. const makeVColorPickerSwatchesProps = propsFactory({
  15993. swatches: {
  15994. type: Array,
  15995. default: () => parseDefaultColors(colors)
  15996. },
  15997. disabled: Boolean,
  15998. color: Object,
  15999. maxHeight: [Number, String],
  16000. ...makeComponentProps()
  16001. }, 'VColorPickerSwatches');
  16002. function parseDefaultColors(colors) {
  16003. return Object.keys(colors).map(key => {
  16004. const color = colors[key];
  16005. 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];
  16006. });
  16007. }
  16008. const VColorPickerSwatches = defineComponent({
  16009. name: 'VColorPickerSwatches',
  16010. props: makeVColorPickerSwatchesProps(),
  16011. emits: {
  16012. 'update:color': color => true
  16013. },
  16014. setup(props, _ref) {
  16015. let {
  16016. emit
  16017. } = _ref;
  16018. useRender(() => createVNode("div", {
  16019. "class": ['v-color-picker-swatches', props.class],
  16020. "style": [{
  16021. maxHeight: convertToUnit(props.maxHeight)
  16022. }, props.style]
  16023. }, [createVNode("div", null, [props.swatches.map(swatch => createVNode("div", {
  16024. "class": "v-color-picker-swatches__swatch"
  16025. }, [swatch.map(color => {
  16026. const rgba = parseColor(color);
  16027. const hsva = RGBtoHSV(rgba);
  16028. const background = RGBtoCSS(rgba);
  16029. return createVNode("div", {
  16030. "class": "v-color-picker-swatches__color",
  16031. "onClick": () => hsva && emit('update:color', hsva)
  16032. }, [createVNode("div", {
  16033. "style": {
  16034. background
  16035. }
  16036. }, [props.color && deepEqual(props.color, hsva) ? createVNode(VIcon, {
  16037. "size": "x-small",
  16038. "icon": "$success",
  16039. "color": getContrast(color, '#FFFFFF') > 2 ? 'white' : 'black'
  16040. }, null) : undefined])]);
  16041. })]))])]));
  16042. return {};
  16043. }
  16044. });
  16045. const makeVSheetProps = propsFactory({
  16046. color: String,
  16047. ...makeBorderProps(),
  16048. ...makeComponentProps(),
  16049. ...makeDimensionProps(),
  16050. ...makeElevationProps(),
  16051. ...makeLocationProps(),
  16052. ...makePositionProps(),
  16053. ...makeRoundedProps(),
  16054. ...makeTagProps(),
  16055. ...makeThemeProps()
  16056. }, 'VSheet');
  16057. const VSheet = genericComponent()({
  16058. name: 'VSheet',
  16059. props: makeVSheetProps(),
  16060. setup(props, _ref) {
  16061. let {
  16062. slots
  16063. } = _ref;
  16064. const {
  16065. themeClasses
  16066. } = provideTheme(props);
  16067. const {
  16068. backgroundColorClasses,
  16069. backgroundColorStyles
  16070. } = useBackgroundColor(toRef(props, 'color'));
  16071. const {
  16072. borderClasses
  16073. } = useBorder(props);
  16074. const {
  16075. dimensionStyles
  16076. } = useDimension(props);
  16077. const {
  16078. elevationClasses
  16079. } = useElevation(props);
  16080. const {
  16081. locationStyles
  16082. } = useLocation(props);
  16083. const {
  16084. positionClasses
  16085. } = usePosition(props);
  16086. const {
  16087. roundedClasses
  16088. } = useRounded(props);
  16089. useRender(() => createVNode(props.tag, {
  16090. "class": ['v-sheet', themeClasses.value, backgroundColorClasses.value, borderClasses.value, elevationClasses.value, positionClasses.value, roundedClasses.value, props.class],
  16091. "style": [backgroundColorStyles.value, dimensionStyles.value, locationStyles.value, props.style]
  16092. }, slots));
  16093. return {};
  16094. }
  16095. });
  16096. // Types
  16097. const makeVColorPickerProps = propsFactory({
  16098. canvasHeight: {
  16099. type: [String, Number],
  16100. default: 150
  16101. },
  16102. disabled: Boolean,
  16103. dotSize: {
  16104. type: [Number, String],
  16105. default: 10
  16106. },
  16107. hideCanvas: Boolean,
  16108. hideSliders: Boolean,
  16109. hideInputs: Boolean,
  16110. mode: {
  16111. type: String,
  16112. default: 'rgba',
  16113. validator: v => Object.keys(modes).includes(v)
  16114. },
  16115. modes: {
  16116. type: Array,
  16117. default: () => Object.keys(modes),
  16118. validator: v => Array.isArray(v) && v.every(m => Object.keys(modes).includes(m))
  16119. },
  16120. showSwatches: Boolean,
  16121. swatches: Array,
  16122. swatchesMaxHeight: {
  16123. type: [Number, String],
  16124. default: 150
  16125. },
  16126. modelValue: {
  16127. type: [Object, String]
  16128. },
  16129. ...omit(makeVSheetProps({
  16130. width: 300
  16131. }), ['height', 'location', 'minHeight', 'maxHeight', 'minWidth', 'maxWidth'])
  16132. }, 'VColorPicker');
  16133. const VColorPicker = defineComponent({
  16134. name: 'VColorPicker',
  16135. props: makeVColorPickerProps(),
  16136. emits: {
  16137. 'update:modelValue': color => true,
  16138. 'update:mode': mode => true
  16139. },
  16140. setup(props) {
  16141. const mode = useProxiedModel(props, 'mode');
  16142. const hue = ref(null);
  16143. const model = useProxiedModel(props, 'modelValue', undefined, v => {
  16144. if (v == null || v === '') return null;
  16145. let c;
  16146. try {
  16147. c = RGBtoHSV(parseColor(v));
  16148. } catch (err) {
  16149. consoleWarn(err);
  16150. return null;
  16151. }
  16152. return c;
  16153. }, v => {
  16154. if (!v) return null;
  16155. return extractColor(v, props.modelValue);
  16156. });
  16157. const currentColor = computed(() => {
  16158. return model.value ? {
  16159. ...model.value,
  16160. h: hue.value ?? model.value.h
  16161. } : null;
  16162. });
  16163. const {
  16164. rtlClasses
  16165. } = useRtl();
  16166. let externalChange = true;
  16167. watch(model, v => {
  16168. if (!externalChange) {
  16169. // prevent hue shift from rgb conversion inaccuracy
  16170. externalChange = true;
  16171. return;
  16172. }
  16173. if (!v) return;
  16174. hue.value = v.h;
  16175. }, {
  16176. immediate: true
  16177. });
  16178. const updateColor = hsva => {
  16179. externalChange = false;
  16180. hue.value = hsva.h;
  16181. model.value = hsva;
  16182. };
  16183. onBeforeMount(() => {
  16184. if (!props.modes.includes(mode.value)) mode.value = props.modes[0];
  16185. });
  16186. provideDefaults({
  16187. VSlider: {
  16188. color: undefined,
  16189. trackColor: undefined,
  16190. trackFillColor: undefined
  16191. }
  16192. });
  16193. useRender(() => {
  16194. const sheetProps = VSheet.filterProps(props);
  16195. return createVNode(VSheet, mergeProps({
  16196. "rounded": props.rounded,
  16197. "elevation": props.elevation,
  16198. "theme": props.theme,
  16199. "class": ['v-color-picker', rtlClasses.value, props.class],
  16200. "style": [{
  16201. '--v-color-picker-color-hsv': HSVtoCSS({
  16202. ...(currentColor.value ?? nullColor),
  16203. a: 1
  16204. })
  16205. }, props.style]
  16206. }, sheetProps, {
  16207. "maxWidth": props.width
  16208. }), {
  16209. default: () => [!props.hideCanvas && createVNode(VColorPickerCanvas, {
  16210. "key": "canvas",
  16211. "color": currentColor.value,
  16212. "onUpdate:color": updateColor,
  16213. "disabled": props.disabled,
  16214. "dotSize": props.dotSize,
  16215. "width": props.width,
  16216. "height": props.canvasHeight
  16217. }, null), (!props.hideSliders || !props.hideInputs) && createVNode("div", {
  16218. "key": "controls",
  16219. "class": "v-color-picker__controls"
  16220. }, [!props.hideSliders && createVNode(VColorPickerPreview, {
  16221. "key": "preview",
  16222. "color": currentColor.value,
  16223. "onUpdate:color": updateColor,
  16224. "hideAlpha": !mode.value.endsWith('a'),
  16225. "disabled": props.disabled
  16226. }, null), !props.hideInputs && createVNode(VColorPickerEdit, {
  16227. "key": "edit",
  16228. "modes": props.modes,
  16229. "mode": mode.value,
  16230. "onUpdate:mode": m => mode.value = m,
  16231. "color": currentColor.value,
  16232. "onUpdate:color": updateColor,
  16233. "disabled": props.disabled
  16234. }, null)]), props.showSwatches && createVNode(VColorPickerSwatches, {
  16235. "key": "swatches",
  16236. "color": currentColor.value,
  16237. "onUpdate:color": updateColor,
  16238. "maxHeight": props.swatchesMaxHeight,
  16239. "swatches": props.swatches,
  16240. "disabled": props.disabled
  16241. }, null)]
  16242. });
  16243. });
  16244. return {};
  16245. }
  16246. });
  16247. // Types
  16248. function highlightResult(text, matches, length) {
  16249. if (matches == null) return text;
  16250. if (Array.isArray(matches)) throw new Error('Multiple matches is not implemented');
  16251. return typeof matches === 'number' && ~matches ? createVNode(Fragment, null, [createVNode("span", {
  16252. "class": "v-combobox__unmask"
  16253. }, [text.substr(0, matches)]), createVNode("span", {
  16254. "class": "v-combobox__mask"
  16255. }, [text.substr(matches, length)]), createVNode("span", {
  16256. "class": "v-combobox__unmask"
  16257. }, [text.substr(matches + length)])]) : text;
  16258. }
  16259. const makeVComboboxProps = propsFactory({
  16260. autoSelectFirst: {
  16261. type: [Boolean, String]
  16262. },
  16263. clearOnSelect: {
  16264. type: Boolean,
  16265. default: true
  16266. },
  16267. delimiters: Array,
  16268. ...makeFilterProps({
  16269. filterKeys: ['title']
  16270. }),
  16271. ...makeSelectProps({
  16272. hideNoData: true,
  16273. returnObject: true
  16274. }),
  16275. ...omit(makeVTextFieldProps({
  16276. modelValue: null,
  16277. role: 'combobox'
  16278. }), ['validationValue', 'dirty', 'appendInnerIcon']),
  16279. ...makeTransitionProps({
  16280. transition: false
  16281. })
  16282. }, 'VCombobox');
  16283. const VCombobox = genericComponent()({
  16284. name: 'VCombobox',
  16285. props: makeVComboboxProps(),
  16286. emits: {
  16287. 'update:focused': focused => true,
  16288. 'update:modelValue': value => true,
  16289. 'update:search': value => true,
  16290. 'update:menu': value => true
  16291. },
  16292. setup(props, _ref) {
  16293. let {
  16294. emit,
  16295. slots
  16296. } = _ref;
  16297. const {
  16298. t
  16299. } = useLocale();
  16300. const vTextFieldRef = ref();
  16301. const isFocused = shallowRef(false);
  16302. const isPristine = shallowRef(true);
  16303. const listHasFocus = shallowRef(false);
  16304. const vMenuRef = ref();
  16305. const vVirtualScrollRef = ref();
  16306. const _menu = useProxiedModel(props, 'menu');
  16307. const menu = computed({
  16308. get: () => _menu.value,
  16309. set: v => {
  16310. if (_menu.value && !v && vMenuRef.value?.ΨopenChildren.size) return;
  16311. _menu.value = v;
  16312. }
  16313. });
  16314. const selectionIndex = shallowRef(-1);
  16315. let cleared = false;
  16316. const color = computed(() => vTextFieldRef.value?.color);
  16317. const label = computed(() => menu.value ? props.closeText : props.openText);
  16318. const {
  16319. items,
  16320. transformIn,
  16321. transformOut
  16322. } = useItems(props);
  16323. const {
  16324. textColorClasses,
  16325. textColorStyles
  16326. } = useTextColor(color);
  16327. const model = useProxiedModel(props, 'modelValue', [], v => transformIn(wrapInArray(v)), v => {
  16328. const transformed = transformOut(v);
  16329. return props.multiple ? transformed : transformed[0] ?? null;
  16330. });
  16331. const form = useForm(props);
  16332. const hasChips = computed(() => !!(props.chips || slots.chip));
  16333. const hasSelectionSlot = computed(() => hasChips.value || !!slots.selection);
  16334. const _search = shallowRef(!props.multiple && !hasSelectionSlot.value ? model.value[0]?.title ?? '' : '');
  16335. const search = computed({
  16336. get: () => {
  16337. return _search.value;
  16338. },
  16339. set: val => {
  16340. _search.value = val ?? '';
  16341. if (!props.multiple && !hasSelectionSlot.value) {
  16342. model.value = [transformItem$3(props, val)];
  16343. }
  16344. if (val && props.multiple && props.delimiters?.length) {
  16345. const values = val.split(new RegExp(`(?:${props.delimiters.join('|')})+`));
  16346. if (values.length > 1) {
  16347. values.forEach(v => {
  16348. v = v.trim();
  16349. if (v) select(transformItem$3(props, v));
  16350. });
  16351. _search.value = '';
  16352. }
  16353. }
  16354. if (!val) selectionIndex.value = -1;
  16355. isPristine.value = !val;
  16356. }
  16357. });
  16358. const counterValue = computed(() => {
  16359. return typeof props.counterValue === 'function' ? props.counterValue(model.value) : typeof props.counterValue === 'number' ? props.counterValue : props.multiple ? model.value.length : search.value.length;
  16360. });
  16361. watch(_search, value => {
  16362. if (cleared) {
  16363. // wait for clear to finish, VTextField sets _search to null
  16364. // then search computed triggers and updates _search to ''
  16365. nextTick(() => cleared = false);
  16366. } else if (isFocused.value && !menu.value) {
  16367. menu.value = true;
  16368. }
  16369. emit('update:search', value);
  16370. });
  16371. watch(model, value => {
  16372. if (!props.multiple && !hasSelectionSlot.value) {
  16373. _search.value = value[0]?.title ?? '';
  16374. }
  16375. });
  16376. const {
  16377. filteredItems,
  16378. getMatches
  16379. } = useFilter(props, items, () => isPristine.value ? '' : search.value);
  16380. const displayItems = computed(() => {
  16381. if (props.hideSelected) {
  16382. return filteredItems.value.filter(filteredItem => !model.value.some(s => s.value === filteredItem.value));
  16383. }
  16384. return filteredItems.value;
  16385. });
  16386. const selectedValues = computed(() => model.value.map(selection => selection.value));
  16387. const highlightFirst = computed(() => {
  16388. const selectFirst = props.autoSelectFirst === true || props.autoSelectFirst === 'exact' && search.value === displayItems.value[0]?.title;
  16389. return selectFirst && displayItems.value.length > 0 && !isPristine.value && !listHasFocus.value;
  16390. });
  16391. const menuDisabled = computed(() => props.hideNoData && !displayItems.value.length || form.isReadonly.value || form.isDisabled.value);
  16392. const listRef = ref();
  16393. const listEvents = useScrolling(listRef, vTextFieldRef);
  16394. function onClear(e) {
  16395. cleared = true;
  16396. if (props.openOnClear) {
  16397. menu.value = true;
  16398. }
  16399. }
  16400. function onMousedownControl() {
  16401. if (menuDisabled.value) return;
  16402. menu.value = true;
  16403. }
  16404. function onMousedownMenuIcon(e) {
  16405. if (menuDisabled.value) return;
  16406. if (isFocused.value) {
  16407. e.preventDefault();
  16408. e.stopPropagation();
  16409. }
  16410. menu.value = !menu.value;
  16411. }
  16412. function onListKeydown(e) {
  16413. if (checkPrintable(e)) {
  16414. vTextFieldRef.value?.focus();
  16415. }
  16416. }
  16417. // eslint-disable-next-line complexity
  16418. function onKeydown(e) {
  16419. if (isComposingIgnoreKey(e) || form.isReadonly.value) return;
  16420. const selectionStart = vTextFieldRef.value.selectionStart;
  16421. const length = model.value.length;
  16422. if (selectionIndex.value > -1 || ['Enter', 'ArrowDown', 'ArrowUp'].includes(e.key)) {
  16423. e.preventDefault();
  16424. }
  16425. if (['Enter', 'ArrowDown'].includes(e.key)) {
  16426. menu.value = true;
  16427. }
  16428. if (['Escape'].includes(e.key)) {
  16429. menu.value = false;
  16430. }
  16431. if (['Enter', 'Escape', 'Tab'].includes(e.key)) {
  16432. if (highlightFirst.value && ['Enter', 'Tab'].includes(e.key) && !model.value.some(_ref2 => {
  16433. let {
  16434. value
  16435. } = _ref2;
  16436. return value === displayItems.value[0].value;
  16437. })) {
  16438. select(filteredItems.value[0]);
  16439. }
  16440. isPristine.value = true;
  16441. }
  16442. if (e.key === 'ArrowDown' && highlightFirst.value) {
  16443. listRef.value?.focus('next');
  16444. }
  16445. if (e.key === 'Enter' && search.value) {
  16446. select(transformItem$3(props, search.value));
  16447. if (hasSelectionSlot.value) _search.value = '';
  16448. }
  16449. if (['Backspace', 'Delete'].includes(e.key)) {
  16450. if (!props.multiple && hasSelectionSlot.value && model.value.length > 0 && !search.value) return select(model.value[0], false);
  16451. if (~selectionIndex.value) {
  16452. const originalSelectionIndex = selectionIndex.value;
  16453. select(model.value[selectionIndex.value], false);
  16454. selectionIndex.value = originalSelectionIndex >= length - 1 ? length - 2 : originalSelectionIndex;
  16455. } else if (e.key === 'Backspace' && !search.value) {
  16456. selectionIndex.value = length - 1;
  16457. }
  16458. }
  16459. if (!props.multiple) return;
  16460. if (e.key === 'ArrowLeft') {
  16461. if (selectionIndex.value < 0 && selectionStart > 0) return;
  16462. const prev = selectionIndex.value > -1 ? selectionIndex.value - 1 : length - 1;
  16463. if (model.value[prev]) {
  16464. selectionIndex.value = prev;
  16465. } else {
  16466. selectionIndex.value = -1;
  16467. vTextFieldRef.value.setSelectionRange(search.value.length, search.value.length);
  16468. }
  16469. }
  16470. if (e.key === 'ArrowRight') {
  16471. if (selectionIndex.value < 0) return;
  16472. const next = selectionIndex.value + 1;
  16473. if (model.value[next]) {
  16474. selectionIndex.value = next;
  16475. } else {
  16476. selectionIndex.value = -1;
  16477. vTextFieldRef.value.setSelectionRange(0, 0);
  16478. }
  16479. }
  16480. }
  16481. function onAfterEnter() {
  16482. if (props.eager) {
  16483. vVirtualScrollRef.value?.calculateVisibleItems();
  16484. }
  16485. }
  16486. function onAfterLeave() {
  16487. if (isFocused.value) {
  16488. isPristine.value = true;
  16489. vTextFieldRef.value?.focus();
  16490. }
  16491. }
  16492. /** @param set - null means toggle */
  16493. function select(item) {
  16494. let set = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  16495. if (!item || item.props.disabled) return;
  16496. if (props.multiple) {
  16497. const index = model.value.findIndex(selection => props.valueComparator(selection.value, item.value));
  16498. const add = set == null ? !~index : set;
  16499. if (~index) {
  16500. const value = add ? [...model.value, item] : [...model.value];
  16501. value.splice(index, 1);
  16502. model.value = value;
  16503. } else if (add) {
  16504. model.value = [...model.value, item];
  16505. }
  16506. if (props.clearOnSelect) {
  16507. search.value = '';
  16508. }
  16509. } else {
  16510. const add = set !== false;
  16511. model.value = add ? [item] : [];
  16512. _search.value = add && !hasSelectionSlot.value ? item.title : '';
  16513. // watch for search watcher to trigger
  16514. nextTick(() => {
  16515. menu.value = false;
  16516. isPristine.value = true;
  16517. });
  16518. }
  16519. }
  16520. function onFocusin(e) {
  16521. isFocused.value = true;
  16522. setTimeout(() => {
  16523. listHasFocus.value = true;
  16524. });
  16525. }
  16526. function onFocusout(e) {
  16527. listHasFocus.value = false;
  16528. }
  16529. function onUpdateModelValue(v) {
  16530. if (v == null || v === '' && !props.multiple && !hasSelectionSlot.value) model.value = [];
  16531. }
  16532. watch(isFocused, (val, oldVal) => {
  16533. if (val || val === oldVal) return;
  16534. selectionIndex.value = -1;
  16535. menu.value = false;
  16536. if (search.value) {
  16537. if (props.multiple) {
  16538. select(transformItem$3(props, search.value));
  16539. return;
  16540. }
  16541. if (!hasSelectionSlot.value) return;
  16542. if (model.value.some(_ref3 => {
  16543. let {
  16544. title
  16545. } = _ref3;
  16546. return title === search.value;
  16547. })) {
  16548. _search.value = '';
  16549. } else {
  16550. select(transformItem$3(props, search.value));
  16551. }
  16552. }
  16553. });
  16554. watch(menu, () => {
  16555. if (!props.hideSelected && menu.value && model.value.length) {
  16556. const index = displayItems.value.findIndex(item => model.value.some(s => props.valueComparator(s.value, item.value)));
  16557. IN_BROWSER && window.requestAnimationFrame(() => {
  16558. index >= 0 && vVirtualScrollRef.value?.scrollToIndex(index);
  16559. });
  16560. }
  16561. });
  16562. watch(() => props.items, (newVal, oldVal) => {
  16563. if (menu.value) return;
  16564. if (isFocused.value && !oldVal.length && newVal.length) {
  16565. menu.value = true;
  16566. }
  16567. });
  16568. useRender(() => {
  16569. const hasList = !!(!props.hideNoData || displayItems.value.length || slots['prepend-item'] || slots['append-item'] || slots['no-data']);
  16570. const isDirty = model.value.length > 0;
  16571. const textFieldProps = VTextField.filterProps(props);
  16572. return createVNode(VTextField, mergeProps({
  16573. "ref": vTextFieldRef
  16574. }, textFieldProps, {
  16575. "modelValue": search.value,
  16576. "onUpdate:modelValue": [$event => search.value = $event, onUpdateModelValue],
  16577. "focused": isFocused.value,
  16578. "onUpdate:focused": $event => isFocused.value = $event,
  16579. "validationValue": model.externalValue,
  16580. "counterValue": counterValue.value,
  16581. "dirty": isDirty,
  16582. "class": ['v-combobox', {
  16583. 'v-combobox--active-menu': menu.value,
  16584. 'v-combobox--chips': !!props.chips,
  16585. 'v-combobox--selection-slot': !!hasSelectionSlot.value,
  16586. 'v-combobox--selecting-index': selectionIndex.value > -1,
  16587. [`v-combobox--${props.multiple ? 'multiple' : 'single'}`]: true
  16588. }, props.class],
  16589. "style": props.style,
  16590. "readonly": form.isReadonly.value,
  16591. "placeholder": isDirty ? undefined : props.placeholder,
  16592. "onClick:clear": onClear,
  16593. "onMousedown:control": onMousedownControl,
  16594. "onKeydown": onKeydown
  16595. }), {
  16596. ...slots,
  16597. default: () => createVNode(Fragment, null, [createVNode(VMenu, mergeProps({
  16598. "ref": vMenuRef,
  16599. "modelValue": menu.value,
  16600. "onUpdate:modelValue": $event => menu.value = $event,
  16601. "activator": "parent",
  16602. "contentClass": "v-combobox__content",
  16603. "disabled": menuDisabled.value,
  16604. "eager": props.eager,
  16605. "maxHeight": 310,
  16606. "openOnClick": false,
  16607. "closeOnContentClick": false,
  16608. "transition": props.transition,
  16609. "onAfterEnter": onAfterEnter,
  16610. "onAfterLeave": onAfterLeave
  16611. }, props.menuProps), {
  16612. default: () => [hasList && createVNode(VList, mergeProps({
  16613. "ref": listRef,
  16614. "selected": selectedValues.value,
  16615. "selectStrategy": props.multiple ? 'independent' : 'single-independent',
  16616. "onMousedown": e => e.preventDefault(),
  16617. "onKeydown": onListKeydown,
  16618. "onFocusin": onFocusin,
  16619. "onFocusout": onFocusout,
  16620. "tabindex": "-1",
  16621. "aria-live": "polite",
  16622. "color": props.itemColor ?? props.color
  16623. }, listEvents, props.listProps), {
  16624. default: () => [slots['prepend-item']?.(), !displayItems.value.length && !props.hideNoData && (slots['no-data']?.() ?? createVNode(VListItem, {
  16625. "key": "no-data",
  16626. "title": t(props.noDataText)
  16627. }, null)), createVNode(VVirtualScroll, {
  16628. "ref": vVirtualScrollRef,
  16629. "renderless": true,
  16630. "items": displayItems.value
  16631. }, {
  16632. default: _ref4 => {
  16633. let {
  16634. item,
  16635. index,
  16636. itemRef
  16637. } = _ref4;
  16638. const itemProps = mergeProps(item.props, {
  16639. ref: itemRef,
  16640. key: item.value,
  16641. active: highlightFirst.value && index === 0 ? true : undefined,
  16642. onClick: () => select(item, null)
  16643. });
  16644. return slots.item?.({
  16645. item,
  16646. index,
  16647. props: itemProps
  16648. }) ?? createVNode(VListItem, mergeProps(itemProps, {
  16649. "role": "option"
  16650. }), {
  16651. prepend: _ref5 => {
  16652. let {
  16653. isSelected
  16654. } = _ref5;
  16655. return createVNode(Fragment, null, [props.multiple && !props.hideSelected ? createVNode(VCheckboxBtn, {
  16656. "key": item.value,
  16657. "modelValue": isSelected,
  16658. "ripple": false,
  16659. "tabindex": "-1"
  16660. }, null) : undefined, item.props.prependAvatar && createVNode(VAvatar, {
  16661. "image": item.props.prependAvatar
  16662. }, null), item.props.prependIcon && createVNode(VIcon, {
  16663. "icon": item.props.prependIcon
  16664. }, null)]);
  16665. },
  16666. title: () => {
  16667. return isPristine.value ? item.title : highlightResult(item.title, getMatches(item)?.title, search.value?.length ?? 0);
  16668. }
  16669. });
  16670. }
  16671. }), slots['append-item']?.()]
  16672. })]
  16673. }), model.value.map((item, index) => {
  16674. function onChipClose(e) {
  16675. e.stopPropagation();
  16676. e.preventDefault();
  16677. select(item, false);
  16678. }
  16679. const slotProps = {
  16680. 'onClick:close': onChipClose,
  16681. onKeydown(e) {
  16682. if (e.key !== 'Enter' && e.key !== ' ') return;
  16683. e.preventDefault();
  16684. e.stopPropagation();
  16685. onChipClose(e);
  16686. },
  16687. onMousedown(e) {
  16688. e.preventDefault();
  16689. e.stopPropagation();
  16690. },
  16691. modelValue: true,
  16692. 'onUpdate:modelValue': undefined
  16693. };
  16694. const hasSlot = hasChips.value ? !!slots.chip : !!slots.selection;
  16695. const slotContent = hasSlot ? ensureValidVNode(hasChips.value ? slots.chip({
  16696. item,
  16697. index,
  16698. props: slotProps
  16699. }) : slots.selection({
  16700. item,
  16701. index
  16702. })) : undefined;
  16703. if (hasSlot && !slotContent) return undefined;
  16704. return createVNode("div", {
  16705. "key": item.value,
  16706. "class": ['v-combobox__selection', index === selectionIndex.value && ['v-combobox__selection--selected', textColorClasses.value]],
  16707. "style": index === selectionIndex.value ? textColorStyles.value : {}
  16708. }, [hasChips.value ? !slots.chip ? createVNode(VChip, mergeProps({
  16709. "key": "chip",
  16710. "closable": props.closableChips,
  16711. "size": "small",
  16712. "text": item.title,
  16713. "disabled": item.props.disabled
  16714. }, slotProps), null) : createVNode(VDefaultsProvider, {
  16715. "key": "chip-defaults",
  16716. "defaults": {
  16717. VChip: {
  16718. closable: props.closableChips,
  16719. size: 'small',
  16720. text: item.title
  16721. }
  16722. }
  16723. }, {
  16724. default: () => [slotContent]
  16725. }) : slotContent ?? createVNode("span", {
  16726. "class": "v-combobox__selection-text"
  16727. }, [item.title, props.multiple && index < model.value.length - 1 && createVNode("span", {
  16728. "class": "v-combobox__selection-comma"
  16729. }, [createTextVNode(",")])])]);
  16730. })]),
  16731. 'append-inner': function () {
  16732. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  16733. args[_key] = arguments[_key];
  16734. }
  16735. return createVNode(Fragment, null, [slots['append-inner']?.(...args), (!props.hideNoData || props.items.length) && props.menuIcon ? createVNode(VIcon, {
  16736. "class": "v-combobox__menu-icon",
  16737. "icon": props.menuIcon,
  16738. "onMousedown": onMousedownMenuIcon,
  16739. "onClick": noop,
  16740. "aria-label": t(label.value),
  16741. "title": t(label.value),
  16742. "tabindex": "-1"
  16743. }, null) : undefined]);
  16744. }
  16745. });
  16746. });
  16747. return forwardRefs({
  16748. isFocused,
  16749. isPristine,
  16750. menu,
  16751. search,
  16752. selectionIndex,
  16753. filteredItems,
  16754. select
  16755. }, vTextFieldRef);
  16756. }
  16757. });
  16758. // Utilities
  16759. // Types
  16760. const firstDay = {
  16761. '001': 1,
  16762. AD: 1,
  16763. AE: 6,
  16764. AF: 6,
  16765. AG: 0,
  16766. AI: 1,
  16767. AL: 1,
  16768. AM: 1,
  16769. AN: 1,
  16770. AR: 1,
  16771. AS: 0,
  16772. AT: 1,
  16773. AU: 1,
  16774. AX: 1,
  16775. AZ: 1,
  16776. BA: 1,
  16777. BD: 0,
  16778. BE: 1,
  16779. BG: 1,
  16780. BH: 6,
  16781. BM: 1,
  16782. BN: 1,
  16783. BR: 0,
  16784. BS: 0,
  16785. BT: 0,
  16786. BW: 0,
  16787. BY: 1,
  16788. BZ: 0,
  16789. CA: 0,
  16790. CH: 1,
  16791. CL: 1,
  16792. CM: 1,
  16793. CN: 1,
  16794. CO: 0,
  16795. CR: 1,
  16796. CY: 1,
  16797. CZ: 1,
  16798. DE: 1,
  16799. DJ: 6,
  16800. DK: 1,
  16801. DM: 0,
  16802. DO: 0,
  16803. DZ: 6,
  16804. EC: 1,
  16805. EE: 1,
  16806. EG: 6,
  16807. ES: 1,
  16808. ET: 0,
  16809. FI: 1,
  16810. FJ: 1,
  16811. FO: 1,
  16812. FR: 1,
  16813. GB: 1,
  16814. 'GB-alt-variant': 0,
  16815. GE: 1,
  16816. GF: 1,
  16817. GP: 1,
  16818. GR: 1,
  16819. GT: 0,
  16820. GU: 0,
  16821. HK: 0,
  16822. HN: 0,
  16823. HR: 1,
  16824. HU: 1,
  16825. ID: 0,
  16826. IE: 1,
  16827. IL: 0,
  16828. IN: 0,
  16829. IQ: 6,
  16830. IR: 6,
  16831. IS: 1,
  16832. IT: 1,
  16833. JM: 0,
  16834. JO: 6,
  16835. JP: 0,
  16836. KE: 0,
  16837. KG: 1,
  16838. KH: 0,
  16839. KR: 0,
  16840. KW: 6,
  16841. KZ: 1,
  16842. LA: 0,
  16843. LB: 1,
  16844. LI: 1,
  16845. LK: 1,
  16846. LT: 1,
  16847. LU: 1,
  16848. LV: 1,
  16849. LY: 6,
  16850. MC: 1,
  16851. MD: 1,
  16852. ME: 1,
  16853. MH: 0,
  16854. MK: 1,
  16855. MM: 0,
  16856. MN: 1,
  16857. MO: 0,
  16858. MQ: 1,
  16859. MT: 0,
  16860. MV: 5,
  16861. MX: 0,
  16862. MY: 1,
  16863. MZ: 0,
  16864. NI: 0,
  16865. NL: 1,
  16866. NO: 1,
  16867. NP: 0,
  16868. NZ: 1,
  16869. OM: 6,
  16870. PA: 0,
  16871. PE: 0,
  16872. PH: 0,
  16873. PK: 0,
  16874. PL: 1,
  16875. PR: 0,
  16876. PT: 0,
  16877. PY: 0,
  16878. QA: 6,
  16879. RE: 1,
  16880. RO: 1,
  16881. RS: 1,
  16882. RU: 1,
  16883. SA: 0,
  16884. SD: 6,
  16885. SE: 1,
  16886. SG: 0,
  16887. SI: 1,
  16888. SK: 1,
  16889. SM: 1,
  16890. SV: 0,
  16891. SY: 6,
  16892. TH: 0,
  16893. TJ: 1,
  16894. TM: 1,
  16895. TR: 1,
  16896. TT: 0,
  16897. TW: 0,
  16898. UA: 1,
  16899. UM: 0,
  16900. US: 0,
  16901. UY: 1,
  16902. UZ: 1,
  16903. VA: 1,
  16904. VE: 0,
  16905. VI: 0,
  16906. VN: 1,
  16907. WS: 0,
  16908. XK: 1,
  16909. YE: 0,
  16910. ZA: 0,
  16911. ZW: 0
  16912. };
  16913. function getWeekArray(date, locale, firstDayOfWeek) {
  16914. const weeks = [];
  16915. let currentWeek = [];
  16916. const firstDayOfMonth = startOfMonth(date);
  16917. const lastDayOfMonth = endOfMonth(date);
  16918. const first = firstDayOfWeek ?? firstDay[locale.slice(-2).toUpperCase()] ?? 0;
  16919. const firstDayWeekIndex = (firstDayOfMonth.getDay() - first + 7) % 7;
  16920. const lastDayWeekIndex = (lastDayOfMonth.getDay() - first + 7) % 7;
  16921. for (let i = 0; i < firstDayWeekIndex; i++) {
  16922. const adjacentDay = new Date(firstDayOfMonth);
  16923. adjacentDay.setDate(adjacentDay.getDate() - (firstDayWeekIndex - i));
  16924. currentWeek.push(adjacentDay);
  16925. }
  16926. for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {
  16927. const day = new Date(date.getFullYear(), date.getMonth(), i);
  16928. // Add the day to the current week
  16929. currentWeek.push(day);
  16930. // If the current week has 7 days, add it to the weeks array and start a new week
  16931. if (currentWeek.length === 7) {
  16932. weeks.push(currentWeek);
  16933. currentWeek = [];
  16934. }
  16935. }
  16936. for (let i = 1; i < 7 - lastDayWeekIndex; i++) {
  16937. const adjacentDay = new Date(lastDayOfMonth);
  16938. adjacentDay.setDate(adjacentDay.getDate() + i);
  16939. currentWeek.push(adjacentDay);
  16940. }
  16941. if (currentWeek.length > 0) {
  16942. weeks.push(currentWeek);
  16943. }
  16944. return weeks;
  16945. }
  16946. function startOfWeek(date, locale, firstDayOfWeek) {
  16947. const day = firstDayOfWeek ?? firstDay[locale.slice(-2).toUpperCase()] ?? 0;
  16948. const d = new Date(date);
  16949. while (d.getDay() !== day) {
  16950. d.setDate(d.getDate() - 1);
  16951. }
  16952. return d;
  16953. }
  16954. function endOfWeek(date, locale) {
  16955. const d = new Date(date);
  16956. const lastDay = ((firstDay[locale.slice(-2).toUpperCase()] ?? 0) + 6) % 7;
  16957. while (d.getDay() !== lastDay) {
  16958. d.setDate(d.getDate() + 1);
  16959. }
  16960. return d;
  16961. }
  16962. function startOfMonth(date) {
  16963. return new Date(date.getFullYear(), date.getMonth(), 1);
  16964. }
  16965. function endOfMonth(date) {
  16966. return new Date(date.getFullYear(), date.getMonth() + 1, 0);
  16967. }
  16968. function parseLocalDate(value) {
  16969. const parts = value.split('-').map(Number);
  16970. // new Date() uses local time zone when passing individual date component values
  16971. return new Date(parts[0], parts[1] - 1, parts[2]);
  16972. }
  16973. const _YYYMMDD = /^([12]\d{3}-([1-9]|0[1-9]|1[0-2])-([1-9]|0[1-9]|[12]\d|3[01]))$/;
  16974. function date(value) {
  16975. if (value == null) return new Date();
  16976. if (value instanceof Date) return value;
  16977. if (typeof value === 'string') {
  16978. let parsed;
  16979. if (_YYYMMDD.test(value)) {
  16980. return parseLocalDate(value);
  16981. } else {
  16982. parsed = Date.parse(value);
  16983. }
  16984. if (!isNaN(parsed)) return new Date(parsed);
  16985. }
  16986. return null;
  16987. }
  16988. const sundayJanuarySecond2000 = new Date(2000, 0, 2);
  16989. function getWeekdays(locale, firstDayOfWeek) {
  16990. const daysFromSunday = firstDayOfWeek ?? firstDay[locale.slice(-2).toUpperCase()] ?? 0;
  16991. return createRange(7).map(i => {
  16992. const weekday = new Date(sundayJanuarySecond2000);
  16993. weekday.setDate(sundayJanuarySecond2000.getDate() + daysFromSunday + i);
  16994. return new Intl.DateTimeFormat(locale, {
  16995. weekday: 'narrow'
  16996. }).format(weekday);
  16997. });
  16998. }
  16999. function format(value, formatString, locale, formats) {
  17000. const newDate = date(value) ?? new Date();
  17001. const customFormat = formats?.[formatString];
  17002. if (typeof customFormat === 'function') {
  17003. return customFormat(newDate, formatString, locale);
  17004. }
  17005. let options = {};
  17006. switch (formatString) {
  17007. case 'fullDate':
  17008. options = {
  17009. year: 'numeric',
  17010. month: 'long',
  17011. day: 'numeric'
  17012. };
  17013. break;
  17014. case 'fullDateWithWeekday':
  17015. options = {
  17016. weekday: 'long',
  17017. year: 'numeric',
  17018. month: 'long',
  17019. day: 'numeric'
  17020. };
  17021. break;
  17022. case 'normalDate':
  17023. const day = newDate.getDate();
  17024. const month = new Intl.DateTimeFormat(locale, {
  17025. month: 'long'
  17026. }).format(newDate);
  17027. return `${day} ${month}`;
  17028. case 'normalDateWithWeekday':
  17029. options = {
  17030. weekday: 'short',
  17031. day: 'numeric',
  17032. month: 'short'
  17033. };
  17034. break;
  17035. case 'shortDate':
  17036. options = {
  17037. month: 'short',
  17038. day: 'numeric'
  17039. };
  17040. break;
  17041. case 'year':
  17042. options = {
  17043. year: 'numeric'
  17044. };
  17045. break;
  17046. case 'month':
  17047. options = {
  17048. month: 'long'
  17049. };
  17050. break;
  17051. case 'monthShort':
  17052. options = {
  17053. month: 'short'
  17054. };
  17055. break;
  17056. case 'monthAndYear':
  17057. options = {
  17058. month: 'long',
  17059. year: 'numeric'
  17060. };
  17061. break;
  17062. case 'monthAndDate':
  17063. options = {
  17064. month: 'long',
  17065. day: 'numeric'
  17066. };
  17067. break;
  17068. case 'weekday':
  17069. options = {
  17070. weekday: 'long'
  17071. };
  17072. break;
  17073. case 'weekdayShort':
  17074. options = {
  17075. weekday: 'short'
  17076. };
  17077. break;
  17078. case 'dayOfMonth':
  17079. return new Intl.NumberFormat(locale).format(newDate.getDate());
  17080. case 'hours12h':
  17081. options = {
  17082. hour: 'numeric',
  17083. hour12: true
  17084. };
  17085. break;
  17086. case 'hours24h':
  17087. options = {
  17088. hour: 'numeric',
  17089. hour12: false
  17090. };
  17091. break;
  17092. case 'minutes':
  17093. options = {
  17094. minute: 'numeric'
  17095. };
  17096. break;
  17097. case 'seconds':
  17098. options = {
  17099. second: 'numeric'
  17100. };
  17101. break;
  17102. case 'fullTime':
  17103. options = {
  17104. hour: 'numeric',
  17105. minute: 'numeric',
  17106. second: 'numeric',
  17107. hour12: true
  17108. };
  17109. break;
  17110. case 'fullTime12h':
  17111. options = {
  17112. hour: 'numeric',
  17113. minute: 'numeric',
  17114. second: 'numeric',
  17115. hour12: true
  17116. };
  17117. break;
  17118. case 'fullTime24h':
  17119. options = {
  17120. hour: 'numeric',
  17121. minute: 'numeric',
  17122. second: 'numeric',
  17123. hour12: false
  17124. };
  17125. break;
  17126. case 'fullDateTime':
  17127. options = {
  17128. year: 'numeric',
  17129. month: 'long',
  17130. day: 'numeric',
  17131. hour: 'numeric',
  17132. minute: 'numeric',
  17133. second: 'numeric',
  17134. hour12: true
  17135. };
  17136. break;
  17137. case 'fullDateTime12h':
  17138. options = {
  17139. year: 'numeric',
  17140. month: 'long',
  17141. day: 'numeric',
  17142. hour: 'numeric',
  17143. minute: 'numeric',
  17144. second: 'numeric',
  17145. hour12: true
  17146. };
  17147. break;
  17148. case 'fullDateTime24h':
  17149. options = {
  17150. year: 'numeric',
  17151. month: 'long',
  17152. day: 'numeric',
  17153. hour: 'numeric',
  17154. minute: 'numeric',
  17155. second: 'numeric',
  17156. hour12: false
  17157. };
  17158. break;
  17159. case 'keyboardDate':
  17160. options = {
  17161. year: 'numeric',
  17162. month: '2-digit',
  17163. day: '2-digit'
  17164. };
  17165. break;
  17166. case 'keyboardDateTime':
  17167. options = {
  17168. year: 'numeric',
  17169. month: '2-digit',
  17170. day: '2-digit',
  17171. hour: 'numeric',
  17172. minute: 'numeric',
  17173. second: 'numeric',
  17174. hour12: false
  17175. };
  17176. break;
  17177. case 'keyboardDateTime12h':
  17178. options = {
  17179. year: 'numeric',
  17180. month: '2-digit',
  17181. day: '2-digit',
  17182. hour: 'numeric',
  17183. minute: 'numeric',
  17184. second: 'numeric',
  17185. hour12: true
  17186. };
  17187. break;
  17188. case 'keyboardDateTime24h':
  17189. options = {
  17190. year: 'numeric',
  17191. month: '2-digit',
  17192. day: '2-digit',
  17193. hour: 'numeric',
  17194. minute: 'numeric',
  17195. second: 'numeric',
  17196. hour12: false
  17197. };
  17198. break;
  17199. default:
  17200. options = customFormat ?? {
  17201. timeZone: 'UTC',
  17202. timeZoneName: 'short'
  17203. };
  17204. }
  17205. return new Intl.DateTimeFormat(locale, options).format(newDate);
  17206. }
  17207. function toISO(adapter, value) {
  17208. const date = adapter.toJsDate(value);
  17209. const year = date.getFullYear();
  17210. const month = padStart(String(date.getMonth() + 1), 2, '0');
  17211. const day = padStart(String(date.getDate()), 2, '0');
  17212. return `${year}-${month}-${day}`;
  17213. }
  17214. function parseISO(value) {
  17215. const [year, month, day] = value.split('-').map(Number);
  17216. return new Date(year, month - 1, day);
  17217. }
  17218. function addMinutes(date, amount) {
  17219. const d = new Date(date);
  17220. d.setMinutes(d.getMinutes() + amount);
  17221. return d;
  17222. }
  17223. function addHours(date, amount) {
  17224. const d = new Date(date);
  17225. d.setHours(d.getHours() + amount);
  17226. return d;
  17227. }
  17228. function addDays(date, amount) {
  17229. const d = new Date(date);
  17230. d.setDate(d.getDate() + amount);
  17231. return d;
  17232. }
  17233. function addWeeks(date, amount) {
  17234. const d = new Date(date);
  17235. d.setDate(d.getDate() + amount * 7);
  17236. return d;
  17237. }
  17238. function addMonths(date, amount) {
  17239. const d = new Date(date);
  17240. d.setDate(1);
  17241. d.setMonth(d.getMonth() + amount);
  17242. return d;
  17243. }
  17244. function getYear(date) {
  17245. return date.getFullYear();
  17246. }
  17247. function getMonth(date) {
  17248. return date.getMonth();
  17249. }
  17250. function getDate(date) {
  17251. return date.getDate();
  17252. }
  17253. function getNextMonth(date) {
  17254. return new Date(date.getFullYear(), date.getMonth() + 1, 1);
  17255. }
  17256. function getPreviousMonth(date) {
  17257. return new Date(date.getFullYear(), date.getMonth() - 1, 1);
  17258. }
  17259. function getHours(date) {
  17260. return date.getHours();
  17261. }
  17262. function getMinutes(date) {
  17263. return date.getMinutes();
  17264. }
  17265. function startOfYear(date) {
  17266. return new Date(date.getFullYear(), 0, 1);
  17267. }
  17268. function endOfYear(date) {
  17269. return new Date(date.getFullYear(), 11, 31);
  17270. }
  17271. function isWithinRange(date, range) {
  17272. return isAfter(date, range[0]) && isBefore(date, range[1]);
  17273. }
  17274. function isValid(date) {
  17275. const d = new Date(date);
  17276. return d instanceof Date && !isNaN(d.getTime());
  17277. }
  17278. function isAfter(date, comparing) {
  17279. return date.getTime() > comparing.getTime();
  17280. }
  17281. function isAfterDay(date, comparing) {
  17282. return isAfter(startOfDay(date), startOfDay(comparing));
  17283. }
  17284. function isBefore(date, comparing) {
  17285. return date.getTime() < comparing.getTime();
  17286. }
  17287. function isEqual(date, comparing) {
  17288. return date.getTime() === comparing.getTime();
  17289. }
  17290. function isSameDay(date, comparing) {
  17291. return date.getDate() === comparing.getDate() && date.getMonth() === comparing.getMonth() && date.getFullYear() === comparing.getFullYear();
  17292. }
  17293. function isSameMonth(date, comparing) {
  17294. return date.getMonth() === comparing.getMonth() && date.getFullYear() === comparing.getFullYear();
  17295. }
  17296. function isSameYear(date, comparing) {
  17297. return date.getFullYear() === comparing.getFullYear();
  17298. }
  17299. function getDiff(date, comparing, unit) {
  17300. const d = new Date(date);
  17301. const c = new Date(comparing);
  17302. switch (unit) {
  17303. case 'years':
  17304. return d.getFullYear() - c.getFullYear();
  17305. case 'quarters':
  17306. return Math.floor((d.getMonth() - c.getMonth() + (d.getFullYear() - c.getFullYear()) * 12) / 4);
  17307. case 'months':
  17308. return d.getMonth() - c.getMonth() + (d.getFullYear() - c.getFullYear()) * 12;
  17309. case 'weeks':
  17310. return Math.floor((d.getTime() - c.getTime()) / (1000 * 60 * 60 * 24 * 7));
  17311. case 'days':
  17312. return Math.floor((d.getTime() - c.getTime()) / (1000 * 60 * 60 * 24));
  17313. case 'hours':
  17314. return Math.floor((d.getTime() - c.getTime()) / (1000 * 60 * 60));
  17315. case 'minutes':
  17316. return Math.floor((d.getTime() - c.getTime()) / (1000 * 60));
  17317. case 'seconds':
  17318. return Math.floor((d.getTime() - c.getTime()) / 1000);
  17319. default:
  17320. {
  17321. return d.getTime() - c.getTime();
  17322. }
  17323. }
  17324. }
  17325. function setHours(date, count) {
  17326. const d = new Date(date);
  17327. d.setHours(count);
  17328. return d;
  17329. }
  17330. function setMinutes(date, count) {
  17331. const d = new Date(date);
  17332. d.setMinutes(count);
  17333. return d;
  17334. }
  17335. function setMonth(date, count) {
  17336. const d = new Date(date);
  17337. d.setMonth(count);
  17338. return d;
  17339. }
  17340. function setDate(date, day) {
  17341. const d = new Date(date);
  17342. d.setDate(day);
  17343. return d;
  17344. }
  17345. function setYear(date, year) {
  17346. const d = new Date(date);
  17347. d.setFullYear(year);
  17348. return d;
  17349. }
  17350. function startOfDay(date) {
  17351. return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0);
  17352. }
  17353. function endOfDay(date) {
  17354. return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999);
  17355. }
  17356. class VuetifyDateAdapter {
  17357. constructor(options) {
  17358. this.locale = options.locale;
  17359. this.formats = options.formats;
  17360. }
  17361. date(value) {
  17362. return date(value);
  17363. }
  17364. toJsDate(date) {
  17365. return date;
  17366. }
  17367. toISO(date) {
  17368. return toISO(this, date);
  17369. }
  17370. parseISO(date) {
  17371. return parseISO(date);
  17372. }
  17373. addMinutes(date, amount) {
  17374. return addMinutes(date, amount);
  17375. }
  17376. addHours(date, amount) {
  17377. return addHours(date, amount);
  17378. }
  17379. addDays(date, amount) {
  17380. return addDays(date, amount);
  17381. }
  17382. addWeeks(date, amount) {
  17383. return addWeeks(date, amount);
  17384. }
  17385. addMonths(date, amount) {
  17386. return addMonths(date, amount);
  17387. }
  17388. getWeekArray(date, firstDayOfWeek) {
  17389. return getWeekArray(date, this.locale, firstDayOfWeek ? Number(firstDayOfWeek) : undefined);
  17390. }
  17391. startOfWeek(date, firstDayOfWeek) {
  17392. return startOfWeek(date, this.locale, firstDayOfWeek ? Number(firstDayOfWeek) : undefined);
  17393. }
  17394. endOfWeek(date) {
  17395. return endOfWeek(date, this.locale);
  17396. }
  17397. startOfMonth(date) {
  17398. return startOfMonth(date);
  17399. }
  17400. endOfMonth(date) {
  17401. return endOfMonth(date);
  17402. }
  17403. format(date, formatString) {
  17404. return format(date, formatString, this.locale, this.formats);
  17405. }
  17406. isEqual(date, comparing) {
  17407. return isEqual(date, comparing);
  17408. }
  17409. isValid(date) {
  17410. return isValid(date);
  17411. }
  17412. isWithinRange(date, range) {
  17413. return isWithinRange(date, range);
  17414. }
  17415. isAfter(date, comparing) {
  17416. return isAfter(date, comparing);
  17417. }
  17418. isAfterDay(date, comparing) {
  17419. return isAfterDay(date, comparing);
  17420. }
  17421. isBefore(date, comparing) {
  17422. return !isAfter(date, comparing) && !isEqual(date, comparing);
  17423. }
  17424. isSameDay(date, comparing) {
  17425. return isSameDay(date, comparing);
  17426. }
  17427. isSameMonth(date, comparing) {
  17428. return isSameMonth(date, comparing);
  17429. }
  17430. isSameYear(date, comparing) {
  17431. return isSameYear(date, comparing);
  17432. }
  17433. setMinutes(date, count) {
  17434. return setMinutes(date, count);
  17435. }
  17436. setHours(date, count) {
  17437. return setHours(date, count);
  17438. }
  17439. setMonth(date, count) {
  17440. return setMonth(date, count);
  17441. }
  17442. setDate(date, day) {
  17443. return setDate(date, day);
  17444. }
  17445. setYear(date, year) {
  17446. return setYear(date, year);
  17447. }
  17448. getDiff(date, comparing, unit) {
  17449. return getDiff(date, comparing, unit);
  17450. }
  17451. getWeekdays(firstDayOfWeek) {
  17452. return getWeekdays(this.locale, firstDayOfWeek ? Number(firstDayOfWeek) : undefined);
  17453. }
  17454. getYear(date) {
  17455. return getYear(date);
  17456. }
  17457. getMonth(date) {
  17458. return getMonth(date);
  17459. }
  17460. getDate(date) {
  17461. return getDate(date);
  17462. }
  17463. getNextMonth(date) {
  17464. return getNextMonth(date);
  17465. }
  17466. getPreviousMonth(date) {
  17467. return getPreviousMonth(date);
  17468. }
  17469. getHours(date) {
  17470. return getHours(date);
  17471. }
  17472. getMinutes(date) {
  17473. return getMinutes(date);
  17474. }
  17475. startOfDay(date) {
  17476. return startOfDay(date);
  17477. }
  17478. endOfDay(date) {
  17479. return endOfDay(date);
  17480. }
  17481. startOfYear(date) {
  17482. return startOfYear(date);
  17483. }
  17484. endOfYear(date) {
  17485. return endOfYear(date);
  17486. }
  17487. }
  17488. // Composables
  17489. const DateOptionsSymbol = Symbol.for('vuetify:date-options');
  17490. const DateAdapterSymbol = Symbol.for('vuetify:date-adapter');
  17491. function createDate(options, locale) {
  17492. const _options = mergeDeep({
  17493. adapter: VuetifyDateAdapter,
  17494. locale: {
  17495. af: 'af-ZA',
  17496. // ar: '', # not the same value for all variants
  17497. bg: 'bg-BG',
  17498. ca: 'ca-ES',
  17499. ckb: '',
  17500. cs: 'cs-CZ',
  17501. de: 'de-DE',
  17502. el: 'el-GR',
  17503. en: 'en-US',
  17504. // es: '', # not the same value for all variants
  17505. et: 'et-EE',
  17506. fa: 'fa-IR',
  17507. fi: 'fi-FI',
  17508. // fr: '', #not the same value for all variants
  17509. hr: 'hr-HR',
  17510. hu: 'hu-HU',
  17511. he: 'he-IL',
  17512. id: 'id-ID',
  17513. it: 'it-IT',
  17514. ja: 'ja-JP',
  17515. ko: 'ko-KR',
  17516. lv: 'lv-LV',
  17517. lt: 'lt-LT',
  17518. nl: 'nl-NL',
  17519. no: 'no-NO',
  17520. pl: 'pl-PL',
  17521. pt: 'pt-PT',
  17522. ro: 'ro-RO',
  17523. ru: 'ru-RU',
  17524. sk: 'sk-SK',
  17525. sl: 'sl-SI',
  17526. srCyrl: 'sr-SP',
  17527. srLatn: 'sr-SP',
  17528. sv: 'sv-SE',
  17529. th: 'th-TH',
  17530. tr: 'tr-TR',
  17531. az: 'az-AZ',
  17532. uk: 'uk-UA',
  17533. vi: 'vi-VN',
  17534. zhHans: 'zh-CN',
  17535. zhHant: 'zh-TW'
  17536. }
  17537. }, options);
  17538. return {
  17539. options: _options,
  17540. instance: createInstance(_options, locale)
  17541. };
  17542. }
  17543. function createInstance(options, locale) {
  17544. const instance = reactive(typeof options.adapter === 'function'
  17545. // eslint-disable-next-line new-cap
  17546. ? new options.adapter({
  17547. locale: options.locale[locale.current.value] ?? locale.current.value,
  17548. formats: options.formats
  17549. }) : options.adapter);
  17550. watch(locale.current, value => {
  17551. instance.locale = options.locale[value] ?? value ?? instance.locale;
  17552. });
  17553. return instance;
  17554. }
  17555. function useDate() {
  17556. const options = inject$1(DateOptionsSymbol);
  17557. if (!options) throw new Error('[Vuetify] Could not find injected date options');
  17558. const locale = useLocale();
  17559. return createInstance(options, locale);
  17560. }
  17561. // https://stackoverflow.com/questions/274861/how-do-i-calculate-the-week-number-given-a-date/275024#275024
  17562. function getWeek(adapter, value) {
  17563. const date = adapter.toJsDate(value);
  17564. let year = date.getFullYear();
  17565. let d1w1 = new Date(year, 0, 1);
  17566. if (date < d1w1) {
  17567. year = year - 1;
  17568. d1w1 = new Date(year, 0, 1);
  17569. } else {
  17570. const tv = new Date(year + 1, 0, 1);
  17571. if (date >= tv) {
  17572. year = year + 1;
  17573. d1w1 = tv;
  17574. }
  17575. }
  17576. const diffTime = Math.abs(date.getTime() - d1w1.getTime());
  17577. const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
  17578. return Math.floor(diffDays / 7) + 1;
  17579. }
  17580. // Types
  17581. const makeVConfirmEditProps = propsFactory({
  17582. modelValue: null,
  17583. color: String,
  17584. cancelText: {
  17585. type: String,
  17586. default: '$vuetify.confirmEdit.cancel'
  17587. },
  17588. okText: {
  17589. type: String,
  17590. default: '$vuetify.confirmEdit.ok'
  17591. }
  17592. }, 'VConfirmEdit');
  17593. const VConfirmEdit = genericComponent()({
  17594. name: 'VConfirmEdit',
  17595. props: makeVConfirmEditProps(),
  17596. emits: {
  17597. cancel: () => true,
  17598. save: value => true,
  17599. 'update:modelValue': value => true
  17600. },
  17601. setup(props, _ref) {
  17602. let {
  17603. emit,
  17604. slots
  17605. } = _ref;
  17606. const model = useProxiedModel(props, 'modelValue');
  17607. const internalModel = ref();
  17608. watchEffect(() => {
  17609. internalModel.value = structuredClone(toRaw(model.value));
  17610. });
  17611. const {
  17612. t
  17613. } = useLocale();
  17614. const isPristine = computed(() => {
  17615. return deepEqual(model.value, internalModel.value);
  17616. });
  17617. function save() {
  17618. model.value = internalModel.value;
  17619. emit('save', internalModel.value);
  17620. }
  17621. function cancel() {
  17622. internalModel.value = structuredClone(toRaw(model.value));
  17623. emit('cancel');
  17624. }
  17625. function actions(actionsProps) {
  17626. return createVNode(Fragment, null, [createVNode(VBtn, mergeProps({
  17627. "disabled": isPristine.value,
  17628. "variant": "text",
  17629. "color": props.color,
  17630. "onClick": cancel,
  17631. "text": t(props.cancelText)
  17632. }, actionsProps), null), createVNode(VBtn, mergeProps({
  17633. "disabled": isPristine.value,
  17634. "variant": "text",
  17635. "color": props.color,
  17636. "onClick": save,
  17637. "text": t(props.okText)
  17638. }, actionsProps), null)]);
  17639. }
  17640. let actionsUsed = false;
  17641. useRender(() => {
  17642. return createVNode(Fragment, null, [slots.default?.({
  17643. model: internalModel,
  17644. save,
  17645. cancel,
  17646. isPristine: isPristine.value,
  17647. get actions() {
  17648. actionsUsed = true;
  17649. return actions;
  17650. }
  17651. }), !actionsUsed && actions()]);
  17652. });
  17653. return {
  17654. save,
  17655. cancel,
  17656. isPristine
  17657. };
  17658. }
  17659. });
  17660. // Composables
  17661. // Types
  17662. const makeDataTableExpandProps = propsFactory({
  17663. expandOnClick: Boolean,
  17664. showExpand: Boolean,
  17665. expanded: {
  17666. type: Array,
  17667. default: () => []
  17668. }
  17669. }, 'DataTable-expand');
  17670. const VDataTableExpandedKey = Symbol.for('vuetify:datatable:expanded');
  17671. function provideExpanded(props) {
  17672. const expandOnClick = toRef(props, 'expandOnClick');
  17673. const expanded = useProxiedModel(props, 'expanded', props.expanded, v => {
  17674. return new Set(v);
  17675. }, v => {
  17676. return [...v.values()];
  17677. });
  17678. function expand(item, value) {
  17679. const newExpanded = new Set(expanded.value);
  17680. if (!value) {
  17681. newExpanded.delete(item.value);
  17682. } else {
  17683. newExpanded.add(item.value);
  17684. }
  17685. expanded.value = newExpanded;
  17686. }
  17687. function isExpanded(item) {
  17688. return expanded.value.has(item.value);
  17689. }
  17690. function toggleExpand(item) {
  17691. expand(item, !isExpanded(item));
  17692. }
  17693. const data = {
  17694. expand,
  17695. expanded,
  17696. expandOnClick,
  17697. isExpanded,
  17698. toggleExpand
  17699. };
  17700. provide(VDataTableExpandedKey, data);
  17701. return data;
  17702. }
  17703. function useExpanded() {
  17704. const data = inject$1(VDataTableExpandedKey);
  17705. if (!data) throw new Error('foo');
  17706. return data;
  17707. }
  17708. // Composables
  17709. // Types
  17710. const makeDataTableGroupProps = propsFactory({
  17711. groupBy: {
  17712. type: Array,
  17713. default: () => []
  17714. }
  17715. }, 'DataTable-group');
  17716. const VDataTableGroupSymbol = Symbol.for('vuetify:data-table-group');
  17717. function createGroupBy(props) {
  17718. const groupBy = useProxiedModel(props, 'groupBy');
  17719. return {
  17720. groupBy
  17721. };
  17722. }
  17723. function provideGroupBy(options) {
  17724. const {
  17725. disableSort,
  17726. groupBy,
  17727. sortBy
  17728. } = options;
  17729. const opened = ref(new Set());
  17730. const sortByWithGroups = computed(() => {
  17731. return groupBy.value.map(val => ({
  17732. ...val,
  17733. order: val.order ?? false
  17734. })).concat(disableSort?.value ? [] : sortBy.value);
  17735. });
  17736. function isGroupOpen(group) {
  17737. return opened.value.has(group.id);
  17738. }
  17739. function toggleGroup(group) {
  17740. const newOpened = new Set(opened.value);
  17741. if (!isGroupOpen(group)) newOpened.add(group.id);else newOpened.delete(group.id);
  17742. opened.value = newOpened;
  17743. }
  17744. function extractRows(items) {
  17745. function dive(group) {
  17746. const arr = [];
  17747. for (const item of group.items) {
  17748. if ('type' in item && item.type === 'group') {
  17749. arr.push(...dive(item));
  17750. } else {
  17751. arr.push(item);
  17752. }
  17753. }
  17754. return arr;
  17755. }
  17756. return dive({
  17757. type: 'group',
  17758. items,
  17759. id: 'dummy',
  17760. key: 'dummy',
  17761. value: 'dummy',
  17762. depth: 0
  17763. });
  17764. }
  17765. // onBeforeMount(() => {
  17766. // for (const key of groupedItems.value.keys()) {
  17767. // opened.value.add(key)
  17768. // }
  17769. // })
  17770. const data = {
  17771. sortByWithGroups,
  17772. toggleGroup,
  17773. opened,
  17774. groupBy,
  17775. extractRows,
  17776. isGroupOpen
  17777. };
  17778. provide(VDataTableGroupSymbol, data);
  17779. return data;
  17780. }
  17781. function useGroupBy() {
  17782. const data = inject$1(VDataTableGroupSymbol);
  17783. if (!data) throw new Error('Missing group!');
  17784. return data;
  17785. }
  17786. function groupItemsByProperty(items, groupBy) {
  17787. if (!items.length) return [];
  17788. const groups = new Map();
  17789. for (const item of items) {
  17790. const value = getObjectValueByPath(item.raw, groupBy);
  17791. if (!groups.has(value)) {
  17792. groups.set(value, []);
  17793. }
  17794. groups.get(value).push(item);
  17795. }
  17796. return groups;
  17797. }
  17798. function groupItems(items, groupBy) {
  17799. let depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
  17800. let prefix = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'root';
  17801. if (!groupBy.length) return [];
  17802. const groupedItems = groupItemsByProperty(items, groupBy[0]);
  17803. const groups = [];
  17804. const rest = groupBy.slice(1);
  17805. groupedItems.forEach((items, value) => {
  17806. const key = groupBy[0];
  17807. const id = `${prefix}_${key}_${value}`;
  17808. groups.push({
  17809. depth,
  17810. id,
  17811. key,
  17812. value,
  17813. items: rest.length ? groupItems(items, rest, depth + 1, id) : items,
  17814. type: 'group'
  17815. });
  17816. });
  17817. return groups;
  17818. }
  17819. function flattenItems(items, opened) {
  17820. const flatItems = [];
  17821. for (const item of items) {
  17822. // TODO: make this better
  17823. if ('type' in item && item.type === 'group') {
  17824. if (item.value != null) {
  17825. flatItems.push(item);
  17826. }
  17827. if (opened.has(item.id) || item.value == null) {
  17828. flatItems.push(...flattenItems(item.items, opened));
  17829. }
  17830. } else {
  17831. flatItems.push(item);
  17832. }
  17833. }
  17834. return flatItems;
  17835. }
  17836. function useGroupedItems(items, groupBy, opened) {
  17837. const flatItems = computed(() => {
  17838. if (!groupBy.value.length) return items.value;
  17839. const groupedItems = groupItems(items.value, groupBy.value.map(item => item.key));
  17840. return flattenItems(groupedItems, opened.value);
  17841. });
  17842. return {
  17843. flatItems
  17844. };
  17845. }
  17846. // Utilities
  17847. // Types
  17848. function useOptions(_ref) {
  17849. let {
  17850. page,
  17851. itemsPerPage,
  17852. sortBy,
  17853. groupBy,
  17854. search
  17855. } = _ref;
  17856. const vm = getCurrentInstance('VDataTable');
  17857. const options = computed(() => ({
  17858. page: page.value,
  17859. itemsPerPage: itemsPerPage.value,
  17860. sortBy: sortBy.value,
  17861. groupBy: groupBy.value,
  17862. search: search.value
  17863. }));
  17864. let oldOptions = null;
  17865. watch(options, () => {
  17866. if (deepEqual(oldOptions, options.value)) return;
  17867. // Reset page when searching
  17868. if (oldOptions && oldOptions.search !== options.value.search) {
  17869. page.value = 1;
  17870. }
  17871. vm.emit('update:options', options.value);
  17872. oldOptions = options.value;
  17873. }, {
  17874. deep: true,
  17875. immediate: true
  17876. });
  17877. }
  17878. // Composables
  17879. // Types
  17880. const makeDataTablePaginateProps = propsFactory({
  17881. page: {
  17882. type: [Number, String],
  17883. default: 1
  17884. },
  17885. itemsPerPage: {
  17886. type: [Number, String],
  17887. default: 10
  17888. }
  17889. }, 'DataTable-paginate');
  17890. const VDataTablePaginationSymbol = Symbol.for('vuetify:data-table-pagination');
  17891. function createPagination(props) {
  17892. const page = useProxiedModel(props, 'page', undefined, value => +(value ?? 1));
  17893. const itemsPerPage = useProxiedModel(props, 'itemsPerPage', undefined, value => +(value ?? 10));
  17894. return {
  17895. page,
  17896. itemsPerPage
  17897. };
  17898. }
  17899. function providePagination(options) {
  17900. const {
  17901. page,
  17902. itemsPerPage,
  17903. itemsLength
  17904. } = options;
  17905. const startIndex = computed(() => {
  17906. if (itemsPerPage.value === -1) return 0;
  17907. return itemsPerPage.value * (page.value - 1);
  17908. });
  17909. const stopIndex = computed(() => {
  17910. if (itemsPerPage.value === -1) return itemsLength.value;
  17911. return Math.min(itemsLength.value, startIndex.value + itemsPerPage.value);
  17912. });
  17913. const pageCount = computed(() => {
  17914. if (itemsPerPage.value === -1 || itemsLength.value === 0) return 1;
  17915. return Math.ceil(itemsLength.value / itemsPerPage.value);
  17916. });
  17917. // Don't run immediately, items may not have been loaded yet: #17966
  17918. watch([page, pageCount], () => {
  17919. if (page.value > pageCount.value) {
  17920. page.value = pageCount.value;
  17921. }
  17922. });
  17923. function setItemsPerPage(value) {
  17924. itemsPerPage.value = value;
  17925. page.value = 1;
  17926. }
  17927. function nextPage() {
  17928. page.value = clamp(page.value + 1, 1, pageCount.value);
  17929. }
  17930. function prevPage() {
  17931. page.value = clamp(page.value - 1, 1, pageCount.value);
  17932. }
  17933. function setPage(value) {
  17934. page.value = clamp(value, 1, pageCount.value);
  17935. }
  17936. const data = {
  17937. page,
  17938. itemsPerPage,
  17939. startIndex,
  17940. stopIndex,
  17941. pageCount,
  17942. itemsLength,
  17943. nextPage,
  17944. prevPage,
  17945. setPage,
  17946. setItemsPerPage
  17947. };
  17948. provide(VDataTablePaginationSymbol, data);
  17949. return data;
  17950. }
  17951. function usePagination() {
  17952. const data = inject$1(VDataTablePaginationSymbol);
  17953. if (!data) throw new Error('Missing pagination!');
  17954. return data;
  17955. }
  17956. function usePaginatedItems(options) {
  17957. const vm = getCurrentInstance('usePaginatedItems');
  17958. const {
  17959. items,
  17960. startIndex,
  17961. stopIndex,
  17962. itemsPerPage
  17963. } = options;
  17964. const paginatedItems = computed(() => {
  17965. if (itemsPerPage.value <= 0) return items.value;
  17966. return items.value.slice(startIndex.value, stopIndex.value);
  17967. });
  17968. watch(paginatedItems, val => {
  17969. vm.emit('update:currentItems', val);
  17970. });
  17971. return {
  17972. paginatedItems
  17973. };
  17974. }
  17975. // Composables
  17976. // Types
  17977. const singleSelectStrategy = {
  17978. showSelectAll: false,
  17979. allSelected: () => [],
  17980. select: _ref => {
  17981. let {
  17982. items,
  17983. value
  17984. } = _ref;
  17985. return new Set(value ? [items[0]?.value] : []);
  17986. },
  17987. selectAll: _ref2 => {
  17988. let {
  17989. selected
  17990. } = _ref2;
  17991. return selected;
  17992. }
  17993. };
  17994. const pageSelectStrategy = {
  17995. showSelectAll: true,
  17996. allSelected: _ref3 => {
  17997. let {
  17998. currentPage
  17999. } = _ref3;
  18000. return currentPage;
  18001. },
  18002. select: _ref4 => {
  18003. let {
  18004. items,
  18005. value,
  18006. selected
  18007. } = _ref4;
  18008. for (const item of items) {
  18009. if (value) selected.add(item.value);else selected.delete(item.value);
  18010. }
  18011. return selected;
  18012. },
  18013. selectAll: _ref5 => {
  18014. let {
  18015. value,
  18016. currentPage,
  18017. selected
  18018. } = _ref5;
  18019. return pageSelectStrategy.select({
  18020. items: currentPage,
  18021. value,
  18022. selected
  18023. });
  18024. }
  18025. };
  18026. const allSelectStrategy = {
  18027. showSelectAll: true,
  18028. allSelected: _ref6 => {
  18029. let {
  18030. allItems
  18031. } = _ref6;
  18032. return allItems;
  18033. },
  18034. select: _ref7 => {
  18035. let {
  18036. items,
  18037. value,
  18038. selected
  18039. } = _ref7;
  18040. for (const item of items) {
  18041. if (value) selected.add(item.value);else selected.delete(item.value);
  18042. }
  18043. return selected;
  18044. },
  18045. selectAll: _ref8 => {
  18046. let {
  18047. value,
  18048. allItems,
  18049. selected
  18050. } = _ref8;
  18051. return allSelectStrategy.select({
  18052. items: allItems,
  18053. value,
  18054. selected
  18055. });
  18056. }
  18057. };
  18058. const makeDataTableSelectProps = propsFactory({
  18059. showSelect: Boolean,
  18060. selectStrategy: {
  18061. type: [String, Object],
  18062. default: 'page'
  18063. },
  18064. modelValue: {
  18065. type: Array,
  18066. default: () => []
  18067. },
  18068. valueComparator: {
  18069. type: Function,
  18070. default: deepEqual
  18071. }
  18072. }, 'DataTable-select');
  18073. const VDataTableSelectionSymbol = Symbol.for('vuetify:data-table-selection');
  18074. function provideSelection(props, _ref9) {
  18075. let {
  18076. allItems,
  18077. currentPage
  18078. } = _ref9;
  18079. const selected = useProxiedModel(props, 'modelValue', props.modelValue, v => {
  18080. return new Set(wrapInArray(v).map(v => {
  18081. return allItems.value.find(item => props.valueComparator(v, item.value))?.value ?? v;
  18082. }));
  18083. }, v => {
  18084. return [...v.values()];
  18085. });
  18086. const allSelectable = computed(() => allItems.value.filter(item => item.selectable));
  18087. const currentPageSelectable = computed(() => currentPage.value.filter(item => item.selectable));
  18088. const selectStrategy = computed(() => {
  18089. if (typeof props.selectStrategy === 'object') return props.selectStrategy;
  18090. switch (props.selectStrategy) {
  18091. case 'single':
  18092. return singleSelectStrategy;
  18093. case 'all':
  18094. return allSelectStrategy;
  18095. case 'page':
  18096. default:
  18097. return pageSelectStrategy;
  18098. }
  18099. });
  18100. function isSelected(items) {
  18101. return wrapInArray(items).every(item => selected.value.has(item.value));
  18102. }
  18103. function isSomeSelected(items) {
  18104. return wrapInArray(items).some(item => selected.value.has(item.value));
  18105. }
  18106. function select(items, value) {
  18107. const newSelected = selectStrategy.value.select({
  18108. items,
  18109. value,
  18110. selected: new Set(selected.value)
  18111. });
  18112. selected.value = newSelected;
  18113. }
  18114. function toggleSelect(item) {
  18115. select([item], !isSelected([item]));
  18116. }
  18117. function selectAll(value) {
  18118. const newSelected = selectStrategy.value.selectAll({
  18119. value,
  18120. allItems: allSelectable.value,
  18121. currentPage: currentPageSelectable.value,
  18122. selected: new Set(selected.value)
  18123. });
  18124. selected.value = newSelected;
  18125. }
  18126. const someSelected = computed(() => selected.value.size > 0);
  18127. const allSelected = computed(() => {
  18128. const items = selectStrategy.value.allSelected({
  18129. allItems: allSelectable.value,
  18130. currentPage: currentPageSelectable.value
  18131. });
  18132. return !!items.length && isSelected(items);
  18133. });
  18134. const showSelectAll = computed(() => selectStrategy.value.showSelectAll);
  18135. const data = {
  18136. toggleSelect,
  18137. select,
  18138. selectAll,
  18139. isSelected,
  18140. isSomeSelected,
  18141. someSelected,
  18142. allSelected,
  18143. showSelectAll
  18144. };
  18145. provide(VDataTableSelectionSymbol, data);
  18146. return data;
  18147. }
  18148. function useSelection() {
  18149. const data = inject$1(VDataTableSelectionSymbol);
  18150. if (!data) throw new Error('Missing selection!');
  18151. return data;
  18152. }
  18153. // Composables
  18154. // Types
  18155. const makeDataTableSortProps = propsFactory({
  18156. sortBy: {
  18157. type: Array,
  18158. default: () => []
  18159. },
  18160. customKeySort: Object,
  18161. multiSort: Boolean,
  18162. mustSort: Boolean
  18163. }, 'DataTable-sort');
  18164. const VDataTableSortSymbol = Symbol.for('vuetify:data-table-sort');
  18165. function createSort(props) {
  18166. const sortBy = useProxiedModel(props, 'sortBy');
  18167. const mustSort = toRef(props, 'mustSort');
  18168. const multiSort = toRef(props, 'multiSort');
  18169. return {
  18170. sortBy,
  18171. mustSort,
  18172. multiSort
  18173. };
  18174. }
  18175. function provideSort(options) {
  18176. const {
  18177. sortBy,
  18178. mustSort,
  18179. multiSort,
  18180. page
  18181. } = options;
  18182. const toggleSort = column => {
  18183. if (column.key == null) return;
  18184. let newSortBy = sortBy.value.map(x => ({
  18185. ...x
  18186. })) ?? [];
  18187. const item = newSortBy.find(x => x.key === column.key);
  18188. if (!item) {
  18189. if (multiSort.value) newSortBy = [...newSortBy, {
  18190. key: column.key,
  18191. order: 'asc'
  18192. }];else newSortBy = [{
  18193. key: column.key,
  18194. order: 'asc'
  18195. }];
  18196. } else if (item.order === 'desc') {
  18197. if (mustSort.value) {
  18198. item.order = 'asc';
  18199. } else {
  18200. newSortBy = newSortBy.filter(x => x.key !== column.key);
  18201. }
  18202. } else {
  18203. item.order = 'desc';
  18204. }
  18205. sortBy.value = newSortBy;
  18206. if (page) page.value = 1;
  18207. };
  18208. function isSorted(column) {
  18209. return !!sortBy.value.find(item => item.key === column.key);
  18210. }
  18211. const data = {
  18212. sortBy,
  18213. toggleSort,
  18214. isSorted
  18215. };
  18216. provide(VDataTableSortSymbol, data);
  18217. return data;
  18218. }
  18219. function useSort() {
  18220. const data = inject$1(VDataTableSortSymbol);
  18221. if (!data) throw new Error('Missing sort!');
  18222. return data;
  18223. }
  18224. // TODO: abstract into project composable
  18225. function useSortedItems(props, items, sortBy, options) {
  18226. const locale = useLocale();
  18227. const sortedItems = computed(() => {
  18228. if (!sortBy.value.length) return items.value;
  18229. return sortItems(items.value, sortBy.value, locale.current.value, {
  18230. transform: options?.transform,
  18231. sortFunctions: {
  18232. ...props.customKeySort,
  18233. ...options?.sortFunctions?.value
  18234. },
  18235. sortRawFunctions: options?.sortRawFunctions?.value
  18236. });
  18237. });
  18238. return {
  18239. sortedItems
  18240. };
  18241. }
  18242. function sortItems(items, sortByItems, locale, options) {
  18243. const stringCollator = new Intl.Collator(locale, {
  18244. sensitivity: 'accent',
  18245. usage: 'sort'
  18246. });
  18247. const transformedItems = items.map(item => [item, options?.transform ? options.transform(item) : item]);
  18248. return transformedItems.sort((a, b) => {
  18249. for (let i = 0; i < sortByItems.length; i++) {
  18250. let hasCustomResult = false;
  18251. const sortKey = sortByItems[i].key;
  18252. const sortOrder = sortByItems[i].order ?? 'asc';
  18253. if (sortOrder === false) continue;
  18254. let sortA = getObjectValueByPath(a[1], sortKey);
  18255. let sortB = getObjectValueByPath(b[1], sortKey);
  18256. let sortARaw = a[0].raw;
  18257. let sortBRaw = b[0].raw;
  18258. if (sortOrder === 'desc') {
  18259. [sortA, sortB] = [sortB, sortA];
  18260. [sortARaw, sortBRaw] = [sortBRaw, sortARaw];
  18261. }
  18262. if (options?.sortRawFunctions?.[sortKey]) {
  18263. const customResult = options.sortRawFunctions[sortKey](sortARaw, sortBRaw);
  18264. if (customResult == null) continue;
  18265. hasCustomResult = true;
  18266. if (customResult) return customResult;
  18267. }
  18268. if (options?.sortFunctions?.[sortKey]) {
  18269. const customResult = options.sortFunctions[sortKey](sortA, sortB);
  18270. if (customResult == null) continue;
  18271. hasCustomResult = true;
  18272. if (customResult) return customResult;
  18273. }
  18274. if (hasCustomResult) continue;
  18275. // Dates should be compared numerically
  18276. if (sortA instanceof Date && sortB instanceof Date) {
  18277. return sortA.getTime() - sortB.getTime();
  18278. }
  18279. [sortA, sortB] = [sortA, sortB].map(s => s != null ? s.toString().toLocaleLowerCase() : s);
  18280. if (sortA !== sortB) {
  18281. if (isEmpty(sortA) && isEmpty(sortB)) return 0;
  18282. if (isEmpty(sortA)) return -1;
  18283. if (isEmpty(sortB)) return 1;
  18284. if (!isNaN(sortA) && !isNaN(sortB)) return Number(sortA) - Number(sortB);
  18285. return stringCollator.compare(sortA, sortB);
  18286. }
  18287. }
  18288. return 0;
  18289. }).map(_ref => {
  18290. let [item] = _ref;
  18291. return item;
  18292. });
  18293. }
  18294. // Utilities
  18295. // Types
  18296. // Composables
  18297. const makeDataIteratorItemsProps = propsFactory({
  18298. items: {
  18299. type: Array,
  18300. default: () => []
  18301. },
  18302. itemValue: {
  18303. type: [String, Array, Function],
  18304. default: 'id'
  18305. },
  18306. itemSelectable: {
  18307. type: [String, Array, Function],
  18308. default: null
  18309. },
  18310. returnObject: Boolean
  18311. }, 'DataIterator-items');
  18312. function transformItem$1(props, item) {
  18313. const value = props.returnObject ? item : getPropertyFromItem(item, props.itemValue);
  18314. const selectable = getPropertyFromItem(item, props.itemSelectable, true);
  18315. return {
  18316. type: 'item',
  18317. value,
  18318. selectable,
  18319. raw: item
  18320. };
  18321. }
  18322. function transformItems$1(props, items) {
  18323. const array = [];
  18324. for (const item of items) {
  18325. array.push(transformItem$1(props, item));
  18326. }
  18327. return array;
  18328. }
  18329. function useDataIteratorItems(props) {
  18330. const items = computed(() => transformItems$1(props, props.items));
  18331. return {
  18332. items
  18333. };
  18334. }
  18335. // Types
  18336. const makeVDataIteratorProps = propsFactory({
  18337. search: String,
  18338. loading: Boolean,
  18339. ...makeComponentProps(),
  18340. ...makeDataIteratorItemsProps(),
  18341. ...makeDataTableSelectProps(),
  18342. ...makeDataTableSortProps(),
  18343. ...makeDataTablePaginateProps({
  18344. itemsPerPage: 5
  18345. }),
  18346. ...makeDataTableExpandProps(),
  18347. ...makeDataTableGroupProps(),
  18348. ...makeFilterProps(),
  18349. ...makeTagProps(),
  18350. ...makeTransitionProps({
  18351. transition: {
  18352. component: VFadeTransition,
  18353. hideOnLeave: true
  18354. }
  18355. })
  18356. }, 'VDataIterator');
  18357. const VDataIterator = genericComponent()({
  18358. name: 'VDataIterator',
  18359. props: makeVDataIteratorProps(),
  18360. emits: {
  18361. 'update:modelValue': value => true,
  18362. 'update:groupBy': value => true,
  18363. 'update:page': value => true,
  18364. 'update:itemsPerPage': value => true,
  18365. 'update:sortBy': value => true,
  18366. 'update:options': value => true,
  18367. 'update:expanded': value => true,
  18368. 'update:currentItems': value => true
  18369. },
  18370. setup(props, _ref) {
  18371. let {
  18372. slots
  18373. } = _ref;
  18374. const groupBy = useProxiedModel(props, 'groupBy');
  18375. const search = toRef(props, 'search');
  18376. const {
  18377. items
  18378. } = useDataIteratorItems(props);
  18379. const {
  18380. filteredItems
  18381. } = useFilter(props, items, search, {
  18382. transform: item => item.raw
  18383. });
  18384. const {
  18385. sortBy,
  18386. multiSort,
  18387. mustSort
  18388. } = createSort(props);
  18389. const {
  18390. page,
  18391. itemsPerPage
  18392. } = createPagination(props);
  18393. const {
  18394. toggleSort
  18395. } = provideSort({
  18396. sortBy,
  18397. multiSort,
  18398. mustSort,
  18399. page
  18400. });
  18401. const {
  18402. sortByWithGroups,
  18403. opened,
  18404. extractRows,
  18405. isGroupOpen,
  18406. toggleGroup
  18407. } = provideGroupBy({
  18408. groupBy,
  18409. sortBy
  18410. });
  18411. const {
  18412. sortedItems
  18413. } = useSortedItems(props, filteredItems, sortByWithGroups, {
  18414. transform: item => item.raw
  18415. });
  18416. const {
  18417. flatItems
  18418. } = useGroupedItems(sortedItems, groupBy, opened);
  18419. const itemsLength = computed(() => flatItems.value.length);
  18420. const {
  18421. startIndex,
  18422. stopIndex,
  18423. pageCount,
  18424. prevPage,
  18425. nextPage,
  18426. setItemsPerPage,
  18427. setPage
  18428. } = providePagination({
  18429. page,
  18430. itemsPerPage,
  18431. itemsLength
  18432. });
  18433. const {
  18434. paginatedItems
  18435. } = usePaginatedItems({
  18436. items: flatItems,
  18437. startIndex,
  18438. stopIndex,
  18439. itemsPerPage
  18440. });
  18441. const paginatedItemsWithoutGroups = computed(() => extractRows(paginatedItems.value));
  18442. const {
  18443. isSelected,
  18444. select,
  18445. selectAll,
  18446. toggleSelect
  18447. } = provideSelection(props, {
  18448. allItems: items,
  18449. currentPage: paginatedItemsWithoutGroups
  18450. });
  18451. const {
  18452. isExpanded,
  18453. toggleExpand
  18454. } = provideExpanded(props);
  18455. useOptions({
  18456. page,
  18457. itemsPerPage,
  18458. sortBy,
  18459. groupBy,
  18460. search
  18461. });
  18462. const slotProps = computed(() => ({
  18463. page: page.value,
  18464. itemsPerPage: itemsPerPage.value,
  18465. sortBy: sortBy.value,
  18466. pageCount: pageCount.value,
  18467. toggleSort,
  18468. prevPage,
  18469. nextPage,
  18470. setPage,
  18471. setItemsPerPage,
  18472. isSelected,
  18473. select,
  18474. selectAll,
  18475. toggleSelect,
  18476. isExpanded,
  18477. toggleExpand,
  18478. isGroupOpen,
  18479. toggleGroup,
  18480. items: paginatedItemsWithoutGroups.value,
  18481. groupedItems: paginatedItems.value
  18482. }));
  18483. useRender(() => createVNode(props.tag, {
  18484. "class": ['v-data-iterator', {
  18485. 'v-data-iterator--loading': props.loading
  18486. }, props.class],
  18487. "style": props.style
  18488. }, {
  18489. default: () => [slots.header?.(slotProps.value), createVNode(MaybeTransition, {
  18490. "transition": props.transition
  18491. }, {
  18492. default: () => [props.loading ? createVNode(LoaderSlot, {
  18493. "key": "loader",
  18494. "name": "v-data-iterator",
  18495. "active": true
  18496. }, {
  18497. default: slotProps => slots.loader?.(slotProps)
  18498. }) : createVNode("div", {
  18499. "key": "items"
  18500. }, [!paginatedItems.value.length ? slots['no-data']?.() : slots.default?.(slotProps.value)])]
  18501. }), slots.footer?.(slotProps.value)]
  18502. }));
  18503. return {};
  18504. }
  18505. });
  18506. // Utilities
  18507. // Types
  18508. function useRefs() {
  18509. const refs = ref([]);
  18510. onBeforeUpdate(() => refs.value = []);
  18511. function updateRef(e, i) {
  18512. refs.value[i] = e;
  18513. }
  18514. return {
  18515. refs,
  18516. updateRef
  18517. };
  18518. }
  18519. // Types
  18520. const makeVPaginationProps = propsFactory({
  18521. activeColor: String,
  18522. start: {
  18523. type: [Number, String],
  18524. default: 1
  18525. },
  18526. modelValue: {
  18527. type: Number,
  18528. default: props => props.start
  18529. },
  18530. disabled: Boolean,
  18531. length: {
  18532. type: [Number, String],
  18533. default: 1,
  18534. validator: val => val % 1 === 0
  18535. },
  18536. totalVisible: [Number, String],
  18537. firstIcon: {
  18538. type: IconValue,
  18539. default: '$first'
  18540. },
  18541. prevIcon: {
  18542. type: IconValue,
  18543. default: '$prev'
  18544. },
  18545. nextIcon: {
  18546. type: IconValue,
  18547. default: '$next'
  18548. },
  18549. lastIcon: {
  18550. type: IconValue,
  18551. default: '$last'
  18552. },
  18553. ariaLabel: {
  18554. type: String,
  18555. default: '$vuetify.pagination.ariaLabel.root'
  18556. },
  18557. pageAriaLabel: {
  18558. type: String,
  18559. default: '$vuetify.pagination.ariaLabel.page'
  18560. },
  18561. currentPageAriaLabel: {
  18562. type: String,
  18563. default: '$vuetify.pagination.ariaLabel.currentPage'
  18564. },
  18565. firstAriaLabel: {
  18566. type: String,
  18567. default: '$vuetify.pagination.ariaLabel.first'
  18568. },
  18569. previousAriaLabel: {
  18570. type: String,
  18571. default: '$vuetify.pagination.ariaLabel.previous'
  18572. },
  18573. nextAriaLabel: {
  18574. type: String,
  18575. default: '$vuetify.pagination.ariaLabel.next'
  18576. },
  18577. lastAriaLabel: {
  18578. type: String,
  18579. default: '$vuetify.pagination.ariaLabel.last'
  18580. },
  18581. ellipsis: {
  18582. type: String,
  18583. default: '...'
  18584. },
  18585. showFirstLastPage: Boolean,
  18586. ...makeBorderProps(),
  18587. ...makeComponentProps(),
  18588. ...makeDensityProps(),
  18589. ...makeElevationProps(),
  18590. ...makeRoundedProps(),
  18591. ...makeSizeProps(),
  18592. ...makeTagProps({
  18593. tag: 'nav'
  18594. }),
  18595. ...makeThemeProps(),
  18596. ...makeVariantProps({
  18597. variant: 'text'
  18598. })
  18599. }, 'VPagination');
  18600. const VPagination = genericComponent()({
  18601. name: 'VPagination',
  18602. props: makeVPaginationProps(),
  18603. emits: {
  18604. 'update:modelValue': value => true,
  18605. first: value => true,
  18606. prev: value => true,
  18607. next: value => true,
  18608. last: value => true
  18609. },
  18610. setup(props, _ref) {
  18611. let {
  18612. slots,
  18613. emit
  18614. } = _ref;
  18615. const page = useProxiedModel(props, 'modelValue');
  18616. const {
  18617. t,
  18618. n
  18619. } = useLocale();
  18620. const {
  18621. isRtl
  18622. } = useRtl();
  18623. const {
  18624. themeClasses
  18625. } = provideTheme(props);
  18626. const {
  18627. width
  18628. } = useDisplay();
  18629. const maxButtons = shallowRef(-1);
  18630. provideDefaults(undefined, {
  18631. scoped: true
  18632. });
  18633. const {
  18634. resizeRef
  18635. } = useResizeObserver(entries => {
  18636. if (!entries.length) return;
  18637. const {
  18638. target,
  18639. contentRect
  18640. } = entries[0];
  18641. const firstItem = target.querySelector('.v-pagination__list > *');
  18642. if (!firstItem) return;
  18643. const totalWidth = contentRect.width;
  18644. const itemWidth = firstItem.offsetWidth + parseFloat(getComputedStyle(firstItem).marginRight) * 2;
  18645. maxButtons.value = getMax(totalWidth, itemWidth);
  18646. });
  18647. const length = computed(() => parseInt(props.length, 10));
  18648. const start = computed(() => parseInt(props.start, 10));
  18649. const totalVisible = computed(() => {
  18650. if (props.totalVisible != null) return parseInt(props.totalVisible, 10);else if (maxButtons.value >= 0) return maxButtons.value;
  18651. return getMax(width.value, 58);
  18652. });
  18653. function getMax(totalWidth, itemWidth) {
  18654. const minButtons = props.showFirstLastPage ? 5 : 3;
  18655. return Math.max(0, Math.floor(
  18656. // Round to two decimal places to avoid floating point errors
  18657. +((totalWidth - itemWidth * minButtons) / itemWidth).toFixed(2)));
  18658. }
  18659. const range = computed(() => {
  18660. if (length.value <= 0 || isNaN(length.value) || length.value > Number.MAX_SAFE_INTEGER) return [];
  18661. if (totalVisible.value <= 0) return [];else if (totalVisible.value === 1) return [page.value];
  18662. if (length.value <= totalVisible.value) {
  18663. return createRange(length.value, start.value);
  18664. }
  18665. const even = totalVisible.value % 2 === 0;
  18666. const middle = even ? totalVisible.value / 2 : Math.floor(totalVisible.value / 2);
  18667. const left = even ? middle : middle + 1;
  18668. const right = length.value - middle;
  18669. if (left - page.value >= 0) {
  18670. return [...createRange(Math.max(1, totalVisible.value - 1), start.value), props.ellipsis, length.value];
  18671. } else if (page.value - right >= (even ? 1 : 0)) {
  18672. const rangeLength = totalVisible.value - 1;
  18673. const rangeStart = length.value - rangeLength + start.value;
  18674. return [start.value, props.ellipsis, ...createRange(rangeLength, rangeStart)];
  18675. } else {
  18676. const rangeLength = Math.max(1, totalVisible.value - 3);
  18677. const rangeStart = rangeLength === 1 ? page.value : page.value - Math.ceil(rangeLength / 2) + start.value;
  18678. return [start.value, props.ellipsis, ...createRange(rangeLength, rangeStart), props.ellipsis, length.value];
  18679. }
  18680. });
  18681. // TODO: 'first' | 'prev' | 'next' | 'last' does not work here?
  18682. function setValue(e, value, event) {
  18683. e.preventDefault();
  18684. page.value = value;
  18685. event && emit(event, value);
  18686. }
  18687. const {
  18688. refs,
  18689. updateRef
  18690. } = useRefs();
  18691. provideDefaults({
  18692. VPaginationBtn: {
  18693. color: toRef(props, 'color'),
  18694. border: toRef(props, 'border'),
  18695. density: toRef(props, 'density'),
  18696. size: toRef(props, 'size'),
  18697. variant: toRef(props, 'variant'),
  18698. rounded: toRef(props, 'rounded'),
  18699. elevation: toRef(props, 'elevation')
  18700. }
  18701. });
  18702. const items = computed(() => {
  18703. return range.value.map((item, index) => {
  18704. const ref = e => updateRef(e, index);
  18705. if (typeof item === 'string') {
  18706. return {
  18707. isActive: false,
  18708. key: `ellipsis-${index}`,
  18709. page: item,
  18710. props: {
  18711. ref,
  18712. ellipsis: true,
  18713. icon: true,
  18714. disabled: true
  18715. }
  18716. };
  18717. } else {
  18718. const isActive = item === page.value;
  18719. return {
  18720. isActive,
  18721. key: item,
  18722. page: n(item),
  18723. props: {
  18724. ref,
  18725. ellipsis: false,
  18726. icon: true,
  18727. disabled: !!props.disabled || +props.length < 2,
  18728. color: isActive ? props.activeColor : props.color,
  18729. 'aria-current': isActive,
  18730. 'aria-label': t(isActive ? props.currentPageAriaLabel : props.pageAriaLabel, item),
  18731. onClick: e => setValue(e, item)
  18732. }
  18733. };
  18734. }
  18735. });
  18736. });
  18737. const controls = computed(() => {
  18738. const prevDisabled = !!props.disabled || page.value <= start.value;
  18739. const nextDisabled = !!props.disabled || page.value >= start.value + length.value - 1;
  18740. return {
  18741. first: props.showFirstLastPage ? {
  18742. icon: isRtl.value ? props.lastIcon : props.firstIcon,
  18743. onClick: e => setValue(e, start.value, 'first'),
  18744. disabled: prevDisabled,
  18745. 'aria-label': t(props.firstAriaLabel),
  18746. 'aria-disabled': prevDisabled
  18747. } : undefined,
  18748. prev: {
  18749. icon: isRtl.value ? props.nextIcon : props.prevIcon,
  18750. onClick: e => setValue(e, page.value - 1, 'prev'),
  18751. disabled: prevDisabled,
  18752. 'aria-label': t(props.previousAriaLabel),
  18753. 'aria-disabled': prevDisabled
  18754. },
  18755. next: {
  18756. icon: isRtl.value ? props.prevIcon : props.nextIcon,
  18757. onClick: e => setValue(e, page.value + 1, 'next'),
  18758. disabled: nextDisabled,
  18759. 'aria-label': t(props.nextAriaLabel),
  18760. 'aria-disabled': nextDisabled
  18761. },
  18762. last: props.showFirstLastPage ? {
  18763. icon: isRtl.value ? props.firstIcon : props.lastIcon,
  18764. onClick: e => setValue(e, start.value + length.value - 1, 'last'),
  18765. disabled: nextDisabled,
  18766. 'aria-label': t(props.lastAriaLabel),
  18767. 'aria-disabled': nextDisabled
  18768. } : undefined
  18769. };
  18770. });
  18771. function updateFocus() {
  18772. const currentIndex = page.value - start.value;
  18773. refs.value[currentIndex]?.$el.focus();
  18774. }
  18775. function onKeydown(e) {
  18776. if (e.key === keyValues.left && !props.disabled && page.value > +props.start) {
  18777. page.value = page.value - 1;
  18778. nextTick(updateFocus);
  18779. } else if (e.key === keyValues.right && !props.disabled && page.value < start.value + length.value - 1) {
  18780. page.value = page.value + 1;
  18781. nextTick(updateFocus);
  18782. }
  18783. }
  18784. useRender(() => createVNode(props.tag, {
  18785. "ref": resizeRef,
  18786. "class": ['v-pagination', themeClasses.value, props.class],
  18787. "style": props.style,
  18788. "role": "navigation",
  18789. "aria-label": t(props.ariaLabel),
  18790. "onKeydown": onKeydown,
  18791. "data-test": "v-pagination-root"
  18792. }, {
  18793. default: () => [createVNode("ul", {
  18794. "class": "v-pagination__list"
  18795. }, [props.showFirstLastPage && createVNode("li", {
  18796. "key": "first",
  18797. "class": "v-pagination__first",
  18798. "data-test": "v-pagination-first"
  18799. }, [slots.first ? slots.first(controls.value.first) : createVNode(VBtn, mergeProps({
  18800. "_as": "VPaginationBtn"
  18801. }, controls.value.first), null)]), createVNode("li", {
  18802. "key": "prev",
  18803. "class": "v-pagination__prev",
  18804. "data-test": "v-pagination-prev"
  18805. }, [slots.prev ? slots.prev(controls.value.prev) : createVNode(VBtn, mergeProps({
  18806. "_as": "VPaginationBtn"
  18807. }, controls.value.prev), null)]), items.value.map((item, index) => createVNode("li", {
  18808. "key": item.key,
  18809. "class": ['v-pagination__item', {
  18810. 'v-pagination__item--is-active': item.isActive
  18811. }],
  18812. "data-test": "v-pagination-item"
  18813. }, [slots.item ? slots.item(item) : createVNode(VBtn, mergeProps({
  18814. "_as": "VPaginationBtn"
  18815. }, item.props), {
  18816. default: () => [item.page]
  18817. })])), createVNode("li", {
  18818. "key": "next",
  18819. "class": "v-pagination__next",
  18820. "data-test": "v-pagination-next"
  18821. }, [slots.next ? slots.next(controls.value.next) : createVNode(VBtn, mergeProps({
  18822. "_as": "VPaginationBtn"
  18823. }, controls.value.next), null)]), props.showFirstLastPage && createVNode("li", {
  18824. "key": "last",
  18825. "class": "v-pagination__last",
  18826. "data-test": "v-pagination-last"
  18827. }, [slots.last ? slots.last(controls.value.last) : createVNode(VBtn, mergeProps({
  18828. "_as": "VPaginationBtn"
  18829. }, controls.value.last), null)])])]
  18830. }));
  18831. return {};
  18832. }
  18833. });
  18834. // Types
  18835. const makeVDataTableFooterProps = propsFactory({
  18836. prevIcon: {
  18837. type: IconValue,
  18838. default: '$prev'
  18839. },
  18840. nextIcon: {
  18841. type: IconValue,
  18842. default: '$next'
  18843. },
  18844. firstIcon: {
  18845. type: IconValue,
  18846. default: '$first'
  18847. },
  18848. lastIcon: {
  18849. type: IconValue,
  18850. default: '$last'
  18851. },
  18852. itemsPerPageText: {
  18853. type: String,
  18854. default: '$vuetify.dataFooter.itemsPerPageText'
  18855. },
  18856. pageText: {
  18857. type: String,
  18858. default: '$vuetify.dataFooter.pageText'
  18859. },
  18860. firstPageLabel: {
  18861. type: String,
  18862. default: '$vuetify.dataFooter.firstPage'
  18863. },
  18864. prevPageLabel: {
  18865. type: String,
  18866. default: '$vuetify.dataFooter.prevPage'
  18867. },
  18868. nextPageLabel: {
  18869. type: String,
  18870. default: '$vuetify.dataFooter.nextPage'
  18871. },
  18872. lastPageLabel: {
  18873. type: String,
  18874. default: '$vuetify.dataFooter.lastPage'
  18875. },
  18876. itemsPerPageOptions: {
  18877. type: Array,
  18878. default: () => [{
  18879. value: 10,
  18880. title: '10'
  18881. }, {
  18882. value: 25,
  18883. title: '25'
  18884. }, {
  18885. value: 50,
  18886. title: '50'
  18887. }, {
  18888. value: 100,
  18889. title: '100'
  18890. }, {
  18891. value: -1,
  18892. title: '$vuetify.dataFooter.itemsPerPageAll'
  18893. }]
  18894. },
  18895. showCurrentPage: Boolean
  18896. }, 'VDataTableFooter');
  18897. const VDataTableFooter = genericComponent()({
  18898. name: 'VDataTableFooter',
  18899. props: makeVDataTableFooterProps(),
  18900. setup(props, _ref) {
  18901. let {
  18902. slots
  18903. } = _ref;
  18904. const {
  18905. t
  18906. } = useLocale();
  18907. const {
  18908. page,
  18909. pageCount,
  18910. startIndex,
  18911. stopIndex,
  18912. itemsLength,
  18913. itemsPerPage,
  18914. setItemsPerPage
  18915. } = usePagination();
  18916. const itemsPerPageOptions = computed(() => props.itemsPerPageOptions.map(option => {
  18917. if (typeof option === 'number') {
  18918. return {
  18919. value: option,
  18920. title: option === -1 ? t('$vuetify.dataFooter.itemsPerPageAll') : String(option)
  18921. };
  18922. }
  18923. return {
  18924. ...option,
  18925. title: !isNaN(Number(option.title)) ? option.title : t(option.title)
  18926. };
  18927. }));
  18928. useRender(() => {
  18929. const paginationProps = VPagination.filterProps(props);
  18930. return createVNode("div", {
  18931. "class": "v-data-table-footer"
  18932. }, [slots.prepend?.(), createVNode("div", {
  18933. "class": "v-data-table-footer__items-per-page"
  18934. }, [createVNode("span", null, [t(props.itemsPerPageText)]), createVNode(VSelect, {
  18935. "items": itemsPerPageOptions.value,
  18936. "modelValue": itemsPerPage.value,
  18937. "onUpdate:modelValue": v => setItemsPerPage(Number(v)),
  18938. "density": "compact",
  18939. "variant": "outlined",
  18940. "hide-details": true
  18941. }, null)]), createVNode("div", {
  18942. "class": "v-data-table-footer__info"
  18943. }, [createVNode("div", null, [t(props.pageText, !itemsLength.value ? 0 : startIndex.value + 1, stopIndex.value, itemsLength.value)])]), createVNode("div", {
  18944. "class": "v-data-table-footer__pagination"
  18945. }, [createVNode(VPagination, mergeProps({
  18946. "modelValue": page.value,
  18947. "onUpdate:modelValue": $event => page.value = $event,
  18948. "density": "comfortable",
  18949. "first-aria-label": props.firstPageLabel,
  18950. "last-aria-label": props.lastPageLabel,
  18951. "length": pageCount.value,
  18952. "next-aria-label": props.nextPageLabel,
  18953. "previous-aria-label": props.prevPageLabel,
  18954. "rounded": true,
  18955. "show-first-last-page": true,
  18956. "total-visible": props.showCurrentPage ? 1 : 0,
  18957. "variant": "plain"
  18958. }, paginationProps), null)])]);
  18959. });
  18960. return {};
  18961. }
  18962. });
  18963. // Types
  18964. const VDataTableColumn = defineFunctionalComponent({
  18965. align: {
  18966. type: String,
  18967. default: 'start'
  18968. },
  18969. fixed: Boolean,
  18970. fixedOffset: [Number, String],
  18971. height: [Number, String],
  18972. lastFixed: Boolean,
  18973. noPadding: Boolean,
  18974. tag: String,
  18975. width: [Number, String],
  18976. maxWidth: [Number, String],
  18977. nowrap: Boolean
  18978. }, (props, _ref) => {
  18979. let {
  18980. slots
  18981. } = _ref;
  18982. const Tag = props.tag ?? 'td';
  18983. return createVNode(Tag, {
  18984. "class": ['v-data-table__td', {
  18985. 'v-data-table-column--fixed': props.fixed,
  18986. 'v-data-table-column--last-fixed': props.lastFixed,
  18987. 'v-data-table-column--no-padding': props.noPadding,
  18988. 'v-data-table-column--nowrap': props.nowrap
  18989. }, `v-data-table-column--align-${props.align}`],
  18990. "style": {
  18991. height: convertToUnit(props.height),
  18992. width: convertToUnit(props.width),
  18993. maxWidth: convertToUnit(props.maxWidth),
  18994. left: convertToUnit(props.fixedOffset || null)
  18995. }
  18996. }, {
  18997. default: () => [slots.default?.()]
  18998. });
  18999. });
  19000. // Utilities
  19001. // Types
  19002. const makeDataTableHeaderProps = propsFactory({
  19003. headers: Array
  19004. }, 'DataTable-header');
  19005. const VDataTableHeadersSymbol = Symbol.for('vuetify:data-table-headers');
  19006. const defaultHeader = {
  19007. title: '',
  19008. sortable: false
  19009. };
  19010. const defaultActionHeader = {
  19011. ...defaultHeader,
  19012. width: 48
  19013. };
  19014. function priorityQueue() {
  19015. let arr = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  19016. const queue = arr.map(element => ({
  19017. element,
  19018. priority: 0
  19019. }));
  19020. return {
  19021. enqueue: (element, priority) => {
  19022. let added = false;
  19023. for (let i = 0; i < queue.length; i++) {
  19024. const item = queue[i];
  19025. if (item.priority > priority) {
  19026. queue.splice(i, 0, {
  19027. element,
  19028. priority
  19029. });
  19030. added = true;
  19031. break;
  19032. }
  19033. }
  19034. if (!added) queue.push({
  19035. element,
  19036. priority
  19037. });
  19038. },
  19039. size: () => queue.length,
  19040. count: () => {
  19041. let count = 0;
  19042. if (!queue.length) return 0;
  19043. const whole = Math.floor(queue[0].priority);
  19044. for (let i = 0; i < queue.length; i++) {
  19045. if (Math.floor(queue[i].priority) === whole) count += 1;
  19046. }
  19047. return count;
  19048. },
  19049. dequeue: () => {
  19050. return queue.shift();
  19051. }
  19052. };
  19053. }
  19054. function extractLeaves(item) {
  19055. let columns = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  19056. if (!item.children) {
  19057. columns.push(item);
  19058. } else {
  19059. for (const child of item.children) {
  19060. extractLeaves(child, columns);
  19061. }
  19062. }
  19063. return columns;
  19064. }
  19065. function extractKeys(headers) {
  19066. let keys = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Set();
  19067. for (const item of headers) {
  19068. if (item.key) keys.add(item.key);
  19069. if (item.children) {
  19070. extractKeys(item.children, keys);
  19071. }
  19072. }
  19073. return keys;
  19074. }
  19075. function getDefaultItem(item) {
  19076. if (!item.key) return undefined;
  19077. if (item.key === 'data-table-group') return defaultHeader;
  19078. if (['data-table-expand', 'data-table-select'].includes(item.key)) return defaultActionHeader;
  19079. return undefined;
  19080. }
  19081. function getDepth(item) {
  19082. let depth = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  19083. if (!item.children) return depth;
  19084. return Math.max(depth, ...item.children.map(child => getDepth(child, depth + 1)));
  19085. }
  19086. function parseFixedColumns(items) {
  19087. let seenFixed = false;
  19088. function setFixed(item) {
  19089. let parentFixed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  19090. if (!item) return;
  19091. if (parentFixed) {
  19092. item.fixed = true;
  19093. }
  19094. if (item.fixed) {
  19095. if (item.children) {
  19096. for (let i = item.children.length - 1; i >= 0; i--) {
  19097. setFixed(item.children[i], true);
  19098. }
  19099. } else {
  19100. if (!seenFixed) {
  19101. item.lastFixed = true;
  19102. } else if (isNaN(+item.width)) {
  19103. consoleError(`Multiple fixed columns should have a static width (key: ${item.key})`);
  19104. }
  19105. seenFixed = true;
  19106. }
  19107. } else {
  19108. if (item.children) {
  19109. for (let i = item.children.length - 1; i >= 0; i--) {
  19110. setFixed(item.children[i]);
  19111. }
  19112. } else {
  19113. seenFixed = false;
  19114. }
  19115. }
  19116. }
  19117. for (let i = items.length - 1; i >= 0; i--) {
  19118. setFixed(items[i]);
  19119. }
  19120. function setFixedOffset(item) {
  19121. let fixedOffset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
  19122. if (!item) return fixedOffset;
  19123. if (item.children) {
  19124. item.fixedOffset = fixedOffset;
  19125. for (const child of item.children) {
  19126. fixedOffset = setFixedOffset(child, fixedOffset);
  19127. }
  19128. } else if (item.fixed) {
  19129. item.fixedOffset = fixedOffset;
  19130. fixedOffset += parseFloat(item.width || '0') || 0;
  19131. }
  19132. return fixedOffset;
  19133. }
  19134. let fixedOffset = 0;
  19135. for (const item of items) {
  19136. fixedOffset = setFixedOffset(item, fixedOffset);
  19137. }
  19138. }
  19139. function parse(items, maxDepth) {
  19140. const headers = [];
  19141. let currentDepth = 0;
  19142. const queue = priorityQueue(items);
  19143. while (queue.size() > 0) {
  19144. let rowSize = queue.count();
  19145. const row = [];
  19146. let fraction = 1;
  19147. while (rowSize > 0) {
  19148. const {
  19149. element: item,
  19150. priority
  19151. } = queue.dequeue();
  19152. const diff = maxDepth - currentDepth - getDepth(item);
  19153. row.push({
  19154. ...item,
  19155. rowspan: diff ?? 1,
  19156. colspan: item.children ? extractLeaves(item).length : 1
  19157. });
  19158. if (item.children) {
  19159. for (const child of item.children) {
  19160. // This internally sorts items that are on the same priority "row"
  19161. const sort = priority % 1 + fraction / Math.pow(10, currentDepth + 2);
  19162. queue.enqueue(child, currentDepth + diff + sort);
  19163. }
  19164. }
  19165. fraction += 1;
  19166. rowSize -= 1;
  19167. }
  19168. currentDepth += 1;
  19169. headers.push(row);
  19170. }
  19171. const columns = items.map(item => extractLeaves(item)).flat();
  19172. return {
  19173. columns,
  19174. headers
  19175. };
  19176. }
  19177. function convertToInternalHeaders(items) {
  19178. const internalHeaders = [];
  19179. for (const item of items) {
  19180. const defaultItem = {
  19181. ...getDefaultItem(item),
  19182. ...item
  19183. };
  19184. const key = defaultItem.key ?? (typeof defaultItem.value === 'string' ? defaultItem.value : null);
  19185. const value = defaultItem.value ?? key ?? null;
  19186. const internalItem = {
  19187. ...defaultItem,
  19188. key,
  19189. value,
  19190. sortable: defaultItem.sortable ?? (defaultItem.key != null || !!defaultItem.sort),
  19191. children: defaultItem.children ? convertToInternalHeaders(defaultItem.children) : undefined
  19192. };
  19193. internalHeaders.push(internalItem);
  19194. }
  19195. return internalHeaders;
  19196. }
  19197. function createHeaders(props, options) {
  19198. const headers = ref([]);
  19199. const columns = ref([]);
  19200. const sortFunctions = ref({});
  19201. const sortRawFunctions = ref({});
  19202. const filterFunctions = ref({});
  19203. watchEffect(() => {
  19204. const _headers = props.headers || Object.keys(props.items[0] ?? {}).map(key => ({
  19205. key,
  19206. title: capitalize(key)
  19207. }));
  19208. const items = _headers.slice();
  19209. const keys = extractKeys(items);
  19210. if (options?.groupBy?.value.length && !keys.has('data-table-group')) {
  19211. items.unshift({
  19212. key: 'data-table-group',
  19213. title: 'Group'
  19214. });
  19215. }
  19216. if (options?.showSelect?.value && !keys.has('data-table-select')) {
  19217. items.unshift({
  19218. key: 'data-table-select'
  19219. });
  19220. }
  19221. if (options?.showExpand?.value && !keys.has('data-table-expand')) {
  19222. items.push({
  19223. key: 'data-table-expand'
  19224. });
  19225. }
  19226. const internalHeaders = convertToInternalHeaders(items);
  19227. parseFixedColumns(internalHeaders);
  19228. const maxDepth = Math.max(...internalHeaders.map(item => getDepth(item))) + 1;
  19229. const parsed = parse(internalHeaders, maxDepth);
  19230. headers.value = parsed.headers;
  19231. columns.value = parsed.columns;
  19232. const flatHeaders = parsed.headers.flat(1);
  19233. for (const header of flatHeaders) {
  19234. if (!header.key) continue;
  19235. if (header.sortable) {
  19236. if (header.sort) {
  19237. sortFunctions.value[header.key] = header.sort;
  19238. }
  19239. if (header.sortRaw) {
  19240. sortRawFunctions.value[header.key] = header.sortRaw;
  19241. }
  19242. }
  19243. if (header.filter) {
  19244. filterFunctions.value[header.key] = header.filter;
  19245. }
  19246. }
  19247. });
  19248. const data = {
  19249. headers,
  19250. columns,
  19251. sortFunctions,
  19252. sortRawFunctions,
  19253. filterFunctions
  19254. };
  19255. provide(VDataTableHeadersSymbol, data);
  19256. return data;
  19257. }
  19258. function useHeaders() {
  19259. const data = inject$1(VDataTableHeadersSymbol);
  19260. if (!data) throw new Error('Missing headers!');
  19261. return data;
  19262. }
  19263. // Types
  19264. const makeVDataTableHeadersProps = propsFactory({
  19265. color: String,
  19266. sticky: Boolean,
  19267. disableSort: Boolean,
  19268. multiSort: Boolean,
  19269. sortAscIcon: {
  19270. type: IconValue,
  19271. default: '$sortAsc'
  19272. },
  19273. sortDescIcon: {
  19274. type: IconValue,
  19275. default: '$sortDesc'
  19276. },
  19277. headerProps: {
  19278. type: Object
  19279. },
  19280. ...makeDisplayProps(),
  19281. ...makeLoaderProps()
  19282. }, 'VDataTableHeaders');
  19283. const VDataTableHeaders = genericComponent()({
  19284. name: 'VDataTableHeaders',
  19285. props: makeVDataTableHeadersProps(),
  19286. setup(props, _ref) {
  19287. let {
  19288. slots
  19289. } = _ref;
  19290. const {
  19291. t
  19292. } = useLocale();
  19293. const {
  19294. toggleSort,
  19295. sortBy,
  19296. isSorted
  19297. } = useSort();
  19298. const {
  19299. someSelected,
  19300. allSelected,
  19301. selectAll,
  19302. showSelectAll
  19303. } = useSelection();
  19304. const {
  19305. columns,
  19306. headers
  19307. } = useHeaders();
  19308. const {
  19309. loaderClasses
  19310. } = useLoader(props);
  19311. function getFixedStyles(column, y) {
  19312. if (!props.sticky && !column.fixed) return undefined;
  19313. return {
  19314. position: 'sticky',
  19315. left: column.fixed ? convertToUnit(column.fixedOffset) : undefined,
  19316. top: props.sticky ? `calc(var(--v-table-header-height) * ${y})` : undefined
  19317. };
  19318. }
  19319. function getSortIcon(column) {
  19320. const item = sortBy.value.find(item => item.key === column.key);
  19321. if (!item) return props.sortAscIcon;
  19322. return item.order === 'asc' ? props.sortAscIcon : props.sortDescIcon;
  19323. }
  19324. const {
  19325. backgroundColorClasses,
  19326. backgroundColorStyles
  19327. } = useBackgroundColor(props, 'color');
  19328. const {
  19329. displayClasses,
  19330. mobile
  19331. } = useDisplay(props);
  19332. const slotProps = computed(() => ({
  19333. headers: headers.value,
  19334. columns: columns.value,
  19335. toggleSort,
  19336. isSorted,
  19337. sortBy: sortBy.value,
  19338. someSelected: someSelected.value,
  19339. allSelected: allSelected.value,
  19340. selectAll,
  19341. getSortIcon
  19342. }));
  19343. const headerCellClasses = computed(() => ['v-data-table__th', {
  19344. 'v-data-table__th--sticky': props.sticky
  19345. }, displayClasses.value, loaderClasses.value]);
  19346. const VDataTableHeaderCell = _ref2 => {
  19347. let {
  19348. column,
  19349. x,
  19350. y
  19351. } = _ref2;
  19352. const noPadding = column.key === 'data-table-select' || column.key === 'data-table-expand';
  19353. const headerProps = mergeProps(props.headerProps ?? {}, column.headerProps ?? {});
  19354. return createVNode(VDataTableColumn, mergeProps({
  19355. "tag": "th",
  19356. "align": column.align,
  19357. "class": [{
  19358. 'v-data-table__th--sortable': column.sortable && !props.disableSort,
  19359. 'v-data-table__th--sorted': isSorted(column),
  19360. 'v-data-table__th--fixed': column.fixed
  19361. }, ...headerCellClasses.value],
  19362. "style": {
  19363. width: convertToUnit(column.width),
  19364. minWidth: convertToUnit(column.minWidth),
  19365. maxWidth: convertToUnit(column.maxWidth),
  19366. ...getFixedStyles(column, y)
  19367. },
  19368. "colspan": column.colspan,
  19369. "rowspan": column.rowspan,
  19370. "onClick": column.sortable ? () => toggleSort(column) : undefined,
  19371. "fixed": column.fixed,
  19372. "nowrap": column.nowrap,
  19373. "lastFixed": column.lastFixed,
  19374. "noPadding": noPadding
  19375. }, headerProps), {
  19376. default: () => {
  19377. const columnSlotName = `header.${column.key}`;
  19378. const columnSlotProps = {
  19379. column,
  19380. selectAll,
  19381. isSorted,
  19382. toggleSort,
  19383. sortBy: sortBy.value,
  19384. someSelected: someSelected.value,
  19385. allSelected: allSelected.value,
  19386. getSortIcon
  19387. };
  19388. if (slots[columnSlotName]) return slots[columnSlotName](columnSlotProps);
  19389. if (column.key === 'data-table-select') {
  19390. return slots['header.data-table-select']?.(columnSlotProps) ?? (showSelectAll.value && createVNode(VCheckboxBtn, {
  19391. "modelValue": allSelected.value,
  19392. "indeterminate": someSelected.value && !allSelected.value,
  19393. "onUpdate:modelValue": selectAll
  19394. }, null));
  19395. }
  19396. return createVNode("div", {
  19397. "class": "v-data-table-header__content"
  19398. }, [createVNode("span", null, [column.title]), column.sortable && !props.disableSort && createVNode(VIcon, {
  19399. "key": "icon",
  19400. "class": "v-data-table-header__sort-icon",
  19401. "icon": getSortIcon(column)
  19402. }, null), props.multiSort && isSorted(column) && createVNode("div", {
  19403. "key": "badge",
  19404. "class": ['v-data-table-header__sort-badge', ...backgroundColorClasses.value],
  19405. "style": backgroundColorStyles.value
  19406. }, [sortBy.value.findIndex(x => x.key === column.key) + 1])]);
  19407. }
  19408. });
  19409. };
  19410. const VDataTableMobileHeaderCell = () => {
  19411. const headerProps = mergeProps(props.headerProps ?? {} ?? {});
  19412. const displayItems = computed(() => {
  19413. return columns.value.filter(column => column?.sortable && !props.disableSort);
  19414. });
  19415. const appendIcon = computed(() => {
  19416. const showSelectColumn = columns.value.find(column => column.key === 'data-table-select');
  19417. if (showSelectColumn == null) return;
  19418. return allSelected.value ? '$checkboxOn' : someSelected.value ? '$checkboxIndeterminate' : '$checkboxOff';
  19419. });
  19420. return createVNode(VDataTableColumn, mergeProps({
  19421. "tag": "th",
  19422. "class": [...headerCellClasses.value],
  19423. "colspan": headers.value.length + 1
  19424. }, headerProps), {
  19425. default: () => [createVNode("div", {
  19426. "class": "v-data-table-header__content"
  19427. }, [createVNode(VSelect, {
  19428. "chips": true,
  19429. "class": "v-data-table__td-sort-select",
  19430. "clearable": true,
  19431. "density": "default",
  19432. "items": displayItems.value,
  19433. "label": t('$vuetify.dataTable.sortBy'),
  19434. "multiple": props.multiSort,
  19435. "variant": "underlined",
  19436. "onClick:clear": () => sortBy.value = [],
  19437. "appendIcon": appendIcon.value,
  19438. "onClick:append": () => selectAll(!allSelected.value)
  19439. }, {
  19440. ...slots,
  19441. chip: props => createVNode(VChip, {
  19442. "onClick": props.item.raw?.sortable ? () => toggleSort(props.item.raw) : undefined,
  19443. "onMousedown": e => {
  19444. e.preventDefault();
  19445. e.stopPropagation();
  19446. }
  19447. }, {
  19448. default: () => [props.item.title, createVNode(VIcon, {
  19449. "class": ['v-data-table__td-sort-icon', isSorted(props.item.raw) && 'v-data-table__td-sort-icon-active'],
  19450. "icon": getSortIcon(props.item.raw),
  19451. "size": "small"
  19452. }, null)]
  19453. })
  19454. })])]
  19455. });
  19456. };
  19457. useRender(() => {
  19458. return mobile.value ? createVNode("tr", null, [createVNode(VDataTableMobileHeaderCell, null, null)]) : createVNode(Fragment, null, [slots.headers ? slots.headers(slotProps.value) : headers.value.map((row, y) => createVNode("tr", null, [row.map((column, x) => createVNode(VDataTableHeaderCell, {
  19459. "column": column,
  19460. "x": x,
  19461. "y": y
  19462. }, null))])), props.loading && createVNode("tr", {
  19463. "class": "v-data-table-progress"
  19464. }, [createVNode("th", {
  19465. "colspan": columns.value.length
  19466. }, [createVNode(LoaderSlot, {
  19467. "name": "v-data-table-progress",
  19468. "absolute": true,
  19469. "active": true,
  19470. "color": typeof props.loading === 'boolean' ? undefined : props.loading,
  19471. "indeterminate": true
  19472. }, {
  19473. default: slots.loader
  19474. })])])]);
  19475. });
  19476. }
  19477. });
  19478. // Types
  19479. const makeVDataTableGroupHeaderRowProps = propsFactory({
  19480. item: {
  19481. type: Object,
  19482. required: true
  19483. }
  19484. }, 'VDataTableGroupHeaderRow');
  19485. const VDataTableGroupHeaderRow = genericComponent()({
  19486. name: 'VDataTableGroupHeaderRow',
  19487. props: makeVDataTableGroupHeaderRowProps(),
  19488. setup(props, _ref) {
  19489. let {
  19490. slots
  19491. } = _ref;
  19492. const {
  19493. isGroupOpen,
  19494. toggleGroup,
  19495. extractRows
  19496. } = useGroupBy();
  19497. const {
  19498. isSelected,
  19499. isSomeSelected,
  19500. select
  19501. } = useSelection();
  19502. const {
  19503. columns
  19504. } = useHeaders();
  19505. const rows = computed(() => {
  19506. return extractRows([props.item]);
  19507. });
  19508. return () => createVNode("tr", {
  19509. "class": "v-data-table-group-header-row",
  19510. "style": {
  19511. '--v-data-table-group-header-row-depth': props.item.depth
  19512. }
  19513. }, [columns.value.map(column => {
  19514. if (column.key === 'data-table-group') {
  19515. const icon = isGroupOpen(props.item) ? '$expand' : '$next';
  19516. const onClick = () => toggleGroup(props.item);
  19517. return slots['data-table-group']?.({
  19518. item: props.item,
  19519. count: rows.value.length,
  19520. props: {
  19521. icon,
  19522. onClick
  19523. }
  19524. }) ?? createVNode(VDataTableColumn, {
  19525. "class": "v-data-table-group-header-row__column"
  19526. }, {
  19527. default: () => [createVNode(VBtn, {
  19528. "size": "small",
  19529. "variant": "text",
  19530. "icon": icon,
  19531. "onClick": onClick
  19532. }, null), createVNode("span", null, [props.item.value]), createVNode("span", null, [createTextVNode("("), rows.value.length, createTextVNode(")")])]
  19533. });
  19534. }
  19535. if (column.key === 'data-table-select') {
  19536. const modelValue = isSelected(rows.value);
  19537. const indeterminate = isSomeSelected(rows.value) && !modelValue;
  19538. const selectGroup = v => select(rows.value, v);
  19539. return slots['data-table-select']?.({
  19540. props: {
  19541. modelValue,
  19542. indeterminate,
  19543. 'onUpdate:modelValue': selectGroup
  19544. }
  19545. }) ?? createVNode("td", null, [createVNode(VCheckboxBtn, {
  19546. "modelValue": modelValue,
  19547. "indeterminate": indeterminate,
  19548. "onUpdate:modelValue": selectGroup
  19549. }, null)]);
  19550. }
  19551. return createVNode("td", null, null);
  19552. })]);
  19553. }
  19554. });
  19555. // Types
  19556. const makeVDataTableRowProps = propsFactory({
  19557. index: Number,
  19558. item: Object,
  19559. cellProps: [Object, Function],
  19560. onClick: EventProp(),
  19561. onContextmenu: EventProp(),
  19562. onDblclick: EventProp(),
  19563. ...makeDisplayProps()
  19564. }, 'VDataTableRow');
  19565. const VDataTableRow = genericComponent()({
  19566. name: 'VDataTableRow',
  19567. props: makeVDataTableRowProps(),
  19568. setup(props, _ref) {
  19569. let {
  19570. slots
  19571. } = _ref;
  19572. const {
  19573. displayClasses,
  19574. mobile
  19575. } = useDisplay(props, 'v-data-table__tr');
  19576. const {
  19577. isSelected,
  19578. toggleSelect,
  19579. someSelected,
  19580. allSelected,
  19581. selectAll
  19582. } = useSelection();
  19583. const {
  19584. isExpanded,
  19585. toggleExpand
  19586. } = useExpanded();
  19587. const {
  19588. toggleSort,
  19589. sortBy,
  19590. isSorted
  19591. } = useSort();
  19592. const {
  19593. columns
  19594. } = useHeaders();
  19595. useRender(() => createVNode("tr", {
  19596. "class": ['v-data-table__tr', {
  19597. 'v-data-table__tr--clickable': !!(props.onClick || props.onContextmenu || props.onDblclick)
  19598. }, displayClasses.value],
  19599. "onClick": props.onClick,
  19600. "onContextmenu": props.onContextmenu,
  19601. "onDblclick": props.onDblclick
  19602. }, [props.item && columns.value.map((column, i) => {
  19603. const item = props.item;
  19604. const slotName = `item.${column.key}`;
  19605. const headerSlotName = `header.${column.key}`;
  19606. const slotProps = {
  19607. index: props.index,
  19608. item: item.raw,
  19609. internalItem: item,
  19610. value: getObjectValueByPath(item.columns, column.key),
  19611. column,
  19612. isSelected,
  19613. toggleSelect,
  19614. isExpanded,
  19615. toggleExpand
  19616. };
  19617. const columnSlotProps = {
  19618. column,
  19619. selectAll,
  19620. isSorted,
  19621. toggleSort,
  19622. sortBy: sortBy.value,
  19623. someSelected: someSelected.value,
  19624. allSelected: allSelected.value,
  19625. getSortIcon: () => ''
  19626. };
  19627. const cellProps = typeof props.cellProps === 'function' ? props.cellProps({
  19628. index: slotProps.index,
  19629. item: slotProps.item,
  19630. internalItem: slotProps.internalItem,
  19631. value: slotProps.value,
  19632. column
  19633. }) : props.cellProps;
  19634. const columnCellProps = typeof column.cellProps === 'function' ? column.cellProps({
  19635. index: slotProps.index,
  19636. item: slotProps.item,
  19637. internalItem: slotProps.internalItem,
  19638. value: slotProps.value
  19639. }) : column.cellProps;
  19640. return createVNode(VDataTableColumn, mergeProps({
  19641. "align": column.align,
  19642. "class": {
  19643. 'v-data-table__td--expanded-row': column.key === 'data-table-expand',
  19644. 'v-data-table__td--select-row': column.key === 'data-table-select'
  19645. },
  19646. "fixed": column.fixed,
  19647. "fixedOffset": column.fixedOffset,
  19648. "lastFixed": column.lastFixed,
  19649. "maxWidth": !mobile.value ? column.maxWidth : undefined,
  19650. "noPadding": column.key === 'data-table-select' || column.key === 'data-table-expand',
  19651. "nowrap": column.nowrap,
  19652. "width": !mobile.value ? column.width : undefined
  19653. }, cellProps, columnCellProps), {
  19654. default: () => {
  19655. if (slots[slotName] && !mobile.value) return slots[slotName]?.(slotProps);
  19656. if (column.key === 'data-table-select') {
  19657. return slots['item.data-table-select']?.(slotProps) ?? createVNode(VCheckboxBtn, {
  19658. "disabled": !item.selectable,
  19659. "modelValue": isSelected([item]),
  19660. "onClick": withModifiers(() => toggleSelect(item), ['stop'])
  19661. }, null);
  19662. }
  19663. if (column.key === 'data-table-expand') {
  19664. return slots['item.data-table-expand']?.(slotProps) ?? createVNode(VBtn, {
  19665. "icon": isExpanded(item) ? '$collapse' : '$expand',
  19666. "size": "small",
  19667. "variant": "text",
  19668. "onClick": withModifiers(() => toggleExpand(item), ['stop'])
  19669. }, null);
  19670. }
  19671. const displayValue = toDisplayString(slotProps.value);
  19672. return !mobile.value ? displayValue : createVNode(Fragment, null, [createVNode("div", {
  19673. "class": "v-data-table__td-title"
  19674. }, [slots[headerSlotName]?.(columnSlotProps) ?? column.title]), createVNode("div", {
  19675. "class": "v-data-table__td-value"
  19676. }, [slots[slotName]?.(slotProps) ?? displayValue])]);
  19677. }
  19678. });
  19679. })]));
  19680. }
  19681. });
  19682. // Types
  19683. const makeVDataTableRowsProps = propsFactory({
  19684. loading: [Boolean, String],
  19685. loadingText: {
  19686. type: String,
  19687. default: '$vuetify.dataIterator.loadingText'
  19688. },
  19689. hideNoData: Boolean,
  19690. items: {
  19691. type: Array,
  19692. default: () => []
  19693. },
  19694. noDataText: {
  19695. type: String,
  19696. default: '$vuetify.noDataText'
  19697. },
  19698. rowProps: [Object, Function],
  19699. cellProps: [Object, Function],
  19700. ...makeDisplayProps()
  19701. }, 'VDataTableRows');
  19702. const VDataTableRows = genericComponent()({
  19703. name: 'VDataTableRows',
  19704. inheritAttrs: false,
  19705. props: makeVDataTableRowsProps(),
  19706. setup(props, _ref) {
  19707. let {
  19708. attrs,
  19709. slots
  19710. } = _ref;
  19711. const {
  19712. columns
  19713. } = useHeaders();
  19714. const {
  19715. expandOnClick,
  19716. toggleExpand,
  19717. isExpanded
  19718. } = useExpanded();
  19719. const {
  19720. isSelected,
  19721. toggleSelect
  19722. } = useSelection();
  19723. const {
  19724. toggleGroup,
  19725. isGroupOpen
  19726. } = useGroupBy();
  19727. const {
  19728. t
  19729. } = useLocale();
  19730. const {
  19731. mobile
  19732. } = useDisplay(props);
  19733. useRender(() => {
  19734. if (props.loading && (!props.items.length || slots.loading)) {
  19735. return createVNode("tr", {
  19736. "class": "v-data-table-rows-loading",
  19737. "key": "loading"
  19738. }, [createVNode("td", {
  19739. "colspan": columns.value.length
  19740. }, [slots.loading?.() ?? t(props.loadingText)])]);
  19741. }
  19742. if (!props.loading && !props.items.length && !props.hideNoData) {
  19743. return createVNode("tr", {
  19744. "class": "v-data-table-rows-no-data",
  19745. "key": "no-data"
  19746. }, [createVNode("td", {
  19747. "colspan": columns.value.length
  19748. }, [slots['no-data']?.() ?? t(props.noDataText)])]);
  19749. }
  19750. return createVNode(Fragment, null, [props.items.map((item, index) => {
  19751. if (item.type === 'group') {
  19752. const slotProps = {
  19753. index,
  19754. item,
  19755. columns: columns.value,
  19756. isExpanded,
  19757. toggleExpand,
  19758. isSelected,
  19759. toggleSelect,
  19760. toggleGroup,
  19761. isGroupOpen
  19762. };
  19763. return slots['group-header'] ? slots['group-header'](slotProps) : createVNode(VDataTableGroupHeaderRow, mergeProps({
  19764. "key": `group-header_${item.id}`,
  19765. "item": item
  19766. }, getPrefixedEventHandlers(attrs, ':group-header', () => slotProps)), slots);
  19767. }
  19768. const slotProps = {
  19769. index,
  19770. item: item.raw,
  19771. internalItem: item,
  19772. columns: columns.value,
  19773. isExpanded,
  19774. toggleExpand,
  19775. isSelected,
  19776. toggleSelect
  19777. };
  19778. const itemSlotProps = {
  19779. ...slotProps,
  19780. props: mergeProps({
  19781. key: `item_${item.key ?? item.index}`,
  19782. onClick: expandOnClick.value ? () => {
  19783. toggleExpand(item);
  19784. } : undefined,
  19785. index,
  19786. item,
  19787. cellProps: props.cellProps,
  19788. mobile: mobile.value
  19789. }, getPrefixedEventHandlers(attrs, ':row', () => slotProps), typeof props.rowProps === 'function' ? props.rowProps({
  19790. item: slotProps.item,
  19791. index: slotProps.index,
  19792. internalItem: slotProps.internalItem
  19793. }) : props.rowProps)
  19794. };
  19795. return createVNode(Fragment, {
  19796. "key": itemSlotProps.props.key
  19797. }, [slots.item ? slots.item(itemSlotProps) : createVNode(VDataTableRow, itemSlotProps.props, slots), isExpanded(item) && slots['expanded-row']?.(slotProps)]);
  19798. })]);
  19799. });
  19800. return {};
  19801. }
  19802. });
  19803. const makeVTableProps = propsFactory({
  19804. fixedHeader: Boolean,
  19805. fixedFooter: Boolean,
  19806. height: [Number, String],
  19807. hover: Boolean,
  19808. ...makeComponentProps(),
  19809. ...makeDensityProps(),
  19810. ...makeTagProps(),
  19811. ...makeThemeProps()
  19812. }, 'VTable');
  19813. const VTable = genericComponent()({
  19814. name: 'VTable',
  19815. props: makeVTableProps(),
  19816. setup(props, _ref) {
  19817. let {
  19818. slots,
  19819. emit
  19820. } = _ref;
  19821. const {
  19822. themeClasses
  19823. } = provideTheme(props);
  19824. const {
  19825. densityClasses
  19826. } = useDensity(props);
  19827. useRender(() => createVNode(props.tag, {
  19828. "class": ['v-table', {
  19829. 'v-table--fixed-height': !!props.height,
  19830. 'v-table--fixed-header': props.fixedHeader,
  19831. 'v-table--fixed-footer': props.fixedFooter,
  19832. 'v-table--has-top': !!slots.top,
  19833. 'v-table--has-bottom': !!slots.bottom,
  19834. 'v-table--hover': props.hover
  19835. }, themeClasses.value, densityClasses.value, props.class],
  19836. "style": props.style
  19837. }, {
  19838. default: () => [slots.top?.(), slots.default ? createVNode("div", {
  19839. "class": "v-table__wrapper",
  19840. "style": {
  19841. height: convertToUnit(props.height)
  19842. }
  19843. }, [createVNode("table", null, [slots.default()])]) : slots.wrapper?.(), slots.bottom?.()]
  19844. }));
  19845. return {};
  19846. }
  19847. });
  19848. // Utilities
  19849. // Types
  19850. // Composables
  19851. const makeDataTableItemsProps = propsFactory({
  19852. items: {
  19853. type: Array,
  19854. default: () => []
  19855. },
  19856. itemValue: {
  19857. type: [String, Array, Function],
  19858. default: 'id'
  19859. },
  19860. itemSelectable: {
  19861. type: [String, Array, Function],
  19862. default: null
  19863. },
  19864. rowProps: [Object, Function],
  19865. cellProps: [Object, Function],
  19866. returnObject: Boolean
  19867. }, 'DataTable-items');
  19868. function transformItem(props, item, index, columns) {
  19869. const value = props.returnObject ? item : getPropertyFromItem(item, props.itemValue);
  19870. const selectable = getPropertyFromItem(item, props.itemSelectable, true);
  19871. const itemColumns = columns.reduce((obj, column) => {
  19872. if (column.key != null) obj[column.key] = getPropertyFromItem(item, column.value);
  19873. return obj;
  19874. }, {});
  19875. return {
  19876. type: 'item',
  19877. key: props.returnObject ? getPropertyFromItem(item, props.itemValue) : value,
  19878. index,
  19879. value,
  19880. selectable,
  19881. columns: itemColumns,
  19882. raw: item
  19883. };
  19884. }
  19885. function transformItems(props, items, columns) {
  19886. return items.map((item, index) => transformItem(props, item, index, columns));
  19887. }
  19888. function useDataTableItems(props, columns) {
  19889. const items = computed(() => transformItems(props, props.items, columns.value));
  19890. return {
  19891. items
  19892. };
  19893. }
  19894. // Types
  19895. const makeDataTableProps = propsFactory({
  19896. ...makeVDataTableRowsProps(),
  19897. hideDefaultBody: Boolean,
  19898. hideDefaultFooter: Boolean,
  19899. hideDefaultHeader: Boolean,
  19900. width: [String, Number],
  19901. search: String,
  19902. ...makeDataTableExpandProps(),
  19903. ...makeDataTableGroupProps(),
  19904. ...makeDataTableHeaderProps(),
  19905. ...makeDataTableItemsProps(),
  19906. ...makeDataTableSelectProps(),
  19907. ...makeDataTableSortProps(),
  19908. ...makeVDataTableHeadersProps(),
  19909. ...makeVTableProps()
  19910. }, 'DataTable');
  19911. const makeVDataTableProps = propsFactory({
  19912. ...makeDataTablePaginateProps(),
  19913. ...makeDataTableProps(),
  19914. ...makeFilterProps(),
  19915. ...makeVDataTableFooterProps()
  19916. }, 'VDataTable');
  19917. const VDataTable = genericComponent()({
  19918. name: 'VDataTable',
  19919. props: makeVDataTableProps(),
  19920. emits: {
  19921. 'update:modelValue': value => true,
  19922. 'update:page': value => true,
  19923. 'update:itemsPerPage': value => true,
  19924. 'update:sortBy': value => true,
  19925. 'update:options': value => true,
  19926. 'update:groupBy': value => true,
  19927. 'update:expanded': value => true,
  19928. 'update:currentItems': value => true
  19929. },
  19930. setup(props, _ref) {
  19931. let {
  19932. attrs,
  19933. slots
  19934. } = _ref;
  19935. const {
  19936. groupBy
  19937. } = createGroupBy(props);
  19938. const {
  19939. sortBy,
  19940. multiSort,
  19941. mustSort
  19942. } = createSort(props);
  19943. const {
  19944. page,
  19945. itemsPerPage
  19946. } = createPagination(props);
  19947. const {
  19948. disableSort
  19949. } = toRefs(props);
  19950. const {
  19951. columns,
  19952. headers,
  19953. sortFunctions,
  19954. sortRawFunctions,
  19955. filterFunctions
  19956. } = createHeaders(props, {
  19957. groupBy,
  19958. showSelect: toRef(props, 'showSelect'),
  19959. showExpand: toRef(props, 'showExpand')
  19960. });
  19961. const {
  19962. items
  19963. } = useDataTableItems(props, columns);
  19964. const search = toRef(props, 'search');
  19965. const {
  19966. filteredItems
  19967. } = useFilter(props, items, search, {
  19968. transform: item => item.columns,
  19969. customKeyFilter: filterFunctions
  19970. });
  19971. const {
  19972. toggleSort
  19973. } = provideSort({
  19974. sortBy,
  19975. multiSort,
  19976. mustSort,
  19977. page
  19978. });
  19979. const {
  19980. sortByWithGroups,
  19981. opened,
  19982. extractRows,
  19983. isGroupOpen,
  19984. toggleGroup
  19985. } = provideGroupBy({
  19986. groupBy,
  19987. sortBy,
  19988. disableSort
  19989. });
  19990. const {
  19991. sortedItems
  19992. } = useSortedItems(props, filteredItems, sortByWithGroups, {
  19993. transform: item => ({
  19994. ...item.raw,
  19995. ...item.columns
  19996. }),
  19997. sortFunctions,
  19998. sortRawFunctions
  19999. });
  20000. const {
  20001. flatItems
  20002. } = useGroupedItems(sortedItems, groupBy, opened);
  20003. const itemsLength = computed(() => flatItems.value.length);
  20004. const {
  20005. startIndex,
  20006. stopIndex,
  20007. pageCount,
  20008. setItemsPerPage
  20009. } = providePagination({
  20010. page,
  20011. itemsPerPage,
  20012. itemsLength
  20013. });
  20014. const {
  20015. paginatedItems
  20016. } = usePaginatedItems({
  20017. items: flatItems,
  20018. startIndex,
  20019. stopIndex,
  20020. itemsPerPage
  20021. });
  20022. const paginatedItemsWithoutGroups = computed(() => extractRows(paginatedItems.value));
  20023. const {
  20024. isSelected,
  20025. select,
  20026. selectAll,
  20027. toggleSelect,
  20028. someSelected,
  20029. allSelected
  20030. } = provideSelection(props, {
  20031. allItems: items,
  20032. currentPage: paginatedItemsWithoutGroups
  20033. });
  20034. const {
  20035. isExpanded,
  20036. toggleExpand
  20037. } = provideExpanded(props);
  20038. useOptions({
  20039. page,
  20040. itemsPerPage,
  20041. sortBy,
  20042. groupBy,
  20043. search
  20044. });
  20045. provideDefaults({
  20046. VDataTableRows: {
  20047. hideNoData: toRef(props, 'hideNoData'),
  20048. noDataText: toRef(props, 'noDataText'),
  20049. loading: toRef(props, 'loading'),
  20050. loadingText: toRef(props, 'loadingText')
  20051. }
  20052. });
  20053. const slotProps = computed(() => ({
  20054. page: page.value,
  20055. itemsPerPage: itemsPerPage.value,
  20056. sortBy: sortBy.value,
  20057. pageCount: pageCount.value,
  20058. toggleSort,
  20059. setItemsPerPage,
  20060. someSelected: someSelected.value,
  20061. allSelected: allSelected.value,
  20062. isSelected,
  20063. select,
  20064. selectAll,
  20065. toggleSelect,
  20066. isExpanded,
  20067. toggleExpand,
  20068. isGroupOpen,
  20069. toggleGroup,
  20070. items: paginatedItemsWithoutGroups.value.map(item => item.raw),
  20071. internalItems: paginatedItemsWithoutGroups.value,
  20072. groupedItems: paginatedItems.value,
  20073. columns: columns.value,
  20074. headers: headers.value
  20075. }));
  20076. useRender(() => {
  20077. const dataTableFooterProps = VDataTableFooter.filterProps(props);
  20078. const dataTableHeadersProps = VDataTableHeaders.filterProps(props);
  20079. const dataTableRowsProps = VDataTableRows.filterProps(props);
  20080. const tableProps = VTable.filterProps(props);
  20081. return createVNode(VTable, mergeProps({
  20082. "class": ['v-data-table', {
  20083. 'v-data-table--show-select': props.showSelect,
  20084. 'v-data-table--loading': props.loading
  20085. }, props.class],
  20086. "style": props.style
  20087. }, tableProps), {
  20088. top: () => slots.top?.(slotProps.value),
  20089. default: () => slots.default ? slots.default(slotProps.value) : createVNode(Fragment, null, [slots.colgroup?.(slotProps.value), !props.hideDefaultHeader && createVNode("thead", {
  20090. "key": "thead"
  20091. }, [createVNode(VDataTableHeaders, dataTableHeadersProps, slots)]), slots.thead?.(slotProps.value), !props.hideDefaultBody && createVNode("tbody", null, [slots['body.prepend']?.(slotProps.value), slots.body ? slots.body(slotProps.value) : createVNode(VDataTableRows, mergeProps(attrs, dataTableRowsProps, {
  20092. "items": paginatedItems.value
  20093. }), slots), slots['body.append']?.(slotProps.value)]), slots.tbody?.(slotProps.value), slots.tfoot?.(slotProps.value)]),
  20094. bottom: () => slots.bottom ? slots.bottom(slotProps.value) : !props.hideDefaultFooter && createVNode(Fragment, null, [createVNode(VDivider, null, null), createVNode(VDataTableFooter, dataTableFooterProps, {
  20095. prepend: slots['footer.prepend']
  20096. })])
  20097. });
  20098. });
  20099. return {};
  20100. }
  20101. });
  20102. // Types
  20103. const makeVDataTableVirtualProps = propsFactory({
  20104. ...makeDataTableProps(),
  20105. ...makeDataTableGroupProps(),
  20106. ...makeVirtualProps(),
  20107. ...makeFilterProps()
  20108. }, 'VDataTableVirtual');
  20109. const VDataTableVirtual = genericComponent()({
  20110. name: 'VDataTableVirtual',
  20111. props: makeVDataTableVirtualProps(),
  20112. emits: {
  20113. 'update:modelValue': value => true,
  20114. 'update:sortBy': value => true,
  20115. 'update:options': value => true,
  20116. 'update:groupBy': value => true,
  20117. 'update:expanded': value => true
  20118. },
  20119. setup(props, _ref) {
  20120. let {
  20121. attrs,
  20122. slots
  20123. } = _ref;
  20124. const {
  20125. groupBy
  20126. } = createGroupBy(props);
  20127. const {
  20128. sortBy,
  20129. multiSort,
  20130. mustSort
  20131. } = createSort(props);
  20132. const {
  20133. disableSort
  20134. } = toRefs(props);
  20135. const {
  20136. columns,
  20137. headers,
  20138. filterFunctions,
  20139. sortFunctions,
  20140. sortRawFunctions
  20141. } = createHeaders(props, {
  20142. groupBy,
  20143. showSelect: toRef(props, 'showSelect'),
  20144. showExpand: toRef(props, 'showExpand')
  20145. });
  20146. const {
  20147. items
  20148. } = useDataTableItems(props, columns);
  20149. const search = toRef(props, 'search');
  20150. const {
  20151. filteredItems
  20152. } = useFilter(props, items, search, {
  20153. transform: item => item.columns,
  20154. customKeyFilter: filterFunctions
  20155. });
  20156. const {
  20157. toggleSort
  20158. } = provideSort({
  20159. sortBy,
  20160. multiSort,
  20161. mustSort
  20162. });
  20163. const {
  20164. sortByWithGroups,
  20165. opened,
  20166. extractRows,
  20167. isGroupOpen,
  20168. toggleGroup
  20169. } = provideGroupBy({
  20170. groupBy,
  20171. sortBy,
  20172. disableSort
  20173. });
  20174. const {
  20175. sortedItems
  20176. } = useSortedItems(props, filteredItems, sortByWithGroups, {
  20177. transform: item => ({
  20178. ...item.raw,
  20179. ...item.columns
  20180. }),
  20181. sortFunctions,
  20182. sortRawFunctions
  20183. });
  20184. const {
  20185. flatItems
  20186. } = useGroupedItems(sortedItems, groupBy, opened);
  20187. const allItems = computed(() => extractRows(flatItems.value));
  20188. const {
  20189. isSelected,
  20190. select,
  20191. selectAll,
  20192. toggleSelect,
  20193. someSelected,
  20194. allSelected
  20195. } = provideSelection(props, {
  20196. allItems,
  20197. currentPage: allItems
  20198. });
  20199. const {
  20200. isExpanded,
  20201. toggleExpand
  20202. } = provideExpanded(props);
  20203. const {
  20204. containerRef,
  20205. markerRef,
  20206. paddingTop,
  20207. paddingBottom,
  20208. computedItems,
  20209. handleItemResize,
  20210. handleScroll,
  20211. handleScrollend
  20212. } = useVirtual(props, flatItems);
  20213. const displayItems = computed(() => computedItems.value.map(item => item.raw));
  20214. useOptions({
  20215. sortBy,
  20216. page: shallowRef(1),
  20217. itemsPerPage: shallowRef(-1),
  20218. groupBy,
  20219. search
  20220. });
  20221. provideDefaults({
  20222. VDataTableRows: {
  20223. hideNoData: toRef(props, 'hideNoData'),
  20224. noDataText: toRef(props, 'noDataText'),
  20225. loading: toRef(props, 'loading'),
  20226. loadingText: toRef(props, 'loadingText')
  20227. }
  20228. });
  20229. const slotProps = computed(() => ({
  20230. sortBy: sortBy.value,
  20231. toggleSort,
  20232. someSelected: someSelected.value,
  20233. allSelected: allSelected.value,
  20234. isSelected,
  20235. select,
  20236. selectAll,
  20237. toggleSelect,
  20238. isExpanded,
  20239. toggleExpand,
  20240. isGroupOpen,
  20241. toggleGroup,
  20242. items: allItems.value.map(item => item.raw),
  20243. internalItems: allItems.value,
  20244. groupedItems: flatItems.value,
  20245. columns: columns.value,
  20246. headers: headers.value
  20247. }));
  20248. useRender(() => {
  20249. const dataTableHeadersProps = VDataTableHeaders.filterProps(props);
  20250. const dataTableRowsProps = VDataTableRows.filterProps(props);
  20251. const tableProps = VTable.filterProps(props);
  20252. return createVNode(VTable, mergeProps({
  20253. "class": ['v-data-table', {
  20254. 'v-data-table--loading': props.loading
  20255. }, props.class],
  20256. "style": props.style
  20257. }, tableProps), {
  20258. top: () => slots.top?.(slotProps.value),
  20259. wrapper: () => createVNode("div", {
  20260. "ref": containerRef,
  20261. "onScrollPassive": handleScroll,
  20262. "onScrollend": handleScrollend,
  20263. "class": "v-table__wrapper",
  20264. "style": {
  20265. height: convertToUnit(props.height)
  20266. }
  20267. }, [createVNode("table", null, [slots.colgroup?.(slotProps.value), !props.hideDefaultHeader && createVNode("thead", {
  20268. "key": "thead"
  20269. }, [createVNode(VDataTableHeaders, mergeProps(dataTableHeadersProps, {
  20270. "sticky": props.fixedHeader
  20271. }), slots)]), !props.hideDefaultBody && createVNode("tbody", null, [createVNode("tr", {
  20272. "ref": markerRef,
  20273. "style": {
  20274. height: convertToUnit(paddingTop.value),
  20275. border: 0
  20276. }
  20277. }, [createVNode("td", {
  20278. "colspan": columns.value.length,
  20279. "style": {
  20280. height: 0,
  20281. border: 0
  20282. }
  20283. }, null)]), slots['body.prepend']?.(slotProps.value), createVNode(VDataTableRows, mergeProps(attrs, dataTableRowsProps, {
  20284. "items": displayItems.value
  20285. }), {
  20286. ...slots,
  20287. item: itemSlotProps => createVNode(VVirtualScrollItem, {
  20288. "key": itemSlotProps.internalItem.index,
  20289. "renderless": true,
  20290. "onUpdate:height": height => handleItemResize(itemSlotProps.internalItem.index, height)
  20291. }, {
  20292. default: _ref2 => {
  20293. let {
  20294. itemRef
  20295. } = _ref2;
  20296. return slots.item?.({
  20297. ...itemSlotProps,
  20298. itemRef
  20299. }) ?? createVNode(VDataTableRow, mergeProps(itemSlotProps.props, {
  20300. "ref": itemRef,
  20301. "key": itemSlotProps.internalItem.index,
  20302. "index": itemSlotProps.internalItem.index
  20303. }), slots);
  20304. }
  20305. })
  20306. }), slots['body.append']?.(slotProps.value), createVNode("tr", {
  20307. "style": {
  20308. height: convertToUnit(paddingBottom.value),
  20309. border: 0
  20310. }
  20311. }, [createVNode("td", {
  20312. "colspan": columns.value.length,
  20313. "style": {
  20314. height: 0,
  20315. border: 0
  20316. }
  20317. }, null)])])])]),
  20318. bottom: () => slots.bottom?.(slotProps.value)
  20319. });
  20320. });
  20321. }
  20322. });
  20323. // Types
  20324. const makeVDataTableServerProps = propsFactory({
  20325. itemsLength: {
  20326. type: [Number, String],
  20327. required: true
  20328. },
  20329. ...makeDataTablePaginateProps(),
  20330. ...makeDataTableProps(),
  20331. ...makeVDataTableFooterProps()
  20332. }, 'VDataTableServer');
  20333. const VDataTableServer = genericComponent()({
  20334. name: 'VDataTableServer',
  20335. props: makeVDataTableServerProps(),
  20336. emits: {
  20337. 'update:modelValue': value => true,
  20338. 'update:page': page => true,
  20339. 'update:itemsPerPage': page => true,
  20340. 'update:sortBy': sortBy => true,
  20341. 'update:options': options => true,
  20342. 'update:expanded': options => true,
  20343. 'update:groupBy': value => true
  20344. },
  20345. setup(props, _ref) {
  20346. let {
  20347. attrs,
  20348. slots
  20349. } = _ref;
  20350. const {
  20351. groupBy
  20352. } = createGroupBy(props);
  20353. const {
  20354. sortBy,
  20355. multiSort,
  20356. mustSort
  20357. } = createSort(props);
  20358. const {
  20359. page,
  20360. itemsPerPage
  20361. } = createPagination(props);
  20362. const {
  20363. disableSort
  20364. } = toRefs(props);
  20365. const itemsLength = computed(() => parseInt(props.itemsLength, 10));
  20366. const {
  20367. columns,
  20368. headers
  20369. } = createHeaders(props, {
  20370. groupBy,
  20371. showSelect: toRef(props, 'showSelect'),
  20372. showExpand: toRef(props, 'showExpand')
  20373. });
  20374. const {
  20375. items
  20376. } = useDataTableItems(props, columns);
  20377. const {
  20378. toggleSort
  20379. } = provideSort({
  20380. sortBy,
  20381. multiSort,
  20382. mustSort,
  20383. page
  20384. });
  20385. const {
  20386. opened,
  20387. isGroupOpen,
  20388. toggleGroup,
  20389. extractRows
  20390. } = provideGroupBy({
  20391. groupBy,
  20392. sortBy,
  20393. disableSort
  20394. });
  20395. const {
  20396. pageCount,
  20397. setItemsPerPage
  20398. } = providePagination({
  20399. page,
  20400. itemsPerPage,
  20401. itemsLength
  20402. });
  20403. const {
  20404. flatItems
  20405. } = useGroupedItems(items, groupBy, opened);
  20406. const {
  20407. isSelected,
  20408. select,
  20409. selectAll,
  20410. toggleSelect,
  20411. someSelected,
  20412. allSelected
  20413. } = provideSelection(props, {
  20414. allItems: items,
  20415. currentPage: items
  20416. });
  20417. const {
  20418. isExpanded,
  20419. toggleExpand
  20420. } = provideExpanded(props);
  20421. const itemsWithoutGroups = computed(() => extractRows(items.value));
  20422. useOptions({
  20423. page,
  20424. itemsPerPage,
  20425. sortBy,
  20426. groupBy,
  20427. search: toRef(props, 'search')
  20428. });
  20429. provide('v-data-table', {
  20430. toggleSort,
  20431. sortBy
  20432. });
  20433. provideDefaults({
  20434. VDataTableRows: {
  20435. hideNoData: toRef(props, 'hideNoData'),
  20436. noDataText: toRef(props, 'noDataText'),
  20437. loading: toRef(props, 'loading'),
  20438. loadingText: toRef(props, 'loadingText')
  20439. }
  20440. });
  20441. const slotProps = computed(() => ({
  20442. page: page.value,
  20443. itemsPerPage: itemsPerPage.value,
  20444. sortBy: sortBy.value,
  20445. pageCount: pageCount.value,
  20446. toggleSort,
  20447. setItemsPerPage,
  20448. someSelected: someSelected.value,
  20449. allSelected: allSelected.value,
  20450. isSelected,
  20451. select,
  20452. selectAll,
  20453. toggleSelect,
  20454. isExpanded,
  20455. toggleExpand,
  20456. isGroupOpen,
  20457. toggleGroup,
  20458. items: itemsWithoutGroups.value.map(item => item.raw),
  20459. internalItems: itemsWithoutGroups.value,
  20460. groupedItems: flatItems.value,
  20461. columns: columns.value,
  20462. headers: headers.value
  20463. }));
  20464. useRender(() => {
  20465. const dataTableFooterProps = VDataTableFooter.filterProps(props);
  20466. const dataTableHeadersProps = VDataTableHeaders.filterProps(props);
  20467. const dataTableRowsProps = VDataTableRows.filterProps(props);
  20468. const tableProps = VTable.filterProps(props);
  20469. return createVNode(VTable, mergeProps({
  20470. "class": ['v-data-table', {
  20471. 'v-data-table--loading': props.loading
  20472. }, props.class],
  20473. "style": props.style
  20474. }, tableProps), {
  20475. top: () => slots.top?.(slotProps.value),
  20476. default: () => slots.default ? slots.default(slotProps.value) : createVNode(Fragment, null, [slots.colgroup?.(slotProps.value), !props.hideDefaultHeader && createVNode("thead", {
  20477. "key": "thead",
  20478. "class": "v-data-table__thead",
  20479. "role": "rowgroup"
  20480. }, [createVNode(VDataTableHeaders, mergeProps(dataTableHeadersProps, {
  20481. "sticky": props.fixedHeader
  20482. }), slots)]), slots.thead?.(slotProps.value), !props.hideDefaultBody && createVNode("tbody", {
  20483. "class": "v-data-table__tbody",
  20484. "role": "rowgroup"
  20485. }, [slots['body.prepend']?.(slotProps.value), slots.body ? slots.body(slotProps.value) : createVNode(VDataTableRows, mergeProps(attrs, dataTableRowsProps, {
  20486. "items": flatItems.value
  20487. }), slots), slots['body.append']?.(slotProps.value)]), slots.tbody?.(slotProps.value), slots.tfoot?.(slotProps.value)]),
  20488. bottom: () => slots.bottom ? slots.bottom(slotProps.value) : !props.hideDefaultFooter && createVNode(Fragment, null, [createVNode(VDivider, null, null), createVNode(VDataTableFooter, dataTableFooterProps, {
  20489. prepend: slots['footer.prepend']
  20490. })])
  20491. });
  20492. });
  20493. }
  20494. });
  20495. const makeVContainerProps = propsFactory({
  20496. fluid: {
  20497. type: Boolean,
  20498. default: false
  20499. },
  20500. ...makeComponentProps(),
  20501. ...makeDimensionProps(),
  20502. ...makeTagProps()
  20503. }, 'VContainer');
  20504. const VContainer = genericComponent()({
  20505. name: 'VContainer',
  20506. props: makeVContainerProps(),
  20507. setup(props, _ref) {
  20508. let {
  20509. slots
  20510. } = _ref;
  20511. const {
  20512. rtlClasses
  20513. } = useRtl();
  20514. const {
  20515. dimensionStyles
  20516. } = useDimension(props);
  20517. useRender(() => createVNode(props.tag, {
  20518. "class": ['v-container', {
  20519. 'v-container--fluid': props.fluid
  20520. }, rtlClasses.value, props.class],
  20521. "style": [dimensionStyles.value, props.style]
  20522. }, slots));
  20523. return {};
  20524. }
  20525. });
  20526. // Styles
  20527. // Types
  20528. const breakpointProps = (() => {
  20529. return breakpoints.reduce((props, val) => {
  20530. props[val] = {
  20531. type: [Boolean, String, Number],
  20532. default: false
  20533. };
  20534. return props;
  20535. }, {});
  20536. })();
  20537. const offsetProps = (() => {
  20538. return breakpoints.reduce((props, val) => {
  20539. const offsetKey = 'offset' + capitalize(val);
  20540. props[offsetKey] = {
  20541. type: [String, Number],
  20542. default: null
  20543. };
  20544. return props;
  20545. }, {});
  20546. })();
  20547. const orderProps = (() => {
  20548. return breakpoints.reduce((props, val) => {
  20549. const orderKey = 'order' + capitalize(val);
  20550. props[orderKey] = {
  20551. type: [String, Number],
  20552. default: null
  20553. };
  20554. return props;
  20555. }, {});
  20556. })();
  20557. const propMap$1 = {
  20558. col: Object.keys(breakpointProps),
  20559. offset: Object.keys(offsetProps),
  20560. order: Object.keys(orderProps)
  20561. };
  20562. function breakpointClass$1(type, prop, val) {
  20563. let className = type;
  20564. if (val == null || val === false) {
  20565. return undefined;
  20566. }
  20567. if (prop) {
  20568. const breakpoint = prop.replace(type, '');
  20569. className += `-${breakpoint}`;
  20570. }
  20571. if (type === 'col') {
  20572. className = 'v-' + className;
  20573. }
  20574. // Handling the boolean style prop when accepting [Boolean, String, Number]
  20575. // means Vue will not convert <v-col sm></v-col> to sm: true for us.
  20576. // Since the default is false, an empty string indicates the prop's presence.
  20577. if (type === 'col' && (val === '' || val === true)) {
  20578. // .v-col-md
  20579. return className.toLowerCase();
  20580. }
  20581. // .order-md-6
  20582. className += `-${val}`;
  20583. return className.toLowerCase();
  20584. }
  20585. const ALIGN_SELF_VALUES = ['auto', 'start', 'end', 'center', 'baseline', 'stretch'];
  20586. const makeVColProps = propsFactory({
  20587. cols: {
  20588. type: [Boolean, String, Number],
  20589. default: false
  20590. },
  20591. ...breakpointProps,
  20592. offset: {
  20593. type: [String, Number],
  20594. default: null
  20595. },
  20596. ...offsetProps,
  20597. order: {
  20598. type: [String, Number],
  20599. default: null
  20600. },
  20601. ...orderProps,
  20602. alignSelf: {
  20603. type: String,
  20604. default: null,
  20605. validator: str => ALIGN_SELF_VALUES.includes(str)
  20606. },
  20607. ...makeComponentProps(),
  20608. ...makeTagProps()
  20609. }, 'VCol');
  20610. const VCol = genericComponent()({
  20611. name: 'VCol',
  20612. props: makeVColProps(),
  20613. setup(props, _ref) {
  20614. let {
  20615. slots
  20616. } = _ref;
  20617. const classes = computed(() => {
  20618. const classList = [];
  20619. // Loop through `col`, `offset`, `order` breakpoint props
  20620. let type;
  20621. for (type in propMap$1) {
  20622. propMap$1[type].forEach(prop => {
  20623. const value = props[prop];
  20624. const className = breakpointClass$1(type, prop, value);
  20625. if (className) classList.push(className);
  20626. });
  20627. }
  20628. const hasColClasses = classList.some(className => className.startsWith('v-col-'));
  20629. classList.push({
  20630. // Default to .v-col if no other col-{bp}-* classes generated nor `cols` specified.
  20631. 'v-col': !hasColClasses || !props.cols,
  20632. [`v-col-${props.cols}`]: props.cols,
  20633. [`offset-${props.offset}`]: props.offset,
  20634. [`order-${props.order}`]: props.order,
  20635. [`align-self-${props.alignSelf}`]: props.alignSelf
  20636. });
  20637. return classList;
  20638. });
  20639. return () => h(props.tag, {
  20640. class: [classes.value, props.class],
  20641. style: props.style
  20642. }, slots.default?.());
  20643. }
  20644. });
  20645. // Styles
  20646. // Types
  20647. const ALIGNMENT = ['start', 'end', 'center'];
  20648. const SPACE = ['space-between', 'space-around', 'space-evenly'];
  20649. function makeRowProps(prefix, def) {
  20650. return breakpoints.reduce((props, val) => {
  20651. const prefixKey = prefix + capitalize(val);
  20652. props[prefixKey] = def();
  20653. return props;
  20654. }, {});
  20655. }
  20656. const ALIGN_VALUES = [...ALIGNMENT, 'baseline', 'stretch'];
  20657. const alignValidator = str => ALIGN_VALUES.includes(str);
  20658. const alignProps = makeRowProps('align', () => ({
  20659. type: String,
  20660. default: null,
  20661. validator: alignValidator
  20662. }));
  20663. const JUSTIFY_VALUES = [...ALIGNMENT, ...SPACE];
  20664. const justifyValidator = str => JUSTIFY_VALUES.includes(str);
  20665. const justifyProps = makeRowProps('justify', () => ({
  20666. type: String,
  20667. default: null,
  20668. validator: justifyValidator
  20669. }));
  20670. const ALIGN_CONTENT_VALUES = [...ALIGNMENT, ...SPACE, 'stretch'];
  20671. const alignContentValidator = str => ALIGN_CONTENT_VALUES.includes(str);
  20672. const alignContentProps = makeRowProps('alignContent', () => ({
  20673. type: String,
  20674. default: null,
  20675. validator: alignContentValidator
  20676. }));
  20677. const propMap = {
  20678. align: Object.keys(alignProps),
  20679. justify: Object.keys(justifyProps),
  20680. alignContent: Object.keys(alignContentProps)
  20681. };
  20682. const classMap = {
  20683. align: 'align',
  20684. justify: 'justify',
  20685. alignContent: 'align-content'
  20686. };
  20687. function breakpointClass(type, prop, val) {
  20688. let className = classMap[type];
  20689. if (val == null) {
  20690. return undefined;
  20691. }
  20692. if (prop) {
  20693. // alignSm -> Sm
  20694. const breakpoint = prop.replace(type, '');
  20695. className += `-${breakpoint}`;
  20696. }
  20697. // .align-items-sm-center
  20698. className += `-${val}`;
  20699. return className.toLowerCase();
  20700. }
  20701. const makeVRowProps = propsFactory({
  20702. dense: Boolean,
  20703. noGutters: Boolean,
  20704. align: {
  20705. type: String,
  20706. default: null,
  20707. validator: alignValidator
  20708. },
  20709. ...alignProps,
  20710. justify: {
  20711. type: String,
  20712. default: null,
  20713. validator: justifyValidator
  20714. },
  20715. ...justifyProps,
  20716. alignContent: {
  20717. type: String,
  20718. default: null,
  20719. validator: alignContentValidator
  20720. },
  20721. ...alignContentProps,
  20722. ...makeComponentProps(),
  20723. ...makeTagProps()
  20724. }, 'VRow');
  20725. const VRow = genericComponent()({
  20726. name: 'VRow',
  20727. props: makeVRowProps(),
  20728. setup(props, _ref) {
  20729. let {
  20730. slots
  20731. } = _ref;
  20732. const classes = computed(() => {
  20733. const classList = [];
  20734. // Loop through `align`, `justify`, `alignContent` breakpoint props
  20735. let type;
  20736. for (type in propMap) {
  20737. propMap[type].forEach(prop => {
  20738. const value = props[prop];
  20739. const className = breakpointClass(type, prop, value);
  20740. if (className) classList.push(className);
  20741. });
  20742. }
  20743. classList.push({
  20744. 'v-row--no-gutters': props.noGutters,
  20745. 'v-row--dense': props.dense,
  20746. [`align-${props.align}`]: props.align,
  20747. [`justify-${props.justify}`]: props.justify,
  20748. [`align-content-${props.alignContent}`]: props.alignContent
  20749. });
  20750. return classList;
  20751. });
  20752. return () => h(props.tag, {
  20753. class: ['v-row', classes.value, props.class],
  20754. style: props.style
  20755. }, slots.default?.());
  20756. }
  20757. });
  20758. // Styles
  20759. const VSpacer = createSimpleFunctional('v-spacer', 'div', 'VSpacer');
  20760. // Types
  20761. const makeVDatePickerControlsProps = propsFactory({
  20762. active: {
  20763. type: [String, Array],
  20764. default: undefined
  20765. },
  20766. disabled: {
  20767. type: [Boolean, String, Array],
  20768. default: false
  20769. },
  20770. nextIcon: {
  20771. type: IconValue,
  20772. default: '$next'
  20773. },
  20774. prevIcon: {
  20775. type: IconValue,
  20776. default: '$prev'
  20777. },
  20778. modeIcon: {
  20779. type: IconValue,
  20780. default: '$subgroup'
  20781. },
  20782. text: String,
  20783. viewMode: {
  20784. type: String,
  20785. default: 'month'
  20786. }
  20787. }, 'VDatePickerControls');
  20788. const VDatePickerControls = genericComponent()({
  20789. name: 'VDatePickerControls',
  20790. props: makeVDatePickerControlsProps(),
  20791. emits: {
  20792. 'click:year': () => true,
  20793. 'click:month': () => true,
  20794. 'click:prev': () => true,
  20795. 'click:next': () => true,
  20796. 'click:text': () => true
  20797. },
  20798. setup(props, _ref) {
  20799. let {
  20800. emit
  20801. } = _ref;
  20802. const disableMonth = computed(() => {
  20803. return Array.isArray(props.disabled) ? props.disabled.includes('text') : !!props.disabled;
  20804. });
  20805. const disableYear = computed(() => {
  20806. return Array.isArray(props.disabled) ? props.disabled.includes('mode') : !!props.disabled;
  20807. });
  20808. const disablePrev = computed(() => {
  20809. return Array.isArray(props.disabled) ? props.disabled.includes('prev') : !!props.disabled;
  20810. });
  20811. const disableNext = computed(() => {
  20812. return Array.isArray(props.disabled) ? props.disabled.includes('next') : !!props.disabled;
  20813. });
  20814. function onClickPrev() {
  20815. emit('click:prev');
  20816. }
  20817. function onClickNext() {
  20818. emit('click:next');
  20819. }
  20820. function onClickYear() {
  20821. emit('click:year');
  20822. }
  20823. function onClickMonth() {
  20824. emit('click:month');
  20825. }
  20826. useRender(() => {
  20827. // TODO: add slot support and scope defaults
  20828. return createVNode("div", {
  20829. "class": ['v-date-picker-controls']
  20830. }, [createVNode(VBtn, {
  20831. "class": "v-date-picker-controls__month-btn",
  20832. "disabled": disableMonth.value,
  20833. "text": props.text,
  20834. "variant": "text",
  20835. "rounded": true,
  20836. "onClick": onClickMonth
  20837. }, null), createVNode(VBtn, {
  20838. "key": "mode-btn",
  20839. "class": "v-date-picker-controls__mode-btn",
  20840. "disabled": disableYear.value,
  20841. "density": "comfortable",
  20842. "icon": props.modeIcon,
  20843. "variant": "text",
  20844. "onClick": onClickYear
  20845. }, null), createVNode(VSpacer, {
  20846. "key": "mode-spacer"
  20847. }, null), createVNode("div", {
  20848. "key": "month-buttons",
  20849. "class": "v-date-picker-controls__month"
  20850. }, [createVNode(VBtn, {
  20851. "disabled": disablePrev.value,
  20852. "icon": props.prevIcon,
  20853. "variant": "text",
  20854. "onClick": onClickPrev
  20855. }, null), createVNode(VBtn, {
  20856. "disabled": disableNext.value,
  20857. "icon": props.nextIcon,
  20858. "variant": "text",
  20859. "onClick": onClickNext
  20860. }, null)])]);
  20861. });
  20862. return {};
  20863. }
  20864. });
  20865. // Types
  20866. const makeVDatePickerHeaderProps = propsFactory({
  20867. appendIcon: IconValue,
  20868. color: String,
  20869. header: String,
  20870. transition: String,
  20871. onClick: EventProp()
  20872. }, 'VDatePickerHeader');
  20873. const VDatePickerHeader = genericComponent()({
  20874. name: 'VDatePickerHeader',
  20875. props: makeVDatePickerHeaderProps(),
  20876. emits: {
  20877. click: () => true,
  20878. 'click:append': () => true
  20879. },
  20880. setup(props, _ref) {
  20881. let {
  20882. emit,
  20883. slots
  20884. } = _ref;
  20885. const {
  20886. backgroundColorClasses,
  20887. backgroundColorStyles
  20888. } = useBackgroundColor(props, 'color');
  20889. function onClick() {
  20890. emit('click');
  20891. }
  20892. function onClickAppend() {
  20893. emit('click:append');
  20894. }
  20895. useRender(() => {
  20896. const hasContent = !!(slots.default || props.header);
  20897. const hasAppend = !!(slots.append || props.appendIcon);
  20898. return createVNode("div", {
  20899. "class": ['v-date-picker-header', {
  20900. 'v-date-picker-header--clickable': !!props.onClick
  20901. }, backgroundColorClasses.value],
  20902. "style": backgroundColorStyles.value,
  20903. "onClick": onClick
  20904. }, [slots.prepend && createVNode("div", {
  20905. "key": "prepend",
  20906. "class": "v-date-picker-header__prepend"
  20907. }, [slots.prepend()]), hasContent && createVNode(MaybeTransition, {
  20908. "key": "content",
  20909. "name": props.transition
  20910. }, {
  20911. default: () => [createVNode("div", {
  20912. "key": props.header,
  20913. "class": "v-date-picker-header__content"
  20914. }, [slots.default?.() ?? props.header])]
  20915. }), hasAppend && createVNode("div", {
  20916. "class": "v-date-picker-header__append"
  20917. }, [!slots.append ? createVNode(VBtn, {
  20918. "key": "append-btn",
  20919. "icon": props.appendIcon,
  20920. "variant": "text",
  20921. "onClick": onClickAppend
  20922. }, null) : createVNode(VDefaultsProvider, {
  20923. "key": "append-defaults",
  20924. "disabled": !props.appendIcon,
  20925. "defaults": {
  20926. VBtn: {
  20927. icon: props.appendIcon,
  20928. variant: 'text'
  20929. }
  20930. }
  20931. }, {
  20932. default: () => [slots.append?.()]
  20933. })])]);
  20934. });
  20935. return {};
  20936. }
  20937. });
  20938. // Composables
  20939. // Types
  20940. // Types
  20941. // Composables
  20942. const makeCalendarProps = propsFactory({
  20943. allowedDates: [Array, Function],
  20944. disabled: Boolean,
  20945. displayValue: null,
  20946. modelValue: Array,
  20947. month: [Number, String],
  20948. max: null,
  20949. min: null,
  20950. showAdjacentMonths: Boolean,
  20951. year: [Number, String],
  20952. weekdays: {
  20953. type: Array,
  20954. default: () => [0, 1, 2, 3, 4, 5, 6]
  20955. },
  20956. weeksInMonth: {
  20957. type: String,
  20958. default: 'dynamic'
  20959. },
  20960. firstDayOfWeek: [Number, String]
  20961. }, 'calendar');
  20962. function useCalendar(props) {
  20963. const adapter = useDate();
  20964. const model = useProxiedModel(props, 'modelValue', [], v => wrapInArray(v));
  20965. const displayValue = computed(() => {
  20966. if (props.displayValue) return adapter.date(props.displayValue);
  20967. if (model.value.length > 0) return adapter.date(model.value[0]);
  20968. if (props.min) return adapter.date(props.min);
  20969. if (Array.isArray(props.allowedDates)) return adapter.date(props.allowedDates[0]);
  20970. return adapter.date();
  20971. });
  20972. const year = useProxiedModel(props, 'year', undefined, v => {
  20973. const value = v != null ? Number(v) : adapter.getYear(displayValue.value);
  20974. return adapter.startOfYear(adapter.setYear(adapter.date(), value));
  20975. }, v => adapter.getYear(v));
  20976. const month = useProxiedModel(props, 'month', undefined, v => {
  20977. const value = v != null ? Number(v) : adapter.getMonth(displayValue.value);
  20978. const date = adapter.setYear(adapter.startOfMonth(adapter.date()), adapter.getYear(year.value));
  20979. return adapter.setMonth(date, value);
  20980. }, v => adapter.getMonth(v));
  20981. const weekDays = computed(() => {
  20982. const firstDayOfWeek = Number(props.firstDayOfWeek ?? 0);
  20983. return props.weekdays.map(day => (day + firstDayOfWeek) % 7);
  20984. });
  20985. const weeksInMonth = computed(() => {
  20986. const weeks = adapter.getWeekArray(month.value, props.firstDayOfWeek);
  20987. const days = weeks.flat();
  20988. // Make sure there's always 6 weeks in month (6 * 7 days)
  20989. // if weeksInMonth is 'static'
  20990. const daysInMonth = 6 * 7;
  20991. if (props.weeksInMonth === 'static' && days.length < daysInMonth) {
  20992. const lastDay = days[days.length - 1];
  20993. let week = [];
  20994. for (let day = 1; day <= daysInMonth - days.length; day++) {
  20995. week.push(adapter.addDays(lastDay, day));
  20996. if (day % 7 === 0) {
  20997. weeks.push(week);
  20998. week = [];
  20999. }
  21000. }
  21001. }
  21002. return weeks;
  21003. });
  21004. function genDays(days, today) {
  21005. return days.filter(date => {
  21006. return weekDays.value.includes(adapter.toJsDate(date).getDay());
  21007. }).map((date, index) => {
  21008. const isoDate = adapter.toISO(date);
  21009. const isAdjacent = !adapter.isSameMonth(date, month.value);
  21010. const isStart = adapter.isSameDay(date, adapter.startOfMonth(month.value));
  21011. const isEnd = adapter.isSameDay(date, adapter.endOfMonth(month.value));
  21012. const isSame = adapter.isSameDay(date, month.value);
  21013. return {
  21014. date,
  21015. isoDate,
  21016. formatted: adapter.format(date, 'keyboardDate'),
  21017. year: adapter.getYear(date),
  21018. month: adapter.getMonth(date),
  21019. isDisabled: isDisabled(date),
  21020. isWeekStart: index % 7 === 0,
  21021. isWeekEnd: index % 7 === 6,
  21022. isToday: adapter.isSameDay(date, today),
  21023. isAdjacent,
  21024. isHidden: isAdjacent && !props.showAdjacentMonths,
  21025. isStart,
  21026. isSelected: model.value.some(value => adapter.isSameDay(date, value)),
  21027. isEnd,
  21028. isSame,
  21029. localized: adapter.format(date, 'dayOfMonth')
  21030. };
  21031. });
  21032. }
  21033. const daysInWeek = computed(() => {
  21034. const lastDay = adapter.startOfWeek(displayValue.value, props.firstDayOfWeek);
  21035. const week = [];
  21036. for (let day = 0; day <= 6; day++) {
  21037. week.push(adapter.addDays(lastDay, day));
  21038. }
  21039. const today = adapter.date();
  21040. return genDays(week, today);
  21041. });
  21042. const daysInMonth = computed(() => {
  21043. const days = weeksInMonth.value.flat();
  21044. const today = adapter.date();
  21045. return genDays(days, today);
  21046. });
  21047. const weekNumbers = computed(() => {
  21048. return weeksInMonth.value.map(week => {
  21049. return week.length ? getWeek(adapter, week[0]) : null;
  21050. });
  21051. });
  21052. function isDisabled(value) {
  21053. if (props.disabled) return true;
  21054. const date = adapter.date(value);
  21055. if (props.min && adapter.isAfter(adapter.date(props.min), date)) return true;
  21056. if (props.max && adapter.isAfter(date, adapter.date(props.max))) return true;
  21057. if (Array.isArray(props.allowedDates) && props.allowedDates.length > 0) {
  21058. return !props.allowedDates.some(d => adapter.isSameDay(adapter.date(d), date));
  21059. }
  21060. if (typeof props.allowedDates === 'function') {
  21061. return !props.allowedDates(date);
  21062. }
  21063. return false;
  21064. }
  21065. return {
  21066. displayValue,
  21067. daysInMonth,
  21068. daysInWeek,
  21069. genDays,
  21070. model,
  21071. weeksInMonth,
  21072. weekDays,
  21073. weekNumbers
  21074. };
  21075. }
  21076. // Types
  21077. const makeVDatePickerMonthProps = propsFactory({
  21078. color: String,
  21079. hideWeekdays: Boolean,
  21080. multiple: [Boolean, Number, String],
  21081. showWeek: Boolean,
  21082. transition: {
  21083. type: String,
  21084. default: 'picker-transition'
  21085. },
  21086. reverseTransition: {
  21087. type: String,
  21088. default: 'picker-reverse-transition'
  21089. },
  21090. ...makeCalendarProps()
  21091. }, 'VDatePickerMonth');
  21092. const VDatePickerMonth = genericComponent()({
  21093. name: 'VDatePickerMonth',
  21094. props: makeVDatePickerMonthProps(),
  21095. emits: {
  21096. 'update:modelValue': date => true,
  21097. 'update:month': date => true,
  21098. 'update:year': date => true
  21099. },
  21100. setup(props, _ref) {
  21101. let {
  21102. emit,
  21103. slots
  21104. } = _ref;
  21105. const daysRef = ref();
  21106. const {
  21107. daysInMonth,
  21108. model,
  21109. weekNumbers
  21110. } = useCalendar(props);
  21111. const adapter = useDate();
  21112. const rangeStart = shallowRef();
  21113. const rangeStop = shallowRef();
  21114. const isReverse = shallowRef(false);
  21115. const transition = computed(() => {
  21116. return !isReverse.value ? props.transition : props.reverseTransition;
  21117. });
  21118. if (props.multiple === 'range' && model.value.length > 0) {
  21119. rangeStart.value = model.value[0];
  21120. if (model.value.length > 1) {
  21121. rangeStop.value = model.value[model.value.length - 1];
  21122. }
  21123. }
  21124. const atMax = computed(() => {
  21125. const max = ['number', 'string'].includes(typeof props.multiple) ? Number(props.multiple) : Infinity;
  21126. return model.value.length >= max;
  21127. });
  21128. watch(daysInMonth, (val, oldVal) => {
  21129. if (!oldVal) return;
  21130. isReverse.value = adapter.isBefore(val[0].date, oldVal[0].date);
  21131. });
  21132. function onRangeClick(value) {
  21133. const _value = adapter.startOfDay(value);
  21134. if (model.value.length === 0) {
  21135. rangeStart.value = undefined;
  21136. } else if (model.value.length === 1) {
  21137. rangeStart.value = model.value[0];
  21138. rangeStop.value = undefined;
  21139. }
  21140. if (!rangeStart.value) {
  21141. rangeStart.value = _value;
  21142. model.value = [rangeStart.value];
  21143. } else if (!rangeStop.value) {
  21144. if (adapter.isSameDay(_value, rangeStart.value)) {
  21145. rangeStart.value = undefined;
  21146. model.value = [];
  21147. return;
  21148. } else if (adapter.isBefore(_value, rangeStart.value)) {
  21149. rangeStop.value = adapter.endOfDay(rangeStart.value);
  21150. rangeStart.value = _value;
  21151. } else {
  21152. rangeStop.value = adapter.endOfDay(_value);
  21153. }
  21154. const diff = adapter.getDiff(rangeStop.value, rangeStart.value, 'days');
  21155. const datesInRange = [rangeStart.value];
  21156. for (let i = 1; i < diff; i++) {
  21157. const nextDate = adapter.addDays(rangeStart.value, i);
  21158. datesInRange.push(nextDate);
  21159. }
  21160. datesInRange.push(rangeStop.value);
  21161. model.value = datesInRange;
  21162. } else {
  21163. rangeStart.value = value;
  21164. rangeStop.value = undefined;
  21165. model.value = [rangeStart.value];
  21166. }
  21167. }
  21168. function onMultipleClick(value) {
  21169. const index = model.value.findIndex(selection => adapter.isSameDay(selection, value));
  21170. if (index === -1) {
  21171. model.value = [...model.value, value];
  21172. } else {
  21173. const value = [...model.value];
  21174. value.splice(index, 1);
  21175. model.value = value;
  21176. }
  21177. }
  21178. function onClick(value) {
  21179. if (props.multiple === 'range') {
  21180. onRangeClick(value);
  21181. } else if (props.multiple) {
  21182. onMultipleClick(value);
  21183. } else {
  21184. model.value = [value];
  21185. }
  21186. }
  21187. return () => createVNode("div", {
  21188. "class": "v-date-picker-month"
  21189. }, [props.showWeek && createVNode("div", {
  21190. "key": "weeks",
  21191. "class": "v-date-picker-month__weeks"
  21192. }, [!props.hideWeekdays && createVNode("div", {
  21193. "key": "hide-week-days",
  21194. "class": "v-date-picker-month__day"
  21195. }, [createTextVNode("\xA0")]), weekNumbers.value.map(week => createVNode("div", {
  21196. "class": ['v-date-picker-month__day', 'v-date-picker-month__day--adjacent']
  21197. }, [week]))]), createVNode(MaybeTransition, {
  21198. "name": transition.value
  21199. }, {
  21200. default: () => [createVNode("div", {
  21201. "ref": daysRef,
  21202. "key": daysInMonth.value[0].date?.toString(),
  21203. "class": "v-date-picker-month__days"
  21204. }, [!props.hideWeekdays && adapter.getWeekdays(props.firstDayOfWeek).map(weekDay => createVNode("div", {
  21205. "class": ['v-date-picker-month__day', 'v-date-picker-month__weekday']
  21206. }, [weekDay])), daysInMonth.value.map((item, i) => {
  21207. const slotProps = {
  21208. props: {
  21209. onClick: () => onClick(item.date)
  21210. },
  21211. item,
  21212. i
  21213. };
  21214. if (atMax.value && !item.isSelected) {
  21215. item.isDisabled = true;
  21216. }
  21217. return createVNode("div", {
  21218. "class": ['v-date-picker-month__day', {
  21219. 'v-date-picker-month__day--adjacent': item.isAdjacent,
  21220. 'v-date-picker-month__day--hide-adjacent': item.isHidden,
  21221. 'v-date-picker-month__day--selected': item.isSelected,
  21222. 'v-date-picker-month__day--week-end': item.isWeekEnd,
  21223. 'v-date-picker-month__day--week-start': item.isWeekStart
  21224. }],
  21225. "data-v-date": !item.isDisabled ? item.isoDate : undefined
  21226. }, [(props.showAdjacentMonths || !item.isAdjacent) && createVNode(VDefaultsProvider, {
  21227. "defaults": {
  21228. VBtn: {
  21229. class: 'v-date-picker-month__day-btn',
  21230. color: (item.isSelected || item.isToday) && !item.isDisabled ? props.color : undefined,
  21231. disabled: item.isDisabled,
  21232. icon: true,
  21233. ripple: false,
  21234. text: item.localized,
  21235. variant: item.isDisabled ? item.isToday ? 'outlined' : 'text' : item.isToday && !item.isSelected ? 'outlined' : 'flat',
  21236. onClick: () => onClick(item.date)
  21237. }
  21238. }
  21239. }, {
  21240. default: () => [slots.day?.(slotProps) ?? createVNode(VBtn, slotProps.props, null)]
  21241. })]);
  21242. })])]
  21243. })]);
  21244. }
  21245. });
  21246. // Types
  21247. const makeVDatePickerMonthsProps = propsFactory({
  21248. color: String,
  21249. height: [String, Number],
  21250. min: null,
  21251. max: null,
  21252. modelValue: Number,
  21253. year: Number
  21254. }, 'VDatePickerMonths');
  21255. const VDatePickerMonths = genericComponent()({
  21256. name: 'VDatePickerMonths',
  21257. props: makeVDatePickerMonthsProps(),
  21258. emits: {
  21259. 'update:modelValue': date => true
  21260. },
  21261. setup(props, _ref) {
  21262. let {
  21263. emit,
  21264. slots
  21265. } = _ref;
  21266. const adapter = useDate();
  21267. const model = useProxiedModel(props, 'modelValue');
  21268. const months = computed(() => {
  21269. let date = adapter.startOfYear(adapter.date());
  21270. if (props.year) {
  21271. date = adapter.setYear(date, props.year);
  21272. }
  21273. return createRange(12).map(i => {
  21274. const text = adapter.format(date, 'monthShort');
  21275. const isDisabled = !!(props.min && adapter.isAfter(adapter.startOfMonth(adapter.date(props.min)), date) || props.max && adapter.isAfter(date, adapter.startOfMonth(adapter.date(props.max))));
  21276. date = adapter.getNextMonth(date);
  21277. return {
  21278. isDisabled,
  21279. text,
  21280. value: i
  21281. };
  21282. });
  21283. });
  21284. watchEffect(() => {
  21285. model.value = model.value ?? adapter.getMonth(adapter.date());
  21286. });
  21287. useRender(() => createVNode("div", {
  21288. "class": "v-date-picker-months",
  21289. "style": {
  21290. height: convertToUnit(props.height)
  21291. }
  21292. }, [createVNode("div", {
  21293. "class": "v-date-picker-months__content"
  21294. }, [months.value.map((month, i) => {
  21295. const btnProps = {
  21296. active: model.value === i,
  21297. color: model.value === i ? props.color : undefined,
  21298. disabled: month.isDisabled,
  21299. rounded: true,
  21300. text: month.text,
  21301. variant: model.value === month.value ? 'flat' : 'text',
  21302. onClick: () => onClick(i)
  21303. };
  21304. function onClick(i) {
  21305. if (model.value === i) {
  21306. emit('update:modelValue', model.value);
  21307. return;
  21308. }
  21309. model.value = i;
  21310. }
  21311. return slots.month?.({
  21312. month,
  21313. i,
  21314. props: btnProps
  21315. }) ?? createVNode(VBtn, mergeProps({
  21316. "key": "month"
  21317. }, btnProps), null);
  21318. })])]));
  21319. return {};
  21320. }
  21321. });
  21322. // Types
  21323. // Types
  21324. const makeVDatePickerYearsProps = propsFactory({
  21325. color: String,
  21326. height: [String, Number],
  21327. min: null,
  21328. max: null,
  21329. modelValue: Number
  21330. }, 'VDatePickerYears');
  21331. const VDatePickerYears = genericComponent()({
  21332. name: 'VDatePickerYears',
  21333. props: makeVDatePickerYearsProps(),
  21334. emits: {
  21335. 'update:modelValue': year => true
  21336. },
  21337. setup(props, _ref) {
  21338. let {
  21339. emit,
  21340. slots
  21341. } = _ref;
  21342. const adapter = useDate();
  21343. const model = useProxiedModel(props, 'modelValue');
  21344. const years = computed(() => {
  21345. const year = adapter.getYear(adapter.date());
  21346. let min = year - 100;
  21347. let max = year + 52;
  21348. if (props.min) {
  21349. min = adapter.getYear(adapter.date(props.min));
  21350. }
  21351. if (props.max) {
  21352. max = adapter.getYear(adapter.date(props.max));
  21353. }
  21354. let date = adapter.startOfYear(adapter.date());
  21355. date = adapter.setYear(date, min);
  21356. return createRange(max - min + 1, min).map(i => {
  21357. const text = adapter.format(date, 'year');
  21358. date = adapter.setYear(date, adapter.getYear(date) + 1);
  21359. return {
  21360. text,
  21361. value: i
  21362. };
  21363. });
  21364. });
  21365. watchEffect(() => {
  21366. model.value = model.value ?? adapter.getYear(adapter.date());
  21367. });
  21368. const yearRef = templateRef();
  21369. onMounted(async () => {
  21370. await nextTick();
  21371. yearRef.el?.scrollIntoView({
  21372. block: 'center'
  21373. });
  21374. });
  21375. useRender(() => createVNode("div", {
  21376. "class": "v-date-picker-years",
  21377. "style": {
  21378. height: convertToUnit(props.height)
  21379. }
  21380. }, [createVNode("div", {
  21381. "class": "v-date-picker-years__content"
  21382. }, [years.value.map((year, i) => {
  21383. const btnProps = {
  21384. ref: model.value === year.value ? yearRef : undefined,
  21385. active: model.value === year.value,
  21386. color: model.value === year.value ? props.color : undefined,
  21387. rounded: true,
  21388. text: year.text,
  21389. variant: model.value === year.value ? 'flat' : 'text',
  21390. onClick: () => {
  21391. if (model.value === year.value) {
  21392. emit('update:modelValue', model.value);
  21393. return;
  21394. }
  21395. model.value = year.value;
  21396. }
  21397. };
  21398. return slots.year?.({
  21399. year,
  21400. i,
  21401. props: btnProps
  21402. }) ?? createVNode(VBtn, mergeProps({
  21403. "key": "month"
  21404. }, btnProps), null);
  21405. })])]));
  21406. return {};
  21407. }
  21408. });
  21409. // Utilities
  21410. const VPickerTitle = createSimpleFunctional('v-picker-title');
  21411. // Types
  21412. const makeVPickerProps = propsFactory({
  21413. bgColor: String,
  21414. landscape: Boolean,
  21415. title: String,
  21416. hideHeader: Boolean,
  21417. ...makeVSheetProps()
  21418. }, 'VPicker');
  21419. const VPicker = genericComponent()({
  21420. name: 'VPicker',
  21421. props: makeVPickerProps(),
  21422. setup(props, _ref) {
  21423. let {
  21424. slots
  21425. } = _ref;
  21426. const {
  21427. backgroundColorClasses,
  21428. backgroundColorStyles
  21429. } = useBackgroundColor(toRef(props, 'color'));
  21430. useRender(() => {
  21431. const sheetProps = VSheet.filterProps(props);
  21432. const hasTitle = !!(props.title || slots.title);
  21433. return createVNode(VSheet, mergeProps(sheetProps, {
  21434. "color": props.bgColor,
  21435. "class": ['v-picker', {
  21436. 'v-picker--landscape': props.landscape,
  21437. 'v-picker--with-actions': !!slots.actions
  21438. }, props.class],
  21439. "style": props.style
  21440. }), {
  21441. default: () => [!props.hideHeader && createVNode("div", {
  21442. "key": "header",
  21443. "class": [backgroundColorClasses.value],
  21444. "style": [backgroundColorStyles.value]
  21445. }, [hasTitle && createVNode(VPickerTitle, {
  21446. "key": "picker-title"
  21447. }, {
  21448. default: () => [slots.title?.() ?? props.title]
  21449. }), slots.header && createVNode("div", {
  21450. "class": "v-picker__header"
  21451. }, [slots.header()])]), createVNode("div", {
  21452. "class": "v-picker__body"
  21453. }, [slots.default?.()]), slots.actions && createVNode(VDefaultsProvider, {
  21454. "defaults": {
  21455. VBtn: {
  21456. slim: true,
  21457. variant: 'text'
  21458. }
  21459. }
  21460. }, {
  21461. default: () => [createVNode("div", {
  21462. "class": "v-picker__actions"
  21463. }, [slots.actions()])]
  21464. })]
  21465. });
  21466. });
  21467. return {};
  21468. }
  21469. });
  21470. // Types
  21471. // Types
  21472. const makeVDatePickerProps = propsFactory({
  21473. // TODO: implement in v3.5
  21474. // calendarIcon: {
  21475. // type: String,
  21476. // default: '$calendar',
  21477. // },
  21478. // keyboardIcon: {
  21479. // type: String,
  21480. // default: '$edit',
  21481. // },
  21482. // inputMode: {
  21483. // type: String as PropType<'calendar' | 'keyboard'>,
  21484. // default: 'calendar',
  21485. // },
  21486. // inputText: {
  21487. // type: String,
  21488. // default: '$vuetify.datePicker.input.placeholder',
  21489. // },
  21490. // inputPlaceholder: {
  21491. // type: String,
  21492. // default: 'dd/mm/yyyy',
  21493. // },
  21494. header: {
  21495. type: String,
  21496. default: '$vuetify.datePicker.header'
  21497. },
  21498. ...makeVDatePickerControlsProps(),
  21499. ...makeVDatePickerMonthProps({
  21500. weeksInMonth: 'static'
  21501. }),
  21502. ...omit(makeVDatePickerMonthsProps(), ['modelValue']),
  21503. ...omit(makeVDatePickerYearsProps(), ['modelValue']),
  21504. ...makeVPickerProps({
  21505. title: '$vuetify.datePicker.title'
  21506. }),
  21507. modelValue: null
  21508. }, 'VDatePicker');
  21509. const VDatePicker = genericComponent()({
  21510. name: 'VDatePicker',
  21511. props: makeVDatePickerProps(),
  21512. emits: {
  21513. 'update:modelValue': date => true,
  21514. 'update:month': date => true,
  21515. 'update:year': date => true,
  21516. // 'update:inputMode': (date: any) => true,
  21517. 'update:viewMode': date => true
  21518. },
  21519. setup(props, _ref) {
  21520. let {
  21521. emit,
  21522. slots
  21523. } = _ref;
  21524. const adapter = useDate();
  21525. const {
  21526. t
  21527. } = useLocale();
  21528. const model = useProxiedModel(props, 'modelValue', undefined, v => wrapInArray(v), v => props.multiple ? v : v[0]);
  21529. const viewMode = useProxiedModel(props, 'viewMode');
  21530. // const inputMode = useProxiedModel(props, 'inputMode')
  21531. const internal = computed(() => {
  21532. const value = adapter.date(model.value?.[0]);
  21533. return value && adapter.isValid(value) ? value : adapter.date();
  21534. });
  21535. const month = ref(Number(props.month ?? adapter.getMonth(adapter.startOfMonth(internal.value))));
  21536. const year = ref(Number(props.year ?? adapter.getYear(adapter.startOfYear(adapter.setMonth(internal.value, month.value)))));
  21537. const isReversing = shallowRef(false);
  21538. const header = computed(() => {
  21539. if (props.multiple && model.value.length > 1) {
  21540. return t('$vuetify.datePicker.itemsSelected', model.value.length);
  21541. }
  21542. return model.value[0] && adapter.isValid(model.value[0]) ? adapter.format(adapter.date(model.value[0]), 'normalDateWithWeekday') : t(props.header);
  21543. });
  21544. const text = computed(() => {
  21545. let date = adapter.date();
  21546. date = adapter.setDate(date, 1);
  21547. date = adapter.setMonth(date, month.value);
  21548. date = adapter.setYear(date, year.value);
  21549. return adapter.format(date, 'monthAndYear');
  21550. });
  21551. // const headerIcon = computed(() => props.inputMode === 'calendar' ? props.keyboardIcon : props.calendarIcon)
  21552. const headerTransition = computed(() => `date-picker-header${isReversing.value ? '-reverse' : ''}-transition`);
  21553. const minDate = computed(() => {
  21554. const date = adapter.date(props.min);
  21555. return props.min && adapter.isValid(date) ? date : null;
  21556. });
  21557. const maxDate = computed(() => {
  21558. const date = adapter.date(props.max);
  21559. return props.max && adapter.isValid(date) ? date : null;
  21560. });
  21561. const disabled = computed(() => {
  21562. if (props.disabled) return true;
  21563. const targets = [];
  21564. if (viewMode.value !== 'month') {
  21565. targets.push(...['prev', 'next']);
  21566. } else {
  21567. let _date = adapter.date();
  21568. _date = adapter.setYear(_date, year.value);
  21569. _date = adapter.setMonth(_date, month.value);
  21570. if (minDate.value) {
  21571. const date = adapter.addDays(adapter.startOfMonth(_date), -1);
  21572. adapter.isAfter(minDate.value, date) && targets.push('prev');
  21573. }
  21574. if (maxDate.value) {
  21575. const date = adapter.addDays(adapter.endOfMonth(_date), 1);
  21576. adapter.isAfter(date, maxDate.value) && targets.push('next');
  21577. }
  21578. }
  21579. return targets;
  21580. });
  21581. // function onClickAppend () {
  21582. // inputMode.value = inputMode.value === 'calendar' ? 'keyboard' : 'calendar'
  21583. // }
  21584. function onClickNext() {
  21585. if (month.value < 11) {
  21586. month.value++;
  21587. } else {
  21588. year.value++;
  21589. month.value = 0;
  21590. onUpdateYear(year.value);
  21591. }
  21592. onUpdateMonth(month.value);
  21593. }
  21594. function onClickPrev() {
  21595. if (month.value > 0) {
  21596. month.value--;
  21597. } else {
  21598. year.value--;
  21599. month.value = 11;
  21600. onUpdateYear(year.value);
  21601. }
  21602. onUpdateMonth(month.value);
  21603. }
  21604. function onClickDate() {
  21605. viewMode.value = 'month';
  21606. }
  21607. function onClickMonth() {
  21608. viewMode.value = viewMode.value === 'months' ? 'month' : 'months';
  21609. }
  21610. function onClickYear() {
  21611. viewMode.value = viewMode.value === 'year' ? 'month' : 'year';
  21612. }
  21613. function onUpdateMonth(value) {
  21614. if (viewMode.value === 'months') onClickMonth();
  21615. emit('update:month', value);
  21616. }
  21617. function onUpdateYear(value) {
  21618. if (viewMode.value === 'year') onClickYear();
  21619. emit('update:year', value);
  21620. }
  21621. watch(model, (val, oldVal) => {
  21622. const arrBefore = wrapInArray(oldVal);
  21623. const arrAfter = wrapInArray(val);
  21624. if (!arrAfter.length) return;
  21625. const before = adapter.date(arrBefore[arrBefore.length - 1]);
  21626. const after = adapter.date(arrAfter[arrAfter.length - 1]);
  21627. const newMonth = adapter.getMonth(after);
  21628. const newYear = adapter.getYear(after);
  21629. if (newMonth !== month.value) {
  21630. month.value = newMonth;
  21631. onUpdateMonth(month.value);
  21632. }
  21633. if (newYear !== year.value) {
  21634. year.value = newYear;
  21635. onUpdateYear(year.value);
  21636. }
  21637. isReversing.value = adapter.isBefore(before, after);
  21638. });
  21639. useRender(() => {
  21640. const pickerProps = VPicker.filterProps(props);
  21641. const datePickerControlsProps = VDatePickerControls.filterProps(props);
  21642. const datePickerHeaderProps = VDatePickerHeader.filterProps(props);
  21643. const datePickerMonthProps = VDatePickerMonth.filterProps(props);
  21644. const datePickerMonthsProps = omit(VDatePickerMonths.filterProps(props), ['modelValue']);
  21645. const datePickerYearsProps = omit(VDatePickerYears.filterProps(props), ['modelValue']);
  21646. const headerProps = {
  21647. header: header.value,
  21648. transition: headerTransition.value
  21649. };
  21650. return createVNode(VPicker, mergeProps(pickerProps, {
  21651. "class": ['v-date-picker', `v-date-picker--${viewMode.value}`, {
  21652. 'v-date-picker--show-week': props.showWeek
  21653. }, props.class],
  21654. "style": props.style
  21655. }), {
  21656. title: () => slots.title?.() ?? createVNode("div", {
  21657. "class": "v-date-picker__title"
  21658. }, [t(props.title)]),
  21659. header: () => slots.header ? createVNode(VDefaultsProvider, {
  21660. "defaults": {
  21661. VDatePickerHeader: {
  21662. ...headerProps
  21663. }
  21664. }
  21665. }, {
  21666. default: () => [slots.header?.(headerProps)]
  21667. }) : createVNode(VDatePickerHeader, mergeProps({
  21668. "key": "header"
  21669. }, datePickerHeaderProps, headerProps, {
  21670. "onClick": viewMode.value !== 'month' ? onClickDate : undefined
  21671. }), {
  21672. ...slots,
  21673. default: undefined
  21674. }),
  21675. default: () => createVNode(Fragment, null, [createVNode(VDatePickerControls, mergeProps(datePickerControlsProps, {
  21676. "disabled": disabled.value,
  21677. "text": text.value,
  21678. "onClick:next": onClickNext,
  21679. "onClick:prev": onClickPrev,
  21680. "onClick:month": onClickMonth,
  21681. "onClick:year": onClickYear
  21682. }), null), createVNode(VFadeTransition, {
  21683. "hideOnLeave": true
  21684. }, {
  21685. default: () => [viewMode.value === 'months' ? createVNode(VDatePickerMonths, mergeProps({
  21686. "key": "date-picker-months"
  21687. }, datePickerMonthsProps, {
  21688. "modelValue": month.value,
  21689. "onUpdate:modelValue": [$event => month.value = $event, onUpdateMonth],
  21690. "min": minDate.value,
  21691. "max": maxDate.value,
  21692. "year": year.value
  21693. }), null) : viewMode.value === 'year' ? createVNode(VDatePickerYears, mergeProps({
  21694. "key": "date-picker-years"
  21695. }, datePickerYearsProps, {
  21696. "modelValue": year.value,
  21697. "onUpdate:modelValue": [$event => year.value = $event, onUpdateYear],
  21698. "min": minDate.value,
  21699. "max": maxDate.value
  21700. }), null) : createVNode(VDatePickerMonth, mergeProps({
  21701. "key": "date-picker-month"
  21702. }, datePickerMonthProps, {
  21703. "modelValue": model.value,
  21704. "onUpdate:modelValue": $event => model.value = $event,
  21705. "month": month.value,
  21706. "onUpdate:month": [$event => month.value = $event, onUpdateMonth],
  21707. "year": year.value,
  21708. "onUpdate:year": [$event => year.value = $event, onUpdateYear],
  21709. "min": minDate.value,
  21710. "max": maxDate.value
  21711. }), null)]
  21712. })]),
  21713. actions: slots.actions
  21714. });
  21715. });
  21716. return {};
  21717. }
  21718. });
  21719. // Types
  21720. // Types
  21721. const makeVEmptyStateProps = propsFactory({
  21722. actionText: String,
  21723. bgColor: String,
  21724. color: String,
  21725. icon: IconValue,
  21726. image: String,
  21727. justify: {
  21728. type: String,
  21729. default: 'center'
  21730. },
  21731. headline: String,
  21732. title: String,
  21733. text: String,
  21734. textWidth: {
  21735. type: [Number, String],
  21736. default: 500
  21737. },
  21738. href: String,
  21739. to: String,
  21740. ...makeComponentProps(),
  21741. ...makeDimensionProps(),
  21742. ...makeSizeProps({
  21743. size: undefined
  21744. }),
  21745. ...makeThemeProps()
  21746. }, 'VEmptyState');
  21747. const VEmptyState = genericComponent()({
  21748. name: 'VEmptyState',
  21749. props: makeVEmptyStateProps(),
  21750. emits: {
  21751. 'click:action': e => true
  21752. },
  21753. setup(props, _ref) {
  21754. let {
  21755. emit,
  21756. slots
  21757. } = _ref;
  21758. const {
  21759. themeClasses
  21760. } = provideTheme(props);
  21761. const {
  21762. backgroundColorClasses,
  21763. backgroundColorStyles
  21764. } = useBackgroundColor(toRef(props, 'bgColor'));
  21765. const {
  21766. dimensionStyles
  21767. } = useDimension(props);
  21768. const {
  21769. displayClasses
  21770. } = useDisplay();
  21771. function onClickAction(e) {
  21772. emit('click:action', e);
  21773. }
  21774. useRender(() => {
  21775. const hasActions = !!(slots.actions || props.actionText);
  21776. const hasHeadline = !!(slots.headline || props.headline);
  21777. const hasTitle = !!(slots.title || props.title);
  21778. const hasText = !!(slots.text || props.text);
  21779. const hasMedia = !!(slots.media || props.image || props.icon);
  21780. const size = props.size || (props.image ? 200 : 96);
  21781. return createVNode("div", {
  21782. "class": ['v-empty-state', {
  21783. [`v-empty-state--${props.justify}`]: true
  21784. }, themeClasses.value, backgroundColorClasses.value, displayClasses.value, props.class],
  21785. "style": [backgroundColorStyles.value, dimensionStyles.value, props.style]
  21786. }, [hasMedia && createVNode("div", {
  21787. "key": "media",
  21788. "class": "v-empty-state__media"
  21789. }, [!slots.media ? createVNode(Fragment, null, [props.image ? createVNode(VImg, {
  21790. "key": "image",
  21791. "src": props.image,
  21792. "height": size
  21793. }, null) : props.icon ? createVNode(VIcon, {
  21794. "key": "icon",
  21795. "color": props.color,
  21796. "size": size,
  21797. "icon": props.icon
  21798. }, null) : undefined]) : createVNode(VDefaultsProvider, {
  21799. "key": "media-defaults",
  21800. "defaults": {
  21801. VImg: {
  21802. src: props.image,
  21803. height: size
  21804. },
  21805. VIcon: {
  21806. size,
  21807. icon: props.icon
  21808. }
  21809. }
  21810. }, {
  21811. default: () => [slots.media()]
  21812. })]), hasHeadline && createVNode("div", {
  21813. "key": "headline",
  21814. "class": "v-empty-state__headline"
  21815. }, [slots.headline?.() ?? props.headline]), hasTitle && createVNode("div", {
  21816. "key": "title",
  21817. "class": "v-empty-state__title"
  21818. }, [slots.title?.() ?? props.title]), hasText && createVNode("div", {
  21819. "key": "text",
  21820. "class": "v-empty-state__text",
  21821. "style": {
  21822. maxWidth: convertToUnit(props.textWidth)
  21823. }
  21824. }, [slots.text?.() ?? props.text]), slots.default && createVNode("div", {
  21825. "key": "content",
  21826. "class": "v-empty-state__content"
  21827. }, [slots.default()]), hasActions && createVNode("div", {
  21828. "key": "actions",
  21829. "class": "v-empty-state__actions"
  21830. }, [createVNode(VDefaultsProvider, {
  21831. "defaults": {
  21832. VBtn: {
  21833. class: 'v-empty-state__action-btn',
  21834. color: props.color ?? 'surface-variant',
  21835. text: props.actionText
  21836. }
  21837. }
  21838. }, {
  21839. default: () => [slots.actions?.({
  21840. props: {
  21841. onClick: onClickAction
  21842. }
  21843. }) ?? createVNode(VBtn, {
  21844. "onClick": onClickAction
  21845. }, null)]
  21846. })])]);
  21847. });
  21848. return {};
  21849. }
  21850. });
  21851. // Types
  21852. const VExpansionPanelSymbol = Symbol.for('vuetify:v-expansion-panel');
  21853. const makeVExpansionPanelTextProps = propsFactory({
  21854. ...makeComponentProps(),
  21855. ...makeLazyProps()
  21856. }, 'VExpansionPanelText');
  21857. const VExpansionPanelText = genericComponent()({
  21858. name: 'VExpansionPanelText',
  21859. props: makeVExpansionPanelTextProps(),
  21860. setup(props, _ref) {
  21861. let {
  21862. slots
  21863. } = _ref;
  21864. const expansionPanel = inject$1(VExpansionPanelSymbol);
  21865. if (!expansionPanel) throw new Error('[Vuetify] v-expansion-panel-text needs to be placed inside v-expansion-panel');
  21866. const {
  21867. hasContent,
  21868. onAfterLeave
  21869. } = useLazy(props, expansionPanel.isSelected);
  21870. useRender(() => createVNode(VExpandTransition, {
  21871. "onAfterLeave": onAfterLeave
  21872. }, {
  21873. default: () => [withDirectives(createVNode("div", {
  21874. "class": ['v-expansion-panel-text', props.class],
  21875. "style": props.style
  21876. }, [slots.default && hasContent.value && createVNode("div", {
  21877. "class": "v-expansion-panel-text__wrapper"
  21878. }, [slots.default?.()])]), [[vShow, expansionPanel.isSelected.value]])]
  21879. }));
  21880. return {};
  21881. }
  21882. });
  21883. // Types
  21884. const makeVExpansionPanelTitleProps = propsFactory({
  21885. color: String,
  21886. expandIcon: {
  21887. type: IconValue,
  21888. default: '$expand'
  21889. },
  21890. collapseIcon: {
  21891. type: IconValue,
  21892. default: '$collapse'
  21893. },
  21894. hideActions: Boolean,
  21895. focusable: Boolean,
  21896. static: Boolean,
  21897. ripple: {
  21898. type: [Boolean, Object],
  21899. default: false
  21900. },
  21901. readonly: Boolean,
  21902. ...makeComponentProps(),
  21903. ...makeDimensionProps()
  21904. }, 'VExpansionPanelTitle');
  21905. const VExpansionPanelTitle = genericComponent()({
  21906. name: 'VExpansionPanelTitle',
  21907. directives: {
  21908. Ripple
  21909. },
  21910. props: makeVExpansionPanelTitleProps(),
  21911. setup(props, _ref) {
  21912. let {
  21913. slots
  21914. } = _ref;
  21915. const expansionPanel = inject$1(VExpansionPanelSymbol);
  21916. if (!expansionPanel) throw new Error('[Vuetify] v-expansion-panel-title needs to be placed inside v-expansion-panel');
  21917. const {
  21918. backgroundColorClasses,
  21919. backgroundColorStyles
  21920. } = useBackgroundColor(props, 'color');
  21921. const {
  21922. dimensionStyles
  21923. } = useDimension(props);
  21924. const slotProps = computed(() => ({
  21925. collapseIcon: props.collapseIcon,
  21926. disabled: expansionPanel.disabled.value,
  21927. expanded: expansionPanel.isSelected.value,
  21928. expandIcon: props.expandIcon,
  21929. readonly: props.readonly
  21930. }));
  21931. const icon = computed(() => expansionPanel.isSelected.value ? props.collapseIcon : props.expandIcon);
  21932. useRender(() => withDirectives(createVNode("button", {
  21933. "class": ['v-expansion-panel-title', {
  21934. 'v-expansion-panel-title--active': expansionPanel.isSelected.value,
  21935. 'v-expansion-panel-title--focusable': props.focusable,
  21936. 'v-expansion-panel-title--static': props.static
  21937. }, backgroundColorClasses.value, props.class],
  21938. "style": [backgroundColorStyles.value, dimensionStyles.value, props.style],
  21939. "type": "button",
  21940. "tabindex": expansionPanel.disabled.value ? -1 : undefined,
  21941. "disabled": expansionPanel.disabled.value,
  21942. "aria-expanded": expansionPanel.isSelected.value,
  21943. "onClick": !props.readonly ? expansionPanel.toggle : undefined
  21944. }, [createVNode("span", {
  21945. "class": "v-expansion-panel-title__overlay"
  21946. }, null), slots.default?.(slotProps.value), !props.hideActions && createVNode(VDefaultsProvider, {
  21947. "defaults": {
  21948. VIcon: {
  21949. icon: icon.value
  21950. }
  21951. }
  21952. }, {
  21953. default: () => [createVNode("span", {
  21954. "class": "v-expansion-panel-title__icon"
  21955. }, [slots.actions?.(slotProps.value) ?? createVNode(VIcon, null, null)])]
  21956. })]), [[resolveDirective("ripple"), props.ripple]]));
  21957. return {};
  21958. }
  21959. });
  21960. const makeVExpansionPanelProps = propsFactory({
  21961. title: String,
  21962. text: String,
  21963. bgColor: String,
  21964. ...makeElevationProps(),
  21965. ...makeGroupItemProps(),
  21966. ...makeRoundedProps(),
  21967. ...makeTagProps(),
  21968. ...makeVExpansionPanelTitleProps(),
  21969. ...makeVExpansionPanelTextProps()
  21970. }, 'VExpansionPanel');
  21971. const VExpansionPanel = genericComponent()({
  21972. name: 'VExpansionPanel',
  21973. props: makeVExpansionPanelProps(),
  21974. emits: {
  21975. 'group:selected': val => true
  21976. },
  21977. setup(props, _ref) {
  21978. let {
  21979. slots
  21980. } = _ref;
  21981. const groupItem = useGroupItem(props, VExpansionPanelSymbol);
  21982. const {
  21983. backgroundColorClasses,
  21984. backgroundColorStyles
  21985. } = useBackgroundColor(props, 'bgColor');
  21986. const {
  21987. elevationClasses
  21988. } = useElevation(props);
  21989. const {
  21990. roundedClasses
  21991. } = useRounded(props);
  21992. const isDisabled = computed(() => groupItem?.disabled.value || props.disabled);
  21993. const selectedIndices = computed(() => groupItem.group.items.value.reduce((arr, item, index) => {
  21994. if (groupItem.group.selected.value.includes(item.id)) arr.push(index);
  21995. return arr;
  21996. }, []));
  21997. const isBeforeSelected = computed(() => {
  21998. const index = groupItem.group.items.value.findIndex(item => item.id === groupItem.id);
  21999. return !groupItem.isSelected.value && selectedIndices.value.some(selectedIndex => selectedIndex - index === 1);
  22000. });
  22001. const isAfterSelected = computed(() => {
  22002. const index = groupItem.group.items.value.findIndex(item => item.id === groupItem.id);
  22003. return !groupItem.isSelected.value && selectedIndices.value.some(selectedIndex => selectedIndex - index === -1);
  22004. });
  22005. provide(VExpansionPanelSymbol, groupItem);
  22006. useRender(() => {
  22007. const hasText = !!(slots.text || props.text);
  22008. const hasTitle = !!(slots.title || props.title);
  22009. const expansionPanelTitleProps = VExpansionPanelTitle.filterProps(props);
  22010. const expansionPanelTextProps = VExpansionPanelText.filterProps(props);
  22011. return createVNode(props.tag, {
  22012. "class": ['v-expansion-panel', {
  22013. 'v-expansion-panel--active': groupItem.isSelected.value,
  22014. 'v-expansion-panel--before-active': isBeforeSelected.value,
  22015. 'v-expansion-panel--after-active': isAfterSelected.value,
  22016. 'v-expansion-panel--disabled': isDisabled.value
  22017. }, roundedClasses.value, backgroundColorClasses.value, props.class],
  22018. "style": [backgroundColorStyles.value, props.style]
  22019. }, {
  22020. default: () => [createVNode("div", {
  22021. "class": ['v-expansion-panel__shadow', ...elevationClasses.value]
  22022. }, null), createVNode(VDefaultsProvider, {
  22023. "defaults": {
  22024. VExpansionPanelTitle: {
  22025. ...expansionPanelTitleProps
  22026. },
  22027. VExpansionPanelText: {
  22028. ...expansionPanelTextProps
  22029. }
  22030. }
  22031. }, {
  22032. default: () => [hasTitle && createVNode(VExpansionPanelTitle, {
  22033. "key": "title"
  22034. }, {
  22035. default: () => [slots.title ? slots.title() : props.title]
  22036. }), hasText && createVNode(VExpansionPanelText, {
  22037. "key": "text"
  22038. }, {
  22039. default: () => [slots.text ? slots.text() : props.text]
  22040. }), slots.default?.()]
  22041. })]
  22042. });
  22043. });
  22044. return {
  22045. groupItem
  22046. };
  22047. }
  22048. });
  22049. // Types
  22050. const allowedVariants = ['default', 'accordion', 'inset', 'popout'];
  22051. const makeVExpansionPanelsProps = propsFactory({
  22052. flat: Boolean,
  22053. ...makeGroupProps(),
  22054. ...pick(makeVExpansionPanelProps(), ['bgColor', 'collapseIcon', 'color', 'eager', 'elevation', 'expandIcon', 'focusable', 'hideActions', 'readonly', 'ripple', 'rounded', 'tile', 'static']),
  22055. ...makeThemeProps(),
  22056. ...makeComponentProps(),
  22057. ...makeTagProps(),
  22058. variant: {
  22059. type: String,
  22060. default: 'default',
  22061. validator: v => allowedVariants.includes(v)
  22062. }
  22063. }, 'VExpansionPanels');
  22064. const VExpansionPanels = genericComponent()({
  22065. name: 'VExpansionPanels',
  22066. props: makeVExpansionPanelsProps(),
  22067. emits: {
  22068. 'update:modelValue': val => true
  22069. },
  22070. setup(props, _ref) {
  22071. let {
  22072. slots
  22073. } = _ref;
  22074. const {
  22075. next,
  22076. prev
  22077. } = useGroup(props, VExpansionPanelSymbol);
  22078. const {
  22079. themeClasses
  22080. } = provideTheme(props);
  22081. const variantClass = computed(() => props.variant && `v-expansion-panels--variant-${props.variant}`);
  22082. provideDefaults({
  22083. VExpansionPanel: {
  22084. bgColor: toRef(props, 'bgColor'),
  22085. collapseIcon: toRef(props, 'collapseIcon'),
  22086. color: toRef(props, 'color'),
  22087. eager: toRef(props, 'eager'),
  22088. elevation: toRef(props, 'elevation'),
  22089. expandIcon: toRef(props, 'expandIcon'),
  22090. focusable: toRef(props, 'focusable'),
  22091. hideActions: toRef(props, 'hideActions'),
  22092. readonly: toRef(props, 'readonly'),
  22093. ripple: toRef(props, 'ripple'),
  22094. rounded: toRef(props, 'rounded'),
  22095. static: toRef(props, 'static')
  22096. }
  22097. });
  22098. useRender(() => createVNode(props.tag, {
  22099. "class": ['v-expansion-panels', {
  22100. 'v-expansion-panels--flat': props.flat,
  22101. 'v-expansion-panels--tile': props.tile
  22102. }, themeClasses.value, variantClass.value, props.class],
  22103. "style": props.style
  22104. }, {
  22105. default: () => [slots.default?.({
  22106. prev,
  22107. next
  22108. })]
  22109. }));
  22110. return {
  22111. next,
  22112. prev
  22113. };
  22114. }
  22115. });
  22116. // Types
  22117. const makeVFabProps = propsFactory({
  22118. app: Boolean,
  22119. appear: Boolean,
  22120. extended: Boolean,
  22121. layout: Boolean,
  22122. offset: Boolean,
  22123. modelValue: {
  22124. type: Boolean,
  22125. default: true
  22126. },
  22127. ...omit(makeVBtnProps({
  22128. active: true
  22129. }), ['location']),
  22130. ...makeLayoutItemProps(),
  22131. ...makeLocationProps(),
  22132. ...makeTransitionProps({
  22133. transition: 'fab-transition'
  22134. })
  22135. }, 'VFab');
  22136. const VFab = genericComponent()({
  22137. name: 'VFab',
  22138. props: makeVFabProps(),
  22139. emits: {
  22140. 'update:modelValue': value => true
  22141. },
  22142. setup(props, _ref) {
  22143. let {
  22144. slots
  22145. } = _ref;
  22146. const model = useProxiedModel(props, 'modelValue');
  22147. const height = shallowRef(56);
  22148. const layoutItemStyles = ref();
  22149. const {
  22150. resizeRef
  22151. } = useResizeObserver(entries => {
  22152. if (!entries.length) return;
  22153. height.value = entries[0].target.clientHeight;
  22154. });
  22155. const hasPosition = computed(() => props.app || props.absolute);
  22156. const position = computed(() => {
  22157. if (!hasPosition.value) return false;
  22158. return props.location?.split(' ').shift() ?? 'bottom';
  22159. });
  22160. const orientation = computed(() => {
  22161. if (!hasPosition.value) return false;
  22162. return props.location?.split(' ')[1] ?? 'end';
  22163. });
  22164. useToggleScope(() => props.app, () => {
  22165. const layout = useLayoutItem({
  22166. id: props.name,
  22167. order: computed(() => parseInt(props.order, 10)),
  22168. position,
  22169. layoutSize: computed(() => props.layout ? height.value + 24 : 0),
  22170. elementSize: computed(() => height.value + 24),
  22171. active: computed(() => props.app && model.value),
  22172. absolute: toRef(props, 'absolute')
  22173. });
  22174. watchEffect(() => {
  22175. layoutItemStyles.value = layout.layoutItemStyles.value;
  22176. });
  22177. });
  22178. const vFabRef = ref();
  22179. useRender(() => {
  22180. const btnProps = VBtn.filterProps(props);
  22181. return createVNode("div", {
  22182. "ref": vFabRef,
  22183. "class": ['v-fab', {
  22184. 'v-fab--absolute': props.absolute,
  22185. 'v-fab--app': !!props.app,
  22186. 'v-fab--extended': props.extended,
  22187. 'v-fab--offset': props.offset,
  22188. [`v-fab--${position.value}`]: hasPosition.value,
  22189. [`v-fab--${orientation.value}`]: hasPosition.value
  22190. }, props.class],
  22191. "style": [props.app ? {
  22192. ...layoutItemStyles.value
  22193. } : {
  22194. height: 'inherit',
  22195. width: undefined
  22196. }, props.style]
  22197. }, [createVNode("div", {
  22198. "class": "v-fab__container"
  22199. }, [createVNode(MaybeTransition, {
  22200. "appear": props.appear,
  22201. "transition": props.transition
  22202. }, {
  22203. default: () => [withDirectives(createVNode(VBtn, mergeProps({
  22204. "ref": resizeRef
  22205. }, btnProps, {
  22206. "active": undefined,
  22207. "location": undefined
  22208. }), slots), [[vShow, props.active]])]
  22209. })])]);
  22210. });
  22211. return {};
  22212. }
  22213. });
  22214. // Types
  22215. const makeVFileInputProps = propsFactory({
  22216. chips: Boolean,
  22217. counter: Boolean,
  22218. counterSizeString: {
  22219. type: String,
  22220. default: '$vuetify.fileInput.counterSize'
  22221. },
  22222. counterString: {
  22223. type: String,
  22224. default: '$vuetify.fileInput.counter'
  22225. },
  22226. hideInput: Boolean,
  22227. multiple: Boolean,
  22228. showSize: {
  22229. type: [Boolean, Number, String],
  22230. default: false,
  22231. validator: v => {
  22232. return typeof v === 'boolean' || [1000, 1024].includes(Number(v));
  22233. }
  22234. },
  22235. ...makeVInputProps({
  22236. prependIcon: '$file'
  22237. }),
  22238. modelValue: {
  22239. type: [Array, Object],
  22240. default: props => props.multiple ? [] : null,
  22241. validator: val => {
  22242. return wrapInArray(val).every(v => v != null && typeof v === 'object');
  22243. }
  22244. },
  22245. ...makeVFieldProps({
  22246. clearable: true
  22247. })
  22248. }, 'VFileInput');
  22249. const VFileInput = genericComponent()({
  22250. name: 'VFileInput',
  22251. inheritAttrs: false,
  22252. props: makeVFileInputProps(),
  22253. emits: {
  22254. 'click:control': e => true,
  22255. 'mousedown:control': e => true,
  22256. 'update:focused': focused => true,
  22257. 'update:modelValue': files => true
  22258. },
  22259. setup(props, _ref) {
  22260. let {
  22261. attrs,
  22262. emit,
  22263. slots
  22264. } = _ref;
  22265. const {
  22266. t
  22267. } = useLocale();
  22268. const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => !props.multiple && Array.isArray(val) ? val[0] : val);
  22269. const {
  22270. isFocused,
  22271. focus,
  22272. blur
  22273. } = useFocus(props);
  22274. const base = computed(() => typeof props.showSize !== 'boolean' ? props.showSize : undefined);
  22275. const totalBytes = computed(() => (model.value ?? []).reduce((bytes, _ref2) => {
  22276. let {
  22277. size = 0
  22278. } = _ref2;
  22279. return bytes + size;
  22280. }, 0));
  22281. const totalBytesReadable = computed(() => humanReadableFileSize(totalBytes.value, base.value));
  22282. const fileNames = computed(() => (model.value ?? []).map(file => {
  22283. const {
  22284. name = '',
  22285. size = 0
  22286. } = file;
  22287. return !props.showSize ? name : `${name} (${humanReadableFileSize(size, base.value)})`;
  22288. }));
  22289. const counterValue = computed(() => {
  22290. const fileCount = model.value?.length ?? 0;
  22291. if (props.showSize) return t(props.counterSizeString, fileCount, totalBytesReadable.value);else return t(props.counterString, fileCount);
  22292. });
  22293. const vInputRef = ref();
  22294. const vFieldRef = ref();
  22295. const inputRef = ref();
  22296. const isActive = computed(() => isFocused.value || props.active);
  22297. const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant));
  22298. function onFocus() {
  22299. if (inputRef.value !== document.activeElement) {
  22300. inputRef.value?.focus();
  22301. }
  22302. if (!isFocused.value) focus();
  22303. }
  22304. function onClickPrepend(e) {
  22305. inputRef.value?.click();
  22306. }
  22307. function onControlMousedown(e) {
  22308. emit('mousedown:control', e);
  22309. }
  22310. function onControlClick(e) {
  22311. inputRef.value?.click();
  22312. emit('click:control', e);
  22313. }
  22314. function onClear(e) {
  22315. e.stopPropagation();
  22316. onFocus();
  22317. nextTick(() => {
  22318. model.value = [];
  22319. callEvent(props['onClick:clear'], e);
  22320. });
  22321. }
  22322. watch(model, newValue => {
  22323. const hasModelReset = !Array.isArray(newValue) || !newValue.length;
  22324. if (hasModelReset && inputRef.value) {
  22325. inputRef.value.value = '';
  22326. }
  22327. });
  22328. useRender(() => {
  22329. const hasCounter = !!(slots.counter || props.counter);
  22330. const hasDetails = !!(hasCounter || slots.details);
  22331. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  22332. const {
  22333. modelValue: _,
  22334. ...inputProps
  22335. } = VInput.filterProps(props);
  22336. const fieldProps = filterFieldProps(props);
  22337. return createVNode(VInput, mergeProps({
  22338. "ref": vInputRef,
  22339. "modelValue": model.value,
  22340. "onUpdate:modelValue": $event => model.value = $event,
  22341. "class": ['v-file-input', {
  22342. 'v-file-input--chips': !!props.chips,
  22343. 'v-file-input--hide': props.hideInput,
  22344. 'v-input--plain-underlined': isPlainOrUnderlined.value
  22345. }, props.class],
  22346. "style": props.style,
  22347. "onClick:prepend": onClickPrepend
  22348. }, rootAttrs, inputProps, {
  22349. "centerAffix": !isPlainOrUnderlined.value,
  22350. "focused": isFocused.value
  22351. }), {
  22352. ...slots,
  22353. default: _ref3 => {
  22354. let {
  22355. id,
  22356. isDisabled,
  22357. isDirty,
  22358. isReadonly,
  22359. isValid
  22360. } = _ref3;
  22361. return createVNode(VField, mergeProps({
  22362. "ref": vFieldRef,
  22363. "prepend-icon": props.prependIcon,
  22364. "onMousedown": onControlMousedown,
  22365. "onClick": onControlClick,
  22366. "onClick:clear": onClear,
  22367. "onClick:prependInner": props['onClick:prependInner'],
  22368. "onClick:appendInner": props['onClick:appendInner']
  22369. }, fieldProps, {
  22370. "id": id.value,
  22371. "active": isActive.value || isDirty.value,
  22372. "dirty": isDirty.value || props.dirty,
  22373. "disabled": isDisabled.value,
  22374. "focused": isFocused.value,
  22375. "error": isValid.value === false
  22376. }), {
  22377. ...slots,
  22378. default: _ref4 => {
  22379. let {
  22380. props: {
  22381. class: fieldClass,
  22382. ...slotProps
  22383. }
  22384. } = _ref4;
  22385. return createVNode(Fragment, null, [createVNode("input", mergeProps({
  22386. "ref": inputRef,
  22387. "type": "file",
  22388. "readonly": isReadonly.value,
  22389. "disabled": isDisabled.value,
  22390. "multiple": props.multiple,
  22391. "name": props.name,
  22392. "onClick": e => {
  22393. e.stopPropagation();
  22394. if (isReadonly.value) e.preventDefault();
  22395. onFocus();
  22396. },
  22397. "onChange": e => {
  22398. if (!e.target) return;
  22399. const target = e.target;
  22400. model.value = [...(target.files ?? [])];
  22401. },
  22402. "onFocus": onFocus,
  22403. "onBlur": blur
  22404. }, slotProps, inputAttrs), null), createVNode("div", {
  22405. "class": fieldClass
  22406. }, [!!model.value?.length && !props.hideInput && (slots.selection ? slots.selection({
  22407. fileNames: fileNames.value,
  22408. totalBytes: totalBytes.value,
  22409. totalBytesReadable: totalBytesReadable.value
  22410. }) : props.chips ? fileNames.value.map(text => createVNode(VChip, {
  22411. "key": text,
  22412. "size": "small",
  22413. "text": text
  22414. }, null)) : fileNames.value.join(', '))])]);
  22415. }
  22416. });
  22417. },
  22418. details: hasDetails ? slotProps => createVNode(Fragment, null, [slots.details?.(slotProps), hasCounter && createVNode(Fragment, null, [createVNode("span", null, null), createVNode(VCounter, {
  22419. "active": !!model.value?.length,
  22420. "value": counterValue.value,
  22421. "disabled": props.disabled
  22422. }, slots.counter)])]) : undefined
  22423. });
  22424. });
  22425. return forwardRefs({}, vInputRef, vFieldRef, inputRef);
  22426. }
  22427. });
  22428. const makeVFooterProps = propsFactory({
  22429. app: Boolean,
  22430. color: String,
  22431. height: {
  22432. type: [Number, String],
  22433. default: 'auto'
  22434. },
  22435. ...makeBorderProps(),
  22436. ...makeComponentProps(),
  22437. ...makeElevationProps(),
  22438. ...makeLayoutItemProps(),
  22439. ...makeRoundedProps(),
  22440. ...makeTagProps({
  22441. tag: 'footer'
  22442. }),
  22443. ...makeThemeProps()
  22444. }, 'VFooter');
  22445. const VFooter = genericComponent()({
  22446. name: 'VFooter',
  22447. props: makeVFooterProps(),
  22448. setup(props, _ref) {
  22449. let {
  22450. slots
  22451. } = _ref;
  22452. const layoutItemStyles = ref();
  22453. const {
  22454. themeClasses
  22455. } = provideTheme(props);
  22456. const {
  22457. backgroundColorClasses,
  22458. backgroundColorStyles
  22459. } = useBackgroundColor(toRef(props, 'color'));
  22460. const {
  22461. borderClasses
  22462. } = useBorder(props);
  22463. const {
  22464. elevationClasses
  22465. } = useElevation(props);
  22466. const {
  22467. roundedClasses
  22468. } = useRounded(props);
  22469. const autoHeight = shallowRef(32);
  22470. const {
  22471. resizeRef
  22472. } = useResizeObserver(entries => {
  22473. if (!entries.length) return;
  22474. autoHeight.value = entries[0].target.clientHeight;
  22475. });
  22476. const height = computed(() => props.height === 'auto' ? autoHeight.value : parseInt(props.height, 10));
  22477. useToggleScope(() => props.app, () => {
  22478. const layout = useLayoutItem({
  22479. id: props.name,
  22480. order: computed(() => parseInt(props.order, 10)),
  22481. position: computed(() => 'bottom'),
  22482. layoutSize: height,
  22483. elementSize: computed(() => props.height === 'auto' ? undefined : height.value),
  22484. active: computed(() => props.app),
  22485. absolute: toRef(props, 'absolute')
  22486. });
  22487. watchEffect(() => {
  22488. layoutItemStyles.value = layout.layoutItemStyles.value;
  22489. });
  22490. });
  22491. useRender(() => createVNode(props.tag, {
  22492. "ref": resizeRef,
  22493. "class": ['v-footer', themeClasses.value, backgroundColorClasses.value, borderClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  22494. "style": [backgroundColorStyles.value, props.app ? layoutItemStyles.value : {
  22495. height: convertToUnit(props.height)
  22496. }, props.style]
  22497. }, slots));
  22498. return {};
  22499. }
  22500. });
  22501. // Types
  22502. const makeVFormProps = propsFactory({
  22503. ...makeComponentProps(),
  22504. ...makeFormProps()
  22505. }, 'VForm');
  22506. const VForm = genericComponent()({
  22507. name: 'VForm',
  22508. props: makeVFormProps(),
  22509. emits: {
  22510. 'update:modelValue': val => true,
  22511. submit: e => true
  22512. },
  22513. setup(props, _ref) {
  22514. let {
  22515. slots,
  22516. emit
  22517. } = _ref;
  22518. const form = createForm(props);
  22519. const formRef = ref();
  22520. function onReset(e) {
  22521. e.preventDefault();
  22522. form.reset();
  22523. }
  22524. function onSubmit(_e) {
  22525. const e = _e;
  22526. const ready = form.validate();
  22527. e.then = ready.then.bind(ready);
  22528. e.catch = ready.catch.bind(ready);
  22529. e.finally = ready.finally.bind(ready);
  22530. emit('submit', e);
  22531. if (!e.defaultPrevented) {
  22532. ready.then(_ref2 => {
  22533. let {
  22534. valid
  22535. } = _ref2;
  22536. if (valid) {
  22537. formRef.value?.submit();
  22538. }
  22539. });
  22540. }
  22541. e.preventDefault();
  22542. }
  22543. useRender(() => createVNode("form", {
  22544. "ref": formRef,
  22545. "class": ['v-form', props.class],
  22546. "style": props.style,
  22547. "novalidate": true,
  22548. "onReset": onReset,
  22549. "onSubmit": onSubmit
  22550. }, [slots.default?.(form)]));
  22551. return forwardRefs(form, formRef);
  22552. }
  22553. });
  22554. // Composables
  22555. const makeVHoverProps = propsFactory({
  22556. disabled: Boolean,
  22557. modelValue: {
  22558. type: Boolean,
  22559. default: null
  22560. },
  22561. ...makeDelayProps()
  22562. }, 'VHover');
  22563. const VHover = genericComponent()({
  22564. name: 'VHover',
  22565. props: makeVHoverProps(),
  22566. emits: {
  22567. 'update:modelValue': value => true
  22568. },
  22569. setup(props, _ref) {
  22570. let {
  22571. slots
  22572. } = _ref;
  22573. const isHovering = useProxiedModel(props, 'modelValue');
  22574. const {
  22575. runOpenDelay,
  22576. runCloseDelay
  22577. } = useDelay(props, value => !props.disabled && (isHovering.value = value));
  22578. return () => slots.default?.({
  22579. isHovering: isHovering.value,
  22580. props: {
  22581. onMouseenter: runOpenDelay,
  22582. onMouseleave: runCloseDelay
  22583. }
  22584. });
  22585. }
  22586. });
  22587. // Types
  22588. const makeVInfiniteScrollProps = propsFactory({
  22589. color: String,
  22590. direction: {
  22591. type: String,
  22592. default: 'vertical',
  22593. validator: v => ['vertical', 'horizontal'].includes(v)
  22594. },
  22595. side: {
  22596. type: String,
  22597. default: 'end',
  22598. validator: v => ['start', 'end', 'both'].includes(v)
  22599. },
  22600. mode: {
  22601. type: String,
  22602. default: 'intersect',
  22603. validator: v => ['intersect', 'manual'].includes(v)
  22604. },
  22605. margin: [Number, String],
  22606. loadMoreText: {
  22607. type: String,
  22608. default: '$vuetify.infiniteScroll.loadMore'
  22609. },
  22610. emptyText: {
  22611. type: String,
  22612. default: '$vuetify.infiniteScroll.empty'
  22613. },
  22614. ...makeDimensionProps(),
  22615. ...makeTagProps()
  22616. }, 'VInfiniteScroll');
  22617. const VInfiniteScrollIntersect = defineComponent({
  22618. name: 'VInfiniteScrollIntersect',
  22619. props: {
  22620. side: {
  22621. type: String,
  22622. required: true
  22623. },
  22624. rootMargin: String
  22625. },
  22626. emits: {
  22627. intersect: (side, isIntersecting) => true
  22628. },
  22629. setup(props, _ref) {
  22630. let {
  22631. emit
  22632. } = _ref;
  22633. const {
  22634. intersectionRef,
  22635. isIntersecting
  22636. } = useIntersectionObserver();
  22637. watch(isIntersecting, async val => {
  22638. emit('intersect', props.side, val);
  22639. });
  22640. useRender(() => createVNode("div", {
  22641. "class": "v-infinite-scroll-intersect",
  22642. "style": {
  22643. '--v-infinite-margin-size': props.rootMargin
  22644. },
  22645. "ref": intersectionRef
  22646. }, [createTextVNode("\xA0")]));
  22647. return {};
  22648. }
  22649. });
  22650. const VInfiniteScroll = genericComponent()({
  22651. name: 'VInfiniteScroll',
  22652. props: makeVInfiniteScrollProps(),
  22653. emits: {
  22654. load: options => true
  22655. },
  22656. setup(props, _ref2) {
  22657. let {
  22658. slots,
  22659. emit
  22660. } = _ref2;
  22661. const rootEl = ref();
  22662. const startStatus = shallowRef('ok');
  22663. const endStatus = shallowRef('ok');
  22664. const margin = computed(() => convertToUnit(props.margin));
  22665. const isIntersecting = shallowRef(false);
  22666. function setScrollAmount(amount) {
  22667. if (!rootEl.value) return;
  22668. const property = props.direction === 'vertical' ? 'scrollTop' : 'scrollLeft';
  22669. rootEl.value[property] = amount;
  22670. }
  22671. function getScrollAmount() {
  22672. if (!rootEl.value) return 0;
  22673. const property = props.direction === 'vertical' ? 'scrollTop' : 'scrollLeft';
  22674. return rootEl.value[property];
  22675. }
  22676. function getScrollSize() {
  22677. if (!rootEl.value) return 0;
  22678. const property = props.direction === 'vertical' ? 'scrollHeight' : 'scrollWidth';
  22679. return rootEl.value[property];
  22680. }
  22681. function getContainerSize() {
  22682. if (!rootEl.value) return 0;
  22683. const property = props.direction === 'vertical' ? 'clientHeight' : 'clientWidth';
  22684. return rootEl.value[property];
  22685. }
  22686. onMounted(() => {
  22687. if (!rootEl.value) return;
  22688. if (props.side === 'start') {
  22689. setScrollAmount(getScrollSize());
  22690. } else if (props.side === 'both') {
  22691. setScrollAmount(getScrollSize() / 2 - getContainerSize() / 2);
  22692. }
  22693. });
  22694. function setStatus(side, status) {
  22695. if (side === 'start') {
  22696. startStatus.value = status;
  22697. } else if (side === 'end') {
  22698. endStatus.value = status;
  22699. }
  22700. }
  22701. function getStatus(side) {
  22702. return side === 'start' ? startStatus.value : endStatus.value;
  22703. }
  22704. let previousScrollSize = 0;
  22705. function handleIntersect(side, _isIntersecting) {
  22706. isIntersecting.value = _isIntersecting;
  22707. if (isIntersecting.value) {
  22708. intersecting(side);
  22709. }
  22710. }
  22711. function intersecting(side) {
  22712. if (props.mode !== 'manual' && !isIntersecting.value) return;
  22713. const status = getStatus(side);
  22714. if (!rootEl.value || ['empty', 'loading'].includes(status)) return;
  22715. previousScrollSize = getScrollSize();
  22716. setStatus(side, 'loading');
  22717. function done(status) {
  22718. setStatus(side, status);
  22719. nextTick(() => {
  22720. if (status === 'empty' || status === 'error') return;
  22721. if (status === 'ok' && side === 'start') {
  22722. setScrollAmount(getScrollSize() - previousScrollSize + getScrollAmount());
  22723. }
  22724. if (props.mode !== 'manual') {
  22725. nextTick(() => {
  22726. window.requestAnimationFrame(() => {
  22727. window.requestAnimationFrame(() => {
  22728. window.requestAnimationFrame(() => {
  22729. intersecting(side);
  22730. });
  22731. });
  22732. });
  22733. });
  22734. }
  22735. });
  22736. }
  22737. emit('load', {
  22738. side,
  22739. done
  22740. });
  22741. }
  22742. const {
  22743. t
  22744. } = useLocale();
  22745. function renderSide(side, status) {
  22746. if (props.side !== side && props.side !== 'both') return;
  22747. const onClick = () => intersecting(side);
  22748. const slotProps = {
  22749. side,
  22750. props: {
  22751. onClick,
  22752. color: props.color
  22753. }
  22754. };
  22755. if (status === 'error') return slots.error?.(slotProps);
  22756. if (status === 'empty') return slots.empty?.(slotProps) ?? createVNode("div", null, [t(props.emptyText)]);
  22757. if (props.mode === 'manual') {
  22758. if (status === 'loading') {
  22759. return slots.loading?.(slotProps) ?? createVNode(VProgressCircular, {
  22760. "indeterminate": true,
  22761. "color": props.color
  22762. }, null);
  22763. }
  22764. return slots['load-more']?.(slotProps) ?? createVNode(VBtn, {
  22765. "variant": "outlined",
  22766. "color": props.color,
  22767. "onClick": onClick
  22768. }, {
  22769. default: () => [t(props.loadMoreText)]
  22770. });
  22771. }
  22772. return slots.loading?.(slotProps) ?? createVNode(VProgressCircular, {
  22773. "indeterminate": true,
  22774. "color": props.color
  22775. }, null);
  22776. }
  22777. const {
  22778. dimensionStyles
  22779. } = useDimension(props);
  22780. useRender(() => {
  22781. const Tag = props.tag;
  22782. const hasStartIntersect = props.side === 'start' || props.side === 'both';
  22783. const hasEndIntersect = props.side === 'end' || props.side === 'both';
  22784. const intersectMode = props.mode === 'intersect';
  22785. return createVNode(Tag, {
  22786. "ref": rootEl,
  22787. "class": ['v-infinite-scroll', `v-infinite-scroll--${props.direction}`, {
  22788. 'v-infinite-scroll--start': hasStartIntersect,
  22789. 'v-infinite-scroll--end': hasEndIntersect
  22790. }],
  22791. "style": dimensionStyles.value
  22792. }, {
  22793. default: () => [createVNode("div", {
  22794. "class": "v-infinite-scroll__side"
  22795. }, [renderSide('start', startStatus.value)]), hasStartIntersect && intersectMode && createVNode(VInfiniteScrollIntersect, {
  22796. "key": "start",
  22797. "side": "start",
  22798. "onIntersect": handleIntersect,
  22799. "rootMargin": margin.value
  22800. }, null), slots.default?.(), hasEndIntersect && intersectMode && createVNode(VInfiniteScrollIntersect, {
  22801. "key": "end",
  22802. "side": "end",
  22803. "onIntersect": handleIntersect,
  22804. "rootMargin": margin.value
  22805. }, null), createVNode("div", {
  22806. "class": "v-infinite-scroll__side"
  22807. }, [renderSide('end', endStatus.value)])]
  22808. });
  22809. });
  22810. }
  22811. });
  22812. // Types
  22813. const VItemGroupSymbol = Symbol.for('vuetify:v-item-group');
  22814. const makeVItemGroupProps = propsFactory({
  22815. ...makeComponentProps(),
  22816. ...makeGroupProps({
  22817. selectedClass: 'v-item--selected'
  22818. }),
  22819. ...makeTagProps(),
  22820. ...makeThemeProps()
  22821. }, 'VItemGroup');
  22822. const VItemGroup = genericComponent()({
  22823. name: 'VItemGroup',
  22824. props: makeVItemGroupProps(),
  22825. emits: {
  22826. 'update:modelValue': value => true
  22827. },
  22828. setup(props, _ref) {
  22829. let {
  22830. slots
  22831. } = _ref;
  22832. const {
  22833. themeClasses
  22834. } = provideTheme(props);
  22835. const {
  22836. isSelected,
  22837. select,
  22838. next,
  22839. prev,
  22840. selected
  22841. } = useGroup(props, VItemGroupSymbol);
  22842. return () => createVNode(props.tag, {
  22843. "class": ['v-item-group', themeClasses.value, props.class],
  22844. "style": props.style
  22845. }, {
  22846. default: () => [slots.default?.({
  22847. isSelected,
  22848. select,
  22849. next,
  22850. prev,
  22851. selected: selected.value
  22852. })]
  22853. });
  22854. }
  22855. });
  22856. // Composables
  22857. const VItem = genericComponent()({
  22858. name: 'VItem',
  22859. props: makeGroupItemProps(),
  22860. emits: {
  22861. 'group:selected': val => true
  22862. },
  22863. setup(props, _ref) {
  22864. let {
  22865. slots
  22866. } = _ref;
  22867. const {
  22868. isSelected,
  22869. select,
  22870. toggle,
  22871. selectedClass,
  22872. value,
  22873. disabled
  22874. } = useGroupItem(props, VItemGroupSymbol);
  22875. return () => slots.default?.({
  22876. isSelected: isSelected.value,
  22877. selectedClass: selectedClass.value,
  22878. select,
  22879. toggle,
  22880. value: value.value,
  22881. disabled: disabled.value
  22882. });
  22883. }
  22884. });
  22885. // Styles
  22886. const VKbd = createSimpleFunctional('v-kbd', 'kbd');
  22887. const makeVLayoutProps = propsFactory({
  22888. ...makeComponentProps(),
  22889. ...makeDimensionProps(),
  22890. ...makeLayoutProps()
  22891. }, 'VLayout');
  22892. const VLayout = genericComponent()({
  22893. name: 'VLayout',
  22894. props: makeVLayoutProps(),
  22895. setup(props, _ref) {
  22896. let {
  22897. slots
  22898. } = _ref;
  22899. const {
  22900. layoutClasses,
  22901. layoutStyles,
  22902. getLayoutItem,
  22903. items,
  22904. layoutRef
  22905. } = createLayout(props);
  22906. const {
  22907. dimensionStyles
  22908. } = useDimension(props);
  22909. useRender(() => createVNode("div", {
  22910. "ref": layoutRef,
  22911. "class": [layoutClasses.value, props.class],
  22912. "style": [dimensionStyles.value, layoutStyles.value, props.style]
  22913. }, [slots.default?.()]));
  22914. return {
  22915. getLayoutItem,
  22916. items
  22917. };
  22918. }
  22919. });
  22920. // Types
  22921. const makeVLayoutItemProps = propsFactory({
  22922. position: {
  22923. type: String,
  22924. required: true
  22925. },
  22926. size: {
  22927. type: [Number, String],
  22928. default: 300
  22929. },
  22930. modelValue: Boolean,
  22931. ...makeComponentProps(),
  22932. ...makeLayoutItemProps()
  22933. }, 'VLayoutItem');
  22934. const VLayoutItem = genericComponent()({
  22935. name: 'VLayoutItem',
  22936. props: makeVLayoutItemProps(),
  22937. setup(props, _ref) {
  22938. let {
  22939. slots
  22940. } = _ref;
  22941. const {
  22942. layoutItemStyles
  22943. } = useLayoutItem({
  22944. id: props.name,
  22945. order: computed(() => parseInt(props.order, 10)),
  22946. position: toRef(props, 'position'),
  22947. elementSize: toRef(props, 'size'),
  22948. layoutSize: toRef(props, 'size'),
  22949. active: toRef(props, 'modelValue'),
  22950. absolute: toRef(props, 'absolute')
  22951. });
  22952. return () => createVNode("div", {
  22953. "class": ['v-layout-item', props.class],
  22954. "style": [layoutItemStyles.value, props.style]
  22955. }, [slots.default?.()]);
  22956. }
  22957. });
  22958. // Types
  22959. const makeVLazyProps = propsFactory({
  22960. modelValue: Boolean,
  22961. options: {
  22962. type: Object,
  22963. // For more information on types, navigate to:
  22964. // https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
  22965. default: () => ({
  22966. root: undefined,
  22967. rootMargin: undefined,
  22968. threshold: undefined
  22969. })
  22970. },
  22971. ...makeComponentProps(),
  22972. ...makeDimensionProps(),
  22973. ...makeTagProps(),
  22974. ...makeTransitionProps({
  22975. transition: 'fade-transition'
  22976. })
  22977. }, 'VLazy');
  22978. const VLazy = genericComponent()({
  22979. name: 'VLazy',
  22980. directives: {
  22981. intersect: Intersect
  22982. },
  22983. props: makeVLazyProps(),
  22984. emits: {
  22985. 'update:modelValue': value => true
  22986. },
  22987. setup(props, _ref) {
  22988. let {
  22989. slots
  22990. } = _ref;
  22991. const {
  22992. dimensionStyles
  22993. } = useDimension(props);
  22994. const isActive = useProxiedModel(props, 'modelValue');
  22995. function onIntersect(isIntersecting) {
  22996. if (isActive.value) return;
  22997. isActive.value = isIntersecting;
  22998. }
  22999. useRender(() => withDirectives(createVNode(props.tag, {
  23000. "class": ['v-lazy', props.class],
  23001. "style": [dimensionStyles.value, props.style]
  23002. }, {
  23003. default: () => [isActive.value && createVNode(MaybeTransition, {
  23004. "transition": props.transition,
  23005. "appear": true
  23006. }, {
  23007. default: () => [slots.default?.()]
  23008. })]
  23009. }), [[resolveDirective("intersect"), {
  23010. handler: onIntersect,
  23011. options: props.options
  23012. }, null]]));
  23013. return {};
  23014. }
  23015. });
  23016. const makeVLocaleProviderProps = propsFactory({
  23017. locale: String,
  23018. fallbackLocale: String,
  23019. messages: Object,
  23020. rtl: {
  23021. type: Boolean,
  23022. default: undefined
  23023. },
  23024. ...makeComponentProps()
  23025. }, 'VLocaleProvider');
  23026. const VLocaleProvider = genericComponent()({
  23027. name: 'VLocaleProvider',
  23028. props: makeVLocaleProviderProps(),
  23029. setup(props, _ref) {
  23030. let {
  23031. slots
  23032. } = _ref;
  23033. const {
  23034. rtlClasses
  23035. } = provideLocale(props);
  23036. useRender(() => createVNode("div", {
  23037. "class": ['v-locale-provider', rtlClasses.value, props.class],
  23038. "style": props.style
  23039. }, [slots.default?.()]));
  23040. return {};
  23041. }
  23042. });
  23043. const makeVMainProps = propsFactory({
  23044. scrollable: Boolean,
  23045. ...makeComponentProps(),
  23046. ...makeDimensionProps(),
  23047. ...makeTagProps({
  23048. tag: 'main'
  23049. })
  23050. }, 'VMain');
  23051. const VMain = genericComponent()({
  23052. name: 'VMain',
  23053. props: makeVMainProps(),
  23054. setup(props, _ref) {
  23055. let {
  23056. slots
  23057. } = _ref;
  23058. const {
  23059. dimensionStyles
  23060. } = useDimension(props);
  23061. const {
  23062. mainStyles
  23063. } = useLayout();
  23064. const {
  23065. ssrBootStyles
  23066. } = useSsrBoot();
  23067. useRender(() => createVNode(props.tag, {
  23068. "class": ['v-main', {
  23069. 'v-main--scrollable': props.scrollable
  23070. }, props.class],
  23071. "style": [mainStyles.value, ssrBootStyles.value, dimensionStyles.value, props.style]
  23072. }, {
  23073. default: () => [props.scrollable ? createVNode("div", {
  23074. "class": "v-main__scroller"
  23075. }, [slots.default?.()]) : slots.default?.()]
  23076. }));
  23077. return {};
  23078. }
  23079. });
  23080. // Utilities
  23081. // Types
  23082. function useSticky(_ref) {
  23083. let {
  23084. rootEl,
  23085. isSticky,
  23086. layoutItemStyles
  23087. } = _ref;
  23088. const isStuck = shallowRef(false);
  23089. const stuckPosition = shallowRef(0);
  23090. const stickyStyles = computed(() => {
  23091. const side = typeof isStuck.value === 'boolean' ? 'top' : isStuck.value;
  23092. return [isSticky.value ? {
  23093. top: 'auto',
  23094. bottom: 'auto',
  23095. height: undefined
  23096. } : undefined, isStuck.value ? {
  23097. [side]: convertToUnit(stuckPosition.value)
  23098. } : {
  23099. top: layoutItemStyles.value.top
  23100. }];
  23101. });
  23102. onMounted(() => {
  23103. watch(isSticky, val => {
  23104. if (val) {
  23105. window.addEventListener('scroll', onScroll, {
  23106. passive: true
  23107. });
  23108. } else {
  23109. window.removeEventListener('scroll', onScroll);
  23110. }
  23111. }, {
  23112. immediate: true
  23113. });
  23114. });
  23115. onBeforeUnmount(() => {
  23116. window.removeEventListener('scroll', onScroll);
  23117. });
  23118. let lastScrollTop = 0;
  23119. function onScroll() {
  23120. const direction = lastScrollTop > window.scrollY ? 'up' : 'down';
  23121. const rect = rootEl.value.getBoundingClientRect();
  23122. const layoutTop = parseFloat(layoutItemStyles.value.top ?? 0);
  23123. const top = window.scrollY - Math.max(0, stuckPosition.value - layoutTop);
  23124. const bottom = rect.height + Math.max(stuckPosition.value, layoutTop) - window.scrollY - window.innerHeight;
  23125. const bodyScroll = parseFloat(getComputedStyle(rootEl.value).getPropertyValue('--v-body-scroll-y')) || 0;
  23126. if (rect.height < window.innerHeight - layoutTop) {
  23127. isStuck.value = 'top';
  23128. stuckPosition.value = layoutTop;
  23129. } else if (direction === 'up' && isStuck.value === 'bottom' || direction === 'down' && isStuck.value === 'top') {
  23130. stuckPosition.value = window.scrollY + rect.top - bodyScroll;
  23131. isStuck.value = true;
  23132. } else if (direction === 'down' && bottom <= 0) {
  23133. stuckPosition.value = 0;
  23134. isStuck.value = 'bottom';
  23135. } else if (direction === 'up' && top <= 0) {
  23136. if (!bodyScroll) {
  23137. stuckPosition.value = rect.top + top;
  23138. isStuck.value = 'top';
  23139. } else if (isStuck.value !== 'top') {
  23140. stuckPosition.value = -top + bodyScroll + layoutTop;
  23141. isStuck.value = 'top';
  23142. }
  23143. }
  23144. lastScrollTop = window.scrollY;
  23145. }
  23146. return {
  23147. isStuck,
  23148. stickyStyles
  23149. };
  23150. }
  23151. // Utilities
  23152. const HORIZON = 100; // ms
  23153. const HISTORY = 20; // number of samples to keep
  23154. /** @see https://android.googlesource.com/platform/frameworks/native/+/master/libs/input/VelocityTracker.cpp */
  23155. function kineticEnergyToVelocity(work) {
  23156. const sqrt2 = 1.41421356237;
  23157. return (work < 0 ? -1.0 : 1.0) * Math.sqrt(Math.abs(work)) * sqrt2;
  23158. }
  23159. /**
  23160. * Returns pointer velocity in px/s
  23161. */
  23162. function calculateImpulseVelocity(samples) {
  23163. // The input should be in reversed time order (most recent sample at index i=0)
  23164. if (samples.length < 2) {
  23165. // if 0 or 1 points, velocity is zero
  23166. return 0;
  23167. }
  23168. // if (samples[1].t > samples[0].t) {
  23169. // // Algorithm will still work, but not perfectly
  23170. // consoleWarn('Samples provided to calculateImpulseVelocity in the wrong order')
  23171. // }
  23172. if (samples.length === 2) {
  23173. // if 2 points, basic linear calculation
  23174. if (samples[1].t === samples[0].t) {
  23175. // consoleWarn(`Events have identical time stamps t=${samples[0].t}, setting velocity = 0`)
  23176. return 0;
  23177. }
  23178. return (samples[1].d - samples[0].d) / (samples[1].t - samples[0].t);
  23179. }
  23180. // Guaranteed to have at least 3 points here
  23181. // start with the oldest sample and go forward in time
  23182. let work = 0;
  23183. for (let i = samples.length - 1; i > 0; i--) {
  23184. if (samples[i].t === samples[i - 1].t) {
  23185. // consoleWarn(`Events have identical time stamps t=${samples[i].t}, skipping sample`)
  23186. continue;
  23187. }
  23188. const vprev = kineticEnergyToVelocity(work); // v[i-1]
  23189. const vcurr = (samples[i].d - samples[i - 1].d) / (samples[i].t - samples[i - 1].t); // v[i]
  23190. work += (vcurr - vprev) * Math.abs(vcurr);
  23191. if (i === samples.length - 1) {
  23192. work *= 0.5;
  23193. }
  23194. }
  23195. return kineticEnergyToVelocity(work) * 1000;
  23196. }
  23197. function useVelocity() {
  23198. const touches = {};
  23199. function addMovement(e) {
  23200. Array.from(e.changedTouches).forEach(touch => {
  23201. const samples = touches[touch.identifier] ?? (touches[touch.identifier] = new CircularBuffer(HISTORY));
  23202. samples.push([e.timeStamp, touch]);
  23203. });
  23204. }
  23205. function endTouch(e) {
  23206. Array.from(e.changedTouches).forEach(touch => {
  23207. delete touches[touch.identifier];
  23208. });
  23209. }
  23210. function getVelocity(id) {
  23211. const samples = touches[id]?.values().reverse();
  23212. if (!samples) {
  23213. throw new Error(`No samples for touch id ${id}`);
  23214. }
  23215. const newest = samples[0];
  23216. const x = [];
  23217. const y = [];
  23218. for (const val of samples) {
  23219. if (newest[0] - val[0] > HORIZON) break;
  23220. x.push({
  23221. t: val[0],
  23222. d: val[1].clientX
  23223. });
  23224. y.push({
  23225. t: val[0],
  23226. d: val[1].clientY
  23227. });
  23228. }
  23229. return {
  23230. x: calculateImpulseVelocity(x),
  23231. y: calculateImpulseVelocity(y),
  23232. get direction() {
  23233. const {
  23234. x,
  23235. y
  23236. } = this;
  23237. const [absX, absY] = [Math.abs(x), Math.abs(y)];
  23238. return absX > absY && x >= 0 ? 'right' : absX > absY && x <= 0 ? 'left' : absY > absX && y >= 0 ? 'down' : absY > absX && y <= 0 ? 'up' : oops$1();
  23239. }
  23240. };
  23241. }
  23242. return {
  23243. addMovement,
  23244. endTouch,
  23245. getVelocity
  23246. };
  23247. }
  23248. function oops$1() {
  23249. throw new Error();
  23250. }
  23251. // Composables
  23252. // Types
  23253. function useTouch(_ref) {
  23254. let {
  23255. el,
  23256. isActive,
  23257. isTemporary,
  23258. width,
  23259. touchless,
  23260. position
  23261. } = _ref;
  23262. onMounted(() => {
  23263. window.addEventListener('touchstart', onTouchstart, {
  23264. passive: true
  23265. });
  23266. window.addEventListener('touchmove', onTouchmove, {
  23267. passive: false
  23268. });
  23269. window.addEventListener('touchend', onTouchend, {
  23270. passive: true
  23271. });
  23272. });
  23273. onBeforeUnmount(() => {
  23274. window.removeEventListener('touchstart', onTouchstart);
  23275. window.removeEventListener('touchmove', onTouchmove);
  23276. window.removeEventListener('touchend', onTouchend);
  23277. });
  23278. const isHorizontal = computed(() => ['left', 'right'].includes(position.value));
  23279. const {
  23280. addMovement,
  23281. endTouch,
  23282. getVelocity
  23283. } = useVelocity();
  23284. let maybeDragging = false;
  23285. const isDragging = shallowRef(false);
  23286. const dragProgress = shallowRef(0);
  23287. const offset = shallowRef(0);
  23288. let start;
  23289. function getOffset(pos, active) {
  23290. 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);
  23291. }
  23292. function getProgress(pos) {
  23293. let limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  23294. 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();
  23295. return limit ? Math.max(0, Math.min(1, progress)) : progress;
  23296. }
  23297. function onTouchstart(e) {
  23298. if (touchless.value) return;
  23299. const touchX = e.changedTouches[0].clientX;
  23300. const touchY = e.changedTouches[0].clientY;
  23301. const touchZone = 25;
  23302. 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();
  23303. 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());
  23304. if (inTouchZone || inElement || isActive.value && isTemporary.value) {
  23305. start = [touchX, touchY];
  23306. offset.value = getOffset(isHorizontal.value ? touchX : touchY, isActive.value);
  23307. dragProgress.value = getProgress(isHorizontal.value ? touchX : touchY);
  23308. maybeDragging = offset.value > -20 && offset.value < 80;
  23309. endTouch(e);
  23310. addMovement(e);
  23311. }
  23312. }
  23313. function onTouchmove(e) {
  23314. const touchX = e.changedTouches[0].clientX;
  23315. const touchY = e.changedTouches[0].clientY;
  23316. if (maybeDragging) {
  23317. if (!e.cancelable) {
  23318. maybeDragging = false;
  23319. return;
  23320. }
  23321. const dx = Math.abs(touchX - start[0]);
  23322. const dy = Math.abs(touchY - start[1]);
  23323. const thresholdMet = isHorizontal.value ? dx > dy && dx > 3 : dy > dx && dy > 3;
  23324. if (thresholdMet) {
  23325. isDragging.value = true;
  23326. maybeDragging = false;
  23327. } else if ((isHorizontal.value ? dy : dx) > 3) {
  23328. maybeDragging = false;
  23329. }
  23330. }
  23331. if (!isDragging.value) return;
  23332. e.preventDefault();
  23333. addMovement(e);
  23334. const progress = getProgress(isHorizontal.value ? touchX : touchY, false);
  23335. dragProgress.value = Math.max(0, Math.min(1, progress));
  23336. if (progress > 1) {
  23337. offset.value = getOffset(isHorizontal.value ? touchX : touchY, true);
  23338. } else if (progress < 0) {
  23339. offset.value = getOffset(isHorizontal.value ? touchX : touchY, false);
  23340. }
  23341. }
  23342. function onTouchend(e) {
  23343. maybeDragging = false;
  23344. if (!isDragging.value) return;
  23345. addMovement(e);
  23346. isDragging.value = false;
  23347. const velocity = getVelocity(e.changedTouches[0].identifier);
  23348. const vx = Math.abs(velocity.x);
  23349. const vy = Math.abs(velocity.y);
  23350. const thresholdMet = isHorizontal.value ? vx > vy && vx > 400 : vy > vx && vy > 3;
  23351. if (thresholdMet) {
  23352. isActive.value = velocity.direction === ({
  23353. left: 'right',
  23354. right: 'left',
  23355. top: 'down',
  23356. bottom: 'up'
  23357. }[position.value] || oops());
  23358. } else {
  23359. isActive.value = dragProgress.value > 0.5;
  23360. }
  23361. }
  23362. const dragStyles = computed(() => {
  23363. return isDragging.value ? {
  23364. 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(),
  23365. transition: 'none'
  23366. } : undefined;
  23367. });
  23368. useToggleScope(isDragging, () => {
  23369. const transform = el.value?.style.transform ?? null;
  23370. const transition = el.value?.style.transition ?? null;
  23371. watchEffect(() => {
  23372. el.value?.style.setProperty('transform', dragStyles.value?.transform || 'none');
  23373. el.value?.style.setProperty('transition', dragStyles.value?.transition || null);
  23374. });
  23375. onScopeDispose(() => {
  23376. el.value?.style.setProperty('transform', transform);
  23377. el.value?.style.setProperty('transition', transition);
  23378. });
  23379. });
  23380. return {
  23381. isDragging,
  23382. dragProgress,
  23383. dragStyles
  23384. };
  23385. }
  23386. function oops() {
  23387. throw new Error();
  23388. }
  23389. // Types
  23390. const locations = ['start', 'end', 'left', 'right', 'top', 'bottom'];
  23391. const makeVNavigationDrawerProps = propsFactory({
  23392. color: String,
  23393. disableResizeWatcher: Boolean,
  23394. disableRouteWatcher: Boolean,
  23395. expandOnHover: Boolean,
  23396. floating: Boolean,
  23397. modelValue: {
  23398. type: Boolean,
  23399. default: null
  23400. },
  23401. permanent: Boolean,
  23402. rail: {
  23403. type: Boolean,
  23404. default: null
  23405. },
  23406. railWidth: {
  23407. type: [Number, String],
  23408. default: 56
  23409. },
  23410. scrim: {
  23411. type: [Boolean, String],
  23412. default: true
  23413. },
  23414. image: String,
  23415. temporary: Boolean,
  23416. persistent: Boolean,
  23417. touchless: Boolean,
  23418. width: {
  23419. type: [Number, String],
  23420. default: 256
  23421. },
  23422. location: {
  23423. type: String,
  23424. default: 'start',
  23425. validator: value => locations.includes(value)
  23426. },
  23427. sticky: Boolean,
  23428. ...makeBorderProps(),
  23429. ...makeComponentProps(),
  23430. ...makeDelayProps(),
  23431. ...makeDisplayProps({
  23432. mobile: null
  23433. }),
  23434. ...makeElevationProps(),
  23435. ...makeLayoutItemProps(),
  23436. ...makeRoundedProps(),
  23437. ...makeTagProps({
  23438. tag: 'nav'
  23439. }),
  23440. ...makeThemeProps()
  23441. }, 'VNavigationDrawer');
  23442. const VNavigationDrawer = genericComponent()({
  23443. name: 'VNavigationDrawer',
  23444. props: makeVNavigationDrawerProps(),
  23445. emits: {
  23446. 'update:modelValue': val => true,
  23447. 'update:rail': val => true
  23448. },
  23449. setup(props, _ref) {
  23450. let {
  23451. attrs,
  23452. emit,
  23453. slots
  23454. } = _ref;
  23455. const {
  23456. isRtl
  23457. } = useRtl();
  23458. const {
  23459. themeClasses
  23460. } = provideTheme(props);
  23461. const {
  23462. borderClasses
  23463. } = useBorder(props);
  23464. const {
  23465. backgroundColorClasses,
  23466. backgroundColorStyles
  23467. } = useBackgroundColor(toRef(props, 'color'));
  23468. const {
  23469. elevationClasses
  23470. } = useElevation(props);
  23471. const {
  23472. displayClasses,
  23473. mobile
  23474. } = useDisplay(props);
  23475. const {
  23476. roundedClasses
  23477. } = useRounded(props);
  23478. const router = useRouter();
  23479. const isActive = useProxiedModel(props, 'modelValue', null, v => !!v);
  23480. const {
  23481. ssrBootStyles
  23482. } = useSsrBoot();
  23483. const {
  23484. scopeId
  23485. } = useScopeId();
  23486. const rootEl = ref();
  23487. const isHovering = shallowRef(false);
  23488. const {
  23489. runOpenDelay,
  23490. runCloseDelay
  23491. } = useDelay(props, value => {
  23492. isHovering.value = value;
  23493. });
  23494. const width = computed(() => {
  23495. return props.rail && props.expandOnHover && isHovering.value ? Number(props.width) : Number(props.rail ? props.railWidth : props.width);
  23496. });
  23497. const location = computed(() => {
  23498. return toPhysical(props.location, isRtl.value);
  23499. });
  23500. const isPersistent = computed(() => props.persistent);
  23501. const isTemporary = computed(() => !props.permanent && (mobile.value || props.temporary));
  23502. const isSticky = computed(() => props.sticky && !isTemporary.value && location.value !== 'bottom');
  23503. useToggleScope(() => props.expandOnHover && props.rail != null, () => {
  23504. watch(isHovering, val => emit('update:rail', !val));
  23505. });
  23506. useToggleScope(() => !props.disableResizeWatcher, () => {
  23507. watch(isTemporary, val => !props.permanent && nextTick(() => isActive.value = !val));
  23508. });
  23509. useToggleScope(() => !props.disableRouteWatcher && !!router, () => {
  23510. watch(router.currentRoute, () => isTemporary.value && (isActive.value = false));
  23511. });
  23512. watch(() => props.permanent, val => {
  23513. if (val) isActive.value = true;
  23514. });
  23515. if (props.modelValue == null && !isTemporary.value) {
  23516. isActive.value = props.permanent || !mobile.value;
  23517. }
  23518. const {
  23519. isDragging,
  23520. dragProgress
  23521. } = useTouch({
  23522. el: rootEl,
  23523. isActive,
  23524. isTemporary,
  23525. width,
  23526. touchless: toRef(props, 'touchless'),
  23527. position: location
  23528. });
  23529. const layoutSize = computed(() => {
  23530. const size = isTemporary.value ? 0 : props.rail && props.expandOnHover ? Number(props.railWidth) : width.value;
  23531. return isDragging.value ? size * dragProgress.value : size;
  23532. });
  23533. const elementSize = computed(() => ['top', 'bottom'].includes(props.location) ? 0 : width.value);
  23534. const {
  23535. layoutItemStyles,
  23536. layoutItemScrimStyles
  23537. } = useLayoutItem({
  23538. id: props.name,
  23539. order: computed(() => parseInt(props.order, 10)),
  23540. position: location,
  23541. layoutSize,
  23542. elementSize,
  23543. active: computed(() => isActive.value || isDragging.value),
  23544. disableTransitions: computed(() => isDragging.value),
  23545. absolute: computed(() =>
  23546. // eslint-disable-next-line @typescript-eslint/no-use-before-define
  23547. props.absolute || isSticky.value && typeof isStuck.value !== 'string')
  23548. });
  23549. const {
  23550. isStuck,
  23551. stickyStyles
  23552. } = useSticky({
  23553. rootEl,
  23554. isSticky,
  23555. layoutItemStyles
  23556. });
  23557. const scrimColor = useBackgroundColor(computed(() => {
  23558. return typeof props.scrim === 'string' ? props.scrim : null;
  23559. }));
  23560. const scrimStyles = computed(() => ({
  23561. ...(isDragging.value ? {
  23562. opacity: dragProgress.value * 0.2,
  23563. transition: 'none'
  23564. } : undefined),
  23565. ...layoutItemScrimStyles.value
  23566. }));
  23567. provideDefaults({
  23568. VList: {
  23569. bgColor: 'transparent'
  23570. }
  23571. });
  23572. useRender(() => {
  23573. const hasImage = slots.image || props.image;
  23574. return createVNode(Fragment, null, [createVNode(props.tag, mergeProps({
  23575. "ref": rootEl,
  23576. "onMouseenter": runOpenDelay,
  23577. "onMouseleave": runCloseDelay,
  23578. "class": ['v-navigation-drawer', `v-navigation-drawer--${location.value}`, {
  23579. 'v-navigation-drawer--expand-on-hover': props.expandOnHover,
  23580. 'v-navigation-drawer--floating': props.floating,
  23581. 'v-navigation-drawer--is-hovering': isHovering.value,
  23582. 'v-navigation-drawer--rail': props.rail,
  23583. 'v-navigation-drawer--temporary': isTemporary.value,
  23584. 'v-navigation-drawer--persistent': isPersistent.value,
  23585. 'v-navigation-drawer--active': isActive.value,
  23586. 'v-navigation-drawer--sticky': isSticky.value
  23587. }, themeClasses.value, backgroundColorClasses.value, borderClasses.value, displayClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  23588. "style": [backgroundColorStyles.value, layoutItemStyles.value, ssrBootStyles.value, stickyStyles.value, props.style, ['top', 'bottom'].includes(location.value) ? {
  23589. height: 'auto'
  23590. } : {}]
  23591. }, scopeId, attrs), {
  23592. default: () => [hasImage && createVNode("div", {
  23593. "key": "image",
  23594. "class": "v-navigation-drawer__img"
  23595. }, [!slots.image ? createVNode(VImg, {
  23596. "key": "image-img",
  23597. "alt": "",
  23598. "cover": true,
  23599. "height": "inherit",
  23600. "src": props.image
  23601. }, null) : createVNode(VDefaultsProvider, {
  23602. "key": "image-defaults",
  23603. "disabled": !props.image,
  23604. "defaults": {
  23605. VImg: {
  23606. alt: '',
  23607. cover: true,
  23608. height: 'inherit',
  23609. src: props.image
  23610. }
  23611. }
  23612. }, slots.image)]), slots.prepend && createVNode("div", {
  23613. "class": "v-navigation-drawer__prepend"
  23614. }, [slots.prepend?.()]), createVNode("div", {
  23615. "class": "v-navigation-drawer__content"
  23616. }, [slots.default?.()]), slots.append && createVNode("div", {
  23617. "class": "v-navigation-drawer__append"
  23618. }, [slots.append?.()])]
  23619. }), createVNode(Transition, {
  23620. "name": "fade-transition"
  23621. }, {
  23622. default: () => [isTemporary.value && (isDragging.value || isActive.value) && !!props.scrim && createVNode("div", mergeProps({
  23623. "class": ['v-navigation-drawer__scrim', scrimColor.backgroundColorClasses.value],
  23624. "style": [scrimStyles.value, scrimColor.backgroundColorStyles.value],
  23625. "onClick": () => {
  23626. if (isPersistent.value) return;
  23627. isActive.value = false;
  23628. }
  23629. }, scopeId), null)]
  23630. })]);
  23631. });
  23632. return {
  23633. isStuck
  23634. };
  23635. }
  23636. });
  23637. // Composables
  23638. const VNoSsr = defineComponent({
  23639. name: 'VNoSsr',
  23640. setup(_, _ref) {
  23641. let {
  23642. slots
  23643. } = _ref;
  23644. const show = useHydration();
  23645. return () => show.value && slots.default?.();
  23646. }
  23647. });
  23648. // Types
  23649. // Types
  23650. const makeVOtpInputProps = propsFactory({
  23651. autofocus: Boolean,
  23652. divider: String,
  23653. focusAll: Boolean,
  23654. label: {
  23655. type: String,
  23656. default: '$vuetify.input.otp'
  23657. },
  23658. length: {
  23659. type: [Number, String],
  23660. default: 6
  23661. },
  23662. modelValue: {
  23663. type: [Number, String],
  23664. default: undefined
  23665. },
  23666. placeholder: String,
  23667. type: {
  23668. type: String,
  23669. default: 'number'
  23670. },
  23671. ...makeDimensionProps(),
  23672. ...makeFocusProps(),
  23673. ...only(makeVFieldProps({
  23674. variant: 'outlined'
  23675. }), ['baseColor', 'bgColor', 'class', 'color', 'disabled', 'error', 'loading', 'rounded', 'style', 'theme', 'variant'])
  23676. }, 'VOtpInput');
  23677. const VOtpInput = genericComponent()({
  23678. name: 'VOtpInput',
  23679. props: makeVOtpInputProps(),
  23680. emits: {
  23681. finish: val => true,
  23682. 'update:focused': val => true,
  23683. 'update:modelValue': val => true
  23684. },
  23685. setup(props, _ref) {
  23686. let {
  23687. attrs,
  23688. emit,
  23689. slots
  23690. } = _ref;
  23691. const {
  23692. dimensionStyles
  23693. } = useDimension(props);
  23694. const {
  23695. isFocused,
  23696. focus,
  23697. blur
  23698. } = useFocus(props);
  23699. const model = useProxiedModel(props, 'modelValue', '', val => val == null ? [] : String(val).split(''), val => val.join(''));
  23700. const {
  23701. t
  23702. } = useLocale();
  23703. const length = computed(() => Number(props.length));
  23704. const fields = computed(() => Array(length.value).fill(0));
  23705. const focusIndex = ref(-1);
  23706. const contentRef = ref();
  23707. const inputRef = ref([]);
  23708. const current = computed(() => inputRef.value[focusIndex.value]);
  23709. function onInput() {
  23710. // The maxlength attribute doesn't work for the number type input, so the text type is used.
  23711. // The following logic simulates the behavior of a number input.
  23712. if (isValidNumber(current.value.value)) {
  23713. current.value.value = '';
  23714. return;
  23715. }
  23716. const array = model.value.slice();
  23717. const value = current.value.value;
  23718. array[focusIndex.value] = value;
  23719. let target = null;
  23720. if (focusIndex.value > model.value.length) {
  23721. target = model.value.length + 1;
  23722. } else if (focusIndex.value + 1 !== length.value) {
  23723. target = 'next';
  23724. }
  23725. model.value = array;
  23726. if (target) focusChild(contentRef.value, target);
  23727. }
  23728. function onKeydown(e) {
  23729. const array = model.value.slice();
  23730. const index = focusIndex.value;
  23731. let target = null;
  23732. if (!['ArrowLeft', 'ArrowRight', 'Backspace', 'Delete'].includes(e.key)) return;
  23733. e.preventDefault();
  23734. if (e.key === 'ArrowLeft') {
  23735. target = 'prev';
  23736. } else if (e.key === 'ArrowRight') {
  23737. target = 'next';
  23738. } else if (['Backspace', 'Delete'].includes(e.key)) {
  23739. array[focusIndex.value] = '';
  23740. model.value = array;
  23741. if (focusIndex.value > 0 && e.key === 'Backspace') {
  23742. target = 'prev';
  23743. } else {
  23744. requestAnimationFrame(() => {
  23745. inputRef.value[index]?.select();
  23746. });
  23747. }
  23748. }
  23749. requestAnimationFrame(() => {
  23750. if (target != null) {
  23751. focusChild(contentRef.value, target);
  23752. }
  23753. });
  23754. }
  23755. function onPaste(index, e) {
  23756. e.preventDefault();
  23757. e.stopPropagation();
  23758. const clipboardText = e?.clipboardData?.getData('Text').slice(0, length.value) ?? '';
  23759. if (isValidNumber(clipboardText)) return;
  23760. model.value = clipboardText.split('');
  23761. inputRef.value?.[index].blur();
  23762. }
  23763. function reset() {
  23764. model.value = [];
  23765. }
  23766. function onFocus(e, index) {
  23767. focus();
  23768. focusIndex.value = index;
  23769. }
  23770. function onBlur() {
  23771. blur();
  23772. focusIndex.value = -1;
  23773. }
  23774. function isValidNumber(value) {
  23775. return props.type === 'number' && /[^0-9]/g.test(value);
  23776. }
  23777. provideDefaults({
  23778. VField: {
  23779. color: computed(() => props.color),
  23780. bgColor: computed(() => props.color),
  23781. baseColor: computed(() => props.baseColor),
  23782. disabled: computed(() => props.disabled),
  23783. error: computed(() => props.error),
  23784. variant: computed(() => props.variant)
  23785. }
  23786. }, {
  23787. scoped: true
  23788. });
  23789. watch(model, val => {
  23790. if (val.length === length.value) emit('finish', val.join(''));
  23791. }, {
  23792. deep: true
  23793. });
  23794. watch(focusIndex, val => {
  23795. if (val < 0) return;
  23796. nextTick(() => {
  23797. inputRef.value[val]?.select();
  23798. });
  23799. });
  23800. useRender(() => {
  23801. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  23802. return createVNode("div", mergeProps({
  23803. "class": ['v-otp-input', {
  23804. 'v-otp-input--divided': !!props.divider
  23805. }, props.class],
  23806. "style": [props.style]
  23807. }, rootAttrs), [createVNode("div", {
  23808. "ref": contentRef,
  23809. "class": "v-otp-input__content",
  23810. "style": [dimensionStyles.value]
  23811. }, [fields.value.map((_, i) => createVNode(Fragment, null, [props.divider && i !== 0 && createVNode("span", {
  23812. "class": "v-otp-input__divider"
  23813. }, [props.divider]), createVNode(VField, {
  23814. "focused": isFocused.value && props.focusAll || focusIndex.value === i,
  23815. "key": i
  23816. }, {
  23817. ...slots,
  23818. loader: undefined,
  23819. default: () => {
  23820. return createVNode("input", {
  23821. "ref": val => inputRef.value[i] = val,
  23822. "aria-label": t(props.label, i + 1),
  23823. "autofocus": i === 0 && props.autofocus,
  23824. "autocomplete": "one-time-code",
  23825. "class": ['v-otp-input__field'],
  23826. "disabled": props.disabled,
  23827. "inputmode": props.type === 'number' ? 'numeric' : 'text',
  23828. "min": props.type === 'number' ? 0 : undefined,
  23829. "maxlength": "1",
  23830. "placeholder": props.placeholder,
  23831. "type": props.type === 'number' ? 'text' : props.type,
  23832. "value": model.value[i],
  23833. "onInput": onInput,
  23834. "onFocus": e => onFocus(e, i),
  23835. "onBlur": onBlur,
  23836. "onKeydown": onKeydown,
  23837. "onPaste": event => onPaste(i, event)
  23838. }, null);
  23839. }
  23840. })])), createVNode("input", mergeProps({
  23841. "class": "v-otp-input-input",
  23842. "type": "hidden"
  23843. }, inputAttrs, {
  23844. "value": model.value.join('')
  23845. }), null), createVNode(VOverlay, {
  23846. "contained": true,
  23847. "content-class": "v-otp-input__loader",
  23848. "model-value": !!props.loading,
  23849. "persistent": true
  23850. }, {
  23851. default: () => [slots.loader?.() ?? createVNode(VProgressCircular, {
  23852. "color": typeof props.loading === 'boolean' ? undefined : props.loading,
  23853. "indeterminate": true,
  23854. "size": "24",
  23855. "width": "2"
  23856. }, null)]
  23857. }), slots.default?.()])]);
  23858. });
  23859. return {
  23860. blur: () => {
  23861. inputRef.value?.some(input => input.blur());
  23862. },
  23863. focus: () => {
  23864. inputRef.value?.[0].focus();
  23865. },
  23866. reset,
  23867. isFocused
  23868. };
  23869. }
  23870. });
  23871. // Types
  23872. function floor(val) {
  23873. return Math.floor(Math.abs(val)) * Math.sign(val);
  23874. }
  23875. const makeVParallaxProps = propsFactory({
  23876. scale: {
  23877. type: [Number, String],
  23878. default: 0.5
  23879. },
  23880. ...makeComponentProps()
  23881. }, 'VParallax');
  23882. const VParallax = genericComponent()({
  23883. name: 'VParallax',
  23884. props: makeVParallaxProps(),
  23885. setup(props, _ref) {
  23886. let {
  23887. slots
  23888. } = _ref;
  23889. const {
  23890. intersectionRef,
  23891. isIntersecting
  23892. } = useIntersectionObserver();
  23893. const {
  23894. resizeRef,
  23895. contentRect
  23896. } = useResizeObserver();
  23897. const {
  23898. height: displayHeight
  23899. } = useDisplay();
  23900. const root = ref();
  23901. watchEffect(() => {
  23902. intersectionRef.value = resizeRef.value = root.value?.$el;
  23903. });
  23904. let scrollParent;
  23905. watch(isIntersecting, val => {
  23906. if (val) {
  23907. scrollParent = getScrollParent(intersectionRef.value);
  23908. scrollParent = scrollParent === document.scrollingElement ? document : scrollParent;
  23909. scrollParent.addEventListener('scroll', onScroll, {
  23910. passive: true
  23911. });
  23912. onScroll();
  23913. } else {
  23914. scrollParent.removeEventListener('scroll', onScroll);
  23915. }
  23916. });
  23917. onBeforeUnmount(() => {
  23918. scrollParent?.removeEventListener('scroll', onScroll);
  23919. });
  23920. watch(displayHeight, onScroll);
  23921. watch(() => contentRect.value?.height, onScroll);
  23922. const scale = computed(() => {
  23923. return 1 - clamp(+props.scale);
  23924. });
  23925. let frame = -1;
  23926. function onScroll() {
  23927. if (!isIntersecting.value) return;
  23928. cancelAnimationFrame(frame);
  23929. frame = requestAnimationFrame(() => {
  23930. const el = (root.value?.$el).querySelector('.v-img__img');
  23931. if (!el) return;
  23932. const scrollHeight = scrollParent instanceof Document ? document.documentElement.clientHeight : scrollParent.clientHeight;
  23933. const scrollPos = scrollParent instanceof Document ? window.scrollY : scrollParent.scrollTop;
  23934. const top = intersectionRef.value.getBoundingClientRect().top + scrollPos;
  23935. const height = contentRect.value.height;
  23936. const center = top + (height - scrollHeight) / 2;
  23937. const translate = floor((scrollPos - center) * scale.value);
  23938. const sizeScale = Math.max(1, (scale.value * (scrollHeight - height) + height) / height);
  23939. el.style.setProperty('transform', `translateY(${translate}px) scale(${sizeScale})`);
  23940. });
  23941. }
  23942. useRender(() => createVNode(VImg, {
  23943. "class": ['v-parallax', {
  23944. 'v-parallax--active': isIntersecting.value
  23945. }, props.class],
  23946. "style": props.style,
  23947. "ref": root,
  23948. "cover": true,
  23949. "onLoadstart": onScroll,
  23950. "onLoad": onScroll
  23951. }, slots));
  23952. return {};
  23953. }
  23954. });
  23955. // Types
  23956. const makeVRadioProps = propsFactory({
  23957. ...makeVSelectionControlProps({
  23958. falseIcon: '$radioOff',
  23959. trueIcon: '$radioOn'
  23960. })
  23961. }, 'VRadio');
  23962. const VRadio = genericComponent()({
  23963. name: 'VRadio',
  23964. props: makeVRadioProps(),
  23965. setup(props, _ref) {
  23966. let {
  23967. slots
  23968. } = _ref;
  23969. useRender(() => {
  23970. const controlProps = VSelectionControl.filterProps(props);
  23971. return createVNode(VSelectionControl, mergeProps(controlProps, {
  23972. "class": ['v-radio', props.class],
  23973. "style": props.style,
  23974. "type": "radio"
  23975. }), slots);
  23976. });
  23977. return {};
  23978. }
  23979. });
  23980. // Types
  23981. const makeVRadioGroupProps = propsFactory({
  23982. height: {
  23983. type: [Number, String],
  23984. default: 'auto'
  23985. },
  23986. ...makeVInputProps(),
  23987. ...omit(makeSelectionControlGroupProps(), ['multiple']),
  23988. trueIcon: {
  23989. type: IconValue,
  23990. default: '$radioOn'
  23991. },
  23992. falseIcon: {
  23993. type: IconValue,
  23994. default: '$radioOff'
  23995. },
  23996. type: {
  23997. type: String,
  23998. default: 'radio'
  23999. }
  24000. }, 'VRadioGroup');
  24001. const VRadioGroup = genericComponent()({
  24002. name: 'VRadioGroup',
  24003. inheritAttrs: false,
  24004. props: makeVRadioGroupProps(),
  24005. emits: {
  24006. 'update:modelValue': value => true
  24007. },
  24008. setup(props, _ref) {
  24009. let {
  24010. attrs,
  24011. slots
  24012. } = _ref;
  24013. const uid = getUid();
  24014. const id = computed(() => props.id || `radio-group-${uid}`);
  24015. const model = useProxiedModel(props, 'modelValue');
  24016. useRender(() => {
  24017. const [rootAttrs, controlAttrs] = filterInputAttrs(attrs);
  24018. const inputProps = VInput.filterProps(props);
  24019. const controlProps = VSelectionControl.filterProps(props);
  24020. const label = slots.label ? slots.label({
  24021. label: props.label,
  24022. props: {
  24023. for: id.value
  24024. }
  24025. }) : props.label;
  24026. return createVNode(VInput, mergeProps({
  24027. "class": ['v-radio-group', props.class],
  24028. "style": props.style
  24029. }, rootAttrs, inputProps, {
  24030. "modelValue": model.value,
  24031. "onUpdate:modelValue": $event => model.value = $event,
  24032. "id": id.value
  24033. }), {
  24034. ...slots,
  24035. default: _ref2 => {
  24036. let {
  24037. id,
  24038. messagesId,
  24039. isDisabled,
  24040. isReadonly
  24041. } = _ref2;
  24042. return createVNode(Fragment, null, [label && createVNode(VLabel, {
  24043. "id": id.value
  24044. }, {
  24045. default: () => [label]
  24046. }), createVNode(VSelectionControlGroup, mergeProps(controlProps, {
  24047. "id": id.value,
  24048. "aria-describedby": messagesId.value,
  24049. "defaultsTarget": "VRadio",
  24050. "trueIcon": props.trueIcon,
  24051. "falseIcon": props.falseIcon,
  24052. "type": props.type,
  24053. "disabled": isDisabled.value,
  24054. "readonly": isReadonly.value,
  24055. "aria-labelledby": label ? id.value : undefined,
  24056. "multiple": false
  24057. }, controlAttrs, {
  24058. "modelValue": model.value,
  24059. "onUpdate:modelValue": $event => model.value = $event
  24060. }), slots)]);
  24061. }
  24062. });
  24063. });
  24064. return {};
  24065. }
  24066. });
  24067. // Types
  24068. const makeVRangeSliderProps = propsFactory({
  24069. ...makeFocusProps(),
  24070. ...makeVInputProps(),
  24071. ...makeSliderProps(),
  24072. strict: Boolean,
  24073. modelValue: {
  24074. type: Array,
  24075. default: () => [0, 0]
  24076. }
  24077. }, 'VRangeSlider');
  24078. const VRangeSlider = genericComponent()({
  24079. name: 'VRangeSlider',
  24080. props: makeVRangeSliderProps(),
  24081. emits: {
  24082. 'update:focused': value => true,
  24083. 'update:modelValue': value => true,
  24084. end: value => true,
  24085. start: value => true
  24086. },
  24087. setup(props, _ref) {
  24088. let {
  24089. slots,
  24090. emit
  24091. } = _ref;
  24092. const startThumbRef = ref();
  24093. const stopThumbRef = ref();
  24094. const inputRef = ref();
  24095. const {
  24096. rtlClasses
  24097. } = useRtl();
  24098. function getActiveThumb(e) {
  24099. if (!startThumbRef.value || !stopThumbRef.value) return;
  24100. const startOffset = getOffset(e, startThumbRef.value.$el, props.direction);
  24101. const stopOffset = getOffset(e, stopThumbRef.value.$el, props.direction);
  24102. const a = Math.abs(startOffset);
  24103. const b = Math.abs(stopOffset);
  24104. return a < b || a === b && startOffset < 0 ? startThumbRef.value.$el : stopThumbRef.value.$el;
  24105. }
  24106. const steps = useSteps(props);
  24107. const model = useProxiedModel(props, 'modelValue', undefined, arr => {
  24108. if (!arr?.length) return [0, 0];
  24109. return arr.map(value => steps.roundValue(value));
  24110. });
  24111. const {
  24112. activeThumbRef,
  24113. hasLabels,
  24114. max,
  24115. min,
  24116. mousePressed,
  24117. onSliderMousedown,
  24118. onSliderTouchstart,
  24119. position,
  24120. trackContainerRef,
  24121. readonly
  24122. } = useSlider({
  24123. props,
  24124. steps,
  24125. onSliderStart: () => {
  24126. emit('start', model.value);
  24127. },
  24128. onSliderEnd: _ref2 => {
  24129. let {
  24130. value
  24131. } = _ref2;
  24132. const newValue = activeThumbRef.value === startThumbRef.value?.$el ? [value, model.value[1]] : [model.value[0], value];
  24133. if (!props.strict && newValue[0] < newValue[1]) {
  24134. model.value = newValue;
  24135. }
  24136. emit('end', model.value);
  24137. },
  24138. onSliderMove: _ref3 => {
  24139. let {
  24140. value
  24141. } = _ref3;
  24142. const [start, stop] = model.value;
  24143. if (!props.strict && start === stop && start !== min.value) {
  24144. activeThumbRef.value = value > start ? stopThumbRef.value?.$el : startThumbRef.value?.$el;
  24145. activeThumbRef.value?.focus();
  24146. }
  24147. if (activeThumbRef.value === startThumbRef.value?.$el) {
  24148. model.value = [Math.min(value, stop), stop];
  24149. } else {
  24150. model.value = [start, Math.max(start, value)];
  24151. }
  24152. },
  24153. getActiveThumb
  24154. });
  24155. const {
  24156. isFocused,
  24157. focus,
  24158. blur
  24159. } = useFocus(props);
  24160. const trackStart = computed(() => position(model.value[0]));
  24161. const trackStop = computed(() => position(model.value[1]));
  24162. useRender(() => {
  24163. const inputProps = VInput.filterProps(props);
  24164. const hasPrepend = !!(props.label || slots.label || slots.prepend);
  24165. return createVNode(VInput, mergeProps({
  24166. "class": ['v-slider', 'v-range-slider', {
  24167. 'v-slider--has-labels': !!slots['tick-label'] || hasLabels.value,
  24168. 'v-slider--focused': isFocused.value,
  24169. 'v-slider--pressed': mousePressed.value,
  24170. 'v-slider--disabled': props.disabled
  24171. }, rtlClasses.value, props.class],
  24172. "style": props.style,
  24173. "ref": inputRef
  24174. }, inputProps, {
  24175. "focused": isFocused.value
  24176. }), {
  24177. ...slots,
  24178. prepend: hasPrepend ? slotProps => createVNode(Fragment, null, [slots.label?.(slotProps) ?? (props.label ? createVNode(VLabel, {
  24179. "class": "v-slider__label",
  24180. "text": props.label
  24181. }, null) : undefined), slots.prepend?.(slotProps)]) : undefined,
  24182. default: _ref4 => {
  24183. let {
  24184. id,
  24185. messagesId
  24186. } = _ref4;
  24187. return createVNode("div", {
  24188. "class": "v-slider__container",
  24189. "onMousedown": !readonly.value ? onSliderMousedown : undefined,
  24190. "onTouchstartPassive": !readonly.value ? onSliderTouchstart : undefined
  24191. }, [createVNode("input", {
  24192. "id": `${id.value}_start`,
  24193. "name": props.name || id.value,
  24194. "disabled": !!props.disabled,
  24195. "readonly": !!props.readonly,
  24196. "tabindex": "-1",
  24197. "value": model.value[0]
  24198. }, null), createVNode("input", {
  24199. "id": `${id.value}_stop`,
  24200. "name": props.name || id.value,
  24201. "disabled": !!props.disabled,
  24202. "readonly": !!props.readonly,
  24203. "tabindex": "-1",
  24204. "value": model.value[1]
  24205. }, null), createVNode(VSliderTrack, {
  24206. "ref": trackContainerRef,
  24207. "start": trackStart.value,
  24208. "stop": trackStop.value
  24209. }, {
  24210. 'tick-label': slots['tick-label']
  24211. }), createVNode(VSliderThumb, {
  24212. "ref": startThumbRef,
  24213. "aria-describedby": messagesId.value,
  24214. "focused": isFocused && activeThumbRef.value === startThumbRef.value?.$el,
  24215. "modelValue": model.value[0],
  24216. "onUpdate:modelValue": v => model.value = [v, model.value[1]],
  24217. "onFocus": e => {
  24218. focus();
  24219. activeThumbRef.value = startThumbRef.value?.$el;
  24220. // Make sure second thumb is focused if
  24221. // the thumbs are on top of each other
  24222. // and they are both at minimum value
  24223. // but only if focused from outside.
  24224. if (max.value !== min.value && model.value[0] === model.value[1] && model.value[1] === min.value && e.relatedTarget !== stopThumbRef.value?.$el) {
  24225. startThumbRef.value?.$el.blur();
  24226. stopThumbRef.value?.$el.focus();
  24227. }
  24228. },
  24229. "onBlur": () => {
  24230. blur();
  24231. activeThumbRef.value = undefined;
  24232. },
  24233. "min": min.value,
  24234. "max": model.value[1],
  24235. "position": trackStart.value,
  24236. "ripple": props.ripple
  24237. }, {
  24238. 'thumb-label': slots['thumb-label']
  24239. }), createVNode(VSliderThumb, {
  24240. "ref": stopThumbRef,
  24241. "aria-describedby": messagesId.value,
  24242. "focused": isFocused && activeThumbRef.value === stopThumbRef.value?.$el,
  24243. "modelValue": model.value[1],
  24244. "onUpdate:modelValue": v => model.value = [model.value[0], v],
  24245. "onFocus": e => {
  24246. focus();
  24247. activeThumbRef.value = stopThumbRef.value?.$el;
  24248. // Make sure first thumb is focused if
  24249. // the thumbs are on top of each other
  24250. // and they are both at maximum value
  24251. // but only if focused from outside.
  24252. if (max.value !== min.value && model.value[0] === model.value[1] && model.value[0] === max.value && e.relatedTarget !== startThumbRef.value?.$el) {
  24253. stopThumbRef.value?.$el.blur();
  24254. startThumbRef.value?.$el.focus();
  24255. }
  24256. },
  24257. "onBlur": () => {
  24258. blur();
  24259. activeThumbRef.value = undefined;
  24260. },
  24261. "min": model.value[0],
  24262. "max": max.value,
  24263. "position": trackStop.value,
  24264. "ripple": props.ripple
  24265. }, {
  24266. 'thumb-label': slots['thumb-label']
  24267. })]);
  24268. }
  24269. });
  24270. });
  24271. return {};
  24272. }
  24273. });
  24274. // Types
  24275. const makeVRatingProps = propsFactory({
  24276. name: String,
  24277. itemAriaLabel: {
  24278. type: String,
  24279. default: '$vuetify.rating.ariaLabel.item'
  24280. },
  24281. activeColor: String,
  24282. color: String,
  24283. clearable: Boolean,
  24284. disabled: Boolean,
  24285. emptyIcon: {
  24286. type: IconValue,
  24287. default: '$ratingEmpty'
  24288. },
  24289. fullIcon: {
  24290. type: IconValue,
  24291. default: '$ratingFull'
  24292. },
  24293. halfIncrements: Boolean,
  24294. hover: Boolean,
  24295. length: {
  24296. type: [Number, String],
  24297. default: 5
  24298. },
  24299. readonly: Boolean,
  24300. modelValue: {
  24301. type: [Number, String],
  24302. default: 0
  24303. },
  24304. itemLabels: Array,
  24305. itemLabelPosition: {
  24306. type: String,
  24307. default: 'top',
  24308. validator: v => ['top', 'bottom'].includes(v)
  24309. },
  24310. ripple: Boolean,
  24311. ...makeComponentProps(),
  24312. ...makeDensityProps(),
  24313. ...makeSizeProps(),
  24314. ...makeTagProps(),
  24315. ...makeThemeProps()
  24316. }, 'VRating');
  24317. const VRating = genericComponent()({
  24318. name: 'VRating',
  24319. props: makeVRatingProps(),
  24320. emits: {
  24321. 'update:modelValue': value => true
  24322. },
  24323. setup(props, _ref) {
  24324. let {
  24325. slots
  24326. } = _ref;
  24327. const {
  24328. t
  24329. } = useLocale();
  24330. const {
  24331. themeClasses
  24332. } = provideTheme(props);
  24333. const rating = useProxiedModel(props, 'modelValue');
  24334. const normalizedValue = computed(() => clamp(parseFloat(rating.value), 0, +props.length));
  24335. const range = computed(() => createRange(Number(props.length), 1));
  24336. const increments = computed(() => range.value.flatMap(v => props.halfIncrements ? [v - 0.5, v] : [v]));
  24337. const hoverIndex = shallowRef(-1);
  24338. const itemState = computed(() => increments.value.map(value => {
  24339. const isHovering = props.hover && hoverIndex.value > -1;
  24340. const isFilled = normalizedValue.value >= value;
  24341. const isHovered = hoverIndex.value >= value;
  24342. const isFullIcon = isHovering ? isHovered : isFilled;
  24343. const icon = isFullIcon ? props.fullIcon : props.emptyIcon;
  24344. const activeColor = props.activeColor ?? props.color;
  24345. const color = isFilled || isHovered ? activeColor : props.color;
  24346. return {
  24347. isFilled,
  24348. isHovered,
  24349. icon,
  24350. color
  24351. };
  24352. }));
  24353. const eventState = computed(() => [0, ...increments.value].map(value => {
  24354. function onMouseenter() {
  24355. hoverIndex.value = value;
  24356. }
  24357. function onMouseleave() {
  24358. hoverIndex.value = -1;
  24359. }
  24360. function onClick() {
  24361. if (props.disabled || props.readonly) return;
  24362. rating.value = normalizedValue.value === value && props.clearable ? 0 : value;
  24363. }
  24364. return {
  24365. onMouseenter: props.hover ? onMouseenter : undefined,
  24366. onMouseleave: props.hover ? onMouseleave : undefined,
  24367. onClick
  24368. };
  24369. }));
  24370. const name = computed(() => props.name ?? `v-rating-${getUid()}`);
  24371. function VRatingItem(_ref2) {
  24372. let {
  24373. value,
  24374. index,
  24375. showStar = true
  24376. } = _ref2;
  24377. const {
  24378. onMouseenter,
  24379. onMouseleave,
  24380. onClick
  24381. } = eventState.value[index + 1];
  24382. const id = `${name.value}-${String(value).replace('.', '-')}`;
  24383. const btnProps = {
  24384. color: itemState.value[index]?.color,
  24385. density: props.density,
  24386. disabled: props.disabled,
  24387. icon: itemState.value[index]?.icon,
  24388. ripple: props.ripple,
  24389. size: props.size,
  24390. variant: 'plain'
  24391. };
  24392. return createVNode(Fragment, null, [createVNode("label", {
  24393. "for": id,
  24394. "class": {
  24395. 'v-rating__item--half': props.halfIncrements && value % 1 > 0,
  24396. 'v-rating__item--full': props.halfIncrements && value % 1 === 0
  24397. },
  24398. "onMouseenter": onMouseenter,
  24399. "onMouseleave": onMouseleave,
  24400. "onClick": onClick
  24401. }, [createVNode("span", {
  24402. "class": "v-rating__hidden"
  24403. }, [t(props.itemAriaLabel, value, props.length)]), !showStar ? undefined : slots.item ? slots.item({
  24404. ...itemState.value[index],
  24405. props: btnProps,
  24406. value,
  24407. index,
  24408. rating: normalizedValue.value
  24409. }) : createVNode(VBtn, mergeProps({
  24410. "aria-label": t(props.itemAriaLabel, value, props.length)
  24411. }, btnProps), null)]), createVNode("input", {
  24412. "class": "v-rating__hidden",
  24413. "name": name.value,
  24414. "id": id,
  24415. "type": "radio",
  24416. "value": value,
  24417. "checked": normalizedValue.value === value,
  24418. "tabindex": -1,
  24419. "readonly": props.readonly,
  24420. "disabled": props.disabled
  24421. }, null)]);
  24422. }
  24423. function createLabel(labelProps) {
  24424. if (slots['item-label']) return slots['item-label'](labelProps);
  24425. if (labelProps.label) return createVNode("span", null, [labelProps.label]);
  24426. return createVNode("span", null, [createTextVNode("\xA0")]);
  24427. }
  24428. useRender(() => {
  24429. const hasLabels = !!props.itemLabels?.length || slots['item-label'];
  24430. return createVNode(props.tag, {
  24431. "class": ['v-rating', {
  24432. 'v-rating--hover': props.hover,
  24433. 'v-rating--readonly': props.readonly
  24434. }, themeClasses.value, props.class],
  24435. "style": props.style
  24436. }, {
  24437. default: () => [createVNode(VRatingItem, {
  24438. "value": 0,
  24439. "index": -1,
  24440. "showStar": false
  24441. }, null), range.value.map((value, i) => createVNode("div", {
  24442. "class": "v-rating__wrapper"
  24443. }, [hasLabels && props.itemLabelPosition === 'top' ? createLabel({
  24444. value,
  24445. index: i,
  24446. label: props.itemLabels?.[i]
  24447. }) : undefined, createVNode("div", {
  24448. "class": "v-rating__item"
  24449. }, [props.halfIncrements ? createVNode(Fragment, null, [createVNode(VRatingItem, {
  24450. "value": value - 0.5,
  24451. "index": i * 2
  24452. }, null), createVNode(VRatingItem, {
  24453. "value": value,
  24454. "index": i * 2 + 1
  24455. }, null)]) : createVNode(VRatingItem, {
  24456. "value": value,
  24457. "index": i
  24458. }, null)]), hasLabels && props.itemLabelPosition === 'bottom' ? createLabel({
  24459. value,
  24460. index: i,
  24461. label: props.itemLabels?.[i]
  24462. }) : undefined]))]
  24463. });
  24464. });
  24465. return {};
  24466. }
  24467. });
  24468. // Types
  24469. const rootTypes = {
  24470. actions: 'button@2',
  24471. article: 'heading, paragraph',
  24472. avatar: 'avatar',
  24473. button: 'button',
  24474. card: 'image, heading',
  24475. 'card-avatar': 'image, list-item-avatar',
  24476. chip: 'chip',
  24477. 'date-picker': 'list-item, heading, divider, date-picker-options, date-picker-days, actions',
  24478. 'date-picker-options': 'text, avatar@2',
  24479. 'date-picker-days': 'avatar@28',
  24480. divider: 'divider',
  24481. heading: 'heading',
  24482. image: 'image',
  24483. 'list-item': 'text',
  24484. 'list-item-avatar': 'avatar, text',
  24485. 'list-item-two-line': 'sentences',
  24486. 'list-item-avatar-two-line': 'avatar, sentences',
  24487. 'list-item-three-line': 'paragraph',
  24488. 'list-item-avatar-three-line': 'avatar, paragraph',
  24489. ossein: 'ossein',
  24490. paragraph: 'text@3',
  24491. sentences: 'text@2',
  24492. subtitle: 'text',
  24493. table: 'table-heading, table-thead, table-tbody, table-tfoot',
  24494. 'table-heading': 'chip, text',
  24495. 'table-thead': 'heading@6',
  24496. 'table-tbody': 'table-row-divider@6',
  24497. 'table-row-divider': 'table-row, divider',
  24498. 'table-row': 'text@6',
  24499. 'table-tfoot': 'text@2, avatar@2',
  24500. text: 'text'
  24501. };
  24502. function genBone(type) {
  24503. let children = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  24504. return createVNode("div", {
  24505. "class": ['v-skeleton-loader__bone', `v-skeleton-loader__${type}`]
  24506. }, [children]);
  24507. }
  24508. function genBones(bone) {
  24509. // e.g. 'text@3'
  24510. const [type, length] = bone.split('@');
  24511. // Generate a length array based upon
  24512. // value after @ in the bone string
  24513. return Array.from({
  24514. length
  24515. }).map(() => genStructure(type));
  24516. }
  24517. function genStructure(type) {
  24518. let children = [];
  24519. if (!type) return children;
  24520. // TODO: figure out a better way to type this
  24521. const bone = rootTypes[type];
  24522. // End of recursion, do nothing
  24523. /* eslint-disable-next-line no-empty, brace-style */
  24524. if (type === bone) ;
  24525. // Array of values - e.g. 'heading, paragraph, text@2'
  24526. else if (type.includes(',')) return mapBones(type);
  24527. // Array of values - e.g. 'paragraph@4'
  24528. else if (type.includes('@')) return genBones(type);
  24529. // Array of values - e.g. 'card@2'
  24530. else if (bone.includes(',')) children = mapBones(bone);
  24531. // Array of values - e.g. 'list-item@2'
  24532. else if (bone.includes('@')) children = genBones(bone);
  24533. // Single value - e.g. 'card-heading'
  24534. else if (bone) children.push(genStructure(bone));
  24535. return [genBone(type, children)];
  24536. }
  24537. function mapBones(bones) {
  24538. // Remove spaces and return array of structures
  24539. return bones.replace(/\s/g, '').split(',').map(genStructure);
  24540. }
  24541. const makeVSkeletonLoaderProps = propsFactory({
  24542. boilerplate: Boolean,
  24543. color: String,
  24544. loading: Boolean,
  24545. loadingText: {
  24546. type: String,
  24547. default: '$vuetify.loading'
  24548. },
  24549. type: {
  24550. type: [String, Array],
  24551. default: 'ossein'
  24552. },
  24553. ...makeDimensionProps(),
  24554. ...makeElevationProps(),
  24555. ...makeThemeProps()
  24556. }, 'VSkeletonLoader');
  24557. const VSkeletonLoader = genericComponent()({
  24558. name: 'VSkeletonLoader',
  24559. props: makeVSkeletonLoaderProps(),
  24560. setup(props, _ref) {
  24561. let {
  24562. slots
  24563. } = _ref;
  24564. const {
  24565. backgroundColorClasses,
  24566. backgroundColorStyles
  24567. } = useBackgroundColor(toRef(props, 'color'));
  24568. const {
  24569. dimensionStyles
  24570. } = useDimension(props);
  24571. const {
  24572. elevationClasses
  24573. } = useElevation(props);
  24574. const {
  24575. themeClasses
  24576. } = provideTheme(props);
  24577. const {
  24578. t
  24579. } = useLocale();
  24580. const items = computed(() => genStructure(wrapInArray(props.type).join(',')));
  24581. useRender(() => {
  24582. const isLoading = !slots.default || props.loading;
  24583. const loadingProps = props.boilerplate || !isLoading ? {} : {
  24584. ariaLive: 'polite',
  24585. ariaLabel: t(props.loadingText),
  24586. role: 'alert'
  24587. };
  24588. return createVNode("div", mergeProps({
  24589. "class": ['v-skeleton-loader', {
  24590. 'v-skeleton-loader--boilerplate': props.boilerplate
  24591. }, themeClasses.value, backgroundColorClasses.value, elevationClasses.value],
  24592. "style": [backgroundColorStyles.value, isLoading ? dimensionStyles.value : {}]
  24593. }, loadingProps), [isLoading ? items.value : slots.default?.()]);
  24594. });
  24595. return {};
  24596. }
  24597. });
  24598. // Composables
  24599. // Types
  24600. const VSlideGroupItem = genericComponent()({
  24601. name: 'VSlideGroupItem',
  24602. props: makeGroupItemProps(),
  24603. emits: {
  24604. 'group:selected': val => true
  24605. },
  24606. setup(props, _ref) {
  24607. let {
  24608. slots
  24609. } = _ref;
  24610. const slideGroupItem = useGroupItem(props, VSlideGroupSymbol);
  24611. return () => slots.default?.({
  24612. isSelected: slideGroupItem.isSelected.value,
  24613. select: slideGroupItem.select,
  24614. toggle: slideGroupItem.toggle,
  24615. selectedClass: slideGroupItem.selectedClass.value
  24616. });
  24617. }
  24618. });
  24619. // Types
  24620. function useCountdown(milliseconds) {
  24621. const time = shallowRef(milliseconds());
  24622. let timer = -1;
  24623. function clear() {
  24624. clearInterval(timer);
  24625. }
  24626. function reset() {
  24627. clear();
  24628. nextTick(() => time.value = milliseconds());
  24629. }
  24630. function start(el) {
  24631. const style = el ? getComputedStyle(el) : {
  24632. transitionDuration: 0.2
  24633. };
  24634. const interval = parseFloat(style.transitionDuration) * 1000 || 200;
  24635. clear();
  24636. if (time.value <= 0) return;
  24637. const startTime = performance.now();
  24638. timer = window.setInterval(() => {
  24639. const elapsed = performance.now() - startTime + interval;
  24640. time.value = Math.max(milliseconds() - elapsed, 0);
  24641. if (time.value <= 0) clear();
  24642. }, interval);
  24643. }
  24644. onScopeDispose(clear);
  24645. return {
  24646. clear,
  24647. time,
  24648. start,
  24649. reset
  24650. };
  24651. }
  24652. const makeVSnackbarProps = propsFactory({
  24653. multiLine: Boolean,
  24654. text: String,
  24655. timer: [Boolean, String],
  24656. timeout: {
  24657. type: [Number, String],
  24658. default: 5000
  24659. },
  24660. vertical: Boolean,
  24661. ...makeLocationProps({
  24662. location: 'bottom'
  24663. }),
  24664. ...makePositionProps(),
  24665. ...makeRoundedProps(),
  24666. ...makeVariantProps(),
  24667. ...makeThemeProps(),
  24668. ...omit(makeVOverlayProps({
  24669. transition: 'v-snackbar-transition'
  24670. }), ['persistent', 'noClickAnimation', 'scrim', 'scrollStrategy'])
  24671. }, 'VSnackbar');
  24672. const VSnackbar = genericComponent()({
  24673. name: 'VSnackbar',
  24674. props: makeVSnackbarProps(),
  24675. emits: {
  24676. 'update:modelValue': v => true
  24677. },
  24678. setup(props, _ref) {
  24679. let {
  24680. slots
  24681. } = _ref;
  24682. const isActive = useProxiedModel(props, 'modelValue');
  24683. const {
  24684. positionClasses
  24685. } = usePosition(props);
  24686. const {
  24687. scopeId
  24688. } = useScopeId();
  24689. const {
  24690. themeClasses
  24691. } = provideTheme(props);
  24692. const {
  24693. colorClasses,
  24694. colorStyles,
  24695. variantClasses
  24696. } = useVariant(props);
  24697. const {
  24698. roundedClasses
  24699. } = useRounded(props);
  24700. const countdown = useCountdown(() => Number(props.timeout));
  24701. const overlay = ref();
  24702. const timerRef = ref();
  24703. const isHovering = shallowRef(false);
  24704. const startY = shallowRef(0);
  24705. const mainStyles = ref();
  24706. const hasLayout = inject$1(VuetifyLayoutKey, undefined);
  24707. useToggleScope(() => !!hasLayout, () => {
  24708. const layout = useLayout();
  24709. watchEffect(() => {
  24710. mainStyles.value = layout.mainStyles.value;
  24711. });
  24712. });
  24713. watch(isActive, startTimeout);
  24714. watch(() => props.timeout, startTimeout);
  24715. onMounted(() => {
  24716. if (isActive.value) startTimeout();
  24717. });
  24718. let activeTimeout = -1;
  24719. function startTimeout() {
  24720. countdown.reset();
  24721. window.clearTimeout(activeTimeout);
  24722. const timeout = Number(props.timeout);
  24723. if (!isActive.value || timeout === -1) return;
  24724. const element = refElement(timerRef.value);
  24725. countdown.start(element);
  24726. activeTimeout = window.setTimeout(() => {
  24727. isActive.value = false;
  24728. }, timeout);
  24729. }
  24730. function clearTimeout() {
  24731. countdown.reset();
  24732. window.clearTimeout(activeTimeout);
  24733. }
  24734. function onPointerenter() {
  24735. isHovering.value = true;
  24736. clearTimeout();
  24737. }
  24738. function onPointerleave() {
  24739. isHovering.value = false;
  24740. startTimeout();
  24741. }
  24742. function onTouchstart(event) {
  24743. startY.value = event.touches[0].clientY;
  24744. }
  24745. function onTouchend(event) {
  24746. if (Math.abs(startY.value - event.changedTouches[0].clientY) > 50) {
  24747. isActive.value = false;
  24748. }
  24749. }
  24750. function onAfterLeave() {
  24751. if (isHovering.value) onPointerleave();
  24752. }
  24753. const locationClasses = computed(() => {
  24754. return props.location.split(' ').reduce((acc, loc) => {
  24755. acc[`v-snackbar--${loc}`] = true;
  24756. return acc;
  24757. }, {});
  24758. });
  24759. useRender(() => {
  24760. const overlayProps = VOverlay.filterProps(props);
  24761. const hasContent = !!(slots.default || slots.text || props.text);
  24762. return createVNode(VOverlay, mergeProps({
  24763. "ref": overlay,
  24764. "class": ['v-snackbar', {
  24765. 'v-snackbar--active': isActive.value,
  24766. 'v-snackbar--multi-line': props.multiLine && !props.vertical,
  24767. 'v-snackbar--timer': !!props.timer,
  24768. 'v-snackbar--vertical': props.vertical
  24769. }, locationClasses.value, positionClasses.value, props.class],
  24770. "style": [mainStyles.value, props.style]
  24771. }, overlayProps, {
  24772. "modelValue": isActive.value,
  24773. "onUpdate:modelValue": $event => isActive.value = $event,
  24774. "contentProps": mergeProps({
  24775. class: ['v-snackbar__wrapper', themeClasses.value, colorClasses.value, roundedClasses.value, variantClasses.value],
  24776. style: [colorStyles.value],
  24777. onPointerenter,
  24778. onPointerleave
  24779. }, overlayProps.contentProps),
  24780. "persistent": true,
  24781. "noClickAnimation": true,
  24782. "scrim": false,
  24783. "scrollStrategy": "none",
  24784. "_disableGlobalStack": true,
  24785. "onTouchstartPassive": onTouchstart,
  24786. "onTouchend": onTouchend,
  24787. "onAfterLeave": onAfterLeave
  24788. }, scopeId), {
  24789. default: () => [genOverlays(false, 'v-snackbar'), props.timer && !isHovering.value && createVNode("div", {
  24790. "key": "timer",
  24791. "class": "v-snackbar__timer"
  24792. }, [createVNode(VProgressLinear, {
  24793. "ref": timerRef,
  24794. "color": typeof props.timer === 'string' ? props.timer : 'info',
  24795. "max": props.timeout,
  24796. "model-value": countdown.time.value
  24797. }, null)]), hasContent && createVNode("div", {
  24798. "key": "content",
  24799. "class": "v-snackbar__content",
  24800. "role": "status",
  24801. "aria-live": "polite"
  24802. }, [slots.text?.() ?? props.text, slots.default?.()]), slots.actions && createVNode(VDefaultsProvider, {
  24803. "defaults": {
  24804. VBtn: {
  24805. variant: 'text',
  24806. ripple: false,
  24807. slim: true
  24808. }
  24809. }
  24810. }, {
  24811. default: () => [createVNode("div", {
  24812. "class": "v-snackbar__actions"
  24813. }, [slots.actions({
  24814. isActive
  24815. })])]
  24816. })],
  24817. activator: slots.activator
  24818. });
  24819. });
  24820. return forwardRefs({}, overlay);
  24821. }
  24822. });
  24823. // Utilities
  24824. // Types
  24825. const makeLineProps = propsFactory({
  24826. autoDraw: Boolean,
  24827. autoDrawDuration: [Number, String],
  24828. autoDrawEasing: {
  24829. type: String,
  24830. default: 'ease'
  24831. },
  24832. color: String,
  24833. gradient: {
  24834. type: Array,
  24835. default: () => []
  24836. },
  24837. gradientDirection: {
  24838. type: String,
  24839. validator: val => ['top', 'bottom', 'left', 'right'].includes(val),
  24840. default: 'top'
  24841. },
  24842. height: {
  24843. type: [String, Number],
  24844. default: 75
  24845. },
  24846. labels: {
  24847. type: Array,
  24848. default: () => []
  24849. },
  24850. labelSize: {
  24851. type: [Number, String],
  24852. default: 7
  24853. },
  24854. lineWidth: {
  24855. type: [String, Number],
  24856. default: 4
  24857. },
  24858. id: String,
  24859. itemValue: {
  24860. type: String,
  24861. default: 'value'
  24862. },
  24863. modelValue: {
  24864. type: Array,
  24865. default: () => []
  24866. },
  24867. min: [String, Number],
  24868. max: [String, Number],
  24869. padding: {
  24870. type: [String, Number],
  24871. default: 8
  24872. },
  24873. showLabels: Boolean,
  24874. smooth: Boolean,
  24875. width: {
  24876. type: [Number, String],
  24877. default: 300
  24878. }
  24879. }, 'Line');
  24880. // Types
  24881. const makeVBarlineProps = propsFactory({
  24882. autoLineWidth: Boolean,
  24883. ...makeLineProps()
  24884. }, 'VBarline');
  24885. const VBarline = genericComponent()({
  24886. name: 'VBarline',
  24887. props: makeVBarlineProps(),
  24888. setup(props, _ref) {
  24889. let {
  24890. slots
  24891. } = _ref;
  24892. const uid = getUid();
  24893. const id = computed(() => props.id || `barline-${uid}`);
  24894. const autoDrawDuration = computed(() => Number(props.autoDrawDuration) || 500);
  24895. const hasLabels = computed(() => {
  24896. return Boolean(props.showLabels || props.labels.length > 0 || !!slots?.label);
  24897. });
  24898. const lineWidth = computed(() => parseFloat(props.lineWidth) || 4);
  24899. const totalWidth = computed(() => Math.max(props.modelValue.length * lineWidth.value, Number(props.width)));
  24900. const boundary = computed(() => {
  24901. return {
  24902. minX: 0,
  24903. maxX: totalWidth.value,
  24904. minY: 0,
  24905. maxY: parseInt(props.height, 10)
  24906. };
  24907. });
  24908. const items = computed(() => props.modelValue.map(item => getPropertyFromItem(item, props.itemValue, item)));
  24909. function genBars(values, boundary) {
  24910. const {
  24911. minX,
  24912. maxX,
  24913. minY,
  24914. maxY
  24915. } = boundary;
  24916. const totalValues = values.length;
  24917. let maxValue = props.max != null ? Number(props.max) : Math.max(...values);
  24918. let minValue = props.min != null ? Number(props.min) : Math.min(...values);
  24919. if (minValue > 0 && props.min == null) minValue = 0;
  24920. if (maxValue < 0 && props.max == null) maxValue = 0;
  24921. const gridX = maxX / totalValues;
  24922. const gridY = (maxY - minY) / (maxValue - minValue || 1);
  24923. const horizonY = maxY - Math.abs(minValue * gridY);
  24924. return values.map((value, index) => {
  24925. const height = Math.abs(gridY * value);
  24926. return {
  24927. x: minX + index * gridX,
  24928. y: horizonY - height + +(value < 0) * height,
  24929. height,
  24930. value
  24931. };
  24932. });
  24933. }
  24934. const parsedLabels = computed(() => {
  24935. const labels = [];
  24936. const points = genBars(items.value, boundary.value);
  24937. const len = points.length;
  24938. for (let i = 0; labels.length < len; i++) {
  24939. const item = points[i];
  24940. let value = props.labels[i];
  24941. if (!value) {
  24942. value = typeof item === 'object' ? item.value : item;
  24943. }
  24944. labels.push({
  24945. x: item.x,
  24946. value: String(value)
  24947. });
  24948. }
  24949. return labels;
  24950. });
  24951. const bars = computed(() => genBars(items.value, boundary.value));
  24952. const offsetX = computed(() => (Math.abs(bars.value[0].x - bars.value[1].x) - lineWidth.value) / 2);
  24953. useRender(() => {
  24954. const gradientData = !props.gradient.slice().length ? [''] : props.gradient.slice().reverse();
  24955. return createVNode("svg", {
  24956. "display": "block"
  24957. }, [createVNode("defs", null, [createVNode("linearGradient", {
  24958. "id": id.value,
  24959. "gradientUnits": "userSpaceOnUse",
  24960. "x1": props.gradientDirection === 'left' ? '100%' : '0',
  24961. "y1": props.gradientDirection === 'top' ? '100%' : '0',
  24962. "x2": props.gradientDirection === 'right' ? '100%' : '0',
  24963. "y2": props.gradientDirection === 'bottom' ? '100%' : '0'
  24964. }, [gradientData.map((color, index) => createVNode("stop", {
  24965. "offset": index / Math.max(gradientData.length - 1, 1),
  24966. "stop-color": color || 'currentColor'
  24967. }, null))])]), createVNode("clipPath", {
  24968. "id": `${id.value}-clip`
  24969. }, [bars.value.map(item => createVNode("rect", {
  24970. "x": item.x + offsetX.value,
  24971. "y": item.y,
  24972. "width": lineWidth.value,
  24973. "height": item.height,
  24974. "rx": typeof props.smooth === 'number' ? props.smooth : props.smooth ? 2 : 0,
  24975. "ry": typeof props.smooth === 'number' ? props.smooth : props.smooth ? 2 : 0
  24976. }, [props.autoDraw && createVNode(Fragment, null, [createVNode("animate", {
  24977. "attributeName": "y",
  24978. "from": item.y + item.height,
  24979. "to": item.y,
  24980. "dur": `${autoDrawDuration.value}ms`,
  24981. "fill": "freeze"
  24982. }, null), createVNode("animate", {
  24983. "attributeName": "height",
  24984. "from": "0",
  24985. "to": item.height,
  24986. "dur": `${autoDrawDuration.value}ms`,
  24987. "fill": "freeze"
  24988. }, null)])]))]), hasLabels.value && createVNode("g", {
  24989. "key": "labels",
  24990. "style": {
  24991. textAnchor: 'middle',
  24992. dominantBaseline: 'mathematical',
  24993. fill: 'currentColor'
  24994. }
  24995. }, [parsedLabels.value.map((item, i) => createVNode("text", {
  24996. "x": item.x + offsetX.value + lineWidth.value / 2,
  24997. "y": parseInt(props.height, 10) - 2 + (parseInt(props.labelSize, 10) || 7 * 0.75),
  24998. "font-size": Number(props.labelSize) || 7
  24999. }, [slots.label?.({
  25000. index: i,
  25001. value: item.value
  25002. }) ?? item.value]))]), createVNode("g", {
  25003. "clip-path": `url(#${id.value}-clip)`,
  25004. "fill": `url(#${id.value})`
  25005. }, [createVNode("rect", {
  25006. "x": 0,
  25007. "y": 0,
  25008. "width": Math.max(props.modelValue.length * lineWidth.value, Number(props.width)),
  25009. "height": props.height
  25010. }, null)])]);
  25011. });
  25012. }
  25013. });
  25014. // @ts-nocheck
  25015. /* eslint-disable */
  25016. // import { checkCollinear, getDistance, moveTo } from './math'
  25017. /**
  25018. * From https://github.com/unsplash/react-trend/blob/master/src/helpers/DOM.helpers.js#L18
  25019. */
  25020. function genPath(points, radius) {
  25021. let fill = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  25022. let height = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 75;
  25023. if (points.length === 0) return '';
  25024. const start = points.shift();
  25025. const end = points[points.length - 1];
  25026. return (fill ? `M${start.x} ${height - start.x + 2} L${start.x} ${start.y}` : `M${start.x} ${start.y}`) + points.map((point, index) => {
  25027. const next = points[index + 1];
  25028. const prev = points[index - 1] || start;
  25029. const isCollinear = next && checkCollinear(next, point, prev);
  25030. if (!next || isCollinear) {
  25031. return `L${point.x} ${point.y}`;
  25032. }
  25033. const threshold = Math.min(getDistance(prev, point), getDistance(next, point));
  25034. const isTooCloseForRadius = threshold / 2 < radius;
  25035. const radiusForPoint = isTooCloseForRadius ? threshold / 2 : radius;
  25036. const before = moveTo(prev, point, radiusForPoint);
  25037. const after = moveTo(next, point, radiusForPoint);
  25038. return `L${before.x} ${before.y}S${point.x} ${point.y} ${after.x} ${after.y}`;
  25039. }).join('') + (fill ? `L${end.x} ${height - start.x + 2} Z` : '');
  25040. }
  25041. function int(value) {
  25042. return parseInt(value, 10);
  25043. }
  25044. /**
  25045. * https://en.wikipedia.org/wiki/Collinearity
  25046. * x=(x1+x2)/2
  25047. * y=(y1+y2)/2
  25048. */
  25049. function checkCollinear(p0, p1, p2) {
  25050. return int(p0.x + p2.x) === int(2 * p1.x) && int(p0.y + p2.y) === int(2 * p1.y);
  25051. }
  25052. function getDistance(p1, p2) {
  25053. return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));
  25054. }
  25055. function moveTo(to, from, radius) {
  25056. const vector = {
  25057. x: to.x - from.x,
  25058. y: to.y - from.y
  25059. };
  25060. const length = Math.sqrt(vector.x * vector.x + vector.y * vector.y);
  25061. const unitVector = {
  25062. x: vector.x / length,
  25063. y: vector.y / length
  25064. };
  25065. return {
  25066. x: from.x + unitVector.x * radius,
  25067. y: from.y + unitVector.y * radius
  25068. };
  25069. }
  25070. // Types
  25071. const makeVTrendlineProps = propsFactory({
  25072. fill: Boolean,
  25073. ...makeLineProps()
  25074. }, 'VTrendline');
  25075. const VTrendline = genericComponent()({
  25076. name: 'VTrendline',
  25077. props: makeVTrendlineProps(),
  25078. setup(props, _ref) {
  25079. let {
  25080. slots
  25081. } = _ref;
  25082. const uid = getUid();
  25083. const id = computed(() => props.id || `trendline-${uid}`);
  25084. const autoDrawDuration = computed(() => Number(props.autoDrawDuration) || (props.fill ? 500 : 2000));
  25085. const lastLength = ref(0);
  25086. const path = ref(null);
  25087. function genPoints(values, boundary) {
  25088. const {
  25089. minX,
  25090. maxX,
  25091. minY,
  25092. maxY
  25093. } = boundary;
  25094. const totalValues = values.length;
  25095. const maxValue = props.max != null ? Number(props.max) : Math.max(...values);
  25096. const minValue = props.min != null ? Number(props.min) : Math.min(...values);
  25097. const gridX = (maxX - minX) / (totalValues - 1);
  25098. const gridY = (maxY - minY) / (maxValue - minValue || 1);
  25099. return values.map((value, index) => {
  25100. return {
  25101. x: minX + index * gridX,
  25102. y: maxY - (value - minValue) * gridY,
  25103. value
  25104. };
  25105. });
  25106. }
  25107. const hasLabels = computed(() => {
  25108. return Boolean(props.showLabels || props.labels.length > 0 || !!slots?.label);
  25109. });
  25110. const lineWidth = computed(() => {
  25111. return parseFloat(props.lineWidth) || 4;
  25112. });
  25113. const totalWidth = computed(() => Number(props.width));
  25114. const boundary = computed(() => {
  25115. const padding = Number(props.padding);
  25116. return {
  25117. minX: padding,
  25118. maxX: totalWidth.value - padding,
  25119. minY: padding,
  25120. maxY: parseInt(props.height, 10) - padding
  25121. };
  25122. });
  25123. const items = computed(() => props.modelValue.map(item => getPropertyFromItem(item, props.itemValue, item)));
  25124. const parsedLabels = computed(() => {
  25125. const labels = [];
  25126. const points = genPoints(items.value, boundary.value);
  25127. const len = points.length;
  25128. for (let i = 0; labels.length < len; i++) {
  25129. const item = points[i];
  25130. let value = props.labels[i];
  25131. if (!value) {
  25132. value = typeof item === 'object' ? item.value : item;
  25133. }
  25134. labels.push({
  25135. x: item.x,
  25136. value: String(value)
  25137. });
  25138. }
  25139. return labels;
  25140. });
  25141. watch(() => props.modelValue, async () => {
  25142. await nextTick();
  25143. if (!props.autoDraw || !path.value) return;
  25144. const pathRef = path.value;
  25145. const length = pathRef.getTotalLength();
  25146. if (!props.fill) {
  25147. // Initial setup to "hide" the line by using the stroke dash array
  25148. pathRef.style.strokeDasharray = `${length}`;
  25149. pathRef.style.strokeDashoffset = `${length}`;
  25150. // Force reflow to ensure the transition starts from this state
  25151. pathRef.getBoundingClientRect();
  25152. // Animate the stroke dash offset to "draw" the line
  25153. pathRef.style.transition = `stroke-dashoffset ${autoDrawDuration.value}ms ${props.autoDrawEasing}`;
  25154. pathRef.style.strokeDashoffset = '0';
  25155. } else {
  25156. // Your existing logic for filled paths remains the same
  25157. pathRef.style.transformOrigin = 'bottom center';
  25158. pathRef.style.transition = 'none';
  25159. pathRef.style.transform = `scaleY(0)`;
  25160. pathRef.getBoundingClientRect();
  25161. pathRef.style.transition = `transform ${autoDrawDuration.value}ms ${props.autoDrawEasing}`;
  25162. pathRef.style.transform = `scaleY(1)`;
  25163. }
  25164. lastLength.value = length;
  25165. }, {
  25166. immediate: true
  25167. });
  25168. function genPath$1(fill) {
  25169. return genPath(genPoints(items.value, boundary.value), props.smooth ? 8 : Number(props.smooth), fill, parseInt(props.height, 10));
  25170. }
  25171. useRender(() => {
  25172. const gradientData = !props.gradient.slice().length ? [''] : props.gradient.slice().reverse();
  25173. return createVNode("svg", {
  25174. "display": "block",
  25175. "stroke-width": parseFloat(props.lineWidth) ?? 4
  25176. }, [createVNode("defs", null, [createVNode("linearGradient", {
  25177. "id": id.value,
  25178. "gradientUnits": "userSpaceOnUse",
  25179. "x1": props.gradientDirection === 'left' ? '100%' : '0',
  25180. "y1": props.gradientDirection === 'top' ? '100%' : '0',
  25181. "x2": props.gradientDirection === 'right' ? '100%' : '0',
  25182. "y2": props.gradientDirection === 'bottom' ? '100%' : '0'
  25183. }, [gradientData.map((color, index) => createVNode("stop", {
  25184. "offset": index / Math.max(gradientData.length - 1, 1),
  25185. "stop-color": color || 'currentColor'
  25186. }, null))])]), hasLabels.value && createVNode("g", {
  25187. "key": "labels",
  25188. "style": {
  25189. textAnchor: 'middle',
  25190. dominantBaseline: 'mathematical',
  25191. fill: 'currentColor'
  25192. }
  25193. }, [parsedLabels.value.map((item, i) => createVNode("text", {
  25194. "x": item.x + lineWidth.value / 2 + lineWidth.value / 2,
  25195. "y": parseInt(props.height, 10) - 4 + (parseInt(props.labelSize, 10) || 7 * 0.75),
  25196. "font-size": Number(props.labelSize) || 7
  25197. }, [slots.label?.({
  25198. index: i,
  25199. value: item.value
  25200. }) ?? item.value]))]), createVNode("path", {
  25201. "ref": path,
  25202. "d": genPath$1(props.fill),
  25203. "fill": props.fill ? `url(#${id.value})` : 'none',
  25204. "stroke": props.fill ? 'none' : `url(#${id.value})`
  25205. }, null), props.fill && createVNode("path", {
  25206. "d": genPath$1(false),
  25207. "fill": "none",
  25208. "stroke": props.color ?? props.gradient?.[0]
  25209. }, null)]);
  25210. });
  25211. }
  25212. });
  25213. // Types
  25214. // Types
  25215. const makeVSparklineProps = propsFactory({
  25216. type: {
  25217. type: String,
  25218. default: 'trend'
  25219. },
  25220. ...makeVBarlineProps(),
  25221. ...makeVTrendlineProps()
  25222. }, 'VSparkline');
  25223. const VSparkline = genericComponent()({
  25224. name: 'VSparkline',
  25225. props: makeVSparklineProps(),
  25226. setup(props, _ref) {
  25227. let {
  25228. slots
  25229. } = _ref;
  25230. const {
  25231. textColorClasses,
  25232. textColorStyles
  25233. } = useTextColor(toRef(props, 'color'));
  25234. const hasLabels = computed(() => {
  25235. return Boolean(props.showLabels || props.labels.length > 0 || !!slots?.label);
  25236. });
  25237. const totalHeight = computed(() => {
  25238. let height = parseInt(props.height, 10);
  25239. if (hasLabels.value) height += parseInt(props.labelSize, 10) * 1.5;
  25240. return height;
  25241. });
  25242. useRender(() => {
  25243. const Tag = props.type === 'trend' ? VTrendline : VBarline;
  25244. const lineProps = props.type === 'trend' ? VTrendline.filterProps(props) : VBarline.filterProps(props);
  25245. return createVNode(Tag, mergeProps({
  25246. "key": props.type,
  25247. "class": textColorClasses.value,
  25248. "style": textColorStyles.value,
  25249. "viewBox": `0 0 ${props.width} ${parseInt(totalHeight.value, 10)}`
  25250. }, lineProps), slots);
  25251. });
  25252. }
  25253. });
  25254. // Types
  25255. const makeVSpeedDialProps = propsFactory({
  25256. ...makeComponentProps(),
  25257. ...makeVMenuProps({
  25258. offset: 8,
  25259. minWidth: 0,
  25260. openDelay: 0,
  25261. closeDelay: 100,
  25262. location: 'top center',
  25263. transition: 'scale-transition'
  25264. })
  25265. }, 'VSpeedDial');
  25266. const VSpeedDial = genericComponent()({
  25267. name: 'VSpeedDial',
  25268. props: makeVSpeedDialProps(),
  25269. emits: {
  25270. 'update:modelValue': value => true
  25271. },
  25272. setup(props, _ref) {
  25273. let {
  25274. slots
  25275. } = _ref;
  25276. const model = useProxiedModel(props, 'modelValue');
  25277. const menuRef = ref();
  25278. const location = computed(() => {
  25279. const [y, x = 'center'] = props.location?.split(' ') ?? [];
  25280. return `${y} ${x}`;
  25281. });
  25282. const locationClasses = computed(() => ({
  25283. [`v-speed-dial__content--${location.value.replace(' ', '-')}`]: true
  25284. }));
  25285. useRender(() => {
  25286. const menuProps = VMenu.filterProps(props);
  25287. return createVNode(VMenu, mergeProps(menuProps, {
  25288. "modelValue": model.value,
  25289. "onUpdate:modelValue": $event => model.value = $event,
  25290. "class": props.class,
  25291. "style": props.style,
  25292. "contentClass": ['v-speed-dial__content', locationClasses.value, props.contentClass],
  25293. "location": location.value,
  25294. "ref": menuRef,
  25295. "transition": "fade-transition"
  25296. }), {
  25297. ...slots,
  25298. default: slotProps => createVNode(VDefaultsProvider, {
  25299. "defaults": {
  25300. VBtn: {
  25301. size: 'small'
  25302. }
  25303. }
  25304. }, {
  25305. default: () => [createVNode(MaybeTransition, {
  25306. "appear": true,
  25307. "group": true,
  25308. "transition": props.transition
  25309. }, {
  25310. default: () => [slots.default?.(slotProps)]
  25311. })]
  25312. })
  25313. });
  25314. });
  25315. return {};
  25316. }
  25317. });
  25318. // Types
  25319. const VStepperSymbol = Symbol.for('vuetify:v-stepper');
  25320. // Types
  25321. const makeVStepperActionsProps = propsFactory({
  25322. color: String,
  25323. disabled: {
  25324. type: [Boolean, String],
  25325. default: false
  25326. },
  25327. prevText: {
  25328. type: String,
  25329. default: '$vuetify.stepper.prev'
  25330. },
  25331. nextText: {
  25332. type: String,
  25333. default: '$vuetify.stepper.next'
  25334. }
  25335. }, 'VStepperActions');
  25336. const VStepperActions = genericComponent()({
  25337. name: 'VStepperActions',
  25338. props: makeVStepperActionsProps(),
  25339. emits: {
  25340. 'click:prev': () => true,
  25341. 'click:next': () => true
  25342. },
  25343. setup(props, _ref) {
  25344. let {
  25345. emit,
  25346. slots
  25347. } = _ref;
  25348. const {
  25349. t
  25350. } = useLocale();
  25351. function onClickPrev() {
  25352. emit('click:prev');
  25353. }
  25354. function onClickNext() {
  25355. emit('click:next');
  25356. }
  25357. useRender(() => {
  25358. const prevSlotProps = {
  25359. onClick: onClickPrev
  25360. };
  25361. const nextSlotProps = {
  25362. onClick: onClickNext
  25363. };
  25364. return createVNode("div", {
  25365. "class": "v-stepper-actions"
  25366. }, [createVNode(VDefaultsProvider, {
  25367. "defaults": {
  25368. VBtn: {
  25369. disabled: ['prev', true].includes(props.disabled),
  25370. text: t(props.prevText),
  25371. variant: 'text'
  25372. }
  25373. }
  25374. }, {
  25375. default: () => [slots.prev?.({
  25376. props: prevSlotProps
  25377. }) ?? createVNode(VBtn, prevSlotProps, null)]
  25378. }), createVNode(VDefaultsProvider, {
  25379. "defaults": {
  25380. VBtn: {
  25381. color: props.color,
  25382. disabled: ['next', true].includes(props.disabled),
  25383. text: t(props.nextText),
  25384. variant: 'tonal'
  25385. }
  25386. }
  25387. }, {
  25388. default: () => [slots.next?.({
  25389. props: nextSlotProps
  25390. }) ?? createVNode(VBtn, nextSlotProps, null)]
  25391. })]);
  25392. });
  25393. return {};
  25394. }
  25395. });
  25396. // Utilities
  25397. const VStepperHeader = createSimpleFunctional('v-stepper-header');
  25398. // Types
  25399. const makeStepperItemProps = propsFactory({
  25400. color: String,
  25401. title: String,
  25402. subtitle: String,
  25403. complete: Boolean,
  25404. completeIcon: {
  25405. type: IconValue,
  25406. default: '$complete'
  25407. },
  25408. editable: Boolean,
  25409. editIcon: {
  25410. type: IconValue,
  25411. default: '$edit'
  25412. },
  25413. error: Boolean,
  25414. errorIcon: {
  25415. type: IconValue,
  25416. default: '$error'
  25417. },
  25418. icon: IconValue,
  25419. ripple: {
  25420. type: [Boolean, Object],
  25421. default: true
  25422. },
  25423. rules: {
  25424. type: Array,
  25425. default: () => []
  25426. }
  25427. }, 'StepperItem');
  25428. const makeVStepperItemProps = propsFactory({
  25429. ...makeStepperItemProps(),
  25430. ...makeGroupItemProps()
  25431. }, 'VStepperItem');
  25432. const VStepperItem = genericComponent()({
  25433. name: 'VStepperItem',
  25434. directives: {
  25435. Ripple
  25436. },
  25437. props: makeVStepperItemProps(),
  25438. emits: {
  25439. 'group:selected': val => true
  25440. },
  25441. setup(props, _ref) {
  25442. let {
  25443. slots
  25444. } = _ref;
  25445. const group = useGroupItem(props, VStepperSymbol, true);
  25446. const step = computed(() => group?.value.value ?? props.value);
  25447. const isValid = computed(() => props.rules.every(handler => handler() === true));
  25448. const isClickable = computed(() => !props.disabled && props.editable);
  25449. const canEdit = computed(() => !props.disabled && props.editable);
  25450. const hasError = computed(() => props.error || !isValid.value);
  25451. const hasCompleted = computed(() => props.complete || props.rules.length > 0 && isValid.value);
  25452. const icon = computed(() => {
  25453. if (hasError.value) return props.errorIcon;
  25454. if (hasCompleted.value) return props.completeIcon;
  25455. if (group.isSelected.value && props.editable) return props.editIcon;
  25456. return props.icon;
  25457. });
  25458. const slotProps = computed(() => ({
  25459. canEdit: canEdit.value,
  25460. hasError: hasError.value,
  25461. hasCompleted: hasCompleted.value,
  25462. title: props.title,
  25463. subtitle: props.subtitle,
  25464. step: step.value,
  25465. value: props.value
  25466. }));
  25467. useRender(() => {
  25468. const hasColor = (!group || group.isSelected.value || hasCompleted.value || canEdit.value) && !hasError.value && !props.disabled;
  25469. const hasTitle = !!(props.title != null || slots.title);
  25470. const hasSubtitle = !!(props.subtitle != null || slots.subtitle);
  25471. function onClick() {
  25472. group?.toggle();
  25473. }
  25474. return withDirectives(createVNode("button", {
  25475. "class": ['v-stepper-item', {
  25476. 'v-stepper-item--complete': hasCompleted.value,
  25477. 'v-stepper-item--disabled': props.disabled,
  25478. 'v-stepper-item--error': hasError.value
  25479. }, group?.selectedClass.value],
  25480. "disabled": !props.editable,
  25481. "onClick": onClick
  25482. }, [isClickable.value && genOverlays(true, 'v-stepper-item'), createVNode(VAvatar, {
  25483. "key": "stepper-avatar",
  25484. "class": "v-stepper-item__avatar",
  25485. "color": hasColor ? props.color : undefined,
  25486. "size": 24
  25487. }, {
  25488. default: () => [slots.icon?.(slotProps.value) ?? (icon.value ? createVNode(VIcon, {
  25489. "icon": icon.value
  25490. }, null) : step.value)]
  25491. }), createVNode("div", {
  25492. "class": "v-stepper-item__content"
  25493. }, [hasTitle && createVNode("div", {
  25494. "key": "title",
  25495. "class": "v-stepper-item__title"
  25496. }, [slots.title?.(slotProps.value) ?? props.title]), hasSubtitle && createVNode("div", {
  25497. "key": "subtitle",
  25498. "class": "v-stepper-item__subtitle"
  25499. }, [slots.subtitle?.(slotProps.value) ?? props.subtitle]), slots.default?.(slotProps.value)])]), [[resolveDirective("ripple"), props.ripple && props.editable, null]]);
  25500. });
  25501. return {};
  25502. }
  25503. });
  25504. const makeVStepperWindowProps = propsFactory({
  25505. ...omit(makeVWindowProps(), ['continuous', 'nextIcon', 'prevIcon', 'showArrows', 'touch', 'mandatory'])
  25506. }, 'VStepperWindow');
  25507. const VStepperWindow = genericComponent()({
  25508. name: 'VStepperWindow',
  25509. props: makeVStepperWindowProps(),
  25510. emits: {
  25511. 'update:modelValue': v => true
  25512. },
  25513. setup(props, _ref) {
  25514. let {
  25515. slots
  25516. } = _ref;
  25517. const group = inject$1(VStepperSymbol, null);
  25518. const _model = useProxiedModel(props, 'modelValue');
  25519. const model = computed({
  25520. get() {
  25521. // Always return modelValue if defined
  25522. // or if not within a VStepper group
  25523. if (_model.value != null || !group) return _model.value;
  25524. // If inside of a VStepper, find the currently selected
  25525. // item by id. Item value may be assigned by its index
  25526. return group.items.value.find(item => group.selected.value.includes(item.id))?.value;
  25527. },
  25528. set(val) {
  25529. _model.value = val;
  25530. }
  25531. });
  25532. useRender(() => {
  25533. const windowProps = VWindow.filterProps(props);
  25534. return createVNode(VWindow, mergeProps({
  25535. "_as": "VStepperWindow"
  25536. }, windowProps, {
  25537. "modelValue": model.value,
  25538. "onUpdate:modelValue": $event => model.value = $event,
  25539. "class": ['v-stepper-window', props.class],
  25540. "style": props.style,
  25541. "mandatory": false,
  25542. "touch": false
  25543. }), slots);
  25544. });
  25545. return {};
  25546. }
  25547. });
  25548. const makeVStepperWindowItemProps = propsFactory({
  25549. ...makeVWindowItemProps()
  25550. }, 'VStepperWindowItem');
  25551. const VStepperWindowItem = genericComponent()({
  25552. name: 'VStepperWindowItem',
  25553. props: makeVStepperWindowItemProps(),
  25554. setup(props, _ref) {
  25555. let {
  25556. slots
  25557. } = _ref;
  25558. useRender(() => {
  25559. const windowItemProps = VWindowItem.filterProps(props);
  25560. return createVNode(VWindowItem, mergeProps({
  25561. "_as": "VStepperWindowItem"
  25562. }, windowItemProps, {
  25563. "class": ['v-stepper-window-item', props.class],
  25564. "style": props.style
  25565. }), slots);
  25566. });
  25567. return {};
  25568. }
  25569. });
  25570. // Types
  25571. const makeStepperProps = propsFactory({
  25572. altLabels: Boolean,
  25573. bgColor: String,
  25574. completeIcon: IconValue,
  25575. editIcon: IconValue,
  25576. editable: Boolean,
  25577. errorIcon: IconValue,
  25578. hideActions: Boolean,
  25579. items: {
  25580. type: Array,
  25581. default: () => []
  25582. },
  25583. itemTitle: {
  25584. type: String,
  25585. default: 'title'
  25586. },
  25587. itemValue: {
  25588. type: String,
  25589. default: 'value'
  25590. },
  25591. nonLinear: Boolean,
  25592. flat: Boolean,
  25593. ...makeDisplayProps()
  25594. }, 'Stepper');
  25595. const makeVStepperProps = propsFactory({
  25596. ...makeStepperProps(),
  25597. ...makeGroupProps({
  25598. mandatory: 'force',
  25599. selectedClass: 'v-stepper-item--selected'
  25600. }),
  25601. ...makeVSheetProps(),
  25602. ...only(makeVStepperActionsProps(), ['prevText', 'nextText'])
  25603. }, 'VStepper');
  25604. const VStepper = genericComponent()({
  25605. name: 'VStepper',
  25606. props: makeVStepperProps(),
  25607. emits: {
  25608. 'update:modelValue': v => true
  25609. },
  25610. setup(props, _ref) {
  25611. let {
  25612. slots
  25613. } = _ref;
  25614. const {
  25615. items: _items,
  25616. next,
  25617. prev,
  25618. selected
  25619. } = useGroup(props, VStepperSymbol);
  25620. const {
  25621. displayClasses,
  25622. mobile
  25623. } = useDisplay(props);
  25624. const {
  25625. completeIcon,
  25626. editIcon,
  25627. errorIcon,
  25628. color,
  25629. editable,
  25630. prevText,
  25631. nextText
  25632. } = toRefs(props);
  25633. const items = computed(() => props.items.map((item, index) => {
  25634. const title = getPropertyFromItem(item, props.itemTitle, item);
  25635. const value = getPropertyFromItem(item, props.itemValue, index + 1);
  25636. return {
  25637. title,
  25638. value,
  25639. raw: item
  25640. };
  25641. }));
  25642. const activeIndex = computed(() => {
  25643. return _items.value.findIndex(item => selected.value.includes(item.id));
  25644. });
  25645. const disabled = computed(() => {
  25646. if (props.disabled) return props.disabled;
  25647. if (activeIndex.value === 0) return 'prev';
  25648. if (activeIndex.value === _items.value.length - 1) return 'next';
  25649. return false;
  25650. });
  25651. provideDefaults({
  25652. VStepperItem: {
  25653. editable,
  25654. errorIcon,
  25655. completeIcon,
  25656. editIcon,
  25657. prevText,
  25658. nextText
  25659. },
  25660. VStepperActions: {
  25661. color,
  25662. disabled,
  25663. prevText,
  25664. nextText
  25665. }
  25666. });
  25667. useRender(() => {
  25668. const sheetProps = VSheet.filterProps(props);
  25669. const hasHeader = !!(slots.header || props.items.length);
  25670. const hasWindow = props.items.length > 0;
  25671. const hasActions = !props.hideActions && !!(hasWindow || slots.actions);
  25672. return createVNode(VSheet, mergeProps(sheetProps, {
  25673. "color": props.bgColor,
  25674. "class": ['v-stepper', {
  25675. 'v-stepper--alt-labels': props.altLabels,
  25676. 'v-stepper--flat': props.flat,
  25677. 'v-stepper--non-linear': props.nonLinear,
  25678. 'v-stepper--mobile': mobile.value
  25679. }, displayClasses.value, props.class],
  25680. "style": props.style
  25681. }), {
  25682. default: () => [hasHeader && createVNode(VStepperHeader, {
  25683. "key": "stepper-header"
  25684. }, {
  25685. default: () => [items.value.map((_ref2, index) => {
  25686. let {
  25687. raw,
  25688. ...item
  25689. } = _ref2;
  25690. return createVNode(Fragment, null, [!!index && createVNode(VDivider, null, null), createVNode(VStepperItem, item, {
  25691. default: slots[`header-item.${item.value}`] ?? slots.header,
  25692. icon: slots.icon,
  25693. title: slots.title,
  25694. subtitle: slots.subtitle
  25695. })]);
  25696. })]
  25697. }), hasWindow && createVNode(VStepperWindow, {
  25698. "key": "stepper-window"
  25699. }, {
  25700. default: () => [items.value.map(item => createVNode(VStepperWindowItem, {
  25701. "value": item.value
  25702. }, {
  25703. default: () => slots[`item.${item.value}`]?.(item) ?? slots.item?.(item)
  25704. }))]
  25705. }), slots.default?.({
  25706. prev,
  25707. next
  25708. }), hasActions && (slots.actions?.({
  25709. next,
  25710. prev
  25711. }) ?? createVNode(VStepperActions, {
  25712. "key": "stepper-actions",
  25713. "onClick:prev": prev,
  25714. "onClick:next": next
  25715. }, slots))]
  25716. });
  25717. });
  25718. return {
  25719. prev,
  25720. next
  25721. };
  25722. }
  25723. });
  25724. // Types
  25725. const makeVSwitchProps = propsFactory({
  25726. indeterminate: Boolean,
  25727. inset: Boolean,
  25728. flat: Boolean,
  25729. loading: {
  25730. type: [Boolean, String],
  25731. default: false
  25732. },
  25733. ...makeVInputProps(),
  25734. ...makeVSelectionControlProps()
  25735. }, 'VSwitch');
  25736. const VSwitch = genericComponent()({
  25737. name: 'VSwitch',
  25738. inheritAttrs: false,
  25739. props: makeVSwitchProps(),
  25740. emits: {
  25741. 'update:focused': focused => true,
  25742. 'update:modelValue': value => true,
  25743. 'update:indeterminate': value => true
  25744. },
  25745. setup(props, _ref) {
  25746. let {
  25747. attrs,
  25748. slots
  25749. } = _ref;
  25750. const indeterminate = useProxiedModel(props, 'indeterminate');
  25751. const model = useProxiedModel(props, 'modelValue');
  25752. const {
  25753. loaderClasses
  25754. } = useLoader(props);
  25755. const {
  25756. isFocused,
  25757. focus,
  25758. blur
  25759. } = useFocus(props);
  25760. const control = ref();
  25761. const isForcedColorsModeActive = IN_BROWSER && window.matchMedia('(forced-colors: active)').matches;
  25762. const loaderColor = computed(() => {
  25763. return typeof props.loading === 'string' && props.loading !== '' ? props.loading : props.color;
  25764. });
  25765. const uid = getUid();
  25766. const id = computed(() => props.id || `switch-${uid}`);
  25767. function onChange() {
  25768. if (indeterminate.value) {
  25769. indeterminate.value = false;
  25770. }
  25771. }
  25772. function onTrackClick(e) {
  25773. e.stopPropagation();
  25774. e.preventDefault();
  25775. control.value?.input?.click();
  25776. }
  25777. useRender(() => {
  25778. const [rootAttrs, controlAttrs] = filterInputAttrs(attrs);
  25779. const inputProps = VInput.filterProps(props);
  25780. const controlProps = VSelectionControl.filterProps(props);
  25781. return createVNode(VInput, mergeProps({
  25782. "class": ['v-switch', {
  25783. 'v-switch--flat': props.flat
  25784. }, {
  25785. 'v-switch--inset': props.inset
  25786. }, {
  25787. 'v-switch--indeterminate': indeterminate.value
  25788. }, loaderClasses.value, props.class]
  25789. }, rootAttrs, inputProps, {
  25790. "modelValue": model.value,
  25791. "onUpdate:modelValue": $event => model.value = $event,
  25792. "id": id.value,
  25793. "focused": isFocused.value,
  25794. "style": props.style
  25795. }), {
  25796. ...slots,
  25797. default: _ref2 => {
  25798. let {
  25799. id,
  25800. messagesId,
  25801. isDisabled,
  25802. isReadonly,
  25803. isValid
  25804. } = _ref2;
  25805. const slotProps = {
  25806. model,
  25807. isValid
  25808. };
  25809. return createVNode(VSelectionControl, mergeProps({
  25810. "ref": control
  25811. }, controlProps, {
  25812. "modelValue": model.value,
  25813. "onUpdate:modelValue": [$event => model.value = $event, onChange],
  25814. "id": id.value,
  25815. "aria-describedby": messagesId.value,
  25816. "type": "checkbox",
  25817. "aria-checked": indeterminate.value ? 'mixed' : undefined,
  25818. "disabled": isDisabled.value,
  25819. "readonly": isReadonly.value,
  25820. "onFocus": focus,
  25821. "onBlur": blur
  25822. }, controlAttrs), {
  25823. ...slots,
  25824. default: _ref3 => {
  25825. let {
  25826. backgroundColorClasses,
  25827. backgroundColorStyles
  25828. } = _ref3;
  25829. return createVNode("div", {
  25830. "class": ['v-switch__track', !isForcedColorsModeActive ? backgroundColorClasses.value : undefined],
  25831. "style": backgroundColorStyles.value,
  25832. "onClick": onTrackClick
  25833. }, [slots['track-true'] && createVNode("div", {
  25834. "key": "prepend",
  25835. "class": "v-switch__track-true"
  25836. }, [slots['track-true'](slotProps)]), slots['track-false'] && createVNode("div", {
  25837. "key": "append",
  25838. "class": "v-switch__track-false"
  25839. }, [slots['track-false'](slotProps)])]);
  25840. },
  25841. input: _ref4 => {
  25842. let {
  25843. inputNode,
  25844. icon,
  25845. backgroundColorClasses,
  25846. backgroundColorStyles
  25847. } = _ref4;
  25848. return createVNode(Fragment, null, [inputNode, createVNode("div", {
  25849. "class": ['v-switch__thumb', {
  25850. 'v-switch__thumb--filled': icon || props.loading
  25851. }, props.inset || isForcedColorsModeActive ? undefined : backgroundColorClasses.value],
  25852. "style": props.inset ? undefined : backgroundColorStyles.value
  25853. }, [slots.thumb ? createVNode(VDefaultsProvider, {
  25854. "defaults": {
  25855. VIcon: {
  25856. icon,
  25857. size: 'x-small'
  25858. }
  25859. }
  25860. }, {
  25861. default: () => [slots.thumb({
  25862. ...slotProps,
  25863. icon
  25864. })]
  25865. }) : createVNode(VScaleTransition, null, {
  25866. default: () => [!props.loading ? icon && createVNode(VIcon, {
  25867. "key": String(icon),
  25868. "icon": icon,
  25869. "size": "x-small"
  25870. }, null) : createVNode(LoaderSlot, {
  25871. "name": "v-switch",
  25872. "active": true,
  25873. "color": isValid.value === false ? undefined : loaderColor.value
  25874. }, {
  25875. default: slotProps => slots.loader ? slots.loader(slotProps) : createVNode(VProgressCircular, {
  25876. "active": slotProps.isActive,
  25877. "color": slotProps.color,
  25878. "indeterminate": true,
  25879. "size": "16",
  25880. "width": "2"
  25881. }, null)
  25882. })]
  25883. })])]);
  25884. }
  25885. });
  25886. }
  25887. });
  25888. });
  25889. return {};
  25890. }
  25891. });
  25892. const makeVSystemBarProps = propsFactory({
  25893. color: String,
  25894. height: [Number, String],
  25895. window: Boolean,
  25896. ...makeComponentProps(),
  25897. ...makeElevationProps(),
  25898. ...makeLayoutItemProps(),
  25899. ...makeRoundedProps(),
  25900. ...makeTagProps(),
  25901. ...makeThemeProps()
  25902. }, 'VSystemBar');
  25903. const VSystemBar = genericComponent()({
  25904. name: 'VSystemBar',
  25905. props: makeVSystemBarProps(),
  25906. setup(props, _ref) {
  25907. let {
  25908. slots
  25909. } = _ref;
  25910. const {
  25911. themeClasses
  25912. } = provideTheme(props);
  25913. const {
  25914. backgroundColorClasses,
  25915. backgroundColorStyles
  25916. } = useBackgroundColor(toRef(props, 'color'));
  25917. const {
  25918. elevationClasses
  25919. } = useElevation(props);
  25920. const {
  25921. roundedClasses
  25922. } = useRounded(props);
  25923. const {
  25924. ssrBootStyles
  25925. } = useSsrBoot();
  25926. const height = computed(() => props.height ?? (props.window ? 32 : 24));
  25927. const {
  25928. layoutItemStyles
  25929. } = useLayoutItem({
  25930. id: props.name,
  25931. order: computed(() => parseInt(props.order, 10)),
  25932. position: shallowRef('top'),
  25933. layoutSize: height,
  25934. elementSize: height,
  25935. active: computed(() => true),
  25936. absolute: toRef(props, 'absolute')
  25937. });
  25938. useRender(() => createVNode(props.tag, {
  25939. "class": ['v-system-bar', {
  25940. 'v-system-bar--window': props.window
  25941. }, themeClasses.value, backgroundColorClasses.value, elevationClasses.value, roundedClasses.value, props.class],
  25942. "style": [backgroundColorStyles.value, layoutItemStyles.value, ssrBootStyles.value, props.style]
  25943. }, slots));
  25944. return {};
  25945. }
  25946. });
  25947. // Types
  25948. const VTabsSymbol = Symbol.for('vuetify:v-tabs');
  25949. // Types
  25950. const makeVTabProps = propsFactory({
  25951. fixed: Boolean,
  25952. sliderColor: String,
  25953. hideSlider: Boolean,
  25954. direction: {
  25955. type: String,
  25956. default: 'horizontal'
  25957. },
  25958. ...omit(makeVBtnProps({
  25959. selectedClass: 'v-tab--selected',
  25960. variant: 'text'
  25961. }), ['active', 'block', 'flat', 'location', 'position', 'symbol'])
  25962. }, 'VTab');
  25963. const VTab = genericComponent()({
  25964. name: 'VTab',
  25965. props: makeVTabProps(),
  25966. setup(props, _ref) {
  25967. let {
  25968. slots,
  25969. attrs
  25970. } = _ref;
  25971. const {
  25972. textColorClasses: sliderColorClasses,
  25973. textColorStyles: sliderColorStyles
  25974. } = useTextColor(props, 'sliderColor');
  25975. const rootEl = ref();
  25976. const sliderEl = ref();
  25977. const isHorizontal = computed(() => props.direction === 'horizontal');
  25978. const isSelected = computed(() => rootEl.value?.group?.isSelected.value ?? false);
  25979. function updateSlider(_ref2) {
  25980. let {
  25981. value
  25982. } = _ref2;
  25983. if (value) {
  25984. const prevEl = rootEl.value?.$el.parentElement?.querySelector('.v-tab--selected .v-tab__slider');
  25985. const nextEl = sliderEl.value;
  25986. if (!prevEl || !nextEl) return;
  25987. const color = getComputedStyle(prevEl).color;
  25988. const prevBox = prevEl.getBoundingClientRect();
  25989. const nextBox = nextEl.getBoundingClientRect();
  25990. const xy = isHorizontal.value ? 'x' : 'y';
  25991. const XY = isHorizontal.value ? 'X' : 'Y';
  25992. const rightBottom = isHorizontal.value ? 'right' : 'bottom';
  25993. const widthHeight = isHorizontal.value ? 'width' : 'height';
  25994. const prevPos = prevBox[xy];
  25995. const nextPos = nextBox[xy];
  25996. const delta = prevPos > nextPos ? prevBox[rightBottom] - nextBox[rightBottom] : prevBox[xy] - nextBox[xy];
  25997. const origin = Math.sign(delta) > 0 ? isHorizontal.value ? 'right' : 'bottom' : Math.sign(delta) < 0 ? isHorizontal.value ? 'left' : 'top' : 'center';
  25998. const size = Math.abs(delta) + (Math.sign(delta) < 0 ? prevBox[widthHeight] : nextBox[widthHeight]);
  25999. const scale = size / Math.max(prevBox[widthHeight], nextBox[widthHeight]) || 0;
  26000. const initialScale = prevBox[widthHeight] / nextBox[widthHeight] || 0;
  26001. const sigma = 1.5;
  26002. animate(nextEl, {
  26003. backgroundColor: [color, 'currentcolor'],
  26004. transform: [`translate${XY}(${delta}px) scale${XY}(${initialScale})`, `translate${XY}(${delta / sigma}px) scale${XY}(${(scale - 1) / sigma + 1})`, 'none'],
  26005. transformOrigin: Array(3).fill(origin)
  26006. }, {
  26007. duration: 225,
  26008. easing: standardEasing
  26009. });
  26010. }
  26011. }
  26012. useRender(() => {
  26013. const btnProps = VBtn.filterProps(props);
  26014. return createVNode(VBtn, mergeProps({
  26015. "symbol": VTabsSymbol,
  26016. "ref": rootEl,
  26017. "class": ['v-tab', props.class],
  26018. "style": props.style,
  26019. "tabindex": isSelected.value ? 0 : -1,
  26020. "role": "tab",
  26021. "aria-selected": String(isSelected.value),
  26022. "active": false
  26023. }, btnProps, attrs, {
  26024. "block": props.fixed,
  26025. "maxWidth": props.fixed ? 300 : undefined,
  26026. "onGroup:selected": updateSlider
  26027. }), {
  26028. ...slots,
  26029. default: () => createVNode(Fragment, null, [slots.default?.() ?? props.text, !props.hideSlider && createVNode("div", {
  26030. "ref": sliderEl,
  26031. "class": ['v-tab__slider', sliderColorClasses.value],
  26032. "style": sliderColorStyles.value
  26033. }, null)])
  26034. });
  26035. });
  26036. return forwardRefs({}, rootEl);
  26037. }
  26038. });
  26039. const makeVTabsWindowProps = propsFactory({
  26040. ...omit(makeVWindowProps(), ['continuous', 'nextIcon', 'prevIcon', 'showArrows', 'touch', 'mandatory'])
  26041. }, 'VTabsWindow');
  26042. const VTabsWindow = genericComponent()({
  26043. name: 'VTabsWindow',
  26044. props: makeVTabsWindowProps(),
  26045. emits: {
  26046. 'update:modelValue': v => true
  26047. },
  26048. setup(props, _ref) {
  26049. let {
  26050. slots
  26051. } = _ref;
  26052. const group = inject$1(VTabsSymbol, null);
  26053. const _model = useProxiedModel(props, 'modelValue');
  26054. const model = computed({
  26055. get() {
  26056. // Always return modelValue if defined
  26057. // or if not within a VTabs group
  26058. if (_model.value != null || !group) return _model.value;
  26059. // If inside of a VTabs, find the currently selected
  26060. // item by id. Item value may be assigned by its index
  26061. return group.items.value.find(item => group.selected.value.includes(item.id))?.value;
  26062. },
  26063. set(val) {
  26064. _model.value = val;
  26065. }
  26066. });
  26067. useRender(() => {
  26068. const windowProps = VWindow.filterProps(props);
  26069. return createVNode(VWindow, mergeProps({
  26070. "_as": "VTabsWindow"
  26071. }, windowProps, {
  26072. "modelValue": model.value,
  26073. "onUpdate:modelValue": $event => model.value = $event,
  26074. "class": ['v-tabs-window', props.class],
  26075. "style": props.style,
  26076. "mandatory": false,
  26077. "touch": false
  26078. }), slots);
  26079. });
  26080. return {};
  26081. }
  26082. });
  26083. const makeVTabsWindowItemProps = propsFactory({
  26084. ...makeVWindowItemProps()
  26085. }, 'VTabsWindowItem');
  26086. const VTabsWindowItem = genericComponent()({
  26087. name: 'VTabsWindowItem',
  26088. props: makeVTabsWindowItemProps(),
  26089. setup(props, _ref) {
  26090. let {
  26091. slots
  26092. } = _ref;
  26093. useRender(() => {
  26094. const windowItemProps = VWindowItem.filterProps(props);
  26095. return createVNode(VWindowItem, mergeProps({
  26096. "_as": "VTabsWindowItem"
  26097. }, windowItemProps, {
  26098. "class": ['v-tabs-window-item', props.class],
  26099. "style": props.style
  26100. }), slots);
  26101. });
  26102. return {};
  26103. }
  26104. });
  26105. function parseItems(items) {
  26106. if (!items) return [];
  26107. return items.map(item => {
  26108. if (!isObject(item)) return {
  26109. text: item,
  26110. value: item
  26111. };
  26112. return item;
  26113. });
  26114. }
  26115. const makeVTabsProps = propsFactory({
  26116. alignTabs: {
  26117. type: String,
  26118. default: 'start'
  26119. },
  26120. color: String,
  26121. fixedTabs: Boolean,
  26122. items: {
  26123. type: Array,
  26124. default: () => []
  26125. },
  26126. stacked: Boolean,
  26127. bgColor: String,
  26128. grow: Boolean,
  26129. height: {
  26130. type: [Number, String],
  26131. default: undefined
  26132. },
  26133. hideSlider: Boolean,
  26134. sliderColor: String,
  26135. ...makeVSlideGroupProps({
  26136. mandatory: 'force',
  26137. selectedClass: 'v-tab-item--selected'
  26138. }),
  26139. ...makeDensityProps(),
  26140. ...makeTagProps()
  26141. }, 'VTabs');
  26142. const VTabs = genericComponent()({
  26143. name: 'VTabs',
  26144. props: makeVTabsProps(),
  26145. emits: {
  26146. 'update:modelValue': v => true
  26147. },
  26148. setup(props, _ref) {
  26149. let {
  26150. attrs,
  26151. slots
  26152. } = _ref;
  26153. const model = useProxiedModel(props, 'modelValue');
  26154. const items = computed(() => parseItems(props.items));
  26155. const {
  26156. densityClasses
  26157. } = useDensity(props);
  26158. const {
  26159. backgroundColorClasses,
  26160. backgroundColorStyles
  26161. } = useBackgroundColor(toRef(props, 'bgColor'));
  26162. const {
  26163. scopeId
  26164. } = useScopeId();
  26165. provideDefaults({
  26166. VTab: {
  26167. color: toRef(props, 'color'),
  26168. direction: toRef(props, 'direction'),
  26169. stacked: toRef(props, 'stacked'),
  26170. fixed: toRef(props, 'fixedTabs'),
  26171. sliderColor: toRef(props, 'sliderColor'),
  26172. hideSlider: toRef(props, 'hideSlider')
  26173. }
  26174. });
  26175. useRender(() => {
  26176. const slideGroupProps = VSlideGroup.filterProps(props);
  26177. const hasWindow = !!(slots.window || props.items.length > 0);
  26178. return createVNode(Fragment, null, [createVNode(VSlideGroup, mergeProps(slideGroupProps, {
  26179. "modelValue": model.value,
  26180. "onUpdate:modelValue": $event => model.value = $event,
  26181. "class": ['v-tabs', `v-tabs--${props.direction}`, `v-tabs--align-tabs-${props.alignTabs}`, {
  26182. 'v-tabs--fixed-tabs': props.fixedTabs,
  26183. 'v-tabs--grow': props.grow,
  26184. 'v-tabs--stacked': props.stacked
  26185. }, densityClasses.value, backgroundColorClasses.value, props.class],
  26186. "style": [{
  26187. '--v-tabs-height': convertToUnit(props.height)
  26188. }, backgroundColorStyles.value, props.style],
  26189. "role": "tablist",
  26190. "symbol": VTabsSymbol
  26191. }, scopeId, attrs), {
  26192. default: () => [slots.default?.() ?? items.value.map(item => slots.tab?.({
  26193. item
  26194. }) ?? createVNode(VTab, mergeProps(item, {
  26195. "key": item.text,
  26196. "value": item.value
  26197. }), {
  26198. default: slots[`tab.${item.value}`] ? () => slots[`tab.${item.value}`]?.({
  26199. item
  26200. }) : undefined
  26201. }))]
  26202. }), hasWindow && createVNode(VTabsWindow, mergeProps({
  26203. "modelValue": model.value,
  26204. "onUpdate:modelValue": $event => model.value = $event,
  26205. "key": "tabs-window"
  26206. }, scopeId), {
  26207. default: () => [items.value.map(item => slots.item?.({
  26208. item
  26209. }) ?? createVNode(VTabsWindowItem, {
  26210. "value": item.value
  26211. }, {
  26212. default: () => slots[`item.${item.value}`]?.({
  26213. item
  26214. })
  26215. })), slots.window?.()]
  26216. })]);
  26217. });
  26218. return {};
  26219. }
  26220. });
  26221. // Types
  26222. const makeVTextareaProps = propsFactory({
  26223. autoGrow: Boolean,
  26224. autofocus: Boolean,
  26225. counter: [Boolean, Number, String],
  26226. counterValue: Function,
  26227. prefix: String,
  26228. placeholder: String,
  26229. persistentPlaceholder: Boolean,
  26230. persistentCounter: Boolean,
  26231. noResize: Boolean,
  26232. rows: {
  26233. type: [Number, String],
  26234. default: 5,
  26235. validator: v => !isNaN(parseFloat(v))
  26236. },
  26237. maxRows: {
  26238. type: [Number, String],
  26239. validator: v => !isNaN(parseFloat(v))
  26240. },
  26241. suffix: String,
  26242. modelModifiers: Object,
  26243. ...makeVInputProps(),
  26244. ...makeVFieldProps()
  26245. }, 'VTextarea');
  26246. const VTextarea = genericComponent()({
  26247. name: 'VTextarea',
  26248. directives: {
  26249. Intersect
  26250. },
  26251. inheritAttrs: false,
  26252. props: makeVTextareaProps(),
  26253. emits: {
  26254. 'click:control': e => true,
  26255. 'mousedown:control': e => true,
  26256. 'update:focused': focused => true,
  26257. 'update:modelValue': val => true
  26258. },
  26259. setup(props, _ref) {
  26260. let {
  26261. attrs,
  26262. emit,
  26263. slots
  26264. } = _ref;
  26265. const model = useProxiedModel(props, 'modelValue');
  26266. const {
  26267. isFocused,
  26268. focus,
  26269. blur
  26270. } = useFocus(props);
  26271. const counterValue = computed(() => {
  26272. return typeof props.counterValue === 'function' ? props.counterValue(model.value) : (model.value || '').toString().length;
  26273. });
  26274. const max = computed(() => {
  26275. if (attrs.maxlength) return attrs.maxlength;
  26276. if (!props.counter || typeof props.counter !== 'number' && typeof props.counter !== 'string') return undefined;
  26277. return props.counter;
  26278. });
  26279. function onIntersect(isIntersecting, entries) {
  26280. if (!props.autofocus || !isIntersecting) return;
  26281. entries[0].target?.focus?.();
  26282. }
  26283. const vInputRef = ref();
  26284. const vFieldRef = ref();
  26285. const controlHeight = shallowRef('');
  26286. const textareaRef = ref();
  26287. const isActive = computed(() => props.persistentPlaceholder || isFocused.value || props.active);
  26288. function onFocus() {
  26289. if (textareaRef.value !== document.activeElement) {
  26290. textareaRef.value?.focus();
  26291. }
  26292. if (!isFocused.value) focus();
  26293. }
  26294. function onControlClick(e) {
  26295. onFocus();
  26296. emit('click:control', e);
  26297. }
  26298. function onControlMousedown(e) {
  26299. emit('mousedown:control', e);
  26300. }
  26301. function onClear(e) {
  26302. e.stopPropagation();
  26303. onFocus();
  26304. nextTick(() => {
  26305. model.value = '';
  26306. callEvent(props['onClick:clear'], e);
  26307. });
  26308. }
  26309. function onInput(e) {
  26310. const el = e.target;
  26311. model.value = el.value;
  26312. if (props.modelModifiers?.trim) {
  26313. const caretPosition = [el.selectionStart, el.selectionEnd];
  26314. nextTick(() => {
  26315. el.selectionStart = caretPosition[0];
  26316. el.selectionEnd = caretPosition[1];
  26317. });
  26318. }
  26319. }
  26320. const sizerRef = ref();
  26321. const rows = ref(+props.rows);
  26322. const isPlainOrUnderlined = computed(() => ['plain', 'underlined'].includes(props.variant));
  26323. watchEffect(() => {
  26324. if (!props.autoGrow) rows.value = +props.rows;
  26325. });
  26326. function calculateInputHeight() {
  26327. if (!props.autoGrow) return;
  26328. nextTick(() => {
  26329. if (!sizerRef.value || !vFieldRef.value) return;
  26330. const style = getComputedStyle(sizerRef.value);
  26331. const fieldStyle = getComputedStyle(vFieldRef.value.$el);
  26332. const padding = parseFloat(style.getPropertyValue('--v-field-padding-top')) + parseFloat(style.getPropertyValue('--v-input-padding-top')) + parseFloat(style.getPropertyValue('--v-field-padding-bottom'));
  26333. const height = sizerRef.value.scrollHeight;
  26334. const lineHeight = parseFloat(style.lineHeight);
  26335. const minHeight = Math.max(parseFloat(props.rows) * lineHeight + padding, parseFloat(fieldStyle.getPropertyValue('--v-input-control-height')));
  26336. const maxHeight = parseFloat(props.maxRows) * lineHeight + padding || Infinity;
  26337. const newHeight = clamp(height ?? 0, minHeight, maxHeight);
  26338. rows.value = Math.floor((newHeight - padding) / lineHeight);
  26339. controlHeight.value = convertToUnit(newHeight);
  26340. });
  26341. }
  26342. onMounted(calculateInputHeight);
  26343. watch(model, calculateInputHeight);
  26344. watch(() => props.rows, calculateInputHeight);
  26345. watch(() => props.maxRows, calculateInputHeight);
  26346. watch(() => props.density, calculateInputHeight);
  26347. let observer;
  26348. watch(sizerRef, val => {
  26349. if (val) {
  26350. observer = new ResizeObserver(calculateInputHeight);
  26351. observer.observe(sizerRef.value);
  26352. } else {
  26353. observer?.disconnect();
  26354. }
  26355. });
  26356. onBeforeUnmount(() => {
  26357. observer?.disconnect();
  26358. });
  26359. useRender(() => {
  26360. const hasCounter = !!(slots.counter || props.counter || props.counterValue);
  26361. const hasDetails = !!(hasCounter || slots.details);
  26362. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  26363. const {
  26364. modelValue: _,
  26365. ...inputProps
  26366. } = VInput.filterProps(props);
  26367. const fieldProps = filterFieldProps(props);
  26368. return createVNode(VInput, mergeProps({
  26369. "ref": vInputRef,
  26370. "modelValue": model.value,
  26371. "onUpdate:modelValue": $event => model.value = $event,
  26372. "class": ['v-textarea v-text-field', {
  26373. 'v-textarea--prefixed': props.prefix,
  26374. 'v-textarea--suffixed': props.suffix,
  26375. 'v-text-field--prefixed': props.prefix,
  26376. 'v-text-field--suffixed': props.suffix,
  26377. 'v-textarea--auto-grow': props.autoGrow,
  26378. 'v-textarea--no-resize': props.noResize || props.autoGrow,
  26379. 'v-input--plain-underlined': isPlainOrUnderlined.value
  26380. }, props.class],
  26381. "style": props.style
  26382. }, rootAttrs, inputProps, {
  26383. "centerAffix": rows.value === 1 && !isPlainOrUnderlined.value,
  26384. "focused": isFocused.value
  26385. }), {
  26386. ...slots,
  26387. default: _ref2 => {
  26388. let {
  26389. id,
  26390. isDisabled,
  26391. isDirty,
  26392. isReadonly,
  26393. isValid
  26394. } = _ref2;
  26395. return createVNode(VField, mergeProps({
  26396. "ref": vFieldRef,
  26397. "style": {
  26398. '--v-textarea-control-height': controlHeight.value
  26399. },
  26400. "onClick": onControlClick,
  26401. "onMousedown": onControlMousedown,
  26402. "onClick:clear": onClear,
  26403. "onClick:prependInner": props['onClick:prependInner'],
  26404. "onClick:appendInner": props['onClick:appendInner']
  26405. }, fieldProps, {
  26406. "id": id.value,
  26407. "active": isActive.value || isDirty.value,
  26408. "centerAffix": rows.value === 1 && !isPlainOrUnderlined.value,
  26409. "dirty": isDirty.value || props.dirty,
  26410. "disabled": isDisabled.value,
  26411. "focused": isFocused.value,
  26412. "error": isValid.value === false
  26413. }), {
  26414. ...slots,
  26415. default: _ref3 => {
  26416. let {
  26417. props: {
  26418. class: fieldClass,
  26419. ...slotProps
  26420. }
  26421. } = _ref3;
  26422. return createVNode(Fragment, null, [props.prefix && createVNode("span", {
  26423. "class": "v-text-field__prefix"
  26424. }, [props.prefix]), withDirectives(createVNode("textarea", mergeProps({
  26425. "ref": textareaRef,
  26426. "class": fieldClass,
  26427. "value": model.value,
  26428. "onInput": onInput,
  26429. "autofocus": props.autofocus,
  26430. "readonly": isReadonly.value,
  26431. "disabled": isDisabled.value,
  26432. "placeholder": props.placeholder,
  26433. "rows": props.rows,
  26434. "name": props.name,
  26435. "onFocus": onFocus,
  26436. "onBlur": blur
  26437. }, slotProps, inputAttrs), null), [[resolveDirective("intersect"), {
  26438. handler: onIntersect
  26439. }, null, {
  26440. once: true
  26441. }]]), props.autoGrow && withDirectives(createVNode("textarea", {
  26442. "class": [fieldClass, 'v-textarea__sizer'],
  26443. "id": `${slotProps.id}-sizer`,
  26444. "onUpdate:modelValue": $event => model.value = $event,
  26445. "ref": sizerRef,
  26446. "readonly": true,
  26447. "aria-hidden": "true"
  26448. }, null), [[vModelText, model.value]]), props.suffix && createVNode("span", {
  26449. "class": "v-text-field__suffix"
  26450. }, [props.suffix])]);
  26451. }
  26452. });
  26453. },
  26454. details: hasDetails ? slotProps => createVNode(Fragment, null, [slots.details?.(slotProps), hasCounter && createVNode(Fragment, null, [createVNode("span", null, null), createVNode(VCounter, {
  26455. "active": props.persistentCounter || isFocused.value,
  26456. "value": counterValue.value,
  26457. "max": max.value,
  26458. "disabled": props.disabled
  26459. }, slots.counter)])]) : undefined
  26460. });
  26461. });
  26462. return forwardRefs({}, vInputRef, vFieldRef, textareaRef);
  26463. }
  26464. });
  26465. const makeVThemeProviderProps = propsFactory({
  26466. withBackground: Boolean,
  26467. ...makeComponentProps(),
  26468. ...makeThemeProps(),
  26469. ...makeTagProps()
  26470. }, 'VThemeProvider');
  26471. const VThemeProvider = genericComponent()({
  26472. name: 'VThemeProvider',
  26473. props: makeVThemeProviderProps(),
  26474. setup(props, _ref) {
  26475. let {
  26476. slots
  26477. } = _ref;
  26478. const {
  26479. themeClasses
  26480. } = provideTheme(props);
  26481. return () => {
  26482. if (!props.withBackground) return slots.default?.();
  26483. return createVNode(props.tag, {
  26484. "class": ['v-theme-provider', themeClasses.value, props.class],
  26485. "style": props.style
  26486. }, {
  26487. default: () => [slots.default?.()]
  26488. });
  26489. };
  26490. }
  26491. });
  26492. const makeVTimelineDividerProps = propsFactory({
  26493. dotColor: String,
  26494. fillDot: Boolean,
  26495. hideDot: Boolean,
  26496. icon: IconValue,
  26497. iconColor: String,
  26498. lineColor: String,
  26499. ...makeComponentProps(),
  26500. ...makeRoundedProps(),
  26501. ...makeSizeProps(),
  26502. ...makeElevationProps()
  26503. }, 'VTimelineDivider');
  26504. const VTimelineDivider = genericComponent()({
  26505. name: 'VTimelineDivider',
  26506. props: makeVTimelineDividerProps(),
  26507. setup(props, _ref) {
  26508. let {
  26509. slots
  26510. } = _ref;
  26511. const {
  26512. sizeClasses,
  26513. sizeStyles
  26514. } = useSize(props, 'v-timeline-divider__dot');
  26515. const {
  26516. backgroundColorStyles,
  26517. backgroundColorClasses
  26518. } = useBackgroundColor(toRef(props, 'dotColor'));
  26519. const {
  26520. roundedClasses
  26521. } = useRounded(props, 'v-timeline-divider__dot');
  26522. const {
  26523. elevationClasses
  26524. } = useElevation(props);
  26525. const {
  26526. backgroundColorClasses: lineColorClasses,
  26527. backgroundColorStyles: lineColorStyles
  26528. } = useBackgroundColor(toRef(props, 'lineColor'));
  26529. useRender(() => createVNode("div", {
  26530. "class": ['v-timeline-divider', {
  26531. 'v-timeline-divider--fill-dot': props.fillDot
  26532. }, props.class],
  26533. "style": props.style
  26534. }, [createVNode("div", {
  26535. "class": ['v-timeline-divider__before', lineColorClasses.value],
  26536. "style": lineColorStyles.value
  26537. }, null), !props.hideDot && createVNode("div", {
  26538. "key": "dot",
  26539. "class": ['v-timeline-divider__dot', elevationClasses.value, roundedClasses.value, sizeClasses.value],
  26540. "style": sizeStyles.value
  26541. }, [createVNode("div", {
  26542. "class": ['v-timeline-divider__inner-dot', backgroundColorClasses.value, roundedClasses.value],
  26543. "style": backgroundColorStyles.value
  26544. }, [!slots.default ? createVNode(VIcon, {
  26545. "key": "icon",
  26546. "color": props.iconColor,
  26547. "icon": props.icon,
  26548. "size": props.size
  26549. }, null) : createVNode(VDefaultsProvider, {
  26550. "key": "icon-defaults",
  26551. "disabled": !props.icon,
  26552. "defaults": {
  26553. VIcon: {
  26554. color: props.iconColor,
  26555. icon: props.icon,
  26556. size: props.size
  26557. }
  26558. }
  26559. }, slots.default)])]), createVNode("div", {
  26560. "class": ['v-timeline-divider__after', lineColorClasses.value],
  26561. "style": lineColorStyles.value
  26562. }, null)]));
  26563. return {};
  26564. }
  26565. });
  26566. // Types
  26567. // Types
  26568. const makeVTimelineItemProps = propsFactory({
  26569. density: String,
  26570. dotColor: String,
  26571. fillDot: Boolean,
  26572. hideDot: Boolean,
  26573. hideOpposite: {
  26574. type: Boolean,
  26575. default: undefined
  26576. },
  26577. icon: IconValue,
  26578. iconColor: String,
  26579. lineInset: [Number, String],
  26580. ...makeComponentProps(),
  26581. ...makeDimensionProps(),
  26582. ...makeElevationProps(),
  26583. ...makeRoundedProps(),
  26584. ...makeSizeProps(),
  26585. ...makeTagProps()
  26586. }, 'VTimelineItem');
  26587. const VTimelineItem = genericComponent()({
  26588. name: 'VTimelineItem',
  26589. props: makeVTimelineItemProps(),
  26590. setup(props, _ref) {
  26591. let {
  26592. slots
  26593. } = _ref;
  26594. const {
  26595. dimensionStyles
  26596. } = useDimension(props);
  26597. const dotSize = shallowRef(0);
  26598. const dotRef = ref();
  26599. watch(dotRef, newValue => {
  26600. if (!newValue) return;
  26601. dotSize.value = newValue.$el.querySelector('.v-timeline-divider__dot')?.getBoundingClientRect().width ?? 0;
  26602. }, {
  26603. flush: 'post'
  26604. });
  26605. useRender(() => createVNode("div", {
  26606. "class": ['v-timeline-item', {
  26607. 'v-timeline-item--fill-dot': props.fillDot
  26608. }, props.class],
  26609. "style": [{
  26610. '--v-timeline-dot-size': convertToUnit(dotSize.value),
  26611. '--v-timeline-line-inset': props.lineInset ? `calc(var(--v-timeline-dot-size) / 2 + ${convertToUnit(props.lineInset)})` : convertToUnit(0)
  26612. }, props.style]
  26613. }, [createVNode("div", {
  26614. "class": "v-timeline-item__body",
  26615. "style": dimensionStyles.value
  26616. }, [slots.default?.()]), createVNode(VTimelineDivider, {
  26617. "ref": dotRef,
  26618. "hideDot": props.hideDot,
  26619. "icon": props.icon,
  26620. "iconColor": props.iconColor,
  26621. "size": props.size,
  26622. "elevation": props.elevation,
  26623. "dotColor": props.dotColor,
  26624. "fillDot": props.fillDot,
  26625. "rounded": props.rounded
  26626. }, {
  26627. default: slots.icon
  26628. }), props.density !== 'compact' && createVNode("div", {
  26629. "class": "v-timeline-item__opposite"
  26630. }, [!props.hideOpposite && slots.opposite?.()])]));
  26631. return {};
  26632. }
  26633. });
  26634. const makeVTimelineProps = propsFactory({
  26635. align: {
  26636. type: String,
  26637. default: 'center',
  26638. validator: v => ['center', 'start'].includes(v)
  26639. },
  26640. direction: {
  26641. type: String,
  26642. default: 'vertical',
  26643. validator: v => ['vertical', 'horizontal'].includes(v)
  26644. },
  26645. justify: {
  26646. type: String,
  26647. default: 'auto',
  26648. validator: v => ['auto', 'center'].includes(v)
  26649. },
  26650. side: {
  26651. type: String,
  26652. validator: v => v == null || ['start', 'end'].includes(v)
  26653. },
  26654. lineThickness: {
  26655. type: [String, Number],
  26656. default: 2
  26657. },
  26658. lineColor: String,
  26659. truncateLine: {
  26660. type: String,
  26661. validator: v => ['start', 'end', 'both'].includes(v)
  26662. },
  26663. ...only(makeVTimelineItemProps({
  26664. lineInset: 0
  26665. }), ['dotColor', 'fillDot', 'hideOpposite', 'iconColor', 'lineInset', 'size']),
  26666. ...makeComponentProps(),
  26667. ...makeDensityProps(),
  26668. ...makeTagProps(),
  26669. ...makeThemeProps()
  26670. }, 'VTimeline');
  26671. const VTimeline = genericComponent()({
  26672. name: 'VTimeline',
  26673. props: makeVTimelineProps(),
  26674. setup(props, _ref) {
  26675. let {
  26676. slots
  26677. } = _ref;
  26678. const {
  26679. themeClasses
  26680. } = provideTheme(props);
  26681. const {
  26682. densityClasses
  26683. } = useDensity(props);
  26684. const {
  26685. rtlClasses
  26686. } = useRtl();
  26687. provideDefaults({
  26688. VTimelineDivider: {
  26689. lineColor: toRef(props, 'lineColor')
  26690. },
  26691. VTimelineItem: {
  26692. density: toRef(props, 'density'),
  26693. dotColor: toRef(props, 'dotColor'),
  26694. fillDot: toRef(props, 'fillDot'),
  26695. hideOpposite: toRef(props, 'hideOpposite'),
  26696. iconColor: toRef(props, 'iconColor'),
  26697. lineColor: toRef(props, 'lineColor'),
  26698. lineInset: toRef(props, 'lineInset'),
  26699. size: toRef(props, 'size')
  26700. }
  26701. });
  26702. const sideClasses = computed(() => {
  26703. const side = props.side ? props.side : props.density !== 'default' ? 'end' : null;
  26704. return side && `v-timeline--side-${side}`;
  26705. });
  26706. const truncateClasses = computed(() => {
  26707. const classes = ['v-timeline--truncate-line-start', 'v-timeline--truncate-line-end'];
  26708. switch (props.truncateLine) {
  26709. case 'both':
  26710. return classes;
  26711. case 'start':
  26712. return classes[0];
  26713. case 'end':
  26714. return classes[1];
  26715. default:
  26716. return null;
  26717. }
  26718. });
  26719. useRender(() => createVNode(props.tag, {
  26720. "class": ['v-timeline', `v-timeline--${props.direction}`, `v-timeline--align-${props.align}`, `v-timeline--justify-${props.justify}`, truncateClasses.value, {
  26721. 'v-timeline--inset-line': !!props.lineInset
  26722. }, themeClasses.value, densityClasses.value, sideClasses.value, rtlClasses.value, props.class],
  26723. "style": [{
  26724. '--v-timeline-line-thickness': convertToUnit(props.lineThickness)
  26725. }, props.style]
  26726. }, slots));
  26727. return {};
  26728. }
  26729. });
  26730. const makeVToolbarItemsProps = propsFactory({
  26731. ...makeComponentProps(),
  26732. ...makeVariantProps({
  26733. variant: 'text'
  26734. })
  26735. }, 'VToolbarItems');
  26736. const VToolbarItems = genericComponent()({
  26737. name: 'VToolbarItems',
  26738. props: makeVToolbarItemsProps(),
  26739. setup(props, _ref) {
  26740. let {
  26741. slots
  26742. } = _ref;
  26743. provideDefaults({
  26744. VBtn: {
  26745. color: toRef(props, 'color'),
  26746. height: 'inherit',
  26747. variant: toRef(props, 'variant')
  26748. }
  26749. });
  26750. useRender(() => createVNode("div", {
  26751. "class": ['v-toolbar-items', props.class],
  26752. "style": props.style
  26753. }, [slots.default?.()]));
  26754. return {};
  26755. }
  26756. });
  26757. // Types
  26758. const makeVTooltipProps = propsFactory({
  26759. id: String,
  26760. text: String,
  26761. ...omit(makeVOverlayProps({
  26762. closeOnBack: false,
  26763. location: 'end',
  26764. locationStrategy: 'connected',
  26765. eager: true,
  26766. minWidth: 0,
  26767. offset: 10,
  26768. openOnClick: false,
  26769. openOnHover: true,
  26770. origin: 'auto',
  26771. scrim: false,
  26772. scrollStrategy: 'reposition',
  26773. transition: false
  26774. }), ['absolute', 'persistent'])
  26775. }, 'VTooltip');
  26776. const VTooltip = genericComponent()({
  26777. name: 'VTooltip',
  26778. props: makeVTooltipProps(),
  26779. emits: {
  26780. 'update:modelValue': value => true
  26781. },
  26782. setup(props, _ref) {
  26783. let {
  26784. slots
  26785. } = _ref;
  26786. const isActive = useProxiedModel(props, 'modelValue');
  26787. const {
  26788. scopeId
  26789. } = useScopeId();
  26790. const uid = getUid();
  26791. const id = computed(() => props.id || `v-tooltip-${uid}`);
  26792. const overlay = ref();
  26793. const location = computed(() => {
  26794. return props.location.split(' ').length > 1 ? props.location : props.location + ' center';
  26795. });
  26796. const origin = computed(() => {
  26797. return props.origin === 'auto' || props.origin === 'overlap' || props.origin.split(' ').length > 1 || props.location.split(' ').length > 1 ? props.origin : props.origin + ' center';
  26798. });
  26799. const transition = computed(() => {
  26800. if (props.transition) return props.transition;
  26801. return isActive.value ? 'scale-transition' : 'fade-transition';
  26802. });
  26803. const activatorProps = computed(() => mergeProps({
  26804. 'aria-describedby': id.value
  26805. }, props.activatorProps));
  26806. useRender(() => {
  26807. const overlayProps = VOverlay.filterProps(props);
  26808. return createVNode(VOverlay, mergeProps({
  26809. "ref": overlay,
  26810. "class": ['v-tooltip', props.class],
  26811. "style": props.style,
  26812. "id": id.value
  26813. }, overlayProps, {
  26814. "modelValue": isActive.value,
  26815. "onUpdate:modelValue": $event => isActive.value = $event,
  26816. "transition": transition.value,
  26817. "absolute": true,
  26818. "location": location.value,
  26819. "origin": origin.value,
  26820. "persistent": true,
  26821. "role": "tooltip",
  26822. "activatorProps": activatorProps.value,
  26823. "_disableGlobalStack": true
  26824. }, scopeId), {
  26825. activator: slots.activator,
  26826. default: function () {
  26827. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  26828. args[_key] = arguments[_key];
  26829. }
  26830. return slots.default?.(...args) ?? props.text;
  26831. }
  26832. });
  26833. });
  26834. return forwardRefs({}, overlay);
  26835. }
  26836. });
  26837. // Composables
  26838. // Types
  26839. const VValidation = genericComponent()({
  26840. name: 'VValidation',
  26841. props: makeValidationProps(),
  26842. emits: {
  26843. 'update:modelValue': value => true
  26844. },
  26845. setup(props, _ref) {
  26846. let {
  26847. slots
  26848. } = _ref;
  26849. const validation = useValidation(props, 'validation');
  26850. return () => slots.default?.(validation);
  26851. }
  26852. });
  26853. const makeVCalendarIntervalEventProps = propsFactory({
  26854. allDay: Boolean,
  26855. interval: Object,
  26856. intervalDivisions: {
  26857. type: Number,
  26858. required: true
  26859. },
  26860. intervalDuration: {
  26861. type: Number,
  26862. required: true
  26863. },
  26864. intervalHeight: {
  26865. type: Number,
  26866. required: true
  26867. },
  26868. event: Object
  26869. }, 'VCalendarIntervalEvent');
  26870. const VCalendarIntervalEvent = genericComponent()({
  26871. name: 'VCalendarIntervalEvent',
  26872. props: makeVCalendarIntervalEventProps(),
  26873. setup(props) {
  26874. const adapter = useDate();
  26875. const calcHeight = () => {
  26876. if (!props.event?.first && !props.event?.last || adapter.isEqual(props.event?.start, props.interval?.start)) {
  26877. return {
  26878. height: '100%',
  26879. margin: convertToUnit(0)
  26880. };
  26881. } else {
  26882. const {
  26883. height,
  26884. margin
  26885. } = Array.from({
  26886. length: props.intervalDivisions
  26887. }, x => x * (props.intervalDuration / props.intervalDivisions)).reduce((total, div, index) => {
  26888. if (adapter.isBefore(adapter.addMinutes(props.interval?.start, div), props.event?.start)) {
  26889. return {
  26890. height: convertToUnit(props.intervalHeight / props.intervalDivisions * index),
  26891. margin: convertToUnit(props.intervalHeight / props.intervalDivisions * index)
  26892. };
  26893. }
  26894. return {
  26895. height: total.height,
  26896. margin: total.margin
  26897. };
  26898. }, {
  26899. height: '',
  26900. margin: ''
  26901. });
  26902. return {
  26903. height,
  26904. margin
  26905. };
  26906. }
  26907. };
  26908. useRender(() => {
  26909. return createVNode(VSheet, {
  26910. "height": calcHeight().height,
  26911. "density": "comfortable",
  26912. "style": `margin-top: ${calcHeight().margin}`,
  26913. "class": "v-calendar-internal-event",
  26914. "color": props.event?.color ?? undefined,
  26915. "rounded": props.event?.first && props.event?.last ? true : props.event?.first ? 't' : props.event?.last ? 'b' : false
  26916. }, {
  26917. default: () => [props.event?.first ? props.event?.title : '']
  26918. });
  26919. });
  26920. return {};
  26921. }
  26922. });
  26923. const makeVCalendarIntervalProps = propsFactory({
  26924. day: {
  26925. type: Object,
  26926. default: () => ({})
  26927. },
  26928. dayIndex: Number,
  26929. events: Array,
  26930. intervalDivisions: {
  26931. type: Number,
  26932. default: 2
  26933. },
  26934. intervalDuration: {
  26935. type: Number,
  26936. default: 60
  26937. },
  26938. intervalHeight: {
  26939. type: Number,
  26940. default: 48
  26941. },
  26942. intervalFormat: {
  26943. type: [String, Function],
  26944. default: 'fullTime12h'
  26945. },
  26946. intervalStart: {
  26947. type: Number,
  26948. default: 0
  26949. }
  26950. }, 'VCalendarInterval');
  26951. const VCalendarInterval = genericComponent()({
  26952. name: 'VCalendarInterval',
  26953. props: {
  26954. index: {
  26955. type: Number,
  26956. required: true
  26957. },
  26958. ...makeVCalendarIntervalProps()
  26959. },
  26960. setup(props, _ref) {
  26961. const adapter = useDate();
  26962. const interval = computed(() => {
  26963. const start = adapter.addMinutes(adapter.startOfDay(props.day.date), props.intervalDuration * (props.index + props.intervalStart));
  26964. const end = adapter.addMinutes(adapter.startOfDay(props.day.date), props.intervalDuration * (props.index + props.intervalStart + 1) - 1);
  26965. return {
  26966. ...props.day,
  26967. label: adapter.format(start, 'fullTime24h'),
  26968. start,
  26969. end,
  26970. events: props.events ? props.events.filter(e => !e.allDay && (adapter.isEqual(start, e.start) || adapter.isWithinRange(e.start, [start, end]) || adapter.isWithinRange(start, [e.start, e.end]) || adapter.isEqual(end, e.end))).map(e => {
  26971. return {
  26972. ...e,
  26973. first: adapter.isEqual(start, e.start) || adapter.isWithinRange(e.start, [start, end]),
  26974. last: adapter.isEqual(end, e.end) || adapter.isWithinRange(e.end, [start, end])
  26975. };
  26976. }) : []
  26977. };
  26978. });
  26979. useRender(() => {
  26980. return props.dayIndex === 0 ? createVNode("div", {
  26981. "class": "v-calendar-day__row-with-label",
  26982. "style": `height: ${convertToUnit(props.intervalHeight)}`
  26983. }, [createVNode("div", {
  26984. "class": "v-calendar-day__row-label"
  26985. }, [createVNode("slot", {
  26986. "name": "intervalFormat",
  26987. "interval": interval.value
  26988. }, [props.index ? props.intervalFormat ? typeof props.intervalFormat === 'string' ? adapter.format(interval.value.start, 'hours12h') : props.intervalFormat(interval.value) : interval.value.label : ''])]), createVNode("div", {
  26989. "class": "v-calendar-day__row-hairline"
  26990. }, null), createVNode("div", {
  26991. "class": ['v-calendar-day__row-content', interval.value.events.some(e => !e.last) ? 'v-calendar-day__row-content-through' : '']
  26992. }, [createVNode("slot", {
  26993. "name": "intervalBody",
  26994. "interval": interval.value
  26995. }, [interval.value.events?.map(event => createVNode(VCalendarIntervalEvent, {
  26996. "event": event,
  26997. "interval": interval.value,
  26998. "intervalDivisions": props.intervalDivisions,
  26999. "intervalDuration": props.intervalDuration,
  27000. "intervalHeight": props.intervalHeight
  27001. }, null))])])]) : createVNode("div", {
  27002. "class": "v-calendar-day__row-without-label",
  27003. "style": `height: ${convertToUnit(props.intervalHeight)}`
  27004. }, [createVNode("div", {
  27005. "class": ['v-calendar-day__row-content', interval.value.events.some(e => !e.last) ? 'v-calendar-day__row-content-through' : '']
  27006. }, [createVNode("slot", {
  27007. "name": "intervalBody",
  27008. "interval": interval.value
  27009. }, [interval.value.events?.filter(event => !event.allDay).map(event => createVNode(VCalendarIntervalEvent, {
  27010. "event": event,
  27011. "interval": interval.value,
  27012. "intervalDivisions": props.intervalDivisions,
  27013. "intervalDuration": props.intervalDuration,
  27014. "intervalHeight": props.intervalHeight
  27015. }, null))])])]);
  27016. });
  27017. return {
  27018. interval
  27019. };
  27020. }
  27021. });
  27022. const makeVCalendarDayProps = propsFactory({
  27023. hideDayHeader: Boolean,
  27024. intervals: {
  27025. type: Number,
  27026. default: 24
  27027. },
  27028. ...makeVCalendarIntervalProps()
  27029. }, 'VCalendarDay');
  27030. const VCalendarDay = genericComponent()({
  27031. name: 'VCalendarDay',
  27032. props: makeVCalendarDayProps(),
  27033. setup(props) {
  27034. const adapter = useDate();
  27035. const intervals = computed(() => [...Array.from({
  27036. length: props.intervals
  27037. }, (v, i) => i).filter((int, index) => props.intervalDuration * (index + props.intervalStart) < 1440)]);
  27038. useRender(() => {
  27039. const calendarIntervalProps = VCalendarInterval.filterProps(props);
  27040. return createVNode("div", {
  27041. "class": "v-calendar-day__container"
  27042. }, [!props.hideDayHeader && createVNode("div", {
  27043. "key": "calender-week-name",
  27044. "class": "v-calendar-weekly__head-weekday"
  27045. }, [adapter.format(props.day.date, 'weekdayShort'), createVNode("div", null, [createVNode(VBtn, {
  27046. "icon": true,
  27047. "text": adapter.format(props.day.date, 'dayOfMonth'),
  27048. "variant": "text"
  27049. }, null)])]), intervals.value.map((_, index) => createVNode(VCalendarInterval, mergeProps({
  27050. "index": index
  27051. }, calendarIntervalProps), null))]);
  27052. });
  27053. return {
  27054. intervals
  27055. };
  27056. }
  27057. });
  27058. // Types
  27059. const makeVCalendarHeaderProps = propsFactory({
  27060. nextIcon: {
  27061. type: String,
  27062. default: '$next'
  27063. },
  27064. prevIcon: {
  27065. type: String,
  27066. default: '$prev'
  27067. },
  27068. title: String,
  27069. text: {
  27070. type: String,
  27071. default: '$vuetify.calendar.today'
  27072. },
  27073. viewMode: {
  27074. type: String,
  27075. default: 'month'
  27076. }
  27077. }, 'VCalendarHeader');
  27078. const VCalendarHeader = genericComponent()({
  27079. name: 'VCalendarHeader',
  27080. props: makeVCalendarHeaderProps(),
  27081. emits: {
  27082. 'click:next': () => true,
  27083. 'click:prev': () => true,
  27084. 'click:toToday': () => true
  27085. },
  27086. setup(props, _ref) {
  27087. let {
  27088. emit
  27089. } = _ref;
  27090. const {
  27091. t
  27092. } = useLocale();
  27093. function prev() {
  27094. emit('click:prev');
  27095. }
  27096. function next() {
  27097. emit('click:next');
  27098. }
  27099. function toToday() {
  27100. emit('click:toToday');
  27101. }
  27102. useRender(() => createVNode("div", {
  27103. "class": "v-calendar-header"
  27104. }, [props.text && createVNode(VBtn, {
  27105. "key": "today",
  27106. "class": "v-calendar-header__today",
  27107. "text": t(props.text),
  27108. "variant": "outlined",
  27109. "onClick": toToday
  27110. }, null), createVNode(VBtn, {
  27111. "density": "comfortable",
  27112. "icon": props.prevIcon,
  27113. "variant": "text",
  27114. "onClick": prev
  27115. }, null), createVNode(VBtn, {
  27116. "density": "comfortable",
  27117. "icon": props.nextIcon,
  27118. "variant": "text",
  27119. "onClick": next
  27120. }, null), createVNode("div", {
  27121. "class": "v-calendar-header__title"
  27122. }, [props.title])]));
  27123. return {};
  27124. }
  27125. });
  27126. const makeVCalendarEventProps = propsFactory({
  27127. allDay: Boolean,
  27128. day: Object,
  27129. event: Object
  27130. }, 'VCalendarEvent');
  27131. const VCalendarEvent = genericComponent()({
  27132. name: 'VCalendarEvent',
  27133. props: makeVCalendarEventProps(),
  27134. setup(props) {
  27135. useRender(() => createVNode(VChip, {
  27136. "color": props.allDay ? 'primary' : undefined,
  27137. "density": "comfortable",
  27138. "label": props.allDay,
  27139. "width": "100%"
  27140. }, {
  27141. default: () => [createVNode(VBadge, {
  27142. "inline": true,
  27143. "dot": true,
  27144. "color": props.event?.color
  27145. }, null), props.event?.title]
  27146. }));
  27147. return {};
  27148. }
  27149. });
  27150. const makeVCalendarMonthDayProps = propsFactory({
  27151. active: Boolean,
  27152. color: String,
  27153. day: Object,
  27154. disabled: Boolean,
  27155. events: Array,
  27156. title: [Number, String]
  27157. }, 'VCalendarMonthDay');
  27158. const VCalendarMonthDay = genericComponent()({
  27159. name: 'VCalendarMonthDay',
  27160. props: makeVCalendarMonthDayProps(),
  27161. setup(props, _ref) {
  27162. let {
  27163. emit,
  27164. slots
  27165. } = _ref;
  27166. useRender(() => {
  27167. const hasTitle = !!(props.title || slots.title?.({
  27168. title: props.title
  27169. }));
  27170. return createVNode("div", {
  27171. "class": ['v-calendar-month__day']
  27172. }, [!props.day?.isHidden && hasTitle && createVNode("div", {
  27173. "key": "title",
  27174. "class": "v-calendar-weekly__day-label"
  27175. }, [slots.title?.({
  27176. title: props.title
  27177. }) ?? createVNode(VBtn, {
  27178. "class": props.day?.isToday ? 'v-calendar-weekly__day-label__today' : undefined,
  27179. "color": props.color,
  27180. "disabled": props.disabled,
  27181. "icon": true,
  27182. "size": "x-small",
  27183. "variant": props.day?.isToday ? undefined : 'flat'
  27184. }, {
  27185. default: () => [props.title]
  27186. })]), !props.day?.isHidden && createVNode("div", {
  27187. "key": "content",
  27188. "class": "v-calendar-weekly__day-content"
  27189. }, [slots.content?.() ?? createVNode("div", null, [createVNode("div", {
  27190. "class": "v-calendar-weekly__day-alldayevents-container"
  27191. }, [props.events?.filter(event => event.allDay).map(event => slots.event ? slots.event({
  27192. day: props.day,
  27193. allDay: true,
  27194. event
  27195. }) : createVNode(VCalendarEvent, {
  27196. "day": props.day,
  27197. "event": event,
  27198. "allDay": true
  27199. }, null))]), createVNode("div", {
  27200. "class": "v-calendar-weekly__day-events-container"
  27201. }, [props.events?.filter(event => !event.allDay).map(event => slots.event ? slots.event({
  27202. day: props.day,
  27203. event,
  27204. allDay: false
  27205. }) : createVNode(VCalendarEvent, {
  27206. "day": props.day,
  27207. "event": event
  27208. }, null))])])]), !props.day?.isHidden && slots.default?.()]);
  27209. });
  27210. return {};
  27211. }
  27212. });
  27213. const makeVCalendarProps = propsFactory({
  27214. hideHeader: Boolean,
  27215. hideWeekNumber: Boolean,
  27216. ...makeCalendarProps(),
  27217. ...makeVCalendarDayProps(),
  27218. ...makeVCalendarHeaderProps()
  27219. }, 'VCalender');
  27220. const VCalendar = genericComponent()({
  27221. name: 'VCalendar',
  27222. props: makeVCalendarProps(),
  27223. emits: {
  27224. next: null,
  27225. prev: null,
  27226. 'update:modelValue': null
  27227. },
  27228. setup(props, _ref) {
  27229. let {
  27230. emit,
  27231. slots
  27232. } = _ref;
  27233. const adapter = useDate();
  27234. const {
  27235. daysInMonth,
  27236. daysInWeek,
  27237. genDays,
  27238. model,
  27239. displayValue,
  27240. weekNumbers,
  27241. weekDays
  27242. } = useCalendar(props);
  27243. const dayNames = adapter.getWeekdays();
  27244. function onClickNext() {
  27245. if (props.viewMode === 'month') {
  27246. model.value = [adapter.addMonths(displayValue.value, 1)];
  27247. }
  27248. if (props.viewMode === 'week') {
  27249. model.value = [adapter.addDays(displayValue.value, 7)];
  27250. }
  27251. if (props.viewMode === 'day') {
  27252. model.value = [adapter.addDays(displayValue.value, 1)];
  27253. }
  27254. }
  27255. function onClickPrev() {
  27256. if (props.viewMode === 'month') {
  27257. model.value = [adapter.addMonths(displayValue.value, -1)];
  27258. }
  27259. if (props.viewMode === 'week') {
  27260. model.value = [adapter.addDays(displayValue.value, -7)];
  27261. }
  27262. if (props.viewMode === 'day') {
  27263. model.value = [adapter.addDays(displayValue.value, -1)];
  27264. }
  27265. }
  27266. function onClickToday() {
  27267. model.value = [adapter.date()];
  27268. }
  27269. const title = computed(() => {
  27270. return adapter.format(displayValue.value, 'monthAndYear');
  27271. });
  27272. useRender(() => {
  27273. const calendarDayProps = VCalendarDay.filterProps(props);
  27274. const calendarHeaderProps = VCalendarHeader.filterProps(props);
  27275. return createVNode("div", {
  27276. "class": ['v-calendar', {
  27277. 'v-calendar-monthly': props.viewMode === 'month',
  27278. 'v-calendar-weekly': props.viewMode === 'week',
  27279. 'v-calendar-day': props.viewMode === 'day'
  27280. }]
  27281. }, [createVNode("div", null, [!props.hideHeader && (!slots.header ? createVNode(VCalendarHeader, mergeProps({
  27282. "key": "calendar-header"
  27283. }, calendarHeaderProps, {
  27284. "title": title.value,
  27285. "onClick:next": onClickNext,
  27286. "onClick:prev": onClickPrev,
  27287. "onClick:toToday": onClickToday
  27288. }), null) : slots.header({
  27289. title: title.value
  27290. }))]), createVNode("div", {
  27291. "class": ['v-calendar__container', `days__${weekDays.value.length}`]
  27292. }, [props.viewMode === 'month' && !props.hideDayHeader && createVNode("div", {
  27293. "class": ['v-calendar-weekly__head', `days__${weekDays.value.length}`, ...(!props.hideWeekNumber ? ['v-calendar-weekly__head-weeknumbers'] : [])],
  27294. "key": "calenderWeeklyHead"
  27295. }, [!props.hideWeekNumber ? createVNode("div", {
  27296. "key": "weekNumber0",
  27297. "class": "v-calendar-weekly__head-weeknumber"
  27298. }, null) : '', weekDays.value.map(weekday => createVNode("div", {
  27299. "class": `v-calendar-weekly__head-weekday${!props.hideWeekNumber ? '-with-weeknumber' : ''}`
  27300. }, [dayNames[weekday]]))]), props.viewMode === 'month' && createVNode("div", {
  27301. "key": "VCalendarMonth",
  27302. "class": ['v-calendar-month__days', `days${!props.hideWeekNumber ? '-with-weeknumbers' : ''}__${weekDays.value.length}`, ...(!props.hideWeekNumber ? ['v-calendar-month__weeknumbers'] : [])]
  27303. }, [chunkArray(daysInMonth.value, weekDays.value.length).map((week, wi) => [!props.hideWeekNumber ? createVNode("div", {
  27304. "class": "v-calendar-month__weeknumber"
  27305. }, [weekNumbers.value[wi]]) : '', week.map(day => createVNode(VCalendarMonthDay, {
  27306. "color": adapter.isSameDay(adapter.date(), day.date) ? 'primary' : undefined,
  27307. "day": day,
  27308. "title": day ? adapter.format(day.date, 'dayOfMonth') : 'NaN',
  27309. "events": props.events?.filter(e => adapter.isSameDay(day.date, e.start) || adapter.isSameDay(day.date, e.end))
  27310. }, {
  27311. event: slots.event
  27312. }))])]), props.viewMode === 'week' && daysInWeek.value.map((day, i) => createVNode(VCalendarDay, mergeProps(calendarDayProps, {
  27313. "day": day,
  27314. "dayIndex": i,
  27315. "events": props.events?.filter(e => adapter.isSameDay(e.start, day.date) || adapter.isSameDay(e.end, day.date))
  27316. }), null)), props.viewMode === 'day' && createVNode(VCalendarDay, mergeProps(calendarDayProps, {
  27317. "day": genDays([displayValue.value], adapter.date())[0],
  27318. "dayIndex": 0,
  27319. "events": props.events?.filter(e => adapter.isSameDay(e.start, genDays([displayValue.value], adapter.date())[0].date) || adapter.isSameDay(e.end, genDays([displayValue.value], adapter.date())[0].date))
  27320. }), null)])]);
  27321. });
  27322. return {
  27323. daysInMonth,
  27324. daysInWeek,
  27325. genDays
  27326. };
  27327. }
  27328. });
  27329. // Types
  27330. const makeVDateInputProps = propsFactory({
  27331. hideActions: Boolean,
  27332. ...makeFocusProps(),
  27333. ...makeVConfirmEditProps(),
  27334. ...makeVTextFieldProps({
  27335. placeholder: 'mm/dd/yyyy',
  27336. prependIcon: '$calendar'
  27337. }),
  27338. ...omit(makeVDatePickerProps({
  27339. weeksInMonth: 'dynamic',
  27340. hideHeader: true
  27341. }), ['active'])
  27342. }, 'VDateInput');
  27343. const VDateInput = genericComponent()({
  27344. name: 'VDateInput',
  27345. props: makeVDateInputProps(),
  27346. emits: {
  27347. 'update:modelValue': val => true
  27348. },
  27349. setup(props, _ref) {
  27350. let {
  27351. slots
  27352. } = _ref;
  27353. const {
  27354. t
  27355. } = useLocale();
  27356. const adapter = useDate();
  27357. const {
  27358. isFocused,
  27359. focus,
  27360. blur
  27361. } = useFocus(props);
  27362. const model = useProxiedModel(props, 'modelValue', props.multiple ? [] : null);
  27363. const menu = shallowRef(false);
  27364. const display = computed(() => {
  27365. const value = wrapInArray(model.value);
  27366. if (!value.length) return null;
  27367. if (props.multiple === true) {
  27368. return t('$vuetify.datePicker.itemsSelected', value.length);
  27369. }
  27370. if (props.multiple === 'range') {
  27371. const start = value[0];
  27372. const end = value[value.length - 1];
  27373. return adapter.isValid(start) && adapter.isValid(end) ? `${adapter.format(start, 'keyboardDate')} - ${adapter.format(end, 'keyboardDate')}` : '';
  27374. }
  27375. return adapter.isValid(model.value) ? adapter.format(model.value, 'keyboardDate') : '';
  27376. });
  27377. const isInteractive = computed(() => !props.disabled && !props.readonly);
  27378. function onKeydown(e) {
  27379. if (e.key !== 'Enter') return;
  27380. if (!menu.value || !isFocused.value) {
  27381. menu.value = true;
  27382. return;
  27383. }
  27384. const target = e.target;
  27385. model.value = adapter.date(target.value);
  27386. }
  27387. function onClick(e) {
  27388. e.preventDefault();
  27389. e.stopPropagation();
  27390. menu.value = true;
  27391. }
  27392. function onSave() {
  27393. menu.value = false;
  27394. }
  27395. useRender(() => {
  27396. const confirmEditProps = VConfirmEdit.filterProps(props);
  27397. const datePickerProps = VDatePicker.filterProps(omit(props, ['active']));
  27398. const textFieldProps = VTextField.filterProps(props);
  27399. return createVNode(VTextField, mergeProps(textFieldProps, {
  27400. "class": props.class,
  27401. "style": props.style,
  27402. "modelValue": display.value,
  27403. "onKeydown": isInteractive.value ? onKeydown : undefined,
  27404. "focused": menu.value || isFocused.value,
  27405. "onFocus": focus,
  27406. "onBlur": blur,
  27407. "onClick:control": isInteractive.value ? onClick : undefined,
  27408. "onClick:prepend": isInteractive.value ? onClick : undefined
  27409. }), {
  27410. default: () => [createVNode(VMenu, {
  27411. "modelValue": menu.value,
  27412. "onUpdate:modelValue": $event => menu.value = $event,
  27413. "activator": "parent",
  27414. "min-width": "0",
  27415. "closeOnContentClick": false,
  27416. "openOnClick": false
  27417. }, {
  27418. default: () => [createVNode(VConfirmEdit, mergeProps(confirmEditProps, {
  27419. "modelValue": model.value,
  27420. "onUpdate:modelValue": $event => model.value = $event,
  27421. "onSave": onSave
  27422. }), {
  27423. default: _ref2 => {
  27424. let {
  27425. actions,
  27426. model: proxyModel
  27427. } = _ref2;
  27428. return createVNode(VDatePicker, mergeProps(datePickerProps, {
  27429. "modelValue": props.hideActions ? model.value : proxyModel.value,
  27430. "onUpdate:modelValue": val => {
  27431. if (!props.hideActions) {
  27432. proxyModel.value = val;
  27433. } else {
  27434. model.value = val;
  27435. if (!props.multiple) menu.value = false;
  27436. }
  27437. },
  27438. "onMousedown": e => e.preventDefault()
  27439. }), {
  27440. actions: !props.hideActions ? actions : undefined
  27441. });
  27442. }
  27443. })]
  27444. }), slots.default?.()]
  27445. });
  27446. });
  27447. }
  27448. });
  27449. // Types
  27450. const makeVFileUploadItemProps = propsFactory({
  27451. clearable: Boolean,
  27452. file: {
  27453. type: Object,
  27454. default: null
  27455. },
  27456. fileIcon: {
  27457. type: String,
  27458. // TODO: setup up a proper aliased icon
  27459. default: 'mdi-file-document'
  27460. },
  27461. showSize: Boolean,
  27462. ...makeVListItemProps({
  27463. border: true,
  27464. rounded: true,
  27465. lines: 'two'
  27466. })
  27467. }, 'VFileUploadItem');
  27468. const VFileUploadItem = genericComponent()({
  27469. name: 'VFileUploadItem',
  27470. props: makeVFileUploadItemProps(),
  27471. emits: {
  27472. 'click:remove': () => true,
  27473. click: e => true
  27474. },
  27475. setup(props, _ref) {
  27476. let {
  27477. emit,
  27478. slots
  27479. } = _ref;
  27480. const preview = ref();
  27481. const base = computed(() => typeof props.showSize !== 'boolean' ? props.showSize : undefined);
  27482. function onClickRemove() {
  27483. emit('click:remove');
  27484. }
  27485. watchEffect(() => {
  27486. preview.value = props.file?.type.startsWith('image') ? URL.createObjectURL(props.file) : undefined;
  27487. });
  27488. useRender(() => {
  27489. const listItemProps = VListItem.filterProps(props);
  27490. return createVNode(VListItem, mergeProps(listItemProps, {
  27491. "title": props.title ?? props.file?.name,
  27492. "subtitle": props.showSize ? humanReadableFileSize(props.file?.size, base.value) : props.file?.type,
  27493. "class": "v-file-upload-item"
  27494. }), {
  27495. ...slots,
  27496. prepend: slotProps => createVNode(Fragment, null, [!slots.prepend ? createVNode(VAvatar, {
  27497. "icon": props.fileIcon,
  27498. "image": preview.value,
  27499. "rounded": true
  27500. }, null) : createVNode(VDefaultsProvider, {
  27501. "defaults": {
  27502. VAvatar: {
  27503. image: preview.value,
  27504. icon: !preview.value ? props.fileIcon : undefined,
  27505. rounded: true
  27506. }
  27507. }
  27508. }, {
  27509. default: () => [slots.prepend?.(slotProps) ?? createVNode(VAvatar, null, null)]
  27510. })]),
  27511. append: slotProps => createVNode(Fragment, null, [props.clearable && createVNode(Fragment, null, [!slots.clear ? createVNode(VBtn, {
  27512. "icon": "$clear",
  27513. "density": "comfortable",
  27514. "variant": "text",
  27515. "onClick": onClickRemove
  27516. }, null) : createVNode(VDefaultsProvider, {
  27517. "defaults": {
  27518. VBtn: {
  27519. icon: '$clear',
  27520. density: 'comfortable',
  27521. variant: 'text'
  27522. }
  27523. }
  27524. }, {
  27525. default: () => [slots.clear?.({
  27526. ...slotProps,
  27527. props: {
  27528. onClick: onClickRemove
  27529. }
  27530. }) ?? createVNode(VBtn, null, null)]
  27531. })]), slots.append?.(slotProps)])
  27532. });
  27533. });
  27534. }
  27535. });
  27536. // Types
  27537. const makeVFileUploadProps = propsFactory({
  27538. browseText: {
  27539. type: String,
  27540. default: '$vuetify.fileUpload.browse'
  27541. },
  27542. dividerText: {
  27543. type: String,
  27544. default: '$vuetify.fileUpload.divider'
  27545. },
  27546. title: {
  27547. type: String,
  27548. default: '$vuetify.fileUpload.title'
  27549. },
  27550. subtitle: String,
  27551. icon: {
  27552. type: IconValue,
  27553. default: '$upload'
  27554. },
  27555. modelValue: {
  27556. type: [Array, Object],
  27557. default: null,
  27558. validator: val => {
  27559. return wrapInArray(val).every(v => v != null && typeof v === 'object');
  27560. }
  27561. },
  27562. clearable: Boolean,
  27563. disabled: Boolean,
  27564. hideBrowse: Boolean,
  27565. multiple: Boolean,
  27566. scrim: {
  27567. type: [Boolean, String],
  27568. default: true
  27569. },
  27570. showSize: Boolean,
  27571. name: String,
  27572. ...makeDelayProps(),
  27573. ...makeDensityProps(),
  27574. ...only(makeVDividerProps({
  27575. length: 150
  27576. }), ['length', 'thickness', 'opacity']),
  27577. ...makeVSheetProps()
  27578. }, 'VFileUpload');
  27579. const VFileUpload = genericComponent()({
  27580. name: 'VFileUpload',
  27581. inheritAttrs: false,
  27582. props: makeVFileUploadProps(),
  27583. emits: {
  27584. 'update:modelValue': files => true
  27585. },
  27586. setup(props, _ref) {
  27587. let {
  27588. attrs,
  27589. slots
  27590. } = _ref;
  27591. const {
  27592. t
  27593. } = useLocale();
  27594. const {
  27595. densityClasses
  27596. } = useDensity(props);
  27597. const model = useProxiedModel(props, 'modelValue', props.modelValue, val => wrapInArray(val), val => props.multiple || Array.isArray(props.modelValue) ? val : val[0]);
  27598. const dragOver = shallowRef(false);
  27599. const vSheetRef = ref(null);
  27600. const inputRef = ref(null);
  27601. onMounted(() => {
  27602. vSheetRef.value?.$el.addEventListener('dragover', onDragOver);
  27603. vSheetRef.value?.$el.addEventListener('drop', onDrop);
  27604. });
  27605. onUnmounted(() => {
  27606. vSheetRef.value?.$el.removeEventListener('dragover', onDragOver);
  27607. vSheetRef.value?.$el.removeEventListener('drop', onDrop);
  27608. });
  27609. function onDragOver(e) {
  27610. e.preventDefault();
  27611. e.stopImmediatePropagation();
  27612. dragOver.value = true;
  27613. }
  27614. function onDragLeave(e) {
  27615. e.preventDefault();
  27616. dragOver.value = false;
  27617. }
  27618. function onDrop(e) {
  27619. e.preventDefault();
  27620. e.stopImmediatePropagation();
  27621. dragOver.value = false;
  27622. const files = Array.from(e.dataTransfer?.files ?? []);
  27623. if (!files.length) return;
  27624. if (!props.multiple) {
  27625. model.value = [files[0]];
  27626. return;
  27627. }
  27628. const array = model.value.slice();
  27629. for (const file of files) {
  27630. if (!array.some(f => f.name === file.name)) {
  27631. array.push(file);
  27632. }
  27633. }
  27634. model.value = array;
  27635. }
  27636. function onClick() {
  27637. inputRef.value?.click();
  27638. }
  27639. function onClickRemove(index) {
  27640. model.value = model.value.filter((_, i) => i !== index);
  27641. if (model.value.length > 0 || !inputRef.value) return;
  27642. inputRef.value.value = '';
  27643. }
  27644. useRender(() => {
  27645. const hasTitle = !!(slots.title || props.title);
  27646. const hasIcon = !!(slots.icon || props.icon);
  27647. const hasBrowse = !!(!props.hideBrowse && (slots.browse || props.density === 'default'));
  27648. const cardProps = VSheet.filterProps(props);
  27649. const dividerProps = VDivider.filterProps(props);
  27650. const [rootAttrs, inputAttrs] = filterInputAttrs(attrs);
  27651. const inputNode = createVNode("input", mergeProps({
  27652. "ref": inputRef,
  27653. "type": "file",
  27654. "disabled": props.disabled,
  27655. "multiple": props.multiple,
  27656. "name": props.name,
  27657. "onChange": e => {
  27658. if (!e.target) return;
  27659. const target = e.target;
  27660. model.value = [...(target.files ?? [])];
  27661. }
  27662. }, inputAttrs), null);
  27663. return createVNode(Fragment, null, [createVNode(VSheet, mergeProps({
  27664. "ref": vSheetRef
  27665. }, cardProps, {
  27666. "class": ['v-file-upload', {
  27667. 'v-file-upload--clickable': !hasBrowse,
  27668. 'v-file-upload--disabled': props.disabled,
  27669. 'v-file-upload--dragging': dragOver.value
  27670. }, densityClasses.value],
  27671. "onDragleave": onDragLeave,
  27672. "onDragover": onDragOver,
  27673. "onDrop": onDrop,
  27674. "onClick": !hasBrowse ? onClick : undefined
  27675. }, rootAttrs), {
  27676. default: () => [hasIcon && createVNode("div", {
  27677. "key": "icon",
  27678. "class": "v-file-upload-icon"
  27679. }, [!slots.icon ? createVNode(VIcon, {
  27680. "key": "icon-icon",
  27681. "icon": props.icon
  27682. }, null) : createVNode(VDefaultsProvider, {
  27683. "key": "icon-defaults",
  27684. "defaults": {
  27685. VIcon: {
  27686. icon: props.icon
  27687. }
  27688. }
  27689. }, {
  27690. default: () => [slots.icon()]
  27691. })]), hasTitle && createVNode("div", {
  27692. "key": "title",
  27693. "class": "v-file-upload-title"
  27694. }, [slots.title?.() ?? t(props.title)]), props.density === 'default' && createVNode(Fragment, null, [createVNode("div", {
  27695. "key": "upload-divider",
  27696. "class": "v-file-upload-divider"
  27697. }, [slots.divider?.() ?? createVNode(VDivider, dividerProps, {
  27698. default: () => [t(props.dividerText)]
  27699. })]), hasBrowse && createVNode(Fragment, null, [!slots.browse ? createVNode(VBtn, {
  27700. "readonly": props.disabled,
  27701. "size": "large",
  27702. "text": t(props.browseText),
  27703. "variant": "tonal",
  27704. "onClick": onClick
  27705. }, null) : createVNode(VDefaultsProvider, {
  27706. "defaults": {
  27707. VBtn: {
  27708. readonly: props.disabled,
  27709. size: 'large',
  27710. text: t(props.browseText),
  27711. variant: 'tonal'
  27712. }
  27713. }
  27714. }, {
  27715. default: () => [slots.browse({
  27716. props: {
  27717. onClick
  27718. }
  27719. })]
  27720. })]), props.subtitle && createVNode("div", {
  27721. "class": "v-file-upload-subtitle"
  27722. }, [props.subtitle])]), createVNode(VOverlay, {
  27723. "model-value": dragOver.value,
  27724. "contained": true,
  27725. "scrim": props.scrim
  27726. }, null), slots.input?.({
  27727. inputNode
  27728. }) ?? inputNode]
  27729. }), model.value.length > 0 && createVNode("div", {
  27730. "class": "v-file-upload-items"
  27731. }, [model.value.map((file, i) => {
  27732. const slotProps = {
  27733. file,
  27734. props: {
  27735. 'onClick:remove': () => onClickRemove(i)
  27736. }
  27737. };
  27738. return createVNode(VDefaultsProvider, {
  27739. "key": i,
  27740. "defaults": {
  27741. VFileUploadItem: {
  27742. file,
  27743. clearable: props.clearable,
  27744. disabled: props.disabled,
  27745. showSize: props.showSize
  27746. }
  27747. }
  27748. }, {
  27749. default: () => [slots.item?.(slotProps) ?? createVNode(VFileUploadItem, {
  27750. "key": i,
  27751. "onClick:remove": () => onClickRemove(i)
  27752. }, slots)]
  27753. });
  27754. })])]);
  27755. });
  27756. }
  27757. });
  27758. // Types
  27759. const makeVNumberInputProps = propsFactory({
  27760. controlVariant: {
  27761. type: String,
  27762. default: 'default'
  27763. },
  27764. inset: Boolean,
  27765. hideInput: Boolean,
  27766. modelValue: {
  27767. type: Number,
  27768. default: null
  27769. },
  27770. min: {
  27771. type: Number,
  27772. default: Number.MIN_SAFE_INTEGER
  27773. },
  27774. max: {
  27775. type: Number,
  27776. default: Number.MAX_SAFE_INTEGER
  27777. },
  27778. step: {
  27779. type: Number,
  27780. default: 1
  27781. },
  27782. ...omit(makeVTextFieldProps({}), ['appendInnerIcon', 'modelValue', 'prependInnerIcon'])
  27783. }, 'VNumberInput');
  27784. const VNumberInput = genericComponent()({
  27785. name: 'VNumberInput',
  27786. props: {
  27787. ...makeVNumberInputProps()
  27788. },
  27789. emits: {
  27790. 'update:modelValue': val => true
  27791. },
  27792. setup(props, _ref) {
  27793. let {
  27794. slots
  27795. } = _ref;
  27796. const _model = useProxiedModel(props, 'modelValue');
  27797. const model = computed({
  27798. get: () => _model.value,
  27799. // model.value could be empty string from VTextField
  27800. // but _model.value should be eventually kept in type Number | null
  27801. set(val) {
  27802. if (val === null || val === '') {
  27803. _model.value = null;
  27804. return;
  27805. }
  27806. const value = Number(val);
  27807. if (!isNaN(value) && value <= props.max && value >= props.min) {
  27808. _model.value = value;
  27809. }
  27810. }
  27811. });
  27812. const vTextFieldRef = ref();
  27813. const stepDecimals = computed(() => getDecimals(props.step));
  27814. const modelDecimals = computed(() => typeof model.value === 'number' ? getDecimals(model.value) : 0);
  27815. const form = useForm(props);
  27816. const controlsDisabled = computed(() => form.isDisabled.value || form.isReadonly.value);
  27817. const canIncrease = computed(() => {
  27818. if (controlsDisabled.value) return false;
  27819. return (model.value ?? 0) + props.step <= props.max;
  27820. });
  27821. const canDecrease = computed(() => {
  27822. if (controlsDisabled.value) return false;
  27823. return (model.value ?? 0) - props.step >= props.min;
  27824. });
  27825. const controlVariant = computed(() => {
  27826. return props.hideInput ? 'stacked' : props.controlVariant;
  27827. });
  27828. const incrementIcon = computed(() => controlVariant.value === 'split' ? '$plus' : '$collapse');
  27829. const decrementIcon = computed(() => controlVariant.value === 'split' ? '$minus' : '$expand');
  27830. const controlNodeSize = computed(() => controlVariant.value === 'split' ? 'default' : 'small');
  27831. const controlNodeDefaultHeight = computed(() => controlVariant.value === 'stacked' ? 'auto' : '100%');
  27832. const incrementSlotProps = computed(() => ({
  27833. click: onClickUp
  27834. }));
  27835. const decrementSlotProps = computed(() => ({
  27836. click: onClickDown
  27837. }));
  27838. onMounted(() => {
  27839. if (!controlsDisabled.value) {
  27840. clampModel();
  27841. }
  27842. });
  27843. function toggleUpDown() {
  27844. let increment = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
  27845. if (controlsDisabled.value) return;
  27846. if (model.value == null) {
  27847. model.value = clamp(0, props.min, props.max);
  27848. return;
  27849. }
  27850. const decimals = Math.max(modelDecimals.value, stepDecimals.value);
  27851. if (increment) {
  27852. if (canIncrease.value) model.value = +(model.value + props.step).toFixed(decimals);
  27853. } else {
  27854. if (canDecrease.value) model.value = +(model.value - props.step).toFixed(decimals);
  27855. }
  27856. }
  27857. function onClickUp(e) {
  27858. e.stopPropagation();
  27859. toggleUpDown();
  27860. }
  27861. function onClickDown(e) {
  27862. e.stopPropagation();
  27863. toggleUpDown(false);
  27864. }
  27865. function onBeforeinput(e) {
  27866. if (!e.data) return;
  27867. const existingTxt = e.target?.value;
  27868. const selectionStart = e.target?.selectionStart;
  27869. const selectionEnd = e.target?.selectionEnd;
  27870. const potentialNewInputVal = existingTxt ? existingTxt.slice(0, selectionStart) + e.data + existingTxt.slice(selectionEnd) : e.data;
  27871. // Only numbers, "-", "." are allowed
  27872. // AND "-", "." are allowed only once
  27873. // AND "-" is only allowed at the start
  27874. if (!/^-?(\d+(\.\d*)?|(\.\d+)|\d*|\.)$/.test(potentialNewInputVal)) {
  27875. e.preventDefault();
  27876. }
  27877. }
  27878. async function onKeydown(e) {
  27879. if (['Enter', 'ArrowLeft', 'ArrowRight', 'Backspace', 'Delete', 'Tab'].includes(e.key) || e.ctrlKey) return;
  27880. if (['ArrowDown', 'ArrowUp'].includes(e.key)) {
  27881. e.preventDefault();
  27882. clampModel();
  27883. // _model is controlled, so need to wait until props['modelValue'] is updated
  27884. await nextTick();
  27885. if (e.key === 'ArrowDown') {
  27886. toggleUpDown(false);
  27887. } else {
  27888. toggleUpDown();
  27889. }
  27890. }
  27891. }
  27892. function onControlMousedown(e) {
  27893. e.stopPropagation();
  27894. }
  27895. function clampModel() {
  27896. if (!vTextFieldRef.value) return;
  27897. const inputText = vTextFieldRef.value.value;
  27898. if (inputText && !isNaN(+inputText)) {
  27899. model.value = clamp(+inputText, props.min, props.max);
  27900. } else {
  27901. model.value = null;
  27902. }
  27903. }
  27904. useRender(() => {
  27905. const {
  27906. modelValue: _,
  27907. ...textFieldProps
  27908. } = VTextField.filterProps(props);
  27909. function incrementControlNode() {
  27910. return !slots.increment ? createVNode(VBtn, {
  27911. "disabled": !canIncrease.value,
  27912. "flat": true,
  27913. "key": "increment-btn",
  27914. "height": controlNodeDefaultHeight.value,
  27915. "data-testid": "increment",
  27916. "aria-hidden": "true",
  27917. "icon": incrementIcon.value,
  27918. "onClick": onClickUp,
  27919. "onMousedown": onControlMousedown,
  27920. "size": controlNodeSize.value,
  27921. "tabindex": "-1"
  27922. }, null) : createVNode(VDefaultsProvider, {
  27923. "key": "increment-defaults",
  27924. "defaults": {
  27925. VBtn: {
  27926. disabled: !canIncrease.value,
  27927. flat: true,
  27928. height: controlNodeDefaultHeight.value,
  27929. size: controlNodeSize.value,
  27930. icon: incrementIcon.value
  27931. }
  27932. }
  27933. }, {
  27934. default: () => [slots.increment(incrementSlotProps.value)]
  27935. });
  27936. }
  27937. function decrementControlNode() {
  27938. return !slots.decrement ? createVNode(VBtn, {
  27939. "disabled": !canDecrease.value,
  27940. "flat": true,
  27941. "key": "decrement-btn",
  27942. "height": controlNodeDefaultHeight.value,
  27943. "data-testid": "decrement",
  27944. "aria-hidden": "true",
  27945. "icon": decrementIcon.value,
  27946. "size": controlNodeSize.value,
  27947. "tabindex": "-1",
  27948. "onClick": onClickDown,
  27949. "onMousedown": onControlMousedown
  27950. }, null) : createVNode(VDefaultsProvider, {
  27951. "key": "decrement-defaults",
  27952. "defaults": {
  27953. VBtn: {
  27954. disabled: !canDecrease.value,
  27955. flat: true,
  27956. height: controlNodeDefaultHeight.value,
  27957. size: controlNodeSize.value,
  27958. icon: decrementIcon.value
  27959. }
  27960. }
  27961. }, {
  27962. default: () => [slots.decrement(decrementSlotProps.value)]
  27963. });
  27964. }
  27965. function controlNode() {
  27966. return createVNode("div", {
  27967. "class": "v-number-input__control"
  27968. }, [decrementControlNode(), createVNode(VDivider, {
  27969. "vertical": controlVariant.value !== 'stacked'
  27970. }, null), incrementControlNode()]);
  27971. }
  27972. function dividerNode() {
  27973. return !props.hideInput && !props.inset ? createVNode(VDivider, {
  27974. "vertical": true
  27975. }, null) : undefined;
  27976. }
  27977. const appendInnerControl = controlVariant.value === 'split' ? createVNode("div", {
  27978. "class": "v-number-input__control"
  27979. }, [createVNode(VDivider, {
  27980. "vertical": true
  27981. }, null), incrementControlNode()]) : props.reverse ? undefined : createVNode(Fragment, null, [dividerNode(), controlNode()]);
  27982. const hasAppendInner = slots['append-inner'] || appendInnerControl;
  27983. const prependInnerControl = controlVariant.value === 'split' ? createVNode("div", {
  27984. "class": "v-number-input__control"
  27985. }, [decrementControlNode(), createVNode(VDivider, {
  27986. "vertical": true
  27987. }, null)]) : props.reverse ? createVNode(Fragment, null, [controlNode(), dividerNode()]) : undefined;
  27988. const hasPrependInner = slots['prepend-inner'] || prependInnerControl;
  27989. return createVNode(VTextField, mergeProps({
  27990. "ref": vTextFieldRef,
  27991. "modelValue": model.value,
  27992. "onUpdate:modelValue": $event => model.value = $event,
  27993. "onBeforeinput": onBeforeinput,
  27994. "onChange": clampModel,
  27995. "onKeydown": onKeydown,
  27996. "class": ['v-number-input', {
  27997. 'v-number-input--default': controlVariant.value === 'default',
  27998. 'v-number-input--hide-input': props.hideInput,
  27999. 'v-number-input--inset': props.inset,
  28000. 'v-number-input--reverse': props.reverse,
  28001. 'v-number-input--split': controlVariant.value === 'split',
  28002. 'v-number-input--stacked': controlVariant.value === 'stacked'
  28003. }, props.class]
  28004. }, textFieldProps, {
  28005. "style": props.style,
  28006. "inputmode": "decimal"
  28007. }), {
  28008. ...slots,
  28009. 'append-inner': hasAppendInner ? function () {
  28010. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  28011. args[_key] = arguments[_key];
  28012. }
  28013. return createVNode(Fragment, null, [slots['append-inner']?.(...args), appendInnerControl]);
  28014. } : undefined,
  28015. 'prepend-inner': hasPrependInner ? function () {
  28016. for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  28017. args[_key2] = arguments[_key2];
  28018. }
  28019. return createVNode(Fragment, null, [prependInnerControl, slots['prepend-inner']?.(...args)]);
  28020. } : undefined
  28021. });
  28022. });
  28023. return forwardRefs({}, vTextFieldRef);
  28024. }
  28025. });
  28026. // Types
  28027. const makeVStepperVerticalActionsProps = propsFactory({
  28028. ...makeVStepperActionsProps()
  28029. }, 'VStepperActions');
  28030. const VStepperVerticalActions = genericComponent()({
  28031. name: 'VStepperVerticalActions',
  28032. props: makeVStepperVerticalActionsProps(),
  28033. emits: {
  28034. 'click:prev': () => true,
  28035. 'click:next': () => true
  28036. },
  28037. setup(props, _ref) {
  28038. let {
  28039. emit,
  28040. slots
  28041. } = _ref;
  28042. function onClickPrev() {
  28043. emit('click:prev');
  28044. }
  28045. function onClickNext() {
  28046. emit('click:next');
  28047. }
  28048. useRender(() => {
  28049. const stepperActionsProps = VStepperActions.filterProps(props);
  28050. return createVNode(VStepperActions, mergeProps({
  28051. "class": "v-stepper-vertical-actions"
  28052. }, stepperActionsProps, {
  28053. "onClick:prev": onClickPrev,
  28054. "onClick:next": onClickNext
  28055. }), slots);
  28056. });
  28057. return {};
  28058. }
  28059. });
  28060. // Types
  28061. const makeVStepperVerticalItemProps = propsFactory({
  28062. hideActions: Boolean,
  28063. ...makeStepperItemProps(),
  28064. ...omit(makeVExpansionPanelProps({
  28065. expandIcon: '',
  28066. collapseIcon: ''
  28067. }), ['hideActions'])
  28068. }, 'VStepperVerticalItem');
  28069. const VStepperVerticalItem = genericComponent()({
  28070. name: 'VStepperVerticalItem',
  28071. props: makeVStepperVerticalItemProps(),
  28072. emits: {
  28073. 'click:next': () => true,
  28074. 'click:prev': () => true,
  28075. 'click:finish': () => true
  28076. },
  28077. setup(props, _ref) {
  28078. let {
  28079. emit,
  28080. slots
  28081. } = _ref;
  28082. const vExpansionPanelRef = ref();
  28083. const step = computed(() => !isNaN(parseInt(props.value)) ? Number(props.value) : props.value);
  28084. const groupItem = computed(() => vExpansionPanelRef.value?.groupItem);
  28085. const isSelected = computed(() => groupItem.value?.isSelected.value ?? false);
  28086. const isValid = computed(() => isSelected.value ? props.rules.every(handler => handler() === true) : null);
  28087. const canEdit = computed(() => !props.disabled && props.editable);
  28088. const hasError = computed(() => props.error || isSelected.value && !isValid.value);
  28089. const hasCompleted = computed(() => props.complete || props.rules.length > 0 && isValid.value === true);
  28090. const disabled = computed(() => {
  28091. if (props.disabled) return props.disabled;
  28092. if (groupItem.value?.isFirst.value) return 'prev';
  28093. return false;
  28094. });
  28095. const icon = computed(() => {
  28096. if (hasError.value) return props.errorIcon;
  28097. if (hasCompleted.value) return props.completeIcon;
  28098. if (groupItem.value?.isSelected.value && props.editable) return props.editIcon;
  28099. return props.icon;
  28100. });
  28101. const slotProps = computed(() => ({
  28102. canEdit: canEdit.value,
  28103. hasError: hasError.value,
  28104. hasCompleted: hasCompleted.value,
  28105. title: props.title,
  28106. subtitle: props.subtitle,
  28107. step: step.value,
  28108. value: props.value
  28109. }));
  28110. const actionProps = computed(() => ({
  28111. ...slotProps.value,
  28112. prev: onClickPrev,
  28113. next: onClickNext
  28114. }));
  28115. function onClickNext() {
  28116. emit('click:next');
  28117. if (groupItem.value?.isLast.value) return;
  28118. groupItem.value.group.next();
  28119. }
  28120. function onClickPrev() {
  28121. emit('click:prev');
  28122. groupItem.value.group.prev();
  28123. }
  28124. useRender(() => {
  28125. const hasColor = (hasCompleted.value || groupItem.value?.isSelected.value) && !hasError.value && !props.disabled;
  28126. const hasActions = !props.hideActions || !!slots.actions;
  28127. const expansionPanelProps = VExpansionPanel.filterProps(props);
  28128. return createVNode(VExpansionPanel, mergeProps({
  28129. "_as": "VStepperVerticalItem",
  28130. "ref": vExpansionPanelRef
  28131. }, expansionPanelProps, {
  28132. "class": ['v-stepper-vertical-item', {
  28133. 'v-stepper-vertical-item--complete': hasCompleted.value,
  28134. 'v-stepper-vertical-item--disabled': props.disabled,
  28135. 'v-stepper-vertical-item--editable': canEdit.value,
  28136. 'v-stepper-vertical-item--error': hasError.value
  28137. }, props.class],
  28138. "readonly": !props.editable,
  28139. "style": props.style,
  28140. "color": "",
  28141. "hide-actions": false,
  28142. "value": step.value
  28143. }), {
  28144. title: () => createVNode(Fragment, null, [createVNode(VAvatar, {
  28145. "key": "stepper-avatar",
  28146. "class": "v-stepper-vertical-item__avatar",
  28147. "color": hasColor ? props.color : undefined,
  28148. "size": 24,
  28149. "start": true
  28150. }, {
  28151. default: () => [slots.icon?.(slotProps.value) ?? (icon.value ? createVNode(VIcon, {
  28152. "icon": icon.value
  28153. }, null) : step.value)]
  28154. }), createVNode("div", null, [createVNode("div", {
  28155. "class": "v-stepper-vertical-item__title"
  28156. }, [slots.title?.(slotProps.value) ?? props.title]), createVNode("div", {
  28157. "class": "v-stepper-vertical-item__subtitle"
  28158. }, [slots.subtitle?.(slotProps.value) ?? props.subtitle])])]),
  28159. text: () => createVNode(Fragment, null, [slots.default?.(slotProps.value) ?? props.text, hasActions && createVNode(VDefaultsProvider, {
  28160. "defaults": {
  28161. VStepperVerticalActions: {
  28162. disabled: disabled.value,
  28163. finish: groupItem.value?.isLast.value
  28164. }
  28165. }
  28166. }, {
  28167. default: () => [slots.actions?.(actionProps.value) ?? createVNode(VStepperVerticalActions, {
  28168. "onClick:next": onClickNext,
  28169. "onClick:prev": onClickPrev
  28170. }, {
  28171. prev: slots.prev ? () => slots.prev?.(actionProps.value) : undefined,
  28172. next: slots.next ? () => slots.next?.(actionProps.value) : undefined
  28173. })]
  28174. })])
  28175. });
  28176. });
  28177. return {};
  28178. }
  28179. });
  28180. // Types
  28181. const makeVStepperVerticalProps = propsFactory({
  28182. prevText: {
  28183. type: String,
  28184. default: '$vuetify.stepper.prev'
  28185. },
  28186. nextText: {
  28187. type: String,
  28188. default: '$vuetify.stepper.next'
  28189. },
  28190. ...makeStepperProps(),
  28191. ...omit(makeVExpansionPanelsProps({
  28192. mandatory: 'force',
  28193. variant: 'accordion'
  28194. }), ['static'])
  28195. }, 'VStepperVertical');
  28196. const VStepperVertical = genericComponent()({
  28197. name: 'VStepperVertical',
  28198. props: makeVStepperVerticalProps(),
  28199. emits: {
  28200. 'update:modelValue': val => true
  28201. },
  28202. setup(props, _ref) {
  28203. let {
  28204. slots
  28205. } = _ref;
  28206. const vExpansionPanelsRef = ref();
  28207. const {
  28208. color,
  28209. eager,
  28210. editable,
  28211. prevText,
  28212. nextText,
  28213. hideActions
  28214. } = toRefs(props);
  28215. const model = useProxiedModel(props, 'modelValue');
  28216. const items = computed(() => props.items.map((item, index) => {
  28217. const title = getPropertyFromItem(item, props.itemTitle, item);
  28218. const value = getPropertyFromItem(item, props.itemValue, index + 1);
  28219. return {
  28220. title,
  28221. value,
  28222. raw: item
  28223. };
  28224. }));
  28225. provideDefaults({
  28226. VStepperVerticalItem: {
  28227. color,
  28228. eager,
  28229. editable,
  28230. prevText,
  28231. nextText,
  28232. hideActions,
  28233. static: true
  28234. },
  28235. VStepperActions: {
  28236. color
  28237. }
  28238. });
  28239. useRender(() => {
  28240. const expansionPanelProps = VExpansionPanels.filterProps(props);
  28241. return createVNode(VExpansionPanels, mergeProps(expansionPanelProps, {
  28242. "modelValue": model.value,
  28243. "onUpdate:modelValue": $event => model.value = $event,
  28244. "ref": vExpansionPanelsRef,
  28245. "class": ['v-stepper', {
  28246. 'v-stepper--alt-labels': props.altLabels,
  28247. 'v-stepper--flat': props.flat,
  28248. 'v-stepper--non-linear': props.nonLinear,
  28249. 'v-stepper--mobile': props.mobile
  28250. }, props.class],
  28251. "style": props.style
  28252. }), {
  28253. ...slots,
  28254. default: _ref2 => {
  28255. let {
  28256. prev,
  28257. next
  28258. } = _ref2;
  28259. return createVNode(Fragment, null, [items.value.map(_ref3 => {
  28260. let {
  28261. raw,
  28262. ...item
  28263. } = _ref3;
  28264. return createVNode(VStepperVerticalItem, item, {
  28265. ...slots,
  28266. default: slots[`item.${item.value}`]
  28267. });
  28268. }), slots.default?.({
  28269. prev,
  28270. next,
  28271. step: model.value
  28272. })]);
  28273. }
  28274. });
  28275. });
  28276. return {};
  28277. }
  28278. });
  28279. const VPullToRefresh = genericComponent()({
  28280. name: 'VPullToRefresh',
  28281. props: {
  28282. disabled: Boolean,
  28283. pullDownThreshold: {
  28284. type: Number,
  28285. default: 64
  28286. }
  28287. },
  28288. emits: {
  28289. load: options => true
  28290. },
  28291. setup(props, _ref) {
  28292. let {
  28293. slots,
  28294. emit
  28295. } = _ref;
  28296. let touchstartY = 0;
  28297. let scrollParents = [];
  28298. const touchDiff = shallowRef(0);
  28299. const containerRef = ref();
  28300. const refreshing = shallowRef(false);
  28301. const goingUp = shallowRef(false);
  28302. const touching = shallowRef(false);
  28303. const canRefresh = computed(() => touchDiff.value >= props.pullDownThreshold && !refreshing.value);
  28304. const topOffset = computed(() => clamp(touchDiff.value, 0, props.pullDownThreshold));
  28305. function onTouchstart(e) {
  28306. if (refreshing.value || props.disabled) return;
  28307. touching.value = true;
  28308. touchstartY = 'clientY' in e ? e.clientY : e.touches[0].clientY;
  28309. }
  28310. function onTouchmove(e) {
  28311. if (refreshing.value || !touching.value || props.disabled) return;
  28312. const touchY = 'clientY' in e ? e.clientY : e.touches[0].clientY;
  28313. if (scrollParents.length && !scrollParents[0].scrollTop) {
  28314. touchDiff.value = touchY - touchstartY;
  28315. }
  28316. }
  28317. function onTouchend(e) {
  28318. if (refreshing.value || props.disabled) return;
  28319. touching.value = false;
  28320. if (canRefresh.value) {
  28321. function done() {
  28322. if (!refreshing.value) return;
  28323. touchDiff.value = 0;
  28324. refreshing.value = false;
  28325. }
  28326. emit('load', {
  28327. done
  28328. });
  28329. refreshing.value = true;
  28330. } else {
  28331. touchDiff.value = 0;
  28332. }
  28333. }
  28334. onMounted(() => {
  28335. scrollParents = getScrollParents(containerRef.value);
  28336. });
  28337. watch([topOffset, refreshing], () => {
  28338. if (scrollParents.length) {
  28339. const stopScrolling = topOffset.value && !refreshing.value;
  28340. scrollParents.forEach(p => p.style.overflow = stopScrolling ? 'hidden' : 'auto');
  28341. }
  28342. });
  28343. watch(topOffset, (newVal, oldVal) => {
  28344. goingUp.value = newVal < oldVal;
  28345. });
  28346. useRender(() => {
  28347. return createVNode("div", {
  28348. "class": ['v-pull-to-refresh'],
  28349. "onTouchstart": onTouchstart,
  28350. "onTouchmove": onTouchmove,
  28351. "onTouchend": onTouchend,
  28352. "onMousedown": onTouchstart,
  28353. "onMouseup": onTouchend,
  28354. "onMouseleave": onTouchend,
  28355. "onMousemove": onTouchmove,
  28356. "ref": containerRef
  28357. }, [createVNode("div", {
  28358. "class": ['v-pull-to-refresh__pull-down', {
  28359. 'v-pull-to-refresh__pull-down--touching': touching.value
  28360. }],
  28361. "style": {
  28362. top: convertToUnit(-1 * props.pullDownThreshold + topOffset.value),
  28363. height: convertToUnit(props.pullDownThreshold)
  28364. }
  28365. }, [slots.pullDownPanel ? slots.pullDownPanel({
  28366. canRefresh: canRefresh.value,
  28367. goingUp: goingUp.value,
  28368. refreshing: refreshing.value
  28369. }) : createVNode("div", {
  28370. "class": ['v-pull-to-refresh__pull-down-default']
  28371. }, [refreshing.value ? createVNode(VProgressCircular, {
  28372. "indeterminate": true,
  28373. "active": false
  28374. }, null) : createVNode(VIcon, {
  28375. "icon": canRefresh.value || goingUp.value ? '$sortAsc' : '$sortDesc'
  28376. }, null)])]), createVNode("div", {
  28377. "class": ['v-pull-to-refresh__scroll-container', {
  28378. 'v-pull-to-refresh__scroll-container--touching': touching.value
  28379. }],
  28380. "style": {
  28381. top: convertToUnit(topOffset.value)
  28382. }
  28383. }, [slots.default?.()])]);
  28384. });
  28385. }
  28386. });
  28387. // Types
  28388. const makeVSnackbarQueueProps = propsFactory({
  28389. // TODO: Port this to Snackbar on dev
  28390. closable: [Boolean, String],
  28391. closeText: {
  28392. type: String,
  28393. default: '$vuetify.dismiss'
  28394. },
  28395. modelValue: {
  28396. type: Array,
  28397. default: () => []
  28398. },
  28399. ...omit(makeVSnackbarProps(), ['modelValue'])
  28400. }, 'VSnackbarQueue');
  28401. const VSnackbarQueue = genericComponent()({
  28402. name: 'VSnackbarQueue',
  28403. props: makeVSnackbarQueueProps(),
  28404. emits: {
  28405. 'update:modelValue': val => true
  28406. },
  28407. setup(props, _ref) {
  28408. let {
  28409. emit,
  28410. slots
  28411. } = _ref;
  28412. const {
  28413. t
  28414. } = useLocale();
  28415. const isActive = shallowRef(false);
  28416. const isVisible = shallowRef(false);
  28417. const current = shallowRef();
  28418. watch(() => props.modelValue.length, (val, oldVal) => {
  28419. if (!isVisible.value && val > oldVal) {
  28420. showNext();
  28421. }
  28422. });
  28423. watch(isActive, val => {
  28424. if (val) isVisible.value = true;
  28425. });
  28426. function onAfterLeave() {
  28427. if (props.modelValue.length) {
  28428. showNext();
  28429. } else {
  28430. current.value = undefined;
  28431. isVisible.value = false;
  28432. }
  28433. }
  28434. function showNext() {
  28435. const [next, ...rest] = props.modelValue;
  28436. emit('update:modelValue', rest);
  28437. current.value = typeof next === 'string' ? {
  28438. text: next
  28439. } : next;
  28440. nextTick(() => {
  28441. isActive.value = true;
  28442. });
  28443. }
  28444. function onClickClose() {
  28445. isActive.value = false;
  28446. }
  28447. const btnProps = computed(() => ({
  28448. color: typeof props.closable === 'string' ? props.closable : undefined,
  28449. text: t(props.closeText)
  28450. }));
  28451. useRender(() => {
  28452. const hasActions = !!(props.closable || slots.actions);
  28453. const {
  28454. modelValue: _,
  28455. ...snackbarProps
  28456. } = VSnackbar.filterProps(props);
  28457. return createVNode(Fragment, null, [isVisible.value && !!current.value && (slots.default ? createVNode(VDefaultsProvider, {
  28458. "defaults": {
  28459. VSnackbar: current.value
  28460. }
  28461. }, {
  28462. default: () => [slots.default({
  28463. item: current.value
  28464. })]
  28465. }) : createVNode(VSnackbar, mergeProps(snackbarProps, current.value, {
  28466. "modelValue": isActive.value,
  28467. "onUpdate:modelValue": $event => isActive.value = $event,
  28468. "onAfterLeave": onAfterLeave
  28469. }), {
  28470. text: slots.text ? () => slots.text?.({
  28471. item: current.value
  28472. }) : undefined,
  28473. actions: hasActions ? () => createVNode(Fragment, null, [!slots.actions ? createVNode(VBtn, mergeProps(btnProps.value, {
  28474. "onClick": onClickClose
  28475. }), null) : createVNode(VDefaultsProvider, {
  28476. "defaults": {
  28477. VBtn: btnProps.value
  28478. }
  28479. }, {
  28480. default: () => [slots.actions({
  28481. item: current.value,
  28482. props: {
  28483. onClick: onClickClose
  28484. }
  28485. })]
  28486. })]) : undefined
  28487. }))]);
  28488. });
  28489. }
  28490. });
  28491. function pad(n) {
  28492. let length = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2;
  28493. return String(n).padStart(length, '0');
  28494. }
  28495. // Types
  28496. const makeVTimePickerClockProps = propsFactory({
  28497. allowedValues: Function,
  28498. ampm: Boolean,
  28499. color: String,
  28500. disabled: Boolean,
  28501. displayedValue: null,
  28502. double: Boolean,
  28503. format: {
  28504. type: Function,
  28505. default: val => val
  28506. },
  28507. max: {
  28508. type: Number,
  28509. required: true
  28510. },
  28511. min: {
  28512. type: Number,
  28513. required: true
  28514. },
  28515. scrollable: Boolean,
  28516. readonly: Boolean,
  28517. rotate: {
  28518. type: Number,
  28519. default: 0
  28520. },
  28521. step: {
  28522. type: Number,
  28523. default: 1
  28524. },
  28525. modelValue: {
  28526. type: Number
  28527. }
  28528. }, 'VTimePickerClock');
  28529. const VTimePickerClock = genericComponent()({
  28530. name: 'VTimePickerClock',
  28531. props: makeVTimePickerClockProps(),
  28532. emits: {
  28533. change: val => true,
  28534. input: val => true
  28535. },
  28536. setup(props, _ref) {
  28537. let {
  28538. emit
  28539. } = _ref;
  28540. const clockRef = ref(null);
  28541. const innerClockRef = ref(null);
  28542. const inputValue = ref(undefined);
  28543. const isDragging = ref(false);
  28544. const valueOnMouseDown = ref(null);
  28545. const valueOnMouseUp = ref(null);
  28546. const {
  28547. textColorClasses,
  28548. textColorStyles
  28549. } = useTextColor(toRef(props, 'color'));
  28550. const {
  28551. backgroundColorClasses,
  28552. backgroundColorStyles
  28553. } = useBackgroundColor(toRef(props, 'color'));
  28554. const count = computed(() => props.max - props.min + 1);
  28555. const roundCount = computed(() => props.double ? count.value / 2 : count.value);
  28556. const degreesPerUnit = computed(() => 360 / roundCount.value);
  28557. const degrees = computed(() => degreesPerUnit.value * Math.PI / 180);
  28558. const displayedValue = computed(() => props.modelValue == null ? props.min : props.modelValue);
  28559. const innerRadiusScale = computed(() => 0.62);
  28560. const genChildren = computed(() => {
  28561. const children = [];
  28562. for (let value = props.min; value <= props.max; value = value + props.step) {
  28563. children.push(value);
  28564. }
  28565. return children;
  28566. });
  28567. watch(() => props.modelValue, val => {
  28568. inputValue.value = val;
  28569. });
  28570. function update(value) {
  28571. if (inputValue.value !== value) {
  28572. inputValue.value = value;
  28573. }
  28574. emit('input', value);
  28575. }
  28576. function isAllowed(value) {
  28577. return !props.allowedValues || props.allowedValues(value);
  28578. }
  28579. function wheel(e) {
  28580. if (!props.scrollable || props.disabled) return;
  28581. e.preventDefault();
  28582. const delta = Math.sign(-e.deltaY || 1);
  28583. let value = displayedValue.value;
  28584. do {
  28585. value = value + delta;
  28586. value = (value - props.min + count.value) % count.value + props.min;
  28587. } while (!isAllowed(value) && value !== displayedValue.value);
  28588. if (value !== props.displayedValue) {
  28589. update(value);
  28590. }
  28591. }
  28592. function isInner(value) {
  28593. return props.double && value - props.min >= roundCount.value;
  28594. }
  28595. function handScale(value) {
  28596. return isInner(value) ? innerRadiusScale.value : 1;
  28597. }
  28598. function getPosition(value) {
  28599. const rotateRadians = props.rotate * Math.PI / 180;
  28600. return {
  28601. x: Math.sin((value - props.min) * degrees.value + rotateRadians) * handScale(value),
  28602. y: -Math.cos((value - props.min) * degrees.value + rotateRadians) * handScale(value)
  28603. };
  28604. }
  28605. function angleToValue(angle, insideClick) {
  28606. const value = (Math.round(angle / degreesPerUnit.value) + (insideClick ? roundCount.value : 0)) % count.value + props.min;
  28607. // Necessary to fix edge case when selecting left part of the value(s) at 12 o'clock
  28608. if (angle < 360 - degreesPerUnit.value / 2) return value;
  28609. return insideClick ? props.max - roundCount.value + 1 : props.min;
  28610. }
  28611. function getTransform(i) {
  28612. const {
  28613. x,
  28614. y
  28615. } = getPosition(i);
  28616. return {
  28617. left: `${50 + x * 50}%`,
  28618. top: `${50 + y * 50}%`
  28619. };
  28620. }
  28621. function euclidean(p0, p1) {
  28622. const dx = p1.x - p0.x;
  28623. const dy = p1.y - p0.y;
  28624. return Math.sqrt(dx * dx + dy * dy);
  28625. }
  28626. function angle(center, p1) {
  28627. const value = 2 * Math.atan2(p1.y - center.y - euclidean(center, p1), p1.x - center.x);
  28628. return Math.abs(value * 180 / Math.PI);
  28629. }
  28630. function setMouseDownValue(value) {
  28631. if (valueOnMouseDown.value === null) {
  28632. valueOnMouseDown.value = value;
  28633. }
  28634. valueOnMouseUp.value = value;
  28635. update(value);
  28636. }
  28637. function onDragMove(e) {
  28638. e.preventDefault();
  28639. if (!isDragging.value && e.type !== 'click' || !clockRef.value) return;
  28640. const {
  28641. width,
  28642. top,
  28643. left
  28644. } = clockRef.value?.getBoundingClientRect();
  28645. const {
  28646. width: innerWidth
  28647. } = innerClockRef.value?.getBoundingClientRect() ?? {
  28648. width: 0
  28649. };
  28650. const {
  28651. clientX,
  28652. clientY
  28653. } = 'touches' in e ? e.touches[0] : e;
  28654. const center = {
  28655. x: width / 2,
  28656. y: -width / 2
  28657. };
  28658. const coords = {
  28659. x: clientX - left,
  28660. y: top - clientY
  28661. };
  28662. const handAngle = Math.round(angle(center, coords) - props.rotate + 360) % 360;
  28663. const insideClick = props.double && euclidean(center, coords) < (innerWidth + innerWidth * innerRadiusScale.value) / 4;
  28664. const checksCount = Math.ceil(15 / degreesPerUnit.value);
  28665. let value;
  28666. for (let i = 0; i < checksCount; i++) {
  28667. value = angleToValue(handAngle + i * degreesPerUnit.value, insideClick);
  28668. if (isAllowed(value)) return setMouseDownValue(value);
  28669. value = angleToValue(handAngle - i * degreesPerUnit.value, insideClick);
  28670. if (isAllowed(value)) return setMouseDownValue(value);
  28671. }
  28672. }
  28673. function onMouseDown(e) {
  28674. if (props.disabled) return;
  28675. e.preventDefault();
  28676. window.addEventListener('mousemove', onDragMove);
  28677. window.addEventListener('touchmove', onDragMove);
  28678. window.addEventListener('mouseup', onMouseUp);
  28679. window.addEventListener('touchend', onMouseUp);
  28680. valueOnMouseDown.value = null;
  28681. valueOnMouseUp.value = null;
  28682. isDragging.value = true;
  28683. onDragMove(e);
  28684. }
  28685. function onMouseUp(e) {
  28686. e.stopPropagation();
  28687. window.removeEventListener('mousemove', onDragMove);
  28688. window.removeEventListener('touchmove', onDragMove);
  28689. window.removeEventListener('mouseup', onMouseUp);
  28690. window.removeEventListener('touchend', onMouseUp);
  28691. isDragging.value = false;
  28692. if (valueOnMouseUp.value !== null && isAllowed(valueOnMouseUp.value)) {
  28693. emit('change', valueOnMouseUp.value);
  28694. }
  28695. }
  28696. useRender(() => {
  28697. return createVNode("div", {
  28698. "class": [{
  28699. 'v-time-picker-clock': true,
  28700. 'v-time-picker-clock--indeterminate': props.modelValue == null,
  28701. 'v-time-picker-clock--readonly': props.readonly
  28702. }],
  28703. "onMousedown": onMouseDown,
  28704. "onTouchstart": onMouseDown,
  28705. "onWheel": wheel,
  28706. "ref": clockRef
  28707. }, [createVNode("div", {
  28708. "class": "v-time-picker-clock__inner",
  28709. "ref": innerClockRef
  28710. }, [createVNode("div", {
  28711. "class": [{
  28712. 'v-time-picker-clock__hand': true,
  28713. 'v-time-picker-clock__hand--inner': isInner(props.modelValue)
  28714. }, textColorClasses.value],
  28715. "style": [{
  28716. transform: `rotate(${props.rotate + degreesPerUnit.value * (displayedValue.value - props.min)}deg) scaleY(${handScale(displayedValue.value)})`
  28717. }, textColorStyles.value]
  28718. }, null), genChildren.value.map(value => {
  28719. const isActive = value === displayedValue.value;
  28720. return createVNode("div", {
  28721. "class": [{
  28722. 'v-time-picker-clock__item': true,
  28723. 'v-time-picker-clock__item--active': isActive,
  28724. 'v-time-picker-clock__item--disabled': props.disabled || !isAllowed(value)
  28725. }, isActive && backgroundColorClasses.value],
  28726. "style": [getTransform(value), isActive && backgroundColorStyles.value]
  28727. }, [createVNode("span", null, [props.format(value)])]);
  28728. })])]);
  28729. });
  28730. }
  28731. });
  28732. // @ts-nocheck
  28733. /* eslint-disable */
  28734. var SelectingTimes = /*#__PURE__*/function (SelectingTimes) {
  28735. SelectingTimes[SelectingTimes["Hour"] = 1] = "Hour";
  28736. SelectingTimes[SelectingTimes["Minute"] = 2] = "Minute";
  28737. SelectingTimes[SelectingTimes["Second"] = 3] = "Second";
  28738. return SelectingTimes;
  28739. }(SelectingTimes || {});
  28740. const makeVTimePickerControlsProps = propsFactory({
  28741. ampm: Boolean,
  28742. ampmInTitle: Boolean,
  28743. ampmReadonly: Boolean,
  28744. color: String,
  28745. disabled: Boolean,
  28746. hour: Number,
  28747. minute: Number,
  28748. second: Number,
  28749. period: String,
  28750. readonly: Boolean,
  28751. useSeconds: Boolean,
  28752. selecting: Number,
  28753. value: Number
  28754. }, 'VTimePickerControls');
  28755. const VTimePickerControls = genericComponent()({
  28756. name: 'VTimePickerControls',
  28757. props: makeVTimePickerControlsProps(),
  28758. emits: {
  28759. 'update:period': data => true,
  28760. 'update:selecting': data => true
  28761. },
  28762. setup(props, _ref) {
  28763. let {
  28764. emit,
  28765. slots
  28766. } = _ref;
  28767. const {
  28768. t
  28769. } = useLocale();
  28770. useRender(() => {
  28771. let hour = props.hour;
  28772. if (props.ampm) {
  28773. hour = hour ? (hour - 1) % 12 + 1 : 12;
  28774. }
  28775. return createVNode("div", {
  28776. "class": "v-time-picker-controls"
  28777. }, [createVNode("div", {
  28778. "class": {
  28779. 'v-time-picker-controls__time': true,
  28780. 'v-time-picker-controls__time--with-seconds': props.useSeconds
  28781. }
  28782. }, [createVNode(VBtn, {
  28783. "active": props.selecting === 1,
  28784. "color": props.selecting === 1 ? props.color : undefined,
  28785. "disabled": props.disabled,
  28786. "variant": "tonal",
  28787. "class": {
  28788. 'v-time-picker-controls__time__btn': true,
  28789. 'v-time-picker-controls__time--with-ampm__btn': props.ampm,
  28790. 'v-time-picker-controls__time--with-seconds__btn': props.useSeconds
  28791. },
  28792. "text": props.hour == null ? '--' : pad(`${hour}`),
  28793. "onClick": () => emit('update:selecting', SelectingTimes.Hour)
  28794. }, null), createVNode("span", {
  28795. "class": ['v-time-picker-controls__time__separator', {
  28796. 'v-time-picker-controls--with-seconds__time__separator': props.useSeconds
  28797. }]
  28798. }, [createTextVNode(":")]), createVNode(VBtn, {
  28799. "active": props.selecting === 2,
  28800. "color": props.selecting === 2 ? props.color : undefined,
  28801. "class": {
  28802. 'v-time-picker-controls__time__btn': true,
  28803. 'v-time-picker-controls__time__btn__active': props.selecting === 2,
  28804. 'v-time-picker-controls__time--with-ampm__btn': props.ampm,
  28805. 'v-time-picker-controls__time--with-seconds__btn': props.useSeconds
  28806. },
  28807. "disabled": props.disabled,
  28808. "variant": "tonal",
  28809. "text": props.minute == null ? '--' : pad(props.minute),
  28810. "onClick": () => emit('update:selecting', SelectingTimes.Minute)
  28811. }, null), props.useSeconds && createVNode("span", {
  28812. "class": ['v-time-picker-controls__time__separator', {
  28813. 'v-time-picker-controls--with-seconds__time__separator': props.useSeconds
  28814. }],
  28815. "key": "secondsDivider"
  28816. }, [createTextVNode(":")]), props.useSeconds && createVNode(VBtn, {
  28817. "key": "secondsVal",
  28818. "variant": "tonal",
  28819. "onClick": () => emit('update:selecting', SelectingTimes.Second),
  28820. "class": {
  28821. 'v-time-picker-controls__time__btn': true,
  28822. 'v-time-picker-controls__time__btn__active': props.selecting === 3,
  28823. 'v-time-picker-controls__time--with-seconds__btn': props.useSeconds
  28824. },
  28825. "disabled": props.disabled,
  28826. "text": props.second == null ? '--' : pad(props.second)
  28827. }, null), props.ampm && props.ampmInTitle && createVNode("div", {
  28828. "class": ['v-time-picker-controls__ampm', {
  28829. 'v-time-picker-controls__ampm--readonly': props.ampmReadonly
  28830. }]
  28831. }, [createVNode(VBtn, {
  28832. "active": props.period === 'am',
  28833. "color": props.period === 'am' ? props.color : undefined,
  28834. "class": {
  28835. 'v-time-picker-controls__ampm__am': true,
  28836. 'v-time-picker-controls__ampm__btn': true,
  28837. 'v-time-picker-controls__ampm__btn__active': props.period === 'am'
  28838. },
  28839. "disabled": props.disabled,
  28840. "text": t('$vuetify.timePicker.am'),
  28841. "variant": props.disabled && props.period === 'am' ? 'elevated' : 'tonal',
  28842. "onClick": () => props.period !== 'am' ? emit('update:period', 'am') : null
  28843. }, null), createVNode(VBtn, {
  28844. "active": props.period === 'pm',
  28845. "color": props.period === 'pm' ? props.color : undefined,
  28846. "class": {
  28847. 'v-time-picker-controls__ampm__pm': true,
  28848. 'v-time-picker-controls__ampm__btn': true,
  28849. 'v-time-picker-controls__ampm__btn__active': props.period === 'pm'
  28850. },
  28851. "disabled": props.disabled,
  28852. "text": t('$vuetify.timePicker.pm'),
  28853. "variant": props.disabled && props.period === 'pm' ? 'elevated' : 'tonal',
  28854. "onClick": () => props.period !== 'pm' ? emit('update:period', 'pm') : null
  28855. }, null)])])]);
  28856. });
  28857. return {};
  28858. }
  28859. });
  28860. // Types
  28861. const rangeHours24 = createRange(24);
  28862. const rangeHours12am = createRange(12);
  28863. const rangeHours12pm = rangeHours12am.map(v => v + 12);
  28864. const range60 = createRange(60);
  28865. const selectingNames = {
  28866. 1: 'hour',
  28867. 2: 'minute',
  28868. 3: 'second'
  28869. };
  28870. const makeVTimePickerProps = propsFactory({
  28871. allowedHours: [Function, Array],
  28872. allowedMinutes: [Function, Array],
  28873. allowedSeconds: [Function, Array],
  28874. ampmInTitle: Boolean,
  28875. disabled: Boolean,
  28876. format: {
  28877. type: String,
  28878. default: 'ampm'
  28879. },
  28880. max: String,
  28881. min: String,
  28882. modelValue: null,
  28883. readonly: Boolean,
  28884. scrollable: Boolean,
  28885. useSeconds: Boolean,
  28886. ...omit(makeVPickerProps({
  28887. title: '$vuetify.timePicker.title'
  28888. }), ['landscape'])
  28889. }, 'VTimePicker');
  28890. const VTimePicker = genericComponent()({
  28891. name: 'VTimePicker',
  28892. props: makeVTimePickerProps(),
  28893. emits: {
  28894. 'update:hour': val => true,
  28895. 'update:minute': val => true,
  28896. 'update:period': val => true,
  28897. 'update:second': val => true,
  28898. 'update:modelValue': val => true
  28899. },
  28900. setup(props, _ref) {
  28901. let {
  28902. emit,
  28903. slots
  28904. } = _ref;
  28905. const {
  28906. t
  28907. } = useLocale();
  28908. const inputHour = ref(null);
  28909. const inputMinute = ref(null);
  28910. const inputSecond = ref(null);
  28911. const lazyInputHour = ref(null);
  28912. const lazyInputMinute = ref(null);
  28913. const lazyInputSecond = ref(null);
  28914. const period = ref('am');
  28915. const selecting = ref(SelectingTimes.Hour);
  28916. const controlsRef = ref(null);
  28917. const clockRef = ref(null);
  28918. const isAllowedHourCb = computed(() => {
  28919. let cb;
  28920. if (props.allowedHours instanceof Array) {
  28921. cb = val => props.allowedHours.includes(val);
  28922. } else {
  28923. cb = props.allowedHours;
  28924. }
  28925. if (!props.min && !props.max) return cb;
  28926. const minHour = props.min ? Number(props.min.split(':')[0]) : 0;
  28927. const maxHour = props.max ? Number(props.max.split(':')[0]) : 23;
  28928. return val => {
  28929. return val >= minHour * 1 && val <= maxHour * 1 && (!cb || cb(val));
  28930. };
  28931. });
  28932. const isAllowedMinuteCb = computed(() => {
  28933. let cb;
  28934. const isHourAllowed = !isAllowedHourCb.value || inputHour.value === null || isAllowedHourCb.value(inputHour.value);
  28935. if (props.allowedMinutes instanceof Array) {
  28936. cb = val => props.allowedMinutes.includes(val);
  28937. } else {
  28938. cb = props.allowedMinutes;
  28939. }
  28940. if (!props.min && !props.max) {
  28941. return isHourAllowed ? cb : () => false;
  28942. }
  28943. const [minHour, minMinute] = props.min ? props.min.split(':').map(Number) : [0, 0];
  28944. const [maxHour, maxMinute] = props.max ? props.max.split(':').map(Number) : [23, 59];
  28945. const minTime = minHour * 60 + minMinute * 1;
  28946. const maxTime = maxHour * 60 + maxMinute * 1;
  28947. return val => {
  28948. const time = 60 * inputHour.value + val;
  28949. return time >= minTime && time <= maxTime && isHourAllowed && (!cb || cb(val));
  28950. };
  28951. });
  28952. const isAllowedSecondCb = computed(() => {
  28953. let cb;
  28954. const isHourAllowed = !isAllowedHourCb.value || inputHour.value === null || isAllowedHourCb.value(inputHour.value);
  28955. const isMinuteAllowed = isHourAllowed && (!isAllowedMinuteCb.value || inputMinute.value === null || isAllowedMinuteCb.value(inputMinute.value));
  28956. if (props.allowedSeconds instanceof Array) {
  28957. cb = val => props.allowedSeconds.includes(val);
  28958. } else {
  28959. cb = props.allowedSeconds;
  28960. }
  28961. if (!props.min && !props.max) {
  28962. return isMinuteAllowed ? cb : () => false;
  28963. }
  28964. const [minHour, minMinute, minSecond] = props.min ? props.min.split(':').map(Number) : [0, 0, 0];
  28965. const [maxHour, maxMinute, maxSecond] = props.max ? props.max.split(':').map(Number) : [23, 59, 59];
  28966. const minTime = minHour * 3600 + minMinute * 60 + (minSecond || 0) * 1;
  28967. const maxTime = maxHour * 3600 + maxMinute * 60 + (maxSecond || 0) * 1;
  28968. return val => {
  28969. const time = 3600 * inputHour.value + 60 * inputMinute.value + val;
  28970. return time >= minTime && time <= maxTime && isMinuteAllowed && (!cb || cb(val));
  28971. };
  28972. });
  28973. const isAmPm = computed(() => {
  28974. return props.format === 'ampm';
  28975. });
  28976. watch(() => props.modelValue, val => setInputData(val));
  28977. onMounted(() => {
  28978. setInputData(props.modelValue);
  28979. });
  28980. function genValue() {
  28981. if (inputHour.value != null && inputMinute.value != null && (!props.useSeconds || inputSecond.value != null)) {
  28982. return `${pad(inputHour.value)}:${pad(inputMinute.value)}` + (props.useSeconds ? `:${pad(inputSecond.value)}` : '');
  28983. }
  28984. return null;
  28985. }
  28986. function emitValue() {
  28987. const value = genValue();
  28988. if (value !== null) emit('update:modelValue', value);
  28989. }
  28990. function convert24to12(hour) {
  28991. return hour ? (hour - 1) % 12 + 1 : 12;
  28992. }
  28993. function convert12to24(hour, period) {
  28994. return hour % 12 + (period === 'pm' ? 12 : 0);
  28995. }
  28996. function setInputData(value) {
  28997. if (value == null || value === '') {
  28998. inputHour.value = null;
  28999. inputMinute.value = null;
  29000. inputSecond.value = null;
  29001. } else if (value instanceof Date) {
  29002. inputHour.value = value.getHours();
  29003. inputMinute.value = value.getMinutes();
  29004. inputSecond.value = value.getSeconds();
  29005. } else {
  29006. const [hour,, minute,, second, period] = value.trim().toLowerCase().match(/^(\d+):(\d+)(:(\d+))?([ap]m)?$/) || new Array(6);
  29007. inputHour.value = period ? convert12to24(parseInt(hour, 10), period) : parseInt(hour, 10);
  29008. inputMinute.value = parseInt(minute, 10);
  29009. inputSecond.value = parseInt(second || 0, 10);
  29010. }
  29011. period.value = inputHour.value == null || inputHour.value < 12 ? 'am' : 'pm';
  29012. }
  29013. function firstAllowed(type, value) {
  29014. const allowedFn = type === 'hour' ? isAllowedHourCb.value : type === 'minute' ? isAllowedMinuteCb.value : isAllowedSecondCb.value;
  29015. if (!allowedFn) return value;
  29016. // TODO: clean up (Note from V2 code)
  29017. const range = type === 'minute' ? range60 : type === 'second' ? range60 : isAmPm.value ? value < 12 ? rangeHours12am : rangeHours12pm : rangeHours24;
  29018. const first = range.find(v => allowedFn((v + value) % range.length + range[0]));
  29019. return ((first || 0) + value) % range.length + range[0];
  29020. }
  29021. function setPeriod(val) {
  29022. period.value = val;
  29023. if (inputHour.value != null) {
  29024. const newHour = inputHour.value + (period.value === 'am' ? -12 : 12);
  29025. inputHour.value = firstAllowed('hour', newHour);
  29026. }
  29027. emit('update:period', val);
  29028. emitValue();
  29029. return true;
  29030. }
  29031. function onInput(value) {
  29032. if (selecting.value === SelectingTimes.Hour) {
  29033. inputHour.value = isAmPm.value ? convert12to24(value, period.value) : value;
  29034. } else if (selecting.value === SelectingTimes.Minute) {
  29035. inputMinute.value = value;
  29036. } else {
  29037. inputSecond.value = value;
  29038. }
  29039. }
  29040. function onChange(value) {
  29041. switch (selectingNames[selecting.value]) {
  29042. case 'hour':
  29043. emit('update:hour', value);
  29044. break;
  29045. case 'minute':
  29046. emit('update:minute', value);
  29047. break;
  29048. case 'second':
  29049. emit('update:second', value);
  29050. break;
  29051. }
  29052. const emitChange = selecting.value === (props.useSeconds ? SelectingTimes.Second : SelectingTimes.Minute);
  29053. if (selecting.value === SelectingTimes.Hour) {
  29054. selecting.value = SelectingTimes.Minute;
  29055. } else if (props.useSeconds && selecting.value === SelectingTimes.Minute) {
  29056. selecting.value = SelectingTimes.Second;
  29057. }
  29058. if (inputHour.value === lazyInputHour.value && inputMinute.value === lazyInputMinute.value && (!props.useSeconds || inputSecond.value === lazyInputSecond.value)) return;
  29059. const time = genValue();
  29060. if (time === null) return;
  29061. lazyInputHour.value = inputHour.value;
  29062. lazyInputMinute.value = inputMinute.value;
  29063. props.useSeconds && (lazyInputSecond.value = inputSecond.value);
  29064. emitChange && emitValue();
  29065. }
  29066. useRender(() => {
  29067. const pickerProps = VPicker.filterProps(props);
  29068. const timePickerControlsProps = VTimePickerControls.filterProps(props);
  29069. const timePickerClockProps = VTimePickerClock.filterProps(omit(props, ['format', 'modelValue', 'min', 'max']));
  29070. return createVNode(VPicker, mergeProps(pickerProps, {
  29071. "color": undefined,
  29072. "class": ['v-time-picker', props.class],
  29073. "style": props.style
  29074. }), {
  29075. title: () => slots.title?.() ?? createVNode("div", {
  29076. "class": "v-time-picker__title"
  29077. }, [t(props.title)]),
  29078. header: () => createVNode(VTimePickerControls, mergeProps(timePickerControlsProps, {
  29079. "ampm": isAmPm.value || props.ampmInTitle,
  29080. "ampmReadonly": isAmPm.value && !props.ampmInTitle,
  29081. "hour": inputHour.value,
  29082. "minute": inputMinute.value,
  29083. "period": period.value,
  29084. "second": inputSecond.value,
  29085. "selecting": selecting.value,
  29086. "onUpdate:period": val => setPeriod(val),
  29087. "onUpdate:selecting": value => selecting.value = value,
  29088. "ref": controlsRef
  29089. }), null),
  29090. default: () => createVNode(VTimePickerClock, mergeProps(timePickerClockProps, {
  29091. "allowedValues": selecting.value === SelectingTimes.Hour ? isAllowedHourCb.value : selecting.value === SelectingTimes.Minute ? isAllowedMinuteCb.value : isAllowedSecondCb.value,
  29092. "double": selecting.value === SelectingTimes.Hour && !isAmPm.value,
  29093. "format": selecting.value === SelectingTimes.Hour ? isAmPm.value ? convert24to12 : val => val : val => pad(val, 2),
  29094. "max": selecting.value === SelectingTimes.Hour ? isAmPm.value && period.value === 'am' ? 11 : 23 : 59,
  29095. "min": selecting.value === SelectingTimes.Hour && isAmPm.value && period.value === 'pm' ? 12 : 0,
  29096. "size": 20,
  29097. "step": selecting.value === SelectingTimes.Hour ? 1 : 5,
  29098. "modelValue": selecting.value === SelectingTimes.Hour ? inputHour.value : selecting.value === SelectingTimes.Minute ? inputMinute.value : inputSecond.value,
  29099. "onChange": onChange,
  29100. "onInput": onInput,
  29101. "ref": clockRef
  29102. }), null),
  29103. actions: slots.actions
  29104. });
  29105. });
  29106. }
  29107. });
  29108. // Types
  29109. const makeVTreeviewGroupProps = propsFactory({
  29110. ...omit(makeVListGroupProps({
  29111. collapseIcon: '$treeviewCollapse',
  29112. expandIcon: '$treeviewExpand'
  29113. }), ['subgroup'])
  29114. }, 'VTreeviewGroup');
  29115. const VTreeviewGroup = genericComponent()({
  29116. name: 'VTreeviewGroup',
  29117. props: makeVTreeviewGroupProps(),
  29118. setup(props, _ref) {
  29119. let {
  29120. slots
  29121. } = _ref;
  29122. const vListGroupRef = ref();
  29123. const toggleIcon = computed(() => vListGroupRef.value?.isOpen ? props.collapseIcon : props.expandIcon);
  29124. const activatorDefaults = computed(() => ({
  29125. VTreeviewItem: {
  29126. prependIcon: undefined,
  29127. appendIcon: undefined,
  29128. active: vListGroupRef.value?.isOpen,
  29129. toggleIcon: toggleIcon.value
  29130. }
  29131. }));
  29132. useRender(() => {
  29133. const listGroupProps = VListGroup.filterProps(props);
  29134. return createVNode(VListGroup, mergeProps(listGroupProps, {
  29135. "ref": vListGroupRef,
  29136. "class": ['v-treeview-group', props.class],
  29137. "subgroup": true
  29138. }), {
  29139. ...slots,
  29140. activator: slots.activator ? slotProps => createVNode(Fragment, null, [createVNode(VDefaultsProvider, {
  29141. "defaults": activatorDefaults.value
  29142. }, {
  29143. default: () => [slots.activator?.(slotProps)]
  29144. })]) : undefined
  29145. });
  29146. });
  29147. return {};
  29148. }
  29149. });
  29150. // Types
  29151. const VTreeviewSymbol = Symbol.for('vuetify:v-treeview');
  29152. const makeVTreeviewItemProps = propsFactory({
  29153. loading: Boolean,
  29154. onToggleExpand: EventProp(),
  29155. toggleIcon: IconValue,
  29156. ...makeVListItemProps({
  29157. slim: true
  29158. })
  29159. }, 'VTreeviewItem');
  29160. const VTreeviewItem = genericComponent()({
  29161. name: 'VTreeviewItem',
  29162. props: makeVTreeviewItemProps(),
  29163. setup(props, _ref) {
  29164. let {
  29165. attrs,
  29166. slots,
  29167. emit
  29168. } = _ref;
  29169. const link = useLink(props, attrs);
  29170. const vListItemRef = ref();
  29171. const isActivatableGroupActivator = computed(() => vListItemRef.value?.root.activatable.value && vListItemRef.value?.isGroupActivator);
  29172. const isClickable = computed(() => !props.disabled && props.link !== false && (props.link || link.isClickable.value || props.value != null && !!vListItemRef.value?.list || isActivatableGroupActivator.value));
  29173. function activateGroupActivator(e) {
  29174. if (isClickable.value && isActivatableGroupActivator.value) {
  29175. vListItemRef.value?.activate(!vListItemRef.value?.isActivated, e);
  29176. }
  29177. }
  29178. const visibleIds = inject$1(VTreeviewSymbol, {
  29179. visibleIds: ref()
  29180. }).visibleIds;
  29181. useRender(() => {
  29182. const listItemProps = omit(VListItem.filterProps(props), ['onClick']);
  29183. const hasPrepend = slots.prepend || props.toggleIcon;
  29184. return createVNode(VListItem, mergeProps({
  29185. "ref": vListItemRef
  29186. }, listItemProps, {
  29187. "active": vListItemRef.value?.isActivated,
  29188. "class": ['v-treeview-item', {
  29189. 'v-treeview-item--activatable-group-activator': isActivatableGroupActivator.value,
  29190. 'v-treeview-item--filtered': visibleIds.value && !visibleIds.value.has(vListItemRef.value?.id)
  29191. }, props.class],
  29192. "ripple": false,
  29193. "onClick": props.onClick ?? activateGroupActivator
  29194. }), {
  29195. ...slots,
  29196. prepend: hasPrepend ? slotProps => {
  29197. return createVNode(Fragment, null, [props.toggleIcon && createVNode(VListItemAction, {
  29198. "start": false
  29199. }, {
  29200. default: () => [createVNode(VBtn, {
  29201. "density": "compact",
  29202. "icon": props.toggleIcon,
  29203. "loading": props.loading,
  29204. "variant": "text",
  29205. "onClick": props.onToggleExpand
  29206. }, {
  29207. loader() {
  29208. return createVNode(VProgressCircular, {
  29209. "indeterminate": "disable-shrink",
  29210. "size": "20",
  29211. "width": "2"
  29212. }, null);
  29213. }
  29214. })]
  29215. }), slots.prepend?.(slotProps)]);
  29216. } : undefined
  29217. });
  29218. });
  29219. return {};
  29220. }
  29221. });
  29222. // Types
  29223. const makeVTreeviewChildrenProps = propsFactory({
  29224. loadChildren: Function,
  29225. loadingIcon: {
  29226. type: String,
  29227. default: '$loading'
  29228. },
  29229. items: Array,
  29230. openOnClick: {
  29231. type: Boolean,
  29232. default: undefined
  29233. },
  29234. indeterminateIcon: {
  29235. type: IconValue,
  29236. default: '$checkboxIndeterminate'
  29237. },
  29238. falseIcon: IconValue,
  29239. trueIcon: IconValue,
  29240. returnObject: Boolean,
  29241. selectable: Boolean,
  29242. selectedColor: String,
  29243. selectStrategy: [String, Function, Object]
  29244. }, 'VTreeviewChildren');
  29245. const VTreeviewChildren = genericComponent()({
  29246. name: 'VTreeviewChildren',
  29247. props: makeVTreeviewChildrenProps(),
  29248. setup(props, _ref) {
  29249. let {
  29250. slots
  29251. } = _ref;
  29252. const isLoading = reactive(new Set());
  29253. const isClickOnOpen = computed(() => props.openOnClick != null ? props.openOnClick : props.selectable);
  29254. async function checkChildren(item) {
  29255. try {
  29256. if (!props.items?.length || !props.loadChildren) return;
  29257. if (item?.children?.length === 0) {
  29258. isLoading.add(item.value);
  29259. await props.loadChildren(item.raw);
  29260. }
  29261. } finally {
  29262. isLoading.delete(item.value);
  29263. }
  29264. }
  29265. function selectItem(select, isSelected) {
  29266. if (props.selectable) {
  29267. select(!isSelected);
  29268. }
  29269. }
  29270. return () => slots.default?.() ?? props.items?.map(item => {
  29271. const {
  29272. children,
  29273. props: itemProps
  29274. } = item;
  29275. const loading = isLoading.has(item.value);
  29276. const slotsWithItem = {
  29277. prepend: slotProps => createVNode(Fragment, null, [props.selectable && (!children || children && !['leaf', 'single-leaf'].includes(props.selectStrategy)) && createVNode("div", null, [createVNode(VCheckboxBtn, {
  29278. "key": item.value,
  29279. "modelValue": slotProps.isSelected,
  29280. "loading": loading,
  29281. "color": props.selectedColor,
  29282. "indeterminate": slotProps.isIndeterminate,
  29283. "indeterminateIcon": props.indeterminateIcon,
  29284. "falseIcon": props.falseIcon,
  29285. "trueIcon": props.trueIcon,
  29286. "onClick": withModifiers(() => selectItem(slotProps.select, slotProps.isSelected), ['stop']),
  29287. "onKeydown": e => {
  29288. if (!['Enter', 'Space'].includes(e.key)) return;
  29289. e.stopPropagation();
  29290. selectItem(slotProps.select, slotProps.isSelected);
  29291. }
  29292. }, null)]), slots.prepend?.({
  29293. ...slotProps,
  29294. item: item.raw,
  29295. internalItem: item
  29296. })]),
  29297. append: slots.append ? slotProps => slots.append?.({
  29298. ...slotProps,
  29299. item: item.raw,
  29300. internalItem: item
  29301. }) : undefined,
  29302. title: slots.title ? slotProps => slots.title?.({
  29303. ...slotProps,
  29304. item: item.raw,
  29305. internalItem: item
  29306. }) : undefined
  29307. };
  29308. const treeviewGroupProps = VTreeviewGroup.filterProps(itemProps);
  29309. const treeviewChildrenProps = VTreeviewChildren.filterProps(props);
  29310. return children ? createVNode(VTreeviewGroup, mergeProps(treeviewGroupProps, {
  29311. "value": props.returnObject ? item.raw : treeviewGroupProps?.value
  29312. }), {
  29313. activator: _ref2 => {
  29314. let {
  29315. props: activatorProps
  29316. } = _ref2;
  29317. const listItemProps = {
  29318. ...itemProps,
  29319. ...activatorProps,
  29320. value: itemProps?.value,
  29321. onToggleExpand: [() => checkChildren(item), activatorProps.onClick],
  29322. onClick: isClickOnOpen.value ? [() => checkChildren(item), activatorProps.onClick] : undefined
  29323. };
  29324. return createVNode(VTreeviewItem, mergeProps(listItemProps, {
  29325. "value": props.returnObject ? toRaw(item.raw) : itemProps.value,
  29326. "loading": loading
  29327. }), slotsWithItem);
  29328. },
  29329. default: () => createVNode(VTreeviewChildren, mergeProps(treeviewChildrenProps, {
  29330. "items": children,
  29331. "returnObject": props.returnObject
  29332. }), slots)
  29333. }) : slots.item?.({
  29334. props: itemProps,
  29335. item: item.raw,
  29336. internalItem: item
  29337. }) ?? createVNode(VTreeviewItem, mergeProps(itemProps, {
  29338. "value": props.returnObject ? toRaw(item.raw) : itemProps.value
  29339. }), slotsWithItem);
  29340. });
  29341. }
  29342. });
  29343. function flatten(items) {
  29344. let flat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
  29345. for (const item of items) {
  29346. flat.push(item);
  29347. if (item.children) flatten(item.children, flat);
  29348. }
  29349. return flat;
  29350. }
  29351. const makeVTreeviewProps = propsFactory({
  29352. openAll: Boolean,
  29353. search: String,
  29354. ...makeFilterProps({
  29355. filterKeys: ['title']
  29356. }),
  29357. ...makeVTreeviewChildrenProps(),
  29358. ...omit(makeVListProps({
  29359. collapseIcon: '$treeviewCollapse',
  29360. expandIcon: '$treeviewExpand',
  29361. slim: true
  29362. }), ['itemType', 'nav', 'openStrategy']),
  29363. modelValue: {
  29364. type: Array,
  29365. default: () => []
  29366. }
  29367. }, 'VTreeview');
  29368. const VTreeview = genericComponent()({
  29369. name: 'VTreeview',
  29370. props: makeVTreeviewProps(),
  29371. emits: {
  29372. 'update:opened': val => true,
  29373. 'update:activated': val => true,
  29374. 'update:selected': val => true,
  29375. 'update:modelValue': val => true,
  29376. 'click:open': value => true,
  29377. 'click:select': value => true
  29378. },
  29379. setup(props, _ref) {
  29380. let {
  29381. slots
  29382. } = _ref;
  29383. const {
  29384. items
  29385. } = useListItems(props);
  29386. const activeColor = toRef(props, 'activeColor');
  29387. const baseColor = toRef(props, 'baseColor');
  29388. const color = toRef(props, 'color');
  29389. const activated = useProxiedModel(props, 'activated');
  29390. const model = useProxiedModel(props, 'modelValue');
  29391. const _selected = useProxiedModel(props, 'selected', props.modelValue);
  29392. const selected = computed({
  29393. get: () => _selected.value,
  29394. set(val) {
  29395. _selected.value = val;
  29396. model.value = val;
  29397. }
  29398. });
  29399. const vListRef = ref();
  29400. const opened = computed(() => props.openAll ? openAll(items.value) : props.opened);
  29401. const flatItems = computed(() => flatten(items.value));
  29402. const search = toRef(props, 'search');
  29403. const {
  29404. filteredItems
  29405. } = useFilter(props, flatItems, search);
  29406. const visibleIds = computed(() => {
  29407. if (!search.value) return null;
  29408. const getPath = vListRef.value?.getPath;
  29409. if (!getPath) return null;
  29410. return new Set(filteredItems.value.flatMap(item => {
  29411. const itemVal = props.returnObject ? item.raw : item.props.value;
  29412. return [...getPath(itemVal), ...getChildren(itemVal)].map(toRaw);
  29413. }));
  29414. });
  29415. function getChildren(id) {
  29416. const arr = [];
  29417. const queue = (vListRef.value?.children.get(id) ?? []).slice();
  29418. while (queue.length) {
  29419. const child = queue.shift();
  29420. if (!child) continue;
  29421. arr.push(child);
  29422. queue.push(...(vListRef.value?.children.get(child) ?? []).slice());
  29423. }
  29424. return arr;
  29425. }
  29426. function openAll(items) {
  29427. let ids = [];
  29428. for (const i of items) {
  29429. if (!i.children) continue;
  29430. ids.push(props.returnObject ? toRaw(i.raw) : i.value);
  29431. if (i.children) {
  29432. ids = ids.concat(openAll(i.children));
  29433. }
  29434. }
  29435. return ids;
  29436. }
  29437. provide(VTreeviewSymbol, {
  29438. visibleIds
  29439. });
  29440. provideDefaults({
  29441. VTreeviewGroup: {
  29442. activeColor,
  29443. baseColor,
  29444. color,
  29445. collapseIcon: toRef(props, 'collapseIcon'),
  29446. expandIcon: toRef(props, 'expandIcon')
  29447. },
  29448. VTreeviewItem: {
  29449. activeClass: toRef(props, 'activeClass'),
  29450. activeColor,
  29451. baseColor,
  29452. color,
  29453. density: toRef(props, 'density'),
  29454. disabled: toRef(props, 'disabled'),
  29455. lines: toRef(props, 'lines'),
  29456. variant: toRef(props, 'variant')
  29457. }
  29458. });
  29459. useRender(() => {
  29460. const listProps = VList.filterProps(props);
  29461. const treeviewChildrenProps = VTreeviewChildren.filterProps(props);
  29462. return createVNode(VList, mergeProps({
  29463. "ref": vListRef
  29464. }, listProps, {
  29465. "class": ['v-treeview', props.class],
  29466. "open-strategy": "multiple",
  29467. "style": props.style,
  29468. "opened": opened.value,
  29469. "activated": activated.value,
  29470. "onUpdate:activated": $event => activated.value = $event,
  29471. "selected": selected.value,
  29472. "onUpdate:selected": $event => selected.value = $event
  29473. }), {
  29474. default: () => [createVNode(VTreeviewChildren, mergeProps(treeviewChildrenProps, {
  29475. "returnObject": props.returnObject,
  29476. "items": items.value
  29477. }), slots)]
  29478. });
  29479. });
  29480. return {};
  29481. }
  29482. });
  29483. var components = /*#__PURE__*/Object.freeze({
  29484. __proto__: null,
  29485. VAlert: VAlert,
  29486. VAlertTitle: VAlertTitle,
  29487. VApp: VApp,
  29488. VAppBar: VAppBar,
  29489. VAppBarNavIcon: VAppBarNavIcon,
  29490. VAppBarTitle: VAppBarTitle,
  29491. VAutocomplete: VAutocomplete,
  29492. VAvatar: VAvatar,
  29493. VBadge: VBadge,
  29494. VBanner: VBanner,
  29495. VBannerActions: VBannerActions,
  29496. VBannerText: VBannerText,
  29497. VBottomNavigation: VBottomNavigation,
  29498. VBottomSheet: VBottomSheet,
  29499. VBreadcrumbs: VBreadcrumbs,
  29500. VBreadcrumbsDivider: VBreadcrumbsDivider,
  29501. VBreadcrumbsItem: VBreadcrumbsItem,
  29502. VBtn: VBtn,
  29503. VBtnGroup: VBtnGroup,
  29504. VBtnToggle: VBtnToggle,
  29505. VCalendar: VCalendar,
  29506. VCalendarDay: VCalendarDay,
  29507. VCalendarHeader: VCalendarHeader,
  29508. VCalendarInterval: VCalendarInterval,
  29509. VCalendarIntervalEvent: VCalendarIntervalEvent,
  29510. VCalendarMonthDay: VCalendarMonthDay,
  29511. VCard: VCard,
  29512. VCardActions: VCardActions,
  29513. VCardItem: VCardItem,
  29514. VCardSubtitle: VCardSubtitle,
  29515. VCardText: VCardText,
  29516. VCardTitle: VCardTitle,
  29517. VCarousel: VCarousel,
  29518. VCarouselItem: VCarouselItem,
  29519. VCheckbox: VCheckbox,
  29520. VCheckboxBtn: VCheckboxBtn,
  29521. VChip: VChip,
  29522. VChipGroup: VChipGroup,
  29523. VClassIcon: VClassIcon,
  29524. VCode: VCode,
  29525. VCol: VCol,
  29526. VColorPicker: VColorPicker,
  29527. VCombobox: VCombobox,
  29528. VComponentIcon: VComponentIcon,
  29529. VConfirmEdit: VConfirmEdit,
  29530. VContainer: VContainer,
  29531. VCounter: VCounter,
  29532. VDataIterator: VDataIterator,
  29533. VDataTable: VDataTable,
  29534. VDataTableFooter: VDataTableFooter,
  29535. VDataTableHeaders: VDataTableHeaders,
  29536. VDataTableRow: VDataTableRow,
  29537. VDataTableRows: VDataTableRows,
  29538. VDataTableServer: VDataTableServer,
  29539. VDataTableVirtual: VDataTableVirtual,
  29540. VDateInput: VDateInput,
  29541. VDatePicker: VDatePicker,
  29542. VDatePickerControls: VDatePickerControls,
  29543. VDatePickerHeader: VDatePickerHeader,
  29544. VDatePickerMonth: VDatePickerMonth,
  29545. VDatePickerMonths: VDatePickerMonths,
  29546. VDatePickerYears: VDatePickerYears,
  29547. VDefaultsProvider: VDefaultsProvider,
  29548. VDialog: VDialog,
  29549. VDialogBottomTransition: VDialogBottomTransition,
  29550. VDialogTopTransition: VDialogTopTransition,
  29551. VDialogTransition: VDialogTransition,
  29552. VDivider: VDivider,
  29553. VEmptyState: VEmptyState,
  29554. VExpandTransition: VExpandTransition,
  29555. VExpandXTransition: VExpandXTransition,
  29556. VExpansionPanel: VExpansionPanel,
  29557. VExpansionPanelText: VExpansionPanelText,
  29558. VExpansionPanelTitle: VExpansionPanelTitle,
  29559. VExpansionPanels: VExpansionPanels,
  29560. VFab: VFab,
  29561. VFabTransition: VFabTransition,
  29562. VFadeTransition: VFadeTransition,
  29563. VField: VField,
  29564. VFieldLabel: VFieldLabel,
  29565. VFileInput: VFileInput,
  29566. VFileUpload: VFileUpload,
  29567. VFileUploadItem: VFileUploadItem,
  29568. VFooter: VFooter,
  29569. VForm: VForm,
  29570. VHover: VHover,
  29571. VIcon: VIcon,
  29572. VImg: VImg,
  29573. VInfiniteScroll: VInfiniteScroll,
  29574. VInput: VInput,
  29575. VItem: VItem,
  29576. VItemGroup: VItemGroup,
  29577. VKbd: VKbd,
  29578. VLabel: VLabel,
  29579. VLayout: VLayout,
  29580. VLayoutItem: VLayoutItem,
  29581. VLazy: VLazy,
  29582. VLigatureIcon: VLigatureIcon,
  29583. VList: VList,
  29584. VListGroup: VListGroup,
  29585. VListImg: VListImg,
  29586. VListItem: VListItem,
  29587. VListItemAction: VListItemAction,
  29588. VListItemMedia: VListItemMedia,
  29589. VListItemSubtitle: VListItemSubtitle,
  29590. VListItemTitle: VListItemTitle,
  29591. VListSubheader: VListSubheader,
  29592. VLocaleProvider: VLocaleProvider,
  29593. VMain: VMain,
  29594. VMenu: VMenu,
  29595. VMessages: VMessages,
  29596. VNavigationDrawer: VNavigationDrawer,
  29597. VNoSsr: VNoSsr,
  29598. VNumberInput: VNumberInput,
  29599. VOtpInput: VOtpInput,
  29600. VOverlay: VOverlay,
  29601. VPagination: VPagination,
  29602. VParallax: VParallax,
  29603. VPicker: VPicker,
  29604. VPickerTitle: VPickerTitle,
  29605. VProgressCircular: VProgressCircular,
  29606. VProgressLinear: VProgressLinear,
  29607. VPullToRefresh: VPullToRefresh,
  29608. VRadio: VRadio,
  29609. VRadioGroup: VRadioGroup,
  29610. VRangeSlider: VRangeSlider,
  29611. VRating: VRating,
  29612. VResponsive: VResponsive,
  29613. VRow: VRow,
  29614. VScaleTransition: VScaleTransition,
  29615. VScrollXReverseTransition: VScrollXReverseTransition,
  29616. VScrollXTransition: VScrollXTransition,
  29617. VScrollYReverseTransition: VScrollYReverseTransition,
  29618. VScrollYTransition: VScrollYTransition,
  29619. VSelect: VSelect,
  29620. VSelectionControl: VSelectionControl,
  29621. VSelectionControlGroup: VSelectionControlGroup,
  29622. VSheet: VSheet,
  29623. VSkeletonLoader: VSkeletonLoader,
  29624. VSlideGroup: VSlideGroup,
  29625. VSlideGroupItem: VSlideGroupItem,
  29626. VSlideXReverseTransition: VSlideXReverseTransition,
  29627. VSlideXTransition: VSlideXTransition,
  29628. VSlideYReverseTransition: VSlideYReverseTransition,
  29629. VSlideYTransition: VSlideYTransition,
  29630. VSlider: VSlider,
  29631. VSnackbar: VSnackbar,
  29632. VSnackbarQueue: VSnackbarQueue,
  29633. VSpacer: VSpacer,
  29634. VSparkline: VSparkline,
  29635. VSpeedDial: VSpeedDial,
  29636. VStepper: VStepper,
  29637. VStepperActions: VStepperActions,
  29638. VStepperHeader: VStepperHeader,
  29639. VStepperItem: VStepperItem,
  29640. VStepperVertical: VStepperVertical,
  29641. VStepperVerticalActions: VStepperVerticalActions,
  29642. VStepperVerticalItem: VStepperVerticalItem,
  29643. VStepperWindow: VStepperWindow,
  29644. VStepperWindowItem: VStepperWindowItem,
  29645. VSvgIcon: VSvgIcon,
  29646. VSwitch: VSwitch,
  29647. VSystemBar: VSystemBar,
  29648. VTab: VTab,
  29649. VTable: VTable,
  29650. VTabs: VTabs,
  29651. VTabsWindow: VTabsWindow,
  29652. VTabsWindowItem: VTabsWindowItem,
  29653. VTextField: VTextField,
  29654. VTextarea: VTextarea,
  29655. VThemeProvider: VThemeProvider,
  29656. VTimePicker: VTimePicker,
  29657. VTimePickerClock: VTimePickerClock,
  29658. VTimePickerControls: VTimePickerControls,
  29659. VTimeline: VTimeline,
  29660. VTimelineItem: VTimelineItem,
  29661. VToolbar: VToolbar,
  29662. VToolbarItems: VToolbarItems,
  29663. VToolbarTitle: VToolbarTitle,
  29664. VTooltip: VTooltip,
  29665. VTreeview: VTreeview,
  29666. VTreeviewGroup: VTreeviewGroup,
  29667. VTreeviewItem: VTreeviewItem,
  29668. VValidation: VValidation,
  29669. VVirtualScroll: VVirtualScroll,
  29670. VWindow: VWindow,
  29671. VWindowItem: VWindowItem
  29672. });
  29673. // Types
  29674. function mounted$2(el, binding) {
  29675. const modifiers = binding.modifiers || {};
  29676. const value = binding.value;
  29677. const {
  29678. once,
  29679. immediate,
  29680. ...modifierKeys
  29681. } = modifiers;
  29682. const defaultValue = !Object.keys(modifierKeys).length;
  29683. const {
  29684. handler,
  29685. options
  29686. } = typeof value === 'object' ? value : {
  29687. handler: value,
  29688. options: {
  29689. attributes: modifierKeys?.attr ?? defaultValue,
  29690. characterData: modifierKeys?.char ?? defaultValue,
  29691. childList: modifierKeys?.child ?? defaultValue,
  29692. subtree: modifierKeys?.sub ?? defaultValue
  29693. }
  29694. };
  29695. const observer = new MutationObserver(function () {
  29696. let mutations = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
  29697. let observer = arguments.length > 1 ? arguments[1] : undefined;
  29698. handler?.(mutations, observer);
  29699. if (once) unmounted$2(el, binding);
  29700. });
  29701. if (immediate) handler?.([], observer);
  29702. el._mutate = Object(el._mutate);
  29703. el._mutate[binding.instance.$.uid] = {
  29704. observer
  29705. };
  29706. observer.observe(el, options);
  29707. }
  29708. function unmounted$2(el, binding) {
  29709. if (!el._mutate?.[binding.instance.$.uid]) return;
  29710. el._mutate[binding.instance.$.uid].observer.disconnect();
  29711. delete el._mutate[binding.instance.$.uid];
  29712. }
  29713. const Mutate = {
  29714. mounted: mounted$2,
  29715. unmounted: unmounted$2
  29716. };
  29717. // Types
  29718. function mounted$1(el, binding) {
  29719. const handler = binding.value;
  29720. const options = {
  29721. passive: !binding.modifiers?.active
  29722. };
  29723. window.addEventListener('resize', handler, options);
  29724. el._onResize = Object(el._onResize);
  29725. el._onResize[binding.instance.$.uid] = {
  29726. handler,
  29727. options
  29728. };
  29729. if (!binding.modifiers?.quiet) {
  29730. handler();
  29731. }
  29732. }
  29733. function unmounted$1(el, binding) {
  29734. if (!el._onResize?.[binding.instance.$.uid]) return;
  29735. const {
  29736. handler,
  29737. options
  29738. } = el._onResize[binding.instance.$.uid];
  29739. window.removeEventListener('resize', handler, options);
  29740. delete el._onResize[binding.instance.$.uid];
  29741. }
  29742. const Resize = {
  29743. mounted: mounted$1,
  29744. unmounted: unmounted$1
  29745. };
  29746. // Types
  29747. function mounted(el, binding) {
  29748. const {
  29749. self = false
  29750. } = binding.modifiers ?? {};
  29751. const value = binding.value;
  29752. const options = typeof value === 'object' && value.options || {
  29753. passive: true
  29754. };
  29755. const handler = typeof value === 'function' || 'handleEvent' in value ? value : value.handler;
  29756. const target = self ? el : binding.arg ? document.querySelector(binding.arg) : window;
  29757. if (!target) return;
  29758. target.addEventListener('scroll', handler, options);
  29759. el._onScroll = Object(el._onScroll);
  29760. el._onScroll[binding.instance.$.uid] = {
  29761. handler,
  29762. options,
  29763. // Don't reference self
  29764. target: self ? undefined : target
  29765. };
  29766. }
  29767. function unmounted(el, binding) {
  29768. if (!el._onScroll?.[binding.instance.$.uid]) return;
  29769. const {
  29770. handler,
  29771. options,
  29772. target = el
  29773. } = el._onScroll[binding.instance.$.uid];
  29774. target.removeEventListener('scroll', handler, options);
  29775. delete el._onScroll[binding.instance.$.uid];
  29776. }
  29777. function updated(el, binding) {
  29778. if (binding.value === binding.oldValue) return;
  29779. unmounted(el, binding);
  29780. mounted(el, binding);
  29781. }
  29782. const Scroll = {
  29783. mounted,
  29784. unmounted,
  29785. updated
  29786. };
  29787. // Utilities
  29788. // Types
  29789. function useDirectiveComponent(component, props) {
  29790. const concreteComponent = typeof component === 'string' ? resolveComponent(component) : component;
  29791. const hook = mountComponent(concreteComponent, props);
  29792. return {
  29793. mounted: hook,
  29794. updated: hook,
  29795. unmounted(el) {
  29796. render(null, el);
  29797. }
  29798. };
  29799. }
  29800. function mountComponent(component, props) {
  29801. return function (el, binding, vnode) {
  29802. const _props = typeof props === 'function' ? props(binding) : props;
  29803. const text = binding.value?.text ?? binding.value ?? _props?.text;
  29804. const value = isObject(binding.value) ? binding.value : {};
  29805. // Get the children from the props or directive value, or the element's children
  29806. const children = () => text ?? el.textContent;
  29807. // If vnode.ctx is the same as the instance, then we're bound to a plain element
  29808. // and need to find the nearest parent component instance to inherit provides from
  29809. const provides = (vnode.ctx === binding.instance.$ ? findComponentParent(vnode, binding.instance.$)?.provides : vnode.ctx?.provides) ?? binding.instance.$.provides;
  29810. const node = h(component, mergeProps(_props, value), children);
  29811. node.appContext = Object.assign(Object.create(null), binding.instance.$.appContext, {
  29812. provides
  29813. });
  29814. render(node, el);
  29815. };
  29816. }
  29817. function findComponentParent(vnode, root) {
  29818. // Walk the tree from root until we find the child vnode
  29819. const stack = new Set();
  29820. const walk = children => {
  29821. for (const child of children) {
  29822. if (!child) continue;
  29823. if (child === vnode || child.el && vnode.el && child.el === vnode.el) {
  29824. return true;
  29825. }
  29826. stack.add(child);
  29827. let result;
  29828. if (child.suspense) {
  29829. result = walk([child.ssContent]);
  29830. } else if (Array.isArray(child.children)) {
  29831. result = walk(child.children);
  29832. } else if (child.component?.vnode) {
  29833. result = walk([child.component?.subTree]);
  29834. }
  29835. if (result) {
  29836. return result;
  29837. }
  29838. stack.delete(child);
  29839. }
  29840. return false;
  29841. };
  29842. if (!walk([root.subTree])) {
  29843. consoleError('Could not find original vnode, component will not inherit provides');
  29844. return root;
  29845. }
  29846. // Return the first component parent
  29847. const result = Array.from(stack).reverse();
  29848. for (const child of result) {
  29849. if (child.component) {
  29850. return child.component;
  29851. }
  29852. }
  29853. return root;
  29854. }
  29855. // Components
  29856. // Types
  29857. const Tooltip = useDirectiveComponent(VTooltip, binding => {
  29858. return {
  29859. activator: 'parent',
  29860. location: binding.arg?.replace('-', ' '),
  29861. text: typeof binding.value === 'boolean' ? undefined : binding.value
  29862. };
  29863. });
  29864. var directives = /*#__PURE__*/Object.freeze({
  29865. __proto__: null,
  29866. ClickOutside: ClickOutside,
  29867. Intersect: Intersect,
  29868. Mutate: Mutate,
  29869. Resize: Resize,
  29870. Ripple: Ripple,
  29871. Scroll: Scroll,
  29872. Tooltip: Tooltip,
  29873. Touch: Touch
  29874. });
  29875. // Composables
  29876. function createVuetify$1() {
  29877. let vuetify = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  29878. const {
  29879. blueprint,
  29880. ...rest
  29881. } = vuetify;
  29882. const options = mergeDeep(blueprint, rest);
  29883. const {
  29884. aliases = {},
  29885. components = {},
  29886. directives = {}
  29887. } = options;
  29888. const defaults = createDefaults(options.defaults);
  29889. const display = createDisplay(options.display, options.ssr);
  29890. const theme = createTheme(options.theme);
  29891. const icons = createIcons(options.icons);
  29892. const locale = createLocale(options.locale);
  29893. const date = createDate(options.date, locale);
  29894. const goTo = createGoTo(options.goTo, locale);
  29895. const install = app => {
  29896. for (const key in directives) {
  29897. app.directive(key, directives[key]);
  29898. }
  29899. for (const key in components) {
  29900. app.component(key, components[key]);
  29901. }
  29902. for (const key in aliases) {
  29903. app.component(key, defineComponent({
  29904. ...aliases[key],
  29905. name: key,
  29906. aliasName: aliases[key].name
  29907. }));
  29908. }
  29909. theme.install(app);
  29910. app.provide(DefaultsSymbol, defaults);
  29911. app.provide(DisplaySymbol, display);
  29912. app.provide(ThemeSymbol, theme);
  29913. app.provide(IconSymbol, icons);
  29914. app.provide(LocaleSymbol, locale);
  29915. app.provide(DateOptionsSymbol, date.options);
  29916. app.provide(DateAdapterSymbol, date.instance);
  29917. app.provide(GoToSymbol, goTo);
  29918. if (IN_BROWSER && options.ssr) {
  29919. if (app.$nuxt) {
  29920. app.$nuxt.hook('app:suspense:resolve', () => {
  29921. display.update();
  29922. });
  29923. } else {
  29924. const {
  29925. mount
  29926. } = app;
  29927. app.mount = function () {
  29928. const vm = mount(...arguments);
  29929. nextTick(() => display.update());
  29930. app.mount = mount;
  29931. return vm;
  29932. };
  29933. }
  29934. }
  29935. getUid.reset();
  29936. if (typeof __VUE_OPTIONS_API__ !== 'boolean' || __VUE_OPTIONS_API__) {
  29937. app.mixin({
  29938. computed: {
  29939. $vuetify() {
  29940. return reactive({
  29941. defaults: inject.call(this, DefaultsSymbol),
  29942. display: inject.call(this, DisplaySymbol),
  29943. theme: inject.call(this, ThemeSymbol),
  29944. icons: inject.call(this, IconSymbol),
  29945. locale: inject.call(this, LocaleSymbol),
  29946. date: inject.call(this, DateAdapterSymbol)
  29947. });
  29948. }
  29949. }
  29950. });
  29951. }
  29952. };
  29953. return {
  29954. install,
  29955. defaults,
  29956. display,
  29957. theme,
  29958. icons,
  29959. locale,
  29960. date,
  29961. goTo
  29962. };
  29963. }
  29964. const version$1 = "3.7.6";
  29965. createVuetify$1.version = version$1;
  29966. // Vue's inject() can only be used in setup
  29967. function inject(key) {
  29968. const vm = this.$;
  29969. const provides = vm.parent?.provides ?? vm.vnode.appContext?.provides;
  29970. if (provides && key in provides) {
  29971. return provides[key];
  29972. }
  29973. }
  29974. // Icons
  29975. // Types
  29976. const md1 = {
  29977. defaults: {
  29978. global: {
  29979. rounded: 'sm'
  29980. },
  29981. VAvatar: {
  29982. rounded: 'circle'
  29983. },
  29984. VAutocomplete: {
  29985. variant: 'underlined'
  29986. },
  29987. VBanner: {
  29988. color: 'primary'
  29989. },
  29990. VBtn: {
  29991. color: 'primary',
  29992. rounded: 0
  29993. },
  29994. VCheckbox: {
  29995. color: 'secondary'
  29996. },
  29997. VCombobox: {
  29998. variant: 'underlined'
  29999. },
  30000. VSelect: {
  30001. variant: 'underlined'
  30002. },
  30003. VSlider: {
  30004. color: 'primary'
  30005. },
  30006. VTabs: {
  30007. color: 'primary'
  30008. },
  30009. VTextarea: {
  30010. variant: 'underlined'
  30011. },
  30012. VTextField: {
  30013. variant: 'underlined'
  30014. },
  30015. VToolbar: {
  30016. VBtn: {
  30017. color: null
  30018. }
  30019. }
  30020. },
  30021. icons: {
  30022. defaultSet: 'mdi',
  30023. sets: {
  30024. mdi
  30025. }
  30026. },
  30027. theme: {
  30028. themes: {
  30029. light: {
  30030. colors: {
  30031. primary: '#3F51B5',
  30032. 'primary-darken-1': '#303F9F',
  30033. 'primary-lighten-1': '#C5CAE9',
  30034. secondary: '#FF4081',
  30035. 'secondary-darken-1': '#F50057',
  30036. 'secondary-lighten-1': '#FF80AB',
  30037. accent: '#009688'
  30038. }
  30039. }
  30040. }
  30041. }
  30042. };
  30043. // Icons
  30044. // Types
  30045. const md2 = {
  30046. defaults: {
  30047. global: {
  30048. rounded: 'md'
  30049. },
  30050. VAvatar: {
  30051. rounded: 'circle'
  30052. },
  30053. VAutocomplete: {
  30054. variant: 'filled'
  30055. },
  30056. VBanner: {
  30057. color: 'primary'
  30058. },
  30059. VBtn: {
  30060. color: 'primary'
  30061. },
  30062. VCheckbox: {
  30063. color: 'secondary'
  30064. },
  30065. VCombobox: {
  30066. variant: 'filled'
  30067. },
  30068. VSelect: {
  30069. variant: 'filled'
  30070. },
  30071. VSlider: {
  30072. color: 'primary'
  30073. },
  30074. VTabs: {
  30075. color: 'primary'
  30076. },
  30077. VTextarea: {
  30078. variant: 'filled'
  30079. },
  30080. VTextField: {
  30081. variant: 'filled'
  30082. },
  30083. VToolbar: {
  30084. VBtn: {
  30085. color: null
  30086. }
  30087. }
  30088. },
  30089. icons: {
  30090. defaultSet: 'mdi',
  30091. sets: {
  30092. mdi
  30093. }
  30094. },
  30095. theme: {
  30096. themes: {
  30097. light: {
  30098. colors: {
  30099. primary: '#6200EE',
  30100. 'primary-darken-1': '#3700B3',
  30101. secondary: '#03DAC6',
  30102. 'secondary-darken-1': '#018786',
  30103. error: '#B00020'
  30104. }
  30105. }
  30106. }
  30107. }
  30108. };
  30109. // Icons
  30110. // Types
  30111. const md3 = {
  30112. defaults: {
  30113. VAppBar: {
  30114. flat: true
  30115. },
  30116. VAutocomplete: {
  30117. variant: 'filled'
  30118. },
  30119. VBanner: {
  30120. color: 'primary'
  30121. },
  30122. VBottomSheet: {
  30123. contentClass: 'rounded-t-xl overflow-hidden'
  30124. },
  30125. VBtn: {
  30126. color: 'primary',
  30127. rounded: 'xl'
  30128. },
  30129. VBtnGroup: {
  30130. rounded: 'xl',
  30131. VBtn: {
  30132. rounded: null
  30133. }
  30134. },
  30135. VCard: {
  30136. rounded: 'lg'
  30137. },
  30138. VCheckbox: {
  30139. color: 'secondary',
  30140. inset: true
  30141. },
  30142. VChip: {
  30143. rounded: 'sm'
  30144. },
  30145. VCombobox: {
  30146. variant: 'filled'
  30147. },
  30148. VNavigationDrawer: {
  30149. // VList: {
  30150. // nav: true,
  30151. // VListItem: {
  30152. // rounded: 'xl',
  30153. // },
  30154. // },
  30155. },
  30156. VSelect: {
  30157. variant: 'filled'
  30158. },
  30159. VSlider: {
  30160. color: 'primary'
  30161. },
  30162. VTabs: {
  30163. color: 'primary'
  30164. },
  30165. VTextarea: {
  30166. variant: 'filled'
  30167. },
  30168. VTextField: {
  30169. variant: 'filled'
  30170. },
  30171. VToolbar: {
  30172. VBtn: {
  30173. color: null
  30174. }
  30175. }
  30176. },
  30177. icons: {
  30178. defaultSet: 'mdi',
  30179. sets: {
  30180. mdi
  30181. }
  30182. },
  30183. theme: {
  30184. themes: {
  30185. light: {
  30186. colors: {
  30187. primary: '#6750a4',
  30188. secondary: '#b4b0bb',
  30189. tertiary: '#7d5260',
  30190. error: '#b3261e',
  30191. surface: '#fffbfe'
  30192. }
  30193. }
  30194. }
  30195. }
  30196. };
  30197. var index = /*#__PURE__*/Object.freeze({
  30198. __proto__: null,
  30199. md1: md1,
  30200. md2: md2,
  30201. md3: md3
  30202. });
  30203. /* eslint-disable local-rules/sort-imports */
  30204. const version = "3.7.6";
  30205. /* eslint-disable local-rules/sort-imports */
  30206. const createVuetify = function () {
  30207. let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  30208. return createVuetify$1({
  30209. components,
  30210. directives,
  30211. ...options
  30212. });
  30213. };
  30214. export { index as blueprints, components, createVuetify, directives, useDate, useDefaults, useDisplay, useGoTo, useLayout, useLocale, useRtl, useTheme, version };
  30215. //# sourceMappingURL=vuetify-labs.esm.js.map