console: Add stories and type utilities for the KnowMoreLink

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7578
GitOrigin-RevId: 7b297877cf57729a249a89563afc957ec15a86e0
This commit is contained in:
Stefano Magni 2023-02-09 13:16:24 +01:00 committed by hasura-bot
parent 8e0e778cd5
commit 2f6b370ced
5 changed files with 103 additions and 39 deletions

View File

@ -268,7 +268,6 @@ export const OasGeneratorForm = (props: OasGeneratorFormProps) => {
noErrorPlaceholder
name="oas"
placeholder="1. Paste OpenAPI spec in raw text (JSON / YAML) here"
tooltip="Enter a sample request in JSON or YAML format to generate the input type"
editorOptions={editorOptions}
editorProps={{
className: 'rounded`-r-none',

View File

@ -125,6 +125,26 @@ VariantWithDescriptionAndTooltipAndKnwMoreLink.parameters = {
},
};
export const VariantWithDescriptionAndTooltipAndKnowMoreLink: ComponentStory<
typeof FieldWrapper
> = () => (
<FieldWrapper
label="The field wrapper label"
description="The field wrapper description"
tooltip="The field wrapper tooltip"
knowMoreLink="https://hasura.io/docs"
>
<ChildrenExample />
</FieldWrapper>
);
VariantWithDescriptionAndTooltipAndKnowMoreLink.storyName =
'🎭 Variant - With description, tooltip, and know more link';
VariantWithDescriptionAndTooltipAndKnowMoreLink.parameters = {
docs: {
source: { state: 'open' },
},
};
export const StateLoading: ComponentStory<typeof FieldWrapper> = () => (
<FieldWrapper
label="The field wrapper label"

View File

@ -4,39 +4,21 @@ import clsx from 'clsx';
import Skeleton from 'react-loading-skeleton';
import { FaExclamationCircle } from 'react-icons/fa';
import type { DiscriminatedTypes } from '@/types';
import { IconTooltip } from '@/new-components/Tooltip';
import { KnowMoreLink } from '../KnowMoreLink';
type FieldWrapperProps = {
export type FieldWrapperPassThroughProps = {
/**
* The field ID
*/
id?: string;
/**
* The field label icon
*/
labelIcon?: React.ReactElement;
/**
* The field label
*/
label?: string;
/**
* The field class
*/
className?: string;
/**
* The field size (full: the full width of the container , medium: half the
* width of the container)
*/
size?: 'full' | 'medium';
/**
* The field children
*/
children: React.ReactNode;
/**
* The field error
*/
error?: FieldError | undefined;
/**
* The field description
*/
@ -57,21 +39,43 @@ type FieldWrapperProps = {
* Render line breaks in the description
*/
renderDescriptionLineBreaks?: boolean;
/**
* The field tooltip label
*/
tooltip?: React.ReactNode;
/**
* The link containing more information about the field
*/
knowMoreLink?: string;
};
export type FieldWrapperPassThroughProps = Omit<
FieldWrapperProps,
'className' | 'children' | 'error'
} & DiscriminatedTypes<
{
/**
* The field label
*/
label: string;
/**
* The field label icon. Can be set only if label is set.
*/
labelIcon?: React.ReactElement;
/**
* The field tooltip label. Can be set only if label is set.
*/
tooltip?: React.ReactNode;
/**
* The link containing more information about the field. Can be set only if label is set.
*/
knowMoreLink?: string;
},
'label'
>;
type FieldWrapperProps = FieldWrapperPassThroughProps & {
/**
* The field class
*/
className?: string;
/**
* The field children
*/
children: React.ReactNode;
/**
* The field error
*/
error?: FieldError | undefined;
};
export const ErrorComponentTemplate = (props: {
label: React.ReactNode;
ariaLabel?: string;

View File

@ -6,10 +6,10 @@ import React from 'react';
import { z } from 'zod';
import { InputField, InputFieldProps, Schema } from './InputField';
export interface GraphQLSanitizedInputFieldProps<T extends z.infer<Schema>>
extends InputFieldProps<T> {
hideTips?: boolean;
}
export type GraphQLSanitizedInputFieldProps<T extends z.infer<Schema>> =
InputFieldProps<T> & {
hideTips?: boolean;
};
export const GraphQLSanitizedInputField = <T extends z.infer<Schema>>({
hideTips,

View File

@ -91,3 +91,44 @@ export type NullableProps<T> = { [K in keyof T]: T[K] | null };
export type DeepNullableProps<T> = {
[K in keyof T]: DeepNullableProps<T[K]> | null;
};
/**
* Set all keys in an object to Never. Useful for writing custom types.
* To grasp it:
* Given { a: string; b: number }
* called like this MakeNever<MyType>
* It will output { a: never; b: never }
*/
export type MakeNever<T> = {
[P in keyof T]: never;
};
/**
* Makes a discriminated union
* Useful if you have part of the object where you need
*
* To grasp it:
* Given { buttonLabel: string, buttonIcon?: string; onClick: () => void }
* Called like this DiscriminatedTypes<MyType, 'buttonLabel'>
* It will output { buttonLabel?: string; buttonIcon?: never; onClick?: never } | { buttonLabel: string; buttonIcon?: string: onClick: () => void; }
* This way :
* If buttonLabel is not set, buttonIcon and onClick cannot be set
* If buttonLabel is set, buttonIcon can be set and onClick is mandatory
*
* @example <caption>Here you prevent `labelIcon` and `labelColor` to be passed without `label`,
* but you can pass just `label` if you want.</caption>
* type FieldWrapperProps =
* | {
* id: string;
* } & DiscriminatedTypes<
* {
* label: string;
* labelColor: string;
* labelIcon?: React.ReactElement;
* },
* 'label'
* >;
*/
export type DiscriminatedTypes<T, K extends keyof T> =
| MakeNever<Partial<Pick<T, K>> & Partial<Omit<T, K>>>
| (Required<Pick<T, K>> & Omit<T, K>);