@k2b/ui 0.23.0 → 0.25.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 (161) hide show
  1. package/README.md +2 -2
  2. package/dist/browser/actions/Dropdown.js +67 -52
  3. package/dist/browser/actions/Dropdown.js.map +1 -1
  4. package/dist/browser/actions/GestureMenu.js +3 -3
  5. package/dist/browser/actions/GestureMenu.js.map +1 -1
  6. package/dist/browser/actions/SpotlightSearch.js +13 -6
  7. package/dist/browser/actions/SpotlightSearch.js.map +1 -1
  8. package/dist/browser/actions/Toolbar.js +75 -1
  9. package/dist/browser/actions/Toolbar.js.map +1 -1
  10. package/dist/browser/content/Calendar.js +1570 -923
  11. package/dist/browser/content/Calendar.js.map +1 -1
  12. package/dist/browser/content/CalendarDayView.js +2 -2
  13. package/dist/browser/content/CalendarDayView.js.map +1 -1
  14. package/dist/browser/content/CalendarWeekView.js +29 -7
  15. package/dist/browser/content/CalendarWeekView.js.map +1 -1
  16. package/dist/browser/content/DataTable.js +45 -35
  17. package/dist/browser/content/DataTable.js.map +1 -1
  18. package/dist/browser/content/Kbd.js +51 -0
  19. package/dist/browser/content/Kbd.js.map +1 -0
  20. package/dist/browser/content/LabelChip.js +38 -0
  21. package/dist/browser/content/LabelChip.js.map +1 -0
  22. package/dist/browser/content/MarkdownView.js +2 -1
  23. package/dist/browser/content/MarkdownView.js.map +1 -1
  24. package/dist/browser/content/Steps.js +34 -0
  25. package/dist/browser/content/Steps.js.map +1 -0
  26. package/dist/browser/content/VirtualFeed.js +33 -1
  27. package/dist/browser/content/VirtualFeed.js.map +1 -1
  28. package/dist/browser/content/calendar-day-scroll.js +17 -4
  29. package/dist/browser/content/calendar-day-scroll.js.map +1 -1
  30. package/dist/browser/content/calendar-dialogs.js +32 -60
  31. package/dist/browser/content/calendar-dialogs.js.map +1 -1
  32. package/dist/browser/content/calendar-month-scroll.js +80 -0
  33. package/dist/browser/content/calendar-month-scroll.js.map +1 -0
  34. package/dist/browser/content/calendar-time-view.js +9 -4
  35. package/dist/browser/content/calendar-time-view.js.map +1 -1
  36. package/dist/browser/content/index.js +4 -1
  37. package/dist/browser/content/index.js.map +1 -1
  38. package/dist/browser/content/markdown-info-blocks.js +33 -5
  39. package/dist/browser/content/markdown-info-blocks.js.map +1 -1
  40. package/dist/browser/feedback/prompts.js +17 -3
  41. package/dist/browser/feedback/prompts.js.map +1 -1
  42. package/dist/browser/intl/index.js +1 -0
  43. package/dist/browser/intl/index.js.map +1 -1
  44. package/dist/browser/intl/shortcut-messages.js +77 -0
  45. package/dist/browser/intl/shortcut-messages.js.map +1 -0
  46. package/dist/browser/intl/shortcut.js +123 -0
  47. package/dist/browser/intl/shortcut.js.map +1 -0
  48. package/dist/browser/layout/AppWorkspace.js +345 -325
  49. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  50. package/dist/browser/layout/Navigation.js +18 -3
  51. package/dist/browser/layout/Navigation.js.map +1 -1
  52. package/dist/browser/layout/PageTitle.js +14 -0
  53. package/dist/browser/layout/PageTitle.js.map +1 -1
  54. package/dist/browser/layout/SidebarSwitcher.js +505 -0
  55. package/dist/browser/layout/SidebarSwitcher.js.map +1 -0
  56. package/dist/browser/layout/TableOfContents.js +115 -0
  57. package/dist/browser/layout/TableOfContents.js.map +1 -0
  58. package/dist/browser/layout/app-workspace-controller.js +15 -48
  59. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  60. package/dist/browser/layout/index.js +2 -0
  61. package/dist/browser/layout/index.js.map +1 -1
  62. package/dist/browser/layout/navigation-model.js +1 -0
  63. package/dist/browser/layout/navigation-model.js.map +1 -1
  64. package/dist/browser/layout/table-of-contents-messages.js +19 -0
  65. package/dist/browser/layout/table-of-contents-messages.js.map +1 -0
  66. package/dist/browser/surfaces/LinkCard.js +40 -24
  67. package/dist/browser/surfaces/LinkCard.js.map +1 -1
  68. package/dist/ssr/actions/Dropdown.js +11 -5
  69. package/dist/ssr/actions/Dropdown.js.map +1 -1
  70. package/dist/ssr/actions/GestureMenu.js +3 -3
  71. package/dist/ssr/actions/GestureMenu.js.map +1 -1
  72. package/dist/ssr/actions/SpotlightSearch.js +9 -3
  73. package/dist/ssr/actions/SpotlightSearch.js.map +1 -1
  74. package/dist/ssr/actions/Toolbar.js +67 -1
  75. package/dist/ssr/actions/Toolbar.js.map +1 -1
  76. package/dist/ssr/content/Calendar.js +895 -321
  77. package/dist/ssr/content/Calendar.js.map +1 -1
  78. package/dist/ssr/content/CalendarDayView.js +2 -2
  79. package/dist/ssr/content/CalendarDayView.js.map +1 -1
  80. package/dist/ssr/content/CalendarWeekView.js +28 -7
  81. package/dist/ssr/content/CalendarWeekView.js.map +1 -1
  82. package/dist/ssr/content/DataTable.js +21 -17
  83. package/dist/ssr/content/DataTable.js.map +1 -1
  84. package/dist/ssr/content/Kbd.js +38 -0
  85. package/dist/ssr/content/Kbd.js.map +1 -0
  86. package/dist/ssr/content/LabelChip.js +21 -0
  87. package/dist/ssr/content/LabelChip.js.map +1 -0
  88. package/dist/ssr/content/MarkdownView.js +2 -1
  89. package/dist/ssr/content/MarkdownView.js.map +1 -1
  90. package/dist/ssr/content/Steps.js +14 -0
  91. package/dist/ssr/content/Steps.js.map +1 -0
  92. package/dist/ssr/content/VirtualFeed.js +33 -1
  93. package/dist/ssr/content/VirtualFeed.js.map +1 -1
  94. package/dist/ssr/content/calendar-day-scroll.js +17 -4
  95. package/dist/ssr/content/calendar-day-scroll.js.map +1 -1
  96. package/dist/ssr/content/calendar-dialogs.js +12 -32
  97. package/dist/ssr/content/calendar-dialogs.js.map +1 -1
  98. package/dist/ssr/content/calendar-month-scroll.js +80 -0
  99. package/dist/ssr/content/calendar-month-scroll.js.map +1 -0
  100. package/dist/ssr/content/calendar-time-view.js +8 -3
  101. package/dist/ssr/content/calendar-time-view.js.map +1 -1
  102. package/dist/ssr/content/index.js +4 -1
  103. package/dist/ssr/content/index.js.map +1 -1
  104. package/dist/ssr/content/markdown-info-blocks.js +33 -5
  105. package/dist/ssr/content/markdown-info-blocks.js.map +1 -1
  106. package/dist/ssr/feedback/prompts.js +17 -3
  107. package/dist/ssr/feedback/prompts.js.map +1 -1
  108. package/dist/ssr/intl/index.js +1 -0
  109. package/dist/ssr/intl/index.js.map +1 -1
  110. package/dist/ssr/intl/shortcut-messages.js +77 -0
  111. package/dist/ssr/intl/shortcut-messages.js.map +1 -0
  112. package/dist/ssr/intl/shortcut.js +123 -0
  113. package/dist/ssr/intl/shortcut.js.map +1 -0
  114. package/dist/ssr/layout/AppWorkspace.js +67 -59
  115. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  116. package/dist/ssr/layout/Navigation.js +12 -2
  117. package/dist/ssr/layout/Navigation.js.map +1 -1
  118. package/dist/ssr/layout/PageTitle.js +14 -0
  119. package/dist/ssr/layout/PageTitle.js.map +1 -1
  120. package/dist/ssr/layout/SidebarSwitcher.js +271 -0
  121. package/dist/ssr/layout/SidebarSwitcher.js.map +1 -0
  122. package/dist/ssr/layout/TableOfContents.js +79 -0
  123. package/dist/ssr/layout/TableOfContents.js.map +1 -0
  124. package/dist/ssr/layout/app-workspace-controller.js +15 -48
  125. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  126. package/dist/ssr/layout/index.js +2 -0
  127. package/dist/ssr/layout/index.js.map +1 -1
  128. package/dist/ssr/layout/navigation-model.js +1 -0
  129. package/dist/ssr/layout/navigation-model.js.map +1 -1
  130. package/dist/ssr/layout/table-of-contents-messages.js +19 -0
  131. package/dist/ssr/layout/table-of-contents-messages.js.map +1 -0
  132. package/dist/ssr/surfaces/LinkCard.js +26 -10
  133. package/dist/ssr/surfaces/LinkCard.js.map +1 -1
  134. package/dist/styles.css +1 -1
  135. package/dist/types/actions/Dropdown.d.ts +12 -0
  136. package/dist/types/actions/SpotlightSearch.d.ts +2 -0
  137. package/dist/types/content/Calendar.d.ts +20 -7
  138. package/dist/types/content/CalendarWeekView.d.ts +1 -1
  139. package/dist/types/content/DataTable.d.ts +9 -0
  140. package/dist/types/content/Kbd.d.ts +16 -0
  141. package/dist/types/content/LabelChip.d.ts +12 -0
  142. package/dist/types/content/MarkdownView.d.ts +2 -1
  143. package/dist/types/content/Steps.d.ts +12 -0
  144. package/dist/types/content/VirtualFeed.d.ts +8 -0
  145. package/dist/types/content/calendar-day-scroll.d.ts +9 -4
  146. package/dist/types/content/calendar-dialogs.d.ts +0 -2
  147. package/dist/types/content/calendar-month-scroll.d.ts +25 -0
  148. package/dist/types/content/index.d.ts +7 -1
  149. package/dist/types/content/markdown-info-blocks.d.ts +21 -4
  150. package/dist/types/feedback/prompts.d.ts +8 -2
  151. package/dist/types/intl/index.d.ts +2 -0
  152. package/dist/types/intl/shortcut-messages.d.ts +35 -0
  153. package/dist/types/intl/shortcut.d.ts +29 -0
  154. package/dist/types/layout/AppWorkspace.d.ts +5 -1
  155. package/dist/types/layout/SidebarSwitcher.d.ts +65 -0
  156. package/dist/types/layout/TableOfContents.d.ts +24 -0
  157. package/dist/types/layout/index.d.ts +3 -0
  158. package/dist/types/layout/navigation-model.d.ts +4 -0
  159. package/dist/types/layout/table-of-contents-messages.d.ts +4 -0
  160. package/dist/types/surfaces/LinkCard.d.ts +3 -0
  161. package/package.json +4 -4
@@ -8,11 +8,21 @@ export type DropdownActionBase = {
8
8
  icon?: string;
9
9
  image?: string;
10
10
  label: string;
11
+ /**
12
+ * Accessible name when it must say more than the visible label, such as the current value and what the next
13
+ * activation does. It must contain the visible label.
14
+ */
15
+ ariaLabel?: string;
11
16
  description?: string;
12
17
  variant?: "danger";
13
18
  };
14
19
  export type DropdownAction = (DropdownActionBase & {
15
20
  action: () => void;
21
+ /**
22
+ * Set `false` for an action that changes a value in place, such as cycling a setting: the menu stays open and
23
+ * the focus stays on the row. Defaults to `true`.
24
+ */
25
+ closeOnSelect?: boolean;
16
26
  href?: never;
17
27
  external?: never;
18
28
  }) | (DropdownActionBase & {
@@ -80,6 +90,8 @@ export type DropdownTriggerProps = Omit<ButtonProps, "aria-controls" | "aria-exp
80
90
  };
81
91
  export type DropdownItemProps = {
82
92
  children: JSX.Element;
93
+ closeOnSelect?: boolean;
94
+ ariaLabel?: string;
83
95
  icon?: string;
84
96
  image?: string;
85
97
  description?: string;
@@ -10,6 +10,8 @@ export type SpotlightButtonProps = {
10
10
  label?: string;
11
11
  title?: string;
12
12
  icon?: string;
13
+ /** Shortcut such as "mod+k"; takes precedence over shortcutLabel. */
14
+ shortcut?: string;
13
15
  shortcutLabel?: string | false;
14
16
  ariaLabel?: string;
15
17
  disabled?: boolean;
@@ -155,17 +155,27 @@ export type CalendarProps<V extends string = never> = {
155
155
  * `startHour`, `endHour`, and the visible hours do not apply then.
156
156
  */
157
157
  dayHours?: readonly [start: number, end: number];
158
- /** Day and week views with `dayHours`: the days of `events`. Without it they cover the day or week of `date`. */
158
+ /** Loaded days of the continuous month view and the day/week views with `dayHours`, with an exclusive end. */
159
159
  range?: CalendarRange;
160
- /** Called once when the reader nears the first loaded day, again once `range.from` moved. */
160
+ /**
161
+ * Called once when the reader nears the first loaded day, again once `range.from` moved.
162
+ * May return a promise that settles once the range has grown; when it settles without moving that end, the
163
+ * continuous month treats the end as reached, and Next/Previous past it go through the host's navigation.
164
+ */
161
165
  onLoadEarlier?: () => unknown;
162
- /** Called once when the reader nears the last loaded day, again once `range.to` moved. */
166
+ /**
167
+ * Called once when the reader nears the last loaded day, again once `range.to` moved.
168
+ * May return a promise that settles once the range has grown; when it settles without moving that end, the
169
+ * continuous month treats the end as reached, and Next/Previous past it go through the host's navigation.
170
+ */
163
171
  onLoadLater?: () => unknown;
164
172
  /**
165
- * Day and week views with `dayHours`: the first and the last day the reader sees, once the view opened and whenever
166
- * scrolling changed them, such as for the URL or a count of what is in view.
173
+ * Scrolling views: the first and last visible day, and the focus date, after positioning and when they change.
174
+ * Day/week views use their first day as focus. Continuous month uses the first selected day inside its focus month,
175
+ * else the host's `date` when in that month, else today when in that month, else its first. Month rows count as
176
+ * visible when more than half is on screen.
167
177
  */
168
- onVisibleDateChange?: (date: Date, last: Date) => void;
178
+ onVisibleDateChange?: (date: Date, last: Date, focus: Date) => void;
169
179
  visibleStartHour?: number;
170
180
  visibleEndHour?: number;
171
181
  allDayMaxHeightRem?: number;
@@ -240,7 +250,10 @@ export type CalendarSelectionControls = {
240
250
  export type CalendarQuickCreateControls = {
241
251
  /** What the person asked to create through `quickCreate`; absent after a click, a drag, or the keyboard. */
242
252
  create?: string;
243
- /** Closes the quick create and returns the focus to the selected day; once another quick create replaced it, nothing. */
253
+ /**
254
+ * Closes the quick create, returns the focus to the selected day only while the focus is still in the quick create, and
255
+ * leaves a newer selection in place; once another quick create replaced it, nothing.
256
+ */
244
257
  close: () => void;
245
258
  };
246
259
  export type CalendarEventTimeChange = {
@@ -2,6 +2,6 @@ import { type TimeViewProps } from "./calendar-time-view";
2
2
  /**
3
3
  * The week view with `dayHours`: the loaded days side by side in one strip, seven on a wide screen and three on a
4
4
  * phone. A trackpad, Shift with the wheel, or a finger scroll it sideways day by day; each gesture keeps the axis it
5
- * started on, and the strip settles on a day start. The arrows move by whole weeks.
5
+ * started on, and the strip settles on a day edge. The arrows move by whole weeks.
6
6
  */
7
7
  export declare const CalendarWeekView: (props: TimeViewProps) => import("solid-js").JSX.Element;
@@ -14,6 +14,15 @@ export type DataTableColumn<T> = {
14
14
  cellClass?: string;
15
15
  /** Defaults to right for numeric values and left for everything else. */
16
16
  align?: "left" | "center" | "right";
17
+ /**
18
+ * Keeps each value on one line, so the column is at least as wide as its
19
+ * longest value. For dates, times, numbers, amounts, and short codes.
20
+ * Defaults to true when the column's first value is a number or date. The
21
+ * default cell wrapper already keeps every value on one line; this option
22
+ * decides wrapping for content under a custom `cellContentClass`, and a
23
+ * `white-space` that class sets itself wins.
24
+ */
25
+ nowrap?: boolean;
17
26
  /**
18
27
  * Marks the column sortable. Pass a string when the server's sort key
19
28
  * differs from the column id — they often do, because one column can show a
@@ -0,0 +1,16 @@
1
+ import { type JSX } from "solid-js";
2
+ import { type KeyboardPlatform } from "../intl/shortcut";
3
+ export type KbdProps = {
4
+ /** Shortcut such as "mod+k", "shift+/", "enter". */
5
+ keys: string;
6
+ /** Set on the server when the host knows the reader's platform. */
7
+ platform?: KeyboardPlatform;
8
+ class?: string;
9
+ };
10
+ /**
11
+ * Accessible key caps using the inherited locale and the reader's platform.
12
+ * A host rendering caps on the server passes `platform` to avoid a switch after hydration.
13
+ * @example <Kbd keys="mod+k" platform="apple" />
14
+ */
15
+ export declare function Kbd(props: KbdProps): JSX.Element;
16
+ export default Kbd;
@@ -0,0 +1,12 @@
1
+ import { type JSX } from "solid-js";
2
+ export type LabelChipProps = {
3
+ icon?: string;
4
+ children: JSX.Element;
5
+ class?: string;
6
+ };
7
+ /**
8
+ * Names a UI control inside running text. The icon is a full class string.
9
+ * @example <LabelChip icon="ti ti-share">Share</LabelChip>
10
+ */
11
+ export declare function LabelChip(props: LabelChipProps): JSX.Element;
12
+ export default LabelChip;
@@ -43,7 +43,8 @@ export declare const createSafeMarked: (locale?: string) => Marked;
43
43
  *
44
44
  * Renders untrusted Markdown safely by default. Raw HTML and unsafe link
45
45
  * protocols are escaped. Info blocks (`:::note`, `:::info`, `:::success`,
46
- * `:::warning`, `:::danger`) render as the calm `NoticeCard`. Already-rendered
46
+ * `:::warning`, `:::danger`) render on a tinted surface without a border.
47
+ * The icon and title use the tone colour; body text stays neutral. Rendered
47
48
  * HTML requires the deliberately named `trustedHtml` boundary; the caller owns
48
49
  * sanitization in that mode.
49
50
  *
@@ -0,0 +1,12 @@
1
+ import type { JSX } from "solid-js";
2
+ export type StepsProps = {
3
+ children: JSX.Element;
4
+ start?: number;
5
+ class?: string;
6
+ };
7
+ /**
8
+ * An ordered instruction list with accent numbers. Trusted HTML can use the same class.
9
+ * @example <Steps start={2}><li>Select Share.</li><li>Copy the link.</li></Steps>
10
+ */
11
+ export declare function Steps(props: StepsProps): JSX.Element;
12
+ export default Steps;
@@ -66,6 +66,14 @@ export type VirtualFeedProps<T> = {
66
66
  announce?: (added: readonly T[]) => string | undefined;
67
67
  /** Called when the reader reaches or leaves the end. */
68
68
  onEndChange?: (atEnd: boolean) => void;
69
+ /**
70
+ * Called when the items in view change: the first and last item whose whole height is in view. An item taller
71
+ * than the view counts while it covers the view. `null` while no item is in view.
72
+ */
73
+ onVisibleChange?: (visible: {
74
+ first: T;
75
+ last: T;
76
+ } | null) => void;
69
77
  /** Receives the controller once the feed is mounted. */
70
78
  controller?: (controller: VirtualFeedController) => void;
71
79
  /** Shown while `items` is empty. */
@@ -3,8 +3,9 @@
3
3
  *
4
4
  * The day view runs down through the days and stops gently at each day start: within `STOP_ZONE` pixels of one the
5
5
  * wheel slows down, and a scroll that rests close to one glides onto it. The week view scrolls sideways through the
6
- * days; a wheel or trackpad gesture keeps the axis it started on, and a scroll that rests between two days glides to
7
- * the nearer day.
6
+ * days; a wheel or trackpad gesture keeps the axis it started on, and a resting scroll glides to the nearest day start
7
+ * or, with end space, day end at the edge of the visible room. A scroll no gesture made, such as a reveal, glides on in
8
+ * its own direction, so what it brought into view stays there.
8
9
  */
9
10
  /** Pixels before and after a day start in which the wheel slows down. */
10
11
  export declare const STOP_ZONE = 72;
@@ -38,5 +39,9 @@ export type WheelAxis = "x" | "y";
38
39
  export declare const wheelAxis: (deltaX: number, deltaY: number, shiftKey: boolean) => WheelAxis;
39
40
  /** The sideways part of a wheel event on an axis, Shift turning the vertical delta into a sideways one. */
40
41
  export declare const wheelDelta: (axis: WheelAxis, deltaX: number, deltaY: number, shiftKey: boolean) => number;
41
- /** The scroll position of the nearest day start in a strip of equal columns. */
42
- export declare const snapToColumn: (position: number, width: number) => number;
42
+ /**
43
+ * The day start nearest to `position` in a strip of equal columns, or with `room` the nearer day edge at either end of
44
+ * the visible room; ties keep the start. A `heading` of 1 or -1 only looks ahead or back, for a scroll that brought
45
+ * something into view and must not slide back over it.
46
+ */
47
+ export declare const snapToColumn: (position: number, width: number, room?: number, heading?: number) => number;
@@ -1,7 +1,5 @@
1
1
  import type { CalendarCommand } from "./Calendar";
2
2
  import type { CalendarMessages } from "./calendar-messages";
3
- /** The keys of a shortcut as the reader presses them, such as ["⇧", "N"] or ["Shift", "N"]. */
4
- export declare const shortcutKeys: (shortcut: string) => string[];
5
3
  /**
6
4
  * The calendar's shortcuts: the same list the host registers for its dispatcher and its help. `alternatives` names
7
5
  * other keys the calendar itself handles for a command, such as the arrow keys that page like J and K.
@@ -0,0 +1,25 @@
1
+ import type { TodayDirection } from "./calendar-time-view";
2
+ export declare const MONTH_ROWS_IN_VIEW = 5;
3
+ export declare const MONTH_ROW_BLOCK = 8;
4
+ /** Whole weeks covering the loaded days, with an exclusive end and the date context's first weekday. */
5
+ export declare const monthWeekKeys: (first: string, to: string, firstDayOfWeek: 0 | 1) => string[];
6
+ /** The row at the center of the area below the weekday header, clamped to the loaded weeks. */
7
+ export declare const monthFocusRow: (top: number, viewHeight: number, rowHeight: number, total: number) => number;
8
+ /** The middle day of a week names its month: Thursday for Monday weeks, Wednesday for Sunday weeks. */
9
+ export declare const monthOfWeek: (week: string) => string;
10
+ /** The loaded row containing a day, including the first of a month; absent outside the loaded weeks. */
11
+ export declare const monthRowOf: (weeks: readonly string[], key: string) => number | undefined;
12
+ /** The half-open interval of rows whose visible height exceeds half a row. */
13
+ export declare const monthVisibleRows: (top: number, viewHeight: number, rowHeight: number, total: number) => {
14
+ first: number;
15
+ end: number;
16
+ };
17
+ /** One block above and below the visible rows' blocks; the window changes only at their block boundaries. */
18
+ export declare const monthRenderWindow: (top: number, viewHeight: number, rowHeight: number, total: number) => {
19
+ first: number;
20
+ end: number;
21
+ };
22
+ /** The least movement that shows a row whole, or nothing when it is already fully in view. */
23
+ export declare const monthRevealTop: (row: number, top: number, viewHeight: number, rowHeight: number) => number | undefined;
24
+ /** Today points up or down until more than half its row is visible. */
25
+ export declare const monthTodayDirection: (row: number, top: number, viewHeight: number, rowHeight: number) => TodayDirection;
@@ -26,6 +26,10 @@ export { FileBrowserPanel, type FileBrowserPanelProps, type FileSource, openFile
26
26
  export { FileGrid, type FileGridProps } from "./FileGrid";
27
27
  export { default as FileTree, type FileTreeActions, type FileTreeEntry, type FileTreeProps } from "./FileTree";
28
28
  export { canPreviewFile, default as FileView, type FileViewContent, type FileViewFile, type FileViewPreviewKind, type FileViewProps, type FileViewRenderer, type FileViewRendererProps, formatFileViewSize, getFileViewPreviewKind, } from "./FileView";
29
+ export type { KbdProps } from "./Kbd";
30
+ export { Kbd } from "./Kbd";
31
+ export type { LabelChipProps } from "./LabelChip";
32
+ export { LabelChip } from "./LabelChip";
29
33
  export type { LightboxAction, LightboxImage } from "./Lightbox";
30
34
  export { default as Lightbox } from "./Lightbox";
31
35
  export type { LogTableEntry } from "./LogEntriesTable";
@@ -33,13 +37,15 @@ export { default as LogEntriesTable } from "./LogEntriesTable";
33
37
  export { default as MarkdownView, type MarkdownRenderOptions, type MarkdownViewProps, renderSafeMarkdown } from "./MarkdownView";
34
38
  export type { MessageGroupEntry, MessageRowAction, MessageRowAttachment, MessageRowAuthor, MessageRowFile, MessageRowMedia, MessageRowProgress, MessageRowProps, MessageRowQuote, MessageRowReaction, MessageRowStatus, MessageRowThread, MessageSystemRowProps, } from "./MessageRow";
35
39
  export { MessageRow, MessageSystemRow, startsMessageGroup } from "./MessageRow";
36
- export { type MarkdownInfoBlock, type MarkdownInfoBlockRenderInput, type MarkdownInfoBlockType, markdownInfoBlocks, renderMarkdownInfoBlock, scanMarkdownInfoBlock, } from "./markdown-info-blocks";
40
+ export { MARKDOWN_CALLOUT_CLASSES, MARKDOWN_CALLOUT_ICON_ATTRIBUTES, type MarkdownInfoBlock, type MarkdownInfoBlockRenderInput, type MarkdownInfoBlockType, markdownInfoBlocks, renderMarkdownInfoBlock, scanMarkdownInfoBlock, } from "./markdown-info-blocks";
37
41
  export { type MarkdownLinkInput, type MarkdownReference, type MarkdownReferenceKind, type MarkdownReferenceType, markdownLinkReference, markdownReferenceIcon, markdownReferenceType, markdownReferenceTypeLabel, markStandaloneLinks, renderMarkdownLink, } from "./markdown-links";
38
42
  export { Pagination, type PaginationProps } from "./Pagination";
39
43
  export type { PdfPreviewProps, PdfPreviewRequest } from "./PdfPreview";
40
44
  export { default as PdfPreview } from "./PdfPreview";
41
45
  export type { RangeOption, RangePickerProps } from "./RangePicker";
42
46
  export { default as RangePicker } from "./RangePicker";
47
+ export type { StepsProps } from "./Steps";
48
+ export { Steps } from "./Steps";
43
49
  export type { StructuredDataPreviewMode, StructuredDataPreviewProps, StructuredDataValue } from "./StructuredDataPreview";
44
50
  export { default as StructuredDataPreview, isStructuredDataValue } from "./StructuredDataPreview";
45
51
  export type { TimelineColor, TimelineController, TimelineItem, TimelineProps } from "./Timeline";
@@ -21,6 +21,23 @@ declare const TONES: {
21
21
  readonly warning: "warning";
22
22
  readonly danger: "danger";
23
23
  };
24
+ export declare const MARKDOWN_CALLOUT_CLASSES: {
25
+ readonly root: "k2b-callout";
26
+ readonly icon: "k2b-callout__icon";
27
+ };
28
+ /** Fixed attributes for decorative callout icons, including hosts with their own sanitizer. */
29
+ export declare const MARKDOWN_CALLOUT_ICON_ATTRIBUTES: {
30
+ readonly class: "k2b-callout__icon";
31
+ readonly "aria-hidden": "true";
32
+ readonly width: "20";
33
+ readonly height: "20";
34
+ readonly viewBox: "0 0 24 24";
35
+ readonly fill: "none";
36
+ readonly stroke: "currentColor";
37
+ readonly "stroke-width": "2";
38
+ readonly "stroke-linecap": "round";
39
+ readonly "stroke-linejoin": "round";
40
+ };
24
41
  export type MarkdownInfoBlockType = keyof typeof TONES;
25
42
  export type MarkdownInfoBlock = {
26
43
  type: MarkdownInfoBlockType;
@@ -48,10 +65,10 @@ export type MarkdownInfoBlockRenderInput = {
48
65
  */
49
66
  export declare const scanMarkdownInfoBlock: (source: string) => MarkdownInfoBlock | null;
50
67
  /**
51
- * Renders an info block as the calm `NoticeCard`: the tone tints the surface,
52
- * the text stays neutral, and there is no icon. A title is the visible heading
53
- * and names the block; without one, the localized type name is announced to
54
- * screen readers only.
68
+ * Renders a callout on a tinted surface without a border. The decorative icon
69
+ * and title use the tone colour; body text stays neutral. A title is the
70
+ * visible heading and names the block; without one, screen readers hear the
71
+ * localized type name.
55
72
  */
56
73
  export declare const renderMarkdownInfoBlock: (input: MarkdownInfoBlockRenderInput) => string;
57
74
  /**
@@ -1,5 +1,5 @@
1
1
  import { type JSX } from "solid-js";
2
- import { type OpenDialogOptions } from "./dialog-core";
2
+ import { type DialogRender, type OpenDialogOptions } from "./dialog-core";
3
3
  export interface DialogOptions {
4
4
  signal?: AbortSignal;
5
5
  title?: string;
@@ -165,7 +165,13 @@ export declare const prompts: {
165
165
  prompt: typeof promptText;
166
166
  promptNumber: typeof promptNumber;
167
167
  form: <T extends Record<string, FieldSchema>>(config: PromptFormOptions<T>) => Promise<InferFormValues<T> | null>;
168
- dialog: <T extends unknown = unknown>(component: (close: (result?: T) => void) => JSX.Element, options?: DialogOptions) => Promise<T | undefined>;
168
+ /**
169
+ * Open custom content with a typed close callback and the dialog render context.
170
+ * Register a dismiss handler to guard Escape, backdrop clicks and the supplied header's close button,
171
+ * for example while saving. Explicit close(result) bypasses the guard. Without a handler, dismissal
172
+ * keeps its existing behavior, including a header close button independent of cancelBehavior.
173
+ */
174
+ dialog: <T extends unknown = unknown>(component: DialogRender<T>, options?: DialogOptions) => Promise<T | undefined>;
169
175
  search: typeof openSearchPrompt;
170
176
  error: (content: string | HTMLElement, options?: DialogOptions) => Promise<unknown>;
171
177
  };
@@ -2,3 +2,5 @@ export type { FormatBytesProps, FormatCurrencyProps, FormatDateProps, FormatDate
2
2
  export { Format } from "./Format";
3
3
  export type { LocaleProviderProps } from "./locale";
4
4
  export { LocaleProvider, useLocale } from "./locale";
5
+ export type { FormattedShortcut, KeyboardPlatform, ShortcutFormatOptions, ShortcutKey } from "./shortcut";
6
+ export { formatShortcut, keyboardPlatform } from "./shortcut";
@@ -0,0 +1,35 @@
1
+ /** Imperative UI inherits the document locale when no locale is supplied. */
2
+ export declare const resolveShortcutMessages: (locale?: string) => {
3
+ ctrlLabel: string;
4
+ altLabel: string;
5
+ shiftLabel: string;
6
+ metaLabel: string;
7
+ control: string;
8
+ appleControl: string;
9
+ option: string;
10
+ shift: string;
11
+ command: string;
12
+ alt: string;
13
+ meta: string;
14
+ arrowup: string;
15
+ arrowdown: string;
16
+ arrowleft: string;
17
+ arrowright: string;
18
+ enter: string;
19
+ escape: string;
20
+ tab: string;
21
+ space: string;
22
+ backspace: string;
23
+ delete: string;
24
+ home: string;
25
+ end: string;
26
+ pageup: string;
27
+ pagedown: string;
28
+ spaceLabel: string;
29
+ deleteLabel: string;
30
+ homeLabel: string;
31
+ endLabel: string;
32
+ pageupLabel: string;
33
+ pagedownLabel: string;
34
+ };
35
+ export declare const checkShortcutMessages: () => import("@k2b/stdlib").CatalogIssue[];
@@ -0,0 +1,29 @@
1
+ export type KeyboardPlatform = "apple" | "other";
2
+ /**
3
+ * Apple keyboards name the platform modifier Command. `source` is a User-Agent or `navigator.platform` string.
4
+ * Without `source`, reads the runtime's navigator; server callers pass the request's User-Agent.
5
+ * @example keyboardPlatform("MacIntel") // "apple"
6
+ */
7
+ export declare const keyboardPlatform: (source?: string) => KeyboardPlatform;
8
+ export type ShortcutKey = {
9
+ /** What the cap shows: "⌘", "Strg", "K", "↵". */
10
+ label: string;
11
+ /** What a screen reader says: "Command", "Steuerung", "K", "Enter". */
12
+ name: string;
13
+ };
14
+ export type FormattedShortcut = {
15
+ keys: ShortcutKey[];
16
+ /** "⌘K" on Apple, "Ctrl+K" / "Strg+K" elsewhere. */
17
+ label: string;
18
+ /** "Command K", "Steuerung K". */
19
+ name: string;
20
+ };
21
+ export type ShortcutFormatOptions = {
22
+ platform?: KeyboardPlatform;
23
+ locale?: string;
24
+ };
25
+ /**
26
+ * Formats one plus-separated shortcut in canonical modifier order.
27
+ * @example formatShortcut("mod+alt+n", { platform: "apple" }).label // "⌥⌘N"
28
+ */
29
+ export declare const formatShortcut: (shortcut: string, options?: ShortcutFormatOptions) => FormattedShortcut;
@@ -2,12 +2,14 @@ import { type LinkNavigateEvent, type NavigationScrollMode } from "@k2b/ssr/nav"
2
2
  import { type JSX } from "solid-js";
3
3
  import { type AppWorkspaceLayoutState } from "./app-workspace-state";
4
4
  import type { ScrollAreaProps } from "./ScrollArea";
5
+ import { type AppWorkspaceSidebarSwitcherProps } from "./SidebarSwitcher";
5
6
  export type AppWorkspaceProps = {
6
7
  children: JSX.Element;
7
8
  class?: string;
8
9
  /** A host with its own phone chrome can use the full canvas below 48rem (768 px). */
9
10
  mobileSurface?: "contained" | "flush";
10
- /** Draws no frame: no border, corner radius, or shadow, for an overview that is the page itself. */
11
+ /** Removes the workspace's own border, radius, and shadow for an overview that is the page itself.
12
+ * A host may frame the outermost workspace as its app card, as Cloud does from 1536 px on signed-in pages. */
11
13
  flat?: boolean;
12
14
  resizable?: boolean;
13
15
  /**
@@ -233,6 +235,7 @@ export type AppWorkspaceSidebarItemIconProps = {
233
235
  };
234
236
  export type AppWorkspaceSidebarItemLabelProps = {
235
237
  children: JSX.Element;
238
+ /** False keeps one line with an ellipsis; rows wrap long labels onto a second line by default. */
236
239
  marquee?: boolean;
237
240
  };
238
241
  export type AppWorkspaceSidebarItemMetaProps = {
@@ -354,6 +357,7 @@ type AppWorkspaceComponent = ((props: AppWorkspaceProps) => JSX.Element) & {
354
357
  SidebarDesktop: (props: {
355
358
  children: JSX.Element;
356
359
  }) => JSX.Element;
360
+ SidebarSwitcher: (props: AppWorkspaceSidebarSwitcherProps) => JSX.Element;
357
361
  SidebarSection: (props: AppWorkspaceSidebarSectionProps) => JSX.Element;
358
362
  SidebarBody: (props: AppWorkspaceSidebarBodyProps) => JSX.Element;
359
363
  SidebarFooter: (props: AppWorkspaceSidebarContentProps) => JSX.Element;
@@ -0,0 +1,65 @@
1
+ import { type JSX } from "solid-js";
2
+ /** One container a person can switch to, such as a notebook, a space, or a mailbox. */
3
+ export type AppWorkspaceSwitcherOption = {
4
+ id: string;
5
+ label: string;
6
+ /** One secondary fact, such as a mailbox's address. */
7
+ description?: string;
8
+ /** Tabler icon class; without it the row takes the switcher's icon. */
9
+ icon?: string;
10
+ /** Tints the icon; without it the app accent does. */
11
+ color?: string;
12
+ href: string;
13
+ };
14
+ /** A row below the containers, such as "New notebook" or "All notebooks". */
15
+ export type AppWorkspaceSwitcherAction = {
16
+ id: string;
17
+ label: string;
18
+ icon: string;
19
+ disabled?: boolean;
20
+ } & ({
21
+ href: string;
22
+ action?: never;
23
+ } | {
24
+ action: () => void;
25
+ href?: never;
26
+ });
27
+ export type AppWorkspaceSidebarSwitcherProps = {
28
+ /** The current container's ID among `options`. */
29
+ currentId: string;
30
+ /** The current container's name. */
31
+ label: string;
32
+ /** One secondary fact under the name, such as a mailbox's address. */
33
+ description?: string;
34
+ icon: string;
35
+ /** Tints the icon; without it the app accent does. */
36
+ color?: string;
37
+ /** Names the button's purpose and its panel, such as "Switch notebook". */
38
+ switchLabel: string;
39
+ /** Every container the person can switch to, the current one included; `undefined` until they are loaded. */
40
+ options?: readonly AppWorkspaceSwitcherOption[];
41
+ /** Shown in place of the options when loading them failed; the panel offers to try again through `onLoad`. */
42
+ error?: string;
43
+ /**
44
+ * Asks for `options` while they are `undefined`: when a pointer or the focus first reaches the button, so the list
45
+ * is usually there when the panel opens, on every opening, and from the panel's retry. Ignore repeated calls while a
46
+ * request runs.
47
+ */
48
+ onLoad?: () => void;
49
+ actions?: readonly AppWorkspaceSwitcherAction[];
50
+ /**
51
+ * A host menu around the switcher, such as the phone menu, finishes dismissing itself before a chosen container
52
+ * opens or an action runs; `false` cancels the choice. Navigation passes its own.
53
+ */
54
+ beforeSelect?: () => boolean | void | Promise<boolean | void>;
55
+ /** Sizes the switcher in its place, such as `flex-1` beside a button in one row. */
56
+ class?: string;
57
+ };
58
+ /** From this many containers the panel scrolls, so it offers a search field. */
59
+ export declare const APP_WORKSPACE_SWITCHER_SEARCH_FROM = 8;
60
+ /**
61
+ * The current container at the top of a sidebar: its icon, name, and an optional fact, with a chevron that opens the
62
+ * other containers, a search field when there are many, and actions such as "New …" and "All …". The rows are links,
63
+ * so a container also opens in a new tab. In a collapsed rail it shows only the icon and opens beside the rail.
64
+ */
65
+ export declare function AppWorkspaceSidebarSwitcher(props: AppWorkspaceSidebarSwitcherProps): JSX.Element;
@@ -0,0 +1,24 @@
1
+ import { type JSX } from "solid-js";
2
+ import type { MaybeAccessor } from "../inputs/field-contract";
3
+ export type TableOfContentsItem = {
4
+ id: string;
5
+ label: string;
6
+ };
7
+ export type TableOfContentsProps = {
8
+ items: readonly TableOfContentsItem[];
9
+ /** Visible heading and navigation name. Defaults to the localized "On this page". */
10
+ title?: string;
11
+ /** Element whose scrolling decides the active section. Defaults to the window. */
12
+ scrollRoot?: MaybeAccessor<HTMLElement | undefined>;
13
+ /** Stay in view inside the caller's layout. */
14
+ sticky?: boolean;
15
+ /** Called when another section becomes active. */
16
+ onActiveChange?: (id: string | undefined) => void;
17
+ class?: string;
18
+ };
19
+ /**
20
+ * Native section links with a scroll spy on the window or a content container.
21
+ * @example <TableOfContents items={[{ id: "sharing", label: "Sharing" }]} sticky />
22
+ */
23
+ export declare function TableOfContents(props: TableOfContentsProps): JSX.Element;
24
+ export default TableOfContents;
@@ -40,5 +40,8 @@ export type { SettingsCollectionActionProps, SettingsCollectionItemActionsProps,
40
40
  export { default as SettingsCollection } from "./SettingsCollection";
41
41
  export type { SettingsModalFooterProps, SettingsModalGroupProps, SettingsModalProps, SettingsModalTabProps, SettingsModalTabTone, } from "./SettingsModal";
42
42
  export { default as SettingsModal } from "./SettingsModal";
43
+ export { APP_WORKSPACE_SWITCHER_SEARCH_FROM, type AppWorkspaceSidebarSwitcherProps, type AppWorkspaceSwitcherAction, type AppWorkspaceSwitcherOption, } from "./SidebarSwitcher";
43
44
  export type { TabBarItem, TabBarProps } from "./TabBar";
44
45
  export { default as TabBar } from "./TabBar";
46
+ export type { TableOfContentsItem, TableOfContentsProps } from "./TableOfContents";
47
+ export { TableOfContents } from "./TableOfContents";
@@ -1,6 +1,7 @@
1
1
  import type { LinkNavigateEvent, NavigationScrollMode } from "@k2b/ssr/nav";
2
2
  import type { Accessor } from "solid-js";
3
3
  import type { IntentTone } from "../semantics";
4
+ import type { AppWorkspaceSidebarSwitcherProps } from "./SidebarSwitcher";
4
5
  /** A status icon at a row's end, such as "running". `label` names it for screen readers and as its tooltip. */
5
6
  export type NavigationStatus = {
6
7
  icon: string;
@@ -72,6 +73,8 @@ export type NavigationItem = NavigationEntry & ({
72
73
  });
73
74
  export type NavigationOptions = {
74
75
  items: Accessor<readonly NavigationItem[]>;
76
+ /** The container the navigation works in, shown above the items with the same switcher as the sidebar's head. */
77
+ switcher?: Accessor<AppWorkspaceSidebarSwitcherProps>;
75
78
  onAction?: (action: string) => void | Promise<void>;
76
79
  onNavigate?: (event: LinkNavigateEvent) => void | Promise<void>;
77
80
  /** Receives disclosure toggles of items that carry `expanded`; the owner decides the next state. */
@@ -81,6 +84,7 @@ export declare function findNavigationItem(items: readonly NavigationItem[], id:
81
84
  /** One live source for renderers; no router, registry, fetching or persisted state. */
82
85
  export declare function createNavigation(options: NavigationOptions): {
83
86
  items: Accessor<readonly NavigationItem[]>;
87
+ switcher: Accessor<AppWorkspaceSidebarSwitcherProps> | undefined;
84
88
  onNavigate: ((event: LinkNavigateEvent) => void | Promise<void>) | undefined;
85
89
  onExpandedChange: ((id: string, expanded: boolean) => void) | undefined;
86
90
  activate(id: string): Promise<void>;
@@ -0,0 +1,4 @@
1
+ export declare const useTableOfContentsMessages: () => () => {
2
+ title: string;
3
+ };
4
+ export declare const checkTableOfContentsMessages: () => import("@k2b/stdlib").CatalogIssue[];
@@ -1,7 +1,10 @@
1
+ import { type LinkNavigateEvent } from "@k2b/ssr/nav";
1
2
  import { type JSX } from "solid-js";
2
3
  export type LinkCardColor = "blue" | "emerald" | "violet" | "orange" | "red" | "amber" | "zinc" | "cyan" | "rose";
3
4
  export type LinkCardProps = {
4
5
  href: string;
6
+ navigation?: "document" | "enhanced";
7
+ onNavigate?: (event: LinkNavigateEvent) => void | Promise<void>;
5
8
  title: string;
6
9
  description: string;
7
10
  icon: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k2b/ui",
3
- "version": "0.23.0",
3
+ "version": "0.25.0",
4
4
  "description": "Production-ready components for SolidJS applications.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -45,19 +45,19 @@
45
45
  "dependencies": {
46
46
  "@fontsource/ibm-plex-mono": "5.3.0",
47
47
  "@fontsource/ibm-plex-sans": "5.3.0",
48
- "@k2b/stdlib": "0.28.0",
48
+ "@k2b/stdlib": "0.29.0",
49
49
  "@tabler/icons-webfont": "3.48.0",
50
50
  "marked": "18.0.14",
51
51
  "qr-scanner": "1.4.2"
52
52
  },
53
53
  "peerDependencies": {
54
- "@k2b/ssr": "^0.12.0 || ^0.13.0 || ^0.14.0 || ^0.15.0",
54
+ "@k2b/ssr": "^0.12.0 || ^0.13.0 || ^0.14.0 || ^0.15.0 || ^0.16.0",
55
55
  "solid-js": "^1.9.10"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@babel/core": "8.0.6",
59
59
  "@babel/preset-typescript": "8.0.1",
60
- "@k2b/ssr": "0.15.0",
60
+ "@k2b/ssr": "0.16.0",
61
61
  "@types/babel__core": "7.20.5",
62
62
  "@types/bun": "1.4.2",
63
63
  "axe-core": "4.11.0",