@yahoo/uds-v5-wip 1.60.0 → 1.62.0
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/config/dist/AssetGroup.d.ts +75 -0
- package/dist/config/dist/AssetGroup.js +114 -0
- package/dist/config/dist/Component.d.ts +309 -0
- package/dist/config/dist/Component.js +897 -0
- package/dist/config/dist/ComponentGroup.d.ts +21 -0
- package/dist/config/dist/ComponentGroup.js +46 -0
- package/dist/config/dist/CompositeStyle.d.ts +28 -0
- package/dist/config/dist/CompositeStyle.js +52 -0
- package/dist/config/dist/Config.d.ts +422 -0
- package/dist/config/dist/Config.js +1426 -0
- package/dist/config/dist/Mode.d.ts +42 -0
- package/dist/config/dist/Mode.js +81 -0
- package/dist/config/dist/Modifier.d.ts +52 -0
- package/dist/config/dist/Modifier.js +97 -0
- package/dist/config/dist/MotionDef.d.ts +50 -0
- package/dist/config/dist/MotionDef.js +97 -0
- package/dist/config/dist/Props.d.ts +284 -39
- package/dist/config/dist/Provider.d.ts +21 -0
- package/dist/config/dist/Provider.js +14 -0
- package/dist/config/dist/StyleProp.d.ts +113 -0
- package/dist/config/dist/StyleProp.js +197 -0
- package/dist/config/dist/Token.d.ts +56 -0
- package/dist/config/dist/Token.js +112 -0
- package/dist/config/dist/TokenGroup.d.ts +33 -0
- package/dist/config/dist/TokenGroup.js +68 -0
- package/dist/config/dist/asset-kind.d.ts +56 -0
- package/dist/config/dist/asset-kind.js +29 -0
- package/dist/config/dist/brands.d.ts +31 -0
- package/dist/config/dist/brands.js +20 -0
- package/dist/config/dist/captureCallerPath.d.ts +49 -0
- package/dist/config/dist/captureCallerPath.js +95 -0
- package/dist/config/dist/colorExpressions.d.ts +132 -0
- package/dist/config/dist/colorExpressions.js +148 -0
- package/dist/config/dist/defineAssetGroup.d.ts +158 -0
- package/dist/config/dist/defineAssetGroup.js +263 -0
- package/dist/config/dist/defineProvider.d.ts +30 -0
- package/dist/config/dist/defineProvider.js +60 -0
- package/dist/config/dist/element-marker.d.ts +55 -0
- package/dist/config/dist/element-marker.js +113 -0
- package/dist/config/dist/entity-utils.d.ts +27 -0
- package/dist/config/dist/entity-utils.js +105 -0
- package/dist/config/dist/factories.d.ts +707 -0
- package/dist/config/dist/factories.js +393 -0
- package/dist/config/dist/foreign-component-name.js +42 -0
- package/dist/config/dist/index.d.ts +31 -13
- package/dist/config/dist/index.js +26 -10
- package/dist/config/dist/interpolate.d.ts +21 -0
- package/dist/{foundational-presets/dist/motion.js → config/dist/interpolate.js} +1 -1
- package/dist/config/dist/markers.d.ts +218 -0
- package/dist/config/dist/markers.js +67 -0
- package/dist/config/dist/refs.d.ts +159 -0
- package/dist/config/dist/refs.js +98 -71
- package/dist/config/dist/token-override-rows.d.ts +67 -0
- package/dist/config/dist/token-override-rows.js +223 -0
- package/dist/config/dist/tokenValueType.js +138 -0
- package/dist/config/dist/types/css-properties.d.ts +233 -0
- package/dist/config/dist/types/css-property-keywords.d.ts +157 -0
- package/dist/config/dist/types/css-property-keywords.js +616 -0
- package/dist/config/dist/types/css-values.d.ts +20 -17
- package/dist/config/dist/types.d.ts +697 -64
- package/dist/config/dist/units.d.ts +15 -0
- package/dist/config/dist/units.js +16 -0
- package/dist/config.d.ts +32 -1562
- package/dist/config.js +28 -21
- package/dist/loader/dist/_virtual/_rolldown/runtime.js +1 -2
- package/dist/loader/dist/index.d.ts +2 -0
- package/dist/loader/dist/index.js +3 -0
- package/dist/loader/dist/loader/artifacts.js +26 -9
- package/dist/loader/dist/loader/babel-utils.js +1 -29
- package/dist/loader/dist/loader.d.ts +17 -1
- package/dist/loader/dist/loader.js +56 -339
- package/dist/loader/dist/next.d.ts +2 -1
- package/dist/loader/dist/next.js +3 -3
- package/dist/loader/dist/transform-runner.js +7 -0
- package/dist/loader/dist/unplugin.d.ts +27 -0
- package/dist/loader/dist/unplugin.js +52 -0
- package/dist/plugin.d.ts +2 -2
- package/dist/plugin.js +3 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/dist/index.js +1 -0
- package/dist/utils/dist/motion-utils/resolveMotionState.d.ts +35 -0
- package/dist/utils/dist/motion-utils/resolveMotionState.js +33 -0
- package/dist/utils/dist/string-utils/componentClassName.d.ts +41 -8
- package/dist/utils/dist/string-utils/componentClassName.js +48 -11
- package/dist/utils.d.ts +3 -2
- package/dist/utils.js +3 -2
- package/package.json +3 -51
- package/dist/components/accordion.config.d.ts +0 -2
- package/dist/components/accordion.config.js +0 -2
- package/dist/components/accordion.d.ts +0 -2
- package/dist/components/accordion.js +0 -2
- package/dist/components/alert.config.d.ts +0 -2
- package/dist/components/alert.config.js +0 -2
- package/dist/components/alert.d.ts +0 -2
- package/dist/components/alert.js +0 -2
- package/dist/components/anchor.config.d.ts +0 -2
- package/dist/components/anchor.config.js +0 -2
- package/dist/components/anchor.d.ts +0 -2
- package/dist/components/anchor.js +0 -2
- package/dist/components/article.d.ts +0 -2
- package/dist/components/article.js +0 -2
- package/dist/components/aside.d.ts +0 -2
- package/dist/components/aside.js +0 -2
- package/dist/components/avatar-group.config.d.ts +0 -2
- package/dist/components/avatar-group.config.js +0 -2
- package/dist/components/avatar-group.d.ts +0 -2
- package/dist/components/avatar-group.js +0 -2
- package/dist/components/avatar.config.d.ts +0 -2
- package/dist/components/avatar.config.js +0 -2
- package/dist/components/avatar.d.ts +0 -2
- package/dist/components/avatar.js +0 -2
- package/dist/components/badge.config.d.ts +0 -2
- package/dist/components/badge.config.js +0 -2
- package/dist/components/badge.d.ts +0 -2
- package/dist/components/badge.js +0 -2
- package/dist/components/box.d.ts +0 -2
- package/dist/components/box.js +0 -2
- package/dist/components/breadcrumb.config.d.ts +0 -2
- package/dist/components/breadcrumb.config.js +0 -2
- package/dist/components/breadcrumb.d.ts +0 -2
- package/dist/components/breadcrumb.js +0 -2
- package/dist/components/button.config.d.ts +0 -2
- package/dist/components/button.config.js +0 -2
- package/dist/components/button.d.ts +0 -2
- package/dist/components/button.js +0 -2
- package/dist/components/card.config.d.ts +0 -2
- package/dist/components/card.config.js +0 -2
- package/dist/components/card.d.ts +0 -2
- package/dist/components/card.js +0 -2
- package/dist/components/collapsible.config.d.ts +0 -2
- package/dist/components/collapsible.config.js +0 -2
- package/dist/components/collapsible.d.ts +0 -2
- package/dist/components/collapsible.js +0 -2
- package/dist/components/command.config.d.ts +0 -2
- package/dist/components/command.config.js +0 -2
- package/dist/components/command.d.ts +0 -2
- package/dist/components/command.js +0 -2
- package/dist/components/control-color.config.d.ts +0 -2
- package/dist/components/control-color.config.js +0 -2
- package/dist/components/control-color.d.ts +0 -2
- package/dist/components/control-color.js +0 -2
- package/dist/components/control-curve.config.d.ts +0 -2
- package/dist/components/control-curve.config.js +0 -2
- package/dist/components/control-curve.d.ts +0 -2
- package/dist/components/control-curve.js +0 -2
- package/dist/components/control-folder.config.d.ts +0 -2
- package/dist/components/control-folder.config.js +0 -2
- package/dist/components/control-folder.d.ts +0 -2
- package/dist/components/control-folder.js +0 -2
- package/dist/components/control-group.config.d.ts +0 -2
- package/dist/components/control-group.config.js +0 -2
- package/dist/components/control-group.d.ts +0 -2
- package/dist/components/control-group.js +0 -2
- package/dist/components/control-knob.config.d.ts +0 -2
- package/dist/components/control-knob.config.js +0 -2
- package/dist/components/control-knob.d.ts +0 -2
- package/dist/components/control-knob.js +0 -2
- package/dist/components/control-panel.config.d.ts +0 -2
- package/dist/components/control-panel.config.js +0 -2
- package/dist/components/control-panel.d.ts +0 -2
- package/dist/components/control-panel.js +0 -2
- package/dist/components/control-select.config.d.ts +0 -2
- package/dist/components/control-select.config.js +0 -2
- package/dist/components/control-select.d.ts +0 -2
- package/dist/components/control-select.js +0 -2
- package/dist/components/control-slider.config.d.ts +0 -2
- package/dist/components/control-slider.config.js +0 -2
- package/dist/components/control-slider.d.ts +0 -2
- package/dist/components/control-slider.js +0 -2
- package/dist/components/control-spring.config.d.ts +0 -2
- package/dist/components/control-spring.config.js +0 -2
- package/dist/components/control-spring.d.ts +0 -2
- package/dist/components/control-spring.js +0 -2
- package/dist/components/control-stepper.config.d.ts +0 -2
- package/dist/components/control-stepper.config.js +0 -2
- package/dist/components/control-stepper.d.ts +0 -2
- package/dist/components/control-stepper.js +0 -2
- package/dist/components/control-toggle.config.d.ts +0 -2
- package/dist/components/control-toggle.config.js +0 -2
- package/dist/components/control-toggle.d.ts +0 -2
- package/dist/components/control-toggle.js +0 -2
- package/dist/components/dist/_slots.js +0 -8
- package/dist/components/dist/accordion.config.d.ts +0 -431
- package/dist/components/dist/accordion.config.js +0 -81
- package/dist/components/dist/accordion.d.ts +0 -453
- package/dist/components/dist/accordion.js +0 -60
- package/dist/components/dist/alert.config.d.ts +0 -219
- package/dist/components/dist/alert.config.js +0 -54
- package/dist/components/dist/alert.d.ts +0 -230
- package/dist/components/dist/alert.js +0 -16
- package/dist/components/dist/anchor.config.d.ts +0 -250
- package/dist/components/dist/anchor.config.js +0 -22
- package/dist/components/dist/anchor.d.ts +0 -261
- package/dist/components/dist/anchor.js +0 -9
- package/dist/components/dist/article.d.ts +0 -11
- package/dist/components/dist/article.js +0 -9
- package/dist/components/dist/aside.d.ts +0 -11
- package/dist/components/dist/aside.js +0 -9
- package/dist/components/dist/avatar-group.config.d.ts +0 -315
- package/dist/components/dist/avatar-group.config.js +0 -33
- package/dist/components/dist/avatar-group.d.ts +0 -329
- package/dist/components/dist/avatar-group.js +0 -39
- package/dist/components/dist/avatar.config.d.ts +0 -197
- package/dist/components/dist/avatar.config.js +0 -49
- package/dist/components/dist/avatar.d.ts +0 -211
- package/dist/components/dist/avatar.js +0 -20
- package/dist/components/dist/badge.config.d.ts +0 -477
- package/dist/components/dist/badge.config.js +0 -99
- package/dist/components/dist/badge.d.ts +0 -489
- package/dist/components/dist/badge.js +0 -16
- package/dist/components/dist/box.d.ts +0 -14
- package/dist/components/dist/box.js +0 -9
- package/dist/components/dist/breadcrumb.config.d.ts +0 -390
- package/dist/components/dist/breadcrumb.config.js +0 -43
- package/dist/components/dist/breadcrumb.d.ts +0 -420
- package/dist/components/dist/breadcrumb.js +0 -119
- package/dist/components/dist/button.config.d.ts +0 -381
- package/dist/components/dist/button.config.js +0 -91
- package/dist/components/dist/button.d.ts +0 -403
- package/dist/components/dist/button.js +0 -35
- package/dist/components/dist/card.config.d.ts +0 -336
- package/dist/components/dist/card.config.js +0 -33
- package/dist/components/dist/card.d.ts +0 -352
- package/dist/components/dist/card.js +0 -27
- package/dist/components/dist/collapsible.config.d.ts +0 -45
- package/dist/components/dist/collapsible.config.js +0 -46
- package/dist/components/dist/collapsible.d.ts +0 -61
- package/dist/components/dist/collapsible.js +0 -38
- package/dist/components/dist/command.config.d.ts +0 -1613
- package/dist/components/dist/command.config.js +0 -170
- package/dist/components/dist/command.d.ts +0 -1722
- package/dist/components/dist/command.js +0 -341
- package/dist/components/dist/control-color.config.d.ts +0 -979
- package/dist/components/dist/control-color.config.js +0 -81
- package/dist/components/dist/control-color.d.ts +0 -995
- package/dist/components/dist/control-color.js +0 -64
- package/dist/components/dist/control-curve.config.d.ts +0 -18
- package/dist/components/dist/control-curve.config.js +0 -14
- package/dist/components/dist/control-curve.d.ts +0 -35
- package/dist/components/dist/control-curve.js +0 -81
- package/dist/components/dist/control-folder.config.d.ts +0 -177
- package/dist/components/dist/control-folder.config.js +0 -47
- package/dist/components/dist/control-folder.d.ts +0 -194
- package/dist/components/dist/control-folder.js +0 -41
- package/dist/components/dist/control-group.config.d.ts +0 -859
- package/dist/components/dist/control-group.config.js +0 -80
- package/dist/components/dist/control-group.d.ts +0 -881
- package/dist/components/dist/control-group.js +0 -89
- package/dist/components/dist/control-knob.config.d.ts +0 -792
- package/dist/components/dist/control-knob.config.js +0 -67
- package/dist/components/dist/control-knob.d.ts +0 -819
- package/dist/components/dist/control-knob.js +0 -148
- package/dist/components/dist/control-panel.config.d.ts +0 -402
- package/dist/components/dist/control-panel.config.js +0 -38
- package/dist/components/dist/control-panel.d.ts +0 -415
- package/dist/components/dist/control-panel.js +0 -22
- package/dist/components/dist/control-select.config.d.ts +0 -1176
- package/dist/components/dist/control-select.config.js +0 -102
- package/dist/components/dist/control-select.d.ts +0 -1200
- package/dist/components/dist/control-select.js +0 -63
- package/dist/components/dist/control-slider.config.d.ts +0 -104
- package/dist/components/dist/control-slider.config.js +0 -98
- package/dist/components/dist/control-slider.d.ts +0 -127
- package/dist/components/dist/control-slider.js +0 -87
- package/dist/components/dist/control-spring.config.d.ts +0 -417
- package/dist/components/dist/control-spring.config.js +0 -36
- package/dist/components/dist/control-spring.d.ts +0 -439
- package/dist/components/dist/control-spring.js +0 -136
- package/dist/components/dist/control-stepper.config.d.ts +0 -1084
- package/dist/components/dist/control-stepper.config.js +0 -108
- package/dist/components/dist/control-stepper.d.ts +0 -1104
- package/dist/components/dist/control-stepper.js +0 -109
- package/dist/components/dist/control-toggle.config.d.ts +0 -407
- package/dist/components/dist/control-toggle.config.js +0 -26
- package/dist/components/dist/control-toggle.d.ts +0 -420
- package/dist/components/dist/control-toggle.js +0 -36
- package/dist/components/dist/createSlot.d.ts +0 -8
- package/dist/components/dist/createSlot.js +0 -89
- package/dist/components/dist/dropdown.config.d.ts +0 -920
- package/dist/components/dist/dropdown.config.js +0 -107
- package/dist/components/dist/dropdown.d.ts +0 -950
- package/dist/components/dist/dropdown.js +0 -92
- package/dist/components/dist/empty-state.config.d.ts +0 -396
- package/dist/components/dist/empty-state.config.js +0 -53
- package/dist/components/dist/empty-state.d.ts +0 -416
- package/dist/components/dist/empty-state.js +0 -33
- package/dist/components/dist/footer.d.ts +0 -11
- package/dist/components/dist/footer.js +0 -9
- package/dist/components/dist/grid.d.ts +0 -41
- package/dist/components/dist/grid.js +0 -34
- package/dist/components/dist/header.d.ts +0 -11
- package/dist/components/dist/header.js +0 -9
- package/dist/components/dist/hstack.d.ts +0 -15
- package/dist/components/dist/hstack.js +0 -21
- package/dist/components/dist/image.d.ts +0 -19
- package/dist/components/dist/image.js +0 -9
- package/dist/components/dist/input.config.d.ts +0 -58
- package/dist/components/dist/input.config.js +0 -42
- package/dist/components/dist/input.d.ts +0 -67
- package/dist/components/dist/input.js +0 -14
- package/dist/components/dist/item.config.d.ts +0 -351
- package/dist/components/dist/item.config.js +0 -83
- package/dist/components/dist/item.d.ts +0 -374
- package/dist/components/dist/item.js +0 -51
- package/dist/components/dist/list.d.ts +0 -19
- package/dist/components/dist/list.js +0 -21
- package/dist/components/dist/main.d.ts +0 -11
- package/dist/components/dist/main.js +0 -9
- package/dist/components/dist/modal.config.d.ts +0 -397
- package/dist/components/dist/modal.config.js +0 -92
- package/dist/components/dist/modal.d.ts +0 -433
- package/dist/components/dist/modal.js +0 -125
- package/dist/components/dist/nav-header.config.d.ts +0 -158
- package/dist/components/dist/nav-header.config.js +0 -26
- package/dist/components/dist/nav-header.d.ts +0 -173
- package/dist/components/dist/nav-header.js +0 -23
- package/dist/components/dist/nav.d.ts +0 -11
- package/dist/components/dist/nav.js +0 -9
- package/dist/components/dist/preset-bar.config.d.ts +0 -192
- package/dist/components/dist/preset-bar.config.js +0 -39
- package/dist/components/dist/preset-bar.d.ts +0 -215
- package/dist/components/dist/preset-bar.js +0 -71
- package/dist/components/dist/presets/index.d.ts +0 -17674
- package/dist/components/dist/presets/index.js +0 -97
- package/dist/components/dist/pressable.d.ts +0 -11
- package/dist/components/dist/pressable.js +0 -9
- package/dist/components/dist/progress.config.d.ts +0 -296
- package/dist/components/dist/progress.config.js +0 -35
- package/dist/components/dist/progress.d.ts +0 -311
- package/dist/components/dist/progress.js +0 -43
- package/dist/components/dist/section.d.ts +0 -11
- package/dist/components/dist/section.js +0 -9
- package/dist/components/dist/select.config.d.ts +0 -31
- package/dist/components/dist/select.config.js +0 -25
- package/dist/components/dist/select.d.ts +0 -45
- package/dist/components/dist/select.js +0 -13
- package/dist/components/dist/sheet.config.d.ts +0 -245
- package/dist/components/dist/sheet.config.js +0 -99
- package/dist/components/dist/sheet.d.ts +0 -267
- package/dist/components/dist/sheet.js +0 -53
- package/dist/components/dist/sidebar.config.d.ts +0 -1651
- package/dist/components/dist/sidebar.config.js +0 -217
- package/dist/components/dist/sidebar.d.ts +0 -1825
- package/dist/components/dist/sidebar.js +0 -492
- package/dist/components/dist/skeleton.config.d.ts +0 -16
- package/dist/components/dist/skeleton.config.js +0 -10
- package/dist/components/dist/skeleton.d.ts +0 -27
- package/dist/components/dist/skeleton.js +0 -16
- package/dist/components/dist/slider.config.d.ts +0 -44
- package/dist/components/dist/slider.config.js +0 -40
- package/dist/components/dist/slider.d.ts +0 -70
- package/dist/components/dist/slider.js +0 -247
- package/dist/components/dist/spinner.config.d.ts +0 -34
- package/dist/components/dist/spinner.config.js +0 -24
- package/dist/components/dist/spinner.d.ts +0 -42
- package/dist/components/dist/spinner.js +0 -29
- package/dist/components/dist/svg.d.ts +0 -21
- package/dist/components/dist/svg.js +0 -17
- package/dist/components/dist/switch.config.d.ts +0 -353
- package/dist/components/dist/switch.config.js +0 -47
- package/dist/components/dist/switch.d.ts +0 -370
- package/dist/components/dist/switch.js +0 -32
- package/dist/components/dist/table.d.ts +0 -36
- package/dist/components/dist/table.js +0 -29
- package/dist/components/dist/tabs.config.d.ts +0 -611
- package/dist/components/dist/tabs.config.js +0 -56
- package/dist/components/dist/tabs.d.ts +0 -632
- package/dist/components/dist/tabs.js +0 -77
- package/dist/components/dist/text.config.d.ts +0 -306
- package/dist/components/dist/text.config.js +0 -149
- package/dist/components/dist/text.d.ts +0 -205
- package/dist/components/dist/text.js +0 -12
- package/dist/components/dist/textarea.config.d.ts +0 -352
- package/dist/components/dist/textarea.config.js +0 -57
- package/dist/components/dist/textarea.d.ts +0 -362
- package/dist/components/dist/textarea.js +0 -9
- package/dist/components/dist/toast.config.d.ts +0 -335
- package/dist/components/dist/toast.config.js +0 -145
- package/dist/components/dist/toast.d.ts +0 -426
- package/dist/components/dist/toast.js +0 -159
- package/dist/components/dist/tooltip.config.d.ts +0 -193
- package/dist/components/dist/tooltip.config.js +0 -40
- package/dist/components/dist/tooltip.d.ts +0 -206
- package/dist/components/dist/tooltip.js +0 -28
- package/dist/components/dist/vstack.d.ts +0 -15
- package/dist/components/dist/vstack.js +0 -20
- package/dist/components/dropdown.config.d.ts +0 -2
- package/dist/components/dropdown.config.js +0 -2
- package/dist/components/dropdown.d.ts +0 -2
- package/dist/components/dropdown.js +0 -2
- package/dist/components/empty-state.config.d.ts +0 -2
- package/dist/components/empty-state.config.js +0 -2
- package/dist/components/empty-state.d.ts +0 -2
- package/dist/components/empty-state.js +0 -2
- package/dist/components/footer.d.ts +0 -2
- package/dist/components/footer.js +0 -2
- package/dist/components/grid.d.ts +0 -2
- package/dist/components/grid.js +0 -2
- package/dist/components/header.d.ts +0 -2
- package/dist/components/header.js +0 -2
- package/dist/components/hstack.d.ts +0 -2
- package/dist/components/hstack.js +0 -2
- package/dist/components/image.d.ts +0 -2
- package/dist/components/image.js +0 -2
- package/dist/components/input.config.d.ts +0 -2
- package/dist/components/input.config.js +0 -2
- package/dist/components/input.d.ts +0 -2
- package/dist/components/input.js +0 -2
- package/dist/components/item.config.d.ts +0 -2
- package/dist/components/item.config.js +0 -2
- package/dist/components/item.d.ts +0 -2
- package/dist/components/item.js +0 -2
- package/dist/components/list.d.ts +0 -2
- package/dist/components/list.js +0 -2
- package/dist/components/main.d.ts +0 -2
- package/dist/components/main.js +0 -2
- package/dist/components/modal.config.d.ts +0 -2
- package/dist/components/modal.config.js +0 -2
- package/dist/components/modal.d.ts +0 -2
- package/dist/components/modal.js +0 -2
- package/dist/components/nav-header.config.d.ts +0 -2
- package/dist/components/nav-header.config.js +0 -2
- package/dist/components/nav-header.d.ts +0 -2
- package/dist/components/nav-header.js +0 -2
- package/dist/components/nav.d.ts +0 -2
- package/dist/components/nav.js +0 -2
- package/dist/components/preset-bar.config.d.ts +0 -2
- package/dist/components/preset-bar.config.js +0 -2
- package/dist/components/preset-bar.d.ts +0 -2
- package/dist/components/preset-bar.js +0 -2
- package/dist/components/presets/index.d.ts +0 -44
- package/dist/components/presets/index.js +0 -44
- package/dist/components/pressable.d.ts +0 -2
- package/dist/components/pressable.js +0 -2
- package/dist/components/progress.config.d.ts +0 -2
- package/dist/components/progress.config.js +0 -2
- package/dist/components/progress.d.ts +0 -2
- package/dist/components/progress.js +0 -2
- package/dist/components/section.d.ts +0 -2
- package/dist/components/section.js +0 -2
- package/dist/components/select.config.d.ts +0 -2
- package/dist/components/select.config.js +0 -2
- package/dist/components/select.d.ts +0 -2
- package/dist/components/select.js +0 -2
- package/dist/components/sheet.config.d.ts +0 -2
- package/dist/components/sheet.config.js +0 -2
- package/dist/components/sheet.d.ts +0 -2
- package/dist/components/sheet.js +0 -2
- package/dist/components/sidebar.config.d.ts +0 -2
- package/dist/components/sidebar.config.js +0 -2
- package/dist/components/sidebar.d.ts +0 -2
- package/dist/components/sidebar.js +0 -2
- package/dist/components/skeleton.config.d.ts +0 -2
- package/dist/components/skeleton.config.js +0 -2
- package/dist/components/skeleton.d.ts +0 -2
- package/dist/components/skeleton.js +0 -2
- package/dist/components/slider.config.d.ts +0 -2
- package/dist/components/slider.config.js +0 -2
- package/dist/components/slider.d.ts +0 -2
- package/dist/components/slider.js +0 -2
- package/dist/components/spinner.config.d.ts +0 -2
- package/dist/components/spinner.config.js +0 -2
- package/dist/components/spinner.d.ts +0 -2
- package/dist/components/spinner.js +0 -2
- package/dist/components/svg.d.ts +0 -2
- package/dist/components/svg.js +0 -2
- package/dist/components/switch.config.d.ts +0 -2
- package/dist/components/switch.config.js +0 -2
- package/dist/components/switch.d.ts +0 -2
- package/dist/components/switch.js +0 -2
- package/dist/components/table.d.ts +0 -2
- package/dist/components/table.js +0 -2
- package/dist/components/tabs.config.d.ts +0 -2
- package/dist/components/tabs.config.js +0 -2
- package/dist/components/tabs.d.ts +0 -2
- package/dist/components/tabs.js +0 -2
- package/dist/components/text.config.d.ts +0 -2
- package/dist/components/text.config.js +0 -2
- package/dist/components/text.d.ts +0 -2
- package/dist/components/text.js +0 -2
- package/dist/components/textarea.config.d.ts +0 -2
- package/dist/components/textarea.config.js +0 -2
- package/dist/components/textarea.d.ts +0 -2
- package/dist/components/textarea.js +0 -2
- package/dist/components/toast.config.d.ts +0 -2
- package/dist/components/toast.config.js +0 -2
- package/dist/components/toast.d.ts +0 -2
- package/dist/components/toast.js +0 -2
- package/dist/components/tooltip.config.d.ts +0 -2
- package/dist/components/tooltip.config.js +0 -2
- package/dist/components/tooltip.d.ts +0 -2
- package/dist/components/tooltip.js +0 -2
- package/dist/components/vstack.d.ts +0 -2
- package/dist/components/vstack.js +0 -2
- package/dist/config/dist/component-config.d.ts +0 -349
- package/dist/config/dist/component-refs.d.ts +0 -98
- package/dist/config/dist/component-resolution.js +0 -78
- package/dist/config/dist/consts/defaultColors.d.ts +0 -253
- package/dist/config/dist/consts/defaultColors.js +0 -252
- package/dist/config/dist/createComponent.d.ts +0 -1
- package/dist/config/dist/createComponent.js +0 -1
- package/dist/config/dist/createConfig.d.ts +0 -375
- package/dist/config/dist/createConfig.js +0 -625
- package/dist/config/dist/defineComponent.d.ts +0 -24
- package/dist/config/dist/defineComponent.js +0 -2
- package/dist/config/dist/defineStyleProp.d.ts +0 -93
- package/dist/config/dist/defineStyleProp.js +0 -60
- package/dist/config/dist/preset-merge.js +0 -192
- package/dist/config/dist/propertyAcceptedTypes.js +0 -220
- package/dist/config/dist/propertyGroups.d.ts +0 -1
- package/dist/config/dist/propertyGroups.js +0 -414
- package/dist/config/dist/resolveStyleProp.d.ts +0 -88
- package/dist/config/dist/resolveStyleProp.js +0 -235
- package/dist/config/dist/resolveTokenTypes.d.ts +0 -1
- package/dist/config/dist/resolveTokenTypes.js +0 -149
- package/dist/config/dist/runtime-registry.js +0 -9
- package/dist/config/dist/serialize.d.ts +0 -73
- package/dist/config/dist/serialize.js +0 -172
- package/dist/config/dist/style-prop-runtime.d.ts +0 -1
- package/dist/config-utils/dist/componentConfig.d.ts +0 -10
- package/dist/config-utils/dist/componentConfig.js +0 -11
- package/dist/config-utils.d.ts +0 -2
- package/dist/config-utils.js +0 -2
- package/dist/core/dist/color-opacity-map.js +0 -33
- package/dist/core/dist/compositeStyles.d.ts +0 -21
- package/dist/core/dist/compositeStyles.js +0 -51
- package/dist/core/dist/configurable-prop-helpers.d.ts +0 -31
- package/dist/core/dist/configurable-prop-helpers.js +0 -61
- package/dist/core/dist/createComponent.boundaries.js +0 -192
- package/dist/core/dist/createComponent.d.ts +0 -56
- package/dist/core/dist/createComponent.js +0 -67
- package/dist/core/dist/createComponentExample.d.ts +0 -41
- package/dist/core/dist/createComponentExample.js +0 -27
- package/dist/core/dist/createProvider.d.ts +0 -12
- package/dist/core/dist/createProvider.js +0 -24
- package/dist/core/dist/generated/stylePropsTwMap.d.ts +0 -1700
- package/dist/core/dist/generated/stylePropsTwMap.js +0 -570
- package/dist/core/dist/getComponentStyles.d.ts +0 -49
- package/dist/core/dist/getComponentStyles.js +0 -85
- package/dist/core/dist/getStyles.d.ts +0 -42
- package/dist/core/dist/getStyles.js +0 -300
- package/dist/core/dist/index.d.ts +0 -13
- package/dist/core/dist/index.js +0 -13
- package/dist/core/dist/modifier-mappings.d.ts +0 -12
- package/dist/core/dist/modifier-mappings.js +0 -61
- package/dist/core/dist/resolveMotionState.d.ts +0 -4
- package/dist/core/dist/resolveMotionState.js +0 -17
- package/dist/core/dist/resolveProps.boundaries.js +0 -131
- package/dist/core/dist/style-prop-data.d.ts +0 -32
- package/dist/core/dist/style-prop-data.js +0 -1257
- package/dist/core/dist/transformPreset.d.ts +0 -17
- package/dist/core/dist/transformPreset.js +0 -28
- package/dist/core/dist/withDefaultStyleProps.d.ts +0 -43
- package/dist/core/dist/withDefaultStyleProps.js +0 -18
- package/dist/core.d.ts +0 -14
- package/dist/core.js +0 -15
- package/dist/createSlot.d.ts +0 -2
- package/dist/createSlot.js +0 -2
- package/dist/fixtures.d.ts +0 -4
- package/dist/fixtures.js +0 -5
- package/dist/foundational-presets/dist/_virtual/_rolldown/runtime.js +0 -13
- package/dist/foundational-presets/dist/defaultPreset.d.ts +0 -1557
- package/dist/foundational-presets/dist/defaultPreset.js +0 -615
- package/dist/foundational-presets/dist/index.d.ts +0 -1
- package/dist/foundational-presets/dist/index.js +0 -1
- package/dist/foundational-presets/dist/motion.d.ts +0 -12
- package/dist/foundational-presets/dist/style-props.js +0 -1445
- package/dist/loader/dist/loader/create-component-data.js +0 -33
- package/dist/loader/dist/loader/create-component-lowering.js +0 -454
- package/dist/loader/dist/loader/data-attr-transform.js +0 -191
- package/dist/loader/dist/loader/dynamic-style-codegen.js +0 -97
- package/dist/loader/dist/loader/internal-meta.js +0 -22
- package/dist/loader/dist/loader/lower-new-api-primitive.js +0 -90
- package/dist/loader/dist/loader/motion-transform.js +0 -717
- package/dist/loader/dist/loader/style-transform.js +0 -670
- package/dist/loader/dist/node_modules/react/cjs/react-jsx-runtime.development.js +0 -203
- package/dist/loader/dist/node_modules/react/cjs/react-jsx-runtime.production.js +0 -25
- package/dist/loader/dist/node_modules/react/cjs/react.development.js +0 -762
- package/dist/loader/dist/node_modules/react/cjs/react.production.js +0 -351
- package/dist/loader/dist/node_modules/react/index.js +0 -10
- package/dist/loader/dist/node_modules/react/jsx-runtime.js +0 -10
- package/dist/loader/dist/packages/core/dist/color-opacity-map.js +0 -33
- package/dist/loader/dist/packages/core/dist/compositeStyles.js +0 -43
- package/dist/loader/dist/packages/core/dist/createComponent.js +0 -6
- package/dist/loader/dist/packages/core/dist/createProvider.js +0 -7
- package/dist/loader/dist/packages/core/dist/generated/stylePropsTwMap.js +0 -570
- package/dist/loader/dist/packages/core/dist/getComponentStyles.js +0 -2
- package/dist/loader/dist/packages/core/dist/getStyles.js +0 -60
- package/dist/loader/dist/packages/core/dist/index.js +0 -6
- package/dist/loader/dist/packages/core/dist/modifier-mappings.js +0 -61
- package/dist/loader/dist/packages/core/dist/style-prop-data.js +0 -1257
- package/dist/loader/dist/packages/core/dist/withDefaultStyleProps.js +0 -1
- package/dist/presets/dist/defaultPreset.d.ts +0 -6
- package/dist/presets/dist/defaultPreset.js +0 -51
- package/dist/presets/dist/index.d.ts +0 -1
- package/dist/presets/dist/index.js +0 -1
- package/dist/presets/motion.d.ts +0 -2
- package/dist/presets/motion.js +0 -2
- package/dist/presets.d.ts +0 -2
- package/dist/presets.js +0 -3
- package/dist/styles.d.ts +0 -4
- package/dist/styles.js +0 -5
- package/dist/transformPreset.d.ts +0 -2
- package/dist/transformPreset.js +0 -3
- /package/dist/{config/dist/component-resolution.d.ts → loader/dist/transform-runner.d.ts} +0 -0
|
@@ -0,0 +1,1426 @@
|
|
|
1
|
+
import { AssetGroup } from "./AssetGroup.js";
|
|
2
|
+
import { attachSourcePath } from "./captureCallerPath.js";
|
|
3
|
+
import { isAssetGroupRef, isModeRef, isTokenRef } from "./refs.js";
|
|
4
|
+
import { ASSET_GROUP_SLUG_KEY, readAssetGroupSlug } from "./defineAssetGroup.js";
|
|
5
|
+
import { FOREIGN_NAMESPACE } from "./foreign-component-name.js";
|
|
6
|
+
import { Component, assertDefinitionAcceptsPlaceable } from "./Component.js";
|
|
7
|
+
import { ComponentGroup } from "./ComponentGroup.js";
|
|
8
|
+
import { CompositeStyle } from "./CompositeStyle.js";
|
|
9
|
+
import { Mode } from "./Mode.js";
|
|
10
|
+
import { Modifier } from "./Modifier.js";
|
|
11
|
+
import { CssMotionDef, JsMotionDef } from "./MotionDef.js";
|
|
12
|
+
import { Provider } from "./Provider.js";
|
|
13
|
+
import { StyleProp } from "./StyleProp.js";
|
|
14
|
+
import { TokenGroup } from "./TokenGroup.js";
|
|
15
|
+
//#region ../config/dist/Config.js
|
|
16
|
+
/**
|
|
17
|
+
* `Config` — top-level container for a UDS design system.
|
|
18
|
+
*
|
|
19
|
+
* Authored data lives on bare properties (Maps for collections, scalars
|
|
20
|
+
* for prefix/preflight). Derived data lives under `.derived`, a memoized
|
|
21
|
+
* lazy getter rebuilt whenever a `register*` chain method runs. The
|
|
22
|
+
* single dot to `.derived` is the boundary between "stored" and
|
|
23
|
+
* "computed"; consumers can tell at a glance which side of the line
|
|
24
|
+
* they're reading.
|
|
25
|
+
*/
|
|
26
|
+
/** Compile-time exhaustiveness backstop for the `dependentsOf`/`dependenciesOf`
|
|
27
|
+
* switches: once every kind is handled, `query` narrows to `never` here; a new,
|
|
28
|
+
* unhandled kind makes the call a type error at the `default` branch. */
|
|
29
|
+
function assertNever(value) {
|
|
30
|
+
throw new Error(`Unhandled dependency kind: ${JSON.stringify(value)}`);
|
|
31
|
+
}
|
|
32
|
+
var Config = class Config {
|
|
33
|
+
static SCHEMA_VERSION = 1;
|
|
34
|
+
prefix = "uds";
|
|
35
|
+
/**
|
|
36
|
+
* Registry namespace — a stable, `package.json`-style identifier
|
|
37
|
+
* (`uds`, `@acme/system`) that namespaces every component's
|
|
38
|
+
* `registryKey` as `<namespace>:<ComponentName>` (the spec `type`).
|
|
39
|
+
* Declared in `uds.config.ts` via `configure({ namespace })` so it's
|
|
40
|
+
* available at build time; the push pipeline validates it for
|
|
41
|
+
* uniqueness / ownership. `undefined` ⇒ components keep bare-name
|
|
42
|
+
* registry keys. See Linear doc "RFC: Registry-namespaced component
|
|
43
|
+
* types".
|
|
44
|
+
*/
|
|
45
|
+
namespace;
|
|
46
|
+
preflight = true;
|
|
47
|
+
globalStyles = {};
|
|
48
|
+
rawCss = [];
|
|
49
|
+
designPrinciples = [];
|
|
50
|
+
buildOptions = {};
|
|
51
|
+
tokenGroups = /* @__PURE__ */ new Map();
|
|
52
|
+
styleProps = /* @__PURE__ */ new Map();
|
|
53
|
+
modifiers = /* @__PURE__ */ new Map();
|
|
54
|
+
modes = /* @__PURE__ */ new Map();
|
|
55
|
+
compositeStyles = /* @__PURE__ */ new Map();
|
|
56
|
+
components = /* @__PURE__ */ new Map();
|
|
57
|
+
componentGroups = /* @__PURE__ */ new Map();
|
|
58
|
+
assetGroups = /* @__PURE__ */ new Map();
|
|
59
|
+
providers = /* @__PURE__ */ new Map();
|
|
60
|
+
motion = /* @__PURE__ */ new Map();
|
|
61
|
+
#derived;
|
|
62
|
+
/**
|
|
63
|
+
* Set top-level config metadata in one call — the single scalar-setter,
|
|
64
|
+
* replacing the former `withPrefix` / `withPreflight` / `withName` /
|
|
65
|
+
* `withDesignPrinciples` / `withBuildOptions` chain. Partial: only
|
|
66
|
+
* provided keys are applied, so it can run once or be merged across
|
|
67
|
+
* calls. `globalStyles` stays on `defineGlobalStyles` — its callback
|
|
68
|
+
* form needs the derived token refs, so it doesn't fit a plain bag.
|
|
69
|
+
*
|
|
70
|
+
* - `namespace` — the registry namespace (`uds`, `@acme/system`) that
|
|
71
|
+
* namespaces every component's `registryKey` as `<namespace>:<Component>`.
|
|
72
|
+
* Declared in `uds.config.ts` (the `package.json`-`name` model) so it's
|
|
73
|
+
* available at build time; the push pipeline additionally validates it
|
|
74
|
+
* for uniqueness / ownership. Throws on a structurally invalid value
|
|
75
|
+
* (the `:` separator, whitespace, or empty).
|
|
76
|
+
* - `prefix` — class-name + CSS-variable prefix (default `uds`); invalidates
|
|
77
|
+
* derived. Pass `''` or `false` to opt out entirely — classes and vars
|
|
78
|
+
* emit unprefixed (`bg-primary`, `--color-brand`). `false` is sugar for
|
|
79
|
+
* `''`, normalized to the empty string here so the value stays a string.
|
|
80
|
+
* - `preflight` — include Tailwind's reset (default `true`).
|
|
81
|
+
* - `designPrinciples` — freeform strings surfaced in the AI prompt.
|
|
82
|
+
* - `buildOptions` — shallow-merged into existing build options.
|
|
83
|
+
*/
|
|
84
|
+
configure(options) {
|
|
85
|
+
if (options.namespace !== void 0) this.namespace = validateNamespace(options.namespace);
|
|
86
|
+
if (options.prefix !== void 0) {
|
|
87
|
+
this.prefix = options.prefix === false ? "" : options.prefix;
|
|
88
|
+
this.#invalidate();
|
|
89
|
+
}
|
|
90
|
+
if (options.preflight !== void 0) this.preflight = options.preflight;
|
|
91
|
+
if (options.designPrinciples !== void 0) this.designPrinciples = [...options.designPrinciples];
|
|
92
|
+
if (options.buildOptions !== void 0) this.buildOptions = {
|
|
93
|
+
...this.buildOptions,
|
|
94
|
+
...options.buildOptions
|
|
95
|
+
};
|
|
96
|
+
return this;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Resolve a spec element `type` (or any component identifier) to its
|
|
100
|
+
* {@link Component}, namespace-aware and backwards-compatible.
|
|
101
|
+
*
|
|
102
|
+
* `components` is keyed by the bare `name`, so:
|
|
103
|
+
* - an exact match is tried first — a bare `'Badge'` resolves directly,
|
|
104
|
+
* keeping every existing bare-name lookup working;
|
|
105
|
+
* - otherwise a namespaced registry key (`'<namespace>:<name>'`, the spec
|
|
106
|
+
* `type`) resolves by its bare name **only when the namespace is this
|
|
107
|
+
* registry's own**. A key from a different registry (`'other:Badge'`)
|
|
108
|
+
* deliberately does not resolve, so specs from multiple registries can
|
|
109
|
+
* coexist without colliding on a shared bare name.
|
|
110
|
+
*
|
|
111
|
+
* Returns `undefined` for unknown types and foreign (`foreign:`) sentinels.
|
|
112
|
+
* This is the single resolution path consumers should use instead of
|
|
113
|
+
* `config.components.get(type)` when `type` may be a spec/registry key.
|
|
114
|
+
*/
|
|
115
|
+
getComponent(type) {
|
|
116
|
+
const direct = this.components.get(type);
|
|
117
|
+
if (direct) return direct;
|
|
118
|
+
const { namespace, name } = parseRegistryKey(type);
|
|
119
|
+
if (namespace !== void 0 && namespace === this.namespace) return this.components.get(name);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* The bare, human-readable component name for a spec `type` — strips this
|
|
123
|
+
* registry's `<namespace>:` prefix (`'uds:Text'` → `'Text'`) for display, and
|
|
124
|
+
* the `foreign:` sentinel third-party leaves carry (`'foreign:CopyIcon'` →
|
|
125
|
+
* `'CopyIcon'`) — that prefix marks "not a UDS component," not a peer system,
|
|
126
|
+
* so the bare name is what every display surface wants. A bare type, an
|
|
127
|
+
* unknown type, or a key from another *peer* registry (`@acme/system:Button`)
|
|
128
|
+
* is returned unchanged — there the prefix is meaningful disambiguation.
|
|
129
|
+
*/
|
|
130
|
+
componentDisplayName(type) {
|
|
131
|
+
const { namespace, name } = parseRegistryKey(type);
|
|
132
|
+
if (namespace === "foreign") return name;
|
|
133
|
+
return namespace !== void 0 && namespace === this.namespace ? name : type;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Components whose catalog `metadata.label` matches `label` (case-insensitive)
|
|
137
|
+
* — the display-name lookup that complements `getComponent` (registry key).
|
|
138
|
+
* Returns an array because labels aren't unique: a collision-dodging export
|
|
139
|
+
* (`StudioListItem` with `label: 'ListItem'`) can share a label with another
|
|
140
|
+
* component's key, so callers must handle 0, 1, or many. Empty when no label
|
|
141
|
+
* matches.
|
|
142
|
+
*/
|
|
143
|
+
getComponentsByLabel(label) {
|
|
144
|
+
const lower = label.toLowerCase();
|
|
145
|
+
const out = [];
|
|
146
|
+
for (const component of this.components.values()) if (component.metadata?.label?.toLowerCase() === lower) out.push(component);
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Style props that emit a given CSS property — the reverse of
|
|
151
|
+
* `StyleProp.cssProperty`. A property can be served by more than one prop
|
|
152
|
+
* (e.g. `border-color` by `borderColor`, `divideColor`; `margin-top` by both
|
|
153
|
+
* the positive `marginTop` and the `negative` `offsetTop`). Match is exact on
|
|
154
|
+
* the CSS property name; a prop targeting several properties matches any.
|
|
155
|
+
*
|
|
156
|
+
* `negative` props are ordered LAST, so a caller taking the first match
|
|
157
|
+
* (`getStylePropsByCssProperty(css)[0]`) always gets the primary, positive
|
|
158
|
+
* prop — the negative variant is only the first result when it's the sole
|
|
159
|
+
* prop for that property. Registration order is preserved within each group.
|
|
160
|
+
*
|
|
161
|
+
* Pass `opts.negative` to filter explicitly: `{ negative: false }` for only
|
|
162
|
+
* positive props, `{ negative: true }` for only the negative variant(s) (e.g.
|
|
163
|
+
* the `offsetTop` behind `margin-top`). Omit it to get every match.
|
|
164
|
+
*/
|
|
165
|
+
getStylePropsByCssProperty(cssProperty, opts) {
|
|
166
|
+
const out = [];
|
|
167
|
+
for (const styleProp of this.styleProps.values()) {
|
|
168
|
+
const css = styleProp.cssProperty;
|
|
169
|
+
if (!(Array.isArray(css) ? css.includes(cssProperty) : css === cssProperty)) continue;
|
|
170
|
+
if (opts?.negative !== void 0 && styleProp.negative !== opts.negative) continue;
|
|
171
|
+
out.push(styleProp);
|
|
172
|
+
}
|
|
173
|
+
return out.sort((a, b) => Number(a.negative) - Number(b.negative));
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Resolve the `StyleProp` behind a component's JSX prop, following any
|
|
177
|
+
* re-alias. A component can expose a style prop under a different JSX name
|
|
178
|
+
* than the registry key — `Box`'s `backgroundColor` prop binds
|
|
179
|
+
* `styleProp('bg')` — so this maps the on-component name back to the
|
|
180
|
+
* registered `StyleProp`. Returns `undefined` if the component has no such
|
|
181
|
+
* style prop.
|
|
182
|
+
*/
|
|
183
|
+
getComponentStyleProp(componentName, jsxProp) {
|
|
184
|
+
const component = this.getComponent(componentName);
|
|
185
|
+
if (!component) return void 0;
|
|
186
|
+
for (const info of component.derived.props) if (info.kind === "styleProp" && info.name === jsxProp) return this.styleProps.get(info.stylePropName);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Components that render `name` as one of their layers — the reverse of
|
|
190
|
+
* `Layer.renders`. Layer composition only; subcomponent parentage is a
|
|
191
|
+
* separate edge (`Component.derived.subcomponentOf`). The component slice of
|
|
192
|
+
* the public {@link Config.dependentsOf} read surface.
|
|
193
|
+
*/
|
|
194
|
+
#componentDependents(name) {
|
|
195
|
+
const out = [];
|
|
196
|
+
for (const component of this.components.values()) {
|
|
197
|
+
if (component.name === name) continue;
|
|
198
|
+
for (const layer of component.layers.values()) {
|
|
199
|
+
const renders = layer.renders;
|
|
200
|
+
if (renders?.kind === "component" && renders.ref === name) {
|
|
201
|
+
out.push(component.name);
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return out;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Components that expose a composite style as a prop (bound via
|
|
210
|
+
* `composite('<name>')`) — e.g. which components offer an `elevation`
|
|
211
|
+
* dropdown. The composite-style slice of {@link Config.dependentsOf}.
|
|
212
|
+
*/
|
|
213
|
+
#compositeStyleDependents(name) {
|
|
214
|
+
const out = [];
|
|
215
|
+
for (const component of this.components.values()) for (const info of component.derived.props) if (info.kind === "composite" && info.compositeName === name) {
|
|
216
|
+
out.push(component.name);
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
return out;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Components that expose a given style prop. Matches on the registered
|
|
223
|
+
* style-prop key (`info.stylePropName`), not the on-component JSX name, so a
|
|
224
|
+
* component that re-aliases the prop under a different name (a
|
|
225
|
+
* `backgroundColor` prop bound to `styleProp('bg')`) is still found; `as`
|
|
226
|
+
* carries that on-component name when it differs from the registry key. The
|
|
227
|
+
* style-prop slice of {@link Config.dependentsOf} (which keeps only the
|
|
228
|
+
* component name).
|
|
229
|
+
*/
|
|
230
|
+
#stylePropDependents(name) {
|
|
231
|
+
const out = [];
|
|
232
|
+
for (const component of this.components.values()) for (const info of component.derived.props) if (info.kind === "styleProp" && info.stylePropName === name) {
|
|
233
|
+
out.push({
|
|
234
|
+
component: component.name,
|
|
235
|
+
as: info.name
|
|
236
|
+
});
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
return out;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Style props that draw their values from a given token group — the group's
|
|
243
|
+
* "defined in" relation: a style prop references a group through its `values`
|
|
244
|
+
* array (`bg` ← `tokenGroup('color')`). Only style props reference token
|
|
245
|
+
* groups today, so the result is style-prop names; empty for an unknown
|
|
246
|
+
* group. The token-group slice of {@link Config.dependentsOf}; the *member*
|
|
247
|
+
* usage ("used in") is the separate {@link Config.getTokenGroupUsage}.
|
|
248
|
+
*/
|
|
249
|
+
#tokenGroupDependents(namespace) {
|
|
250
|
+
const group = this.tokenGroups.get(namespace);
|
|
251
|
+
return group ? [...group.derived.styleProperties] : [];
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Components that reference a given token anywhere in their styling. Reads
|
|
255
|
+
* the structural `Component.derived.tokenRefs` (which captures both
|
|
256
|
+
* `token(...)` refs and shorthand style-prop values, across base / variants /
|
|
257
|
+
* compound), so the match is on token *identity*, not CSS-var or substring
|
|
258
|
+
* matching. `name` may be qualified (`color/brand`) or bare (`brand`) — a
|
|
259
|
+
* bare name matches the token part in any group. The component half of a
|
|
260
|
+
* token's referrers in {@link Config.dependentsOf}; the token half is
|
|
261
|
+
* {@link Config.#tokenTokenDependents}.
|
|
262
|
+
*/
|
|
263
|
+
#tokenComponentDependents(name) {
|
|
264
|
+
const qualified = name.includes("/");
|
|
265
|
+
const out = [];
|
|
266
|
+
for (const component of this.components.values()) {
|
|
267
|
+
const refs = component.derived.tokenRefs;
|
|
268
|
+
if (qualified ? refs.includes(name) : refs.some((ref) => ref.slice(ref.indexOf("/") + 1) === name)) out.push(component.name);
|
|
269
|
+
}
|
|
270
|
+
return out;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Other tokens that reference a given token — the "which tokens alias or
|
|
274
|
+
* mode-override this one?" lookup. Walks each token's value + modifiers for
|
|
275
|
+
* `token()` refs (the same structural channel `tokenUsageStats` counts).
|
|
276
|
+
* Returns qualified token names; `name` may be qualified or bare. Excludes
|
|
277
|
+
* self. The token half of a token's referrers in {@link Config.dependentsOf}.
|
|
278
|
+
*/
|
|
279
|
+
#tokenTokenDependents(name) {
|
|
280
|
+
const qualified = name.includes("/");
|
|
281
|
+
const out = [];
|
|
282
|
+
for (const [qualifiedName, token] of this.derived.tokens) {
|
|
283
|
+
if (qualifiedName === name) continue;
|
|
284
|
+
const refs = /* @__PURE__ */ new Set();
|
|
285
|
+
this.#collectStyleTokenRefs(token.value, refs, /* @__PURE__ */ new WeakSet());
|
|
286
|
+
if (token.modifiers) this.#collectStyleTokenRefs(token.modifiers, refs, /* @__PURE__ */ new WeakSet());
|
|
287
|
+
if (qualified ? refs.has(name) : [...refs].some((ref) => ref.slice(ref.indexOf("/") + 1) === name)) out.push(qualifiedName);
|
|
288
|
+
}
|
|
289
|
+
return out;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Every qualified token name referenced *anywhere* in the system — the
|
|
293
|
+
* "used somewhere" set. Three reference channels, so a token reached only
|
|
294
|
+
* through one of them (e.g. a raw spectrum step a semantic token aliases,
|
|
295
|
+
* never touched by a component directly) still counts as used:
|
|
296
|
+
* - **components** — the structural `tokenRefs` union;
|
|
297
|
+
* - **token → token** — a token's value or a mode-override referencing
|
|
298
|
+
* another via `token()` (aliases, `_dark` swaps);
|
|
299
|
+
* - **composite styles** — `token()` refs and shorthand values in each bag.
|
|
300
|
+
*/
|
|
301
|
+
#referencedTokenNames() {
|
|
302
|
+
const refs = /* @__PURE__ */ new Set();
|
|
303
|
+
for (const component of this.components.values()) for (const ref of component.derived.tokenRefs) refs.add(ref);
|
|
304
|
+
for (const token of this.derived.tokens.values()) {
|
|
305
|
+
this.#collectStyleTokenRefs(token.value, refs, /* @__PURE__ */ new WeakSet());
|
|
306
|
+
if (token.modifiers) this.#collectStyleTokenRefs(token.modifiers, refs, /* @__PURE__ */ new WeakSet());
|
|
307
|
+
}
|
|
308
|
+
for (const composite of this.compositeStyles.values()) for (const bag of composite.styles.values()) this.#collectStyleTokenRefs(bag, refs, /* @__PURE__ */ new WeakSet());
|
|
309
|
+
return refs;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Walk an arbitrary value (a token value, modifier map, or composite-style
|
|
313
|
+
* bag), collecting every token it references into `refs`: structured
|
|
314
|
+
* `token()` refs by identity (including ones nested in a color expression),
|
|
315
|
+
* and bare style-prop shorthand values resolved through the registry.
|
|
316
|
+
*/
|
|
317
|
+
#collectStyleTokenRefs(node, refs, seen) {
|
|
318
|
+
if (node === null || typeof node !== "object") return;
|
|
319
|
+
if (isTokenRef(node)) {
|
|
320
|
+
refs.add(node.ref);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
if (seen.has(node)) return;
|
|
324
|
+
seen.add(node);
|
|
325
|
+
if (Array.isArray(node)) {
|
|
326
|
+
for (const item of node) this.#collectStyleTokenRefs(item, refs, seen);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
for (const [key, value] of Object.entries(node)) {
|
|
330
|
+
if (key.startsWith("__")) continue;
|
|
331
|
+
if (typeof value === "string") {
|
|
332
|
+
const ref = this.#resolveStylePropValueToken(key, value);
|
|
333
|
+
if (ref) refs.add(ref);
|
|
334
|
+
} else this.#collectStyleTokenRefs(value, refs, seen);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Aggregate token-usage stats across the whole registry — how many tokens
|
|
339
|
+
* are referenced *somewhere* (components, other tokens, or composite styles;
|
|
340
|
+
* see {@link Config.#referencedTokenNames}) vs not. `usagePercent` is
|
|
341
|
+
* rounded; `0` total tokens reports `0%`.
|
|
342
|
+
*/
|
|
343
|
+
tokenUsageStats() {
|
|
344
|
+
const referenced = this.#referencedTokenNames();
|
|
345
|
+
const tokens = [...this.derived.tokens.keys()];
|
|
346
|
+
const total = tokens.length;
|
|
347
|
+
const used = tokens.filter((name) => referenced.has(name)).length;
|
|
348
|
+
const usagePercent = total === 0 ? 0 : Math.round(used / total * 100);
|
|
349
|
+
return {
|
|
350
|
+
total,
|
|
351
|
+
used,
|
|
352
|
+
unused: total - used,
|
|
353
|
+
usagePercent
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Token values ranked by how often they appear across component base styles —
|
|
358
|
+
* the aggregate "what's load-bearing?" companion to `dependentsOf('token')`.
|
|
359
|
+
* `opts.property` narrows to one CSS property. Descends into `_<modifier>`
|
|
360
|
+
* sub-objects so a value used only in a hover/dark state still counts.
|
|
361
|
+
*/
|
|
362
|
+
tokenValueUsage(opts) {
|
|
363
|
+
const property = opts?.property;
|
|
364
|
+
const counts = /* @__PURE__ */ new Map();
|
|
365
|
+
const collect = (styles) => {
|
|
366
|
+
for (const [prop, value] of Object.entries(styles)) if (typeof value === "string") {
|
|
367
|
+
if (property && prop.toLowerCase() !== property.toLowerCase()) continue;
|
|
368
|
+
const key = `${prop}:${value}`;
|
|
369
|
+
const existing = counts.get(key);
|
|
370
|
+
if (existing) existing.count++;
|
|
371
|
+
else counts.set(key, {
|
|
372
|
+
count: 1,
|
|
373
|
+
property: prop
|
|
374
|
+
});
|
|
375
|
+
} else if (isStyleRecord(value) && prop.startsWith("_")) collect(value);
|
|
376
|
+
};
|
|
377
|
+
for (const component of this.components.values()) {
|
|
378
|
+
if (!component.base) continue;
|
|
379
|
+
for (const styles of Object.values(component.base)) if (isStyleRecord(styles)) collect(styles);
|
|
380
|
+
}
|
|
381
|
+
return [...counts.entries()].map(([key, data]) => ({
|
|
382
|
+
value: key.slice(key.indexOf(":") + 1),
|
|
383
|
+
count: data.count,
|
|
384
|
+
property: data.property
|
|
385
|
+
})).sort((a, b) => b.count - a.count);
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* The reverse-dependency read surface — "what references this entity, and
|
|
389
|
+
* would break if I delete or rename it?" — uniform across every kind. One
|
|
390
|
+
* public entry point: callers dispatch by `kind` and get a single tagged
|
|
391
|
+
* list (the affected entities, each with its own kind), never a per-kind
|
|
392
|
+
* bespoke shape. The relation is always *references to the entity*; the
|
|
393
|
+
* per-kind walks behind it are private slices.
|
|
394
|
+
*
|
|
395
|
+
* A `token` resolves to BOTH the components that reference it AND the tokens
|
|
396
|
+
* that alias or mode-override it — a token's full referrer set, not split
|
|
397
|
+
* across two methods. A `modifier` flattens its components, composite styles,
|
|
398
|
+
* and token-group namespaces into the one tagged list. A token group's other
|
|
399
|
+
* relation — what actually *uses* its member tokens — is the separate
|
|
400
|
+
* {@link Config.getTokenGroupUsage} (only containers have it); ranking every
|
|
401
|
+
* entity of a kind at once is {@link Config.componentDependentCounts} & co.
|
|
402
|
+
*/
|
|
403
|
+
dependentsOf(query) {
|
|
404
|
+
switch (query.kind) {
|
|
405
|
+
case "component": return this.#componentDependents(query.name).map((name) => ({
|
|
406
|
+
kind: "component",
|
|
407
|
+
name
|
|
408
|
+
}));
|
|
409
|
+
case "compositeStyle": return this.#compositeStyleDependents(query.name).map((name) => ({
|
|
410
|
+
kind: "component",
|
|
411
|
+
name
|
|
412
|
+
}));
|
|
413
|
+
case "styleProp":
|
|
414
|
+
if (query.value === void 0) return this.#stylePropDependents(query.name).map((d) => ({
|
|
415
|
+
kind: "component",
|
|
416
|
+
name: d.component
|
|
417
|
+
}));
|
|
418
|
+
return this.#stylePropKeywordDependents(query.name, query.value).map((name) => ({
|
|
419
|
+
kind: "component",
|
|
420
|
+
name
|
|
421
|
+
}));
|
|
422
|
+
case "token": return [...this.#tokenComponentDependents(query.name).map((name) => ({
|
|
423
|
+
kind: "component",
|
|
424
|
+
name
|
|
425
|
+
})), ...this.#tokenTokenDependents(query.name).map((name) => ({
|
|
426
|
+
kind: "token",
|
|
427
|
+
name
|
|
428
|
+
}))];
|
|
429
|
+
case "tokenGroup": return this.#tokenGroupDependents(query.name).map((name) => ({
|
|
430
|
+
kind: "styleProp",
|
|
431
|
+
name
|
|
432
|
+
}));
|
|
433
|
+
case "modifier": {
|
|
434
|
+
const m = this.#modifierDependents(query.name);
|
|
435
|
+
return [
|
|
436
|
+
...m.components.map((name) => ({
|
|
437
|
+
kind: "component",
|
|
438
|
+
name
|
|
439
|
+
})),
|
|
440
|
+
...m.compositeStyles.map((name) => ({
|
|
441
|
+
kind: "compositeStyle",
|
|
442
|
+
name
|
|
443
|
+
})),
|
|
444
|
+
...m.tokenGroups.map((name) => ({
|
|
445
|
+
kind: "tokenGroup",
|
|
446
|
+
name
|
|
447
|
+
}))
|
|
448
|
+
];
|
|
449
|
+
}
|
|
450
|
+
default: return assertNever(query);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* The outbound mirror of {@link Config.dependentsOf} — "what does this entity
|
|
455
|
+
* *use*, and would I have to update if I delete those?". Same tagged
|
|
456
|
+
* `DependencyRef[]` shape, same `kind`-keyed exhaustiveness. A `component`
|
|
457
|
+
* reports the tokens it references, the keyword values it sets
|
|
458
|
+
* (`{ kind: 'styleProp', name, value }`), the composites and style props it
|
|
459
|
+
* binds, the components it renders as layers, and the modifiers it styles
|
|
460
|
+
* with; a `token` reports the tokens it aliases and the modifiers in its mode
|
|
461
|
+
* overrides; a `styleProp` reports the token groups it draws from. `modifier`
|
|
462
|
+
* and `tokenGroup` are leaves here — a selector and a container don't *use*
|
|
463
|
+
* other registry entities — so they report nothing.
|
|
464
|
+
*/
|
|
465
|
+
dependenciesOf(query) {
|
|
466
|
+
switch (query.kind) {
|
|
467
|
+
case "component": return this.#componentDependencies(query.name);
|
|
468
|
+
case "token": return this.#tokenDependencies(query.name);
|
|
469
|
+
case "styleProp": {
|
|
470
|
+
const sp = this.styleProps.get(query.name);
|
|
471
|
+
if (!sp) return [];
|
|
472
|
+
return [...new Set(sp.consumedTokenGroups())].map((name) => ({
|
|
473
|
+
kind: "tokenGroup",
|
|
474
|
+
name
|
|
475
|
+
}));
|
|
476
|
+
}
|
|
477
|
+
case "compositeStyle": return this.#compositeStyleDependencies(query.name);
|
|
478
|
+
case "tokenGroup": {
|
|
479
|
+
const group = this.tokenGroups.get(query.name);
|
|
480
|
+
if (!group) return [];
|
|
481
|
+
return [...group.tokens.keys()].map((leaf) => ({
|
|
482
|
+
kind: "token",
|
|
483
|
+
name: `${query.name}/${leaf}`
|
|
484
|
+
}));
|
|
485
|
+
}
|
|
486
|
+
case "modifier": return [];
|
|
487
|
+
default: return assertNever(query);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Components that use a given style-prop *keyword* value — the "what breaks
|
|
492
|
+
* if I remove the `flex` value from `display`?" lookup, the value-narrowed
|
|
493
|
+
* slice of `dependentsOf({ kind: 'styleProp', name, value })`. Scoped to the
|
|
494
|
+
* `(styleProp, value)` pair (keywords aren't global — `col` on `flexDirection`
|
|
495
|
+
* is unrelated to `col` elsewhere), reading `derived.stylePropKeywords`.
|
|
496
|
+
*/
|
|
497
|
+
#stylePropKeywordDependents(styleProp, value) {
|
|
498
|
+
const out = [];
|
|
499
|
+
for (const component of this.components.values()) if (component.derived.stylePropKeywords.some((kw) => kw.styleProp === styleProp && kw.value === value)) out.push(component.name);
|
|
500
|
+
return out;
|
|
501
|
+
}
|
|
502
|
+
/** Outbound edges of a component — its `dependenciesOf` slice: the tokens it
|
|
503
|
+
* references, the keyword values it sets, the composites + style props it
|
|
504
|
+
* binds, the components it renders as layers, and the modifiers it styles
|
|
505
|
+
* with. Deduped across those sources. */
|
|
506
|
+
#componentDependencies(name) {
|
|
507
|
+
const component = this.getComponent(name);
|
|
508
|
+
if (!component) return [];
|
|
509
|
+
const out = [];
|
|
510
|
+
const d = component.derived;
|
|
511
|
+
for (const ref of d.tokenRefs) out.push({
|
|
512
|
+
kind: "token",
|
|
513
|
+
name: ref
|
|
514
|
+
});
|
|
515
|
+
for (const kw of d.stylePropKeywords) out.push({
|
|
516
|
+
kind: "styleProp",
|
|
517
|
+
name: kw.styleProp,
|
|
518
|
+
value: kw.value
|
|
519
|
+
});
|
|
520
|
+
for (const info of d.props) if (info.kind === "composite") out.push({
|
|
521
|
+
kind: "compositeStyle",
|
|
522
|
+
name: info.compositeName
|
|
523
|
+
});
|
|
524
|
+
else if (info.kind === "styleProp") out.push({
|
|
525
|
+
kind: "styleProp",
|
|
526
|
+
name: info.stylePropName
|
|
527
|
+
});
|
|
528
|
+
for (const layer of component.layers.values()) {
|
|
529
|
+
const renders = layer.renders;
|
|
530
|
+
if (renders?.kind === "component" && renders.ref !== component.name) out.push({
|
|
531
|
+
kind: "component",
|
|
532
|
+
name: renders.ref
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
const mods = /* @__PURE__ */ new Set();
|
|
536
|
+
if (component.base) this.#collectModifierKeys(component.base, mods);
|
|
537
|
+
for (const binding of Object.values(component.props)) this.#collectModifierKeys(binding, mods);
|
|
538
|
+
for (const entry of component.compoundProps ?? []) this.#collectModifierKeys(entry.layers, mods);
|
|
539
|
+
for (const mod of mods) out.push({
|
|
540
|
+
kind: "modifier",
|
|
541
|
+
name: mod
|
|
542
|
+
});
|
|
543
|
+
return this.#dedupeRefs(out);
|
|
544
|
+
}
|
|
545
|
+
/** Outbound edges of a token — the tokens it aliases (value + mode overrides)
|
|
546
|
+
* and the modifiers carrying those overrides. `name` must be qualified. */
|
|
547
|
+
#tokenDependencies(name) {
|
|
548
|
+
const token = this.derived.tokens.get(name);
|
|
549
|
+
if (!token) return [];
|
|
550
|
+
const out = [];
|
|
551
|
+
const refs = /* @__PURE__ */ new Set();
|
|
552
|
+
this.#collectStyleTokenRefs(token.value, refs, /* @__PURE__ */ new WeakSet());
|
|
553
|
+
if (token.modifiers) this.#collectStyleTokenRefs(token.modifiers, refs, /* @__PURE__ */ new WeakSet());
|
|
554
|
+
for (const ref of refs) if (ref !== name) out.push({
|
|
555
|
+
kind: "token",
|
|
556
|
+
name: ref
|
|
557
|
+
});
|
|
558
|
+
for (const key of Object.keys(token.modifiers ?? {})) if (this.modifiers.has(key)) out.push({
|
|
559
|
+
kind: "modifier",
|
|
560
|
+
name: key
|
|
561
|
+
});
|
|
562
|
+
return out;
|
|
563
|
+
}
|
|
564
|
+
/** Outbound edges of a composite style — the tokens and modifiers across its
|
|
565
|
+
* variant style bags. */
|
|
566
|
+
#compositeStyleDependencies(name) {
|
|
567
|
+
const cs = this.compositeStyles.get(name);
|
|
568
|
+
if (!cs) return [];
|
|
569
|
+
const refs = /* @__PURE__ */ new Set();
|
|
570
|
+
const mods = /* @__PURE__ */ new Set();
|
|
571
|
+
for (const bag of cs.styles.values()) {
|
|
572
|
+
this.#collectStyleTokenRefs(bag, refs, /* @__PURE__ */ new WeakSet());
|
|
573
|
+
this.#collectModifierKeys(bag, mods);
|
|
574
|
+
}
|
|
575
|
+
return [...[...refs].map((name) => ({
|
|
576
|
+
kind: "token",
|
|
577
|
+
name
|
|
578
|
+
})), ...[...mods].map((name) => ({
|
|
579
|
+
kind: "modifier",
|
|
580
|
+
name
|
|
581
|
+
}))];
|
|
582
|
+
}
|
|
583
|
+
/** Collect every registered single-underscore modifier key reachable in a
|
|
584
|
+
* styling node (skipping `__`-internals), into `into`. */
|
|
585
|
+
#collectModifierKeys(node, into, seen = /* @__PURE__ */ new WeakSet()) {
|
|
586
|
+
if (node === null || typeof node !== "object") return;
|
|
587
|
+
if (seen.has(node)) return;
|
|
588
|
+
seen.add(node);
|
|
589
|
+
for (const [key, value] of Object.entries(node)) {
|
|
590
|
+
if (key.startsWith("__")) continue;
|
|
591
|
+
if (key.startsWith("_") && this.modifiers.has(key)) into.add(key);
|
|
592
|
+
this.#collectModifierKeys(value, into, seen);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
/** Dedupe a `DependencyRef[]` by `(kind, name, value)`. */
|
|
596
|
+
#dedupeRefs(refs) {
|
|
597
|
+
const seen = /* @__PURE__ */ new Set();
|
|
598
|
+
const out = [];
|
|
599
|
+
for (const ref of refs) {
|
|
600
|
+
const key = `${ref.kind} ${ref.name} ${ref.value ?? ""}`;
|
|
601
|
+
if (seen.has(key)) continue;
|
|
602
|
+
seen.add(key);
|
|
603
|
+
out.push(ref);
|
|
604
|
+
}
|
|
605
|
+
return out;
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Everything that references a modifier (`_hover`, `_dataStateOpen`, `_dark`)
|
|
609
|
+
* in its own styling. Walks all the places a `_<modifier>` key can appear:
|
|
610
|
+
* - **components**: `base`, each variant's per-layer styles, and
|
|
611
|
+
* `compoundProps` layer overrides;
|
|
612
|
+
* - **compositeStyles**: each variant bag;
|
|
613
|
+
* - **tokenGroups**: tokens carrying a `_<modifier>` mode override (e.g.
|
|
614
|
+
* `{ value, _dark }`) — grouped by namespace since a mode modifier touches
|
|
615
|
+
* many tokens at once.
|
|
616
|
+
* Matches single-underscore modifier keys only (skips `__kind` etc.). The
|
|
617
|
+
* modifier slice of {@link Config.dependentsOf}, which flattens the three
|
|
618
|
+
* buckets into one tagged list.
|
|
619
|
+
*/
|
|
620
|
+
#modifierDependents(modifier) {
|
|
621
|
+
const usesModifier = (node, seen = /* @__PURE__ */ new WeakSet()) => {
|
|
622
|
+
if (node === null || typeof node !== "object") return false;
|
|
623
|
+
if (seen.has(node)) return false;
|
|
624
|
+
seen.add(node);
|
|
625
|
+
for (const [key, value] of Object.entries(node)) {
|
|
626
|
+
if (key === modifier) return true;
|
|
627
|
+
if (key.startsWith("__")) continue;
|
|
628
|
+
if (usesModifier(value, seen)) return true;
|
|
629
|
+
}
|
|
630
|
+
return false;
|
|
631
|
+
};
|
|
632
|
+
const components = [];
|
|
633
|
+
for (const component of this.components.values()) {
|
|
634
|
+
const inBase = component.base ? usesModifier(component.base) : false;
|
|
635
|
+
const inProps = !inBase && Object.values(component.props).some((binding) => usesModifier(binding));
|
|
636
|
+
const inCompound = !inBase && !inProps && (component.compoundProps?.some((e) => usesModifier(e.layers)) ?? false);
|
|
637
|
+
if (inBase || inProps || inCompound) components.push(component.name);
|
|
638
|
+
}
|
|
639
|
+
const compositeStyles = [];
|
|
640
|
+
for (const cs of this.compositeStyles.values()) for (const bag of cs.styles.values()) if (usesModifier(bag)) {
|
|
641
|
+
compositeStyles.push(cs.name);
|
|
642
|
+
break;
|
|
643
|
+
}
|
|
644
|
+
const tokenGroups = [];
|
|
645
|
+
for (const group of this.tokenGroups.values()) for (const token of group.tokens.values()) if (token.modifiers && Object.hasOwn(token.modifiers, modifier)) {
|
|
646
|
+
tokenGroups.push(group.namespace);
|
|
647
|
+
break;
|
|
648
|
+
}
|
|
649
|
+
return {
|
|
650
|
+
components,
|
|
651
|
+
compositeStyles,
|
|
652
|
+
tokenGroups
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
/**
|
|
656
|
+
* The aggregate sibling of {@link Config.dependentsOf} — for *every* entity of
|
|
657
|
+
* a kind at once, how many dependents each has (`Map<name, count>`, ranked by
|
|
658
|
+
* `uds_analyze_usage`). A single entity's count is just
|
|
659
|
+
* `dependentsOf(query).length`; this exists for the all-at-once case, where
|
|
660
|
+
* calling that per entity would re-walk the component set N times
|
|
661
|
+
* (O(N × components)) — each private slice walks once (O(components)) and
|
|
662
|
+
* tallies as it goes, kept consistent with `dependentsOf` (a dependent
|
|
663
|
+
* counted once per entity, self-references excluded; the cross-check tests
|
|
664
|
+
* assert the equivalence against the live config).
|
|
665
|
+
*/
|
|
666
|
+
dependentCounts(kind) {
|
|
667
|
+
switch (kind) {
|
|
668
|
+
case "component": return this.#componentDependentCounts();
|
|
669
|
+
case "compositeStyle": return this.#compositeStyleDependentCounts();
|
|
670
|
+
case "styleProp": return this.#stylePropDependentCounts();
|
|
671
|
+
case "tokenGroup": return this.#tokenGroupDependentCounts();
|
|
672
|
+
case "modifier": return this.#modifierDependentCounts();
|
|
673
|
+
case "token": return this.#tokenDependentCounts();
|
|
674
|
+
default: return assertNever(kind);
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
#componentDependentCounts() {
|
|
678
|
+
const counts = /* @__PURE__ */ new Map();
|
|
679
|
+
for (const component of this.components.values()) {
|
|
680
|
+
const refs = /* @__PURE__ */ new Set();
|
|
681
|
+
for (const layer of component.layers.values()) {
|
|
682
|
+
const renders = layer.renders;
|
|
683
|
+
if (renders?.kind === "component" && renders.ref !== component.name) refs.add(renders.ref);
|
|
684
|
+
}
|
|
685
|
+
for (const ref of refs) counts.set(ref, (counts.get(ref) ?? 0) + 1);
|
|
686
|
+
}
|
|
687
|
+
return counts;
|
|
688
|
+
}
|
|
689
|
+
#compositeStyleDependentCounts() {
|
|
690
|
+
const counts = /* @__PURE__ */ new Map();
|
|
691
|
+
for (const component of this.components.values()) {
|
|
692
|
+
const names = /* @__PURE__ */ new Set();
|
|
693
|
+
for (const info of component.derived.props) if (info.kind === "composite") names.add(info.compositeName);
|
|
694
|
+
for (const name of names) counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
695
|
+
}
|
|
696
|
+
return counts;
|
|
697
|
+
}
|
|
698
|
+
#stylePropDependentCounts() {
|
|
699
|
+
const counts = /* @__PURE__ */ new Map();
|
|
700
|
+
for (const component of this.components.values()) {
|
|
701
|
+
const names = /* @__PURE__ */ new Set();
|
|
702
|
+
for (const info of component.derived.props) if (info.kind === "styleProp") names.add(info.stylePropName);
|
|
703
|
+
for (const name of names) counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
704
|
+
}
|
|
705
|
+
return counts;
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Single-pass companion to `dependentsOf('tokenGroup', …)` — how many style props
|
|
709
|
+
* draw from each token-group namespace. Walks the style props once (the
|
|
710
|
+
* forward `consumedTokenGroups` direction) rather than re-deriving each
|
|
711
|
+
* group's consumer list, counting a prop once per group it references.
|
|
712
|
+
*/
|
|
713
|
+
#tokenGroupDependentCounts() {
|
|
714
|
+
const counts = /* @__PURE__ */ new Map();
|
|
715
|
+
for (const styleProp of this.styleProps.values()) for (const namespace of new Set(styleProp.consumedTokenGroups())) counts.set(namespace, (counts.get(namespace) ?? 0) + 1);
|
|
716
|
+
return counts;
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Single-pass companion to `dependentsOf('modifier', …)` — the total it sums per
|
|
720
|
+
* modifier (components + composite styles + token-group namespaces that
|
|
721
|
+
* reference it). Mirrors the modifier walk's traversal rules: gathers every
|
|
722
|
+
* single-underscore key (skipping `__`-prefixed internals, so a slot's
|
|
723
|
+
* `__accepts` child definitions never leak in), counts each source once per
|
|
724
|
+
* modifier, and tallies only registered modifiers.
|
|
725
|
+
*/
|
|
726
|
+
#modifierDependentCounts() {
|
|
727
|
+
const counts = /* @__PURE__ */ new Map();
|
|
728
|
+
const bump = (key, into) => {
|
|
729
|
+
if (this.modifiers.has(key)) into.add(key);
|
|
730
|
+
};
|
|
731
|
+
const collect = (node, into, seen = /* @__PURE__ */ new WeakSet()) => {
|
|
732
|
+
if (node === null || typeof node !== "object") return;
|
|
733
|
+
if (seen.has(node)) return;
|
|
734
|
+
seen.add(node);
|
|
735
|
+
for (const [key, value] of Object.entries(node)) {
|
|
736
|
+
if (key.startsWith("__")) continue;
|
|
737
|
+
if (key.startsWith("_")) bump(key, into);
|
|
738
|
+
collect(value, into, seen);
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
const tally = (keys) => {
|
|
742
|
+
for (const key of keys) counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
743
|
+
};
|
|
744
|
+
for (const component of this.components.values()) {
|
|
745
|
+
const keys = /* @__PURE__ */ new Set();
|
|
746
|
+
if (component.base) collect(component.base, keys);
|
|
747
|
+
for (const binding of Object.values(component.props)) collect(binding, keys);
|
|
748
|
+
for (const entry of component.compoundProps ?? []) collect(entry.layers, keys);
|
|
749
|
+
tally(keys);
|
|
750
|
+
}
|
|
751
|
+
for (const cs of this.compositeStyles.values()) {
|
|
752
|
+
const keys = /* @__PURE__ */ new Set();
|
|
753
|
+
for (const bag of cs.styles.values()) collect(bag, keys);
|
|
754
|
+
tally(keys);
|
|
755
|
+
}
|
|
756
|
+
for (const group of this.tokenGroups.values()) {
|
|
757
|
+
const keys = /* @__PURE__ */ new Set();
|
|
758
|
+
for (const token of group.tokens.values()) for (const key of Object.keys(token.modifiers ?? {})) bump(key, keys);
|
|
759
|
+
tally(keys);
|
|
760
|
+
}
|
|
761
|
+
return counts;
|
|
762
|
+
}
|
|
763
|
+
/** Single-pass `dependentCounts('token')` — referrers per token: each
|
|
764
|
+
* component counted once per token it references, plus each token that
|
|
765
|
+
* aliases/mode-overrides another (self excluded). Mirrors the union
|
|
766
|
+
* `dependentsOf({ kind: 'token' })` returns. */
|
|
767
|
+
#tokenDependentCounts() {
|
|
768
|
+
const counts = /* @__PURE__ */ new Map();
|
|
769
|
+
const bump = (name) => counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
770
|
+
for (const component of this.components.values()) for (const ref of new Set(component.derived.tokenRefs)) bump(ref);
|
|
771
|
+
for (const [qualifiedName, token] of this.derived.tokens) {
|
|
772
|
+
const refs = /* @__PURE__ */ new Set();
|
|
773
|
+
this.#collectStyleTokenRefs(token.value, refs, /* @__PURE__ */ new WeakSet());
|
|
774
|
+
if (token.modifiers) this.#collectStyleTokenRefs(token.modifiers, refs, /* @__PURE__ */ new WeakSet());
|
|
775
|
+
for (const ref of refs) if (ref !== qualifiedName) bump(ref);
|
|
776
|
+
}
|
|
777
|
+
return counts;
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* A component's style-prop surface as a delta against a base set, so
|
|
781
|
+
* consumers can render "inherits Box (226); adds …; removes …" instead of
|
|
782
|
+
* re-emitting the full ~226-name list per component. The base is the
|
|
783
|
+
* `extendsFrom` parent's set when value-extending, else the union across the
|
|
784
|
+
* `primitives` group (the set every primitive shares). `baseSource` is the
|
|
785
|
+
* parent's name, or `undefined` when the base is the primitives union — every
|
|
786
|
+
* `extends:Box` primitive has an identical set today, so `adds`/`removes` are
|
|
787
|
+
* usually empty, which is the dedup the projection relies on.
|
|
788
|
+
*/
|
|
789
|
+
stylePropSummary(component) {
|
|
790
|
+
const own = component.derived.stylePropNames;
|
|
791
|
+
const parent = component.extendsFrom ? this.components.get(component.extendsFrom) : void 0;
|
|
792
|
+
const baseSource = parent ? component.extendsFrom : void 0;
|
|
793
|
+
const base = parent ? parent.derived.stylePropNames : this.#primitivesStyleProps();
|
|
794
|
+
const baseSet = new Set(base);
|
|
795
|
+
const ownSet = new Set(own);
|
|
796
|
+
return {
|
|
797
|
+
own,
|
|
798
|
+
base,
|
|
799
|
+
baseSource,
|
|
800
|
+
adds: own.filter((n) => !baseSet.has(n)),
|
|
801
|
+
removes: baseSource ? base.filter((n) => !ownSet.has(n)) : []
|
|
802
|
+
};
|
|
803
|
+
}
|
|
804
|
+
/** Union of style-prop names across the `primitives` group — the comparison
|
|
805
|
+
* base for root components (no `extendsFrom`, e.g. `Box`). */
|
|
806
|
+
#primitivesStyleProps() {
|
|
807
|
+
const names = /* @__PURE__ */ new Set();
|
|
808
|
+
for (const component of this.components.values()) if (component.derived.componentGroup === "primitives") for (const n of component.derived.stylePropNames) names.add(n);
|
|
809
|
+
return [...names];
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Author global CSS — a selector → declarations bag. The callback
|
|
813
|
+
* form receives the same 2D CSS-var ref table as `derived.cssVarRefs`
|
|
814
|
+
* (`tokens.bg.primary` resolves to a `var(--uds-bg-primary)` brand)
|
|
815
|
+
* so consumers can reach for token values without re-deriving them.
|
|
816
|
+
* Mirrors the old `@uds/config` `defineGlobalStyles` chain.
|
|
817
|
+
*/
|
|
818
|
+
defineGlobalStyles(input) {
|
|
819
|
+
this.globalStyles = typeof input === "function" ? input(this.derived.cssVarRefs) : input;
|
|
820
|
+
return this;
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Include a raw CSS string verbatim in the generated stylesheet — for
|
|
824
|
+
* declarations the token/style-prop system can't express, most commonly
|
|
825
|
+
* `@font-face` blocks (the codegen pipeline emits none on its own) plus
|
|
826
|
+
* the `:root { --<prefix>-font-family-<id>: … }` definitions that font
|
|
827
|
+
* tokens reference. Accumulates across calls.
|
|
828
|
+
*
|
|
829
|
+
* Takes the CSS *content*, not a path, so `Config` stays free of Node
|
|
830
|
+
* `fs` and remains importable in the browser/runtime. Read the file in
|
|
831
|
+
* `uds.config.ts` (Node context) and pass the string:
|
|
832
|
+
*
|
|
833
|
+
* ```ts
|
|
834
|
+
* import { readFileSync } from 'node:fs';
|
|
835
|
+
* const fontsCss = readFileSync(new URL('./fonts.css', import.meta.url), 'utf8');
|
|
836
|
+
* export default defineConfig({ … }).includeCss(fontsCss);
|
|
837
|
+
* ```
|
|
838
|
+
*
|
|
839
|
+
* Injected after Tailwind compilation and the unused-var purge, so
|
|
840
|
+
* `@font-face` families and any custom properties it declares are never
|
|
841
|
+
* stripped as "unused".
|
|
842
|
+
*/
|
|
843
|
+
includeCss(css) {
|
|
844
|
+
this.rawCss.push(css);
|
|
845
|
+
return this;
|
|
846
|
+
}
|
|
847
|
+
registerModes(modes) {
|
|
848
|
+
for (const [name, def] of Object.entries(modes)) this.modes.set(name, new Mode({
|
|
849
|
+
name,
|
|
850
|
+
definition: def
|
|
851
|
+
}));
|
|
852
|
+
return this;
|
|
853
|
+
}
|
|
854
|
+
registerModifiers(modifiers) {
|
|
855
|
+
for (const [name, def] of Object.entries(modifiers)) {
|
|
856
|
+
const key = name;
|
|
857
|
+
this.modifiers.set(key, new Modifier({
|
|
858
|
+
name: key,
|
|
859
|
+
definition: def,
|
|
860
|
+
compositeLookup: (ref) => this.#lookupCompositeSelector(ref),
|
|
861
|
+
modeLookup: (ref) => this.#lookupModeSelector(ref)
|
|
862
|
+
}));
|
|
863
|
+
}
|
|
864
|
+
return this;
|
|
865
|
+
}
|
|
866
|
+
registerTokenGroups(groups) {
|
|
867
|
+
for (const [namespace, def] of Object.entries(groups)) this.tokenGroups.set(namespace, new TokenGroup({
|
|
868
|
+
namespace,
|
|
869
|
+
prefixGetter: () => this.prefix,
|
|
870
|
+
definition: def,
|
|
871
|
+
tokenLookup: (ref) => this.derived.tokens.get(ref),
|
|
872
|
+
stylePropertiesLookup: (ns) => this.#stylePropertiesFor(ns)
|
|
873
|
+
}));
|
|
874
|
+
this.#invalidate();
|
|
875
|
+
return this;
|
|
876
|
+
}
|
|
877
|
+
registerStyleProps(props) {
|
|
878
|
+
for (const [name, def] of Object.entries(props)) this.styleProps.set(name, new StyleProp({
|
|
879
|
+
name,
|
|
880
|
+
definition: def,
|
|
881
|
+
tokenLookup: (groupName) => this.#tokensInGroup(groupName),
|
|
882
|
+
prefixGetter: () => this.prefix
|
|
883
|
+
}));
|
|
884
|
+
return this;
|
|
885
|
+
}
|
|
886
|
+
registerComposites(composites) {
|
|
887
|
+
for (const [name, def] of Object.entries(composites)) this.compositeStyles.set(name, new CompositeStyle({
|
|
888
|
+
name,
|
|
889
|
+
definition: def,
|
|
890
|
+
prefixGetter: () => this.prefix
|
|
891
|
+
}));
|
|
892
|
+
return this;
|
|
893
|
+
}
|
|
894
|
+
registerMotion(motion) {
|
|
895
|
+
for (const [name, def] of Object.entries(motion)) this.motion.set(name, def.runtime === "js" ? new JsMotionDef({
|
|
896
|
+
name,
|
|
897
|
+
definition: def
|
|
898
|
+
}) : new CssMotionDef({
|
|
899
|
+
name,
|
|
900
|
+
definition: def
|
|
901
|
+
}));
|
|
902
|
+
return this;
|
|
903
|
+
}
|
|
904
|
+
registerComponents(components) {
|
|
905
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
906
|
+
const childrenOf = /* @__PURE__ */ new Map();
|
|
907
|
+
const flat = new Map(Object.entries(components));
|
|
908
|
+
for (const [parentName, def] of Object.entries(components)) {
|
|
909
|
+
const subs = def.__subcomponents;
|
|
910
|
+
if (!subs) continue;
|
|
911
|
+
const childNames = [];
|
|
912
|
+
for (const [childName, child] of Object.entries(subs)) {
|
|
913
|
+
const existing = parentOf.get(childName);
|
|
914
|
+
if (existing !== void 0) throw new Error(`registerComponents: subcomponent "${childName}" registered under both "${existing}" and "${parentName}"`);
|
|
915
|
+
if (Object.hasOwn(components, childName)) throw new Error(`registerComponents: "${childName}" is registered both as a top-level component and as a subcomponent of "${parentName}" — pick one`);
|
|
916
|
+
flat.set(childName, child);
|
|
917
|
+
parentOf.set(childName, parentName);
|
|
918
|
+
childNames.push(childName);
|
|
919
|
+
}
|
|
920
|
+
childrenOf.set(parentName, childNames);
|
|
921
|
+
}
|
|
922
|
+
for (const [name, def] of flat) Object.defineProperty(def, "__componentName", {
|
|
923
|
+
enumerable: false,
|
|
924
|
+
configurable: true,
|
|
925
|
+
writable: true,
|
|
926
|
+
value: name
|
|
927
|
+
});
|
|
928
|
+
for (const [name, def] of flat) {
|
|
929
|
+
assertNameAvailable(this.components, name, this.namespace);
|
|
930
|
+
assertDefinitionAcceptsPlaceable(name, def);
|
|
931
|
+
this.components.set(name, new Component({
|
|
932
|
+
name,
|
|
933
|
+
definition: def,
|
|
934
|
+
subcomponentOf: parentOf.get(name),
|
|
935
|
+
subcomponents: childrenOf.get(name),
|
|
936
|
+
namespaceGetter: () => this.namespace,
|
|
937
|
+
prefixGetter: () => this.prefix,
|
|
938
|
+
componentResolver: (ref) => this.getComponent(ref),
|
|
939
|
+
resolveStylePropValueToken: (prop, value) => this.#resolveStylePropValueToken(prop, value),
|
|
940
|
+
isStyleProp: (propName) => this.styleProps.has(propName)
|
|
941
|
+
}));
|
|
942
|
+
}
|
|
943
|
+
return this;
|
|
944
|
+
}
|
|
945
|
+
/**
|
|
946
|
+
* Build a single component from its definition with this config's context
|
|
947
|
+
* getters wired — `prefixGetter`, `namespaceGetter`, `componentResolver` —
|
|
948
|
+
* and set it on the registry, replacing any existing entry of the same name.
|
|
949
|
+
*
|
|
950
|
+
* This is the ONE sanctioned way to put a constructed component into the
|
|
951
|
+
* config outside `registerComponents`. Constructing a `Component` by hand and
|
|
952
|
+
* calling `config.components.set(...)` silently drops those getters, so the
|
|
953
|
+
* component's `derived.classNames` fall back to an empty prefix/namespace and
|
|
954
|
+
* its anatomy CSS emits unprefixed (`:where(.button-root)`) — it renders
|
|
955
|
+
* unstyled while the runtime applies the prefixed class. Patch-apply code that
|
|
956
|
+
* rebuilds a component from a mutated definition (e.g.
|
|
957
|
+
* `applyComponentStyleUpdatePatch`) routes through here so the wiring can't be
|
|
958
|
+
* forgotten.
|
|
959
|
+
*/
|
|
960
|
+
upsertComponent(name, definition, meta) {
|
|
961
|
+
this.components.set(name, new Component({
|
|
962
|
+
name,
|
|
963
|
+
definition,
|
|
964
|
+
componentGroup: meta?.componentGroup,
|
|
965
|
+
subcomponentOf: meta?.subcomponentOf,
|
|
966
|
+
subcomponents: meta?.subcomponents,
|
|
967
|
+
namespaceGetter: () => this.namespace,
|
|
968
|
+
prefixGetter: () => this.prefix,
|
|
969
|
+
componentResolver: (ref) => this.getComponent(ref),
|
|
970
|
+
resolveStylePropValueToken: (prop, value) => this.#resolveStylePropValueToken(prop, value),
|
|
971
|
+
isStyleProp: (propName) => this.styleProps.has(propName)
|
|
972
|
+
}));
|
|
973
|
+
return this;
|
|
974
|
+
}
|
|
975
|
+
/**
|
|
976
|
+
* Register one or more labeled bundles of components. Each group's
|
|
977
|
+
* `components` record is flattened into `this.components` (same
|
|
978
|
+
* surface as `registerComponents`), and every member's
|
|
979
|
+
* `Component.derived.componentGroup` carries the group key. The
|
|
980
|
+
* group entry itself lives on `this.componentGroups[key]` with a
|
|
981
|
+
* JSON-safe ref list (`components: readonly string[]`).
|
|
982
|
+
*
|
|
983
|
+
* Subcomponents declared on a grouped parent via
|
|
984
|
+
* `.subcomponents({...})` auto-register alongside their parent;
|
|
985
|
+
* they carry `subcomponentOf` instead of `componentGroup` (a
|
|
986
|
+
* subcomponent belongs to a parent, not a group).
|
|
987
|
+
*
|
|
988
|
+
* Component names are the identity (`<namespace>:<name>`, the spec
|
|
989
|
+
* `type`) and must be unique across the whole config — the same name
|
|
990
|
+
* under two groups, repeated in one group, or already registered by a
|
|
991
|
+
* prior `register*` call throws. Two components that should *display*
|
|
992
|
+
* the same use distinct names + `metadata.label`.
|
|
993
|
+
*/
|
|
994
|
+
registerComponentGroups(groups) {
|
|
995
|
+
const groupOf = /* @__PURE__ */ new Map();
|
|
996
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
997
|
+
const childrenOf = /* @__PURE__ */ new Map();
|
|
998
|
+
const flat = /* @__PURE__ */ new Map();
|
|
999
|
+
const groupRecords = /* @__PURE__ */ new Map();
|
|
1000
|
+
for (const [groupKey, group] of Object.entries(groups)) {
|
|
1001
|
+
const componentNames = [];
|
|
1002
|
+
for (const [name, def] of Object.entries(group.components)) {
|
|
1003
|
+
if (this.components.has(name) || flat.has(name)) throw new Error(`registerComponentGroups: component "${name}" is already registered${groupOf.get(name) ? ` (group "${groupOf.get(name)}")` : ""} — component names must be unique within a registry. Rename one (e.g. "Studio${name}") and give it metadata.label "${name}" for a shared display name.`);
|
|
1004
|
+
flat.set(name, def);
|
|
1005
|
+
groupOf.set(name, groupKey);
|
|
1006
|
+
componentNames.push(name);
|
|
1007
|
+
}
|
|
1008
|
+
groupRecords.set(groupKey, {
|
|
1009
|
+
label: group.label,
|
|
1010
|
+
description: group.description,
|
|
1011
|
+
componentNames
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
for (const group of Object.values(groups)) for (const [parentName, def] of Object.entries(group.components)) {
|
|
1015
|
+
const subs = def.__subcomponents;
|
|
1016
|
+
if (!subs) continue;
|
|
1017
|
+
const childNames = [];
|
|
1018
|
+
for (const [childName, child] of Object.entries(subs)) {
|
|
1019
|
+
const existingParent = parentOf.get(childName);
|
|
1020
|
+
if (existingParent !== void 0) throw new Error(`registerComponentGroups: subcomponent "${childName}" registered under both "${existingParent}" and "${parentName}"`);
|
|
1021
|
+
if (groupOf.has(childName)) throw new Error(`registerComponentGroups: "${childName}" is registered both as a top-level component and as a subcomponent of "${parentName}" — pick one`);
|
|
1022
|
+
flat.set(childName, child);
|
|
1023
|
+
parentOf.set(childName, parentName);
|
|
1024
|
+
childNames.push(childName);
|
|
1025
|
+
}
|
|
1026
|
+
childrenOf.set(parentName, childNames);
|
|
1027
|
+
}
|
|
1028
|
+
for (const [name, def] of flat) Object.defineProperty(def, "__componentName", {
|
|
1029
|
+
enumerable: false,
|
|
1030
|
+
configurable: true,
|
|
1031
|
+
writable: true,
|
|
1032
|
+
value: name
|
|
1033
|
+
});
|
|
1034
|
+
for (const [name, def] of flat) {
|
|
1035
|
+
assertNameAvailable(this.components, name, this.namespace);
|
|
1036
|
+
assertDefinitionAcceptsPlaceable(name, def);
|
|
1037
|
+
this.components.set(name, new Component({
|
|
1038
|
+
name,
|
|
1039
|
+
definition: def,
|
|
1040
|
+
componentGroup: groupOf.get(name),
|
|
1041
|
+
subcomponentOf: parentOf.get(name),
|
|
1042
|
+
subcomponents: childrenOf.get(name),
|
|
1043
|
+
namespaceGetter: () => this.namespace,
|
|
1044
|
+
prefixGetter: () => this.prefix,
|
|
1045
|
+
componentResolver: (ref) => this.getComponent(ref),
|
|
1046
|
+
resolveStylePropValueToken: (prop, value) => this.#resolveStylePropValueToken(prop, value),
|
|
1047
|
+
isStyleProp: (propName) => this.styleProps.has(propName)
|
|
1048
|
+
}));
|
|
1049
|
+
}
|
|
1050
|
+
for (const [groupKey, record] of groupRecords) this.componentGroups.set(groupKey, new ComponentGroup({
|
|
1051
|
+
name: groupKey,
|
|
1052
|
+
label: record.label,
|
|
1053
|
+
description: record.description,
|
|
1054
|
+
components: record.componentNames
|
|
1055
|
+
}));
|
|
1056
|
+
return this;
|
|
1057
|
+
}
|
|
1058
|
+
/**
|
|
1059
|
+
* Register one or more asset groups. The record key IS the slug —
|
|
1060
|
+
* stamped onto the group at registration (late-bound, like
|
|
1061
|
+
* `registerComponentGroups` deriving a group's name from its key and
|
|
1062
|
+
* `Component.registryKey` reading the namespace getter). Each member
|
|
1063
|
+
* then resolves to `${namespace}:asset:${slug}/${assetName}` via
|
|
1064
|
+
* `AssetGroup.assetType()`.
|
|
1065
|
+
*
|
|
1066
|
+
* Trade-off (accepted, same as `registerComponentGroups`): the
|
|
1067
|
+
* `{ icons }` shorthand ties the slug to the variable name — write
|
|
1068
|
+
* the key out explicitly (`{ icons: phosphorIcons }`) whenever it
|
|
1069
|
+
* shouldn't track the variable.
|
|
1070
|
+
*/
|
|
1071
|
+
registerAssetGroups(groups) {
|
|
1072
|
+
for (const [slug, def] of Object.entries(groups)) {
|
|
1073
|
+
if (!isAssetGroupRef(def)) {
|
|
1074
|
+
const looksLikeBuilder = typeof def.config === "function";
|
|
1075
|
+
throw new Error(looksLikeBuilder ? `registerAssetGroups: group "${slug}" is missing its .config({...}) call — defineAssetGroup(members).config({ sizes }) is a complete icon registration.` : `registerAssetGroups: value for "${slug}" is not an asset group — author it with defineAssetGroup(members).config({...}).`);
|
|
1076
|
+
}
|
|
1077
|
+
if (!/^[A-Za-z][A-Za-z0-9]*(?:[-_][A-Za-z0-9]+)*$/.test(slug)) throw new Error(`registerAssetGroups: slug "${slug}" is invalid — slugs become the asset-id group segment (alphanumeric segments separated by single "-" or "_").`);
|
|
1078
|
+
if (this.assetGroups.has(slug)) throw new Error(`registerAssetGroups: asset group "${slug}" is already registered — slugs must be unique within a config.`);
|
|
1079
|
+
const priorSlug = readAssetGroupSlug(def);
|
|
1080
|
+
if (priorSlug !== void 0 && priorSlug !== slug) throw new Error(`registerAssetGroups: this group is already registered as "${priorSlug}" — a group has one identity; re-export it instead of registering it twice.`);
|
|
1081
|
+
def[ASSET_GROUP_SLUG_KEY] = slug;
|
|
1082
|
+
this.assetGroups.set(slug, new AssetGroup({
|
|
1083
|
+
name: slug,
|
|
1084
|
+
label: def.label ?? titleCaseSlug(slug),
|
|
1085
|
+
description: def.description,
|
|
1086
|
+
assetKind: def.assetKind,
|
|
1087
|
+
assetNames: Object.keys(def.members),
|
|
1088
|
+
sizes: def.assetKind === "icon" ? def.sizes : void 0,
|
|
1089
|
+
variants: def.assetKind === "icon" ? def.variants : void 0,
|
|
1090
|
+
component: def.assetKind === "icon" ? def.component : void 0,
|
|
1091
|
+
members: def.members,
|
|
1092
|
+
memberMetadata: def.assetKind === "icon" ? def.memberMetadata : void 0,
|
|
1093
|
+
namespaceGetter: () => this.namespace
|
|
1094
|
+
}));
|
|
1095
|
+
}
|
|
1096
|
+
return this;
|
|
1097
|
+
}
|
|
1098
|
+
registerProviders(providers) {
|
|
1099
|
+
for (const [name, ProviderFC] of Object.entries(providers)) {
|
|
1100
|
+
ProviderFC.displayName = name;
|
|
1101
|
+
const marker = ProviderFC.__udsProvider;
|
|
1102
|
+
marker.name = name;
|
|
1103
|
+
this.providers.set(name, new Provider({
|
|
1104
|
+
name,
|
|
1105
|
+
component: ProviderFC
|
|
1106
|
+
}));
|
|
1107
|
+
}
|
|
1108
|
+
return this;
|
|
1109
|
+
}
|
|
1110
|
+
get derived() {
|
|
1111
|
+
if (!this.#derived) {
|
|
1112
|
+
const tokens = /* @__PURE__ */ new Map();
|
|
1113
|
+
const cssVarRefs = {};
|
|
1114
|
+
for (const [namespace, group] of this.tokenGroups) {
|
|
1115
|
+
const groupRefs = {};
|
|
1116
|
+
for (const [name, token] of group.tokens) {
|
|
1117
|
+
tokens.set(`${namespace}/${name}`, token);
|
|
1118
|
+
groupRefs[name] = token.derived.cssVarRef;
|
|
1119
|
+
}
|
|
1120
|
+
cssVarRefs[namespace] = groupRefs;
|
|
1121
|
+
}
|
|
1122
|
+
const modeOptionsByModifier = /* @__PURE__ */ new Map();
|
|
1123
|
+
for (const modifier of this.modifiers.values()) {
|
|
1124
|
+
const selector = modifier.selector;
|
|
1125
|
+
if (!isModeRef(selector)) continue;
|
|
1126
|
+
const option = this.#resolveModeOption(selector.ref);
|
|
1127
|
+
if (option) modeOptionsByModifier.set(modifier.name, option);
|
|
1128
|
+
}
|
|
1129
|
+
this.#derived = {
|
|
1130
|
+
tokens,
|
|
1131
|
+
cssVarRefs,
|
|
1132
|
+
modeOptionsByModifier
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
return this.#derived;
|
|
1136
|
+
}
|
|
1137
|
+
#invalidate() {
|
|
1138
|
+
this.#derived = void 0;
|
|
1139
|
+
}
|
|
1140
|
+
#stylePropertiesFor(namespace) {
|
|
1141
|
+
const out = [];
|
|
1142
|
+
for (const styleProp of this.styleProps.values()) if (styleProp.consumedTokenGroups().includes(namespace)) out.push(styleProp.name);
|
|
1143
|
+
return out;
|
|
1144
|
+
}
|
|
1145
|
+
/**
|
|
1146
|
+
* Resolve a shorthand style-prop value to the qualified token it names —
|
|
1147
|
+
* `('bg', 'tertiary')` → `'bg/tertiary'` — by checking the style prop's
|
|
1148
|
+
* token groups for a token of that name. Returns `undefined` when the key
|
|
1149
|
+
* isn't a registered style prop, or the value is a keyword / arbitrary
|
|
1150
|
+
* literal rather than a token. Feeds `Component.derived.tokenRefs` so
|
|
1151
|
+
* shorthand token usage is captured structurally, not by string matching.
|
|
1152
|
+
*/
|
|
1153
|
+
#resolveStylePropValueToken(styleProp, value) {
|
|
1154
|
+
const sp = this.styleProps.get(styleProp);
|
|
1155
|
+
if (!sp) return void 0;
|
|
1156
|
+
for (const namespace of sp.consumedTokenGroups()) if (this.tokenGroups.get(namespace)?.tokens.has(value)) return `${namespace}/${value}`;
|
|
1157
|
+
}
|
|
1158
|
+
*#tokensInGroup(namespace) {
|
|
1159
|
+
const group = this.tokenGroups.get(namespace);
|
|
1160
|
+
if (!group) return;
|
|
1161
|
+
for (const token of group.tokens.values()) yield token;
|
|
1162
|
+
}
|
|
1163
|
+
#lookupCompositeSelector(ref) {
|
|
1164
|
+
const [name, variant] = ref.split("/");
|
|
1165
|
+
if (!name || !variant) return void 0;
|
|
1166
|
+
const composite = this.compositeStyles.get(name);
|
|
1167
|
+
if (!composite) return void 0;
|
|
1168
|
+
if (!composite.styles.has(variant)) return void 0;
|
|
1169
|
+
const { markerVarName, markerVarValue } = composite.derived;
|
|
1170
|
+
return `@container style(${markerVarName}: ${markerVarValue(variant)})`;
|
|
1171
|
+
}
|
|
1172
|
+
/**
|
|
1173
|
+
* Resolve a `mode()` ref (`'colorMode/dark'`) to its `ModeOption`. The single
|
|
1174
|
+
* place that knows the ref's `group/option` shape — both the CSS-selector
|
|
1175
|
+
* lookup and the modifier→mode reverse map go through here, so the ref syntax
|
|
1176
|
+
* lives in exactly one spot.
|
|
1177
|
+
*/
|
|
1178
|
+
#resolveModeOption(ref) {
|
|
1179
|
+
const [name, optionName] = ref.split("/");
|
|
1180
|
+
if (!name || !optionName) return void 0;
|
|
1181
|
+
return this.modes.get(name)?.options.get(optionName);
|
|
1182
|
+
}
|
|
1183
|
+
#lookupModeSelector(ref) {
|
|
1184
|
+
return this.#resolveModeOption(ref)?.css;
|
|
1185
|
+
}
|
|
1186
|
+
/**
|
|
1187
|
+
* Validate cross-references. Throws on cycles in token aliases or on
|
|
1188
|
+
* unknown refs in markers (`token()`, `composite()`, `mode()`,
|
|
1189
|
+
* `styleProp()`, `tokenGroup()`).
|
|
1190
|
+
*/
|
|
1191
|
+
validate() {
|
|
1192
|
+
const tokens = this.derived.tokens;
|
|
1193
|
+
for (const [qualified, token] of tokens) visit(qualified, token, tokens, /* @__PURE__ */ new Set());
|
|
1194
|
+
for (const styleProp of this.styleProps.values()) for (const groupName of styleProp.consumedTokenGroups()) if (!this.tokenGroups.has(groupName)) throw new Error(`Style prop '${styleProp.name}' references unknown token group '${groupName}'`);
|
|
1195
|
+
for (const modifier of this.modifiers.values()) {
|
|
1196
|
+
const selector = modifier.selector;
|
|
1197
|
+
if (typeof selector === "object" && selector !== null) {
|
|
1198
|
+
if (selector.__kind === "composite") {
|
|
1199
|
+
if (this.#lookupCompositeSelector(selector.ref) === void 0) throw new Error(`Modifier '${modifier.name}' references unknown composite '${selector.ref}'`);
|
|
1200
|
+
}
|
|
1201
|
+
if (selector.__kind === "mode") {
|
|
1202
|
+
if (this.#lookupModeSelector(selector.ref) === void 0) throw new Error(`Modifier '${modifier.name}' references unknown mode '${selector.ref}'`);
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
/**
|
|
1208
|
+
* Deep-fork for Studio drafts. Re-builds every entity from `toJSON` /
|
|
1209
|
+
* `fromJSON` rather than sharing instances so the clone is fully
|
|
1210
|
+
* isolated.
|
|
1211
|
+
*
|
|
1212
|
+
* `overlay` shallow-merges into the serialized form before re-hydration —
|
|
1213
|
+
* lets callers swap top-level slices (`{ components, tokenGroups }`)
|
|
1214
|
+
* without round-tripping through the chain methods. Each overlay key
|
|
1215
|
+
* fully replaces the existing slice (no per-entry merge); pass the
|
|
1216
|
+
* full record you want for that slice.
|
|
1217
|
+
*/
|
|
1218
|
+
clone(overlay) {
|
|
1219
|
+
const base = this.toJSON();
|
|
1220
|
+
return Config.fromJSON(overlay ? {
|
|
1221
|
+
...base,
|
|
1222
|
+
...overlay
|
|
1223
|
+
} : base);
|
|
1224
|
+
}
|
|
1225
|
+
/**
|
|
1226
|
+
* Serialize to the wire format. Derived data is never included.
|
|
1227
|
+
* `meta.builtAt` lands in the JSON when the caller passes it (CLI
|
|
1228
|
+
* stamps it at write time so re-serializing in tests stays stable).
|
|
1229
|
+
* `meta.projectRoot` relativizes per-component `sourceFilePath`
|
|
1230
|
+
* values at the wire boundary — keeps `config.json` portable across
|
|
1231
|
+
* machines. Omitting it leaves paths absolute.
|
|
1232
|
+
*/
|
|
1233
|
+
toJSON(meta) {
|
|
1234
|
+
const out = {
|
|
1235
|
+
schemaVersion: Config.SCHEMA_VERSION,
|
|
1236
|
+
prefix: this.prefix,
|
|
1237
|
+
preflight: this.preflight
|
|
1238
|
+
};
|
|
1239
|
+
if (meta?.builtAt !== void 0) out.builtAt = meta.builtAt;
|
|
1240
|
+
if (this.namespace !== void 0) out.namespace = this.namespace;
|
|
1241
|
+
if (this.designPrinciples.length > 0) out.designPrinciples = this.designPrinciples;
|
|
1242
|
+
if (Object.keys(this.globalStyles).length > 0) out.globalStyles = this.globalStyles;
|
|
1243
|
+
if (this.rawCss.length > 0) out.rawCss = this.rawCss;
|
|
1244
|
+
if (this.modes.size > 0) out.modes = mapToRecord(this.modes, (mode) => mode.toJSON());
|
|
1245
|
+
if (this.modifiers.size > 0) out.modifiers = mapToRecord(this.modifiers, stripName);
|
|
1246
|
+
if (this.tokenGroups.size > 0) out.tokenGroups = mapToRecord(this.tokenGroups, (group) => group.toJSON());
|
|
1247
|
+
if (this.styleProps.size > 0) out.styleProps = mapToRecord(this.styleProps, stripName);
|
|
1248
|
+
if (this.compositeStyles.size > 0) out.compositeStyles = mapToRecord(this.compositeStyles, stripName);
|
|
1249
|
+
if (this.motion.size > 0) {
|
|
1250
|
+
const motionRecord = {};
|
|
1251
|
+
for (const [name, motion] of this.motion) {
|
|
1252
|
+
const { name: _omit, ...rest } = motion.toJSON();
|
|
1253
|
+
motionRecord[name] = rest;
|
|
1254
|
+
}
|
|
1255
|
+
out.motion = motionRecord;
|
|
1256
|
+
}
|
|
1257
|
+
if (this.components.size > 0) out.components = mapToRecord(this.components, (component) => {
|
|
1258
|
+
const { name: _name, ...rest } = component.toJSON({ projectRoot: meta?.projectRoot });
|
|
1259
|
+
return rest;
|
|
1260
|
+
});
|
|
1261
|
+
if (this.componentGroups.size > 0) out.componentGroups = mapToRecord(this.componentGroups, (group) => {
|
|
1262
|
+
const { name: _omit, ...rest } = group.toJSON();
|
|
1263
|
+
return rest;
|
|
1264
|
+
});
|
|
1265
|
+
if (this.assetGroups.size > 0) out.assetGroups = mapToRecord(this.assetGroups, (group) => {
|
|
1266
|
+
const { name: _omit, ...rest } = group.toJSON();
|
|
1267
|
+
return rest;
|
|
1268
|
+
});
|
|
1269
|
+
if (this.providers.size > 0) {
|
|
1270
|
+
const providers = {};
|
|
1271
|
+
for (const name of this.providers.keys()) providers[name] = {};
|
|
1272
|
+
out.providers = providers;
|
|
1273
|
+
}
|
|
1274
|
+
return out;
|
|
1275
|
+
}
|
|
1276
|
+
/**
|
|
1277
|
+
* Hydrate from the wire format. Throws when `schemaVersion` doesn't
|
|
1278
|
+
* match — the CLI's job is to translate the error into "your manifest
|
|
1279
|
+
* is from an older build; run `uds build`."
|
|
1280
|
+
*/
|
|
1281
|
+
static fromJSON(json) {
|
|
1282
|
+
if (json.schemaVersion !== Config.SCHEMA_VERSION) throw new Error(`Config schema version mismatch: file is v${json.schemaVersion}, runtime expects v${Config.SCHEMA_VERSION}. Re-run \`uds build\`.`);
|
|
1283
|
+
const config = new Config();
|
|
1284
|
+
config.prefix = json.prefix;
|
|
1285
|
+
config.preflight = json.preflight;
|
|
1286
|
+
if (json.namespace !== void 0) config.namespace = json.namespace;
|
|
1287
|
+
if (json.designPrinciples) config.designPrinciples = [...json.designPrinciples];
|
|
1288
|
+
if (json.globalStyles) config.globalStyles = json.globalStyles;
|
|
1289
|
+
if (json.rawCss) config.rawCss = [...json.rawCss];
|
|
1290
|
+
if (json.modes) config.registerModes(json.modes);
|
|
1291
|
+
if (json.tokenGroups) config.registerTokenGroups(json.tokenGroups);
|
|
1292
|
+
if (json.styleProps) config.registerStyleProps(json.styleProps);
|
|
1293
|
+
if (json.modifiers) config.registerModifiers(json.modifiers);
|
|
1294
|
+
if (json.compositeStyles) config.registerComposites(json.compositeStyles);
|
|
1295
|
+
if (json.motion) config.registerMotion(json.motion);
|
|
1296
|
+
const componentsByName = json.components ?? {};
|
|
1297
|
+
for (const def of Object.values(componentsByName)) if (def.sourceFilePath) attachSourcePath(def, def.sourceFilePath);
|
|
1298
|
+
const isSubcomponent = /* @__PURE__ */ new Set();
|
|
1299
|
+
for (const parentDef of Object.values(componentsByName)) {
|
|
1300
|
+
const subs = parentDef.subcomponents;
|
|
1301
|
+
if (!subs || subs.length === 0) continue;
|
|
1302
|
+
const childMap = {};
|
|
1303
|
+
for (const childName of subs) {
|
|
1304
|
+
const child = componentsByName[childName];
|
|
1305
|
+
if (!child) continue;
|
|
1306
|
+
childMap[childName] = child;
|
|
1307
|
+
isSubcomponent.add(childName);
|
|
1308
|
+
}
|
|
1309
|
+
if (Object.keys(childMap).length === 0) continue;
|
|
1310
|
+
Object.defineProperty(parentDef, "__subcomponents", {
|
|
1311
|
+
enumerable: false,
|
|
1312
|
+
configurable: true,
|
|
1313
|
+
writable: true,
|
|
1314
|
+
value: childMap
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1317
|
+
const grouped = /* @__PURE__ */ new Set();
|
|
1318
|
+
if (json.componentGroups) {
|
|
1319
|
+
const groupDefs = {};
|
|
1320
|
+
for (const [groupKey, group] of Object.entries(json.componentGroups)) {
|
|
1321
|
+
const components = {};
|
|
1322
|
+
for (const name of group.components) {
|
|
1323
|
+
if (isSubcomponent.has(name)) continue;
|
|
1324
|
+
const def = componentsByName[name];
|
|
1325
|
+
if (def === void 0) throw new Error(`Config.fromJSON: componentGroup "${groupKey}" references unknown component "${name}"`);
|
|
1326
|
+
components[name] = def;
|
|
1327
|
+
grouped.add(name);
|
|
1328
|
+
}
|
|
1329
|
+
groupDefs[groupKey] = {
|
|
1330
|
+
label: group.label,
|
|
1331
|
+
...group.description !== void 0 ? { description: group.description } : {},
|
|
1332
|
+
components
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
config.registerComponentGroups(groupDefs);
|
|
1336
|
+
}
|
|
1337
|
+
if (json.components) {
|
|
1338
|
+
const ungrouped = {};
|
|
1339
|
+
for (const [name, def] of Object.entries(componentsByName)) {
|
|
1340
|
+
if (grouped.has(name) || isSubcomponent.has(name)) continue;
|
|
1341
|
+
ungrouped[name] = def;
|
|
1342
|
+
}
|
|
1343
|
+
if (Object.keys(ungrouped).length > 0) config.registerComponents(ungrouped);
|
|
1344
|
+
}
|
|
1345
|
+
if (json.assetGroups) for (const [slug, group] of Object.entries(json.assetGroups)) config.assetGroups.set(slug, AssetGroup.fromJSON(slug, group, () => config.namespace));
|
|
1346
|
+
return config;
|
|
1347
|
+
}
|
|
1348
|
+
};
|
|
1349
|
+
/**
|
|
1350
|
+
* Structural validation for a registry namespace. Guards only the
|
|
1351
|
+
* invariants the namespacing scheme depends on — non-empty, no `:`
|
|
1352
|
+
* (the `<namespace>:<Component>` separator), no whitespace. Stricter
|
|
1353
|
+
* format rules and uniqueness / ownership are enforced at push time
|
|
1354
|
+
* against the registered systems. Returns the value unchanged on
|
|
1355
|
+
* success; throws otherwise.
|
|
1356
|
+
*/
|
|
1357
|
+
/**
|
|
1358
|
+
* Guard against registering two components under the same name. The name
|
|
1359
|
+
* is the component's identity (`<namespace>:<name>`, the spec `type`), so
|
|
1360
|
+
* a collision is unresolvable — a spec referencing it couldn't tell the
|
|
1361
|
+
* two apart. Thrown across every registration path (flat + grouped +
|
|
1362
|
+
* cross-call) so author-time mistakes fail loudly instead of silently
|
|
1363
|
+
* shadowing a component. Two components that should *display* the same
|
|
1364
|
+
* use distinct names + `metadata.label`.
|
|
1365
|
+
*/
|
|
1366
|
+
/** A non-null object — a nested style bag (per-slot styles or a `_<modifier>`
|
|
1367
|
+
* sub-object) to descend into when walking component base styles. */
|
|
1368
|
+
function isStyleRecord(value) {
|
|
1369
|
+
return typeof value === "object" && value !== null;
|
|
1370
|
+
}
|
|
1371
|
+
function assertNameAvailable(components, name, namespace) {
|
|
1372
|
+
if (!components.has(name)) return;
|
|
1373
|
+
const qualified = namespace ? `${namespace}:${name}` : name;
|
|
1374
|
+
throw new Error(`Config: component "${name}" is already registered (identity "${qualified}") — component names must be unique within a registry. Rename one (e.g. "Studio${name}") and give it metadata.label "${name}" for a shared display name.`);
|
|
1375
|
+
}
|
|
1376
|
+
/**
|
|
1377
|
+
* Split a spec element `type` / registry key into its namespace + bare name.
|
|
1378
|
+
* `'uds:Text'` → `{ namespace: 'uds', name: 'Text' }`; a bare `'Text'` →
|
|
1379
|
+
* `{ name: 'Text' }`. The namespace is everything before the first `:`
|
|
1380
|
+
* (namespaces are validated to contain no `:`, see {@link validateNamespace}),
|
|
1381
|
+
* so a scoped namespace like `'@acme/system:Button'` still splits on the right
|
|
1382
|
+
* colon. The inverse of {@link Component.registryKey}.
|
|
1383
|
+
*/
|
|
1384
|
+
function parseRegistryKey(type) {
|
|
1385
|
+
const sep = type.indexOf(":");
|
|
1386
|
+
if (sep < 0) return { name: type };
|
|
1387
|
+
return {
|
|
1388
|
+
namespace: type.slice(0, sep),
|
|
1389
|
+
name: type.slice(sep + 1)
|
|
1390
|
+
};
|
|
1391
|
+
}
|
|
1392
|
+
function validateNamespace(value) {
|
|
1393
|
+
if (value.length === 0) throw new Error("Config.configure: namespace must be non-empty.");
|
|
1394
|
+
if (value.includes(":")) throw new Error(`Config.configure: namespace "${value}" must not contain ":" — it's the reserved \`<namespace>:<Component>\` separator.`);
|
|
1395
|
+
if (/\s/.test(value)) throw new Error(`Config.configure: namespace "${value}" must not contain whitespace.`);
|
|
1396
|
+
if (value === "foreign") throw new Error(`Config.configure: namespace "${FOREIGN_NAMESPACE}" is reserved for third-party leaf components (the \`${FOREIGN_NAMESPACE}:<Component>\` sentinel).`);
|
|
1397
|
+
return value;
|
|
1398
|
+
}
|
|
1399
|
+
function visit(qualified, token, tokens, seen) {
|
|
1400
|
+
if (seen.has(qualified)) throw new Error(`Token cycle detected at '${qualified}'`);
|
|
1401
|
+
const value = token.value;
|
|
1402
|
+
if (typeof value === "object" && value !== null && "ref" in value && typeof value.ref === "string") {
|
|
1403
|
+
const next = tokens.get(value.ref);
|
|
1404
|
+
if (!next) throw new Error(`Token '${qualified}' references unknown token '${value.ref}'`);
|
|
1405
|
+
visit(value.ref, next, tokens, new Set(seen).add(qualified));
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
function stripName(entity) {
|
|
1409
|
+
const { name: _name, namespace: _namespace, ...rest } = entity.toJSON();
|
|
1410
|
+
return rest;
|
|
1411
|
+
}
|
|
1412
|
+
/**
|
|
1413
|
+
* Default asset-group label from its slug — `'icons'` → `'Icons'`,
|
|
1414
|
+
* `'brand-icons'` → `'Brand Icons'`. `label` is optional and defaults
|
|
1415
|
+
* to the title-cased registration key.
|
|
1416
|
+
*/
|
|
1417
|
+
function titleCaseSlug(slug) {
|
|
1418
|
+
return slug.split(/[-_]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ");
|
|
1419
|
+
}
|
|
1420
|
+
function mapToRecord(map, serializer) {
|
|
1421
|
+
const out = {};
|
|
1422
|
+
for (const [key, value] of map) out[key] = serializer(value);
|
|
1423
|
+
return out;
|
|
1424
|
+
}
|
|
1425
|
+
//#endregion
|
|
1426
|
+
export { Config, parseRegistryKey };
|