cherry-styled-components 0.2.12 → 0.2.13

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.
@@ -0,0 +1,234 @@
1
+ "use client";
2
+ "use client";
3
+ import { Avatar } from "./avatar.js";
4
+ import { Callout } from "./callout.js";
5
+ import { ChatSource, ChatSources } from "./chat-sources.js";
6
+ import { ChatTyping } from "./chat-typing.js";
7
+ import { Prose } from "./prose.js";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ import React from "react";
10
+ import styled from "styled-components";
11
+ //#region src/lib/chat-showcase.tsx
12
+ var StyledStack = styled.div.withConfig({
13
+ displayName: "chat-showcase__StyledStack",
14
+ componentId: "sc-37301b14-0"
15
+ })([`display:flex;flex-direction:column;gap:12px;width:100%;`]);
16
+ var StyledRow = styled.div.withConfig({
17
+ displayName: "chat-showcase__StyledRow",
18
+ componentId: "sc-37301b14-1"
19
+ })([`display:flex;align-items:center;gap:12px;flex-wrap:wrap;`]);
20
+ var CATALOG = [
21
+ {
22
+ group: "Form",
23
+ components: [
24
+ "Button",
25
+ "IconButton",
26
+ "Input (Checkbox / Radio via type)",
27
+ "Select",
28
+ "Textarea",
29
+ "Toggle",
30
+ "Range",
31
+ "Password",
32
+ "Dropzone",
33
+ "AvatarDropzone"
34
+ ]
35
+ },
36
+ {
37
+ group: "Layout",
38
+ components: [
39
+ "Container",
40
+ "Grid",
41
+ "Col",
42
+ "Flex",
43
+ "Box",
44
+ "MaxWidth",
45
+ "Space"
46
+ ]
47
+ },
48
+ {
49
+ group: "Interactive",
50
+ components: [
51
+ "Accordion",
52
+ "Tabs",
53
+ "Modal",
54
+ "Toast",
55
+ "ThemeToggle",
56
+ "Icon"
57
+ ]
58
+ },
59
+ {
60
+ group: "Content",
61
+ components: [
62
+ "Prose",
63
+ "Callout",
64
+ "Avatar"
65
+ ]
66
+ },
67
+ {
68
+ group: "Chat",
69
+ components: [
70
+ "ChatProvider",
71
+ "ChatPanel",
72
+ "ChatMessageList",
73
+ "ChatMessage",
74
+ "ChatInput",
75
+ "ChatLauncher",
76
+ "ChatTyping",
77
+ "ChatSources"
78
+ ]
79
+ }
80
+ ];
81
+ function HelpReply() {
82
+ return /*#__PURE__*/ jsxs(Prose, {
83
+ $compact: true,
84
+ children: [/*#__PURE__*/ jsx("p", { children: "Here is what I can render:" }), /*#__PURE__*/ jsx("ul", { children: showcaseCommands.map((command) => /*#__PURE__*/ jsxs("li", { children: [
85
+ /*#__PURE__*/ jsx("code", { children: command.name }),
86
+ " — ",
87
+ command.description
88
+ ] }, command.name)) })]
89
+ });
90
+ }
91
+ function ListReply() {
92
+ return /*#__PURE__*/ jsxs(Prose, {
93
+ $compact: true,
94
+ children: [/*#__PURE__*/ jsx("p", { children: "The Cherry component catalog:" }), CATALOG.map(({ group, components }) => /*#__PURE__*/ jsxs(React.Fragment, { children: [/*#__PURE__*/ jsx("h6", { children: group }), /*#__PURE__*/ jsx("ul", { children: components.map((component) => /*#__PURE__*/ jsx("li", { children: component }, component)) })] }, group))]
95
+ });
96
+ }
97
+ function CalloutReply() {
98
+ return /*#__PURE__*/ jsxs(StyledStack, { children: [
99
+ /*#__PURE__*/ jsx(Callout, {
100
+ $type: "note",
101
+ children: /*#__PURE__*/ jsx("p", { children: "A note callout for supplementary details." })
102
+ }),
103
+ /*#__PURE__*/ jsx(Callout, {
104
+ $type: "info",
105
+ children: /*#__PURE__*/ jsx("p", { children: "An info callout for neutral information." })
106
+ }),
107
+ /*#__PURE__*/ jsx(Callout, {
108
+ $type: "warning",
109
+ children: /*#__PURE__*/ jsx("p", { children: "A warning callout for things to watch out for." })
110
+ }),
111
+ /*#__PURE__*/ jsx(Callout, {
112
+ $type: "danger",
113
+ children: /*#__PURE__*/ jsx("p", { children: "A danger callout for destructive outcomes." })
114
+ }),
115
+ /*#__PURE__*/ jsx(Callout, {
116
+ $type: "success",
117
+ children: /*#__PURE__*/ jsx("p", { children: "A success callout for confirmations." })
118
+ })
119
+ ] });
120
+ }
121
+ function AvatarReply() {
122
+ return /*#__PURE__*/ jsxs(StyledRow, { children: [
123
+ /*#__PURE__*/ jsx(Avatar, {
124
+ $size: "small",
125
+ $name: "Ada Lovelace"
126
+ }),
127
+ /*#__PURE__*/ jsx(Avatar, {
128
+ $name: "Cherry",
129
+ $color: "secondary"
130
+ }),
131
+ /*#__PURE__*/ jsx(Avatar, {
132
+ $size: "big",
133
+ $color: "tertiary",
134
+ $alt: "Assistant"
135
+ })
136
+ ] });
137
+ }
138
+ function ProseReply() {
139
+ return /*#__PURE__*/ jsxs(Prose, {
140
+ $compact: true,
141
+ children: [
142
+ /*#__PURE__*/ jsx("h5", { children: "Rendered markdown" }),
143
+ /*#__PURE__*/ jsxs("p", { children: [
144
+ "Prose styles ",
145
+ /*#__PURE__*/ jsx("a", {
146
+ href: "#",
147
+ children: "links"
148
+ }),
149
+ ", lists, tables and",
150
+ " ",
151
+ /*#__PURE__*/ jsx("code", { children: "inline code" }),
152
+ " with Cherry typography."
153
+ ] }),
154
+ /*#__PURE__*/ jsxs("ul", { children: [/*#__PURE__*/ jsx("li", { children: "First item" }), /*#__PURE__*/ jsx("li", { children: "Second item" })] }),
155
+ /*#__PURE__*/ jsx("div", {
156
+ className: "table-wrapper",
157
+ children: /*#__PURE__*/ jsxs("table", { children: [/*#__PURE__*/ jsx("thead", { children: /*#__PURE__*/ jsxs("tr", { children: [/*#__PURE__*/ jsx("th", { children: "Prop" }), /*#__PURE__*/ jsx("th", { children: "Default" })] }) }), /*#__PURE__*/ jsx("tbody", { children: /*#__PURE__*/ jsxs("tr", { children: [/*#__PURE__*/ jsx("td", { children: "$compact" }), /*#__PURE__*/ jsx("td", { children: "false" })] }) })] })
158
+ })
159
+ ]
160
+ });
161
+ }
162
+ function SourcesReply() {
163
+ return /*#__PURE__*/ jsxs(StyledStack, { children: [/*#__PURE__*/ jsx(Prose, {
164
+ $compact: true,
165
+ children: /*#__PURE__*/ jsx("p", { children: "Source chips link an answer back to where it came from:" })
166
+ }), /*#__PURE__*/ jsxs(ChatSources, { children: [
167
+ /*#__PURE__*/ jsx(ChatSource, {
168
+ href: "#",
169
+ children: "Getting Started"
170
+ }),
171
+ /*#__PURE__*/ jsx(ChatSource, {
172
+ href: "#",
173
+ children: "Theming"
174
+ }),
175
+ /*#__PURE__*/ jsx(ChatSource, {
176
+ href: "#",
177
+ children: "Chat Kit"
178
+ })
179
+ ] })] });
180
+ }
181
+ function TypingReply() {
182
+ return /*#__PURE__*/ jsxs(StyledStack, { children: [/*#__PURE__*/ jsx(Prose, {
183
+ $compact: true,
184
+ children: /*#__PURE__*/ jsx("p", { children: "The typing indicator shown while a reply is on its way:" })
185
+ }), /*#__PURE__*/ jsx(ChatTyping, {})] });
186
+ }
187
+ var showcaseCommands = [
188
+ {
189
+ name: "help",
190
+ description: "list these commands",
191
+ render: () => /*#__PURE__*/ jsx(HelpReply, {})
192
+ },
193
+ {
194
+ name: "list",
195
+ description: "the full Cherry component catalog",
196
+ render: () => /*#__PURE__*/ jsx(ListReply, {})
197
+ },
198
+ {
199
+ name: "callout",
200
+ description: "the five callout intents",
201
+ render: () => /*#__PURE__*/ jsx(CalloutReply, {})
202
+ },
203
+ {
204
+ name: "avatar",
205
+ description: "avatars with initials and icon fallbacks",
206
+ render: () => /*#__PURE__*/ jsx(AvatarReply, {})
207
+ },
208
+ {
209
+ name: "prose",
210
+ description: "markdown-style content with Cherry typography",
211
+ render: () => /*#__PURE__*/ jsx(ProseReply, {})
212
+ },
213
+ {
214
+ name: "sources",
215
+ description: "the source-chip row",
216
+ render: () => /*#__PURE__*/ jsx(SourcesReply, {})
217
+ },
218
+ {
219
+ name: "typing",
220
+ description: "the three-dot typing indicator",
221
+ render: () => /*#__PURE__*/ jsx(TypingReply, {})
222
+ }
223
+ ];
224
+ /**
225
+ * Matches a chat question against the showcase commands ("help", "/help" and
226
+ * any casing all work) and returns the rendered demo, or null when the input
227
+ * is not a command and should go to the transport.
228
+ */ function resolveShowcaseCommand(input) {
229
+ const name = input.trim().toLowerCase().replace(/^\//, "");
230
+ const command = showcaseCommands.find((entry) => entry.name === name);
231
+ return command ? command.render() : null;
232
+ }
233
+ //#endregion
234
+ export { resolveShowcaseCommand, showcaseCommands };
@@ -0,0 +1,10 @@
1
+ import { default as React } from 'react';
2
+ export interface ChatSourcesProps extends React.HTMLAttributes<HTMLDivElement> {
3
+ children: React.ReactNode;
4
+ }
5
+ export interface ChatSourceProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
6
+ children: React.ReactNode;
7
+ }
8
+ declare const ChatSources: React.ForwardRefExoticComponent<ChatSourcesProps & React.RefAttributes<HTMLDivElement>>;
9
+ declare const ChatSource: React.ForwardRefExoticComponent<ChatSourceProps & React.RefAttributes<HTMLAnchorElement>>;
10
+ export { ChatSource, ChatSources };
@@ -0,0 +1,41 @@
1
+ "use client";
2
+ "use client";
3
+ import { alpha, interactiveStyles } from "./utils/mixins.js";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { forwardRef } from "react";
6
+ import styled from "styled-components";
7
+ //#region src/lib/chat-sources.tsx
8
+ var StyledChatSources = styled.div.withConfig({
9
+ displayName: "chat-sources__StyledChatSources",
10
+ componentId: "sc-7fa69b52-0"
11
+ })([`display:flex;gap:16px;flex-wrap:wrap;`]);
12
+ var StyledChatSource = styled.a.withConfig({
13
+ displayName: "chat-sources__StyledChatSource",
14
+ componentId: "sc-7fa69b52-1"
15
+ })([
16
+ `position:relative;text-decoration:none;font-size:`,
17
+ `;line-height:1;color:`,
18
+ `;display:flex;align-items:center;gap:6px;transition:all 0.3s ease;font-weight:600;white-space:nowrap;min-width:fit-content;background:`,
19
+ `;padding:6px 8px;border-radius:`,
20
+ `;`,
21
+ `;& svg{width:14px;height:14px;flex-shrink:0;}&:hover{color:`,
22
+ `;}`
23
+ ], ({ theme }) => theme.fontSizes.small.lg, ({ theme }) => theme.colors.primary, ({ theme }) => alpha(theme.colors.primaryLight, 10), ({ theme }) => theme.spacing.radius.xs, interactiveStyles, ({ theme }) => theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark);
24
+ function LocalChatSources({ children, ...props }, ref) {
25
+ return /*#__PURE__*/ jsx(StyledChatSources, {
26
+ ...props,
27
+ ref,
28
+ children
29
+ });
30
+ }
31
+ function LocalChatSource({ children, ...props }, ref) {
32
+ return /*#__PURE__*/ jsx(StyledChatSource, {
33
+ ...props,
34
+ ref,
35
+ children
36
+ });
37
+ }
38
+ var ChatSources = /*#__PURE__*/ forwardRef(LocalChatSources);
39
+ var ChatSource = /*#__PURE__*/ forwardRef(LocalChatSource);
40
+ //#endregion
41
+ export { ChatSource, ChatSources };
@@ -0,0 +1,7 @@
1
+ import { default as React } from 'react';
2
+ export interface ChatTypingProps extends React.HTMLAttributes<HTMLDivElement> {
3
+ /** The label before the dots. */
4
+ children?: React.ReactNode;
5
+ }
6
+ declare const ChatTyping: React.ForwardRefExoticComponent<ChatTypingProps & React.RefAttributes<HTMLDivElement>>;
7
+ export { ChatTyping };
@@ -0,0 +1,44 @@
1
+ "use client";
2
+ "use client";
3
+ import { chatTextStyles } from "./chat-message.js";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { forwardRef } from "react";
6
+ import styled, { keyframes } from "styled-components";
7
+ //#region src/lib/chat-typing.tsx
8
+ var dotFade = keyframes([`0%{opacity:0;}50%{opacity:1;}100%{opacity:0;}`]);
9
+ var StyledChatTyping = styled.div.withConfig({
10
+ displayName: "chat-typing__StyledChatTyping",
11
+ componentId: "sc-ef02cd3b-0"
12
+ })([
13
+ `width:100%;font-weight:600;color:`,
14
+ `;`,
15
+ `;& .chat-typing-dot{animation:`,
16
+ ` 1s ease infinite;&:nth-child(2){animation-delay:0.2s;}&:nth-child(3){animation-delay:0.4s;}}@media (prefers-reduced-motion:reduce){& .chat-typing-dot{animation:none;}}`
17
+ ], ({ theme }) => theme.colors.dark, ({ theme }) => chatTextStyles(theme), dotFade);
18
+ function LocalChatTyping({ children = "Answering", ...props }, ref) {
19
+ return /*#__PURE__*/ jsxs(StyledChatTyping, {
20
+ role: "status",
21
+ ...props,
22
+ ref,
23
+ children: [children, /*#__PURE__*/ jsxs("span", {
24
+ "aria-hidden": "true",
25
+ children: [
26
+ /*#__PURE__*/ jsx("span", {
27
+ className: "chat-typing-dot",
28
+ children: "."
29
+ }),
30
+ /*#__PURE__*/ jsx("span", {
31
+ className: "chat-typing-dot",
32
+ children: "."
33
+ }),
34
+ /*#__PURE__*/ jsx("span", {
35
+ className: "chat-typing-dot",
36
+ children: "."
37
+ })
38
+ ]
39
+ })]
40
+ });
41
+ }
42
+ var ChatTyping = /*#__PURE__*/ forwardRef(LocalChatTyping);
43
+ //#endregion
44
+ export { ChatTyping };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,20 @@
1
1
  export * from './styled-components';
2
2
  export * from './utils';
3
3
  export * from './accordion';
4
+ export * from './avatar';
4
5
  export * from './avatar-dropzone';
5
6
  export * from './box';
6
7
  export * from './button';
8
+ export * from './callout';
9
+ export * from './chat-input';
10
+ export * from './chat-launcher';
11
+ export * from './chat-message';
12
+ export * from './chat-message-list';
13
+ export * from './chat-panel';
14
+ export * from './chat-provider';
15
+ export * from './chat-showcase';
16
+ export * from './chat-sources';
17
+ export * from './chat-typing';
7
18
  export * from './col';
8
19
  export * from './container';
9
20
  export * from './dropzone';
@@ -15,9 +26,11 @@ export * from './input';
15
26
  export * from './max-width';
16
27
  export * from './modal';
17
28
  export * from './password';
29
+ export * from './prose';
18
30
  export * from './range';
19
31
  export * from './select';
20
32
  export * from './space';
33
+ export * from './spinner';
21
34
  export * from './tabs';
22
35
  export * from './textarea';
23
36
  export * from './theme-toggle';
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import { GlobalStyles } from "./utils/global.js";
2
2
  import { breakpoints, colors, colorsDark, fontSizes, fonts, lineHeights, mq, shadows, shadowsDark, spacing, theme, themeDark } from "./utils/theme.js";
3
- import { alpha, errorInteractiveStyles, formElementHeightStyles, fullWidthStyles, generateAlignContentStyles, generateAlignItemsStyles, generateColSpanStyles, generateColsStyles, generateDirectionStyles, generateGapStyles, generateJustifyContentStyles, generatePaddingStyles, interactiveStyles, resetButton, resetInput, shade, statusBorderStyles, tint } from "./utils/mixins.js";
3
+ import { alpha, darkFilledTextRule, errorInteractiveStyles, filledTextColor, formElementHeightStyles, fullWidthStyles, generateAlignContentStyles, generateAlignItemsStyles, generateColSpanStyles, generateColsStyles, generateDirectionStyles, generateGapStyles, generateJustifyContentStyles, generatePaddingStyles, interactiveStyles, resetButton, resetInput, shade, statusBorderStyles, thinScrollbar, tint } from "./utils/mixins.js";
4
4
  import { createTypographyStyle, styledBlockquote, styledButton, styledButtonBig, styledCode, styledH1, styledH2, styledH3, styledH4, styledH5, styledH6, styledHero1, styledHero2, styledHero3, styledInput, styledInputBig, styledSmall, styledStrong, styledText } from "./utils/typography.js";
5
+ import { useLockBodyScroll } from "./utils/use-lock-body-scroll.js";
6
+ import { useBelowBreakpoint, useMediaQuery } from "./utils/use-media-query.js";
5
7
  import { useOnClickOutside } from "./utils/use-on-click-outside.js";
6
8
  import { CherryThemeProvider, ThemeContext } from "./styled-components/theme-provider.js";
7
9
  import { ClientThemeProvider } from "./styled-components/client-theme-provider.js";
@@ -9,15 +11,28 @@ import { StyledComponentsRegistry } from "./styled-components/registry.js";
9
11
  import { createThemeInitScript, resolveTheme, themeInitScript } from "./styled-components/theme-init.js";
10
12
  import { Icon } from "./icon.js";
11
13
  import { Accordion } from "./accordion.js";
14
+ import { Avatar } from "./avatar.js";
12
15
  import { Dropzone, matchesAccept } from "./dropzone.js";
13
16
  import { AvatarDropzone } from "./avatar-dropzone.js";
14
17
  import { Container } from "./container.js";
15
18
  import { Box } from "./box.js";
16
19
  import { Button, buttonStyles } from "./button.js";
20
+ import { Callout } from "./callout.js";
21
+ import { ChatSource, ChatSources } from "./chat-sources.js";
22
+ import { ChatMessage, chatTextStyles } from "./chat-message.js";
23
+ import { ChatTyping } from "./chat-typing.js";
24
+ import { Prose, proseStyles } from "./prose.js";
25
+ import { resolveShowcaseCommand, showcaseCommands } from "./chat-showcase.js";
26
+ import { ChatContext, ChatProvider, useChat } from "./chat-provider.js";
27
+ import { Spinner } from "./spinner.js";
28
+ import { ChatInput } from "./chat-input.js";
29
+ import { ChatLauncher } from "./chat-launcher.js";
30
+ import { ChatMessageList } from "./chat-message-list.js";
31
+ import { IconButton, iconButtonStyles } from "./icon-button.js";
32
+ import { ChatPanel } from "./chat-panel.js";
17
33
  import { Col } from "./col.js";
18
34
  import { Flex } from "./flex.js";
19
35
  import { Grid } from "./grid.js";
20
- import { IconButton, iconButtonStyles } from "./icon-button.js";
21
36
  import { Input, StyledInputWrapper, StyledLabel } from "./input.js";
22
37
  import { MaxWidth } from "./max-width.js";
23
38
  import { Modal } from "./modal.js";
@@ -30,4 +45,4 @@ import { Textarea } from "./textarea.js";
30
45
  import { ThemeToggle } from "./theme-toggle.js";
31
46
  import { StyledNotificationItem, StyledNotifications, ToastNotifications, ToastNotificationsContext, ToastNotificationsProvider, useToastNotifications } from "./toast.js";
32
47
  import { Toggle } from "./toggle.js";
33
- export { Accordion, AvatarDropzone, Box, Button, CherryThemeProvider, ClientThemeProvider, Col, Container, Dropzone, Flex, GlobalStyles, Grid, Icon, IconButton, Input, MaxWidth, Modal, Password, Range, Select, Space, StyledComponentsRegistry, StyledIconWrapper, StyledInputWrapper, StyledLabel, StyledNotificationItem, StyledNotifications, TabContent, Tabs, Textarea, ThemeContext, ThemeToggle, ToastNotifications, ToastNotificationsContext, ToastNotificationsProvider, Toggle, alpha, breakpoints, buttonStyles, colors, colorsDark, createThemeInitScript, createTypographyStyle, errorInteractiveStyles, fontSizes, fonts, formElementHeightStyles, fullWidthStyles, generateAlignContentStyles, generateAlignItemsStyles, generateColSpanStyles, generateColsStyles, generateDirectionStyles, generateGapStyles, generateJustifyContentStyles, generatePaddingStyles, iconButtonStyles, interactiveStyles, lineHeights, matchesAccept, mq, resetButton, resetInput, resolveTheme, shade, shadows, shadowsDark, spacing, statusBorderStyles, styledBlockquote, styledButton, styledButtonBig, styledCode, styledH1, styledH2, styledH3, styledH4, styledH5, styledH6, styledHero1, styledHero2, styledHero3, styledInput, styledInputBig, styledSmall, styledStrong, styledText, theme, themeDark, themeInitScript, tint, useOnClickOutside, useToastNotifications };
48
+ export { Accordion, Avatar, AvatarDropzone, Box, Button, Callout, ChatContext, ChatInput, ChatLauncher, ChatMessage, ChatMessageList, ChatPanel, ChatProvider, ChatSource, ChatSources, ChatTyping, CherryThemeProvider, ClientThemeProvider, Col, Container, Dropzone, Flex, GlobalStyles, Grid, Icon, IconButton, Input, MaxWidth, Modal, Password, Prose, Range, Select, Space, Spinner, StyledComponentsRegistry, StyledIconWrapper, StyledInputWrapper, StyledLabel, StyledNotificationItem, StyledNotifications, TabContent, Tabs, Textarea, ThemeContext, ThemeToggle, ToastNotifications, ToastNotificationsContext, ToastNotificationsProvider, Toggle, alpha, breakpoints, buttonStyles, chatTextStyles, colors, colorsDark, createThemeInitScript, createTypographyStyle, darkFilledTextRule, errorInteractiveStyles, filledTextColor, fontSizes, fonts, formElementHeightStyles, fullWidthStyles, generateAlignContentStyles, generateAlignItemsStyles, generateColSpanStyles, generateColsStyles, generateDirectionStyles, generateGapStyles, generateJustifyContentStyles, generatePaddingStyles, iconButtonStyles, interactiveStyles, lineHeights, matchesAccept, mq, proseStyles, resetButton, resetInput, resolveShowcaseCommand, resolveTheme, shade, shadows, shadowsDark, showcaseCommands, spacing, statusBorderStyles, styledBlockquote, styledButton, styledButtonBig, styledCode, styledH1, styledH2, styledH3, styledH4, styledH5, styledH6, styledHero1, styledHero2, styledHero3, styledInput, styledInputBig, styledSmall, styledStrong, styledText, theme, themeDark, themeInitScript, thinScrollbar, tint, useBelowBreakpoint, useChat, useLockBodyScroll, useMediaQuery, useOnClickOutside, useToastNotifications };
@@ -0,0 +1,17 @@
1
+ import { default as React } from 'react';
2
+ import { Theme } from './utils';
3
+ export interface ProseProps extends React.HTMLAttributes<HTMLDivElement> {
4
+ children?: React.ReactNode;
5
+ /** Tightens the vertical rhythm for dense contexts such as chat bubbles. */
6
+ $compact?: boolean;
7
+ }
8
+ /**
9
+ * Styles for rendered markdown: links, lists, tables, code, media and
10
+ * headings. Exported so it can be applied to an element that is already
11
+ * styled, rather than wrapping it in another <div>.
12
+ */
13
+ export declare const proseStyles: (theme: Theme, $compact?: boolean) => import('styled-components').RuleSet<NoInfer<{
14
+ theme: Theme;
15
+ }>>;
16
+ declare const Prose: React.ForwardRefExoticComponent<ProseProps & React.RefAttributes<HTMLDivElement>>;
17
+ export { Prose };
package/dist/prose.js ADDED
@@ -0,0 +1,75 @@
1
+ "use client";
2
+ "use client";
3
+ import { alpha, thinScrollbar } from "./utils/mixins.js";
4
+ import { styledH1, styledH2, styledH3, styledH4, styledH5, styledH6, styledSmall, styledText } from "./utils/typography.js";
5
+ import { jsx } from "react/jsx-runtime";
6
+ import { forwardRef } from "react";
7
+ import styled, { css } from "styled-components";
8
+ //#region src/lib/prose.tsx
9
+ var accent = (theme) => theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark;
10
+ /**
11
+ * Styles for rendered markdown: links, lists, tables, code, media and
12
+ * headings. Exported so it can be applied to an element that is already
13
+ * styled, rather than wrapping it in another <div>.
14
+ */ var proseStyles = (theme, $compact) => {
15
+ const block = $compact ? "10px" : "20px";
16
+ return css([
17
+ `color:`,
18
+ `;`,
19
+ `;& > *:first-child{margin-top:0;}& > *:last-child{margin-bottom:0;& > *:last-child{margin-bottom:0;}}& p{margin:0 0 `,
20
+ `;`,
21
+ `;}& h1,& h2,& h3,& h4,& h5,& h6{margin:`,
22
+ ` 0;padding:0;color:`,
23
+ `;}& h1{`,
24
+ `;}& h2{`,
25
+ `;}& h3{`,
26
+ `;}& h4{`,
27
+ `;}& h5{`,
28
+ `;}& h6{`,
29
+ `;}& a:not([class]):not(:has(img)){color:inherit;transition:all 0.3s ease;text-decoration:none;box-shadow:0 2px 0 0 `,
30
+ `;&:hover{color:`,
31
+ `;box-shadow:0 1px 0 0 `,
32
+ `;}&:focus-visible{outline:none;border-radius:`,
33
+ `;box-shadow:0 2px 0 0 `,
34
+ `,0 0 0 2px `,
35
+ `;}}& ul,& ol{margin:0 0 `,
36
+ `;padding:0;& li{& > .code-wrapper{margin:10px 0;}& p{display:inline;}}}& ul{list-style:none;& li{text-indent:0;display:block;position:relative;padding:0 0 0 24px;margin:0;`,
37
+ `;&::before{content:"";display:block;width:6px;height:6px;border-radius:50%;background:`,
38
+ `;position:absolute;top:0.65em;left:9px;}}}& ol{counter-reset:item;& > li{counter-increment:item;padding:0 0 0 24px;margin:0;`,
39
+ `;&::before{content:counter(item) ".";display:inline-block;min-width:20px;margin-left:-24px;margin-right:4px;text-align:right;font-weight:700;color:`,
40
+ `;}}}& code:not([class]){background:`,
41
+ `;color:`,
42
+ `;padding:2px 4px;border-radius:`,
43
+ `;font-family:`,
44
+ `;white-space:pre;}& pre,& .hljs{margin:10px 0;overflow-x:auto;`,
45
+ `;}& .code-wrapper pre{margin:0;}& blockquote{margin:`,
46
+ ` 0;padding:0 0 0 16px;border-left:solid 2px `,
47
+ `;color:`,
48
+ `;}& hr{margin:`,
49
+ ` 0;border:none;border-bottom:solid 1px `,
50
+ `;}& .table-wrapper{overflow-x:auto;width:100%;margin:0 0 `,
51
+ `;`,
52
+ `;}& table{margin:0;padding:0;border-collapse:collapse;width:100%;text-align:left;& tr{margin:0;padding:0;}& th{border-bottom:solid 1px `,
53
+ `;padding:10px 10px 10px 0;`,
54
+ `;font-weight:600;color:`,
55
+ `;}& td{border-bottom:solid 1px `,
56
+ `;padding:10px 10px 10px 0;color:`,
57
+ `;`,
58
+ `;}}& img,& video,& iframe{max-width:100%;border-radius:`,
59
+ `;margin:10px 0;display:block;}`
60
+ ], theme.colors.dark, styledText(theme), block, styledText(theme), block, theme.colors.dark, ($compact ? styledH3 : styledH1)(theme), ($compact ? styledH4 : styledH2)(theme), ($compact ? styledH5 : styledH3)(theme), ($compact ? styledH6 : styledH4)(theme), ($compact ? styledH6 : styledH5)(theme), styledH6(theme), theme.colors.primary, accent(theme), theme.colors.primary, theme.spacing.radius.xs, theme.colors.primary, theme.colors.primaryLight, block, styledText(theme), theme.colors.primary, styledText(theme), theme.colors.primary, alpha(theme.colors.primaryLight, 20), theme.colors.dark, theme.spacing.radius.xs, theme.fonts.mono, thinScrollbar, block, theme.colors.grayLight, theme.colors.grayDark, block, theme.colors.grayLight, block, thinScrollbar, theme.colors.grayLight, styledSmall(theme), theme.colors.dark, theme.colors.grayLight, theme.colors.grayDark, styledSmall(theme), theme.spacing.radius.lg);
61
+ };
62
+ var StyledProse = styled.div.withConfig({
63
+ displayName: "prose__StyledProse",
64
+ componentId: "sc-91bd953a-0"
65
+ })([``, `;`], ({ theme, $compact }) => proseStyles(theme, $compact));
66
+ function LocalProse({ children, ...props }, ref) {
67
+ return /*#__PURE__*/ jsx(StyledProse, {
68
+ ...props,
69
+ ref,
70
+ children
71
+ });
72
+ }
73
+ var Prose = /*#__PURE__*/ forwardRef(LocalProse);
74
+ //#endregion
75
+ export { Prose, proseStyles };
@@ -0,0 +1,11 @@
1
+ import { IconProps } from './icon';
2
+ export interface SpinnerProps {
3
+ /** Lucide icon to rotate. */
4
+ name?: IconProps;
5
+ color?: string;
6
+ size?: number;
7
+ className?: string;
8
+ "aria-label"?: string;
9
+ }
10
+ declare const Spinner: ({ name, ...props }: SpinnerProps) => import("react").JSX.Element;
11
+ export { Spinner };
@@ -0,0 +1,21 @@
1
+ "use client";
2
+ "use client";
3
+ import { Icon } from "./icon.js";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import styled, { keyframes } from "styled-components";
6
+ //#region src/lib/spinner.tsx
7
+ var spin = keyframes([`0%{transform:rotate(0deg);}100%{transform:rotate(360deg);}`]);
8
+ var StyledSpinner = styled(Icon).withConfig({
9
+ displayName: "spinner__StyledSpinner",
10
+ componentId: "sc-bb636095-0"
11
+ })([
12
+ `color:`,
13
+ `;animation:`,
14
+ ` 1s linear infinite;@media (prefers-reduced-motion:reduce){animation:none;}`
15
+ ], ({ theme }) => theme.colors.dark, spin);
16
+ var Spinner = ({ name = "LoaderCircle", ...props }) => /*#__PURE__*/ jsx(StyledSpinner, {
17
+ name,
18
+ ...props
19
+ });
20
+ //#endregion
21
+ export { Spinner };
@@ -6,7 +6,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
6
6
  import { useEffect, useMemo, useState } from "react";
7
7
  import { ThemeProvider } from "styled-components";
8
8
  //#region src/lib/styled-components/client-theme-provider.tsx
9
- var THEME_COOKIE_MAX_AGE = 3600 * 24 * 365;
9
+ var THEME_COOKIE_MAX_AGE = 31536e3;
10
10
  function readThemeCookie() {
11
11
  const cookie = document.cookie.split(";").map((c) => c.trim()).find((c) => c.startsWith("theme="));
12
12
  const value = cookie ? cookie.split("=")[1] : void 0;
package/dist/toast.d.ts CHANGED
@@ -35,14 +35,14 @@ export declare const StyledNotifications: import('styled-components/dist/types')
35
35
  $align?: ToastAlign;
36
36
  $bottom?: boolean;
37
37
  }, never>>> & string;
38
- export declare const StyledNotificationItem: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('styled-components').FastOmit<React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "theme" | "$align" | "$bottom" | "$color" | "$visible" | "$static"> & {
38
+ export declare const StyledNotificationItem: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components').FastOmit<import('styled-components').FastOmit<React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "theme" | "$color" | "$align" | "$bottom" | "$visible" | "$static"> & {
39
39
  theme: Theme;
40
40
  $color: ToastColor;
41
41
  $visible: boolean;
42
42
  $static: boolean;
43
43
  $align?: ToastAlign;
44
44
  $bottom?: boolean;
45
- }, never> & Partial<Pick<import('styled-components').FastOmit<React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "theme" | "$align" | "$bottom" | "$color" | "$visible" | "$static"> & {
45
+ }, never> & Partial<Pick<import('styled-components').FastOmit<React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "theme" | "$color" | "$align" | "$bottom" | "$visible" | "$static"> & {
46
46
  theme: Theme;
47
47
  $color: ToastColor;
48
48
  $visible: boolean;
@@ -2,4 +2,6 @@ export * from './global';
2
2
  export * from './mixins';
3
3
  export * from './theme';
4
4
  export * from './typography';
5
+ export * from './use-lock-body-scroll';
6
+ export * from './use-media-query';
5
7
  export * from './use-on-click-outside';
@@ -9,6 +9,26 @@ export declare const alpha: (color: string, percent: number) => string;
9
9
  export declare const shade: (color: string, percent: number) => string;
10
10
  /** Lightens a color by mixing it toward white. See `alpha` for why it is CSS. */
11
11
  export declare const tint: (color: string, percent: number) => string;
12
+ /**
13
+ * Text color for a label sitting on a brand-colored fill: the palette's
14
+ * contrasting end, `light` in light mode and `dark` in dark mode.
15
+ */
16
+ export declare const filledTextColor: (theme: Theme) => string;
17
+ /**
18
+ * The same choice restated as a rule scoped to a `dark` class on <html>, which
19
+ * is what apps resolving the mode in CSS key off before hydration can swap the
20
+ * theme object. Additive: with an already-dark theme object both paths resolve
21
+ * to the same color. Interpolate alongside `filledTextColor`.
22
+ */
23
+ export declare const darkFilledTextRule: (theme: Theme) => string;
24
+ /**
25
+ * Slim, theme-aware scrollbar for internal scroll areas (chat transcripts, code
26
+ * blocks, tables) so the chunky native bar doesn't stand out, especially in
27
+ * dark mode.
28
+ */
29
+ export declare const thinScrollbar: import('styled-components').RuleSet<NoInfer<{
30
+ theme: Theme;
31
+ }>>;
12
32
  /**
13
33
  * Hover/focus/active affordance for interactive surfaces (cards, tiles,
14
34
  * links-as-blocks): a transparent 1px border that picks up the primary color
@@ -11,6 +11,21 @@ import { css } from "styled-components";
11
11
  /** Darkens a color by mixing it toward black. See `alpha` for why it is CSS. */ var shade = (color, percent) => `color-mix(in srgb, ${color} ${100 - percent}%, black)`;
12
12
  /** Lightens a color by mixing it toward white. See `alpha` for why it is CSS. */ var tint = (color, percent) => `color-mix(in srgb, ${color} ${100 - percent}%, white)`;
13
13
  /**
14
+ * Text color for a label sitting on a brand-colored fill: the palette's
15
+ * contrasting end, `light` in light mode and `dark` in dark mode.
16
+ */ var filledTextColor = (theme) => theme.isDark ? theme.colors.dark : theme.colors.light;
17
+ /**
18
+ * The same choice restated as a rule scoped to a `dark` class on <html>, which
19
+ * is what apps resolving the mode in CSS key off before hydration can swap the
20
+ * theme object. Additive: with an already-dark theme object both paths resolve
21
+ * to the same color. Interpolate alongside `filledTextColor`.
22
+ */ var darkFilledTextRule = (theme) => `:root.dark & { color: ${theme.colors.dark}; }`;
23
+ /**
24
+ * Slim, theme-aware scrollbar for internal scroll areas (chat transcripts, code
25
+ * blocks, tables) so the chunky native bar doesn't stand out, especially in
26
+ * dark mode.
27
+ */ var thinScrollbar = css([`scrollbar-width:thin;scrollbar-color:`, ` transparent;`], ({ theme }) => theme.colors.grayLight);
28
+ /**
14
29
  * Hover/focus/active affordance for interactive surfaces (cards, tiles,
15
30
  * links-as-blocks): a transparent 1px border that picks up the primary color
16
31
  * on hover, with a soft focus ring. Pair with resetButton for clickable
@@ -90,4 +105,4 @@ var generateDirectionStyles = (size, direction) => css([
90
105
  `;}`
91
106
  ], mq(size), direction && `${direction}`);
92
107
  //#endregion
93
- export { alpha, errorInteractiveStyles, formElementHeightStyles, fullWidthStyles, generateAlignContentStyles, generateAlignItemsStyles, generateColSpanStyles, generateColsStyles, generateDirectionStyles, generateGapStyles, generateJustifyContentStyles, generatePaddingStyles, interactiveStyles, resetButton, resetInput, shade, statusBorderStyles, tint };
108
+ export { alpha, darkFilledTextRule, errorInteractiveStyles, filledTextColor, formElementHeightStyles, fullWidthStyles, generateAlignContentStyles, generateAlignItemsStyles, generateColSpanStyles, generateColsStyles, generateDirectionStyles, generateGapStyles, generateJustifyContentStyles, generatePaddingStyles, interactiveStyles, resetButton, resetInput, shade, statusBorderStyles, thinScrollbar, tint };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Freezes body scrolling while `isLocked` is true. Safe to nest: the body is
3
+ * restored only when every active lock has been released.
4
+ */
5
+ export declare function useLockBodyScroll(isLocked: boolean): void;