cherry-styled-components 0.2.3 → 0.2.4

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.
@@ -5,7 +5,8 @@ export interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonEl
5
5
  "aria-label": string;
6
6
  $size?: "default" | "big" | "small";
7
7
  $error?: boolean;
8
+ $active?: boolean;
8
9
  }
9
- export declare const iconButtonStyles: (theme: Theme, $size?: "default" | "big" | "small", $error?: boolean, disabled?: boolean) => import('styled-components').RuleSet<object>;
10
+ export declare const iconButtonStyles: (theme: Theme, $size?: "default" | "big" | "small", $error?: boolean, disabled?: boolean, $active?: boolean) => import('styled-components').RuleSet<object>;
10
11
  declare const IconButton: React.ForwardRefExoticComponent<IconButtonProps & React.RefAttributes<HTMLButtonElement>>;
11
12
  export { IconButton };
@@ -4,7 +4,7 @@ import { resetButton } from "./utils/mixins.js";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  import { forwardRef } from "react";
6
6
  import styled, { css } from "styled-components";
7
- import { darken, lighten } from "polished";
7
+ import { darken, lighten, rgba } from "polished";
8
8
  //#region src/lib/icon-button.tsx
9
9
  var iconButtonSizes = {
10
10
  small: {
@@ -20,11 +20,11 @@ var iconButtonSizes = {
20
20
  icon: 16
21
21
  }
22
22
  };
23
- var iconButtonStyles = (theme, $size, $error, disabled) => {
23
+ var iconButtonStyles = (theme, $size, $error, disabled, $active) => {
24
24
  const { box, icon } = iconButtonSizes[$size ?? "default"];
25
25
  return css([
26
26
  ``,
27
- `;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:`,
27
+ `;display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;position:relative;width:`,
28
28
  `px;height:`,
29
29
  `px;border-radius:50%;background:`,
30
30
  `;border:solid 2px `,
@@ -34,6 +34,7 @@ var iconButtonStyles = (theme, $size, $error, disabled) => {
34
34
  `px;height:`,
35
35
  `px;}`,
36
36
  ` `,
37
+ ` `,
37
38
  ``
38
39
  ], resetButton, box, box, theme.colors.light, theme.colors.grayLight, $error ? theme.colors.error : theme.colors.grayDark, $error ? lighten(.1, theme.colors.error) : theme.colors.primaryLight, icon, icon, !disabled && ($error ? css([
39
40
  `border-color:`,
@@ -49,7 +50,12 @@ var iconButtonStyles = (theme, $size, $error, disabled) => {
49
50
  `;border-color:`,
50
51
  `;}&:active{box-shadow:0 0 0 2px `,
51
52
  `;}`
52
- ], theme.colors.primary, theme.colors.primary, theme.colors.primaryLight, theme.colors.primary, theme.colors.primaryLight)), disabled && css([
53
+ ], theme.colors.primary, theme.colors.primary, theme.colors.primaryLight, theme.colors.primary, theme.colors.primaryLight)), !disabled && $active && css([
54
+ `border-color:`,
55
+ `;background:`,
56
+ `;color:`,
57
+ `;`
58
+ ], theme.colors.primary, rgba(theme.colors.primary, theme.isDark ? .18 : .1), theme.colors.primary), disabled && css([
53
59
  `cursor:not-allowed;background:`,
54
60
  `;border-color:`,
55
61
  `;color:`,
@@ -58,11 +64,12 @@ var iconButtonStyles = (theme, $size, $error, disabled) => {
58
64
  };
59
65
  var StyledIconButton = styled.button.withConfig({
60
66
  displayName: "icon-button__StyledIconButton",
61
- componentId: "sc-def35ae6-0"
62
- })([``, ``], ({ theme, $size, $error, disabled }) => iconButtonStyles(theme, $size, $error, disabled));
67
+ componentId: "sc-e26e58e2-0"
68
+ })([``, ``], ({ theme, $size, $error, disabled, $active }) => iconButtonStyles(theme, $size, $error, disabled, $active));
63
69
  function LocalIconButton({ ...props }, ref) {
64
70
  return /*#__PURE__*/ jsx(StyledIconButton, {
65
71
  type: "button",
72
+ "aria-pressed": props.$active === void 0 ? void 0 : props.$active,
66
73
  ...props,
67
74
  ref
68
75
  });
package/dist/index.d.ts CHANGED
@@ -18,6 +18,7 @@ export * from './password';
18
18
  export * from './range';
19
19
  export * from './select';
20
20
  export * from './space';
21
+ export * from './tabs';
21
22
  export * from './textarea';
22
23
  export * from './theme-toggle';
23
24
  export * from './toast';
package/dist/index.js CHANGED
@@ -26,8 +26,9 @@ import { Password } from "./password.js";
26
26
  import { Range } from "./range.js";
27
27
  import { Select, StyledIconWrapper } from "./select.js";
28
28
  import { Space } from "./space.js";
29
+ import { TabContent, Tabs } from "./tabs.js";
29
30
  import { Textarea } from "./textarea.js";
30
31
  import { ThemeToggle } from "./theme-toggle.js";
31
32
  import { StyledNotificationItem, StyledNotifications, ToastNotifications, ToastNotificationsContext, ToastNotificationsProvider, useToastNotifications } from "./toast.js";
32
33
  import { Toggle } from "./toggle.js";
33
- export { Accordion, AvatarDropzone, Box, Button, CherryThemeProvider, ClientThemeProvider, Col, Container, Dropzone, Flex, GlobalStyles, Grid, Icon, IconArrow, IconButton, IconCalendar, IconCheck, Input, MaxWidth, Modal, Password, Range, Select, Space, StyledComponentsRegistry, StyledIconWrapper, StyledInputWrapper, StyledLabel, StyledNotificationItem, StyledNotifications, Textarea, ThemeContext, ThemeToggle, ToastNotifications, ToastNotificationsContext, ToastNotificationsProvider, Toggle, 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, 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, useOnClickOutside, useToastNotifications };
34
+ export { Accordion, AvatarDropzone, Box, Button, CherryThemeProvider, ClientThemeProvider, Col, Container, Dropzone, Flex, GlobalStyles, Grid, Icon, IconArrow, IconButton, IconCalendar, IconCheck, Input, MaxWidth, Modal, Password, Range, Select, Space, StyledComponentsRegistry, StyledIconWrapper, StyledInputWrapper, StyledLabel, StyledNotificationItem, StyledNotifications, TabContent, Tabs, Textarea, ThemeContext, ThemeToggle, ToastNotifications, ToastNotificationsContext, ToastNotificationsProvider, Toggle, 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, 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, useOnClickOutside, useToastNotifications };
package/dist/tabs.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { default as React } from 'react';
2
+ export interface TabContentProps {
3
+ title: string;
4
+ children: React.ReactNode;
5
+ }
6
+ declare function TabContent({ children }: TabContentProps): React.JSX.Element;
7
+ export interface TabsProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange"> {
8
+ children: React.ReactNode;
9
+ onTabChange?: (index: number) => void;
10
+ defaultActiveTab?: number;
11
+ activeTab?: number;
12
+ }
13
+ declare function Tabs({ children, onTabChange, defaultActiveTab, activeTab, ...rest }: TabsProps): React.JSX.Element;
14
+ export { Tabs, TabContent };
package/dist/tabs.js ADDED
@@ -0,0 +1,120 @@
1
+ "use client";
2
+ "use client";
3
+ import { resetButton } from "./utils/mixins.js";
4
+ import { styledText } from "./utils/typography.js";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ import React, { useId, useRef, useState } from "react";
7
+ import styled, { css } from "styled-components";
8
+ import { rgba } from "polished";
9
+ //#region src/lib/tabs.tsx
10
+ var StyledTabs = styled.div.withConfig({
11
+ displayName: "tabs__StyledTabs",
12
+ componentId: "sc-7af80746-0"
13
+ })([`width:100%;`]);
14
+ var StyledTabsList = styled.div.withConfig({
15
+ displayName: "tabs__StyledTabsList",
16
+ componentId: "sc-7af80746-1"
17
+ })([
18
+ `display:flex;overflow-x:auto;border-radius:`,
19
+ ` `,
20
+ ` 0 0;background:`,
21
+ `;border:solid 1px `,
22
+ `;`
23
+ ], ({ theme }) => theme.spacing.radius.lg, ({ theme }) => theme.spacing.radius.lg, ({ theme }) => theme.colors.light, ({ theme }) => theme.colors.grayLight);
24
+ var StyledTabButton = styled.button.withConfig({
25
+ displayName: "tabs__StyledTabButton",
26
+ componentId: "sc-7af80746-2"
27
+ })([
28
+ ``,
29
+ `;flex:1;min-width:fit-content;padding:12px 20px;`,
30
+ `;font-weight:600;color:`,
31
+ `;border-bottom:solid 3px transparent;transition:color 0.2s ease,background 0.2s ease,border-color 0.2s ease;@media (prefers-reduced-motion:reduce){transition:none;}&:not(:last-child){border-right:solid 1px `,
32
+ `;}&:focus-visible{border-radius:`,
33
+ `;outline:solid 2px `,
34
+ `;outline-offset:-4px;border-bottom-color:transparent;}`,
35
+ ``
36
+ ], resetButton, ({ theme }) => styledText(theme), ({ theme }) => theme.colors.dark, ({ theme }) => theme.colors.grayLight, ({ theme }) => theme.spacing.radius.xs, ({ theme }) => theme.colors.primary, ({ theme, $isActive }) => $isActive ? css([
37
+ `color:`,
38
+ `;border-bottom-color:`,
39
+ `;`
40
+ ], theme.colors.primary, theme.colors.primary) : css([
41
+ `@media (hover:hover){&:hover{color:`,
42
+ `;background:`,
43
+ `;}}`
44
+ ], theme.colors.primary, rgba(theme.colors.primaryLight, .1)));
45
+ var StyledTabPanel = styled.div.withConfig({
46
+ displayName: "tabs__StyledTabPanel",
47
+ componentId: "sc-7af80746-3"
48
+ })([
49
+ ``,
50
+ `;color:`,
51
+ `;background:`,
52
+ `;padding:20px;border:solid 1px `,
53
+ `;border-top:none;border-radius:0 0 `,
54
+ ` `,
55
+ `;`
56
+ ], ({ theme }) => styledText(theme), ({ theme }) => theme.colors.grayDark, ({ theme }) => theme.colors.light, ({ theme }) => theme.colors.grayLight, ({ theme }) => theme.spacing.radius.lg, ({ theme }) => theme.spacing.radius.lg);
57
+ function TabContent({ children }) {
58
+ return /*#__PURE__*/ jsx(Fragment, { children });
59
+ }
60
+ function Tabs({ children, onTabChange, defaultActiveTab, activeTab, ...rest }) {
61
+ const [internalActive, setInternalActive] = useState(defaultActiveTab ?? 0);
62
+ const isControlled = activeTab !== void 0;
63
+ const baseId = useId();
64
+ const tabRefs = useRef([]);
65
+ const tabs = React.Children.toArray(children).filter((child) => /*#__PURE__*/ React.isValidElement(child) && typeof child.props.title === "string" && child.props.title.trim() !== "");
66
+ const active = Math.min(isControlled ? activeTab : internalActive, Math.max(tabs.length - 1, 0));
67
+ const selectTab = (index) => {
68
+ if (!isControlled) setInternalActive(index);
69
+ onTabChange?.(index);
70
+ };
71
+ const handleKeyDown = (event) => {
72
+ let next;
73
+ switch (event.key) {
74
+ case "ArrowRight":
75
+ next = (active + 1) % tabs.length;
76
+ break;
77
+ case "ArrowLeft":
78
+ next = (active - 1 + tabs.length) % tabs.length;
79
+ break;
80
+ case "Home":
81
+ next = 0;
82
+ break;
83
+ case "End":
84
+ next = tabs.length - 1;
85
+ break;
86
+ default: return;
87
+ }
88
+ event.preventDefault();
89
+ selectTab(next);
90
+ tabRefs.current[next]?.focus();
91
+ };
92
+ return /*#__PURE__*/ jsxs(StyledTabs, {
93
+ ...rest,
94
+ children: [/*#__PURE__*/ jsx(StyledTabsList, {
95
+ role: "tablist",
96
+ onKeyDown: handleKeyDown,
97
+ children: tabs.map((tab, index) => /*#__PURE__*/ jsx(StyledTabButton, {
98
+ type: "button",
99
+ role: "tab",
100
+ id: `${baseId}-tab-${index}`,
101
+ "aria-selected": index === active,
102
+ "aria-controls": `${baseId}-panel-${index}`,
103
+ tabIndex: index === active ? 0 : -1,
104
+ $isActive: index === active,
105
+ ref: (node) => {
106
+ tabRefs.current[index] = node;
107
+ },
108
+ onClick: () => selectTab(index),
109
+ children: tab.props.title
110
+ }, index))
111
+ }), /*#__PURE__*/ jsx(StyledTabPanel, {
112
+ role: "tabpanel",
113
+ id: `${baseId}-panel-${active}`,
114
+ "aria-labelledby": `${baseId}-tab-${active}`,
115
+ children: tabs[active]?.props.children
116
+ })]
117
+ });
118
+ }
119
+ //#endregion
120
+ export { TabContent, Tabs };
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  "use client";
3
- import { resetButton } from "./utils/mixins.js";
3
+ import { interactiveStyles, resetButton } from "./utils/mixins.js";
4
4
  import { ThemeContext } from "./styled-components/theme-provider.js";
5
5
  import { Icon } from "./icon.js";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -10,19 +10,19 @@ import { rgba } from "polished";
10
10
  //#region src/lib/theme-toggle.tsx
11
11
  var StyledThemeToggle = styled.button.withConfig({
12
12
  displayName: "theme-toggle__StyledThemeToggle",
13
- componentId: "sc-cc0c1ca5-0"
13
+ componentId: "sc-fe6f1d3-0"
14
14
  })([
15
15
  ``,
16
- ` width:56px;height:30px;border-radius:30px;display:flex;position:relative;margin:auto 0;transform:scale(1);background:`,
17
- `;border:1px solid `,
18
- `;transition:all 0.3s ease;&::after{content:"";position:absolute;top:2px;left:2px;width:24px;height:24px;border-radius:50%;background:`,
16
+ ` `,
17
+ ` width:56px;height:30px;border-radius:30px;display:flex;align-items:center;justify-content:space-between;padding:0 6px;position:relative;margin:auto 0;background:`,
18
+ `;border-color:`,
19
+ `;&::after{content:"";position:absolute;top:2px;left:2px;width:24px;height:24px;border-radius:50%;background:`,
19
20
  `;transition:all 0.3s ease;z-index:1;`,
20
21
  `}`,
21
- ` & svg{width:16px;height:16px;object-fit:contain;margin:auto;transition:all 0.3s ease;position:relative;z-index:2;}& .lucide-sun{transform:translateX(1px);}& svg[stroke]{stroke:`,
22
- `;}&:hover{transform:scale(1.05);color:`,
23
- `;& svg[stroke]{stroke:`,
24
- `;}}&:active{transform:scale(0.97);}`
25
- ], resetButton, ({ theme }) => theme.colors.light, ({ theme }) => theme.colors.grayLight, ({ theme }) => rgba(theme.colors.primaryLight, .2), ({ theme }) => theme.isDark && css([`transform:translateX(26px);`]), ({ $hidden }) => $hidden && css([`display:none;`]), ({ theme }) => theme.colors.primary, ({ theme }) => theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark, ({ theme }) => theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark);
22
+ ` & svg{width:16px;height:16px;object-fit:contain;transition:all 0.3s ease;position:relative;z-index:2;}& svg[stroke]{stroke:`,
23
+ `;}@media (hover:hover){&:hover svg[stroke]{stroke:`,
24
+ `;}}`
25
+ ], resetButton, interactiveStyles, ({ theme }) => theme.colors.light, ({ theme }) => theme.colors.grayLight, ({ theme }) => rgba(theme.colors.primaryLight, .2), ({ theme }) => theme.isDark && css([`transform:translateX(26px);`]), ({ $hidden }) => $hidden && css([`display:none;`]), ({ theme }) => theme.colors.primary, ({ theme }) => theme.isDark ? theme.colors.primaryLight : theme.colors.primaryDark);
26
26
  function LocalThemeToggle({ onClick, ...props }, ref) {
27
27
  const { toggleTheme } = useContext(ThemeContext);
28
28
  return /*#__PURE__*/ jsxs(StyledThemeToggle, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cherry-styled-components",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
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",