mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2026-05-27 07:36:34 +00:00
Replace most stylesheets with tailwind styles
This commit is contained in:
@@ -1,22 +0,0 @@
|
|||||||
.main-header.main-header {
|
|
||||||
color: white;
|
|
||||||
background-color: var(--brand-color) !important;
|
|
||||||
|
|
||||||
.navbar-brand {
|
|
||||||
color: inherit !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-header__brand-logo {
|
|
||||||
width: 26px;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-header__toggle-icon {
|
|
||||||
width: 20px;
|
|
||||||
transition: transform 300ms;
|
|
||||||
}
|
|
||||||
|
|
||||||
.main-header__toggle-icon--opened {
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,6 @@ import { Collapse, Nav, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink } f
|
|||||||
import type { FCWithDeps } from '../container/utils';
|
import type { FCWithDeps } from '../container/utils';
|
||||||
import { componentFactory, useDependencies } from '../container/utils';
|
import { componentFactory, useDependencies } from '../container/utils';
|
||||||
import { ShlinkLogo } from './img/ShlinkLogo';
|
import { ShlinkLogo } from './img/ShlinkLogo';
|
||||||
import './MainHeader.scss';
|
|
||||||
|
|
||||||
type MainHeaderDeps = {
|
type MainHeaderDeps = {
|
||||||
ServersDropdown: FC;
|
ServersDropdown: FC;
|
||||||
@@ -25,20 +24,22 @@ const MainHeader: FCWithDeps<unknown, MainHeaderDeps> = () => {
|
|||||||
useEffect(collapse, [location, collapse]);
|
useEffect(collapse, [location, collapse]);
|
||||||
|
|
||||||
const settingsPath = '/settings';
|
const settingsPath = '/settings';
|
||||||
const toggleClass = clsx('main-header__toggle-icon', { 'main-header__toggle-icon--opened': isNotCollapsed });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Navbar color="primary" dark fixed="top" className="main-header" expand="md">
|
<Navbar color="primary" dark fixed="top" expand="md" className="tw:text-white tw:bg-lm-brand tw:dark:bg-dm-brand">
|
||||||
<NavbarBrand tag={Link} to="/">
|
<NavbarBrand tag={Link} to="/">
|
||||||
<ShlinkLogo className="main-header__brand-logo tw:inline" color="white" /> Shlink
|
<ShlinkLogo className="tw:inline tw:w-7 tw:mr-1" color="white" /> Shlink
|
||||||
</NavbarBrand>
|
</NavbarBrand>
|
||||||
|
|
||||||
<NavbarToggler onClick={toggleCollapse}>
|
<NavbarToggler onClick={toggleCollapse}>
|
||||||
<FontAwesomeIcon icon={arrowIcon} className={toggleClass} />
|
<FontAwesomeIcon
|
||||||
|
icon={arrowIcon}
|
||||||
|
className={clsx('tw:transition-transform tw:duration-300', { 'tw:rotate-180': isNotCollapsed })}
|
||||||
|
/>
|
||||||
</NavbarToggler>
|
</NavbarToggler>
|
||||||
|
|
||||||
<Collapse navbar isOpen={isNotCollapsed}>
|
<Collapse navbar isOpen={isNotCollapsed}>
|
||||||
<Nav navbar className="ms-auto">
|
<Nav navbar className="tw:ml-auto">
|
||||||
<NavItem>
|
<NavItem>
|
||||||
<NavLink tag={Link} to={settingsPath} active={pathname.startsWith(settingsPath)}>
|
<NavLink tag={Link} to={settingsPath} active={pathname.startsWith(settingsPath)}>
|
||||||
<FontAwesomeIcon icon={cogsIcon} /> Settings
|
<FontAwesomeIcon icon={cogsIcon} /> Settings
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
@use '../../node_modules/@shlinkio/shlink-frontend-kit/dist/base';
|
|
||||||
|
|
||||||
.shlink-versions-container--with-sidebar {
|
|
||||||
margin-left: 0;
|
|
||||||
|
|
||||||
@media (min-width: base.$mdMin) {
|
|
||||||
margin-left: base.$asideMenuWidth;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,6 @@ import { clsx } from 'clsx';
|
|||||||
import type { SelectedServer } from '../servers/data';
|
import type { SelectedServer } from '../servers/data';
|
||||||
import { isReachableServer } from '../servers/data';
|
import { isReachableServer } from '../servers/data';
|
||||||
import { ShlinkVersions } from './ShlinkVersions';
|
import { ShlinkVersions } from './ShlinkVersions';
|
||||||
import './ShlinkVersionsContainer.scss';
|
|
||||||
|
|
||||||
export type ShlinkVersionsContainerProps = {
|
export type ShlinkVersionsContainerProps = {
|
||||||
selectedServer: SelectedServer;
|
selectedServer: SelectedServer;
|
||||||
@@ -10,9 +9,7 @@ export type ShlinkVersionsContainerProps = {
|
|||||||
|
|
||||||
export const ShlinkVersionsContainer = ({ selectedServer }: ShlinkVersionsContainerProps) => (
|
export const ShlinkVersionsContainer = ({ selectedServer }: ShlinkVersionsContainerProps) => (
|
||||||
<div
|
<div
|
||||||
className={clsx('text-center', {
|
className={clsx('text-center', { 'tw:md:ml-(--aside-menu-width)': isReachableServer(selectedServer) })}
|
||||||
'shlink-versions-container--with-sidebar': isReachableServer(selectedServer),
|
|
||||||
})}
|
|
||||||
>
|
>
|
||||||
<ShlinkVersions selectedServer={selectedServer} />
|
<ShlinkVersions selectedServer={selectedServer} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
@use '../../../node_modules/@shlinkio/shlink-frontend-kit/dist/base';
|
|
||||||
|
|
||||||
.server-error__container {
|
|
||||||
text-align: center;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.server-error__delete-btn {
|
|
||||||
color: base.$dangerColor;
|
|
||||||
font-weight: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.server-error__delete-btn:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,6 @@ import type { SelectedServer, ServersMap } from '../data';
|
|||||||
import { isServerWithId } from '../data';
|
import { isServerWithId } from '../data';
|
||||||
import type { DeleteServerButtonProps } from '../DeleteServerButton';
|
import type { DeleteServerButtonProps } from '../DeleteServerButton';
|
||||||
import { ServersListGroup } from '../ServersListGroup';
|
import { ServersListGroup } from '../ServersListGroup';
|
||||||
import './ServerError.scss';
|
|
||||||
|
|
||||||
type ServerErrorProps = {
|
type ServerErrorProps = {
|
||||||
servers: ServersMap;
|
servers: ServersMap;
|
||||||
@@ -24,8 +23,8 @@ const ServerError: FCWithDeps<ServerErrorProps, ServerErrorDeps> = ({ servers, s
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<NoMenuLayout>
|
<NoMenuLayout>
|
||||||
<div className="server-error__container flex-column">
|
<div className="tw:flex tw:flex-col tw:items-center tw:gap-y-4 tw:md:gap-y-8">
|
||||||
<Message className="w-100 mb-3 mb-md-5" variant="error">
|
<Message className="tw:w-full tw:lg:w-[80%]" variant="error">
|
||||||
{!isServerWithId(selectedServer) && 'Could not find this Shlink server.'}
|
{!isServerWithId(selectedServer) && 'Could not find this Shlink server.'}
|
||||||
{isServerWithId(selectedServer) && (
|
{isServerWithId(selectedServer) && (
|
||||||
<>
|
<>
|
||||||
@@ -39,19 +38,17 @@ const ServerError: FCWithDeps<ServerErrorProps, ServerErrorDeps> = ({ servers, s
|
|||||||
These are the Shlink servers currently configured. Choose one of
|
These are the Shlink servers currently configured. Choose one of
|
||||||
them or <Link to="/server/create">add a new one</Link>.
|
them or <Link to="/server/create">add a new one</Link>.
|
||||||
</p>
|
</p>
|
||||||
<Card className="tw:w-full tw:max-w-100 tw:overflow-hidden tw:mt-4">
|
<Card className="tw:w-full tw:max-w-100 tw:overflow-hidden">
|
||||||
<ServersListGroup borderless servers={Object.values(servers)} />
|
<ServersListGroup borderless servers={Object.values(servers)} />
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{isServerWithId(selectedServer) && (
|
{isServerWithId(selectedServer) && (
|
||||||
<div className="container mt-3 mt-md-5">
|
<p className="tw:text-xl">
|
||||||
<p className="tw:text-xl">
|
Alternatively, if you think you may have misconfigured this server, you
|
||||||
Alternatively, if you think you may have misconfigured this server, you
|
can <DeleteServerButton server={selectedServer} className="tw:text-danger tw:hover:underline">remove
|
||||||
can <DeleteServerButton server={selectedServer} className="server-error__delete-btn">remove
|
it</DeleteServerButton> or
|
||||||
it</DeleteServerButton> or
|
<Link to={`/server/${selectedServer.id}/edit?reconnect=true`}>edit it</Link>.
|
||||||
<Link to={`/server/${selectedServer.id}/edit?reconnect=true`}>edit it</Link>.
|
</p>
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</NoMenuLayout>
|
</NoMenuLayout>
|
||||||
|
|||||||
@@ -14,3 +14,11 @@
|
|||||||
border-radius: .5rem;
|
border-radius: .5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
:root {
|
||||||
|
--header-height: 56px;
|
||||||
|
/* Width of ShlinkWebComponent's side menu when not collapsed */
|
||||||
|
--aside-menu-width: 260px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
@mixin horizontal-align {
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
@mixin vertical-align($extraTransforms: null) {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%) $extraTransforms;
|
|
||||||
}
|
|
||||||
@@ -51,14 +51,12 @@ describe('<MainHeader />', () => {
|
|||||||
const toggle = screen.getByLabelText('Toggle navigation');
|
const toggle = screen.getByLabelText('Toggle navigation');
|
||||||
const icon = toggle.firstChild;
|
const icon = toggle.firstChild;
|
||||||
|
|
||||||
expect(icon).toHaveAttribute('class', expect.stringMatching(/main-header__toggle-icon$/));
|
expect(icon).not.toHaveClass('tw:rotate-180');
|
||||||
await user.click(toggle);
|
await user.click(toggle);
|
||||||
expect(icon).toHaveAttribute(
|
|
||||||
'class',
|
expect(icon).toHaveClass('tw:rotate-180');
|
||||||
expect.stringMatching(/main-header__toggle-icon main-header__toggle-icon--opened$/),
|
|
||||||
);
|
|
||||||
await user.click(toggle);
|
await user.click(toggle);
|
||||||
expect(icon).toHaveAttribute('class', expect.stringMatching(/main-header__toggle-icon$/));
|
expect(icon).not.toHaveClass('tw:rotate-180');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('opens Collapse when clicking toggle', async () => {
|
it('opens Collapse when clicking toggle', async () => {
|
||||||
|
|||||||
@@ -16,11 +16,16 @@ describe('<ShlinkVersionsContainer />', () => {
|
|||||||
])('passes a11y checks', (selectedServer) => checkAccessibility(setUp(selectedServer)));
|
])('passes a11y checks', (selectedServer) => checkAccessibility(setUp(selectedServer)));
|
||||||
|
|
||||||
it.each([
|
it.each([
|
||||||
[null, 'text-center'],
|
[null, false],
|
||||||
[fromPartial<SelectedServer>({}), 'text-center'],
|
[fromPartial<SelectedServer>({}), false],
|
||||||
[fromPartial<ReachableServer>({ version: '1.0.0' }), 'text-center shlink-versions-container--with-sidebar'],
|
[fromPartial<ReachableServer>({ version: '1.0.0' }), true],
|
||||||
])('renders proper col classes based on sidebar status', (selectedServer, expectedClasses) => {
|
])('renders proper col classes based on sidebar status', (selectedServer, shouldAddMargin) => {
|
||||||
const { container } = setUp(selectedServer);
|
const { container } = setUp(selectedServer);
|
||||||
expect(container.firstChild).toHaveAttribute('class', `${expectedClasses}`);
|
|
||||||
|
if (shouldAddMargin) {
|
||||||
|
expect(container.firstChild).toHaveClass('tw:md:ml-(--aside-menu-width)');
|
||||||
|
} else {
|
||||||
|
expect(container.firstChild).not.toHaveClass('tw:md:ml-(--aside-menu-width)');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user