handoff-app 1.2.1 → 1.2.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.
package/Changelog.md CHANGED
@@ -6,6 +6,33 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to
7
7
  [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
 
9
+ ## \[1.2.2] - 2026-04-09
10
+
11
+ This patch release clears ESLint failures in the Next.js app pages and aligns
12
+ several code paths with the compiler target so production builds succeed without
13
+ enabling `--downlevelIteration`.
14
+
15
+ ### Lint and code quality
16
+
17
+ * Resolved `no-else-return`, `no-unused-vars`, `camelcase`, `prefer-const`,
18
+ `eqeqeq`, `no-nested-ternary`, `no-lonely-if`, and `no-use-before-define`
19
+ across static pages (catch-all docs, assets, foundations, home, system, and
20
+ design-token foundation pages).
21
+ * Removed or refactored unused `getStaticProps` context parameters, props, and
22
+ locals; normalized naming (e.g. font machine keys); simplified icon detail
23
+ routing query handling.
24
+ * Reordered helper components (token color/effect/typography tables, component
25
+ token previews) ahead of page components where required for declaration order.
26
+ * Converted `getComponentPreviews` to a hoisted `function` declaration and
27
+ refactored the component token table for clearer control flow.
28
+
29
+ ### Build / TypeScript compatibility
30
+
31
+ * Avoid iterating `Map` / `Set` / `Iterable` / `matchAll` results directly in
32
+ `for...of` where the compile target requires it: use `Array.from(...)` or
33
+ equivalent helpers in the config-diff registry, snapshot diff, CSF import
34
+ parsing, and component artifact sync.
35
+
9
36
  ## \[1.2.1] - 2026-04-08
10
37
 
11
38
  This is a minor release that fixes a bug in the new config diff calculator.
package/dist/cli.js CHANGED
@@ -19,7 +19,7 @@ class HandoffCliError extends Error {
19
19
  * Show the help message
20
20
  */
21
21
  const showVersion = () => {
22
- return 'Handoff App - 1.2.1';
22
+ return 'Handoff App - 1.2.2';
23
23
  };
24
24
  /**
25
25
  * Define a CLI error
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "handoff-app",
3
- "version": "1.2.1",
3
+ "version": "1.2.2-1",
4
4
  "description": "Automated documentation toolchain for building client side documentation from figma",
5
5
  "author ": {
6
6
  "name": "Convertiv",
@@ -41,26 +41,7 @@ export const getStaticProps: GetStaticProps = (context) => {
41
41
  export default function DocCatchAllPage({ content, menu, metadata, current, config }: DocumentationProps) {
42
42
  const bodyRef = useRef<HTMLDivElement>(null);
43
43
 
44
- if (content) {
45
- return (
46
- <Layout config={config} menu={menu} current={current} metadata={metadata}>
47
- <div className="flex flex-col gap-2 pb-7">
48
- <HeadersType.H1>{metadata.title}</HeadersType.H1>
49
- <p className="text-lg leading-relaxed text-gray-600 dark:text-gray-300">{metadata.description}</p>
50
- </div>
51
- <div className="lg:gap-10 lg:py-8 xl:grid xl:grid-cols-[1fr_280px]">
52
- <div className="min-w-0">
53
- <div className="prose mb-10" ref={bodyRef}>
54
- <ReactMarkdown components={MarkdownComponents} remarkPlugins={[remarkGfm, remarkCodeMeta]} rehypePlugins={[rehypeRaw]}>
55
- {content}
56
- </ReactMarkdown>
57
- </div>
58
- </div>
59
- <PageTOC body={bodyRef} title="On This Page" />
60
- </div>
61
- </Layout>
62
- );
63
- } else {
44
+ if (!content) {
64
45
  return (
65
46
  <div className="flex min-h-screen flex-col items-center justify-center bg-white dark:bg-gray-900">
66
47
  <Head>
@@ -85,4 +66,23 @@ export default function DocCatchAllPage({ content, menu, metadata, current, conf
85
66
  </div>
86
67
  );
87
68
  }
69
+
70
+ return (
71
+ <Layout config={config} menu={menu} current={current} metadata={metadata}>
72
+ <div className="flex flex-col gap-2 pb-7">
73
+ <HeadersType.H1>{metadata.title}</HeadersType.H1>
74
+ <p className="text-lg leading-relaxed text-gray-600 dark:text-gray-300">{metadata.description}</p>
75
+ </div>
76
+ <div className="lg:gap-10 lg:py-8 xl:grid xl:grid-cols-[1fr_280px]">
77
+ <div className="min-w-0">
78
+ <div className="prose mb-10" ref={bodyRef}>
79
+ <ReactMarkdown components={MarkdownComponents} remarkPlugins={[remarkGfm, remarkCodeMeta]} rehypePlugins={[rehypeRaw]}>
80
+ {content}
81
+ </ReactMarkdown>
82
+ </div>
83
+ </div>
84
+ <PageTOC body={bodyRef} title="On This Page" />
85
+ </div>
86
+ </Layout>
87
+ );
88
88
  }
@@ -21,7 +21,7 @@ import { fetchDocPageMarkdown, FontDocumentationProps, getClientRuntimeConfig, g
21
21
  * @param context GetStaticProps
22
22
  * @returns
23
23
  */
24
- export const getStaticProps: GetStaticProps = async (context) => {
24
+ export const getStaticProps: GetStaticProps = async () => {
25
25
  const fonts = fs.readdirSync(
26
26
  path.resolve(process.env.HANDOFF_MODULE_PATH ?? '', '.handoff', `${process.env.HANDOFF_PROJECT_ID}`, 'public', 'fonts')
27
27
  );
@@ -45,16 +45,15 @@ export const getStaticProps: GetStaticProps = async (context) => {
45
45
  };
46
46
  };
47
47
 
48
- const FontsPage = ({ content, menu, metadata, current, customFonts, design, config }: FontDocumentationProps) => {
48
+ const FontsPage = ({ content, menu, metadata, customFonts, design, config }: FontDocumentationProps) => {
49
49
  const fontFamilies: string[] = uniq(design.typography.map((type) => type.values.fontFamily));
50
50
  const fontLinks: string[] = fontFamilies.map((fontFamily) => {
51
- const machine_name = fontFamily.replace(/\s/g, '');
52
- const custom = customFonts.find((font) => font === machine_name);
51
+ const machineName = fontFamily.replace(/\s/g, '');
52
+ const custom = customFonts.find((font) => font === machineName);
53
53
  if (custom) {
54
- return `/fonts/${machine_name}.zip`;
55
- } else {
56
- return `https://fonts.google.com/specimen/${fontFamily}`;
54
+ return `/fonts/${machineName}.zip`;
57
55
  }
56
+ return `https://fonts.google.com/specimen/${fontFamily}`;
58
57
  });
59
58
  return (
60
59
  <div className="c-page">
@@ -18,7 +18,7 @@ import { DocumentationProps, fetchDocPageMarkdown, getClientRuntimeConfig } from
18
18
  * @param context GetStaticProps
19
19
  * @returns
20
20
  */
21
- export const getStaticProps: GetStaticProps = async (context) => {
21
+ export const getStaticProps: GetStaticProps = async () => {
22
22
  return {
23
23
  props: {
24
24
  ...fetchDocPageMarkdown('docs/', 'assets', `/assets`).props,
@@ -27,7 +27,7 @@ export const getStaticProps: GetStaticProps = async (context) => {
27
27
  };
28
28
  };
29
29
 
30
- const AssetsPage = ({ content, menu, metadata, current, config }: DocumentationProps) => {
30
+ const AssetsPage = ({ content, menu, metadata, config }: DocumentationProps) => {
31
31
  return (
32
32
  <div className="c-page">
33
33
  <Head>
@@ -17,7 +17,7 @@ import { DocumentationProps, fetchDocPageMarkdown, getClientRuntimeConfig } from
17
17
  * @param context GetStaticProps
18
18
  * @returns
19
19
  */
20
- export const getStaticProps: GetStaticProps = async (context) => {
20
+ export const getStaticProps: GetStaticProps = async () => {
21
21
  return {
22
22
  props: {
23
23
  ...fetchDocPageMarkdown('docs/assets/', 'logos', `/assets`).props,
@@ -26,7 +26,7 @@ export const getStaticProps: GetStaticProps = async (context) => {
26
26
  };
27
27
  };
28
28
 
29
- const AssetsLogosPage = ({ content, menu, metadata, current, config }: DocumentationProps) => {
29
+ const AssetsLogosPage = ({ content, menu, metadata, config }: DocumentationProps) => {
30
30
  return (
31
31
  <div className="c-page">
32
32
  <Head>
@@ -22,7 +22,7 @@ import { getTokens } from '../../components/util';
22
22
  * @param context GetStaticProps
23
23
  * @returns
24
24
  */
25
- export const getStaticProps: GetStaticProps = async (context) => {
25
+ export const getStaticProps: GetStaticProps = async () => {
26
26
  return {
27
27
  props: {
28
28
  ...util.fetchFoundationDocPageMarkdown('docs/foundations/', 'colors', `/foundations`).props,
@@ -58,7 +58,7 @@ export async function getStaticPaths() {
58
58
  * @param context GetStaticProps
59
59
  * @returns
60
60
  */
61
- export const getStaticProps: GetStaticProps = (context) => {
61
+ export const getStaticProps: GetStaticProps = () => {
62
62
  return {
63
63
  props: {
64
64
  ...fetchDocPageMarkdown('docs/foundations/', 'icons', `/foundations`).props,
@@ -68,10 +68,13 @@ export const getStaticProps: GetStaticProps = (context) => {
68
68
  };
69
69
  };
70
70
 
71
- export default function SingleIcon({ content, menu, metadata, current, config, assets }: AssetDocumentationProps) {
71
+ export default function SingleIcon({ menu, metadata, current, config, assets }: AssetDocumentationProps) {
72
72
  const router = useRouter();
73
- let { name } = router.query;
74
- const icon = assets?.icons.find((icon) => icon.icon === name);
73
+ const nameParam = router.query.name;
74
+ let name = undefined;
75
+ if (typeof nameParam === 'string') { name = nameParam } else if (Array.isArray(nameParam)) { name = nameParam[0] } else { name = undefined }
76
+ const icon = assets?.icons.find((i) => i.icon === name);
77
+
75
78
  const copySvg = React.useCallback<React.MouseEventHandler>(
76
79
  (event) => {
77
80
  event.preventDefault();
@@ -52,7 +52,7 @@ export const DisplayIcon: React.FC<{ icon: CoreTypes.IAssetObject }> = ({ icon }
52
52
  * @param context GetStaticProps
53
53
  * @returns
54
54
  */
55
- export const getStaticProps: GetStaticProps = async (context) => {
55
+ export const getStaticProps: GetStaticProps = async () => {
56
56
  return {
57
57
  props: {
58
58
  ...fetchDocPageMarkdown('docs/foundations/', 'icons', `/foundations`).props,
@@ -17,7 +17,7 @@ import { DocumentationProps, fetchDocPageMarkdown, getClientRuntimeConfig } from
17
17
  * @param context GetStaticProps
18
18
  * @returns
19
19
  */
20
- export const getStaticProps: GetStaticProps = async (context) => {
20
+ export const getStaticProps: GetStaticProps = async () => {
21
21
  return {
22
22
  props: {
23
23
  ...fetchDocPageMarkdown('docs/', 'foundations', `/foundations`).props,
@@ -36,7 +36,7 @@ import { buttonVariants } from '../../components/ui/button';
36
36
  * @param context GetStaticProps
37
37
  * @returns
38
38
  */
39
- export const getStaticProps: GetStaticProps = async (context) => {
39
+ export const getStaticProps: GetStaticProps = async () => {
40
40
  return {
41
41
  props: {
42
42
  ...fetchDocPageMarkdown('docs/foundations/', 'logo', `/foundations`).props,
@@ -62,16 +62,6 @@ const Typography = ({
62
62
  };
63
63
  }, {} as FontFamily);
64
64
 
65
- const type_copy = config?.app?.type_copy ?? 'Almost before we knew it, we had left the ground.';
66
-
67
- const typographyCategories = typography.reduce((acc, type) => {
68
- if (type.name.includes('/')) {
69
- const category = type.name.split('/')[0].trim();
70
- acc.add(category);
71
- }
72
- return acc;
73
- }, new Set<string>());
74
-
75
65
  return (
76
66
  <Layout config={config} menu={menu} metadata={metadata} current={current}>
77
67
  <div className="flex flex-col gap-2 pb-7">
@@ -2,7 +2,6 @@ import { ArrowRight, Component, Hexagon, Layers, Shapes } from 'lucide-react';
2
2
  import { GetStaticProps } from 'next';
3
3
  import Image from 'next/image';
4
4
  import Link from 'next/link';
5
- import { useRouter } from 'next/router';
6
5
  import ReactMarkdown from 'react-markdown';
7
6
  import rehypeRaw from 'rehype-raw';
8
7
  import remarkGfm from 'remark-gfm';
@@ -21,7 +20,7 @@ import { DocumentationProps, fetchDocPageMarkdown, getClientRuntimeConfig } from
21
20
  * @param context GetStaticProps
22
21
  * @returns
23
22
  */
24
- export const getStaticProps: GetStaticProps = async (context) => {
23
+ export const getStaticProps: GetStaticProps = async () => {
25
24
  return {
26
25
  props: {
27
26
  ...fetchDocPageMarkdown('docs/', 'index', `/`).props,
@@ -31,8 +30,6 @@ export const getStaticProps: GetStaticProps = async (context) => {
31
30
  };
32
31
 
33
32
  const Home = ({ content, menu, metadata, config, current }: DocumentationProps) => {
34
- const router = useRouter();
35
-
36
33
  return (
37
34
  <Layout config={config} menu={menu} current={current} metadata={metadata} fullWidthHero={true}>
38
35
  <div className="w-full bg-linear-to-r py-12 dark:from-gray-900 dark:to-gray-800 sm:py-20">
@@ -110,7 +110,7 @@ export const getStaticProps = async (context) => {
110
110
  };
111
111
 
112
112
  function filterPreviews(previews: Record<string, OptionalPreviewRender>, filter: Filter): Record<string, OptionalPreviewRender> {
113
- return Object.fromEntries(Object.entries(previews).filter(([_, preview]) => evaluateFilter(preview.values, filter)));
113
+ return Object.fromEntries(Object.entries(previews).filter(([, preview]) => evaluateFilter(preview.values, filter)));
114
114
  }
115
115
 
116
116
  const GenericComponentPage = ({ menu, metadata, current, id, config, componentHotReloadIsAvailable, previousComponent, nextComponent }) => {
@@ -123,7 +123,7 @@ const GenericComponentPage = ({ menu, metadata, current, id, config, componentHo
123
123
  const componentRoute = (componentId: string) => `${normalizedBasePath}/system/component/${componentId}`;
124
124
 
125
125
  const fetchComponents = async () => {
126
- let data = await fetch(`${normalizedBasePath}/api/component/${id}.json`).then((res) => res.json());
126
+ const data = await fetch(`${normalizedBasePath}/api/component/${id}.json`).then((res) => res.json());
127
127
  setComponent(data as PreviewObject);
128
128
  };
129
129
 
@@ -30,7 +30,7 @@ type ComponentPageDocumentationProps = DocumentationProps;
30
30
  * @param context GetStaticProps
31
31
  * @returns
32
32
  */
33
- export const getStaticProps: GetStaticProps = async (context) => {
33
+ export const getStaticProps: GetStaticProps = async () => {
34
34
  // Read current slug
35
35
  const config = getClientRuntimeConfig();
36
36
  return {
@@ -49,7 +49,7 @@ const ComponentsPage = ({ content, menu, metadata, current, config }: ComponentP
49
49
  // Fetch components from api
50
50
  const [components, setComponents] = useState<PreviewObject[]>(undefined);
51
51
  const fetchComponents = async () => {
52
- let data = await fetch(`${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/components.json`).then((res) => res.json());
52
+ const data = await fetch(`${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/components.json`).then((res) => res.json());
53
53
  setComponents(data as PreviewObject[]);
54
54
  };
55
55
  useEffect(() => {
@@ -67,7 +67,6 @@ const GenericComponentPage = ({
67
67
  menu,
68
68
  metadata,
69
69
  current,
70
- id,
71
70
  config,
72
71
  component,
73
72
  options,
@@ -101,11 +100,11 @@ const GenericComponentPage = ({
101
100
  );
102
101
  };
103
102
 
104
- export const getComponentPreviews = (
103
+ export function getComponentPreviews(
105
104
  tab: 'overview' | 'tokens',
106
105
  component: CoreTypes.IFileComponentObject,
107
106
  options: ComponentDocumentationOptions
108
- ) => {
107
+ ): ComponentPreview[] {
109
108
  const instances = component.instances;
110
109
  const view = (options?.views ?? {})[tab] ?? {};
111
110
  const viewFilters = view.condition ?? {};
@@ -147,13 +146,10 @@ export const getComponentPreviews = (
147
146
  // Filter value object keys do not contain the value of the respective component property
148
147
  // Since component should not be displayed we return null value
149
148
  return null;
150
- } else {
151
- // Filter value object keys do contain the value of the respective component property
152
- // We will store the property value of the filter value object for later use
153
- overrides = filterValue[variantProps.get(filterProp)];
154
- // Use as a default possibly distinctive name
155
- name ??= variantProps.get(filterProp);
156
149
  }
150
+ // Filter value object keys do contain the value of the respective component property
151
+ overrides = filterValue[variantProps.get(filterProp)];
152
+ name ??= variantProps.get(filterProp);
157
153
  }
158
154
  } else if (typeof filterValue === 'string' && variantProps.get(filterProp) !== filterValue) {
159
155
  return null;
@@ -175,7 +171,7 @@ export const getComponentPreviews = (
175
171
  }
176
172
 
177
173
  return tabComponents;
178
- };
174
+ }
179
175
 
180
176
  function multiPropSort(properties: string[], array: ComponentPreview[]) {
181
177
  return array.sort((l, r) => {
@@ -199,14 +195,10 @@ function multiPropSort(properties: string[], array: ComponentPreview[]) {
199
195
  });
200
196
  }
201
197
 
202
- const IsColorValue = (value: string) => {
203
- return value.match(/^#[0-9A-F]{6}$/i) || value.match(/linear-gradient\(.*?\)|rgba\(.*?\)/);
204
- };
205
-
206
198
  const NormalizeValue = (value: string): string => {
207
199
  if (!Number.isNaN(Number(value))) {
208
200
  const numericValue = Number(value);
209
- if (numericValue % 1 != 0) {
201
+ if (numericValue % 1 !== 0) {
210
202
  return round(numericValue, 2).toFixed(2);
211
203
  }
212
204
  }
@@ -220,7 +212,6 @@ export interface ComponentDesignTokensProps {
220
212
  previewObjectOptions?: CoreTypes.IHandoffConfigurationComponentOptions;
221
213
  componentInstances: CoreTypes.IComponentInstance[];
222
214
  overrides?: { [variantProp: string]: string[] };
223
- children?: React.ReactNode;
224
215
  renderPreviews: boolean;
225
216
  useReferences: boolean;
226
217
  }
@@ -228,23 +219,19 @@ export interface ComponentDesignTokensProps {
228
219
  interface DataTableRow extends Map<string, [string, string, CoreTypes.IToken | undefined][]> { }
229
220
  interface DataTable extends Map<string, DataTableRow> { }
230
221
 
231
- export const ComponentDesignTokens: React.FC<ComponentDesignTokensProps> = ({
222
+ export function ComponentDesignTokens({
232
223
  title,
233
224
  componentInstances,
234
225
  previewObject,
235
226
  previewObjectOptions,
236
227
  overrides,
237
- children,
238
- renderPreviews,
239
228
  useReferences,
240
- }) => {
229
+ }: ComponentDesignTokensProps) {
241
230
  const previewObjectVariantPropsMap = new Map(previewObject.variantProperties);
242
- const [showReference, setShowReference] = React.useState(useReferences);
231
+ const [showReference] = React.useState(useReferences);
243
232
  const headings: Set<string> = new Set<string>();
244
233
  const dataTable = new Map() as DataTable;
245
234
 
246
- let numberOfColumns = 0;
247
-
248
235
  if (overrides) {
249
236
  const overrideVariantProps = Object.keys(overrides) ?? [];
250
237
  const masterOverride = overrideVariantProps[0];
@@ -278,9 +265,6 @@ export const ComponentDesignTokens: React.FC<ComponentDesignTokensProps> = ({
278
265
  .push([token.name, token.value, token ?? undefined]);
279
266
  });
280
267
 
281
- // Increase columns count
282
- numberOfColumns++;
283
-
284
268
  // Append heading to the list of headings
285
269
  headings.add(componentVariantPropsMap.get(masterOverride));
286
270
  });
@@ -299,9 +283,6 @@ export const ComponentDesignTokens: React.FC<ComponentDesignTokensProps> = ({
299
283
  .push([token.name, token.value, token ?? undefined]);
300
284
  });
301
285
 
302
- // Increase columns count
303
- numberOfColumns++;
304
-
305
286
  // Append heading to the list of headings
306
287
  headings.add('Value');
307
288
  }
@@ -310,8 +291,6 @@ export const ComponentDesignTokens: React.FC<ComponentDesignTokensProps> = ({
310
291
  return <></>;
311
292
  }
312
293
 
313
- const layoutLeftColWidth = renderPreviews ? (numberOfColumns >= 7 ? 11 : 4 + numberOfColumns) : 12;
314
- const layoutRightColWidth = 12 - layoutLeftColWidth;
315
294
  const headingsTotal = Array.from(headings).length + 1;
316
295
 
317
296
  return (
@@ -341,26 +320,19 @@ export const ComponentDesignTokens: React.FC<ComponentDesignTokensProps> = ({
341
320
 
342
321
  {Array.from(propertiesMap)
343
322
  .sort(([lProp], [rProp]) => lProp.localeCompare(rProp))
344
- .map(([prop, cells], i) => (
323
+ .map(([, cells], i) => (
345
324
  <TableRow key={`${previewObject.id}_table_tokens_row_${rowIdx}_${i}`} className="h-12">
346
325
  <TableCell>
347
- {/* <p>{prop}</p> */}
348
326
  {cells[0][0]}
349
327
  </TableCell>
350
328
 
351
- {cells.map(([_, tokenValue, tokenReference], i) => (
352
- <TableCell key={`${previewObject.id}_table_tokens_row_${rowIdx}_${i}_cell_${i}`}>
353
- {/* {IsColorValue(tokenValue) && (
354
- <div className="group relative inline-block h-7 w-7 rounded-lg" style={{ background: tokenValue }}></div>
355
- )} */}
356
- {/* <PropertyIcon name={property} /> */}
357
- {!showReference ? (
358
- NormalizeValue(tokenValue)
359
- ) : tokenReference ? (
360
- <>{tokenReferenceFormat(tokenReference, 'css')} </>
361
- ) : (
362
- NormalizeValue(tokenValue)
363
- )}
329
+ {cells.map(([, tokenValue, tokenReference], cellIdx) => (
330
+ <TableCell key={`${previewObject.id}_table_tokens_row_${rowIdx}_${i}_cell_${cellIdx}`}>
331
+ {(() => {
332
+ if (!showReference) return NormalizeValue(tokenValue);
333
+ if (tokenReference) return <>{tokenReferenceFormat(tokenReference, 'css')} </>;
334
+ return NormalizeValue(tokenValue);
335
+ })()}
364
336
  </TableCell>
365
337
  ))}
366
338
  </TableRow>
@@ -371,6 +343,6 @@ export const ComponentDesignTokens: React.FC<ComponentDesignTokensProps> = ({
371
343
  </Table>
372
344
  </>
373
345
  );
374
- };
346
+ }
375
347
 
376
348
  export default GenericComponentPage;
@@ -19,8 +19,7 @@ import { fetchDocPageMarkdown, FoundationDocumentationProps, getClientRuntimeCon
19
19
  * @param context GetStaticProps
20
20
  * @returns
21
21
  */
22
- export const getStaticProps: GetStaticProps = async (context) => {
23
- // Read current slug
22
+ export const getStaticProps: GetStaticProps = async () => {
24
23
  const config = getClientRuntimeConfig();
25
24
  return {
26
25
  ...{
@@ -32,6 +31,36 @@ export const getStaticProps: GetStaticProps = async (context) => {
32
31
  },
33
32
  };
34
33
  };
34
+
35
+ const ColorGroupTable = ({ colors }: { group: string; colors: CoreTypes.IColorObject[] }) => {
36
+ return (
37
+ <Table className="border-b-[0.5px] border-l-[0.5px] border-r-[0.5px]">
38
+ <TableHeader className="border-b-0 border-l-[0.5px] border-r-[0.5px] border-t-[0.5px] bg-gray-50/80 dark:bg-gray-800/80 ">
39
+ <TableRow className="border-b-[0.5px]!">
40
+ <TableHead className="border-r-[0.5px] px-4 text-xs font-light text-gray-900 dark:text-gray-100">Name</TableHead>
41
+ <TableHead className="border-r-[0.5px] px-4 text-xs font-light text-gray-900 dark:text-gray-100">Value</TableHead>
42
+ </TableRow>
43
+ </TableHeader>
44
+ <TableBody>
45
+ {colors.map((color) => (
46
+ <TableRow key={color.id} className="h-10 border-b-[0.5px]">
47
+ <TableCell className="border-r-[0.5px] px-3.5 py-1">{color.reference}</TableCell>
48
+ <TableCell className="border-r-[0.5px] px-3.5 py-1">
49
+ <div className="flex items-center gap-2">
50
+ <span
51
+ className="group relative block h-4 w-4 rounded-full"
52
+ style={{ background: color.value ?? '', backgroundBlendMode: color.blend ?? '' }}
53
+ ></span>
54
+ <code className="text-xs">{color.value}</code>
55
+ </div>
56
+ </TableCell>
57
+ </TableRow>
58
+ ))}
59
+ </TableBody>
60
+ </Table>
61
+ );
62
+ };
63
+
35
64
  /**
36
65
  * Define the components page
37
66
  * @param param0
@@ -94,33 +123,4 @@ const ComponentsPage = ({ content, menu, metadata, current, config, design }: Fo
94
123
  );
95
124
  };
96
125
 
97
- const ColorGroupTable = ({ group, colors }: { group: string; colors: CoreTypes.IColorObject[] }) => {
98
- return (
99
- <Table className="border-b-[0.5px] border-l-[0.5px] border-r-[0.5px]">
100
- <TableHeader className="border-b-0 border-l-[0.5px] border-r-[0.5px] border-t-[0.5px] bg-gray-50/80 dark:bg-gray-800/80 ">
101
- <TableRow className="border-b-[0.5px]!">
102
- <TableHead className="border-r-[0.5px] px-4 text-xs font-light text-gray-900 dark:text-gray-100">Name</TableHead>
103
- <TableHead className="border-r-[0.5px] px-4 text-xs font-light text-gray-900 dark:text-gray-100">Value</TableHead>
104
- </TableRow>
105
- </TableHeader>
106
- <TableBody>
107
- {colors.map((color) => (
108
- <TableRow key={color.id} className="h-10 border-b-[0.5px]">
109
- <TableCell className="border-r-[0.5px] px-3.5 py-1">{color.reference}</TableCell>
110
- <TableCell className="border-r-[0.5px] px-3.5 py-1">
111
- <div className="flex items-center gap-2">
112
- <span
113
- className="group relative block h-4 w-4 rounded-full"
114
- style={{ background: color.value ?? '', backgroundBlendMode: color.blend ?? '' }}
115
- ></span>
116
- <code className="text-xs">{color.value}</code>
117
- </div>
118
- </TableCell>
119
- </TableRow>
120
- ))}
121
- </TableBody>
122
- </Table>
123
- );
124
- };
125
-
126
126
  export default ComponentsPage;
@@ -19,8 +19,7 @@ import { fetchDocPageMarkdown, FoundationDocumentationProps, getClientRuntimeCon
19
19
  * @param context GetStaticProps
20
20
  * @returns
21
21
  */
22
- export const getStaticProps: GetStaticProps = async (context) => {
23
- // Read current slug
22
+ export const getStaticProps: GetStaticProps = async () => {
24
23
  const config = getClientRuntimeConfig();
25
24
  return {
26
25
  ...{
@@ -32,6 +31,30 @@ export const getStaticProps: GetStaticProps = async (context) => {
32
31
  },
33
32
  };
34
33
  };
34
+
35
+ const EffectsTable = ({ effects }: { group: string; effects: CoreTypes.IEffectObject[] }) => {
36
+ return (
37
+ <Table className="border-b-[0.5px] border-l-[0.5px] border-r-[0.5px]">
38
+ <TableHeader className="border-b-0 border-l-[0.5px] border-r-[0.5px] border-t-[0.5px] bg-gray-50/80 dark:bg-gray-800/80 ">
39
+ <TableRow className="border-b-[0.5px]!">
40
+ <TableHead className="border-r-[0.5px] px-4 text-xs font-light text-gray-900 dark:text-gray-100">Reference</TableHead>
41
+ <TableHead className="border-r-[0.5px] px-4 text-xs font-light text-gray-900 dark:text-gray-100">Effects</TableHead>
42
+ </TableRow>
43
+ </TableHeader>
44
+ <TableBody>
45
+ {effects.map((effect) => (
46
+ <TableRow key={effect.id} className="h-10 border-b-[0.5px]">
47
+ <TableCell className="border-r-[0.5px] px-3.5 py-1">{effect.reference.replace(/-+/g, '-')}</TableCell>
48
+ <TableCell className="border-r-[0.5px] px-3.5 py-1">
49
+ {effect.effects.map((effect) => effect.value).join(', ') || 'none'}
50
+ </TableCell>
51
+ </TableRow>
52
+ ))}
53
+ </TableBody>
54
+ </Table>
55
+ );
56
+ };
57
+
35
58
  /**
36
59
  * Define the components page
37
60
  * @param param0
@@ -87,27 +110,4 @@ const ComponentsPage = ({ content, menu, metadata, current, config, design }: Fo
87
110
  );
88
111
  };
89
112
 
90
- const EffectsTable = ({ group, effects }: { group: string; effects: CoreTypes.IEffectObject[] }) => {
91
- return (
92
- <Table className="border-b-[0.5px] border-l-[0.5px] border-r-[0.5px]">
93
- <TableHeader className="border-b-0 border-l-[0.5px] border-r-[0.5px] border-t-[0.5px] bg-gray-50/80 dark:bg-gray-800/80 ">
94
- <TableRow className="border-b-[0.5px]!">
95
- <TableHead className="border-r-[0.5px] px-4 text-xs font-light text-gray-900 dark:text-gray-100">Reference</TableHead>
96
- <TableHead className="border-r-[0.5px] px-4 text-xs font-light text-gray-900 dark:text-gray-100">Effects</TableHead>
97
- </TableRow>
98
- </TableHeader>
99
- <TableBody>
100
- {effects.map((effect) => (
101
- <TableRow key={effect.id} className="h-10 border-b-[0.5px]">
102
- <TableCell className="border-r-[0.5px] px-3.5 py-1">{effect.reference.replace(/-+/g, '-')}</TableCell>
103
- <TableCell className="border-r-[0.5px] px-3.5 py-1">
104
- {effect.effects.map((effect) => effect.value).join(', ') || 'none'}
105
- </TableCell>
106
- </TableRow>
107
- ))}
108
- </TableBody>
109
- </Table>
110
- );
111
- };
112
-
113
113
  export default ComponentsPage;
@@ -20,8 +20,7 @@ import { fetchDocPageMarkdown, FoundationDocumentationProps, getClientRuntimeCon
20
20
  * @param context GetStaticProps
21
21
  * @returns
22
22
  */
23
- export const getStaticProps: GetStaticProps = async (context) => {
24
- // Read current slug
23
+ export const getStaticProps: GetStaticProps = async () => {
25
24
  const config = getClientRuntimeConfig();
26
25
  return {
27
26
  ...{
@@ -33,40 +32,6 @@ export const getStaticProps: GetStaticProps = async (context) => {
33
32
  },
34
33
  };
35
34
  };
36
- /**
37
- * Define the components page
38
- * @param param0
39
- * @returns
40
- */
41
- const ComponentsPage = ({ content, menu, metadata, current, config, design }: FoundationDocumentationProps) => {
42
- const typography = design.typography.slice().sort((a, b) => {
43
- const l = (config?.app?.type_sort ?? []).indexOf(a.name) >>> 0;
44
- const r = (config?.app?.type_sort ?? []).indexOf(b.name) >>> 0;
45
- return l !== r ? l - r : a.name.localeCompare(b.name);
46
- });
47
-
48
- return (
49
- <Layout config={config} menu={menu} current={current} metadata={metadata}>
50
- <div className="flex flex-col gap-2 pb-7">
51
- <HeadersType.H1>{metadata.title}</HeadersType.H1>
52
- <p className="text-lg leading-relaxed text-gray-600 dark:text-gray-300">{metadata.description}</p>
53
- </div>
54
- <div className="mt-10 lg:gap-10 lg:py-8 xl:grid xl:grid-cols-[1fr_280px]">
55
- <div>
56
- <div className="prose">
57
- <ReactMarkdown components={MarkdownComponents} remarkPlugins={[remarkGfm, remarkCodeMeta]} rehypePlugins={[rehypeRaw]}>
58
- {content}
59
- </ReactMarkdown>
60
- </div>
61
- <FontsTable types={typography} />
62
- </div>
63
- <AnchorNav
64
- groups={[Object.assign({}, ...[...typography.map((type) => ({ [`${type.name}-typography`]: `${upperFirst(type.name)}` }))])]}
65
- />
66
- </div>
67
- </Layout>
68
- );
69
- };
70
35
 
71
36
  const FontsTable = ({ types }: { types: CoreTypes.ITypographyObject[] }) => {
72
37
  return (
@@ -114,6 +79,41 @@ const FontsTable = ({ types }: { types: CoreTypes.ITypographyObject[] }) => {
114
79
  );
115
80
  };
116
81
 
82
+ /**
83
+ * Define the components page
84
+ * @param param0
85
+ * @returns
86
+ */
87
+ const ComponentsPage = ({ content, menu, metadata, current, config, design }: FoundationDocumentationProps) => {
88
+ const typography = design.typography.slice().sort((a, b) => {
89
+ const l = (config?.app?.type_sort ?? []).indexOf(a.name) >>> 0;
90
+ const r = (config?.app?.type_sort ?? []).indexOf(b.name) >>> 0;
91
+ return l !== r ? l - r : a.name.localeCompare(b.name);
92
+ });
93
+
94
+ return (
95
+ <Layout config={config} menu={menu} current={current} metadata={metadata}>
96
+ <div className="flex flex-col gap-2 pb-7">
97
+ <HeadersType.H1>{metadata.title}</HeadersType.H1>
98
+ <p className="text-lg leading-relaxed text-gray-600 dark:text-gray-300">{metadata.description}</p>
99
+ </div>
100
+ <div className="mt-10 lg:gap-10 lg:py-8 xl:grid xl:grid-cols-[1fr_280px]">
101
+ <div>
102
+ <div className="prose">
103
+ <ReactMarkdown components={MarkdownComponents} remarkPlugins={[remarkGfm, remarkCodeMeta]} rehypePlugins={[rehypeRaw]}>
104
+ {content}
105
+ </ReactMarkdown>
106
+ </div>
107
+ <FontsTable types={typography} />
108
+ </div>
109
+ <AnchorNav
110
+ groups={[Object.assign({}, ...[...typography.map((type) => ({ [`${type.name}-typography`]: `${upperFirst(type.name)}` }))])]}
111
+ />
112
+ </div>
113
+ </Layout>
114
+ );
115
+ };
116
+
117
117
  export const pluckStyle = (type: CoreTypes.ITypographyObject) => {
118
118
  return {
119
119
  fontFamily: type.values.fontFamily,
package/src/cli.ts CHANGED
@@ -19,7 +19,7 @@ class HandoffCliError extends Error {
19
19
  * Show the help message
20
20
  */
21
21
  const showVersion = () => {
22
- return 'Handoff App - 1.2.1';
22
+ return 'Handoff App - 1.2.2';
23
23
  };
24
24
 
25
25
  /**