@a4ui/core 0.37.1 → 0.38.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +8 -7
  2. package/dist/Collapse-Cr5cDqAl.js +375 -0
  3. package/dist/charts/AreaChart.d.ts +38 -0
  4. package/dist/charts/BarChart.d.ts +17 -1
  5. package/dist/charts/PieChart.d.ts +29 -0
  6. package/dist/charts/RadialBarChart.d.ts +33 -0
  7. package/dist/charts/index.d.ts +5 -0
  8. package/dist/charts/shared.d.ts +111 -0
  9. package/dist/charts.js +1493 -780
  10. package/dist/commerce.js +625 -634
  11. package/dist/elements.css +1076 -8
  12. package/dist/elements.iife.js +1 -6
  13. package/dist/elements.js +7774 -9133
  14. package/dist/full.css +1076 -8
  15. package/dist/index.d.ts +30 -3
  16. package/dist/index.js +17502 -15126
  17. package/dist/layout/Aurora.d.ts +16 -0
  18. package/dist/layout/EffectsToggle.d.ts +1 -1
  19. package/dist/layout/SpaceBackground.d.ts +1 -1
  20. package/dist/motion-CTIBwMCA.js +104 -0
  21. package/dist/styles.css +110 -3
  22. package/dist/ui/AspectRatio.d.ts +19 -0
  23. package/dist/ui/Attachment.d.ts +70 -0
  24. package/dist/ui/ButtonGroup.d.ts +37 -0
  25. package/dist/ui/ChatMarker.d.ts +20 -0
  26. package/dist/ui/ChatThread.d.ts +32 -8
  27. package/dist/ui/ContactSection.d.ts +49 -0
  28. package/dist/ui/CtaBanner.d.ts +28 -0
  29. package/dist/ui/Drawer.d.ts +5 -2
  30. package/dist/ui/Faq.d.ts +29 -0
  31. package/dist/ui/FeatureGrid.d.ts +35 -0
  32. package/dist/ui/Field.d.ts +148 -0
  33. package/dist/ui/Hero.d.ts +48 -0
  34. package/dist/ui/InputGroup.d.ts +93 -0
  35. package/dist/ui/Item.d.ts +63 -0
  36. package/dist/ui/Label.d.ts +23 -0
  37. package/dist/ui/Menubar.d.ts +83 -0
  38. package/dist/ui/Message.d.ts +51 -5
  39. package/dist/ui/Modal.d.ts +8 -2
  40. package/dist/ui/NativeSelect.d.ts +26 -0
  41. package/dist/ui/NavigationMenu.d.ts +85 -0
  42. package/dist/ui/PromptComposer.d.ts +5 -0
  43. package/dist/ui/Prose.d.ts +21 -0
  44. package/dist/ui/Questionnaire.d.ts +71 -0
  45. package/dist/ui/ScrollArea.d.ts +30 -0
  46. package/dist/ui/Sidebar.d.ts +229 -0
  47. package/dist/ui/SiteFooter.d.ts +39 -0
  48. package/dist/ui/SiteNav.d.ts +35 -0
  49. package/dist/ui/TeamGrid.d.ts +33 -0
  50. package/dist/ui/Testimonials.d.ts +37 -0
  51. package/dist/ui/internal/sectionKit.d.ts +22 -0
  52. package/dist/ui/internal/socialIcons.d.ts +9 -0
  53. package/package.json +38 -26
  54. package/preset.d.ts +23 -0
  55. package/src/charts/AreaChart.tsx +206 -0
  56. package/src/charts/BarChart.tsx +241 -5
  57. package/src/charts/DonutChart.tsx +8 -11
  58. package/src/charts/LineChart.tsx +2 -3
  59. package/src/charts/PieChart.tsx +145 -0
  60. package/src/charts/RadialBarChart.tsx +141 -0
  61. package/src/charts/index.ts +14 -0
  62. package/src/charts/shared.tsx +304 -0
  63. package/src/index.ts +192 -3
  64. package/src/layout/Aurora.tsx +36 -7
  65. package/src/layout/sceneEffects.ts +22 -3
  66. package/src/ui/AlertDialog.tsx +6 -3
  67. package/src/ui/AspectRatio.tsx +35 -0
  68. package/src/ui/Attachment.tsx +189 -0
  69. package/src/ui/ButtonGroup.tsx +89 -0
  70. package/src/ui/ChatMarker.tsx +58 -0
  71. package/src/ui/ChatThread.tsx +115 -23
  72. package/src/ui/Command.tsx +6 -3
  73. package/src/ui/ContactSection.tsx +199 -0
  74. package/src/ui/CtaBanner.tsx +62 -0
  75. package/src/ui/DateField.tsx +2 -1
  76. package/src/ui/DateRangePicker.tsx +2 -1
  77. package/src/ui/Drawer.tsx +43 -7
  78. package/src/ui/Faq.tsx +57 -0
  79. package/src/ui/FeatureGrid.tsx +77 -0
  80. package/src/ui/Field.tsx +374 -0
  81. package/src/ui/Hero.tsx +146 -0
  82. package/src/ui/Image.tsx +6 -3
  83. package/src/ui/InputGroup.tsx +219 -0
  84. package/src/ui/Item.tsx +185 -0
  85. package/src/ui/Label.tsx +50 -0
  86. package/src/ui/Menubar.tsx +212 -0
  87. package/src/ui/Message.tsx +139 -13
  88. package/src/ui/Modal.tsx +47 -8
  89. package/src/ui/MultiSelect.tsx +2 -1
  90. package/src/ui/NativeSelect.tsx +66 -0
  91. package/src/ui/NavigationMenu.tsx +262 -0
  92. package/src/ui/PromptComposer.tsx +11 -0
  93. package/src/ui/Prose.tsx +63 -0
  94. package/src/ui/Questionnaire.tsx +331 -0
  95. package/src/ui/ScrollArea.tsx +70 -0
  96. package/src/ui/Sidebar.tsx +753 -0
  97. package/src/ui/SiteFooter.tsx +112 -0
  98. package/src/ui/SiteNav.tsx +146 -0
  99. package/src/ui/TeamGrid.tsx +81 -0
  100. package/src/ui/Testimonials.tsx +103 -0
  101. package/src/ui/TimeField.tsx +2 -1
  102. package/src/ui/internal/sectionKit.tsx +72 -0
  103. package/src/ui/internal/socialIcons.tsx +41 -0
  104. package/dist/NumberInput-Bnh2u7pp.js +0 -381
  105. package/dist/motion-jYMWmZqB.js +0 -119
@@ -15,6 +15,22 @@ export interface AuroraProps {
15
15
  * @default 'blobs'
16
16
  */
17
17
  variant?: 'blobs' | 'mesh';
18
+ /**
19
+ * Blob palette. Each entry is a CSS color (`'#ff6a3d'`, `'oklch(0.7 0.2 40)'`,
20
+ * `'hsl(var(--brand))'`) or a theme token written as a custom property name
21
+ * (`'--primary'`, `'--accent'`, `'--success'` ...). Entries are assigned to the
22
+ * blobs / mesh points in order and repeat when there are fewer colors than
23
+ * blobs. Defaults to the theme tokens `--primary` / `--accent`, so every theme
24
+ * still tints it for free.
25
+ */
26
+ colors?: string[];
27
+ /**
28
+ * Color of the cursor-following glow, same format as a `colors` entry.
29
+ * @default '--primary'
30
+ */
31
+ glowColor?: string;
32
+ /** Peak opacity of the cursor glow, 0..1. @default 0.1 */
33
+ glowOpacity?: number;
18
34
  class?: string;
19
35
  }
20
36
  /**
@@ -15,5 +15,5 @@ interface EffectsToggleProps {
15
15
  * <EffectsToggle label="Toggle effects" />
16
16
  * ```
17
17
  */
18
- export declare function EffectsToggle(props: EffectsToggleProps): import("solid-js").JSX.Element;
18
+ export declare function EffectsToggle(props: EffectsToggleProps): import('solid-js').JSX.Element;
19
19
  export {};
@@ -11,4 +11,4 @@
11
11
  * <SpaceBackground />
12
12
  * ```
13
13
  */
14
- export declare function SpaceBackground(): import("solid-js").JSX.Element;
14
+ export declare function SpaceBackground(): import('solid-js').JSX.Element;
@@ -0,0 +1,104 @@
1
+ import { clsx as e } from "clsx";
2
+ import { twMerge as t } from "tailwind-merge";
3
+ import { createEffect as n, createSignal as r, onCleanup as i, untrack as a } from "solid-js";
4
+ import { animate as o, inView as s, scroll as c, spring as l, stagger as u } from "motion";
5
+ // src/lib/cn.ts
6
+ function d(...n) {
7
+ return t(e(n));
8
+ }
9
+ // src/lib/effects.ts
10
+ var f = "a4ui-effects";
11
+ function p() {
12
+ try {
13
+ return window.localStorage;
14
+ } catch {
15
+ return null;
16
+ }
17
+ }
18
+ function m() {
19
+ try {
20
+ if (new URLSearchParams(window.location.search).get("calm") === "1") return !1;
21
+ } catch {}
22
+ let e = p()?.getItem(f);
23
+ return e === null || e === "1";
24
+ }
25
+ function h(e) {
26
+ typeof document < "u" && document.documentElement.classList.toggle("calm", !e);
27
+ }
28
+ var g = m();
29
+ h(g);
30
+ var [_, v] = r(g);
31
+ function y() {
32
+ return _;
33
+ }
34
+ function b() {
35
+ return !_();
36
+ }
37
+ function x(e) {
38
+ p()?.setItem(f, e ? "1" : "0"), h(e), v(e);
39
+ }
40
+ // src/lib/motion.ts
41
+ var S = "(prefers-reduced-motion: reduce)";
42
+ function C() {
43
+ return typeof window > "u" || typeof window.matchMedia != "function" ? !1 : window.matchMedia(S).matches;
44
+ }
45
+ var w = "a4ui-motion-forced";
46
+ function T() {
47
+ try {
48
+ return window.localStorage;
49
+ } catch {
50
+ return null;
51
+ }
52
+ }
53
+ var [E, D] = r(T()?.getItem(w) === "1");
54
+ typeof document < "u" && document.documentElement.classList.toggle("force-motion", a(E));
55
+ function O() {
56
+ return E;
57
+ }
58
+ function k(e) {
59
+ T()?.setItem(w, e ? "1" : "0"), typeof document < "u" && document.documentElement.classList.toggle("force-motion", e), D(e);
60
+ }
61
+ function A() {
62
+ return b() || C() && !E();
63
+ }
64
+ function j(e, t = 600) {
65
+ let [s, c] = r(0), l;
66
+ return n(() => {
67
+ let n = e();
68
+ if (l?.stop(), A()) {
69
+ c(n);
70
+ return;
71
+ }
72
+ let r = a(s);
73
+ r !== n && (l = o(r, n, {
74
+ duration: t / 1e3,
75
+ ease: "easeOut",
76
+ onUpdate: (e) => c(e)
77
+ }));
78
+ }), i(() => l?.stop()), s;
79
+ }
80
+ function M(e, t = {}) {
81
+ A() || o(e, {
82
+ opacity: [0, 1],
83
+ y: [t.y ?? 8, 0]
84
+ }, {
85
+ duration: t.duration ?? .32,
86
+ delay: t.delay ?? 0,
87
+ ease: "easeOut"
88
+ });
89
+ }
90
+ function N(e, t = {}) {
91
+ if (A()) return () => {};
92
+ e.style.opacity = "0";
93
+ let n = !1;
94
+ return s(e, () => {
95
+ n || (n = !0, o(e, {
96
+ opacity: [0, 1],
97
+ y: [t.y ?? 16, 0]
98
+ }, {
99
+ duration: t.duration ?? .5,
100
+ ease: "easeOut"
101
+ }));
102
+ }, { amount: t.amount ?? .2 });
103
+ }
104
+ export { A as a, c, u as d, O as f, d as g, y as h, s as i, k as l, x as m, M as n, C as o, b as p, j as r, N as s, o as t, l as u };
package/dist/styles.css CHANGED
@@ -254,10 +254,11 @@ body {
254
254
  }
255
255
 
256
256
  /* Drawer / Modal drawer-variant slide-over (Kobalte Dialog presence →
257
- animationend keyframes, keyed off data-expanded/data-closed like Modal). */
257
+ animationend keyframes, keyed off data-expanded/data-closed like Modal).
258
+ --drawer-offscreen is set per side by Drawer (default: off the right edge). */
258
259
  @keyframes drawer-in {
259
260
  from {
260
- transform: translateX(100%);
261
+ transform: var(--drawer-offscreen, translateX(100%));
261
262
  }
262
263
  to {
263
264
  transform: translateX(0);
@@ -268,7 +269,7 @@ body {
268
269
  transform: translateX(0);
269
270
  }
270
271
  to {
271
- transform: translateX(100%);
272
+ transform: var(--drawer-offscreen, translateX(100%));
272
273
  }
273
274
  }
274
275
  .drawer-content[data-expanded] {
@@ -293,6 +294,112 @@ body {
293
294
  }
294
295
  }
295
296
 
297
+ /* Questionnaire */
298
+ @keyframes questionnaire-step-in {
299
+ from {
300
+ opacity: 0;
301
+ transform: translateX(16px);
302
+ }
303
+ to {
304
+ opacity: 1;
305
+ transform: none;
306
+ }
307
+ }
308
+ @keyframes questionnaire-step-in-back {
309
+ from {
310
+ opacity: 0;
311
+ transform: translateX(-16px);
312
+ }
313
+ to {
314
+ opacity: 1;
315
+ transform: none;
316
+ }
317
+ }
318
+
319
+ /* NavigationMenu — Kobalte keys viewport/panel presence off animation names, so
320
+ these MUST be @keyframes. Panels slide in from the side of the previously
321
+ open one (data-motion) and are hidden once they have slid out. */
322
+ @keyframes navmenu-viewport-in {
323
+ from {
324
+ opacity: 0;
325
+ transform: translateY(-6px) scale(0.97);
326
+ }
327
+ to {
328
+ opacity: 1;
329
+ transform: none;
330
+ }
331
+ }
332
+ @keyframes navmenu-viewport-out {
333
+ from {
334
+ opacity: 1;
335
+ transform: none;
336
+ }
337
+ to {
338
+ opacity: 0;
339
+ transform: translateY(-6px) scale(0.97);
340
+ }
341
+ }
342
+ @keyframes navmenu-from-start {
343
+ from {
344
+ opacity: 0;
345
+ transform: translateX(-2.5rem);
346
+ }
347
+ to {
348
+ opacity: 1;
349
+ transform: none;
350
+ }
351
+ }
352
+ @keyframes navmenu-from-end {
353
+ from {
354
+ opacity: 0;
355
+ transform: translateX(2.5rem);
356
+ }
357
+ to {
358
+ opacity: 1;
359
+ transform: none;
360
+ }
361
+ }
362
+ @keyframes navmenu-to-start {
363
+ from {
364
+ opacity: 1;
365
+ visibility: visible;
366
+ }
367
+ to {
368
+ opacity: 0;
369
+ visibility: hidden;
370
+ transform: translateX(-2.5rem);
371
+ }
372
+ }
373
+ @keyframes navmenu-to-end {
374
+ from {
375
+ opacity: 1;
376
+ visibility: visible;
377
+ }
378
+ to {
379
+ opacity: 0;
380
+ visibility: hidden;
381
+ transform: translateX(2.5rem);
382
+ }
383
+ }
384
+ .navmenu-viewport[data-expanded] {
385
+ animation: navmenu-viewport-in 0.2s ease-out;
386
+ }
387
+ .navmenu-viewport[data-closed] {
388
+ animation: navmenu-viewport-out 0.15s ease-in;
389
+ }
390
+ .navmenu-content[data-motion='from-start'] {
391
+ animation: navmenu-from-start 0.25s ease-out;
392
+ }
393
+ .navmenu-content[data-motion='from-end'] {
394
+ animation: navmenu-from-end 0.25s ease-out;
395
+ }
396
+ .navmenu-content[data-motion='to-start'] {
397
+ animation: navmenu-to-start 0.25s ease-in forwards;
398
+ }
399
+ .navmenu-content[data-motion='to-end'] {
400
+ animation: navmenu-to-end 0.25s ease-in forwards;
401
+ }
402
+
296
403
  /* A4ui — starfield backdrop styles for <SpaceBackground/>.
297
404
  *
298
405
  * Extracted from the source project's space-theme.css. Mount SpaceBackground as
@@ -0,0 +1,19 @@
1
+ import { JSX, ParentProps } from 'solid-js';
2
+ interface AspectRatioProps extends ParentProps {
3
+ /** Width divided by height, e.g. `16 / 9`. @default 1 */
4
+ ratio?: number;
5
+ class?: string;
6
+ }
7
+ export type { AspectRatioProps };
8
+ /**
9
+ * Box that keeps a fixed width:height ratio (CSS `aspect-ratio`). Children fill
10
+ * it; give images/video `object-cover`.
11
+ *
12
+ * @example
13
+ * ```tsx
14
+ * <AspectRatio ratio={16 / 9} class="w-full overflow-hidden rounded-lg">
15
+ * <img src="/cover.jpg" alt="" class="object-cover" />
16
+ * </AspectRatio>
17
+ * ```
18
+ */
19
+ export declare function AspectRatio(props: AspectRatioProps): JSX.Element;
@@ -0,0 +1,70 @@
1
+ import { JSX, ParentProps } from 'solid-js';
2
+ import { ItemSize } from './Item';
3
+ export type AttachmentState = 'idle' | 'uploading' | 'processing' | 'error' | 'done';
4
+ export type AttachmentOrientation = 'horizontal' | 'vertical';
5
+ interface AttachmentProps extends ParentProps {
6
+ /** Lifecycle state. `uploading`/`processing` set `aria-busy`; `error` uses destructive tokens. @default 'idle' */
7
+ state?: AttachmentState;
8
+ /** Density, forwarded to `Item`. @default 'default' */
9
+ size?: ItemSize;
10
+ /** Lay media and text side by side, or stacked. @default 'horizontal' */
11
+ orientation?: AttachmentOrientation;
12
+ /**
13
+ * Upload progress, 0–100. Only used while `state="uploading"`; when omitted
14
+ * the bar is indeterminate (no `aria-valuenow`).
15
+ */
16
+ progress?: number;
17
+ /** Accessible name of the progress bar. @default 'Uploading' / 'Processing' */
18
+ progressLabel?: string;
19
+ class?: string;
20
+ }
21
+ export type { AttachmentProps };
22
+ /**
23
+ * A file or image attachment: `AttachmentMedia`, an `AttachmentContent` with
24
+ * title/description and trailing `AttachmentActions`. Group several in an
25
+ * `AttachmentGroup` (horizontal scroll-snap row).
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * <Attachment state="uploading" progress={42}>
30
+ * <AttachmentMedia><FileText /></AttachmentMedia>
31
+ * <AttachmentContent>
32
+ * <AttachmentTitle>roadmap.pdf</AttachmentTitle>
33
+ * <AttachmentDescription>42% of 2.4 MB</AttachmentDescription>
34
+ * </AttachmentContent>
35
+ * <AttachmentActions>
36
+ * <AttachmentAction label="Cancel upload"><X /></AttachmentAction>
37
+ * </AttachmentActions>
38
+ * </Attachment>
39
+ * ```
40
+ */
41
+ export declare function Attachment(props: AttachmentProps): JSX.Element;
42
+ interface SlotProps extends ParentProps {
43
+ class?: string;
44
+ }
45
+ /** Leading visual: an icon tile (`icon`, default) or an image thumbnail (`image`). */
46
+ export declare function AttachmentMedia(props: SlotProps & {
47
+ variant?: 'icon' | 'image';
48
+ }): JSX.Element;
49
+ /** The text column. */
50
+ export declare function AttachmentContent(props: SlotProps): JSX.Element;
51
+ /** File name; truncates on one line. */
52
+ export declare function AttachmentTitle(props: SlotProps): JSX.Element;
53
+ /** Secondary line: size, status or error message. */
54
+ export declare function AttachmentDescription(props: SlotProps): JSX.Element;
55
+ /** Trailing controls. */
56
+ export declare function AttachmentActions(props: SlotProps): JSX.Element;
57
+ interface AttachmentActionProps extends ParentProps {
58
+ /** Accessible name (required: the button only holds an icon). */
59
+ label: string;
60
+ onClick?: (event: MouseEvent) => void;
61
+ disabled?: boolean;
62
+ class?: string;
63
+ }
64
+ export type { AttachmentActionProps };
65
+ /** Icon button inside `AttachmentActions`. */
66
+ export declare function AttachmentAction(props: AttachmentActionProps): JSX.Element;
67
+ /** Horizontal scroll-snap row of attachments. */
68
+ export declare function AttachmentGroup(props: SlotProps & {
69
+ label?: string;
70
+ }): JSX.Element;
@@ -0,0 +1,37 @@
1
+ import { JSX, ParentProps } from 'solid-js';
2
+ export type ButtonGroupOrientation = 'horizontal' | 'vertical';
3
+ interface ButtonGroupProps extends ParentProps {
4
+ /** Layout direction. @default 'horizontal' */
5
+ orientation?: ButtonGroupOrientation;
6
+ /** Accessible name for the group (recommended). */
7
+ 'aria-label'?: string;
8
+ class?: string;
9
+ }
10
+ export type { ButtonGroupProps };
11
+ /**
12
+ * Groups buttons so they share borders; only the outer corners stay rounded.
13
+ * Renders `role="group"` — pass `aria-label` so it has a name. Children can be
14
+ * `Button`s, links, a `Dropdown` trigger, `ButtonGroupText` or
15
+ * `ButtonGroupSeparator`.
16
+ *
17
+ * @example
18
+ * ```tsx
19
+ * <ButtonGroup aria-label="Text alignment">
20
+ * <Button variant="outline">Left</Button>
21
+ * <Button variant="outline">Center</Button>
22
+ * <Button variant="outline">Right</Button>
23
+ * </ButtonGroup>
24
+ * ```
25
+ */
26
+ export declare function ButtonGroup(props: ButtonGroupProps): JSX.Element;
27
+ interface ButtonGroupTextProps extends ParentProps {
28
+ class?: string;
29
+ }
30
+ /** Non-interactive label cell that sits inside a {@link ButtonGroup}. */
31
+ export declare function ButtonGroupText(props: ButtonGroupTextProps): JSX.Element;
32
+ interface ButtonGroupSeparatorProps {
33
+ class?: string;
34
+ }
35
+ /** Thin divider between buttons that have no border of their own (e.g. primary). */
36
+ export declare function ButtonGroupSeparator(props: ButtonGroupSeparatorProps): JSX.Element;
37
+ export type { ButtonGroupTextProps, ButtonGroupSeparatorProps };
@@ -0,0 +1,20 @@
1
+ import { JSX, ParentProps } from 'solid-js';
2
+ export type ChatMarkerVariant = 'default' | 'border' | 'separator';
3
+ interface ChatMarkerProps extends ParentProps {
4
+ /** `default`: muted text. `border`: bordered pill. `separator`: text between two lines. @default 'default' */
5
+ variant?: ChatMarkerVariant;
6
+ /** Optional leading icon; decorative (`aria-hidden`). */
7
+ icon?: JSX.Element;
8
+ class?: string;
9
+ }
10
+ export type { ChatMarkerProps };
11
+ /**
12
+ * Inline system note in a thread, e.g. a date divider or a status change.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * <ChatMarker variant="separator">Yesterday</ChatMarker>
17
+ * <ChatMarker variant="border" icon={<UserPlus />}>Nova joined</ChatMarker>
18
+ * ```
19
+ */
20
+ export declare function ChatMarker(props: ChatMarkerProps): JSX.Element;
@@ -1,24 +1,48 @@
1
1
  import { JSX } from 'solid-js';
2
+ /** Imperative handle handed out through {@link ChatThreadProps.apiRef}. */
3
+ export interface ChatThreadApi {
4
+ /** Scroll the element carrying `data-message-id={id}` to the top of the view. Throws if there is none. */
5
+ scrollToMessage: (id: string, options?: {
6
+ behavior?: ScrollBehavior;
7
+ }) => void;
8
+ /** Scroll to the newest content and re-pin the thread to the bottom. */
9
+ scrollToEnd: (options?: {
10
+ behavior?: ScrollBehavior;
11
+ }) => void;
12
+ }
2
13
  export interface ChatThreadProps {
3
14
  children: JSX.Element;
4
15
  /** Max width of the reading column, in px. Defaults to `768`. */
5
16
  maxWidth?: number;
6
- /** Auto-scroll to the newest message on mount and whenever children change. Defaults to `true`. */
17
+ /**
18
+ * Follow new content (appended messages and streamed text) to the bottom,
19
+ * but only while the reader is already at the bottom. Defaults to `true`.
20
+ */
7
21
  stickToBottom?: boolean;
22
+ /** Receives the imperative API once on mount. */
23
+ apiRef?: (api: ChatThreadApi) => void;
24
+ /** Label of the button shown when new content arrives off-screen. Defaults to `'Jump to latest'`. */
25
+ jumpLabel?: string;
8
26
  class?: string;
9
27
  }
10
28
  /**
11
- * Scrollable, centered reading column that stacks chat messages. Layout-only:
12
- * it renders whatever is passed as `children`, so pair it with your own
13
- * message bubbles/components.
29
+ * Scrollable, centered reading column that stacks chat messages. Give message
30
+ * elements a `data-message-id` (`<Message id="…">` does) to target them with
31
+ * `apiRef`'s `scrollToMessage`.
32
+ *
33
+ * - Appended or streamed content scrolls into view only while the reader is
34
+ * pinned to the bottom; otherwise the view stays put and a **Jump to latest**
35
+ * button appears.
36
+ * - Prepending older messages keeps the visible messages where they were.
14
37
  *
15
38
  * @example
16
39
  * ```tsx
17
- * <ChatThread maxWidth={640}>
18
- * <div>Hi! Ask me anything about your itinerary.</div>
19
- * <div>What's the weather like in Rivertown this weekend?</div>
20
- * <div>Sunny and mild, 18–22°C, light breeze on Saturday.</div>
40
+ * let api!: ChatThreadApi
41
+ * <ChatThread maxWidth={640} apiRef={(a) => (api = a)} class="h-96">
42
+ * <Message id="m1" role="user">What changed in v2?</Message>
43
+ * <Message id="m2" role="assistant">Three things…</Message>
21
44
  * </ChatThread>
45
+ * // later: api.scrollToMessage('m1')
22
46
  * ```
23
47
  */
24
48
  export declare function ChatThread(props: ChatThreadProps): JSX.Element;
@@ -0,0 +1,49 @@
1
+ import { JSX } from 'solid-js';
2
+ /** A field {@link ContactSection} can render. */
3
+ export type ContactField = 'name' | 'email' | 'phone' | 'subject' | 'message';
4
+ /** Submitted values, keyed by field. Only the rendered fields are present. */
5
+ export type ContactValues = Partial<Record<ContactField, string>>;
6
+ export interface ContactSectionProps {
7
+ title?: string;
8
+ subtitle?: string;
9
+ /** Fields to render, in order. Defaults to `['name', 'email', 'message']`. */
10
+ fields?: ContactField[];
11
+ /** Override field and contact-detail labels, e.g. for another language. */
12
+ labels?: Partial<Record<ContactField | 'address', string>>;
13
+ /** Submit button text. Defaults to `'Send message'`. */
14
+ submitLabel?: string;
15
+ /**
16
+ * Where the form posts (`method="post"`): an endpoint URL, or a `mailto:` link
17
+ * (sent as plain text). Omit it to handle submission yourself with `onSubmit`.
18
+ */
19
+ action?: string;
20
+ /** Called with the values when the form submits and there is no `action`. */
21
+ onSubmit?: (values: ContactValues) => void;
22
+ /** Email shown (and linked) beside the form. */
23
+ email?: string;
24
+ /** Phone number shown (and linked) beside the form. */
25
+ phone?: string;
26
+ /** Postal address shown beside the form. */
27
+ address?: string;
28
+ /** Anchor id for in-page navigation. */
29
+ id?: string;
30
+ class?: string;
31
+ }
32
+ /**
33
+ * Contact section: a form (any of name, email, phone, subject, message) beside
34
+ * the business's email, phone and address. With `action` the form posts
35
+ * natively to that URL or `mailto:` link; without it, `onSubmit` receives the
36
+ * values. Name, email and message are required.
37
+ *
38
+ * @example
39
+ * ```tsx
40
+ * <ContactSection
41
+ * title="Talk to us"
42
+ * fields={['name', 'email', 'subject', 'message']}
43
+ * action="https://formspree.io/f/your-id"
44
+ * email="hello@example.com"
45
+ * phone="+52 55 1234 5678"
46
+ * />
47
+ * ```
48
+ */
49
+ export declare function ContactSection(props: ContactSectionProps): JSX.Element;
@@ -0,0 +1,28 @@
1
+ import { JSX } from 'solid-js';
2
+ import { SectionLink } from './internal/sectionKit';
3
+ export interface CtaBannerProps {
4
+ title: string;
5
+ subtitle?: string;
6
+ /** Main call-to-action (filled button). */
7
+ primary: SectionLink;
8
+ /** Secondary call-to-action (outline button). */
9
+ secondary?: SectionLink;
10
+ /** Anchor id for in-page navigation. */
11
+ id?: string;
12
+ class?: string;
13
+ }
14
+ /**
15
+ * Call-to-action band that closes a page or splits long ones: a headline, an
16
+ * optional line of support and one or two buttons on a glass panel tinted with
17
+ * the theme's primary color.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * <CtaBanner
22
+ * title="Ready to launch?"
23
+ * subtitle="Start free, upgrade when you grow."
24
+ * primary={{ label: 'Create account', href: '/signup' }}
25
+ * />
26
+ * ```
27
+ */
28
+ export declare function CtaBanner(props: CtaBannerProps): JSX.Element;
@@ -9,9 +9,13 @@ interface DrawerProps extends ParentProps {
9
9
  class?: string;
10
10
  /** Accessible label for the close button. @default 'Close' */
11
11
  closeLabel?: string;
12
+ /** Edge the panel is anchored to and slides in from. @default 'right' */
13
+ side?: DrawerSide;
12
14
  }
15
+ export type DrawerSide = 'right' | 'left' | 'top' | 'bottom';
16
+ export type { DrawerProps };
13
17
  /**
14
- * Right-anchored slide-over panel built on Kobalte's `Dialog` (focus trap, portal,
18
+ * Edge-anchored slide-over panel (right by default, or `side="left" | "top" | "bottom"`) built on Kobalte's `Dialog` (focus trap, portal,
15
19
  * and open/close presence handled for you). Use for create/edit forms or detail
16
20
  * panels that need more room than a centered `Modal`.
17
21
  *
@@ -24,4 +28,3 @@ interface DrawerProps extends ParentProps {
24
28
  * ```
25
29
  */
26
30
  export declare function Drawer(props: DrawerProps): JSX.Element;
27
- export {};
@@ -0,0 +1,29 @@
1
+ import { JSX } from 'solid-js';
2
+ /** One question/answer pair rendered by {@link Faq}. */
3
+ export interface FaqItem {
4
+ question: string;
5
+ answer: string;
6
+ }
7
+ export interface FaqProps {
8
+ title?: string;
9
+ subtitle?: string;
10
+ items: FaqItem[];
11
+ /** Allow several answers open at once. Defaults to `false`. */
12
+ multiple?: boolean;
13
+ /** Anchor id for in-page navigation. */
14
+ id?: string;
15
+ class?: string;
16
+ }
17
+ /**
18
+ * Frequently-asked-questions section: an optional heading over an
19
+ * {@link Accordion} of questions on a glass panel; each answer expands in place.
20
+ *
21
+ * @example
22
+ * ```tsx
23
+ * <Faq
24
+ * title="Questions"
25
+ * items={[{ question: 'Can I cancel anytime?', answer: 'Yes, from your account settings.' }]}
26
+ * />
27
+ * ```
28
+ */
29
+ export declare function Faq(props: FaqProps): JSX.Element;
@@ -0,0 +1,35 @@
1
+ import { JSX } from 'solid-js';
2
+ /** One feature rendered by {@link FeatureGrid}. */
3
+ export interface FeatureItem {
4
+ title: string;
5
+ text: string;
6
+ /** Optional icon node, shown in a tinted tile above the title. */
7
+ icon?: JSX.Element;
8
+ }
9
+ export interface FeatureGridProps {
10
+ title?: string;
11
+ subtitle?: string;
12
+ items: FeatureItem[];
13
+ /** Columns on wide screens (one column on phones). Defaults to `3`. */
14
+ columns?: 2 | 3 | 4;
15
+ /** Anchor id for in-page navigation. */
16
+ id?: string;
17
+ class?: string;
18
+ }
19
+ /**
20
+ * Section listing a product's features: an optional heading and a responsive
21
+ * grid of glass cards, each with an optional icon, a title and a short text.
22
+ *
23
+ * @example
24
+ * ```tsx
25
+ * <FeatureGrid
26
+ * title="Why teams switch"
27
+ * items={[
28
+ * { title: 'Fast', text: 'Pages load in under a second.' },
29
+ * { title: 'Accessible', text: 'Keyboard and screen-reader friendly.' },
30
+ * { title: 'Themeable', text: 'Swap palettes without touching CSS.' },
31
+ * ]}
32
+ * />
33
+ * ```
34
+ */
35
+ export declare function FeatureGrid(props: FeatureGridProps): JSX.Element;