Fix project panel bug (#2656)

Mikayla Maki created

Release Notes:

* Fix a bug where project panel entries would not be styled correctly
(preview only)

Change summary

styles/src/component/icon_button.ts           |  86 ++++++
styles/src/component/text_button.ts           |  90 +++++++
styles/src/element/interactive.ts             |   2 
styles/src/styleTree/assistant.ts             |  83 +++---
styles/src/styleTree/components.ts            |   8 
styles/src/styleTree/projectPanel.ts          | 190 +++++++++-----
styles/src/styleTree/titlebar.ts              | 266 +++++++++++++++++++++
styles/src/themes/rose-pine/common.ts         |  66 ++--
styles/src/themes/rose-pine/rose-pine-dawn.ts |  24 +
styles/src/themes/rose-pine/rose-pine-moon.ts |  22 +
styles/src/themes/rose-pine/rose-pine.ts      |  20 +
11 files changed, 693 insertions(+), 164 deletions(-)

Detailed changes

styles/src/component/icon_button.ts πŸ”—

@@ -0,0 +1,86 @@
+import { ColorScheme } from "../common"
+import { interactive, toggleable } from "../element"
+import { background, foreground } from "../styleTree/components"
+
+export type Margin = {
+    top: number
+    bottom: number
+    left: number
+    right: number
+}
+
+interface IconButtonOptions {
+    layer?:
+        | ColorScheme["lowest"]
+        | ColorScheme["middle"]
+        | ColorScheme["highest"]
+    color?: keyof ColorScheme["lowest"]
+    margin?: Partial<Margin>
+}
+
+type ToggleableIconButtonOptions = IconButtonOptions & {
+    active_color?: keyof ColorScheme["lowest"]
+}
+
+export function icon_button(
+    theme: ColorScheme,
+    { color, margin, layer }: IconButtonOptions
+) {
+    if (!color) color = "base"
+
+    const m = {
+        top: margin?.top ?? 0,
+        bottom: margin?.bottom ?? 0,
+        left: margin?.left ?? 0,
+        right: margin?.right ?? 0,
+    }
+
+    return interactive({
+        base: {
+            corner_radius: 6,
+            padding: {
+                top: 2,
+                bottom: 2,
+                left: 4,
+                right: 4,
+            },
+            margin: m,
+            icon_width: 14,
+            icon_height: 14,
+            button_width: 20,
+            button_height: 16,
+        },
+        state: {
+            default: {
+                background: background(layer ?? theme.lowest, color),
+                color: foreground(layer ?? theme.lowest, color),
+            },
+            hovered: {
+                background: background(layer ?? theme.lowest, color, "hovered"),
+                color: foreground(layer ?? theme.lowest, color, "hovered"),
+            },
+            clicked: {
+                background: background(layer ?? theme.lowest, color, "pressed"),
+                color: foreground(layer ?? theme.lowest, color, "pressed"),
+            },
+        },
+    })
+}
+
+export function toggleable_icon_button(
+    theme: ColorScheme,
+    { color, active_color, margin }: ToggleableIconButtonOptions
+) {
+    if (!color) color = "base"
+
+    return toggleable({
+        state: {
+            inactive: icon_button(theme, { color, margin }),
+            active: icon_button(theme, {
+                color: active_color ? active_color : color,
+                margin,
+                layer: theme.middle,
+            }),
+        },
+    })
+}

styles/src/component/text_button.ts πŸ”—

@@ -0,0 +1,90 @@
+import { ColorScheme } from "../common"
+import { interactive, toggleable } from "../element"
+import {
+    TextProperties,
+    background,
+    foreground,
+    text,
+} from "../styleTree/components"
+import { Margin } from "./icon_button"
+
+interface TextButtonOptions {
+    layer?:
+        | ColorScheme["lowest"]
+        | ColorScheme["middle"]
+        | ColorScheme["highest"]
+    color?: keyof ColorScheme["lowest"]
+    margin?: Partial<Margin>
+    text_properties?: TextProperties
+}
+
+type ToggleableTextButtonOptions = TextButtonOptions & {
+    active_color?: keyof ColorScheme["lowest"]
+}
+
+export function text_button(
+    theme: ColorScheme,
+    { color, layer, margin, text_properties }: TextButtonOptions
+) {
+    if (!color) color = "base"
+
+    const text_options: TextProperties = {
+        size: "xs",
+        weight: "normal",
+        ...text_properties,
+    }
+
+    const m = {
+        top: margin?.top ?? 0,
+        bottom: margin?.bottom ?? 0,
+        left: margin?.left ?? 0,
+        right: margin?.right ?? 0,
+    }
+
+    return interactive({
+        base: {
+            corner_radius: 6,
+            padding: {
+                top: 1,
+                bottom: 1,
+                left: 6,
+                right: 6,
+            },
+            margin: m,
+            button_height: 22,
+            ...text(layer ?? theme.lowest, "sans", color, text_options),
+        },
+        state: {
+            default: {
+                background: background(layer ?? theme.lowest, color),
+                color: foreground(layer ?? theme.lowest, color),
+            },
+            hovered: {
+                background: background(layer ?? theme.lowest, color, "hovered"),
+                color: foreground(layer ?? theme.lowest, color, "hovered"),
+            },
+            clicked: {
+                background: background(layer ?? theme.lowest, color, "pressed"),
+                color: foreground(layer ?? theme.lowest, color, "pressed"),
+            },
+        },
+    })
+}
+
+export function toggleable_text_button(
+    theme: ColorScheme,
+    { color, active_color, margin }: ToggleableTextButtonOptions
+) {
+    if (!color) color = "base"
+
+    return toggleable({
+        state: {
+            inactive: text_button(theme, { color, margin }),
+            active: text_button(theme, {
+                color: active_color ? active_color : color,
+                margin,
+                layer: theme.middle,
+            }),
+        },
+    })
+}

styles/src/element/interactive.ts πŸ”—

@@ -1,7 +1,7 @@
 import merge from "ts-deepmerge"
 import { DeepPartial } from "utility-types"
 
-type InteractiveState =
+export type InteractiveState =
     | "default"
     | "hovered"
     | "clicked"

styles/src/styleTree/assistant.ts πŸ”—

@@ -26,15 +26,15 @@ export default function assistant(colorScheme: ColorScheme) {
                 },
                 container: {
                     padding: { left: 12, right: 8.5 },
-                }
+                },
             },
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered")
-                    }
-                }
-            }
+                        color: foreground(layer, "hovered"),
+                    },
+                },
+            },
         }),
         splitButton: interactive({
             base: {
@@ -48,15 +48,15 @@ export default function assistant(colorScheme: ColorScheme) {
                 },
                 container: {
                     padding: { left: 8.5, right: 8.5 },
-                }
+                },
             },
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered")
-                    }
-                }
-            }
+                        color: foreground(layer, "hovered"),
+                    },
+                },
+            },
         }),
         quoteButton: interactive({
             base: {
@@ -70,15 +70,15 @@ export default function assistant(colorScheme: ColorScheme) {
                 },
                 container: {
                     padding: { left: 8.5, right: 8.5 },
-                }
+                },
             },
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered")
-                    }
-                }
-            }
+                        color: foreground(layer, "hovered"),
+                    },
+                },
+            },
         }),
         assistButton: interactive({
             base: {
@@ -92,15 +92,15 @@ export default function assistant(colorScheme: ColorScheme) {
                 },
                 container: {
                     padding: { left: 8.5, right: 8.5 },
-                }
+                },
             },
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered")
-                    }
-                }
-            }
+                        color: foreground(layer, "hovered"),
+                    },
+                },
+            },
         }),
         zoomInButton: interactive({
             base: {
@@ -114,15 +114,15 @@ export default function assistant(colorScheme: ColorScheme) {
                 },
                 container: {
                     padding: { left: 10, right: 10 },
-                }
+                },
             },
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered")
-                    }
-                }
-            }
+                        color: foreground(layer, "hovered"),
+                    },
+                },
+            },
         }),
         zoomOutButton: interactive({
             base: {
@@ -136,15 +136,15 @@ export default function assistant(colorScheme: ColorScheme) {
                 },
                 container: {
                     padding: { left: 10, right: 10 },
-                }
+                },
             },
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered")
-                    }
-                }
-            }
+                        color: foreground(layer, "hovered"),
+                    },
+                },
+            },
         }),
         plusButton: interactive({
             base: {
@@ -158,29 +158,29 @@ export default function assistant(colorScheme: ColorScheme) {
                 },
                 container: {
                     padding: { left: 10, right: 10 },
-                }
+                },
             },
             state: {
                 hovered: {
                     icon: {
-                        color: foreground(layer, "hovered")
-                    }
-                }
-            }
+                        color: foreground(layer, "hovered"),
+                    },
+                },
+            },
         }),
         title: {
-            ...text(layer, "sans", "default", { size: "sm" })
+            ...text(layer, "sans", "default", { size: "sm" }),
         },
         savedConversation: {
             container: interactive({
                 base: {
                     background: background(layer, "on"),
-                    padding: { top: 4, bottom: 4 }
+                    padding: { top: 4, bottom: 4 },
                 },
                 state: {
                     hovered: {
                         background: background(layer, "on", "hovered"),
-                    }
+                    },
                 },
             }),
             savedAt: {
@@ -189,8 +189,11 @@ export default function assistant(colorScheme: ColorScheme) {
             },
             title: {
                 margin: { left: 16 },
-                ...text(layer, "sans", "default", { size: "sm", weight: "bold" }),
-            }
+                ...text(layer, "sans", "default", {
+                    size: "sm",
+                    weight: "bold",
+                }),
+            },
         },
         userSender: {
             default: {

styles/src/styleTree/components.ts πŸ”—

@@ -93,6 +93,14 @@ interface Text extends Object {
     underline?: boolean
 }
 
+export interface TextStyle extends Object {
+    family: keyof typeof fontFamilies
+    color: string
+    size: number
+    weight?: FontWeight
+    underline?: boolean
+}
+
 export interface TextProperties {
     size?: keyof typeof fontSizes
     weight?: FontWeight

styles/src/styleTree/projectPanel.ts πŸ”—

@@ -1,73 +1,116 @@
 import { ColorScheme } from "../theme/colorScheme"
 import { withOpacity } from "../theme/color"
-import { background, border, foreground, text } from "./components"
+import {
+    Border,
+    TextStyle,
+    background,
+    border,
+    foreground,
+    text,
+} from "./components"
 import { interactive, toggleable } from "../element"
+import merge from "ts-deepmerge"
 export default function projectPanel(colorScheme: ColorScheme) {
     const { isLight } = colorScheme
 
     let layer = colorScheme.middle
 
-    let baseEntry = {
-        height: 22,
-        iconColor: foreground(layer, "variant"),
-        iconSize: 7,
-        iconSpacing: 5,
+    type EntryStateProps = {
+        background?: string
+        border?: Border
+        text?: TextStyle
+        iconColor?: string
     }
 
-    let status = {
-        git: {
-            modified: isLight
-                ? colorScheme.ramps.yellow(0.6).hex()
-                : colorScheme.ramps.yellow(0.5).hex(),
-            inserted: isLight
-                ? colorScheme.ramps.green(0.45).hex()
-                : colorScheme.ramps.green(0.5).hex(),
-            conflict: isLight
-                ? colorScheme.ramps.red(0.6).hex()
-                : colorScheme.ramps.red(0.5).hex(),
-        },
+    type EntryState = {
+        default: EntryStateProps
+        hovered?: EntryStateProps
+        clicked?: EntryStateProps
     }
 
-    const default_entry = interactive({
-        base: {
-            ...baseEntry,
-            text: text(layer, "mono", "variant", { size: "sm" }),
-            status,
-        },
-        state: {
-            default: {
-                background: background(layer),
+    const entry = (unselected?: EntryState, selected?: EntryState) => {
+        const git_status = {
+            git: {
+                modified: isLight
+                    ? colorScheme.ramps.yellow(0.6).hex()
+                    : colorScheme.ramps.yellow(0.5).hex(),
+                inserted: isLight
+                    ? colorScheme.ramps.green(0.45).hex()
+                    : colorScheme.ramps.green(0.5).hex(),
+                conflict: isLight
+                    ? colorScheme.ramps.red(0.6).hex()
+                    : colorScheme.ramps.red(0.5).hex(),
             },
-            hovered: {
-                background: background(layer, "variant", "hovered"),
-            },
-            clicked: {
-                background: background(layer, "variant", "pressed"),
+        }
+
+        const base_properties = {
+            height: 22,
+            background: background(layer),
+            iconColor: foreground(layer, "variant"),
+            iconSize: 7,
+            iconSpacing: 5,
+            text: text(layer, "mono", "variant", { size: "sm" }),
+            status: {
+                ...git_status,
             },
-        },
-    })
+        }
 
-    let entry = toggleable({
-        base: default_entry,
-        state: {
-            active: interactive({
-                base: {
-                    ...default_entry,
-                },
-                state: {
-                    default: {
-                        background: background(colorScheme.lowest),
-                    },
-                    hovered: {
-                        background: background(colorScheme.lowest, "hovered"),
+        const selectedStyle: EntryState | undefined = selected
+            ? selected
+            : unselected
+
+        const unselected_default_style = merge(
+            base_properties,
+            unselected?.default ?? {},
+            {}
+        )
+        const unselected_hovered_style = merge(
+            base_properties,
+            unselected?.hovered ?? {},
+            { background: background(layer, "variant", "hovered") }
+        )
+        const unselected_clicked_style = merge(
+            base_properties,
+            unselected?.clicked ?? {},
+            { background: background(layer, "variant", "pressed") }
+        )
+        const selected_default_style = merge(
+            base_properties,
+            selectedStyle?.default ?? {},
+            { background: background(layer) }
+        )
+        const selected_hovered_style = merge(
+            base_properties,
+            selectedStyle?.hovered ?? {},
+            { background: background(layer, "variant", "hovered") }
+        )
+        const selected_clicked_style = merge(
+            base_properties,
+            selectedStyle?.clicked ?? {},
+            { background: background(layer, "variant", "pressed") }
+        )
+
+        return toggleable({
+            state: {
+                inactive: interactive({
+                    state: {
+                        default: unselected_default_style,
+                        hovered: unselected_hovered_style,
+                        clicked: unselected_clicked_style,
                     },
-                    clicked: {
-                        background: background(colorScheme.lowest, "pressed"),
+                }),
+                active: interactive({
+                    state: {
+                        default: selected_default_style,
+                        hovered: selected_hovered_style,
+                        clicked: selected_clicked_style,
                     },
-                },
-            }),
-        },
-    })
+                }),
+            },
+        })
+    }
+
+    const defaultEntry = entry()
 
     return {
         openProjectButton: interactive({
@@ -104,35 +147,38 @@ export default function projectPanel(colorScheme: ColorScheme) {
         background: background(layer),
         padding: { left: 6, right: 6, top: 0, bottom: 6 },
         indentWidth: 12,
-        entry,
+        entry: defaultEntry,
         draggedEntry: {
-            ...baseEntry,
+            ...defaultEntry.inactive.default,
             text: text(layer, "mono", "on", { size: "sm" }),
             background: withOpacity(background(layer, "on"), 0.9),
             border: border(layer),
-            status,
         },
-        ignoredEntry: {
-            ...entry,
-            iconColor: foreground(layer, "disabled"),
-            text: text(layer, "mono", "disabled"),
-            active: {
-                ...entry.active,
-                iconColor: foreground(layer, "variant"),
+        ignoredEntry: entry(
+            {
+                default: {
+                    text: text(layer, "mono", "disabled"),
+                },
             },
-        },
-        cutEntry: {
-            ...entry,
-            text: text(layer, "mono", "disabled"),
-            active: {
-                ...entry.active,
+            {
+                default: {
+                    iconColor: foreground(layer, "variant"),
+                },
+            }
+        ),
+        cutEntry: entry(
+            {
+                default: {
+                    text: text(layer, "mono", "disabled"),
+                },
+            },
+            {
                 default: {
-                    ...entry.active.default,
                     background: background(layer, "active"),
                     text: text(layer, "mono", "disabled", { size: "sm" }),
                 },
-            },
-        },
+            }
+        ),
         filenameEditor: {
             background: background(layer, "on"),
             text: text(layer, "mono", "on", { size: "sm" }),

styles/src/styleTree/titlebar.ts πŸ”—

@@ -0,0 +1,266 @@
+import { ColorScheme } from "../common"
+import { icon_button, toggleable_icon_button } from "../component/icon_button"
+import { toggleable_text_button } from "../component/text_button"
+import { interactive, toggleable } from "../element"
+import { withOpacity } from "../theme/color"
+import { background, border, foreground, text } from "./components"
+
+const ITEM_SPACING = 8
+const TITLEBAR_HEIGHT = 32
+
+function build_spacing(
+    container_height: number,
+    element_height: number,
+    spacing: number
+) {
+    return {
+        group: spacing,
+        item: spacing / 2,
+        half_item: spacing / 4,
+        marginY: (container_height - element_height) / 2,
+        marginX: (container_height - element_height) / 2,
+    }
+}
+
+function call_controls(theme: ColorScheme) {
+    const button_height = 18
+
+    const space = build_spacing(TITLEBAR_HEIGHT, button_height, ITEM_SPACING)
+    const marginY = {
+        top: space.marginY,
+        bottom: space.marginY,
+    }
+
+    return {
+        toggle_microphone_button: toggleable_icon_button(theme, {
+            margin: {
+                ...marginY,
+                left: space.group,
+                right: space.half_item,
+            },
+            active_color: "negative",
+        }),
+
+        toggle_speakers_button: toggleable_icon_button(theme, {
+            margin: {
+                ...marginY,
+                left: space.half_item,
+                right: space.half_item,
+            },
+        }),
+
+        screen_share_button: toggleable_icon_button(theme, {
+            margin: {
+                ...marginY,
+                left: space.half_item,
+                right: space.group,
+            },
+            active_color: "accent",
+        }),
+
+        muted: foreground(theme.lowest, "negative"),
+        speaking: foreground(theme.lowest, "accent"),
+    }
+}
+
+/**
+ * Opens the User Menu when toggled
+ *
+ * When logged in shows the user's avatar and a chevron,
+ * When logged out only shows a chevron.
+ */
+function user_menu(theme: ColorScheme) {
+    const button_height = 18
+
+    const space = build_spacing(TITLEBAR_HEIGHT, button_height, ITEM_SPACING)
+
+    const build_button = ({ online }: { online: boolean }) => {
+        const button = toggleable({
+            base: interactive({
+                base: {
+                    cornerRadius: 6,
+                    height: button_height,
+                    width: online ? 37 : 24,
+                    padding: {
+                        top: 2,
+                        bottom: 2,
+                        left: 6,
+                        right: 6,
+                    },
+                    margin: {
+                        left: space.item,
+                        right: space.item,
+                    },
+                    ...text(theme.lowest, "sans", { size: "xs" }),
+                    background: background(theme.lowest),
+                },
+                state: {
+                    hovered: {
+                        ...text(theme.lowest, "sans", "hovered", {
+                            size: "xs",
+                        }),
+                        background: background(theme.lowest, "hovered"),
+                    },
+                    clicked: {
+                        ...text(theme.lowest, "sans", "pressed", {
+                            size: "xs",
+                        }),
+                        background: background(theme.lowest, "pressed"),
+                    },
+                },
+            }),
+            state: {
+                active: {
+                    default: {
+                        ...text(theme.lowest, "sans", "active", { size: "xs" }),
+                        background: background(theme.middle),
+                    },
+                    hovered: {
+                        ...text(theme.lowest, "sans", "active", { size: "xs" }),
+                        background: background(theme.middle, "hovered"),
+                    },
+                    clicked: {
+                        ...text(theme.lowest, "sans", "active", { size: "xs" }),
+                        background: background(theme.middle, "pressed"),
+                    },
+                },
+            },
+        })
+
+        return {
+            user_menu: button,
+            avatar: {
+                icon_width: 16,
+                icon_height: 16,
+                corner_radius: 4,
+                outer_width: 16,
+                outer_corner_radius: 16,
+            },
+            icon: {
+                margin: {
+                    top: 2,
+                    left: online ? space.item : 0,
+                    right: space.group,
+                    bottom: 2,
+                },
+                width: 11,
+                height: 11,
+                color: foreground(theme.lowest),
+            },
+        }
+    }
+    return {
+        userMenuButtonOnline: build_button({ online: true }),
+        userMenuButtonOffline: build_button({ online: false }),
+    }
+}
+
+export function titlebar(theme: ColorScheme) {
+    const avatarWidth = 15
+    const avatarOuterWidth = avatarWidth + 4
+    const followerAvatarWidth = 14
+    const followerAvatarOuterWidth = followerAvatarWidth + 4
+
+    return {
+        item_spacing: ITEM_SPACING,
+        facePileSpacing: 2,
+        height: TITLEBAR_HEIGHT,
+        background: background(theme.lowest),
+        border: border(theme.lowest, { bottom: true }),
+        padding: {
+            left: 80,
+            right: 0,
+        },
+
+        // Project
+        title: text(theme.lowest, "sans", "variant"),
+        highlight_color: text(theme.lowest, "sans", "active").color,
+
+        // Collaborators
+        leaderAvatar: {
+            width: avatarWidth,
+            outerWidth: avatarOuterWidth,
+            cornerRadius: avatarWidth / 2,
+            outerCornerRadius: avatarOuterWidth / 2,
+        },
+        followerAvatar: {
+            width: followerAvatarWidth,
+            outerWidth: followerAvatarOuterWidth,
+            cornerRadius: followerAvatarWidth / 2,
+            outerCornerRadius: followerAvatarOuterWidth / 2,
+        },
+        inactiveAvatarGrayscale: true,
+        followerAvatarOverlap: 8,
+        leaderSelection: {
+            margin: {
+                top: 4,
+                bottom: 4,
+            },
+            padding: {
+                left: 2,
+                right: 2,
+                top: 2,
+                bottom: 2,
+            },
+            cornerRadius: 6,
+        },
+        avatarRibbon: {
+            height: 3,
+            width: 14,
+            // TODO: Chore: Make avatarRibbon colors driven by the theme rather than being hard coded.
+        },
+
+        sign_in_button: toggleable_text_button(theme, {}),
+        offlineIcon: {
+            color: foreground(theme.lowest, "variant"),
+            width: 16,
+            margin: {
+                left: ITEM_SPACING,
+            },
+            padding: {
+                right: 4,
+            },
+        },
+
+        // When the collaboration server is out of date, show a warning
+        outdatedWarning: {
+            ...text(theme.lowest, "sans", "warning", { size: "xs" }),
+            background: withOpacity(background(theme.lowest, "warning"), 0.3),
+            border: border(theme.lowest, "warning"),
+            margin: {
+                left: ITEM_SPACING,
+            },
+            padding: {
+                left: 8,
+                right: 8,
+            },
+            cornerRadius: 6,
+        },
+
+        leave_call_button: icon_button(theme, {
+            margin: {
+                left: ITEM_SPACING / 2,
+                right: ITEM_SPACING,
+            },
+        }),
+
+        ...call_controls(theme),
+
+        toggle_contacts_button: toggleable_icon_button(theme, {
+            margin: {
+                left: ITEM_SPACING,
+            },
+        }),
+
+        // Jewel that notifies you that there are new contact requests
+        toggleContactsBadge: {
+            cornerRadius: 3,
+            padding: 2,
+            margin: { top: 3, left: 3 },
+            border: border(theme.lowest),
+            background: foreground(theme.lowest, "accent"),
+        },
+        shareButton: toggleable_text_button(theme, {}),
+        user_menu: user_menu(theme),
+    }
+}

styles/src/themes/rose-pine/common.ts πŸ”—

@@ -1,39 +1,39 @@
-import { ThemeSyntax } from "../../common";
+import { ThemeSyntax } from "../../common"
 
 export const color = {
     default: {
-        base: '#191724',
-        surface: '#1f1d2e',
-        overlay: '#26233a',
-        muted: '#6e6a86',
-        subtle: '#908caa',
-        text: '#e0def4',
-        love: '#eb6f92',
-        gold: '#f6c177',
-        rose: '#ebbcba',
-        pine: '#31748f',
-        foam: '#9ccfd8',
-        iris: '#c4a7e7',
-        highlightLow: '#21202e',
-        highlightMed: '#403d52',
-        highlightHigh: '#524f67',
+        base: "#191724",
+        surface: "#1f1d2e",
+        overlay: "#26233a",
+        muted: "#6e6a86",
+        subtle: "#908caa",
+        text: "#e0def4",
+        love: "#eb6f92",
+        gold: "#f6c177",
+        rose: "#ebbcba",
+        pine: "#31748f",
+        foam: "#9ccfd8",
+        iris: "#c4a7e7",
+        highlightLow: "#21202e",
+        highlightMed: "#403d52",
+        highlightHigh: "#524f67",
     },
     moon: {
-        base: '#232136',
-        surface: '#2a273f',
-        overlay: '#393552',
-        muted: '#6e6a86',
-        subtle: '#908caa',
-        text: '#e0def4',
-        love: '#eb6f92',
-        gold: '#f6c177',
-        rose: '#ea9a97',
-        pine: '#3e8fb0',
-        foam: '#9ccfd8',
-        iris: '#c4a7e7',
-        highlightLow: '#2a283e',
-        highlightMed: '#44415a',
-        highlightHigh: '#56526e',
+        base: "#232136",
+        surface: "#2a273f",
+        overlay: "#393552",
+        muted: "#6e6a86",
+        subtle: "#908caa",
+        text: "#e0def4",
+        love: "#eb6f92",
+        gold: "#f6c177",
+        rose: "#ea9a97",
+        pine: "#3e8fb0",
+        foam: "#9ccfd8",
+        iris: "#c4a7e7",
+        highlightLow: "#2a283e",
+        highlightMed: "#44415a",
+        highlightHigh: "#56526e",
     },
     dawn: {
         base: "#faf4ed",
@@ -51,8 +51,8 @@ export const color = {
         highlightLow: "#f4ede8",
         highlightMed: "#dfdad9",
         highlightHigh: "#cecacd",
-    }
-};
+    },
+}
 
 export const syntax = (c: typeof color.default): Partial<ThemeSyntax> => {
     return {

styles/src/themes/rose-pine/rose-pine-dawn.ts πŸ”—

@@ -6,12 +6,12 @@ import {
     ThemeConfig,
 } from "../../common"
 
-import { color as c, syntax } from "./common";
+import { color as c, syntax } from "./common"
 
 const color = c.dawn
 
-const green = chroma.mix(color.foam, "#10b981", 0.6, 'lab');
-const magenta = chroma.mix(color.love, color.pine, 0.5, 'lab');
+const green = chroma.mix(color.foam, "#10b981", 0.6, "lab")
+const magenta = chroma.mix(color.love, color.pine, 0.5, "lab")
 
 export const theme: ThemeConfig = {
     name: "RosΓ© Pine Dawn",
@@ -21,7 +21,19 @@ export const theme: ThemeConfig = {
     licenseUrl: "https://github.com/edunfelt/base16-rose-pine-scheme",
     licenseFile: `${__dirname}/LICENSE`,
     inputColor: {
-        neutral: chroma.scale([color.base, color.surface, color.highlightHigh, color.overlay, color.muted, color.subtle, color.text].reverse()).domain([0, 0.35, 0.45, 0.65, 0.7, 0.8, 0.9, 1]),
+        neutral: chroma
+            .scale(
+                [
+                    color.base,
+                    color.surface,
+                    color.highlightHigh,
+                    color.overlay,
+                    color.muted,
+                    color.subtle,
+                    color.text,
+                ].reverse()
+            )
+            .domain([0, 0.35, 0.45, 0.65, 0.7, 0.8, 0.9, 1]),
         red: colorRamp(chroma(color.love)),
         orange: colorRamp(chroma(color.iris)),
         yellow: colorRamp(chroma(color.gold)),
@@ -32,6 +44,6 @@ export const theme: ThemeConfig = {
         magenta: colorRamp(chroma(magenta)),
     },
     override: {
-        syntax: syntax(color)
-    }
+        syntax: syntax(color),
+    },
 }

styles/src/themes/rose-pine/rose-pine-moon.ts πŸ”—

@@ -6,12 +6,12 @@ import {
     ThemeConfig,
 } from "../../common"
 
-import { color as c, syntax } from "./common";
+import { color as c, syntax } from "./common"
 
 const color = c.moon
 
-const green = chroma.mix(color.foam, "#10b981", 0.6, 'lab');
-const magenta = chroma.mix(color.love, color.pine, 0.5, 'lab');
+const green = chroma.mix(color.foam, "#10b981", 0.6, "lab")
+const magenta = chroma.mix(color.love, color.pine, 0.5, "lab")
 
 export const theme: ThemeConfig = {
     name: "RosΓ© Pine Moon",
@@ -21,7 +21,17 @@ export const theme: ThemeConfig = {
     licenseUrl: "https://github.com/edunfelt/base16-rose-pine-scheme",
     licenseFile: `${__dirname}/LICENSE`,
     inputColor: {
-        neutral: chroma.scale([color.base, color.surface, color.highlightHigh, color.overlay, color.muted, color.subtle, color.text]).domain([0, 0.3, 0.55, 1]),
+        neutral: chroma
+            .scale([
+                color.base,
+                color.surface,
+                color.highlightHigh,
+                color.overlay,
+                color.muted,
+                color.subtle,
+                color.text,
+            ])
+            .domain([0, 0.3, 0.55, 1]),
         red: colorRamp(chroma(color.love)),
         orange: colorRamp(chroma(color.iris)),
         yellow: colorRamp(chroma(color.gold)),
@@ -32,6 +42,6 @@ export const theme: ThemeConfig = {
         magenta: colorRamp(chroma(magenta)),
     },
     override: {
-        syntax: syntax(color)
-    }
+        syntax: syntax(color),
+    },
 }

styles/src/themes/rose-pine/rose-pine.ts πŸ”—

@@ -5,12 +5,12 @@ import {
     ThemeLicenseType,
     ThemeConfig,
 } from "../../common"
-import { color as c, syntax } from "./common";
+import { color as c, syntax } from "./common"
 
 const color = c.default
 
-const green = chroma.mix(color.foam, "#10b981", 0.6, 'lab');
-const magenta = chroma.mix(color.love, color.pine, 0.5, 'lab');
+const green = chroma.mix(color.foam, "#10b981", 0.6, "lab")
+const magenta = chroma.mix(color.love, color.pine, 0.5, "lab")
 
 export const theme: ThemeConfig = {
     name: "RosΓ© Pine",
@@ -20,7 +20,15 @@ export const theme: ThemeConfig = {
     licenseUrl: "https://github.com/edunfelt/base16-rose-pine-scheme",
     licenseFile: `${__dirname}/LICENSE`,
     inputColor: {
-        neutral: chroma.scale([color.base, color.surface, color.highlightHigh, color.overlay, color.muted, color.subtle, color.text]),
+        neutral: chroma.scale([
+            color.base,
+            color.surface,
+            color.highlightHigh,
+            color.overlay,
+            color.muted,
+            color.subtle,
+            color.text,
+        ]),
         red: colorRamp(chroma(color.love)),
         orange: colorRamp(chroma(color.iris)),
         yellow: colorRamp(chroma(color.gold)),
@@ -31,6 +39,6 @@ export const theme: ThemeConfig = {
         magenta: colorRamp(chroma(magenta)),
     },
     override: {
-        syntax: syntax(color)
-    }
+        syntax: syntax(color),
+    },
 }