theme function (#73451)
This commit is contained in:
parent
910c883607
commit
0ef17f92a6
|
@ -64,7 +64,7 @@ export const font: ExpressionFunctionFont = {
|
|||
inputTypes: ['null'],
|
||||
args: {
|
||||
align: {
|
||||
default: 'left',
|
||||
default: '{ theme "font.align" default="left" }',
|
||||
help: i18n.translate('expressions.functions.font.args.alignHelpText', {
|
||||
defaultMessage: 'The horizontal text alignment.',
|
||||
}),
|
||||
|
@ -72,13 +72,14 @@ export const font: ExpressionFunctionFont = {
|
|||
types: ['string'],
|
||||
},
|
||||
color: {
|
||||
default: `{ theme "font.color" }`,
|
||||
help: i18n.translate('expressions.functions.font.args.colorHelpText', {
|
||||
defaultMessage: 'The text color.',
|
||||
}),
|
||||
types: ['string'],
|
||||
},
|
||||
family: {
|
||||
default: `"${openSans.value}"`,
|
||||
default: `{ theme "font.family" default="${openSans.value}" }`,
|
||||
help: i18n.translate('expressions.functions.font.args.familyHelpText', {
|
||||
defaultMessage: 'An acceptable {css} web font string',
|
||||
values: {
|
||||
|
@ -88,7 +89,7 @@ export const font: ExpressionFunctionFont = {
|
|||
types: ['string'],
|
||||
},
|
||||
italic: {
|
||||
default: false,
|
||||
default: `{ theme "font.italic" default=false }`,
|
||||
help: i18n.translate('expressions.functions.font.args.italicHelpText', {
|
||||
defaultMessage: 'Italicize the text?',
|
||||
}),
|
||||
|
@ -96,7 +97,7 @@ export const font: ExpressionFunctionFont = {
|
|||
types: ['boolean'],
|
||||
},
|
||||
lHeight: {
|
||||
default: null,
|
||||
default: `{ theme "font.lHeight" }`,
|
||||
aliases: ['lineHeight'],
|
||||
help: i18n.translate('expressions.functions.font.args.lHeightHelpText', {
|
||||
defaultMessage: 'The line height in pixels',
|
||||
|
@ -104,14 +105,14 @@ export const font: ExpressionFunctionFont = {
|
|||
types: ['number', 'null'],
|
||||
},
|
||||
size: {
|
||||
default: 14,
|
||||
default: `{ theme "font.size" default=14 }`,
|
||||
help: i18n.translate('expressions.functions.font.args.sizeHelpText', {
|
||||
defaultMessage: 'The font size in pixels',
|
||||
}),
|
||||
types: ['number'],
|
||||
},
|
||||
underline: {
|
||||
default: false,
|
||||
default: `{ theme "font.underline" default=false }`,
|
||||
help: i18n.translate('expressions.functions.font.args.underlineHelpText', {
|
||||
defaultMessage: 'Underline the text?',
|
||||
}),
|
||||
|
@ -119,7 +120,7 @@ export const font: ExpressionFunctionFont = {
|
|||
types: ['boolean'],
|
||||
},
|
||||
weight: {
|
||||
default: 'normal',
|
||||
default: `{ theme "font.weight" default="normal" }`,
|
||||
help: i18n.translate('expressions.functions.font.args.weightHelpText', {
|
||||
defaultMessage: 'The font weight. For example, {list}, or {end}.',
|
||||
values: {
|
||||
|
|
|
@ -24,6 +24,7 @@ import { kibanaContextFunction } from './kibana_context';
|
|||
import { variableSet } from './var_set';
|
||||
import { variable } from './var';
|
||||
import { AnyExpressionFunctionDefinition } from '../types';
|
||||
import { theme } from './theme';
|
||||
|
||||
export const functionSpecs: AnyExpressionFunctionDefinition[] = [
|
||||
clog,
|
||||
|
@ -32,6 +33,7 @@ export const functionSpecs: AnyExpressionFunctionDefinition[] = [
|
|||
kibanaContextFunction,
|
||||
variableSet,
|
||||
variable,
|
||||
theme,
|
||||
];
|
||||
|
||||
export * from './clog';
|
||||
|
@ -40,3 +42,4 @@ export * from './kibana';
|
|||
export * from './kibana_context';
|
||||
export * from './var_set';
|
||||
export * from './var';
|
||||
export * from './theme';
|
||||
|
|
|
@ -24,8 +24,19 @@ import { functionWrapper } from './utils';
|
|||
describe('font', () => {
|
||||
const fn = functionWrapper(font);
|
||||
|
||||
const args = {
|
||||
align: 'left',
|
||||
color: null,
|
||||
family: openSans.value,
|
||||
italic: false,
|
||||
lHeight: null,
|
||||
size: 14,
|
||||
underline: false,
|
||||
weight: 'normal',
|
||||
};
|
||||
|
||||
describe('default output', () => {
|
||||
const result = fn(null);
|
||||
const result = fn(null, args);
|
||||
|
||||
it('returns a style', () => {
|
||||
expect(result).toMatchObject({
|
||||
|
@ -39,7 +50,7 @@ describe('font', () => {
|
|||
describe('args', () => {
|
||||
describe('size', () => {
|
||||
it('sets font size', () => {
|
||||
const result = fn(null, { size: 20 });
|
||||
const result = fn(null, { ...args, size: 20 });
|
||||
expect(result).toMatchObject({
|
||||
spec: {
|
||||
fontSize: '20px',
|
||||
|
@ -47,21 +58,11 @@ describe('font', () => {
|
|||
});
|
||||
expect(result.css).toContain('font-size:20px');
|
||||
});
|
||||
|
||||
it('defaults to 14px', () => {
|
||||
const result = fn(null);
|
||||
expect(result).toMatchObject({
|
||||
spec: {
|
||||
fontSize: '14px',
|
||||
},
|
||||
});
|
||||
expect(result.css).toContain('font-size:14px');
|
||||
});
|
||||
});
|
||||
|
||||
describe('lHeight', () => {
|
||||
it('sets line height', () => {
|
||||
const result = fn(null, { lHeight: 30 });
|
||||
const result = fn(null, { ...args, lHeight: 30 });
|
||||
expect(result).toMatchObject({
|
||||
spec: {
|
||||
lineHeight: '30px',
|
||||
|
@ -69,31 +70,19 @@ describe('font', () => {
|
|||
});
|
||||
expect(result.css).toContain('line-height:30px');
|
||||
});
|
||||
|
||||
it('defaults to 1', () => {
|
||||
const result = fn(null);
|
||||
expect(result.spec.lineHeight).toBe('1');
|
||||
expect(result.css).toContain('line-height:1');
|
||||
});
|
||||
});
|
||||
|
||||
describe('family', () => {
|
||||
it('sets font family', () => {
|
||||
const result = fn(null, { family: 'Optima, serif' });
|
||||
const result = fn(null, { ...args, family: 'Optima, serif' });
|
||||
expect(result.spec.fontFamily).toBe('Optima, serif');
|
||||
expect(result.css).toContain('font-family:Optima, serif');
|
||||
});
|
||||
|
||||
it(`defaults to "${openSans.value}"`, () => {
|
||||
const result = fn(null);
|
||||
expect(result.spec.fontFamily).toBe(`"${openSans.value}"`);
|
||||
expect(result.css).toContain(`font-family:"${openSans.value}"`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('color', () => {
|
||||
it('sets font color', () => {
|
||||
const result = fn(null, { color: 'blue' });
|
||||
const result = fn(null, { ...args, color: 'blue' });
|
||||
expect(result.spec.color).toBe('blue');
|
||||
expect(result.css).toContain('color:blue');
|
||||
});
|
||||
|
@ -101,51 +90,39 @@ describe('font', () => {
|
|||
|
||||
describe('weight', () => {
|
||||
it('sets font weight', () => {
|
||||
let result = fn(null, { weight: 'normal' });
|
||||
let result = fn(null, { ...args, weight: 'normal' });
|
||||
expect(result.spec.fontWeight).toBe('normal');
|
||||
expect(result.css).toContain('font-weight:normal');
|
||||
|
||||
result = fn(null, { weight: 'bold' });
|
||||
result = fn(null, { ...args, weight: 'bold' });
|
||||
expect(result.spec.fontWeight).toBe('bold');
|
||||
expect(result.css).toContain('font-weight:bold');
|
||||
|
||||
result = fn(null, { weight: 'bolder' });
|
||||
result = fn(null, { ...args, weight: 'bolder' });
|
||||
expect(result.spec.fontWeight).toBe('bolder');
|
||||
expect(result.css).toContain('font-weight:bolder');
|
||||
|
||||
result = fn(null, { weight: 'lighter' });
|
||||
result = fn(null, { ...args, weight: 'lighter' });
|
||||
expect(result.spec.fontWeight).toBe('lighter');
|
||||
expect(result.css).toContain('font-weight:lighter');
|
||||
|
||||
result = fn(null, { weight: '400' });
|
||||
result = fn(null, { ...args, weight: '400' });
|
||||
expect(result.spec.fontWeight).toBe('400');
|
||||
expect(result.css).toContain('font-weight:400');
|
||||
});
|
||||
|
||||
it("defaults to 'normal'", () => {
|
||||
const result = fn(null);
|
||||
expect(result.spec.fontWeight).toBe('normal');
|
||||
expect(result.css).toContain('font-weight:normal');
|
||||
});
|
||||
|
||||
it('throws when provided an invalid weight', () => {
|
||||
expect(() => fn(null, { weight: 'foo' })).toThrow();
|
||||
expect(() => fn(null, { ...args, weight: 'foo' })).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('underline', () => {
|
||||
it('sets text underline', () => {
|
||||
let result = fn(null, { underline: true });
|
||||
let result = fn(null, { ...args, underline: true });
|
||||
expect(result.spec.textDecoration).toBe('underline');
|
||||
expect(result.css).toContain('text-decoration:underline');
|
||||
|
||||
result = fn(null, { underline: false });
|
||||
expect(result.spec.textDecoration).toBe('none');
|
||||
expect(result.css).toContain('text-decoration:none');
|
||||
});
|
||||
|
||||
it('defaults to false', () => {
|
||||
const result = fn(null);
|
||||
result = fn(null, { ...args, underline: false });
|
||||
expect(result.spec.textDecoration).toBe('none');
|
||||
expect(result.css).toContain('text-decoration:none');
|
||||
});
|
||||
|
@ -153,17 +130,11 @@ describe('font', () => {
|
|||
|
||||
describe('italic', () => {
|
||||
it('sets italic', () => {
|
||||
let result = fn(null, { italic: true });
|
||||
let result = fn(null, { ...args, italic: true });
|
||||
expect(result.spec.fontStyle).toBe('italic');
|
||||
expect(result.css).toContain('font-style:italic');
|
||||
|
||||
result = fn(null, { italic: false });
|
||||
expect(result.spec.fontStyle).toBe('normal');
|
||||
expect(result.css).toContain('font-style:normal');
|
||||
});
|
||||
|
||||
it('defaults to false', () => {
|
||||
const result = fn(null);
|
||||
result = fn(null, { ...args, italic: false });
|
||||
expect(result.spec.fontStyle).toBe('normal');
|
||||
expect(result.css).toContain('font-style:normal');
|
||||
});
|
||||
|
@ -171,31 +142,25 @@ describe('font', () => {
|
|||
|
||||
describe('align', () => {
|
||||
it('sets text alignment', () => {
|
||||
let result = fn(null, { align: 'left' });
|
||||
let result = fn(null, { ...args, align: 'left' });
|
||||
expect(result.spec.textAlign).toBe('left');
|
||||
expect(result.css).toContain('text-align:left');
|
||||
|
||||
result = fn(null, { align: 'center' });
|
||||
result = fn(null, { ...args, align: 'center' });
|
||||
expect(result.spec.textAlign).toBe('center');
|
||||
expect(result.css).toContain('text-align:center');
|
||||
|
||||
result = fn(null, { align: 'right' });
|
||||
result = fn(null, { ...args, align: 'right' });
|
||||
expect(result.spec.textAlign).toBe('right');
|
||||
expect(result.css).toContain('text-align:right');
|
||||
|
||||
result = fn(null, { align: 'justify' });
|
||||
result = fn(null, { ...args, align: 'justify' });
|
||||
expect(result.spec.textAlign).toBe('justify');
|
||||
expect(result.css).toContain('text-align:justify');
|
||||
});
|
||||
|
||||
it(`defaults to 'left'`, () => {
|
||||
const result = fn(null);
|
||||
expect(result.spec.textAlign).toBe('left');
|
||||
expect(result.css).toContain('text-align:left');
|
||||
});
|
||||
|
||||
it('throws when provided an invalid alignment', () => {
|
||||
expect(() => fn(null, { align: 'foo' })).toThrow();
|
||||
expect(() => fn(null, { ...args, align: 'foo' })).toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { functionWrapper } from './utils';
|
||||
import { theme } from '../theme';
|
||||
import { ExecutionContext } from '../../../execution/types';
|
||||
|
||||
describe('expression_functions', () => {
|
||||
describe('theme', () => {
|
||||
const fn = functionWrapper(theme);
|
||||
let context: ExecutionContext;
|
||||
|
||||
let themeProps;
|
||||
|
||||
beforeEach(() => {
|
||||
themeProps = {
|
||||
font: {
|
||||
family: 'Arial',
|
||||
size: 14,
|
||||
},
|
||||
};
|
||||
|
||||
context = {
|
||||
getInitialInput: () => {},
|
||||
types: {},
|
||||
variables: { theme: themeProps },
|
||||
abortSignal: {} as any,
|
||||
inspectorAdapters: {} as any,
|
||||
};
|
||||
});
|
||||
|
||||
it('returns the selected variable', () => {
|
||||
const actual = fn(null, { variable: 'font.family' }, context);
|
||||
expect(actual).toEqual('Arial');
|
||||
});
|
||||
|
||||
it('returns undefined if variable does not exist', () => {
|
||||
const actual = fn(null, { variable: 'font.weight' }, context);
|
||||
expect(actual).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('returns default if variable does not exist and default is provided', () => {
|
||||
const actual = fn(null, { variable: 'font.weight', default: 'normal' }, context);
|
||||
expect(actual).toEqual('normal');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch B.V. under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch B.V. licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { get } from 'lodash';
|
||||
import { ExpressionFunctionDefinition } from '../types';
|
||||
|
||||
interface Arguments {
|
||||
variable: string;
|
||||
default: string | number | boolean;
|
||||
}
|
||||
|
||||
type Output = any;
|
||||
|
||||
export type ExpressionFunctionTheme = ExpressionFunctionDefinition<
|
||||
'theme',
|
||||
null,
|
||||
Arguments,
|
||||
Output
|
||||
>;
|
||||
|
||||
export const theme: ExpressionFunctionTheme = {
|
||||
name: 'theme',
|
||||
aliases: [],
|
||||
help: i18n.translate('expressions.functions.themeHelpText', {
|
||||
defaultMessage: 'Reads a theme setting.',
|
||||
}),
|
||||
inputTypes: ['null'],
|
||||
args: {
|
||||
variable: {
|
||||
aliases: ['_'],
|
||||
help: i18n.translate('expressions.functions.theme.args.variableHelpText', {
|
||||
defaultMessage: 'Name of the theme variable to read.',
|
||||
}),
|
||||
required: true,
|
||||
types: ['string'],
|
||||
},
|
||||
default: {
|
||||
help: i18n.translate('expressions.functions.theme.args.defaultHelpText', {
|
||||
defaultMessage: 'default value in case theming info is not available.',
|
||||
}),
|
||||
},
|
||||
},
|
||||
fn: (input, args, handlers) => {
|
||||
// currently we use variable `theme`, but external theme service would be preferable
|
||||
const vars = handlers.variables.theme || {};
|
||||
return get(vars, args.variable, args.default);
|
||||
},
|
||||
};
|
|
@ -28,6 +28,7 @@ import {
|
|||
ExpressionFunctionKibana,
|
||||
ExpressionFunctionVarSet,
|
||||
ExpressionFunctionVar,
|
||||
ExpressionFunctionTheme,
|
||||
} from './specs';
|
||||
|
||||
/**
|
||||
|
@ -122,4 +123,5 @@ export interface ExpressionFunctionDefinitions {
|
|||
kibana: ExpressionFunctionKibana;
|
||||
var_set: ExpressionFunctionVarSet;
|
||||
var: ExpressionFunctionVar;
|
||||
theme: ExpressionFunctionTheme;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue