diff --git a/packages/assets/svgs/chevron-double.svg b/packages/assets/svgs/chevron-double.svg
new file mode 100644
index 000000000..042d0bfd7
--- /dev/null
+++ b/packages/assets/svgs/chevron-double.svg
@@ -0,0 +1,4 @@
+
diff --git a/packages/interface/src/components/explorer/Explorer.tsx b/packages/interface/src/components/explorer/Explorer.tsx
index 88240c526..648232c89 100644
--- a/packages/interface/src/components/explorer/Explorer.tsx
+++ b/packages/interface/src/components/explorer/Explorer.tsx
@@ -1,8 +1,8 @@
import { ExplorerData, rspc, useCurrentLibrary, useExplorerStore } from '@sd/client';
import { Inspector } from '../explorer/Inspector';
-import { TopBar } from '../layout/TopBar';
import ExplorerContextMenu from './ExplorerContextMenu';
+import { TopBar } from './ExplorerTopBar';
import { VirtualizedList } from './VirtualizedList';
interface Props {
diff --git a/packages/interface/src/components/explorer/ExplorerOptionsPanel.tsx b/packages/interface/src/components/explorer/ExplorerOptionsPanel.tsx
new file mode 100644
index 000000000..8ac7e08da
--- /dev/null
+++ b/packages/interface/src/components/explorer/ExplorerOptionsPanel.tsx
@@ -0,0 +1,47 @@
+import { Select, SelectOption } from '@sd/ui';
+import { useState } from 'react';
+
+import Slider from '../primitive/Slider';
+
+const Heading: React.FC<{ children: React.ReactNode }> = ({ children }) => (
+
{children}
+);
+
+const SubHeading: React.FC<{ children: React.ReactNode }> = ({ children }) => (
+ {children}
+);
+
+export const ExplorerOptionsPanel: React.FC = () => {
+ const [sortBy, setSortBy] = useState('name');
+ const [stackBy, setStackBy] = useState('kind');
+ const [size, setSize] = useState([50]);
+
+ return (
+
+ {/*
Explorer Appearance */}
+
Item size
+
+
+
+ Sort by
+
+
+
+ Stack by
+
+
+
+
+ );
+};
diff --git a/packages/interface/src/components/layout/TopBar.tsx b/packages/interface/src/components/explorer/ExplorerTopBar.tsx
similarity index 98%
rename from packages/interface/src/components/layout/TopBar.tsx
rename to packages/interface/src/components/explorer/ExplorerTopBar.tsx
index 513ec836a..c9edbd401 100644
--- a/packages/interface/src/components/layout/TopBar.tsx
+++ b/packages/interface/src/components/explorer/ExplorerTopBar.tsx
@@ -31,6 +31,7 @@ import { KeyManager } from '../key/KeyManager';
import { Shortcut } from '../primitive/Shortcut';
import { DefaultProps } from '../primitive/types';
import { Tooltip } from '../tooltip/Tooltip';
+import { ExplorerOptionsPanel } from './ExplorerOptionsPanel';
export interface TopBarButtonProps {
icon: React.ComponentType;
@@ -276,12 +277,6 @@ export const TopBar: React.FC = (props) => {
-
(getExplorerStore().showInspector = !store.showInspector)}
- className="my-2"
- icon={SidebarSimple}
- />
= (props) => {
//
}
>
- {/* */}
+
+
+
+ (getExplorerStore().showInspector = !store.showInspector)}
+ className="my-2"
+ icon={SidebarSimple}
+ />
{/*
= ({ data, index }) => {
)}
{/* #{data.id}
*/}
- {/* {data.stats && (
-
+ {data.stats && (
+
{data.stats.objectCount && (
-
+
{data.stats.objectCount} Objects
)}
{data.stats.containerCount && (
-
+
{data.stats.containerCount} Containers
)}
- )} */}
+ )}
@@ -154,9 +154,9 @@ export function KeyManager(props: KeyManagerProps) {
- {/*
+
Files encrypted with this key will be revealed and decrypted on the fly.
-
*/}
+
diff --git a/packages/interface/src/components/primitive/Slider.tsx b/packages/interface/src/components/primitive/Slider.tsx
index d7c4e2983..da054c9a7 100644
--- a/packages/interface/src/components/primitive/Slider.tsx
+++ b/packages/interface/src/components/primitive/Slider.tsx
@@ -1,12 +1,16 @@
import * as SliderPrimitive from '@radix-ui/react-slider';
+import clsx from 'clsx';
const Slider = (props: SliderPrimitive.SliderProps) => (
-
+
diff --git a/packages/interface/src/screens/Overview.tsx b/packages/interface/src/screens/Overview.tsx
index e8b61f55c..3dbf5a65b 100644
--- a/packages/interface/src/screens/Overview.tsx
+++ b/packages/interface/src/screens/Overview.tsx
@@ -70,7 +70,7 @@ const StatItem: React.FC = (props) => {
)}
>
{title}
-
+
{isLoading && (
@@ -81,7 +81,7 @@ const StatItem: React.FC = (props) => {
hidden: isLoading
})}
>
- {count}
+ {count}
{size.unit}
diff --git a/packages/interface/src/screens/settings/client/AppearanceSettings.tsx b/packages/interface/src/screens/settings/client/AppearanceSettings.tsx
index 7319ab9a0..ab74d3b37 100644
--- a/packages/interface/src/screens/settings/client/AppearanceSettings.tsx
+++ b/packages/interface/src/screens/settings/client/AppearanceSettings.tsx
@@ -1,10 +1,31 @@
+import { useState } from 'react';
+
+import { Toggle } from '../../../components/primitive';
+import { InputContainer } from '../../../components/primitive/InputContainer';
import { SettingsContainer } from '../../../components/settings/SettingsContainer';
import { SettingsHeader } from '../../../components/settings/SettingsHeader';
export default function AppearanceSettings() {
+ const [uiAnimations, setUiAnimations] = useState(true);
+ const [blurEffects, setBlurEffects] = useState(true);
+
return (
+
+
+
+
+
+
);
}
diff --git a/packages/interface/src/screens/settings/client/KeybindingSettings.tsx b/packages/interface/src/screens/settings/client/KeybindingSettings.tsx
index db44b9675..b831fbc07 100644
--- a/packages/interface/src/screens/settings/client/KeybindingSettings.tsx
+++ b/packages/interface/src/screens/settings/client/KeybindingSettings.tsx
@@ -1,9 +1,12 @@
+import { useState } from 'react';
+
import { Toggle } from '../../../components/primitive';
import { InputContainer } from '../../../components/primitive/InputContainer';
import { SettingsContainer } from '../../../components/settings/SettingsContainer';
import { SettingsHeader } from '../../../components/settings/SettingsHeader';
export default function AppearanceSettings() {
+ const [syncWithLibrary, setSyncWithLibrary] = useState(true);
return (
@@ -12,7 +15,7 @@ export default function AppearanceSettings() {
title="Sync with Library"
description="If enabled your keybindings will be synced with library, otherwise they will apply only to this client."
>
-
+
);
diff --git a/packages/ui/package.json b/packages/ui/package.json
index b9a6871ea..6053003a8 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -22,9 +22,11 @@
"@radix-ui/react-context-menu": "^1.0.0",
"@radix-ui/react-dialog": "^1.0.0",
"@radix-ui/react-dropdown-menu": "^1.0.0",
+ "@radix-ui/react-select": "^1.0.0",
"@tailwindcss/forms": "^0.5.3",
"class-variance-authority": "^0.2.3",
"clsx": "^1.2.1",
+ "@sd/assets": "workspace:*",
"phosphor-react": "^1.4.1",
"postcss": "^8.4.17",
"react": "^18.2.0",
@@ -32,7 +34,8 @@
"react-loading-icons": "^1.1.0",
"react-spring": "^9.5.5",
"storybook": "^6.5.12",
- "tailwindcss": "^3.1.8"
+ "tailwindcss": "^3.1.8",
+ "tailwindcss-radix": "^2.6.0"
},
"devDependencies": {
"@babel/core": "^7.19.3",
diff --git a/packages/ui/src/OverlayPanel.tsx b/packages/ui/src/OverlayPanel.tsx
index 31395fa75..77a12d189 100644
--- a/packages/ui/src/OverlayPanel.tsx
+++ b/packages/ui/src/OverlayPanel.tsx
@@ -33,7 +33,7 @@ export const OverlayPanel = ({
const transitions = useTransition(open, {
from: {
opacity: 0,
- transform: `scale(${0.9})`,
+ transform: `scale(0.9)`,
transformOrigin: transformOrigin || 'top'
},
enter: { opacity: 1, transform: 'scale(1)' },
diff --git a/packages/ui/src/Select.tsx b/packages/ui/src/Select.tsx
new file mode 100644
index 000000000..d2b3ea82b
--- /dev/null
+++ b/packages/ui/src/Select.tsx
@@ -0,0 +1,71 @@
+import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/solid';
+import * as SelectPrimitive from '@radix-ui/react-select';
+import { ReactComponent as ChevronDouble } from '@sd/assets/svgs/chevron-double.svg';
+import clsx from 'clsx';
+import { CaretDown } from 'phosphor-react';
+
+interface SelectProps {
+ value: string;
+ size?: 'sm' | 'md' | 'lg';
+ className?: string;
+ onChange: (value: string) => void;
+ children: React.ReactNode;
+}
+
+export function Select(props: SelectProps) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {props.children}
+
+
+
+
+ );
+}
+
+export interface SelectOptionProps {
+ value: string;
+ children: string;
+}
+
+export function SelectOption(props: SelectOptionProps) {
+ return (
+
+ {props.children}
+
+
+
+
+ );
+}
diff --git a/packages/ui/src/declarations.d.ts b/packages/ui/src/declarations.d.ts
new file mode 100644
index 000000000..077695674
--- /dev/null
+++ b/packages/ui/src/declarations.d.ts
@@ -0,0 +1,4 @@
+declare module '*.svg' {
+ const ReactComponent: React.ReactComponent;
+ export { ReactComponent };
+}
diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts
index fa9e01722..f88a5c1f4 100644
--- a/packages/ui/src/index.ts
+++ b/packages/ui/src/index.ts
@@ -5,3 +5,4 @@ export * from './Loader';
export * as ContextMenu from './ContextMenu';
export * from './OverlayPanel';
export * from './Input';
+export * from './Select';
diff --git a/packages/ui/style/tailwind.js b/packages/ui/style/tailwind.js
index 0d05ffefb..c75375cf1 100644
--- a/packages/ui/style/tailwind.js
+++ b/packages/ui/style/tailwind.js
@@ -125,7 +125,8 @@ module.exports = function (app, options) {
plugin(({ addVariant }) => {
addVariant('open', '&[data-state="open"]');
addVariant('closed', '&[data-state="closed"]');
- })
+ }),
+ require('tailwindcss-radix')()
]
};
if (app === 'landing') {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 6c1ed17b2..95c463bc8 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -487,6 +487,8 @@ importers:
'@radix-ui/react-context-menu': ^1.0.0
'@radix-ui/react-dialog': ^1.0.0
'@radix-ui/react-dropdown-menu': ^1.0.0
+ '@radix-ui/react-select': ^1.0.0
+ '@sd/assets': workspace:*
'@sd/config': workspace:*
'@storybook/addon-actions': ^6.5.12
'@storybook/addon-essentials': ^6.5.12
@@ -521,6 +523,7 @@ importers:
storybook-tailwind-dark-mode: ^1.0.15
style-loader: ^3.3.1
tailwindcss: ^3.1.8
+ tailwindcss-radix: ^2.6.0
typescript: ^4.8.4
dependencies:
'@headlessui/react': 1.7.3_biqbaboplfbrettd7655fr4n2y
@@ -528,6 +531,8 @@ importers:
'@radix-ui/react-context-menu': 1.0.0_rj7ozvcq3uehdlnj3cbwzbi5ce
'@radix-ui/react-dialog': 1.0.0_rj7ozvcq3uehdlnj3cbwzbi5ce
'@radix-ui/react-dropdown-menu': 1.0.0_rj7ozvcq3uehdlnj3cbwzbi5ce
+ '@radix-ui/react-select': 1.0.0_rj7ozvcq3uehdlnj3cbwzbi5ce
+ '@sd/assets': link:../assets
'@tailwindcss/forms': 0.5.3_tailwindcss@3.1.8
class-variance-authority: 0.2.3_typescript@4.8.4
clsx: 1.2.1
@@ -539,6 +544,7 @@ importers:
react-spring: 9.5.5_biqbaboplfbrettd7655fr4n2y
storybook: 6.5.12_yalvw3r2waubxycyb7k7qsruca
tailwindcss: 3.1.8
+ tailwindcss-radix: 2.6.0
devDependencies:
'@babel/core': 7.19.3
'@sd/config': link:../config
@@ -3285,6 +3291,21 @@ packages:
react: 18.2.0
dev: false
+ /@radix-ui/react-label/1.0.0_biqbaboplfbrettd7655fr4n2y:
+ resolution: {integrity: sha512-k+EbxeRaVbSJ4oaR9eUYuC0cDIGRB4TAPhilbFCIMpP9pXFNcyQPQUvRaVOQBrviuArYM80xh0BQR/0y3kjUdQ==}
+ peerDependencies:
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ dependencies:
+ '@babel/runtime': 7.19.0
+ '@radix-ui/react-compose-refs': 1.0.0_react@18.2.0
+ '@radix-ui/react-context': 1.0.0_react@18.2.0
+ '@radix-ui/react-id': 1.0.0_react@18.2.0
+ '@radix-ui/react-primitive': 1.0.0_biqbaboplfbrettd7655fr4n2y
+ react: 18.2.0
+ react-dom: 18.2.0_react@18.2.0
+ dev: false
+
/@radix-ui/react-menu/1.0.0_rj7ozvcq3uehdlnj3cbwzbi5ce:
resolution: {integrity: sha512-icW4C64T6nHh3Z4Q1fxO1RlSShouFF4UpUmPV8FLaJZfphDljannKErDuALDx4ClRLihAPZ9i+PrLNPoWS2DMA==}
peerDependencies:
@@ -3408,6 +3429,40 @@ packages:
react-dom: 18.2.0_react@18.2.0
dev: false
+ /@radix-ui/react-select/1.0.0_rj7ozvcq3uehdlnj3cbwzbi5ce:
+ resolution: {integrity: sha512-GfbVBxx7JPvytNT+0XYCFCOImEMmpl0Vg7hhifLaLV7p5zRottFMgQ7qrrxw8v6B8buKXz41kWYMrdRrWqsZaQ==}
+ peerDependencies:
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ dependencies:
+ '@babel/runtime': 7.19.0
+ '@radix-ui/number': 1.0.0
+ '@radix-ui/primitive': 1.0.0
+ '@radix-ui/react-collection': 1.0.0_biqbaboplfbrettd7655fr4n2y
+ '@radix-ui/react-compose-refs': 1.0.0_react@18.2.0
+ '@radix-ui/react-context': 1.0.0_react@18.2.0
+ '@radix-ui/react-direction': 1.0.0_react@18.2.0
+ '@radix-ui/react-dismissable-layer': 1.0.0_biqbaboplfbrettd7655fr4n2y
+ '@radix-ui/react-focus-guards': 1.0.0_react@18.2.0
+ '@radix-ui/react-focus-scope': 1.0.0_biqbaboplfbrettd7655fr4n2y
+ '@radix-ui/react-id': 1.0.0_react@18.2.0
+ '@radix-ui/react-label': 1.0.0_biqbaboplfbrettd7655fr4n2y
+ '@radix-ui/react-portal': 1.0.0_biqbaboplfbrettd7655fr4n2y
+ '@radix-ui/react-primitive': 1.0.0_biqbaboplfbrettd7655fr4n2y
+ '@radix-ui/react-slot': 1.0.0_react@18.2.0
+ '@radix-ui/react-use-callback-ref': 1.0.0_react@18.2.0
+ '@radix-ui/react-use-controllable-state': 1.0.0_react@18.2.0
+ '@radix-ui/react-use-layout-effect': 1.0.0_react@18.2.0
+ '@radix-ui/react-use-previous': 1.0.0_react@18.2.0
+ '@radix-ui/react-visually-hidden': 1.0.0_biqbaboplfbrettd7655fr4n2y
+ aria-hidden: 1.2.1_iapumuv4e6jcjznwuxpf4tt22e
+ react: 18.2.0
+ react-dom: 18.2.0_react@18.2.0
+ react-remove-scroll: 2.5.4_iapumuv4e6jcjznwuxpf4tt22e
+ transitivePeerDependencies:
+ - '@types/react'
+ dev: false
+
/@radix-ui/react-slider/1.0.0_biqbaboplfbrettd7655fr4n2y:
resolution: {integrity: sha512-LMZET7vn7HYwYSjsc9Jcen8Vn4cJXZZxQT7T+lGlqp+F+FofX+H86TBF2yDq+L51d99f1KLEsflTGBz9WRLSig==}
peerDependencies:
@@ -6374,7 +6429,7 @@ packages:
'@babel/plugin-transform-react-jsx-source': 7.18.6_@babel+core@7.19.3
magic-string: 0.26.6
react-refresh: 0.14.0
- vite: 3.1.4
+ vite: 3.1.4_sass@1.55.0
transitivePeerDependencies:
- supports-color
@@ -7109,7 +7164,6 @@ packages:
normalize-range: 0.1.2
picocolors: 1.0.0
postcss-value-parser: 4.2.0
- dev: false
/autoprefixer/10.4.12_postcss@8.4.17:
resolution: {integrity: sha512-WrCGV9/b97Pa+jtwf5UGaRjgQIg7OK3D06GnoYoZNcG1Xb8Gt3EfuKjlhh9i/VtT16g6PYjZ69jdJ2g8FxSC4Q==}
@@ -7699,7 +7753,7 @@ packages:
dev: true
/buffer-equal/0.0.1:
- resolution: {integrity: sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==}
+ resolution: {integrity: sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=}
engines: {node: '>=0.4.0'}
dev: true
@@ -10990,7 +11044,7 @@ packages:
dev: true
/github-from-package/0.0.0:
- resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
+ resolution: {integrity: sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=}
dev: true
/github-slugger/1.4.0:
@@ -16955,6 +17009,10 @@ packages:
- utf-8-validate
dev: true
+ /tailwindcss-radix/2.6.0:
+ resolution: {integrity: sha512-32gv65ommaEMPKRS9yPmbvc6QcV+LsAqtSe1RFindBctVpS6+SbmkfcdecW/zgRvHW7KeAgl3iyzq2ZmRqsdZQ==}
+ dev: false
+
/tailwindcss/3.1.8:
resolution: {integrity: sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==}
engines: {node: '>=12.13.0'}
@@ -18265,7 +18323,7 @@ packages:
valtio: ^1.2.5
dependencies:
lodash: 4.17.21
- valtio: 1.7.0_react@18.2.0+vite@3.1.4
+ valtio: 1.7.0
dev: false
/valtio/1.7.0:
@@ -18429,7 +18487,7 @@ packages:
dependencies:
'@rollup/pluginutils': 4.2.1
'@svgr/core': 6.4.0
- vite: 3.1.4
+ vite: 3.1.4_sass@1.55.0
transitivePeerDependencies:
- '@babel/core'
- supports-color