aboutsummaryrefslogtreecommitdiff
path: root/packages/memory-graph/src/ui/button.css.ts
diff options
context:
space:
mode:
authornexxeln <[email protected]>2025-11-19 18:57:55 +0000
committernexxeln <[email protected]>2025-11-19 18:57:56 +0000
commit5e24eb66c3ca7d2224d0d1f7837cda17015f5fcb (patch)
tree60336fd37b41e3597065729d098877483eba73b6 /packages/memory-graph/src/ui/button.css.ts
parentFix: Prevent multiple prompts while AI response is generated (fixes #538) (#583) (diff)
downloadsupermemory-5e24eb66c3ca7d2224d0d1f7837cda17015f5fcb.tar.xz
supermemory-5e24eb66c3ca7d2224d0d1f7837cda17015f5fcb.zip
includes: - a package that contains a MemoryGraph component which handles fetching data and rendering the graph - a playground to test the package problems: - the bundle size is huge - the styles are kinda broken? we are using [https://www.npmjs.com/package/vite-plugin-libgi-inject-css](https://www.npmjs.com/package/vite-plugin-lib-inject-css) to inject the styles ![image.png](https://app.graphite.com/user-attachments/assets/cb1822c5-850a-45a2-9bfa-72b73436659f.png)
Diffstat (limited to 'packages/memory-graph/src/ui/button.css.ts')
-rw-r--r--packages/memory-graph/src/ui/button.css.ts210
1 files changed, 210 insertions, 0 deletions
diff --git a/packages/memory-graph/src/ui/button.css.ts b/packages/memory-graph/src/ui/button.css.ts
new file mode 100644
index 00000000..ad9cce8c
--- /dev/null
+++ b/packages/memory-graph/src/ui/button.css.ts
@@ -0,0 +1,210 @@
+import { recipe, type RecipeVariants } from "@vanilla-extract/recipes";
+import { style } from "@vanilla-extract/css";
+import { themeContract } from "../styles/theme.css";
+
+/**
+ * Base styles for SVG icons inside buttons
+ */
+export const buttonIcon = style({
+ pointerEvents: "none",
+ flexShrink: 0,
+ selectors: {
+ "&:not([class*='size-'])": {
+ width: "1rem",
+ height: "1rem",
+ },
+ },
+});
+
+/**
+ * Button recipe with variants
+ * Replaces CVA-based button variants with vanilla-extract recipes
+ */
+export const button = recipe({
+ base: {
+ display: "inline-flex",
+ alignItems: "center",
+ justifyContent: "center",
+ gap: themeContract.space[2],
+ whiteSpace: "nowrap",
+ borderRadius: themeContract.radii.md,
+ fontSize: themeContract.typography.fontSize.sm,
+ fontWeight: themeContract.typography.fontWeight.medium,
+ transition: themeContract.transitions.normal,
+ flexShrink: 0,
+ outline: "none",
+ border: "1px solid transparent",
+ cursor: "pointer",
+
+ // SVG sizing
+ selectors: {
+ [`&:has(${buttonIcon})`]: {
+ // Buttons with icons get adjusted padding
+ },
+ "&:disabled": {
+ pointerEvents: "none",
+ opacity: 0.5,
+ },
+ "&:focus-visible": {
+ borderColor: themeContract.colors.accent.primary,
+ boxShadow: `0 0 0 2px ${themeContract.colors.accent.primary}33`,
+ },
+ "&[aria-invalid='true']": {
+ boxShadow: `0 0 0 2px ${themeContract.colors.status.forgotten}`,
+ borderColor: themeContract.colors.status.forgotten,
+ },
+ },
+ },
+
+ variants: {
+ variant: {
+ default: {
+ backgroundColor: themeContract.colors.accent.primary,
+ color: themeContract.colors.text.primary,
+ boxShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
+
+ selectors: {
+ "&:hover:not(:disabled)": {
+ backgroundColor: themeContract.colors.accent.secondary,
+ },
+ },
+ },
+
+ destructive: {
+ backgroundColor: themeContract.colors.status.forgotten,
+ color: themeContract.colors.text.primary,
+ boxShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
+
+ selectors: {
+ "&:hover:not(:disabled)": {
+ opacity: 0.9,
+ },
+ "&:focus-visible": {
+ boxShadow: `0 0 0 2px ${themeContract.colors.status.forgotten}33`,
+ },
+ },
+ },
+
+ outline: {
+ backgroundColor: themeContract.colors.background.primary,
+ borderColor: themeContract.colors.document.border,
+ color: themeContract.colors.text.primary,
+ boxShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
+
+ selectors: {
+ "&:hover:not(:disabled)": {
+ backgroundColor: themeContract.colors.document.primary,
+ },
+ },
+ },
+
+ secondary: {
+ backgroundColor: themeContract.colors.background.secondary,
+ color: themeContract.colors.text.secondary,
+ boxShadow: "0 1px 2px 0 rgb(0 0 0 / 0.05)",
+
+ selectors: {
+ "&:hover:not(:disabled)": {
+ backgroundColor: themeContract.colors.background.accent,
+ },
+ },
+ },
+
+ ghost: {
+ backgroundColor: "transparent",
+ color: themeContract.colors.text.primary,
+
+ selectors: {
+ "&:hover:not(:disabled)": {
+ backgroundColor: themeContract.colors.document.primary,
+ },
+ },
+ },
+
+ link: {
+ backgroundColor: "transparent",
+ color: themeContract.colors.accent.primary,
+ textDecoration: "underline",
+ textUnderlineOffset: "4px",
+
+ selectors: {
+ "&:hover:not(:disabled)": {
+ textDecoration: "underline",
+ },
+ },
+ },
+
+ settingsNav: {
+ cursor: "pointer",
+ borderRadius: themeContract.radii.sm,
+ backgroundColor: "transparent",
+ color: themeContract.colors.text.primary,
+ },
+ },
+
+ size: {
+ default: {
+ height: "36px",
+ paddingLeft: themeContract.space[4],
+ paddingRight: themeContract.space[4],
+ paddingTop: themeContract.space[2],
+ paddingBottom: themeContract.space[2],
+
+ selectors: {
+ "&:has(svg)": {
+ paddingLeft: themeContract.space[3],
+ paddingRight: themeContract.space[3],
+ },
+ },
+ },
+
+ sm: {
+ height: "32px",
+ borderRadius: themeContract.radii.md,
+ gap: themeContract.space[1],
+ paddingLeft: themeContract.space[3],
+ paddingRight: themeContract.space[3],
+
+ selectors: {
+ "&:has(svg)": {
+ paddingLeft: themeContract.space[2],
+ paddingRight: themeContract.space[2],
+ },
+ },
+ },
+
+ lg: {
+ height: "40px",
+ borderRadius: themeContract.radii.md,
+ paddingLeft: themeContract.space[6],
+ paddingRight: themeContract.space[6],
+
+ selectors: {
+ "&:has(svg)": {
+ paddingLeft: themeContract.space[4],
+ paddingRight: themeContract.space[4],
+ },
+ },
+ },
+
+ icon: {
+ width: "36px",
+ height: "36px",
+ padding: 0,
+ },
+
+ settingsNav: {
+ height: "32px",
+ gap: 0,
+ padding: 0,
+ },
+ },
+ },
+
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+});
+
+export type ButtonVariants = RecipeVariants<typeof button>;