Skip to content

Commit d287fb4

Browse files
jeff-zuckerclaude
andcommitted
sol-pod: gear-icon attr, dropdown scheme-strip, select min-width:0; add sol-solidos help
- sol-pod: new gear-icon attribute on the per-item action button. Treated as a URL when it contains "/" or ends in svg/png/jpg/gif/webp (rendered as <img>); otherwise used as text. Defaults to ⚙. - sol-pod: strip http(s):// from the pod dropdown options for display compactness; option .value still carries the full URL so selection/fetch are unchanged. - sol-pod-css: .item-gear img { display:block; width:1.1em; height:1.1em; pointer-events:none } and .pod-header select { min-width: 0 } so the login + settings buttons stay in the row in narrow sidebars (long URLs ellipsis- truncate inside the select). - help/sol-pod-demo: document all attributes including gear-icon and the new dropdown behavior; demo now passes gear-icon="../web/styles/solid-logo.svg". - help/sol-solidos-help (new): covers attributes, mashlib runtime deps, the known empty-window.Mashlib quirk (entry-point exports initMainPage via window.panes), and a panes-only embedding pattern that skips sol-solidos's duplicate DOM scaffolding. - home.html: surface sol-solidos as a visible row in the components table. - dist/sol-pod.umd.min.js, dist/podz-extras.bundle.min.js rebuilt. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent e3512d2 commit d287fb4

7 files changed

Lines changed: 159 additions & 6 deletions

File tree

dist/podz-extras.bundle.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/sol-pod.umd.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

help/sol-pod-demo.html

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,30 @@ <h1> sol-pod component </h1>
1212

1313
<!-- No `source` — sol-pod discovers pods from the current origin
1414
(and again on login). Discovery only finds pods when this page is
15-
served from a Solid origin. -->
16-
<sol-pod></sol-pod>
15+
served from a Solid origin.
16+
`gear-icon` swaps the default ⚙ for an image; here we use this
17+
project's Solid logo. If you omit the attribute you get the ⚙.
18+
If you give it a short string (like a single emoji) it's used
19+
as text. If it contains a slash or ends in svg/png/jpg/gif/webp
20+
it's rendered as <img>. -->
21+
<sol-pod gear-icon="../web/styles/solid-logo.svg"></sol-pod>
1722
<div id="results"></div>
1823

24+
<h3>Attributes</h3>
25+
<ul>
26+
<li><code>source</code> — pod storage URL or comma/space-separated list. Omit to auto-discover from the current origin / WebID.</li>
27+
<li><code>login</code> — CSS selector for an external <code>&lt;sol-login&gt;</code>. Omit to use the built-in one in the header.</li>
28+
<li><code>login-mode</code>, <code>login-callback</code>, <code>issuers</code>, <code>side</code> — forwarded to the built-in <code>&lt;sol-login&gt;</code>.</li>
29+
<li><code>pod-click-action</code> — function (assigned via JS property) or named handler. Receives <code>(item, podEl)</code> when the user clicks the per-item icon, presses Enter, or double-clicks. Item carries <code>{ url, name, displayName, isContainer, contentType }</code>.</li>
30+
<li><code>handler</code> — alias for <code>pod-click-action</code>.</li>
31+
<li><code>gear-icon</code> — replaces the default <code></code> per-item button. URL (contains <code>/</code> or ends in svg/png/jpg/gif/webp) → renders as <code>&lt;img&gt;</code>; otherwise used as text.</li>
32+
<li><code>pods-group</code> — shared pod-list scope across multiple <code>&lt;sol-pod&gt;</code>s on the page. Absent = default shared group; <code>'none'</code> = standalone registry.</li>
33+
</ul>
34+
35+
<h3>Pod selector display</h3>
36+
<p>The pod dropdown strips the <code>http://</code> / <code>https://</code> prefix from each option for compactness — <code>https://alice.solidcommunity.net/</code> shows as <code>alice.solidcommunity.net/</code>. The option's <code>value</code> stays the full URL so selection / fetch are unchanged.</p>
37+
<p>The selector also has <code>min-width: 0</code> in flex layouts so the login + settings buttons stay visible even in narrow sidebars; long URLs ellipsis-truncate inside the select.</p>
38+
1939
<script src="../dist/vendor/rdflib.umd.js"></script>
2040
<script src="../dist/sol-pod.umd.min.js?v=7"></script>
2141
<script>

help/sol-solidos-help.html

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<!DOCTYPE html><html lang="en"><head>
2+
<meta charset="utf-8">
3+
<title>sol-solidos</title>
4+
<script src="../web/scripts/prefs.js"></script>
5+
<link rel="stylesheet" href="../web/styles/root.css">
6+
<link rel="stylesheet" href="../web/styles/sol-query-help.css">
7+
<link rel="stylesheet" href="../web/styles/help.css">
8+
</head><body>
9+
10+
<div class="container">
11+
<h1>sol-solidos</h1>
12+
13+
<p>A custom element that mounts the
14+
<a href="https://github.com/SolidOS/mashlib">SolidOS</a> data
15+
browser inside its light DOM. Setting the <code>source</code>
16+
attribute drives <code>outliner.GotoSubject(...)</code> so the
17+
panes navigate to that resource.</p>
18+
19+
<h2>Attributes</h2>
20+
<ul>
21+
<li><code>source</code> — URL of the Solid resource to display.
22+
Setting it after the element is connected triggers a
23+
navigation. If unset on first mount, the panes initialise
24+
with <code>window.location.href</code> as the subject.</li>
25+
</ul>
26+
27+
<h2>Runtime dependencies (bring-your-own)</h2>
28+
<p>sol-solidos relies on mashlib + solid-panes (a substantial
29+
dependency tree — RDF store, panes, login UI, theme module).
30+
These are <em>not</em> in the all-in-one
31+
<code>solid-web-components.bundle.min.js</code> or in
32+
<code>podz-extras.bundle.min.js</code>. You must load mashlib
33+
separately so that <code>window.panes</code>,
34+
<code>window.SolidLogic</code>, and <code>window.Mashlib</code>
35+
are populated before sol-solidos's <code>connectedCallback</code>
36+
runs.</p>
37+
38+
<pre><code>&lt;script src="dist/vendor/rdflib.umd.js"&gt;&lt;/script&gt;
39+
&lt;script src="dist/vendor/@inrupt-solid-client-authn-browser.umd.js"&gt;&lt;/script&gt;
40+
&lt;link rel="stylesheet" href="node_modules/mashlib/dist/mash.css"&gt;
41+
&lt;script src="node_modules/mashlib/dist/mashlib.min.js"&gt;&lt;/script&gt;
42+
&lt;script src="dist/sol-solidos.umd.min.js"&gt;&lt;/script&gt;
43+
44+
&lt;sol-solidos source="https://your.pod/some/resource"&gt;&lt;/sol-solidos&gt;</code></pre>
45+
46+
<h2>Known mashlib quirk: empty <code>window.Mashlib</code></h2>
47+
<p>mashlib's UMD wrapper sets <code>window.Mashlib</code> to its
48+
entry-point exports — and its entry point
49+
(<code>./src/index.ts</code>) is pure side-effects with no
50+
exports. So <code>window.Mashlib</code> ends up an empty
51+
<code>{}</code>. sol-solidos's <code>getMashlib()</code> looks
52+
for <code>Mashlib.initMainPage</code>, which is actually exposed
53+
on <code>window.panes</code>. Patch it before mounting
54+
sol-solidos:</p>
55+
56+
<pre><code>&lt;script&gt;
57+
if (window.Mashlib &amp;&amp; window.panes &amp;&amp; window.panes.initMainPage) {
58+
window.Mashlib.initMainPage = window.panes.initMainPage;
59+
}
60+
&lt;/script&gt;
61+
&lt;sol-solidos&gt;&lt;/sol-solidos&gt;</code></pre>
62+
63+
<h2>Embedding alternative: skip sol-solidos, use panes directly</h2>
64+
<p>sol-solidos creates its own DOM scaffolding
65+
(<code>&lt;header id="PageHeader"&gt;</code>,
66+
<code>&lt;main id="mainContent"&gt;</code>,
67+
<code>&lt;footer id="PageFooter"&gt;</code>) and then calls
68+
<code>initMainPage</code>, which creates a parallel set of
69+
SolidOS-shell elements
70+
(<code>#mainSolidUiHeader</code>, <code>#MainContent</code>,
71+
<code>#PageFooter</code>) at the document body. If you want the
72+
SolidOS chrome (banner + side menu + footer) and the outline
73+
<em>without</em> the duplicate IDs, skip sol-solidos and use
74+
mashlib's lower-level API directly:</p>
75+
76+
<pre><code>&lt;body id="PageBody"&gt;
77+
&lt;solid-ui-header id="mainSolidUiHeader"&gt;&lt;span slot="title"&gt;&lt;/span&gt;&lt;/solid-ui-header&gt;
78+
&lt;main id="MainContent" role="main"&gt;
79+
&lt;div class="app-shell"&gt;
80+
&lt;aside id="NavMenu" class="app-nav" hidden&gt;&lt;div id="NavMenuContent"&gt;&lt;/div&gt;&lt;/aside&gt;
81+
&lt;div class="app-view"&gt;&lt;table id="OutlineView" class="outline-view"&gt;&lt;/table&gt;&lt;/div&gt;
82+
&lt;/div&gt;
83+
&lt;/main&gt;
84+
&lt;footer id="PageFooter"&gt;&lt;/footer&gt;
85+
&lt;script&gt;
86+
const store = window.SolidLogic.solidLogicSingleton.store;
87+
window.panes.initMainPage(store, 'https://your.pod/foo');
88+
&lt;/script&gt;
89+
&lt;/body&gt;</code></pre>
90+
91+
<p>This is the structure
92+
<a href="../../node_modules/mashlib/dist/databrowser.html">mashlib's
93+
<code>databrowser.html</code></a> uses; <code>initMainPage</code>
94+
fills the existing elements instead of creating new ones. For
95+
navigation after the initial render, hold the outliner and call
96+
it directly:</p>
97+
98+
<pre><code>const outliner = window.panes.getOutliner(document);
99+
outliner.GotoSubject(window.$rdf.sym(newUrl), true, undefined, true, undefined);</code></pre>
100+
101+
<h2>Working embedded example</h2>
102+
<p>See <a href="https://github.com/jeff-zucker/data-kitchen">data-kitchen</a>
103+
for an integration that hosts SolidOS inside a same-origin iframe
104+
(so its CSS / globals / theme handling stay contained) and drives
105+
it from a sidebar <code>&lt;sol-pod&gt;</code>.</p>
106+
107+
</div>
108+
</body></html>

home.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ <h3>Access Solid and Linked Data resources using HTML custom elements</h3>
7070
<span class="cell name" role="cell"><a href="help/sol-form-help.html">sol-form</a></span>
7171
<span class="cell" role="cell">Auto-saving editable forms bound to RDF. Two paths: <b>shape-driven</b> &mdash; point at a SHACL shape + data document and sol-form generates the inputs from the shape; <b>form-driven</b> &mdash; supply a hand-authored <code>ui:Form</code> TTL and solid-ui renders it. Includes a live SHACL-to-form demo on the help page.</span>
7272
</article>
73+
<article class="row" role="row">
74+
<span class="cell name" role="cell"><a href="help/sol-solidos-help.html">sol-solidos</a></span>
75+
<span class="cell" role="cell">Mount the SolidOS data browser (mashlib panes) inside a custom element; set <code>source</code> to navigate. Requires loading <code>mashlib</code> separately as a UMD &mdash; not in the all-in-one bundle. Help page covers the standard wiring, the known empty-<code>window.Mashlib</code> quirk, and a panes-only embedding pattern for hosts (like an iframe) that just want the outline.</span>
76+
</article>
7377
<article class="row" role="row">
7478
<span class="cell name" role="cell"><b>dashboard</b></span>
7579
<span class="cell" role="cell">A worked-example page combining <a href="help/sol-weather-help.html">sol-weather</a>, <a href="help/sol-time-help.html">sol-time</a>, <a href="help/sol-calendar-help.html">sol-calendar</a>, and <a href="help/sol-feed-help.html">sol-feed</a> into a single dashboard layout. Open <a href="dashboard.html">dashboard.html</a> in the repo root to see them all working together.</span>

web/sol-pod.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ import './sol-login.js'; // built-in login button in the pod header
4444
* @attr {string} side - auth session tag; also forwarded to the built-in sol-login as its `side`
4545
* @attr {string} pod-click-action - callback when an item is activated (gear / Enter / double-click)
4646
* @attr {string} handler - default sol-* component for file viewing
47+
* @attr {string} gear-icon - icon for the per-item action button. Treated as
48+
* a URL when it contains '/' or ends in svg/png/jpg/gif/webp;
49+
* otherwise used as text (emoji). Defaults to '⚙'.
4750
* @attr {string} pods-group - shared pod-list scope; absent = the default shared
4851
* group, 'none' = a standalone unshared registry
4952
* @property {Object} login - SolLogin element reference (external if given, else the built-in one)
@@ -488,7 +491,10 @@ class SolPod extends HTMLElement {
488491
} else {
489492
storages.forEach(url => {
490493
const opt = document.createElement('option');
491-
opt.value = url; opt.textContent = url;
494+
opt.value = url;
495+
// Strip the scheme for display; the value still carries the
496+
// full URL so selection / fetch keep working.
497+
opt.textContent = url.replace(/^https?:\/\//, '');
492498
sel.appendChild(opt);
493499
});
494500
}
@@ -733,8 +739,17 @@ class SolPod extends HTMLElement {
733739
};
734740

735741
const gear = document.createElement('button');
736-
gear.className = 'item-gear'; gear.textContent = '\u2699';
742+
gear.className = 'item-gear';
737743
gear.title = 'Actions';
744+
const iconAttr = this.getAttribute('gear-icon');
745+
if (iconAttr && /\/|\.(svg|png|jpe?g|gif|webp)$/i.test(iconAttr)) {
746+
const img = document.createElement('img');
747+
img.src = iconAttr;
748+
img.alt = '';
749+
gear.appendChild(img);
750+
} else {
751+
gear.textContent = iconAttr || '\u2699';
752+
}
738753
gear.onclick = openItemAction;
739754
li.appendChild(gear);
740755

web/styles/sol-pod-css.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ export const CSS = BTN_CSS + `
3333
}
3434
.pod-header select {
3535
flex: 1; padding: 6px 10px;
36+
/* Without min-width:0 a flex <select> reserves the width of its
37+
widest option, pushing the login + settings buttons out of the
38+
sidebar in narrow panels. */
39+
min-width: 0;
3640
border: 1px solid var(--border, #e0e0e0); border-radius: 4px;
3741
font-size: 0.9em;
3842
background: var(--surface, #fff); color: var(--text, #212121);
@@ -129,6 +133,8 @@ export const CSS = BTN_CSS + `
129133
transition: color 0.15s;
130134
}
131135
.item-gear:hover { color: var(--accent-dark, #1976d2); background: var(--focus-bg, #e3f2fd); }
136+
/* When gear-icon attribute is a URL, the button holds an <img>. */
137+
.item-gear img { display: block; width: 1.1em; height: 1.1em; pointer-events: none; }
132138
133139
.file-tree .folder { font-weight: 500; color: var(--folder-color, var(--accent-dark, #1976d2)); }
134140
.file-tree .file { color: var(--file-color, #424242); }

0 commit comments

Comments
 (0)