@dust-tt/sparkle 0.1.5 → 0.1.7
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/.rollup.cache/home/spolu/code/dust/sparkle/dist/components/Button.d.ts +1 -1
- package/.rollup.cache/home/spolu/code/dust/sparkle/dist/components/Button.js.map +1 -1
- package/.rollup.cache/home/spolu/code/dust/sparkle/dist/components/Item.d.ts +13 -0
- package/.rollup.cache/home/spolu/code/dust/sparkle/dist/components/Item.js +63 -0
- package/.rollup.cache/home/spolu/code/dust/sparkle/dist/components/Item.js.map +1 -0
- package/.rollup.cache/home/spolu/code/dust/sparkle/dist/components/Tab.js +5 -3
- package/.rollup.cache/home/spolu/code/dust/sparkle/dist/components/Tab.js.map +1 -1
- package/.rollup.cache/home/spolu/code/dust/sparkle/dist/context.d.ts +12 -6
- package/.rollup.cache/home/spolu/code/dust/sparkle/dist/context.js +9 -4
- package/.rollup.cache/home/spolu/code/dust/sparkle/dist/context.js.map +1 -1
- package/.rollup.cache/home/spolu/code/dust/sparkle/dist/index.d.ts +2 -0
- package/.rollup.cache/home/spolu/code/dust/sparkle/dist/index.js +2 -0
- package/.rollup.cache/home/spolu/code/dust/sparkle/dist/index.js.map +1 -1
- package/dist/cjs/components/Button.d.ts +1 -1
- package/dist/cjs/components/Item.d.ts +13 -0
- package/dist/cjs/context.d.ts +12 -6
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +85 -19
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/components/Button.d.ts +1 -1
- package/dist/esm/components/Item.d.ts +13 -0
- package/dist/esm/context.d.ts +12 -6
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +85 -20
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Button.tsx +3 -1
- package/src/components/Item.tsx +122 -0
- package/src/components/Tab.tsx +10 -3
- package/src/context.tsx +60 -11
- package/src/index.ts +3 -0
package/package.json
CHANGED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import React, { ComponentType, MouseEvent } from "react";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
noHrefLink,
|
|
5
|
+
SparkleContext,
|
|
6
|
+
SparkleContextLinkType,
|
|
7
|
+
} from "@sparkle/context";
|
|
8
|
+
import { ChevronRight } from "@sparkle/icons/mini";
|
|
9
|
+
import { classNames } from "@sparkle/lib/utils";
|
|
10
|
+
|
|
11
|
+
import { Icon } from "./Icon";
|
|
12
|
+
|
|
13
|
+
type ItemProps = {
|
|
14
|
+
onClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
|
|
15
|
+
size?: "sm" | "md";
|
|
16
|
+
selected?: boolean;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
label: string;
|
|
19
|
+
icon?: ComponentType;
|
|
20
|
+
className?: string;
|
|
21
|
+
href?: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const baseClasses =
|
|
25
|
+
"group inline-flex transition-color ease-out duration-400 box-border gap-x-2 py-3 text-sm font-semibold";
|
|
26
|
+
|
|
27
|
+
const iconBaseClasses = "h-5 w-5 transition-color ease-out duration-400";
|
|
28
|
+
|
|
29
|
+
const iconClasses = {
|
|
30
|
+
default: {
|
|
31
|
+
base: "h-5 w-5 text-element-700",
|
|
32
|
+
hover: "group-hover:text-action-400",
|
|
33
|
+
dark: {
|
|
34
|
+
base: "dark:text-element-600-dark",
|
|
35
|
+
hover: "dark:group-hover:text-action-500-dark",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
selected: {
|
|
39
|
+
base: "text-action-500",
|
|
40
|
+
hover: "",
|
|
41
|
+
dark: {
|
|
42
|
+
base: "dark:text-action-500-dark",
|
|
43
|
+
hover: "",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const stateClasses = {
|
|
49
|
+
default: {
|
|
50
|
+
base: "text-element-900 cursor-pointer",
|
|
51
|
+
hover: "hover:text-action-500",
|
|
52
|
+
active: "active:text-action-700",
|
|
53
|
+
dark: {
|
|
54
|
+
base: "dark:bg-action-500-dark dark:border-action-600-dark",
|
|
55
|
+
hover: "dark:hover:bg-action-500-dark dark:hover:border-action-500-dark",
|
|
56
|
+
active:
|
|
57
|
+
"dark:active:bg-action-600-dark dark:active:border-action-700-dark",
|
|
58
|
+
},
|
|
59
|
+
disabled: "cursor-not-allowed opacity-50 bg-gray-200",
|
|
60
|
+
},
|
|
61
|
+
selected: {
|
|
62
|
+
base: "bg-action-500 border-action-600 text-white cursor-default",
|
|
63
|
+
dark: {
|
|
64
|
+
base: "dark:bg-action-500-dark dark:border-action-600-dark",
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export function Item({
|
|
70
|
+
onClick,
|
|
71
|
+
selected = false,
|
|
72
|
+
disabled = false,
|
|
73
|
+
label,
|
|
74
|
+
icon,
|
|
75
|
+
className = "",
|
|
76
|
+
href,
|
|
77
|
+
}: ItemProps) {
|
|
78
|
+
const { components } = React.useContext(SparkleContext);
|
|
79
|
+
|
|
80
|
+
const currentStateClasses = selected
|
|
81
|
+
? stateClasses.selected
|
|
82
|
+
: stateClasses.default;
|
|
83
|
+
|
|
84
|
+
const itemClasses = classNames(
|
|
85
|
+
baseClasses,
|
|
86
|
+
currentStateClasses.base,
|
|
87
|
+
currentStateClasses.dark?.base,
|
|
88
|
+
disabled ? currentStateClasses.disabled : "",
|
|
89
|
+
!selected && !disabled ? currentStateClasses.hover : "",
|
|
90
|
+
!selected && !disabled ? currentStateClasses.dark?.hover : "",
|
|
91
|
+
!selected && !disabled ? currentStateClasses.active : "",
|
|
92
|
+
!selected && !disabled ? currentStateClasses.dark?.active : "",
|
|
93
|
+
className
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const currentIconClasses = selected
|
|
97
|
+
? iconClasses.selected
|
|
98
|
+
: iconClasses.default;
|
|
99
|
+
|
|
100
|
+
const finalIconClasses = classNames(
|
|
101
|
+
iconBaseClasses,
|
|
102
|
+
currentIconClasses.base,
|
|
103
|
+
currentIconClasses.hover,
|
|
104
|
+
currentIconClasses.dark.base,
|
|
105
|
+
currentIconClasses.dark.hover
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
const Link: SparkleContextLinkType = href ? components.link : noHrefLink;
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<Link
|
|
112
|
+
className={itemClasses}
|
|
113
|
+
onClick={selected || disabled ? undefined : onClick}
|
|
114
|
+
aria-label={label}
|
|
115
|
+
href={href || "#"}
|
|
116
|
+
>
|
|
117
|
+
{icon && <Icon IconComponent={icon} className={finalIconClasses} />}
|
|
118
|
+
<span className="grow">{label}</span>
|
|
119
|
+
<Icon IconComponent={ChevronRight} className={finalIconClasses} />
|
|
120
|
+
</Link>
|
|
121
|
+
);
|
|
122
|
+
}
|
package/src/components/Tab.tsx
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { ReactComponentLike } from "prop-types";
|
|
2
2
|
import React, { MouseEvent } from "react";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
noHrefLink,
|
|
6
|
+
SparkleContext,
|
|
7
|
+
SparkleContextLinkType,
|
|
8
|
+
} from "@sparkle/context";
|
|
5
9
|
import { classNames } from "@sparkle/lib/utils";
|
|
6
10
|
|
|
7
11
|
type TabProps = {
|
|
@@ -62,7 +66,6 @@ const tabSizingClasses = {
|
|
|
62
66
|
|
|
63
67
|
export function Tab({ tabs, onTabClick, className = "" }: TabProps) {
|
|
64
68
|
const { components } = React.useContext(SparkleContext);
|
|
65
|
-
const Link = components.link;
|
|
66
69
|
|
|
67
70
|
const renderTabs = () =>
|
|
68
71
|
tabs.map((tab) => {
|
|
@@ -92,13 +95,17 @@ export function Tab({ tabs, onTabClick, className = "" }: TabProps) {
|
|
|
92
95
|
className
|
|
93
96
|
);
|
|
94
97
|
|
|
98
|
+
const Link: SparkleContextLinkType = tab.href
|
|
99
|
+
? components.link
|
|
100
|
+
: noHrefLink;
|
|
101
|
+
|
|
95
102
|
return (
|
|
96
103
|
<Link
|
|
97
104
|
key={tab.label}
|
|
98
105
|
className={finalTabClasses}
|
|
99
106
|
aria-current={tab.current ? "page" : undefined}
|
|
100
107
|
onClick={(event) => onTabClick?.(tab.label, event)}
|
|
101
|
-
href={tab.href}
|
|
108
|
+
href={tab.href || "#"}
|
|
102
109
|
>
|
|
103
110
|
<div
|
|
104
111
|
className={
|
package/src/context.tsx
CHANGED
|
@@ -1,22 +1,71 @@
|
|
|
1
1
|
import React, { ComponentType, MouseEvent, ReactNode } from "react";
|
|
2
2
|
|
|
3
|
+
export type SparkleContextLinkType = ComponentType<{
|
|
4
|
+
key?: React.Key | null;
|
|
5
|
+
href: string;
|
|
6
|
+
className?: string;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
ariaLabel?: string;
|
|
9
|
+
ariaCurrent?:
|
|
10
|
+
| boolean
|
|
11
|
+
| "time"
|
|
12
|
+
| "false"
|
|
13
|
+
| "true"
|
|
14
|
+
| "page"
|
|
15
|
+
| "step"
|
|
16
|
+
| "location"
|
|
17
|
+
| "date";
|
|
18
|
+
onClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
|
|
19
|
+
}>;
|
|
20
|
+
|
|
3
21
|
export type SparkleContextType = {
|
|
4
22
|
components: {
|
|
5
|
-
link:
|
|
6
|
-
href?: string;
|
|
7
|
-
className?: string;
|
|
8
|
-
children: ReactNode;
|
|
9
|
-
onClick?: (event: MouseEvent<HTMLAnchorElement>) => void;
|
|
10
|
-
}>;
|
|
23
|
+
link: SparkleContextLinkType;
|
|
11
24
|
};
|
|
12
25
|
};
|
|
13
26
|
|
|
27
|
+
export const aLink: SparkleContextLinkType = ({
|
|
28
|
+
key,
|
|
29
|
+
href,
|
|
30
|
+
className,
|
|
31
|
+
ariaCurrent,
|
|
32
|
+
ariaLabel,
|
|
33
|
+
onClick,
|
|
34
|
+
children,
|
|
35
|
+
}) => (
|
|
36
|
+
<a
|
|
37
|
+
key={key}
|
|
38
|
+
href={href}
|
|
39
|
+
className={className}
|
|
40
|
+
aria-current={ariaCurrent}
|
|
41
|
+
aria-label={ariaLabel}
|
|
42
|
+
onClick={onClick}
|
|
43
|
+
>
|
|
44
|
+
{children}
|
|
45
|
+
</a>
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
export const noHrefLink: SparkleContextLinkType = ({
|
|
49
|
+
key,
|
|
50
|
+
className,
|
|
51
|
+
ariaCurrent,
|
|
52
|
+
ariaLabel,
|
|
53
|
+
onClick,
|
|
54
|
+
children,
|
|
55
|
+
}) => (
|
|
56
|
+
<a
|
|
57
|
+
key={key}
|
|
58
|
+
className={className}
|
|
59
|
+
aria-current={ariaCurrent}
|
|
60
|
+
arria-label={ariaLabel}
|
|
61
|
+
onClick={onClick}
|
|
62
|
+
>
|
|
63
|
+
{children}
|
|
64
|
+
</a>
|
|
65
|
+
);
|
|
66
|
+
|
|
14
67
|
export const SparkleContext = React.createContext<SparkleContextType>({
|
|
15
68
|
components: {
|
|
16
|
-
link:
|
|
17
|
-
<a href={href} className={className}>
|
|
18
|
-
{children}
|
|
19
|
-
</a>
|
|
20
|
-
),
|
|
69
|
+
link: aLink,
|
|
21
70
|
},
|
|
22
71
|
});
|