mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-17 23:14:03 +01:00
Improve <details> component (#238)
Co-authored-by: Gregory Schier <gschier1990@gmail.com>
This commit is contained in:
@@ -20,6 +20,7 @@ import { showDialog } from '../lib/dialog';
|
||||
import { resolvedModelName } from '../lib/resolvedModelName';
|
||||
import { Banner } from './core/Banner';
|
||||
import { Checkbox } from './core/Checkbox';
|
||||
import { DetailsBanner } from './core/DetailsBanner';
|
||||
import { Editor } from './core/Editor/Editor';
|
||||
import { IconButton } from './core/IconButton';
|
||||
import { Input } from './core/Input';
|
||||
@@ -174,22 +175,23 @@ function FormInputs<T extends Record<string, JsonPrimitive>>({
|
||||
);
|
||||
case 'accordion':
|
||||
return (
|
||||
<Banner key={i} className={classNames('!p-0', disabled && 'opacity-disabled')}>
|
||||
<details>
|
||||
<summary className="px-3 py-1.5 text-text-subtle">{input.label}</summary>
|
||||
<div className="mb-3 px-3">
|
||||
<FormInputs
|
||||
data={data}
|
||||
disabled={disabled}
|
||||
inputs={input.inputs}
|
||||
setDataAttr={setDataAttr}
|
||||
stateKey={stateKey}
|
||||
autocompleteFunctions={autocompleteFunctions || false}
|
||||
autocompleteVariables={autocompleteVariables}
|
||||
/>
|
||||
</div>
|
||||
</details>
|
||||
</Banner>
|
||||
<DetailsBanner
|
||||
key={i}
|
||||
summary={input.label}
|
||||
className={classNames(disabled && 'opacity-disabled')}
|
||||
>
|
||||
<div className="mb-3 px-3">
|
||||
<FormInputs
|
||||
data={data}
|
||||
disabled={disabled}
|
||||
inputs={input.inputs}
|
||||
setDataAttr={setDataAttr}
|
||||
stateKey={stateKey}
|
||||
autocompleteFunctions={autocompleteFunctions || false}
|
||||
autocompleteVariables={autocompleteVariables}
|
||||
/>
|
||||
</div>
|
||||
</DetailsBanner>
|
||||
);
|
||||
case 'banner':
|
||||
return (
|
||||
|
||||
@@ -7,9 +7,9 @@ import slugify from 'slugify';
|
||||
import { activeWorkspaceAtom } from '../hooks/useActiveWorkspace';
|
||||
import { pluralizeCount } from '../lib/pluralize';
|
||||
import { invokeCmd } from '../lib/tauri';
|
||||
import { Banner } from './core/Banner';
|
||||
import { Button } from './core/Button';
|
||||
import { Checkbox } from './core/Checkbox';
|
||||
import { DetailsBanner } from './core/DetailsBanner';
|
||||
import { HStack, VStack } from './core/Stacks';
|
||||
|
||||
interface Props {
|
||||
@@ -123,19 +123,14 @@ function ExportDataDialogContent({
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
<Banner className="!p-0">
|
||||
<details open>
|
||||
<summary className="px-3 py-2">Extra Settings</summary>
|
||||
<div className="px-3 pb-2">
|
||||
<Checkbox
|
||||
checked={includePrivateEnvironments}
|
||||
onChange={setIncludePrivateEnvironments}
|
||||
title="Include private environments"
|
||||
help='Environments marked as "sharable" will be exported by default'
|
||||
/>
|
||||
</div>
|
||||
</details>
|
||||
</Banner>
|
||||
<DetailsBanner color="secondary" open summary="Extra Settings">
|
||||
<Checkbox
|
||||
checked={includePrivateEnvironments}
|
||||
onChange={setIncludePrivateEnvironments}
|
||||
title="Include private environments"
|
||||
help='Environments marked as "sharable" will be exported by default'
|
||||
/>
|
||||
</DetailsBanner>
|
||||
<HStack space={2} justifyContent="end">
|
||||
<Button className="focus" variant="border" onClick={onHide}>
|
||||
Cancel
|
||||
|
||||
@@ -5,8 +5,8 @@ import { connections } from '../lib/data/connections';
|
||||
import { encodings } from '../lib/data/encodings';
|
||||
import { headerNames } from '../lib/data/headerNames';
|
||||
import { mimeTypes } from '../lib/data/mimetypes';
|
||||
import { Banner } from './core/Banner';
|
||||
import { CountBadge } from './core/CountBadge';
|
||||
import { DetailsBanner } from './core/DetailsBanner';
|
||||
import type { GenericCompletionConfig } from './core/Editor/genericCompletion';
|
||||
import type { InputProps } from './core/Input';
|
||||
import type { Pair, PairEditorProps } from './core/PairEditor';
|
||||
@@ -35,35 +35,36 @@ export function HeadersEditor({
|
||||
return (
|
||||
<div className="@container w-full h-full grid grid-rows-[auto_minmax(0,1fr)]">
|
||||
{validInheritedHeaders.length > 0 ? (
|
||||
<Banner className="!py-0 mb-1.5 border-dashed" color="secondary">
|
||||
<details>
|
||||
<summary className="py-1.5 text-sm !cursor-default !select-none opacity-70 hover:opacity-100">
|
||||
<HStack>
|
||||
Inherited <CountBadge count={validInheritedHeaders.length} />
|
||||
</HStack>
|
||||
</summary>
|
||||
<div className="pb-2">
|
||||
{validInheritedHeaders?.map((pair, i) => (
|
||||
<PairEditorRow
|
||||
key={pair.id + '.' + i}
|
||||
index={i}
|
||||
disabled
|
||||
disableDrag
|
||||
className="py-1"
|
||||
onChange={() => {}}
|
||||
onEnd={() => {}}
|
||||
onMove={() => {}}
|
||||
pair={ensurePairId(pair)}
|
||||
stateKey={null}
|
||||
nameAutocompleteFunctions
|
||||
nameAutocompleteVariables
|
||||
valueAutocompleteFunctions
|
||||
valueAutocompleteVariables
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</details>
|
||||
</Banner>
|
||||
<DetailsBanner
|
||||
color="secondary"
|
||||
className="text-sm mb-1.5"
|
||||
summary={
|
||||
<HStack>
|
||||
Inherited <CountBadge count={validInheritedHeaders.length} />
|
||||
</HStack>
|
||||
}
|
||||
>
|
||||
<div className="pb-2">
|
||||
{validInheritedHeaders?.map((pair, i) => (
|
||||
<PairEditorRow
|
||||
key={pair.id + '.' + i}
|
||||
index={i}
|
||||
disabled
|
||||
disableDrag
|
||||
className="py-1"
|
||||
onChange={() => {}}
|
||||
onEnd={() => {}}
|
||||
onMove={() => {}}
|
||||
pair={ensurePairId(pair)}
|
||||
stateKey={null}
|
||||
nameAutocompleteFunctions
|
||||
nameAutocompleteVariables
|
||||
valueAutocompleteFunctions
|
||||
valueAutocompleteVariables
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</DetailsBanner>
|
||||
) : (
|
||||
<span />
|
||||
)}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Button } from './core/Button';
|
||||
import { DetailsBanner } from './core/DetailsBanner';
|
||||
import { FormattedError } from './core/FormattedError';
|
||||
import { Heading } from './core/Heading';
|
||||
import { VStack } from './core/Stacks';
|
||||
@@ -17,10 +18,9 @@ export default function RouteError({ error }: { error: unknown }) {
|
||||
<FormattedError>
|
||||
{message}
|
||||
{stack && (
|
||||
<details className="mt-3 select-auto text-xs">
|
||||
<summary className="!cursor-default !select-none">Stack Trace</summary>
|
||||
<DetailsBanner color="secondary" className="mt-3 select-auto text-xs" summary="Stack Trace">
|
||||
<div className="mt-2 text-xs">{stack}</div>
|
||||
</details>
|
||||
</DetailsBanner>
|
||||
)}
|
||||
</FormattedError>
|
||||
<VStack space={2}>
|
||||
|
||||
@@ -13,9 +13,10 @@ export function Banner({ children, className, color }: BannerProps) {
|
||||
<div
|
||||
className={classNames(
|
||||
className,
|
||||
color && 'bg-surface',
|
||||
`x-theme-banner--${color}`,
|
||||
'border border-border bg-surface',
|
||||
'px-4 py-3 rounded-lg select-auto',
|
||||
'border border-border border-dashed',
|
||||
'px-4 py-2 rounded-lg select-auto',
|
||||
'overflow-auto text-text',
|
||||
)}
|
||||
>
|
||||
|
||||
31
src-web/components/core/DetailsBanner.tsx
Normal file
31
src-web/components/core/DetailsBanner.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import classNames from 'classnames';
|
||||
import type { HTMLAttributes, ReactNode } from 'react';
|
||||
import type { BannerProps } from './Banner';
|
||||
import { Banner } from './Banner';
|
||||
|
||||
interface Props extends HTMLAttributes<HTMLDetailsElement> {
|
||||
summary: ReactNode;
|
||||
color?: BannerProps['color'];
|
||||
open?: boolean;
|
||||
}
|
||||
|
||||
export function DetailsBanner({ className, color, summary, children, ...extraProps }: Props) {
|
||||
return (
|
||||
<Banner color={color} className={className}>
|
||||
<details className="group list-none" {...extraProps}>
|
||||
<summary className="!cursor-default !select-none list-none flex items-center gap-2 focus:outline-none opacity-70 hover:opacity-100 focus:opacity-100">
|
||||
<div
|
||||
className={classNames(
|
||||
'transition-transform',
|
||||
'group-open:rotate-90',
|
||||
'w-0 h-0 border-t-[0.3em] border-b-[0.3em] border-l-[0.5em] border-r-0',
|
||||
'border-t-transparent border-b-transparent border-l-text-subtle',
|
||||
)}
|
||||
></div>
|
||||
{summary}
|
||||
</summary>
|
||||
{children}
|
||||
</details>
|
||||
</Banner>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user