From e85c5a3877d524b60b22c5f93289bc14f14211c1 Mon Sep 17 00:00:00 2001 From: "Md. Almas Ali" Date: Fri, 9 Feb 2024 16:16:21 +0600 Subject: [PATCH 01/14] refactor: moved docs to gh-pages branch to manage versions. --- docs/404.html | 878 --- docs/assets/images/favicon.ico | Bin 15086 -> 0 bytes docs/assets/images/favicon.png | Bin 1870 -> 0 bytes docs/assets/images/fronty.png | Bin 23027 -> 0 bytes docs/assets/images/logo.png | Bin 21894 -> 0 bytes .../assets/javascripts/bundle.fac441b0.min.js | 29 - .../javascripts/bundle.fac441b0.min.js.map | 8 - .../javascripts/lunr/min/lunr.ar.min.js | 1 - .../javascripts/lunr/min/lunr.da.min.js | 18 - .../javascripts/lunr/min/lunr.de.min.js | 18 - .../javascripts/lunr/min/lunr.du.min.js | 18 - .../javascripts/lunr/min/lunr.es.min.js | 18 - .../javascripts/lunr/min/lunr.fi.min.js | 18 - .../javascripts/lunr/min/lunr.fr.min.js | 18 - .../javascripts/lunr/min/lunr.hi.min.js | 1 - .../javascripts/lunr/min/lunr.hu.min.js | 18 - .../javascripts/lunr/min/lunr.hy.min.js | 1 - .../javascripts/lunr/min/lunr.it.min.js | 18 - .../javascripts/lunr/min/lunr.ja.min.js | 1 - .../javascripts/lunr/min/lunr.jp.min.js | 1 - .../javascripts/lunr/min/lunr.kn.min.js | 1 - .../javascripts/lunr/min/lunr.ko.min.js | 1 - .../javascripts/lunr/min/lunr.multi.min.js | 1 - .../javascripts/lunr/min/lunr.nl.min.js | 18 - .../javascripts/lunr/min/lunr.no.min.js | 18 - .../javascripts/lunr/min/lunr.pt.min.js | 18 - .../javascripts/lunr/min/lunr.ro.min.js | 18 - .../javascripts/lunr/min/lunr.ru.min.js | 18 - .../javascripts/lunr/min/lunr.sa.min.js | 1 - .../lunr/min/lunr.stemmer.support.min.js | 1 - .../javascripts/lunr/min/lunr.sv.min.js | 18 - .../javascripts/lunr/min/lunr.ta.min.js | 1 - .../javascripts/lunr/min/lunr.te.min.js | 1 - .../javascripts/lunr/min/lunr.th.min.js | 1 - .../javascripts/lunr/min/lunr.tr.min.js | 18 - .../javascripts/lunr/min/lunr.vi.min.js | 1 - .../javascripts/lunr/min/lunr.zh.min.js | 1 - docs/assets/javascripts/lunr/tinyseg.js | 206 - docs/assets/javascripts/lunr/wordcut.js | 6708 ----------------- .../workers/search.208ed371.min.js | 42 - .../workers/search.208ed371.min.js.map | 8 - docs/assets/stylesheets/main.85bb2934.min.css | 1 - .../stylesheets/main.85bb2934.min.css.map | 1 - .../stylesheets/palette.a6bdf11c.min.css | 1 - .../stylesheets/palette.a6bdf11c.min.css.map | 1 - docs/blog/index.html | 917 --- docs/components/css/attributes.html | 1032 --- docs/components/css/introduction.html | 1284 ---- docs/components/html/attributes.html | 1172 --- docs/components/html/introduction.html | 1062 --- docs/components/introduction.html | 1011 --- docs/components/js/introduction.html | 968 --- docs/contribution.html | 917 --- docs/customization/customized-html.html | 1013 --- docs/examples.html | 995 --- docs/index.html | 1003 --- docs/installation.html | 926 --- docs/projects/bootstrap-integration.html | 1299 ---- docs/projects/custom-css-project.html | 1214 --- docs/projects/starter-project.html | 1042 --- docs/quick-start.html | 1070 --- docs/search/search_index.json | 1 - docs/sitemap.xml | 93 - docs/sitemap.xml.gz | Bin 378 -> 0 bytes docs/theme/announce.html | 3 - docs/theme/main.html | 10 - docs/widgets/attributes.html | 1059 --- docs/widgets/introduction.html | 1027 --- 68 files changed, 27286 deletions(-) delete mode 100644 docs/404.html delete mode 100644 docs/assets/images/favicon.ico delete mode 100644 docs/assets/images/favicon.png delete mode 100644 docs/assets/images/fronty.png delete mode 100644 docs/assets/images/logo.png delete mode 100644 docs/assets/javascripts/bundle.fac441b0.min.js delete mode 100644 docs/assets/javascripts/bundle.fac441b0.min.js.map delete mode 100644 docs/assets/javascripts/lunr/min/lunr.ar.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.da.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.de.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.du.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.es.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.fi.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.fr.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.hi.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.hu.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.hy.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.it.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.ja.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.jp.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.kn.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.ko.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.multi.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.nl.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.no.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.pt.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.ro.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.ru.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.sa.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.stemmer.support.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.sv.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.ta.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.te.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.th.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.tr.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.vi.min.js delete mode 100644 docs/assets/javascripts/lunr/min/lunr.zh.min.js delete mode 100644 docs/assets/javascripts/lunr/tinyseg.js delete mode 100644 docs/assets/javascripts/lunr/wordcut.js delete mode 100644 docs/assets/javascripts/workers/search.208ed371.min.js delete mode 100644 docs/assets/javascripts/workers/search.208ed371.min.js.map delete mode 100644 docs/assets/stylesheets/main.85bb2934.min.css delete mode 100644 docs/assets/stylesheets/main.85bb2934.min.css.map delete mode 100644 docs/assets/stylesheets/palette.a6bdf11c.min.css delete mode 100644 docs/assets/stylesheets/palette.a6bdf11c.min.css.map delete mode 100644 docs/blog/index.html delete mode 100644 docs/components/css/attributes.html delete mode 100644 docs/components/css/introduction.html delete mode 100644 docs/components/html/attributes.html delete mode 100644 docs/components/html/introduction.html delete mode 100644 docs/components/introduction.html delete mode 100644 docs/components/js/introduction.html delete mode 100644 docs/contribution.html delete mode 100644 docs/customization/customized-html.html delete mode 100644 docs/examples.html delete mode 100644 docs/index.html delete mode 100644 docs/installation.html delete mode 100644 docs/projects/bootstrap-integration.html delete mode 100644 docs/projects/custom-css-project.html delete mode 100644 docs/projects/starter-project.html delete mode 100644 docs/quick-start.html delete mode 100644 docs/search/search_index.json delete mode 100644 docs/sitemap.xml delete mode 100644 docs/sitemap.xml.gz delete mode 100644 docs/theme/announce.html delete mode 100644 docs/theme/main.html delete mode 100644 docs/widgets/attributes.html delete mode 100644 docs/widgets/introduction.html diff --git a/docs/404.html b/docs/404.html deleted file mode 100644 index a77032c..0000000 --- a/docs/404.html +++ /dev/null @@ -1,878 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- -

404 - Not found

- -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/assets/images/favicon.ico b/docs/assets/images/favicon.ico deleted file mode 100644 index 5ce7e0f83b7c82bcd178feb3ed5b9adf5b08a598..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 zcmeI2O{i5>6vwwISwg7~3bevUs6_*F5YMO}Niik*P^eL41ffmRK|~ngYa#{BqM_t4 z$U(zq@6kB0c@!6%H7RJ~AUyql=k9giy8G^ZKJLdep$p5kzt;Ny*V=3EbMJYEuqA8_ zhYtto)Qwo97%^V>qWq6JTCjZDJ362|M#{-OH+-*N_ygryyl zJyBMq5$o?LTi%%&af2@$&q=OI)+9Fz!W?T@i_IO2N7&>P9yQ;Uu)FFbvLi-p@v&#K zvJaNzqU7fD_dImF59i!keBdkkTxcA^V9(d)!8?s5#=(AYJ~SwR=QGulaWCOCjn5-q@-}S@vZH3MHgQbn;QaYhFIQ`?e^kpi zD{oeBJh;Ety_EWlG4!q_*SloUr&1;`NT;S9t2Cd_~uJ!THTIz;;r@8+A*!%TV`{zu2^eO~FXR`_wuh-EF3#aJd{SR+eYpDPSL9#({?O%a>9VGc zSJ!#*&wYO=-a+J+{5L&gHj96({n6cN`=IgS8K5TYIf;g=7wXFMCr&@#wT)dUrP^p%3wd44=-lOaVv3LQ?^UtmE>q~8N z&mBh$xqXPWQ~doH&+%M;znAh@8i#l3tcic)@At@`J?Q;A((<3nTZwCKoV_9c`1A8{ zk~HSt)lu;-@;-gr?kI4leFk8MJ^9C<`4{i(Z${&r)3WLP{?P6yYM6Fk!4B@&Sq{)} z$#HBNlMVN2@tJJ7@fs}dKzMLZ^%d-}H}3d`16-Q8mgZ!~S?Co5nBY$COyjU0twdO&}B z2&rCYd}|2v(gXZuaEyoPl&{5+#;1_$xJP*y#JtE+ohQqi77lZ1c_q_~4K@EyYguws zGWvg7yVRNENA*D`-%D5%*J3jh z57`q7xPP|crt{cD+k?fVHcZHtT(-uW;--Ck;Hv>@VoK}JN*ZH6cJJQN@0b)b?c)od z6F`{(tt0LtHn?9t{c82o>5r=)PJB?k^YEcgJR*n2JZKI3-I#O32G`oJJ@9x}4(vs? z9yCs!UrTeB_KEqE14l=Aq~7gZ4cC5Ev-w(4bR5u zQ-fX@YpY2x9e!)wdpuwNoIS9-bUBy8zXrZEwRhe8x9K$g()zY@31-A@#J4>)ZE;#Z zr&$Aj)4gQ)F$WX*$M3fA*3W6U=P>=4 z@K?d+qxQu4EA2BmX^YL{l-ghp(QEvP`zIGaaTzb#x!BXO9KNvA`)A_*&Fw#N8-CZ? zU|qT&!XLYT;~pH>_{8(a$4T4p{dgL)@3WpXWH&I&H-`Sc_?Ylsl_ksv3)mOueGN0_pi1)z_8gX`6ch8n)jG#TkAS~|HN;b zkhh54>HDW~fvcqPyP)k!lg0mtV-as@ZXp*9UqZahX>PdS9`RR}KTcen8gs*2H90 zuM~1(^XNge!w0_biSPOq1z2F}!+Q!|ODs!9?*ch4v!^W^pk7Ez{`}}zve1YdVn9t~^&L4Xa z;~2#Np66otHXiNk{j)txYtOiNe0S&ih-*>Xy9NJZrJR_FouvnFas= diff --git a/docs/assets/images/favicon.png b/docs/assets/images/favicon.png deleted file mode 100644 index 1cf13b9f9d978896599290a74f77d5dbe7d1655c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1870 zcmV-U2eJ5xP)Gc)JR9QMau)O=X#!i9;T z37kk-upj^(fsR36MHs_+1RCI)NNu9}lD0S{B^g8PN?Ww(5|~L#Ng*g{WsqleV}|#l zz8@ri&cTzw_h33bHI+12+kK6WN$h#n5cD8OQt`5kw6p~9H3()bUQ8OS4Q4HTQ=1Ol z_JAocz`fLbT2^{`8n~UAo=#AUOf=SOq4pYkt;XbC&f#7lb$*7=$na!mWCQ`dBQsO0 zLFBSPj*N?#u5&pf2t4XjEGH|=pPQ8xh7tpx;US5Cx_Ju;!O`ya-yF`)b%TEt5>eP1ZX~}sjjA%FJF?h7cX8=b!DZl<6%Cv z*G0uvvU+vmnpLZ2paivG-(cd*y3$hCIcsZcYOGh{$&)A6*XX&kXZd3G8m)G$Zz-LV z^GF3VAW^Mdv!)4OM8EgqRiz~*Cji;uzl2uC9^=8I84vNp;ltJ|q-*uQwGp2ma6cY7 z;`%`!9UXO@fr&Ebapfs34OmS9^u6$)bJxrucutf>`dKPKT%%*d3XlFVKunp9 zasduxjrjs>f8V=D|J=XNZp;_Zy^WgQ$9WDjgY=z@stwiEBm9u5*|34&1Na8BMjjgf3+SHcr`5~>oz1Y?SW^=K z^bTyO6>Gar#P_W2gEMwq)ot3; zREHn~U&Dp0l6YT0&k-wLwYjb?5zGK`W6S2v+K>AM(95m2C20L|3m~rN8dprPr@t)5lsk9Hu*W z?pS990s;Ez=+Rj{x7p``4>+c0G5^pYnB1^!TL=(?HLHZ+HicG{~4F1d^5Awl_2!1jICM-!9eoLhbbT^;yHcefyTAaqRcY zmuctDopPT!%k+}x%lZRKnzykr2}}XfG_ne?nRQO~?%hkzo;@RN{P6o`&mMUWBYMTe z6i8ChtjX&gXl`nvrU>jah)2iNM%JdjqoaeaU%yVn!^70x-flljp6Q5tK}5}&X8&&G zX3fpb3E(!rH=zVI_9Gjl45w@{(ITqngWFe7@9{mX;tO25Z_8 zQHEpI+FkTU#4xu>RkN>b3Tnc3UpWzPXWm#o55GKF09j^Mh~)K7{QqbO_~(@CVq! zS<8954|P8mXN2MRs86xZ&Q4EfM@JB94b=(YGuk)s&^jiSF=t3*oNK3`rD{H`yQ?d; ztE=laAUoZx5?RC8*WKOj`%LXEkgDd>&^Q4M^z`%u0rg-It=hLCVsq!Z%^6eB-OvOT zFZ28TN&cRmgU}Elrnk43)!>Z1FCPL2K$7}gwzIc48NX}#!A1BpJP?#v5wkNprhV** z?Cpalt1oH&{r!o3eSKc&ap)iz2BTn_VV`4>9M^b3;(YY}4>#ML6{~(4mH+?%07*qo IM6N<$f(jP3KmY&$ diff --git a/docs/assets/images/fronty.png b/docs/assets/images/fronty.png deleted file mode 100644 index 0b0314bec7000dabf04a512452ff2e55045d23b3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23027 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 lNVSJE$-92}fBdm0WO!CAy7RflX+Rzban<@tc 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 diff --git a/docs/assets/javascripts/bundle.fac441b0.min.js b/docs/assets/javascripts/bundle.fac441b0.min.js deleted file mode 100644 index 4bb4cd6..0000000 --- a/docs/assets/javascripts/bundle.fac441b0.min.js +++ /dev/null @@ -1,29 +0,0 @@ -"use strict";(()=>{var Ci=Object.create;var gr=Object.defineProperty;var Ri=Object.getOwnPropertyDescriptor;var ki=Object.getOwnPropertyNames,Ht=Object.getOwnPropertySymbols,Hi=Object.getPrototypeOf,yr=Object.prototype.hasOwnProperty,nn=Object.prototype.propertyIsEnumerable;var rn=(e,t,r)=>t in e?gr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,P=(e,t)=>{for(var r in t||(t={}))yr.call(t,r)&&rn(e,r,t[r]);if(Ht)for(var r of Ht(t))nn.call(t,r)&&rn(e,r,t[r]);return e};var on=(e,t)=>{var r={};for(var n in e)yr.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&Ht)for(var n of Ht(e))t.indexOf(n)<0&&nn.call(e,n)&&(r[n]=e[n]);return r};var Pt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Pi=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ki(t))!yr.call(e,o)&&o!==r&&gr(e,o,{get:()=>t[o],enumerable:!(n=Ri(t,o))||n.enumerable});return e};var yt=(e,t,r)=>(r=e!=null?Ci(Hi(e)):{},Pi(t||!e||!e.__esModule?gr(r,"default",{value:e,enumerable:!0}):r,e));var sn=Pt((xr,an)=>{(function(e,t){typeof xr=="object"&&typeof an!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(xr,function(){"use strict";function e(r){var n=!0,o=!1,i=null,s={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function a(O){return!!(O&&O!==document&&O.nodeName!=="HTML"&&O.nodeName!=="BODY"&&"classList"in O&&"contains"in O.classList)}function f(O){var Qe=O.type,De=O.tagName;return!!(De==="INPUT"&&s[Qe]&&!O.readOnly||De==="TEXTAREA"&&!O.readOnly||O.isContentEditable)}function c(O){O.classList.contains("focus-visible")||(O.classList.add("focus-visible"),O.setAttribute("data-focus-visible-added",""))}function u(O){O.hasAttribute("data-focus-visible-added")&&(O.classList.remove("focus-visible"),O.removeAttribute("data-focus-visible-added"))}function p(O){O.metaKey||O.altKey||O.ctrlKey||(a(r.activeElement)&&c(r.activeElement),n=!0)}function m(O){n=!1}function d(O){a(O.target)&&(n||f(O.target))&&c(O.target)}function h(O){a(O.target)&&(O.target.classList.contains("focus-visible")||O.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),u(O.target))}function v(O){document.visibilityState==="hidden"&&(o&&(n=!0),Q())}function Q(){document.addEventListener("mousemove",N),document.addEventListener("mousedown",N),document.addEventListener("mouseup",N),document.addEventListener("pointermove",N),document.addEventListener("pointerdown",N),document.addEventListener("pointerup",N),document.addEventListener("touchmove",N),document.addEventListener("touchstart",N),document.addEventListener("touchend",N)}function B(){document.removeEventListener("mousemove",N),document.removeEventListener("mousedown",N),document.removeEventListener("mouseup",N),document.removeEventListener("pointermove",N),document.removeEventListener("pointerdown",N),document.removeEventListener("pointerup",N),document.removeEventListener("touchmove",N),document.removeEventListener("touchstart",N),document.removeEventListener("touchend",N)}function N(O){O.target.nodeName&&O.target.nodeName.toLowerCase()==="html"||(n=!1,B())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",m,!0),document.addEventListener("pointerdown",m,!0),document.addEventListener("touchstart",m,!0),document.addEventListener("visibilitychange",v,!0),Q(),r.addEventListener("focus",d,!0),r.addEventListener("blur",h,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var cn=Pt(Er=>{(function(e){var t=function(){try{return!!Symbol.iterator}catch(c){return!1}},r=t(),n=function(c){var u={next:function(){var p=c.shift();return{done:p===void 0,value:p}}};return r&&(u[Symbol.iterator]=function(){return u}),u},o=function(c){return encodeURIComponent(c).replace(/%20/g,"+")},i=function(c){return decodeURIComponent(String(c).replace(/\+/g," "))},s=function(){var c=function(p){Object.defineProperty(this,"_entries",{writable:!0,value:{}});var m=typeof p;if(m!=="undefined")if(m==="string")p!==""&&this._fromString(p);else if(p instanceof c){var d=this;p.forEach(function(B,N){d.append(N,B)})}else if(p!==null&&m==="object")if(Object.prototype.toString.call(p)==="[object Array]")for(var h=0;hd[0]?1:0}),c._entries&&(c._entries={});for(var p=0;p1?i(d[1]):"")}})})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Er);(function(e){var t=function(){try{var o=new e.URL("b","http://a");return o.pathname="c d",o.href==="http://a/c%20d"&&o.searchParams}catch(i){return!1}},r=function(){var o=e.URL,i=function(f,c){typeof f!="string"&&(f=String(f)),c&&typeof c!="string"&&(c=String(c));var u=document,p;if(c&&(e.location===void 0||c!==e.location.href)){c=c.toLowerCase(),u=document.implementation.createHTMLDocument(""),p=u.createElement("base"),p.href=c,u.head.appendChild(p);try{if(p.href.indexOf(c)!==0)throw new Error(p.href)}catch(O){throw new Error("URL unable to set base "+c+" due to "+O)}}var m=u.createElement("a");m.href=f,p&&(u.body.appendChild(m),m.href=m.href);var d=u.createElement("input");if(d.type="url",d.value=f,m.protocol===":"||!/:/.test(m.href)||!d.checkValidity()&&!c)throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:m});var h=new e.URLSearchParams(this.search),v=!0,Q=!0,B=this;["append","delete","set"].forEach(function(O){var Qe=h[O];h[O]=function(){Qe.apply(h,arguments),v&&(Q=!1,B.search=h.toString(),Q=!0)}}),Object.defineProperty(this,"searchParams",{value:h,enumerable:!0});var N=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==N&&(N=this.search,Q&&(v=!1,this.searchParams._fromString(this.search),v=!0))}})},s=i.prototype,a=function(f){Object.defineProperty(s,f,{get:function(){return this._anchorElement[f]},set:function(c){this._anchorElement[f]=c},enumerable:!0})};["hash","host","hostname","port","protocol"].forEach(function(f){a(f)}),Object.defineProperty(s,"search",{get:function(){return this._anchorElement.search},set:function(f){this._anchorElement.search=f,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(s,{toString:{get:function(){var f=this;return function(){return f.href}}},href:{get:function(){return this._anchorElement.href.replace(/\?$/,"")},set:function(f){this._anchorElement.href=f,this._updateSearchParams()},enumerable:!0},pathname:{get:function(){return this._anchorElement.pathname.replace(/(^\/?)/,"/")},set:function(f){this._anchorElement.pathname=f},enumerable:!0},origin:{get:function(){var f={"http:":80,"https:":443,"ftp:":21}[this._anchorElement.protocol],c=this._anchorElement.port!=f&&this._anchorElement.port!=="";return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(c?":"+this._anchorElement.port:"")},enumerable:!0},password:{get:function(){return""},set:function(f){},enumerable:!0},username:{get:function(){return""},set:function(f){},enumerable:!0}}),i.createObjectURL=function(f){return o.createObjectURL.apply(o,arguments)},i.revokeObjectURL=function(f){return o.revokeObjectURL.apply(o,arguments)},e.URL=i};if(t()||r(),e.location!==void 0&&!("origin"in e.location)){var n=function(){return e.location.protocol+"//"+e.location.hostname+(e.location.port?":"+e.location.port:"")};try{Object.defineProperty(e.location,"origin",{get:n,enumerable:!0})}catch(o){setInterval(function(){e.location.origin=n()},100)}}})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Er)});var qr=Pt((Mt,Nr)=>{/*! - * clipboard.js v2.0.11 - * https://clipboardjs.com/ - * - * Licensed MIT © Zeno Rocha - */(function(t,r){typeof Mt=="object"&&typeof Nr=="object"?Nr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Mt=="object"?Mt.ClipboardJS=r():t.ClipboardJS=r()})(Mt,function(){return function(){var e={686:function(n,o,i){"use strict";i.d(o,{default:function(){return Ai}});var s=i(279),a=i.n(s),f=i(370),c=i.n(f),u=i(817),p=i.n(u);function m(j){try{return document.execCommand(j)}catch(T){return!1}}var d=function(T){var E=p()(T);return m("cut"),E},h=d;function v(j){var T=document.documentElement.getAttribute("dir")==="rtl",E=document.createElement("textarea");E.style.fontSize="12pt",E.style.border="0",E.style.padding="0",E.style.margin="0",E.style.position="absolute",E.style[T?"right":"left"]="-9999px";var H=window.pageYOffset||document.documentElement.scrollTop;return E.style.top="".concat(H,"px"),E.setAttribute("readonly",""),E.value=j,E}var Q=function(T,E){var H=v(T);E.container.appendChild(H);var I=p()(H);return m("copy"),H.remove(),I},B=function(T){var E=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},H="";return typeof T=="string"?H=Q(T,E):T instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(T==null?void 0:T.type)?H=Q(T.value,E):(H=p()(T),m("copy")),H},N=B;function O(j){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?O=function(E){return typeof E}:O=function(E){return E&&typeof Symbol=="function"&&E.constructor===Symbol&&E!==Symbol.prototype?"symbol":typeof E},O(j)}var Qe=function(){var T=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},E=T.action,H=E===void 0?"copy":E,I=T.container,q=T.target,Me=T.text;if(H!=="copy"&&H!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(q!==void 0)if(q&&O(q)==="object"&&q.nodeType===1){if(H==="copy"&&q.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(H==="cut"&&(q.hasAttribute("readonly")||q.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Me)return N(Me,{container:I});if(q)return H==="cut"?h(q):N(q,{container:I})},De=Qe;function $e(j){return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?$e=function(E){return typeof E}:$e=function(E){return E&&typeof Symbol=="function"&&E.constructor===Symbol&&E!==Symbol.prototype?"symbol":typeof E},$e(j)}function Ei(j,T){if(!(j instanceof T))throw new TypeError("Cannot call a class as a function")}function tn(j,T){for(var E=0;E0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof I.action=="function"?I.action:this.defaultAction,this.target=typeof I.target=="function"?I.target:this.defaultTarget,this.text=typeof I.text=="function"?I.text:this.defaultText,this.container=$e(I.container)==="object"?I.container:document.body}},{key:"listenClick",value:function(I){var q=this;this.listener=c()(I,"click",function(Me){return q.onClick(Me)})}},{key:"onClick",value:function(I){var q=I.delegateTarget||I.currentTarget,Me=this.action(q)||"copy",kt=De({action:Me,container:this.container,target:this.target(q),text:this.text(q)});this.emit(kt?"success":"error",{action:Me,text:kt,trigger:q,clearSelection:function(){q&&q.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(I){return vr("action",I)}},{key:"defaultTarget",value:function(I){var q=vr("target",I);if(q)return document.querySelector(q)}},{key:"defaultText",value:function(I){return vr("text",I)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(I){var q=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return N(I,q)}},{key:"cut",value:function(I){return h(I)}},{key:"isSupported",value:function(){var I=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],q=typeof I=="string"?[I]:I,Me=!!document.queryCommandSupported;return q.forEach(function(kt){Me=Me&&!!document.queryCommandSupported(kt)}),Me}}]),E}(a()),Ai=Li},828:function(n){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function s(a,f){for(;a&&a.nodeType!==o;){if(typeof a.matches=="function"&&a.matches(f))return a;a=a.parentNode}}n.exports=s},438:function(n,o,i){var s=i(828);function a(u,p,m,d,h){var v=c.apply(this,arguments);return u.addEventListener(m,v,h),{destroy:function(){u.removeEventListener(m,v,h)}}}function f(u,p,m,d,h){return typeof u.addEventListener=="function"?a.apply(null,arguments):typeof m=="function"?a.bind(null,document).apply(null,arguments):(typeof u=="string"&&(u=document.querySelectorAll(u)),Array.prototype.map.call(u,function(v){return a(v,p,m,d,h)}))}function c(u,p,m,d){return function(h){h.delegateTarget=s(h.target,p),h.delegateTarget&&d.call(u,h)}}n.exports=f},879:function(n,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var s=Object.prototype.toString.call(i);return i!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}},370:function(n,o,i){var s=i(879),a=i(438);function f(m,d,h){if(!m&&!d&&!h)throw new Error("Missing required arguments");if(!s.string(d))throw new TypeError("Second argument must be a String");if(!s.fn(h))throw new TypeError("Third argument must be a Function");if(s.node(m))return c(m,d,h);if(s.nodeList(m))return u(m,d,h);if(s.string(m))return p(m,d,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(m,d,h){return m.addEventListener(d,h),{destroy:function(){m.removeEventListener(d,h)}}}function u(m,d,h){return Array.prototype.forEach.call(m,function(v){v.addEventListener(d,h)}),{destroy:function(){Array.prototype.forEach.call(m,function(v){v.removeEventListener(d,h)})}}}function p(m,d,h){return a(document.body,m,d,h)}n.exports=f},817:function(n){function o(i){var s;if(i.nodeName==="SELECT")i.focus(),s=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var a=i.hasAttribute("readonly");a||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),a||i.removeAttribute("readonly"),s=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var f=window.getSelection(),c=document.createRange();c.selectNodeContents(i),f.removeAllRanges(),f.addRange(c),s=f.toString()}return s}n.exports=o},279:function(n){function o(){}o.prototype={on:function(i,s,a){var f=this.e||(this.e={});return(f[i]||(f[i]=[])).push({fn:s,ctx:a}),this},once:function(i,s,a){var f=this;function c(){f.off(i,c),s.apply(a,arguments)}return c._=s,this.on(i,c,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),f=0,c=a.length;for(f;f{"use strict";/*! - * escape-html - * Copyright(c) 2012-2013 TJ Holowaychuk - * Copyright(c) 2015 Andreas Lubbe - * Copyright(c) 2015 Tiancheng "Timothy" Gu - * MIT Licensed - */var rs=/["'&<>]/;Yo.exports=ns;function ns(e){var t=""+e,r=rs.exec(t);if(!r)return t;var n,o="",i=0,s=0;for(i=r.index;i0&&i[i.length-1])&&(c[0]===6||c[0]===2)){r=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function W(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var n=r.call(e),o,i=[],s;try{for(;(t===void 0||t-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(a){s={error:a}}finally{try{o&&!o.done&&(r=n.return)&&r.call(n)}finally{if(s)throw s.error}}return i}function D(e,t,r){if(r||arguments.length===2)for(var n=0,o=t.length,i;n1||a(m,d)})})}function a(m,d){try{f(n[m](d))}catch(h){p(i[0][3],h)}}function f(m){m.value instanceof et?Promise.resolve(m.value.v).then(c,u):p(i[0][2],m)}function c(m){a("next",m)}function u(m){a("throw",m)}function p(m,d){m(d),i.shift(),i.length&&a(i[0][0],i[0][1])}}function pn(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof Ee=="function"?Ee(e):e[Symbol.iterator](),r={},n("next"),n("throw"),n("return"),r[Symbol.asyncIterator]=function(){return this},r);function n(i){r[i]=e[i]&&function(s){return new Promise(function(a,f){s=e[i](s),o(a,f,s.done,s.value)})}}function o(i,s,a,f){Promise.resolve(f).then(function(c){i({value:c,done:a})},s)}}function C(e){return typeof e=="function"}function at(e){var t=function(n){Error.call(n),n.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var It=at(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: -`+r.map(function(n,o){return o+1+") "+n.toString()}).join(` - `):"",this.name="UnsubscriptionError",this.errors=r}});function Ve(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Ie=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,n,o,i;if(!this.closed){this.closed=!0;var s=this._parentage;if(s)if(this._parentage=null,Array.isArray(s))try{for(var a=Ee(s),f=a.next();!f.done;f=a.next()){var c=f.value;c.remove(this)}}catch(v){t={error:v}}finally{try{f&&!f.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}else s.remove(this);var u=this.initialTeardown;if(C(u))try{u()}catch(v){i=v instanceof It?v.errors:[v]}var p=this._finalizers;if(p){this._finalizers=null;try{for(var m=Ee(p),d=m.next();!d.done;d=m.next()){var h=d.value;try{ln(h)}catch(v){i=i!=null?i:[],v instanceof It?i=D(D([],W(i)),W(v.errors)):i.push(v)}}}catch(v){n={error:v}}finally{try{d&&!d.done&&(o=m.return)&&o.call(m)}finally{if(n)throw n.error}}}if(i)throw new It(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)ln(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Ve(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Ve(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Sr=Ie.EMPTY;function jt(e){return e instanceof Ie||e&&"closed"in e&&C(e.remove)&&C(e.add)&&C(e.unsubscribe)}function ln(e){C(e)?e():e.unsubscribe()}var Le={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var st={setTimeout:function(e,t){for(var r=[],n=2;n0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var n=this,o=this,i=o.hasError,s=o.isStopped,a=o.observers;return i||s?Sr:(this.currentObservers=null,a.push(r),new Ie(function(){n.currentObservers=null,Ve(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,s=n.isStopped;o?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new F;return r.source=this,r},t.create=function(r,n){return new xn(r,n)},t}(F);var xn=function(e){ie(t,e);function t(r,n){var o=e.call(this)||this;return o.destination=r,o.source=n,o}return t.prototype.next=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.next)===null||o===void 0||o.call(n,r)},t.prototype.error=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.error)===null||o===void 0||o.call(n,r)},t.prototype.complete=function(){var r,n;(n=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||n===void 0||n.call(r)},t.prototype._subscribe=function(r){var n,o;return(o=(n=this.source)===null||n===void 0?void 0:n.subscribe(r))!==null&&o!==void 0?o:Sr},t}(x);var Et={now:function(){return(Et.delegate||Date).now()},delegate:void 0};var wt=function(e){ie(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=Et);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=n,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=n===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,n),i}return t.prototype.next=function(r){var n=this,o=n.isStopped,i=n._buffer,s=n._infiniteTimeWindow,a=n._timestampProvider,f=n._windowTime;o||(i.push(r),!s&&i.push(a.now()+f)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var n=this._innerSubscribe(r),o=this,i=o._infiniteTimeWindow,s=o._buffer,a=s.slice(),f=0;f0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=ut.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){var i;if(o===void 0&&(o=0),o!=null?o>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);var s=r.actions;n!=null&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==n&&(ut.cancelAnimationFrame(n),r._scheduled=void 0)},t}(Wt);var Sn=function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var n=this._scheduled;this._scheduled=void 0;var o=this.actions,i;r=r||o.shift();do if(i=r.execute(r.state,r.delay))break;while((r=o[0])&&r.id===n&&o.shift());if(this._active=!1,i){for(;(r=o[0])&&r.id===n&&o.shift();)r.unsubscribe();throw i}},t}(Dt);var Oe=new Sn(wn);var _=new F(function(e){return e.complete()});function Vt(e){return e&&C(e.schedule)}function Cr(e){return e[e.length-1]}function Ye(e){return C(Cr(e))?e.pop():void 0}function Te(e){return Vt(Cr(e))?e.pop():void 0}function zt(e,t){return typeof Cr(e)=="number"?e.pop():t}var pt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Nt(e){return C(e==null?void 0:e.then)}function qt(e){return C(e[ft])}function Kt(e){return Symbol.asyncIterator&&C(e==null?void 0:e[Symbol.asyncIterator])}function Qt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function zi(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Yt=zi();function Gt(e){return C(e==null?void 0:e[Yt])}function Bt(e){return un(this,arguments,function(){var r,n,o,i;return $t(this,function(s){switch(s.label){case 0:r=e.getReader(),s.label=1;case 1:s.trys.push([1,,9,10]),s.label=2;case 2:return[4,et(r.read())];case 3:return n=s.sent(),o=n.value,i=n.done,i?[4,et(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,et(o)];case 6:return[4,s.sent()];case 7:return s.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function Jt(e){return C(e==null?void 0:e.getReader)}function U(e){if(e instanceof F)return e;if(e!=null){if(qt(e))return Ni(e);if(pt(e))return qi(e);if(Nt(e))return Ki(e);if(Kt(e))return On(e);if(Gt(e))return Qi(e);if(Jt(e))return Yi(e)}throw Qt(e)}function Ni(e){return new F(function(t){var r=e[ft]();if(C(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function qi(e){return new F(function(t){for(var r=0;r=2;return function(n){return n.pipe(e?A(function(o,i){return e(o,i,n)}):de,ge(1),r?He(t):Dn(function(){return new Zt}))}}function Vn(){for(var e=[],t=0;t=2,!0))}function pe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new x}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,f=a===void 0?!0:a;return function(c){var u,p,m,d=0,h=!1,v=!1,Q=function(){p==null||p.unsubscribe(),p=void 0},B=function(){Q(),u=m=void 0,h=v=!1},N=function(){var O=u;B(),O==null||O.unsubscribe()};return y(function(O,Qe){d++,!v&&!h&&Q();var De=m=m!=null?m:r();Qe.add(function(){d--,d===0&&!v&&!h&&(p=$r(N,f))}),De.subscribe(Qe),!u&&d>0&&(u=new rt({next:function($e){return De.next($e)},error:function($e){v=!0,Q(),p=$r(B,o,$e),De.error($e)},complete:function(){h=!0,Q(),p=$r(B,s),De.complete()}}),U(O).subscribe(u))})(c)}}function $r(e,t){for(var r=[],n=2;ne.next(document)),e}function K(e,t=document){return Array.from(t.querySelectorAll(e))}function z(e,t=document){let r=ce(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function ce(e,t=document){return t.querySelector(e)||void 0}function _e(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}function tr(e){return L(b(document.body,"focusin"),b(document.body,"focusout")).pipe(ke(1),l(()=>{let t=_e();return typeof t!="undefined"?e.contains(t):!1}),V(e===_e()),J())}function Xe(e){return{x:e.offsetLeft,y:e.offsetTop}}function Kn(e){return L(b(window,"load"),b(window,"resize")).pipe(Ce(0,Oe),l(()=>Xe(e)),V(Xe(e)))}function rr(e){return{x:e.scrollLeft,y:e.scrollTop}}function dt(e){return L(b(e,"scroll"),b(window,"resize")).pipe(Ce(0,Oe),l(()=>rr(e)),V(rr(e)))}var Yn=function(){if(typeof Map!="undefined")return Map;function e(t,r){var n=-1;return t.some(function(o,i){return o[0]===r?(n=i,!0):!1}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(r){var n=e(this.__entries__,r),o=this.__entries__[n];return o&&o[1]},t.prototype.set=function(r,n){var o=e(this.__entries__,r);~o?this.__entries__[o][1]=n:this.__entries__.push([r,n])},t.prototype.delete=function(r){var n=this.__entries__,o=e(n,r);~o&&n.splice(o,1)},t.prototype.has=function(r){return!!~e(this.__entries__,r)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(r,n){n===void 0&&(n=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!Wr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),va?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!Wr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var r=t.propertyName,n=r===void 0?"":r,o=ba.some(function(i){return!!~n.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),Gn=function(e,t){for(var r=0,n=Object.keys(t);r0},e}(),Jn=typeof WeakMap!="undefined"?new WeakMap:new Yn,Xn=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var r=ga.getInstance(),n=new La(t,r,this);Jn.set(this,n)}return e}();["observe","unobserve","disconnect"].forEach(function(e){Xn.prototype[e]=function(){var t;return(t=Jn.get(this))[e].apply(t,arguments)}});var Aa=function(){return typeof nr.ResizeObserver!="undefined"?nr.ResizeObserver:Xn}(),Zn=Aa;var eo=new x,Ca=$(()=>k(new Zn(e=>{for(let t of e)eo.next(t)}))).pipe(g(e=>L(ze,k(e)).pipe(R(()=>e.disconnect()))),X(1));function he(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ye(e){return Ca.pipe(S(t=>t.observe(e)),g(t=>eo.pipe(A(({target:r})=>r===e),R(()=>t.unobserve(e)),l(()=>he(e)))),V(he(e)))}function bt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function ar(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var to=new x,Ra=$(()=>k(new IntersectionObserver(e=>{for(let t of e)to.next(t)},{threshold:0}))).pipe(g(e=>L(ze,k(e)).pipe(R(()=>e.disconnect()))),X(1));function sr(e){return Ra.pipe(S(t=>t.observe(e)),g(t=>to.pipe(A(({target:r})=>r===e),R(()=>t.unobserve(e)),l(({isIntersecting:r})=>r))))}function ro(e,t=16){return dt(e).pipe(l(({y:r})=>{let n=he(e),o=bt(e);return r>=o.height-n.height-t}),J())}var cr={drawer:z("[data-md-toggle=drawer]"),search:z("[data-md-toggle=search]")};function no(e){return cr[e].checked}function Ke(e,t){cr[e].checked!==t&&cr[e].click()}function Ue(e){let t=cr[e];return b(t,"change").pipe(l(()=>t.checked),V(t.checked))}function ka(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ha(){return L(b(window,"compositionstart").pipe(l(()=>!0)),b(window,"compositionend").pipe(l(()=>!1))).pipe(V(!1))}function oo(){let e=b(window,"keydown").pipe(A(t=>!(t.metaKey||t.ctrlKey)),l(t=>({mode:no("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),A(({mode:t,type:r})=>{if(t==="global"){let n=_e();if(typeof n!="undefined")return!ka(n,r)}return!0}),pe());return Ha().pipe(g(t=>t?_:e))}function le(){return new URL(location.href)}function ot(e){location.href=e.href}function io(){return new x}function ao(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)ao(e,r)}function M(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="undefined"&&(typeof t[o]!="boolean"?n.setAttribute(o,t[o]):n.setAttribute(o,""));for(let o of r)ao(n,o);return n}function fr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function so(){return location.hash.substring(1)}function Dr(e){let t=M("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Pa(e){return L(b(window,"hashchange"),e).pipe(l(so),V(so()),A(t=>t.length>0),X(1))}function co(e){return Pa(e).pipe(l(t=>ce(`[id="${t}"]`)),A(t=>typeof t!="undefined"))}function Vr(e){let t=matchMedia(e);return er(r=>t.addListener(()=>r(t.matches))).pipe(V(t.matches))}function fo(){let e=matchMedia("print");return L(b(window,"beforeprint").pipe(l(()=>!0)),b(window,"afterprint").pipe(l(()=>!1))).pipe(V(e.matches))}function zr(e,t){return e.pipe(g(r=>r?t():_))}function ur(e,t={credentials:"same-origin"}){return ue(fetch(`${e}`,t)).pipe(fe(()=>_),g(r=>r.status!==200?Ot(()=>new Error(r.statusText)):k(r)))}function We(e,t){return ur(e,t).pipe(g(r=>r.json()),X(1))}function uo(e,t){let r=new DOMParser;return ur(e,t).pipe(g(n=>n.text()),l(n=>r.parseFromString(n,"text/xml")),X(1))}function pr(e){let t=M("script",{src:e});return $(()=>(document.head.appendChild(t),L(b(t,"load"),b(t,"error").pipe(g(()=>Ot(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(l(()=>{}),R(()=>document.head.removeChild(t)),ge(1))))}function po(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function lo(){return L(b(window,"scroll",{passive:!0}),b(window,"resize",{passive:!0})).pipe(l(po),V(po()))}function mo(){return{width:innerWidth,height:innerHeight}}function ho(){return b(window,"resize",{passive:!0}).pipe(l(mo),V(mo()))}function bo(){return Y([lo(),ho()]).pipe(l(([e,t])=>({offset:e,size:t})),X(1))}function lr(e,{viewport$:t,header$:r}){let n=t.pipe(ee("size")),o=Y([n,r]).pipe(l(()=>Xe(e)));return Y([r,t,o]).pipe(l(([{height:i},{offset:s,size:a},{x:f,y:c}])=>({offset:{x:s.x-f,y:s.y-c+i},size:a})))}(()=>{function e(n,o){parent.postMessage(n,o||"*")}function t(...n){return n.reduce((o,i)=>o.then(()=>new Promise(s=>{let a=document.createElement("script");a.src=i,a.onload=s,document.body.appendChild(a)})),Promise.resolve())}var r=class extends EventTarget{constructor(n){super(),this.url=n,this.m=i=>{i.source===this.w&&(this.dispatchEvent(new MessageEvent("message",{data:i.data})),this.onmessage&&this.onmessage(i))},this.e=(i,s,a,f,c)=>{if(s===`${this.url}`){let u=new ErrorEvent("error",{message:i,filename:s,lineno:a,colno:f,error:c});this.dispatchEvent(u),this.onerror&&this.onerror(u)}};let o=document.createElement("iframe");o.hidden=!0,document.body.appendChild(this.iframe=o),this.w.document.open(),this.w.document.write(` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Blog

- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/components/css/attributes.html b/docs/components/css/attributes.html deleted file mode 100644 index 1e107b6..0000000 --- a/docs/components/css/attributes.html +++ /dev/null @@ -1,1032 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Attributes - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Attributes of CSS Components

-

Attributes

-

properties

-

properties is a dictionary that contains all the properties of a CSS component. It is a required attribute of a Selector element. You have to pass a dictionary to this attribute. The keys of the dictionary are the properties of the CSS component and the values of the dictionary are the values of the properties. Here is an example:

-
Example of properties attribute
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
from fronty.css import CSS, Selector, Style
-
-css = CSS(
-    Selector('body')
-    .properties({
-        "background-color": "red",
-        "color": "white",
-        "font-size": "20px",
-        "font-weight": "bold",
-        "padding": "10px",
-        "border-radius": "5px",
-        "border": "1px solid black"
-    })
-)
-
-print(css.render())
-
-

Output:

-
Output of the above code
body{background-color:red;color:white;font-size:20px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}
-
-

Fronty returns every frontend code minified for better performance.

- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/components/css/introduction.html b/docs/components/css/introduction.html deleted file mode 100644 index d158038..0000000 --- a/docs/components/css/introduction.html +++ /dev/null @@ -1,1284 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Introduction - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

CSS Components

-

What are CSS Components?

-

CSS components are a list of dictionary that can be used to create a CSS styling fast and easily. These components are very easy to use and can be used to create a CSS styling in a few lines of code. Here is lots of customization options are available. Let's get started.

-

Important CSS Components

-

CSS : To create a css in a html website.

-

Selector : To create a selector in a html website. It is like query selector in JavaScript.

-

Style : To create a style in a html website.

-

Using CSS Components

-

To use CSS components, you have to import the fronty.css module methods. CSS, Selector and Style are the methods of fronty.css module. Here is an example of using fronty.css module methods:

-
Example of importing fronty.css module
1
-2
-3
-4
-5
-6
-7
from fronty.css import CSS, Selector, Style
-
-css = CSS(
-    Selector('body')
-)
-
-print(css.render())
-
-

With this you can create a selector in a html website. But it is not enough to create a css file. You have to add some properties to the selector. To add properties to the selector, you have to use the properties attribute of the Selector element. Here is an example:

-
Example of properties attribute
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
from fronty.css import CSS, Selector, Style
-
-css = CSS(
-    Selector('body')
-    .properties({
-        "background-color": "red",
-        "color": "white",
-        "font-size": "20px",
-        "font-weight": "bold",
-        "padding": "10px",
-        "border-radius": "5px",
-        "border": "1px solid black"
-    })
-)
-
-print(css.render())
-
-

Output:

-
Output of the above code
body{background-color:red;color:white;font-size:20px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}
-
-

Here we have provided a dictionary in properties method of Selector class. The keys of the dictionary are the properties of the CSS component and the values of the dictionary are the values of the properties. You can add as many properties as you want. You can also add multiple selectors in a CSS file. Here is an example:

-
Example of multiple selectors
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
from fronty.css import CSS, Selector, Style
-
-css = CSS(
-    Selector('body')
-    .properties({
-        "background-color": "red",
-        "color": "white",
-        "font-size": "20px",
-        "font-weight": "bold",
-        "padding": "10px",
-        "border-radius": "5px",
-        "border": "1px solid black"
-    }),
-    Selector('h1')
-    .properties({
-        "color": "blue",
-        "font-size": "30px",
-        "font-weight": "bold",
-        "padding": "10px",
-        "border-radius": "5px",
-        "border": "1px solid black"
-    })
-)
-
-print(css.render())
-
-

Output:

-
Output of the above code
body{background-color:red;color:white;font-size:20px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}h1{color:blue;font-size:30px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}
-
-

You can also add multiple properties in a selector. Here is an example:

-
Example of multiple properties
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
from fronty.css import CSS, Selector, Style
-
-css = CSS(
-    Selector('body')
-    .properties({
-        "background-color": "red",
-        "color": "white",
-        "font-size": "20px",
-        "font-weight": "bold",
-        "padding": "10px",
-        "border-radius": "5px",
-        "border": "1px solid black"
-    })
-    .properties({
-        "color": "blue",
-        "font-size": "30px",
-        "font-weight": "bold",
-        "padding": "10px",
-        "border-radius": "5px",
-        "border": "1px solid black"
-    })
-)
-
-print(css.render())
-
-

Output:

-
Output of the above code
body{background-color:red;color:blue;font-size:30px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}
-
-

Here we can see, only the unique properties are added to the selector and the duplicate properties are overwritten with the new properties.

-

Using Style Component

-

You can also use the Style component to create a CSS file. Here is an example:

-
Example of Style component
1
-2
-3
-4
-5
-6
-7
-8
-9
from fronty.css import CSS, Selector
-from fronty.html import Style
-
-css = CSS(
-    Style('body{background-color:red;color:white;font-size:20px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}'),
-    Style('h1{color:blue;font-size:30px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}')
-)
-
-print(css.render())
-
-

Output:

-
Output of the above code
<style type="text/css" href="" rel="stylesheet">body{background-color:red;color:white;font-size:20px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}</style><style type="text/css" href="" rel="stylesheet">h1{color:blue;font-size:30px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}</style>
-
-

This is very unrealistic to create a style component like this. But you can use this method to add a CSS to your website. Here is an example:

-
Example of Style component
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
from fronty.css import CSS, Selector
-from fronty.html import Html, Head, Title, Meta, Style, Body, H1
-
-css = CSS(
-    Selector('body')
-    .properties({
-        "background-color": "red",
-        "color": "white",
-        "font-size": "20px",
-        "font-weight": "bold",
-        "padding": "10px",
-        "border-radius": "5px",
-        "border": "1px solid black"
-    }),
-    Selector('h1')
-    .properties({
-        "color": "blue",
-        "font-size": "30px",
-        "font-weight": "bold",
-        "padding": "10px",
-        "border-radius": "5px",
-        "border": "1px solid black"
-    }),
-)
-
-...
-# Now we will add the style component to the html component
-
-html = Html(
-    Head(
-        Title('My Website'),
-        Meta(charset="UTF-8"),
-        Meta(name="viewport", content="width=device-width, initial-scale=1.0"),
-        Style(css.render())
-    ),
-    Body(
-        H1('Hello World')
-    )
-)
-
-print(html.render())
-
-

Output:

-
Output of the above code
<!DOCTYPE html><html><head><title>My Website</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><style type="text/css" href="" rel="stylesheet">body{background-color:red;color:white;font-size:20px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}h1{color:blue;font-size:30px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}</style></head><body><h1>Hello World</h1></body></html>
-
-

This is how you can add a CSS to your website fast, easily and efficiently with Style component.

- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/components/html/attributes.html b/docs/components/html/attributes.html deleted file mode 100644 index ca99325..0000000 --- a/docs/components/html/attributes.html +++ /dev/null @@ -1,1172 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Attributes - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Attributes of Component Elements

-

Attributes

-

The attributes of the component elements are the same as the attributes of the html elements. You can use the attributes of the html elements in the component elements. Check the attributes of the html elements.

-

Important attributes

-

id

-

The id attribute is used to give a unique id to a component element. You can use this id to select the component element using JavaScript. Element().id('something') or Element(id='something') can be used to set the id of a component element.

-

class

-

The class attribute is used to give multiple classes to a component element. You can use the same method again to override the previous class. Element().class_('something1 something2 somethingNth') or Element(class='something1 something2 somethingNth') can be used to set the class of a component element. You can also use class_ instead of class to set the class of a component element as class is a reserved keyword in Python and every programming language.

-

placeholder

-

The placeholder attribute is used to set the placeholder of a field. Element().placeholder('something') or Element(placeholder='something') can be used to set the placeholder of a field. It is a method in the BaseElement class. You can use this any element that accepts the placeholder attribute as it is defined in the BaseElement class.

-

type

-

The type attribute is used to set the type of a field. Element().type('something') or Element(type='something') can be used to set the type of a field. It is a method in the BaseElement class. You can use this any element that accepts the type attribute as it is defined in the BaseElement class.

-

name

-

The name attribute is used to set the name of a field. Element().name('something') or Element(name='something') can be used to set the name of a field. It is a method in the BaseElement class. You can use this any element that accepts the name attribute as it is defined in the BaseElement class.

-

style

-

The style attribute is used to give inline CSS to a component element. You can use the same method again to override the previous style. Element().style(color='red', background_color='blue') can be used to set the style of a component element. This method takes keyword arguments as the CSS properties and their values. Some CSS properties have hyphen in their name. You can use underscore instead of hyphen in the name of the CSS properties. For example, background-color can be written as background_color.

-

attr

-

The attr attribute is used to give attributes to a component element. You can add as much as you need attributes to a component element. Element().attr('key', 'value').attr('more', 'more') can be used to set the attribute of a component element. This method takes two arguments as the key and value of the attribute.

-

required

-

The required attribute is used to make a input field required. Element().required can be used to make a input field required. It is just a property of the Input component element. You can use this any element that accepts the required attribute as it is defined in the BaseElement class.

-

disabled

-

The disabled attribute is used to make a input field disabled. Element().disabled can be used to make a input field disabled. It is just a property of the Input component element. You can use this any element that accepts the disabled attribute as it is defined in the BaseElement class.

-

readonly

-

The readonly attribute is used to make a input field readonly. Element().readonly can be used to make a input field readonly. It is just a property of the Input component element. You can use this any element that accepts the readonly attribute as it is defined in the BaseElement class.

-

value

-

The value attribute is used to set the value of a field. Element().value('something') or Element(value='something') can be used to set the value of a field. It is a method in the BaseElement class. You can use this any element that accepts the value attribute as it is defined in the BaseElement class.

- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/components/html/introduction.html b/docs/components/html/introduction.html deleted file mode 100644 index c15d65f..0000000 --- a/docs/components/html/introduction.html +++ /dev/null @@ -1,1062 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Introduction - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

HTML Components

-

What are HTML Components?

-

HTML components are some simple set of classes that can be used to create a HTML website fast and easily. These components are very easy to use and can be used to create a HTML website in a few lines of code. Try to create a HTML website using these components and you will see how easy it is to create a HTML website using these components. So, let's get started.

-

Built-in HTML Components

-

Html : To create the main HTML page layout.

-

Head : To create the head section of a html website.

-

Title: To describe the title of a website in the head section.

-

Meta : To describe all types of meta tags for SEO.

-

Body : To create the body structure of a html website.

-

Script: To load Javascript codes in fronty based website.

-

Style: To write custom CSS fronty.

-

Link : To load CSS codes in fronty based website.

-

Anchor : To create a anchor links in a html website.

-

Image : To load images in a html website.

-

Button : To create a button in a html website.

-

Input : To create a input field in a html website.

-

Text : To create a text in a html website.

-

Break : To create a break line in a html website.

-

Form : To create a form in a html website.

-

Div : To create a div in a html website.

-

Span : To create a span in a html website.

-

H1 : To create a h1 in a html website.

-

H2 : To create a h2 in a html website.

-

H3 : To create a h3 in a html website.

-

H4 : To create a h4 in a html website.

-

H5 : To create a h5 in a html website.

-

H6 : To create a h6 in a html website.

-

P : To create a p in a html website.

-

Ul : To create a ul in a html website.

-

Ol : To create a ol in a html website.

-

Li : To create a li in a html website.

-

Table : To create a table in a html website.

-

Tr : To create a tr in a html website.

-

Td : To create a td in a html website.

-

Th : To create a th in a html website.

-

Caption : To create a caption in a html website.

-

Thead : To create a thead in a html website.

-

Tbody : To create a tbody in a html website.

-

Tfoot : To create a tfoot in a html website.

-

Iframe : To create a iframe in a html website.

-

Audio : To create a audio in a html website.

-

Video : To create a video in a html website.

-

Source : To create a source in a html website.

-

Select : To create a select in a html website.

-

Option : To create a option in a html website.

-

Nav : To create a nav in a html website.

-

Header : To create a header in a html website.

-

Footer : To create a footer in a html website.

-

Section : To create a section in a html website.

-

Article : To create a article in a html website.

-

Aside : To create a aside in a html website.

-

Main : To create a main in a html website.

-

Figure : To create a figure in a html website.

-

Figcaption : To create a figcaption in a html website.

-

Dl : To create a dl in a html website.

-

Dt : To create a dt in a html website.

-

Dd : To create a dd in a html website.

-

Time : To create a time in a html website.

-

Mark : To create a mark in a html website.

-

Small : To create a small in a html website.

-

Strong : To create a strong in a html website.

-

Em : To create a em in a html website.

-

Code : To create a code in a html website.

-

Pre : To create a pre in a html website.

-

Blockquote : To create a blockquote in a html website.

-

Empty : To wrap multiple elements to return a single element.

-

Comment : To create a comment in a html website.

-

- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/components/introduction.html b/docs/components/introduction.html deleted file mode 100644 index 678a4b9..0000000 --- a/docs/components/introduction.html +++ /dev/null @@ -1,1011 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Introduction - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Components

-

What are Components?

-

Components are the building blocks of your application. They are reusable UI elements that can be composed together to build a UI. Components are also the unit of encapsulation for the UI, CSS, and behavior. Components for manipulating HTML, CSS, and JavaScript from Python code are provided by the fronty package. Components are created by subclassing the fronty.html.BaseElement class. We will learn more about components in the customizing components section.

-

Built-in Components

-

Fronty provides a set of built-in components that can be used to create a UI. These components are:

-

For JavaScript

-

Till now, there is no built-in component for JavaScript. But you can use the Script component to load JavaScript codes in your website from js file.

- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/components/js/introduction.html b/docs/components/js/introduction.html deleted file mode 100644 index dd0376f..0000000 --- a/docs/components/js/introduction.html +++ /dev/null @@ -1,968 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Introduction - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Javascript Components

-

What are Javascript Components?

- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/contribution.html b/docs/contribution.html deleted file mode 100644 index c6fb58c..0000000 --- a/docs/contribution.html +++ /dev/null @@ -1,917 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - Contribution - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Contribution

-

Pull requests are welcome. For any changes, please open an issue first to discuss what you would like to change.

-

Thanks for using Fronty!

- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/customization/customized-html.html b/docs/customization/customized-html.html deleted file mode 100644 index fe3d950..0000000 --- a/docs/customization/customized-html.html +++ /dev/null @@ -1,1013 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - HTML Customization - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Customizing Components

-

You can customize the built-in components or create your own components by subclassing the fronty.html.BaseElement class. Let's see how to create a custom component.

-
custom_components.py
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
from fronty.html import (
-    BaseElement,
-    Text
-)
-
-
-class CustomComponent(BaseElement):
-    def __init__(self, *children, **attributes):
-        super().__init__('custom-component', *children, **attributes)
-
-        # Optional attributes if you want to add any custom attributes
-        self._attributes['custom-attribute'] = 'custom-value'
-
-        # Optional children if you want to add any custom children
-        self._children = [
-            Text('This is a custom component.'),
-        ]
-
-

Now, you can use this component in your application.

-
main.py
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
from flask import Flask # or any other framework
-from fronty.html import (
-    Html,
-    Head,
-    Title,
-    Body,
-)
-from custom_components import CustomComponent # import the custom component
-
-app = Flask(__name__)
-
-def layout():
-    return Html(
-        Head(
-            Title('Custom Component')
-        ),
-        Body(
-            CustomComponent()
-        )
-    )
-
-
-@app.route('/')
-def home():
-    return layout().render()
-
-
-if __name__ == '__main__':
-    app.run(debug=True)
-
- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/examples.html b/docs/examples.html deleted file mode 100644 index 88282c9..0000000 --- a/docs/examples.html +++ /dev/null @@ -1,995 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Examples - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Example projects

-

Project URL: Starter project

-

Starter Project

-

Project URL: Bootstrap Integration

-

Bootstrap Integration

-

Project URL: Custom CSS Project

-

Custom CSS Project

-

Custom CSS Project

-

How to run the example projects?

-

You can easily run the example projects by cloning the Fronty repository and running the following commands in your terminal.

-
    -
  1. Clone the Fronty repository.
  2. -
  3. -

    Go to the examples/starter project directory.
    -

    cd fronty/examples/starter\ project
    -

    -
  4. -
  5. -

    Run the following command in your terminal. -

    python app.py
    -

    -
  6. -
  7. -

    Open your browser and go to http://localhost:5000 -Starter Project

    -
  8. -
  9. -

    You can also run the other example projects by going to their directories and running the same command.

    -
  10. -
  11. -

    Note: You have to install a backend server to run the project. Fronty does not provide a backend server. You can use any backend server you want. For example, you can use Flask. You can also use Fronty with Django. But you have to install Django first. For simplicity, we have used Flask in the example projects. We are woring on a backend server for Fronty. It will be available soon.

    -
  12. -
- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 2c1b4d5..0000000 --- a/docs/index.html +++ /dev/null @@ -1,1003 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Fronty

-

logo

-

-A frontend web framework for the web -

-

Created by Md. Almas Ali

-

pypi -Hits -Total downloads -This month downloads -license -stars

-
-

Documentation: https://almas-ali.github.io/fronty

-

Source Code: https://github.com/Almas-Ali/fronty

-
-

Fronty is a lightweight, fast, and easy-to-use Python-based frontend web framework that simplifies web development by allowing developers to create web pages using only Python. Its simple syntax and intuitive design make it an excellent option for beginners or developers who prefer working with Python.

-

The key features are:

-
    -
  • Python-based frontend web framework
  • -
  • No need to use HTML, CSS, or JavaScript (though you can if you want)
  • -
  • Simple and lightweight
  • -
  • Fast rendering times
  • -
  • Easy to use and customize
  • -
  • Can integrate with other Python libraries and frameworks, such as Flask, Django, FastAPI, etc.
  • -
  • Growing community with extensive documentation and resources.
  • -
-

Sponsors

-

No sponsors yet. Be the first one to sponsor this project. Become a sponsor

- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/installation.html b/docs/installation.html deleted file mode 100644 index 3a9bd5e..0000000 --- a/docs/installation.html +++ /dev/null @@ -1,926 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Installation - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Installation

-

You can easily install Fronty using pip. Just run the following command in your terminal.

-
pip install fronty
-
-

You can also install a backend framework to use with Fronty. For example, if you want to use Fronty with Flask, you can checkout flask documentation https://flask.palletsprojects.com/en/2.1.x/installation/

-

If you want to use Fronty with Django, you can checkout django documentation https://docs.djangoproject.com/en/4.2/topics/install/

-

If you want to use Fronty with FastAPI, you can checkout fastapi documentation https://fastapi.tiangolo.com/tutorial/first-steps/

-
-

Start learning Fronty by reading the documentation.

-

Want to contribute? Check out the Github project.

- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/projects/bootstrap-integration.html b/docs/projects/bootstrap-integration.html deleted file mode 100644 index c94bd1d..0000000 --- a/docs/projects/bootstrap-integration.html +++ /dev/null @@ -1,1299 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Bootstrap Integration - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Bootstrap Integration

-

Now, let's integrate Bootstrap into our project. We will use the Bootstrap CDN to load the Bootstrap CSS and JavaScript files.

-

First, we will create a new folder named components inside the project folder. Then, we will create a new component named layout.py inside the components folder.

-
project/components/layout.py
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
from fronty.html import *
-
-
-def navbar(request, **data) -> Element:
-    '''This is the navbar component'''
-
-    # The navbar layout
-    _layout = Nav(
-        Div(
-            Anchor(
-                'Fronty',
-                href='/',
-            ).class_('navbar-brand'),
-            Button(
-                Element('span').class_('navbar-toggler-icon'),
-
-            ).class_('navbar-toggler').attr('type', 'button').attr('data-bs-toggle', 'collapse').attr('data-bs-target', '#navbarScroll').attr('aria-controls', 'navbarScroll').attr('aria-expanded', 'false').attr('aria-label', 'Toggle navigation'),
-            Ul(
-                Li(
-                    Anchor(
-                        'Home',
-                        href='/',
-                    ).class_('nav-link active').attr('aria-current', 'page'),
-                ).class_('nav-item'),
-                Li(
-                    Anchor(
-                        'About',
-                        href='/about',
-                    ).class_('nav-link'),
-                ).class_('nav-item'),
-                Li(
-                    Anchor(
-                        'More',
-                        href='#',
-                    ).class_('nav-link dropdown-toggle').attr('role', 'button').attr('data-bs-toggle', 'dropdown').attr('aria-expanded', 'false'),
-                    Ul(
-                        Li(
-                            Anchor(
-                                'Action',
-                                href='#',
-                            ).class_('dropdown-item'),
-                        ),
-                        Li(
-                            Anchor(
-                                'Another action',
-                                href='#',
-                            ).class_('dropdown-item'),
-                        ),
-                        Li(
-                            Element('hr').class_('dropdown-divider'),
-                        ),
-                        Li(
-                            Anchor(
-                                'Something else here',
-                                href='#',
-                            ).class_('dropdown-item'),
-                        ),
-                    ).class_('dropdown-menu'),
-                ).class_('nav-item dropdown'),
-            ).class_('navbar-nav me-auto my-2 my-lg-0 navbar-nav-scroll').attr('style', '--bs-scroll-height: 100px;'),
-            Form(
-                Input(
-                    placeholder='Search',
-                    aria_label='Search',
-                ).class_('form-control me-2').attr('type', 'search'),
-                Button(
-                    'Search',
-                ).class_('btn btn-outline-success').attr('type', 'submit'),
-            ).class_('d-flex').attr('role', 'search'),
-
-        ).class_('container-fluid'),
-    ).class_('navbar navbar-expand-lg bg-body-tertiary')
-
-    return _layout
-
-
-def layout(request, **data) -> Html:
-    '''This is the layout component'''
-
-    # The main layout
-    return Html(
-        Head(
-            Title('Fronty'),  # Page title
-            Meta(charset='utf-8'),  # Character encoding
-            # Responsive design
-            Meta(name='viewport', content='width=device-width, initial-scale=1'),
-
-            # Bootstrap CSS
-            Link(rel='stylesheet', href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css',
-                 integrity='sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD', crossorigin='anonymous'),
-        ),
-
-        Body(
-
-            # Navbar
-            navbar(request),
-
-            # Main area of the page
-            # The main area of the page is passed as a parameter to the layout component.
-            # Get subcomponent from data or use default value
-            data.get('content', 'Empty content'),
-
-            # Bootstrap JS
-            Script(src='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js", integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN', crossorigin='anonymous'),
-        ),
-    )
-
-

Now, we will create a index.py file inside the components folder. This file will contain the home page component.

-
project/components/index.py
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
from fronty.html import (
-    Element,
-    Div,
-    H1,
-    Text,
-    Break
-)
-
-# components
-from components.layout import layout
-
-
-def home(request, **data) -> Element:
-    '''This is the home page component'''
-
-    _layout = layout(
-        request=request,
-        content=Div(
-            H1('Home'),
-
-            Text(
-                f"""
-                    Path: {request.path}
-                    {Break()}
-                    Method: {request.method}
-
-                """
-            ),
-
-        ).class_('container text-center')
-    )
-
-    return _layout
-
-
-# We have added the about inside the index.py file for simplicity.
-# You can create a new file for the about page component.
-def about(request, **data) -> Element:
-    '''This is the about page component'''
-
-    _layout = layout(
-        request=request,
-        content=Div(
-            H1('About'),
-        ).class_('container text-center')
-    )
-
-    return _layout
-
-

Now, we will update the app.py file to use the new components.

-
project/app.py
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
from flask import Flask, request
-from fronty.html import *
-
-# components
-from components.index import home, about
-
-app = Flask(__name__)
-
-
-@app.route('/')
-def index():
-    '''This is the home page view function'''
-
-    return home(
-        request=request,
-        title='A simple framework to build a website only with Python.',
-    ).render()
-
-
-@app.route('/about')
-def about_view():
-    '''This is the about page view function'''
-
-    return about(
-        request=request,
-        title='A simple framework to build a website only with Python.',
-    ).render()
-
-
-if __name__ == '__main__':
-    app.run(debug=True)
-
-

Now, we will run the project and open the home page in the browser.

-
python project/app.py
-
-

Visit http://127.0.0.1:5000 in your browser.

-

Project URL: Bootstrap Integration

-

Bootstrap Integration

- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/projects/custom-css-project.html b/docs/projects/custom-css-project.html deleted file mode 100644 index 00e4499..0000000 --- a/docs/projects/custom-css-project.html +++ /dev/null @@ -1,1214 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Custom CSS Project - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Custom CSS Project

-

Initially, we have created a basic HTML only project. Then we have integrated Bootstrap into our project. Now, we will create a custom CSS project. We will use only Python to create this project.

-

Let's create a new project directory named custom_css_project. Then create a new file named app.py inside the custom_css_project directory.

-

Now, we will create everything in side the app.py file.

-
custom_css_project/app.py
  1
-  2
-  3
-  4
-  5
-  6
-  7
-  8
-  9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
-100
-101
-102
-103
-104
-105
-106
-107
-108
-109
-110
-111
-112
-113
-114
-115
-116
-117
-118
-119
-120
-121
-122
-123
-124
-125
-126
-127
-128
-129
-130
-131
-132
-133
-134
-135
-136
-137
-138
-139
-140
-141
-142
-143
-144
-145
-146
from flask import Flask
-from fronty.html import *
-from fronty.css import *
-from datetime import date
-
-# CSS components
-
-def style_css():
-    '''This is the style component'''
-
-    # The CSS() is used to create a CSS object.
-    return CSS(
-
-        # The Selector() is used to create a CSS selector.
-        # Here we have used the universal selector to select all the elements.
-        # *{} means select all the elements.
-        # We have css properties inside the properties() method.
-        # Passed the css properties as keyword arguments.
-        # The properties() method returns a CSSProperties object.
-        Selector('*').properties({
-            'margin': '0',
-            'padding': '0',
-            'font-family': 'Roboto, sans-serif, Arial',
-        }),
-
-        # Here we have selected the body tag.
-        # We have used the Selector('body') to select the body tag.
-        # Selector('body').properties({}) is used to add css properties to the body tag.
-        Selector('body').properties({
-            'background-color': '#d6d6e7',
-        }),
-        Selector('nav').properties({
-            'background-color': '#484c7a',
-            'color': '#fff',
-            'padding': '20px',
-            'position': 'absolute',
-            'width': '80%',
-            'margin': '0 10%',
-            'top': '10px',
-            'border-radius': '12px'
-        }),
-        Selector('nav ul').properties({
-            'list-style': 'none',
-            'display': 'flex',
-            'flex-direction': 'row',
-            'justify-content': 'center',
-        }),
-        Selector('nav ul li').properties({
-            'margin': '0 10px'
-        }),
-        Selector('a').properties({
-            'text-decoration': 'none',
-            'color': '#fff',
-            'padding': '12px',
-            'border-radius': '12px',
-            'transition': 'all 0.3s ease-in-out',
-            'font-size': '18px',
-        }),
-        Selector('nav a:hover').properties({
-            'background-color': '#ddd',
-            'color': 'black',
-        }),
-        Selector('nav a:active').properties({
-            'background-color': '#4CAF50',
-            'color': 'white',
-        }),
-        Selector('.container').properties({
-            'margin': '90px 10%',
-            'width': '80%',
-            'text-align': 'center',
-            'padding': '20px',
-            'background-color': '#fff',
-            'border-radius': '12px',
-        }),
-        Selector('footer').properties({
-            'position': 'absolute',
-            'bottom': '10px',
-            'width': '80%',
-            'margin': '0 10%',
-            'border-radius': '12px',
-            'text-align': 'center',
-            'padding': '20px',
-            'background-color': '#484c7a',
-            'color': '#fff',
-            'font-size': '12px',
-        }),
-    )
-
-
-# Fronty components
-
-def layout(request, **data):
-    '''This is the layout component'''
-
-    # The Html() is used to create a HTML object.
-    return Html(
-        Head(
-            Title('Custom CSS Project'),
-            Meta(charset='UTF-8'),
-            Meta(content="IE=edge").attr('http-equiv', 'X-UA-Compatible'),
-            Meta(name='viewport', content='width=device-width, initial-scale=1.0'),
-            Style(
-                style_css().render(),
-            ),
-        ),
-        Body(
-            Nav(
-                Ul(
-                    Li(
-                        Anchor('Home', href='/'),
-                    ),
-                    Li(
-                        Anchor('About', href='/about'),
-                    )
-                )
-            ),
-            Div(
-                H1(
-                    'Custom CSS Project',
-                ),
-                Text(
-                    'This is a custom CSS project using Fronty.',
-                ),
-            ).class_('container'),
-            Footer(
-                f{date.today().year} Fronty',
-            ),
-        )
-    )
-
-
-app = Flask(__name__)
-
-
-@app.route('/')
-def home():
-    '''This is the home page view function'''
-
-    # The render() method is used to convert the python objects to HTML string.
-    return layout(
-        request=None,
-    ).render()
-
-
-if __name__ == '__main__':
-    app.run(debug=True)
-
- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/projects/starter-project.html b/docs/projects/starter-project.html deleted file mode 100644 index 193a52a..0000000 --- a/docs/projects/starter-project.html +++ /dev/null @@ -1,1042 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Starter Project - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Starter Project

-

For simplicity, we have created a starter project that you can use to get started with your own project. It is a simple project that contains a single page with a single component. It is a good starting point for your own project.

-
starter_project/app.py
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
-41
-42
-43
-44
-45
-46
-47
-48
-49
-50
-51
-52
-53
-54
-55
-56
-57
-58
-59
-60
-61
from flask import Flask, request
-from fronty.html import *
-
-app = Flask(__name__)
-
-
-def home(request) -> Html:
-    '''This is the home page view function'''
-
-    # The main HTML element.
-    return Html(
-
-        # The head tag contains the title and meta tags.
-        Head(
-
-            # The title tag contains the title of the page.
-            Title('Home'),
-
-            # The meta tags contain the meta information of the page.
-            Meta(charset='utf-8'),
-            Meta(name='viewport', content='width=device-width, initial-scale=1'),
-        ),
-
-        # The body tag contains all the content of the page.
-        Body(
-
-            # The center tag contains the main content of the page.
-            # It is like using a HTML element when you don't know whats the name of a tag in fronty.
-            # You can use the Element('tag') for this purpose.
-            Element(
-                'center',
-
-                # The h1 tag contains the title of the page.
-                H1(
-                    'Welcome to Fronty!'
-                ),
-
-                # The Text() is used to add text to the page like paragraphs.
-                Text(
-                    'Fronty is a frontend web framework.'
-                ),
-            )
-        )
-    )
-
-
-@app.route('/')
-def index() -> str:
-    '''This is the home page view function'''
-
-    # The render() method is used to convert the python objects to HTML string.
-    # The render() method returns a string. So, we can return it directly.
-    return home(
-        request=request,
-    ).render()
-
-
-if __name__ == '__main__':
-    # Run the app in debug mode.
-    # Learn more about Flask at https://flask.palletsprojects.com/en/2.1.x/
-    app.run(debug=True)
-
- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/quick-start.html b/docs/quick-start.html deleted file mode 100644 index 8ba77a0..0000000 --- a/docs/quick-start.html +++ /dev/null @@ -1,1070 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Quick Start - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Quick Start

-

As fronty is a very simple framework, it is very easy to use. You can easily create a website using. It -is mainly focused on the frontend part. So, we haven't add any backend features. But, you can easily add -backend features using any backend framework like Flask, Django, Fastapi etc.

-

But, we are working on a backend framework for fronty named Backkr. And we are also -working on a database framework named Flexdb. So, you can easily create a full stack -website with database using Fronty in only Python technology without knowing any kind -of web technologies like HTML, CSS, and JavaScript.

-

Here we will use flask as a backend framework for making this documentation short. But, you can use any -backend framework you want. We will update this documentation when we release Backkr and Flexdb. So, you can easily create a full stack website using only Python.

-

Starter template

-
app.py
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
-23
-24
-25
-26
-27
-28
-29
-30
-31
-32
-33
-34
-35
-36
-37
-38
-39
-40
from flask import Flask, request
-from fronty.html import *
-
-app = Flask(__name__)
-
-
-def home(request) -> Html:
-    '''This is the home page view function'''
-    return Html(
-        Head(
-            Title('Home'),
-            Meta(charset='utf-8'),
-            Meta(name='viewport', content='width=device-width, initial-scale=1'),
-        ),
-        Body(
-            Element(
-                'center',
-                Element(
-                    'h1',
-                    'Welcome to Fronty!'
-                ),
-                Element(
-                    'p',
-                    'Fronty is a frontend web framework.'
-                ),
-            )
-        )
-    )
-
-
-@app.route('/')
-def index() -> str:
-    '''This is the home page view function'''
-    return home(
-        request=request,
-    ).render()
-
-
-if __name__ == '__main__':
-    app.run(debug=True)
-
-

This is a starter template for fronty. You can use this template to create a basic website using -fronty. -
-First, we import the Flask and request from flask. Then, we import Html, Head, Title, Meta, Body, -Element from fronty.html package. -
-Then, we create a flask app. Then, we create a home view function. This view function will return -a Html object. This Html object will contain the HTML code for the home page. -
-Then, we create a index view function. This view function will call the home view function and -render the HTML code. -
-Then, we run the flask app.

-

Fronty has a very simple syntax. You can easily create a website using it. It has -some built-in element like Button, Link, Anchor etc. You can use these elements to -create a website. You can also create your own element using the BaseElement class. -We will see how to create a element in the customization section.

- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/search/search_index.json b/docs/search/search_index.json deleted file mode 100644 index 49aba35..0000000 --- a/docs/search/search_index.json +++ /dev/null @@ -1 +0,0 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"index.html","title":"Fronty","text":"

A frontend web framework for the web

Created by Md. Almas Ali

Documentation: https://almas-ali.github.io/fronty

Source Code: https://github.com/Almas-Ali/fronty

Fronty is a lightweight, fast, and easy-to-use Python-based frontend web framework that simplifies web development by allowing developers to create web pages using only Python. Its simple syntax and intuitive design make it an excellent option for beginners or developers who prefer working with Python.

"},{"location":"index.html#the-key-features-are","title":"The key features are:","text":"
  • Python-based frontend web framework
  • No need to use HTML, CSS, or JavaScript (though you can if you want)
  • Simple and lightweight
  • Fast rendering times
  • Easy to use and customize
  • Can integrate with other Python libraries and frameworks, such as Flask, Django, FastAPI, etc.
  • Growing community with extensive documentation and resources.
"},{"location":"index.html#sponsors","title":"Sponsors","text":"

No sponsors yet. Be the first one to sponsor this project. Become a sponsor

"},{"location":"contribution.html","title":"Contribution","text":"

Pull requests are welcome. For any changes, please open an issue first to discuss what you would like to change.

Thanks for using Fronty!

"},{"location":"examples.html","title":"Example projects","text":"

Project URL: Starter project

Project URL: Bootstrap Integration

Project URL: Custom CSS Project

"},{"location":"examples.html#how-to-run-the-example-projects","title":"How to run the example projects?","text":"

You can easily run the example projects by cloning the Fronty repository and running the following commands in your terminal.

  1. Clone the Fronty repository.
  2. Go to the examples/starter project directory.

    cd fronty/examples/starter\\ project\n

  3. Run the following command in your terminal.

    python app.py\n

  4. Open your browser and go to http://localhost:5000

  5. You can also run the other example projects by going to their directories and running the same command.

  6. Note: You have to install a backend server to run the project. Fronty does not provide a backend server. You can use any backend server you want. For example, you can use Flask. You can also use Fronty with Django. But you have to install Django first. For simplicity, we have used Flask in the example projects. We are woring on a backend server for Fronty. It will be available soon.

"},{"location":"installation.html","title":"Installation","text":"

You can easily install Fronty using pip. Just run the following command in your terminal.

pip install fronty\n

You can also install a backend framework to use with Fronty. For example, if you want to use Fronty with Flask, you can checkout flask documentation https://flask.palletsprojects.com/en/2.1.x/installation/

If you want to use Fronty with Django, you can checkout django documentation https://docs.djangoproject.com/en/4.2/topics/install/

If you want to use Fronty with FastAPI, you can checkout fastapi documentation https://fastapi.tiangolo.com/tutorial/first-steps/

Start learning Fronty by reading the documentation.

Want to contribute? Check out the Github project.

"},{"location":"quick-start.html","title":"Quick Start","text":"

As fronty is a very simple framework, it is very easy to use. You can easily create a website using. It is mainly focused on the frontend part. So, we haven't add any backend features. But, you can easily add backend features using any backend framework like Flask, Django, Fastapi etc.

But, we are working on a backend framework for fronty named Backkr. And we are also working on a database framework named Flexdb. So, you can easily create a full stack website with database using Fronty in only Python technology without knowing any kind of web technologies like HTML, CSS, and JavaScript.

Here we will use flask as a backend framework for making this documentation short. But, you can use any backend framework you want. We will update this documentation when we release Backkr and Flexdb. So, you can easily create a full stack website using only Python.

"},{"location":"quick-start.html#starter-template","title":"Starter template","text":"app.py
from flask import Flask, request\nfrom fronty.html import *\napp = Flask(__name__)\ndef home(request) -> Html:\n'''This is the home page view function'''\nreturn Html(\nHead(\nTitle('Home'),\nMeta(charset='utf-8'),\nMeta(name='viewport', content='width=device-width, initial-scale=1'),\n),\nBody(\nElement(\n'center',\nElement(\n'h1',\n'Welcome to Fronty!'\n),\nElement(\n'p',\n'Fronty is a frontend web framework.'\n),\n)\n)\n)\n@app.route('/')\ndef index() -> str:\n'''This is the home page view function'''\nreturn home(\nrequest=request,\n).render()\nif __name__ == '__main__':\napp.run(debug=True)\n

This is a starter template for fronty. You can use this template to create a basic website using fronty. First, we import the Flask and request from flask. Then, we import Html, Head, Title, Meta, Body, Element from fronty.html package. Then, we create a flask app. Then, we create a home view function. This view function will return a Html object. This Html object will contain the HTML code for the home page. Then, we create a index view function. This view function will call the home view function and render the HTML code. Then, we run the flask app.

Fronty has a very simple syntax. You can easily create a website using it. It has some built-in element like Button, Link, Anchor etc. You can use these elements to create a website. You can also create your own element using the BaseElement class. We will see how to create a element in the customization section.

"},{"location":"blog/index.html","title":"Blog","text":""},{"location":"components/introduction.html","title":"Components","text":""},{"location":"components/introduction.html#what-are-components","title":"What are Components?","text":"

Components are the building blocks of your application. They are reusable UI elements that can be composed together to build a UI. Components are also the unit of encapsulation for the UI, CSS, and behavior. Components for manipulating HTML, CSS, and JavaScript from Python code are provided by the fronty package. Components are created by subclassing the fronty.html.BaseElement class. We will learn more about components in the customizing components section.

"},{"location":"components/introduction.html#built-in-components","title":"Built-in Components","text":"

Fronty provides a set of built-in components that can be used to create a UI. These components are:

"},{"location":"components/introduction.html#for-javascript","title":"For JavaScript","text":"

Till now, there is no built-in component for JavaScript. But you can use the Script component to load JavaScript codes in your website from js file.

"},{"location":"components/css/attributes.html","title":"Attributes of CSS Components","text":""},{"location":"components/css/attributes.html#attributes","title":"Attributes","text":""},{"location":"components/css/attributes.html#properties","title":"properties","text":"

properties is a dictionary that contains all the properties of a CSS component. It is a required attribute of a Selector element. You have to pass a dictionary to this attribute. The keys of the dictionary are the properties of the CSS component and the values of the dictionary are the values of the properties. Here is an example:

Example of properties attribute
from fronty.css import CSS, Selector, Style\ncss = CSS(\nSelector('body')\n.properties({\n\"background-color\": \"red\",\n\"color\": \"white\",\n\"font-size\": \"20px\",\n\"font-weight\": \"bold\",\n\"padding\": \"10px\",\n\"border-radius\": \"5px\",\n\"border\": \"1px solid black\"\n})\n)\nprint(css.render())\n

Output:

Output of the above code
body{background-color:red;color:white;font-size:20px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}\n

Fronty returns every frontend code minified for better performance.

"},{"location":"components/css/introduction.html","title":"CSS Components","text":""},{"location":"components/css/introduction.html#what-are-css-components","title":"What are CSS Components?","text":"

CSS components are a list of dictionary that can be used to create a CSS styling fast and easily. These components are very easy to use and can be used to create a CSS styling in a few lines of code. Here is lots of customization options are available. Let's get started.

"},{"location":"components/css/introduction.html#important-css-components","title":"Important CSS Components","text":"

CSS : To create a css in a html website.

Selector : To create a selector in a html website. It is like query selector in JavaScript.

Style : To create a style in a html website.

"},{"location":"components/css/introduction.html#using-css-components","title":"Using CSS Components","text":"

To use CSS components, you have to import the fronty.css module methods. CSS, Selector and Style are the methods of fronty.css module. Here is an example of using fronty.css module methods:

Example of importing fronty.css module
from fronty.css import CSS, Selector, Style\ncss = CSS(\nSelector('body')\n)\nprint(css.render())\n

With this you can create a selector in a html website. But it is not enough to create a css file. You have to add some properties to the selector. To add properties to the selector, you have to use the properties attribute of the Selector element. Here is an example:

Example of properties attribute
from fronty.css import CSS, Selector, Style\ncss = CSS(\nSelector('body')\n.properties({\n\"background-color\": \"red\",\n\"color\": \"white\",\n\"font-size\": \"20px\",\n\"font-weight\": \"bold\",\n\"padding\": \"10px\",\n\"border-radius\": \"5px\",\n\"border\": \"1px solid black\"\n})\n)\nprint(css.render())\n

Output:

Output of the above code
body{background-color:red;color:white;font-size:20px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}\n

Here we have provided a dictionary in properties method of Selector class. The keys of the dictionary are the properties of the CSS component and the values of the dictionary are the values of the properties. You can add as many properties as you want. You can also add multiple selectors in a CSS file. Here is an example:

Example of multiple selectors
from fronty.css import CSS, Selector, Style\ncss = CSS(\nSelector('body')\n.properties({\n\"background-color\": \"red\",\n\"color\": \"white\",\n\"font-size\": \"20px\",\n\"font-weight\": \"bold\",\n\"padding\": \"10px\",\n\"border-radius\": \"5px\",\n\"border\": \"1px solid black\"\n}),\nSelector('h1')\n.properties({\n\"color\": \"blue\",\n\"font-size\": \"30px\",\n\"font-weight\": \"bold\",\n\"padding\": \"10px\",\n\"border-radius\": \"5px\",\n\"border\": \"1px solid black\"\n})\n)\nprint(css.render())\n

Output:

Output of the above code
body{background-color:red;color:white;font-size:20px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}h1{color:blue;font-size:30px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}\n

You can also add multiple properties in a selector. Here is an example:

Example of multiple properties
from fronty.css import CSS, Selector, Style\ncss = CSS(\nSelector('body')\n.properties({\n\"background-color\": \"red\",\n\"color\": \"white\",\n\"font-size\": \"20px\",\n\"font-weight\": \"bold\",\n\"padding\": \"10px\",\n\"border-radius\": \"5px\",\n\"border\": \"1px solid black\"\n})\n.properties({\n\"color\": \"blue\",\n\"font-size\": \"30px\",\n\"font-weight\": \"bold\",\n\"padding\": \"10px\",\n\"border-radius\": \"5px\",\n\"border\": \"1px solid black\"\n})\n)\nprint(css.render())\n

Output:

Output of the above code
body{background-color:red;color:blue;font-size:30px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}\n

Here we can see, only the unique properties are added to the selector and the duplicate properties are overwritten with the new properties.

"},{"location":"components/css/introduction.html#using-style-component","title":"Using Style Component","text":"

You can also use the Style component to create a CSS file. Here is an example:

Example of Style component
from fronty.css import CSS, Selector\nfrom fronty.html import Style\ncss = CSS(\nStyle('body{background-color:red;color:white;font-size:20px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}'),\nStyle('h1{color:blue;font-size:30px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}')\n)\nprint(css.render())\n

Output:

Output of the above code
<style type=\"text/css\" href=\"\" rel=\"stylesheet\">body{background-color:red;color:white;font-size:20px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}</style><style type=\"text/css\" href=\"\" rel=\"stylesheet\">h1{color:blue;font-size:30px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}</style>\n

This is very unrealistic to create a style component like this. But you can use this method to add a CSS to your website. Here is an example:

Example of Style component
from fronty.css import CSS, Selector\nfrom fronty.html import Html, Head, Title, Meta, Style, Body, H1\ncss = CSS(\nSelector('body')\n.properties({\n\"background-color\": \"red\",\n\"color\": \"white\",\n\"font-size\": \"20px\",\n\"font-weight\": \"bold\",\n\"padding\": \"10px\",\n\"border-radius\": \"5px\",\n\"border\": \"1px solid black\"\n}),\nSelector('h1')\n.properties({\n\"color\": \"blue\",\n\"font-size\": \"30px\",\n\"font-weight\": \"bold\",\n\"padding\": \"10px\",\n\"border-radius\": \"5px\",\n\"border\": \"1px solid black\"\n}),\n)\n...\n# Now we will add the style component to the html component\nhtml = Html(\nHead(\nTitle('My Website'),\nMeta(charset=\"UTF-8\"),\nMeta(name=\"viewport\", content=\"width=device-width, initial-scale=1.0\"),\nStyle(css.render())\n),\nBody(\nH1('Hello World')\n)\n)\nprint(html.render())\n

Output:

Output of the above code
<!DOCTYPE html><html><head><title>My Website</title><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style type=\"text/css\" href=\"\" rel=\"stylesheet\">body{background-color:red;color:white;font-size:20px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}h1{color:blue;font-size:30px;font-weight:bold;padding:10px;border-radius:5px;border:1px solid black}</style></head><body><h1>Hello World</h1></body></html>\n

This is how you can add a CSS to your website fast, easily and efficiently with Style component.

"},{"location":"components/html/attributes.html","title":"Attributes of Component Elements","text":""},{"location":"components/html/attributes.html#attributes","title":"Attributes","text":"

The attributes of the component elements are the same as the attributes of the html elements. You can use the attributes of the html elements in the component elements. Check the attributes of the html elements.

"},{"location":"components/html/attributes.html#important-attributes","title":"Important attributes","text":""},{"location":"components/html/attributes.html#id","title":"id","text":"

The id attribute is used to give a unique id to a component element. You can use this id to select the component element using JavaScript. Element().id('something') or Element(id='something') can be used to set the id of a component element.

"},{"location":"components/html/attributes.html#class","title":"class","text":"

The class attribute is used to give multiple classes to a component element. You can use the same method again to override the previous class. Element().class_('something1 something2 somethingNth') or Element(class='something1 something2 somethingNth') can be used to set the class of a component element. You can also use class_ instead of class to set the class of a component element as class is a reserved keyword in Python and every programming language.

"},{"location":"components/html/attributes.html#placeholder","title":"placeholder","text":"

The placeholder attribute is used to set the placeholder of a field. Element().placeholder('something') or Element(placeholder='something') can be used to set the placeholder of a field. It is a method in the BaseElement class. You can use this any element that accepts the placeholder attribute as it is defined in the BaseElement class.

"},{"location":"components/html/attributes.html#type","title":"type","text":"

The type attribute is used to set the type of a field. Element().type('something') or Element(type='something') can be used to set the type of a field. It is a method in the BaseElement class. You can use this any element that accepts the type attribute as it is defined in the BaseElement class.

"},{"location":"components/html/attributes.html#name","title":"name","text":"

The name attribute is used to set the name of a field. Element().name('something') or Element(name='something') can be used to set the name of a field. It is a method in the BaseElement class. You can use this any element that accepts the name attribute as it is defined in the BaseElement class.

"},{"location":"components/html/attributes.html#style","title":"style","text":"

The style attribute is used to give inline CSS to a component element. You can use the same method again to override the previous style. Element().style(color='red', background_color='blue') can be used to set the style of a component element. This method takes keyword arguments as the CSS properties and their values. Some CSS properties have hyphen in their name. You can use underscore instead of hyphen in the name of the CSS properties. For example, background-color can be written as background_color.

"},{"location":"components/html/attributes.html#attr","title":"attr","text":"

The attr attribute is used to give attributes to a component element. You can add as much as you need attributes to a component element. Element().attr('key', 'value').attr('more', 'more') can be used to set the attribute of a component element. This method takes two arguments as the key and value of the attribute.

"},{"location":"components/html/attributes.html#required","title":"required","text":"

The required attribute is used to make a input field required. Element().required can be used to make a input field required. It is just a property of the Input component element. You can use this any element that accepts the required attribute as it is defined in the BaseElement class.

"},{"location":"components/html/attributes.html#disabled","title":"disabled","text":"

The disabled attribute is used to make a input field disabled. Element().disabled can be used to make a input field disabled. It is just a property of the Input component element. You can use this any element that accepts the disabled attribute as it is defined in the BaseElement class.

"},{"location":"components/html/attributes.html#readonly","title":"readonly","text":"

The readonly attribute is used to make a input field readonly. Element().readonly can be used to make a input field readonly. It is just a property of the Input component element. You can use this any element that accepts the readonly attribute as it is defined in the BaseElement class.

"},{"location":"components/html/attributes.html#value","title":"value","text":"

The value attribute is used to set the value of a field. Element().value('something') or Element(value='something') can be used to set the value of a field. It is a method in the BaseElement class. You can use this any element that accepts the value attribute as it is defined in the BaseElement class.

"},{"location":"components/html/introduction.html","title":"HTML Components","text":""},{"location":"components/html/introduction.html#what-are-html-components","title":"What are HTML Components?","text":"

HTML components are some simple set of classes that can be used to create a HTML website fast and easily. These components are very easy to use and can be used to create a HTML website in a few lines of code. Try to create a HTML website using these components and you will see how easy it is to create a HTML website using these components. So, let's get started.

"},{"location":"components/html/introduction.html#built-in-html-components","title":"Built-in HTML Components","text":"

Html : To create the main HTML page layout.

Head : To create the head section of a html website.

Title: To describe the title of a website in the head section.

Meta : To describe all types of meta tags for SEO.

Body : To create the body structure of a html website.

Script: To load Javascript codes in fronty based website.

Style: To write custom CSS fronty.

Link : To load CSS codes in fronty based website.

Anchor : To create a anchor links in a html website.

Image : To load images in a html website.

Button : To create a button in a html website.

Input : To create a input field in a html website.

Text : To create a text in a html website.

Break : To create a break line in a html website.

Form : To create a form in a html website.

Div : To create a div in a html website.

Span : To create a span in a html website.

H1 : To create a h1 in a html website.

H2 : To create a h2 in a html website.

H3 : To create a h3 in a html website.

H4 : To create a h4 in a html website.

H5 : To create a h5 in a html website.

H6 : To create a h6 in a html website.

P : To create a p in a html website.

Ul : To create a ul in a html website.

Ol : To create a ol in a html website.

Li : To create a li in a html website.

Table : To create a table in a html website.

Tr : To create a tr in a html website.

Td : To create a td in a html website.

Th : To create a th in a html website.

Caption : To create a caption in a html website.

Thead : To create a thead in a html website.

Tbody : To create a tbody in a html website.

Tfoot : To create a tfoot in a html website.

Iframe : To create a iframe in a html website.

Audio : To create a audio in a html website.

Video : To create a video in a html website.

Source : To create a source in a html website.

Select : To create a select in a html website.

Option : To create a option in a html website.

Nav : To create a nav in a html website.

Header : To create a header in a html website.

Footer : To create a footer in a html website.

Section : To create a section in a html website.

Article : To create a article in a html website.

Aside : To create a aside in a html website.

Main : To create a main in a html website.

Figure : To create a figure in a html website.

Figcaption : To create a figcaption in a html website.

Dl : To create a dl in a html website.

Dt : To create a dt in a html website.

Dd : To create a dd in a html website.

Time : To create a time in a html website.

Mark : To create a mark in a html website.

Small : To create a small in a html website.

Strong : To create a strong in a html website.

Em : To create a em in a html website.

Code : To create a code in a html website.

Pre : To create a pre in a html website.

Blockquote : To create a blockquote in a html website.

Empty : To wrap multiple elements to return a single element.

Comment : To create a comment in a html website.

"},{"location":"components/html/introduction.html#_1","title":"Introduction","text":""},{"location":"components/js/introduction.html","title":"Javascript Components","text":""},{"location":"components/js/introduction.html#what-are-javascript-components","title":"What are Javascript Components?","text":""},{"location":"customization/customized-html.html","title":"Customizing Components","text":"

You can customize the built-in components or create your own components by subclassing the fronty.html.BaseElement class. Let's see how to create a custom component.

custom_components.py
from fronty.html import (\nBaseElement,\nText\n)\nclass CustomComponent(BaseElement):\ndef __init__(self, *children, **attributes):\nsuper().__init__('custom-component', *children, **attributes)\n# Optional attributes if you want to add any custom attributes\nself._attributes['custom-attribute'] = 'custom-value'\n# Optional children if you want to add any custom children\nself._children = [\nText('This is a custom component.'),\n]\n

Now, you can use this component in your application.

main.py
from flask import Flask # or any other framework\nfrom fronty.html import (\nHtml,\nHead,\nTitle,\nBody,\n)\nfrom custom_components import CustomComponent # import the custom component\napp = Flask(__name__)\ndef layout():\nreturn Html(\nHead(\nTitle('Custom Component')\n),\nBody(\nCustomComponent()\n)\n)\n@app.route('/')\ndef home():\nreturn layout().render()\nif __name__ == '__main__':\napp.run(debug=True)\n
"},{"location":"projects/bootstrap-integration.html","title":"Bootstrap Integration","text":"

Now, let's integrate Bootstrap into our project. We will use the Bootstrap CDN to load the Bootstrap CSS and JavaScript files.

First, we will create a new folder named components inside the project folder. Then, we will create a new component named layout.py inside the components folder.

project/components/layout.py
from fronty.html import *\ndef navbar(request, **data) -> Element:\n'''This is the navbar component'''\n# The navbar layout\n_layout = Nav(\nDiv(\nAnchor(\n'Fronty',\nhref='/',\n).class_('navbar-brand'),\nButton(\nElement('span').class_('navbar-toggler-icon'),\n).class_('navbar-toggler').attr('type', 'button').attr('data-bs-toggle', 'collapse').attr('data-bs-target', '#navbarScroll').attr('aria-controls', 'navbarScroll').attr('aria-expanded', 'false').attr('aria-label', 'Toggle navigation'),\nUl(\nLi(\nAnchor(\n'Home',\nhref='/',\n).class_('nav-link active').attr('aria-current', 'page'),\n).class_('nav-item'),\nLi(\nAnchor(\n'About',\nhref='/about',\n).class_('nav-link'),\n).class_('nav-item'),\nLi(\nAnchor(\n'More',\nhref='#',\n).class_('nav-link dropdown-toggle').attr('role', 'button').attr('data-bs-toggle', 'dropdown').attr('aria-expanded', 'false'),\nUl(\nLi(\nAnchor(\n'Action',\nhref='#',\n).class_('dropdown-item'),\n),\nLi(\nAnchor(\n'Another action',\nhref='#',\n).class_('dropdown-item'),\n),\nLi(\nElement('hr').class_('dropdown-divider'),\n),\nLi(\nAnchor(\n'Something else here',\nhref='#',\n).class_('dropdown-item'),\n),\n).class_('dropdown-menu'),\n).class_('nav-item dropdown'),\n).class_('navbar-nav me-auto my-2 my-lg-0 navbar-nav-scroll').attr('style', '--bs-scroll-height: 100px;'),\nForm(\nInput(\nplaceholder='Search',\naria_label='Search',\n).class_('form-control me-2').attr('type', 'search'),\nButton(\n'Search',\n).class_('btn btn-outline-success').attr('type', 'submit'),\n).class_('d-flex').attr('role', 'search'),\n).class_('container-fluid'),\n).class_('navbar navbar-expand-lg bg-body-tertiary')\nreturn _layout\ndef layout(request, **data) -> Html:\n'''This is the layout component'''\n# The main layout\nreturn Html(\nHead(\nTitle('Fronty'),  # Page title\nMeta(charset='utf-8'),  # Character encoding\n# Responsive design\nMeta(name='viewport', content='width=device-width, initial-scale=1'),\n# Bootstrap CSS\nLink(rel='stylesheet', href='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css',\nintegrity='sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD', crossorigin='anonymous'),\n),\nBody(\n# Navbar\nnavbar(request),\n# Main area of the page\n# The main area of the page is passed as a parameter to the layout component.\n# Get subcomponent from data or use default value\ndata.get('content', 'Empty content'),\n# Bootstrap JS\nScript(src='https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js\", integrity=\"sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN', crossorigin='anonymous'),\n),\n)\n

Now, we will create a index.py file inside the components folder. This file will contain the home page component.

project/components/index.py
from fronty.html import (\nElement,\nDiv,\nH1,\nText,\nBreak\n)\n# components\nfrom components.layout import layout\ndef home(request, **data) -> Element:\n'''This is the home page component'''\n_layout = layout(\nrequest=request,\ncontent=Div(\nH1('Home'),\nText(\nf\"\"\"\n                    Path: {request.path}\n{Break()}\n                    Method: {request.method}\n                \"\"\"\n),\n).class_('container text-center')\n)\nreturn _layout\n# We have added the about inside the index.py file for simplicity.\n# You can create a new file for the about page component.\ndef about(request, **data) -> Element:\n'''This is the about page component'''\n_layout = layout(\nrequest=request,\ncontent=Div(\nH1('About'),\n).class_('container text-center')\n)\nreturn _layout\n

Now, we will update the app.py file to use the new components.

project/app.py
from flask import Flask, request\nfrom fronty.html import *\n# components\nfrom components.index import home, about\napp = Flask(__name__)\n@app.route('/')\ndef index():\n'''This is the home page view function'''\nreturn home(\nrequest=request,\ntitle='A simple framework to build a website only with Python.',\n).render()\n@app.route('/about')\ndef about_view():\n'''This is the about page view function'''\nreturn about(\nrequest=request,\ntitle='A simple framework to build a website only with Python.',\n).render()\nif __name__ == '__main__':\napp.run(debug=True)\n

Now, we will run the project and open the home page in the browser.

python project/app.py\n

Visit http://127.0.0.1:5000 in your browser.

Project URL: Bootstrap Integration

"},{"location":"projects/custom-css-project.html","title":"Custom CSS Project","text":"

Initially, we have created a basic HTML only project. Then we have integrated Bootstrap into our project. Now, we will create a custom CSS project. We will use only Python to create this project.

Let's create a new project directory named custom_css_project. Then create a new file named app.py inside the custom_css_project directory.

Now, we will create everything in side the app.py file.

custom_css_project/app.py
from flask import Flask\nfrom fronty.html import *\nfrom fronty.css import *\nfrom datetime import date\n# CSS components\ndef style_css():\n'''This is the style component'''\n# The CSS() is used to create a CSS object.\nreturn CSS(\n# The Selector() is used to create a CSS selector.\n# Here we have used the universal selector to select all the elements.\n# *{} means select all the elements.\n# We have css properties inside the properties() method.\n# Passed the css properties as keyword arguments.\n# The properties() method returns a CSSProperties object.\nSelector('*').properties({\n'margin': '0',\n'padding': '0',\n'font-family': 'Roboto, sans-serif, Arial',\n}),\n# Here we have selected the body tag.\n# We have used the Selector('body') to select the body tag.\n# Selector('body').properties({}) is used to add css properties to the body tag.\nSelector('body').properties({\n'background-color': '#d6d6e7',\n}),\nSelector('nav').properties({\n'background-color': '#484c7a',\n'color': '#fff',\n'padding': '20px',\n'position': 'absolute',\n'width': '80%',\n'margin': '0 10%',\n'top': '10px',\n'border-radius': '12px'\n}),\nSelector('nav ul').properties({\n'list-style': 'none',\n'display': 'flex',\n'flex-direction': 'row',\n'justify-content': 'center',\n}),\nSelector('nav ul li').properties({\n'margin': '0 10px'\n}),\nSelector('a').properties({\n'text-decoration': 'none',\n'color': '#fff',\n'padding': '12px',\n'border-radius': '12px',\n'transition': 'all 0.3s ease-in-out',\n'font-size': '18px',\n}),\nSelector('nav a:hover').properties({\n'background-color': '#ddd',\n'color': 'black',\n}),\nSelector('nav a:active').properties({\n'background-color': '#4CAF50',\n'color': 'white',\n}),\nSelector('.container').properties({\n'margin': '90px 10%',\n'width': '80%',\n'text-align': 'center',\n'padding': '20px',\n'background-color': '#fff',\n'border-radius': '12px',\n}),\nSelector('footer').properties({\n'position': 'absolute',\n'bottom': '10px',\n'width': '80%',\n'margin': '0 10%',\n'border-radius': '12px',\n'text-align': 'center',\n'padding': '20px',\n'background-color': '#484c7a',\n'color': '#fff',\n'font-size': '12px',\n}),\n)\n# Fronty components\ndef layout(request, **data):\n'''This is the layout component'''\n# The Html() is used to create a HTML object.\nreturn Html(\nHead(\nTitle('Custom CSS Project'),\nMeta(charset='UTF-8'),\nMeta(content=\"IE=edge\").attr('http-equiv', 'X-UA-Compatible'),\nMeta(name='viewport', content='width=device-width, initial-scale=1.0'),\nStyle(\nstyle_css().render(),\n),\n),\nBody(\nNav(\nUl(\nLi(\nAnchor('Home', href='/'),\n),\nLi(\nAnchor('About', href='/about'),\n)\n)\n),\nDiv(\nH1(\n'Custom CSS Project',\n),\nText(\n'This is a custom CSS project using Fronty.',\n),\n).class_('container'),\nFooter(\nf'\u00a9 {date.today().year} Fronty',\n),\n)\n)\napp = Flask(__name__)\n@app.route('/')\ndef home():\n'''This is the home page view function'''\n# The render() method is used to convert the python objects to HTML string.\nreturn layout(\nrequest=None,\n).render()\nif __name__ == '__main__':\napp.run(debug=True)\n
"},{"location":"projects/starter-project.html","title":"Starter Project","text":"

For simplicity, we have created a starter project that you can use to get started with your own project. It is a simple project that contains a single page with a single component. It is a good starting point for your own project.

starter_project/app.py
from flask import Flask, request\nfrom fronty.html import *\napp = Flask(__name__)\ndef home(request) -> Html:\n'''This is the home page view function'''\n# The main HTML element.\nreturn Html(\n# The head tag contains the title and meta tags.\nHead(\n# The title tag contains the title of the page.\nTitle('Home'),\n# The meta tags contain the meta information of the page.\nMeta(charset='utf-8'),\nMeta(name='viewport', content='width=device-width, initial-scale=1'),\n),\n# The body tag contains all the content of the page.\nBody(\n# The center tag contains the main content of the page.\n# It is like using a HTML element when you don't know whats the name of a tag in fronty.\n# You can use the Element('tag') for this purpose.\nElement(\n'center',\n# The h1 tag contains the title of the page.\nH1(\n'Welcome to Fronty!'\n),\n# The Text() is used to add text to the page like paragraphs.\nText(\n'Fronty is a frontend web framework.'\n),\n)\n)\n)\n@app.route('/')\ndef index() -> str:\n'''This is the home page view function'''\n# The render() method is used to convert the python objects to HTML string.\n# The render() method returns a string. So, we can return it directly.\nreturn home(\nrequest=request,\n).render()\nif __name__ == '__main__':\n# Run the app in debug mode.\n# Learn more about Flask at https://flask.palletsprojects.com/en/2.1.x/\napp.run(debug=True)\n
"},{"location":"widgets/attributes.html","title":"Attributes","text":""},{"location":"widgets/attributes.html#attributes-of-widgets","title":"Attributes of widgets","text":"

All widgets have some attributes that can be used to customize the widget. The attributes are:

"},{"location":"widgets/attributes.html#load_css","title":"load_css","text":"

This attribute is used to load the CSS of the widget. It is a boolean value. If it is True, the CSS of the widget will be loaded. If it is False, the CSS of the widget will not be loaded. The default value is False. If you need to add the CSS of the widget, you can add it manually. FormWidget(load_css=True) will load the CSS of the FormWidget widget.

"},{"location":"widgets/attributes.html#forms_type","title":"forms_type","text":"

This attribute is used to set the type of the form. It is a string value. The default value is loginform. Currently, we are working on loginform, registrationform, contactform, searchform, subscribeform and commentform. More will come soon. FormWidget(forms_type=\"loginform\") will set the type of the form to loginform.

"},{"location":"widgets/attributes.html#action","title":"action","text":"

This attribute is used to set the action of the form. It is a string value. The default value is #. FormWidget(action=\"/login\") will set the action of the form to /login. If you need to set the action of the form to the current page, you can set it to \"\" or #.

"},{"location":"widgets/attributes.html#method","title":"method","text":"

This attribute is used to set the method of the form. It is a string value. The default value is POST. FormWidget(method=\"GET\") will set the method of the form to GET.

"},{"location":"widgets/attributes.html#add_element","title":"add_element","text":"

This attribute is used to add more elements to the form. You can use it FormWidget().add_element(element) to add an element to the form. FormWidget().add_element(Input(type=\"text\", name=\"username\")) will add an input element to the form.

"},{"location":"widgets/introduction.html","title":"Widgets Introduction","text":""},{"location":"widgets/introduction.html#what-is-a-widget","title":"What is a widget?","text":"

A widget is a set of components that can be used to build a user interface (UI) smoothly and very quickly. Widgets are build for making development process easier and faster. Widgets are also used to make the UI more beautiful and attractive with a single line of code.

"},{"location":"widgets/introduction.html#how-to-use-a-widget","title":"How to use a widget?","text":"

To use a widget, you need to import it from the fronty.html.widgets module. For example, if you need to make a login form, you can use the FormWidget widget. You can simply call the FormWidget class and add it to your page.

main.py
from fronty.html.widgets import FormWidget\nfrom fronty.html import *\nfrom flask import Flask\napp = Flask(__name__)\n@app.route(\"/\")\ndef login():\nreturn Html(\nHead(\nMeta(charset=\"utf-8\"),\nTitle(\"Test case\"),\n),\nBody(\nFormWidget(load_css=True)\n)\n).render()\nif __name__ == \"__main__\":\napp.run(debug=True)\n
"}]} \ No newline at end of file diff --git a/docs/sitemap.xml b/docs/sitemap.xml deleted file mode 100644 index 8b7686b..0000000 --- a/docs/sitemap.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - https://almas-ali.github.io/fronty/index.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/contribution.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/examples.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/installation.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/quick-start.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/blog/index.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/components/introduction.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/components/css/attributes.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/components/css/introduction.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/components/html/attributes.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/components/html/introduction.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/components/js/introduction.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/customization/customized-html.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/projects/bootstrap-integration.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/projects/custom-css-project.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/projects/starter-project.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/widgets/attributes.html - 2023-05-29 - daily - - - https://almas-ali.github.io/fronty/widgets/introduction.html - 2023-05-29 - daily - - \ No newline at end of file diff --git a/docs/sitemap.xml.gz b/docs/sitemap.xml.gz deleted file mode 100644 index b9f8035a1f94506383d1a87c7835682f1e1d468e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 378 zcmV-=0fqh_iwFn~5Orh%|8r?{Wo=<_E_iKh0M(bxZi6rk$M1a##65&{nzT-o-u49B z1BBp0x_r>sjCN1I09}Q4++iX)BSNAfC>#*RKh+NQIA0l{lzsO@%eMF5^_6a>!-A}PynI6d* z^)+>w`w40`g0G&w^X>#P$X+=|NM3X-s1J>gqiNppXWdySIP7MNhkfe#;G+Q_RNVkY Y)sudZ|G% - -Fronty is ready to rock and roll! Try it out, and let us know what you think. \ No newline at end of file diff --git a/docs/theme/main.html b/docs/theme/main.html deleted file mode 100644 index 41af1c4..0000000 --- a/docs/theme/main.html +++ /dev/null @@ -1,10 +0,0 @@ -{% extends "base.html" %} - -{% block announce %} - {% include 'announce.html' ignore missing %} -{% endblock %} - -{% block content %} - {{ super() }} - -{% endblock %} \ No newline at end of file diff --git a/docs/widgets/attributes.html b/docs/widgets/attributes.html deleted file mode 100644 index f8ad698..0000000 --- a/docs/widgets/attributes.html +++ /dev/null @@ -1,1059 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Attributes - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Attributes

-

Attributes of widgets

-

All widgets have some attributes that can be used to customize the widget. The attributes are:

-

load_css

-

This attribute is used to load the CSS of the widget. It is a boolean value. If it is True, the CSS of the widget will be loaded. If it is False, the CSS of the widget will not be loaded. The default value is False. If you need to add the CSS of the widget, you can add it manually. FormWidget(load_css=True) will load the CSS of the FormWidget widget.

-

forms_type

-

This attribute is used to set the type of the form. It is a string value. The default value is loginform. Currently, we are working on loginform, registrationform, contactform, searchform, subscribeform and commentform. More will come soon. FormWidget(forms_type="loginform") will set the type of the form to loginform.

-

action

-

This attribute is used to set the action of the form. It is a string value. The default value is #. FormWidget(action="/login") will set the action of the form to /login. If you need to set the action of the form to the current page, you can set it to "" or #.

-

method

-

This attribute is used to set the method of the form. It is a string value. The default value is POST. FormWidget(method="GET") will set the method of the form to GET.

-

add_element

-

This attribute is used to add more elements to the form. You can use it FormWidget().add_element(element) to add an element to the form. FormWidget().add_element(Input(type="text", name="username")) will add an input element to the form.

- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/docs/widgets/introduction.html b/docs/widgets/introduction.html deleted file mode 100644 index 2ed2a61..0000000 --- a/docs/widgets/introduction.html +++ /dev/null @@ -1,1027 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - Introduction - Fronty - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - - - - -
- - -
- -
- - - - - - -
-
- - - -
-
-
- - - - -
-
-
- - - -
-
-
- - - -
-
-
- - - -
-
- - - - - - - - -

Widgets Introduction

-

What is a widget?

-

A widget is a set of components that can be used to build a user interface (UI) smoothly and very quickly. Widgets are build for making development process easier and faster. Widgets are also used to make the UI more beautiful and attractive with a single line of code.

-

How to use a widget?

-

To use a widget, you need to import it from the fronty.html.widgets module. For example, if you need to make a login form, you can use the FormWidget widget. You can simply call the FormWidget class and add it to your page.

-
main.py
 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
-10
-11
-12
-13
-14
-15
-16
-17
-18
-19
-20
-21
-22
from fronty.html.widgets import FormWidget
-from fronty.html import *
-
-from flask import Flask
-
-app = Flask(__name__)
-
-@app.route("/")
-def login():
-   return Html(
-        Head(
-            Meta(charset="utf-8"),
-            Title("Test case"),
-        ),
-        Body(
-            FormWidget(load_css=True)
-        )
-    ).render()
-
-
-if __name__ == "__main__":
-    app.run(debug=True)
-
- - - - - - - - - - -
-
- - - - -
- - - -
- -
- - -
- -
-
-
-
- - - - - - - - - \ No newline at end of file From c79ac12ecfdd615f11547206daa5496bf953d2c5 Mon Sep 17 00:00:00 2001 From: "Md. Almas Ali" Date: Sat, 10 Feb 2024 02:25:56 +0600 Subject: [PATCH 02/14] build: moved to pyproject.toml from setup.py --- pyproject.toml | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..893b48c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,67 @@ +[project] +name = "fronty" +dynamic = ["version"] +dependencies = [] +requires-python = ">=3.7" +authors = [{name = "Md. Almas Ali", email = "almaspr3@gmail.com"}] +maintainers = [{name = "Md. Almas Ali", email = "almaspr3@gmail.com"}] +description = "A frontend web framework" +readme = "README.md" +license = {file = "LICENSE"} +keywords = [ + "web framework", + "frontend framework", + "frontend", + "web", + "framework", + "html", + "css", + "javascript", + "simple", + "easy", + "fast", + "lightweight", + "light", + "light-weight", + "quick", + "rapid", +] +classifiers = [ + "Topic :: Internet", + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", +] + + +[project.urls] +Homepage = "https://github.com/Almas-Ali/fronty" +Documentation = "https://github.com/Almas-Ali/fronty#readme" +Repository = "https://github.com/Almas-Ali/fronty" +"Bug Tracker" = "https://github.com/Almas-Ali/fronty/issues" + + +[project.scripts] +fronty = "fronty.cli:main" + + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + + +[tool.hatch.version] +path = "fronty/__init__.py" + + +[tool.ruff.format] +quote-style = "single" From 11bbceff7376a31b6cc98547bedb99476d0bd33a Mon Sep 17 00:00:00 2001 From: "Md. Almas Ali" Date: Sat, 10 Feb 2024 02:26:37 +0600 Subject: [PATCH 03/14] build: moved to pyproject.toml from setup.py --- setup.py | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 setup.py diff --git a/setup.py b/setup.py deleted file mode 100644 index 9245809..0000000 --- a/setup.py +++ /dev/null @@ -1,36 +0,0 @@ -from setuptools import setup, find_packages - -with open('README.md', 'r') as f: - long_description = f.read() - -setup( - name='fronty', - version='0.0.5', - description='A frontend web framework', - long_description_content_type='text/markdown', - long_description=long_description, - author='Almas Ali', - author_email='almaspr3@gmail.com', - url='https://github.com/Almas-Ali/fronty', - packages=find_packages(), - classifiers=[ - 'Development Status :: 3 - Alpha', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: MIT License', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.7', - ], - keywords='web framework', - python_requires='>=3.7', - - entry_points={ - 'console_scripts': [ - 'fronty=fronty.cli:main', - ], - }, -) From 72c3577e3ee81398912414224348de66cf876f7c Mon Sep 17 00:00:00 2001 From: "Md. Almas Ali" Date: Sat, 10 Feb 2024 02:27:56 +0600 Subject: [PATCH 04/14] docs: added customization sections. --- docs_src/mkdocs.yml | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs_src/mkdocs.yml b/docs_src/mkdocs.yml index 36070bf..c003019 100644 --- a/docs_src/mkdocs.yml +++ b/docs_src/mkdocs.yml @@ -45,6 +45,9 @@ extra: provider: google property: G-XJC75ENC9N + version: + provider: mike + social: - icon: fontawesome/brands/github-alt link: https://github.com/Almas-Ali/fronty @@ -58,7 +61,7 @@ extra: - icon: fontawesome/solid/globe link: https://almasali.net - generator: false + generator: true copyright: Build with love for the community © 2023 @@ -72,16 +75,19 @@ nav: - Quick Start: quick-start.md - Components: - Introduction: components/introduction.md - - HTML: + - HTML Components: - Introduction: components/html/introduction.md - Attributes: components/html/attributes.md - - CSS: + - CSS Components: - Introduction: components/css/introduction.md - Attributes: components/css/attributes.md - - JavaScript: + - JavaScript Components: - Introduction: components/js/introduction.md - Customization: + - Introduction: customization/introduction.md - HTML Customization: customization/customized-html.md + - CSS Customization: customization/customized-css.md + - JavaScript Customization: customization/customized-js.md - Widgets: - Introduction: widgets/introduction.md - Attributes: widgets/attributes.md From 542b247c3e08bb9127af2d04b446e0c874a7b82b Mon Sep 17 00:00:00 2001 From: "Md. Almas Ali" Date: Sat, 10 Feb 2024 02:29:41 +0600 Subject: [PATCH 05/14] docs: added bref introductions about components. --- docs_src/docs/components/introduction.md | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/docs_src/docs/components/introduction.md b/docs_src/docs/components/introduction.md index 918328d..6c091b5 100644 --- a/docs_src/docs/components/introduction.md +++ b/docs_src/docs/components/introduction.md @@ -2,18 +2,12 @@ ## What are Components? -Components are the building blocks of your application. They are reusable UI elements that can be composed together to build a UI. Components are also the unit of encapsulation for the UI, CSS, and behavior. Components for manipulating HTML, CSS, and JavaScript from Python code are provided by the `fronty` package. Components are created by subclassing the `fronty.html.BaseElement` class. We will learn more about components in the customizing components section. +Components are the building blocks of your application. They are reusable UI elements that can be composed together to build a UI. Components are also the unit of encapsulation for the UI, CSS, and behavior. Components for manipulating HTML, CSS, and JavaScript from Python code are provided by the `fronty` package. Components are created by subclassing the `BaseElement` class in every modules. There are available `BaseElement` for HTML elements, CSS, and JavaScript. We will learn more about components in the [customizing components](../customization/introduction.md) ## Built-in Components Fronty provides a set of built-in components that can be used to create a UI. These components are: - - - - - -### For JavaScript - -Till now, there is no built-in component for JavaScript. But you can use the `Script` component to load JavaScript codes in your website from js file. - +- [HTML Components](./html/introduction.md) +- [CSS Components](./css/introduction.md) +- [Javascript Components](./js/introduction.md) From 2c0fdfd48780a914c8c6ea035ef9fc48147110ee Mon Sep 17 00:00:00 2001 From: "Md. Almas Ali" Date: Sat, 10 Feb 2024 02:30:20 +0600 Subject: [PATCH 06/14] feat: added js elements. --- fronty/js/__init__.py | 118 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 fronty/js/__init__.py diff --git a/fronty/js/__init__.py b/fronty/js/__init__.py new file mode 100644 index 0000000..178ba28 --- /dev/null +++ b/fronty/js/__init__.py @@ -0,0 +1,118 @@ +from ..html import AnyHTMLElement + + +class BaseElement(object): + def __init__(self, **kwargs): + self.kwargs = kwargs + + def render(self): + raise NotImplementedError + + def script_wrap(self): + '''Returns the JS code wrapped in " + + def __str__(self): + return self.render() + + def __repr__(self): + return self.render() + + def __add__(self, other): + return self.render() + other.render() + + def __radd__(self, other): + return other.render() + self.render() + + def __iadd__(self, other): + return self.render() + other.render() + + def __eq__(self, other): + return self.render() == other.render() + + def __ne__(self, other): + return self.render() != other.render() + + def __lt__(self, other): + return self.render() < other.render() + + def __le__(self, other): + return self.render() <= other.render() + + def __gt__(self, other): + return self.render() > other.render() + + def __ge__(self, other): + return self.render() >= other.render() + + def __len__(self): + return len(self.render()) + + +class Alert(BaseElement): + def __init__(self, message): + super().__init__() + self.message = message + + def render(self): + return f"alert('{self.message}');" + + +class Event(BaseElement): + def __init__(self, event, **kwargs): + super().__init__(**kwargs) + self.event = event + + def render(self): + return f"document.getElementById('{self.kwargs.get('id')}').{self.event}();" if 'id' in self.kwargs else f"document.{self.event}();" + + +class ConsoleLog(BaseElement): + def __init__(self, message): + super().__init__() + self.message = message + + def render(self): + return f"console.log('{self.message}');" + + +class Function(BaseElement): + def __init__(self, name, args: list, body: str): + super().__init__() + self.name = name + self.args = args + self.body = body + + def render(self): + return f"function {self.name}({', '.join(self.args)}){{ {self.body} }};" + + +class SetTimeout(BaseElement): + def __init__(self, function, time): + super().__init__() + self.function = function + self.time = time + + def render(self): + return f"setTimeout({self.function}, {self.time});" + + +class SetInterval(BaseElement): + def __init__(self, function, time: int): + super().__init__() + self.function = function + self.time = time + + def render(self): + return f"setInterval({self.function}, {self.time});" + + +class ToggleClass(BaseElement): + def __init__(self, html: AnyHTMLElement, class1: str, class2: str): + super().__init__() + self.html = html + self.class1 = class1 + self.class2 = class2 + + def render(self): + return self.html.class_ From c49c2720dfa070b9e0ff316dd1fa3b7b8b8f44e5 Mon Sep 17 00:00:00 2001 From: "Md. Almas Ali" Date: Sat, 10 Feb 2024 02:31:24 +0600 Subject: [PATCH 07/14] docs: added js components introduction page. --- docs_src/docs/components/js/introduction.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs_src/docs/components/js/introduction.md b/docs_src/docs/components/js/introduction.md index 1baa4df..cc3572d 100644 --- a/docs_src/docs/components/js/introduction.md +++ b/docs_src/docs/components/js/introduction.md @@ -1,3 +1,8 @@ # Javascript Components ## What are Javascript Components? + +Javascript components are the simple implementation of Javascript code that can be used to create a reusable component. These components can be used to create a reusable code that can be used in multiple places in the application. It is very easy to create a Javascript component and use it in the application. You can easily implement some of the common functionalities in the Javascript component and use it in the application. We are currently have some very basic components which we are planning to expand in the future. + +## How to use Javascript Components? + From 4068b2705d138570fb657cf9329f5cd6cdc2c880 Mon Sep 17 00:00:00 2001 From: "Md. Almas Ali" Date: Sat, 10 Feb 2024 02:32:21 +0600 Subject: [PATCH 08/14] docs: added outdated docs warning. --- docs_src/docs/theme/main.html | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs_src/docs/theme/main.html b/docs_src/docs/theme/main.html index 41af1c4..db07bc3 100644 --- a/docs_src/docs/theme/main.html +++ b/docs_src/docs/theme/main.html @@ -1,10 +1,12 @@ {% extends "base.html" %} - + {% block announce %} {% include 'announce.html' ignore missing %} {% endblock %} - -{% block content %} - {{ super() }} - -{% endblock %} \ No newline at end of file + +{% block outdated %} + You're not viewing the latest version. + + Click here to go to latest. + +{% endblock %} From 85a50b6665a1b79ea6e5d92bc04572058aaea260 Mon Sep 17 00:00:00 2001 From: "Md. Almas Ali" Date: Sat, 10 Feb 2024 02:33:39 +0600 Subject: [PATCH 09/14] refactor: version update. --- fronty/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fronty/__init__.py b/fronty/__init__.py index a396ced..1590db1 100644 --- a/fronty/__init__.py +++ b/fronty/__init__.py @@ -1,4 +1,4 @@ -__version__ = '0.0.3' +__version__ = '0.0.6' class Fronty: def __init__(self, file_path: str) -> None: From 5ff9adade33698ff22e7cf389066451e65ed2532 Mon Sep 17 00:00:00 2001 From: "Md. Almas Ali" Date: Sat, 10 Feb 2024 02:34:45 +0600 Subject: [PATCH 10/14] fix: object __str__, __repr__ return types. --- fronty/css/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fronty/css/__init__.py b/fronty/css/__init__.py index 179e8ba..9eb5333 100644 --- a/fronty/css/__init__.py +++ b/fronty/css/__init__.py @@ -3,7 +3,7 @@ def __init__(self, css): self.css = css def __str__(self): - return '' + return self.render() def __add__(self, other): return BaseCSS(self.css + other.css) @@ -12,7 +12,7 @@ def __radd__(self, other): return BaseCSS(other.css + self.css) def __repr__(self): - return f'' + return f'' def __call__(self): return self From e42cbb027faafebb803b8207e8672bb9abfe544e Mon Sep 17 00:00:00 2001 From: "Md. Almas Ali" Date: Sat, 10 Feb 2024 02:36:01 +0600 Subject: [PATCH 11/14] feat: added AnyHTMLElement type, Style.render() formattings. --- fronty/html/__init__.py | 73 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/fronty/html/__init__.py b/fronty/html/__init__.py index bab3117..b678e13 100644 --- a/fronty/html/__init__.py +++ b/fronty/html/__init__.py @@ -1,3 +1,6 @@ +from typing import Union + + class BaseElement: '''Base element.''' @@ -321,6 +324,12 @@ def __init__(self, *children, **attributes): self.attributes['href'] = attributes['href'] if 'href' in attributes else '' self.attributes['rel'] = 'stylesheet' if 'rel' not in attributes else attributes['rel'] + def render(self): + '''render all inner css.Selector elements''' + _styles = ''.join(child.render() for child in self.children) + _is_space = ' ' if self._render_attributes() else '' + return f'<{self.tag}{_is_space}{self._render_attributes()}>{_styles}' + class Body(BaseElement): '''Body element.''' @@ -769,3 +778,67 @@ def __add__(self, other): def __str__(self): return self.render() + + +AnyHTMLElement = Union[ + Html, + Head, + Title, + Script, + Style, + Body, + Meta, + Link, + Anchor, + Image, + Button, + Input, + Text, + Break, + Form, + Label, + Select, + Option, + Table, + Thead, + Tbody, + Tr, + Th, + Td, + H1, + H2, + H3, + H4, + H5, + H6, + Ul, + Ol, + Li, + Span, + Div, + Nav, + Footer, + Header, + Section, + Article, + Aside, + Main, + Figure, + Figcaption, + Dl, + Dt, + Dd, + Small, + Time, + Strong, + Em, + Mark, + Code, + Pre, + Blockquote, + Iframe, + Video, + Audio, + Source, + Empty, +] From 5a4b3f308ad49f84e74dfb9439e967759cf83de7 Mon Sep 17 00:00:00 2001 From: "Md. Almas Ali" Date: Sat, 10 Feb 2024 02:37:16 +0600 Subject: [PATCH 12/14] fix: html.Style render issue. --- fronty/html/widgets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fronty/html/widgets.py b/fronty/html/widgets.py index 6f1e2cc..5cc38d2 100644 --- a/fronty/html/widgets.py +++ b/fronty/html/widgets.py @@ -129,7 +129,7 @@ def __get_loginform(self): # All styles are included here if load_css is True. html.Style( - styles.render() + styles ) if self.load_css is True else html.Style(), html.Form( @@ -197,7 +197,7 @@ def __get_registrationform(self): return html.Section( html.Style( - styles.render() + styles ) if self.load_css is True else html.Style(), html.Form( From 5f60b5b2d4e751ebb02dca9bf58a0a301d99b332 Mon Sep 17 00:00:00 2001 From: "Md. Almas Ali" Date: Sat, 10 Feb 2024 02:38:01 +0600 Subject: [PATCH 13/14] docs: added detailed customization documentation. --- docs_src/docs/customization/customized-css.md | 1 + docs_src/docs/customization/customized-js.md | 1 + docs_src/docs/customization/introduction.md | 15 +++++++++++++++ 3 files changed, 17 insertions(+) create mode 100644 docs_src/docs/customization/customized-css.md create mode 100644 docs_src/docs/customization/customized-js.md create mode 100644 docs_src/docs/customization/introduction.md diff --git a/docs_src/docs/customization/customized-css.md b/docs_src/docs/customization/customized-css.md new file mode 100644 index 0000000..d220605 --- /dev/null +++ b/docs_src/docs/customization/customized-css.md @@ -0,0 +1 @@ +# Customizing CSS Components diff --git a/docs_src/docs/customization/customized-js.md b/docs_src/docs/customization/customized-js.md new file mode 100644 index 0000000..e6d1075 --- /dev/null +++ b/docs_src/docs/customization/customized-js.md @@ -0,0 +1 @@ +# Customizing JavaScript Components diff --git a/docs_src/docs/customization/introduction.md b/docs_src/docs/customization/introduction.md new file mode 100644 index 0000000..f6a26ce --- /dev/null +++ b/docs_src/docs/customization/introduction.md @@ -0,0 +1,15 @@ +# Customization of the components + +## What is Customization? + +When we talk about customization, we are talking about the ability to change the behavior of the components. This can be done by changing the default behavior of the components or by adding new behavior to the components. This can be done by creating a new component or by extending the existing component. + +## How to Customize Components? + +Customization of the components can be done by creating a new component or by extending the existing component. The new component can be created by subclassing the `BaseElement` class and adding the new behavior to the component. The existing component can be extended by subclassing the existing component and adding the new behavior to the component. + +We will see how to create a new component and how to extend the existing component in the following sections. + +- [HTML Customization](./customized-html.md) +- [CSS Customization](./customized-css.md) +- [Javascript Customization](./customized-js.md) From d34340cdb704ad60fd6cac3e555b9f9e4be182e5 Mon Sep 17 00:00:00 2001 From: "Md. Almas Ali" Date: Sat, 10 Feb 2024 02:38:51 +0600 Subject: [PATCH 14/14] feat: working on clickable action buttons. --- examples/Action button/app.py | 103 ++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 examples/Action button/app.py diff --git a/examples/Action button/app.py b/examples/Action button/app.py new file mode 100644 index 0000000..db6e085 --- /dev/null +++ b/examples/Action button/app.py @@ -0,0 +1,103 @@ +from fronty.html import widgets +from fronty import ( + html, + css, + js +) + +import flask + +app = flask.Flask(__name__) + + +@app.route('/') +def page(): + def button_event_1(event, id): + return js.Event(event, id=id) + + return html.Html( + html.Head( + html.Title('Action button'), + html.Style( + css.Selector('button').properties({ + 'padding': '10px', + 'margin': '10px', + 'font-size': '20px', + 'cursor': 'pointer', + 'background-color': 'lightblue', + 'color': '#000', + 'border': 'none', + 'border-radius': '5px', + }), + css.Selector('button:hover').properties({ + 'background-color': 'lightgreen', + }), + css.Selector('.theme').properties({ + 'background-color': '#f0f0f0', + 'color': '#000', + }), + ), + ), + html.Body( + html.Div( + html.Button('Click me', id='button1', + onclick="alert('Button clicked');"), + html.Button('Python Click me', id='button2', + onclick=js.Alert('Python Alert')), + # html.Button('Python Click me', id='button3', onclick=js.Event('click', id='button3')), + # html.Button('Python Click me', id='button4', onclick=button_event_1('click', 'button4')), + js.ConsoleLog('Hello world').script_wrap(), + html.Button('Console log click', id='button5', + onclick=js.ConsoleLog('Python Console Log')), + + js.Function('squreNumber', ['x'], + js.ConsoleLog('x')).script_wrap(), + js.SetTimeout('squreNumber(4)', 1000).script_wrap(), + ), + ) + ).render() + + +@app.route("/login", methods=['GET', 'POST']) +def login(): + if flask.request.method == 'POST': + print(flask.request.form) + # print(widgets.FormWidget.get_form_data(flask.request.form)) + + return html.Html( + html.Head( + html.Meta(charset="utf-8"), + html.Title("Test case"), + ), + html.Body( + widgets.FormWidget( + load_css=True, + method='POST', + action='/login', + ).add_element( + html.Div( + html.Label('Mobile number') + .attr('for', 'mobile'), + html.Input( + type='phone', + name='mobile', + required="", + placeholder='Enter your mobile number', + ) + .style(**{ + 'width': '100%', + 'padding': '12px 20px', + 'margin': '8px 0', + 'display': 'inline-block', + 'border': '1px solid #ccc', + 'box-sizing': 'border-box', + }), + ), + first=True + ) + ) + ).render() + + +if __name__ == '__main__': + app.run(debug=True)