@dust-tt/sparkle 0.1.2 → 0.1.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dust-tt/sparkle",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "scripts": {
5
5
  "build": "rollup -c"
6
6
  },
@@ -1,20 +1,33 @@
1
- import React, { MouseEvent } from "react";
2
-
3
- import { classNames } from "../lib/utils";
1
+ import React, { MouseEvent, ComponentType } from "react";
2
+ import { classNames } from "@sparkle/lib/utils";
3
+ import { Icon } from "./Icon";
4
4
 
5
5
  type ButtonProps = {
6
- type?: "primary" | "secondary";
6
+ type?: "primary" | "secondary" | "tertiary";
7
7
  size?: "xs" | "sm" | "md";
8
8
  onClick?: (event: MouseEvent<HTMLButtonElement>) => void;
9
9
  disabled?: boolean;
10
10
  label: string;
11
+ icon?: ComponentType;
11
12
  className?: string;
12
13
  };
13
14
 
14
15
  const sizeClasses = {
15
- xs: "px-2.5 py-1.5 text-xs font-medium rounded-md",
16
- sm: "px-3 py-2 text-xs font-bold rounded-lg",
17
- md: "px-4 py-3 text-sm font-bold rounded-xl",
16
+ xs: "gap-x-1 px-3 py-1.5 text-xs font-semibold",
17
+ sm: "gap-x-1 px-4 py-2 text-sm font-semibold",
18
+ md: "gap-x-1.5 px-5 py-3 text-sm font-bold",
19
+ };
20
+
21
+ const containerClasses = {
22
+ xs: "px-0.5",
23
+ sm: "px-1",
24
+ md: "px-1",
25
+ };
26
+
27
+ const iconSizeClasses = {
28
+ xs: "h-4 w-4",
29
+ sm: "h-5 w-5",
30
+ md: "h-5 w-5",
18
31
  };
19
32
 
20
33
  const typeClasses = {
@@ -30,11 +43,22 @@ const typeClasses = {
30
43
  },
31
44
  },
32
45
  secondary: {
33
- base: "text-action-500 border-structure-200",
46
+ base: "text-action-500 border-structure-300 bg-structure-0",
34
47
  hover: "hover:bg-action-50 hover:border-action-300",
35
48
  active: "active:bg-action-100 active:border-action-500",
36
49
  dark: {
37
- base: "dark:text-action-500-dark dark:border-structure-300-dark",
50
+ base: "dark:text-action-500-dark dark:border-structure-300-dark dark:bg-structure-50-dark",
51
+ hover: "dark:hover:bg-action-50-dark dark:hover:border-action-300-dark",
52
+ active:
53
+ "dark:active:bg-action-100-dark dark:active:border-action-500-dark",
54
+ },
55
+ },
56
+ tertiary: {
57
+ base: "text-element-700 border-structure-300 bg-structure-0",
58
+ hover: "hover:text-element-800 hover:bg-action-50 hover:border-action-300",
59
+ active: "active:bg-action-100 active:border-action-500",
60
+ dark: {
61
+ base: "dark:text-element-700-dark dark:border-structure-300-dark dark:bg-structure-50-dark",
38
62
  hover: "dark:hover:bg-action-50-dark dark:hover:border-action-300-dark",
39
63
  active:
40
64
  "dark:active:bg-action-100-dark dark:active:border-action-500-dark",
@@ -48,10 +72,11 @@ export function Button({
48
72
  onClick,
49
73
  disabled = false,
50
74
  label,
75
+ icon,
51
76
  className = "",
52
77
  }: ButtonProps) {
53
78
  const buttonClasses = classNames(
54
- "inline-flex items-center border-2 transition-colors duration-200",
79
+ "inline-flex items-center border transition-all ease-out duration-400 box-border rounded-full scale-95 hover:scale-100 hover:drop-shadow-md active:scale-95 active:drop-shadow-none",
55
80
  sizeClasses[size],
56
81
  typeClasses[type]?.base,
57
82
  typeClasses[type]?.hover,
@@ -63,6 +88,9 @@ export function Button({
63
88
  className
64
89
  );
65
90
 
91
+ const iconClasses = classNames(iconSizeClasses[size]);
92
+ const finalContainerClasses = classNames(containerClasses[size]);
93
+
66
94
  return (
67
95
  <button
68
96
  type="button"
@@ -71,7 +99,8 @@ export function Button({
71
99
  disabled={disabled}
72
100
  aria-label={label}
73
101
  >
74
- {label}
102
+ {icon && <Icon IconComponent={icon} className={iconClasses} />}
103
+ <div className={finalContainerClasses}>{label}</div>
75
104
  </button>
76
105
  );
77
106
  }
@@ -1,16 +1,17 @@
1
1
  import { ReactComponentLike } from "prop-types";
2
2
  import React, { MouseEvent } from "react";
3
3
 
4
+ import { SparkleContext } from "@sparkle/context";
4
5
  import { classNames } from "@sparkle/lib/utils";
5
6
 
6
7
  type TabProps = {
7
8
  tabs: Array<{
8
9
  label: string;
9
10
  hideLabel?: boolean;
10
- href: string;
11
11
  current: boolean;
12
12
  sizing?: "hug" | "expand";
13
13
  icon?: ReactComponentLike;
14
+ href?: string;
14
15
  }>;
15
16
  onTabClick?: (tabName: string, event: MouseEvent<HTMLAnchorElement>) => void;
16
17
  className?: string;
@@ -18,15 +19,15 @@ type TabProps = {
18
19
 
19
20
  const tabClasses = {
20
21
  default: {
21
- base: "text-element-800 border-transparent",
22
- hover: "hover:text-action-600",
22
+ base: "text-element-800 border-transparent cursor-pointer",
23
+ hover: "hover:text-action-500",
23
24
  dark: {
24
- base: "dark:text-element-800-dark",
25
+ base: "dark:text-element-700-dark",
25
26
  hover: "dark:hover:text-action-600-dark",
26
27
  },
27
28
  },
28
29
  selected: {
29
- base: "border-action-500 text-action-600 cursor-default",
30
+ base: "border-action-500 text-action-500 cursor-default",
30
31
  hover: "",
31
32
  dark: {
32
33
  base: "dark:border-action-500-dark dark:text-action-500-dark",
@@ -38,17 +39,17 @@ const tabClasses = {
38
39
  const iconClasses = {
39
40
  default: {
40
41
  base: "text-element-600",
41
- hover: "group-hover:text-action-400 group-hover:text-action-400",
42
+ hover: "group-hover:text-action-400",
42
43
  dark: {
43
44
  base: "dark:text-element-600-dark",
44
- hover: "dark:group-hover:text-action-400-dark",
45
+ hover: "dark:group-hover:text-action-500-dark",
45
46
  },
46
47
  },
47
48
  selected: {
48
- base: "text-action-400",
49
+ base: "text-action-500",
49
50
  hover: "",
50
51
  dark: {
51
- base: "dark:text-action-400-dark",
52
+ base: "dark:text-action-500-dark",
52
53
  hover: "",
53
54
  },
54
55
  },
@@ -60,6 +61,9 @@ const tabSizingClasses = {
60
61
  };
61
62
 
62
63
  export function Tab({ tabs, onTabClick, className = "" }: TabProps) {
64
+ const { components } = React.useContext(SparkleContext);
65
+ const Link = components.link;
66
+
63
67
  const renderTabs = () =>
64
68
  tabs.map((tab) => {
65
69
  const tabStateClasses = tab.current
@@ -70,31 +74,43 @@ export function Tab({ tabs, onTabClick, className = "" }: TabProps) {
70
74
  : iconClasses.default;
71
75
 
72
76
  const finalTabClasses = classNames(
73
- "group justify-center flex gap-x-2 text-sm font-medium px-4 py-3 border-b-2 transition-colors duration-200 whitespace-nowrap",
77
+ "group justify-center flex text-sm font-semibold px-4 py-3 border-b-2 transition-colors duration-400 whitespace-nowrap select-none",
74
78
  tabStateClasses.base,
75
79
  tabStateClasses.hover,
80
+ tabStateClasses.dark.base,
81
+ tabStateClasses.dark.hover,
76
82
  tabSizingClasses[tab.sizing ?? "hug"],
77
83
  className
78
84
  );
79
85
 
80
86
  const finalIconClasses = classNames(
81
- "h-5 w-5",
87
+ "h-5 w-5 transition-colors duration-400",
82
88
  iconStateClasses.base,
83
89
  iconStateClasses.hover,
90
+ iconStateClasses.dark.base,
91
+ iconStateClasses.dark.hover,
84
92
  className
85
93
  );
86
94
 
87
95
  return (
88
- <a
96
+ <Link
89
97
  key={tab.label}
90
- href={tab.href}
91
98
  className={finalTabClasses}
92
99
  aria-current={tab.current ? "page" : undefined}
93
100
  onClick={(event) => onTabClick?.(tab.label, event)}
101
+ href={tab.href}
94
102
  >
95
- {tab.icon && <tab.icon className={finalIconClasses} />}
96
- {tab.hideLabel ?? tab.label}
97
- </a>
103
+ <div
104
+ className={
105
+ tab.current
106
+ ? "flex gap-x-2"
107
+ : "duration-400 flex scale-100 transform gap-x-2 transition-transform ease-out group-hover:scale-110"
108
+ }
109
+ >
110
+ {tab.icon && <tab.icon className={finalIconClasses} />}
111
+ {tab.hideLabel ?? tab.label}
112
+ </div>
113
+ </Link>
98
114
  );
99
115
  });
100
116
 
@@ -0,0 +1,22 @@
1
+ import React, { ComponentType, MouseEvent, ReactNode } from "react";
2
+
3
+ export type SparkleContextType = {
4
+ components: {
5
+ link: ComponentType<{
6
+ href?: string;
7
+ className?: string;
8
+ children: ReactNode;
9
+ onClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
10
+ }>;
11
+ };
12
+ };
13
+
14
+ export const SparkleContext = React.createContext<SparkleContextType>({
15
+ components: {
16
+ link: ({ href, className, children }) => (
17
+ <a href={href} className={className}>
18
+ {children}
19
+ </a>
20
+ ),
21
+ },
22
+ });
@@ -14,16 +14,16 @@ module.exports = {
14
14
  dark: colors.emerald[500],
15
15
  },
16
16
  action: {
17
+ 950: { DEFAULT: colors.blue[950], dark: colors.blue[50] },
18
+ 900: { DEFAULT: colors.blue[900], dark: colors.blue[100] },
19
+ 800: { DEFAULT: colors.blue[800], dark: colors.blue[200] },
20
+ 700: { DEFAULT: colors.blue[700], dark: colors.blue[300] },
21
+ 600: { DEFAULT: colors.blue[600], dark: colors.blue[400] },
17
22
  500: { DEFAULT: colors.blue[500], dark: colors.blue[500] },
18
23
  400: { DEFAULT: colors.blue[400], dark: colors.blue[600] },
19
24
  200: { DEFAULT: colors.blue[200], dark: colors.blue[800] },
20
25
  300: { DEFAULT: colors.blue[300], dark: colors.blue[700] },
21
26
  100: { DEFAULT: colors.blue[100], dark: colors.blue[900] },
22
- 600: { DEFAULT: colors.blue[600], dark: colors.blue[400] },
23
- 700: { DEFAULT: colors.blue[700], dark: colors.blue[300] },
24
- 800: { DEFAULT: colors.blue[800], dark: colors.blue[200] },
25
- 900: { DEFAULT: colors.blue[900], dark: colors.blue[100] },
26
- 950: { DEFAULT: colors.blue[950], dark: colors.blue[50] },
27
27
  50: { DEFAULT: colors.blue[50], dark: colors.blue[950] },
28
28
  },
29
29
  success: {
@@ -43,15 +43,15 @@ module.exports = {
43
43
  },
44
44
  element: {
45
45
  900: { DEFAULT: colors.slate[900], dark: colors.slate[50] },
46
- 800: { DEFAULT: colors.slate[800], dark: colors.slate[200] },
46
+ 800: { DEFAULT: colors.slate[700], dark: colors.slate[200] },
47
47
  700: { DEFAULT: colors.slate[500], dark: colors.slate[300] },
48
- 500: { DEFAULT: colors.slate[300], dark: colors.slate[500] },
49
48
  600: { DEFAULT: colors.slate[400], dark: colors.slate[400] },
49
+ 500: { DEFAULT: colors.slate[300], dark: colors.slate[500] },
50
50
  },
51
51
  },
52
52
  },
53
53
  },
54
- darkMode: "media",
54
+ darkMode: "class",
55
55
  variants: {
56
56
  extend: {
57
57
  backgroundColor: ["dark"],