@signal9/era-ui 2.1.0 → 2.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/dist/ai/actions/action.svelte +41 -0
- package/dist/ai/actions/action.svelte.d.ts +12 -0
- package/dist/ai/actions/actions.svelte +15 -0
- package/dist/ai/actions/actions.svelte.d.ts +8 -0
- package/dist/ai/actions/index.d.ts +2 -0
- package/dist/ai/actions/index.js +2 -0
- package/dist/ai/artifact/artifact-actions.svelte +7 -0
- package/dist/ai/artifact/artifact-actions.svelte.d.ts +8 -0
- package/dist/ai/artifact/artifact-close.svelte +9 -0
- package/dist/ai/artifact/artifact-close.svelte.d.ts +6 -0
- package/dist/ai/artifact/artifact-content.svelte +7 -0
- package/dist/ai/artifact/artifact-content.svelte.d.ts +8 -0
- package/dist/ai/artifact/artifact-description.svelte +7 -0
- package/dist/ai/artifact/artifact-description.svelte.d.ts +8 -0
- package/dist/ai/artifact/artifact-header.svelte +16 -0
- package/dist/ai/artifact/artifact-header.svelte.d.ts +8 -0
- package/dist/ai/artifact/artifact-title.svelte +7 -0
- package/dist/ai/artifact/artifact-title.svelte.d.ts +8 -0
- package/dist/ai/artifact/artifact.svelte +16 -0
- package/dist/ai/artifact/artifact.svelte.d.ts +8 -0
- package/dist/ai/artifact/index.d.ts +8 -0
- package/dist/ai/artifact/index.js +8 -0
- package/dist/ai/chain-of-thought/chain-of-thought-step.svelte +39 -0
- package/dist/ai/chain-of-thought/chain-of-thought-step.svelte.d.ts +11 -0
- package/dist/ai/chain-of-thought/chain-of-thought.svelte +30 -0
- package/dist/ai/chain-of-thought/chain-of-thought.svelte.d.ts +11 -0
- package/dist/ai/chain-of-thought/index.d.ts +3 -0
- package/dist/ai/chain-of-thought/index.js +3 -0
- package/dist/ai/checkpoint.svelte +27 -0
- package/dist/ai/checkpoint.svelte.d.ts +10 -0
- package/dist/ai/confirmation/confirmation-actions.svelte +9 -0
- package/dist/ai/confirmation/confirmation-actions.svelte.d.ts +8 -0
- package/dist/ai/confirmation/confirmation.svelte +36 -0
- package/dist/ai/confirmation/confirmation.svelte.d.ts +11 -0
- package/dist/ai/confirmation/index.d.ts +2 -0
- package/dist/ai/confirmation/index.js +2 -0
- package/dist/ai/context/context.svelte +49 -0
- package/dist/ai/context/context.svelte.d.ts +9 -0
- package/dist/ai/context/index.d.ts +1 -0
- package/dist/ai/context/index.js +1 -0
- package/dist/ai/conversation/context.d.ts +3 -0
- package/dist/ai/conversation/context.js +12 -0
- package/dist/ai/conversation/conversation-content.svelte +32 -0
- package/dist/ai/conversation/conversation-content.svelte.d.ts +8 -0
- package/dist/ai/conversation/conversation-empty-state.svelte +32 -0
- package/dist/ai/conversation/conversation-empty-state.svelte.d.ts +11 -0
- package/dist/ai/conversation/conversation-scroll-button.svelte +27 -0
- package/dist/ai/conversation/conversation-scroll-button.svelte.d.ts +6 -0
- package/dist/ai/conversation/conversation.svelte +21 -0
- package/dist/ai/conversation/conversation.svelte.d.ts +8 -0
- package/dist/ai/conversation/index.d.ts +5 -0
- package/dist/ai/conversation/index.js +5 -0
- package/dist/ai/copy-button.svelte +42 -0
- package/dist/ai/copy-button.svelte.d.ts +8 -0
- package/dist/ai/image.svelte +19 -0
- package/dist/ai/image.svelte.d.ts +8 -0
- package/dist/ai/index.d.ts +29 -0
- package/dist/ai/index.js +31 -0
- package/dist/ai/inline-citation/index.d.ts +1 -0
- package/dist/ai/inline-citation/index.js +1 -0
- package/dist/ai/inline-citation/inline-citation.svelte +66 -0
- package/dist/ai/inline-citation/inline-citation.svelte.d.ts +11 -0
- package/dist/ai/loader.svelte +8 -0
- package/dist/ai/loader.svelte.d.ts +6 -0
- package/dist/ai/message/branch.svelte.d.ts +10 -0
- package/dist/ai/message/branch.svelte.js +28 -0
- package/dist/ai/message/context.d.ts +6 -0
- package/dist/ai/message/context.js +1 -0
- package/dist/ai/message/index.d.ts +8 -0
- package/dist/ai/message/index.js +7 -0
- package/dist/ai/message/message-branch-content.svelte +24 -0
- package/dist/ai/message/message-branch-content.svelte.d.ts +10 -0
- package/dist/ai/message/message-branch-selector.svelte +25 -0
- package/dist/ai/message/message-branch-selector.svelte.d.ts +6 -0
- package/dist/ai/message/message-branch.svelte +25 -0
- package/dist/ai/message/message-branch.svelte.d.ts +9 -0
- package/dist/ai/message/message-content.svelte +24 -0
- package/dist/ai/message/message-content.svelte.d.ts +8 -0
- package/dist/ai/message/message-toolbar.svelte +23 -0
- package/dist/ai/message/message-toolbar.svelte.d.ts +8 -0
- package/dist/ai/message/message.svelte +27 -0
- package/dist/ai/message/message.svelte.d.ts +10 -0
- package/dist/ai/model-selector/index.d.ts +1 -0
- package/dist/ai/model-selector/index.js +1 -0
- package/dist/ai/model-selector/model-selector.svelte +61 -0
- package/dist/ai/model-selector/model-selector.svelte.d.ts +15 -0
- package/dist/ai/open-in-chat/index.d.ts +1 -0
- package/dist/ai/open-in-chat/index.js +1 -0
- package/dist/ai/open-in-chat/open-in-chat.svelte +41 -0
- package/dist/ai/open-in-chat/open-in-chat.svelte.d.ts +32 -0
- package/dist/ai/plan/index.d.ts +3 -0
- package/dist/ai/plan/index.js +3 -0
- package/dist/ai/plan/plan-content.svelte +13 -0
- package/dist/ai/plan/plan-content.svelte.d.ts +8 -0
- package/dist/ai/plan/plan-header.svelte +22 -0
- package/dist/ai/plan/plan-header.svelte.d.ts +9 -0
- package/dist/ai/plan/plan.svelte +23 -0
- package/dist/ai/plan/plan.svelte.d.ts +10 -0
- package/dist/ai/prompt-input/attachments.svelte.d.ts +27 -0
- package/dist/ai/prompt-input/attachments.svelte.js +60 -0
- package/dist/ai/prompt-input/index.d.ts +7 -0
- package/dist/ai/prompt-input/index.js +7 -0
- package/dist/ai/prompt-input/prompt-input-add-attachments.svelte +12 -0
- package/dist/ai/prompt-input/prompt-input-add-attachments.svelte.d.ts +6 -0
- package/dist/ai/prompt-input/prompt-input-attachments.svelte +40 -0
- package/dist/ai/prompt-input/prompt-input-attachments.svelte.d.ts +18 -0
- package/dist/ai/prompt-input/prompt-input-submit.svelte +49 -0
- package/dist/ai/prompt-input/prompt-input-submit.svelte.d.ts +10 -0
- package/dist/ai/prompt-input/prompt-input-textarea.svelte +57 -0
- package/dist/ai/prompt-input/prompt-input-textarea.svelte.d.ts +7 -0
- package/dist/ai/prompt-input/prompt-input-toolbar.svelte +15 -0
- package/dist/ai/prompt-input/prompt-input-toolbar.svelte.d.ts +8 -0
- package/dist/ai/prompt-input/prompt-input.svelte +98 -0
- package/dist/ai/prompt-input/prompt-input.svelte.d.ts +17 -0
- package/dist/ai/queue/index.d.ts +2 -0
- package/dist/ai/queue/index.js +2 -0
- package/dist/ai/queue/queue-item.svelte +26 -0
- package/dist/ai/queue/queue-item.svelte.d.ts +9 -0
- package/dist/ai/queue/queue.svelte +14 -0
- package/dist/ai/queue/queue.svelte.d.ts +8 -0
- package/dist/ai/reasoning/index.d.ts +3 -0
- package/dist/ai/reasoning/index.js +3 -0
- package/dist/ai/reasoning/reasoning-trigger.svelte +22 -0
- package/dist/ai/reasoning/reasoning-trigger.svelte.d.ts +9 -0
- package/dist/ai/reasoning/reasoning.svelte +52 -0
- package/dist/ai/reasoning/reasoning.svelte.d.ts +13 -0
- package/dist/ai/response/index.d.ts +2 -0
- package/dist/ai/response/index.js +2 -0
- package/dist/ai/response/repair.d.ts +7 -0
- package/dist/ai/response/repair.js +26 -0
- package/dist/ai/response/response.svelte +112 -0
- package/dist/ai/response/response.svelte.d.ts +10 -0
- package/dist/ai/shimmer.svelte +15 -0
- package/dist/ai/shimmer.svelte.d.ts +9 -0
- package/dist/ai/sources/index.d.ts +4 -0
- package/dist/ai/sources/index.js +4 -0
- package/dist/ai/sources/source.svelte +16 -0
- package/dist/ai/sources/source.svelte.d.ts +7 -0
- package/dist/ai/sources/sources-trigger.svelte +12 -0
- package/dist/ai/sources/sources-trigger.svelte.d.ts +8 -0
- package/dist/ai/sources/sources.svelte +15 -0
- package/dist/ai/sources/sources.svelte.d.ts +9 -0
- package/dist/ai/stick-to-bottom.svelte.d.ts +38 -0
- package/dist/ai/stick-to-bottom.svelte.js +133 -0
- package/dist/ai/suggestion/index.d.ts +2 -0
- package/dist/ai/suggestion/index.js +2 -0
- package/dist/ai/suggestion/suggestion.svelte +25 -0
- package/dist/ai/suggestion/suggestion.svelte.d.ts +10 -0
- package/dist/ai/suggestion/suggestions.svelte +18 -0
- package/dist/ai/suggestion/suggestions.svelte.d.ts +8 -0
- package/dist/ai/task/index.d.ts +5 -0
- package/dist/ai/task/index.js +5 -0
- package/dist/ai/task/task-content.svelte +14 -0
- package/dist/ai/task/task-content.svelte.d.ts +8 -0
- package/dist/ai/task/task-item-file.svelte +8 -0
- package/dist/ai/task/task-item-file.svelte.d.ts +7 -0
- package/dist/ai/task/task-item.svelte +8 -0
- package/dist/ai/task/task-item.svelte.d.ts +8 -0
- package/dist/ai/task/task-trigger.svelte +12 -0
- package/dist/ai/task/task-trigger.svelte.d.ts +8 -0
- package/dist/ai/task/task.svelte +17 -0
- package/dist/ai/task/task.svelte.d.ts +11 -0
- package/dist/ai/tool/index.d.ts +5 -0
- package/dist/ai/tool/index.js +5 -0
- package/dist/ai/tool/tool-header.svelte +20 -0
- package/dist/ai/tool/tool-header.svelte.d.ts +9 -0
- package/dist/ai/tool/tool-input.svelte +10 -0
- package/dist/ai/tool/tool-input.svelte.d.ts +6 -0
- package/dist/ai/tool/tool-output.svelte +20 -0
- package/dist/ai/tool/tool-output.svelte.d.ts +7 -0
- package/dist/ai/tool/tool.svelte +41 -0
- package/dist/ai/tool/tool.svelte.d.ts +12 -0
- package/dist/ai/web-preview/index.d.ts +1 -0
- package/dist/ai/web-preview/index.js +1 -0
- package/dist/ai/web-preview/web-preview.svelte +48 -0
- package/dist/ai/web-preview/web-preview.svelte.d.ts +8 -0
- package/dist/ai/workflow/canvas.svelte +19 -0
- package/dist/ai/workflow/canvas.svelte.d.ts +11 -0
- package/dist/ai/workflow/index.d.ts +2 -0
- package/dist/ai/workflow/index.js +2 -0
- package/dist/ai/workflow/node.svelte +27 -0
- package/dist/ai/workflow/node.svelte.d.ts +9 -0
- package/dist/era-ui.css +1 -1
- package/dist/generated-docs/llms-full.txt +56 -0
- package/dist/generated-docs/llms.txt +1 -1
- package/dist/generated-docs/manifest.json +14 -0
- package/dist/generated-docs/step.md +51 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/os/motion.d.ts +1 -19
- package/dist/os/motion.js +3 -44
- package/dist/os/taskbar.svelte +6 -3
- package/dist/styles/index.css +26 -0
- package/dist/ui/command-bar/command-bar.svelte +8 -6
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.js +1 -0
- package/dist/ui/step/context.d.ts +8 -0
- package/dist/ui/step/context.js +8 -0
- package/dist/ui/step/index.d.ts +5 -0
- package/dist/ui/step/index.js +4 -0
- package/dist/ui/step/step-content.svelte +55 -0
- package/dist/ui/step/step-content.svelte.d.ts +5 -0
- package/dist/ui/step/step-root.svelte +31 -0
- package/dist/ui/step/step-root.svelte.d.ts +9 -0
- package/dist/ui/step/step-section.svelte +23 -0
- package/dist/ui/step/step-section.svelte.d.ts +10 -0
- package/dist/ui/step/step-summary.svelte +55 -0
- package/dist/ui/step/step-summary.svelte.d.ts +5 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/motion.d.ts +19 -0
- package/dist/utils/motion.js +44 -0
- package/package.json +14 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Step
|
|
2
|
+
|
|
3
|
+
Expandable inline step — tool calls, thinking, agent actions.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { Step } from "$lib/ui/step";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Composed from sub-components — compose explicitly at the call site:
|
|
12
|
+
|
|
13
|
+
- `Step.Root`
|
|
14
|
+
- `Step.Summary`
|
|
15
|
+
- `Step.Content`
|
|
16
|
+
- `Step.Section`
|
|
17
|
+
|
|
18
|
+
## Step.Root
|
|
19
|
+
|
|
20
|
+
Inherits all props from `Collapsible.RootProps`.
|
|
21
|
+
|
|
22
|
+
| Prop | Type | Default | Notes |
|
|
23
|
+
|------|------|---------|-------|
|
|
24
|
+
| `status?` | `StepStatus` | `'done'` | Drives the summary's icon and shimmer; exposed as data-status. |
|
|
25
|
+
| `ref?` | `(forwarded)` | `null` | bindable |
|
|
26
|
+
| `open?` | `(forwarded)` | `false` | bindable |
|
|
27
|
+
|
|
28
|
+
## Step.Summary
|
|
29
|
+
|
|
30
|
+
Inherits all props from `PartProps<Collapsible.TriggerProps>`.
|
|
31
|
+
|
|
32
|
+
| Prop | Type | Default | Notes |
|
|
33
|
+
|------|------|---------|-------|
|
|
34
|
+
| `ref?` | `(forwarded)` | `null` | bindable |
|
|
35
|
+
|
|
36
|
+
## Step.Content
|
|
37
|
+
|
|
38
|
+
Inherits all props from `PartProps<Collapsible.ContentProps>`.
|
|
39
|
+
|
|
40
|
+
| Prop | Type | Default | Notes |
|
|
41
|
+
|------|------|---------|-------|
|
|
42
|
+
| `ref?` | `(forwarded)` | `null` | bindable |
|
|
43
|
+
|
|
44
|
+
## Step.Section
|
|
45
|
+
|
|
46
|
+
Inherits all props from `HTMLAttributes<HTMLDivElement>`.
|
|
47
|
+
|
|
48
|
+
| Prop | Type | Default | Notes |
|
|
49
|
+
|------|------|---------|-------|
|
|
50
|
+
| `label?` | `string` | — | Tiny uppercase section header — INPUT, OUTPUT, … |
|
|
51
|
+
| `children?` | `Snippet` | — | — |
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './ui/index.js';
|
|
2
2
|
export * as OS from './os/index.js';
|
|
3
|
+
export * as AI from './ai/index.js';
|
|
3
4
|
export type { Point, Size, Rect, Insets, Frame, Workspace, WindowState, SnapZone, AppWindow, AppDefinition, AppComponent, AppProps } from './os/index.js';
|
|
4
5
|
export { cn, tv, hotkeys, keys, parseKeybinding, matchKeyBindingPress, createKeybindingsHandler, formatKeybinding, isApplePlatform, modKey, type KeyBindingMap, type KeyBindingPress, type KeyBindingOptions, type PartProps, type VariantProps } from './utils/index.js';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export * from './ui/index.js';
|
|
2
2
|
export * as OS from './os/index.js';
|
|
3
|
+
export * as AI from './ai/index.js';
|
|
3
4
|
export { cn, tv, hotkeys, keys, parseKeybinding, matchKeyBindingPress, createKeybindingsHandler, formatKeybinding, isApplePlatform, modKey } from './utils/index.js';
|
package/dist/os/motion.d.ts
CHANGED
|
@@ -1,19 +1 @@
|
|
|
1
|
-
|
|
2
|
-
type EraFlyParams = {
|
|
3
|
-
x?: number | string;
|
|
4
|
-
y?: number | string;
|
|
5
|
-
opacity?: number;
|
|
6
|
-
delay?: number;
|
|
7
|
-
duration?: number;
|
|
8
|
-
easing?: EasingFunction;
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* Fly transition that reads Era's motion tokens from the rendered element.
|
|
12
|
-
*
|
|
13
|
-
* Svelte transition durations are JavaScript parameters, so hard-coded numbers
|
|
14
|
-
* bypass the runtime `data-motion` axis. Reading `--era-duration` here keeps OS
|
|
15
|
-
* overlays in sync with docs settings and library consumers that set motion on
|
|
16
|
-
* an ancestor.
|
|
17
|
-
*/
|
|
18
|
-
export declare function eraFly(node: Element, { x, y, opacity, delay, duration, easing }?: EraFlyParams): TransitionConfig;
|
|
19
|
-
export {};
|
|
1
|
+
export { eraFly } from '../utils/motion.js';
|
package/dist/os/motion.js
CHANGED
|
@@ -1,44 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
function parseDuration(value) {
|
|
6
|
-
const match = value.trim().match(/^(-?\d*\.?\d+)(ms|s)$/i);
|
|
7
|
-
if (!match)
|
|
8
|
-
return undefined;
|
|
9
|
-
return Math.max(0, Number(match[1]) * durationUnits[match[2].toLowerCase()]);
|
|
10
|
-
}
|
|
11
|
-
function eraDuration(node, fallback) {
|
|
12
|
-
const token = getComputedStyle(node).getPropertyValue('--era-duration');
|
|
13
|
-
return parseDuration(token) ?? fallback;
|
|
14
|
-
}
|
|
15
|
-
function offset(value, progress) {
|
|
16
|
-
return typeof value === 'number' ? `${value * progress}px` : `calc(${value} * ${progress})`;
|
|
17
|
-
}
|
|
18
|
-
function eraEase(node) {
|
|
19
|
-
return getComputedStyle(node).getPropertyValue('--era-ease').trim() || undefined;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Fly transition that reads Era's motion tokens from the rendered element.
|
|
23
|
-
*
|
|
24
|
-
* Svelte transition durations are JavaScript parameters, so hard-coded numbers
|
|
25
|
-
* bypass the runtime `data-motion` axis. Reading `--era-duration` here keeps OS
|
|
26
|
-
* overlays in sync with docs settings and library consumers that set motion on
|
|
27
|
-
* an ancestor.
|
|
28
|
-
*/
|
|
29
|
-
export function eraFly(node, { x = 0, y = 0, opacity = 0, delay = 0, duration = 150, easing } = {}) {
|
|
30
|
-
const style = getComputedStyle(node);
|
|
31
|
-
const targetOpacity = Number(style.opacity);
|
|
32
|
-
const transform = style.transform === 'none' ? '' : style.transform;
|
|
33
|
-
const cssEase = eraEase(node);
|
|
34
|
-
return {
|
|
35
|
-
delay,
|
|
36
|
-
duration: eraDuration(node, duration),
|
|
37
|
-
easing,
|
|
38
|
-
css: (t, u) => `
|
|
39
|
-
transform: ${transform} translate(${offset(x, u)}, ${offset(y, u)});
|
|
40
|
-
opacity: ${targetOpacity - (targetOpacity - opacity) * u};
|
|
41
|
-
${cssEase ? `animation-timing-function: ${cssEase};` : ''}
|
|
42
|
-
`
|
|
43
|
-
};
|
|
44
|
-
}
|
|
1
|
+
// Motion helpers moved to utils (they're layer-agnostic — the ui/ layer needs
|
|
2
|
+
// them too). Re-exported here so os-internal imports keep working.
|
|
3
|
+
export { eraFly } from '../utils/motion.js';
|
package/dist/os/taskbar.svelte
CHANGED
|
@@ -80,8 +80,10 @@
|
|
|
80
80
|
// every registered app launches from the root view, `windows` drills into
|
|
81
81
|
// the open windows (focus/restore — the recovery path when the window tabs
|
|
82
82
|
// are hidden), and `workspace` drills into numbered workspaces + `new`.
|
|
83
|
-
// Consumer `commands` append after the built-ins
|
|
84
|
-
|
|
83
|
+
// Consumer `commands` append after the built-ins (merged in a thin outer
|
|
84
|
+
// derived, so a consumer-commands change doesn't rebuild the wm closures
|
|
85
|
+
// and vice-versa).
|
|
86
|
+
const builtinItems = $derived.by((): CommandBarItem[] => {
|
|
85
87
|
const apps: CommandBarItem[] = Object.values(wm.apps).map((app) => ({
|
|
86
88
|
value: `app:${app.id}`,
|
|
87
89
|
label: app.title,
|
|
@@ -125,8 +127,9 @@
|
|
|
125
127
|
}
|
|
126
128
|
]
|
|
127
129
|
};
|
|
128
|
-
return [...apps, windows, workspaces
|
|
130
|
+
return [...apps, windows, workspaces];
|
|
129
131
|
});
|
|
132
|
+
const commandItems = $derived([...builtinItems, ...commands]);
|
|
130
133
|
</script>
|
|
131
134
|
|
|
132
135
|
<!-- Flush: three edges touch the shell; the exposed OUTER corners are the two
|
package/dist/styles/index.css
CHANGED
|
@@ -56,6 +56,32 @@
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
/* In-progress text shimmer — a bright sweep through muted text (the standard
|
|
60
|
+
* "working…" label treatment in streaming UIs). Timing derives from the motion
|
|
61
|
+
* axis (10× --era-duration ≈ 1.5s at normal, 2.6s at extra); at instant the
|
|
62
|
+
* duration is 0s and the sweep freezes on its base frame — plain muted text —
|
|
63
|
+
* so reduced-motion and data-motion="instant" both kill it for free. */
|
|
64
|
+
@utility era-shimmer {
|
|
65
|
+
background: linear-gradient(
|
|
66
|
+
110deg,
|
|
67
|
+
var(--color-muted) 0% 43%,
|
|
68
|
+
var(--color-bright) 50%,
|
|
69
|
+
var(--color-muted) 57% 100%
|
|
70
|
+
);
|
|
71
|
+
background-size: 200% 100%;
|
|
72
|
+
background-clip: text;
|
|
73
|
+
-webkit-text-fill-color: transparent;
|
|
74
|
+
animation: era-shimmer calc(var(--era-duration) * 10) cubic-bezier(0.7, 0, 1, 0.4) infinite;
|
|
75
|
+
}
|
|
76
|
+
@keyframes era-shimmer {
|
|
77
|
+
0% {
|
|
78
|
+
background-position: 100% 0;
|
|
79
|
+
}
|
|
80
|
+
100% {
|
|
81
|
+
background-position: -100% 0;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
59
85
|
/* Register color tokens as Tailwind theme values for autocomplete and bare utility usage */
|
|
60
86
|
@theme inline {
|
|
61
87
|
/* Density-derived body size: `text-body` replaces text-[length:var(--era-text)] */
|
|
@@ -61,6 +61,12 @@
|
|
|
61
61
|
});
|
|
62
62
|
const selected = $derived(filtered[selectedIndex]);
|
|
63
63
|
const open = $derived(focused || value !== '');
|
|
64
|
+
const hotkeyList = $derived(hotkey ? (Array.isArray(hotkey) ? hotkey : [hotkey]) : []);
|
|
65
|
+
// The focus hotkeys double as close keys while the bar is focused (a bound
|
|
66
|
+
// key is never part of a command — it toggles). Only single-character
|
|
67
|
+
// bindings qualify; chords/mod combos can't collide with typing. Escape
|
|
68
|
+
// always closes.
|
|
69
|
+
const closeKeys = $derived(new Set(['Escape', ...hotkeyList.filter((b) => b.length === 1)]));
|
|
64
70
|
|
|
65
71
|
// zsh-style ghost completion: the selected item's remaining characters laid
|
|
66
72
|
// under the caret (or the view placeholder while empty).
|
|
@@ -118,9 +124,7 @@
|
|
|
118
124
|
e.preventDefault();
|
|
119
125
|
complete(selected);
|
|
120
126
|
}
|
|
121
|
-
} else if (
|
|
122
|
-
// Backtick closes too: it's the focus hotkey, and a backtick is
|
|
123
|
-
// never part of a command — so it toggles rather than types.
|
|
127
|
+
} else if (closeKeys.has(e.key)) {
|
|
124
128
|
e.preventDefault();
|
|
125
129
|
e.stopPropagation();
|
|
126
130
|
reset();
|
|
@@ -139,10 +143,8 @@
|
|
|
139
143
|
// acts (it blurs the field); every other binding is ignored so typing a
|
|
140
144
|
// backtick in a text input never steals the caret.
|
|
141
145
|
const bindings = $derived.by((): KeyBindingMap => {
|
|
142
|
-
if (!hotkey) return {};
|
|
143
|
-
const list = Array.isArray(hotkey) ? hotkey : [hotkey];
|
|
144
146
|
return Object.fromEntries(
|
|
145
|
-
|
|
147
|
+
hotkeyList.map((b) => [
|
|
146
148
|
b,
|
|
147
149
|
(e: KeyboardEvent) => {
|
|
148
150
|
if (isTextEntryFocused()) {
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export * as Combobox from './combobox/index.js';
|
|
|
11
11
|
export * as Collapsible from './collapsible/index.js';
|
|
12
12
|
export * as Command from './command/index.js';
|
|
13
13
|
export * from './command-bar/index.js';
|
|
14
|
+
export * as Step from './step/index.js';
|
|
14
15
|
export * as ContextMenu from './context-menu/index.js';
|
|
15
16
|
export * as DateField from './date-field/index.js';
|
|
16
17
|
export * as DatePicker from './date-picker/index.js';
|
package/dist/ui/index.js
CHANGED
|
@@ -11,6 +11,7 @@ export * as Combobox from './combobox/index.js';
|
|
|
11
11
|
export * as Collapsible from './collapsible/index.js';
|
|
12
12
|
export * as Command from './command/index.js';
|
|
13
13
|
export * from './command-bar/index.js';
|
|
14
|
+
export * as Step from './step/index.js';
|
|
14
15
|
export * as ContextMenu from './context-menu/index.js';
|
|
15
16
|
export * as DateField from './date-field/index.js';
|
|
16
17
|
export * as DatePicker from './date-picker/index.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** The lifecycle of a step: not started, working, finished, failed. */
|
|
2
|
+
export type StepStatus = 'pending' | 'running' | 'done' | 'error';
|
|
3
|
+
type StepContext = {
|
|
4
|
+
readonly status: StepStatus;
|
|
5
|
+
};
|
|
6
|
+
export declare function setStepContext(ctx: StepContext): void;
|
|
7
|
+
export declare function getStepContext(): StepContext;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as Root } from './step-root.svelte';
|
|
2
|
+
export { default as Summary } from './step-summary.svelte';
|
|
3
|
+
export { default as Content } from './step-content.svelte';
|
|
4
|
+
export { default as Section } from './step-section.svelte';
|
|
5
|
+
export type { StepStatus } from './context.js';
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Collapsible } from 'bits-ui';
|
|
3
|
+
import { cn, type PartProps } from '../../utils/index.js';
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
ref = $bindable(null),
|
|
7
|
+
children,
|
|
8
|
+
class: className,
|
|
9
|
+
...restProps
|
|
10
|
+
}: PartProps<Collapsible.ContentProps> = $props();
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<!-- Height animates on the outer (padding-free) element via bits' measured
|
|
14
|
+
content-height var — padding lives on the inner well so the animation
|
|
15
|
+
never fights box metrics. The well is recessed (shadow-well): payload the
|
|
16
|
+
step produced, not raised chrome. -->
|
|
17
|
+
<Collapsible.Content bind:ref data-era-step-content class="overflow-hidden" {...restProps}>
|
|
18
|
+
<div
|
|
19
|
+
class={cn(
|
|
20
|
+
'mt-(--era-gap) mb-(--era-gap) flex min-w-0 flex-col gap-(--era-pad-sm) rounded-(--era-rd-md) bg-(--era-surface-bg) p-(--era-pad-sm) shadow-(--era-shadow-well)',
|
|
21
|
+
className
|
|
22
|
+
)}
|
|
23
|
+
>
|
|
24
|
+
{@render children?.()}
|
|
25
|
+
</div>
|
|
26
|
+
</Collapsible.Content>
|
|
27
|
+
|
|
28
|
+
<style>
|
|
29
|
+
:global([data-era-step-content][data-state='open']) {
|
|
30
|
+
animation: era-step-expand var(--era-duration) var(--era-ease);
|
|
31
|
+
}
|
|
32
|
+
:global([data-era-step-content][data-state='closed']) {
|
|
33
|
+
animation: era-step-collapse var(--era-duration) var(--era-ease);
|
|
34
|
+
}
|
|
35
|
+
@keyframes -global-era-step-expand {
|
|
36
|
+
from {
|
|
37
|
+
height: 0;
|
|
38
|
+
opacity: 0;
|
|
39
|
+
}
|
|
40
|
+
to {
|
|
41
|
+
height: var(--bits-collapsible-content-height);
|
|
42
|
+
opacity: 1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
@keyframes -global-era-step-collapse {
|
|
46
|
+
from {
|
|
47
|
+
height: var(--bits-collapsible-content-height);
|
|
48
|
+
opacity: 1;
|
|
49
|
+
}
|
|
50
|
+
to {
|
|
51
|
+
height: 0;
|
|
52
|
+
opacity: 0;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
</style>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Collapsible } from 'bits-ui';
|
|
2
|
+
import { type PartProps } from '../../utils/index.js';
|
|
3
|
+
declare const StepContent: import("svelte").Component<PartProps<Collapsible.ContentProps>, {}, "ref">;
|
|
4
|
+
type StepContent = ReturnType<typeof StepContent>;
|
|
5
|
+
export default StepContent;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Collapsible } from 'bits-ui';
|
|
3
|
+
import { cn } from '../../utils/index.js';
|
|
4
|
+
import { setStepContext, type StepStatus } from './context.js';
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
ref = $bindable(null),
|
|
8
|
+
open = $bindable(false),
|
|
9
|
+
status = 'done',
|
|
10
|
+
class: className,
|
|
11
|
+
...restProps
|
|
12
|
+
}: Collapsible.RootProps & {
|
|
13
|
+
/** Drives the summary's icon and shimmer; exposed as data-status. */
|
|
14
|
+
status?: StepStatus;
|
|
15
|
+
} = $props();
|
|
16
|
+
|
|
17
|
+
// Shared with Summary via context (a getter, so status stays reactive).
|
|
18
|
+
setStepContext({
|
|
19
|
+
get status() {
|
|
20
|
+
return status;
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<Collapsible.Root
|
|
26
|
+
bind:ref
|
|
27
|
+
bind:open
|
|
28
|
+
data-status={status}
|
|
29
|
+
class={cn('group/step flex w-full min-w-0 flex-col', className)}
|
|
30
|
+
{...restProps}
|
|
31
|
+
/>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Collapsible } from 'bits-ui';
|
|
2
|
+
import { type StepStatus } from './context.js';
|
|
3
|
+
type $$ComponentProps = Collapsible.RootProps & {
|
|
4
|
+
/** Drives the summary's icon and shimmer; exposed as data-status. */
|
|
5
|
+
status?: StepStatus;
|
|
6
|
+
};
|
|
7
|
+
declare const StepRoot: import("svelte").Component<$$ComponentProps, {}, "ref" | "open">;
|
|
8
|
+
type StepRoot = ReturnType<typeof StepRoot>;
|
|
9
|
+
export default StepRoot;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import { cn } from '../../utils/index.js';
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
label,
|
|
8
|
+
children,
|
|
9
|
+
class: className,
|
|
10
|
+
...restProps
|
|
11
|
+
}: HTMLAttributes<HTMLDivElement> & {
|
|
12
|
+
/** Tiny uppercase section header — INPUT, OUTPUT, … */
|
|
13
|
+
label?: string;
|
|
14
|
+
children?: Snippet;
|
|
15
|
+
} = $props();
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<div class={cn('flex min-w-0 flex-col gap-(--era-gap)', className)} {...restProps}>
|
|
19
|
+
{#if label}
|
|
20
|
+
<span class="text-[0.625rem] leading-none tracking-[0.15em] text-muted uppercase">{label}</span>
|
|
21
|
+
{/if}
|
|
22
|
+
{@render children?.()}
|
|
23
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
|
|
4
|
+
/** Tiny uppercase section header — INPUT, OUTPUT, … */
|
|
5
|
+
label?: string;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
};
|
|
8
|
+
declare const StepSection: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
9
|
+
type StepSection = ReturnType<typeof StepSection>;
|
|
10
|
+
export default StepSection;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Collapsible } from 'bits-ui';
|
|
3
|
+
import LoaderCircle from '@lucide/svelte/icons/loader-circle';
|
|
4
|
+
import CircleCheck from '@lucide/svelte/icons/circle-check';
|
|
5
|
+
import CircleX from '@lucide/svelte/icons/circle-x';
|
|
6
|
+
import CircleDashed from '@lucide/svelte/icons/circle-dashed';
|
|
7
|
+
import ChevronDown from '@lucide/svelte/icons/chevron-down';
|
|
8
|
+
import { cn, type PartProps } from '../../utils/index.js';
|
|
9
|
+
import { getStepContext } from './context.js';
|
|
10
|
+
|
|
11
|
+
let {
|
|
12
|
+
ref = $bindable(null),
|
|
13
|
+
children,
|
|
14
|
+
class: className,
|
|
15
|
+
...restProps
|
|
16
|
+
}: PartProps<Collapsible.TriggerProps> = $props();
|
|
17
|
+
|
|
18
|
+
const step = getStepContext();
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<!-- The collapsed line: status icon, label (shimmering while running — the
|
|
22
|
+
shimmer freezes to plain muted text at instant motion), rotating chevron.
|
|
23
|
+
Quiet by design — a step reads as an aside in the conversation, not a
|
|
24
|
+
control; it brightens on hover to reveal it's expandable. The spinner is
|
|
25
|
+
a progress indicator, not decoration, so it spins at every motion level. -->
|
|
26
|
+
<Collapsible.Trigger
|
|
27
|
+
bind:ref
|
|
28
|
+
class={cn(
|
|
29
|
+
'flex h-(--era-h-md) w-full min-w-0 cursor-pointer era-interactive items-center gap-(--era-gap) rounded-(--era-rd-md) px-(--era-inset-md) text-body text-muted transition-colors duration-(--era-duration) ease-(--era-ease) hover:text-fg',
|
|
30
|
+
className
|
|
31
|
+
)}
|
|
32
|
+
{...restProps}
|
|
33
|
+
>
|
|
34
|
+
{#if step.status === 'running'}
|
|
35
|
+
<LoaderCircle class="size-(--era-h-xs) shrink-0 animate-spin" aria-hidden="true" />
|
|
36
|
+
{:else if step.status === 'done'}
|
|
37
|
+
<CircleCheck class="size-(--era-h-xs) shrink-0 text-success" aria-hidden="true" />
|
|
38
|
+
{:else if step.status === 'error'}
|
|
39
|
+
<CircleX class="size-(--era-h-xs) shrink-0 text-destructive" aria-hidden="true" />
|
|
40
|
+
{:else}
|
|
41
|
+
<CircleDashed class="size-(--era-h-xs) shrink-0" aria-hidden="true" />
|
|
42
|
+
{/if}
|
|
43
|
+
<span
|
|
44
|
+
class={cn(
|
|
45
|
+
'flex min-w-0 flex-1 items-center gap-(--era-gap) truncate text-left',
|
|
46
|
+
step.status === 'running' && 'era-shimmer'
|
|
47
|
+
)}
|
|
48
|
+
>
|
|
49
|
+
{@render children?.()}
|
|
50
|
+
</span>
|
|
51
|
+
<ChevronDown
|
|
52
|
+
class="size-(--era-h-xs) shrink-0 transition-transform duration-(--era-duration) ease-(--era-ease) group-data-[state=open]/step:rotate-180"
|
|
53
|
+
aria-hidden="true"
|
|
54
|
+
/>
|
|
55
|
+
</Collapsible.Trigger>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Collapsible } from 'bits-ui';
|
|
2
|
+
import { type PartProps } from '../../utils/index.js';
|
|
3
|
+
declare const StepSummary: import("svelte").Component<PartProps<Collapsible.TriggerProps>, {}, "ref">;
|
|
4
|
+
type StepSummary = ReturnType<typeof StepSummary>;
|
|
5
|
+
export default StepSummary;
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -14,3 +14,4 @@ export type PartProps<T> = WithoutChildrenOrChild<T> & {
|
|
|
14
14
|
children?: Snippet;
|
|
15
15
|
};
|
|
16
16
|
export { hotkeys, keys, parseKeybinding, matchKeyBindingPress, createKeybindingsHandler, formatKeybinding, isApplePlatform, modKey, type KeyBindingMap, type KeyBindingPress, type KeyBindingOptions } from './hotkeys.js';
|
|
17
|
+
export { eraFly } from './motion.js';
|
package/dist/utils/index.js
CHANGED
|
@@ -23,3 +23,4 @@ export function cn(...inputs) {
|
|
|
23
23
|
/** `tv` preconfigured with this library's tailwind-merge settings. */
|
|
24
24
|
export const tv = createTV({ twMergeConfig });
|
|
25
25
|
export { hotkeys, keys, parseKeybinding, matchKeyBindingPress, createKeybindingsHandler, formatKeybinding, isApplePlatform, modKey } from './hotkeys.js';
|
|
26
|
+
export { eraFly } from './motion.js';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { EasingFunction, TransitionConfig } from 'svelte/transition';
|
|
2
|
+
type EraFlyParams = {
|
|
3
|
+
x?: number | string;
|
|
4
|
+
y?: number | string;
|
|
5
|
+
opacity?: number;
|
|
6
|
+
delay?: number;
|
|
7
|
+
duration?: number;
|
|
8
|
+
easing?: EasingFunction;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Fly transition that reads Era's motion tokens from the rendered element.
|
|
12
|
+
*
|
|
13
|
+
* Svelte transition durations are JavaScript parameters, so hard-coded numbers
|
|
14
|
+
* bypass the runtime `data-motion` axis. Reading `--era-duration` here keeps OS
|
|
15
|
+
* overlays in sync with docs settings and library consumers that set motion on
|
|
16
|
+
* an ancestor.
|
|
17
|
+
*/
|
|
18
|
+
export declare function eraFly(node: Element, { x, y, opacity, delay, duration, easing }?: EraFlyParams): TransitionConfig;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const durationUnits = {
|
|
2
|
+
ms: 1,
|
|
3
|
+
s: 1000
|
|
4
|
+
};
|
|
5
|
+
function parseDuration(value) {
|
|
6
|
+
const match = value.trim().match(/^(-?\d*\.?\d+)(ms|s)$/i);
|
|
7
|
+
if (!match)
|
|
8
|
+
return undefined;
|
|
9
|
+
return Math.max(0, Number(match[1]) * durationUnits[match[2].toLowerCase()]);
|
|
10
|
+
}
|
|
11
|
+
function eraDuration(node, fallback) {
|
|
12
|
+
const token = getComputedStyle(node).getPropertyValue('--era-duration');
|
|
13
|
+
return parseDuration(token) ?? fallback;
|
|
14
|
+
}
|
|
15
|
+
function offset(value, progress) {
|
|
16
|
+
return typeof value === 'number' ? `${value * progress}px` : `calc(${value} * ${progress})`;
|
|
17
|
+
}
|
|
18
|
+
function eraEase(node) {
|
|
19
|
+
return getComputedStyle(node).getPropertyValue('--era-ease').trim() || undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Fly transition that reads Era's motion tokens from the rendered element.
|
|
23
|
+
*
|
|
24
|
+
* Svelte transition durations are JavaScript parameters, so hard-coded numbers
|
|
25
|
+
* bypass the runtime `data-motion` axis. Reading `--era-duration` here keeps OS
|
|
26
|
+
* overlays in sync with docs settings and library consumers that set motion on
|
|
27
|
+
* an ancestor.
|
|
28
|
+
*/
|
|
29
|
+
export function eraFly(node, { x = 0, y = 0, opacity = 0, delay = 0, duration = 150, easing } = {}) {
|
|
30
|
+
const style = getComputedStyle(node);
|
|
31
|
+
const targetOpacity = Number(style.opacity);
|
|
32
|
+
const transform = style.transform === 'none' ? '' : style.transform;
|
|
33
|
+
const cssEase = eraEase(node);
|
|
34
|
+
return {
|
|
35
|
+
delay,
|
|
36
|
+
duration: eraDuration(node, duration),
|
|
37
|
+
easing,
|
|
38
|
+
css: (t, u) => `
|
|
39
|
+
transform: ${transform} translate(${offset(x, u)}, ${offset(y, u)});
|
|
40
|
+
opacity: ${targetOpacity - (targetOpacity - opacity) * u};
|
|
41
|
+
${cssEase ? `animation-timing-function: ${cssEase};` : ''}
|
|
42
|
+
`
|
|
43
|
+
};
|
|
44
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signal9/era-ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "vite dev --host",
|
|
6
6
|
"build": "vite build && npm run prepack",
|
|
@@ -47,6 +47,16 @@
|
|
|
47
47
|
"svelte": "./dist/ui/provider/index.js",
|
|
48
48
|
"default": "./dist/ui/provider/index.js"
|
|
49
49
|
},
|
|
50
|
+
"./ai": {
|
|
51
|
+
"types": "./dist/ai/index.d.ts",
|
|
52
|
+
"svelte": "./dist/ai/index.js",
|
|
53
|
+
"default": "./dist/ai/index.js"
|
|
54
|
+
},
|
|
55
|
+
"./ai/workflow": {
|
|
56
|
+
"types": "./dist/ai/workflow/index.d.ts",
|
|
57
|
+
"svelte": "./dist/ai/workflow/index.js",
|
|
58
|
+
"default": "./dist/ai/workflow/index.js"
|
|
59
|
+
},
|
|
50
60
|
"./os": {
|
|
51
61
|
"types": "./dist/os/index.d.ts",
|
|
52
62
|
"svelte": "./dist/os/index.js",
|
|
@@ -77,6 +87,7 @@
|
|
|
77
87
|
"@threlte/extras": "^9.21.0",
|
|
78
88
|
"@types/node": "^24.13.2",
|
|
79
89
|
"@types/three": "^0.184.1",
|
|
90
|
+
"@xyflow/svelte": "^1.6.2",
|
|
80
91
|
"eslint": "^9.39.4",
|
|
81
92
|
"eslint-config-prettier": "^10.1.8",
|
|
82
93
|
"eslint-plugin-better-tailwindcss": "^4.6.1",
|
|
@@ -114,6 +125,8 @@
|
|
|
114
125
|
"@neodrag/svelte": "^3.0.0-next.8",
|
|
115
126
|
"bits-ui": "^2.18.1",
|
|
116
127
|
"clsx": "^2.1.1",
|
|
128
|
+
"dompurify": "^3.4.12",
|
|
129
|
+
"marked": "^15.0.12",
|
|
117
130
|
"tailwind-merge": "^3.6.0",
|
|
118
131
|
"tailwind-variants": "^3.2.2",
|
|
119
132
|
"vidstack": "^0.6.15"
|