Skip to content

Commit

Permalink
feat: Add primitive layout picker control.
Browse files Browse the repository at this point in the history
* Initial crude physical layout picker for selecting
  from the available layouts on the device.
  • Loading branch information
petejohanson committed Jun 2, 2024
1 parent c6de9de commit e77c09b
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/keyboard/PhysicalLayoutPicker.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { Meta, StoryObj } from '@storybook/react';
import { fn } from '@storybook/test';
import { PhysicalLayoutPicker } from './PhysicalLayoutPicker';

// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = {
title: 'Keyboard/PhysicalLayoutPicker',
component: PhysicalLayoutPicker,
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'],
// More on argTypes: https://storybook.js.org/docs/api/argtypes
argTypes: {
// backgroundColor: { control: 'color' },
},
// Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args
args: { },
} satisfies Meta<typeof PhysicalLayoutPicker>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Standard: Story = {
args: {
layouts: [
{ name: "ISO"},
{ name: "ANSI"},
],
selectedPhysicalLayoutIndex: 1,
onPhysicalLayoutClicked: (index) => console.log("Layer clicked", index),
},
};
40 changes: 40 additions & 0 deletions src/keyboard/PhysicalLayoutPicker.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import './physical-layout-picker.css';

export interface PhysicalLayoutItem {
name: string;
}

export type PhysicalLayoutClickCallback = (index: number) => void;

export interface PhysicalLayoutPickerProps {
layouts: Array<PhysicalLayoutItem>;

selectedPhysicalLayoutIndex: number;

onPhysicalLayoutClicked?: PhysicalLayoutClickCallback;
}

function renderItem(item: PhysicalLayoutItem, index: number, selected: boolean, onClick?: PhysicalLayoutClickCallback) {
let className = "zmk-physical-layout-picker__item";
if (selected) {
className += " zmk-physical-layout-picker__item--selected";
}
return <li className={className} onClick={() => onClick?.(index)}>{item.name}</li>;
}

export const PhysicalLayoutPicker = ({
layouts,
selectedPhysicalLayoutIndex,
onPhysicalLayoutClicked,
...props
}: PhysicalLayoutPickerProps) => {
let layout_items = layouts.map((item, index) => renderItem(item, index, index === selectedPhysicalLayoutIndex, onPhysicalLayoutClicked));

return (
<ul
className='zmk-physical-layout-picker'
{...props}>
{layout_items}
</ul>
);
};
42 changes: 42 additions & 0 deletions src/keyboard/physical-layout-picker.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.zmk-physical-layout-picker {
border: 0;
cursor: pointer;
display: inline-block;
line-height: 1;
display: flex;
justify-content: center;
align-items: center;
list-style: none;
display: grid;
grid-auto-flow: row;
grid-auto-rows: auto;
}

.zmk-physical-layout-picker__item {
padding: 0.25em;
border-width: 1px;
border-style: solid;
border-color: transparent;
}

.zmk-physical-layout-picker__item--selected {
background-color: gray;
}

.zmk-physical-layout-picker__item:hover {
border-radius: 2px;
border-color: black;
}


/*
.zmk-key__button--primary {
color: #333;
background-color: transparent;
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
}
.zmk-key__button--secondary {
color: white;
background-color: #8c8c8c;
} */

0 comments on commit e77c09b

Please sign in to comment.