add app readme
lots of styling improvements fix dark/bright mode
This commit is contained in:
parent
e8b6fcdbba
commit
5791b61a48
@ -1,7 +1,11 @@
|
|||||||
# Tauri + React + Typescript
|
# tempblade Creator
|
||||||
|
|
||||||
This template should help get you started developing with Tauri, React and Typescript in Vite.
|
This is the directory containing the application. It uses tauri with react/vite.
|
||||||
|
|
||||||
## Recommended IDE Setup
|
## Commands
|
||||||
|
|
||||||
- [VS Code](https://code.visualstudio.com/) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
|
Start the dev server:
|
||||||
|
```yarn tauri dev```
|
||||||
|
|
||||||
|
Create a production build:
|
||||||
|
```yarn tauri build```
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
"@radix-ui/react-menubar": "^1.0.2",
|
"@radix-ui/react-menubar": "^1.0.2",
|
||||||
"@radix-ui/react-popover": "^1.0.6",
|
"@radix-ui/react-popover": "^1.0.6",
|
||||||
|
"@radix-ui/react-scroll-area": "^1.0.4",
|
||||||
"@radix-ui/react-select": "^1.2.2",
|
"@radix-ui/react-select": "^1.2.2",
|
||||||
"@radix-ui/react-slider": "^1.1.1",
|
"@radix-ui/react-slider": "^1.1.1",
|
||||||
"@radix-ui/react-toggle-group": "^1.0.4",
|
"@radix-ui/react-toggle-group": "^1.0.4",
|
||||||
|
@ -17,7 +17,7 @@ tauri-build = { version = "1.3", features = [] }
|
|||||||
|
|
||||||
uuid = { version = "1.3.3", features = ["v4", "fast-rng", "macro-diagnostics"] }
|
uuid = { version = "1.3.3", features = ["v4", "fast-rng", "macro-diagnostics"] }
|
||||||
tauri = { version = "1.3", features = ["dialog-open", "dialog-save", "shell-open"] }
|
tauri = { version = "1.3", features = ["dialog-open", "dialog-save", "shell-open"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive", "rc"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
tint = "1.0.0"
|
tint = "1.0.0"
|
||||||
simple-easing = "1.0.1"
|
simple-easing = "1.0.1"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::cmp::Ordering;
|
use std::{cmp::Ordering, sync::Arc};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@ -12,10 +12,26 @@ use super::{
|
|||||||
pub struct Keyframe {
|
pub struct Keyframe {
|
||||||
pub value: f32,
|
pub value: f32,
|
||||||
pub offset: f32,
|
pub offset: f32,
|
||||||
pub id: String,
|
pub id: Arc<str>,
|
||||||
pub interpolation: Option<InterpolationType>,
|
pub interpolation: Option<InterpolationType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Keyframe {
|
||||||
|
pub fn new(
|
||||||
|
value: f32,
|
||||||
|
offset: f32,
|
||||||
|
id: Arc<str>,
|
||||||
|
interpolation: Option<InterpolationType>,
|
||||||
|
) -> Self {
|
||||||
|
Keyframe {
|
||||||
|
value,
|
||||||
|
offset,
|
||||||
|
id,
|
||||||
|
interpolation,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct RenderedKeyframe {
|
pub struct RenderedKeyframe {
|
||||||
pub absolute_frame: i32,
|
pub absolute_frame: i32,
|
||||||
|
@ -25,19 +25,19 @@ fn interpolates_the_input() {
|
|||||||
let keyframes1 = Keyframes {
|
let keyframes1 = Keyframes {
|
||||||
values: vec![
|
values: vec![
|
||||||
Keyframe {
|
Keyframe {
|
||||||
id: "1".to_string(),
|
id: "1".into(),
|
||||||
value: 0.0,
|
value: 0.0,
|
||||||
offset: 0.0,
|
offset: 0.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
},
|
},
|
||||||
Keyframe {
|
Keyframe {
|
||||||
id: "2".to_string(),
|
id: "2".into(),
|
||||||
value: 100.0,
|
value: 100.0,
|
||||||
offset: 1.0,
|
offset: 1.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
},
|
},
|
||||||
Keyframe {
|
Keyframe {
|
||||||
id: "3".to_string(),
|
id: "3".into(),
|
||||||
value: 300.0,
|
value: 300.0,
|
||||||
offset: 3.0,
|
offset: 3.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
@ -48,13 +48,13 @@ fn interpolates_the_input() {
|
|||||||
let keyframes2 = Keyframes {
|
let keyframes2 = Keyframes {
|
||||||
values: vec![
|
values: vec![
|
||||||
Keyframe {
|
Keyframe {
|
||||||
id: "4".to_string(),
|
id: "4".into(),
|
||||||
value: -100.0,
|
value: -100.0,
|
||||||
offset: 0.0,
|
offset: 0.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
},
|
},
|
||||||
Keyframe {
|
Keyframe {
|
||||||
id: "5".to_string(),
|
id: "5".into(),
|
||||||
value: 0.0,
|
value: 0.0,
|
||||||
offset: 1.0,
|
offset: 1.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
@ -150,19 +150,19 @@ fn gets_value_at_frame() {
|
|||||||
let keyframes = Keyframes {
|
let keyframes = Keyframes {
|
||||||
values: vec![
|
values: vec![
|
||||||
Keyframe {
|
Keyframe {
|
||||||
id: "1".to_string(),
|
id: "1".into(),
|
||||||
value: 0.0,
|
value: 0.0,
|
||||||
offset: 0.0,
|
offset: 0.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
},
|
},
|
||||||
Keyframe {
|
Keyframe {
|
||||||
id: "2".to_string(),
|
id: "2".into(),
|
||||||
value: 100.0,
|
value: 100.0,
|
||||||
offset: 1.0,
|
offset: 1.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
},
|
},
|
||||||
Keyframe {
|
Keyframe {
|
||||||
id: "3".to_string(),
|
id: "3".into(),
|
||||||
value: 300.0,
|
value: 300.0,
|
||||||
offset: 3.0,
|
offset: 3.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
|
@ -29,7 +29,7 @@ impl AnimatedFloat {
|
|||||||
AnimatedFloat {
|
AnimatedFloat {
|
||||||
keyframes: Keyframes {
|
keyframes: Keyframes {
|
||||||
values: vec![Keyframe {
|
values: vec![Keyframe {
|
||||||
id: Uuid::new_v4().to_string(),
|
id: Uuid::new_v4().to_string().into(),
|
||||||
value: val,
|
value: val,
|
||||||
offset: 0.0,
|
offset: 0.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
|
@ -70,7 +70,7 @@ fn build_bg(offset: f32, paint: Paint, size: (i32, i32)) -> AnimatedRectEntity {
|
|||||||
keyframes: Keyframes {
|
keyframes: Keyframes {
|
||||||
values: vec![
|
values: vec![
|
||||||
Keyframe {
|
Keyframe {
|
||||||
id: "1".to_string(),
|
id: "1".into(),
|
||||||
value: (size.0 * -1) as f32,
|
value: (size.0 * -1) as f32,
|
||||||
offset: 0.0,
|
offset: 0.0,
|
||||||
interpolation: Some(InterpolationType::EasingFunction(
|
interpolation: Some(InterpolationType::EasingFunction(
|
||||||
@ -78,7 +78,7 @@ fn build_bg(offset: f32, paint: Paint, size: (i32, i32)) -> AnimatedRectEntity {
|
|||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
Keyframe {
|
Keyframe {
|
||||||
id: "2".to_string(),
|
id: "2".into(),
|
||||||
value: 0.0,
|
value: 0.0,
|
||||||
offset: 5.0,
|
offset: 5.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
@ -89,7 +89,7 @@ fn build_bg(offset: f32, paint: Paint, size: (i32, i32)) -> AnimatedRectEntity {
|
|||||||
AnimatedFloat {
|
AnimatedFloat {
|
||||||
keyframes: Keyframes {
|
keyframes: Keyframes {
|
||||||
values: vec![Keyframe {
|
values: vec![Keyframe {
|
||||||
id: "3".to_string(),
|
id: "3".into(),
|
||||||
value: 0.0,
|
value: 0.0,
|
||||||
offset: 0.0,
|
offset: 0.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
@ -103,7 +103,7 @@ fn build_bg(offset: f32, paint: Paint, size: (i32, i32)) -> AnimatedRectEntity {
|
|||||||
AnimatedFloat {
|
AnimatedFloat {
|
||||||
keyframes: Keyframes {
|
keyframes: Keyframes {
|
||||||
values: vec![Keyframe {
|
values: vec![Keyframe {
|
||||||
id: "4".to_string(),
|
id: "4".into(),
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
value: size.0 as f32,
|
value: size.0 as f32,
|
||||||
offset: 0.0,
|
offset: 0.0,
|
||||||
@ -113,7 +113,7 @@ fn build_bg(offset: f32, paint: Paint, size: (i32, i32)) -> AnimatedRectEntity {
|
|||||||
AnimatedFloat {
|
AnimatedFloat {
|
||||||
keyframes: Keyframes {
|
keyframes: Keyframes {
|
||||||
values: vec![Keyframe {
|
values: vec![Keyframe {
|
||||||
id: "5".to_string(),
|
id: "5".into(),
|
||||||
value: size.1 as f32,
|
value: size.1 as f32,
|
||||||
offset: 0.0,
|
offset: 0.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
@ -159,7 +159,7 @@ pub fn test_timeline_entities_at_frame(
|
|||||||
color: Color::new(0, 0, 0, 1.0),
|
color: Color::new(0, 0, 0, 1.0),
|
||||||
width: 10.0,
|
width: 10.0,
|
||||||
}),
|
}),
|
||||||
font_name: "Arial".to_string(),
|
font_name: "Arial".into(),
|
||||||
align: TextAlign::Center,
|
align: TextAlign::Center,
|
||||||
size: 20.0,
|
size: 20.0,
|
||||||
};
|
};
|
||||||
@ -168,7 +168,7 @@ pub fn test_timeline_entities_at_frame(
|
|||||||
style: PaintStyle::Fill(FillStyle {
|
style: PaintStyle::Fill(FillStyle {
|
||||||
color: Color::new(0, 0, 0, 1.0),
|
color: Color::new(0, 0, 0, 1.0),
|
||||||
}),
|
}),
|
||||||
font_name: "Arial".to_string(),
|
font_name: "Arial".into(),
|
||||||
align: TextAlign::Center,
|
align: TextAlign::Center,
|
||||||
size: 10.0,
|
size: 10.0,
|
||||||
};
|
};
|
||||||
@ -198,7 +198,7 @@ pub fn test_timeline_entities_at_frame(
|
|||||||
keyframes: Keyframes {
|
keyframes: Keyframes {
|
||||||
values: vec![
|
values: vec![
|
||||||
Keyframe {
|
Keyframe {
|
||||||
id: "1".to_string(),
|
id: "1".into(),
|
||||||
value: 0.0,
|
value: 0.0,
|
||||||
offset: 0.0,
|
offset: 0.0,
|
||||||
interpolation: Some(InterpolationType::Spring(
|
interpolation: Some(InterpolationType::Spring(
|
||||||
@ -210,7 +210,7 @@ pub fn test_timeline_entities_at_frame(
|
|||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
Keyframe {
|
Keyframe {
|
||||||
id: "2".to_string(),
|
id: "2".into(),
|
||||||
value: (size.0 / 2) as f32,
|
value: (size.0 / 2) as f32,
|
||||||
offset: 2.0,
|
offset: 2.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
@ -221,7 +221,7 @@ pub fn test_timeline_entities_at_frame(
|
|||||||
AnimatedFloat {
|
AnimatedFloat {
|
||||||
keyframes: Keyframes {
|
keyframes: Keyframes {
|
||||||
values: vec![Keyframe {
|
values: vec![Keyframe {
|
||||||
id: "3".to_string(),
|
id: "3".into(),
|
||||||
value: (size.1 / 2) as f32,
|
value: (size.1 / 2) as f32,
|
||||||
offset: 0.0,
|
offset: 0.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
@ -248,7 +248,7 @@ pub fn test_timeline_entities_at_frame(
|
|||||||
keyframes: Keyframes {
|
keyframes: Keyframes {
|
||||||
values: vec![
|
values: vec![
|
||||||
Keyframe {
|
Keyframe {
|
||||||
id: "5".to_string(),
|
id: "5".into(),
|
||||||
value: 0.0,
|
value: 0.0,
|
||||||
offset: 0.0,
|
offset: 0.0,
|
||||||
interpolation: Some(InterpolationType::Spring(
|
interpolation: Some(InterpolationType::Spring(
|
||||||
@ -260,7 +260,7 @@ pub fn test_timeline_entities_at_frame(
|
|||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
Keyframe {
|
Keyframe {
|
||||||
id: "6".to_string(),
|
id: "6".into(),
|
||||||
|
|
||||||
value: (size.0 / 2) as f32,
|
value: (size.0 / 2) as f32,
|
||||||
offset: 2.0,
|
offset: 2.0,
|
||||||
@ -272,7 +272,7 @@ pub fn test_timeline_entities_at_frame(
|
|||||||
AnimatedFloat {
|
AnimatedFloat {
|
||||||
keyframes: Keyframes {
|
keyframes: Keyframes {
|
||||||
values: vec![Keyframe {
|
values: vec![Keyframe {
|
||||||
id: "7".to_string(),
|
id: "7".into(),
|
||||||
value: ((size.1 / 2) as f32) + 80.0,
|
value: ((size.1 / 2) as f32) + 80.0,
|
||||||
offset: 0.0,
|
offset: 0.0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
|
@ -2,10 +2,11 @@ import "./App.css";
|
|||||||
import Timeline from "./components/Timeline";
|
import Timeline from "./components/Timeline";
|
||||||
import Canvas from "./components/Canvas";
|
import Canvas from "./components/Canvas";
|
||||||
import Properties, { PropertiesContainer } from "components/Properties";
|
import Properties, { PropertiesContainer } from "components/Properties";
|
||||||
import MenuBar from "components/MenuBar";
|
|
||||||
import ToolBar from "components/ToolBar";
|
import ToolBar from "components/ToolBar";
|
||||||
import useKeyControls from "hooks/useKeyControls";
|
import useKeyControls from "hooks/useKeyControls";
|
||||||
import { useFontsStore } from "stores/fonts.store";
|
import { useFontsStore } from "stores/fonts.store";
|
||||||
|
import * as ScrollArea from "@radix-ui/react-scroll-area";
|
||||||
|
import ScrollBar from "components/ScrollArea";
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const fontsStoreDidInit = useFontsStore((store) => store.didInit);
|
const fontsStoreDidInit = useFontsStore((store) => store.didInit);
|
||||||
@ -13,13 +14,15 @@ export default function App() {
|
|||||||
useKeyControls();
|
useKeyControls();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-gray-950 h-full w-full flex flex-col overflow-hidden">
|
<div className="bg-neutral h-full w-full flex flex-col overflow-hidden">
|
||||||
<MenuBar />
|
{/* <MenuBar /> */}
|
||||||
<div className="flex flex-row flex-[1] overflow-hidden">
|
<div className="flex flex-row flex-[1] overflow-hidden">
|
||||||
<ToolBar />
|
<ToolBar />
|
||||||
{fontsStoreDidInit && (
|
{fontsStoreDidInit && (
|
||||||
<div className="flex flex-col pl-4 gap-4 pr-4 overflow-x-hidden overflow-y-auto">
|
<ScrollArea.Root className="w-full">
|
||||||
<div className="flex w-full gap-4 flex-col lg:flex-row justify-center items-center">
|
<ScrollArea.Viewport className="w-full h-full">
|
||||||
|
<div className="flex w-full flex-col pl-4 gap-4 pr-4 overflow-x-hidden overflow-y-auto">
|
||||||
|
<div className="flex w-full gap-4 flex-col lg:flex-row justify-center items-center mt-4">
|
||||||
<Canvas />
|
<Canvas />
|
||||||
<PropertiesContainer>
|
<PropertiesContainer>
|
||||||
<Properties />
|
<Properties />
|
||||||
@ -27,12 +30,11 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
<Timeline />
|
<Timeline />
|
||||||
</div>
|
</div>
|
||||||
|
</ScrollArea.Viewport>
|
||||||
|
<ScrollBar />
|
||||||
|
</ScrollArea.Root>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
/* */
|
|
||||||
}
|
|
||||||
|
@ -17,7 +17,8 @@ const SelectTrigger = React.forwardRef<
|
|||||||
<SelectPrimitive.Trigger
|
<SelectPrimitive.Trigger
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm",
|
||||||
|
"placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
@ -38,7 +39,7 @@ const SelectContent = React.forwardRef<
|
|||||||
<SelectPrimitive.Content
|
<SelectPrimitive.Content
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-slate-900 text-popover-foreground shadow-md animate-in fade-in-80",
|
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-neutral-accent text-popover-foreground shadow-md animate-in fade-in-80",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
@ -70,7 +71,8 @@ const SelectItem = React.forwardRef<
|
|||||||
<SelectPrimitive.Item
|
<SelectPrimitive.Item
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn(
|
className={cn(
|
||||||
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-indigo-800 focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none",
|
||||||
|
"focus:bg-primary focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
15
app/src/components/Panel.tsx
Normal file
15
app/src/components/Panel.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { FC, ReactNode } from "react";
|
||||||
|
|
||||||
|
const Panel: FC<{ title: string; children: ReactNode }> = ({
|
||||||
|
title,
|
||||||
|
children,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h3>{title}</h3>
|
||||||
|
<div>{children}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Panel;
|
@ -36,12 +36,8 @@ export const PaintProperties: FC<PaintPropertiesProps> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<fieldset>
|
|
||||||
<label htmlFor="staggered-text-letter-font">Font</label>
|
|
||||||
</fieldset>
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<label htmlFor="paint-style-type">PaintStyle</label>
|
<label htmlFor="paint-style-type">PaintStyle</label>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
defaultValue={entity.style.type}
|
defaultValue={entity.style.type}
|
||||||
onValueChange={(value) => {
|
onValueChange={(value) => {
|
||||||
|
17
app/src/components/ScrollArea.tsx
Normal file
17
app/src/components/ScrollArea.tsx
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import * as ScrollArea from "@radix-ui/react-scroll-area";
|
||||||
|
import { FC } from "react";
|
||||||
|
|
||||||
|
const ScrollBar: FC<{ orientation?: "horizontal" | "vertical" }> = ({
|
||||||
|
orientation = "vertical",
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<ScrollArea.Scrollbar
|
||||||
|
className="flex select-none touch-none p-0.5 bg-neutral-accent transition-colors duration-[160ms] ease-out data-[orientation=vertical]:w-2.5 data-[orientation=horizontal]:flex-col data-[orientation=horizontal]:h-2.5"
|
||||||
|
orientation={orientation}
|
||||||
|
>
|
||||||
|
<ScrollArea.Thumb className="flex-1 bg-main rounded-[10px] relative before:content-[''] before:absolute before:top-1/2 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2 before:w-full before:h-full before:min-w-[44px] before:min-h-[44px]" />
|
||||||
|
</ScrollArea.Scrollbar>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ScrollBar;
|
@ -79,6 +79,14 @@ const KeyframeIndicator: FC<{
|
|||||||
}}
|
}}
|
||||||
whileTap={{
|
whileTap={{
|
||||||
scale: 1.6,
|
scale: 1.6,
|
||||||
|
transition: {
|
||||||
|
scale: {
|
||||||
|
type: "spring",
|
||||||
|
stiffness: 200,
|
||||||
|
damping: 10,
|
||||||
|
mass: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
animate={{
|
animate={{
|
||||||
x: (animationData.offset + keyframe.offset) * TIMELINE_SCALE + 2,
|
x: (animationData.offset + keyframe.offset) * TIMELINE_SCALE + 2,
|
||||||
@ -97,8 +105,8 @@ const KeyframeIndicator: FC<{
|
|||||||
>
|
>
|
||||||
<motion.span
|
<motion.span
|
||||||
data-selected={selected}
|
data-selected={selected}
|
||||||
className="bg-gray-200
|
className="bg-secondary
|
||||||
data-[selected=true]:bg-indigo-600
|
data-[selected=true]:bg-secondary
|
||||||
h-full transition-colors"
|
h-full transition-colors"
|
||||||
style={{
|
style={{
|
||||||
width: 10,
|
width: 10,
|
||||||
@ -108,7 +116,7 @@ const KeyframeIndicator: FC<{
|
|||||||
/>
|
/>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent className="w-80 backdrop-blur-md bg-slate-700/50">
|
<PopoverContent className="w-80 backdrop-blur-md bg-neutral/50">
|
||||||
<KeyframePopover
|
<KeyframePopover
|
||||||
onClose={() => deselectKeyframe()}
|
onClose={() => deselectKeyframe()}
|
||||||
onUpdate={handleValueUpdate}
|
onUpdate={handleValueUpdate}
|
||||||
|
@ -21,11 +21,11 @@ const TimePicker: FC<TimePickerProps> = () => {
|
|||||||
step={1}
|
step={1}
|
||||||
aria-label="Current Frame"
|
aria-label="Current Frame"
|
||||||
>
|
>
|
||||||
<Slider.Track className="bg-blackA10 relative grow rounded-full h-[3px]">
|
<Slider.Track className="bg-neutral-accent relative grow rounded-full h-[3px]">
|
||||||
<Slider.Range className="absolute bg-white rounded-full h-full" />
|
<Slider.Range className="absolute bg-main rounded-full h-full" />
|
||||||
</Slider.Track>
|
</Slider.Track>
|
||||||
<Slider.Thumb
|
<Slider.Thumb
|
||||||
className="block w-5 h-5 bg-white shadow-[0_2px_10px] shadow-blackA7 rounded-[10px] hover:bg-violet3 focus:outline-none focus:shadow-[0_0_0_5px] focus:shadow-blackA8"
|
className="transition-colors block w-4 h-4 bg-main shadow-[0_2px_10px] shadow-main/20 rounded-[10px] hover:bg-secondary focus:outline-none focus:shadow-[0_0_0_2px] focus:shadow-main"
|
||||||
aria-label="Volume"
|
aria-label="Volume"
|
||||||
/>
|
/>
|
||||||
</Slider.Root>
|
</Slider.Root>
|
||||||
|
@ -45,7 +45,7 @@ const Track: FC<TrackProps> = ({ animationData, index, name, entity }) => {
|
|||||||
dragListener={false}
|
dragListener={false}
|
||||||
dragControls={controls}
|
dragControls={controls}
|
||||||
onMouseDown={(e) => e.preventDefault()}
|
onMouseDown={(e) => e.preventDefault()}
|
||||||
className="min-h-8 relative flex flex-1 flex-col gap-1 select-none"
|
className="h-6 relative flex flex-1 flex-col gap-1 select-none"
|
||||||
>
|
>
|
||||||
<motion.div
|
<motion.div
|
||||||
layout
|
layout
|
||||||
@ -56,7 +56,7 @@ const Track: FC<TrackProps> = ({ animationData, index, name, entity }) => {
|
|||||||
onMouseDown={(e) => e.preventDefault()}
|
onMouseDown={(e) => e.preventDefault()}
|
||||||
onPointerDown={(e) => controls.start(e)}
|
onPointerDown={(e) => controls.start(e)}
|
||||||
className={`h-full transition-all rounded-sm min-w-[200px] p-1 px-2 flex flex-col ${
|
className={`h-full transition-all rounded-sm min-w-[200px] p-1 px-2 flex flex-col ${
|
||||||
selectedEntity === index ? "bg-gray-800" : "bg-gray-900"
|
selectedEntity === index ? "bg-highlight" : "bg-neutral-accent"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="flex flex-row">
|
<div className="flex flex-row">
|
||||||
@ -77,17 +77,18 @@ const Track: FC<TrackProps> = ({ animationData, index, name, entity }) => {
|
|||||||
? deselectEntity()
|
? deselectEntity()
|
||||||
: selectEntity(index)
|
: selectEntity(index)
|
||||||
}
|
}
|
||||||
className="text-white-800 select-none cursor-pointer"
|
className="text-white-800 h-2 text-base leading-loose font-semibold select-none cursor-pointer"
|
||||||
>
|
>
|
||||||
{name}
|
{name}
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="flex h-full w-full flex-row relative rounded-sm bg-neutral-accent/50 select-none shrink-0">
|
||||||
<div
|
<div
|
||||||
|
className="absolute top-0 h-full bg-neutral-accent"
|
||||||
style={{ width: TIMELINE_SCALE * 10 }}
|
style={{ width: TIMELINE_SCALE * 10 }}
|
||||||
className="flex h-full flex-row relative bg-gray-900 select-none shrink-0"
|
/>
|
||||||
>
|
|
||||||
{!isExpanded &&
|
{!isExpanded &&
|
||||||
flattenedKeyframes.map((keyframe, index) => (
|
flattenedKeyframes.map((keyframe, index) => (
|
||||||
<KeyframeIndicator
|
<KeyframeIndicator
|
||||||
@ -132,10 +133,10 @@ const Track: FC<TrackProps> = ({ animationData, index, name, entity }) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
className="z-10 w-4 bg-slate-500 h-8 top-1 absolute rounded-md select-none cursor-w-resize"
|
className="z-10 w-4 bg-primary/80 h-full top-0 absolute rounded-md select-none cursor-w-resize"
|
||||||
/>
|
/>
|
||||||
<motion.div
|
<motion.div
|
||||||
className="z-10 w-4 bg-slate-500 h-8 top-1 absolute rounded-md select-none cursor-e-resize"
|
className="z-10 w-4 bg-primary/80 h-full top-0 absolute rounded-md select-none cursor-e-resize"
|
||||||
onMouseDown={(e) => e.preventDefault()}
|
onMouseDown={(e) => e.preventDefault()}
|
||||||
drag="x"
|
drag="x"
|
||||||
animate={{
|
animate={{
|
||||||
@ -194,7 +195,7 @@ const Track: FC<TrackProps> = ({ animationData, index, name, entity }) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
className="z-5 h-8 top-1 absolute rounded-md transition-colors bg-gray-700 hover:bg-gray-600 select-none cursor-grab"
|
className="z-5 h-full top-0 absolute rounded-md transition-colors bg-primary/30 hover:bg-primary/50 select-none cursor-grab"
|
||||||
></motion.div>
|
></motion.div>
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
@ -78,10 +78,10 @@ const TrackAnimatedProperty: FC<{
|
|||||||
<motion.div
|
<motion.div
|
||||||
transition={ease.quint(0.8).out}
|
transition={ease.quint(0.8).out}
|
||||||
variants={{ enter: { y: 0, opacity: 1 }, from: { y: -10, opacity: 0 } }}
|
variants={{ enter: { y: 0, opacity: 1 }, from: { y: -10, opacity: 0 } }}
|
||||||
className="flex flex-row bg-slate-900 ml-2 align-center"
|
className="flex flex-row bg-neutral-accent ml-2 align-center"
|
||||||
>
|
>
|
||||||
<div className="min-w-[195px] flex flex-row justify-between px-2">
|
<div className="min-w-[195px] flex flex-row justify-between px-2">
|
||||||
<h4>{animatedProperty.label}</h4>
|
<h4 className="text-main/70">{animatedProperty.label}</h4>
|
||||||
<ToggleGroup>
|
<ToggleGroup>
|
||||||
<ToggleGroupItem
|
<ToggleGroupItem
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
|
@ -6,6 +6,8 @@ import Timestamp from "./Timestamp";
|
|||||||
import { PauseIcon, PlayIcon } from "@radix-ui/react-icons";
|
import { PauseIcon, PlayIcon } from "@radix-ui/react-icons";
|
||||||
import { useRenderStateStore } from "stores/render-state.store";
|
import { useRenderStateStore } from "stores/render-state.store";
|
||||||
import Track from "./Track";
|
import Track from "./Track";
|
||||||
|
import * as ScrollArea from "@radix-ui/react-scroll-area";
|
||||||
|
import ScrollBar from "components/ScrollArea";
|
||||||
|
|
||||||
export type AnimationEntity = {
|
export type AnimationEntity = {
|
||||||
offset: number;
|
offset: number;
|
||||||
@ -37,8 +39,10 @@ const Timeline: FC<TimelineProps> = () => {
|
|||||||
</div>
|
</div>
|
||||||
<Timestamp />
|
<Timestamp />
|
||||||
</div>
|
</div>
|
||||||
<div className="gap-1 w-full flex flex-col overflow-x-auto overflow-y-visible">
|
<ScrollArea.Root>
|
||||||
<div className="z-20 flex flex-row gap-2">
|
<ScrollArea.Viewport className="w-full h-full">
|
||||||
|
<div className="gap-1 w-full flex flex-col">
|
||||||
|
<div className="z-20 flex flex-row gap-1">
|
||||||
<div className="flex-shrink-0 min-w-[200px]" />
|
<div className="flex-shrink-0 min-w-[200px]" />
|
||||||
<TimePicker />
|
<TimePicker />
|
||||||
</div>
|
</div>
|
||||||
@ -58,6 +62,11 @@ const Timeline: FC<TimelineProps> = () => {
|
|||||||
))}
|
))}
|
||||||
</Reorder.Group>
|
</Reorder.Group>
|
||||||
</div>
|
</div>
|
||||||
|
</ScrollArea.Viewport>
|
||||||
|
<div className="h-4 sticky bottom-0">
|
||||||
|
<ScrollBar orientation="horizontal" />
|
||||||
|
</div>
|
||||||
|
</ScrollArea.Root>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -12,9 +12,9 @@ const ToggleGroupItem: FC<{
|
|||||||
data-selected={selected}
|
data-selected={selected}
|
||||||
asChild
|
asChild
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
className="hover:bg-indigo-600 text-white data-[selected=true]:bg-indigo-700
|
className="hover:bg-primary/30 text-main data-[selected=true]:bg-primary/60
|
||||||
data-[selected=true]:text-indigo-200 flex h-6 w-6
|
data-[selected=true]:text-indigo-200 flex h-6 w-6
|
||||||
items-center justify-center bg-slate-800 text-sm leading-4
|
items-center justify-center bg-neutral text-sm leading-4
|
||||||
first:rounded-l last:rounded-r focus:z-10 focus:shadow-[0_0_0_2px] focus:shadow-black
|
first:rounded-l last:rounded-r focus:z-10 focus:shadow-[0_0_0_2px] focus:shadow-black
|
||||||
focus:outline-none transition-colors"
|
focus:outline-none transition-colors"
|
||||||
value="left"
|
value="left"
|
||||||
@ -29,7 +29,7 @@ const ToggleGroupItem: FC<{
|
|||||||
|
|
||||||
const ToggleGroup: FC<{ children: ReactNode }> = ({ children }) => (
|
const ToggleGroup: FC<{ children: ReactNode }> = ({ children }) => (
|
||||||
<ToggleGroupComponents.Root
|
<ToggleGroupComponents.Root
|
||||||
className="inline-flex my-auto bg-slate-800 h-fit rounded shadow-[0_2px_10px] shadow-black space-x-px"
|
className="inline-flex my-auto bg-neutral-accent h-fit rounded shadow-[0_2px_10px] shadow-black space-x-px"
|
||||||
type="single"
|
type="single"
|
||||||
defaultValue="center"
|
defaultValue="center"
|
||||||
aria-label="Text alignment"
|
aria-label="Text alignment"
|
||||||
|
@ -25,9 +25,9 @@ const ToolBarButton: FC<{ children: ReactNode; onClick?: () => void }> = ({
|
|||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
onMouseOver={() => !didHover && setDidHover(true)}
|
onMouseOver={() => !didHover && setDidHover(true)}
|
||||||
asChild
|
asChild
|
||||||
className="text-white p-[10px] bg-gray-900 flex-shrink-0 flex-grow-0
|
className="text-main p-[10px] bg-neutral flex-shrink-0 flex-grow-0
|
||||||
basis-auto w-[40px] h-[40px] rounded inline-flex text-[13px] leading-none
|
basis-auto w-[40px] h-[40px] rounded inline-flex text-[13px] leading-none
|
||||||
items-center justify-center outline-none hover:bg-indigo-900
|
items-center justify-center outline-none hover:bg-primary/50
|
||||||
transition-colors
|
transition-colors
|
||||||
focus:relative focus:shadow-[0_0_0_2px] focus:shadow-indigo"
|
focus:relative focus:shadow-[0_0_0_2px] focus:shadow-indigo"
|
||||||
>
|
>
|
||||||
@ -52,7 +52,7 @@ const ToolBar = () => {
|
|||||||
return (
|
return (
|
||||||
<Toolbar.Root
|
<Toolbar.Root
|
||||||
asChild
|
asChild
|
||||||
className="bg-gray-800 flex flex-col gap-1 p-1 h-full"
|
className="bg-neutral-accent flex flex-col gap-1 p-1 h-full"
|
||||||
orientation="vertical"
|
orientation="vertical"
|
||||||
>
|
>
|
||||||
<motion.div
|
<motion.div
|
||||||
|
@ -17,32 +17,21 @@
|
|||||||
@apply text-white;
|
@apply text-white;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1,
|
|
||||||
h2,
|
|
||||||
h3,
|
|
||||||
h4,
|
|
||||||
h5,
|
|
||||||
h6,
|
|
||||||
a,
|
|
||||||
label {
|
|
||||||
@apply dark:text-white;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@apply text-blue-600 underline;
|
@apply text-blue-600 underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
select,
|
select,
|
||||||
input {
|
input {
|
||||||
@apply box-border bg-gray-900 shadow-indigo-100 hover:shadow-indigo-400
|
@apply box-border bg-transparent shadow-main/10 hover:shadow-primary/50
|
||||||
focus:shadow-indigo-600 selection:bg-indigo-400 selection:text-black
|
focus:ring-primary focus:ring-2 focus:ring-offset-2
|
||||||
|
focus:shadow-primary selection:bg-secondary selection:text-black
|
||||||
outline-none px-3 py-2 rounded-md shadow-[0_0_0_1px];
|
outline-none px-3 py-2 rounded-md shadow-[0_0_0_1px];
|
||||||
}
|
}
|
||||||
|
|
||||||
input {
|
input {
|
||||||
@apply appearance-none items-center justify-center
|
@apply appearance-none items-center justify-center
|
||||||
w-full text-base leading-none
|
w-full text-base leading-none transition-all;
|
||||||
text-white transition-all;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
@ -50,78 +39,39 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
--background: 0 0% 100%;
|
--color-main: 0 0% 0%;
|
||||||
--foreground: 222.2 47.4% 11.2%;
|
|
||||||
|
|
||||||
--muted: 210 40% 96.1%;
|
--color-secondary: 0 0% 10%;
|
||||||
--muted-foreground: 215.4 16.3% 46.9%;
|
|
||||||
|
|
||||||
--popover: 0 0% 100%;
|
--color-neutral: 0 0% 100%;
|
||||||
--popover-foreground: 222.2 47.4% 11.2%;
|
--color-neutral-accent: 0 0% 90%;
|
||||||
|
|
||||||
--card: 0 0% 100%;
|
--color-highlight: 0 0% 0%;
|
||||||
--card-foreground: 222.2 47.4% 11.2%;
|
|
||||||
|
|
||||||
--border: 214.3 31.8% 91.4%;
|
--color-primary: 222.2 47.4% 11.2%;
|
||||||
--input: 214.3 31.8% 91.4%;
|
|
||||||
|
|
||||||
--primary: 222.2 47.4% 11.2%;
|
|
||||||
--primary-foreground: 210 40% 98%;
|
|
||||||
|
|
||||||
--secondary: 210 40% 96.1%;
|
|
||||||
--secondary-foreground: 222.2 47.4% 11.2%;
|
|
||||||
|
|
||||||
--accent: 210 40% 96.1%;
|
|
||||||
--accent-foreground: 222.2 47.4% 11.2%;
|
|
||||||
|
|
||||||
--destructive: 0 100% 50%;
|
|
||||||
--destructive-foreground: 210 40% 98%;
|
|
||||||
|
|
||||||
--ring: 215 20.2% 65.1%;
|
|
||||||
|
|
||||||
--radius: 0.5rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
@media (prefers-color-scheme: dark) {
|
||||||
--background: 224 71% 4%;
|
:root {
|
||||||
--foreground: 213 31% 91%;
|
--color-main: 0 0% 100%;
|
||||||
|
|
||||||
--muted: 223 47% 11%;
|
--color-primary: 260 80% 50%;
|
||||||
--muted-foreground: 215.4 16.3% 56.9%;
|
--color-secondary: 260 50% 70%;
|
||||||
|
|
||||||
--popover: 224 71% 4%;
|
--color-neutral: 250 30% 8%;
|
||||||
--popover-foreground: 215 20.2% 65.1%;
|
--color-neutral-accent: 250 40% 12%;
|
||||||
|
|
||||||
--card: 224 71% 4%;
|
--color-highlight: 250 20% 15%;
|
||||||
--card-foreground: 213 31% 91%;
|
}
|
||||||
|
|
||||||
--border: 216 34% 17%;
|
|
||||||
--input: 216 34% 17%;
|
|
||||||
|
|
||||||
--primary: 210 40% 98%;
|
|
||||||
--primary-foreground: 222.2 47.4% 1.2%;
|
|
||||||
|
|
||||||
--secondary: 222.2 47.4% 11.2%;
|
|
||||||
--secondary-foreground: 210 40% 98%;
|
|
||||||
|
|
||||||
--accent: 216 34% 17%;
|
|
||||||
--accent-foreground: 210 40% 98%;
|
|
||||||
|
|
||||||
--destructive: 0 63% 31%;
|
|
||||||
--destructive-foreground: 210 40% 98%;
|
|
||||||
|
|
||||||
--ring: 216 34% 17%;
|
|
||||||
|
|
||||||
--radius: 0.5rem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
* {
|
* {
|
||||||
@apply border-border;
|
@apply border-highlight;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
@apply bg-background text-foreground;
|
@apply bg-neutral text-main;
|
||||||
font-feature-settings: "rlig" 1, "calt" 1;
|
font-feature-settings: "rlig" 1, "calt" 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,53 +3,14 @@
|
|||||||
export default {
|
export default {
|
||||||
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
|
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
|
||||||
theme: {
|
theme: {
|
||||||
container: {
|
|
||||||
center: true,
|
|
||||||
padding: "2rem",
|
|
||||||
screens: {
|
|
||||||
"2xl": "1400px",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
extend: {
|
extend: {
|
||||||
colors: {
|
colors: {
|
||||||
border: "hsl(var(--border))",
|
main: "hsl(var(--color-main))",
|
||||||
input: "hsl(var(--input))",
|
secondary: "hsl(var(--color-secondary))",
|
||||||
ring: "hsl(var(--ring))",
|
neutral: "hsl(var(--color-neutral))",
|
||||||
background: "hsl(var(--background))",
|
"neutral-accent": "hsl(var(--color-neutral-accent))",
|
||||||
foreground: "hsl(var(--foreground))",
|
highlight: "hsl(var(--color-highlight))",
|
||||||
primary: {
|
primary: "hsl(var(--color-primary))",
|
||||||
DEFAULT: "hsl(var(--primary))",
|
|
||||||
foreground: "hsl(var(--primary-foreground))",
|
|
||||||
},
|
|
||||||
secondary: {
|
|
||||||
DEFAULT: "hsl(var(--secondary))",
|
|
||||||
foreground: "hsl(var(--secondary-foreground))",
|
|
||||||
},
|
|
||||||
destructive: {
|
|
||||||
DEFAULT: "hsl(var(--destructive))",
|
|
||||||
foreground: "hsl(var(--destructive-foreground))",
|
|
||||||
},
|
|
||||||
muted: {
|
|
||||||
DEFAULT: "hsl(var(--muted))",
|
|
||||||
foreground: "hsl(var(--muted-foreground))",
|
|
||||||
},
|
|
||||||
accent: {
|
|
||||||
DEFAULT: "hsl(var(--accent))",
|
|
||||||
foreground: "hsl(var(--accent-foreground))",
|
|
||||||
},
|
|
||||||
popover: {
|
|
||||||
DEFAULT: "hsl(var(--popover))",
|
|
||||||
foreground: "hsl(var(--popover-foreground))",
|
|
||||||
},
|
|
||||||
card: {
|
|
||||||
DEFAULT: "hsl(var(--card))",
|
|
||||||
foreground: "hsl(var(--card-foreground))",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
borderRadius: {
|
|
||||||
lg: "var(--radius)",
|
|
||||||
md: "calc(var(--radius) - 2px)",
|
|
||||||
sm: "calc(var(--radius) - 4px)",
|
|
||||||
},
|
},
|
||||||
keyframes: {
|
keyframes: {
|
||||||
"accordion-down": {
|
"accordion-down": {
|
||||||
|
@ -702,6 +702,22 @@
|
|||||||
"@radix-ui/react-use-callback-ref" "1.0.1"
|
"@radix-ui/react-use-callback-ref" "1.0.1"
|
||||||
"@radix-ui/react-use-controllable-state" "1.0.1"
|
"@radix-ui/react-use-controllable-state" "1.0.1"
|
||||||
|
|
||||||
|
"@radix-ui/react-scroll-area@^1.0.4":
|
||||||
|
version "1.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-scroll-area/-/react-scroll-area-1.0.4.tgz#13c36c453b2880aba57df67fb91a1d3f9b18998d"
|
||||||
|
integrity sha512-OIClwBkwPG+FKvC4OMTRaa/3cfD069nkKFFL/TQzRzaO42Ce5ivKU9VMKgT7UU6UIkjcQqKBrDOIzWtPGw6e6w==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
"@radix-ui/number" "1.0.1"
|
||||||
|
"@radix-ui/primitive" "1.0.1"
|
||||||
|
"@radix-ui/react-compose-refs" "1.0.1"
|
||||||
|
"@radix-ui/react-context" "1.0.1"
|
||||||
|
"@radix-ui/react-direction" "1.0.1"
|
||||||
|
"@radix-ui/react-presence" "1.0.1"
|
||||||
|
"@radix-ui/react-primitive" "1.0.3"
|
||||||
|
"@radix-ui/react-use-callback-ref" "1.0.1"
|
||||||
|
"@radix-ui/react-use-layout-effect" "1.0.1"
|
||||||
|
|
||||||
"@radix-ui/react-select@^1.2.2":
|
"@radix-ui/react-select@^1.2.2":
|
||||||
version "1.2.2"
|
version "1.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-select/-/react-select-1.2.2.tgz#caa981fa0d672cf3c1b2a5240135524e69b32181"
|
resolved "https://registry.yarnpkg.com/@radix-ui/react-select/-/react-select-1.2.2.tgz#caa981fa0d672cf3c1b2a5240135524e69b32181"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user