@discourser/design-system 0.25.1 → 0.25.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/dist/figma-codex/resolver.d.ts.map +1 -1
- package/dist/figma-codex.json +290 -14
- package/package.json +19 -6
- package/src/figma-codex/resolver.ts +116 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/figma-codex/resolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/figma-codex/resolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,UAAU,CAAC;AA8SlB,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,gBAAgB,GACvB,cAAc,CAyEhB"}
|
package/dist/figma-codex.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": "1.0.0",
|
|
3
3
|
"packageName": "@discourser/design-system",
|
|
4
|
-
"generatedAt": "2026-03-
|
|
5
|
-
"gitHash": "
|
|
4
|
+
"generatedAt": "2026-03-31T23:00:26.390Z",
|
|
5
|
+
"gitHash": "73dd9324",
|
|
6
6
|
"figmaFiles": {
|
|
7
7
|
"GaHmFfmvO4loUzuZS4TgEz": {
|
|
8
8
|
"fileKey": "GaHmFfmvO4loUzuZS4TgEz"
|
|
@@ -20,7 +20,13 @@
|
|
|
20
20
|
"imports": {
|
|
21
21
|
"primary": "import * as Accordion from '@discourser/design-system/Accordion'",
|
|
22
22
|
"namedExports": [
|
|
23
|
-
"Accordion.ItemBody"
|
|
23
|
+
"Accordion.ItemBody",
|
|
24
|
+
"Accordion.Root",
|
|
25
|
+
"Accordion.RootProvider",
|
|
26
|
+
"Accordion.Item",
|
|
27
|
+
"Accordion.ItemContent",
|
|
28
|
+
"Accordion.ItemIndicator",
|
|
29
|
+
"Accordion.ItemTrigger"
|
|
24
30
|
],
|
|
25
31
|
"subpath": "@discourser/design-system/Accordion"
|
|
26
32
|
},
|
|
@@ -29,6 +35,30 @@
|
|
|
29
35
|
{
|
|
30
36
|
"name": "ItemBody",
|
|
31
37
|
"element": "div"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "Root",
|
|
41
|
+
"element": "root"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "RootProvider",
|
|
45
|
+
"element": "root"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "Item",
|
|
49
|
+
"element": "item"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "ItemContent",
|
|
53
|
+
"element": "itemContent"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "ItemIndicator",
|
|
57
|
+
"element": "itemIndicator"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "ItemTrigger",
|
|
61
|
+
"element": "itemTrigger"
|
|
32
62
|
}
|
|
33
63
|
],
|
|
34
64
|
"example": "<Accordion.Root collapsible>\n <Accordion.Item value=\"item-1\">\n <Accordion.ItemTrigger>\n <span>Trigger</span>\n <Accordion.ItemIndicator />\n </Accordion.ItemTrigger>\n <Accordion.ItemContent>Content</Accordion.ItemContent>\n </Accordion.Item>\n </Accordion.Root>",
|
|
@@ -307,7 +337,8 @@
|
|
|
307
337
|
"primary": "import { Header } from '@discourser/design-system/Header'",
|
|
308
338
|
"namedExports": [
|
|
309
339
|
"Header"
|
|
310
|
-
]
|
|
340
|
+
],
|
|
341
|
+
"subpath": "@discourser/design-system/Header"
|
|
311
342
|
},
|
|
312
343
|
"props": [],
|
|
313
344
|
"example": "<Header size={size}>Heading Text</Header>",
|
|
@@ -716,11 +747,91 @@
|
|
|
716
747
|
},
|
|
717
748
|
"imports": {
|
|
718
749
|
"primary": "import * as RadioGroup from '@discourser/design-system/RadioGroup'",
|
|
719
|
-
"namedExports": [
|
|
750
|
+
"namedExports": [
|
|
751
|
+
"RadioGroup.Root",
|
|
752
|
+
"RadioGroup.RootProvider",
|
|
753
|
+
"RadioGroup.Indicator",
|
|
754
|
+
"RadioGroup.Item",
|
|
755
|
+
"RadioGroup.ItemControl",
|
|
756
|
+
"RadioGroup.ItemText",
|
|
757
|
+
"RadioGroup.Label"
|
|
758
|
+
],
|
|
720
759
|
"subpath": "@discourser/design-system/RadioGroup"
|
|
721
760
|
},
|
|
722
|
-
"props": [
|
|
723
|
-
|
|
761
|
+
"props": [
|
|
762
|
+
{
|
|
763
|
+
"name": "value",
|
|
764
|
+
"type": "string",
|
|
765
|
+
"required": false,
|
|
766
|
+
"description": "controlled selected value (string)"
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
"name": "defaultValue",
|
|
770
|
+
"type": "string",
|
|
771
|
+
"required": false,
|
|
772
|
+
"description": "uncontrolled initial value (string)"
|
|
773
|
+
},
|
|
774
|
+
{
|
|
775
|
+
"name": "onValueChange",
|
|
776
|
+
"type": "({ value }: { value: string }) => void",
|
|
777
|
+
"required": false,
|
|
778
|
+
"description": "callback ({ value }: { value: string }) => void"
|
|
779
|
+
},
|
|
780
|
+
{
|
|
781
|
+
"name": "disabled",
|
|
782
|
+
"type": "boolean",
|
|
783
|
+
"required": false,
|
|
784
|
+
"description": "boolean, disables all items"
|
|
785
|
+
},
|
|
786
|
+
{
|
|
787
|
+
"name": "orientation",
|
|
788
|
+
"type": "'horizontal' | 'vertical'",
|
|
789
|
+
"required": false,
|
|
790
|
+
"description": "'horizontal' | 'vertical' (default: 'vertical')"
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
"name": "value",
|
|
794
|
+
"type": "string",
|
|
795
|
+
"required": false,
|
|
796
|
+
"description": "required unique string for this option"
|
|
797
|
+
},
|
|
798
|
+
{
|
|
799
|
+
"name": "disabled",
|
|
800
|
+
"type": "boolean",
|
|
801
|
+
"required": false,
|
|
802
|
+
"description": "boolean, disables this item only"
|
|
803
|
+
}
|
|
804
|
+
],
|
|
805
|
+
"subComponents": [
|
|
806
|
+
{
|
|
807
|
+
"name": "Root",
|
|
808
|
+
"element": "root"
|
|
809
|
+
},
|
|
810
|
+
{
|
|
811
|
+
"name": "RootProvider",
|
|
812
|
+
"element": "root"
|
|
813
|
+
},
|
|
814
|
+
{
|
|
815
|
+
"name": "Indicator",
|
|
816
|
+
"element": "indicator"
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
"name": "Item",
|
|
820
|
+
"element": "item"
|
|
821
|
+
},
|
|
822
|
+
{
|
|
823
|
+
"name": "ItemControl",
|
|
824
|
+
"element": "itemControl"
|
|
825
|
+
},
|
|
826
|
+
{
|
|
827
|
+
"name": "ItemText",
|
|
828
|
+
"element": "itemText"
|
|
829
|
+
},
|
|
830
|
+
{
|
|
831
|
+
"name": "Label",
|
|
832
|
+
"element": "label"
|
|
833
|
+
}
|
|
834
|
+
],
|
|
724
835
|
"example": "<RadioGroup.Root defaultValue=\"option-1\">\n <RadioGroup.Item value=\"option-1\">\n <RadioGroup.ItemControl />\n <RadioGroup.ItemText>Option 1</RadioGroup.ItemText>\n </RadioGroup.Item>\n <RadioGroup.Item value=\"option-2\">\n <RadioGroup.ItemControl />\n <RadioGroup.ItemText>Option 2</RadioGroup.ItemText>\n </RadioGroup.Item>\n <RadioGroup.Item value=\"option-3\">\n <RadioGroup.ItemControl />\n <RadioGroup.ItemText>Option 3</RadioGroup.ItemText>\n </RadioGroup.Item>\n </RadioGroup.Root>",
|
|
725
836
|
"sourcePath": "src/components/RadioGroup.tsx",
|
|
726
837
|
"tokens": {
|
|
@@ -931,11 +1042,128 @@
|
|
|
931
1042
|
},
|
|
932
1043
|
"imports": {
|
|
933
1044
|
"primary": "import * as Slider from '@discourser/design-system/Slider'",
|
|
934
|
-
"namedExports": [
|
|
1045
|
+
"namedExports": [
|
|
1046
|
+
"Slider.Control",
|
|
1047
|
+
"Slider.Track",
|
|
1048
|
+
"Slider.Range",
|
|
1049
|
+
"Slider.Root",
|
|
1050
|
+
"Slider.Thumb",
|
|
1051
|
+
"Slider.Label",
|
|
1052
|
+
"Slider.ValueText",
|
|
1053
|
+
"Slider.Marker",
|
|
1054
|
+
"Slider.MarkerGroup",
|
|
1055
|
+
"Slider.MarkerIndicator",
|
|
1056
|
+
"Slider.DraggingIndicator",
|
|
1057
|
+
"Slider.Marks"
|
|
1058
|
+
],
|
|
935
1059
|
"subpath": "@discourser/design-system/Slider"
|
|
936
1060
|
},
|
|
937
|
-
"props": [
|
|
938
|
-
|
|
1061
|
+
"props": [
|
|
1062
|
+
{
|
|
1063
|
+
"name": "defaultValue",
|
|
1064
|
+
"type": "string",
|
|
1065
|
+
"required": false,
|
|
1066
|
+
"description": "uncontrolled initial value array, e.g. [50]"
|
|
1067
|
+
},
|
|
1068
|
+
{
|
|
1069
|
+
"name": "value",
|
|
1070
|
+
"type": "string",
|
|
1071
|
+
"required": false,
|
|
1072
|
+
"description": "controlled value array, e.g. [50]"
|
|
1073
|
+
},
|
|
1074
|
+
{
|
|
1075
|
+
"name": "onValueChange",
|
|
1076
|
+
"type": "({ value }: { value: number[] }) => void",
|
|
1077
|
+
"required": false,
|
|
1078
|
+
"description": "callback ({ value }: { value: number[] }) => void"
|
|
1079
|
+
},
|
|
1080
|
+
{
|
|
1081
|
+
"name": "min",
|
|
1082
|
+
"type": "string",
|
|
1083
|
+
"required": false,
|
|
1084
|
+
"description": "number (default: 0)"
|
|
1085
|
+
},
|
|
1086
|
+
{
|
|
1087
|
+
"name": "max",
|
|
1088
|
+
"type": "string",
|
|
1089
|
+
"required": false,
|
|
1090
|
+
"description": "number (default: 100)"
|
|
1091
|
+
},
|
|
1092
|
+
{
|
|
1093
|
+
"name": "step",
|
|
1094
|
+
"type": "string",
|
|
1095
|
+
"required": false,
|
|
1096
|
+
"description": "number (default: 1)"
|
|
1097
|
+
},
|
|
1098
|
+
{
|
|
1099
|
+
"name": "orientation",
|
|
1100
|
+
"type": "'horizontal' | 'vertical'",
|
|
1101
|
+
"required": false,
|
|
1102
|
+
"description": "'horizontal' | 'vertical' (default: 'horizontal')"
|
|
1103
|
+
},
|
|
1104
|
+
{
|
|
1105
|
+
"name": "disabled",
|
|
1106
|
+
"type": "boolean",
|
|
1107
|
+
"required": false,
|
|
1108
|
+
"description": "boolean"
|
|
1109
|
+
},
|
|
1110
|
+
{
|
|
1111
|
+
"name": "colorPalette",
|
|
1112
|
+
"type": "'primary' | 'secondary' | 'tertiary' | 'neutral' | 'error'",
|
|
1113
|
+
"required": false,
|
|
1114
|
+
"description": "'primary' | 'secondary' | 'tertiary' | 'neutral' | 'error'"
|
|
1115
|
+
}
|
|
1116
|
+
],
|
|
1117
|
+
"subComponents": [
|
|
1118
|
+
{
|
|
1119
|
+
"name": "Control",
|
|
1120
|
+
"element": "control"
|
|
1121
|
+
},
|
|
1122
|
+
{
|
|
1123
|
+
"name": "Track",
|
|
1124
|
+
"element": "track"
|
|
1125
|
+
},
|
|
1126
|
+
{
|
|
1127
|
+
"name": "Range",
|
|
1128
|
+
"element": "range"
|
|
1129
|
+
},
|
|
1130
|
+
{
|
|
1131
|
+
"name": "Root",
|
|
1132
|
+
"element": "div"
|
|
1133
|
+
},
|
|
1134
|
+
{
|
|
1135
|
+
"name": "Thumb",
|
|
1136
|
+
"element": "div"
|
|
1137
|
+
},
|
|
1138
|
+
{
|
|
1139
|
+
"name": "Label",
|
|
1140
|
+
"element": "label"
|
|
1141
|
+
},
|
|
1142
|
+
{
|
|
1143
|
+
"name": "ValueText",
|
|
1144
|
+
"element": "div"
|
|
1145
|
+
},
|
|
1146
|
+
{
|
|
1147
|
+
"name": "Marker",
|
|
1148
|
+
"element": "span"
|
|
1149
|
+
},
|
|
1150
|
+
{
|
|
1151
|
+
"name": "MarkerGroup",
|
|
1152
|
+
"element": "div"
|
|
1153
|
+
},
|
|
1154
|
+
{
|
|
1155
|
+
"name": "MarkerIndicator",
|
|
1156
|
+
"element": "div"
|
|
1157
|
+
},
|
|
1158
|
+
{
|
|
1159
|
+
"name": "DraggingIndicator",
|
|
1160
|
+
"element": "div"
|
|
1161
|
+
},
|
|
1162
|
+
{
|
|
1163
|
+
"name": "Marks",
|
|
1164
|
+
"element": "div"
|
|
1165
|
+
}
|
|
1166
|
+
],
|
|
939
1167
|
"example": "<Slider.Root defaultValue={[50]} orientation={orientation}>\n <Slider.Label>Volume</Slider.Label>\n <Slider.Control>\n <Slider.Track>\n <Slider.Range />\n </Slider.Track>\n <Slider.Thumbs />\n </Slider.Control>\n </Slider.Root>",
|
|
940
1168
|
"sourcePath": "src/components/Slider.tsx",
|
|
941
1169
|
"tokens": {
|
|
@@ -993,7 +1221,8 @@
|
|
|
993
1221
|
"primary": "import { StudioControls } from '@discourser/design-system/StudioControls'",
|
|
994
1222
|
"namedExports": [
|
|
995
1223
|
"StudioControls"
|
|
996
|
-
]
|
|
1224
|
+
],
|
|
1225
|
+
"subpath": "@discourser/design-system/StudioControls"
|
|
997
1226
|
},
|
|
998
1227
|
"props": [
|
|
999
1228
|
{
|
|
@@ -1075,11 +1304,58 @@
|
|
|
1075
1304
|
},
|
|
1076
1305
|
"imports": {
|
|
1077
1306
|
"primary": "import * as Switch from '@discourser/design-system/Switch'",
|
|
1078
|
-
"namedExports": [
|
|
1307
|
+
"namedExports": [
|
|
1308
|
+
"Switch.Root",
|
|
1309
|
+
"Switch.Label",
|
|
1310
|
+
"Switch.Thumb",
|
|
1311
|
+
"Switch.Control"
|
|
1312
|
+
],
|
|
1079
1313
|
"subpath": "@discourser/design-system/Switch"
|
|
1080
1314
|
},
|
|
1081
|
-
"props": [
|
|
1082
|
-
|
|
1315
|
+
"props": [
|
|
1316
|
+
{
|
|
1317
|
+
"name": "defaultChecked",
|
|
1318
|
+
"type": "boolean",
|
|
1319
|
+
"required": false,
|
|
1320
|
+
"description": "uncontrolled initial state (boolean)"
|
|
1321
|
+
},
|
|
1322
|
+
{
|
|
1323
|
+
"name": "checked",
|
|
1324
|
+
"type": "boolean",
|
|
1325
|
+
"required": false,
|
|
1326
|
+
"description": "controlled state (boolean)"
|
|
1327
|
+
},
|
|
1328
|
+
{
|
|
1329
|
+
"name": "onCheckedChange",
|
|
1330
|
+
"type": "({ checked }: { checked: boolean }) => void",
|
|
1331
|
+
"required": false,
|
|
1332
|
+
"description": "callback ({ checked }: { checked: boolean }) => void"
|
|
1333
|
+
},
|
|
1334
|
+
{
|
|
1335
|
+
"name": "disabled",
|
|
1336
|
+
"type": "boolean",
|
|
1337
|
+
"required": false,
|
|
1338
|
+
"description": "boolean"
|
|
1339
|
+
}
|
|
1340
|
+
],
|
|
1341
|
+
"subComponents": [
|
|
1342
|
+
{
|
|
1343
|
+
"name": "Root",
|
|
1344
|
+
"element": "root"
|
|
1345
|
+
},
|
|
1346
|
+
{
|
|
1347
|
+
"name": "Label",
|
|
1348
|
+
"element": "label"
|
|
1349
|
+
},
|
|
1350
|
+
{
|
|
1351
|
+
"name": "Thumb",
|
|
1352
|
+
"element": "thumb"
|
|
1353
|
+
},
|
|
1354
|
+
{
|
|
1355
|
+
"name": "Control",
|
|
1356
|
+
"element": "control"
|
|
1357
|
+
}
|
|
1358
|
+
],
|
|
1083
1359
|
"example": "<Switch.Root defaultChecked={checked}>\n <Switch.Control />\n <Switch.Label>Toggle</Switch.Label>\n </Switch.Root>",
|
|
1084
1360
|
"sourcePath": "src/components/Switch.tsx",
|
|
1085
1361
|
"tokens": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@discourser/design-system",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.3",
|
|
4
4
|
"description": "Aesthetic-agnostic design system with Panda CSS and Ark UI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -102,9 +102,21 @@
|
|
|
102
102
|
"types": "./src/components/Tooltip.tsx",
|
|
103
103
|
"import": "./src/components/Tooltip.tsx"
|
|
104
104
|
},
|
|
105
|
-
"./
|
|
106
|
-
"types": "./src/components/
|
|
107
|
-
"import": "./src/components/
|
|
105
|
+
"./Header": {
|
|
106
|
+
"types": "./src/components/Header.tsx",
|
|
107
|
+
"import": "./src/components/Header.tsx"
|
|
108
|
+
},
|
|
109
|
+
"./Dialog": {
|
|
110
|
+
"types": "./src/components/Dialog.tsx",
|
|
111
|
+
"import": "./src/components/Dialog.tsx"
|
|
112
|
+
},
|
|
113
|
+
"./Divider": {
|
|
114
|
+
"types": "./src/components/divider/index.ts",
|
|
115
|
+
"import": "./src/components/divider/index.ts"
|
|
116
|
+
},
|
|
117
|
+
"./StudioControls": {
|
|
118
|
+
"types": "./src/components/StudioControls/index.ts",
|
|
119
|
+
"import": "./src/components/StudioControls/index.ts"
|
|
108
120
|
},
|
|
109
121
|
"./Textarea": {
|
|
110
122
|
"types": "./src/components/Textarea.tsx",
|
|
@@ -186,7 +198,7 @@
|
|
|
186
198
|
],
|
|
187
199
|
"scripts": {
|
|
188
200
|
"dev": "pnpm build:css && pnpm docs:generate && storybook dev -p 6006",
|
|
189
|
-
"build": "pnpm build:panda && pnpm typecheck && pnpm build:lib && pnpm build:types && pnpm codex:generate",
|
|
201
|
+
"build": "pnpm build:panda && pnpm typecheck && pnpm build:lib && pnpm build:types && pnpm exports:validate && pnpm codex:generate",
|
|
190
202
|
"build:panda": "panda codegen",
|
|
191
203
|
"build:css": "panda cssgen --outfile dist/styles.css",
|
|
192
204
|
"build:lib": "tsup",
|
|
@@ -220,7 +232,8 @@
|
|
|
220
232
|
"changeset": "changeset",
|
|
221
233
|
"version": "changeset version",
|
|
222
234
|
"ci:version": "pnpm exec changeset version",
|
|
223
|
-
"release": "pnpm build && changeset publish --access public"
|
|
235
|
+
"release": "pnpm build && changeset publish --access public",
|
|
236
|
+
"exports:validate": "tsx scripts/validate-exports.ts"
|
|
224
237
|
},
|
|
225
238
|
"peerDependencies": {
|
|
226
239
|
"@pandacss/dev": "^1.8.0",
|
|
@@ -38,13 +38,93 @@ function resolveImplementationFile(sourceFile: string): string {
|
|
|
38
38
|
return sourceFile;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
function
|
|
41
|
+
function inferTypeFromDescription(description: string): string {
|
|
42
|
+
const desc = description.trim();
|
|
43
|
+
|
|
44
|
+
// Direct type keyword at start
|
|
45
|
+
const directType = desc.match(
|
|
46
|
+
/^(boolean|string|number|string\[\]|number\[\])(\s*[,.]|$)/,
|
|
47
|
+
);
|
|
48
|
+
if (directType) return directType[1];
|
|
49
|
+
|
|
50
|
+
// Parenthesized type at end: "description (boolean)"
|
|
51
|
+
const parenEnd = desc.match(/\(([a-zA-Z[\]]+)\)\s*$/);
|
|
52
|
+
if (parenEnd && /^(boolean|string|number)(\[\])?$/.test(parenEnd[1])) {
|
|
53
|
+
return parenEnd[1];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Union of string literals: 'a' | 'b' | 'c' — possibly with trailing " (default: ...)"
|
|
57
|
+
if (/^'[^']+'(\s*\|\s*'[^']+')+/.test(desc)) {
|
|
58
|
+
const match = desc.match(/^('(?:[^']+)'\s*(?:\|\s*'(?:[^']+)'\s*)*)/);
|
|
59
|
+
if (match) return match[1].trim();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Callback: "callback (...) => void"
|
|
63
|
+
if (desc.startsWith('callback')) {
|
|
64
|
+
const rest = desc.replace(/^callback\s+/, '');
|
|
65
|
+
return rest || '(...args: unknown[]) => void';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return 'string';
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function extractPropsFromFigmaJsdoc(figmaFilePath: string): PropDefinition[] {
|
|
72
|
+
if (!existsSync(figmaFilePath)) return [];
|
|
73
|
+
const content = readFileSync(figmaFilePath, 'utf-8');
|
|
74
|
+
const props: PropDefinition[] = [];
|
|
75
|
+
|
|
76
|
+
const lines = content.split('\n');
|
|
77
|
+
let inPropsSection = false;
|
|
78
|
+
|
|
79
|
+
for (const line of lines) {
|
|
80
|
+
const trimmed = line.trim();
|
|
81
|
+
|
|
82
|
+
if (!trimmed.startsWith('//')) {
|
|
83
|
+
if (inPropsSection) break; // left the comment block
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Strip the leading `//` (and optional single space)
|
|
88
|
+
const commentContent = trimmed.replace(/^\/\/\s?/, '');
|
|
89
|
+
|
|
90
|
+
if (/^Key props/i.test(commentContent)) {
|
|
91
|
+
inPropsSection = true;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!inPropsSection) continue;
|
|
96
|
+
|
|
97
|
+
// Match " propName — description" (em-dash, en-dash, or hyphen)
|
|
98
|
+
const propMatch = commentContent.match(/^\s+(\w+)\s+[—–-]+\s+(.+)$/);
|
|
99
|
+
if (propMatch) {
|
|
100
|
+
const [, name, description] = propMatch;
|
|
101
|
+
const type = inferTypeFromDescription(description);
|
|
102
|
+
props.push({
|
|
103
|
+
name,
|
|
104
|
+
type,
|
|
105
|
+
required: false,
|
|
106
|
+
description: description.trim(),
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return props;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function extractProps(
|
|
115
|
+
sourceContent: string,
|
|
116
|
+
figmaFilePath?: string,
|
|
117
|
+
): PropDefinition[] {
|
|
42
118
|
const props: PropDefinition[] = [];
|
|
43
119
|
|
|
44
120
|
// Step 1: Find the Props interface and extract its full body using balanced-brace tracking
|
|
45
121
|
const ifaceRe = /interface\s+\w+Props\s*\{/g;
|
|
46
122
|
const startMatch = ifaceRe.exec(sourceContent);
|
|
47
|
-
if (!startMatch)
|
|
123
|
+
if (!startMatch) {
|
|
124
|
+
// Fallback: no interface found — read Key props section from the .figma.tsx JSDoc
|
|
125
|
+
if (figmaFilePath) return extractPropsFromFigmaJsdoc(figmaFilePath);
|
|
126
|
+
return props;
|
|
127
|
+
}
|
|
48
128
|
|
|
49
129
|
// Find the opening { of the interface body
|
|
50
130
|
const openBrace = sourceContent.indexOf(
|
|
@@ -157,15 +237,41 @@ function extractProps(sourceContent: string): PropDefinition[] {
|
|
|
157
237
|
}
|
|
158
238
|
|
|
159
239
|
function extractSubComponents(sourceContent: string): SubComponentEntry[] {
|
|
160
|
-
const subs
|
|
161
|
-
const re =
|
|
162
|
-
/export\s+const\s+(\w+)\s+=\s+with(?:Provider|Context)\(ark\.(\w+)/g;
|
|
240
|
+
const subs = new Map<string, SubComponentEntry>();
|
|
163
241
|
let m: RegExpExecArray | null;
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
242
|
+
|
|
243
|
+
// Pattern 1: withProvider/withContext(ark.tagName, ...) — Park UI ark factory
|
|
244
|
+
const arkRe =
|
|
245
|
+
/export\s+const\s+(\w+)\s+=\s+with(?:Provider|Context)\(ark\.(\w+)/g;
|
|
246
|
+
while ((m = arkRe.exec(sourceContent)) !== null) {
|
|
247
|
+
subs.set(m[1], { name: m[1], element: m[2] });
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Pattern 2: withProvider/withContext(Namespace.Sub, 'slotName') — styleContext pattern
|
|
251
|
+
// Used by RadioGroup, Switch, and similar Ark UI compound components
|
|
252
|
+
const styleCtxRe =
|
|
253
|
+
/export\s+const\s+(\w+)\s+=\s+with(?:Provider|Context)\(\s*\w+\.\w+\s*,\s*['"](\w+)['"]/g;
|
|
254
|
+
while ((m = styleCtxRe.exec(sourceContent)) !== null) {
|
|
255
|
+
if (!subs.has(m[1])) subs.set(m[1], { name: m[1], element: m[2] });
|
|
167
256
|
}
|
|
168
|
-
|
|
257
|
+
|
|
258
|
+
// Pattern 3: createStyledComponent(Namespace.Sub, 'slotName', ...) — custom styled wrapper
|
|
259
|
+
// Used by Slider and similar components with manual style context
|
|
260
|
+
const styledRe =
|
|
261
|
+
/export\s+const\s+(\w+)\s+=\s+createStyledComponent\(\s*\w+\.\w+\s*,\s*['"](\w+)['"]/g;
|
|
262
|
+
while ((m = styledRe.exec(sourceContent)) !== null) {
|
|
263
|
+
if (!subs.has(m[1])) subs.set(m[1], { name: m[1], element: m[2] });
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Pattern 4: forwardRef<HTMLXxxElement, ...> — typed forward ref exports
|
|
267
|
+
const forwardRefRe =
|
|
268
|
+
/export\s+const\s+(\w+)\s+=\s+forwardRef<HTML(\w+)Element/g;
|
|
269
|
+
while ((m = forwardRefRe.exec(sourceContent)) !== null) {
|
|
270
|
+
if (!subs.has(m[1]))
|
|
271
|
+
subs.set(m[1], { name: m[1], element: m[2].toLowerCase() });
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return Array.from(subs.values());
|
|
169
275
|
}
|
|
170
276
|
|
|
171
277
|
function classifyComponent(
|
|
@@ -237,7 +343,7 @@ export function resolveComponent(
|
|
|
237
343
|
}
|
|
238
344
|
|
|
239
345
|
const componentType = classifyComponent(parsed, sourceContent);
|
|
240
|
-
const props = extractProps(typesContent);
|
|
346
|
+
const props = extractProps(typesContent, parsed.filePath);
|
|
241
347
|
const subComponents =
|
|
242
348
|
componentType === 'compound'
|
|
243
349
|
? extractSubComponents(sourceContent)
|