diff --git a/sparkle/src/_index.ts b/sparkle/src/_index.ts
index 8ff81e06d6ae..ad8c4a7a3f8f 100644
--- a/sparkle/src/_index.ts
+++ b/sparkle/src/_index.ts
@@ -88,6 +88,9 @@ export { Tooltip };
import { ContentMessage } from "./components/ContentMessage";
export { ContentMessage };
+import { ColorPicker } from "./components/ColorPicker";
+export { ColorPicker };
+
import { Avatar } from "./components/Avatar";
export { Avatar };
diff --git a/sparkle/src/components/ColorPicker.tsx b/sparkle/src/components/ColorPicker.tsx
new file mode 100644
index 000000000000..04e0c15cc6f2
--- /dev/null
+++ b/sparkle/src/components/ColorPicker.tsx
@@ -0,0 +1,36 @@
+import React from "react";
+
+interface ColorSwatchProps {
+ onClick: (color: string) => void;
+ color: string;
+}
+
+const ColorSwatch = ({ color, onClick }: ColorSwatchProps) => {
+ return (
+
onClick(color)}
+ />
+ );
+};
+
+interface ColorPickerProps {
+ onColorSelect: (color: string) => void;
+ colors: string[];
+}
+
+export function ColorPicker({ colors, onColorSelect }: ColorPickerProps) {
+ return (
+
+ {colors.map((color) => {
+ return (
+ onColorSelect(color)}
+ />
+ );
+ })}
+
+ );
+}
diff --git a/sparkle/src/components/DropdownMenu.tsx b/sparkle/src/components/DropdownMenu.tsx
index 7acca2cc4253..4638b5187fd4 100644
--- a/sparkle/src/components/DropdownMenu.tsx
+++ b/sparkle/src/components/DropdownMenu.tsx
@@ -304,6 +304,21 @@ DropdownMenu.SectionHeader = function ({ label }: DropdownSectionHeaderProps) {
);
};
+type ItemsVariantType = "default" | "no-padding";
+
+const classNamesForVariant = (
+ variant: ItemsVariantType,
+ hasDropdownItem: boolean
+) => {
+ switch (variant) {
+ case "no-padding":
+ return "";
+
+ case "default":
+ return `s-px-5 ${hasDropdownItem ? "s-py-1.5" : "s-py-4"}`;
+ }
+};
+
interface DropdownItemsProps {
origin?: "topLeft" | "topRight" | "bottomLeft" | "bottomRight" | "auto";
width?: number;
@@ -312,6 +327,7 @@ interface DropdownItemsProps {
topBar?: React.ReactNode;
bottomBar?: React.ReactNode;
overflow?: "visible" | "auto";
+ variant?: ItemsVariantType;
}
DropdownMenu.Items = function ({
@@ -322,6 +338,7 @@ DropdownMenu.Items = function ({
topBar,
bottomBar,
overflow = "auto",
+ variant = "default",
}: DropdownItemsProps) {
const buttonRef = useContext(ButtonRefContext);
const [buttonHeight, setButtonHeight] = useState(0);
@@ -420,8 +437,7 @@ DropdownMenu.Items = function ({
{topBar}
diff --git a/sparkle/src/stories/ColorPicker.stories.tsx b/sparkle/src/stories/ColorPicker.stories.tsx
new file mode 100644
index 000000000000..bc95e59ea99a
--- /dev/null
+++ b/sparkle/src/stories/ColorPicker.stories.tsx
@@ -0,0 +1,177 @@
+import type { Meta } from "@storybook/react";
+import React from "react";
+
+import { ColorPicker } from "../index_with_tw_base";
+
+const meta = {
+ title: "Components/ColorPicker",
+ component: ColorPicker,
+} satisfies Meta
;
+
+export default meta;
+
+const colors = [
+ "bg-amber-100",
+ "bg-amber-200",
+ "bg-amber-300",
+ "bg-amber-400",
+ "bg-amber-500",
+ "bg-amber-600",
+ "bg-amber-700",
+ "bg-amber-800",
+ "bg-blue-100",
+ "bg-blue-200",
+ "bg-blue-300",
+ "bg-blue-400",
+ "bg-blue-500",
+ "bg-blue-600",
+ "bg-blue-700",
+ "bg-blue-800",
+ "bg-cyan-100",
+ "bg-cyan-200",
+ "bg-cyan-300",
+ "bg-cyan-400",
+ "bg-cyan-500",
+ "bg-cyan-600",
+ "bg-cyan-700",
+ "bg-cyan-800",
+ "bg-emerald-100",
+ "bg-emerald-200",
+ "bg-emerald-300",
+ "bg-emerald-400",
+ "bg-emerald-500",
+ "bg-emerald-600",
+ "bg-emerald-700",
+ "bg-emerald-800",
+ "bg-fuchsia-100",
+ "bg-fuchsia-200",
+ "bg-fuchsia-300",
+ "bg-fuchsia-400",
+ "bg-fuchsia-500",
+ "bg-fuchsia-600",
+ "bg-fuchsia-700",
+ "bg-fuchsia-800",
+ "bg-gray-100",
+ "bg-gray-200",
+ "bg-gray-300",
+ "bg-gray-400",
+ "bg-gray-500",
+ "bg-gray-600",
+ "bg-gray-700",
+ "bg-gray-800",
+ "bg-green-100",
+ "bg-green-200",
+ "bg-green-300",
+ "bg-green-400",
+ "bg-green-500",
+ "bg-green-600",
+ "bg-green-700",
+ "bg-green-800",
+ "bg-indigo-100",
+ "bg-indigo-200",
+ "bg-indigo-300",
+ "bg-indigo-400",
+ "bg-indigo-500",
+ "bg-indigo-600",
+ "bg-indigo-700",
+ "bg-indigo-800",
+ "bg-lime-100",
+ "bg-lime-200",
+ "bg-lime-300",
+ "bg-lime-400",
+ "bg-lime-500",
+ "bg-lime-600",
+ "bg-lime-700",
+ "bg-lime-800",
+ "bg-orange-100",
+ "bg-orange-200",
+ "bg-orange-300",
+ "bg-orange-400",
+ "bg-orange-500",
+ "bg-orange-600",
+ "bg-orange-700",
+ "bg-orange-800",
+ "bg-pink-100",
+ "bg-pink-200",
+ "bg-pink-300",
+ "bg-pink-400",
+ "bg-pink-500",
+ "bg-pink-600",
+ "bg-pink-700",
+ "bg-pink-800",
+ "bg-purple-100",
+ "bg-purple-200",
+ "bg-purple-300",
+ "bg-purple-400",
+ "bg-purple-500",
+ "bg-purple-600",
+ "bg-purple-700",
+ "bg-purple-800",
+ "bg-red-100",
+ "bg-red-200",
+ "bg-red-300",
+ "bg-red-400",
+ "bg-red-500",
+ "bg-red-600",
+ "bg-red-700",
+ "bg-red-800",
+ "bg-rose-100",
+ "bg-rose-200",
+ "bg-rose-300",
+ "bg-rose-400",
+ "bg-rose-500",
+ "bg-rose-600",
+ "bg-rose-700",
+ "bg-rose-800",
+ "bg-sky-100",
+ "bg-sky-200",
+ "bg-sky-300",
+ "bg-sky-400",
+ "bg-sky-500",
+ "bg-sky-600",
+ "bg-sky-700",
+ "bg-sky-800",
+ "bg-stone-100",
+ "bg-stone-200",
+ "bg-stone-300",
+ "bg-stone-400",
+ "bg-stone-500",
+ "bg-stone-600",
+ "bg-stone-700",
+ "bg-stone-800",
+ "bg-teal-100",
+ "bg-teal-200",
+ "bg-teal-300",
+ "bg-teal-400",
+ "bg-teal-500",
+ "bg-teal-600",
+ "bg-teal-700",
+ "bg-teal-800",
+ "bg-violet-100",
+ "bg-violet-200",
+ "bg-violet-300",
+ "bg-violet-400",
+ "bg-violet-500",
+ "bg-violet-600",
+ "bg-violet-700",
+ "bg-violet-800",
+ "bg-yellow-100",
+ "bg-yellow-200",
+ "bg-yellow-300",
+ "bg-yellow-400",
+ "bg-yellow-500",
+ "bg-yellow-600",
+ "bg-yellow-700",
+ "bg-yellow-800",
+];
+
+export const ColorPickerExample = () => (
+
+ {
+ console.log(">> colorSelected:", color);
+ }}
+ />
+
+);
diff --git a/sparkle/tailwind.config.js b/sparkle/tailwind.config.js
index ebeed1a00617..85ceaeddbf7a 100644
--- a/sparkle/tailwind.config.js
+++ b/sparkle/tailwind.config.js
@@ -2,19 +2,37 @@
const colors = require("tailwindcss/colors");
const safeColorsArray = [
- "emerald",
+ "action",
"amber",
- "slate",
- "purple",
- "warning",
- "sky",
+ "blue",
+ "cyan",
+ "emerald",
+ "emerald",
+ "fuchsia",
+ "gray",
+ "green",
+ "indigo",
+ "lime",
+ "orange",
"pink",
- "action",
+ "pink",
+ "purple",
+ "purple",
"red",
+ "red",
+ "rose",
+ "sky",
+ "slate",
+ "stone",
+ "teal",
+ "violet",
+ "warning",
+ "yellow",
];
const safeColorlist = safeColorsArray.flatMap((color) => [
- `s-bg-${color}-100`,
+ // Whitelist all bg colors from shade 100 t0 800.
+ ...Array.from({ length: 8 }, (_, i) => `s-bg-${color}-${(i + 1) * 100}`),
`s-border-${color}-200`,
`s-text-${color}-800`,
`s-text-${color}-900`,