Merge pull request #30 from Oliver-Akins/GH-19
Ask Application Block Improvements
This commit is contained in:
commit
ab14729e91
16 changed files with 182 additions and 35 deletions
|
|
@ -2,6 +2,15 @@ import { __ID__, filePath } from "../consts.mjs";
|
|||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
||||
const validInputTypes = [
|
||||
`checkbox`,
|
||||
`details`,
|
||||
`divider`,
|
||||
`error`,
|
||||
`input`,
|
||||
`select`,
|
||||
];
|
||||
|
||||
export class Ask extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
static DEFAULT_OPTIONS = {
|
||||
tag: `dialog`,
|
||||
|
|
@ -32,11 +41,7 @@ export class Ask extends HandlebarsApplicationMixin(ApplicationV2) {
|
|||
static PARTS = {
|
||||
inputs: {
|
||||
template: filePath(`templates/Ask/inputs.hbs`),
|
||||
templates: [
|
||||
filePath(`templates/Ask/inputs/checkbox.hbs`),
|
||||
filePath(`templates/Ask/inputs/details.hbs`),
|
||||
filePath(`templates/Ask/inputs/input.hbs`),
|
||||
],
|
||||
templates: validInputTypes.map(type => filePath(`templates/Ask/inputs/${type}.hbs`)),
|
||||
},
|
||||
controls: {
|
||||
template: filePath(`templates/Ask/controls.hbs`),
|
||||
|
|
@ -69,6 +74,14 @@ export class Ask extends HandlebarsApplicationMixin(ApplicationV2) {
|
|||
} = {}) {
|
||||
super(options);
|
||||
this.alwaysUseAnswerObject = alwaysUseAnswerObject;
|
||||
|
||||
for (const input of inputs) {
|
||||
if (!validInputTypes.includes(input.type)) {
|
||||
input.details = `Invalid input type provided: ${input.type}`;
|
||||
input.type = `error`;
|
||||
};
|
||||
};
|
||||
|
||||
this._inputs = inputs;
|
||||
this._description = description;
|
||||
this._userOnCancel = onCancel;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { filePath } from "../consts.mjs";
|
||||
import { options } from "./options.mjs";
|
||||
|
||||
export default {
|
||||
systemFilePath: filePath,
|
||||
"taf-options": options,
|
||||
};
|
||||
|
|
|
|||
34
module/handlebarsHelpers/options.mjs
Normal file
34
module/handlebarsHelpers/options.mjs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* @typedef {object} Option
|
||||
* @property {string} [label]
|
||||
* @property {string|number} value
|
||||
* @property {boolean} [disabled]
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {string | number} selected The selected value
|
||||
* @param {Array<Option | string>} opts The options that are valid
|
||||
* @param {any} meta The Handlebars meta processing
|
||||
*/
|
||||
export function options(selected, opts, meta) {
|
||||
const { localize = false } = meta.hash;
|
||||
selected = Handlebars.escapeExpression(selected);
|
||||
const htmlOptions = [];
|
||||
|
||||
for (let opt of opts) {
|
||||
if (typeof opt === `string`) {
|
||||
opt = { label: opt, value: opt };
|
||||
};
|
||||
opt.value = Handlebars.escapeExpression(opt.value);
|
||||
htmlOptions.push(
|
||||
`<option
|
||||
value="${opt.value}"
|
||||
${selected === opt.value ? `selected` : ``}
|
||||
${opt.disabled ? `disabled` : ``}
|
||||
>
|
||||
${localize ? game.i18n.format(opt.label) : opt.label}
|
||||
</option>`,
|
||||
);
|
||||
};
|
||||
return new Handlebars.SafeString(htmlOptions.join(`\n`));
|
||||
};
|
||||
|
|
@ -36,8 +36,19 @@
|
|||
|
||||
p {
|
||||
margin: 0;
|
||||
grid-column: 1 / -1;
|
||||
text-indent: 1em;
|
||||
|
||||
&.error {
|
||||
font-size: 1.1rem;
|
||||
padding: 6px 8px;
|
||||
box-shadow: 0 0 10px var(--color-shadow-dark);
|
||||
color: var(--color-text-light-1);
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
background: var(--color-level-error-bg);
|
||||
border: 1px solid var(--color-level-error);
|
||||
text-indent: 0;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
|
|
|
|||
7
styles/elements/hr.css
Normal file
7
styles/elements/hr.css
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
.taf > .window-content hr {
|
||||
height: 1px;
|
||||
background: rebeccapurple;
|
||||
border-radius: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
|
@ -3,4 +3,54 @@
|
|||
--input-height: 2.5rem;
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
&[type="checkbox"] {
|
||||
--checkbox-checked-color: var(--color-warm-1);
|
||||
width: var(--checkbox-size);
|
||||
height: var(--checkbox-size);
|
||||
background: var(--input-background-color);
|
||||
border: 2px solid var(--color-cool-3);
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
|
||||
&::before, &::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--checkbox-checked-color);
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
&:checked::after {
|
||||
display: block;
|
||||
position: absolute;
|
||||
inset: 4px;
|
||||
z-index: 1;
|
||||
content: "";
|
||||
border-radius: 4px;
|
||||
background: var(--checkbox-checked-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
|
||||
&::before {
|
||||
display: block;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
content: "";
|
||||
background: var(--color-level-error-bg);
|
||||
border-radius: 2px;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&::after {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
@layer resets, themes, elements, components, partials, apps, exceptions;
|
||||
|
||||
/* Resets */
|
||||
@import url("./resets/hr.css") layer(resets);
|
||||
@import url("./resets/inputs.css") layer(resets);
|
||||
|
||||
/* Themes */
|
||||
@import url("./themes/dark.css") layer(themes);
|
||||
@import url("./themes/light.css") layer(themes);
|
||||
|
||||
/* Elements */
|
||||
@import url("./elements/headers.css") layer(elements);
|
||||
@import url("./elements/hr.css") layer(elements);
|
||||
@import url("./elements/input.css") layer(elements);
|
||||
@import url("./elements/p.css") layer(elements);
|
||||
@import url("./elements/prose-mirror.css") layer(elements);
|
||||
|
|
|
|||
3
styles/resets/hr.css
Normal file
3
styles/resets/hr.css
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
.taf > .window-content hr {
|
||||
all: initial;
|
||||
}
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
.taf > .window-content {
|
||||
button, input {
|
||||
input[type="checkbox"] {
|
||||
all: initial;
|
||||
&::after, &::before {
|
||||
all: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
</p>
|
||||
{{/if}}
|
||||
{{#each inputs as | i |}}
|
||||
<div class="prompt">
|
||||
{{> (concat (systemFilePath "templates/Ask/inputs/" ) i.type ".hbs") i}}
|
||||
</div>
|
||||
{{> (concat (systemFilePath "templates/Ask/inputs/" ) i.type ".hbs") i}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
<label
|
||||
for="{{id}}"
|
||||
>
|
||||
{{ label }}
|
||||
</label>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="{{ id }}"
|
||||
name="{{ key }}"
|
||||
{{ checked defaultValue }}
|
||||
{{#if autofocus}}autofocus{{/if}}
|
||||
>
|
||||
<div class="prompt">
|
||||
<label
|
||||
for="{{id}}"
|
||||
>
|
||||
{{ label }}
|
||||
</label>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="{{ id }}"
|
||||
name="{{ key }}"
|
||||
{{ checked defaultValue }}
|
||||
{{#if autofocus}}autofocus{{/if}}
|
||||
>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
<p class="prompt__details">
|
||||
<p>
|
||||
{{{ details }}}
|
||||
</p>
|
||||
|
|
|
|||
1
templates/Ask/inputs/divider.hbs
Normal file
1
templates/Ask/inputs/divider.hbs
Normal file
|
|
@ -0,0 +1 @@
|
|||
<hr>
|
||||
3
templates/Ask/inputs/error.hbs
Normal file
3
templates/Ask/inputs/error.hbs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<p class="error">
|
||||
{{ details }}
|
||||
</p>
|
||||
|
|
@ -1,12 +1,14 @@
|
|||
<label
|
||||
for="{{id}}"
|
||||
>
|
||||
{{ label }}
|
||||
</label>
|
||||
<input
|
||||
type="{{ inputType }}"
|
||||
id="{{ id }}"
|
||||
name="{{ key }}"
|
||||
{{ valueAttribute }}="{{ defaultValue }}"
|
||||
{{#if autofocus}}autofocus{{/if}}
|
||||
>
|
||||
<div class="prompt">
|
||||
<label
|
||||
for="{{id}}"
|
||||
>
|
||||
{{ label }}
|
||||
</label>
|
||||
<input
|
||||
type="{{ inputType }}"
|
||||
id="{{ id }}"
|
||||
name="{{ key }}"
|
||||
{{ valueAttribute }}="{{ defaultValue }}"
|
||||
{{#if autofocus}}autofocus{{/if}}
|
||||
>
|
||||
</div>
|
||||
|
|
|
|||
13
templates/Ask/inputs/select.hbs
Normal file
13
templates/Ask/inputs/select.hbs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<div class="prompt">
|
||||
<label
|
||||
for="{{id}}"
|
||||
>
|
||||
{{ label }}
|
||||
</label>
|
||||
<select
|
||||
id="{{ id }}"
|
||||
name="{{ key }}"
|
||||
>
|
||||
{{ taf-options defaultValue options }}
|
||||
</select>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue