@datalayer/core 1.1.49 → 1.1.56

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.
Files changed (82) hide show
  1. package/README.md +19 -42
  2. package/lib/client/auth/AuthenticationManager.js +6 -4
  3. package/lib/client/auth/strategies.js +2 -0
  4. package/lib/components/animation/AnimatedText.d.ts +98 -0
  5. package/lib/components/animation/AnimatedText.js +220 -0
  6. package/lib/components/animation/index.d.ts +1 -0
  7. package/lib/components/{tokens → animation}/index.js +1 -1
  8. package/lib/components/auth/{LoginToken.d.ts → SigInAPIKey.d.ts} +3 -3
  9. package/lib/components/auth/{LoginToken.js → SigInAPIKey.js} +5 -5
  10. package/lib/components/auth/{Login.d.ts → SignIn.d.ts} +3 -3
  11. package/lib/components/auth/{Login.js → SignIn.js} +13 -13
  12. package/lib/components/auth/{Login.stories.d.ts → SignIn.stories.d.ts} +2 -2
  13. package/lib/components/auth/{Login.stories.js → SignIn.stories.js} +9 -9
  14. package/lib/components/auth/index.d.ts +2 -2
  15. package/lib/components/auth/index.js +2 -2
  16. package/lib/components/avatars/UserAvatar.d.ts +7 -1
  17. package/lib/components/avatars/UserAvatar.js +19 -6
  18. package/lib/components/avatars/UserProfileAvatar.js +2 -6
  19. package/lib/components/billing/BillingEntitySelect.js +10 -2
  20. package/lib/components/collaboration/LiveEditorCollaborators.d.ts +31 -0
  21. package/lib/components/collaboration/LiveEditorCollaborators.js +107 -0
  22. package/lib/components/collaboration/index.d.ts +1 -0
  23. package/lib/components/collaboration/index.js +9 -0
  24. package/lib/components/display/DatalayerBox.d.ts +3 -1
  25. package/lib/components/display/DatalayerBox.js +7 -7
  26. package/lib/components/display/JupyterDialog.d.ts +2 -0
  27. package/lib/components/display/JupyterDialog.js +10 -4
  28. package/lib/components/iam/ExternalTokenSilentLogin.js +8 -4
  29. package/lib/components/index.d.ts +2 -0
  30. package/lib/components/index.js +2 -0
  31. package/lib/components/labels/StatusLabels.d.ts +42 -0
  32. package/lib/components/labels/StatusLabels.js +61 -0
  33. package/lib/components/labels/index.d.ts +1 -0
  34. package/lib/components/labels/index.js +1 -0
  35. package/lib/components/principal/Principal.d.ts +2 -0
  36. package/lib/components/principal/Principal.js +11 -1
  37. package/lib/components/principal/PrincipalAppearance.d.ts +136 -0
  38. package/lib/components/principal/PrincipalAppearance.js +203 -0
  39. package/lib/components/principal/PrincipalAvatar.d.ts +5 -2
  40. package/lib/components/principal/PrincipalAvatar.js +16 -3
  41. package/lib/components/principal/PrincipalBadge.js +7 -0
  42. package/lib/components/principal/PrincipalDetailsOverlay.d.ts +2 -1
  43. package/lib/components/principal/PrincipalDetailsOverlay.js +2 -2
  44. package/lib/components/principal/index.d.ts +1 -0
  45. package/lib/components/principal/index.js +1 -0
  46. package/lib/components/progress/ConsumptionBar.d.ts +9 -0
  47. package/lib/components/progress/ConsumptionBar.js +10 -2
  48. package/lib/components/sharing/ShareAccessComponent.js +6 -1
  49. package/lib/config/Configuration.d.ts +17 -8
  50. package/lib/config/Configuration.js +12 -5
  51. package/lib/hooks/useCache.d.ts +2 -0
  52. package/lib/hooks/useCache.js +35 -11
  53. package/lib/hooks/usePrincipalCacheStore.d.ts +2 -0
  54. package/lib/hooks/usePrincipalCacheStore.js +2 -0
  55. package/lib/models/IAM.d.ts +10 -0
  56. package/lib/models/Organization.d.ts +2 -0
  57. package/lib/models/Organization.js +2 -0
  58. package/lib/models/Profile.d.ts +2 -0
  59. package/lib/models/Team.d.ts +2 -0
  60. package/lib/models/Team.js +2 -0
  61. package/lib/models/User.d.ts +4 -0
  62. package/lib/models/User.js +4 -0
  63. package/lib/models/UserDTO.d.ts +6 -0
  64. package/lib/models/UserDTO.js +8 -0
  65. package/lib/state/substates/CoreState.js +5 -4
  66. package/lib/state/substates/IAMState.js +6 -0
  67. package/lib/state/substates/LayoutState.js +62 -7
  68. package/lib/state/substates/OrganizationState.d.ts +6 -0
  69. package/lib/state/substates/OrganizationState.js +5 -0
  70. package/lib/state/substates/ProfileState.d.ts +34 -0
  71. package/lib/state/substates/ProfileState.js +68 -0
  72. package/lib/state/substates/TeamState.d.ts +6 -0
  73. package/lib/state/substates/TeamState.js +3 -0
  74. package/lib/state/substates/index.d.ts +1 -0
  75. package/lib/state/substates/index.js +1 -0
  76. package/lib/utils/Jwt.d.ts +0 -6
  77. package/lib/utils/Jwt.js +8 -1
  78. package/lib/views/iam/SignInSimple.d.ts +1 -1
  79. package/lib/views/iam/SignInSimple.js +131 -97
  80. package/lib/views/profile/UserBadge.js +6 -3
  81. package/package.json +3 -3
  82. package/lib/components/tokens/index.d.ts +0 -1
@@ -114,6 +114,8 @@ export const Principal = ({ principal, isAdmin = false, avatarSize = 20, gap = 2
114
114
  lastName: profile.last_name,
115
115
  handle: profile.handle,
116
116
  avatarUrl: profile.avatar_url,
117
+ avatarIcon: profile.avatar_icon_s || profile.avatar_icon,
118
+ banner: profile.banner_s || profile.banner,
117
119
  origin: profile.origin,
118
120
  email: profile.email,
119
121
  };
@@ -129,6 +131,8 @@ export const Principal = ({ principal, isAdmin = false, avatarSize = 20, gap = 2
129
131
  description: profile.description || profile.description_t,
130
132
  handle: profile.handle,
131
133
  avatarUrl: profile.avatar_url,
134
+ avatarIcon: profile.avatar_icon_s || profile.avatar_icon,
135
+ banner: profile.banner_s || profile.banner,
132
136
  };
133
137
  }, [hydratedPublicOrgQuery.data]);
134
138
  const hydratedEntity = principal.kind === 'personal'
@@ -222,6 +226,10 @@ export const Principal = ({ principal, isAdmin = false, avatarSize = 20, gap = 2
222
226
  hydratedEntity?.avatarUrl ||
223
227
  cachedPrincipal?.avatarUrl ||
224
228
  undefined,
229
+ avatarIcon: principal.avatarIcon ||
230
+ hydratedEntity?.avatarIcon ||
231
+ undefined,
232
+ banner: principal.banner || hydratedEntity?.banner || undefined,
225
233
  firstName: principal.firstName ||
226
234
  hydratedEntity?.firstName ||
227
235
  cachedPrincipal?.firstName ||
@@ -263,6 +271,8 @@ export const Principal = ({ principal, isAdmin = false, avatarSize = 20, gap = 2
263
271
  email: resolvedPrincipal.email,
264
272
  origin: resolvedPrincipal.origin,
265
273
  avatarUrl: resolvedPrincipal.avatarUrl,
274
+ avatarIcon: resolvedPrincipal.avatarIcon,
275
+ banner: resolvedPrincipal.banner,
266
276
  organizationHandle: teamOrganizationHandleResolved,
267
277
  organizationName: teamOrganizationNameResolved,
268
278
  memberCount: teamMemberCount,
@@ -286,6 +296,6 @@ export const Principal = ({ principal, isAdmin = false, avatarSize = 20, gap = 2
286
296
  gap,
287
297
  minWidth: 0,
288
298
  ...sx,
289
- }, children: [_jsx(PrincipalAvatar, { kind: resolvedPrincipal.kind, avatarUrl: resolvedPrincipal.avatarUrl, alt: resolvedPrincipal.displayName, size: avatarSize, square: square }), _jsx(PrincipalDetailsOverlay, { kind: resolvedPrincipal.kind, uid: resolvedPrincipal.uid, displayName: resolvedPrincipal.displayName, name: resolvedPrincipal.name, description: resolvedPrincipal.description, handle: resolvedPrincipal.handle, accountHandle: resolvedPrincipal.accountHandle, firstName: resolvedPrincipal.firstName, lastName: resolvedPrincipal.lastName, email: resolvedPrincipal.email, origin: resolvedPrincipal.origin, avatarUrl: resolvedPrincipal.avatarUrl, organizationName: teamOrganizationNameResolved, memberCount: teamMemberCount, isPublic: resolvedIsPublic, isAdmin: isAdmin })] }));
299
+ }, children: [_jsx(PrincipalAvatar, { kind: resolvedPrincipal.kind, avatarUrl: resolvedPrincipal.avatarUrl, avatarIcon: resolvedPrincipal.avatarIcon, alt: resolvedPrincipal.displayName, size: avatarSize, square: square }), _jsx(PrincipalDetailsOverlay, { kind: resolvedPrincipal.kind, uid: resolvedPrincipal.uid, displayName: resolvedPrincipal.displayName, name: resolvedPrincipal.name, description: resolvedPrincipal.description, handle: resolvedPrincipal.handle, accountHandle: resolvedPrincipal.accountHandle, firstName: resolvedPrincipal.firstName, lastName: resolvedPrincipal.lastName, email: resolvedPrincipal.email, origin: resolvedPrincipal.origin, avatarUrl: resolvedPrincipal.avatarUrl, avatarIcon: resolvedPrincipal.avatarIcon, organizationName: teamOrganizationNameResolved, memberCount: teamMemberCount, isPublic: resolvedIsPublic, isAdmin: isAdmin })] }));
290
300
  };
291
301
  export default Principal;
@@ -0,0 +1,136 @@
1
+ import { type ComponentType, type SVGProps } from 'react';
2
+ import { SvgAboutHero } from '@datalayer/design/lib/svg/SvgAboutHero';
3
+ import { SvgAgentsHero } from '@datalayer/design/lib/svg/SvgAgentsHero';
4
+ import { SvgAgentsHomeHero } from '@datalayer/design/lib/svg/SvgAgentsHomeHero';
5
+ import { SvgBlogHero } from '@datalayer/design/lib/svg/SvgBlogHero';
6
+ import { SvgCareersHero } from '@datalayer/design/lib/svg/SvgCareersHero';
7
+ import { SvgChangelogHero } from '@datalayer/design/lib/svg/SvgChangelogHero';
8
+ import { SvgCommunityHero } from '@datalayer/design/lib/svg/SvgCommunityHero';
9
+ import { SvgContactHero } from '@datalayer/design/lib/svg/SvgContactHero';
10
+ import { SvgEarthHero } from '@datalayer/design/lib/svg/SvgEarthHero';
11
+ import { SvgEvalsHero } from '@datalayer/design/lib/svg/SvgEvalsHero';
12
+ import { SvgEventsHero } from '@datalayer/design/lib/svg/SvgEventsHero';
13
+ import { SvgIntegrationsHero } from '@datalayer/design/lib/svg/SvgIntegrationsHero';
14
+ import { SvgLoginHero } from '@datalayer/design/lib/svg/SvgLoginHero';
15
+ import { SvgPartnersHero } from '@datalayer/design/lib/svg/SvgPartnersHero';
16
+ import { SvgPricingHero } from '@datalayer/design/lib/svg/SvgPricingHero';
17
+ import { SvgPrivacyHero } from '@datalayer/design/lib/svg/SvgPrivacyHero';
18
+ import { SvgResearchHero } from '@datalayer/design/lib/svg/SvgResearchHero';
19
+ import { SvgStarsHero } from '@datalayer/design/lib/svg/SvgStarsHero';
20
+ import { SvgTermsHero } from '@datalayer/design/lib/svg/SvgTermsHero';
21
+ import { SvgTutorialsHero } from '@datalayer/design/lib/svg/SvgTutorialsHero';
22
+ import { SvgUsecasesHero } from '@datalayer/design/lib/svg/SvgUsecasesHero';
23
+ export type PrincipalType = 'personal' | 'organization' | 'team';
24
+ type AvatarComponent = ComponentType<SVGProps<SVGSVGElement> & {
25
+ size?: number | 'small' | 'medium' | 'large';
26
+ colored?: boolean;
27
+ }>;
28
+ export declare const PRINCIPAL_AVATAR_ICONS: ReadonlyArray<{
29
+ name: string;
30
+ label: string;
31
+ Icon: AvatarComponent;
32
+ }>;
33
+ export declare const PRINCIPAL_BANNERS: readonly [{
34
+ readonly name: "SvgAboutHero";
35
+ readonly label: "About";
36
+ readonly Component: typeof SvgAboutHero;
37
+ }, {
38
+ readonly name: "SvgAgentsHero";
39
+ readonly label: "Agents";
40
+ readonly Component: typeof SvgAgentsHero;
41
+ }, {
42
+ readonly name: "SvgAgentsHomeHero";
43
+ readonly label: "Agents home";
44
+ readonly Component: typeof SvgAgentsHomeHero;
45
+ }, {
46
+ readonly name: "SvgBlogHero";
47
+ readonly label: "Blog";
48
+ readonly Component: typeof SvgBlogHero;
49
+ }, {
50
+ readonly name: "SvgCareersHero";
51
+ readonly label: "Careers";
52
+ readonly Component: typeof SvgCareersHero;
53
+ }, {
54
+ readonly name: "SvgChangelogHero";
55
+ readonly label: "Changelog";
56
+ readonly Component: typeof SvgChangelogHero;
57
+ }, {
58
+ readonly name: "SvgCommunityHero";
59
+ readonly label: "Community";
60
+ readonly Component: typeof SvgCommunityHero;
61
+ }, {
62
+ readonly name: "SvgContactHero";
63
+ readonly label: "Contact";
64
+ readonly Component: typeof SvgContactHero;
65
+ }, {
66
+ readonly name: "SvgEarthHero";
67
+ readonly label: "Earth";
68
+ readonly Component: typeof SvgEarthHero;
69
+ }, {
70
+ readonly name: "SvgEvalsHero";
71
+ readonly label: "Evaluations";
72
+ readonly Component: typeof SvgEvalsHero;
73
+ }, {
74
+ readonly name: "SvgEventsHero";
75
+ readonly label: "Events";
76
+ readonly Component: typeof SvgEventsHero;
77
+ }, {
78
+ readonly name: "SvgIntegrationsHero";
79
+ readonly label: "Integrations";
80
+ readonly Component: typeof SvgIntegrationsHero;
81
+ }, {
82
+ readonly name: "SvgLoginHero";
83
+ readonly label: "Login";
84
+ readonly Component: typeof SvgLoginHero;
85
+ }, {
86
+ readonly name: "SvgPartnersHero";
87
+ readonly label: "Partners";
88
+ readonly Component: typeof SvgPartnersHero;
89
+ }, {
90
+ readonly name: "SvgPricingHero";
91
+ readonly label: "Pricing";
92
+ readonly Component: typeof SvgPricingHero;
93
+ }, {
94
+ readonly name: "SvgPrivacyHero";
95
+ readonly label: "Privacy";
96
+ readonly Component: typeof SvgPrivacyHero;
97
+ }, {
98
+ readonly name: "SvgResearchHero";
99
+ readonly label: "Research";
100
+ readonly Component: typeof SvgResearchHero;
101
+ }, {
102
+ readonly name: "SvgStarsHero";
103
+ readonly label: "Stars";
104
+ readonly Component: typeof SvgStarsHero;
105
+ }, {
106
+ readonly name: "SvgTermsHero";
107
+ readonly label: "Terms";
108
+ readonly Component: typeof SvgTermsHero;
109
+ }, {
110
+ readonly name: "SvgTutorialsHero";
111
+ readonly label: "Tutorials";
112
+ readonly Component: typeof SvgTutorialsHero;
113
+ }, {
114
+ readonly name: "SvgUsecasesHero";
115
+ readonly label: "Use cases";
116
+ readonly Component: typeof SvgUsecasesHero;
117
+ }];
118
+ export declare function getPrincipalBannerForSeed(seed: string): string;
119
+ export declare function getPrincipalAvatarIcon(name?: string): AvatarComponent | undefined;
120
+ export declare function PrincipalBannerImage({ banner, height, }: {
121
+ banner?: string;
122
+ height?: number;
123
+ }): JSX.Element | null;
124
+ export declare function PrincipalAvatarPicker({ value, onChange, disabled, }: {
125
+ value?: string;
126
+ onChange: (name: string) => void;
127
+ disabled?: boolean;
128
+ }): JSX.Element;
129
+ export declare function PrincipalBannerPicker({ value, onChange, disabled, showPreview, }: {
130
+ value?: string;
131
+ onChange: (name: string) => void;
132
+ disabled?: boolean;
133
+ /** Off when the surface already shows the banner the picker changes. */
134
+ showPreview?: boolean;
135
+ }): JSX.Element;
136
+ export {};
@@ -0,0 +1,203 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /*
3
+ * Copyright (c) 2023-2026 Datalayer, Inc.
4
+ * Distributed under the terms of the Modified BSD License.
5
+ */
6
+ import { useEffect, useState } from 'react';
7
+ import { Box, Button, Text } from '@primer/react';
8
+ import { Dialog } from '@primer/react/experimental';
9
+ import AlienMonsterIcon from '@datalayer/icons-react/data2/AlienMonsterIcon';
10
+ import AstronautIcon from '@datalayer/icons-react/data2/AstronautIcon';
11
+ import ConstructionWorkerIcon from '@datalayer/icons-react/data2/ConstructionWorkerIcon';
12
+ import CowboyHatFaceIcon from '@datalayer/icons-react/data2/CowboyHatFaceIcon';
13
+ import DragonFaceIcon from '@datalayer/icons-react/data2/DragonFaceIcon';
14
+ import ElfManIcon from '@datalayer/icons-react/data2/ElfManIcon';
15
+ import FlyingSaucerIcon from '@datalayer/icons-react/data2/FlyingSaucerIcon';
16
+ import GremlinIcon from '@datalayer/icons-react/data2/GremlinIcon';
17
+ import GrinningFaceIcon from '@datalayer/icons-react/data2/GrinningFaceIcon';
18
+ import LizardIcon from '@datalayer/icons-react/data2/LizardIcon';
19
+ import MagicWandIcon from '@datalayer/icons-react/data2/MagicWandIcon';
20
+ import ManOfficeWorkerIcon from '@datalayer/icons-react/data2/ManOfficeWorkerIcon';
21
+ import ManTechnologistIcon from '@datalayer/icons-react/data2/ManTechnologistIcon';
22
+ import NinjaIcon from '@datalayer/icons-react/data2/NinjaIcon';
23
+ import PenguinIcon from '@datalayer/icons-react/data2/PenguinIcon';
24
+ import PersonSurfingIcon from '@datalayer/icons-react/data2/PersonSurfingIcon';
25
+ import PersonSwimmingIcon from '@datalayer/icons-react/data2/PersonSwimmingIcon';
26
+ import RingedPlanetIcon from '@datalayer/icons-react/data2/RingedPlanetIcon';
27
+ import RobotIcon from '@datalayer/icons-react/data2/RobotIcon';
28
+ import RocketIcon from '@datalayer/icons-react/data2/RocketIcon';
29
+ import SantaClausIcon from '@datalayer/icons-react/data2/SantaClausIcon';
30
+ import ScientistIcon from '@datalayer/icons-react/data2/ScientistIcon';
31
+ import SharkIcon from '@datalayer/icons-react/data2/SharkIcon';
32
+ import SnowmanIcon from '@datalayer/icons-react/data2/SnowmanIcon';
33
+ import StarIcon from '@datalayer/icons-react/data2/StarIcon';
34
+ import StudentWomanIcon from '@datalayer/icons-react/data2/StudentWomanIcon';
35
+ import SunIcon from '@datalayer/icons-react/data2/SunIcon';
36
+ import WhaleSpoutingIcon from '@datalayer/icons-react/data2/WhaleSpoutingIcon';
37
+ import WomanTechnologistIcon from '@datalayer/icons-react/data2/WomanTechnologistIcon';
38
+ import { SvgAboutHero } from '@datalayer/design/lib/svg/SvgAboutHero';
39
+ import { SvgAgentsHero } from '@datalayer/design/lib/svg/SvgAgentsHero';
40
+ import { SvgAgentsHomeHero } from '@datalayer/design/lib/svg/SvgAgentsHomeHero';
41
+ import { SvgBlogHero } from '@datalayer/design/lib/svg/SvgBlogHero';
42
+ import { SvgCareersHero } from '@datalayer/design/lib/svg/SvgCareersHero';
43
+ import { SvgChangelogHero } from '@datalayer/design/lib/svg/SvgChangelogHero';
44
+ import { SvgCommunityHero } from '@datalayer/design/lib/svg/SvgCommunityHero';
45
+ import { SvgContactHero } from '@datalayer/design/lib/svg/SvgContactHero';
46
+ import { SvgEarthHero } from '@datalayer/design/lib/svg/SvgEarthHero';
47
+ import { SvgEvalsHero } from '@datalayer/design/lib/svg/SvgEvalsHero';
48
+ import { SvgEventsHero } from '@datalayer/design/lib/svg/SvgEventsHero';
49
+ import { SvgIntegrationsHero } from '@datalayer/design/lib/svg/SvgIntegrationsHero';
50
+ import { SvgLoginHero } from '@datalayer/design/lib/svg/SvgLoginHero';
51
+ import { SvgPartnersHero } from '@datalayer/design/lib/svg/SvgPartnersHero';
52
+ import { SvgPricingHero } from '@datalayer/design/lib/svg/SvgPricingHero';
53
+ import { SvgPrivacyHero } from '@datalayer/design/lib/svg/SvgPrivacyHero';
54
+ import { SvgResearchHero } from '@datalayer/design/lib/svg/SvgResearchHero';
55
+ import { SvgStarsHero } from '@datalayer/design/lib/svg/SvgStarsHero';
56
+ import { SvgTermsHero } from '@datalayer/design/lib/svg/SvgTermsHero';
57
+ import { SvgTutorialsHero } from '@datalayer/design/lib/svg/SvgTutorialsHero';
58
+ import { SvgUsecasesHero } from '@datalayer/design/lib/svg/SvgUsecasesHero';
59
+ export const PRINCIPAL_AVATAR_ICONS = [
60
+ { name: 'AlienMonsterIcon', label: 'Alien monster', Icon: AlienMonsterIcon },
61
+ { name: 'AstronautIcon', label: 'Astronaut', Icon: AstronautIcon },
62
+ { name: 'ConstructionWorkerIcon', label: 'Construction worker', Icon: ConstructionWorkerIcon },
63
+ { name: 'CowboyHatFaceIcon', label: 'Cowboy', Icon: CowboyHatFaceIcon },
64
+ { name: 'DragonFaceIcon', label: 'Dragon', Icon: DragonFaceIcon },
65
+ { name: 'ElfManIcon', label: 'Elf', Icon: ElfManIcon },
66
+ { name: 'FlyingSaucerIcon', label: 'Flying saucer', Icon: FlyingSaucerIcon },
67
+ { name: 'GremlinIcon', label: 'Gremlin', Icon: GremlinIcon },
68
+ { name: 'GrinningFaceIcon', label: 'Grinning face', Icon: GrinningFaceIcon },
69
+ { name: 'LizardIcon', label: 'Lizard', Icon: LizardIcon },
70
+ { name: 'MagicWandIcon', label: 'Magic wand', Icon: MagicWandIcon },
71
+ { name: 'ManOfficeWorkerIcon', label: 'Office worker', Icon: ManOfficeWorkerIcon },
72
+ { name: 'ManTechnologistIcon', label: 'Man technologist', Icon: ManTechnologistIcon },
73
+ { name: 'NinjaIcon', label: 'Ninja', Icon: NinjaIcon },
74
+ { name: 'PenguinIcon', label: 'Penguin', Icon: PenguinIcon },
75
+ { name: 'PersonSurfingIcon', label: 'Surfer', Icon: PersonSurfingIcon },
76
+ { name: 'PersonSwimmingIcon', label: 'Swimmer', Icon: PersonSwimmingIcon },
77
+ { name: 'RingedPlanetIcon', label: 'Planet', Icon: RingedPlanetIcon },
78
+ { name: 'RobotIcon', label: 'Robot', Icon: RobotIcon },
79
+ { name: 'RocketIcon', label: 'Rocket', Icon: RocketIcon },
80
+ { name: 'SantaClausIcon', label: 'Santa', Icon: SantaClausIcon },
81
+ { name: 'ScientistIcon', label: 'Scientist', Icon: ScientistIcon },
82
+ { name: 'SharkIcon', label: 'Shark', Icon: SharkIcon },
83
+ { name: 'SnowmanIcon', label: 'Snowman', Icon: SnowmanIcon },
84
+ { name: 'StarIcon', label: 'Star', Icon: StarIcon },
85
+ { name: 'StudentWomanIcon', label: 'Student', Icon: StudentWomanIcon },
86
+ { name: 'SunIcon', label: 'Sun', Icon: SunIcon },
87
+ { name: 'WhaleSpoutingIcon', label: 'Whale', Icon: WhaleSpoutingIcon },
88
+ { name: 'WomanTechnologistIcon', label: 'Woman technologist', Icon: WomanTechnologistIcon },
89
+ ];
90
+ export const PRINCIPAL_BANNERS = [
91
+ { name: 'SvgAboutHero', label: 'About', Component: SvgAboutHero },
92
+ { name: 'SvgAgentsHero', label: 'Agents', Component: SvgAgentsHero },
93
+ { name: 'SvgAgentsHomeHero', label: 'Agents home', Component: SvgAgentsHomeHero },
94
+ { name: 'SvgBlogHero', label: 'Blog', Component: SvgBlogHero },
95
+ { name: 'SvgCareersHero', label: 'Careers', Component: SvgCareersHero },
96
+ { name: 'SvgChangelogHero', label: 'Changelog', Component: SvgChangelogHero },
97
+ { name: 'SvgCommunityHero', label: 'Community', Component: SvgCommunityHero },
98
+ { name: 'SvgContactHero', label: 'Contact', Component: SvgContactHero },
99
+ { name: 'SvgEarthHero', label: 'Earth', Component: SvgEarthHero },
100
+ { name: 'SvgEvalsHero', label: 'Evaluations', Component: SvgEvalsHero },
101
+ { name: 'SvgEventsHero', label: 'Events', Component: SvgEventsHero },
102
+ { name: 'SvgIntegrationsHero', label: 'Integrations', Component: SvgIntegrationsHero },
103
+ { name: 'SvgLoginHero', label: 'Login', Component: SvgLoginHero },
104
+ { name: 'SvgPartnersHero', label: 'Partners', Component: SvgPartnersHero },
105
+ { name: 'SvgPricingHero', label: 'Pricing', Component: SvgPricingHero },
106
+ { name: 'SvgPrivacyHero', label: 'Privacy', Component: SvgPrivacyHero },
107
+ { name: 'SvgResearchHero', label: 'Research', Component: SvgResearchHero },
108
+ { name: 'SvgStarsHero', label: 'Stars', Component: SvgStarsHero },
109
+ { name: 'SvgTermsHero', label: 'Terms', Component: SvgTermsHero },
110
+ { name: 'SvgTutorialsHero', label: 'Tutorials', Component: SvgTutorialsHero },
111
+ { name: 'SvgUsecasesHero', label: 'Use cases', Component: SvgUsecasesHero },
112
+ ];
113
+ export function getPrincipalBannerForSeed(seed) {
114
+ let hash = 0;
115
+ for (let index = 0; index < seed.length; index += 1) {
116
+ hash = (hash * 31 + seed.charCodeAt(index)) | 0;
117
+ }
118
+ return PRINCIPAL_BANNERS[Math.abs(hash) % PRINCIPAL_BANNERS.length].name;
119
+ }
120
+ export function getPrincipalAvatarIcon(name) {
121
+ return PRINCIPAL_AVATAR_ICONS.find(option => option.name === name)?.Icon;
122
+ }
123
+ export function PrincipalBannerImage({ banner, height = 180, }) {
124
+ const Banner = PRINCIPAL_BANNERS.find(option => option.name === banner)?.Component;
125
+ if (!Banner)
126
+ return null;
127
+ return (_jsx(Box, { sx: {
128
+ position: 'relative',
129
+ width: '100%',
130
+ height,
131
+ overflow: 'hidden',
132
+ borderRadius: 2,
133
+ bg: 'canvas.subtle',
134
+ '& > svg': {
135
+ position: 'absolute',
136
+ inset: 0,
137
+ display: 'block',
138
+ width: '100% !important',
139
+ height: '100% !important',
140
+ maxWidth: 'none !important',
141
+ maxHeight: 'none !important',
142
+ },
143
+ }, children: _jsx(Banner, {}) }, banner));
144
+ }
145
+ export function PrincipalAvatarPicker({ value, onChange, disabled = false, }) {
146
+ const [open, setOpen] = useState(false);
147
+ const selected = PRINCIPAL_AVATAR_ICONS.find(option => option.name === value);
148
+ return (_jsxs(_Fragment, { children: [_jsx(Button, { type: "button", disabled: disabled, onClick: () => setOpen(true), children: selected ? `Change Avatar (${selected.label})` : 'Choose Avatar' }), open ? (_jsx(Dialog, { title: "Choose an Avatar", onClose: () => setOpen(false), width: "large", sx: { width: 'min(720px, calc(100vw - 32px))', maxWidth: 'none' }, children: _jsx(Box, { sx: {
149
+ display: 'grid',
150
+ gridTemplateColumns: 'repeat(auto-fill, minmax(72px, 1fr))',
151
+ gap: 2,
152
+ }, children: PRINCIPAL_AVATAR_ICONS.map(({ name, label, Icon }) => (_jsx(Button, { type: "button", "aria-label": label, "aria-pressed": value === name, onClick: () => {
153
+ onChange(name);
154
+ setOpen(false);
155
+ }, sx: {
156
+ height: 72,
157
+ p: 1,
158
+ borderColor: value === name ? 'accent.emphasis' : 'border.default',
159
+ bg: value === name ? 'accent.subtle' : 'canvas.default',
160
+ }, children: _jsx(Icon, { size: 52, colored: true }) }, name))) }) })) : null] }));
161
+ }
162
+ export function PrincipalBannerPicker({ value, onChange, disabled = false, showPreview = true, }) {
163
+ const [open, setOpen] = useState(false);
164
+ const [selectedName, setSelectedName] = useState(value);
165
+ useEffect(() => setSelectedName(value), [value]);
166
+ const selected = PRINCIPAL_BANNERS.find(option => option.name === selectedName);
167
+ return (_jsxs(_Fragment, { children: [showPreview && selected ? (_jsx(Box, { sx: { mb: 2 }, children: _jsx(PrincipalBannerImage, { banner: selected.name, height: 120 }) })) : null, _jsx(Button, { type: "button", disabled: disabled, onClick: () => setOpen(true), children: selected ? `Change Banner (${selected.label})` : 'Choose Banner' }), open ? (_jsx(Dialog, { title: "Choose a Banner", onClose: () => setOpen(false), width: "xlarge", sx: { width: 'min(960px, calc(100vw - 32px))', maxWidth: 'none' }, children: _jsx(Box, { sx: {
168
+ display: 'grid',
169
+ gridTemplateColumns: ['1fr', 'repeat(3, minmax(0, 1fr))'],
170
+ gap: 3,
171
+ }, children: PRINCIPAL_BANNERS.map(({ name, label, Component }) => (_jsxs(Box, { as: "button", type: "button", "aria-label": label, "aria-pressed": selectedName === name, onClick: () => {
172
+ setSelectedName(name);
173
+ onChange(name);
174
+ setOpen(false);
175
+ }, sx: {
176
+ display: 'block',
177
+ width: '100%',
178
+ p: 0,
179
+ overflow: 'hidden',
180
+ appearance: 'none',
181
+ color: 'fg.default',
182
+ cursor: 'pointer',
183
+ border: '1px solid',
184
+ borderRadius: 2,
185
+ borderColor: selectedName === name ? 'accent.emphasis' : 'border.default',
186
+ bg: selectedName === name ? 'accent.subtle' : 'canvas.default',
187
+ textAlign: 'left',
188
+ ':hover': { borderColor: 'accent.emphasis' },
189
+ }, children: [_jsx(Box, { sx: {
190
+ position: 'relative',
191
+ width: '100%',
192
+ aspectRatio: '3 / 1',
193
+ overflow: 'hidden',
194
+ '& > svg': {
195
+ position: 'absolute',
196
+ inset: 0,
197
+ width: '100% !important',
198
+ height: '100% !important',
199
+ maxWidth: 'none !important',
200
+ maxHeight: 'none !important',
201
+ },
202
+ }, children: _jsx(Component, {}) }), _jsx(Text, { sx: { display: 'block', px: 2, py: 1, fontSize: 0 }, children: label })] }, name))) }) })) : null] }));
203
+ }
@@ -1,10 +1,13 @@
1
- export type PrincipalAvatarKind = 'personal' | 'team' | 'organization';
1
+ import { type PrincipalType } from './PrincipalAppearance';
2
+ export type PrincipalAvatarKind = PrincipalType;
2
3
  export type PrincipalAvatarProps = {
3
4
  kind: PrincipalAvatarKind;
4
5
  avatarUrl?: string;
6
+ avatarIcon?: string;
5
7
  alt?: string;
6
8
  size?: number;
7
9
  square?: boolean;
10
+ className?: string;
8
11
  };
9
- export declare function PrincipalAvatar({ kind, avatarUrl, alt, size, square, }: PrincipalAvatarProps): JSX.Element;
12
+ export declare function PrincipalAvatar({ kind, avatarUrl, avatarIcon, alt, size, square, className, }: PrincipalAvatarProps): JSX.Element;
10
13
  export default PrincipalAvatar;
@@ -6,17 +6,30 @@ import { jsx as _jsx } from "react/jsx-runtime";
6
6
  import { Box } from '@datalayer/primer-addons';
7
7
  import { OrganizationIcon, PeopleIcon } from '@primer/octicons-react';
8
8
  import { UserAvatar } from '../avatars/index.js';
9
+ import { getPrincipalAvatarIcon } from './PrincipalAppearance.js';
9
10
  function getFallbackIconSize(size) {
10
11
  return Math.max(12, Math.round(size * 0.62));
11
12
  }
12
- export function PrincipalAvatar({ kind, avatarUrl, alt, size = 20, square = false, }) {
13
+ export function PrincipalAvatar({ kind, avatarUrl, avatarIcon, alt, size = 20, square = false, className, }) {
14
+ const SelectedIcon = getPrincipalAvatarIcon(avatarIcon);
15
+ if (SelectedIcon) {
16
+ return (_jsx(Box, { className: className, sx: {
17
+ width: size,
18
+ height: size,
19
+ display: 'inline-flex',
20
+ alignItems: 'center',
21
+ justifyContent: 'center',
22
+ overflow: 'hidden',
23
+ borderRadius: square ? 2 : '50%',
24
+ }, "aria-label": alt || `${kind} avatar`, children: _jsx(SelectedIcon, { size: size, colored: true }) }));
25
+ }
13
26
  if (kind === 'personal') {
14
- return (_jsx(UserAvatar, { avatarUrl: avatarUrl, size: size, square: square, iconSize: getFallbackIconSize(size) }));
27
+ return (_jsx(UserAvatar, { avatarUrl: avatarUrl, avatarIcon: avatarIcon, size: size, square: square, iconSize: getFallbackIconSize(size), className: className }));
15
28
  }
16
29
  const iconSize = getFallbackIconSize(size);
17
30
  const borderRadius = square ? 2 : '50%';
18
31
  const Icon = kind === 'team' ? PeopleIcon : OrganizationIcon;
19
- return (_jsx(Box, { sx: {
32
+ return (_jsx(Box, { className: className, sx: {
20
33
  width: size,
21
34
  height: size,
22
35
  display: 'inline-flex',
@@ -115,6 +115,7 @@ export const PrincipalBadge = ({ principal: providedPrincipal, showPrincipalLabe
115
115
  lastName: user?.lastName,
116
116
  email: user?.email,
117
117
  avatarUrl: user?.avatarUrl,
118
+ avatarIcon: user?.avatarIcon,
118
119
  origin: normalizeUserOrigin(user?.origin),
119
120
  };
120
121
  }, [
@@ -130,6 +131,7 @@ export const PrincipalBadge = ({ principal: providedPrincipal, showPrincipalLabe
130
131
  user?.lastName,
131
132
  user?.email,
132
133
  user?.avatarUrl,
134
+ user?.avatarIcon,
133
135
  ]);
134
136
  const userLookupUid = basePrincipal.kind === 'personal' ? String(basePrincipal.uid || '') : '';
135
137
  const organizationLookupUid = basePrincipal.kind === 'organization'
@@ -153,6 +155,7 @@ export const PrincipalBadge = ({ principal: providedPrincipal, showPrincipalLabe
153
155
  `@${normalizedHandle}`,
154
156
  handle: resolvedHandle,
155
157
  accountHandle: resolvedHandle,
158
+ avatarIcon: resolvedOrganization?.avatarIcon || basePrincipal.avatarIcon,
156
159
  origin: basePrincipal.origin || 'Datalayer',
157
160
  };
158
161
  }
@@ -167,6 +170,7 @@ export const PrincipalBadge = ({ principal: providedPrincipal, showPrincipalLabe
167
170
  handle: basePrincipal.handle,
168
171
  accountHandle: basePrincipal.accountHandle,
169
172
  avatarUrl: basePrincipal.avatarUrl,
173
+ avatarIcon: basePrincipal.avatarIcon,
170
174
  origin: basePrincipal.origin,
171
175
  };
172
176
  }
@@ -198,6 +202,7 @@ export const PrincipalBadge = ({ principal: providedPrincipal, showPrincipalLabe
198
202
  lastName: resolvedUser?.lastName || basePrincipal.lastName,
199
203
  email: resolvedUser?.email || basePrincipal.email,
200
204
  avatarUrl: resolvedUser?.avatarUrl || basePrincipal.avatarUrl,
205
+ avatarIcon: resolvedUser?.avatarIcon || basePrincipal.avatarIcon,
201
206
  origin,
202
207
  };
203
208
  }, [
@@ -211,6 +216,8 @@ export const PrincipalBadge = ({ principal: providedPrincipal, showPrincipalLabe
211
216
  resolvedUser?.lastName,
212
217
  resolvedUser?.email,
213
218
  resolvedUser?.avatarUrl,
219
+ resolvedUser?.avatarIcon,
220
+ resolvedOrganization?.avatarIcon,
214
221
  resolvedUser?.origin,
215
222
  ]);
216
223
  return (_jsxs(Box, { sx: {
@@ -12,6 +12,7 @@ export type PrincipalDetailsOverlayProps = {
12
12
  email?: string;
13
13
  origin?: string;
14
14
  avatarUrl?: string;
15
+ avatarIcon?: string;
15
16
  /** Team-specific: parent organization display name. */
16
17
  organizationName?: string;
17
18
  /** Team-specific: number of members. */
@@ -27,5 +28,5 @@ export declare function buildPrincipalProfilePath({ kind, uid, handle, accountHa
27
28
  accountHandle?: string;
28
29
  isAdmin?: boolean;
29
30
  }): string | null;
30
- export declare function PrincipalDetailsOverlay({ kind, uid, displayName, name, description, handle, accountHandle, firstName, lastName, email, origin, avatarUrl, organizationName, memberCount, isPublic, isAdmin, }: PrincipalDetailsOverlayProps): JSX.Element;
31
+ export declare function PrincipalDetailsOverlay({ kind, uid, displayName, name, description, handle, accountHandle, firstName, lastName, email, origin, avatarUrl, avatarIcon, organizationName, memberCount, isPublic, isAdmin, }: PrincipalDetailsOverlayProps): JSX.Element;
31
32
  export default PrincipalDetailsOverlay;
@@ -80,7 +80,7 @@ export function buildPrincipalProfilePath({ kind, uid, handle, accountHandle, is
80
80
  }
81
81
  return null;
82
82
  }
83
- export function PrincipalDetailsOverlay({ kind, uid, displayName, name, description, handle, accountHandle, firstName, lastName, email, origin, avatarUrl, organizationName, memberCount, isPublic, isAdmin = false, }) {
83
+ export function PrincipalDetailsOverlay({ kind, uid, displayName, name, description, handle, accountHandle, firstName, lastName, email, origin, avatarUrl, avatarIcon, organizationName, memberCount, isPublic, isAdmin = false, }) {
84
84
  const navigate = useNavigate();
85
85
  const normalizedDisplayName = normalize(displayName) ||
86
86
  normalize(handle) ||
@@ -129,7 +129,7 @@ export function PrincipalDetailsOverlay({ kind, uid, displayName, name, descript
129
129
  ':hover': {
130
130
  textDecoration: 'underline',
131
131
  },
132
- }, children: normalizedDisplayName }) }), _jsx(ActionMenu.Overlay, { width: "large", children: _jsxs(Box, { sx: { display: 'grid', gap: 3, p: 4, minWidth: 420 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(PrincipalAvatar, { kind: kind, avatarUrl: avatarUrl, alt: normalizedDisplayName, size: 40 }), _jsxs(Box, { sx: { display: 'grid', gap: 0.5 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: normalizedDisplayName }), kind === 'team' ? (teamHandleOnly ? (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [displayHandleText(teamHandleOnly), teamOrganizationHandle
132
+ }, children: normalizedDisplayName }) }), _jsx(ActionMenu.Overlay, { width: "large", children: _jsxs(Box, { sx: { display: 'grid', gap: 3, p: 4, minWidth: 420 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(PrincipalAvatar, { kind: kind, avatarUrl: avatarUrl, avatarIcon: avatarIcon, alt: normalizedDisplayName, size: 40 }), _jsxs(Box, { sx: { display: 'grid', gap: 0.5 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: normalizedDisplayName }), kind === 'team' ? (teamHandleOnly ? (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: [displayHandleText(teamHandleOnly), teamOrganizationHandle
133
133
  ? ` · @${teamOrganizationHandle.replace(/^@+/, '')}`
134
134
  : ''] })) : null) : resolvedHandle ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: displayHandleText(resolvedHandle) })) : null] })] }), _jsxs(Box, { sx: {
135
135
  display: 'grid',
@@ -1,5 +1,6 @@
1
1
  export * from './Principal';
2
2
  export * from './PrincipalAvatar';
3
+ export * from './PrincipalAppearance';
3
4
  export * from './PrincipalBadge';
4
5
  export * from './PrincipalBanner';
5
6
  export { buildPrincipalProfilePath, PrincipalDetailsOverlay, } from './PrincipalDetailsOverlay';
@@ -4,6 +4,7 @@
4
4
  */
5
5
  export * from './Principal.js';
6
6
  export * from './PrincipalAvatar.js';
7
+ export * from './PrincipalAppearance.js';
7
8
  export * from './PrincipalBadge.js';
8
9
  export * from './PrincipalBanner.js';
9
10
  export { buildPrincipalProfilePath, PrincipalDetailsOverlay, } from './PrincipalDetailsOverlay.js';
@@ -33,6 +33,15 @@ export interface IConsumptionBarProps {
33
33
  * Duration is the kernel max duration in seconds.
34
34
  */
35
35
  onUpdate?: (progress: number, duration: number) => void;
36
+ /**
37
+ * Paddings of the indicator, each defaulting to what the button wears
38
+ * today. `0` collapses a side entirely — a host laying the bar out on a
39
+ * grid of its own passes zeros and spaces it itself.
40
+ */
41
+ paddingLeft?: number | string;
42
+ paddingRight?: number | string;
43
+ paddingTop?: number | string;
44
+ paddingBottom?: number | string;
36
45
  }
37
46
  /**
38
47
  * Consumption progress bar
@@ -31,7 +31,7 @@ function formatTimeRemaining(seconds) {
31
31
  * Consumption progress bar
32
32
  */
33
33
  export function ConsumptionBar(props) {
34
- const { expiredAt, startedAt, burningRate, onClick, onUpdate, refreshInterval = 2000, style, } = props;
34
+ const { expiredAt, startedAt, burningRate, onClick, onUpdate, refreshInterval = 2000, style, paddingLeft, paddingRight, paddingTop, paddingBottom, } = props;
35
35
  const duration = useMemo(() => getConsumptionDuration(startedAt, expiredAt), [expiredAt, startedAt]);
36
36
  const [progress, setProgress] = useState(getConsumptionProgress(startedAt, expiredAt));
37
37
  useEffect(() => {
@@ -62,5 +62,13 @@ export function ConsumptionBar(props) {
62
62
  onClick();
63
63
  }
64
64
  }
65
- : undefined, tabIndex: onClick ? 0 : -1, sx: { cursor: onClick ? 'pointer' : 'default' }, children: _jsx(Box, { sx: { width: '70px' }, children: _jsx(ProgressBar, { style: style, animated: expiredAt ? false : true, bg: bg, progress: progress }) }) }) }) }));
65
+ : undefined, tabIndex: onClick ? 0 : -1, sx: {
66
+ cursor: onClick ? 'pointer' : 'default',
67
+ // Only the sides that were asked for: an absent padding keeps
68
+ // the button's own.
69
+ ...(paddingLeft !== undefined ? { paddingLeft } : {}),
70
+ ...(paddingRight !== undefined ? { paddingRight } : {}),
71
+ ...(paddingTop !== undefined ? { paddingTop } : {}),
72
+ ...(paddingBottom !== undefined ? { paddingBottom } : {}),
73
+ }, children: _jsx(Box, { sx: { width: '70px' }, children: _jsx(ProgressBar, { style: style, animated: expiredAt ? false : true, bg: bg, progress: progress }) }) }) }) }));
66
74
  }
@@ -1408,7 +1408,12 @@ export function ShareAccessComponent({ isOpen, requestUrl, resourceLabel, resour
1408
1408
  bg: 'canvas.default',
1409
1409
  }, children: content }));
1410
1410
  }
1411
- return (_jsx(Dialog, { title: `Share ${resourceLabel.toLowerCase()}`, onClose: onClose, width: "large", children: content }));
1411
+ return (_jsx(Dialog, { title: `Share ${resourceLabel.toLowerCase()}`, onClose: onClose,
1412
+ // Wider than any preset — Primer's `xlarge` stops at 640px, and the
1413
+ // principal picker, the access levels and the ACL list all live in
1414
+ // this one surface. Capped to the viewport so small screens keep a
1415
+ // margin.
1416
+ width: "xlarge", sx: { width: 'min(960px, calc(100vw - 64px))', maxWidth: 'none' }, children: content }));
1412
1417
  }
1413
1418
  export default ShareAccessComponent;
1414
1419
  // Backward-compatible aliases (deprecated: use ShareAccessComponent).