mirror of
https://github.com/stackblitz/bolt.new
synced 2025-03-12 14:58:30 +00:00
Merge pull request #592 from oTToDev-CE/ui/settings-style
ui/settings style
This commit is contained in:
commit
db8c65ec2b
@ -10,6 +10,9 @@ import { toast } from 'react-toastify';
|
|||||||
import { useNavigate } from '@remix-run/react';
|
import { useNavigate } from '@remix-run/react';
|
||||||
import commit from '~/commit.json';
|
import commit from '~/commit.json';
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
|
import { SettingsSlider } from './SettingsSlider';
|
||||||
|
import '~/styles/components/SettingsSlider.scss';
|
||||||
|
import '~/styles/components/Settings.scss';
|
||||||
|
|
||||||
interface SettingsProps {
|
interface SettingsProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@ -27,6 +30,7 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|||||||
const [isDebugEnabled, setIsDebugEnabled] = useState(false);
|
const [isDebugEnabled, setIsDebugEnabled] = useState(false);
|
||||||
const [searchTerm, setSearchTerm] = useState('');
|
const [searchTerm, setSearchTerm] = useState('');
|
||||||
const [isDeleting, setIsDeleting] = useState(false);
|
const [isDeleting, setIsDeleting] = useState(false);
|
||||||
|
const [isJustSayEnabled, setIsJustSayEnabled] = useState(false);
|
||||||
|
|
||||||
// Load base URLs from cookies
|
// Load base URLs from cookies
|
||||||
const [baseUrls, setBaseUrls] = useState(() => {
|
const [baseUrls, setBaseUrls] = useState(() => {
|
||||||
@ -203,21 +207,20 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|||||||
</RadixDialog.Overlay>
|
</RadixDialog.Overlay>
|
||||||
<RadixDialog.Content asChild>
|
<RadixDialog.Content asChild>
|
||||||
<motion.div
|
<motion.div
|
||||||
className="fixed top-[50%] left-[50%] z-max h-[85vh] w-[90vw] max-w-[900px] translate-x-[-50%] translate-y-[-50%] border border-bolt-elements-borderColor rounded-lg bg-gray-800 shadow-lg focus:outline-none overflow-hidden"
|
className="fixed top-[50%] left-[50%] z-max h-[85vh] w-[90vw] max-w-[900px] translate-x-[-50%] translate-y-[-50%] border border-bolt-elements-borderColor rounded-lg shadow-lg focus:outline-none overflow-hidden"
|
||||||
initial="closed"
|
initial="closed"
|
||||||
animate="open"
|
animate="open"
|
||||||
exit="closed"
|
exit="closed"
|
||||||
variants={dialogVariants}
|
variants={dialogVariants}
|
||||||
>
|
>
|
||||||
<div className="flex h-full">
|
<div className="flex h-full">
|
||||||
<div className="w-48 border-r border-bolt-elements-borderColor bg-gray-700 p-4 flex flex-col justify-between">
|
<div className="w-48 border-r border-bolt-elements-borderColor bg-white dark:bg-gray-900 p-4 flex flex-col justify-between settings-tabs">
|
||||||
{tabs.map((tab) => (
|
{tabs.map((tab) => (
|
||||||
<button
|
<button
|
||||||
key={tab.id}
|
key={tab.id}
|
||||||
onClick={() => setActiveTab(tab.id)}
|
onClick={() => setActiveTab(tab.id)}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'w-full flex items-center gap-2 px-4 py-3 rounded-lg text-left text-sm transition-all mb-2',
|
activeTab === tab.id ? 'active' : ''
|
||||||
activeTab === tab.id ? 'bg-blue-600 text-white' : 'bg-gray-600 text-gray-200 hover:bg-blue-500',
|
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className={tab.icon} />
|
<div className={tab.icon} />
|
||||||
@ -229,27 +232,29 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|||||||
href="https://github.com/coleam00/bolt.new-any-llm"
|
href="https://github.com/coleam00/bolt.new-any-llm"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="flex items-center justify-center bg-blue-600 text-white rounded-lg py-2 hover:bg-blue-500 transition-colors duration-200"
|
className="settings-button flex items-center gap-2"
|
||||||
>
|
>
|
||||||
|
<div className="i-ph:github-logo" />
|
||||||
GitHub
|
GitHub
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
href="https://coleam00.github.io/bolt.new-any-llm"
|
href="https://coleam00.github.io/bolt.new-any-llm"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="flex items-center justify-center bg-blue-600 text-white rounded-lg py-2 hover:bg-blue-500 transition-colors duration-200"
|
className="settings-button flex items-center gap-2"
|
||||||
>
|
>
|
||||||
|
<div className="i-ph:book" />
|
||||||
Docs
|
Docs
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex-1 flex flex-col p-8">
|
<div className="flex-1 flex flex-col p-8 bg-gray-50 dark:bg-gray-800">
|
||||||
<DialogTitle className="flex-shrink-0 text-lg font-semibold text-white">Settings</DialogTitle>
|
<DialogTitle className="flex-shrink-0 text-lg font-semibold text-bolt-elements-textPrimary">Settings</DialogTitle>
|
||||||
<div className="flex-1 overflow-y-auto">
|
<div className="flex-1 overflow-y-auto">
|
||||||
{activeTab === 'chat-history' && (
|
{activeTab === 'chat-history' && (
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
<h3 className="text-lg font-medium text-white mb-4">Chat History</h3>
|
<h3 className="text-lg font-medium text-bolt-elements-textPrimary mb-4">Chat History</h3>
|
||||||
<button
|
<button
|
||||||
onClick={handleExportAllChats}
|
onClick={handleExportAllChats}
|
||||||
className="bg-blue-500 text-white rounded-lg px-4 py-2 hover:bg-blue-600 mb-4 transition-colors duration-200"
|
className="bg-blue-500 text-white rounded-lg px-4 py-2 hover:bg-blue-600 mb-4 transition-colors duration-200"
|
||||||
@ -257,7 +262,7 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|||||||
Export All Chats
|
Export All Chats
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div className="bg-red-500 text-white rounded-lg p-4 mb-4">
|
<div className="text-bolt-elements-textPrimary rounded-lg p-4 mb-4 settings-danger-area">
|
||||||
<h4 className="font-semibold">Danger Area</h4>
|
<h4 className="font-semibold">Danger Area</h4>
|
||||||
<p className="mb-2">This action cannot be undone!</p>
|
<p className="mb-2">This action cannot be undone!</p>
|
||||||
<button
|
<button
|
||||||
@ -275,21 +280,23 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|||||||
)}
|
)}
|
||||||
{activeTab === 'providers' && (
|
{activeTab === 'providers' && (
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
<h3 className="text-lg font-medium text-white mb-4">Providers</h3>
|
<div className="flex items-center justify-between mb-4">
|
||||||
<input
|
<h3 className="text-lg font-medium text-bolt-elements-textPrimary">Providers</h3>
|
||||||
type="text"
|
<input
|
||||||
placeholder="Search providers..."
|
type="text"
|
||||||
value={searchTerm}
|
placeholder="Search providers..."
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
value={searchTerm}
|
||||||
className="mb-4 p-2 rounded border border-gray-300 w-full"
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
/>
|
className="mb-4 p-2 rounded border border-gray-300"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
{filteredProviders.map((provider) => (
|
{filteredProviders.map((provider) => (
|
||||||
<div
|
<div
|
||||||
key={provider.name}
|
key={provider.name}
|
||||||
className="flex flex-col mb-6 provider-item hover:bg-gray-600 p-4 rounded-lg"
|
className="flex flex-col mb-6 provider-item hover:bg-bolt-elements-bg-depth-3 p-4 rounded-lg"
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between mb-2">
|
<div className="flex items-center justify-between mb-2">
|
||||||
<span className="text-white">{provider.name}</span>
|
<span className="text-bolt-elements-textPrimary">{provider.name}</span>
|
||||||
<label className="relative inline-flex items-center cursor-pointer">
|
<label className="relative inline-flex items-center cursor-pointer">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@ -297,25 +304,26 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|||||||
checked={provider.isEnabled}
|
checked={provider.isEnabled}
|
||||||
onChange={() => handleToggleProvider(provider.name)}
|
onChange={() => handleToggleProvider(provider.name)}
|
||||||
/>
|
/>
|
||||||
<div className="w-11 h-6 bg-gray-300 rounded-full shadow-inner"></div>
|
<div className={classNames(
|
||||||
<div
|
'settings-toggle__track',
|
||||||
className={`absolute left-0 w-6 h-6 bg-white rounded-full shadow transition-transform duration-200 ease-in-out ${
|
provider.isEnabled ? 'settings-toggle__track--enabled' : 'settings-toggle__track--disabled'
|
||||||
provider.isEnabled ? 'transform translate-x-full bg-green-500' : ''
|
)}></div>
|
||||||
}`}
|
<div className={classNames(
|
||||||
></div>
|
'settings-toggle__thumb',
|
||||||
|
provider.isEnabled ? 'settings-toggle__thumb--enabled' : ''
|
||||||
|
)}></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Base URL input for configurable providers */}
|
{/* Base URL input for configurable providers */}
|
||||||
{URL_CONFIGURABLE_PROVIDERS.includes(provider.name) && provider.isEnabled && (
|
{URL_CONFIGURABLE_PROVIDERS.includes(provider.name) && provider.isEnabled && (
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<label className="block text-sm text-gray-300 mb-1">Base URL:</label>
|
<label className="block text-sm text-bolt-elements-textSecondary mb-1">Base URL:</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={baseUrls[provider.name]}
|
value={baseUrls[provider.name]}
|
||||||
onChange={(e) => handleBaseUrlChange(provider.name, e.target.value)}
|
onChange={(e) => handleBaseUrlChange(provider.name, e.target.value)}
|
||||||
placeholder={`Enter ${provider.name} base URL`}
|
placeholder={`Enter ${provider.name} base URL`}
|
||||||
className="w-full p-2 rounded border border-gray-600 bg-gray-700 text-white text-sm"
|
className="w-full p-2 rounded border border-bolt-elements-borderColor bg-bolt-elements-bg-depth-2 text-bolt-elements-textPrimary text-sm"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -324,9 +332,10 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{activeTab === 'features' && (
|
{activeTab === 'features' && (
|
||||||
<div className="p-4">
|
<div className="p-4 bg-bolt-elements-bg-depth-2 border border-bolt-elements-borderColor rounded-lg mb-4">
|
||||||
|
<h3 className="text-lg font-medium text-bolt-elements-textPrimary mb-4">Feature Settings</h3>
|
||||||
<div className="flex items-center justify-between mb-2">
|
<div className="flex items-center justify-between mb-2">
|
||||||
<span className="text-white">Debug Info</span>
|
<span className="text-bolt-elements-textPrimary">Debug Info</span>
|
||||||
<label className="relative inline-flex items-center cursor-pointer">
|
<label className="relative inline-flex items-center cursor-pointer">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@ -334,20 +343,45 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|||||||
checked={isDebugEnabled}
|
checked={isDebugEnabled}
|
||||||
onChange={() => setIsDebugEnabled(!isDebugEnabled)}
|
onChange={() => setIsDebugEnabled(!isDebugEnabled)}
|
||||||
/>
|
/>
|
||||||
<div className="w-11 h-6 bg-gray-300 rounded-full shadow-inner"></div>
|
<div className={classNames(
|
||||||
<div
|
'settings-toggle__track',
|
||||||
className={`absolute left-0 w-6 h-6 bg-white rounded-full shadow transition-transform duration-200 ease-in-out ${
|
isDebugEnabled ? 'settings-toggle__track--enabled' : 'settings-toggle__track--disabled'
|
||||||
isDebugEnabled ? 'transform translate-x-full bg-green-500' : ''
|
)}></div>
|
||||||
}`}
|
<div className={classNames(
|
||||||
></div>
|
'settings-toggle__thumb',
|
||||||
|
isDebugEnabled ? 'settings-toggle__thumb--enabled' : ''
|
||||||
|
)}></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{activeTab === 'features' && (
|
||||||
|
<div className="p-4 bg-bolt-elements-bg-depth-2 border border-bolt-elements-borderColor rounded-lg">
|
||||||
|
<h3 className="text-lg font-medium text-bolt-elements-textPrimary mb-4">Experimental Area</h3>
|
||||||
|
<div className="flex items-center justify-between mb-2">
|
||||||
|
<span className="text-bolt-elements-textPrimary">Replace with local models</span>
|
||||||
|
<label className="relative inline-flex items-center cursor-pointer">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="sr-only"
|
||||||
|
checked={isJustSayEnabled}
|
||||||
|
onChange={() => setIsJustSayEnabled(!isJustSayEnabled)}
|
||||||
|
/>
|
||||||
|
<div className={classNames(
|
||||||
|
'settings-toggle__track',
|
||||||
|
isJustSayEnabled ? 'settings-toggle__track--enabled' : 'settings-toggle__track--disabled'
|
||||||
|
)}></div>
|
||||||
|
<div className={classNames(
|
||||||
|
'settings-toggle__thumb',
|
||||||
|
isJustSayEnabled ? 'settings-toggle__thumb--enabled' : ''
|
||||||
|
)}></div>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="feature-row">{/* Your feature content here */}</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{activeTab === 'debug' && isDebugEnabled && (
|
{activeTab === 'debug' && isDebugEnabled && (
|
||||||
<div className="p-4">
|
<div className="p-4">
|
||||||
<h3 className="text-lg font-medium text-white mb-4">Debug Tab</h3>
|
<h3 className="text-lg font-medium text-bolt-elements-textPrimary mb-4">Debug Tab</h3>
|
||||||
<button
|
<button
|
||||||
onClick={handleCopyToClipboard}
|
onClick={handleCopyToClipboard}
|
||||||
className="bg-blue-500 text-white rounded-lg px-4 py-2 hover:bg-blue-600 mb-4 transition-colors duration-200"
|
className="bg-blue-500 text-white rounded-lg px-4 py-2 hover:bg-blue-600 mb-4 transition-colors duration-200"
|
||||||
@ -355,30 +389,30 @@ export const Settings = ({ open, onClose }: SettingsProps) => {
|
|||||||
Copy to Clipboard
|
Copy to Clipboard
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<h4 className="text-md font-medium text-white">System Information</h4>
|
<h4 className="text-md font-medium text-bolt-elements-textPrimary">System Information</h4>
|
||||||
<p className="text-white">OS: {navigator.platform}</p>
|
<p className="text-bolt-elements-textSecondary">OS: {navigator.platform}</p>
|
||||||
<p className="text-white">Browser: {navigator.userAgent}</p>
|
<p className="text-bolt-elements-textSecondary">Browser: {navigator.userAgent}</p>
|
||||||
|
|
||||||
<h4 className="text-md font-medium text-white mt-4">Active Features</h4>
|
<h4 className="text-md font-medium text-bolt-elements-textPrimary mt-4">Active Features</h4>
|
||||||
<ul>
|
<ul>
|
||||||
{providers
|
{providers
|
||||||
.filter((provider) => provider.isEnabled)
|
.filter((provider) => provider.isEnabled)
|
||||||
.map((provider) => (
|
.map((provider) => (
|
||||||
<li key={provider.name} className="text-white">
|
<li key={provider.name} className="text-bolt-elements-textSecondary">
|
||||||
{provider.name}
|
{provider.name}
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h4 className="text-md font-medium text-white mt-4">Base URLs</h4>
|
<h4 className="text-md font-medium text-bolt-elements-textPrimary mt-4">Base URLs</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li className="text-white">Ollama: {process.env.REACT_APP_OLLAMA_URL}</li>
|
<li className="text-bolt-elements-textSecondary">Ollama: {process.env.REACT_APP_OLLAMA_URL}</li>
|
||||||
<li className="text-white">OpenAI: {process.env.REACT_APP_OPENAI_URL}</li>
|
<li className="text-bolt-elements-textSecondary">OpenAI: {process.env.REACT_APP_OPENAI_URL}</li>
|
||||||
<li className="text-white">LM Studio: {process.env.REACT_APP_LM_STUDIO_URL}</li>
|
<li className="text-bolt-elements-textSecondary">LM Studio: {process.env.REACT_APP_LM_STUDIO_URL}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h4 className="text-md font-medium text-white mt-4">Version Information</h4>
|
<h4 className="text-md font-medium text-bolt-elements-textPrimary mt-4">Version Information</h4>
|
||||||
<p className="text-white">Version Hash: {versionHash}</p>
|
<p className="text-bolt-elements-textSecondary">Version Hash: {versionHash}</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { classNames } from '~/utils/classNames';
|
import { classNames } from '~/utils/classNames';
|
||||||
|
import '~/styles/components/SettingsSlider.scss';
|
||||||
|
|
||||||
interface SliderOption<T> {
|
interface SliderOption<T> {
|
||||||
value: T;
|
value: T;
|
||||||
@ -22,11 +23,11 @@ export const SettingsSlider = memo(<T,>({ selected, options, setSelected }: Sett
|
|||||||
const isLeftSelected = selected === options.left.value;
|
const isLeftSelected = selected === options.left.value;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex items-center bg-bolt-elements-prompt-background rounded-lg">
|
<div className="settings-slider">
|
||||||
<motion.div
|
<motion.div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'absolute h-full bg-green-500 transition-all duration-300 rounded-lg',
|
'settings-slider__thumb',
|
||||||
isLeftSelected ? 'left-0 w-1/2' : 'right-0 w-1/2',
|
isLeftSelected ? 'settings-slider__thumb--left' : 'settings-slider__thumb--right'
|
||||||
)}
|
)}
|
||||||
initial={false}
|
initial={false}
|
||||||
animate={{
|
animate={{
|
||||||
@ -42,8 +43,8 @@ export const SettingsSlider = memo(<T,>({ selected, options, setSelected }: Sett
|
|||||||
<button
|
<button
|
||||||
onClick={() => setSelected?.(options.left.value)}
|
onClick={() => setSelected?.(options.left.value)}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'relative z-10 flex-1 p-2 rounded-lg text-sm transition-colors duration-200',
|
'settings-slider__button',
|
||||||
isLeftSelected ? 'text-white' : 'text-bolt-elements-textSecondary hover:text-bolt-elements-textPrimary',
|
isLeftSelected ? 'settings-slider__button--selected' : 'settings-slider__button--unselected'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{options.left.text}
|
{options.left.text}
|
||||||
@ -51,8 +52,8 @@ export const SettingsSlider = memo(<T,>({ selected, options, setSelected }: Sett
|
|||||||
<button
|
<button
|
||||||
onClick={() => setSelected?.(options.right.value)}
|
onClick={() => setSelected?.(options.right.value)}
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'relative z-10 flex-1 p-2 rounded-lg text-sm transition-colors duration-200',
|
'settings-slider__button',
|
||||||
!isLeftSelected ? 'text-white' : 'text-bolt-elements-textSecondary hover:text-bolt-elements-textPrimary',
|
!isLeftSelected ? 'settings-slider__button--selected' : 'settings-slider__button--unselected'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{options.right.text}
|
{options.right.text}
|
||||||
|
60
app/styles/components/Settings.scss
Normal file
60
app/styles/components/Settings.scss
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
.settings-tabs {
|
||||||
|
button {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
transition: all 0.2s;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: var(--bolt-elements-button-primary-background);
|
||||||
|
color: var(--bolt-elements-textPrimary);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.active) {
|
||||||
|
background: var(--bolt-elements-bg-depth-3);
|
||||||
|
color: var(--bolt-elements-textPrimary);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: var(--bolt-elements-button-primary-backgroundHover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-button {
|
||||||
|
background-color: var(--bolt-elements-button-primary-background);
|
||||||
|
color: var(--bolt-elements-textPrimary);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--bolt-elements-button-primary-backgroundHover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-danger-area {
|
||||||
|
background-color: transparent;
|
||||||
|
color: var(--bolt-elements-textPrimary);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
padding: 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
|
||||||
|
button {
|
||||||
|
background-color: var(--bolt-elements-button-danger-background);
|
||||||
|
color: var(--bolt-elements-button-danger-text);
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--bolt-elements-button-danger-backgroundHover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
51
app/styles/components/SettingsSlider.scss
Normal file
51
app/styles/components/SettingsSlider.scss
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
.settings-slider {
|
||||||
|
@apply relative flex items-center bg-bolt-elements-prompt-background rounded-lg;
|
||||||
|
|
||||||
|
&__thumb {
|
||||||
|
@apply absolute h-full transition-all duration-300 rounded-lg;
|
||||||
|
background-color: var(--bolt-elements-button-primary-background);
|
||||||
|
|
||||||
|
&--left {
|
||||||
|
@apply left-0 w-1/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--right {
|
||||||
|
@apply right-0 w-1/2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__button {
|
||||||
|
@apply relative z-10 flex-1 p-2 rounded-lg text-sm transition-colors duration-200;
|
||||||
|
|
||||||
|
&--selected {
|
||||||
|
@apply text-bolt-elements-textPrimary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--unselected {
|
||||||
|
@apply text-bolt-elements-textSecondary hover:text-bolt-elements-textPrimary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.settings-toggle {
|
||||||
|
&__track {
|
||||||
|
@apply w-11 h-6 rounded-full shadow-inner transition-colors duration-200;
|
||||||
|
|
||||||
|
&--enabled {
|
||||||
|
background-color: var(--bolt-elements-item-contentAccent);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disabled {
|
||||||
|
background-color: var(--bolt-elements-bg-depth-3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__thumb {
|
||||||
|
@apply absolute left-0 w-6 h-6 rounded-full shadow transition-transform duration-200 ease-in-out;
|
||||||
|
background-color: var(--bolt-elements-textPrimary);
|
||||||
|
|
||||||
|
&--enabled {
|
||||||
|
@apply transform translate-x-full;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user