Skip to content

Commit

Permalink
improve: Key Component scale transition
Browse files Browse the repository at this point in the history
- improve: smoother scale transition when hovering
- feat: toggle select+deselect, allows users to deselect a currently
  selected key

.
  • Loading branch information
pongstr committed Dec 20, 2024
1 parent e5ab3b5 commit e3ff99c
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 23 deletions.
15 changes: 14 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,22 @@ module.exports = {
parser: "@typescript-eslint/parser",
plugins: ["react-refresh"],
rules: {
"tailwindcss/no-custom-classname": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{
args: "all",
argsIgnorePattern: "^_",
caughtErrors: "all",
caughtErrorsIgnorePattern: "^_",
destructuredArrayIgnorePattern: "^_",
varsIgnorePattern: "^_",
ignoreRestSiblings: true,
},
],
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
},
};
}
5 changes: 4 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
{}
{
"tabWidth": 2,
"semi": true,
}
29 changes: 29 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"eslint-plugin-storybook": "^0.8.0",
"eslint-plugin-tailwindcss": "^3.17.5",
"postcss": "^8.4.38",
"prettier": "3.3.2",
"run-script-os": "^1.1.6",
Expand Down
49 changes: 31 additions & 18 deletions src/keyboard/Key.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// import './key.css';

import { PropsWithChildren, Children, CSSProperties } from "react";
import { PropsWithChildren, Children, CSSProperties, FC } from "react";

interface KeyProps {
/**
Expand Down Expand Up @@ -39,11 +39,25 @@ function makeSize(
height *= oneU;

return {
"--zmk-key-center-width": "calc(" + width + "px - 2px)",
"--zmk-key-center-height": "calc(" + height + "px - 2px)",
"--zmk-key-center-width": `calc(${width}px - 2px)`,
"--zmk-key-center-height": `calc(${height}px - 2px)`,
};
}

const ChildItem: FC<PropsWithChildren<{ hoverZoom: boolean }>> = ({
children,
hoverZoom,
}) => {
return (
<div
data-zoomer={hoverZoom}
className="col-start-2 col-end-3 row-start-2 row-end-3 self-center justify-self-center font-keycap text-lg"
>
{children}
</div>
);
};

export const Key = ({
selected = false,
header,
Expand All @@ -53,35 +67,34 @@ export const Key = ({
}: PropsWithChildren<KeyProps>) => {
const size = makeSize(props, oneU);

const children = Children.map(props.children, (c) => (
<div
data-zoomer={hoverZoom}
className="justify-self-center self-center row-start-2 row-end-3 col-start-2 col-end-3 font-keycap text-lg data-[zoomer=true]:group-hover:text-2xl"
>
{c}
</div>
));

return (
<div
className="group inline-flex b-0 justify-content-center items-center transition-all duration-100 data-[zoomer=true]:hover:translate-y-[calc(-1em-7px)] data-[zoomer=true]:hover:translate-x-[calc(-1em)]"
className="group justify-content-center group items-center select-none transition-transform origin-center data-[zoomer=true]:hover:scale-[2] data-[zoomer=true]:hover:z-20"
data-zoomer={hoverZoom}
style={size}
{...props}
>
<button
aria-selected={selected}
data-zoomer={hoverZoom}
className={`rounded${
oneU > 20 ? "-md" : ""
} transition-all duration-100 m-auto p-0 b-0 box-border grid grid-rows-[0_var(--zmk-key-center-height)_0] grid-cols-[0_var(--zmk-key-center-width)_0] data-[zoomer=true]:hover:grid-rows-[1em_var(--zmk-key-center-height)_1em] data-[zoomer=true]:hover:grid-cols-[1em_var(--zmk-key-center-width)_1em] shadow-[0_0_0_1px_inset] shadow-base-content data-[zoomer=true]:shadow-base-200 data-[zoomer=true]:hover:shadow-base-content data-[zoomer=true]:hover:z-50 text-base-content bg-base-100 aria-selected:bg-primary aria-selected:text-primary-content grow @container`}
className={[
oneU > 20 ? "rounded-md" : "rounded",
"relative w-[var(--zmk-key-center-width)] h-[var(--zmk-key-center-height)] bg-base-100 border border-transparent",
"group-hover:border-[#a6adbb] aria-selected:bg-primary aria-selected:text-primary-content @container",
].join(' ')}
>
{header && (
<span className="p-0 b-0 m-0 text-xs w-full h-full text-nowrap justify-self-start row-start-1 row-end-2 col-start-1 col-end-4 hidden group-hover:inline-block group-hover:truncate @md:underline">
<span className="opacity-80 truncate hidden group-hover:block text-[6px] text-center uppercase absolute top-1 left-[4px] right-[4px] max-w-[90%] h-4 leading-none">
{header}
</span>
)}
{children}

{props.children &&
Children.map(props.children, (child, index) => (
<ChildItem key={index} hoverZoom={hoverZoom}>
{child}
</ChildItem>
))}
</button>
</div>
);
Expand Down
3 changes: 2 additions & 1 deletion src/keyboard/Keymap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
PhysicalLayout as PhysicalLayoutComp,
} from "./PhysicalLayout";
import { HidUsageLabel } from "./HidUsageLabel";
import { Dispatch, SetStateAction } from "react";

type BehaviorMap = Record<number, GetBehaviorDetailsResponse>;

Expand All @@ -19,7 +20,7 @@ export interface KeymapProps {
scale: LayoutZoom;
selectedLayerIndex: number;
selectedKeyPosition: number | undefined;
onKeyPositionClicked: (keyPosition: number) => void;
onKeyPositionClicked: Dispatch<SetStateAction<number | undefined>>
}

export const Keymap = ({
Expand Down
1 change: 1 addition & 0 deletions src/keyboard/PhysicalLayout.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const meta = {
component: PhysicalLayout,
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
layout: "centered"
},
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
tags: ["autodocs"],
Expand Down
10 changes: 8 additions & 2 deletions src/keyboard/PhysicalLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {
Dispatch,
SetStateAction,
CSSProperties,
PropsWithChildren,
useLayoutEffect,
Expand Down Expand Up @@ -33,7 +35,7 @@ interface PhysicalLayoutProps {
oneU?: number;
hoverZoom?: boolean;
zoom?: LayoutZoom;
onPositionClicked?: (position: number) => void;
onPositionClicked?: Dispatch<SetStateAction<number | undefined>>
}

interface PhysicalLayoutPositionLocation {
Expand Down Expand Up @@ -125,7 +127,11 @@ export const PhysicalLayout = ({
const positionItems = positions.map((p, idx) => (
<div
key={idx}
onClick={() => onPositionClicked?.(idx)}
onClick={() =>
onPositionClicked?.((prev: number | undefined) =>
prev !== idx ? idx : undefined,
)
}
className="absolute data-[zoomer=true]:hover:z-[1000] leading-[0]"
data-zoomer={hoverZoom}
style={scalePosition(p, oneU)}
Expand Down

0 comments on commit e3ff99c

Please sign in to comment.