mirror of
https://github.com/tabler/tabler.git
synced 2026-10-12 13:17:00 +04:00
474 lines
12 KiB
SCSS
474 lines
12 KiB
SCSS
// Datepicker
|
|
//
|
|
// Styles the `data-vc-*` markup that Vanilla Calendar Pro renders, the same way
|
|
// Bootstrap 6 does: the calendar grid is one set of tokens (`--calendar-*`),
|
|
// the popup surface the datepicker adds around it is another (`--datepicker-*`).
|
|
// An inline calendar renders unadorned and takes the surface of its container.
|
|
|
|
@use '../config' as *;
|
|
|
|
// stylelint-disable selector-max-attribute, selector-no-qualifying-type -- the plugin marks everything with data attributes
|
|
|
|
//
|
|
// Calendar grid
|
|
//
|
|
|
|
[data-vc='calendar'] {
|
|
--calendar-padding: #{$datepicker-calendar-padding};
|
|
--calendar-color: var(--body-color);
|
|
--calendar-font-size: #{$datepicker-calendar-font-size};
|
|
--calendar-header-font-weight: #{$datepicker-calendar-header-font-weight};
|
|
--calendar-weekday-color: var(--secondary);
|
|
--calendar-week-number-color: var(--secondary);
|
|
--calendar-week-number-border-color: var(--border-color);
|
|
--calendar-day-hover-bg: var(--hover-bg);
|
|
--calendar-day-selected-bg: var(--primary);
|
|
--calendar-day-selected-color: var(--primary-fg);
|
|
--calendar-day-today-bg: #{color-transparent(var(--body-color), 6%)};
|
|
--calendar-day-today-color: var(--primary);
|
|
--calendar-day-disabled-color: var(--disabled-color);
|
|
--calendar-day-size: #{$datepicker-calendar-day-size};
|
|
--calendar-day-font-size: #{$datepicker-calendar-day-font-size};
|
|
--calendar-border-radius: var(--border-radius);
|
|
position: relative;
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: fit-content;
|
|
padding: var(--calendar-padding);
|
|
font-family: inherit;
|
|
font-size: var(--calendar-font-size);
|
|
color: var(--calendar-color);
|
|
|
|
button {
|
|
font-family: inherit;
|
|
@include focus-ring-transition();
|
|
}
|
|
|
|
button:focus-visible {
|
|
position: relative;
|
|
z-index: 1;
|
|
@include focus-ring(true);
|
|
}
|
|
}
|
|
|
|
// Month navigation
|
|
[data-vc-arrow] {
|
|
position: relative;
|
|
display: block;
|
|
width: 2rem;
|
|
height: 2rem;
|
|
color: var(--calendar-color);
|
|
pointer-events: auto;
|
|
cursor: pointer;
|
|
background-color: transparent;
|
|
border: 0;
|
|
@include border-radius(var(--calendar-border-radius));
|
|
|
|
&::before {
|
|
position: absolute;
|
|
inset: 0.25rem;
|
|
content: '';
|
|
background-color: currentColor;
|
|
@include mask-icon(url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 16c-.3 0-.5-.1-.7-.3l-6-6c-.4-.4-.4-1 0-1.4s1-.4 1.4 0l5.3 5.3 5.3-5.3c.4-.4 1-.4 1.4 0s.4 1 0 1.4l-6 6c-.2.2-.4.3-.7.3'/></svg>"), $size: 1rem);
|
|
}
|
|
|
|
&:hover {
|
|
background-color: var(--calendar-day-hover-bg);
|
|
}
|
|
}
|
|
|
|
[data-vc-arrow='prev']::before {
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
[data-vc-arrow='next']::before {
|
|
transform: rotate(-90deg);
|
|
}
|
|
|
|
// The controls overlay the header, so they repeat the calendar's own inset to
|
|
// keep the arrows aligned with the content below.
|
|
[data-vc='controls'] {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
left: 0;
|
|
z-index: 20;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding-block-start: var(--calendar-padding);
|
|
padding-inline: var(--calendar-padding);
|
|
pointer-events: none;
|
|
}
|
|
|
|
[data-vc='grid'] {
|
|
display: flex;
|
|
flex-grow: 1;
|
|
flex-wrap: wrap;
|
|
gap: 1.75rem;
|
|
}
|
|
|
|
[data-vc='column'] {
|
|
display: flex;
|
|
flex-grow: 1;
|
|
flex-direction: column;
|
|
min-width: 240px;
|
|
}
|
|
|
|
// Header: month and year
|
|
[data-vc='header'] {
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 0.75rem;
|
|
}
|
|
|
|
[data-vc-header='content'] {
|
|
display: inline-flex;
|
|
flex-grow: 1;
|
|
align-items: center;
|
|
justify-content: center;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
[data-vc='month'],
|
|
[data-vc='year'] {
|
|
padding: 0.25rem 0.5rem;
|
|
margin-inline: -0.125rem;
|
|
font-size: var(--font-size-base, 1rem);
|
|
font-weight: var(--calendar-header-font-weight);
|
|
color: var(--calendar-color);
|
|
background-color: transparent;
|
|
border: 0;
|
|
@include border-radius(var(--calendar-border-radius));
|
|
|
|
&:disabled {
|
|
color: var(--calendar-day-disabled-color);
|
|
pointer-events: none;
|
|
}
|
|
|
|
&:hover:not(:disabled) {
|
|
background-color: var(--calendar-day-hover-bg);
|
|
}
|
|
}
|
|
|
|
// Holds the week numbers column, when enabled, next to the month
|
|
[data-vc='wrapper'] {
|
|
display: flex;
|
|
flex-grow: 1;
|
|
}
|
|
|
|
[data-vc='content'] {
|
|
display: flex;
|
|
flex-grow: 1;
|
|
flex-direction: column;
|
|
}
|
|
|
|
// Month and year views. The plugin wraps each set in role="row" and
|
|
// role="gridcell" elements, so the column grid goes on the row.
|
|
[data-vc='months'],
|
|
[data-vc='years'] {
|
|
display: flex;
|
|
flex-grow: 1;
|
|
flex-direction: column;
|
|
row-gap: 1rem;
|
|
}
|
|
|
|
[data-vc-months='row'],
|
|
[data-vc-years='row'] {
|
|
display: grid;
|
|
grid-template-columns: repeat(var(--calendar-columns, 4), minmax(0, 1fr));
|
|
column-gap: 0.25rem;
|
|
align-items: center;
|
|
}
|
|
|
|
[data-vc='years'] {
|
|
--calendar-columns: 5;
|
|
}
|
|
|
|
[data-vc-months='cell'],
|
|
[data-vc-years='cell'] {
|
|
display: flex;
|
|
}
|
|
|
|
[data-vc-months-month],
|
|
[data-vc-years-year] {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 100%;
|
|
height: 2.5rem;
|
|
padding: 0.25rem;
|
|
font-size: var(--calendar-day-font-size);
|
|
font-weight: var(--calendar-header-font-weight);
|
|
line-height: 1rem;
|
|
color: var(--calendar-weekday-color);
|
|
text-align: center;
|
|
word-break: break-all;
|
|
cursor: pointer;
|
|
background-color: transparent;
|
|
border: 0;
|
|
@include border-radius(var(--calendar-border-radius));
|
|
|
|
&:disabled {
|
|
color: var(--calendar-day-disabled-color);
|
|
pointer-events: none;
|
|
}
|
|
|
|
&:hover:not(:disabled) {
|
|
background-color: var(--calendar-day-hover-bg);
|
|
}
|
|
|
|
&[data-vc-months-month-selected],
|
|
&[data-vc-years-year-selected] {
|
|
color: var(--calendar-day-selected-color);
|
|
background-color: var(--calendar-day-selected-bg);
|
|
|
|
&:hover {
|
|
color: var(--calendar-day-selected-color);
|
|
background-color: var(--calendar-day-selected-bg);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Weekday header
|
|
[data-vc='week'] {
|
|
display: grid;
|
|
grid-template-columns: repeat(7, 1fr);
|
|
justify-items: center;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
[data-vc-week-day] {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 100%;
|
|
min-width: var(--calendar-day-size);
|
|
padding: 0;
|
|
margin: 0;
|
|
font-size: var(--calendar-day-font-size);
|
|
font-weight: var(--calendar-header-font-weight);
|
|
line-height: 1rem;
|
|
color: var(--calendar-weekday-color);
|
|
background-color: transparent;
|
|
border: 0;
|
|
}
|
|
|
|
button[data-vc-week-day] {
|
|
cursor: pointer;
|
|
}
|
|
|
|
// Week numbers: a column in front of the month, with a title that lines up
|
|
// with the weekday header and one number for each row of dates.
|
|
[data-vc-week='numbers'] {
|
|
display: flex;
|
|
flex-direction: column;
|
|
padding-inline-end: 0.5rem;
|
|
margin-inline-end: 0.5rem;
|
|
border-inline-end: var(--border-width) solid var(--calendar-week-number-border-color);
|
|
}
|
|
|
|
[data-vc-week-numbers='title'] {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-bottom: 0.5rem;
|
|
font-size: var(--calendar-day-font-size);
|
|
font-weight: var(--calendar-header-font-weight);
|
|
line-height: 1rem;
|
|
color: var(--calendar-week-number-color);
|
|
}
|
|
|
|
[data-vc-week-numbers='content'] {
|
|
display: grid;
|
|
grid-auto-rows: calc(var(--calendar-day-size) + 0.25rem);
|
|
align-items: center;
|
|
justify-items: center;
|
|
}
|
|
|
|
[data-vc-week-number] {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 100%;
|
|
min-width: var(--calendar-day-size);
|
|
font-size: var(--calendar-day-font-size);
|
|
font-weight: $font-weight-normal;
|
|
line-height: 1rem;
|
|
color: var(--calendar-week-number-color);
|
|
}
|
|
|
|
// Dates grid
|
|
[data-vc='dates'] {
|
|
pointer-events: none;
|
|
}
|
|
|
|
[data-vc-dates='row'] {
|
|
display: grid;
|
|
grid-template-columns: repeat(7, 1fr);
|
|
align-items: center;
|
|
justify-items: center;
|
|
width: 100%;
|
|
}
|
|
|
|
[data-vc-date] {
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 100%;
|
|
padding-top: 0.125rem;
|
|
padding-bottom: 0.125rem;
|
|
pointer-events: auto;
|
|
|
|
&:not(:has([data-vc-date-btn])),
|
|
&[data-vc-date-disabled],
|
|
&[data-vc-date-disabled] [data-vc-date-btn] {
|
|
pointer-events: none;
|
|
}
|
|
}
|
|
|
|
// A day paints its background from two variables: the colour a state picks
|
|
// and the opacity it gets. States change the variables, never `opacity`, so
|
|
// the date stays readable on a faded background.
|
|
[data-vc-date-btn] {
|
|
--calendar-day-bg: transparent;
|
|
--calendar-day-bg-opacity: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 100%;
|
|
min-width: var(--calendar-day-size);
|
|
height: 100%;
|
|
min-height: var(--calendar-day-size);
|
|
padding: 0;
|
|
font-size: var(--calendar-day-font-size);
|
|
font-weight: $font-weight-normal;
|
|
line-height: 1rem;
|
|
color: var(--calendar-color);
|
|
cursor: pointer;
|
|
background-color: color-transparent(var(--calendar-day-bg), var(--calendar-day-bg-opacity));
|
|
border: 0;
|
|
border-radius: var(--calendar-border-radius);
|
|
@include focus-ring-transition(color $transition-time, background-color $transition-time);
|
|
|
|
&:hover {
|
|
--calendar-day-bg: var(--calendar-day-hover-bg);
|
|
}
|
|
}
|
|
|
|
// Today
|
|
[data-vc-date-today] [data-vc-date-btn] {
|
|
font-weight: $font-weight-bold;
|
|
--calendar-day-bg: var(--calendar-day-today-bg);
|
|
color: var(--calendar-day-today-color);
|
|
}
|
|
|
|
// Days of the previous and next month
|
|
[data-vc-date-month='next'] [data-vc-date-btn],
|
|
[data-vc-date-month='prev'] [data-vc-date-btn] {
|
|
--calendar-day-bg-opacity: 50%;
|
|
color: var(--calendar-weekday-color);
|
|
}
|
|
|
|
[data-vc-date-disabled] [data-vc-date-btn] {
|
|
color: var(--calendar-day-disabled-color);
|
|
}
|
|
|
|
// Range selection: the hovered and selected runs join into one bar, so only the
|
|
// outer corners keep their radius. Logical corners follow the writing direction.
|
|
[data-vc-date-hover] [data-vc-date-btn] {
|
|
--calendar-day-bg: var(--calendar-day-hover-bg);
|
|
border-radius: 0;
|
|
}
|
|
|
|
[data-vc-date-hover='first'] [data-vc-date-btn] {
|
|
border-start-start-radius: var(--calendar-border-radius);
|
|
border-end-start-radius: var(--calendar-border-radius);
|
|
}
|
|
|
|
[data-vc-date-hover='last'] [data-vc-date-btn] {
|
|
border-start-end-radius: var(--calendar-border-radius);
|
|
border-end-end-radius: var(--calendar-border-radius);
|
|
}
|
|
|
|
[data-vc-date-hover='first-and-last'] [data-vc-date-btn] {
|
|
border-radius: var(--calendar-border-radius);
|
|
}
|
|
|
|
[data-vc-date-selected] [data-vc-date-btn] {
|
|
--calendar-day-bg: var(--calendar-day-selected-bg);
|
|
color: var(--calendar-day-selected-color);
|
|
}
|
|
|
|
// Inside a range only the two ends are solid; the days between keep their own
|
|
// text colour on a faint tint of the selected colour.
|
|
[data-vc-date-selected='middle'] [data-vc-date-btn] {
|
|
--calendar-day-bg-opacity: #{$datepicker-calendar-range-bg-opacity};
|
|
color: var(--calendar-color);
|
|
border-radius: 0;
|
|
}
|
|
|
|
[data-vc-date-selected='first'] [data-vc-date-btn] {
|
|
border-start-start-radius: var(--calendar-border-radius);
|
|
border-start-end-radius: 0;
|
|
border-end-start-radius: var(--calendar-border-radius);
|
|
border-end-end-radius: 0;
|
|
}
|
|
|
|
[data-vc-date-selected='last'] [data-vc-date-btn] {
|
|
border-start-start-radius: 0;
|
|
border-start-end-radius: var(--calendar-border-radius);
|
|
border-end-start-radius: 0;
|
|
border-end-end-radius: var(--calendar-border-radius);
|
|
}
|
|
|
|
[data-vc-date-selected='first-and-last'] [data-vc-date-btn] {
|
|
border-radius: var(--calendar-border-radius);
|
|
}
|
|
|
|
//
|
|
// Popup surface
|
|
//
|
|
// The plugin adds `[data-vc-input]` only when it owns a popup, so inline
|
|
// calendars keep the bare grid styling above.
|
|
|
|
[data-vc='calendar'][data-vc-input] {
|
|
--datepicker-padding: #{$datepicker-padding};
|
|
--datepicker-bg: #{$datepicker-bg};
|
|
--datepicker-border-radius: #{$datepicker-border-radius};
|
|
--datepicker-box-shadow: #{$datepicker-box-shadow};
|
|
--datepicker-min-width: #{$datepicker-min-width};
|
|
--datepicker-zindex: #{$zindex-dropdown};
|
|
--calendar-padding: var(--datepicker-padding);
|
|
position: absolute;
|
|
z-index: var(--datepicker-zindex);
|
|
min-width: var(--datepicker-min-width);
|
|
// Same surface as `.dropdown-menu`: the edge is the 1px ring inside the
|
|
// dropdown shadow, so the popup has no border of its own.
|
|
background-color: var(--datepicker-bg);
|
|
box-shadow: var(--datepicker-box-shadow);
|
|
@include border-radius(var(--datepicker-border-radius));
|
|
|
|
// The plugin creates the popup at 0/0 with this attribute, positions it on
|
|
// show, and puts the attribute back on hide. The selector repeats the popup
|
|
// one so it wins on specificity; otherwise the popup flashes in the corner
|
|
// and never disappears.
|
|
&[data-vc-calendar-hidden] {
|
|
pointer-events: none;
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
[data-vc-position='bottom'] {
|
|
margin-block-start: 0.25rem;
|
|
}
|
|
|
|
[data-vc-position='top'] {
|
|
margin-block-end: -0.25rem;
|
|
}
|
|
|
|
// stylelint-enable selector-max-attribute, selector-no-qualifying-type
|