#505 - Theming for snippets view

This commit is contained in:
Elio Struyf
2023-02-07 13:49:05 +01:00
parent dd939f4b7a
commit 5354619283
19 changed files with 222 additions and 57 deletions
@@ -29,6 +29,8 @@ export const ChoiceButton: React.FunctionComponent<IChoiceButtonProps> = ({
<button
type="button"
className={`inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium ${
choices.length > 0 ? `rounded-l` : `rounded`
} ${
getColors(
`text-white dark:text-vulcan-500 bg-teal-600 hover:bg-teal-700 disabled:bg-gray-500`,
`text-[var(--vscode-button-foreground)] bg-[var(--vscode-button-background)] hover:bg-[var(--vscode-button-hoverBackground)] disabled:opacity-50`
@@ -43,7 +45,7 @@ export const ChoiceButton: React.FunctionComponent<IChoiceButtonProps> = ({
{choices.length > 0 && (
<Menu as="span" className="-ml-px relative block">
<Menu.Button
className={`h-full inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium focus:outline-none ${
className={`h-full inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium focus:outline-none rounded-r ${
getColors(
`text-white dark:text-vulcan-500 bg-teal-700 hover:bg-teal-800 disabled:bg-gray-500`,
`text-[var(--vscode-button-foreground)] bg-[var(--vscode-button-background)] hover:bg-[var(--vscode-button-hoverBackground)] disabled:opacity-50`
@@ -1,5 +1,6 @@
import * as React from 'react';
import { useRecoilValue } from 'recoil';
import useThemeColors from '../../hooks/useThemeColors';
import { DashboardViewType } from '../../models';
import { ViewSelector } from '../../state';
@@ -9,7 +10,8 @@ export const List: React.FunctionComponent<IListProps> = ({
children
}: React.PropsWithChildren<IListProps>) => {
const view = useRecoilValue(ViewSelector);
const { getColors } = useThemeColors();
let className = '';
if (view === DashboardViewType.Grid) {
className = `grid grid-cols-2 gap-x-4 gap-y-8 sm:grid-cols-3 sm:gap-x-6 lg:grid-cols-4 xl:gap-x-8`;
@@ -20,7 +22,9 @@ export const List: React.FunctionComponent<IListProps> = ({
return (
<ul role="list" className={className}>
{view === DashboardViewType.List && (
<li className="px-5 relative uppercase text-vulcan-100 dark:text-whisper-900 py-2 border-b border-vulcan-50">
<li className={`px-5 relative uppercase py-2 border-b ${
getColors('text-vulcan-100 dark:text-whisper-900 border-vulcan-50', 'text-[var(--vscode-editor-foreground)] border-[var(--vscode-panel-border)]')
}`}>
<div className={`grid grid-cols-12 gap-x-4 sm:gap-x-6 xl:gap-x-8`}>
<div className="col-span-8">Title</div>
<div className="col-span-2">Date</div>
@@ -12,6 +12,7 @@ import { GroupingSelector, PageAtom } from '../../state';
import { Item } from './Item';
import { List } from './List';
import usePagination from '../../hooks/usePagination';
import useThemeColors from '../../hooks/useThemeColors';
export interface IOverviewProps {
pages: Page[];
@@ -25,6 +26,7 @@ export const Overview: React.FunctionComponent<IOverviewProps> = ({
const grouping = useRecoilValue(GroupingSelector);
const page = useRecoilValue(PageAtom);
const { pageSetNr } = usePagination(settings?.dashboardState.contents.pagination);
const { getColors } = useThemeColors();
const pagedPages = useMemo(() => {
if (pageSetNr) {
@@ -50,7 +52,9 @@ export const Overview: React.FunctionComponent<IOverviewProps> = ({
<div className={`flex items-center justify-center h-full`}>
<div className={`max-w-xl text-center`}>
<FrontMatterIcon
className={`text-vulcan-300 dark:text-whisper-800 h-32 mx-auto opacity-90 mb-8`}
className={`h-32 mx-auto opacity-90 mb-8 ${
getColors('text-vulcan-300 dark:text-whisper-800', 'text-[var(--vscode-editor-foreground)]')
}`}
/>
{settings && settings?.contentFolders?.length > 0 ? (
<p className={`text-xl font-medium`}>No Markdown to show</p>
@@ -1,4 +1,4 @@
import { SearchIcon, XCircleIcon } from '@heroicons/react/outline';
import { SearchIcon, XCircleIcon } from '@heroicons/react/solid';
import * as React from 'react';
import useThemeColors from '../../hooks/useThemeColors';
@@ -35,10 +35,10 @@ export const FilterInput: React.FunctionComponent<IFilterInputProps> = ({
<input
type="text"
name="search"
className={`block w-full py-2 pl-10 pr-3 sm:text-sm focus:outline-none appearance-none disabled:opacity-50 ${
className={`block w-full py-2 pl-10 pr-3 sm:text-sm appearance-none disabled:opacity-50 rounded ${
getColors(
'bg-white dark:bg-vulcan-300 border border-gray-300 dark:border-vulcan-100 text-vulcan-500 dark:text-whisper-500 placeholder-gray-400 dark:placeholder-whisper-800',
'bg-[var(--vscode-input-background)] text-[var(--vscode-input-foreground)] border-[var(--vscode-editorWidget-border)] placeholder-[var(--vscode-input-placeholderForeground)]'
'bg-white dark:bg-vulcan-300 border border-gray-300 dark:border-vulcan-100 text-vulcan-500 dark:text-whisper-500 placeholder-gray-400 dark:placeholder-whisper-800 focus:outline-none',
'bg-[var(--vscode-input-background)] text-[var(--vscode-input-foreground)] border-[var(--vscode-editorWidget-border)] placeholder-[var(--vscode-input-placeholderForeground)] focus:outline-[var(--vscode-focusBorder)] focus:outline-1 focus:outline-offset-0 focus:shadow-none focus:border-transparent'
)
}`}
placeholder={placeholder || 'Search'}
@@ -52,7 +52,7 @@ export const Searchbox: React.FunctionComponent<ISearchboxProps> = ({
<input
type="text"
name="search"
className={`block w-full py-2 pl-10 pr-3 sm:text-sm appearance-none disabled:opacity-50 ${
className={`block w-full py-2 pl-10 pr-3 sm:text-sm appearance-none disabled:opacity-50 rounded ${
getColors(
'bg-white dark:bg-vulcan-300 border border-gray-300 dark:border-vulcan-100 text-vulcan-500 dark:text-whisper-500 placeholder-gray-400 dark:placeholder-whisper-800 focus:outline-none',
'bg-[var(--vscode-input-background)] text-[var(--vscode-input-foreground)] border-[var(--vscode-editorWidget-border)] placeholder-[var(--vscode-input-placeholderForeground)] focus:outline-[var(--vscode-focusBorder)] focus:outline-1 focus:outline-offset-0 focus:shadow-none focus:border-transparent'
@@ -47,7 +47,7 @@ export const SyncButton: React.FunctionComponent<ISyncButtonProps> = (
<div className="git_actions">
<button
type="button"
className={`inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium focus:outline-none ${
className={`inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium focus:outline-none rounded ${
getColors(
`text-white dark:text-vulcan-500 bg-teal-600 hover:bg-teal-700 disabled:bg-gray-500`,
`text-[var(--vscode-button-foreground)] bg-[var(--vscode-button-background)] hover:bg-[var(--vscode-button-hoverBackground)] disabled:opacity-50`
@@ -115,7 +115,7 @@ export const FolderCreation: React.FunctionComponent<IFolderCreationProps> = (
<div className="flex flex-1 justify-end">
{renderPostAssetsButton}
<button
className={`inline-flex items-center px-3 py-1 border border-transparent text-xs leading-4 font-medium focus:outline-none ${
className={`inline-flex items-center px-3 py-1 border border-transparent text-xs leading-4 font-medium focus:outline-none rounded ${
getColors(
`text-white dark:text-vulcan-500 bg-teal-600 hover:bg-teal-700 disabled:bg-gray-500`,
`text-[var(--vscode-button-foreground)] bg-[var(--vscode-button-background)] hover:bg-[var(--vscode-button-hoverBackground)] disabled:opacity-50`
@@ -23,7 +23,12 @@ export const Lightbox: React.FunctionComponent<ILightboxProps> = (
return (
<div
onClick={hideLightbox}
className={`fixed top-0 left-0 right-0 bottom-0 w-full h-full flex flex-wrap items-center justify-center bg-black bg-opacity-50 z-50`}
className={`fixed top-0 left-0 right-0 bottom-0 w-full h-full flex flex-wrap items-center justify-center z-50 ${
getColors(
`bg-black bg-opacity-50`,
`bg-[var(--vscode-editor-background)] opacity-75`
)
}`}
>
<div className={`w-full h-full flex flex-wrap items-center justify-center`}>
<img
@@ -177,7 +177,7 @@ export const Media: React.FunctionComponent<IMediaProps> = (
<div className={`absolute top-0 left-0 w-full h-full flex flex-col justify-center items-center z-50 ${
getColors(
'text-whisper-500 bg-gray-900 bg-opacity-70',
'text-[var(--vscode-foreground)] bg-black bg-opacity-70'
'text-[var(--vscode-foreground)] bg-[var(--vscode-editor-background)] opacity-75'
)
}`}>
<UploadIcon className={`h-32`} />
@@ -1,4 +1,5 @@
import * as React from 'react';
import useThemeColors from '../../hooks/useThemeColors';
export interface IQuickActionProps {
title: string;
@@ -10,12 +11,19 @@ export const QuickAction: React.FunctionComponent<IQuickActionProps> = ({
onClick,
children
}: React.PropsWithChildren<IQuickActionProps>) => {
const { getColors } = useThemeColors();
return (
<button
type="button"
title={title}
onClick={onClick}
className={`px-2 group inline-flex justify-center text-sm font-medium text-vulcan-400 hover:text-vulcan-600 dark:text-gray-400 dark:hover:text-whisper-600`}
className={`px-2 group inline-flex justify-center text-sm font-medium ${
getColors(
'text-vulcan-400 hover:text-vulcan-600 dark:text-gray-400 dark:hover:text-whisper-600',
'text-[var(--vscode-foreground)] hover:text-[var(--vscode-list-activeSelectionForeground)]'
)
}`}
>
{children}
<span className="sr-only">{title}</span>
@@ -42,7 +42,12 @@ export const Alert: React.FunctionComponent<IAlertProps> = ({
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Dialog.Overlay className={`fixed inset-0 bg-black bg-opacity-75 transition-opacity`} />
<Dialog.Overlay className={`fixed inset-0 transition-opacity ${
getColors(
`bg-vulcan-500 bg-opacity-75`,
`bg-[var(--vscode-editor-background)] opacity-75`
)
}`} />
</Transition.Child>
{/* This element is to trick the browser into centering the modal contents. */}
@@ -1,6 +1,7 @@
import { Dialog, Transition } from '@headlessui/react';
import * as React from 'react';
import { Fragment, useRef } from 'react';
import useThemeColors from '../../hooks/useThemeColors';
export interface IFormDialogProps {
title: string;
@@ -24,6 +25,7 @@ export const FormDialog: React.FunctionComponent<IFormDialogProps> = ({
children
}: React.PropsWithChildren<IFormDialogProps>) => {
const cancelButtonRef = useRef(null);
const { getColors } = useThemeColors();
return (
<Transition.Root show={true} as={Fragment}>
@@ -42,7 +44,12 @@ export const FormDialog: React.FunctionComponent<IFormDialogProps> = ({
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Dialog.Overlay className="fixed inset-0 bg-vulcan-500 bg-opacity-75 transition-opacity" />
<Dialog.Overlay className={`fixed inset-0 transition-opacity ${
getColors(
`bg-vulcan-500 bg-opacity-75`,
`bg-[var(--vscode-editor-background)] opacity-75`
)
}`} />
</Transition.Child>
{/* This element is to trick the browser into centering the modal contents. */}
@@ -59,11 +66,18 @@ export const FormDialog: React.FunctionComponent<IFormDialogProps> = ({
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<div className="inline-block align-bottom bg-white dark:bg-vulcan-500 rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6 border-2 border-whisper-900">
<div className={`inline-block align-bottom rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6 border-2 ${
getColors(
'bg-white dark:bg-vulcan-500 border-whisper-900',
'bg-[var(--vscode-sideBar-background)] border-[var(--vscode-panel-border)]'
)
}`}>
<div>
<Dialog.Title
as="h3"
className="text-lg leading-6 font-medium text-vulcan-300 dark:text-whisper-900"
className={`text-lg leading-6 font-medium ${
getColors(`text-vulcan-300 dark:text-whisper-900`, `text-[var(--vscode-editor-foreground)]`)
}`}
>
{title}
</Dialog.Title>
@@ -77,15 +91,26 @@ export const FormDialog: React.FunctionComponent<IFormDialogProps> = ({
<div className="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
<button
type="button"
className="w-full inline-flex justify-center border border-transparent shadow-sm px-4 py-2 bg-teal-600 text-base font-medium text-white hover:bg-teal-700 dark:hover:bg-teal-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-teal-500 sm:ml-3 sm:w-auto sm:text-sm disabled:opacity-30"
className={`w-full inline-flex justify-center rounded shadow-sm px-4 py-2 text-base font-medium focus:outline-none sm:mt-0 sm:w-auto sm:text-sm sm:ml-3 ${
getColors(
'bg-teal-600 focus:ring-teal-500 text-white hover:bg-teal-700 dark:hover:bg-teal-900 ',
'bg-[var(--vscode-button-background)] text-[var(--vscode-button-foreground)] hover:bg-[var(--vscode-button-hoverBackground)]'
)
}`}
onClick={() => trigger()}
disabled={isSaveDisabled}
>
{okBtnText}
</button>
<button
type="button"
className="mt-3 w-full inline-flex justify-center border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 dark:hover:bg-gray-200 focus:outline-none sm:mt-0 sm:w-auto sm:text-sm"
className={`mt-3 w-full inline-flex justify-center rounded shadow-sm px-4 py-2 text-base font-medium focus:outline-none sm:mt-0 sm:w-auto sm:text-sm ${
getColors(
'bg-white border-gray-300 text-gray-700 hover:bg-gray-50 dark:hover:bg-gray-200',
'bg-[var(--vscode-button-secondaryBackground)] text-[var(--vscode-button-secondaryForeground)] hover:bg-[var(--vscode-button-secondaryHoverBackground)]'
)
}`}
onClick={() => dismiss()}
ref={cancelButtonRef}
>
@@ -17,6 +17,7 @@ import { FEATURE_FLAG } from '../../../constants';
import { SnippetParser } from '../../../helpers/SnippetParser';
import { Snippet, Snippets } from '../../../models';
import { DashboardMessage } from '../../DashboardMessage';
import useThemeColors from '../../hooks/useThemeColors';
import { ModeAtom, SettingsSelector, ViewDataSelector } from '../../state';
import { QuickAction } from '../Menu';
import { Alert } from '../Modals/Alert';
@@ -39,6 +40,7 @@ export const Item: React.FunctionComponent<IItemProps> = ({
const [showInsertDialog, setShowInsertDialog] = useState(false);
const [showEditDialog, setShowEditDialog] = useState(false);
const [showAlert, setShowAlert] = React.useState(false);
const { getColors } = useThemeColors();
const [snippetTitle, setSnippetTitle] = useState<string>('');
const [snippetDescription, setSnippetDescription] = useState<string>('');
@@ -143,9 +145,19 @@ export const Item: React.FunctionComponent<IItemProps> = ({
return (
<>
<li className="group relative overflow-hidden bg-gray-50 dark:bg-vulcan-200 shadow-md hover:shadow-xl dark:shadow-none dark:hover:bg-vulcan-100 border border-gray-200 dark:border-vulcan-50 p-4 space-y-2">
<li className={`group relative overflow-hidden shadow-md hover:shadow-xl dark:shadow-none border p-4 space-y-2 ${
getColors(
'bg-gray-50 dark:bg-vulcan-200 dark:hover:bg-vulcan-100 border-gray-200 dark:border-vulcan-50',
'bg-[var(--vscode-sideBar-background)] hover:bg-[var(--vscode-list-hoverBackground)] border-[var(--vscode-panel-border)]'
)
}`}>
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<CodeIcon className="w-64 h-64 opacity-5 text-vulcan-200 dark:text-gray-400" />
<CodeIcon className={`w-64 h-64 opacity-5 ${
getColors(
'text-vulcan-200 dark:text-gray-400',
'text-[var(--vscode-foreground)]'
)
}`} />
</div>
<h2
@@ -167,7 +179,12 @@ export const Item: React.FunctionComponent<IItemProps> = ({
alternative={
insertToContent ? (
<div className={`absolute top-4 right-4 flex flex-col space-y-4`}>
<div className="flex items-center border border-transparent group-hover:bg-gray-200 dark:group-hover:bg-vulcan-200 group-hover:border-gray-100 dark:group-hover:border-vulcan-50 rounded-full p-2 -mr-2 -mt-2">
<div className={`flex items-center border border-transparent rounded-full p-2 -mr-2 -mt-2 ${
getColors(
'group-hover:bg-gray-200 dark:group-hover:bg-vulcan-200 group-hover:border-gray-100 dark:group-hover:border-vulcan-50',
'group-hover:bg-[var(--vscode-sideBar-background)] group-hover:border-[var(--vscode-panel-border)]'
)
}`}>
<div className="group-hover:hidden">
<DotsHorizontalIcon className="w-4 h-4" />
</div>
@@ -183,7 +200,12 @@ export const Item: React.FunctionComponent<IItemProps> = ({
}
>
<div className={`absolute top-4 right-4 flex flex-col space-y-4`}>
<div className="flex items-center border border-transparent group-hover:bg-gray-200 dark:group-hover:bg-vulcan-200 group-hover:border-gray-100 dark:group-hover:border-vulcan-50 rounded-full p-2 -mr-2 -mt-2">
<div className={`flex items-center border border-transparent rounded-full p-2 -mr-2 -mt-2 ${
getColors(
'group-hover:bg-gray-200 dark:group-hover:bg-vulcan-200 group-hover:border-gray-100 dark:group-hover:border-vulcan-50',
'group-hover:bg-[var(--vscode-sideBar-background)] group-hover:border-[var(--vscode-panel-border)]'
)
}`}>
<div className="group-hover:hidden">
<DotsHorizontalIcon className="w-4 h-4" />
</div>
@@ -217,7 +239,12 @@ export const Item: React.FunctionComponent<IItemProps> = ({
</div>
</FeatureFlag>
<p className="text-xs text-vulcan-200 dark:text-whisper-800">{snippet.description}</p>
<p className={`text-xs ${
getColors(
'text-vulcan-200 dark:text-whisper-800',
'text-[var(--vscode-foreground)]'
)
}`}>{snippet.description}</p>
</li>
{showInsertDialog && (
@@ -1,6 +1,8 @@
import { Messenger } from '@estruyf/vscode/dist/client';
import * as React from 'react';
import { GeneralCommands } from '../../../constants';
import useThemeColors from '../../hooks/useThemeColors';
import { SnippetInput } from './SnippetInput';
export interface INewFormProps {
title: string;
@@ -24,6 +26,8 @@ export const NewForm: React.FunctionComponent<INewFormProps> = ({
onDescriptionUpdate,
onBodyUpdate
}: React.PropsWithChildren<INewFormProps>) => {
const { getColors } = useThemeColors();
const openLink = () => {
Messenger.send(
GeneralCommands.toVSCode.openLink,
@@ -36,19 +40,17 @@ export const NewForm: React.FunctionComponent<INewFormProps> = ({
<div>
<label htmlFor={`title`} className="block text-sm font-medium capitalize">
Title{' '}
<span className="text-red-400" title="Required field">
<span className={getColors(`text-red-400`, `text-[var(--vscode-notificationsErrorIcon-foreground)]`)} title="Required field">
*
</span>
</label>
<div className="mt-1">
<input
type="text"
name={`title`}
value={title || ''}
placeholder={`Snippet title`}
className="focus:outline-none block w-full sm:text-sm border-gray-300 text-vulcan-500"
<SnippetInput
name='title'
value={title}
placeholder='Snippet title'
onChange={(e) => onTitleUpdate(e.currentTarget.value)}
/>
/>
</div>
</div>
@@ -57,14 +59,12 @@ export const NewForm: React.FunctionComponent<INewFormProps> = ({
Description
</label>
<div className="mt-1">
<input
type="text"
name={`description`}
value={description || ''}
placeholder={`Snippet description`}
className="focus:outline-none block w-full sm:text-sm border-gray-300 text-vulcan-500"
<SnippetInput
name='description'
value={description}
placeholder='Snippet description'
onChange={(e) => onDescriptionUpdate(e.currentTarget.value)}
/>
/>
</div>
</div>
@@ -76,13 +76,13 @@ export const NewForm: React.FunctionComponent<INewFormProps> = ({
</span>
</label>
<div className="mt-1">
<textarea
name={`snippet`}
value={body || ''}
placeholder={`Snippet content`}
className="focus:outline-none block w-full sm:text-sm border-gray-300 text-vulcan-500"
<SnippetInput
name='snippet'
value={body}
placeholder='Snippet content'
onChange={(e) => onBodyUpdate(e.currentTarget.value)}
/>
isTextArea
/>
</div>
</div>
@@ -99,23 +99,30 @@ export const NewForm: React.FunctionComponent<INewFormProps> = ({
type="checkbox"
checked={isMediaSnippet}
onChange={(e) => onMediaSnippetUpdate(e.currentTarget.checked)}
className="focus:ring-teal-500 h-4 w-4 text-teal-600 border-gray-300 rounded"
className={`h-4 w-4 rounded ${
getColors(
`focus:ring-teal-500 text-teal-600 border-gray-300 dark:border-vulcan-50`,
`focus:ring-[var(--vscode-button-background)] text-[var(--vscode-button-background)] border-[var(--vscode-editorWidget-border)]`
)
}`}
/>
</div>
<div className="ml-3 text-sm">
<label
htmlFor="isMediaSnippet"
className="font-medium text-vulcan-100 dark:text-whisper-900"
className={`font-medium ${
getColors(`text-vulcan-100 dark:text-whisper-900`, `text-[var(--vscode-editor-foreground)]`)
}`}
>
Media snippet
</label>
<p id="isMediaSnippet-description" className="text-vulcan-300 dark:text-whisper-500">
<p id="isMediaSnippet-description" className={getColors('text-vulcan-300 dark:text-whisper-500', `text-[var(--vscode-foreground)]`)}>
Use the current snippet for inserting media files into your content.
</p>
<p>
Check our{' '}
<button
className="text-teal-700 hover:text-teal-500"
className={getColors('text-teal-700 hover:text-teal-500', 'text-[var(--vscode-textLink-foreground)] hover:text-[var(--vscode-textLink-activeForeground)]')}
onClick={openLink}
title="media snippet placeholders"
>
@@ -6,6 +6,7 @@ import { processKnownPlaceholders } from '../../../helpers/PlaceholderHelper';
import { SnippetParser } from '../../../helpers/SnippetParser';
import { Snippet, SnippetField, SnippetSpecialPlaceholders } from '../../../models';
import { DashboardMessage } from '../../DashboardMessage';
import useThemeColors from '../../hooks/useThemeColors';
import { SettingsAtom, ViewDataSelector } from '../../state';
import { SnippetInputField } from './SnippetInputField';
@@ -27,6 +28,7 @@ const SnippetForm: React.ForwardRefRenderFunction<SnippetFormHandle, ISnippetFor
const viewData = useRecoilValue(ViewDataSelector);
const [fields, setFields] = useState<SnippetField[]>([]);
const settings = useRecoilValue(SettingsAtom);
const { getColors } = useThemeColors();
const onTextChange = useCallback(
(field: SnippetField, value: string) => {
@@ -146,7 +148,12 @@ const SnippetForm: React.ForwardRefRenderFunction<SnippetFormHandle, ISnippetFor
return (
<div>
<pre className="border border-opacity-40 p-2 whitespace-pre-wrap break-words max-h-64 overflow-auto">
<pre className={`border p-2 whitespace-pre-wrap break-words max-h-64 overflow-auto rounded ${
getColors(
'border-opacity-40',
'border-[var(--vscode-panel-border)] bg-[var(--vscode-editor-background)] text-[var(--vscode-editor-foreground)]',
)
}`}>
{snippetBody}
</pre>
@@ -0,0 +1,48 @@
import * as React from 'react';
import useThemeColors from '../../hooks/useThemeColors';
export interface ISnippetInputProps {
name: string;
value?: string;
placeholder?: string;
onChange?: (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
isTextArea?: boolean;
}
export const SnippetInput: React.FunctionComponent<ISnippetInputProps> = ({ name, value, placeholder, isTextArea, onChange }: React.PropsWithChildren<ISnippetInputProps>) => {
const { getColors } = useThemeColors();
if (isTextArea) {
return (
<textarea
name={name}
value={value || ''}
placeholder={placeholder}
rows={5}
className={`block w-full sm:text-sm ${
getColors(
'focus:outline-none border-gray-300 text-vulcan-500',
'border-transparent bg-[var(--vscode-input-background)] text-[var(--vscode-input-foreground)] placeholder-[var(--vscode-input-placeholderForeground)] focus:outline-[var(--vscode-focusBorder)] focus:outline-1 focus:outline-offset-0 focus:shadow-none focus:border-transparent'
)
}`}
onChange={onChange}
/>
)
}
return (
<input
type="text"
name={name}
value={value || ''}
placeholder={placeholder}
className={`block w-full sm:text-sm ${
getColors(
'focus:outline-none border-gray-300 text-vulcan-500',
'border-transparent bg-[var(--vscode-input-background)] text-[var(--vscode-input-foreground)] placeholder-[var(--vscode-input-placeholderForeground)] focus:outline-[var(--vscode-focusBorder)] focus:outline-1 focus:outline-offset-0 focus:shadow-none focus:border-transparent'
)
}`}
onChange={onChange}
/>
);
};
@@ -1,6 +1,7 @@
import * as React from 'react';
import { ChevronDownIcon } from '@heroicons/react/outline';
import { Choice, SnippetField } from '../../../models';
import useThemeColors from '../../hooks/useThemeColors';
export interface ISnippetInputFieldProps {
field: SnippetField;
@@ -11,13 +12,20 @@ export const SnippetInputField: React.FunctionComponent<ISnippetInputFieldProps>
field,
onValueChange
}: React.PropsWithChildren<ISnippetInputFieldProps>) => {
const { getColors } = useThemeColors();
if (field.type === 'choice') {
return (
<div className="relative">
<select
name={field.name}
value={field.value || ''}
className="focus:outline-none block w-full sm:text-sm border-gray-300 text-vulcan-500"
className={`block w-full sm:text-sm ${
getColors(
'focus:outline-none border-gray-300 text-vulcan-500',
'border-transparent bg-[var(--vscode-input-background)] text-[var(--vscode-input-foreground)] placeholder-[var(--vscode-input-placeholderForeground)] focus:outline-[var(--vscode-focusBorder)] focus:outline-1 focus:outline-offset-0 focus:shadow-none focus:border-transparent'
)
}`}
onChange={(e) => onValueChange(field, e.target.value)}
>
{(field.choices || [])?.map((option: string | Choice, index: number) =>
@@ -43,7 +51,12 @@ export const SnippetInputField: React.FunctionComponent<ISnippetInputFieldProps>
<textarea
name={field.name}
value={field.value || ''}
className="focus:outline-none block w-full sm:text-sm border-gray-300 text-vulcan-500 h-auto"
className={`block w-full sm:text-sm h-auto ${
getColors(
'focus:outline-none border-gray-300 text-vulcan-500',
'border-transparent bg-[var(--vscode-input-background)] text-[var(--vscode-input-foreground)] placeholder-[var(--vscode-input-placeholderForeground)] focus:outline-[var(--vscode-focusBorder)] focus:outline-1 focus:outline-offset-0 focus:shadow-none focus:border-transparent'
)
}`}
onChange={(e) => onValueChange(field, e.currentTarget.value)}
rows={4}
/>
@@ -55,7 +68,12 @@ export const SnippetInputField: React.FunctionComponent<ISnippetInputFieldProps>
type="text"
name={field.name}
value={field.value || ''}
className="focus:outline-none block w-full sm:text-sm border-gray-300 text-vulcan-500"
className={`block w-full sm:text-sm ${
getColors(
'focus:outline-none border-gray-300 text-vulcan-500',
'border-transparent bg-[var(--vscode-input-background)] text-[var(--vscode-input-foreground)] placeholder-[var(--vscode-input-placeholderForeground)] focus:outline-[var(--vscode-focusBorder)] focus:outline-1 focus:outline-offset-0 focus:shadow-none focus:border-transparent'
)
}`}
onChange={(e) => onValueChange(field, e.currentTarget.value)}
/>
);
@@ -84,7 +84,7 @@ export const Snippets: React.FunctionComponent<ISnippetsProps> = (
<FeatureFlag features={mode?.features || []} flag={FEATURE_FLAG.dashboard.snippets.manage}>
<div
className={`py-3 px-4 flex items-center justify-between border-b ${
getColors(`border-gray-300 dark:border-vulcan-100`, `border-[var(--vscode-sideBar-border)]`)
getColors(`border-gray-300 dark:border-vulcan-100`, `border-[var(--vscode-panel-border)]`)
}`}
aria-label="snippets header"
>
@@ -99,7 +99,7 @@ export const Snippets: React.FunctionComponent<ISnippetsProps> = (
<div className="flex flex-1 justify-end">
<button
className={`inline-flex items-center px-3 py-1 border border-transparent text-xs leading-4 font-medium focus:outline-none ${
className={`inline-flex items-center px-3 py-1 rounded text-xs leading-4 font-medium focus:outline-none ${
getColors(
`text-white dark:text-vulcan-500 bg-teal-600 hover:bg-teal-700 disabled:bg-gray-500`,
`text-[var(--vscode-button-foreground)] bg-[var(--vscode-button-background)] hover:bg-[var(--vscode-button-hoverBackground)] disabled:opacity-50`
+6 -1
View File
@@ -10,7 +10,12 @@ export const Spinner: React.FunctionComponent<ISpinnerProps> = (
return (
<div
className={`fixed top-0 left-0 right-0 bottom-0 w-full h-full flex flex-wrap items-center justify-center bg-black bg-opacity-50 z-50`}
className={`fixed top-0 left-0 right-0 bottom-0 w-full h-full flex flex-wrap items-center justify-center z-50 ${
getColors(
`bg-black bg-opacity-50`,
`bg-[var(--vscode-editor-background)] opacity-75`
)
}`}
>
<div className={`loader ease-linear rounded-full border-8 border-t-8 h-16 w-16 ${
getColors(`border-gray-50 border-t-teal-500`, `border-[var(--vscode-activityBar-inactiveForeground)] border-t-[var(--vscode-activityBarBadge-background)]`)