refactor: Extract post form textarea autogrow styles

- Created: static/css/components/post-form.css (textarea.autogrow with min/max height, overflow control)
- Modified: templates/feed/post_form.html (replaced inline styles with CSS import)
- Description: Extracted 13-line style block for autogrow textarea behavior
- Result: Post form now uses reusable component CSS
This commit is contained in:
admin i 2025-10-28 10:10:07 +03:00
parent 737f0a9623
commit 2cc14bc208
8 changed files with 260 additions and 124 deletions

View File

@ -0,0 +1,38 @@
/**
* department-list.css
* Стили списка отделов
*/
/* ─────────────────────────────────────────────────────────────
HEADER
────────────────────────────────────────────────────────────── */
.feed-header {
gap: .6rem;
flex-wrap: wrap;
}
/* ─────────────────────────────────────────────────────────────
SCROLLABLE LIST
────────────────────────────────────────────────────────────── */
/* список — единственный прокручиваемый блок */
#deptList {
max-height: calc(100dvh - var(--navbar-h) - 160px);
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
#deptList .dept-row {
padding: .6rem .75rem;
}
#deptList .dept-row + .dept-row {
border-top: 1px solid var(--bs-border-color);
}
.feed-author {
font-weight: 700;
}
.feed-sub {
color: var(--bs-secondary-color);
}

View File

@ -0,0 +1,173 @@
/**
* logout-modal.css
* Стили iOS-style модального окна выхода
*/
/* ─────────────────────────────────────────────────────────────
OVERLAY
────────────────────────────────────────────────────────────── */
/* Overlay поверх всего (и навбара тоже) */
.ios-overlay {
position: fixed;
inset: 0;
z-index: 1080;
background: color-mix(in srgb, var(--bs-body-bg), #000 35%);
backdrop-filter: blur(10px) saturate(110%);
display: grid;
place-items: end center; /* bottom sheet по умолчанию */
}
@media (min-width: 992px) {
.ios-overlay {
place-items: center;
}
}
/* ─────────────────────────────────────────────────────────────
SHEET / CARD
────────────────────────────────────────────────────────────── */
/* Bottom sheet / Card */
.ios-sheet {
width: 100%;
max-width: 560px;
background: color-mix(in srgb, var(--bs-body-bg), #fff 6%);
border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 30%);
border-radius: 16px 16px 0 0;
box-shadow: 0 12px 48px rgba(0, 0, 0, .28);
animation: slideUp .28s ease both;
}
@media (min-width: 992px) {
.ios-sheet {
border-radius: 18px;
animation: popIn .18s ease both;
}
}
/* Грип-бар как в iOS */
.ios-grip {
width: 36px;
height: 4px;
border-radius: 999px;
background: color-mix(in srgb, var(--bs-body-color), transparent 70%);
margin: .5rem auto 0.25rem auto;
}
/* ─────────────────────────────────────────────────────────────
CONTENT
────────────────────────────────────────────────────────────── */
.ios-body {
padding: 1rem 1.25rem 1.25rem 1.25rem;
}
@media (min-width: 992px) {
.ios-body {
padding: 1.25rem 1.5rem 1.5rem 1.5rem;
}
}
.ios-title {
margin: .25rem 0 .25rem 0;
text-align: center;
font-weight: 800;
letter-spacing: .2px;
}
.ios-sub {
text-align: center;
color: var(--bs-secondary-color);
margin: 0 0 1rem 0;
}
/* ─────────────────────────────────────────────────────────────
AVATAR & ICON
────────────────────────────────────────────────────────────── */
/* Аватар + иконка выхода */
.ios-ava {
width: 64px;
height: 64px;
border-radius: 999px;
overflow: hidden;
border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 20%);
background: var(--bs-tertiary-bg);
display: grid;
place-items: center;
margin: .25rem auto .75rem auto;
}
.ios-ava img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.ios-ico {
width: 56px;
height: 56px;
border-radius: 14px;
background: color-mix(in srgb, var(--bs-danger), #000 12%);
color: #fff;
display: grid;
place-items: center;
margin: .25rem auto .75rem auto;
}
/* ─────────────────────────────────────────────────────────────
BUTTONS
────────────────────────────────────────────────────────────── */
.ios-actions {
display: grid;
gap: .6rem;
}
.ios-btn {
min-height: 48px;
border-radius: 12px;
font-weight: 700;
}
.ios-btn-danger {
background: var(--bs-danger);
border-color: var(--bs-danger);
color: #fff;
}
.ios-btn-danger:hover {
filter: brightness(1.02);
}
.ios-btn-ghost {
background: color-mix(in srgb, var(--bs-body-bg), #fff 6%);
border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 20%);
color: var(--bs-body-color);
}
.ios-btn-ghost:hover {
background: color-mix(in srgb, var(--bs-body-bg), #fff 9%);
}
/* ─────────────────────────────────────────────────────────────
ANIMATIONS
────────────────────────────────────────────────────────────── */
@keyframes slideUp {
from {
transform: translateY(16px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@keyframes popIn {
from {
transform: scale(.98);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}

View File

@ -0,0 +1,21 @@
/**
* modal-overrides.css
* Z-index corrections для модальных окон
*/
/* ─────────────────────────────────────────────────────────────
MODAL Z-INDEX
────────────────────────────────────────────────────────────── */
/* модал всегда выше бэкдропа/локальных стэков */
.modal {
z-index: 1080;
}
.modal-backdrop {
z-index: 1075;
}
/* не даём «просвечивать» через бэкдроп */
.modal .modal-content {
background-color: var(--bs-body-bg);
}

View File

@ -0,0 +1,20 @@
/**
* post-form.css
* Стили формы создания/редактирования поста
*/
/* ─────────────────────────────────────────────────────────────
AUTOGROW TEXTAREA
────────────────────────────────────────────────────────────── */
/* авто-рост для больших текстов */
textarea.autogrow {
overflow: hidden; /* без внутренних скроллов, пока не упремся в max-height */
resize: none; /* убираем ручной ресайз, если хочешь оставить — поменяй на 'vertical' */
min-height: 120px; /* стартовая высота (на вкус) */
max-height: 70vh; /* чтобы не занимало весь экран */
}
/* когда достигли max-height — позволим вертикальный скролл */
textarea.autogrow.is-max {
overflow-y: auto;
}

View File

@ -5,91 +5,7 @@
{% block title %}Выход{% endblock %}
{% block extra_css %}
<style>
/* Overlay поверх всего (и навбара тоже) */
.ios-overlay{
position: fixed; inset: 0; z-index: 1080;
background: color-mix(in srgb, var(--bs-body-bg), #000 35%);
backdrop-filter: blur(10px) saturate(110%);
display: grid; place-items: end center; /* bottom sheet по умолчанию */
}
@media (min-width: 992px){
.ios-overlay{ place-items: center; }
}
/* Bottom sheet / Card */
.ios-sheet{
width: 100%; max-width: 560px;
background: color-mix(in srgb, var(--bs-body-bg), #fff 6%);
border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 30%);
border-radius: 16px 16px 0 0;
box-shadow: 0 12px 48px rgba(0,0,0,.28);
animation: slideUp .28s ease both;
}
@media (min-width: 992px){
.ios-sheet{
border-radius: 18px; animation: popIn .18s ease both;
}
}
/* Грип-бар как в iOS */
.ios-grip{
width: 36px; height: 4px; border-radius: 999px;
background: color-mix(in srgb, var(--bs-body-color), transparent 70%);
margin: .5rem auto 0.25rem auto;
}
/* Контент */
.ios-body{ padding: 1rem 1.25rem 1.25rem 1.25rem; }
@media (min-width: 992px){ .ios-body{ padding: 1.25rem 1.5rem 1.5rem 1.5rem; } }
.ios-title{
margin: .25rem 0 .25rem 0; text-align: center;
font-weight: 800; letter-spacing: .2px;
}
.ios-sub{
text-align: center; color: var(--bs-secondary-color);
margin: 0 0 1rem 0;
}
/* Аватар + иконка выхода */
.ios-ava{
width: 64px; height: 64px; border-radius: 999px; overflow: hidden;
border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 20%);
background: var(--bs-tertiary-bg);
display: grid; place-items: center; margin: .25rem auto .75rem auto;
}
.ios-ava img{ width: 100%; height: 100%; object-fit: cover; display: block; }
.ios-ico{
width: 56px; height: 56px; border-radius: 14px;
background: color-mix(in srgb, var(--bs-danger), #000 12%);
color: #fff; display: grid; place-items: center; margin: .25rem auto .75rem auto;
}
/* Кнопки */
.ios-actions{ display: grid; gap: .6rem; }
.ios-btn{ min-height: 48px; border-radius: 12px; font-weight: 700; }
.ios-btn-danger{
background: var(--bs-danger); border-color: var(--bs-danger); color: #fff;
}
.ios-btn-danger:hover{ filter: brightness(1.02); }
.ios-btn-ghost{
background: color-mix(in srgb, var(--bs-body-bg), #fff 6%);
border: 1px solid color-mix(in srgb, var(--bs-border-color), transparent 20%);
color: var(--bs-body-color);
}
.ios-btn-ghost:hover{ background: color-mix(in srgb, var(--bs-body-bg), #fff 9%); }
/* Анимации */
@keyframes slideUp{
from{ transform: translateY(16px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
@keyframes popIn{
from{ transform: scale(.98); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
</style>
<link rel="stylesheet" href="{% static 'css/components/logout-modal.css' %}">
{% endblock %}
{% block content %}

View File

@ -1,12 +1,7 @@
{# templates/employees/_employee_edit.html #}
{# Форма редактирования сотрудника - рефакторированная версия #}
<style>
/* модал всегда выше бэкдропа/локальных стэков */
.modal { z-index: 1080; }
.modal-backdrop { z-index: 1075; }
/* не даём «просвечивать» через бэкдроп */
.modal .modal-content { background-color: var(--bs-body-bg); }
</style>
{% load static %}
<link rel="stylesheet" href="{% static 'css/components/modal-overrides.css' %}">
<form id="apiEditForm" class="row g-3" data-endpoint="{{ endpoint }}"
action="{% if is_me %}{% url 'employees:employee_set_position_me' %}{% else %}{% url 'employees:employee_set_position' emp.id %}{% endif %}">

View File

@ -5,22 +5,7 @@
{% block extra_css %}
<link rel="stylesheet" href="{% static 'css/components/ios-search.css' %}">
<style>
/* ios-search стили теперь в static/css/components/ios-search.css */
.feed-header { gap:.6rem; flex-wrap:wrap; }
/* список — единственный прокручиваемый блок */
#deptList{
max-height: calc(100dvh - var(--navbar-h) - 160px);
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
#deptList .dept-row{ padding:.6rem .75rem; }
#deptList .dept-row + .dept-row{ border-top:1px solid var(--bs-border-color); }
.feed-author{ font-weight:700; }
.feed-sub{ color:var(--bs-secondary-color); }
<link rel="stylesheet" href="{% static 'css/components/department-list.css' %}">
{% endblock %}
{% block content %}

View File

@ -5,23 +5,11 @@
{% if is_update %}Редактировать{% else %}Создать{% endif %} публикацию
{% endblock %}
{% block extra_css %}
<link rel="stylesheet" href="{% static 'css/components/post-form.css' %}">
{% endblock %}
{% block content %}
<style>
/* авто-рост для больших текстов */
textarea.autogrow {
overflow: hidden; /* без внутренних скроллов, пока не упремся в max-height */
resize: none; /* убираем ручной ресайз, если хочешь оставить — поменяй на 'vertical' */
min-height: 120px; /* стартовая высота (на вкус) */
max-height: 70vh; /* чтобы не занимало весь экран */
}
/* когда достигли max-height — позволим вертикальный скролл */
textarea.autogrow.is-max {
overflow-y: auto;
}
</style>
<div class="container">
<!-- Header (без кнопки Отмена) -->
<div class="d-flex align-items-center justify-content-between mb-3">
<div class="d-flex align-items-center gap-2">