mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-07-06 01:41:48 +02:00
#505 - Data view theming
This commit is contained in:
@@ -27,7 +27,7 @@ export const Button: React.FunctionComponent<IButtonProps> = ({
|
||||
)
|
||||
} ${secondary ?
|
||||
getColors(`bg-red-300 hover:bg-red-400`, `bg-[var(--vscode-button-secondaryBackground)] text-[--vscode-button-secondaryForeground] hover:bg-[var(--vscode-button-secondaryHoverBackground)]`) :
|
||||
getColors(`bg-teal-600 hover:bg-teal-700`, `bg-[var(--frontmatter-button-background)] text-[--vscode-button-foreground] hover:bg-[var(--frontmatter-button-hoverBackground)]`)
|
||||
getColors(`bg-teal-600 hover:bg-teal-700`, `bg-[var(--frontmatter-button-background)] text-[var(--vscode-button-foreground)] hover:bg-[var(--frontmatter-button-hoverBackground)]`)
|
||||
}
|
||||
`}
|
||||
onClick={onClick}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { AutoFields, AutoForm, ErrorsField } from '../../../components/uniforms-
|
||||
// import { AutoFields, AutoForm, ErrorsField } from 'uniforms-antd';
|
||||
import { ErrorBoundary } from '@sentry/react';
|
||||
import { DataFormControls } from './DataFormControls';
|
||||
import useThemeColors from '../../hooks/useThemeColors';
|
||||
|
||||
export interface IDataFormProps {
|
||||
schema: any;
|
||||
@@ -21,6 +22,7 @@ export const DataForm: React.FunctionComponent<IDataFormProps> = ({
|
||||
onClear
|
||||
}: React.PropsWithChildren<IDataFormProps>) => {
|
||||
const [bridge, setBridge] = useState<JSONSchemaBridge | null>(null);
|
||||
const { getColors } = useThemeColors();
|
||||
|
||||
const ajv = new Ajv({ allErrors: true, useDefaults: true });
|
||||
|
||||
@@ -47,9 +49,9 @@ export const DataForm: React.FunctionComponent<IDataFormProps> = ({
|
||||
<ErrorBoundary>
|
||||
<div className="autoform">
|
||||
{model ? (
|
||||
<h2 className="text-gray-500 dark:text-whisper-900">Modify the data</h2>
|
||||
<h2 className={getColors(`text-gray-500 dark:text-whisper-900`, `text-[var(--frontmatter-secondary-text)]`)}>Modify the data</h2>
|
||||
) : (
|
||||
<h2 className="text-gray-500 dark:text-whisper-900">Add new data</h2>
|
||||
<h2 className={getColors(`text-gray-500 dark:text-whisper-900`, `text-[var(--frontmatter-secondary-text)]`)}>Add new data</h2>
|
||||
)}
|
||||
|
||||
<AutoForm
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { useForm } from 'uniforms';
|
||||
import { SubmitField } from 'uniforms-unstyled';
|
||||
import useThemeColors from '../../hooks/useThemeColors';
|
||||
import { Button } from '../Common/Button';
|
||||
|
||||
export interface IDataFormControlsProps {
|
||||
@@ -13,9 +14,10 @@ export const DataFormControls: React.FunctionComponent<IDataFormControlsProps> =
|
||||
onClear
|
||||
}: React.PropsWithChildren<IDataFormControlsProps>) => {
|
||||
const { formRef } = useForm();
|
||||
const { getColors } = useThemeColors();
|
||||
|
||||
return (
|
||||
<div className="text-right border-t border-gray-200 dark:border-vulcan-300">
|
||||
<div className={`text-right border-t ${getColors(`border-gray-200 dark:border-vulcan-300`, `border-[var(--frontmatter-border)]`)}`}>
|
||||
<SubmitField value={model ? `Update` : `Add`} />
|
||||
|
||||
<Button
|
||||
|
||||
@@ -21,6 +21,7 @@ import 'react-toastify/dist/ReactToastify.css';
|
||||
import { DataType } from '../../../models/DataType';
|
||||
import { TelemetryEvent } from '../../../constants';
|
||||
import { NavigationItem } from '../Layout';
|
||||
import useThemeColors from '../../hooks/useThemeColors';
|
||||
|
||||
export interface IDataViewProps { }
|
||||
|
||||
@@ -31,6 +32,7 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
|
||||
const [selectedIndex, setSelectedIndex] = useState<number | null>(null);
|
||||
const [dataEntries, setDataEntries] = useState<any | any[] | null>(null);
|
||||
const settings = useRecoilValue(SettingsSelector);
|
||||
const { getColors } = useThemeColors();
|
||||
|
||||
const setSchema = (dataFile: DataFile) => {
|
||||
setSelectedData(dataFile);
|
||||
@@ -173,15 +175,27 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
|
||||
<div className="relative w-full flex-grow mx-auto overflow-hidden">
|
||||
<div className={`flex w-64 flex-col absolute inset-y-0`}>
|
||||
<aside
|
||||
className={`flex flex-col flex-grow overflow-y-auto border-r border-gray-200 dark:border-vulcan-300 py-6 px-4 overflow-auto`}
|
||||
className={`flex flex-col flex-grow overflow-y-auto border-r py-6 px-4 overflow-auto ${getColors(
|
||||
'border-gray-200 dark:border-vulcan-300',
|
||||
'border-[var(--frontmatter-border)]'
|
||||
)
|
||||
}`}
|
||||
>
|
||||
<h2 className={`text-lg text-gray-500 dark:text-whisper-900`}>
|
||||
<h2 className={`text-lg ${getColors(
|
||||
`text-gray-500 dark:text-whisper-900`,
|
||||
`text-[var(--frontmatter-text)]`
|
||||
)
|
||||
}`}>
|
||||
Select your data type
|
||||
</h2>
|
||||
|
||||
<nav className={`flex-1 py-4 -mx-4 `}>
|
||||
<nav className={`flex-1 py-4 -mx-4`}>
|
||||
<div
|
||||
className={`divide-y divide-gray-200 dark:divide-vulcan-300 border-t border-b border-gray-200 dark:border-vulcan-300`}
|
||||
className={`divide-y border-t border-b ${getColors(
|
||||
`divide-gray-200 dark:divide-vulcan-300 border-gray-200 dark:border-vulcan-300`,
|
||||
`divide-[var(--frontmatter-border)] border-[var(--frontmatter-border)]`
|
||||
)
|
||||
}`}
|
||||
>
|
||||
{dataFiles &&
|
||||
dataFiles.length > 0 &&
|
||||
@@ -205,9 +219,17 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
|
||||
<>
|
||||
{!selectedData.singleEntry && (
|
||||
<div
|
||||
className={`w-1/3 py-6 px-4 flex-1 border-r border-gray-200 dark:border-vulcan-300 overflow-auto`}
|
||||
className={`w-1/3 py-6 px-4 flex-1 border-r overflow-auto ${getColors(
|
||||
`border-gray-200 dark:border-vulcan-300`,
|
||||
`border-[var(--frontmatter-border)]`
|
||||
)
|
||||
}`}
|
||||
>
|
||||
<h2 className={`text-lg text-gray-500 dark:text-whisper-900`}>
|
||||
<h2 className={`text-lg ${getColors(
|
||||
`text-gray-500 dark:text-whisper-900`,
|
||||
`text-[var(--frontmatter-text)]`
|
||||
)
|
||||
}`}>
|
||||
Your {selectedData?.title?.toLowerCase() || ''} data items
|
||||
</h2>
|
||||
|
||||
@@ -233,7 +255,7 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
|
||||
</>
|
||||
) : (
|
||||
<div className={`flex flex-col items-center justify-center`}>
|
||||
<p className={`text-gray-500 dark:text-whisper-900`}>
|
||||
<p className={getColors(`text-gray-500 dark:text-whisper-900`, `text-[var(--frontmatter-text)]`)}>
|
||||
No {selectedData.title.toLowerCase()} data entries found
|
||||
</p>
|
||||
</div>
|
||||
@@ -245,7 +267,7 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
|
||||
className={`${selectedData.singleEntry ? 'w-full' : 'w-2/3'
|
||||
} py-6 px-4 overflow-auto`}
|
||||
>
|
||||
<h2 className={`text-lg text-gray-500 dark:text-whisper-900`}>
|
||||
<h2 className={`text-lg ${getColors(`text-gray-500 dark:text-whisper-900`, `text-[var(--frontmatter-text)]`)}`}>
|
||||
Create or modify your {selectedData.title.toLowerCase()} data
|
||||
</h2>
|
||||
{selectedData ? (
|
||||
@@ -267,12 +289,16 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
|
||||
</div>
|
||||
) : (
|
||||
<div className="w-full h-full flex items-center justify-center">
|
||||
<div className="flex flex-col items-center text-gray-500 dark:text-whisper-900">
|
||||
<div className={`flex flex-col items-center ${getColors(
|
||||
'text-gray-500 dark:text-whisper-900',
|
||||
'text-[var(--frontmatter-text)]'
|
||||
)
|
||||
}`}>
|
||||
<DatabaseIcon className="w-32 h-32" />
|
||||
<p className="text-3xl mt-2">No data files found</p>
|
||||
<p className="text-xl mt-4">
|
||||
<a
|
||||
className={`text-teal-700 hover:text-teal-900`}
|
||||
className={getColors(`text-teal-700 hover:text-teal-900`, `text-[var(--frontmatter-link)] hover:text-[var(--frontmatter-link-hover)]`)}
|
||||
href={`https://frontmatter.codes/docs/dashboard#data-files-view`}
|
||||
title={`Read more to get started using data files`}
|
||||
>
|
||||
@@ -281,7 +307,8 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
)
|
||||
}
|
||||
|
||||
<SponsorMsg
|
||||
beta={settings?.beta}
|
||||
@@ -290,6 +317,6 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
|
||||
/>
|
||||
|
||||
<ToastContainer />
|
||||
</div>
|
||||
</div >
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import { ExclamationCircleIcon } from '@heroicons/react/outline';
|
||||
import * as React from 'react';
|
||||
import useThemeColors from '../../hooks/useThemeColors';
|
||||
|
||||
export interface IEmptyViewProps {}
|
||||
export interface IEmptyViewProps { }
|
||||
|
||||
export const EmptyView: React.FunctionComponent<IEmptyViewProps> = (
|
||||
props: React.PropsWithChildren<IEmptyViewProps>
|
||||
) => {
|
||||
const { getColors } = useThemeColors();
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center w-full">
|
||||
<ExclamationCircleIcon className={`w-1/12 text-gray-500 dark:text-whisper-900 opacity-90`} />
|
||||
<h2 className={`text-xl text-gray-500 dark:text-whisper-900`}>Select your date type first</h2>
|
||||
<ExclamationCircleIcon className={`w-1/12 opacity-90 ${getColors(`text-gray-500 dark:text-whisper-900`, `text-[var(--frontmatter-secondary-text)]`)}`} />
|
||||
<h2 className={`text-xl ${getColors(`text-gray-500 dark:text-whisper-900`, `text-[var(--frontmatter-secondary-text)]`)}`}>Select your date type first</h2>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
import * as React from 'react';
|
||||
import { SortableContainer } from 'react-sortable-hoc';
|
||||
import useThemeColors from '../../hooks/useThemeColors';
|
||||
|
||||
export interface ISortableContainerProps {}
|
||||
export interface ISortableContainerProps { }
|
||||
|
||||
export const Container = SortableContainer(
|
||||
({ children }: React.PropsWithChildren<ISortableContainerProps>) => (
|
||||
<ul
|
||||
className={`-mx-4 divide-y divide-gray-200 dark:divide-vulcan-300 border-t border-b border-gray-200 dark:border-vulcan-300`}
|
||||
>
|
||||
{children}
|
||||
</ul>
|
||||
)
|
||||
({ children }: React.PropsWithChildren<ISortableContainerProps>) => {
|
||||
const { getColors } = useThemeColors();
|
||||
|
||||
return (
|
||||
<ul
|
||||
className={`-mx-4 divide-y border-t border-b ${getColors(`divide-gray-200 dark:divide-vulcan-300 border-gray-200 dark:border-vulcan-300`, `divide-[var(--frontmatter-list-border)] border-[var(--frontmatter-list-border)]`)
|
||||
}`}
|
||||
>
|
||||
{children}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { PencilIcon, SelectorIcon, TrashIcon, XIcon } from '@heroicons/react/outline';
|
||||
import * as React from 'react';
|
||||
import { SortableHandle, SortableElement } from 'react-sortable-hoc';
|
||||
import useThemeColors from '../../hooks/useThemeColors';
|
||||
import { Alert } from '../Modals/Alert';
|
||||
|
||||
export interface ISortableItemProps {
|
||||
@@ -12,7 +13,7 @@ export interface ISortableItemProps {
|
||||
onDeleteItem: (index: number) => void;
|
||||
}
|
||||
|
||||
const DragHandle = SortableHandle(() => <SelectorIcon className={`w-6 h-6 cursor-move`} />);
|
||||
const DragHandle = SortableHandle(() => <SelectorIcon className={`w-6 h-6 cursor-move hover:text-[var(--frontmatter-link-hover)]`} />);
|
||||
|
||||
export const SortableItem = SortableElement(
|
||||
({
|
||||
@@ -23,6 +24,7 @@ export const SortableItem = SortableElement(
|
||||
onDeleteItem
|
||||
}: ISortableItemProps) => {
|
||||
const [showAlert, setShowAlert] = React.useState(false);
|
||||
const { getColors } = useThemeColors();
|
||||
|
||||
const deleteItemConfirm = () => {
|
||||
setShowAlert(true);
|
||||
@@ -32,9 +34,12 @@ export const SortableItem = SortableElement(
|
||||
<>
|
||||
<li
|
||||
data-test={`${selectedIndex}-${crntIndex}`}
|
||||
className={`sortable_item py-2 px-2 w-full flex justify-between content-center hover:bg-gray-200 dark:hover:bg-vulcan-400 ${
|
||||
selectedIndex === crntIndex ? `bg-gray-300 dark:bg-vulcan-300` : ``
|
||||
}`}
|
||||
className={`sortable_item py-2 px-2 w-full flex justify-between content-center cursor-pointer ${selectedIndex === crntIndex ? getColors(`bg-gray-300 dark:bg-vulcan-300`, `bg-[var(--frontmatter-list-selected-background)] text-[var(--frontmatter-list-selected-text)]`) : ``
|
||||
} ${getColors(
|
||||
'hover:bg-gray-200 dark:hover:bg-vulcan-400',
|
||||
'hover:bg-[var(--frontmatter-list-hover-background)]'
|
||||
)
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className="flex items-center w-full"
|
||||
@@ -47,7 +52,12 @@ export const SortableItem = SortableElement(
|
||||
<div className={`space-x-2 flex items-center`}>
|
||||
<button
|
||||
type="button"
|
||||
className={`text-gray-500 dark:text-whisper-900 hover:text-gray-600 dark:hover:text-whisper-500`}
|
||||
className={
|
||||
getColors(
|
||||
`text-gray-500 dark:text-whisper-900 hover:text-gray-600 dark:hover:text-whisper-500`,
|
||||
`text-[var(--frontmatter-secondary-text)] hover:text-[var(--frontmatter-link-hover)]`
|
||||
)
|
||||
}
|
||||
title={`Edit "${value}"`}
|
||||
onClick={() => onSelectedIndexChange(crntIndex)}
|
||||
>
|
||||
@@ -56,7 +66,12 @@ export const SortableItem = SortableElement(
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={`text-gray-500 dark:text-whisper-900 hover:text-gray-600 dark:hover:text-whisper-500`}
|
||||
className={
|
||||
getColors(
|
||||
`text-gray-500 dark:text-whisper-900 hover:text-gray-600 dark:hover:text-whisper-500`,
|
||||
`text-[var(--frontmatter-secondary-text)] hover:text-[var(--frontmatter-link-hover)]`
|
||||
)
|
||||
}
|
||||
title={`Delete "${value}"`}
|
||||
onClick={() => deleteItemConfirm()}
|
||||
>
|
||||
|
||||
@@ -12,25 +12,23 @@ export const NavigationItem: React.FunctionComponent<INavigationItemProps> = ({
|
||||
children
|
||||
}: React.PropsWithChildren<INavigationItemProps>) => {
|
||||
const { getColors } = useThemeColors();
|
||||
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className={`navigationitem px-4 py-2 flex items-center text-sm font-medium w-full text-left cursor-pointer ${
|
||||
getColors(
|
||||
'hover:bg-gray-200 dark:hover:bg-vulcan-400 hover:text-vulcan-500 dark:hover:text-whisper-500',
|
||||
'hover:bg-[var(--vscode-list-hoverBackground)] hover:text-[var(--vscode-list-hoverForeground)]'
|
||||
)
|
||||
} ${
|
||||
isSelected
|
||||
className={`navigationitem px-4 py-2 flex items-center text-sm font-medium w-full text-left cursor-pointer ${getColors(
|
||||
'hover:bg-gray-200 dark:hover:bg-vulcan-400 hover:text-vulcan-500 dark:hover:text-whisper-500',
|
||||
'hover:bg-[var(--frontmatter-list-hover-background)] hover:text-[var(--frontmatter-list-selected-text)]'
|
||||
)
|
||||
} ${isSelected
|
||||
? getColors(
|
||||
'bg-gray-300 dark:bg-vulcan-300 text-vulcan-500 dark:text-whisper-500',
|
||||
'bg-[var(--vscode-list-activeSelectionBackground)] text-[var(--vscode-list-activeSelectionForeground)]'
|
||||
'bg-gray-300 dark:bg-vulcan-300 text-vulcan-500 dark:text-whisper-500',
|
||||
'bg-[var(--frontmatter-list-selected-background)] text-[var(--frontmatter-list-selected-text)]'
|
||||
) : getColors(
|
||||
'text-gray-500 dark:text-whisper-900',
|
||||
'text-[var(--vscode-tab-inactiveForeground)]'
|
||||
'text-[var(--frontmatter-list-text)]'
|
||||
)
|
||||
}`}
|
||||
}`}
|
||||
onClick={onClick}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -42,11 +42,23 @@ const preserveColor = (color: string | undefined) => {
|
||||
const updateCssVariables = () => {
|
||||
const styles = getComputedStyle(document.documentElement);
|
||||
|
||||
const panelBorder = styles.getPropertyValue('--vscode-panel-border');
|
||||
if (panelBorder) {
|
||||
document.documentElement.style.setProperty('--frontmatter-border', preserveColor(panelBorder) || "var(--vscode-panel-border)");
|
||||
}
|
||||
// Text
|
||||
document.documentElement.style.setProperty('--frontmatter-text', 'var(--vscode-editor-foreground)');
|
||||
document.documentElement.style.setProperty('--frontmatter-secondary-text', 'var(--vscode-editorHint-foreground)');
|
||||
document.documentElement.style.setProperty('--frontmatter-link', 'var(--vscode-textLink-foreground)');
|
||||
document.documentElement.style.setProperty('--frontmatter-link-hover', 'var(--vscode-textLink-activeForeground)');
|
||||
|
||||
// List
|
||||
document.documentElement.style.setProperty('--frontmatter-list-text', 'var(--vscode-editor-foreground)');
|
||||
document.documentElement.style.setProperty('--frontmatter-list-background', 'var(--vscode-list-activeSelectionBackground)');
|
||||
document.documentElement.style.setProperty('--frontmatter-list-hover-background', 'var(--vscode-list-hoverBackground)');
|
||||
document.documentElement.style.setProperty('--frontmatter-list-selected-background', 'var(--vscode-list-activeSelectionBackground)');
|
||||
document.documentElement.style.setProperty('--frontmatter-list-selected-text', 'var(--vscode-list-activeSelectionForeground)');
|
||||
|
||||
// Borders
|
||||
document.documentElement.style.setProperty('--frontmatter-border', 'var(--vscode-panel-border)');
|
||||
|
||||
// Other colors which should be preserved (no opacity)
|
||||
const buttonBackground = styles.getPropertyValue('--vscode-button-background');
|
||||
if (buttonBackground) {
|
||||
document.documentElement.style.setProperty('--frontmatter-button-background', preserveColor(buttonBackground) || "var(--vscode-button-background)");
|
||||
|
||||
Reference in New Issue
Block a user