mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-08-07 17:32:58 +02:00
New combobox implementation
This commit is contained in:
Generated
+25
-5
@@ -12,7 +12,7 @@
|
||||
"@actions/core": "^1.10.0",
|
||||
"@bendera/vscode-webview-elements": "0.6.2",
|
||||
"@estruyf/vscode": "^1.1.0",
|
||||
"@headlessui/react": "1.5.0",
|
||||
"@headlessui/react": "^1.7.17",
|
||||
"@heroicons/react": "1.0.4",
|
||||
"@iarna/toml": "2.2.3",
|
||||
"@octokit/rest": "^18.12.0",
|
||||
@@ -348,9 +348,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@headlessui/react": {
|
||||
"version": "1.5.0",
|
||||
"version": "1.7.17",
|
||||
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.17.tgz",
|
||||
"integrity": "sha512-4am+tzvkqDSSgiwrsEpGWqgGo9dz8qU5M3znCkC4PgkpY4HcCZzEDEvozltGGGHIKl9jbXbZPSH5TWn4sWJdow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"client-only": "^0.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@@ -2960,6 +2964,12 @@
|
||||
"node": ">= 4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/client-only": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
||||
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/clipboardy": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz",
|
||||
@@ -13314,9 +13324,13 @@
|
||||
}
|
||||
},
|
||||
"@headlessui/react": {
|
||||
"version": "1.5.0",
|
||||
"version": "1.7.17",
|
||||
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.7.17.tgz",
|
||||
"integrity": "sha512-4am+tzvkqDSSgiwrsEpGWqgGo9dz8qU5M3znCkC4PgkpY4HcCZzEDEvozltGGGHIKl9jbXbZPSH5TWn4sWJdow==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
"requires": {
|
||||
"client-only": "^0.0.1"
|
||||
}
|
||||
},
|
||||
"@heroicons/react": {
|
||||
"version": "1.0.4",
|
||||
@@ -15272,6 +15286,12 @@
|
||||
"source-map": "~0.6.0"
|
||||
}
|
||||
},
|
||||
"client-only": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
||||
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
|
||||
"dev": true
|
||||
},
|
||||
"clipboardy": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz",
|
||||
|
||||
+1
-1
@@ -2526,7 +2526,7 @@
|
||||
"@actions/core": "^1.10.0",
|
||||
"@bendera/vscode-webview-elements": "0.6.2",
|
||||
"@estruyf/vscode": "^1.1.0",
|
||||
"@headlessui/react": "1.5.0",
|
||||
"@headlessui/react": "^1.7.17",
|
||||
"@heroicons/react": "1.0.4",
|
||||
"@iarna/toml": "2.2.3",
|
||||
"@octokit/rest": "^18.12.0",
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
import { Combobox, Transition } from '@headlessui/react';
|
||||
import * as React from 'react';
|
||||
import { BaseFieldProps } from '../../../models';
|
||||
import { Fragment, useEffect, useMemo } from 'react';
|
||||
import { Page } from '../../../dashboardWebView/models';
|
||||
import { messageHandler } from '@estruyf/vscode/dist/client/webview';
|
||||
import { CommandToCode } from '../../CommandToCode';
|
||||
import { ChevronDownIcon } from '@heroicons/react/outline';
|
||||
|
||||
export interface IComboboxFieldProps extends BaseFieldProps<string | string[]> {
|
||||
contentTypeName?: string;
|
||||
contentTypeValue?: string;
|
||||
multiSelect?: boolean;
|
||||
onChange: (value: string | string[]) => void;
|
||||
}
|
||||
|
||||
export const ComboboxField: React.FunctionComponent<IComboboxFieldProps> = ({
|
||||
label,
|
||||
description,
|
||||
value,
|
||||
contentTypeName,
|
||||
contentTypeValue,
|
||||
multiSelect,
|
||||
onChange,
|
||||
required
|
||||
}: React.PropsWithChildren<IComboboxFieldProps>) => {
|
||||
const [loading, setLoading] = React.useState<boolean>(false);
|
||||
const [choices, setChoices] = React.useState<string[]>([]);
|
||||
const [pages, setPages] = React.useState<Page[]>([]);
|
||||
const [crntSelected, setCrntSelected] = React.useState<string | string[] | null>(value);
|
||||
|
||||
const availableChoices = useMemo(() => {
|
||||
return pages.filter((page: Page) => {
|
||||
const value = contentTypeValue === "slug" ? page.slug : page.fmFilePath;
|
||||
|
||||
if (typeof crntSelected === 'string') {
|
||||
return crntSelected !== `${value}` && !value.includes(crntSelected);
|
||||
} else if (crntSelected instanceof Array) {
|
||||
const selected = crntSelected.filter((v) => v === `${value}` || value.includes(v));
|
||||
return selected.length === 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}, [choices, crntSelected, multiSelect, contentTypeValue]);
|
||||
|
||||
useEffect(() => {
|
||||
if (contentTypeName) {
|
||||
setLoading(true);
|
||||
messageHandler
|
||||
.request<Page[]>(CommandToCode.searchByType, contentTypeName)
|
||||
.then((pages: Page[]) => {
|
||||
setPages(pages || []);
|
||||
setChoices((pages || []).map(page => page.title))
|
||||
}).finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
}
|
||||
}, [contentTypeName]);
|
||||
|
||||
return (
|
||||
<Combobox
|
||||
value={crntSelected}
|
||||
onChange={(value) => null}
|
||||
>
|
||||
<div className="relative mt-1">
|
||||
|
||||
<div className="relative w-full cursor-default overflow-hidden text-left focus:outline-none">
|
||||
<Combobox.Input
|
||||
className="w-full border-none py-2 pl-3 pr-10 text-sm leading-5 text-gray-900 focus:ring-0"
|
||||
onChange={(e) => console.log(e)} />
|
||||
|
||||
|
||||
<Combobox.Button className="absolute inset-y-0 right-0 flex items-center pr-2 w-8">
|
||||
<ChevronDownIcon
|
||||
className="h-5 w-5 text-gray-400"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</Combobox.Button>
|
||||
</div>
|
||||
|
||||
<Transition
|
||||
as={Fragment}
|
||||
leave="transition ease-in duration-100"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0"
|
||||
>
|
||||
<Combobox.Options
|
||||
className="absolute mt-1 max-h-60 w-full overflow-auto py-1 text-base focus:outline-none z-50 bg-black">
|
||||
{availableChoices.map((choice) => (
|
||||
<Combobox.Option key={choice.fmFilePath} value={choice.fmFileName}>
|
||||
{choice.title}
|
||||
</Combobox.Option>
|
||||
))}
|
||||
</Combobox.Options>
|
||||
</Transition>
|
||||
</div>
|
||||
</Combobox>
|
||||
)
|
||||
};
|
||||
@@ -33,6 +33,7 @@ import { fieldWhenClause } from '../../../utils/fieldWhenClause';
|
||||
import { ContentTypeRelationshipField } from './ContentTypeRelationshipField';
|
||||
import * as l10n from '@vscode/l10n';
|
||||
import { LocalizationKey } from '../../../localization';
|
||||
import { ComboboxField } from './ComboboxField';
|
||||
|
||||
export interface IWrapperFieldProps {
|
||||
field: Field;
|
||||
@@ -485,7 +486,18 @@ export const WrapperField: React.FunctionComponent<IWrapperFieldProps> = ({
|
||||
} else if (field.type === 'contentRelationship') {
|
||||
return (
|
||||
<FieldBoundary key={field.name} fieldName={field.title || field.name}>
|
||||
<ContentTypeRelationshipField
|
||||
{/* <ContentTypeRelationshipField
|
||||
label={field.title || field.name}
|
||||
description={field.description}
|
||||
value={fieldValue as string}
|
||||
required={!!field.required}
|
||||
contentTypeName={field.contentTypeName}
|
||||
contentTypeValue={field.contentTypeValue}
|
||||
multiSelect={field.multiple}
|
||||
onChange={(value) => onSendUpdate(field.name, value, parentFields)}
|
||||
/> */}
|
||||
|
||||
<ComboboxField
|
||||
label={field.title || field.name}
|
||||
description={field.description}
|
||||
value={fieldValue as string}
|
||||
|
||||
@@ -5,6 +5,7 @@ import * as Sentry from '@sentry/react';
|
||||
import { Integrations } from '@sentry/tracing';
|
||||
import { SENTRY_LINK, SentryIgnore } from '../constants';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
|
||||
import './styles.css';
|
||||
|
||||
// require('@vscode/codicons/dist/codicon.css');
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
@import 'tailwindcss/components';
|
||||
@import 'tailwindcss/utilities';
|
||||
|
||||
/* Animations */
|
||||
@keyframes spin {
|
||||
from {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
const defaultConfig = require("./tailwind.config")
|
||||
|
||||
module.exports = {
|
||||
...defaultConfig,
|
||||
corePlugins: {
|
||||
preflight: false,
|
||||
}
|
||||
}
|
||||
+15
-1
@@ -31,7 +31,21 @@ const config = [{
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ['style-loader', 'css-loader', 'postcss-loader']
|
||||
use: ['style-loader', 'css-loader', {
|
||||
loader: "postcss-loader",
|
||||
options: {
|
||||
postcssOptions: {
|
||||
plugins: {
|
||||
'postcss-import': {},
|
||||
'tailwindcss/nesting': {},
|
||||
tailwindcss: {
|
||||
config: path.resolve(__dirname, '../tailwind.panel.js')
|
||||
},
|
||||
autoprefixer: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
}]
|
||||
},
|
||||
{
|
||||
test: /\.m?js/,
|
||||
|
||||
Reference in New Issue
Block a user