This commit is contained in:
Untone 2024-10-03 12:08:17 +03:00
parent cb17a241a2
commit 7d5562d256
5 changed files with 322 additions and 0 deletions

80
src/lib/createTooltip.ts Normal file
View 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
View 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
View 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
View File

@ -0,0 +1,2 @@
@import 'vars';
@import 'grid';

30
src/styles/_vars.scss Normal file
View 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;