Browse Source

refactor Select component to use settings variant for settings modal styling

David Hill 1 month ago
parent
commit
7be6671e6e

+ 0 - 1
packages/app/src/components/prompt-input.tsx

@@ -1583,7 +1583,6 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
                     onSelect={local.agent.set}
                     class="capitalize"
                     variant="ghost"
-                    triggerVariant="button"
                   />
                 </TooltipKeybind>
                 <Show

+ 6 - 0
packages/app/src/components/settings-general.tsx

@@ -69,6 +69,7 @@ export const SettingsGeneral: Component = () => {
                 }}
                 variant="secondary"
                 size="small"
+                triggerVariant="settings"
               />
             </SettingsRow>
 
@@ -99,6 +100,7 @@ export const SettingsGeneral: Component = () => {
                 }}
                 variant="secondary"
                 size="small"
+                triggerVariant="settings"
               />
             </SettingsRow>
 
@@ -111,6 +113,7 @@ export const SettingsGeneral: Component = () => {
                 onSelect={(option) => option && settings.appearance.setFont(option.value)}
                 variant="secondary"
                 size="small"
+                triggerVariant="settings"
                 triggerStyle={{ "font-family": monoFontFamily(settings.appearance.font()), "min-width": "180px" }}
               >
                 {(option) => <span style={{ "font-family": monoFontFamily(option?.value) }}>{option?.label}</span>}
@@ -172,6 +175,7 @@ export const SettingsGeneral: Component = () => {
                 }}
                 variant="secondary"
                 size="small"
+                triggerVariant="settings"
               />
             </SettingsRow>
 
@@ -192,6 +196,7 @@ export const SettingsGeneral: Component = () => {
                 }}
                 variant="secondary"
                 size="small"
+                triggerVariant="settings"
               />
             </SettingsRow>
 
@@ -212,6 +217,7 @@ export const SettingsGeneral: Component = () => {
                 }}
                 variant="secondary"
                 size="small"
+                triggerVariant="settings"
               />
             </SettingsRow>
           </div>

+ 1 - 0
packages/app/src/components/settings-permissions.tsx

@@ -129,6 +129,7 @@ export const SettingsPermissions: Component = () => {
                     onSelect={(option) => option && setPermission(item.id, option.value)}
                     variant="secondary"
                     size="small"
+                    triggerVariant="settings"
                   />
                 </SettingsRow>
               )}

+ 81 - 43
packages/ui/src/components/select.css

@@ -1,70 +1,89 @@
 [data-component="select"] {
   [data-slot="select-select-trigger"] {
-    padding: 6px 6px 6px 12px;
+    padding: 0 4px 0 8px;
     box-shadow: none;
-    border-radius: 6px;
-    min-width: 160px;
-    height: 32px;
-    justify-content: flex-end;
-    gap: 12px;
-    background-color: transparent;
 
     [data-slot="select-select-trigger-value"] {
       overflow: hidden;
       text-overflow: ellipsis;
       white-space: nowrap;
-      font-size: var(--font-size-base);
-      font-weight: var(--font-weight-regular);
     }
     [data-slot="select-select-trigger-icon"] {
       width: 16px;
-      height: 20px;
+      height: 16px;
       display: flex;
       align-items: center;
       justify-content: center;
       flex-shrink: 0;
       color: var(--text-weak);
-      background-color: var(--surface-raised-base);
-      border-radius: 4px;
       transition: transform 0.1s ease-in-out;
     }
 
-    &[data-slot="select-select-trigger"]:hover:not(:disabled),
-    &[data-slot="select-select-trigger"][data-expanded],
-    &[data-slot="select-select-trigger"][data-expanded]:hover:not(:disabled) {
-      background-color: var(--input-base);
-      box-shadow: var(--shadow-xs-border-base);
+    &[data-expanded] {
+      &[data-variant="secondary"] {
+        background-color: var(--button-secondary-hover);
+      }
+      &[data-variant="ghost"] {
+        background-color: var(--surface-raised-base-active);
+      }
+      &[data-variant="primary"] {
+        background-color: var(--icon-strong-active);
+      }
     }
 
     &:not([data-expanded]):focus {
-      background-color: transparent;
-      box-shadow: none;
+      &[data-variant="secondary"] {
+        background-color: var(--button-secondary-base);
+      }
+      &[data-variant="ghost"] {
+        background-color: transparent;
+      }
+      &[data-variant="primary"] {
+        background-color: var(--icon-strong-base);
+      }
     }
   }
 
-  &[data-trigger-style="button"] {
+  &[data-trigger-style="settings"] {
     [data-slot="select-select-trigger"] {
-      padding: 0 6px;
-      min-width: auto;
-      height: 24px;
-      justify-content: center;
-      gap: 6px;
+      padding: 6px 6px 6px 12px;
+      box-shadow: none;
+      border-radius: 6px;
+      min-width: 160px;
+      height: 32px;
+      justify-content: flex-end;
+      gap: 12px;
+      background-color: transparent;
 
-      [data-slot="select-select-trigger-icon"] {
-        width: auto;
-        height: auto;
-        background-color: transparent;
-        border-radius: 0;
+      [data-slot="select-select-trigger-value"] {
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+        font-size: var(--font-size-base);
+        font-weight: var(--font-weight-regular);
       }
-
-      &[data-slot="select-select-trigger"]:hover:not(:disabled) {
-        background-color: var(--surface-raised-base-hover);
-        box-shadow: none;
+      [data-slot="select-select-trigger-icon"] {
+        width: 16px;
+        height: 20px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        flex-shrink: 0;
+        color: var(--text-weak);
+        background-color: var(--surface-raised-base);
+        border-radius: 4px;
+        transition: transform 0.1s ease-in-out;
       }
 
+      &[data-slot="select-select-trigger"]:hover:not(:disabled),
       &[data-slot="select-select-trigger"][data-expanded],
       &[data-slot="select-select-trigger"][data-expanded]:hover:not(:disabled) {
-        background-color: var(--surface-raised-base-active);
+        background-color: var(--input-base);
+        box-shadow: var(--shadow-xs-border-base);
+      }
+
+      &:not([data-expanded]):focus {
+        background-color: transparent;
         box-shadow: none;
       }
     }
@@ -72,12 +91,12 @@
 }
 
 [data-component="select-content"] {
-  min-width: 160px;
+  min-width: 104px;
   max-width: 23rem;
   overflow: hidden;
-  border-radius: 8px;
+  border-radius: var(--radius-md);
   background-color: var(--surface-raised-stronger-non-alpha);
-  padding: 0;
+  padding: 4px;
   box-shadow: var(--shadow-xs-border);
   z-index: 60;
 
@@ -92,7 +111,6 @@
     overflow-x: hidden;
     display: flex;
     flex-direction: column;
-    padding: 4px;
 
     &:focus {
       outline: none;
@@ -112,12 +130,12 @@
     border-radius: 4px;
     cursor: default;
 
-    /* text-14-regular */
+    /* text-12-medium */
     font-family: var(--font-family-sans);
-    font-size: var(--font-size-base);
+    font-size: var(--font-size-small);
     font-style: normal;
-    font-weight: var(--font-weight-regular);
-    line-height: var(--line-height-large);
+    font-weight: var(--font-weight-medium);
+    line-height: var(--line-height-large); /* 166.667% */
     letter-spacing: var(--letter-spacing-normal);
 
     color: var(--text-strong);
@@ -152,6 +170,26 @@
   }
 }
 
+[data-component="select-content"][data-trigger-style="settings"] {
+  min-width: 160px;
+  border-radius: 8px;
+  padding: 0;
+
+  [data-slot="select-select-content-list"] {
+    padding: 4px;
+  }
+
+  [data-slot="select-select-item"] {
+    /* text-14-regular */
+    font-family: var(--font-family-sans);
+    font-size: var(--font-size-base);
+    font-style: normal;
+    font-weight: var(--font-weight-regular);
+    line-height: var(--line-height-large);
+    letter-spacing: var(--letter-spacing-normal);
+  }
+}
+
 @keyframes select-open {
   from {
     opacity: 0;

+ 4 - 3
packages/ui/src/components/select.tsx

@@ -17,7 +17,7 @@ export type SelectProps<T> = Omit<ComponentProps<typeof Kobalte<T>>, "value" | "
   classList?: ComponentProps<"div">["classList"]
   children?: (item: T | undefined) => JSX.Element
   triggerStyle?: JSX.CSSProperties
-  triggerVariant?: "default" | "button"
+  triggerVariant?: "settings"
 }
 
 export function Select<T>(props: SelectProps<T> & Omit<ButtonProps, "children">) {
@@ -84,7 +84,7 @@ export function Select<T>(props: SelectProps<T> & Omit<ButtonProps, "children">)
       {...others}
       data-component="select"
       data-trigger-style={local.triggerVariant}
-      placement="bottom-end"
+      placement={local.triggerVariant === "settings" ? "bottom-end" : "bottom-start"}
       gutter={4}
       value={local.current}
       options={grouped()}
@@ -148,7 +148,7 @@ export function Select<T>(props: SelectProps<T> & Omit<ButtonProps, "children">)
           }}
         </Kobalte.Value>
         <Kobalte.Icon data-slot="select-select-trigger-icon">
-          <Icon name={local.triggerVariant === "button" ? "chevron-down" : "selector"} size="small" />
+          <Icon name={local.triggerVariant === "settings" ? "selector" : "chevron-down"} size="small" />
         </Kobalte.Icon>
       </Kobalte.Trigger>
       <Kobalte.Portal>
@@ -158,6 +158,7 @@ export function Select<T>(props: SelectProps<T> & Omit<ButtonProps, "children">)
             [local.class ?? ""]: !!local.class,
           }}
           data-component="select-content"
+          data-trigger-style={local.triggerVariant}
         >
           <Kobalte.Listbox data-slot="select-select-content-list" />
         </Kobalte.Content>