feat!: updated admin UI (#7424)

## Description

- Updates admin UI with more condensed spacing throughout.
- Improves hover states and read-only states for various components.
- Removes the `Merriweather` font from `next/font` and replaces with
stack of system serif fonts and fallbacks (Georgia, etc). Closes #7257

## BREAKING CHANGES
- Custom components and styling that don't utilize Payload's CSS/SCSS
variables may need adjustments to match the updated styling.
- If you are using the `Merriweather` font, you will need to manually
configure `next/font` in your own project.

---------

Co-authored-by: Paul Popus <paul@nouance.io>
This commit is contained in:
Tylan Davis
2024-08-05 11:08:00 -04:00
committed by GitHub
parent 9a3bce1118
commit 68553ff974
140 changed files with 1410 additions and 1155 deletions

View File

@@ -35,7 +35,7 @@
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
border-radius: 2px; border-radius: var(--style-radius-s);
background-color: var(--theme-elevation-50); background-color: var(--theme-elevation-50);
opacity: 0; opacity: 0;
} }
@@ -51,6 +51,7 @@
} }
&--active { &--active {
font-weight: 600;
&::before { &::before {
opacity: 1; opacity: 1;
background-color: var(--theme-elevation-100); background-color: var(--theme-elevation-100);
@@ -78,14 +79,15 @@
gap: 4px; gap: 4px;
width: 100%; width: 100%;
height: 100%; height: 100%;
padding: calc(var(--base) / 2) calc(var(--base)); line-height: base(1.2);
padding: base(0.2) base(0.6);
} }
&__count { &__count {
min-width: 22px; line-height: base(0.8);
min-width: base(0.8);
text-align: center; text-align: center;
padding: 2px 7px;
background-color: var(--theme-elevation-100); background-color: var(--theme-elevation-100);
border-radius: 1px; border-radius: var(--style-radius-s);
} }
} }

View File

@@ -37,10 +37,12 @@ const Component: React.FC<{
<p>{t('general:changesNotSaved')}</p> <p>{t('general:changesNotSaved')}</p>
</div> </div>
<div className={`${baseClass}__controls`}> <div className={`${baseClass}__controls`}>
<Button buttonStyle="secondary" onClick={onCancel}> <Button buttonStyle="secondary" onClick={onCancel} size="large">
{t('general:stayOnThisPage')} {t('general:stayOnThisPage')}
</Button> </Button>
<Button onClick={onConfirm}>{t('general:leaveAnyway')}</Button> <Button onClick={onConfirm} size="large">
{t('general:leaveAnyway')}
</Button>
</div> </div>
</div> </div>
</Modal> </Modal>

View File

@@ -5,7 +5,6 @@ import { initI18n, rtlLanguages } from '@payloadcms/translations'
import { RootProvider } from '@payloadcms/ui' import { RootProvider } from '@payloadcms/ui'
import '@payloadcms/ui/scss/app.scss' import '@payloadcms/ui/scss/app.scss'
import { buildComponentMap } from '@payloadcms/ui/utilities/buildComponentMap' import { buildComponentMap } from '@payloadcms/ui/utilities/buildComponentMap'
import { Merriweather } from 'next/font/google'
import { headers as getHeaders, cookies as nextCookies } from 'next/headers.js' import { headers as getHeaders, cookies as nextCookies } from 'next/headers.js'
import { createClientConfig, parseCookies } from 'payload' import { createClientConfig, parseCookies } from 'payload'
import React from 'react' import React from 'react'
@@ -16,14 +15,6 @@ import { getRequestTheme } from '../../utilities/getRequestTheme.js'
import { DefaultEditView } from '../../views/Edit/Default/index.js' import { DefaultEditView } from '../../views/Edit/Default/index.js'
import { DefaultListView } from '../../views/List/Default/index.js' import { DefaultListView } from '../../views/List/Default/index.js'
const merriweather = Merriweather({
display: 'swap',
style: ['normal', 'italic'],
subsets: ['latin'],
variable: '--font-serif',
weight: ['400', '900'],
})
export const metadata = { export const metadata = {
description: 'Generated by Next.js', description: 'Generated by Next.js',
title: 'Next.js', title: 'Next.js',
@@ -100,7 +91,7 @@ export const RootLayout = async ({
}) })
return ( return (
<html className={merriweather.variable} data-theme={theme} dir={dir} lang={languageCode}> <html data-theme={theme} dir={dir} lang={languageCode}>
<body> <body>
<RootProvider <RootProvider
componentMap={componentMap} componentMap={componentMap}

View File

@@ -1,9 +1,9 @@
@import './styles.scss'; @import 'styles';
@import './toasts.scss'; @import './toasts.scss';
@import './colors.scss'; @import './colors.scss';
:root { :root {
--base-px: 25; --base-px: 20;
--base-body-size: 13; --base-body-size: 13;
--base: calc((var(--base-px) / var(--base-body-size)) * 1rem); --base: calc((var(--base-px) / var(--base-body-size)) * 1rem);
@@ -21,6 +21,7 @@
--theme-baseline-body-size: #{$baseline-body-size}; --theme-baseline-body-size: #{$baseline-body-size};
--font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
sans-serif; sans-serif;
--font-serif: Georgia, 'Bitstream Charter', 'Charis SIL', Utopia, 'URW Bookman L', serif;
--font-mono: monospace; --font-mono: monospace;
--style-radius-s: #{$style-radius-s}; --style-radius-s: #{$style-radius-s};
@@ -67,12 +68,6 @@ html {
@extend %body; @extend %body;
background: var(--theme-bg); background: var(--theme-bg);
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
opacity: 0;
&[data-theme='dark'],
&[data-theme='light'] {
opacity: initial;
}
&[data-theme='dark'] { &[data-theme='dark'] {
--theme-bg: var(--theme-elevation-0); --theme-bg: var(--theme-elevation-0);
@@ -111,12 +106,12 @@ body {
} }
::selection { ::selection {
background: var(--theme-success-500); background: var(--color-success-250);
color: var(--theme-base-800); color: var(--theme-base-800);
} }
::-moz-selection { ::-moz-selection {
background: var(--theme-success-500); background: var(--color-success-250);
color: var(--theme-base-800); color: var(--theme-base-800);
} }

View File

@@ -0,0 +1,59 @@
@import 'vars';
@import 'queries';
.Toastify {
.Toastify__toast-container {
left: base(5);
transform: none;
right: base(5);
width: auto;
}
.Toastify__toast {
padding: base(0.5);
border-radius: $style-radius-m;
font-weight: 600;
}
.Toastify__close-button {
align-self: center;
opacity: 0.7;
&:hover {
opacity: 1;
}
}
.Toastify__toast--success {
color: var(--color-success-900);
background: var(--color-success-500);
.Toastify__progress-bar {
background-color: var(--color-success-900);
}
}
.Toastify__close-button--success {
color: var(--color-success-900);
}
.Toastify__toast--error {
background: var(--theme-error-500);
color: #fff;
.Toastify__progress-bar {
background-color: #fff;
}
}
.Toastify__close-button--light {
color: inherit;
}
@include mid-break {
.Toastify__toast-container {
left: $baseline;
right: $baseline;
}
}
}

View File

@@ -1,24 +1,28 @@
@import './styles.scss';
.payload-toast-container { .payload-toast-container {
padding: 0;
margin: 0;
.payload-toast-close-button { .payload-toast-close-button {
position: absolute;
order: 3;
left: unset; left: unset;
right: 0.5rem; inset-inline-end: base(0.5);
top: 1.55rem; top: 50%;
color: var(--theme-elevation-400); transform: translateY(-50%);
color: var(--theme-elevation-600);
background: unset; background: unset;
border: none; border: none;
display: flex;
width: 1.25rem;
height: 1.25rem;
justify-content: center;
align-items: center;
&:hover {
background: none;
}
svg { svg {
width: 2rem; width: base(0.75);
height: 2rem; height: base(0.75);
}
&:hover {
color: var(--theme-elevation-250);
background: none;
} }
[dir='RTL'] & { [dir='RTL'] & {
@@ -27,16 +31,20 @@
} }
} }
.toast-title {
line-height: base(1);
}
.payload-toast-item { .payload-toast-item {
padding: 1rem 2.5rem 1rem 1rem; padding: base(0.5);
color: var(--theme-text); color: var(--theme-elevation-800);
font-style: normal; font-style: normal;
font-weight: 600; font-weight: 600;
display: flex; display: flex;
gap: 1rem; gap: 1rem;
align-items: center; align-items: center;
width: 100%; width: 100%;
border-radius: 0.15rem; border-radius: 4px;
border: 1px solid var(--theme-border-color); border: 1px solid var(--theme-border-color);
background: var(--theme-input-bg); background: var(--theme-input-bg);
box-shadow: box-shadow:
@@ -45,6 +53,7 @@
.toast-content { .toast-content {
transition: opacity 100ms cubic-bezier(0.55, 0.055, 0.675, 0.19); transition: opacity 100ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
width: 100%;
} }
&[data-front='false'] { &[data-front='false'] {
@@ -60,51 +69,72 @@
} }
.toast-icon { .toast-icon {
svg { width: base(1);
width: 2.4rem; height: base(1);
height: 2.4rem; margin: 0;
display: flex;
align-items: center;
justify-content: center;
& > * {
width: base(1.2);
height: base(1.2);
} }
} }
&.toast-warning { &.toast-warning {
border-color: var(--theme-warning-200); color: var(--theme-warning-800);
background-color: var(--theme-warning-100); border-color: var(--theme-warning-150);
background-color: var(--theme-warning-50);
.payload-toast-close-button {
color: var(--theme-warning-600);
&:hover {
color: var(--theme-warning-250);
}
}
} }
&.toast-error { &.toast-error {
border-color: var(--theme-error-300); color: var(--theme-error-800);
background-color: var(--theme-error-150); border-color: var(--theme-error-150);
background-color: var(--theme-error-50);
.payload-toast-close-button {
color: var(--theme-error-600);
&:hover {
color: var(--theme-error-250);
}
}
} }
&.toast-success { &.toast-success {
border-color: var(--theme-success-200); color: var(--theme-success-800);
background-color: var(--theme-success-100); border-color: var(--theme-success-150);
background-color: var(--theme-success-50);
.payload-toast-close-button {
color: var(--theme-success-600);
&:hover {
color: var(--theme-success-250);
}
}
} }
&.toast-info { &.toast-info {
border-color: var(--theme-elevation-250); color: var(--theme-elevation-800);
background-color: var(--theme-elevation-100); border-color: var(--theme-elevation-150);
} background-color: var(--theme-elevation-50);
[data-theme='light'] & { .payload-toast-close-button {
&.toast-warning { color: var(--theme-elevation-600);
border-color: var(--theme-warning-550);
background-color: var(--theme-warning-100);
}
&.toast-error { &:hover {
border-color: var(--theme-error-200); color: var(--theme-elevation-250);
background-color: var(--theme-error-50); }
}
&.toast-success {
border-color: var(--theme-success-550);
background-color: var(--theme-success-50);
}
&.toast-info {
border-color: var(--theme-border-color);
background-color: var(--theme-elevation-50);
} }
} }
} }

View File

@@ -15,17 +15,10 @@
font-weight: 500; font-weight: 500;
} }
%jumbo {
font-size: base(2.5);
line-height: 1;
margin: 0 0 base(2);
}
%h1 { %h1 {
margin: 0 0 base(1); margin: 0 0 base(1);
font-size: base(2); font-size: base(1.6);
line-height: 1.15; line-height: base(1.8);
letter-spacing: -1px;
@include small-break { @include small-break {
letter-spacing: -0.5px; letter-spacing: -0.5px;
@@ -35,9 +28,8 @@
%h2 { %h2 {
margin: 0 0 base(1); margin: 0 0 base(1);
font-size: base(1.25); font-size: base(1.3);
line-height: 1.15; line-height: base(1.6);
letter-spacing: -0.5px;
@include small-break { @include small-break {
font-size: base(0.85); font-size: base(0.85);
@@ -46,9 +38,8 @@
%h3 { %h3 {
margin: 0 0 base(1); margin: 0 0 base(1);
font-size: base(0.925); font-size: base(1);
line-height: 1.25; line-height: base(1.2);
letter-spacing: -0.5px;
@include small-break { @include small-break {
font-size: base(0.65); font-size: base(0.65);
@@ -58,27 +49,27 @@
%h4 { %h4 {
margin: 0 0 $baseline; margin: 0 0 $baseline;
font-size: base(0.75); font-size: base(0.8);
line-height: 1.5; line-height: base(1);
letter-spacing: -0.375px; letter-spacing: -0.375px;
} }
%h5 { %h5 {
margin: 0; margin: 0;
font-size: base(0.5625); font-size: base(0.65);
line-height: 1.5; line-height: base(0.8);
} }
%h6 { %h6 {
margin: 0; margin: 0;
font-size: base(0.5); font-size: base(0.6);
line-height: 1.5; line-height: base(0.8);
} }
%small { %small {
margin: 0; margin: 0;
font-size: 11px; font-size: 12px;
line-height: 1.5; line-height: 20px;
} }
///////////////////////////// /////////////////////////////

View File

@@ -13,7 +13,7 @@ $breakpoint-l-width: 1440px !default;
// BASELINE GRID // BASELINE GRID
////////////////////////////// //////////////////////////////
$baseline-px: 25px !default; $baseline-px: 20px !default;
$baseline-body-size: 13px !default; $baseline-body-size: 13px !default;
$baseline: math.div($baseline-px, $baseline-body-size) + rem; $baseline: math.div($baseline-px, $baseline-body-size) + rem;
@@ -40,7 +40,7 @@ $color-purple: #f3ddf3 !default;
$style-radius-s: 3px !default; $style-radius-s: 3px !default;
$style-radius-m: 4px !default; $style-radius-m: 4px !default;
$style-radius-l: 9px !default; $style-radius-l: 8px !default;
$style-stroke-width: 1px !default; $style-stroke-width: 1px !default;
$style-stroke-width-s: 1px !default; $style-stroke-width-s: 1px !default;
@@ -50,8 +50,8 @@ $style-stroke-width-m: 2px !default;
// MISC // MISC
////////////////////////////// //////////////////////////////
$top-header-offset: calc(var(--base) - 1px); $top-header-offset: calc(base(1) - 1px);
$top-header-offset-m: calc(var(--base) * 3); $top-header-offset-m: base(3);
$focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500); $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
////////////////////////////// //////////////////////////////
@@ -59,41 +59,19 @@ $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
////////////////////////////// //////////////////////////////
@mixin shadow-sm { @mixin shadow-sm {
box-shadow: box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.1);
0 2px 3px 0 rgba(0, 2, 4, 0.05),
0 10px 4px -8px rgba(0, 2, 4, 0.02);
} }
@mixin shadow-m { @mixin shadow-m {
box-shadow: box-shadow: 0 4px 8px -3px rgba(0, 0, 0, 0.1);
0 0 30px 0 rgb(0 2 4 / 12%),
0 30px 25px -8px rgb(0 2 4 / 10%);
} }
@mixin shadow-lg { @mixin shadow-lg {
box-shadow: box-shadow: 0 -2px 16px -2px rgba(0, 0, 0, 0.2);
0 20px 35px -10px rgba(0, 2, 4, 0.2),
0 6px 4px -4px rgba(0, 2, 4, 0.02);
} }
@mixin shadow-lg-top { @mixin shadow-lg-top {
box-shadow: box-shadow: 0 2px 16px -2px rgba(0, 0, 0, 0.2);
0 -20px 35px -10px rgba(0, 2, 4, 0.2),
0 -6px 4px -4px rgba(0, 2, 4, 0.02);
}
@mixin shadow {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.07);
&:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
}
@mixin inputShadowActive {
box-shadow:
0 2px 3px 0 rgba(0, 2, 4, 0.16),
0 6px 4px -4px rgba(0, 2, 4, 0.13);
} }
@mixin inputShadow { @mixin inputShadow {
@@ -101,15 +79,7 @@ $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
&:not(:disabled) { &:not(:disabled) {
&:hover { &:hover {
box-shadow: box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.2);
0 2px 3px 0 rgba(0, 2, 4, 0.13),
0 6px 4px -4px rgba(0, 2, 4, 0.1);
}
&:active,
&:focus-within,
&:focus {
@include inputShadowActive;
} }
} }
} }
@@ -147,19 +117,33 @@ $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
@include blur-bg(var(--theme-bg), 0.3); @include blur-bg(var(--theme-bg), 0.3);
} }
@mixin readOnly {
background: var(--theme-elevation-100);
color: var(--theme-elevation-400);
box-shadow: none;
&:hover {
border-color: var(--theme-elevation-150);
box-shadow: none;
}
}
@mixin formInput() { @mixin formInput() {
@include inputShadow; @include inputShadow;
font-family: var(--font-body); font-family: var(--font-body);
width: 100%; width: 100%;
border: 1px solid var(--theme-elevation-150); border: 1px solid var(--theme-elevation-150);
border-radius: var(--style-radius-s);
background: var(--theme-input-bg); background: var(--theme-input-bg);
color: var(--theme-elevation-800); color: var(--theme-elevation-800);
border-radius: 0;
font-size: 1rem; font-size: 1rem;
height: base(2); height: base(2);
line-height: base(1); line-height: base(1);
padding: base(0.5) base(0.75); padding: base(0.4) base(0.75);
-webkit-appearance: none; -webkit-appearance: none;
transition-property: border, box-shadow;
transition-duration: 100ms;
transition-timing-function: cubic-bezier(0, 0.2, 0.2, 1);
&[data-rtl='true'] { &[data-rtl='true'] {
direction: rtl; direction: rtl;
@@ -189,12 +173,7 @@ $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
} }
&:disabled { &:disabled {
background: var(--theme-elevation-200); @include readOnly;
color: var(--theme-elevation-450);
&:hover {
border-color: var(--theme-elevation-150);
}
} }
} }

View File

@@ -77,7 +77,7 @@ export const CreateFirstUserClient: React.FC<{
readOnly={false} readOnly={false}
schemaPath={userSlug} schemaPath={userSlug}
/> />
<FormSubmit>{t('general:create')}</FormSubmit> <FormSubmit size="large">{t('general:create')}</FormSubmit>
</Form> </Form>
) )
} }

View File

@@ -26,13 +26,9 @@
padding: 0; padding: 0;
margin: 0; margin: 0;
list-style: none; list-style: none;
display: flex;
gap: var(--gap); gap: var(--gap);
flex-wrap: wrap; display: grid;
grid-template-columns: repeat(var(--cols), 1fr);
li {
width: calc(100% / var(--cols) - var(--gap) / var(--cols) * (var(--cols) - 1));
}
.card { .card {
height: 100%; height: 100%;
@@ -49,10 +45,18 @@
} }
@include small-break { @include small-break {
--cols: 1; --cols: 2;
&__wrap { &__wrap {
gap: var(--base); gap: var(--base);
} }
&__card-list {
gap: base(0.4);
}
}
@include extra-small-break {
--cols: 1;
} }
} }

View File

@@ -190,7 +190,7 @@ export const Auth: React.FC<Props> = (props) => {
buttonStyle="secondary" buttonStyle="secondary"
disabled={disabled} disabled={disabled}
onClick={() => handleChangePassword(false)} onClick={() => handleChangePassword(false)}
size="small" size="medium"
> >
{t('general:cancel')} {t('general:cancel')}
</Button> </Button>
@@ -201,7 +201,7 @@ export const Auth: React.FC<Props> = (props) => {
disabled={disabled} disabled={disabled}
id="change-password" id="change-password"
onClick={() => handleChangePassword(true)} onClick={() => handleChangePassword(true)}
size="small" size="medium"
> >
{t('authentication:changePassword')} {t('authentication:changePassword')}
</Button> </Button>
@@ -211,7 +211,7 @@ export const Auth: React.FC<Props> = (props) => {
buttonStyle="secondary" buttonStyle="secondary"
disabled={disabled} disabled={disabled}
onClick={() => void unlock()} onClick={() => void unlock()}
size="small" size="medium"
> >
{t('authentication:forceUnlock')} {t('authentication:forceUnlock')}
</Button> </Button>

View File

@@ -8,8 +8,8 @@
} }
&__auth { &__auth {
margin-bottom: calc(var(--base) * 2); margin-bottom: base(1.6);
margin-top: calc(var(--base) * 0.5); border-radius: var(--style-radius-s);
} }
@include small-break { @include small-break {

View File

@@ -51,7 +51,7 @@ export const ForgotPasswordView: React.FC<AdminViewProps> = ({ initPageResult })
/> />
</p> </p>
<br /> <br />
<Button Link={Link} buttonStyle="secondary" el="link" to={adminRoute}> <Button Link={Link} buttonStyle="secondary" el="link" size="large" to={adminRoute}>
{i18n.t('general:backToDashboard')} {i18n.t('general:backToDashboard')}
</Button> </Button>
</Fragment> </Fragment>

View File

@@ -2,7 +2,6 @@
.collection-list { .collection-list {
width: 100%; width: 100%;
margin-top: base(0.5);
&__wrap { &__wrap {
padding-bottom: var(--spacing-view-bottom); padding-bottom: var(--spacing-view-bottom);
@@ -14,7 +13,7 @@
&__header { &__header {
display: flex; display: flex;
align-items: flex-end; align-items: center;
flex-wrap: wrap; flex-wrap: wrap;
gap: base(0.75); gap: base(0.75);
@@ -28,14 +27,12 @@
.pill { .pill {
position: relative; position: relative;
top: -14px;
margin: 0; margin: 0;
} }
} }
&__sub-header { &__sub-header {
flex-basis: 100%; flex-basis: 100%;
margin-top: base(0.25);
} }
.table { .table {
@@ -57,7 +54,7 @@
#heading-_select, #heading-_select,
.cell-_select { .cell-_select {
min-width: unset; min-width: unset;
width: auto; width: base(1);
} }
} }
} }

View File

@@ -91,7 +91,7 @@ export const LoginForm: React.FC<{
> >
{t('authentication:forgotPasswordQuestion')} {t('authentication:forgotPasswordQuestion')}
</Link> </Link>
<FormSubmit>{t('authentication:login')}</FormSubmit> <FormSubmit size="large">{t('authentication:login')}</FormSubmit>
</Form> </Form>
) )
} }

View File

@@ -20,7 +20,7 @@ export const LogoutClient: React.FC<{
useEffect(() => { useEffect(() => {
if (!isLoggingOut) { if (!isLoggingOut) {
setIsLoggingOut(true) setIsLoggingOut(true)
logOut() void logOut()
} }
}, [isLoggingOut, logOut]) }, [isLoggingOut, logOut])
@@ -33,6 +33,7 @@ export const LogoutClient: React.FC<{
Link={Link} Link={Link}
buttonStyle="secondary" buttonStyle="secondary"
el="link" el="link"
size="large"
url={formatAdminURL({ url={formatAdminURL({
adminRoute, adminRoute,
path: `/login${ path: `/login${

View File

@@ -38,7 +38,13 @@ export const NotFoundClient: React.FC<{
<Gutter className={`${baseClass}__wrap`}> <Gutter className={`${baseClass}__wrap`}>
<h1>{t('general:nothingFound')}</h1> <h1>{t('general:nothingFound')}</h1>
<p>{t('general:sorryNotFound')}</p> <p>{t('general:sorryNotFound')}</p>
<Button Link={Link} className={`${baseClass}__button`} el="link" to={adminRoute}> <Button
Link={Link}
className={`${baseClass}__button`}
el="link"
size="large"
to={adminRoute}
>
{t('general:backToDashboard')} {t('general:backToDashboard')}
</Button> </Button>
</Gutter> </Gutter>

View File

@@ -81,7 +81,7 @@ export const ResetPasswordClient: React.FC<Args> = ({ token }) => {
/> />
<ConfirmPasswordField /> <ConfirmPasswordField />
<HiddenField forceUsePathFromProps name="token" value={token} /> <HiddenField forceUsePathFromProps name="token" value={token} />
<FormSubmit>{i18n.t('authentication:resetPassword')}</FormSubmit> <FormSubmit size="large">{i18n.t('authentication:resetPassword')}</FormSubmit>
</Form> </Form>
) )
} }

View File

@@ -30,7 +30,13 @@ export const UnauthorizedView: AdminViewComponent = ({ initPageResult }) => {
<Gutter className={baseClass}> <Gutter className={baseClass}>
<h2>{i18n.t('error:unauthorized')}</h2> <h2>{i18n.t('error:unauthorized')}</h2>
<p>{i18n.t('error:notAllowedToAccessPage')}</p> <p>{i18n.t('error:notAllowedToAccessPage')}</p>
<Button Link={Link} className={`${baseClass}__button`} el="link" to={logoutRoute}> <Button
Link={Link}
className={`${baseClass}__button`}
el="link"
size="large"
to={logoutRoute}
>
{i18n.t('authentication:logOut')} {i18n.t('authentication:logOut')}
</Button> </Button>
</Gutter> </Gutter>

View File

@@ -21,7 +21,7 @@ import './index.scss'
const baseClass = 'rich-text-lexical' const baseClass = 'rich-text-lexical'
const _RichText: React.FC< const RichTextComponent: React.FC<
{ {
editorConfig: SanitizedClientEditorConfig // With rendered features n stuff editorConfig: SanitizedClientEditorConfig // With rendered features n stuff
name: string name: string
@@ -41,7 +41,7 @@ const _RichText: React.FC<
label, label,
labelProps, labelProps,
path: pathFromProps, path: pathFromProps,
readOnly, readOnly: readOnlyFromProps,
required, required,
style, style,
validate, // Users can pass in client side validation if they WANT to, but it's not required anymore validate, // Users can pass in client side validation if they WANT to, but it's not required anymore
@@ -59,21 +59,33 @@ const _RichText: React.FC<
// Removing props from the dependencies array fixed this issue: https://github.com/payloadcms/payload/issues/3709 // Removing props from the dependencies array fixed this issue: https://github.com/payloadcms/payload/issues/3709
[validate, required], [validate, required],
) )
const { path: pathFromContext } = useFieldProps() const { path: pathFromContext, readOnly: readOnlyFromContext } = useFieldProps()
const fieldType = useField<SerializedEditorState>({ const fieldType = useField<SerializedEditorState>({
path: pathFromContext ?? pathFromProps ?? name, path: pathFromContext ?? pathFromProps ?? name,
validate: memoizedValidate, validate: memoizedValidate,
}) })
const { errorMessage, initialValue, path, schemaPath, setValue, showError, value } = fieldType const {
errorMessage,
formInitializing,
formProcessing,
initialValue,
path,
schemaPath,
setValue,
showError,
value,
} = fieldType
const disabled = readOnlyFromProps || readOnlyFromContext || formProcessing || formInitializing
const classes = [ const classes = [
baseClass, baseClass,
'field-type', 'field-type',
className, className,
showError && 'error', showError && 'error',
readOnly && `${baseClass}--read-only`, disabled && `${baseClass}--read-only`,
editorConfig?.admin?.hideGutter !== true ? `${baseClass}--show-gutter` : null, editorConfig?.admin?.hideGutter !== true ? `${baseClass}--show-gutter` : null,
] ]
.filter(Boolean) .filter(Boolean)
@@ -114,7 +126,7 @@ const _RichText: React.FC<
setValue(serializedEditorState) setValue(serializedEditorState)
}} }}
path={path} path={path}
readOnly={readOnly} readOnly={disabled}
value={value} value={value}
/> />
</ErrorBoundary> </ErrorBoundary>
@@ -139,4 +151,4 @@ function fallbackRender({ error }): React.ReactElement {
) )
} }
export const RichText = withCondition(_RichText) export const RichText = withCondition(RichTextComponent)

View File

@@ -9,7 +9,8 @@
position: relative; position: relative;
font-family: var(--font-serif); font-family: var(--font-serif);
font-size: calc(var(--base) * 0.625); font-size: base(0.8);
letter-spacing: 0.02em;
h1, h1,
h2, h2,
@@ -19,6 +20,7 @@
h6 { h6 {
font-family: var(--font-body); font-family: var(--font-body);
line-height: 1.125; line-height: 1.125;
letter-spacing: 0;
} }
} }

View File

@@ -37,24 +37,18 @@
line-height: 1.125; line-height: 1.125;
color: rgb(5, 5, 5); color: rgb(5, 5, 5);
font-weight: 500; font-weight: 500;
margin-top: 2rem;
margin-bottom: 1rem;
} }
&__h2 { &__h2 {
font-size: 2rem; font-size: 2rem;
color: rgb(5, 5, 5); color: rgb(5, 5, 5);
font-weight: 700; font-weight: 700;
margin-top: 1.8rem;
margin-bottom: 1rem;
} }
&__h3 { &__h3 {
font-size: 1.4rem; font-size: 1.4rem;
color: rgb(101, 103, 107); color: rgb(101, 103, 107);
font-weight: 700; font-weight: 700;
margin-top: 1.4rem;
margin-bottom: 1rem;
} }
&__indent { &__indent {

View File

@@ -3,7 +3,7 @@
@import './colors.scss'; @import './colors.scss';
:root { :root {
--base-px: 25; --base-px: 20;
--base-body-size: 13; --base-body-size: 13;
--base: calc((var(--base-px) / var(--base-body-size)) * 1rem); --base: calc((var(--base-px) / var(--base-body-size)) * 1rem);
@@ -21,6 +21,7 @@
--theme-baseline-body-size: #{$baseline-body-size}; --theme-baseline-body-size: #{$baseline-body-size};
--font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
sans-serif; sans-serif;
--font-serif: Georgia, 'Bitstream Charter', 'Charis SIL', Utopia, 'URW Bookman L', serif;
--font-mono: monospace; --font-mono: monospace;
--style-radius-s: #{$style-radius-s}; --style-radius-s: #{$style-radius-s};
@@ -67,12 +68,6 @@ html {
@extend %body; @extend %body;
background: var(--theme-bg); background: var(--theme-bg);
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
opacity: 0;
&[data-theme='dark'],
&[data-theme='light'] {
opacity: initial;
}
&[data-theme='dark'] { &[data-theme='dark'] {
--theme-bg: var(--theme-elevation-0); --theme-bg: var(--theme-elevation-0);
@@ -111,12 +106,12 @@ body {
} }
::selection { ::selection {
background: var(--theme-success-500); background: var(--color-success-250);
color: var(--theme-base-800); color: var(--theme-base-800);
} }
::-moz-selection { ::-moz-selection {
background: var(--theme-success-500); background: var(--color-success-250);
color: var(--theme-base-800); color: var(--theme-base-800);
} }

View File

@@ -0,0 +1,59 @@
@import 'vars';
@import 'queries';
.Toastify {
.Toastify__toast-container {
left: base(5);
transform: none;
right: base(5);
width: auto;
}
.Toastify__toast {
padding: base(0.5);
border-radius: $style-radius-m;
font-weight: 600;
}
.Toastify__close-button {
align-self: center;
opacity: 0.7;
&:hover {
opacity: 1;
}
}
.Toastify__toast--success {
color: var(--color-success-900);
background: var(--color-success-500);
.Toastify__progress-bar {
background-color: var(--color-success-900);
}
}
.Toastify__close-button--success {
color: var(--color-success-900);
}
.Toastify__toast--error {
background: var(--theme-error-500);
color: #fff;
.Toastify__progress-bar {
background-color: #fff;
}
}
.Toastify__close-button--light {
color: inherit;
}
@include mid-break {
.Toastify__toast-container {
left: $baseline;
right: $baseline;
}
}
}

View File

@@ -1,24 +1,28 @@
@import './styles.scss';
.payload-toast-container { .payload-toast-container {
padding: 0;
margin: 0;
.payload-toast-close-button { .payload-toast-close-button {
position: absolute;
order: 3;
left: unset; left: unset;
right: 0.5rem; inset-inline-end: base(0.5);
top: 1.55rem; top: 50%;
color: var(--theme-elevation-400); transform: translateY(-50%);
color: var(--theme-elevation-600);
background: unset; background: unset;
border: none; border: none;
display: flex;
width: 1.25rem;
height: 1.25rem;
justify-content: center;
align-items: center;
&:hover {
background: none;
}
svg { svg {
width: 2rem; width: base(0.75);
height: 2rem; height: base(0.75);
}
&:hover {
color: var(--theme-elevation-250);
background: none;
} }
[dir='RTL'] & { [dir='RTL'] & {
@@ -27,16 +31,20 @@
} }
} }
.toast-title {
line-height: base(1);
}
.payload-toast-item { .payload-toast-item {
padding: 1rem 2.5rem 1rem 1rem; padding: base(0.5);
color: var(--theme-text); color: var(--theme-elevation-800);
font-style: normal; font-style: normal;
font-weight: 600; font-weight: 600;
display: flex; display: flex;
gap: 1rem; gap: 1rem;
align-items: center; align-items: center;
width: 100%; width: 100%;
border-radius: 0.15rem; border-radius: 4px;
border: 1px solid var(--theme-border-color); border: 1px solid var(--theme-border-color);
background: var(--theme-input-bg); background: var(--theme-input-bg);
box-shadow: box-shadow:
@@ -45,6 +53,7 @@
.toast-content { .toast-content {
transition: opacity 100ms cubic-bezier(0.55, 0.055, 0.675, 0.19); transition: opacity 100ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
width: 100%;
} }
&[data-front='false'] { &[data-front='false'] {
@@ -60,51 +69,72 @@
} }
.toast-icon { .toast-icon {
svg { width: base(1);
width: 2.4rem; height: base(1);
height: 2.4rem; margin: 0;
display: flex;
align-items: center;
justify-content: center;
& > * {
width: base(1.2);
height: base(1.2);
} }
} }
&.toast-warning { &.toast-warning {
border-color: var(--theme-warning-200); color: var(--theme-warning-800);
background-color: var(--theme-warning-100); border-color: var(--theme-warning-150);
background-color: var(--theme-warning-50);
.payload-toast-close-button {
color: var(--theme-warning-600);
&:hover {
color: var(--theme-warning-250);
}
}
} }
&.toast-error { &.toast-error {
border-color: var(--theme-error-300); color: var(--theme-error-800);
background-color: var(--theme-error-150); border-color: var(--theme-error-150);
background-color: var(--theme-error-50);
.payload-toast-close-button {
color: var(--theme-error-600);
&:hover {
color: var(--theme-error-250);
}
}
} }
&.toast-success { &.toast-success {
border-color: var(--theme-success-200); color: var(--theme-success-800);
background-color: var(--theme-success-100); border-color: var(--theme-success-150);
background-color: var(--theme-success-50);
.payload-toast-close-button {
color: var(--theme-success-600);
&:hover {
color: var(--theme-success-250);
}
}
} }
&.toast-info { &.toast-info {
border-color: var(--theme-elevation-250); color: var(--theme-elevation-800);
background-color: var(--theme-elevation-100); border-color: var(--theme-elevation-150);
} background-color: var(--theme-elevation-50);
[data-theme='light'] & { .payload-toast-close-button {
&.toast-warning { color: var(--theme-elevation-600);
border-color: var(--theme-warning-550);
background-color: var(--theme-warning-100);
}
&.toast-error { &:hover {
border-color: var(--theme-error-200); color: var(--theme-elevation-250);
background-color: var(--theme-error-50); }
}
&.toast-success {
border-color: var(--theme-success-550);
background-color: var(--theme-success-50);
}
&.toast-info {
border-color: var(--theme-border-color);
background-color: var(--theme-elevation-50);
} }
} }
} }

View File

@@ -15,17 +15,10 @@
font-weight: 500; font-weight: 500;
} }
%jumbo {
font-size: base(2.5);
line-height: 1;
margin: 0 0 base(2);
}
%h1 { %h1 {
margin: 0 0 base(1); margin: 0 0 base(1);
font-size: base(2); font-size: base(1.6);
line-height: 1.15; line-height: base(1.8);
letter-spacing: -1px;
@include small-break { @include small-break {
letter-spacing: -0.5px; letter-spacing: -0.5px;
@@ -35,9 +28,8 @@
%h2 { %h2 {
margin: 0 0 base(1); margin: 0 0 base(1);
font-size: base(1.25); font-size: base(1.3);
line-height: 1.15; line-height: base(1.6);
letter-spacing: -0.5px;
@include small-break { @include small-break {
font-size: base(0.85); font-size: base(0.85);
@@ -46,9 +38,8 @@
%h3 { %h3 {
margin: 0 0 base(1); margin: 0 0 base(1);
font-size: base(0.925); font-size: base(1);
line-height: 1.25; line-height: base(1.2);
letter-spacing: -0.5px;
@include small-break { @include small-break {
font-size: base(0.65); font-size: base(0.65);
@@ -58,27 +49,27 @@
%h4 { %h4 {
margin: 0 0 $baseline; margin: 0 0 $baseline;
font-size: base(0.75); font-size: base(0.8);
line-height: 1.5; line-height: base(1);
letter-spacing: -0.375px; letter-spacing: -0.375px;
} }
%h5 { %h5 {
margin: 0; margin: 0;
font-size: base(0.5625); font-size: base(0.65);
line-height: 1.5; line-height: base(0.8);
} }
%h6 { %h6 {
margin: 0; margin: 0;
font-size: base(0.5); font-size: base(0.6);
line-height: 1.5; line-height: base(0.8);
} }
%small { %small {
margin: 0; margin: 0;
font-size: 11px; font-size: 12px;
line-height: 1.5; line-height: 20px;
} }
///////////////////////////// /////////////////////////////

View File

@@ -13,7 +13,7 @@ $breakpoint-l-width: 1440px !default;
// BASELINE GRID // BASELINE GRID
////////////////////////////// //////////////////////////////
$baseline-px: 25px !default; $baseline-px: 20px !default;
$baseline-body-size: 13px !default; $baseline-body-size: 13px !default;
$baseline: math.div($baseline-px, $baseline-body-size) + rem; $baseline: math.div($baseline-px, $baseline-body-size) + rem;
@@ -40,7 +40,7 @@ $color-purple: #f3ddf3 !default;
$style-radius-s: 3px !default; $style-radius-s: 3px !default;
$style-radius-m: 4px !default; $style-radius-m: 4px !default;
$style-radius-l: 9px !default; $style-radius-l: 8px !default;
$style-stroke-width: 1px !default; $style-stroke-width: 1px !default;
$style-stroke-width-s: 1px !default; $style-stroke-width-s: 1px !default;
@@ -50,8 +50,8 @@ $style-stroke-width-m: 2px !default;
// MISC // MISC
////////////////////////////// //////////////////////////////
$top-header-offset: calc(var(--base) - 1px); $top-header-offset: calc(base(1) - 1px);
$top-header-offset-m: calc(var(--base) * 3); $top-header-offset-m: base(3);
$focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500); $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
////////////////////////////// //////////////////////////////
@@ -59,41 +59,19 @@ $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
////////////////////////////// //////////////////////////////
@mixin shadow-sm { @mixin shadow-sm {
box-shadow: box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.1);
0 2px 3px 0 rgba(0, 2, 4, 0.05),
0 10px 4px -8px rgba(0, 2, 4, 0.02);
} }
@mixin shadow-m { @mixin shadow-m {
box-shadow: box-shadow: 0 4px 8px -3px rgba(0, 0, 0, 0.1);
0 0 30px 0 rgb(0 2 4 / 12%),
0 30px 25px -8px rgb(0 2 4 / 10%);
} }
@mixin shadow-lg { @mixin shadow-lg {
box-shadow: box-shadow: 0 -2px 16px -2px rgba(0, 0, 0, 0.2);
0 20px 35px -10px rgba(0, 2, 4, 0.2),
0 6px 4px -4px rgba(0, 2, 4, 0.02);
} }
@mixin shadow-lg-top { @mixin shadow-lg-top {
box-shadow: box-shadow: 0 2px 16px -2px rgba(0, 0, 0, 0.2);
0 -20px 35px -10px rgba(0, 2, 4, 0.2),
0 -6px 4px -4px rgba(0, 2, 4, 0.02);
}
@mixin shadow {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.07);
&:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
}
@mixin inputShadowActive {
box-shadow:
0 2px 3px 0 rgba(0, 2, 4, 0.16),
0 6px 4px -4px rgba(0, 2, 4, 0.13);
} }
@mixin inputShadow { @mixin inputShadow {
@@ -101,15 +79,7 @@ $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
&:not(:disabled) { &:not(:disabled) {
&:hover { &:hover {
box-shadow: box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.2);
0 2px 3px 0 rgba(0, 2, 4, 0.13),
0 6px 4px -4px rgba(0, 2, 4, 0.1);
}
&:active,
&:focus-within,
&:focus {
@include inputShadowActive;
} }
} }
} }
@@ -147,19 +117,33 @@ $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
@include blur-bg(var(--theme-bg), 0.3); @include blur-bg(var(--theme-bg), 0.3);
} }
@mixin readOnly {
background: var(--theme-elevation-100);
color: var(--theme-elevation-400);
box-shadow: none;
&:hover {
border-color: var(--theme-elevation-150);
box-shadow: none;
}
}
@mixin formInput() { @mixin formInput() {
@include inputShadow; @include inputShadow;
font-family: var(--font-body); font-family: var(--font-body);
width: 100%; width: 100%;
border: 1px solid var(--theme-elevation-150); border: 1px solid var(--theme-elevation-150);
border-radius: var(--style-radius-s);
background: var(--theme-input-bg); background: var(--theme-input-bg);
color: var(--theme-elevation-800); color: var(--theme-elevation-800);
border-radius: 0;
font-size: 1rem; font-size: 1rem;
height: base(2); height: base(2);
line-height: base(1); line-height: base(1);
padding: base(0.5) base(0.75); padding: base(0.4) base(0.75);
-webkit-appearance: none; -webkit-appearance: none;
transition-property: border, box-shadow;
transition-duration: 100ms;
transition-timing-function: cubic-bezier(0, 0.2, 0.2, 1);
&[data-rtl='true'] { &[data-rtl='true'] {
direction: rtl; direction: rtl;
@@ -189,12 +173,7 @@ $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
} }
&:disabled { &:disabled {
background: var(--theme-elevation-200); @include readOnly;
color: var(--theme-elevation-450);
&:hover {
border-color: var(--theme-elevation-150);
}
} }
} }

View File

@@ -38,7 +38,8 @@
&__editor { &__editor {
font-family: var(--font-serif); font-family: var(--font-serif);
font-size: base(0.625); font-size: base(0.8);
letter-spacing: 0.02em;
h1, h1,
h2, h2,
@@ -48,6 +49,7 @@
h6 { h6 {
font-family: var(--font-body); font-family: var(--font-body);
line-height: 1.125; line-height: 1.125;
letter-spacing: 0;
} }
h1[data-slate-node='element'] { h1[data-slate-node='element'] {

View File

@@ -3,7 +3,7 @@
@import './colors.scss'; @import './colors.scss';
:root { :root {
--base-px: 25; --base-px: 20;
--base-body-size: 13; --base-body-size: 13;
--base: calc((var(--base-px) / var(--base-body-size)) * 1rem); --base: calc((var(--base-px) / var(--base-body-size)) * 1rem);
@@ -21,6 +21,7 @@
--theme-baseline-body-size: #{$baseline-body-size}; --theme-baseline-body-size: #{$baseline-body-size};
--font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, --font-body: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
sans-serif; sans-serif;
--font-serif: Georgia, 'Bitstream Charter', 'Charis SIL', Utopia, 'URW Bookman L', serif;
--font-mono: monospace; --font-mono: monospace;
--style-radius-s: #{$style-radius-s}; --style-radius-s: #{$style-radius-s};
@@ -67,12 +68,6 @@ html {
@extend %body; @extend %body;
background: var(--theme-bg); background: var(--theme-bg);
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
opacity: 0;
&[data-theme='dark'],
&[data-theme='light'] {
opacity: initial;
}
&[data-theme='dark'] { &[data-theme='dark'] {
--theme-bg: var(--theme-elevation-0); --theme-bg: var(--theme-elevation-0);
@@ -111,12 +106,12 @@ body {
} }
::selection { ::selection {
background: var(--theme-success-500); background: var(--color-success-250);
color: var(--theme-base-800); color: var(--theme-base-800);
} }
::-moz-selection { ::-moz-selection {
background: var(--theme-success-500); background: var(--color-success-250);
color: var(--theme-base-800); color: var(--theme-base-800);
} }

View File

@@ -0,0 +1,59 @@
@import 'vars';
@import 'queries';
.Toastify {
.Toastify__toast-container {
left: base(5);
transform: none;
right: base(5);
width: auto;
}
.Toastify__toast {
padding: base(0.5);
border-radius: $style-radius-m;
font-weight: 600;
}
.Toastify__close-button {
align-self: center;
opacity: 0.7;
&:hover {
opacity: 1;
}
}
.Toastify__toast--success {
color: var(--color-success-900);
background: var(--color-success-500);
.Toastify__progress-bar {
background-color: var(--color-success-900);
}
}
.Toastify__close-button--success {
color: var(--color-success-900);
}
.Toastify__toast--error {
background: var(--theme-error-500);
color: #fff;
.Toastify__progress-bar {
background-color: #fff;
}
}
.Toastify__close-button--light {
color: inherit;
}
@include mid-break {
.Toastify__toast-container {
left: $baseline;
right: $baseline;
}
}
}

View File

@@ -1,24 +1,28 @@
@import './styles.scss';
.payload-toast-container { .payload-toast-container {
padding: 0;
margin: 0;
.payload-toast-close-button { .payload-toast-close-button {
position: absolute;
order: 3;
left: unset; left: unset;
right: 0.5rem; inset-inline-end: base(0.5);
top: 1.55rem; top: 50%;
color: var(--theme-elevation-400); transform: translateY(-50%);
color: var(--theme-elevation-600);
background: unset; background: unset;
border: none; border: none;
display: flex;
width: 1.25rem;
height: 1.25rem;
justify-content: center;
align-items: center;
&:hover {
background: none;
}
svg { svg {
width: 2rem; width: base(0.75);
height: 2rem; height: base(0.75);
}
&:hover {
color: var(--theme-elevation-250);
background: none;
} }
[dir='RTL'] & { [dir='RTL'] & {
@@ -27,16 +31,20 @@
} }
} }
.toast-title {
line-height: base(1);
}
.payload-toast-item { .payload-toast-item {
padding: 1rem 2.5rem 1rem 1rem; padding: base(0.5);
color: var(--theme-text); color: var(--theme-elevation-800);
font-style: normal; font-style: normal;
font-weight: 600; font-weight: 600;
display: flex; display: flex;
gap: 1rem; gap: 1rem;
align-items: center; align-items: center;
width: 100%; width: 100%;
border-radius: 0.15rem; border-radius: 4px;
border: 1px solid var(--theme-border-color); border: 1px solid var(--theme-border-color);
background: var(--theme-input-bg); background: var(--theme-input-bg);
box-shadow: box-shadow:
@@ -45,6 +53,7 @@
.toast-content { .toast-content {
transition: opacity 100ms cubic-bezier(0.55, 0.055, 0.675, 0.19); transition: opacity 100ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
width: 100%;
} }
&[data-front='false'] { &[data-front='false'] {
@@ -60,51 +69,72 @@
} }
.toast-icon { .toast-icon {
svg { width: base(1);
width: 2.4rem; height: base(1);
height: 2.4rem; margin: 0;
display: flex;
align-items: center;
justify-content: center;
& > * {
width: base(1.2);
height: base(1.2);
} }
} }
&.toast-warning { &.toast-warning {
border-color: var(--theme-warning-200); color: var(--theme-warning-800);
background-color: var(--theme-warning-100); border-color: var(--theme-warning-150);
background-color: var(--theme-warning-50);
.payload-toast-close-button {
color: var(--theme-warning-600);
&:hover {
color: var(--theme-warning-250);
}
}
} }
&.toast-error { &.toast-error {
border-color: var(--theme-error-300); color: var(--theme-error-800);
background-color: var(--theme-error-150); border-color: var(--theme-error-150);
background-color: var(--theme-error-50);
.payload-toast-close-button {
color: var(--theme-error-600);
&:hover {
color: var(--theme-error-250);
}
}
} }
&.toast-success { &.toast-success {
border-color: var(--theme-success-200); color: var(--theme-success-800);
background-color: var(--theme-success-100); border-color: var(--theme-success-150);
background-color: var(--theme-success-50);
.payload-toast-close-button {
color: var(--theme-success-600);
&:hover {
color: var(--theme-success-250);
}
}
} }
&.toast-info { &.toast-info {
border-color: var(--theme-elevation-250); color: var(--theme-elevation-800);
background-color: var(--theme-elevation-100); border-color: var(--theme-elevation-150);
} background-color: var(--theme-elevation-50);
[data-theme='light'] & { .payload-toast-close-button {
&.toast-warning { color: var(--theme-elevation-600);
border-color: var(--theme-warning-550);
background-color: var(--theme-warning-100);
}
&.toast-error { &:hover {
border-color: var(--theme-error-200); color: var(--theme-elevation-250);
background-color: var(--theme-error-50); }
}
&.toast-success {
border-color: var(--theme-success-550);
background-color: var(--theme-success-50);
}
&.toast-info {
border-color: var(--theme-border-color);
background-color: var(--theme-elevation-50);
} }
} }
} }

View File

@@ -15,17 +15,10 @@
font-weight: 500; font-weight: 500;
} }
%jumbo {
font-size: base(2.5);
line-height: 1;
margin: 0 0 base(2);
}
%h1 { %h1 {
margin: 0 0 base(1); margin: 0 0 base(1);
font-size: base(2); font-size: base(1.6);
line-height: 1.15; line-height: base(1.8);
letter-spacing: -1px;
@include small-break { @include small-break {
letter-spacing: -0.5px; letter-spacing: -0.5px;
@@ -35,9 +28,8 @@
%h2 { %h2 {
margin: 0 0 base(1); margin: 0 0 base(1);
font-size: base(1.25); font-size: base(1.3);
line-height: 1.15; line-height: base(1.6);
letter-spacing: -0.5px;
@include small-break { @include small-break {
font-size: base(0.85); font-size: base(0.85);
@@ -46,9 +38,8 @@
%h3 { %h3 {
margin: 0 0 base(1); margin: 0 0 base(1);
font-size: base(0.925); font-size: base(1);
line-height: 1.25; line-height: base(1.2);
letter-spacing: -0.5px;
@include small-break { @include small-break {
font-size: base(0.65); font-size: base(0.65);
@@ -58,27 +49,27 @@
%h4 { %h4 {
margin: 0 0 $baseline; margin: 0 0 $baseline;
font-size: base(0.75); font-size: base(0.8);
line-height: 1.5; line-height: base(1);
letter-spacing: -0.375px; letter-spacing: -0.375px;
} }
%h5 { %h5 {
margin: 0; margin: 0;
font-size: base(0.5625); font-size: base(0.65);
line-height: 1.5; line-height: base(0.8);
} }
%h6 { %h6 {
margin: 0; margin: 0;
font-size: base(0.5); font-size: base(0.6);
line-height: 1.5; line-height: base(0.8);
} }
%small { %small {
margin: 0; margin: 0;
font-size: 11px; font-size: 12px;
line-height: 1.5; line-height: 20px;
} }
///////////////////////////// /////////////////////////////

View File

@@ -13,7 +13,7 @@ $breakpoint-l-width: 1440px !default;
// BASELINE GRID // BASELINE GRID
////////////////////////////// //////////////////////////////
$baseline-px: 25px !default; $baseline-px: 20px !default;
$baseline-body-size: 13px !default; $baseline-body-size: 13px !default;
$baseline: math.div($baseline-px, $baseline-body-size) + rem; $baseline: math.div($baseline-px, $baseline-body-size) + rem;
@@ -40,7 +40,7 @@ $color-purple: #f3ddf3 !default;
$style-radius-s: 3px !default; $style-radius-s: 3px !default;
$style-radius-m: 4px !default; $style-radius-m: 4px !default;
$style-radius-l: 9px !default; $style-radius-l: 8px !default;
$style-stroke-width: 1px !default; $style-stroke-width: 1px !default;
$style-stroke-width-s: 1px !default; $style-stroke-width-s: 1px !default;
@@ -50,8 +50,8 @@ $style-stroke-width-m: 2px !default;
// MISC // MISC
////////////////////////////// //////////////////////////////
$top-header-offset: calc(var(--base) - 1px); $top-header-offset: calc(base(1) - 1px);
$top-header-offset-m: calc(var(--base) * 3); $top-header-offset-m: base(3);
$focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500); $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
////////////////////////////// //////////////////////////////
@@ -59,41 +59,19 @@ $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
////////////////////////////// //////////////////////////////
@mixin shadow-sm { @mixin shadow-sm {
box-shadow: box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.1);
0 2px 3px 0 rgba(0, 2, 4, 0.05),
0 10px 4px -8px rgba(0, 2, 4, 0.02);
} }
@mixin shadow-m { @mixin shadow-m {
box-shadow: box-shadow: 0 4px 8px -3px rgba(0, 0, 0, 0.1);
0 0 30px 0 rgb(0 2 4 / 12%),
0 30px 25px -8px rgb(0 2 4 / 10%);
} }
@mixin shadow-lg { @mixin shadow-lg {
box-shadow: box-shadow: 0 -2px 16px -2px rgba(0, 0, 0, 0.2);
0 20px 35px -10px rgba(0, 2, 4, 0.2),
0 6px 4px -4px rgba(0, 2, 4, 0.02);
} }
@mixin shadow-lg-top { @mixin shadow-lg-top {
box-shadow: box-shadow: 0 2px 16px -2px rgba(0, 0, 0, 0.2);
0 -20px 35px -10px rgba(0, 2, 4, 0.2),
0 -6px 4px -4px rgba(0, 2, 4, 0.02);
}
@mixin shadow {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.07);
&:hover {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
}
@mixin inputShadowActive {
box-shadow:
0 2px 3px 0 rgba(0, 2, 4, 0.16),
0 6px 4px -4px rgba(0, 2, 4, 0.13);
} }
@mixin inputShadow { @mixin inputShadow {
@@ -101,15 +79,7 @@ $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
&:not(:disabled) { &:not(:disabled) {
&:hover { &:hover {
box-shadow: box-shadow: 0 2px 2px -1px rgba(0, 0, 0, 0.2);
0 2px 3px 0 rgba(0, 2, 4, 0.13),
0 6px 4px -4px rgba(0, 2, 4, 0.1);
}
&:active,
&:focus-within,
&:focus {
@include inputShadowActive;
} }
} }
} }
@@ -147,19 +117,33 @@ $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
@include blur-bg(var(--theme-bg), 0.3); @include blur-bg(var(--theme-bg), 0.3);
} }
@mixin readOnly {
background: var(--theme-elevation-100);
color: var(--theme-elevation-400);
box-shadow: none;
&:hover {
border-color: var(--theme-elevation-150);
box-shadow: none;
}
}
@mixin formInput() { @mixin formInput() {
@include inputShadow; @include inputShadow;
font-family: var(--font-body); font-family: var(--font-body);
width: 100%; width: 100%;
border: 1px solid var(--theme-elevation-150); border: 1px solid var(--theme-elevation-150);
border-radius: var(--style-radius-s);
background: var(--theme-input-bg); background: var(--theme-input-bg);
color: var(--theme-elevation-800); color: var(--theme-elevation-800);
border-radius: 0;
font-size: 1rem; font-size: 1rem;
height: base(2); height: base(2);
line-height: base(1); line-height: base(1);
padding: base(0.5) base(0.75); padding: base(0.4) base(0.75);
-webkit-appearance: none; -webkit-appearance: none;
transition-property: border, box-shadow;
transition-duration: 100ms;
transition-timing-function: cubic-bezier(0, 0.2, 0.2, 1);
&[data-rtl='true'] { &[data-rtl='true'] {
direction: rtl; direction: rtl;
@@ -189,12 +173,7 @@ $focus-box-shadow: 0 0 0 $style-stroke-width-m var(--theme-success-500);
} }
&:disabled { &:disabled {
background: var(--theme-elevation-200); @include readOnly;
color: var(--theme-elevation-450);
&:hover {
border-color: var(--theme-elevation-150);
}
} }
} }

View File

@@ -30,17 +30,4 @@
} }
} }
} }
&__move-up {
margin-bottom: 2px;
}
&__move-down {
margin-top: 6px;
margin-bottom: 2px;
}
&__action-chevron {
padding: 0 calc(var(--base) / 4);
}
} }

View File

@@ -7,7 +7,7 @@
vertical-align: middle; vertical-align: middle;
background: var(--theme-elevation-100); background: var(--theme-elevation-100);
color: var(--theme-elevation-800); color: var(--theme-elevation-800);
border-radius: $style-radius-s; border-radius: $style-radius-m;
padding: base(0.5); padding: base(0.5);
margin-bottom: $baseline; margin-bottom: $baseline;

View File

@@ -6,22 +6,45 @@ a.btn {
.btn { .btn {
background: transparent; background: transparent;
line-height: base(1); border-radius: $style-radius-s;
border-radius: $style-radius-m; font-size: var(--base-body-size);
font-size: 1rem; margin-block: base(1.2);
margin-top: base(1); line-height: base(1.2);
margin-bottom: base(1);
border: 0; border: 0;
cursor: pointer; cursor: pointer;
font-weight: normal; font-weight: normal;
text-decoration: none; text-decoration: none;
text-align: center;
color: inherit; color: inherit;
transition-property: border, color, box-shadow, background;
transition-duration: 100ms;
transition-timing-function: cubic-bezier(0, 0.2, 0.2, 1);
.btn__icon { &__content {
display: flex;
align-items: center;
justify-content: center;
}
&__icon {
width: base(1.2);
height: base(1.2);
display: flex;
align-items: center;
justify-content: center;
border: 1px solid; border: 1px solid;
border-radius: 100%; border-radius: 100%;
@include color-svg(currentColor); @include color-svg(currentColor);
padding: base(0.1);
color: inherit;
.icon {
width: 100%;
height: 100%;
}
&.btn--size-small {
padding: base(0.2);
}
} }
&--has-tooltip { &--has-tooltip {
@@ -40,158 +63,125 @@ a.btn {
} }
} }
span { &--size-small {
line-height: base(1); padding: 0 base(0.4);
}
span, &.btn--icon-position-left {
svg { padding-inline-start: base(0.1);
vertical-align: top; padding-inline-end: base(0.4);
.btn__content {
flex-direction: row-reverse;
}
}
&.btn--icon-position-right {
padding-inline-start: base(0.4);
padding-inline-end: base(0.1);
}
} }
&--size-medium { &--size-medium {
padding: base(0.5) $baseline; padding: base(0.2) base(0.6);
&.btn--icon-position-left {
padding-inline-start: base(0.4);
padding-inline-end: base(0.6);
.btn__content {
gap: base(0.2);
flex-direction: row-reverse;
}
}
&.btn--icon-position-right {
padding-inline-start: base(0.6);
padding-inline-end: base(0.4);
.btn__content {
gap: base(0.2);
}
}
} }
&--size-small { &--size-large {
padding: base(0.25) base(0.5); padding: base(0.4) base(0.8);
&.btn--icon-position-left {
padding-inline-start: base(0.6);
padding-inline-end: base(0.8);
.btn__content {
gap: base(0.4);
flex-direction: row-reverse;
}
}
&.btn--icon-position-right {
padding-inline-start: base(0.8);
padding-inline-end: base(0.6);
.btn__content {
gap: base(0.4);
}
}
} }
&--style-primary { &--style-primary {
background-color: var(--theme-elevation-800); background: var(--theme-elevation-800);
color: var(--theme-elevation-0); color: var(--theme-elevation-0);
&.btn--disabled { &.btn--disabled {
background-color: var(--theme-elevation-400); background: var(--theme-elevation-200);
} }
&:not(.btn--disabled) { &:not(.btn--disabled) {
&:hover, &:hover,
&:focus-visible { &:focus-visible,
background: var(--theme-elevation-750); &:focus,
}
&:active { &:active {
background: var(--theme-elevation-700); background: var(--theme-elevation-600);
} }
} }
&:focus:not(:focus-visible) { .icon {
box-shadow: $focus-box-shadow; @include color-svg(var(--theme-elevation-0));
outline: none;
} }
} }
&--style-secondary { &--style-secondary {
$base-box-shadow: inset 0 0 0 $style-stroke-width var(--theme-elevation-800); box-shadow: inset 0 0 0 1px var(--theme-elevation-800);
$hover-box-shadow: inset 0 0 0 $style-stroke-width var(--theme-elevation-700); color: var(--theme-text);
box-shadow: $base-box-shadow;
color: var(--theme-elevation-800);
background: none;
backdrop-filter: blur(5px);
&:hover,
&:focus-visible {
background: var(--theme-elevation-100);
box-shadow: $hover-box-shadow;
}
&:active {
background: var(--theme-elevation-200);
}
&.btn--disabled { &.btn--disabled {
color: var(--theme-elevation-400); color: var(--theme-elevation-200);
background: none; box-shadow: inset 0 0 0 1px var(--theme-elevation-200);
box-shadow: inset 0 0 0 $style-stroke-width var(--theme-elevation-400);
} }
&:focus:not(:focus-visible) { &:not(.btn--disabled) {
outline: none; &:hover,
box-shadow: $hover-box-shadow, $focus-box-shadow; &:focus-visible,
&:focus,
&:active {
color: var(--theme-elevation-600);
box-shadow: inset 0 0 0 1px var(--theme-elevation-400);
}
}
}
&--style-icon-label,
&--style-icon-label.btn--icon-position-left,
&--style-icon-label.btn--icon-position-right {
padding: 0;
font-weight: 600;
.btn__content {
gap: base(0.4);
} }
} }
&--style-none { &--style-none {
padding: 0; padding: 0;
margin: 0;
border-radius: 0;
&:focus {
opacity: 0.8;
}
&:active {
opacity: 0.7;
}
}
&--round {
border-radius: 100%;
}
[dir='rtl'] &--icon {
span {
margin-left: 5px;
}
}
&--icon {
span {
display: flex;
justify-content: space-between;
}
&.btn--style-primary {
.icon {
@include color-svg(var(--theme-elevation-0));
}
}
}
&--style-icon-label {
padding: 0;
font-weight: 600;
}
&--style-light-gray {
box-shadow: inset 0 0 0 $style-stroke-width var(--theme-elevation-800);
}
&--icon-position-left {
.btn__content {
flex-direction: row-reverse;
}
.btn__icon {
margin-right: base(0.5);
}
}
&--icon-position-right {
.btn__icon {
margin-left: base(0.5);
}
}
&--icon-only {
.btn__icon {
padding: 0;
margin: 0;
}
}
&--disabled {
cursor: default;
}
&:hover,
&:focus-visible {
.btn__icon {
@include color-svg(var(--theme-elevation-0));
background: var(--theme-elevation-800);
}
} }
&:focus:not(:focus-visible) { &:focus:not(:focus-visible) {
@@ -214,4 +204,8 @@ a.btn {
outline: var(--accessibility-outline); outline: var(--accessibility-outline);
outline-offset: var(--accessibility-outline-offset); outline-offset: var(--accessibility-outline-offset);
} }
&.btn--disabled {
cursor: not-allowed;
}
} }

View File

@@ -81,7 +81,7 @@ export const Button = forwardRef<HTMLAnchorElement | HTMLButtonElement, Props>((
disabled && `${baseClass}--disabled`, disabled && `${baseClass}--disabled`,
round && `${baseClass}--round`, round && `${baseClass}--round`,
size && `${baseClass}--size-${size}`, size && `${baseClass}--size-${size}`,
iconPosition && `${baseClass}--icon-position-${iconPosition}`, icon && iconPosition && `${baseClass}--icon-position-${iconPosition}`,
tooltip && `${baseClass}--has-tooltip`, tooltip && `${baseClass}--has-tooltip`,
] ]
.filter(Boolean) .filter(Boolean)

View File

@@ -17,7 +17,7 @@ export type Props = {
newTab?: boolean newTab?: boolean
onClick?: (event: MouseEvent) => void onClick?: (event: MouseEvent) => void
round?: boolean round?: boolean
size?: 'medium' | 'small' size?: 'large' | 'medium' | 'small'
to?: string to?: string
tooltip?: string tooltip?: string
type?: 'button' | 'submit' type?: 'button' | 'submit'

View File

@@ -2,24 +2,50 @@
.card { .card {
background: var(--theme-elevation-50); background: var(--theme-elevation-50);
padding: base(1.25) $baseline; padding: base(0.8);
width: 100%;
min-height: base(4);
position: relative; position: relative;
border-radius: var(--style-radius-m);
border: 1px solid var(--theme-border-color);
transition-property: border, box-shadow, background;
transition-duration: 100ms;
transition-timing-function: cubic-bezier(0, 0.2, 0.2, 1);
display: flex;
justify-content: space-between;
align-self: start;
gap: base(0.8);
&__title { &__title {
@extend %h5; @extend %h4;
white-space: nowrap; letter-spacing: 0;
overflow: hidden; font-weight: 600;
text-overflow: ellipsis; line-height: base(1.2);
width: 100%;
margin: 0;
} }
&__actions { &__actions {
position: relative; position: relative;
z-index: 2; z-index: 2;
margin-top: base(0.5);
display: inline-flex; display: inline-flex;
.btn { .btn {
margin: 0; margin: 0;
flex-shrink: 0;
}
.btn__icon {
border: 1px solid var(--theme-border-color);
transition-property: border, box-shadow, color, background;
transition-duration: 100ms;
transition-timing-function: cubic-bezier(0, 0.2, 0.2, 1);
&:hover {
border: 1px solid var(--theme-elevation-500);
background-color: var(--theme-elevation-0);
color: currentColor;
@include shadow-sm;
}
} }
} }
@@ -27,16 +53,19 @@
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background: var(--theme-elevation-100); background: var(--theme-elevation-50);
border: 1px solid var(--theme-elevation-250);
box-shadow: 0 4px 8px -2px rgba(0, 0, 0, 0.05);
} }
} }
&__click { &__click {
position: absolute;
z-index: 1; z-index: 1;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
position: absolute;
margin: 0;
} }
} }

View File

@@ -21,6 +21,7 @@ const CodeEditor: React.FC<Props> = (props) => {
baseClass, baseClass,
className, className,
rest?.defaultLanguage ? `language--${rest.defaultLanguage}` : '', rest?.defaultLanguage ? `language--${rest.defaultLanguage}` : '',
readOnly && 'read-only',
] ]
.filter(Boolean) .filter(Boolean)
.join(' ') .join(' ')

View File

@@ -2,20 +2,44 @@
.collapsible { .collapsible {
--toggle-pad-h: #{base(0.75)}; --toggle-pad-h: #{base(0.75)};
--toggle-pad-v: #{base(0.5)}; --toggle-pad-v: #{base(0.6)};
border-radius: $style-radius-m; border-radius: $style-radius-m;
&__toggle-wrap { &__toggle-wrap {
position: relative; position: relative;
padding: base(0.4) base(0.4) base(0.4) base(0.8);
display: flex;
align-items: center;
justify-content: space-between;
background: var(--theme-elevation-50);
line-height: base(1.2);
gap: base(0.2);
border-top-right-radius: $style-radius-m;
border-top-left-radius: $style-radius-m;
& > * {
z-index: 2;
}
&:has(.collapsible__drag) {
padding-inline-start: base(0.4);
}
} }
&__drag { &__drag {
display: flex;
opacity: 0.5; opacity: 0.5;
position: absolute; z-index: 2;
z-index: 1;
top: var(--toggle-pad-v); top: var(--toggle-pad-v);
left: base(0.5); width: base(1.2);
height: base(1.2);
padding: base(0.1);
icon {
width: 100%;
height: 100%;
}
} }
&__toggle { &__toggle {
@@ -23,10 +47,15 @@
@extend %body; @extend %body;
text-align: left; text-align: left;
cursor: pointer; cursor: pointer;
border-top-right-radius: $style-radius-s; border-top-right-radius: $style-radius-m;
border-top-left-radius: $style-radius-s; border-top-left-radius: $style-radius-m;
width: 100%; width: 100%;
height: 100%;
color: transparent; color: transparent;
position: absolute;
top: 0;
left: 0;
z-index: 1;
span { span {
user-select: none; user-select: none;
@@ -43,9 +72,6 @@
.row-label { .row-label {
color: var(--theme-text); color: var(--theme-text);
} }
.collapsible__toggle {
background: var(--theme-elevation-50);
}
} }
&.collapsible--hovered { &.collapsible--hovered {
> .collapsible__toggle-wrap .collapsible__toggle { > .collapsible__toggle-wrap .collapsible__toggle {
@@ -54,57 +80,62 @@
} }
} }
&__toggle,
&__header-wrap { &__header-wrap {
padding: var(--toggle-pad-v) var(--toggle-pad-h);
}
&__header-wrap {
position: absolute;
top: 0; top: 0;
right: base(3); right: base(3);
bottom: 0; bottom: 0;
left: 0; left: 0;
pointer-events: none; pointer-events: none;
width: 100%;
> * {
pointer-events: all;
}
} }
&__header-wrap--has-drag-handle { &__header-wrap--has-drag-handle {
left: base(0.875); left: base(1);
} }
&--collapsed { &--collapsed {
.collapsible__toggle { .collapsible__toggle-wrap {
border-bottom-right-radius: $style-radius-s; border-bottom-right-radius: $style-radius-m;
border-bottom-left-radius: $style-radius-s; border-bottom-left-radius: $style-radius-m;
} }
} }
&__actions-wrap { &__actions-wrap {
position: absolute;
right: var(--toggle-pad-h);
top: var(--toggle-pad-v);
pointer-events: none; pointer-events: none;
display: flex; display: flex;
gap: base(0.2);
margin-inline-end: base(0.2);
} }
&__actions { &__actions {
pointer-events: all; pointer-events: all;
display: flex;
align-items: center;
justify-content: center;
width: base(1.2);
height: base(1.2);
&.icon {
padding: base(0.1);
}
} }
&__indicator { &__indicator {
padding: calc(var(--base) / 4);
display: flex; display: flex;
align-items: flex-start; align-items: center;
justify-content: center;
width: base(1.2);
height: base(1.2);
&.icon {
padding: base(0.1);
}
} }
&__content { &__content {
background-color: var(--theme-elevation-0); background-color: var(--theme-elevation-0);
border-bottom-left-radius: $style-radius-s; border-bottom-left-radius: $style-radius-m;
border-bottom-right-radius: $style-radius-s; border-bottom-right-radius: $style-radius-m;
padding: var(--base); padding: var(--base);
} }

View File

@@ -10,10 +10,28 @@
margin-right: base(0.5); margin-right: base(0.5);
margin-bottom: base(0.5); margin-bottom: base(0.5);
background-color: transparent; background-color: transparent;
box-shadow: 0 0 0 1px var(--theme-elevation-200); box-shadow: 0 0 0 1px var(--theme-elevation-150);
&.column-selector__column {
cursor: pointer;
&:hover {
background-color: var(--theme-elevation-100);
}
}
&.column-selector__column--active { &.column-selector__column--active {
background-color: var(--theme-elevation-150); background-color: var(--theme-elevation-0);
box-shadow:
0 0px 1px 1px var(--theme-elevation-150),
0 2px 4px -2px rgba(0, 0, 0, 0.1);
&:hover {
background-color: var(--theme-elevation-0);
box-shadow:
0 0px 1px 1px var(--theme-elevation-250),
0 3px 4px -1px rgba(0, 0, 0, 0.1);
}
} }
} }

View File

@@ -103,8 +103,8 @@
gap: 2px; gap: 2px;
border: 1px solid var(--theme-elevation-100); border: 1px solid var(--theme-elevation-100);
border-radius: $style-radius-m; border-radius: $style-radius-m;
height: calc(var(--base) * 1.5); height: calc(var(--base) * 1.6);
width: calc(var(--base) * 1.5); width: calc(var(--base) * 1.6);
&:hover { &:hover {
border: 1px solid var(--theme-elevation-500); border: 1px solid var(--theme-elevation-500);

View File

@@ -45,15 +45,13 @@
padding: 0; padding: 0;
cursor: pointer; cursor: pointer;
overflow: hidden; overflow: hidden;
width: base(1); width: base(2);
height: base(1); height: base(2);
svg { svg {
width: base(2.75); width: base(2);
height: base(2.75); height: base(2);
position: relative; position: relative;
left: base(-0.825);
top: base(-0.825);
.stroke { .stroke {
stroke-width: 2px; stroke-width: 2px;

View File

@@ -14,10 +14,11 @@ export const DraggableSortableItem: React.FC<
> = (props) => { > = (props) => {
const { id, children, disabled } = props const { id, children, disabled } = props
const { attributes, isDragging, listeners, setNodeRef, transform } = useDraggableSortable({ const { attributes, isDragging, listeners, setNodeRef, transform, transition } =
id, useDraggableSortable({
disabled, id,
}) disabled,
})
return ( return (
<Fragment> <Fragment>
@@ -28,9 +29,11 @@ export const DraggableSortableItem: React.FC<
cursor: isDragging ? 'grabbing' : 'grab', cursor: isDragging ? 'grabbing' : 'grab',
}, },
}, },
isDragging,
listeners, listeners,
setNodeRef, setNodeRef,
transform, transform,
transition,
})} })}
</Fragment> </Fragment>
) )

View File

@@ -8,9 +8,13 @@ import type { UseDraggableSortableReturn } from './types.js'
export const useDraggableSortable = (props: UseDraggableArguments): UseDraggableSortableReturn => { export const useDraggableSortable = (props: UseDraggableArguments): UseDraggableSortableReturn => {
const { id, disabled } = props const { id, disabled } = props
const { attributes, isDragging, listeners, setNodeRef, transform } = useSortable({ const { attributes, isDragging, listeners, setNodeRef, transform, transition } = useSortable({
id, id,
disabled, disabled,
transition: {
duration: 250,
easing: 'cubic-bezier(0, 0.2, 0.2, 1)',
},
}) })
return { return {
@@ -18,11 +22,13 @@ export const useDraggableSortable = (props: UseDraggableArguments): UseDraggable
...attributes, ...attributes,
style: { style: {
cursor: isDragging ? 'grabbing' : 'grab', cursor: isDragging ? 'grabbing' : 'grab',
transition,
}, },
}, },
isDragging, isDragging,
listeners, listeners,
setNodeRef, setNodeRef,
transform: transform && `translate3d(${transform.x}px, ${transform.y}px, 0)`, // translate3d is faster than translate in most browsers transform: transform && `translate3d(${transform.x}px, ${transform.y}px, 0)`, // translate3d is faster than translate in most browsers
transition,
} }
} }

View File

@@ -7,4 +7,5 @@ export type UseDraggableSortableReturn = {
listeners: SyntheticListenerMap listeners: SyntheticListenerMap
setNodeRef: (node: HTMLElement | null) => void setNodeRef: (node: HTMLElement | null) => void
transform: string transform: string
transition: string
} }

View File

@@ -80,6 +80,7 @@ $transTime: 200;
&__header { &__header {
display: flex; display: flex;
align-items: center;
margin-top: base(2.5); margin-top: base(2.5);
margin-bottom: base(1); margin-bottom: base(1);
width: 100%; width: 100%;
@@ -95,19 +96,22 @@ $transTime: 200;
padding: 0; padding: 0;
cursor: pointer; cursor: pointer;
overflow: hidden; overflow: hidden;
width: base(1);
height: base(1);
direction: ltr; direction: ltr;
display: flex;
align-items: center;
justify-content: center;
width: base(1.2);
height: base(1.2);
svg { svg {
width: base(2.75); margin: base(-1.2);
height: base(2.75); width: base(2.4);
height: base(2.4);
position: relative; position: relative;
left: base(-0.825);
top: base(-0.825);
.stroke { .stroke {
stroke-width: 2px; stroke-width: 1px;
vector-effect: non-scaling-stroke; vector-effect: non-scaling-stroke;
} }
} }

View File

@@ -4,12 +4,15 @@
position: relative; position: relative;
display: flex; display: flex;
align-items: center; align-items: center;
gap: $baseline; gap: base(0.4);
padding: base(2); padding: base(1.6);
background: var(--theme-elevation-100); background: var(--theme-elevation-50);
border: 1px dotted var(--theme-elevation-400); border: 1px dotted var(--theme-elevation-400);
border-radius: var(--style-radius-s);
height: 100%; height: 100%;
width: 100%; width: 100%;
box-shadow: 0 0 0 0 transparent;
transition: all 100ms cubic-bezier(0, 0.2, 0.2, 1);
.btn { .btn {
margin: 0; margin: 0;
@@ -18,6 +21,7 @@
&.dragging { &.dragging {
border-color: var(--theme-success-500); border-color: var(--theme-success-500);
background: var(--theme-success-150); background: var(--theme-success-150);
@include shadow-m;
* { * {
pointer-events: none; pointer-events: none;

View File

@@ -107,7 +107,7 @@ export const Dropzone: React.FC<Props> = ({ className, mimeTypes, onChange, onPa
onClick={() => { onClick={() => {
inputRef.current.click() inputRef.current.click()
}} }}
size="small" size="medium"
> >
{t('upload:selectFile')} {t('upload:selectFile')}
</Button> </Button>
@@ -115,7 +115,7 @@ export const Dropzone: React.FC<Props> = ({ className, mimeTypes, onChange, onPa
buttonStyle="secondary" buttonStyle="secondary"
className={`${baseClass}__file-button`} className={`${baseClass}__file-button`}
onClick={onPasteUrlClick} onClick={onPasteUrlClick}
size="small" size="medium"
> >
{t('upload:pasteURL')} {t('upload:pasteURL')}
</Button> </Button>

View File

@@ -3,7 +3,7 @@
.edit-many { .edit-many {
&__toggle { &__toggle {
font-size: 1rem; font-size: 1rem;
line-height: base(1); line-height: base(1.2);
display: inline-flex; display: inline-flex;
background: var(--theme-elevation-150); background: var(--theme-elevation-150);
color: var(--theme-elevation-800); color: var(--theme-elevation-800);
@@ -12,7 +12,7 @@
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
border: 0; border: 0;
padding: 0 base(0.25); padding: 0 base(0.4);
align-items: center; align-items: center;
cursor: pointer; cursor: pointer;
text-decoration: none; text-decoration: none;

View File

@@ -111,6 +111,9 @@ $header-height: base(5);
&__crop, &__crop,
&__focalOnly { &__focalOnly {
padding: base(1.5) base(1.5) base(1.5) 0; padding: base(1.5) base(1.5) base(1.5) 0;
width: 100%;
display: flex;
justify-content: center;
} }
&__crop { &__crop {
@@ -181,7 +184,7 @@ $header-height: base(5);
height: fit-content; height: fit-content;
border-radius: var(--style-radius-s); border-radius: var(--style-radius-s);
background-color: var(--theme-elevation-150); background-color: var(--theme-elevation-150);
padding: 0 base(0.25); padding: 0 base(0.4);
} }
&__input { &__input {

View File

@@ -3,6 +3,7 @@
.file-meta { .file-meta {
&__url { &__url {
display: flex; display: flex;
gap: base(0.4);
a { a {
font-weight: 600; font-weight: 600;

View File

@@ -1,27 +1,46 @@
@import '../../scss/styles.scss'; @import '../../scss/styles.scss';
.file-details { .file-details {
background-color: var(--theme-elevation-50); background: var(--theme-elevation-50);
border: 1px solid var(--theme-border-color);
border-radius: var(--style-radius-m);
@include inputShadow;
header { header {
display: flex; display: flex;
align-items: flex-start; flex-direction: row;
border-bottom: 1px solid var(--theme-elevation-0); flex-wrap: wrap;
} }
&__remove { &__remove {
margin: $baseline $baseline $baseline 0; position: absolute;
margin: 0;
top: $baseline;
right: $baseline;
& .btn__icon {
border: 1px solid var(--theme-border-color);
background: var(--theme-input-bg);
@include inputShadow;
transition: border 100ms cubic-bezier(0, 0.2, 0.2, 1);
&:hover {
border: 1px solid var(--theme-elevation-400);
}
}
} }
&__main-detail { &__main-detail {
padding: $baseline base(1.5); padding: base(0.8) base(1.2);
width: auto; width: auto;
flex-grow: 1; flex-grow: 1;
min-width: 0; min-width: 280px;
max-width: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-self: center; justify-content: center;
gap: base(0.25); align-self: stretch;
gap: base(0.2);
} }
&__toggle-more-info { &__toggle-more-info {
@@ -66,7 +85,7 @@
cursor: pointer; cursor: pointer;
background-color: var(--theme-elevation-150); background-color: var(--theme-elevation-150);
border: none; border: none;
border-radius: $style-radius-s; border-radius: $style-radius-m;
padding: base(0.25) base(0.5); padding: base(0.25) base(0.5);
&:hover { &:hover {
@@ -102,12 +121,9 @@
&__remove { &__remove {
order: 2; order: 2;
margin-left: auto;
margin-right: $baseline;
} }
&__main-detail { &__main-detail {
border-top: $style-stroke-width-m solid var(--theme-elevation-0);
order: 3; order: 3;
width: 100%; width: 100%;
} }

View File

@@ -42,6 +42,8 @@ export const FileDetails: React.FC<FileDetailsProps> = (props) => {
<div className={baseClass}> <div className={baseClass}>
<header> <header>
<Thumbnail <Thumbnail
// size="small"
className={`${baseClass}__thumbnail`}
collectionSlug={collectionSlug} collectionSlug={collectionSlug}
doc={doc} doc={doc}
fileSrc={thumbnailURL || url} fileSrc={thumbnailURL || url}
@@ -60,12 +62,14 @@ export const FileDetails: React.FC<FileDetailsProps> = (props) => {
width={width as number} width={width as number}
/> />
<UploadActions {(enableAdjustments || customUploadActions) && (
customActions={customUploadActions} <UploadActions
enableAdjustments={enableAdjustments} customActions={customUploadActions}
enablePreviewSizes={hasImageSizes && doc.filename} enableAdjustments={enableAdjustments}
mimeType={mimeType} enablePreviewSizes={hasImageSizes && doc.filename}
/> mimeType={mimeType}
/>
)}
</div> </div>
{handleRemove && ( {handleRemove && (
<Button <Button

View File

@@ -4,117 +4,37 @@
padding: 0; padding: 0;
border: 0; border: 0;
cursor: pointer; cursor: pointer;
background-color: transparent; background-color: var(--theme-bg);
outline: none; outline: none;
position: relative; position: relative;
@include blur-bg;
--hamburger-padding: 8px;
--hamburger-size: 9px;
--hamburger-line-gap: 3px;
color: var(--theme-text); color: var(--theme-text);
box-shadow: 0px 0px 0px 1px var(--theme-elevation-150);
padding: base(0.1);
border-radius: 3px;
position: relative;
z-index: 1;
height: 100%;
width: 100%;
transition-property: box-shadow, background-color;
transition-duration: 100ms;
transition-timing-function: cubic-bezier(0, 0.2, 0.2, 1);
&__wrapper { &:hover {
border: 1px solid var(--theme-elevation-150); background-color: var(--theme-elevation-100);
padding: var(--hamburger-padding); box-shadow: 0px 0px 0px 1px var(--theme-elevation-500);
border-radius: 3px;
position: relative;
z-index: 1;
height: 100%;
width: 100%;
&:hover {
border: 1px solid var(--theme-elevation-500);
background-color: var(--theme-elevation-100);
}
&:focus {
outline: none;
}
} }
&__icon { &:focus {
position: relative; outline: none;
z-index: 1;
height: var(--hamburger-size);
width: var(--hamburger-size);
display: flex;
.stroke {
stroke: currentColor;
stroke-width: 1px;
}
svg {
height: 100%;
}
} }
&::after {
z-index: -1;
}
&__open-icon,
&__close-icon { &__close-icon {
display: flex; width: var(--hamburger-size);
align-items: center; height: var(--hamburger-size);
justify-content: center;
position: absolute;
top: 50%;
left: 50%;
width: 100%;
height: 100%;
transform: translate3d(-50%, -50%, 0);
}
&__lines {
display: flex;
flex-direction: column;
gap: var(--hamburger-line-gap);
width: 100%;
margin: auto;
}
&__line {
background-color: currentColor;
width: 100%;
height: 1px;
}
&__x-left {
position: absolute;
top: 50%;
left: 50%;
transform: translate3d(-50%, -50%, 0) rotate(45deg);
}
&__x-right {
position: absolute;
top: 50%;
left: 50%;
transform: translate3d(-50%, -50%, 0) rotate(-45deg);
}
&__collapse-chevron {
left: -1px;
position: relative;
}
&--active {
.hamburger {
&__x,
&__collapse,
&__collapse-label {
display: block;
opacity: 1;
}
&__icon {
display: none;
opacity: 0;
}
}
}
@include mid-break {
&__collapse-chevron {
top: 1px;
left: 0px;
}
} }
} }

View File

@@ -1,4 +1,5 @@
'use client' 'use client'
import { CloseMenuIcon, MenuIcon } from '@payloadcms/ui'
import React from 'react' import React from 'react'
import { ChevronIcon } from '../../icons/Chevron/index.js' import { ChevronIcon } from '../../icons/Chevron/index.js'
@@ -16,34 +17,25 @@ export const Hamburger: React.FC<{
return ( return (
<div className={baseClass}> <div className={baseClass}>
<div className={`${baseClass}__wrapper`}> {!isActive && (
<div className={`${baseClass}__icon`}> <div
{!isActive && ( aria-label={t('general:open')}
<div className={`${baseClass}__lines`} title={t('general:open')}> className={`${baseClass}__open-icon`}
<div className={`${baseClass}__line ${baseClass}__top`} /> title={t('general:open')}
<div className={`${baseClass}__line ${baseClass}__middle`} /> >
<div className={`${baseClass}__line ${baseClass}__bottom`} /> <MenuIcon />
</div>
)}
{isActive && (
<div
aria-label={closeIcon === 'collapse' ? t('general:collapse') : t('general:close')}
className={`${baseClass}__close-icon`}
title={closeIcon === 'collapse' ? t('general:collapse') : t('general:close')}
>
{closeIcon === 'x' && (
<React.Fragment>
<div className={`${baseClass}__line ${baseClass}__x-left`} />
<div className={`${baseClass}__line ${baseClass}__x-right`} />
</React.Fragment>
)}
{closeIcon === 'collapse' && (
<ChevronIcon className={`${baseClass}__collapse-chevron`} direction="left" />
)}
</div>
)}
</div> </div>
</div> )}
{isActive && (
<div
aria-label={closeIcon === 'collapse' ? t('general:collapse') : t('general:close')}
className={`${baseClass}__close-icon`}
title={closeIcon === 'collapse' ? t('general:collapse') : t('general:close')}
>
{closeIcon === 'x' && <CloseMenuIcon />}
{closeIcon === 'collapse' && <ChevronIcon direction="left" />}
</div>
)}
</div> </div>
) )
} }

View File

@@ -3,9 +3,9 @@
.id-label { .id-label {
font-size: base(0.75); font-size: base(0.75);
font-weight: normal; font-weight: normal;
color: var(--theme-elevation-400); color: var(--theme-elevation-600);
background: var(--theme-elevation-100); background: var(--theme-elevation-100);
padding: base(0.25) base(0.5); padding: 0 base(0.6);
border-radius: $style-radius-m; border-radius: $style-radius-m;
display: inline-flex; display: inline-flex;
} }

View File

@@ -12,7 +12,7 @@ export const IDLabel: React.FC<{ className?: string; id: string; prefix?: string
}) => ( }) => (
<div className={[baseClass, className].filter(Boolean).join(' ')} title={id}> <div className={[baseClass, className].filter(Boolean).join(' ')} title={id}>
{prefix} {prefix}
&nbsp;&nbsp; &nbsp;
{id} {id}
</div> </div>
) )

View File

@@ -5,6 +5,9 @@
display: flex; display: flex;
align-items: center; align-items: center;
background-color: var(--theme-elevation-50); background-color: var(--theme-elevation-50);
border-radius: var(--style-radius-m);
padding: base(0.6);
gap: base(0.6);
} }
.search-filter { .search-filter {
@@ -18,21 +21,13 @@
&__buttons-wrap { &__buttons-wrap {
display: flex; display: flex;
align-items: center; align-items: center;
gap: base(0.5); gap: base(0.2);
[dir='ltr'] & {
margin-right: base(0.5);
}
[dir='rtl'] & {
margin-left: base(0.5);
}
.pill { .pill {
background-color: var(--theme-elevation-200); background-color: var(--theme-elevation-150);
&:hover { &:hover {
background-color: var(--theme-elevation-150); background-color: var(--theme-elevation-100);
} }
} }
} }
@@ -56,7 +51,6 @@
} }
.search-filter { .search-filter {
margin-bottom: base(0.5);
width: 100%; width: 100%;
} }

View File

@@ -13,6 +13,7 @@ import { useListInfo } from '@payloadcms/ui'
import { useUseTitleField } from '../../hooks/useUseAsTitle.js' import { useUseTitleField } from '../../hooks/useUseAsTitle.js'
import { ChevronIcon } from '../../icons/Chevron/index.js' import { ChevronIcon } from '../../icons/Chevron/index.js'
import { SearchIcon } from '../../icons/Search/index.js'
import { useListQuery } from '../../providers/ListQuery/index.js' import { useListQuery } from '../../providers/ListQuery/index.js'
import { useSearchParams } from '../../providers/SearchParams/index.js' import { useSearchParams } from '../../providers/SearchParams/index.js'
import { useTranslation } from '../../providers/Translation/index.js' import { useTranslation } from '../../providers/Translation/index.js'
@@ -131,9 +132,12 @@ export const ListControls: React.FC<ListControlsProps> = (props) => {
return ( return (
<div className={baseClass}> <div className={baseClass}>
<div className={`${baseClass}__wrap`}> <div className={`${baseClass}__wrap`}>
<SearchIcon />
<SearchFilter <SearchFilter
fieldName={titleField?.name} fieldName={titleField?.name}
handleChange={handleSearchChange} handleChange={(search) => {
return void handleSearchChange(search)
}}
initialParams={searchParams} initialParams={searchParams}
key={collectionSlug} key={collectionSlug}
label={searchLabelTranslated.current} label={searchLabelTranslated.current}

View File

@@ -49,8 +49,8 @@
&--collapsed { &--collapsed {
.collapsible__toggle { .collapsible__toggle {
border-bottom-right-radius: $style-radius-s; border-bottom-right-radius: $style-radius-m;
border-bottom-left-radius: $style-radius-s; border-bottom-left-radius: $style-radius-m;
} }
} }
} }

View File

@@ -2,7 +2,7 @@
.pill { .pill {
font-size: 1rem; font-size: 1rem;
line-height: base(1); line-height: base(1.2);
display: inline-flex; display: inline-flex;
background: var(--theme-elevation-150); background: var(--theme-elevation-150);
color: var(--theme-elevation-800); color: var(--theme-elevation-800);
@@ -12,7 +12,7 @@
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
border: 0; border: 0;
padding: 0 base(0.25); padding: 0 base(0.4);
align-items: center; align-items: center;
flex-shrink: 0; flex-shrink: 0;
@@ -34,6 +34,7 @@
.icon { .icon {
flex-shrink: 0; flex-shrink: 0;
margin: base(0.1);
} }
&__label { &__label {
@@ -42,10 +43,6 @@
text-overflow: ellipsis; text-overflow: ellipsis;
} }
&__icon {
padding: calc(var(--base) / 4);
}
&--has-action { &--has-action {
cursor: pointer; cursor: pointer;
text-decoration: none; text-decoration: none;
@@ -56,27 +53,17 @@
} }
&--has-icon { &--has-icon {
padding-inline-start: base(0.4);
padding-inline-end: base(0.1);
svg { svg {
display: block; display: block;
} }
} }
[dir='rtl'] &--align-icon-left {
padding-right: 0;
padding-left: 10px;
}
[dir='rtl'] &--align-icon-right {
padding-right: 10px;
padding-left: 0;
}
&--align-icon-left { &--align-icon-left {
padding-left: 0; flex-direction: row-reverse;
} padding-inline-start: base(0.1);
padding-inline-end: base(0.4);
&--align-icon-right {
padding-right: 0;
} }
&--style-white { &--style-white {

View File

@@ -110,9 +110,8 @@ const StaticPill: React.FC<PillProps> = (props) => {
onClick={onClick} onClick={onClick}
type={Element === 'button' ? 'button' : undefined} type={Element === 'button' ? 'button' : undefined}
> >
{icon && alignIcon === 'left' && <span className={`${baseClass}__icon`}>{icon}</span>}
<span className={`${baseClass}__label`}>{children}</span> <span className={`${baseClass}__label`}>{children}</span>
{icon && alignIcon === 'right' && <span className={`${baseClass}__icon`}>{icon}</span>} {icon && <span className={`${baseClass}__icon`}>{icon}</span>}
</Element> </Element>
) )
} }

View File

@@ -9,6 +9,12 @@
--popup-padding: calc(var(--base) * 0.5); --popup-padding: calc(var(--base) * 0.5);
position: relative; position: relative;
&__trigger-wrap {
display: flex;
align-items: stretch;
height: 100%;
}
&__content { &__content {
position: absolute; position: absolute;
background: var(--popup-bg); background: var(--popup-bg);

View File

@@ -13,13 +13,15 @@ const DefaultPreviewButton: React.FC = () => {
<Button <Button
buttonStyle="secondary" buttonStyle="secondary"
className={baseClass} className={baseClass}
icon={'link'}
iconPosition="left"
// disabled={disabled} // disabled={disabled}
onClick={() => onClick={() =>
generatePreviewURL({ generatePreviewURL({
openPreviewWindow: true, openPreviewWindow: true,
}) })
} }
size="small" size="medium"
> >
{label} {label}
</Button> </Button>

View File

@@ -46,7 +46,7 @@ export const DefaultPublishButton: React.FC<{ label?: string }> = ({ label: labe
buttonId="action-save" buttonId="action-save"
disabled={!canPublish} disabled={!canPublish}
onClick={publish} onClick={publish}
size="small" size="medium"
type="button" type="button"
> >
{label} {label}

View File

@@ -2,14 +2,36 @@
.multi-value { .multi-value {
&.rs__multi-value { &.rs__multi-value {
display: flex;
padding: 0; padding: 0;
background: var(--theme-input-bg); border: 1px solid var(--theme-border-color);
border: $style-stroke-width-s solid var(--theme-elevation-800); border-radius: var(--style-radius-s);
line-height: calc(#{$baseline} - #{$style-stroke-width-s * 2}); line-height: calc(#{$baseline} - 2px);
margin: base(0.25) base(0.5) base(0.25) 0; margin: base(0.25) base(0.5) base(0.25) 0;
transition: border 0.2s cubic-bezier(0.2, 0, 0, 1);
&:hover {
border: 1px solid var(--theme-elevation-250);
}
} }
&--is-dragging { &--is-dragging {
z-index: 2; z-index: 2;
} }
} }
html[data-theme='light'] {
.multi-value {
&.rs__multi-value {
background: var(--theme-elevation-50);
}
}
}
html[data-theme='dark'] {
.multi-value {
&.rs__multi-value {
background: var(--theme-elevation-50);
}
}
}

View File

@@ -4,9 +4,9 @@
@extend %small; @extend %small;
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0 base(0.125) 0 base(0.25);
max-width: 150px; max-width: 150px;
color: currentColor; color: currentColor;
padding: 0 base(0.4);
&__text { &__text {
text-overflow: ellipsis; text-overflow: ellipsis;

View File

@@ -2,8 +2,7 @@
.multi-value-remove { .multi-value-remove {
cursor: pointer; cursor: pointer;
width: base(0.75); width: base(1);
height: base(0.75);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@@ -11,10 +10,11 @@
background-color: transparent; background-color: transparent;
border: none; border: none;
padding: 0; padding: 0;
color: inherit;
&:hover { &:hover {
color: var(--theme-elevation-800); color: var(--theme-elevation-800);
background: var(--theme-error-150); background: var(--theme-elevation-150);
} }
&__icon { &__icon {

View File

@@ -5,9 +5,9 @@
min-width: 0; min-width: 0;
.rs__value-container { .rs__value-container {
padding: base(0.25) 0;
min-height: base(1.5);
overflow: visible; overflow: visible;
padding: 2px;
gap: 2px;
> * { > * {
margin: 0; margin: 0;
@@ -21,18 +21,11 @@
} }
&--is-multi { &--is-multi {
margin-left: - base(0.25);
width: calc(100% + base(0.5)); width: calc(100% + base(0.5));
padding-top: base(0.25);
padding-bottom: base(0.25);
padding-left: base(0.25);
.rs__multi-value {
margin: calc(#{base(0.125)} - #{$style-stroke-width-s * 2});
}
&.rs__value-container--has-value { &.rs__value-container--has-value {
padding-left: 0; padding: 0;
margin-inline-start: -4px;
} }
} }
} }

View File

@@ -8,8 +8,7 @@
.rs__control { .rs__control {
@include formInput; @include formInput;
height: auto; height: auto;
padding-top: base(0.25); padding: base(0.4) base(0.6);
padding-bottom: base(0.25);
flex-wrap: nowrap; flex-wrap: nowrap;
} }
@@ -73,6 +72,6 @@
} }
&.rs--is-disabled .rs__control { &.rs--is-disabled .rs__control {
background: var(--theme-elevation-200); @include readOnly;
} }
} }

View File

@@ -1,9 +1,9 @@
@import '../../scss/styles.scss'; @import '../../scss/styles.scss';
.render-title { .render-title {
display: inline-flex;
&__id { &__id {
vertical-align: middle; vertical-align: middle;
position: relative; position: relative;
top: -3px;
} }
} }

View File

@@ -36,9 +36,11 @@ export const DefaultSaveButton: React.FC<{ label?: string }> = ({ label: labelPr
<FormSubmit <FormSubmit
buttonId="action-save" buttonId="action-save"
disabled={forceDisable} disabled={forceDisable}
onClick={() => submit()} onClick={() => {
return void submit()
}}
ref={ref} ref={ref}
size="small" size="medium"
type="button" type="button"
> >
{label} {label}

View File

@@ -74,9 +74,11 @@ export const DefaultSaveDraftButton: React.FC = () => {
buttonStyle="secondary" buttonStyle="secondary"
className={baseClass} className={baseClass}
disabled={forceDisable} disabled={forceDisable}
onClick={saveDraft} onClick={() => {
return void saveDraft()
}}
ref={ref} ref={ref}
size="small" size="medium"
type="button" type="button"
> >
{t('version:saveDraft')} {t('version:saveDraft')}

View File

@@ -21,8 +21,9 @@
&__input { &__input {
@include formInput; @include formInput;
height: auto;
padding: 0;
box-shadow: none; box-shadow: none;
padding-left: base(2);
background-color: var(--theme-elevation-50); background-color: var(--theme-elevation-50);
border: none; border: none;

View File

@@ -13,7 +13,6 @@ export type SearchFilterProps = {
import type { ParsedQs } from 'qs-esm' import type { ParsedQs } from 'qs-esm'
import { useDebounce } from '../../hooks/useDebounce.js' import { useDebounce } from '../../hooks/useDebounce.js'
import { SearchIcon } from '../../icons/Search/index.js'
import './index.scss' import './index.scss'
const baseClass = 'search-filter' const baseClass = 'search-filter'
@@ -49,7 +48,6 @@ export const SearchFilter: React.FC<SearchFilterProps> = (props) => {
type="text" type="text"
value={value || ''} value={value || ''}
/> />
<SearchIcon />
</div> </div>
) )
} }

View File

@@ -1,5 +1,6 @@
.select-row { .select-row {
&__checkbox { &__checkbox {
display: block; display: block;
width: min-content;
} }
} }

View File

@@ -50,6 +50,7 @@ export const StayLoggedInModal: React.FC = () => {
}), }),
) )
}} }}
size="large"
> >
{t('authentication:logOut')} {t('authentication:logOut')}
</Button> </Button>
@@ -58,6 +59,7 @@ export const StayLoggedInModal: React.FC = () => {
refreshCookie() refreshCookie()
toggleModal(stayLoggedInModalSlug) toggleModal(stayLoggedInModalSlug)
}} }}
size="large"
> >
{t('authentication:stayLoggedIn')} {t('authentication:stayLoggedIn')}
</Button> </Button>

View File

@@ -8,7 +8,7 @@
vertical-align: middle; vertical-align: middle;
background: var(--theme-elevation-150); background: var(--theme-elevation-150);
color: var(--theme-elevation-800); color: var(--theme-elevation-800);
border-radius: $style-radius-s; border-radius: $style-radius-m;
padding: 0 base(0.25); padding: 0 base(0.25);
background: var(--theme-elevation-100); background: var(--theme-elevation-100);
color: var(--theme-elevation-800); color: var(--theme-elevation-800);

View File

@@ -8,7 +8,7 @@
vertical-align: middle; vertical-align: middle;
background: var(--theme-elevation-150); background: var(--theme-elevation-150);
color: var(--theme-elevation-800); color: var(--theme-elevation-800);
border-radius: $style-radius-s; border-radius: $style-radius-m;
padding: 0 base(0.25); padding: 0 base(0.25);
[dir='ltr'] & { [dir='ltr'] & {
padding-left: base(0.0875 + 0.25); padding-left: base(0.0875 + 0.25);

View File

@@ -19,14 +19,23 @@
th, th,
td { td {
padding: base(0.75); padding: base(0.8) base(0.6);
min-width: 150px; min-width: 150px;
&:first-child {
padding-inline-start: base(0.8);
}
&:last-child {
padding-inline-end: base(0.8);
}
} }
tbody { tbody {
tr { tr {
&:nth-child(odd) { &:nth-child(odd) {
background: var(--theme-elevation-50); background: var(--theme-elevation-50);
border-radius: $style-radius-s;
} }
} }
} }

View File

@@ -2,9 +2,12 @@
.thumbnail-card { .thumbnail-card {
@include btn-reset; @include btn-reset;
@include shadow; @include shadow-m;
width: 100%; width: 100%;
background: var(--theme-input-bg); background: var(--theme-input-bg);
border: 1px solid var(--theme-border-color);
border-radius: var(--style-radius-m);
transition: border 100ms cubic-bezier(0, 0.2, 0.2, 1);
&__label { &__label {
padding: base(0.5); padding: base(0.5);
@@ -16,6 +19,12 @@
&--has-on-click { &--has-on-click {
cursor: pointer; cursor: pointer;
&:hover,
&:focus,
&:active {
border: 1px solid var(--theme-elevation-350);
}
} }
&--align-label-center { &--align-label-center {

View File

@@ -4,6 +4,7 @@
position: relative; position: relative;
margin-bottom: var(--base); margin-bottom: var(--base);
background: var(--theme-elevation-50); background: var(--theme-elevation-50);
border-radius: var(--style-radius-s);
&__upload { &__upload {
display: flex; display: flex;
@@ -60,7 +61,7 @@
cursor: pointer; cursor: pointer;
background-color: var(--theme-elevation-150); background-color: var(--theme-elevation-150);
border: none; border: none;
border-radius: $style-radius-s; border-radius: $style-radius-m;
padding: base(0.25) base(0.5); padding: base(0.25) base(0.5);
text-wrap: nowrap; text-wrap: nowrap;
overflow: hidden; overflow: hidden;

View File

@@ -50,6 +50,7 @@ export const ArrayRow: React.FC<ArrayRowProps> = ({
forceRender = false, forceRender = false,
hasMaxRows, hasMaxRows,
indexPath, indexPath,
isDragging,
isSortable, isSortable,
labels, labels,
listeners, listeners,
@@ -65,6 +66,7 @@ export const ArrayRow: React.FC<ArrayRowProps> = ({
setCollapse, setCollapse,
setNodeRef, setNodeRef,
transform, transform,
transition,
}) => { }) => {
const path = `${parentPath}.${rowIndex}` const path = `${parentPath}.${rowIndex}`
const { i18n } = useTranslation() const { i18n } = useTranslation()
@@ -91,6 +93,8 @@ export const ArrayRow: React.FC<ArrayRowProps> = ({
ref={setNodeRef} ref={setNodeRef}
style={{ style={{
transform, transform,
transition,
zIndex: isDragging ? 1 : undefined,
}} }}
> >
<Collapsible <Collapsible

View File

@@ -41,6 +41,7 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
display: flex; display: flex;
color: var(--theme-elevation-800);
} }
&__header-action { &__header-action {
@@ -51,6 +52,7 @@
&:hover, &:hover,
&:focus-visible { &:focus-visible {
text-decoration: underline; text-decoration: underline;
color: var(--theme-elevation-600);
} }
} }
@@ -74,7 +76,7 @@
&__add-row { &__add-row {
align-self: flex-start; align-self: flex-start;
color: var(--theme-elevation-400); color: var(--theme-elevation-400);
margin: 0; margin: 2px 0;
&:hover { &:hover {
color: var(--theme-elevation-800); color: var(--theme-elevation-800);

View File

@@ -1,6 +1,6 @@
@import '../../../../scss/styles.scss'; @import '../../../../scss/styles.scss';
$icon-width: base(1); $icon-width: base(2);
$icon-margin: base(0.25); $icon-margin: base(0.25);
.block-search { .block-search {
@@ -13,14 +13,13 @@ $icon-margin: base(0.25);
&__input { &__input {
@include formInput; @include formInput;
padding-right: calc(#{$icon-width} + #{$icon-margin} * 2);
} }
.search { .icon--search {
position: absolute; position: absolute;
top: 50%; top: 50%;
transform: translate3d(0, -50%, 0); transform: translate3d(0, -50%, 0);
right: base(0.25); right: 0;
width: $icon-width; width: $icon-width;
margin: 0 $icon-margin; margin: 0 $icon-margin;

View File

@@ -3,6 +3,7 @@
.section-title { .section-title {
position: relative; position: relative;
min-width: 0; min-width: 0;
pointer-events: all;
&:after { &:after {
display: block; display: block;

View File

@@ -15,14 +15,16 @@
.checkbox-input { .checkbox-input {
display: inline-flex; display: inline-flex;
&:hover:not(&--read-only) {
label,
input {
cursor: pointer;
}
}
label { label {
padding-bottom: 0; padding-bottom: 0;
padding-left: base(0.5); padding-left: base(0.5);
&[for] {
cursor: pointer;
}
} }
[dir='rtl'] &__input { [dir='rtl'] &__input {
@@ -51,7 +53,6 @@
opacity: 0; opacity: 0;
border-radius: 0; border-radius: 0;
z-index: 1; z-index: 1;
cursor: pointer;
} }
} }
@@ -69,8 +70,6 @@
&:focus { &:focus {
.checkbox-input__input, .checkbox-input__input,
& input[type='checkbox'] { & input[type='checkbox'] {
@include inputShadowActive;
outline: 0; outline: 0;
box-shadow: 0 0 3px 3px var(--theme-success-400) !important; box-shadow: 0 0 3px 3px var(--theme-success-400) !important;
border: 1px solid var(--theme-elevation-150); border: 1px solid var(--theme-elevation-150);
@@ -105,7 +104,7 @@
&--read-only { &--read-only {
.checkbox-input__input { .checkbox-input__input {
background-color: var(--theme-elevation-100); @include readOnly;
} }
label { label {

View File

@@ -15,4 +15,10 @@
background-color: var(--theme-error-50); background-color: var(--theme-error-50);
} }
} }
.read-only {
.code-editor {
@include readOnly;
}
}
} }

View File

@@ -18,7 +18,9 @@
} }
&__styled-radio { &__styled-radio {
@include formInput; border: 1px solid var(--theme-border-color);
background-color: var(--theme-input-bg);
@include shadow-sm;
width: $baseline; width: $baseline;
height: $baseline; height: $baseline;
position: relative; position: relative;
@@ -31,11 +33,18 @@
display: block; display: block;
border-radius: 100%; border-radius: 100%;
background-color: var(--theme-elevation-800); background-color: var(--theme-elevation-800);
width: calc(100% - 10px); width: calc(100% - 8px);
height: calc(100% - 10px); height: calc(100% - 8px);
border: 5px solid var(--theme-elevation-0); border: 4px solid var(--theme-elevation-0);
opacity: 0; opacity: 0;
} }
&--disabled {
@include readOnly;
&::before {
border-color: var(--theme-elevation-100);
}
}
} }
[dir='rtl'] &__label { [dir='rtl'] &__label {
@@ -61,8 +70,6 @@
&:hover { &:hover {
.radio-input { .radio-input {
&__styled-radio { &__styled-radio {
border-color: var(--theme-elevation-250);
&:before { &:before {
opacity: 0.2; opacity: 0.2;
} }

View File

@@ -39,7 +39,14 @@ export const Radio: React.FC<{
onChange={() => (typeof onChange === 'function' ? onChange(option.value) : null)} onChange={() => (typeof onChange === 'function' ? onChange(option.value) : null)}
type="radio" type="radio"
/> />
<span className={`${baseClass}__styled-radio`} /> <span
className={[
`${baseClass}__styled-radio`,
readOnly && `${baseClass}__styled-radio--disabled`,
]
.filter(Boolean)
.join(' ')}
/>
<span className={`${baseClass}__label`}>{getTranslation(option.label, i18n)}</span> <span className={`${baseClass}__label`}>{getTranslation(option.label, i18n)}</span>
</div> </div>
</label> </label>

View File

@@ -36,6 +36,10 @@
.radio-input { .radio-input {
cursor: default; cursor: default;
&:hover {
border-color: var(--theme-elevation-50);
}
&__label { &__label {
color: var(--theme-elevation-400); color: var(--theme-elevation-400);
} }
@@ -43,7 +47,7 @@
&--is-selected { &--is-selected {
.radio-input__styled-radio { .radio-input__styled-radio {
&:before { &:before {
background-color: var(--theme-elevation-100); background-color: var(--theme-elevation-250);
} }
} }
} }

View File

@@ -13,6 +13,9 @@
&__add-button, &__add-button,
&__add-button.doc-drawer__toggler { &__add-button.doc-drawer__toggler {
@include formInput; @include formInput;
margin: 0;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
position: relative; position: relative;
height: 100%; height: 100%;
margin-left: -1px; margin-left: -1px;

View File

@@ -22,6 +22,13 @@
background-color: var(--theme-error-500); background-color: var(--theme-error-500);
color: var(--theme-elevation-0); color: var(--theme-elevation-0);
} }
&--allow-create {
.rs__control {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
} }
html[data-theme='light'] { html[data-theme='light'] {

View File

@@ -472,6 +472,7 @@ const RelationshipFieldComponent: React.FC<RelationshipFieldProps> = (props) =>
showError && 'error', showError && 'error',
errorLoading && 'error-loading', errorLoading && 'error-loading',
readOnly && `${baseClass}--read-only`, readOnly && `${baseClass}--read-only`,
!readOnly && allowCreate && `${baseClass}--allow-create`,
] ]
.filter(Boolean) .filter(Boolean)
.join(' ')} .join(' ')}

View File

@@ -2,10 +2,12 @@
.relationship--multi-value-label { .relationship--multi-value-label {
display: flex; display: flex;
padding-inline-start: base(0.4);
gap: base(0.2);
&__content { &__content {
@extend %small; @extend %small;
padding: 0 base(0.125) 0 base(0.25); line-height: base(1.1);
max-width: 150px; max-width: 150px;
color: currentColor; color: currentColor;
display: flex; display: flex;
@@ -23,16 +25,17 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin-left: base(0.25); margin-left: base(0.2);
pointer-events: all; pointer-events: all;
.icon { .icon {
width: base(0.75); width: base(1);
height: base(0.75); height: base(1);
padding: base(0.1);
} }
&:hover { &:hover {
background-color: var(--theme-elevation-100); background-color: var(--theme-elevation-150);
} }
&:focus-visible { &:focus-visible {

View File

@@ -70,7 +70,7 @@ export const TextInput: React.FC<TextInputProps> = (props) => {
/> />
<div className={`${fieldBaseClass}__wrap`}> <div className={`${fieldBaseClass}__wrap`}>
<FieldError CustomError={CustomError} path={path} {...(errorProps || {})} /> <FieldError CustomError={CustomError} path={path} {...(errorProps || {})} />
{BeforeInput}
{hasMany ? ( {hasMany ? (
<ReactSelect <ReactSelect
className={`field-${path.replace(/\./g, '__')}`} className={`field-${path.replace(/\./g, '__')}`}
@@ -97,23 +97,20 @@ export const TextInput: React.FC<TextInputProps> = (props) => {
value={valueToRender} value={valueToRender}
/> />
) : ( ) : (
<div> <input
{BeforeInput} data-rtl={rtl}
<input disabled={readOnly}
data-rtl={rtl} id={`field-${path?.replace(/\./g, '__')}`}
disabled={readOnly} name={path}
id={`field-${path?.replace(/\./g, '__')}`} onChange={onChange as (e: ChangeEvent<HTMLInputElement>) => void}
name={path} onKeyDown={onKeyDown}
onChange={onChange as (e: ChangeEvent<HTMLInputElement>) => void} placeholder={getTranslation(placeholder, i18n)}
onKeyDown={onKeyDown} ref={inputRef}
placeholder={getTranslation(placeholder, i18n)} type="text"
ref={inputRef} value={value || ''}
type="text" />
value={value || ''}
/>
{AfterInput}
</div>
)} )}
{AfterInput}
{CustomDescription !== undefined ? ( {CustomDescription !== undefined ? (
CustomDescription CustomDescription
) : ( ) : (

View File

@@ -23,12 +23,7 @@
&.read-only { &.read-only {
.textarea-outer { .textarea-outer {
background: var(--theme-elevation-200); @include readOnly;
color: var(--theme-elevation-450);
&:hover {
border-color: var(--theme-elevation-150);
@include shadow-sm;
}
} }
} }

View File

@@ -6,16 +6,16 @@
&__wrap { &__wrap {
background: var(--theme-elevation-50); background: var(--theme-elevation-50);
padding: base(1); padding: base(1.6);
border-radius: $style-radius-s;
} }
&__buttons { &__buttons {
margin: base(-0.25);
width: calc(100% + #{base(0.5)}); width: calc(100% + #{base(0.5)});
flex-wrap: wrap; flex-wrap: wrap;
display: flex; display: flex;
align-items: center; align-items: center;
gap: base(0.25); gap: base(0.4);
.btn { .btn {
margin: 0; margin: 0;
@@ -35,6 +35,13 @@
width: calc(100% - #{base(0.5)}); width: calc(100% - #{base(0.5)});
} }
} }
&.read-only {
.file-details {
@include readOnly;
color: var(--theme-elevation-600);
}
}
} }
html[data-theme='light'] { html[data-theme='light'] {

Some files were not shown because too many files have changed in this diff Show More