Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
S
Stable Diffusion Webui
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
novelai-storage
Stable Diffusion Webui
Commits
f49c220c
Commit
f49c220c
authored
Jan 15, 2024
by
Sj-Si
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move extra network tab buttons into tree view;
parent
d88424ef
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
401 additions
and
284 deletions
+401
-284
html/extra-networks-card.html
html/extra-networks-card.html
+2
-6
html/extra-networks-copy-path-button.html
html/extra-networks-copy-path-button.html
+5
-0
html/extra-networks-edit-item-button.html
html/extra-networks-edit-item-button.html
+4
-0
html/extra-networks-metadata-button.html
html/extra-networks-metadata-button.html
+4
-0
html/extra-networks-tree-button.html
html/extra-networks-tree-button.html
+4
-2
html/extra-networks-tree.html
html/extra-networks-tree.html
+42
-0
javascript/extraNetworks.js
javascript/extraNetworks.js
+63
-19
modules/ui_extra_networks.py
modules/ui_extra_networks.py
+91
-179
style.css
style.css
+186
-78
No files found.
html/extra-networks-card.html
View file @
f49c220c
<div
class=
'card'
style=
{style}
onclick=
{card_clicked}
data-name=
"{name}"
{
sort_keys
}
>
<div
class=
"card"
style=
{style}
onclick=
"{card_clicked}"
data-name=
"{name}"
{
sort_keys
}
>
{background_image}
<div
class=
"button-row"
>
{copy_path_button}
{metadata_button}
{edit_button}
</div>
<div
class=
"button-row"
>
{copy_path_button}{metadata_button}{edit_button}
</div>
<div
class=
'actions'
>
<div
class=
'additional'
>
{search_terms}
</div>
<span
class=
'name'
>
{name}
</span>
...
...
html/extra-networks-copy-path-button.html
0 → 100644
View file @
f49c220c
<div
class=
"copy-path-button card-button"
title=
"Copy path to clipboard"
onclick=
"extraNetworksCopyCardPath(event, '{filename}')"
data-clipboard-text=
"{filename}"
>
</div>
\ No newline at end of file
html/extra-networks-edit-item-button.html
0 → 100644
View file @
f49c220c
<div
class=
"edit-button card-button"
title=
"Edit metadata"
onclick=
"extraNetworksEditUserMetadata(event, '{tabname}', '{page_id}', '{name}')"
>
</div>
\ No newline at end of file
html/extra-networks-metadata-button.html
0 → 100644
View file @
f49c220c
<div
class=
"metadata-button card-button"
title=
"Show internal metadata"
onclick=
"extraNetworksRequestMetadata(event, '{page_id}', '{name}')"
>
</div>
\ No newline at end of file
html/extra-networks-tree-button.html
View file @
f49c220c
<span
data-filterable-item-text
hidden
>
{search_terms}
</span>
<
button
class=
"tree-list-content {subclass}"
<
div
class=
"tree-list-content {subclass}"
expanded=
"false"
type=
"button"
onclick=
"extraNetworksTreeOnClick(event, '{tabname}', '{tab_id}');{onclick_extra}"
data-path=
"{data_path}"
data-hash=
"{data_hash}"
>
<span
class=
'tree-list-item-action tree-list-item-action--leading'
>
{action_list_item_action_leading}
...
...
@@ -19,4 +21,4 @@
<span
class=
"tree-list-item-action tree-list-item-action--trailing"
>
{action_list_item_action_trailing}
</span>
</button>
\ No newline at end of file
</div>
\ No newline at end of file
html/extra-networks-tree.html
0 → 100644
View file @
f49c220c
<div
class=
"tree-list"
>
<div
class=
"tree-list-controls"
>
<div
class=
"tree-list-search"
>
<input
id=
"{tabname}_{tab_id}_extra_search"
class=
"tree-list-search-text"
type=
"search"
placeholder=
"Filter files"
>
</div>
<div
id=
"{tabname}_{tab_id}_extra_sort"
class=
"tree-list-sort"
data-sortmode=
"path"
data-sortkey=
"sortPath-Ascending-640"
title=
"Sort by path"
onclick=
"extraNetworksTreeSortOnClick(event, '{tabname}', '{tab_id}');"
>
<i
class=
"tree-list-sort-icon"
></i>
</div>
<div
id=
"{tabname}_{tab_id}_extra_sort_dir"
class=
"tree-list-sort-dir"
data-sortdir=
"Ascending"
title=
"Sort ascending"
onclick=
"extraNetworksTreeSortDirOnClick(event, '{tabname}', '{tab_id}');"
>
<i
class=
"tree-list-sort-dir-icon"
></i>
</div>
<div
id=
"{tabname}_{tab_id}_extra_refresh"
class=
"tree-list-refresh"
title=
"Refresh page"
onclick=
"extraNetworksTreeRefreshOnClick(event, '{tabname}', '{tab_id}');"
>
<i
class=
"tree-list-refresh-icon"
></i>
</div>
</div>
<div
class=
"tree-list-container"
>
{tree}
</div>
</div>
\ No newline at end of file
javascript/extraNetworks.js
View file @
f49c220c
...
...
@@ -37,15 +37,20 @@ function setupExtraNetworksForTab(tabname) {
return
;
// `continue` doesn't work in `forEach` loops. This is equivalent.
}
var
tabs
=
gradioApp
().
querySelector
(
'
#
'
+
tabname
+
'
_extra_tabs > div
'
);
var
sort
=
gradioApp
().
getElementById
(
tabname
+
'
_extra_sort
'
);
var
sortOrder
=
gradioApp
().
getElementById
(
tabname
+
'
_extra_sortorder
'
);
var
refresh
=
gradioApp
().
getElementById
(
tabname
+
'
_extra_refresh
'
);
var
promptContainer
=
gradioApp
().
querySelector
(
'
.prompt-container-compact#
'
+
tabname
+
'
_prompt_container
'
);
var
negativePrompt
=
gradioApp
().
querySelector
(
'
#
'
+
tabname
+
'
_neg_prompt
'
);
tabs
.
appendChild
(
sort
);
tabs
.
appendChild
(
sortOrder
);
tabs
.
appendChild
(
refresh
);
var
sort
=
gradioApp
().
querySelector
(
"
#
"
+
tab_id
+
"
_extra_sort
"
);
if
(
!
sort
)
{
return
;
// `continue` doesn't work in `forEach` loops. This is equivalent.
}
var
sort_dir
=
gradioApp
().
querySelector
(
"
#
"
+
tab_id
+
"
_extra_sort_dir
"
);
if
(
!
sort_dir
)
{
return
;
// `continue` doesn't work in `forEach` loops. This is equivalent.
}
var
refresh
=
gradioApp
().
querySelector
(
"
#
"
+
tab_id
+
"
_extra_refresh
"
);
if
(
!
refresh
)
{
return
;
// `continue` doesn't work in `forEach` loops. This is equivalent.
}
var
applyFilter
=
function
()
{
var
searchTerm
=
search
.
value
.
toLowerCase
();
...
...
@@ -72,8 +77,8 @@ function setupExtraNetworksForTab(tabname) {
var
applySort
=
function
()
{
var
cards
=
gradioApp
().
querySelectorAll
(
'
#
'
+
tabname
+
'
_extra_tabs div.card
'
);
var
reverse
=
sort
Order
.
classList
.
contains
(
"
sortReverse
"
)
;
var
sortKey
=
sort
.
querySelector
(
"
input
"
).
valu
e
.
toLowerCase
().
replace
(
"
sort
"
,
""
).
replaceAll
(
"
"
,
"
_
"
).
replace
(
/_+$/
,
""
).
trim
()
||
"
name
"
;
var
reverse
=
sort
_dir
.
dataset
.
sortdir
==
"
Descending
"
;
var
sortKey
=
sort
.
dataset
.
sortmod
e
.
toLowerCase
().
replace
(
"
sort
"
,
""
).
replaceAll
(
"
"
,
"
_
"
).
replace
(
/_+$/
,
""
).
trim
()
||
"
name
"
;
sortKey
=
"
sort
"
+
sortKey
.
charAt
(
0
).
toUpperCase
()
+
sortKey
.
slice
(
1
);
var
sortKeyStore
=
sortKey
+
"
-
"
+
(
reverse
?
"
Descending
"
:
"
Ascending
"
)
+
"
-
"
+
cards
.
length
;
...
...
@@ -107,10 +112,7 @@ function setupExtraNetworksForTab(tabname) {
};
search
.
addEventListener
(
"
input
"
,
applyFilter
);
sortOrder
.
addEventListener
(
"
click
"
,
function
()
{
sortOrder
.
classList
.
toggle
(
"
sortReverse
"
);
applySort
();
});
applyFilter
();
extraNetworksApplySort
[
tab_id
]
=
applySort
;
...
...
@@ -274,7 +276,7 @@ function extraNetworksTreeProcessFileClick(event, btn, tabname, tab_id) {
var
par
=
btn
.
parentElement
;
var
search_id
=
tabname
+
"
_
"
+
tab_id
+
"
_extra_search
"
;
var
type
=
par
.
getAttribute
(
"
data-tree-entry-type
"
);
var
path
=
par
.
getAttribute
(
"
data-path
"
);
var
path
=
btn
.
getAttribute
(
"
data-path
"
);
}
function
extraNetworksTreeProcessDirectoryClick
(
event
,
btn
,
tabname
,
tab_id
)
{
...
...
@@ -310,7 +312,7 @@ function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, tab_id) {
function
_remove_selected_from_all
()
{
// Removes the `selected` attribute from all buttons.
var
sels
=
document
.
querySelectorAll
(
"
button
.tree-list-content
"
);
var
sels
=
document
.
querySelectorAll
(
"
div
.tree-list-content
"
);
[...
sels
].
forEach
(
el
=>
{
el
.
removeAttribute
(
"
selected
"
);
});
...
...
@@ -345,11 +347,11 @@ function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, tab_id) {
// NOTE: Double inversion sucks but it is the clearest way to show the branching here.
_expand_or_collapse
(
ul
,
btn
);
_select_button
(
btn
,
tabname
,
tab_id
);
_update_search
(
tabname
,
tab_id
,
btn
.
parentElement
.
getAttribute
(
"
data-path
"
));
_update_search
(
tabname
,
tab_id
,
btn
.
getAttribute
(
"
data-path
"
));
}
else
{
// All other cases, just select the button.
_select_button
(
btn
,
tabname
,
tab_id
);
_update_search
(
tabname
,
tab_id
,
btn
.
parentElement
.
getAttribute
(
"
data-path
"
));
_update_search
(
tabname
,
tab_id
,
btn
.
getAttribute
(
"
data-path
"
));
}
}
}
...
...
@@ -374,6 +376,48 @@ function extraNetworksTreeOnClick(event, tabname, tab_id) {
}
}
function
extraNetworksTreeSortOnClick
(
event
,
tabname
,
tab_id
)
{
var
curr_mode
=
event
.
currentTarget
.
dataset
.
sortmode
;
var
el_sort_dir
=
gradioApp
().
querySelector
(
"
#
"
+
tabname
+
"
_
"
+
tab_id
+
"
_extra_sort_dir
"
);
var
sort_dir
=
el_sort_dir
.
dataset
.
sortdir
;
if
(
curr_mode
==
"
path
"
)
{
event
.
currentTarget
.
dataset
.
sortmode
=
"
name
"
;
event
.
currentTarget
.
dataset
.
sortkey
=
"
sortName-
"
+
sort_dir
+
"
-640
"
;
event
.
currentTarget
.
setAttribute
(
"
title
"
,
"
Sort by filename
"
);
}
else
if
(
curr_mode
==
"
name
"
)
{
event
.
currentTarget
.
dataset
.
sortmode
=
"
date_created
"
;
event
.
currentTarget
.
dataset
.
sortkey
=
"
sortDate_created-
"
+
sort_dir
+
"
-640
"
;
event
.
currentTarget
.
setAttribute
(
"
title
"
,
"
Sort by date created
"
);
}
else
if
(
curr_mode
==
"
date_created
"
)
{
event
.
currentTarget
.
dataset
.
sortmode
=
"
date_modified
"
;
event
.
currentTarget
.
dataset
.
sortkey
=
"
sortDate_modified-
"
+
sort_dir
+
"
-640
"
;
event
.
currentTarget
.
setAttribute
(
"
title
"
,
"
Sort by date modified
"
);
}
else
{
event
.
currentTarget
.
dataset
.
sortmode
=
"
path
"
;
event
.
currentTarget
.
dataset
.
sortkey
=
"
sortPath-
"
+
sort_dir
+
"
-640
"
;
event
.
currentTarget
.
setAttribute
(
"
title
"
,
"
Sort by path
"
);
}
applyExtraNetworkSort
(
tabname
+
"
_
"
+
tab_id
);
}
function
extraNetworksTreeSortDirOnClick
(
event
,
tabname
,
tab_id
)
{
var
curr_dir
=
event
.
currentTarget
.
getAttribute
(
"
data-sortdir
"
);
if
(
curr_dir
==
"
Ascending
"
)
{
event
.
currentTarget
.
dataset
.
sortdir
=
"
Descending
"
;
event
.
currentTarget
.
setAttribute
(
"
title
"
,
"
Sort descending
"
);
}
else
{
event
.
currentTarget
.
dataset
.
sortdir
=
"
Ascending
"
;
event
.
currentTarget
.
setAttribute
(
"
title
"
,
"
Sort ascending
"
);
}
applyExtraNetworkSort
(
tabname
+
"
_
"
+
tab_id
);
}
function
extraNetworksTreeRefreshOnClick
(
event
,
tabname
,
tab_id
)
{
console
.
log
(
"
refresh clicked
"
);
var
btn_refresh_internal
=
gradioApp
().
getElementById
(
tabname
+
"
_extra_refresh_internal
"
);
btn_refresh_internal
.
dispatchEvent
(
new
Event
(
"
click
"
));
}
var
globalPopup
=
null
;
var
globalPopupInner
=
null
;
...
...
modules/ui_extra_networks.py
View file @
f49c220c
...
...
@@ -19,50 +19,6 @@ extra_pages = []
allowed_dirs
=
set
()
default_allowed_preview_extensions
=
[
"png"
,
"jpg"
,
"jpeg"
,
"webp"
,
"gif"
]
tree_tpl
=
(
"<div class='tree-list-search'>"
"<input "
"id='{tabname}_{tab_id}_extra_search' "
"class='tree-list-search-text' "
"type='search' "
"placeholder='Filter files'"
">"
"</div>"
"<ul class='tree-list tree-list--tree'>"
"{content}"
"</ul>"
)
tree_ul_tpl
=
(
"<ul class='tree-list tree-list--subgroup' data-hidden>"
"{content}"
"</ul>"
)
tree_li_dir_tpl
=
(
"<li "
"class='tree-list-item tree-list-item--has-subitem' "
"data-path='{path}' "
"data-tree-entry-type='dir'>"
"{content}"
"</li>"
)
tree_li_file_tpl
=
(
"<li "
"id='file-tree-item-{hash}' "
"class='tree-list-item tree-list-item--subitem' "
"data-path='{path}' "
"data-tree-entry-type='file'>"
"{content}"
"</li>"
)
action_list_item_action_leading
=
(
"<span class='tree-list-item-action tree-list-item-action--leading'>"
"<i class='tree-list-item-action-chevron'></i>"
"</span>"
)
@
functools
.
cache
def
allowed_preview_extensions_with_extra
(
extra_extensions
=
None
):
return
set
(
default_allowed_preview_extensions
)
|
set
(
extra_extensions
or
[])
...
...
@@ -201,9 +157,13 @@ class ExtraNetworksPage:
self
.
title
=
title
self
.
name
=
title
.
lower
()
self
.
id_page
=
self
.
name
.
replace
(
" "
,
"_"
)
self
.
extra_networks_pane_template
=
shared
.
html
(
"extra-networks-pane.html"
)
self
.
card_page_template
=
shared
.
html
(
"extra-networks-card.html"
)
self
.
tree_button_template
=
shared
.
html
(
"extra-networks-tree-button.html"
)
self
.
pane_tpl
=
shared
.
html
(
"extra-networks-pane.html"
)
self
.
tree_tpl
=
shared
.
html
(
"extra-networks-tree.html"
)
self
.
card_tpl
=
shared
.
html
(
"extra-networks-card.html"
)
self
.
btn_tree_tpl
=
shared
.
html
(
"extra-networks-tree-button.html"
)
self
.
btn_copy_path_tpl
=
shared
.
html
(
"extra-networks-copy-path-button.html"
)
self
.
btn_metadata_tpl
=
shared
.
html
(
"extra-networks-metadata-button.html"
)
self
.
btn_edit_item_tpl
=
shared
.
html
(
"extra-networks-edit-item-button.html"
)
self
.
allow_prompt
=
True
self
.
allow_negative_prompt
=
False
self
.
metadata
=
{}
...
...
@@ -268,12 +228,8 @@ class ExtraNetworksPage:
onclick
=
item
.
get
(
"onclick"
,
None
)
if
onclick
is
None
:
print
(
"HERE"
)
print
(
"TABNAME:"
,
tabname
)
print
(
"PROMPT:"
,
item
[
"prompt"
])
print
(
"NEG_PROMPT:"
,
item
.
get
(
"negative_prompt"
,
""
))
print
(
"ALLOW_NEG:"
,
self
.
allow_negative_prompt
)
onclick_js_tpl
=
"cardClicked('{tabname}', '{prompt}', '{neg_prompt}', '{allow_neg}');"
# Don't quote prompt/neg_prompt since they are stored as js strings already.
onclick_js_tpl
=
"cardClicked('{tabname}', {prompt}, {neg_prompt}, '{allow_neg}');"
onclick
=
onclick_js_tpl
.
format
(
**
{
"tabname"
:
tabname
,
...
...
@@ -284,15 +240,23 @@ class ExtraNetworksPage:
)
onclick
=
html
.
escape
(
onclick
)
copy_path_button
=
f
"<div class='copy-path-button card-button' title='Copy path to clipboard' onclick='extraNetworksCopyCardPath(event, {quote_js(item['filename'])})' data-clipboard-text='{quote_js(item['filename'])}'></div>"
metadata_button
=
""
btn_copy_path
=
self
.
btn_copy_path_tpl
.
format
(
**
{
"filename"
:
item
[
"filename"
]})
btn_metadata
=
""
metadata
=
item
.
get
(
"metadata"
)
if
metadata
:
metadata_button
=
f
"<div class='metadata-button card-button' title='Show internal metadata' onclick='extraNetworksRequestMetadata(event, {quote_js(self.id_page)}, {quote_js(html.escape(item['name']))})'></div>"
edit_button
=
f
"<div class='edit-button card-button' title='Edit metadata' onclick='extraNetworksEditUserMetadata(event, {quote_js(tabname)}, {quote_js(self.id_page)}, {quote_js(html.escape(item['name']))})'></div>"
btn_metadata
=
self
.
btn_metadata_tpl
.
format
(
**
{
"page_id"
:
self
.
id_page
,
"name"
:
html
.
escape
(
item
[
"name"
]),
}
)
btn_edit_item
=
self
.
btn_edit_item_tpl
.
format
(
**
{
"tabname"
:
tabname
,
"page_id"
:
self
.
id_page
,
"name"
:
html
.
escape
(
item
[
"name"
]),
}
)
local_path
=
""
filename
=
item
.
get
(
"filename"
,
""
)
...
...
@@ -334,11 +298,11 @@ class ExtraNetworksPage:
args
=
{
"background_image"
:
background_image
,
"card_clicked"
:
onclick
,
"copy_path_button"
:
copy_path_button
,
"copy_path_button"
:
btn_copy_path
,
"description"
:
(
item
.
get
(
"description"
)
or
""
if
shared
.
opts
.
extra_networks_card_show_desc
else
""
),
"edit_button"
:
edit_button
,
"edit_button"
:
btn_edit_item
,
"local_preview"
:
quote_js
(
item
[
"local_preview"
]),
"metadata_button"
:
metadata_button
,
"metadata_button"
:
btn_metadata
,
"name"
:
html
.
escape
(
item
[
"name"
]),
"prompt"
:
item
.
get
(
"prompt"
,
None
),
"save_card_preview"
:
'"'
+
html
.
escape
(
f
"""return saveCardPreview(event, {quote_js(tabname)}, {quote_js(item["local_preview"])})"""
)
+
'"'
,
...
...
@@ -355,6 +319,57 @@ class ExtraNetworksPage:
else
:
return
args
def
create_tree_dir_item_html
(
self
,
tabname
:
str
,
dir_path
:
str
,
content
:
Optional
[
str
]
=
None
)
->
Optional
[
str
]:
if
not
content
:
return
None
btn
=
self
.
btn_tree_tpl
.
format
(
**
{
"search_terms"
:
""
,
"subclass"
:
"tree-list-content-dir"
,
"tabname"
:
tabname
,
"tab_id"
:
self
.
id_page
,
"onclick_extra"
:
""
,
"data_path"
:
dir_path
,
"data_hash"
:
""
,
"action_list_item_action_leading"
:
"<i class='tree-list-item-action-chevron'></i>"
,
"action_list_item_visual_leading"
:
"🗀"
,
"action_list_item_label"
:
os
.
path
.
basename
(
dir_path
),
"action_list_item_visual_trailing"
:
""
,
"action_list_item_action_trailing"
:
""
,
}
)
ul
=
f
"<ul class='tree-list tree-list--subgroup' data-hidden>{content}</ul>"
return
f
"<li class='tree-list-item tree-list-item--has-subitem' data-tree-entry-type='dir'>{btn + ul}</li>"
def
create_tree_file_item_html
(
self
,
tabname
:
str
,
item_name
:
str
,
item
:
dict
)
->
str
:
item_html_args
=
self
.
create_item_html
(
tabname
,
item
)
action_buttons
=
""
.
join
(
[
item_html_args
[
"copy_path_button"
],
item_html_args
[
"metadata_button"
],
item_html_args
[
"edit_button"
],
]
)
action_buttons
=
f
"<div class=
\"
button-row
\"
>{action_buttons}</div>"
btn
=
self
.
btn_tree_tpl
.
format
(
**
{
"search_terms"
:
""
,
"subclass"
:
"tree-list-content-file"
,
"tabname"
:
tabname
,
"tab_id"
:
self
.
id_page
,
"onclick_extra"
:
item_html_args
[
"card_clicked"
],
"data_path"
:
item_name
,
"data_hash"
:
item
[
"shorthash"
],
"action_list_item_action_leading"
:
"<i class='tree-list-item-action-chevron'></i>"
,
"action_list_item_visual_leading"
:
"🗎"
,
"action_list_item_label"
:
item
[
"name"
],
"action_list_item_visual_trailing"
:
""
,
"action_list_item_action_trailing"
:
action_buttons
,
}
)
return
f
"<li class='tree-list-item tree-list-item--subitem' data-tree-entry-type='file'>{btn}</li>"
def
create_tree_view_html
(
self
,
tabname
:
str
)
->
str
:
"""Generates HTML for displaying folders in a tree view.
...
...
@@ -385,57 +400,9 @@ class ExtraNetworksPage:
for
k
,
v
in
sorted
(
data
.
items
(),
key
=
lambda
x
:
shared
.
natural_sort_key
(
x
[
0
])):
if
isinstance
(
v
,
(
ExtraNetworksItem
,)):
_item_html_args
=
self
.
create_item_html
(
tabname
,
v
.
item
)
_action_buttons
=
""
.
join
(
[
_item_html_args
[
"copy_path_button"
],
_item_html_args
[
"metadata_button"
],
_item_html_args
[
"edit_button"
],
]
)
_action_buttons
=
f
"<div class=
\"
button-row
\"
>{_action_buttons}</div>"
_btn
=
self
.
tree_button_template
.
format
(
**
{
"search_terms"
:
""
,
"subclass"
:
"tree-list-content-file"
,
"tabname"
:
tabname
,
"tab_id"
:
self
.
id_page
,
"onclick_extra"
:
_item_html_args
[
"card_clicked"
],
"action_list_item_action_leading"
:
action_list_item_action_leading
,
"action_list_item_visual_leading"
:
"🗎"
,
"action_list_item_label"
:
v
.
item
[
"name"
],
"action_list_item_visual_trailing"
:
""
,
"action_list_item_action_trailing"
:
_action_buttons
,
}
)
_li
=
tree_li_file_tpl
.
format
(
**
{
"hash"
:
v
.
item
[
"shorthash"
],
"path"
:
k
,
"type"
:
"file"
,
"content"
:
_btn
,
}
)
_file_li
.
append
(
_li
)
_file_li
.
append
(
self
.
create_tree_file_item_html
(
tabname
,
k
,
v
.
item
))
else
:
_btn
=
self
.
tree_button_template
.
format
(
**
{
"search_terms"
:
""
,
"subclass"
:
"tree-list-content-dir"
,
"tabname"
:
tabname
,
"tab_id"
:
self
.
id_page
,
"onclick_extra"
:
""
,
"action_list_item_action_leading"
:
action_list_item_action_leading
,
"action_list_item_visual_leading"
:
"🗀"
,
"action_list_item_label"
:
os
.
path
.
basename
(
k
),
"action_list_item_visual_trailing"
:
""
,
"action_list_item_action_trailing"
:
""
,
}
)
_ul
=
tree_ul_tpl
.
format
(
**
{
"content"
:
_build_tree
(
v
)})
_li
=
tree_li_dir_tpl
.
format
(
**
{
"content"
:
_btn
+
_ul
,
"path"
:
k
})
_dir_li
.
append
(
_li
)
_dir_li
.
append
(
self
.
create_tree_dir_item_html
(
tabname
,
k
,
_build_tree
(
v
)))
# Directories should always be displayed before files.
return
""
.
join
(
_dir_li
)
+
""
.
join
(
_file_li
)
...
...
@@ -443,31 +410,15 @@ class ExtraNetworksPage:
# Add each root directory to the tree.
for
k
,
v
in
sorted
(
tree
.
items
(),
key
=
lambda
x
:
shared
.
natural_sort_key
(
x
[
0
])):
# If root is empty, append the "disabled" attribute to the template details tag.
btn
=
self
.
tree_button_template
.
format
(
**
{
"search_terms"
:
""
,
"subclass"
:
"tree-list-content-dir"
,
"tabname"
:
tabname
,
"tab_id"
:
self
.
id_page
,
"onclick_extra"
:
""
,
"action_list_item_action_leading"
:
action_list_item_action_leading
,
"action_list_item_visual_leading"
:
"🗀"
,
"action_list_item_label"
:
os
.
path
.
basename
(
k
),
"action_list_item_visual_trailing"
:
""
,
"action_list_item_action_trailing"
:
""
,
}
)
subtree
=
_build_tree
(
v
)
if
subtree
:
ul
=
tree_ul_tpl
.
format
(
**
{
"content"
:
_build_tree
(
v
)})
li
=
tree_li_dir_tpl
.
format
(
**
{
"content"
:
btn
+
ul
,
"path"
:
k
})
res
+=
li
item_html
=
self
.
create_tree_dir_item_html
(
tabname
,
k
,
_build_tree
(
v
))
if
item_html
:
res
+=
item_html
return
tree_tpl
.
format
(
return
self
.
tree_tpl
.
format
(
**
{
"content"
:
res
,
"tabname"
:
tabname
,
"tab_id"
:
self
.
id_page
,
"tree"
:
f
"<ul class='tree-list tree-list--tree'>{res}</ul>"
}
)
...
...
@@ -475,8 +426,7 @@ class ExtraNetworksPage:
res
=
""
self
.
items
=
{
x
[
"name"
]:
x
for
x
in
self
.
list_items
()}
for
item
in
self
.
items
.
values
():
print
(
"HEEEERRE:"
,
item
)
res
+=
self
.
create_item_html
(
tabname
,
item
,
self
.
card_page_template
)
res
+=
self
.
create_item_html
(
tabname
,
item
,
self
.
card_tpl
)
if
res
==
""
:
dirs
=
""
.
join
([
f
"<li>{x}</li>"
for
x
in
self
.
allowed_directories_for_previews
()])
...
...
@@ -493,7 +443,7 @@ class ExtraNetworksPage:
card_view_html
=
self
.
create_card_view_html
(
tabname
)
network_type_id
=
self
.
id_page
return
self
.
extra_networks_pane_template
.
format
(
return
self
.
pane_tpl
.
format
(
**
{
"tabname"
:
tabname
,
"network_type_id"
:
network_type_id
,
...
...
@@ -612,6 +562,8 @@ def create_ui(interface: gr.Blocks, unrelated_tabs, tabname):
related_tabs
=
[]
button_refresh
=
gr
.
Button
(
"Refresh"
,
elem_id
=
tabname
+
"_extra_refresh_internal"
,
visible
=
False
)
for
page
in
ui
.
stored_extra_pages
:
with
gr
.
Tab
(
page
.
title
,
elem_id
=
f
"{tabname}_{page.id_page}"
,
elem_classes
=
[
"extra-page"
])
as
tab
:
with
gr
.
Column
(
elem_id
=
f
"{tabname}_{page.id_page}_prompts"
,
elem_classes
=
[
"extra-page-prompts"
]):
...
...
@@ -633,51 +585,9 @@ def create_ui(interface: gr.Blocks, unrelated_tabs, tabname):
related_tabs
.
append
(
tab
)
dropdown_sort
=
gr
.
Dropdown
(
choices
=
[
'Path'
,
'Name'
,
'Date Created'
,
'Date Modified'
,
],
value
=
shared
.
opts
.
extra_networks_card_order_field
,
elem_id
=
tabname
+
"_extra_sort"
,
elem_classes
=
"sort"
,
multiselect
=
False
,
visible
=
False
,
show_label
=
False
,
interactive
=
True
,
label
=
tabname
+
"_extra_sort_order"
)
button_sortorder
=
ToolButton
(
switch_values_symbol
,
elem_id
=
tabname
+
"_extra_sortorder"
,
elem_classes
=
[
"sortorder"
]
+
([]
if
shared
.
opts
.
extra_networks_card_order
==
"Ascending"
else
[
"sortReverse"
]),
visible
=
False
,
tooltip
=
"Invert sort order"
)
button_refresh
=
gr
.
Button
(
'Refresh'
,
elem_id
=
tabname
+
"_extra_refresh"
,
visible
=
False
)
tab_controls
=
[
dropdown_sort
,
button_sortorder
,
button_refresh
,
]
ui
.
button_save_preview
=
gr
.
Button
(
'Save preview'
,
elem_id
=
tabname
+
"_save_preview"
,
visible
=
False
)
ui
.
preview_target_filename
=
gr
.
Textbox
(
'Preview save filename'
,
elem_id
=
tabname
+
"_preview_filename"
,
visible
=
False
)
for
tab
in
unrelated_tabs
:
tab
.
select
(
fn
=
lambda
:
[
gr
.
update
(
visible
=
False
)
for
_
in
tab_controls
],
_js
=
f
"function(){{ extraNetworksUnrelatedTabSelected('{tabname}'); }}"
,
inputs
=
[],
outputs
=
tab_controls
,
show_progress
=
False
,
)
for
page
,
tab
in
zip
(
ui
.
stored_extra_pages
,
related_tabs
):
allow_prompt
=
"true"
if
page
.
allow_prompt
else
"false"
allow_negative_prompt
=
"true"
if
page
.
allow_negative_prompt
else
"false"
jscode
=
(
"extraNetworksTabSelected("
f
"'{tabname}', "
f
"'{tabname}_{page.id_page}_prompts', "
f
"'{allow_prompt}', "
f
"'{allow_negative_prompt}'"
");"
)
tab
.
select
(
fn
=
lambda
:
[
gr
.
update
(
visible
=
True
)
for
_
in
tab_controls
],
_js
=
"function(){ "
+
jscode
+
" }"
,
inputs
=
[],
outputs
=
tab_controls
,
show_progress
=
False
,
)
dropdown_sort
.
change
(
fn
=
lambda
:
None
,
_js
=
"function(){ applyExtraNetworkSort('"
+
tabname
+
"'); }"
)
def
create_html
():
ui
.
pages_contents
=
[
pg
.
create_html
(
ui
.
tabname
)
for
pg
in
ui
.
stored_extra_pages
]
...
...
@@ -693,6 +603,8 @@ def create_ui(interface: gr.Blocks, unrelated_tabs, tabname):
return
ui
.
pages_contents
interface
.
load
(
fn
=
pages_html
,
inputs
=
[],
outputs
=
ui
.
pages
)
# NOTE: Event is manually fired in extraNetworks.js:extraNetworksTreeRefreshOnClick()
# button is unused and hidden at all times. Only used in order to fire this event.
button_refresh
.
click
(
fn
=
refresh
,
inputs
=
[],
outputs
=
ui
.
pages
)
return
ui
...
...
style.css
View file @
f49c220c
...
...
@@ -1196,17 +1196,33 @@ body.resizing .resize-handle {
overflow
:
hidden
;
}
.extra-network-tree
.tree-list--tree
{
cursor
:
pointer
;
-webkit-user-select
:
none
;
-moz-user-select
:
none
;
-ms-user-select
:
none
;
user-select
:
none
;
margin
:
0
;
.extra-network-tree
.tree-list
{
margin
:
0
0.25rem
;
padding
:
0
;
margin-left
:
0.25rem
;
}
.extra-network-tree
.tree-list
.tree-list-controls
{
position
:
relative
;
display
:
grid
;
width
:
100%
;
padding
:
0
!important
;
margin-top
:
0
!important
;
margin-bottom
:
0
!important
;
font-size
:
1rem
;
text-align
:
left
;
user-select
:
none
;
background-color
:
transparent
;
border
:
none
;
transition
:
background
33.333ms
linear
;
grid-template-rows
:
min-content
;
grid-template-areas
:
"tree-list-controls-col-0 tree-list-controls-col-1 tree-list-controls-col-2 tree-list-controls-col-3"
;
grid-template-columns
:
minmax
(
0
,
auto
)
min-content
min-content
min-content
;
grid-gap
:
0.1rem
;
align-items
:
start
;
}
.extra-network-tree
.tree-list--tree
{}
/* Remove auto indentation from tree. Will be overridden later. */
.extra-network-tree
.tree-list--subgroup
{
margin
:
0
!important
;
...
...
@@ -1221,9 +1237,6 @@ body.resizing .resize-handle {
padding-left
:
0.4rem
!important
;
}
/* Styles for tree <ul> elements. */
.extra-network-tree
.tree-list
{}
/* Styles for tree <li> elements. */
.extra-network-tree
.tree-list-item
{
list-style
:
none
;
...
...
@@ -1288,26 +1301,182 @@ body.resizing .resize-handle {
padding-top
:
0.5rem
!important
;
}
.dark
.extra-network-tree
button
.tree-list-content
:hover
{
.dark
.extra-network-tree
div
.tree-list-content
:hover
{
-webkit-transition
:
all
0.05s
ease-in-out
;
transition
:
all
0.05s
ease-in-out
;
background-color
:
var
(
--neutral-800
);
}
.dark
.extra-network-tree
button
.tree-list-content
[
selected
]
{
.dark
.extra-network-tree
div
.tree-list-content
[
selected
]
{
background-color
:
var
(
--neutral-700
);
}
.extra-network-tree
button
.tree-list-content
:hover
{
.extra-network-tree
div
.tree-list-content
:hover
{
-webkit-transition
:
all
0.05s
ease-in-out
;
transition
:
all
0.05s
ease-in-out
;
background-color
:
var
(
--neutral-200
);
}
.extra-network-tree
button
.tree-list-content
[
selected
]
{
.extra-network-tree
div
.tree-list-content
[
selected
]
{
background-color
:
var
(
--neutral-300
);
}
/* ==== CHEVRON ICON ACTIONS ==== */
/* Define the animation for the arrow when it is clicked. */
.extra-network-tree
.tree-list-content-dir
[
expanded
=
false
]
.tree-list-item-action-chevron
{
-ms-transform
:
rotate
(
135deg
);
-webkit-transform
:
rotate
(
135deg
);
transform
:
rotate
(
135deg
);
transition
:
transform
0.2s
;
}
.extra-network-tree
.tree-list-content-dir
[
expanded
=
true
]
.tree-list-item-action-chevron
{
-ms-transform
:
rotate
(
225deg
);
-webkit-transform
:
rotate
(
225deg
);
transform
:
rotate
(
225deg
);
transition
:
transform
0.2s
;
}
.tree-list-item-action-chevron
{
display
:
inline-flex
;
/* Uses box shadow to generate a pseudo chevron `>` icon. */
padding
:
0.3rem
;
box-shadow
:
0.1rem
0.1rem
0
0
var
(
--neutral-200
)
inset
;
transform
:
rotate
(
135deg
);
}
/* ==== SEARCH INPUT ACTIONS ==== */
/* Add icon to left side of <input> */
.extra-network-tree
.tree-list-controls
.tree-list-search
::before
{
content
:
"🔎︎"
;
position
:
absolute
;
margin
:
0.5rem
;
font-size
:
1rem
;
color
:
var
(
--input-placeholder-color
);
}
.extra-network-tree
.tree-list-controls
.tree-list-search
{
display
:
inline-flex
;
grid-area
:
tree-list-controls-col-0
;
position
:
relative
;
margin
:
0.5rem
;
}
.extra-network-tree
.tree-list-controls
.tree-list-search
.tree-list-search-text
{
border
:
1px
solid
var
(
--button-secondary-border-color
);
border-radius
:
0.5rem
;
color
:
var
(
--button-secondary-text-color
);
background-color
:
transparent
;
width
:
100%
;
padding-left
:
2rem
;
line-height
:
1rem
;
}
/* <input> clear button (x on right side) styling */
.extra-network-tree
.tree-list-controls
.tree-list-search
.tree-list-search-text
::-webkit-search-cancel-button
{
-webkit-appearance
:
none
;
appearance
:
none
;
cursor
:
pointer
;
height
:
1rem
;
width
:
1rem
;
mask-image
:
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>')
;
mask-repeat
:
no-repeat
;
mask-position
:
center
center
;
mask-size
:
100%
;
background-color
:
var
(
--input-placeholder-color
);
}
/* ==== SORT ICON ACTIONS ==== */
.extra-network-tree
.tree-list-controls
.tree-list-sort
{
grid-area
:
tree-list-controls-col-1
;
padding
:
0.25rem
;
display
:
inline-flex
;
cursor
:
pointer
;
justify-self
:
center
;
align-self
:
center
;
}
.extra-network-tree
.tree-list-controls
.tree-list-sort
.tree-list-sort-icon
{
height
:
1.5rem
;
width
:
1.5rem
;
mask-repeat
:
no-repeat
;
mask-position
:
center
center
;
mask-size
:
100%
;
background-color
:
var
(
--input-placeholder-color
);
}
.extra-network-tree
.tree-list-sort
[
data-sortmode
=
"path"
]
.tree-list-sort-icon
{
mask-image
:
url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path fill-rule="evenodd" clip-rule="evenodd" d="M1 5C1 3.34315 2.34315 2 4 2H8.43845C9.81505 2 11.015 2.93689 11.3489 4.27239L11.7808 6H13.5H20C21.6569 6 23 7.34315 23 9V11C23 11.5523 22.5523 12 22 12C21.4477 12 21 11.5523 21 11V9C21 8.44772 20.5523 8 20 8H13.5H11.7808H4C3.44772 8 3 8.44772 3 9V10V19C3 19.5523 3.44772 20 4 20H9C9.55228 20 10 20.4477 10 21C10 21.5523 9.55228 22 9 22H4C2.34315 22 1 20.6569 1 19V10V9V5ZM3 6.17071C3.31278 6.06015 3.64936 6 4 6H9.71922L9.40859 4.75746C9.2973 4.3123 8.89732 4 8.43845 4H4C3.44772 4 3 4.44772 3 5V6.17071ZM20.1716 18.7574C20.6951 17.967 21 17.0191 21 16C21 13.2386 18.7614 11 16 11C13.2386 11 11 13.2386 11 16C11 18.7614 13.2386 21 16 21C17.0191 21 17.967 20.6951 18.7574 20.1716L21.2929 22.7071C21.6834 23.0976 22.3166 23.0976 22.7071 22.7071C23.0976 22.3166 23.0976 21.6834 22.7071 21.2929L20.1716 18.7574ZM13 16C13 14.3431 14.3431 13 16 13C17.6569 13 19 14.3431 19 16C19 17.6569 17.6569 19 16 19C14.3431 19 13 17.6569 13 16Z" fill="%23000000"></path></g></svg>')
;
}
.extra-network-tree
.tree-list-sort
[
data-sortmode
=
"name"
]
.tree-list-sort-icon
{
mask-image
:
url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path fill-rule="evenodd" clip-rule="evenodd" d="M17.1841 6.69223C17.063 6.42309 16.7953 6.25 16.5002 6.25C16.2051 6.25 15.9374 6.42309 15.8162 6.69223L11.3162 16.6922C11.1463 17.07 11.3147 17.514 11.6924 17.6839C12.0701 17.8539 12.5141 17.6855 12.6841 17.3078L14.1215 14.1136H18.8789L20.3162 17.3078C20.4862 17.6855 20.9302 17.8539 21.308 17.6839C21.6857 17.514 21.8541 17.07 21.6841 16.6922L17.1841 6.69223ZM16.5002 8.82764L14.7965 12.6136H18.2039L16.5002 8.82764Z" fill="%231C274C"></path><path opacity="0.5" fill-rule="evenodd" clip-rule="evenodd" d="M2.25 7C2.25 6.58579 2.58579 6.25 3 6.25H13C13.4142 6.25 13.75 6.58579 13.75 7C13.75 7.41421 13.4142 7.75 13 7.75H3C2.58579 7.75 2.25 7.41421 2.25 7Z" fill="%231C274C"></path><path opacity="0.5" d="M2.25 12C2.25 11.5858 2.58579 11.25 3 11.25H10C10.4142 11.25 10.75 11.5858 10.75 12C10.75 12.4142 10.4142 12.75 10 12.75H3C2.58579 12.75 2.25 12.4142 2.25 12Z" fill="%231C274C"></path><path opacity="0.5" d="M2.25 17C2.25 16.5858 2.58579 16.25 3 16.25H8C8.41421 16.25 8.75 16.5858 8.75 17C8.75 17.4142 8.41421 17.75 8 17.75H3C2.58579 17.75 2.25 17.4142 2.25 17Z" fill="%231C274C"></path></g></svg>')
;
}
.extra-network-tree
.tree-list-sort
[
data-sortmode
=
"date_created"
]
.tree-list-sort-icon
{
mask-image
:
url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M17 11C14.2386 11 12 13.2386 12 16C12 18.7614 14.2386 21 17 21C19.7614 21 22 18.7614 22 16C22 13.2386 19.7614 11 17 11ZM17 11V9M2 9V15.8C2 16.9201 2 17.4802 2.21799 17.908C2.40973 18.2843 2.71569 18.5903 3.09202 18.782C3.51984 19 4.0799 19 5.2 19H13M2 9V8.2C2 7.0799 2 6.51984 2.21799 6.09202C2.40973 5.71569 2.71569 5.40973 3.09202 5.21799C3.51984 5 4.0799 5 5.2 5H13.8C14.9201 5 15.4802 5 15.908 5.21799C16.2843 5.40973 16.5903 5.71569 16.782 6.09202C17 6.51984 17 7.0799 17 8.2V9M2 9H17M5 3V5M14 3V5M15 16H17M17 16H19M17 16V14M17 16V18" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>')
;
}
.extra-network-tree
.tree-list-sort
[
data-sortmode
=
"date_modified"
]
.tree-list-sort-icon
{
mask-image
:
url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M10 21H6.2C5.0799 21 4.51984 21 4.09202 20.782C3.71569 20.5903 3.40973 20.2843 3.21799 19.908C3 19.4802 3 18.9201 3 17.8V8.2C3 7.0799 3 6.51984 3.21799 6.09202C3.40973 5.71569 3.71569 5.40973 4.09202 5.21799C4.51984 5 5.0799 5 6.2 5H17.8C18.9201 5 19.4802 5 19.908 5.21799C20.2843 5.40973 20.5903 5.71569 20.782 6.09202C21 6.51984 21 7.0799 21 8.2V10M7 3V5M17 3V5M3 9H21M13.5 13.0001L7 13M10 17.0001L7 17M14 21L16.025 20.595C16.2015 20.5597 16.2898 20.542 16.3721 20.5097C16.4452 20.4811 16.5147 20.4439 16.579 20.399C16.6516 20.3484 16.7152 20.2848 16.8426 20.1574L21 16C21.5523 15.4477 21.5523 14.5523 21 14C20.4477 13.4477 19.5523 13.4477 19 14L14.8426 18.1574C14.7152 18.2848 14.6516 18.3484 14.601 18.421C14.5561 18.4853 14.5189 18.5548 14.4903 18.6279C14.458 18.7102 14.4403 18.7985 14.405 18.975L14 21Z" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>')
;
}
/* ==== SORT DIRECTION ICON ACTIONS ==== */
.extra-network-tree
.tree-list-controls
.tree-list-sort-dir
{
grid-area
:
tree-list-controls-col-2
;
padding
:
0.25rem
;
display
:
inline-flex
;
cursor
:
pointer
;
justify-self
:
center
;
align-self
:
center
;
}
.extra-network-tree
.tree-list-controls
.tree-list-sort-dir
.tree-list-sort-dir-icon
{
height
:
1.5rem
;
width
:
1.5rem
;
mask-repeat
:
no-repeat
;
mask-position
:
center
center
;
mask-size
:
100%
;
background-color
:
var
(
--input-placeholder-color
);
}
.extra-network-tree
.tree-list-sort-dir
[
data-sortdir
=
"Ascending"
]
.tree-list-sort-dir-icon
{
mask-image
:
url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M13 12H21M13 8H21M13 16H21M6 7V17M6 7L3 10M6 7L9 10" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>')
;
}
.extra-network-tree
.tree-list-sort-dir
[
data-sortdir
=
"Descending"
]
.tree-list-sort-dir-icon
{
mask-image
:
url('data:image/svg+xml,<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><path d="M13 12H21M13 8H21M13 16H21M6 7V17M6 17L3 14M6 17L9 14" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></g></svg>')
;
}
/* ==== REFRESH ICON ACTIONS ==== */
.extra-network-tree
.tree-list-controls
.tree-list-refresh
{
grid-area
:
tree-list-controls-col-3
;
padding
:
0.25rem
;
display
:
inline-flex
;
cursor
:
pointer
;
justify-self
:
center
;
align-self
:
center
;
}
.extra-network-tree
.tree-list-controls
.tree-list-refresh
.tree-list-refresh-icon
{
height
:
1.5rem
;
width
:
1.5rem
;
mask-image
:
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="bevel"><path d="M21.5 2v6h-6M21.34 15.57a10 10 0 1 1-.57-8.38"/></svg>')
;
mask-repeat
:
no-repeat
;
mask-position
:
center
center
;
mask-size
:
100%
;
background-color
:
var
(
--input-placeholder-color
);
}
.extra-network-tree
.tree-list-refresh-icon
:active
{
-ms-transform
:
rotate
(
180deg
);
-webkit-transform
:
rotate
(
180deg
);
transform
:
rotate
(
180deg
);
transition
:
transform
0.2s
;
}
/* ==== TREE GRID CONFIG ==== */
/* Text for button. */
.extra-network-tree
.tree-list-item-label
{
position
:
relative
;
...
...
@@ -1332,6 +1501,7 @@ body.resizing .resize-handle {
align-items
:
right
;
}
/* Icon for button when it is before label. */
.extra-network-tree
.tree-list-item-visual--leading
{
grid-area
:
leading-visual
;
...
...
@@ -1348,7 +1518,7 @@ body.resizing .resize-handle {
/* Dropdown arrow for button. */
.extra-network-tree
.tree-list-item-action--leading
{
margin-right
:
0.
2
rem
;
margin-right
:
0.
5
rem
;
margin-left
:
0.2rem
;
}
...
...
@@ -1356,30 +1526,6 @@ body.resizing .resize-handle {
visibility
:
hidden
;
}
/* Define the animation for the arrow when it is clicked. */
.extra-network-tree
.tree-list-content-dir
[
expanded
=
false
]
.tree-list-item-action-chevron
{
-ms-transform
:
rotate
(
135deg
);
-webkit-transform
:
rotate
(
135deg
);
transform
:
rotate
(
135deg
);
transition
:
transform
0.2s
;
}
.extra-network-tree
.tree-list-content-dir
[
expanded
=
true
]
.tree-list-item-action-chevron
{
-ms-transform
:
rotate
(
225deg
);
-webkit-transform
:
rotate
(
225deg
);
transform
:
rotate
(
225deg
);
transition
:
transform
0.2s
;
}
.tree-list-item-action-chevron
{
display
:
inline-flex
;
/* Uses box shadow to generate a pseudo chevron `>` icon. */
padding
:
0.3rem
;
box-shadow
:
0.1rem
0.1rem
0
0
var
(
--neutral-200
)
inset
;
transform
:
rotate
(
135deg
);
}
.extra-network-tree
.tree-list-item-action--leading
{
grid-area
:
leading-action
;
}
...
...
@@ -1399,41 +1545,3 @@ body.resizing .resize-handle {
.extra-network-tree
.tree-list-content
:hover
.button-row
{
visibility
:
visible
;
}
/* Add icon to left side of <input> */
.extra-network-tree
.tree-list-search
::before
{
content
:
"🔎︎"
;
position
:
absolute
;
margin
:
0.5rem
;
font-size
:
1rem
;
color
:
var
(
--input-placeholder-color
);
}
.extra-network-tree
.tree-list-search
{
position
:
relative
;
margin
:
0.5rem
;
}
.extra-network-tree
.tree-list-search
.tree-list-search-text
{
border
:
1px
solid
var
(
--button-secondary-border-color
);
border-radius
:
0.5rem
;
color
:
var
(
--button-secondary-text-color
);
background-color
:
transparent
;
width
:
100%
;
padding-left
:
2rem
;
line-height
:
1rem
;
}
/* <input> clear button (x on right side) styling */
.extra-network-tree
.tree-list-search
.tree-list-search-text
::-webkit-search-cancel-button
{
-webkit-appearance
:
none
;
appearance
:
none
;
cursor
:
pointer
;
height
:
1rem
;
width
:
1rem
;
mask-image
:
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>')
;
mask-repeat
:
no-repeat
;
mask-position
:
center
center
;
mask-size
:
100%
;
background-color
:
var
(
--input-placeholder-color
);
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment