@pilotiq/pilotiq 0.23.1 → 0.24.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +91 -0
- package/boost/guidelines.md +566 -0
- package/boost/skills/pilotiq-fields/SKILL.md +47 -0
- package/boost/skills/pilotiq-fields/rules/field-catalog.md +288 -0
- package/boost/skills/pilotiq-fields/rules/reactive-fields.md +199 -0
- package/boost/skills/pilotiq-fields/rules/validation.md +198 -0
- package/boost/skills/pilotiq-relations/SKILL.md +47 -0
- package/boost/skills/pilotiq-relations/rules/relation-managers.md +256 -0
- package/boost/skills/pilotiq-relations/rules/repeater-relationship.md +177 -0
- package/boost/skills/pilotiq-resource/SKILL.md +61 -0
- package/boost/skills/pilotiq-resource/rules/authorization.md +242 -0
- package/boost/skills/pilotiq-resource/rules/defining-resources.md +228 -0
- package/boost/skills/pilotiq-resource/rules/page-overrides.md +296 -0
- package/dist/actions/exportFactory.d.ts +10 -0
- package/dist/actions/exportFactory.d.ts.map +1 -1
- package/dist/actions/exportFactory.js +10 -0
- package/dist/actions/exportFactory.js.map +1 -1
- package/dist/react/CollabRoomContext.d.ts +5 -5
- package/dist/react/index.d.ts +0 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +0 -1
- package/dist/react/index.js.map +1 -1
- package/dist/routes/helpers.d.ts.map +1 -1
- package/dist/routes/helpers.js +6 -2
- package/dist/routes/helpers.js.map +1 -1
- package/dist/routes/relations.d.ts.map +1 -1
- package/dist/routes/relations.js +12 -0
- package/dist/routes/relations.js.map +1 -1
- package/package.json +6 -1
- package/.turbo/turbo-build.log +0 -8
- package/CLAUDE.md +0 -265
- package/dist/react/useCollabSeed.d.ts +0 -23
- package/dist/react/useCollabSeed.d.ts.map +0 -1
- package/dist/react/useCollabSeed.js +0 -82
- package/dist/react/useCollabSeed.js.map +0 -1
- package/src/Cluster.test.ts +0 -283
- package/src/Cluster.ts +0 -83
- package/src/Column.test.ts +0 -199
- package/src/Column.ts +0 -710
- package/src/Global.test.ts +0 -367
- package/src/Global.ts +0 -169
- package/src/Page.test.ts +0 -114
- package/src/Page.ts +0 -208
- package/src/Pilotiq.perf.test.ts +0 -252
- package/src/Pilotiq.test.ts +0 -129
- package/src/Pilotiq.ts +0 -1158
- package/src/PilotiqRegistry.ts +0 -36
- package/src/PilotiqServiceProvider.ts +0 -121
- package/src/RelationManager.test.ts +0 -400
- package/src/RelationManager.ts +0 -527
- package/src/RenderHook.test.ts +0 -252
- package/src/RenderHook.ts +0 -242
- package/src/Resource.test.ts +0 -284
- package/src/Resource.ts +0 -526
- package/src/RightPanel.test.ts +0 -202
- package/src/RightPanel.ts +0 -132
- package/src/Tab.test.ts +0 -91
- package/src/Tab.ts +0 -156
- package/src/UserMenuItem.ts +0 -145
- package/src/actions/Action.test.ts +0 -2526
- package/src/actions/Action.ts +0 -1515
- package/src/actions/ActionGroup.test.ts +0 -112
- package/src/actions/ActionGroup.ts +0 -173
- package/src/actions/attachFactory.ts +0 -172
- package/src/actions/bulkFactories.ts +0 -168
- package/src/actions/crudFactories.ts +0 -220
- package/src/actions/exportFactory.ts +0 -215
- package/src/actions/factoryHelpers.ts +0 -177
- package/src/actions/importFactory.ts +0 -243
- package/src/actions/index.ts +0 -17
- package/src/actions/m2mFactories.ts +0 -193
- package/src/actions/relationFactories.ts +0 -372
- package/src/applyPageHooks.test.ts +0 -463
- package/src/applyPageHooks.ts +0 -330
- package/src/authorization.test.ts +0 -483
- package/src/breadcrumbs.test.ts +0 -238
- package/src/cells/coerce.test.ts +0 -85
- package/src/cells/coerce.ts +0 -84
- package/src/clusterPaths.ts +0 -35
- package/src/columns/BadgeColumn.test.ts +0 -54
- package/src/columns/BadgeColumn.ts +0 -32
- package/src/columns/BooleanColumn.test.ts +0 -41
- package/src/columns/BooleanColumn.ts +0 -18
- package/src/columns/ColorColumn.test.ts +0 -37
- package/src/columns/ColorColumn.ts +0 -38
- package/src/columns/IconColumn.test.ts +0 -54
- package/src/columns/IconColumn.ts +0 -37
- package/src/columns/ImageColumn.test.ts +0 -41
- package/src/columns/ImageColumn.ts +0 -28
- package/src/columns/SelectColumn.ts +0 -98
- package/src/columns/TextColumn.test.ts +0 -190
- package/src/columns/TextColumn.ts +0 -20
- package/src/columns/TextInputColumn.ts +0 -68
- package/src/columns/ToggleColumn.ts +0 -46
- package/src/columns/editableColumns.test.ts +0 -238
- package/src/columns/index.ts +0 -9
- package/src/defaultGlobalPages.ts +0 -95
- package/src/defaultPages.test.ts +0 -634
- package/src/defaultPages.ts +0 -617
- package/src/defaultViewPage.test.ts +0 -147
- package/src/elements/Form.test.ts +0 -223
- package/src/elements/Form.ts +0 -416
- package/src/elements/ListTabs.ts +0 -28
- package/src/elements/Table.test.ts +0 -422
- package/src/elements/Table.ts +0 -850
- package/src/elements/TableGroup.test.ts +0 -260
- package/src/elements/TableGroup.ts +0 -334
- package/src/elements/dispatchAction.test.ts +0 -463
- package/src/elements/dispatchAction.ts +0 -355
- package/src/elements/dispatchForm.test.ts +0 -477
- package/src/elements/dispatchForm.ts +0 -1993
- package/src/elements/dispatchTable.test.ts +0 -1514
- package/src/elements/dispatchTable.ts +0 -745
- package/src/elements/index.ts +0 -21
- package/src/entries/BadgeEntry.ts +0 -39
- package/src/entries/CodeEntry.test.ts +0 -40
- package/src/entries/CodeEntry.ts +0 -52
- package/src/entries/ColorEntry.ts +0 -63
- package/src/entries/ComponentEntry.test.ts +0 -173
- package/src/entries/ComponentEntry.ts +0 -95
- package/src/entries/Entry.ts +0 -304
- package/src/entries/IconEntry.ts +0 -49
- package/src/entries/ImageEntry.ts +0 -61
- package/src/entries/KeyValueEntry.ts +0 -47
- package/src/entries/RepeatableEntry.test.ts +0 -239
- package/src/entries/RepeatableEntry.ts +0 -173
- package/src/entries/TextEntry.test.ts +0 -394
- package/src/entries/TextEntry.ts +0 -60
- package/src/entries/index.ts +0 -12
- package/src/entries/leaves.test.ts +0 -306
- package/src/entries/registry.ts +0 -54
- package/src/fields/BuilderField.test.ts +0 -1188
- package/src/fields/BuilderField.ts +0 -605
- package/src/fields/BuilderRelationship.test.ts +0 -811
- package/src/fields/CheckboxField.test.ts +0 -44
- package/src/fields/CheckboxField.ts +0 -27
- package/src/fields/CheckboxListField.test.ts +0 -99
- package/src/fields/CheckboxListField.ts +0 -66
- package/src/fields/ColorPickerField.test.ts +0 -33
- package/src/fields/ColorPickerField.ts +0 -25
- package/src/fields/DateField.ts +0 -54
- package/src/fields/DateTimeField.test.ts +0 -55
- package/src/fields/EmailField.ts +0 -16
- package/src/fields/Field.test.ts +0 -654
- package/src/fields/Field.ts +0 -817
- package/src/fields/FileUploadField.test.ts +0 -143
- package/src/fields/FileUploadField.ts +0 -159
- package/src/fields/HiddenField.test.ts +0 -27
- package/src/fields/HiddenField.ts +0 -28
- package/src/fields/KeyValueField.test.ts +0 -105
- package/src/fields/KeyValueField.ts +0 -55
- package/src/fields/MarkdownField.test.ts +0 -167
- package/src/fields/MarkdownField.ts +0 -162
- package/src/fields/NumberField.ts +0 -33
- package/src/fields/RadioField.test.ts +0 -94
- package/src/fields/RadioField.ts +0 -67
- package/src/fields/RepeaterField.test.ts +0 -1806
- package/src/fields/RepeaterField.ts +0 -939
- package/src/fields/RepeaterRelationship.test.ts +0 -1923
- package/src/fields/RepeaterSimple.test.ts +0 -248
- package/src/fields/RowButton.test.ts +0 -219
- package/src/fields/RowButton.ts +0 -135
- package/src/fields/SelectField.test.ts +0 -192
- package/src/fields/SelectField.ts +0 -235
- package/src/fields/SliderField.test.ts +0 -50
- package/src/fields/SliderField.ts +0 -53
- package/src/fields/SlugField.ts +0 -24
- package/src/fields/TagsInputField.test.ts +0 -154
- package/src/fields/TagsInputField.ts +0 -133
- package/src/fields/TextField.test.ts +0 -213
- package/src/fields/TextField.ts +0 -177
- package/src/fields/TextareaField.test.ts +0 -58
- package/src/fields/TextareaField.ts +0 -59
- package/src/fields/ToggleButtonsField.test.ts +0 -106
- package/src/fields/ToggleButtonsField.ts +0 -59
- package/src/fields/ToggleField.ts +0 -16
- package/src/fields/disableOptionsWhenSelectedInSiblingRepeaterItems.test.ts +0 -319
- package/src/fields/optionsResolver.ts +0 -95
- package/src/fields/resolveField.ts +0 -28
- package/src/filters/BooleanFilter.ts +0 -35
- package/src/filters/DateRangeFilter.test.ts +0 -194
- package/src/filters/DateRangeFilter.ts +0 -148
- package/src/filters/Filter.test.ts +0 -268
- package/src/filters/Filter.ts +0 -184
- package/src/filters/FormFilter.test.ts +0 -238
- package/src/filters/FormFilter.ts +0 -215
- package/src/filters/MultiSelectFilter.test.ts +0 -119
- package/src/filters/MultiSelectFilter.ts +0 -78
- package/src/filters/QueryBuilderFilter.test.ts +0 -662
- package/src/filters/QueryBuilderFilter.ts +0 -398
- package/src/filters/SelectFilter.ts +0 -46
- package/src/filters/TernaryFilter.test.ts +0 -160
- package/src/filters/TernaryFilter.ts +0 -72
- package/src/filters/TrashedFilter.test.ts +0 -149
- package/src/filters/TrashedFilter.ts +0 -55
- package/src/filters/queryBuilder/BooleanConstraint.ts +0 -31
- package/src/filters/queryBuilder/Constraint.ts +0 -115
- package/src/filters/queryBuilder/DateConstraint.ts +0 -69
- package/src/filters/queryBuilder/NumberConstraint.ts +0 -66
- package/src/filters/queryBuilder/SelectConstraint.ts +0 -72
- package/src/filters/queryBuilder/TextConstraint.ts +0 -64
- package/src/filters/queryBuilder/index.ts +0 -12
- package/src/icons/index.ts +0 -2
- package/src/icons/lucide.ts +0 -204
- package/src/icons/registry.test.ts +0 -56
- package/src/icons/registry.ts +0 -41
- package/src/icons/types.ts +0 -47
- package/src/index.ts +0 -525
- package/src/io/csv.test.ts +0 -142
- package/src/io/csv.ts +0 -170
- package/src/nestedRelationManagerData.test.ts +0 -547
- package/src/notifications/Notification.test.ts +0 -210
- package/src/notifications/Notification.ts +0 -354
- package/src/notifications/broadcast.test.ts +0 -110
- package/src/notifications/broadcast.ts +0 -95
- package/src/notifications/database.test.ts +0 -383
- package/src/notifications/database.ts +0 -398
- package/src/notifications/databaseNotifications.test.ts +0 -187
- package/src/notifications/dispatchNotificationAction.test.ts +0 -341
- package/src/notifications/dispatchNotificationAction.ts +0 -142
- package/src/notifications/flash.test.ts +0 -89
- package/src/notifications/flash.ts +0 -71
- package/src/notifications/index.ts +0 -45
- package/src/notifications/registerBroadcastAuth.test.ts +0 -134
- package/src/notifications/registerBroadcastAuth.ts +0 -100
- package/src/notifications/resolveSavedNotification.test.ts +0 -82
- package/src/notifications/resolveSavedNotification.ts +0 -59
- package/src/notifications/types.ts +0 -93
- package/src/orm/m2mAccessor.ts +0 -66
- package/src/orm/modelDefaults.test.ts +0 -633
- package/src/orm/modelDefaults.ts +0 -666
- package/src/pageData/breadcrumbs.ts +0 -288
- package/src/pageData/forms.ts +0 -578
- package/src/pageData/helpers.ts +0 -857
- package/src/pageData/misc.ts +0 -347
- package/src/pageData/navigation.ts +0 -842
- package/src/pageData/relationPages.ts +0 -1248
- package/src/pageData/relationTabs.ts +0 -286
- package/src/pageData/resourcePages.ts +0 -609
- package/src/pageData.test.ts +0 -1545
- package/src/pageData.ts +0 -341
- package/src/plugins/index.ts +0 -8
- package/src/plugins/themeEditor.test.ts +0 -36
- package/src/plugins/themeEditor.ts +0 -45
- package/src/react/AppShell.tsx +0 -251
- package/src/react/CollabExtensionFactoryRegistry.ts +0 -55
- package/src/react/CollabRoomContext.ts +0 -98
- package/src/react/CollabTextRendererRegistry.ts +0 -102
- package/src/react/CommandPalette.tsx +0 -375
- package/src/react/CurrentUserContext.tsx +0 -50
- package/src/react/CustomPageWrapperGate.tsx +0 -69
- package/src/react/CustomPageWrapperRegistry.ts +0 -45
- package/src/react/FieldFocusReporterRegistry.ts +0 -37
- package/src/react/FieldLabelSlotRegistry.ts +0 -30
- package/src/react/FieldPresenceRegistry.ts +0 -46
- package/src/react/FormCollabBindingRegistry.ts +0 -242
- package/src/react/FormStateContext.tsx +0 -591
- package/src/react/HeadHooks.tsx +0 -126
- package/src/react/MarkdownEditorRegistry.test.ts +0 -38
- package/src/react/MarkdownEditorRegistry.ts +0 -107
- package/src/react/NotificationActionStrip.tsx +0 -263
- package/src/react/NotificationBell.tsx +0 -426
- package/src/react/PendingSuggestionApplierRegistry.test.ts +0 -97
- package/src/react/PendingSuggestionApplierRegistry.ts +0 -98
- package/src/react/PendingSuggestionOverlayRegistry.ts +0 -54
- package/src/react/PendingSuggestionsContext.tsx +0 -172
- package/src/react/RecordWrapperGate.tsx +0 -58
- package/src/react/RecordWrapperRegistry.ts +0 -39
- package/src/react/RenderHookSlot.tsx +0 -32
- package/src/react/RightSidebar.tsx +0 -257
- package/src/react/RightSidebarContext.tsx +0 -234
- package/src/react/RightSidebarTrigger.tsx +0 -53
- package/src/react/RowCoordsContext.tsx +0 -23
- package/src/react/SchemaRenderer.tsx +0 -549
- package/src/react/SearchTrigger.tsx +0 -46
- package/src/react/ThemeProvider.tsx +0 -93
- package/src/react/ThemeSettingsPage.tsx +0 -579
- package/src/react/ThemeToggle.tsx +0 -20
- package/src/react/Toaster.tsx +0 -158
- package/src/react/UserMenu.tsx +0 -196
- package/src/react/WidgetDataContext.tsx +0 -157
- package/src/react/cells/EditableCell.tsx +0 -389
- package/src/react/component-slots.test.ts +0 -103
- package/src/react/component-slots.ts +0 -116
- package/src/react/fieldJsHandler.test.ts +0 -166
- package/src/react/fieldJsHandler.ts +0 -79
- package/src/react/fields/BuilderInput.tsx +0 -1078
- package/src/react/fields/CheckboxInput.tsx +0 -39
- package/src/react/fields/CheckboxListInput.tsx +0 -102
- package/src/react/fields/ColorInput.tsx +0 -71
- package/src/react/fields/DateFieldInput.tsx +0 -70
- package/src/react/fields/DateTimeInput.tsx +0 -62
- package/src/react/fields/FieldShell.tsx +0 -348
- package/src/react/fields/FileUploadInput.tsx +0 -639
- package/src/react/fields/HiddenInput.tsx +0 -17
- package/src/react/fields/KeyValueInput.tsx +0 -230
- package/src/react/fields/MarkdownInput.tsx +0 -560
- package/src/react/fields/RadioInput.tsx +0 -81
- package/src/react/fields/RepeaterInput.test.ts +0 -116
- package/src/react/fields/RepeaterInput.tsx +0 -1420
- package/src/react/fields/SelectFieldInput.tsx +0 -280
- package/src/react/fields/SliderInput.tsx +0 -81
- package/src/react/fields/TagsInput.tsx +0 -283
- package/src/react/fields/TextLikeInput.tsx +0 -256
- package/src/react/fields/ToggleButtonsInput.tsx +0 -60
- package/src/react/fields/ToggleFieldInput.tsx +0 -56
- package/src/react/fields/relationshipRenameDispatch.test.ts +0 -106
- package/src/react/fields/relationshipRenameDispatch.ts +0 -97
- package/src/react/fields/repeaterReconcile.test.ts +0 -114
- package/src/react/fields/repeaterReconcile.ts +0 -104
- package/src/react/fields/rowChromeButton.tsx +0 -336
- package/src/react/fields/rowState.ts +0 -106
- package/src/react/fields/syncRowGates.test.ts +0 -202
- package/src/react/fields/syncRowGates.ts +0 -66
- package/src/react/fields/textInputControls.tsx +0 -238
- package/src/react/fields/useRowReorderDnd.ts +0 -78
- package/src/react/formStateHelpers.test.ts +0 -508
- package/src/react/formStateHelpers.ts +0 -381
- package/src/react/hooks/use-mobile.ts +0 -19
- package/src/react/icon-context.tsx +0 -60
- package/src/react/index.ts +0 -195
- package/src/react/layouts/SidebarLayout.tsx +0 -250
- package/src/react/layouts/TopbarLayout.tsx +0 -258
- package/src/react/navigate.tsx +0 -37
- package/src/react/onProviderSynced.test.ts +0 -90
- package/src/react/parseRecordEditUrl.test.ts +0 -122
- package/src/react/parseRecordEditUrl.ts +0 -94
- package/src/react/persistedState.ts +0 -40
- package/src/react/registry.ts +0 -48
- package/src/react/right-panel-registry.tsx +0 -47
- package/src/react/schemaRenderer/AlertRenderer.tsx +0 -112
- package/src/react/schemaRenderer/EntryRenderer.tsx +0 -501
- package/src/react/schemaRenderer/SectionRenderer.tsx +0 -120
- package/src/react/schemaRenderer/SimpleElements.tsx +0 -306
- package/src/react/schemaRenderer/TabsRenderer.tsx +0 -62
- package/src/react/schemaRenderer/WizardRenderer.tsx +0 -338
- package/src/react/schemaRenderer/action/ActionGroupTrigger.tsx +0 -177
- package/src/react/schemaRenderer/action/ActionModalDialog.tsx +0 -273
- package/src/react/schemaRenderer/action/ConfirmActionDialog.tsx +0 -61
- package/src/react/schemaRenderer/action/HandlerActionButton.tsx +0 -43
- package/src/react/schemaRenderer/action/MethodActionButton.tsx +0 -64
- package/src/react/schemaRenderer/action/buttons.tsx +0 -99
- package/src/react/schemaRenderer/action/helpers.ts +0 -140
- package/src/react/schemaRenderer/action/renderAction.tsx +0 -245
- package/src/react/schemaRenderer/columnFormat.ts +0 -65
- package/src/react/schemaRenderer/constants.ts +0 -50
- package/src/react/schemaRenderer/form/FormRenderer.tsx +0 -274
- package/src/react/schemaRenderer/form/renderField.tsx +0 -511
- package/src/react/schemaRenderer/helpers.tsx +0 -81
- package/src/react/schemaRenderer/table/CardsLayoutBody.tsx +0 -308
- package/src/react/schemaRenderer/table/TableRenderer.tsx +0 -123
- package/src/react/schemaRenderer/table/TableRendererBody.tsx +0 -974
- package/src/react/schemaRenderer/table/filters.tsx +0 -1233
- package/src/react/schemaRenderer/table/formatCell.tsx +0 -264
- package/src/react/schemaRenderer/table/links.tsx +0 -112
- package/src/react/schemaRenderer/table/renderRowActions.tsx +0 -52
- package/src/react/schemaRenderer/table/url.tsx +0 -143
- package/src/react/theme-preview/apply.ts +0 -99
- package/src/react/theme-preview/build-html.ts +0 -436
- package/src/react/ui/button.tsx +0 -51
- package/src/react/ui/calendar.tsx +0 -67
- package/src/react/ui/checkbox.tsx +0 -29
- package/src/react/ui/dialog.tsx +0 -108
- package/src/react/ui/dropdown-menu.tsx +0 -97
- package/src/react/ui/input.tsx +0 -20
- package/src/react/ui/label.tsx +0 -21
- package/src/react/ui/popover.tsx +0 -50
- package/src/react/ui/select.tsx +0 -169
- package/src/react/ui/separator.tsx +0 -25
- package/src/react/ui/sheet.tsx +0 -136
- package/src/react/ui/sidebar.tsx +0 -723
- package/src/react/ui/skeleton.tsx +0 -13
- package/src/react/ui/slider.tsx +0 -34
- package/src/react/ui/switch.tsx +0 -28
- package/src/react/ui/table.tsx +0 -105
- package/src/react/ui/tabs.tsx +0 -63
- package/src/react/ui/textarea.tsx +0 -18
- package/src/react/ui/tooltip.tsx +0 -64
- package/src/react/useCollabSeed.ts +0 -86
- package/src/react/useResizableWidth.ts +0 -139
- package/src/react/utils.ts +0 -6
- package/src/react/widgetRegistry.test.ts +0 -43
- package/src/react/widgetRegistry.ts +0 -50
- package/src/react/widgets/StatsOverviewRenderer.tsx +0 -232
- package/src/react/widgets/TableWidgetRenderer.tsx +0 -231
- package/src/react/widgets/ViewRenderer.tsx +0 -71
- package/src/relationManagerData.test.ts +0 -1595
- package/src/richtext/index.ts +0 -8
- package/src/richtext/registry.ts +0 -89
- package/src/routes/globals.ts +0 -148
- package/src/routes/guard.test.ts +0 -325
- package/src/routes/helpers.ts +0 -700
- package/src/routes/pages.ts +0 -175
- package/src/routes/panel.ts +0 -204
- package/src/routes/relations.ts +0 -1227
- package/src/routes/resources.ts +0 -781
- package/src/routes/theme.ts +0 -91
- package/src/routes-nested-relations.test.ts +0 -676
- package/src/routes-relations.test.ts +0 -972
- package/src/routes.test.ts +0 -2027
- package/src/routes.ts +0 -303
- package/src/schema/Alert.test.ts +0 -109
- package/src/schema/Alert.ts +0 -131
- package/src/schema/Block.ts +0 -169
- package/src/schema/Breadcrumbs.ts +0 -40
- package/src/schema/Card.ts +0 -35
- package/src/schema/Divider.ts +0 -20
- package/src/schema/Element.ts +0 -219
- package/src/schema/EmptyState.test.ts +0 -37
- package/src/schema/EmptyState.ts +0 -63
- package/src/schema/Fieldset.ts +0 -43
- package/src/schema/Grid.ts +0 -43
- package/src/schema/Group.ts +0 -30
- package/src/schema/Heading.ts +0 -39
- package/src/schema/Html.ts +0 -67
- package/src/schema/Icon.ts +0 -54
- package/src/schema/Image.ts +0 -57
- package/src/schema/LinkTag.ts +0 -41
- package/src/schema/Markdown.ts +0 -85
- package/src/schema/MetaTag.ts +0 -41
- package/src/schema/RelationTabs.ts +0 -71
- package/src/schema/ScriptTag.ts +0 -55
- package/src/schema/Section.ts +0 -160
- package/src/schema/ServerDataElement.test.ts +0 -140
- package/src/schema/ServerDataElement.ts +0 -156
- package/src/schema/SlotComponent.test.ts +0 -77
- package/src/schema/SlotComponent.ts +0 -71
- package/src/schema/Split.ts +0 -50
- package/src/schema/Stat.test.ts +0 -118
- package/src/schema/Stat.ts +0 -154
- package/src/schema/StatsOverview.test.ts +0 -141
- package/src/schema/StatsOverview.ts +0 -119
- package/src/schema/StyleTag.ts +0 -35
- package/src/schema/TableWidget.test.ts +0 -297
- package/src/schema/TableWidget.ts +0 -289
- package/src/schema/Tabs.ts +0 -79
- package/src/schema/Text.ts +0 -58
- package/src/schema/UnorderedList.ts +0 -49
- package/src/schema/View.test.ts +0 -111
- package/src/schema/View.ts +0 -127
- package/src/schema/Wizard.ts +0 -220
- package/src/schema/containers.test.ts +0 -564
- package/src/schema/headTags.test.ts +0 -134
- package/src/schema/index.ts +0 -40
- package/src/schema/primes.test.ts +0 -269
- package/src/schema/resolveSchema.test.ts +0 -379
- package/src/schema/resolveSchema.ts +0 -917
- package/src/schema/sanitize.ts +0 -58
- package/src/search.test.ts +0 -446
- package/src/search.ts +0 -178
- package/src/sessionFilters.test.ts +0 -375
- package/src/sessionFilters.ts +0 -143
- package/src/slot-components/index.ts +0 -10
- package/src/slot-components/registry.ts +0 -56
- package/src/styles/file-upload.css +0 -13
- package/src/summarizers/Summarizer.test.ts +0 -84
- package/src/summarizers/Summarizer.ts +0 -123
- package/src/summarizers/index.ts +0 -11
- package/src/theme/base-colors.ts +0 -68
- package/src/theme/chart-colors.ts +0 -50
- package/src/theme/colors.ts +0 -447
- package/src/theme/generate-css.test.ts +0 -139
- package/src/theme/generate-css.ts +0 -44
- package/src/theme/generate-scale.test.ts +0 -106
- package/src/theme/generate-scale.ts +0 -97
- package/src/theme/icon-map.ts +0 -42
- package/src/theme/index.ts +0 -34
- package/src/theme/migrate.test.ts +0 -178
- package/src/theme/migrate.ts +0 -81
- package/src/theme/presets.ts +0 -135
- package/src/theme/radius.ts +0 -18
- package/src/theme/resolve.test.ts +0 -238
- package/src/theme/resolve.ts +0 -96
- package/src/theme/spacing.ts +0 -18
- package/src/theme/storage.test.ts +0 -126
- package/src/theme/storage.ts +0 -106
- package/src/theme/theme-colors.ts +0 -88
- package/src/theme/types.ts +0 -125
- package/src/uploads/UploadAdapter.ts +0 -35
- package/src/uploads/index.ts +0 -2
- package/src/uploads/localUpload.test.ts +0 -70
- package/src/uploads/localUpload.ts +0 -84
- package/src/validation/Validator.ts +0 -49
- package/src/validation/index.ts +0 -28
- package/src/validation/rules.ts +0 -78
- package/src/validation/runValidators.ts +0 -435
- package/src/validation/uniqueValidator.test.ts +0 -196
- package/src/validation/uniqueValidator.ts +0 -133
- package/src/validation/validators.test.ts +0 -268
- package/src/vite.test.ts +0 -184
- package/src/vite.ts +0 -787
- package/src/widgets/index.ts +0 -10
- package/src/widgets/registry.ts +0 -45
- package/src/widgets.test.ts +0 -592
- package/tsconfig.build.json +0 -11
- package/tsconfig.json +0 -4
- package/tsconfig.test.json +0 -10
- package/views/react/Dashboard.tsx +0 -27
- package/views/react/Resources/Form.tsx +0 -102
- package/views/react/Resources/Index.tsx +0 -49
package/src/theme/migrate.ts
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import type { ThemeConfig } from './types.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Read-side migration shim — translates legacy theme override shapes from the
|
|
5
|
-
* `panelGlobal` table into the current `ThemeConfig` schema. Pure function;
|
|
6
|
-
* no DB writes. The next time the editor saves, the row lands in the new
|
|
7
|
-
* shape and the shim becomes a no-op for that row.
|
|
8
|
-
*
|
|
9
|
-
* Handles renames (`accentColor` → `themeColor`, `chartPalette` → `chartColor`),
|
|
10
|
-
* dropped values (`preset: 'default'`, `baseColor: 'slate'/'cream'/'default'`,
|
|
11
|
-
* `accentColor: 'terracotta'`, multi-hue chart palettes), and the `'base'`
|
|
12
|
-
* sentinel that replaces several old defaults.
|
|
13
|
-
*/
|
|
14
|
-
export function migrateThemeOverrides(raw: unknown): Partial<ThemeConfig> {
|
|
15
|
-
if (!raw || typeof raw !== 'object') return {}
|
|
16
|
-
const input = raw as Record<string, unknown>
|
|
17
|
-
const out: Partial<ThemeConfig> & Record<string, unknown> = {}
|
|
18
|
-
|
|
19
|
-
// ── preset ─────────────────────────────────────────────
|
|
20
|
-
// 'default' (Pilotiq brand) → 'vega'. Other names ('nova'/'maia'/'lyra')
|
|
21
|
-
// were placeholders that mapped to neutral defaults — they survive the
|
|
22
|
-
// rename intact (still valid in the new union).
|
|
23
|
-
if (typeof input.preset === 'string') {
|
|
24
|
-
out.preset = input.preset === 'default' ? 'vega' : input.preset as NonNullable<ThemeConfig['preset']>
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// ── baseColor ──────────────────────────────────────────
|
|
28
|
-
// 'slate' → 'mist' (closest cool-gray match)
|
|
29
|
-
// 'cream' → drop (Vega preset's bg already supplies it; layering would be redundant)
|
|
30
|
-
// 'default' → drop (was a no-op sentinel; "no override" is just the field absent)
|
|
31
|
-
if (typeof input.baseColor === 'string') {
|
|
32
|
-
if (input.baseColor === 'slate') out.baseColor = 'mist'
|
|
33
|
-
else if (input.baseColor !== 'cream' && input.baseColor !== 'default') {
|
|
34
|
-
out.baseColor = input.baseColor as NonNullable<ThemeConfig['baseColor']>
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// ── accentColor → themeColor ───────────────────────────
|
|
39
|
-
// 'terracotta' → 'base' when preset=vega (it's the Vega preset's own primary),
|
|
40
|
-
// → 'orange' otherwise (closest hue match).
|
|
41
|
-
if (typeof input.accentColor === 'string') {
|
|
42
|
-
if (input.accentColor === 'terracotta') {
|
|
43
|
-
out.themeColor = out.preset === 'vega' ? 'base' : 'orange'
|
|
44
|
-
} else {
|
|
45
|
-
out.themeColor = input.accentColor as NonNullable<ThemeConfig['themeColor']>
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
// If new shape is already present (writes from the new editor), prefer it.
|
|
49
|
-
if (typeof input.themeColor === 'string') {
|
|
50
|
-
out.themeColor = input.themeColor as NonNullable<ThemeConfig['themeColor']>
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// ── chartPalette → chartColor ──────────────────────────
|
|
54
|
-
// Multi-hue palettes collapse to single-hue closest match.
|
|
55
|
-
if (typeof input.chartPalette === 'string') {
|
|
56
|
-
const map: Record<string, NonNullable<ThemeConfig['chartColor']>> = {
|
|
57
|
-
ocean: 'sky',
|
|
58
|
-
sunset: 'orange',
|
|
59
|
-
forest: 'emerald',
|
|
60
|
-
berry: 'fuchsia',
|
|
61
|
-
terracotta: 'base',
|
|
62
|
-
default: 'base',
|
|
63
|
-
}
|
|
64
|
-
out.chartColor = map[input.chartPalette] ?? (input.chartPalette as NonNullable<ThemeConfig['chartColor']>)
|
|
65
|
-
}
|
|
66
|
-
if (typeof input.chartColor === 'string') {
|
|
67
|
-
out.chartColor = input.chartColor as NonNullable<ThemeConfig['chartColor']>
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// ── pass-through fields ────────────────────────────────
|
|
71
|
-
if (typeof input.radius === 'string') out.radius = input.radius as NonNullable<ThemeConfig['radius']>
|
|
72
|
-
if (typeof input.iconLibrary === 'string') out.iconLibrary = input.iconLibrary as NonNullable<ThemeConfig['iconLibrary']>
|
|
73
|
-
if (input.fonts && typeof input.fonts === 'object') {
|
|
74
|
-
out.fonts = input.fonts as NonNullable<ThemeConfig['fonts']>
|
|
75
|
-
}
|
|
76
|
-
if (input.cssVariables && typeof input.cssVariables === 'object') {
|
|
77
|
-
out.cssVariables = input.cssVariables as NonNullable<ThemeConfig['cssVariables']>
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return out
|
|
81
|
-
}
|
package/src/theme/presets.ts
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import { colors } from './colors.js'
|
|
2
|
-
import type { PresetDefinition, StylePreset, ThemeFonts, RadiusPreset, SpacingPreset } from './types.js'
|
|
3
|
-
|
|
4
|
-
// Pure white for surfaces that sit ABOVE the sidebar (`--background`, `--card`,
|
|
5
|
-
// `--popover`). The sidebar tracks `--muted` (one step darker than white) so
|
|
6
|
-
// the sidebar reads as a recessed surface against the bright content area.
|
|
7
|
-
const WHITE = 'oklch(1 0 0)'
|
|
8
|
-
|
|
9
|
-
// ─── Shadcn neutral default ────────────────────────────────
|
|
10
|
-
// Exact mapping of `https://ui.shadcn.com/themes` neutral defaults onto our
|
|
11
|
-
// color tokens. Both Vega (the seeded default) and the six placeholder
|
|
12
|
-
// presets share this baseline; differentiation between styles comes later.
|
|
13
|
-
|
|
14
|
-
// Note: --primary, --ring, --sidebar-primary*, and --chart-1..5 are
|
|
15
|
-
// intentionally omitted here — the theme-color and chart-color resolver
|
|
16
|
-
// layers in `resolve.ts` always apply (defaulting to the `'base'` sentinel),
|
|
17
|
-
// so anything we'd put for those tokens here would be unconditionally
|
|
18
|
-
// overridden. Keeping them out makes the override chain easier to reason
|
|
19
|
-
// about.
|
|
20
|
-
const shadcnNeutral: PresetDefinition = {
|
|
21
|
-
light: {
|
|
22
|
-
'--background': WHITE,
|
|
23
|
-
'--foreground': colors.neutral[950],
|
|
24
|
-
'--card': WHITE,
|
|
25
|
-
'--card-foreground': colors.neutral[950],
|
|
26
|
-
'--popover': WHITE,
|
|
27
|
-
'--popover-foreground': colors.neutral[950],
|
|
28
|
-
'--secondary': colors.neutral[100],
|
|
29
|
-
'--secondary-foreground': colors.neutral[900],
|
|
30
|
-
'--muted': colors.neutral[100],
|
|
31
|
-
'--muted-foreground': colors.neutral[500],
|
|
32
|
-
'--accent': colors.neutral[100],
|
|
33
|
-
'--accent-foreground': colors.neutral[900],
|
|
34
|
-
'--destructive': colors.red[600],
|
|
35
|
-
// shadcn ships destructive-foreground identical to destructive in light
|
|
36
|
-
// mode — preserves the same red token for both fg and bg surfaces.
|
|
37
|
-
'--destructive-foreground': colors.red[600],
|
|
38
|
-
'--border': colors.neutral[200],
|
|
39
|
-
'--input': colors.neutral[200],
|
|
40
|
-
'--sidebar': 'var(--muted)',
|
|
41
|
-
'--sidebar-foreground': colors.neutral[950],
|
|
42
|
-
'--sidebar-accent': colors.neutral[200],
|
|
43
|
-
'--sidebar-accent-foreground': colors.neutral[900],
|
|
44
|
-
'--sidebar-border': colors.neutral[200],
|
|
45
|
-
},
|
|
46
|
-
dark: {
|
|
47
|
-
'--background': colors.neutral[950],
|
|
48
|
-
'--foreground': colors.neutral[50],
|
|
49
|
-
'--card': colors.neutral[950],
|
|
50
|
-
'--card-foreground': colors.neutral[50],
|
|
51
|
-
'--popover': colors.neutral[950],
|
|
52
|
-
'--popover-foreground': colors.neutral[50],
|
|
53
|
-
'--secondary': colors.neutral[800],
|
|
54
|
-
'--secondary-foreground': colors.neutral[50],
|
|
55
|
-
'--muted': colors.neutral[800],
|
|
56
|
-
'--muted-foreground': colors.neutral[400],
|
|
57
|
-
'--accent': colors.neutral[800],
|
|
58
|
-
'--accent-foreground': colors.neutral[50],
|
|
59
|
-
'--destructive': colors.red[900],
|
|
60
|
-
'--destructive-foreground': colors.red[500],
|
|
61
|
-
'--border': colors.neutral[800],
|
|
62
|
-
'--input': colors.neutral[800],
|
|
63
|
-
'--sidebar': 'var(--muted)',
|
|
64
|
-
'--sidebar-foreground': colors.neutral[50],
|
|
65
|
-
'--sidebar-accent': colors.neutral[700],
|
|
66
|
-
'--sidebar-accent-foreground': colors.neutral[50],
|
|
67
|
-
'--sidebar-border': colors.neutral[700],
|
|
68
|
-
},
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// All seven styles share the shadcn baseline for now. Per-style personality
|
|
72
|
-
// (radius, token relationships) lands in a follow-up pass.
|
|
73
|
-
export const presets: Record<StylePreset, PresetDefinition> = {
|
|
74
|
-
vega: shadcnNeutral,
|
|
75
|
-
nova: shadcnNeutral,
|
|
76
|
-
maia: shadcnNeutral,
|
|
77
|
-
lyra: shadcnNeutral,
|
|
78
|
-
mira: shadcnNeutral,
|
|
79
|
-
luma: shadcnNeutral,
|
|
80
|
-
sera: shadcnNeutral,
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Per-style default font pairing. Picking a Style updates the Heading + Font
|
|
85
|
-
* pickers automatically (unless the user has explicitly overridden them via
|
|
86
|
-
* `Pilotiq.theme({ fonts: {...} })` or the editor).
|
|
87
|
-
*
|
|
88
|
-
* Currently confirmed:
|
|
89
|
-
* - vega → Inter
|
|
90
|
-
* - nova → Geist
|
|
91
|
-
*
|
|
92
|
-
* Placeholder for the others (Inter); replace once the design system
|
|
93
|
-
* specifies a font per style.
|
|
94
|
-
*/
|
|
95
|
-
export const PRESET_FONTS: Record<StylePreset, Required<ThemeFonts>> = {
|
|
96
|
-
vega: { heading: 'Inter', body: 'Inter' },
|
|
97
|
-
nova: { heading: 'Geist', body: 'Geist' },
|
|
98
|
-
maia: { heading: 'Figtree', body: 'Figtree' },
|
|
99
|
-
lyra: { heading: 'JetBrains Mono', body: 'JetBrains Mono' },
|
|
100
|
-
mira: { heading: 'Inter', body: 'Inter' },
|
|
101
|
-
luma: { heading: 'Inter', body: 'Inter' },
|
|
102
|
-
sera: { heading: 'Playfair Display', body: 'Noto Sans' },
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Per-style default radius. The picker's "Default" option resolves through
|
|
107
|
-
* this map: with Style = Maia + Radius = Default, the actual rendered radius
|
|
108
|
-
* is `large` (1rem). Picking an explicit radius (e.g. "Small") still
|
|
109
|
-
* overrides this default.
|
|
110
|
-
*/
|
|
111
|
-
export const PRESET_RADIUS: Record<StylePreset, RadiusPreset> = {
|
|
112
|
-
vega: 'medium',
|
|
113
|
-
nova: 'medium',
|
|
114
|
-
maia: 'large',
|
|
115
|
-
lyra: 'none',
|
|
116
|
-
mira: 'medium',
|
|
117
|
-
luma: 'xlarge',
|
|
118
|
-
sera: 'none',
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Per-style default spacing density. The picker's "Default" option resolves
|
|
123
|
-
* through this map. Mirrors shadcn/ui/create's per-preset density behavior:
|
|
124
|
-
* Vega / Nova / Maia / Luma / Sera lean comfortable; Lyra stays at default;
|
|
125
|
-
* Mira goes compact.
|
|
126
|
-
*/
|
|
127
|
-
export const PRESET_SPACING: Record<StylePreset, SpacingPreset> = {
|
|
128
|
-
vega: 'comfortable',
|
|
129
|
-
nova: 'compact',
|
|
130
|
-
maia: 'comfortable',
|
|
131
|
-
lyra: 'default',
|
|
132
|
-
mira: 'compact',
|
|
133
|
-
luma: 'comfortable',
|
|
134
|
-
sera: 'comfortable',
|
|
135
|
-
}
|
package/src/theme/radius.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { RadiusPreset } from './types.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Maps radius preset names to CSS values.
|
|
5
|
-
*
|
|
6
|
-
* `'default'` is a sentinel synonym for `'medium'` (10px) — both render the
|
|
7
|
-
* same radius. The picker shows it as the first option and as the "no
|
|
8
|
-
* explicit choice" label so users see "Default" rather than a specific size
|
|
9
|
-
* when they haven't overridden anything.
|
|
10
|
-
*/
|
|
11
|
-
export const radiusMap: Record<RadiusPreset, string> = {
|
|
12
|
-
default: '0.625rem',
|
|
13
|
-
none: '0px',
|
|
14
|
-
small: '0.25rem',
|
|
15
|
-
medium: '0.625rem',
|
|
16
|
-
large: '1rem',
|
|
17
|
-
xlarge: '1.5rem',
|
|
18
|
-
}
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
import { describe, it } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
|
|
4
|
-
import { resolveTheme } from './resolve.js'
|
|
5
|
-
import { baseColors } from './base-colors.js'
|
|
6
|
-
import { colors } from './colors.js'
|
|
7
|
-
import { PRESET_FONTS, PRESET_RADIUS, PRESET_SPACING } from './presets.js'
|
|
8
|
-
import { radiusMap } from './radius.js'
|
|
9
|
-
import { spacingMap } from './spacing.js'
|
|
10
|
-
|
|
11
|
-
describe('resolveTheme', () => {
|
|
12
|
-
// ─── Preset layering ─────────────────────────────────────
|
|
13
|
-
|
|
14
|
-
describe('preset', () => {
|
|
15
|
-
it('defaults to vega when not specified', () => {
|
|
16
|
-
const empty = resolveTheme({})
|
|
17
|
-
const explicit = resolveTheme({ preset: 'vega' })
|
|
18
|
-
assert.deepEqual(empty.light, explicit.light)
|
|
19
|
-
assert.deepEqual(empty.dark, explicit.dark)
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
it('falls back to vega for unknown preset values (defensive)', () => {
|
|
23
|
-
// Cast to bypass type — defensive code in resolve.ts handles bad input
|
|
24
|
-
// from deserialized DB rows.
|
|
25
|
-
const bogus = resolveTheme({ preset: 'definitely-not-a-preset' as never })
|
|
26
|
-
const vega = resolveTheme({ preset: 'vega' })
|
|
27
|
-
assert.deepEqual(bogus.light, vega.light)
|
|
28
|
-
})
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
// ─── Base color defaulting (the recent regression) ───────
|
|
32
|
-
|
|
33
|
-
describe('base color', () => {
|
|
34
|
-
it('default state matches explicit baseColor: neutral', () => {
|
|
35
|
-
// Regression guard: previously, empty config skipped the baseColor
|
|
36
|
-
// overlay entirely, leaving the preset's hardcoded WHITE surfaces.
|
|
37
|
-
// Picking "Neutral" applied neutral[50] surfaces. The two paths
|
|
38
|
-
// produced different output — this asserts they now agree.
|
|
39
|
-
const fromDefault = resolveTheme({})
|
|
40
|
-
const fromExplicit = resolveTheme({ baseColor: 'neutral' })
|
|
41
|
-
assert.deepEqual(fromDefault.light, fromExplicit.light)
|
|
42
|
-
assert.deepEqual(fromDefault.dark, fromExplicit.dark)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it('applies stone tokens when baseColor: stone', () => {
|
|
46
|
-
const stone = resolveTheme({ baseColor: 'stone' })
|
|
47
|
-
// baseColors.stone uses stone[50] for --background (light mode).
|
|
48
|
-
assert.equal(stone.light['--background'], baseColors.stone.light['--background'])
|
|
49
|
-
// And stone[800] for --muted (dark mode).
|
|
50
|
-
assert.equal(stone.dark['--muted'], baseColors.stone.dark['--muted'])
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
it('does not leak stone tokens when baseColor is neutral', () => {
|
|
54
|
-
const neutral = resolveTheme({ baseColor: 'neutral' })
|
|
55
|
-
assert.notEqual(neutral.light['--background'], baseColors.stone.light['--background'])
|
|
56
|
-
})
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
// ─── Theme color resolution ──────────────────────────────
|
|
60
|
-
|
|
61
|
-
describe('theme color', () => {
|
|
62
|
-
it("'base' sentinel uses the resolved base color scale", () => {
|
|
63
|
-
// With baseColor: 'stone' and themeColor: 'base', --primary should be
|
|
64
|
-
// stone[900] in light (the strongest in-scale contrast). The 'base'
|
|
65
|
-
// path uses isBase=true, which picks scale[900] for light --primary.
|
|
66
|
-
const stoneBase = resolveTheme({ baseColor: 'stone', themeColor: 'base' })
|
|
67
|
-
assert.equal(stoneBase.light['--primary'], colors.stone[900])
|
|
68
|
-
assert.equal(stoneBase.dark['--primary'], colors.stone[50])
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
it("'base' sentinel falls back to neutral when no baseColor set", () => {
|
|
72
|
-
const fallback = resolveTheme({ themeColor: 'base' })
|
|
73
|
-
assert.equal(fallback.light['--primary'], colors.neutral[900])
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
it('hue values override --primary with that hue', () => {
|
|
77
|
-
const blue = resolveTheme({ themeColor: 'blue' })
|
|
78
|
-
// Non-base hue uses scale[600] in BOTH light and dark for brand
|
|
79
|
-
// consistency across modes.
|
|
80
|
-
assert.equal(blue.light['--primary'], colors.blue[600])
|
|
81
|
-
assert.equal(blue.dark['--primary'], colors.blue[600])
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
it('defaults to base sentinel when not specified', () => {
|
|
85
|
-
const noTheme = resolveTheme({ baseColor: 'stone' })
|
|
86
|
-
const explicitBase = resolveTheme({ baseColor: 'stone', themeColor: 'base' })
|
|
87
|
-
assert.equal(noTheme.light['--primary'], explicitBase.light['--primary'])
|
|
88
|
-
})
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
// ─── Chart color resolution ──────────────────────────────
|
|
92
|
-
|
|
93
|
-
describe('chart color', () => {
|
|
94
|
-
it("'base' sentinel uses the resolved base color scale for --chart-1..5", () => {
|
|
95
|
-
const stoneChart = resolveTheme({ baseColor: 'stone', chartColor: 'base' })
|
|
96
|
-
// All five chart vars should be defined and pull from the stone scale.
|
|
97
|
-
for (const i of [1, 2, 3, 4, 5]) {
|
|
98
|
-
const value = stoneChart.light[`--chart-${i}`]
|
|
99
|
-
assert.ok(value, `--chart-${i} should be set`)
|
|
100
|
-
// Chart vars derived from a single-hue ramp should appear in the
|
|
101
|
-
// stone scale's value set.
|
|
102
|
-
const stoneValues = Object.values(colors.stone)
|
|
103
|
-
assert.ok(stoneValues.includes(value!), `--chart-${i} (${value}) should come from the stone scale`)
|
|
104
|
-
}
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
it('hue value overrides chart palette', () => {
|
|
108
|
-
const a = resolveTheme({ chartColor: 'blue' })
|
|
109
|
-
const b = resolveTheme({ chartColor: 'red' })
|
|
110
|
-
assert.notEqual(a.light['--chart-1'], b.light['--chart-1'])
|
|
111
|
-
})
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
// ─── Radius resolution ───────────────────────────────────
|
|
115
|
-
|
|
116
|
-
describe('radius', () => {
|
|
117
|
-
it("'default' falls through to PRESET_RADIUS[preset]", () => {
|
|
118
|
-
// Maia's default radius is 'large' per PRESET_RADIUS.
|
|
119
|
-
const maia = resolveTheme({ preset: 'maia', radius: 'default' })
|
|
120
|
-
assert.equal(maia.radius, radiusMap[PRESET_RADIUS.maia])
|
|
121
|
-
assert.equal(maia.radius, radiusMap.large)
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
it('undefined radius falls through to PRESET_RADIUS[preset]', () => {
|
|
125
|
-
// Same path as 'default' — both resolve through PRESET_RADIUS.
|
|
126
|
-
const luma = resolveTheme({ preset: 'luma' })
|
|
127
|
-
assert.equal(luma.radius, radiusMap[PRESET_RADIUS.luma])
|
|
128
|
-
assert.equal(luma.radius, radiusMap.xlarge)
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
it('explicit radius wins over preset default', () => {
|
|
132
|
-
// Maia's preset radius is 'large', but explicit 'small' should win.
|
|
133
|
-
const maia = resolveTheme({ preset: 'maia', radius: 'small' })
|
|
134
|
-
assert.equal(maia.radius, radiusMap.small)
|
|
135
|
-
})
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
// ─── Spacing resolution ──────────────────────────────────
|
|
139
|
-
|
|
140
|
-
describe('spacing', () => {
|
|
141
|
-
it("'default' falls through to PRESET_SPACING[preset]", () => {
|
|
142
|
-
// Mira's default spacing is 'compact'.
|
|
143
|
-
const mira = resolveTheme({ preset: 'mira', spacing: 'default' })
|
|
144
|
-
assert.equal(mira.spacing, spacingMap[PRESET_SPACING.mira])
|
|
145
|
-
assert.equal(mira.spacing, spacingMap.compact)
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
it('undefined spacing falls through to PRESET_SPACING[preset]', () => {
|
|
149
|
-
const vega = resolveTheme({ preset: 'vega' })
|
|
150
|
-
assert.equal(vega.spacing, spacingMap[PRESET_SPACING.vega])
|
|
151
|
-
assert.equal(vega.spacing, spacingMap.comfortable)
|
|
152
|
-
})
|
|
153
|
-
|
|
154
|
-
it('explicit spacing wins over preset default', () => {
|
|
155
|
-
// Mira's preset spacing is 'compact', but explicit 'comfortable' wins.
|
|
156
|
-
const mira = resolveTheme({ preset: 'mira', spacing: 'comfortable' })
|
|
157
|
-
assert.equal(mira.spacing, spacingMap.comfortable)
|
|
158
|
-
})
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
// ─── Font resolution ─────────────────────────────────────
|
|
162
|
-
|
|
163
|
-
describe('fonts', () => {
|
|
164
|
-
it('falls through to PRESET_FONTS[preset] when not set', () => {
|
|
165
|
-
const sera = resolveTheme({ preset: 'sera' })
|
|
166
|
-
assert.equal(sera.fonts?.heading, PRESET_FONTS.sera.heading)
|
|
167
|
-
assert.equal(sera.fonts?.body, PRESET_FONTS.sera.body)
|
|
168
|
-
assert.equal(sera.fonts?.heading, 'Playfair Display')
|
|
169
|
-
assert.equal(sera.fonts?.body, 'Noto Sans')
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
it('field-level fallback — body override does not drop heading default', () => {
|
|
173
|
-
// Regression guard: if resolveTheme used object-level `??`, supplying
|
|
174
|
-
// only `fonts.body` would drop the heading default. Field-level merge
|
|
175
|
-
// keeps both pieces independently overridable.
|
|
176
|
-
const sera = resolveTheme({ preset: 'sera', fonts: { body: 'Inter' } })
|
|
177
|
-
assert.equal(sera.fonts?.body, 'Inter')
|
|
178
|
-
assert.equal(sera.fonts?.heading, 'Playfair Display') // preset default
|
|
179
|
-
})
|
|
180
|
-
|
|
181
|
-
it('emits fontFamily with quoted-name fallback chain', () => {
|
|
182
|
-
const vega = resolveTheme({ preset: 'vega' })
|
|
183
|
-
assert.match(vega.fontFamily?.heading ?? '', /^'Inter', system-ui, sans-serif$/)
|
|
184
|
-
assert.match(vega.fontFamily?.body ?? '', /^'Inter', system-ui, sans-serif$/)
|
|
185
|
-
})
|
|
186
|
-
})
|
|
187
|
-
|
|
188
|
-
// ─── cssVariables escape hatch ───────────────────────────
|
|
189
|
-
|
|
190
|
-
describe('cssVariables override', () => {
|
|
191
|
-
it('overrides preset, base, theme, and chart layers', () => {
|
|
192
|
-
const result = resolveTheme({
|
|
193
|
-
preset: 'vega',
|
|
194
|
-
baseColor: 'stone',
|
|
195
|
-
themeColor: 'blue',
|
|
196
|
-
chartColor: 'red',
|
|
197
|
-
cssVariables: {
|
|
198
|
-
light: { '--primary': 'oklch(0.5 0.2 200)', '--background': 'rebeccapurple' },
|
|
199
|
-
dark: { '--primary': 'oklch(0.6 0.2 200)' },
|
|
200
|
-
},
|
|
201
|
-
})
|
|
202
|
-
// Wins over themeColor (blue would have been set first).
|
|
203
|
-
assert.equal(result.light['--primary'], 'oklch(0.5 0.2 200)')
|
|
204
|
-
// Wins over baseColor stone's --background.
|
|
205
|
-
assert.equal(result.light['--background'], 'rebeccapurple')
|
|
206
|
-
// Dark override applied independently.
|
|
207
|
-
assert.equal(result.dark['--primary'], 'oklch(0.6 0.2 200)')
|
|
208
|
-
})
|
|
209
|
-
|
|
210
|
-
it('does not leak light overrides into dark or vice versa', () => {
|
|
211
|
-
const result = resolveTheme({
|
|
212
|
-
cssVariables: { light: { '--custom': 'x' } },
|
|
213
|
-
})
|
|
214
|
-
assert.equal(result.light['--custom'], 'x')
|
|
215
|
-
assert.equal(result.dark['--custom'], undefined)
|
|
216
|
-
})
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
// ─── Misc result shape ───────────────────────────────────
|
|
220
|
-
|
|
221
|
-
describe('result shape', () => {
|
|
222
|
-
it('defaults iconLibrary to lucide', () => {
|
|
223
|
-
assert.equal(resolveTheme({}).iconLibrary, 'lucide')
|
|
224
|
-
})
|
|
225
|
-
|
|
226
|
-
it('respects iconLibrary when set', () => {
|
|
227
|
-
assert.equal(resolveTheme({ iconLibrary: 'phosphor' }).iconLibrary, 'phosphor')
|
|
228
|
-
})
|
|
229
|
-
|
|
230
|
-
it('always emits radius and spacing as concrete CSS strings', () => {
|
|
231
|
-
const r = resolveTheme({})
|
|
232
|
-
assert.equal(typeof r.radius, 'string')
|
|
233
|
-
assert.equal(typeof r.spacing, 'string')
|
|
234
|
-
assert.match(r.radius, /rem$|px$/)
|
|
235
|
-
assert.match(r.spacing, /rem$/)
|
|
236
|
-
})
|
|
237
|
-
})
|
|
238
|
-
})
|
package/src/theme/resolve.ts
DELETED
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import type { ThemeConfig, ThemeMeta, BaseColor } from './types.js'
|
|
2
|
-
import { presets, PRESET_FONTS, PRESET_RADIUS, PRESET_SPACING } from './presets.js'
|
|
3
|
-
import { baseColors } from './base-colors.js'
|
|
4
|
-
import { resolveThemeColor } from './theme-colors.js'
|
|
5
|
-
import { resolveChartColor } from './chart-colors.js'
|
|
6
|
-
import { radiusMap } from './radius.js'
|
|
7
|
-
import { spacingMap } from './spacing.js'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Resolves a user-facing `ThemeConfig` into a serializable `ThemeMeta`.
|
|
11
|
-
*
|
|
12
|
-
* Layering order (each overrides the previous):
|
|
13
|
-
* 1. Preset (full variable set)
|
|
14
|
-
* 2. Base color (gray/neutral overrides)
|
|
15
|
-
* 3. Theme color (primary/ring overrides — `'base'` derives from base color)
|
|
16
|
-
* 4. Chart color (chart-1..5 ramp — `'base'` derives from base color)
|
|
17
|
-
* 5. Raw cssVariables escape hatch
|
|
18
|
-
*/
|
|
19
|
-
export function resolveTheme(config: ThemeConfig): ThemeMeta {
|
|
20
|
-
// 1. Start with preset. Validate the name once so every downstream
|
|
21
|
-
// preset-keyed lookup (PRESET_RADIUS, PRESET_SPACING, PRESET_FONTS) is
|
|
22
|
-
// safe — bogus names from deserialized data fall through to 'vega'
|
|
23
|
-
// instead of crashing with "Cannot read properties of undefined".
|
|
24
|
-
const requestedName = config.preset ?? 'vega'
|
|
25
|
-
const presetName = presets[requestedName] ? requestedName : 'vega'
|
|
26
|
-
const preset = presets[presetName]
|
|
27
|
-
const light = { ...preset.light }
|
|
28
|
-
const dark = { ...preset.dark }
|
|
29
|
-
|
|
30
|
-
// 2. Apply base color — always layered, defaulting to neutral so the
|
|
31
|
-
// "default state" and an explicit `baseColor: 'neutral'` resolve to the
|
|
32
|
-
// same tokens. Without this, the preset's hardcoded surface values
|
|
33
|
-
// (e.g. WHITE for --background) would leak through whenever no base
|
|
34
|
-
// color is selected, making the picker show "Neutral" while the actual
|
|
35
|
-
// rendered colors didn't match a neutral selection.
|
|
36
|
-
const effectiveBase: BaseColor = config.baseColor ?? 'neutral'
|
|
37
|
-
const base = baseColors[effectiveBase]
|
|
38
|
-
Object.assign(light, base.light)
|
|
39
|
-
Object.assign(dark, base.dark)
|
|
40
|
-
|
|
41
|
-
// 3 + 4. Always apply theme + chart color (default to `'base'` sentinel).
|
|
42
|
-
// We default these so the editor's trigger ("Theme: Neutral", "Chart: Neutral")
|
|
43
|
-
// matches what the resolver actually renders. Otherwise the trigger would
|
|
44
|
-
// show "Neutral" but the preset's hardcoded primary/chart values would
|
|
45
|
-
// still leak through.
|
|
46
|
-
const themeColor = config.themeColor ?? 'base'
|
|
47
|
-
const tc = resolveThemeColor(themeColor, effectiveBase)
|
|
48
|
-
Object.assign(light, tc.light)
|
|
49
|
-
Object.assign(dark, tc.dark)
|
|
50
|
-
|
|
51
|
-
const chartColor = config.chartColor ?? 'base'
|
|
52
|
-
const cc = resolveChartColor(chartColor, effectiveBase)
|
|
53
|
-
Object.assign(light, cc.light)
|
|
54
|
-
Object.assign(dark, cc.dark)
|
|
55
|
-
|
|
56
|
-
// 5. Raw CSS variable overrides — highest priority escape hatch
|
|
57
|
-
if (config.cssVariables?.light) Object.assign(light, config.cssVariables.light)
|
|
58
|
-
if (config.cssVariables?.dark) Object.assign(dark, config.cssVariables.dark)
|
|
59
|
-
|
|
60
|
-
// Resolve radius — `'default'` (or undefined) routes through PRESET_RADIUS
|
|
61
|
-
// so each style can pick its own baseline (e.g. Maia = large). An explicit
|
|
62
|
-
// pick (none/small/medium/large) always wins over the preset default.
|
|
63
|
-
const isExplicit = config.radius && config.radius !== 'default'
|
|
64
|
-
const radiusKey = isExplicit ? config.radius! : PRESET_RADIUS[presetName]
|
|
65
|
-
const radius = radiusMap[radiusKey]
|
|
66
|
-
|
|
67
|
-
// Resolve spacing density — same pattern as radius. Drives `--spacing`,
|
|
68
|
-
// which Tailwind v4 multiplies into every `p-*` / `gap-*` / `m-*` utility.
|
|
69
|
-
const isSpacingExplicit = config.spacing && config.spacing !== 'default'
|
|
70
|
-
const spacingKey = isSpacingExplicit ? config.spacing! : PRESET_SPACING[presetName]
|
|
71
|
-
const spacing = spacingMap[spacingKey]
|
|
72
|
-
|
|
73
|
-
// Resolve fonts — fall through to the per-style font pairing in PRESET_FONTS.
|
|
74
|
-
// Field-level fallback (not object-level ??) so `fonts: { body: '...' }`
|
|
75
|
-
// doesn't accidentally drop the heading default.
|
|
76
|
-
const presetFonts = PRESET_FONTS[presetName]
|
|
77
|
-
const fonts = {
|
|
78
|
-
body: config.fonts?.body ?? presetFonts.body,
|
|
79
|
-
heading: config.fonts?.heading ?? presetFonts.heading,
|
|
80
|
-
}
|
|
81
|
-
const fontFamily: { heading?: string; body?: string } = {}
|
|
82
|
-
if (fonts.heading) fontFamily.heading = `'${fonts.heading}', system-ui, sans-serif`
|
|
83
|
-
if (fonts.body) fontFamily.body = `'${fonts.body}', system-ui, sans-serif`
|
|
84
|
-
|
|
85
|
-
const result: ThemeMeta = {
|
|
86
|
-
light,
|
|
87
|
-
dark,
|
|
88
|
-
radius,
|
|
89
|
-
spacing,
|
|
90
|
-
iconLibrary: config.iconLibrary ?? 'lucide',
|
|
91
|
-
}
|
|
92
|
-
result.fonts = fonts
|
|
93
|
-
if (Object.keys(fontFamily).length > 0) result.fontFamily = fontFamily
|
|
94
|
-
|
|
95
|
-
return result
|
|
96
|
-
}
|
package/src/theme/spacing.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { SpacingPreset } from './types.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Maps spacing density presets to Tailwind v4 `--spacing` values.
|
|
5
|
-
*
|
|
6
|
-
* Tailwind compiles every `p-*`, `gap-*`, `m-*` utility as
|
|
7
|
-
* `calc(var(--spacing) * N)`, so swapping this single token uniformly tightens
|
|
8
|
-
* or loosens every gap and padding in the panel — no per-component edits.
|
|
9
|
-
*
|
|
10
|
-
* `'default'` is the sentinel resolver; the picker shows it as the first
|
|
11
|
-
* option and falls through to `PRESET_SPACING[preset]`. `0.25rem` matches
|
|
12
|
-
* Tailwind's stock value, kept as `default`'s rendered fallback for parity.
|
|
13
|
-
*/
|
|
14
|
-
export const spacingMap: Record<SpacingPreset, string> = {
|
|
15
|
-
default: '0.25rem',
|
|
16
|
-
compact: '0.2rem',
|
|
17
|
-
comfortable: '0.3rem',
|
|
18
|
-
}
|