sol-components 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/core/activate.js +27 -0
- package/core/adopt.js +71 -0
- package/core/auth-core.js +73 -0
- package/core/auth-fetch.js +154 -0
- package/core/component-mount.js +110 -0
- package/core/defaults.js +48 -0
- package/core/define.js +15 -0
- package/core/display-target.js +166 -0
- package/core/edit-placements.js +28 -0
- package/core/editor-self.js +127 -0
- package/core/editor.js +162 -0
- package/core/events.js +27 -0
- package/core/extension-points.js +189 -0
- package/core/form-utils.js +210 -0
- package/core/from-query.js +138 -0
- package/core/from-rdf.js +52 -0
- package/core/here.js +33 -0
- package/core/include-core.js +73 -0
- package/core/inrupt-global.js +18 -0
- package/core/menu-consumer.js +41 -0
- package/core/menu-rdf.js +154 -0
- package/core/pod-ops.js +392 -0
- package/core/pod-registry.js +82 -0
- package/core/popup-proxy.js +255 -0
- package/core/rdf-core.js +280 -0
- package/core/rdf-render.js +136 -0
- package/core/rdf-utils.js +411 -0
- package/core/rdf.js +154 -0
- package/core/services.js +106 -0
- package/core/shape-to-form.js +741 -0
- package/core/sparql-safety.js +20 -0
- package/core/utils.js +196 -0
- package/dist/importmap-cdn.json +49 -0
- package/dist/importmap-local.json +49 -0
- package/dist/sol-loader.manifest.json +140 -0
- package/dist/vendor/@comunica-query-sparql.js +137851 -0
- package/dist/vendor/@inrupt-solid-client-authn-browser.js +7503 -0
- package/dist/vendor/dompurify.js +1476 -0
- package/dist/vendor/ical.js.js +9739 -0
- package/dist/vendor/marked.js +85 -0
- package/dist/vendor/n3.js +14670 -0
- package/dist/vendor/rdf-validate-shacl.js +6970 -0
- package/dist/vendor/rdflib.js +35172 -0
- package/dist/vendor/solid-logic.js +6819 -0
- package/dist/vendor/solid-ui.js +21945 -0
- package/node/sol-form.js +133 -0
- package/node/sol-include.js +55 -0
- package/node/sol-login.js +632 -0
- package/node/sol-menu.js +639 -0
- package/node/sol-query.js +116 -0
- package/package.json +133 -0
- package/web/menu-from-rdf.js +23 -0
- package/web/scripts/prefs.js +25 -0
- package/web/sol-accordion.js +114 -0
- package/web/sol-basic.js +50 -0
- package/web/sol-breadcrumb.js +131 -0
- package/web/sol-button.js +244 -0
- package/web/sol-calendar.js +465 -0
- package/web/sol-default.js +118 -0
- package/web/sol-dropdown-button.js +222 -0
- package/web/sol-feed.js +1336 -0
- package/web/sol-form.js +949 -0
- package/web/sol-full.js +43 -0
- package/web/sol-gallery.js +303 -0
- package/web/sol-include.js +246 -0
- package/web/sol-live-edit.js +415 -0
- package/web/sol-login.js +856 -0
- package/web/sol-menu.js +593 -0
- package/web/sol-modal.js +377 -0
- package/web/sol-pod-extras.js +17 -0
- package/web/sol-pod-ops.js +680 -0
- package/web/sol-pod.js +1039 -0
- package/web/sol-query.js +546 -0
- package/web/sol-rolodex.js +95 -0
- package/web/sol-search.js +402 -0
- package/web/sol-settings.js +199 -0
- package/web/sol-solidos.js +93 -0
- package/web/sol-tabs.js +445 -0
- package/web/sol-time.js +194 -0
- package/web/sol-tree-edit.js +492 -0
- package/web/sol-wac.js +456 -0
- package/web/sol-weather.js +337 -0
- package/web/sol-window.js +142 -0
- package/web/styles/buttons-css.js +108 -0
- package/web/styles/help.css +242 -0
- package/web/styles/root.css +112 -0
- package/web/styles/sol-accordion-css.js +97 -0
- package/web/styles/sol-calendar-css.js +154 -0
- package/web/styles/sol-feed-css.js +475 -0
- package/web/styles/sol-form-css.js +471 -0
- package/web/styles/sol-gallery-css.js +181 -0
- package/web/styles/sol-include-css.js +95 -0
- package/web/styles/sol-live-edit-css.js +84 -0
- package/web/styles/sol-live-edit.css +101 -0
- package/web/styles/sol-login-css.js +116 -0
- package/web/styles/sol-menu-css.js +145 -0
- package/web/styles/sol-modal-css.js +134 -0
- package/web/styles/sol-pod-css.js +187 -0
- package/web/styles/sol-pod-modal-css.js +203 -0
- package/web/styles/sol-query-css.js +140 -0
- package/web/styles/sol-query-help.css +267 -0
- package/web/styles/sol-query-one-pager.css +67 -0
- package/web/styles/sol-search-css.js +157 -0
- package/web/styles/sol-solidos-css.js +7 -0
- package/web/styles/sol-tabs-css.js +114 -0
- package/web/styles/sol-time-css.js +30 -0
- package/web/styles/sol-wac-css.js +73 -0
- package/web/styles/sol-weather-css.js +59 -0
- package/web/styles/solid-logo.svg +9 -0
- package/web/styles/view-accordion-css.js +66 -0
- package/web/styles/view-anchorlist-css.js +22 -0
- package/web/styles/view-autocomplete-css.js +59 -0
- package/web/styles/view-rolodex-css.js +102 -0
- package/web/styles/view-select-css.js +21 -0
- package/web/utils/calendar-fetch.js +388 -0
- package/web/utils/code-mirror-editor.js +82 -0
- package/web/utils/commons-fetch.js +108 -0
- package/web/utils/feed-edit.js +159 -0
- package/web/utils/feed-edit.smoke.mjs +74 -0
- package/web/utils/feed-fetch.js +573 -0
- package/web/utils/live-edit-help/csv.js +64 -0
- package/web/utils/live-edit-help/graphviz.js +41 -0
- package/web/utils/live-edit-help/jsonld.js +55 -0
- package/web/utils/live-edit-help/markdown.js +52 -0
- package/web/utils/live-edit-help/mermaid.js +48 -0
- package/web/utils/live-edit-help/turtle.js +85 -0
- package/web/utils/rdf-config.js +125 -0
- package/web/utils/renderers/csv.js +124 -0
- package/web/utils/renderers/d3-force.js +82 -0
- package/web/utils/renderers/graphviz.js +13 -0
- package/web/utils/renderers/html.js +10 -0
- package/web/utils/renderers/jsonld.js +63 -0
- package/web/utils/renderers/markdown.js +19 -0
- package/web/utils/renderers/mermaid.js +54 -0
- package/web/utils/renderers/turtle.js +51 -0
- package/web/utils/sol-query-triple-patterns.js +151 -0
- package/web/utils/sol-query-ui.js +250 -0
- package/web/utils/sol-query-views.js +32 -0
- package/web/views/_helpers.js +34 -0
- package/web/views/accordion.js +133 -0
- package/web/views/anchorlist.js +59 -0
- package/web/views/auto-complete.js +183 -0
- package/web/views/dl.js +38 -0
- package/web/views/list.js +19 -0
- package/web/views/menu.js +56 -0
- package/web/views/rolodex.js +126 -0
- package/web/views/select.js +79 -0
- package/web/views/table.js +73 -0
- package/web/views/tabs.js +57 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <sol-dropdown-button> — a trigger button that drops an RDF-defined menu.
|
|
3
|
+
*
|
|
4
|
+
* A thin presentation over <sol-menu>: same ui:Menu shape, same item kinds
|
|
5
|
+
* (ui:Link, ui:Component, command), same submenu / keyboard / command dispatch
|
|
6
|
+
* engine — but rendered as a button that opens its top-level items in a floating
|
|
7
|
+
* popup, instead of <sol-menu>'s always-open nav bar. Nothing is pre-selected
|
|
8
|
+
* (a dropdown has no content panel to fill).
|
|
9
|
+
*
|
|
10
|
+
* <sol-dropdown-button source="./menu.ttl#More" label="⋮"></sol-dropdown-button>
|
|
11
|
+
*
|
|
12
|
+
* Or declare the menu inline (no source) with a <menu> of items — `handler`
|
|
13
|
+
* names what each does (a bare action name dispatches sol-command; a
|
|
14
|
+
* custom-element tag / <a href> mounts a component); owner-gated items add
|
|
15
|
+
* `requires-write`:
|
|
16
|
+
*
|
|
17
|
+
* <sol-dropdown-button label="⋮">
|
|
18
|
+
* <menu>
|
|
19
|
+
* <button handler="installPod" requires-write>Install on my Pod…</button>
|
|
20
|
+
* <a href="about.html">About</a>
|
|
21
|
+
* </menu>
|
|
22
|
+
* </sol-dropdown-button>
|
|
23
|
+
*
|
|
24
|
+
* Command items (a ui:Component whose ui:name is a bare registry key) dispatch
|
|
25
|
+
* `sol-command` for the host app to resolve — see core/rdf-render.js. Link /
|
|
26
|
+
* component items render via the region= cascade (e.g. region="modal"); set a
|
|
27
|
+
* region on the element if you want them surfaced somewhere.
|
|
28
|
+
*
|
|
29
|
+
* Access requirements: an item declaring `acl:mode acl:Write` in the RDF is
|
|
30
|
+
* rendered with `part="requires-write"` (no policy here) — the host app decides
|
|
31
|
+
* what that means (hide / disable / …), e.g.
|
|
32
|
+
* `.cannot-write sol-dropdown-button::part(requires-write) { display: none }`.
|
|
33
|
+
*
|
|
34
|
+
* Attributes:
|
|
35
|
+
* source — URL of the ui:Menu document (where the menu data lives).
|
|
36
|
+
* `from-rdf` is accepted as a fallback for <sol-menu> parity.
|
|
37
|
+
* OPT-IN: building from RDF is inert until `web/menu-from-rdf.js`
|
|
38
|
+
* is imported; with neither attribute the inline <menu> is used and
|
|
39
|
+
* no rdflib is needed.
|
|
40
|
+
* label — trigger text (default "⋮")
|
|
41
|
+
*
|
|
42
|
+
* Parts: `trigger` (the button), `requires-write` (items needing write access).
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
import { define } from '../core/define.js';
|
|
46
|
+
import { adopt, sheetFrom } from '../core/adopt.js';
|
|
47
|
+
import { CSS as MENU_CSS } from './styles/sol-menu-css.js';
|
|
48
|
+
import { SolMenu } from './sol-menu.js';
|
|
49
|
+
|
|
50
|
+
const DD_CSS = `
|
|
51
|
+
:host {
|
|
52
|
+
display: inline-block; position: relative;
|
|
53
|
+
height: auto; overflow: visible;
|
|
54
|
+
flex: 0 0 auto; min-width: 0; max-width: none;
|
|
55
|
+
}
|
|
56
|
+
.sol-dd-trigger { font: inherit; cursor: pointer; }
|
|
57
|
+
.sol-dd-popup {
|
|
58
|
+
position: absolute; top: calc(100% + 4px); right: 0; left: auto;
|
|
59
|
+
z-index: 1000;
|
|
60
|
+
/* Explicit content width — in an abs-positioned box the inherited
|
|
61
|
+
.sol-menu-nav shrink-to-fit collapses to the trigger width. */
|
|
62
|
+
width: max-content;
|
|
63
|
+
min-width: var(--menu-popup-min-width, 200px);
|
|
64
|
+
max-width: min(90vw, 360px);
|
|
65
|
+
border: 1px solid var(--border, #e0e0e0);
|
|
66
|
+
border-radius: var(--radius-md, 8px);
|
|
67
|
+
background: var(--surface, #fff);
|
|
68
|
+
box-shadow: var(--shadow-popup, 0 8px 24px rgba(0,0,0,0.28));
|
|
69
|
+
}
|
|
70
|
+
.sol-dd-popup[hidden] { display: none; }
|
|
71
|
+
/* A dropdown has no inline content panel; items use the region= cascade. The
|
|
72
|
+
authored <menu> (and content panel) is a declaration, not UI — its items
|
|
73
|
+
are harvested into the popup, so keep the slotted source hidden. */
|
|
74
|
+
::slotted(.sol-menu-content), ::slotted(menu) { display: none; }
|
|
75
|
+
`;
|
|
76
|
+
|
|
77
|
+
const DD_SHEET = sheetFrom(MENU_CSS + DD_CSS);
|
|
78
|
+
|
|
79
|
+
class SolDropdownButton extends SolMenu {
|
|
80
|
+
static get observedAttributes() { return ['source', 'from-rdf']; }
|
|
81
|
+
|
|
82
|
+
// Where the menu data lives. `source` is canonical (sol-* launcher parity);
|
|
83
|
+
// `from-rdf` is accepted for <sol-menu> parity. With neither, the inline
|
|
84
|
+
// <menu> children are harvested instead.
|
|
85
|
+
_menuUri() { return this.getAttribute('source') || this.getAttribute('from-rdf'); }
|
|
86
|
+
|
|
87
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
88
|
+
if ((name === 'source' || name === 'from-rdf') && oldValue !== newValue && this._rendered) {
|
|
89
|
+
const uri = this._menuUri();
|
|
90
|
+
if (uri) this._loadFromRdf(uri);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
connectedCallback() {
|
|
95
|
+
if (this._rendered) return;
|
|
96
|
+
this._initShell();
|
|
97
|
+
const uri = this._menuUri();
|
|
98
|
+
if (uri) {
|
|
99
|
+
this._loadFromRdf(uri); // wrap items + _renderNav (no auto-select)
|
|
100
|
+
} else {
|
|
101
|
+
const declared = this._items.length === 0 ? this._harvestItems(this) : null;
|
|
102
|
+
if (declared?.length) this._items = declared;
|
|
103
|
+
this._renderNav();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async reload() {
|
|
108
|
+
const uri = this._menuUri();
|
|
109
|
+
if (uri) await this._loadFromRdf(uri);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
_initShell() {
|
|
113
|
+
// A dropdown is always a vertical list — pin it before _loadFromRdf can
|
|
114
|
+
// copy ui:orientation (which defaults to horizontal and would trigger the
|
|
115
|
+
// sol-menu horizontal-nav rules that collapse the popup).
|
|
116
|
+
this.setAttribute('orientation', 'vertical');
|
|
117
|
+
const root = this.shadowRoot;
|
|
118
|
+
const label = this.getAttribute('label') || '⋮'; // ⋮
|
|
119
|
+
root.innerHTML = `
|
|
120
|
+
<button class="sol-dd-trigger" part="trigger" type="button"
|
|
121
|
+
aria-haspopup="menu" aria-expanded="false">${label}</button>
|
|
122
|
+
<div class="sol-menu-nav sol-dd-popup" part="menu" role="menu" hidden></div>
|
|
123
|
+
<slot></slot>`;
|
|
124
|
+
adopt(root, { sheet: DD_SHEET, css: MENU_CSS + DD_CSS });
|
|
125
|
+
|
|
126
|
+
// A (hidden) content panel so inherited select() for link/component items
|
|
127
|
+
// has somewhere to mount; commands never touch it.
|
|
128
|
+
if (!this.querySelector(':scope > .sol-menu-content')) {
|
|
129
|
+
const content = document.createElement('div');
|
|
130
|
+
content.className = 'sol-menu-content';
|
|
131
|
+
content.hidden = true;
|
|
132
|
+
this.appendChild(content);
|
|
133
|
+
}
|
|
134
|
+
this._rendered = true;
|
|
135
|
+
|
|
136
|
+
const trigger = root.querySelector('.sol-dd-trigger');
|
|
137
|
+
const a11y = this.getAttribute('aria-label') || this.getAttribute('title');
|
|
138
|
+
if (a11y) trigger.setAttribute('aria-label', a11y);
|
|
139
|
+
trigger.addEventListener('click', (e) => { e.stopPropagation(); this._toggle(); });
|
|
140
|
+
|
|
141
|
+
this._onDocClick = (e) => {
|
|
142
|
+
if (!this.contains(e.target) && !root.contains(e.target)) this._close();
|
|
143
|
+
};
|
|
144
|
+
document.addEventListener('click', this._onDocClick);
|
|
145
|
+
|
|
146
|
+
this._onKeyDown = (e) => {
|
|
147
|
+
if (e.key === 'Escape') { this._close(); trigger.focus(); return; }
|
|
148
|
+
this._handleKeyDown(e);
|
|
149
|
+
};
|
|
150
|
+
root.addEventListener('keydown', this._onKeyDown);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Build the item buttons into the popup (reuses the shared nav-level renderer
|
|
154
|
+
// — commands, links, components, submenus). No single-item hide; visibility
|
|
155
|
+
// is the trigger's job.
|
|
156
|
+
_renderNav() {
|
|
157
|
+
const pop = this.shadowRoot.querySelector('.sol-dd-popup');
|
|
158
|
+
if (!pop) return;
|
|
159
|
+
pop.innerHTML = '';
|
|
160
|
+
this._btns = {};
|
|
161
|
+
// Render every item; items needing write declare it (part="requires-write")
|
|
162
|
+
// for the host app to gate — the dropdown takes no policy itself.
|
|
163
|
+
this._renderNavLevel(pop, this._items, 0);
|
|
164
|
+
pop.querySelectorAll('button').forEach((b, i) => b.setAttribute('tabindex', i === 0 ? '0' : '-1'));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// A dropdown has no content panel — never pre-fire.
|
|
168
|
+
_autoSelectFirst() {}
|
|
169
|
+
|
|
170
|
+
get _popup() { return this.shadowRoot.querySelector('.sol-dd-popup'); }
|
|
171
|
+
get _trigger() { return this.shadowRoot.querySelector('.sol-dd-trigger'); }
|
|
172
|
+
|
|
173
|
+
_open() {
|
|
174
|
+
this._popup.hidden = false;
|
|
175
|
+
this._trigger.setAttribute('aria-expanded', 'true');
|
|
176
|
+
// Position the popup viewport-fixed against the trigger so it escapes any
|
|
177
|
+
// ancestor that clips overflow (a tab bar, a scroll container) — an
|
|
178
|
+
// absolutely-positioned popup would be cropped there. Stays right-aligned
|
|
179
|
+
// to the trigger; tracks scroll/resize while open.
|
|
180
|
+
this._place();
|
|
181
|
+
this._onReflow = () => this._place();
|
|
182
|
+
window.addEventListener('scroll', this._onReflow, true);
|
|
183
|
+
window.addEventListener('resize', this._onReflow);
|
|
184
|
+
const first = this._popup.querySelector('button');
|
|
185
|
+
if (first) { first.setAttribute('tabindex', '0'); first.focus(); }
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
_place() {
|
|
189
|
+
const r = this._trigger.getBoundingClientRect();
|
|
190
|
+
const pop = this._popup;
|
|
191
|
+
pop.style.position = 'fixed';
|
|
192
|
+
pop.style.top = `${Math.round(r.bottom + 4)}px`;
|
|
193
|
+
pop.style.right = `${Math.round(window.innerWidth - r.right)}px`;
|
|
194
|
+
pop.style.left = 'auto';
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
_close() {
|
|
198
|
+
if (this._popup) this._popup.hidden = true;
|
|
199
|
+
this._trigger?.setAttribute('aria-expanded', 'false');
|
|
200
|
+
if (this._onReflow) {
|
|
201
|
+
window.removeEventListener('scroll', this._onReflow, true);
|
|
202
|
+
window.removeEventListener('resize', this._onReflow);
|
|
203
|
+
this._onReflow = null;
|
|
204
|
+
}
|
|
205
|
+
super._closeAllPopups(); // collapse any submenu fly-outs
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
_toggle() { (this._popup && this._popup.hidden) ? this._open() : this._close(); }
|
|
209
|
+
|
|
210
|
+
// Item clicks call this (commands) — route it to closing the whole dropdown.
|
|
211
|
+
_closeAllPopups() { this._close(); }
|
|
212
|
+
|
|
213
|
+
// Link/component items mount via the region cascade, then the dropdown closes.
|
|
214
|
+
select(name) {
|
|
215
|
+
super.select(name);
|
|
216
|
+
this._close();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
define('sol-dropdown-button', SolDropdownButton);
|
|
221
|
+
export { SolDropdownButton };
|
|
222
|
+
export default SolDropdownButton;
|