handoff-app 1.0.3 → 1.0.5
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 +16 -5
- package/README.md +93 -57
- package/dist/cli.js +1 -1
- package/dist/commands/index.d.ts +1 -1
- package/dist/commands/index.js +2 -0
- package/dist/commands/init/index.d.ts +5 -0
- package/dist/commands/init/index.js +26 -0
- package/dist/create.d.ts +5 -0
- package/dist/create.js +293 -0
- package/dist/index.js +4 -1
- package/dist/transformers/plugins/ssr-render.js +4 -3
- package/dist/transformers/preview/component/api.js +3 -2
- package/dist/transformers/preview/component/builder.js +2 -1
- package/dist/transformers/utils/handlebars.js +3 -2
- package/package.json +1 -1
- package/src/app/components/Component/Preview.tsx +121 -121
- package/src/app/components/ComponentSearch.tsx +1 -1
- package/src/app/components/util/index.ts +17 -9
- package/src/app/pages/system/component/[component]/index.tsx +1 -1
- package/src/app/pages/system/index.tsx +2 -2
- package/src/app/pages/system/tokens/index.tsx +10 -10
- package/src/cli.ts +1 -1
- package/src/commands/index.ts +2 -0
- package/src/commands/init/index.ts +17 -0
- package/src/create.ts +302 -0
- package/src/index.ts +3 -0
- package/src/transformers/plugins/ssr-render.ts +3 -3
- package/src/transformers/preview/component/api.ts +1 -1
- package/src/transformers/preview/component/builder.ts +1 -1
- package/src/transformers/utils/handlebars.ts +2 -2
- package/templates/default/README.md.tpl +15 -0
- package/templates/default/components/button/Button.tsx.tpl +92 -0
- package/templates/default/components/button/button.js.tpl +62 -0
- package/templates/default/env.tpl +2 -0
- package/templates/default/gitignore.tpl +7 -0
- package/templates/default/handoff.config.js.tpl +181 -0
- package/templates/default/handoff.config.with-examples.js.tpl +182 -0
- package/templates/default/package.json.tpl +20 -0
- package/templates/default/tsconfig.json.tpl +24 -0
- package/dist/commands/platform/init.d.ts +0 -6
- package/dist/commands/platform/init.js +0 -231
- package/dist/commands/platform/login.d.ts +0 -6
- package/dist/commands/platform/login.js +0 -108
- package/dist/commands/platform/logout.d.ts +0 -6
- package/dist/commands/platform/logout.js +0 -88
- package/dist/commands/platform/pull.d.ts +0 -8
- package/dist/commands/platform/pull.js +0 -112
- package/dist/commands/platform/push.d.ts +0 -8
- package/dist/commands/platform/push.js +0 -428
- package/dist/platform/client.d.ts +0 -122
- package/dist/platform/client.js +0 -228
- package/dist/platform/credentials.d.ts +0 -40
- package/dist/platform/credentials.js +0 -91
- package/dist/platform/sync.d.ts +0 -68
- package/dist/platform/sync.js +0 -349
|
@@ -95,20 +95,21 @@ exports.writeComponentApi = writeComponentApi;
|
|
|
95
95
|
* @param componentData
|
|
96
96
|
*/
|
|
97
97
|
const updateComponentSummaryApi = (handoff_1, componentData_1, ...args_1) => __awaiter(void 0, [handoff_1, componentData_1, ...args_1], void 0, function* (handoff, componentData, isFullRebuild = false) {
|
|
98
|
+
var _a;
|
|
98
99
|
if (isFullRebuild) {
|
|
99
100
|
// Full rebuild: replace the entire file
|
|
100
101
|
yield writeComponentSummaryAPI(handoff, componentData);
|
|
101
102
|
return;
|
|
102
103
|
}
|
|
103
104
|
// Partial update: merge with existing data
|
|
104
|
-
const apiPath = path_1.default.resolve(handoff.workingPath, '
|
|
105
|
+
const apiPath = path_1.default.resolve(handoff.workingPath, `${(_a = process.env.HANDOFF_APP_BASE_PATH) !== null && _a !== void 0 ? _a : ''}/api/components.json`);
|
|
105
106
|
let existingData = [];
|
|
106
107
|
if (fs_extra_1.default.existsSync(apiPath)) {
|
|
107
108
|
try {
|
|
108
109
|
const existing = yield fs_extra_1.default.readFile(apiPath, 'utf8');
|
|
109
110
|
existingData = JSON.parse(existing);
|
|
110
111
|
}
|
|
111
|
-
catch (
|
|
112
|
+
catch (_b) {
|
|
112
113
|
// Corrupt or missing JSON — treat as empty
|
|
113
114
|
existingData = [];
|
|
114
115
|
}
|
|
@@ -313,6 +313,7 @@ function processComponents(handoff, id, segmentToProcess, options) {
|
|
|
313
313
|
* @returns
|
|
314
314
|
*/
|
|
315
315
|
const buildComponentSummary = (id, data) => {
|
|
316
|
+
var _a;
|
|
316
317
|
return {
|
|
317
318
|
id,
|
|
318
319
|
title: data.title,
|
|
@@ -325,7 +326,7 @@ const buildComponentSummary = (id, data) => {
|
|
|
325
326
|
tags: data.tags ? data.tags : [],
|
|
326
327
|
properties: data.properties,
|
|
327
328
|
previews: data.previews,
|
|
328
|
-
path:
|
|
329
|
+
path: `${(_a = process.env.HANDOFF_APP_BASE_PATH) !== null && _a !== void 0 ? _a : ''}/api/component/${id}.json`,
|
|
329
330
|
};
|
|
330
331
|
};
|
|
331
332
|
exports.default = processComponents;
|
|
@@ -52,9 +52,10 @@ exports.registerHandlebarsHelpers = registerHandlebarsHelpers;
|
|
|
52
52
|
* @returns Handlebars context object
|
|
53
53
|
*/
|
|
54
54
|
const createHandlebarsContext = (data, previewData) => {
|
|
55
|
+
var _a, _b, _c, _d, _e;
|
|
55
56
|
return {
|
|
56
|
-
style: `<link rel="stylesheet" href="/api/component/shared.css"><link rel="stylesheet" href="/api/component/${data.id}.css">\n<link rel="stylesheet" href="/assets/css/preview.css">`,
|
|
57
|
-
script: `<script src="/api/component/${data.id}.js"></script>\n<script src="/assets/js/preview.js"></script><script>var fields = ${JSON.stringify(data.properties)};</script>`,
|
|
57
|
+
style: `<link rel="stylesheet" href="${(_a = process.env.HANDOFF_APP_BASE_PATH) !== null && _a !== void 0 ? _a : ''}/api/component/shared.css"><link rel="stylesheet" href="${(_b = process.env.HANDOFF_APP_BASE_PATH) !== null && _b !== void 0 ? _b : ''}/api/component/${data.id}.css">\n<link rel="stylesheet" href="${(_c = process.env.HANDOFF_APP_BASE_PATH) !== null && _c !== void 0 ? _c : ''}/assets/css/preview.css">`,
|
|
58
|
+
script: `<script src="${(_d = process.env.HANDOFF_APP_BASE_PATH) !== null && _d !== void 0 ? _d : ''}/api/component/${data.id}.js"></script>\n<script src="${(_e = process.env.HANDOFF_APP_BASE_PATH) !== null && _e !== void 0 ? _e : ''}/assets/js/preview.js"></script><script>var fields = ${JSON.stringify(data.properties)};</script>`,
|
|
58
59
|
properties: previewData.values || {},
|
|
59
60
|
fields: data.properties,
|
|
60
61
|
title: data.title,
|
package/package.json
CHANGED
|
@@ -303,7 +303,7 @@ export const ComponentDisplay: React.FC<{
|
|
|
303
303
|
className="h-7 px-3 hover:bg-gray-300 [&_svg]:size-3"
|
|
304
304
|
onClick={() => {
|
|
305
305
|
// open in new tab
|
|
306
|
-
window.open('/api/component
|
|
306
|
+
window.open(`${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/component/${previewUrl}`, '_blank');
|
|
307
307
|
}}
|
|
308
308
|
variant="ghost"
|
|
309
309
|
>
|
|
@@ -333,7 +333,7 @@ export const ComponentDisplay: React.FC<{
|
|
|
333
333
|
display: 'block',
|
|
334
334
|
margin: '0 auto',
|
|
335
335
|
}}
|
|
336
|
-
src={
|
|
336
|
+
src={`${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/component/${previewUrl}`}
|
|
337
337
|
/>
|
|
338
338
|
</div>
|
|
339
339
|
) : (
|
|
@@ -539,9 +539,9 @@ const hasNestedProperties = (row: SlotMetadata): boolean => {
|
|
|
539
539
|
);
|
|
540
540
|
};
|
|
541
541
|
|
|
542
|
-
const TableRows: React.FC<{
|
|
543
|
-
rows: SlotMetadata[];
|
|
544
|
-
openSheet: (field: SlotMetadata) => void;
|
|
542
|
+
const TableRows: React.FC<{
|
|
543
|
+
rows: SlotMetadata[];
|
|
544
|
+
openSheet: (field: SlotMetadata) => void;
|
|
545
545
|
depth?: number;
|
|
546
546
|
parentPath?: string;
|
|
547
547
|
}> = ({
|
|
@@ -550,24 +550,24 @@ const TableRows: React.FC<{
|
|
|
550
550
|
depth = 0,
|
|
551
551
|
parentPath = '',
|
|
552
552
|
}) => {
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
};
|
|
553
|
+
return (
|
|
554
|
+
<>
|
|
555
|
+
{rows.map((row, i) => {
|
|
556
|
+
if (!row) return null;
|
|
557
|
+
const currentPath = parentPath ? `${parentPath}.${row.key || row.name}` : (row.key || row.name);
|
|
558
|
+
return (
|
|
559
|
+
<ExpandableTableRow
|
|
560
|
+
key={`row-${currentPath}-${i}`}
|
|
561
|
+
row={row}
|
|
562
|
+
openSheet={openSheet}
|
|
563
|
+
depth={depth}
|
|
564
|
+
path={currentPath}
|
|
565
|
+
/>
|
|
566
|
+
);
|
|
567
|
+
})}
|
|
568
|
+
</>
|
|
569
|
+
);
|
|
570
|
+
};
|
|
571
571
|
|
|
572
572
|
const humanReadableSizeRule = (rule: string, value: any) => {
|
|
573
573
|
switch (rule) {
|
|
@@ -597,9 +597,9 @@ const humanReadableSizeRule = (rule: string, value: any) => {
|
|
|
597
597
|
* An expandable table row that can show nested properties
|
|
598
598
|
* Supports deep nesting with visual indentation and expand/collapse
|
|
599
599
|
*/
|
|
600
|
-
const ExpandableTableRow: React.FC<{
|
|
601
|
-
row: SlotMetadata;
|
|
602
|
-
openSheet: (field: SlotMetadata) => void;
|
|
600
|
+
const ExpandableTableRow: React.FC<{
|
|
601
|
+
row: SlotMetadata;
|
|
602
|
+
openSheet: (field: SlotMetadata) => void;
|
|
603
603
|
depth: number;
|
|
604
604
|
path: string;
|
|
605
605
|
}> = ({
|
|
@@ -608,104 +608,104 @@ const ExpandableTableRow: React.FC<{
|
|
|
608
608
|
depth,
|
|
609
609
|
path,
|
|
610
610
|
}) => {
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
const getSizeDisplay = (row: SlotMetadata) => {
|
|
616
|
-
if (!row.rules) return '-';
|
|
617
|
-
|
|
618
|
-
// Find the first applicable size rule
|
|
619
|
-
const sizeRules = ['dimensions', 'content', 'maxSize'];
|
|
620
|
-
const rule = Object.keys(row.rules).find((r) => sizeRules.includes(r));
|
|
621
|
-
|
|
622
|
-
return rule ? humanReadableSizeRule(rule, row.rules[rule]) : '-';
|
|
623
|
-
};
|
|
611
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
612
|
+
const nested = getNestedProperties(row);
|
|
613
|
+
const canExpand = hasNestedProperties(row);
|
|
624
614
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
// Get background color based on depth for visual hierarchy
|
|
629
|
-
const getDepthBgClass = (depth: number) => {
|
|
630
|
-
if (depth === 0) return '';
|
|
631
|
-
if (depth === 1) return 'bg-gray-50/50 dark:bg-gray-800/30';
|
|
632
|
-
if (depth === 2) return 'bg-gray-100/50 dark:bg-gray-800/50';
|
|
633
|
-
return 'bg-gray-100/70 dark:bg-gray-800/70';
|
|
634
|
-
};
|
|
615
|
+
const getSizeDisplay = (row: SlotMetadata) => {
|
|
616
|
+
if (!row.rules) return '-';
|
|
635
617
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
return;
|
|
640
|
-
}
|
|
641
|
-
openSheet(row);
|
|
642
|
-
};
|
|
618
|
+
// Find the first applicable size rule
|
|
619
|
+
const sizeRules = ['dimensions', 'content', 'maxSize'];
|
|
620
|
+
const rule = Object.keys(row.rules).find((r) => sizeRules.includes(r));
|
|
643
621
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
setIsExpanded(!isExpanded);
|
|
647
|
-
};
|
|
622
|
+
return rule ? humanReadableSizeRule(rule, row.rules[rule]) : '-';
|
|
623
|
+
};
|
|
648
624
|
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
625
|
+
// Calculate indent based on depth (each level adds 20px)
|
|
626
|
+
const indentPx = depth * 20;
|
|
627
|
+
|
|
628
|
+
// Get background color based on depth for visual hierarchy
|
|
629
|
+
const getDepthBgClass = (depth: number) => {
|
|
630
|
+
if (depth === 0) return '';
|
|
631
|
+
if (depth === 1) return 'bg-gray-50/50 dark:bg-gray-800/30';
|
|
632
|
+
if (depth === 2) return 'bg-gray-100/50 dark:bg-gray-800/50';
|
|
633
|
+
return 'bg-gray-100/70 dark:bg-gray-800/70';
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
const handleRowClick = (e: React.MouseEvent) => {
|
|
637
|
+
// If clicking on the expand button area, don't open the sheet
|
|
638
|
+
if ((e.target as HTMLElement).closest('.expand-toggle')) {
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
openSheet(row);
|
|
642
|
+
};
|
|
643
|
+
|
|
644
|
+
const handleExpandToggle = (e: React.MouseEvent) => {
|
|
645
|
+
e.stopPropagation();
|
|
646
|
+
setIsExpanded(!isExpanded);
|
|
647
|
+
};
|
|
648
|
+
|
|
649
|
+
return (
|
|
650
|
+
<>
|
|
651
|
+
<TableRow
|
|
652
|
+
className={`h-10 cursor-pointer border-b-[0.5px] ${getDepthBgClass(depth)}`}
|
|
653
|
+
onClick={handleRowClick}
|
|
654
|
+
>
|
|
655
|
+
<TableCell className="whitespace-nowrap border-l-[0.5px] border-r-[0.5px] px-4 py-1">
|
|
656
|
+
<div className="flex items-center" style={{ paddingLeft: `${indentPx}px` }}>
|
|
657
|
+
{canExpand ? (
|
|
658
|
+
<button
|
|
659
|
+
className="expand-toggle mr-2 flex h-5 w-5 items-center justify-center rounded hover:bg-gray-200 dark:hover:bg-gray-700"
|
|
660
|
+
onClick={handleExpandToggle}
|
|
661
|
+
aria-label={isExpanded ? 'Collapse' : 'Expand'}
|
|
662
|
+
>
|
|
663
|
+
{isExpanded ? (
|
|
664
|
+
<ChevronDown className="h-4 w-4 text-gray-500" />
|
|
665
|
+
) : (
|
|
666
|
+
<ChevronRight className="h-4 w-4 text-gray-500" />
|
|
667
|
+
)}
|
|
668
|
+
</button>
|
|
669
|
+
) : (
|
|
670
|
+
<span className="mr-2 w-5" />
|
|
671
|
+
)}
|
|
672
|
+
<span className={depth > 0 ? 'text-gray-700 dark:text-gray-300' : ''}>
|
|
673
|
+
{startCase(row.name)}
|
|
678
674
|
</span>
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
</
|
|
686
|
-
|
|
687
|
-
<Badge variant=
|
|
688
|
-
{row.
|
|
675
|
+
{canExpand && (
|
|
676
|
+
<span className="ml-2 text-xs text-gray-400">
|
|
677
|
+
({Object.keys(nested || {}).length} {row.type === 'array' ? 'item fields' : 'fields'})
|
|
678
|
+
</span>
|
|
679
|
+
)}
|
|
680
|
+
</div>
|
|
681
|
+
</TableCell>
|
|
682
|
+
<TableCell className="border-r-[0.5px] px-3.5 py-1">
|
|
683
|
+
<Badge variant={getVariantForType(row.type)} className="rounded-xl px-2.5">
|
|
684
|
+
{row.type}
|
|
689
685
|
</Badge>
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
<
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
686
|
+
{row.type === 'array' && row.items?.type && (
|
|
687
|
+
<Badge variant="outline" className="ml-1 rounded-xl px-2 text-[10px]">
|
|
688
|
+
{row.items.type}[]
|
|
689
|
+
</Badge>
|
|
690
|
+
)}
|
|
691
|
+
</TableCell>
|
|
692
|
+
<TableCell className="whitespace-nowrap border-l-[0.5px] border-r-[0.5px] px-4 py-1 text-gray-600 dark:text-gray-300">
|
|
693
|
+
{getSizeDisplay(row)}
|
|
694
|
+
</TableCell>
|
|
695
|
+
<TableCell className="border-r-[0.5px] px-4 py-1 text-gray-600 dark:text-gray-300">
|
|
696
|
+
<span className="slot-description line-clamp-1">{row.description || row.generic || '-'}</span>
|
|
697
|
+
</TableCell>
|
|
698
|
+
</TableRow>
|
|
699
|
+
|
|
700
|
+
{/* Render nested properties when expanded */}
|
|
701
|
+
{isExpanded && nested && nested.length > 0 && (
|
|
702
|
+
<TableRows
|
|
703
|
+
rows={nested}
|
|
704
|
+
openSheet={openSheet}
|
|
705
|
+
depth={depth + 1}
|
|
706
|
+
parentPath={path}
|
|
707
|
+
/>
|
|
708
|
+
)}
|
|
709
|
+
</>
|
|
710
|
+
);
|
|
711
|
+
};
|
|
@@ -9,7 +9,7 @@ import React from 'react';
|
|
|
9
9
|
*/
|
|
10
10
|
export const getComponentList = async (): Promise<ComponentListObject[]> => {
|
|
11
11
|
// Try to load the component from the public json
|
|
12
|
-
let data = await fetch(
|
|
12
|
+
let data = await fetch(`${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/components.json`).then((res) => res.json());
|
|
13
13
|
return data as ComponentListObject[];
|
|
14
14
|
};
|
|
15
15
|
|
|
@@ -206,6 +206,9 @@ export const staticBuildMenu = () => {
|
|
|
206
206
|
// // Contents of docs
|
|
207
207
|
const docRoot = path.join(process.env.HANDOFF_MODULE_PATH ?? '', 'config/docs');
|
|
208
208
|
// Get the file list
|
|
209
|
+
if(!fs.existsSync(docRoot)) {
|
|
210
|
+
return [];
|
|
211
|
+
}
|
|
209
212
|
const files = fs.readdirSync(docRoot);
|
|
210
213
|
let list = files;
|
|
211
214
|
const workingPages = path.resolve(process.env.HANDOFF_WORKING_PATH ?? '', 'pages');
|
|
@@ -277,7 +280,7 @@ export const staticBuildMenu = () => {
|
|
|
277
280
|
title: metadata.menuTitle ?? metadata.title,
|
|
278
281
|
external,
|
|
279
282
|
weight: metadata.weight ?? 0,
|
|
280
|
-
path: filepath
|
|
283
|
+
path: `${filepath}`,
|
|
281
284
|
subSections,
|
|
282
285
|
};
|
|
283
286
|
}
|
|
@@ -287,6 +290,7 @@ export const staticBuildMenu = () => {
|
|
|
287
290
|
};
|
|
288
291
|
|
|
289
292
|
const staticBuildComponentMenu = (type?: boolean | string) => {
|
|
293
|
+
const basePath = (process.env.HANDOFF_APP_BASE_PATH ?? '').replace(/^\//, '');
|
|
290
294
|
let menu = [];
|
|
291
295
|
let components = fetchComponents({ includeTokens: false });
|
|
292
296
|
if (typeof type === 'string' && type !== '') {
|
|
@@ -305,7 +309,7 @@ const staticBuildComponentMenu = (type?: boolean | string) => {
|
|
|
305
309
|
if (component.name) {
|
|
306
310
|
title = component.name;
|
|
307
311
|
}
|
|
308
|
-
menuGroup.menu.push({ path:
|
|
312
|
+
menuGroup.menu.push({ path: `${basePath}/system/component/${component.id}`, title });
|
|
309
313
|
});
|
|
310
314
|
// sort the menu group by name alphabetical
|
|
311
315
|
menuGroup.menu = menuGroup.menu.sort((a, b) => a.title.localeCompare(b.title));
|
|
@@ -317,22 +321,24 @@ const staticBuildComponentMenu = (type?: boolean | string) => {
|
|
|
317
321
|
};
|
|
318
322
|
|
|
319
323
|
const staticBuildTokensMenu = () => {
|
|
324
|
+
const basePath = (process.env.HANDOFF_APP_BASE_PATH ?? '').replace(/^\//, '');
|
|
325
|
+
|
|
320
326
|
const menu = [
|
|
321
327
|
{
|
|
322
328
|
title: `Foundations`,
|
|
323
|
-
path:
|
|
329
|
+
path: `${basePath}/system/tokens/foundations`,
|
|
324
330
|
menu: [
|
|
325
331
|
{
|
|
326
332
|
title: `Colors`,
|
|
327
|
-
path:
|
|
333
|
+
path: `${basePath}/system/tokens/foundations/colors`,
|
|
328
334
|
},
|
|
329
335
|
{
|
|
330
336
|
title: `Effects`,
|
|
331
|
-
path:
|
|
337
|
+
path: `${basePath}/system/tokens/foundations/effects`,
|
|
332
338
|
},
|
|
333
339
|
{
|
|
334
340
|
title: `Typography`,
|
|
335
|
-
path:
|
|
341
|
+
path: `${basePath}/system/tokens/foundations/typography`,
|
|
336
342
|
},
|
|
337
343
|
],
|
|
338
344
|
},
|
|
@@ -352,14 +358,14 @@ const staticBuildTokensMenu = () => {
|
|
|
352
358
|
if (component.name) {
|
|
353
359
|
title = component.name;
|
|
354
360
|
}
|
|
355
|
-
componentMenuItems.push({ path:
|
|
361
|
+
componentMenuItems.push({ path: `${basePath}/system/tokens/components/${component.id}`, title });
|
|
356
362
|
});
|
|
357
363
|
});
|
|
358
364
|
|
|
359
365
|
if (componentMenuItems.length > 0) {
|
|
360
366
|
menu.push({
|
|
361
367
|
title: `Components`,
|
|
362
|
-
path:
|
|
368
|
+
path: `${basePath}/system/tokens/components`,
|
|
363
369
|
menu: componentMenuItems,
|
|
364
370
|
});
|
|
365
371
|
}
|
|
@@ -368,9 +374,11 @@ const staticBuildTokensMenu = () => {
|
|
|
368
374
|
};
|
|
369
375
|
|
|
370
376
|
const staticBuildTokenMenu = () => {
|
|
377
|
+
const basePath = (process.env.HANDOFF_APP_BASE_PATH ?? '').replace(/^\//, '');
|
|
378
|
+
|
|
371
379
|
let subSections = {
|
|
372
380
|
title: 'Tokens',
|
|
373
|
-
path:
|
|
381
|
+
path: `${basePath}/system/tokens`,
|
|
374
382
|
menu: [],
|
|
375
383
|
};
|
|
376
384
|
const tokens = getTokens();
|
|
@@ -110,7 +110,7 @@ const GenericComponentPage = ({ menu, metadata, current, id, config, componentHo
|
|
|
110
110
|
const [componentPreviews, setComponentPreviews] = useState<PreviewObject | [string, PreviewObject][]>();
|
|
111
111
|
|
|
112
112
|
const fetchComponents = async () => {
|
|
113
|
-
let data = await fetch(
|
|
113
|
+
let data = await fetch(`${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/component/${id}.json`).then((res) => res.json());
|
|
114
114
|
setComponent(data as PreviewObject);
|
|
115
115
|
};
|
|
116
116
|
|
|
@@ -67,7 +67,7 @@ const ComponentsPage = ({ content, menu, metadata, current, config }: ComponentP
|
|
|
67
67
|
// Fetch components from api
|
|
68
68
|
const [components, setComponents] = useState<PreviewObject[]>(undefined);
|
|
69
69
|
const fetchComponents = async () => {
|
|
70
|
-
let data = await fetch(
|
|
70
|
+
let data = await fetch(`${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/components.json`).then((res) => res.json());
|
|
71
71
|
setComponents(data as PreviewObject[]);
|
|
72
72
|
};
|
|
73
73
|
useEffect(() => {
|
|
@@ -108,7 +108,7 @@ const ComponentsPage = ({ content, menu, metadata, current, config }: ComponentP
|
|
|
108
108
|
);
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
const apiUrl = (window.location.origin && window.location.origin) +
|
|
111
|
+
const apiUrl = (window.location.origin && window.location.origin) + `${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/components.json`;
|
|
112
112
|
return (
|
|
113
113
|
<Layout config={config} menu={menu} current={current} metadata={metadata}>
|
|
114
114
|
<div className="flex flex-col gap-2 pb-7">
|
|
@@ -39,14 +39,14 @@ export const getStaticProps: GetStaticProps = async (context) => {
|
|
|
39
39
|
...fetchDocPageMarkdown('docs/', 'system', `/system`).props,
|
|
40
40
|
components: components
|
|
41
41
|
? components.reduce(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
42
|
+
(acc, component) => ({
|
|
43
|
+
...acc,
|
|
44
|
+
...{
|
|
45
|
+
[component]: fetchDocPageMetadataAndContent('docs/components/', component).metadata,
|
|
46
|
+
},
|
|
47
|
+
}),
|
|
48
|
+
{}
|
|
49
|
+
)
|
|
50
50
|
: null,
|
|
51
51
|
} as ComponentPageDocumentationProps,
|
|
52
52
|
},
|
|
@@ -61,14 +61,14 @@ const ComponentsPage = ({ content, menu, metadata, current, config }: ComponentP
|
|
|
61
61
|
// Fetch components from api
|
|
62
62
|
const [components, setComponents] = useState<PreviewObject[]>(undefined);
|
|
63
63
|
const fetchComponents = async () => {
|
|
64
|
-
let data = await fetch(
|
|
64
|
+
let data = await fetch(`${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/components.json`).then((res) => res.json());
|
|
65
65
|
setComponents(data as PreviewObject[]);
|
|
66
66
|
};
|
|
67
67
|
useEffect(() => {
|
|
68
68
|
fetchComponents();
|
|
69
69
|
}, []);
|
|
70
70
|
if (!components) return <p>Loading...</p>;
|
|
71
|
-
const apiUrl = (window.location.origin && window.location.origin) +
|
|
71
|
+
const apiUrl = (window.location.origin && window.location.origin) + `${process.env.HANDOFF_APP_BASE_PATH ?? ''}/api/components.json`;
|
|
72
72
|
return (
|
|
73
73
|
<Layout config={config} menu={menu} current={current} metadata={metadata}>
|
|
74
74
|
<div className="flex flex-col gap-2 pb-7">
|
package/src/cli.ts
CHANGED
package/src/commands/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import ejectConfigCommand from './eject/config';
|
|
|
5
5
|
import ejectPagesCommand from './eject/pages';
|
|
6
6
|
import ejectThemeCommand from './eject/theme';
|
|
7
7
|
import fetchCommand from './fetch';
|
|
8
|
+
import initCommand from './init';
|
|
8
9
|
import makeComponentCommand from './make/component';
|
|
9
10
|
import makePageCommand from './make/page';
|
|
10
11
|
import makeTemplateCommand from './make/template';
|
|
@@ -20,6 +21,7 @@ export const commands = [
|
|
|
20
21
|
ejectPagesCommand,
|
|
21
22
|
ejectThemeCommand,
|
|
22
23
|
fetchCommand,
|
|
24
|
+
initCommand,
|
|
23
25
|
makePageCommand,
|
|
24
26
|
makeComponentCommand,
|
|
25
27
|
makeTemplateCommand,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CommandModule } from 'yargs';
|
|
2
|
+
import create from '../../create';
|
|
3
|
+
|
|
4
|
+
export interface InitArgs {}
|
|
5
|
+
|
|
6
|
+
const command: CommandModule<{}, InitArgs> = {
|
|
7
|
+
command: 'init',
|
|
8
|
+
describe: 'Initialize a new Handoff project with interactive wizard',
|
|
9
|
+
builder: (yargs) => {
|
|
10
|
+
return yargs;
|
|
11
|
+
},
|
|
12
|
+
handler: async () => {
|
|
13
|
+
await create();
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default command;
|