mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* Add docs; fix nits * Updating documentation * Tweaks * Fix missed conversions
This commit is contained in:
parent
f1efbf0654
commit
78a6c3dd4e
6 changed files with 216 additions and 48 deletions
|
@ -4,7 +4,7 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { ExpressionFunction } from 'src/legacy/core_plugins/interpreter/public';
|
||||
import { ContainerStyle } from '../types';
|
||||
import { ContainerStyle, Overflow, BackgroundRepeat, BackgroundSize } from '../types';
|
||||
import { getFunctionHelp, getFunctionErrors } from '../../strings';
|
||||
// @ts-ignore untyped local
|
||||
import { isValidUrl } from '../../../common/lib/url';
|
||||
|
@ -55,13 +55,13 @@ export function containerStyle(): ExpressionFunction<
|
|||
types: ['string'],
|
||||
help: argHelp.backgroundSize,
|
||||
default: 'contain',
|
||||
options: ['contain', 'cover', 'auto'],
|
||||
options: Object.values(BackgroundSize),
|
||||
},
|
||||
backgroundRepeat: {
|
||||
types: ['string'],
|
||||
help: argHelp.backgroundRepeat,
|
||||
default: 'no-repeat',
|
||||
options: ['repeat-x', 'repeat', 'space', 'round', 'no-repeat', 'space'],
|
||||
options: Object.values(BackgroundRepeat),
|
||||
},
|
||||
opacity: {
|
||||
types: ['number'],
|
||||
|
@ -70,7 +70,7 @@ export function containerStyle(): ExpressionFunction<
|
|||
overflow: {
|
||||
types: ['string'],
|
||||
help: argHelp.overflow,
|
||||
options: ['visible', 'hidden', 'scroll', 'auto'],
|
||||
options: Object.values(Overflow),
|
||||
default: 'hidden',
|
||||
},
|
||||
},
|
||||
|
|
|
@ -9,7 +9,15 @@ import inlineStyle from 'inline-style';
|
|||
import { ExpressionFunction } from 'src/legacy/core_plugins/interpreter/public';
|
||||
import { openSans } from '../../../common/lib/fonts';
|
||||
import { getFunctionHelp, getFunctionErrors } from '../../strings';
|
||||
import { CSSStyle, FontFamily, FontWeight, Style, TextAlignment, TEXT_ALIGNMENTS } from '../types';
|
||||
import {
|
||||
CSSStyle,
|
||||
FontFamily,
|
||||
FontWeight,
|
||||
TextDecoration,
|
||||
Style,
|
||||
TextAlignment,
|
||||
FontStyle,
|
||||
} from '../types';
|
||||
|
||||
interface Arguments {
|
||||
align: TextAlignment;
|
||||
|
@ -38,7 +46,7 @@ export function font(): ExpressionFunction<'font', null, Arguments, Style> {
|
|||
align: {
|
||||
default: 'left',
|
||||
help: argHelp.align,
|
||||
options: TEXT_ALIGNMENTS,
|
||||
options: Object.values(TextAlignment),
|
||||
types: ['string'],
|
||||
},
|
||||
color: {
|
||||
|
@ -83,7 +91,7 @@ export function font(): ExpressionFunction<'font', null, Arguments, Style> {
|
|||
if (!Object.values(FontWeight).includes(args.weight)) {
|
||||
throw errors.invalidFontWeight(args.weight);
|
||||
}
|
||||
if (!TEXT_ALIGNMENTS.includes(args.align)) {
|
||||
if (!Object.values(TextAlignment).includes(args.align)) {
|
||||
throw errors.invalidTextAlignment(args.align);
|
||||
}
|
||||
|
||||
|
@ -94,8 +102,8 @@ export function font(): ExpressionFunction<'font', null, Arguments, Style> {
|
|||
const spec: CSSStyle = {
|
||||
fontFamily: args.family,
|
||||
fontWeight: args.weight,
|
||||
fontStyle: args.italic ? 'italic' : 'normal',
|
||||
textDecoration: args.underline ? 'underline' : 'none',
|
||||
fontStyle: args.italic ? FontStyle.ITALIC : FontStyle.NORMAL,
|
||||
textDecoration: args.underline ? TextDecoration.UNDERLINE : TextDecoration.NONE,
|
||||
textAlign: args.align,
|
||||
fontSize: `${args.size}px`, // apply font size as a pixel setting
|
||||
lineHeight, // apply line height as a pixel setting
|
||||
|
|
|
@ -9,20 +9,80 @@ import { functions as commonFunctions } from '../../functions/common';
|
|||
import { functions as browserFunctions } from '../../functions/browser';
|
||||
import { functions as serverFunctions } from '../../functions/server';
|
||||
|
||||
// A reducing type for Function Factories to a base `Function`.
|
||||
// This is useful for collecting all of the Functions and the concepts they share as
|
||||
// one useable type.
|
||||
/**
|
||||
* A `ExpressionFunctionFactory` is a powerful type used for any function that produces
|
||||
* an `ExpressionFunction`. If it does not meet the signature for such a function,
|
||||
* or if it does not produce an `ExpressionFunction`, it will be typed as
|
||||
* returning `never`.
|
||||
*
|
||||
* This type will, in turn, strongly-type both a factory that produces an
|
||||
* `ExpressionFunction`, *and* the `ExpressionFunction` itself. This means one can
|
||||
* effectively introspect properties from the factory in other places.
|
||||
*
|
||||
* As an example, given the following:
|
||||
*
|
||||
```
|
||||
function foo(): ExpressionFunction<'foo', Context, Arguments, Return> {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
*
|
||||
* `foo` would be an `ExpressionFunctionFactory`. Using the `FunctionFactory` type allows one to
|
||||
* introspect the generics from the `ExpressionFunction` without needing to access it
|
||||
* directly:
|
||||
*
|
||||
```
|
||||
type Baz = FunctionFactory<typeof foo>;
|
||||
```
|
||||
*
|
||||
* Thus, in reality, and in a Typescript-enabled IDE, one would see the following definition
|
||||
* for `Baz`:
|
||||
*
|
||||
```
|
||||
type Baz = ExpressionFunction<"foo", Context, Arguments, Return>
|
||||
```
|
||||
*
|
||||
* Why is this useful? Given a collection of `ExpressionFunctions` that have been registered
|
||||
* with the `Interpreter`, you could take that collection and do any number of other
|
||||
* introspected, strongly-typed operations.
|
||||
*
|
||||
* One example would to create a dictionary of all of the names of the `ExpressionFunctions`
|
||||
* that have been registered:
|
||||
*
|
||||
```
|
||||
const someFunctions = [
|
||||
functionOne: ExpressionFunction<'functionOne', Context, Arguments, Return>,
|
||||
functionTwo: ExpressionFunction<'functionTwo', Context, Arguments, Return>,
|
||||
functionThree: ExpressionFunction<'functionThree', Context, Arguments, Return>,
|
||||
];
|
||||
|
||||
export type FunctionName = FunctionFactory<typeof someFunctions[number]>['name'];
|
||||
|
||||
const name: FunctionName = 'functionOne'; // passes
|
||||
const nonName: FunctionName = 'elastic`; // fails
|
||||
```
|
||||
*
|
||||
* A more practical example would be to use the introspected generics to create dictionaries,
|
||||
* like of help strings or documentation, that would contain only valid functions and their
|
||||
* generics, but nothing extraneous. This is actually used in a number of built-in functions
|
||||
* in Kibana and Canvas.
|
||||
*/
|
||||
// prettier-ignore
|
||||
export type ExpressionFunctionFactory<Name extends string, Context, Arguments, Return> =
|
||||
() => ExpressionFunction<Name, Context, Arguments, Return>;
|
||||
|
||||
/**
|
||||
* `FunctionFactory` exists as a name shim between the `ExpressionFunction` type and
|
||||
* the functions that already existed in Canvas. This type can likely be removed, and
|
||||
* callsites converted, if `ExpressionFunctionFactory` is moved into the Interpreter, (perhaps
|
||||
* with a shorter name).
|
||||
*/
|
||||
// prettier-ignore
|
||||
export type FunctionFactory<FnFactory> =
|
||||
FnFactory extends ExpressionFunctionFactory<infer Name, infer Context, infer Arguments, infer Return> ?
|
||||
ExpressionFunction<Name, Context, Arguments, Return> :
|
||||
never;
|
||||
|
||||
// A `ExpressionFunctionFactory` defines a function that produces a named `ExpressionFunction`.
|
||||
// prettier-ignore
|
||||
type ExpressionFunctionFactory<Name extends string, Context, Arguments, Return> =
|
||||
() => ExpressionFunction<Name, Context, Arguments, Return>;
|
||||
|
||||
// A type containing all of the raw Function definitions in Canvas.
|
||||
// prettier-ignore
|
||||
type Functions =
|
||||
|
@ -31,11 +91,11 @@ type Functions =
|
|||
typeof browserFunctions[number];
|
||||
|
||||
/**
|
||||
* A type containing all Canvas Functions.
|
||||
* A union type of all Canvas Functions.
|
||||
*/
|
||||
export type AvailableFunctions = FunctionFactory<Functions>;
|
||||
export type CanvasFunction = FunctionFactory<Functions>;
|
||||
|
||||
/**
|
||||
* A type containing all Canvas Function names.
|
||||
* A union type of all Canvas Function names.
|
||||
*/
|
||||
export type AvailableFunctionNames = AvailableFunctions['name'];
|
||||
export type CanvasFunctionName = CanvasFunction['name'];
|
||||
|
|
|
@ -8,7 +8,36 @@ import { FontLabel } from '../../../common/lib/fonts';
|
|||
export { FontLabel as FontFamily, FontValue } from '../../../common/lib/fonts';
|
||||
|
||||
/**
|
||||
* Type containing font weights.
|
||||
* Enum of supported CSS `background-repeat` properties.
|
||||
*/
|
||||
export enum BackgroundRepeat {
|
||||
REPEAT = 'repeat',
|
||||
REPEAT_NO = 'no-repeat',
|
||||
REPEAT_X = 'repeat-x',
|
||||
REPEAT_Y = 'repeat-y',
|
||||
ROUND = 'round',
|
||||
SPACE = 'space',
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum of supported CSS `background-size` properties.
|
||||
*/
|
||||
export enum BackgroundSize {
|
||||
AUTO = 'auto',
|
||||
CONTAIN = 'contain',
|
||||
COVER = 'cover',
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum of supported CSS `font-style` properties.
|
||||
*/
|
||||
export enum FontStyle {
|
||||
ITALIC = 'italic',
|
||||
NORMAL = 'normal',
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum of supported CSS `font-weight` properties.
|
||||
*/
|
||||
export enum FontWeight {
|
||||
NORMAL = 'normal',
|
||||
|
@ -27,14 +56,32 @@ export enum FontWeight {
|
|||
}
|
||||
|
||||
/**
|
||||
* Type containing valid text alignments.
|
||||
* Enum of supported CSS `overflow` properties.
|
||||
*/
|
||||
export type TextAlignment = 'center' | 'left' | 'right' | 'justify';
|
||||
export enum Overflow {
|
||||
AUTO = 'auto',
|
||||
HIDDEN = 'hidden',
|
||||
SCROLL = 'scroll',
|
||||
VISIBLE = 'visible',
|
||||
}
|
||||
|
||||
/**
|
||||
* Collection of text alignments.
|
||||
* Enum of supported CSS `text-align` properties.
|
||||
*/
|
||||
export const TEXT_ALIGNMENTS: TextAlignment[] = ['center', 'left', 'right', 'justify'];
|
||||
export enum TextAlignment {
|
||||
CENTER = 'center',
|
||||
JUSTIFY = 'justify',
|
||||
LEFT = 'left',
|
||||
RIGHT = 'right',
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum of supported CSS `text-decoration` properties.
|
||||
*/
|
||||
export enum TextDecoration {
|
||||
NONE = 'none',
|
||||
UNDERLINE = 'underline',
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the various style properties that can be applied to an element.
|
||||
|
@ -44,11 +91,11 @@ export interface CSSStyle {
|
|||
fill?: string;
|
||||
fontFamily?: FontLabel;
|
||||
fontSize?: string;
|
||||
fontStyle?: 'italic' | 'normal';
|
||||
fontStyle?: FontStyle;
|
||||
fontWeight?: FontWeight;
|
||||
lineHeight?: number | string;
|
||||
textAlign?: TextAlignment;
|
||||
textDecoration?: 'underline' | 'none';
|
||||
textDecoration?: TextDecoration;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -60,10 +107,10 @@ export interface ContainerStyle {
|
|||
padding: string | null;
|
||||
backgroundColor: string | null;
|
||||
backgroundImage: string | null;
|
||||
backgroundSize: 'contain' | 'cover' | 'auto';
|
||||
backgroundRepeat: 'repeat-x' | 'repeat' | 'space' | 'round' | 'no-repeat' | 'space';
|
||||
backgroundSize: BackgroundSize;
|
||||
backgroundRepeat: BackgroundRepeat;
|
||||
opacity: number | null;
|
||||
overflow: 'visible' | 'hidden' | 'scroll' | 'auto';
|
||||
overflow: Overflow;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import { ExpressionFunction } from 'src/legacy/core_plugins/interpreter/public';
|
||||
import { AvailableFunctions } from '../../functions/types';
|
||||
import { CanvasFunction } from '../../functions/types';
|
||||
import { UnionToIntersection } from '../../functions/types';
|
||||
|
||||
import { help as all } from './all';
|
||||
|
@ -72,8 +72,33 @@ import { help as timefilterControl } from './timefilterControl';
|
|||
import { help as urlparam } from './urlparam';
|
||||
|
||||
/**
|
||||
* This type infers Function argument types. This allows for validation that every
|
||||
* function argument has the correct help strings.
|
||||
* This type defines an entry in the `FunctionHelpMap`. It uses
|
||||
* an `ExpressionFunction` to infer its `Arguments` in order to strongly-type that
|
||||
* entry.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
```
|
||||
interface Arguments {
|
||||
bar: string;
|
||||
baz: number;
|
||||
}
|
||||
|
||||
function foo(): ExpressionFunction<'foo', Context, Arguments, Return> {
|
||||
// ...
|
||||
}
|
||||
|
||||
const help: FunctionHelp<typeof foo> = {
|
||||
help: 'Some help for foo',
|
||||
args: {
|
||||
bar: 'Help for bar.', // pass; error if missing
|
||||
baz: 'Help for baz.', // pass; error if missing
|
||||
zap: 'Help for zap.`, // error: zap doesn't exist
|
||||
}
|
||||
};
|
||||
```
|
||||
* This allows one to ensure each argument is present, and no extraneous arguments
|
||||
* remain.
|
||||
*/
|
||||
export type FunctionHelp<T> = T extends ExpressionFunction<
|
||||
infer Name,
|
||||
|
@ -87,8 +112,22 @@ export type FunctionHelp<T> = T extends ExpressionFunction<
|
|||
}
|
||||
: never;
|
||||
|
||||
// This type infers a Function name and Arguments to ensure every Function is defined
|
||||
// in the `dict` and all Arguments have help strings.
|
||||
// This internal type infers a Function name and uses `FunctionHelp` above to build
|
||||
// a dictionary entry. This can be used to ensure every Function is defined and all
|
||||
// Arguments have help strings.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// function foo(): ExpressionFunction<'foo', Context, Arguments, Return> {
|
||||
// // ...
|
||||
// }
|
||||
//
|
||||
// const map: FunctionHelpMap<typeof foo> = {
|
||||
// foo: FunctionHelp<typeof foo>,
|
||||
// }
|
||||
//
|
||||
// Given a collection of functions, the map would contain each entry.
|
||||
//
|
||||
type FunctionHelpMap<T> = T extends ExpressionFunction<
|
||||
infer Name,
|
||||
infer Context,
|
||||
|
@ -98,17 +137,17 @@ type FunctionHelpMap<T> = T extends ExpressionFunction<
|
|||
? { [key in Name]: FunctionHelp<T> }
|
||||
: never;
|
||||
|
||||
// This type represents an exhaustive dictionary of Function help strings,
|
||||
// organized by Function and then Function Argument.
|
||||
// This internal type represents an exhaustive dictionary of `FunctionHelp` types,
|
||||
// organized by Function Name and then Function Argument.
|
||||
//
|
||||
// This type indexes the existing function factories, reverses the union to an
|
||||
// intersection, and produces the dictionary of strings.
|
||||
type FunctionHelpDict = UnionToIntersection<FunctionHelpMap<AvailableFunctions>>;
|
||||
type FunctionHelpDict = UnionToIntersection<FunctionHelpMap<CanvasFunction>>;
|
||||
|
||||
/**
|
||||
* Help text for Canvas Functions should be properly localized. This function will
|
||||
* return a dictionary of help strings, organized by Canvas Function specification
|
||||
* and then by available arguments.
|
||||
* return a dictionary of help strings, organized by `CanvasFunction` specification
|
||||
* and then by available arguments within each `CanvasFunction`.
|
||||
*
|
||||
* This a function, rather than an object, to future-proof string initialization,
|
||||
* if ever necessary.
|
||||
|
|
|
@ -4,20 +4,31 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export type FontValue = typeof fonts[number]['value'];
|
||||
/**
|
||||
* This type contains a unions of all supported font labels, or the the name of
|
||||
* the font the user would see in a UI.
|
||||
*/
|
||||
export type FontLabel = typeof fonts[number]['label'];
|
||||
|
||||
/**
|
||||
* This type contains a union of all supported font values, equivalent to the CSS
|
||||
* `font-value` property.
|
||||
*/
|
||||
export type FontValue = typeof fonts[number]['value'];
|
||||
|
||||
/**
|
||||
* An interface representing a font in Canvas, with a textual label and the CSS
|
||||
* `font-value`.
|
||||
*/
|
||||
export interface Font {
|
||||
label: FontLabel;
|
||||
value: FontValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function allows one to create a strongly-typed font for inclusion in
|
||||
* the font collection. As a result, the values and labels are known to the
|
||||
* type system, preventing one from specifying a non-existent font at build
|
||||
* time.
|
||||
*/
|
||||
// This function allows one to create a strongly-typed font for inclusion in
|
||||
// the font collection. As a result, the values and labels are known to the
|
||||
// type system, preventing one from specifying a non-existent font at build
|
||||
// time.
|
||||
function createFont<
|
||||
RawFont extends { value: RawFontValue; label: RawFontLabel },
|
||||
RawFontValue extends string,
|
||||
|
@ -104,6 +115,9 @@ export const palatino = createFont({
|
|||
value: "Palatino, 'Book Antiqua', Georgia, Garamond, 'Times New Roman', Times, serif",
|
||||
});
|
||||
|
||||
/**
|
||||
* A collection of supported fonts.
|
||||
*/
|
||||
export const fonts = [
|
||||
americanTypewriter,
|
||||
arial,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue