@k2b/ui 0.32.0 → 0.33.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 (109) hide show
  1. package/dist/browser/actions/Dropdown.js +159 -99
  2. package/dist/browser/actions/Dropdown.js.map +1 -1
  3. package/dist/browser/actions/FilterChip.js +113 -56
  4. package/dist/browser/actions/FilterChip.js.map +1 -1
  5. package/dist/browser/actions/filter-messages.js +26 -2
  6. package/dist/browser/actions/filter-messages.js.map +1 -1
  7. package/dist/browser/actions/menu-rows.js +23 -3
  8. package/dist/browser/actions/menu-rows.js.map +1 -1
  9. package/dist/browser/actions/menu-sheet.js +2 -7
  10. package/dist/browser/actions/menu-sheet.js.map +1 -1
  11. package/dist/browser/chat/ChatComposer.js +480 -403
  12. package/dist/browser/chat/ChatComposer.js.map +1 -1
  13. package/dist/browser/chat/chat-messages.js +14 -0
  14. package/dist/browser/chat/chat-messages.js.map +1 -1
  15. package/dist/browser/chat/index.js.map +1 -1
  16. package/dist/browser/content/Calendar.js +39 -29
  17. package/dist/browser/content/Calendar.js.map +1 -1
  18. package/dist/browser/content/CalendarDayView.js +159 -165
  19. package/dist/browser/content/CalendarDayView.js.map +1 -1
  20. package/dist/browser/content/MessageRow.js +607 -343
  21. package/dist/browser/content/MessageRow.js.map +1 -1
  22. package/dist/browser/content/ReactionBar.js +17 -0
  23. package/dist/browser/content/ReactionBar.js.map +1 -1
  24. package/dist/browser/content/index.js +1 -1
  25. package/dist/browser/content/index.js.map +1 -1
  26. package/dist/browser/feedback/dialog-core.js +6 -0
  27. package/dist/browser/feedback/dialog-core.js.map +1 -1
  28. package/dist/browser/inputs/TextInput.js +4 -1
  29. package/dist/browser/inputs/TextInput.js.map +1 -1
  30. package/dist/browser/intl/shortcut-messages.js +4 -0
  31. package/dist/browser/intl/shortcut-messages.js.map +1 -1
  32. package/dist/browser/intl/shortcut.js +4 -0
  33. package/dist/browser/intl/shortcut.js.map +1 -1
  34. package/dist/browser/layout/AppWorkspace.js +529 -512
  35. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  36. package/dist/browser/layout/MobileShell.js +213 -38
  37. package/dist/browser/layout/MobileShell.js.map +1 -1
  38. package/dist/browser/layout/index.js +1 -0
  39. package/dist/browser/layout/index.js.map +1 -1
  40. package/dist/browser/layout/scroll-fade.js +32 -5
  41. package/dist/browser/layout/scroll-fade.js.map +1 -1
  42. package/dist/browser/surfaces/NoticeCard.js +46 -30
  43. package/dist/browser/surfaces/NoticeCard.js.map +1 -1
  44. package/dist/browser/surfaces/resource-messages.js +2 -2
  45. package/dist/browser/surfaces/resource-messages.js.map +1 -1
  46. package/dist/ssr/actions/Dropdown.js +51 -27
  47. package/dist/ssr/actions/Dropdown.js.map +1 -1
  48. package/dist/ssr/actions/FilterChip.js +67 -16
  49. package/dist/ssr/actions/FilterChip.js.map +1 -1
  50. package/dist/ssr/actions/filter-messages.js +26 -2
  51. package/dist/ssr/actions/filter-messages.js.map +1 -1
  52. package/dist/ssr/actions/menu-rows.js +23 -3
  53. package/dist/ssr/actions/menu-rows.js.map +1 -1
  54. package/dist/ssr/actions/menu-sheet.js +2 -7
  55. package/dist/ssr/actions/menu-sheet.js.map +1 -1
  56. package/dist/ssr/chat/ChatComposer.js +96 -67
  57. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  58. package/dist/ssr/chat/chat-messages.js +14 -0
  59. package/dist/ssr/chat/chat-messages.js.map +1 -1
  60. package/dist/ssr/chat/index.js.map +1 -1
  61. package/dist/ssr/content/Calendar.js +40 -31
  62. package/dist/ssr/content/Calendar.js.map +1 -1
  63. package/dist/ssr/content/CalendarDayView.js +40 -48
  64. package/dist/ssr/content/CalendarDayView.js.map +1 -1
  65. package/dist/ssr/content/MessageRow.js +264 -91
  66. package/dist/ssr/content/MessageRow.js.map +1 -1
  67. package/dist/ssr/content/ReactionBar.js +17 -0
  68. package/dist/ssr/content/ReactionBar.js.map +1 -1
  69. package/dist/ssr/content/index.js +1 -1
  70. package/dist/ssr/content/index.js.map +1 -1
  71. package/dist/ssr/feedback/dialog-core.js +6 -0
  72. package/dist/ssr/feedback/dialog-core.js.map +1 -1
  73. package/dist/ssr/inputs/TextInput.js +4 -1
  74. package/dist/ssr/inputs/TextInput.js.map +1 -1
  75. package/dist/ssr/intl/shortcut-messages.js +4 -0
  76. package/dist/ssr/intl/shortcut-messages.js.map +1 -1
  77. package/dist/ssr/intl/shortcut.js +4 -0
  78. package/dist/ssr/intl/shortcut.js.map +1 -1
  79. package/dist/ssr/layout/AppWorkspace.js +134 -122
  80. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  81. package/dist/ssr/layout/MobileShell.js +100 -20
  82. package/dist/ssr/layout/MobileShell.js.map +1 -1
  83. package/dist/ssr/layout/index.js +1 -0
  84. package/dist/ssr/layout/index.js.map +1 -1
  85. package/dist/ssr/layout/scroll-fade.js +32 -5
  86. package/dist/ssr/layout/scroll-fade.js.map +1 -1
  87. package/dist/ssr/surfaces/NoticeCard.js +21 -12
  88. package/dist/ssr/surfaces/NoticeCard.js.map +1 -1
  89. package/dist/ssr/surfaces/resource-messages.js +2 -2
  90. package/dist/ssr/surfaces/resource-messages.js.map +1 -1
  91. package/dist/styles.css +1 -1
  92. package/dist/types/actions/Dropdown.d.ts +14 -0
  93. package/dist/types/actions/FilterChip.d.ts +11 -0
  94. package/dist/types/actions/filter-messages.d.ts +12 -0
  95. package/dist/types/actions/menu-rows.d.ts +7 -2
  96. package/dist/types/chat/ChatComposer.d.ts +13 -0
  97. package/dist/types/chat/chat-messages.d.ts +7 -0
  98. package/dist/types/chat/index.d.ts +1 -1
  99. package/dist/types/content/Calendar.d.ts +7 -0
  100. package/dist/types/content/MessageRow.d.ts +64 -2
  101. package/dist/types/content/index.d.ts +2 -2
  102. package/dist/types/feedback/dialog-core.d.ts +3 -0
  103. package/dist/types/intl/shortcut-messages.d.ts +2 -0
  104. package/dist/types/layout/AppWorkspace.d.ts +2 -0
  105. package/dist/types/layout/MobileShell.d.ts +52 -5
  106. package/dist/types/layout/index.d.ts +2 -1
  107. package/dist/types/layout/scroll-fade.d.ts +5 -0
  108. package/dist/types/surfaces/NoticeCard.d.ts +3 -0
  109. package/package.json +2 -2
@@ -44,6 +44,13 @@ export type DropdownAction = (DropdownActionBase & {
44
44
  href?: never;
45
45
  external?: never;
46
46
  });
47
+ /** A second, smaller action at the end of a row, such as "Only" beside a checkbox; it keeps the menu open. */
48
+ export type DropdownSecondaryAction = {
49
+ label: string;
50
+ /** Accessible name when the visible label alone does not say what it acts on, such as "Only Team Logistik". */
51
+ ariaLabel?: string;
52
+ action: () => void;
53
+ };
47
54
  /** Declarative radio or checkbox row for compact action menus. */
48
55
  export type DropdownChoice = DropdownActionBase & {
49
56
  action: () => void;
@@ -52,6 +59,11 @@ export type DropdownChoice = DropdownActionBase & {
52
59
  href?: string;
53
60
  closeOnSelect?: boolean;
54
61
  color?: string;
62
+ /**
63
+ * A second action at the end of the row. It shows while the row is hovered or focused, always on a touch screen,
64
+ * and keeps its place when hidden, so the row never changes width. Right and Left move between the two.
65
+ */
66
+ secondary?: DropdownSecondaryAction;
55
67
  };
56
68
  export type DropdownSection = {
57
69
  sectionLabel?: string;
@@ -60,6 +72,8 @@ export type DropdownSection = {
60
72
  * `sectionLabel`: the label names the choice above the row and for screen readers.
61
73
  */
62
74
  layout?: "row";
75
+ /** A quiet action at the end of the section label, such as "All"; it needs a `sectionLabel` and keeps the menu open. */
76
+ labelAction?: DropdownSecondaryAction;
63
77
  items: readonly (DropdownAction | DropdownChoice)[];
64
78
  };
65
79
  export type DropdownItem = DropdownAction | DropdownChoice | DropdownSection;
@@ -5,6 +5,8 @@ export type FilterChipOption = {
5
5
  label: string;
6
6
  icon?: string;
7
7
  color?: string;
8
+ /** Quiet trailing information about the option, such as a short note or a loading or warning icon with its own label. */
9
+ trailing?: JSX.Element;
8
10
  };
9
11
  export type FilterChipSection = {
10
12
  label?: string;
@@ -15,6 +17,8 @@ export type FilterChipSection = {
15
17
  * chosen option again keeps it; give the row a value in `defaultValue` so Reset keeps a choice too.
16
18
  */
17
19
  layout?: "row";
20
+ /** A labelled `multiple` section offers "All" or, once all its options are chosen, "None" beside its label. */
21
+ toggleAll?: boolean;
18
22
  };
19
23
  export type FilterChipProps = {
20
24
  label: string;
@@ -33,6 +37,13 @@ export type FilterChipProps = {
33
37
  * chips of `AppWorkspace.Head`; pass only the filter's name as `label`. The chip then grows with its value.
34
38
  */
35
39
  showValue?: boolean;
40
+ /**
41
+ * Each option of a `multiple` section offers "Only" at the end of its row: it chooses that option alone among the
42
+ * `multiple` sections and keeps the choices of single-select sections.
43
+ */
44
+ only?: boolean;
45
+ /** The trigger shows the colors of the first four chosen options before its label, as a quiet hint of what is in view. */
46
+ swatches?: boolean;
36
47
  disabled?: boolean;
37
48
  class?: string;
38
49
  };
@@ -2,6 +2,18 @@ declare const filterMessages: import("@k2b/stdlib").Catalog<{
2
2
  filterActions: string;
3
3
  filters: string;
4
4
  reset: string;
5
+ all: string;
6
+ none: string;
7
+ allOf: ({ label }: {
8
+ label: string;
9
+ }) => string;
10
+ noneOf: ({ label }: {
11
+ label: string;
12
+ }) => string;
13
+ only: string;
14
+ onlyOption: ({ label }: {
15
+ label: string;
16
+ }) => string;
5
17
  }>;
6
18
  export type FilterMessages = ReturnType<(typeof filterMessages)["resolve"]>["t"];
7
19
  /** Resolved from the inherited render locale. */
@@ -1,5 +1,10 @@
1
1
  /**
2
- * Left and Right cycle through the segments of a row section; Up and Down leave it like any item. Returns whether
3
- * the key moved focus.
2
+ * Left and Right cycle through the segments of a row section, or between a row and its secondary action; Up and Down
3
+ * leave it like any item. Returns whether the key moved focus.
4
4
  */
5
5
  export declare const focusRowSegment: (items: HTMLElement[], key: string) => boolean;
6
+ /**
7
+ * Moves Up, Down, Home, or End through the rows; a row's secondary action is no stop of its own there, so Down from
8
+ * it goes to the next row. Returns whether the key moved focus.
9
+ */
10
+ export declare const focusMenuRow: (items: HTMLElement[], key: string) => boolean;
@@ -133,6 +133,14 @@ export type ChatPasteHandler = (event: ClipboardEvent & {
133
133
  currentTarget: HTMLTextAreaElement;
134
134
  target: Element;
135
135
  }) => void;
136
+ export type ChatComposerReply = {
137
+ /** Name of the answered message's author. */
138
+ author: string;
139
+ /** Plain text of the answered message; it shows at most two lines. */
140
+ text: string;
141
+ onCancel: () => void;
142
+ onSelect?: () => void;
143
+ };
136
144
  export type ChatComposerProps = {
137
145
  value: string;
138
146
  onValueChange: (value: string) => void;
@@ -216,5 +224,10 @@ export type ChatComposerProps = {
216
224
  microphone?: ChatComposerMicrophone;
217
225
  /** One line above the field. The conversation variant always keeps its height; the default shows it only with content. */
218
226
  hint?: JSX.Element;
227
+ /**
228
+ * The message this draft answers, shown above the field on the same quiet tint as a quote in a message, with a
229
+ * button that cancels the reply. `onSelect` makes the quote a button, for example to jump to the original.
230
+ */
231
+ reply?: ChatComposerReply;
219
232
  };
220
233
  export declare function ChatComposer(props: ChatComposerProps): JSX.Element;
@@ -28,6 +28,7 @@ export declare const chatMessages: import("@k2b/stdlib").Catalog<{
28
28
  messageSent: string;
29
29
  messageNotSent: string;
30
30
  messageRetry: string;
31
+ messageDiscard: string;
31
32
  messageShowMore: string;
32
33
  messageShowLess: string;
33
34
  messageReplyTo: string;
@@ -75,6 +76,12 @@ export declare const chatMessages: import("@k2b/stdlib").Catalog<{
75
76
  couldNotLoadEarlierMessages: string;
76
77
  couldNotPostMessage: string;
77
78
  messageActions: string;
79
+ cancelReply: string;
80
+ replyingTo: string;
81
+ messageMenu: ({ author, time }: {
82
+ author: string;
83
+ time: string;
84
+ }) => string;
78
85
  messageComposer: string;
79
86
  messageInput: string;
80
87
  model: string;
@@ -7,7 +7,7 @@ import { ChatDecision, ChatMark, ChatOutcome } from "./ChatDecision";
7
7
  import { ChatActivity, ChatActivityToggle, ChatContextUsage, ChatMessage } from "./ChatPrimitives";
8
8
  import { ChatRoot } from "./ChatRoot";
9
9
  import { ChatTimeline } from "./ChatTimeline";
10
- export type { ChatCommand, ChatCommandContext, ChatCommandDraft, ChatCommandOpenResult, ChatCommandResult, ChatCommandScope, ChatCommandSearch, ChatCommandSection, ChatComposerProps, ChatFileSelection, ChatPasteHandler, } from "./ChatComposer";
10
+ export type { ChatCommand, ChatCommandContext, ChatCommandDraft, ChatCommandOpenResult, ChatCommandResult, ChatCommandScope, ChatCommandSearch, ChatCommandSection, ChatComposerProps, ChatComposerReply, ChatFileSelection, ChatPasteHandler, } from "./ChatComposer";
11
11
  export type { ChatDecisionProps, ChatMarkProps, ChatOutcomeProps, ChatPreviewExcerptProps, ChatPreviewHeaderProps, ChatPreviewLineProps, ChatPreviewPeopleProps, ChatPreviewProps, ChatPreviewReadMoreProps, ChatPreviewShowAllProps, ChatPreviewTitleProps, } from "./ChatDecision";
12
12
  export type { ChatActivityProps, ChatActivityToggleProps, ChatContextUsageProps, ChatMessageProps } from "./ChatPrimitives";
13
13
  export { formatChatTokens } from "./ChatPrimitives";
@@ -129,12 +129,19 @@ export type CalendarController = {
129
129
  export type CalendarCustomView<V extends string = string> = {
130
130
  value: V;
131
131
  label: string;
132
+ /** Days the previous and next buttons and keys move, such as 14 for a two-week list. Defaults to one day. */
133
+ days?: number;
132
134
  };
133
135
  export type CalendarProps<V extends string = never> = {
134
136
  date: Date | string;
135
137
  events: CalendarEvent[];
136
138
  view?: CalendarView | V;
137
139
  views?: CalendarView[];
140
+ /**
141
+ * `false` leaves the view switcher out of the toolbar, for a host that shows the views elsewhere, such as tabs in
142
+ * its page head. The view commands stay.
143
+ */
144
+ viewSwitcher?: boolean;
138
145
  /** Views after the built-in ones. While one is active, `children` is the body and the header pages by day. */
139
146
  customViews?: CalendarCustomView<V>[];
140
147
  /** The body of the active custom view. */
@@ -1,4 +1,5 @@
1
1
  import { type JSX } from "solid-js";
2
+ import { type GestureKind } from "../actions/GestureMenu";
2
3
  import { type ReactionBarItem } from "./ReactionBar";
3
4
  export type MessageRowAuthor = {
4
5
  /** Display name, shown at the start of a group and read before every message. */
@@ -11,12 +12,26 @@ export type MessageRowAuthor = {
11
12
  export type MessageRowStatus = "pending" | "sent" | "failed";
12
13
  export type MessageRowAction = {
13
14
  id: string;
14
- /** Accessible name and tooltip. */
15
+ /** Visible name of the menu entry. */
15
16
  label: string;
16
17
  /** Icon class, for example `ti ti-arrow-back-up`. */
17
18
  icon: string;
19
+ /** One quiet sentence below the label that says what the entry does. */
20
+ description?: string;
18
21
  onSelect: () => void;
19
22
  disabled?: boolean;
23
+ variant?: "danger";
24
+ /** A touch gesture that runs the entry too. Give each gesture to at most one entry. */
25
+ gesture?: GestureKind;
26
+ /**
27
+ * Alt+click (Option+click on Apple devices) on the message runs the entry directly, and the entry shows that
28
+ * shortcut. Give it to at most one entry.
29
+ */
30
+ altClick?: boolean;
31
+ /** A key the application handles for the focused message, such as "r"; the entry shows it at its end. */
32
+ shortcut?: string;
33
+ /** In the phone sheet, runs while the tap still counts as the person's gesture, as clipboard writes require. */
34
+ immediate?: boolean;
20
35
  };
21
36
  export type MessageRowQuote = {
22
37
  /** Name of the quoted message's author. */
@@ -67,6 +82,16 @@ export type MessageRowFile = MessageRowAttachmentTarget & {
67
82
  icon?: string;
68
83
  };
69
84
  export type MessageRowAttachment = MessageRowMedia | MessageRowFile;
85
+ /** Where a message belongs, shown as a small chip under it, for example its thread in a timeline of several. */
86
+ export type MessageRowOrigin = {
87
+ label: string;
88
+ /** Icon class, for example `ti ti-hash`. */
89
+ icon?: string;
90
+ /** Opens where the message belongs. Without it, the chip is not a control. */
91
+ onSelect?: () => void;
92
+ /** Accessible name of the control when it must say more than the label, such as "Open thread Updates". */
93
+ selectLabel?: string;
94
+ };
70
95
  export type MessageRowProgress = {
71
96
  /** What is happening, for example "Writing" or "Searching the files". */
72
97
  status: string;
@@ -96,7 +121,12 @@ export type MessageRowProps = {
96
121
  receipt?: string;
97
122
  /** Called by "Retry" while `status` is `"failed"`. */
98
123
  onRetry?: () => void;
99
- /** Shown as a toolbar over the message while it is hovered or focused. It never moves the layout. */
124
+ /** Called by "Discard" next to "Retry" while `status` is `"failed"`, so both answers to a failure sit where it shows. */
125
+ onDiscard?: () => void;
126
+ /**
127
+ * The message's menu. A quiet "…" beside the bubble opens it while the message is hovered or focused, also from the
128
+ * keyboard; right-click and a long press open the same menu. Showing "…" never moves the layout.
129
+ */
100
130
  actions?: readonly MessageRowAction[];
101
131
  /** The message this one answers, shown above it. */
102
132
  quote?: MessageRowQuote;
@@ -124,6 +154,8 @@ export type MessageRowProps = {
124
154
  onAddReaction?: (anchor: HTMLElement) => void;
125
155
  /** A bar of fixed height that opens the replies to this message. */
126
156
  thread?: MessageRowThread;
157
+ /** A chip of fixed height under the message that names where it belongs. */
158
+ origin?: MessageRowOrigin;
127
159
  /** The message is still being written, by a person or an automated author alike: a status line with "Stop". */
128
160
  progress?: MessageRowProgress;
129
161
  class?: string;
@@ -138,6 +170,29 @@ export type MessageSystemRowProps = {
138
170
  icon?: string;
139
171
  class?: string;
140
172
  };
173
+ export type MessageEventRowProps = {
174
+ /** What changed, for example "Mara set the status to “In review”". */
175
+ children: JSX.Element;
176
+ /** Icon class of the kind of change; a dot by default. */
177
+ icon?: string;
178
+ /** Where the change belongs, such as its thread, where several threads mix. */
179
+ origin?: MessageRowOrigin;
180
+ /** Visible time, formatted by the caller. */
181
+ time?: string;
182
+ dateTime?: string | Date;
183
+ class?: string;
184
+ };
185
+ export type MessageEventGroupProps = {
186
+ /** What the closed group stands for, for example "4 changes to Invitation and Light test". */
187
+ label: string;
188
+ expanded: boolean;
189
+ onToggle: () => void;
190
+ /** Visible time or range, formatted by the caller, for example "09:50–09:58". */
191
+ time?: string;
192
+ /** The first event's time. */
193
+ dateTime?: string | Date;
194
+ class?: string;
195
+ };
141
196
  export type MessageGroupEntry = {
142
197
  /** Stable identity of the author. */
143
198
  author: string;
@@ -156,6 +211,13 @@ export declare const startsMessageGroup: (entry: MessageGroupEntry, previous?: M
156
211
  * as `VirtualFeed` keeps its positions.
157
212
  */
158
213
  export declare function MessageRow(props: MessageRowProps): JSX.Element;
214
+ /**
215
+ * A quiet line for a change to something the conversation is about, such as a task's new status: no bubble, aligned
216
+ * with the messages' text, with its time at the end. It is no message: it never counts as unread.
217
+ */
218
+ export declare function MessageEventRow(props: MessageEventRowProps): JSX.Element;
219
+ /** Several event lines in a row as one line that opens them, such as "4 changes to Invitation and Light test". */
220
+ export declare function MessageEventGroup(props: MessageEventGroupProps): JSX.Element;
159
221
  /** A quiet, centered line for something that happened in the conversation, such as a person joining. */
160
222
  export declare function MessageSystemRow(props: MessageSystemRowProps): JSX.Element;
161
223
  export {};
@@ -40,8 +40,8 @@ export { MapAttribution } from "./MapAttribution";
40
40
  export { MapView } from "./MapView";
41
41
  export { MapViewFrame } from "./MapViewFrame";
42
42
  export { default as MarkdownView, type MarkdownRenderOptions, type MarkdownViewProps, renderSafeMarkdown } from "./MarkdownView";
43
- export type { MessageGroupEntry, MessageRowAction, MessageRowAttachment, MessageRowAuthor, MessageRowFile, MessageRowMedia, MessageRowProgress, MessageRowProps, MessageRowQuote, MessageRowReaction, MessageRowStatus, MessageRowThread, MessageSystemRowProps, } from "./MessageRow";
44
- export { MessageRow, MessageSystemRow, startsMessageGroup } from "./MessageRow";
43
+ export type { MessageEventGroupProps, MessageEventRowProps, MessageGroupEntry, MessageRowAction, MessageRowAttachment, MessageRowAuthor, MessageRowFile, MessageRowMedia, MessageRowOrigin, MessageRowProgress, MessageRowProps, MessageRowQuote, MessageRowReaction, MessageRowStatus, MessageRowThread, MessageSystemRowProps, } from "./MessageRow";
44
+ export { MessageEventGroup, MessageEventRow, MessageRow, MessageSystemRow, startsMessageGroup } from "./MessageRow";
45
45
  export { type MapPaletteColors, type MapTheme, mapPalette } from "./map-palette";
46
46
  export { type MapStyleOptions, mapAttribution, mapStyle } from "./map-style";
47
47
  export type { MapViewArea, MapViewFit, MapViewFrameProps, MapViewLine, MapViewLineTone, MapViewMarker, MapViewOwnLocation, MapViewPoint, MapViewProps, MapViewStyle, MapViewStyleSource, MapViewTone, } from "./map-view-types";
@@ -8,6 +8,9 @@ export type OpenDialogOptions = {
8
8
  initialFocus?: "first-input" | "none" | ((dialog: HTMLDialogElement) => HTMLElement | null);
9
9
  cancelBehavior?: "resolve-undefined" | "ignore";
10
10
  ariaLabel?: string;
11
+ ariaDescribedBy?: string;
12
+ /** Use for a consequential confirmation that requires a response. Defaults to dialog. */
13
+ role?: "dialog" | "alertdialog";
11
14
  /**
12
15
  * Add a same-URL history entry while the dialog is open, so the browser's or the phone's Back closes the dialog
13
16
  * instead of leaving the page. Normally closing the dialog removes the entry again; the returned promise settles after that.
@@ -26,6 +26,8 @@ export declare const resolveShortcutMessages: (locale?: string) => {
26
26
  pageup: string;
27
27
  pagedown: string;
28
28
  spaceLabel: string;
29
+ click: string;
30
+ clickLabel: string;
29
31
  deleteLabel: string;
30
32
  homeLabel: string;
31
33
  endLabel: string;
@@ -91,6 +91,8 @@ export type AppWorkspaceMainPaneProps = {
91
91
  href?: string;
92
92
  /** Quiet one-line text below the level title. */
93
93
  description?: JSX.Element;
94
+ /** Levels mode: a small mark before the level title, such as the colour dot of the object's container. */
95
+ lead?: JSX.Element;
94
96
  /** Controls at the end of the level head. */
95
97
  actions?: JSX.Element;
96
98
  surface?: "default" | "navigation";
@@ -1,20 +1,38 @@
1
1
  import { type JSX } from "solid-js";
2
+ import type { TabBarItem } from "./TabBar";
2
3
  export type MobileShellProps = {
3
4
  /** Usually `MobileShell.Header`; it sits above the scroll area and pads the top safe area. */
4
- header: JSX.Element;
5
+ header?: JSX.Element;
5
6
  /** Usually a `TabBar`; it sits below the scroll area and pads the bottom safe area itself. */
6
7
  footer?: JSX.Element;
8
+ /**
9
+ * Usually `MobileShell.Sidebar` with the footer's destinations and more. From 48rem of window width it stands at
10
+ * the start edge and the footer goes; below, it is not shown. The server renders both, so CSS alone decides.
11
+ */
12
+ sidebar?: JSX.Element;
7
13
  /** The page content, inside the shell's only scroll area. */
8
14
  children: JSX.Element;
15
+ /**
16
+ * `false` for content that brings its own heads and scroll areas, such as `AppWorkspace.Main` levels: it fills the
17
+ * main area without the shell's scroll area, and the header shows only as the frame of the next page while a tapped
18
+ * tab's page loads.
19
+ */
20
+ scroll?: boolean;
9
21
  class?: string;
10
22
  };
11
23
  export type MobileShellHeaderProps = {
12
24
  title: string;
13
- /** A Back control before the title: a link with `href`, otherwise a button. */
25
+ /** The title while the shell shows its sidebar, which already names the app; `title` by default. */
26
+ sidebarTitle?: string;
27
+ /**
28
+ * A Back control before the title: a link with `href`, otherwise a button. `withSidebar: false` hides it while the
29
+ * shell shows its sidebar, for a way back to a destination the sidebar lists.
30
+ */
14
31
  back?: {
15
32
  href?: string;
16
33
  onClick?: () => void;
17
34
  label: string;
35
+ withSidebar?: boolean;
18
36
  };
19
37
  /** Controls after the title, such as a menu. */
20
38
  actions?: JSX.Element;
@@ -29,12 +47,41 @@ export type MobileShellHeaderProps = {
29
47
  export declare function observeMobileShell(root: HTMLElement): () => void;
30
48
  declare function MobileShellRoot(props: MobileShellProps): JSX.Element;
31
49
  declare function MobileShellHeader(props: MobileShellHeaderProps): JSX.Element;
50
+ export type MobileShellSidebarItem = TabBarItem & {
51
+ /** A count after the label, such as unread messages; 0 shows nothing. */
52
+ count?: number;
53
+ };
54
+ export type MobileShellSidebarProps = {
55
+ /** Accessible name of the navigation landmark; usually the tab bar's. */
56
+ label: string;
57
+ /** The app's name in the sidebar's head. */
58
+ title: string;
59
+ /** Address of the app's logo before the name; decorative, the name says it. */
60
+ logo?: string;
61
+ /** Destinations at the top, such as Start. */
62
+ items: readonly MobileShellSidebarItem[];
63
+ /** Named groups below them, such as the apps; a group without items is left out. */
64
+ sections?: readonly {
65
+ title: string;
66
+ items: readonly MobileShellSidebarItem[];
67
+ }[];
68
+ /** Destinations at the bottom edge, such as Settings. */
69
+ footer?: readonly MobileShellSidebarItem[];
70
+ };
71
+ /**
72
+ * The navigation of a touch app on a wide screen, in `MobileShell`'s `sidebar`: the app's name, then its destinations
73
+ * as 44 px rows with icon and label, the open one in the action colour. A press shows the item's page frame at once,
74
+ * as on a tab, and the row of a loading page pulses.
75
+ */
76
+ declare function MobileShellSidebar(props: MobileShellSidebarProps): JSX.Element;
32
77
  /**
33
- * The full-screen frame of a phone app: a header, one scroll area, and an optional footer such as a `TabBar`. While
34
- * it is mounted, the document itself never scrolls, pinch zoom and rubber-banding are off, and the toast rail sits
35
- * above the footer. Mount one per page, as the page's layout.
78
+ * The full-screen frame of a phone app: a header, one scroll area, and an optional footer such as a `TabBar`. With a
79
+ * `sidebar`, a window of 48rem and wider shows the sidebar at the start edge instead of the footer, and the toast rail
80
+ * stays in the area beside it. While it is mounted, the document itself never scrolls, pinch zoom and rubber-banding
81
+ * are off, and the toast rail sits above the footer. Mount one per page, as the page's layout.
36
82
  */
37
83
  export declare const MobileShell: typeof MobileShellRoot & {
38
84
  Header: typeof MobileShellHeader;
85
+ Sidebar: typeof MobileShellSidebar;
39
86
  };
40
87
  export default MobileShell;
@@ -16,7 +16,7 @@ export type { DiscussionComposerProps, DiscussionItemProps, DiscussionListProps,
16
16
  export { default as Discussion } from "./Discussion";
17
17
  export type { FloatingWindowClose, FloatingWindowProps, OpenFloatingWindowOptions, } from "./FloatingWindow";
18
18
  export { default as FloatingWindow, type FloatingWindowRect, fitFloatingWindowRect, openFloatingWindow, } from "./FloatingWindow";
19
- export type { MobileShellHeaderProps, MobileShellProps } from "./MobileShell";
19
+ export type { MobileShellHeaderProps, MobileShellProps, MobileShellSidebarItem, MobileShellSidebarProps } from "./MobileShell";
20
20
  export { default as MobileShell, observeMobileShell } from "./MobileShell";
21
21
  export { default as Navigation, type NavigationProps } from "./Navigation";
22
22
  export { createNavigation, findNavigationItem, type NavigationController, type NavigationItem, type NavigationOptions, type NavigationStatus, } from "./navigation-model";
@@ -44,6 +44,7 @@ export { default as SettingsCollection } from "./SettingsCollection";
44
44
  export type { SettingsModalFooterProps, SettingsModalGroupProps, SettingsModalProps, SettingsModalTabProps, SettingsModalTabTone, } from "./SettingsModal";
45
45
  export { default as SettingsModal } from "./SettingsModal";
46
46
  export { APP_WORKSPACE_SWITCHER_SEARCH_FROM, type AppWorkspaceSidebarSwitcherProps, type AppWorkspaceSwitcherAction, type AppWorkspaceSwitcherOption, } from "./SidebarSwitcher";
47
+ export { measureScrollFade } from "./scroll-fade";
47
48
  export type { TabBarItem, TabBarProps } from "./TabBar";
48
49
  export { default as TabBar } from "./TabBar";
49
50
  export type { TableOfContentsItem, TableOfContentsProps } from "./TableOfContents";
@@ -1,5 +1,10 @@
1
1
  /** Self-contained because the sidebar inline script embeds its source. */
2
2
  export declare function scrollFadeEdges(body: HTMLElement): "top" | "bottom" | "both" | undefined;
3
+ /**
4
+ * Measures an observed scrollport's fades now instead of at the end of the frame. Call it before reading the fades in
5
+ * the same frame as a change of the scrollport's content, as an editor does when it keeps its cursor clear of them.
6
+ */
7
+ export declare function measureScrollFade(element: HTMLElement): void;
3
8
  export declare function createScrollFade(element: () => HTMLElement | undefined, enabled: () => boolean): void;
4
9
  /** Enrich only explicitly marked UI scrollports, including SSR and later navigation. */
5
10
  export declare function installScrollFades(root: Document | HTMLElement): () => void;
@@ -14,11 +14,14 @@ type NoticeCardContentProps = {
14
14
  };
15
15
  export type NoticeCardProps = Omit<JSX.HTMLAttributes<HTMLElement>, "children" | "class" | "title"> & NoticeCardContentProps & {
16
16
  tone?: NoticeTone;
17
+ /** A Tabler icon class. Turns the notice into a compact status line whose icon and text take the tone colour. */
18
+ icon?: string;
17
19
  class?: string;
18
20
  bodyClass?: string;
19
21
  };
20
22
  export declare const NOTICE_CARD_CLASSES: {
21
23
  readonly root: "k2b-notice-card";
24
+ readonly icon: "k2b-notice-card__icon";
22
25
  readonly content: "k2b-notice-card__content";
23
26
  readonly head: "k2b-notice-card__head";
24
27
  readonly title: "k2b-notice-card__title";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k2b/ui",
3
- "version": "0.32.0",
3
+ "version": "0.33.0",
4
4
  "description": "Production-ready components for SolidJS applications.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -65,7 +65,7 @@
65
65
  "devDependencies": {
66
66
  "@babel/core": "8.0.6",
67
67
  "@babel/preset-typescript": "8.0.1",
68
- "@k2b/ssr": "0.20.0",
68
+ "@k2b/ssr": "0.20.1",
69
69
  "@types/babel__core": "7.20.5",
70
70
  "@types/bun": "1.4.2",
71
71
  "axe-core": "4.11.0",