diff --git a/package-lock.json b/package-lock.json index 697a6e1..9b9a368 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@tnsu/ui-kit", - "version": "0.13.0", + "version": "0.14.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@tnsu/ui-kit", - "version": "0.13.0", + "version": "0.14.0", "license": "ISC", "devDependencies": { "@chromatic-com/storybook": "latest", diff --git a/package.json b/package.json index 6224e00..89701a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tnsu/ui-kit", - "version": "0.13.0", + "version": "0.14.0", "description": "TNSU shared UI components for SPFx web parts", "author": "Timur Gorodetskiy", "license": "ISC", diff --git a/src/Sidebar/Sidebar.module.scss b/src/Sidebar/Sidebar.module.scss index a057c7d..b489913 100644 --- a/src/Sidebar/Sidebar.module.scss +++ b/src/Sidebar/Sidebar.module.scss @@ -99,7 +99,8 @@ text-align: left; // Пункт-ссылка () выглядит так же, как пункт-кнопка. text-decoration: none; - white-space: nowrap; + // Длинное название переносится (не больше 2 строк — см. .itemTitle), а не обрезается многоточием. + white-space: normal; cursor: pointer; transition: color .18s, background .18s, border-color .18s; @@ -130,11 +131,26 @@ color: inherit; } +// Не больше 2 строк: совсем длинное название обрезается многоточием на второй строке. .itemTitle { flex: 1; min-width: 0; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; overflow: hidden; - text-overflow: ellipsis; + line-height: 1.3; + overflow-wrap: anywhere; +} + +// ---- Линии между пунктами (проп dividers) ---- +// Линия — над каждым пунктом, кроме первого; подпункты раскрытой группы лежат внутри .group — их не трогаем. +.navDividers .items { + gap: 0; + + > * + * { + border-top: 1px solid rgba(255, 255, 255, .06); + } } .badge { @@ -189,7 +205,7 @@ $sub-item-indent: 48px; // 18px отступ пункта + 3px маркер + font-size: 13px; text-align: left; text-decoration: none; - white-space: nowrap; + white-space: normal; cursor: pointer; transition: color .18s, background .18s; diff --git a/src/Sidebar/Sidebar.stories.tsx b/src/Sidebar/Sidebar.stories.tsx index cc2ec6e..1e76903 100644 --- a/src/Sidebar/Sidebar.stories.tsx +++ b/src/Sidebar/Sidebar.stories.tsx @@ -66,6 +66,7 @@ export const Collapsed: Story = { // Пункт с children — раскрывающаяся группа; подпункт с href открывается в новой вкладке. const ITEMS_WITH_GROUP: ISidebarItem[] = [ ...ITEMS.slice(0, 3), + { id: 'long', title: 'Загрузить работы из сметы проекта', icon: 'download' }, { id: 'catalogs', title: 'Справочники', @@ -96,6 +97,25 @@ export const WithGroupAndLinks: Story = { }, }; +// Линии между пунктами; длинное название переносится на вторую строку. +export const WithDividers: Story = { + render: () => { + const [active, setActive] = useState('approvals'); + const [collapsed, setCollapsed] = useState(false); + return ( + setCollapsed((c) => !c)} + dividers + /> + ); + }, +}; + // Мобильный drawer: сузь окно браузера (или переключи Viewport в панели Storybook) // ниже 768px — сайдбар спрячется, а «☰ Меню» его выдвинет поверх контента. export const MobileDrawer: Story = { diff --git a/src/Sidebar/Sidebar.tsx b/src/Sidebar/Sidebar.tsx index 0a4cd50..2fa0f51 100644 --- a/src/Sidebar/Sidebar.tsx +++ b/src/Sidebar/Sidebar.tsx @@ -24,6 +24,8 @@ export interface ISidebarProps { mobileOpen?: boolean; /** Закрыть мобильный drawer (клик по затемнению или выбор пункта). */ onMobileClose?: () => void; + /** Тонкие линии между пунктами (подпункты раскрытой группы — без линий, они читаются как одно целое). */ + dividers?: boolean; } /** @@ -43,11 +45,13 @@ export const Sidebar: React.FC = ({ onToggleCollapsed, mobileOpen = false, onMobileClose, + dividers = false, }) => { const navClasses = [ styles.nav, collapsed ? styles.navCollapsed : '', mobileOpen ? styles.navMobileOpen : '', + dividers ? styles.navDividers : '', ] .filter(Boolean) .join(' ');