cherry-styled-components 0.2.15 → 0.2.17
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/README.md +7 -6
- package/dist/accordion.js +7 -6
- package/dist/avatar-dropzone.d.ts +3 -3
- package/dist/avatar-dropzone.js +8 -7
- package/dist/avatar.d.ts +3 -3
- package/dist/avatar.js +5 -7
- package/dist/callout.d.ts +3 -3
- package/dist/callout.js +11 -13
- package/dist/chat-input.js +9 -8
- package/dist/chat-launcher.js +3 -2
- package/dist/chat-panel.d.ts +3 -2
- package/dist/chat-panel.js +6 -5
- package/dist/dropzone.d.ts +3 -3
- package/dist/dropzone.js +15 -14
- package/dist/icon-dynamic.d.ts +24 -0
- package/dist/icon-dynamic.js +34 -0
- package/dist/icon.d.ts +39 -5
- package/dist/icon.js +25 -13
- package/dist/index.js +2 -3
- package/dist/input.js +10 -9
- package/dist/modal.js +6 -5
- package/dist/password.js +4 -3
- package/dist/select.js +4 -3
- package/dist/spinner.d.ts +4 -4
- package/dist/spinner.js +4 -3
- package/dist/styled-components/index.d.ts +0 -1
- package/dist/theme-toggle.js +3 -2
- package/dist/toast.d.ts +2 -2
- package/dist/toast.js +9 -8
- package/dist/utils/use-on-click-outside.js +43 -0
- package/package.json +22 -15
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { DynamicIcon as DynamicIcon$1, iconNames } from "lucide-react/dynamic";
|
|
5
|
+
//#region src/lib/icon-dynamic.tsx
|
|
6
|
+
var KEBAB_NAMES = new Set(iconNames);
|
|
7
|
+
function toPascal(name) {
|
|
8
|
+
return name.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
9
|
+
}
|
|
10
|
+
var KEBAB_BY_PASCAL = new Map(iconNames.map((name) => [toPascal(name), name]));
|
|
11
|
+
function resolveIconName(name) {
|
|
12
|
+
if (KEBAB_NAMES.has(name)) return name;
|
|
13
|
+
return KEBAB_BY_PASCAL.get(toPascal(name)) ?? null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Renders a lucide icon chosen at runtime (CMS content, user settings). The
|
|
17
|
+
* glyph is fetched on demand through `lucide-react/dynamic`, so it appears
|
|
18
|
+
* after hydration once its chunk has loaded, and never in server-rendered
|
|
19
|
+
* HTML. For any icon known when the code is written, use
|
|
20
|
+
* `<Icon icon={Glyph} />` from the main entry instead. In a `$icon`-style
|
|
21
|
+
* prop, pass it as an element: `$icon={<DynamicIcon name={n} />}`.
|
|
22
|
+
*/ function DynamicIcon({ name, "aria-label": ariaLabel, ...props }) {
|
|
23
|
+
const iconName = resolveIconName(name);
|
|
24
|
+
if (!iconName) return null;
|
|
25
|
+
return /*#__PURE__*/ jsx(DynamicIcon$1, {
|
|
26
|
+
name: iconName,
|
|
27
|
+
...props,
|
|
28
|
+
"aria-label": ariaLabel,
|
|
29
|
+
"aria-hidden": !ariaLabel,
|
|
30
|
+
role: ariaLabel ? "img" : void 0
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { DynamicIcon };
|
package/dist/icon.d.ts
CHANGED
|
@@ -1,11 +1,45 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { ComponentType, ReactElement } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* The props Cherry hands to an icon component. Every `lucide-react` export
|
|
4
|
+
* satisfies this, and so does any SVG component that takes a `size`.
|
|
5
|
+
*/
|
|
6
|
+
export interface IconGlyphProps {
|
|
7
|
+
size?: number;
|
|
8
|
+
color?: string;
|
|
9
|
+
className?: string;
|
|
10
|
+
"aria-label"?: string;
|
|
11
|
+
"aria-hidden"?: boolean;
|
|
12
|
+
role?: "img";
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* An icon component: `import { ArrowRight } from "lucide-react"`, or a
|
|
16
|
+
* component of your own that accepts `IconGlyphProps`.
|
|
17
|
+
*/
|
|
18
|
+
export type IconComponent = ComponentType<IconGlyphProps>;
|
|
19
|
+
/**
|
|
20
|
+
* What a component's `$icon`-style prop accepts: an `IconComponent`, which
|
|
21
|
+
* the component renders through `Icon` at the size it chooses, or a rendered
|
|
22
|
+
* element such as `<DynamicIcon name={n} />`, which is used as given.
|
|
23
|
+
*/
|
|
24
|
+
export type IconSource = IconComponent | ReactElement;
|
|
25
|
+
export interface IconProps {
|
|
26
|
+
/** An imported lucide component, or any component taking `IconGlyphProps`. */
|
|
27
|
+
icon: IconComponent;
|
|
5
28
|
color?: string;
|
|
6
29
|
size?: number;
|
|
7
30
|
className?: string;
|
|
8
31
|
"aria-label"?: string;
|
|
9
32
|
}
|
|
10
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Renders one icon component. It costs exactly that glyph and renders on the
|
|
35
|
+
* server. Decorative unless labelled; a labelled glyph is announced as an
|
|
36
|
+
* image. For an icon chosen at runtime, see `DynamicIcon` in the
|
|
37
|
+
* `cherry-styled-components/dynamic` subpath.
|
|
38
|
+
*/
|
|
39
|
+
declare const Icon: ({ icon: Glyph, color, size, className, "aria-label": ariaLabel, }: IconProps) => import("react").JSX.Element;
|
|
40
|
+
/**
|
|
41
|
+
* Renders an `IconSource`: an element as given, a component through `Icon`
|
|
42
|
+
* with `props`. For components that forward a `$icon`-style prop.
|
|
43
|
+
*/
|
|
44
|
+
export declare function renderIcon(source: IconSource, props?: Omit<IconProps, "icon">): ReactElement;
|
|
11
45
|
export { Icon };
|
package/dist/icon.js
CHANGED
|
@@ -1,17 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
1
3
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
4
|
+
import { isValidElement } from "react";
|
|
3
5
|
//#region src/lib/icon.tsx
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Renders one icon component. It costs exactly that glyph and renders on the
|
|
8
|
+
* server. Decorative unless labelled; a labelled glyph is announced as an
|
|
9
|
+
* image. For an icon chosen at runtime, see `DynamicIcon` in the
|
|
10
|
+
* `cherry-styled-components/dynamic` subpath.
|
|
11
|
+
*/ var Icon = ({ icon: Glyph, color, size, className, "aria-label": ariaLabel }) => /*#__PURE__*/ jsx(Glyph, {
|
|
12
|
+
color,
|
|
13
|
+
size,
|
|
14
|
+
className,
|
|
15
|
+
"aria-label": ariaLabel,
|
|
16
|
+
"aria-hidden": !ariaLabel,
|
|
17
|
+
role: ariaLabel ? "img" : void 0
|
|
18
|
+
});
|
|
19
|
+
/**
|
|
20
|
+
* Renders an `IconSource`: an element as given, a component through `Icon`
|
|
21
|
+
* with `props`. For components that forward a `$icon`-style prop.
|
|
22
|
+
*/ function renderIcon(source, props) {
|
|
23
|
+
return /*#__PURE__*/ isValidElement(source) ? source : /*#__PURE__*/ jsx(Icon, {
|
|
24
|
+
icon: source,
|
|
25
|
+
...props
|
|
14
26
|
});
|
|
15
|
-
}
|
|
27
|
+
}
|
|
16
28
|
//#endregion
|
|
17
|
-
export { Icon };
|
|
29
|
+
export { Icon, renderIcon };
|
package/dist/index.js
CHANGED
|
@@ -7,9 +7,8 @@ import { useBelowBreakpoint, useMediaQuery } from "./utils/use-media-query.js";
|
|
|
7
7
|
import { useOnClickOutside } from "./utils/use-on-click-outside.js";
|
|
8
8
|
import { CherryThemeProvider, ThemeContext } from "./styled-components/theme-provider.js";
|
|
9
9
|
import { ClientThemeProvider } from "./styled-components/client-theme-provider.js";
|
|
10
|
-
import { StyledComponentsRegistry } from "./styled-components/registry.js";
|
|
11
10
|
import { createThemeInitScript, resolveTheme, themeInitScript } from "./styled-components/theme-init.js";
|
|
12
|
-
import { Icon } from "./icon.js";
|
|
11
|
+
import { Icon, renderIcon } from "./icon.js";
|
|
13
12
|
import { Accordion } from "./accordion.js";
|
|
14
13
|
import { Avatar } from "./avatar.js";
|
|
15
14
|
import { Dropzone, matchesAccept } from "./dropzone.js";
|
|
@@ -45,4 +44,4 @@ import { Textarea } from "./textarea.js";
|
|
|
45
44
|
import { ThemeToggle } from "./theme-toggle.js";
|
|
46
45
|
import { StyledNotificationItem, StyledNotifications, ToastNotifications, ToastNotificationsContext, ToastNotificationsProvider, useToastNotifications } from "./toast.js";
|
|
47
46
|
import { Toggle } from "./toggle.js";
|
|
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,
|
|
47
|
+
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, 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, renderIcon, 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 };
|
package/dist/input.js
CHANGED
|
@@ -5,10 +5,11 @@ import { Icon } from "./icon.js";
|
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { forwardRef } from "react";
|
|
7
7
|
import styled, { css } from "styled-components";
|
|
8
|
+
import { CalendarDays, Check } from "lucide-react";
|
|
8
9
|
//#region src/lib/input.tsx
|
|
9
10
|
var StyledInputWrapper = styled.span.withConfig({
|
|
10
11
|
displayName: "input__StyledInputWrapper",
|
|
11
|
-
componentId: "sc-
|
|
12
|
+
componentId: "sc-8a4d191a-0"
|
|
12
13
|
})([
|
|
13
14
|
`display:inline-flex;flex-wrap:`,
|
|
14
15
|
`;align-items:center;`,
|
|
@@ -20,7 +21,7 @@ var StyledInputWrapper = styled.span.withConfig({
|
|
|
20
21
|
], ({ type }) => type === "checkbox" || type === "radio" ? "nowrap" : "wrap", ({ $label }) => $label && css([`gap:5px;align-items:flex-start;align-content:flex-start;`]), ({ $size }) => $size === "small" ? "14px" : "17px", ({ $size }) => $size === "small" ? "18px" : "24px", ({ $size }) => $size === "small" ? "18px" : "24px", ({ $fullWidth }) => fullWidthStyles($fullWidth));
|
|
21
22
|
var StyledLabel = styled.label.withConfig({
|
|
22
23
|
displayName: "input__StyledLabel",
|
|
23
|
-
componentId: "sc-
|
|
24
|
+
componentId: "sc-8a4d191a-1"
|
|
24
25
|
})([
|
|
25
26
|
`display:inline-block;color:`,
|
|
26
27
|
`;font-size:`,
|
|
@@ -29,7 +30,7 @@ var StyledLabel = styled.label.withConfig({
|
|
|
29
30
|
], ({ theme }) => theme.colors.grayDark, ({ theme }) => theme.fontSizes.small.lg, ({ theme }) => theme.lineHeights.small.lg);
|
|
30
31
|
var StyledInput = styled.input.withConfig({
|
|
31
32
|
displayName: "input__StyledInput",
|
|
32
|
-
componentId: "sc-
|
|
33
|
+
componentId: "sc-8a4d191a-2"
|
|
33
34
|
})([
|
|
34
35
|
``,
|
|
35
36
|
`;`,
|
|
@@ -38,7 +39,7 @@ var StyledInput = styled.input.withConfig({
|
|
|
38
39
|
`;background:`,
|
|
39
40
|
`;border:solid 2px `,
|
|
40
41
|
`;box-shadow:0 0 0 0px `,
|
|
41
|
-
`;transition:all 0.3s ease;word-break:keep-all;white-space:nowrap;display:inline-flex;&::-webkit-datetime-edit{padding:0;margin:0;vertical-align:middle;}&::-webkit-datetime-edit-fields-wrapper{padding:4px 0;margin:0;vertical-align:middle;}&::-webkit-calendar-picker-indicator{background:transparent;cursor:pointer;position:absolute;right:15px;top:50%;transform:translateY(-50%);width:24px;height:24px;}&::-webkit-datetime-edit-text{color:`,
|
|
42
|
+
`;transition:all 0.3s ease;word-break:keep-all;white-space:nowrap;display:inline-flex;&::-webkit-datetime-edit{padding:0;margin:0;vertical-align:middle;}&::-webkit-datetime-edit-fields-wrapper{padding:4px 0;margin:0;vertical-align:middle;}&::-webkit-date-and-time-value{text-align:left;margin:0;}&::-webkit-calendar-picker-indicator{background:transparent;cursor:pointer;position:absolute;right:15px;top:50%;transform:translateY(-50%);width:24px;height:24px;}&::-webkit-datetime-edit-text{color:`,
|
|
42
43
|
`;}&::-webkit-datetime-edit-month-field{&:focus{background:`,
|
|
43
44
|
`;color:`,
|
|
44
45
|
`;border-radius:4px;}}&::-webkit-datetime-edit-day-field{&:focus{background:`,
|
|
@@ -85,7 +86,7 @@ var StyledInput = styled.input.withConfig({
|
|
|
85
86
|
`, ({ $fullWidth }) => fullWidthStyles($fullWidth));
|
|
86
87
|
var StyledIconWrapper = styled.span.withConfig({
|
|
87
88
|
displayName: "input__StyledIconWrapper",
|
|
88
|
-
componentId: "sc-
|
|
89
|
+
componentId: "sc-8a4d191a-3"
|
|
89
90
|
})([
|
|
90
91
|
`display:inline-flex;position:relative;line-height:0;min-width:fit-content;& em{display:block;border-radius:50%;background:`,
|
|
91
92
|
`;}& svg,& em{object-fit:contain;position:absolute;top:50%;left:50%;color:`,
|
|
@@ -93,7 +94,7 @@ var StyledIconWrapper = styled.span.withConfig({
|
|
|
93
94
|
], ({ theme }) => theme.colors.primary, ({ theme }) => theme.colors.primary);
|
|
94
95
|
var StyledRadioCheckboxInput = styled.input.withConfig({
|
|
95
96
|
displayName: "input__StyledRadioCheckboxInput",
|
|
96
|
-
componentId: "sc-
|
|
97
|
+
componentId: "sc-8a4d191a-4"
|
|
97
98
|
})([
|
|
98
99
|
``,
|
|
99
100
|
`;display:inline-block;background:`,
|
|
@@ -178,7 +179,7 @@ var StyledRadioCheckboxInput = styled.input.withConfig({
|
|
|
178
179
|
});
|
|
179
180
|
var StyledCustomIconWrapper = styled.span.withConfig({
|
|
180
181
|
displayName: "input__StyledCustomIconWrapper",
|
|
181
|
-
componentId: "sc-
|
|
182
|
+
componentId: "sc-8a4d191a-5"
|
|
182
183
|
})([
|
|
183
184
|
`position:relative;`,
|
|
184
185
|
`;& svg{position:absolute;top:50%;transform:translateY(-50%);pointer-events:none;width:24px;height:24px;object-fit:contain;color:`,
|
|
@@ -195,7 +196,7 @@ function LocalInput({ ...props }, ref) {
|
|
|
195
196
|
...props,
|
|
196
197
|
"aria-invalid": props.$error || void 0,
|
|
197
198
|
ref
|
|
198
|
-
}), !props.disabled && props.type === "checkbox" ? /*#__PURE__*/ jsx(Icon, {
|
|
199
|
+
}), !props.disabled && props.type === "checkbox" ? /*#__PURE__*/ jsx(Icon, { icon: Check }) : /*#__PURE__*/ jsx("em", {})] }), props.$label && /*#__PURE__*/ jsx(StyledLabel, {
|
|
199
200
|
htmlFor: props.id,
|
|
200
201
|
children: props.$label
|
|
201
202
|
})]
|
|
@@ -222,7 +223,7 @@ function LocalInput({ ...props }, ref) {
|
|
|
222
223
|
}),
|
|
223
224
|
props.$iconPosition === "right" && props.$icon && props.$icon,
|
|
224
225
|
(props.type === "date" || props.type === "datetime-local" || props.type === "month" || props.type === "week" || props.type === "time") && /*#__PURE__*/ jsx(Icon, {
|
|
225
|
-
|
|
226
|
+
icon: CalendarDays,
|
|
226
227
|
className: "icon-calendar"
|
|
227
228
|
})
|
|
228
229
|
]
|
package/dist/modal.js
CHANGED
|
@@ -9,6 +9,7 @@ import { IconButton } from "./icon-button.js";
|
|
|
9
9
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
10
10
|
import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
11
11
|
import styled, { css, keyframes } from "styled-components";
|
|
12
|
+
import { X } from "lucide-react";
|
|
12
13
|
import { createPortal } from "react-dom";
|
|
13
14
|
//#region src/lib/modal.tsx
|
|
14
15
|
var emptySubscribe = () => () => {};
|
|
@@ -21,7 +22,7 @@ var innerRiseIn = keyframes([`from{transform:translateY(40px);}to{transform:tran
|
|
|
21
22
|
var innerSinkOut = keyframes([`from{transform:translateY(0);}to{transform:translateY(40px);}`]);
|
|
22
23
|
var StyledModal = styled.div.withConfig({
|
|
23
24
|
displayName: "modal__StyledModal",
|
|
24
|
-
componentId: "sc-
|
|
25
|
+
componentId: "sc-937855ae-0"
|
|
25
26
|
})([
|
|
26
27
|
`position:fixed;top:0;left:0;width:100%;height:100%;background:`,
|
|
27
28
|
`;display:flex;justify-content:center;align-items:center;z-index:1010;animation:`,
|
|
@@ -35,11 +36,11 @@ var StyledModal = styled.div.withConfig({
|
|
|
35
36
|
], ({ theme }) => alpha(theme.colors.primary, 50), ({ $isClosing }) => $isClosing ? overlayFadeOut : overlayFadeIn, ({ $isClosing }) => $isClosing && css([`pointer-events:none;`]), ({ theme }) => theme.colors.light, ({ theme }) => theme.spacing.radius.lg, ({ $isClosing }) => $isClosing ? innerSinkOut : innerRiseIn, mq("lg"), ({ $width }) => $width && css([`max-width:`, `px;`], $width));
|
|
36
37
|
var StyledModalClose = styled(IconButton).withConfig({
|
|
37
38
|
displayName: "modal__StyledModalClose",
|
|
38
|
-
componentId: "sc-
|
|
39
|
+
componentId: "sc-937855ae-1"
|
|
39
40
|
})([`position:absolute;top:20px;right:20px;z-index:10;`]);
|
|
40
41
|
var StyledModalTitle = styled.h2.withConfig({
|
|
41
42
|
displayName: "modal__StyledModalTitle",
|
|
42
|
-
componentId: "sc-
|
|
43
|
+
componentId: "sc-937855ae-2"
|
|
43
44
|
})([
|
|
44
45
|
`--divider-color:`,
|
|
45
46
|
`;margin:0 0 15px 0;padding:0 0 15px 0;color:`,
|
|
@@ -48,7 +49,7 @@ var StyledModalTitle = styled.h2.withConfig({
|
|
|
48
49
|
], ({ theme }) => theme.colors.grayLight, ({ theme }) => theme.colors.dark, ({ theme }) => styledH5(theme));
|
|
49
50
|
var StyledModalContent = styled.div.withConfig({
|
|
50
51
|
displayName: "modal__StyledModalContent",
|
|
51
|
-
componentId: "sc-
|
|
52
|
+
componentId: "sc-937855ae-3"
|
|
52
53
|
})([
|
|
53
54
|
`max-height:calc(100svh - 200px);overflow-y:auto;padding:5px;margin:-5px;--divider-color:`,
|
|
54
55
|
`;`,
|
|
@@ -101,7 +102,7 @@ function Modal({ children, $isOpen, $onClose, $title, $width, $hideCloseButton,
|
|
|
101
102
|
onClick: closeModal,
|
|
102
103
|
className: "modal-close",
|
|
103
104
|
"aria-label": "Close Modal",
|
|
104
|
-
children: /*#__PURE__*/ jsx(Icon, {
|
|
105
|
+
children: /*#__PURE__*/ jsx(Icon, { icon: X })
|
|
105
106
|
})
|
|
106
107
|
}),
|
|
107
108
|
$title && /*#__PURE__*/ jsx(StyledModalTitle, {
|
package/dist/password.js
CHANGED
|
@@ -7,6 +7,7 @@ import { Input } from "./input.js";
|
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { forwardRef, useState } from "react";
|
|
9
9
|
import styled, { css } from "styled-components";
|
|
10
|
+
import { Eye, EyeOff } from "lucide-react";
|
|
10
11
|
//#region src/lib/password.tsx
|
|
11
12
|
var passwordSizes = {
|
|
12
13
|
small: {
|
|
@@ -27,7 +28,7 @@ var passwordSizes = {
|
|
|
27
28
|
};
|
|
28
29
|
var StyledPassword = styled.span.withConfig({
|
|
29
30
|
displayName: "password__StyledPassword",
|
|
30
|
-
componentId: "sc-
|
|
31
|
+
componentId: "sc-ab5e6dd3-0"
|
|
31
32
|
})([
|
|
32
33
|
`position:relative;display:inline-flex;& input{padding-right:`,
|
|
33
34
|
`;}`,
|
|
@@ -38,7 +39,7 @@ var StyledPassword = styled.span.withConfig({
|
|
|
38
39
|
}, ({ $fullWidth }) => fullWidthStyles($fullWidth));
|
|
39
40
|
var StyledPasswordReveal = styled.span.withConfig({
|
|
40
41
|
displayName: "password__StyledPasswordReveal",
|
|
41
|
-
componentId: "sc-
|
|
42
|
+
componentId: "sc-ab5e6dd3-1"
|
|
42
43
|
})([`position:absolute;bottom:0;display:flex;align-items:center;`, ``], ({ $size }) => {
|
|
43
44
|
const { height, inset } = passwordSizes[$size ?? "default"];
|
|
44
45
|
return css([
|
|
@@ -65,7 +66,7 @@ function LocalPassword({ ...props }, ref) {
|
|
|
65
66
|
"aria-pressed": show,
|
|
66
67
|
title: show ? "Hide password" : "Show password",
|
|
67
68
|
onClick: () => setShow((prev) => !prev),
|
|
68
|
-
children: /*#__PURE__*/ jsx(Icon, {
|
|
69
|
+
children: /*#__PURE__*/ jsx(Icon, { icon: show ? EyeOff : Eye })
|
|
69
70
|
})
|
|
70
71
|
})]
|
|
71
72
|
});
|
package/dist/select.js
CHANGED
|
@@ -6,10 +6,11 @@ import { StyledInputWrapper, StyledLabel } from "./input.js";
|
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { forwardRef } from "react";
|
|
8
8
|
import styled from "styled-components";
|
|
9
|
+
import { ChevronDown } from "lucide-react";
|
|
9
10
|
//#region src/lib/select.tsx
|
|
10
11
|
var StyledSelect = styled.select.withConfig({
|
|
11
12
|
displayName: "select__StyledSelect",
|
|
12
|
-
componentId: "sc-
|
|
13
|
+
componentId: "sc-ea1826c7-0"
|
|
13
14
|
})([
|
|
14
15
|
``,
|
|
15
16
|
`;`,
|
|
@@ -38,7 +39,7 @@ var StyledSelect = styled.select.withConfig({
|
|
|
38
39
|
`, ({ $fullWidth }) => fullWidthStyles($fullWidth));
|
|
39
40
|
var StyledIconWrapper = styled.span.withConfig({
|
|
40
41
|
displayName: "select__StyledIconWrapper",
|
|
41
|
-
componentId: "sc-
|
|
42
|
+
componentId: "sc-ea1826c7-1"
|
|
42
43
|
})([
|
|
43
44
|
`position:relative;`,
|
|
44
45
|
` & svg{position:absolute;top:50%;right:15px;width:24px;height:24px;color:`,
|
|
@@ -59,7 +60,7 @@ function LocalSelect({ ...props }, ref) {
|
|
|
59
60
|
"aria-invalid": props.$error || void 0,
|
|
60
61
|
ref,
|
|
61
62
|
children: props.children
|
|
62
|
-
}), /*#__PURE__*/ jsx(Icon, {
|
|
63
|
+
}), /*#__PURE__*/ jsx(Icon, { icon: ChevronDown })]
|
|
63
64
|
})]
|
|
64
65
|
});
|
|
65
66
|
}
|
package/dist/spinner.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IconComponent } from './icon';
|
|
2
2
|
export interface SpinnerProps {
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/** The icon to rotate: an imported lucide component. Defaults to `LoaderCircle`. */
|
|
4
|
+
icon?: IconComponent;
|
|
5
5
|
color?: string;
|
|
6
6
|
size?: number;
|
|
7
7
|
className?: string;
|
|
8
8
|
"aria-label"?: string;
|
|
9
9
|
}
|
|
10
|
-
declare const Spinner: ({
|
|
10
|
+
declare const Spinner: ({ icon, ...props }: SpinnerProps) => import("react").JSX.Element;
|
|
11
11
|
export { Spinner };
|
package/dist/spinner.js
CHANGED
|
@@ -3,18 +3,19 @@
|
|
|
3
3
|
import { Icon } from "./icon.js";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
import styled, { keyframes } from "styled-components";
|
|
6
|
+
import { LoaderCircle } from "lucide-react";
|
|
6
7
|
//#region src/lib/spinner.tsx
|
|
7
8
|
var spin = keyframes([`0%{transform:rotate(0deg);}100%{transform:rotate(360deg);}`]);
|
|
8
9
|
var StyledSpinner = styled(Icon).withConfig({
|
|
9
10
|
displayName: "spinner__StyledSpinner",
|
|
10
|
-
componentId: "sc-
|
|
11
|
+
componentId: "sc-af2b088c-0"
|
|
11
12
|
})([
|
|
12
13
|
`color:`,
|
|
13
14
|
`;animation:`,
|
|
14
15
|
` 1s linear infinite;@media (prefers-reduced-motion:reduce){animation:none;}`
|
|
15
16
|
], ({ theme }) => theme.colors.dark, spin);
|
|
16
|
-
var Spinner = ({
|
|
17
|
-
|
|
17
|
+
var Spinner = ({ icon = LoaderCircle, ...props }) => /*#__PURE__*/ jsx(StyledSpinner, {
|
|
18
|
+
icon,
|
|
18
19
|
...props
|
|
19
20
|
});
|
|
20
21
|
//#endregion
|
package/dist/theme-toggle.js
CHANGED
|
@@ -6,10 +6,11 @@ import { Icon } from "./icon.js";
|
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { forwardRef, useContext, useEffect } from "react";
|
|
8
8
|
import styled, { css } from "styled-components";
|
|
9
|
+
import { MoonStar, Sun } from "lucide-react";
|
|
9
10
|
//#region src/lib/theme-toggle.tsx
|
|
10
11
|
var StyledThemeToggle = styled.button.withConfig({
|
|
11
12
|
displayName: "theme-toggle__StyledThemeToggle",
|
|
12
|
-
componentId: "sc-
|
|
13
|
+
componentId: "sc-85f678d3-0"
|
|
13
14
|
})([
|
|
14
15
|
``,
|
|
15
16
|
` `,
|
|
@@ -45,7 +46,7 @@ function LocalThemeToggle({ onClick, $shortcut = false, ...props }, ref) {
|
|
|
45
46
|
onClick?.(event);
|
|
46
47
|
},
|
|
47
48
|
ref,
|
|
48
|
-
children: [/*#__PURE__*/ jsx(Icon, {
|
|
49
|
+
children: [/*#__PURE__*/ jsx(Icon, { icon: Sun }), /*#__PURE__*/ jsx(Icon, { icon: MoonStar })]
|
|
49
50
|
});
|
|
50
51
|
}
|
|
51
52
|
var ThemeToggle = /*#__PURE__*/ forwardRef(LocalThemeToggle);
|
package/dist/toast.d.ts
CHANGED
|
@@ -27,14 +27,14 @@ interface ToastNotificationsProviderProps {
|
|
|
27
27
|
}
|
|
28
28
|
declare function ToastNotificationsProvider({ children, }: ToastNotificationsProviderProps): React.JSX.Element;
|
|
29
29
|
export declare const StyledNotifications: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Merged<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>, "style"> & {
|
|
30
|
-
style?: import('styled-components/dist/types').CSSPropertiesWithVars |
|
|
30
|
+
style?: React.CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars | undefined;
|
|
31
31
|
}, {
|
|
32
32
|
theme: Theme;
|
|
33
33
|
$align?: ToastAlign;
|
|
34
34
|
$bottom?: boolean;
|
|
35
35
|
}>> & string;
|
|
36
36
|
export declare const StyledNotificationItem: import('styled-components/dist/types').IStyledComponentBase<"web", import('styled-components/dist/types').Merged<Omit<React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "style"> & {
|
|
37
|
-
style?: import('styled-components/dist/types').CSSPropertiesWithVars |
|
|
37
|
+
style?: React.CSSProperties | import('styled-components/dist/types').CSSPropertiesWithVars | undefined;
|
|
38
38
|
}, {
|
|
39
39
|
theme: Theme;
|
|
40
40
|
$color: ToastColor;
|
package/dist/toast.js
CHANGED
|
@@ -5,12 +5,13 @@ import { IconButton } from "./icon-button.js";
|
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
7
7
|
import styled, { css } from "styled-components";
|
|
8
|
+
import { CircleCheck, CircleX, Info, TriangleAlert, X } from "lucide-react";
|
|
8
9
|
//#region src/lib/toast.tsx
|
|
9
10
|
var statusIcons = {
|
|
10
|
-
success:
|
|
11
|
-
error:
|
|
12
|
-
warning:
|
|
13
|
-
info:
|
|
11
|
+
success: CircleCheck,
|
|
12
|
+
error: CircleX,
|
|
13
|
+
warning: TriangleAlert,
|
|
14
|
+
info: Info
|
|
14
15
|
};
|
|
15
16
|
var EXIT_DURATION_MS = 400;
|
|
16
17
|
var ToastNotificationsContext = /*#__PURE__*/ createContext({
|
|
@@ -52,11 +53,11 @@ function ToastNotificationsProvider({ children }) {
|
|
|
52
53
|
}
|
|
53
54
|
var StyledNotifications = styled.ul.withConfig({
|
|
54
55
|
displayName: "toast__StyledNotifications",
|
|
55
|
-
componentId: "sc-
|
|
56
|
+
componentId: "sc-5ff21b00-0"
|
|
56
57
|
})([`position:fixed;z-index:99999;margin:0;padding:0;list-style:none;left:20px;right:20px;pointer-events:none;`, ``], ({ $bottom }) => $bottom ? css([`bottom:20px;`]) : css([`top:20px;`]));
|
|
57
58
|
var StyledNotificationItem = styled.li.withConfig({
|
|
58
59
|
displayName: "toast__StyledNotificationItem",
|
|
59
|
-
componentId: "sc-
|
|
60
|
+
componentId: "sc-5ff21b00-1"
|
|
60
61
|
})([
|
|
61
62
|
`display:grid;grid-template-rows:0fr;justify-items:center;margin:0;padding:0;opacity:0;pointer-events:none;transform:translateY(`,
|
|
62
63
|
`);transition:opacity 0.2s ease,transform 0.2s ease,grid-template-rows 0.25s ease 0.15s,margin 0.25s ease 0.15s;`,
|
|
@@ -126,7 +127,7 @@ function NotificationItem({ notification, $align, $bottom }) {
|
|
|
126
127
|
children: [
|
|
127
128
|
/*#__PURE__*/ jsx("span", {
|
|
128
129
|
className: "status-icon",
|
|
129
|
-
children: /*#__PURE__*/ jsx(Icon, {
|
|
130
|
+
children: /*#__PURE__*/ jsx(Icon, { icon: statusIcons[notification.color] ?? statusIcons.info })
|
|
130
131
|
}),
|
|
131
132
|
/*#__PURE__*/ jsx("span", {
|
|
132
133
|
className: "message",
|
|
@@ -137,7 +138,7 @@ function NotificationItem({ notification, $align, $bottom }) {
|
|
|
137
138
|
className: "close-button",
|
|
138
139
|
"aria-label": "Dismiss notification",
|
|
139
140
|
onClick: () => setPhase("exiting"),
|
|
140
|
-
children: /*#__PURE__*/ jsx(Icon, {
|
|
141
|
+
children: /*#__PURE__*/ jsx(Icon, { icon: X })
|
|
141
142
|
})
|
|
142
143
|
]
|
|
143
144
|
})
|
|
@@ -2,6 +2,46 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
import { useEffect, useRef } from "react";
|
|
4
4
|
//#region src/lib/utils/use-on-click-outside.tsx
|
|
5
|
+
var NATIVE_PICKER_SELECTOR = [
|
|
6
|
+
"select",
|
|
7
|
+
"input[type=\"date\"]",
|
|
8
|
+
"input[type=\"datetime-local\"]",
|
|
9
|
+
"input[type=\"month\"]",
|
|
10
|
+
"input[type=\"time\"]",
|
|
11
|
+
"input[type=\"week\"]"
|
|
12
|
+
].join(",");
|
|
13
|
+
var RECENT_PRESS_MS = 400;
|
|
14
|
+
var subscriberCount = 0;
|
|
15
|
+
var lastPressAt = Number.NEGATIVE_INFINITY;
|
|
16
|
+
var pickerBlurredAt = Number.NEGATIVE_INFINITY;
|
|
17
|
+
var capture = {
|
|
18
|
+
capture: true,
|
|
19
|
+
passive: true
|
|
20
|
+
};
|
|
21
|
+
function notePress() {
|
|
22
|
+
lastPressAt = performance.now();
|
|
23
|
+
}
|
|
24
|
+
function noteFocusOut(event) {
|
|
25
|
+
const target = event.target;
|
|
26
|
+
if (target instanceof Element && target.matches(NATIVE_PICKER_SELECTOR)) pickerBlurredAt = performance.now();
|
|
27
|
+
}
|
|
28
|
+
function subscribeToPresses() {
|
|
29
|
+
if (subscriberCount++ > 0) return;
|
|
30
|
+
document.addEventListener("pointerdown", notePress, capture);
|
|
31
|
+
document.addEventListener("touchstart", notePress, capture);
|
|
32
|
+
document.addEventListener("focusout", noteFocusOut, true);
|
|
33
|
+
}
|
|
34
|
+
function unsubscribeFromPresses() {
|
|
35
|
+
if (--subscriberCount > 0) return;
|
|
36
|
+
document.removeEventListener("pointerdown", notePress, capture);
|
|
37
|
+
document.removeEventListener("touchstart", notePress, capture);
|
|
38
|
+
document.removeEventListener("focusout", noteFocusOut, true);
|
|
39
|
+
}
|
|
40
|
+
function isStrayPickerEvent() {
|
|
41
|
+
const now = performance.now();
|
|
42
|
+
const active = document.activeElement;
|
|
43
|
+
return (active instanceof Element && active.matches(NATIVE_PICKER_SELECTOR) || now - pickerBlurredAt < RECENT_PRESS_MS) && now - lastPressAt >= RECENT_PRESS_MS;
|
|
44
|
+
}
|
|
5
45
|
function useOnClickOutside(refs, cb) {
|
|
6
46
|
const latest = useRef({
|
|
7
47
|
refs,
|
|
@@ -16,11 +56,14 @@ function useOnClickOutside(refs, cb) {
|
|
|
16
56
|
useEffect(() => {
|
|
17
57
|
function handleClickOutside(event) {
|
|
18
58
|
const { refs, cb } = latest.current;
|
|
59
|
+
if (isStrayPickerEvent()) return;
|
|
19
60
|
if (refs.every((ref) => !ref.current || !ref.current.contains(event.target))) cb();
|
|
20
61
|
}
|
|
62
|
+
subscribeToPresses();
|
|
21
63
|
document.addEventListener("mousedown", handleClickOutside);
|
|
22
64
|
return () => {
|
|
23
65
|
document.removeEventListener("mousedown", handleClickOutside);
|
|
66
|
+
unsubscribeFromPresses();
|
|
24
67
|
};
|
|
25
68
|
}, []);
|
|
26
69
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cherry-styled-components",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.17",
|
|
4
4
|
"description": "Cherry is a design system for the modern web. Designed in Figma, built in React using Typescript.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -10,6 +10,14 @@
|
|
|
10
10
|
".": {
|
|
11
11
|
"types": "./dist/index.d.ts",
|
|
12
12
|
"import": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./next": {
|
|
15
|
+
"types": "./dist/styled-components/registry.d.ts",
|
|
16
|
+
"import": "./dist/styled-components/registry.js"
|
|
17
|
+
},
|
|
18
|
+
"./dynamic": {
|
|
19
|
+
"types": "./dist/icon-dynamic.d.ts",
|
|
20
|
+
"import": "./dist/icon-dynamic.js"
|
|
13
21
|
}
|
|
14
22
|
},
|
|
15
23
|
"files": [
|
|
@@ -20,7 +28,7 @@
|
|
|
20
28
|
"homepage": "https://cherry.al",
|
|
21
29
|
"repository": "https://github.com/cherry-design-system/styled-components",
|
|
22
30
|
"license": "MIT",
|
|
23
|
-
"packageManager": "pnpm@
|
|
31
|
+
"packageManager": "pnpm@12.3.4",
|
|
24
32
|
"engines": {
|
|
25
33
|
"node": ">=18.0.0"
|
|
26
34
|
},
|
|
@@ -44,33 +52,32 @@
|
|
|
44
52
|
"format:check": "prettier --check .",
|
|
45
53
|
"screenshots": "node scripts/screenshot-previews.cjs"
|
|
46
54
|
},
|
|
47
|
-
"dependencies": {
|
|
48
|
-
"lucide-react": "^1.28.0"
|
|
49
|
-
},
|
|
50
55
|
"peerDependencies": {
|
|
56
|
+
"lucide-react": "^1.31.0",
|
|
51
57
|
"react": "^18.0.0 || ^19.0.0",
|
|
52
58
|
"react-dom": "^18.0.0 || ^19.0.0",
|
|
53
59
|
"styled-components": "^6.0.0"
|
|
54
60
|
},
|
|
55
61
|
"devDependencies": {
|
|
56
|
-
"@swc/plugin-styled-components": "^
|
|
57
|
-
"@types/node": "^26.1
|
|
62
|
+
"@swc/plugin-styled-components": "^14.0.0",
|
|
63
|
+
"@types/node": "^26.4.1",
|
|
58
64
|
"@types/react": "^19.2.18",
|
|
59
|
-
"@types/react-dom": "^19.2.
|
|
65
|
+
"@types/react-dom": "^19.2.7",
|
|
60
66
|
"@typescript/typescript6": "^6.0.2",
|
|
61
67
|
"@vitejs/plugin-react-swc": "^4.3.3",
|
|
62
68
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
63
|
-
"eslint-plugin-react-refresh": "^0.5.
|
|
64
|
-
"
|
|
65
|
-
"
|
|
69
|
+
"eslint-plugin-react-refresh": "^0.5.6",
|
|
70
|
+
"lucide-react": "^1.41.0",
|
|
71
|
+
"next": "^16.3.4",
|
|
72
|
+
"playwright-core": "^1.63.0",
|
|
66
73
|
"prettier": "^3.9.6",
|
|
67
74
|
"react": "^19.2.8",
|
|
68
75
|
"react-dom": "^19.2.8",
|
|
69
76
|
"rollup-plugin-preserve-directives": "^0.4.0",
|
|
70
|
-
"sharp": "^0.35.
|
|
71
|
-
"styled-components": "^6.5.
|
|
77
|
+
"sharp": "^0.35.4",
|
|
78
|
+
"styled-components": "^6.5.3",
|
|
72
79
|
"typescript": "^7.0.2",
|
|
73
|
-
"vite": "^8.2.
|
|
74
|
-
"vite-plugin-dts": "^5.0
|
|
80
|
+
"vite": "^8.2.2",
|
|
81
|
+
"vite-plugin-dts": "^5.1.0"
|
|
75
82
|
}
|
|
76
83
|
}
|