Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
0fb2bd796d Add a barebones list view implementation 2026-02-01 15:28:41 -07:00
7 changed files with 105 additions and 4 deletions

4
assets/LICENSES Normal file
View file

@ -0,0 +1,4 @@
Disclaimer: All icons have been optimized and scaled for the web unless otherwise noted.
icons/layout/grid.svg (https://thenounproject.com/icon/grid-2442978/)
icons/layout/list.svg (https://thenounproject.com/icon/list-5060696/)

View file

@ -0,0 +1 @@
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="M77.641 100a8.6 8.6 0 0 1-4.332-2.36 7.42 7.42 0 0 1-1.86-5.109V78.88a6.87 6.87 0 0 1 4-6.648A9 9 0 0 1 79 71.469c4.41-.09 8.829 0 13.25 0 3.95 0 6.84 2.211 7.61 6q.042.111.11.211v16.09c-.052.18-.11.352-.161.531a6.6 6.6 0 0 1-2.758 4.23 26.5 26.5 0 0 1-3.281 1.47zM22.359 0c1.094.375 2.156.84 3.172 1.39a6.76 6.76 0 0 1 3 6q.059 6.902 0 13.81a6.92 6.92 0 0 1-4.121 6.652 8.4 8.4 0 0 1-3.32.687c-4.551.07-9.102.051-13.648 0a7.15 7.15 0 0 1-7.301-5.8 3 3 0 0 0-.14-.38V6.232c0-.149.108-.301.148-.45A6.6 6.6 0 0 1 2.922 1.47 26 26 0 0 1 6.23 0zM100 22.359a21.3 21.3 0 0 1-1.398 3.18 6.74 6.74 0 0 1-6 3q-6.901.058-13.81 0h-.003a6.8 6.8 0 0 1-6.52-3.918 8.7 8.7 0 0 1-.808-3.52c-.09-4.55-.059-9.101 0-13.648V7.45A7.134 7.134 0 0 1 77.35.121a2 2 0 0 0 .29-.12h16.128q.183.075.371.128a6.5 6.5 0 0 1 4.34 2.723A26 26 0 0 1 100 6.23zM0 77.641a19.7 19.7 0 0 1 1.34-3.121 6.83 6.83 0 0 1 6.058-3.07h13.813a6.8 6.8 0 0 1 6.52 3.922c.512 1.101.789 2.3.808 3.519.09 4.55.059 9.102 0 13.648a7.14 7.14 0 0 1-5.91 7.352 1.7 1.7 0 0 0-.289.12H6.231a3 3 0 0 0-.371-.132 6.56 6.56 0 0 1-4.39-2.79A25 25 0 0 1 0 93.77zm0-35.789a21.5 21.5 0 0 1 1.531-3.281 6.2 6.2 0 0 1 5.29-2.79h14.69a7.077 7.077 0 0 1 7 7.25c0 4.66.059 9.321 0 14a7.006 7.006 0 0 1-7 7.23c-4.82.11-9.64.103-14.449.001-3.558-.07-6-2.16-6.91-5.64 0-.149-.101-.29-.16-.442q.007-8.179.008-16.328m100 16.296a20.4 20.4 0 0 1-1.48 3.223 6.29 6.29 0 0 1-5.34 2.84c-4.922 0-9.852.12-14.77 0a6.944 6.944 0 0 1-7-7.223c-.059-4.66 0-9.32 0-14a7.07 7.07 0 0 1 1.984-5.086 7.1 7.1 0 0 1 5.016-2.164c4.82 0 9.64-.078 14.449 0a7.006 7.006 0 0 1 6.922 5.723q.053.182.14.359v16.328zM41.852 100a22.7 22.7 0 0 1-3.402-1.629 6 6 0 0 1-2.64-5c-.09-3.371-.06-6.871-.071-10.37v-4.552a7.1 7.1 0 0 1 2.168-5.011 7.08 7.08 0 0 1 5.082-1.989h14a7.1 7.1 0 0 1 5.086 1.985 7.1 7.1 0 0 1 2.156 5.015c0 4.871.09 9.739 0 14.61-.078 3.55-2.238 6-5.711 6.84q-.182.057-.36.14H41.853zM58 0a9.2 9.2 0 0 1 3.61 1.602A6.48 6.48 0 0 1 64.2 6.52c.089 4 .058 7.93.07 11.89v3a7.12 7.12 0 0 1-7.348 7.121h-13.81c-4.19 0-7.19-2.84-7.288-7-.13-4.87-.11-9.738 0-14.608C35.87 3.43 38 1 41.5.142A3 3 0 0 0 41.85 0zm6.211 50c0 2.55.09 5.11 0 7.66a6.75 6.75 0 0 1-6.512 6.531q-7.699.181-15.398 0a6.706 6.706 0 0 1-6.472-6.48 349 349 0 0 1 0-15.398v-.004a6.695 6.695 0 0 1 6.46-6.48 330 330 0 0 1 15.48 0 6.75 6.75 0 0 1 6.43 6.433c.11 2.578 0 5.16 0 7.738z"/></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1 @@
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><path d="M41.668 9.375H87.5c4.027 0 7.293 4.027 7.293 7.293V25a7.294 7.294 0 0 1-7.293 7.293H41.668c-4.027 0-7.293-4.027-7.293-7.293v-8.332a7.294 7.294 0 0 1 7.293-7.293m-29.168 0h8.332c4.027 0 7.293 4.027 7.293 7.293V25a7.294 7.294 0 0 1-7.293 7.293H12.5c-4.027 0-7.293-4.027-7.293-7.293v-8.332A7.294 7.294 0 0 1 12.5 9.375m29.168 58.332H87.5c4.027 0 7.293 4.027 7.293 7.293v8.332a7.294 7.294 0 0 1-7.293 7.293H41.668c-4.027 0-7.293-4.027-7.293-7.293V75a7.294 7.294 0 0 1 7.293-7.293m-29.168 0h8.332c4.027 0 7.293 4.027 7.293 7.293v8.332a7.294 7.294 0 0 1-7.293 7.293H12.5c-4.027 0-7.293-4.027-7.293-7.293V75a7.294 7.294 0 0 1 7.293-7.293m29.168-29.164h29.168c4.027 0 7.293 4.027 7.293 7.293v8.332a7.294 7.294 0 0 1-7.293 7.293H41.668c-4.027 0-7.293-4.027-7.293-7.293v-8.332a7.294 7.294 0 0 1 7.293-7.293m-29.168 0h8.332c4.027 0 7.293 4.027 7.293 7.293v8.332a7.294 7.294 0 0 1-7.293 7.293H12.5c-4.027 0-7.293-4.027-7.293-7.293v-8.332a7.294 7.294 0 0 1 7.293-7.293"/></svg>

After

Width:  |  Height:  |  Size: 1 KiB

View file

@ -35,6 +35,7 @@ export class ArtBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
template: filePath(`templates/ArtBrowser/images.hbs`),
templates: [
filePath(`templates/ArtBrowser/image/grid.hbs`),
filePath(`templates/ArtBrowser/image/list.hbs`),
],
},
};
@ -44,16 +45,23 @@ export class ArtBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
#page = 1;
#selectCount = 0;
#onSubmit = null;
#layout = `grid`;
filters = {
name: ``,
tags: [],
artists: [],
};
constructor({ selectCount = 0, onSubmit = null, ...opts } = {}) {
constructor({
selectCount = 0,
onSubmit = null,
layout = `grid`,
...opts
} = {}) {
super(opts);
this.#selectCount = selectCount;
this.#onSubmit = onSubmit;
this.#layout = layout;
};
async setPage(page) {
@ -65,6 +73,15 @@ export class ArtBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
return;
};
async changeLayout(layout) {
console.log(`changing layout to:`, layout)
if (![`grid`, `list`].includes(layout)) {
throw `Cannot set layout to: ${layout}`;
};
this.#layout = layout;
await this.render({ parts: [`images`] });
};
get selectMode() {
if (this.#selectCount === 0) {
return `view`;
@ -132,6 +149,11 @@ export class ArtBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
if (options.parts?.includes(`images`)) {
this._updateSelectedCount();
const layoutTypeInputs = this.element.querySelectorAll(`input[name="layoutType"]`);
for (const element of layoutTypeInputs) {
element.addEventListener(`change`, this.#onLayoutChange.bind(this));
};
};
};
@ -178,9 +200,10 @@ export class ArtBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
idp: this.id,
},
is: {
multi: this.selectMode === `multi`,
single: this.selectMode === `single`,
multi: this.#selectCount > 1,
single: this.#selectCount === 1,
},
layout: this.#layout,
can: {
upload: true,
},
@ -270,6 +293,13 @@ export class ArtBrowser extends HandlebarsApplicationMixin(ApplicationV2) {
this.render({ parts: [`images`] });
};
async #onLayoutChange(event) {
event.preventDefault();
event.stopPropagation();
const newLayout = event.target.value;
await this.changeLayout(newLayout);
};
/** @this {ArtBrowser} */
static async #nextPage() {
this.#page += 1;

38
styles/elements/radio.css Normal file
View file

@ -0,0 +1,38 @@
.token-browser > .window-content {
.radio-group {
display: flex;
flex-direction: row;
input[type="radio"] {
width: 0;
height: 0;
margin: 0;
&::before, &::after {
display: none;
}
}
label {
display: flex;
justify-content: center;
align-items: center;
border: 1px solid var(--color-light-5);
cursor: pointer;
height: 28px;
min-width: 28px;
&:first-child {
border-radius: 4px 0 0 4px;
}
&:last-child {
border-radius: 0 4px 4px 0;
}
&:has(:checked) {
background: var(--color-cool-4);
}
}
}
}

View file

@ -8,6 +8,7 @@
@import url("./elements/utils.css") layer(elements);
@import url("./elements/checkbox.css") layer(elements);
@import url("./elements/lists.css") layer(elements);
@import url("./elements/radio.css") layer(elements);
/* Apps */
@import url("./apps/common.css") layer(apps);

View file

@ -1,5 +1,31 @@
<div class="paginated">
<div class="row">
<div class="radio-group">
<label data-tooltip="Grid layout">
<input
type="radio"
name="layoutType"
value="grid"
{{checked (eq layout "grid")}}
>
<it-icon
name="icons/layout/grid"
var:fill="currentColor"
></it-icon>
</label>
<label data-tooltip="List layout">
<input
type="radio"
name="layoutType"
value="list"
{{checked (eq layout "list")}}
>
<it-icon
name="icons/layout/list"
var:fill="currentColor"
></it-icon>
</label>
</div>
{{#if can.upload}}
<button data-action="uploadImage">Upload Image</button>
{{/if}}
@ -12,7 +38,7 @@
<ul class="image-list image-list--{{listLayout}}">
{{#each images as | image |}}
{{>
(tb-filePath "templates/ArtBrowser/image/grid.hbs")
(concat (tb-filePath "templates/ArtBrowser/image/") @root.layout ".hbs")
image=image
is=@root.is
}}