@flanksource/clicky-ui 0.2.14 → 0.2.16
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/chat.cjs +20 -0
- package/dist/chat.cjs.map +1 -0
- package/dist/chat.d.ts +2 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +20 -0
- package/dist/chat.js.map +1 -0
- package/dist/components/Combobox.cjs +19 -9
- package/dist/components/Combobox.cjs.map +1 -1
- package/dist/components/Combobox.d.ts +10 -0
- package/dist/components/Combobox.d.ts.map +1 -1
- package/dist/components/Combobox.js +19 -9
- package/dist/components/Combobox.js.map +1 -1
- package/dist/components/DateTimePicker.cjs +6 -1
- package/dist/components/DateTimePicker.cjs.map +1 -1
- package/dist/components/DateTimePicker.d.ts +11 -3
- package/dist/components/DateTimePicker.d.ts.map +1 -1
- package/dist/components/DateTimePicker.js +6 -1
- package/dist/components/DateTimePicker.js.map +1 -1
- package/dist/components/Field.cjs +33 -0
- package/dist/components/Field.cjs.map +1 -0
- package/dist/components/Field.d.ts +27 -0
- package/dist/components/Field.d.ts.map +1 -0
- package/dist/components/Field.js +33 -0
- package/dist/components/Field.js.map +1 -0
- package/dist/components/FilterBar.cjs +49 -55
- package/dist/components/FilterBar.cjs.map +1 -1
- package/dist/components/FilterBar.d.ts +2 -2
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +44 -50
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/FormatOptionsDropdown.cjs +2 -18
- package/dist/components/FormatOptionsDropdown.cjs.map +1 -1
- package/dist/components/FormatOptionsDropdown.d.ts +1 -17
- package/dist/components/FormatOptionsDropdown.d.ts.map +1 -1
- package/dist/components/FormatOptionsDropdown.js +1 -17
- package/dist/components/FormatOptionsDropdown.js.map +1 -1
- package/dist/components/JsonSchemaForm.cjs +128 -12
- package/dist/components/JsonSchemaForm.cjs.map +1 -1
- package/dist/components/JsonSchemaForm.d.ts +1 -1
- package/dist/components/JsonSchemaForm.d.ts.map +1 -1
- package/dist/components/JsonSchemaForm.js +131 -15
- package/dist/components/JsonSchemaForm.js.map +1 -1
- package/dist/components/MultiSelect.cjs +2 -1
- package/dist/components/MultiSelect.cjs.map +1 -1
- package/dist/components/MultiSelect.d.ts +5 -1
- package/dist/components/MultiSelect.d.ts.map +1 -1
- package/dist/components/MultiSelect.js +2 -1
- package/dist/components/MultiSelect.js.map +1 -1
- package/dist/components/SecretKeySelector.cjs +0 -1
- package/dist/components/SecretKeySelector.cjs.map +1 -1
- package/dist/components/SecretKeySelector.d.ts +0 -2
- package/dist/components/SecretKeySelector.d.ts.map +1 -1
- package/dist/components/SecretKeySelector.js +1 -2
- package/dist/components/SecretKeySelector.js.map +1 -1
- package/dist/components/TreePickerField.cjs +137 -0
- package/dist/components/TreePickerField.cjs.map +1 -0
- package/dist/components/TreePickerField.d.ts +30 -0
- package/dist/components/TreePickerField.d.ts.map +1 -0
- package/dist/components/TreePickerField.js +137 -0
- package/dist/components/TreePickerField.js.map +1 -0
- package/dist/components/WorkloadPicker.cjs +6 -81
- package/dist/components/WorkloadPicker.cjs.map +1 -1
- package/dist/components/WorkloadPicker.d.ts +1 -20
- package/dist/components/WorkloadPicker.d.ts.map +1 -1
- package/dist/components/WorkloadPicker.js +3 -78
- package/dist/components/WorkloadPicker.js.map +1 -1
- package/dist/components/button-variants.cjs +30 -0
- package/dist/components/button-variants.cjs.map +1 -0
- package/dist/components/button-variants.d.ts +5 -0
- package/dist/components/button-variants.d.ts.map +1 -0
- package/dist/components/button-variants.js +30 -0
- package/dist/components/button-variants.js.map +1 -0
- package/dist/components/button.cjs +11 -82
- package/dist/components/button.cjs.map +1 -1
- package/dist/components/button.d.ts +1 -5
- package/dist/components/button.d.ts.map +1 -1
- package/dist/components/button.js +5 -76
- package/dist/components/button.js.map +1 -1
- package/dist/components/filter-bar-utils.cjs +37 -0
- package/dist/components/filter-bar-utils.cjs.map +1 -0
- package/dist/components/filter-bar-utils.d.ts +4 -0
- package/dist/components/filter-bar-utils.d.ts.map +1 -0
- package/dist/components/filter-bar-utils.js +37 -0
- package/dist/components/filter-bar-utils.js.map +1 -0
- package/dist/components/format-options.cjs +20 -0
- package/dist/components/format-options.cjs.map +1 -0
- package/dist/components/format-options.d.ts +18 -0
- package/dist/components/format-options.d.ts.map +1 -0
- package/dist/components/format-options.js +20 -0
- package/dist/components/format-options.js.map +1 -0
- package/dist/components/json-schema-form-array.cjs +13 -17
- package/dist/components/json-schema-form-array.cjs.map +1 -1
- package/dist/components/json-schema-form-array.d.ts +1 -2
- package/dist/components/json-schema-form-array.d.ts.map +1 -1
- package/dist/components/json-schema-form-array.js +3 -7
- package/dist/components/json-schema-form-array.js.map +1 -1
- package/dist/components/json-schema-form-fields.cjs +97 -232
- package/dist/components/json-schema-form-fields.cjs.map +1 -1
- package/dist/components/json-schema-form-fields.d.ts +51 -6
- package/dist/components/json-schema-form-fields.d.ts.map +1 -1
- package/dist/components/json-schema-form-fields.js +89 -224
- package/dist/components/json-schema-form-fields.js.map +1 -1
- package/dist/components/json-schema-form-object.cjs +149 -0
- package/dist/components/json-schema-form-object.cjs.map +1 -0
- package/dist/components/json-schema-form-object.d.ts +10 -0
- package/dist/components/json-schema-form-object.d.ts.map +1 -0
- package/dist/components/json-schema-form-object.js +149 -0
- package/dist/components/json-schema-form-object.js.map +1 -0
- package/dist/components/json-schema-form-preferences.cjs +41 -0
- package/dist/components/json-schema-form-preferences.cjs.map +1 -0
- package/dist/components/json-schema-form-preferences.d.ts +10 -0
- package/dist/components/json-schema-form-preferences.d.ts.map +1 -0
- package/dist/components/json-schema-form-preferences.js +41 -0
- package/dist/components/json-schema-form-preferences.js.map +1 -0
- package/dist/components/json-schema-form-render.cjs +43 -72
- package/dist/components/json-schema-form-render.cjs.map +1 -1
- package/dist/components/json-schema-form-render.d.ts +5 -33
- package/dist/components/json-schema-form-render.d.ts.map +1 -1
- package/dist/components/json-schema-form-render.js +41 -70
- package/dist/components/json-schema-form-render.js.map +1 -1
- package/dist/components/json-schema-form-resolve.cjs +9 -1
- package/dist/components/json-schema-form-resolve.cjs.map +1 -1
- package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
- package/dist/components/json-schema-form-resolve.js +9 -1
- package/dist/components/json-schema-form-resolve.js.map +1 -1
- package/dist/components/json-schema-form-types.d.ts +59 -1
- package/dist/components/json-schema-form-types.d.ts.map +1 -1
- package/dist/components/json-schema-form-utils.cjs +96 -0
- package/dist/components/json-schema-form-utils.cjs.map +1 -0
- package/dist/components/json-schema-form-utils.d.ts +17 -0
- package/dist/components/json-schema-form-utils.d.ts.map +1 -0
- package/dist/components/json-schema-form-utils.js +96 -0
- package/dist/components/json-schema-form-utils.js.map +1 -0
- package/dist/components/loading.cjs +109 -0
- package/dist/components/loading.cjs.map +1 -0
- package/dist/components/loading.d.ts +29 -0
- package/dist/components/loading.d.ts.map +1 -0
- package/dist/components/loading.js +109 -0
- package/dist/components/loading.js.map +1 -0
- package/dist/components/use-form.cjs +27 -0
- package/dist/components/use-form.cjs.map +1 -0
- package/dist/components/use-form.d.ts +30 -0
- package/dist/components/use-form.d.ts.map +1 -0
- package/dist/components/use-form.js +27 -0
- package/dist/components/use-form.js.map +1 -0
- package/dist/components/workload-picker-utils.cjs +88 -0
- package/dist/components/workload-picker-utils.cjs.map +1 -0
- package/dist/components/workload-picker-utils.d.ts +34 -0
- package/dist/components/workload-picker-utils.d.ts.map +1 -0
- package/dist/components/workload-picker-utils.js +88 -0
- package/dist/components/workload-picker-utils.js.map +1 -0
- package/dist/components.cjs +25 -6
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.ts +14 -4
- package/dist/components.d.ts.map +1 -1
- package/dist/components.js +24 -5
- package/dist/components.js.map +1 -1
- package/dist/data/Badge.cjs +11 -91
- package/dist/data/Badge.cjs.map +1 -1
- package/dist/data/Badge.d.ts +1 -5
- package/dist/data/Badge.d.ts.map +1 -1
- package/dist/data/Badge.js +11 -91
- package/dist/data/Badge.js.map +1 -1
- package/dist/data/Clicky.cjs +4 -3
- package/dist/data/Clicky.cjs.map +1 -1
- package/dist/data/Clicky.d.ts.map +1 -1
- package/dist/data/Clicky.js +4 -3
- package/dist/data/Clicky.js.map +1 -1
- package/dist/data/DataTable.cjs +161 -156
- package/dist/data/DataTable.cjs.map +1 -1
- package/dist/data/DataTable.d.ts +25 -4
- package/dist/data/DataTable.d.ts.map +1 -1
- package/dist/data/DataTable.js +140 -135
- package/dist/data/DataTable.js.map +1 -1
- package/dist/data/FilterPill.cjs +3 -0
- package/dist/data/FilterPill.cjs.map +1 -1
- package/dist/data/FilterPill.d.ts.map +1 -1
- package/dist/data/FilterPill.js +3 -0
- package/dist/data/FilterPill.js.map +1 -1
- package/dist/data/Icon.cjs +7 -7
- package/dist/data/Icon.cjs.map +1 -1
- package/dist/data/Icon.js +7 -7
- package/dist/data/Icon.js.map +1 -1
- package/dist/data/LogDetails.cjs +5 -14
- package/dist/data/LogDetails.cjs.map +1 -1
- package/dist/data/LogDetails.d.ts +8 -4
- package/dist/data/LogDetails.d.ts.map +1 -1
- package/dist/data/LogDetails.js +4 -13
- package/dist/data/LogDetails.js.map +1 -1
- package/dist/data/LogsTable.cjs +6 -165
- package/dist/data/LogsTable.cjs.map +1 -1
- package/dist/data/LogsTable.d.ts +2 -15
- package/dist/data/LogsTable.d.ts.map +1 -1
- package/dist/data/LogsTable.js +6 -165
- package/dist/data/LogsTable.js.map +1 -1
- package/dist/data/TimeseriesPanel.axes.cjs.map +1 -1
- package/dist/data/TimeseriesPanel.axes.js.map +1 -1
- package/dist/data/TreeNode.cjs +13 -7
- package/dist/data/TreeNode.cjs.map +1 -1
- package/dist/data/TreeNode.d.ts.map +1 -1
- package/dist/data/TreeNode.js +13 -7
- package/dist/data/TreeNode.js.map +1 -1
- package/dist/data/badge-variants.cjs +85 -0
- package/dist/data/badge-variants.cjs.map +1 -0
- package/dist/data/badge-variants.d.ts +6 -0
- package/dist/data/badge-variants.d.ts.map +1 -0
- package/dist/data/badge-variants.js +85 -0
- package/dist/data/badge-variants.js.map +1 -0
- package/dist/data/cache-browser/CacheBrowser.cjs +59 -0
- package/dist/data/cache-browser/CacheBrowser.cjs.map +1 -0
- package/dist/data/cache-browser/CacheBrowser.d.ts +26 -0
- package/dist/data/cache-browser/CacheBrowser.d.ts.map +1 -0
- package/dist/data/cache-browser/CacheBrowser.js +59 -0
- package/dist/data/cache-browser/CacheBrowser.js.map +1 -0
- package/dist/data/cache-browser/CacheDetailPanel.cjs +193 -0
- package/dist/data/cache-browser/CacheDetailPanel.cjs.map +1 -0
- package/dist/data/cache-browser/CacheDetailPanel.d.ts +20 -0
- package/dist/data/cache-browser/CacheDetailPanel.d.ts.map +1 -0
- package/dist/data/cache-browser/CacheDetailPanel.js +193 -0
- package/dist/data/cache-browser/CacheDetailPanel.js.map +1 -0
- package/dist/data/cache-browser/CacheStatsOverview.cjs +126 -0
- package/dist/data/cache-browser/CacheStatsOverview.cjs.map +1 -0
- package/dist/data/cache-browser/CacheStatsOverview.d.ts +17 -0
- package/dist/data/cache-browser/CacheStatsOverview.d.ts.map +1 -0
- package/dist/data/cache-browser/CacheStatsOverview.js +126 -0
- package/dist/data/cache-browser/CacheStatsOverview.js.map +1 -0
- package/dist/data/cache-browser/CacheTree.cjs +189 -0
- package/dist/data/cache-browser/CacheTree.cjs.map +1 -0
- package/dist/data/cache-browser/CacheTree.d.ts +27 -0
- package/dist/data/cache-browser/CacheTree.d.ts.map +1 -0
- package/dist/data/cache-browser/CacheTree.js +189 -0
- package/dist/data/cache-browser/CacheTree.js.map +1 -0
- package/dist/data/cache-browser/CacheValue.cjs +86 -0
- package/dist/data/cache-browser/CacheValue.cjs.map +1 -0
- package/dist/data/cache-browser/CacheValue.d.ts +11 -0
- package/dist/data/cache-browser/CacheValue.d.ts.map +1 -0
- package/dist/data/cache-browser/CacheValue.js +86 -0
- package/dist/data/cache-browser/CacheValue.js.map +1 -0
- package/dist/data/cache-browser/adapter.cjs +52 -0
- package/dist/data/cache-browser/adapter.cjs.map +1 -0
- package/dist/data/cache-browser/adapter.d.ts +48 -0
- package/dist/data/cache-browser/adapter.d.ts.map +1 -0
- package/dist/data/cache-browser/adapter.js +52 -0
- package/dist/data/cache-browser/adapter.js.map +1 -0
- package/dist/data/cache-browser/api.cjs +42 -0
- package/dist/data/cache-browser/api.cjs.map +1 -0
- package/dist/data/cache-browser/api.d.ts +33 -0
- package/dist/data/cache-browser/api.d.ts.map +1 -0
- package/dist/data/cache-browser/api.js +42 -0
- package/dist/data/cache-browser/api.js.map +1 -0
- package/dist/data/cache-browser/index.d.ts +9 -0
- package/dist/data/cache-browser/index.d.ts.map +1 -0
- package/dist/data/cache-browser/types.cjs +7 -0
- package/dist/data/cache-browser/types.cjs.map +1 -0
- package/dist/data/cache-browser/types.d.ts +78 -0
- package/dist/data/cache-browser/types.d.ts.map +1 -0
- package/dist/data/cache-browser/types.js +7 -0
- package/dist/data/cache-browser/types.js.map +1 -0
- package/dist/data/cells/TagList.cjs +4 -101
- package/dist/data/cells/TagList.cjs.map +1 -1
- package/dist/data/cells/TagList.d.ts +1 -49
- package/dist/data/cells/TagList.d.ts.map +1 -1
- package/dist/data/cells/TagList.js +3 -100
- package/dist/data/cells/TagList.js.map +1 -1
- package/dist/data/cells/Timestamp.cjs +3 -192
- package/dist/data/cells/Timestamp.cjs.map +1 -1
- package/dist/data/cells/Timestamp.d.ts +1 -50
- package/dist/data/cells/Timestamp.d.ts.map +1 -1
- package/dist/data/cells/Timestamp.js +2 -191
- package/dist/data/cells/Timestamp.js.map +1 -1
- package/dist/data/cells/tag-utils.cjs +103 -0
- package/dist/data/cells/tag-utils.cjs.map +1 -0
- package/dist/data/cells/tag-utils.d.ts +51 -0
- package/dist/data/cells/tag-utils.d.ts.map +1 -0
- package/dist/data/cells/tag-utils.js +103 -0
- package/dist/data/cells/tag-utils.js.map +1 -0
- package/dist/data/cells/timestamp-format.cjs +193 -0
- package/dist/data/cells/timestamp-format.cjs.map +1 -0
- package/dist/data/cells/timestamp-format.d.ts +51 -0
- package/dist/data/cells/timestamp-format.d.ts.map +1 -0
- package/dist/data/cells/timestamp-format.js +193 -0
- package/dist/data/cells/timestamp-format.js.map +1 -0
- package/dist/data/chat/Chat.cjs +48 -0
- package/dist/data/chat/Chat.cjs.map +1 -0
- package/dist/data/chat/Chat.d.ts +26 -0
- package/dist/data/chat/Chat.d.ts.map +1 -0
- package/dist/data/chat/Chat.fixtures.d.ts +6 -0
- package/dist/data/chat/Chat.fixtures.d.ts.map +1 -0
- package/dist/data/chat/Chat.js +48 -0
- package/dist/data/chat/Chat.js.map +1 -0
- package/dist/data/chat/Conversation.cjs +34 -0
- package/dist/data/chat/Conversation.cjs.map +1 -0
- package/dist/data/chat/Conversation.d.ts +11 -0
- package/dist/data/chat/Conversation.d.ts.map +1 -0
- package/dist/data/chat/Conversation.js +34 -0
- package/dist/data/chat/Conversation.js.map +1 -0
- package/dist/data/chat/Message.cjs +44 -0
- package/dist/data/chat/Message.cjs.map +1 -0
- package/dist/data/chat/Message.d.ts +10 -0
- package/dist/data/chat/Message.d.ts.map +1 -0
- package/dist/data/chat/Message.js +44 -0
- package/dist/data/chat/Message.js.map +1 -0
- package/dist/data/chat/PromptInput.cjs +61 -0
- package/dist/data/chat/PromptInput.cjs.map +1 -0
- package/dist/data/chat/PromptInput.d.ts +16 -0
- package/dist/data/chat/PromptInput.d.ts.map +1 -0
- package/dist/data/chat/PromptInput.js +61 -0
- package/dist/data/chat/PromptInput.js.map +1 -0
- package/dist/data/chat/ToolCall.cjs +92 -0
- package/dist/data/chat/ToolCall.cjs.map +1 -0
- package/dist/data/chat/ToolCall.d.ts +14 -0
- package/dist/data/chat/ToolCall.d.ts.map +1 -0
- package/dist/data/chat/ToolCall.js +92 -0
- package/dist/data/chat/ToolCall.js.map +1 -0
- package/dist/data/chat/clickyOperationsToTools.cjs +73 -0
- package/dist/data/chat/clickyOperationsToTools.cjs.map +1 -0
- package/dist/data/chat/clickyOperationsToTools.d.ts +10 -0
- package/dist/data/chat/clickyOperationsToTools.d.ts.map +1 -0
- package/dist/data/chat/clickyOperationsToTools.js +73 -0
- package/dist/data/chat/clickyOperationsToTools.js.map +1 -0
- package/dist/data/chat/index.d.ts +8 -0
- package/dist/data/chat/index.d.ts.map +1 -0
- package/dist/data/chat/types.cjs +18 -0
- package/dist/data/chat/types.cjs.map +1 -0
- package/dist/data/chat/types.d.ts +41 -0
- package/dist/data/chat/types.d.ts.map +1 -0
- package/dist/data/chat/types.js +18 -0
- package/dist/data/chat/types.js.map +1 -0
- package/dist/data/data-table-utils.cjs +55 -0
- package/dist/data/data-table-utils.cjs.map +1 -0
- package/dist/data/data-table-utils.d.ts +24 -0
- package/dist/data/data-table-utils.d.ts.map +1 -0
- package/dist/data/data-table-utils.js +55 -0
- package/dist/data/data-table-utils.js.map +1 -0
- package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +2 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -1
- package/dist/data/diagnostics/DiagnosticsDetailPanel.js +3 -2
- package/dist/data/diagnostics/DiagnosticsDetailPanel.js.map +1 -1
- package/dist/data/diagnostics/GoroutineCard.cjs +3 -22
- package/dist/data/diagnostics/GoroutineCard.cjs.map +1 -1
- package/dist/data/diagnostics/GoroutineCard.d.ts +0 -2
- package/dist/data/diagnostics/GoroutineCard.d.ts.map +1 -1
- package/dist/data/diagnostics/GoroutineCard.js +2 -21
- package/dist/data/diagnostics/GoroutineCard.js.map +1 -1
- package/dist/data/diagnostics/ThreadCard.cjs +3 -38
- package/dist/data/diagnostics/ThreadCard.cjs.map +1 -1
- package/dist/data/diagnostics/ThreadCard.d.ts +0 -2
- package/dist/data/diagnostics/ThreadCard.d.ts.map +1 -1
- package/dist/data/diagnostics/ThreadCard.js +2 -37
- package/dist/data/diagnostics/ThreadCard.js.map +1 -1
- package/dist/data/diagnostics/state-styles.cjs +59 -0
- package/dist/data/diagnostics/state-styles.cjs.map +1 -0
- package/dist/data/diagnostics/state-styles.d.ts +5 -0
- package/dist/data/diagnostics/state-styles.d.ts.map +1 -0
- package/dist/data/diagnostics/state-styles.js +59 -0
- package/dist/data/diagnostics/state-styles.js.map +1 -0
- package/dist/data/logs-normalize.cjs +166 -0
- package/dist/data/logs-normalize.cjs.map +1 -0
- package/dist/data/logs-normalize.d.ts +16 -0
- package/dist/data/logs-normalize.d.ts.map +1 -0
- package/dist/data/logs-normalize.js +166 -0
- package/dist/data/logs-normalize.js.map +1 -0
- package/dist/data/task-status.cjs +19 -19
- package/dist/data/task-status.cjs.map +1 -1
- package/dist/data/task-status.js +19 -19
- package/dist/data/task-status.js.map +1 -1
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +43 -18
- package/dist/data.cjs.map +1 -1
- package/dist/data.d.ts +11 -5
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +30 -5
- package/dist/data.js.map +1 -1
- package/dist/hooks/density-provider.cjs +38 -0
- package/dist/hooks/density-provider.cjs.map +1 -0
- package/dist/hooks/density-provider.d.ts +20 -0
- package/dist/hooks/density-provider.d.ts.map +1 -0
- package/dist/hooks/density-provider.js +38 -0
- package/dist/hooks/density-provider.js.map +1 -0
- package/dist/hooks/theme-provider.cjs +43 -0
- package/dist/hooks/theme-provider.cjs.map +1 -0
- package/dist/hooks/theme-provider.d.ts +9 -0
- package/dist/hooks/theme-provider.d.ts.map +1 -0
- package/dist/hooks/theme-provider.js +43 -0
- package/dist/hooks/theme-provider.js.map +1 -0
- package/dist/hooks/use-density.cjs +8 -37
- package/dist/hooks/use-density.cjs.map +1 -1
- package/dist/hooks/use-density.d.ts +5 -20
- package/dist/hooks/use-density.d.ts.map +1 -1
- package/dist/hooks/use-density.js +9 -38
- package/dist/hooks/use-density.js.map +1 -1
- package/dist/hooks/use-theme.cjs +10 -43
- package/dist/hooks/use-theme.cjs.map +1 -1
- package/dist/hooks/use-theme.d.ts +6 -9
- package/dist/hooks/use-theme.d.ts.map +1 -1
- package/dist/hooks/use-theme.js +11 -44
- package/dist/hooks/use-theme.js.map +1 -1
- package/dist/hooks.cjs +5 -2
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.ts +4 -2
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +5 -2
- package/dist/hooks.js.map +1 -1
- package/dist/icons/changeIconAliases.cjs +13 -13
- package/dist/icons/changeIconAliases.cjs.map +1 -1
- package/dist/icons/changeIconAliases.d.ts.map +1 -1
- package/dist/icons/changeIconAliases.js +13 -13
- package/dist/icons/changeIconAliases.js.map +1 -1
- package/dist/index.cjs +78 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +61 -13
- package/dist/index.js.map +1 -1
- package/dist/overlay/DropdownMenu.cjs +2 -0
- package/dist/overlay/DropdownMenu.cjs.map +1 -1
- package/dist/overlay/DropdownMenu.d.ts +3 -1
- package/dist/overlay/DropdownMenu.d.ts.map +1 -1
- package/dist/overlay/DropdownMenu.js +2 -0
- package/dist/overlay/DropdownMenu.js.map +1 -1
- package/dist/overlay/Modal.cjs +38 -27
- package/dist/overlay/Modal.cjs.map +1 -1
- package/dist/overlay/Modal.d.ts +8 -2
- package/dist/overlay/Modal.d.ts.map +1 -1
- package/dist/overlay/Modal.js +38 -27
- package/dist/overlay/Modal.js.map +1 -1
- package/dist/overlay/modalStack.cjs +35 -0
- package/dist/overlay/modalStack.cjs.map +1 -0
- package/dist/overlay/modalStack.d.ts +13 -0
- package/dist/overlay/modalStack.d.ts.map +1 -0
- package/dist/overlay/modalStack.js +35 -0
- package/dist/overlay/modalStack.js.map +1 -0
- package/dist/rpc/AcceptPicker.cjs +2 -18
- package/dist/rpc/AcceptPicker.cjs.map +1 -1
- package/dist/rpc/AcceptPicker.d.ts +1 -41
- package/dist/rpc/AcceptPicker.d.ts.map +1 -1
- package/dist/rpc/AcceptPicker.js +2 -18
- package/dist/rpc/AcceptPicker.js.map +1 -1
- package/dist/rpc/CommandOutput.cjs +1 -1
- package/dist/rpc/CommandOutput.cjs.map +1 -1
- package/dist/rpc/CommandOutput.js +1 -1
- package/dist/rpc/CommandOutput.js.map +1 -1
- package/dist/rpc/EndpointList.cjs +1 -1
- package/dist/rpc/EndpointList.cjs.map +1 -1
- package/dist/rpc/EndpointList.js +1 -1
- package/dist/rpc/EndpointList.js.map +1 -1
- package/dist/rpc/FilterForm.cjs +4 -4
- package/dist/rpc/FilterForm.cjs.map +1 -1
- package/dist/rpc/FilterForm.js +4 -4
- package/dist/rpc/FilterForm.js.map +1 -1
- package/dist/rpc/OperationCatalog.cjs +38 -60
- package/dist/rpc/OperationCatalog.cjs.map +1 -1
- package/dist/rpc/OperationCatalog.d.ts +3 -3
- package/dist/rpc/OperationCatalog.d.ts.map +1 -1
- package/dist/rpc/OperationCatalog.js +40 -62
- package/dist/rpc/OperationCatalog.js.map +1 -1
- package/dist/rpc/OperationCommandPage.cjs.map +1 -1
- package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
- package/dist/rpc/OperationCommandPage.js.map +1 -1
- package/dist/rpc/accept-options.cjs +20 -0
- package/dist/rpc/accept-options.cjs.map +1 -0
- package/dist/rpc/accept-options.d.ts +42 -0
- package/dist/rpc/accept-options.d.ts.map +1 -0
- package/dist/rpc/accept-options.js +20 -0
- package/dist/rpc/accept-options.js.map +1 -0
- package/dist/rpc/classify.cjs +15 -4
- package/dist/rpc/classify.cjs.map +1 -1
- package/dist/rpc/classify.d.ts.map +1 -1
- package/dist/rpc/classify.js +15 -4
- package/dist/rpc/classify.js.map +1 -1
- package/dist/rpc/clickyMetadata.cjs +13 -3
- package/dist/rpc/clickyMetadata.cjs.map +1 -1
- package/dist/rpc/clickyMetadata.d.ts +2 -0
- package/dist/rpc/clickyMetadata.d.ts.map +1 -1
- package/dist/rpc/clickyMetadata.js +14 -4
- package/dist/rpc/clickyMetadata.js.map +1 -1
- package/dist/rpc/formMetadata.cjs +5 -3
- package/dist/rpc/formMetadata.cjs.map +1 -1
- package/dist/rpc/formMetadata.d.ts.map +1 -1
- package/dist/rpc/formMetadata.js +5 -3
- package/dist/rpc/formMetadata.js.map +1 -1
- package/dist/rpc.cjs +3 -2
- package/dist/rpc.cjs.map +1 -1
- package/dist/rpc.d.ts +2 -1
- package/dist/rpc.d.ts.map +1 -1
- package/dist/rpc.js +2 -1
- package/dist/rpc.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +16 -1
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
require("react");
|
|
5
|
+
const utils = require("../lib/utils.cjs");
|
|
6
|
+
const Icon = require("../data/Icon.cjs");
|
|
7
|
+
const button = require("./button.cjs");
|
|
8
|
+
const Combobox = require("./Combobox.cjs");
|
|
9
|
+
const jsonSchemaFormUtils = require("./json-schema-form-utils.cjs");
|
|
10
|
+
const jsonSchemaFormFields = require("./json-schema-form-fields.cjs");
|
|
11
|
+
const jsonSchemaFormSize = require("./json-schema-form-size.cjs");
|
|
12
|
+
const UiAdd = require("../icons/components/UiAdd.cjs");
|
|
13
|
+
const UiTrash = require("../icons/components/UiTrash.cjs");
|
|
14
|
+
function ObjectControl({ field, ctx }) {
|
|
15
|
+
const obj = jsonSchemaFormUtils.isPlainObject(field.value) ? field.value : {};
|
|
16
|
+
const subSchema = {
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: field.objectProperties ?? {},
|
|
19
|
+
...field.objectRequired ? { required: field.objectRequired } : {},
|
|
20
|
+
...Array.isArray(field.schema.allOf) ? { allOf: field.schema.allOf } : {},
|
|
21
|
+
...Array.isArray(field.schema["x-order"]) ? { "x-order": field.schema["x-order"] } : {}
|
|
22
|
+
};
|
|
23
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsonSchemaFormFields.FieldsGrid, { layout: ctx.layout, size: ctx.size, children: ctx.render.renderObjectFields(subSchema, obj, (next) => field.onChange(next), {
|
|
24
|
+
...ctx,
|
|
25
|
+
readOnly: ctx.readOnly || field.readOnly === true,
|
|
26
|
+
depth: ctx.depth + 1
|
|
27
|
+
}) });
|
|
28
|
+
}
|
|
29
|
+
function StringMapControl({ field, ctx }) {
|
|
30
|
+
const readOnly = ctx.readOnly || field.readOnly === true;
|
|
31
|
+
const map = jsonSchemaFormUtils.isPlainObject(field.value) ? field.value : {};
|
|
32
|
+
const known = field.knownProperties ?? {};
|
|
33
|
+
const knownKeys = Object.keys(known);
|
|
34
|
+
const extraKeys = Object.keys(map).filter((k) => !(k in known));
|
|
35
|
+
const childCtx = { ...ctx, readOnly, depth: ctx.depth + 1 };
|
|
36
|
+
const pn = field.schema.propertyNames;
|
|
37
|
+
const keyTitle = typeof (pn == null ? void 0 : pn.title) === "string" && pn.title ? pn.title : void 0;
|
|
38
|
+
function valueSchemaForKey(key) {
|
|
39
|
+
for (const { pattern, schema } of field.valuePatternSchemas ?? []) {
|
|
40
|
+
let re;
|
|
41
|
+
try {
|
|
42
|
+
re = new RegExp(pattern);
|
|
43
|
+
} catch {
|
|
44
|
+
re = void 0;
|
|
45
|
+
}
|
|
46
|
+
if (re == null ? void 0 : re.test(key)) return schema;
|
|
47
|
+
}
|
|
48
|
+
return field.valueSchema ?? { type: "string" };
|
|
49
|
+
}
|
|
50
|
+
function entryIsStacked(key) {
|
|
51
|
+
return valueSchemaForKey(key)["x-layout"] === "stack";
|
|
52
|
+
}
|
|
53
|
+
function setEntry(key, next) {
|
|
54
|
+
field.onChange({ ...map, [key]: next });
|
|
55
|
+
}
|
|
56
|
+
function renameEntry(oldKey, newKey) {
|
|
57
|
+
if (newKey === oldKey) return;
|
|
58
|
+
const next = {};
|
|
59
|
+
for (const [k, v] of Object.entries(map)) next[k === oldKey ? newKey : k] = v;
|
|
60
|
+
field.onChange(next);
|
|
61
|
+
}
|
|
62
|
+
function removeEntry(key) {
|
|
63
|
+
const next = { ...map };
|
|
64
|
+
delete next[key];
|
|
65
|
+
field.onChange(next);
|
|
66
|
+
}
|
|
67
|
+
function addEntry() {
|
|
68
|
+
if ("" in map) return;
|
|
69
|
+
field.onChange({ ...map, "": "" });
|
|
70
|
+
}
|
|
71
|
+
function valueControlFor(key, valueSchema) {
|
|
72
|
+
const nodes = ctx.render.renderFieldNodes(
|
|
73
|
+
{
|
|
74
|
+
key,
|
|
75
|
+
prop: valueSchema,
|
|
76
|
+
required: false,
|
|
77
|
+
value: map[key] ?? "",
|
|
78
|
+
onChange: (next) => setEntry(key, next)
|
|
79
|
+
},
|
|
80
|
+
childCtx
|
|
81
|
+
);
|
|
82
|
+
return (nodes == null ? void 0 : nodes.value) ?? null;
|
|
83
|
+
}
|
|
84
|
+
function valueControlForKey(key) {
|
|
85
|
+
return valueControlFor(key, valueSchemaForKey(key));
|
|
86
|
+
}
|
|
87
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils.cn("flex flex-col rounded-md border border-input p-2", jsonSchemaFormSize.fieldInnerGapClass[childCtx.size]), children: [
|
|
88
|
+
knownKeys.map((key) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[10rem_1fr] items-center gap-2", children: [
|
|
89
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: jsonSchemaFormUtils.fieldInputId(key, childCtx.idPrefix), className: "truncate text-xs text-muted-foreground", title: key, children: key }),
|
|
90
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children: valueControlFor(key, known[key] ?? { type: "string" }) })
|
|
91
|
+
] }, `known-${key}`)),
|
|
92
|
+
extraKeys.map((key) => {
|
|
93
|
+
const keyControl = field.keyOptions ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
94
|
+
Combobox.Combobox,
|
|
95
|
+
{
|
|
96
|
+
options: jsonSchemaFormUtils.keyPickerOptions(field.keyOptions, extraKeys, key),
|
|
97
|
+
value: key,
|
|
98
|
+
disabled: readOnly,
|
|
99
|
+
size: childCtx.size,
|
|
100
|
+
allowCustomValue: false,
|
|
101
|
+
onChange: (next) => renameEntry(key, next),
|
|
102
|
+
placeholder: "Select…"
|
|
103
|
+
}
|
|
104
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
105
|
+
"input",
|
|
106
|
+
{
|
|
107
|
+
type: "text",
|
|
108
|
+
"aria-label": "Field name",
|
|
109
|
+
className: utils.cn(jsonSchemaFormUtils.inputClass(childCtx.size), "font-mono"),
|
|
110
|
+
value: key,
|
|
111
|
+
disabled: readOnly,
|
|
112
|
+
onChange: (e) => renameEntry(key, e.target.value)
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
const removeButton = !readOnly ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
116
|
+
"button",
|
|
117
|
+
{
|
|
118
|
+
type: "button",
|
|
119
|
+
"aria-label": `Remove ${key}`,
|
|
120
|
+
className: "inline-flex h-8 w-8 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
121
|
+
onClick: () => removeEntry(key),
|
|
122
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiTrash.UiTrash, className: "text-sm" })
|
|
123
|
+
}
|
|
124
|
+
) : null;
|
|
125
|
+
if (entryIsStacked(key)) {
|
|
126
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5 rounded-md border border-input p-2", children: [
|
|
127
|
+
keyTitle && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs font-medium text-muted-foreground", children: keyTitle }),
|
|
128
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
129
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: keyControl }),
|
|
130
|
+
removeButton
|
|
131
|
+
] }),
|
|
132
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children: valueControlForKey(key) })
|
|
133
|
+
] }, `extra-${key}`);
|
|
134
|
+
}
|
|
135
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[10rem_1fr_auto] items-center gap-2", children: [
|
|
136
|
+
keyControl,
|
|
137
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0", children: valueControlForKey(key) }),
|
|
138
|
+
removeButton
|
|
139
|
+
] }, `extra-${key}`);
|
|
140
|
+
}),
|
|
141
|
+
!readOnly && field.allowExtraKeys !== false && /* @__PURE__ */ jsxRuntime.jsxs(button.Button, { type: "button", variant: "outline", size: "sm", onClick: addEntry, className: "gap-1.5", children: [
|
|
142
|
+
/* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiAdd.UiAdd, className: "text-sm" }),
|
|
143
|
+
"Add field"
|
|
144
|
+
] })
|
|
145
|
+
] });
|
|
146
|
+
}
|
|
147
|
+
exports.ObjectControl = ObjectControl;
|
|
148
|
+
exports.StringMapControl = StringMapControl;
|
|
149
|
+
//# sourceMappingURL=json-schema-form-object.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema-form-object.cjs","sources":["../../src/components/json-schema-form-object.tsx"],"sourcesContent":["import { type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiAdd, UiTrash } from \"../icons\";\nimport { Button } from \"./button\";\nimport { Combobox } from \"./Combobox\";\nimport type {\n FieldControl,\n JsonSchemaObject,\n JsonSchemaProperty,\n RenderContext,\n} from \"./json-schema-form-types\";\nimport {\n fieldInputId,\n inputClass,\n isPlainObject,\n keyPickerOptions,\n} from \"./json-schema-form-utils\";\nimport { FieldsGrid } from \"./json-schema-form-fields\";\nimport { fieldInnerGapClass } from \"./json-schema-form-size\";\n\n// ObjectControl renders a nested structured object as a sub-form: its own\n// properties, required markers, if/then, soft errors — all via the shared\n// recursive renderer (ctx.render), so pre/post extensions apply at this depth too.\nexport function ObjectControl({ field, ctx }: { field: FieldControl; ctx: RenderContext }) {\n const obj = isPlainObject(field.value) ? (field.value as Record<string, unknown>) : {};\n const subSchema: JsonSchemaObject = {\n type: \"object\",\n properties: field.objectProperties ?? {},\n ...(field.objectRequired ? { required: field.objectRequired } : {}),\n ...(Array.isArray(field.schema.allOf) ? { allOf: field.schema.allOf } : {}),\n ...(Array.isArray(field.schema[\"x-order\"]) ? { \"x-order\": field.schema[\"x-order\"] } : {}),\n };\n // No border/box: nested objects render as flat headed sections (see\n // ObjectSection in renderFieldRow) rather than progressively indented\n // sub-forms, so deep schemas stay readable as a single column.\n // A read-only object marks its whole subtree non-editable: recurse with\n // form-level readOnly on so child inputs are disabled (and any child the\n // schema marks readOnly still renders as a value span).\n return (\n <FieldsGrid layout={ctx.layout} size={ctx.size}>\n {ctx.render.renderObjectFields(subSchema, obj, (next) => field.onChange(next), {\n ...ctx,\n readOnly: ctx.readOnly || field.readOnly === true,\n depth: ctx.depth + 1,\n })}\n </FieldsGrid>\n );\n}\n\n// StringMapControl edits an object as key/value rows. Known properties (from the\n// schema) render first with derived value controls; unknown keys render as\n// editable key/value pairs. \"Add field\" appears when extra keys are allowed.\n// Values recurse through the shared pipeline, so a value that is itself an object\n// or array renders structurally and pre/post extensions apply to it.\nexport function StringMapControl({ field, ctx }: { field: FieldControl; ctx: RenderContext }) {\n // A read-only map marks its whole subtree non-editable: no rename/remove/add\n // and value inputs disabled.\n const readOnly = ctx.readOnly || field.readOnly === true;\n const map = isPlainObject(field.value) ? (field.value as Record<string, unknown>) : {};\n const known = field.knownProperties ?? {};\n const knownKeys = Object.keys(known);\n const extraKeys = Object.keys(map).filter((k) => !(k in known));\n const childCtx: RenderContext = { ...ctx, readOnly, depth: ctx.depth + 1 };\n // What the map key IS (e.g. \"Address Role\"), from the key-constraint schema.\n const pn = field.schema.propertyNames as JsonSchemaProperty | undefined;\n const keyTitle = typeof pn?.title === \"string\" && pn.title ? pn.title : undefined;\n\n // valueSchemaForKey picks an entry's value schema: the first patternProperties\n // entry whose regex matches the key, else the `additionalProperties` schema,\n // else a bare string. Lets the value form vary by key (e.g. House vs Apartment).\n function valueSchemaForKey(key: string): JsonSchemaProperty {\n for (const { pattern, schema } of field.valuePatternSchemas ?? []) {\n let re: RegExp | undefined;\n try {\n re = new RegExp(pattern);\n } catch {\n re = undefined; // a malformed pattern simply never matches\n }\n if (re?.test(key)) return schema;\n }\n return field.valueSchema ?? { type: \"string\" };\n }\n\n // When the entry value opts into a stacked layout (`x-layout: \"stack\"`), the\n // key+value render as one full-width stacked unit instead of a key column\n // beside the value. Resolved per key, since pattern schemas may differ.\n function entryIsStacked(key: string): boolean {\n return valueSchemaForKey(key)[\"x-layout\"] === \"stack\";\n }\n\n function setEntry(key: string, next: unknown) {\n field.onChange({ ...map, [key]: next });\n }\n function renameEntry(oldKey: string, newKey: string) {\n if (newKey === oldKey) return;\n const next: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(map)) next[k === oldKey ? newKey : k] = v;\n field.onChange(next);\n }\n function removeEntry(key: string) {\n const next = { ...map };\n delete next[key];\n field.onChange(next);\n }\n function addEntry() {\n if (\"\" in map) return;\n field.onChange({ ...map, \"\": \"\" });\n }\n\n function valueControlFor(key: string, valueSchema: JsonSchemaProperty): ReactNode {\n const nodes = ctx.render.renderFieldNodes(\n {\n key,\n prop: valueSchema,\n required: false,\n value: map[key] ?? \"\",\n onChange: (next) => setEntry(key, next),\n },\n childCtx,\n );\n return nodes?.value ?? null;\n }\n\n // valueControlForKey resolves the per-key value schema (patternProperties /\n // additionalProperties) before rendering, so the form varies by key.\n function valueControlForKey(key: string): ReactNode {\n return valueControlFor(key, valueSchemaForKey(key));\n }\n\n return (\n <div className={cn(\"flex flex-col rounded-md border border-input p-2\", fieldInnerGapClass[childCtx.size])}>\n {knownKeys.map((key) => (\n <div key={`known-${key}`} className=\"grid grid-cols-[10rem_1fr] items-center gap-2\">\n <label htmlFor={fieldInputId(key, childCtx.idPrefix)} className=\"truncate text-xs text-muted-foreground\" title={key}>\n {key}\n </label>\n <div className=\"min-w-0\">{valueControlFor(key, known[key] ?? { type: \"string\" })}</div>\n </div>\n ))}\n {extraKeys.map((key) => {\n const keyControl = field.keyOptions ? (\n <Combobox\n options={keyPickerOptions(field.keyOptions, extraKeys, key)}\n value={key}\n disabled={readOnly}\n size={childCtx.size}\n allowCustomValue={false}\n onChange={(next) => renameEntry(key, next)}\n placeholder=\"Select…\"\n />\n ) : (\n <input\n type=\"text\"\n aria-label=\"Field name\"\n className={cn(inputClass(childCtx.size), \"font-mono\")}\n value={key}\n disabled={readOnly}\n onChange={(e) => renameEntry(key, e.target.value)}\n />\n );\n const removeButton = !readOnly ? (\n <button\n type=\"button\"\n aria-label={`Remove ${key}`}\n className=\"inline-flex h-8 w-8 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground\"\n onClick={() => removeEntry(key)}\n >\n <Icon icon={UiTrash} className=\"text-sm\" />\n </button>\n ) : null;\n // When the value is stacked (`x-layout: \"stack\"` on the entry schema),\n // the key joins the stack: it sits full-width above its value as one\n // unit, rather than cramped in a fixed key column beside it. The key\n // picker is labelled from `propertyNames.title` so a constrained key\n // (e.g. an AsCode role) says what it is.\n if (entryIsStacked(key)) {\n return (\n <div key={`extra-${key}`} className=\"space-y-1.5 rounded-md border border-input p-2\">\n {keyTitle && (\n <span className=\"block text-xs font-medium text-muted-foreground\">{keyTitle}</span>\n )}\n <div className=\"flex items-center gap-2\">\n <div className=\"min-w-0 flex-1\">{keyControl}</div>\n {removeButton}\n </div>\n <div className=\"min-w-0\">{valueControlForKey(key)}</div>\n </div>\n );\n }\n return (\n <div key={`extra-${key}`} className=\"grid grid-cols-[10rem_1fr_auto] items-center gap-2\">\n {keyControl}\n <div className=\"min-w-0\">{valueControlForKey(key)}</div>\n {removeButton}\n </div>\n );\n })}\n {!readOnly && field.allowExtraKeys !== false && (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addEntry} className=\"gap-1.5\">\n <Icon icon={UiAdd} className=\"text-sm\" />\n Add field\n </Button>\n )}\n </div>\n );\n}\n"],"names":["isPlainObject","FieldsGrid","jsxs","cn","fieldInnerGapClass","jsx","fieldInputId","Combobox","keyPickerOptions","inputClass","Icon","UiTrash","Button","UiAdd"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FieldControl, RenderContext } from './json-schema-form-types';
|
|
2
|
+
export declare function ObjectControl({ field, ctx }: {
|
|
3
|
+
field: FieldControl;
|
|
4
|
+
ctx: RenderContext;
|
|
5
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export declare function StringMapControl({ field, ctx }: {
|
|
7
|
+
field: FieldControl;
|
|
8
|
+
ctx: RenderContext;
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=json-schema-form-object.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema-form-object.d.ts","sourceRoot":"","sources":["../../src/components/json-schema-form-object.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,YAAY,EAGZ,aAAa,EACd,MAAM,0BAA0B,CAAC;AAalC,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,GAAG,EAAE,aAAa,CAAA;CAAE,2CAwBxF;AAOD,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;IAAE,KAAK,EAAE,YAAY,CAAC;IAAC,GAAG,EAAE,aAAa,CAAA;CAAE,2CAuJ3F"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import "react";
|
|
3
|
+
import { cn } from "../lib/utils.js";
|
|
4
|
+
import { Icon } from "../data/Icon.js";
|
|
5
|
+
import { Button } from "./button.js";
|
|
6
|
+
import { Combobox } from "./Combobox.js";
|
|
7
|
+
import { isPlainObject, fieldInputId, keyPickerOptions, inputClass } from "./json-schema-form-utils.js";
|
|
8
|
+
import { FieldsGrid } from "./json-schema-form-fields.js";
|
|
9
|
+
import { fieldInnerGapClass } from "./json-schema-form-size.js";
|
|
10
|
+
import { UiAdd } from "../icons/components/UiAdd.js";
|
|
11
|
+
import { UiTrash } from "../icons/components/UiTrash.js";
|
|
12
|
+
function ObjectControl({ field, ctx }) {
|
|
13
|
+
const obj = isPlainObject(field.value) ? field.value : {};
|
|
14
|
+
const subSchema = {
|
|
15
|
+
type: "object",
|
|
16
|
+
properties: field.objectProperties ?? {},
|
|
17
|
+
...field.objectRequired ? { required: field.objectRequired } : {},
|
|
18
|
+
...Array.isArray(field.schema.allOf) ? { allOf: field.schema.allOf } : {},
|
|
19
|
+
...Array.isArray(field.schema["x-order"]) ? { "x-order": field.schema["x-order"] } : {}
|
|
20
|
+
};
|
|
21
|
+
return /* @__PURE__ */ jsx(FieldsGrid, { layout: ctx.layout, size: ctx.size, children: ctx.render.renderObjectFields(subSchema, obj, (next) => field.onChange(next), {
|
|
22
|
+
...ctx,
|
|
23
|
+
readOnly: ctx.readOnly || field.readOnly === true,
|
|
24
|
+
depth: ctx.depth + 1
|
|
25
|
+
}) });
|
|
26
|
+
}
|
|
27
|
+
function StringMapControl({ field, ctx }) {
|
|
28
|
+
const readOnly = ctx.readOnly || field.readOnly === true;
|
|
29
|
+
const map = isPlainObject(field.value) ? field.value : {};
|
|
30
|
+
const known = field.knownProperties ?? {};
|
|
31
|
+
const knownKeys = Object.keys(known);
|
|
32
|
+
const extraKeys = Object.keys(map).filter((k) => !(k in known));
|
|
33
|
+
const childCtx = { ...ctx, readOnly, depth: ctx.depth + 1 };
|
|
34
|
+
const pn = field.schema.propertyNames;
|
|
35
|
+
const keyTitle = typeof (pn == null ? void 0 : pn.title) === "string" && pn.title ? pn.title : void 0;
|
|
36
|
+
function valueSchemaForKey(key) {
|
|
37
|
+
for (const { pattern, schema } of field.valuePatternSchemas ?? []) {
|
|
38
|
+
let re;
|
|
39
|
+
try {
|
|
40
|
+
re = new RegExp(pattern);
|
|
41
|
+
} catch {
|
|
42
|
+
re = void 0;
|
|
43
|
+
}
|
|
44
|
+
if (re == null ? void 0 : re.test(key)) return schema;
|
|
45
|
+
}
|
|
46
|
+
return field.valueSchema ?? { type: "string" };
|
|
47
|
+
}
|
|
48
|
+
function entryIsStacked(key) {
|
|
49
|
+
return valueSchemaForKey(key)["x-layout"] === "stack";
|
|
50
|
+
}
|
|
51
|
+
function setEntry(key, next) {
|
|
52
|
+
field.onChange({ ...map, [key]: next });
|
|
53
|
+
}
|
|
54
|
+
function renameEntry(oldKey, newKey) {
|
|
55
|
+
if (newKey === oldKey) return;
|
|
56
|
+
const next = {};
|
|
57
|
+
for (const [k, v] of Object.entries(map)) next[k === oldKey ? newKey : k] = v;
|
|
58
|
+
field.onChange(next);
|
|
59
|
+
}
|
|
60
|
+
function removeEntry(key) {
|
|
61
|
+
const next = { ...map };
|
|
62
|
+
delete next[key];
|
|
63
|
+
field.onChange(next);
|
|
64
|
+
}
|
|
65
|
+
function addEntry() {
|
|
66
|
+
if ("" in map) return;
|
|
67
|
+
field.onChange({ ...map, "": "" });
|
|
68
|
+
}
|
|
69
|
+
function valueControlFor(key, valueSchema) {
|
|
70
|
+
const nodes = ctx.render.renderFieldNodes(
|
|
71
|
+
{
|
|
72
|
+
key,
|
|
73
|
+
prop: valueSchema,
|
|
74
|
+
required: false,
|
|
75
|
+
value: map[key] ?? "",
|
|
76
|
+
onChange: (next) => setEntry(key, next)
|
|
77
|
+
},
|
|
78
|
+
childCtx
|
|
79
|
+
);
|
|
80
|
+
return (nodes == null ? void 0 : nodes.value) ?? null;
|
|
81
|
+
}
|
|
82
|
+
function valueControlForKey(key) {
|
|
83
|
+
return valueControlFor(key, valueSchemaForKey(key));
|
|
84
|
+
}
|
|
85
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col rounded-md border border-input p-2", fieldInnerGapClass[childCtx.size]), children: [
|
|
86
|
+
knownKeys.map((key) => /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[10rem_1fr] items-center gap-2", children: [
|
|
87
|
+
/* @__PURE__ */ jsx("label", { htmlFor: fieldInputId(key, childCtx.idPrefix), className: "truncate text-xs text-muted-foreground", title: key, children: key }),
|
|
88
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0", children: valueControlFor(key, known[key] ?? { type: "string" }) })
|
|
89
|
+
] }, `known-${key}`)),
|
|
90
|
+
extraKeys.map((key) => {
|
|
91
|
+
const keyControl = field.keyOptions ? /* @__PURE__ */ jsx(
|
|
92
|
+
Combobox,
|
|
93
|
+
{
|
|
94
|
+
options: keyPickerOptions(field.keyOptions, extraKeys, key),
|
|
95
|
+
value: key,
|
|
96
|
+
disabled: readOnly,
|
|
97
|
+
size: childCtx.size,
|
|
98
|
+
allowCustomValue: false,
|
|
99
|
+
onChange: (next) => renameEntry(key, next),
|
|
100
|
+
placeholder: "Select…"
|
|
101
|
+
}
|
|
102
|
+
) : /* @__PURE__ */ jsx(
|
|
103
|
+
"input",
|
|
104
|
+
{
|
|
105
|
+
type: "text",
|
|
106
|
+
"aria-label": "Field name",
|
|
107
|
+
className: cn(inputClass(childCtx.size), "font-mono"),
|
|
108
|
+
value: key,
|
|
109
|
+
disabled: readOnly,
|
|
110
|
+
onChange: (e) => renameEntry(key, e.target.value)
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
const removeButton = !readOnly ? /* @__PURE__ */ jsx(
|
|
114
|
+
"button",
|
|
115
|
+
{
|
|
116
|
+
type: "button",
|
|
117
|
+
"aria-label": `Remove ${key}`,
|
|
118
|
+
className: "inline-flex h-8 w-8 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground",
|
|
119
|
+
onClick: () => removeEntry(key),
|
|
120
|
+
children: /* @__PURE__ */ jsx(Icon, { icon: UiTrash, className: "text-sm" })
|
|
121
|
+
}
|
|
122
|
+
) : null;
|
|
123
|
+
if (entryIsStacked(key)) {
|
|
124
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5 rounded-md border border-input p-2", children: [
|
|
125
|
+
keyTitle && /* @__PURE__ */ jsx("span", { className: "block text-xs font-medium text-muted-foreground", children: keyTitle }),
|
|
126
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
127
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: keyControl }),
|
|
128
|
+
removeButton
|
|
129
|
+
] }),
|
|
130
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0", children: valueControlForKey(key) })
|
|
131
|
+
] }, `extra-${key}`);
|
|
132
|
+
}
|
|
133
|
+
return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[10rem_1fr_auto] items-center gap-2", children: [
|
|
134
|
+
keyControl,
|
|
135
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0", children: valueControlForKey(key) }),
|
|
136
|
+
removeButton
|
|
137
|
+
] }, `extra-${key}`);
|
|
138
|
+
}),
|
|
139
|
+
!readOnly && field.allowExtraKeys !== false && /* @__PURE__ */ jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: addEntry, className: "gap-1.5", children: [
|
|
140
|
+
/* @__PURE__ */ jsx(Icon, { icon: UiAdd, className: "text-sm" }),
|
|
141
|
+
"Add field"
|
|
142
|
+
] })
|
|
143
|
+
] });
|
|
144
|
+
}
|
|
145
|
+
export {
|
|
146
|
+
ObjectControl,
|
|
147
|
+
StringMapControl
|
|
148
|
+
};
|
|
149
|
+
//# sourceMappingURL=json-schema-form-object.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema-form-object.js","sources":["../../src/components/json-schema-form-object.tsx"],"sourcesContent":["import { type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { Icon } from \"../data/Icon\";\nimport { UiAdd, UiTrash } from \"../icons\";\nimport { Button } from \"./button\";\nimport { Combobox } from \"./Combobox\";\nimport type {\n FieldControl,\n JsonSchemaObject,\n JsonSchemaProperty,\n RenderContext,\n} from \"./json-schema-form-types\";\nimport {\n fieldInputId,\n inputClass,\n isPlainObject,\n keyPickerOptions,\n} from \"./json-schema-form-utils\";\nimport { FieldsGrid } from \"./json-schema-form-fields\";\nimport { fieldInnerGapClass } from \"./json-schema-form-size\";\n\n// ObjectControl renders a nested structured object as a sub-form: its own\n// properties, required markers, if/then, soft errors — all via the shared\n// recursive renderer (ctx.render), so pre/post extensions apply at this depth too.\nexport function ObjectControl({ field, ctx }: { field: FieldControl; ctx: RenderContext }) {\n const obj = isPlainObject(field.value) ? (field.value as Record<string, unknown>) : {};\n const subSchema: JsonSchemaObject = {\n type: \"object\",\n properties: field.objectProperties ?? {},\n ...(field.objectRequired ? { required: field.objectRequired } : {}),\n ...(Array.isArray(field.schema.allOf) ? { allOf: field.schema.allOf } : {}),\n ...(Array.isArray(field.schema[\"x-order\"]) ? { \"x-order\": field.schema[\"x-order\"] } : {}),\n };\n // No border/box: nested objects render as flat headed sections (see\n // ObjectSection in renderFieldRow) rather than progressively indented\n // sub-forms, so deep schemas stay readable as a single column.\n // A read-only object marks its whole subtree non-editable: recurse with\n // form-level readOnly on so child inputs are disabled (and any child the\n // schema marks readOnly still renders as a value span).\n return (\n <FieldsGrid layout={ctx.layout} size={ctx.size}>\n {ctx.render.renderObjectFields(subSchema, obj, (next) => field.onChange(next), {\n ...ctx,\n readOnly: ctx.readOnly || field.readOnly === true,\n depth: ctx.depth + 1,\n })}\n </FieldsGrid>\n );\n}\n\n// StringMapControl edits an object as key/value rows. Known properties (from the\n// schema) render first with derived value controls; unknown keys render as\n// editable key/value pairs. \"Add field\" appears when extra keys are allowed.\n// Values recurse through the shared pipeline, so a value that is itself an object\n// or array renders structurally and pre/post extensions apply to it.\nexport function StringMapControl({ field, ctx }: { field: FieldControl; ctx: RenderContext }) {\n // A read-only map marks its whole subtree non-editable: no rename/remove/add\n // and value inputs disabled.\n const readOnly = ctx.readOnly || field.readOnly === true;\n const map = isPlainObject(field.value) ? (field.value as Record<string, unknown>) : {};\n const known = field.knownProperties ?? {};\n const knownKeys = Object.keys(known);\n const extraKeys = Object.keys(map).filter((k) => !(k in known));\n const childCtx: RenderContext = { ...ctx, readOnly, depth: ctx.depth + 1 };\n // What the map key IS (e.g. \"Address Role\"), from the key-constraint schema.\n const pn = field.schema.propertyNames as JsonSchemaProperty | undefined;\n const keyTitle = typeof pn?.title === \"string\" && pn.title ? pn.title : undefined;\n\n // valueSchemaForKey picks an entry's value schema: the first patternProperties\n // entry whose regex matches the key, else the `additionalProperties` schema,\n // else a bare string. Lets the value form vary by key (e.g. House vs Apartment).\n function valueSchemaForKey(key: string): JsonSchemaProperty {\n for (const { pattern, schema } of field.valuePatternSchemas ?? []) {\n let re: RegExp | undefined;\n try {\n re = new RegExp(pattern);\n } catch {\n re = undefined; // a malformed pattern simply never matches\n }\n if (re?.test(key)) return schema;\n }\n return field.valueSchema ?? { type: \"string\" };\n }\n\n // When the entry value opts into a stacked layout (`x-layout: \"stack\"`), the\n // key+value render as one full-width stacked unit instead of a key column\n // beside the value. Resolved per key, since pattern schemas may differ.\n function entryIsStacked(key: string): boolean {\n return valueSchemaForKey(key)[\"x-layout\"] === \"stack\";\n }\n\n function setEntry(key: string, next: unknown) {\n field.onChange({ ...map, [key]: next });\n }\n function renameEntry(oldKey: string, newKey: string) {\n if (newKey === oldKey) return;\n const next: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(map)) next[k === oldKey ? newKey : k] = v;\n field.onChange(next);\n }\n function removeEntry(key: string) {\n const next = { ...map };\n delete next[key];\n field.onChange(next);\n }\n function addEntry() {\n if (\"\" in map) return;\n field.onChange({ ...map, \"\": \"\" });\n }\n\n function valueControlFor(key: string, valueSchema: JsonSchemaProperty): ReactNode {\n const nodes = ctx.render.renderFieldNodes(\n {\n key,\n prop: valueSchema,\n required: false,\n value: map[key] ?? \"\",\n onChange: (next) => setEntry(key, next),\n },\n childCtx,\n );\n return nodes?.value ?? null;\n }\n\n // valueControlForKey resolves the per-key value schema (patternProperties /\n // additionalProperties) before rendering, so the form varies by key.\n function valueControlForKey(key: string): ReactNode {\n return valueControlFor(key, valueSchemaForKey(key));\n }\n\n return (\n <div className={cn(\"flex flex-col rounded-md border border-input p-2\", fieldInnerGapClass[childCtx.size])}>\n {knownKeys.map((key) => (\n <div key={`known-${key}`} className=\"grid grid-cols-[10rem_1fr] items-center gap-2\">\n <label htmlFor={fieldInputId(key, childCtx.idPrefix)} className=\"truncate text-xs text-muted-foreground\" title={key}>\n {key}\n </label>\n <div className=\"min-w-0\">{valueControlFor(key, known[key] ?? { type: \"string\" })}</div>\n </div>\n ))}\n {extraKeys.map((key) => {\n const keyControl = field.keyOptions ? (\n <Combobox\n options={keyPickerOptions(field.keyOptions, extraKeys, key)}\n value={key}\n disabled={readOnly}\n size={childCtx.size}\n allowCustomValue={false}\n onChange={(next) => renameEntry(key, next)}\n placeholder=\"Select…\"\n />\n ) : (\n <input\n type=\"text\"\n aria-label=\"Field name\"\n className={cn(inputClass(childCtx.size), \"font-mono\")}\n value={key}\n disabled={readOnly}\n onChange={(e) => renameEntry(key, e.target.value)}\n />\n );\n const removeButton = !readOnly ? (\n <button\n type=\"button\"\n aria-label={`Remove ${key}`}\n className=\"inline-flex h-8 w-8 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-accent hover:text-foreground\"\n onClick={() => removeEntry(key)}\n >\n <Icon icon={UiTrash} className=\"text-sm\" />\n </button>\n ) : null;\n // When the value is stacked (`x-layout: \"stack\"` on the entry schema),\n // the key joins the stack: it sits full-width above its value as one\n // unit, rather than cramped in a fixed key column beside it. The key\n // picker is labelled from `propertyNames.title` so a constrained key\n // (e.g. an AsCode role) says what it is.\n if (entryIsStacked(key)) {\n return (\n <div key={`extra-${key}`} className=\"space-y-1.5 rounded-md border border-input p-2\">\n {keyTitle && (\n <span className=\"block text-xs font-medium text-muted-foreground\">{keyTitle}</span>\n )}\n <div className=\"flex items-center gap-2\">\n <div className=\"min-w-0 flex-1\">{keyControl}</div>\n {removeButton}\n </div>\n <div className=\"min-w-0\">{valueControlForKey(key)}</div>\n </div>\n );\n }\n return (\n <div key={`extra-${key}`} className=\"grid grid-cols-[10rem_1fr_auto] items-center gap-2\">\n {keyControl}\n <div className=\"min-w-0\">{valueControlForKey(key)}</div>\n {removeButton}\n </div>\n );\n })}\n {!readOnly && field.allowExtraKeys !== false && (\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addEntry} className=\"gap-1.5\">\n <Icon icon={UiAdd} className=\"text-sm\" />\n Add field\n </Button>\n )}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const DEFAULT_PREFERENCES_STORAGE_KEY = "clicky-ui-json-schema-form-preferences";
|
|
4
|
+
const VALID_SIZES = ["xs", "sm", "md", "lg", "xl"];
|
|
5
|
+
function isFormSize(value) {
|
|
6
|
+
return typeof value === "string" && VALID_SIZES.includes(value);
|
|
7
|
+
}
|
|
8
|
+
function isLayoutMode(value) {
|
|
9
|
+
return value === "stacked" || value === "inline";
|
|
10
|
+
}
|
|
11
|
+
function readPreferences(storageKey) {
|
|
12
|
+
let raw;
|
|
13
|
+
try {
|
|
14
|
+
raw = localStorage.getItem(storageKey);
|
|
15
|
+
} catch {
|
|
16
|
+
return {};
|
|
17
|
+
}
|
|
18
|
+
if (!raw) return {};
|
|
19
|
+
let parsed;
|
|
20
|
+
try {
|
|
21
|
+
parsed = JSON.parse(raw);
|
|
22
|
+
} catch {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
if (typeof parsed !== "object" || parsed === null) return {};
|
|
26
|
+
const record = parsed;
|
|
27
|
+
const prefs = {};
|
|
28
|
+
if (isFormSize(record.size)) prefs.size = record.size;
|
|
29
|
+
if (isLayoutMode(record.layoutMode)) prefs.layoutMode = record.layoutMode;
|
|
30
|
+
return prefs;
|
|
31
|
+
}
|
|
32
|
+
function writePreferences(storageKey, prefs) {
|
|
33
|
+
try {
|
|
34
|
+
localStorage.setItem(storageKey, JSON.stringify(prefs));
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.DEFAULT_PREFERENCES_STORAGE_KEY = DEFAULT_PREFERENCES_STORAGE_KEY;
|
|
39
|
+
exports.readPreferences = readPreferences;
|
|
40
|
+
exports.writePreferences = writePreferences;
|
|
41
|
+
//# sourceMappingURL=json-schema-form-preferences.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema-form-preferences.cjs","sources":["../../src/components/json-schema-form-preferences.ts"],"sourcesContent":["import type { FormSize } from \"./json-schema-form-size\";\n\n// FormPreferences are the form-local appearance overrides the display-options\n// menu persists: the input/label scale and the layout mode. They never touch\n// field values or the global page density — only how one form looks.\nexport interface FormPreferences {\n size?: FormSize;\n layoutMode?: LayoutMode;\n}\n\nexport type LayoutMode = \"stacked\" | \"inline\";\n\nexport const DEFAULT_PREFERENCES_STORAGE_KEY = \"clicky-ui-json-schema-form-preferences\";\n\nconst VALID_SIZES: readonly string[] = [\"xs\", \"sm\", \"md\", \"lg\", \"xl\"];\n\nfunction isFormSize(value: unknown): value is FormSize {\n return typeof value === \"string\" && VALID_SIZES.includes(value);\n}\n\nfunction isLayoutMode(value: unknown): value is LayoutMode {\n return value === \"stacked\" || value === \"inline\";\n}\n\n// readPreferences loads stored preferences, tolerating anything malformed: a\n// missing key, invalid JSON, a non-object payload, out-of-range values, or a\n// localStorage that throws (private mode / storage disabled). Each field is\n// validated independently so one bad value doesn't discard the whole record.\n// Display preferences are best-effort, so a read failure yields {} rather than\n// an error — the form falls back to its props.\nexport function readPreferences(storageKey: string): FormPreferences {\n let raw: string | null;\n try {\n raw = localStorage.getItem(storageKey);\n } catch {\n return {};\n }\n if (!raw) return {};\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return {};\n }\n if (typeof parsed !== \"object\" || parsed === null) return {};\n\n const record = parsed as Record<string, unknown>;\n const prefs: FormPreferences = {};\n if (isFormSize(record.size)) prefs.size = record.size;\n if (isLayoutMode(record.layoutMode)) prefs.layoutMode = record.layoutMode;\n return prefs;\n}\n\n// writePreferences persists the record as JSON, swallowing localStorage errors\n// (quota exceeded / storage disabled). Like reads, persistence is best-effort:\n// failing to save a display preference must never break the form.\nexport function writePreferences(storageKey: string, prefs: FormPreferences): void {\n try {\n localStorage.setItem(storageKey, JSON.stringify(prefs));\n } catch {\n // Best-effort persistence; ignore storage failures.\n }\n}\n"],"names":[],"mappings":";;AAYO,MAAM,kCAAkC;AAE/C,MAAM,cAAiC,CAAC,MAAM,MAAM,MAAM,MAAM,IAAI;AAEpE,SAAS,WAAW,OAAmC;AACrD,SAAO,OAAO,UAAU,YAAY,YAAY,SAAS,KAAK;AAChE;AAEA,SAAS,aAAa,OAAqC;AACzD,SAAO,UAAU,aAAa,UAAU;AAC1C;AAQO,SAAS,gBAAgB,YAAqC;AACnE,MAAI;AACJ,MAAI;AACF,UAAM,aAAa,QAAQ,UAAU;AAAA,EACvC,QAAQ;AACN,WAAO,CAAA;AAAA,EACT;AACA,MAAI,CAAC,IAAK,QAAO,CAAA;AAEjB,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,GAAG;AAAA,EACzB,QAAQ;AACN,WAAO,CAAA;AAAA,EACT;AACA,MAAI,OAAO,WAAW,YAAY,WAAW,aAAa,CAAA;AAE1D,QAAM,SAAS;AACf,QAAM,QAAyB,CAAA;AAC/B,MAAI,WAAW,OAAO,IAAI,EAAG,OAAM,OAAO,OAAO;AACjD,MAAI,aAAa,OAAO,UAAU,EAAG,OAAM,aAAa,OAAO;AAC/D,SAAO;AACT;AAKO,SAAS,iBAAiB,YAAoB,OAA8B;AACjF,MAAI;AACF,iBAAa,QAAQ,YAAY,KAAK,UAAU,KAAK,CAAC;AAAA,EACxD,QAAQ;AAAA,EAER;AACF;;;;"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { FormSize } from './json-schema-form-size';
|
|
2
|
+
export interface FormPreferences {
|
|
3
|
+
size?: FormSize;
|
|
4
|
+
layoutMode?: LayoutMode;
|
|
5
|
+
}
|
|
6
|
+
export type LayoutMode = "stacked" | "inline";
|
|
7
|
+
export declare const DEFAULT_PREFERENCES_STORAGE_KEY = "clicky-ui-json-schema-form-preferences";
|
|
8
|
+
export declare function readPreferences(storageKey: string): FormPreferences;
|
|
9
|
+
export declare function writePreferences(storageKey: string, prefs: FormPreferences): void;
|
|
10
|
+
//# sourceMappingURL=json-schema-form-preferences.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema-form-preferences.d.ts","sourceRoot":"","sources":["../../src/components/json-schema-form-preferences.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAKxD,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE9C,eAAO,MAAM,+BAA+B,2CAA2C,CAAC;AAkBxF,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAsBnE;AAKD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CAMjF"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const DEFAULT_PREFERENCES_STORAGE_KEY = "clicky-ui-json-schema-form-preferences";
|
|
2
|
+
const VALID_SIZES = ["xs", "sm", "md", "lg", "xl"];
|
|
3
|
+
function isFormSize(value) {
|
|
4
|
+
return typeof value === "string" && VALID_SIZES.includes(value);
|
|
5
|
+
}
|
|
6
|
+
function isLayoutMode(value) {
|
|
7
|
+
return value === "stacked" || value === "inline";
|
|
8
|
+
}
|
|
9
|
+
function readPreferences(storageKey) {
|
|
10
|
+
let raw;
|
|
11
|
+
try {
|
|
12
|
+
raw = localStorage.getItem(storageKey);
|
|
13
|
+
} catch {
|
|
14
|
+
return {};
|
|
15
|
+
}
|
|
16
|
+
if (!raw) return {};
|
|
17
|
+
let parsed;
|
|
18
|
+
try {
|
|
19
|
+
parsed = JSON.parse(raw);
|
|
20
|
+
} catch {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
if (typeof parsed !== "object" || parsed === null) return {};
|
|
24
|
+
const record = parsed;
|
|
25
|
+
const prefs = {};
|
|
26
|
+
if (isFormSize(record.size)) prefs.size = record.size;
|
|
27
|
+
if (isLayoutMode(record.layoutMode)) prefs.layoutMode = record.layoutMode;
|
|
28
|
+
return prefs;
|
|
29
|
+
}
|
|
30
|
+
function writePreferences(storageKey, prefs) {
|
|
31
|
+
try {
|
|
32
|
+
localStorage.setItem(storageKey, JSON.stringify(prefs));
|
|
33
|
+
} catch {
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
DEFAULT_PREFERENCES_STORAGE_KEY,
|
|
38
|
+
readPreferences,
|
|
39
|
+
writePreferences
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=json-schema-form-preferences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-schema-form-preferences.js","sources":["../../src/components/json-schema-form-preferences.ts"],"sourcesContent":["import type { FormSize } from \"./json-schema-form-size\";\n\n// FormPreferences are the form-local appearance overrides the display-options\n// menu persists: the input/label scale and the layout mode. They never touch\n// field values or the global page density — only how one form looks.\nexport interface FormPreferences {\n size?: FormSize;\n layoutMode?: LayoutMode;\n}\n\nexport type LayoutMode = \"stacked\" | \"inline\";\n\nexport const DEFAULT_PREFERENCES_STORAGE_KEY = \"clicky-ui-json-schema-form-preferences\";\n\nconst VALID_SIZES: readonly string[] = [\"xs\", \"sm\", \"md\", \"lg\", \"xl\"];\n\nfunction isFormSize(value: unknown): value is FormSize {\n return typeof value === \"string\" && VALID_SIZES.includes(value);\n}\n\nfunction isLayoutMode(value: unknown): value is LayoutMode {\n return value === \"stacked\" || value === \"inline\";\n}\n\n// readPreferences loads stored preferences, tolerating anything malformed: a\n// missing key, invalid JSON, a non-object payload, out-of-range values, or a\n// localStorage that throws (private mode / storage disabled). Each field is\n// validated independently so one bad value doesn't discard the whole record.\n// Display preferences are best-effort, so a read failure yields {} rather than\n// an error — the form falls back to its props.\nexport function readPreferences(storageKey: string): FormPreferences {\n let raw: string | null;\n try {\n raw = localStorage.getItem(storageKey);\n } catch {\n return {};\n }\n if (!raw) return {};\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return {};\n }\n if (typeof parsed !== \"object\" || parsed === null) return {};\n\n const record = parsed as Record<string, unknown>;\n const prefs: FormPreferences = {};\n if (isFormSize(record.size)) prefs.size = record.size;\n if (isLayoutMode(record.layoutMode)) prefs.layoutMode = record.layoutMode;\n return prefs;\n}\n\n// writePreferences persists the record as JSON, swallowing localStorage errors\n// (quota exceeded / storage disabled). Like reads, persistence is best-effort:\n// failing to save a display preference must never break the form.\nexport function writePreferences(storageKey: string, prefs: FormPreferences): void {\n try {\n localStorage.setItem(storageKey, JSON.stringify(prefs));\n } catch {\n // Best-effort persistence; ignore storage failures.\n }\n}\n"],"names":[],"mappings":"AAYO,MAAM,kCAAkC;AAE/C,MAAM,cAAiC,CAAC,MAAM,MAAM,MAAM,MAAM,IAAI;AAEpE,SAAS,WAAW,OAAmC;AACrD,SAAO,OAAO,UAAU,YAAY,YAAY,SAAS,KAAK;AAChE;AAEA,SAAS,aAAa,OAAqC;AACzD,SAAO,UAAU,aAAa,UAAU;AAC1C;AAQO,SAAS,gBAAgB,YAAqC;AACnE,MAAI;AACJ,MAAI;AACF,UAAM,aAAa,QAAQ,UAAU;AAAA,EACvC,QAAQ;AACN,WAAO,CAAA;AAAA,EACT;AACA,MAAI,CAAC,IAAK,QAAO,CAAA;AAEjB,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,GAAG;AAAA,EACzB,QAAQ;AACN,WAAO,CAAA;AAAA,EACT;AACA,MAAI,OAAO,WAAW,YAAY,WAAW,aAAa,CAAA;AAE1D,QAAM,SAAS;AACf,QAAM,QAAyB,CAAA;AAC/B,MAAI,WAAW,OAAO,IAAI,EAAG,OAAM,OAAO,OAAO;AACjD,MAAI,aAAa,OAAO,UAAU,EAAG,OAAM,aAAa,OAAO;AAC/D,SAAO;AACT;AAKO,SAAS,iBAAiB,YAAoB,OAA8B;AACjF,MAAI;AACF,iBAAa,QAAQ,YAAY,KAAK,UAAU,KAAK,CAAC;AAAA,EACxD,QAAQ;AAAA,EAER;AACF;"}
|