..
This commit is contained in:
parent
cb17a241a2
commit
7d5562d256
80
src/lib/createTooltip.ts
Normal file
80
src/lib/createTooltip.ts
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
export function createTooltip(referenceElement?: Element, tooltipElement?: HTMLElement, options = {}) {
|
||||||
|
const defaultOptions = {
|
||||||
|
placement: 'top',
|
||||||
|
offset: [0, 8]
|
||||||
|
}
|
||||||
|
const config = { ...defaultOptions, ...options }
|
||||||
|
|
||||||
|
function updatePosition() {
|
||||||
|
if (!(referenceElement && tooltipElement)) return
|
||||||
|
|
||||||
|
const rect = referenceElement.getBoundingClientRect()
|
||||||
|
const tooltipRect = tooltipElement.getBoundingClientRect()
|
||||||
|
const offsetX = config.offset[0]
|
||||||
|
const offsetY = config.offset[1]
|
||||||
|
|
||||||
|
let top = 0
|
||||||
|
let left = 0
|
||||||
|
|
||||||
|
switch (config.placement) {
|
||||||
|
case 'top': {
|
||||||
|
top = rect.top - tooltipRect.height - offsetY
|
||||||
|
left = rect.left + (rect.width - tooltipRect.width) / 2 + offsetX
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'bottom': {
|
||||||
|
top = rect.bottom + offsetY
|
||||||
|
left = rect.left + (rect.width - tooltipRect.width) / 2 + offsetX
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'left': {
|
||||||
|
top = rect.top + (rect.height - tooltipRect.height) / 2 + offsetY
|
||||||
|
left = rect.left - tooltipRect.width - offsetX
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'right': {
|
||||||
|
top = rect.top + (rect.height - tooltipRect.height) / 2 + offsetY
|
||||||
|
left = rect.right + offsetX
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
top = rect.top - tooltipRect.height - offsetY
|
||||||
|
left = rect.left + (rect.width - tooltipRect.width) / 2 + offsetX
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltipElement.style.position = 'absolute'
|
||||||
|
tooltipElement.style.top = `${top}px`
|
||||||
|
tooltipElement.style.left = `${left}px`
|
||||||
|
}
|
||||||
|
|
||||||
|
function showTooltip() {
|
||||||
|
if (tooltipElement) tooltipElement.style.visibility = 'visible'
|
||||||
|
updatePosition()
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideTooltip() {
|
||||||
|
if (tooltipElement) tooltipElement.style.visibility = 'hidden'
|
||||||
|
}
|
||||||
|
|
||||||
|
referenceElement?.addEventListener('mouseenter', showTooltip)
|
||||||
|
referenceElement?.addEventListener('mouseleave', hideTooltip)
|
||||||
|
window.addEventListener('resize', updatePosition)
|
||||||
|
|
||||||
|
return {
|
||||||
|
update: updatePosition,
|
||||||
|
destroy() {
|
||||||
|
referenceElement?.removeEventListener('mouseenter', showTooltip)
|
||||||
|
referenceElement?.removeEventListener('mouseleave', hideTooltip)
|
||||||
|
window.removeEventListener('resize', updatePosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usage example
|
||||||
|
const referenceElement = document.querySelector('#reference')
|
||||||
|
const tooltipElement = document.querySelector('#tooltip')
|
||||||
|
createTooltip(referenceElement as HTMLElement, tooltipElement as HTMLElement, {
|
||||||
|
placement: 'top',
|
||||||
|
offset: [0, 8]
|
||||||
|
})
|
65
src/styles/README.md
Normal file
65
src/styles/README.md
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
# _grid.scss - a Minimalistic Bootstrap-Compatible Grid System
|
||||||
|
|
||||||
|
This grid system is a lightweight alternative to Bootstrap's grid, providing essential features for responsive design. It includes a set of SCSS mixins and classes to create flexible layouts.
|
||||||
|
|
||||||
|
## Supported Classes in _grid.scss
|
||||||
|
|
||||||
|
### Container
|
||||||
|
|
||||||
|
- **`.container`**: Creates a fixed-width container and centers it on the page.
|
||||||
|
- **`.container-fluid`**: Creates a full-width container that spans the entire width of the viewport.
|
||||||
|
|
||||||
|
### Row
|
||||||
|
|
||||||
|
- **`.row`**: Creates a flexbox container for columns, with negative margins to offset column padding.
|
||||||
|
|
||||||
|
### Columns
|
||||||
|
|
||||||
|
- **`.col-xx-#`**: Defines the width of a column for a specific breakpoint (`xx` can be `xs`, `sm`, `md`, `lg`, `xl`, `xxl`). Replace `#` with a number from 1 to 24 (based on `$grid-columns`).
|
||||||
|
|
||||||
|
### Offsets
|
||||||
|
|
||||||
|
- **`.offset-xx-#`**: Adds left margin to a column, effectively moving it to the right by the specified number of columns. Replace `xx` with the breakpoint and `#` with the number of columns to offset.
|
||||||
|
|
||||||
|
## Mixins
|
||||||
|
|
||||||
|
### `media-breakpoint-up($breakpoint)`
|
||||||
|
|
||||||
|
Applies styles at a minimum width of the specified breakpoint.
|
||||||
|
|
||||||
|
### `media-breakpoint-down($breakpoint)`
|
||||||
|
|
||||||
|
Applies styles at a maximum width of the specified breakpoint.
|
||||||
|
|
||||||
|
### `media-breakpoint-between($lower, $upper)`
|
||||||
|
|
||||||
|
Applies styles between two breakpoints.
|
||||||
|
|
||||||
|
### `make-container($max-widths, $gutter)`
|
||||||
|
|
||||||
|
Creates a container with specified maximum widths and gutter.
|
||||||
|
|
||||||
|
### `make-row($gutter)`
|
||||||
|
|
||||||
|
Creates a flexbox row with specified gutter.
|
||||||
|
|
||||||
|
### `make-col($size, $columns)`
|
||||||
|
|
||||||
|
Defines a column with a specific size and total number of columns.
|
||||||
|
|
||||||
|
### `make-col-offset($size, $columns)`
|
||||||
|
|
||||||
|
Offsets a column by a specific size.
|
||||||
|
|
||||||
|
### `row-cols($count)`
|
||||||
|
|
||||||
|
Sets the number of columns in a row, each taking an equal width.
|
||||||
|
|
||||||
|
## Customization
|
||||||
|
|
||||||
|
You can customize the grid system by modifying the variables in `_globals.scss`:
|
||||||
|
|
||||||
|
- **`$grid-columns`**: Total number of columns in the grid.
|
||||||
|
- **`$grid-gutter-width`**: Width of the gutter between columns.
|
||||||
|
- **`$grid-breakpoints`**: Map of breakpoints for responsive design.
|
||||||
|
- **`$container-max-widths`**: Maximum widths for containers at each breakpoint.
|
145
src/styles/_grid.scss
Normal file
145
src/styles/_grid.scss
Normal file
|
@ -0,0 +1,145 @@
|
||||||
|
// Миксин для media-breakpoint-up
|
||||||
|
@mixin media-breakpoint-up($breakpoint, $breakpoints: $grid-breakpoints) {
|
||||||
|
$min-width: map-get($breakpoints, $breakpoint);
|
||||||
|
|
||||||
|
@if $min-width {
|
||||||
|
@media (min-width: #{$min-width}) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
} @else {
|
||||||
|
@warn "Нет валидного брейкпоинта для '#{$breakpoint}'.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Миксин для media-breakpoint-down
|
||||||
|
@mixin media-breakpoint-down($breakpoint, $breakpoints: $grid-breakpoints) {
|
||||||
|
$max-width: map-get($breakpoints, $breakpoint) - 0.02px;
|
||||||
|
|
||||||
|
@if $max-width {
|
||||||
|
@media (max-width: #{$max-width}) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
} @else {
|
||||||
|
@warn "Нет валидного брейкпоинта для '#{$breakpoint}'.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Миксин для media-breakpoint-between
|
||||||
|
@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {
|
||||||
|
$min-width: map-get($breakpoints, $lower);
|
||||||
|
$max-width: map-get($breakpoints, $upper) - 0.02px;
|
||||||
|
|
||||||
|
@if $min-width and $max-width {
|
||||||
|
@media (min-width: #{$min-width}) and (max-width: #{$max-width}) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
} @else {
|
||||||
|
@warn "Нет валидных брейкпоинтов для '#{$lower}' или '#{$upper}'.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Миксин make-container
|
||||||
|
@mixin make-container($max-widths: $container-max-widths, $gutter: $grid-gutter-width) {
|
||||||
|
width: 100%;
|
||||||
|
padding-right: $gutter;
|
||||||
|
padding-left: $gutter;
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
|
||||||
|
@each $breakpoint, $max-width in $max-widths {
|
||||||
|
@include media-breakpoint-up($breakpoint, $grid-breakpoints) {
|
||||||
|
max-width: #{$max-width};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Миксин make-row
|
||||||
|
@mixin make-row($gutter: $grid-gutter-width) {
|
||||||
|
--gutter-x: #{$gutter};
|
||||||
|
--gutter-y: 0;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-top: calc(-1 * var(--gutter-y));
|
||||||
|
margin-right: calc(-0.5 * var(--gutter-x));
|
||||||
|
margin-left: calc(-0.5 * var(--gutter-x));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Миксин make-col-ready
|
||||||
|
@mixin make-col-ready() {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
padding-right: calc(var(--gutter-x) * 0.5);
|
||||||
|
padding-left: calc(var(--gutter-x) * 0.5);
|
||||||
|
margin-top: var(--gutter-y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Миксин make-col
|
||||||
|
@mixin make-col($size: false, $columns: $grid-columns) {
|
||||||
|
@if $size {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: calc(100% * #{calc($size / $columns)});
|
||||||
|
} @else {
|
||||||
|
flex: 1 1 0;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Миксин make-col-auto
|
||||||
|
@mixin make-col-auto() {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Миксин make-col-offset
|
||||||
|
@mixin make-col-offset($size, $columns: $grid-columns) {
|
||||||
|
$num: calc($size / $columns);
|
||||||
|
|
||||||
|
margin-left: if($num == 0, 0, calc(100% * #{$num}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Миксин row-cols
|
||||||
|
@mixin row-cols($count) {
|
||||||
|
> * {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 100% / $count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Миксин make-grid-columns
|
||||||
|
@mixin make-grid-columns($columns: $grid-columns, $breakpoints: $grid-breakpoints) {
|
||||||
|
@each $breakpoint, $value in $breakpoints {
|
||||||
|
$infix: if($breakpoint == 'xs', '', "-#{$breakpoint}");
|
||||||
|
|
||||||
|
@include media-breakpoint-up($breakpoint, $breakpoints) {
|
||||||
|
@for $i from 1 through $columns {
|
||||||
|
.col#{$infix}-#{$i} {
|
||||||
|
@include make-col($i, $columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
.offset#{$infix}-#{$i} {
|
||||||
|
@include make-col-offset($i, $columns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Генерация классов контейнера и ряда
|
||||||
|
.container,
|
||||||
|
.container-fluid {
|
||||||
|
@include make-container($container-max-widths, $grid-gutter-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
@include make-row;
|
||||||
|
|
||||||
|
> * {
|
||||||
|
@include make-col-ready;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Генерация классов столбцов и смещений
|
||||||
|
@include make-grid-columns($grid-columns, $grid-breakpoints);
|
2
src/styles/_inject.scss
Normal file
2
src/styles/_inject.scss
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
@import 'vars';
|
||||||
|
@import 'grid';
|
30
src/styles/_vars.scss
Normal file
30
src/styles/_vars.scss
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
$include-column-box-sizing: true !default;
|
||||||
|
$rfs-breakpoint: 1460px !default;
|
||||||
|
$rfs-base-value: 1.6rem !default;
|
||||||
|
$rfs-rem-value: 10 !default;
|
||||||
|
$grid-columns: 24;
|
||||||
|
$grid-gutter-width: 4rem !default;
|
||||||
|
$grid-breakpoints: (
|
||||||
|
xs: 0,
|
||||||
|
sm: 576px,
|
||||||
|
md: 768px,
|
||||||
|
lg: 992px,
|
||||||
|
xl: 1200px,
|
||||||
|
xxl: 1400px,
|
||||||
|
) !default;
|
||||||
|
$default-color: #141414;
|
||||||
|
$link-color: #2638d9;
|
||||||
|
$container-padding-x: $grid-gutter-width * 0.5 !default;
|
||||||
|
|
||||||
|
// Additional variables needed
|
||||||
|
$container-max-widths: $grid-breakpoints;
|
||||||
|
$gutters: (
|
||||||
|
0: 0,
|
||||||
|
1: 0.25rem,
|
||||||
|
2: 0.5rem,
|
||||||
|
3: 1rem,
|
||||||
|
4: 1.5rem,
|
||||||
|
5: 3rem
|
||||||
|
) !default;
|
||||||
|
$grid-row-columns: 6 !default;
|
||||||
|
$prefix: '' !default;
|
Loading…
Reference in New Issue
Block a user