@stigmer/react 3.41.0 → 3.41.1-dev.20261003133619.g58ac1f23a411
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/access/ManageAccessButton.d.ts +1 -1
- package/access/ManageAccessButton.js +1 -1
- package/access/ManageAccessDialog.js +1 -1
- package/access/ManageAccessDialog.js.map +1 -1
- package/agent/AgentDetailView.d.ts.map +1 -1
- package/agent/AgentDetailView.js +2 -1
- package/agent/AgentDetailView.js.map +1 -1
- package/api-key/ApiKeyListPanel.d.ts.map +1 -1
- package/api-key/ApiKeyListPanel.js +2 -1
- package/api-key/ApiKeyListPanel.js.map +1 -1
- package/attachment/AttachmentImageLightbox.d.ts.map +1 -1
- package/attachment/AttachmentImageLightbox.js.map +1 -1
- package/billing/AutoRechargeCard.d.ts +3 -3
- package/billing/AutoRechargeCard.d.ts.map +1 -1
- package/billing/AutoRechargeCard.js +4 -4
- package/billing/AutoRechargeCard.js.map +1 -1
- package/billing/BillingSection.d.ts.map +1 -1
- package/billing/BillingSection.js +7 -6
- package/billing/BillingSection.js.map +1 -1
- package/billing/CreditLedgerTable.d.ts +3 -3
- package/billing/CreditLedgerTable.d.ts.map +1 -1
- package/billing/CreditLedgerTable.js +3 -3
- package/billing/CreditLedgerTable.js.map +1 -1
- package/billing/CreditPackGrid.d.ts +1 -1
- package/billing/CreditPackGrid.js +1 -1
- package/billing/PaymentMethodCard.d.ts +1 -1
- package/billing/PaymentMethodCard.js +1 -1
- package/billing/PlanSection.d.ts +3 -3
- package/billing/PlanSection.d.ts.map +1 -1
- package/billing/PlanSection.js +4 -3
- package/billing/PlanSection.js.map +1 -1
- package/billing/ProviderKeysSection.js +13 -13
- package/billing/ProviderKeysSection.js.map +1 -1
- package/billing/plan-features.js +1 -1
- package/billing/plan-features.js.map +1 -1
- package/billing/useBillingAccount.d.ts +4 -4
- package/billing/useBillingAccount.d.ts.map +1 -1
- package/billing/useBillingAccount.js +7 -7
- package/billing/useBillingAccount.js.map +1 -1
- package/billing/useBillingUsageReport.d.ts +4 -4
- package/billing/useBillingUsageReport.d.ts.map +1 -1
- package/billing/useBillingUsageReport.js +7 -7
- package/billing/useBillingUsageReport.js.map +1 -1
- package/billing/useChangePlan.d.ts +2 -2
- package/billing/useChangePlan.d.ts.map +1 -1
- package/billing/useChangePlan.js +4 -4
- package/billing/useChangePlan.js.map +1 -1
- package/billing/useCreateBillingPortalSession.d.ts +2 -2
- package/billing/useCreateBillingPortalSession.d.ts.map +1 -1
- package/billing/useCreateBillingPortalSession.js +3 -3
- package/billing/useCreateBillingPortalSession.js.map +1 -1
- package/billing/useCreateCheckoutSession.d.ts +2 -2
- package/billing/useCreateCheckoutSession.d.ts.map +1 -1
- package/billing/useCreateCheckoutSession.js +2 -2
- package/billing/useCreateCheckoutSession.js.map +1 -1
- package/billing/useCreatePaymentMethodSetupSession.d.ts +1 -1
- package/billing/useCreatePaymentMethodSetupSession.d.ts.map +1 -1
- package/billing/useCreatePaymentMethodSetupSession.js +2 -2
- package/billing/useCreatePaymentMethodSetupSession.js.map +1 -1
- package/billing/useCreditLedger.d.ts +4 -4
- package/billing/useCreditLedger.d.ts.map +1 -1
- package/billing/useCreditLedger.js +7 -7
- package/billing/useCreditLedger.js.map +1 -1
- package/billing/useCustomerModelPricing.d.ts +4 -4
- package/billing/useCustomerModelPricing.d.ts.map +1 -1
- package/billing/useCustomerModelPricing.js +6 -6
- package/billing/useCustomerModelPricing.js.map +1 -1
- package/billing/useEntitlements.d.ts +2 -2
- package/billing/useEntitlements.d.ts.map +1 -1
- package/billing/useEntitlements.js +4 -4
- package/billing/useEntitlements.js.map +1 -1
- package/billing/usePeriodEstimate.d.ts +1 -1
- package/billing/usePeriodEstimate.d.ts.map +1 -1
- package/billing/usePeriodEstimate.js +3 -3
- package/billing/usePeriodEstimate.js.map +1 -1
- package/billing/useProviderKeys.d.ts +5 -5
- package/billing/useProviderKeys.d.ts.map +1 -1
- package/billing/useProviderKeys.js +7 -7
- package/billing/useProviderKeys.js.map +1 -1
- package/billing/useSetAutoRechargeConfig.d.ts +2 -2
- package/billing/useSetAutoRechargeConfig.d.ts.map +1 -1
- package/billing/useSetAutoRechargeConfig.js +2 -2
- package/billing/useSetAutoRechargeConfig.js.map +1 -1
- package/billing/useSubscription.d.ts +3 -3
- package/billing/useSubscription.d.ts.map +1 -1
- package/billing/useSubscription.js +7 -7
- package/billing/useSubscription.js.map +1 -1
- package/channel-app/ChannelAppListPanel.d.ts.map +1 -1
- package/channel-app/ChannelAppListPanel.js +2 -1
- package/channel-app/ChannelAppListPanel.js.map +1 -1
- package/channel-app/slackAppSetup.d.ts +0 -23
- package/channel-app/slackAppSetup.d.ts.map +1 -1
- package/channel-app/slackAppSetup.js +3 -2
- package/channel-app/slackAppSetup.js.map +1 -1
- package/channel-app/whatsappAppSetup.d.ts +0 -26
- package/channel-app/whatsappAppSetup.d.ts.map +1 -1
- package/channel-app/whatsappAppSetup.js +2 -1
- package/channel-app/whatsappAppSetup.js.map +1 -1
- package/cursor-accounts/CursorAccountEditor.js +3 -3
- package/cursor-accounts/CursorAccountEditor.js.map +1 -1
- package/cursor-accounts/CursorAccountsConsole.js +3 -3
- package/cursor-accounts/CursorAccountsConsole.js.map +1 -1
- package/dashboard/OperationalDashboard.d.ts +1 -4
- package/dashboard/OperationalDashboard.d.ts.map +1 -1
- package/dashboard/OperationalDashboard.js +1 -3
- package/dashboard/OperationalDashboard.js.map +1 -1
- package/dashboard/useDashboardSummary.d.ts +1 -3
- package/dashboard/useDashboardSummary.d.ts.map +1 -1
- package/dashboard/useDashboardSummary.js +1 -1
- package/dashboard/useDashboardSummary.js.map +1 -1
- package/environment/EnvironmentListPanel.d.ts.map +1 -1
- package/environment/EnvironmentListPanel.js +2 -1
- package/environment/EnvironmentListPanel.js.map +1 -1
- package/environment/EnvironmentVariableEditor.d.ts.map +1 -1
- package/environment/EnvironmentVariableEditor.js +2 -1
- package/environment/EnvironmentVariableEditor.js.map +1 -1
- package/execution/ArtifactFileContent.d.ts.map +1 -1
- package/execution/ArtifactFileContent.js +2 -1
- package/execution/ArtifactFileContent.js.map +1 -1
- package/execution/McpToolDetail.d.ts.map +1 -1
- package/execution/McpToolDetail.js +2 -1
- package/execution/McpToolDetail.js.map +1 -1
- package/execution/ResultView.d.ts.map +1 -1
- package/execution/ResultView.js +2 -1
- package/execution/ResultView.js.map +1 -1
- package/execution/TerminalSession.js +1 -1
- package/execution/TerminalSession.js.map +1 -1
- package/execution/ThreadSkeleton.d.ts.map +1 -1
- package/execution/ThreadSkeleton.js +2 -1
- package/execution/ThreadSkeleton.js.map +1 -1
- package/execution/file-path-resolver.d.ts.map +1 -1
- package/execution/file-path-resolver.js +3 -2
- package/execution/file-path-resolver.js.map +1 -1
- package/execution/sandbox-path-normalizer.d.ts +0 -11
- package/execution/sandbox-path-normalizer.d.ts.map +1 -1
- package/execution/sandbox-path-normalizer.js +2 -1
- package/execution/sandbox-path-normalizer.js.map +1 -1
- package/github/parseGitUrl.d.ts.map +1 -1
- package/github/parseGitUrl.js +16 -4
- package/github/parseGitUrl.js.map +1 -1
- package/iam-policy/GrantAccessForm.d.ts +3 -3
- package/iam-policy/GrantAccessForm.d.ts.map +1 -1
- package/iam-policy/GrantAccessForm.js +3 -3
- package/iam-policy/GrantAccessForm.js.map +1 -1
- package/iam-policy/OrgMembersPanel.d.ts +3 -3
- package/iam-policy/OrgMembersPanel.d.ts.map +1 -1
- package/iam-policy/OrgMembersPanel.js +4 -3
- package/iam-policy/OrgMembersPanel.js.map +1 -1
- package/iam-policy/PeopleWithAccess.d.ts +2 -2
- package/iam-policy/PeopleWithAccess.d.ts.map +1 -1
- package/iam-policy/PeopleWithAccess.js +2 -2
- package/iam-policy/PeopleWithAccess.js.map +1 -1
- package/iam-policy/PrincipalPicker.d.ts +2 -2
- package/iam-policy/PrincipalPicker.d.ts.map +1 -1
- package/iam-policy/PrincipalPicker.js +2 -2
- package/iam-policy/PrincipalPicker.js.map +1 -1
- package/iam-policy/SharePanel.d.ts +3 -3
- package/iam-policy/SharePanel.d.ts.map +1 -1
- package/iam-policy/SharePanel.js +3 -3
- package/iam-policy/SharePanel.js.map +1 -1
- package/iam-policy/useCreateIamPolicy.d.ts +1 -1
- package/iam-policy/useCreateIamPolicy.js +1 -1
- package/iam-policy/useDeleteIamPolicy.d.ts +1 -1
- package/iam-policy/useDeleteIamPolicy.js +1 -1
- package/iam-policy/useGranteeCandidates.d.ts +3 -3
- package/iam-policy/useGranteeCandidates.d.ts.map +1 -1
- package/iam-policy/useGranteeCandidates.js +2 -2
- package/iam-policy/useGranteeCandidates.js.map +1 -1
- package/iam-policy/useOwnerAssignment.d.ts +2 -2
- package/iam-policy/useOwnerAssignment.d.ts.map +1 -1
- package/iam-policy/useOwnerAssignment.js +3 -3
- package/iam-policy/useOwnerAssignment.js.map +1 -1
- package/iam-policy/usePrincipalsCount.d.ts +4 -4
- package/iam-policy/usePrincipalsCount.d.ts.map +1 -1
- package/iam-policy/usePrincipalsCount.js +7 -7
- package/iam-policy/usePrincipalsCount.js.map +1 -1
- package/iam-policy/useResourceAccess.d.ts +1 -1
- package/iam-policy/useResourceAccess.js +1 -1
- package/iam-policy/useRevokeOrgAccess.d.ts +1 -1
- package/iam-policy/useRevokeOrgAccess.d.ts.map +1 -1
- package/iam-policy/useRevokeOrgAccess.js +2 -2
- package/iam-policy/useRevokeOrgAccess.js.map +1 -1
- package/identity-account/AccountPreferencesPanel.d.ts.map +1 -1
- package/identity-account/AccountPreferencesPanel.js +2 -1
- package/identity-account/AccountPreferencesPanel.js.map +1 -1
- package/identity-provider/IdentityProviderDetailPanel.js +4 -4
- package/identity-provider/IdentityProviderDetailPanel.js.map +1 -1
- package/identity-provider/IdentityProviderListPanel.d.ts.map +1 -1
- package/identity-provider/IdentityProviderListPanel.js +2 -1
- package/identity-provider/IdentityProviderListPanel.js.map +1 -1
- package/identity-provider/IdentityProviderWizard.js +1 -1
- package/identity-provider/IdentityProviderWizard.js.map +1 -1
- package/identity-provider/SsoLoginPrompt.js +2 -1
- package/identity-provider/SsoLoginPrompt.js.map +1 -1
- package/identity-provider/useIdentityProviderList.d.ts +2 -2
- package/identity-provider/useIdentityProviderList.js +2 -2
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/inline-edit/InlineEditImage.d.ts +4 -0
- package/inline-edit/InlineEditImage.d.ts.map +1 -1
- package/inline-edit/InlineEditImage.js +12 -11
- package/inline-edit/InlineEditImage.js.map +1 -1
- package/inline-edit/InlineEditText.d.ts +4 -0
- package/inline-edit/InlineEditText.d.ts.map +1 -1
- package/inline-edit/InlineEditText.js +12 -11
- package/inline-edit/InlineEditText.js.map +1 -1
- package/inline-edit/InlineEditTextarea.d.ts +4 -0
- package/inline-edit/InlineEditTextarea.d.ts.map +1 -1
- package/inline-edit/InlineEditTextarea.js +11 -16
- package/inline-edit/InlineEditTextarea.js.map +1 -1
- package/inline-edit/useInlineDraft.d.ts +26 -0
- package/inline-edit/useInlineDraft.d.ts.map +1 -0
- package/inline-edit/useInlineDraft.js +61 -0
- package/inline-edit/useInlineDraft.js.map +1 -0
- package/internal/DialogShell.d.ts +21 -0
- package/internal/DialogShell.d.ts.map +1 -1
- package/internal/DialogShell.js +51 -4
- package/internal/DialogShell.js.map +1 -1
- package/internal/LoadingRegion.d.ts +35 -0
- package/internal/LoadingRegion.d.ts.map +1 -0
- package/internal/LoadingRegion.js +33 -0
- package/internal/LoadingRegion.js.map +1 -0
- package/internal/markdown-components.d.ts.map +1 -1
- package/internal/markdown-components.js +18 -4
- package/internal/markdown-components.js.map +1 -1
- package/internal/trim.d.ts +7 -0
- package/internal/trim.d.ts.map +1 -0
- package/internal/trim.js +12 -0
- package/internal/trim.js.map +1 -0
- package/invitation/InvitationManager.d.ts.map +1 -1
- package/invitation/InvitationManager.js +2 -1
- package/invitation/InvitationManager.js.map +1 -1
- package/invitation/InvitationRedemption.d.ts.map +1 -1
- package/invitation/InvitationRedemption.js +5 -4
- package/invitation/InvitationRedemption.js.map +1 -1
- package/invitation/useInvitationPreview.d.ts +1 -1
- package/invitation/useInvitationPreview.js +1 -1
- package/licenses/LicenseDetail.d.ts.map +1 -1
- package/licenses/LicenseDetail.js +3 -3
- package/licenses/LicenseDetail.js.map +1 -1
- package/licenses/LicenseIssueForm.js +6 -6
- package/licenses/LicenseIssueForm.js.map +1 -1
- package/licenses/license-draft.d.ts +1 -1
- package/licenses/license-draft.d.ts.map +1 -1
- package/licenses/license-draft.js +3 -3
- package/licenses/license-draft.js.map +1 -1
- package/licenses/license-format.js +1 -1
- package/licenses/license-format.js.map +1 -1
- package/mcp-server/McpServerDetailView.d.ts.map +1 -1
- package/mcp-server/McpServerDetailView.js +2 -1
- package/mcp-server/McpServerDetailView.js.map +1 -1
- package/memory/MemoryListPanel.d.ts.map +1 -1
- package/memory/MemoryListPanel.js +2 -1
- package/memory/MemoryListPanel.js.map +1 -1
- package/oauth-app/OAuthAppListPanel.d.ts.map +1 -1
- package/oauth-app/OAuthAppListPanel.js +2 -1
- package/oauth-app/OAuthAppListPanel.js.map +1 -1
- package/organization/OrgPreferencesPanel.d.ts +3 -3
- package/organization/OrgPreferencesPanel.d.ts.map +1 -1
- package/organization/OrgPreferencesPanel.js +6 -5
- package/organization/OrgPreferencesPanel.js.map +1 -1
- package/organization/OrgProfilePanel.d.ts +3 -3
- package/organization/OrgProfilePanel.d.ts.map +1 -1
- package/organization/OrgProfilePanel.js +8 -7
- package/organization/OrgProfilePanel.js.map +1 -1
- package/organization/index.d.ts +1 -0
- package/organization/index.d.ts.map +1 -1
- package/organization/index.js +1 -0
- package/organization/index.js.map +1 -1
- package/organization/useFollowSessionOrganization.d.ts +9 -0
- package/organization/useFollowSessionOrganization.d.ts.map +1 -0
- package/organization/useFollowSessionOrganization.js +52 -0
- package/organization/useFollowSessionOrganization.js.map +1 -0
- package/package.json +5 -5
- package/plan-catalog/plan-draft.js +3 -3
- package/plan-catalog/plan-draft.js.map +1 -1
- package/platform-client/PlatformClientListPanel.d.ts.map +1 -1
- package/platform-client/PlatformClientListPanel.js +2 -1
- package/platform-client/PlatformClientListPanel.js.map +1 -1
- package/plugin/PluginDetailView.d.ts.map +1 -1
- package/plugin/PluginDetailView.js +2 -1
- package/plugin/PluginDetailView.js.map +1 -1
- package/portal-container.d.ts +8 -0
- package/portal-container.d.ts.map +1 -1
- package/portal-container.js +8 -0
- package/portal-container.js.map +1 -1
- package/provider.d.ts +4 -1
- package/provider.d.ts.map +1 -1
- package/provider.js +4 -1
- package/provider.js.map +1 -1
- package/public-base-url-context.d.ts.map +1 -1
- package/public-base-url-context.js +2 -1
- package/public-base-url-context.js.map +1 -1
- package/schedule/ScheduleDetailView.d.ts.map +1 -1
- package/schedule/ScheduleDetailView.js +2 -1
- package/schedule/ScheduleDetailView.js.map +1 -1
- package/session/SessionViewer.d.ts +7 -2
- package/session/SessionViewer.d.ts.map +1 -1
- package/session/SessionViewer.js +7 -2
- package/session/SessionViewer.js.map +1 -1
- package/session/useSessionConversation.d.ts +10 -1
- package/session/useSessionConversation.d.ts.map +1 -1
- package/session/useSessionConversation.js +5 -3
- package/session/useSessionConversation.js.map +1 -1
- package/settings/EnvironmentsSection.d.ts.map +1 -1
- package/settings/EnvironmentsSection.js +2 -1
- package/settings/EnvironmentsSection.js.map +1 -1
- package/settings/MembersSection.js +2 -2
- package/settings/MembersSection.js.map +1 -1
- package/settings/OrgPreferencesSection.js +1 -1
- package/settings/OrgPreferencesSection.js.map +1 -1
- package/settings/OrgProfileSection.js +1 -1
- package/settings/OrgProfileSection.js.map +1 -1
- package/settings/TeamsSection.js +1 -1
- package/settings/TeamsSection.js.map +1 -1
- package/settings/UsageSection.js +1 -1
- package/settings/UsageSection.js.map +1 -1
- package/sharing/ShareAgentDialog.d.ts.map +1 -1
- package/sharing/ShareAgentDialog.js +2 -1
- package/sharing/ShareAgentDialog.js.map +1 -1
- package/sharing/SharedAgentChat.d.ts.map +1 -1
- package/sharing/SharedAgentChat.js +2 -1
- package/sharing/SharedAgentChat.js.map +1 -1
- package/sidebar/WorkspaceSidebar.d.ts.map +1 -1
- package/sidebar/WorkspaceSidebar.js +2 -1
- package/sidebar/WorkspaceSidebar.js.map +1 -1
- package/skill/SkillDetailView.d.ts.map +1 -1
- package/skill/SkillDetailView.js +2 -1
- package/skill/SkillDetailView.js.map +1 -1
- package/skill/SkillDiffDialog.d.ts.map +1 -1
- package/skill/SkillDiffDialog.js +2 -1
- package/skill/SkillDiffDialog.js.map +1 -1
- package/skill/SkillFileBrowser.d.ts.map +1 -1
- package/skill/SkillFileBrowser.js +2 -1
- package/skill/SkillFileBrowser.js.map +1 -1
- package/src/access/ManageAccessButton.tsx +1 -1
- package/src/access/ManageAccessDialog.tsx +1 -1
- package/src/agent/AgentDetailView.tsx +4 -4
- package/src/api-key/ApiKeyListPanel.tsx +4 -4
- package/src/attachment/AttachmentImageLightbox.tsx +3 -4
- package/src/billing/AutoRechargeCard.tsx +5 -5
- package/src/billing/BillingSection.tsx +10 -9
- package/src/billing/CreditLedgerTable.tsx +4 -4
- package/src/billing/CreditPackGrid.tsx +1 -1
- package/src/billing/PaymentMethodCard.tsx +1 -1
- package/src/billing/PlanSection.tsx +6 -5
- package/src/billing/ProviderKeysSection.tsx +15 -15
- package/src/billing/plan-features.ts +1 -1
- package/src/billing/useBillingAccount.ts +7 -7
- package/src/billing/useBillingUsageReport.ts +7 -7
- package/src/billing/useChangePlan.ts +6 -6
- package/src/billing/useCreateBillingPortalSession.ts +4 -4
- package/src/billing/useCreateCheckoutSession.ts +3 -3
- package/src/billing/useCreatePaymentMethodSetupSession.ts +3 -3
- package/src/billing/useCreditLedger.ts +7 -7
- package/src/billing/useCustomerModelPricing.ts +7 -7
- package/src/billing/useEntitlements.ts +5 -5
- package/src/billing/usePeriodEstimate.ts +4 -4
- package/src/billing/useProviderKeys.ts +12 -12
- package/src/billing/useSetAutoRechargeConfig.ts +3 -3
- package/src/billing/useSubscription.ts +7 -7
- package/src/channel-app/ChannelAppListPanel.tsx +4 -4
- package/src/channel-app/slackAppSetup.ts +3 -2
- package/src/channel-app/whatsappAppSetup.ts +2 -1
- package/src/cursor-accounts/CursorAccountEditor.tsx +3 -3
- package/src/cursor-accounts/CursorAccountsConsole.tsx +5 -5
- package/src/dashboard/OperationalDashboard.tsx +1 -6
- package/src/dashboard/useDashboardSummary.ts +2 -4
- package/src/environment/EnvironmentListPanel.tsx +4 -4
- package/src/environment/EnvironmentVariableEditor.tsx +4 -4
- package/src/execution/ArtifactFileContent.tsx +3 -2
- package/src/execution/McpToolDetail.tsx +3 -3
- package/src/execution/ResultView.tsx +3 -3
- package/src/execution/TerminalSession.tsx +1 -1
- package/src/execution/ThreadSkeleton.tsx +4 -4
- package/src/execution/file-path-resolver.ts +3 -2
- package/src/execution/sandbox-path-normalizer.ts +2 -1
- package/src/github/parseGitUrl.ts +13 -4
- package/src/iam-policy/GrantAccessForm.tsx +4 -4
- package/src/iam-policy/OrgMembersPanel.tsx +7 -7
- package/src/iam-policy/PeopleWithAccess.tsx +3 -3
- package/src/iam-policy/PrincipalPicker.tsx +3 -3
- package/src/iam-policy/SharePanel.tsx +4 -4
- package/src/iam-policy/useCreateIamPolicy.ts +1 -1
- package/src/iam-policy/useDeleteIamPolicy.ts +1 -1
- package/src/iam-policy/useGranteeCandidates.ts +3 -3
- package/src/iam-policy/useOwnerAssignment.ts +3 -3
- package/src/iam-policy/usePrincipalsCount.ts +7 -7
- package/src/iam-policy/useResourceAccess.ts +1 -1
- package/src/iam-policy/useRevokeOrgAccess.ts +3 -3
- package/src/identity-account/AccountPreferencesPanel.tsx +4 -4
- package/src/identity-provider/IdentityProviderDetailPanel.tsx +3 -9
- package/src/identity-provider/IdentityProviderListPanel.tsx +4 -4
- package/src/identity-provider/IdentityProviderWizard.tsx +1 -1
- package/src/identity-provider/SsoLoginPrompt.tsx +6 -5
- package/src/identity-provider/useIdentityProviderList.ts +2 -2
- package/src/index.ts +1 -0
- package/src/inline-edit/InlineEditImage.tsx +13 -11
- package/src/inline-edit/InlineEditText.tsx +13 -11
- package/src/inline-edit/InlineEditTextarea.tsx +12 -16
- package/src/inline-edit/useInlineDraft.ts +85 -0
- package/src/internal/DialogShell.tsx +80 -3
- package/src/internal/LoadingRegion.tsx +46 -0
- package/src/internal/loading-region-markup.json +71 -0
- package/src/internal/markdown-components.tsx +15 -4
- package/src/internal/trim.ts +10 -0
- package/src/invitation/InvitationManager.tsx +4 -4
- package/src/invitation/InvitationRedemption.tsx +7 -7
- package/src/invitation/useInvitationPreview.ts +1 -1
- package/src/licenses/LicenseDetail.tsx +8 -6
- package/src/licenses/LicenseIssueForm.tsx +6 -6
- package/src/licenses/license-draft.ts +4 -4
- package/src/licenses/license-format.ts +1 -1
- package/src/mcp-server/McpServerDetailView.tsx +4 -4
- package/src/memory/MemoryListPanel.tsx +4 -4
- package/src/oauth-app/OAuthAppListPanel.tsx +4 -4
- package/src/organization/OrgPreferencesPanel.tsx +9 -9
- package/src/organization/OrgProfilePanel.tsx +12 -12
- package/src/organization/index.ts +1 -0
- package/src/organization/useFollowSessionOrganization.ts +54 -0
- package/src/plan-catalog/plan-draft.ts +3 -3
- package/src/platform-client/PlatformClientListPanel.tsx +4 -4
- package/src/plugin/PluginDetailView.tsx +3 -2
- package/src/portal-container.ts +8 -0
- package/src/provider.tsx +4 -1
- package/src/public-base-url-context.ts +2 -1
- package/src/schedule/ScheduleDetailView.tsx +4 -4
- package/src/session/SessionViewer.tsx +13 -3
- package/src/session/useSessionConversation.ts +14 -3
- package/src/settings/EnvironmentsSection.tsx +3 -2
- package/src/settings/MembersSection.tsx +3 -3
- package/src/settings/OrgPreferencesSection.tsx +1 -1
- package/src/settings/OrgProfileSection.tsx +1 -1
- package/src/settings/TeamsSection.tsx +1 -1
- package/src/settings/UsageSection.tsx +1 -1
- package/src/sharing/ShareAgentDialog.tsx +2 -1
- package/src/sharing/SharedAgentChat.tsx +4 -4
- package/src/sidebar/WorkspaceSidebar.tsx +3 -2
- package/src/skill/SkillDetailView.tsx +4 -4
- package/src/skill/SkillDiffDialog.tsx +4 -4
- package/src/skill/SkillFileBrowser.tsx +4 -4
- package/src/team/TeamDetailPanel.tsx +3 -3
- package/src/team/TeamListPanel.tsx +3 -2
- package/src/team/TeamMembersPanel.tsx +3 -3
- package/src/usage/OrgUsagePanel.tsx +9 -9
- package/src/usage/useExportCSV.ts +9 -9
- package/src/usage/useOrgUsageReport.ts +7 -7
- package/src/version-history/VersionTimeline.tsx +4 -4
- package/src/workflow/WorkflowVersionDiffViewer.tsx +4 -4
- package/src/workflow/WorkflowVersionTimeline.tsx +4 -4
- package/src/workflow/useDiagnoseExecutionFlow.ts +23 -18
- package/src/workflow/useExplainWorkflowFlow.ts +7 -3
- package/src/workflow/useRefineWorkflowFlow.ts +17 -10
- package/src/workflow/useWorkflowArchitectFlow.ts +7 -3
- package/src/workspace/ExplorerTree.tsx +4 -8
- package/src/workspace/FileViewer.tsx +4 -5
- package/styles.css +1 -1
- package/team/TeamDetailPanel.d.ts +2 -2
- package/team/TeamDetailPanel.d.ts.map +1 -1
- package/team/TeamDetailPanel.js +2 -2
- package/team/TeamDetailPanel.js.map +1 -1
- package/team/TeamListPanel.d.ts.map +1 -1
- package/team/TeamListPanel.js +2 -1
- package/team/TeamListPanel.js.map +1 -1
- package/team/TeamMembersPanel.d.ts +2 -2
- package/team/TeamMembersPanel.d.ts.map +1 -1
- package/team/TeamMembersPanel.js +2 -2
- package/team/TeamMembersPanel.js.map +1 -1
- package/usage/OrgUsagePanel.d.ts +3 -3
- package/usage/OrgUsagePanel.d.ts.map +1 -1
- package/usage/OrgUsagePanel.js +6 -5
- package/usage/OrgUsagePanel.js.map +1 -1
- package/usage/useExportCSV.d.ts +2 -2
- package/usage/useExportCSV.d.ts.map +1 -1
- package/usage/useExportCSV.js +9 -9
- package/usage/useExportCSV.js.map +1 -1
- package/usage/useOrgUsageReport.d.ts +4 -4
- package/usage/useOrgUsageReport.d.ts.map +1 -1
- package/usage/useOrgUsageReport.js +7 -7
- package/usage/useOrgUsageReport.js.map +1 -1
- package/version-history/VersionTimeline.d.ts.map +1 -1
- package/version-history/VersionTimeline.js +2 -1
- package/version-history/VersionTimeline.js.map +1 -1
- package/workflow/WorkflowVersionDiffViewer.d.ts.map +1 -1
- package/workflow/WorkflowVersionDiffViewer.js +2 -1
- package/workflow/WorkflowVersionDiffViewer.js.map +1 -1
- package/workflow/WorkflowVersionTimeline.d.ts.map +1 -1
- package/workflow/WorkflowVersionTimeline.js +2 -1
- package/workflow/WorkflowVersionTimeline.js.map +1 -1
- package/workflow/useDiagnoseExecutionFlow.d.ts.map +1 -1
- package/workflow/useDiagnoseExecutionFlow.js +23 -18
- package/workflow/useDiagnoseExecutionFlow.js.map +1 -1
- package/workflow/useExplainWorkflowFlow.d.ts.map +1 -1
- package/workflow/useExplainWorkflowFlow.js +7 -3
- package/workflow/useExplainWorkflowFlow.js.map +1 -1
- package/workflow/useRefineWorkflowFlow.d.ts.map +1 -1
- package/workflow/useRefineWorkflowFlow.js +14 -10
- package/workflow/useRefineWorkflowFlow.js.map +1 -1
- package/workflow/useWorkflowArchitectFlow.d.ts.map +1 -1
- package/workflow/useWorkflowArchitectFlow.js +7 -3
- package/workflow/useWorkflowArchitectFlow.js.map +1 -1
- package/workspace/ExplorerTree.d.ts.map +1 -1
- package/workspace/ExplorerTree.js +2 -5
- package/workspace/ExplorerTree.js.map +1 -1
- package/workspace/FileViewer.d.ts.map +1 -1
- package/workspace/FileViewer.js +2 -1
- package/workspace/FileViewer.js.map +1 -1
|
@@ -10,6 +10,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from "../internal/tooltip.js"
|
|
|
10
10
|
import { useIdentityProviderList } from "./useIdentityProviderList.js";
|
|
11
11
|
import { useDeleteIdentityProvider } from "./useDeleteIdentityProvider.js";
|
|
12
12
|
import { SpinnerIcon } from "../internal/SpinnerIcon.js";
|
|
13
|
+
import { LoadingRegion } from "../internal/LoadingRegion.js";
|
|
13
14
|
|
|
14
15
|
/** Props for {@link IdentityProviderListPanel}. */
|
|
15
16
|
export interface IdentityProviderListPanelProps {
|
|
@@ -75,10 +76,9 @@ export function IdentityProviderListPanel({
|
|
|
75
76
|
|
|
76
77
|
if (isLoading) {
|
|
77
78
|
return (
|
|
78
|
-
<
|
|
79
|
+
<LoadingRegion
|
|
79
80
|
className={cn("stg:space-y-2", className)}
|
|
80
|
-
|
|
81
|
-
aria-label="Loading identity providers"
|
|
81
|
+
label="Loading identity providers"
|
|
82
82
|
>
|
|
83
83
|
{Array.from({ length: 2 }, (_, i) => (
|
|
84
84
|
<div
|
|
@@ -86,7 +86,7 @@ export function IdentityProviderListPanel({
|
|
|
86
86
|
className="stg:bg-muted-subtle stg:h-14 stg:animate-pulse stg:rounded-lg"
|
|
87
87
|
/>
|
|
88
88
|
))}
|
|
89
|
-
</
|
|
89
|
+
</LoadingRegion>
|
|
90
90
|
);
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -557,7 +557,7 @@ function ReviewStep({
|
|
|
557
557
|
value={userinfoEndpoint}
|
|
558
558
|
onChange={onUserinfoEndpointChange}
|
|
559
559
|
placeholder="https://example.com/userinfo"
|
|
560
|
-
hint="Optional
|
|
560
|
+
hint="Optional. Read only when Stigmer creates an account from a token with no email claim"
|
|
561
561
|
disabled={isCreating}
|
|
562
562
|
/>
|
|
563
563
|
|
|
@@ -186,6 +186,7 @@ function resolvePhase(
|
|
|
186
186
|
|
|
187
187
|
import { forwardRef, useId } from "react";
|
|
188
188
|
import { SpinnerIcon } from "../internal/SpinnerIcon.js";
|
|
189
|
+
import { LoadingRegion } from "../internal/LoadingRegion.js";
|
|
189
190
|
|
|
190
191
|
interface OrgInputFormProps {
|
|
191
192
|
readonly value: string;
|
|
@@ -241,16 +242,16 @@ const OrgInputForm = forwardRef<HTMLInputElement, OrgInputFormProps>(
|
|
|
241
242
|
|
|
242
243
|
function LoadingState({ org }: { org: string }) {
|
|
243
244
|
return (
|
|
244
|
-
<
|
|
245
|
+
<LoadingRegion
|
|
245
246
|
className="stg:flex stg:flex-col stg:items-center stg:gap-3 stg:py-4"
|
|
246
|
-
|
|
247
|
-
aria-label={`Looking up SSO provider for ${org}`}
|
|
247
|
+
label={`Looking up SSO provider for ${org}`}
|
|
248
248
|
>
|
|
249
249
|
<SpinnerIcon size={20} className="stg:text-muted-foreground" />
|
|
250
|
-
|
|
250
|
+
{/* The hidden label says it in full; this is its short visible form. */}
|
|
251
|
+
<p className="stg:text-sm stg:text-muted-foreground" aria-hidden="true">
|
|
251
252
|
Looking up <span className="stg:font-medium stg:text-foreground">{org}</span>…
|
|
252
253
|
</p>
|
|
253
|
-
</
|
|
254
|
+
</LoadingRegion>
|
|
254
255
|
);
|
|
255
256
|
}
|
|
256
257
|
|
|
@@ -32,8 +32,8 @@ export interface UseIdentityProviderListReturn {
|
|
|
32
32
|
*
|
|
33
33
|
* @example
|
|
34
34
|
* ```tsx
|
|
35
|
-
* function IdpSettings({
|
|
36
|
-
* const { identityProviders, isLoading, error } = useIdentityProviderList(
|
|
35
|
+
* function IdpSettings({ org }: { org: string }) {
|
|
36
|
+
* const { identityProviders, isLoading, error } = useIdentityProviderList(org);
|
|
37
37
|
*
|
|
38
38
|
* if (isLoading) return <Skeleton />;
|
|
39
39
|
* if (error) return <ErrorMessage error={error} />;
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useCallback,
|
|
3
|
+
import { useCallback, useRef, useState } from "react";
|
|
4
4
|
import { cn } from "@stigmer/theme";
|
|
5
5
|
import type { InlineEditBaseProps } from "./types.js";
|
|
6
|
+
import { useInlineDraft } from "./useInlineDraft.js";
|
|
6
7
|
|
|
7
8
|
/** Props for {@link InlineEditImage}. */
|
|
8
9
|
export interface InlineEditImageProps extends InlineEditBaseProps {
|
|
@@ -21,6 +22,10 @@ export interface InlineEditImageProps extends InlineEditBaseProps {
|
|
|
21
22
|
*
|
|
22
23
|
* Shows the current image (or fallback icon). On click, reveals
|
|
23
24
|
* an input for entering a new image URL with confirm/cancel.
|
|
25
|
+
*
|
|
26
|
+
* The draft is seeded from `value` when editing opens. While the editor is
|
|
27
|
+
* open, a draft the user has edited keeps their text if `value` changes, and
|
|
28
|
+
* an untouched draft follows the new `value`.
|
|
24
29
|
*/
|
|
25
30
|
export function InlineEditImage({
|
|
26
31
|
value,
|
|
@@ -32,18 +37,15 @@ export function InlineEditImage({
|
|
|
32
37
|
error,
|
|
33
38
|
className,
|
|
34
39
|
}: InlineEditImageProps) {
|
|
35
|
-
const [isEditing, setIsEditing] = useState(false);
|
|
36
|
-
const [draft, setDraft] = useState(value);
|
|
37
40
|
const [localError, setLocalError] = useState<string | null>(null);
|
|
38
41
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
42
|
+
const { isEditing, setIsEditing, draft, setDraft, startEditing } =
|
|
43
|
+
useInlineDraft(value, inputRef);
|
|
39
44
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
requestAnimationFrame(() => inputRef.current?.focus());
|
|
45
|
-
}
|
|
46
|
-
}, [isEditing, value]);
|
|
45
|
+
const handleEdit = useCallback(() => {
|
|
46
|
+
setLocalError(null);
|
|
47
|
+
startEditing();
|
|
48
|
+
}, [startEditing]);
|
|
47
49
|
|
|
48
50
|
const handleConfirm = useCallback(async () => {
|
|
49
51
|
const trimmed = draft.trim();
|
|
@@ -81,7 +83,7 @@ export function InlineEditImage({
|
|
|
81
83
|
<div className={cn("stg:group/inline-edit stg:inline-flex", className)}>
|
|
82
84
|
<button
|
|
83
85
|
type="button"
|
|
84
|
-
onClick={() => { if (!disabled)
|
|
86
|
+
onClick={() => { if (!disabled) handleEdit(); }}
|
|
85
87
|
disabled={disabled}
|
|
86
88
|
className={cn(
|
|
87
89
|
"stg:relative stg:rounded-md stg:p-0.5 stg:transition-colors",
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useCallback,
|
|
3
|
+
import { useCallback, useRef, useState } from "react";
|
|
4
4
|
import { cn } from "@stigmer/theme";
|
|
5
5
|
import type { InlineEditBaseProps } from "./types.js";
|
|
6
|
+
import { useInlineDraft } from "./useInlineDraft.js";
|
|
6
7
|
|
|
7
8
|
/** Props for {@link InlineEditText}. */
|
|
8
9
|
export interface InlineEditTextProps extends InlineEditBaseProps {
|
|
@@ -24,6 +25,10 @@ export interface InlineEditTextProps extends InlineEditBaseProps {
|
|
|
24
25
|
* Displays the value as styled text. On click, transitions to an input
|
|
25
26
|
* with inline confirm/cancel controls. Confirm triggers `onSave`;
|
|
26
27
|
* cancel reverts. Escape key also cancels.
|
|
28
|
+
*
|
|
29
|
+
* The draft is seeded from `value` when editing opens. While the editor is
|
|
30
|
+
* open, a draft the user has edited keeps their text if `value` changes, and
|
|
31
|
+
* an untouched draft follows the new `value`.
|
|
27
32
|
*/
|
|
28
33
|
export function InlineEditText({
|
|
29
34
|
value,
|
|
@@ -36,18 +41,15 @@ export function InlineEditText({
|
|
|
36
41
|
error,
|
|
37
42
|
className,
|
|
38
43
|
}: InlineEditTextProps) {
|
|
39
|
-
const [isEditing, setIsEditing] = useState(false);
|
|
40
|
-
const [draft, setDraft] = useState(value);
|
|
41
44
|
const [localError, setLocalError] = useState<string | null>(null);
|
|
42
45
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
46
|
+
const { isEditing, setIsEditing, draft, setDraft, startEditing } =
|
|
47
|
+
useInlineDraft(value, inputRef);
|
|
43
48
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
requestAnimationFrame(() => inputRef.current?.focus());
|
|
49
|
-
}
|
|
50
|
-
}, [isEditing, value]);
|
|
49
|
+
const handleEdit = useCallback(() => {
|
|
50
|
+
setLocalError(null);
|
|
51
|
+
startEditing();
|
|
52
|
+
}, [startEditing]);
|
|
51
53
|
|
|
52
54
|
const handleConfirm = useCallback(async () => {
|
|
53
55
|
const trimmed = draft.trim();
|
|
@@ -91,7 +93,7 @@ export function InlineEditText({
|
|
|
91
93
|
<div className={cn("stg:group/inline-edit", className)}>
|
|
92
94
|
<button
|
|
93
95
|
type="button"
|
|
94
|
-
onClick={() => { if (!disabled)
|
|
96
|
+
onClick={() => { if (!disabled) handleEdit(); }}
|
|
95
97
|
disabled={disabled}
|
|
96
98
|
className={cn(
|
|
97
99
|
"stg:inline-flex stg:w-full stg:items-center stg:gap-1.5 stg:rounded-md stg:px-1.5 stg:py-0.5 stg:text-left stg:transition-colors",
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
4
|
import { cn } from "@stigmer/theme";
|
|
5
5
|
import type { InlineEditBaseProps } from "./types.js";
|
|
6
|
+
import { useInlineDraft } from "./useInlineDraft.js";
|
|
6
7
|
|
|
7
8
|
/** Props for {@link InlineEditTextarea}. */
|
|
8
9
|
export interface InlineEditTextareaProps extends InlineEditBaseProps {
|
|
@@ -23,6 +24,10 @@ export interface InlineEditTextareaProps extends InlineEditBaseProps {
|
|
|
23
24
|
*
|
|
24
25
|
* In read mode, renders the value as preformatted text with expand/collapse.
|
|
25
26
|
* On click, opens a textarea with confirm/cancel. Ctrl+Enter confirms.
|
|
27
|
+
*
|
|
28
|
+
* The draft is seeded from `value` when editing opens. While the editor is
|
|
29
|
+
* open, a draft the user has edited keeps their text if `value` changes, and
|
|
30
|
+
* an untouched draft follows the new `value`.
|
|
26
31
|
*/
|
|
27
32
|
export function InlineEditTextarea({
|
|
28
33
|
value,
|
|
@@ -35,24 +40,15 @@ export function InlineEditTextarea({
|
|
|
35
40
|
error,
|
|
36
41
|
className,
|
|
37
42
|
}: InlineEditTextareaProps) {
|
|
38
|
-
const [isEditing, setIsEditing] = useState(false);
|
|
39
|
-
const [draft, setDraft] = useState(value);
|
|
40
43
|
const [localError, setLocalError] = useState<string | null>(null);
|
|
41
44
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
|
45
|
+
const { isEditing, setIsEditing, draft, setDraft, startEditing } =
|
|
46
|
+
useInlineDraft(value, textareaRef, { caretAtEnd: true });
|
|
42
47
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
requestAnimationFrame(() => {
|
|
48
|
-
const ta = textareaRef.current;
|
|
49
|
-
if (ta) {
|
|
50
|
-
ta.focus();
|
|
51
|
-
ta.selectionStart = ta.value.length;
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
}, [isEditing, value]);
|
|
48
|
+
const handleEdit = useCallback(() => {
|
|
49
|
+
setLocalError(null);
|
|
50
|
+
startEditing();
|
|
51
|
+
}, [startEditing]);
|
|
56
52
|
|
|
57
53
|
// Auto-resize textarea
|
|
58
54
|
useEffect(() => {
|
|
@@ -103,7 +99,7 @@ export function InlineEditTextarea({
|
|
|
103
99
|
<div className={cn("stg:group/inline-edit", className)}>
|
|
104
100
|
<button
|
|
105
101
|
type="button"
|
|
106
|
-
onClick={() => { if (!disabled)
|
|
102
|
+
onClick={() => { if (!disabled) handleEdit(); }}
|
|
107
103
|
disabled={disabled}
|
|
108
104
|
className={cn(
|
|
109
105
|
"stg:w-full stg:rounded-md stg:px-2 stg:py-1.5 stg:text-left stg:transition-colors",
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The draft, focus and caret contract shared by the click-to-edit text
|
|
5
|
+
* editors (`InlineEditText`, `InlineEditTextarea`, `InlineEditImage`), kept in
|
|
6
|
+
* one place so the three cannot drift apart. Internal: not exported from the
|
|
7
|
+
* package.
|
|
8
|
+
*
|
|
9
|
+
* - Opening seeds the draft from the stored value and focuses the field in
|
|
10
|
+
* the commit that shows it, never a frame later, so a selection made right
|
|
11
|
+
* after opening (select-all, then type) is not collapsed afterwards
|
|
12
|
+
* (stigmer/stigmer#1575). A layout effect is used rather than a passive one
|
|
13
|
+
* because, in a browser, a passive effect may run after paint and after the
|
|
14
|
+
* next input.
|
|
15
|
+
* - An untouched draft follows the stored value, so a save never writes a
|
|
16
|
+
* stale copy over a change made elsewhere; once the user edits, the draft
|
|
17
|
+
* is theirs until they save or cancel. The follow is adjusted during render
|
|
18
|
+
* (the `ResizableSplit` idiom), so the field never shows the stale value.
|
|
19
|
+
*/
|
|
20
|
+
import { useCallback, useLayoutEffect, useMemo, useState } from "react";
|
|
21
|
+
import type { RefObject } from "react";
|
|
22
|
+
|
|
23
|
+
/** Return value of {@link useInlineDraft}. */
|
|
24
|
+
export interface UseInlineDraftReturn {
|
|
25
|
+
/** `true` while the field is open for editing. */
|
|
26
|
+
readonly isEditing: boolean;
|
|
27
|
+
/** Open or close the field without reseeding the draft. */
|
|
28
|
+
readonly setIsEditing: (editing: boolean) => void;
|
|
29
|
+
/** The text in the field. */
|
|
30
|
+
readonly draft: string;
|
|
31
|
+
/** Replace the text in the field (the user typed, or a control reset it). */
|
|
32
|
+
readonly setDraft: (draft: string) => void;
|
|
33
|
+
/** Open the field with the draft seeded from the stored value. */
|
|
34
|
+
readonly startEditing: () => void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Holds an inline editor's open state and draft, and places focus when the
|
|
39
|
+
* field opens (the contract in this module's header).
|
|
40
|
+
*
|
|
41
|
+
* @param value - The stored value.
|
|
42
|
+
* @param fieldRef - The input or textarea shown while editing.
|
|
43
|
+
* @param options.caretAtEnd - Place the caret after the text on opening.
|
|
44
|
+
*/
|
|
45
|
+
export function useInlineDraft(
|
|
46
|
+
value: string,
|
|
47
|
+
fieldRef: RefObject<HTMLInputElement | HTMLTextAreaElement | null>,
|
|
48
|
+
options?: { readonly caretAtEnd?: boolean },
|
|
49
|
+
): UseInlineDraftReturn {
|
|
50
|
+
const caretAtEnd = options?.caretAtEnd ?? false;
|
|
51
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
52
|
+
const [draft, setDraft] = useState(value);
|
|
53
|
+
// The stored value the draft was last seeded from.
|
|
54
|
+
const [seed, setSeed] = useState(value);
|
|
55
|
+
|
|
56
|
+
// An untouched draft follows the stored value (see the module header).
|
|
57
|
+
if (value !== seed) {
|
|
58
|
+
setSeed(value);
|
|
59
|
+
if (draft === seed) setDraft(value);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const startEditing = useCallback(() => {
|
|
63
|
+
setDraft(value);
|
|
64
|
+
setSeed(value);
|
|
65
|
+
setIsEditing(true);
|
|
66
|
+
}, [value]);
|
|
67
|
+
|
|
68
|
+
// A layout effect, not a frame later: focus (and the caret) land in the
|
|
69
|
+
// commit that shows the field, before the browser handles the next input.
|
|
70
|
+
useLayoutEffect(() => {
|
|
71
|
+
if (!isEditing) return;
|
|
72
|
+
const field = fieldRef.current;
|
|
73
|
+
if (!field) return;
|
|
74
|
+
field.focus();
|
|
75
|
+
if (caretAtEnd) {
|
|
76
|
+
const end = field.value.length;
|
|
77
|
+
field.setSelectionRange(end, end);
|
|
78
|
+
}
|
|
79
|
+
}, [isEditing, fieldRef, caretAtEnd]);
|
|
80
|
+
|
|
81
|
+
return useMemo(
|
|
82
|
+
() => ({ isEditing, setIsEditing, draft, setDraft, startEditing }),
|
|
83
|
+
[isEditing, draft, startEditing],
|
|
84
|
+
);
|
|
85
|
+
}
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useCallback, useEffect, useRef } from "react";
|
|
4
|
-
import type {
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
+
import type {
|
|
5
|
+
KeyboardEvent,
|
|
6
|
+
MouseEvent,
|
|
7
|
+
ReactNode,
|
|
8
|
+
SyntheticEvent,
|
|
9
|
+
} from "react";
|
|
5
10
|
import { cn } from "@stigmer/theme";
|
|
11
|
+
import {
|
|
12
|
+
PortalContainerContext,
|
|
13
|
+
useStigmerPortalContainer,
|
|
14
|
+
} from "../portal-container.js";
|
|
6
15
|
|
|
7
16
|
/**
|
|
8
17
|
* Width presets for {@link DialogShell}, mapping to Tailwind `max-w-*`
|
|
@@ -79,6 +88,27 @@ export interface DialogShellProps {
|
|
|
79
88
|
* escaped the #652 fence, and animation classes present on some dialogs and
|
|
80
89
|
* missing from others.
|
|
81
90
|
*
|
|
91
|
+
* Popups opened inside a modal shell render inside it (stigmer#1509). A
|
|
92
|
+
* modal `<dialog>` sits in the browser's top layer and makes the rest of
|
|
93
|
+
* the document inert, so a popover, menu or tooltip portaled into the
|
|
94
|
+
* provider's `document.body` container would paint beneath the dialog and
|
|
95
|
+
* refuse every click. The shell therefore owns an empty portal target as
|
|
96
|
+
* its last child and re-provides it through {@link PortalContainerContext}:
|
|
97
|
+
* every SDK popup below it lands in the top layer with the dialog, themed
|
|
98
|
+
* by ordinary inheritance from the provider's in-tree scope. The target is
|
|
99
|
+
* a zero-size fixed box, so the dialog's own scrolling box never clips a
|
|
100
|
+
* popup that extends past its edge. The target
|
|
101
|
+
* carries no `data-stgm-portal` marker; that selector keeps meaning the one
|
|
102
|
+
* body container. A non-modal shell is in-flow, so it keeps the provider's
|
|
103
|
+
* container.
|
|
104
|
+
*
|
|
105
|
+
* Because those popups now receive keys, Escape pressed while one is open
|
|
106
|
+
* belongs to the popup: Base UI closes it but does not prevent the
|
|
107
|
+
* keydown's default, which is the dialog's own close request. The shell
|
|
108
|
+
* notes, before any popup handler runs, whether its target held a popup,
|
|
109
|
+
* and keeps the dialog open for that one close request; the next Escape
|
|
110
|
+
* closes the dialog.
|
|
111
|
+
*
|
|
82
112
|
* Internal on purpose — not exported from the package until a host needs it.
|
|
83
113
|
* The `stigmer/no-handrolled-dialog` lint rule fences new `<dialog>`
|
|
84
114
|
* elements onto this shell.
|
|
@@ -102,6 +132,19 @@ export function DialogShell({
|
|
|
102
132
|
"aria-labelledby": ariaLabelledby,
|
|
103
133
|
}: DialogShellProps) {
|
|
104
134
|
const dialogRef = useRef<HTMLDialogElement>(null);
|
|
135
|
+
const inheritedPortalContainer = useStigmerPortalContainer();
|
|
136
|
+
// State, not a ref: children must re-render with the element once it
|
|
137
|
+
// mounts. Until then the value is `null`, which Base UI reads as "wait
|
|
138
|
+
// for a container" — no popup flashes into the body first.
|
|
139
|
+
const [portalTarget, setPortalTarget] = useState<HTMLDivElement | null>(
|
|
140
|
+
null,
|
|
141
|
+
);
|
|
142
|
+
// Set while one Escape keydown is in flight and a popup was open when it
|
|
143
|
+
// started; see the doc comment. Cleared by the cancel it guards, or by a
|
|
144
|
+
// task queued at keydown time when the browser sends no cancel (it may
|
|
145
|
+
// skip one for a repeated Escape without user activation), so it can
|
|
146
|
+
// never swallow a later Escape meant for the dialog.
|
|
147
|
+
const escapeClosesPopupRef = useRef(false);
|
|
105
148
|
|
|
106
149
|
// Sync the native top-layer state to the controlled prop. Runs on mount
|
|
107
150
|
// too, so a shell mounted with `open` already true shows immediately.
|
|
@@ -121,11 +164,28 @@ export function DialogShell({
|
|
|
121
164
|
const handleCancel = useCallback(
|
|
122
165
|
(e: SyntheticEvent<HTMLDialogElement>) => {
|
|
123
166
|
e.preventDefault();
|
|
167
|
+
if (escapeClosesPopupRef.current) {
|
|
168
|
+
escapeClosesPopupRef.current = false;
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
124
171
|
onOpenChange(false);
|
|
125
172
|
},
|
|
126
173
|
[onOpenChange],
|
|
127
174
|
);
|
|
128
175
|
|
|
176
|
+
// Capture phase: runs before the popup's own key handlers, which stop
|
|
177
|
+
// propagation, while the popup is certainly still mounted.
|
|
178
|
+
const handleKeyDownCapture = useCallback(
|
|
179
|
+
(e: KeyboardEvent<HTMLDialogElement>) => {
|
|
180
|
+
if (e.key !== "Escape" || !portalTarget?.hasChildNodes()) return;
|
|
181
|
+
escapeClosesPopupRef.current = true;
|
|
182
|
+
setTimeout(() => {
|
|
183
|
+
escapeClosesPopupRef.current = false;
|
|
184
|
+
}, 0);
|
|
185
|
+
},
|
|
186
|
+
[portalTarget],
|
|
187
|
+
);
|
|
188
|
+
|
|
129
189
|
// A native close the effect did not perform (e.g. a `method="dialog"`
|
|
130
190
|
// form submit) must not leave the controlled state stranded open.
|
|
131
191
|
const handleClose = useCallback(() => {
|
|
@@ -146,6 +206,7 @@ export function DialogShell({
|
|
|
146
206
|
ref={dialogRef}
|
|
147
207
|
open={modal ? undefined : open || undefined}
|
|
148
208
|
onCancel={modal ? handleCancel : undefined}
|
|
209
|
+
onKeyDownCapture={modal ? handleKeyDownCapture : undefined}
|
|
149
210
|
onClose={modal ? handleClose : undefined}
|
|
150
211
|
onClick={modal && dismissOnBackdrop ? handleClick : undefined}
|
|
151
212
|
aria-label={ariaLabel}
|
|
@@ -163,7 +224,23 @@ export function DialogShell({
|
|
|
163
224
|
className,
|
|
164
225
|
)}
|
|
165
226
|
>
|
|
166
|
-
|
|
227
|
+
<PortalContainerContext.Provider
|
|
228
|
+
value={modal ? portalTarget : inheritedPortalContainer}
|
|
229
|
+
>
|
|
230
|
+
{children}
|
|
231
|
+
</PortalContainerContext.Provider>
|
|
232
|
+
{/* A zero-size fixed box at the viewport origin, not an in-flow
|
|
233
|
+
div: a fixed box's containing block is the viewport, so popups
|
|
234
|
+
positioned inside it escape the dialog's own overflow clip (a
|
|
235
|
+
modal dialog scrolls its content) while staying in its top layer.
|
|
236
|
+
An in-flow target left every popup cut off at the dialog's edge
|
|
237
|
+
in Chromium. */}
|
|
238
|
+
{modal && (
|
|
239
|
+
<div
|
|
240
|
+
ref={setPortalTarget}
|
|
241
|
+
className="stg:fixed stg:top-0 stg:left-0 stg:size-0"
|
|
242
|
+
/>
|
|
243
|
+
)}
|
|
167
244
|
</dialog>
|
|
168
245
|
);
|
|
169
246
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The SDK's container for a labelled loading region: the region a skeleton
|
|
5
|
+
* fills while its data is in flight, marked busy and named for a screen reader
|
|
6
|
+
* without a role. A skeleton with no name needs none of this and stays a bare
|
|
7
|
+
* busy element.
|
|
8
|
+
*
|
|
9
|
+
* Why hidden text, not `aria-label`: a `div` with no role may not take
|
|
10
|
+
* `aria-label` (axe `aria-prohibited-attr`, WCAG 4.1.2), so a labelled
|
|
11
|
+
* skeleton fails any page audit it is on screen for (stigmer/stigmer#1653).
|
|
12
|
+
* Why no role: `status` is what this console's phase badges, empty states and
|
|
13
|
+
* notices carry, and `progressbar` its usage gauge, so a skeleton with either
|
|
14
|
+
* would answer locators meant for them.
|
|
15
|
+
*
|
|
16
|
+
* Why not a live region: a loading placeholder is not news. The content that
|
|
17
|
+
* replaces it is what a screen reader user reads, and an announcement per
|
|
18
|
+
* skeleton would talk over every panel that loads at once.
|
|
19
|
+
*
|
|
20
|
+
* `label` names a wordless skeleton ("Loading sessions"). Leave it out, or
|
|
21
|
+
* empty, when the children already say what is loading in visible text, so a
|
|
22
|
+
* screen reader does not read it twice. The hidden text comes first: the
|
|
23
|
+
* containers space their children with `space-y-*` and `gap-*`, and an
|
|
24
|
+
* absolutely positioned first child changes neither, where a trailing one
|
|
25
|
+
* would give the last placeholder a margin it never had. The
|
|
26
|
+
* `stigmer/require-loading-region` lint rule sends a busy element here when
|
|
27
|
+
* axe would refuse its name, or when it takes role="status".
|
|
28
|
+
*
|
|
29
|
+
* @internal Not part of the public API.
|
|
30
|
+
*/
|
|
31
|
+
export function LoadingRegion({
|
|
32
|
+
label,
|
|
33
|
+
className,
|
|
34
|
+
children,
|
|
35
|
+
}: {
|
|
36
|
+
readonly label?: string;
|
|
37
|
+
readonly className?: string;
|
|
38
|
+
readonly children?: ReactNode;
|
|
39
|
+
}) {
|
|
40
|
+
return (
|
|
41
|
+
<div className={className} aria-busy="true">
|
|
42
|
+
{label ? <span className="stg:sr-only">{label}</span> : null}
|
|
43
|
+
{children}
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "Which elements axe-core refuses a name on, for the stigmer/require-loading-region lint rule (tools/eslint-plugin-stigmer/rules/require-loading-region.js), which reports a busy, labelled element with no role written when its tag is in namelessElements. Measured, not judged: src/internal/__tests__/a11y/loading-region-markup.browser.test.ts renders every HTML element, busy, labelled, empty and with no role, through axe's aria-prohibited-attr in Chromium, and fails, printing what axe measured, when these lists disagree. Update a list by copying that output.",
|
|
3
|
+
"axeCore": "4.11.4",
|
|
4
|
+
"namelessElements": [
|
|
5
|
+
"abbr",
|
|
6
|
+
"address",
|
|
7
|
+
"b",
|
|
8
|
+
"bdi",
|
|
9
|
+
"bdo",
|
|
10
|
+
"blockquote",
|
|
11
|
+
"br",
|
|
12
|
+
"caption",
|
|
13
|
+
"cite",
|
|
14
|
+
"code",
|
|
15
|
+
"col",
|
|
16
|
+
"colgroup",
|
|
17
|
+
"data",
|
|
18
|
+
"del",
|
|
19
|
+
"div",
|
|
20
|
+
"em",
|
|
21
|
+
"figcaption",
|
|
22
|
+
"hgroup",
|
|
23
|
+
"i",
|
|
24
|
+
"ins",
|
|
25
|
+
"kbd",
|
|
26
|
+
"legend",
|
|
27
|
+
"map",
|
|
28
|
+
"mark",
|
|
29
|
+
"p",
|
|
30
|
+
"picture",
|
|
31
|
+
"pre",
|
|
32
|
+
"q",
|
|
33
|
+
"rt",
|
|
34
|
+
"ruby",
|
|
35
|
+
"s",
|
|
36
|
+
"samp",
|
|
37
|
+
"small",
|
|
38
|
+
"span",
|
|
39
|
+
"strong",
|
|
40
|
+
"sub",
|
|
41
|
+
"sup",
|
|
42
|
+
"time",
|
|
43
|
+
"u",
|
|
44
|
+
"var",
|
|
45
|
+
"wbr"
|
|
46
|
+
],
|
|
47
|
+
"elementsLeftToAxe": {
|
|
48
|
+
"a": {
|
|
49
|
+
"reason": "an a with an href is a link, which takes a name; the rule cannot see an href passed in a spread",
|
|
50
|
+
"accepted": "<a id=\"probe\" href=\"#x\" aria-busy=\"true\" aria-label=\"Loading\"></a>"
|
|
51
|
+
},
|
|
52
|
+
"td": {
|
|
53
|
+
"reason": "a table cell takes a name inside a table; axe cannot judge one alone",
|
|
54
|
+
"accepted": "<table><tbody><tr><td id=\"probe\" aria-busy=\"true\" aria-label=\"Loading\"></td></tr></tbody></table>"
|
|
55
|
+
},
|
|
56
|
+
"th": {
|
|
57
|
+
"reason": "a header cell takes a name inside a table; axe cannot judge one alone",
|
|
58
|
+
"accepted": "<table><tbody><tr><th id=\"probe\" aria-busy=\"true\" aria-label=\"Loading\"></th></tr></tbody></table>"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"elementsAxeSkips": {
|
|
62
|
+
"area": "hidden by default",
|
|
63
|
+
"audio": "hidden by default without controls",
|
|
64
|
+
"datalist": "hidden by default",
|
|
65
|
+
"dialog": "hidden until opened",
|
|
66
|
+
"noscript": "not rendered while scripting runs",
|
|
67
|
+
"rp": "hidden by default",
|
|
68
|
+
"template": "inert content",
|
|
69
|
+
"slot": "outside axe's tree"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -97,7 +97,7 @@ export function unwrapEnclosingMarkdownFence(
|
|
|
97
97
|
* blank lines only). Group 1 is the heading text; the match spans through the
|
|
98
98
|
* heading's trailing newline(s) so `body` starts at the first content line.
|
|
99
99
|
*/
|
|
100
|
-
const
|
|
100
|
+
const LEADING_H1_MARKER = /^#[ \t]+/;
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
103
|
* Splits a markdown document into its leading `# H1` title and the remaining
|
|
@@ -115,10 +115,21 @@ export function extractLeadingH1(markdown: string): {
|
|
|
115
115
|
readonly title: string | null;
|
|
116
116
|
readonly body: string;
|
|
117
117
|
} {
|
|
118
|
+
// Read line by line: a single pattern over the heading and the newlines
|
|
119
|
+
// after it backtracks on a long run of spaces.
|
|
118
120
|
const trimmed = markdown.trim();
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
const lineEnd = trimmed.indexOf("\n");
|
|
122
|
+
const firstLine = lineEnd === -1 ? trimmed : trimmed.slice(0, lineEnd);
|
|
123
|
+
const marker = LEADING_H1_MARKER.exec(firstLine);
|
|
124
|
+
if (!marker) return { title: null, body: markdown };
|
|
125
|
+
const rawTitle = firstLine.slice(marker[0].length).replace(/\r$/, "");
|
|
126
|
+
let titleEnd = rawTitle.length;
|
|
127
|
+
while (titleEnd > 0 && (rawTitle[titleEnd - 1] === " " || rawTitle[titleEnd - 1] === "\t")) titleEnd -= 1;
|
|
128
|
+
const title = rawTitle.slice(0, titleEnd);
|
|
129
|
+
if (title === "") return { title: null, body: markdown };
|
|
130
|
+
let bodyStart = lineEnd === -1 ? trimmed.length : lineEnd + 1;
|
|
131
|
+
while (trimmed[bodyStart] === "\n") bodyStart += 1;
|
|
132
|
+
return { title, body: trimmed.slice(bodyStart) };
|
|
122
133
|
}
|
|
123
134
|
|
|
124
135
|
/**
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `value` without its trailing run of `char`. A `/x+$/` regex rescans the run
|
|
3
|
+
* from every starting position, so a long run costs quadratic time; this walks
|
|
4
|
+
* it once.
|
|
5
|
+
*/
|
|
6
|
+
export function trimTrailing(value: string, char: string): string {
|
|
7
|
+
let end = value.length;
|
|
8
|
+
while (end > 0 && value[end - 1] === char) end -= 1;
|
|
9
|
+
return end === value.length ? value : value.slice(0, end);
|
|
10
|
+
}
|
|
@@ -21,6 +21,7 @@ import { RoleSelector } from "../iam-policy/RoleSelector.js";
|
|
|
21
21
|
import { useOwnerAssignment } from "../iam-policy/useOwnerAssignment.js";
|
|
22
22
|
import { SpinnerIcon } from "../internal/SpinnerIcon.js";
|
|
23
23
|
import { useCopyFeedback } from "../internal/useCopyFeedback.js";
|
|
24
|
+
import { LoadingRegion } from "../internal/LoadingRegion.js";
|
|
24
25
|
|
|
25
26
|
// ---------------------------------------------------------------------------
|
|
26
27
|
// Public API
|
|
@@ -115,10 +116,9 @@ export function InvitationManager({
|
|
|
115
116
|
|
|
116
117
|
if (isLoading) {
|
|
117
118
|
return (
|
|
118
|
-
<
|
|
119
|
+
<LoadingRegion
|
|
119
120
|
className={cn("stg:space-y-2", className)}
|
|
120
|
-
|
|
121
|
-
aria-label="Loading invitations"
|
|
121
|
+
label="Loading invitations"
|
|
122
122
|
>
|
|
123
123
|
{Array.from({ length: 2 }, (_, i) => (
|
|
124
124
|
<div
|
|
@@ -126,7 +126,7 @@ export function InvitationManager({
|
|
|
126
126
|
className="stg:bg-muted-subtle stg:h-14 stg:animate-pulse stg:rounded-lg"
|
|
127
127
|
/>
|
|
128
128
|
))}
|
|
129
|
-
</
|
|
129
|
+
</LoadingRegion>
|
|
130
130
|
);
|
|
131
131
|
}
|
|
132
132
|
|