mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-14 14:21:36 +01:00
Auto-expand URL bar height
This commit is contained in:
@@ -47,11 +47,11 @@ export const UrlBar = memo(function UrlBar({ id: requestId, url, method, classNa
|
||||
<form onSubmit={handleSubmit} className={classNames('url-bar', className)}>
|
||||
<Input
|
||||
ref={inputRef}
|
||||
size="sm"
|
||||
size="auto"
|
||||
hideLabel
|
||||
useTemplating
|
||||
contentType="url"
|
||||
className="px-0"
|
||||
className="px-0 py-0.5"
|
||||
name="url"
|
||||
label="Enter URL"
|
||||
forceUpdateKey={updateKey}
|
||||
@@ -63,7 +63,7 @@ export const UrlBar = memo(function UrlBar({ id: requestId, url, method, classNa
|
||||
<RequestMethodDropdown
|
||||
method={method}
|
||||
onChange={handleMethodChange}
|
||||
className="mx-0.5 h-full my-1"
|
||||
className="!h-auto mx-0.5 my-0.5"
|
||||
/>
|
||||
}
|
||||
rightSlot={
|
||||
@@ -72,7 +72,7 @@ export const UrlBar = memo(function UrlBar({ id: requestId, url, method, classNa
|
||||
iconSize="sm"
|
||||
title="Send Request"
|
||||
type="submit"
|
||||
className="w-8 mr-0.5"
|
||||
className="!h-auto w-8 mr-0.5 my-0.5"
|
||||
icon={loading ? 'update' : 'paperPlane'}
|
||||
spin={loading}
|
||||
/>
|
||||
|
||||
@@ -1,203 +1,210 @@
|
||||
.cm-wrapper {
|
||||
@apply h-full overflow-hidden;
|
||||
@apply h-full overflow-hidden;
|
||||
|
||||
.cm-editor {
|
||||
@apply w-full block text-base;
|
||||
|
||||
* {
|
||||
@apply cursor-text;
|
||||
}
|
||||
|
||||
&.cm-focused {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.cm-content {
|
||||
@apply py-0;
|
||||
}
|
||||
|
||||
.cm-line {
|
||||
@apply text-gray-800 pl-1 pr-1.5;
|
||||
}
|
||||
|
||||
.cm-placeholder {
|
||||
@apply text-placeholder;
|
||||
}
|
||||
|
||||
.cm-scroller {
|
||||
/* Inherit line-height from outside */
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
/* Don't show selection on blurred input */
|
||||
.cm-selectionBackground {
|
||||
@apply bg-transparent;
|
||||
}
|
||||
&.cm-focused .cm-selectionBackground {
|
||||
@apply bg-selection;
|
||||
}
|
||||
|
||||
/* Style gutters */
|
||||
.cm-gutters {
|
||||
@apply border-0 text-gray-500/50;
|
||||
|
||||
.cm-gutterElement {
|
||||
@apply cursor-default;
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder-widget {
|
||||
@apply text-xs text-gray-800 dark:text-gray-900 px-1 rounded cursor-default dark:shadow;
|
||||
|
||||
/* NOTE: Background and border are translucent so we can see text selection through it */
|
||||
@apply bg-gray-300/40 border border-gray-300 border-opacity-40 hover:border-opacity-80;
|
||||
|
||||
/* Bring above on hover */
|
||||
@apply hover:z-10 relative;
|
||||
}
|
||||
}
|
||||
|
||||
&.cm-singleline {
|
||||
.cm-editor {
|
||||
@apply w-full h-auto;
|
||||
}
|
||||
|
||||
.cm-scroller {
|
||||
@apply font-mono text-[0.8rem] overflow-hidden;
|
||||
}
|
||||
|
||||
.cm-line {
|
||||
@apply px-2 overflow-hidden;
|
||||
}
|
||||
}
|
||||
|
||||
&.cm-multiline {
|
||||
&.cm-full-height {
|
||||
@apply relative;
|
||||
|
||||
.cm-editor {
|
||||
@apply inset-0 absolute;
|
||||
position: absolute !important;
|
||||
}
|
||||
}
|
||||
|
||||
.cm-editor {
|
||||
@apply w-full block text-base;
|
||||
|
||||
* {
|
||||
@apply cursor-text;
|
||||
}
|
||||
|
||||
&.cm-focused {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.cm-content {
|
||||
@apply py-0;
|
||||
}
|
||||
|
||||
.cm-line {
|
||||
@apply text-gray-800 pl-1 pr-1.5;
|
||||
}
|
||||
|
||||
.cm-placeholder {
|
||||
@apply text-placeholder;
|
||||
}
|
||||
|
||||
.cm-scroller {
|
||||
/* Inherit line-height from outside */
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
/* Don't show selection on blurred input */
|
||||
.cm-selectionBackground {
|
||||
@apply bg-transparent;
|
||||
}
|
||||
&.cm-focused .cm-selectionBackground {
|
||||
@apply bg-selection;
|
||||
}
|
||||
|
||||
/* Style gutters */
|
||||
.cm-gutters {
|
||||
@apply border-0 text-gray-500/50;
|
||||
|
||||
.cm-gutterElement {
|
||||
@apply cursor-default;
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder-widget {
|
||||
@apply text-xs text-gray-800 dark:text-gray-900 px-1 rounded cursor-default dark:shadow;
|
||||
|
||||
/* NOTE: Background and border are translucent so we can see text selection through it */
|
||||
@apply bg-gray-300/40 border border-gray-300 border-opacity-40 hover:border-opacity-80;
|
||||
|
||||
/* Bring above on hover */
|
||||
@apply hover:z-10 relative;
|
||||
}
|
||||
@apply h-full;
|
||||
}
|
||||
|
||||
&.cm-singleline {
|
||||
.cm-editor {
|
||||
@apply w-full h-auto;
|
||||
}
|
||||
.cm-scroller {
|
||||
@apply font-mono text-[0.75rem];
|
||||
|
||||
.cm-scroller {
|
||||
@apply font-mono text-[0.8rem] overflow-hidden;
|
||||
}
|
||||
|
||||
.cm-line {
|
||||
@apply px-2 overflow-hidden;
|
||||
}
|
||||
}
|
||||
|
||||
&.cm-multiline {
|
||||
&.cm-full-height {
|
||||
@apply relative;
|
||||
|
||||
.cm-editor {
|
||||
@apply inset-0 absolute;
|
||||
position: absolute !important;
|
||||
}
|
||||
}
|
||||
|
||||
.cm-editor {
|
||||
@apply h-full;
|
||||
}
|
||||
|
||||
.cm-scroller {
|
||||
@apply font-mono text-[0.75rem];
|
||||
|
||||
/*
|
||||
/*
|
||||
* Round corners or they'll stick out of the editor bounds of editor is rounded.
|
||||
* Could potentially be pushed up from the editor like we do with bg color but this
|
||||
* is probably fine.
|
||||
*/
|
||||
@apply rounded-lg;
|
||||
}
|
||||
@apply rounded-lg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Obscure text for password fields */
|
||||
.cm-wrapper.cm-obscure-text .cm-line {
|
||||
-webkit-text-security: disc;
|
||||
-webkit-text-security: disc;
|
||||
}
|
||||
|
||||
.cm-editor .cm-gutterElement {
|
||||
@apply flex items-center;
|
||||
transition: color var(--transition-duration);
|
||||
@apply flex items-center;
|
||||
transition: color var(--transition-duration);
|
||||
}
|
||||
|
||||
.cm-editor .fold-gutter-icon {
|
||||
@apply pt-[0.25em] pl-[0.4em] px-[0.4em] h-4 cursor-pointer rounded;
|
||||
@apply pt-[0.25em] pl-[0.4em] px-[0.4em] h-4 cursor-pointer rounded;
|
||||
}
|
||||
|
||||
.cm-editor .fold-gutter-icon::after {
|
||||
@apply block w-1.5 h-1.5 border-transparent -rotate-45
|
||||
@apply block w-1.5 h-1.5 border-transparent -rotate-45
|
||||
border-l border-b border-l-[currentColor] border-b-[currentColor] content-[''];
|
||||
}
|
||||
|
||||
.cm-editor .fold-gutter-icon[data-open] {
|
||||
@apply pt-[0.38em] pl-[0.3em];
|
||||
@apply pt-[0.38em] pl-[0.3em];
|
||||
}
|
||||
|
||||
.cm-editor .fold-gutter-icon[data-open]::after {
|
||||
@apply rotate-[-135deg];
|
||||
@apply rotate-[-135deg];
|
||||
}
|
||||
|
||||
.cm-editor .fold-gutter-icon:hover {
|
||||
@apply text-gray-900 bg-gray-300/50;
|
||||
@apply text-gray-900 bg-gray-300/50;
|
||||
}
|
||||
|
||||
.cm-editor .cm-foldPlaceholder {
|
||||
@apply px-2 border border-gray-400/50 bg-gray-300/50 cursor-default;
|
||||
@apply hover:text-gray-800 hover:border-gray-400;
|
||||
@apply px-2 border border-gray-400/50 bg-gray-300/50 cursor-default;
|
||||
@apply hover:text-gray-800 hover:border-gray-400;
|
||||
}
|
||||
|
||||
.cm-editor .cm-activeLineGutter {
|
||||
@apply bg-transparent;
|
||||
@apply bg-transparent;
|
||||
}
|
||||
|
||||
.cm-wrapper:not(.cm-readonly) .cm-editor {
|
||||
&.cm-focused .cm-activeLineGutter {
|
||||
@apply text-gray-600;
|
||||
}
|
||||
&.cm-focused .cm-activeLineGutter {
|
||||
@apply text-gray-600;
|
||||
}
|
||||
|
||||
.cm-cursor {
|
||||
@apply border-l-2 border-gray-800;
|
||||
}
|
||||
.cm-cursor {
|
||||
@apply border-l-2 border-gray-800;
|
||||
}
|
||||
}
|
||||
|
||||
.cm-singleline .cm-editor {
|
||||
.cm-content {
|
||||
@apply h-full flex items-center;
|
||||
.cm-content {
|
||||
@apply h-full flex items-center;
|
||||
|
||||
/* Break characters on line wrapping mode, useful for URL field.
|
||||
* We can make this dynamic if we need it to be configurable later
|
||||
*/
|
||||
&.cm-lineWrapping {
|
||||
@apply break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: Extra selector required to override default styles */
|
||||
.cm-tooltip.cm-tooltip {
|
||||
@apply shadow-lg bg-gray-50 rounded text-gray-700 border border-gray-200 z-50 pointer-events-auto text-[0.75rem];
|
||||
@apply shadow-lg bg-gray-50 rounded text-gray-700 border border-gray-200 z-50 pointer-events-auto text-[0.75rem];
|
||||
|
||||
&.cm-completionInfo-right {
|
||||
@apply ml-1 -mt-0.5 text-sm;
|
||||
&.cm-completionInfo-right {
|
||||
@apply ml-1 -mt-0.5 text-sm;
|
||||
}
|
||||
|
||||
&.cm-completionInfo-right-narrow {
|
||||
@apply ml-1;
|
||||
}
|
||||
|
||||
* {
|
||||
@apply transition-none;
|
||||
}
|
||||
|
||||
&.cm-tooltip-autocomplete {
|
||||
& > ul {
|
||||
@apply p-1 max-h-[40vh];
|
||||
}
|
||||
|
||||
&.cm-completionInfo-right-narrow {
|
||||
@apply ml-1;
|
||||
& > ul > li {
|
||||
@apply cursor-default px-2 rounded-sm text-gray-600 h-7 flex items-center;
|
||||
}
|
||||
|
||||
* {
|
||||
@apply transition-none;
|
||||
& > ul > li[aria-selected] {
|
||||
@apply bg-highlight text-gray-900;
|
||||
}
|
||||
|
||||
&.cm-tooltip-autocomplete {
|
||||
& > ul {
|
||||
@apply p-1 max-h-[40vh];
|
||||
}
|
||||
|
||||
& > ul > li {
|
||||
@apply cursor-default px-2 rounded-sm text-gray-600 h-7 flex items-center;
|
||||
}
|
||||
|
||||
& > ul > li[aria-selected] {
|
||||
@apply bg-highlight text-gray-900;
|
||||
}
|
||||
|
||||
.cm-completionIcon {
|
||||
@apply text-sm flex items-center pb-0.5 flex-shrink-0;
|
||||
}
|
||||
|
||||
.cm-completionLabel {
|
||||
@apply text-gray-700;
|
||||
}
|
||||
|
||||
.cm-completionDetail {
|
||||
@apply ml-auto pl-6;
|
||||
}
|
||||
.cm-completionIcon {
|
||||
@apply text-sm flex items-center pb-0.5 flex-shrink-0;
|
||||
}
|
||||
|
||||
.cm-completionLabel {
|
||||
@apply text-gray-700;
|
||||
}
|
||||
|
||||
.cm-completionDetail {
|
||||
@apply ml-auto pl-6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add default icon. Needs low priority so it can be overwritten */
|
||||
.cm-completionIcon::after {
|
||||
content: '𝑥';
|
||||
content: '𝑥';
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ export interface EditorProps {
|
||||
onChange?: (value: string) => void;
|
||||
onFocus?: () => void;
|
||||
onBlur?: () => void;
|
||||
onSubmit?: () => void;
|
||||
onEnter?: () => void;
|
||||
singleLine?: boolean;
|
||||
wrapLines?: boolean;
|
||||
format?: (v: string) => string;
|
||||
@@ -58,7 +58,7 @@ const _Editor = forwardRef<EditorView | undefined, EditorProps>(function Editor(
|
||||
onChange,
|
||||
onFocus,
|
||||
onBlur,
|
||||
onSubmit,
|
||||
onEnter,
|
||||
className,
|
||||
singleLine,
|
||||
format,
|
||||
@@ -80,10 +80,10 @@ const _Editor = forwardRef<EditorView | undefined, EditorProps>(function Editor(
|
||||
}, [onChange]);
|
||||
|
||||
// Use ref so we can update the onChange handler without re-initializing the editor
|
||||
const handleSubmit = useRef<EditorProps['onSubmit']>(onSubmit);
|
||||
const handleEnter = useRef<EditorProps['onEnter']>(onEnter);
|
||||
useEffect(() => {
|
||||
handleSubmit.current = onSubmit;
|
||||
}, [onSubmit]);
|
||||
handleEnter.current = onEnter;
|
||||
}, [onEnter]);
|
||||
|
||||
// Use ref so we can update the onChange handler without re-initializing the editor
|
||||
const handleFocus = useRef<EditorProps['onFocus']>(onFocus);
|
||||
@@ -143,7 +143,12 @@ const _Editor = forwardRef<EditorView | undefined, EditorProps>(function Editor(
|
||||
let view: EditorView;
|
||||
try {
|
||||
const languageCompartment = new Compartment();
|
||||
const langExt = getLanguageExtension({ contentType, useTemplating, autocomplete, environment });
|
||||
const langExt = getLanguageExtension({
|
||||
contentType,
|
||||
useTemplating,
|
||||
autocomplete,
|
||||
environment,
|
||||
});
|
||||
|
||||
const state = EditorState.create({
|
||||
doc: `${defaultValue ?? ''}`,
|
||||
@@ -155,7 +160,7 @@ const _Editor = forwardRef<EditorView | undefined, EditorProps>(function Editor(
|
||||
container,
|
||||
readOnly,
|
||||
singleLine,
|
||||
onSubmit: handleSubmit,
|
||||
onEnter: handleEnter,
|
||||
onChange: handleChange,
|
||||
onFocus: handleFocus,
|
||||
onBlur: handleBlur,
|
||||
@@ -228,13 +233,13 @@ function getExtensions({
|
||||
onChange,
|
||||
onFocus,
|
||||
onBlur,
|
||||
onSubmit,
|
||||
onEnter,
|
||||
}: Pick<EditorProps, 'singleLine' | 'readOnly'> & {
|
||||
container: HTMLDivElement | null;
|
||||
onChange: MutableRefObject<EditorProps['onChange']>;
|
||||
onFocus: MutableRefObject<EditorProps['onFocus']>;
|
||||
onBlur: MutableRefObject<EditorProps['onBlur']>;
|
||||
onSubmit: MutableRefObject<EditorProps['onSubmit']>;
|
||||
onEnter: MutableRefObject<EditorProps['onEnter']>;
|
||||
}) {
|
||||
// TODO: Ensure tooltips render inside the dialog if we are in one.
|
||||
const parent =
|
||||
@@ -253,19 +258,19 @@ function getExtensions({
|
||||
: []),
|
||||
...(singleLine
|
||||
? [
|
||||
EditorView.domEventHandlers({
|
||||
focus: (_, view) => {
|
||||
// select all text on focus, like a regular input does
|
||||
view.dispatch({ selection: { anchor: 0, head: view.state.doc.length } });
|
||||
},
|
||||
keydown: (e) => {
|
||||
// Submit nearest form on enter if there is one
|
||||
if (onSubmit != null && e.key === 'Enter') {
|
||||
onSubmit.current?.();
|
||||
}
|
||||
},
|
||||
}),
|
||||
]
|
||||
EditorView.domEventHandlers({
|
||||
focus: (_, view) => {
|
||||
// select all text on focus, like a regular input does
|
||||
view.dispatch({ selection: { anchor: 0, head: view.state.doc.length } });
|
||||
},
|
||||
keydown: (e) => {
|
||||
// Submit nearest form on enter if there is one
|
||||
if (onEnter != null && e.key === 'Enter') {
|
||||
onEnter.current?.();
|
||||
}
|
||||
},
|
||||
}),
|
||||
]
|
||||
: []),
|
||||
|
||||
// Handle onFocus
|
||||
|
||||
@@ -21,7 +21,7 @@ export type InputProps = Omit<HTMLAttributes<HTMLInputElement>, 'onChange' | 'on
|
||||
defaultValue?: string;
|
||||
leftSlot?: ReactNode;
|
||||
rightSlot?: ReactNode;
|
||||
size?: 'sm' | 'md';
|
||||
size?: 'sm' | 'md' | 'auto';
|
||||
className?: string;
|
||||
placeholder?: string;
|
||||
autoFocus?: boolean;
|
||||
@@ -31,24 +31,24 @@ export type InputProps = Omit<HTMLAttributes<HTMLInputElement>, 'onChange' | 'on
|
||||
|
||||
export const Input = forwardRef<EditorView | undefined, InputProps>(function Input(
|
||||
{
|
||||
label,
|
||||
type = 'text',
|
||||
hideLabel,
|
||||
className,
|
||||
containerClassName,
|
||||
labelClassName,
|
||||
onChange,
|
||||
placeholder,
|
||||
size = 'md',
|
||||
name,
|
||||
leftSlot,
|
||||
rightSlot,
|
||||
defaultValue,
|
||||
validate,
|
||||
require,
|
||||
onFocus,
|
||||
onBlur,
|
||||
forceUpdateKey,
|
||||
hideLabel,
|
||||
label,
|
||||
labelClassName,
|
||||
leftSlot,
|
||||
name,
|
||||
onBlur,
|
||||
onChange,
|
||||
onFocus,
|
||||
placeholder,
|
||||
require,
|
||||
rightSlot,
|
||||
size = 'md',
|
||||
type = 'text',
|
||||
validate,
|
||||
...props
|
||||
}: InputProps,
|
||||
ref,
|
||||
@@ -70,10 +70,7 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
|
||||
const id = `input-${name}`;
|
||||
const inputClassName = classNames(
|
||||
className,
|
||||
'!bg-transparent min-w-0 h-full w-full focus:outline-none placeholder:text-placeholder',
|
||||
// Bump things over if the slots are occupied
|
||||
leftSlot && 'pl-0.5 -ml-2',
|
||||
rightSlot && 'pr-0.5 -mr-2',
|
||||
'!bg-transparent min-w-0 h-auto w-full focus:outline-none placeholder:text-placeholder',
|
||||
);
|
||||
|
||||
const isValid = useMemo(() => {
|
||||
@@ -92,7 +89,7 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
|
||||
|
||||
const wrapperRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const handleSubmit = useCallback(() => {
|
||||
const handleEnter = useCallback(() => {
|
||||
const form = wrapperRef.current?.closest('form');
|
||||
if (!isValid || form == null) return;
|
||||
|
||||
@@ -112,7 +109,7 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
|
||||
{label}
|
||||
</label>
|
||||
<HStack
|
||||
alignItems="center"
|
||||
alignItems="stretch"
|
||||
className={classNames(
|
||||
containerClassName,
|
||||
'relative w-full rounded-md text-gray-900',
|
||||
@@ -121,24 +118,31 @@ export const Input = forwardRef<EditorView | undefined, InputProps>(function Inp
|
||||
!isValid && '!border-invalid',
|
||||
size === 'md' && 'h-md leading-md',
|
||||
size === 'sm' && 'h-sm leading-sm',
|
||||
size === 'auto' && '!min-h-sm',
|
||||
)}
|
||||
>
|
||||
{leftSlot}
|
||||
<Editor
|
||||
ref={ref}
|
||||
id={id}
|
||||
singleLine
|
||||
onSubmit={handleSubmit}
|
||||
type={type === 'password' && !obscured ? 'text' : type}
|
||||
defaultValue={defaultValue}
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
placeholder={placeholder}
|
||||
onChange={handleChange}
|
||||
className={inputClassName}
|
||||
onFocus={handleFocus}
|
||||
onBlur={handleBlur}
|
||||
{...props}
|
||||
/>
|
||||
<HStack
|
||||
alignItems="center"
|
||||
className={classNames('w-full', leftSlot && 'pl-0.5 -ml-2', rightSlot && 'pr-0.5 -mr-2')}
|
||||
>
|
||||
<Editor
|
||||
ref={ref}
|
||||
id={id}
|
||||
singleLine
|
||||
wrapLines={size === 'auto'}
|
||||
onEnter={handleEnter}
|
||||
type={type === 'password' && !obscured ? 'text' : type}
|
||||
defaultValue={defaultValue}
|
||||
forceUpdateKey={forceUpdateKey}
|
||||
placeholder={placeholder}
|
||||
onChange={handleChange}
|
||||
className={inputClassName}
|
||||
onFocus={handleFocus}
|
||||
onBlur={handleBlur}
|
||||
{...props}
|
||||
/>
|
||||
</HStack>
|
||||
{type === 'password' && (
|
||||
<IconButton
|
||||
title={obscured ? `Show ${label}` : `Obscure ${label}`}
|
||||
|
||||
@@ -56,7 +56,7 @@ export const VStack = forwardRef(function VStack(
|
||||
type BaseStackProps = HTMLAttributes<HTMLElement> & {
|
||||
as?: ComponentType | 'ul' | 'form';
|
||||
space?: keyof typeof gapClasses;
|
||||
alignItems?: 'start' | 'center';
|
||||
alignItems?: 'start' | 'center' | 'stretch';
|
||||
justifyContent?: 'start' | 'center' | 'end' | 'between';
|
||||
};
|
||||
|
||||
@@ -74,6 +74,7 @@ const BaseStack = forwardRef(function BaseStack(
|
||||
'flex',
|
||||
alignItems === 'center' && 'items-center',
|
||||
alignItems === 'start' && 'items-start',
|
||||
alignItems === 'stretch' && 'items-stretch',
|
||||
justifyContent === 'start' && 'justify-start',
|
||||
justifyContent === 'center' && 'justify-center',
|
||||
justifyContent === 'end' && 'justify-end',
|
||||
|
||||
@@ -1,89 +1,89 @@
|
||||
const plugin = require('tailwindcss/plugin')
|
||||
const plugin = require('tailwindcss/plugin');
|
||||
|
||||
const height = {
|
||||
xs: '1.75rem',
|
||||
sm: '2.0rem',
|
||||
md: '2.5rem',
|
||||
};
|
||||
|
||||
/** @type {import("tailwindcss").Config} */
|
||||
module.exports = {
|
||||
darkMode: ["class", "[data-appearance=\"dark\"]"],
|
||||
content: [
|
||||
"./index.html",
|
||||
"./src-web/**/*.{html,js,jsx,ts,tsx}"
|
||||
],
|
||||
darkMode: ['class', '[data-appearance="dark"]'],
|
||||
content: ['./index.html', './src-web/**/*.{html,js,jsx,ts,tsx}'],
|
||||
theme: {
|
||||
extend: {
|
||||
opacity: {
|
||||
"disabled": "0.3"
|
||||
disabled: '0.3',
|
||||
},
|
||||
fontSize: {
|
||||
"xs": "0.8rem"
|
||||
},
|
||||
height: {
|
||||
"xs": "1.75rem",
|
||||
"sm": "2.0rem",
|
||||
"md": "2.5rem"
|
||||
xs: '0.8rem',
|
||||
},
|
||||
height,
|
||||
minHeight: height,
|
||||
lineHeight: {
|
||||
// HACK: Minus 2 to account for borders inside inputs
|
||||
"xs": "calc(1.75rem - 2px)",
|
||||
"sm": "calc(2.0rem - 2px)",
|
||||
"md": "calc(2.5rem - 2px)"
|
||||
xs: 'calc(1.75rem - 2px)',
|
||||
sm: 'calc(2.0rem - 2px)',
|
||||
md: 'calc(2.5rem - 2px)',
|
||||
},
|
||||
},
|
||||
fontFamily: {
|
||||
"mono": ["JetBrains Mono", "Menlo", "monospace"],
|
||||
"sans": [
|
||||
"Inter",
|
||||
"-apple-system",
|
||||
"BlinkMacSystemFont",
|
||||
"Segoe UI",
|
||||
"Roboto",
|
||||
"Oxygen-Sans",
|
||||
"Ubuntu",
|
||||
"Cantarell",
|
||||
"Helvetica Neue",
|
||||
"sans-serif",
|
||||
"Apple Color Emoji",
|
||||
"Segoe UI Emoji",
|
||||
"Segoe UI Symbol",
|
||||
mono: ['JetBrains Mono', 'Menlo', 'monospace'],
|
||||
sans: [
|
||||
'Inter',
|
||||
'-apple-system',
|
||||
'BlinkMacSystemFont',
|
||||
'Segoe UI',
|
||||
'Roboto',
|
||||
'Oxygen-Sans',
|
||||
'Ubuntu',
|
||||
'Cantarell',
|
||||
'Helvetica Neue',
|
||||
'sans-serif',
|
||||
'Apple Color Emoji',
|
||||
'Segoe UI Emoji',
|
||||
'Segoe UI Symbol',
|
||||
],
|
||||
},
|
||||
fontSize: {
|
||||
'3xs': "0.6rem",
|
||||
'2xs': "0.7rem",
|
||||
xs: "0.8rem",
|
||||
sm: "0.9rem",
|
||||
base: "1rem",
|
||||
xl: "1.25rem",
|
||||
"2xl": "1.563rem",
|
||||
"3xl": "1.953rem",
|
||||
"4xl": "2.441rem",
|
||||
"5xl": "3.052rem"
|
||||
'3xs': '0.6rem',
|
||||
'2xs': '0.7rem',
|
||||
xs: '0.8rem',
|
||||
sm: '0.9rem',
|
||||
base: '1rem',
|
||||
xl: '1.25rem',
|
||||
'2xl': '1.563rem',
|
||||
'3xl': '1.953rem',
|
||||
'4xl': '2.441rem',
|
||||
'5xl': '3.052rem',
|
||||
},
|
||||
colors: {
|
||||
selection: "hsl(var(--color-violet-500) / 0.4)",
|
||||
focus: "hsl(var(--color-blue-500) / 0.6)",
|
||||
invalid: "hsl(var(--color-red-500))",
|
||||
highlight: "hsl(var(--color-gray-300) / 0.35)",
|
||||
highlightSecondary: "hsl(var(--color-gray-300) / 0.2)",
|
||||
transparent: "transparent",
|
||||
white: "hsl(0 100% 100% / <alpha-value>)",
|
||||
black: "hsl(0 100% 0% / <alpha-value>)",
|
||||
placeholder: "hsl(var(--color-gray-400) / <alpha-value>)",
|
||||
red: color("red"),
|
||||
orange: color("orange"),
|
||||
yellow: color("yellow"),
|
||||
gray: color("gray"),
|
||||
blue: color("blue"),
|
||||
green: color("green"),
|
||||
pink: color("pink"),
|
||||
violet: color("violet")
|
||||
}
|
||||
selection: 'hsl(var(--color-violet-500) / 0.4)',
|
||||
focus: 'hsl(var(--color-blue-500) / 0.6)',
|
||||
invalid: 'hsl(var(--color-red-500))',
|
||||
highlight: 'hsl(var(--color-gray-300) / 0.35)',
|
||||
highlightSecondary: 'hsl(var(--color-gray-300) / 0.2)',
|
||||
transparent: 'transparent',
|
||||
white: 'hsl(0 100% 100% / <alpha-value>)',
|
||||
black: 'hsl(0 100% 0% / <alpha-value>)',
|
||||
placeholder: 'hsl(var(--color-gray-400) / <alpha-value>)',
|
||||
red: color('red'),
|
||||
orange: color('orange'),
|
||||
yellow: color('yellow'),
|
||||
gray: color('gray'),
|
||||
blue: color('blue'),
|
||||
green: color('green'),
|
||||
pink: color('pink'),
|
||||
violet: color('violet'),
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
require("@tailwindcss/container-queries"),
|
||||
plugin(function({ addVariant }) {
|
||||
addVariant('hocus', ['&:hover', '&:focus-visible', '&.focus:focus'])
|
||||
addVariant('focus-visible-or-class', ['&:focus-visible', '&.focus:focus'])
|
||||
})
|
||||
]
|
||||
require('@tailwindcss/container-queries'),
|
||||
plugin(function ({ addVariant }) {
|
||||
addVariant('hocus', ['&:hover', '&:focus-visible', '&.focus:focus']);
|
||||
addVariant('focus-visible-or-class', ['&:focus-visible', '&.focus:focus']);
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
function color(name) {
|
||||
@@ -100,6 +100,6 @@ function color(name) {
|
||||
800: `hsl(var(--color-${name}-800) / <alpha-value>)`,
|
||||
900: `hsl(var(--color-${name}-900) / <alpha-value>)`,
|
||||
950: `hsl(var(--color-${name}-950) / <alpha-value>)`,
|
||||
1000: `hsl(var(--color-${name}-1000) / <alpha-value>)`
|
||||
1000: `hsl(var(--color-${name}-1000) / <alpha-value>)`,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user