@gpichot/spectacle-deck 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-dev.log +4 -0
  3. package/{index.cjs → dist/index.cjs} +5 -4
  4. package/{index.mjs → dist/index.mjs} +5 -4
  5. package/package.json +21 -16
  6. package/publish.sh +7 -0
  7. package/scripts/bundle.ts +84 -0
  8. package/src/SlideWrapper.tsx +25 -0
  9. package/src/colors.ts +42 -0
  10. package/src/components/CodeStepper/CodeStepper.tsx +228 -0
  11. package/src/components/CodeStepper/code-directives.test.ts +58 -0
  12. package/src/components/CodeStepper/code-directives.ts +129 -0
  13. package/src/components/DocumentationItem.tsx +85 -0
  14. package/src/components/FilePane.tsx +18 -0
  15. package/src/components/HorizontalList.tsx +141 -0
  16. package/src/components/IconBox.tsx +31 -0
  17. package/src/components/Image.tsx +39 -0
  18. package/src/components/ItemsColumn.tsx +60 -0
  19. package/src/components/QRCode.tsx +55 -0
  20. package/src/components/Timeline.styled.tsx +24 -0
  21. package/src/components/Timeline.tsx +159 -0
  22. package/src/components/map.tsx +128 -0
  23. package/src/components/styled.tsx +73 -0
  24. package/src/context.tsx +33 -0
  25. package/src/front.png +0 -0
  26. package/src/index.tsx +127 -0
  27. package/src/layouts/BaseLayout.tsx +52 -0
  28. package/src/layouts/CenteredLayout.tsx +40 -0
  29. package/src/layouts/Default3Layout.tsx +159 -0
  30. package/src/layouts/MainSectionLayout.tsx +31 -0
  31. package/src/layouts/QuoteLayout.tsx +107 -0
  32. package/src/layouts/SectionLayout.tsx +14 -0
  33. package/src/layouts/SideCodeLayout.tsx +44 -0
  34. package/src/layouts/SideImageLayout.tsx +82 -0
  35. package/src/layouts/SideLayout.tsx +31 -0
  36. package/src/layouts/columns.tsx +56 -0
  37. package/src/layouts/index.tsx +19 -0
  38. package/src/layouts/styled.ts +7 -0
  39. package/src/layouts/utils.ts +66 -0
  40. package/src/node.d.ts +5 -0
  41. package/src/style.d.ts +10 -0
  42. package/src/template.tsx +25 -0
  43. package/src/theme.ts +28 -0
  44. package/tsconfig.json +29 -0
  45. /package/{SlideWrapper.d.ts → dist/SlideWrapper.d.ts} +0 -0
  46. /package/{colors.d.ts → dist/colors.d.ts} +0 -0
  47. /package/{components → dist/components}/CodeStepper/CodeStepper.d.ts +0 -0
  48. /package/{components → dist/components}/CodeStepper/code-directives.d.ts +0 -0
  49. /package/{components → dist/components}/DocumentationItem.d.ts +0 -0
  50. /package/{components → dist/components}/FilePane.d.ts +0 -0
  51. /package/{components → dist/components}/HorizontalList.d.ts +0 -0
  52. /package/{components → dist/components}/IconBox.d.ts +0 -0
  53. /package/{components → dist/components}/Image.d.ts +0 -0
  54. /package/{components → dist/components}/ItemsColumn.d.ts +0 -0
  55. /package/{components → dist/components}/QRCode.d.ts +0 -0
  56. /package/{components → dist/components}/Timeline.d.ts +0 -0
  57. /package/{components → dist/components}/Timeline.styled.d.ts +0 -0
  58. /package/{components → dist/components}/map.d.ts +0 -0
  59. /package/{components → dist/components}/styled.d.ts +0 -0
  60. /package/{context.d.ts → dist/context.d.ts} +0 -0
  61. /package/{index.d.ts → dist/index.d.ts} +0 -0
  62. /package/{layouts → dist/layouts}/BaseLayout.d.ts +0 -0
  63. /package/{layouts → dist/layouts}/CenteredLayout.d.ts +0 -0
  64. /package/{layouts → dist/layouts}/Default3Layout.d.ts +0 -0
  65. /package/{layouts → dist/layouts}/MainSectionLayout.d.ts +0 -0
  66. /package/{layouts → dist/layouts}/QuoteLayout.d.ts +0 -0
  67. /package/{layouts → dist/layouts}/SectionLayout.d.ts +0 -0
  68. /package/{layouts → dist/layouts}/SideCodeLayout.d.ts +0 -0
  69. /package/{layouts → dist/layouts}/SideImageLayout.d.ts +0 -0
  70. /package/{layouts → dist/layouts}/SideLayout.d.ts +0 -0
  71. /package/{layouts → dist/layouts}/columns.d.ts +0 -0
  72. /package/{layouts → dist/layouts}/index.d.ts +0 -0
  73. /package/{layouts → dist/layouts}/styled.d.ts +0 -0
  74. /package/{layouts → dist/layouts}/utils.d.ts +0 -0
  75. /package/{template.d.ts → dist/template.d.ts} +0 -0
  76. /package/{theme.d.ts → dist/theme.d.ts} +0 -0
@@ -0,0 +1,4 @@
1
+
2
+ > @gpichot/spectacle-deck@1.1.7 build /Users/gabriel/Dev/CraftValue/Formations/presentations-next/packages/spectacle-deck
3
+ > tnode scripts/bundle.ts
4
+
@@ -0,0 +1,4 @@
1
+
2
+ > @gpichot/spectacle-deck@1.1.7 dev /Users/gabriel/Dev/CraftValue/Formations/presentations-next/packages/spectacle-deck
3
+ > tnode scripts/bundle.ts
4
+
@@ -515,7 +515,7 @@ var DivWithHeading = import_styled_components5.default.div`
515
515
  margin-top: 0;
516
516
  }
517
517
  h2 strong {
518
- color: #f49676;
518
+ color: var(--color-secondary);
519
519
  font-weight: 400;
520
520
  }
521
521
  `;
@@ -657,7 +657,7 @@ var DivWithHeading2 = import_styled_components8.default.div`
657
657
  margin-top: 0;
658
658
  }
659
659
  h2 strong {
660
- color: #f49676;
660
+ color: var(--color-secondary);
661
661
  font-weight: 400;
662
662
  }
663
663
  `;
@@ -1431,8 +1431,8 @@ var DocContainer = import_styled_components12.default.div`
1431
1431
  var DocLink = import_styled_components12.default.a`
1432
1432
  text-decoration: none;
1433
1433
  font-weight: normal;
1434
- font-family: Bitter, "Helvetica Neue", Helvetica, Arial, sans-serif;
1435
- color: #f49676;
1434
+ font-family: var(--font-family);
1435
+ color: var(--color-secondary);
1436
1436
  `;
1437
1437
  var DocLinkItem = (0, import_styled_components12.default)(DocLink)`
1438
1438
  width: fit-content;
@@ -1791,6 +1791,7 @@ function Deck({
1791
1791
  return import_styled_components17.createGlobalStyle`
1792
1792
  :root {
1793
1793
  ${cssVariables}
1794
+ --font-family: ${theme_default.fonts.text}
1794
1795
  }
1795
1796
  `;
1796
1797
  }, [theme]);
@@ -464,7 +464,7 @@ var DivWithHeading = styled5.div`
464
464
  margin-top: 0;
465
465
  }
466
466
  h2 strong {
467
- color: #f49676;
467
+ color: var(--color-secondary);
468
468
  font-weight: 400;
469
469
  }
470
470
  `;
@@ -606,7 +606,7 @@ var DivWithHeading2 = styled8.div`
606
606
  margin-top: 0;
607
607
  }
608
608
  h2 strong {
609
- color: #f49676;
609
+ color: var(--color-secondary);
610
610
  font-weight: 400;
611
611
  }
612
612
  `;
@@ -1384,8 +1384,8 @@ var DocContainer = styled12.div`
1384
1384
  var DocLink = styled12.a`
1385
1385
  text-decoration: none;
1386
1386
  font-weight: normal;
1387
- font-family: Bitter, "Helvetica Neue", Helvetica, Arial, sans-serif;
1388
- color: #f49676;
1387
+ font-family: var(--font-family);
1388
+ color: var(--color-secondary);
1389
1389
  `;
1390
1390
  var DocLinkItem = styled12(DocLink)`
1391
1391
  width: fit-content;
@@ -1744,6 +1744,7 @@ function Deck({
1744
1744
  return createGlobalStyle`
1745
1745
  :root {
1746
1746
  ${cssVariables}
1747
+ --font-family: ${theme_default.fonts.text}
1747
1748
  }
1748
1749
  `;
1749
1750
  }, [theme]);
package/package.json CHANGED
@@ -1,21 +1,12 @@
1
1
  {
2
2
  "name": "@gpichot/spectacle-deck",
3
- "version": "1.2.0",
4
- "license": "MIT",
5
- "type": "module",
6
- "main": "index.cjs",
7
- "types": "index.d.ts",
8
- "module": "index.mjs",
9
- "exports": {
10
- ".": {
11
- "types": "./index.d.ts",
12
- "require": "./index.cjs",
13
- "import": "./index.mjs"
14
- }
15
- },
16
- "keywords": [
17
- "spectacle"
18
- ],
3
+ "version": "1.2.1",
4
+ "description": "",
5
+ "module": "src/index.tsx",
6
+ "types": "src/index.d.ts",
7
+ "keywords": [],
8
+ "author": "",
9
+ "license": "ISC",
19
10
  "dependencies": {
20
11
  "@fontsource/bitter": "^5.0.18",
21
12
  "@mdx-js/react": "^3.0.1",
@@ -27,5 +18,19 @@
27
18
  "react-syntax-highlighter": "^15.5.0",
28
19
  "spectacle": "^10.1.8",
29
20
  "styled-components": "^6.1.11"
21
+ },
22
+ "devDependencies": {
23
+ "@arnaud-barre/tnode": "^0.19.2",
24
+ "@types/react": "^18.3.2",
25
+ "@types/react-dom": "^18.3.0",
26
+ "@types/react-is": "^18.3.0",
27
+ "@types/react-syntax-highlighter": "^15.5.13",
28
+ "esbuild": "^0.21.3",
29
+ "typescript": "^5.4.5"
30
+ },
31
+ "scripts": {
32
+ "test": "echo \"Error: no test specified\" && exit 1",
33
+ "dev": "tnode scripts/bundle.ts",
34
+ "build": "tnode scripts/bundle.ts"
30
35
  }
31
36
  }
package/publish.sh ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ pnpm run build
4
+
5
+ cd dist
6
+
7
+ pnpm publish --no-git-checks
@@ -0,0 +1,84 @@
1
+ import { rmSync, writeFileSync, copyFileSync } from "node:fs";
2
+ import { execSync } from "node:child_process";
3
+ import { build, BuildOptions, context } from "esbuild";
4
+
5
+ import packageJSON from "../package.json";
6
+
7
+ const dev = process.argv.includes("--dev");
8
+
9
+ rmSync("dist", { force: true, recursive: true });
10
+
11
+ const serverOptions: BuildOptions = {
12
+ bundle: true,
13
+ platform: "node",
14
+ target: "node14",
15
+ legalComments: "inline",
16
+ loader: {
17
+ ".png": "dataurl",
18
+ },
19
+ external: Object.keys(packageJSON.peerDependencies || {}).concat(
20
+ Object.keys(packageJSON.dependencies || {}),
21
+ ),
22
+ };
23
+
24
+ const buildOrWatch = async (options: BuildOptions) => {
25
+ if (!dev) return build(options);
26
+ const ctx = await context(options);
27
+ await ctx.watch();
28
+ await ctx.rebuild();
29
+ };
30
+
31
+ Promise.all([
32
+ buildOrWatch({
33
+ ...serverOptions,
34
+ stdin: {
35
+ contents: `import * as mod from "./src";
36
+ module.exports = mod;
37
+ `,
38
+ resolveDir: ".",
39
+ },
40
+ outfile: "dist/index.cjs",
41
+ logOverride: { "empty-import-meta": "silent" },
42
+ }),
43
+ buildOrWatch({
44
+ ...serverOptions,
45
+ entryPoints: ["src/index.tsx"],
46
+ format: "esm",
47
+ outfile: "dist/index.mjs",
48
+ }),
49
+ ]).then(() => {
50
+ // copyFileSync("LICENSE", "dist/LICENSE");
51
+ // copyFileSync("README.md", "dist/README.md");
52
+
53
+ execSync(
54
+ "tsc src/index.tsx --declaration --jsx react --emitDeclarationOnly --outDir dist --module preserve --target es2020 --allowSyntheticDefaultImports --skipLibCheck --moduleResolution bundler --types ./src/node.d.ts,./src/style.d.ts",
55
+ { stdio: "inherit" },
56
+ );
57
+
58
+ writeFileSync(
59
+ "dist/package.json",
60
+ JSON.stringify(
61
+ {
62
+ name: "@gpichot/spectacle-deck",
63
+ version: packageJSON.version,
64
+ license: "MIT",
65
+ type: "module",
66
+ main: "index.cjs",
67
+ types: "index.d.ts",
68
+ module: "index.mjs",
69
+ exports: {
70
+ ".": {
71
+ types: "./index.d.ts",
72
+ require: "./index.cjs",
73
+ import: "./index.mjs",
74
+ },
75
+ },
76
+ keywords: ["spectacle"],
77
+ peerDependencies: packageJSON.peerDependencies,
78
+ dependencies: packageJSON.dependencies,
79
+ },
80
+ null,
81
+ 2,
82
+ ),
83
+ );
84
+ });
@@ -0,0 +1,25 @@
1
+ import React from "react";
2
+ import { usePestacle } from "./context";
3
+
4
+ export function SlideWrapper({
5
+ children,
6
+ frontmatter,
7
+ }: {
8
+ children: React.ReactNode;
9
+ frontmatter: { layout?: string };
10
+ }) {
11
+ const { layouts } = usePestacle();
12
+ const layout = frontmatter?.layout || "default";
13
+ console.log(layouts, layout);
14
+ const Layout = layout in layouts ? layouts[layout] : null;
15
+
16
+ if (layout && !Layout) {
17
+ console.warn(`Layout ${layout} not found`);
18
+ }
19
+
20
+ if (Layout) {
21
+ return <Layout {...frontmatter}>{children}</Layout>;
22
+ }
23
+
24
+ return <>{children}</>;
25
+ }
package/src/colors.ts ADDED
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Extract colors from `rgb(...) or rgba(...)` string or #hex string
3
+ */
4
+ export function extractColors(color: string): {
5
+ r: number;
6
+ g: number;
7
+ b: number;
8
+ } {
9
+ if (color.startsWith("rgb")) {
10
+ const [r, g, b] = color
11
+ .replace("rgb(", "")
12
+ .replace("rgba(", "")
13
+ .replace(")", "")
14
+ .split(",")
15
+ .map((c) => parseInt(c.trim(), 10));
16
+ return { r, g, b };
17
+ } else if (color.startsWith("#")) {
18
+ const hex = color.replace("#", "");
19
+ const r = parseInt(hex.substring(0, 2), 16);
20
+ const g = parseInt(hex.substring(2, 4), 16);
21
+ const b = parseInt(hex.substring(4, 6), 16);
22
+ return { r, g, b };
23
+ }
24
+ throw new Error(`Invalid color format: ${color}`);
25
+ }
26
+
27
+ /**
28
+ * Create vars for css colors
29
+ */
30
+ export function createCssVariables(colors: { [key: string]: string }) {
31
+ const base = Object.entries(colors)
32
+ .map(([key, value]) => `--color-${key}: ${value};`)
33
+ .join("\n");
34
+ const rgbs = Object.entries(colors)
35
+ .map(([key, value]) => {
36
+ const { r, g, b } = extractColors(value);
37
+ return `--color-${key}-rgb: ${r}, ${g}, ${b};`;
38
+ })
39
+ .join("\n");
40
+
41
+ return `${base}\n${rgbs}`;
42
+ }
@@ -0,0 +1,228 @@
1
+ import React from "react";
2
+ import ReactIs from "react-is";
3
+ import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
4
+ import { gruvboxDark } from "react-syntax-highlighter/dist/esm/styles/prism";
5
+ import { Stepper } from "spectacle";
6
+ import styled from "styled-components";
7
+
8
+ import { parseStepDirectives, Step } from "./code-directives";
9
+
10
+ const Highlighter = SyntaxHighlighter as unknown as React.ElementType;
11
+
12
+ const CodeContainer = styled.div`
13
+ pre {
14
+ padding: 1rem 0rem !important;
15
+ background-color: transparent !important;
16
+ }
17
+ .linenumber {
18
+ min-width: 2rem !important;
19
+ }
20
+ [data-highlight-line="true"] {
21
+ &:before {
22
+ content: " ";
23
+ position: absolute;
24
+ background-color: rgba(var(--color-primary-rgb), 0.5);
25
+ }
26
+
27
+ &[data-step-active="true"]:before {
28
+ background-color: var(--color-secondary);
29
+ }
30
+ }
31
+ `;
32
+
33
+ function useCodeSteps(code: string) {
34
+ return React.useMemo(() => {
35
+ const prefixes = code.match(/(?:\/\/|<!--) @.*\n/g) || ([] as string[]);
36
+ const prefixesLength = prefixes.reduce(
37
+ (acc, prefix) => acc + prefix.length,
38
+ 0,
39
+ );
40
+
41
+ const codeWithoutPrefixes = code.slice(prefixesLength);
42
+
43
+ const hasDirectives = prefixes.length > 0;
44
+ const allDirectives = hasDirectives ? [...prefixes] : [];
45
+ const steps = parseStepDirectives(allDirectives);
46
+
47
+ return {
48
+ steps,
49
+ code: codeWithoutPrefixes,
50
+ prefixes,
51
+ hasSteps: Boolean(steps.length),
52
+ hasName: steps.some((step) => step.name),
53
+ };
54
+ }, [code]);
55
+ }
56
+
57
+ function getCodeDetails(children: React.ReactNode) {
58
+ const child = React.Children.toArray(children)[0];
59
+
60
+ if (!React.isValidElement(child)) {
61
+ return {
62
+ language: "",
63
+ code: ReactIs.isFragment(child) ? "" : String(child || ""),
64
+ };
65
+ }
66
+
67
+ const result = {
68
+ language: (String(child.props.className) || "").replace("language-", ""),
69
+ code: (child.props.children as string).trim(),
70
+ };
71
+
72
+ return result;
73
+ }
74
+
75
+ function CodeWrapper({
76
+ name,
77
+ stepName,
78
+ hasName,
79
+ children,
80
+ }: {
81
+ name?: string;
82
+ stepName?: string;
83
+ hasName?: boolean;
84
+ children: React.ReactNode;
85
+ }) {
86
+ return (
87
+ <div
88
+ style={{
89
+ boxSizing: "border-box",
90
+ margin: "0.5rem 1rem",
91
+ backgroundColor: "rgb(38,39,40)",
92
+ borderRadius: "4px",
93
+ }}
94
+ >
95
+ {name && (
96
+ <span
97
+ style={{
98
+ fontFamily: 'Consolas, Monaco, "Andale Mono", monospace',
99
+ fontSize: "1rem",
100
+ color: "#ffffffbb",
101
+ backgroundColor: "#33333388",
102
+ display: "inline-block",
103
+ padding: "8px 8px",
104
+ width: "100%",
105
+ boxSizing: "border-box",
106
+ }}
107
+ >
108
+ {name}
109
+ </span>
110
+ )}
111
+ {children}
112
+ {hasName && (
113
+ <span
114
+ style={{
115
+ fontFamily: 'Consolas, Monaco, "Andale Mono", monospace',
116
+ fontSize: "0.8rem",
117
+ color: "#ffffffaa",
118
+ backgroundColor: "#33333388",
119
+ display: "inline-block",
120
+ padding: "4px 8px",
121
+ width: "100%",
122
+ boxSizing: "border-box",
123
+ fontStyle: "italic",
124
+ }}
125
+ >
126
+ {stepName || <span style={{ visibility: "hidden" }}>Step</span>}
127
+ </span>
128
+ )}
129
+ </div>
130
+ );
131
+ }
132
+
133
+ export default function CodeStepper({
134
+ priority,
135
+ name,
136
+ ...props
137
+ }: React.ComponentProps<"pre"> & {
138
+ priority?: number;
139
+ name?: string;
140
+ }) {
141
+ const { language, code } = React.useMemo(() => {
142
+ return getCodeDetails(props.children);
143
+ }, [props.children]);
144
+
145
+ const {
146
+ steps,
147
+ code: codeNormalized,
148
+ prefixes,
149
+ hasSteps,
150
+ hasName,
151
+ } = useCodeSteps(code);
152
+ return (
153
+ <CodeContainer>
154
+ {import.meta.env.DEV && false && Boolean(prefixes?.length) && (
155
+ <div style={{ position: "absolute", top: 0, opacity: 0.5, left: 0 }}>
156
+ <Highlighter language={language} style={gruvboxDark}>
157
+ {prefixes.join("")}
158
+ </Highlighter>
159
+ </div>
160
+ )}
161
+ <Stepper
162
+ values={steps}
163
+ alwaysVisible={!hasSteps}
164
+ priority={priority ? priority + 1 : undefined}
165
+ >
166
+ {(step, _, isActive) => {
167
+ console.log({ step, isActive });
168
+ return (
169
+ <CodeWrapper
170
+ name={name}
171
+ stepName={(step as Step | null)?.name}
172
+ hasName={hasName}
173
+ >
174
+ <Highlighter
175
+ language={language}
176
+ wrapLines
177
+ showLineNumbers
178
+ style={gruvboxDark}
179
+ lineNumberStyle={(lineNumber: number) => {
180
+ const { highlight = [] } = (step as Step) || {};
181
+ const isHighlighted = highlight.includes(lineNumber);
182
+
183
+ return {
184
+ fontWeight: isHighlighted ? "bold" : "normal",
185
+ };
186
+ }}
187
+ lineProps={(lineNumber: number) => {
188
+ const { hiddenLines = [], highlight = [] } =
189
+ (step as Step) || {};
190
+ const isVisible =
191
+ hasSteps && isActive
192
+ ? !hiddenLines.includes(lineNumber)
193
+ : isActive || !hasSteps;
194
+ const isHighlighted = highlight.includes(lineNumber);
195
+ const getOpacity = () => {
196
+ if (!isVisible) return 0;
197
+ if (isHighlighted || !highlight.length) return 1;
198
+ return 0.8;
199
+ };
200
+
201
+ return {
202
+ ...(isHighlighted && {
203
+ "data-highlight-line": isHighlighted,
204
+ "data-step-active": isActive,
205
+ }),
206
+ style: {
207
+ opacity: getOpacity(),
208
+ transition: "all 0.3s ease",
209
+ display: "block",
210
+ width: "100%",
211
+ backgroundColor: isHighlighted
212
+ ? "rgba(var(--color-secondary-rgb), 0.13)"
213
+ : "",
214
+ },
215
+ };
216
+ }}
217
+ >
218
+ {codeNormalized}
219
+ </Highlighter>
220
+ </CodeWrapper>
221
+ );
222
+ }}
223
+ </Stepper>
224
+ </CodeContainer>
225
+ );
226
+ }
227
+
228
+ CodeStepper.mdxType = "CodeStepper";
@@ -0,0 +1,58 @@
1
+ import { parseStepDirectives } from './code-directives';
2
+
3
+ function splitDirectives(str: string): string[] {
4
+ return str.trim().split('\n');
5
+ }
6
+
7
+ describe('parseStepDirectives', () => {
8
+ it('should reduce properly with showLines', () => {
9
+ const directives = splitDirectives(`
10
+ // @step showLines(1-3) highlight(1-3)
11
+ // @step showLines(4-6) highlight(4-6)
12
+ `);
13
+
14
+ const result = parseStepDirectives(directives);
15
+ expect(result[0]).toEqual({ hiddenLines: [4, 5, 6], highlight: [1, 2, 3] });
16
+ expect(result[1]).toEqual({ hiddenLines: [], highlight: [4, 5, 6] });
17
+ });
18
+
19
+ it('should reduce properly with highlight', () => {
20
+ const directives = splitDirectives(`
21
+ // @step highlight(3)
22
+ // @step showLines(4) highlight(4)
23
+ `);
24
+
25
+ const result = parseStepDirectives(directives);
26
+ expect(result).toHaveLength(2);
27
+ expect(result[0]).toEqual({ hiddenLines: [4], highlight: [3] });
28
+ expect(result[1]).toEqual({ hiddenLines: [], highlight: [4] });
29
+ });
30
+
31
+ it('parse only highlights', () => {
32
+ const directives = splitDirectives(`
33
+ // @step highlight(6)
34
+ // @step highlight(7-9)
35
+ // @step highlight(10)
36
+ `);
37
+
38
+ const result = parseStepDirectives(directives);
39
+ expect(result).toHaveLength(3);
40
+ expect(result[0]).toEqual({ hiddenLines: [], highlight: [6] });
41
+ expect(result[1]).toEqual({ hiddenLines: [], highlight: [7, 8, 9] });
42
+ expect(result[2]).toEqual({ hiddenLines: [], highlight: [10] });
43
+ });
44
+
45
+ it('parses typescript lines', () => {
46
+ const directives = splitDirectives(`
47
+ // @step highlight(3) name("(string|number)[]")
48
+ `);
49
+
50
+ const result = parseStepDirectives(directives);
51
+ expect(result).toHaveLength(1);
52
+ expect(result[0]).toEqual({
53
+ hiddenLines: [],
54
+ highlight: [3],
55
+ name: '(string|number)[]',
56
+ });
57
+ });
58
+ });