20 | Learn how CSS Grid works through a number of CSS Grid questions!
21 |
22 |
23 | With the current version, you can learn how grid placement
24 | properties work.
25 |
26 | >
27 | ),
28 | proceed: "Proceed to Tutorial",
29 | progress: (
30 | <>
31 |
33 | To save your progress, just save current URL. To continue, open that
34 | URL and go on!
35 |
36 | >
37 | ),
38 | },
39 | ja: {
40 | intro: (
41 | <>
42 |
44 | 現在のバージョンでは、グリッドアイテムの配置にかかわるプロパティの挙動を学ぶことができます。
45 |
46 | >
47 | ),
48 | proceed: "チュートリアルに進む",
49 | progress: (
50 | <>
51 |
53 | 現在の進捗を保存するには、現在のURLを保存しておくだけで構いません。そのURLを開けば再開できます。
54 |
55 | >
56 | ),
57 | },
58 | });
59 |
60 | return (
61 | {
4 | try {
5 | const ns = await import(`./v1/${id}.tsx`);
6 | if (ns.data) {
7 | return ns.data;
8 | }
9 | } catch (err) {
10 | console.error(err);
11 | }
12 | throw new Error(`Cannot load quiz for v1/${id}`);
13 | }
14 |
--------------------------------------------------------------------------------
/src/questions/v1/1.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 | import { Tutorial1 } from "./tutorial/Tutorial1";
3 |
4 | export const data: QuestionData = {
5 | type: "tutorial",
6 | contents: ,
7 | };
8 |
--------------------------------------------------------------------------------
/src/questions/v1/10.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | `.trim();
7 |
8 | const itemStyle = `
9 | grid-column: 2 / span 2;
10 | grid-row: span 2 / auto;
11 | `.trim();
12 |
13 | export const data: QuestionData = {
14 | type: "grid",
15 | gridStyle,
16 | itemStyle,
17 | gridDef: {
18 | rows: 4,
19 | columns: 4,
20 | },
21 | answer: ["2,1", "3,1", "2,2", "3,2"],
22 | };
23 |
--------------------------------------------------------------------------------
/src/questions/v1/11.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | grid-template-areas:
7 | "a a b b"
8 | "a a b b"
9 | "a a c c"
10 | "a a c c";
11 | `.trim();
12 |
13 | const itemStyle = `
14 | grid-area: b;
15 | `.trim();
16 |
17 | export const data: QuestionData = {
18 | type: "grid",
19 | gridStyle,
20 | itemStyle,
21 | gridDef: {
22 | rows: 4,
23 | columns: 4,
24 | },
25 | answer: ["3,1", "4,1", "3,2", "4,2"],
26 | };
27 |
--------------------------------------------------------------------------------
/src/questions/v1/12.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | grid-template-areas:
7 | "a a b b"
8 | "a a b b"
9 | "a a c c"
10 | "a a c c";
11 | `.trim();
12 |
13 | const itemStyle = `
14 | grid-column: b;
15 | grid-row: c;
16 | `.trim();
17 |
18 | export const data: QuestionData = {
19 | type: "grid",
20 | gridStyle,
21 | itemStyle,
22 | gridDef: {
23 | rows: 4,
24 | columns: 4,
25 | },
26 | answer: ["3,3", "4,3", "3,4", "4,4"],
27 | };
28 |
--------------------------------------------------------------------------------
/src/questions/v1/13.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | grid-template-areas:
7 | "a a b b"
8 | "a a b b"
9 | "a a c c"
10 | "a a c c";
11 | `.trim();
12 |
13 | const itemStyle = `
14 | grid-column: 2;
15 | grid-row: b / c;
16 | `.trim();
17 |
18 | export const data: QuestionData = {
19 | type: "grid",
20 | gridStyle,
21 | itemStyle,
22 | gridDef: {
23 | rows: 4,
24 | columns: 4,
25 | },
26 | answer: ["2,1", "2,2", "2,3", "2,4"],
27 | };
28 |
--------------------------------------------------------------------------------
/src/questions/v1/14.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | grid-template-areas:
7 | "a a b b"
8 | "a a b b"
9 | "a a c c"
10 | "a a c c";
11 | `.trim();
12 |
13 | const itemStyle = `
14 | grid-column: a / span 1;
15 | grid-row: b / span 2;
16 | `.trim();
17 |
18 | export const data: QuestionData = {
19 | type: "grid",
20 | gridStyle,
21 | itemStyle,
22 | gridDef: {
23 | rows: 4,
24 | columns: 4,
25 | },
26 | answer: ["1,1", "1,2"],
27 | };
28 |
--------------------------------------------------------------------------------
/src/questions/v1/15.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | grid-template-areas:
7 | "a a b b"
8 | "a a b b"
9 | "a a c c"
10 | "a a c c";
11 | `.trim();
12 |
13 | const itemStyle = `
14 | grid-column: span 1 / a;
15 | grid-row: c / -1;
16 | `.trim();
17 |
18 | export const data: QuestionData = {
19 | type: "grid",
20 | gridStyle,
21 | itemStyle,
22 | gridDef: {
23 | rows: 4,
24 | columns: 4,
25 | },
26 | answer: ["2,3", "2,4"],
27 | };
28 |
--------------------------------------------------------------------------------
/src/questions/v1/16.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | grid-template-areas:
7 | "a a b b"
8 | "a a b b"
9 | "a a c c"
10 | "a a c c";
11 | `.trim();
12 |
13 | const itemStyle = `
14 | grid-column: 2 / a;
15 | grid-row: auto / b;
16 | `.trim();
17 |
18 | export const data: QuestionData = {
19 | type: "grid",
20 | gridStyle,
21 | itemStyle,
22 | gridDef: {
23 | rows: 4,
24 | columns: 4,
25 | },
26 | answer: ["2,2"],
27 | };
28 |
--------------------------------------------------------------------------------
/src/questions/v1/17.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [c] 1fr [d] 1fr [e];
6 | grid-template-rows:
7 | [v] 1fr [w] 1fr [x] 1fr [y] 1fr [z];
8 | `.trim();
9 |
10 | const itemStyle = `
11 | grid-column: b / span 2;
12 | grid-row: x;
13 | `.trim();
14 |
15 | export const data: QuestionData = {
16 | type: "grid",
17 | gridStyle,
18 | itemStyle,
19 | gridDef: {
20 | rows: 4,
21 | columns: 4,
22 | },
23 | answer: ["2,3", "3,3"],
24 | };
25 |
--------------------------------------------------------------------------------
/src/questions/v1/18.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [c] 1fr [d] 1fr [e];
6 | grid-template-rows:
7 | [v] 1fr [w] 1fr [x] 1fr [y] 1fr [z];
8 | `.trim();
9 |
10 | const itemStyle = `
11 | grid-column: b / c;
12 | grid-row: v / y;
13 | `.trim();
14 |
15 | export const data: QuestionData = {
16 | type: "grid",
17 | gridStyle,
18 | itemStyle,
19 | gridDef: {
20 | rows: 4,
21 | columns: 4,
22 | },
23 | answer: ["2,1", "2,2", "2,3"],
24 | };
25 |
--------------------------------------------------------------------------------
/src/questions/v1/19.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [c] 1fr [d] 1fr [e];
6 | grid-template-rows:
7 | [v] 1fr [w] 1fr [x] 1fr [y] 1fr [z];
8 | `.trim();
9 |
10 | const itemStyle = `
11 | grid-column: a / span d;
12 | grid-row: span v / 3;
13 | `.trim();
14 |
15 | export const data: QuestionData = {
16 | type: "grid",
17 | gridStyle,
18 | itemStyle,
19 | gridDef: {
20 | rows: 4,
21 | columns: 4,
22 | },
23 | answer: ["1,1", "2,1", "3,1", "1,2", "2,2", "3,2"],
24 | };
25 |
--------------------------------------------------------------------------------
/src/questions/v1/2.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | `.trim();
7 |
8 | const itemStyle = `
9 | grid-column: 3;
10 | grid-row: 2;
11 | `.trim();
12 |
13 | export const data: QuestionData = {
14 | type: "grid",
15 | gridStyle,
16 | itemStyle,
17 | gridDef: {
18 | rows: 4,
19 | columns: 4,
20 | },
21 | answer: ["3,2"],
22 | };
23 |
--------------------------------------------------------------------------------
/src/questions/v1/20.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [a] 1fr [b] 1fr [a b];
6 | grid-template-rows:
7 | [x] 1fr [y] 1fr [x] 1fr [y] 1fr [x y];
8 | `.trim();
9 |
10 | const itemStyle = `
11 | grid-column: a / span 2;
12 | grid-row: y;
13 | `.trim();
14 |
15 | export const data: QuestionData = {
16 | type: "grid",
17 | gridStyle,
18 | itemStyle,
19 | gridDef: {
20 | rows: 4,
21 | columns: 4,
22 | },
23 | answer: ["1,2", "2,2"],
24 | };
25 |
--------------------------------------------------------------------------------
/src/questions/v1/21.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [a] 1fr [b] 1fr [a b];
6 | grid-template-rows:
7 | [x] 1fr [y] 1fr [x] 1fr [y] 1fr [x y];
8 | `.trim();
9 |
10 | const itemStyle = `
11 | grid-column: a 2;
12 | grid-row: x / y;
13 | `.trim();
14 |
15 | export const data: QuestionData = {
16 | type: "grid",
17 | gridStyle,
18 | itemStyle,
19 | gridDef: {
20 | rows: 4,
21 | columns: 4,
22 | },
23 | answer: ["3,1"],
24 | };
25 |
--------------------------------------------------------------------------------
/src/questions/v1/22.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [a] 1fr [b] 1fr [a b];
6 | grid-template-rows:
7 | [x] 1fr [y] 1fr [x] 1fr [y] 1fr [x y];
8 | `.trim();
9 |
10 | const itemStyle = `
11 | grid-column: a 2 / b 3;
12 | grid-row: x / span y 3;
13 | `.trim();
14 |
15 | export const data: QuestionData = {
16 | type: "grid",
17 | gridStyle,
18 | itemStyle,
19 | gridDef: {
20 | rows: 4,
21 | columns: 4,
22 | },
23 | answer: ["3,1", "4,1", "3,2", "4,2", "3,3", "4,3", "3,4", "4,4"],
24 | };
25 |
--------------------------------------------------------------------------------
/src/questions/v1/23.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [a] 1fr [b] 1fr [a b];
6 | grid-template-rows:
7 | [x] 1fr [y] 1fr [x] 1fr [y] 1fr [x y];
8 | `.trim();
9 |
10 | const itemStyle = `
11 | grid-column: a / b -2;
12 | grid-row: 2 / span x;
13 | `.trim();
14 |
15 | export const data: QuestionData = {
16 | type: "grid",
17 | gridStyle,
18 | itemStyle,
19 | gridDef: {
20 | rows: 4,
21 | columns: 4,
22 | },
23 | answer: ["1,2", "2,2", "3,2"],
24 | };
25 |
--------------------------------------------------------------------------------
/src/questions/v1/24.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [a] 1fr [b] 1fr [a b];
6 | grid-template-rows:
7 | [x] 1fr [y] 1fr [x] 1fr [y] 1fr [x y];
8 | `.trim();
9 |
10 | const itemStyle = `
11 | grid-column: 4 / 2;
12 | grid-row: 2 x / 2 y;
13 | `.trim();
14 |
15 | export const data: QuestionData = {
16 | type: "grid",
17 | gridStyle,
18 | itemStyle,
19 | gridDef: {
20 | rows: 4,
21 | columns: 4,
22 | },
23 | answer: ["2,3", "3,3"],
24 | };
25 |
--------------------------------------------------------------------------------
/src/questions/v1/25.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | grid-template-areas:
7 | "a a b b"
8 | "a a b b"
9 | "a a c c"
10 | "a a c c";
11 | `.trim();
12 |
13 | const itemStyle = `
14 | grid-column: 2 / a;
15 | grid-row: b-end / span 2;
16 | `.trim();
17 |
18 | export const data: QuestionData = {
19 | type: "grid",
20 | gridStyle,
21 | itemStyle,
22 | gridDef: {
23 | rows: 4,
24 | columns: 4,
25 | },
26 | answer: ["2,3", "2,4"],
27 | };
28 |
--------------------------------------------------------------------------------
/src/questions/v1/26.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 | import { Tutorial2 } from "./tutorial/Tutorial2";
3 |
4 | export const data: QuestionData = {
5 | type: "tutorial",
6 | contents: ,
7 | };
8 |
--------------------------------------------------------------------------------
/src/questions/v1/27.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | `.trim();
7 |
8 | const itemStyle = `
9 | grid-column: 4 / 6;
10 | grid-row: 3;
11 | `.trim();
12 |
13 | export const data: QuestionData = {
14 | type: "grid",
15 | extensible: true,
16 | gridStyle,
17 | itemStyle,
18 | gridDef: {
19 | rows: 4,
20 | columns: 4,
21 | },
22 | answer: ["4,3", "5,3"],
23 | };
24 |
--------------------------------------------------------------------------------
/src/questions/v1/28.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | `.trim();
7 |
8 | const itemStyle = `
9 | grid-column: span 3 / -4;
10 | grid-row: 2 / 4;
11 | `.trim();
12 |
13 | export const data: QuestionData = {
14 | type: "grid",
15 | extensible: true,
16 | gridStyle,
17 | itemStyle,
18 | gridDef: {
19 | rows: 4,
20 | columns: 4,
21 | },
22 | answer: ["-1,2", "0,2", "1,2", "-1,3", "0,3", "1,3"],
23 | };
24 |
--------------------------------------------------------------------------------
/src/questions/v1/29.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | `.trim();
7 |
8 | const itemStyle = `
9 | grid-column: 8;
10 | grid-row: 6;
11 | `.trim();
12 |
13 | export const data: QuestionData = {
14 | type: "grid",
15 | extensible: true,
16 | gridStyle,
17 | itemStyle,
18 | gridDef: {
19 | rows: 4,
20 | columns: 4,
21 | },
22 | answer: ["8,6"],
23 | };
24 |
--------------------------------------------------------------------------------
/src/questions/v1/3.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | `.trim();
7 |
8 | const itemStyle = `
9 | grid-column: 1 / 3;
10 | grid-row: 2 / 3;
11 | `.trim();
12 |
13 | export const data: QuestionData = {
14 | type: "grid",
15 | gridStyle,
16 | itemStyle,
17 | gridDef: {
18 | rows: 4,
19 | columns: 4,
20 | },
21 | answer: ["1,2", "2,2"],
22 | };
23 |
--------------------------------------------------------------------------------
/src/questions/v1/30.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [a] 1fr [b] 1fr [a b];
6 | grid-template-rows:
7 | [x] 1fr [y] 1fr [x] 1fr [y] 1fr [x y];
8 | `.trim();
9 |
10 | const itemStyle = `
11 | grid-column: span 2 / a;
12 | grid-row: y / span y;
13 | `.trim();
14 |
15 | export const data: QuestionData = {
16 | type: "grid",
17 | extensible: true,
18 | gridStyle,
19 | itemStyle,
20 | gridDef: {
21 | rows: 4,
22 | columns: 4,
23 | },
24 | answer: ["-1,2", "0,2", "-1,3", "0,3"],
25 | };
26 |
--------------------------------------------------------------------------------
/src/questions/v1/31.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [a] 1fr [b] 1fr [a b];
6 | grid-template-rows:
7 | [x] 1fr [y] 1fr [x] 1fr [y] 1fr [x y];
8 | `.trim();
9 |
10 | const itemStyle = `
11 | grid-column: a 2 / a 4;
12 | grid-row: x -5;
13 | `.trim();
14 |
15 | export const data: QuestionData = {
16 | type: "grid",
17 | extensible: true,
18 | gridStyle,
19 | itemStyle,
20 | gridDef: {
21 | rows: 4,
22 | columns: 4,
23 | },
24 | answer: ["3,-1", "4,-1", "5,-1"],
25 | };
26 |
--------------------------------------------------------------------------------
/src/questions/v1/32.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [a] 1fr [b] 1fr [a b];
6 | grid-template-rows:
7 | [x] 1fr [y] 1fr [x] 1fr [y] 1fr [x y];
8 | `.trim();
9 |
10 | const itemStyle = `
11 | grid-column: c -1 / span c;
12 | grid-row: 2;
13 | `.trim();
14 |
15 | export const data: QuestionData = {
16 | type: "grid",
17 | extensible: true,
18 | gridStyle,
19 | itemStyle,
20 | gridDef: {
21 | rows: 4,
22 | columns: 4,
23 | },
24 | answer: ["0,2", "1,2", "2,2", "3,2", "4,2", "5,2"],
25 | };
26 |
--------------------------------------------------------------------------------
/src/questions/v1/33.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [a] 1fr [b] 1fr [a b];
6 | grid-template-rows:
7 | [x] 1fr [y] 1fr [x] 1fr [y] 1fr [x y];
8 | `.trim();
9 |
10 | const itemStyle = `
11 | grid-column: span a 2 / 2;
12 | grid-row: -2 z;
13 | `.trim();
14 |
15 | export const data: QuestionData = {
16 | type: "grid",
17 | extensible: true,
18 | gridStyle,
19 | itemStyle,
20 | gridDef: {
21 | rows: 4,
22 | columns: 4,
23 | },
24 | answer: ["0,-1", "1,-1"],
25 | };
26 |
--------------------------------------------------------------------------------
/src/questions/v1/34.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | grid-template-areas:
7 | "a a b b"
8 | "a a b b"
9 | "a a c c"
10 | "a a c c";
11 | `.trim();
12 |
13 | const itemStyle = `
14 | grid-column: 2 / span a 2;
15 | grid-row: -2 b;
16 | `.trim();
17 |
18 | export const data: QuestionData = {
19 | type: "grid",
20 | extensible: true,
21 | gridStyle,
22 | itemStyle,
23 | gridDef: {
24 | rows: 4,
25 | columns: 4,
26 | },
27 | answer: ["2,-1", "3,-1", "4,-1", "5,-1", "6,-1"],
28 | };
29 |
--------------------------------------------------------------------------------
/src/questions/v1/35.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | grid-template-areas:
7 | "a a b b"
8 | "a a b b"
9 | "a a c c"
10 | "a a c c";
11 | `.trim();
12 |
13 | const itemStyle = `
14 | grid-column: a-end / span a-start;
15 | grid-row: c 2 / c 4;
16 | `.trim();
17 |
18 | export const data: QuestionData = {
19 | type: "grid",
20 | extensible: true,
21 | gridStyle,
22 | itemStyle,
23 | gridDef: {
24 | rows: 4,
25 | columns: 4,
26 | },
27 | answer: ["3,7", "4,7", "5,7", "3,8", "4,8", "5,8"],
28 | };
29 |
--------------------------------------------------------------------------------
/src/questions/v1/36.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: [a] 1fr [b] 1fr [c];
5 | grid-template-rows: [a] 1fr [b] 1fr [c];
6 | grid-template-areas:
7 | "c b"
8 | "x a";
9 | `.trim();
10 |
11 | const itemStyle = `
12 | grid-column: a;
13 | grid-row: b;
14 | `.trim();
15 |
16 | export const data: QuestionData = {
17 | type: "grid",
18 | extensible: true,
19 | gridStyle,
20 | itemStyle,
21 | gridDef: {
22 | rows: 2,
23 | columns: 2,
24 | },
25 | answer: ["2,1"],
26 | };
27 |
--------------------------------------------------------------------------------
/src/questions/v1/37.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: [a] 1fr [b] 1fr [c];
5 | grid-template-rows: [a] 1fr [b] 1fr [c];
6 | grid-template-areas:
7 | "c b"
8 | "x a";
9 | `.trim();
10 |
11 | const itemStyle = `
12 | grid-column: c / 1 c;
13 | grid-row: b 1 / span a;
14 | `.trim();
15 |
16 | export const data: QuestionData = {
17 | type: "grid",
18 | extensible: true,
19 | gridStyle,
20 | itemStyle,
21 | gridDef: {
22 | rows: 2,
23 | columns: 2,
24 | },
25 | answer: ["1,2", "2,2", "1,3", "2,3"],
26 | };
27 |
--------------------------------------------------------------------------------
/src/questions/v1/38.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: [a] 1fr [b] 1fr [c];
5 | grid-template-rows: [a] 1fr [b] 1fr [c];
6 | grid-template-areas:
7 | "c b"
8 | "x a";
9 | `.trim();
10 |
11 | const itemStyle = `
12 | grid-column: span x / b-end;
13 | grid-row: x-start;
14 | `.trim();
15 |
16 | export const data: QuestionData = {
17 | type: "grid",
18 | extensible: true,
19 | gridStyle,
20 | itemStyle,
21 | gridDef: {
22 | rows: 2,
23 | columns: 2,
24 | },
25 | answer: ["0,2", "1,2", "2,2"],
26 | };
27 |
--------------------------------------------------------------------------------
/src/questions/v1/39.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 | import { Tutorial3 } from "./tutorial/Tutorial3";
3 |
4 | export const data: QuestionData = {
5 | type: "tutorial",
6 | contents: ,
7 | };
8 |
--------------------------------------------------------------------------------
/src/questions/v1/4.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | `.trim();
7 |
8 | const itemStyle = `
9 | grid-column: 1 / -2;
10 | grid-row: 4;
11 | `.trim();
12 |
13 | export const data: QuestionData = {
14 | type: "grid",
15 | gridStyle,
16 | itemStyle,
17 | gridDef: {
18 | rows: 4,
19 | columns: 4,
20 | },
21 | answer: ["1,4", "2,4", "3,4"],
22 | };
23 |
--------------------------------------------------------------------------------
/src/questions/v1/40.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(5, 1fr);
5 | grid-template-rows: repeat(5, 1fr);
6 | `.trim();
7 |
8 | const subgridStyle = `
9 | grid-column: 2 / span 3;
10 | grid-row: 2 / span 3;
11 | grid-template-columns: subgrid;
12 | grid-template-rows: subgrid;
13 | `.trim();
14 |
15 | const itemStyle = `
16 | grid-column: 2;
17 | grid-row: 1 / 3;
18 | `.trim();
19 |
20 | export const data: QuestionData = {
21 | type: "grid",
22 | gridStyle,
23 | subgridStyle,
24 | itemStyle,
25 | gridDef: {
26 | rows: 5,
27 | columns: 5,
28 | },
29 | answer: ["3,2", "3,3"],
30 | };
31 |
--------------------------------------------------------------------------------
/src/questions/v1/41.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(5, 1fr);
5 | grid-template-rows: repeat(5, 1fr);
6 | `.trim();
7 |
8 | const subgridStyle = `
9 | grid-column: 2 / span 3;
10 | grid-row: 2 / span 3;
11 | grid-template-columns: subgrid;
12 | grid-template-rows: subgrid;
13 | `.trim();
14 |
15 | const itemStyle = `
16 | grid-column: 2 / span 3;
17 | grid-row: 2;
18 | `.trim();
19 |
20 | export const data: QuestionData = {
21 | type: "grid",
22 | gridStyle,
23 | subgridStyle,
24 | itemStyle,
25 | gridDef: {
26 | rows: 5,
27 | columns: 5,
28 | },
29 | answer: ["3,3", "4,3"],
30 | };
31 |
--------------------------------------------------------------------------------
/src/questions/v1/42.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(5, 1fr);
5 | grid-template-rows: repeat(5, 1fr);
6 | `.trim();
7 |
8 | const subgridStyle = `
9 | grid-column: 2 / span 3;
10 | grid-row: 2 / span 3;
11 | grid-template-columns: subgrid;
12 | grid-template-rows: subgrid;
13 | `.trim();
14 |
15 | const itemStyle = `
16 | grid-column: span 2 / -2;
17 | grid-row: -2 / -4;
18 | `.trim();
19 |
20 | export const data: QuestionData = {
21 | type: "grid",
22 | gridStyle,
23 | subgridStyle,
24 | itemStyle,
25 | gridDef: {
26 | rows: 5,
27 | columns: 5,
28 | },
29 | answer: ["2,2", "3,2", "2,3", "3,3"],
30 | };
31 |
--------------------------------------------------------------------------------
/src/questions/v1/43.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(5, 1fr);
5 | grid-template-rows: repeat(5, 1fr);
6 | `.trim();
7 |
8 | const subgridStyle = `
9 | grid-column: 2 / span 3;
10 | grid-row: 2 / span 3;
11 | grid-template-columns: subgrid [a] [b] [c] [d];
12 | grid-template-rows: subgrid [w] [x] [y] [z];
13 | `.trim();
14 |
15 | const itemStyle = `
16 | grid-column: a / c;
17 | grid-row: x / z;
18 | `.trim();
19 |
20 | export const data: QuestionData = {
21 | type: "grid",
22 | gridStyle,
23 | subgridStyle,
24 | itemStyle,
25 | gridDef: {
26 | rows: 5,
27 | columns: 5,
28 | },
29 | answer: ["2,3", "3,3", "2,4", "3,4"],
30 | };
31 |
--------------------------------------------------------------------------------
/src/questions/v1/44.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(5, 1fr);
5 | grid-template-rows: repeat(5, 1fr);
6 | `.trim();
7 |
8 | const subgridStyle = `
9 | grid-column: 2 / span 3;
10 | grid-row: 2 / span 3;
11 | grid-template-columns: subgrid [a] [b] [c] [d];
12 | grid-template-rows: subgrid [w] [x] [y] [z];
13 | `.trim();
14 |
15 | const itemStyle = `
16 | grid-column: a / a 2;
17 | grid-row: span w / y;
18 | `.trim();
19 |
20 | export const data: QuestionData = {
21 | type: "grid",
22 | gridStyle,
23 | subgridStyle,
24 | itemStyle,
25 | gridDef: {
26 | rows: 5,
27 | columns: 5,
28 | },
29 | answer: ["2,2", "3,2", "4,2", "2,3", "3,3", "4,3"],
30 | };
31 |
--------------------------------------------------------------------------------
/src/questions/v1/45.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [c] 1fr [d] 1fr [e];
6 | grid-template-rows:
7 | [v] 1fr [w] 1fr [x] 1fr [y] 1fr [z];
8 | `.trim();
9 |
10 | const subgridStyle = `
11 | grid-column: b / e;
12 | grid-row: v / y;
13 | grid-template-columns: subgrid;
14 | grid-template-rows: subgrid;
15 | `.trim();
16 |
17 | const itemStyle = `
18 | grid-column: b / d;
19 | grid-row: z / w;
20 | `.trim();
21 |
22 | export const data: QuestionData = {
23 | type: "grid",
24 | gridStyle,
25 | subgridStyle,
26 | itemStyle,
27 | gridDef: {
28 | rows: 4,
29 | columns: 4,
30 | },
31 | answer: ["2,2", "3,2", "2,3", "3,3"],
32 | };
33 |
--------------------------------------------------------------------------------
/src/questions/v1/46.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [c] 1fr [d] 1fr [e];
6 | grid-template-rows:
7 | [v] 1fr [w] 1fr [x] 1fr [y] 1fr [z];
8 | `.trim();
9 |
10 | const subgridStyle = `
11 | grid-column: b / e;
12 | grid-row: v / y;
13 | grid-template-columns: subgrid [f] [] [g];
14 | grid-template-rows: subgrid [] [h] [] [i];
15 | `.trim();
16 |
17 | const itemStyle = `
18 | grid-column: c / g;
19 | grid-row: h / span 1 i;
20 | `.trim();
21 |
22 | export const data: QuestionData = {
23 | type: "grid",
24 | gridStyle,
25 | subgridStyle,
26 | itemStyle,
27 | gridDef: {
28 | rows: 4,
29 | columns: 4,
30 | },
31 | answer: ["3,2", "3,3"],
32 | };
33 |
--------------------------------------------------------------------------------
/src/questions/v1/47.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns:
5 | [a] 1fr [b] 1fr [c] 1fr [d] 1fr [e];
6 | grid-template-rows:
7 | [v] 1fr [w] 1fr [x] 1fr [y] 1fr [z];
8 | `.trim();
9 |
10 | const subgridStyle = `
11 | grid-column: c / -1;
12 | grid-row: v / -2;
13 | grid-template-columns: subgrid [] [f];
14 | grid-template-rows: subgrid [] [h] [i];
15 | `.trim();
16 |
17 | const itemStyle = `
18 | grid-column: f;
19 | grid-row: h / i;
20 | `.trim();
21 |
22 | export const data: QuestionData = {
23 | type: "grid",
24 | gridStyle,
25 | subgridStyle,
26 | itemStyle,
27 | gridDef: {
28 | rows: 4,
29 | columns: 4,
30 | },
31 | answer: ["4,2"],
32 | };
33 |
--------------------------------------------------------------------------------
/src/questions/v1/48.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | grid-template-areas:
7 | "a a b b"
8 | "a a b b"
9 | "a a c c"
10 | "a a c c";
11 | `.trim();
12 |
13 | const subgridStyle = `
14 | grid-column: a;
15 | grid-row: a;
16 | grid-template-columns: subgrid;
17 | grid-template-rows: subgrid;
18 | `.trim();
19 |
20 | const itemStyle = `
21 | grid-column: a / b;
22 | grid-row: 2 / span 2;
23 | `.trim();
24 |
25 | export const data: QuestionData = {
26 | type: "grid",
27 | gridStyle,
28 | subgridStyle,
29 | itemStyle,
30 | gridDef: {
31 | rows: 4,
32 | columns: 4,
33 | },
34 | answer: ["1,2", "2,2", "1,3", "2,3"],
35 | };
36 |
--------------------------------------------------------------------------------
/src/questions/v1/49.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | grid-template-areas:
7 | "a a b b"
8 | "a a b b"
9 | "a a c c"
10 | "a a c c";
11 | `.trim();
12 |
13 | const subgridStyle = `
14 | grid-column: 2 / span 2;
15 | grid-row: 2 / span 2;
16 | grid-template-columns: subgrid;
17 | grid-template-rows: subgrid;
18 | `.trim();
19 |
20 | const itemStyle = `
21 | grid-column: a;
22 | grid-row: b / c-end;
23 | `.trim();
24 |
25 | export const data: QuestionData = {
26 | type: "grid",
27 | gridStyle,
28 | subgridStyle,
29 | itemStyle,
30 | gridDef: {
31 | rows: 4,
32 | columns: 4,
33 | },
34 | answer: ["2,2", "2,3"],
35 | };
36 |
--------------------------------------------------------------------------------
/src/questions/v1/5.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | `.trim();
7 |
8 | const itemStyle = `
9 | grid-column: 2 / span 2;
10 | grid-row: 1 / 3;
11 | `.trim();
12 |
13 | export const data: QuestionData = {
14 | type: "grid",
15 | gridStyle,
16 | itemStyle,
17 | gridDef: {
18 | rows: 4,
19 | columns: 4,
20 | },
21 | answer: ["2,1", "3,1", "2,2", "3,2"],
22 | };
23 |
--------------------------------------------------------------------------------
/src/questions/v1/50.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | grid-template-areas:
7 | "a a b b"
8 | "a a b b"
9 | "a a c c"
10 | "a a c c";
11 | `.trim();
12 |
13 | const subgridStyle = `
14 | grid-column: 2 / span 2;
15 | grid-row: 2 / span 2;
16 | grid-template-columns: subgrid;
17 | grid-template-rows: subgrid;
18 | grid-template-areas:
19 | "b a"
20 | "b a";
21 | `.trim();
22 |
23 | const itemStyle = `
24 | grid-column: a;
25 | grid-row: c;
26 | `.trim();
27 |
28 | export const data: QuestionData = {
29 | type: "grid",
30 | gridStyle,
31 | subgridStyle,
32 | itemStyle,
33 | gridDef: {
34 | rows: 4,
35 | columns: 4,
36 | },
37 | answer: ["2,3"],
38 | };
39 |
--------------------------------------------------------------------------------
/src/questions/v1/51.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | grid-template-areas:
7 | "a a b b"
8 | "a a b b"
9 | "a a c c"
10 | "a a c c";
11 | `.trim();
12 |
13 | const subgridStyle = `
14 | grid-column: 2 / span 3;
15 | grid-row: 2 / span 3;
16 | grid-template-columns: subgrid;
17 | grid-template-rows: subgrid;
18 | grid-template-areas:
19 | "b a a"
20 | "b a a"
21 | "b a a;
22 | `.trim();
23 |
24 | const itemStyle = `
25 | grid-column: a-start 2;
26 | grid-row: span 2 / b-end -1;
27 | `.trim();
28 |
29 | export const data: QuestionData = {
30 | type: "grid",
31 | gridStyle,
32 | subgridStyle,
33 | itemStyle,
34 | gridDef: {
35 | rows: 4,
36 | columns: 4,
37 | },
38 | answer: ["3,3", "3,4"],
39 | };
40 |
--------------------------------------------------------------------------------
/src/questions/v1/52.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | grid-template-areas:
7 | "a a b b"
8 | "a a b b"
9 | "a a c c"
10 | "a a c c";
11 | `.trim();
12 |
13 | const subgridStyle = `
14 | grid-column: 2 / span 3;
15 | grid-row: 2 / span 3;
16 | grid-template-columns: subgrid [] [c-start];
17 | grid-template-rows: subgrid [] [] [b-end];
18 | grid-template-areas:
19 | "b a a"
20 | "b a a"
21 | "b a a;
22 | `.trim();
23 |
24 | const itemStyle = `
25 | grid-column: c-start 2;
26 | grid-row: 1 / b-end 2;
27 | `.trim();
28 |
29 | export const data: QuestionData = {
30 | type: "grid",
31 | gridStyle,
32 | subgridStyle,
33 | itemStyle,
34 | gridDef: {
35 | rows: 4,
36 | columns: 4,
37 | },
38 | answer: ["4,2", "4,3"],
39 | };
40 |
--------------------------------------------------------------------------------
/src/questions/v1/53.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 | import { Congratulations } from "./tutorial/Congratulations";
3 |
4 | export const data: QuestionData = {
5 | type: "tutorial",
6 | contents: ,
7 | noNext: true,
8 | };
9 |
--------------------------------------------------------------------------------
/src/questions/v1/6.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | `.trim();
7 |
8 | const itemStyle = `
9 | grid-column: span 2 / 4;
10 | grid-row: 1 / span 3;
11 | `.trim();
12 |
13 | export const data: QuestionData = {
14 | type: "grid",
15 | gridStyle,
16 | itemStyle,
17 | gridDef: {
18 | rows: 4,
19 | columns: 4,
20 | },
21 | answer: ["2,1", "3,1", "2,2", "3,2", "2,3", "3,3"],
22 | };
23 |
--------------------------------------------------------------------------------
/src/questions/v1/7.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | `.trim();
7 |
8 | const itemStyle = `
9 | grid-area: 1 / 2 / 3 / 4;
10 | `.trim();
11 |
12 | export const data: QuestionData = {
13 | type: "grid",
14 | gridStyle,
15 | itemStyle,
16 | gridDef: {
17 | rows: 4,
18 | columns: 4,
19 | },
20 | answer: ["2,1", "3,1", "2,2", "3,2"],
21 | };
22 |
--------------------------------------------------------------------------------
/src/questions/v1/8.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | `.trim();
7 |
8 | const itemStyle = `
9 | grid-column: auto / 3;
10 | grid-row: 3 / auto;
11 | `.trim();
12 |
13 | export const data: QuestionData = {
14 | type: "grid",
15 | gridStyle,
16 | itemStyle,
17 | gridDef: {
18 | rows: 4,
19 | columns: 4,
20 | },
21 | answer: ["2,3"],
22 | };
23 |
--------------------------------------------------------------------------------
/src/questions/v1/9.tsx:
--------------------------------------------------------------------------------
1 | import { QuestionData } from "../QuestionData";
2 |
3 | const gridStyle = `
4 | grid-template-columns: repeat(4, 1fr);
5 | grid-template-rows: repeat(4, 1fr);
6 | `.trim();
7 |
8 | const itemStyle = `
9 | grid-column: auto;
10 | grid-row: auto / span 4;
11 | `.trim();
12 |
13 | export const data: QuestionData = {
14 | type: "grid",
15 | gridStyle,
16 | itemStyle,
17 | gridDef: {
18 | rows: 4,
19 | columns: 4,
20 | },
21 | answer: ["1,1", "1,2", "1,3", "1,4"],
22 | };
23 |
--------------------------------------------------------------------------------
/src/questions/v1/tutorial/Congratulations.tsx:
--------------------------------------------------------------------------------
1 | import { useMemo } from "react";
2 | import { appUrl } from "../../../const";
3 | import { useI18n } from "../../../utils/i18n/LanguageContext";
4 | import classes from "./Tutorial.module.css";
5 |
6 | export const Congratulations: React.VFC = () => {
7 | const shareText = useI18n({
8 | en: "I solved all the problems in CSS Grid Mastery Quiz!\n",
9 | ja: "CSS Grid Mastery Quizで全ての問題をクリアしました!\n",
10 | });
11 |
12 | const twitterIntent = useMemo(() => {
13 | return `https://twitter.com/intent/tweet?text=${encodeURIComponent(
14 | shareText
15 | )}&url=${encodeURIComponent(appUrl)}`;
16 | }, [shareText]);
17 | const contents = useI18n({
18 | en: (
19 | <>
20 | Congratulations!
21 | You solved all the problems in CSS Grid Mastery Quiz.
22 |
23 | You are now CSS Grid Master!
24 |
25 |
26 |
32 | Share on Twitter
33 |
34 |
35 | >
36 | ),
37 | ja: (
38 | <>
39 | 完全制覇!
40 |
41 | おめでとうございます! CSS Grid Mastery
42 | Quizの全ての問題をクリアしました。
43 |
44 |
45 | あなたはCSS Gridマスターです!
46 |
47 |
48 |
54 | Twitterでシェアする
55 |
56 |
57 | >
58 | ),
59 | });
60 | return {contents};
61 | };
62 |
--------------------------------------------------------------------------------
/src/questions/v1/tutorial/Tutorial.module.css:
--------------------------------------------------------------------------------
1 | .tutorial h1 {
2 | font-size: 2em;
3 | }
4 |
5 | .sampleGridWrapper {
6 | width: 300px;
7 | }
8 |
9 | .shareOnTwitter {
10 | background-color: #00aced;
11 | color: #ffffff;
12 | font-size: 1.5em;
13 | font-weight: bold;
14 | padding: 0.5em;
15 | border-radius: 0.5em;
16 | text-decoration: none;
17 | }
--------------------------------------------------------------------------------
/src/questions/v1/tutorial/Tutorial1.tsx:
--------------------------------------------------------------------------------
1 | import { GridArea } from "../../../pages/QuestionPage/components/GridArea";
2 | import { useGridItemSelection } from "../../../pages/QuestionPage/logic/useGridItemSelection";
3 | import { useI18n } from "../../../utils/i18n/LanguageContext";
4 | import classes from "./Tutorial.module.css";
5 |
6 | export const Tutorial1: React.VFC = () => {
7 | const { gridDef, selectedItems, toggleItem } = useSampleGrid();
8 |
9 | const code1 = (
10 |
11 |
12 | {`
13 |
16 | `.trim()}
17 |
18 |
19 | );
20 | const code2 = (
21 |
22 |
23 | {`
24 | .grid-container {
25 | display: grid;
26 | grid-template-columns: 1fr 1fr;
27 | grid-template-rows: 1fr 1fr;
28 | }
29 | .grid-item {
30 | grid-column: 1;
31 | grid-row: 1;
32 | }
33 | `.trim()}
34 |
35 |
36 | );
37 | const sample = (
38 |
39 |
45 |
46 | );
47 |
48 | const contents = useI18n({
49 | en: (
50 | <>
51 | Tutorial #1
52 | Consider the following HTML structure:
53 | {code1}
54 | You are given style definitions for above elements. Example:
55 | {code2}
56 |
57 | Click/tap all grid cells occupied by the .grid-item
{" "}
58 | element. Press “Check” button to check your answer.
59 |
60 | Sample:
61 | {sample}
62 | After making three mistakes, a “Cheat” button appears.
63 | >
64 | ),
65 | ja: (
66 | <>
67 | チュートリアル #1
68 | ここでは、次のHTML構造を考えます。
69 | {code1}
70 | これに対して、次の例のようにスタイル定義が与えられます。
71 | {code2}
72 |
73 | .grid-item
74 | 要素が占めるすべてのグリッドセルをクリック/タップしてください。
75 | その後“Check”ボタンを押して答えが合っているか確かめましょう。
76 |
77 | 例:
78 | {sample}
79 | 3回間違えると“Cheat”ボタンが出現します。
80 | >
81 | ),
82 | });
83 |
84 | return {contents};
85 | };
86 |
87 | function useSampleGrid() {
88 | const gridDef = {
89 | columns: 2,
90 | rows: 2,
91 | };
92 | const { selectedItems, toggleItem } = useGridItemSelection([], ["1,1"]);
93 |
94 | return {
95 | gridDef,
96 | selectedItems,
97 | toggleItem,
98 | };
99 | }
100 |
--------------------------------------------------------------------------------
/src/questions/v1/tutorial/Tutorial2.tsx:
--------------------------------------------------------------------------------
1 | import { GridArea } from "../../../pages/QuestionPage/components/GridArea";
2 | import { GridAreaExtensionControl } from "../../../pages/QuestionPage/components/GridAreaExtensionControl";
3 | import { useGridExtension } from "../../../pages/QuestionPage/logic/useGridExtension";
4 | import { useGridItemSelection } from "../../../pages/QuestionPage/logic/useGridItemSelection";
5 | import { useI18n } from "../../../utils/i18n/LanguageContext";
6 | import classes from "./Tutorial.module.css";
7 |
8 | export const Tutorial2: React.VFC = () => {
9 | const { gridDef, selectedItems, extension, toggleItem, extend } =
10 | useSampleGrid();
11 |
12 | const sample = (
13 |
14 |
15 |
26 |
27 |
28 | );
29 |
30 | const contents = useI18n({
31 | en: (
32 | <>
33 | Tutorial #2
34 |
35 | When grid items are placed outside of the grid area explicitly deined
36 | by grid-template-columns
and{" "}
37 | grid-template-rows
,implicit grid tracks and{" "}
38 | implicit grid lines are generated outside of explicit grid
39 | tracks.
40 |
41 |
42 | From now on, the correct answer may enter those implicit grid cells.
43 |
44 |
45 | To specify such cells, you need to extend the displayed grid
46 | by pressing the plus buttons placed at each edge.
47 |
48 |
49 | To remove extended cells, you need to reset the state of the grid by
50 | pressing “Reset” button.
51 |
52 | Sample:
53 | {sample}
54 | >
55 | ),
56 | ja: (
57 | <>
58 | チュートリアル #2
59 |
60 | グリッドアイテムがgrid-template-columns
および
61 | grid-template-rows
62 | によって明示的に定義されたグリッドエリアの外に配置された場合、
63 | 明示的なグリッドエリアの外側に暗黙のグリッドトラック
64 | が生成されます。
65 |
66 |
67 | これからは、正しい答えが初期表示されているグリッドの範囲を超えて暗黙のグリッドトラックにまたがる可能性があります。
68 |
69 |
70 | そのような回答をするためには、表示されているグリッドを、各辺に配置されたプラスボタンを押すことで拡張する必要があります。
71 |
72 |
73 | 拡張したグリッドセルを元に戻すには、“Reset”ボタンを押して画面を初期化する必要があります。
74 |
75 | 拡張できるグリッドセルのサンプル:
76 | {sample}
77 | >
78 | ),
79 | });
80 | return {contents};
81 | };
82 |
83 | function useSampleGrid() {
84 | const gridDef = {
85 | columns: 2,
86 | rows: 2,
87 | };
88 | const { selectedItems, toggleItem } = useGridItemSelection([]);
89 | const { extension, extend } = useGridExtension([]);
90 |
91 | return {
92 | gridDef,
93 | selectedItems,
94 | extension,
95 | toggleItem,
96 | extend,
97 | };
98 | }
99 |
--------------------------------------------------------------------------------
/src/questions/v1/tutorial/Tutorial3.tsx:
--------------------------------------------------------------------------------
1 | import { GridArea } from "../../../pages/QuestionPage/components/GridArea";
2 | import { useGridItemSelection } from "../../../pages/QuestionPage/logic/useGridItemSelection";
3 | import { useI18n } from "../../../utils/i18n/LanguageContext";
4 | import classes from "./Tutorial.module.css";
5 |
6 | export const Tutorial3: React.VFC = () => {
7 | const { gridDef, selectedItems, toggleItem } = useSampleGrid();
8 |
9 | const code1 = (
10 |
11 |
12 | {`
13 |
18 | `.trim()}
19 |
20 |
21 | );
22 |
23 | const code2 = (
24 |
25 |
26 | {`
27 | .grid-container {
28 | display: grid;
29 | grid-template-columns: 1fr 1fr 1fr;
30 | grid-template-rows: 1fr 1fr 1fr;
31 | }
32 | .subgrid {
33 | grid-column: 2 / 4;
34 | grid-rows: 1 / 3;
35 | display: grid;
36 | grid-template-columns: subgrid;
37 | grid-template-rows: subgrid;
38 | }
39 | .grid-item {
40 | grid-column: 1;
41 | grid-row: 1;
42 | }
43 | `.trim()}
44 |
45 |
46 | );
47 |
48 | const sample = (
49 |
50 |
60 |
61 | );
62 |
63 | const contents = useI18n({
64 | en: (
65 | <>
66 | Tutorial #3
67 |
68 | A recent version of CSS Grid has the concept of subgrid. A
69 | subgrid itself is a grid item of the parent grid container and also
70 | has its own grid in it. An axis declared as subgrid inherit grid lines
71 | from the parent grid, still maintaining its own coordinate system.
72 |
73 | From now on, let's consider the following HTML structure:
74 | {code1}
75 |
76 | Now you are given style definitions for these three elements. Example:
77 |
78 | {code2}
79 |
80 | You still need to answer the grid cells occupied by the element at the
81 | bottom of tree, namely .grid-item
one. Note that the
82 | coordinates displayed in the answering grid is ones of the parent grid
83 | container (.grid-container
).
84 |
85 | Sample (answer for the above style):
86 | {sample}
87 | >
88 | ),
89 | ja: (
90 | <>
91 | チュートリアル #3
92 |
93 | 最近のバージョンのCSS Gridには、サブグリッド
94 | という概念があります。サブグリッドは、親のグリッドに
95 | 属するグリッドアイテムでありつつ、自身もグリッドコンテナです。
96 | サブグリッドとして宣言された軸は、親のグリッドトラックをそのまま継承しますが、独自の座標軸を持っています。
97 |
98 | 今後の問題では、次のようなHTML構造を考えます。
99 | {code1}
100 |
101 | そして、次の例のように、これら3つの要素に対するスタイルが与えられます。
102 |
103 | {code2}
104 |
105 | これまで通り、ツリーの末端にある.grid-item
106 | 要素が占めるグリッドセルを解答してください。解答用のグリッドに表示されている座標は親グリッド(
107 | .grid-container
)のものである点に注意してください。
108 |
109 | 例(上記の例に対する解答):
110 | {sample}
111 | >
112 | ),
113 | });
114 |
115 | return {contents};
116 | };
117 |
118 | function useSampleGrid() {
119 | const gridDef = {
120 | columns: 3,
121 | rows: 3,
122 | };
123 | const { selectedItems, toggleItem } = useGridItemSelection([], ["2,1"]);
124 |
125 | return {
126 | gridDef,
127 | selectedItems,
128 | toggleItem,
129 | };
130 | }
131 |
--------------------------------------------------------------------------------
/src/utils/arrayShallowEqual.ts:
--------------------------------------------------------------------------------
1 | export function arrayShallowEqual(
2 | a: readonly unknown[],
3 | b: readonly unknown[]
4 | ) {
5 | return a.length === b.length && a.every((v, i) => v === b[i]);
6 | }
7 |
--------------------------------------------------------------------------------
/src/utils/hooks/useStateReset.ts:
--------------------------------------------------------------------------------
1 | import { useMemo, useState } from "react";
2 | import { arrayShallowEqual } from "../arrayShallowEqual";
3 |
4 | /**
5 | * useState, but reset when given deps has changed.
6 | */
7 | export function useStateReset(
8 | deps: readonly unknown[],
9 | initialValue: () => T
10 | ): [state: T, update: (updater: T | ((current: T) => T)) => void] {
11 | type InternalState = {
12 | deps: readonly unknown[];
13 | value: T;
14 | };
15 | const [state, setStateInternal] = useState(() => ({
16 | deps,
17 | value: initialValue(),
18 | }));
19 |
20 | const setState = (value: T | ((current: T) => T)) => {
21 | setStateInternal((current) => {
22 | if (typeof value !== "function") {
23 | return {
24 | deps,
25 | value,
26 | };
27 | }
28 | const currentState = arrayShallowEqual(current.deps, deps)
29 | ? current.value
30 | : initialValue();
31 | return {
32 | deps,
33 | value: (value as (current: T) => T)(currentState),
34 | };
35 | });
36 | };
37 |
38 | const currentState = useMemo(() => {
39 | if (arrayShallowEqual(deps, state.deps)) {
40 | return state.value;
41 | } else {
42 | return initialValue();
43 | }
44 | }, [state, deps]);
45 |
46 | return [currentState, setState];
47 | }
48 |
--------------------------------------------------------------------------------
/src/utils/i18n/DefineLanguageRoute.tsx:
--------------------------------------------------------------------------------
1 | import { Outlet, useSearch } from "react-location";
2 | import { defaultLanguage, isLanguage } from "./language";
3 | import { LanguageProvider } from "./LanguageContext";
4 |
5 | export const DefineLanguageRoute: React.VFC = () => {
6 | const { lang: rawLang } = useSearch<{
7 | Search: {
8 | lang: string;
9 | };
10 | }>();
11 | const lang = isLanguage(rawLang) ? rawLang : defaultLanguage;
12 |
13 | return (
14 |
15 |
16 |
17 | );
18 | };
19 |
--------------------------------------------------------------------------------
/src/utils/i18n/LanguageContext.tsx:
--------------------------------------------------------------------------------
1 | import { createContext, useContext } from "react";
2 | import { defaultLanguage, Language } from "./language";
3 |
4 | const LanguageContext = createContext(defaultLanguage);
5 |
6 | export const LanguageProvider = LanguageContext.Provider;
7 |
8 | export function useI18n(values: {
9 | [K in Language]: T;
10 | }): T {
11 | const language = useContext(LanguageContext);
12 | return values[language];
13 | }
14 |
--------------------------------------------------------------------------------
/src/utils/i18n/language.ts:
--------------------------------------------------------------------------------
1 | const languages = ["en", "ja"] as const;
2 |
3 | export type Language = typeof languages[number];
4 |
5 | export const defaultLanguage: Language = "en";
6 |
7 | export function isLanguage(l: unknown): l is Language {
8 | return (languages as readonly unknown[]).includes(l);
9 | }
10 |
--------------------------------------------------------------------------------
/src/utils/indent.ts:
--------------------------------------------------------------------------------
1 | export function indent(str: string, space = " ") {
2 | return str.replace(/^(?!$)/gm, space);
3 | }
4 |
--------------------------------------------------------------------------------
/src/utils/range.ts:
--------------------------------------------------------------------------------
1 | export function* range(start: number, end: number) {
2 | for (let i = start; i < end; i++) {
3 | yield i;
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/src/utils/simpleParseCss.ts:
--------------------------------------------------------------------------------
1 | export function simpleParseCss(css: string): Record {
2 | const matches = css.matchAll(/([\w-]+)\s*:\s*([^;]+);/g);
3 | return Object.fromEntries(
4 | Array.from(matches).map(([, key, value]) => [
5 | key.replace(/-[a-z]/g, (match) => match[1].toUpperCase()),
6 | value,
7 | ])
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
6 | "allowJs": false,
7 | "skipLibCheck": false,
8 | "esModuleInterop": false,
9 | "allowSyntheticDefaultImports": true,
10 | "strict": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "module": "ESNext",
13 | "moduleResolution": "Node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx"
18 | },
19 | "include": ["./src"]
20 | }
21 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()]
7 | })
8 |
--------------------------------------------------------------------------------