@getaster/elements 0.1.0-preview.1 → 0.3.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/NOTICE +3 -8
- package/README.md +68 -3
- package/dist/carousel/carousel.js +12 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/tabs/tabs.js +18 -4
- package/package.json +14 -2
- package/styles/aster-ui.css +4 -0
- package/styles/elements.css +4 -0
package/NOTICE
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
@getaster/elements
|
|
2
2
|
Copyright 2026 Aster UI contributors
|
|
3
3
|
|
|
4
|
-
Aster UI
|
|
5
|
-
|
|
6
|
-
their respective licenses. The binary's attribution inventory and license texts
|
|
7
|
-
are supplied in packages/mock/wasm/; packages include those notices when shipped.
|
|
8
|
-
|
|
9
|
-
Geist and IBM Plex Mono fonts retain their SIL Open Font License notices.
|
|
10
|
-
ECharts is an optional separately loaded third-party runtime.
|
|
4
|
+
Aster UI code in this package is licensed under the Apache License, Version 2.0.
|
|
5
|
+
See LICENSE. Separately installed dependencies retain their respective licenses.
|
package/README.md
CHANGED
|
@@ -1,7 +1,72 @@
|
|
|
1
1
|
# @getaster/elements
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Browser-native controls for metadata-driven enterprise applications: grids,
|
|
4
|
+
forms, pickers, filters, dashboards and workspaces. Controls share records and
|
|
5
|
+
edit state through `@getaster/data` and use CSS for layout and theming.
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
Aster is pre-1.0; production API stability is not yet promised. Experimental
|
|
8
|
+
controls are published separately in `@getaster/elements-preview`.
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
npm install @getaster/data @getaster/elements
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Use a modern browser with custom elements and ES modules, plus a bundler that
|
|
17
|
+
resolves npm modules and CSS imports. The package ships TypeScript declarations.
|
|
18
|
+
Its main entry registers browser elements and requires a DOM; use
|
|
19
|
+
`@getaster/data` for headless work. Package tooling requires Node 22 or later.
|
|
20
|
+
|
|
21
|
+
## Connect a grid
|
|
22
|
+
|
|
23
|
+
With an OData service exposing a `Projects` entity set and JSON CSDL metadata:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
import { DataContext, fetchTransport } from '@getaster/data';
|
|
27
|
+
import { Grid } from '@getaster/elements';
|
|
28
|
+
import '@getaster/elements/styles/aster-ui.css';
|
|
29
|
+
|
|
30
|
+
const ctx = await DataContext.connect(
|
|
31
|
+
fetchTransport('https://your-service.example/odata/')
|
|
32
|
+
);
|
|
33
|
+
const grid = new Grid();
|
|
34
|
+
grid.ctx = ctx;
|
|
35
|
+
grid.set = 'Projects';
|
|
36
|
+
grid.label = 'Projects';
|
|
37
|
+
grid.style.height = '24rem';
|
|
38
|
+
document.body.append(grid);
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Replace the endpoint and entity set with your own. Give a virtualized grid a
|
|
42
|
+
bounded height, and supply your application's theme tokens as described in the
|
|
43
|
+
[theming guide](https://ui.getaster.now/docs/guide/themes.html). When the view
|
|
44
|
+
closes, remove the element; separately owned data models remain the host's
|
|
45
|
+
responsibility.
|
|
46
|
+
|
|
47
|
+
## Compose an application
|
|
48
|
+
|
|
49
|
+
Use a shared data context to connect a grid, form and selection. JavaScript and
|
|
50
|
+
YAML composition support reusable workspace definitions. Controls provide
|
|
51
|
+
keyboard interaction and semantic markup; application labels, focus flow and
|
|
52
|
+
accessibility still need testing in the completed application.
|
|
53
|
+
|
|
54
|
+
The package depends on Aster's data core, Lit HTML and Preact signals. Keep one
|
|
55
|
+
compatible copy of each shared runtime in your build. The optional ECharts
|
|
56
|
+
adapter accepts an application-supplied runtime; ECharts, showcase data, fonts
|
|
57
|
+
and the mock service are not bundled into this package. There are no install
|
|
58
|
+
scripts.
|
|
59
|
+
|
|
60
|
+
## Documentation and support
|
|
61
|
+
|
|
62
|
+
- [Get started](https://ui.getaster.now/docs/guide/getting-started.html)
|
|
63
|
+
- [Connected views](https://ui.getaster.now/docs/guide/connected-views.html)
|
|
64
|
+
- [Workspace composition](https://ui.getaster.now/docs/guide/declarative-workspace.html)
|
|
65
|
+
- [API reference](https://ui.getaster.now/docs/reference/)
|
|
66
|
+
- [Interactive showcase](https://ui.getaster.now/showcase/)
|
|
67
|
+
- [Report a bug](https://github.com/GetAster/aster-ui/issues)
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
Apache-2.0. See the included `LICENSE` and package-specific `NOTICE`.
|
|
72
|
+
Separately installed dependencies retain their own licenses.
|
|
@@ -14,6 +14,7 @@ export class Carousel extends AsterElement {
|
|
|
14
14
|
/** The slides don't all fit: only then are there places to move to. */
|
|
15
15
|
#overflows = this.prop(false);
|
|
16
16
|
#resize;
|
|
17
|
+
#resizeFrame = 0;
|
|
17
18
|
#id = uid("aster-carousel");
|
|
18
19
|
#observer;
|
|
19
20
|
/** Rebuilt when descriptors change or the element reconnects. */
|
|
@@ -59,6 +60,8 @@ export class Carousel extends AsterElement {
|
|
|
59
60
|
disconnectedCallback() {
|
|
60
61
|
this.#observer?.disconnect();
|
|
61
62
|
this.#resize?.disconnect();
|
|
63
|
+
cancelAnimationFrame(this.#resizeFrame);
|
|
64
|
+
this.#resizeFrame = 0;
|
|
62
65
|
this.#observed = undefined;
|
|
63
66
|
super.disconnectedCallback();
|
|
64
67
|
}
|
|
@@ -122,7 +125,15 @@ export class Carousel extends AsterElement {
|
|
|
122
125
|
for (const el of this.#slideEls())
|
|
123
126
|
this.#observer.observe(el);
|
|
124
127
|
this.#resize?.disconnect();
|
|
125
|
-
this.#resize = new ResizeObserver(() =>
|
|
128
|
+
this.#resize = new ResizeObserver(() => {
|
|
129
|
+
// Adding navigation changes the rail's layout; commit outside observer delivery.
|
|
130
|
+
if (this.#resizeFrame)
|
|
131
|
+
return;
|
|
132
|
+
this.#resizeFrame = requestAnimationFrame(() => {
|
|
133
|
+
this.#resizeFrame = 0;
|
|
134
|
+
this.#overflows.value = rail.scrollWidth > rail.clientWidth + 1;
|
|
135
|
+
});
|
|
136
|
+
});
|
|
126
137
|
this.#resize.observe(rail);
|
|
127
138
|
for (const el of this.#slideEls())
|
|
128
139
|
this.#resize.observe(el);
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { ProgressStatus } from "./progress/status.ts";
|
|
|
2
2
|
export { provideProgressPolicy, progressPolicyOf } from "./progress/policy.ts";
|
|
3
3
|
export { asterComponents } from "./composition/builtins.ts";
|
|
4
4
|
export { Sidebar, sidebarItems, type SidebarItem } from "./sidebar/sidebar.ts";
|
|
5
|
-
export { AsterElement, define, each, provideScope, read, scopeOf, type Bindable, type View } from "./base/element.ts";
|
|
5
|
+
export { AsterElement, define, each, uid, provideScope, read, scopeOf, type Bindable, type View } from "./base/element.ts";
|
|
6
6
|
export { Composite, compositeComponent, type CompositeOptions, type CompositeChildHandle, type CompositePlacement } from "./composition/composite.ts";
|
|
7
7
|
export { CommandBar } from "./composition/command-bar.ts";
|
|
8
8
|
export { defineCompositeRegistry, defineCompositeRenderer, CompositeAuthoring, type RegistryCatalog, type CompositeDiagnostic, type CompositeCompletion } from "./composition/authoring.ts";
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ export { ProgressStatus } from "./progress/status.js";
|
|
|
2
2
|
export { provideProgressPolicy, progressPolicyOf } from "./progress/policy.js";
|
|
3
3
|
export { asterComponents } from "./composition/builtins.js";
|
|
4
4
|
export { Sidebar, sidebarItems } from "./sidebar/sidebar.js";
|
|
5
|
-
export { AsterElement, define, each, provideScope, read, scopeOf } from "./base/element.js";
|
|
5
|
+
export { AsterElement, define, each, uid, provideScope, read, scopeOf } from "./base/element.js";
|
|
6
6
|
export { Composite, compositeComponent } from "./composition/composite.js";
|
|
7
7
|
export { CommandBar } from "./composition/command-bar.js";
|
|
8
8
|
export { defineCompositeRegistry, defineCompositeRenderer, CompositeAuthoring } from "./composition/authoring.js";
|
package/dist/tabs/tabs.js
CHANGED
|
@@ -108,10 +108,24 @@ export class Tabs extends AsterElement {
|
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
110
|
#revealSelected() {
|
|
111
|
-
this.querySelector(".aster-tabs")?.querySelector('[role="tab"][aria-selected="true"]')
|
|
111
|
+
const tab = this.querySelector(".aster-tabs")?.querySelector('[role="tab"][aria-selected="true"]');
|
|
112
|
+
if (tab)
|
|
113
|
+
this.#reveal(tab);
|
|
114
|
+
}
|
|
115
|
+
/** Reveal within the strip without scrolling the containing page or panel. */
|
|
116
|
+
#reveal(tab) {
|
|
117
|
+
const viewport = this.querySelector(".aster-tabs-viewport");
|
|
118
|
+
if (!viewport)
|
|
119
|
+
return;
|
|
120
|
+
const visible = viewport.getBoundingClientRect();
|
|
121
|
+
const target = tab.getBoundingClientRect();
|
|
122
|
+
const left = target.left < visible.left ? target.left - visible.left : Math.max(0, target.right - visible.right);
|
|
123
|
+
if (left)
|
|
124
|
+
viewport.scrollBy({ left, behavior: "instant" });
|
|
112
125
|
}
|
|
113
126
|
#focusSelected() {
|
|
114
|
-
this.querySelector(".aster-tabs")?.querySelector('[role="tab"][aria-selected="true"]')?.focus();
|
|
127
|
+
this.querySelector(".aster-tabs")?.querySelector('[role="tab"][aria-selected="true"]')?.focus({ preventScroll: true });
|
|
128
|
+
this.#revealSelected();
|
|
115
129
|
}
|
|
116
130
|
/** Stable for a value while the element lives; encoded so any value is a valid single id token. */
|
|
117
131
|
#tabId(value) {
|
|
@@ -193,8 +207,8 @@ export class Tabs extends AsterElement {
|
|
|
193
207
|
}
|
|
194
208
|
e.preventDefault();
|
|
195
209
|
tabs.forEach((tab, index) => { tab.tabIndex = index === n ? 0 : -1; });
|
|
196
|
-
tabs[n].focus();
|
|
197
|
-
tabs[n]
|
|
210
|
+
tabs[n].focus({ preventScroll: true });
|
|
211
|
+
this.#reveal(tabs[n]);
|
|
198
212
|
if (this.#activation.peek() === "automatic")
|
|
199
213
|
this.#choose(tabs[n].dataset.value);
|
|
200
214
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getaster/elements",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"./styles/*": "./styles/*"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@getaster/data": "0.
|
|
14
|
+
"@getaster/data": "0.3.0",
|
|
15
15
|
"@preact/signals-core": "1.14.4",
|
|
16
16
|
"lit-html": "3.3.3"
|
|
17
17
|
},
|
|
@@ -24,6 +24,18 @@
|
|
|
24
24
|
"url": "git+https://github.com/GetAster/aster-ui.git",
|
|
25
25
|
"directory": "packages/elements"
|
|
26
26
|
},
|
|
27
|
+
"description": "Browser-native grids, forms and workspace controls backed by shared Aster data models.",
|
|
28
|
+
"homepage": "https://ui.getaster.now/docs/guide/getting-started.html",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/GetAster/aster-ui/issues"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"web-components",
|
|
34
|
+
"odata",
|
|
35
|
+
"grid",
|
|
36
|
+
"forms",
|
|
37
|
+
"typescript"
|
|
38
|
+
],
|
|
27
39
|
"types": "./dist/index.d.ts",
|
|
28
40
|
"publishConfig": {
|
|
29
41
|
"access": "public"
|
package/styles/aster-ui.css
CHANGED
|
@@ -462,6 +462,10 @@
|
|
|
462
462
|
.aster-window-bar button:hover { background: var(--aster-accent-soft); color: var(--aster-text); }
|
|
463
463
|
.aster-window-bar button:focus-visible { outline: 2px solid var(--aster-focus); outline-offset: -2px; }
|
|
464
464
|
.aster-window-bar svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; }
|
|
465
|
+
@media (max-width: 600px), (pointer: coarse) and (max-height: 500px) {
|
|
466
|
+
.aster-window { left:8px; top:8px; width:calc(100vw - 16px) !important; height:min(420px, calc(100dvh - 16px)) !important; resize:none; }
|
|
467
|
+
.aster-window-bar .aster-window-move, .aster-window-bar button[aria-describedby$="-resize-help"] { display:none; }
|
|
468
|
+
}
|
|
465
469
|
.aster-window-body { flex: 1; min-height: 0; overflow: auto; padding: var(--aster-pad) 14px; }
|
|
466
470
|
/* Dashboard geometry stays in CSS; stored sizes are column/row intent. */
|
|
467
471
|
aster-dashboard { display: block; min-width: 0; container-type: inline-size; }
|
package/styles/elements.css
CHANGED
|
@@ -373,6 +373,10 @@
|
|
|
373
373
|
.aster-window-bar button:hover { background: var(--aster-accent-soft); color: var(--aster-text); }
|
|
374
374
|
.aster-window-bar button:focus-visible { outline: 2px solid var(--aster-focus); outline-offset: -2px; }
|
|
375
375
|
.aster-window-bar svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.4; stroke-linecap: round; }
|
|
376
|
+
@media (max-width: 600px), (pointer: coarse) and (max-height: 500px) {
|
|
377
|
+
.aster-window { left:8px; top:8px; width:calc(100vw - 16px) !important; height:min(420px, calc(100dvh - 16px)) !important; resize:none; }
|
|
378
|
+
.aster-window-bar .aster-window-move, .aster-window-bar button[aria-describedby$="-resize-help"] { display:none; }
|
|
379
|
+
}
|
|
376
380
|
.aster-window-body { flex: 1; min-height: 0; overflow: auto; padding: var(--aster-pad) 14px; }
|
|
377
381
|
/* Dashboard geometry stays in CSS; stored sizes are column/row intent. */
|
|
378
382
|
aster-dashboard { display: block; min-width: 0; container-type: inline-size; }
|