mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Add Markdown cell format
Summary: Text columns can now display their values as Markdown-formatted text by changing their cell format to "Markdown". A minimal subset of the Markdown specification is currently supported. Test Plan: Browser tests. Reviewers: Spoffy, dsagal Reviewed By: Spoffy, dsagal Subscribers: dsagal, Spoffy Differential Revision: https://phab.getgrist.com/D4326
This commit is contained in:
@@ -23,6 +23,7 @@ export type IconName = "ChartArea" |
|
||||
"FieldFunctionEqual" |
|
||||
"FieldInteger" |
|
||||
"FieldLink" |
|
||||
"FieldMarkdown" |
|
||||
"FieldNumeric" |
|
||||
"FieldReference" |
|
||||
"FieldSpinner" |
|
||||
@@ -185,6 +186,7 @@ export const IconList: IconName[] = ["ChartArea",
|
||||
"FieldFunctionEqual",
|
||||
"FieldInteger",
|
||||
"FieldLink",
|
||||
"FieldMarkdown",
|
||||
"FieldNumeric",
|
||||
"FieldReference",
|
||||
"FieldSpinner",
|
||||
|
||||
@@ -895,6 +895,13 @@ export const theme = {
|
||||
undefined, colors.slate),
|
||||
widgetGallerySecondaryHeaderBgHover: new CustomProp(
|
||||
'theme-widget-gallery-secondary-header-bg-hover', undefined, '#7E7E85'),
|
||||
|
||||
/* Markdown Cell */
|
||||
markdownCellLightBg: new CustomProp('theme-markdown-cell-light-bg', undefined, colors.lightGrey),
|
||||
markdownCellLightBorder: new CustomProp('theme-markdown-cell-light-border', undefined,
|
||||
colors.mediumGreyOpaque),
|
||||
markdownCellMediumBorder: new CustomProp('theme-markdown-cell-medium-border', undefined,
|
||||
colors.darkGrey),
|
||||
};
|
||||
|
||||
const cssColors = values(colors).map(v => v.decl()).join('\n');
|
||||
|
||||
@@ -56,7 +56,7 @@ import { IconName } from './IconList';
|
||||
/**
|
||||
* Defaults for all icons.
|
||||
*/
|
||||
const iconDiv = styled('div', `
|
||||
const iconStyles = `
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
@@ -66,24 +66,35 @@ const iconDiv = styled('div', `
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: var(--icon-color, var(--grist-theme-text, black));
|
||||
`);
|
||||
`;
|
||||
|
||||
export const cssIconBackground = styled(iconDiv, `
|
||||
background-color: var(--icon-background, inherit);
|
||||
-webkit-mask: none;
|
||||
& .${iconDiv.className} {
|
||||
transition: inherit;
|
||||
display: block;
|
||||
}
|
||||
`);
|
||||
const cssIconDiv = styled('div', iconStyles);
|
||||
|
||||
const cssIconSpan = styled('span', iconStyles);
|
||||
|
||||
export function icon(name: IconName, ...domArgs: DomElementArg[]): HTMLElement {
|
||||
return iconDiv(
|
||||
return cssIconDiv(
|
||||
dom.style('-webkit-mask-image', `var(--icon-${name})`),
|
||||
...domArgs
|
||||
);
|
||||
}
|
||||
|
||||
export function iconSpan(name: IconName, ...domArgs: DomElementArg[]): HTMLElement {
|
||||
return cssIconSpan(
|
||||
dom.style('-webkit-mask-image', `var(--icon-${name})`),
|
||||
...domArgs
|
||||
);
|
||||
}
|
||||
|
||||
export const cssIconSpanBackground = styled(cssIconSpan, `
|
||||
background-color: var(--icon-background, inherit);
|
||||
-webkit-mask: none;
|
||||
& .${cssIconSpan.className} {
|
||||
transition: inherit;
|
||||
display: block;
|
||||
}
|
||||
`);
|
||||
|
||||
/**
|
||||
* Container box for an icon to serve as a button..
|
||||
*/
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {findLinks} from 'app/client/lib/textUtils';
|
||||
import { sameDocumentUrlState, urlState } from 'app/client/models/gristUrlState';
|
||||
import { hideInPrintView, testId, theme } from 'app/client/ui2018/cssVars';
|
||||
import {cssIconBackground, icon} from 'app/client/ui2018/icons';
|
||||
import { CellValue } from 'app/plugin/GristData';
|
||||
import { dom, DomArg, IDomArgs, Observable, styled } from 'grainjs';
|
||||
import {sameDocumentUrlState, urlState} from 'app/client/models/gristUrlState';
|
||||
import {hideInPrintView, testId, theme} from 'app/client/ui2018/cssVars';
|
||||
import {cssIconSpanBackground, iconSpan} from 'app/client/ui2018/icons';
|
||||
import {CellValue} from 'app/plugin/GristData';
|
||||
import {dom, DomArg, IDomArgs, Observable, styled} from 'grainjs';
|
||||
|
||||
/**
|
||||
* Styling for a simple <A HREF> link.
|
||||
@@ -37,6 +37,19 @@ export function gristLink(href: string|Observable<string>, ...args: IDomArgs<HTM
|
||||
);
|
||||
}
|
||||
|
||||
export function gristIconLink(href: string, label = href) {
|
||||
return cssMaybeWrap(
|
||||
gristLink(href,
|
||||
cssIconSpanBackground(
|
||||
iconSpan("FieldLink", testId('tb-link-icon')),
|
||||
dom.cls(cssHoverInText.className),
|
||||
),
|
||||
),
|
||||
linkColor(label),
|
||||
testId("text-link"),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* If possible (i.e. if `url` points to somewhere in the current document)
|
||||
* use pushUrl to navigate without reloading or opening a new tab
|
||||
@@ -60,17 +73,7 @@ export function makeLinks(text: string) {
|
||||
const domElements: DomArg[] = [];
|
||||
for (const {value, isLink} of findLinks(text)) {
|
||||
if (isLink) {
|
||||
// Wrap link with a span to provide hover on and to override wrapping.
|
||||
domElements.push(cssMaybeWrap(
|
||||
gristLink(value,
|
||||
cssIconBackground(
|
||||
icon("FieldLink", testId('tb-link-icon')),
|
||||
dom.cls(cssHoverInText.className),
|
||||
),
|
||||
),
|
||||
linkColor(value),
|
||||
testId("text-link")
|
||||
));
|
||||
domElements.push(gristIconLink(value));
|
||||
} else {
|
||||
domElements.push(value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user