Skip to content

Commit

Permalink
Merge pull request #122 from oaknational/feat/PUPIL-434/quiz-order
Browse files Browse the repository at this point in the history
PUPIL-434: Order question sortable UI
  • Loading branch information
carlmw authored Mar 1, 2024
2 parents f938e54 + 1096085 commit e318854
Show file tree
Hide file tree
Showing 37 changed files with 2,198 additions and 3 deletions.
56 changes: 55 additions & 1 deletion package-lock.json

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

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
"devDependencies": {
"@commitlint/cli": "^18.4.4",
"@commitlint/config-conventional": "^18.4.4",
"@dnd-kit/core": "^6.1.0",
"@dnd-kit/sortable": "^8.0.0",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",
Expand Down
43 changes: 43 additions & 0 deletions src/components/atoms/OakKbd/OakKbd.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from "react";
import { Meta, StoryObj } from "@storybook/react";

import { OakKbd } from "../OakKbd";

const meta: Meta<typeof OakKbd> = {
component: OakKbd,
tags: ["autodocs"],
title: "components/atoms/OakKbd",
args: {
children: "Tab",
},
argTypes: {
children: {
type: { name: "string" },
},
},
parameters: {
controls: {
include: ["children"],
},
backgrounds: {
default: "light",
},
},
render: (args) => <OakKbd {...args} />,
};
export default meta;

type Story = StoryObj<typeof OakKbd>;

export const Default: Story = {};

export const ArrowKeys: Story = {
render: () => {
return (
<>
<OakKbd></OakKbd> <OakKbd></OakKbd> <OakKbd></OakKbd>{" "}
<OakKbd></OakKbd>
</>
);
},
};
20 changes: 20 additions & 0 deletions src/components/atoms/OakKbd/OakKbd.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from "react";
import "@testing-library/jest-dom";
import { create } from "react-test-renderer";

import { OakKbd } from "./OakKbd";

import { OakThemeProvider } from "@/components/atoms";
import { oakDefaultTheme } from "@/styles";

describe(OakKbd, () => {
it("matches snapshot", () => {
const tree = create(
<OakThemeProvider theme={oakDefaultTheme}>
<OakKbd>Tab</OakKbd>
</OakThemeProvider>,
).toJSON();

expect(tree).toMatchSnapshot();
});
});
28 changes: 28 additions & 0 deletions src/components/atoms/OakKbd/OakKbd.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { ReactNode } from "react";

import { OakSpan } from "@/components/atoms/OakSpan";

export type OakKbdProps = {
children: ReactNode;
};

/**
* Represents textual user input from a keyboard, voice input, or any other text entry device.
* */
export const OakKbd = ({ children }: OakKbdProps) => {
return (
<OakSpan
$font="body-3-bold"
as="kbd"
$borderColor="border-decorative3-stronger"
$background="bg-primary"
$borderRadius="border-radius-m"
$ba="border-solid-m"
$ph="inner-padding-xs"
$pv="inner-padding-ssx"
$whiteSpace="nowrap"
>
{children}
</OakSpan>
);
};
29 changes: 29 additions & 0 deletions src/components/atoms/OakKbd/__snapshots__/OakKbd.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`OakKbd matches snapshot 1`] = `
.c0 {
background: #ffffff;
padding-left: 0.5rem;
padding-right: 0.5rem;
padding-top: 0.25rem;
padding-bottom: 0.25rem;
border: 0.125rem solid;
border-color: #7c9aec;
border-radius: 0.375rem;
font-family: Lexend,sans-serif;
font-weight: 700;
font-size: 0.875rem;
line-height: 1.25rem;
-webkit-letter-spacing: -0.005rem;
-moz-letter-spacing: -0.005rem;
-ms-letter-spacing: -0.005rem;
letter-spacing: -0.005rem;
white-space: nowrap;
}
<kbd
className="c0"
>
Tab
</kbd>
`;
1 change: 1 addition & 0 deletions src/components/atoms/OakKbd/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./OakKbd";
1 change: 1 addition & 0 deletions src/components/atoms/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ export * from "./OakGridArea";
export * from "./OakThemeProvider";
export * from "./OakMaxWidth";
export * from "./OakCloudinaryImage";
export * from "./OakKbd";
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from "react";
import { Meta, StoryObj } from "@storybook/react";

import { OakDragAndDropInstructions } from "./OakDragAndDropInstructions";

const meta: Meta<typeof OakDragAndDropInstructions> = {
component: OakDragAndDropInstructions,
tags: ["autodocs"],
title: "components/molecules/OakDragAndDropInstructions",
parameters: {
controls: {
include: [],
},
backgrounds: {
default: "light",
},
},
render: (args) => <OakDragAndDropInstructions {...args} />,
};
export default meta;

type Story = StoryObj<typeof OakDragAndDropInstructions>;

export const Default: Story = {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from "react";
import "@testing-library/jest-dom";
import { create } from "react-test-renderer";

import { OakDragAndDropInstructions } from "./OakDragAndDropInstructions";

import { OakThemeProvider } from "@/components/atoms";
import { oakDefaultTheme } from "@/styles";

describe(OakDragAndDropInstructions, () => {
it("matches snapshot", () => {
const tree = create(
<OakThemeProvider theme={oakDefaultTheme}>
<OakDragAndDropInstructions />
</OakThemeProvider>,
).toJSON();

expect(tree).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React, { ComponentPropsWithoutRef } from "react";
import styled from "styled-components";

import { OakBox, OakFlex, OakIcon, OakKbd } from "@/components/atoms";
import { parseSpacing } from "@/styles/helpers/parseSpacing";

const KeyboardInstructions = styled(OakBox)`
@media (pointer: coarse) {
display: none;
}
`;

const TouchInstructions = styled(OakBox)`
@media (hover: hover) and (pointer: fine) {
display: none;
}
`;

/**
* Adds additional leading between each line of text to make room for the
* keyboard instructions wrapped in `<OakKbd>`
*
* This might be a useful atom to extract
*/
const StyledLeadingTrim = styled(OakFlex)`
margin-block: calc(-${parseSpacing("space-between-ssx")} / 2);
line-height: calc(1.5rem + ${parseSpacing("space-between-ssx")});
`;

/**
* Displays different instructions for drag and drop functionality
* depending on the user's primary input device
*/
export const OakDragAndDropInstructions = (
props: ComponentPropsWithoutRef<typeof OakFlex>,
) => {
return (
<OakFlex $gap="space-between-ssx" {...props}>
<OakFlex $flexGrow={0}>
<OakIcon iconName="move-arrows" />
</OakFlex>
<StyledLeadingTrim
$font="body-2"
$gap="space-between-ssx"
$flexDirection="column"
>
<KeyboardInstructions>
Where you see this, you can click and move things around by dragging
them, or by pressing the{" "}
<OakKbd>
<span aria-hidden="true"></span> Tab
</OakKbd>{" "}
and <OakKbd>Space</OakKbd> keys and the <OakKbd></OakKbd>{" "}
<OakKbd></OakKbd> <OakKbd></OakKbd> <OakKbd></OakKbd> arrows on
your keyboard
</KeyboardInstructions>
<TouchInstructions>
Where you see this, you can click and move things around by dragging
them. If you're using a keyboard, press the{" "}
<OakKbd>
<span aria-hidden="true"></span> Tab
</OakKbd>{" "}
and <OakKbd>Space</OakKbd> keys and the <OakKbd></OakKbd>{" "}
<OakKbd></OakKbd> <OakKbd></OakKbd> <OakKbd></OakKbd> arrows on
your keyboard to select and move items.
</TouchInstructions>
</StyledLeadingTrim>
</OakFlex>
);
};
Loading

0 comments on commit e318854

Please sign in to comment.