Merge branch 'cleanup' into 'develop'

Fixes, styles improvements, cleanup, enforce classes order for classNames

See merge request soapbox-pub/soapbox!2258
environments/review-develop-3zknud/deployments/2597
marcin mikołajczak 2 years ago
commit 35bf20507d

@ -29,7 +29,7 @@ const CopyableInput: React.FC<ICopyableInput> = ({ value }) => {
type='text'
value={value}
className='rounded-r-none rtl:rounded-l-none rtl:rounded-r-lg'
outerClassName='flex-grow'
outerClassName='grow'
onClick={selectInput}
readOnly
/>

@ -18,4 +18,4 @@ const OutlineBox: React.FC<IOutlineBox> = ({ children, className, ...rest }) =>
);
};
export default OutlineBox;
export default OutlineBox;

@ -8,7 +8,7 @@ const themes = {
tertiary:
'bg-transparent border-gray-400 dark:border-gray-800 hover:border-primary-300 dark:hover:border-primary-700 focus:border-primary-500 text-gray-900 dark:text-gray-100 focus:ring-primary-500',
accent: 'border-transparent bg-secondary-500 hover:bg-secondary-400 focus:bg-secondary-500 text-gray-100 focus:ring-secondary-300',
danger: 'border-transparent bg-danger-100 dark:bg-danger-900 text-danger-600 dark:text-danger-200 hover:bg-danger-600 hover:text-gray-100 dark:hover:text-gray-100 dark:hover:bg-danger-500 focus:bg-danger-800 dark:focus:bg-danger-600',
danger: 'border-transparent bg-danger-100 dark:bg-danger-900 text-danger-600 dark:text-danger-200 hover:bg-danger-600 hover:text-gray-100 dark:hover:text-gray-100 dark:hover:bg-danger-500 focus:bg-danger-800 focus:text-gray-200 dark:focus:bg-danger-600 dark:focus:text-gray-100',
transparent: 'border-transparent text-gray-800 backdrop-blur-sm bg-white/75 hover:bg-white/80',
outline: 'border-gray-100 border-2 bg-transparent text-gray-100 hover:bg-white/10',
muted: 'border border-solid bg-transparent border-gray-400 dark:border-gray-800 hover:border-primary-300 dark:hover:border-primary-700 focus:border-primary-500 text-gray-900 dark:text-gray-100 focus:ring-primary-500',

@ -142,4 +142,4 @@ const Toast = (props: IToast) => {
);
};
export default Toast;
export default Toast;

@ -4,9 +4,8 @@ import { defineMessages, useIntl } from 'react-intl';
import { expandUserIndex, fetchUserIndex, setUserIndexQuery } from 'soapbox/actions/admin';
import ScrollableList from 'soapbox/components/scrollable-list';
import { Column } from 'soapbox/components/ui';
import { Column, Input } from 'soapbox/components/ui';
import AccountContainer from 'soapbox/containers/account-container';
import { SimpleForm, TextInput } from 'soapbox/features/forms';
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
const messages = defineMessages({
@ -22,7 +21,7 @@ const UserIndex: React.FC = () => {
const { isLoading, items, total, query, next } = useAppSelector((state) => state.admin_user_index);
const handleLoadMore = () => {
dispatch(expandUserIndex());
if (!isLoading) dispatch(expandUserIndex());
};
const updateQuery = useCallback(debounce(() => {
@ -31,25 +30,25 @@ const UserIndex: React.FC = () => {
const handleQueryChange: React.ChangeEventHandler<HTMLInputElement> = e => {
dispatch(setUserIndexQuery(e.target.value));
updateQuery();
};
useEffect(() => {
updateQuery();
}, [query]);
}, []);
const hasMore = items.count() < total && next !== null;
const hasMore = items.count() < total && !!next;
const showLoading = isLoading && items.isEmpty();
return (
<Column label={intl.formatMessage(messages.heading)}>
<SimpleForm style={{ paddingBottom: 0 }}>
<TextInput
value={query}
onChange={handleQueryChange}
placeholder={intl.formatMessage(messages.searchPlaceholder)}
/>
</SimpleForm>
<Input
value={query}
onChange={handleQueryChange}
placeholder={intl.formatMessage(messages.searchPlaceholder)}
/>
<ScrollableList
scrollKey='user-index'
hasMore={hasMore}

@ -581,4 +581,4 @@ const Audio: React.FC<IAudio> = (props) => {
);
};
export default Audio;
export default Audio;

@ -242,7 +242,10 @@ const PrivacyDropdown: React.FC<IPrivacyDropdown> = ({
<div className={clsx('privacy-dropdown', placement, { active: open })} onKeyDown={handleKeyDown} ref={node}>
<div className={clsx('privacy-dropdown__value', { active: valueOption && options.indexOf(valueOption) === 0 })}>
<IconButton
className='text-gray-600 hover:text-gray-700 dark:hover:text-gray-500'
className={clsx({
'text-gray-600 hover:text-gray-700 dark:hover:text-gray-500': !open,
'text-primary-500 hover:text-primary-600 dark:text-primary-500 dark:hover:text-primary-400': open,
})}
src={valueOption?.icon}
title={intl.formatMessage(messages.change_privacy)}
onClick={handleToggle}

@ -1,3 +1,4 @@
import clsx from 'clsx';
import React from 'react';
import AttachmentThumbs from 'soapbox/components/attachment-thumbs';
@ -8,12 +9,13 @@ import { isRtl } from 'soapbox/rtl';
import type { Status } from 'soapbox/types/entities';
interface IReplyIndicator {
className?: string,
status?: Status,
onCancel?: () => void,
hideActions: boolean,
}
const ReplyIndicator: React.FC<IReplyIndicator> = ({ status, hideActions, onCancel }) => {
const ReplyIndicator: React.FC<IReplyIndicator> = ({ className, status, hideActions, onCancel }) => {
const handleClick = () => {
onCancel!();
};
@ -33,7 +35,7 @@ const ReplyIndicator: React.FC<IReplyIndicator> = ({ status, hideActions, onCanc
}
return (
<Stack space={2} className='rounded-lg bg-gray-100 p-4 dark:bg-gray-800'>
<Stack space={2} className={clsx('rounded-lg bg-gray-100 p-4 dark:bg-gray-800', className)}>
<AccountContainer
{...actions}
id={status.getIn(['account', 'id']) as string}

@ -21,4 +21,4 @@ const Indicator: React.FC<IIndicator> = ({ state = 'inactive', size = 'sm' }) =>
);
};
export default Indicator;
export default Indicator;

@ -152,14 +152,14 @@ const ProfileField: StreamfieldComponent<AccountCredentialsField> = ({ value, on
<HStack space={2} grow>
<Input
type='text'
outerClassName='w-2/5 flex-grow'
outerClassName='w-2/5 grow'
value={value.name}
onChange={handleChange('name')}
placeholder={intl.formatMessage(messages.metaFieldLabel)}
/>
<Input
type='text'
outerClassName='w-3/5 flex-grow'
outerClassName='w-3/5 grow'
value={value.value}
onChange={handleChange('value')}
placeholder={intl.formatMessage(messages.metaFieldContent)}

@ -103,63 +103,6 @@ export const SimpleInput: React.FC<ISimpleInput> = (props) => {
);
};
interface ISimpleTextarea {
label?: React.ReactNode,
hint?: React.ReactNode,
value?: string,
onChange?: React.ChangeEventHandler<HTMLTextAreaElement>,
rows?: number,
name?: string,
maxLength?: number,
required?: boolean,
}
export const SimpleTextarea: React.FC<ISimpleTextarea> = (props) => {
const { hint, label, ...rest } = props;
const Input = label ? LabelTextarea : 'textarea';
return (
<InputContainer {...props}>
<Input {...rest} />
</InputContainer>
);
};
interface ISimpleForm {
className?: string,
onSubmit?: React.FormEventHandler,
acceptCharset?: string,
style?: React.CSSProperties,
children: React.ReactNode,
}
export const SimpleForm: React.FC<ISimpleForm> = (props) => {
const {
className,
children,
onSubmit = () => {},
acceptCharset = 'UTF-8',
...rest
} = props;
const handleSubmit: React.FormEventHandler = e => {
onSubmit(e);
e.preventDefault();
};
return (
<form
className={clsx('simple_form', className)}
method='post'
onSubmit={handleSubmit}
acceptCharset={acceptCharset}
{...rest}
>
{children}
</form>
);
};
interface ICheckbox {
label?: React.ReactNode,
hint?: React.ReactNode,

@ -36,7 +36,7 @@ const ListForm = () => {
<Form onSubmit={handleSubmit}>
<HStack space={2}>
<Input
outerClassName='flex-grow'
outerClassName='grow'
type='text'
value={value}
onChange={handleChange}

@ -1,18 +0,0 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
import Icon from 'soapbox/components/icon';
interface IClearColumnButton {
onClick: React.MouseEventHandler<HTMLButtonElement>;
}
const ClearColumnButton: React.FC<IClearColumnButton> = ({ onClick }) => (
<button className='text-btn column-header__setting-btn' tabIndex={0} onClick={onClick}>
<Icon src={require('@tabler/icons/eraser.svg')} />
{' '}
<FormattedMessage id='notifications.clear' defaultMessage='Clear notifications' />
</button>
);
export default ClearColumnButton;

@ -78,7 +78,7 @@ const PlaceholderMediaGallery: React.FC<IPlaceholderMediaGallery> = ({ media, de
const float = dimensions.float as any || 'left';
const position = dimensions.pos as any || 'relative';
return <div key={i} className='media-gallery__item' style={{ position, float, left, top, right, bottom, height, width }} />;
return <div key={i} className='media-gallery__item animate-pulse bg-primary-200' style={{ position, float, left, top, right, bottom, height, width }} />;
};
const sizeData = getSizeData(media.size);

@ -1,58 +0,0 @@
import React from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { getSettings, changeSettingImmediate } from 'soapbox/actions/settings';
import List, { ListItem } from 'soapbox/components/list';
import { Card, CardBody, CardHeader, CardTitle } from 'soapbox/components/ui';
import { SimpleForm, SelectDropdown } from 'soapbox/features/forms';
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
const messages = defineMessages({
mediaDisplay: { id: 'preferences.fields.media_display_label', defaultMessage: 'Media display' },
display_media_default: { id: 'preferences.fields.display_media.default', defaultMessage: 'Hide media marked as sensitive' },
display_media_hide_all: { id: 'preferences.fields.display_media.hide_all', defaultMessage: 'Always hide media' },
display_media_show_all: { id: 'preferences.fields.display_media.show_all', defaultMessage: 'Always show media' },
});
const MediaDisplay = () => {
const dispatch = useAppDispatch();
const intl = useIntl();
const settings = useAppSelector((state) => getSettings(state));
const displayMediaOptions = {
default: intl.formatMessage(messages.display_media_default),
hide_all: intl.formatMessage(messages.display_media_hide_all),
show_all: intl.formatMessage(messages.display_media_show_all),
};
const onSelectChange: (path: string[]) => React.ChangeEventHandler<HTMLSelectElement> = path => {
return e => {
dispatch(changeSettingImmediate(path, e.target.value));
};
};
return (
<Card variant='rounded'>
<CardHeader>
<CardTitle title={intl.formatMessage(messages.mediaDisplay)} />
</CardHeader>
<CardBody>
<SimpleForm className='space-y-3 p-0'>
<List>
<ListItem label={intl.formatMessage(messages.mediaDisplay)}>
<SelectDropdown
items={displayMediaOptions}
defaultValue={settings.get('displayMedia') as string}
onChange={onSelectChange(['displayMedia'])}
/>
</ListItem>
</List>
</SimpleForm>
</CardBody>
</Card>
);
};
export default MediaDisplay;

@ -25,21 +25,21 @@ const CryptoAddressInput: StreamfieldComponent<CryptoAddress> = ({ value, onChan
<HStack space={2} grow>
<Input
type='text'
outerClassName='w-1/6 flex-grow'
outerClassName='w-1/6 grow'
value={value.ticker}
onChange={handleChange('ticker')}
placeholder={intl.formatMessage(messages.ticker)}
/>
<Input
type='text'
outerClassName='w-3/6 flex-grow'
outerClassName='w-3/6 grow'
value={value.address}
onChange={handleChange('address')}
placeholder={intl.formatMessage(messages.address)}
/>
<Input
type='text'
outerClassName='w-2/6 flex-grow'
outerClassName='w-2/6 grow'
value={value.note}
onChange={handleChange('note')}
placeholder={intl.formatMessage(messages.note)}

@ -24,14 +24,14 @@ const PromoPanelInput: StreamfieldComponent<FooterItem> = ({ value, onChange })
<HStack space={2} grow>
<Input
type='text'
outerClassName='w-full flex-grow'
outerClassName='w-full grow'
placeholder={intl.formatMessage(messages.label)}
value={value.title}
onChange={handleChange('title')}
/>
<Input
type='text'
outerClassName='w-full flex-grow'
outerClassName='w-full grow'
placeholder={intl.formatMessage(messages.url)}
value={value.url}
onChange={handleChange('url')}

@ -36,14 +36,14 @@ const PromoPanelInput: StreamfieldComponent<PromoPanelItem> = ({ value, onChange
<Input
type='text'
outerClassName='w-full flex-grow'
outerClassName='w-full grow'
placeholder={intl.formatMessage(messages.label)}
value={value.text}
onChange={handleChange('text')}
/>
<Input
type='text'
outerClassName='w-full flex-grow'
outerClassName='w-full grow'
placeholder={intl.formatMessage(messages.url)}
value={value.url}
onChange={handleChange('url')}

@ -1,4 +1,4 @@
import classnames from 'clsx';
import clsx from 'clsx';
import { List as ImmutableList } from 'immutable';
import React, { useState, useEffect } from 'react';
@ -112,7 +112,7 @@ const Card: React.FC<ICard> = ({
const interactive = card.type !== 'link';
horizontal = typeof horizontal === 'boolean' ? horizontal : interactive || embedded;
const className = classnames('status-card', { horizontal, compact, interactive }, `status-card--${card.type}`);
const className = clsx('status-card', { horizontal, compact, interactive }, `status-card--${card.type}`);
const ratio = getRatio(card);
const height = (compact && !embedded) ? (width / (16 / 9)) : (width / ratio);
@ -223,7 +223,7 @@ const Card: React.FC<ICard> = ({
);
} else if (card.image) {
embed = (
<div className={classnames(
<div className={clsx(
'status-card__image',
'w-full flex-none rounded-l md:h-auto md:w-auto md:flex-auto',
{

@ -39,4 +39,4 @@ const FloatingActionButton: React.FC<IFloatingActionButton> = () => {
);
};
export default FloatingActionButton;
export default FloatingActionButton;

@ -162,4 +162,4 @@ class ImageLoader extends React.PureComponent<IImageLoader> {
}
export default ImageLoader;
export default ImageLoader;

@ -4,9 +4,8 @@ import { FormattedMessage } from 'react-intl';
import { spring } from 'react-motion';
import Icon from 'soapbox/components/icon';
import StatusContent from 'soapbox/components/status-content';
import { HStack, Stack } from 'soapbox/components/ui';
import AccountContainer from 'soapbox/containers/account-container';
import { HStack } from 'soapbox/components/ui';
import ReplyIndicator from 'soapbox/features/compose/components/reply-indicator';
import Motion from '../../util/optional-motion';
@ -56,16 +55,7 @@ const ActionsModal: React.FC<IActionsModal> = ({ status, actions, onClick, onClo
{({ top }) => (
<div className='modal-root__modal actions-modal' style={{ top: `${top}%` }}>
{status && (
<Stack space={2} className='border-b border-solid border-gray-200 bg-gray-50 p-4 dark:border-gray-700 dark:bg-gray-800'>
<AccountContainer
key={status.account as string}
id={status.account as string}
showProfileHoverCard={false}
withLinkToProfile={false}
timestamp={status.created_at}
/>
<StatusContent status={status} />
</Stack>
<ReplyIndicator className='actions-modal__status rounded-b-none' status={status} hideActions />
)}
<ul className={clsx({ 'with-status': !!status })}>

@ -3,7 +3,7 @@ import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
import { useHistory } from 'react-router-dom';
import { remoteInteraction } from 'soapbox/actions/interactions';
import { Button, Modal, Stack, Text } from 'soapbox/components/ui';
import { Button, Form, Input, Modal, Stack, Text } from 'soapbox/components/ui';
import { useAppSelector, useAppDispatch, useFeatures, useInstance, useRegistrationStatus } from 'soapbox/hooks';
import toast from 'soapbox/toast';
@ -104,9 +104,8 @@ const UnauthorizedModal: React.FC<IUnauthorizedModal> = ({ action, onClose, acco
secondaryText={isOpen ? <FormattedMessage id='account.register' defaultMessage='Sign up' /> : undefined}
>
<div className='remote-interaction-modal__content'>
<form className='simple_form remote-interaction-modal__fields' onSubmit={onSubmit}>
<input
type='text'
<Form className='remote-interaction-modal__fields' onSubmit={onSubmit}>
<Input
placeholder={intl.formatMessage(messages.accountPlaceholder)}
name='remote_follow[acct]'
value={account}
@ -116,7 +115,7 @@ const UnauthorizedModal: React.FC<IUnauthorizedModal> = ({ action, onClose, acco
required
/>
<Button type='submit' theme='primary'>{button}</Button>
</form>
</Form>
<div className='remote-interaction-modal__divider'>
<Text align='center'>
<FormattedMessage id='remote_interaction.divider' defaultMessage='or' />

@ -56,7 +56,7 @@ const UploadArea: React.FC<IUploadArea> = ({ active, onClose }) => {
<Stack space={3} justifyContent='center' alignItems='center'>
<Icon
src={require('@tabler/icons/cloud-upload.svg')}
className='h-12 w-12 text-white text-opacity-90'
className='h-12 w-12 text-white/90'
/>
<Text size='xl' theme='white'>

@ -72,7 +72,6 @@ import {
Lists,
Bookmarks,
Settings,
MediaDisplay,
EditProfile,
EditEmail,
EditPassword,
@ -301,7 +300,6 @@ const SwitchingColumnsArea: React.FC<ISwitchingColumnsArea> = ({ children }) =>
<WrappedRoute path='/settings/email' page={DefaultPage} component={EditEmail} content={children} />
<WrappedRoute path='/settings/password' page={DefaultPage} component={EditPassword} content={children} />
<WrappedRoute path='/settings/account' page={DefaultPage} component={DeleteAccount} content={children} />
<WrappedRoute path='/settings/media_display' page={DefaultPage} component={MediaDisplay} content={children} />
<WrappedRoute path='/settings/mfa' page={DefaultPage} component={MfaForm} exact />
<WrappedRoute path='/settings/tokens' page={DefaultPage} component={AuthTokenList} content={children} />
<WrappedRoute path='/settings' page={DefaultPage} component={Settings} content={children} />

@ -238,10 +238,6 @@ export function Settings() {
return import(/* webpackChunkName: "features/settings" */'../../settings');
}
export function MediaDisplay() {
return import(/* webpackChunkName: "features/settings" */'../../settings/media-display');
}
export function EditProfile() {
return import(/* webpackChunkName: "features/edit_profile" */'../../edit-profile');
}

@ -1,34 +0,0 @@
// THEME MIXINS
// standard container drop shadow
@mixin standard-panel-shadow {
box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.1);
}
// common properties for all standard containers
@mixin standard-panel {
@include standard-panel-shadow;
border-radius: 10px;
background: var(--foreground-color);
}
// SHORTCUTS
@mixin input-placeholder($color) {
&::-webkit-input-placeholder { color: $color; }
&::-moz-placeholder { color: $color; }
&:-ms-input-placeholder { color: $color; }
&:-moz-placeholder { color: $color; }
}
@mixin avatar-radius {
border-radius: 50%;
background: transparent no-repeat;
background-position: 50%;
background-clip: padding-box;
}
@mixin avatar-size($size: 48px) {
width: $size;
height: $size;
background-size: $size $size;
}

@ -1,5 +1,3 @@
@import 'mixins';
@import 'themes';
@import 'variables';
@import 'fonts';
@import 'basics';
@ -9,7 +7,6 @@
@import 'rtl';
@import 'accessibility';
@import 'navigation';
@import 'placeholder';
@import 'autosuggest';
// COMPONENTS
@ -17,7 +14,6 @@
@import 'components/dropdown-menu';
@import 'components/modal';
@import 'components/compose-form';
@import 'components/emoji-reacts';
@import 'components/status';
@import 'components/reply-mentions';
@import 'components/detailed-status';

@ -1,8 +1,3 @@
.autosuggest-input {
position: relative;
}
.autosuggest-input input,
.react-datepicker__input-container input {
// display: block;
// box-sizing: border-box;

@ -8,64 +8,9 @@ body.with-modals {
@apply overflow-hidden;
}
body {
&.lighter {
background: var(--brand-color--med);
}
&.player {
text-align: center;
}
&.embed {
background: var(--brand-color--faint);
margin: 0;
padding-bottom: 0;
.container {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
}
}
&.admin {
background: var(--brand-color--med);
position: fixed;
width: 100%;
height: 100%;
padding: 0;
}
&.error {
@apply text-gray-400;
position: absolute;
text-align: center;
background: var(--brand-color--med);
width: 100%;
height: 100%;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
.dialog {
vertical-align: middle;
margin: 20px;
h1 {
font-size: 20px;
line-height: 28px;
font-weight: 400;
}
}
}
}
// Note: this is needed for React HotKeys performance. Removing this
// will cause severe performance degradation on Safari.
div[tabindex="-1"]:focus {
div[tabindex='-1']:focus {
outline: 0;
}
@ -75,28 +20,6 @@ div[tabindex="-1"]:focus {
noscript {
text-align: center;
img {
width: 200px;
opacity: 0.5;
animation: flicker 4s infinite;
}
div {
@apply text-gray-400;
font-size: 14px;
margin: 30px auto;
max-width: 400px;
a {
color: var(--highlight-text-color);
text-decoration: underline;
&:hover {
text-decoration: none;
}
}
}
}
.emojione {
@ -105,6 +28,6 @@ noscript {
// Virtuoso empty placeholder fix.
// https://gitlab.com/petyosi/soapbox-fe/-/commit/1e22c39934b60e5e186de804060ecfdf1955b506
div[data-viewport-type="window"] {
div[data-viewport-type='window'] {
position: static !important;
}

@ -1,69 +1,51 @@
.audio-player {
overflow: hidden;
box-sizing: border-box;
position: relative;
background: $base-shadow-color;
border-radius: 10px;
padding-bottom: 44px;
@apply relative box-border overflow-hidden rounded-[10px] bg-black pb-11;
direction: ltr;
&.editable {
border-radius: 0;
height: 100%;
@apply rounded-none h-full;
}
.video-player__volume::before,
.video-player__seek::before {
background: currentcolor;
opacity: 0.15;
@apply bg-current opacity-[15];
}
.video-player__seek__buffer {
background: currentcolor;
opacity: 0.2;
@apply bg-current opacity-20;
}
.video-player__buttons button {
color: currentcolor;
opacity: 0.75;
@apply text-current opacity-[75];
&:active,
&:hover,
&:focus {
color: currentcolor;
opacity: 1;
@apply text-current opacity-100;
}
}
.video-player__time-sep,
.video-player__time-total,
.video-player__time-current {
color: currentcolor;
@apply text-current;
}
.video-player__seek::before,
.video-player__seek__buffer,
.video-player__seek__progress {
top: 0;
@apply top-0;
}
.video-player__seek__handle {
top: -4px;
@apply -top-1;
}
.video-player__controls {
padding-top: 10px;
background: transparent;
@apply pt-2.5 bg-transparent;
}
}
.media-spoiler-audio {
background-size: cover;
background-repeat: no-repeat;
background-position: center;
cursor: pointer;
margin-top: 8px;
position: relative;
border: 0;
display: block;
@apply relative mt-2 block cursor-pointer border-0 bg-cover bg-center bg-no-repeat;
}

@ -1,79 +1,3 @@
.column {
width: 350px;
position: relative;
box-sizing: border-box;
display: flex;
flex-direction: column;
flex: 1 1 100%;
}
@media screen and (min-width: 631px) {
.column {
flex: 0 0 auto;
padding: 10px;
padding-left: 5px;
padding-right: 5px;
&:first-child {
padding-left: 10px;
}
&:last-child {
padding-right: 10px;
}
}
}
.column-link {
@apply text-gray-900;
background: var(--brand-color--med);
display: flex;
align-items: center;
font-size: 16px;
padding: 15px;
text-decoration: none;
&:hover,
&:focus,
&:active {
background: var(--brand-color--faint);
}
&:focus {
outline: 0;
}
&--transparent {
@apply bg-transparent;
color: var(--background-color);
&:hover,
&:focus,
&:active {
@apply text-gray-900 bg-transparent;
}
&.active {
color: var(--brand-color);
}
}
}
.svg-icon.column-link__icon {
display: inline-block;
margin-right: 5px;
}
.column-header__setting-btn {
&--link {
text-decoration: none;
}
&:hover {
@apply text-gray-400 underline;
}
}
.empty-column-indicator,
.error-column {
@apply bg-primary-50 dark:bg-gray-700 text-gray-900 dark:text-gray-300 text-center p-10 flex flex-1 items-center justify-center min-h-[160px] rounded-lg;

@ -13,7 +13,6 @@
}
a {
color: var(--brand-color--hicontrast);
font-weight: 500;
text-decoration: underline;
@ -28,171 +27,153 @@
&__modifiers {
@apply text-gray-900 text-sm;
font-family: inherit;
background: var(--background-color);
}
}
.compose-form__upload-wrapper { overflow: hidden; }
&__upload-wrapper { overflow: hidden; }
.compose-form__uploads-wrapper {
display: flex;
flex-direction: row;
flex-wrap: wrap;
&__uploads-wrapper {
display: flex;
flex-direction: row;
flex-wrap: wrap;
&.contains-media {
padding: 5px;
border-top: 1px solid var(--foreground-color);
&.contains-media {
padding: 5px;
}
}
}
.compose-form__upload {
flex: 1 1 0;
min-width: 40%;
margin: 5px;
position: relative;
border-radius: 4px;
overflow: hidden;
&__upload {
flex: 1 1 0;
min-width: 40%;
margin: 5px;
position: relative;
border-radius: 4px;
overflow: hidden;
&__actions {
@apply bg-gradient-to-b from-gray-900/80 via-gray-900/50 to-transparent flex items-start justify-between opacity-0 transition-opacity duration-100 ease-linear;
&__actions {
@apply bg-gradient-to-b from-gray-900/80 via-gray-900/50 to-transparent flex items-start justify-between opacity-0 transition-opacity duration-100 ease-linear;
&.active {
@apply opacity-100;
}
&.active {
@apply opacity-100;
}
.icon-button {
@apply text-gray-200 hover:text-white text-sm font-medium p-2.5 space-x-1 rtl:space-x-reverse flex items-center;
.icon-button {
@apply text-gray-200 hover:text-white text-sm font-medium p-2.5 space-x-1 rtl:space-x-reverse flex items-center;
}
}
}
&-description {
@apply bg-gradient-to-b from-transparent via-gray-900/50 to-gray-900/80 absolute z-[2px] bottom-0 left-0 right-0 p-2.5 opacity-0 transition-opacity duration-100 ease-linear;
&-description {
@apply bg-gradient-to-b from-transparent via-gray-900/50 to-gray-900/80 absolute z-[2px] bottom-0 left-0 right-0 p-2.5 opacity-0 transition-opacity duration-100 ease-linear;
&.active {
@apply opacity-100;
}
&.active {
@apply opacity-100;
}
textarea {
@apply bg-transparent text-white border-solid border border-white/25 p-2.5 rounded-md text-sm w-full m-0;
textarea {
@apply bg-transparent text-white border-solid border border-white/25 p-2.5 rounded-md text-sm w-full m-0;
&::placeholder {
@apply text-white/60;
&::placeholder {
@apply text-white/60;
}
}
}
}
&-preview {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
video {
&-preview {
position: absolute;
width: 100%;
height: 100%;
object-fit: cover;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: -1;
video {
width: 100%;
height: 100%;
object-fit: cover;
}
}
}
}
.compose-form__upload-thumbnail {
background-position: center;
background-size: contain;
background-repeat: no-repeat;
height: 160px;
width: 100%;
overflow: hidden;
position: relative;
&.video {
background-image: url('../assets/images/video-placeholder.png');
background-size: cover;
}
&.audio {
background-image: url('../assets/images/audio-placeholder.png');
background-size: cover;
}
}
.privacy-dropdown__dropdown {
@apply absolute bg-white dark:bg-gray-900 z-[1000] rounded-md shadow-lg ml-10 text-sm;
&__upload-thumbnail {
background-position: center;
background-size: contain;
background-repeat: no-repeat;
height: 160px;
width: 100%;
overflow: hidden;
position: relative;
&.top {
transform-origin: 50% 100%;
}
&.video {
background-image: url('../assets/images/video-placeholder.png');
background-size: cover;
}
&.bottom {
transform-origin: 50% 0;
&.audio {
background-image: url('../assets/images/audio-placeholder.png');
background-size: cover;
}
}
}
.privacy-dropdown__option {
@apply flex p-2.5 text-sm text-gray-700 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer;
.privacy-dropdown {
&.active {
@apply bg-gray-100 dark:bg-gray-800;
}
&.top .privacy-dropdown__value {
@apply rounded-t-md;
}
&:hover,
&.active {
.privacy-dropdown__option__content,
.privacy-dropdown__option__content strong {
@apply text-black dark:text-white;
.privacy-dropdown__dropdown {
@apply block shadow-md;
}
}
&.active {
@apply hover:bg-gray-200 dark:hover:bg-gray-700;
}
}
&__dropdown {
@apply absolute bg-white dark:bg-gray-900 z-[1000] rounded-md shadow-lg ml-10 text-sm overflow-hidden;
.privacy-dropdown__option__icon {
@apply flex items-center justify-center mr-2.5;
}
.privacy-dropdown__option__content {
@apply flex-auto text-primary-600 dark:text-primary-400;
strong {
@apply block font-medium text-black dark:text-white;
&.top {
transform-origin: 50% 100%;
}
@each $lang in $cjk-langs {
&:lang(#{$lang}) {
@apply font-bold;
}
&.bottom {
transform-origin: 50% 0;
}
}
}
.privacy-dropdown.active {
.privacy-dropdown__value {
background: var(--foreground-color);
border-radius: 4px 4px 0 0;
box-shadow: 0 -4px 4px rgba($base-shadow-color, 0.1);
&__option {
@apply flex p-2.5 text-sm text-gray-700 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800 cursor-pointer;
&.active {
@apply bg-gray-100 dark:bg-gray-800;
}
.icon-button {
transition: none;
&:hover,
&.active {
.privacy-dropdown__option__content,
.privacy-dropdown__option__content strong {
@apply text-black dark:text-white;
}
}
&.active {
background: var(--brand-color);
@apply hover:bg-gray-200 dark:hover:bg-gray-700;
}
.icon-button {
@apply text-gray-900;
}
&__icon {
@apply flex items-center justify-center mr-2.5 rtl:mr-0 rtl:ml-2.5;
}
}
&.top .privacy-dropdown__value {
@apply rounded-t-md;
}
&__content {
@apply flex-auto text-primary-600 dark:text-primary-400;
strong {
@apply block font-medium text-black dark:text-white;
.privacy-dropdown__dropdown {
@apply block shadow-md;
@each $lang in $cjk-langs {
&:lang(#{$lang}) {
@apply font-bold;
}
}
}
}
}
}

@ -1,98 +0,0 @@
.emoji-react {
@apply inline-block text-gray-900 dark:text-gray-300 no-underline;
transition: 0.2s;
&__emoji {
img {
@apply w-5 h-5;
filter: drop-shadow(2px 0 0 var(--foreground-color));
}
}
&__count {
@apply hidden;
}
+ .emoji-react {
@apply -mr-3;
}
&[type='button'] {
cursor: pointer;
}
}
.emoji-reacts {
display: inline-flex;
flex-direction: row-reverse;
}
.emoji-reacts-container {
display: inline-flex;
&:hover {
.emoji-react {
margin: 0;
&__count {
display: inline;
}
}
.emoji-reacts__count {
display: none;
}
}
}
.emoji-react-selector {
position: absolute;
display: flex;
background-color: var(--foreground-color);
padding: 5px 8px;
border-radius: 9999px;
box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.1);
opacity: 0;
pointer-events: none;
transition: 0.1s;
z-index: 999;
&--visible,
&--focused {
opacity: 1;
pointer-events: all;
}
&__emoji {
display: block;
padding: 0;
margin: 0;
border: 0;
background: transparent;
img {
width: 36px;
height: 36px;
padding: 3px;
transition: 0.1s;
}
&:hover,
&:focus {
img {
transform: scale(1.2);
}
}
}
}
.status .emoji-react-selector {
bottom: 100%;
left: -20px;
@media (max-width: 455px) {
bottom: 31px;
right: 10px;
left: auto;
}
}

@ -12,46 +12,6 @@
height: 100%;
transition: 0.2s;
}
&--active {
&.svg-icon--home svg {
fill: currentcolor;
}
svg.icon-tabler-search,
svg.icon-tabler-code {
stroke-width: 2.3px;
}
svg.icon-tabler-bell,
svg.icon-tabler-messages {
path:nth-child(2) {
fill: currentcolor;
}
}
svg.icon-tabler-users {
circle,
circle + path {
fill: currentcolor;
}
}
svg.icon-tabler-mail {
stroke: var(--background-color);
rect {
fill: currentcolor;
stroke: currentcolor;
}
}
}
&--unread {
svg.icon-tabler-bell {
transform: rotate(45deg);
}
}
}
.icon-button > div {

@ -1,3 +1,5 @@
$media-compact-size: 50px;
.media-gallery {
box-sizing: border-box;
overflow: hidden;
@ -6,159 +8,145 @@
position: relative;
width: 100%;
height: auto;
background-color: var(--brand-color--faint);
}
.media-gallery__item {
border: 0;
box-sizing: border-box;
display: block;
float: left;
position: relative;
border-radius: 10px;
overflow: hidden;
&__item {
border: 0;
box-sizing: border-box;
display: block;
float: left;
position: relative;
border-radius: 10px;
overflow: hidden;
&__icons {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
.svg-icon {
@apply h-24 w-24;
}
}
&__icons {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
&-overflow {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.75);
z-index: 2;
color: #333;
text-align: center;
font-weight: bold;
font-size: 50px;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
}
.svg-icon {
@apply h-24 w-24;
&-thumbnail {
@apply text-gray-400;
cursor: zoom-in;
display: block;
text-decoration: none;
line-height: 0;
position: relative;
z-index: 1;
height: 100%;
width: 100%;
video {
width: 100%;
height: 100%;
object-fit: cover;
}
}
}
&-overflow {
position: absolute;
&__preview {
@apply bg-gray-200 dark:bg-gray-900 rounded-lg;
width: 100%;
height: 100%;
object-fit: cover;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.75);
z-index: 2;
color: #333;
text-align: center;
font-weight: bold;
font-size: 50px;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
}
}
z-index: 0;
.media-gallery__item-thumbnail {
@apply text-gray-400;
cursor: zoom-in;
display: block;
text-decoration: none;
line-height: 0;
position: relative;
z-index: 1;
height: 100%;
width: 100%;
&--hidden {
display: none;
}
}
video {
&__gifv {
height: 100%;
overflow: hidden;
position: relative;
width: 100%;
}
&__item-gifv-thumbnail {
@apply rounded-md;
cursor: zoom-in;
height: 100%;
object-fit: cover;
position: relative;
width: 100%;
z-index: 1;
transform: none;
top: 0;
}
}
.media-gallery__preview {
@apply bg-gray-200 dark:bg-gray-900 rounded-lg;
width: 100%;
height: 100%;
object-fit: cover;
position: absolute;
top: 0;
left: 0;
z-index: 0;
&--hidden {
display: none;
&__gifv__label,
&__filename__label,
&__file-extension__label {
@apply pointer-events-none absolute bottom-1.5 left-1.5 z-[1] block bg-black/50 py-0.5 px-1.5 font-semibold text-white opacity-90;
font-size: 11px;
transition: opacity 0.1s ease;
line-height: 18px;
}
}
.media-gallery__gifv {
height: 100%;
overflow: hidden;
position: relative;
width: 100%;
}
.media-gallery__item-gifv-thumbnail {
@apply rounded-md;
cursor: zoom-in;
height: 100%;
object-fit: cover;
position: relative;
width: 100%;
z-index: 1;
transform: none;
top: 0;
}
.media-gallery__gifv__label,
.media-gallery__filename__label,
.media-gallery__file-extension__label {
display: block;
position: absolute;
color: #fff;
background: rgba($base-overlay-background, 0.5);
bottom: 6px;
left: 6px;
padding: 2px 6px;
border-radius: 2px;
font-size: 11px;
font-weight: 600;
z-index: 1;
pointer-events: none;
opacity: 0.9;
transition: opacity 0.1s ease;
line-height: 18px;
}
.media-gallery__gifv {
&.autoplay {
.media-gallery__gifv__label {
display: none;
&__gifv {
&.autoplay {
.media-gallery__gifv__label {
display: none;
}
}
}
&:hover {
.media-gallery__gifv__label {
opacity: 1;
&:hover {
.media-gallery__gifv__label {
opacity: 1;
}
}
}
}
$media-compact-size: 50px;
.media-gallery--compact {
height: $media-compact-size !important;
background: transparent;
.media-gallery__item {
width: $media-compact-size !important;
&--compact {
height: $media-compact-size !important;
inset: auto !important;
float: left !important;
margin-right: 5px;
&-overflow {
font-size: 20px;
background: transparent;
.media-gallery__item {
width: $media-compact-size !important;
height: $media-compact-size !important;
inset: auto !important;
float: left !important;
margin-right: 5px;
&-overflow {
font-size: 20px;
}
&__icons .svg-icon {
@apply h-8 w-8;
}
}
&__icons .svg-icon {
@apply h-8 w-8;
.media-gallery__file-extension__label {
display: none;
}
}
.media-gallery__file-extension__label {
display: none;
}
}

@ -27,197 +27,179 @@
height: 100%;
video {
max-width: $media-modal-media-max-width;
max-height: $media-modal-media-max-height;
@apply max-w-full max-h-[80%];
}
}
}
.media-modal__closer {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.media-modal__navigation {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: none;
transition: opacity 0.3s linear;
will-change: opacity;
* {
pointer-events: auto;
&__closer {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
&.media-modal__navigation--hidden {
opacity: 0;
&__navigation {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: none;
transition: opacity 0.3s linear;
will-change: opacity;
* {
pointer-events: none;
pointer-events: auto;
}
}
}
.media-modal__nav {
background: rgba($base-overlay-background, 0.5);
box-sizing: border-box;
border: 0;
color: #fff;
cursor: pointer;
display: flex;
align-items: center;
font-size: 24px;
height: 20vmax;
margin: auto 0;
padding: 30px 15px;
position: absolute;
top: 0;
bottom: 0;
@media screen and (max-width: 600px) { padding: 30px 2px; }
.svg-icon {
width: 24px;
height: 24px;
&--hidden {
opacity: 0;
* {
pointer-events: none;
}
}
}
}
.media-modal__nav--left {
left: 0;
}
&__nav {
@apply absolute top-0 bottom-0 my-auto mx-0 box-border flex h-[20vmax] cursor-pointer items-center border-0 bg-black/50 text-2xl text-white;
padding: 30px 15px;
.media-modal__nav--right {
right: 0;
}
@media screen and (max-width: 600px) {
@apply px-0.5;
}
.media-modal__pagination {
width: 100%;
text-align: center;
position: absolute;
left: 0;
bottom: 20px;
pointer-events: none;
}
.svg-icon {
@apply h-6 w-6;
}
.media-modal__meta {
text-align: center;
position: absolute;
left: 0;
bottom: 20px;
width: 100%;
pointer-events: none;
&--left {
left: 0;
}
&--shifted {
bottom: 62px;
&--right {
right: 0;
}
}
a {
text-decoration: none;
font-weight: 500;
color: #fff;
&__pagination {
width: 100%;
text-align: center;
position: absolute;
left: 0;
bottom: 20px;
pointer-events: none;
}
&:hover,
&:focus,
&:active {
text-decoration: underline;
&__meta {
text-align: center;
position: absolute;
left: 0;
bottom: 20px;
width: 100%;
pointer-events: none;
&--shifted {
bottom: 62px;
}
}
}
.media-modal__page-dot {
display: inline-block;
}
a {
text-decoration: none;
font-weight: 500;
color: #fff;
.media-modal__button {
background-color: #fff;
height: 12px;
width: 12px;
border-radius: 6px;
margin: 10px;
padding: 0;
border: 0;
font-size: 0;
}
&:hover,
&:focus,
&:active {
text-decoration: underline;
}
}
}
.media-modal__button--active {
@apply bg-accent-500;
}
&__page-dot {
display: inline-block;
}
.media-modal__close {
position: absolute;
right: 8px;
top: 8px;
height: 48px;
width: 48px;
z-index: 100;
color: #fff;
&__button {
background-color: #fff;
height: 12px;
width: 12px;
border-radius: 6px;
margin: 10px;
padding: 0;
border: 0;
font-size: 0;
.svg-icon {
&--active {
@apply bg-accent-500;
}
}
&__close {
position: absolute;
right: 8px;
top: 8px;
height: 48px;
width: 48px;
z-index: 100;
color: #fff;
.svg-icon {
height: 48px;
width: 48px;
}
}
}
.error-modal {
@apply text-gray-900;
background: var(--background-color);
border-radius: 8px;
overflow: hidden;
display: flex;
flex-direction: column;
}
.error-modal__body {
height: 80vh;
width: 80vw;
max-width: 520px;
max-height: 420px;
position: relative;
& > div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 25px;
&__body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
opacity: 0;
user-select: text;
align-items: center;
height: 80vh;
width: 80vw;
max-width: 520px;
max-height: 420px;
position: relative;
text-align: center;
& > div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 25px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
opacity: 0;
user-select: text;
}
}
}
.error-modal__body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.error-modal__footer {
flex: 0 0 auto;
background: var(--background-color);
display: flex;
justify-content: center;
padding: 25px;
&__footer {
flex: 0 0 auto;
display: flex;
justify-content: center;
padding: 25px;
& > div {
min-width: 33px;
& > div {
min-width: 33px;
}
}
.error-modal__nav {
color: var(--highlight-text-color);
&__nav {
border: 0;
font-size: 14px;
font-weight: 500;
@ -232,45 +214,39 @@
&:focus,
&:active {
@apply text-gray-400;
background-color: var(--background-color);
}
}
}
.actions-modal {
@apply flex-col relative text-gray-400 overflow-hidden;
border-radius: 10px;
border: 1px solid var(--background-color);
@apply flex-col relative text-gray-400 overflow-hidden w-full max-w-lg m-auto bg-white dark:bg-gray-900 shadow-xl rounded-2xl;
max-height: calc(100vh - 3rem);
&__item-label {
font-weight: 500;
}
.dropdown-menu__separator {
@apply block m-2 h-[1px] bg-gray-200 dark:bg-gray-600;
}
}
.actions-modal {
@apply w-full max-h-full max-w-lg m-auto mb-2 bg-white dark:bg-gray-800;
.status {
overflow-y: auto;
max-height: 300px;
&__status {
@apply overflow-y-auto max-h-[300px];
}
.actions-modal__item-label { font-weight: 500; }
ul {
@apply my-2 flex-shrink-0 overflow-y-auto;
max-height: calc(100vh - 147px);
// NOTE - not sure what this is yet, leaving alone for now until I find out.
&.with-status { max-height: calc(80vh - 75px); }
li:not(:empty) {
a,
button {
@apply flex items-center px-4 py-3 text-gray-600 dark:text-gray-300 no-underline hover:bg-gray-100 dark:bg-gray-800 hover:text-gray-800 dark:hover:text-gray-200 text-left;
@apply flex items-center px-4 py-3 text-gray-700 dark:text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 focus:bg-gray-100 dark:focus:bg-primary-800 no-underline text-left;
&.destructive {
@apply text-danger-600;
@apply text-danger-600 dark:text-danger-400;
}
.svg-icon:first-child {
@ -278,11 +254,6 @@
svg {
stroke-width: 1.5;
&.feather {
// Feather icons are a little larger
transform: scale(0.9);
}
}
}
}

@ -6,7 +6,7 @@
border: 0;
padding: 0;
user-select: none;
-webkit-tap-highlight-color: rgba($base-overlay-background, 0);
-webkit-tap-highlight-color: #0000;
-webkit-tap-highlight-color: transparent;
&:focus-within .react-toggle-track {

@ -38,24 +38,7 @@
.svg-icon--backspace {
cursor: pointer;
color: var(--highlight-text-color);
width: 22px;
height: 22px;
&:hover {
color: var(--brand-color);
}
}
}
.column {
.search {
@apply border border-solid border-b-gray-900/20;
padding: 10px 15px;
background-color: var(--foreground-color);
}
.search__icon .svg-icon {
right: 24px;
}
}

@ -78,7 +78,6 @@ a.status-card {
.status-card__image {
flex: 0 0 40%;
background: var(--brand-color--med);
position: relative;
overflow: hidden;
@ -117,8 +116,9 @@ a.status-card {
padding-bottom: 10px;
&__status {
@include standard-panel;
padding: 15px 0 10px;
box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.1);
border-radius: 10px;
}
.status {

@ -11,17 +11,11 @@
}
.video-player {
overflow: hidden;
position: relative;
background: $base-shadow-color;
max-width: 100%;
border-radius: 10px;
box-sizing: border-box;
@apply relative box-border max-w-full overflow-hidden rounded-[10px] bg-black text-white;
direction: ltr;
color: white;
&.editable {
border-radius: 0;
@apply rounded-none;
height: 100% !important;
}
@ -63,7 +57,7 @@
left: 0;
right: 0;
box-sizing: border-box;
background: linear-gradient(0deg, rgba($base-shadow-color, 0.85) 0, rgba($base-shadow-color, 0.45) 60%, transparent);
background: linear-gradient(0deg, #000000d9 0, #00000073 60%, transparent);
padding: 0 15px;
opacity: 0;
transition: opacity 0.1s ease;
@ -199,7 +193,7 @@
left: 0;
margin-left: -6px;
transform: translate(0, -50%);
box-shadow: 1px 2px 6px rgba($base-shadow-color, 0.2);
box-shadow: 1px 2px 6px #0003;
opacity: 0;
.no-reduce-motion & {
@ -272,7 +266,7 @@
height: 12px;
top: 10px;
margin-left: -6px;
box-shadow: 1px 2px 6px rgba($base-shadow-color, 0.2);
box-shadow: 1px 2px 6px #0003;
.no-reduce-motion & {
transition: opacity 0.1s ease;

@ -2,21 +2,6 @@
// TYPEOGRAPHY MIXINS
// declare the font family using these shortcuts
@mixin font-inter { font-family: Inter, Arial, sans-serif !important; }
// Declare font weights as a numerical value in rendered output
// Prevents certain browsers which do not play nice with "light, medium" textual declarations
// Numeical values always work more consistently across browsers
// Each font-weight is linked with the @font-face declaration to the actual font file
@mixin font-weight($weight) {
@if $weight == 'light' { font-weight: 300; }
@if $weight == 'normal' { font-weight: 400; }
@if $weight == 'medium' { font-weight: 500; }
@if $weight == 'bold' { font-weight: 700; }
@if $weight == 'extrabold' { font-weight: 800; }
}
// Use these mixins to define font-size and line-height
// html and body declaration allows developer to pass px value as argument
// Rendered css will default to "rem" and fall back to "px" for unsupported browsers
@ -26,10 +11,3 @@
font-size: #{$px + 'px'};
font-size: #{$rem + 'rem'};
}
@mixin line-height($size) {
$rem: math.div($size, 10);
$px: $size;
line-height: #{$px + 'px'};
line-height: #{$rem + 'rem'};
}

@ -22,442 +22,8 @@ select {
margin-left: -1px;
}
.simple_form {
.input {
&.hidden {
margin: 0;
}
&.radio_buttons {
.radio {
margin-bottom: 15px;
&:last-child {
margin-bottom: 0;
}
}
.radio > label {
position: relative;
padding-left: 28px;
input {
position: absolute;
top: -2px;
left: 0;
}
}
}
&.boolean {
position: relative;
.label_input > label {
@apply text-sm font-medium text-gray-700 dark:text-gray-400;
font-family: inherit;
font-size: 14px;
display: block;
width: auto;
}
.label_input,
.hint {
padding-left: 28px;
}
.label_input__wrapper {
position: static;
}
input[type="checkbox"] {
position: absolute;
top: 1px;
left: 0;
}
label a {
color: var(--highlight-text-color);
text-decoration: underline;
&:hover,
&:active,
&:focus {
text-decoration: none;
}
}
}
}
.row {
display: flex;
margin: 0 -5px;
.input {
box-sizing: border-box;
flex: 1 1 auto;
width: 50%;
padding: 0 5px;
}
}
.hint {
@apply text-gray-400;
a {
color: var(--highlight-text-color);
}
code {
border-radius: 3px;
padding: 0.2em 0.4em;
background: var(--background-color);
}
}
span.hint {
display: block;
font-size: 12px;
}
p.hint {
@apply text-gray-400;
margin-bottom: 15px;
&.subtle-hint {
text-align: center;
font-size: 12px;
line-height: 18px;
margin-top: 15px;
margin-bottom: 0;
}
}
.card {
margin-bottom: 15px;
}
strong {
font-weight: 500;
@each $lang in $cjk-langs {
&:lang(#{$lang}) {
font-weight: 700;
}
}
}
.input.with_floating_label {
.label_input {
display: flex;
& > label {
@apply text-gray-900;
font-family: inherit;
font-size: 14px;
font-weight: 500;
min-width: 150px;
flex: 0 0 auto;
}
input,
select {
flex: 1 1 auto;
}
}
&.select .hint {
margin-top: 6px;
margin-left: 150px;
}
}
.input {
.label_input > label {
@apply text-gray-700 dark:text-gray-400;
font-family: inherit;
font-size: 14px;
display: block;
word-wrap: break-word;
font-weight: 500;
}
ul {
flex: 390px;
}
}
.required abbr {
text-decoration: none;
color: lighten($error-value-color, 12%);
}
.input.radio_buttons .radio label {
@apply text-gray-900;
margin-bottom: 5px;
font-family: inherit;
font-size: 14px;
display: block;
width: auto;
}
fieldset[disabled] {
input[type=text],
input[type=number],
input[type=email],
input[type=url],
input[type=password],
textarea {
@apply text-gray-400 border-gray-400;
}
}
input[type=text],
input[type=number],
input[type=email],
input[type=url],
input[type=password],
textarea,
.rfipbtn {
@apply border border-solid border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-black dark:text-white;
box-sizing: border-box;
font-size: 16px;
display: block;
width: 100%;
outline: 0;
font-family: inherit;
resize: vertical;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
border-radius: 6px;
padding: 8px 12px;
transition: 0.2s;
&:invalid {
box-shadow: none;
}
&:focus:invalid:not(:placeholder-shown) {
border-color: lighten($error-red, 12%);
}
// &:required:valid {
// border-color: $valid-value-color;
// }
&:active,
&:focus {
border-color: var(--brand-color);
outline: 2px solid transparent;
outline-offset: 2px;
box-shadow: rgb(255, 255, 255) 0 0 0 0,
var(--brand-color) 0 0 0 1px,
rgba(0, 0, 0, 0.05) 0 1px 2px 0;
}
}
.rfip {
width: 100%;
margin: 0;
}
input[type=text][disabled],
input[type=number][disabled],
input[type=email][disabled],
input[type=url][disabled],
input[type=password][disabled],
textarea[disabled] {
@apply text-gray-400 border-gray-400;
}
.input.field_with_errors {
label {
color: lighten($error-red, 12%);
}
input[type=text],
input[type=number],
input[type=email],
input[type=url],
input[type=password],
textarea,
select {
border-color: lighten($error-red, 12%);
}
}
.error {
display: block;
font-weight: 500;
color: lighten($error-red, 12%);
margin-top: 4px;
}
.input.disabled {
opacity: 0.5;
}
.actions {
margin-top: 20px;
display: flex;
justify-content: flex-end;
}
// button,
// .button,
// .block-button,
// .color-swatch {
// display: block;
// width: 100%;
// border: 0;
// border-radius: 4px;
// background: var(--brand-color);
// color: #fff;
// line-height: inherit;
// height: auto;
// padding: 10px;
// text-decoration: none;
// text-align: center;
// box-sizing: border-box;
// cursor: pointer;
// font-weight: 500;
// outline: 0;
// &:last-child {
// margin-right: 0;
// }
// &:hover,
// &:active,
// &:focus {
// background-color: var(--brand-color--hicontrast);
// }
// &.negative {
// background: $error-value-color;
// &:hover {
// background-color: lighten($error-value-color, 5%);
// }
// &:active,
// &:focus {
// background-color: darken($error-value-color, 5%);
// }
// }
// &.accordion__toggle {
// display: inline-block;
// width: auto;
// border: 0;
// border-radius: 0;
// background: none;
// color: var(--primary-text-color--faint);
// font-size: 18px;
// line-height: inherit;
// height: auto;
// padding: 0 10px;
// text-transform: none;
// text-decoration: none;
// text-align: center;
// box-sizing: border-box;
// cursor: pointer;
// font-weight: 500;
// outline: 0;
// margin-bottom: 0;
// margin-right: 10px;
// }
// }
// select {
// appearance: none;
// background-color: transparent;
// background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M6 8l4 4 4-4'/%3e%3c/svg%3e");
// background-position: right 0.5rem center;
// background-repeat: no-repeat;
// background-size: 1.5em 1.5em;
// border-radius: 0.375rem;
// border: none;
// color: var(--gray-500);
// display: inline-block;
// font-family: var(--font-sans-serif), sans-serif;
// font-size: 14px;
// height: var(--input-height);
// padding-bottom: 0.5rem;
// padding-left: 0.75rem;
// padding-right: 2.5rem;
// padding-top: 0.5rem;
// }
.label_input__wrapper {
position: relative;
}
h2 {
font-size: 20px;
line-height: normal;
margin-bottom: 14px;
font-weight: bold;
}
}
.simple_form {
.warning {
@apply text-gray-900;
box-sizing: border-box;
background: rgba($error-value-color, 0.5);
text-shadow: 1px 1px 0 rgba($base-shadow-color, 0.3);
box-shadow: 0 2px 6px rgba($base-shadow-color, 0.4);
border-radius: 4px;
padding: 10px;
margin-bottom: 15px;
a {
@apply text-gray-900 underline;
&:hover,
&:focus,
&:active {
@apply no-underline;
}
}
strong {
font-weight: 600;
display: block;
margin-bottom: 5px;
@each $lang in $cjk-langs {
&:lang(#{$lang}) {
font-weight: 700;
}
}
.fa {
font-weight: 400;
}
}
}
}
.captcha {
background-color: #fff;
border-radius: 4px;
img {
display: table;
margin: 0 auto;
}
input[type="text"] {
border-radius: 0 0 4px 4px;
}
}
.input.with_label.toggle .label_input {
display: flex;
font-size: 14px;
align-items: center;
.theme-toggle {
margin-left: 10px;
}
}

@ -59,7 +59,7 @@
}
@keyframes heartbeat {
from {
0% {
transform: scale(1);
animation-timing-function: ease-out;
}
@ -130,26 +130,16 @@
.load-more {
@apply block w-full m-0 p-4 border-0 box-border text-gray-900 bg-transparent;
&:hover,
&:focus {
background: var(--brand-color--faint);
}
.svg-icon {
@apply mx-auto;
}
}
.load-gap {
border-bottom: 1px solid var(--brand-color--med);
}
.regeneration-indicator {
@apply text-gray-900;
text-align: center;
font-size: 16px;
font-weight: 500;
background: var(--accent-color--faint);
cursor: default;
display: flex;
flex: 1 1 auto;

@ -1,40 +0,0 @@
.media-gallery--placeholder {
position: relative;
&::before {
content: '';
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
background-image: linear-gradient(
90deg,
hsla(var(--foreground-color_hsl), 0) 0%,
hsla(var(--foreground-color_hsl), 0) 25%,
var(--foreground-color) 50%,
hsla(var(--foreground-color_hsl), 0) 70%,
hsla(var(--foreground-color_hsl), 0) 100%
);
background-size: 200%;
animation: placeholder-pulse 2s infinite;
z-index: 1;
opacity: 0.9;
}
}
@keyframes placeholder-pulse {
0% { background-position-x: 200%; }
100% { background-position-x: 0; }
}
.media-gallery.media-gallery--placeholder {
background: none;
.media-gallery__item {
background-color: var(--brand-color--faint);
}
}

@ -1,56 +1,11 @@
body.rtl {
direction: rtl;
.column-link__icon {
margin-right: 0;
margin-left: 5px;
}
.status {
padding-left: 10px;
padding-right: 68px;
}
.privacy-dropdown__dropdown {
margin-left: 0;
margin-right: 40px;
}
.privacy-dropdown__option__icon {
margin-left: 10px;
margin-right: 0;
}
.simple_form .input.with_label.boolean label.checkbox {
padding-left: 25px;
padding-right: 0;
}
.simple_form .input.radio_buttons .radio {
left: auto;
right: 0;
}
.simple_form .input.radio_buttons .radio > label {
padding-right: 28px;
padding-left: 0;
}
.simple_form .input.boolean label.checkbox {
left: auto;
right: 0;
}
.simple_form .input.boolean .label_input,
.simple_form .input.boolean .hint {
padding-left: 0;
padding-right: 28px;
}
// .simple_form select {
// background: var(--background-color) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14.933 18.467' height='19.698' width='15.929'><path d='M3.467 14.967l-3.393-3.5H14.86l-3.392 3.5c-1.866 1.925-3.666 3.5-4 3.5-.335 0-2.135-1.575-4-3.5zm.266-11.234L7.467 0 11.2 3.733l3.733 3.734H0l3.733-3.734z' fill='#{hex-color(var(--brand-color--med))}'/></svg>") no-repeat left 8px center / auto 16px;
// }
.table th,
.table td {
text-align: right;
@ -67,9 +22,4 @@ body.rtl {
}
}
}
.simple_form .input.radio_buttons .radio > label input {
left: auto;
right: 0;
}
}

@ -1,77 +0,0 @@
/*
# CSS VARIABLE NAMING CONVENTIONS
Primary variables are fully-formed CSS properties.
Form: --{primary-name}
Examples:
--brand-color
--accent-color
--primary-text-color
Meta-variables are combined to make primary variables.
Form: --{primary-name}_{property}
Examples:
--brand-color_h (int, hue)
--brand-color_s (percent, saturation)
--brand-color_l (percent, lightness)
--brand-color_hsl (csv of the 3 variables above)
Modifiers are variations of primary variables made by modifying their meta-values.
Form: --{primary-name}--{modifier}
Examples:
--brand-color--faint
--brand-color--hicontrast
--primary-text-color--faint
*/
body,
.site-preview {
// Primary variables
--brand-color: hsl(var(--brand-color_hsl));
--accent-color: hsl(var(--accent-color_hsl));
--background-color: hsl(var(--background-color_hsl));
--foreground-color: hsl(var(--foreground-color_hsl));
// Meta-variables
--brand-color_hsl: var(--brand-color_h), var(--brand-color_s), var(--brand-color_l);
--accent-color_hsl: var(--accent-color_h), var(--accent-color_s), var(--accent-color_l);
--background-color_hsl: var(--background-color_h), var(--background-color_s), var(--background-color_l);
--foreground-color_hsl: var(--foreground-color_h), var(--foreground-color_s), var(--foreground-color_l);
--accent-color_h: calc(var(--brand-color_h) - 15);
--accent-color_s: 86%;
--accent-color_l: 44%;
// Modifiers
--brand-color--faint: hsla(var(--brand-color_hsl), 0.1);
--brand-color--med: hsla(var(--brand-color_hsl), 0.2);
--accent-color--faint: hsla(var(--accent-color_hsl), 0.15);
--accent-color--bright: hsl(
var(--accent-color_h),
var(--accent-color_s),
calc(var(--accent-color_l) + 3%)
);
}
.theme-mode-light {
// Primary variables
--highlight-text-color: hsl(
var(--brand-color_h),
var(--brand-color_s),
calc(var(--brand-color_l) - 8%)
);
// Meta-variables
--background-color_h: 0;
--background-color_s: 0%;
--background-color_l: 94.9%;
--foreground-color_h: 0;
--foreground-color_s: 0%;
--foreground-color_l: 100%;
// Modifiers
--brand-color--hicontrast: hsl(
var(--brand-color_h),
var(--brand-color_s),
calc(var(--brand-color_l) - 5%)
);
}

@ -25,11 +25,6 @@
cursor: default;
}
&.active {
color: var(--highlight-text-color);
opacity: 1;
}
&::-moz-focus-inner {
border: 0;
}
@ -75,8 +70,7 @@
flex-direction: column;
.image-loader__preview-canvas {
max-width: $media-modal-media-max-width;
max-height: $media-modal-media-max-height;
@apply max-w-full max-h-[80%];
background: url('../assets/images/void.png') repeat;
object-fit: contain;
}
@ -90,9 +84,7 @@
@apply relative w-full h-full flex items-center justify-center;
img {
@apply w-auto h-auto object-contain shadow-2xl;
max-width: $media-modal-media-max-width;
max-height: $media-modal-media-max-height;
@apply w-auto h-auto max-w-full max-h-[80%] object-contain shadow-2xl;
}
}
@ -133,12 +125,6 @@
font-family: inherit;
padding: 7px 0;
&:focus,
&:active {
@apply text-gray-900;
border-bottom-color: var(--highlight-text-color);
}
@media screen and (max-width: 600px) {
font-size: 16px;
}

@ -1,23 +1,7 @@
// Commonly used web colors
$error-red: #df405a !default; // Cerise
// Variables for defaults in UI
$base-shadow-color: #000 !default;
$base-overlay-background: #000 !default;
$error-value-color: $error-red !default;
// Language codes that uses CJK fonts
/* stylelint-disable-next-line value-keyword-case -- locale filenames */
$cjk-langs: ja, ko, zh-CN, zh-HK, zh-TW;
// Variables for components
$media-modal-media-max-width: 100%;
// put margins on top and bottom of image to avoid the screen covered by image.
$media-modal-media-max-height: 80%;
$no-gap-breakpoint: 415px;
// CSS variables
// NOTE: Prefer CSS variables whenever possible.
// They're future-proof and more flexible.

Loading…
Cancel
Save