Skip to content

Commit

Permalink
use only markdown for links
Browse files Browse the repository at this point in the history
* add optional parameter "target" to specify whether it should open in a new tab
  • Loading branch information
aalencar committed Apr 28, 2022
1 parent 0d9b982 commit 3bbc4b8
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 51 deletions.
14 changes: 6 additions & 8 deletions py/examples/table_markdown_links.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Table / Markdown / Links
# Creates a table with relative and absolute links.
# Creates a table with Markdown link that open in new tab
# #table #markdown #links
# ---

Expand All @@ -9,19 +9,17 @@
@app('/demo')
async def serve(q: Q):

q.page['example'] = ui.form_card(box='1 1 5 3', items=[
q.page['example'] = ui.form_card(box='1 1 3 3', items=[
ui.text_xl(content='Table with Markdown links'),
ui.table(
name='table',
columns=[
ui.table_column(name='description', label='Description', min_width="200"),
ui.table_column(name='newtab', label='Open in new tab'),
ui.table_column(name='markdown', label='Link',
cell_type=ui.markdown_table_cell_type())
ui.table_column(name='description', label='URL type'),
ui.table_column(name='markdown', label='Link', cell_type=ui.markdown_table_cell_type(target='_blank'))
],
rows=[
ui.table_row(name='row1', cells=['Absolute URL', 'Yes', '[Wave](http://wave.h2o.ai/)']),
ui.table_row(name='row2', cells=['Relative URL', 'No', '[Go to /wave](wave)']),
ui.table_row(name='row1', cells=['Absolute', '[Wave website](http://wave.h2o.ai/)']),
ui.table_row(name='row1', cells=['Reative', '[Go to /wave](/wave)']),
]
)
])
Expand Down
10 changes: 10 additions & 0 deletions py/h2o_wave/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -3229,26 +3229,36 @@ class MarkdownTableCellType:
def __init__(
self,
name: Optional[str] = None,
target: Optional[str] = None,
):
_guard_scalar('MarkdownTableCellType.name', name, (str,), False, True, False)
_guard_scalar('MarkdownTableCellType.target', target, (str,), False, True, False)
self.name = name
"""An identifying name for this component."""
self.target = target
"""Where to display the link. Setting this to '_blank'` opens the link in a new tab or window."""

def dump(self) -> Dict:
"""Returns the contents of this object as a dict."""
_guard_scalar('MarkdownTableCellType.name', self.name, (str,), False, True, False)
_guard_scalar('MarkdownTableCellType.target', self.target, (str,), False, True, False)
return _dump(
name=self.name,
target=self.target,
)

@staticmethod
def load(__d: Dict) -> 'MarkdownTableCellType':
"""Creates an instance of this class using the contents of a dict."""
__d_name: Any = __d.get('name')
_guard_scalar('MarkdownTableCellType.name', __d_name, (str,), False, True, False)
__d_target: Any = __d.get('target')
_guard_scalar('MarkdownTableCellType.target', __d_target, (str,), False, True, False)
name: Optional[str] = __d_name
target: Optional[str] = __d_target
return MarkdownTableCellType(
name,
target,
)


Expand Down
3 changes: 3 additions & 0 deletions py/h2o_wave/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -1265,16 +1265,19 @@ def menu_table_cell_type(

def markdown_table_cell_type(
name: Optional[str] = None,
target: Optional[str] = None,
) -> TableCellType:
"""Create a cell type that renders Markdown content.
Args:
name: An identifying name for this component.
target: Where to display the link. Setting this to '_blank'` opens the link in a new tab or window.
Returns:
A `h2o_wave.types.MarkdownTableCellType` instance.
"""
return TableCellType(markdown=MarkdownTableCellType(
name,
target,
))


Expand Down
8 changes: 6 additions & 2 deletions r/R/ui.R
Original file line number Diff line number Diff line change
Expand Up @@ -1475,13 +1475,17 @@ ui_menu_table_cell_type <- function(
#' Create a cell type that renders Markdown content.
#'
#' @param name An identifying name for this component.
#' @param target Where to display the link. Setting this to '_blank'` opens the link in a new tab or window.
#' @return A MarkdownTableCellType instance.
#' @export
ui_markdown_table_cell_type <- function(
name = NULL) {
name = NULL,
target = NULL) {
.guard_scalar("name", "character", name)
.guard_scalar("target", "character", target)
.o <- list(markdown=list(
name=name))
name=name,
target=target))
class(.o) <- append(class(.o), c(.wave_obj, "WaveTableCellType"))
return(.o)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1451,8 +1451,9 @@
<option name="Python" value="true"/>
</context>
</template>
<template name="w_full_markdown_table_cell_type" value="ui.markdown_table_cell_type(name='$name$'),$END$" description="Create Wave MarkdownTableCellType with full attributes." toReformat="true" toShortenFQNames="true">
<template name="w_full_markdown_table_cell_type" value="ui.markdown_table_cell_type(name='$name$',target='$target$'),$END$" description="Create Wave MarkdownTableCellType with full attributes." toReformat="true" toShortenFQNames="true">
<variable name="name" expression="" defaultValue="" alwaysStopAt="true"/>
<variable name="target" expression="" defaultValue="" alwaysStopAt="true"/>
<context>
<option name="Python" value="true"/>
</context>
Expand Down
2 changes: 1 addition & 1 deletion tools/vscode-extension/component-snippets.json
Original file line number Diff line number Diff line change
Expand Up @@ -1185,7 +1185,7 @@
"Wave Full MarkdownTableCellType": {
"prefix": "w_full_markdown_table_cell_type",
"body": [
"ui.markdown_table_cell_type(name='$1'),$0"
"ui.markdown_table_cell_type(name='$1', target='$2'),$0"
],
"description": "Create a full Wave MarkdownTableCellType."
},
Expand Down
32 changes: 11 additions & 21 deletions ui/src/markdown_table_cell_type.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,19 @@ import { render } from '@testing-library/react'
import React from 'react'
import { XMarkdownTableCellType } from './markdown_table_cell_type'

describe('MarkdownTableCellType.tsx', () => {

const
label = 'wave',
url = 'https://wave.h2o.ai',
absoluteLink = `[${label}](${url})`,
relativeLink = `[${label}](/wave)`
const
label = 'wave',
link = `[${label}](https://wave.h2o.ai)`

it('Renders link with label', () => {
const { queryByText } = render(<XMarkdownTableCellType content={absoluteLink} />)
expect(queryByText(label)).toBeInTheDocument()
expect(queryByText(url)).not.toBeInTheDocument()
})
describe('MarkdownTableCellType.tsx', () => {

it('Opens absolute links in new tab', () => {
const { container } = render(<XMarkdownTableCellType content={absoluteLink} />)
const anchor = container.querySelector(`a[href="${url}"]`) as HTMLAnchorElement
expect(anchor?.target).toBe('_blank')
it('Opens link in same tab', () => {
const { getByText } = render(<XMarkdownTableCellType model={{content: link}} />)
expect(getByText(label).getAttribute('target')).toBeNull()
})

it('Opens relative links in same tab', () => {
const { container } = render(<XMarkdownTableCellType content={relativeLink} />)
const anchor = container.querySelector(`a[href="${url}"]`) as HTMLAnchorElement
expect(anchor?.target).toBeUndefined()

it('Opens link in new tab', () => {
const { getByText } = render(<XMarkdownTableCellType model={{ target: '_blank', content: link }} />)
expect(getByText(label).getAttribute('target')).toBe('_blank')
})
})
24 changes: 15 additions & 9 deletions ui/src/markdown_table_cell_type.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import { S } from 'h2o-wave'
import React from 'react'
import { XLink } from './link'
import { Markdown } from './markdown'

/**
Expand All @@ -23,14 +22,21 @@ import { Markdown } from './markdown'
export interface MarkdownTableCellType {
/** An identifying name for this component. */
name?: S
/** Where to display the link. Setting this to '_blank'` opens the link in a new tab or window. */
target?: S
}

export const XMarkdownTableCellType = ({ content }: { content: S}) => {
const [, label, path] = /\[(.*)\]\((.+)\)/.exec(content) || []
if (path) {
const isPathAbsolute = /https*:\/\//.exec(path)
return <XLink model={{ label, path, target: isPathAbsolute ? '_blank' : undefined }} />
} else {
return <Markdown source={content} />
}
export const XMarkdownTableCellType = ({ model: m }: { model: MarkdownTableCellType & { content: S}} ) => {
const ref = React.useRef<HTMLDivElement>(null)

React.useEffect(() => {
const anchors = document.querySelectorAll<HTMLAnchorElement>('a')
anchors?.forEach(a => {if (m.target) a.target = m.target})
}, [m.target])

return (
<div data-test={m.name} ref={ref}>
<Markdown source={m.content} />
</div>
)
}
2 changes: 1 addition & 1 deletion ui/src/table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ const
if (col.cellType?.icon) return <XIconTableCellType model={col.cellType.icon} icon={item[col.key]} />
if (col.cellType?.tag) return <XTagTableCellType model={col.cellType.tag} serializedTags={item[col.key]} />
if (col.cellType?.menu) return <XMenuTableCellType model={{...col.cellType.menu, rowId: String(item.key)}} />
if (col.cellType?.markdown) return <XMarkdownTableCellType content={item[col.key]} />
if (col.cellType?.markdown) return <XMarkdownTableCellType model={{...col.cellType.markdown, content: item[col.key]}}/>
if (col.dataType === 'time') v = new Date(v).toLocaleString()
if (col.key === primaryColumnKey && !isMultiple) {
const onClick = () => {
Expand Down
Binary file modified website/docs/examples/assets/table-markdown-links.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 4 additions & 8 deletions website/widgets/form/table.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,22 +378,18 @@ Leverage the power and versatility of [Markdown](https://www.markdownguide.org/)

### Links

To open in a new tab use absolute links.
To open links in a new tab use `target='_blank'`.

```py
q.page['example'] = ui.form_card(box='1 1 5 5', items=[
q.page['example'] = ui.form_card(box='1 1 3 2', items=[
ui.text_xl(content='Table with Markdown links'),
ui.table(
name='table',
columns=[
ui.table_column(name='description', label='Description', min_width="200"),
ui.table_column(name='newtab', label='Open in new tab'),
ui.table_column(name='markdown', label='Link',
cell_type=ui.markdown_table_cell_type())
ui.table_column(name='markdown', label='Link', cell_type=ui.markdown_table_cell_type(target='_blank'))
],
rows=[
ui.table_row(name='row1', cells=['Absolute URL', 'Yes', '[Wave](http://wave.h2o.ai/)']),
ui.table_row(name='row2', cells=['Relative URL', 'No', '[Go to /wave](wave)']),
ui.table_row(name='row1', cells=['[Wave](http://wave.h2o.ai/)']),
]
)
])
Expand Down

0 comments on commit 3bbc4b8

Please sign in to comment.