@k2b/ui 0.45.0 → 0.46.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.
Files changed (96) hide show
  1. package/dist/browser/actions/Dropdown.js +8 -1
  2. package/dist/browser/actions/Dropdown.js.map +1 -1
  3. package/dist/browser/actions/FilterChip.js +11 -5
  4. package/dist/browser/actions/FilterChip.js.map +1 -1
  5. package/dist/browser/actions/ViewTabs.js +225 -93
  6. package/dist/browser/actions/ViewTabs.js.map +1 -1
  7. package/dist/browser/content/FileGrid.js +125 -99
  8. package/dist/browser/content/FileGrid.js.map +1 -1
  9. package/dist/browser/inputs/choice.js +36 -9
  10. package/dist/browser/inputs/choice.js.map +1 -1
  11. package/dist/browser/layout/AppWorkspace.js +30 -26
  12. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  13. package/dist/browser/layout/DetailPanel.js +130 -108
  14. package/dist/browser/layout/DetailPanel.js.map +1 -1
  15. package/dist/browser/layout/DetailSections.js +1019 -0
  16. package/dist/browser/layout/DetailSections.js.map +1 -0
  17. package/dist/browser/layout/DetailsToggle.js +32 -0
  18. package/dist/browser/layout/DetailsToggle.js.map +1 -0
  19. package/dist/browser/layout/Discussion.js +3 -0
  20. package/dist/browser/layout/Discussion.js.map +1 -1
  21. package/dist/browser/layout/MobileShell.js +116 -94
  22. package/dist/browser/layout/MobileShell.js.map +1 -1
  23. package/dist/browser/layout/PageTitle.js +33 -10
  24. package/dist/browser/layout/PageTitle.js.map +1 -1
  25. package/dist/browser/layout/app-workspace-controller.js +12 -0
  26. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  27. package/dist/browser/layout/detail-sections-messages.js +123 -0
  28. package/dist/browser/layout/detail-sections-messages.js.map +1 -0
  29. package/dist/browser/layout/index.js +2 -0
  30. package/dist/browser/layout/index.js.map +1 -1
  31. package/dist/browser/surfaces/Avatar.js +3 -1
  32. package/dist/browser/surfaces/Avatar.js.map +1 -1
  33. package/dist/browser/surfaces/AvatarStack.js +95 -61
  34. package/dist/browser/surfaces/AvatarStack.js.map +1 -1
  35. package/dist/browser/surfaces/ChangeList.js +77 -0
  36. package/dist/browser/surfaces/ChangeList.js.map +1 -0
  37. package/dist/browser/surfaces/index.js +2 -1
  38. package/dist/browser/surfaces/index.js.map +1 -1
  39. package/dist/browser/text-editor/TextEditor.js +19 -8
  40. package/dist/browser/text-editor/TextEditor.js.map +1 -1
  41. package/dist/ssr/actions/Dropdown.js +6 -0
  42. package/dist/ssr/actions/Dropdown.js.map +1 -1
  43. package/dist/ssr/actions/FilterChip.js +1 -1
  44. package/dist/ssr/actions/FilterChip.js.map +1 -1
  45. package/dist/ssr/actions/ViewTabs.js +144 -37
  46. package/dist/ssr/actions/ViewTabs.js.map +1 -1
  47. package/dist/ssr/content/FileGrid.js +36 -22
  48. package/dist/ssr/content/FileGrid.js.map +1 -1
  49. package/dist/ssr/inputs/choice.js +36 -9
  50. package/dist/ssr/inputs/choice.js.map +1 -1
  51. package/dist/ssr/layout/AppWorkspace.js +27 -27
  52. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  53. package/dist/ssr/layout/DetailPanel.js +17 -0
  54. package/dist/ssr/layout/DetailPanel.js.map +1 -1
  55. package/dist/ssr/layout/DetailSections.js +762 -0
  56. package/dist/ssr/layout/DetailSections.js.map +1 -0
  57. package/dist/ssr/layout/DetailsToggle.js +29 -0
  58. package/dist/ssr/layout/DetailsToggle.js.map +1 -0
  59. package/dist/ssr/layout/Discussion.js +3 -0
  60. package/dist/ssr/layout/Discussion.js.map +1 -1
  61. package/dist/ssr/layout/MobileShell.js +45 -28
  62. package/dist/ssr/layout/MobileShell.js.map +1 -1
  63. package/dist/ssr/layout/PageTitle.js +29 -6
  64. package/dist/ssr/layout/PageTitle.js.map +1 -1
  65. package/dist/ssr/layout/app-workspace-controller.js +12 -0
  66. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  67. package/dist/ssr/layout/detail-sections-messages.js +123 -0
  68. package/dist/ssr/layout/detail-sections-messages.js.map +1 -0
  69. package/dist/ssr/layout/index.js +2 -0
  70. package/dist/ssr/layout/index.js.map +1 -1
  71. package/dist/ssr/surfaces/Avatar.js +3 -1
  72. package/dist/ssr/surfaces/Avatar.js.map +1 -1
  73. package/dist/ssr/surfaces/AvatarStack.js +61 -32
  74. package/dist/ssr/surfaces/AvatarStack.js.map +1 -1
  75. package/dist/ssr/surfaces/ChangeList.js +37 -0
  76. package/dist/ssr/surfaces/ChangeList.js.map +1 -0
  77. package/dist/ssr/surfaces/index.js +2 -1
  78. package/dist/ssr/surfaces/index.js.map +1 -1
  79. package/dist/ssr/text-editor/TextEditor.js +19 -8
  80. package/dist/ssr/text-editor/TextEditor.js.map +1 -1
  81. package/dist/styles.css +1 -1
  82. package/dist/types/actions/FilterChip.d.ts +4 -0
  83. package/dist/types/actions/ViewTabs.d.ts +11 -1
  84. package/dist/types/content/FileGrid.d.ts +6 -0
  85. package/dist/types/inputs/choice.d.ts +9 -3
  86. package/dist/types/layout/DetailPanel.d.ts +9 -0
  87. package/dist/types/layout/DetailSections.d.ts +156 -0
  88. package/dist/types/layout/DetailsToggle.d.ts +13 -0
  89. package/dist/types/layout/PageTitle.d.ts +7 -0
  90. package/dist/types/layout/detail-sections-messages.d.ts +59 -0
  91. package/dist/types/layout/index.d.ts +4 -1
  92. package/dist/types/surfaces/Avatar.d.ts +3 -0
  93. package/dist/types/surfaces/AvatarStack.d.ts +20 -1
  94. package/dist/types/surfaces/ChangeList.d.ts +20 -0
  95. package/dist/types/surfaces/index.d.ts +5 -3
  96. package/package.json +3 -3
@@ -0,0 +1,123 @@
1
+ import { i18n } from "@k2b/stdlib";
2
+ import { useLocale } from "../intl/locale";
3
+
4
+ /** Titles and sentences of the shared detail sections: presence, access, links, properties, and tags. */
5
+ const detailSectionMessages = i18n.define({
6
+ baseLocale: "en",
7
+ messages: {
8
+ en: {
9
+ hereNow: "Here now",
10
+ onlyYou: "Only you",
11
+ you: "You",
12
+ writesIn: "in",
13
+ writing: "writing",
14
+ reading: "reading",
15
+ readingAlong: ({
16
+ names,
17
+ count
18
+ }) => count > 2 ? `${count} reading along` : `${names} ${count === 1 ? "is" : "are"} reading along`,
19
+ and: "and",
20
+ jumpTo: ({
21
+ name,
22
+ place
23
+ }) => `${name}, writing in “${place}”. Jump there`,
24
+ personWriting: ({
25
+ name,
26
+ place
27
+ }) => place ? `${name}, writing in “${place}”` : `${name}, writing`,
28
+ personReading: ({
29
+ name
30
+ }) => `${name}, reading`,
31
+ everyoneHere: ({
32
+ count
33
+ }) => `Here now: all ${count}, with you`,
34
+ presenceLoading: "Loading who is here",
35
+ presenceUnavailable: "Presence is unavailable right now",
36
+ retry: "Try again",
37
+ access: "Access",
38
+ accessLoading: "Loading who has access",
39
+ accessFailed: "Could not load who has access",
40
+ accessSummary: ({
41
+ names,
42
+ more
43
+ }) => more > 0 ? `${names} and ${more} more` : names,
44
+ links: "Links",
45
+ linkedBy: ({
46
+ count
47
+ }) => `Linked from ${count}`,
48
+ linksTo: ({
49
+ count
50
+ }) => `Links to ${count}`,
51
+ linkedBySummary: ({
52
+ names,
53
+ more
54
+ }) => more > 0 ? `Linked from ${names} and ${more} more` : `Linked from ${names}`,
55
+ linksToSummary: ({
56
+ names,
57
+ more
58
+ }) => more > 0 ? `Links to ${names} and ${more} more` : `Links to ${names}`,
59
+ properties: "Properties",
60
+ tags: "Tags"
61
+ },
62
+ de: {
63
+ hereNow: "Gerade hier",
64
+ onlyYou: "Nur du",
65
+ you: "Du",
66
+ writesIn: "in",
67
+ writing: "schreibt",
68
+ reading: "liest",
69
+ readingAlong: ({
70
+ names,
71
+ count
72
+ }) => count > 2 ? `${count} lesen mit` : `${names} ${count === 1 ? "liest" : "lesen"} mit`,
73
+ and: "und",
74
+ jumpTo: ({
75
+ name,
76
+ place
77
+ }) => `${name}, schreibt in „${place}“. Zur Stelle springen`,
78
+ personWriting: ({
79
+ name,
80
+ place
81
+ }) => place ? `${name}, schreibt in „${place}“` : `${name}, schreibt`,
82
+ personReading: ({
83
+ name
84
+ }) => `${name}, liest`,
85
+ everyoneHere: ({
86
+ count
87
+ }) => `Gerade hier: alle ${count}, mit dir`,
88
+ presenceLoading: "Lädt, wer gerade hier ist",
89
+ presenceUnavailable: "Anwesenheit gerade nicht verfügbar",
90
+ retry: "Erneut versuchen",
91
+ access: "Zugriff",
92
+ accessLoading: "Lädt, wer Zugriff hat",
93
+ accessFailed: "Zugriff konnte nicht geladen werden",
94
+ accessSummary: ({
95
+ names,
96
+ more
97
+ }) => more > 0 ? `${names} und ${more} weitere` : names,
98
+ links: "Verknüpfungen",
99
+ linkedBy: ({
100
+ count
101
+ }) => `Verlinkt von ${count}`,
102
+ linksTo: ({
103
+ count
104
+ }) => `Verweist auf ${count}`,
105
+ linkedBySummary: ({
106
+ names,
107
+ more
108
+ }) => more > 0 ? `Verlinkt von ${names} und ${more} weiteren` : `Verlinkt von ${names}`,
109
+ linksToSummary: ({
110
+ names,
111
+ more
112
+ }) => more > 0 ? `Verweist auf ${names} und ${more} weitere` : `Verweist auf ${names}`,
113
+ properties: "Eigenschaften",
114
+ tags: "Tags"
115
+ }
116
+ }
117
+ });
118
+ export const useDetailSectionMessages = () => {
119
+ const locale = useLocale();
120
+ return () => detailSectionMessages.resolve([locale()]).t;
121
+ };
122
+ export const checkDetailSectionMessages = () => detailSectionMessages.check();
123
+ //# sourceMappingURL=detail-sections-messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["layout/detail-sections-messages.ts"],"sourcesContent":["import { i18n } from \"@k2b/stdlib\";\nimport { useLocale } from \"../intl/locale\";\n\n/** Titles and sentences of the shared detail sections: presence, access, links, properties, and tags. */\nconst detailSectionMessages = i18n.define({\n baseLocale: \"en\",\n messages: {\n en: {\n hereNow: \"Here now\",\n onlyYou: \"Only you\",\n you: \"You\",\n writesIn: \"in\",\n writing: \"writing\",\n reading: \"reading\",\n readingAlong: ({ names, count }: { names: string; count: number }) =>\n count > 2 ? `${count} reading along` : `${names} ${count === 1 ? \"is\" : \"are\"} reading along`,\n and: \"and\",\n jumpTo: ({ name, place }: { name: string; place: string }) => `${name}, writing in “${place}”. Jump there`,\n personWriting: ({ name, place }: { name: string; place: string }) => (place ? `${name}, writing in “${place}”` : `${name}, writing`),\n personReading: ({ name }: { name: string }) => `${name}, reading`,\n everyoneHere: ({ count }: { count: number }) => `Here now: all ${count}, with you`,\n presenceLoading: \"Loading who is here\",\n presenceUnavailable: \"Presence is unavailable right now\",\n retry: \"Try again\",\n access: \"Access\",\n accessLoading: \"Loading who has access\",\n accessFailed: \"Could not load who has access\",\n accessSummary: ({ names, more }: { names: string; more: number }) => (more > 0 ? `${names} and ${more} more` : names),\n links: \"Links\",\n linkedBy: ({ count }: { count: number }) => `Linked from ${count}`,\n linksTo: ({ count }: { count: number }) => `Links to ${count}`,\n linkedBySummary: ({ names, more }: { names: string; more: number }) =>\n more > 0 ? `Linked from ${names} and ${more} more` : `Linked from ${names}`,\n linksToSummary: ({ names, more }: { names: string; more: number }) =>\n more > 0 ? `Links to ${names} and ${more} more` : `Links to ${names}`,\n properties: \"Properties\",\n tags: \"Tags\",\n },\n de: {\n hereNow: \"Gerade hier\",\n onlyYou: \"Nur du\",\n you: \"Du\",\n writesIn: \"in\",\n writing: \"schreibt\",\n reading: \"liest\",\n readingAlong: ({ names, count }) => (count > 2 ? `${count} lesen mit` : `${names} ${count === 1 ? \"liest\" : \"lesen\"} mit`),\n and: \"und\",\n jumpTo: ({ name, place }) => `${name}, schreibt in „${place}“. Zur Stelle springen`,\n personWriting: ({ name, place }) => (place ? `${name}, schreibt in „${place}“` : `${name}, schreibt`),\n personReading: ({ name }) => `${name}, liest`,\n everyoneHere: ({ count }) => `Gerade hier: alle ${count}, mit dir`,\n presenceLoading: \"Lädt, wer gerade hier ist\",\n presenceUnavailable: \"Anwesenheit gerade nicht verfügbar\",\n retry: \"Erneut versuchen\",\n access: \"Zugriff\",\n accessLoading: \"Lädt, wer Zugriff hat\",\n accessFailed: \"Zugriff konnte nicht geladen werden\",\n accessSummary: ({ names, more }) => (more > 0 ? `${names} und ${more} weitere` : names),\n links: \"Verknüpfungen\",\n linkedBy: ({ count }) => `Verlinkt von ${count}`,\n linksTo: ({ count }) => `Verweist auf ${count}`,\n linkedBySummary: ({ names, more }) => (more > 0 ? `Verlinkt von ${names} und ${more} weiteren` : `Verlinkt von ${names}`),\n linksToSummary: ({ names, more }) => (more > 0 ? `Verweist auf ${names} und ${more} weitere` : `Verweist auf ${names}`),\n properties: \"Eigenschaften\",\n tags: \"Tags\",\n },\n },\n});\n\nexport type DetailSectionMessages = ReturnType<(typeof detailSectionMessages)[\"resolve\"]>[\"t\"];\n\nexport const useDetailSectionMessages = (): (() => DetailSectionMessages) => {\n const locale = useLocale();\n return () => detailSectionMessages.resolve([locale()]).t;\n};\n\nexport const checkDetailSectionMessages = () => detailSectionMessages.check();\n"],"mappings":"AAAA,SAAS,IAAI,QAAQ,aAAa;AAClC,SAAS,SAAS,QAAQ,gBAAgB;;AAE1C;AACA,MAAM,qBAAqB,GAAG,IAAI,CAAC,MAAM,CAAC;EACxC,UAAU,EAAE,IAAI;EAChB,QAAQ,EAAE;IACR,EAAE,EAAE;MACF,OAAO,EAAE,UAAU;MACnB,OAAO,EAAE,UAAU;MACnB,GAAG,EAAE,KAAK;MACV,QAAQ,EAAE,IAAI;MACd,OAAO,EAAE,SAAS;MAClB,OAAO,EAAE,SAAS;MAClB,YAAY,EAAE,CAAC;QAAE,KAAK;QAAE;MAAwC,CAAC,KAC/D,KAAK,GAAG,CAAC,GAAG,GAAG,KAAK,gBAAgB,GAAG,GAAG,KAAK,IAAI,KAAK,KAAK,CAAC,GAAG,IAAI,GAAG,KAAK,gBAAgB;MAC/F,GAAG,EAAE,KAAK;MACV,MAAM,EAAE,CAAC;QAAE,IAAI;QAAE;MAAuC,CAAC,KAAK,GAAG,IAAI,iBAAiB,KAAK,eAAe;MAC1G,aAAa,EAAE,CAAC;QAAE,IAAI;QAAE;MAAuC,CAAC,KAAM,KAAK,GAAG,GAAG,IAAI,iBAAiB,KAAK,GAAG,GAAG,GAAG,IAAI,WAAY;MACpI,aAAa,EAAE,CAAC;QAAE;MAAuB,CAAC,KAAK,GAAG,IAAI,WAAW;MACjE,YAAY,EAAE,CAAC;QAAE;MAAyB,CAAC,KAAK,iBAAiB,KAAK,YAAY;MAClF,eAAe,EAAE,qBAAqB;MACtC,mBAAmB,EAAE,mCAAmC;MACxD,KAAK,EAAE,WAAW;MAClB,MAAM,EAAE,QAAQ;MAChB,aAAa,EAAE,wBAAwB;MACvC,YAAY,EAAE,+BAA+B;MAC7C,aAAa,EAAE,CAAC;QAAE,KAAK;QAAE;MAAsC,CAAC,KAAM,IAAI,GAAG,CAAC,GAAG,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAM;MACrH,KAAK,EAAE,OAAO;MACd,QAAQ,EAAE,CAAC;QAAE;MAAyB,CAAC,KAAK,eAAe,KAAK,EAAE;MAClE,OAAO,EAAE,CAAC;QAAE;MAAyB,CAAC,KAAK,YAAY,KAAK,EAAE;MAC9D,eAAe,EAAE,CAAC;QAAE,KAAK;QAAE;MAAsC,CAAC,KAChE,IAAI,GAAG,CAAC,GAAG,eAAe,KAAK,QAAQ,IAAI,OAAO,GAAG,eAAe,KAAK,EAAE;MAC7E,cAAc,EAAE,CAAC;QAAE,KAAK;QAAE;MAAsC,CAAC,KAC/D,IAAI,GAAG,CAAC,GAAG,YAAY,KAAK,QAAQ,IAAI,OAAO,GAAG,YAAY,KAAK,EAAE;MACvE,UAAU,EAAE,YAAY;MACxB,IAAI,EAAE;IACR,CAAC;IACD,EAAE,EAAE;MACF,OAAO,EAAE,aAAa;MACtB,OAAO,EAAE,QAAQ;MACjB,GAAG,EAAE,IAAI;MACT,QAAQ,EAAE,IAAI;MACd,OAAO,EAAE,UAAU;MACnB,OAAO,EAAE,OAAO;MAChB,YAAY,EAAE,CAAC;QAAE,KAAK;QAAE;MAAM,CAAC,KAAM,KAAK,GAAG,CAAC,GAAG,GAAG,KAAK,YAAY,GAAG,GAAG,KAAK,IAAI,KAAK,KAAK,CAAC,GAAG,OAAO,GAAG,OAAO,MAAO;MAC1H,GAAG,EAAE,KAAK;MACV,MAAM,EAAE,CAAC;QAAE,IAAI;QAAE;MAAM,CAAC,KAAK,GAAG,IAAI,kBAAkB,KAAK,wBAAwB;MACnF,aAAa,EAAE,CAAC;QAAE,IAAI;QAAE;MAAM,CAAC,KAAM,KAAK,GAAG,GAAG,IAAI,kBAAkB,KAAK,GAAG,GAAG,GAAG,IAAI,YAAa;MACrG,aAAa,EAAE,CAAC;QAAE;MAAK,CAAC,KAAK,GAAG,IAAI,SAAS;MAC7C,YAAY,EAAE,CAAC;QAAE;MAAM,CAAC,KAAK,qBAAqB,KAAK,WAAW;MAClE,eAAe,EAAE,2BAA2B;MAC5C,mBAAmB,EAAE,oCAAoC;MACzD,KAAK,EAAE,kBAAkB;MACzB,MAAM,EAAE,SAAS;MACjB,aAAa,EAAE,uBAAuB;MACtC,YAAY,EAAE,qCAAqC;MACnD,aAAa,EAAE,CAAC;QAAE,KAAK;QAAE;MAAK,CAAC,KAAM,IAAI,GAAG,CAAC,GAAG,GAAG,KAAK,QAAQ,IAAI,UAAU,GAAG,KAAM;MACvF,KAAK,EAAE,eAAe;MACtB,QAAQ,EAAE,CAAC;QAAE;MAAM,CAAC,KAAK,gBAAgB,KAAK,EAAE;MAChD,OAAO,EAAE,CAAC;QAAE;MAAM,CAAC,KAAK,gBAAgB,KAAK,EAAE;MAC/C,eAAe,EAAE,CAAC;QAAE,KAAK;QAAE;MAAK,CAAC,KAAM,IAAI,GAAG,CAAC,GAAG,gBAAgB,KAAK,QAAQ,IAAI,WAAW,GAAG,gBAAgB,KAAK,EAAG;MACzH,cAAc,EAAE,CAAC;QAAE,KAAK;QAAE;MAAK,CAAC,KAAM,IAAI,GAAG,CAAC,GAAG,gBAAgB,KAAK,QAAQ,IAAI,UAAU,GAAG,gBAAgB,KAAK,EAAG;MACvH,UAAU,EAAE,eAAe;MAC3B,IAAI,EAAE;IACR;EACF;AACF,CAAC,CAAC;AAIF,OAAO,MAAM,wBAAwB,GAAG,MAAqC;EAC3E,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC;EAC1B,OAAO,MAAM,qBAAqB,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,OAAO,MAAM,0BAA0B,GAAG,MAAM,qBAAqB,CAAC,KAAK,CAAC,CAAC","ignoreList":[]}
@@ -7,6 +7,8 @@ export { APP_WORKSPACE_DETAIL_DEFAULT, APP_WORKSPACE_DETAIL_MAX, APP_WORKSPACE_D
7
7
  export { bottomSheetAdaptiveOptions, bottomSheetOptions, default as BottomSheet } from "./BottomSheet";
8
8
  export { DataPanel } from "./DataPanel";
9
9
  export { default as DetailPanel } from "./DetailPanel";
10
+ export { DetailAccess, DetailLinks, DetailPresence, DetailPresenceSlot, DetailProperties, DetailTags } from "./DetailSections";
11
+ export { DETAILS_ICON, DetailsToggle } from "./DetailsToggle";
10
12
  export { default as Discussion } from "./Discussion";
11
13
  export { default as FloatingWindow, fitFloatingWindowRect, openFloatingWindow } from "./FloatingWindow";
12
14
  export { default as MobileShell, observeMobileShell } from "./MobileShell";
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["layout/index.ts"],"sourcesContent":["export { AnchoredPopover, type AnchoredPopoverProps } from \"./AnchoredPopover\";\nexport type {\n AppOverviewCardsProps,\n AppOverviewEmptyStateProps,\n AppOverviewPanelProps,\n AppOverviewProps,\n} from \"./AppOverview\";\nexport { default as AppOverview } from \"./AppOverview\";\nexport type {\n AppWorkspaceBottomDrawerHeight,\n AppWorkspaceBottomDrawerProps,\n AppWorkspaceContentProps,\n AppWorkspaceDetailProps,\n AppWorkspaceDetailWidth,\n AppWorkspaceHeadProps,\n AppWorkspaceMainPaneProps,\n AppWorkspaceMainProps,\n AppWorkspaceNavTreeItemProps,\n AppWorkspaceNavTreeMove,\n AppWorkspaceNavTreeProps,\n AppWorkspaceProps,\n AppWorkspaceSidebarAccessoryVisibility,\n AppWorkspaceSidebarBodyProps,\n AppWorkspaceSidebarIconActionProps,\n AppWorkspaceSidebarIconActionTone,\n AppWorkspaceSidebarIconGridProps,\n AppWorkspaceSidebarItemActionProps,\n AppWorkspaceSidebarItemActionsProps,\n AppWorkspaceSidebarItemIconProps,\n AppWorkspaceSidebarItemLabelProps,\n AppWorkspaceSidebarItemMetaProps,\n AppWorkspaceSidebarItemProps,\n AppWorkspaceSidebarItemStatusProps,\n AppWorkspaceSidebarItemTone,\n AppWorkspaceSidebarProps,\n AppWorkspaceSidebarSectionProps,\n AppWorkspaceSidebarVisibility,\n AppWorkspaceWidthShare,\n} from \"./AppWorkspace\";\nexport { appWorkspaceDetailElementId, default as AppWorkspace } from \"./AppWorkspace\";\nexport { watchAppHostWidth } from \"./app-host-width\";\nexport type { AppWorkspaceControllerOptions } from \"./app-workspace-controller\";\nexport { installAppWorkspaceController, parkWorkspaceDetailDrawers } from \"./app-workspace-controller\";\nexport type {\n AppWorkspaceLayoutState,\n AppWorkspaceResizeKind,\n} from \"./app-workspace-state\";\nexport {\n APP_WORKSPACE_DETAIL_DEFAULT,\n APP_WORKSPACE_DETAIL_MAX,\n APP_WORKSPACE_DETAIL_MIN,\n APP_WORKSPACE_DRAWER_DEFAULT,\n APP_WORKSPACE_DRAWER_MAX,\n APP_WORKSPACE_DRAWER_MIN,\n APP_WORKSPACE_MAIN_MIN,\n APP_WORKSPACE_MAIN_MIN_HEIGHT,\n APP_WORKSPACE_PANE_DEFAULT,\n APP_WORKSPACE_PANE_MAX,\n APP_WORKSPACE_PANE_MIN,\n APP_WORKSPACE_SIDEBAR_COLLAPSE_THRESHOLD,\n APP_WORKSPACE_SIDEBAR_COLLAPSED,\n APP_WORKSPACE_SIDEBAR_DEFAULT,\n APP_WORKSPACE_SIDEBAR_MAX,\n APP_WORKSPACE_SIDEBAR_MIN,\n appWorkspaceLayoutStyle,\n appWorkspacePanelVariable,\n appWorkspaceResizeLimits,\n normalizeAppWorkspaceLayoutState,\n parseAppWorkspaceLayoutState,\n resolveAppWorkspaceSidebarWidth,\n safeAppWorkspacePanelId,\n serializeAppWorkspaceLayoutState,\n shouldCollapseAppWorkspaceSidebar,\n} from \"./app-workspace-state\";\nexport { type BottomSheetProps, bottomSheetAdaptiveOptions, bottomSheetOptions, default as BottomSheet } from \"./BottomSheet\";\nexport type { DataPanelProps } from \"./DataPanel\";\nexport { DataPanel } from \"./DataPanel\";\nexport type {\n DetailPanelActionButtonProps,\n DetailPanelActionLinkProps,\n DetailPanelActionProps,\n DetailPanelActionSecondary,\n DetailPanelBodyProps,\n DetailPanelGroupProps,\n DetailPanelHeaderProps,\n DetailPanelProps,\n DetailPanelSectionProps,\n DetailPanelSummaryProps,\n DetailPanelTone,\n} from \"./DetailPanel\";\nexport { default as DetailPanel } from \"./DetailPanel\";\nexport type { DiscussionComposerProps, DiscussionItemProps, DiscussionListProps, DiscussionProps } from \"./Discussion\";\nexport { default as Discussion } from \"./Discussion\";\nexport type {\n FloatingWindowClose,\n FloatingWindowProps,\n OpenFloatingWindowOptions,\n} from \"./FloatingWindow\";\nexport {\n default as FloatingWindow,\n type FloatingWindowRect,\n fitFloatingWindowRect,\n openFloatingWindow,\n} from \"./FloatingWindow\";\nexport type { MobileShellHeaderProps, MobileShellProps, MobileShellSidebarItem, MobileShellSidebarProps } from \"./MobileShell\";\nexport { default as MobileShell, observeMobileShell } from \"./MobileShell\";\nexport { default as Navigation, type NavigationProps } from \"./Navigation\";\nexport {\n createNavigation,\n findNavigationItem,\n type NavigationController,\n type NavigationItem,\n type NavigationOptions,\n type NavigationStatus,\n} from \"./navigation-model\";\nexport type { PageTitleProps, PageTrailLink, PageTrailState } from \"./PageTitle\";\nexport { followPageTrail, PAGE_TRAIL_EVENT, PageTitle, PageTrailProvider, readPageTrail, setPageTrail, usePageTrail } from \"./PageTitle\";\nexport type {\n PanelDialogBodyProps,\n PanelDialogFooterProps,\n PanelDialogHeaderProps,\n PanelDialogProps,\n PanelDialogSectionProps,\n PanelDialogSurface,\n PanelDialogTabOption,\n PanelDialogTabsProps,\n} from \"./PanelDialog\";\nexport {\n confirmDiscardIfDirty,\n default as PanelDialog,\n panelDialogFixedOptions,\n panelDialogFixedPanelClass,\n panelDialogOptions,\n panelDialogPanelClass,\n panelDialogWideOptions,\n panelDialogWidePanelClass,\n panelDialogWorkspaceOptions,\n panelDialogWorkspacePanelClass,\n} from \"./PanelDialog\";\nexport type { PanelHeaderProps } from \"./PanelHeader\";\nexport { PanelHeader } from \"./PanelHeader\";\nexport type { PanesItem, PanesProps } from \"./Panes\";\nexport { default as Panes } from \"./Panes\";\nexport type { PullToRefreshProps, PullToRefreshState } from \"./PullToRefresh\";\nexport { default as PullToRefresh } from \"./PullToRefresh\";\nexport { installPageTitleController } from \"./page-title-controller\";\nexport type {\n AddPanesItemOptions,\n PanesDirection,\n PanesGroup,\n PanesIntent,\n PanesLayout,\n PanesNode,\n PanesPath,\n PanesPathSegment,\n PanesSide,\n PanesSplit,\n} from \"./panes-layout\";\nexport {\n activatePanesItem,\n addPanesItem,\n applyPanesIntent,\n createPanesLayout,\n isPanesItemVisible,\n PANES_LAYOUT_VERSION,\n parsePanesLayout,\n reconcilePanesLayout,\n removePanesItem,\n resizePanesSplit,\n} from \"./panes-layout\";\nexport { default as ResizeSeparator, type ResizeSeparatorProps } from \"./ResizeSeparator\";\nexport { attachResizeSeparator, type ResizeSeparatorOptions } from \"./resize-separator\";\nexport type { ScrollAreaProps } from \"./ScrollArea\";\nexport { default as ScrollArea } from \"./ScrollArea\";\nexport type {\n SaveStatusProps,\n SaveStatusState,\n SettingsFieldControlProps,\n SettingsFieldProps,\n SettingsFieldWidth,\n SettingsGroupActionProps,\n SettingsGroupProps,\n SettingsPageProps,\n SettingsPanelFooterProps,\n SettingsSaveBarProps,\n SettingsSectionProps,\n} from \"./Settings\";\nexport {\n readSettingsError,\n SaveStatus,\n SettingsField,\n SettingsGroup,\n SettingsPage,\n SettingsPanelFooter,\n SettingsSaveBar,\n SettingsSection,\n sameSettingValue,\n} from \"./Settings\";\nexport type {\n SettingsCollectionActionProps,\n SettingsCollectionItemActionsProps,\n SettingsCollectionItemProps,\n SettingsCollectionItemReorderProps,\n SettingsCollectionItemStatusProps,\n SettingsCollectionProps,\n} from \"./SettingsCollection\";\nexport { default as SettingsCollection } from \"./SettingsCollection\";\nexport type {\n SettingsModalFooterProps,\n SettingsModalGroupProps,\n SettingsModalProps,\n SettingsModalTabProps,\n SettingsModalTabTone,\n} from \"./SettingsModal\";\nexport { default as SettingsModal } from \"./SettingsModal\";\nexport {\n APP_WORKSPACE_SWITCHER_SEARCH_FROM,\n type AppWorkspaceSidebarSwitcherProps,\n type AppWorkspaceSwitcherAction,\n type AppWorkspaceSwitcherOption,\n} from \"./SidebarSwitcher\";\nexport { measureScrollFade } from \"./scroll-fade\";\nexport type { TabBarItem, TabBarProps } from \"./TabBar\";\nexport { default as TabBar } from \"./TabBar\";\nexport type { TableOfContentsItem, TableOfContentsProps } from \"./TableOfContents\";\nexport { TableOfContents } from \"./TableOfContents\";\n"],"mappings":"AAAA,SAAS,eAAe,QAAmC,mBAAmB;AAO9E,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AAgCtD,SAAS,2BAA2B,EAAE,OAAO,IAAI,YAAY,QAAQ,gBAAgB;AACrF,SAAS,iBAAiB,QAAQ,kBAAkB;AAEpD,SAAS,6BAA6B,EAAE,0BAA0B,QAAQ,4BAA4B;AAKtG,SACE,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,6BAA6B,EAC7B,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,EACtB,wCAAwC,EACxC,+BAA+B,EAC/B,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,EACzB,wBAAwB,EACxB,gCAAgC,EAChC,4BAA4B,EAC5B,+BAA+B,EAC/B,uBAAuB,EACvB,gCAAgC,EAChC,iCAAiC,QAC5B,uBAAuB;AAC9B,SAAgC,0BAA0B,EAAE,kBAAkB,EAAE,OAAO,IAAI,WAAW,QAAQ,eAAe;AAE7H,SAAS,SAAS,QAAQ,aAAa;AAcvC,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AAEtD,SAAS,OAAO,IAAI,UAAU,QAAQ,cAAc;AAMpD,SACE,OAAO,IAAI,cAAc,EAEzB,qBAAqB,EACrB,kBAAkB,QACb,kBAAkB;AAEzB,SAAS,OAAO,IAAI,WAAW,EAAE,kBAAkB,QAAQ,eAAe;AAC1E,SAAS,OAAO,IAAI,UAAU,QAA8B,cAAc;AAC1E,SACE,gBAAgB,EAChB,kBAAkB,QAKb,oBAAoB;AAE3B,SAAS,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,QAAQ,aAAa;AAWxI,SACE,qBAAqB,EACrB,OAAO,IAAI,WAAW,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,EAC3B,8BAA8B,QACzB,eAAe;AAEtB,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,OAAO,IAAI,KAAK,QAAQ,SAAS;AAE1C,SAAS,OAAO,IAAI,aAAa,QAAQ,iBAAiB;AAC1D,SAAS,0BAA0B,QAAQ,yBAAyB;AAapE,SACE,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,gBAAgB,QACX,gBAAgB;AACvB,SAAS,OAAO,IAAI,eAAe,QAAmC,mBAAmB;AACzF,SAAS,qBAAqB,QAAqC,oBAAoB;AAEvF,SAAS,OAAO,IAAI,UAAU,QAAQ,cAAc;AAcpD,SACE,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,gBAAgB,QACX,YAAY;AASnB,SAAS,OAAO,IAAI,kBAAkB,QAAQ,sBAAsB;AAQpE,SAAS,OAAO,IAAI,aAAa,QAAQ,iBAAiB;AAC1D,SACE,kCAAkC,QAI7B,mBAAmB;AAC1B,SAAS,iBAAiB,QAAQ,eAAe;AAEjD,SAAS,OAAO,IAAI,MAAM,QAAQ,UAAU;AAE5C,SAAS,eAAe,QAAQ,mBAAmB","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["layout/index.ts"],"sourcesContent":["export { AnchoredPopover, type AnchoredPopoverProps } from \"./AnchoredPopover\";\nexport type {\n AppOverviewCardsProps,\n AppOverviewEmptyStateProps,\n AppOverviewPanelProps,\n AppOverviewProps,\n} from \"./AppOverview\";\nexport { default as AppOverview } from \"./AppOverview\";\nexport type {\n AppWorkspaceBottomDrawerHeight,\n AppWorkspaceBottomDrawerProps,\n AppWorkspaceContentProps,\n AppWorkspaceDetailProps,\n AppWorkspaceDetailWidth,\n AppWorkspaceHeadProps,\n AppWorkspaceMainPaneProps,\n AppWorkspaceMainProps,\n AppWorkspaceNavTreeItemProps,\n AppWorkspaceNavTreeMove,\n AppWorkspaceNavTreeProps,\n AppWorkspaceProps,\n AppWorkspaceSidebarAccessoryVisibility,\n AppWorkspaceSidebarBodyProps,\n AppWorkspaceSidebarIconActionProps,\n AppWorkspaceSidebarIconActionTone,\n AppWorkspaceSidebarIconGridProps,\n AppWorkspaceSidebarItemActionProps,\n AppWorkspaceSidebarItemActionsProps,\n AppWorkspaceSidebarItemIconProps,\n AppWorkspaceSidebarItemLabelProps,\n AppWorkspaceSidebarItemMetaProps,\n AppWorkspaceSidebarItemProps,\n AppWorkspaceSidebarItemStatusProps,\n AppWorkspaceSidebarItemTone,\n AppWorkspaceSidebarProps,\n AppWorkspaceSidebarSectionProps,\n AppWorkspaceSidebarVisibility,\n AppWorkspaceWidthShare,\n} from \"./AppWorkspace\";\nexport { appWorkspaceDetailElementId, default as AppWorkspace } from \"./AppWorkspace\";\nexport { watchAppHostWidth } from \"./app-host-width\";\nexport type { AppWorkspaceControllerOptions } from \"./app-workspace-controller\";\nexport { installAppWorkspaceController, parkWorkspaceDetailDrawers } from \"./app-workspace-controller\";\nexport type {\n AppWorkspaceLayoutState,\n AppWorkspaceResizeKind,\n} from \"./app-workspace-state\";\nexport {\n APP_WORKSPACE_DETAIL_DEFAULT,\n APP_WORKSPACE_DETAIL_MAX,\n APP_WORKSPACE_DETAIL_MIN,\n APP_WORKSPACE_DRAWER_DEFAULT,\n APP_WORKSPACE_DRAWER_MAX,\n APP_WORKSPACE_DRAWER_MIN,\n APP_WORKSPACE_MAIN_MIN,\n APP_WORKSPACE_MAIN_MIN_HEIGHT,\n APP_WORKSPACE_PANE_DEFAULT,\n APP_WORKSPACE_PANE_MAX,\n APP_WORKSPACE_PANE_MIN,\n APP_WORKSPACE_SIDEBAR_COLLAPSE_THRESHOLD,\n APP_WORKSPACE_SIDEBAR_COLLAPSED,\n APP_WORKSPACE_SIDEBAR_DEFAULT,\n APP_WORKSPACE_SIDEBAR_MAX,\n APP_WORKSPACE_SIDEBAR_MIN,\n appWorkspaceLayoutStyle,\n appWorkspacePanelVariable,\n appWorkspaceResizeLimits,\n normalizeAppWorkspaceLayoutState,\n parseAppWorkspaceLayoutState,\n resolveAppWorkspaceSidebarWidth,\n safeAppWorkspacePanelId,\n serializeAppWorkspaceLayoutState,\n shouldCollapseAppWorkspaceSidebar,\n} from \"./app-workspace-state\";\nexport { type BottomSheetProps, bottomSheetAdaptiveOptions, bottomSheetOptions, default as BottomSheet } from \"./BottomSheet\";\nexport type { DataPanelProps } from \"./DataPanel\";\nexport { DataPanel } from \"./DataPanel\";\nexport type {\n DetailPanelActionButtonProps,\n DetailPanelActionLinkProps,\n DetailPanelActionProps,\n DetailPanelActionSecondary,\n DetailPanelBodyProps,\n DetailPanelGroupProps,\n DetailPanelHeaderProps,\n DetailPanelProps,\n DetailPanelRowProps,\n DetailPanelSectionProps,\n DetailPanelSummaryProps,\n DetailPanelTone,\n} from \"./DetailPanel\";\nexport { default as DetailPanel } from \"./DetailPanel\";\nexport type {\n DetailAccessEntry,\n DetailAccessProps,\n DetailLinkItem,\n DetailLinksProps,\n DetailPresencePerson,\n DetailPresenceProps,\n DetailPresenceState,\n DetailPropertiesProps,\n DetailProperty,\n DetailTag,\n DetailTagsProps,\n} from \"./DetailSections\";\nexport { DetailAccess, DetailLinks, DetailPresence, DetailPresenceSlot, DetailProperties, DetailTags } from \"./DetailSections\";\nexport { DETAILS_ICON, DetailsToggle, type DetailsToggleProps } from \"./DetailsToggle\";\nexport type { DiscussionComposerProps, DiscussionItemProps, DiscussionListProps, DiscussionProps } from \"./Discussion\";\nexport { default as Discussion } from \"./Discussion\";\nexport type {\n FloatingWindowClose,\n FloatingWindowProps,\n OpenFloatingWindowOptions,\n} from \"./FloatingWindow\";\nexport {\n default as FloatingWindow,\n type FloatingWindowRect,\n fitFloatingWindowRect,\n openFloatingWindow,\n} from \"./FloatingWindow\";\nexport type { MobileShellHeaderProps, MobileShellProps, MobileShellSidebarItem, MobileShellSidebarProps } from \"./MobileShell\";\nexport { default as MobileShell, observeMobileShell } from \"./MobileShell\";\nexport { default as Navigation, type NavigationProps } from \"./Navigation\";\nexport {\n createNavigation,\n findNavigationItem,\n type NavigationController,\n type NavigationItem,\n type NavigationOptions,\n type NavigationStatus,\n} from \"./navigation-model\";\nexport type { PageTitleProps, PageTrailLink, PageTrailState } from \"./PageTitle\";\nexport { followPageTrail, PAGE_TRAIL_EVENT, PageTitle, PageTrailProvider, readPageTrail, setPageTrail, usePageTrail } from \"./PageTitle\";\nexport type {\n PanelDialogBodyProps,\n PanelDialogFooterProps,\n PanelDialogHeaderProps,\n PanelDialogProps,\n PanelDialogSectionProps,\n PanelDialogSurface,\n PanelDialogTabOption,\n PanelDialogTabsProps,\n} from \"./PanelDialog\";\nexport {\n confirmDiscardIfDirty,\n default as PanelDialog,\n panelDialogFixedOptions,\n panelDialogFixedPanelClass,\n panelDialogOptions,\n panelDialogPanelClass,\n panelDialogWideOptions,\n panelDialogWidePanelClass,\n panelDialogWorkspaceOptions,\n panelDialogWorkspacePanelClass,\n} from \"./PanelDialog\";\nexport type { PanelHeaderProps } from \"./PanelHeader\";\nexport { PanelHeader } from \"./PanelHeader\";\nexport type { PanesItem, PanesProps } from \"./Panes\";\nexport { default as Panes } from \"./Panes\";\nexport type { PullToRefreshProps, PullToRefreshState } from \"./PullToRefresh\";\nexport { default as PullToRefresh } from \"./PullToRefresh\";\nexport { installPageTitleController } from \"./page-title-controller\";\nexport type {\n AddPanesItemOptions,\n PanesDirection,\n PanesGroup,\n PanesIntent,\n PanesLayout,\n PanesNode,\n PanesPath,\n PanesPathSegment,\n PanesSide,\n PanesSplit,\n} from \"./panes-layout\";\nexport {\n activatePanesItem,\n addPanesItem,\n applyPanesIntent,\n createPanesLayout,\n isPanesItemVisible,\n PANES_LAYOUT_VERSION,\n parsePanesLayout,\n reconcilePanesLayout,\n removePanesItem,\n resizePanesSplit,\n} from \"./panes-layout\";\nexport { default as ResizeSeparator, type ResizeSeparatorProps } from \"./ResizeSeparator\";\nexport { attachResizeSeparator, type ResizeSeparatorOptions } from \"./resize-separator\";\nexport type { ScrollAreaProps } from \"./ScrollArea\";\nexport { default as ScrollArea } from \"./ScrollArea\";\nexport type {\n SaveStatusProps,\n SaveStatusState,\n SettingsFieldControlProps,\n SettingsFieldProps,\n SettingsFieldWidth,\n SettingsGroupActionProps,\n SettingsGroupProps,\n SettingsPageProps,\n SettingsPanelFooterProps,\n SettingsSaveBarProps,\n SettingsSectionProps,\n} from \"./Settings\";\nexport {\n readSettingsError,\n SaveStatus,\n SettingsField,\n SettingsGroup,\n SettingsPage,\n SettingsPanelFooter,\n SettingsSaveBar,\n SettingsSection,\n sameSettingValue,\n} from \"./Settings\";\nexport type {\n SettingsCollectionActionProps,\n SettingsCollectionItemActionsProps,\n SettingsCollectionItemProps,\n SettingsCollectionItemReorderProps,\n SettingsCollectionItemStatusProps,\n SettingsCollectionProps,\n} from \"./SettingsCollection\";\nexport { default as SettingsCollection } from \"./SettingsCollection\";\nexport type {\n SettingsModalFooterProps,\n SettingsModalGroupProps,\n SettingsModalProps,\n SettingsModalTabProps,\n SettingsModalTabTone,\n} from \"./SettingsModal\";\nexport { default as SettingsModal } from \"./SettingsModal\";\nexport {\n APP_WORKSPACE_SWITCHER_SEARCH_FROM,\n type AppWorkspaceSidebarSwitcherProps,\n type AppWorkspaceSwitcherAction,\n type AppWorkspaceSwitcherOption,\n} from \"./SidebarSwitcher\";\nexport { measureScrollFade } from \"./scroll-fade\";\nexport type { TabBarItem, TabBarProps } from \"./TabBar\";\nexport { default as TabBar } from \"./TabBar\";\nexport type { TableOfContentsItem, TableOfContentsProps } from \"./TableOfContents\";\nexport { TableOfContents } from \"./TableOfContents\";\n"],"mappings":"AAAA,SAAS,eAAe,QAAmC,mBAAmB;AAO9E,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AAgCtD,SAAS,2BAA2B,EAAE,OAAO,IAAI,YAAY,QAAQ,gBAAgB;AACrF,SAAS,iBAAiB,QAAQ,kBAAkB;AAEpD,SAAS,6BAA6B,EAAE,0BAA0B,QAAQ,4BAA4B;AAKtG,SACE,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,6BAA6B,EAC7B,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,EACtB,wCAAwC,EACxC,+BAA+B,EAC/B,6BAA6B,EAC7B,yBAAyB,EACzB,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,EACzB,wBAAwB,EACxB,gCAAgC,EAChC,4BAA4B,EAC5B,+BAA+B,EAC/B,uBAAuB,EACvB,gCAAgC,EAChC,iCAAiC,QAC5B,uBAAuB;AAC9B,SAAgC,0BAA0B,EAAE,kBAAkB,EAAE,OAAO,IAAI,WAAW,QAAQ,eAAe;AAE7H,SAAS,SAAS,QAAQ,aAAa;AAevC,SAAS,OAAO,IAAI,WAAW,QAAQ,eAAe;AActD,SAAS,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,UAAU,QAAQ,kBAAkB;AAC9H,SAAS,YAAY,EAAE,aAAa,QAAiC,iBAAiB;AAEtF,SAAS,OAAO,IAAI,UAAU,QAAQ,cAAc;AAMpD,SACE,OAAO,IAAI,cAAc,EAEzB,qBAAqB,EACrB,kBAAkB,QACb,kBAAkB;AAEzB,SAAS,OAAO,IAAI,WAAW,EAAE,kBAAkB,QAAQ,eAAe;AAC1E,SAAS,OAAO,IAAI,UAAU,QAA8B,cAAc;AAC1E,SACE,gBAAgB,EAChB,kBAAkB,QAKb,oBAAoB;AAE3B,SAAS,eAAe,EAAE,gBAAgB,EAAE,SAAS,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,QAAQ,aAAa;AAWxI,SACE,qBAAqB,EACrB,OAAO,IAAI,WAAW,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,EAC3B,8BAA8B,QACzB,eAAe;AAEtB,SAAS,WAAW,QAAQ,eAAe;AAE3C,SAAS,OAAO,IAAI,KAAK,QAAQ,SAAS;AAE1C,SAAS,OAAO,IAAI,aAAa,QAAQ,iBAAiB;AAC1D,SAAS,0BAA0B,QAAQ,yBAAyB;AAapE,SACE,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,gBAAgB,QACX,gBAAgB;AACvB,SAAS,OAAO,IAAI,eAAe,QAAmC,mBAAmB;AACzF,SAAS,qBAAqB,QAAqC,oBAAoB;AAEvF,SAAS,OAAO,IAAI,UAAU,QAAQ,cAAc;AAcpD,SACE,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,gBAAgB,QACX,YAAY;AASnB,SAAS,OAAO,IAAI,kBAAkB,QAAQ,sBAAsB;AAQpE,SAAS,OAAO,IAAI,aAAa,QAAQ,iBAAiB;AAC1D,SACE,kCAAkC,QAI7B,mBAAmB;AAC1B,SAAS,iBAAiB,QAAQ,eAAe;AAEjD,SAAS,OAAO,IAAI,MAAM,QAAQ,UAAU;AAE5C,SAAS,eAAe,QAAQ,mBAAmB","ignoreList":[]}
@@ -21,6 +21,8 @@ import { personTint } from "./person-color";
21
21
 
22
22
  /** `square` marks an agent or service account; people stay round. */
23
23
 
24
+ /** `person` tints initials and icons by name; `neutral` keeps them gray, such as for someone outside the team. */
25
+
24
26
  const initialsFor = name => {
25
27
  const parts = name.trim().split(/\s+/).filter(Boolean);
26
28
  if (parts.length === 0) return "?";
@@ -65,7 +67,7 @@ export function Avatar(props) {
65
67
  var _v$ = className(),
66
68
  _v$2 = props.size ?? "md",
67
69
  _v$3 = props.shape === "square" ? "square" : undefined,
68
- _v$4 = personTint(props.name),
70
+ _v$4 = props.tone === "neutral" ? undefined : personTint(props.name),
69
71
  _v$5 = ring(),
70
72
  _v$6 = style(),
71
73
  _v$7 = props.alt ?? avatarMessages().avatarLabel({
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["surfaces/Avatar.tsx"],"sourcesContent":["import { createEffect, createSignal, type JSX, on, Show } from \"solid-js\";\nimport { useAvatarMessages } from \"./avatar-messages\";\nimport { personTint } from \"./person-color\";\n\nexport type AvatarSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n\n/**\n * A status ring around the avatar: `\"success\"` for an active state such as someone working on a task, or an explicit\n * color, for example a collaborator's cursor color.\n */\nexport type AvatarRing = \"success\" | { color: string };\n\n/** `square` marks an agent or service account; people stay round. */\nexport type AvatarShape = \"circle\" | \"square\";\n\nexport type AvatarProps = {\n name: string;\n src?: string | null;\n icon?: string;\n alt?: string;\n fallback?: string;\n size?: AvatarSize;\n /** Draws a ring with a small transparent gap inside the avatar's own box, so the avatar keeps its size and no container clips the ring. */\n ring?: AvatarRing;\n shape?: AvatarShape;\n loading?: \"eager\" | \"lazy\";\n class?: string;\n style?: JSX.CSSProperties | string;\n};\n\nconst initialsFor = (name: string): string => {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return \"?\";\n if (parts.length === 1) return parts[0]?.slice(0, 2).toUpperCase() ?? \"?\";\n return `${parts[0]?.[0] ?? \"\"}${parts.at(-1)?.[0] ?? \"\"}`.toUpperCase();\n};\n\nexport function Avatar(props: AvatarProps): JSX.Element {\n const avatarMessages = useAvatarMessages();\n const [failed, setFailed] = createSignal(false);\n const label = () => props.name.trim() || avatarMessages().unknownUser;\n // Derive initials from the given name, not from the accessible-name fallback:\n // an empty `name` must render \"?\" the way Cloud's avatar does, not \"UU\".\n const fallback = () => props.fallback ?? initialsFor(props.name);\n const fallbackContent = () => (props.icon ? <i class={props.icon} aria-hidden=\"true\" /> : fallback());\n const className = () => `k2b-avatar ${props.class ?? \"\"}`;\n const ring = () => (props.ring === undefined ? undefined : typeof props.ring === \"string\" ? props.ring : \"color\");\n const style = (): JSX.CSSProperties | string | undefined => {\n const color = typeof props.ring === \"object\" ? props.ring.color : undefined;\n if (color === undefined) return props.style;\n if (typeof props.style === \"string\") return `${props.style ? `${props.style};` : \"\"}--k2b-avatar-ring:${color}`;\n return { ...props.style, \"--k2b-avatar-ring\": color };\n };\n\n createEffect(\n on(\n () => props.src,\n () => setFailed(false),\n { defer: true },\n ),\n );\n\n return (\n <Show\n when={!failed() ? props.src || undefined : undefined}\n fallback={\n <span\n class={className()}\n data-size={props.size ?? \"md\"}\n data-shape={props.shape === \"square\" ? \"square\" : undefined}\n data-tint={personTint(props.name)}\n data-ring={ring()}\n style={style()}\n role=\"img\"\n aria-label={props.alt ?? avatarMessages().avatarLabel({ name: label() })}\n >\n {fallbackContent()}\n </span>\n }\n >\n {(src) => (\n <img\n src={src()}\n alt={props.alt ?? avatarMessages().avatarLabel({ name: label() })}\n class={className()}\n data-size={props.size ?? \"md\"}\n data-shape={props.shape === \"square\" ? \"square\" : undefined}\n data-ring={ring()}\n style={style()}\n loading={props.loading ?? \"lazy\"}\n decoding=\"async\"\n onError={() => setFailed(true)}\n />\n )}\n </Show>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["surfaces/Avatar.tsx"],"sourcesContent":["import { createEffect, createSignal, type JSX, on, Show } from \"solid-js\";\nimport { useAvatarMessages } from \"./avatar-messages\";\nimport { personTint } from \"./person-color\";\n\nexport type AvatarSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\";\n\n/**\n * A status ring around the avatar: `\"success\"` for an active state such as someone working on a task, or an explicit\n * color, for example a collaborator's cursor color.\n */\nexport type AvatarRing = \"success\" | { color: string };\n\n/** `square` marks an agent or service account; people stay round. */\nexport type AvatarShape = \"circle\" | \"square\";\n\n/** `person` tints initials and icons by name; `neutral` keeps them gray, such as for someone outside the team. */\nexport type AvatarTone = \"person\" | \"neutral\";\n\nexport type AvatarProps = {\n name: string;\n src?: string | null;\n icon?: string;\n alt?: string;\n fallback?: string;\n size?: AvatarSize;\n /** Draws a ring with a small transparent gap inside the avatar's own box, so the avatar keeps its size and no container clips the ring. */\n ring?: AvatarRing;\n shape?: AvatarShape;\n tone?: AvatarTone;\n loading?: \"eager\" | \"lazy\";\n class?: string;\n style?: JSX.CSSProperties | string;\n};\n\nconst initialsFor = (name: string): string => {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return \"?\";\n if (parts.length === 1) return parts[0]?.slice(0, 2).toUpperCase() ?? \"?\";\n return `${parts[0]?.[0] ?? \"\"}${parts.at(-1)?.[0] ?? \"\"}`.toUpperCase();\n};\n\nexport function Avatar(props: AvatarProps): JSX.Element {\n const avatarMessages = useAvatarMessages();\n const [failed, setFailed] = createSignal(false);\n const label = () => props.name.trim() || avatarMessages().unknownUser;\n // Derive initials from the given name, not from the accessible-name fallback:\n // an empty `name` must render \"?\" the way Cloud's avatar does, not \"UU\".\n const fallback = () => props.fallback ?? initialsFor(props.name);\n const fallbackContent = () => (props.icon ? <i class={props.icon} aria-hidden=\"true\" /> : fallback());\n const className = () => `k2b-avatar ${props.class ?? \"\"}`;\n const ring = () => (props.ring === undefined ? undefined : typeof props.ring === \"string\" ? props.ring : \"color\");\n const style = (): JSX.CSSProperties | string | undefined => {\n const color = typeof props.ring === \"object\" ? props.ring.color : undefined;\n if (color === undefined) return props.style;\n if (typeof props.style === \"string\") return `${props.style ? `${props.style};` : \"\"}--k2b-avatar-ring:${color}`;\n return { ...props.style, \"--k2b-avatar-ring\": color };\n };\n\n createEffect(\n on(\n () => props.src,\n () => setFailed(false),\n { defer: true },\n ),\n );\n\n return (\n <Show\n when={!failed() ? props.src || undefined : undefined}\n fallback={\n <span\n class={className()}\n data-size={props.size ?? \"md\"}\n data-shape={props.shape === \"square\" ? \"square\" : undefined}\n data-tint={props.tone === \"neutral\" ? undefined : personTint(props.name)}\n data-ring={ring()}\n style={style()}\n role=\"img\"\n aria-label={props.alt ?? avatarMessages().avatarLabel({ name: label() })}\n >\n {fallbackContent()}\n </span>\n }\n >\n {(src) => (\n <img\n src={src()}\n alt={props.alt ?? avatarMessages().avatarLabel({ name: label() })}\n class={className()}\n data-size={props.size ?? \"md\"}\n data-shape={props.shape === \"square\" ? \"square\" : undefined}\n data-ring={ring()}\n style={style()}\n loading={props.loading ?? \"lazy\"}\n decoding=\"async\"\n onError={() => setFailed(true)}\n />\n )}\n </Show>\n );\n}\n"],"mappings":"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","ignoreList":[]}
@@ -20,9 +20,11 @@ var _tmpl$ = /*#__PURE__*/_$template(`<span class=k2b-avatar-stack__row-badge>`)
20
20
  _tmpl$9 = /*#__PURE__*/_$template(`<ul class=k2b-avatar-stack__rows tabindex=-1><!$><!/><!$><!/>`),
21
21
  _tmpl$0 = /*#__PURE__*/_$template(`<header class=k2b-avatar-stack__header><h3></h3><span class=k2b-count-chip>`),
22
22
  _tmpl$1 = /*#__PURE__*/_$template(`<p class=k2b-avatar-stack__hint>`),
23
- _tmpl$10 = /*#__PURE__*/_$template(`<div class=k2b-avatar-stack__sheet role=group>`),
23
+ _tmpl$10 = /*#__PURE__*/_$template(`<span class=k2b-avatar-stack__faces aria-hidden=true>`),
24
24
  _tmpl$11 = /*#__PURE__*/_$template(`<span class=k2b-avatar-stack__more aria-hidden=true>+<!$><!/>`),
25
- _tmpl$12 = /*#__PURE__*/_$template(`<span><button type=button class=k2b-avatar-stack__trigger aria-haspopup=dialog><span class=k2b-avatar-stack__faces aria-hidden=true></span><!$><!/></button><div popover=auto role=dialog class=k2b-avatar-stack__popover>`);
25
+ _tmpl$12 = /*#__PURE__*/_$template(`<div class=k2b-avatar-stack__sheet role=group>`),
26
+ _tmpl$13 = /*#__PURE__*/_$template(`<span><button type=button class=k2b-avatar-stack__trigger aria-haspopup=dialog></button><div popover=auto role=dialog class=k2b-avatar-stack__popover>`),
27
+ _tmpl$14 = /*#__PURE__*/_$template(`<span class=k2b-avatar-stack__custom aria-hidden=true>`);
26
28
  import { createMemo, createSignal, createUniqueId, For, onCleanup, onMount, Show } from "solid-js";
27
29
  import { dropdownPosition } from "../actions/Dropdown";
28
30
  import { prefersMenuSheet } from "../actions/menu-sheet";
@@ -207,6 +209,60 @@ const PeopleList = props => [(() => {
207
209
  return _el$24;
208
210
  }
209
211
  })];
212
+ /**
213
+ * The stack's faces and "+n" without its button or list, for a row or link that is already interactive. The faces
214
+ * are decorative: name the people in the surrounding label or a tooltip.
215
+ */
216
+ export function AvatarFaces(props) {
217
+ const messages = useAvatarMessages();
218
+ const max = () => Math.max(1, props.max ?? 3);
219
+ const shown = () => props.people.slice(0, max());
220
+ const more = () => Math.max(0, Math.max(props.total ?? 0, props.people.length) - shown().length);
221
+ return [(() => {
222
+ var _el$25 = _$getNextElement(_tmpl$10);
223
+ _$insert(_el$25, _$createComponent(For, {
224
+ get each() {
225
+ return shown();
226
+ },
227
+ children: person => _$createComponent(Avatar, {
228
+ get name() {
229
+ return person.name;
230
+ },
231
+ get src() {
232
+ return person.src;
233
+ },
234
+ get icon() {
235
+ return person.icon;
236
+ },
237
+ get shape() {
238
+ return person.shape;
239
+ },
240
+ get tone() {
241
+ return person.tone;
242
+ },
243
+ size: "xs",
244
+ alt: ""
245
+ })
246
+ }));
247
+ _$effect(() => _$setAttribute(_el$25, "data-faces-size", props.size === "md" ? "md" : undefined));
248
+ return _el$25;
249
+ })(), _$createComponent(Show, {
250
+ get when() {
251
+ return more() > 0;
252
+ },
253
+ get children() {
254
+ var _el$26 = _$getNextElement(_tmpl$11),
255
+ _el$27 = _el$26.firstChild,
256
+ _el$28 = _el$27.nextSibling,
257
+ [_el$29, _co$6] = _$getNextMarker(_el$28.nextSibling);
258
+ _$insert(_el$26, more, _el$29, _co$6);
259
+ _$effect(() => _$setAttribute(_el$26, "title", messages().moreCount({
260
+ count: more()
261
+ })));
262
+ return _el$26;
263
+ }
264
+ })];
265
+ }
210
266
 
211
267
  /**
212
268
  * A few overlapping faces, then "+n", as one button. It opens the full list of people beside it, or as a bottom sheet
@@ -214,7 +270,6 @@ const PeopleList = props => [(() => {
214
270
  */
215
271
  export function AvatarStack(props) {
216
272
  const locale = useLocale();
217
- const messages = useAvatarMessages();
218
273
  const id = createUniqueId().replace(/[^a-zA-Z0-9_-]/g, "-");
219
274
  const popoverId = `k2b-avatar-stack-${id}`;
220
275
  const titleId = `${popoverId}-title`;
@@ -225,9 +280,6 @@ export function AvatarStack(props) {
225
280
  const disposed = new AbortController();
226
281
  onCleanup(() => disposed.abort());
227
282
  const faces = () => props.people.filter(person => !person.self);
228
- const max = () => Math.max(1, props.max ?? 3);
229
- const shown = () => faces().slice(0, max());
230
- const more = () => Math.max(0, faces().length - max());
231
283
  const place = () => {
232
284
  const rect = dropdownPosition(trigger.getBoundingClientRect(), popover.getBoundingClientRect(), "bottom-left", {
233
285
  width: window.innerWidth,
@@ -265,9 +317,9 @@ export function AvatarStack(props) {
265
317
  get children() {
266
318
  return _$createComponent(BottomSheet.Body, {
267
319
  get children() {
268
- var _el$25 = _$getNextElement(_tmpl$10);
269
- _$setAttribute(_el$25, "aria-labelledby", `${titleId}-sheet`);
270
- _$insert(_el$25, _$createComponent(PeopleList, {
320
+ var _el$30 = _$getNextElement(_tmpl$12);
321
+ _$setAttribute(_el$30, "aria-labelledby", `${titleId}-sheet`);
322
+ _$insert(_el$30, _$createComponent(PeopleList, {
271
323
  get people() {
272
324
  return props.people;
273
325
  },
@@ -283,7 +335,7 @@ export function AvatarStack(props) {
283
335
  close();
284
336
  }
285
337
  }));
286
- return _el$25;
338
+ return _el$30;
287
339
  }
288
340
  });
289
341
  }
@@ -312,64 +364,46 @@ export function AvatarStack(props) {
312
364
  place();
313
365
  };
314
366
  return (() => {
315
- var _el$26 = _$getNextElement(_tmpl$12),
316
- _el$27 = _el$26.firstChild,
317
- _el$28 = _el$27.firstChild,
318
- _el$33 = _el$28.nextSibling,
319
- [_el$34, _co$7] = _$getNextMarker(_el$33.nextSibling),
320
- _el$35 = _el$27.nextSibling;
321
- _el$27.$$click = toggle;
367
+ var _el$31 = _$getNextElement(_tmpl$13),
368
+ _el$32 = _el$31.firstChild,
369
+ _el$33 = _el$32.nextSibling;
370
+ _el$32.$$click = toggle;
322
371
  var _ref$3 = trigger;
323
- typeof _ref$3 === "function" ? _$use(_ref$3, _el$27) : trigger = _el$27;
324
- _$setAttribute(_el$27, "aria-controls", popoverId);
325
- _$insert(_el$28, _$createComponent(For, {
326
- get each() {
327
- return shown();
328
- },
329
- children: person => _$createComponent(Avatar, {
330
- get name() {
331
- return person.name;
332
- },
333
- get src() {
334
- return person.src;
335
- },
336
- get icon() {
337
- return person.icon;
338
- },
339
- get shape() {
340
- return person.shape;
341
- },
342
- size: "xs",
343
- alt: ""
344
- })
345
- }));
346
- _$insert(_el$27, _$createComponent(Show, {
372
+ typeof _ref$3 === "function" ? _$use(_ref$3, _el$32) : trigger = _el$32;
373
+ _$setAttribute(_el$32, "aria-controls", popoverId);
374
+ _$insert(_el$32, _$createComponent(Show, {
347
375
  get when() {
348
- return more() > 0;
376
+ return props.trigger === undefined;
377
+ },
378
+ get fallback() {
379
+ return (() => {
380
+ var _el$34 = _$getNextElement(_tmpl$14);
381
+ _$insert(_el$34, () => props.trigger);
382
+ return _el$34;
383
+ })();
349
384
  },
350
385
  get children() {
351
- var _el$29 = _$getNextElement(_tmpl$11),
352
- _el$30 = _el$29.firstChild,
353
- _el$31 = _el$30.nextSibling,
354
- [_el$32, _co$6] = _$getNextMarker(_el$31.nextSibling);
355
- _$insert(_el$29, more, _el$32, _co$6);
356
- _$effect(() => _$setAttribute(_el$29, "title", messages().moreCount({
357
- count: more()
358
- })));
359
- return _el$29;
386
+ return _$createComponent(AvatarFaces, {
387
+ get people() {
388
+ return faces();
389
+ },
390
+ get max() {
391
+ return props.max;
392
+ }
393
+ });
360
394
  }
361
- }), _el$34, _co$7);
362
- _el$35.addEventListener("toggle", event => {
395
+ }));
396
+ _el$33.addEventListener("toggle", event => {
363
397
  const next = event.newState === "open";
364
398
  setOpen(next);
365
399
  follow(next);
366
400
  if (!next && document.activeElement && popover.contains(document.activeElement)) trigger.focus();
367
401
  });
368
402
  var _ref$4 = popover;
369
- typeof _ref$4 === "function" ? _$use(_ref$4, _el$35) : popover = _el$35;
370
- _$setAttribute(_el$35, "id", popoverId);
371
- _$setAttribute(_el$35, "aria-labelledby", titleId);
372
- _$insert(_el$35, _$createComponent(PeopleList, {
403
+ typeof _ref$4 === "function" ? _$use(_ref$4, _el$33) : popover = _el$33;
404
+ _$setAttribute(_el$33, "id", popoverId);
405
+ _$setAttribute(_el$33, "aria-labelledby", titleId);
406
+ _$insert(_el$33, _$createComponent(PeopleList, {
373
407
  get people() {
374
408
  return props.people;
375
409
  },
@@ -389,9 +423,9 @@ export function AvatarStack(props) {
389
423
  var _v$ = `k2b-avatar-stack ${props.class ?? ""}`,
390
424
  _v$2 = props.label,
391
425
  _v$3 = open();
392
- _v$ !== _p$.e && _$className(_el$26, _p$.e = _v$);
393
- _v$2 !== _p$.t && _$setAttribute(_el$27, "aria-label", _p$.t = _v$2);
394
- _v$3 !== _p$.a && _$setAttribute(_el$27, "aria-expanded", _p$.a = _v$3);
426
+ _v$ !== _p$.e && _$className(_el$31, _p$.e = _v$);
427
+ _v$2 !== _p$.t && _$setAttribute(_el$32, "aria-label", _p$.t = _v$2);
428
+ _v$3 !== _p$.a && _$setAttribute(_el$32, "aria-expanded", _p$.a = _v$3);
395
429
  return _p$;
396
430
  }, {
397
431
  e: undefined,
@@ -399,7 +433,7 @@ export function AvatarStack(props) {
399
433
  a: undefined
400
434
  });
401
435
  _$runHydrationEvents();
402
- return _el$26;
436
+ return _el$31;
403
437
  })();
404
438
  }
405
439
  _$delegateEvents(["click"]);
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["surfaces/AvatarStack.tsx"],"sourcesContent":["import { createMemo, createSignal, createUniqueId, For, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { dropdownPosition } from \"../actions/Dropdown\";\nimport { prefersMenuSheet } from \"../actions/menu-sheet\";\nimport { dialogCore } from \"../feedback/dialog-core\";\nimport { LocaleProvider, useLocale } from \"../intl/locale\";\nimport BottomSheet, { bottomSheetOptions } from \"../layout/BottomSheet\";\nimport { Avatar, type AvatarShape } from \"./Avatar\";\nimport { useAvatarMessages } from \"./avatar-messages\";\n\nexport type AvatarStackPerson = {\n /** Stable key, such as the account id. */\n id: string;\n name: string;\n src?: string | null;\n /** Shown instead of initials when there is no picture. */\n icon?: string;\n /** `square` for agents and service accounts. */\n shape?: AvatarShape;\n /** A short tag after the name, such as \"Agent\". */\n badge?: JSX.Element;\n /** One line below the name; it ends with an ellipsis instead of wrapping. */\n detail?: JSX.Element;\n /** Icon class before `detail`. */\n detailIcon?: string;\n /** Short text at the end of the row, such as \"2 tabs\". */\n trailing?: JSX.Element;\n /** The person viewing: listed last, below a gap, and never in the stack. */\n self?: boolean;\n /** Makes the row a button. The list closes first. */\n onSelect?: () => void;\n};\n\nexport type AvatarStackProps = {\n people: readonly AvatarStackPerson[];\n /** Title of the list that the stack opens, such as \"Here now\". */\n title: string;\n /** Accessible name of the stack button, such as \"Here now: Jana Berger and 2 more\". */\n label: string;\n /** One quiet line below the list. */\n hint?: JSX.Element;\n /** Faces before \"+n\". Defaults to 3. */\n max?: number;\n class?: string;\n};\n\nconst PersonRows = (props: { people: readonly AvatarStackPerson[]; choose: (person: AvatarStackPerson) => void }): JSX.Element => {\n let list!: HTMLUListElement;\n /**\n * A focused row that stops being a button (the person can no longer be chosen) or leaves hands focus to the nearest\n * row that still is one, else to the list, so focus never drops out of the open list.\n */\n const keepFocus = (button: HTMLButtonElement) => {\n if (!button.contains(document.activeElement)) return;\n const buttons = Array.from(list.querySelectorAll<HTMLButtonElement>(\"button.k2b-avatar-stack__row\"));\n const index = buttons.indexOf(button);\n const candidates = [...buttons.slice(index + 1), ...buttons.slice(0, Math.max(0, index)).reverse()];\n queueMicrotask(() => {\n if (!list.isConnected) return;\n (candidates.find((candidate) => candidate.isConnected) ?? list).focus();\n });\n };\n const others = () => props.people.filter((person) => !person.self);\n const selves = () => props.people.filter((person) => person.self);\n // A row reads its person through an accessor, so a live update changes the row in place and a focused row keeps focus.\n const row = (person: () => AvatarStackPerson) => {\n const content = (\n <>\n <Avatar name={person().name} src={person().src} icon={person().icon} shape={person().shape} size=\"sm\" />\n <span class=\"k2b-avatar-stack__row-copy\">\n <span class=\"k2b-avatar-stack__row-name\">\n <span>{person().name}</span>\n <Show when={person().badge}>\n <span class=\"k2b-avatar-stack__row-badge\">{person().badge}</span>\n </Show>\n </span>\n <Show when={person().detail}>\n <span class=\"k2b-avatar-stack__row-detail\">\n <Show when={person().detailIcon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n <span>{person().detail}</span>\n </span>\n </Show>\n </span>\n <Show when={person().trailing}>\n <span class=\"k2b-avatar-stack__row-trailing\">{person().trailing}</span>\n </Show>\n </>\n );\n return (\n <li data-self={person().self ? \"true\" : undefined}>\n <Show when={Boolean(person().onSelect)} fallback={<div class=\"k2b-avatar-stack__row\">{content}</div>}>\n {(() => {\n let button!: HTMLButtonElement;\n // Browser only: a server render never mounts the button.\n onMount(() => onCleanup(() => keepFocus(button)));\n return (\n <button ref={button} type=\"button\" class=\"k2b-avatar-stack__row\" onClick={() => props.choose(person())}>\n {content}\n </button>\n );\n })()}\n </Show>\n </li>\n );\n };\n // Rows follow each person by id: a row stays with its person when others leave or the order changes, and still\n // shows that person's latest details.\n const byId = createMemo(() => new Map(props.people.map((person) => [person.id, person])));\n const keyed = (id: string) => row(() => byId().get(id) ?? { id, name: \"\" });\n return (\n <ul ref={list} class=\"k2b-avatar-stack__rows\" tabIndex={-1}>\n <For each={others().map((person) => person.id)}>{keyed}</For>\n <For each={selves().map((person) => person.id)}>{keyed}</For>\n </ul>\n );\n};\n\nconst PeopleList = (props: {\n people: readonly AvatarStackPerson[];\n title: string;\n titleId: string;\n hint?: JSX.Element;\n choose: (person: AvatarStackPerson) => void;\n}): JSX.Element => (\n <>\n <header class=\"k2b-avatar-stack__header\">\n <h3 id={props.titleId}>{props.title}</h3>\n <span class=\"k2b-count-chip\">{props.people.length}</span>\n </header>\n <PersonRows people={props.people} choose={props.choose} />\n <Show when={props.hint}>\n <p class=\"k2b-avatar-stack__hint\">{props.hint}</p>\n </Show>\n </>\n);\n\n/**\n * A few overlapping faces, then \"+n\", as one button. It opens the full list of people beside it, or as a bottom sheet\n * on phones. People with `self` are listed last and never shown in the stack.\n */\nexport function AvatarStack(props: AvatarStackProps): JSX.Element {\n const locale = useLocale();\n const messages = useAvatarMessages();\n const id = createUniqueId().replace(/[^a-zA-Z0-9_-]/g, \"-\");\n const popoverId = `k2b-avatar-stack-${id}`;\n const titleId = `${popoverId}-title`;\n const [open, setOpen] = createSignal(false);\n let trigger!: HTMLButtonElement;\n let popover!: HTMLDivElement;\n let sheetOpen = false;\n const disposed = new AbortController();\n onCleanup(() => disposed.abort());\n\n const faces = () => props.people.filter((person) => !person.self);\n const max = () => Math.max(1, props.max ?? 3);\n const shown = () => faces().slice(0, max());\n const more = () => Math.max(0, faces().length - max());\n\n const place = () => {\n const rect = dropdownPosition(trigger.getBoundingClientRect(), popover.getBoundingClientRect(), \"bottom-left\", {\n width: window.innerWidth,\n height: window.innerHeight,\n });\n popover.style.left = `${rect.left}px`;\n popover.style.top = `${rect.top}px`;\n };\n // Like a dropdown menu, the open list follows its trigger when the window resizes or scrolls, and its own size.\n let resizeObserver: ResizeObserver | undefined;\n const follow = (on: boolean) => {\n const method = on ? \"addEventListener\" : \"removeEventListener\";\n window[method](\"resize\", place);\n window[method](\"scroll\", place, true);\n if (on && typeof ResizeObserver !== \"undefined\") {\n resizeObserver ??= new ResizeObserver(place);\n resizeObserver.observe(popover);\n } else resizeObserver?.disconnect();\n };\n // Only the browser ever follows; a server render has no window to let go of.\n onMount(() => onCleanup(() => follow(false)));\n\n const openSheet = () => {\n if (sheetOpen) return;\n sheetOpen = true;\n setOpen(true);\n let chosen: AvatarStackPerson | undefined;\n const current = locale();\n void dialogCore\n .open<void>(\n (close, context) => (\n <LocaleProvider locale={current}>\n <BottomSheet onDismiss={context.requestDismiss}>\n <BottomSheet.Body>\n <div class=\"k2b-avatar-stack__sheet\" role=\"group\" aria-labelledby={`${titleId}-sheet`}>\n <PeopleList\n people={props.people}\n title={props.title}\n titleId={`${titleId}-sheet`}\n hint={props.hint}\n choose={(person) => {\n chosen = person;\n close();\n }}\n />\n </div>\n </BottomSheet.Body>\n </BottomSheet>\n </LocaleProvider>\n ),\n { ...bottomSheetOptions, ariaLabel: props.title, history: true, signal: disposed.signal },\n )\n .then(() => chosen?.onSelect?.())\n .finally(() => {\n sheetOpen = false;\n setOpen(false);\n });\n };\n\n const toggle = () => {\n if (prefersMenuSheet()) {\n openSheet();\n return;\n }\n if (popover.matches(\":popover-open\")) {\n popover.hidePopover();\n return;\n }\n popover.showPopover();\n place();\n };\n\n return (\n <span class={`k2b-avatar-stack ${props.class ?? \"\"}`}>\n <button\n ref={trigger}\n type=\"button\"\n class=\"k2b-avatar-stack__trigger\"\n aria-label={props.label}\n aria-haspopup=\"dialog\"\n aria-expanded={open()}\n aria-controls={popoverId}\n onClick={toggle}\n >\n <span class=\"k2b-avatar-stack__faces\" aria-hidden=\"true\">\n <For each={shown()}>\n {(person) => <Avatar name={person.name} src={person.src} icon={person.icon} shape={person.shape} size=\"xs\" alt=\"\" />}\n </For>\n </span>\n <Show when={more() > 0}>\n <span class=\"k2b-avatar-stack__more\" aria-hidden=\"true\" title={messages().moreCount({ count: more() })}>\n +{more()}\n </span>\n </Show>\n </button>\n <div\n ref={popover}\n id={popoverId}\n popover=\"auto\"\n role=\"dialog\"\n aria-labelledby={titleId}\n class=\"k2b-avatar-stack__popover\"\n onToggle={(event) => {\n const next = (event as ToggleEvent).newState === \"open\";\n setOpen(next);\n follow(next);\n if (!next && document.activeElement && popover.contains(document.activeElement)) trigger.focus();\n }}\n >\n <PeopleList\n people={props.people}\n title={props.title}\n titleId={titleId}\n hint={props.hint}\n choose={(person) => {\n if (open()) popover.hidePopover();\n person.onSelect?.();\n }}\n />\n </div>\n </span>\n );\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["surfaces/AvatarStack.tsx"],"sourcesContent":["import { createMemo, createSignal, createUniqueId, For, type JSX, onCleanup, onMount, Show } from \"solid-js\";\nimport { dropdownPosition } from \"../actions/Dropdown\";\nimport { prefersMenuSheet } from \"../actions/menu-sheet\";\nimport { dialogCore } from \"../feedback/dialog-core\";\nimport { LocaleProvider, useLocale } from \"../intl/locale\";\nimport BottomSheet, { bottomSheetOptions } from \"../layout/BottomSheet\";\nimport { Avatar, type AvatarShape, type AvatarTone } from \"./Avatar\";\nimport { useAvatarMessages } from \"./avatar-messages\";\n\nexport type AvatarStackPerson = {\n /** Stable key, such as the account id. */\n id: string;\n name: string;\n src?: string | null;\n /** Shown instead of initials when there is no picture. */\n icon?: string;\n /** `square` for agents and service accounts. */\n shape?: AvatarShape;\n /** A short tag after the name, such as \"Agent\". */\n badge?: JSX.Element;\n /** One line below the name; it ends with an ellipsis instead of wrapping. */\n detail?: JSX.Element;\n /** Icon class before `detail`. */\n detailIcon?: string;\n /** Short text at the end of the row, such as \"2 tabs\". */\n trailing?: JSX.Element;\n /** The person viewing: listed last, below a gap, and never in the stack. */\n self?: boolean;\n /** Makes the row a button. The list closes first. */\n onSelect?: () => void;\n};\n\nexport type AvatarStackProps = {\n people: readonly AvatarStackPerson[];\n /** Title of the list that the stack opens, such as \"Here now\". */\n title: string;\n /** Accessible name of the stack button, such as \"Here now: Jana Berger and 2 more\". */\n label: string;\n /** One quiet line below the list. */\n hint?: JSX.Element;\n /** Faces before \"+n\". Defaults to 3. */\n max?: number;\n /** What the button shows instead of the faces, such as a \"+n\" chip and the viewer's own chip. */\n trigger?: JSX.Element;\n class?: string;\n};\n\nconst PersonRows = (props: { people: readonly AvatarStackPerson[]; choose: (person: AvatarStackPerson) => void }): JSX.Element => {\n let list!: HTMLUListElement;\n /**\n * A focused row that stops being a button (the person can no longer be chosen) or leaves hands focus to the nearest\n * row that still is one, else to the list, so focus never drops out of the open list.\n */\n const keepFocus = (button: HTMLButtonElement) => {\n if (!button.contains(document.activeElement)) return;\n const buttons = Array.from(list.querySelectorAll<HTMLButtonElement>(\"button.k2b-avatar-stack__row\"));\n const index = buttons.indexOf(button);\n const candidates = [...buttons.slice(index + 1), ...buttons.slice(0, Math.max(0, index)).reverse()];\n queueMicrotask(() => {\n if (!list.isConnected) return;\n (candidates.find((candidate) => candidate.isConnected) ?? list).focus();\n });\n };\n const others = () => props.people.filter((person) => !person.self);\n const selves = () => props.people.filter((person) => person.self);\n // A row reads its person through an accessor, so a live update changes the row in place and a focused row keeps focus.\n const row = (person: () => AvatarStackPerson) => {\n const content = (\n <>\n <Avatar name={person().name} src={person().src} icon={person().icon} shape={person().shape} size=\"sm\" />\n <span class=\"k2b-avatar-stack__row-copy\">\n <span class=\"k2b-avatar-stack__row-name\">\n <span>{person().name}</span>\n <Show when={person().badge}>\n <span class=\"k2b-avatar-stack__row-badge\">{person().badge}</span>\n </Show>\n </span>\n <Show when={person().detail}>\n <span class=\"k2b-avatar-stack__row-detail\">\n <Show when={person().detailIcon}>{(icon) => <i class={icon()} aria-hidden=\"true\" />}</Show>\n <span>{person().detail}</span>\n </span>\n </Show>\n </span>\n <Show when={person().trailing}>\n <span class=\"k2b-avatar-stack__row-trailing\">{person().trailing}</span>\n </Show>\n </>\n );\n return (\n <li data-self={person().self ? \"true\" : undefined}>\n <Show when={Boolean(person().onSelect)} fallback={<div class=\"k2b-avatar-stack__row\">{content}</div>}>\n {(() => {\n let button!: HTMLButtonElement;\n // Browser only: a server render never mounts the button.\n onMount(() => onCleanup(() => keepFocus(button)));\n return (\n <button ref={button} type=\"button\" class=\"k2b-avatar-stack__row\" onClick={() => props.choose(person())}>\n {content}\n </button>\n );\n })()}\n </Show>\n </li>\n );\n };\n // Rows follow each person by id: a row stays with its person when others leave or the order changes, and still\n // shows that person's latest details.\n const byId = createMemo(() => new Map(props.people.map((person) => [person.id, person])));\n const keyed = (id: string) => row(() => byId().get(id) ?? { id, name: \"\" });\n return (\n <ul ref={list} class=\"k2b-avatar-stack__rows\" tabIndex={-1}>\n <For each={others().map((person) => person.id)}>{keyed}</For>\n <For each={selves().map((person) => person.id)}>{keyed}</For>\n </ul>\n );\n};\n\nconst PeopleList = (props: {\n people: readonly AvatarStackPerson[];\n title: string;\n titleId: string;\n hint?: JSX.Element;\n choose: (person: AvatarStackPerson) => void;\n}): JSX.Element => (\n <>\n <header class=\"k2b-avatar-stack__header\">\n <h3 id={props.titleId}>{props.title}</h3>\n <span class=\"k2b-count-chip\">{props.people.length}</span>\n </header>\n <PersonRows people={props.people} choose={props.choose} />\n <Show when={props.hint}>\n <p class=\"k2b-avatar-stack__hint\">{props.hint}</p>\n </Show>\n </>\n);\n\nexport type AvatarFacesPerson = Pick<AvatarStackPerson, \"name\" | \"src\" | \"icon\" | \"shape\"> & { tone?: AvatarTone };\n\nexport type AvatarFacesProps = {\n people: readonly AvatarFacesPerson[];\n /** Faces before \"+n\". Defaults to 3. */\n max?: number;\n /** Everyone the faces stand for when `people` lists only some of them; \"+n\" counts the rest. */\n total?: number;\n /** `sm` (default) matches the stack button; `md` suits a row or table cell whose text the faces stand beside. */\n size?: \"sm\" | \"md\";\n};\n\n/**\n * The stack's faces and \"+n\" without its button or list, for a row or link that is already interactive. The faces\n * are decorative: name the people in the surrounding label or a tooltip.\n */\nexport function AvatarFaces(props: AvatarFacesProps): JSX.Element {\n const messages = useAvatarMessages();\n const max = () => Math.max(1, props.max ?? 3);\n const shown = () => props.people.slice(0, max());\n const more = () => Math.max(0, Math.max(props.total ?? 0, props.people.length) - shown().length);\n return (\n <>\n <span class=\"k2b-avatar-stack__faces\" data-faces-size={props.size === \"md\" ? \"md\" : undefined} aria-hidden=\"true\">\n <For each={shown()}>\n {(person) => (\n <Avatar name={person.name} src={person.src} icon={person.icon} shape={person.shape} tone={person.tone} size=\"xs\" alt=\"\" />\n )}\n </For>\n </span>\n <Show when={more() > 0}>\n <span class=\"k2b-avatar-stack__more\" aria-hidden=\"true\" title={messages().moreCount({ count: more() })}>\n +{more()}\n </span>\n </Show>\n </>\n );\n}\n\n/**\n * A few overlapping faces, then \"+n\", as one button. It opens the full list of people beside it, or as a bottom sheet\n * on phones. People with `self` are listed last and never shown in the stack.\n */\nexport function AvatarStack(props: AvatarStackProps): JSX.Element {\n const locale = useLocale();\n const id = createUniqueId().replace(/[^a-zA-Z0-9_-]/g, \"-\");\n const popoverId = `k2b-avatar-stack-${id}`;\n const titleId = `${popoverId}-title`;\n const [open, setOpen] = createSignal(false);\n let trigger!: HTMLButtonElement;\n let popover!: HTMLDivElement;\n let sheetOpen = false;\n const disposed = new AbortController();\n onCleanup(() => disposed.abort());\n\n const faces = () => props.people.filter((person) => !person.self);\n\n const place = () => {\n const rect = dropdownPosition(trigger.getBoundingClientRect(), popover.getBoundingClientRect(), \"bottom-left\", {\n width: window.innerWidth,\n height: window.innerHeight,\n });\n popover.style.left = `${rect.left}px`;\n popover.style.top = `${rect.top}px`;\n };\n // Like a dropdown menu, the open list follows its trigger when the window resizes or scrolls, and its own size.\n let resizeObserver: ResizeObserver | undefined;\n const follow = (on: boolean) => {\n const method = on ? \"addEventListener\" : \"removeEventListener\";\n window[method](\"resize\", place);\n window[method](\"scroll\", place, true);\n if (on && typeof ResizeObserver !== \"undefined\") {\n resizeObserver ??= new ResizeObserver(place);\n resizeObserver.observe(popover);\n } else resizeObserver?.disconnect();\n };\n // Only the browser ever follows; a server render has no window to let go of.\n onMount(() => onCleanup(() => follow(false)));\n\n const openSheet = () => {\n if (sheetOpen) return;\n sheetOpen = true;\n setOpen(true);\n let chosen: AvatarStackPerson | undefined;\n const current = locale();\n void dialogCore\n .open<void>(\n (close, context) => (\n <LocaleProvider locale={current}>\n <BottomSheet onDismiss={context.requestDismiss}>\n <BottomSheet.Body>\n <div class=\"k2b-avatar-stack__sheet\" role=\"group\" aria-labelledby={`${titleId}-sheet`}>\n <PeopleList\n people={props.people}\n title={props.title}\n titleId={`${titleId}-sheet`}\n hint={props.hint}\n choose={(person) => {\n chosen = person;\n close();\n }}\n />\n </div>\n </BottomSheet.Body>\n </BottomSheet>\n </LocaleProvider>\n ),\n { ...bottomSheetOptions, ariaLabel: props.title, history: true, signal: disposed.signal },\n )\n .then(() => chosen?.onSelect?.())\n .finally(() => {\n sheetOpen = false;\n setOpen(false);\n });\n };\n\n const toggle = () => {\n if (prefersMenuSheet()) {\n openSheet();\n return;\n }\n if (popover.matches(\":popover-open\")) {\n popover.hidePopover();\n return;\n }\n popover.showPopover();\n place();\n };\n\n return (\n <span class={`k2b-avatar-stack ${props.class ?? \"\"}`}>\n <button\n ref={trigger}\n type=\"button\"\n class=\"k2b-avatar-stack__trigger\"\n aria-label={props.label}\n aria-haspopup=\"dialog\"\n aria-expanded={open()}\n aria-controls={popoverId}\n onClick={toggle}\n >\n <Show\n when={props.trigger === undefined}\n fallback={\n <span class=\"k2b-avatar-stack__custom\" aria-hidden=\"true\">\n {props.trigger}\n </span>\n }\n >\n <AvatarFaces people={faces()} max={props.max} />\n </Show>\n </button>\n <div\n ref={popover}\n id={popoverId}\n popover=\"auto\"\n role=\"dialog\"\n aria-labelledby={titleId}\n class=\"k2b-avatar-stack__popover\"\n onToggle={(event) => {\n const next = (event as ToggleEvent).newState === \"open\";\n setOpen(next);\n follow(next);\n if (!next && document.activeElement && popover.contains(document.activeElement)) trigger.focus();\n }}\n >\n <PeopleList\n people={props.people}\n title={props.title}\n titleId={titleId}\n hint={props.hint}\n choose={(person) => {\n if (open()) popover.hidePopover();\n person.onSelect?.();\n }}\n />\n </div>\n </span>\n );\n}\n"],"mappings":"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","ignoreList":[]}