banhaten 0.1.2 → 0.1.3
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/README.md +93 -328
- package/banhaten.config.example.json +1 -1
- package/docs/design-system/README.md +11 -0
- package/docs/design-system/appearance-presets.md +184 -0
- package/docs/design-system/appearances/default.md +94 -0
- package/docs/design-system/appearances/rounded.md +95 -0
- package/docs/design-system/appearances/sharp.md +95 -0
- package/docs/design-system/component-showcase-consistency-report.md +217 -0
- package/docs/design-system/component-token-consistency-audit.md +163 -0
- package/docs/design-system/components/README.md +74 -0
- package/docs/design-system/components/accordion.md +51 -0
- package/docs/design-system/components/activity-feed.md +92 -0
- package/docs/design-system/components/alert-dialog.md +70 -0
- package/docs/design-system/components/alert.md +79 -0
- package/docs/design-system/components/aspect-ratio.md +44 -0
- package/docs/design-system/components/attribute.md +87 -0
- package/docs/design-system/components/autocomplete.md +74 -0
- package/docs/design-system/components/avatar.md +52 -0
- package/docs/design-system/components/badge.md +53 -0
- package/docs/design-system/components/banner.md +85 -0
- package/docs/design-system/components/breadcrumbs.md +174 -0
- package/docs/design-system/components/button-group.md +83 -0
- package/docs/design-system/components/button.md +77 -0
- package/docs/design-system/components/card.md +78 -0
- package/docs/design-system/components/carousel.md +44 -0
- package/docs/design-system/components/catalog-components.md +45 -0
- package/docs/design-system/components/chart.md +43 -0
- package/docs/design-system/components/checkbox.md +52 -0
- package/docs/design-system/components/collapsible.md +48 -0
- package/docs/design-system/components/command-bar.md +57 -0
- package/docs/design-system/components/command.md +60 -0
- package/docs/design-system/components/context-menu.md +44 -0
- package/docs/design-system/components/date-picker.md +77 -0
- package/docs/design-system/components/divider.md +101 -0
- package/docs/design-system/components/empty-state.md +55 -0
- package/docs/design-system/components/field.md +69 -0
- package/docs/design-system/components/file-upload.md +185 -0
- package/docs/design-system/components/hover-card.md +46 -0
- package/docs/design-system/components/icons.md +48 -0
- package/docs/design-system/components/input-group.md +56 -0
- package/docs/design-system/components/input-otp.md +55 -0
- package/docs/design-system/components/input.md +48 -0
- package/docs/design-system/components/kbd.md +44 -0
- package/docs/design-system/components/label.md +48 -0
- package/docs/design-system/components/menu.md +59 -0
- package/docs/design-system/components/menubar.md +45 -0
- package/docs/design-system/components/modal.md +98 -0
- package/docs/design-system/components/native-select.md +52 -0
- package/docs/design-system/components/navigation-menu.md +48 -0
- package/docs/design-system/components/onboarding-step-list-item.md +80 -0
- package/docs/design-system/components/page-header.md +84 -0
- package/docs/design-system/components/pagination.md +49 -0
- package/docs/design-system/components/popover.md +58 -0
- package/docs/design-system/components/progress-slider.md +48 -0
- package/docs/design-system/components/progress.md +75 -0
- package/docs/design-system/components/radio-card.md +49 -0
- package/docs/design-system/components/radio-group.md +55 -0
- package/docs/design-system/components/resizable.md +42 -0
- package/docs/design-system/components/scroll-area.md +45 -0
- package/docs/design-system/components/select.md +50 -0
- package/docs/design-system/components/sheet.md +65 -0
- package/docs/design-system/components/sidebar.md +68 -0
- package/docs/design-system/components/skeleton.md +73 -0
- package/docs/design-system/components/slideout.md +63 -0
- package/docs/design-system/components/slider.md +61 -0
- package/docs/design-system/components/social-button.md +47 -0
- package/docs/design-system/components/spinner.md +61 -0
- package/docs/design-system/components/steps.md +63 -0
- package/docs/design-system/components/table.md +397 -0
- package/docs/design-system/components/tabs.md +52 -0
- package/docs/design-system/components/tag.md +78 -0
- package/docs/design-system/components/textarea.md +48 -0
- package/docs/design-system/components/timeline.md +81 -0
- package/docs/design-system/components/toast.md +56 -0
- package/docs/design-system/components/toggle.md +79 -0
- package/docs/design-system/components/toolbar.md +85 -0
- package/docs/design-system/components/tooltip.md +90 -0
- package/docs/design-system/components/typography.md +18 -0
- package/docs/design-system/design-system-test-missing-items.md +368 -0
- package/docs/design-system/icons.md +69 -0
- package/docs/design-system/registry-and-cli.md +41 -0
- package/docs/design-system/tabs.md +53 -0
- package/docs/design-system/token-governance.md +38 -0
- package/package.json +83 -65
- package/registry/components/alert-dialog.tsx +297 -0
- package/registry/components/aspect-ratio.tsx +30 -0
- package/registry/components/carousel.tsx +234 -0
- package/registry/components/chart.tsx +170 -0
- package/registry/components/collapsible.tsx +69 -0
- package/registry/components/command.tsx +174 -0
- package/registry/components/context-menu.tsx +236 -0
- package/registry/components/date-picker.tsx +1 -1
- package/registry/components/expanded/PageHeader.tsx +1 -1
- package/registry/components/expanded/breadcrumbs.css +139 -139
- package/registry/components/expanded/catalogComponentsShowcase.css +83 -83
- package/registry/components/expanded/steps.css +274 -274
- package/registry/components/expanded/timeline.css +264 -264
- package/registry/components/field.tsx +230 -0
- package/registry/components/hover-card.tsx +48 -0
- package/registry/components/input-group.tsx +130 -0
- package/registry/components/input.tsx +2 -2
- package/registry/components/kbd.tsx +44 -0
- package/registry/components/label.tsx +78 -0
- package/registry/components/menu.tsx +3 -1
- package/registry/components/menubar.tsx +226 -0
- package/registry/components/modal.tsx +109 -76
- package/registry/components/native-select.tsx +205 -0
- package/registry/components/navigation-menu.tsx +171 -0
- package/registry/components/radio-group.tsx +1 -1
- package/registry/components/resizable.tsx +74 -0
- package/registry/components/scroll-area.tsx +67 -0
- package/registry/components/select.tsx +2 -4
- package/registry/components/sheet.tsx +305 -0
- package/registry/components/sidebar.tsx +352 -0
- package/registry/components/social-button.tsx +74 -10
- package/registry/components/{expanded/tabs.css → tabs.css} +127 -106
- package/registry/components/tabs.tsx +242 -0
- package/registry/components/textarea.tsx +1 -1
- package/registry/components/toast.tsx +131 -0
- package/registry/examples/alert-dialog-demo.tsx +42 -0
- package/registry/examples/aspect-ratio-demo.tsx +11 -0
- package/registry/examples/carousel-demo.tsx +25 -0
- package/registry/examples/chart-demo.tsx +33 -0
- package/registry/examples/collapsible-demo.tsx +16 -0
- package/registry/examples/command-demo.tsx +42 -0
- package/registry/examples/context-menu-demo.tsx +29 -0
- package/registry/examples/expanded/tabs-demo.tsx +1 -1
- package/registry/examples/field-demo.tsx +51 -0
- package/registry/examples/hover-card-demo.tsx +23 -0
- package/registry/examples/input-group-demo.tsx +16 -0
- package/registry/examples/kbd-demo.tsx +11 -0
- package/registry/examples/label-demo.tsx +20 -0
- package/registry/examples/menubar-demo.tsx +34 -0
- package/registry/examples/native-select-demo.tsx +16 -0
- package/registry/examples/navigation-menu-demo.tsx +29 -0
- package/registry/examples/resizable-demo.tsx +22 -0
- package/registry/examples/scroll-area-demo.tsx +15 -0
- package/registry/examples/sheet-demo.tsx +47 -0
- package/registry/examples/sidebar-demo.tsx +55 -0
- package/registry/examples/tabs-demo.tsx +13 -0
- package/registry/examples/toast-demo.tsx +35 -0
- package/registry/index.json +655 -11
- package/registry/styles/globals.css +4733 -4690
- package/registry.json +1612 -0
- package/schema/config.schema.json +48 -0
- package/schema/registry.schema.json +85 -0
- package/schema/tokens.schema.json +63 -0
- package/src/cli/index.js +312 -18
- package/tokens/banhaten.tokens.json +1 -1
- package/registry/assets/avatars/avatar-02.jpg +0 -0
- package/registry/assets/avatars/avatar-03.jpg +0 -0
- package/registry/assets/avatars/avatar-04.jpg +0 -0
- package/registry/assets/avatars/avatar-05.jpg +0 -0
- package/registry/assets/avatars/avatar-06.jpg +0 -0
- package/registry/assets/avatars/avatar-07.jpg +0 -0
- package/registry/assets/avatars/avatar-08.jpg +0 -0
- package/registry/assets/avatars/avatar-09.jpg +0 -0
- package/registry/assets/avatars/avatar-10.jpg +0 -0
- package/registry/assets/avatars/avatar-11.jpg +0 -0
- package/registry/assets/avatars/avatar-12.jpg +0 -0
- package/registry/assets/avatars/avatar-13.jpg +0 -0
- package/registry/assets/avatars/avatar-14.jpg +0 -0
- package/registry/assets/avatars/avatar-15.jpg +0 -0
- package/registry/assets/avatars/avatar-16.jpg +0 -0
- package/registry/assets/avatars/avatar-17.jpg +0 -0
- package/registry/assets/avatars/avatar-18.jpg +0 -0
- package/registry/assets/avatars/avatar-19.jpg +0 -0
- package/registry/assets/avatars/avatar-20.jpg +0 -0
- package/registry/assets/avatars/avatar-21.jpg +0 -0
- package/registry/assets/avatars/avatar-22.jpg +0 -0
- package/registry/assets/avatars/avatar-23.jpg +0 -0
- package/registry/assets/avatars/avatar-24.jpg +0 -0
- package/registry/assets/avatars/avatar-25.jpg +0 -0
- package/registry/assets/avatars/avatar-26.jpg +0 -0
- package/registry/assets/avatars/avatar-27.jpg +0 -0
- package/registry/assets/avatars/avatar-28.jpg +0 -0
- package/registry/assets/avatars/avatar-29.jpg +0 -0
- package/registry/assets/avatars/avatar-30.jpg +0 -0
- package/registry/assets/avatars/avatar-31.jpg +0 -0
- package/registry/assets/avatars/avatar-32.jpg +0 -0
- package/registry/assets/avatars/avatar-33.jpg +0 -0
- package/registry/assets/avatars/avatar-34.jpg +0 -0
- package/registry/assets/avatars/avatar-35.jpg +0 -0
- package/registry/assets/image-assets.json +0 -744
- package/registry/assets/images/art-02.jpg +0 -0
- package/registry/assets/images/art-03.jpg +0 -0
- package/registry/assets/images/art-04.jpg +0 -0
- package/registry/assets/images/art-05.jpg +0 -0
- package/registry/assets/images/art-06.jpg +0 -0
- package/registry/assets/images/art-07.jpg +0 -0
- package/registry/assets/images/art-08.jpg +0 -0
- package/registry/assets/images/art-09.jpg +0 -0
- package/registry/assets/images/art-10.jpg +0 -0
- package/registry/assets/images/art-11.jpg +0 -0
- package/registry/assets/images/art-12.jpg +0 -0
- package/registry/assets/images/art-13.jpg +0 -0
- package/registry/assets/images/art-14.jpg +0 -0
- package/registry/assets/images/art-15.jpg +0 -0
- package/registry/assets/images/art-16.jpg +0 -0
- package/registry/assets/images/art-17.jpg +0 -0
- package/registry/assets/images/art-18.jpg +0 -0
- package/registry/assets/images/art-19.jpg +0 -0
- package/registry/assets/images/art-20.jpg +0 -0
- package/registry/assets/images/art-21.jpg +0 -0
- package/registry/assets/images/art-22.jpg +0 -0
- package/registry/assets/images/art-23.jpg +0 -0
- package/registry/assets/images/art-24.jpg +0 -0
- package/registry/assets/images/art-25.jpg +0 -0
- package/registry/assets/images/art-26.jpg +0 -0
- package/registry/assets/images/art-27.jpg +0 -0
- package/registry/assets/images/nature-01.jpg +0 -0
- package/registry/assets/images/nature-02.jpg +0 -0
- package/registry/assets/images/nature-03.jpg +0 -0
- package/registry/assets/images/nature-04.jpg +0 -0
- package/registry/assets/images/nature-05.jpg +0 -0
- package/registry/assets/images/nature-06.jpg +0 -0
- package/registry/assets/images/nature-07.jpg +0 -0
- package/registry/assets/images/nature-08.jpg +0 -0
- package/registry/assets/images/nature-09.jpg +0 -0
- package/registry/assets/images/nature-10.jpg +0 -0
- package/registry/assets/images/nature-11.jpg +0 -0
- package/registry/assets/images/nature-12.jpg +0 -0
- package/registry/assets/images/nature-13.jpg +0 -0
- package/registry/assets/images/nature-14.jpg +0 -0
- package/registry/assets/images/nature-15.jpg +0 -0
- package/registry/assets/images/nature-16.jpg +0 -0
- package/registry/assets/images/nature-17.jpg +0 -0
- package/registry/assets/images/nature-18.jpg +0 -0
- package/registry/assets/images/nature-19.jpg +0 -0
- package/registry/assets/images/nature-20.jpg +0 -0
- package/registry/components/expanded/Tabs.tsx +0 -86
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "urn:banhaten:schema:config",
|
|
4
|
+
"title": "Banhaten CLI config",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"properties": {
|
|
8
|
+
"$schema": {
|
|
9
|
+
"type": "string"
|
|
10
|
+
},
|
|
11
|
+
"style": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"default": "default"
|
|
14
|
+
},
|
|
15
|
+
"tsx": {
|
|
16
|
+
"type": "boolean",
|
|
17
|
+
"default": true
|
|
18
|
+
},
|
|
19
|
+
"tailwind": {
|
|
20
|
+
"type": "object",
|
|
21
|
+
"additionalProperties": false,
|
|
22
|
+
"properties": {
|
|
23
|
+
"css": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "Path to the global CSS file that imports Tailwind and receives Banhaten tokens."
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"aliases": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"additionalProperties": false,
|
|
32
|
+
"properties": {
|
|
33
|
+
"ui": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"description": "Import alias where Banhaten UI components are installed."
|
|
36
|
+
},
|
|
37
|
+
"utils": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"description": "Import alias for the cn utility file."
|
|
40
|
+
},
|
|
41
|
+
"hooks": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"description": "Import alias for generated hooks."
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "urn:banhaten:schema:registry",
|
|
4
|
+
"title": "Banhaten registry index",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["name", "base", "components"],
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"$schema": {
|
|
10
|
+
"type": "string"
|
|
11
|
+
},
|
|
12
|
+
"name": {
|
|
13
|
+
"type": "string"
|
|
14
|
+
},
|
|
15
|
+
"base": {
|
|
16
|
+
"$ref": "#/$defs/registryEntry"
|
|
17
|
+
},
|
|
18
|
+
"components": {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"additionalProperties": {
|
|
21
|
+
"$ref": "#/$defs/registryEntry"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"$defs": {
|
|
26
|
+
"registryEntry": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"additionalProperties": true,
|
|
29
|
+
"properties": {
|
|
30
|
+
"description": {
|
|
31
|
+
"type": "string"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"additionalProperties": {
|
|
36
|
+
"type": "string"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"registryDependencies": {
|
|
40
|
+
"type": "array",
|
|
41
|
+
"items": {
|
|
42
|
+
"type": "string"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"parts": {
|
|
46
|
+
"type": "array",
|
|
47
|
+
"items": {
|
|
48
|
+
"type": "string"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"files": {
|
|
52
|
+
"type": "array",
|
|
53
|
+
"items": {
|
|
54
|
+
"$ref": "#/$defs/registryFile"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"examples": {
|
|
58
|
+
"type": "array",
|
|
59
|
+
"items": {
|
|
60
|
+
"type": "string"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"rtl": {
|
|
64
|
+
"type": "object",
|
|
65
|
+
"additionalProperties": {
|
|
66
|
+
"type": ["string", "boolean"]
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"registryFile": {
|
|
72
|
+
"type": "object",
|
|
73
|
+
"required": ["source", "target"],
|
|
74
|
+
"additionalProperties": false,
|
|
75
|
+
"properties": {
|
|
76
|
+
"source": {
|
|
77
|
+
"type": "string"
|
|
78
|
+
},
|
|
79
|
+
"target": {
|
|
80
|
+
"type": "string"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "urn:banhaten:schema:tokens",
|
|
4
|
+
"title": "Banhaten design tokens",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": ["name", "sourceStatus", "sourceFiles", "modes", "cssContract", "tokens"],
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"$schema": {
|
|
10
|
+
"type": "string"
|
|
11
|
+
},
|
|
12
|
+
"name": {
|
|
13
|
+
"type": "string"
|
|
14
|
+
},
|
|
15
|
+
"sourceStatus": {
|
|
16
|
+
"type": "string"
|
|
17
|
+
},
|
|
18
|
+
"sourceFiles": {
|
|
19
|
+
"type": "array",
|
|
20
|
+
"items": {
|
|
21
|
+
"type": "string"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"modes": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"additionalProperties": {
|
|
27
|
+
"type": "array",
|
|
28
|
+
"items": {
|
|
29
|
+
"type": "string"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"cssContract": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"required": ["semanticPrefix", "fontFamily", "defaultTheme", "defaultRadius"],
|
|
36
|
+
"additionalProperties": true,
|
|
37
|
+
"properties": {
|
|
38
|
+
"semanticPrefix": {
|
|
39
|
+
"type": "string"
|
|
40
|
+
},
|
|
41
|
+
"fontFamily": {
|
|
42
|
+
"type": "string"
|
|
43
|
+
},
|
|
44
|
+
"defaultTheme": {
|
|
45
|
+
"type": "string"
|
|
46
|
+
},
|
|
47
|
+
"defaultRadius": {
|
|
48
|
+
"type": "string"
|
|
49
|
+
},
|
|
50
|
+
"shadcnAliases": {
|
|
51
|
+
"type": "object",
|
|
52
|
+
"additionalProperties": {
|
|
53
|
+
"type": "string"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"tokens": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"additionalProperties": true
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
package/src/cli/index.js
CHANGED
|
@@ -12,6 +12,8 @@ const packageRoot = path.resolve(
|
|
|
12
12
|
)
|
|
13
13
|
const registryRoot = path.join(packageRoot, "registry")
|
|
14
14
|
const registryIndexPath = path.join(registryRoot, "index.json")
|
|
15
|
+
const packageJsonPath = path.join(packageRoot, "package.json")
|
|
16
|
+
const schemaRoot = path.join(packageRoot, "schema")
|
|
15
17
|
|
|
16
18
|
const CONFIG_FILE = "banhaten.config.json"
|
|
17
19
|
const FONT_IMPORTS = [
|
|
@@ -30,9 +32,14 @@ const VITE_DEV_DEPENDENCIES = {
|
|
|
30
32
|
const CSS_START = "/* Banhaten design system tokens:"
|
|
31
33
|
const CSS_END = "/* End Banhaten design system tokens. */"
|
|
32
34
|
const syncExistsCache = new Map()
|
|
35
|
+
const VALUE_FLAGS = new Set(["cwd", "file", "format"])
|
|
36
|
+
let runtimeOptions = {
|
|
37
|
+
json: false,
|
|
38
|
+
silent: false,
|
|
39
|
+
}
|
|
33
40
|
|
|
34
41
|
const DEFAULT_CONFIG = {
|
|
35
|
-
$schema: "
|
|
42
|
+
$schema: ".banhaten/schema/config.schema.json",
|
|
36
43
|
style: "default",
|
|
37
44
|
tsx: true,
|
|
38
45
|
tailwind: {
|
|
@@ -46,6 +53,7 @@ const DEFAULT_CONFIG = {
|
|
|
46
53
|
}
|
|
47
54
|
|
|
48
55
|
const registry = await readJson(registryIndexPath)
|
|
56
|
+
const packageManifest = await readJson(packageJsonPath)
|
|
49
57
|
|
|
50
58
|
main().catch((error) => {
|
|
51
59
|
console.error(`banhaten: ${error.message}`)
|
|
@@ -54,6 +62,15 @@ main().catch((error) => {
|
|
|
54
62
|
|
|
55
63
|
async function main() {
|
|
56
64
|
const { command, positionals, flags } = parseArgs(process.argv.slice(2))
|
|
65
|
+
runtimeOptions = {
|
|
66
|
+
json: Boolean(flags.json),
|
|
67
|
+
silent: Boolean(flags.silent || flags.s),
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (command === "version" || flags.version || flags.v) {
|
|
71
|
+
console.log(packageManifest.version)
|
|
72
|
+
return
|
|
73
|
+
}
|
|
57
74
|
|
|
58
75
|
if (!command || command === "help" || flags.help || flags.h) {
|
|
59
76
|
printHelp()
|
|
@@ -61,7 +78,22 @@ async function main() {
|
|
|
61
78
|
}
|
|
62
79
|
|
|
63
80
|
if (command === "list") {
|
|
64
|
-
listComponents()
|
|
81
|
+
listComponents(flags)
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (command === "search") {
|
|
86
|
+
searchComponents(positionals, flags)
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (command === "docs") {
|
|
91
|
+
showComponentDocs(positionals, flags)
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (command === "view") {
|
|
96
|
+
await viewComponent(positionals, flags)
|
|
65
97
|
return
|
|
66
98
|
}
|
|
67
99
|
|
|
@@ -100,6 +132,21 @@ function parseArgs(argv) {
|
|
|
100
132
|
continue
|
|
101
133
|
}
|
|
102
134
|
|
|
135
|
+
if (arg === "-s") {
|
|
136
|
+
flags.s = true
|
|
137
|
+
continue
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (arg === "-v") {
|
|
141
|
+
flags.v = true
|
|
142
|
+
continue
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (arg === "-y") {
|
|
146
|
+
flags.yes = true
|
|
147
|
+
continue
|
|
148
|
+
}
|
|
149
|
+
|
|
103
150
|
if (!arg.startsWith("--")) {
|
|
104
151
|
positionals.push(arg)
|
|
105
152
|
continue
|
|
@@ -114,7 +161,7 @@ function parseArgs(argv) {
|
|
|
114
161
|
}
|
|
115
162
|
|
|
116
163
|
const next = argv[index + 1]
|
|
117
|
-
if ((key
|
|
164
|
+
if (VALUE_FLAGS.has(key) && next && !next.startsWith("-")) {
|
|
118
165
|
flags[key] = next
|
|
119
166
|
index += 1
|
|
120
167
|
continue
|
|
@@ -135,24 +182,196 @@ Usage:
|
|
|
135
182
|
banhaten add <component...> [--cwd <path>] [--force] [--dry-run]
|
|
136
183
|
banhaten diff [component...] [--cwd <path>] [--force]
|
|
137
184
|
banhaten update [component...] [--cwd <path>] [--force] [--dry-run]
|
|
138
|
-
banhaten list
|
|
185
|
+
banhaten list [--json]
|
|
186
|
+
banhaten search <query> [--json]
|
|
187
|
+
banhaten docs <component> [--json]
|
|
188
|
+
banhaten view <component> [--file <registry-source>] [--json]
|
|
189
|
+
banhaten version
|
|
139
190
|
|
|
140
191
|
Examples:
|
|
141
192
|
npx banhaten init
|
|
142
193
|
npx banhaten add button
|
|
143
194
|
npx banhaten diff
|
|
144
195
|
npx banhaten update button
|
|
196
|
+
npx banhaten search input
|
|
197
|
+
npx banhaten docs button
|
|
198
|
+
npx banhaten view button
|
|
199
|
+
|
|
200
|
+
Global flags:
|
|
201
|
+
--cwd <path> Run against a project directory.
|
|
202
|
+
--dry-run Preview writes without changing files.
|
|
203
|
+
--force Rewrite generated files even when already current.
|
|
204
|
+
--json Print machine-readable output where supported.
|
|
205
|
+
--silent, -s Suppress normal command output.
|
|
206
|
+
--yes, -y Accepted for non-interactive scripts.
|
|
207
|
+
--version, -v Print the installed CLI version.
|
|
145
208
|
`)
|
|
146
209
|
}
|
|
147
210
|
|
|
148
211
|
function listComponents() {
|
|
149
|
-
const
|
|
212
|
+
const components = Object.entries(registry.components).map(([name, component]) => ({
|
|
213
|
+
name,
|
|
214
|
+
description: component.description || "",
|
|
215
|
+
dependencies: Object.keys(component.dependencies || {}),
|
|
216
|
+
registryDependencies: component.registryDependencies || [],
|
|
217
|
+
}))
|
|
218
|
+
|
|
219
|
+
if (runtimeOptions.json) {
|
|
220
|
+
writeJson({ components })
|
|
221
|
+
return
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (runtimeOptions.silent) return
|
|
150
225
|
|
|
151
226
|
console.log("Available Banhaten design system components:")
|
|
152
|
-
for (const name of
|
|
153
|
-
|
|
154
|
-
|
|
227
|
+
for (const { name, description } of components) {
|
|
228
|
+
console.log(`- ${name}: ${description}`)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function searchComponents(positionals) {
|
|
233
|
+
const query = positionals.join(" ").trim().toLowerCase()
|
|
234
|
+
if (!query) {
|
|
235
|
+
throw new Error("missing search query. Try `banhaten search input`.")
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const matches = Object.entries(registry.components)
|
|
239
|
+
.filter(([name, component]) => {
|
|
240
|
+
const haystack = [
|
|
241
|
+
name,
|
|
242
|
+
component.description,
|
|
243
|
+
...(component.parts || []),
|
|
244
|
+
...(component.registryDependencies || []),
|
|
245
|
+
]
|
|
246
|
+
.filter(Boolean)
|
|
247
|
+
.join(" ")
|
|
248
|
+
.toLowerCase()
|
|
249
|
+
|
|
250
|
+
return haystack.includes(query)
|
|
251
|
+
})
|
|
252
|
+
.map(([name, component]) => ({
|
|
253
|
+
name,
|
|
254
|
+
description: component.description || "",
|
|
255
|
+
parts: component.parts || [],
|
|
256
|
+
}))
|
|
257
|
+
|
|
258
|
+
if (runtimeOptions.json) {
|
|
259
|
+
writeJson({ query, matches })
|
|
260
|
+
return
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (runtimeOptions.silent) return
|
|
264
|
+
|
|
265
|
+
if (matches.length === 0) {
|
|
266
|
+
console.log(`No Banhaten components matched "${query}".`)
|
|
267
|
+
return
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
console.log(`Banhaten components matching "${query}":`)
|
|
271
|
+
for (const match of matches) {
|
|
272
|
+
console.log(`- ${match.name}: ${match.description}`)
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function showComponentDocs(positionals) {
|
|
277
|
+
const [name] = positionals
|
|
278
|
+
const component = getComponentOrThrow(name)
|
|
279
|
+
const docsPath = getComponentDocPath(name)
|
|
280
|
+
const result = {
|
|
281
|
+
name,
|
|
282
|
+
description: component.description || "",
|
|
283
|
+
install: `npx banhaten add ${name}`,
|
|
284
|
+
docsPath,
|
|
285
|
+
files: component.files || [],
|
|
286
|
+
examples: component.examples || [],
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (runtimeOptions.json) {
|
|
290
|
+
writeJson(result)
|
|
291
|
+
return
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (runtimeOptions.silent) return
|
|
295
|
+
|
|
296
|
+
console.log(`${name}: ${result.description}`)
|
|
297
|
+
console.log(`Install: ${result.install}`)
|
|
298
|
+
console.log(`Docs: ${docsPath}`)
|
|
299
|
+
|
|
300
|
+
if (result.files.length > 0) {
|
|
301
|
+
console.log("Files:")
|
|
302
|
+
for (const file of result.files) {
|
|
303
|
+
console.log(`- ${file.source} -> ${file.target}`)
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if (result.examples.length > 0) {
|
|
308
|
+
console.log("Examples:")
|
|
309
|
+
for (const example of result.examples) {
|
|
310
|
+
console.log(`- ${example}`)
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
async function viewComponent(positionals, flags) {
|
|
316
|
+
const [name] = positionals
|
|
317
|
+
const component = getComponentOrThrow(name)
|
|
318
|
+
const files = component.files || []
|
|
319
|
+
const requestedFile = typeof flags.file === "string" ? flags.file : null
|
|
320
|
+
const file =
|
|
321
|
+
(requestedFile
|
|
322
|
+
? files.find((entry) => entry.source === requestedFile)
|
|
323
|
+
: files.find((entry) => /\.(ts|tsx|css)$/.test(entry.source)) || files[0]) ||
|
|
324
|
+
null
|
|
325
|
+
|
|
326
|
+
if (!file) {
|
|
327
|
+
throw new Error(`component "${name}" has no viewable registry files.`)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
const sourcePath = path.join(registryRoot, file.source)
|
|
331
|
+
const content = await fs.readFile(
|
|
332
|
+
sourcePath,
|
|
333
|
+
isTextRegistryFile(file.source) ? "utf8" : undefined
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
if (runtimeOptions.json) {
|
|
337
|
+
writeJson({
|
|
338
|
+
name,
|
|
339
|
+
file,
|
|
340
|
+
content: Buffer.isBuffer(content) ? content.toString("base64") : content,
|
|
341
|
+
encoding: Buffer.isBuffer(content) ? "base64" : "utf8",
|
|
342
|
+
})
|
|
343
|
+
return
|
|
155
344
|
}
|
|
345
|
+
|
|
346
|
+
if (runtimeOptions.silent) return
|
|
347
|
+
|
|
348
|
+
console.log(Buffer.isBuffer(content) ? content.toString("base64") : content)
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function getComponentOrThrow(name) {
|
|
352
|
+
if (!name) {
|
|
353
|
+
throw new Error("missing component name. Try `banhaten docs button`.")
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const component = registry.components[name]
|
|
357
|
+
if (!component) {
|
|
358
|
+
throw new Error(`unknown component "${name}". Run \`banhaten list\`.`)
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return component
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function getComponentDocPath(name) {
|
|
365
|
+
const docAliases = {
|
|
366
|
+
"onboarding-step": "onboarding-step-list-item",
|
|
367
|
+
}
|
|
368
|
+
const docId = docAliases[name] || name
|
|
369
|
+
|
|
370
|
+
return `docs/design-system/components/${docId}.md`
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function writeJson(value) {
|
|
374
|
+
console.log(JSON.stringify(value, null, 2))
|
|
156
375
|
}
|
|
157
376
|
|
|
158
377
|
async function initProject(flags) {
|
|
@@ -165,6 +384,7 @@ async function initProject(flags) {
|
|
|
165
384
|
|
|
166
385
|
writes.push(
|
|
167
386
|
...(await writeConfig(cwd, config, { dryRun, force })),
|
|
387
|
+
...(await writeProjectSchemaFiles(cwd, { dryRun, force })),
|
|
168
388
|
...(await writeBaseFiles(cwd, config, { dryRun, force })),
|
|
169
389
|
...(await writeGlobalCss(cwd, config, { dryRun, force })),
|
|
170
390
|
...(await writeAliasConfig(cwd, config, { dryRun, force }))
|
|
@@ -178,7 +398,7 @@ async function initProject(flags) {
|
|
|
178
398
|
writes.push(...dependencyWrites)
|
|
179
399
|
|
|
180
400
|
printResult("Initialized Banhaten design system", writes, dryRun)
|
|
181
|
-
printInstallHint(writes, dryRun)
|
|
401
|
+
await printInstallHint(cwd, writes, dryRun)
|
|
182
402
|
}
|
|
183
403
|
|
|
184
404
|
async function addComponents(names, flags) {
|
|
@@ -236,7 +456,9 @@ async function writeComponents(requestedNames, flags, options) {
|
|
|
236
456
|
|
|
237
457
|
writes.push(
|
|
238
458
|
...(await writeConfig(cwd, config, { dryRun, force })),
|
|
459
|
+
...(await writeProjectSchemaFiles(cwd, { dryRun, force })),
|
|
239
460
|
...(await writeBaseFiles(cwd, config, { dryRun, force })),
|
|
461
|
+
...(await writeGlobalCss(cwd, config, { dryRun, force })),
|
|
240
462
|
...(await writeAliasConfig(cwd, config, { dryRun, force }))
|
|
241
463
|
)
|
|
242
464
|
|
|
@@ -262,7 +484,7 @@ async function writeComponents(requestedNames, flags, options) {
|
|
|
262
484
|
)))
|
|
263
485
|
|
|
264
486
|
printResult(options.title, writes, dryRun)
|
|
265
|
-
printInstallHint(writes, dryRun)
|
|
487
|
+
await printInstallHint(cwd, writes, dryRun)
|
|
266
488
|
}
|
|
267
489
|
|
|
268
490
|
async function findInstalledComponents(cwd, config) {
|
|
@@ -371,6 +593,24 @@ async function detectCssPath(cwd, fallback) {
|
|
|
371
593
|
async function writeConfig(cwd, config, options) {
|
|
372
594
|
const configPath = path.join(cwd, CONFIG_FILE)
|
|
373
595
|
if ((await exists(configPath)) && !options.force) {
|
|
596
|
+
const current = await fs.readFile(configPath, "utf8")
|
|
597
|
+
const currentConfig = JSON.parse(current)
|
|
598
|
+
|
|
599
|
+
if (currentConfig.$schema !== DEFAULT_CONFIG.$schema) {
|
|
600
|
+
const nextConfig = {
|
|
601
|
+
$schema: DEFAULT_CONFIG.$schema,
|
|
602
|
+
...currentConfig,
|
|
603
|
+
}
|
|
604
|
+
nextConfig.$schema = DEFAULT_CONFIG.$schema
|
|
605
|
+
const status = await writeFile(
|
|
606
|
+
configPath,
|
|
607
|
+
`${JSON.stringify(nextConfig, null, 2)}\n`,
|
|
608
|
+
{ dryRun: options.dryRun }
|
|
609
|
+
)
|
|
610
|
+
|
|
611
|
+
return [`${status} ${relative(cwd, configPath)}`]
|
|
612
|
+
}
|
|
613
|
+
|
|
374
614
|
return [`kept ${relative(cwd, configPath)}`]
|
|
375
615
|
}
|
|
376
616
|
|
|
@@ -382,6 +622,26 @@ async function writeConfig(cwd, config, options) {
|
|
|
382
622
|
return [`${status} ${relative(cwd, configPath)}`]
|
|
383
623
|
}
|
|
384
624
|
|
|
625
|
+
async function writeProjectSchemaFiles(cwd, options) {
|
|
626
|
+
const schemaFiles = [
|
|
627
|
+
"config.schema.json",
|
|
628
|
+
"registry.schema.json",
|
|
629
|
+
"tokens.schema.json",
|
|
630
|
+
]
|
|
631
|
+
const writes = []
|
|
632
|
+
|
|
633
|
+
for (const schemaFile of schemaFiles) {
|
|
634
|
+
const sourcePath = path.join(schemaRoot, schemaFile)
|
|
635
|
+
const targetPath = path.join(cwd, ".banhaten", "schema", schemaFile)
|
|
636
|
+
const source = await fs.readFile(sourcePath, "utf8")
|
|
637
|
+
const status = await writeFile(targetPath, source, options)
|
|
638
|
+
|
|
639
|
+
writes.push(`${status} ${relative(cwd, targetPath)}`)
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
return writes
|
|
643
|
+
}
|
|
644
|
+
|
|
385
645
|
async function writeBaseFiles(cwd, config, options) {
|
|
386
646
|
return writeRegistryFiles(cwd, config, registry.base.files || [], options)
|
|
387
647
|
}
|
|
@@ -413,16 +673,12 @@ async function writeGlobalCss(cwd, config, options) {
|
|
|
413
673
|
? removeExistingTokenBlock(current, relative(cwd, cssPath))
|
|
414
674
|
: { content: "", found: false }
|
|
415
675
|
|
|
416
|
-
if (tokenBlock.found && !options.force) {
|
|
417
|
-
return [`kept ${relative(cwd, cssPath)}`]
|
|
418
|
-
}
|
|
419
|
-
|
|
420
676
|
const nextCss = current
|
|
421
677
|
? `${tokenBlock.content.trimEnd()}\n\n${tokenCss}\n`
|
|
422
678
|
: `${tokenCss}\n`
|
|
423
679
|
const next = ensureGlobalCssImports(nextCss)
|
|
424
680
|
|
|
425
|
-
const status = await writeFile(cssPath, next,
|
|
681
|
+
const status = await writeFile(cssPath, next, options)
|
|
426
682
|
return [`${status} ${relative(cwd, cssPath)}`]
|
|
427
683
|
}
|
|
428
684
|
|
|
@@ -1742,20 +1998,58 @@ function relative(cwd, targetPath) {
|
|
|
1742
1998
|
}
|
|
1743
1999
|
|
|
1744
2000
|
function printResult(title, writes, dryRun) {
|
|
2001
|
+
if (runtimeOptions.json) {
|
|
2002
|
+
writeJson({ dryRun, title, writes })
|
|
2003
|
+
return
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
if (runtimeOptions.silent) return
|
|
2007
|
+
|
|
1745
2008
|
console.log(`${dryRun ? "Dry run: " : ""}${title}`)
|
|
1746
2009
|
for (const write of writes) {
|
|
1747
2010
|
console.log(`- ${write}`)
|
|
1748
2011
|
}
|
|
1749
2012
|
}
|
|
1750
2013
|
|
|
1751
|
-
function printInstallHint(writes, dryRun) {
|
|
1752
|
-
if (dryRun) return
|
|
2014
|
+
async function printInstallHint(cwd, writes, dryRun) {
|
|
2015
|
+
if (dryRun || runtimeOptions.json || runtimeOptions.silent) return
|
|
1753
2016
|
|
|
1754
2017
|
const packageJsonChanged = writes.some((write) =>
|
|
1755
2018
|
/^(wrote|updated) package\.json$/.test(write)
|
|
1756
2019
|
)
|
|
1757
2020
|
|
|
1758
2021
|
if (packageJsonChanged) {
|
|
1759
|
-
console.log(
|
|
2022
|
+
console.log(`\nNext: run ${await getInstallCommand(cwd)} to install the added dependencies.`)
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
async function getInstallCommand(cwd) {
|
|
2027
|
+
const packageJson = await readJsonIfExists(path.join(cwd, "package.json"))
|
|
2028
|
+
const declaredPackageManager = parsePackageManager(packageJson?.packageManager)
|
|
2029
|
+
|
|
2030
|
+
if (declaredPackageManager) return `${declaredPackageManager} install`
|
|
2031
|
+
|
|
2032
|
+
const lockfileManagers = [
|
|
2033
|
+
["pnpm-lock.yaml", "pnpm"],
|
|
2034
|
+
["yarn.lock", "yarn"],
|
|
2035
|
+
["bun.lockb", "bun"],
|
|
2036
|
+
["bun.lock", "bun"],
|
|
2037
|
+
["package-lock.json", "npm"],
|
|
2038
|
+
["npm-shrinkwrap.json", "npm"],
|
|
2039
|
+
]
|
|
2040
|
+
|
|
2041
|
+
for (const [lockfile, manager] of lockfileManagers) {
|
|
2042
|
+
if (await exists(path.join(cwd, lockfile))) return `${manager} install`
|
|
1760
2043
|
}
|
|
2044
|
+
|
|
2045
|
+
return "npm install"
|
|
2046
|
+
}
|
|
2047
|
+
|
|
2048
|
+
function parsePackageManager(packageManager) {
|
|
2049
|
+
if (typeof packageManager !== "string") return null
|
|
2050
|
+
|
|
2051
|
+
const name = packageManager.split("@")[0]
|
|
2052
|
+
if (["npm", "pnpm", "yarn", "bun"].includes(name)) return name
|
|
2053
|
+
|
|
2054
|
+
return null
|
|
1761
2055
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|