@parallelworks/ui 0.52.0 → 0.54.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 (92) hide show
  1. package/README.md +97 -8
  2. package/dist/access/AccessDrawer.d.ts +55 -0
  3. package/dist/access/AccessDrawer.js +445 -0
  4. package/dist/access/AccessList.d.ts +58 -0
  5. package/dist/access/AccessList.js +382 -0
  6. package/dist/access/GrantView.d.ts +35 -0
  7. package/dist/access/GrantView.js +188 -0
  8. package/dist/access/GroupPicker.d.ts +35 -0
  9. package/dist/access/GroupPicker.js +336 -0
  10. package/dist/access/focus.d.ts +10 -0
  11. package/dist/access/focus.js +27 -0
  12. package/dist/access/index.d.ts +3 -0
  13. package/dist/access/index.js +3 -0
  14. package/dist/access/model.d.ts +49 -0
  15. package/dist/access/model.js +129 -0
  16. package/dist/access/strings.d.ts +122 -0
  17. package/dist/access/strings.js +151 -0
  18. package/dist/access/types.d.ts +56 -0
  19. package/dist/ai/ai.css +5 -3
  20. package/dist/ai/components/SlashMenu.js +1 -1
  21. package/dist/ai/components/agent/AgentMessageParts.js +1 -1
  22. package/dist/ai/strings.js +0 -1
  23. package/dist/ai/ui/sidebar.js +1 -1
  24. package/dist/components/Combobox.d.ts +19 -0
  25. package/dist/components/Combobox.js +101 -50
  26. package/dist/components/Drawer.d.ts +6 -1
  27. package/dist/components/Drawer.js +25 -16
  28. package/dist/components/Field.d.ts +5 -4
  29. package/dist/components/Field.js +27 -4
  30. package/dist/components/InfoTip.d.ts +12 -4
  31. package/dist/components/InfoTip.js +13 -3
  32. package/dist/components/MarkdownImpl.d.ts +1 -0
  33. package/dist/components/MarkdownImpl.js +1 -0
  34. package/dist/components/Menu.js +4 -4
  35. package/dist/components/MenuEntries.js +1 -1
  36. package/dist/components/OptionDescription.d.ts +7 -0
  37. package/dist/components/OptionDescription.js +19 -0
  38. package/dist/components/Popover.d.ts +4 -1
  39. package/dist/components/Popover.js +2 -1
  40. package/dist/components/Provider.d.ts +9 -0
  41. package/dist/components/Provider.js +4 -0
  42. package/dist/components/Select.js +13 -11
  43. package/dist/components/comboboxItems.d.ts +10 -0
  44. package/dist/components/comboboxItems.js +8 -1
  45. package/dist/components/floating.d.ts +5 -2
  46. package/dist/components/floating.js +2 -2
  47. package/dist/components/focus.d.ts +5 -0
  48. package/dist/components/focus.js +21 -1
  49. package/dist/editor/Editor.js +13 -3
  50. package/dist/editor/Monaco.d.ts +8 -1
  51. package/dist/editor/Monaco.js +16 -3
  52. package/dist/editor/editorModel.d.ts +1 -1
  53. package/dist/editor/editorModel.js +1 -1
  54. package/dist/editor/index.d.ts +1 -0
  55. package/dist/editor/index.js +2 -1
  56. package/dist/editor/languages.d.ts +24 -0
  57. package/dist/editor/languages.js +31 -0
  58. package/dist/editor/monacoFeatures.d.ts +7 -0
  59. package/dist/editor/monacoFeatures.js +19 -0
  60. package/dist/editor/themes.d.ts +5 -0
  61. package/dist/editor/themes.js +24 -4
  62. package/dist/editor/workers.d.ts +3 -3
  63. package/dist/editor/workers.js +8 -4
  64. package/dist/editor/yamlLanguage.js +55 -38
  65. package/dist/file-explorer/FileExplorer.d.ts +18 -4
  66. package/dist/file-explorer/FileExplorer.js +64 -20
  67. package/dist/file-explorer/FilePreview/Viewer.js +12 -8
  68. package/dist/file-explorer/FileRow.d.ts +6 -2
  69. package/dist/file-explorer/FileRow.js +35 -17
  70. package/dist/file-explorer/FileRowsWindow.d.ts +2 -1
  71. package/dist/file-explorer/FileRowsWindow.js +2 -1
  72. package/dist/file-explorer/FileTable.d.ts +3 -1
  73. package/dist/file-explorer/FileTable.js +3 -2
  74. package/dist/file-explorer/TreeView.d.ts +5 -1
  75. package/dist/file-explorer/TreeView.js +49 -25
  76. package/dist/file-explorer/helpers.js +3 -3
  77. package/dist/file-explorer/lib/paging.d.ts +1 -0
  78. package/dist/file-explorer/lib/paging.js +5 -1
  79. package/dist/file-explorer/lib/utils.d.ts +3 -0
  80. package/dist/file-explorer/lib/utils.js +6 -1
  81. package/dist/form/Wizard/utils.js +2 -1
  82. package/dist/list/ActionToolbar.js +3 -2
  83. package/dist/list/ListPage.js +1 -1
  84. package/dist/list/ListTable.d.ts +5 -0
  85. package/dist/list/ListTable.js +6 -2
  86. package/dist/styles/theme.css +82 -62
  87. package/dist/styles.css +1 -1
  88. package/dist/theme/derive.d.ts +5 -3
  89. package/dist/theme/derive.js +61 -3
  90. package/package.json +9 -2
  91. package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +0 -6
  92. package/dist/file-explorer/FilePreview/CodePreviewEditor.js +0 -64
@@ -0,0 +1,122 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type UIStrings } from '../components/Provider.js';
3
+ export declare const ACCESS_STRINGS: {
4
+ title: string;
5
+ /** Under the title: the resource, and how many groups have a role on it. */
6
+ summary: (resource: string, groups: number, everyone: boolean) => string;
7
+ /** Names the switch between the two ways of listing who has access. */
8
+ arrange: string;
9
+ byRole: string;
10
+ byGroup: string;
11
+ filter: string;
12
+ grantAccess: string;
13
+ highImpact: string;
14
+ loading: string;
15
+ groups: (n: number) => string;
16
+ /** How many of a role's groups a filter left. */
17
+ groupsShown: (shown: number, total: number) => string;
18
+ members: (n: number) => string;
19
+ people: (n: number) => string;
20
+ /** Everyone, where it is short: a tag or a picker row. */
21
+ everyone: string;
22
+ /** Everyone, where it stands as a row of its own. */
23
+ everyoneInOrganization: string;
24
+ everyoneJoinLater: string;
25
+ /** Read with the badges a group row folds away: "+2". */
26
+ moreRoles: (n: number) => string;
27
+ moreRolesLabel: (roles: readonly string[]) => string;
28
+ /** Beside a group whose other role gives everything this one does. */
29
+ coveredBy: (roles: readonly string[]) => string;
30
+ /** Beside a group that has this through everyone as well. */
31
+ everyoneHasThisToo: string;
32
+ /** A role a group holds that another of its roles already gives. */
33
+ redundant: (roles: readonly string[]) => string;
34
+ /** A role a group has only because everyone does. */
35
+ throughEveryone: string;
36
+ removeRole: (group: string, role: string) => string;
37
+ grantMoreRoles: string;
38
+ removeAllAccess: string;
39
+ removeTitle: (group: string, roles: readonly string[]) => string;
40
+ removeAllTitle: (group: string) => string;
41
+ /** Leads the list of what a group loses; `members` is undefined when the count isn't known. */
42
+ losesIntro: (members: number | undefined, everyone: boolean) => string;
43
+ /** After the list: why these are lost, and what they keep. */
44
+ keeps: (own: readonly string[], throughEveryone: readonly string[]) => string;
45
+ /** When the roles it keeps give everything the removed ones did. */
46
+ losesNothing: (own: readonly string[], throughEveryone: readonly string[]) => string;
47
+ confirmRemove: (roles: readonly string[]) => string;
48
+ removeFailed: (group: string, roles: readonly string[]) => string;
49
+ grantFailed: (groups: readonly string[], roles: readonly string[]) => string;
50
+ undoFailed: string;
51
+ /** Under a failed save; `reason` is the host's error message, when it gave one. */
52
+ nothingChanged: (reason: string | undefined) => string;
53
+ /** The toast after a grant. */
54
+ granted: (groups: readonly string[], roles: readonly string[]) => string;
55
+ /** The toast after a removal. */
56
+ removed: (groups: readonly string[], roles: readonly string[]) => string;
57
+ undone: string;
58
+ readOnly: string;
59
+ /** After `readOnly` when the host gives no reason. */
60
+ readOnlyReason: string;
61
+ emptyTitle: string;
62
+ emptyDescription: (resource: string) => string;
63
+ noMatches: string;
64
+ clearFilter: string;
65
+ back: string;
66
+ groupsLabel: string;
67
+ addGroup: string;
68
+ /** Under the groups field; `count` is undefined when the host doesn't say how many there are. */
69
+ groupsHint: (count: number | undefined, everyone: boolean) => string;
70
+ everyoneCoversGroups: string;
71
+ organization: string;
72
+ recent: string;
73
+ allGroups: string;
74
+ /** On a group's row in the picker: the roles it holds here. */
75
+ hasRoles: (roles: readonly string[]) => string;
76
+ /** Read with a group's row: its size, where it comes from and its roles here. */
77
+ groupSummary: (members: number | undefined, everyone: boolean, source: 'synced' | 'manual' | undefined, roles: readonly string[]) => string;
78
+ rolesLabel: string;
79
+ searchRoles: string;
80
+ /** On a role's row in the picker. */
81
+ alreadyHave: (groups: readonly string[]) => string;
82
+ alreadyCovered: (roles: readonly string[]) => string;
83
+ everyoneHasIt: string;
84
+ /** The footer's account of what pressing Grant does. */
85
+ grantSummary: (groups: readonly string[], roles: readonly string[]) => ReactNode;
86
+ /** Why Grant can't be pressed: every group has every role already. */
87
+ nothingToGrant: (groups: readonly string[], roles: readonly string[]) => string;
88
+ pickGroupsAndRoles: string;
89
+ pickGroups: string;
90
+ pickRoles: string;
91
+ grant: (roles: readonly string[]) => string;
92
+ grantToEveryone: string;
93
+ everyoneWarningTitle: (roles: readonly string[], people: number | undefined) => string;
94
+ everyoneWarning: (resource: string) => string;
95
+ confirmEveryoneTitle: (roles: readonly string[], people: number | undefined) => string;
96
+ synced: string;
97
+ syncedShort: string;
98
+ manual: string;
99
+ wholeOrganization: string;
100
+ joinLater: string;
101
+ /** The first few members by name, and how many more there are. */
102
+ memberNames: (names: readonly string[], more: number) => string;
103
+ moreMembers: (n: number) => string;
104
+ onResource: (resource: string) => string;
105
+ noRolesHere: string;
106
+ /** When a role being granted gives everything one the group holds does. */
107
+ becomesRedundant: (granting: readonly string[], held: readonly string[]) => string;
108
+ alreadyHas: (roles: readonly string[]) => string;
109
+ everyoneReach: (roles: readonly string[], people: number | undefined) => string;
110
+ updated: (ago: string) => string;
111
+ detailsFailed: string;
112
+ loadingDetails: string;
113
+ noHighlight: string;
114
+ };
115
+ /** The drawer's own text, which a host translates through UIProvider's `access`. */
116
+ export type AccessText = typeof ACCESS_STRINGS;
117
+ /** The drawer's text with the shared words, such as Cancel and Retry, beside it. */
118
+ export type AccessStrings = AccessText & {
119
+ common: UIStrings['common'];
120
+ };
121
+ /** The access drawer's strings: the host's translations over the English defaults. */
122
+ export declare function useAccessStrings(): AccessStrings;
@@ -0,0 +1,151 @@
1
+ import { useStrings } from "../components/Provider.js";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useMemo } from "react";
4
+ //#region src/access/strings.tsx
5
+ var plural = new Intl.PluralRules("en");
6
+ var list = new Intl.ListFormat("en", { type: "conjunction" });
7
+ /** A count and its noun: "1 group", "1,024 groups". */
8
+ var countOf = (n, one, other) => `${n.toLocaleString()} ${plural.select(n) === "one" ? one : other}`;
9
+ var and = (names) => list.format(names);
10
+ var has = (names) => names.length === 1 ? "has" : "have";
11
+ var ACCESS_STRINGS = {
12
+ title: "Access",
13
+ /** Under the title: the resource, and how many groups have a role on it. */
14
+ summary: (resource, groups, everyone) => everyone ? groups === 0 ? `${resource} · Everyone has access` : `${resource} · Everyone and ${countOf(groups, "group have access", "groups have access")}` : groups === 0 ? `${resource} · No groups have access` : `${resource} · ${countOf(groups, "group has access", "groups have access")}`,
15
+ /** Names the switch between the two ways of listing who has access. */
16
+ arrange: "List access",
17
+ byRole: "By role",
18
+ byGroup: "By group",
19
+ filter: "Filter by role or group",
20
+ grantAccess: "Grant access",
21
+ highImpact: "High impact",
22
+ loading: "Loading who has access",
23
+ groups: (n) => countOf(n, "group", "groups"),
24
+ /** How many of a role's groups a filter left. */
25
+ groupsShown: (shown, total) => `${shown.toLocaleString()} of ${countOf(total, "group", "groups")}`,
26
+ members: (n) => countOf(n, "member", "members"),
27
+ people: (n) => countOf(n, "person", "people"),
28
+ /** Everyone, where it is short: a tag or a picker row. */
29
+ everyone: "Everyone",
30
+ /** Everyone, where it stands as a row of its own. */
31
+ everyoneInOrganization: "Everyone in your organization",
32
+ everyoneJoinLater: "Including people who join later",
33
+ /** Read with the badges a group row folds away: "+2". */
34
+ moreRoles: (n) => `+${n.toLocaleString()}`,
35
+ moreRolesLabel: (roles) => `Also ${and(roles)}`,
36
+ /** Beside a group whose other role gives everything this one does. */
37
+ coveredBy: (roles) => `${and(roles)} covers this too`,
38
+ /** Beside a group that has this through everyone as well. */
39
+ everyoneHasThisToo: "Everyone has this too",
40
+ /** A role a group holds that another of its roles already gives. */
41
+ redundant: (roles) => `Redundant: ${and(roles)} already covers this.`,
42
+ /** A role a group has only because everyone does. */
43
+ throughEveryone: "Everyone in your organization has it",
44
+ removeRole: (group, role) => `Remove ${group} from ${role}`,
45
+ grantMoreRoles: "Grant more roles",
46
+ removeAllAccess: "Remove all access",
47
+ removeTitle: (group, roles) => `Remove ${group} from ${and(roles)}?`,
48
+ removeAllTitle: (group) => `Remove all of ${group}’s access?`,
49
+ /** Leads the list of what a group loses; `members` is undefined when the count isn't known. */
50
+ losesIntro: (members, everyone) => everyone ? "People who have it only through everyone will no longer be able to:" : members === void 0 ? "Its members will no longer be able to:" : `Its ${countOf(members, "member", "members")} will no longer be able to:`,
51
+ /** After the list: why these are lost, and what they keep. */
52
+ keeps: (own, throughEveryone) => [
53
+ "No other role of theirs gives these.",
54
+ own.length > 0 && `They keep ${and(own)}.`,
55
+ throughEveryone.length > 0 && `They keep ${and(throughEveryone)}, which everyone has.`
56
+ ].filter(Boolean).join(" "),
57
+ /** When the roles it keeps give everything the removed ones did. */
58
+ losesNothing: (own, throughEveryone) => `They lose nothing: ${and([...own, ...throughEveryone])} still ${own.length + throughEveryone.length === 1 ? "gives" : "give"} them all of it.`,
59
+ confirmRemove: (roles) => roles.length === 1 ? `Remove ${roles[0]}` : "Remove all access",
60
+ removeFailed: (group, roles) => `Couldn’t remove ${group} from ${and(roles)}`,
61
+ grantFailed: (groups, roles) => `Couldn’t grant ${and(roles)} to ${and(groups)}`,
62
+ undoFailed: "Couldn’t undo the change",
63
+ /** Under a failed save; `reason` is the host's error message, when it gave one. */
64
+ nothingChanged: (reason) => reason ? `${reason.replace(/\.?$/, ".")} Nothing changed.` : "Nothing changed.",
65
+ /** The toast after a grant. */
66
+ granted: (groups, roles) => `Gave ${and(groups)} ${and(roles)}.`,
67
+ /** The toast after a removal. */
68
+ removed: (groups, roles) => `Removed ${and(groups)} from ${and(roles)}.`,
69
+ undone: "Change undone.",
70
+ readOnly: "You can see who has access.",
71
+ /** After `readOnly` when the host gives no reason. */
72
+ readOnlyReason: "Only people who manage access here can change it.",
73
+ emptyTitle: "No groups have access yet",
74
+ emptyDescription: (resource) => `Give a group a role so its members can see, use or manage ${resource}.`,
75
+ noMatches: "No roles or groups match",
76
+ clearFilter: "Clear filter",
77
+ back: "Back to who has access",
78
+ groupsLabel: "Groups",
79
+ addGroup: "Add a group",
80
+ /** Under the groups field; `count` is undefined when the host doesn't say how many there are. */
81
+ groupsHint: (count, everyone) => count === void 0 ? everyone ? "Search groups, or pick Everyone in your organization." : "Search groups." : `Search ${countOf(count, "group", "groups")}${everyone ? ", or pick Everyone in your organization" : ""}.`,
82
+ everyoneCoversGroups: "Everyone covers every group, so there’s no need to add others.",
83
+ organization: "Organization",
84
+ recent: "Recent",
85
+ allGroups: "All groups",
86
+ /** On a group's row in the picker: the roles it holds here. */
87
+ hasRoles: (roles) => `has ${and(roles)}`,
88
+ /** Read with a group's row: its size, where it comes from and its roles here. */
89
+ groupSummary: (members, everyone, source, roles) => [
90
+ members !== void 0 && (everyone ? countOf(members, "person", "people") : countOf(members, "member", "members")),
91
+ source === "synced" && "synced",
92
+ roles.length > 0 ? `has ${and(roles)} here` : "no roles here"
93
+ ].filter(Boolean).join(", "),
94
+ rolesLabel: "Roles",
95
+ searchRoles: "Search roles",
96
+ /** On a role's row in the picker. */
97
+ alreadyHave: (groups) => `${and(groups)} already ${has(groups)} it.`,
98
+ alreadyCovered: (roles) => `${and(roles)} already covers this.`,
99
+ everyoneHasIt: "Everyone already has it.",
100
+ /** The footer's account of what pressing Grant does. */
101
+ grantSummary: (groups, roles) => /* @__PURE__ */ jsxs(Fragment, { children: [
102
+ /* @__PURE__ */ jsx("strong", {
103
+ className: "font-medium text-(--theme-app)",
104
+ children: and(groups)
105
+ }),
106
+ " ",
107
+ groups.length === 1 ? "gets" : "get",
108
+ " ",
109
+ and(roles),
110
+ "."
111
+ ] }),
112
+ /** Why Grant can't be pressed: every group has every role already. */
113
+ nothingToGrant: (groups, roles) => `${and(groups)} already ${has(groups)} ${and(roles)}, so there’s nothing to grant.`,
114
+ pickGroupsAndRoles: "Pick the groups and the roles to grant.",
115
+ pickGroups: "Pick a group to grant to.",
116
+ pickRoles: "Pick a role to grant.",
117
+ grant: (roles) => roles.length === 0 ? "Grant" : roles.length === 1 ? `Grant ${roles[0]}` : `Grant ${countOf(roles.length, "role", "roles")}`,
118
+ grantToEveryone: "Grant to everyone",
119
+ everyoneWarningTitle: (roles, people) => people === void 0 ? `${and(roles)} for everyone` : `${and(roles)} for all ${countOf(people, "person", "people")}`,
120
+ everyoneWarning: (resource) => `Everyone in your organization, and everyone who joins later, will have it on ${resource}.`,
121
+ confirmEveryoneTitle: (roles, people) => people === void 0 ? `Grant ${and(roles)} to everyone?` : `Grant ${and(roles)} to all ${countOf(people, "person", "people")}?`,
122
+ synced: "Synced from your identity provider",
123
+ syncedShort: "Synced",
124
+ manual: "Members added by hand",
125
+ wholeOrganization: "Your whole organization",
126
+ joinLater: "And anyone who joins later gets it automatically.",
127
+ /** The first few members by name, and how many more there are. */
128
+ memberNames: (names, more) => more > 0 ? and([...names, `${more.toLocaleString()} more`]) : and(names),
129
+ moreMembers: (n) => `+${n.toLocaleString()}`,
130
+ onResource: (resource) => `On ${resource}`,
131
+ noRolesHere: "No roles here yet.",
132
+ /** When a role being granted gives everything one the group holds does. */
133
+ becomesRedundant: (granting, held) => `${and(granting)} also ${granting.length === 1 ? "gives" : "give"} them ${and(held)}, so ${and(held)} becomes redundant. Nothing is removed.`,
134
+ alreadyHas: (roles) => `Already has ${and(roles)}.`,
135
+ everyoneReach: (roles, people) => `${and(roles)} for everyone reaches ${people === void 0 ? "every person" : `all ${countOf(people, "person", "people")}`} in your organization, and anyone who joins later. You’ll be asked to confirm.`,
136
+ updated: (ago) => `Membership updated ${ago}`,
137
+ detailsFailed: "Couldn’t load this group’s details.",
138
+ loadingDetails: "Loading the group’s details",
139
+ noHighlight: "Highlight a group to see who is in it."
140
+ };
141
+ /** The access drawer's strings: the host's translations over the English defaults. */
142
+ function useAccessStrings() {
143
+ const { access: overrides, common } = useStrings();
144
+ return useMemo(() => ({
145
+ ...ACCESS_STRINGS,
146
+ ...overrides,
147
+ common
148
+ }), [overrides, common]);
149
+ }
150
+ //#endregion
151
+ export { ACCESS_STRINGS, useAccessStrings };
@@ -0,0 +1,56 @@
1
+ import type { TimeValue } from '../format.js';
2
+ /** A named set of permissions. Groups are granted roles, never permissions one by one. */
3
+ export interface AccessRole {
4
+ id: string;
5
+ name: string;
6
+ /** What it lets someone do, in a sentence. */
7
+ description?: string | undefined;
8
+ /** The permissions it gives. Two roles that share some are allowed, and only redundant: the
9
+ * drawer works out the overlap from these and says so as a hint. */
10
+ permissions: readonly string[];
11
+ /** Marks a role that reaches far, such as root on every node. It carries a tag, and granting
12
+ * it to everyone says so before asking to confirm. */
13
+ highImpact?: boolean | undefined;
14
+ }
15
+ /** A permission's name in words, for what a group loses when a role is taken away. */
16
+ export interface AccessPermission {
17
+ id: string;
18
+ /** What it lets someone do, as a phrase that follows "will no longer be able to": "Sign in". */
19
+ label: string;
20
+ }
21
+ /** Who a role can be granted to. */
22
+ export interface AccessGroup {
23
+ id: string;
24
+ name: string;
25
+ /** How many people are in it; for everyone, the organization's size. */
26
+ memberCount?: number | undefined;
27
+ /** `everyone` is the whole organization, people who join later included. At most one group
28
+ * is; leave it out where a resource can't be granted to everyone. */
29
+ kind?: 'everyone' | 'group' | undefined;
30
+ }
31
+ /** A role held by a group. */
32
+ export interface AccessGrant {
33
+ groupId: string;
34
+ roleId: string;
35
+ }
36
+ /** What one change grants and takes away; neither list holds a grant that changes nothing. */
37
+ export interface AccessChange {
38
+ grant: AccessGrant[];
39
+ revoke: AccessGrant[];
40
+ }
41
+ /** A person, as a group's details show its first few members. */
42
+ export interface AccessMember {
43
+ name: string;
44
+ avatarUrl?: string | undefined;
45
+ }
46
+ /** More about a group than the list needs, loaded when it is highlighted in the group picker. */
47
+ export interface AccessGroupDetails {
48
+ description?: string | undefined;
49
+ /** `synced` comes from an identity provider; `manual` is kept by hand. */
50
+ source?: 'synced' | 'manual' | undefined;
51
+ /** The first few, in the order to show them. */
52
+ members: readonly AccessMember[];
53
+ memberCount: number;
54
+ /** When its membership last changed. */
55
+ updatedAt?: TimeValue;
56
+ }
package/dist/ai/ai.css CHANGED
@@ -71,13 +71,15 @@
71
71
  color: inherit;
72
72
  }
73
73
 
74
- /* KaTeX overrides */
75
- .katex-display {
74
+ /* KaTeX overrides. Its own sheet loads with the markdown renderer, after
75
+ * this one, so these need the extra class to win. A wide display formula
76
+ * scrolls instead of widening the answer. */
77
+ .markdown .katex-display {
76
78
  margin: 1em 0;
77
79
  overflow-x: auto;
78
80
  overflow-y: hidden;
79
81
  }
80
- .katex {
82
+ .markdown .katex {
81
83
  font-size: 1.1em;
82
84
  }
83
85
 
@@ -83,7 +83,7 @@ function SlashMenu({ label, listId, matches, active, onChoose }) {
83
83
  role: "listbox",
84
84
  "aria-label": label,
85
85
  "data-testid": "slash-menu",
86
- className: cx("absolute bottom-full left-0 right-0 z-20 mb-2 overflow-hidden py-1", panelClassName),
86
+ className: cx("absolute bottom-full left-0 right-0 z-20 mb-2 overflow-hidden", "p-1", panelClassName),
87
87
  children: matches.map((c, i) => /* @__PURE__ */ jsxs("div", {
88
88
  id: optionId(listId, i),
89
89
  role: "option",
@@ -4,6 +4,7 @@ import { Loader } from "../../../components/Loader.js";
4
4
  import { toneSurface } from "../../../components/tone.js";
5
5
  import { useStrings } from "../../../components/Provider.js";
6
6
  import { fieldBox } from "../../../components/fieldBox.js";
7
+ import { focusOnMount } from "../../../components/focus.js";
7
8
  import { Disclosure } from "../../../components/Disclosure.js";
8
9
  import { formatDuration } from "../../../format.js";
9
10
  import { LogViewer } from "../../../logviewer/LogViewer.js";
@@ -12,7 +13,6 @@ import { computeEditDiff, computeWriteRows, editSummary, isEditDiffTool, parseEd
12
13
  import { languageForPath, tokenizeDiffLines } from "../../agent/diffHighlight.js";
13
14
  import { thinkingHeading } from "../../agent/transcript.js";
14
15
  import { useChatConfig } from "../../core/config.js";
15
- import { focusOnMount } from "../../../components/focus.js";
16
16
  import Markdown from "../../ui/Markdown.js";
17
17
  import { chatProseClasses } from "../../ui/prose.js";
18
18
  import { Reasoning, ReasoningBody } from "../Reasoning.js";
@@ -93,7 +93,6 @@ var defaultChatStrings = {
93
93
  "Manifesting",
94
94
  "Moseying",
95
95
  "Musing",
96
- "Percussing",
97
96
  "Reticulating",
98
97
  "Schlepping",
99
98
  "Stewing",
@@ -4,9 +4,9 @@ import { Tooltip } from "../../components/Tooltip.js";
4
4
  import { AppLink, isPlainClick } from "../../components/AppLink.js";
5
5
  import { IconButton } from "../../components/IconButton.js";
6
6
  import { fieldBox } from "../../components/fieldBox.js";
7
+ import { focusOnMount } from "../../components/focus.js";
7
8
  import { ConfirmModal } from "../../components/ConfirmModal.js";
8
9
  import { MoreButton, rowContextMenuProps, useRowMenuActive } from "../../list/rowMenu.js";
9
- import { focusOnMount } from "../../components/focus.js";
10
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
11
  import { useState } from "react";
12
12
  //#region src/ai/ui/sidebar.tsx
@@ -46,6 +46,25 @@ export type ComboboxProps<Value = string> = FieldProps & SelectionProps<Value> &
46
46
  trigger?: ReactElement | undefined;
47
47
  /** A hint on the trigger button. */
48
48
  triggerTooltip?: ReactNode;
49
+ /** A pane beside the list about the highlighted item, such as who is in a group; it gets
50
+ * undefined while nothing is highlighted. It follows the highlight from the keyboard and
51
+ * the pointer alike, and is hidden from assistive technology, so each item's
52
+ * `accessibleDescription` must say what matters in it. Where the list is narrower than
53
+ * 30rem the pane has no room, and `detailsSummary` shows under the highlighted item. */
54
+ details?: ((value: Value | undefined) => ReactNode) | undefined;
55
+ /** Called as the highlight moves, from the keyboard or the pointer, such as to load what
56
+ * `details` shows; undefined once nothing is highlighted. */
57
+ onItemHighlighted?: ((value: Value | undefined) => void) | undefined;
58
+ /** A line about the highlighted item, under it, where the list has no room for `details`. */
59
+ detailsSummary?: ((value: Value) => ReactNode) | undefined;
60
+ /** Called as the typed text changes. With it, the host does the filtering: the list shows
61
+ * `items` as given, such as the results of a search on the server. */
62
+ onQueryChange?: ((query: string) => void) | undefined;
63
+ /** The host's search is under way. */
64
+ loading?: boolean | undefined;
65
+ /** The area the open list stays inside, such as a drawer's body above its footer; by
66
+ * default, the viewport. With `details`, the list grows to fill it. */
67
+ collisionBoundary?: Element | null | undefined;
49
68
  };
50
69
  export interface AutocompleteProps extends FieldProps {
51
70
  /** Suggestions; any typed text is also a valid value. */