@dust-tt/sparkle 0.2.266 → 0.2.267

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.
@@ -1,122 +1,106 @@
1
+ import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
2
+ import { cva, VariantProps } from "class-variance-authority";
1
3
  import React from "react";
2
4
 
3
5
  import { CheckIcon, DashIcon } from "@sparkle/icons/solid";
4
- import { classNames } from "@sparkle/lib/utils";
6
+ import { cn } from "@sparkle/lib/utils";
5
7
 
6
8
  import { Icon } from "./Icon";
9
+ import { Label } from "./Label";
7
10
 
8
- export type CheckBoxCheckedStatus = "checked" | "unchecked" | "partial";
9
-
10
- export interface CheckboxProps {
11
- variant?: "selectable" | "checkable";
12
- size?: "xs" | "sm";
13
- checked?: CheckBoxCheckedStatus;
14
- disabled?: boolean;
15
- onChange: (checked: boolean) => void;
16
- className?: string;
17
- }
18
-
19
- export function Checkbox({
20
- variant = "selectable",
21
- checked = "unchecked",
22
- size = "sm",
23
- onChange,
24
- className = "",
25
- disabled,
26
- }: CheckboxProps) {
27
- let isChecked: boolean;
28
- let isPartialChecked: boolean;
29
- switch (checked) {
30
- case "checked":
31
- isChecked = true;
32
- isPartialChecked = false;
33
- break;
34
- case "unchecked":
35
- isChecked = false;
36
- isPartialChecked = false;
37
- break;
38
- case "partial":
39
- isChecked = true;
40
- isPartialChecked = true;
41
- break;
42
- default:
43
- throw new Error("Invalid checked prop");
11
+ const checkboxStyles = cva(
12
+ cn(
13
+ "s-shrink-0 s-peer s-border s-border-primary-500 s-text-foreground",
14
+ "data-[state=checked]:s-text-white data-[state=checked]:s-text-foreground",
15
+ "focus-visible:s-ring-ring s-ring-offset-background focus-visible:s-outline-none focus-visible:s-ring-2 focus-visible:s-ring-offset-2",
16
+ "disabled:s-cursor-not-allowed disabled:s-opacity-50"
17
+ ),
18
+ {
19
+ variants: {
20
+ checked: {
21
+ true: "data-[state=checked]:s-bg-action-500",
22
+ partial: "data-[state=checked]:s-bg-muted-foreground",
23
+ false: "",
24
+ },
25
+ size: {
26
+ xs: "s-h-4 s-w-4 s-rounded",
27
+ sm: "s-h-5 s-w-5 s-rounded-md",
28
+ },
29
+ },
30
+ defaultVariants: {
31
+ size: "sm",
32
+ checked: false,
33
+ },
44
34
  }
35
+ );
45
36
 
46
- const baseStyleClasses = {
47
- base: "s-border s-justify-center s-flex s-items-center s-transition-colors s-duration-300 s-ease-out",
48
- idle: "s-bg-structure-50 s-border-element-600 s-cursor-pointer",
49
- hover:
50
- "hover:s-border-action-500 hover:s-bg-action-200 hover:s-text-white/100",
51
- disabled: "s-bg-structure-0 s-border-structure-300 s-cursor-default",
52
- dark: {
53
- base: "dark:s-bg-structure-50-dark dark:s-border-element-500-dark",
54
- hover:
55
- "dark:hover:s-border-action-500-dark dark:hover:s-bg-action-200-dark",
56
- disabled:
57
- "dark:s-bg-structure-0-dark dark:s-border-structure-300-dark s-cursor-default",
58
- },
59
- };
37
+ type CheckBoxStateType = boolean | "partial";
38
+
39
+ interface CheckboxProps
40
+ extends Omit<
41
+ React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>,
42
+ "checked" | "defaultChecked"
43
+ >,
44
+ VariantProps<typeof checkboxStyles> {
45
+ checked?: CheckBoxStateType;
46
+ }
60
47
 
61
- const baseSizeClasses = {
62
- xs: "s-w-4 s-h-4 s-rounded",
63
- sm: "s-w-5 s-h-5 s-rounded-md",
64
- };
48
+ const Checkbox = React.forwardRef<
49
+ React.ElementRef<typeof CheckboxPrimitive.Root>,
50
+ CheckboxProps
51
+ >(({ className, size, checked, ...props }, ref) => (
52
+ <CheckboxPrimitive.Root
53
+ ref={ref}
54
+ className={cn(checkboxStyles({ checked, size }), className)}
55
+ checked={checked === "partial" ? "indeterminate" : checked}
56
+ {...props}
57
+ >
58
+ <CheckboxPrimitive.Indicator className="s-flex s-items-center s-justify-center s-text-current">
59
+ <span className={cn(size === "xs" ? "-s-mt-px" : "")}>
60
+ <Icon size="xs" visual={checked === "partial" ? DashIcon : CheckIcon} />
61
+ </span>
62
+ </CheckboxPrimitive.Indicator>
63
+ </CheckboxPrimitive.Root>
64
+ ));
65
65
 
66
- const checkedIndicatorClasses = {
67
- base: "s-transition s-duration-300 s-ease-in-out",
68
- selected: "s-opacity-100 s-bg-action-500 dark:s-bg-action-500-dark",
69
- unselected: "s-opacity-0",
70
- partialChecked: "s-opacity-100 s-bg-element-700 dark:s-bg-element-700-dark",
71
- disabled: "s-opacity-100 s-bg-element-500 dark:s-bg-element-500-dark",
72
- };
66
+ Checkbox.displayName = CheckboxPrimitive.Root.displayName;
73
67
 
74
- const sizeStyles = {
75
- xs: { width: "12px", height: "12px", borderRadius: "2px" },
76
- sm: { width: "14px", height: "14px", borderRadius: "3px" },
77
- };
68
+ interface CheckboxWithTextProps extends CheckboxProps {
69
+ text: string;
70
+ }
78
71
 
79
- const combinedBaseClasses = classNames(
80
- baseStyleClasses.base,
81
- baseSizeClasses[size],
82
- isChecked || isPartialChecked ? "s-text-white" : "s-text-white/0",
83
- disabled ? baseStyleClasses.disabled : baseStyleClasses.idle,
84
- !disabled ? baseStyleClasses.hover : "",
85
- disabled ? baseStyleClasses.dark.disabled : baseStyleClasses.dark.base,
86
- !disabled ? baseStyleClasses.dark.hover : "",
87
- className
72
+ function CheckboxWithText({ text, ...props }: CheckboxWithTextProps) {
73
+ return (
74
+ <div className="s-items-top s-flex s-items-center s-space-x-2">
75
+ <Checkbox {...props} />
76
+ <Label className="s-text-sm s-leading-none peer-disabled:s-cursor-not-allowed peer-disabled:s-opacity-70">
77
+ {text}
78
+ </Label>
79
+ </div>
88
80
  );
81
+ }
89
82
 
90
- const combinedCheckedIndicatorClasses = classNames(
91
- checkedIndicatorClasses.base,
92
- disabled ? checkedIndicatorClasses.disabled : "",
93
- isChecked && !isPartialChecked && !disabled
94
- ? checkedIndicatorClasses.selected
95
- : "",
96
- isPartialChecked && !disabled ? checkedIndicatorClasses.partialChecked : "",
97
- !isChecked && !disabled ? checkedIndicatorClasses.unselected : ""
98
- );
83
+ interface CheckboxWithTextAndDescriptionProps extends CheckboxWithTextProps {
84
+ description: string;
85
+ }
99
86
 
87
+ function CheckBoxWithTextAndDescription({
88
+ text,
89
+ description,
90
+ ...props
91
+ }: CheckboxWithTextAndDescriptionProps) {
100
92
  return (
101
- <label>
102
- <input
103
- type="checkbox"
104
- checked={isChecked}
105
- onChange={(e) => onChange && onChange(e.target.checked)}
106
- className="s-hidden"
107
- disabled={disabled}
108
- />
109
- <div className={classNames(combinedBaseClasses, "s-relative")}>
110
- <div
111
- className={combinedCheckedIndicatorClasses}
112
- style={sizeStyles[size]}
113
- />
114
- {variant === "checkable" && (
115
- <div className="s-absolute">
116
- <Icon visual={isPartialChecked ? DashIcon : CheckIcon} size="xs" />
117
- </div>
118
- )}
93
+ <div className="s-items-top s-flex s-space-x-2">
94
+ <Checkbox {...props} />
95
+ <div className="s-grid s-gap-1.5 s-leading-none">
96
+ <Label className="s-text-sm s-leading-none peer-disabled:s-cursor-not-allowed peer-disabled:s-opacity-70">
97
+ {text}
98
+ </Label>
99
+ <p className="s-text-xs s-text-muted-foreground">{description}</p>
119
100
  </div>
120
- </label>
101
+ </div>
121
102
  );
122
103
  }
104
+
105
+ export { Checkbox, CheckboxWithText, CheckBoxWithTextAndDescription };
106
+ export type { CheckboxProps };
@@ -5,7 +5,12 @@ export { BarHeader } from "./BarHeader";
5
5
  export { Breadcrumbs } from "./Breadcrumbs";
6
6
  export { Button } from "./Button";
7
7
  export { CardButton } from "./CardButton";
8
- export { Checkbox } from "./Checkbox";
8
+ export type { CheckboxProps } from "./Checkbox";
9
+ export {
10
+ Checkbox,
11
+ CheckboxWithText,
12
+ CheckBoxWithTextAndDescription,
13
+ } from "./Checkbox";
9
14
  export { Chip } from "./Chip";
10
15
  export { Citation } from "./Citation";
11
16
  export { default as CollapseButton } from "./CollapseButton";
@@ -1,7 +1,11 @@
1
- import type { Meta, StoryObj } from "@storybook/react";
1
+ import type { Meta } from "@storybook/react";
2
2
  import React from "react";
3
3
 
4
- import { Checkbox } from "../index_with_tw_base";
4
+ import {
5
+ Checkbox,
6
+ CheckboxWithText,
7
+ CheckBoxWithTextAndDescription,
8
+ } from "../index_with_tw_base";
5
9
 
6
10
  const meta = {
7
11
  title: "Primitives/Checkbox",
@@ -9,70 +13,34 @@ const meta = {
9
13
  } satisfies Meta<typeof Checkbox>;
10
14
 
11
15
  export default meta;
12
- type Story = StoryObj<typeof meta>;
13
- export const CheckBoxExample = () => {
14
- // No-op function for onChange
15
- const handleChange = () => {
16
- // This function intentionally left blank
17
- };
18
16
 
17
+ const handleChange = () => {
18
+ // This function intentionally left blank
19
+ };
20
+
21
+ export const CheckBoxSizesExample = () => {
19
22
  return (
20
23
  <div className="s-flex s-flex-col s-gap-10">
21
- SM
22
24
  <div className="s-flex s-gap-10">
23
- Selectable
24
- <Checkbox variant="selectable" onChange={handleChange} />
25
- <Checkbox
26
- checked="checked"
27
- variant="selectable"
28
- onChange={handleChange}
29
- />
30
- <Checkbox
31
- checked="partial"
32
- variant="selectable"
33
- onChange={handleChange}
34
- />
35
- Checkable
36
- <Checkbox variant="checkable" onChange={handleChange} />
37
- <Checkbox
38
- checked="checked"
39
- variant="checkable"
40
- onChange={handleChange}
41
- />
42
- <Checkbox
43
- checked="partial"
44
- variant="checkable"
45
- onChange={handleChange}
46
- />
25
+ SM
26
+ <Checkbox onChange={handleChange} />
27
+ <Checkbox disabled onChange={handleChange} />
28
+ <Checkbox checked onChange={handleChange} />
29
+ <Checkbox checked disabled onChange={handleChange} />
30
+ <Checkbox checked="partial" onChange={handleChange} />
31
+ <Checkbox checked="partial" disabled onChange={handleChange} />
47
32
  </div>
48
- XS
49
33
  <div className="s-flex s-gap-10">
50
- Selectable
51
- <Checkbox size="xs" variant="selectable" onChange={handleChange} />
52
- <Checkbox
53
- size="xs"
54
- checked="checked"
55
- variant="selectable"
56
- onChange={handleChange}
57
- />
34
+ XS
35
+ <Checkbox size="xs" onChange={handleChange} />
36
+ <Checkbox size="xs" disabled onChange={handleChange} />
37
+ <Checkbox size="xs" checked onChange={handleChange} />
38
+ <Checkbox size="xs" checked disabled onChange={handleChange} />
39
+ <Checkbox size="xs" checked="partial" onChange={handleChange} />
58
40
  <Checkbox
59
41
  size="xs"
60
42
  checked="partial"
61
- variant="selectable"
62
- onChange={handleChange}
63
- />
64
- Checkable
65
- <Checkbox size="xs" variant="checkable" onChange={handleChange} />
66
- <Checkbox
67
- size="xs"
68
- checked="checked"
69
- variant="checkable"
70
- onChange={handleChange}
71
- />
72
- <Checkbox
73
- size="xs"
74
- checked="partial"
75
- variant="checkable"
43
+ disabled
76
44
  onChange={handleChange}
77
45
  />
78
46
  </div>
@@ -80,36 +48,25 @@ export const CheckBoxExample = () => {
80
48
  );
81
49
  };
82
50
 
83
- export const Selectable: Story = {
84
- args: {
85
- checked: "checked",
86
- variant: "selectable",
87
- },
88
- };
89
-
90
- export const Checked: Story = {
91
- args: {
92
- checked: "checked",
93
- variant: "checkable",
94
- },
95
- };
96
-
97
- export const Unchecked: Story = {
98
- args: {
99
- checked: "unchecked",
100
- },
101
- };
102
-
103
- export const PartialChecked: Story = {
104
- args: {
105
- checked: "partial",
106
- variant: "checkable",
107
- },
51
+ export const CheckBoxWithTextExample = () => {
52
+ return (
53
+ <div className="s-flex s-gap-10">
54
+ <CheckboxWithText text="Google Drive" />
55
+ </div>
56
+ );
108
57
  };
109
58
 
110
- export const Disabled: Story = {
111
- args: {
112
- checked: "checked",
113
- disabled: true,
114
- },
59
+ export const CheckBoxWithTextAndDescriptionExample = () => {
60
+ return (
61
+ <div className="s-flex s-flex-col s-gap-3">
62
+ <CheckBoxWithTextAndDescription
63
+ text="Google Drive"
64
+ description="This is a nice Google Drive description."
65
+ />
66
+ <CheckBoxWithTextAndDescription
67
+ text="Microsoft"
68
+ description="This is a nice Microsoft description."
69
+ />
70
+ </div>
71
+ );
115
72
  };