updated layouts with new components

This commit is contained in:
sairaj mote 2021-07-19 19:52:40 +05:30
parent c51d69c2ac
commit 87e10e8c0b
35 changed files with 4237 additions and 14243 deletions

View File

@ -1,65 +1,88 @@
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@500;600;700&family=Roboto:wght@400;500;700&display=swap");
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
margin: 0;
font-family: 'Roboto', sans-serif;
box-sizing: border-box;
font-family: "Roboto", sans-serif;
}
:root {
font-size: clamp(1rem, 1.2vmax, 3rem);
}
html, body {
height: 100%;
scroll-behavior: smooth;
}
html {
margin-left: calc(100vw - 100%);
}
body {
--accent-color: #303F9F;
--text-color: 17, 17, 17;
--foreground-color: 255, 255, 255;
background: rgba(var(--foreground-color), 1);
color: rgba(var(--text-color), 1);
font-size: 16px;
background: rgba(var(--background-color), 1);
}
body,
body * {
--accent-color: #0D7377;
--text-color: 17, 17, 17;
--background-color: 255, 255, 255;
--danger-color: red;
}
body[data-theme="dark"] {
--accent-color: #4a5cd3;
--foreground-color: 20, 20, 20;
--text-color: 238, 238, 238;
}
h1, h2, h3, h4, h5 {
font-family: 'Poppins', sans-serif;
text-transform: capitalize;
}
h1 {
font-size: 3rem;
}
h2 {
font-size: 2rem;
}
h3 {
font-size: 1.5rem;
}
h4 {
font-size: 1rem;
}
h5 {
font-size: 0.8rem;
body[data-theme=dark],
body[data-theme=dark] * {
--accent-color: #32E0C4;
--text-color: 240, 240, 240;
--text-color-light: 170, 170, 170;
--background-color: 10, 10, 10;
--danger-color: rgb(255, 106, 106);
}
p {
margin: 1.5rem 0;
font-size: 0.8;
max-width: 65ch;
line-height: 1.7;
margin-bottom: 1.5rem;
color: rgba(var(--text-color), 0.8);
}
p:not(:last-of-type) {
margin-bottom: 1rem;
}
img {
object-fit: cover;
}
a {
color: inherit;
text-decoration: none;
}
a:focus-visible {
box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset;
}
button {
display: inline-flex;
border: none;
background-color: inherit;
}
a:any-link:focus-visible {
outline: rgba(var(--text-color), 1) 0.1rem solid;
}
sm-button {
--border-radius: 0.3rem;
}
ul {
list-style: none;
}
.flex {
display: flex;
}
.grid {
display: grid;
}
.hide {
opacity: 0;
@ -70,102 +93,263 @@ p {
display: none !important;
}
.icon {
height: 1.2rem;
width: 1.2rem;
fill: none;
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
.no-transformations {
transform: none !important;
}
#navbar {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: space-evenly;
-ms-flex-pack: space-evenly;
justify-content: space-evenly;
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: auto;
border-top: solid 1px rgba(var(--text-color), 0.2);
border-right: none;
z-index: 3;
background: rgba(var(--foreground-color), 1);
.overflow-ellipsis {
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
#navbar .navbar-item {
position: relative;
text-align: center;
cursor: pointer;
padding: 0.3em;
margin: 0.3em;
border-radius: 0.4em;
color: rgba(var(--text-color), 0.8);
font-size: 0.9em;
.breakable {
overflow-wrap: break-word;
word-wrap: break-word;
-ms-word-break: break-all;
word-break: break-word;
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
.full-bleed {
grid-column: 1/4;
}
.h1 {
font-size: 2.5rem;
}
.h2 {
font-size: 2rem;
}
.h3 {
font-size: 1.4rem;
}
.h4 {
font-size: 1rem;
}
.h5 {
font-size: 0.8rem;
}
.uppercase {
text-transform: uppercase;
width: 100%;
letter-spacing: 0.08em;
-webkit-tap-highlight-color: transparent;
}
#navbar .navbar-item h5 {
font-size: 0.6em;
margin-top: 0.4em;
font-weight: 700;
}
#navbar .active {
color: var(--accent-color);
}
#navbar .active .icon {
stroke: var(--accent-color);
}
#main_header {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
padding: 1rem 0;
}
#logo {
display: -ms-grid;
display: grid;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
width: 100%;
-ms-grid-columns: auto 1fr;
grid-template-columns: auto 1fr;
gap: 0.6rem 0.6rem;
margin-right: 1rem;
}
#logo h4 {
.capitalize {
text-transform: capitalize;
font-size: 1.2rem;
font-weight: 600;
}
#logo h5 {
font-family: 'Roboto', sans-serif;
.flex {
display: flex;
}
.grid {
display: grid;
}
.grid-3 {
grid-template-columns: 1fr auto auto;
}
.flow-column {
grid-auto-flow: column;
}
.gap-0-5 {
gap: 0.5rem;
}
.gap-1 {
gap: 1rem;
}
.gap-1-5 {
gap: 1.5rem;
}
.gap-2 {
gap: 2rem;
}
.gap-3 {
gap: 3rem;
}
.text-align-right {
text-align: right;
}
.align-start {
align-items: flex-start;
}
.align-center {
align-items: center;
}
.text-center {
text-align: center;
}
.justify-start {
justify-content: start;
}
.justify-center {
justify-content: center;
}
.justify-right {
margin-left: auto;
}
.align-self-center {
align-self: center;
}
.justify-self-center {
justify-self: center;
}
.justify-self-start {
justify-self: start;
}
.justify-self-end {
justify-self: end;
}
.direction-column {
flex-direction: column;
}
.space-between {
justify-content: space-between;
}
.w-100 {
width: 100%;
}
.color-0-8 {
color: rgba(var(--text-color), 0.8);
}
.weight-400 {
font-weight: 400;
}
.weight-500 {
font-weight: 500;
}
.ripple {
position: absolute;
border-radius: 50%;
transform: scale(0);
background: rgba(var(--text-color), 0.16);
pointer-events: none;
}
.interact {
position: relative;
overflow: hidden;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
.observe-empty-state:empty {
display: none;
}
.observe-empty-state:not(:empty) ~ .empty-state {
display: none;
}
.icon {
width: 1.5rem;
height: 1.5rem;
fill: rgba(var(--text-color), 0.9);
}
.button__icon {
height: 1.2rem;
width: 1.2rem;
}
.button__icon--left {
margin-right: 0.5rem;
}
.button__icon--right {
margin-left: 0.5rem;
}
#confirmation_popup,
#prompt_popup {
flex-direction: column;
}
#confirmation_popup h4,
#prompt_popup h4 {
font-weight: 500;
margin-bottom: 0.5rem;
}
#confirmation_popup sm-button,
#prompt_popup sm-button {
margin: 0;
}
#confirmation_popup .flex,
#prompt_popup .flex {
padding: 0;
margin-top: 1rem;
}
#confirmation_popup .flex sm-button:first-of-type,
#prompt_popup .flex sm-button:first-of-type {
margin-right: 0.6rem;
margin-left: auto;
}
h1, h2, h3, h4.h5 {
font-family: "Poppins", sans-serif;
}
h2 {
margin: 3rem 0 1rem 0;
text-transform: capitalize;
}
main {
display: grid;
height: 100%;
grid-template-rows: auto 1fr auto;
grid-template-areas: "main-header" "." "side-nav";
}
#main_header {
grid-area: main-header;
padding: 1rem 1.5rem;
border-bottom: 1px solid rgba(var(--text-color), 0.1);
}
#logo {
display: grid;
align-items: center;
width: 100%;
grid-template-columns: auto 1fr;
gap: 0 0.5rem;
margin-right: 1rem;
}
#logo h4 {
text-transform: capitalize;
font-size: 1rem;
font-weight: 600;
}
#logo #main_logo {
height: 1.4rem;
width: 1.4rem;
@ -173,175 +357,126 @@ p {
stroke: none;
}
.toggle {
position: relative;
cursor: pointer;
z-index: 1;
padding: 0;
.right {
max-height: 100%;
overflow-y: auto;
}
.toggle input[type='checkbox'] {
display: none;
#side_nav {
grid-area: side-nav;
}
#side_nav h4 {
font-size: 0.9rem;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 1.5rem;
}
.toggle .switch {
overflow: hidden;
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
justify-items: center;
padding: 0.2rem;
min-height: 1.6rem;
max-height: 1.6rem;
border-radius: 0.5rem;
position: relative;
margin: 0;
.nav-list {
list-style: none;
display: flex;
justify-content: space-evenly;
}
.nav-list li {
width: 100%;
}
.toggle .circle {
border-radius: 0.5rem;
-webkit-transition: -webkit-transform 0.3s;
transition: -webkit-transform 0.3s;
transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
fill: rgba(var(--text-color), 0.8);
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
height: 1.2rem;
width: 1.2rem;
.nav-list__item {
display: flex;
padding: 0.8rem 1.5rem;
text-transform: capitalize;
}
.nav-list__item--active {
color: var(--accent-color);
}
.nav-list__item--active .icon {
fill: var(--accent-color);
}
.toggle .circle:first-of-type {
margin-bottom: 0.4rem;
.right {
padding: 1.5rem;
}
.toggle .circle line {
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
}
.toggle input:checked ~ .switch .circle {
-webkit-transform: translateY(-1.7rem);
transform: translateY(-1.7rem);
.right h1 {
margin-bottom: 1.5rem;
}
.page {
padding: 2rem 0;
padding-bottom: 4rem;
}
.options-tab {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
margin-top: 1rem;
margin-bottom: 1rem;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
flex-direction: column;
padding-bottom: 3rem;
}
.options-tab .option {
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
border-radius: 0.4rem;
padding: 1.5rem;
margin-right: 1rem;
margin-bottom: 1rem;
width: 9rem;
border: solid 1px rgba(var(--text-color), 0.2);
text-transform: capitalize;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
@media screen and (max-width: 640px) {
main {
grid-template-rows: auto 1fr;
grid-template-columns: 1fr;
}
.options-tab .option .icon {
background: rgba(var(--text-color), 0.1);
height: 2.8rem;
width: 2.8rem;
padding: 0.8rem;
border-radius: 2rem;
margin-bottom: 1rem;
stroke: rgba(var(--text-color), 0.4);
.nav-list__item {
flex-direction: column;
justify-content: center;
align-items: center;
padding: 0.4rem;
}
.nav-list__item span {
font-size: 0.8rem;
margin-top: 0.3rem;
}
}
@media screen and (min-width: 640px) {
sm-popup {
--width: 32rem;
}
.options-tab .option h4 {
font-weight: 400;
font-size: 0.9rem;
}
main {
grid-template-columns: 14rem minmax(0, 1fr);
grid-template-rows: auto 1fr;
grid-template-areas: "main-header main-header" "side-nav .";
}
#home_page h1 {
margin-top: 3vw;
font-weight: 600;
}
.nav-list {
flex-direction: column;
}
#home_page p {
margin-bottom: 3rem;
}
.nav-list__item {
align-items: center;
justify-content: start;
}
.nav-list__item--active {
background: rgba(var(--text-color), 0.06);
}
.nav-list__item .icon {
margin-right: 0.5rem;
}
#home_page h2 {
margin-bottom: 1rem;
}
.right {
display: grid;
grid-template-columns: 1fr 90% 1fr;
}
.right > * {
grid-column: 2/3;
}
@media only screen and (min-width: 640px) {
body {
padding: 1rem 6vw;
margin-left: 6rem;
}
p {
max-width: 40rem;
}
#navbar {
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-align: stretch;
-ms-flex-align: stretch;
align-items: stretch;
left: 0;
bottom: 0;
top: 0;
right: auto;
width: 6rem;
border-top: none;
border-right: solid 1px rgba(var(--text-color), 0.2);
}
#navbar .navbar-item {
width: auto;
padding: 1.4em 0;
margin: 0.6em;
}
#navbar .navbar-item .icon {
height: 1.4rem;
width: 1.4rem;
}
#navbar .navbar-item h5 {
font-size: 0.8em;
}
#navbar .navbar-item:hover .icon {
stroke: rgba(var(--text-color), 1);
}
#navbar .navbar-item:hover h5 {
color: rgba(var(--text-color), 1);
}
#navbar .navbar-item.active:hover .icon {
stroke: var(--accent-color);
}
#navbar .navbar-item.active:hover h5 {
color: var(--accent-color);
.page__title {
font-size: 2.5rem;
}
}
/*# sourceMappingURL=main.css.map */
@media (any-hover: hover) {
::-webkit-scrollbar {
width: 0.5rem;
height: 0.5rem;
}
::-webkit-scrollbar-thumb {
background: rgba(var(--text-color), 0.3);
border-radius: 1rem;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(var(--text-color), 0.5);
}
.nav-list__item:hover {
background: rgba(var(--text-color), 0.1);
cursor: pointer;
}
}

1
Layouts/boxes layout/css/main.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,52 +1,79 @@
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@500;600;700&family=Roboto:wght@400;500;700&display=swap');
*{
box-sizing: border-box;
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Roboto', sans-serif;
}
:root{
font-size: clamp(1rem, 1.2vmax, 3rem);
}
html, body{
height: 100%;
scroll-behavior: smooth;
}
html{
margin-left: calc(100vw - 100%);
}
body{
--accent-color: #303F9F;
--text-color: 17, 17, 17;
--foreground-color: 255, 255, 255;
background: rgba(var(--foreground-color), 1);
body {
&,
*{
--accent-color: #0D7377;
--text-color: 17, 17, 17;
--background-color: 255, 255, 255;
--danger-color: red;
}
color: rgba(var(--text-color), 1);
font-size: 16px;
background: rgba(var(--background-color), 1);
}
body[data-theme="dark"]{
--accent-color: #4a5cd3;
--foreground-color: 20, 20, 20;
--text-color: 238, 238, 238;
body[data-theme='dark']{
&,
*{
--accent-color: #32E0C4;
--text-color: 240, 240, 240;
--text-color-light: 170, 170, 170;
--background-color: 10, 10, 10;
--danger-color: rgb(255, 106, 106);
}
}
h1, h2, h3, h4, h5{
font-family: 'Poppins', sans-serif;
text-transform: capitalize;
}
h1{
font-size: 3rem;
}
h2{
font-size: 2rem;
}
h3{
font-size: 1.5rem;
}
h4{
font-size: 1rem;
}
h5{
font-size: 0.8rem;
}
p{
margin: 1.5rem 0;
p {
font-size: 0.8;
max-width: 65ch;
line-height: 1.7;
margin-bottom: 1.5rem;
color: rgba(var(--text-color), 0.8);
&:not(:last-of-type){
margin-bottom: 1rem;
}
}
img{
object-fit: cover;
}
a{
color: inherit;
text-decoration: none;
&:focus-visible{
box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset;
}
}
button{
display: inline-flex;
border: none;
background-color: inherit;
}
a:any-link:focus-visible{
outline: rgba(var(--text-color), 1) 0.1rem solid;
}
sm-button{
--border-radius: 0.3rem;
}
ul{
list-style: none;
}
.flex{
display: flex;
}
.grid{
display: grid;
}
.hide{
opacity: 0;
@ -55,76 +82,212 @@ p{
.hide-completely{
display: none !important;
}
.no-transformations{
transform: none !important;
}
.overflow-ellipsis{
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.breakable{
overflow-wrap: break-word;
word-wrap: break-word;
-ms-word-break: break-all;
word-break: break-word;
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
.full-bleed{
grid-column: 1/4;
}
.h1{
font-size: 2.5rem;
}
.h2{
font-size: 2rem;
}
.h3{
font-size: 1.4rem;
}
.h4{
font-size: 1rem;
}
.h5{
font-size: 0.8rem;
}
.uppercase{
text-transform: uppercase;
}
.capitalize{
text-transform: capitalize;
}
.flex{
display: flex;
}
.grid{
display: grid;
}
.grid-3{
grid-template-columns: 1fr auto auto;
}
.flow-column{
grid-auto-flow: column;
}
.gap-0-5{
gap: 0.5rem;
}
.gap-1{
gap: 1rem;
}
.gap-1-5{
gap: 1.5rem;
}
.gap-2{
gap: 2rem;
}
.gap-3{
gap: 3rem;
}
.text-align-right{
text-align: right;
}
.align-start{
align-items: flex-start;
}
.align-center{
align-items: center;
}
.text-center{
text-align: center;
}
.justify-start{
justify-content: start;
}
.justify-center{
justify-content: center;
}
.justify-right{
margin-left: auto;
}
.align-self-center{
align-self: center;
}
.justify-self-center{
justify-self: center;
}
.justify-self-start{
justify-self: start;
}
.justify-self-end{
justify-self: end;
}
.direction-column{
flex-direction: column;
}
.space-between{
justify-content: space-between;
}
.w-100{
width: 100%;
}
.color-0-8{
color: rgba(var(--text-color), 0.8);
}
.weight-400{
font-weight: 400;
}
.weight-500{
font-weight: 500;
}
.ripple{
position: absolute;
border-radius: 50%;
transform: scale(0);
background: rgba(var(--text-color), 0.16);
pointer-events: none;
}
.interact{
position: relative;
overflow: hidden;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
.observe-empty-state:empty{
display: none;
}
.observe-empty-state:not(:empty) ~ .empty-state{
display: none;
}
.icon{
width: 1.5rem;
height: 1.5rem;
fill: rgba(var(--text-color), 0.9);
}
.button__icon{
height: 1.2rem;
width: 1.2rem;
fill: none;
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
&--left{
margin-right: 0.5rem;
}
&--right{
margin-left: 0.5rem;
}
}
#navbar{
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-evenly;
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: auto;
border-top: solid 1px rgba(var(--text-color), 0.2);
border-right: none;
z-index: 3;
background: rgba(var(--foreground-color), 1);
.navbar-item{
position: relative;
text-align: center;
cursor: pointer;
padding: 0.3em;
margin: 0.3em;
border-radius: 0.4em;
color: rgba(var(--text-color), 0.8);
font-size: 0.9em;
text-transform: uppercase;
width: 100%;
letter-spacing: 0.08em;
-webkit-tap-highlight-color: transparent;
h5{
font-size: 0.6em;
margin-top: 0.4em;
font-weight: 700;
}
}
.active{
color: var(--accent-color);
.icon{
stroke: var(--accent-color);
#confirmation_popup,
#prompt_popup {
flex-direction: column;
h4 {
font-weight: 500;
margin-bottom: 0.5rem;
}
sm-button{
margin: 0;
}
.flex {
padding: 0;
margin-top: 1rem;
sm-button:first-of-type {
margin-right: 0.6rem;
margin-left: auto;
}
}
}
h1,h2,h3,h4.h5{
font-family: 'Poppins', sans-serif;
}
h2{
margin: 3rem 0 1rem 0;
text-transform: capitalize;
}
main{
display: grid;
height: 100%;
grid-template-rows: auto 1fr auto;
grid-template-areas: 'main-header' '.' 'side-nav';
}
#main_header{
display: flex;
padding: 1rem 0;
grid-area: main-header;
padding: 1rem 1.5rem;
border-bottom: 1px solid rgba(var(--text-color), .1);
}
#logo{
display: grid;
align-items: center;
width: 100%;
grid-template-columns: auto 1fr;
gap: 0.6rem 0.6rem;
gap: 0 0.5rem;
margin-right: 1rem;
h4{
text-transform: capitalize;
font-size: 1.2rem;
font-size: 1rem;
font-weight: 600;
}
h5{
font-family: 'Roboto', sans-serif;
font-weight: 400;
}
#main_logo{
height: 1.4rem;
width: 1.4rem;
@ -132,141 +295,113 @@ p{
stroke: none;
}
}
.toggle{
position: relative;
cursor: pointer;
z-index: 1;
padding: 0;
input[type='checkbox']{
display: none;
.right{
max-height: 100%;
overflow-y: auto;
}
#side_nav{
grid-area: side-nav;
h4{
font-size: 0.9rem;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 1.5rem;
}
.switch{
overflow: hidden;
display: inline-flex;
flex-direction: column;
justify-items: center;
padding: 0.2rem;
min-height: 1.6rem;
max-height: 1.6rem;
border-radius: 0.5rem;
position: relative;
margin: 0;
}
.nav-list{
list-style: none;
display: flex;
justify-content: space-evenly;
li{
width: 100%;
}
.circle{
border-radius: 0.5rem;
transition: transform 0.3s;
&:first-of-type{
margin-bottom: 0.4rem;
}
fill: rgba(var(--text-color), 0.8);
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
height: 1.2rem;
width: 1.2rem;
line{
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
}
.nav-list__item{
display: flex;
padding: 0.8rem 1.5rem;
text-transform: capitalize;
&--active{
color: var(--accent-color);
.icon{
fill: var(--accent-color);
}
}
input:checked ~ .switch .circle{
transform: translateY(-1.7rem);
}
.right{
padding: 1.5rem;
h1{
margin-bottom: 1.5rem;
}
}
.page{
padding: 2rem 0;
padding-bottom: 4rem;
}
.options-tab{
display: flex;
margin-top: 1rem;
margin-bottom: 1rem;
flex-wrap: wrap;
.option{
display: inline-flex;
flex-direction: column;
padding-bottom: 3rem;
}
@media screen and (max-width: 640px){
main{
grid-template-rows: auto 1fr;
grid-template-columns: 1fr;
}
.nav-list__item{
flex-direction: column;
border-radius: 0.4rem;
padding: 1.5rem;
margin-right: 1rem;
margin-bottom: 1rem;
width: 9rem;
border: solid 1px rgba(var(--text-color), 0.2);
text-transform: capitalize;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
.icon{
background: rgba(var(--text-color), 0.1);
height: 2.8rem;
width: 2.8rem;
padding: 0.8rem;
border-radius: 2rem;
margin-bottom: 1rem;
stroke: rgba(var(--text-color), 0.4);
}
h4{
font-weight: 400;
font-size: 0.9rem;
}
}
}
#home_page{
h1{
margin-top: 3vw;
font-weight: 600;
}
p{
margin-bottom: 3rem;
}
h2{
margin-bottom: 1rem;
}
}
@media only screen and (min-width: 640px){
body{
padding: 1rem 6vw;
margin-left: 6rem;
}
p{
max-width: 40rem;
}
#navbar{
justify-content: center;
flex-direction: column;
align-items: stretch;
left: 0;
bottom: 0;
top: 0;
right: auto;
width: 6rem;
border-top: none;
border-right: solid 1px rgba(var(--text-color), 0.2);
.navbar-item{
width: auto;
padding: 1.4em 0;
margin: 0.6em;
.icon{
height: 1.4rem;
width: 1.4rem;
}
h5{
font-size: 0.8em;
}
&:hover{
.icon{
stroke: rgba(var(--text-color), 1);
}
h5{
color: rgba(var(--text-color), 1);
}
}
&.active:hover{
.icon{
stroke: var(--accent-color);
}
h5{
color: var(--accent-color);
}
}
align-items: center;
padding: 0.4rem;
span{
font-size: 0.8rem;
margin-top: 0.3rem;
}
}
}
@media screen and (min-width: 640px){
sm-popup{
--width: 32rem;
}
main{
grid-template-columns: 14rem minmax(0, 1fr);
grid-template-rows: auto 1fr;
grid-template-areas: 'main-header main-header' 'side-nav .';
}
.nav-list{
flex-direction: column;
}
.nav-list__item{
align-items: center;
justify-content: start;
&--active{
background: rgba(var(--text-color), .06);
}
.icon{
margin-right: 0.5rem;
}
}
.right{
display: grid;
grid-template-columns: 1fr 90% 1fr;
& > * {
grid-column: 2/3;
}
}
.page__title{
font-size: 2.5rem;
}
}
@media (any-hover: hover){
::-webkit-scrollbar{
width: 0.5rem;
height: 0.5rem;
}
::-webkit-scrollbar-thumb{
background: rgba(var(--text-color), 0.3);
border-radius: 1rem;
&:hover{
background: rgba(var(--text-color), 0.5);
}
}
.nav-list__item:hover{
background: rgba(var(--text-color), .1);
cursor: pointer;
}
}

View File

@ -6,131 +6,82 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="css/main.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;700&family=Roboto+Mono&family=Roboto:wght@400;500;700&display=swap"
rel="stylesheet">
</head>
<body data-theme="light">
<header id="main_header" class="flex">
<div id="logo">
<svg id="main_logo" viewBox="0 0 27.25 32">
<title>RanchiMall</title>
<path
d="M27.14,30.86c-.74-2.48-3-4.36-8.25-6.94a20,20,0,0,1-4.2-2.49,6,6,0,0,1-1.25-1.67,4,4,0,0,1,0-2.26c.37-1.08.79-1.57,3.89-4.55a11.66,11.66,0,0,0,3.34-4.67,6.54,6.54,0,0,0,.05-2.82C20,3.6,18.58,2,16.16.49c-.89-.56-1.29-.64-1.3-.24a3,3,0,0,1-.3.72l-.3.55L13.42.94C13,.62,12.4.26,12.19.15c-.4-.2-.73-.18-.72.05a9.39,9.39,0,0,1-.61,1.33s-.14,0-.27-.13C8.76.09,8-.27,8,.23A11.73,11.73,0,0,1,6.76,2.6C4.81,5.87,2.83,7.49.77,7.49c-.89,0-.88,0-.61,1,.22.85.33.92,1.09.69A5.29,5.29,0,0,0,3,8.33c.23-.17.45-.29.49-.26a2,2,0,0,1,.22.63A1.31,1.31,0,0,0,4,9.34a5.62,5.62,0,0,0,2.27-.87L7,8l.13.55c.19.74.32.82,1,.65a7.06,7.06,0,0,0,3.46-2.47l.6-.71-.06.64c-.17,1.63-1.3,3.42-3.39,5.42L6.73,14c-3.21,3.06-3,5.59.6,8a46.77,46.77,0,0,0,4.6,2.41c.28.13,1,.52,1.59.87,3.31,2,4.95,3.92,4.95,5.93a2.49,2.49,0,0,0,.07.77h0c.09.09,0,.1.9-.14a2.61,2.61,0,0,0,.83-.32,3.69,3.69,0,0,0-.55-1.83A11.14,11.14,0,0,0,17,26.81a35.7,35.7,0,0,0-5.1-2.91C9.37,22.64,8.38,22,7.52,21.17a3.53,3.53,0,0,1-1.18-2.48c0-1.38.71-2.58,2.5-4.23,2.84-2.6,3.92-3.91,4.67-5.65a3.64,3.64,0,0,0,.42-2A3.37,3.37,0,0,0,13.61,5l-.32-.74.29-.48c.17-.27.37-.63.46-.8l.15-.3.44.64a5.92,5.92,0,0,1,1,2.81,5.86,5.86,0,0,1-.42,1.94c0,.12-.12.3-.15.4a9.49,9.49,0,0,1-.67,1.1,28,28,0,0,1-4,4.29C8.62,15.49,8.05,16.44,8,17.78a3.28,3.28,0,0,0,1.11,2.76c.95,1,2.07,1.74,5.25,3.32,3.64,1.82,5.22,2.9,6.41,4.38A4.78,4.78,0,0,1,21.94,31a3.21,3.21,0,0,0,.14.92,1.06,1.06,0,0,0,.43-.05l.83-.22.46-.12-.06-.46c-.21-1.53-1.62-3.25-3.94-4.8a37.57,37.57,0,0,0-5.22-2.82A13.36,13.36,0,0,1,11,21.19a3.36,3.36,0,0,1-.8-4.19c.41-.85.83-1.31,3.77-4.15,2.39-2.31,3.43-4.13,3.43-6a5.85,5.85,0,0,0-2.08-4.29c-.23-.21-.44-.43-.65-.65A2.5,2.5,0,0,1,15.27.69a10.6,10.6,0,0,1,2.91,2.78A4.16,4.16,0,0,1,19,6.16a4.91,4.91,0,0,1-.87,3c-.71,1.22-1.26,1.82-4.27,4.67a9.47,9.47,0,0,0-2.07,2.6,2.76,2.76,0,0,0-.33,1.54,2.76,2.76,0,0,0,.29,1.47c.57,1.21,2.23,2.55,4.65,3.73a32.41,32.41,0,0,1,5.82,3.24c2.16,1.6,3.2,3.16,3.2,4.8a1.94,1.94,0,0,0,.09.76,4.54,4.54,0,0,0,1.66-.4C27.29,31.42,27.29,31.37,27.14,30.86ZM6.1,7h0a3.77,3.77,0,0,1-1.46.45L4,7.51l.68-.83a25.09,25.09,0,0,0,3-4.82A12,12,0,0,1,8.28.76c.11-.12.77.32,1.53,1l.63.58-.57.84A10.34,10.34,0,0,1,6.1,7Zm5.71-1.78A9.77,9.77,0,0,1,9.24,7.18h0a5.25,5.25,0,0,1-1.17.28l-.58,0,.65-.78a21.29,21.29,0,0,0,2.1-3.12c.22-.41.42-.76.44-.79s.5.43.9,1.24L12,5ZM13.41,3a2.84,2.84,0,0,1-.45.64,11,11,0,0,1-.9-.91l-.84-.9.19-.45c.34-.79.39-.8,1-.31A9.4,9.4,0,0,1,13.8,2.33q-.18.34-.39.69Z" />
</svg>
<span>
<h5>RanchiMall</h5>
<h4>App Name</h4>
</span>
<body data-theme="light" class="hide-completely">
<sm-notifications id="notification_drawer"></sm-notifications>
<audio id="notification_sound">
<source src="https://rmservices.duckdns.org/files/notification-sound.mp3" type="audio/mpeg">
<source src="https://rmservices.duckdns.org/files/notification-sound.ogg" type="audio/ogg">
</audio>
<sm-popup id="confirmation_popup">
<h4 id="confirm_title"></h4>
<p id="confirm_message"></p>
<div class="flex align-center">
<sm-button variant="no-outline" class="cancel-btn">Cancel</sm-button>
<sm-button variant="no-outline" class="submit-btn">OK</button>
</div>
<label class="toggle" title="Change theme">
<input type="checkbox" name="theme toggle" id="theme_toggle">
<div class="switch">
<svg class="circle" viewBox="0 0 64 64">
<title>dark theme</title>
<path
d="M48.25,45.45A27.26,27.26,0,0,1,20.82,18.37,26.75,26.75,0,0,1,27.47.71a31.71,31.71,0,0,0-27,31.2,31.8,31.8,0,0,0,32,31.59A32,32,0,0,0,63.12,41.12,27.59,27.59,0,0,1,48.25,45.45Z"
transform="translate(0 0)" />
</svg>
<svg class="circle" viewBox="0 0 64 64">
<title>light theme</title>
<circle cx="32" cy="32" r="13.9" />
<line x1="32" y1="6.86" x2="32" />
<line x1="32" y1="64" x2="32" y2="57.14" />
<line x1="57.14" y1="32" x2="64" y2="32" />
<line y1="32" x2="6.86" y2="32" />
<line x1="49.78" y1="14.22" x2="54.63" y2="9.37" />
<line x1="9.37" y1="54.63" x2="14.22" y2="49.78" />
<line x1="49.78" y1="49.78" x2="54.63" y2="54.63" />
<line x1="9.37" y1="9.37" x2="14.22" y2="14.22" />
</svg>
</div>
</label>
</header>
<nav id="navbar">
<div class="navbar-item active" onclick="showPage(this, 'home_page')">
<svg class="icon" viewBox="0 0 64 64">
<path
d="M24.77,44.15H40.06V63.5H53.4V36h5.66a3.38,3.38,0,0,0,2.53-5.68l-6.73-7.16V11.26H46.48v3L34.53,1.59a3.49,3.49,0,0,0-5.06,0L2.41,30.35A3.38,3.38,0,0,0,4.94,36H10.6V63.5H24.77" />
</svg>
<h5>Home</h5>
</sm-popup>
<sm-popup id="prompt_popup">
<h4 id="prompt_title"></h4>
<p id="prompt_message"></p>
<sm-input id="prompt_input"></sm-input>
<div class="flex align-center">
<sm-button variant="no-outline" class="cancel-btn">Cancel</sm-button>
<sm-button variant="no-outline" class="submit-btn" type="submit">OK</button>
</div>
<div class="navbar-item" onclick="showPage(this, 'profile_page')">
<svg class="icon" viewBox="0 0 49.54 61.12">
<path
d="M49.34,19.94c7.73,0,13.26,5.26,13.26,14S58.18,50.14,49.71,50.08,36.82,42.66,36.82,33.93s5.53-14,13.26-14"
transform="translate(-25.23 -20)" />
<path
d="M43.83,52c-2.34,4.38-9.77,6.64-15.31,9.06-2.29,1-4.11,13-1.53,13a46.06,46.06,0,0,0,23.51,6,40.48,40.48,0,0,0,22.51-6c2.58,0,.76-12-1.53-13-5.54-2.42-13-4.68-15.31-9.06"
transform="translate(-25.23 -19.44)" />
</svg>
<h5>User</h5>
</div>
</nav>
</sm-popup>
<main>
<section class="page" id="home_page">
<h1>Heading</h1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nisi excepturi eius voluptate quod quasi
dolore, quisquam, voluptatem repellendus sapiente consectetur similique ducimus dicta magni harum,
perspiciatis unde debitis? Eveniet, temporibus!
</p>
<h3>Options</h3>
<div class="options-tab">
<div class="option">
<svg class="icon" viewBox="0 0 64 64">
<title>transfer</title>
<polyline
points="17.04 35.97 14.57 33.5 40.15 7.9 32.75 0.5 55.52 0.5 55.52 23.28 48.12 15.87 23.86 40.14 15.88 48.13 8.48 40.72 8.48 63.5 31.25 63.5 23.85 56.1 49.43 30.5 46.96 28.03" />
</svg>
<h4>Option</h4>
</div>
<div class="option">
<svg class="icon" viewBox="0 0 64 64">
<title>transfer</title>
<polyline
points="17.04 35.97 14.57 33.5 40.15 7.9 32.75 0.5 55.52 0.5 55.52 23.28 48.12 15.87 23.86 40.14 15.88 48.13 8.48 40.72 8.48 63.5 31.25 63.5 23.85 56.1 49.43 30.5 46.96 28.03" />
</svg>
<h4>Option</h4>
</div>
<div class="option">
<svg class="icon" viewBox="0 0 64 64">
<title>transfer</title>
<polyline
points="17.04 35.97 14.57 33.5 40.15 7.9 32.75 0.5 55.52 0.5 55.52 23.28 48.12 15.87 23.86 40.14 15.88 48.13 8.48 40.72 8.48 63.5 31.25 63.5 23.85 56.1 49.43 30.5 46.96 28.03" />
</svg>
<h4>Option</h4>
</div>
<div class="option">
<svg class="icon" viewBox="0 0 64 64">
<title>transfer</title>
<polyline
points="17.04 35.97 14.57 33.5 40.15 7.9 32.75 0.5 55.52 0.5 55.52 23.28 48.12 15.87 23.86 40.14 15.88 48.13 8.48 40.72 8.48 63.5 31.25 63.5 23.85 56.1 49.43 30.5 46.96 28.03" />
</svg>
<h4>Option</h4>
</div>
<header id="main_header" class="flex align-center space-between">
<div id="logo">
<svg id="main_logo" viewBox="0 0 27.25 32">
<title>RanchiMall</title>
<path
d="M27.14,30.86c-.74-2.48-3-4.36-8.25-6.94a20,20,0,0,1-4.2-2.49,6,6,0,0,1-1.25-1.67,4,4,0,0,1,0-2.26c.37-1.08.79-1.57,3.89-4.55a11.66,11.66,0,0,0,3.34-4.67,6.54,6.54,0,0,0,.05-2.82C20,3.6,18.58,2,16.16.49c-.89-.56-1.29-.64-1.3-.24a3,3,0,0,1-.3.72l-.3.55L13.42.94C13,.62,12.4.26,12.19.15c-.4-.2-.73-.18-.72.05a9.39,9.39,0,0,1-.61,1.33s-.14,0-.27-.13C8.76.09,8-.27,8,.23A11.73,11.73,0,0,1,6.76,2.6C4.81,5.87,2.83,7.49.77,7.49c-.89,0-.88,0-.61,1,.22.85.33.92,1.09.69A5.29,5.29,0,0,0,3,8.33c.23-.17.45-.29.49-.26a2,2,0,0,1,.22.63A1.31,1.31,0,0,0,4,9.34a5.62,5.62,0,0,0,2.27-.87L7,8l.13.55c.19.74.32.82,1,.65a7.06,7.06,0,0,0,3.46-2.47l.6-.71-.06.64c-.17,1.63-1.3,3.42-3.39,5.42L6.73,14c-3.21,3.06-3,5.59.6,8a46.77,46.77,0,0,0,4.6,2.41c.28.13,1,.52,1.59.87,3.31,2,4.95,3.92,4.95,5.93a2.49,2.49,0,0,0,.07.77h0c.09.09,0,.1.9-.14a2.61,2.61,0,0,0,.83-.32,3.69,3.69,0,0,0-.55-1.83A11.14,11.14,0,0,0,17,26.81a35.7,35.7,0,0,0-5.1-2.91C9.37,22.64,8.38,22,7.52,21.17a3.53,3.53,0,0,1-1.18-2.48c0-1.38.71-2.58,2.5-4.23,2.84-2.6,3.92-3.91,4.67-5.65a3.64,3.64,0,0,0,.42-2A3.37,3.37,0,0,0,13.61,5l-.32-.74.29-.48c.17-.27.37-.63.46-.8l.15-.3.44.64a5.92,5.92,0,0,1,1,2.81,5.86,5.86,0,0,1-.42,1.94c0,.12-.12.3-.15.4a9.49,9.49,0,0,1-.67,1.1,28,28,0,0,1-4,4.29C8.62,15.49,8.05,16.44,8,17.78a3.28,3.28,0,0,0,1.11,2.76c.95,1,2.07,1.74,5.25,3.32,3.64,1.82,5.22,2.9,6.41,4.38A4.78,4.78,0,0,1,21.94,31a3.21,3.21,0,0,0,.14.92,1.06,1.06,0,0,0,.43-.05l.83-.22.46-.12-.06-.46c-.21-1.53-1.62-3.25-3.94-4.8a37.57,37.57,0,0,0-5.22-2.82A13.36,13.36,0,0,1,11,21.19a3.36,3.36,0,0,1-.8-4.19c.41-.85.83-1.31,3.77-4.15,2.39-2.31,3.43-4.13,3.43-6a5.85,5.85,0,0,0-2.08-4.29c-.23-.21-.44-.43-.65-.65A2.5,2.5,0,0,1,15.27.69a10.6,10.6,0,0,1,2.91,2.78A4.16,4.16,0,0,1,19,6.16a4.91,4.91,0,0,1-.87,3c-.71,1.22-1.26,1.82-4.27,4.67a9.47,9.47,0,0,0-2.07,2.6,2.76,2.76,0,0,0-.33,1.54,2.76,2.76,0,0,0,.29,1.47c.57,1.21,2.23,2.55,4.65,3.73a32.41,32.41,0,0,1,5.82,3.24c2.16,1.6,3.2,3.16,3.2,4.8a1.94,1.94,0,0,0,.09.76,4.54,4.54,0,0,0,1.66-.4C27.29,31.42,27.29,31.37,27.14,30.86ZM6.1,7h0a3.77,3.77,0,0,1-1.46.45L4,7.51l.68-.83a25.09,25.09,0,0,0,3-4.82A12,12,0,0,1,8.28.76c.11-.12.77.32,1.53,1l.63.58-.57.84A10.34,10.34,0,0,1,6.1,7Zm5.71-1.78A9.77,9.77,0,0,1,9.24,7.18h0a5.25,5.25,0,0,1-1.17.28l-.58,0,.65-.78a21.29,21.29,0,0,0,2.1-3.12c.22-.41.42-.76.44-.79s.5.43.9,1.24L12,5ZM13.41,3a2.84,2.84,0,0,1-.45.64,11,11,0,0,1-.9-.91l-.84-.9.19-.45c.34-.79.39-.8,1-.31A9.4,9.4,0,0,1,13.8,2.33q-.18.34-.39.69Z" />
</svg>
<h4>App name</h4>
</div>
</section>
<section id="profile_page" class="page hide-completely">
<h2>User Settings</h2>
</section>
<theme-toggle></theme-toggle>
</header>
<nav id="side_nav">
<ul class="nav-list">
<li>
<a href="#dashboard" class="nav-list__item nav-list__item--active interact">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M13 21V11h8v10h-8zM3 13V3h8v10H3zm6-2V5H5v6h4zM3 21v-6h8v6H3zm2-2h4v-2H5v2zm10 0h4v-6h-4v6zM13 3h8v6h-8V3zm2 2v2h4V5h-4z"/></svg>
<span>
dashboard
</span>
</a>
</li>
<li>
<a href="#settings" class="nav-list__item interact">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M2 12c0-.865.11-1.703.316-2.504A3 3 0 0 0 4.99 4.867a9.99 9.99 0 0 1 4.335-2.505 3 3 0 0 0 5.348 0 9.99 9.99 0 0 1 4.335 2.505 3 3 0 0 0 2.675 4.63c.206.8.316 1.638.316 2.503 0 .865-.11 1.703-.316 2.504a3 3 0 0 0-2.675 4.629 9.99 9.99 0 0 1-4.335 2.505 3 3 0 0 0-5.348 0 9.99 9.99 0 0 1-4.335-2.505 3 3 0 0 0-2.675-4.63C2.11 13.704 2 12.866 2 12zm4.804 3c.63 1.091.81 2.346.564 3.524.408.29.842.541 1.297.75A4.993 4.993 0 0 1 12 18c1.26 0 2.438.471 3.335 1.274.455-.209.889-.46 1.297-.75A4.993 4.993 0 0 1 17.196 15a4.993 4.993 0 0 1 2.77-2.25 8.126 8.126 0 0 0 0-1.5A4.993 4.993 0 0 1 17.195 9a4.993 4.993 0 0 1-.564-3.524 7.989 7.989 0 0 0-1.297-.75A4.993 4.993 0 0 1 12 6a4.993 4.993 0 0 1-3.335-1.274 7.99 7.99 0 0 0-1.297.75A4.993 4.993 0 0 1 6.804 9a4.993 4.993 0 0 1-2.77 2.25 8.126 8.126 0 0 0 0 1.5A4.993 4.993 0 0 1 6.805 15zM12 15a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0-2a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/></svg>
<span>
Settings
</span>
</a>
</li>
</ul>
</nav>
<article class="right language-html">
<section id="dashboard" class="page">
<h1 class="page__title">Dashboard</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Esse, sint. Aperiam ipsum expedita tenetur quasi, repellat ea. Laboriosam, earum ratione!</p>
</section>
<section id="settings" class="page hide-completely">
<h1 class="page__title">Settings</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Excepturi nihil distinctio dolore molestias ullam architecto ipsam qui possimus aliquam. Odio.</p>
</section>
</article>
</main>
<script id="helper_functions" src="js/helper.js"></script>
<script src="js/components.js"></script>
<script id="UI_functions">
let allPages = document.querySelectorAll('.page'),
allTabs = document.querySelectorAll('.navbar-item');
function showPage(btn, page) {
allPages.forEach((page) => {
page.classList.add('hide-completely')
})
allTabs.forEach((tab) => {
tab.classList.remove('active')
})
document.getElementById(page).classList.remove('hide-completely')
btn.classList.add('active')
}
</script>
<script src="js/main_UI.js"></script>
<script src="js/components.min.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,133 +0,0 @@
if (!navigator.onLine)
notify('There seems to be a problem connecting to the internet.', 'error', 'fixed', true)
window.addEventListener('offline', () => {
notify('There seems to be a problem connecting to the internet.', 'error', 'fixed', true)
})
window.addEventListener('online', () => {
notify('We are back online.', '', '', true)
})
let themeToggler = document.getElementById("theme_toggle")
if (localStorage.theme === "dark") {
darkTheme()
themeToggler.checked = true;
} else {
lightTheme()
themeToggler.checked = false;
}
function lightTheme() {
document.body.setAttribute("data-theme", "light");
}
function darkTheme() {
document.body.setAttribute("data-theme", "dark");
}
themeToggler.addEventListener("change", () => {
if (themeToggler.checked) {
darkTheme()
localStorage.setItem("theme", "dark");
} else {
lightTheme()
localStorage.setItem("theme", "light");
}
})
// function required for popups or modals to appear
class Stack {
constructor() {
this.items = [];
}
push(element) {
this.items.push(element);
}
pop() {
if (this.items.length == 0)
return "Underflow";
return this.items.pop();
}
peek(index) {
let newIndex = index ? index : 1
return this.items[this.items.length - index];
}
}
let popupStack = new Stack(),
zIndex = 10;
function showPopup(popup, permission) {
let thisPopup = document.getElementById(popup);
document.body.setAttribute('style', `overflow: hidden; top: -${window.scrollY}px`)
popupStack.push({ thisPopup, permission })
thisPopup.show(permission, popupStack)
zIndex++;
thisPopup.setAttribute('style', `z-index: ${zIndex}`)
return thisPopup;
}
function setAttributes(el, attrs) {
for (var key in attrs) {
el.setAttribute(key, attrs[key]);
}
}
// displays a popup for asking permission. Use this instead of JS confirm
let confirmation = function (message) {
return new Promise(resolve => {
let popup = document.getElementById('confirmation');
showPopup('confirmation')
popup.querySelector('#confirm_message').textContent = message;
popup.querySelector('.submit-btn').onclick = () => {
hidePopup()
resolve(true);
}
popup.querySelector('.cancel-btn').onclick = () => {
hidePopup()
resolve(false);
}
})
}
// displays a popup for asking user input. Use this instead of JS prompt
let askPrompt = function (message, defaultVal) {
return new Promise(resolve => {
let popup = document.getElementById('prompt'),
input = popup.querySelector('input');
if (defaultVal)
input.value = defaultVal;
showPopup('prompt')
input.focus()
input.addEventListener('keyup', e => {
if (e.key === 'Enter') {
resolve(input.value);
hidePopup()
}
})
popup.querySelector('#prompt_message').textContent = message;
popup.querySelector('.submit-btn').onclick = () => {
hidePopup()
resolve(input.value);
}
popup.querySelector('.cancel-btn').onclick = () => {
hidePopup()
resolve(null);
}
})
}
function formatedTime(time) {
let timeFrag = new Date(parseInt(time)).toString().split(' '),
day = timeFrag[0],
month = timeFrag[1],
date = timeFrag[2],
year = timeFrag[3],
hours = timeFrag[4].slice(0, timeFrag[4].lastIndexOf(':')),
finalTime = '';
parseInt(hours.split(':')[0]) > 12 ? finalTime = 'PM' : finalTime = 'AM'
return `${hours} ${finalTime} ${day} ${date} ${month} ${year}`
}
function copyToClipboard(parent) {
let toast = document.getElementById('textCopied'),
textToCopy = parent.querySelector('.copy').textContent;
navigator.clipboard.writeText(textToCopy)
toast.classList.remove('hide');
setTimeout(() => {
toast.classList.add('hide');
}, 2000)
}

View File

@ -0,0 +1,309 @@
// Global variables
const domRefs = {};
const appPages = ['dashboard', 'settings']
//Checks for internet connection status
if (!navigator.onLine)
notify(
"There seems to be a problem connecting to the internet, Please check you internet connection.",
"error",
{ sound: true }
);
window.addEventListener("offline", () => {
notify(
"There seems to be a problem connecting to the internet, Please check you internet connection.",
"error",
{ pinned: true, sound: true }
);
});
window.addEventListener("online", () => {
getRef("notification_drawer").clearAll();
notify("We are back online.", "success");
});
// Use instead of document.getElementById
function getRef(elementId) {
if (!domRefs.hasOwnProperty(elementId)) {
domRefs[elementId] = {
count: 1,
ref: null,
};
return document.getElementById(elementId);
} else {
if (domRefs[elementId].count < 3) {
domRefs[elementId].count = domRefs[elementId].count + 1;
return document.getElementById(elementId);
} else {
if (!domRefs[elementId].ref)
domRefs[elementId].ref = document.getElementById(elementId);
return domRefs[elementId].ref;
}
}
}
// returns dom with specified element
function createElement(tagName, obj) {
const { className, textContent, innerHTML, attributes = {} } = obj
const elem = document.createElement(tagName)
for (let attribute in attributes) {
elem.setAttribute(attribute, attributes[attribute])
}
if (className)
elem.className = className
if (textContent)
elem.textContent = textContent
if (innerHTML)
elem.innerHTML = innerHTML
return elem
}
// Use when a function needs to be executed after user finishes changes
const debounce = (callback, wait) => {
let timeoutId = null;
return (...args) => {
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(() => {
callback.apply(null, args);
}, wait);
};
}
// Limits the rate of function execution
let timerId;
function throttle(func, delay) {
// If setTimeout is already scheduled, no need to do anything
if (timerId) {
return;
}
// Schedule a setTimeout after delay seconds
timerId = setTimeout(function () {
func();
// Once setTimeout function execution is finished, timerId = undefined so that in
// the next scroll event function execution can be scheduled by the setTimeout
timerId = undefined;
}, delay);
}
// function required for popups or modals to appear
class Stack {
constructor() {
this.items = [];
}
push(element) {
this.items.push(element);
}
pop() {
if (this.items.length == 0)
return "Underflow";
return this.items.pop();
}
peek() {
return this.items[this.items.length - 1];
}
}
let popupStack = new Stack(),
zIndex = 10;
async function showPopup(popup, pinned) {
zIndex++
getRef(popup).setAttribute('style', `z-index: ${zIndex}`)
popupStack = getRef(popup).show({ pinned, popupStack })
return getRef(popup);
}
// hides the popup or modal
function hidePopup() {
if (popupStack.peek() === undefined)
return;
popupStack.peek().popup.hide()
}
// displays a popup for asking permission. Use this instead of JS confirm
let getConfirmation = (title, message, cancelText = 'Cancel', confirmText = 'OK') => {
return new Promise(resolve => {
showPopup('confirmation_popup', true)
getRef('confirm_title').textContent = title;
getRef('confirm_message').textContent = message;
let cancelButton = getRef('confirmation_popup').children[2].children[0],
submitButton = getRef('confirmation_popup').children[2].children[1]
submitButton.textContent = confirmText
cancelButton.textContent = cancelText
submitButton.onclick = () => {
hidePopup()
resolve(true);
}
cancelButton.onclick = () => {
hidePopup()
resolve(false);
}
})
}
// displays a popup for asking user input. Use this instead of JS prompt
async function getPromptInput(title, message = '', showText = true, trueBtn = "Ok", falseBtn = "Cancel") {
showPopup('prompt_popup', true)
getRef('prompt_title').textContent = title;
let input = getRef('prompt_input');
input.setAttribute("placeholder", message)
let buttons = getRef('prompt_popup').querySelectorAll("sm-button");
if (showText)
input.setAttribute("type", "text")
else
input.setAttribute("type", "password")
input.focusIn()
buttons[0].textContent = falseBtn;
buttons[1].textContent = trueBtn;
return new Promise((resolve, reject) => {
buttons[0].onclick = () => {
hidePopup()
return;
}
buttons[1].onclick = () => {
let value = input.value;
hidePopup()
resolve(value)
}
})
}
//Function for displaying toast notifications. pass in error for mode param if you want to show an error.
function notify(message, mode, options = {}) {
const { pinned = false, sound } = options
if (mode === "error") console.error(message);
let icon
switch (mode) {
case 'success':
icon = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 15.172l9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z"/></svg>`
break;
case 'error':
icon = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-7v2h2v-2h-2zm0-8v6h2V7h-2z"/></svg>`
break;
}
getRef("notification_drawer").push(message, { pinned, icon });
if (navigator.onLine && sound) {
getRef("notification_sound").currentTime = 0;
getRef("notification_sound").play();
}
}
const currentYear = new Date().getFullYear();
function getFormatedTime(time, relative) {
try {
if (String(time).indexOf("_")) time = String(time).split("_")[0];
const intTime = parseInt(time);
if (String(intTime).length < 13) time *= 1000;
let timeFrag = new Date(intTime).toString().split(" "),
day = timeFrag[0],
month = timeFrag[1],
date = timeFrag[2],
year = timeFrag[3],
minutes = new Date(intTime).getMinutes(),
hours = new Date(intTime).getHours(),
currentTime = new Date().toString().split(" ");
minutes = minutes < 10 ? `0${minutes}` : minutes;
let finalHours = ``;
if (hours > 12) finalHours = `${hours - 12}:${minutes}`;
else if (hours === 0) finalHours = `12:${minutes}`;
else finalHours = `${hours}:${minutes}`;
finalHours = hours >= 12 ? `${finalHours} PM` : `${finalHours} AM`;
if (relative) {
return `${date} ${month} ${year}`;
} else return `${finalHours} ${month} ${date} ${year}`;
} catch (e) {
console.error(e);
return time;
}
}
window.addEventListener('hashchange', e => showPage(window.location.hash))
window.addEventListener("load", () => {
document.body.classList.remove('hide-completely')
showPage(window.location.hash)
// document.querySelectorAll('sm-input[data-flo-id]').forEach(input => input.customValidation = validateAddr)
document.addEventListener('keyup', (e) => {
if (e.code === 'Escape') {
hidePopup()
}
})
document.addEventListener("pointerdown", (e) => {
if (e.target.closest("button, sm-button:not([disabled]), .interact")) {
createRipple(e, e.target.closest("button, sm-button, .interact"));
}
});
document.addEventListener('copy', () => {
notify('copied', 'success')
})
});
function createRipple(event, target) {
const circle = document.createElement("span");
const diameter = Math.max(target.clientWidth, target.clientHeight);
const radius = diameter / 2;
const targetDimensions = target.getBoundingClientRect();
circle.style.width = circle.style.height = `${diameter}px`;
circle.style.left = `${event.clientX - (targetDimensions.left + radius)}px`;
circle.style.top = `${event.clientY - (targetDimensions.top + radius)}px`;
circle.classList.add("ripple");
const rippleAnimation = circle.animate(
[
{
transform: "scale(3)",
opacity: 0,
},
],
{
duration: 1000,
fill: "forwards",
easing: "ease-out",
}
);
target.append(circle);
rippleAnimation.onfinish = () => {
circle.remove();
};
}
function showPage(targetPage, options = {}) {
const { firstLoad, hashChange } = options
let pageId
if (targetPage === '') {
pageId = 'overview_page'
}
else {
pageId = targetPage.includes('#') ? targetPage.split('#')[1] : targetPage
}
if(!appPages.includes(pageId)) return
document.querySelector('.page:not(.hide-completely)').classList.add('hide-completely')
document.querySelector('.nav-list__item--active').classList.remove('nav-list__item--active')
getRef(pageId).classList.remove('hide-completely')
getRef(pageId).animate([
{
opacity: 0,
transform: 'translateX(-1rem)'
},
{
opacity: 1,
transform: 'none'
},
],
{
duration: 300,
easing: 'ease'
})
const targetListItem = document.querySelector(`.nav-list__item[href="#${pageId}"]`)
targetListItem.classList.add('nav-list__item--active')
if (firstLoad && window.innerWidth > 640 && targetListItem.getBoundingClientRect().top > getRef('side_nav').getBoundingClientRect().height) {
getRef('side_nav').scrollTo({
top: (targetListItem.getBoundingClientRect().top - getRef('side_nav').getBoundingClientRect().top + getRef('side_nav').scrollTop),
behavior: 'smooth'
})
}
if (hashChange && window.innerWidth < 640) {
getRef('side_nav').close()
}
}

View File

@ -1,64 +1,88 @@
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@500;600;700&family=Roboto:wght@400;500;700&display=swap");
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
margin: 0;
font-family: 'Roboto', sans-serif;
box-sizing: border-box;
font-family: "Roboto", sans-serif;
}
:root {
font-size: clamp(1rem, 1.2vmax, 3rem);
}
html, body {
height: 100%;
scroll-behavior: smooth;
}
body {
--accent-color: #303F9F;
--text-color: 17, 17, 17;
--foreground-color: 255, 255, 255;
background: rgba(var(--foreground-color), 1);
color: rgba(var(--text-color), 1);
font-size: 16px;
background: rgba(var(--background-color), 1);
}
body,
body * {
--accent-color: #0D7377;
--text-color: 17, 17, 17;
--background-color: 255, 255, 255;
--danger-color: red;
}
body[data-theme="dark"] {
--foreground-color: 20, 20, 20;
--text-color: 238, 238, 238;
}
main {
margin: 1.5rem;
}
h1, h2, h3, h4, h5 {
font-family: 'Poppins', sans-serif;
text-transform: capitalize;
}
h1 {
font-size: 3rem;
}
h2 {
font-size: 2rem;
}
h3 {
font-size: 1.5rem;
}
h4 {
font-size: 1rem;
}
h5 {
font-size: 0.8rem;
body[data-theme=dark],
body[data-theme=dark] * {
--accent-color: #32E0C4;
--text-color: 240, 240, 240;
--text-color-light: 170, 170, 170;
--background-color: 10, 10, 10;
--danger-color: rgb(255, 106, 106);
}
p {
margin: 1.5rem 0;
font-size: 0.8;
max-width: 65ch;
line-height: 1.7;
margin-bottom: 1.5rem;
color: rgba(var(--text-color), 0.8);
}
p:not(:last-of-type) {
margin-bottom: 1rem;
}
img {
object-fit: cover;
}
a {
color: inherit;
text-decoration: none;
}
a:focus-visible {
box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset;
}
button {
display: inline-flex;
border: none;
background-color: inherit;
}
a:any-link:focus-visible {
outline: rgba(var(--text-color), 1) 0.1rem solid;
}
sm-button {
--border-radius: 0.3rem;
}
ul {
list-style: none;
}
.flex {
display: flex;
}
.grid {
display: grid;
}
.hide {
opacity: 0;
@ -69,124 +93,258 @@ p {
display: none !important;
}
.flex {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
.no-transformations {
transform: none !important;
}
.icon {
height: 1.2rem;
width: 1.2rem;
fill: none;
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
}
.toggle {
position: relative;
cursor: pointer;
z-index: 1;
padding: 0;
}
.toggle input[type='checkbox'] {
display: none;
}
.toggle .switch {
overflow: hidden;
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
justify-items: center;
padding: 0.2rem;
min-height: 1.6rem;
max-height: 1.6rem;
border-radius: 0.5rem;
position: relative;
margin: 0;
}
.toggle .circle {
border-radius: 0.5rem;
-webkit-transition: -webkit-transform 0.3s;
transition: -webkit-transform 0.3s;
transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
fill: rgba(var(--text-color), 0.8);
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
height: 1.2rem;
width: 1.2rem;
}
.toggle .circle:first-of-type {
margin-bottom: 0.4rem;
}
.toggle .circle line {
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
}
.toggle input:checked ~ .switch .circle {
-webkit-transform: translateY(-1.7rem);
transform: translateY(-1.7rem);
}
#navbar {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
position: -webkit-sticky;
position: sticky;
padding: 1.5rem 2rem;
left: 0;
right: 0;
top: 0;
background: rgba(var(--foreground-color), 1);
border-bottom: solid 1px rgba(var(--text-color), 0.16);
-webkit-box-shadow: 0 0.2rem 0.6rem rgba(0, 0, 0, 0.06);
box-shadow: 0 0.2rem 0.6rem rgba(0, 0, 0, 0.06);
z-index: 3;
}
#logo {
display: -ms-grid;
display: grid;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
.overflow-ellipsis {
width: 100%;
-ms-grid-columns: auto 1fr;
grid-template-columns: auto 1fr;
gap: 0.6rem 0.6rem;
margin-right: 1rem;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
#logo h4 {
.breakable {
overflow-wrap: break-word;
word-wrap: break-word;
-ms-word-break: break-all;
word-break: break-word;
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
.full-bleed {
grid-column: 1/4;
}
.h1 {
font-size: 2.5rem;
}
.h2 {
font-size: 2rem;
}
.h3 {
font-size: 1.4rem;
}
.h4 {
font-size: 1rem;
}
.h5 {
font-size: 0.8rem;
}
.uppercase {
text-transform: uppercase;
}
.capitalize {
text-transform: capitalize;
font-size: 1.2rem;
font-weight: 600;
}
#logo h5 {
font-family: 'Roboto', sans-serif;
.flex {
display: flex;
}
.grid {
display: grid;
}
.grid-3 {
grid-template-columns: 1fr auto auto;
}
.flow-column {
grid-auto-flow: column;
}
.gap-0-5 {
gap: 0.5rem;
}
.gap-1 {
gap: 1rem;
}
.gap-1-5 {
gap: 1.5rem;
}
.gap-2 {
gap: 2rem;
}
.gap-3 {
gap: 3rem;
}
.text-align-right {
text-align: right;
}
.align-start {
align-items: flex-start;
}
.align-center {
align-items: center;
}
.text-center {
text-align: center;
}
.justify-start {
justify-content: start;
}
.justify-center {
justify-content: center;
}
.justify-right {
margin-left: auto;
}
.align-self-center {
align-self: center;
}
.justify-self-center {
justify-self: center;
}
.justify-self-start {
justify-self: start;
}
.justify-self-end {
justify-self: end;
}
.direction-column {
flex-direction: column;
}
.space-between {
justify-content: space-between;
}
.w-100 {
width: 100%;
}
.color-0-8 {
color: rgba(var(--text-color), 0.8);
}
.weight-400 {
font-weight: 400;
}
.weight-500 {
font-weight: 500;
}
.ripple {
position: absolute;
border-radius: 50%;
transform: scale(0);
background: rgba(var(--text-color), 0.16);
pointer-events: none;
}
.interact {
position: relative;
overflow: hidden;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
.observe-empty-state:empty {
display: none;
}
.observe-empty-state:not(:empty) ~ .empty-state {
display: none;
}
.icon {
width: 1.5rem;
height: 1.5rem;
fill: rgba(var(--text-color), 0.9);
}
.button__icon {
height: 1.2rem;
width: 1.2rem;
}
.button__icon--left {
margin-right: 0.5rem;
}
.button__icon--right {
margin-left: 0.5rem;
}
#confirmation_popup,
#prompt_popup {
flex-direction: column;
}
#confirmation_popup h4,
#prompt_popup h4 {
font-weight: 500;
margin-bottom: 0.5rem;
}
#confirmation_popup sm-button,
#prompt_popup sm-button {
margin: 0;
}
#confirmation_popup .flex,
#prompt_popup .flex {
padding: 0;
margin-top: 1rem;
}
#confirmation_popup .flex sm-button:first-of-type,
#prompt_popup .flex sm-button:first-of-type {
margin-right: 0.6rem;
margin-left: auto;
}
#main_header {
display: flex;
gap: 1rem;
align-items: center;
position: sticky;
padding: 1rem 1.5rem;
background: rgba(var(--background-color), 1);
border-bottom: solid 1px rgba(var(--text-color), 0.16);
z-index: 2;
}
#logo {
display: grid;
align-items: center;
width: 100%;
grid-template-columns: auto 1fr;
gap: 0 0.5rem;
margin-right: 1rem;
}
#logo h4 {
text-transform: capitalize;
font-size: 1rem;
font-weight: 600;
margin-top: 0.2rem;
}
#logo h5 {
font-size: 0.8rem;
font-family: "Roboto", sans-serif;
font-weight: 400;
}
#logo #main_logo {
height: 1.4rem;
width: 1.4rem;
@ -195,46 +353,36 @@ p {
}
.section {
display: flex;
flex-direction: column;
margin-top: 3rem;
padding: 0 1.5rem;
}
.section h3 + p {
margin-top: 1rem;
}
.section:first-of-type {
margin-top: 0;
}
.section__header {
display: flex;
padding: 1rem 0;
justify-content: space-between;
}
.card {
padding: 1.5rem;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
flex-direction: column;
min-width: 20rem;
border-radius: 0.5rem;
margin-right: 1.5rem;
border: solid 1px rgba(var(--text-color), 0.2);
background-color: rgba(var(--text-color), 0.06);
}
.card h3 {
font-weight: 500;
}
sm-menu {
margin-left: auto;
}
@media only screen and (min-width: 640px) {
main {
margin: 1.5rem 4vw;
@media screen and (min-width: 640px) {
sm-popup {
--width: 24rem;
}
p {
max-width: 40rem;
}
}
/*# sourceMappingURL=main.css.map */
}

View File

@ -0,0 +1 @@
#logo h5,*{font-family:Roboto,sans-serif}*{padding:0;margin:0;box-sizing:border-box}:root{font-size:clamp(1rem,1.2vmax,3rem)}body,html{height:100%;scroll-behavior:smooth}body{color:rgba(var(--text-color),1);background:rgba(var(--background-color),1)}body,body *{--accent-color:#0D7377;--text-color:17,17,17;--background-color:255,255,255;--danger-color:red}body[data-theme=dark],body[data-theme=dark] *{--accent-color:#32E0C4;--text-color:240,240,240;--text-color-light:170,170,170;--background-color:10,10,10;--danger-color:rgb(255, 106, 106)}p{font-size:.8;max-width:65ch;line-height:1.7;margin-bottom:1.5rem;color:rgba(var(--text-color),.8)}p:not(:last-of-type){margin-bottom:1rem}img{object-fit:cover}a{color:inherit;text-decoration:none}a:focus-visible{box-shadow:0 0 0 .1rem rgba(var(--text-color),1) inset}button{display:inline-flex;border:none;background-color:inherit}a:any-link:focus-visible{outline:solid rgba(var(--text-color),1)}sm-button{--border-radius:0.3rem}ul{list-style:none}.hide{opacity:0;pointer-events:none}.hide-completely{display:none!important}.no-transformations{transform:none!important}.overflow-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.breakable{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.full-bleed{grid-column:1/4}.h1{font-size:2.5rem}.h2{font-size:2rem}.h3{font-size:1.4rem}.h4{font-size:1rem}.h5{font-size:.8rem}.uppercase{text-transform:uppercase}#logo h4,.capitalize{text-transform:capitalize}.flex{display:flex}.grid{display:grid}.grid-3{grid-template-columns:1fr auto auto}.flow-column{grid-auto-flow:column}.gap-0-5{gap:.5rem}.gap-1{gap:1rem}.gap-1-5{gap:1.5rem}.gap-2{gap:2rem}.gap-3{gap:3rem}.text-align-right{text-align:right}.align-start{align-items:flex-start}#main_header,.align-center{align-items:center}.text-center{text-align:center}.justify-start{justify-content:start}.justify-center{justify-content:center}.justify-right{margin-left:auto}.align-self-center{align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.direction-column{flex-direction:column}.space-between{justify-content:space-between}.w-100{width:100%}.color-0-8{color:rgba(var(--text-color),.8)}.weight-400{font-weight:400}.weight-500{font-weight:500}.ripple{position:absolute;border-radius:50%;transform:scale(0);background:rgba(var(--text-color),.16);pointer-events:none}.interact{position:relative;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:transparent}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)~.empty-state{display:none}.icon{width:1.5rem;height:1.5rem;fill:rgba(var(--text-color),.9)}.button__icon{height:1.2rem;width:1.2rem}.button__icon--left{margin-right:.5rem}.button__icon--right{margin-left:.5rem}#confirmation_popup,#prompt_popup{flex-direction:column}#confirmation_popup h4,#prompt_popup h4{font-weight:500;margin-bottom:.5rem}#confirmation_popup sm-button,#prompt_popup sm-button{margin:0}#confirmation_popup .flex,#prompt_popup .flex{padding:0;margin-top:1rem}#confirmation_popup .flex sm-button:first-of-type,#prompt_popup .flex sm-button:first-of-type{margin-right:.6rem;margin-left:auto}#main_header{display:flex;gap:1rem;position:sticky;padding:1rem 1.5rem;background:rgba(var(--background-color),1);border-bottom:solid 1px rgba(var(--text-color),.16);z-index:2}#logo{display:grid;align-items:center;width:100%;grid-template-columns:auto 1fr;gap:0 .5rem;margin-right:1rem}#logo h4{font-size:1rem;font-weight:600;margin-top:.2rem}#logo h5{font-size:.8rem;font-weight:400}#logo #main_logo{height:1.4rem;width:1.4rem;fill:rgba(var(--text-color),1);stroke:none}.section{display:flex;flex-direction:column;margin-top:3rem;padding:0 1.5rem}.section:first-of-type{margin-top:0}.section__header{display:flex;padding:1rem 0;justify-content:space-between}.card{padding:1.5rem;display:flex;flex-direction:column;min-width:20rem;border-radius:.5rem;margin-right:1.5rem;background-color:rgba(var(--text-color),.06)}.card h3{font-weight:500}@media screen and (min-width:640px){sm-popup{--width:24rem}}

View File

@ -1,51 +1,79 @@
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@500;600;700&family=Roboto:wght@400;500;700&display=swap');
*{
box-sizing: border-box;
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Roboto', sans-serif;
}
:root{
font-size: clamp(1rem, 1.2vmax, 3rem);
}
html, body{
height: 100%;
scroll-behavior: smooth;
}
body{
--accent-color: #303F9F;
--text-color: 17, 17, 17;
--foreground-color: 255, 255, 255;
background: rgba(var(--foreground-color), 1);
body {
&,
*{
--accent-color: #0D7377;
--text-color: 17, 17, 17;
--background-color: 255, 255, 255;
--danger-color: red;
}
color: rgba(var(--text-color), 1);
font-size: 16px;
background: rgba(var(--background-color), 1);
}
body[data-theme="dark"]{
--foreground-color: 20, 20, 20;
--text-color: 238, 238, 238;
body[data-theme='dark']{
&,
*{
--accent-color: #32E0C4;
--text-color: 240, 240, 240;
--text-color-light: 170, 170, 170;
--background-color: 10, 10, 10;
--danger-color: rgb(255, 106, 106);
}
}
main{
margin: 1.5rem;
}
h1, h2, h3, h4, h5{
font-family: 'Poppins', sans-serif;
text-transform: capitalize;
}
h1{
font-size: 3rem;
}
h2{
font-size: 2rem;
}
h3{
font-size: 1.5rem;
}
h4{
font-size: 1rem;
}
h5{
font-size: 0.8rem;
}
p{
margin: 1.5rem 0;
p {
font-size: 0.8;
max-width: 65ch;
line-height: 1.7;
margin-bottom: 1.5rem;
color: rgba(var(--text-color), 0.8);
&:not(:last-of-type){
margin-bottom: 1rem;
}
}
img{
object-fit: cover;
}
a{
color: inherit;
text-decoration: none;
&:focus-visible{
box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset;
}
}
button{
display: inline-flex;
border: none;
background-color: inherit;
}
a:any-link:focus-visible{
outline: rgba(var(--text-color), 1) 0.1rem solid;
}
sm-button{
--border-radius: 0.3rem;
}
ul{
list-style: none;
}
.flex{
display: flex;
}
.grid{
display: grid;
}
.hide{
opacity: 0;
@ -54,86 +82,206 @@ p{
.hide-completely{
display: none !important;
}
.no-transformations{
transform: none !important;
}
.overflow-ellipsis{
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.breakable{
overflow-wrap: break-word;
word-wrap: break-word;
-ms-word-break: break-all;
word-break: break-word;
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
.full-bleed{
grid-column: 1/4;
}
.h1{
font-size: 2.5rem;
}
.h2{
font-size: 2rem;
}
.h3{
font-size: 1.4rem;
}
.h4{
font-size: 1rem;
}
.h5{
font-size: 0.8rem;
}
.uppercase{
text-transform: uppercase;
}
.capitalize{
text-transform: capitalize;
}
.flex{
display: flex;
}
.grid{
display: grid;
}
.grid-3{
grid-template-columns: 1fr auto auto;
}
.flow-column{
grid-auto-flow: column;
}
.gap-0-5{
gap: 0.5rem;
}
.gap-1{
gap: 1rem;
}
.gap-1-5{
gap: 1.5rem;
}
.gap-2{
gap: 2rem;
}
.gap-3{
gap: 3rem;
}
.text-align-right{
text-align: right;
}
.align-start{
align-items: flex-start;
}
.align-center{
align-items: center;
}
.text-center{
text-align: center;
}
.justify-start{
justify-content: start;
}
.justify-center{
justify-content: center;
}
.justify-right{
margin-left: auto;
}
.align-self-center{
align-self: center;
}
.justify-self-center{
justify-self: center;
}
.justify-self-start{
justify-self: start;
}
.justify-self-end{
justify-self: end;
}
.direction-column{
flex-direction: column;
}
.space-between{
justify-content: space-between;
}
.w-100{
width: 100%;
}
.color-0-8{
color: rgba(var(--text-color), 0.8);
}
.weight-400{
font-weight: 400;
}
.weight-500{
font-weight: 500;
}
.ripple{
position: absolute;
border-radius: 50%;
transform: scale(0);
background: rgba(var(--text-color), 0.16);
pointer-events: none;
}
.interact{
position: relative;
overflow: hidden;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
.observe-empty-state:empty{
display: none;
}
.observe-empty-state:not(:empty) ~ .empty-state{
display: none;
}
.icon{
width: 1.5rem;
height: 1.5rem;
fill: rgba(var(--text-color), 0.9);
}
.button__icon{
height: 1.2rem;
width: 1.2rem;
fill: none;
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
}
.toggle{
position: relative;
cursor: pointer;
z-index: 1;
padding: 0;
input[type='checkbox']{
display: none;
&--left{
margin-right: 0.5rem;
}
.switch{
overflow: hidden;
display: inline-flex;
flex-direction: column;
justify-items: center;
padding: 0.2rem;
min-height: 1.6rem;
max-height: 1.6rem;
border-radius: 0.5rem;
position: relative;
&--right{
margin-left: 0.5rem;
}
}
#confirmation_popup,
#prompt_popup {
flex-direction: column;
h4 {
font-weight: 500;
margin-bottom: 0.5rem;
}
sm-button{
margin: 0;
}
.circle{
border-radius: 0.5rem;
transition: transform 0.3s;
&:first-of-type{
margin-bottom: 0.4rem;
.flex {
padding: 0;
margin-top: 1rem;
sm-button:first-of-type {
margin-right: 0.6rem;
margin-left: auto;
}
fill: rgba(var(--text-color), 0.8);
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
height: 1.2rem;
width: 1.2rem;
line{
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
}
}
input:checked ~ .switch .circle{
transform: translateY(-1.7rem);
}
}
#navbar{
#main_header{
display: flex;
gap: 1rem;
align-items: center;
position: sticky;
padding: 1.5rem 2rem;
left: 0;
right: 0;
top: 0;
background: rgba(var(--foreground-color), 1);
padding: 1rem 1.5rem;
background: rgba(var(--background-color), 1);
border-bottom: solid 1px rgba(var(--text-color), 0.16);
box-shadow: 0 0.2rem 0.6rem rgba(0, 0, 0, 0.06);
z-index: 3;
z-index: 2;
}
#logo{
display: grid;
align-items: center;
width: 100%;
grid-template-columns: auto 1fr;
gap: 0.6rem 0.6rem;
gap: 0 0.5rem;
margin-right: 1rem;
h4{
text-transform: capitalize;
font-size: 1.2rem;
font-size: 1rem;
font-weight: 600;
margin-top: 0.2rem;
}
h5{
font-size: 0.8rem;
font-family: 'Roboto', sans-serif;
font-weight: 400;
}
@ -145,14 +293,19 @@ p{
}
}
.section{
display: flex;
flex-direction: column;
margin-top: 3rem;
h3 + p{
margin-top: 1rem;
}
padding: 0 1.5rem;
&:first-of-type{
margin-top: 0;
}
}
.section__header{
display: flex;
padding: 1rem 0;
justify-content: space-between;
}
.card{
padding: 1.5rem;
display: flex;
@ -160,19 +313,15 @@ p{
min-width: 20rem;
border-radius: 0.5rem;
margin-right: 1.5rem;
border: solid 1px rgba(var(--text-color), 0.2);
background-color: rgba(var(--text-color), 0.06);
h3{
font-weight: 500;
}
}
sm-menu{
margin-left: auto;
}
@media only screen and (min-width: 640px){
main{
margin: 1.5rem 4vw;
}
p{
max-width: 40rem;
@media screen and (min-width: 640px) {
// for tablet and desktop
sm-popup{
--width: 24rem;
}
}

View File

@ -6,59 +6,66 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="css/main.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;700&family=Roboto+Mono&family=Roboto:wght@400;500;700&display=swap"
rel="stylesheet">
</head>
<body data-theme="light">
<nav id="navbar">
<div id="logo">
<svg id="main_logo" viewBox="0 0 27.25 32">
<title>RanchiMall</title>
<path
d="M27.14,30.86c-.74-2.48-3-4.36-8.25-6.94a20,20,0,0,1-4.2-2.49,6,6,0,0,1-1.25-1.67,4,4,0,0,1,0-2.26c.37-1.08.79-1.57,3.89-4.55a11.66,11.66,0,0,0,3.34-4.67,6.54,6.54,0,0,0,.05-2.82C20,3.6,18.58,2,16.16.49c-.89-.56-1.29-.64-1.3-.24a3,3,0,0,1-.3.72l-.3.55L13.42.94C13,.62,12.4.26,12.19.15c-.4-.2-.73-.18-.72.05a9.39,9.39,0,0,1-.61,1.33s-.14,0-.27-.13C8.76.09,8-.27,8,.23A11.73,11.73,0,0,1,6.76,2.6C4.81,5.87,2.83,7.49.77,7.49c-.89,0-.88,0-.61,1,.22.85.33.92,1.09.69A5.29,5.29,0,0,0,3,8.33c.23-.17.45-.29.49-.26a2,2,0,0,1,.22.63A1.31,1.31,0,0,0,4,9.34a5.62,5.62,0,0,0,2.27-.87L7,8l.13.55c.19.74.32.82,1,.65a7.06,7.06,0,0,0,3.46-2.47l.6-.71-.06.64c-.17,1.63-1.3,3.42-3.39,5.42L6.73,14c-3.21,3.06-3,5.59.6,8a46.77,46.77,0,0,0,4.6,2.41c.28.13,1,.52,1.59.87,3.31,2,4.95,3.92,4.95,5.93a2.49,2.49,0,0,0,.07.77h0c.09.09,0,.1.9-.14a2.61,2.61,0,0,0,.83-.32,3.69,3.69,0,0,0-.55-1.83A11.14,11.14,0,0,0,17,26.81a35.7,35.7,0,0,0-5.1-2.91C9.37,22.64,8.38,22,7.52,21.17a3.53,3.53,0,0,1-1.18-2.48c0-1.38.71-2.58,2.5-4.23,2.84-2.6,3.92-3.91,4.67-5.65a3.64,3.64,0,0,0,.42-2A3.37,3.37,0,0,0,13.61,5l-.32-.74.29-.48c.17-.27.37-.63.46-.8l.15-.3.44.64a5.92,5.92,0,0,1,1,2.81,5.86,5.86,0,0,1-.42,1.94c0,.12-.12.3-.15.4a9.49,9.49,0,0,1-.67,1.1,28,28,0,0,1-4,4.29C8.62,15.49,8.05,16.44,8,17.78a3.28,3.28,0,0,0,1.11,2.76c.95,1,2.07,1.74,5.25,3.32,3.64,1.82,5.22,2.9,6.41,4.38A4.78,4.78,0,0,1,21.94,31a3.21,3.21,0,0,0,.14.92,1.06,1.06,0,0,0,.43-.05l.83-.22.46-.12-.06-.46c-.21-1.53-1.62-3.25-3.94-4.8a37.57,37.57,0,0,0-5.22-2.82A13.36,13.36,0,0,1,11,21.19a3.36,3.36,0,0,1-.8-4.19c.41-.85.83-1.31,3.77-4.15,2.39-2.31,3.43-4.13,3.43-6a5.85,5.85,0,0,0-2.08-4.29c-.23-.21-.44-.43-.65-.65A2.5,2.5,0,0,1,15.27.69a10.6,10.6,0,0,1,2.91,2.78A4.16,4.16,0,0,1,19,6.16a4.91,4.91,0,0,1-.87,3c-.71,1.22-1.26,1.82-4.27,4.67a9.47,9.47,0,0,0-2.07,2.6,2.76,2.76,0,0,0-.33,1.54,2.76,2.76,0,0,0,.29,1.47c.57,1.21,2.23,2.55,4.65,3.73a32.41,32.41,0,0,1,5.82,3.24c2.16,1.6,3.2,3.16,3.2,4.8a1.94,1.94,0,0,0,.09.76,4.54,4.54,0,0,0,1.66-.4C27.29,31.42,27.29,31.37,27.14,30.86ZM6.1,7h0a3.77,3.77,0,0,1-1.46.45L4,7.51l.68-.83a25.09,25.09,0,0,0,3-4.82A12,12,0,0,1,8.28.76c.11-.12.77.32,1.53,1l.63.58-.57.84A10.34,10.34,0,0,1,6.1,7Zm5.71-1.78A9.77,9.77,0,0,1,9.24,7.18h0a5.25,5.25,0,0,1-1.17.28l-.58,0,.65-.78a21.29,21.29,0,0,0,2.1-3.12c.22-.41.42-.76.44-.79s.5.43.9,1.24L12,5ZM13.41,3a2.84,2.84,0,0,1-.45.64,11,11,0,0,1-.9-.91l-.84-.9.19-.45c.34-.79.39-.8,1-.31A9.4,9.4,0,0,1,13.8,2.33q-.18.34-.39.69Z" />
</svg>
<span>
<h5>RanchiMall</h5>
<h4>App name</h4>
</span>
<body data-theme="light" class="hide-completely">
<sm-notifications id="notification_drawer"></sm-notifications>
<audio id="notification_sound">
<source src="https://rmservices.duckdns.org/files/notification-sound.mp3" type="audio/mpeg">
<source src="https://rmservices.duckdns.org/files/notification-sound.ogg" type="audio/ogg">
</audio>
<sm-popup id="confirmation_popup">
<h4 id="confirm_title"></h4>
<p id="confirm_message"></p>
<div class="flex align-center">
<sm-button variant="no-outline" class="cancel-btn">Cancel</sm-button>
<sm-button variant="no-outline" class="submit-btn">OK</button>
</div>
<sm-input placeholder="search" oninput="console.log(this.value)"></sm-input>
<label class="toggle" title="Change theme">
<input type="checkbox" name="theme toggle" id="theme_toggle">
<div class="switch">
<svg class="circle" viewBox="0 0 64 64">
<title>dark theme</title>
</sm-popup>
<sm-popup id="prompt_popup">
<h4 id="prompt_title"></h4>
<p id="prompt_message"></p>
<sm-input id="prompt_input"></sm-input>
<div class="flex align-center">
<sm-button variant="no-outline" class="cancel-btn">Cancel</sm-button>
<sm-button variant="no-outline" class="submit-btn" type="submit">OK</button>
</div>
</sm-popup>
<article id="home" class="page">
<header id="main_header" class="full-bleed">
<div id="logo">
<svg id="main_logo" viewBox="0 0 27.25 32">
<title>RanchiMall</title>
<path
d="M48.25,45.45A27.26,27.26,0,0,1,20.82,18.37,26.75,26.75,0,0,1,27.47.71a31.71,31.71,0,0,0-27,31.2,31.8,31.8,0,0,0,32,31.59A32,32,0,0,0,63.12,41.12,27.59,27.59,0,0,1,48.25,45.45Z"
transform="translate(0 0)" />
</svg>
<svg class="circle" viewBox="0 0 64 64">
<title>light theme</title>
<circle cx="32" cy="32" r="13.9" />
<line x1="32" y1="6.86" x2="32" />
<line x1="32" y1="64" x2="32" y2="57.14" />
<line x1="57.14" y1="32" x2="64" y2="32" />
<line y1="32" x2="6.86" y2="32" />
<line x1="49.78" y1="14.22" x2="54.63" y2="9.37" />
<line x1="9.37" y1="54.63" x2="14.22" y2="49.78" />
<line x1="49.78" y1="49.78" x2="54.63" y2="54.63" />
<line x1="9.37" y1="9.37" x2="14.22" y2="14.22" />
d="M27.14,30.86c-.74-2.48-3-4.36-8.25-6.94a20,20,0,0,1-4.2-2.49,6,6,0,0,1-1.25-1.67,4,4,0,0,1,0-2.26c.37-1.08.79-1.57,3.89-4.55a11.66,11.66,0,0,0,3.34-4.67,6.54,6.54,0,0,0,.05-2.82C20,3.6,18.58,2,16.16.49c-.89-.56-1.29-.64-1.3-.24a3,3,0,0,1-.3.72l-.3.55L13.42.94C13,.62,12.4.26,12.19.15c-.4-.2-.73-.18-.72.05a9.39,9.39,0,0,1-.61,1.33s-.14,0-.27-.13C8.76.09,8-.27,8,.23A11.73,11.73,0,0,1,6.76,2.6C4.81,5.87,2.83,7.49.77,7.49c-.89,0-.88,0-.61,1,.22.85.33.92,1.09.69A5.29,5.29,0,0,0,3,8.33c.23-.17.45-.29.49-.26a2,2,0,0,1,.22.63A1.31,1.31,0,0,0,4,9.34a5.62,5.62,0,0,0,2.27-.87L7,8l.13.55c.19.74.32.82,1,.65a7.06,7.06,0,0,0,3.46-2.47l.6-.71-.06.64c-.17,1.63-1.3,3.42-3.39,5.42L6.73,14c-3.21,3.06-3,5.59.6,8a46.77,46.77,0,0,0,4.6,2.41c.28.13,1,.52,1.59.87,3.31,2,4.95,3.92,4.95,5.93a2.49,2.49,0,0,0,.07.77h0c.09.09,0,.1.9-.14a2.61,2.61,0,0,0,.83-.32,3.69,3.69,0,0,0-.55-1.83A11.14,11.14,0,0,0,17,26.81a35.7,35.7,0,0,0-5.1-2.91C9.37,22.64,8.38,22,7.52,21.17a3.53,3.53,0,0,1-1.18-2.48c0-1.38.71-2.58,2.5-4.23,2.84-2.6,3.92-3.91,4.67-5.65a3.64,3.64,0,0,0,.42-2A3.37,3.37,0,0,0,13.61,5l-.32-.74.29-.48c.17-.27.37-.63.46-.8l.15-.3.44.64a5.92,5.92,0,0,1,1,2.81,5.86,5.86,0,0,1-.42,1.94c0,.12-.12.3-.15.4a9.49,9.49,0,0,1-.67,1.1,28,28,0,0,1-4,4.29C8.62,15.49,8.05,16.44,8,17.78a3.28,3.28,0,0,0,1.11,2.76c.95,1,2.07,1.74,5.25,3.32,3.64,1.82,5.22,2.9,6.41,4.38A4.78,4.78,0,0,1,21.94,31a3.21,3.21,0,0,0,.14.92,1.06,1.06,0,0,0,.43-.05l.83-.22.46-.12-.06-.46c-.21-1.53-1.62-3.25-3.94-4.8a37.57,37.57,0,0,0-5.22-2.82A13.36,13.36,0,0,1,11,21.19a3.36,3.36,0,0,1-.8-4.19c.41-.85.83-1.31,3.77-4.15,2.39-2.31,3.43-4.13,3.43-6a5.85,5.85,0,0,0-2.08-4.29c-.23-.21-.44-.43-.65-.65A2.5,2.5,0,0,1,15.27.69a10.6,10.6,0,0,1,2.91,2.78A4.16,4.16,0,0,1,19,6.16a4.91,4.91,0,0,1-.87,3c-.71,1.22-1.26,1.82-4.27,4.67a9.47,9.47,0,0,0-2.07,2.6,2.76,2.76,0,0,0-.33,1.54,2.76,2.76,0,0,0,.29,1.47c.57,1.21,2.23,2.55,4.65,3.73a32.41,32.41,0,0,1,5.82,3.24c2.16,1.6,3.2,3.16,3.2,4.8a1.94,1.94,0,0,0,.09.76,4.54,4.54,0,0,0,1.66-.4C27.29,31.42,27.29,31.37,27.14,30.86ZM6.1,7h0a3.77,3.77,0,0,1-1.46.45L4,7.51l.68-.83a25.09,25.09,0,0,0,3-4.82A12,12,0,0,1,8.28.76c.11-.12.77.32,1.53,1l.63.58-.57.84A10.34,10.34,0,0,1,6.1,7Zm5.71-1.78A9.77,9.77,0,0,1,9.24,7.18h0a5.25,5.25,0,0,1-1.17.28l-.58,0,.65-.78a21.29,21.29,0,0,0,2.1-3.12c.22-.41.42-.76.44-.79s.5.43.9,1.24L12,5ZM13.41,3a2.84,2.84,0,0,1-.45.64,11,11,0,0,1-.9-.91l-.84-.9.19-.45c.34-.79.39-.8,1-.31A9.4,9.4,0,0,1,13.8,2.33q-.18.34-.39.69Z" />
</svg>
<div class="grid">
<h5>RanchiMall</h5>
<h4>App name</h4>
</div>
</div>
</label>
</nav>
<main>
<sm-input placeholder="Search" type="search"></sm-input>
<theme-toggle></theme-toggle>
</header>
<section class="section">
<div class="flex">
<h3>Section Heading</h3>
<sm-menu set-context="true">
<sm-menu-option>first option</sm-menu-option>
<sm-menu-option>second option</sm-menu-option>
<sm-menu-option>third option</sm-menu-option>
<div class="section__header">
<div class="grid">
<h3>Section Heading</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</p>
</div>
<sm-menu align-options="right">
<menu-option>first option</menu-option>
<menu-option>second option</menu-option>
<menu-option>third option</menu-option>
</sm-menu>
</div>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</p>
<sm-carousel>
<div class="card">
<h3>Card</h3>
@ -87,17 +94,19 @@
</sm-carousel>
</section>
<section class="section">
<div class="flex">
<h3>Section Heading</h3>
<sm-menu set-context="true">
<sm-menu-option>first option</sm-menu-option>
<sm-menu-option>second option</sm-menu-option>
<sm-menu-option>third option</sm-menu-option>
<div class="section__header">
<div class="grid">
<h3>Section Heading</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</p>
</div>
<sm-menu align-options="right">
<menu-option>first option</menu-option>
<menu-option>second option</menu-option>
<menu-option>third option</menu-option>
</sm-menu>
</div>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</p>
<sm-carousel>
<div class="card">
<h3>Card</h3>
@ -126,17 +135,19 @@
</sm-carousel>
</section>
<section class="section">
<div class="flex">
<h3>Section Heading</h3>
<sm-menu set-context="true">
<sm-menu-option>first option</sm-menu-option>
<sm-menu-option>second option</sm-menu-option>
<sm-menu-option>third option</sm-menu-option>
<div class="section__header">
<div class="grid">
<h3>Section Heading</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</p>
</div>
<sm-menu align-options="right">
<menu-option>first option</menu-option>
<menu-option>second option</menu-option>
<menu-option>third option</menu-option>
</sm-menu>
</div>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</p>
<sm-carousel>
<div class="card">
<h3>Card</h3>
@ -164,23 +175,9 @@
</div>
</sm-carousel>
</section>
</main>
<script id="helper_functions" src="js/helper.js"></script>
<script src="js/components.js"></script>
<script id="UI_functions">
let allPages = document.querySelectorAll('.page'),
allTabs = document.querySelectorAll('.navbar-item');
function showPage(btn, page) {
allPages.forEach((page) => {
page.classList.add('hide-completely')
})
allTabs.forEach((tab) => {
tab.classList.remove('active')
})
document.getElementById(page).classList.remove('hide-completely')
btn.classList.add('active')
}
</script>
</article>
<script src="js/main_UI.js"></script>
<script src="js/components.min.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,133 +0,0 @@
if (!navigator.onLine)
notify('There seems to be a problem connecting to the internet.', 'error', 'fixed', true)
window.addEventListener('offline', () => {
notify('There seems to be a problem connecting to the internet.', 'error', 'fixed', true)
})
window.addEventListener('online', () => {
notify('We are back online.', '', '', true)
})
let themeToggler = document.getElementById("theme_toggle")
if (localStorage.theme === "dark") {
darkTheme()
themeToggler.checked = true;
} else {
lightTheme()
themeToggler.checked = false;
}
function lightTheme() {
document.body.setAttribute("data-theme", "light");
}
function darkTheme() {
document.body.setAttribute("data-theme", "dark");
}
themeToggler.addEventListener("change", () => {
if (themeToggler.checked) {
darkTheme()
localStorage.setItem("theme", "dark");
} else {
lightTheme()
localStorage.setItem("theme", "light");
}
})
// function required for popups or modals to appear
class Stack {
constructor() {
this.items = [];
}
push(element) {
this.items.push(element);
}
pop() {
if (this.items.length == 0)
return "Underflow";
return this.items.pop();
}
peek(index) {
let newIndex = index ? index : 1
return this.items[this.items.length - index];
}
}
let popupStack = new Stack(),
zIndex = 10;
function showPopup(popup, permission) {
let thisPopup = document.getElementById(popup);
document.body.setAttribute('style', `overflow: hidden; top: -${window.scrollY}px`)
popupStack.push({ thisPopup, permission })
thisPopup.show(permission, popupStack)
zIndex++;
thisPopup.setAttribute('style', `z-index: ${zIndex}`)
return thisPopup;
}
function setAttributes(el, attrs) {
for (var key in attrs) {
el.setAttribute(key, attrs[key]);
}
}
// displays a popup for asking permission. Use this instead of JS confirm
let confirmation = function (message) {
return new Promise(resolve => {
let popup = document.getElementById('confirmation');
showPopup('confirmation')
popup.querySelector('#confirm_message').textContent = message;
popup.querySelector('.submit-btn').onclick = () => {
hidePopup()
resolve(true);
}
popup.querySelector('.cancel-btn').onclick = () => {
hidePopup()
resolve(false);
}
})
}
// displays a popup for asking user input. Use this instead of JS prompt
let askPrompt = function (message, defaultVal) {
return new Promise(resolve => {
let popup = document.getElementById('prompt'),
input = popup.querySelector('input');
if (defaultVal)
input.value = defaultVal;
showPopup('prompt')
input.focus()
input.addEventListener('keyup', e => {
if (e.key === 'Enter') {
resolve(input.value);
hidePopup()
}
})
popup.querySelector('#prompt_message').textContent = message;
popup.querySelector('.submit-btn').onclick = () => {
hidePopup()
resolve(input.value);
}
popup.querySelector('.cancel-btn').onclick = () => {
hidePopup()
resolve(null);
}
})
}
function formatedTime(time) {
let timeFrag = new Date(parseInt(time)).toString().split(' '),
day = timeFrag[0],
month = timeFrag[1],
date = timeFrag[2],
year = timeFrag[3],
hours = timeFrag[4].slice(0, timeFrag[4].lastIndexOf(':')),
finalTime = '';
parseInt(hours.split(':')[0]) > 12 ? finalTime = 'PM' : finalTime = 'AM'
return `${hours} ${finalTime} ${day} ${date} ${month} ${year}`
}
function copyToClipboard(parent) {
let toast = document.getElementById('textCopied'),
textToCopy = parent.querySelector('.copy').textContent;
navigator.clipboard.writeText(textToCopy)
toast.classList.remove('hide');
setTimeout(() => {
toast.classList.add('hide');
}, 2000)
}

View File

@ -0,0 +1,282 @@
// Global variables
const domRefs = {};
const appPages = ['home']
//Checks for internet connection status
if (!navigator.onLine)
notify(
"There seems to be a problem connecting to the internet, Please check you internet connection.",
"error",
{ sound: true }
);
window.addEventListener("offline", () => {
notify(
"There seems to be a problem connecting to the internet, Please check you internet connection.",
"error",
{ pinned: true, sound: true }
);
});
window.addEventListener("online", () => {
getRef("notification_drawer").clearAll();
notify("We are back online.", "success");
});
// Use instead of document.getElementById
function getRef(elementId) {
if (!domRefs.hasOwnProperty(elementId)) {
domRefs[elementId] = {
count: 1,
ref: null,
};
return document.getElementById(elementId);
} else {
if (domRefs[elementId].count < 3) {
domRefs[elementId].count = domRefs[elementId].count + 1;
return document.getElementById(elementId);
} else {
if (!domRefs[elementId].ref)
domRefs[elementId].ref = document.getElementById(elementId);
return domRefs[elementId].ref;
}
}
}
// returns dom with specified element
function createElement(tagName, obj) {
const { className, textContent, innerHTML, attributes = {} } = obj
const elem = document.createElement(tagName)
for (let attribute in attributes) {
elem.setAttribute(attribute, attributes[attribute])
}
if (className)
elem.className = className
if (textContent)
elem.textContent = textContent
if (innerHTML)
elem.innerHTML = innerHTML
return elem
}
// Use when a function needs to be executed after user finishes changes
const debounce = (callback, wait) => {
let timeoutId = null;
return (...args) => {
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(() => {
callback.apply(null, args);
}, wait);
};
}
// Limits the rate of function execution
let timerId;
function throttle(func, delay) {
// If setTimeout is already scheduled, no need to do anything
if (timerId) {
return;
}
// Schedule a setTimeout after delay seconds
timerId = setTimeout(function () {
func();
// Once setTimeout function execution is finished, timerId = undefined so that in
// the next scroll event function execution can be scheduled by the setTimeout
timerId = undefined;
}, delay);
}
// function required for popups or modals to appear
class Stack {
constructor() {
this.items = [];
}
push(element) {
this.items.push(element);
}
pop() {
if (this.items.length == 0)
return "Underflow";
return this.items.pop();
}
peek() {
return this.items[this.items.length - 1];
}
}
let popupStack = new Stack(),
zIndex = 10;
async function showPopup(popup, pinned) {
zIndex++
getRef(popup).setAttribute('style', `z-index: ${zIndex}`)
popupStack = getRef(popup).show({ pinned, popupStack })
return getRef(popup);
}
// hides the popup or modal
function hidePopup() {
if (popupStack.peek() === undefined)
return;
popupStack.peek().popup.hide()
}
// displays a popup for asking permission. Use this instead of JS confirm
let getConfirmation = (title, message, cancelText = 'Cancel', confirmText = 'OK') => {
return new Promise(resolve => {
showPopup('confirmation_popup', true)
getRef('confirm_title').textContent = title;
getRef('confirm_message').textContent = message;
let cancelButton = getRef('confirmation_popup').children[2].children[0],
submitButton = getRef('confirmation_popup').children[2].children[1]
submitButton.textContent = confirmText
cancelButton.textContent = cancelText
submitButton.onclick = () => {
hidePopup()
resolve(true);
}
cancelButton.onclick = () => {
hidePopup()
resolve(false);
}
})
}
// displays a popup for asking user input. Use this instead of JS prompt
async function getPromptInput(title, message = '', showText = true, trueBtn = "Ok", falseBtn = "Cancel") {
showPopup('prompt_popup', true)
getRef('prompt_title').textContent = title;
let input = getRef('prompt_input');
input.setAttribute("placeholder", message)
let buttons = getRef('prompt_popup').querySelectorAll("sm-button");
if (showText)
input.setAttribute("type", "text")
else
input.setAttribute("type", "password")
input.focusIn()
buttons[0].textContent = falseBtn;
buttons[1].textContent = trueBtn;
return new Promise((resolve, reject) => {
buttons[0].onclick = () => {
hidePopup()
return;
}
buttons[1].onclick = () => {
let value = input.value;
hidePopup()
resolve(value)
}
})
}
//Function for displaying toast notifications. pass in error for mode param if you want to show an error.
function notify(message, mode, options = {}) {
const { pinned = false, sound } = options
if (mode === "error") console.error(message);
let icon
switch (mode) {
case 'success':
icon = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 15.172l9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z"/></svg>`
break;
case 'error':
icon = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-7v2h2v-2h-2zm0-8v6h2V7h-2z"/></svg>`
break;
}
getRef("notification_drawer").push(message, { pinned, icon });
if (navigator.onLine && sound) {
getRef("notification_sound").currentTime = 0;
getRef("notification_sound").play();
}
}
const currentYear = new Date().getFullYear();
function getFormatedTime(time, relative) {
try {
if (String(time).indexOf("_")) time = String(time).split("_")[0];
const intTime = parseInt(time);
if (String(intTime).length < 13) time *= 1000;
let timeFrag = new Date(intTime).toString().split(" "),
day = timeFrag[0],
month = timeFrag[1],
date = timeFrag[2],
year = timeFrag[3],
minutes = new Date(intTime).getMinutes(),
hours = new Date(intTime).getHours(),
currentTime = new Date().toString().split(" ");
minutes = minutes < 10 ? `0${minutes}` : minutes;
let finalHours = ``;
if (hours > 12) finalHours = `${hours - 12}:${minutes}`;
else if (hours === 0) finalHours = `12:${minutes}`;
else finalHours = `${hours}:${minutes}`;
finalHours = hours >= 12 ? `${finalHours} PM` : `${finalHours} AM`;
if (relative) {
return `${date} ${month} ${year}`;
} else return `${finalHours} ${month} ${date} ${year}`;
} catch (e) {
console.error(e);
return time;
}
}
window.addEventListener('hashchange', e => showPage(window.location.hash))
window.addEventListener("load", () => {
document.body.classList.remove('hide-completely')
showPage(window.location.hash)
// document.querySelectorAll('sm-input[data-flo-id]').forEach(input => input.customValidation = validateAddr)
document.addEventListener('keyup', (e) => {
if (e.code === 'Escape') {
hidePopup()
}
})
document.addEventListener("pointerdown", (e) => {
if (e.target.closest("button, sm-button:not([disabled]), .interact")) {
createRipple(e, e.target.closest("button, sm-button, .interact"));
}
});
document.addEventListener('copy', () => {
notify('copied', 'success')
})
});
function createRipple(event, target) {
const circle = document.createElement("span");
const diameter = Math.max(target.clientWidth, target.clientHeight);
const radius = diameter / 2;
const targetDimensions = target.getBoundingClientRect();
circle.style.width = circle.style.height = `${diameter}px`;
circle.style.left = `${event.clientX - (targetDimensions.left + radius)}px`;
circle.style.top = `${event.clientY - (targetDimensions.top + radius)}px`;
circle.classList.add("ripple");
const rippleAnimation = circle.animate(
[
{
transform: "scale(3)",
opacity: 0,
},
],
{
duration: 1000,
fill: "forwards",
easing: "ease-out",
}
);
target.append(circle);
rippleAnimation.onfinish = () => {
circle.remove();
};
}
function showPage(targetPage) {
let pageId
if (targetPage === '') {
pageId = 'overview_page'
}
else {
pageId = targetPage.includes('#') ? targetPage.split('#')[1] : targetPage
}
if(!appPages.includes(pageId)) return
document.querySelector('.page:not(.hide-completely)').classList.add('hide-completely')
getRef(pageId).classList.remove('hide-completely')
}

View File

@ -1,61 +1,88 @@
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@500;600;700&family=Roboto:wght@400;500;700&display=swap");
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
margin: 0;
font-family: 'Roboto', sans-serif;
box-sizing: border-box;
font-family: "Roboto", sans-serif;
}
:root {
font-size: clamp(1rem, 1.2vmax, 3rem);
}
html, body {
height: 100%;
scroll-behavior: smooth;
}
body {
--accent-color: #303F9F;
--text-color: 17, 17, 17;
--foreground-color: 255, 255, 255;
background: rgba(var(--foreground-color), 1);
color: rgba(var(--text-color), 1);
font-size: 16px;
background: rgba(var(--background-color), 1);
}
body,
body * {
--accent-color: #0D7377;
--text-color: 17, 17, 17;
--background-color: 255, 255, 255;
--danger-color: red;
}
body[data-theme="dark"] {
--accent-color: #4a5cd3;
--foreground-color: 20, 20, 20;
--text-color: 238, 238, 238;
}
h1, h2, h3, h4, h5 {
font-family: 'Poppins', sans-serif;
text-transform: capitalize;
}
h1 {
font-size: 3rem;
}
h2 {
font-size: 2rem;
}
h3 {
font-size: 1.5rem;
}
h4 {
font-size: 1rem;
}
h5 {
font-size: 0.8rem;
body[data-theme=dark],
body[data-theme=dark] * {
--accent-color: #32E0C4;
--text-color: 240, 240, 240;
--text-color-light: 170, 170, 170;
--background-color: 10, 10, 10;
--danger-color: rgb(255, 106, 106);
}
p {
margin: 1.5rem 0;
font-size: 0.8;
max-width: 65ch;
line-height: 1.7;
margin-bottom: 1.5rem;
color: rgba(var(--text-color), 0.8);
}
p:not(:last-of-type) {
margin-bottom: 1rem;
}
img {
object-fit: cover;
}
a {
color: inherit;
text-decoration: none;
}
a:focus-visible {
box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset;
}
button {
display: inline-flex;
border: none;
background-color: inherit;
}
a:any-link:focus-visible {
outline: rgba(var(--text-color), 1) 0.1rem solid;
}
sm-button {
--border-radius: 0.3rem;
}
ul {
list-style: none;
}
.flex {
display: flex;
}
.grid {
display: grid;
}
.hide {
opacity: 0;
@ -67,110 +94,264 @@ p {
}
.no-transformations {
-webkit-transform: none !important;
transform: none !important;
transform: none !important;
}
.icon {
height: 1.2rem;
width: 1.2rem;
fill: none;
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
.overflow-ellipsis {
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
#navbar {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
position: fixed;
left: 0;
bottom: 0;
top: 0;
-webkit-box-shadow: 0.2rem 0 0.5rem rgba(0, 0, 0, 0.1);
box-shadow: 0.2rem 0 0.5rem rgba(0, 0, 0, 0.1);
z-index: 3;
padding: 1rem 0;
background: rgba(var(--foreground-color), 1);
border-right: solid 1px rgba(var(--text-color), 0.16);
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
-webkit-transition: -webkit-transform 0.3s;
transition: -webkit-transform 0.3s;
transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
.breakable {
overflow-wrap: break-word;
word-wrap: break-word;
-ms-word-break: break-all;
word-break: break-word;
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
#navbar .navbar-item {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
position: relative;
text-align: center;
cursor: pointer;
padding: 0.6rem 1.5rem;
padding-right: 3rem;
border-radius: 0.4em;
color: rgba(var(--text-color), 0.8);
font-size: 0.9em;
.full-bleed {
grid-column: 1/4;
}
.h1 {
font-size: 2.5rem;
}
.h2 {
font-size: 2rem;
}
.h3 {
font-size: 1.4rem;
}
.h4 {
font-size: 1rem;
}
.h5 {
font-size: 0.8rem;
}
.uppercase {
text-transform: uppercase;
width: 100%;
-webkit-tap-highlight-color: transparent;
}
#navbar .navbar-item .icon {
margin-right: 1rem;
}
#navbar .navbar-item h4 {
.capitalize {
text-transform: capitalize;
font-weight: 600;
}
#navbar .active {
color: var(--accent-color);
.flex {
display: flex;
}
#navbar .active .icon {
stroke: var(--accent-color);
}
#logo {
display: -ms-grid;
.grid {
display: grid;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.grid-3 {
grid-template-columns: 1fr auto auto;
}
.flow-column {
grid-auto-flow: column;
}
.gap-0-5 {
gap: 0.5rem;
}
.gap-1 {
gap: 1rem;
}
.gap-1-5 {
gap: 1.5rem;
}
.gap-2 {
gap: 2rem;
}
.gap-3 {
gap: 3rem;
}
.text-align-right {
text-align: right;
}
.align-start {
align-items: flex-start;
}
.align-center {
align-items: center;
}
.text-center {
text-align: center;
}
.justify-start {
justify-content: start;
}
.justify-center {
justify-content: center;
}
.justify-right {
margin-left: auto;
}
.align-self-center {
align-self: center;
}
.justify-self-center {
justify-self: center;
}
.justify-self-start {
justify-self: start;
}
.justify-self-end {
justify-self: end;
}
.direction-column {
flex-direction: column;
}
.space-between {
justify-content: space-between;
}
.w-100 {
width: 100%;
-ms-grid-columns: auto 1fr;
grid-template-columns: auto 1fr;
gap: 0.6rem 0.6rem;
margin-right: 1rem;
padding: 0.6rem 2rem;
margin-bottom: 1rem;
}
#logo h4 {
text-transform: capitalize;
font-size: 1.2rem;
font-weight: 600;
.color-0-8 {
color: rgba(var(--text-color), 0.8);
}
#logo h5 {
font-family: 'Roboto', sans-serif;
.weight-400 {
font-weight: 400;
}
.weight-500 {
font-weight: 500;
}
.ripple {
position: absolute;
border-radius: 50%;
transform: scale(0);
background: rgba(var(--text-color), 0.16);
pointer-events: none;
}
.interact {
position: relative;
overflow: hidden;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
.observe-empty-state:empty {
display: none;
}
.observe-empty-state:not(:empty) ~ .empty-state {
display: none;
}
.icon {
width: 1.5rem;
height: 1.5rem;
fill: rgba(var(--text-color), 0.9);
}
.button__icon {
height: 1.2rem;
width: 1.2rem;
}
.button__icon--left {
margin-right: 0.5rem;
}
.button__icon--right {
margin-left: 0.5rem;
}
#confirmation_popup,
#prompt_popup {
flex-direction: column;
}
#confirmation_popup h4,
#prompt_popup h4 {
font-weight: 500;
margin-bottom: 0.5rem;
}
#confirmation_popup sm-button,
#prompt_popup sm-button {
margin: 0;
}
#confirmation_popup .flex,
#prompt_popup .flex {
padding: 0;
margin-top: 1rem;
}
#confirmation_popup .flex sm-button:first-of-type,
#prompt_popup .flex sm-button:first-of-type {
margin-right: 0.6rem;
margin-left: auto;
}
h1, h2, h3, h4.h5 {
font-family: "Poppins", sans-serif;
}
h2 {
margin: 3rem 0 1rem 0;
text-transform: capitalize;
}
main {
display: grid;
height: 100%;
}
#main_header {
padding: 0.5rem 1.5rem;
border-bottom: 1px solid rgba(var(--text-color), 0.1);
}
#side_nav_button {
padding: 0.5rem;
margin-left: -0.5rem;
}
#logo {
display: grid;
align-items: center;
width: 100%;
grid-template-columns: auto 1fr;
gap: 0 0.5rem;
margin-right: 1rem;
}
#logo h4 {
text-transform: capitalize;
font-size: 1rem;
font-weight: 600;
}
#logo #main_logo {
height: 1.4rem;
width: 1.4rem;
@ -178,172 +359,118 @@ p {
stroke: none;
}
.toggle {
margin-top: auto;
position: relative;
cursor: pointer;
padding: 0;
}
.toggle input[type='checkbox'] {
display: none;
}
.toggle .switch {
overflow: hidden;
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
justify-items: center;
padding: 0.2rem;
min-height: 1.6rem;
max-height: 1.6rem;
border-radius: 0.5rem;
position: relative;
margin: 0;
margin-right: 1rem;
}
.toggle .circle {
border-radius: 0.5rem;
-webkit-transition: -webkit-transform 0.3s;
transition: -webkit-transform 0.3s;
transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
fill: rgba(var(--text-color), 0.8);
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
height: 1.2rem;
width: 1.2rem;
}
.toggle .circle:first-of-type {
margin-bottom: 0.4rem;
}
.toggle .circle line {
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
}
.toggle input:checked ~ .switch .circle {
-webkit-transform: translateY(-1.7rem);
transform: translateY(-1.7rem);
}
.page {
padding: 2rem 1.5rem;
.right {
max-height: 100%;
overflow-y: auto;
}
.options-tab {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
margin-top: 1rem;
margin-bottom: 1rem;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
#side_nav > :last-child {
padding-bottom: 3rem;
}
.options-tab .option {
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
border-radius: 0.4rem;
padding: 1.5rem;
margin-right: 1rem;
margin-bottom: 1rem;
width: 9rem;
border: solid 1px rgba(var(--text-color), 0.2);
text-transform: capitalize;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
.options-tab .option .icon {
background: rgba(var(--text-color), 0.1);
height: 2.8rem;
width: 2.8rem;
padding: 0.8rem;
border-radius: 2rem;
margin-bottom: 1rem;
stroke: rgba(var(--text-color), 0.4);
}
.options-tab .option h4 {
font-weight: 400;
#side_nav h4 {
font-size: 0.9rem;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 1.5rem;
}
#home_page h1 {
font-weight: 600;
.right {
padding: 1.5rem;
}
.right h1 {
margin-bottom: 1.5rem;
}
#home_page p {
margin-bottom: 3rem;
.page {
display: flex;
flex-direction: column;
padding-bottom: 3rem;
}
#home_page h2 {
margin-bottom: 1rem;
.list {
list-style: none;
display: flex;
flex-direction: column;
margin-bottom: 0.8rem;
}
.list__item {
display: flex;
padding: 0.8rem 1.5rem;
text-transform: capitalize;
}
.list__item--active {
color: var(--accent-color);
background: rgba(var(--text-color), 0.06);
}
@media screen and (max-width: 640px) {
#main_header {
position: -webkit-sticky;
position: sticky;
top: 0;
padding: 1.5rem;
}
#main_header .icon {
stroke-width: 12;
height: 3rem;
width: 3rem;
background: rgba(var(--foreground-color), 1);
border-radius: 2rem;
padding: 1rem;
-webkit-box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.16), 0 0.4rem 0.8rem rgba(0, 0, 0, 0.16);
box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.16), 0 0.4rem 0.8rem rgba(0, 0, 0, 0.16);
main {
grid-template-rows: auto 1fr;
grid-template-columns: 1fr;
}
}
@media screen and (min-width: 640px) {
sm-popup {
--width: 32rem;
}
@media only screen and (min-width: 640px) {
main {
display: -ms-grid;
display: grid;
-ms-grid-columns: auto 1fr;
grid-template-columns: auto 1fr;
gap: 2rem;
height: 100vh;
overflow-y: auto;
}
p {
max-width: 40rem;
}
#navbar {
position: relative;
-webkit-transform: none;
transform: none;
height: 100%;
}
#main_header {
padding: 1rem 1.5rem;
grid-area: main-header;
}
#side_nav_button {
display: none;
}
}
@media (hover: hover) {
.navbar-item:hover {
background: rgba(var(--text-color), 0.1);
main {
grid-template-columns: 14rem minmax(0, 1fr);
grid-template-rows: auto 1fr;
grid-template-areas: "main-header main-header" ". .";
}
.right {
display: grid;
grid-template-columns: 1fr 90% 1fr;
}
.right > * {
grid-column: 2/3;
}
.page__title {
font-size: 2.5rem;
}
#overview_page {
display: grid;
gap: 1.5rem;
grid-template-columns: 1fr auto;
}
#overview_page > div:first-of-type {
grid-column: 2/3;
text-align: right;
}
#overview_page > div:nth-of-type(2) {
grid-row: 1/2;
}
}
/*# sourceMappingURL=main.css.map */
@media (any-hover: hover) {
::-webkit-scrollbar {
width: 0.5rem;
height: 0.5rem;
}
::-webkit-scrollbar-thumb {
background: rgba(var(--text-color), 0.3);
border-radius: 1rem;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(var(--text-color), 0.5);
}
.list__item:hover {
background: rgba(var(--text-color), 0.1);
cursor: pointer;
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,49 +1,79 @@
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@500;600;700&family=Roboto:wght@400;500;700&display=swap');
*{
box-sizing: border-box;
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Roboto', sans-serif;
}
:root{
font-size: clamp(1rem, 1.2vmax, 3rem);
}
html, body{
height: 100%;
scroll-behavior: smooth;
}
body{
--accent-color: #303F9F;
--text-color: 17, 17, 17;
--foreground-color: 255, 255, 255;
background: rgba(var(--foreground-color), 1);
body {
&,
*{
--accent-color: #0D7377;
--text-color: 17, 17, 17;
--background-color: 255, 255, 255;
--danger-color: red;
}
color: rgba(var(--text-color), 1);
font-size: 16px;
background: rgba(var(--background-color), 1);
}
body[data-theme="dark"]{
--accent-color: #4a5cd3;
--foreground-color: 20, 20, 20;
--text-color: 238, 238, 238;
body[data-theme='dark']{
&,
*{
--accent-color: #32E0C4;
--text-color: 240, 240, 240;
--text-color-light: 170, 170, 170;
--background-color: 10, 10, 10;
--danger-color: rgb(255, 106, 106);
}
}
h1, h2, h3, h4, h5{
font-family: 'Poppins', sans-serif;
text-transform: capitalize;
}
h1{
font-size: 3rem;
}
h2{
font-size: 2rem;
}
h3{
font-size: 1.5rem;
}
h4{
font-size: 1rem;
}
h5{
font-size: 0.8rem;
}
p{
margin: 1.5rem 0;
p {
font-size: 0.8;
max-width: 65ch;
line-height: 1.7;
margin-bottom: 1.5rem;
color: rgba(var(--text-color), 0.8);
&:not(:last-of-type){
margin-bottom: 1rem;
}
}
img{
object-fit: cover;
}
a{
color: inherit;
text-decoration: none;
&:focus-visible{
box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset;
}
}
button{
display: inline-flex;
border: none;
background-color: inherit;
}
a:any-link:focus-visible{
outline: rgba(var(--text-color), 1) 0.1rem solid;
}
sm-button{
--border-radius: 0.3rem;
}
ul{
list-style: none;
}
.flex{
display: flex;
}
.grid{
display: grid;
}
.hide{
opacity: 0;
@ -55,77 +85,209 @@ p{
.no-transformations{
transform: none !important;
}
.overflow-ellipsis{
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.breakable{
overflow-wrap: break-word;
word-wrap: break-word;
-ms-word-break: break-all;
word-break: break-word;
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
.full-bleed{
grid-column: 1/4;
}
.h1{
font-size: 2.5rem;
}
.h2{
font-size: 2rem;
}
.h3{
font-size: 1.4rem;
}
.h4{
font-size: 1rem;
}
.h5{
font-size: 0.8rem;
}
.uppercase{
text-transform: uppercase;
}
.capitalize{
text-transform: capitalize;
}
.flex{
display: flex;
}
.grid{
display: grid;
}
.grid-3{
grid-template-columns: 1fr auto auto;
}
.flow-column{
grid-auto-flow: column;
}
.gap-0-5{
gap: 0.5rem;
}
.gap-1{
gap: 1rem;
}
.gap-1-5{
gap: 1.5rem;
}
.gap-2{
gap: 2rem;
}
.gap-3{
gap: 3rem;
}
.text-align-right{
text-align: right;
}
.align-start{
align-items: flex-start;
}
.align-center{
align-items: center;
}
.text-center{
text-align: center;
}
.justify-start{
justify-content: start;
}
.justify-center{
justify-content: center;
}
.justify-right{
margin-left: auto;
}
.align-self-center{
align-self: center;
}
.justify-self-center{
justify-self: center;
}
.justify-self-start{
justify-self: start;
}
.justify-self-end{
justify-self: end;
}
.direction-column{
flex-direction: column;
}
.space-between{
justify-content: space-between;
}
.w-100{
width: 100%;
}
.color-0-8{
color: rgba(var(--text-color), 0.8);
}
.weight-400{
font-weight: 400;
}
.weight-500{
font-weight: 500;
}
.ripple{
position: absolute;
border-radius: 50%;
transform: scale(0);
background: rgba(var(--text-color), 0.16);
pointer-events: none;
}
.interact{
position: relative;
overflow: hidden;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
.observe-empty-state:empty{
display: none;
}
.observe-empty-state:not(:empty) ~ .empty-state{
display: none;
}
.icon{
width: 1.5rem;
height: 1.5rem;
fill: rgba(var(--text-color), 0.9);
}
.button__icon{
height: 1.2rem;
width: 1.2rem;
fill: none;
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
&--left{
margin-right: 0.5rem;
}
&--right{
margin-left: 0.5rem;
}
}
#navbar{
display: flex;
#confirmation_popup,
#prompt_popup {
flex-direction: column;
align-items: center;
position: fixed;
left: 0;
bottom: 0;
top: 0;
box-shadow: 0.2rem 0 0.5rem rgba(0, 0, 0, 0.1);
z-index: 3;
padding: 1rem 0;
background: rgba(var(--foreground-color), 1);
border-right: solid 1px rgba(var(--text-color), 0.16);
transform: translateX(-100%);
transition: transform 0.3s;
.navbar-item{
display: flex;
position: relative;
text-align: center;
cursor: pointer;
padding: 0.6rem 1.5rem;
padding-right: 3rem;
border-radius: 0.4em;
color: rgba(var(--text-color), 0.8);
font-size: 0.9em;
text-transform: uppercase;
width: 100%;
-webkit-tap-highlight-color: transparent;
.icon{
margin-right: 1rem;
}
h4{
text-transform: capitalize;
font-weight: 600;
}
}
.active{
color: var(--accent-color);
.icon{
stroke: var(--accent-color);
h4 {
font-weight: 500;
margin-bottom: 0.5rem;
}
sm-button{
margin: 0;
}
.flex {
padding: 0;
margin-top: 1rem;
sm-button:first-of-type {
margin-right: 0.6rem;
margin-left: auto;
}
}
}
h1,h2,h3,h4.h5{
font-family: 'Poppins', sans-serif;
}
h2{
margin: 3rem 0 1rem 0;
text-transform: capitalize;
}
main{
display: grid;
height: 100%;
}
#main_header{
padding: 0.5rem 1.5rem;
border-bottom: 1px solid rgba(var(--text-color), .1);
}
#side_nav_button{
padding: 0.5rem;
margin-left: -0.5rem;
}
#logo{
display: grid;
align-items: center;
width: 100%;
grid-template-columns: auto 1fr;
gap: 0.6rem 0.6rem;
gap: 0 0.5rem;
margin-right: 1rem;
padding: 0.6rem 2rem;
margin-bottom: 1rem;
h4{
text-transform: capitalize;
font-size: 1.2rem;
font-size: 1rem;
font-weight: 600;
}
h5{
font-family: 'Roboto', sans-serif;
font-weight: 400;
}
#main_logo{
height: 1.4rem;
width: 1.4rem;
@ -133,135 +295,107 @@ p{
stroke: none;
}
}
.toggle{
margin-top: auto;
position: relative;
cursor: pointer;
padding: 0;
input[type='checkbox']{
display: none;
}
.switch{
overflow: hidden;
display: inline-flex;
flex-direction: column;
justify-items: center;
padding: 0.2rem;
min-height: 1.6rem;
max-height: 1.6rem;
border-radius: 0.5rem;
position: relative;
margin: 0;
margin-right: 1rem;
}
.circle{
border-radius: 0.5rem;
transition: transform 0.3s;
&:first-of-type{
margin-bottom: 0.4rem;
}
fill: rgba(var(--text-color), 0.8);
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
height: 1.2rem;
width: 1.2rem;
line{
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
}
}
input:checked ~ .switch .circle{
transform: translateY(-1.7rem);
}
}
.page{
padding: 2rem 1.5rem;
.right{
max-height: 100%;
overflow-y: auto;
}
.options-tab{
display: flex;
margin-top: 1rem;
margin-bottom: 1rem;
flex-wrap: wrap;
.option{
display: inline-flex;
flex-direction: column;
border-radius: 0.4rem;
#side_nav{
& > :last-child{
padding-bottom: 3rem;
}
h4{
font-size: 0.9rem;
letter-spacing: 0.08em;
text-transform: uppercase;
padding: 1.5rem;
margin-right: 1rem;
margin-bottom: 1rem;
width: 9rem;
border: solid 1px rgba(var(--text-color), 0.2);
text-transform: capitalize;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
.icon{
background: rgba(var(--text-color), 0.1);
height: 2.8rem;
width: 2.8rem;
padding: 0.8rem;
border-radius: 2rem;
margin-bottom: 1rem;
stroke: rgba(var(--text-color), 0.4);
}
h4{
font-weight: 400;
font-size: 0.9rem;
}
}
}
#home_page{
.right{
padding: 1.5rem;
h1{
font-weight: 600;
margin-bottom: 1.5rem;
}
p{
margin-bottom: 3rem;
}
h2{
margin-bottom: 1rem;
}
.page{
display: flex;
flex-direction: column;
padding-bottom: 3rem;
}
.list{
list-style: none;
display: flex;
flex-direction: column;
margin-bottom: 0.8rem;
}
.list__item{
display: flex;
padding: 0.8rem 1.5rem;
text-transform: capitalize;
&--active{
color: var(--accent-color);
background: rgba(var(--text-color), .06);
}
}
@media screen and (max-width: 640px){
main{
grid-template-rows: auto 1fr;
grid-template-columns: 1fr;
}
}
@media screen and (min-width: 640px){
sm-popup{
--width: 32rem;
}
#main_header{
position: sticky;
top: 0;
padding: 1.5rem;
.icon{
stroke-width: 12;
height: 3rem;
width: 3rem;
background: rgba(var(--foreground-color), 1);
border-radius: 2rem;
padding: 1rem;
box-shadow: 0 0.1rem 0.2rem rgba(0, 0, 0, 0.16),
0 0.4rem 0.8rem rgba(0, 0, 0, 0.16);
padding: 1rem 1.5rem;
grid-area: main-header;
}
#side_nav_button{
display: none;
}
main{
grid-template-columns: 14rem minmax(0, 1fr);
grid-template-rows: auto 1fr;
grid-template-areas: 'main-header main-header' '. .';
}
.right{
display: grid;
grid-template-columns: 1fr 90% 1fr;
& > * {
grid-column: 2/3;
}
}
.page__title{
font-size: 2.5rem;
}
#overview_page{
display: grid;
gap: 1.5rem;
grid-template-columns: 1fr auto;
& > div:first-of-type{
grid-column: 2/3;
text-align: right;
}
& > div:nth-of-type(2){
grid-row: 1/2;
}
}
}
@media only screen and (min-width: 640px){
main{
display: grid;
grid-template-columns: auto 1fr;
gap: 2rem;
height: 100vh;
overflow-y: auto;
@media (any-hover: hover){
::-webkit-scrollbar{
width: 0.5rem;
height: 0.5rem;
}
p{
max-width: 40rem;
::-webkit-scrollbar-thumb{
background: rgba(var(--text-color), 0.3);
border-radius: 1rem;
&:hover{
background: rgba(var(--text-color), 0.5);
}
}
#navbar{
position: relative;
transform: none;
height: 100%;
}
#main_header{
display: none;
}
}
@media (hover: hover){
.navbar-item:hover{
background: rgba(var(--text-color), 0.1);
.list__item:hover{
background: rgba(var(--text-color), .1);
cursor: pointer;
}
}

View File

@ -6,149 +6,83 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="css/main.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;700&family=Roboto+Mono&family=Roboto:wght@400;500;700&display=swap"
rel="stylesheet">
</head>
<body data-theme="light">
<body data-theme="light" class="hide-completely">
<sm-notifications id="notification_drawer"></sm-notifications>
<audio id="notification_sound">
<source src="https://rmservices.duckdns.org/files/notification-sound.mp3" type="audio/mpeg">
<source src="https://rmservices.duckdns.org/files/notification-sound.ogg" type="audio/ogg">
</audio>
<sm-popup id="confirmation_popup">
<h4 id="confirm_title"></h4>
<p id="confirm_message"></p>
<div class="flex align-center">
<sm-button variant="no-outline" class="cancel-btn">Cancel</sm-button>
<sm-button variant="no-outline" class="submit-btn">OK</button>
</div>
</sm-popup>
<sm-popup id="prompt_popup">
<h4 id="prompt_title"></h4>
<p id="prompt_message"></p>
<sm-input id="prompt_input"></sm-input>
<div class="flex align-center">
<sm-button variant="no-outline" class="cancel-btn">Cancel</sm-button>
<sm-button variant="no-outline" class="submit-btn" type="submit">OK</button>
</div>
</sm-popup>
<main>
<nav id="navbar">
<header id="main_header" class="flex align-center space-between">
<button id="side_nav_button" class="interact" onclick="getRef('side_nav').open()"
aria-label="Hamburger menu toggle button">
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
<path fill="none" d="M0 0h24v24H0z" />
<path d="M16 18v2H5v-2h11zm5-7v2H3v-2h18zm-2-7v2H8V4h11z" />
</svg>
</button>
<div id="logo">
<svg id="main_logo" viewBox="0 0 27.25 32">
<title>RanchiMall</title>
<path
d="M27.14,30.86c-.74-2.48-3-4.36-8.25-6.94a20,20,0,0,1-4.2-2.49,6,6,0,0,1-1.25-1.67,4,4,0,0,1,0-2.26c.37-1.08.79-1.57,3.89-4.55a11.66,11.66,0,0,0,3.34-4.67,6.54,6.54,0,0,0,.05-2.82C20,3.6,18.58,2,16.16.49c-.89-.56-1.29-.64-1.3-.24a3,3,0,0,1-.3.72l-.3.55L13.42.94C13,.62,12.4.26,12.19.15c-.4-.2-.73-.18-.72.05a9.39,9.39,0,0,1-.61,1.33s-.14,0-.27-.13C8.76.09,8-.27,8,.23A11.73,11.73,0,0,1,6.76,2.6C4.81,5.87,2.83,7.49.77,7.49c-.89,0-.88,0-.61,1,.22.85.33.92,1.09.69A5.29,5.29,0,0,0,3,8.33c.23-.17.45-.29.49-.26a2,2,0,0,1,.22.63A1.31,1.31,0,0,0,4,9.34a5.62,5.62,0,0,0,2.27-.87L7,8l.13.55c.19.74.32.82,1,.65a7.06,7.06,0,0,0,3.46-2.47l.6-.71-.06.64c-.17,1.63-1.3,3.42-3.39,5.42L6.73,14c-3.21,3.06-3,5.59.6,8a46.77,46.77,0,0,0,4.6,2.41c.28.13,1,.52,1.59.87,3.31,2,4.95,3.92,4.95,5.93a2.49,2.49,0,0,0,.07.77h0c.09.09,0,.1.9-.14a2.61,2.61,0,0,0,.83-.32,3.69,3.69,0,0,0-.55-1.83A11.14,11.14,0,0,0,17,26.81a35.7,35.7,0,0,0-5.1-2.91C9.37,22.64,8.38,22,7.52,21.17a3.53,3.53,0,0,1-1.18-2.48c0-1.38.71-2.58,2.5-4.23,2.84-2.6,3.92-3.91,4.67-5.65a3.64,3.64,0,0,0,.42-2A3.37,3.37,0,0,0,13.61,5l-.32-.74.29-.48c.17-.27.37-.63.46-.8l.15-.3.44.64a5.92,5.92,0,0,1,1,2.81,5.86,5.86,0,0,1-.42,1.94c0,.12-.12.3-.15.4a9.49,9.49,0,0,1-.67,1.1,28,28,0,0,1-4,4.29C8.62,15.49,8.05,16.44,8,17.78a3.28,3.28,0,0,0,1.11,2.76c.95,1,2.07,1.74,5.25,3.32,3.64,1.82,5.22,2.9,6.41,4.38A4.78,4.78,0,0,1,21.94,31a3.21,3.21,0,0,0,.14.92,1.06,1.06,0,0,0,.43-.05l.83-.22.46-.12-.06-.46c-.21-1.53-1.62-3.25-3.94-4.8a37.57,37.57,0,0,0-5.22-2.82A13.36,13.36,0,0,1,11,21.19a3.36,3.36,0,0,1-.8-4.19c.41-.85.83-1.31,3.77-4.15,2.39-2.31,3.43-4.13,3.43-6a5.85,5.85,0,0,0-2.08-4.29c-.23-.21-.44-.43-.65-.65A2.5,2.5,0,0,1,15.27.69a10.6,10.6,0,0,1,2.91,2.78A4.16,4.16,0,0,1,19,6.16a4.91,4.91,0,0,1-.87,3c-.71,1.22-1.26,1.82-4.27,4.67a9.47,9.47,0,0,0-2.07,2.6,2.76,2.76,0,0,0-.33,1.54,2.76,2.76,0,0,0,.29,1.47c.57,1.21,2.23,2.55,4.65,3.73a32.41,32.41,0,0,1,5.82,3.24c2.16,1.6,3.2,3.16,3.2,4.8a1.94,1.94,0,0,0,.09.76,4.54,4.54,0,0,0,1.66-.4C27.29,31.42,27.29,31.37,27.14,30.86ZM6.1,7h0a3.77,3.77,0,0,1-1.46.45L4,7.51l.68-.83a25.09,25.09,0,0,0,3-4.82A12,12,0,0,1,8.28.76c.11-.12.77.32,1.53,1l.63.58-.57.84A10.34,10.34,0,0,1,6.1,7Zm5.71-1.78A9.77,9.77,0,0,1,9.24,7.18h0a5.25,5.25,0,0,1-1.17.28l-.58,0,.65-.78a21.29,21.29,0,0,0,2.1-3.12c.22-.41.42-.76.44-.79s.5.43.9,1.24L12,5ZM13.41,3a2.84,2.84,0,0,1-.45.64,11,11,0,0,1-.9-.91l-.84-.9.19-.45c.34-.79.39-.8,1-.31A9.4,9.4,0,0,1,13.8,2.33q-.18.34-.39.69Z" />
</svg>
<span>
<h5>RanchiMall</h5>
<h4>App Name</h4>
</span>
<h4>App name</h4>
</div>
<div class="navbar-item active" onclick="showPage(this, 'home_page')">
<svg class="icon" viewBox="0 0 64 64">
<path
d="M24.77,44.15H40.06V63.5H53.4V36h5.66a3.38,3.38,0,0,0,2.53-5.68l-6.73-7.16V11.26H46.48v3L34.53,1.59a3.49,3.49,0,0,0-5.06,0L2.41,30.35A3.38,3.38,0,0,0,4.94,36H10.6V63.5H24.77" />
</svg>
<h4>Home</h4>
</div>
<div class="navbar-item" onclick="showPage(this, 'profile_page')">
<svg class="icon" viewBox="0 0 49.54 61.12">
<path
d="M49.34,19.94c7.73,0,13.26,5.26,13.26,14S58.18,50.14,49.71,50.08,36.82,42.66,36.82,33.93s5.53-14,13.26-14"
transform="translate(-25.23 -20)" />
<path
d="M43.83,52c-2.34,4.38-9.77,6.64-15.31,9.06-2.29,1-4.11,13-1.53,13a46.06,46.06,0,0,0,23.51,6,40.48,40.48,0,0,0,22.51-6c2.58,0,.76-12-1.53-13-5.54-2.42-13-4.68-15.31-9.06"
transform="translate(-25.23 -19.44)" />
</svg>
<h4>User</h4>
</div>
<label class="toggle navbar-item" title="Change theme">
<input type="checkbox" name="theme toggle" id="theme_toggle">
<div class="switch">
<svg class="circle" viewBox="0 0 64 64">
<title>dark theme</title>
<path
d="M48.25,45.45A27.26,27.26,0,0,1,20.82,18.37,26.75,26.75,0,0,1,27.47.71a31.71,31.71,0,0,0-27,31.2,31.8,31.8,0,0,0,32,31.59A32,32,0,0,0,63.12,41.12,27.59,27.59,0,0,1,48.25,45.45Z"
transform="translate(0 0)" />
</svg>
<svg class="circle" viewBox="0 0 64 64">
<title>light theme</title>
<circle cx="32" cy="32" r="13.9" />
<line x1="32" y1="6.86" x2="32" />
<line x1="32" y1="64" x2="32" y2="57.14" />
<line x1="57.14" y1="32" x2="64" y2="32" />
<line y1="32" x2="6.86" y2="32" />
<line x1="49.78" y1="14.22" x2="54.63" y2="9.37" />
<line x1="9.37" y1="54.63" x2="14.22" y2="49.78" />
<line x1="49.78" y1="49.78" x2="54.63" y2="54.63" />
<line x1="9.37" y1="9.37" x2="14.22" y2="14.22" />
</svg>
</div>
<h4>Toggle theme</h4>
</label>
</nav>
<header id="main_header">
<svg id="sidebar_btn" class="icon" viewBox="0 0 64 64">
<title>menu</title>
<line y1="12" x2="64" y2="12" />
<line y1="52" x2="42" y2="52" />
</svg>
<theme-toggle></theme-toggle>
</header>
<section class="page" id="home_page">
<h1>Heading</h1>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nisi excepturi eius voluptate quod quasi
dolore, quisquam, voluptatem repellendus sapiente consectetur similique ducimus dicta magni harum,
</p>
<h3>Options</h3>
<hamburger-menu id="side_nav">
<ul class="list">
<li>
<a href="#dashboard" class="list__item list__item--active interact">
dashboard
</a>
</li>
<li>
<a href="#settings" class="list__item interact">
Settings
</a>
</li>
</ul>
</hamburger-menu>
<article class="right language-html">
<section id="dashboard" class="page">
<h1 class="page__title">Dashboard</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Esse, sint. Aperiam ipsum expedita tenetur quasi, repellat ea. Laboriosam, earum ratione!</p>
</section>
<div class="options-tab">
<div class="option">
<svg class="icon" viewBox="0 0 64 64">
<title>transfer</title>
<polyline
points="17.04 35.97 14.57 33.5 40.15 7.9 32.75 0.5 55.52 0.5 55.52 23.28 48.12 15.87 23.86 40.14 15.88 48.13 8.48 40.72 8.48 63.5 31.25 63.5 23.85 56.1 49.43 30.5 46.96 28.03" />
</svg>
<h4>Option</h4>
</div>
<div class="option">
<svg class="icon" viewBox="0 0 64 64">
<title>transfer</title>
<polyline
points="17.04 35.97 14.57 33.5 40.15 7.9 32.75 0.5 55.52 0.5 55.52 23.28 48.12 15.87 23.86 40.14 15.88 48.13 8.48 40.72 8.48 63.5 31.25 63.5 23.85 56.1 49.43 30.5 46.96 28.03" />
</svg>
<h4>Option</h4>
</div>
<div class="option">
<svg class="icon" viewBox="0 0 64 64">
<title>transfer</title>
<polyline
points="17.04 35.97 14.57 33.5 40.15 7.9 32.75 0.5 55.52 0.5 55.52 23.28 48.12 15.87 23.86 40.14 15.88 48.13 8.48 40.72 8.48 63.5 31.25 63.5 23.85 56.1 49.43 30.5 46.96 28.03" />
</svg>
<h4>Option</h4>
</div>
<div class="option">
<svg class="icon" viewBox="0 0 64 64">
<title>transfer</title>
<polyline
points="17.04 35.97 14.57 33.5 40.15 7.9 32.75 0.5 55.52 0.5 55.52 23.28 48.12 15.87 23.86 40.14 15.88 48.13 8.48 40.72 8.48 63.5 31.25 63.5 23.85 56.1 49.43 30.5 46.96 28.03" />
</svg>
<h4>Option</h4>
</div>
</div>
</section>
<section id="profile_page" class="page hide-completely">
<h2>User Settings</h2>
</section>
<section id="settings" class="page hide-completely">
<h1 class="page__title">Settings</h1>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Excepturi nihil distinctio dolore molestias ullam architecto ipsam qui possimus aliquam. Odio.</p>
</section>
</article>
</main>
<script id="helper_functions" src="js/helper.js"></script>
<script src="js/components.js"></script>
<script id="UI_functions">
let allPages = document.querySelectorAll('.page'),
allTabs = document.querySelectorAll('.navbar-item');
function showPage(btn, page) {
allPages.forEach((page) => {
page.classList.add('hide-completely')
})
allTabs.forEach((tab) => {
tab.classList.remove('active')
})
document.getElementById(page).classList.remove('hide-completely')
btn.classList.add('active')
}
let sidebarBtn = document.getElementById('sidebar_btn'),
sidebar = document.getElementById('navbar'),
sidebarExpanded = false;
sidebarBtn.addEventListener('click', e => {
sidebar.classList.add('no-transformations')
sidebarExpanded = true
})
addEventListener('click', e => {
if(sidebarExpanded)
if(!e.target.closest('#navbar') && !e.target.closest('#sidebar_btn')){
sidebar.classList.remove('no-transformations')
sidebarExpanded = false;
}
})
</script>
<script src="js/main_UI.js"></script>
<script src="js/components.min.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,133 +0,0 @@
if (!navigator.onLine)
notify('There seems to be a problem connecting to the internet.', 'error', 'fixed', true)
window.addEventListener('offline', () => {
notify('There seems to be a problem connecting to the internet.', 'error', 'fixed', true)
})
window.addEventListener('online', () => {
notify('We are back online.', '', '', true)
})
let themeToggler = document.getElementById("theme_toggle")
if (localStorage.theme === "dark") {
darkTheme()
themeToggler.checked = true;
} else {
lightTheme()
themeToggler.checked = false;
}
function lightTheme() {
document.body.setAttribute("data-theme", "light");
}
function darkTheme() {
document.body.setAttribute("data-theme", "dark");
}
themeToggler.addEventListener("change", () => {
if (themeToggler.checked) {
darkTheme()
localStorage.setItem("theme", "dark");
} else {
lightTheme()
localStorage.setItem("theme", "light");
}
})
// function required for popups or modals to appear
class Stack {
constructor() {
this.items = [];
}
push(element) {
this.items.push(element);
}
pop() {
if (this.items.length == 0)
return "Underflow";
return this.items.pop();
}
peek(index) {
let newIndex = index ? index : 1
return this.items[this.items.length - index];
}
}
let popupStack = new Stack(),
zIndex = 10;
function showPopup(popup, permission) {
let thisPopup = document.getElementById(popup);
document.body.setAttribute('style', `overflow: hidden; top: -${window.scrollY}px`)
popupStack.push({ thisPopup, permission })
thisPopup.show(permission, popupStack)
zIndex++;
thisPopup.setAttribute('style', `z-index: ${zIndex}`)
return thisPopup;
}
function setAttributes(el, attrs) {
for (var key in attrs) {
el.setAttribute(key, attrs[key]);
}
}
// displays a popup for asking permission. Use this instead of JS confirm
let confirmation = function (message) {
return new Promise(resolve => {
let popup = document.getElementById('confirmation');
showPopup('confirmation')
popup.querySelector('#confirm_message').textContent = message;
popup.querySelector('.submit-btn').onclick = () => {
hidePopup()
resolve(true);
}
popup.querySelector('.cancel-btn').onclick = () => {
hidePopup()
resolve(false);
}
})
}
// displays a popup for asking user input. Use this instead of JS prompt
let askPrompt = function (message, defaultVal) {
return new Promise(resolve => {
let popup = document.getElementById('prompt'),
input = popup.querySelector('input');
if (defaultVal)
input.value = defaultVal;
showPopup('prompt')
input.focus()
input.addEventListener('keyup', e => {
if (e.key === 'Enter') {
resolve(input.value);
hidePopup()
}
})
popup.querySelector('#prompt_message').textContent = message;
popup.querySelector('.submit-btn').onclick = () => {
hidePopup()
resolve(input.value);
}
popup.querySelector('.cancel-btn').onclick = () => {
hidePopup()
resolve(null);
}
})
}
function formatedTime(time) {
let timeFrag = new Date(parseInt(time)).toString().split(' '),
day = timeFrag[0],
month = timeFrag[1],
date = timeFrag[2],
year = timeFrag[3],
hours = timeFrag[4].slice(0, timeFrag[4].lastIndexOf(':')),
finalTime = '';
parseInt(hours.split(':')[0]) > 12 ? finalTime = 'PM' : finalTime = 'AM'
return `${hours} ${finalTime} ${day} ${date} ${month} ${year}`
}
function copyToClipboard(parent) {
let toast = document.getElementById('textCopied'),
textToCopy = parent.querySelector('.copy').textContent;
navigator.clipboard.writeText(textToCopy)
toast.classList.remove('hide');
setTimeout(() => {
toast.classList.add('hide');
}, 2000)
}

View File

@ -0,0 +1,309 @@
// Global variables
const domRefs = {};
const appPages = ['dashboard', 'settings']
//Checks for internet connection status
if (!navigator.onLine)
notify(
"There seems to be a problem connecting to the internet, Please check you internet connection.",
"error",
{ sound: true }
);
window.addEventListener("offline", () => {
notify(
"There seems to be a problem connecting to the internet, Please check you internet connection.",
"error",
{ pinned: true, sound: true }
);
});
window.addEventListener("online", () => {
getRef("notification_drawer").clearAll();
notify("We are back online.", "success");
});
// Use instead of document.getElementById
function getRef(elementId) {
if (!domRefs.hasOwnProperty(elementId)) {
domRefs[elementId] = {
count: 1,
ref: null,
};
return document.getElementById(elementId);
} else {
if (domRefs[elementId].count < 3) {
domRefs[elementId].count = domRefs[elementId].count + 1;
return document.getElementById(elementId);
} else {
if (!domRefs[elementId].ref)
domRefs[elementId].ref = document.getElementById(elementId);
return domRefs[elementId].ref;
}
}
}
// returns dom with specified element
function createElement(tagName, obj) {
const { className, textContent, innerHTML, attributes = {} } = obj
const elem = document.createElement(tagName)
for (let attribute in attributes) {
elem.setAttribute(attribute, attributes[attribute])
}
if (className)
elem.className = className
if (textContent)
elem.textContent = textContent
if (innerHTML)
elem.innerHTML = innerHTML
return elem
}
// Use when a function needs to be executed after user finishes changes
const debounce = (callback, wait) => {
let timeoutId = null;
return (...args) => {
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(() => {
callback.apply(null, args);
}, wait);
};
}
// Limits the rate of function execution
let timerId;
function throttle(func, delay) {
// If setTimeout is already scheduled, no need to do anything
if (timerId) {
return;
}
// Schedule a setTimeout after delay seconds
timerId = setTimeout(function () {
func();
// Once setTimeout function execution is finished, timerId = undefined so that in
// the next scroll event function execution can be scheduled by the setTimeout
timerId = undefined;
}, delay);
}
// function required for popups or modals to appear
class Stack {
constructor() {
this.items = [];
}
push(element) {
this.items.push(element);
}
pop() {
if (this.items.length == 0)
return "Underflow";
return this.items.pop();
}
peek() {
return this.items[this.items.length - 1];
}
}
let popupStack = new Stack(),
zIndex = 10;
async function showPopup(popup, pinned) {
zIndex++
getRef(popup).setAttribute('style', `z-index: ${zIndex}`)
popupStack = getRef(popup).show({ pinned, popupStack })
return getRef(popup);
}
// hides the popup or modal
function hidePopup() {
if (popupStack.peek() === undefined)
return;
popupStack.peek().popup.hide()
}
// displays a popup for asking permission. Use this instead of JS confirm
let getConfirmation = (title, message, cancelText = 'Cancel', confirmText = 'OK') => {
return new Promise(resolve => {
showPopup('confirmation_popup', true)
getRef('confirm_title').textContent = title;
getRef('confirm_message').textContent = message;
let cancelButton = getRef('confirmation_popup').children[2].children[0],
submitButton = getRef('confirmation_popup').children[2].children[1]
submitButton.textContent = confirmText
cancelButton.textContent = cancelText
submitButton.onclick = () => {
hidePopup()
resolve(true);
}
cancelButton.onclick = () => {
hidePopup()
resolve(false);
}
})
}
// displays a popup for asking user input. Use this instead of JS prompt
async function getPromptInput(title, message = '', showText = true, trueBtn = "Ok", falseBtn = "Cancel") {
showPopup('prompt_popup', true)
getRef('prompt_title').textContent = title;
let input = getRef('prompt_input');
input.setAttribute("placeholder", message)
let buttons = getRef('prompt_popup').querySelectorAll("sm-button");
if (showText)
input.setAttribute("type", "text")
else
input.setAttribute("type", "password")
input.focusIn()
buttons[0].textContent = falseBtn;
buttons[1].textContent = trueBtn;
return new Promise((resolve, reject) => {
buttons[0].onclick = () => {
hidePopup()
return;
}
buttons[1].onclick = () => {
let value = input.value;
hidePopup()
resolve(value)
}
})
}
//Function for displaying toast notifications. pass in error for mode param if you want to show an error.
function notify(message, mode, options = {}) {
const { pinned = false, sound } = options
if (mode === "error") console.error(message);
let icon
switch (mode) {
case 'success':
icon = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 15.172l9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z"/></svg>`
break;
case 'error':
icon = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-7v2h2v-2h-2zm0-8v6h2V7h-2z"/></svg>`
break;
}
getRef("notification_drawer").push(message, { pinned, icon });
if (navigator.onLine && sound) {
getRef("notification_sound").currentTime = 0;
getRef("notification_sound").play();
}
}
const currentYear = new Date().getFullYear();
function getFormatedTime(time, relative) {
try {
if (String(time).indexOf("_")) time = String(time).split("_")[0];
const intTime = parseInt(time);
if (String(intTime).length < 13) time *= 1000;
let timeFrag = new Date(intTime).toString().split(" "),
day = timeFrag[0],
month = timeFrag[1],
date = timeFrag[2],
year = timeFrag[3],
minutes = new Date(intTime).getMinutes(),
hours = new Date(intTime).getHours(),
currentTime = new Date().toString().split(" ");
minutes = minutes < 10 ? `0${minutes}` : minutes;
let finalHours = ``;
if (hours > 12) finalHours = `${hours - 12}:${minutes}`;
else if (hours === 0) finalHours = `12:${minutes}`;
else finalHours = `${hours}:${minutes}`;
finalHours = hours >= 12 ? `${finalHours} PM` : `${finalHours} AM`;
if (relative) {
return `${date} ${month} ${year}`;
} else return `${finalHours} ${month} ${date} ${year}`;
} catch (e) {
console.error(e);
return time;
}
}
window.addEventListener('hashchange', e => showPage(window.location.hash))
window.addEventListener("load", () => {
document.body.classList.remove('hide-completely')
showPage(window.location.hash)
// document.querySelectorAll('sm-input[data-flo-id]').forEach(input => input.customValidation = validateAddr)
document.addEventListener('keyup', (e) => {
if (e.code === 'Escape') {
hidePopup()
}
})
document.addEventListener("pointerdown", (e) => {
if (e.target.closest("button, sm-button:not([disabled]), .interact")) {
createRipple(e, e.target.closest("button, sm-button, .interact"));
}
});
document.addEventListener('copy', () => {
notify('copied', 'success')
})
});
function createRipple(event, target) {
const circle = document.createElement("span");
const diameter = Math.max(target.clientWidth, target.clientHeight);
const radius = diameter / 2;
const targetDimensions = target.getBoundingClientRect();
circle.style.width = circle.style.height = `${diameter}px`;
circle.style.left = `${event.clientX - (targetDimensions.left + radius)}px`;
circle.style.top = `${event.clientY - (targetDimensions.top + radius)}px`;
circle.classList.add("ripple");
const rippleAnimation = circle.animate(
[
{
transform: "scale(3)",
opacity: 0,
},
],
{
duration: 1000,
fill: "forwards",
easing: "ease-out",
}
);
target.append(circle);
rippleAnimation.onfinish = () => {
circle.remove();
};
}
function showPage(targetPage, options = {}) {
const { firstLoad, hashChange } = options
let pageId
if (targetPage === '') {
pageId = 'overview_page'
}
else {
pageId = targetPage.includes('#') ? targetPage.split('#')[1] : targetPage
}
if(!appPages.includes(pageId)) return
document.querySelector('.page:not(.hide-completely)').classList.add('hide-completely')
document.querySelector('.list__item--active').classList.remove('list__item--active')
getRef(pageId).classList.remove('hide-completely')
getRef(pageId).animate([
{
opacity: 0,
transform: 'translateX(-1rem)'
},
{
opacity: 1,
transform: 'none'
},
],
{
duration: 300,
easing: 'ease'
})
const targetListItem = document.querySelector(`.list__item[href="#${pageId}"]`)
targetListItem.classList.add('list__item--active')
if (firstLoad && window.innerWidth > 640 && targetListItem.getBoundingClientRect().top > getRef('side_nav').getBoundingClientRect().height) {
getRef('side_nav').scrollTo({
top: (targetListItem.getBoundingClientRect().top - getRef('side_nav').getBoundingClientRect().top + getRef('side_nav').scrollTop),
behavior: 'smooth'
})
}
if (hashChange && window.innerWidth < 640) {
getRef('side_nav').close()
}
}

View File

@ -1,61 +1,88 @@
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@500;600;700&family=Roboto:wght@400;500;700&display=swap");
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
margin: 0;
font-family: 'Roboto', sans-serif;
box-sizing: border-box;
font-family: "Roboto", sans-serif;
}
:root {
font-size: clamp(1rem, 1.2vmax, 3rem);
}
html, body {
height: 100%;
scroll-behavior: smooth;
}
body {
--accent-color: #303F9F;
--text-color: 17, 17, 17;
--foreground-color: 255, 255, 255;
background: rgba(var(--foreground-color), 1);
color: rgba(var(--text-color), 1);
font-size: 16px;
background: rgba(var(--background-color), 1);
}
body,
body * {
--accent-color: #0D7377;
--text-color: 17, 17, 17;
--background-color: 255, 255, 255;
--danger-color: red;
}
body[data-theme="dark"] {
--accent-color: #6a7dff;
--foreground-color: 20, 20, 20;
--text-color: 238, 238, 238;
}
h1, h2, h3, h4, h5 {
font-family: 'Poppins', sans-serif;
text-transform: capitalize;
}
h1 {
font-size: 3rem;
}
h2 {
font-size: 2rem;
}
h3 {
font-size: 1.5rem;
}
h4 {
font-size: 1rem;
}
h5 {
font-size: 0.8rem;
body[data-theme=dark],
body[data-theme=dark] * {
--accent-color: #32E0C4;
--text-color: 240, 240, 240;
--text-color-light: 170, 170, 170;
--background-color: 10, 10, 10;
--danger-color: rgb(255, 106, 106);
}
p {
margin: 1.5rem 0;
font-size: 0.8;
max-width: 65ch;
line-height: 1.7;
margin-bottom: 1.5rem;
color: rgba(var(--text-color), 0.8);
}
p:not(:last-of-type) {
margin-bottom: 1rem;
}
img {
object-fit: cover;
}
a {
color: inherit;
text-decoration: none;
}
a:focus-visible {
box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset;
}
button {
display: inline-flex;
border: none;
background-color: inherit;
}
a:any-link:focus-visible {
outline: rgba(var(--text-color), 1) 0.1rem solid;
}
sm-button {
--border-radius: 0.3rem;
}
ul {
list-style: none;
}
.flex {
display: flex;
}
.grid {
display: grid;
}
.hide {
opacity: 0;
@ -66,124 +93,258 @@ p {
display: none !important;
}
.icon {
height: 1.2rem;
width: 1.2rem;
fill: none;
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
.no-transformations {
transform: none !important;
}
.toggle {
position: relative;
cursor: pointer;
z-index: 1;
padding: 0;
}
.toggle input[type='checkbox'] {
display: none;
}
.toggle .switch {
overflow: hidden;
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
justify-items: center;
padding: 0.2rem;
min-height: 1.6rem;
max-height: 1.6rem;
border-radius: 0.5rem;
position: relative;
margin: 0;
}
.toggle .circle {
border-radius: 0.5rem;
-webkit-transition: -webkit-transform 0.3s;
transition: -webkit-transform 0.3s;
transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
fill: rgba(var(--text-color), 0.8);
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
height: 1.2rem;
width: 1.2rem;
}
.toggle .circle:first-of-type {
margin-bottom: 0.4rem;
}
.toggle .circle line {
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
}
.toggle input:checked ~ .switch .circle {
-webkit-transform: translateY(-1.7rem);
transform: translateY(-1.7rem);
}
sm-tabs {
margin-bottom: 2rem;
}
sm-tabs::part(tab-header) {
border-bottom: solid 1px rgba(var(--text-color), 0.2);
padding: 0 1.5rem;
margin-bottom: 2rem;
}
sm-tabs::part(panel-container) {
padding: 0 1.5rem;
}
#navbar {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
padding: 1.5rem 2rem;
background: rgba(var(--foreground-color), 1);
z-index: 3;
}
#logo {
display: -ms-grid;
display: grid;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
.overflow-ellipsis {
width: 100%;
-ms-grid-columns: auto 1fr;
grid-template-columns: auto 1fr;
gap: 0.6rem 0.6rem;
margin-right: 1rem;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
#logo h4 {
.breakable {
overflow-wrap: break-word;
word-wrap: break-word;
-ms-word-break: break-all;
word-break: break-word;
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
.full-bleed {
grid-column: 1/4;
}
.h1 {
font-size: 2.5rem;
}
.h2 {
font-size: 2rem;
}
.h3 {
font-size: 1.4rem;
}
.h4 {
font-size: 1rem;
}
.h5 {
font-size: 0.8rem;
}
.uppercase {
text-transform: uppercase;
}
.capitalize {
text-transform: capitalize;
font-size: 1.2rem;
font-weight: 600;
}
#logo h5 {
font-family: 'Roboto', sans-serif;
.flex {
display: flex;
}
.grid {
display: grid;
}
.grid-3 {
grid-template-columns: 1fr auto auto;
}
.flow-column {
grid-auto-flow: column;
}
.gap-0-5 {
gap: 0.5rem;
}
.gap-1 {
gap: 1rem;
}
.gap-1-5 {
gap: 1.5rem;
}
.gap-2 {
gap: 2rem;
}
.gap-3 {
gap: 3rem;
}
.text-align-right {
text-align: right;
}
.align-start {
align-items: flex-start;
}
.align-center {
align-items: center;
}
.text-center {
text-align: center;
}
.justify-start {
justify-content: start;
}
.justify-center {
justify-content: center;
}
.justify-right {
margin-left: auto;
}
.align-self-center {
align-self: center;
}
.justify-self-center {
justify-self: center;
}
.justify-self-start {
justify-self: start;
}
.justify-self-end {
justify-self: end;
}
.direction-column {
flex-direction: column;
}
.space-between {
justify-content: space-between;
}
.w-100 {
width: 100%;
}
.color-0-8 {
color: rgba(var(--text-color), 0.8);
}
.weight-400 {
font-weight: 400;
}
.weight-500 {
font-weight: 500;
}
.ripple {
position: absolute;
border-radius: 50%;
transform: scale(0);
background: rgba(var(--text-color), 0.16);
pointer-events: none;
}
.interact {
position: relative;
overflow: hidden;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
.observe-empty-state:empty {
display: none;
}
.observe-empty-state:not(:empty) ~ .empty-state {
display: none;
}
.icon {
width: 1.5rem;
height: 1.5rem;
fill: rgba(var(--text-color), 0.9);
}
.button__icon {
height: 1.2rem;
width: 1.2rem;
}
.button__icon--left {
margin-right: 0.5rem;
}
.button__icon--right {
margin-left: 0.5rem;
}
#confirmation_popup,
#prompt_popup {
flex-direction: column;
}
#confirmation_popup h4,
#prompt_popup h4 {
font-weight: 500;
margin-bottom: 0.5rem;
}
#confirmation_popup sm-button,
#prompt_popup sm-button {
margin: 0;
}
#confirmation_popup .flex,
#prompt_popup .flex {
padding: 0;
margin-top: 1rem;
}
#confirmation_popup .flex sm-button:first-of-type,
#prompt_popup .flex sm-button:first-of-type {
margin-right: 0.6rem;
margin-left: auto;
}
#main_header {
display: flex;
gap: 1rem;
align-items: center;
position: sticky;
padding: 1rem 1.5rem;
background: rgba(var(--background-color), 1);
border-bottom: solid 1px rgba(var(--text-color), 0.16);
z-index: 2;
}
#logo {
display: grid;
align-items: center;
width: 100%;
grid-template-columns: auto 1fr;
gap: 0 0.5rem;
margin-right: 1rem;
}
#logo h4 {
text-transform: capitalize;
font-size: 1rem;
font-weight: 600;
margin-top: 0.2rem;
}
#logo h5 {
font-size: 0.8rem;
font-family: "Roboto", sans-serif;
font-weight: 400;
}
#logo #main_logo {
height: 1.4rem;
width: 1.4rem;
@ -191,43 +352,46 @@ sm-tabs::part(panel-container) {
stroke: none;
}
sm-tab-header {
padding: 0 1.5rem;
background-color: rgba(var(--text-color), 0.06);
}
sm-tab {
padding: 0.5rem 0.8rem;
}
.section {
display: flex;
flex-direction: column;
margin-top: 3rem;
padding: 0 1.5rem;
}
.section h3 + p {
margin-top: 1rem;
}
.section:first-of-type {
margin-top: 0;
}
.card {
padding: 1.5rem;
display: -webkit-box;
display: -ms-flexbox;
.section__header {
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
width: 20rem;
border-radius: 0.5rem;
margin-right: 1.5rem;
border: solid 1px rgba(var(--text-color), 0.2);
padding: 1rem 0;
justify-content: space-between;
}
.card {
padding: 1.5rem;
display: flex;
flex-direction: column;
min-width: 20rem;
border-radius: 0.5rem;
margin-right: 1.5rem;
background-color: rgba(var(--text-color), 0.06);
}
.card h3 {
font-weight: 500;
}
@media only screen and (min-width: 640px) {
sm-tabs::part(tab-header), sm-tabs::part(panel-container) {
padding: 0 4vw;
@media screen and (min-width: 640px) {
sm-popup {
--width: 24rem;
}
p {
max-width: 40rem;
}
}
/*# sourceMappingURL=main.css.map */
}

1
Layouts/tabs layout/css/main.min.css vendored Normal file
View File

@ -0,0 +1 @@
#logo h5,*{font-family:Roboto,sans-serif}*{padding:0;margin:0;box-sizing:border-box}:root{font-size:clamp(1rem,1.2vmax,3rem)}body,html{height:100%;scroll-behavior:smooth}body{color:rgba(var(--text-color),1);background:rgba(var(--background-color),1)}body,body *{--accent-color:#0D7377;--text-color:17,17,17;--background-color:255,255,255;--danger-color:red}body[data-theme=dark],body[data-theme=dark] *{--accent-color:#32E0C4;--text-color:240,240,240;--text-color-light:170,170,170;--background-color:10,10,10;--danger-color:rgb(255, 106, 106)}p{font-size:.8;max-width:65ch;line-height:1.7;margin-bottom:1.5rem;color:rgba(var(--text-color),.8)}p:not(:last-of-type){margin-bottom:1rem}img{object-fit:cover}a{color:inherit;text-decoration:none}a:focus-visible{box-shadow:0 0 0 .1rem rgba(var(--text-color),1) inset}button{display:inline-flex;border:none;background-color:inherit}a:any-link:focus-visible{outline:solid rgba(var(--text-color),1)}sm-button{--border-radius:0.3rem}ul{list-style:none}.hide{opacity:0;pointer-events:none}.hide-completely{display:none!important}#main_header,.flex{display:flex}.no-transformations{transform:none!important}.overflow-ellipsis{width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.breakable{overflow-wrap:break-word;word-wrap:break-word;-ms-word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.full-bleed{grid-column:1/4}.h1{font-size:2.5rem}.h2{font-size:2rem}.h3{font-size:1.4rem}.h4{font-size:1rem}.h5{font-size:.8rem}.uppercase{text-transform:uppercase}#logo h4,.capitalize{text-transform:capitalize}.grid{display:grid}.grid-3{grid-template-columns:1fr auto auto}.flow-column{grid-auto-flow:column}.gap-0-5{gap:.5rem}.gap-1{gap:1rem}.gap-1-5{gap:1.5rem}.gap-2{gap:2rem}.gap-3{gap:3rem}.text-align-right{text-align:right}.align-start{align-items:flex-start}#main_header,.align-center{align-items:center}.text-center{text-align:center}.justify-start{justify-content:start}.justify-center{justify-content:center}.justify-right{margin-left:auto}.align-self-center{align-self:center}.justify-self-center{justify-self:center}.justify-self-start{justify-self:start}.justify-self-end{justify-self:end}.direction-column{flex-direction:column}.space-between{justify-content:space-between}.w-100{width:100%}.color-0-8{color:rgba(var(--text-color),.8)}.weight-400{font-weight:400}.weight-500{font-weight:500}.ripple{position:absolute;border-radius:50%;transform:scale(0);background:rgba(var(--text-color),.16);pointer-events:none}.interact{position:relative;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:transparent}.observe-empty-state:empty{display:none}.observe-empty-state:not(:empty)~.empty-state{display:none}.icon{width:1.5rem;height:1.5rem;fill:rgba(var(--text-color),.9)}.button__icon{height:1.2rem;width:1.2rem}.button__icon--left{margin-right:.5rem}.button__icon--right{margin-left:.5rem}#confirmation_popup,#prompt_popup{flex-direction:column}#confirmation_popup h4,#prompt_popup h4{font-weight:500;margin-bottom:.5rem}#confirmation_popup sm-button,#prompt_popup sm-button{margin:0}#confirmation_popup .flex,#prompt_popup .flex{padding:0;margin-top:1rem}#confirmation_popup .flex sm-button:first-of-type,#prompt_popup .flex sm-button:first-of-type{margin-right:.6rem;margin-left:auto}#main_header{gap:1rem;position:sticky;padding:1rem 1.5rem;background:rgba(var(--background-color),1);border-bottom:solid 1px rgba(var(--text-color),.16);z-index:2}#logo{display:grid;align-items:center;width:100%;grid-template-columns:auto 1fr;gap:0 .5rem;margin-right:1rem}#logo h4{font-size:1rem;font-weight:600;margin-top:.2rem}#logo h5{font-size:.8rem;font-weight:400}#logo #main_logo{height:1.4rem;width:1.4rem;fill:rgba(var(--text-color),1);stroke:none}sm-tab-header{padding:0 1.5rem;background-color:rgba(var(--text-color),.06)}sm-tab{padding:.5rem .8rem}.section{display:flex;flex-direction:column;margin-top:3rem;padding:0 1.5rem}.section:first-of-type{margin-top:0}.section__header{display:flex;padding:1rem 0;justify-content:space-between}.card{padding:1.5rem;display:flex;flex-direction:column;min-width:20rem;border-radius:.5rem;margin-right:1.5rem;background-color:rgba(var(--text-color),.06)}.card h3{font-weight:500}@media screen and (min-width:640px){sm-popup{--width:24rem}}

View File

@ -1,49 +1,79 @@
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@500;600;700&family=Roboto:wght@400;500;700&display=swap');
*{
box-sizing: border-box;
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: 'Roboto', sans-serif;
}
:root{
font-size: clamp(1rem, 1.2vmax, 3rem);
}
html, body{
height: 100%;
scroll-behavior: smooth;
}
body{
--accent-color: #303F9F;
--text-color: 17, 17, 17;
--foreground-color: 255, 255, 255;
background: rgba(var(--foreground-color), 1);
body {
&,
*{
--accent-color: #0D7377;
--text-color: 17, 17, 17;
--background-color: 255, 255, 255;
--danger-color: red;
}
color: rgba(var(--text-color), 1);
font-size: 16px;
background: rgba(var(--background-color), 1);
}
body[data-theme="dark"]{
--accent-color: #6a7dff;
--foreground-color: 20, 20, 20;
--text-color: 238, 238, 238;
body[data-theme='dark']{
&,
*{
--accent-color: #32E0C4;
--text-color: 240, 240, 240;
--text-color-light: 170, 170, 170;
--background-color: 10, 10, 10;
--danger-color: rgb(255, 106, 106);
}
}
h1, h2, h3, h4, h5{
font-family: 'Poppins', sans-serif;
text-transform: capitalize;
}
h1{
font-size: 3rem;
}
h2{
font-size: 2rem;
}
h3{
font-size: 1.5rem;
}
h4{
font-size: 1rem;
}
h5{
font-size: 0.8rem;
}
p{
margin: 1.5rem 0;
p {
font-size: 0.8;
max-width: 65ch;
line-height: 1.7;
margin-bottom: 1.5rem;
color: rgba(var(--text-color), 0.8);
&:not(:last-of-type){
margin-bottom: 1rem;
}
}
img{
object-fit: cover;
}
a{
color: inherit;
text-decoration: none;
&:focus-visible{
box-shadow: 0 0 0 0.1rem rgba(var(--text-color), 1) inset;
}
}
button{
display: inline-flex;
border: none;
background-color: inherit;
}
a:any-link:focus-visible{
outline: rgba(var(--text-color), 1) 0.1rem solid;
}
sm-button{
--border-radius: 0.3rem;
}
ul{
list-style: none;
}
.flex{
display: flex;
}
.grid{
display: grid;
}
.hide{
opacity: 0;
@ -52,88 +82,206 @@ p{
.hide-completely{
display: none !important;
}
.no-transformations{
transform: none !important;
}
.overflow-ellipsis{
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.breakable{
overflow-wrap: break-word;
word-wrap: break-word;
-ms-word-break: break-all;
word-break: break-word;
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
.full-bleed{
grid-column: 1/4;
}
.h1{
font-size: 2.5rem;
}
.h2{
font-size: 2rem;
}
.h3{
font-size: 1.4rem;
}
.h4{
font-size: 1rem;
}
.h5{
font-size: 0.8rem;
}
.uppercase{
text-transform: uppercase;
}
.capitalize{
text-transform: capitalize;
}
.flex{
display: flex;
}
.grid{
display: grid;
}
.grid-3{
grid-template-columns: 1fr auto auto;
}
.flow-column{
grid-auto-flow: column;
}
.gap-0-5{
gap: 0.5rem;
}
.gap-1{
gap: 1rem;
}
.gap-1-5{
gap: 1.5rem;
}
.gap-2{
gap: 2rem;
}
.gap-3{
gap: 3rem;
}
.text-align-right{
text-align: right;
}
.align-start{
align-items: flex-start;
}
.align-center{
align-items: center;
}
.text-center{
text-align: center;
}
.justify-start{
justify-content: start;
}
.justify-center{
justify-content: center;
}
.justify-right{
margin-left: auto;
}
.align-self-center{
align-self: center;
}
.justify-self-center{
justify-self: center;
}
.justify-self-start{
justify-self: start;
}
.justify-self-end{
justify-self: end;
}
.direction-column{
flex-direction: column;
}
.space-between{
justify-content: space-between;
}
.w-100{
width: 100%;
}
.color-0-8{
color: rgba(var(--text-color), 0.8);
}
.weight-400{
font-weight: 400;
}
.weight-500{
font-weight: 500;
}
.ripple{
position: absolute;
border-radius: 50%;
transform: scale(0);
background: rgba(var(--text-color), 0.16);
pointer-events: none;
}
.interact{
position: relative;
overflow: hidden;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
.observe-empty-state:empty{
display: none;
}
.observe-empty-state:not(:empty) ~ .empty-state{
display: none;
}
.icon{
width: 1.5rem;
height: 1.5rem;
fill: rgba(var(--text-color), 0.9);
}
.button__icon{
height: 1.2rem;
width: 1.2rem;
fill: none;
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
}
.toggle{
position: relative;
cursor: pointer;
z-index: 1;
padding: 0;
input[type='checkbox']{
display: none;
&--left{
margin-right: 0.5rem;
}
.switch{
overflow: hidden;
display: inline-flex;
flex-direction: column;
justify-items: center;
padding: 0.2rem;
min-height: 1.6rem;
max-height: 1.6rem;
border-radius: 0.5rem;
position: relative;
&--right{
margin-left: 0.5rem;
}
}
#confirmation_popup,
#prompt_popup {
flex-direction: column;
h4 {
font-weight: 500;
margin-bottom: 0.5rem;
}
sm-button{
margin: 0;
}
.circle{
border-radius: 0.5rem;
transition: transform 0.3s;
&:first-of-type{
margin-bottom: 0.4rem;
}
fill: rgba(var(--text-color), 0.8);
overflow: visible;
stroke-linecap: round;
stroke-linejoin: round;
height: 1.2rem;
width: 1.2rem;
line{
stroke: rgba(var(--text-color), 0.8);
stroke-width: 6;
.flex {
padding: 0;
margin-top: 1rem;
sm-button:first-of-type {
margin-right: 0.6rem;
margin-left: auto;
}
}
input:checked ~ .switch .circle{
transform: translateY(-1.7rem);
}
}
sm-tabs{
margin-bottom: 2rem;
&::part(tab-header){
border-bottom: solid 1px rgba(var(--text-color), 0.2);
padding: 0 1.5rem;
margin-bottom: 2rem;
}
&::part(panel-container){
padding: 0 1.5rem;
}
}
#navbar{
#main_header{
display: flex;
gap: 1rem;
align-items: center;
padding: 1.5rem 2rem;
background: rgba(var(--foreground-color), 1);
z-index: 3;
position: sticky;
padding: 1rem 1.5rem;
background: rgba(var(--background-color), 1);
border-bottom: solid 1px rgba(var(--text-color), 0.16);
z-index: 2;
}
#logo{
display: grid;
align-items: center;
width: 100%;
grid-template-columns: auto 1fr;
gap: 0.6rem 0.6rem;
gap: 0 0.5rem;
margin-right: 1rem;
h4{
text-transform: capitalize;
font-size: 1.2rem;
font-size: 1rem;
font-weight: 600;
margin-top: 0.2rem;
}
h5{
font-size: 0.8rem;
font-family: 'Roboto', sans-serif;
font-weight: 400;
}
@ -144,35 +292,43 @@ sm-tabs{
stroke: none;
}
}
sm-tab-header{
padding: 0 1.5rem;
background-color: rgba(var(--text-color), 0.06);
}
sm-tab{
padding: 0.5rem 0.8rem;
}
.section{
display: flex;
flex-direction: column;
margin-top: 3rem;
h3 + p{
margin-top: 1rem;
}
padding: 0 1.5rem;
&:first-of-type{
margin-top: 0;
}
}
.section__header{
display: flex;
padding: 1rem 0;
justify-content: space-between;
}
.card{
padding: 1.5rem;
display: flex;
flex-direction: column;
width: 20rem;
min-width: 20rem;
border-radius: 0.5rem;
margin-right: 1.5rem;
border: solid 1px rgba(var(--text-color), 0.2);
background-color: rgba(var(--text-color), 0.06);
h3{
font-weight: 500;
}
}
@media only screen and (min-width: 640px){
sm-tabs{
&::part(tab-header),
&::part(panel-container){
padding: 0 4vw;
}
}
p{
max-width: 40rem;
@media screen and (min-width: 640px) {
// for tablet and desktop
sm-popup{
--width: 24rem;
}
}

View File

@ -6,200 +6,143 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="css/main.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;700&family=Roboto+Mono&family=Roboto:wght@400;500;700&display=swap"
rel="stylesheet">
</head>
<body data-theme="light">
<nav id="navbar">
<div id="logo">
<svg id="main_logo" viewBox="0 0 27.25 32">
<title>RanchiMall</title>
<path
d="M27.14,30.86c-.74-2.48-3-4.36-8.25-6.94a20,20,0,0,1-4.2-2.49,6,6,0,0,1-1.25-1.67,4,4,0,0,1,0-2.26c.37-1.08.79-1.57,3.89-4.55a11.66,11.66,0,0,0,3.34-4.67,6.54,6.54,0,0,0,.05-2.82C20,3.6,18.58,2,16.16.49c-.89-.56-1.29-.64-1.3-.24a3,3,0,0,1-.3.72l-.3.55L13.42.94C13,.62,12.4.26,12.19.15c-.4-.2-.73-.18-.72.05a9.39,9.39,0,0,1-.61,1.33s-.14,0-.27-.13C8.76.09,8-.27,8,.23A11.73,11.73,0,0,1,6.76,2.6C4.81,5.87,2.83,7.49.77,7.49c-.89,0-.88,0-.61,1,.22.85.33.92,1.09.69A5.29,5.29,0,0,0,3,8.33c.23-.17.45-.29.49-.26a2,2,0,0,1,.22.63A1.31,1.31,0,0,0,4,9.34a5.62,5.62,0,0,0,2.27-.87L7,8l.13.55c.19.74.32.82,1,.65a7.06,7.06,0,0,0,3.46-2.47l.6-.71-.06.64c-.17,1.63-1.3,3.42-3.39,5.42L6.73,14c-3.21,3.06-3,5.59.6,8a46.77,46.77,0,0,0,4.6,2.41c.28.13,1,.52,1.59.87,3.31,2,4.95,3.92,4.95,5.93a2.49,2.49,0,0,0,.07.77h0c.09.09,0,.1.9-.14a2.61,2.61,0,0,0,.83-.32,3.69,3.69,0,0,0-.55-1.83A11.14,11.14,0,0,0,17,26.81a35.7,35.7,0,0,0-5.1-2.91C9.37,22.64,8.38,22,7.52,21.17a3.53,3.53,0,0,1-1.18-2.48c0-1.38.71-2.58,2.5-4.23,2.84-2.6,3.92-3.91,4.67-5.65a3.64,3.64,0,0,0,.42-2A3.37,3.37,0,0,0,13.61,5l-.32-.74.29-.48c.17-.27.37-.63.46-.8l.15-.3.44.64a5.92,5.92,0,0,1,1,2.81,5.86,5.86,0,0,1-.42,1.94c0,.12-.12.3-.15.4a9.49,9.49,0,0,1-.67,1.1,28,28,0,0,1-4,4.29C8.62,15.49,8.05,16.44,8,17.78a3.28,3.28,0,0,0,1.11,2.76c.95,1,2.07,1.74,5.25,3.32,3.64,1.82,5.22,2.9,6.41,4.38A4.78,4.78,0,0,1,21.94,31a3.21,3.21,0,0,0,.14.92,1.06,1.06,0,0,0,.43-.05l.83-.22.46-.12-.06-.46c-.21-1.53-1.62-3.25-3.94-4.8a37.57,37.57,0,0,0-5.22-2.82A13.36,13.36,0,0,1,11,21.19a3.36,3.36,0,0,1-.8-4.19c.41-.85.83-1.31,3.77-4.15,2.39-2.31,3.43-4.13,3.43-6a5.85,5.85,0,0,0-2.08-4.29c-.23-.21-.44-.43-.65-.65A2.5,2.5,0,0,1,15.27.69a10.6,10.6,0,0,1,2.91,2.78A4.16,4.16,0,0,1,19,6.16a4.91,4.91,0,0,1-.87,3c-.71,1.22-1.26,1.82-4.27,4.67a9.47,9.47,0,0,0-2.07,2.6,2.76,2.76,0,0,0-.33,1.54,2.76,2.76,0,0,0,.29,1.47c.57,1.21,2.23,2.55,4.65,3.73a32.41,32.41,0,0,1,5.82,3.24c2.16,1.6,3.2,3.16,3.2,4.8a1.94,1.94,0,0,0,.09.76,4.54,4.54,0,0,0,1.66-.4C27.29,31.42,27.29,31.37,27.14,30.86ZM6.1,7h0a3.77,3.77,0,0,1-1.46.45L4,7.51l.68-.83a25.09,25.09,0,0,0,3-4.82A12,12,0,0,1,8.28.76c.11-.12.77.32,1.53,1l.63.58-.57.84A10.34,10.34,0,0,1,6.1,7Zm5.71-1.78A9.77,9.77,0,0,1,9.24,7.18h0a5.25,5.25,0,0,1-1.17.28l-.58,0,.65-.78a21.29,21.29,0,0,0,2.1-3.12c.22-.41.42-.76.44-.79s.5.43.9,1.24L12,5ZM13.41,3a2.84,2.84,0,0,1-.45.64,11,11,0,0,1-.9-.91l-.84-.9.19-.45c.34-.79.39-.8,1-.31A9.4,9.4,0,0,1,13.8,2.33q-.18.34-.39.69Z" />
</svg>
<span>
<h5>RanchiMall</h5>
<h4>App name</h4>
</span>
<body data-theme="light" class="hide-completely">
<sm-notifications id="notification_drawer"></sm-notifications>
<audio id="notification_sound">
<source src="https://rmservices.duckdns.org/files/notification-sound.mp3" type="audio/mpeg">
<source src="https://rmservices.duckdns.org/files/notification-sound.ogg" type="audio/ogg">
</audio>
<sm-popup id="confirmation_popup">
<h4 id="confirm_title"></h4>
<p id="confirm_message"></p>
<div class="flex align-center">
<sm-button variant="no-outline" class="cancel-btn">Cancel</sm-button>
<sm-button variant="no-outline" class="submit-btn">OK</button>
</div>
<label class="toggle" title="Change theme">
<input type="checkbox" name="theme toggle" id="theme_toggle">
<div class="switch">
<svg class="circle" viewBox="0 0 64 64">
<title>dark theme</title>
</sm-popup>
<sm-popup id="prompt_popup">
<h4 id="prompt_title"></h4>
<p id="prompt_message"></p>
<sm-input id="prompt_input"></sm-input>
<div class="flex align-center">
<sm-button variant="no-outline" class="cancel-btn">Cancel</sm-button>
<sm-button variant="no-outline" class="submit-btn" type="submit">OK</button>
</div>
</sm-popup>
<article id="home" class="page">
<header id="main_header" class="full-bleed">
<div id="logo">
<svg id="main_logo" viewBox="0 0 27.25 32">
<title>RanchiMall</title>
<path
d="M48.25,45.45A27.26,27.26,0,0,1,20.82,18.37,26.75,26.75,0,0,1,27.47.71a31.71,31.71,0,0,0-27,31.2,31.8,31.8,0,0,0,32,31.59A32,32,0,0,0,63.12,41.12,27.59,27.59,0,0,1,48.25,45.45Z"
transform="translate(0 0)" />
</svg>
<svg class="circle" viewBox="0 0 64 64">
<title>light theme</title>
<circle cx="32" cy="32" r="13.9" />
<line x1="32" y1="6.86" x2="32" />
<line x1="32" y1="64" x2="32" y2="57.14" />
<line x1="57.14" y1="32" x2="64" y2="32" />
<line y1="32" x2="6.86" y2="32" />
<line x1="49.78" y1="14.22" x2="54.63" y2="9.37" />
<line x1="9.37" y1="54.63" x2="14.22" y2="49.78" />
<line x1="49.78" y1="49.78" x2="54.63" y2="54.63" />
<line x1="9.37" y1="9.37" x2="14.22" y2="14.22" />
d="M27.14,30.86c-.74-2.48-3-4.36-8.25-6.94a20,20,0,0,1-4.2-2.49,6,6,0,0,1-1.25-1.67,4,4,0,0,1,0-2.26c.37-1.08.79-1.57,3.89-4.55a11.66,11.66,0,0,0,3.34-4.67,6.54,6.54,0,0,0,.05-2.82C20,3.6,18.58,2,16.16.49c-.89-.56-1.29-.64-1.3-.24a3,3,0,0,1-.3.72l-.3.55L13.42.94C13,.62,12.4.26,12.19.15c-.4-.2-.73-.18-.72.05a9.39,9.39,0,0,1-.61,1.33s-.14,0-.27-.13C8.76.09,8-.27,8,.23A11.73,11.73,0,0,1,6.76,2.6C4.81,5.87,2.83,7.49.77,7.49c-.89,0-.88,0-.61,1,.22.85.33.92,1.09.69A5.29,5.29,0,0,0,3,8.33c.23-.17.45-.29.49-.26a2,2,0,0,1,.22.63A1.31,1.31,0,0,0,4,9.34a5.62,5.62,0,0,0,2.27-.87L7,8l.13.55c.19.74.32.82,1,.65a7.06,7.06,0,0,0,3.46-2.47l.6-.71-.06.64c-.17,1.63-1.3,3.42-3.39,5.42L6.73,14c-3.21,3.06-3,5.59.6,8a46.77,46.77,0,0,0,4.6,2.41c.28.13,1,.52,1.59.87,3.31,2,4.95,3.92,4.95,5.93a2.49,2.49,0,0,0,.07.77h0c.09.09,0,.1.9-.14a2.61,2.61,0,0,0,.83-.32,3.69,3.69,0,0,0-.55-1.83A11.14,11.14,0,0,0,17,26.81a35.7,35.7,0,0,0-5.1-2.91C9.37,22.64,8.38,22,7.52,21.17a3.53,3.53,0,0,1-1.18-2.48c0-1.38.71-2.58,2.5-4.23,2.84-2.6,3.92-3.91,4.67-5.65a3.64,3.64,0,0,0,.42-2A3.37,3.37,0,0,0,13.61,5l-.32-.74.29-.48c.17-.27.37-.63.46-.8l.15-.3.44.64a5.92,5.92,0,0,1,1,2.81,5.86,5.86,0,0,1-.42,1.94c0,.12-.12.3-.15.4a9.49,9.49,0,0,1-.67,1.1,28,28,0,0,1-4,4.29C8.62,15.49,8.05,16.44,8,17.78a3.28,3.28,0,0,0,1.11,2.76c.95,1,2.07,1.74,5.25,3.32,3.64,1.82,5.22,2.9,6.41,4.38A4.78,4.78,0,0,1,21.94,31a3.21,3.21,0,0,0,.14.92,1.06,1.06,0,0,0,.43-.05l.83-.22.46-.12-.06-.46c-.21-1.53-1.62-3.25-3.94-4.8a37.57,37.57,0,0,0-5.22-2.82A13.36,13.36,0,0,1,11,21.19a3.36,3.36,0,0,1-.8-4.19c.41-.85.83-1.31,3.77-4.15,2.39-2.31,3.43-4.13,3.43-6a5.85,5.85,0,0,0-2.08-4.29c-.23-.21-.44-.43-.65-.65A2.5,2.5,0,0,1,15.27.69a10.6,10.6,0,0,1,2.91,2.78A4.16,4.16,0,0,1,19,6.16a4.91,4.91,0,0,1-.87,3c-.71,1.22-1.26,1.82-4.27,4.67a9.47,9.47,0,0,0-2.07,2.6,2.76,2.76,0,0,0-.33,1.54,2.76,2.76,0,0,0,.29,1.47c.57,1.21,2.23,2.55,4.65,3.73a32.41,32.41,0,0,1,5.82,3.24c2.16,1.6,3.2,3.16,3.2,4.8a1.94,1.94,0,0,0,.09.76,4.54,4.54,0,0,0,1.66-.4C27.29,31.42,27.29,31.37,27.14,30.86ZM6.1,7h0a3.77,3.77,0,0,1-1.46.45L4,7.51l.68-.83a25.09,25.09,0,0,0,3-4.82A12,12,0,0,1,8.28.76c.11-.12.77.32,1.53,1l.63.58-.57.84A10.34,10.34,0,0,1,6.1,7Zm5.71-1.78A9.77,9.77,0,0,1,9.24,7.18h0a5.25,5.25,0,0,1-1.17.28l-.58,0,.65-.78a21.29,21.29,0,0,0,2.1-3.12c.22-.41.42-.76.44-.79s.5.43.9,1.24L12,5ZM13.41,3a2.84,2.84,0,0,1-.45.64,11,11,0,0,1-.9-.91l-.84-.9.19-.45c.34-.79.39-.8,1-.31A9.4,9.4,0,0,1,13.8,2.33q-.18.34-.39.69Z" />
</svg>
<div class="grid">
<h5>RanchiMall</h5>
<h4>App name</h4>
</div>
</div>
</label>
</nav>
<main>
<sm-tabs class="border-bottom">
<sm-tab slot="tab">Page 1</sm-tab>
<sm-panel slot="panel">
<section class="section">
<h3>Heading</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</p>
<sm-button variant="primary">This is a button</sm-button>
<sm-carousel>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
</sm-carousel>
</section>
<section class="section">
<h3>Heading</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</p>
<sm-carousel>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
</sm-carousel>
</section>
</sm-panel>
<sm-tab slot="tab">Page 2</sm-tab>
<sm-panel slot="panel">
<section class="section">
<h3>Heading</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</p>
<sm-carousel>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
</sm-carousel>
</section>
<section class="section">
<h3>Heading</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</p>
<sm-carousel>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
</sm-carousel>
</section>
</sm-panel>
</sm-tabs>
</main>
<script id="helper_functions" src="js/helper.js"></script>
<script src="js/components.js"></script>
<script id="UI_functions">
let allPages = document.querySelectorAll('.page'),
allTabs = document.querySelectorAll('.navbar-item');
function showPage(btn, page) {
allPages.forEach((page) => {
page.classList.add('hide-completely')
})
allTabs.forEach((tab) => {
tab.classList.remove('active')
})
document.getElementById(page).classList.remove('hide-completely')
btn.classList.add('active')
}
</script>
<sm-input placeholder="Search" type="search"></sm-input>
<theme-toggle></theme-toggle>
</header>
<sm-tab-header target="sections">
<sm-tab>Section 1</sm-tab>
<sm-tab>Section 2</sm-tab>
</sm-tab-header>
<sm-tab-panels id="sections">
<section class="section">
<div class="section__header">
<div class="grid">
<h3>Section Heading</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</p>
</div>
<sm-menu align-options="right">
<menu-option>first option</menu-option>
<menu-option>second option</menu-option>
<menu-option>third option</menu-option>
</sm-menu>
</div>
<sm-carousel>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
</sm-carousel>
</section>
<section class="section">
<div class="section__header">
<div class="grid">
<h3>Section Heading</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</p>
</div>
<sm-menu align-options="right">
<menu-option>first option</menu-option>
<menu-option>second option</menu-option>
<menu-option>third option</menu-option>
</sm-menu>
</div>
<sm-carousel>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
<div class="card">
<h3>Card</h3>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ipsam, officia.
</p>
</div>
</sm-carousel>
</section>
</sm-tab-panels>
</article>
<script src="js/main_UI.js"></script>
<script src="js/components.min.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,133 +0,0 @@
if (!navigator.onLine)
notify('There seems to be a problem connecting to the internet.', 'error', 'fixed', true)
window.addEventListener('offline', () => {
notify('There seems to be a problem connecting to the internet.', 'error', 'fixed', true)
})
window.addEventListener('online', () => {
notify('We are back online.', '', '', true)
})
let themeToggler = document.getElementById("theme_toggle")
if (localStorage.theme === "dark") {
darkTheme()
themeToggler.checked = true;
} else {
lightTheme()
themeToggler.checked = false;
}
function lightTheme() {
document.body.setAttribute("data-theme", "light");
}
function darkTheme() {
document.body.setAttribute("data-theme", "dark");
}
themeToggler.addEventListener("change", () => {
if (themeToggler.checked) {
darkTheme()
localStorage.setItem("theme", "dark");
} else {
lightTheme()
localStorage.setItem("theme", "light");
}
})
// function required for popups or modals to appear
class Stack {
constructor() {
this.items = [];
}
push(element) {
this.items.push(element);
}
pop() {
if (this.items.length == 0)
return "Underflow";
return this.items.pop();
}
peek(index) {
let newIndex = index ? index : 1
return this.items[this.items.length - index];
}
}
let popupStack = new Stack(),
zIndex = 10;
function showPopup(popup, permission) {
let thisPopup = document.getElementById(popup);
document.body.setAttribute('style', `overflow: hidden; top: -${window.scrollY}px`)
popupStack.push({ thisPopup, permission })
thisPopup.show(permission, popupStack)
zIndex++;
thisPopup.setAttribute('style', `z-index: ${zIndex}`)
return thisPopup;
}
function setAttributes(el, attrs) {
for (var key in attrs) {
el.setAttribute(key, attrs[key]);
}
}
// displays a popup for asking permission. Use this instead of JS confirm
let confirmation = function (message) {
return new Promise(resolve => {
let popup = document.getElementById('confirmation');
showPopup('confirmation')
popup.querySelector('#confirm_message').textContent = message;
popup.querySelector('.submit-btn').onclick = () => {
hidePopup()
resolve(true);
}
popup.querySelector('.cancel-btn').onclick = () => {
hidePopup()
resolve(false);
}
})
}
// displays a popup for asking user input. Use this instead of JS prompt
let askPrompt = function (message, defaultVal) {
return new Promise(resolve => {
let popup = document.getElementById('prompt'),
input = popup.querySelector('input');
if (defaultVal)
input.value = defaultVal;
showPopup('prompt')
input.focus()
input.addEventListener('keyup', e => {
if (e.key === 'Enter') {
resolve(input.value);
hidePopup()
}
})
popup.querySelector('#prompt_message').textContent = message;
popup.querySelector('.submit-btn').onclick = () => {
hidePopup()
resolve(input.value);
}
popup.querySelector('.cancel-btn').onclick = () => {
hidePopup()
resolve(null);
}
})
}
function formatedTime(time) {
let timeFrag = new Date(parseInt(time)).toString().split(' '),
day = timeFrag[0],
month = timeFrag[1],
date = timeFrag[2],
year = timeFrag[3],
hours = timeFrag[4].slice(0, timeFrag[4].lastIndexOf(':')),
finalTime = '';
parseInt(hours.split(':')[0]) > 12 ? finalTime = 'PM' : finalTime = 'AM'
return `${hours} ${finalTime} ${day} ${date} ${month} ${year}`
}
function copyToClipboard(parent) {
let toast = document.getElementById('textCopied'),
textToCopy = parent.querySelector('.copy').textContent;
navigator.clipboard.writeText(textToCopy)
toast.classList.remove('hide');
setTimeout(() => {
toast.classList.add('hide');
}, 2000)
}

View File

@ -0,0 +1,282 @@
// Global variables
const domRefs = {};
const appPages = ['home']
//Checks for internet connection status
if (!navigator.onLine)
notify(
"There seems to be a problem connecting to the internet, Please check you internet connection.",
"error",
{ sound: true }
);
window.addEventListener("offline", () => {
notify(
"There seems to be a problem connecting to the internet, Please check you internet connection.",
"error",
{ pinned: true, sound: true }
);
});
window.addEventListener("online", () => {
getRef("notification_drawer").clearAll();
notify("We are back online.", "success");
});
// Use instead of document.getElementById
function getRef(elementId) {
if (!domRefs.hasOwnProperty(elementId)) {
domRefs[elementId] = {
count: 1,
ref: null,
};
return document.getElementById(elementId);
} else {
if (domRefs[elementId].count < 3) {
domRefs[elementId].count = domRefs[elementId].count + 1;
return document.getElementById(elementId);
} else {
if (!domRefs[elementId].ref)
domRefs[elementId].ref = document.getElementById(elementId);
return domRefs[elementId].ref;
}
}
}
// returns dom with specified element
function createElement(tagName, obj) {
const { className, textContent, innerHTML, attributes = {} } = obj
const elem = document.createElement(tagName)
for (let attribute in attributes) {
elem.setAttribute(attribute, attributes[attribute])
}
if (className)
elem.className = className
if (textContent)
elem.textContent = textContent
if (innerHTML)
elem.innerHTML = innerHTML
return elem
}
// Use when a function needs to be executed after user finishes changes
const debounce = (callback, wait) => {
let timeoutId = null;
return (...args) => {
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(() => {
callback.apply(null, args);
}, wait);
};
}
// Limits the rate of function execution
let timerId;
function throttle(func, delay) {
// If setTimeout is already scheduled, no need to do anything
if (timerId) {
return;
}
// Schedule a setTimeout after delay seconds
timerId = setTimeout(function () {
func();
// Once setTimeout function execution is finished, timerId = undefined so that in
// the next scroll event function execution can be scheduled by the setTimeout
timerId = undefined;
}, delay);
}
// function required for popups or modals to appear
class Stack {
constructor() {
this.items = [];
}
push(element) {
this.items.push(element);
}
pop() {
if (this.items.length == 0)
return "Underflow";
return this.items.pop();
}
peek() {
return this.items[this.items.length - 1];
}
}
let popupStack = new Stack(),
zIndex = 10;
async function showPopup(popup, pinned) {
zIndex++
getRef(popup).setAttribute('style', `z-index: ${zIndex}`)
popupStack = getRef(popup).show({ pinned, popupStack })
return getRef(popup);
}
// hides the popup or modal
function hidePopup() {
if (popupStack.peek() === undefined)
return;
popupStack.peek().popup.hide()
}
// displays a popup for asking permission. Use this instead of JS confirm
let getConfirmation = (title, message, cancelText = 'Cancel', confirmText = 'OK') => {
return new Promise(resolve => {
showPopup('confirmation_popup', true)
getRef('confirm_title').textContent = title;
getRef('confirm_message').textContent = message;
let cancelButton = getRef('confirmation_popup').children[2].children[0],
submitButton = getRef('confirmation_popup').children[2].children[1]
submitButton.textContent = confirmText
cancelButton.textContent = cancelText
submitButton.onclick = () => {
hidePopup()
resolve(true);
}
cancelButton.onclick = () => {
hidePopup()
resolve(false);
}
})
}
// displays a popup for asking user input. Use this instead of JS prompt
async function getPromptInput(title, message = '', showText = true, trueBtn = "Ok", falseBtn = "Cancel") {
showPopup('prompt_popup', true)
getRef('prompt_title').textContent = title;
let input = getRef('prompt_input');
input.setAttribute("placeholder", message)
let buttons = getRef('prompt_popup').querySelectorAll("sm-button");
if (showText)
input.setAttribute("type", "text")
else
input.setAttribute("type", "password")
input.focusIn()
buttons[0].textContent = falseBtn;
buttons[1].textContent = trueBtn;
return new Promise((resolve, reject) => {
buttons[0].onclick = () => {
hidePopup()
return;
}
buttons[1].onclick = () => {
let value = input.value;
hidePopup()
resolve(value)
}
})
}
//Function for displaying toast notifications. pass in error for mode param if you want to show an error.
function notify(message, mode, options = {}) {
const { pinned = false, sound } = options
if (mode === "error") console.error(message);
let icon
switch (mode) {
case 'success':
icon = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M10 15.172l9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z"/></svg>`
break;
case 'error':
icon = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-7v2h2v-2h-2zm0-8v6h2V7h-2z"/></svg>`
break;
}
getRef("notification_drawer").push(message, { pinned, icon });
if (navigator.onLine && sound) {
getRef("notification_sound").currentTime = 0;
getRef("notification_sound").play();
}
}
const currentYear = new Date().getFullYear();
function getFormatedTime(time, relative) {
try {
if (String(time).indexOf("_")) time = String(time).split("_")[0];
const intTime = parseInt(time);
if (String(intTime).length < 13) time *= 1000;
let timeFrag = new Date(intTime).toString().split(" "),
day = timeFrag[0],
month = timeFrag[1],
date = timeFrag[2],
year = timeFrag[3],
minutes = new Date(intTime).getMinutes(),
hours = new Date(intTime).getHours(),
currentTime = new Date().toString().split(" ");
minutes = minutes < 10 ? `0${minutes}` : minutes;
let finalHours = ``;
if (hours > 12) finalHours = `${hours - 12}:${minutes}`;
else if (hours === 0) finalHours = `12:${minutes}`;
else finalHours = `${hours}:${minutes}`;
finalHours = hours >= 12 ? `${finalHours} PM` : `${finalHours} AM`;
if (relative) {
return `${date} ${month} ${year}`;
} else return `${finalHours} ${month} ${date} ${year}`;
} catch (e) {
console.error(e);
return time;
}
}
window.addEventListener('hashchange', e => showPage(window.location.hash))
window.addEventListener("load", () => {
document.body.classList.remove('hide-completely')
showPage(window.location.hash)
// document.querySelectorAll('sm-input[data-flo-id]').forEach(input => input.customValidation = validateAddr)
document.addEventListener('keyup', (e) => {
if (e.code === 'Escape') {
hidePopup()
}
})
document.addEventListener("pointerdown", (e) => {
if (e.target.closest("button, sm-button:not([disabled]), .interact")) {
createRipple(e, e.target.closest("button, sm-button, .interact"));
}
});
document.addEventListener('copy', () => {
notify('copied', 'success')
})
});
function createRipple(event, target) {
const circle = document.createElement("span");
const diameter = Math.max(target.clientWidth, target.clientHeight);
const radius = diameter / 2;
const targetDimensions = target.getBoundingClientRect();
circle.style.width = circle.style.height = `${diameter}px`;
circle.style.left = `${event.clientX - (targetDimensions.left + radius)}px`;
circle.style.top = `${event.clientY - (targetDimensions.top + radius)}px`;
circle.classList.add("ripple");
const rippleAnimation = circle.animate(
[
{
transform: "scale(3)",
opacity: 0,
},
],
{
duration: 1000,
fill: "forwards",
easing: "ease-out",
}
);
target.append(circle);
rippleAnimation.onfinish = () => {
circle.remove();
};
}
function showPage(targetPage) {
let pageId
if (targetPage === '') {
pageId = 'overview_page'
}
else {
pageId = targetPage.includes('#') ? targetPage.split('#')[1] : targetPage
}
if(!appPages.includes(pageId)) return
document.querySelector('.page:not(.hide-completely)').classList.add('hide-completely')
getRef(pageId).classList.remove('hide-completely')
}

21
components/components.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -5,6 +5,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SM Components</title>
<meta name="description" content="SM-Components. collection of web components">
<link rel="stylesheet" href="css/main.min.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
@ -53,7 +54,6 @@
<h4>Components</h4>
<ul id="components_list" class="list"></ul>
</hamburger-menu>
<section id="backdrop" class="hide-completely" onclick="sideNav(false)"></section>
<article class="right language-html">
<section id="overview_page" class="page">
<div>
@ -648,7 +648,7 @@
navigationDrawerButton.addEventListner('click', e => {
navigationDrawer.open(); // Will open hamburger menu on mobile devices when hidden
})
&lt;/script&gt;
&lt;/script&gt;
</code>
</pre>
</section>
@ -1328,18 +1328,6 @@
</div>
</section>
</section>
<section id="spinner_page" class="page hide-completely">
<h1 class="page__title">Spinner</h1>
<p>
Just drop the <span class="highlight">sm-spinner</span> in markup where you want to show the spinner
</p>
<sm-spinner></sm-spinner>
<pre>
<code>
&lt;sm-spinner&gt;&lt;/sm-spinner&gt;
</code>
</pre>
</section>
<section id="strip_select_page" class="page hide-completely">
<h1 class="page__title">Strip select</h1>
@ -1923,9 +1911,10 @@
</sm-checkbox>
</template>
<script src="assets/prism.js"></script>
<script src="components.js"></script>
<script src="components.min.js"></script>
<script id="default_ui_library">
const domRefs = {};
const appPages = ["overview_page", "quick_start_page", "global_styling_page", "button_page", "carousel_page", "checkbox_page", "copy_page", "file_input_page", "form_page", "hamburger_menu_page", "input_page", "menu_page", "notifications_page", "popup_page", "radio_page", "select_page", "spinner_page", "switch_page", "strip_select_page", "tabs_page", "tags_input_page", "textarea_page", "text_field_page", "theme_toggle_page"]
function getRef(elementId) {
if (!domRefs.hasOwnProperty(elementId)) {
@ -2218,6 +2207,7 @@
else {
pageId = targetPage.includes('#') ? targetPage.split('#')[1] : targetPage
}
if(!appPages.includes(pageId)) return
document.querySelector('.page:not(.hide-completely)').classList.add('hide-completely')
document.querySelector('.list__item--active').classList.remove('list__item--active')
getRef(pageId).classList.remove('hide-completely')

View File

@ -1,4 +1,4 @@
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>SM Components</title><link rel="stylesheet" href="css/main.min.css"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;700&family=Roboto+Mono&family=Roboto:wght@400;500;700&display=swap" rel="stylesheet"></head><body class="hide-completely"><sm-notifications id="notification_drawer"></sm-notifications><audio id="notification_sound"><source src="https://rmservices.duckdns.org/files/notification-sound.mp3" type="audio/mpeg"><source src="https://rmservices.duckdns.org/files/notification-sound.ogg" type="audio/ogg"></audio><main><header id="main_header" class="flex align-center space-between"><button id="side_nav_button" class="interact" onclick="getRef('side_nav').open()" aria-label="Hamburger menu toggle button"><svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M16 18v2H5v-2h11zm5-7v2H3v-2h18zm-2-7v2H8V4h11z"/></svg></button><h4>SM Components</h4><theme-toggle></theme-toggle></header><hamburger-menu id="side_nav"><h4>Getting Started</h4><ul class="list"><li><a href="#overview_page" class="list__item list__item--active interact">Overview</a></li><li><a href="#quick_start_page" class="list__item interact">Quick start</a></li><li><a href="#global_styling_page" class="list__item interact">Global styling</a></li></ul><h4>Components</h4><ul id="components_list" class="list"></ul></hamburger-menu><section id="backdrop" class="hide-completely" onclick="sideNav(false)"></section><article class="right language-html"><section id="overview_page" class="page"><div><h5 class="color-0-8 weight-500">Total components</h5><h1 id="total_components_count" class="h1"></h1></div><div><h1 class="page__title">Overview</h1><p>Component-based design is the cornerstone of the modern UI development process. With rise of more UI frameworks every day, the web platform has a serious issue of fragmentation and portability.</p><p>Web components to the rescue! This is the collection of web components (WC here forward) that we use at RanchiMall, especially since we are a framework-less development environment so this was a logical choice.</p><h3>Features</h3><ul class="grid gap-1"><li>Native and Cross framework support</li><li>Encapsulated style and functionality</li><li>Easy styling</li><li>Adaptive scaling</li></ul></div></section><section id="quick_start_page" class="page hide-completely"><h1 class="page__title">Quick Start</h1><ol><li>To start using these components, Select the ones you want to add to your project. You can un-check 'get minified' to get the readable code.</li><li>Now you can download or copy the source code for selected components. <strong class="important">You might get a warning while downloading like this file is not safe, please allow the download as this is caused when downloading files with '.js' extension. These components are 100% safe to use.</strong></li><li>Link the downloaded js before <span class="highlight">&lt;/body&gt;</span><pre>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>SM Components</title><meta name="description" content="SM-Components. collection of web components"><link rel="stylesheet" href="css/main.min.css"><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;700&family=Roboto+Mono&family=Roboto:wght@400;500;700&display=swap" rel="stylesheet"></head><body class="hide-completely"><sm-notifications id="notification_drawer"></sm-notifications><audio id="notification_sound"><source src="https://rmservices.duckdns.org/files/notification-sound.mp3" type="audio/mpeg"><source src="https://rmservices.duckdns.org/files/notification-sound.ogg" type="audio/ogg"></audio><main><header id="main_header" class="flex align-center space-between"><button id="side_nav_button" class="interact" onclick="getRef('side_nav').open()" aria-label="Hamburger menu toggle button"><svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M16 18v2H5v-2h11zm5-7v2H3v-2h18zm-2-7v2H8V4h11z"/></svg></button><h4>SM Components</h4><theme-toggle></theme-toggle></header><hamburger-menu id="side_nav"><h4>Getting Started</h4><ul class="list"><li><a href="#overview_page" class="list__item list__item--active interact">Overview</a></li><li><a href="#quick_start_page" class="list__item interact">Quick start</a></li><li><a href="#global_styling_page" class="list__item interact">Global styling</a></li></ul><h4>Components</h4><ul id="components_list" class="list"></ul></hamburger-menu><article class="right language-html"><section id="overview_page" class="page"><div><h5 class="color-0-8 weight-500">Total components</h5><h1 id="total_components_count" class="h1"></h1></div><div><h1 class="page__title">Overview</h1><p>Component-based design is the cornerstone of the modern UI development process. With rise of more UI frameworks every day, the web platform has a serious issue of fragmentation and portability.</p><p>Web components to the rescue! This is the collection of web components (WC here forward) that we use at RanchiMall, especially since we are a framework-less development environment so this was a logical choice.</p><h3>Features</h3><ul class="grid gap-1"><li>Native and Cross framework support</li><li>Encapsulated style and functionality</li><li>Easy styling</li><li>Adaptive scaling</li></ul></div></section><section id="quick_start_page" class="page hide-completely"><h1 class="page__title">Quick Start</h1><ol><li>To start using these components, Select the ones you want to add to your project. You can un-check 'get minified' to get the readable code.</li><li>Now you can download or copy the source code for selected components. <strong class="important">You might get a warning while downloading like this file is not safe, please allow the download as this is caused when downloading files with '.js' extension. These components are 100% safe to use.</strong></li><li>Link the downloaded js before <span class="highlight">&lt;/body&gt;</span><pre>
<code>
&lt;script src=".../components.js"&gt;&lt;/script&gt;
</code>
@ -57,7 +57,7 @@
navigationDrawerButton.addEventListner('click', e => {
navigationDrawer.open(); // Will open hamburger menu on mobile devices when hidden
})
&lt;/script&gt;
&lt;/script&gt;
</code>
</pre></section><section id="input_page" class="page hide-completely"><h1 class="page__title">Input</h1><h2>Interactive demo</h2><sm-input id="my_input" placeholder="Email" type="email" value="john@doe" animate></sm-input><pre>
<code>
@ -186,11 +186,7 @@
&lt;/div&gt;
&lt;/sm-switch&gt;
</code>
</pre><h2>Attributes</h2><p>All the native HTML checkbox attributes are valid</p><section class="table"><div class="tr"><h4 class="table__heading">Attribute</h4><h4 class="table__heading">Description</h4></div><div class="tr"><div><span class="highlight">checked</span> (boolean)</div><p>If present, switch is set to checked state as default.</p></div><div class="tr"><div><span class="highlight">disabled</span> (boolean)</div><p>If present switch is set to disabled state. all the interactions are disabled</p></div><div class="tr"><div><span class="highlight">value</span> (string)</div><p>Sets value of switch which can be accessed by value property with JS</p></div></section></section><section id="spinner_page" class="page hide-completely"><h1 class="page__title">Spinner</h1><p>Just drop the <span class="highlight">sm-spinner</span> in markup where you want to show the spinner</p><sm-spinner></sm-spinner><pre>
<code>
&lt;sm-spinner&gt;&lt;/sm-spinner&gt;
</code>
</pre></section><section id="strip_select_page" class="page hide-completely"><h1 class="page__title">Strip select</h1><p>This is a modern interpritation of classical HTML <span class="highlight">select</span> tag. More suitable for touch devices,</p><h2>Interactive demo</h2><span>Sort by</span><strip-select id="sort_by"><strip-option value="relevance" selected>Relevance</strip-option><strip-option value="popularity">Popularity</strip-option><strip-option value="price">Price</strip-option><strip-option value="rating">Rating</strip-option></strip-select><pre>
</pre><h2>Attributes</h2><p>All the native HTML checkbox attributes are valid</p><section class="table"><div class="tr"><h4 class="table__heading">Attribute</h4><h4 class="table__heading">Description</h4></div><div class="tr"><div><span class="highlight">checked</span> (boolean)</div><p>If present, switch is set to checked state as default.</p></div><div class="tr"><div><span class="highlight">disabled</span> (boolean)</div><p>If present switch is set to disabled state. all the interactions are disabled</p></div><div class="tr"><div><span class="highlight">value</span> (string)</div><p>Sets value of switch which can be accessed by value property with JS</p></div></section></section><section id="strip_select_page" class="page hide-completely"><h1 class="page__title">Strip select</h1><p>This is a modern interpritation of classical HTML <span class="highlight">select</span> tag. More suitable for touch devices,</p><h2>Interactive demo</h2><span>Sort by</span><strip-select id="sort_by"><strip-option value="relevance" selected>Relevance</strip-option><strip-option value="popularity">Popularity</strip-option><strip-option value="price">Price</strip-option><strip-option value="rating">Rating</strip-option></strip-select><pre>
<code>
&lt;strip-select id="sort_by"&gt;
&lt;strip-option value="relevance" selected&gt;Relevance&lt;/strip-option&gt;
@ -330,7 +326,8 @@
})
&lt;/script&gt;
</code>
</pre></section></article></main><template id="nav_item_template"><li><a class="list__item interact"></a></li></template><template id="comp_checkbox_template"><sm-checkbox><span class="comp-checkbox__title"></span></sm-checkbox></template><script src="assets/prism.js"></script><script src="components.js"></script><script id="default_ui_library">const domRefs = {};
</pre></section></article></main><template id="nav_item_template"><li><a class="list__item interact"></a></li></template><template id="comp_checkbox_template"><sm-checkbox><span class="comp-checkbox__title"></span></sm-checkbox></template><script src="assets/prism.js"></script><script src="components.min.js"></script><script id="default_ui_library">const domRefs = {};
const appPages = ["overview_page", "quick_start_page", "global_styling_page", "button_page", "carousel_page", "checkbox_page", "copy_page", "file_input_page", "form_page", "hamburger_menu_page", "input_page", "menu_page", "notifications_page", "popup_page", "radio_page", "select_page", "spinner_page", "switch_page", "strip_select_page", "tabs_page", "tags_input_page", "textarea_page", "text_field_page", "theme_toggle_page"]
function getRef(elementId) {
if (!domRefs.hasOwnProperty(elementId)) {
@ -620,6 +617,7 @@
else {
pageId = targetPage.includes('#') ? targetPage.split('#')[1] : targetPage
}
if(!appPages.includes(pageId)) return
document.querySelector('.page:not(.hide-completely)').classList.add('hide-completely')
document.querySelector('.list__item--active').classList.remove('list__item--active')
getRef(pageId).classList.remove('hide-completely')