@refraction-ui/astro 0.11.1 → 0.13.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/astro-audio-room/AudioRoom.astro +81 -0
- package/dist/astro-audio-room/index.ts +1 -0
- package/dist/astro-call-controls/CallControls.astro +57 -0
- package/dist/astro-call-controls/index.ts +1 -0
- package/dist/astro-checklist/Checklist.astro +76 -0
- package/dist/astro-checklist/index.ts +1 -0
- package/dist/astro-editor-status-bar/EditorStatusBar.astro +92 -0
- package/dist/astro-editor-status-bar/index.ts +1 -0
- package/dist/astro-editor-tabs/EditorTabs.astro +74 -0
- package/dist/astro-editor-tabs/index.ts +1 -0
- package/dist/astro-empty-state/EmptyState.astro +57 -0
- package/dist/astro-empty-state/index.ts +1 -0
- package/dist/astro-floating-reactions/FloatingReactions.astro +56 -0
- package/dist/astro-floating-reactions/index.ts +1 -0
- package/dist/astro-flow-editor/FlowEditor.astro +99 -0
- package/dist/astro-flow-editor/index.ts +3 -0
- package/dist/astro-graph-view/GraphView.astro +109 -0
- package/dist/astro-graph-view/index.ts +1 -0
- package/dist/astro-infinite-canvas/InfiniteCanvas.astro +43 -0
- package/dist/astro-infinite-canvas/index.ts +1 -0
- package/dist/astro-input/Input.astro +5 -1
- package/dist/astro-live-captions/LiveCaptions.astro +54 -0
- package/dist/astro-live-captions/index.ts +1 -0
- package/dist/astro-live-cursors/LiveCursors.astro +55 -0
- package/dist/astro-live-cursors/index.ts +1 -0
- package/dist/astro-live-transcript/LiveTranscript.astro +55 -0
- package/dist/astro-live-transcript/index.ts +1 -0
- package/dist/astro-mini-map/MiniMap.astro +74 -0
- package/dist/astro-mini-map/index.ts +1 -0
- package/dist/astro-password-input/PasswordInput.astro +102 -0
- package/dist/astro-password-input/index.ts +1 -0
- package/dist/astro-pre-call-lobby/PreCallLobby.astro +202 -0
- package/dist/astro-pre-call-lobby/index.ts +1 -0
- package/dist/astro-radial-gauge/RadialGauge.astro +144 -0
- package/dist/astro-radial-gauge/index.ts +1 -0
- package/dist/astro-rating-scale/RatingScale.astro +73 -0
- package/dist/astro-rating-scale/index.ts +1 -0
- package/dist/astro-segmented-control/SegmentedControl.astro +106 -0
- package/dist/astro-segmented-control/SegmentedControlItem.astro +32 -0
- package/dist/astro-segmented-control/index.ts +1 -0
- package/dist/astro-separator/Separator.astro +49 -0
- package/dist/astro-separator/index.ts +1 -0
- package/dist/astro-social-auth-button/SocialAuthButton.astro +110 -0
- package/dist/astro-social-auth-button/SocialAuthRow.astro +13 -0
- package/dist/astro-social-auth-button/index.ts +1 -0
- package/dist/astro-sticky-note/StickyNote.astro +55 -0
- package/dist/astro-sticky-note/index.ts +1 -0
- package/dist/astro-terminal/Terminal.astro +67 -0
- package/dist/astro-terminal/index.ts +1 -0
- package/dist/astro-test-results/TestResults.astro +76 -0
- package/dist/astro-test-results/index.ts +1 -0
- package/dist/astro-timeline/Timeline.astro +59 -0
- package/dist/astro-timeline/index.ts +1 -0
- package/dist/astro-video-grid/VideoGrid.astro +182 -0
- package/dist/astro-video-grid/index.ts +1 -0
- package/dist/astro-video-tile/VideoTile.astro +104 -0
- package/dist/astro-video-tile/index.ts +1 -0
- package/dist/astro-wizard/Wizard.astro +137 -0
- package/dist/astro-wizard/index.ts +1 -0
- package/dist/audio-room/audio-room.styles.ts +88 -0
- package/dist/audio-room/audio-room.ts +70 -0
- package/dist/audio-room/index.ts +16 -0
- package/dist/call-controls/call-controls.styles.ts +63 -0
- package/dist/call-controls/call-controls.ts +79 -0
- package/dist/call-controls/index.ts +15 -0
- package/dist/checklist/checklist.styles.ts +76 -0
- package/dist/checklist/checklist.ts +62 -0
- package/dist/checklist/index.ts +18 -0
- package/dist/editor-status-bar/editor-status-bar.styles.ts +40 -0
- package/dist/editor-status-bar/editor-status-bar.ts +78 -0
- package/dist/editor-status-bar/index.ts +15 -0
- package/dist/editor-tabs/editor-tabs.styles.ts +52 -0
- package/dist/editor-tabs/editor-tabs.ts +82 -0
- package/dist/editor-tabs/index.ts +15 -0
- package/dist/empty-state/empty-state.styles.ts +42 -0
- package/dist/empty-state/empty-state.ts +27 -0
- package/dist/empty-state/index.ts +14 -0
- package/dist/floating-reactions/floating-reactions.styles.ts +54 -0
- package/dist/floating-reactions/floating-reactions.ts +85 -0
- package/dist/floating-reactions/index.ts +14 -0
- package/dist/flow-editor/flow-editor.styles.ts +56 -0
- package/dist/flow-editor/flow-editor.ts +126 -0
- package/dist/flow-editor/index.ts +18 -0
- package/dist/graph-view/graph-view.styles.ts +66 -0
- package/dist/graph-view/graph-view.ts +130 -0
- package/dist/graph-view/index.ts +21 -0
- package/dist/index.ts +45 -17
- package/dist/infinite-canvas/index.ts +17 -0
- package/dist/infinite-canvas/infinite-canvas.styles.ts +49 -0
- package/dist/infinite-canvas/infinite-canvas.ts +97 -0
- package/dist/input/index.ts +2 -0
- package/dist/input/input.styles.ts +4 -0
- package/dist/input/input.ts +39 -3
- package/dist/live-captions/index.ts +13 -0
- package/dist/live-captions/live-captions.styles.ts +45 -0
- package/dist/live-captions/live-captions.ts +57 -0
- package/dist/live-cursors/index.ts +14 -0
- package/dist/live-cursors/live-cursors.styles.ts +41 -0
- package/dist/live-cursors/live-cursors.ts +73 -0
- package/dist/live-transcript/index.ts +16 -0
- package/dist/live-transcript/live-transcript.styles.ts +48 -0
- package/dist/live-transcript/live-transcript.ts +82 -0
- package/dist/mini-map/index.ts +16 -0
- package/dist/mini-map/mini-map.styles.ts +32 -0
- package/dist/mini-map/mini-map.ts +122 -0
- package/dist/password-input/index.ts +9 -0
- package/dist/password-input/password-input.styles.ts +10 -0
- package/dist/password-input/password-input.ts +45 -0
- package/dist/pre-call-lobby/index.ts +22 -0
- package/dist/pre-call-lobby/pre-call-lobby.styles.ts +108 -0
- package/dist/pre-call-lobby/pre-call-lobby.ts +61 -0
- package/dist/radial-gauge/index.ts +26 -0
- package/dist/radial-gauge/radial-gauge.styles.ts +75 -0
- package/dist/radial-gauge/radial-gauge.ts +183 -0
- package/dist/rating-scale/index.ts +16 -0
- package/dist/rating-scale/rating-scale.styles.ts +48 -0
- package/dist/rating-scale/rating-scale.ts +101 -0
- package/dist/segmented-control/index.ts +13 -0
- package/dist/segmented-control/segmented-control.styles.ts +42 -0
- package/dist/segmented-control/segmented-control.ts +80 -0
- package/dist/separator/index.ts +12 -0
- package/dist/separator/separator.styles.ts +34 -0
- package/dist/separator/separator.ts +53 -0
- package/dist/social-auth-button/index.ts +14 -0
- package/dist/social-auth-button/social-auth-button.styles.ts +16 -0
- package/dist/social-auth-button/social-auth-button.ts +51 -0
- package/dist/sticky-note/index.ts +14 -0
- package/dist/sticky-note/sticky-note.styles.ts +37 -0
- package/dist/sticky-note/sticky-note.ts +47 -0
- package/dist/terminal/index.ts +13 -0
- package/dist/terminal/terminal.styles.ts +56 -0
- package/dist/terminal/terminal.ts +60 -0
- package/dist/test-results/index.ts +19 -0
- package/dist/test-results/test-results.styles.ts +93 -0
- package/dist/test-results/test-results.ts +83 -0
- package/dist/timeline/index.ts +22 -0
- package/dist/timeline/timeline.styles.ts +98 -0
- package/dist/timeline/timeline.ts +86 -0
- package/dist/video-grid/index.ts +16 -0
- package/dist/video-grid/video-grid.styles.ts +38 -0
- package/dist/video-grid/video-grid.ts +93 -0
- package/dist/video-tile/index.ts +17 -0
- package/dist/video-tile/video-tile.styles.ts +59 -0
- package/dist/video-tile/video-tile.ts +74 -0
- package/dist/wizard/index.ts +28 -0
- package/dist/wizard/wizard.styles.ts +147 -0
- package/dist/wizard/wizard.ts +128 -0
- package/package.json +47 -19
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { cva } from '../shared/index.ts'
|
|
2
|
+
|
|
3
|
+
/** Outer wrapper for the graph canvas area. */
|
|
4
|
+
export const graphViewVariants = cva({
|
|
5
|
+
base: 'relative w-full overflow-hidden rounded-lg border border-border bg-background',
|
|
6
|
+
variants: {},
|
|
7
|
+
defaultVariants: {},
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Node chip: a positioned, clickable concept node colored by mastery state.
|
|
12
|
+
*
|
|
13
|
+
* `state` variant drives the visual treatment:
|
|
14
|
+
* - mastered → filled primary (bg-primary / text-primary-foreground)
|
|
15
|
+
* - in-progress → accent ring (ring-2 ring-ring bg-accent text-accent-foreground)
|
|
16
|
+
* - not-started → muted (bg-muted text-muted-foreground)
|
|
17
|
+
* - highlight → border-primary accent outline (border-primary bg-background text-foreground)
|
|
18
|
+
*/
|
|
19
|
+
export const graphNodeVariants = cva({
|
|
20
|
+
base: [
|
|
21
|
+
'absolute inline-flex items-center justify-center rounded-md border px-2 py-1',
|
|
22
|
+
'text-xs font-medium leading-none -translate-x-1/2 -translate-y-1/2',
|
|
23
|
+
'transition-colors focus-visible:outline-none focus-visible:ring-2',
|
|
24
|
+
'focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',
|
|
25
|
+
'cursor-default select-none',
|
|
26
|
+
].join(' '),
|
|
27
|
+
variants: {
|
|
28
|
+
state: {
|
|
29
|
+
mastered: 'border-transparent bg-primary text-primary-foreground',
|
|
30
|
+
'in-progress': 'border-transparent bg-accent text-accent-foreground ring-2 ring-ring',
|
|
31
|
+
'not-started': 'border-transparent bg-muted text-muted-foreground',
|
|
32
|
+
highlight: 'border-primary bg-background text-foreground',
|
|
33
|
+
},
|
|
34
|
+
interactive: {
|
|
35
|
+
true: 'cursor-pointer hover:opacity-90',
|
|
36
|
+
false: 'cursor-default',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
defaultVariants: {
|
|
40
|
+
state: 'not-started',
|
|
41
|
+
interactive: 'false',
|
|
42
|
+
},
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
/** Label text rendered inside each node chip (already embedded in the chip). */
|
|
46
|
+
export const graphNodeLabelClass = 'pointer-events-none whitespace-nowrap'
|
|
47
|
+
|
|
48
|
+
/** SVG edge line/path classes. */
|
|
49
|
+
export const graphEdgeClass =
|
|
50
|
+
'fill-none stroke-border stroke-[1.5] opacity-60'
|
|
51
|
+
|
|
52
|
+
/** Legend chip: a small colored indicator + label for a single mastery state. */
|
|
53
|
+
export const graphLegendChipVariants = cva({
|
|
54
|
+
base: 'inline-flex items-center gap-1.5 rounded-md border px-2 py-0.5 text-xs font-medium',
|
|
55
|
+
variants: {
|
|
56
|
+
state: {
|
|
57
|
+
mastered: 'border-transparent bg-primary text-primary-foreground',
|
|
58
|
+
'in-progress': 'border-transparent bg-accent text-accent-foreground ring-1 ring-ring',
|
|
59
|
+
'not-started': 'border-transparent bg-muted text-muted-foreground',
|
|
60
|
+
highlight: 'border-primary bg-background text-foreground',
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
defaultVariants: {
|
|
64
|
+
state: 'not-started',
|
|
65
|
+
},
|
|
66
|
+
})
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/** Visual mastery state of a node in the knowledge graph. */
|
|
2
|
+
export type GraphNodeState = 'mastered' | 'in-progress' | 'not-started' | 'highlight'
|
|
3
|
+
|
|
4
|
+
/** A concept node in the knowledge / dependency graph. */
|
|
5
|
+
export interface GraphNode {
|
|
6
|
+
/** Unique identifier. */
|
|
7
|
+
id: string
|
|
8
|
+
/** X position in the graph canvas (pixels). */
|
|
9
|
+
x: number
|
|
10
|
+
/** Y position in the graph canvas (pixels). */
|
|
11
|
+
y: number
|
|
12
|
+
/** Human-readable label shown in the node chip. */
|
|
13
|
+
label: string
|
|
14
|
+
/** Visual mastery state. Defaults to `'not-started'`. */
|
|
15
|
+
state?: GraphNodeState
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** A directed edge connecting two nodes. */
|
|
19
|
+
export interface GraphEdge {
|
|
20
|
+
/** Unique identifier. */
|
|
21
|
+
id: string
|
|
22
|
+
/** ID of the source node. */
|
|
23
|
+
source: string
|
|
24
|
+
/** ID of the target node. */
|
|
25
|
+
target: string
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Axis-aligned bounding box of a set of nodes. */
|
|
29
|
+
export interface GraphBounds {
|
|
30
|
+
minX: number
|
|
31
|
+
minY: number
|
|
32
|
+
maxX: number
|
|
33
|
+
maxY: number
|
|
34
|
+
width: number
|
|
35
|
+
height: number
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Per-state counts returned by {@link summarizeStates}. */
|
|
39
|
+
export type GraphStateSummary = Record<GraphNodeState, number>
|
|
40
|
+
|
|
41
|
+
export interface GraphViewAPI {
|
|
42
|
+
/** ARIA/role attributes to spread on the graph container. */
|
|
43
|
+
ariaProps: { role: string; 'aria-label': string }
|
|
44
|
+
/** Data attributes for styling hooks. */
|
|
45
|
+
dataAttributes: Record<string, string>
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Build framework-agnostic container props for a GraphView.
|
|
50
|
+
*
|
|
51
|
+
* The graph is a read-only knowledge / dependency visualisation. It uses
|
|
52
|
+
* `role="group"` (not `role="img"`) so that interactive node chips inside it
|
|
53
|
+
* remain in the accessibility tree and keyboard reachable.
|
|
54
|
+
*/
|
|
55
|
+
export function createGraphView(): GraphViewAPI {
|
|
56
|
+
return {
|
|
57
|
+
ariaProps: {
|
|
58
|
+
role: 'group',
|
|
59
|
+
'aria-label': 'Knowledge graph',
|
|
60
|
+
},
|
|
61
|
+
dataAttributes: {},
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Look up a node by id. Returns `undefined` when not found.
|
|
67
|
+
*/
|
|
68
|
+
export function nodeById(nodes: GraphNode[], id: string): GraphNode | undefined {
|
|
69
|
+
return nodes.find((n) => n.id === id)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Build an SVG cubic-bezier path `d` string between two node positions.
|
|
74
|
+
*
|
|
75
|
+
* The control points bend the curve vertically so edges arc gracefully between
|
|
76
|
+
* horizontally or vertically offset nodes. Works for any pair of positions.
|
|
77
|
+
*/
|
|
78
|
+
export function graphEdgePath(source: GraphNode, target: GraphNode): string {
|
|
79
|
+
const sx = source.x
|
|
80
|
+
const sy = source.y
|
|
81
|
+
const tx = target.x
|
|
82
|
+
const ty = target.y
|
|
83
|
+
|
|
84
|
+
// Control-point offset: half the vertical distance, minimum 40px.
|
|
85
|
+
const dy = Math.abs(ty - sy)
|
|
86
|
+
const offset = Math.max(dy * 0.5, 40)
|
|
87
|
+
|
|
88
|
+
return `M ${sx} ${sy} C ${sx} ${sy + offset}, ${tx} ${ty - offset}, ${tx} ${ty}`
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Compute the axis-aligned bounding box of a set of nodes.
|
|
93
|
+
*
|
|
94
|
+
* Returns zero-area bounds centred at the origin when the array is empty.
|
|
95
|
+
*/
|
|
96
|
+
export function graphBounds(nodes: GraphNode[]): GraphBounds {
|
|
97
|
+
if (nodes.length === 0) {
|
|
98
|
+
return { minX: 0, minY: 0, maxX: 0, maxY: 0, width: 0, height: 0 }
|
|
99
|
+
}
|
|
100
|
+
let minX = Infinity
|
|
101
|
+
let minY = Infinity
|
|
102
|
+
let maxX = -Infinity
|
|
103
|
+
let maxY = -Infinity
|
|
104
|
+
for (const n of nodes) {
|
|
105
|
+
if (n.x < minX) minX = n.x
|
|
106
|
+
if (n.y < minY) minY = n.y
|
|
107
|
+
if (n.x > maxX) maxX = n.x
|
|
108
|
+
if (n.y > maxY) maxY = n.y
|
|
109
|
+
}
|
|
110
|
+
return { minX, minY, maxX, maxY, width: maxX - minX, height: maxY - minY }
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Count nodes per mastery state.
|
|
115
|
+
*
|
|
116
|
+
* Nodes without an explicit `state` are counted as `'not-started'`.
|
|
117
|
+
*/
|
|
118
|
+
export function summarizeStates(nodes: GraphNode[]): GraphStateSummary {
|
|
119
|
+
const counts: GraphStateSummary = {
|
|
120
|
+
mastered: 0,
|
|
121
|
+
'in-progress': 0,
|
|
122
|
+
'not-started': 0,
|
|
123
|
+
highlight: 0,
|
|
124
|
+
}
|
|
125
|
+
for (const n of nodes) {
|
|
126
|
+
const s: GraphNodeState = n.state ?? 'not-started'
|
|
127
|
+
counts[s] += 1
|
|
128
|
+
}
|
|
129
|
+
return counts
|
|
130
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export {
|
|
2
|
+
createGraphView,
|
|
3
|
+
nodeById,
|
|
4
|
+
graphEdgePath,
|
|
5
|
+
graphBounds,
|
|
6
|
+
summarizeStates,
|
|
7
|
+
type GraphNodeState,
|
|
8
|
+
type GraphNode,
|
|
9
|
+
type GraphEdge,
|
|
10
|
+
type GraphBounds,
|
|
11
|
+
type GraphStateSummary,
|
|
12
|
+
type GraphViewAPI,
|
|
13
|
+
} from './graph-view.js'
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
graphViewVariants,
|
|
17
|
+
graphNodeVariants,
|
|
18
|
+
graphNodeLabelClass,
|
|
19
|
+
graphEdgeClass,
|
|
20
|
+
graphLegendChipVariants,
|
|
21
|
+
} from './graph-view.styles.js'
|
package/dist/index.ts
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
export * from './astro-accordion/index.ts';
|
|
3
3
|
export * from './shared/index.ts';
|
|
4
4
|
export * from './astro-ai/index.ts';
|
|
5
|
+
export * from './astro-analytics/index.ts';
|
|
5
6
|
export * from './astro-animated-text/index.ts';
|
|
6
7
|
export * from './astro-app-shell/index.ts';
|
|
8
|
+
export * from './astro-audio-room/index.ts';
|
|
7
9
|
export * from './astro-auth/index.ts';
|
|
8
10
|
export * from './astro-avatar/index.ts';
|
|
9
11
|
export * from './astro-avatar-group/index.ts';
|
|
@@ -12,14 +14,21 @@ export * from './astro-bottom-nav/index.ts';
|
|
|
12
14
|
export * from './astro-breadcrumbs/index.ts';
|
|
13
15
|
export * from './astro-button/index.ts';
|
|
14
16
|
export * from './astro-calendar/index.ts';
|
|
17
|
+
export * from './astro-call-controls/index.ts';
|
|
18
|
+
export * from './astro-callout/index.ts';
|
|
15
19
|
export * from './astro-card/index.ts';
|
|
20
|
+
export * from './astro-card-grid/index.ts';
|
|
21
|
+
export * from './astro-carousel/index.ts';
|
|
16
22
|
export * from './astro-charts/index.ts';
|
|
17
23
|
export * from './astro-checkbox/index.ts';
|
|
24
|
+
export * from './astro-checklist/index.ts';
|
|
25
|
+
export * from './astro-code-block/index.ts';
|
|
18
26
|
export * from './astro-code-editor/index.ts';
|
|
19
27
|
export * from './astro-collapsible/index.ts';
|
|
20
28
|
export * from './astro-command/index.ts';
|
|
21
|
-
export * from './astro-
|
|
29
|
+
export * from './astro-command-input/index.ts';
|
|
22
30
|
export * from './astro-content-protection/index.ts';
|
|
31
|
+
export * from './astro-conversation/index.ts';
|
|
23
32
|
export * from './astro-cookie-consent/index.ts';
|
|
24
33
|
export * from './astro-data-table/index.ts';
|
|
25
34
|
export * from './astro-date-picker/index.ts';
|
|
@@ -27,57 +36,76 @@ export * from './astro-device-frame/index.ts';
|
|
|
27
36
|
export * from './astro-dialog/index.ts';
|
|
28
37
|
export * from './astro-diff-viewer/index.ts';
|
|
29
38
|
export * from './astro-dropdown-menu/index.ts';
|
|
39
|
+
export * from './astro-editor-status-bar/index.ts';
|
|
40
|
+
export * from './astro-editor-tabs/index.ts';
|
|
30
41
|
export * from './astro-emoji-picker/index.ts';
|
|
42
|
+
export * from './astro-empty-state/index.ts';
|
|
31
43
|
export * from './astro-feedback-dialog/index.ts';
|
|
44
|
+
export * from './astro-file-tree/index.ts';
|
|
32
45
|
export * from './astro-file-upload/index.ts';
|
|
46
|
+
export * from './astro-floating-reactions/index.ts';
|
|
47
|
+
export * from './astro-flow-editor/index.ts';
|
|
33
48
|
export * from './astro-footer/index.ts';
|
|
49
|
+
export * from './astro-graph-view/index.ts';
|
|
50
|
+
export * from './astro-icon-system/index.ts';
|
|
51
|
+
export * from './astro-infinite-canvas/index.ts';
|
|
34
52
|
export * from './astro-inline-editor/index.ts';
|
|
35
53
|
export * from './astro-input/index.ts';
|
|
36
54
|
export * from './astro-input-group/index.ts';
|
|
37
55
|
export * from './astro-install-prompt/index.ts';
|
|
38
56
|
export * from './astro-keyboard-shortcut/index.ts';
|
|
39
57
|
export * from './astro-language-selector/index.ts';
|
|
58
|
+
export * from './astro-link-card/index.ts';
|
|
59
|
+
export * from './astro-live-captions/index.ts';
|
|
60
|
+
export * from './astro-live-cursors/index.ts';
|
|
61
|
+
export * from './astro-live-transcript/index.ts';
|
|
62
|
+
export * from './astro-logger/index.ts';
|
|
40
63
|
export * from './astro-markdown-renderer/index.ts';
|
|
64
|
+
export * from './astro-mini-map/index.ts';
|
|
41
65
|
export * from './astro-mobile-nav/index.ts';
|
|
42
66
|
export * from './astro-navbar/index.ts';
|
|
43
67
|
export * from './astro-otp-input/index.ts';
|
|
68
|
+
export * from './astro-pagination/index.ts';
|
|
69
|
+
export * from './astro-password-input/index.ts';
|
|
70
|
+
export * from './astro-payment/index.ts';
|
|
44
71
|
export * from './astro-popover/index.ts';
|
|
72
|
+
export * from './astro-pre-call-lobby/index.ts';
|
|
45
73
|
export * from './astro-presence-indicator/index.ts';
|
|
46
74
|
export * from './astro-progress-display/index.ts';
|
|
75
|
+
export * from './astro-radial-gauge/index.ts';
|
|
47
76
|
export * from './astro-radio/index.ts';
|
|
77
|
+
export * from './astro-rating-scale/index.ts';
|
|
48
78
|
export * from './astro-reaction-bar/index.ts';
|
|
49
79
|
export * from './astro-resizable-layout/index.ts';
|
|
50
80
|
export * from './astro-rich-editor/index.ts';
|
|
51
81
|
export * from './astro-search-bar/index.ts';
|
|
82
|
+
export * from './astro-segmented-control/index.ts';
|
|
52
83
|
export * from './astro-select/index.ts';
|
|
84
|
+
export * from './astro-separator/index.ts';
|
|
53
85
|
export * from './astro-sidebar/index.ts';
|
|
54
86
|
export * from './astro-skeleton/index.ts';
|
|
87
|
+
export * from './astro-skip-to-content/index.ts';
|
|
55
88
|
export * from './astro-slide-viewer/index.ts';
|
|
89
|
+
export * from './astro-slider/index.ts';
|
|
90
|
+
export * from './astro-social-auth-button/index.ts';
|
|
56
91
|
export * from './astro-status-indicator/index.ts';
|
|
92
|
+
export * from './astro-steps/index.ts';
|
|
93
|
+
export * from './astro-sticky-note/index.ts';
|
|
57
94
|
export * from './astro-switch/index.ts';
|
|
95
|
+
export * from './astro-table-of-contents/index.ts';
|
|
58
96
|
export * from './astro-tabs/index.ts';
|
|
97
|
+
export * from './astro-terminal/index.ts';
|
|
98
|
+
export * from './astro-test-results/index.ts';
|
|
59
99
|
export * from './astro-textarea/index.ts';
|
|
60
100
|
export * from './astro-theme/index.ts';
|
|
61
101
|
export * from './astro-thread-view/index.ts';
|
|
102
|
+
export * from './astro-timeline/index.ts';
|
|
62
103
|
export * from './astro-toast/index.ts';
|
|
63
104
|
export * from './astro-tooltip/index.ts';
|
|
64
105
|
export * from './astro-version-selector/index.ts';
|
|
106
|
+
export * from './astro-video-grid/index.ts';
|
|
65
107
|
export * from './astro-video-player/index.ts';
|
|
108
|
+
export * from './astro-video-tile/index.ts';
|
|
66
109
|
export * from './astro-voice-pill/index.ts';
|
|
67
110
|
export * from './astro-waveform/index.ts';
|
|
68
|
-
export * from './astro-
|
|
69
|
-
export * from './astro-carousel/index.ts';
|
|
70
|
-
export * from './astro-slider/index.ts';
|
|
71
|
-
export * from './astro-pagination/index.ts';
|
|
72
|
-
export * from './astro-callout/index.ts';
|
|
73
|
-
export * from './astro-steps/index.ts';
|
|
74
|
-
export * from './astro-file-tree/index.ts';
|
|
75
|
-
export * from './astro-icon-system/index.ts';
|
|
76
|
-
export * from './astro-skip-to-content/index.ts';
|
|
77
|
-
export * from './astro-code-block/index.ts';
|
|
78
|
-
export * from './astro-link-card/index.ts';
|
|
79
|
-
export * from './astro-card-grid/index.ts';
|
|
80
|
-
export * from './astro-payment/index.ts';
|
|
81
|
-
export * from './astro-command-input/index.ts';
|
|
82
|
-
export * from './astro-logger/index.ts';
|
|
83
|
-
export * from './astro-analytics/index.ts';
|
|
111
|
+
export * from './astro-wizard/index.ts';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export {
|
|
2
|
+
clampZoom,
|
|
3
|
+
fitTransform,
|
|
4
|
+
transformToCss,
|
|
5
|
+
createInfiniteCanvas,
|
|
6
|
+
type CanvasTransform,
|
|
7
|
+
type Bounds,
|
|
8
|
+
type CreateInfiniteCanvasOptions,
|
|
9
|
+
type InfiniteCanvasAPI,
|
|
10
|
+
} from './infinite-canvas.js'
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
infiniteCanvasVariants,
|
|
14
|
+
canvasContentClass,
|
|
15
|
+
canvasControlsClass,
|
|
16
|
+
canvasZoomButtonVariants,
|
|
17
|
+
} from './infinite-canvas.styles.js'
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { cva } from '../shared/index.ts'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The outer viewport container. `overflow-hidden` clips panned content;
|
|
5
|
+
* `relative` anchors the absolute controls overlay.
|
|
6
|
+
*
|
|
7
|
+
* The `grid` variant adds a subtle dot-grid background rendered with a radial
|
|
8
|
+
* gradient using the `--border` semantic token so it respects the active theme.
|
|
9
|
+
*/
|
|
10
|
+
export const infiniteCanvasVariants = cva({
|
|
11
|
+
base: 'relative overflow-hidden bg-background',
|
|
12
|
+
variants: {
|
|
13
|
+
grid: {
|
|
14
|
+
'true': [
|
|
15
|
+
'bg-[radial-gradient(circle,hsl(var(--border))_1px,transparent_1px)]',
|
|
16
|
+
'[background-size:24px_24px]',
|
|
17
|
+
].join(' '),
|
|
18
|
+
'false': '',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
defaultVariants: {
|
|
22
|
+
grid: 'false',
|
|
23
|
+
},
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The transformed content layer that wraps children.
|
|
28
|
+
* `transform-gpu` promotes the layer for smooth panning/zooming.
|
|
29
|
+
* `origin-top-left` matches `transformOrigin: '0 0'` in the React adapter.
|
|
30
|
+
*/
|
|
31
|
+
export const canvasContentClass =
|
|
32
|
+
'absolute inset-0 origin-top-left will-change-transform'
|
|
33
|
+
|
|
34
|
+
/** Zoom-controls cluster — pinned to the bottom-right of the viewport. */
|
|
35
|
+
export const canvasControlsClass =
|
|
36
|
+
'absolute bottom-4 right-4 z-10 flex items-center gap-1'
|
|
37
|
+
|
|
38
|
+
/** Individual zoom button (+ / − / fit). */
|
|
39
|
+
export const canvasZoomButtonVariants = cva({
|
|
40
|
+
base: [
|
|
41
|
+
'inline-flex h-8 w-8 items-center justify-center rounded-md border border-border',
|
|
42
|
+
'bg-card text-foreground text-sm font-medium',
|
|
43
|
+
'hover:bg-muted transition-colors',
|
|
44
|
+
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',
|
|
45
|
+
'disabled:pointer-events-none disabled:opacity-50',
|
|
46
|
+
].join(' '),
|
|
47
|
+
variants: {},
|
|
48
|
+
defaultVariants: {},
|
|
49
|
+
})
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/** Transform state for an infinite canvas viewport. */
|
|
2
|
+
export type CanvasTransform = {
|
|
3
|
+
zoom: number
|
|
4
|
+
x: number
|
|
5
|
+
y: number
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** Axis-aligned bounding box of canvas content. */
|
|
9
|
+
export interface Bounds {
|
|
10
|
+
minX: number
|
|
11
|
+
minY: number
|
|
12
|
+
maxX: number
|
|
13
|
+
maxY: number
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Clamp a zoom level to [min, max].
|
|
18
|
+
*
|
|
19
|
+
* Defaults match common design-tool conventions: 25 % (0.25) to 400 % (4).
|
|
20
|
+
*/
|
|
21
|
+
export function clampZoom(zoom: number, min = 0.25, max = 4): number {
|
|
22
|
+
return Math.min(Math.max(zoom, min), max)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Compute the transform that centers `bounds` inside a viewport of size
|
|
27
|
+
* `viewportW × viewportH` with optional uniform `padding` (default 32 px).
|
|
28
|
+
*
|
|
29
|
+
* Returns a `CanvasTransform` clamped to [0.25, 4].
|
|
30
|
+
*/
|
|
31
|
+
export function fitTransform(
|
|
32
|
+
bounds: Bounds,
|
|
33
|
+
viewportW: number,
|
|
34
|
+
viewportH: number,
|
|
35
|
+
padding = 32,
|
|
36
|
+
): CanvasTransform {
|
|
37
|
+
const contentW = bounds.maxX - bounds.minX
|
|
38
|
+
const contentH = bounds.maxY - bounds.minY
|
|
39
|
+
|
|
40
|
+
if (contentW <= 0 || contentH <= 0 || viewportW <= 0 || viewportH <= 0) {
|
|
41
|
+
return { zoom: 1, x: 0, y: 0 }
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const availW = viewportW - padding * 2
|
|
45
|
+
const availH = viewportH - padding * 2
|
|
46
|
+
const rawZoom = Math.min(availW / contentW, availH / contentH)
|
|
47
|
+
const zoom = clampZoom(rawZoom)
|
|
48
|
+
|
|
49
|
+
// Center the scaled content within the viewport.
|
|
50
|
+
const scaledW = contentW * zoom
|
|
51
|
+
const scaledH = contentH * zoom
|
|
52
|
+
const x = (viewportW - scaledW) / 2 - bounds.minX * zoom
|
|
53
|
+
const y = (viewportH - scaledH) / 2 - bounds.minY * zoom
|
|
54
|
+
|
|
55
|
+
return { zoom, x, y }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Convert a `CanvasTransform` to a CSS `transform` string suitable for the
|
|
60
|
+
* content layer (`transformOrigin: '0 0'`).
|
|
61
|
+
*/
|
|
62
|
+
export function transformToCss(t: CanvasTransform): string {
|
|
63
|
+
return `translate(${t.x}px, ${t.y}px) scale(${t.zoom})`
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface CreateInfiniteCanvasOptions {
|
|
67
|
+
zoom?: number
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface InfiniteCanvasAPI {
|
|
71
|
+
/** ARIA attributes to spread on the viewport element. */
|
|
72
|
+
ariaProps: Record<string, string | number | boolean>
|
|
73
|
+
/** Data attributes for styling hooks. */
|
|
74
|
+
dataAttributes: Record<string, string | number | boolean>
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Build the framework-agnostic props for an infinite canvas viewport.
|
|
79
|
+
*
|
|
80
|
+
* Returns `role="group"` plus data attributes; adapters spread these onto
|
|
81
|
+
* their container element.
|
|
82
|
+
*/
|
|
83
|
+
export function createInfiniteCanvas(
|
|
84
|
+
options: CreateInfiniteCanvasOptions = {},
|
|
85
|
+
): InfiniteCanvasAPI {
|
|
86
|
+
const { zoom = 1 } = options
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
ariaProps: {
|
|
90
|
+
role: 'group',
|
|
91
|
+
'aria-label': 'Canvas',
|
|
92
|
+
},
|
|
93
|
+
dataAttributes: {
|
|
94
|
+
'data-zoom': zoom,
|
|
95
|
+
},
|
|
96
|
+
}
|
|
97
|
+
}
|
package/dist/input/index.ts
CHANGED
|
@@ -8,6 +8,10 @@ export const inputVariants = cva({
|
|
|
8
8
|
default: 'h-9',
|
|
9
9
|
lg: 'h-10 text-base',
|
|
10
10
|
},
|
|
11
|
+
validationState: {
|
|
12
|
+
valid: 'border-green-500 focus-visible:ring-green-500',
|
|
13
|
+
invalid: 'border-destructive focus-visible:ring-destructive',
|
|
14
|
+
},
|
|
11
15
|
},
|
|
12
16
|
defaultVariants: {
|
|
13
17
|
size: 'default',
|
package/dist/input/input.ts
CHANGED
|
@@ -2,6 +2,9 @@ import type { AccessibilityProps } from '../shared/index.ts'
|
|
|
2
2
|
|
|
3
3
|
export type InputType = 'text' | 'password' | 'email' | 'number' | 'tel' | 'url' | 'search'
|
|
4
4
|
|
|
5
|
+
/** High-level validation affordance for an input. */
|
|
6
|
+
export type InputValidationState = 'valid' | 'invalid'
|
|
7
|
+
|
|
5
8
|
export interface InputProps {
|
|
6
9
|
type?: InputType
|
|
7
10
|
disabled?: boolean
|
|
@@ -9,6 +12,14 @@ export interface InputProps {
|
|
|
9
12
|
required?: boolean
|
|
10
13
|
placeholder?: string
|
|
11
14
|
'aria-invalid'?: boolean
|
|
15
|
+
/**
|
|
16
|
+
* Validation affordance. The core derives `aria-invalid` from this:
|
|
17
|
+
* - `'valid'` → `aria-invalid={false}`
|
|
18
|
+
* - `'invalid'` → `aria-invalid={true}`
|
|
19
|
+
*
|
|
20
|
+
* An explicit `aria-invalid` prop always takes precedence.
|
|
21
|
+
*/
|
|
22
|
+
validationState?: InputValidationState
|
|
12
23
|
}
|
|
13
24
|
|
|
14
25
|
export interface InputAPI {
|
|
@@ -18,22 +29,47 @@ export interface InputAPI {
|
|
|
18
29
|
dataAttributes: Record<string, string>
|
|
19
30
|
}
|
|
20
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Resolve the effective `aria-invalid` value from an explicit `aria-invalid`
|
|
34
|
+
* prop and a high-level `validationState`. The explicit prop always wins;
|
|
35
|
+
* otherwise `validationState` maps `'invalid' → true`, `'valid' → false`, and
|
|
36
|
+
* an absent state leaves `aria-invalid` undefined (legacy behavior).
|
|
37
|
+
*/
|
|
38
|
+
export function resolveAriaInvalid(
|
|
39
|
+
ariaInvalid: boolean | undefined,
|
|
40
|
+
validationState: InputValidationState | undefined,
|
|
41
|
+
): boolean | undefined {
|
|
42
|
+
if (ariaInvalid !== undefined) {
|
|
43
|
+
return ariaInvalid
|
|
44
|
+
}
|
|
45
|
+
if (validationState === 'invalid') {
|
|
46
|
+
return true
|
|
47
|
+
}
|
|
48
|
+
if (validationState === 'valid') {
|
|
49
|
+
return false
|
|
50
|
+
}
|
|
51
|
+
return undefined
|
|
52
|
+
}
|
|
53
|
+
|
|
21
54
|
export function createInput(props: InputProps = {}): InputAPI {
|
|
22
55
|
const {
|
|
23
56
|
disabled = false,
|
|
24
57
|
readOnly = false,
|
|
25
58
|
required = false,
|
|
26
59
|
'aria-invalid': ariaInvalid,
|
|
60
|
+
validationState,
|
|
27
61
|
} = props
|
|
28
62
|
|
|
63
|
+
const resolvedInvalid = resolveAriaInvalid(ariaInvalid, validationState)
|
|
64
|
+
|
|
29
65
|
const ariaProps: InputAPI['ariaProps'] = {}
|
|
30
66
|
|
|
31
67
|
if (disabled) {
|
|
32
68
|
ariaProps['aria-disabled'] = true
|
|
33
69
|
}
|
|
34
70
|
|
|
35
|
-
if (
|
|
36
|
-
ariaProps['aria-invalid'] =
|
|
71
|
+
if (resolvedInvalid !== undefined) {
|
|
72
|
+
ariaProps['aria-invalid'] = resolvedInvalid
|
|
37
73
|
}
|
|
38
74
|
|
|
39
75
|
if (required) {
|
|
@@ -50,7 +86,7 @@ export function createInput(props: InputProps = {}): InputAPI {
|
|
|
50
86
|
dataAttributes['data-readonly'] = ''
|
|
51
87
|
}
|
|
52
88
|
|
|
53
|
-
if (
|
|
89
|
+
if (resolvedInvalid === true) {
|
|
54
90
|
dataAttributes['data-invalid'] = ''
|
|
55
91
|
}
|
|
56
92
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export {
|
|
2
|
+
visibleCues,
|
|
3
|
+
formatCue,
|
|
4
|
+
createLiveCaptions,
|
|
5
|
+
type CaptionCue,
|
|
6
|
+
type LiveCaptionsAPI,
|
|
7
|
+
} from './live-captions.js'
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
liveCaptionsVariants,
|
|
11
|
+
liveCaptionsCueVariants,
|
|
12
|
+
liveCaptionsSpeakerClass,
|
|
13
|
+
} from './live-captions.styles.js'
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { cva } from '../shared/index.ts'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Caption overlay container — an absolute-friendly, translucent dark surface
|
|
5
|
+
* centred over its positioned ancestor (e.g. a video element).
|
|
6
|
+
*/
|
|
7
|
+
export const liveCaptionsVariants = cva({
|
|
8
|
+
base: [
|
|
9
|
+
'relative mx-auto w-full max-w-2xl rounded-xl',
|
|
10
|
+
'bg-card/80 backdrop-blur-sm',
|
|
11
|
+
'px-4 py-3 space-y-1',
|
|
12
|
+
].join(' '),
|
|
13
|
+
variants: {
|
|
14
|
+
/** Controls how the container is positioned in the layout. */
|
|
15
|
+
position: {
|
|
16
|
+
/** Sits in normal document flow (default). */
|
|
17
|
+
static: '',
|
|
18
|
+
/** Absolutely positioned — consumer places it with inset utilities. */
|
|
19
|
+
absolute: 'absolute',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
defaultVariants: {
|
|
23
|
+
position: 'static',
|
|
24
|
+
},
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* A single cue line inside the overlay.
|
|
29
|
+
* Non-final (interim) cues get a dimmed italic treatment to signal they may change.
|
|
30
|
+
*/
|
|
31
|
+
export const liveCaptionsCueVariants = cva({
|
|
32
|
+
base: 'text-sm leading-snug text-foreground',
|
|
33
|
+
variants: {
|
|
34
|
+
interim: {
|
|
35
|
+
true: 'opacity-60 italic',
|
|
36
|
+
false: '',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
defaultVariants: {
|
|
40
|
+
interim: 'false',
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
/** Speaker-name prefix — rendered slightly muted to distinguish it from the speech text. */
|
|
45
|
+
export const liveCaptionsSpeakerClass = 'font-medium text-muted-foreground'
|