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.
Files changed (150) hide show
  1. package/README.md +7 -0
  2. package/core/activate.js +27 -0
  3. package/core/adopt.js +71 -0
  4. package/core/auth-core.js +73 -0
  5. package/core/auth-fetch.js +154 -0
  6. package/core/component-mount.js +110 -0
  7. package/core/defaults.js +48 -0
  8. package/core/define.js +15 -0
  9. package/core/display-target.js +166 -0
  10. package/core/edit-placements.js +28 -0
  11. package/core/editor-self.js +127 -0
  12. package/core/editor.js +162 -0
  13. package/core/events.js +27 -0
  14. package/core/extension-points.js +189 -0
  15. package/core/form-utils.js +210 -0
  16. package/core/from-query.js +138 -0
  17. package/core/from-rdf.js +52 -0
  18. package/core/here.js +33 -0
  19. package/core/include-core.js +73 -0
  20. package/core/inrupt-global.js +18 -0
  21. package/core/menu-consumer.js +41 -0
  22. package/core/menu-rdf.js +154 -0
  23. package/core/pod-ops.js +392 -0
  24. package/core/pod-registry.js +82 -0
  25. package/core/popup-proxy.js +255 -0
  26. package/core/rdf-core.js +280 -0
  27. package/core/rdf-render.js +136 -0
  28. package/core/rdf-utils.js +411 -0
  29. package/core/rdf.js +154 -0
  30. package/core/services.js +106 -0
  31. package/core/shape-to-form.js +741 -0
  32. package/core/sparql-safety.js +20 -0
  33. package/core/utils.js +196 -0
  34. package/dist/importmap-cdn.json +49 -0
  35. package/dist/importmap-local.json +49 -0
  36. package/dist/sol-loader.manifest.json +140 -0
  37. package/dist/vendor/@comunica-query-sparql.js +137851 -0
  38. package/dist/vendor/@inrupt-solid-client-authn-browser.js +7503 -0
  39. package/dist/vendor/dompurify.js +1476 -0
  40. package/dist/vendor/ical.js.js +9739 -0
  41. package/dist/vendor/marked.js +85 -0
  42. package/dist/vendor/n3.js +14670 -0
  43. package/dist/vendor/rdf-validate-shacl.js +6970 -0
  44. package/dist/vendor/rdflib.js +35172 -0
  45. package/dist/vendor/solid-logic.js +6819 -0
  46. package/dist/vendor/solid-ui.js +21945 -0
  47. package/node/sol-form.js +133 -0
  48. package/node/sol-include.js +55 -0
  49. package/node/sol-login.js +632 -0
  50. package/node/sol-menu.js +639 -0
  51. package/node/sol-query.js +116 -0
  52. package/package.json +133 -0
  53. package/web/menu-from-rdf.js +23 -0
  54. package/web/scripts/prefs.js +25 -0
  55. package/web/sol-accordion.js +114 -0
  56. package/web/sol-basic.js +50 -0
  57. package/web/sol-breadcrumb.js +131 -0
  58. package/web/sol-button.js +244 -0
  59. package/web/sol-calendar.js +465 -0
  60. package/web/sol-default.js +118 -0
  61. package/web/sol-dropdown-button.js +222 -0
  62. package/web/sol-feed.js +1336 -0
  63. package/web/sol-form.js +949 -0
  64. package/web/sol-full.js +43 -0
  65. package/web/sol-gallery.js +303 -0
  66. package/web/sol-include.js +246 -0
  67. package/web/sol-live-edit.js +415 -0
  68. package/web/sol-login.js +856 -0
  69. package/web/sol-menu.js +593 -0
  70. package/web/sol-modal.js +377 -0
  71. package/web/sol-pod-extras.js +17 -0
  72. package/web/sol-pod-ops.js +680 -0
  73. package/web/sol-pod.js +1039 -0
  74. package/web/sol-query.js +546 -0
  75. package/web/sol-rolodex.js +95 -0
  76. package/web/sol-search.js +402 -0
  77. package/web/sol-settings.js +199 -0
  78. package/web/sol-solidos.js +93 -0
  79. package/web/sol-tabs.js +445 -0
  80. package/web/sol-time.js +194 -0
  81. package/web/sol-tree-edit.js +492 -0
  82. package/web/sol-wac.js +456 -0
  83. package/web/sol-weather.js +337 -0
  84. package/web/sol-window.js +142 -0
  85. package/web/styles/buttons-css.js +108 -0
  86. package/web/styles/help.css +242 -0
  87. package/web/styles/root.css +112 -0
  88. package/web/styles/sol-accordion-css.js +97 -0
  89. package/web/styles/sol-calendar-css.js +154 -0
  90. package/web/styles/sol-feed-css.js +475 -0
  91. package/web/styles/sol-form-css.js +471 -0
  92. package/web/styles/sol-gallery-css.js +181 -0
  93. package/web/styles/sol-include-css.js +95 -0
  94. package/web/styles/sol-live-edit-css.js +84 -0
  95. package/web/styles/sol-live-edit.css +101 -0
  96. package/web/styles/sol-login-css.js +116 -0
  97. package/web/styles/sol-menu-css.js +145 -0
  98. package/web/styles/sol-modal-css.js +134 -0
  99. package/web/styles/sol-pod-css.js +187 -0
  100. package/web/styles/sol-pod-modal-css.js +203 -0
  101. package/web/styles/sol-query-css.js +140 -0
  102. package/web/styles/sol-query-help.css +267 -0
  103. package/web/styles/sol-query-one-pager.css +67 -0
  104. package/web/styles/sol-search-css.js +157 -0
  105. package/web/styles/sol-solidos-css.js +7 -0
  106. package/web/styles/sol-tabs-css.js +114 -0
  107. package/web/styles/sol-time-css.js +30 -0
  108. package/web/styles/sol-wac-css.js +73 -0
  109. package/web/styles/sol-weather-css.js +59 -0
  110. package/web/styles/solid-logo.svg +9 -0
  111. package/web/styles/view-accordion-css.js +66 -0
  112. package/web/styles/view-anchorlist-css.js +22 -0
  113. package/web/styles/view-autocomplete-css.js +59 -0
  114. package/web/styles/view-rolodex-css.js +102 -0
  115. package/web/styles/view-select-css.js +21 -0
  116. package/web/utils/calendar-fetch.js +388 -0
  117. package/web/utils/code-mirror-editor.js +82 -0
  118. package/web/utils/commons-fetch.js +108 -0
  119. package/web/utils/feed-edit.js +159 -0
  120. package/web/utils/feed-edit.smoke.mjs +74 -0
  121. package/web/utils/feed-fetch.js +573 -0
  122. package/web/utils/live-edit-help/csv.js +64 -0
  123. package/web/utils/live-edit-help/graphviz.js +41 -0
  124. package/web/utils/live-edit-help/jsonld.js +55 -0
  125. package/web/utils/live-edit-help/markdown.js +52 -0
  126. package/web/utils/live-edit-help/mermaid.js +48 -0
  127. package/web/utils/live-edit-help/turtle.js +85 -0
  128. package/web/utils/rdf-config.js +125 -0
  129. package/web/utils/renderers/csv.js +124 -0
  130. package/web/utils/renderers/d3-force.js +82 -0
  131. package/web/utils/renderers/graphviz.js +13 -0
  132. package/web/utils/renderers/html.js +10 -0
  133. package/web/utils/renderers/jsonld.js +63 -0
  134. package/web/utils/renderers/markdown.js +19 -0
  135. package/web/utils/renderers/mermaid.js +54 -0
  136. package/web/utils/renderers/turtle.js +51 -0
  137. package/web/utils/sol-query-triple-patterns.js +151 -0
  138. package/web/utils/sol-query-ui.js +250 -0
  139. package/web/utils/sol-query-views.js +32 -0
  140. package/web/views/_helpers.js +34 -0
  141. package/web/views/accordion.js +133 -0
  142. package/web/views/anchorlist.js +59 -0
  143. package/web/views/auto-complete.js +183 -0
  144. package/web/views/dl.js +38 -0
  145. package/web/views/list.js +19 -0
  146. package/web/views/menu.js +56 -0
  147. package/web/views/rolodex.js +126 -0
  148. package/web/views/select.js +79 -0
  149. package/web/views/table.js +73 -0
  150. 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;