staffa 0.3.1 → 0.4.1
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 +45 -23
- package/dist/components/box.d.ts +2 -2
- package/dist/components/box.js +3 -4
- package/dist/components/button.d.ts +9 -11
- package/dist/components/button.js +16 -18
- package/dist/components/buttonChooser.d.ts +5 -5
- package/dist/components/buttonChooser.js +7 -5
- package/dist/components/buttonGroup.d.ts +3 -3
- package/dist/components/buttonGroup.js +5 -5
- package/dist/components/dialog.d.ts +2 -2
- package/dist/components/dialog.js +10 -10
- package/dist/components/form.d.ts +4 -4
- package/dist/components/form.js +6 -6
- package/dist/components/main.d.ts +5 -5
- package/dist/components/main.js +28 -40
- package/dist/components/menu.d.ts +4 -4
- package/dist/components/menu.js +8 -6
- package/dist/components/tabs.d.ts +3 -3
- package/dist/components/tabs.js +1 -1
- package/dist/components/toast.d.ts +1 -3
- package/dist/components/toast.js +2 -2
- package/dist/components/tooltip.js +2 -2
- package/dist/core.d.ts +10 -4
- package/dist/core.js +13 -0
- package/dist/index.d.ts +19 -65
- package/dist/index.js +18 -48
- package/dist/staffa.esm.js +1 -1
- package/dist/theme.d.ts +0 -7
- package/dist/theme.js +37 -14
- package/package.json +9 -2
- package/src/components/box.ts +5 -5
- package/src/components/button.ts +21 -22
- package/src/components/buttonChooser.ts +10 -8
- package/src/components/buttonGroup.ts +5 -4
- package/src/components/dialog.ts +10 -10
- package/src/components/form.ts +8 -8
- package/src/components/main.ts +31 -40
- package/src/components/menu.ts +9 -7
- package/src/components/tabs.ts +4 -4
- package/src/components/toast.ts +3 -5
- package/src/components/tooltip.ts +2 -2
- package/src/core.ts +16 -5
- package/src/index.ts +21 -76
- package/src/theme.ts +36 -22
package/dist/components/main.js
CHANGED
|
@@ -15,8 +15,9 @@ A.insertGlobalCss({
|
|
|
15
15
|
"> header .s-title": "font-weight:800 font-size:1.1em line-height:1.2 overflow:hidden text-overflow:ellipsis white-space:nowrap letter-spacing:-0.01em background: $s-gradient; -webkit-background-clip:text; background-clip:text; color:transparent; width:fit-content max-width:100%",
|
|
16
16
|
"> header .s-subtitle": "fg:$s-fg-muted font-size:0.85em overflow:hidden text-overflow:ellipsis white-space:nowrap",
|
|
17
17
|
"> header .s-menu": "display:flex align-items:center gap:$2",
|
|
18
|
-
// Body
|
|
19
|
-
//
|
|
18
|
+
// Body always wraps <main> (with or without a sidebar) so max-width centering
|
|
19
|
+
// and scrollbar alignment work identically in both cases.
|
|
20
|
+
// .s-body centres .s-body-inner; .s-body-inner caps the content to maxWidth.
|
|
20
21
|
".s-body": "flex:1 overflow:hidden display:flex flex-direction:row min-height:0 justify-content:center",
|
|
21
22
|
".s-body-inner": "flex:1 display:flex flex-direction:row min-height:0",
|
|
22
23
|
// Put the sidebar on the right (content fills the left) for right-hand navs.
|
|
@@ -24,20 +25,19 @@ A.insertGlobalCss({
|
|
|
24
25
|
// A vertical hairline between sidebar and content, fading out at both ends —
|
|
25
26
|
// the vertical sibling of the menu's `hr.s-menu-sep`.
|
|
26
27
|
".s-nav-sep": "width:1px flex-shrink:0 align-self:stretch margin: 0.6rem 0; border:0 background: linear-gradient(to bottom, transparent, $s-border-strong 18%, $s-border-strong 82%, transparent);",
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
//
|
|
31
|
-
// drawMainContent); with one, `.s-body-inner` does the capping for the trio.
|
|
28
|
+
// min-height:0 overrides the flex default of min-height:auto so <main> can
|
|
29
|
+
// shrink to fit the bounded container and show its own scrollbar.
|
|
30
|
+
".s-body main": "flex:1 min-height:0 overflow-y:auto display:flex flex-direction:column",
|
|
31
|
+
// The content area fills the scroll region with comfortable padding.
|
|
32
32
|
// It is deliberately NOT a boxed "sheet" — content brings its own boxes.
|
|
33
|
-
"
|
|
33
|
+
".s-body main > .s-content": "width:100% flex:1 p:$3",
|
|
34
34
|
// When <main> actually shows a vertical scrollbar (the `.s-scroll-y` class is
|
|
35
35
|
// toggled from JS by watchVerticalOverflow), inset it from the shell edge by
|
|
36
36
|
// $3 so the bar's right edge lines up with the header/footer content (which
|
|
37
37
|
// sits $3 inside the edge via `.s-bar` padding). The $3 gap between the content
|
|
38
38
|
// and the bar already comes from `.s-content`'s padding. Without a scrollbar
|
|
39
39
|
// there's no margin, so the content keeps its single $3 edge — not 2×$3.
|
|
40
|
-
"
|
|
40
|
+
".s-body main.s-scroll-y": "margin-right:$3",
|
|
41
41
|
},
|
|
42
42
|
// Sidebar nav panel. Items reuse the shared `.s-menu-item[-link]` /
|
|
43
43
|
// `.s-menu-sep` styles from menu.ts, so the sidebar and the floating
|
|
@@ -63,6 +63,9 @@ A.insertGlobalCss({
|
|
|
63
63
|
// On phones a top-level content box becomes a full-bleed block: pull it out
|
|
64
64
|
// to negate the content padding and drop the rounded corners.
|
|
65
65
|
".s-content > .s-box": "margin-inline: calc(-1 * $3); r:0 border-inline:0",
|
|
66
|
+
// At narrow widths, content boxes are full-bleed so there's no inset to
|
|
67
|
+
// align the scrollbar with — cancel the right margin.
|
|
68
|
+
".s-main .s-body main.s-scroll-y": "margin-right:0",
|
|
66
69
|
},
|
|
67
70
|
});
|
|
68
71
|
/**
|
|
@@ -85,7 +88,7 @@ A.insertGlobalCss({
|
|
|
85
88
|
* ],
|
|
86
89
|
* },
|
|
87
90
|
* navPosition: "left",
|
|
88
|
-
* menu: () => S.button({
|
|
91
|
+
* menu: () => S.button({ content: "New", attrs: ".small" }),
|
|
89
92
|
* content: () => drawPage(),
|
|
90
93
|
* footer: "© 2026",
|
|
91
94
|
* });
|
|
@@ -146,31 +149,28 @@ export function main(opts = {}) {
|
|
|
146
149
|
});
|
|
147
150
|
A(() => {
|
|
148
151
|
if (opts.menu)
|
|
149
|
-
A("div.s-menu", () => opts.menu
|
|
152
|
+
A("div.s-menu", () => drawSlot(opts.menu));
|
|
150
153
|
});
|
|
151
154
|
});
|
|
152
155
|
});
|
|
153
156
|
});
|
|
154
|
-
// Body
|
|
155
|
-
//
|
|
156
|
-
|
|
157
|
-
A("div.s-body", () => {
|
|
158
|
-
A(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
157
|
+
// Body always wraps <main> so max-width centering and scrollbar alignment
|
|
158
|
+
// are identical with and without a sidebar nav.
|
|
159
|
+
A("div.s-body", () => {
|
|
160
|
+
A("div.s-body-inner", () => {
|
|
161
|
+
A(() => {
|
|
162
|
+
if (opts.maxWidth != null)
|
|
163
|
+
A("max-width:", opts.maxWidth);
|
|
164
|
+
});
|
|
165
|
+
if (hasNav && navPos !== "button") {
|
|
163
166
|
A(`nav.s-nav-panel.s-s.raised.s-nav-${navPos}`, opts.navAttrs, () => {
|
|
164
167
|
drawMenu(nav.items);
|
|
165
168
|
});
|
|
166
169
|
A("div.s-nav-sep aria-hidden=true");
|
|
167
|
-
|
|
168
|
-
|
|
170
|
+
}
|
|
171
|
+
drawMainContent(opts);
|
|
169
172
|
});
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
drawMainContent(opts, true);
|
|
173
|
-
}
|
|
173
|
+
});
|
|
174
174
|
// Footer — full-width background, content centred to maxWidth via .s-bar.
|
|
175
175
|
A(() => {
|
|
176
176
|
if (opts.footer != null) {
|
|
@@ -187,22 +187,10 @@ export function main(opts = {}) {
|
|
|
187
187
|
});
|
|
188
188
|
});
|
|
189
189
|
}
|
|
190
|
-
|
|
191
|
-
* Draw the scrollable `<main>` + content area. When `capWidth` is true (no
|
|
192
|
-
* sidebar), the content caps its own width to maxWidth and centres; in sidebar
|
|
193
|
-
* mode the surrounding `.s-body-inner` already caps the sidebar+content trio.
|
|
194
|
-
*/
|
|
195
|
-
function drawMainContent(opts, capWidth) {
|
|
190
|
+
function drawMainContent(opts) {
|
|
196
191
|
const mainEl = A("main", () => {
|
|
197
192
|
A("div.s-content", opts.contentAttrs, () => {
|
|
198
|
-
|
|
199
|
-
A(() => {
|
|
200
|
-
if (opts.maxWidth != null)
|
|
201
|
-
A("margin-inline:auto max-width:", opts.maxWidth);
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
if (opts.content)
|
|
205
|
-
opts.content();
|
|
193
|
+
drawSlot(opts.content);
|
|
206
194
|
});
|
|
207
195
|
});
|
|
208
196
|
watchVerticalOverflow(mainEl);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type Slot, type Attributes } from "../core.js";
|
|
2
2
|
import { type ButtonOptions } from "./button.js";
|
|
3
3
|
/**
|
|
4
4
|
* A clickable item in a menu or sidebar nav.
|
|
@@ -36,10 +36,10 @@ export interface MenuSeparator {
|
|
|
36
36
|
* An entry in a menu or sidebar nav list. Three forms:
|
|
37
37
|
* - `MenuItem` — a clickable/linkable row with label and optional icon.
|
|
38
38
|
* - `MenuSeparator` — a visual divider (`{ separator: true }`).
|
|
39
|
-
* - A draw function
|
|
39
|
+
* - A slot (string or draw function) — renders custom content (section header,
|
|
40
40
|
* avatar, search box, …). Skipped by keyboard navigation.
|
|
41
41
|
*/
|
|
42
|
-
export type MenuEntry = MenuItem | MenuSeparator |
|
|
42
|
+
export type MenuEntry = MenuItem | MenuSeparator | Slot;
|
|
43
43
|
/** Options for {@link menuButton} and {@link MainOptions.nav}. */
|
|
44
44
|
export interface MenuOptions {
|
|
45
45
|
/** Items shown in the dropdown or sidebar nav. */
|
|
@@ -106,7 +106,7 @@ export declare function showFloatingMenu(opts: FloatingMenuOptions): () => void;
|
|
|
106
106
|
* @example
|
|
107
107
|
* ```ts
|
|
108
108
|
* S.menuButton({
|
|
109
|
-
* button: {
|
|
109
|
+
* button: { content: "Actions", attrs: ".neutral .outlined" },
|
|
110
110
|
* items: [
|
|
111
111
|
* { label: "Edit", icon: () => A("#✎"), click: () => edit() },
|
|
112
112
|
* { separator: true },
|
package/dist/components/menu.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import A from "aberdeen";
|
|
2
2
|
import { matchCurrent } from "aberdeen/route";
|
|
3
|
-
import { drawSlot } from "../core.js";
|
|
3
|
+
import { drawSlot, mountPortal } from "../core.js";
|
|
4
4
|
import { button } from "./button.js";
|
|
5
5
|
// Styles shared by the floating dropdown and the sidebar nav, so both look
|
|
6
6
|
// identical. The item styles aren't scoped to a container, so `drawMenu` can
|
|
@@ -68,8 +68,8 @@ export function drawMenu(items, onActivate) {
|
|
|
68
68
|
els[next].focus();
|
|
69
69
|
});
|
|
70
70
|
for (const entry of items) {
|
|
71
|
-
if (typeof entry === "function") {
|
|
72
|
-
entry
|
|
71
|
+
if (typeof entry === "string" || typeof entry === "function") {
|
|
72
|
+
drawSlot(entry);
|
|
73
73
|
continue;
|
|
74
74
|
}
|
|
75
75
|
if ("separator" in entry) {
|
|
@@ -122,7 +122,7 @@ function positionMenu(menuEl, rect) {
|
|
|
122
122
|
menuEl.style.left = Math.max(8, x) + "px";
|
|
123
123
|
menuEl.style.top = Math.max(8, y) + "px";
|
|
124
124
|
}
|
|
125
|
-
|
|
125
|
+
mountPortal(() => {
|
|
126
126
|
const f = $floating.opts;
|
|
127
127
|
if (!f)
|
|
128
128
|
return;
|
|
@@ -187,7 +187,7 @@ export function showFloatingMenu(opts) {
|
|
|
187
187
|
* @example
|
|
188
188
|
* ```ts
|
|
189
189
|
* S.menuButton({
|
|
190
|
-
* button: {
|
|
190
|
+
* button: { content: "Actions", attrs: ".neutral .outlined" },
|
|
191
191
|
* items: [
|
|
192
192
|
* { label: "Edit", icon: () => A("#✎"), click: () => edit() },
|
|
193
193
|
* { separator: true },
|
|
@@ -202,7 +202,9 @@ export function menuButton(opts) {
|
|
|
202
202
|
closeFloating(); });
|
|
203
203
|
button({
|
|
204
204
|
icon: () => A("span aria-hidden=true #☰"),
|
|
205
|
-
|
|
205
|
+
// Only label the trigger "Open menu" when it has no visible text of its
|
|
206
|
+
// own — an aria-label would otherwise *hide* that text from AT.
|
|
207
|
+
...(opts.button?.content == null ? { ariaLabel: "Open menu" } : null),
|
|
206
208
|
attrs: ".neutral .outlined",
|
|
207
209
|
...opts.button,
|
|
208
210
|
click: (e) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Bindable, type
|
|
1
|
+
import { type Bindable, type Slot, type Attributes } from "../core.js";
|
|
2
2
|
/** A single tab definition. */
|
|
3
3
|
export interface Tab {
|
|
4
4
|
/** Stable id used as the selection value. Falls back to the array index. */
|
|
@@ -7,8 +7,8 @@ export interface Tab {
|
|
|
7
7
|
label: Slot;
|
|
8
8
|
/** Optional leading icon. */
|
|
9
9
|
icon?: Slot;
|
|
10
|
-
/** Content rendered in the panel when this tab is active. */
|
|
11
|
-
content?:
|
|
10
|
+
/** Content rendered in the panel when this tab is active. A string is rendered as rich text. */
|
|
11
|
+
content?: Slot;
|
|
12
12
|
/** Disables selecting this tab. */
|
|
13
13
|
disabled?: boolean;
|
|
14
14
|
}
|
package/dist/components/tabs.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { type Slot, type Attributes } from "../core.js";
|
|
2
|
-
import type { SurfaceRole } from "../theme.js";
|
|
3
2
|
/** Options for {@link toast}. */
|
|
4
3
|
export interface ToastOptions {
|
|
5
4
|
/** Primary message. A string is rendered as rich text. */
|
|
@@ -8,9 +7,8 @@ export interface ToastOptions {
|
|
|
8
7
|
title?: Slot;
|
|
9
8
|
/**
|
|
10
9
|
* Colour role. Defaults to `"neutral"`.
|
|
11
|
-
* Use `"success"` / `"danger"` / `"warning"` for semantic feedback.
|
|
12
10
|
*/
|
|
13
|
-
type?:
|
|
11
|
+
type?: "success" | "danger" | "warning" | "neutral";
|
|
14
12
|
/**
|
|
15
13
|
* Auto-dismiss delay in milliseconds. Defaults to `4000`.
|
|
16
14
|
* Pass `0` to make the toast persistent until dismissed manually.
|
package/dist/components/toast.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import A from "aberdeen";
|
|
2
2
|
import { grow, shrink } from "aberdeen/transitions";
|
|
3
|
-
import { drawSlot } from "../core.js";
|
|
3
|
+
import { drawSlot, mountPortal } from "../core.js";
|
|
4
4
|
A.insertGlobalCss({
|
|
5
5
|
".s-toasts": "position:fixed bottom:$3 right:$3 z-index:400 " +
|
|
6
6
|
"display:flex flex-direction:column gap:$2 " +
|
|
@@ -21,7 +21,7 @@ A.insertGlobalCss({
|
|
|
21
21
|
let toastCount = 0;
|
|
22
22
|
// Keyed by stable ID so A.onEach scopes are per-toast — removing one never re-renders others.
|
|
23
23
|
const toasts = A.proxy({});
|
|
24
|
-
|
|
24
|
+
mountPortal(() => {
|
|
25
25
|
A("div.s-toasts aria-live=polite aria-atomic=false", () => {
|
|
26
26
|
A.onEach(toasts, (entry) => {
|
|
27
27
|
const { opts } = entry;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import A from "aberdeen";
|
|
2
|
-
import { drawSlot } from "../core.js";
|
|
2
|
+
import { drawSlot, mountPortal } from "../core.js";
|
|
3
3
|
A.insertGlobalCss({
|
|
4
4
|
".s-tt-tip": {
|
|
5
5
|
"&": "position:fixed z-index:500 " +
|
|
@@ -67,7 +67,7 @@ function scheduleHide() {
|
|
|
67
67
|
}, 100);
|
|
68
68
|
}
|
|
69
69
|
// ─── Portal ──────────────────────────────────────────────────────────────────
|
|
70
|
-
|
|
70
|
+
mountPortal(() => {
|
|
71
71
|
const active = $ttActive.value;
|
|
72
72
|
if (!active)
|
|
73
73
|
return;
|
package/dist/core.d.ts
CHANGED
|
@@ -26,8 +26,6 @@ export type Attributes = string;
|
|
|
26
26
|
export type Bindable<T> = {
|
|
27
27
|
value: T;
|
|
28
28
|
};
|
|
29
|
-
/** A content function. It runs inside the relevant element's reactive scope. */
|
|
30
|
-
export type Content = () => void;
|
|
31
29
|
/**
|
|
32
30
|
* Something that renders a small piece of content: either a plain string or a
|
|
33
31
|
* draw function (for icons, badges, custom markup, ...).
|
|
@@ -47,8 +45,8 @@ export type Slot<Args extends unknown[] = []> = string | ((...args: Args) => voi
|
|
|
47
45
|
export interface ContentOptions {
|
|
48
46
|
/** Aberdeen attr/style string applied to the widget's outermost element. */
|
|
49
47
|
attrs?: Attributes;
|
|
50
|
-
/** Draws the children of this component. */
|
|
51
|
-
content?:
|
|
48
|
+
/** Draws the children of this component. A string is rendered as rich text. */
|
|
49
|
+
content?: Slot;
|
|
52
50
|
}
|
|
53
51
|
/** Generates a process-unique id, used to wire `<label for>` to its control. */
|
|
54
52
|
export declare function uniqueId(prefix?: string): string;
|
|
@@ -58,3 +56,11 @@ export declare function uniqueId(prefix?: string): string;
|
|
|
58
56
|
* `rich` markup (`*italic*`, `**bold**`, `` `code` ``, `[link](/path)`).
|
|
59
57
|
*/
|
|
60
58
|
export declare function drawSlot<Args extends unknown[] = []>(slot: Slot<Args> | undefined, ...args: Args): void;
|
|
59
|
+
/**
|
|
60
|
+
* Mount a portal (tooltip, toast, menu, dialog, …) in its own dedicated
|
|
61
|
+
* container under `<body>`. Each portal gets a private parent element because
|
|
62
|
+
* two `A.mount`s sharing one parent can't tell their nodes apart: a redraw of
|
|
63
|
+
* one (e.g. a tooltip hiding) may sweep up nodes another portal inserted
|
|
64
|
+
* earlier in the same parent (e.g. an open menu).
|
|
65
|
+
*/
|
|
66
|
+
export declare function mountPortal(draw: () => void): void;
|
package/dist/core.js
CHANGED
|
@@ -17,3 +17,16 @@ export function drawSlot(slot, ...args) {
|
|
|
17
17
|
else
|
|
18
18
|
A("rich=", slot);
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Mount a portal (tooltip, toast, menu, dialog, …) in its own dedicated
|
|
22
|
+
* container under `<body>`. Each portal gets a private parent element because
|
|
23
|
+
* two `A.mount`s sharing one parent can't tell their nodes apart: a redraw of
|
|
24
|
+
* one (e.g. a tooltip hiding) may sweep up nodes another portal inserted
|
|
25
|
+
* earlier in the same parent (e.g. an open menu).
|
|
26
|
+
*/
|
|
27
|
+
export function mountPortal(draw) {
|
|
28
|
+
const container = document.createElement("div");
|
|
29
|
+
container.style.display = "contents";
|
|
30
|
+
document.body.appendChild(container);
|
|
31
|
+
A.mount(container, draw);
|
|
32
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Import the default `S` object and call its component functions:
|
|
6
6
|
*
|
|
7
7
|
* ```ts
|
|
8
|
-
* import S from "staffa";
|
|
8
|
+
* import * as S from "staffa";
|
|
9
9
|
*
|
|
10
10
|
* S.main({
|
|
11
11
|
* title: "Hello",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* S.textline({ label: "Email", type: "email", bind: A.ref($u, "email") });
|
|
18
18
|
* S.checkbox({ label: "Remember me", bind: A.ref($u, "remember") });
|
|
19
19
|
* },
|
|
20
|
-
* actions: () => S.button({
|
|
20
|
+
* actions: () => S.button({ content: "Sign in", type: "submit" }),
|
|
21
21
|
* });
|
|
22
22
|
* }});
|
|
23
23
|
* },
|
|
@@ -29,68 +29,22 @@
|
|
|
29
29
|
* which case the component re-renders the affected parts in place when you
|
|
30
30
|
* mutate it. See `AGENTS.md` for the design philosophy.
|
|
31
31
|
*/
|
|
32
|
-
import { setDarkMode, getDarkMode } from "./theme.js";
|
|
33
|
-
import { autocomplete } from "./components/autocomplete.js";
|
|
34
|
-
import { box } from "./components/box.js";
|
|
35
|
-
import { button } from "./components/button.js";
|
|
36
|
-
import { buttonChooser } from "./components/buttonChooser.js";
|
|
37
|
-
import { buttonGroup } from "./components/buttonGroup.js";
|
|
38
|
-
import { checkbox } from "./components/checkbox.js";
|
|
39
|
-
import { form } from "./components/form.js";
|
|
40
|
-
import { main } from "./components/main.js";
|
|
41
|
-
import { menuButton, showFloatingMenu } from "./components/menu.js";
|
|
42
|
-
import { dialog, alert, confirm, prompt } from "./components/dialog.js";
|
|
43
|
-
import { select } from "./components/select.js";
|
|
44
|
-
import { tabs } from "./components/tabs.js";
|
|
45
|
-
import { textarea } from "./components/textarea.js";
|
|
46
|
-
import { textline } from "./components/textline.js";
|
|
47
|
-
import { toast } from "./components/toast.js";
|
|
48
|
-
import { addTooltip } from "./components/tooltip.js";
|
|
49
|
-
/** The Staffa component namespace. */
|
|
50
|
-
export declare const S: {
|
|
51
|
-
main: typeof main;
|
|
52
|
-
box: typeof box;
|
|
53
|
-
dialog: typeof dialog;
|
|
54
|
-
alert: typeof alert;
|
|
55
|
-
confirm: typeof confirm;
|
|
56
|
-
prompt: typeof prompt;
|
|
57
|
-
form: typeof form;
|
|
58
|
-
menuButton: typeof menuButton;
|
|
59
|
-
showFloatingMenu: typeof showFloatingMenu;
|
|
60
|
-
textline: typeof textline;
|
|
61
|
-
textarea: typeof textarea;
|
|
62
|
-
checkbox: typeof checkbox;
|
|
63
|
-
tabs: typeof tabs;
|
|
64
|
-
button: typeof button;
|
|
65
|
-
buttonChooser: typeof buttonChooser;
|
|
66
|
-
buttonGroup: typeof buttonGroup;
|
|
67
|
-
autocomplete: typeof autocomplete;
|
|
68
|
-
select: typeof select;
|
|
69
|
-
toast: typeof toast;
|
|
70
|
-
addTooltip: typeof addTooltip;
|
|
71
|
-
setDarkMode: typeof setDarkMode;
|
|
72
|
-
getDarkMode: typeof getDarkMode;
|
|
73
|
-
};
|
|
74
|
-
export default S;
|
|
75
32
|
export { setDarkMode, getDarkMode } from "./theme.js";
|
|
76
|
-
export
|
|
77
|
-
export
|
|
78
|
-
export {
|
|
33
|
+
export { autocomplete, type AutocompleteOptions, type AutocompleteOptionInput } from "./components/autocomplete.js";
|
|
34
|
+
export { box, type BoxOptions } from "./components/box.js";
|
|
35
|
+
export { button, type ButtonOptions } from "./components/button.js";
|
|
36
|
+
export { buttonChooser, type ButtonChooserOptions } from "./components/buttonChooser.js";
|
|
37
|
+
export { buttonGroup, type ButtonGroupOptions } from "./components/buttonGroup.js";
|
|
38
|
+
export { checkbox, type CheckboxOptions } from "./components/checkbox.js";
|
|
39
|
+
export { form, type FormOptions } from "./components/form.js";
|
|
40
|
+
export { main, type MainOptions } from "./components/main.js";
|
|
41
|
+
export { menuButton, showFloatingMenu, type MenuOptions, type MenuEntry, type MenuItem, type MenuSeparator, type FloatingMenuOptions } from "./components/menu.js";
|
|
42
|
+
export { dialog, alert, confirm, prompt, type DialogOptions } from "./components/dialog.js";
|
|
43
|
+
export { select, type SelectOptions, type SelectOptionInput } from "./components/select.js";
|
|
44
|
+
export { tabs, type Tab, type TabsOptions } from "./components/tabs.js";
|
|
45
|
+
export { textarea, type TextareaOptions } from "./components/textarea.js";
|
|
46
|
+
export { textline, type TextlineOptions, type TextlineType } from "./components/textline.js";
|
|
47
|
+
export { toast, type ToastOptions } from "./components/toast.js";
|
|
48
|
+
export { addTooltip, type TooltipOptions } from "./components/tooltip.js";
|
|
79
49
|
export type { FieldOptions } from "./components/field.js";
|
|
80
|
-
export type {
|
|
81
|
-
export type { MenuOptions, MenuEntry, MenuItem, MenuSeparator, FloatingMenuOptions } from "./components/menu.js";
|
|
82
|
-
export { drawMenu } from "./components/menu.js";
|
|
83
|
-
export type { ToastOptions } from "./components/toast.js";
|
|
84
|
-
export type { TooltipOptions } from "./components/tooltip.js";
|
|
85
|
-
export type { BoxOptions } from "./components/box.js";
|
|
86
|
-
export type { FormOptions } from "./components/form.js";
|
|
87
|
-
export type { TextlineOptions, TextlineType } from "./components/textline.js";
|
|
88
|
-
export type { TextareaOptions } from "./components/textarea.js";
|
|
89
|
-
export type { CheckboxOptions } from "./components/checkbox.js";
|
|
90
|
-
export type { Tab, TabsOptions } from "./components/tabs.js";
|
|
91
|
-
export type { ButtonOptions } from "./components/button.js";
|
|
92
|
-
export type { ButtonChooserOptions } from "./components/buttonChooser.js";
|
|
93
|
-
export type { ButtonGroupOptions } from "./components/buttonGroup.js";
|
|
94
|
-
export type { AutocompleteOptions, AutocompleteOptionInput } from "./components/autocomplete.js";
|
|
95
|
-
export type { SelectOptions, SelectOptionInput } from "./components/select.js";
|
|
96
|
-
export type { DialogOptions } from "./components/dialog.js";
|
|
50
|
+
export type { ContentOptions, Bindable, Slot, Attributes } from "./core.js";
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Import the default `S` object and call its component functions:
|
|
6
6
|
*
|
|
7
7
|
* ```ts
|
|
8
|
-
* import S from "staffa";
|
|
8
|
+
* import * as S from "staffa";
|
|
9
9
|
*
|
|
10
10
|
* S.main({
|
|
11
11
|
* title: "Hello",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* S.textline({ label: "Email", type: "email", bind: A.ref($u, "email") });
|
|
18
18
|
* S.checkbox({ label: "Remember me", bind: A.ref($u, "remember") });
|
|
19
19
|
* },
|
|
20
|
-
* actions: () => S.button({
|
|
20
|
+
* actions: () => S.button({ content: "Sign in", type: "submit" }),
|
|
21
21
|
* });
|
|
22
22
|
* }});
|
|
23
23
|
* },
|
|
@@ -32,50 +32,20 @@
|
|
|
32
32
|
// Importing the theme module installs spacing vars, the reactive theme and the
|
|
33
33
|
// base stylesheet. Customise it from your app with A.insertGlobalCss (see
|
|
34
34
|
// theme.ts); toggle modes with setDarkMode / getDarkMode.
|
|
35
|
-
import { setDarkMode, getDarkMode } from "./theme.js";
|
|
36
|
-
import { autocomplete } from "./components/autocomplete.js";
|
|
37
|
-
import { box } from "./components/box.js";
|
|
38
|
-
import { button } from "./components/button.js";
|
|
39
|
-
import { buttonChooser } from "./components/buttonChooser.js";
|
|
40
|
-
import { buttonGroup } from "./components/buttonGroup.js";
|
|
41
|
-
import { checkbox } from "./components/checkbox.js";
|
|
42
|
-
import { form } from "./components/form.js";
|
|
43
|
-
import { main } from "./components/main.js";
|
|
44
|
-
import { menuButton, showFloatingMenu } from "./components/menu.js";
|
|
45
|
-
import { dialog, alert, confirm, prompt } from "./components/dialog.js";
|
|
46
|
-
import { select } from "./components/select.js";
|
|
47
|
-
import { tabs } from "./components/tabs.js";
|
|
48
|
-
import { textarea } from "./components/textarea.js";
|
|
49
|
-
import { textline } from "./components/textline.js";
|
|
50
|
-
import { toast } from "./components/toast.js";
|
|
51
|
-
import { addTooltip } from "./components/tooltip.js";
|
|
52
|
-
/** The Staffa component namespace. */
|
|
53
|
-
export const S = {
|
|
54
|
-
main,
|
|
55
|
-
box,
|
|
56
|
-
dialog,
|
|
57
|
-
alert,
|
|
58
|
-
confirm,
|
|
59
|
-
prompt,
|
|
60
|
-
form,
|
|
61
|
-
menuButton,
|
|
62
|
-
showFloatingMenu,
|
|
63
|
-
textline,
|
|
64
|
-
textarea,
|
|
65
|
-
checkbox,
|
|
66
|
-
tabs,
|
|
67
|
-
button,
|
|
68
|
-
buttonChooser,
|
|
69
|
-
buttonGroup,
|
|
70
|
-
autocomplete,
|
|
71
|
-
select,
|
|
72
|
-
toast,
|
|
73
|
-
addTooltip,
|
|
74
|
-
setDarkMode,
|
|
75
|
-
getDarkMode,
|
|
76
|
-
};
|
|
77
|
-
export default S;
|
|
78
|
-
// Re-export theming and shared types for advanced use.
|
|
79
35
|
export { setDarkMode, getDarkMode } from "./theme.js";
|
|
80
|
-
export {
|
|
81
|
-
export {
|
|
36
|
+
export { autocomplete } from "./components/autocomplete.js";
|
|
37
|
+
export { box } from "./components/box.js";
|
|
38
|
+
export { button } from "./components/button.js";
|
|
39
|
+
export { buttonChooser } from "./components/buttonChooser.js";
|
|
40
|
+
export { buttonGroup } from "./components/buttonGroup.js";
|
|
41
|
+
export { checkbox } from "./components/checkbox.js";
|
|
42
|
+
export { form } from "./components/form.js";
|
|
43
|
+
export { main } from "./components/main.js";
|
|
44
|
+
export { menuButton, showFloatingMenu } from "./components/menu.js";
|
|
45
|
+
export { dialog, alert, confirm, prompt } from "./components/dialog.js";
|
|
46
|
+
export { select } from "./components/select.js";
|
|
47
|
+
export { tabs } from "./components/tabs.js";
|
|
48
|
+
export { textarea } from "./components/textarea.js";
|
|
49
|
+
export { textline } from "./components/textline.js";
|
|
50
|
+
export { toast } from "./components/toast.js";
|
|
51
|
+
export { addTooltip } from "./components/tooltip.js";
|