mirror of
https://github.com/Kingsrook/qqq-frontend-material-dashboard.git
synced 2025-07-18 13:20:43 +00:00
CTL-214: initial checkin
This commit is contained in:
@ -23,8 +23,9 @@ import {InputAdornment, InputLabel} from "@mui/material";
|
||||
import Box from "@mui/material/Box";
|
||||
import Switch from "@mui/material/Switch";
|
||||
import {ErrorMessage, Field, useFormikContext} from "formik";
|
||||
import React, {useState} from "react";
|
||||
import React, {useContext, useState} from "react";
|
||||
import AceEditor from "react-ace";
|
||||
import QContext from "QContext";
|
||||
import BooleanFieldSwitch from "qqq/components/forms/BooleanFieldSwitch";
|
||||
import MDInput from "qqq/components/legacy/MDInput";
|
||||
import MDTypography from "qqq/components/legacy/MDTypography";
|
||||
@ -52,6 +53,7 @@ function QDynamicFormField({
|
||||
{
|
||||
const [switchChecked, setSwitchChecked] = useState(false);
|
||||
const [isDisabled, setIsDisabled] = useState(!isEditable || bulkEditMode);
|
||||
const {setAllowShortcuts} = useContext(QContext);
|
||||
|
||||
const {setFieldValue} = useFormikContext();
|
||||
|
||||
@ -125,6 +127,14 @@ function QDynamicFormField({
|
||||
field = (
|
||||
<>
|
||||
<Field {...rest} onWheel={handleOnWheel} name={name} type={type} as={MDInput} variant="standard" label={label} InputLabelProps={inputLabelProps} InputProps={inputProps} fullWidth disabled={isDisabled}
|
||||
onBlur={(e: any) =>
|
||||
{
|
||||
setAllowShortcuts(true);
|
||||
}}
|
||||
onFocus={(e: any) =>
|
||||
{
|
||||
setAllowShortcuts(false);
|
||||
}}
|
||||
onKeyPress={(e: any) =>
|
||||
{
|
||||
if (e.key === "Enter")
|
||||
|
@ -30,8 +30,9 @@ import ListItemIcon from "@mui/material/ListItemIcon";
|
||||
import Menu from "@mui/material/Menu";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import Toolbar from "@mui/material/Toolbar";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import React, {useContext, useEffect, useState} from "react";
|
||||
import {useLocation, useNavigate} from "react-router-dom";
|
||||
import QContext from "QContext";
|
||||
import QBreadcrumbs, {routeToLabel} from "qqq/components/horseshoe/Breadcrumbs";
|
||||
import {navbar, navbarContainer, navbarIconButton, navbarRow,} from "qqq/components/horseshoe/Styles";
|
||||
import {setTransparentNavbar, useMaterialUIController,} from "qqq/context";
|
||||
@ -62,6 +63,7 @@ function NavBar({absolute, light, isMini}: Props): JSX.Element
|
||||
const [autocompleteValue, setAutocompleteValue] = useState<any>(null);
|
||||
const route = useLocation().pathname.split("/").slice(1);
|
||||
const navigate = useNavigate();
|
||||
const {setAllowShortcuts} = useContext(QContext);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
@ -93,7 +95,6 @@ function NavBar({absolute, light, isMini}: Props): JSX.Element
|
||||
buildHistoryEntries();
|
||||
|
||||
const history = HistoryUtils.get();
|
||||
setHistory([ {label: "The Godfather", id: 1}, {label: "Pulp Fiction", id: 2}]);
|
||||
const options = [] as any;
|
||||
history.entries.reverse().forEach((entry, index) =>
|
||||
options.push({label: `${entry.label} index`, id: index, key: index, path: entry.path, iconName: entry.iconName})
|
||||
@ -119,6 +120,17 @@ function NavBar({absolute, light, isMini}: Props): JSX.Element
|
||||
setHistory(options);
|
||||
}
|
||||
|
||||
function handleHistoryOnOpen()
|
||||
{
|
||||
setAllowShortcuts(false);
|
||||
buildHistoryEntries();
|
||||
}
|
||||
|
||||
function handleHistoryOnClose()
|
||||
{
|
||||
setAllowShortcuts(true);
|
||||
}
|
||||
|
||||
const handleOpenMenu = (event: any) => setOpenMenu(event.currentTarget);
|
||||
const handleCloseMenu = () => setOpenMenu(false);
|
||||
|
||||
@ -152,7 +164,8 @@ function NavBar({absolute, light, isMini}: Props): JSX.Element
|
||||
autoHighlight
|
||||
blurOnSelect
|
||||
style={{width: "200px"}}
|
||||
onOpen={buildHistoryEntries}
|
||||
onOpen={handleHistoryOnOpen}
|
||||
onClose={handleHistoryOnClose}
|
||||
onChange={handleAutocompleteOnChange}
|
||||
PopperComponent={CustomPopper}
|
||||
isOptionEqualToValue={(option, value) => option.id === value.id}
|
||||
|
@ -26,8 +26,9 @@ import {QProcessMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/
|
||||
import {QTableMetaData} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableMetaData";
|
||||
import {QTableSection} from "@kingsrook/qqq-frontend-core/lib/model/metaData/QTableSection";
|
||||
import {QRecord} from "@kingsrook/qqq-frontend-core/lib/model/QRecord";
|
||||
import {Alert, Box, Typography} from "@mui/material";
|
||||
import {Alert, Typography} from "@mui/material";
|
||||
import Avatar from "@mui/material/Avatar";
|
||||
import Box from "@mui/material/Box";
|
||||
import Button from "@mui/material/Button";
|
||||
import Card from "@mui/material/Card";
|
||||
import Dialog from "@mui/material/Dialog";
|
||||
@ -79,7 +80,6 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
||||
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const {accentColor} = useContext(QContext);
|
||||
|
||||
const pathParts = location.pathname.replace(/\/+$/, "").split("/");
|
||||
const tableName = table.name;
|
||||
@ -102,7 +102,7 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
||||
const [errorMessage, setErrorMessage] = useState(null as string)
|
||||
const [successMessage, setSuccessMessage] = useState(null as string);
|
||||
const [warningMessage, setWarningMessage] = useState(null as string);
|
||||
const {setPageHeader} = useContext(QContext);
|
||||
const {accentColor, setPageHeader, allowShortcuts} = useContext(QContext);
|
||||
const [activeModalProcess, setActiveModalProcess] = useState(null as QProcessMetaData);
|
||||
const [reloadCounter, setReloadCounter] = useState(0);
|
||||
|
||||
@ -113,6 +113,8 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
||||
const openActionsMenu = (event: any) => setActionsMenu(event.currentTarget);
|
||||
const closeActionsMenu = () => setActionsMenu(null);
|
||||
|
||||
|
||||
|
||||
const reload = () =>
|
||||
{
|
||||
setSuccessMessage(null);
|
||||
@ -128,6 +130,47 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
||||
setShowAudit(false);
|
||||
};
|
||||
|
||||
// Toggle the menu when ⌘K is pressed
|
||||
useEffect(() =>
|
||||
{
|
||||
const down = (e: { key: string; metaKey: any; ctrlKey: any; preventDefault: () => void; }) =>
|
||||
{
|
||||
if(allowShortcuts)
|
||||
{
|
||||
if (e.key === "e" && table.capabilities.has(Capability.TABLE_UPDATE) && table.editPermission)
|
||||
{
|
||||
e.preventDefault()
|
||||
navigate("edit");
|
||||
}
|
||||
else if (e.key === "c" && table.capabilities.has(Capability.TABLE_INSERT) && table.insertPermission)
|
||||
{
|
||||
e.preventDefault()
|
||||
gotoCreate();
|
||||
}
|
||||
else if (e.key === "d" && table.capabilities.has(Capability.TABLE_DELETE) && table.deletePermission)
|
||||
{
|
||||
e.preventDefault()
|
||||
handleClickDeleteButton();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", down)
|
||||
return () => document.removeEventListener("keydown", down)
|
||||
}, [allowShortcuts])
|
||||
|
||||
const gotoCreate = () =>
|
||||
{
|
||||
const path = `${pathParts.slice(0, -1).join("/")}/create`;
|
||||
navigate(path);
|
||||
}
|
||||
|
||||
const gotoEdit = () =>
|
||||
{
|
||||
const path = `${pathParts.slice(0, -1).join("/")}/${record.values.get(table.primaryKeyField)}/edit`;
|
||||
navigate(path);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// monitor location changes - if we've clicked a link from viewing one record to viewing another, //
|
||||
// we'll stay in this component, but we'll need to reload all data for the new record. //
|
||||
@ -506,12 +549,6 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
||||
|
||||
let hasEditOrDelete = (table.capabilities.has(Capability.TABLE_UPDATE) && table.editPermission) || (table.capabilities.has(Capability.TABLE_DELETE) && table.deletePermission);
|
||||
|
||||
function gotoCreate()
|
||||
{
|
||||
const path = `${pathParts.slice(0, -1).join("/")}/create`;
|
||||
navigate(path);
|
||||
}
|
||||
|
||||
const renderActionsMenu = (
|
||||
<Menu
|
||||
anchorEl={actionsMenu}
|
||||
@ -682,7 +719,7 @@ function RecordView({table, launchProcess}: Props): JSX.Element
|
||||
<Box pb={3}>
|
||||
{
|
||||
successMessage ?
|
||||
<Alert color="success" sx={{mb: 3}} onClose={() =>
|
||||
<Alert color="success" sx={{mb: 3}} onClose={() =>
|
||||
{
|
||||
setSuccessMessage(null);
|
||||
}}>
|
||||
|
142
src/qqq/styles/globals.scss
Normal file
142
src/qqq/styles/globals.scss
Normal file
@ -0,0 +1,142 @@
|
||||
|
||||
::selection {
|
||||
background: hotpink;
|
||||
color: white;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family: var(--font-sans);
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--app-bg);
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
button {
|
||||
background: none;
|
||||
font-family: var(--font-sans);
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
*,
|
||||
*::after,
|
||||
*::before {
|
||||
box-sizing: border-box;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
:root {
|
||||
--font-sans: 'Inter', --apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Fira Sans,
|
||||
Droid Sans, Helvetica Neue, sans-serif;
|
||||
--app-bg: var(--gray1);
|
||||
--cmdk-shadow: 0 16px 700px rgb(0 0 0 / 40%);
|
||||
|
||||
--lowContrast: #ffffff;
|
||||
--highContrast: #000000;
|
||||
|
||||
--gray1: hsl(0, 0%, 99%);
|
||||
--gray2: hsl(0, 0%, 97.3%);
|
||||
--gray3: hsl(0, 0%, 95.1%);
|
||||
--gray4: hsl(0, 0%, 93%);
|
||||
--gray5: hsl(0, 0%, 90.9%);
|
||||
--gray6: hsl(0, 0%, 88.7%);
|
||||
--gray7: hsl(0, 0%, 85.8%);
|
||||
--gray8: hsl(0, 0%, 78%);
|
||||
--gray9: hsl(0, 0%, 56.1%);
|
||||
--gray10: hsl(0, 0%, 52.3%);
|
||||
--gray11: hsl(0, 0%, 43.5%);
|
||||
--gray12: hsl(0, 0%, 9%);
|
||||
|
||||
--grayA1: hsla(0, 0%, 0%, 0.012);
|
||||
--grayA2: hsla(0, 0%, 0%, 0.027);
|
||||
--grayA3: hsla(0, 0%, 0%, 0.047);
|
||||
--grayA4: hsla(0, 0%, 0%, 0.071);
|
||||
--grayA5: hsla(0, 0%, 0%, 0.09);
|
||||
--grayA6: hsla(0, 0%, 0%, 0.114);
|
||||
--grayA7: hsla(0, 0%, 0%, 0.141);
|
||||
--grayA8: hsla(0, 0%, 0%, 0.22);
|
||||
--grayA9: hsla(0, 0%, 0%, 0.439);
|
||||
--grayA10: hsla(0, 0%, 0%, 0.478);
|
||||
--grayA11: hsla(0, 0%, 0%, 0.565);
|
||||
--grayA12: hsla(0, 0%, 0%, 0.91);
|
||||
|
||||
--blue1: hsl(206, 100%, 99.2%);
|
||||
--blue2: hsl(210, 100%, 98%);
|
||||
--blue3: hsl(209, 100%, 96.5%);
|
||||
--blue4: hsl(210, 98.8%, 94%);
|
||||
--blue5: hsl(209, 95%, 90.1%);
|
||||
--blue6: hsl(209, 81.2%, 84.5%);
|
||||
--blue7: hsl(208, 77.5%, 76.9%);
|
||||
--blue8: hsl(206, 81.9%, 65.3%);
|
||||
--blue9: hsl(206, 100%, 50%);
|
||||
--blue10: hsl(208, 100%, 47.3%);
|
||||
--blue11: hsl(211, 100%, 43.2%);
|
||||
--blue12: hsl(211, 100%, 15%);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--app-bg: var(--gray1);
|
||||
|
||||
--lowContrast: #000000;
|
||||
--highContrast: #ffffff;
|
||||
|
||||
--gray1: hsl(0, 0%, 8.5%);
|
||||
--gray2: hsl(0, 0%, 11%);
|
||||
--gray3: hsl(0, 0%, 13.6%);
|
||||
--gray4: hsl(0, 0%, 15.8%);
|
||||
--gray5: hsl(0, 0%, 17.9%);
|
||||
--gray6: hsl(0, 0%, 20.5%);
|
||||
--gray7: hsl(0, 0%, 24.3%);
|
||||
--gray8: hsl(0, 0%, 31.2%);
|
||||
--gray9: hsl(0, 0%, 43.9%);
|
||||
--gray10: hsl(0, 0%, 49.4%);
|
||||
--gray11: hsl(0, 0%, 62.8%);
|
||||
--gray12: hsl(0, 0%, 93%);
|
||||
|
||||
--grayA1: hsla(0, 0%, 100%, 0);
|
||||
--grayA2: hsla(0, 0%, 100%, 0.026);
|
||||
--grayA3: hsla(0, 0%, 100%, 0.056);
|
||||
--grayA4: hsla(0, 0%, 100%, 0.077);
|
||||
--grayA5: hsla(0, 0%, 100%, 0.103);
|
||||
--grayA6: hsla(0, 0%, 100%, 0.129);
|
||||
--grayA7: hsla(0, 0%, 100%, 0.172);
|
||||
--grayA8: hsla(0, 0%, 100%, 0.249);
|
||||
--grayA9: hsla(0, 0%, 100%, 0.386);
|
||||
--grayA10: hsla(0, 0%, 100%, 0.446);
|
||||
--grayA11: hsla(0, 0%, 100%, 0.592);
|
||||
--grayA12: hsla(0, 0%, 100%, 0.923);
|
||||
|
||||
--blue1: hsl(212, 35%, 9.2%);
|
||||
--blue2: hsl(216, 50%, 11.8%);
|
||||
--blue3: hsl(214, 59.4%, 15.3%);
|
||||
--blue4: hsl(214, 65.8%, 17.9%);
|
||||
--blue5: hsl(213, 71.2%, 20.2%);
|
||||
--blue6: hsl(212, 77.4%, 23.1%);
|
||||
--blue7: hsl(211, 85.1%, 27.4%);
|
||||
--blue8: hsl(211, 89.7%, 34.1%);
|
||||
--blue9: hsl(206, 100%, 50%);
|
||||
--blue10: hsl(209, 100%, 60.6%);
|
||||
--blue11: hsl(210, 100%, 66.1%);
|
||||
--blue12: hsl(206, 98%, 95.8%);
|
||||
}
|
544
src/qqq/styles/raycast.scss
Normal file
544
src/qqq/styles/raycast.scss
Normal file
@ -0,0 +1,544 @@
|
||||
/*!
|
||||
* Copyright © 2022-2023. ColdTrack <contact@coldtrack.com>. All Rights Reserved.
|
||||
*/
|
||||
|
||||
.raycast {
|
||||
[cmdk-root] {
|
||||
max-width: 1000px;
|
||||
width: 650px;
|
||||
background: var(--gray1);
|
||||
border-radius: 12px;
|
||||
padding: 8px 0;
|
||||
font-family: var(--font-sans);
|
||||
box-shadow: var(--cmdk-shadow);
|
||||
border: 1px solid var(--gray6);
|
||||
position: relative;
|
||||
|
||||
.dark & {
|
||||
background: var(--gray2);
|
||||
border: 0;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
var(--gray6) 20%,
|
||||
var(--gray6) 40%,
|
||||
var(--gray10) 50%,
|
||||
var(--gray10) 55%,
|
||||
var(--gray6) 70%,
|
||||
var(--gray6) 100%
|
||||
);
|
||||
z-index: -1;
|
||||
position: absolute;
|
||||
border-radius: 12px;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
width: calc(100% + 2px);
|
||||
height: calc(100% + 2px);
|
||||
animation: shine 3s ease forwards 0.1s;
|
||||
background-size: 200% auto;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
z-index: -1;
|
||||
position: absolute;
|
||||
border-radius: 12px;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
width: calc(100% + 2px);
|
||||
height: calc(100% + 2px);
|
||||
box-shadow: 0 0 0 1px transparent;
|
||||
animation: border 1s linear forwards 0.5s;
|
||||
}
|
||||
}
|
||||
|
||||
kbd {
|
||||
font-family: var(--font-sans);
|
||||
background: var(--gray3);
|
||||
color: var(--gray11);
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
border-radius: 4px;
|
||||
padding: 0 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&:first-of-type {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[cmdk-input] {
|
||||
font-family: var(--font-sans);
|
||||
border: none;
|
||||
width: 100%;
|
||||
font-size: 15px;
|
||||
padding: 8px 16px;
|
||||
outline: none;
|
||||
background: var(--bg);
|
||||
color: var(--gray12);
|
||||
|
||||
&::placeholder {
|
||||
color: var(--gray9);
|
||||
}
|
||||
}
|
||||
|
||||
[cmdk-raycast-top-shine] {
|
||||
.dark & {
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(56, 189, 248, 0),
|
||||
var(--gray5) 20%,
|
||||
var(--gray9) 67.19%,
|
||||
rgba(236, 72, 153, 0)
|
||||
);
|
||||
height: 1px;
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
width: 100%;
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
animation: showTopShine 0.1s ease forwards 0.2s;
|
||||
}
|
||||
}
|
||||
|
||||
[cmdk-raycast-loader] {
|
||||
--loader-color: var(--gray9);
|
||||
border: 0;
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
height: 1px;
|
||||
background: var(--gray6);
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
display: block;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
width: 50%;
|
||||
height: 1px;
|
||||
position: absolute;
|
||||
background: linear-gradient(90deg, transparent 0%, var(--loader-color) 50%, transparent 100%);
|
||||
top: -1px;
|
||||
opacity: 0;
|
||||
animation-duration: 1.5s;
|
||||
animation-delay: 1s;
|
||||
animation-timing-function: ease;
|
||||
animation-name: loading;
|
||||
}
|
||||
}
|
||||
|
||||
[cmdk-item] {
|
||||
content-visibility: auto;
|
||||
|
||||
cursor: pointer;
|
||||
height: 40px;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 0 8px;
|
||||
color: var(--gray12);
|
||||
user-select: none;
|
||||
will-change: background, color;
|
||||
transition: all 150ms ease;
|
||||
transition-property: none;
|
||||
|
||||
&[data-selected='true'] {
|
||||
background: var(--gray4);
|
||||
color: var(--gray12);
|
||||
}
|
||||
|
||||
&[data-disabled='true'] {
|
||||
color: var(--gray8);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&:active {
|
||||
transition-property: background;
|
||||
background: var(--gray4);
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
& + [cmdk-item] {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
[cmdk-raycast-meta] {
|
||||
margin-left: auto;
|
||||
color: var(--gray11);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
[cmdk-list] {
|
||||
padding: 0 8px;
|
||||
height: 393px;
|
||||
overflow: auto;
|
||||
overscroll-behavior: contain;
|
||||
scroll-padding-block-end: 40px;
|
||||
transition: 100ms ease;
|
||||
transition-property: height;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
[cmdk-raycast-open-trigger],
|
||||
[cmdk-raycast-subcommand-trigger] {
|
||||
color: var(--gray11);
|
||||
padding: 0px 4px 0px 8px;
|
||||
border-radius: 6px;
|
||||
font-weight: 500;
|
||||
font-size: 12px;
|
||||
height: 28px;
|
||||
letter-spacing: -0.25px;
|
||||
}
|
||||
|
||||
[cmdk-raycast-clipboard-icon],
|
||||
[cmdk-raycast-hammer-icon] {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #ffffff;
|
||||
|
||||
svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
[cmdk-raycast-clipboard-icon] {
|
||||
background: linear-gradient(to bottom, #f55354, #eb4646);
|
||||
}
|
||||
|
||||
[cmdk-raycast-hammer-icon] {
|
||||
background: linear-gradient(to bottom, #6cb9a3, #2c6459);
|
||||
}
|
||||
|
||||
[cmdk-raycast-open-trigger] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--gray12);
|
||||
}
|
||||
|
||||
[cmdk-raycast-subcommand-trigger] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
right: 8px;
|
||||
bottom: 8px;
|
||||
|
||||
svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 100%;
|
||||
background: var(--gray6);
|
||||
border: 0;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
&[aria-expanded='true'],
|
||||
&:hover {
|
||||
background: var(--gray4);
|
||||
|
||||
kbd {
|
||||
background: var(--gray7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[cmdk-separator] {
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
background: var(--gray5);
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
*:not([hidden]) + [cmdk-group] {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
[cmdk-group-heading] {
|
||||
user-select: none;
|
||||
font-size: 12px;
|
||||
color: var(--gray11);
|
||||
padding: 0 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
[cmdk-raycast-footer] {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
background: var(--gray1);
|
||||
bottom: 0;
|
||||
padding: 8px;
|
||||
border-top: 1px solid var(--gray6);
|
||||
border-radius: 0 0 12px 12px;
|
||||
|
||||
svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
filter: grayscale(1);
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 12px;
|
||||
width: 1px;
|
||||
border: 0;
|
||||
background: var(--gray6);
|
||||
margin: 0 4px 0px 12px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
background: var(--gray2);
|
||||
}
|
||||
}
|
||||
|
||||
[cmdk-dialog] {
|
||||
z-index: var(--layer-portal);
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 20%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
[cmdk] {
|
||||
width: 640px;
|
||||
transform-origin: center center;
|
||||
animation: dialogIn var(--transition-fast) forwards;
|
||||
}
|
||||
|
||||
&[data-state='closed'] [cmdk] {
|
||||
animation: dialogOut var(--transition-fast) forwards;
|
||||
}
|
||||
}
|
||||
|
||||
[cmdk-empty] {
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 64px;
|
||||
white-space: pre-wrap;
|
||||
color: var(--gray11);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
50% {
|
||||
opacity: 1;
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shine {
|
||||
to {
|
||||
background-position: 200% center;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes border {
|
||||
to {
|
||||
box-shadow: 0 0 0 1px var(--gray6);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes showTopShine {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.raycast-submenu {
|
||||
[cmdk-root] {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 320px;
|
||||
border: 1px solid var(--gray6);
|
||||
background: var(--gray2);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
[cmdk-list] {
|
||||
padding: 8px;
|
||||
overflow: auto;
|
||||
overscroll-behavior: contain;
|
||||
transition: 100ms ease;
|
||||
transition-property: height;
|
||||
}
|
||||
|
||||
[cmdk-item] {
|
||||
height: 40px;
|
||||
|
||||
cursor: pointer;
|
||||
height: 40px;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 0 8px;
|
||||
color: var(--gray12);
|
||||
user-select: none;
|
||||
will-change: background, color;
|
||||
transition: all 150ms ease;
|
||||
transition-property: none;
|
||||
|
||||
&[aria-selected='true'] {
|
||||
background: var(--gray5);
|
||||
color: var(--gray12);
|
||||
|
||||
[cmdk-raycast-submenu-shortcuts] kbd {
|
||||
background: var(--gray7);
|
||||
}
|
||||
}
|
||||
|
||||
&[aria-disabled='true'] {
|
||||
color: var(--gray8);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
[cmdk-raycast-submenu-shortcuts] {
|
||||
display: flex;
|
||||
margin-left: auto;
|
||||
gap: 2px;
|
||||
|
||||
kbd {
|
||||
font-family: var(--font-sans);
|
||||
background: var(--gray5);
|
||||
color: var(--gray11);
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
border-radius: 4px;
|
||||
padding: 0 4px;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&:first-of-type {
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[cmdk-group-heading] {
|
||||
text-transform: capitalize;
|
||||
font-size: 12px;
|
||||
color: var(--gray11);
|
||||
font-weight: 500;
|
||||
margin-bottom: 8px;
|
||||
margin-top: 8px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
[cmdk-input] {
|
||||
padding: 12px;
|
||||
font-family: var(--font-sans);
|
||||
border: 0;
|
||||
border-top: 1px solid var(--gray6);
|
||||
font-size: 13px;
|
||||
background: transparent;
|
||||
margin-top: auto;
|
||||
width: 100%;
|
||||
outline: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
animation-duration: 0.2s;
|
||||
animation-timing-function: ease;
|
||||
animation-fill-mode: forwards;
|
||||
transform-origin: var(--radix-popover-content-transform-origin);
|
||||
|
||||
&[data-state='open'] {
|
||||
animation-name: slideIn;
|
||||
}
|
||||
|
||||
&[data-state='closed'] {
|
||||
animation-name: slideOut;
|
||||
}
|
||||
|
||||
[cmdk-empty] {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 64px;
|
||||
white-space: pre-wrap;
|
||||
font-size: 14px;
|
||||
color: var(--gray11);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.96);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform: scale(0.96);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.raycast {
|
||||
[cmdk-input] {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user