@oxy.so/bloom 7.1.4 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/character-runtime/README.md +19 -114
- package/assets/character-runtime/legacy-engine.mjs +54 -406
- package/assets/character-runtime/legacy-geometry.mjs +85 -242
- package/assets/character-runtime/legacy-worker.mjs +23 -82
- package/assets/character-runtime/managed-avatar.mjs +18 -12
- package/assets/character-runtime/render-budget.mjs +11 -6
- package/assets/character-runtime/runtime.mjs +295 -744
- package/docs/adoption-matrix.mdx +12 -11
- package/docs/agent-avatar.mdx +8 -45
- package/docs/agent-creator.mdx +3 -13
- package/docs/app-shell.mdx +26 -2
- package/docs/appearance.mdx +16 -1
- package/docs/content-panel.mdx +4 -0
- package/docs/mail-thread.mdx +8 -0
- package/docs/page-footer.mdx +60 -0
- package/docs/sidebar.mdx +1 -1
- package/lib/commonjs/agent-avatar/AgentAvatar.js +1 -1
- package/lib/commonjs/agent-avatar/AgentAvatar.js.map +1 -1
- package/lib/commonjs/agent-avatar/CharacterAvatar.js +1 -2
- package/lib/commonjs/agent-avatar/CharacterAvatar.js.map +1 -1
- package/lib/commonjs/agent-avatar/config-character.js +0 -4
- package/lib/commonjs/agent-avatar/config-character.js.map +1 -1
- package/lib/commonjs/agent-avatar/legacy-recipe.js +6 -19
- package/lib/commonjs/agent-avatar/legacy-recipe.js.map +1 -1
- package/lib/commonjs/agent-creator/AgentCreatorBase.js +107 -67
- package/lib/commonjs/agent-creator/AgentCreatorBase.js.map +1 -1
- package/lib/commonjs/agent-creator/CharacterControls.js +5 -23
- package/lib/commonjs/agent-creator/CharacterControls.js.map +1 -1
- package/lib/commonjs/agent-creator/EmotionPicker.js +1 -8
- package/lib/commonjs/agent-creator/EmotionPicker.js.map +1 -1
- package/lib/commonjs/agent-creator/ShapeSilhouette.js +1 -8
- package/lib/commonjs/agent-creator/ShapeSilhouette.js.map +1 -1
- package/lib/commonjs/agent-creator/constants.js +17 -16
- package/lib/commonjs/agent-creator/constants.js.map +1 -1
- package/lib/commonjs/agent-creator/messages.js +1 -1
- package/lib/commonjs/agent-creator/messages.js.map +1 -1
- package/lib/commonjs/app-shell/AppShell.js +3 -2
- package/lib/commonjs/app-shell/AppShell.js.map +1 -1
- package/lib/commonjs/app-shell/AppShellBars.js +8 -5
- package/lib/commonjs/app-shell/AppShellBars.js.map +1 -1
- package/lib/commonjs/app-shell/AppShellEngine.js +81 -36
- package/lib/commonjs/app-shell/AppShellEngine.js.map +1 -1
- package/lib/commonjs/appearance/BloomScope.js +8 -3
- package/lib/commonjs/appearance/BloomScope.js.map +1 -1
- package/lib/commonjs/appearance/context.js.map +1 -1
- package/lib/commonjs/content-panel/ContentPanel.js +34 -23
- package/lib/commonjs/content-panel/ContentPanel.js.map +1 -1
- package/lib/commonjs/content-panel/ContentPanel.web.js +39 -17
- package/lib/commonjs/content-panel/ContentPanel.web.js.map +1 -1
- package/lib/commonjs/design-tokens/shapes.js +2 -2
- package/lib/commonjs/design-tokens/shapes.js.map +1 -1
- package/lib/commonjs/design-tokens/tokens.json +2 -2
- package/lib/commonjs/index.js +939 -927
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +939 -927
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/commonjs/locale/translations/ar.js +1 -1
- package/lib/commonjs/locale/translations/ar.js.map +1 -1
- package/lib/commonjs/locale/translations/bn.js +1 -1
- package/lib/commonjs/locale/translations/bn.js.map +1 -1
- package/lib/commonjs/locale/translations/ca.js +1 -1
- package/lib/commonjs/locale/translations/ca.js.map +1 -1
- package/lib/commonjs/locale/translations/de.js +1 -1
- package/lib/commonjs/locale/translations/de.js.map +1 -1
- package/lib/commonjs/locale/translations/es.js +1 -1
- package/lib/commonjs/locale/translations/es.js.map +1 -1
- package/lib/commonjs/locale/translations/fr.js +1 -1
- package/lib/commonjs/locale/translations/fr.js.map +1 -1
- package/lib/commonjs/locale/translations/hi.js +1 -1
- package/lib/commonjs/locale/translations/hi.js.map +1 -1
- package/lib/commonjs/locale/translations/id.js +1 -1
- package/lib/commonjs/locale/translations/id.js.map +1 -1
- package/lib/commonjs/locale/translations/it.js +1 -1
- package/lib/commonjs/locale/translations/it.js.map +1 -1
- package/lib/commonjs/locale/translations/ja.js +1 -1
- package/lib/commonjs/locale/translations/ja.js.map +1 -1
- package/lib/commonjs/locale/translations/pt.js +1 -1
- package/lib/commonjs/locale/translations/pt.js.map +1 -1
- package/lib/commonjs/locale/translations/ru.js +1 -1
- package/lib/commonjs/locale/translations/ru.js.map +1 -1
- package/lib/commonjs/locale/translations/tr.js +1 -1
- package/lib/commonjs/locale/translations/tr.js.map +1 -1
- package/lib/commonjs/locale/translations/zh.js +1 -1
- package/lib/commonjs/locale/translations/zh.js.map +1 -1
- package/lib/commonjs/mail-thread/MailMessage.js +8 -14
- package/lib/commonjs/mail-thread/MailMessage.js.map +1 -1
- package/lib/commonjs/mail-thread/MailThread.js +6 -2
- package/lib/commonjs/mail-thread/MailThread.js.map +1 -1
- package/lib/commonjs/mail-thread/shared.js +2 -1
- package/lib/commonjs/mail-thread/shared.js.map +1 -1
- package/lib/commonjs/page-footer/PageFooter.js +137 -0
- package/lib/commonjs/page-footer/PageFooter.js.map +1 -0
- package/lib/commonjs/page-footer/PageFooterProvider.js +22 -0
- package/lib/commonjs/page-footer/PageFooterProvider.js.map +1 -0
- package/lib/commonjs/page-footer/context.js +11 -0
- package/lib/commonjs/page-footer/context.js.map +1 -0
- package/lib/commonjs/page-footer/index.js +27 -0
- package/lib/commonjs/page-footer/index.js.map +1 -0
- package/lib/commonjs/page-footer/types.js +6 -0
- package/lib/commonjs/page-footer/types.js.map +1 -0
- package/lib/commonjs/page-footer/use-page-footer-inset.js +19 -0
- package/lib/commonjs/page-footer/use-page-footer-inset.js.map +1 -0
- package/lib/commonjs/sidebar/Sidebar.js +6 -5
- package/lib/commonjs/sidebar/Sidebar.js.map +1 -1
- package/lib/commonjs/styles/panel-chrome.js +15 -1
- package/lib/commonjs/styles/panel-chrome.js.map +1 -1
- package/lib/module/agent-avatar/AgentAvatar.js +1 -1
- package/lib/module/agent-avatar/AgentAvatar.js.map +1 -1
- package/lib/module/agent-avatar/CharacterAvatar.js +1 -2
- package/lib/module/agent-avatar/CharacterAvatar.js.map +1 -1
- package/lib/module/agent-avatar/config-character.js +0 -4
- package/lib/module/agent-avatar/config-character.js.map +1 -1
- package/lib/module/agent-avatar/legacy-recipe.js +6 -19
- package/lib/module/agent-avatar/legacy-recipe.js.map +1 -1
- package/lib/module/agent-creator/AgentCreatorBase.js +109 -69
- package/lib/module/agent-creator/AgentCreatorBase.js.map +1 -1
- package/lib/module/agent-creator/CharacterControls.js +6 -24
- package/lib/module/agent-creator/CharacterControls.js.map +1 -1
- package/lib/module/agent-creator/EmotionPicker.js +1 -8
- package/lib/module/agent-creator/EmotionPicker.js.map +1 -1
- package/lib/module/agent-creator/ShapeSilhouette.js +1 -8
- package/lib/module/agent-creator/ShapeSilhouette.js.map +1 -1
- package/lib/module/agent-creator/constants.js +16 -8
- package/lib/module/agent-creator/constants.js.map +1 -1
- package/lib/module/agent-creator/messages.js +1 -1
- package/lib/module/agent-creator/messages.js.map +1 -1
- package/lib/module/app-shell/AppShell.js +3 -2
- package/lib/module/app-shell/AppShell.js.map +1 -1
- package/lib/module/app-shell/AppShellBars.js +8 -5
- package/lib/module/app-shell/AppShellBars.js.map +1 -1
- package/lib/module/app-shell/AppShellEngine.js +81 -36
- package/lib/module/app-shell/AppShellEngine.js.map +1 -1
- package/lib/module/appearance/BloomScope.js +8 -3
- package/lib/module/appearance/BloomScope.js.map +1 -1
- package/lib/module/appearance/context.js.map +1 -1
- package/lib/module/content-panel/ContentPanel.js +35 -24
- package/lib/module/content-panel/ContentPanel.js.map +1 -1
- package/lib/module/content-panel/ContentPanel.web.js +41 -19
- package/lib/module/content-panel/ContentPanel.web.js.map +1 -1
- package/lib/module/design-tokens/shapes.js +2 -2
- package/lib/module/design-tokens/shapes.js.map +1 -1
- package/lib/module/design-tokens/tokens.json +2 -2
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +1 -0
- package/lib/module/index.web.js.map +1 -1
- package/lib/module/locale/translations/ar.js +1 -1
- package/lib/module/locale/translations/ar.js.map +1 -1
- package/lib/module/locale/translations/bn.js +1 -1
- package/lib/module/locale/translations/bn.js.map +1 -1
- package/lib/module/locale/translations/ca.js +1 -1
- package/lib/module/locale/translations/ca.js.map +1 -1
- package/lib/module/locale/translations/de.js +1 -1
- package/lib/module/locale/translations/de.js.map +1 -1
- package/lib/module/locale/translations/es.js +1 -1
- package/lib/module/locale/translations/es.js.map +1 -1
- package/lib/module/locale/translations/fr.js +1 -1
- package/lib/module/locale/translations/fr.js.map +1 -1
- package/lib/module/locale/translations/hi.js +1 -1
- package/lib/module/locale/translations/hi.js.map +1 -1
- package/lib/module/locale/translations/id.js +1 -1
- package/lib/module/locale/translations/id.js.map +1 -1
- package/lib/module/locale/translations/it.js +1 -1
- package/lib/module/locale/translations/it.js.map +1 -1
- package/lib/module/locale/translations/ja.js +1 -1
- package/lib/module/locale/translations/ja.js.map +1 -1
- package/lib/module/locale/translations/pt.js +1 -1
- package/lib/module/locale/translations/pt.js.map +1 -1
- package/lib/module/locale/translations/ru.js +1 -1
- package/lib/module/locale/translations/ru.js.map +1 -1
- package/lib/module/locale/translations/tr.js +1 -1
- package/lib/module/locale/translations/tr.js.map +1 -1
- package/lib/module/locale/translations/zh.js +1 -1
- package/lib/module/locale/translations/zh.js.map +1 -1
- package/lib/module/mail-thread/MailMessage.js +8 -14
- package/lib/module/mail-thread/MailMessage.js.map +1 -1
- package/lib/module/mail-thread/MailThread.js +6 -2
- package/lib/module/mail-thread/MailThread.js.map +1 -1
- package/lib/module/mail-thread/shared.js +2 -1
- package/lib/module/mail-thread/shared.js.map +1 -1
- package/lib/module/page-footer/PageFooter.js +132 -0
- package/lib/module/page-footer/PageFooter.js.map +1 -0
- package/lib/module/page-footer/PageFooterProvider.js +18 -0
- package/lib/module/page-footer/PageFooterProvider.js.map +1 -0
- package/lib/module/page-footer/context.js +7 -0
- package/lib/module/page-footer/context.js.map +1 -0
- package/lib/module/page-footer/index.js +6 -0
- package/lib/module/page-footer/index.js.map +1 -0
- package/lib/module/page-footer/types.js +4 -0
- package/lib/module/page-footer/types.js.map +1 -0
- package/lib/module/page-footer/use-page-footer-inset.js +16 -0
- package/lib/module/page-footer/use-page-footer-inset.js.map +1 -0
- package/lib/module/sidebar/Sidebar.js +6 -5
- package/lib/module/sidebar/Sidebar.js.map +1 -1
- package/lib/module/styles/panel-chrome.js +14 -1
- package/lib/module/styles/panel-chrome.js.map +1 -1
- package/lib/typescript/commonjs/agent-avatar/CharacterAvatar.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-avatar/config-character.d.ts +0 -4
- package/lib/typescript/commonjs/agent-avatar/config-character.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-avatar/legacy-recipe.d.ts +10 -2
- package/lib/typescript/commonjs/agent-avatar/legacy-recipe.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-creator/AgentCreatorBase.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-creator/CharacterControls.d.ts +1 -2
- package/lib/typescript/commonjs/agent-creator/CharacterControls.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-creator/EmotionPicker.d.ts +0 -1
- package/lib/typescript/commonjs/agent-creator/EmotionPicker.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-creator/ShapeSilhouette.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-creator/constants.d.ts +15 -7
- package/lib/typescript/commonjs/agent-creator/constants.d.ts.map +1 -1
- package/lib/typescript/commonjs/agent-creator/messages.d.ts.map +1 -1
- package/lib/typescript/commonjs/app-shell/AppShellBars.d.ts +4 -0
- package/lib/typescript/commonjs/app-shell/AppShellBars.d.ts.map +1 -1
- package/lib/typescript/commonjs/app-shell/AppShellEngine.d.ts.map +1 -1
- package/lib/typescript/commonjs/app-shell/types.d.ts +11 -3
- package/lib/typescript/commonjs/app-shell/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/appearance/BloomScope.d.ts +1 -1
- package/lib/typescript/commonjs/appearance/BloomScope.d.ts.map +1 -1
- package/lib/typescript/commonjs/appearance/context.d.ts +2 -2
- package/lib/typescript/commonjs/appearance/context.d.ts.map +1 -1
- package/lib/typescript/commonjs/appearance/types.d.ts +4 -1
- package/lib/typescript/commonjs/appearance/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/content-panel/ContentPanel.d.ts +3 -4
- package/lib/typescript/commonjs/content-panel/ContentPanel.d.ts.map +1 -1
- package/lib/typescript/commonjs/content-panel/ContentPanel.web.d.ts +1 -1
- package/lib/typescript/commonjs/content-panel/ContentPanel.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/content-panel/types.d.ts +2 -2
- package/lib/typescript/commonjs/design-tokens/shapes.d.ts +2 -2
- package/lib/typescript/commonjs/index.d.ts +1 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +1 -0
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/mail-thread/MailMessage.d.ts.map +1 -1
- package/lib/typescript/commonjs/mail-thread/MailThread.d.ts +1 -1
- package/lib/typescript/commonjs/mail-thread/MailThread.d.ts.map +1 -1
- package/lib/typescript/commonjs/mail-thread/shared.d.ts +1 -1
- package/lib/typescript/commonjs/mail-thread/shared.d.ts.map +1 -1
- package/lib/typescript/commonjs/mail-thread/types.d.ts +2 -0
- package/lib/typescript/commonjs/mail-thread/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/page-footer/PageFooter.d.ts +7 -0
- package/lib/typescript/commonjs/page-footer/PageFooter.d.ts.map +1 -0
- package/lib/typescript/commonjs/page-footer/PageFooterProvider.d.ts +4 -0
- package/lib/typescript/commonjs/page-footer/PageFooterProvider.d.ts.map +1 -0
- package/lib/typescript/commonjs/page-footer/context.d.ts +3 -0
- package/lib/typescript/commonjs/page-footer/context.d.ts.map +1 -0
- package/lib/typescript/commonjs/page-footer/index.d.ts +5 -0
- package/lib/typescript/commonjs/page-footer/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/page-footer/types.d.ts +26 -0
- package/lib/typescript/commonjs/page-footer/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/page-footer/use-page-footer-inset.d.ts +7 -0
- package/lib/typescript/commonjs/page-footer/use-page-footer-inset.d.ts.map +1 -0
- package/lib/typescript/commonjs/sidebar/Sidebar.d.ts.map +1 -1
- package/lib/typescript/commonjs/sidebar/types.d.ts +1 -1
- package/lib/typescript/commonjs/styles/panel-chrome.d.ts +5 -0
- package/lib/typescript/commonjs/styles/panel-chrome.d.ts.map +1 -1
- package/lib/typescript/module/agent-avatar/CharacterAvatar.d.ts.map +1 -1
- package/lib/typescript/module/agent-avatar/config-character.d.ts +0 -4
- package/lib/typescript/module/agent-avatar/config-character.d.ts.map +1 -1
- package/lib/typescript/module/agent-avatar/legacy-recipe.d.ts +10 -2
- package/lib/typescript/module/agent-avatar/legacy-recipe.d.ts.map +1 -1
- package/lib/typescript/module/agent-creator/AgentCreatorBase.d.ts.map +1 -1
- package/lib/typescript/module/agent-creator/CharacterControls.d.ts +1 -2
- package/lib/typescript/module/agent-creator/CharacterControls.d.ts.map +1 -1
- package/lib/typescript/module/agent-creator/EmotionPicker.d.ts +0 -1
- package/lib/typescript/module/agent-creator/EmotionPicker.d.ts.map +1 -1
- package/lib/typescript/module/agent-creator/ShapeSilhouette.d.ts.map +1 -1
- package/lib/typescript/module/agent-creator/constants.d.ts +15 -7
- package/lib/typescript/module/agent-creator/constants.d.ts.map +1 -1
- package/lib/typescript/module/agent-creator/messages.d.ts.map +1 -1
- package/lib/typescript/module/app-shell/AppShellBars.d.ts +4 -0
- package/lib/typescript/module/app-shell/AppShellBars.d.ts.map +1 -1
- package/lib/typescript/module/app-shell/AppShellEngine.d.ts.map +1 -1
- package/lib/typescript/module/app-shell/types.d.ts +11 -3
- package/lib/typescript/module/app-shell/types.d.ts.map +1 -1
- package/lib/typescript/module/appearance/BloomScope.d.ts +1 -1
- package/lib/typescript/module/appearance/BloomScope.d.ts.map +1 -1
- package/lib/typescript/module/appearance/context.d.ts +2 -2
- package/lib/typescript/module/appearance/context.d.ts.map +1 -1
- package/lib/typescript/module/appearance/types.d.ts +4 -1
- package/lib/typescript/module/appearance/types.d.ts.map +1 -1
- package/lib/typescript/module/content-panel/ContentPanel.d.ts +3 -4
- package/lib/typescript/module/content-panel/ContentPanel.d.ts.map +1 -1
- package/lib/typescript/module/content-panel/ContentPanel.web.d.ts +1 -1
- package/lib/typescript/module/content-panel/ContentPanel.web.d.ts.map +1 -1
- package/lib/typescript/module/content-panel/types.d.ts +2 -2
- package/lib/typescript/module/design-tokens/shapes.d.ts +2 -2
- package/lib/typescript/module/index.d.ts +1 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +1 -0
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/lib/typescript/module/mail-thread/MailMessage.d.ts.map +1 -1
- package/lib/typescript/module/mail-thread/MailThread.d.ts +1 -1
- package/lib/typescript/module/mail-thread/MailThread.d.ts.map +1 -1
- package/lib/typescript/module/mail-thread/shared.d.ts +1 -1
- package/lib/typescript/module/mail-thread/shared.d.ts.map +1 -1
- package/lib/typescript/module/mail-thread/types.d.ts +2 -0
- package/lib/typescript/module/mail-thread/types.d.ts.map +1 -1
- package/lib/typescript/module/page-footer/PageFooter.d.ts +7 -0
- package/lib/typescript/module/page-footer/PageFooter.d.ts.map +1 -0
- package/lib/typescript/module/page-footer/PageFooterProvider.d.ts +4 -0
- package/lib/typescript/module/page-footer/PageFooterProvider.d.ts.map +1 -0
- package/lib/typescript/module/page-footer/context.d.ts +3 -0
- package/lib/typescript/module/page-footer/context.d.ts.map +1 -0
- package/lib/typescript/module/page-footer/index.d.ts +5 -0
- package/lib/typescript/module/page-footer/index.d.ts.map +1 -0
- package/lib/typescript/module/page-footer/types.d.ts +26 -0
- package/lib/typescript/module/page-footer/types.d.ts.map +1 -0
- package/lib/typescript/module/page-footer/use-page-footer-inset.d.ts +7 -0
- package/lib/typescript/module/page-footer/use-page-footer-inset.d.ts.map +1 -0
- package/lib/typescript/module/sidebar/Sidebar.d.ts.map +1 -1
- package/lib/typescript/module/sidebar/types.d.ts +1 -1
- package/lib/typescript/module/styles/panel-chrome.d.ts +5 -0
- package/lib/typescript/module/styles/panel-chrome.d.ts.map +1 -1
- package/package.json +18 -1
- package/src/__tests__/support/adoption-matrix.ts +683 -0
- package/src/__tests__/support/card-surface.ts +25 -0
- package/src/__tests__/support/collision-fixture-barrel.ts +20 -0
- package/src/__tests__/support/commerce-harness.tsx +97 -0
- package/src/__tests__/support/composite.ts +68 -0
- package/src/__tests__/support/constructed-style-sheets.ts +68 -0
- package/src/__tests__/support/messages-in.ts +10 -0
- package/src/__tests__/support/press-host.ts +30 -0
- package/src/__tests__/support/rendered-style.ts +99 -0
- package/src/__tests__/support/unread-hook-fixture.ts +33 -0
- package/src/__tests__/support/worklet-capture-fixture.tsx +28 -0
- package/src/agent-avatar/AgentAvatar.tsx +1 -1
- package/src/agent-avatar/CharacterAvatar.tsx +1 -4
- package/src/agent-avatar/__tests__/artwork-golden.json +774 -0
- package/src/agent-avatar/config-character.ts +6 -39
- package/src/agent-avatar/legacy-recipe.ts +6 -34
- package/src/agent-creator/AgentCreatorBase.tsx +152 -121
- package/src/agent-creator/CharacterControls.tsx +14 -39
- package/src/agent-creator/EmotionPicker.tsx +16 -55
- package/src/agent-creator/ShapeSilhouette.tsx +1 -16
- package/src/agent-creator/__tests__/support/character-runtime-fixture.tsx +26 -0
- package/src/agent-creator/constants.ts +14 -47
- package/src/agent-creator/messages.ts +1 -2
- package/src/app-shell/AppShell.tsx +2 -2
- package/src/app-shell/AppShellBars.tsx +6 -4
- package/src/app-shell/AppShellEngine.tsx +51 -18
- package/src/app-shell/types.ts +11 -3
- package/src/appearance/BloomScope.tsx +5 -2
- package/src/appearance/context.ts +2 -2
- package/src/appearance/types.ts +4 -1
- package/src/content-panel/ContentPanel.tsx +32 -25
- package/src/content-panel/ContentPanel.web.tsx +32 -23
- package/src/content-panel/types.ts +2 -2
- package/src/design-tokens/shapes.ts +1 -1
- package/src/design-tokens/tokens.json +2 -2
- package/src/index.ts +1 -0
- package/src/index.web.ts +1 -0
- package/src/locale/translations/ar.ts +1 -1
- package/src/locale/translations/bn.ts +1 -1
- package/src/locale/translations/ca.ts +1 -1
- package/src/locale/translations/de.ts +1 -1
- package/src/locale/translations/es.ts +1 -1
- package/src/locale/translations/fr.ts +1 -1
- package/src/locale/translations/hi.ts +1 -1
- package/src/locale/translations/id.ts +1 -1
- package/src/locale/translations/it.ts +1 -1
- package/src/locale/translations/ja.ts +1 -1
- package/src/locale/translations/pt.ts +1 -1
- package/src/locale/translations/ru.ts +1 -1
- package/src/locale/translations/tr.ts +1 -1
- package/src/locale/translations/zh.ts +1 -1
- package/src/mail-thread/MailMessage.tsx +9 -11
- package/src/mail-thread/MailThread.tsx +3 -1
- package/src/mail-thread/shared.ts +2 -1
- package/src/mail-thread/types.ts +2 -0
- package/src/page-footer/PageFooter.tsx +96 -0
- package/src/page-footer/PageFooterProvider.tsx +9 -0
- package/src/page-footer/context.ts +6 -0
- package/src/page-footer/index.ts +4 -0
- package/src/page-footer/types.ts +26 -0
- package/src/page-footer/use-page-footer-inset.ts +17 -0
- package/src/sidebar/Sidebar.tsx +5 -4
- package/src/sidebar/types.ts +1 -1
- package/src/styles/panel-chrome.ts +9 -1
- package/src/theme/__tests__/__fixtures__/golden-resolved-tokens.json +9346 -0
- package/src/theme/__tests__/__fixtures__/tonal-glass-primary-failures.json +69 -0
- package/src/theme/__tests__/fixtures/color-engine-golden.json +1 -0
- package/assets/character-runtime/authored-parts.mjs +0 -754
- package/assets/character-runtime/catalog-parts.mjs +0 -362
- package/assets/character-runtime/character-recipe.mjs +0 -247
- package/assets/character-runtime/clippo-geometry.mjs +0 -679
- package/assets/character-runtime/controller-mode.mjs +0 -208
- package/assets/character-runtime/cyclops-geometry.mjs +0 -180
- package/assets/character-runtime/migrated-contours.mjs +0 -2067
- package/assets/character-runtime/migrated-faces.mjs +0 -59
- package/assets/character-runtime/pose-transition.mjs +0 -523
- package/assets/character-runtime/preparation-cache.mjs +0 -60
- package/assets/character-runtime/render-errors.mjs +0 -180
- package/assets/character-runtime/resolution.mjs +0 -10
- package/assets/character-runtime/sha256.mjs +0 -44
- package/assets/character-runtime/shared-programs.mjs +0 -534
- package/assets/character-runtime/shared-surface.mjs +0 -490
- package/assets/character-runtime/shared-textures.mjs +0 -420
- package/assets/character-runtime/thumbnails/eyes/todd.png +0 -0
- package/lib/commonjs/agent-avatar/character-colors.js +0 -19
- package/lib/commonjs/agent-avatar/character-colors.js.map +0 -1
- package/lib/commonjs/agent-avatar/character-shapes.js +0 -106
- package/lib/commonjs/agent-avatar/character-shapes.js.map +0 -1
- package/lib/commonjs/agent-creator/ClippoArtwork.js +0 -63
- package/lib/commonjs/agent-creator/ClippoArtwork.js.map +0 -1
- package/lib/commonjs/agent-creator/CyclopsArtwork.js +0 -45
- package/lib/commonjs/agent-creator/CyclopsArtwork.js.map +0 -1
- package/lib/commonjs/agent-creator/ToddArtwork.js +0 -29
- package/lib/commonjs/agent-creator/ToddArtwork.js.map +0 -1
- package/lib/module/agent-avatar/character-colors.js +0 -15
- package/lib/module/agent-avatar/character-colors.js.map +0 -1
- package/lib/module/agent-avatar/character-shapes.js +0 -97
- package/lib/module/agent-avatar/character-shapes.js.map +0 -1
- package/lib/module/agent-creator/ClippoArtwork.js +0 -59
- package/lib/module/agent-creator/ClippoArtwork.js.map +0 -1
- package/lib/module/agent-creator/CyclopsArtwork.js +0 -41
- package/lib/module/agent-creator/CyclopsArtwork.js.map +0 -1
- package/lib/module/agent-creator/ToddArtwork.js +0 -25
- package/lib/module/agent-creator/ToddArtwork.js.map +0 -1
- package/lib/typescript/commonjs/agent-avatar/character-colors.d.ts +0 -13
- package/lib/typescript/commonjs/agent-avatar/character-colors.d.ts.map +0 -1
- package/lib/typescript/commonjs/agent-avatar/character-shapes.d.ts +0 -19
- package/lib/typescript/commonjs/agent-avatar/character-shapes.d.ts.map +0 -1
- package/lib/typescript/commonjs/agent-creator/ClippoArtwork.d.ts +0 -6
- package/lib/typescript/commonjs/agent-creator/ClippoArtwork.d.ts.map +0 -1
- package/lib/typescript/commonjs/agent-creator/CyclopsArtwork.d.ts +0 -5
- package/lib/typescript/commonjs/agent-creator/CyclopsArtwork.d.ts.map +0 -1
- package/lib/typescript/commonjs/agent-creator/ToddArtwork.d.ts +0 -6
- package/lib/typescript/commonjs/agent-creator/ToddArtwork.d.ts.map +0 -1
- package/lib/typescript/module/agent-avatar/character-colors.d.ts +0 -13
- package/lib/typescript/module/agent-avatar/character-colors.d.ts.map +0 -1
- package/lib/typescript/module/agent-avatar/character-shapes.d.ts +0 -19
- package/lib/typescript/module/agent-avatar/character-shapes.d.ts.map +0 -1
- package/lib/typescript/module/agent-creator/ClippoArtwork.d.ts +0 -6
- package/lib/typescript/module/agent-creator/ClippoArtwork.d.ts.map +0 -1
- package/lib/typescript/module/agent-creator/CyclopsArtwork.d.ts +0 -5
- package/lib/typescript/module/agent-creator/CyclopsArtwork.d.ts.map +0 -1
- package/lib/typescript/module/agent-creator/ToddArtwork.d.ts +0 -6
- package/lib/typescript/module/agent-creator/ToddArtwork.d.ts.map +0 -1
- package/src/agent-avatar/character-colors.ts +0 -12
- package/src/agent-avatar/character-shapes.ts +0 -122
- package/src/agent-creator/ClippoArtwork.tsx +0 -49
- package/src/agent-creator/CyclopsArtwork.tsx +0 -27
- package/src/agent-creator/ToddArtwork.tsx +0 -24
|
@@ -12,26 +12,13 @@ import Animated, {
|
|
|
12
12
|
} from 'react-native-reanimated';
|
|
13
13
|
import { EYES, type AvatarConfig } from '../agent-avatar';
|
|
14
14
|
import { AgentFace } from '../agent-avatar/AgentFace';
|
|
15
|
-
import {
|
|
16
|
-
import { CyclopsArtwork } from './CyclopsArtwork';
|
|
17
|
-
import {
|
|
18
|
-
StyledImage,
|
|
19
|
-
StyledPressable,
|
|
20
|
-
StyledView,
|
|
21
|
-
} from '../styles/styled-primitives';
|
|
15
|
+
import { StyledImage, StyledPressable, StyledView } from '../styles/styled-primitives';
|
|
22
16
|
import { useTheme } from '../theme/use-theme';
|
|
23
17
|
import { useAgentCreatorMessages } from './context';
|
|
24
18
|
import { useTrackEvents } from './use-track-events';
|
|
25
19
|
|
|
26
20
|
const AnimatedView = Animated.createAnimatedComponent(StyledView);
|
|
27
|
-
export type EmotionChoice = {
|
|
28
|
-
id: string;
|
|
29
|
-
label: string;
|
|
30
|
-
config: AvatarConfig;
|
|
31
|
-
disabled?: boolean;
|
|
32
|
-
thumbnail?: string;
|
|
33
|
-
artwork?: 'clippo' | 'cyclops';
|
|
34
|
-
};
|
|
21
|
+
export type EmotionChoice = { id: string; label: string; config: AvatarConfig; disabled?: boolean; thumbnail?: string };
|
|
35
22
|
function Emotion({
|
|
36
23
|
config,
|
|
37
24
|
choice,
|
|
@@ -84,40 +71,21 @@ function Emotion({
|
|
|
84
71
|
pointerEvents="auto"
|
|
85
72
|
className={`pointer-events-auto flex size-[34px] cursor-pointer items-center justify-center overflow-hidden rounded-full border-2 outline-none transition-[border-color,box-shadow] hover:ring-2 hover:ring-border-button-hover focus-visible:ring-2 focus-visible:ring-border-focus-ring ${active ? 'border-foreground-icon-secondary' : 'border-transparent'}`}
|
|
86
73
|
style={{
|
|
87
|
-
backgroundColor:
|
|
88
|
-
backgroundColor ??
|
|
89
|
-
`hsl(${config.hue}, ${config.saturation}%, ${config.lightness ?? 80}%)`,
|
|
74
|
+
backgroundColor: backgroundColor ?? `hsl(${config.hue}, ${config.saturation}%, ${config.lightness ?? 80}%)`,
|
|
90
75
|
borderColor: active ? colors.icon : 'transparent',
|
|
91
76
|
}}
|
|
92
77
|
>
|
|
93
|
-
{choice.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
height: 27,
|
|
105
|
-
opacity: choice.disabled ? 0.35 : 1,
|
|
106
|
-
}}
|
|
107
|
-
/>
|
|
108
|
-
) : (
|
|
109
|
-
<AgentFace
|
|
110
|
-
config={{
|
|
111
|
-
...choice.config,
|
|
112
|
-
eyeSize: 24,
|
|
113
|
-
eyeGap: 36,
|
|
114
|
-
lookAt: 'center',
|
|
115
|
-
motion: 0,
|
|
116
|
-
idle: false,
|
|
117
|
-
}}
|
|
118
|
-
size={34}
|
|
119
|
-
/>
|
|
120
|
-
)}
|
|
78
|
+
{choice.thumbnail ? <StyledImage source={{ uri: choice.thumbnail }} resizeMode="contain" accessible={false} style={{ width: 27, height: 27, opacity: choice.disabled ? 0.35 : 1 }} /> : <AgentFace
|
|
79
|
+
config={{
|
|
80
|
+
...choice.config,
|
|
81
|
+
eyeSize: 24,
|
|
82
|
+
eyeGap: 36,
|
|
83
|
+
lookAt: 'center',
|
|
84
|
+
motion: 0,
|
|
85
|
+
idle: false,
|
|
86
|
+
}}
|
|
87
|
+
size={34}
|
|
88
|
+
/>}
|
|
121
89
|
</StyledPressable>
|
|
122
90
|
</AnimatedView>
|
|
123
91
|
</StyledView>
|
|
@@ -141,16 +109,9 @@ export function EmotionPicker({
|
|
|
141
109
|
onChange: (eyes: AvatarConfig['eyes']) => void;
|
|
142
110
|
}) {
|
|
143
111
|
const messages = useAgentCreatorMessages();
|
|
144
|
-
const choices =
|
|
145
|
-
choicesProp ??
|
|
146
|
-
EYES.map((eyes) => ({
|
|
147
|
-
id: eyes,
|
|
148
|
-
label: messages.emotions[eyes],
|
|
149
|
-
config: { ...config, eyes },
|
|
150
|
-
}));
|
|
112
|
+
const choices = choicesProp ?? EYES.map((eyes) => ({ id: eyes, label: messages.emotions[eyes], config: { ...config, eyes } }));
|
|
151
113
|
const value = valueProp ?? config.eyes;
|
|
152
|
-
const emit = (id: string) =>
|
|
153
|
-
onSelect ? onSelect(id) : onChange(id as AvatarConfig['eyes']);
|
|
114
|
+
const emit = (id: string) => onSelect ? onSelect(id) : onChange(id as AvatarConfig['eyes']);
|
|
154
115
|
const ref = useRef<View>(null);
|
|
155
116
|
const visible = useSharedValue(true);
|
|
156
117
|
const target = useSharedValue(0);
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import { characterShapeGeometry } from '../agent-avatar/character-shapes';
|
|
2
1
|
import { memo } from 'react';
|
|
3
2
|
import Svg, { Path } from 'react-native-svg';
|
|
4
3
|
import { legacyContours } from '../agent-avatar/legacy-contours';
|
|
5
4
|
import { radialContour } from '../agent-avatar/legacy-recipe';
|
|
6
5
|
import type { AvatarConfig } from '../agent-avatar/model';
|
|
7
6
|
import { CHARACTER_COLORS } from './constants';
|
|
8
|
-
import { ClippoArtwork } from './ClippoArtwork';
|
|
9
|
-
import { ToddArtwork } from './ToddArtwork';
|
|
10
7
|
|
|
11
8
|
const silhouettes = new Map<string, { path: string; viewBox: string }>();
|
|
12
9
|
|
|
@@ -52,19 +49,7 @@ export const ShapeSilhouette = memo(function ShapeSilhouette({
|
|
|
52
49
|
}: {
|
|
53
50
|
config: AvatarConfig;
|
|
54
51
|
}) {
|
|
55
|
-
|
|
56
|
-
config.character?.selections?.shape === 'todd' ||
|
|
57
|
-
(config.character?.preset === 'lime_frog' &&
|
|
58
|
-
!config.character.selections?.shape)
|
|
59
|
-
)
|
|
60
|
-
return <ToddArtwork />;
|
|
61
|
-
if (
|
|
62
|
-
config.character?.selections?.shape === 'clippo' ||
|
|
63
|
-
(config.character?.preset === 'clippo' &&
|
|
64
|
-
!config.character.selections?.shape)
|
|
65
|
-
)
|
|
66
|
-
return <ClippoArtwork kind="shape" />;
|
|
67
|
-
const { path, viewBox } = silhouette(characterShapeGeometry(config));
|
|
52
|
+
const { path, viewBox } = silhouette(config);
|
|
68
53
|
return (
|
|
69
54
|
<Svg
|
|
70
55
|
width={56}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ContextType, ReactNode } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
CharacterCapabilitiesContext,
|
|
4
|
+
CharacterRuntimeContext,
|
|
5
|
+
} from '../../../agent-avatar/context';
|
|
6
|
+
|
|
7
|
+
/** Supply both internal channels without starting the browser engine in UI tests. */
|
|
8
|
+
export function CharacterRuntimeFixture({
|
|
9
|
+
value,
|
|
10
|
+
children,
|
|
11
|
+
}: {
|
|
12
|
+
value: ContextType<typeof CharacterRuntimeContext> &
|
|
13
|
+
ContextType<typeof CharacterCapabilitiesContext>;
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
}) {
|
|
16
|
+
const { runtimeUrl, reportCapabilities, ...catalog } = value;
|
|
17
|
+
return (
|
|
18
|
+
<CharacterRuntimeContext.Provider
|
|
19
|
+
value={{ runtimeUrl, reportCapabilities }}
|
|
20
|
+
>
|
|
21
|
+
<CharacterCapabilitiesContext.Provider value={catalog}>
|
|
22
|
+
{children}
|
|
23
|
+
</CharacterCapabilitiesContext.Provider>
|
|
24
|
+
</CharacterRuntimeContext.Provider>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { NATIVE_CHARACTER_SHAPES } from '../agent-avatar/character-shapes';
|
|
2
1
|
import type { AgentLanguage, AgentPreferences } from './types';
|
|
3
2
|
export const AGENT_LANGUAGES = [
|
|
4
3
|
{ id: 'auto', label: 'Auto-detect' },
|
|
@@ -59,7 +58,6 @@ export const PREVIEW_TEXT: Record<AgentLanguage, string> = {
|
|
|
59
58
|
|
|
60
59
|
// Recovered engine catalog metadata. IDs are renderer selections; titles retain the beta catalog's English defaults.
|
|
61
60
|
export const CHARACTER_PRESETS = [
|
|
62
|
-
{ id: 'clippo', title: 'Clippo' },
|
|
63
61
|
{ id: 'blue_beret', title: 'Felipe' },
|
|
64
62
|
{ id: 'alfred', title: 'Alfred' },
|
|
65
63
|
{ id: 'purple_heart', title: 'Jojo' },
|
|
@@ -70,51 +68,20 @@ export const CHARACTER_PRESETS = [
|
|
|
70
68
|
{ id: 'lime_headphones', title: 'Iggy' },
|
|
71
69
|
] as const;
|
|
72
70
|
export const CHARACTER_OPTIONS = {
|
|
73
|
-
shape:
|
|
74
|
-
|
|
75
|
-
['
|
|
76
|
-
['
|
|
77
|
-
['
|
|
78
|
-
['blue', 'Blue'],
|
|
79
|
-
['cyan', 'Cyan'],
|
|
80
|
-
['teal', 'Teal'],
|
|
81
|
-
['lime', 'Lime'],
|
|
82
|
-
['yellow', 'Yellow'],
|
|
83
|
-
['coral', 'Coral'],
|
|
84
|
-
],
|
|
85
|
-
eyes: [
|
|
86
|
-
['cyclops', 'Single eye'],
|
|
87
|
-
['clippo', 'Clippo'],
|
|
88
|
-
['todd', 'Todd'],
|
|
89
|
-
['swept_lids', 'Swept lids'],
|
|
90
|
-
['oval', 'Oval'],
|
|
91
|
-
['sparkle_capsules', 'Sparkle capsules'],
|
|
92
|
-
['highlight_capsules', 'Highlight capsules'],
|
|
93
|
-
['dots', 'Dots'],
|
|
94
|
-
['double_highlights', 'Round highlights'],
|
|
95
|
-
['round_inset', 'Round inset'],
|
|
96
|
-
['crescent_inset', 'Crescent inset'],
|
|
97
|
-
['sleepy_lids', 'Sleepy lids'],
|
|
98
|
-
],
|
|
99
|
-
eyewear: [
|
|
100
|
-
['none', 'None'],
|
|
101
|
-
['monocle', 'Monocle'],
|
|
102
|
-
['tall_oval_frames', 'Tall oval frames'],
|
|
103
|
-
['separate_trapezoid_lenses', 'Separate trapezoid lenses'],
|
|
104
|
-
['classic_sunglasses', 'Classic sunglasses'],
|
|
105
|
-
['round_sunglasses', 'Round sunglasses'],
|
|
106
|
-
],
|
|
107
|
-
accessory: [
|
|
108
|
-
['headphones', 'Headphones'],
|
|
109
|
-
['bow', 'Bow tie'],
|
|
110
|
-
['beanie', 'Beanie'],
|
|
111
|
-
['hat', 'Hat'],
|
|
112
|
-
['beret', 'Beret'],
|
|
113
|
-
['felipe_beret', 'Felipe’s beret'],
|
|
114
|
-
['orb', 'Bulb'],
|
|
115
|
-
['three_lobe', 'Tuft'],
|
|
116
|
-
['crown', 'Crown'],
|
|
71
|
+
shape: [
|
|
72
|
+
['circle', 'Circle'], ['rounded_triangle', 'Rounded triangle'], ['capsule', 'Capsule'],
|
|
73
|
+
['rounded_head_two_ears', 'Rounded head with two ears'], ['six_lobed_flower', 'Six lobed flower'],
|
|
74
|
+
['heart', 'Heart'], ['four_lobed_butterfly', 'Four lobed butterfly'], ['circle_two_ears', 'Circle with two ears'],
|
|
75
|
+
['twelve_scalloped_rosette', 'Twelve scalloped rosette'], ['rounded_cube', 'Hexagon'], ['rounded_diamond', 'Rounded diamond'],
|
|
117
76
|
],
|
|
77
|
+
color: [['pink', 'Pink'], ['orchid', 'Orchid'], ['violet', 'Violet'], ['blue', 'Blue'], ['cyan', 'Cyan'], ['teal', 'Teal'], ['lime', 'Lime'], ['yellow', 'Yellow'], ['coral', 'Coral']],
|
|
78
|
+
eyes: [['swept_lids', 'Swept lids'], ['oval', 'Oval'], ['sparkle_capsules', 'Sparkle capsules'], ['highlight_capsules', 'Highlight capsules'], ['dots', 'Dots'], ['double_highlights', 'Round highlights'], ['round_inset', 'Round inset'], ['crescent_inset', 'Crescent inset'], ['sleepy_lids', 'Sleepy lids']],
|
|
79
|
+
eyewear: [['none', 'None'], ['monocle', 'Monocle'], ['tall_oval_frames', 'Tall oval frames'], ['separate_trapezoid_lenses', 'Separate trapezoid lenses'], ['classic_sunglasses', 'Classic sunglasses'], ['round_sunglasses', 'Round sunglasses']],
|
|
80
|
+
accessory: [['headphones', 'Headphones'], ['bow', 'Bow tie'], ['beanie', 'Beanie'], ['hat', 'Hat'], ['beret', 'Beret'], ['orb', 'Bulb'], ['three_lobe', 'Tuft'], ['crown', 'Crown']],
|
|
118
81
|
} as const;
|
|
119
82
|
|
|
120
|
-
|
|
83
|
+
/** RGB swatches returned by the recovered engine's Color catalog. */
|
|
84
|
+
export const CHARACTER_COLORS = {
|
|
85
|
+
pink: '#fa70ab', orchid: '#dd6adc', violet: '#a25bff', blue: '#4778ff', cyan: '#00b1ff',
|
|
86
|
+
teal: '#04bb9f', lime: '#b6d80b', yellow: '#ffcc38', coral: '#ff8066',
|
|
87
|
+
} as const;
|
|
@@ -114,8 +114,7 @@ export const AGENT_CREATOR_MESSAGES: MessageCatalog<AgentCreatorMessages> =
|
|
|
114
114
|
betaEyes: 'Eye style',
|
|
115
115
|
eyewear: 'Eyewear',
|
|
116
116
|
accessory: 'Accessory',
|
|
117
|
-
characterOption: (
|
|
118
|
-
category === 'eyes' && id === 'cyclops' ? 'Single eye' : String(title),
|
|
117
|
+
characterOption: (_category, _id, title) => String(title),
|
|
119
118
|
editor: 'Agent editor',
|
|
120
119
|
newBot: 'New bot',
|
|
121
120
|
closeEditor: 'Close agent editor',
|
|
@@ -84,7 +84,7 @@ export function createAppShell(BottomBar: ComponentType<BottomBarProps>, Fab: Co
|
|
|
84
84
|
) : null}
|
|
85
85
|
<Screen navigationScope="shared" active={active} documentScroll={scroll === 'external'} testID={testID ? `${testID}-screen` : undefined} style={{ minWidth: 0 }} header={header ?? (title ? <PageHeader title={title} subtitle={breadcrumb} actions={actions} sticky={false} /> : null)} bottomBar={bottom} primaryAction={placement !== 'bottom' && primaryAction ? <Fab {...primaryAction} /> : undefined}>
|
|
86
86
|
{scroll === 'auto' ? <ScreenScrollView style={{ flex: 1 }}>
|
|
87
|
-
<View style={{ width: '100%', maxWidth: contentMaxWidth, alignSelf: 'center', padding: 16, gap: 16 }}>{children}</View>
|
|
87
|
+
<View testID={testID ? `${testID}-content` : undefined} style={{ width: '100%', maxWidth: contentMaxWidth === 'none' ? undefined : contentMaxWidth, alignSelf: 'center', padding: 16, gap: 16 }}>{children}</View>
|
|
88
88
|
</ScreenScrollView> : children}
|
|
89
89
|
{overlay}
|
|
90
90
|
</Screen>
|
|
@@ -151,7 +151,7 @@ export function createAppShell(BottomBar: ComponentType<BottomBarProps>, Fab: Co
|
|
|
151
151
|
|| props.primaryAction !== undefined || props.scroll === 'auto' || props.scroll === 'external';
|
|
152
152
|
if (!adaptive) return <AppShellEngine {...props as AppShellEngineProps} />;
|
|
153
153
|
const scroll = props.scroll ?? (Platform.OS === 'web' ? 'document' : 'auto');
|
|
154
|
-
const usesLayout = props.panel !== undefined || props.panelColorPreset !== undefined || props.variant !== undefined || props.aside !== undefined || props.list !== undefined || props.info !== undefined
|
|
154
|
+
const usesLayout = props.safeArea !== undefined || props.panel !== undefined || props.panelColorPreset !== undefined || props.variant !== undefined || props.aside !== undefined || props.list !== undefined || props.info !== undefined
|
|
155
155
|
|| props.contentWidth !== undefined || props.navigationAlign !== undefined || props.navigationGap !== undefined || props.drawer !== undefined
|
|
156
156
|
|| props.navFrom !== undefined || props.navExpandedFrom !== undefined || props.topBar !== undefined
|
|
157
157
|
|| props.bottomBar !== undefined || props.floatingAction !== undefined;
|
|
@@ -36,13 +36,13 @@ import { useClaimBottomEdge } from '../layout/bottom-edge';
|
|
|
36
36
|
import { Z_INDEX } from '../styles/z-index';
|
|
37
37
|
|
|
38
38
|
/** The safe-area insets, or zeros outside a `SafeAreaProvider`. */
|
|
39
|
-
export function useShellInsets(): { top: number; bottom: number } {
|
|
39
|
+
export function useShellInsets(): { top: number; right: number; bottom: number; left: number } {
|
|
40
40
|
// `useContext(SafeAreaInsetsContext)` rather than `useSafeAreaInsets()`: the
|
|
41
41
|
// hook THROWS outside a provider, and `AppShell` is mounted at an app's root,
|
|
42
42
|
// where making a previously-optional provider mandatory would be a breaking
|
|
43
43
|
// change for every consumer that never had a bar to inset.
|
|
44
44
|
const insets = useContext(SafeAreaInsetsContext);
|
|
45
|
-
return { top:
|
|
45
|
+
return insets ?? { top: 0, right: 0, bottom: 0, left: 0 };
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
/** Pinned to the bottom of the viewport (document scroll) or of the frame. */
|
|
@@ -152,6 +152,8 @@ export const AppShellFloatingAction = memo(AppShellFloatingActionComponent);
|
|
|
152
152
|
AppShellFloatingAction.displayName = 'AppShellFloatingAction';
|
|
153
153
|
|
|
154
154
|
export interface AppShellTopBarProps {
|
|
155
|
+
/** The enclosing safe frame may already own the top inset. */
|
|
156
|
+
insetTop?: number;
|
|
155
157
|
children: React.ReactNode;
|
|
156
158
|
onHeightChange?: (height: number) => void;
|
|
157
159
|
doc: boolean;
|
|
@@ -167,11 +169,11 @@ export interface AppShellTopBarProps {
|
|
|
167
169
|
* only as far as `top: 0`); in `container`/`fixed` and on native it is simply
|
|
168
170
|
* outside the scroller, which pins it by construction.
|
|
169
171
|
*/
|
|
170
|
-
const AppShellTopBarComponent: React.FC<AppShellTopBarProps> = ({ children, doc, testID, onHeightChange }) => {
|
|
172
|
+
const AppShellTopBarComponent: React.FC<AppShellTopBarProps> = ({ children, doc, testID, onHeightChange, insetTop }) => {
|
|
171
173
|
const insets = useShellInsets();
|
|
172
174
|
const pinned: WebCssStyle = doc ? { position: WEB_POSITION_STICKY, top: 0 } : {};
|
|
173
175
|
return (
|
|
174
|
-
<View testID={testID} onLayout={event => onHeightChange?.(event.nativeEvent.layout.height)} style={[{ zIndex: Z_INDEX.floating, paddingTop: insets.top }, pinned]}>
|
|
176
|
+
<View testID={testID} onLayout={event => onHeightChange?.(event.nativeEvent.layout.height)} style={[{ zIndex: Z_INDEX.floating, paddingTop: insetTop ?? insets.top }, pinned]}>
|
|
175
177
|
{children}
|
|
176
178
|
</View>
|
|
177
179
|
);
|
|
@@ -106,6 +106,7 @@ export function createAppShellEngine(
|
|
|
106
106
|
) {
|
|
107
107
|
const AppShellComponent: React.FC<AppShellEngineProps> = ({
|
|
108
108
|
variant = 'dashboard',
|
|
109
|
+
safeArea = false,
|
|
109
110
|
navigationAlign = 'edge',
|
|
110
111
|
navigationGap,
|
|
111
112
|
asideGap,
|
|
@@ -166,6 +167,7 @@ const AppShellComponent: React.FC<AppShellEngineProps> = ({
|
|
|
166
167
|
const [asideHeight, setAsideHeight] = useState(0);
|
|
167
168
|
const { width, onLayout } = useShellWidth();
|
|
168
169
|
const insets = useShellInsets();
|
|
170
|
+
const ownsSafeArea = safeArea && Platform.OS !== 'web';
|
|
169
171
|
const mode = resolveScrollMode(variant, scroll);
|
|
170
172
|
const doc = mode === 'document';
|
|
171
173
|
const fixed = mode === 'fixed';
|
|
@@ -175,6 +177,10 @@ const AppShellComponent: React.FC<AppShellEngineProps> = ({
|
|
|
175
177
|
// for every other shape.
|
|
176
178
|
const gutter = gutterProp ?? (variant === 'dashboard' ? D.dashboardGutter : D.gutter);
|
|
177
179
|
const columnGap = variant === 'dashboard' ? D.dashboardColumnGap : gutter;
|
|
180
|
+
// Historical reveal geometry stays the default; an explicit gutter owns
|
|
181
|
+
// every frame edge, including the old extra top gap at wider breakpoints.
|
|
182
|
+
const revealGutter = gutterProp ?? 12;
|
|
183
|
+
const revealTopGutter = gutterProp ?? (small ? 24 : 12);
|
|
178
184
|
|
|
179
185
|
// The nav: `navExpandedFrom` decides which sidebar variant is drawn, and the
|
|
180
186
|
// variant decides how early it can sit in flow (a rail is narrow enough at
|
|
@@ -290,6 +296,24 @@ const AppShellComponent: React.FC<AppShellEngineProps> = ({
|
|
|
290
296
|
const showTopBar = topBar != null && barActive(topBarVisibility);
|
|
291
297
|
const showBottomBar = bottomBar != null && barActive(bottomBarVisibility);
|
|
292
298
|
const showFloatingAction = floatingAction != null;
|
|
299
|
+
// Preserve the real device insets for fullscreen dialogs and portals. Only
|
|
300
|
+
// the bounded shell consumes these edges; bottom chrome keeps its own inset.
|
|
301
|
+
const bottomChrome = showBottomBar || showFloatingAction;
|
|
302
|
+
const frameBottomInset = ownsSafeArea && !bottomChrome ? insets.bottom : 0;
|
|
303
|
+
const navigationBottomInset = ownsSafeArea && bottomChrome ? insets.bottom : 0;
|
|
304
|
+
const safeFrame = (node: React.ReactElement) => ownsSafeArea ? (
|
|
305
|
+
<View {...dirProps} testID={testID ? `${testID}-safe-area` : undefined} style={{
|
|
306
|
+
flex: 1, minHeight: 0, minWidth: 0,
|
|
307
|
+
paddingTop: insets.top,
|
|
308
|
+
paddingInlineStart: rtl ? insets.right : insets.left,
|
|
309
|
+
paddingInlineEnd: rtl ? insets.left : insets.right,
|
|
310
|
+
paddingBottom: frameBottomInset, backgroundColor: background,
|
|
311
|
+
}}>{node}</View>
|
|
312
|
+
) : node;
|
|
313
|
+
|
|
314
|
+
const safeNavigation = (node: React.ReactElement) => navigationBottomInset ? (
|
|
315
|
+
<View style={{ flexShrink: 0, paddingBottom: navigationBottomInset }}>{node}</View>
|
|
316
|
+
) : node;
|
|
293
317
|
const [topBarHeight, setTopBarHeight] = useState(0);
|
|
294
318
|
const [bottomBarHeight, setBottomBarHeight] = useState(0);
|
|
295
319
|
const [floatingActionHeight, setFloatingActionHeight] = useState(0);
|
|
@@ -328,7 +352,7 @@ const AppShellComponent: React.FC<AppShellEngineProps> = ({
|
|
|
328
352
|
);
|
|
329
353
|
|
|
330
354
|
const topBarNode = showTopBar ? (
|
|
331
|
-
<AppShellTopBar doc={doc} onHeightChange={setTopBarHeight} testID={testID ? `${testID}-top-bar` : undefined}>
|
|
355
|
+
<AppShellTopBar insetTop={ownsSafeArea ? 0 : undefined} doc={doc} onHeightChange={setTopBarHeight} testID={testID ? `${testID}-top-bar` : undefined}>
|
|
332
356
|
{topBar}
|
|
333
357
|
</AppShellTopBar>
|
|
334
358
|
) : null;
|
|
@@ -363,7 +387,7 @@ const AppShellComponent: React.FC<AppShellEngineProps> = ({
|
|
|
363
387
|
|
|
364
388
|
const fill = fixed ? { flex: 1, minHeight: 0 } : null;
|
|
365
389
|
const column = (
|
|
366
|
-
<View style={[{ width: '100%', maxWidth: contentMaxWidth, alignSelf: 'center', gap: 10 }, fill]}>
|
|
390
|
+
<View testID={testID ? `${testID}-content` : undefined} style={[{ width: '100%', maxWidth: contentMaxWidth === 'none' ? undefined : contentMaxWidth, alignSelf: 'center', gap: 10 }, fill]}>
|
|
367
391
|
{headerNode}
|
|
368
392
|
<View
|
|
369
393
|
style={[
|
|
@@ -432,7 +456,7 @@ const AppShellComponent: React.FC<AppShellEngineProps> = ({
|
|
|
432
456
|
const veilStyle = useAnimatedStyle(() => ({ opacity: reveal.value }), [reveal]);
|
|
433
457
|
|
|
434
458
|
if (drawerStyle === 'reveal' && variant === 'dashboard') {
|
|
435
|
-
return (
|
|
459
|
+
return safeFrame(
|
|
436
460
|
<AppShellProvider value={shell}>
|
|
437
461
|
<View
|
|
438
462
|
{...dirProps}
|
|
@@ -445,20 +469,21 @@ const AppShellComponent: React.FC<AppShellEngineProps> = ({
|
|
|
445
469
|
style={[
|
|
446
470
|
flowSidebar.surface === 'docked'
|
|
447
471
|
? { flexShrink: 0 }
|
|
448
|
-
: { paddingTop:
|
|
472
|
+
: { paddingTop: revealGutter, paddingBottom: revealGutter, paddingInlineStart: revealGutter, flexShrink: 0 },
|
|
449
473
|
doc ? stickyRail(0) : null,
|
|
450
474
|
]}
|
|
451
475
|
>
|
|
452
|
-
<Sidebar {...flowSidebar} />
|
|
476
|
+
{safeNavigation(<Sidebar {...flowSidebar} />)}
|
|
453
477
|
</View>
|
|
454
478
|
) : null}
|
|
455
479
|
{drawerAvailable && drawerSidebar ? (
|
|
456
480
|
<View
|
|
481
|
+
testID={testID ? `${testID}-navigation-drawer` : undefined}
|
|
457
482
|
aria-hidden={!isOpen}
|
|
458
483
|
pointerEvents={isOpen ? 'auto' : 'none'}
|
|
459
484
|
// Fixed on web in document mode: the rail waits beneath the VIEWPORT,
|
|
460
485
|
// wherever the page is scrolled to.
|
|
461
|
-
style={{ position: doc ? WEB_POSITION_FIXED : 'absolute', top: 0, bottom: 0, insetInlineStart: 0, width: 272, paddingTop:
|
|
486
|
+
style={{ position: doc ? WEB_POSITION_FIXED : 'absolute', top: 0, bottom: 0, insetInlineStart: 0, width: 272, paddingTop: revealGutter, paddingBottom: revealGutter + navigationBottomInset, paddingInlineStart: revealGutter / 2 }}
|
|
462
487
|
>
|
|
463
488
|
<Animated.View style={[{ height: '100%', width: 260, transformOrigin: railOrigin }, railStyle]}>
|
|
464
489
|
<Sidebar {...drawerSidebar} mobile surface="plain" onClose={() => setOpen(false)} />
|
|
@@ -487,13 +512,13 @@ const AppShellComponent: React.FC<AppShellEngineProps> = ({
|
|
|
487
512
|
// layered over the shorthand, and only when there is one.
|
|
488
513
|
contentStyle={
|
|
489
514
|
contentReserve
|
|
490
|
-
? { paddingLeft:
|
|
491
|
-
: { padding:
|
|
515
|
+
? { paddingLeft: revealGutter, paddingRight: revealGutter, paddingTop: revealTopGutter, paddingBottom: revealGutter + contentReserve }
|
|
516
|
+
: { padding: revealGutter, paddingTop: revealTopGutter }
|
|
492
517
|
}
|
|
493
518
|
>
|
|
494
519
|
{column}
|
|
495
520
|
</Scroller>
|
|
496
|
-
{asideColumn({ paddingTop:
|
|
521
|
+
{asideColumn({ paddingTop: revealTopGutter, paddingBottom: revealGutter, paddingInlineEnd: revealGutter })}
|
|
497
522
|
{!wide ? (
|
|
498
523
|
<Animated.View
|
|
499
524
|
pointerEvents={isOpen ? 'auto' : 'none'}
|
|
@@ -758,15 +783,15 @@ const AppShellComponent: React.FC<AppShellEngineProps> = ({
|
|
|
758
783
|
navInFlow && flowSidebar ? (
|
|
759
784
|
doc ? (
|
|
760
785
|
<View testID={testID ? `${testID}-navigation` : undefined} style={stickyRail(dockedNav || plainFrame ? 0 : gutter)}>
|
|
761
|
-
<Sidebar {...flowSidebar} />
|
|
786
|
+
{safeNavigation(<Sidebar {...flowSidebar} />)}
|
|
762
787
|
</View>
|
|
763
788
|
) : canvas && !dockedNav ? (
|
|
764
789
|
// The canvas row has no padding of its own, so the nav states its.
|
|
765
790
|
<View style={{ paddingTop: gutter, paddingBottom: gutter, paddingInlineStart: gutter, flexShrink: 0 }}>
|
|
766
|
-
<Sidebar {...flowSidebar} />
|
|
791
|
+
{safeNavigation(<Sidebar {...flowSidebar} />)}
|
|
767
792
|
</View>
|
|
768
793
|
) : (
|
|
769
|
-
<Sidebar {...flowSidebar} />
|
|
794
|
+
safeNavigation(<Sidebar {...flowSidebar} />)
|
|
770
795
|
)
|
|
771
796
|
) : null;
|
|
772
797
|
|
|
@@ -783,7 +808,15 @@ const AppShellComponent: React.FC<AppShellEngineProps> = ({
|
|
|
783
808
|
<View
|
|
784
809
|
{...dirProps}
|
|
785
810
|
pointerEvents="box-none"
|
|
786
|
-
|
|
811
|
+
testID={testID ? `${testID}-navigation-drawer` : undefined}
|
|
812
|
+
style={{ position: 'absolute', top: 0, bottom: 0, insetInlineStart: 0, flexDirection: 'row',
|
|
813
|
+
...(ownsSafeArea ? {
|
|
814
|
+
paddingTop: 12 + insets.top,
|
|
815
|
+
paddingBottom: 12 + insets.bottom,
|
|
816
|
+
paddingInlineStart: 12 + (rtl ? insets.right : insets.left),
|
|
817
|
+
paddingInlineEnd: 12 + (rtl ? insets.left : insets.right),
|
|
818
|
+
} : { padding: 12 }),
|
|
819
|
+
}}
|
|
787
820
|
>
|
|
788
821
|
<View pointerEvents="auto" style={{ height: '100%' }}>
|
|
789
822
|
<Sidebar {...drawerSidebar} mobile onClose={() => setOpen(false)} />
|
|
@@ -810,12 +843,12 @@ const AppShellComponent: React.FC<AppShellEngineProps> = ({
|
|
|
810
843
|
};
|
|
811
844
|
|
|
812
845
|
if (variant === 'feed' && drawerStyle === 'reveal' && drawerAvailable) {
|
|
813
|
-
return (
|
|
846
|
+
return safeFrame(
|
|
814
847
|
<AppShellProvider value={shell}>
|
|
815
848
|
<View {...dirProps} testID={testID} onLayout={onLayout}
|
|
816
849
|
style={[frame, { overflow: doc ? WEB_OVERFLOW_CLIP : 'hidden', backgroundColor: background }, style]}>
|
|
817
|
-
<View aria-hidden={!isOpen} pointerEvents={isOpen ? 'auto' : 'none'}
|
|
818
|
-
style={{ position: doc ? WEB_POSITION_FIXED : 'absolute', top: 0, bottom: 0, insetInlineStart: 0, width: 272, paddingTop:
|
|
850
|
+
<View testID={testID ? `${testID}-navigation-drawer` : undefined} aria-hidden={!isOpen} pointerEvents={isOpen ? 'auto' : 'none'}
|
|
851
|
+
style={{ position: doc ? WEB_POSITION_FIXED : 'absolute', top: 0, bottom: 0, insetInlineStart: 0, width: 272, paddingTop: revealGutter, paddingBottom: revealGutter + navigationBottomInset, paddingInlineStart: revealGutter / 2 }}>
|
|
819
852
|
<Animated.View style={[{ height: '100%', width: 260, transformOrigin: railOrigin }, railStyle]}>
|
|
820
853
|
{drawerSidebar && <Sidebar {...drawerSidebar} mobile surface="plain" onClose={() => setOpen(false)} />}
|
|
821
854
|
</Animated.View>
|
|
@@ -850,7 +883,7 @@ const AppShellComponent: React.FC<AppShellEngineProps> = ({
|
|
|
850
883
|
// edge without escaping the frame's padding. Without one the root stays the
|
|
851
884
|
// row it has always been, so nothing about an existing shell moves.
|
|
852
885
|
if (topBarNode) {
|
|
853
|
-
return (
|
|
886
|
+
return safeFrame(
|
|
854
887
|
<AppShellProvider value={shell}>
|
|
855
888
|
<View
|
|
856
889
|
{...dirProps}
|
|
@@ -871,7 +904,7 @@ const AppShellComponent: React.FC<AppShellEngineProps> = ({
|
|
|
871
904
|
);
|
|
872
905
|
}
|
|
873
906
|
|
|
874
|
-
return (
|
|
907
|
+
return safeFrame(
|
|
875
908
|
<AppShellProvider value={shell}>
|
|
876
909
|
<View {...dirProps} testID={testID} onLayout={onLayout} style={[frame, rowStyle, style]}>
|
|
877
910
|
{navRegion}
|
package/src/app-shell/types.ts
CHANGED
|
@@ -67,6 +67,14 @@ export type AppShellScroll = 'document' | 'container' | 'fixed';
|
|
|
67
67
|
export type AppShellBarVisibility = 'compact' | 'always';
|
|
68
68
|
|
|
69
69
|
export interface AppShellEngineProps {
|
|
70
|
+
/**
|
|
71
|
+
* Native: keep the shell, navigation and pages inside the device's safe area.
|
|
72
|
+
* The bottom-bar slot still owns its bottom inset; without bottom chrome the
|
|
73
|
+
* frame reserves it. Use `safeArea={false}` on descendant PageHeaders because
|
|
74
|
+
* the frame already owns their top edge. Device insets remain available to
|
|
75
|
+
* dialogs and other portaled surfaces. Defaults to false; no effect on web.
|
|
76
|
+
*/
|
|
77
|
+
safeArea?: boolean;
|
|
70
78
|
/**
|
|
71
79
|
* The layout shape. Defaults to `dashboard` — the behaviour this component
|
|
72
80
|
* had before variants existed, down to the pixel.
|
|
@@ -124,8 +132,8 @@ export interface AppShellEngineProps {
|
|
|
124
132
|
*/
|
|
125
133
|
asideCollapse?: 'stack' | 'hidden';
|
|
126
134
|
children?: ReactNode;
|
|
127
|
-
/** The content column's max width. Defaults to 1300. */
|
|
128
|
-
contentMaxWidth?: number;
|
|
135
|
+
/** The content column's max width. Defaults to 1300; `none` fills the available width. */
|
|
136
|
+
contentMaxWidth?: number | 'none';
|
|
129
137
|
/** Floating extras rendered last, e.g. a `ProOfferCard`. */
|
|
130
138
|
overlay?: ReactNode;
|
|
131
139
|
/** Controlled drawer state (below `lg`). */
|
|
@@ -364,7 +372,7 @@ export interface AppShellNavigationProps {
|
|
|
364
372
|
actions?: ReactNode;
|
|
365
373
|
header?: ReactNode;
|
|
366
374
|
children?: ReactNode;
|
|
367
|
-
contentMaxWidth?: number;
|
|
375
|
+
contentMaxWidth?: number | 'none';
|
|
368
376
|
overlay?: ReactNode;
|
|
369
377
|
style?: StyleProp<ViewStyle>;
|
|
370
378
|
testID?: string;
|
|
@@ -3,8 +3,11 @@ import { BloomAppearanceContext } from './context';
|
|
|
3
3
|
import type { BloomScopeProps } from './types';
|
|
4
4
|
|
|
5
5
|
/** A visual environment only: never inherits actions, selection or disabled state. */
|
|
6
|
-
export function BloomScope({ children, size, tone }: BloomScopeProps) {
|
|
6
|
+
export function BloomScope({ children, size, tone, panelRadius }: BloomScopeProps) {
|
|
7
|
+
if (panelRadius !== undefined && (!Number.isFinite(panelRadius) || panelRadius < 0)) {
|
|
8
|
+
throw new RangeError('panelRadius must be a finite, non-negative number.');
|
|
9
|
+
}
|
|
7
10
|
const parent = useContext(BloomAppearanceContext);
|
|
8
|
-
const value = useMemo(() => ({ size: size ?? parent.size, tone: tone ?? parent.tone }), [size, tone, parent]);
|
|
11
|
+
const value = useMemo(() => ({ size: size ?? parent.size, tone: tone ?? parent.tone, panelRadius: panelRadius ?? parent.panelRadius }), [size, tone, panelRadius, parent]);
|
|
9
12
|
return <BloomAppearanceContext.Provider value={value}>{children}</BloomAppearanceContext.Provider>;
|
|
10
13
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createContext, useContext } from 'react';
|
|
2
|
-
import type { BloomAppearanceProps } from './types';
|
|
2
|
+
import type { BloomAppearanceProps, BloomScopeProps } from './types';
|
|
3
3
|
|
|
4
|
-
export const BloomAppearanceContext = createContext<
|
|
4
|
+
export const BloomAppearanceContext = createContext<Omit<BloomScopeProps, 'children'>>({});
|
|
5
5
|
|
|
6
6
|
/** Explicit props override the nearest scope, then the family's defaults. */
|
|
7
7
|
export function useBloomAppearance(
|
package/src/appearance/types.ts
CHANGED
|
@@ -8,4 +8,7 @@ export interface BloomAppearanceProps {
|
|
|
8
8
|
size?: BloomSize;
|
|
9
9
|
tone?: BloomTone;
|
|
10
10
|
}
|
|
11
|
-
export type BloomScopeProps = PropsWithChildren<BloomAppearanceProps
|
|
11
|
+
export type BloomScopeProps = PropsWithChildren<BloomAppearanceProps & {
|
|
12
|
+
/** Shared corner radius for framed content panels and card sidebars. Defaults to 28. */
|
|
13
|
+
panelRadius?: number;
|
|
14
|
+
}>;
|