update sound design
update form design
This commit is contained in:
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@avocadi/ui",
|
"name": "@avocadi/ui",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.2.18",
|
"version": "0.3.0",
|
||||||
"description": "ui elements for avocadi",
|
"description": "ui elements for avocadi",
|
||||||
"private": false,
|
"private": false,
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+7
-2
@@ -64,10 +64,15 @@ function Button({
|
|||||||
className={cn(buttonVariants({ variant, size, className }))}
|
className={cn(buttonVariants({ variant, size, className }))}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
onClick?.(e);
|
onClick?.(e);
|
||||||
play({ id: "click1" });
|
}}
|
||||||
|
onMouseUp={() => {
|
||||||
|
play({ id: "clickSmall" });
|
||||||
|
}}
|
||||||
|
onMouseDown={() => {
|
||||||
|
play({ id: "clickSmall" });
|
||||||
}}
|
}}
|
||||||
onMouseEnter={(e) => {
|
onMouseEnter={(e) => {
|
||||||
play({ id: "click2" });
|
play({ id: "hover" });
|
||||||
onMouseEnter?.(e);
|
onMouseEnter?.(e);
|
||||||
}}
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
+28
-1
@@ -5,6 +5,7 @@ import { type HTMLMotionProps, motion } from "motion/react";
|
|||||||
import { forwardRef, type HTMLAttributes, type ReactNode } from "react";
|
import { forwardRef, type HTMLAttributes, type ReactNode } from "react";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { CardDepthProvider, useCardDepth } from "./card-context";
|
import { CardDepthProvider, useCardDepth } from "./card-context";
|
||||||
|
import useInterfaceSound from "./hooks/useInterfaceSound";
|
||||||
import {
|
import {
|
||||||
defaultTransitionCard,
|
defaultTransitionCard,
|
||||||
defaultVariantsCard,
|
defaultVariantsCard,
|
||||||
@@ -51,9 +52,26 @@ const Card = forwardRef<HTMLDivElement, CommonCardProps>(
|
|||||||
|
|
||||||
const Comp = asChild ? Slot : "div";
|
const Comp = asChild ? Slot : "div";
|
||||||
|
|
||||||
|
const { play } = useInterfaceSound();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CardDepthProvider>
|
<CardDepthProvider>
|
||||||
<Comp
|
<Comp
|
||||||
|
onMouseEnter={() => {
|
||||||
|
if (interactive) {
|
||||||
|
play({ id: "hover" });
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onMouseDown={() => {
|
||||||
|
if (interactive) {
|
||||||
|
play({ id: "clickSmall" });
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onMouseUp={() => {
|
||||||
|
if (interactive) {
|
||||||
|
play({ id: "clickSmall" });
|
||||||
|
}
|
||||||
|
}}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
style={{ borderRadius: `${radius}rem`, ...style }}
|
style={{ borderRadius: `${radius}rem`, ...style }}
|
||||||
className={cn(cardVariants({ interactive, className, padding }))}
|
className={cn(cardVariants({ interactive, className, padding }))}
|
||||||
@@ -70,11 +88,20 @@ const MCard = motion.create(Card);
|
|||||||
|
|
||||||
export const AnimatedCard: React.FC<
|
export const AnimatedCard: React.FC<
|
||||||
CommonCardProps & HTMLMotionProps<"div">
|
CommonCardProps & HTMLMotionProps<"div">
|
||||||
> = (props) => {
|
> = ({ interactive, ...props }) => {
|
||||||
return (
|
return (
|
||||||
<MCard
|
<MCard
|
||||||
variants={defaultVariantsCard}
|
variants={defaultVariantsCard}
|
||||||
transition={defaultTransitionCard}
|
transition={defaultTransitionCard}
|
||||||
|
{...(interactive && {
|
||||||
|
whileHover: {
|
||||||
|
scale: 1.05,
|
||||||
|
},
|
||||||
|
whileTap: {
|
||||||
|
scale: 0.95,
|
||||||
|
},
|
||||||
|
})}
|
||||||
|
interactive={interactive}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ function Checkbox({
|
|||||||
<CheckboxPrimitive.Root
|
<CheckboxPrimitive.Root
|
||||||
onCheckedChange={(checked) => {
|
onCheckedChange={(checked) => {
|
||||||
if (onCheckedChange) onCheckedChange(checked);
|
if (onCheckedChange) onCheckedChange(checked);
|
||||||
play({ id: "click2" });
|
play({ id: "clickSmall" });
|
||||||
}}
|
}}
|
||||||
data-slot="checkbox"
|
data-slot="checkbox"
|
||||||
className={cn(
|
className={cn(
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ const InputNumber = React.forwardRef<HTMLInputElement, Props>(
|
|||||||
value={draft}
|
value={draft}
|
||||||
onFocus={(e) => {
|
onFocus={(e) => {
|
||||||
setFocused(true);
|
setFocused(true);
|
||||||
play({ id: "click2" });
|
play({ id: "clickSmall" });
|
||||||
onFocus?.(e);
|
onFocus?.(e);
|
||||||
}}
|
}}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ const InputText = React.forwardRef<
|
|||||||
return (
|
return (
|
||||||
<input
|
<input
|
||||||
onFocus={() => {
|
onFocus={() => {
|
||||||
play({ id: "click2" });
|
play({ id: "clickSmall" });
|
||||||
}}
|
}}
|
||||||
type={type}
|
type={type}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex h-input-height w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
"flex h-input-height w-full rounded-input border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
+4
-4
@@ -15,9 +15,9 @@ function Select({
|
|||||||
<SelectPrimitive.Root
|
<SelectPrimitive.Root
|
||||||
onOpenChange={(open) => {
|
onOpenChange={(open) => {
|
||||||
if (open) {
|
if (open) {
|
||||||
play({ id: "click3" });
|
play({ id: "clickSmall" });
|
||||||
} else {
|
} else {
|
||||||
play({ id: "click4" });
|
play({ id: "clickSmall" });
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
data-slot="select"
|
data-slot="select"
|
||||||
@@ -53,7 +53,7 @@ function SelectTrigger({
|
|||||||
className={cn(
|
className={cn(
|
||||||
"border-main data-placeholder:text-secondary [&_svg:not([class*='text-'])]:text-secondary focus-visible:border-ring",
|
"border-main data-placeholder:text-secondary [&_svg:not([class*='text-'])]:text-secondary focus-visible:border-ring",
|
||||||
"focus-visible:ring-main/50 aria-invalid:ring-error/20 dark:aria-invalid:ring-error/40 aria-invalid:border-error",
|
"focus-visible:ring-main/50 aria-invalid:ring-error/20 dark:aria-invalid:ring-error/40 aria-invalid:border-error",
|
||||||
"dark:bg-neutral-accent/30 dark:hover:bg-neutral-accent/50 flex w-fit items-center justify-between gap-2 rounded-full",
|
"dark:bg-neutral-accent/30 dark:hover:bg-neutral-accent/50 flex w-fit items-center justify-between gap-2 rounded-input",
|
||||||
"border bg-transparent px-4 py-2 text-sm text-main whitespace-nowrap shadow-xs transition-[color,box-shadow,background-color] outline-none",
|
"border bg-transparent px-4 py-2 text-sm text-main whitespace-nowrap shadow-xs transition-[color,box-shadow,background-color] outline-none",
|
||||||
"focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-input-height data-[size=sm]:h-8",
|
"focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-input-height data-[size=sm]:h-8",
|
||||||
"*:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center",
|
"*:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center",
|
||||||
@@ -133,7 +133,7 @@ function SelectItem({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<SelectPrimitive.Item
|
<SelectPrimitive.Item
|
||||||
onMouseEnter={() => play({ id: "click2" })}
|
onMouseEnter={() => play({ id: "hover" })}
|
||||||
data-slot="select-item"
|
data-slot="select-item"
|
||||||
className={cn(
|
className={cn(
|
||||||
"focus:bg-main/25 text-main/75 focus:text-main [&_svg:not([class*='text-'])]:text-main transition-colors",
|
"focus:bg-main/25 text-main/75 focus:text-main [&_svg:not([class*='text-'])]:text-main transition-colors",
|
||||||
|
|||||||
@@ -1,41 +1,32 @@
|
|||||||
import { useSound } from "use-sound";
|
import { useSound } from "use-sound";
|
||||||
import z from "zod";
|
import z from "zod";
|
||||||
import soundSpriteButtons from "../assets/sounds/762132__ienba__ui-buttons.wav";
|
|
||||||
import soundSprite from "../assets/sounds/842498__newlocknew__uimvmt_game-user-interface-sound-set.mp3";
|
|
||||||
|
|
||||||
const UiSoundSetSprites = z.enum([
|
import clickSmallSound from "../assets/sounds/clickSmall.wav";
|
||||||
"smooth1",
|
import hoverSound from "../assets/sounds/hover.wav";
|
||||||
"smooth2",
|
import uploadSuccessSound from "../assets/sounds/uploadSuccess.wav";
|
||||||
"lobbyCreated",
|
|
||||||
"gameStart",
|
|
||||||
]);
|
|
||||||
|
|
||||||
const UiButtonSprites = z.enum(["click1", "click2", "click3", "click4"]);
|
export const InterfaceSounds = z.enum(["clickSmall", "hover", "uploadSuccess"]);
|
||||||
|
|
||||||
export default function useInterfaceSound() {
|
export default function useInterfaceSound() {
|
||||||
const [playSprite1] = useSound(soundSprite, {
|
const [playHover] = useSound(hoverSound);
|
||||||
sprite: {
|
|
||||||
smooth1: [0, 1200],
|
|
||||||
smooth2: [7800, 1400],
|
|
||||||
lobbyCreated: [53800, 3500],
|
|
||||||
gameStart: [62000, 4000],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const [playSprite2] = useSound(soundSpriteButtons, {
|
const [playClickSmall] = useSound(clickSmallSound);
|
||||||
sprite: {
|
|
||||||
click1: [0, 1000],
|
|
||||||
click2: [2750, 1000],
|
|
||||||
click3: [5200, 1000],
|
|
||||||
click4: [7700, 1000],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const play = ({ id }: { id: string }) => {
|
const [playUploadSuccess] = useSound(uploadSuccessSound);
|
||||||
if (UiSoundSetSprites.safeParse(id).success) {
|
|
||||||
playSprite1({ id });
|
const play = ({ id }: { id: z.output<typeof InterfaceSounds> }) => {
|
||||||
} else if (UiButtonSprites.safeParse(id).success) {
|
switch (id) {
|
||||||
playSprite2({ id });
|
case "clickSmall":
|
||||||
|
playClickSmall();
|
||||||
|
break;
|
||||||
|
case "hover":
|
||||||
|
playHover();
|
||||||
|
break;
|
||||||
|
case "uploadSuccess":
|
||||||
|
playUploadSuccess();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import { stagger, type Transition } from "motion";
|
import { stagger, type Transition } from "motion";
|
||||||
import { motion, type Variants } from "motion/react";
|
import { motion, type Variants } from "motion/react";
|
||||||
import type { FC } from "react";
|
import type { FC } from "react";
|
||||||
|
import useInterfaceSound from "@/hooks/useInterfaceSound";
|
||||||
import { cn, getRandomInt } from "@/lib/utils";
|
import { cn, getRandomInt } from "@/lib/utils";
|
||||||
|
|
||||||
const variants: {
|
const variants: {
|
||||||
@@ -46,6 +47,8 @@ export const LogoText: FC<{
|
|||||||
"transition-colors",
|
"transition-colors",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { play } = useInterfaceSound();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<motion.svg
|
<motion.svg
|
||||||
variants={variants.container}
|
variants={variants.container}
|
||||||
@@ -53,6 +56,9 @@ export const LogoText: FC<{
|
|||||||
transition={{
|
transition={{
|
||||||
delayChildren: stagger(0.1, { from: "center" }),
|
delayChildren: stagger(0.1, { from: "center" }),
|
||||||
}}
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
play({ id: "clickSmall" });
|
||||||
|
}}
|
||||||
{...(animateOnGestures && { whileHover: "hover", whileTap: "active" })}
|
{...(animateOnGestures && { whileHover: "hover", whileTap: "active" })}
|
||||||
className="overflow-visible"
|
className="overflow-visible"
|
||||||
width="100%"
|
width="100%"
|
||||||
|
|||||||
@@ -49,6 +49,8 @@
|
|||||||
--radius-lg: var(--radius);
|
--radius-lg: var(--radius);
|
||||||
--radius-xl: calc(var(--radius) + 4px);
|
--radius-xl: calc(var(--radius) + 4px);
|
||||||
--radius-2xl: calc(var(--radius) + 12px);
|
--radius-2xl: calc(var(--radius) + 12px);
|
||||||
|
|
||||||
|
--radius-input: calc(var(--radius) + 4px);
|
||||||
}
|
}
|
||||||
|
|
||||||
@theme {
|
@theme {
|
||||||
|
|||||||
Reference in New Issue
Block a user