@refraction-ui/astro 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/dist/astro-audience-feature-card/AudienceFeatureCard.astro +53 -0
  2. package/dist/astro-audience-feature-card/index.ts +1 -0
  3. package/dist/astro-audio-room/AudioRoom.astro +81 -0
  4. package/dist/astro-audio-room/index.ts +1 -0
  5. package/dist/astro-brand-network-cell/BrandNetworkCell.astro +77 -0
  6. package/dist/astro-brand-network-cell/index.ts +1 -0
  7. package/dist/astro-browser-chrome-mock/BrowserChromeMock.astro +62 -0
  8. package/dist/astro-browser-chrome-mock/index.ts +1 -0
  9. package/dist/astro-call-controls/CallControls.astro +57 -0
  10. package/dist/astro-call-controls/index.ts +1 -0
  11. package/dist/astro-checklist/Checklist.astro +76 -0
  12. package/dist/astro-checklist/index.ts +1 -0
  13. package/dist/astro-editor-status-bar/EditorStatusBar.astro +92 -0
  14. package/dist/astro-editor-status-bar/index.ts +1 -0
  15. package/dist/astro-editor-tabs/EditorTabs.astro +74 -0
  16. package/dist/astro-editor-tabs/index.ts +1 -0
  17. package/dist/astro-floating-reactions/FloatingReactions.astro +56 -0
  18. package/dist/astro-floating-reactions/index.ts +1 -0
  19. package/dist/astro-flow-editor/FlowEditor.astro +99 -0
  20. package/dist/astro-flow-editor/index.ts +3 -0
  21. package/dist/astro-graph-view/GraphView.astro +109 -0
  22. package/dist/astro-graph-view/index.ts +1 -0
  23. package/dist/astro-infinite-canvas/InfiniteCanvas.astro +43 -0
  24. package/dist/astro-infinite-canvas/index.ts +1 -0
  25. package/dist/astro-live-captions/LiveCaptions.astro +54 -0
  26. package/dist/astro-live-captions/index.ts +1 -0
  27. package/dist/astro-live-cursors/LiveCursors.astro +55 -0
  28. package/dist/astro-live-cursors/index.ts +1 -0
  29. package/dist/astro-live-transcript/LiveTranscript.astro +55 -0
  30. package/dist/astro-live-transcript/index.ts +1 -0
  31. package/dist/astro-marquee-strip/MarqueeStrip.astro +63 -0
  32. package/dist/astro-marquee-strip/index.ts +1 -0
  33. package/dist/astro-mastery-bar/MasteryBar.astro +56 -0
  34. package/dist/astro-mastery-bar/index.ts +1 -0
  35. package/dist/astro-mini-map/MiniMap.astro +74 -0
  36. package/dist/astro-mini-map/index.ts +1 -0
  37. package/dist/astro-numbered-steps/NumberedSteps.astro +47 -0
  38. package/dist/astro-numbered-steps/index.ts +1 -0
  39. package/dist/astro-pre-call-lobby/PreCallLobby.astro +202 -0
  40. package/dist/astro-pre-call-lobby/index.ts +1 -0
  41. package/dist/astro-pricing-card/PricingCard.astro +114 -0
  42. package/dist/astro-pricing-card/index.ts +1 -0
  43. package/dist/astro-radial-gauge/RadialGauge.astro +144 -0
  44. package/dist/astro-radial-gauge/index.ts +1 -0
  45. package/dist/astro-rating-scale/RatingScale.astro +73 -0
  46. package/dist/astro-rating-scale/index.ts +1 -0
  47. package/dist/astro-section-head/SectionHead.astro +44 -0
  48. package/dist/astro-section-head/index.ts +1 -0
  49. package/dist/astro-stat-grid/StatGrid.astro +46 -0
  50. package/dist/astro-stat-grid/index.ts +1 -0
  51. package/dist/astro-sticky-note/StickyNote.astro +55 -0
  52. package/dist/astro-sticky-note/index.ts +1 -0
  53. package/dist/astro-terminal/Terminal.astro +67 -0
  54. package/dist/astro-terminal/index.ts +1 -0
  55. package/dist/astro-test-results/TestResults.astro +76 -0
  56. package/dist/astro-test-results/index.ts +1 -0
  57. package/dist/astro-timeline/Timeline.astro +59 -0
  58. package/dist/astro-timeline/index.ts +1 -0
  59. package/dist/astro-video-grid/VideoGrid.astro +182 -0
  60. package/dist/astro-video-grid/index.ts +1 -0
  61. package/dist/astro-video-tile/VideoTile.astro +104 -0
  62. package/dist/astro-video-tile/index.ts +1 -0
  63. package/dist/astro-wizard/Wizard.astro +137 -0
  64. package/dist/astro-wizard/index.ts +1 -0
  65. package/dist/audience-feature-card/audience-feature-card.styles.ts +23 -0
  66. package/dist/audience-feature-card/audience-feature-card.ts +39 -0
  67. package/dist/audience-feature-card/index.ts +13 -0
  68. package/dist/audio-room/audio-room.styles.ts +88 -0
  69. package/dist/audio-room/audio-room.ts +70 -0
  70. package/dist/audio-room/index.ts +16 -0
  71. package/dist/brand-network-cell/brand-network-cell.styles.ts +46 -0
  72. package/dist/brand-network-cell/brand-network-cell.ts +35 -0
  73. package/dist/brand-network-cell/index.ts +14 -0
  74. package/dist/browser-chrome-mock/browser-chrome-mock.styles.ts +43 -0
  75. package/dist/browser-chrome-mock/browser-chrome-mock.ts +52 -0
  76. package/dist/browser-chrome-mock/index.ts +17 -0
  77. package/dist/call-controls/call-controls.styles.ts +63 -0
  78. package/dist/call-controls/call-controls.ts +79 -0
  79. package/dist/call-controls/index.ts +15 -0
  80. package/dist/checklist/checklist.styles.ts +76 -0
  81. package/dist/checklist/checklist.ts +62 -0
  82. package/dist/checklist/index.ts +18 -0
  83. package/dist/editor-status-bar/editor-status-bar.styles.ts +40 -0
  84. package/dist/editor-status-bar/editor-status-bar.ts +78 -0
  85. package/dist/editor-status-bar/index.ts +15 -0
  86. package/dist/editor-tabs/editor-tabs.styles.ts +52 -0
  87. package/dist/editor-tabs/editor-tabs.ts +82 -0
  88. package/dist/editor-tabs/index.ts +15 -0
  89. package/dist/floating-reactions/floating-reactions.styles.ts +54 -0
  90. package/dist/floating-reactions/floating-reactions.ts +85 -0
  91. package/dist/floating-reactions/index.ts +14 -0
  92. package/dist/flow-editor/flow-editor.styles.ts +56 -0
  93. package/dist/flow-editor/flow-editor.ts +126 -0
  94. package/dist/flow-editor/index.ts +18 -0
  95. package/dist/graph-view/graph-view.styles.ts +66 -0
  96. package/dist/graph-view/graph-view.ts +130 -0
  97. package/dist/graph-view/index.ts +21 -0
  98. package/dist/index.ts +32 -0
  99. package/dist/infinite-canvas/index.ts +17 -0
  100. package/dist/infinite-canvas/infinite-canvas.styles.ts +49 -0
  101. package/dist/infinite-canvas/infinite-canvas.ts +97 -0
  102. package/dist/live-captions/index.ts +13 -0
  103. package/dist/live-captions/live-captions.styles.ts +45 -0
  104. package/dist/live-captions/live-captions.ts +57 -0
  105. package/dist/live-cursors/index.ts +14 -0
  106. package/dist/live-cursors/live-cursors.styles.ts +41 -0
  107. package/dist/live-cursors/live-cursors.ts +73 -0
  108. package/dist/live-transcript/index.ts +16 -0
  109. package/dist/live-transcript/live-transcript.styles.ts +48 -0
  110. package/dist/live-transcript/live-transcript.ts +82 -0
  111. package/dist/marquee-strip/index.ts +14 -0
  112. package/dist/marquee-strip/marquee-strip.styles.ts +61 -0
  113. package/dist/marquee-strip/marquee-strip.ts +35 -0
  114. package/dist/mastery-bar/index.ts +15 -0
  115. package/dist/mastery-bar/mastery-bar.styles.ts +45 -0
  116. package/dist/mastery-bar/mastery-bar.ts +55 -0
  117. package/dist/mini-map/index.ts +16 -0
  118. package/dist/mini-map/mini-map.styles.ts +32 -0
  119. package/dist/mini-map/mini-map.ts +122 -0
  120. package/dist/numbered-steps/index.ts +16 -0
  121. package/dist/numbered-steps/numbered-steps.styles.ts +36 -0
  122. package/dist/numbered-steps/numbered-steps.ts +64 -0
  123. package/dist/pre-call-lobby/index.ts +22 -0
  124. package/dist/pre-call-lobby/pre-call-lobby.styles.ts +108 -0
  125. package/dist/pre-call-lobby/pre-call-lobby.ts +61 -0
  126. package/dist/pricing-card/index.ts +19 -0
  127. package/dist/pricing-card/pricing-card.styles.ts +71 -0
  128. package/dist/pricing-card/pricing-card.ts +37 -0
  129. package/dist/radial-gauge/index.ts +26 -0
  130. package/dist/radial-gauge/radial-gauge.styles.ts +75 -0
  131. package/dist/radial-gauge/radial-gauge.ts +183 -0
  132. package/dist/rating-scale/index.ts +16 -0
  133. package/dist/rating-scale/rating-scale.styles.ts +48 -0
  134. package/dist/rating-scale/rating-scale.ts +101 -0
  135. package/dist/section-head/index.ts +13 -0
  136. package/dist/section-head/section-head.styles.ts +30 -0
  137. package/dist/section-head/section-head.ts +28 -0
  138. package/dist/stat-grid/index.ts +13 -0
  139. package/dist/stat-grid/stat-grid.styles.ts +25 -0
  140. package/dist/stat-grid/stat-grid.ts +41 -0
  141. package/dist/sticky-note/index.ts +14 -0
  142. package/dist/sticky-note/sticky-note.styles.ts +37 -0
  143. package/dist/sticky-note/sticky-note.ts +47 -0
  144. package/dist/terminal/index.ts +13 -0
  145. package/dist/terminal/terminal.styles.ts +56 -0
  146. package/dist/terminal/terminal.ts +60 -0
  147. package/dist/test-results/index.ts +19 -0
  148. package/dist/test-results/test-results.styles.ts +93 -0
  149. package/dist/test-results/test-results.ts +83 -0
  150. package/dist/timeline/index.ts +22 -0
  151. package/dist/timeline/timeline.styles.ts +98 -0
  152. package/dist/timeline/timeline.ts +86 -0
  153. package/dist/video-grid/index.ts +16 -0
  154. package/dist/video-grid/video-grid.styles.ts +38 -0
  155. package/dist/video-grid/video-grid.ts +93 -0
  156. package/dist/video-tile/index.ts +17 -0
  157. package/dist/video-tile/video-tile.styles.ts +59 -0
  158. package/dist/video-tile/video-tile.ts +74 -0
  159. package/dist/wizard/index.ts +28 -0
  160. package/dist/wizard/wizard.styles.ts +147 -0
  161. package/dist/wizard/wizard.ts +128 -0
  162. package/package.json +33 -1
@@ -0,0 +1,53 @@
1
+ ---
2
+ import {
3
+ createAudienceFeatureCard,
4
+ audienceFeatureCardVariants,
5
+ audienceFeatureCardKickerClass,
6
+ audienceFeatureCardTitleClass,
7
+ audienceFeatureCardBodyClass,
8
+ audienceFeatureCardFooterClass,
9
+ } from '../audience-feature-card/index.ts'
10
+ import { cn } from '../shared/index.ts'
11
+
12
+ interface Props extends astroHTML.JSX.HTMLAttributes {
13
+ /** Kicker text displayed above the title (e.g. "For teams"). */
14
+ kicker?: string
15
+ /** Main title — required (or pass content via default slot). */
16
+ title?: string
17
+ /** Body copy. */
18
+ body?: string
19
+ /** Footer string (alternative to the named footer slot). */
20
+ footer?: string
21
+ class?: string
22
+ }
23
+
24
+ const {
25
+ kicker,
26
+ title,
27
+ body,
28
+ footer,
29
+ class: className,
30
+ ...rest
31
+ } = Astro.props
32
+
33
+ const { ariaProps, dataAttributes } = createAudienceFeatureCard()
34
+ ---
35
+
36
+ <div
37
+ class={cn(audienceFeatureCardVariants(), className)}
38
+ {...ariaProps}
39
+ {...dataAttributes}
40
+ {...rest}
41
+ >
42
+ {kicker && <p class={audienceFeatureCardKickerClass}>{kicker}</p>}
43
+ {title
44
+ ? <p class={audienceFeatureCardTitleClass}>{title}</p>
45
+ : <p class={audienceFeatureCardTitleClass}><slot /></p>
46
+ }
47
+ {body && <p class={audienceFeatureCardBodyClass}>{body}</p>}
48
+ {(footer || Astro.slots.has('footer')) && (
49
+ <div class={audienceFeatureCardFooterClass}>
50
+ {footer ?? <slot name="footer" />}
51
+ </div>
52
+ )}
53
+ </div>
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,81 @@
1
+ ---
2
+ import {
3
+ createAudioRoom,
4
+ getInitials,
5
+ orbColumns,
6
+ audioRoomVariants,
7
+ audioRoomOrbCellVariants,
8
+ speakingOrbVariants,
9
+ audioRoomNameLabelClass,
10
+ audioRoomMutedBadgeClass,
11
+ audioRoomHandBadgeClass,
12
+ type AudioParticipant,
13
+ } from '../audio-room/index.ts'
14
+ import { cn } from '../shared/index.ts'
15
+
16
+ interface Props extends astroHTML.JSX.HTMLAttributes {
17
+ /** Participants to render as speaking orbs. */
18
+ participants: AudioParticipant[]
19
+ }
20
+
21
+ const { participants, class: className, ...rest } = Astro.props
22
+
23
+ const cols = orbColumns(participants.length)
24
+ const { ariaProps, dataAttributes } = createAudioRoom()
25
+ ---
26
+
27
+ <div
28
+ class={cn(audioRoomVariants(), className)}
29
+ style={`grid-template-columns: repeat(${cols}, minmax(0, 1fr))`}
30
+ {...ariaProps}
31
+ {...dataAttributes}
32
+ {...rest}
33
+ >
34
+ {
35
+ participants.map((participant) => {
36
+ const initials = getInitials(participant.name)
37
+ const speaking = participant.speaking ?? false
38
+ const muted = participant.muted ?? false
39
+ const handRaised = participant.handRaised ?? false
40
+
41
+ return (
42
+ <div class={audioRoomOrbCellVariants()}>
43
+ <div
44
+ role="img"
45
+ aria-label={participant.name}
46
+ data-speaking={speaking ? 'true' : 'false'}
47
+ data-muted={muted ? 'true' : 'false'}
48
+ data-hand-raised={handRaised ? 'true' : 'false'}
49
+ class={speakingOrbVariants({
50
+ speaking: speaking ? 'true' : 'false',
51
+ muted: muted ? 'true' : 'false',
52
+ })}
53
+ >
54
+ {participant.avatarUrl ? (
55
+ <img
56
+ src={participant.avatarUrl}
57
+ alt={participant.name}
58
+ class="absolute inset-0 size-full object-cover"
59
+ />
60
+ ) : (
61
+ <span aria-hidden="true">{initials}</span>
62
+ )}
63
+
64
+ {muted && (
65
+ <span class={audioRoomMutedBadgeClass} aria-label="Muted">
66
+ 🔇
67
+ </span>
68
+ )}
69
+
70
+ {handRaised && (
71
+ <span class={audioRoomHandBadgeClass} aria-label="Hand raised">
72
+ ✋
73
+ </span>
74
+ )}
75
+ </div>
76
+ <span class={audioRoomNameLabelClass}>{participant.name}</span>
77
+ </div>
78
+ )
79
+ })
80
+ }
81
+ </div>
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,77 @@
1
+ ---
2
+ import {
3
+ createBrandNetworkCell,
4
+ brandNetworkCellVariants,
5
+ brandNetworkCellGlyphClass,
6
+ brandNetworkCellDomainClass,
7
+ brandNetworkCellCurrentBadgeClass,
8
+ brandNetworkCellBodyClass,
9
+ brandNetworkCellLinkClass,
10
+ } from '../brand-network-cell/index.ts'
11
+ import { cn } from '../shared/index.ts'
12
+
13
+ interface Props extends astroHTML.JSX.HTMLAttributes {
14
+ /** Single character or short string used as the brand monogram. */
15
+ glyph: string
16
+ /** CSS colour value for the glyph box background (brand tint). Applied via inline style. */
17
+ glyphBg?: string
18
+ /** CSS colour value for the glyph text (brand tint). Applied via inline style. */
19
+ glyphColor?: string
20
+ /** Primary identifier shown below the glyph (product domain or name). */
21
+ domain: string
22
+ /** Supporting description text. */
23
+ body: string
24
+ /** When provided, renders a link at the bottom of the card. */
25
+ href?: string
26
+ /** Label for the link. Defaults to "Visit →". */
27
+ linkLabel?: string
28
+ /** Marks this cell as the current/active product in the network. */
29
+ current?: boolean
30
+ }
31
+
32
+ const {
33
+ glyph,
34
+ glyphBg,
35
+ glyphColor,
36
+ domain,
37
+ body,
38
+ href,
39
+ linkLabel,
40
+ current = false,
41
+ class: className,
42
+ ...rest
43
+ } = Astro.props
44
+
45
+ const { ariaProps, dataAttributes } = createBrandNetworkCell({ current })
46
+ const glyphStyle = `${glyphBg ? `background:${glyphBg};` : ''}${glyphColor ? `color:${glyphColor};` : ''}`
47
+ ---
48
+
49
+ <div
50
+ class={cn(brandNetworkCellVariants({ current: current ? 'true' : 'false' }), className)}
51
+ {...ariaProps}
52
+ {...dataAttributes}
53
+ {...rest}
54
+ >
55
+ <!-- Glyph box — brand tint via inline style -->
56
+ <div class={brandNetworkCellGlyphClass} style={glyphStyle} aria-hidden="true">
57
+ {glyph}
58
+ </div>
59
+
60
+ <!-- Domain row -->
61
+ <div class="flex items-center gap-2">
62
+ <span class={brandNetworkCellDomainClass}>{domain}</span>
63
+ {current && (
64
+ <span class={brandNetworkCellCurrentBadgeClass}>You are here</span>
65
+ )}
66
+ </div>
67
+
68
+ <!-- Body -->
69
+ <p class={brandNetworkCellBodyClass}>{body}</p>
70
+
71
+ <!-- Optional link -->
72
+ {href && (
73
+ <a href={href} class={brandNetworkCellLinkClass}>
74
+ {linkLabel ?? 'Visit →'}
75
+ </a>
76
+ )}
77
+ </div>
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,62 @@
1
+ ---
2
+ import {
3
+ createBrowserChromeMock,
4
+ splitUrl,
5
+ browserChromeMockVariants,
6
+ chromeBarClass,
7
+ trafficDotClass,
8
+ urlBarClass,
9
+ urlDomainClass,
10
+ statusBadgeVariants,
11
+ contentAreaClass,
12
+ type BrowserChromeStatus,
13
+ } from '../browser-chrome-mock/index.ts'
14
+ import { cn } from '../shared/index.ts'
15
+
16
+ interface Props extends astroHTML.JSX.HTMLAttributes {
17
+ /** URL to display in the address bar. Bold domain + normal path. */
18
+ url: string
19
+ /** Optional status badge shown in the chrome bar. */
20
+ status?: BrowserChromeStatus
21
+ }
22
+
23
+ const { url, status, class: className, ...rest } = Astro.props
24
+
25
+ const { ariaProps, dataAttributes } = createBrowserChromeMock({ status })
26
+ const { domain, path } = splitUrl(url)
27
+
28
+ const trafficDots = ['bg-red-400', 'bg-yellow-400', 'bg-green-400'] as const
29
+ ---
30
+
31
+ <div class={cn(browserChromeMockVariants(), className)} {...ariaProps} {...dataAttributes} {...rest}>
32
+ <!-- Chrome toolbar -->
33
+ <div class={chromeBarClass}>
34
+ <!-- Traffic-light dots -->
35
+ <div class="flex items-center gap-1.5 shrink-0">
36
+ {trafficDots.map((color) => (
37
+ <span class={`${trafficDotClass} ${color}`} />
38
+ ))}
39
+ </div>
40
+
41
+ <!-- URL bar -->
42
+ <div class={urlBarClass}>
43
+ <span class={urlDomainClass}>{domain}</span>
44
+ {path && <span>{path}</span>}
45
+ </div>
46
+
47
+ <!-- Status badge -->
48
+ {status && (
49
+ <div class={statusBadgeVariants({ status })}>
50
+ {status === 'rec' && (
51
+ <span class="size-1.5 rounded-full bg-destructive animate-pulse" />
52
+ )}
53
+ {status}
54
+ </div>
55
+ )}
56
+ </div>
57
+
58
+ <!-- Content area -->
59
+ <div class={contentAreaClass}>
60
+ <slot />
61
+ </div>
62
+ </div>
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,57 @@
1
+ ---
2
+ import {
3
+ createCallControls,
4
+ callControlsVariants,
5
+ callControlButtonVariants,
6
+ callControlLabelClass,
7
+ type CallControlTone,
8
+ type CallControlItem,
9
+ } from '../call-controls/index.ts'
10
+ import { cn } from '../shared/index.ts'
11
+
12
+ interface Props extends astroHTML.JSX.HTMLAttributes {
13
+ /**
14
+ * Array of control descriptors to render as buttons.
15
+ * If omitted, the default <slot /> is used instead (composable usage).
16
+ */
17
+ controls?: CallControlItem[]
18
+ /** Visual size of the toolbar and its buttons. */
19
+ size?: 'sm' | 'md'
20
+ }
21
+
22
+ const {
23
+ controls,
24
+ size = 'md',
25
+ class: className,
26
+ ...rest
27
+ } = Astro.props
28
+
29
+ const { ariaProps, dataAttributes } = createCallControls({ controls })
30
+
31
+ function toneClass(tone: CallControlTone | undefined): string {
32
+ return callControlButtonVariants({ tone: tone ?? 'default', size })
33
+ }
34
+ ---
35
+
36
+ <div
37
+ class={cn(callControlsVariants({ size }), className)}
38
+ role={ariaProps.role}
39
+ aria-label={ariaProps['aria-label']}
40
+ {...dataAttributes}
41
+ {...rest}
42
+ >
43
+ {controls
44
+ ? controls.map((ctrl) => (
45
+ <button
46
+ type="button"
47
+ aria-label={ctrl.label}
48
+ aria-pressed={ctrl.pressed !== undefined ? ctrl.pressed : undefined}
49
+ class={toneClass(ctrl.tone)}
50
+ >
51
+ {ctrl.icon && <span aria-hidden="true">{ctrl.icon}</span>}
52
+ <span class={callControlLabelClass}>{ctrl.label}</span>
53
+ </button>
54
+ ))
55
+ : <slot />
56
+ }
57
+ </div>
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,76 @@
1
+ ---
2
+ import {
3
+ createChecklist,
4
+ checklistProgress,
5
+ checklistContainerClass,
6
+ checklistListClass,
7
+ checklistItemVariants,
8
+ checklistBoxVariants,
9
+ checklistLabelWrapClass,
10
+ checklistLabelVariants,
11
+ checklistDescriptionClass,
12
+ checklistProgressClass,
13
+ type ChecklistItemData,
14
+ } from '../checklist/index.ts'
15
+ import { cn } from '../shared/index.ts'
16
+
17
+ interface Props extends astroHTML.JSX.HTMLAttributes {
18
+ /** List of checklist items. */
19
+ items: ChecklistItemData[]
20
+ /** Show a "{completed}/{total}" progress summary below the list. */
21
+ showProgress?: boolean
22
+ }
23
+
24
+ const { items, showProgress = false, class: className, ...rest } = Astro.props
25
+
26
+ const { ariaProps, dataAttributes } = createChecklist()
27
+ const progress = showProgress ? checklistProgress(items) : null
28
+ ---
29
+
30
+ <div class={cn(checklistContainerClass, className)} {...dataAttributes} {...rest}>
31
+ <ul class={checklistListClass} {...ariaProps}>
32
+ {
33
+ items.map((item) => {
34
+ const checked = Boolean(item.checked)
35
+ return (
36
+ <li role="presentation">
37
+ <button
38
+ type="button"
39
+ role="checkbox"
40
+ aria-checked={checked}
41
+ data-state={checked ? 'checked' : 'unchecked'}
42
+ class={checklistItemVariants({ checked: checked ? 'true' : 'false' })}
43
+ >
44
+ <span aria-hidden="true" class={checklistBoxVariants({ checked: checked ? 'true' : 'false' })}>
45
+ {checked && (
46
+ <svg viewBox="0 0 12 12" fill="none" class="h-3 w-3" aria-hidden="true">
47
+ <path
48
+ d="M2 6l3 3 5-5"
49
+ stroke="currentColor"
50
+ stroke-width="1.5"
51
+ stroke-linecap="round"
52
+ stroke-linejoin="round"
53
+ />
54
+ </svg>
55
+ )}
56
+ </span>
57
+ <span class={checklistLabelWrapClass}>
58
+ <span class={checklistLabelVariants({ checked: checked ? 'true' : 'false' })}>{item.label}</span>
59
+ {item.description && (
60
+ <span class={checklistDescriptionClass}>{item.description}</span>
61
+ )}
62
+ </span>
63
+ </button>
64
+ </li>
65
+ )
66
+ })
67
+ }
68
+ </ul>
69
+ {
70
+ progress !== null && (
71
+ <p class={checklistProgressClass}>
72
+ {progress.completed}/{progress.total} completed
73
+ </p>
74
+ )
75
+ }
76
+ </div>
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,92 @@
1
+ ---
2
+ import {
3
+ createEditorStatusBar,
4
+ formatCursorPosition,
5
+ partitionSegments,
6
+ editorStatusBarVariants,
7
+ statusBarGroupClass,
8
+ statusBarSegmentVariants,
9
+ type StatusSegment,
10
+ type StatusSegmentTone,
11
+ } from '../editor-status-bar/index.ts'
12
+ import { cn } from '../shared/index.ts'
13
+
14
+ interface Props extends astroHTML.JSX.HTMLAttributes {
15
+ /**
16
+ * Explicit list of segments. When provided, all convenience props are
17
+ * ignored.
18
+ */
19
+ segments?: StatusSegment[]
20
+ /** Current line number (1-indexed). */
21
+ line?: number
22
+ /** Current column number (1-indexed). */
23
+ col?: number
24
+ /** Indentation descriptor, e.g. `'Spaces: 4'`. */
25
+ indentation?: string
26
+ /** Language / runtime label, e.g. `'Python 3.11.4'`. */
27
+ language?: string
28
+ /** File encoding, e.g. `'UTF-8'`. */
29
+ encoding?: string
30
+ /** End-of-line sequence, e.g. `'LF'` or `'CRLF'`. */
31
+ eol?: string
32
+ /** Persistence status label, e.g. `'Auto-saved'`. */
33
+ status?: string
34
+ }
35
+
36
+ const {
37
+ segments: segmentsProp,
38
+ line,
39
+ col,
40
+ indentation,
41
+ language,
42
+ encoding,
43
+ eol,
44
+ status,
45
+ class: className,
46
+ ...rest
47
+ } = Astro.props
48
+
49
+ function buildSegments(): StatusSegment[] {
50
+ const segs: StatusSegment[] = []
51
+ if (line !== undefined && col !== undefined) {
52
+ segs.push({ id: 'cursor', label: formatCursorPosition(line, col), align: 'left', tone: 'default' })
53
+ }
54
+ if (indentation) {
55
+ segs.push({ id: 'indentation', label: indentation, align: 'left', tone: 'muted' })
56
+ }
57
+ if (language) {
58
+ segs.push({ id: 'language', label: language, align: 'right', tone: 'accent' })
59
+ }
60
+ if (encoding) {
61
+ segs.push({ id: 'encoding', label: encoding, align: 'right', tone: 'muted' })
62
+ }
63
+ if (eol) {
64
+ segs.push({ id: 'eol', label: eol, align: 'right', tone: 'muted' })
65
+ }
66
+ if (status) {
67
+ segs.push({ id: 'status', label: status, align: 'right', tone: 'muted' })
68
+ }
69
+ return segs
70
+ }
71
+
72
+ const segments = segmentsProp ?? buildSegments()
73
+ const { left, right } = partitionSegments(segments)
74
+ const { ariaProps, dataAttributes } = createEditorStatusBar()
75
+ ---
76
+
77
+ <div class={cn(editorStatusBarVariants(), className)} {...ariaProps} {...dataAttributes} {...rest}>
78
+ <div class={statusBarGroupClass}>
79
+ {left.map((seg) => (
80
+ <span class={statusBarSegmentVariants({ tone: (seg.tone ?? 'default') as StatusSegmentTone })}>
81
+ {seg.label}
82
+ </span>
83
+ ))}
84
+ </div>
85
+ <div class={statusBarGroupClass}>
86
+ {right.map((seg) => (
87
+ <span class={statusBarSegmentVariants({ tone: (seg.tone ?? 'default') as StatusSegmentTone })}>
88
+ {seg.label}
89
+ </span>
90
+ ))}
91
+ </div>
92
+ </div>
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,74 @@
1
+ ---
2
+ import {
3
+ createEditorTabs,
4
+ editorTabsVariants,
5
+ editorTabVariants,
6
+ editorTabDirtyDotClass,
7
+ editorTabCloseButtonClass,
8
+ editorTabIconClass,
9
+ type EditorTabData,
10
+ } from '../editor-tabs/index.ts'
11
+ import { cn } from '../shared/index.ts'
12
+
13
+ interface Props extends astroHTML.JSX.HTMLAttributes {
14
+ /** The list of tab entries to render. */
15
+ tabs: EditorTabData[]
16
+ /** The id of the currently active tab. */
17
+ activeId: string
18
+ }
19
+
20
+ const {
21
+ tabs,
22
+ activeId,
23
+ class: className,
24
+ ...rest
25
+ } = Astro.props
26
+
27
+ const activeIndex = tabs.findIndex((t) => t.id === activeId)
28
+ const tabbableIndex = activeIndex === -1 ? 0 : activeIndex
29
+ const { ariaProps, dataAttributes } = createEditorTabs({ activeId })
30
+ ---
31
+
32
+ <div class={cn(editorTabsVariants(), className)} {...ariaProps} {...dataAttributes} {...rest}>
33
+ {
34
+ tabs.map((tab, index) => {
35
+ const isActive = tab.id === activeId
36
+ return (
37
+ <button
38
+ type="button"
39
+ role="tab"
40
+ aria-selected={isActive}
41
+ aria-controls={`tabpanel-${tab.id}`}
42
+ id={`tab-${tab.id}`}
43
+ tabindex={index === tabbableIndex ? 0 : -1}
44
+ data-state={isActive ? 'active' : 'inactive'}
45
+ class={editorTabVariants({ state: isActive ? 'active' : 'inactive' })}
46
+ >
47
+ {tab.icon && (
48
+ <span class={editorTabIconClass} aria-hidden="true">
49
+ {tab.icon}
50
+ </span>
51
+ )}
52
+ <span>{tab.label}</span>
53
+ {tab.dirty && (
54
+ <span
55
+ class={editorTabDirtyDotClass}
56
+ aria-label="unsaved changes"
57
+ role="status"
58
+ />
59
+ )}
60
+ {tab.closable && (
61
+ <span
62
+ role="button"
63
+ aria-label={`Close ${tab.label}`}
64
+ tabindex="-1"
65
+ class={editorTabCloseButtonClass}
66
+ >
67
+ ×
68
+ </span>
69
+ )}
70
+ </button>
71
+ )
72
+ })
73
+ }
74
+ </div>
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,56 @@
1
+ ---
2
+ import {
3
+ createFloatingReactions,
4
+ laneOffsetPercent,
5
+ floatingReactionsVariants,
6
+ floatingReactionItemClass,
7
+ floatingReactionLabelClass,
8
+ type FloatingReaction,
9
+ } from '../floating-reactions/index.ts'
10
+ import { cn } from '../shared/index.ts'
11
+
12
+ interface Props extends astroHTML.JSX.HTMLAttributes {
13
+ /**
14
+ * Reactions to render at SSR time. For animated runtime usage, use the
15
+ * React adapter which manages auto-expiry via useFloatingReactions().
16
+ */
17
+ reactions?: FloatingReaction[]
18
+ /**
19
+ * Total number of horizontal lane buckets used to spread reactions.
20
+ * @default 5
21
+ */
22
+ lanes?: number
23
+ }
24
+
25
+ const {
26
+ reactions = [],
27
+ lanes = 5,
28
+ class: className,
29
+ ...rest
30
+ } = Astro.props
31
+
32
+ const { ariaProps, dataAttributes } = createFloatingReactions()
33
+ ---
34
+
35
+ <div
36
+ class={cn(floatingReactionsVariants({ active: reactions.length > 0 ? 'true' : 'false' }), className)}
37
+ {...ariaProps}
38
+ {...dataAttributes}
39
+ {...rest}
40
+ >
41
+ {
42
+ reactions.map((reaction) => {
43
+ const left = laneOffsetPercent(reaction.lane ?? 0, lanes)
44
+ return (
45
+ <span
46
+ class={floatingReactionItemClass}
47
+ style={`left:${left}%`}
48
+ aria-hidden="true"
49
+ >
50
+ {reaction.emoji}
51
+ <span class={floatingReactionLabelClass}>{reaction.emoji}</span>
52
+ </span>
53
+ )
54
+ })
55
+ }
56
+ </div>
@@ -0,0 +1 @@
1
+ export {}