Initial commit

This commit is contained in:
2025-08-04 16:33:07 +03:30
commit f798e8e35c
9595 changed files with 1208683 additions and 0 deletions

View File

@@ -0,0 +1,195 @@
@use "@core-scss/base/mixins";
@use "@layouts/styles/placeholders";
@use "@layouts/styles/mixins" as layoutMixins;
@use "@configured-variables" as variables;
@use "@styles/variables/_vuetify.scss" as vuetify;
// 👉 Avatar group
.v-avatar-group {
display: flex;
align-items: center;
> * {
&:not(:first-child) {
margin-inline-start: -0.8rem;
}
transition: transform 0.25s ease, box-shadow 0.15s ease;
&:hover {
z-index: 2;
transform: translateY(-5px) scale(1.05);
@include mixins.elevation(3);
}
}
> .v-avatar {
border: 2px solid rgb(var(--v-theme-surface));
transition: transform 0.15s ease;
}
}
// 👉 Button outline with default color border color
.v-alert--variant-outlined,
.v-avatar--variant-outlined,
.v-btn.v-btn--variant-outlined,
.v-card--variant-outlined,
.v-chip--variant-outlined,
.v-list-item--variant-outlined {
&:not([class*="text-"]) {
border-color: rgba(var(--v-border-color), var(--v-border-opacity));
}
&.text-default {
border-color: rgba(var(--v-border-color), var(--v-border-opacity));
}
}
// 👉 Custom Input
.v-label.custom-input {
padding: 1rem;
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
opacity: 1;
white-space: normal;
+.v-label {
letter-spacing: normal;
}
&:hover {
border-color: rgba(var(--v-border-color), 0.25);
}
&.active {
border-color: rgb(var(--v-theme-primary));
.v-icon {
color: rgb(var(--v-theme-primary)) !important;
}
}
&.custom-checkbox,
&.custom-radio {
.v-input__control {
grid-area: none;
}
}
}
// 👉 Datatable
.v-data-table-footer__pagination {
@include layoutMixins.rtl {
.v-btn {
.v-icon {
transform: rotate(180deg);
}
}
}
}
// Dialog responsive width
.v-dialog {
// dialog custom close btn
.v-dialog-close-btn {
position: absolute;
z-index: 1;
color: rgba(var(--v-theme-on-surface), var(--v-disabled-opacity)) !important;
inset-block-start: 0.5rem;
inset-inline-end: 0.5rem;
.v-btn__overlay {
display: none;
}
}
.v-card {
@extend %style-scroll-bar;
}
}
@media (min-width: 600px) {
.v-dialog {
&.v-dialog-sm,
&.v-dialog-lg,
&.v-dialog-xl {
.v-overlay__content {
inline-size: 565px !important;
}
}
}
}
@media (min-width: 960px) {
.v-dialog {
&.v-dialog-lg,
&.v-dialog-xl {
.v-overlay__content {
inline-size: 865px !important;
}
}
}
}
@media (min-width: 1264px) {
.v-dialog.v-dialog-xl {
.v-overlay__content {
inline-size: 1165px !important;
}
}
}
// 👉 Expansion panel
.v-expansion-panels.customized-panels {
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
border-radius: vuetify.$border-radius-root;
.v-expansion-panel-title {
background-color: rgb(var(--v-theme-expansion-panel-text-custom-bg));
border-block-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
margin-block-end: -1px;
}
.v-expansion-panel-text__wrapper {
padding: 20px;
}
}
// v-tab with pill support
.v-tabs.v-tabs-pill {
.v-tab.v-btn {
border-radius: 6px !important;
transition: none;
.v-tab__slider {
visibility: hidden;
}
}
}
// loop for all colors bg
@each $color-name in variables.$theme-colors-name {
body .v-tabs.v-tabs-pill {
.v-slide-group__content {
gap: 0.25rem;
}
.v-tab--selected.text-#{$color-name} {
background-color: rgb(var(--v-theme-#{$color-name}));
color: rgb(var(--v-theme-on-#{$color-name})) !important;
}
}
}
// We are make even width of all v-timeline body
.v-timeline--vertical.v-timeline {
.v-timeline-item {
.v-timeline-item__body {
justify-self: stretch !important;
}
}
}
// 👉 Switch
.v-switch .v-selection-control:not(.v-selection-control--dirty) .v-switch__thumb {
color: #fff !important;
}

View File

@@ -0,0 +1,16 @@
@use "@configured-variables" as variables;
// ————————————————————————————————————
// * ——— Perfect Scrollbar
// ————————————————————————————————————
body.v-theme--dark {
.ps__rail-y,
.ps__rail-x {
background-color: transparent !important;
}
.ps__thumb-y {
background-color: variables.$plugin-ps-thumb-y-dark;
}
}

View File

@@ -0,0 +1,45 @@
@use "@core-scss/base/placeholders" as *;
@use "@core-scss/template/placeholders" as *;
@use "@core-scss/base/mixins";
.layout-wrapper.layout-nav-type-horizontal {
.layout-navbar-and-nav-container {
@extend %default-layout-horizontal-nav-navbar-and-nav-container;
}
// 👉 Navbar
.layout-navbar {
@extend %default-layout-horizontal-nav-navbar;
}
// 👉 Layout content container
.navbar-content-container {
display: flex;
align-items: center;
block-size: 100%;
}
.layout-horizontal-nav {
@extend %default-layout-horizontal-nav-nav;
.nav-items {
@extend %default-layout-horizontal-nav-nav-items-list;
}
}
// 👉 App footer
.layout-footer {
@at-root {
.layout-footer-sticky#{&} {
background-color: rgb(var(--v-theme-surface));
@include mixins.elevation(3);
}
}
}
// TODO: Use Vuetify grid sass variable here
.layout-page-content {
padding-block: 1.5rem;
}
}

View File

@@ -0,0 +1,103 @@
@use "@configured-variables" as variables;
@use "@core-scss/base/placeholders" as *;
@use "@core-scss/template/placeholders" as *;
@use "misc";
@use "@core-scss/base/mixins";
$header: ".layout-navbar";
@if variables.$layout-vertical-nav-navbar-is-contained {
$header: ".layout-navbar .navbar-content-container";
}
.layout-wrapper.layout-nav-type-vertical {
// SECTION Layout Navbar
// 👉 Elevated navbar
@if variables.$vertical-nav-navbar-style == "elevated" {
// Add transition
#{$header} {
transition: padding 0.2s ease, background-color 0.18s ease;
}
// If navbar is contained => Add border radius to header
@if variables.$layout-vertical-nav-navbar-is-contained {
#{$header} {
border-radius: 0 0 variables.$default-layout-with-vertical-nav-navbar-footer-roundness variables.$default-layout-with-vertical-nav-navbar-footer-roundness;
}
}
// Scrolled styles for sticky navbar
@at-root {
/* This html selector with not selector is required when:
dialog is opened and window don't have any scroll. This removes window-scrolled class from layout and our style broke
*/
html.v-overlay-scroll-blocked:not([style*="--v-body-scroll-y: 0px;"]) .layout-navbar-sticky,
&.window-scrolled.layout-navbar-sticky {
#{$header} {
@extend %default-layout-vertical-nav-scrolled-sticky-elevated-nav;
@extend %default-layout-vertical-nav-floating-navbar-and-sticky-elevated-navbar-scrolled;
}
.navbar-blur#{$header} {
@extend %blurry-bg;
}
}
}
}
// 👉 Floating navbar
@else if variables.$vertical-nav-navbar-style == "floating" {
// Regardless of navbar is contained or not => Apply overlay to .layout-navbar
.layout-navbar {
&.navbar-blur {
@extend %default-layout-vertical-nav-floating-navbar-overlay;
}
}
&:not(.layout-navbar-sticky) {
#{$header} {
margin-block-start: variables.$vertical-nav-floating-navbar-top;
}
}
#{$header} {
@if variables.$layout-vertical-nav-navbar-is-contained {
border-radius: variables.$default-layout-with-vertical-nav-navbar-footer-roundness;
}
background-color: rgb(var(--v-theme-surface));
@extend %default-layout-vertical-nav-floating-navbar-and-sticky-elevated-navbar-scrolled;
}
.navbar-blur#{$header} {
@extend %blurry-bg;
}
}
// !SECTION
// 👉 Layout footer
.layout-footer {
$ele-layout-footer: &;
.footer-content-container {
border-radius: variables.$default-layout-with-vertical-nav-navbar-footer-roundness variables.$default-layout-with-vertical-nav-navbar-footer-roundness 0 0;
// Sticky footer
@at-root {
// .layout-footer-sticky#{$ele-layout-footer} => .layout-footer-sticky.layout-wrapper.layout-nav-type-vertical .layout-footer
.layout-footer-sticky#{$ele-layout-footer} {
.footer-content-container {
background-color: rgb(var(--v-theme-surface));
padding-block: 0;
padding-inline: 1.2rem;
@include mixins.elevation(3);
}
}
}
}
}
}

View File

@@ -0,0 +1,16 @@
@use "@core-scss/base/placeholders";
@use "@core-scss/base/variables";
.layout-vertical-nav,
.layout-horizontal-nav {
ol,
ul {
list-style: none;
}
}
.layout-navbar {
@if variables.$navbar-high-emphasis-text {
@extend %layout-navbar;
}
}

View File

@@ -0,0 +1,194 @@
@use "@core-scss/base/placeholders" as *;
@use "@core-scss/template/placeholders" as *;
@use "@configured-variables" as variables;
@use "@layouts/styles/mixins" as layoutsMixins;
@use "@core-scss/base/mixins";
@use "vuetify/lib/styles/tools/states" as vuetifyStates;
.layout-horizontal-nav {
@extend %nav;
// 👉 Icon styles
.nav-item-icon {
@extend %horizontal-nav-item-icon;
}
// 👉 Common styles for nav group & nav link
.nav-link,
.nav-group {
// 👉 Disabled nav items
&.disabled {
@extend %horizontal-nav-disabled;
}
// Set width of inner nav group and link
&.sub-item {
@extend %horizontal-nav-subitem;
}
}
// SECTION Nav Link
.nav-link {
@extend %nav-link;
a {
@extend %horizontal-nav-item;
// Adds before psudo element to style hover state
@include mixins.before-pseudo;
// Adds vuetify states
@include vuetifyStates.states($active: false);
}
// 👉 Top level nav link
&:not(.sub-item) {
a {
@extend %horizontal-nav-top-level-item;
&.router-link-active {
@extend %nav-link-active;
}
}
}
// 👉 Sub link
&.sub-item {
a {
&.router-link-active {
// We will not use active styles from material here because we want to use primary color for active link
@extend %horizontal-nav-sub-nav-link-active;
}
}
}
}
// !SECTION
// SECTION Nav Group
.nav-group {
.popper-triggerer {
.nav-group-label {
@extend %horizontal-nav-item;
}
}
> .popper-triggerer > .nav-group-label {
// Adds before psudo element to style hover state
@include mixins.before-pseudo;
// Adds vuetify states
@include vuetifyStates.states($active: false);
}
.popper-content {
@extend %horizontal-nav-popper-content-hidden;
@extend %horizontal-nav-popper-content;
background-color: rgb(var(--v-theme-surface));
// Set max-height for the popper content
> div {
max-block-size: variables.$horizontal-nav-popper-content-max-height;
}
}
// 👉 Top level group
&:not(.sub-item) {
> .popper-triggerer {
position: relative;
/*
The Bridge
This after pseudo will work as bridge when we have space between popper triggerer and popper content
Initially it will have pointer events none for normal behavior and once the content is shown it will
work as bridge by setting pointer events to `auto`
*/
&::after {
position: absolute;
block-size: variables.$horizontal-nav-popper-content-top;
content: "";
inline-size: 100%;
inset-block-start: 100%;
inset-inline-start: 0;
pointer-events: none;
}
}
// Enable the pseudo bridge when content is shown by setting pointer events to `auto`
&.show-content > .popper-triggerer::after {
/*
We have added `z-index: 2` because when there is horizontal nav item below the popper trigger (group)
without this style nav item below popper trigger (group) gets focus hence closes the popper content
*/
z-index: 2;
pointer-events: auto;
}
> .popper-triggerer > .nav-group-label {
@extend %horizontal-nav-top-level-item;
}
&.active {
> .popper-triggerer > .nav-group-label {
@extend %nav-link-active;
}
}
// Add space between popper wrapper & content
> .popper-content {
margin-block-start: variables.$horizontal-nav-popper-content-top !important;
}
}
// 👉 Sub group
&.sub-item {
&.active {
@include mixins.selected-states("> .popper-triggerer > .nav-group-label::before");
}
// Reduce the icon's size of nested group's nav links (Top level group > Sub group > [Nav links])
.sub-item {
.nav-item-icon {
@extend %third-level-nav-item-icon;
}
}
}
.nav-group-arrow {
font-size: variables.$horizontal-nav-group-arrow-icon-size;
/*
ml-auto won't matter in top level group (because we haven't specified fixed width for top level groups)
but we wrote generally because we don't want to become so specific
*/
margin-inline-start: auto;
}
&.popper-inline-end {
.nav-group-arrow {
transform: rotateZ(270deg);
@include layoutsMixins.rtl {
transform: rotateZ(90deg);
}
}
}
.nav-item-title {
@extend %horizontal-nav-item-title;
}
&.show-content {
> .popper-content {
@extend %horizontal-nav-popper-content-visible;
}
&:not(.active) {
@include mixins.selected-states("> .popper-triggerer > .nav-group-label::before");
}
}
}
// !SECTION
}

View File

@@ -0,0 +1,48 @@
@use "sass:map";
// Layout
@use "vertical-nav";
@use "horizontal-nav";
@use "default-layout";
@use "default-layout-w-vertical-nav";
@use "default-layout-w-horizontal-nav";
// Layouts package
@use "layouts";
// Skins
@use "skins";
// Components
@use "components";
// Utilities
@use "utilities";
// Route Transitions
@use "route-transitions";
// Misc
@use "misc";
// Dark
@use "dark";
// libs
@use "libs/perfect-scrollbar";
a {
color: rgb(var(--v-theme-primary));
text-decoration: none;
}
// Vuetify 3 don't provide margin bottom style like vuetify 2
p {
margin-block-end: 1rem;
}
// Iconify icon size
svg.iconify {
block-size: 1em;
inline-size: 1em;
}

View File

@@ -0,0 +1,63 @@
@use "@configured-variables" as variables;
/* This styles extends the existing layout package's styles for handling cases that aren't related to layouts package */
/*
When we use v-layout as immediate first child of `.page-content-container`, it adds display:flex and page doesn't get contained height
*/
// .layout-wrapper.layout-nav-type-vertical {
// &.layout-content-height-fixed {
// .page-content-container {
// > .v-layout:first-child > :not(.v-navigation-drawer):first-child {
// flex-grow: 1;
// block-size: 100%;
// }
// }
// }
// }
.layout-wrapper.layout-nav-type-vertical {
&.layout-content-height-fixed {
.page-content-container {
> .v-layout:first-child {
overflow: hidden;
min-block-size: 100%;
> .v-main {
// overflow-y: auto;
.v-main__wrap > :first-child {
block-size: 100%;
overflow-y: auto;
}
}
}
}
}
}
// Let div/v-layout take full height. E.g. Email App
.layout-wrapper.layout-nav-type-horizontal {
&.layout-content-height-fixed {
> .layout-page-content {
display: flex;
}
}
}
// 👉 Floating navbar styles
@if variables.$vertical-nav-navbar-style == "floating" {
// Add spacing above navbar if navbar is floating (was in %layout-navbar-sticky placeholder)
body .layout-wrapper.layout-nav-type-vertical.layout-navbar-sticky {
.layout-navbar {
inset-block-start: variables.$vertical-nav-floating-navbar-top;
}
/*
If it's floating navbar
Add `vertical-nav-floating-navbar-top` as margin top to .layout-page-content
*/
.layout-page-content {
margin-block-start: variables.$vertical-nav-floating-navbar-top;
}
}
}

View File

@@ -0,0 +1,20 @@
// scrollable-content allows creating fixed header and scrollable content for VNavigationDrawer (Used when perfect scrollbar is used)
.scrollable-content {
&.v-navigation-drawer {
.v-navigation-drawer__content {
display: flex;
overflow: hidden;
flex-direction: column;
}
}
}
// adding styling for code tag
code {
border-radius: 3px;
color: rgb(var(--v-code-color));
font-size: 90%;
font-weight: 400;
padding-block: 0.2em;
padding-inline: 0.4em;
}

View File

@@ -0,0 +1,63 @@
@use "sass:map";
@use "@styles/variables/vuetify.scss";
@mixin elevation($z, $important: false) {
box-shadow: map.get(vuetify.$shadow-key-umbra, $z), map.get(vuetify.$shadow-key-penumbra, $z), map.get(vuetify.$shadow-key-ambient, $z) if($important, !important, null);
}
// #region before-pseudo
// This mixin is inspired from vuetify for adding hover styles via before pseudo element
@mixin before-pseudo() {
position: relative;
&::before {
position: absolute;
border-radius: inherit;
background: currentcolor;
block-size: 100%;
content: "";
inline-size: 100%;
inset: 0;
opacity: 0;
pointer-events: none;
}
}
// #endregion before-pseudo
@mixin bordered-skin($component, $border-property: "border", $important: false) {
#{$component} {
box-shadow: none !important;
// stylelint-disable-next-line annotation-no-unknown
#{$border-property}: 1px solid rgba(var(--v-border-color), var(--v-border-opacity)) if($important, !important, null);
}
}
// #region selected-states
// Inspired from vuetify's active-states mixin
// focus => 0.12 & selected => 0.08
@mixin selected-states($selector) {
#{$selector} {
opacity: calc(var(--v-selected-opacity) * var(--v-theme-overlay-multiplier));
}
&:hover
#{$selector} {
opacity: calc(var(--v-selected-opacity) + var(--v-hover-opacity) * var(--v-theme-overlay-multiplier));
}
&:focus-visible
#{$selector} {
opacity: calc(var(--v-selected-opacity) + var(--v-focus-opacity) * var(--v-theme-overlay-multiplier));
}
@supports not selector(:focus-visible) {
&:focus {
#{$selector} {
opacity: calc(var(--v-selected-opacity) + var(--v-focus-opacity) * var(--v-theme-overlay-multiplier));
}
}
}
}
// #endregion selected-states

View File

@@ -0,0 +1,70 @@
// 👉 Zoom fade
.app-transition-zoom-fade-enter-active,
.app-transition-zoom-fade-leave-active {
transition: transform 0.35s, opacity 0.28s ease-in-out;
}
.app-transition-zoom-fade-enter-from {
opacity: 0;
transform: scale(0.98);
}
.app-transition-zoom-fade-leave-to {
opacity: 0;
transform: scale(1.02);
}
// 👉 Fade
.app-transition-fade-enter-active,
.app-transition-fade-leave-active {
transition: opacity 0.25s ease-in-out;
}
.app-transition-fade-enter-from,
.app-transition-fade-leave-to {
opacity: 0;
}
// 👉 Fade bottom
.app-transition-fade-bottom-enter-active,
.app-transition-fade-bottom-leave-active {
transition: opacity 0.3s, transform 0.35s;
}
.app-transition-fade-bottom-enter-from {
opacity: 0;
transform: translateY(-0.6rem);
}
.app-transition-fade-bottom-leave-to {
opacity: 0;
transform: translateY(0.6rem);
}
// 👉 Slide fade
.app-transition-slide-fade-enter-active,
.app-transition-slide-fade-leave-active {
transition: opacity 0.3s, transform 0.35s;
}
.app-transition-slide-fade-enter-from {
opacity: 0;
transform: translateX(-0.6rem);
}
.app-transition-slide-fade-leave-to {
opacity: 0;
transform: translateX(0.6rem);
}
// 👉 Zoom out
.app-transition-zoom-out-enter-active,
.app-transition-zoom-out-leave-active {
transition: opacity 0.26s ease-in-out, transform 0.3s ease-out;
}
.app-transition-zoom-out-enter-from,
.app-transition-zoom-out-leave-to {
opacity: 0;
transform: scale(0.98);
}

View File

@@ -0,0 +1,189 @@
@use "@configured-variables" as variables;
@use "@layouts/styles/mixins" as layoutsMixins;
/* 👉 Demo spacers */
/* TODO: Use vuetify SCSS variable here; */
$card-spacer-content: 16px;
.demo-space-x {
display: flex;
flex-wrap: wrap;
align-items: center;
margin-block-start: -$card-spacer-content;
& > * {
margin-block-start: $card-spacer-content;
margin-inline-end: $card-spacer-content;
}
}
.demo-space-y {
& > * {
margin-block-end: $card-spacer-content;
&:last-child {
margin-block-end: 0;
}
}
}
// 👉 Card match height
.match-height.v-row {
.v-card {
block-size: 100%;
}
}
// 👉 Whitespace
.whitespace-no-wrap {
white-space: nowrap;
}
// 👉 Colors
/*
Vuetify is applying `.text-white` class to badge icon but don't provide its styles
Moreover, we also use this class in some places
In vuetify 2 with `$color-pack: false` SCSS var config this class was getting generated but this is not the case in v3
We also need !important to get correct color in badge icon
*/
.text-white {
color: #fff !important;
}
.text-white-variant {
color: rgba(211, 212, 220);
}
.text-link {
&:not(:hover) {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
}
}
.text-link {
&:not(:hover) {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
}
}
.bg-var-theme-background {
background-color: rgba(var(--v-theme-on-background), var(--v-hover-opacity)) !important;
}
.bg-global-primary {
background-color: rgb(var(--v-global-theme-primary)) !important;
color: rgb(var(--v-theme-on-primary)) !important;
}
// [/^bg-light-(\w+)$/, ([, w]) => ({ backgroundColor: `rgba(var(--v-theme-${w}), var(--v-activated-opacity))` })],
@each $color-name in variables.$theme-colors-name {
.bg-light-#{$color-name} {
background-color: rgba(var(--v-theme-#{$color-name}), var(--v-activated-opacity)) !important;
}
}
// 👉 clamp text
.clamp-text {
display: -webkit-box;
overflow: hidden;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
text-overflow: ellipsis;
}
.custom-badge {
.v-badge__badge {
border-radius: 6px !important;
block-size: 12px !important;
inline-size: 12px !important;
}
}
.leading-normal {
line-height: normal !important;
}
// 👉 for rtl only
.flip-in-rtl {
@include layoutsMixins.rtl {
transform: scaleX(-1);
}
}
// 👉 Carousel
.carousel-delimiter-top-end {
.v-carousel__controls {
justify-content: end;
block-size: 40px;
inset-block-start: 0;
padding-inline: 1rem;
.v-btn--icon.v-btn--density-default {
block-size: calc(var(--v-btn-height) + -10px);
inline-size: calc(var(--v-btn-height) + -8px);
&.v-btn--active {
color: #fff;
}
.v-btn__overlay {
opacity: 0;
}
.v-ripple__container {
display: none;
}
.v-btn__content {
.v-icon {
block-size: 8px !important;
font-size: 8px !important;
inline-size: 8px !important;
}
}
}
}
@each $color-name in variables.$theme-colors-name {
&.dots-active-#{$color-name} {
.v-carousel__controls {
.v-btn--active {
color: rgb(var(--v-theme-#{$color-name})) !important;
}
}
}
}
}
.v-timeline-item {
.app-timeline-title {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
font-size: 16px;
font-weight: 500;
line-height: 1.3125rem;
}
.app-timeline-meta {
color: rgba(var(--v-theme-on-surface), var(--v-disabled-opacity));
font-size: 12px;
line-height: 0.875rem;
}
.app-timeline-text {
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
font-size: 14px;
line-height: 1.25rem;
}
.timeline-chip {
border-radius: 6px;
background: rgba(var(--v-theme-on-surface), var(--v-hover-opacity));
padding-block: 5px;
padding-inline: 10px;
}
}

View File

@@ -0,0 +1,90 @@
@use "sass:map";
@use "sass:list";
@use "@configured-variables" as variables;
// Thanks: https://css-tricks.com/snippets/sass/deep-getset-maps/
@function map-deep-get($map, $keys...) {
@each $key in $keys {
$map: map.get($map, $key);
}
@return $map;
}
@function map-deep-set($map, $keys, $value) {
$maps: ($map,);
$result: null;
// If the last key is a map already
// Warn the user we will be overriding it with $value
@if type-of(nth($keys, -1)) == "map" {
@warn "The last key you specified is a map; it will be overrided with `#{$value}`.";
}
// If $keys is a single key
// Just merge and return
@if length($keys) == 1 {
@return map-merge($map, ($keys: $value));
}
// Loop from the first to the second to last key from $keys
// Store the associated map to this key in the $maps list
// If the key doesn't exist, throw an error
@for $i from 1 through length($keys) - 1 {
$current-key: list.nth($keys, $i);
$current-map: list.nth($maps, -1);
$current-get: map.get($current-map, $current-key);
@if not $current-get {
@error "Key `#{$key}` doesn't exist at current level in map.";
}
$maps: list.append($maps, $current-get);
}
// Loop from the last map to the first one
// Merge it with the previous one
@for $i from length($maps) through 1 {
$current-map: list.nth($maps, $i);
$current-key: list.nth($keys, $i);
$current-val: if($i == list.length($maps), $value, $result);
$result: map.map-merge($current-map, ($current-key: $current-val));
}
// Return result
@return $result;
}
// font size utility classes
@each $name, $size in variables.$font-sizes {
.text-#{$name} {
font-size: $size;
line-height: map.get(variables.$font-line-height, $name);
}
}
// truncate utility class
.truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
// gap utility class
@each $name, $size in variables.$gap {
.gap-#{$name} {
gap: $size;
}
.gap-x-#{$name} {
column-gap: $size;
}
.gap-y-#{$name} {
row-gap: $size;
}
}
.list-none {
list-style-type: none;
}

View File

@@ -0,0 +1,198 @@
@use "vuetify/lib/styles/tools/functions" as *;
/*
TODO: Add docs on when to use placeholder vs when to use SASS variable
Placeholder
- When we want to keep customization to our self between templates use it
Variables
- When we want to allow customization from both user and our side
- You can also use variable for consistency (e.g. mx 1 rem should be applied to both vertical nav items and vertical nav header)
*/
@forward "@layouts/styles/variables" with (
// Adjust z-index so vertical nav & overlay stays on top of v-layout in v-main. E.g. Email app
$layout-vertical-nav-z-index: 1003,
$layout-overlay-z-index: 1002,
);
@use "@layouts/styles/variables" as *;
// 👉 Default layout
$navbar-high-emphasis-text: true !default;
// @forward "@layouts/styles/variables" with (
// $layout-vertical-nav-width: 350px !default,
// );
$theme-colors-name: (
"primary",
"secondary",
"error",
"info",
"success",
"warning"
) !default;
// 👉 Default layout with vertical nav
$default-layout-with-vertical-nav-navbar-footer-roundness: 10px !default;
// 👉 Vertical nav
$vertical-nav-background-color-rgb: var(--v-theme-background) !default;
$vertical-nav-background-color: rgb(#{$vertical-nav-background-color-rgb}) !default;
// This is used to keep consistency between nav items and nav header left & right margin
// This is used by nav items & nav header
$vertical-nav-horizontal-spacing: 1rem !default;
$vertical-nav-horizontal-padding: 0.75rem !default;
// Vertical nav header height. Mostly we will align it with navbar height;
$vertical-nav-header-height: $layout-vertical-nav-navbar-height !default;
$vertical-nav-navbar-elevation: 3 !default;
$vertical-nav-navbar-style: "elevated" !default; // options: elevated, floating
$vertical-nav-floating-navbar-top: 1rem !default;
// Vertical nav header padding
$vertical-nav-header-padding: 1rem $vertical-nav-horizontal-padding !default;
$vertical-nav-header-inline-spacing: $vertical-nav-horizontal-spacing !default;
// Move logo when vertical nav is mini (collapsed but not hovered)
$vertical-nav-header-logo-translate-x-when-vertical-nav-mini: -4px !default;
// Space between logo and title
$vertical-nav-header-logo-title-spacing: 0.9rem !default;
// Section title margin top (when its not first child)
$vertical-nav-section-title-mt: 1.5rem !default;
// Section title margin bottom
$vertical-nav-section-title-mb: 0.5rem !default;
// Vertical nav icons
$vertical-nav-items-icon-size: 1.5rem !default;
$vertical-nav-items-nested-icon-size: 0.9rem !default;
$vertical-nav-items-icon-margin-inline-end: 0.5rem !default;
// Transition duration for nav group arrow
$vertical-nav-nav-group-arrow-transition-duration: 0.15s !default;
// Timing function for nav group arrow
$vertical-nav-nav-group-arrow-transition-timing-function: ease-in-out !default;
// 👉 Horizontal nav
/*
❗ Heads up
==================
Here we assume we will always use shorthand property which will apply same padding on four side
This is because this have been used as value of top property by `.popper-content`
*/
$horizontal-nav-padding: 0.6875rem !default;
// Gap between top level horizontal nav items
$horizontal-nav-top-level-items-gap: 4px !default;
// Horizontal nav icons
$horizontal-nav-items-icon-size: 1.5rem !default;
$horizontal-nav-third-level-icon-size: 0.9rem !default;
$horizontal-nav-items-icon-margin-inline-end: 0.625rem !default;
$horizontal-nav-group-arrow-icon-size: 1.375rem !default;
// We used SCSS variable because we want to allow users to update max height of popper content
// 120px is combined height of navbar & horizontal nav
$horizontal-nav-popper-content-max-height: calc(100dvh - 120px - 4rem) !default;
// This variable is used for horizontal nav popper content's `margin-top` and "The bridge"'s height. We need to sync both values.
$horizontal-nav-popper-content-top: calc($horizontal-nav-padding + 0.375rem) !default;
// 👉 Plugins
$plugin-ps-thumb-y-dark: rgba(var(--v-theme-surface-variant), 0.35) !default;
// 👉 Vuetify
// Used in src/@core-scss/base/libs/vuetify/_overrides.scss
$vuetify-reduce-default-compact-button-icon-size: true !default;
// 👉 Custom variables
// for utility classes
$font-sizes: () !default;
$font-sizes: map-deep-merge(
(
"xs": 0.75rem,
"sm": 0.875rem,
"base": 1rem,
"lg": 1.125rem,
"xl": 1.25rem,
"2xl": 1.5rem,
"3xl": 1.875rem,
"4xl": 2.25rem,
"5xl": 3rem,
"6xl": 3.75rem,
"7xl": 4.5rem,
"8xl": 6rem,
"9xl": 8rem
),
$font-sizes
);
// line height
$font-line-height: () !default;
$font-line-height: map-deep-merge(
(
"xs": 1rem,
"sm": 1.25rem,
"base": 1.5rem,
"lg": 1.75rem,
"xl": 1.75rem,
"2xl": 2rem,
"3xl": 2.25rem,
"4xl": 2.5rem,
"5xl": 1,
"6xl": 1,
"7xl": 1,
"8xl": 1,
"9xl": 1
),
$font-line-height
);
// gap utility class
$gap: () !default;
$gap: map-deep-merge(
(
"0": 0,
"1": 0.25rem,
"2": 0.5rem,
"3": 0.75rem,
"4": 1rem,
"5": 1.25rem,
"6":1.5rem,
"7": 1.75rem,
"8": 2rem,
"9": 2.25rem,
"10": 2.5rem,
"11": 2.75rem,
"12": 3rem,
"14": 3.5rem,
"16": 4rem,
"20": 5rem,
"24": 6rem,
"28": 7rem,
"32": 8rem,
"36": 9rem,
"40": 10rem,
"44": 11rem,
"48": 12rem,
"52": 13rem,
"56": 14rem,
"60": 15rem,
"64": 16rem,
"72": 18rem,
"80": 20rem,
"96": 24rem
),
$gap
);

View File

@@ -0,0 +1,255 @@
@use "@core-scss/base/placeholders" as *;
@use "@core-scss/template/placeholders" as *;
@use "@layouts/styles/mixins" as layoutsMixins;
@use "@configured-variables" as variables;
@use "@core-scss/base/mixins" as mixins;
@use "vuetify/lib/styles/tools/states" as vuetifyStates;
.layout-nav-type-vertical {
// 👉 Layout Vertical nav
.layout-vertical-nav {
$sl-layout-nav-type-vertical: &;
@extend %nav;
@at-root {
// Add styles for collapsed vertical nav
.layout-vertical-nav-collapsed#{$sl-layout-nav-type-vertical}.hovered {
@include mixins.elevation(6);
}
}
background-color: variables.$vertical-nav-background-color;
// 👉 Nav header
.nav-header {
overflow: hidden;
padding: variables.$vertical-nav-header-padding;
margin-inline: variables.$vertical-nav-header-inline-spacing;
min-block-size: variables.$vertical-nav-header-height;
// TEMPLATE: Check if we need to move this to master
.app-logo {
flex-shrink: 0;
transition: transform 0.25s ease-in-out;
@at-root {
// Move logo a bit to align center with the icons in vertical nav mini variant
.layout-vertical-nav-collapsed#{$sl-layout-nav-type-vertical}:not(.hovered) .nav-header .app-logo {
transform: translateX(variables.$vertical-nav-header-logo-translate-x-when-vertical-nav-mini);
@include layoutsMixins.rtl {
transform: translateX(-(variables.$vertical-nav-header-logo-translate-x-when-vertical-nav-mini));
}
}
}
}
.header-action {
@extend %nav-header-action;
}
}
// 👉 Nav items shadow
.vertical-nav-items-shadow {
position: absolute;
z-index: 1;
background:
linear-gradient(
rgb(#{variables.$vertical-nav-background-color-rgb}) 5%,
rgba(#{variables.$vertical-nav-background-color-rgb}, 75%) 45%,
rgba(#{variables.$vertical-nav-background-color-rgb}, 20%) 80%,
transparent
);
block-size: 55px;
inline-size: 100%;
inset-block-start: calc(#{variables.$vertical-nav-header-height} - 2px);
opacity: 0;
pointer-events: none;
transition: opacity 0.15s ease-in-out;
will-change: opacity;
@include layoutsMixins.rtl {
transform: translateX(8px);
}
}
&.scrolled {
.vertical-nav-items-shadow {
opacity: 1;
}
}
// Setting z-index 1 will make perfect scrollbar thumb appear on top of vertical nav items shadow;
.ps__rail-y {
z-index: 1;
}
// 👉 Nav section title
.nav-section-title {
@extend %vertical-nav-item;
@extend %vertical-nav-section-title;
margin-block-end: variables.$vertical-nav-section-title-mb;
&:not(:first-child) {
margin-block-start: variables.$vertical-nav-section-title-mt;
}
.placeholder-icon {
margin-inline: auto;
}
}
// Nav item badge
.nav-item-badge {
@extend %vertical-nav-item-badge;
}
// 👉 Nav group & Link
.nav-link,
.nav-group {
overflow: hidden;
> :first-child {
@extend %vertical-nav-item;
@extend %vertical-nav-item-interactive;
}
.nav-item-icon {
@extend %vertical-nav-items-icon;
}
&.disabled {
opacity: var(--v-disabled-opacity);
pointer-events: none;
}
a {
outline: none;
}
}
// 👉 Vertical nav link
.nav-link {
@extend %nav-link;
> .router-link-exact-active {
@extend %nav-link-active;
}
> a {
// Adds before psudo element to style hover state
@include mixins.before-pseudo;
// Adds vuetify states
&:not(.router-link-active, .router-link-exact-active) {
@include vuetifyStates.states($active: false);
}
}
}
// 👉 Vertical nav group
.nav-group {
// Reduce the size of icon if link/group is inside group
.nav-group,
.nav-link {
.nav-item-icon {
@extend %vertical-nav-items-nested-icon;
}
}
// Hide icons after 2nd level
& .nav-group {
.nav-link,
.nav-group {
.nav-item-icon {
@extend %vertical-nav-items-icon-after-2nd-level;
}
}
}
.nav-group-arrow {
flex-shrink: 0;
transform-origin: center;
transition: transform variables.$vertical-nav-nav-group-arrow-transition-duration variables.$vertical-nav-nav-group-arrow-transition-timing-function;
will-change: transform;
}
// Rotate arrow icon if group is opened
&.open {
> .nav-group-label .nav-group-arrow {
transform: rotateZ(90deg);
}
}
// Nav group label
> :first-child {
// Adds before psudo element to style hover state
@include mixins.before-pseudo;
}
&:not(.active,.open) > :first-child {
// Adds vuetify states
@include vuetifyStates.states($active: false);
}
// Active & open states for nav group label
&.active,
&.open {
> :first-child {
@extend %vertical-nav-group-open-active;
}
}
}
}
}
// SECTION: Transitions
.vertical-nav-section-title-enter-active,
.vertical-nav-section-title-leave-active {
transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;
}
.vertical-nav-section-title-enter-from,
.vertical-nav-section-title-leave-to {
opacity: 0;
transform: translateX(15px);
@include layoutsMixins.rtl {
transform: translateX(-15px);
}
}
.transition-slide-x-enter-active,
.transition-slide-x-leave-active {
transition: opacity 0.1s ease-in-out, transform 0.12s ease-in-out;
}
.transition-slide-x-enter-from,
.transition-slide-x-leave-to {
opacity: 0;
transform: translateX(-15px);
@include layoutsMixins.rtl {
transform: translateX(15px);
}
}
.vertical-nav-app-title-enter-active,
.vertical-nav-app-title-leave-active {
transition: opacity 0.1s ease-in-out, transform 0.12s ease-in-out;
}
.vertical-nav-app-title-enter-from,
.vertical-nav-app-title-leave-to {
opacity: 0;
transform: translateX(-15px);
@include layoutsMixins.rtl {
transform: translateX(15px);
}
}
// !SECTION

View File

@@ -0,0 +1,35 @@
$ps-size: 0.25rem;
$ps-hover-size: 0.375rem;
$ps-track-size: 0.5rem;
.ps__thumb-y {
inline-size: $ps-size !important;
inset-inline-end: 0.0625rem;
}
.ps__thumb-y,
.ps__thumb-x {
background-color: rgb(var(--v-theme-perfect-scrollbar-thumb)) !important;
}
.ps__thumb-x {
block-size: $ps-size !important;
}
.ps__rail-x {
background: transparent !important;
block-size: $ps-track-size;
}
.ps__rail-y {
background: transparent !important;
inline-size: $ps-track-size !important;
inset-inline-end: 0.125rem !important;
inset-inline-start: unset !important;
}
.ps__rail-y.ps--clicking .ps__thumb-y,
.ps__rail-y:focus > .ps__thumb-y,
.ps__rail-y:hover > .ps__thumb-y {
inline-size: $ps-hover-size !important;
}

View File

@@ -0,0 +1 @@
@use "overrides";

View File

@@ -0,0 +1,262 @@
@use "@core-scss/base/utils";
@use "@configured-variables" as variables;
// 👉 Application
// We need accurate vh in mobile devices as well
.v-application__wrap {
/* stylelint-disable-next-line liberty/use-logical-spec */
min-height: 100dvh;
}
// 👉 Typography
h1,
h2,
h3,
h4,
h5,
h6,
.text-h1,
.text-h2,
.text-h3,
.text-h4,
.text-h5,
.text-h6,
.text-button,
.text-overline,
.v-card-title {
color: rgba(var(--v-theme-on-background), var(--v-high-emphasis-opacity));
}
body,
.text-body-1,
.text-body-2,
.text-subtitle-1,
.text-subtitle-2 {
color: rgba(var(--v-theme-on-background), var(--v-medium-emphasis-opacity));
}
// 👉 Grid
// Remove margin-bottom of v-input_details inside grid (validation error message)
.v-row {
.v-col,
[class^="v-col-*"] {
.v-input__details {
margin-block-end: 0;
}
}
}
// 👉 Button
// Update tonal variant disabled opacity
.v-btn--disabled {
opacity: 0.65;
}
@if variables.$vuetify-reduce-default-compact-button-icon-size {
.v-btn--density-compact.v-btn--size-default {
.v-btn__content > svg {
block-size: 22px;
font-size: 22px;
inline-size: 22px;
}
}
}
// 👉 Card
// Removes padding-top for immediately placed v-card-text after itself
.v-card-text {
& + & {
padding-block-start: 0 !important;
}
}
/*
👉 Checkbox & Radio Ripple
TODO Checkbox and switch component. Remove it when vuetify resolve the extra spacing: https://github.com/vuetifyjs/vuetify/issues/15519
We need this because form elements likes checkbox and switches are by default set to height of textfield height which is way big than we want
Tested with checkbox & switches
*/
.v-checkbox.v-input,
.v-switch.v-input {
--v-input-control-height: auto;
flex: unset;
}
.v-radio-group {
.v-selection-control-group {
.v-radio:not(:last-child) {
margin-inline-end: 0.9rem;
}
}
}
/*
👉 Tabs
Disable tab transition
This is for tabs where we don't have card wrapper to tabs and have multiple cards as tab content.
This class will disable transition and adds `overflow: unset` on `VWindow` to allow spreading shadow
*/
.disable-tab-transition {
overflow: unset !important;
.v-window__container {
block-size: auto !important;
}
.v-window-item:not(.v-window-item--active) {
display: none !important;
}
.v-window__container .v-window-item {
transform: none !important;
}
}
// 👉 List
.v-list {
// Set icons opacity to .87
.v-list-item__prepend > .v-icon,
.v-list-item__append > .v-icon {
opacity: 1;
}
}
// 👉 Card list
/*
Custom class
Remove list spacing inside card
This is because card title gets padding of 20px and list item have padding of 16px. Moreover, list container have padding-bottom as well.
*/
.card-list {
--v-card-list-gap: 20px;
&.v-list {
padding-block: 0;
}
.v-list-item {
min-block-size: unset;
min-block-size: auto !important;
padding-block: 0 !important;
padding-inline: 0 !important;
> .v-ripple__container {
opacity: 0;
}
&:not(:last-child) {
padding-block-end: var(--v-card-list-gap) !important;
}
}
.v-list-item:hover,
.v-list-item:focus,
.v-list-item:active,
.v-list-item.active {
> .v-list-item__overlay {
opacity: 0 !important;
}
}
}
// 👉 Divider
.v-divider {
color: rgb(var(--v-border-color));
}
.v-divider.v-divider--vertical {
block-size: inherit;
}
// 👉 DataTable
.v-data-table {
/* stylelint-disable-next-line no-descending-specificity */
.v-checkbox-btn .v-selection-control__wrapper {
margin-inline-start: 0 !important;
}
.v-selection-control {
display: flex !important;
}
.v-pagination {
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
}
}
// 👉 v-field
.v-field:hover .v-field__outline {
--v-field-border-opacity: var(--v-medium-emphasis-opacity);
}
// 👉 VLabel
.v-label {
opacity: 1 !important;
&:not(.v-field-label--floating) {
color: rgba(var(--v-theme-on-background), var(--v-medium-emphasis-opacity));
}
}
// 👉 Overlay
.v-overlay__scrim,
.v-navigation-drawer__scrim {
background: rgba(var(--v-overlay-scrim-background), var(--v-overlay-scrim-opacity)) !important;
opacity: 1 !important;
}
// 👉 VMessages
.v-messages {
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
opacity: 1 !important;
}
// 👉 Alert close btn
.v-alert__close {
.v-btn--icon .v-icon {
--v-icon-size-multiplier: 1.5;
}
}
// 👉 Badge icon alignment
.v-badge__badge {
display: flex;
align-items: center;
}
// 👉 Btn focus outline style removed
.v-btn:focus-visible::after {
opacity: 0 !important;
}
// .v-select chip spacing for slot
.v-input:not(.v-select--chips) .v-select__selection {
.v-chip {
margin-block: 2px var(--select-chips-margin-bottom);
}
}
// 👉 VCard and VList subtitle color
.v-list-item-subtitle {
color: rgba(var(--v-theme-on-background), var(--v-medium-emphasis-opacity));
}
// 👉 placeholders
.v-field__input {
@at-root {
& input::placeholder,
input#{&}::placeholder,
textarea#{&}::placeholder {
color: rgba(var(--v-theme-on-surface), var(--v-disabled-opacity)) !important;
opacity: 1 !important;
}
}
}

View File

@@ -0,0 +1,62 @@
@use "sass:map";
/* 👉 Shadow opacities */
$shadow-key-umbra-opacity-custom: var(--v-shadow-key-umbra-opacity);
$shadow-key-penumbra-opacity-custom: var(--v-shadow-key-penumbra-opacity);
$shadow-key-ambient-opacity-custom: var(--v-shadow-key-ambient-opacity);
/* 👉 Card transition properties */
$card-transition-property-custom: box-shadow, opacity;
@forward "vuetify/settings" with (
// 👉 General settings
$color-pack: false !default,
// 👉 Shadow opacity
$shadow-key-umbra-opacity: $shadow-key-umbra-opacity-custom !default,
$shadow-key-penumbra-opacity: $shadow-key-penumbra-opacity-custom !default,
$shadow-key-ambient-opacity: $shadow-key-ambient-opacity-custom !default,
// 👉 Card
$card-color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity)) !default,
$card-elevation: 6 !default,
$card-title-line-height: 1.6 !default,
$card-actions-min-height: unset !default,
$card-text-padding: 1.25rem !default,
$card-item-padding: 1.25rem !default,
$card-actions-padding: 0 12px 12px !default,
$card-transition-property: $card-transition-property-custom !default,
$card-subtitle-opacity: 1 !default,
// 👉 Expansion Panel
$expansion-panel-active-title-min-height: 48px !default,
// 👉 List
$list-item-icon-margin-end: 16px !default,
$list-item-icon-margin-start: 16px !default,
$list-item-subtitle-opacity: 1 !default,
// 👉 Navigation Drawer
$navigation-drawer-content-overflow-y: hidden !default,
// 👉 Tooltip
$tooltip-background-color: rgba(59, 55, 68, 0.9) !default,
$tooltip-text-color: rgb(var(--v-theme-on-primary)) !default,
$tooltip-font-size: 0.75rem !default,
// 👉 VTimeline
$timeline-dot-size: 34px !default,
// 👉 table
$table-transition-property: height !default,
// 👉 VOverlay
$overlay-opacity: 1 !default,
// 👉 VContainer
$container-max-widths: (
"xl": 1440px,
"xxl": 1440px
) !default,
);

View File

@@ -0,0 +1,27 @@
@use "@configured-variables" as variables;
@use "misc";
@use "@core-scss/base/mixins";
%default-layout-horizontal-nav-navbar-and-nav-container {
@include mixins.elevation(3);
// 1000 is v-window z-index
z-index: 1001;
background-color: rgb(var(--v-theme-surface));
&.header-blur {
@extend %blurry-bg;
}
}
%default-layout-horizontal-nav-navbar {
border-block-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
}
%default-layout-horizontal-nav-nav {
padding-block: variables.$horizontal-nav-padding;
}
%default-layout-horizontal-nav-nav-items-list {
gap: variables.$horizontal-nav-top-level-items-gap;
}

View File

@@ -0,0 +1,45 @@
@use "@configured-variables" as variables;
@use "misc";
@use "@core-scss/base/mixins";
%default-layout-vertical-nav-scrolled-sticky-elevated-nav {
background-color: rgb(var(--v-theme-surface));
}
%default-layout-vertical-nav-floating-navbar-and-sticky-elevated-navbar-scrolled {
@include mixins.elevation(variables.$vertical-nav-navbar-elevation);
// If navbar is contained => Squeeze navbar content on scroll
@if variables.$layout-vertical-nav-navbar-is-contained {
padding-inline: 1.2rem;
}
}
%default-layout-vertical-nav-floating-navbar-overlay {
isolation: isolate;
&::after {
position: absolute;
z-index: -1;
/* stylelint-disable property-no-vendor-prefix */
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
/* stylelint-enable */
background:
linear-gradient(
180deg,
rgba(var(--v-theme-background), 70%) 44%,
rgba(var(--v-theme-background), 43%) 73%,
rgba(var(--v-theme-background), 0%)
);
background-repeat: repeat;
block-size: calc(variables.$layout-vertical-nav-navbar-height + variables.$vertical-nav-floating-navbar-top + 0.5rem);
content: "";
inset-block-start: -(variables.$vertical-nav-floating-navbar-top);
inset-inline: 0 0;
/* stylelint-disable property-no-vendor-prefix */
-webkit-mask: linear-gradient(black, black 18%, transparent 100%);
mask: linear-gradient(black, black 18%, transparent 100%);
/* stylelint-enable */
}
}

View File

@@ -0,0 +1,3 @@
%layout-navbar {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
}

View File

@@ -0,0 +1,98 @@
@use "@layouts/styles/mixins" as layoutsMixins;
@use "@core-scss/base/variables";
@use "@layouts/styles/placeholders";
@use "@core-scss/base/mixins";
// Horizontal nav item styles (including nested)
%horizontal-nav-item {
padding-block: 0.6rem;
padding-inline: 1rem;
}
// Top level horizontal nav item styles (`a` tag & group label)
%horizontal-nav-top-level-item {
border-radius: 0.4rem;
}
%horizontal-nav-disabled {
opacity: var(--v-disabled-opacity);
pointer-events: none;
}
// Active styles for sub nav link
%horizontal-nav-sub-nav-link-active {
background: rgba(var(--v-theme-primary), 0.1);
color: rgb(var(--v-theme-primary));
}
/*
This style is required when you don't provide any transition to horizontal nav items via themeConfig `themeConfig.horizontalNav.transition`
Also, you have to disable it if you are using transition
*/
// Popper content styles when it's hidden
%horizontal-nav-popper-content-hidden {
// display: none;
// opacity: 0;
// pointer-events: none;
// transform: translateY(7px);
// transition: transform 0.25s ease-in-out, opacity 0.15s ease-in-out;
}
/*
This style is required when you don't provide any transition to horizontal nav items via themeConfig `themeConfig.horizontalNav.transition`
Also, you have to disable it if you are using transition
*/
// Popper content styles when it's shown
%horizontal-nav-popper-content-visible {
// display: block;
// opacity: 1;
// pointer-events: auto;
// pointer-events: auto;
// transform: translateY(0);
}
// Horizontal nav item icon (Including sub nav items)
%horizontal-nav-item-icon {
font-size: variables.$horizontal-nav-items-icon-size;
margin-inline-end: variables.$horizontal-nav-items-icon-margin-inline-end;
}
// Horizontal nav subitem
%horizontal-nav-subitem {
min-inline-size: 12rem;
.nav-item-title {
margin-inline-end: 1rem;
}
}
// Styles for third level item icon/ (e.g. Reduce the icon's size of nested group's nav links (Top level group > Sub group > [Nav links]))
%third-level-nav-item-icon {
font-size: variables.$horizontal-nav-third-level-icon-size;
margin-inline: calc((variables.$horizontal-nav-items-icon-size - variables.$horizontal-nav-third-level-icon-size) / 2) 0.75rem;
/*
`margin-inline` will be (normal icon font-size - small icon font-size) / 2
(1.5rem - 0.9rem) / 2 => 0.6rem / 2 => 0.3rem
*/
}
// Horizontal nav item title
%horizontal-nav-item-title {
margin-inline-end: 0.3rem;
white-space: nowrap;
}
// Popper content styles
%horizontal-nav-popper-content {
@include mixins.elevation(4);
border-radius: 6px;
padding-block: 0.3rem;
> div {
@extend %style-scroll-bar;
}
}

View File

@@ -0,0 +1,7 @@
@forward "horizontal-nav";
@forward "vertical-nav";
@forward "nav";
@forward "default-layout";
@forward "default-layout-vertical-nav";
@forward "default-layout-horizontal-nav";
@forward "misc";

View File

@@ -0,0 +1,7 @@
%blurry-bg {
/* stylelint-disable property-no-vendor-prefix */
-webkit-backdrop-filter: blur(6px);
backdrop-filter: blur(6px);
/* stylelint-enable */
background-color: rgb(var(--v-theme-surface), 0.9);
}

View File

@@ -0,0 +1,33 @@
@use "@core-scss/base/mixins";
// This is common style that needs to be applied to both navs
%nav {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
.nav-item-title {
letter-spacing: 0.15px;
}
.nav-section-title {
letter-spacing: 0.4px;
}
}
/*
Active nav link styles for horizontal & vertical nav
For horizontal nav it will be only applied to top level nav items
For vertical nav it will be only applied to nav links (not nav groups)
*/
%nav-link-active {
background-color: rgb(var(--v-global-theme-primary));
color: rgb(var(--v-theme-on-primary));
@include mixins.elevation(3);
}
%nav-link {
a {
color: inherit;
}
}

View File

@@ -0,0 +1,80 @@
@use "@core-scss/base/mixins";
@use "@configured-variables" as variables;
@use "vuetify/lib/styles/tools/states" as vuetifyStates;
%nav-header-action {
font-size: 1.25rem;
}
// Nav items styles (including section title)
%vertical-nav-item {
margin-block: 0;
margin-inline: variables.$vertical-nav-horizontal-spacing;
padding-block: 0;
padding-inline: variables.$vertical-nav-horizontal-padding;
white-space: nowrap;
}
// This is same as `%vertical-nav-item` except section title is excluded
%vertical-nav-item-interactive {
border-radius: 0.4rem;
block-size: 2.75rem;
/*
We will use `margin-block-end` instead of `margin-block` to give more space for shadow to appear.
With `margin-block`, due to small space (space gets divided between top & bottom) shadow cuts
*/
margin-block-end: 0.375rem;
}
// Common styles for nav item icon styles
// Nav group's children icon styles are not here (Adjusts height, width & margin)
%vertical-nav-items-icon {
flex-shrink: 0;
font-size: variables.$vertical-nav-items-icon-size;
margin-inline-end: variables.$vertical-nav-items-icon-margin-inline-end;
}
// Icon styling for icon nested inside another nav item (2nd level)
%vertical-nav-items-nested-icon {
/*
`margin-inline` will be (normal icon font-size - small icon font-size) / 2
(1.5rem - 0.9rem) / 2 => 0.6rem / 2 => 0.3rem
*/
$vertical-nav-items-nested-icon-margin-inline: calc((variables.$vertical-nav-items-icon-size - variables.$vertical-nav-items-nested-icon-size) / 2);
font-size: variables.$vertical-nav-items-nested-icon-size;
margin-inline: $vertical-nav-items-nested-icon-margin-inline $vertical-nav-items-nested-icon-margin-inline + variables.$vertical-nav-items-icon-margin-inline-end;
}
%vertical-nav-items-icon-after-2nd-level {
visibility: hidden;
}
// Open & Active nav group styles
%vertical-nav-group-open-active {
@include mixins.selected-states("&::before");
}
// Section title
// Setting height will prevent jerking when text & icon is toggled
%vertical-nav-section-title {
block-size: 1.5rem;
color: rgba(var(--v-theme-on-surface), var(--v-disabled-opacity));
font-size: 0.75rem;
text-transform: uppercase;
}
// Vertical nav item badge styles
%vertical-nav-item-badge {
display: inline-block;
border-radius: 1.5rem;
font-size: 0.8em;
font-weight: 500;
line-height: 1;
padding-block: 0.25em;
padding-inline: 0.55em;
text-align: center;
vertical-align: baseline;
white-space: nowrap;
}

View File

@@ -0,0 +1,72 @@
@use "sass:map";
@use "@core-scss/base/mixins";
@use "@configured-variables" as variables;
@use "../utils";
$header: ".layout-navbar";
@if variables.$layout-vertical-nav-navbar-is-contained {
$header: ".layout-navbar .navbar-content-container";
}
.skin--bordered {
@include mixins.bordered-skin(".v-card:not(.v-card--flat)");
@include mixins.bordered-skin(".v-menu .v-overlay__content > .v-card, .v-menu .v-overlay__content > .v-sheet, .v-menu .v-overlay__content > .v-list");
@include mixins.bordered-skin(".popper-content");
// Navbar
// -- Horizontal
@include mixins.bordered-skin(".layout-navbar-and-nav-container", "border-bottom");
// -- Vertical
// We have added `.layout-navbar-sticky` as well in selector because we don't want to add borders if navbar is static
@if variables.$layout-vertical-nav-navbar-is-contained {
@include mixins.bordered-skin(".layout-nav-type-vertical.window-scrolled.layout-navbar-sticky #{$header}");
.layout-nav-type-vertical.window-scrolled #{$header} {
border-block-start: none !important;
}
}
// stylelint-disable-next-line @stylistic/indentation
@else {
@include mixins.bordered-skin(".layout-nav-type-vertical.window-scrolled.layout-navbar-sticky #{$header}", "border-bottom");
}
// Footer
// -- Vertical
@include mixins.bordered-skin(".layout-nav-type-vertical.layout-footer-sticky .layout-footer .footer-content-container");
.layout-nav-type-vertical.layout-footer-sticky .layout-footer .footer-content-container {
border-block-end: none;
}
// -- Horizontal
@include mixins.bordered-skin(".layout-nav-type-horizontal.layout-footer-sticky .layout-footer");
.layout-nav-type-horizontal.layout-footer-sticky .layout-footer {
border-block-end: none;
}
// Vertical Nav
.layout-vertical-nav {
border-inline-end: thin solid rgba(var(--v-border-color), var(--v-border-opacity));
}
// Expansion Panels
.v-expansion-panels:not(.customized-panels) {
.v-expansion-panel__shadow {
box-shadow: none !important;
}
.v-expansion-panel {
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
&:not(:last-child) {
margin-block-end: -1px;
}
&::after {
content: none;
}
}
}
}

View File

@@ -0,0 +1 @@
@use "bordered";

View File

@@ -0,0 +1,9 @@
.layout-wrapper.layout-nav-type-horizontal {
.layout-navbar-and-nav-container {
.app-logo {
.app-title {
font-size: 22px;
}
}
}
}

View File

@@ -0,0 +1,20 @@
@use "@core-scss/base/mixins";
.layout-wrapper.layout-nav-type-vertical {
// 👉 Layout footer
.layout-footer {
$ele-layout-footer: &;
.footer-content-container {
// Sticky footer
@at-root {
// .layout-footer-sticky#{$ele-layout-footer} => .layout-footer-sticky.layout-wrapper.layout-nav-type-vertical .layout-footer
.layout-footer-sticky#{$ele-layout-footer} {
.footer-content-container {
@include mixins.elevation(6);
}
}
}
}
}
}

View File

@@ -0,0 +1,40 @@
@use "@core-scss/template/placeholders" as *;
.layout-horizontal-nav {
color: rgba(var(--v-theme-on-background), var(--v-high-emphasis-opacity));
// SECTION Nav Group
.nav-group,
.nav-link {
.popper-content {
.nav-link.sub-item a,
.nav-group-label {
@extend %nav-group-label-and-nav-link-style;
}
.nav-group.active {
> .popper-triggerer .nav-group-label {
font-weight: 500;
}
}
.nav-group.sub-item .sub-item {
.nav-group-label .nav-item-icon {
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
}
a:not(.router-link-exact-active) .nav-item-icon {
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
}
}
.nav-link.sub-item {
.router-link-active.router-link-exact-active {
font-weight: 500;
}
}
}
}
// !SECTION
}

View File

@@ -0,0 +1,6 @@
@use "sass:map";
@use "@configured-variables" as variables;
@mixin custom-elevation($color, $size) {
box-shadow: (map.get(variables.$shadow-params, $size) rgba($color, map.get(variables.$shadow-opacity, $size)));
}

View File

@@ -0,0 +1,49 @@
.v-timeline-item {
.app-timeline-title {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
font-size: 15px;
font-weight: 500;
line-height: 1.3125rem;
}
.app-timeline-meta {
color: rgba(var(--v-theme-on-surface), var(--v-disabled-opacity));
font-size: 11px;
line-height: 0.875rem;
}
.app-timeline-text {
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
font-size: 13px;
line-height: 1.25rem;
}
}
// Temporary solution as v-spacer style is not getting applied in build version. will remove this after release.
// VSpacer
.v-spacer {
flex-grow: 1;
}
// app-logo & app-logo-title
.app-logo {
display: flex;
align-items: center;
column-gap: 0.75rem;
.app-logo-title {
font-size: 1.375rem;
font-weight: 700;
letter-spacing: 0.25px;
line-height: 1.5rem;
text-transform: capitalize;
}
}
.text-white-variant {
color: rgba(255, 255, 255, 78%) !important;
}
.bg-custom-background {
background-color: rgb(var(--v-table-header-color));
}

View File

@@ -0,0 +1,102 @@
@forward "@core-scss/base/variables" with (
$default-layout-with-vertical-nav-navbar-footer-roundness: 6px !default,
$vertical-nav-navbar-style: "floating" !default, // options: elevated, floating
// 👉 Vertical nav
$vertical-nav-background-color-rgb: var(--v-theme-surface) !default,
// This is used to keep consistency between nav items and nav header left & right margin
// This is used by nav items & nav header
$vertical-nav-horizontal-spacing: 0.75rem !default,
// Section title margin top (when its not first child)
$vertical-nav-section-title-mt: 1rem !default,
$vertical-nav-navbar-elevation: 4 !default,
$vertical-nav-horizontal-padding: 0.75rem !default,
$layout-vertical-nav-collapsed-width: 70px !default,
// Move logo when vertical nav is mini (collapsed but not hovered)
$vertical-nav-header-logo-translate-x-when-vertical-nav-mini: -1px !default,
// Section title margin bottom
$vertical-nav-section-title-mb: 0.375rem !default,
// Vertical nav header padding
$vertical-nav-header-padding: 1.25rem 0.5rem !default,
// Vertical nav icons
$vertical-nav-items-icon-size: 1.375rem !default,
$vertical-nav-items-nested-icon-size: 0.75rem !default,
// 👉Footer
$layout-vertical-nav-footer-height: 54px !default,
// Gap between top level horizontal nav items
$horizontal-nav-top-level-items-gap: 6px !default,
$horizontal-nav-items-icon-margin-inline-end: 0.5rem !default,
$horizontal-nav-popper-content-top: 0.375rem !default,
$horizontal-nav-group-arrow-icon-size: 1.25rem !default,
$horizontal-nav-third-level-icon-size: 0.75rem !default,
/*
❗ Heads up
==================
Here we assume we will always use shorthand property which will apply same padding on four side
This is because this have been used as value of top property by `.popper-content`
*/
$horizontal-nav-padding: 0.5rem !default,
// 👉 Navbar
$layout-vertical-nav-navbar-height: 54px !default,
$layout-horizontal-nav-navbar-height: 54px !default,
// Font sizes
$font-sizes: (
"xs": 0.6875rem,
"sm": 0.8125rem,
"base": 0.9375rem,
"lg": 1.125rem,
"xl": 1.5rem,
"2xl": 1.75rem,
"3xl": 2rem,
"4xl": 2.375rem,
"5xl": 3rem,
"6xl": 3.5rem,
"7xl": 4rem,
"8xl": 4.5rem,
"9xl": 5.25rem,
) !default,
// Line heights
$font-line-height: (
"xs": 0.9375rem,
"sm": 1.25rem,
"base": 1.375rem,
"lg": 1.75rem,
"xl": 2.375rem,
"2xl": 2.625rem,
"3xl": 2.75rem,
"4xl": 3.25rem,
"5xl": 1,
"6xl": 1,
"7xl": 1,
"8xl": 1,
"9xl": 1
) !default,
);
/* Custom shadow opacity */
$shadow-opacity: (
"sm": 0.3,
"md": 0.4,
"lg": 0.5,
) !default;
/* Custom shadow params */
$shadow-params: (
"sm": 0 2px 6px 0,
"md": 0 4px 16px 0,
"lg": 0 6px 20px 0,
) !default;

View File

@@ -0,0 +1,57 @@
@use "@configured-variables" as variables;
@use "@core-scss/base/mixins";
@use "@layouts/styles/mixins" as layoutsMixins;
.layout-nav-type-vertical {
// 👉 Layout Vertical nav
.layout-vertical-nav {
color: rgba(var(--v-theme-on-background), var(--v-high-emphasis-opacity));
@include mixins.elevation(4);
.nav-header {
padding-inline-end: 0.125rem;
.app-logo {
.app-title {
font-size: 22px;
}
}
}
.nav-items {
padding-block: 0.25rem;
}
// 👉 Nav group & Link
.nav-link,
.nav-group {
/* shadow cut issue fix */
margin-block-end: -0.5rem;
padding-block-end: 0.5rem;
a {
outline: none;
}
}
.nav-section-title .placeholder-icon {
margin-inline-start: 0.0625rem;
transform: scaleX(1.6);
@include layoutsMixins.rtl {
margin-inline-start: 0.125rem;
}
}
}
&.layout-vertical-nav-collapsed {
.layout-vertical-nav:not(.hovered) {
.nav-header {
.header-action {
opacity: 0;
}
}
}
}
}

View File

@@ -0,0 +1,17 @@
@use "sass:map";
@use "@core-scss/base";
// Layout
@use "vertical-nav";
@use "horizontal-nav";
@use "default-layout-w-vertical-nav";
@use "default-layout-w-horizontal-nav";
// Skins
@use "skins";
// Utilities
@use "utilities";
// Mixins
@use "mixins";

View File

@@ -0,0 +1,108 @@
@use "@styles/variables/_vuetify.scss" as vuetify;
@use "@layouts/styles/mixins" as layoutsMixins;
@use "@core-scss/base/mixins";
body .apexcharts-canvas {
&line[stroke="transparent"] {
display: "none";
}
.apexcharts-tooltip {
@include mixins.elevation(3);
border-color: rgba(var(--v-border-color), var(--v-border-opacity));
background: rgb(var(--v-theme-surface));
.apexcharts-tooltip-title {
border-color: rgba(var(--v-border-color), var(--v-border-opacity));
background: rgb(var(--v-theme-surface));
font-weight: 500;
padding-inline: 10px;
}
&.apexcharts-theme-light {
color: rgba(var(--v-theme-on-background), var(--v-high-emphasis-opacity));
}
&.apexcharts-theme-dark {
color: white;
}
.apexcharts-tooltip-series-group:first-of-type {
padding-block-end: 0;
}
}
.apexcharts-xaxistooltip {
border-color: rgba(var(--v-border-color), var(--v-border-opacity));
background: rgb(var(--v-theme-grey-50));
color: rgba(var(--v-theme-on-background), var(--v-high-emphasis-opacity));
&::after {
border-block-end-color: rgb(var(--v-theme-grey-50));
}
&::before {
border-block-end-color: rgba(var(--v-border-color), var(--v-border-opacity));
}
}
.apexcharts-yaxistooltip {
border-color: rgba(var(--v-border-color), var(--v-border-opacity));
background: rgb(var(--v-theme-grey-50));
&::after {
border-inline-start-color: rgb(var(--v-theme-grey-50));
}
&::before {
border-inline-start-color: rgba(var(--v-border-color), var(--v-border-opacity));
}
}
.apexcharts-xaxistooltip-text,
.apexcharts-yaxistooltip-text {
color: rgba(var(--v-theme-on-background), var(--v-high-emphasis-opacity));
}
.apexcharts-yaxis .apexcharts-yaxis-texts-g .apexcharts-yaxis-label {
@include layoutsMixins.rtl {
text-anchor: start;
}
}
.apexcharts-text,
.apexcharts-tooltip-text,
.apexcharts-datalabel-label,
.apexcharts-datalabel,
.apexcharts-xaxistooltip-text,
.apexcharts-yaxistooltip-text,
.apexcharts-legend-text {
font-family: vuetify.$body-font-family !important;
}
.apexcharts-pie-label {
fill: white;
filter: none;
}
.apexcharts-marker {
box-shadow: none;
}
.apexcharts-tooltip-marker {
margin-inline-end: 0.625rem;
@include layoutsMixins.rtl {
margin-inline: 0 0.625rem !important;
}
}
.apexcharts-legend-marker {
margin-inline-end: 0.3875rem !important;
@include layoutsMixins.rtl {
margin-inline-end: 0.75rem !important;
}
}
}

View File

@@ -0,0 +1,351 @@
/* stylelint-disable no-duplicate-selectors */
/* stylelint-disable no-descending-specificity */
@use "@core-scss/base/mixins";
@use "@styles/variables/vuetify.scss";
.calendar-add-event-drawer {
.v-navigation-drawer__content {
overflow-y: hidden;
}
}
body .fc {
--fc-today-bg-color: rgba(var(--v-theme-on-surface), var(--v-hover-opacity));
--fc-border-color: rgba(var(--v-border-color), var(--v-border-opacity));
--fc-neutral-bg-color: rgb(var(--v-theme-background));
--fc-list-event-hover-bg-color: rgba(var(--v-theme-on-surface), 0.02);
--fc-page-bg-color: rgb(var(--v-theme-surface));
--fc-event-border-color: currentcolor;
a {
color: inherit;
}
.fc-timegrid-divider {
padding: 0;
}
.fc-button {
border-width: 0;
border-radius: 0.375rem;
line-height: 22px;
padding-block: 0.5rem;
padding-inline: 1.25rem;
}
th.fc-col-header-cell {
border-inline-end-color: transparent;
}
.fc-day-other .fc-daygrid-day-top {
color: rgba(var(--v-theme-on-surface), var(--v-disabled-opacity));
opacity: 1;
}
.fc-daygrid-event {
border-radius: 4px;
}
.fc-col-header-cell-cushion {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
font-size: 0.9375rem;
font-weight: 500;
line-height: 1.375rem;
}
.fc-toolbar-title {
display: inline-block;
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
font-size: clamp(1.1rem, 2.5vw, 1.5rem);
font-weight: 500;
line-height: 38px;
}
.fc-toolbar .fc-toolbar-title {
margin-inline-start: 1rem;
}
.fc-timegrid-event,
.fc-timegrid-more-link {
border-radius: 0;
}
.fc-event-time {
font-size: 0.8125rem;
font-weight: 500 !important;
line-height: 14px;
}
.fc-event-title {
font-size: 0.75rem;
font-weight: 500 !important;
line-height: 14px;
}
.fc-timegrid-event {
.fc-event-title {
font-size: 0.8125rem;
line-height: 1.25rem;
}
.fc-event-time {
margin-block-end: 2px;
}
}
.fc-event-title-container {
.fc-event-title {
font-size: 0.8125rem;
}
}
.fc-prev-button {
padding-inline-start: 0;
}
.fc-prev-button,
.fc-next-button {
padding: 0.5rem;
}
.fc-timegrid-event-harness-inset .fc-timegrid-event,
.fc-timegrid-event.fc-event-mirror,
.fc-timegrid-more-link {
box-shadow: none;
}
&.fc-direction-ltr .fc-timegrid-col-events {
margin: 0;
}
.fc-col-header .fc-col-header-cell .fc-col-header-cell-cushion {
padding: 0.5rem;
text-decoration: none !important;
}
.fc-timegrid .fc-timegrid-slots .fc-timegrid-slot {
block-size: 3rem;
}
// Removed double border in list view
.fc-list {
border-block-end: none;
border-inline: none;
font-size: 0.8125rem;
.fc-list-day-cushion.fc-cell-shaded {
background-color: rgba(var(--v-theme-on-surface), var(--v-hover-opacity));
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
font-weight: 500;
}
.fc-list-event-time,
.fc-list-event-title {
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
font-size: 0.9375rem;
}
.fc-list-day .fc-list-day-text,
.fc-list-day .fc-list-day-side-text {
font-size: 0.9375rem;
line-height: 22px;
text-decoration: none;
}
.fc-list-table {
border-block-end: 1px solid rgba(var(--v-theme-on-surface));
}
}
.fc-timegrid-axis {
color: rgba(var(--v-theme-on-surface), var(--v-disabled-opacity));
font-size: 0.8125rem;
text-transform: capitalize;
}
.fc-timegrid-slot-label-frame {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
font-size: 0.8125rem;
text-align: center;
text-transform: uppercase;
}
.fc-header-toolbar {
flex-wrap: wrap;
padding: 1.4688rem;
gap: 1rem 0.5rem;
margin-block-end: 0 !important;
}
.fc-toolbar-chunk {
display: flex;
align-items: center;
.fc-button-group {
.fc-button-primary {
&,
&:hover,
&:not(.disabled):active {
border-color: transparent;
background-color: transparent;
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
}
&:focus {
box-shadow: none !important;
}
}
}
&:last-child {
.fc-button-group {
border-radius: 0.375rem;
.fc-button,
.fc-button:active {
background-color: rgba(var(--v-theme-primary), 0.16);
color: rgb(var(--v-theme-primary));
font-size: 0.9375rem;
font-weight: 500;
letter-spacing: 0.0187rem;
padding-inline: 1rem;
text-transform: capitalize;
&:not(:last-child) {
border-inline-end: 0.0625rem solid rgba(var(--v-theme-primary), var(--v-border-opacity));
}
&.fc-button-active {
background-color: rgba(var(--v-theme-primary), 0.24);
color: rgb(var(--v-theme-primary));
}
}
}
}
}
// Calendar content container
.fc-view-harness {
min-block-size: 41.625rem;
}
.fc-event {
border-color: transparent;
cursor: pointer;
margin-block-end: 0.5625rem;
padding-block: 0.25rem;
padding-inline: 0.75rem;
}
.fc-event-main {
color: inherit;
font-weight: 500;
line-height: 14px;
}
tbody[role="rowgroup"] {
> tr > td[role="presentation"] {
border: none;
}
}
.fc-scrollgrid {
border-inline-start: none;
}
.fc-daygrid-day {
padding: 0.3125rem;
}
.fc-daygrid-day-number {
padding-block: 0.5rem;
padding-inline: 0.6875rem;
}
.fc-scrollgrid-section > * {
border-inline-end-width: 0;
border-inline-start-width: 0;
}
.fc-list-event-dot {
color: inherit;
--fc-event-border-color: currentcolor;
}
.fc-list-event {
background-color: transparent !important;
}
.fc-popover {
@include mixins.elevation(3);
border-radius: 6px;
.fc-popover-header,
.fc-popover-body {
padding: 0.5rem;
}
.fc-popover-title {
margin: 0;
font-size: 0.9375rem;
font-weight: 500;
}
}
// 👉 sidebar toggler
.fc-toolbar-chunk {
.fc-button-group {
align-items: center;
.fc-button .fc-icon {
vertical-align: bottom;
}
// Below two `background-image` styles contains static color due to browser limitation of not parsing the css var inside CSS url()
.fc-drawerToggler-button {
display: none;
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' stroke='rgba(47,43,61,0.9)' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round' class='css-i6dzq1'%3E%3Cpath d='M3 12h18M3 6h18M3 18h18'/%3E%3C/svg%3E");
background-position: 50%;
background-repeat: no-repeat;
block-size: 1.5625rem;
font-size: 0;
inline-size: 1.5625rem;
margin-inline-end: 0.25rem;
@media (max-width: 1279px) {
display: block !important;
}
}
}
}
// Workaround of https://github.com/fullcalendar/fullcalendar/issues/6407
.fc-col-header,
.fc-daygrid-body,
.fc-scrollgrid-sync-table,
.fc-timegrid-body,
.fc-timegrid-body table {
inline-size: 100% !important;
}
// Remove event margin in week view inside day column
.fc-timegrid-col-events {
.fc-event {
padding-block: 8px !important;
}
}
.fc-timeGridWeek-view .fc-timegrid-slot-minor {
border-block-start-style: none;
}
}
.v-theme--dark .fc .fc-toolbar-chunk .fc-button-group .fc-drawerToggler-button {
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' stroke='rgba(225,222,245,0.9)' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round' class='css-i6dzq1'%3E%3Cpath d='M3 12h18M3 6h18M3 18h18'/%3E%3C/svg%3E");
}
.v-theme--dark .fc .fc-toolbar-chunk .fc-button-group .fc-drawerToggler-button {
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' stroke='rgba(232,232,241,0.68)' stroke-width='2' fill='none' stroke-linecap='round' stroke-linejoin='round' class='css-i6dzq1'%3E%3Cpath d='M3 12h18M3 6h18M3 18h18'/%3E%3C/svg%3E");
}

View File

@@ -0,0 +1,94 @@
@use "shepherd.js/dist/css/shepherd.css";
@use "@core-scss/base/mixins";
@use "@styles/variables/_vuetify.scss" as variables;
.shepherd-button {
border-radius: variables.$button-border-radius;
block-size: 1.75rem;
color: #fff;
font-size: 0.8125rem;
font-weight: variables.$button-font-weight;
margin-inline-end: 0.75rem;
padding-block: 0.25rem;
padding-inline: 1rem;
&:not(:disabled):hover {
color: #fff;
}
}
.shepherd-footer {
background: rgb(var(--v-theme-background));
padding-block: 0.5rem 1rem;
padding-inline: 1rem;
}
.shepherd-element .shepherd-content .shepherd-header {
background: rgb(var(--v-theme-background));
padding-block: 1rem 0;
padding-inline: 1rem;
}
.shepherd-element .shepherd-content .shepherd-header .shepherd-title {
color: rgb(var(--v-theme-on-background));
font-size: 1.125rem;
font-weight: 500;
}
.shepherd-text {
padding: 1rem;
background: rgb(var(--v-theme-background));
color: rgb(var(--v-theme-on-background));
font-size: variables.$card-text-font-size;
}
.shepherd-cancel-icon {
color: rgba(var(--v-theme-on-background), var(--v-disabled-opacity)) !important;
font-size: 1.5rem;
}
.shepherd-element[data-popper-placement^="bottom"] {
margin-block-start: 0.75rem !important;
}
.shepherd-element[data-popper-placement^="top"] {
margin-block-start: -0.75rem !important;
}
.shepherd-element[data-popper-placement^="right"] {
margin-inline-start: 0.75rem !important;
}
.shepherd-element[data-popper-placement^="left"] {
margin-inline-end: 0.75rem !important;
}
.shepherd-element[data-popper-placement] {
.shepherd-arrow::before {
background: rgb(var(--v-theme-background)) !important;
}
}
.shepherd-element {
border-radius: variables.$card-border-radius;
background: transparent;
@include mixins.elevation(6);
}
.nextBtnClass,
.nextBtnClass:not(:disabled):hover {
background: rgb(var(--v-theme-primary));
}
.backBtnClass,
.backBtnClass:not(:disabled):hover {
background: rgba(var(--v-theme-secondary), var(--v-activated-opacity));
color: rgb(var(--v-theme-secondary));
}
@media screen and (max-width: 600px) {
.shepherd-element {
max-inline-size: 75vw;
}
}

View File

@@ -0,0 +1,5 @@
swiper-container {
--swiper-navigation-color: rgb(var(--v-theme-primary));
--swiper-navigation-size: 1.75rem;
--swiper-pagination-color: rgb(var(--v-theme-primary));
}

View File

@@ -0,0 +1,348 @@
@use "sass:math";
$font-family-custom: "Public Sans",sans-serif,-apple-system,blinkmacsystemfont,
"Segoe UI",roboto,"Helvetica Neue",arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";
/* 👉 Typography custom variables */
$typography-h5-font-size: 1.125rem;
$typography-body-1-font-size: 0.9375rem;
$typography-body-1-line-height: 1.375rem;
@forward "../../../base/libs/vuetify/variables" with (
$body-font-family: $font-family-custom !default,
$border-radius-root: 6px !default,
// 👉 Rounded
$rounded: (
"sm": 4px,
"lg": 8px,
"shaped": 30px 0,
) !default,
// 👉 Shadows
$shadow-key-umbra: (
0: (0 0 0 0 rgba(var(--v-shadow-key-umbra-color), 1)),
1: (0 2px 4px rgba(var(--v-shadow-key-umbra-color), 0.12)),
2: (0 1px 6px rgba(var(--v-shadow-key-umbra-color), var(--v-shadow-xs-opacity))),
3: (0 3px 8px rgba(var(--v-shadow-key-umbra-color), 0.14)),
4: (0 2px 8px rgba(var(--v-shadow-key-umbra-color), var(--v-shadow-sm-opacity))),
5: (0 4px 10px rgba(var(--v-shadow-key-umbra-color), 0.15)),
6: (0 3px 12px rgba(var(--v-shadow-key-umbra-color), var(--v-shadow-md-opacity))),
7: (0 4px 18px rgba(var(--v-shadow-key-umbra-color), 0.1)),
8: (0 4px 18px rgba(var(--v-shadow-key-umbra-color), var(--v-shadow-lg-opacity))),
9: (0 5px 14px rgba(var(--v-shadow-key-umbra-color), 0.18)),
10: (0 5px 30px rgba(var(--v-shadow-key-umbra-color), var(--v-shadow-xl-opacity))),
11: (0 5px 16px rgba(var(--v-shadow-key-umbra-color), 0.2)),
12: (0 6px 17px rgba(var(--v-shadow-key-umbra-color), 0.22)),
13: (0 6px 18px rgba(var(--v-shadow-key-umbra-color), 0.22)),
14: (0 6px 19px rgba(var(--v-shadow-key-umbra-color), 0.24)),
15: (0 7px 20px rgba(var(--v-shadow-key-umbra-color), 0.24)),
16: (0 7px 21px rgba(var(--v-shadow-key-umbra-color), 0.26)),
17: (0 7px 22px rgba(var(--v-shadow-key-umbra-color), 0.26)),
18: (0 8px 23px rgba(var(--v-shadow-key-umbra-color), 0.28)),
19: (0 8px 24px 6px rgba(var(--v-shadow-key-umbra-color), 0.28)),
20: (0 9px 25px rgba(var(--v-shadow-key-umbra-color), 0.3)),
21: (0 9px 26px rgba(var(--v-shadow-key-umbra-color), 0.32)),
22: (0 9px 27px rgba(var(--v-shadow-key-umbra-color), 0.32)),
23: (0 10px 28px rgba(var(--v-shadow-key-umbra-color), 0.34)),
24: (0 10px 30px rgba(var(--v-shadow-key-umbra-color), 0.34))
) !default,
$shadow-key-penumbra: (
0: (0 0 transparent),
1: (0 0 transparent),
2: (0 0 transparent),
3: (0 0 transparent),
4: (0 0 transparent),
5: (0 0 transparent),
6: (0 0 transparent),
7: (0 0 transparent),
8: (0 0 transparent),
9: (0 0 transparent),
10: (0 0 transparent),
11: (0 0 transparent),
12: (0 0 transparent),
13: (0 0 transparent),
14: (0 0 transparent),
15: (0 0 transparent),
16: (0 0 transparent),
17: (0 0 transparent),
18: (0 0 transparent),
19: (0 0 transparent),
20: (0 0 transparent),
21: (0 0 transparent),
22: (0 0 transparent),
23: (0 0 transparent),
24: (0 0 transparent),
) !default,
$shadow-key-ambient: (
0: (0 0 transparent),
1: (0 0 transparent),
2: (0 0 transparent),
3: (0 0 transparent),
4: (0 0 transparent),
5: (0 0 transparent),
6: (0 0 transparent),
7: (0 0 transparent),
8: (0 0 transparent),
9: (0 0 transparent),
10: (0 0 transparent),
11: (0 0 transparent),
12: (0 0 transparent),
13: (0 0 transparent),
14: (0 0 transparent),
15: (0 0 transparent),
16: (0 0 transparent),
17: (0 0 transparent),
18: (0 0 transparent),
19: (0 0 transparent),
20: (0 0 transparent),
21: (0 0 transparent),
22: (0 0 transparent),
23: (0 0 transparent),
24: (0 0 transparent),
) !default,
// 👉 Typography
$typography: (
"h1": (
"size": 2.875rem,
"weight": 500,
"line-height": 4.25rem,
"letter-spacing": normal
),
"h2": (
"size": 2.375rem,
"weight": 500,
"line-height": 3.5rem,
"letter-spacing": normal
),
"h3": (
"size": 1.75rem,
"weight": 500,
"line-height": 2.625rem
),
"h4": (
"size": 1.5rem,
"weight": 500,
"line-height": 2.375rem,
"letter-spacing": normal
),
"h5": (
"size": $typography-h5-font-size,
"weight": 500,
"line-height": 1.75rem
),
"h6":(
"size": 0.9375rem,
"line-height": 1.375rem,
"letter-spacing": normal
),
"body-1":(
"size": $typography-body-1-font-size,
"line-height": $typography-body-1-line-height,
"letter-spacing": normal
),
"body-2": (
"size": 0.8125rem,
"line-height": 1.25rem,
"letter-spacing": normal
),
"subtitle-1":(
"size": 0.9375rem,
"weight": 400,
"line-height": 1.375rem
),
"subtitle-2": (
"size": 0.8125rem,
"weight": 400,
"line-height": 1.25rem,
"letter-spacing": normal
),
"button": (
"size": 0.9375rem,
"weight": 500,
"line-height": 1.125rem,
"letter-spacing": 0.0269rem,
"text-transform": capitalize
),
"caption":(
"size": 0.8125rem,
"line-height": 1.125rem,
"letter-spacing": 0.025rem
),
"overline": (
"size": 0.75rem,
"weight": 400,
"line-height": 0.875rem,
"letter-spacing": 0.05rem,
),
) !default,
// 👉 Alert
$alert-title-font-size: 1.125rem !default,
$alert-title-line-height: 1.5rem !default,
$alert-border-opacity: 0.38 !default,
// 👉 Badge
$badge-dot-height: 8px !default,
$badge-dot-width: 8px !default,
$badge-min-width: 24px !default,
$badge-height: 1.5rem !default,
$badge-font-size: 0.8125rem !default,
$badge-border-radius: 12px !default,
$badge-border-color: rgb(var(--v-theme-surface)) !default,
$badge-border-transform: scale(1.5) !default,
$badge-dot-border-width: 2px !default,
// 👉 Chip
$chip-font-size: 13px !default,
$chip-font-weight: 500 !default,
$chip-label-border-radius: 0.375rem !default,
$chip-height: 32px !default,
$chip-close-size: 1.25rem !default,
$chip-elevation: 0 !default,
// 👉 Button
$button-height: 38px !default,
$button-padding-ratio: 1.9 !default,
$button-line-height: 1.375rem !default,
$button-disabled-opacity: 0.45 !default,
$button-disabled-overlay: 0.2025 !default,
$button-icon-font-size: 0.9375rem !default,
// 👉 Button Group
$btn-group-border-radius: 8px !default,
// 👉 Dialog
$dialog-card-header-padding: 24px 24px 0 !default,
$dialog-card-header-text-padding-top: 24px !default,
$dialog-card-text-padding: 24px !default,
$dialog-elevation: 8 !default,
// 👉 Card
$card-title-font-size: $typography-h5-font-size !default,
$card-text-font-size: $typography-body-1-font-size !default,
$card-subtitle-font-size: 0.9375rem !default,
$card-subtitle-header-padding: 0 !default,
$card-subtitle-line-height: 1.375rem !default,
$card-title-line-height: 1.75rem !default,
$card-text-padding: 24px !default,
$card-text-line-height: 1.375rem !default,
$card-item-padding: 24px !default,
$card-elevation: 6 !default,
// 👉 Carousel
$carousel-dot-margin: 0 !default,
$carousel-dot-inactive-opacity: 0.4 !default,
// 👉 Expansion Panel
$expansion-panel-title-padding: 12px 20px 12px 24px !default,
$expansion-panel-color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity)) !default,
$expansion-panel-active-title-min-height: 46px !default,
$expansion-panel-title-min-height: 46px !default,
$expansion-panel-text-padding: 0 20px 20px 24px !default,
// 👉 Field
$field-font-size: 0.9375rem !default,
$input-density: ("default": -2, "comfortable": -4.5, "compact": -6.5) !default,
$field-outline-opacity: 0.22 !default,
$field-border-width: 1px !default,
$field-focused-border-width: 2px !default,
$field-control-affixed-padding: 14px !default,
// 👉 Input
$input-details-padding-above: 4px !default,
$input-details-font-size: 0.8125rem !default,
// 👉 List
$list-density: ("default": 0, "comfortable": -1.5, "compact": -2.5) !default,
$list-border-radius: 6px !default,
$list-item-padding: 8px 20px !default,
$list-item-icon-margin-end: 10px !default,
$list-item-icon-margin-start : 12px !default,
$list-item-subtitle-line-height: 20px !default,
$list-subheader-font-size: 13px !default,
$list-subheader-line-height: 1.25rem !default,
$list-subheader-padding-end: 20px !default,
$list-subheader-min-height: 40px !default,
$list-item-avatar-margin-start: 12px !default,
$list-item-avatar-margin-end: 12px !default,
$list-disabled-opacity: 0.4,
// 👉 label
$label-font-size: 0.9375rem !default,
// 👉 message
$messages-font-size: 13px !default,
// 👉 menu
$menu-elevation: 8 !default,
// 👉 navigation drawer
$navigation-drawer-temporary-elevation: 8 !default,
// 👉 pagination
$pagination-item-margin: 0.1875rem !default,
// 👉 Progress Linear
$progress-linear-background-opacity: 1 !default,
// 👉 Radio
$radio-group-label-selection-group-padding-inline: 0 !default,
// 👉 slider
$slider-thumb-hover-opacity: var(--v-activated-opacity) !default,
$slider-thumb-label-padding: 2px 10px !default,
$slider-thumb-label-font-size: 0.8125rem !default,
$slider-track-active-size: 6px !default,
// 👉 select
$select-chips-margin-bottom: ("default": 1, "comfortable": 1, "compact": 1) !default,
// 👉 snackbar
$snackbar-background: rgb(var(--v-tooltip-background)) !default,
$snackbar-color: rgb(var(--v-theme-surface)) !default,
$snackbar-content-padding: 12px 16px !default,
$snackbar-font-size: 0.8125rem !default,
$snackbar-elevation: 2 !default,
$snackbar-wrapper-min-height:44px !default,
$snackbar-btn-padding: 0 9px !default,
$snackbar-action-margin: 16px !default,
// 👉 switch
$switch-inset-track-width: 1.875rem !default,
$switch-inset-track-height: 1.125rem !default,
$switch-inset-thumb-height: 0.875rem !default,
$switch-inset-thumb-width: 0.875rem !default,
$switch-inset-thumb-off-height: 0.875rem !default,
$switch-inset-thumb-off-width: 0.875rem !default,
$switch-thumb-elevation: 2 !default,
$switch-track-opacity: 1 !default,
$switch-track-background: rgba(var(--v-theme-on-surface), var(--v-focus-opacity)) !default,
$switch-thumb-background: rgb(var(--v-theme-on-primary)),
// 👉 table
$table-row-height: 50px !default,
$table-color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity)) !default,
$table-font-size: 0.9375rem !default,
// 👉 tabs
$tabs-height: 42px !default,
$tab-min-width: 50px !default,
// 👉 tooltip
$tooltip-background-color: rgb(var(--v-tooltip-background)) !default,
$tooltip-text-color: rgb(var(--v-theme-surface)) !default,
$tooltip-font-size: 0.8125rem !default,
$tooltip-border-radius: 0.25rem !default,
$tooltip-padding: 5px 12px !default,
// 👉 timeline
$timeline-dot-size: 34px !default,
$timeline-dot-divider-background: rgba(var(--v-border-color),0.08) !default,
$timeline-divider-line-background: rgba(var(--v-border-color), var(--v-border-opacity)) !default,
$timeline-divider-line-thickness: 1.5px !default,
$timeline-item-padding: 16px !default,
);

View File

@@ -0,0 +1,114 @@
@use "@core-scss/base/mixins";
@use "@configured-variables" as variables;
/* 👉 Alert
/ custom icon styling */
$alert-prepend-icon-font-size: 1.375rem !important;
.v-alert {
.v-alert__content {
line-height: 1.375rem;
}
&:not(.v-alert--prominent) .v-alert__prepend {
block-size: 1.875rem !important;
inline-size: 1.875rem !important;
.v-icon {
margin: auto;
block-size: 1.375rem !important;
font-size: 1.375rem !important;
inline-size: 1.375rem !important;
}
}
.v-alert-title {
margin-block-end: 0.25rem;
}
.v-alert__close {
.v-btn--icon {
.v-icon {
block-size: 1.25rem;
font-size: 1.25rem;
inline-size: 1.25rem;
}
.v-btn__overlay,
.v-ripple__container {
opacity: 0;
}
}
}
&:not(.v-alert--prominent) {
/* stylelint-disable-next-line no-duplicate-selectors */
.v-alert__prepend {
border-radius: 0.375rem;
}
&.v-alert--variant-flat,
&.v-alert--variant-elevated {
.v-alert__prepend {
background-color: #fff;
@include mixins.elevation(2);
}
}
&.v-alert--variant-tonal {
.v-alert__prepend {
z-index: 1;
background-color: rgb(var(--v-theme-surface));
}
}
}
}
.v-alert.v-alert--density-compact {
border-radius: 0.25rem;
}
.v-alert.v-alert--density-default {
border-radius: 0.5rem;
}
@each $color-name in variables.$theme-colors-name {
.v-alert {
&:not(.v-alert--prominent) {
&.bg-#{$color-name},
&.text-#{$color-name} {
.v-alert__prepend .v-icon {
color: rgb(var(--v-theme-#{$color-name})) !important;
}
}
&.v-alert--variant-tonal {
&.text-#{$color-name},
&.bg-#{$color-name} {
.v-alert__underlay {
background: rgb(var(--v-theme-#{$color-name})) !important;
}
.v-alert__prepend {
background-color: rgb(var(--v-theme-#{$color-name}));
.v-icon {
color: #fff !important;
}
}
}
}
&.v-alert--variant-outlined {
&.text-#{$color-name},
&.bg-#{$color-name} {
.v-alert__prepend {
background-color: rgba(var(--v-theme-#{$color-name}), 0.16);
}
}
}
}
}
}

View File

@@ -0,0 +1,27 @@
@use "@core-scss/base/mixins";
// 👉 Avatar
body {
.v-avatar {
.v-icon {
block-size: 1.5rem;
inline-size: 1.5rem;
}
&.v-avatar--variant-tonal:not([class*="text-"]) {
.v-avatar__underlay {
--v-activated-opacity: 0.08;
}
}
}
.v-avatar-group {
> * {
&:hover {
transform: translateY(-5px) scale(1);
@include mixins.elevation(6);
}
}
}
}

View File

@@ -0,0 +1,25 @@
@use "@configured-variables" as variables;
// 👉 Badge
.v-badge {
.v-badge__badge .v-icon {
font-size: 0.9375rem;
}
&.v-badge--bordered:not(.v-badge--dot) {
.v-badge__badge {
&::after {
transform: scale(1.05);
}
}
}
&.v-badge--tonal {
@each $color-name in variables.$theme-colors-name {
.v-badge__badge.bg-#{$color-name} {
background-color: rgba(var(--v-theme-#{$color-name}), 0.16) !important;
color: rgb(var(--v-theme-#{$color-name})) !important;
}
}
}
}

View File

@@ -0,0 +1,280 @@
@use "sass:list";
@use "sass:map";
@use "@core-scss/template/mixins" as templateMixins;
@use "@configured-variables" as variables;
/* 👉 Button
Above map but opacity values as key and variant as value */
$btn-active-overlay-opacity: (
0.08: (outlined, flat, text, plain),
0.24: (tonal),
);
$btn-hover-overlay-opacity: (
0: (elevated),
0.08: (outlined, flat, text, plain),
0.24: (tonal),
);
$btn-focus-overlay-opacity: (
0.08: (outlined, flat, text, plain),
0.24: (tonal),
);
body .v-btn {
// This is necessary because as we have darker overlay on hover for elevated variant, button text doesn't get dimmed
// This style is already applied to `.v-icon`
.v-btn__content {
z-index: 0;
}
transition: all 0.135s ease; /* Add transition */
&:active {
transform: scale(0.98);
}
// Add transition on hover
&:not(.v-btn--loading) .v-btn__overlay {
transition: opacity 0.15s ease-in-out;
will-change: opacity;
}
// box-shadow
@each $color-name in variables.$theme-colors-name {
&:not(.v-btn--disabled) {
&.bg-#{$color-name}.v-btn--variant-elevated {
&,
&:hover,
&:active,
&:focus {
@include templateMixins.custom-elevation(var(--v-theme-#{$color-name}), "sm");
}
}
}
}
/*
Loop over $btn-active-overlay-opacity map and add active styles for each variant.
Group variants with same opacity value.
*/
@each $opacity, $variants in $btn-active-overlay-opacity {
$overlay-selectors: ();
$underlay-selectors: ();
// append each variant to selectors list
@each $variant in $variants {
$overlay-selectors: list.append($overlay-selectors, "&.v-btn--variant-#{$variant}:active > .v-btn__overlay,");
$underlay-selectors: list.append($underlay-selectors, "&.v-btn--variant-#{$variant}:active > .v-btn__underlay,");
}
#{$overlay-selectors} {
--v-hover-opacity: #{$opacity};
opacity: var(--v-hover-opacity);
}
#{$underlay-selectors} {
opacity: 0;
}
}
@each $opacity, $variants in $btn-focus-overlay-opacity {
$selectors: ();
// append each variant to selectors list
@each $variant in $variants {
$selectors: list.append($selectors, "&.v-btn--variant-#{$variant}:focus > .v-btn__overlay,");
}
#{$selectors} {
opacity: $opacity;
}
}
/*
Loop over $btn-hover-overlay-opacity map and add hover styles for each variant.
Group variants with same opacity value.
*/
@each $opacity, $variants in $btn-hover-overlay-opacity {
$selectors: ();
// append each variant to selectors list
@each $variant in $variants {
$selectors: list.append($selectors, "&.v-btn--variant-#{$variant}:hover > .v-btn__overlay,");
}
#{$selectors} {
--v-hover-opacity: #{$opacity};
}
}
// Default (elevated) button
&--variant-elevated,
&--variant-flat {
// We want a darken color on hover
&:not(.v-btn--loading, .v-btn--disabled) {
@each $color-name in variables.$theme-colors-name {
&.bg-#{$color-name} {
&:hover,
&:active,
&:focus {
background-color: rgb(var(--v-theme-#{$color-name}-darken-1)) !important;
}
}
}
}
}
// Outlined button
&:not(.v-btn--icon, .v-tab).v-btn--variant-text {
&.v-btn--size-default {
padding-inline: 0.75rem;
}
&.v-btn--size-small {
padding-inline: 0.5625rem;
}
&.v-btn--size-large {
padding-inline: 1rem;
}
}
// Button border-radius
&:not(.v-btn--icon).v-btn--size-x-small {
border-radius: 2px;
}
&:not(.v-btn--icon).v-btn--size-small {
border-radius: 4px;
line-height: 1.125rem;
padding-block: 0;
padding-inline: 0.875rem;
}
&:not(.v-btn--icon).v-btn--size-default {
.v-btn__content,
.v-btn__append,
.v-btn__prepend {
.v-icon {
--v-icon-size-multiplier: 0.7113;
block-size: 1rem;
font-size: 1rem;
inline-size: 1rem;
}
.v-icon--start {
margin-inline: -2px 6px;
}
.v-icon--end {
margin-inline: 6px -2px;
}
}
}
&:not(.v-btn--icon).v-btn--size-large {
--v-btn-height: 3rem;
border-radius: 8px;
line-height: 1.625rem;
padding-block: 0;
padding-inline: 1.625rem;
}
&:not(.v-btn--icon).v-btn--size-x-large {
border-radius: 10px;
}
// icon buttons
&.v-btn--icon.v-btn--density-default {
block-size: var(--v-btn-height);
inline-size: var(--v-btn-height);
&.v-btn--size-default {
.v-icon {
--v-icon-size-multiplier: 0.978 !important;
block-size: 1.375rem;
font-size: 1.375rem;
inline-size: 1.375rem;
}
}
&.v-btn--size-small {
--v-btn-height: 2.125rem;
.v-icon {
block-size: 1.25rem;
font-size: 1.25rem;
inline-size: 1.25rem;
}
}
&.v-btn--size-large {
--v-btn-height: 2.625rem;
.v-icon {
block-size: 1.75rem;
font-size: 1.75rem;
inline-size: 1.75rem;
}
}
}
&-group.v-btn-toggle {
.v-btn {
border-radius: 0.5rem;
block-size: 52px !important;
border-inline-end: none;
inline-size: 52px !important;
&.v-btn--density-comfortable {
border-radius: 0.375rem;
block-size: 44px !important;
inline-size: 44px !important;
}
&.v-btn--density-compact {
border-radius: 0.25rem;
block-size: 36px !important;
inline-size: 36px !important;
}
&.v-btn--icon .v-icon {
block-size: 1.5rem;
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
font-size: 1.5rem;
inline-size: 1.5rem;
}
&.v-btn--icon.v-btn--active {
.v-icon {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
}
}
}
&.v-btn-group {
align-items: center;
padding: 7px;
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
block-size: 66px;
.v-btn.v-btn--active {
.v-btn__overlay {
--v-activated-opacity: 0.08;
}
}
&.v-btn-group--density-compact {
block-size: 50px;
}
&.v-btn-group--density-comfortable {
block-size: 58px;
}
}
}
}

View File

@@ -0,0 +1,3 @@
.v-card-subtitle {
color: rgba(var(--v-theme-on-background), 0.55);
}

View File

@@ -0,0 +1,65 @@
@use "sass:list";
@use "sass:map";
@use "@styles/variables/vuetify";
@use "@configured-variables" as variables;
// 👉 Checkbox
.v-checkbox {
// We adjusted it to vertically align the label
.v-selection-control--disabled {
--v-disabled-opacity: 0.45;
}
// Remove extra space below the label
.v-input__details {
min-block-size: unset !important;
padding-block-start: 0 !important;
}
}
// 👉 checkbox size and box shadow
.v-checkbox-btn {
// 👉 Checkbox icon opacity
.v-selection-control__input > .v-icon {
opacity: 1;
}
&.v-selection-control--dirty {
@each $color-name in variables.$theme-colors-name {
.v-selection-control__wrapper.text-#{$color-name} {
.v-selection-control__input {
/* Using filter: drop-shadow() instead of box-shadow because box-shadow creates white background for SVG; */
.v-icon {
filter: drop-shadow(0 2px 6px rgba(var(--v-theme-#{$color-name}), 0.3));
}
}
}
}
}
}
// checkbox icon size
.v-checkbox,
.v-checkbox-btn {
&.v-selection-control {
.v-selection-control__input {
svg {
font-size: 1.5rem;
}
}
.v-label {
color: rgba(var(--v-theme-on-background), var(--v-high-emphasis-opacity));
line-height: 1.375rem;
}
}
&:not(.v-selection-control--dirty) {
.v-selection-control__input {
> .custom-checkbox-indeterminate {
color: rgb(var(--v-theme-primary)) !important;
}
}
}
}

View File

@@ -0,0 +1,102 @@
// 👉 Chip
.v-chip {
line-height: 1.25rem;
.v-chip__close {
margin-inline: 4px -6px !important;
.v-icon {
opacity: 0.7;
}
}
.v-chip__content {
.v-icon {
block-size: 20px;
font-size: 20px;
inline-size: 20px;
}
}
&:not(.v-chip--variant-elevated) {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
}
&.v-chip--variant-elevated {
background-color: rgba(var(--v-theme-on-surface), var(--v-activated-opacity));
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
}
&:not([class*="text-"]) {
--v-activated-opacity: 0.08;
}
// common style for all sizes
&.v-chip--size-default,
&.v-chip--size-small {
.v-icon--start,
.v-chip__filter {
margin-inline-start: 0 !important;
}
&:not(.v-chip--pill) {
.v-avatar--start {
margin-inline: -6px 4px;
}
.v-avatar--end {
margin-inline: 4px -6px;
}
}
}
// small size
&:not(.v-chip--pill).v-chip--size-small {
--v-chip-height: 24px;
&.v-chip--label {
border-radius: 0.25rem;
}
font-size: 13px;
.v-avatar {
--v-avatar-height: 16px;
}
.v-chip__close {
font-size: 16px;
max-block-size: 16px;
max-inline-size: 16px;
}
}
// extra small size
&:not(.v-chip--pill).v-chip--size-x-small {
--v-chip-height: 20px;
&.v-chip--label {
border-radius: 0.25rem;
padding-inline: 0.625rem;
}
font-size: 13px;
.v-avatar {
--v-avatar-height: 16px;
}
.v-chip__close {
font-size: 16px;
max-block-size: 16px;
max-inline-size: 16px;
}
}
// default size
&:not(.v-chip--pill).v-chip--size-default {
.v-avatar {
--v-avatar-height: 20px;
}
}
}

View File

@@ -0,0 +1,27 @@
@use "@layouts/styles/mixins" as layoutsMixins;
// 👉 Dialog
body .v-dialog {
// dialog custom close btn
.v-dialog-close-btn {
border-radius: 0.375rem;
background-color: rgb(var(--v-theme-surface)) !important;
block-size: 2rem;
inline-size: 2rem;
inset-block-start: 0;
inset-inline-end: 0;
transform: translate(0.5rem, -0.5rem);
@include layoutsMixins.rtl {
transform: translate(-0.5rem, -0.5rem);
}
&:hover {
transform: translate(0.3125rem, -0.3125rem);
@include layoutsMixins.rtl {
transform: translate(-0.3125rem, -0.3125rem);
}
}
}
}

View File

@@ -0,0 +1,106 @@
@use "@core-scss/base/mixins";
@use "@layouts/styles/mixins" as layoutsMixins;
// 👉 Expansion panels
body .v-layout .v-application__wrap .v-expansion-panels {
.v-expansion-panel {
margin-block-start: 0 !important;
// expansion panel arrow font size
.v-expansion-panel-title {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
font-weight: 500;
.v-expansion-panel-title__icon {
transition: transform 0.2s ease-in-out;
.v-icon {
block-size: 1.25rem !important;
font-size: 1.25rem !important;
inline-size: 1.25rem !important;
}
}
}
.v-expansion-panel-title,
.v-expansion-panel-title--active,
.v-expansion-panel-title:hover,
.v-expansion-panel-title:focus,
.v-expansion-panel-title:focus-visible,
.v-expansion-panel-title--active:focus,
.v-expansion-panel-title--active:hover {
.v-expansion-panel-title__overlay {
opacity: 0 !important;
}
}
// Set Elevation when panel open
&:not(.v-expansion-panels--variant-accordion) {
&.v-expansion-panel--active {
.v-expansion-panel__shadow {
@include mixins.elevation(6);
}
}
}
}
// custom style for expansion panels
&.expansion-panels-width-border {
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
border-radius: 0.375rem;
.v-expansion-panel-title {
background-color: rgb(var(--v-theme-grey-light));
border-block-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
margin-block-end: -1px;
}
.v-expansion-panel-text {
.v-expansion-panel-text__wrapper {
padding: 1.25rem;
}
}
}
&:not(.no-icon-rotate, .expansion-panels-width-border) {
.v-expansion-panel {
.v-expansion-panel-title__icon {
.v-icon {
@include layoutsMixins.rtl {
transform: scaleX(-1);
}
}
}
&.v-expansion-panel--active {
.v-expansion-panel-title__icon {
transform: rotate(90deg);
@include layoutsMixins.rtl {
transform: rotate(-90deg);
}
}
}
}
}
&:not(.expansion-panels-width-border) {
.v-expansion-panel {
&:not(:last-child) {
margin-block-end: 0.5rem;
}
&:not(:first-child)::after {
content: none;
}
// we have to use below style of increase the specificity and override the default style
/* stylelint-disable-next-line no-descending-specificity */
&:first-child:not(:last-child),
&:not(:first-child, :last-child),
&:not(:first-child) {
border-radius: 0.375rem !important;
}
}
}
}

View File

@@ -0,0 +1,308 @@
@use "sass:map";
@use "@configured-variables" as variables;
@use "@core-scss/template/mixins" as templateMixins;
$v-input-density: (
comfortable: (
icon-size: 1rem,
font-size: 0.9375rem,
line-height: 1.5rem,
),
default: (
icon-size: 1.125rem,
font-size: 1.0625rem,
line-height: 1.5rem,
),
compact: (
icon-size: 0.8125rem,
font-size: 0.8125rem,
line-height: 1.375rem,
),
);
// 👉 VInput
.v-input {
// 👉 VField
.v-field {
.v-field__loader {
.v-progress-linear {
.v-progress-linear__background {
background-color: transparent !important;
}
}
}
&.v-field--variant-solo,
&.v-field--variant-filled {
--v-field-padding-top: 7px !important;
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
}
// Color for text field
.v-field__input {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
}
// Make field border width 2px when error
&.v-field--error {
.v-field__outline {
--v-field-border-width: 2px;
}
}
// Label
&.v-field--variant-outlined {
.v-label {
&.v-field-label--floating {
line-height: 0.9375rem;
margin-block: 0;
margin-inline: 6px;
}
}
}
&:not(.v-field--focused, .v-field--error):hover .v-field__outline {
--v-field-border-opacity: 0.6 !important;
}
// Shadow on focus
&.v-field--variant-outlined.v-field--focused:not(.v-field--error, .v-field--success) {
.v-field__outline {
@each $color-name in variables.$theme-colors-name {
&.text-#{$color-name} {
@include templateMixins.custom-elevation(var(--v-theme-#{$color-name}), "sm");
}
}
&:not([class*="text-"]) {
@include templateMixins.custom-elevation(var(--v-theme-primary), "sm");
}
}
}
}
// Give hint messages color based on theme color
@each $color-name in variables.$theme-colors-name {
&:has( .v-field.v-field--focused .v-field__outline.text-#{$color-name}) {
.v-messages {
color: rgb(var(--v-theme-#{$color-name}));
}
}
}
// Loop through each density setting in the map
@each $density, $settings in $v-input-density {
&.v-input--density-#{$density} {
.v-input__append,
.v-input__prepend,
.v-input__details,
.v-field .v-field__append-inner,
.v-field .v-field__prepend-inner,
.v-field .v-field__clearable {
> .v-icon {
block-size: map.get($settings, icon-size);
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
font-size: map.get($settings, icon-size);
inline-size: map.get($settings, icon-size);
opacity: 1;
}
}
.v-field {
.v-field__input {
font-size: map.get($settings, font-size);
line-height: map.get($settings, line-height);
}
}
}
}
}
// 👉 TextField, Select, AutoComplete, ComboBox, Textarea
// We added .v-application to increase the specificity of the selector
// Styles related to our custom input components
body {
.app-text-field,
.app-select,
.app-autocomplete,
.app-combobox,
.app-textarea,
.app-picker-field {
// making padding 0 for help text
.v-text-field .v-input__details {
padding-inline-start: 0;
}
// Placeholder
.v-input {
.v-field {
// Placeholder transition
input,
.v-field__input {
&::placeholder {
transition: transform 0.2s ease-out;
}
}
&.v-field--focused {
input,
.v-field__input {
&::placeholder {
transform: translateX(4px) !important;
[dir="rtl"] & {
transform: translateX(-4px) !important;
}
}
}
}
}
// padding for different density
&.v-input--density-default {
.v-field {
.v-field__input {
--v-field-padding-start: 16px;
--v-field-padding-end: 16px;
}
}
}
&.v-input--density-comfortable {
.v-field {
.v-field__input {
--v-field-padding-start: 14px;
--v-field-padding-end: 14px;
}
}
}
&.v-input--density-compact {
.v-field {
.v-field__input {
--v-field-padding-start: 12px;
--v-field-padding-end: 12px;
}
}
}
}
// Disabled state
&:has(.v-input.v-input--disabled) {
.v-label {
color: rgba(var(--v-theme-on-surface), 0.38);
}
.v-input {
.v-field.v-field--disabled {
background-color: rgba(var(--v-theme-on-surface), var(--v-hover-opacity));
opacity: 1;
.v-field__outline {
--v-field-border-opacity: 0.24;
}
.v-field__input {
color: rgba(var(--v-theme-on-surface), var(--v-disabled-opacity));
}
}
}
}
// Apply color to label
@each $color-name in variables.$theme-colors-name {
.v-label {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
&:has(+ .v-input .v-field.v-field--focused .v-field__outline.text-#{$color-name}) {
color: rgb(var(--v-theme-#{$color-name}));
}
&:has(+ .v-input .v-field.v-field--error) {
color: rgb(var(--v-theme-error));
}
}
}
}
@mixin style-selectable-component($component-name) {
.app-#{$component-name} {
.v-#{$component-name}__selection {
line-height: 24px;
margin-block: 0 !important;
}
// Vertical alignment of placeholder & text
.v-#{$component-name} .v-field .v-field__input > input {
align-self: center;
}
// Chips
.v-#{$component-name}.v-#{$component-name}--chips.v-input--dirty {
.v-#{$component-name}__selection {
margin: 0;
}
.v-field__input {
gap: 3px;
}
&.v-input--density-compact {
.v-field__input {
padding-inline-start: 0.5rem;
}
}
&.v-input--density-comfortable {
.v-field__input {
padding-inline-start: 0.75rem;
}
}
&.v-input--density-default {
.v-field__input {
padding-inline-start: 1rem;
}
}
}
}
}
@include style-selectable-component("autocomplete");
@include style-selectable-component("select");
@include style-selectable-component("combobox");
// AutoComplete
@at-root {
.app-autocomplete__content {
.v-list-item--active {
.v-autocomplete__mask {
background: rgba(92, 82, 192, 60%);
}
}
.v-theme--dark {
.v-list-item:not(.v-list-item--active) {
.v-autocomplete__mask {
background: rgba(59, 64, 92, 60%);
}
}
}
}
}
}
.app-inner-list {
// Hide checkboxes
.v-selection-control {
display: none;
}
}
// Hide resizer
::-webkit-resizer {
background: transparent;
}

View File

@@ -0,0 +1,30 @@
// 👉 List
.v-list-item {
--v-hover-opacity: 0.06 !important;
.v-checkbox-btn.v-selection-control--density-compact {
margin-inline-end: 0.5rem;
}
.v-list-item__overlay {
transition: none;
}
.v-list-item__prepend {
.v-icon {
font-size: 1.375rem;
}
}
&.v-list-item--active {
&.v-list-group__header {
color: rgb(var(--v-theme-primary));
}
&:not(.v-list-group__header) {
.v-list-item-subtitle {
color: rgb(var(--v-theme-primary));
}
}
}
}

View File

@@ -0,0 +1,35 @@
// Style list differently when it's used in a components like select, menu etc
.v-menu {
// Adjust padding of list item inside menu
.v-list-item {
padding-block: 8px !important;
padding-inline: 16px !important;
}
}
// 👉 Menu
// Menu custom style
.v-menu.v-overlay {
.v-overlay__content {
.v-list {
.v-list-item {
border-radius: 0.375rem !important;
margin-block: 0.125rem;
margin-inline: 0.5rem;
min-block-size: 2.375rem;
&:first-child {
margin-block-start: 0;
}
&:last-child {
margin-block-end: 0;
}
}
.v-list-item--density-default:not(.v-list-item--nav).v-list-item--one-line {
padding-block: 0.5rem;
}
}
}
}

View File

@@ -0,0 +1,17 @@
// otp input
.v-otp-input {
justify-content: unset !important;
.v-otp-input__content {
max-inline-size: 100%;
.v-field.v-field--focused {
.v-field__outline {
.v-field__outline__start,
.v-field__outline__end {
border-color: rgb(var(--v-theme-primary)) !important;
}
}
}
}
}

View File

@@ -0,0 +1,140 @@
/* stylelint-disable no-descending-specificity */
@use "@core-scss/template/mixins" as templateMixins;
@use "@configured-variables" as variables;
// 👉 Pagination
.v-pagination {
// pagination
.v-pagination__next,
.v-pagination__prev {
.v-btn--icon {
&.v-btn--size-small {
.v-icon {
font-size: 1rem;
}
}
&.v-btn--size-default {
.v-icon {
font-size: 1.125rem;
}
}
&.v-btn--size-large {
.v-icon {
font-size: 1.5rem;
}
}
}
}
// common style for all components
.v-pagination__next,
.v-pagination__prev,
.v-pagination__first,
.v-pagination__last,
.v-pagination__item {
.v-btn {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
font-size: 0.8125rem;
font-weight: 400;
line-height: 1;
--v-activated-opacity: 0.08;
&:hover {
.v-btn__overlay {
--v-hover-opacity: 0.16;
}
}
&.v-btn--disabled {
opacity: 0.45;
}
&.v-btn--size-large {
font-size: 0.9375rem;
}
}
}
// Disable scale animation for button
.v-pagination__item {
.v-btn {
transform: scale(1) !important;
/* We disabled transition because it looks ugly 🤮 */
transition-duration: 0s;
&:active {
transform: scale(1);
}
}
}
.v-pagination__list {
@each $color-name in variables.$theme-colors-name {
&:has(.v-pagination__item.v-pagination__item--is-active .v-btn.text-#{$color-name}) {
.v-pagination__item {
.v-btn {
&:hover {
color: rgb(var(--v-theme-#{$color-name}));
.v-btn__overlay {
background-color: rgb(var(--v-theme-#{$color-name}));
}
}
}
}
}
}
.v-pagination__item--is-active {
.v-btn {
&:not([class*="text-"]) {
color: rgb(var(--v-theme-primary));
&:not(.v-btn--variant-outlined) {
.v-btn__underlay {
--v-activated-opacity: 0.04;
}
}
&.v-btn--variant-outlined {
border-color: rgb(var(--v-theme-primary));
.v-btn__overlay {
opacity: 0.16;
}
}
}
// box-shadow
@each $color-name in variables.$theme-colors-name {
&:not(.v-btn--disabled) {
&.text-#{$color-name} {
&,
&:hover,
&:active,
&:focus {
@include templateMixins.custom-elevation(var(--v-theme-#{$color-name}), "sm");
}
.v-btn__underlay {
opacity: 1 !important;
}
.v-btn__content {
color: #fff;
}
&.v-btn--variant-outlined {
background-color: rgb(var(--v-theme-#{$color-name}));
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1,13 @@
// @use "@core-scss/template/mixins" as templateMixins;
@use "@configured-variables" as variables;
// 👉 Progress
// .v-progress-linear {
// .v-progress-linear__determinate {
// @each $color-name in variables.$theme-colors-name {
// &.bg-#{$color-name} {
// // @include templateMixins.custom-elevation(var(--v-theme-#{$color-name}), "sm");
// }
// }
// }
// }

View File

@@ -0,0 +1,46 @@
@use "@core-scss/base/mixins";
@use "@configured-variables" as variables;
// 👉 Radio
.v-radio,
.v-radio-btn {
// 👉 radio icon opacity
.v-selection-control__input > .v-icon {
opacity: 1;
}
&.v-selection-control--disabled {
--v-disabled-opacity: 0.45;
}
&.v-selection-control--dirty {
@each $color-name in variables.$theme-colors-name {
.v-selection-control__wrapper.text-#{$color-name} {
.v-selection-control__input {
/* Using filter: drop-shadow() instead of box-shadow because box-shadow creates white background for SVG; */
.v-icon {
filter: drop-shadow(0 2px 6px rgba(var(--v-theme-#{$color-name}), 0.3));
}
}
}
}
}
&.v-selection-control {
.v-selection-control__input {
svg {
font-size: 1.5rem;
}
}
.v-label {
color: rgba(var(--v-theme-on-background), var(--v-high-emphasis-opacity));
}
}
}
// 👉 Radio, Checkbox
.v-input.v-radio-group > .v-input__control > .v-label {
margin-inline-start: 0;
}

View File

@@ -0,0 +1,20 @@
// 👉 Rating
.v-rating {
.v-rating__wrapper {
.v-btn .v-icon {
--v-icon-size-multiplier: 1;
}
.v-btn--density-default {
--v-btn-height: 26px;
}
.v-btn--density-compact {
--v-btn-height: 30px;
}
.v-btn--density-comfortable {
--v-btn-height: 32px;
}
}
}

View File

@@ -0,0 +1,27 @@
// 👉 Slider
.v-slider {
.v-slider-track__background--opacity {
opacity: 0.16;
}
}
.v-slider-thumb {
.v-slider-thumb__surface::after {
border-radius: 50%;
background-color: #fff;
block-size: calc(var(--v-slider-thumb-size) - 10px);
inline-size: calc(var(--v-slider-thumb-size) - 10px);
}
.v-slider-thumb__label {
background-color: rgb(var(--v-tooltip-background));
color: rgb(var(--v-theme-surface));
font-weight: 500;
letter-spacing: 0.15px;
line-height: 1.25rem;
&::before {
content: none;
}
}
}

View File

@@ -0,0 +1,10 @@
// 👉 snackbar
.v-snackbar {
.v-snackbar__actions {
.v-btn {
font-size: 13px;
line-height: 18px;
text-transform: capitalize;
}
}
}

View File

@@ -0,0 +1,58 @@
@use "@configured-variables" as variables;
@use "@core-scss/template/mixins" as templateMixins;
// 👉 switch
.v-switch {
&.v-switch--inset {
.v-selection-control {
.v-switch__track {
transition: all 0.1s;
}
&.v-selection-control--dirty {
@each $color-name in variables.$theme-colors-name {
.v-switch__track.bg-#{$color-name} {
@include templateMixins.custom-elevation(var(--v-theme-#{$color-name}), "sm");
}
}
}
&:not(.v-selection-control--dirty) {
.v-switch__track {
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 16%) inset;
}
}
}
.v-selection-control__input {
transform: translateX(-6px) !important;
--v-selection-control-size: 0.875rem;
.v-switch__thumb {
box-shadow: 0 1px 6px rgba(var(--v-shadow-key-umbra-color), var(--v-shadow-xs-opacity));
transform: scale(1);
}
}
.v-selection-control--dirty {
.v-selection-control__input {
transform: translateX(6px) !important;
}
}
}
.v-label {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
line-height: 1.375rem !important;
}
}
.v-switch.v-input,
.v-checkbox-btn,
.v-radio-btn,
.v-radio {
--v-input-control-height: auto;
flex: unset;
}

View File

@@ -0,0 +1,48 @@
// 👉 Table
.v-table {
th {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity)) !important;
font-size: 0.8125rem;
letter-spacing: 0.2px;
text-transform: uppercase;
.v-data-table-header__content {
display: flex;
justify-content: space-between;
}
}
}
// 👉 Datatable
.v-data-table,
.v-table {
table {
thead,
tbody {
tr {
th,
td {
&:first-child:has(.v-checkbox-btn) {
padding-inline-start: 13px !important;
}
&:first-child {
padding-inline-start: 24px !important;
}
&:last-child {
padding-inline-end: 24px !important;
}
}
}
}
tbody {
.v-data-table-group-header-row {
td {
background-color: rgb(var(--v-theme-surface));
}
}
}
}
}

View File

@@ -0,0 +1,91 @@
@use "@configured-variables" as variables;
@use "@core-scss/template/mixins" as templateMixins;
// 👉 Tabs
.v-tabs {
&.v-tabs--vertical {
--v-tabs-height: 38px !important;
&:not(.v-tabs-pill) {
block-size: 100%;
border-inline-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
}
}
&.v-tabs--horizontal:not(.v-tabs-pill) {
border-block-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
.v-tab__slider {
block-size: 3px;
}
}
/* stylelint-disable-next-line no-descending-specificity */
.v-btn {
color: rgba(var(--v-theme-on-surface), var(--v-high-emphasis-opacity));
transform: none !important;
.v-icon {
block-size: 1.125rem !important;
font-size: 1.125rem !important;
inline-size: 1.125rem !important;
}
&:hover:not(.v-tab--selected) {
color: rgb(var(--v-theme-primary));
.v-btn__content {
.v-tab__slider {
opacity: var(--v-activated-opacity);
}
}
}
&.v-btn--stacked {
/* stylelint-disable-next-line no-descending-specificity */
.v-icon {
block-size: 1.5rem !important;
font-size: 1.5rem !important;
inline-size: 1.5rem !important;
}
}
/* stylelint-disable-next-line no-descending-specificity */
.v-btn__overlay,
.v-ripple__container {
opacity: 0 !important;
}
/* stylelint-disable-next-line no-descending-specificity */
.v-tab__slider {
inset-inline-end: 0;
inset-inline-start: unset;
}
}
}
// 👉 Tab Pill
.v-tabs.v-tabs-pill {
.v-slide-group__content {
gap: 0.25rem;
}
@each $color-name in variables.$theme-colors-name {
.v-tab--selected.text-#{$color-name} {
@include templateMixins.custom-elevation(var(--v-theme-#{$color-name}), "sm");
}
}
&.v-slide-group,
.v-slide-group__container {
box-sizing: content-box;
padding: 1rem;
margin: -1rem;
}
.v-tab.v-btn:not(.v-tab--selected) {
&:hover {
background-color: rgba(var(--v-theme-primary), var(--v-activated-opacity));
}
}
}

View File

@@ -0,0 +1,9 @@
.v-textarea {
textarea {
opacity: 0 !important;
}
& .v-field--active textarea {
opacity: 1 !important;
}
}

View File

@@ -0,0 +1,99 @@
@use "@configured-variables" as variables;
// 👉 Timeline
.v-timeline {
// timeline items
.v-timeline-item {
&:not(:last-child) {
.v-timeline-item__body {
margin-block-end: 0.5rem;
}
}
.app-timeline-title {
line-height: 1.375rem;
}
.app-timeline-meta {
font-size: 0.8125rem;
font-weight: 400;
letter-spacing: 0.025rem;
line-height: 1.125rem;
}
.app-timeline-text {
font-size: 0.9375rem;
font-weight: 400;
line-height: 1.375rem;
}
}
// timeline icon only
&.v-timeline-icon-only {
.v-timeline-divider__dot {
.v-timeline-divider__inner-dot {
background: rgb(var(--v-theme-background));
box-shadow: none;
}
}
}
&:not(.v-timeline--variant-outlined) .v-timeline-divider__dot {
background: none !important;
.v-timeline-divider__inner-dot {
box-shadow: 0 0 0 0.1875rem rgb(var(--v-theme-on-surface-variant));
@each $color-name in variables.$theme-colors-name {
&.bg-#{$color-name} {
box-shadow: 0 0 0 0.1875rem rgba(var(--v-theme-#{$color-name}), 0.12);
}
}
}
}
&.v-timeline--variant-outlined {
.v-timeline-item {
.v-timeline-divider {
.v-timeline-divider__dot {
background: none !important;
}
}
.v-timeline-divider__after {
border: 1.5px dashed rgba(var(--v-border-color), var(--v-border-opacity));
background: none;
}
.v-timeline-divider__before {
background: none;
}
}
}
// we have to override the default bg-color of the timeline dot in the card
.v-card:not(.v-card--variant-text, .v-card--variant-plain, .v-card--variant-outlined) & {
&.v-timeline-icon-only {
.v-timeline-divider__dot {
.v-timeline-divider__inner-dot {
/* stylelint-disable-next-line no-descending-specificity */
background: rgb(var(--v-theme-surface));
}
}
}
}
.v-card.v-card--variant-tonal & {
&.v-timeline-icon-only {
.v-timeline-divider__dot {
.v-timeline-divider__inner-dot {
/* stylelint-disable-next-line no-descending-specificity */
.v-icon {
background: none;
}
}
}
}
}
}

View File

@@ -0,0 +1,6 @@
// 👉 Tooltip
.v-tooltip {
.v-overlay__content {
font-weight: 500;
}
}

View File

@@ -0,0 +1,25 @@
@use "alert";
@use "avatar";
@use "button";
@use "badge";
@use "cards";
@use "chip";
@use "dialog";
@use "expansion-panels";
@use "list";
@use "menu";
@use "pagination";
@use "progress";
@use "rating";
@use "snackbar";
@use "slider";
@use "table";
@use "tabs";
@use "timeline";
@use "tooltip";
@use "otp-input";
@use "field";
@use "checkbox";
@use "textarea";
@use "radio";
@use "switch";

View File

@@ -0,0 +1,3 @@
@use "@core-scss/base/libs/vuetify";
@use "overrides";
@use "components/index.scss";

View File

@@ -0,0 +1,18 @@
@use "@core-scss/base/utils";
@use "@configured-variables" as variables;
// 👉 Body
// set body font size 15px
body {
font-size: 15px !important;
// We reduced this margin to get 40px input height
.v-input--density-compact {
--v-input-chips-margin-bottom: 1px;
}
}
.text-caption {
color: rgba(var(--v-theme-on-background), var(--v-disabled-opacity));
}

View File

@@ -0,0 +1,20 @@
.layout-blank {
.misc-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 1.25rem;
min-block-size: 100dvh;
}
.misc-avatar {
z-index: 1;
}
.misc-footer-img {
position: absolute;
inline-size: 100%;
inset-block-end: 0;
}
}

View File

@@ -0,0 +1,63 @@
.layout-blank {
.auth-wrapper {
min-block-size: 100dvh;
}
.auth-v1-top-shape,
.auth-v1-bottom-shape {
position: absolute;
}
.auth-footer-mask {
position: absolute;
inset-block-end: 0;
min-inline-size: 100%;
}
.auth-card {
z-index: 1 !important;
}
.auth-illustration {
z-index: 1;
}
.auth-v1-top-shape {
inset-block-start: -77px;
inset-inline-start: -45px;
}
.auth-v1-bottom-shape {
inset-block-end: -58px;
inset-inline-end: -58px;
}
@media (min-width: 1264px), (max-width: 959px) and (min-width: 450px) {
.v-otp-input .v-otp-input__content {
gap: 1rem;
}
}
}
@media (min-width: 960px) {
.skin--bordered {
.auth-card-v2 {
border-inline-start: 1px solid rgba(var(--v-border-color), var(--v-border-opacity)) !important;
}
}
}
.auth-logo {
position: absolute;
z-index: 2;
inset-block-start: 2rem;
inset-inline-start: 2.3rem;
}
.auth-title {
font-size: 1.375rem;
font-weight: 700;
letter-spacing: 0.25px;
line-height: 1.5rem;
text-transform: capitalize;
}

View File

@@ -0,0 +1,7 @@
%default-layout-horizontal-nav-navbar-and-nav-container {
box-shadow: 0 1px 4px 0 rgba(var(--v-shadow-key-umbra-color), 0.1);
&.header-blur {
background-color: rgb(var(--v-theme-surface), 0.96);
}
}

View File

@@ -0,0 +1,8 @@
@use "@configured-variables" as variables;
%default-layout-vertical-nav-floating-navbar-and-sticky-elevated-navbar-scrolled {
// If navbar is contained => Squeeze navbar content on scroll
@if variables.$layout-vertical-nav-navbar-is-contained {
padding-inline: 1.5rem;
}
}

View File

@@ -0,0 +1,47 @@
@use "@core-scss/base/mixins";
// Horizontal nav item icon (Including sub nav items)
%horizontal-nav-item-icon {
font-size: 1.375rem;
}
// Horizontal nav item styles (including nested)
%horizontal-nav-item {
padding-block: 0.5rem;
padding-inline: 1rem;
}
%nav-group-label-and-nav-link-style {
border-radius: 0.375rem;
margin-block: 0.125rem;
margin-inline: 0.5rem;
}
// Active styles for sub nav link
%horizontal-nav-sub-nav-link-active {
background: rgba(var(--v-theme-primary), 0.08);
// Remove before pseudo element from sub nav link to avoid overlapping with active state
&::before {
content: none;
}
}
// Popper content styles
%horizontal-nav-popper-content {
@include mixins.elevation(8);
}
// Top level horizontal nav item styles (`a` tag & group label)
%horizontal-nav-top-level-item {
border-radius: 0.375rem;
}
// Horizontal nav item title
%horizontal-nav-item-title {
line-height: 1.375rem;
}
%third-level-nav-item-icon {
margin-inline: 0 0.5rem;
}

View File

@@ -0,0 +1,6 @@
@forward "nav";
@forward "vertical-nav";
@forward "horizontal-nav";
@forward "default-layout-vertical-nav";
@forward "default-layout-horizontal-nav";
@forward "misc";

View File

@@ -0,0 +1,3 @@
%blurry-bg {
background-color: rgb(var(--v-theme-surface), 0.88);
}

View File

@@ -0,0 +1,27 @@
// This is common style that needs to be applied to both navs
%nav {
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
.nav-item-title {
letter-spacing: normal;
}
}
/*
Active nav link styles for horizontal & vertical nav
For horizontal nav it will be only applied to top level nav items
For vertical nav it will be only applied to nav links (not nav groups)
*/
%nav-link-active {
background: linear-gradient(270deg, rgba(var(--v-global-theme-primary), 0.7) 0%, rgb(var(--v-global-theme-primary)) 100%) !important;
box-shadow: 0 2px 6px rgba(var(--v-global-theme-primary), 0.3);
i {
color: rgb(var(--v-theme-on-primary)) !important;
}
html[dir="rtl"] &.router-link-exact-active {
background: linear-gradient(-270deg, rgba(var(--v-global-theme-primary), 0.7) 0%, rgb(var(--v-global-theme-primary)) 100%) !important;
}
}

View File

@@ -0,0 +1,40 @@
// Vertical nav item badge styles
%nav-header-action {
font-size: 0;
}
%vertical-nav-item-badge {
z-index: 1;
font-size: 0.8125rem;
line-height: 1.25rem;
margin-inline-end: 0.5rem;
padding-block: 0.125rem;
padding-inline: 0.625rem;
}
// This is same as `%vertical-nav-item` except section title is excluded
%vertical-nav-item-interactive {
border-radius: 0.375rem;
block-size: 2.375rem;
margin-block-end: 0.375rem;
}
%vertical-nav-items-icon-after-2nd-level {
margin-inline: 15px 0.8125rem;
visibility: visible;
}
// Section title
// Setting height will prevent jerking when text & icon is toggled
%vertical-nav-section-title {
block-size: 1.25rem;
font-size: 0.8125rem;
line-height: 1.125rem;
text-transform: uppercase;
}
// Icon styling for icon nested inside another nav item (2nd level)
%vertical-nav-items-nested-icon {
color: rgba(var(--v-theme-on-surface), var(--v-medium-emphasis-opacity));
}

View File

@@ -0,0 +1,82 @@
@use "sass:map";
@use "@core-scss/base/mixins";
@use "@configured-variables" as variables;
$header: ".layout-navbar";
@if variables.$layout-vertical-nav-navbar-is-contained {
$header: ".layout-navbar .navbar-content-container";
}
.skin--bordered {
// Expansion Panels
@include mixins.bordered-skin(
".v-expansion-panels:not(.expansion-panels-width-border) .v-expansion-panel, .v-expansion-panel__shadow"
);
// Navbar
// -- Vertical
@if variables.$layout-vertical-nav-navbar-is-contained {
@include mixins.bordered-skin(".layout-nav-type-vertical #{$header}");
.layout-nav-type-vertical.window-scrolled #{$header} {
border-block-start: 1px solid rgba(var(--v-border-color), var(--v-border-opacity)) !important;
}
}
/* stylelint-disable-next-line @stylistic/indentation */
@else {
@include mixins.bordered-skin(".layout-nav-type-vertical #{$header}", "border-bottom");
}
// Dialog close button
@include mixins.bordered-skin(".v-dialog-close-btn");
// Vertical Nav
.layout-vertical-nav {
box-shadow: none;
}
.v-expansion-panels.expansion-panels-width-border {
.v-expansion-panel__shadow {
box-shadow: none !important;
}
.v-expansion-panel {
border: none !important;
&:not(:last-child) {
margin-block-end: -1px;
}
&::after {
content: "";
}
}
}
// select remove box shadow
.v-select__content,
.v-combobox__content,
.v-autocomplete__content {
box-shadow: none;
}
.flatpickr-calendar {
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
box-shadow: none !important;
}
// calendar
.fc .fc-popover {
box-shadow: none;
}
// navigation drawer
.v-navigation-drawer:not(.app-customizer) {
box-shadow: none;
}
.shepherd-element {
box-shadow: none;
}
}

View File

@@ -0,0 +1 @@
@use "bordered";

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
// Write your overrides

View File

@@ -0,0 +1,6 @@
@forward "@core-scss/template/variables";
// Remove above import and uncomment below to override core variables.
// @forward "@core-scss/template/variables" with (
// $<variable-name>: <variable-value>
// )

View File

@@ -0,0 +1,7 @@
// ❗ Path must be relative
@forward "../@core/template/libs/vuetify/variables";
// Remove above import and uncomment below to override core variables.
// @forward "../@core/template/libs/vuetify/variables" with (
// $<variable-name>: <variable-value>
// )