Skip to content

Commit

Permalink
work on demo
Browse files Browse the repository at this point in the history
  • Loading branch information
bollwyvl committed Nov 13, 2024
1 parent d871908 commit 0180288
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 45 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ Once the data is _validated_, the user sees a button which gets a URL, which can

## Install

> See the [contributing guide][contrib] for a development install.
[contrib]: https://github.com/deathbeds/urljsf/blob/main/CONTRIBUTING.md

### From PyPI
Expand Down Expand Up @@ -96,6 +94,10 @@ mamba install -c conda-forge urljsf
conda install -c conda-forge urljsf
```

### Development

See the [contributing guide][contrib] for a development install.

## Usage

`urljsf` work with some [JSON schema](#json-schema) constrained files as a:
Expand Down
61 changes: 61 additions & 0 deletions docs/demo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
[forms.demo.schema]
type = "object"

[forms.demo.schema.properties.learn_more]
title = "Learn more?"
type = "string"
enum = ["Nah.", "A little..."]

[forms.demo.schema.dependencies.learn_more]
oneOf = [
{"$ref" = "#/definitions/nah"},
{"$ref" = "#/definitions/more"},
]

[forms.demo.schema.definitions.nah.properties]
learn_more = {type = "string", enum = ["Nah."]}

[forms.demo.schema.definitions.more.properties]
learn_more = {type = "string", enum = ["A little..."]}
topic = {title = "Still more?", type = "string", description = """
`urljsf` is a tool for building forms (like this one) out of JSON (or TOML or YAML).
> Pick something to learn more about
""", enum = [
"Install",
"Usage",
"Limitations",
"Open Source",
"Documentation Contents",
]}

[forms.demo.schema.definitions]
[forms.demo.ui_schema.learn_more."ui:options"]
widget = "radio"
inline = true

[style."& > .list-group > .list-group-item:first-child"]
background = "url(./_static/logo.svg)"
background-size = "6em"
background-position = "98% 0.5em"
background-repeat = "no-repeat"


[templates]
url = """#{{ data.demo.topic | default("urljsf") | replace(" ", "-") | lower }}"""
submit_button = """
{% if data.demo.learn_more %}
Skip to {{ data.demo.topic | default('Main Content') }}
{% endif %}
"""
above_demo = """
What is this?
> Find out with this demo (or one of the other [demos](demos/index.html)), or
> scroll down to learn more.
"""


[nunjucks]
filters = ["toml", "yaml", "json"]
4 changes: 3 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<img src="_static/logo.svg" alt="a wordmark with an icon" class="dark-light" />
```{urljsf} demo.toml

```

# `urljsf`

Expand Down
16 changes: 13 additions & 3 deletions docs/use/advanced/templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,22 @@ The `templates.url` field should generate a valid URL. All whitespace should be

#### `submit_button`

The text to show on the submit button, if all `checks` and schema validation are
successful.
Markdown to show on the submit button, if all `checks` and schema validation are
successful. If this evaluates to the empty string, no submit button will be shown.

#### `submit_target`

The [`target`][target] for the `submit_button`. If an empty string, the default behavior
of replacing the current page will be used.

- use `_blank` to open a new browser tab
- use the name of an `<iframe name="some-iframe">` to replace that `iframe`'s content

[target]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLAnchorElement/target

#### `download_filename`

A filename to suggest for `data:` URLs.
A filename to suggest for `data:` URLs when the `submit_button` is shown.

#### `above_{form}`

Expand Down
13 changes: 9 additions & 4 deletions js/schema/form.schema.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,20 @@ type = "object"

[definitions.known-templates.properties]
url = {"$ref" = "#/definitions/any-template", description = """
a URL to build. all whitespace will be trimmed, then joined with no delimiter.
a URL to apply to the submit button. All whitespace will be removed.
"""}
submit_button = {"$ref" = "#/definitions/any-template", description = """
text to show on the button when a form is valid. multiple lines will be joined
with `\\n`, then leading and trailing whitespace will be trimmed.
Markdown to show on the button when a form is valid. Multiple lines will be joined
with `\\n`. Leading and trailing whitespace will be trimmed. If empty,
no submit button will be shown.
"""}
submit_target = {"$ref" = "#/definitions/any-template", description = """
If given, the value of the `target` attribute on the `submit_button`. Use `_blank`
to open a new tab.
"""}
download_filename = {"$ref" = "#/definitions/any-template", description = """
If given, a template for the submit button's `download` attribute, to
suggest an appropriate filename, with leading and trailing whitespace trimmed.
suggest an appropriate filename. Leading and trailing whitespace will be trimmed.
"""}

[definitions.checks]
Expand Down
10 changes: 7 additions & 3 deletions js/schema/v0/form.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -525,15 +525,19 @@
"properties": {
"download_filename": {
"$ref": "#/definitions/any-template",
"description": "If given, a template for the submit button's `download` attribute, to\nsuggest an appropriate filename, with leading and trailing whitespace trimmed.\n"
"description": "If given, a template for the submit button's `download` attribute, to\nsuggest an appropriate filename. Leading and trailing whitespace will be trimmed.\n"
},
"submit_button": {
"$ref": "#/definitions/any-template",
"description": "text to show on the button when a form is valid. multiple lines will be joined\nwith `\\n`, then leading and trailing whitespace will be trimmed.\n"
"description": "Markdown to show on the button when a form is valid. Multiple lines will be joined\nwith `\\n`. Leading and trailing whitespace will be trimmed. If empty,\nno submit button will be shown.\n"
},
"submit_target": {
"$ref": "#/definitions/any-template",
"description": "If given, the value of the `target` attribute on the `submit_button`. Use `_blank`\nto open a new tab.\n"
},
"url": {
"$ref": "#/definitions/any-template",
"description": "a URL to build. all whitespace will be trimmed, then joined with no delimiter.\n"
"description": "a URL to apply to the submit button. All whitespace will be removed.\n"
}
}
},
Expand Down
15 changes: 11 additions & 4 deletions js/src/_schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -591,18 +591,25 @@ export interface Styles {
export interface KnownTemplates {
/**
* If given, a template for the submit button's `download` attribute, to
* suggest an appropriate filename, with leading and trailing whitespace trimmed.
* suggest an appropriate filename. Leading and trailing whitespace will be trimmed.
*
*/
download_filename?: string | [string, ...string[]];
/**
* text to show on the button when a form is valid. multiple lines will be joined
* with `\n`, then leading and trailing whitespace will be trimmed.
* Markdown to show on the button when a form is valid. Multiple lines will be joined
* with `\n`. Leading and trailing whitespace will be trimmed. If empty,
* no submit button will be shown.
*
*/
submit_button?: string | [string, ...string[]];
/**
* a URL to build. all whitespace will be trimmed, then joined with no delimiter.
* If given, the value of the `target` attribute on the `submit_button`. Use `_blank`
* to open a new tab.
*
*/
submit_target?: string | [string, ...string[]];
/**
* a URL to apply to the submit button. All whitespace will be removed.
*
*/
url?: string | [string, ...string[]];
Expand Down
69 changes: 41 additions & 28 deletions js/src/components/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { ensureBootstrap, getBoostrapCss } from '../bootstrap.js';
import { ensureNunjucks, renderMarkdown } from '../nunjucks.js';
import {
CHECKS_PATH_PREFIX,
DEBUG,
DEFAULTS,
FORM_CLASS,
IAboveBelowForms,
Expand Down Expand Up @@ -54,11 +55,8 @@ const BTN_COMMON: Pick<ButtonProps, 'size' | 'className'> = {

const SUBMIT_DEFAULT: Pick<ButtonProps, 'variant' | 'target'> = {
variant: 'success',
target: '_blank',
};

const DEFAULT_SUBMIT = 'Submit';

/** process a single form
*
* @param script - a DOM script with a urljsf mime type
Expand Down Expand Up @@ -140,7 +138,7 @@ function UrljsfForm(props: IUrljsfFormProps): JSX.Element {
_url = nunjucksEnv.render('url', context.value).replace(/\s\n/, '');
} catch (err) {
/* istanbul ignore next */
console.warn('Could not render URL', err);
DEBUG && console.warn('Could not render URL', err);
}
return _url;
});
Expand All @@ -151,7 +149,18 @@ function UrljsfForm(props: IUrljsfFormProps): JSX.Element {
name = nunjucksEnv.render('download_filename', context.value).trim();
} catch (err) {
/* istanbul ignore next */
console.warn('Could not render download filename', err);
DEBUG && console.warn('Could not render download filename', err);
}
return name;
});

const linkTarget = computed(() => {
let name = '';
try {
name = nunjucksEnv.render('submit_target', context.value).trim();
} catch (err) {
/* istanbul ignore next */
DEBUG && console.warn('Could not render link target', err);
}
return name;
});
Expand All @@ -161,7 +170,6 @@ function UrljsfForm(props: IUrljsfFormProps): JSX.Element {
path: 'submit_button',
context: context.value,
env: nunjucksEnv,
fallback: DEFAULT_SUBMIT,
}),
);

Expand All @@ -178,7 +186,7 @@ function UrljsfForm(props: IUrljsfFormProps): JSX.Element {
let hasAb = false;
for (const ab of ['above', 'below'] as (keyof IFormAboveBelow)[]) {
const abName = `${ab}_${key}`;
const tmpl = config.templates[abName];
const tmpl = (config.templates && config.templates[abName]) || null;
if (tmpl) {
formAb[ab] = makeAboveBelow(abName);
hasAb = true;
Expand Down Expand Up @@ -217,7 +225,7 @@ function UrljsfForm(props: IUrljsfFormProps): JSX.Element {
}).trim();
} catch (err) {
/* istanbul ignore next */
console.warn('Failed to check', label, err);
DEBUG && console.warn('Failed to check', label, err);
}

if (rendered) {
Expand Down Expand Up @@ -278,7 +286,7 @@ function UrljsfForm(props: IUrljsfFormProps): JSX.Element {
};

const URLJSF = () => {
let submitButton: JSX.Element;
let submitButton: JSX.Element[] = [];
const checkItems: JSX.Element[] = [];
const formItems: JSX.Element[] = [];

Expand Down Expand Up @@ -319,27 +327,32 @@ function UrljsfForm(props: IUrljsfFormProps): JSX.Element {
}

if (errorCount.value) {
submitButton = (
<Button onClick={onErrorClick} variant="danger" {...BTN_COMMON}>
{errorCount} Error{errorCount.value > 1 ? 's' : ''}
</Button>
);
} else {
submitButton = [
<li className="list-group-item">
<Button onClick={onErrorClick} variant="danger" {...BTN_COMMON}>
{errorCount} Error{errorCount.value > 1 ? 's' : ''}
</Button>
</li>,
];
} else if (submitText.value) {
const download = downloadFilename.value
? { download: downloadFilename.value }
: emptyObject;
submitButton = (
<Button
as="a"
href={url.value}
target="_blank"
{...SUBMIT_DEFAULT}
{...BTN_COMMON}
{...download}
>
<Markdown options={SUBMIT_MD_OPTIONS}>{submitText.value}</Markdown>
</Button>
);
const target = linkTarget.value ? { target: linkTarget.value } : emptyObject;
submitButton = [
<li className="list-group-item">
<Button
as="a"
href={url.value}
{...SUBMIT_DEFAULT}
{...BTN_COMMON}
{...download}
{...target}
>
<Markdown options={SUBMIT_MD_OPTIONS}>{submitText.value}</Markdown>
</Button>
</li>,
];
}

return (
Expand All @@ -348,7 +361,7 @@ function UrljsfForm(props: IUrljsfFormProps): JSX.Element {
<ul className="list-group">
{...formItems}
{...checkItems}
<li className="list-group-item">{submitButton}</li>
{...submitButton}
</ul>
</div>
);
Expand Down
1 change: 1 addition & 0 deletions pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ cmd = """taplo fmt
--option=column_width=88
--option=indent_string=" "
*.toml
docs/**/*.toml
js/demo/toml/*.toml
js/schema/*.toml
tests/fixtures/*/*/*/*.toml
Expand Down
1 change: 1 addition & 0 deletions scripts/vale/config/vocabularies/urljsf/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ showErrorList
src
stylesheet
submit_button
submit_target
tagName
textarea
theming
Expand Down
3 changes: 3 additions & 0 deletions src/urljsf/_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ class _TemplatesTyped(TypedDict, total=False):
submit_button: _AnyTemplate
""" Aggregation type: anyOf """

submit_target: _AnyTemplate
""" Aggregation type: anyOf """

url: _AnyTemplate
""" Aggregation type: anyOf """

Expand Down

0 comments on commit 0180288

Please sign in to comment.