@crewlethq/ui 0.12.0 → 0.13.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 (157) hide show
  1. package/README.md +66 -5
  2. package/dist/AppShell/index.js +2 -1
  3. package/dist/Avatar/index.js +1 -1
  4. package/dist/{Avatar-QHYOFID3.css → Avatar-BPJ36QZR.css} +1 -1
  5. package/dist/AvatarPicker/index.js +6 -6
  6. package/dist/Breadcrumb/Breadcrumb.d.ts +68 -0
  7. package/dist/Breadcrumb/index.d.ts +3 -0
  8. package/dist/Breadcrumb/index.js +3 -0
  9. package/dist/Breadcrumb-YMWVM3SV.css +193 -0
  10. package/dist/ChoiceButtons/ChoiceButtons.d.ts +43 -0
  11. package/dist/ChoiceButtons/index.d.ts +3 -0
  12. package/dist/ChoiceButtons/index.js +3 -0
  13. package/dist/ChoiceButtons-DJ5EOGUA.css +127 -0
  14. package/dist/Combobox/index.js +2 -2
  15. package/dist/CommandPalette/CommandPalette.d.ts +48 -1
  16. package/dist/CommandPalette/index.js +3 -3
  17. package/dist/{CommandPalette-C5AMKGN2.css → CommandPalette-HBTNKHZQ.css} +55 -2
  18. package/dist/DataTable/index.js +4 -4
  19. package/dist/DataView/index.js +11 -11
  20. package/dist/DateTimePicker/index.js +2 -2
  21. package/dist/Document/Document.d.ts +56 -0
  22. package/dist/Document/index.d.ts +3 -0
  23. package/dist/Document/index.js +2 -0
  24. package/dist/Document-PQGXJHB7.css +288 -0
  25. package/dist/EntityChip/index.js +1 -1
  26. package/dist/Highlight/Highlight.d.ts +45 -0
  27. package/dist/Highlight/index.d.ts +3 -0
  28. package/dist/Highlight/index.js +2 -0
  29. package/dist/Highlight-DXLV2R6L.css +29 -0
  30. package/dist/HuePicker/index.js +3 -3
  31. package/dist/ImageUpload/index.js +2 -2
  32. package/dist/{ImageUpload-L2GE4JUM.css → ImageUpload-NVGMN7DP.css} +9 -6
  33. package/dist/InboxList/InboxList.d.ts +116 -0
  34. package/dist/InboxList/index.d.ts +3 -0
  35. package/dist/InboxList/index.js +5 -0
  36. package/dist/InboxList-YMFWKGGS.css +252 -0
  37. package/dist/KeyChip/KeyChip.d.ts +21 -0
  38. package/dist/KeyChip/index.d.ts +3 -0
  39. package/dist/KeyChip/index.js +2 -0
  40. package/dist/KeyChip-4XJU4BBE.css +30 -0
  41. package/dist/Link/Link.d.ts +17 -2
  42. package/dist/Link/index.js +1 -1
  43. package/dist/{Link-6BEFNMN2.css → Link-WPMVLKLY.css} +36 -1
  44. package/dist/ListInput/index.js +2 -2
  45. package/dist/Listbox/index.d.ts +2 -0
  46. package/dist/Listbox/index.js +1 -1
  47. package/dist/Listbox/useHighlightRest.d.ts +35 -0
  48. package/dist/MarkdownEditor/MarkdownEditor.d.ts +93 -0
  49. package/dist/MarkdownEditor/format.d.ts +34 -0
  50. package/dist/MarkdownEditor/index.d.ts +5 -0
  51. package/dist/MarkdownEditor/index.js +12 -0
  52. package/dist/MarkdownEditor-ZLSHTOIZ.css +146 -0
  53. package/dist/Modal/Modal.d.ts +5 -1
  54. package/dist/Modal/index.js +1 -1
  55. package/dist/{Modal-BNT3TDV2.css → Modal-3YJ2GG2T.css} +33 -0
  56. package/dist/OrgLabel/index.js +1 -1
  57. package/dist/OrgNode/index.js +1 -1
  58. package/dist/OrgTable/index.js +5 -5
  59. package/dist/Outline/Outline.d.ts +72 -0
  60. package/dist/Outline/index.d.ts +3 -0
  61. package/dist/Outline/index.js +2 -0
  62. package/dist/Outline-VCXKKU3E.css +78 -0
  63. package/dist/Popover/Popover.d.ts +21 -1
  64. package/dist/Popover/index.js +1 -1
  65. package/dist/ReadingPane/ReadingPane.d.ts +95 -0
  66. package/dist/ReadingPane/index.d.ts +3 -0
  67. package/dist/ReadingPane/index.js +4 -0
  68. package/dist/ReadingPane-5UOLPWY5.css +194 -0
  69. package/dist/SegmentedControl/SegmentedControl.d.ts +9 -1
  70. package/dist/SegmentedControl/index.js +3 -3
  71. package/dist/{SegmentedControl-76HODRBT.css → SegmentedControl-PKBLJVSA.css} +18 -0
  72. package/dist/Select/Select.d.ts +22 -0
  73. package/dist/Select/index.js +2 -2
  74. package/dist/{Select-4ANVLHUY.css → Select-XMZ44RWY.css} +24 -0
  75. package/dist/SidebarNav/index.js +2 -1
  76. package/dist/{SidebarNav-X5NLZNWA.css → SidebarNav-KF66MLOM.css} +4 -19
  77. package/dist/Switcher/Switcher.d.ts +151 -0
  78. package/dist/Switcher/index.d.ts +3 -0
  79. package/dist/Switcher/index.js +16 -0
  80. package/dist/Switcher-B44Q4WF4.css +346 -0
  81. package/dist/Tabs/Tabs.d.ts +7 -1
  82. package/dist/Tabs/index.js +1 -1
  83. package/dist/{Tabs-5I5Q5KKM.css → Tabs-ITJYJFMU.css} +49 -0
  84. package/dist/TagsInput/index.js +3 -3
  85. package/dist/ThemeGallery/ThemeGallery.d.ts +65 -0
  86. package/dist/ThemeGallery/index.d.ts +3 -0
  87. package/dist/ThemeGallery/index.js +6 -0
  88. package/dist/ThemeGallery-NITASULQ.css +93 -0
  89. package/dist/ThemeSwatch/ThemeSwatch.d.ts +71 -0
  90. package/dist/ThemeSwatch/index.d.ts +3 -0
  91. package/dist/ThemeSwatch/index.js +2 -0
  92. package/dist/ThemeSwatch-4DL457ZB.css +256 -0
  93. package/dist/ThemeSwitcher/ThemeSwitcher.d.ts +5 -1
  94. package/dist/ThemeSwitcher/index.js +4 -4
  95. package/dist/ThemeToggle/ThemeToggle.d.ts +1 -1
  96. package/dist/ThemeToggle/index.js +1 -1
  97. package/dist/TimeWindowPicker/index.js +4 -4
  98. package/dist/Toaster/index.js +1 -1
  99. package/dist/{Toaster-NVDCEIP5.css → Toaster-KZ7YE2HA.css} +1 -0
  100. package/dist/Tree/index.d.ts +1 -1
  101. package/dist/Tree/index.js +1 -1
  102. package/dist/Tree/useTreeState.d.ts +37 -7
  103. package/dist/TreeCanvas/index.js +2 -2
  104. package/dist/TreeGrid/TreeGrid.d.ts +22 -2
  105. package/dist/TreeGrid/index.js +2 -2
  106. package/dist/{TreeGrid-NSW7VMOX.css → TreeGrid-FBX3MSJA.css} +19 -0
  107. package/dist/{chunk-EBBAAQDY.js → chunk-26PEPONN.js} +3 -1
  108. package/dist/{chunk-HV6IZFBK.js → chunk-4FFHJBEN.js} +2 -2
  109. package/dist/{chunk-JHQUT4WJ.js → chunk-4LDTQWS7.js} +1 -1
  110. package/dist/{chunk-GXYNEDNA.js → chunk-4Y7WKXAW.js} +1 -1
  111. package/dist/{chunk-MCPKHYMC.js → chunk-6LXMLQUM.js} +17 -4
  112. package/dist/{chunk-3UK4VFSK.js → chunk-6NIZCQUM.js} +1 -1
  113. package/dist/{chunk-ORNOOMVY.js → chunk-6TSZCBID.js} +2 -2
  114. package/dist/{chunk-ZMJHK7DR.js → chunk-75WOCYGC.js} +2 -2
  115. package/dist/chunk-77IEHFY4.js +299 -0
  116. package/dist/chunk-A5YKNRG6.js +94 -0
  117. package/dist/{chunk-HLBRPES3.js → chunk-B2CITO6R.js} +2 -2
  118. package/dist/{chunk-TEEJSTFG.js → chunk-CF6DTETT.js} +1 -1
  119. package/dist/{chunk-LAQK4V3Z.js → chunk-DJMLHCLD.js} +1 -1
  120. package/dist/{chunk-6MU7HNB4.js → chunk-F73MC7EZ.js} +47 -2
  121. package/dist/{chunk-ZPSOF6VL.js → chunk-FBSEJO2C.js} +1 -1
  122. package/dist/chunk-FYTIJM2T.js +40 -0
  123. package/dist/{chunk-ZHOM65MI.js → chunk-GG2QEZO2.js} +2 -2
  124. package/dist/chunk-H6VKCIWV.js +41 -0
  125. package/dist/{chunk-XV65NTIT.js → chunk-HKGS67VG.js} +94 -41
  126. package/dist/chunk-IG75YMUN.js +22 -0
  127. package/dist/{chunk-JCNUQ3US.js → chunk-JDPAA2JU.js} +1 -1
  128. package/dist/chunk-KLIEPFEZ.js +95 -0
  129. package/dist/{chunk-7LD6P32I.js → chunk-L3CTFFLZ.js} +2 -18
  130. package/dist/{chunk-UG5ZMAXW.js → chunk-LELD5KPA.js} +1 -1
  131. package/dist/chunk-MNFU2RNT.js +74 -0
  132. package/dist/{chunk-S3BCVWTU.js → chunk-MY374UUD.js} +49 -31
  133. package/dist/{chunk-K5Q2DK3P.js → chunk-NXDEPUVG.js} +1 -1
  134. package/dist/{chunk-PDUZO35I.js → chunk-O2ZDZZS7.js} +15 -6
  135. package/dist/{chunk-5WEVLIB6.js → chunk-RZ7RGECB.js} +1 -1
  136. package/dist/chunk-S3IENQ3E.js +336 -0
  137. package/dist/{chunk-WEIINZPA.js → chunk-SBRE7IML.js} +6 -2
  138. package/dist/{chunk-IVFJD7WY.js → chunk-UCCC7YVZ.js} +3 -2
  139. package/dist/{chunk-IINFVK3W.js → chunk-UZPHPW3Z.js} +6 -6
  140. package/dist/chunk-VWNC2L6W.js +110 -0
  141. package/dist/chunk-VYY56AMX.js +2 -0
  142. package/dist/chunk-WI6K5M5X.js +24 -0
  143. package/dist/{chunk-GOUKOXJK.js → chunk-WY2NLRZN.js} +3 -3
  144. package/dist/{chunk-SEFMO2EV.js → chunk-XFE5W2I4.js} +44 -5
  145. package/dist/chunk-XYCADWZN.js +100 -0
  146. package/dist/chunk-YSJC7AZC.js +62 -0
  147. package/dist/chunk-ZAJHGDAW.js +93 -0
  148. package/dist/generated/index.d.ts +12 -0
  149. package/dist/generated/index.js +65 -52
  150. package/dist/index.js +65 -52
  151. package/dist/styles.css +2449 -161
  152. package/dist/utils/highlight.d.ts +17 -0
  153. package/dist/utils/useMediaMatch.d.ts +12 -0
  154. package/package.json +3 -3
  155. package/dist/chunk-UAQIUSSK.js +0 -2
  156. package/dist/{chunk-74OVQWA5.js → chunk-6AR2T5Y4.js} +0 -0
  157. package/dist/{chunk-GARACZAH.js → chunk-LZP7FGT7.js} +1 -1
@@ -0,0 +1,95 @@
1
+ import { type HTMLAttributes, type ReactNode } from 'react';
2
+ import { type HeadingLevel } from '../utils/headingLevel.js';
3
+ export interface ReadingPaneProps extends HTMLAttributes<HTMLElement> {
4
+ /** Overrides the level the title is rendered at. */
5
+ headingLevel?: HeadingLevel | undefined;
6
+ }
7
+ /**
8
+ * One item read in full, top to bottom, in one column: the line saying who is
9
+ * asking and about what, the question in large type, its context, the
10
+ * reasoning behind a recommendation, the answer, and the conversation.
11
+ *
12
+ * ONE COLUMN AND NOTHING TO OPEN. Every detail an item has is part of its
13
+ * reading, in the order a reader needs it, so nothing hides behind a toggle
14
+ * and nothing is said twice. The column is bounded to a reading measure and
15
+ * centred in whatever pane holds it, and it narrows its margins when the pane
16
+ * itself is narrow, measured on the pane rather than the window, because a
17
+ * pane beside a list is narrow on a wide screen too.
18
+ *
19
+ * The article is named by its title, so a reader moving by landmark hears the
20
+ * question rather than "article".
21
+ */
22
+ export declare function ReadingPane({ headingLevel, className, children, ...rest }: ReadingPaneProps): import("react").JSX.Element;
23
+ export declare namespace ReadingPane {
24
+ var Byline: typeof ReadingPaneByline;
25
+ var Title: typeof ReadingPaneTitle;
26
+ var Lead: typeof ReadingPaneLead;
27
+ var Quote: typeof ReadingPaneQuote;
28
+ var Reasoning: typeof ReadingPaneReasoning;
29
+ var Outcome: typeof ReadingPaneOutcome;
30
+ var Section: typeof ReadingPaneSection;
31
+ }
32
+ export interface ReadingPaneBylineProps extends HTMLAttributes<HTMLParagraphElement> {
33
+ /** A control at the start of the line: Back to the list, on a phone. */
34
+ start?: ReactNode;
35
+ /** Before the sentence: an avatar. */
36
+ leading?: ReactNode;
37
+ /**
38
+ * After the sentence, in the quiet ink: why it reached the reader, where the
39
+ * sentence does not already say so ("you follow this task").
40
+ */
41
+ note?: ReactNode;
42
+ }
43
+ /**
44
+ * The one sentence over the item: who, what is asked of the reader, and the
45
+ * task. Set the name in `strong` and the task as a quiet link. The time is
46
+ * not repeated here, because the row in the list already carries it.
47
+ */
48
+ export declare function ReadingPaneByline({ start, leading, note, className, children, ...rest }: ReadingPaneBylineProps): import("react").JSX.Element;
49
+ export type ReadingPaneTitleProps = HTMLAttributes<HTMLHeadingElement>;
50
+ /** The question, the stop or what changed, in large type. It names the pane. */
51
+ export declare function ReadingPaneTitle({ className, children, ...rest }: ReadingPaneTitleProps): import("react").JSX.Element;
52
+ export type ReadingPaneLeadProps = HTMLAttributes<HTMLDivElement>;
53
+ /**
54
+ * What the title needs to be understood: the context of a question, what a
55
+ * change adds to its own sentence. A block rather than a paragraph, so it can
56
+ * hold rendered markdown of more than one paragraph.
57
+ */
58
+ export declare function ReadingPaneLead({ className, children, ...rest }: ReadingPaneLeadProps): import("react").JSX.Element;
59
+ export interface ReadingPaneQuoteProps extends HTMLAttributes<HTMLQuoteElement> {
60
+ /**
61
+ * Words a machine wrote, verbatim: a coding run's question. Set in the mono
62
+ * face behind a rule, small, rather than as prose a person wrote.
63
+ */
64
+ verbatim?: boolean | undefined;
65
+ }
66
+ /** Somebody's own words, quoted whole: the comment a notice is about. */
67
+ export declare function ReadingPaneQuote({ verbatim, className, children, ...rest }: ReadingPaneQuoteProps): import("react").JSX.Element;
68
+ export interface ReadingPaneReasoningProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
69
+ /** Whose reasoning, and what it recommends: "Crewlet-PM recommends **Accept**". */
70
+ title: ReactNode;
71
+ /** Under the reasoning: the evidence it rests on. */
72
+ footer?: ReactNode;
73
+ }
74
+ /**
75
+ * Why the asker recommends what it does, on an inset ground so it reads as an
76
+ * aside to the question rather than part of it, with the evidence it cites
77
+ * underneath.
78
+ */
79
+ export declare function ReadingPaneReasoning({ title, footer, className, children, ...rest }: ReadingPaneReasoningProps): import("react").JSX.Element;
80
+ export type ReadingPaneOutcomeProps = HTMLAttributes<HTMLParagraphElement>;
81
+ /**
82
+ * What the reader's action did, in place of the controls that did it:
83
+ * "Answered **Accept**". A live region, so the line is announced when it
84
+ * replaces the button that was just pressed.
85
+ */
86
+ export declare function ReadingPaneOutcome({ className, children, ...rest }: ReadingPaneOutcomeProps): import("react").JSX.Element;
87
+ export interface ReadingPaneSectionProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
88
+ /** What is below it, said exactly: "Replies to this question". */
89
+ label: ReactNode;
90
+ }
91
+ /**
92
+ * A part of the reading after the answer, the conversation most of all, set
93
+ * off by a hairline and named by a heading in the micro-label register.
94
+ */
95
+ export declare function ReadingPaneSection({ label, className, children, ...rest }: ReadingPaneSectionProps): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import './ReadingPane.css';
2
+ export { ReadingPane, ReadingPaneByline, ReadingPaneTitle, ReadingPaneLead, ReadingPaneQuote, ReadingPaneReasoning, ReadingPaneOutcome, ReadingPaneSection, } from './ReadingPane.js';
3
+ export type { ReadingPaneProps, ReadingPaneBylineProps, ReadingPaneTitleProps, ReadingPaneLeadProps, ReadingPaneQuoteProps, ReadingPaneReasoningProps, ReadingPaneOutcomeProps, ReadingPaneSectionProps, } from './ReadingPane.js';
@@ -0,0 +1,4 @@
1
+ export { ReadingPane, ReadingPaneByline, ReadingPaneLead, ReadingPaneOutcome, ReadingPaneQuote, ReadingPaneReasoning, ReadingPaneSection, ReadingPaneTitle } from '../chunk-ZAJHGDAW.js';
2
+ import '../chunk-RK4XPHVG.js';
3
+ import '../chunk-PQADV6P6.js';
4
+ import '../chunk-ODEQTPFM.js';
@@ -0,0 +1,194 @@
1
+ /*
2
+ * One item read in full, in one column.
3
+ *
4
+ * The pane is its own container, so the column narrows its margins when the
5
+ * PANE is narrow (beside a list on a small laptop, or alone on a phone)
6
+ * rather than when the window is.
7
+ */
8
+
9
+ .crewlet-reading-pane {
10
+ container: crewlet-reading-pane / inline-size;
11
+ min-width: 0;
12
+ }
13
+
14
+ .crewlet-reading-pane__column {
15
+ /* A question and its answers read best at about seventy characters a line. */
16
+ --crewlet-reading-pane-measure: 640px;
17
+
18
+ display: grid;
19
+ grid-template-columns: minmax(0, 1fr);
20
+ gap: calc(var(--spacing-4) + var(--spacing-1) / 2);
21
+ max-width: var(--crewlet-reading-pane-measure);
22
+ margin: 0 auto;
23
+ padding: calc(var(--spacing-6) + var(--spacing-1)) calc(var(--spacing-6) + var(--spacing-1)) var(--spacing-8);
24
+ font-size: var(--font-size-compact);
25
+ line-height: var(--font-line-height-body);
26
+ color: var(--color-text-primary);
27
+ }
28
+
29
+ @container crewlet-reading-pane (width < 640px) {
30
+ .crewlet-reading-pane__column {
31
+ padding-inline: var(--spacing-4);
32
+ }
33
+ }
34
+
35
+ /* ---- The byline -------------------------------------------------------- */
36
+
37
+ .crewlet-reading-pane__byline {
38
+ display: flex;
39
+ align-items: center;
40
+ gap: var(--spacing-2);
41
+ min-width: 0;
42
+ margin: 0;
43
+ color: var(--color-text-tertiary);
44
+ }
45
+
46
+ .crewlet-reading-pane__start,
47
+ .crewlet-reading-pane__leading {
48
+ display: inline-flex;
49
+ flex: none;
50
+ align-items: center;
51
+ }
52
+
53
+ .crewlet-reading-pane__by {
54
+ min-width: 0;
55
+ overflow-wrap: anywhere;
56
+ color: var(--color-text-secondary);
57
+ }
58
+
59
+ .crewlet-reading-pane__by strong {
60
+ font-weight: var(--font-weight-medium);
61
+ color: var(--color-text-primary);
62
+ }
63
+
64
+ .crewlet-reading-pane__note {
65
+ color: var(--color-text-tertiary);
66
+ }
67
+
68
+ /* ---- The title and what it needs -------------------------------------- */
69
+
70
+ .crewlet-reading-pane__title {
71
+ margin: 0;
72
+ font-size: var(--font-size-2xl);
73
+ font-weight: var(--font-weight-semibold);
74
+ line-height: var(--font-line-height-tight);
75
+ letter-spacing: var(--font-letter-spacing-snug);
76
+ text-wrap: balance;
77
+ overflow-wrap: anywhere;
78
+ color: var(--color-text-primary);
79
+ }
80
+
81
+ .crewlet-reading-pane__lead {
82
+ display: grid;
83
+ gap: var(--spacing-2);
84
+ min-width: 0;
85
+ font-size: var(--font-size-sm);
86
+ line-height: var(--font-line-height-normal);
87
+ overflow-wrap: anywhere;
88
+ color: var(--color-text-secondary);
89
+ }
90
+
91
+ .crewlet-reading-pane__lead > * {
92
+ margin: 0;
93
+ }
94
+
95
+ .crewlet-reading-pane__quote {
96
+ display: grid;
97
+ gap: var(--spacing-2);
98
+ min-width: 0;
99
+ margin: 0;
100
+ font-size: var(--font-size-md);
101
+ line-height: var(--font-line-height-normal);
102
+ overflow-wrap: anywhere;
103
+ color: var(--color-text-primary);
104
+ }
105
+
106
+ .crewlet-reading-pane__quote > * {
107
+ margin: 0;
108
+ }
109
+
110
+ .crewlet-reading-pane__quote--verbatim {
111
+ padding: var(--spacing-2) var(--spacing-3);
112
+ border-left: 2px solid var(--color-border-strong);
113
+ font-family: var(--font-family-mono);
114
+ font-size: var(--font-size-xs);
115
+ white-space: pre-wrap;
116
+ }
117
+
118
+ /* ---- The reasoning ----------------------------------------------------- */
119
+
120
+ .crewlet-reading-pane__reasoning {
121
+ display: grid;
122
+ gap: var(--spacing-1);
123
+ min-width: 0;
124
+ padding: var(--spacing-3) calc(var(--spacing-3) + var(--spacing-1) / 2);
125
+ border-radius: var(--radius-md);
126
+ background: var(--color-surface-inset);
127
+ }
128
+
129
+ .crewlet-reading-pane__reasoning-title {
130
+ margin: 0;
131
+ font-size: var(--font-size-xs);
132
+ color: var(--color-text-tertiary);
133
+ }
134
+
135
+ .crewlet-reading-pane__reasoning-title strong {
136
+ font-weight: var(--font-weight-semibold);
137
+ color: var(--color-text-primary);
138
+ }
139
+
140
+ .crewlet-reading-pane__reasoning-body {
141
+ display: grid;
142
+ gap: var(--spacing-2);
143
+ min-width: 0;
144
+ overflow-wrap: anywhere;
145
+ color: var(--color-text-secondary);
146
+ }
147
+
148
+ .crewlet-reading-pane__reasoning-body > * {
149
+ margin: 0;
150
+ }
151
+
152
+ .crewlet-reading-pane__reasoning-footer {
153
+ margin-top: calc(var(--spacing-1) / 2);
154
+ }
155
+
156
+ /* ---- What the reader did ----------------------------------------------- */
157
+
158
+ .crewlet-reading-pane__outcome {
159
+ display: flex;
160
+ align-items: center;
161
+ gap: var(--spacing-2);
162
+ min-width: 0;
163
+ margin: 0;
164
+ font-size: var(--font-size-xs);
165
+ overflow-wrap: anywhere;
166
+ color: var(--color-feedback-success-ink);
167
+ }
168
+
169
+ .crewlet-reading-pane__outcome-mark {
170
+ flex: none;
171
+ }
172
+
173
+ .crewlet-reading-pane__outcome strong {
174
+ font-weight: var(--font-weight-medium);
175
+ color: var(--color-text-primary);
176
+ }
177
+
178
+ /* ---- A section after the answer ---------------------------------------- */
179
+
180
+ .crewlet-reading-pane__section {
181
+ display: grid;
182
+ grid-template-columns: minmax(0, 1fr);
183
+ gap: var(--spacing-3);
184
+ padding-top: calc(var(--spacing-4) + var(--spacing-1) / 2);
185
+ border-top: 1px solid var(--color-border-default);
186
+ }
187
+
188
+ /* The heading's own line box is the label's, so the label sits where it is drawn. */
189
+ .crewlet-reading-pane__section-label {
190
+ margin: 0;
191
+ font: inherit;
192
+ font-size: var(--font-size-2xs);
193
+ line-height: var(--font-line-height-snug);
194
+ }
@@ -45,6 +45,14 @@ interface SegmentedShared<T extends string> {
45
45
  * caret moves inside it as it does in any field.
46
46
  */
47
47
  trailing?: ReactNode | undefined;
48
+ /**
49
+ * Every option takes an equal share of the row, and the row fills the
50
+ * width it is given. Two settings drawn one above the other (Mode over
51
+ * Density) then draw one box, whatever their options say: a row sized to
52
+ * its own options draws a glyph row and a letter row at two widths, which
53
+ * reads as two kinds of control. Pill rows only.
54
+ */
55
+ fill?: boolean | undefined;
48
56
  className?: string | undefined;
49
57
  }
50
58
  /**
@@ -115,5 +123,5 @@ export type SegmentedControlProps<T extends string = string> = SegmentedShared<T
115
123
  * look like two different controls depending on which component a screen
116
124
  * reached for.
117
125
  */
118
- export declare function SegmentedControl<T extends string = string>({ label, options, value, onValueChange, size, layout, trailing, className, semantics, panelId, activate, activateHint, }: SegmentedControlProps<T>): import("react").JSX.Element;
126
+ export declare function SegmentedControl<T extends string = string>({ label, options, value, onValueChange, size, layout, trailing, fill, className, semantics, panelId, activate, activateHint, }: SegmentedControlProps<T>): import("react").JSX.Element;
119
127
  export {};
@@ -1,6 +1,6 @@
1
- import '../chunk-UAQIUSSK.js';
2
- export { SegmentedControl } from '../chunk-EBBAAQDY.js';
3
- import '../chunk-JHQUT4WJ.js';
1
+ import '../chunk-VYY56AMX.js';
2
+ export { SegmentedControl } from '../chunk-26PEPONN.js';
3
+ import '../chunk-4LDTQWS7.js';
4
4
  import '../chunk-CBOICT64.js';
5
5
  import '../chunk-BHHIIK3M.js';
6
6
  import '../chunk-BZFWDIV6.js';
@@ -158,3 +158,21 @@
158
158
  .crewlet-segmented--cards .crewlet-segmented__option.is-active .crewlet-segmented__description {
159
159
  color: var(--color-brand-accent-ink);
160
160
  }
161
+
162
+ /*
163
+ * EQUAL SHARES. The row fills the width it is given and every option takes
164
+ * an equal column of it, so two settings stacked in one panel draw one box.
165
+ * Two classes, for the reason the card row gives: the pill's own rules size
166
+ * the row to its content.
167
+ */
168
+ .crewlet-tabs.crewlet-segmented--fill {
169
+ display: grid;
170
+ grid-auto-flow: column;
171
+ grid-auto-columns: minmax(0, 1fr);
172
+ width: 100%;
173
+ }
174
+
175
+ .crewlet-segmented--fill .crewlet-segmented__option {
176
+ justify-content: center;
177
+ min-width: 0;
178
+ }
@@ -42,6 +42,19 @@ export interface SelectOption {
42
42
  label: ReactNode;
43
43
  /** A second line under the label: a handle, a path, what the choice means. */
44
44
  description?: ReactNode;
45
+ /**
46
+ * Drawn before the label, in the list and on the trigger while the option is
47
+ * the one chosen: a swatch, an avatar, a glyph. Decorative, so it is hidden
48
+ * from assistive technology: the label carries the words. Listbox mode only;
49
+ * a native option draws text alone.
50
+ */
51
+ leading?: ReactNode;
52
+ /**
53
+ * A quieter word on the label's own line, at the row's end: a tag, a count,
54
+ * the one fact that tells two options apart at a glance. Read with the
55
+ * label. Listbox mode only.
56
+ */
57
+ hint?: ReactNode;
45
58
  disabled?: boolean;
46
59
  /** Options sharing a group are listed under its name, in first-seen order. */
47
60
  group?: string;
@@ -126,6 +139,15 @@ export interface SelectProps extends NativePassthrough {
126
139
  renderMultiLabel?: (selected: SelectOption[]) => ReactNode;
127
140
  /** The line shown when a search matches nothing. */
128
141
  emptyMessage?: string;
142
+ /**
143
+ * Told where the highlight COMES TO REST while the list is open, and `null`
144
+ * when it closes or the pointer leaves it: at once for a key, and once the
145
+ * pointer has rested on a row for `HIGHLIGHT_REST_MS`. What a list that
146
+ * previews its options listens to, so a pointer crossing the list does not
147
+ * preview every row it passed. Told the chosen row as the list opens.
148
+ * Listbox mode only.
149
+ */
150
+ onHighlight?: ((option: SelectOption | null) => void) | undefined;
129
151
  }
130
152
  /**
131
153
  * A picker over a known set of values.
@@ -1,5 +1,5 @@
1
- export { Select } from '../chunk-SEFMO2EV.js';
2
- import '../chunk-6MU7HNB4.js';
1
+ export { Select } from '../chunk-XFE5W2I4.js';
2
+ import '../chunk-F73MC7EZ.js';
3
3
  import '../chunk-7RPGY3JE.js';
4
4
  import '../chunk-R25RGPUB.js';
5
5
  import '../chunk-ODEQTPFM.js';
@@ -297,6 +297,30 @@ svg.crewlet-select__chevron {
297
297
  min-width: 0;
298
298
  }
299
299
 
300
+ /*
301
+ * WHAT AN OPTION DRAWS BEFORE ITS LABEL (a swatch, an avatar, a glyph),
302
+ * centred on the label's first line rather than on the row, so a row with a
303
+ * second line keeps its mark beside the words it belongs to. The same slot on
304
+ * the trigger, while that option is the one chosen, sits on the value's line.
305
+ */
306
+ .crewlet-select__option-leading,
307
+ .crewlet-select__leading {
308
+ display: inline-flex;
309
+ align-items: center;
310
+ flex: none;
311
+ }
312
+
313
+ .crewlet-select__option-leading {
314
+ min-height: calc(var(--font-line-height-normal) * 1em);
315
+ }
316
+
317
+ /* A hint ends the row's FIRST line, on the label's baseline, rather than
318
+ sitting on the row's top edge at its own smaller size. */
319
+ .crewlet-select__option:has(> .crewlet-listbox__hint) .crewlet-select__option-body,
320
+ .crewlet-select__option > .crewlet-listbox__hint {
321
+ align-self: baseline;
322
+ }
323
+
300
324
  /*
301
325
  * ONE LINE, WHICH IS WHAT THE ELLIPSIS BELOW WAS ALWAYS FOR. `overflow:
302
326
  * hidden` clips what leaves the box and `text-overflow` replaces what a LINE
@@ -1,3 +1,4 @@
1
- export { NavGroup, NavItem, SidebarNav } from '../chunk-IVFJD7WY.js';
1
+ export { NavGroup, NavItem, SidebarNav } from '../chunk-UCCC7YVZ.js';
2
+ import '../chunk-FYTIJM2T.js';
2
3
  import '../chunk-BZFWDIV6.js';
3
4
  import '../chunk-ODEQTPFM.js';
@@ -263,26 +263,11 @@
263
263
 
264
264
  /*
265
265
  * A PROJECT'S KEY, as a chip in the glyph's place: the prefix every item in
266
- * the project is filed under, in mono so ENG and PROD line up by letter. It
267
- * is the raised rung inside the plain hairline, in the secondary ink, which
268
- * the palette suite measures on every ground a row can have; on the reader's
269
- * own row, which is raised too, the hairline is what draws it.
266
+ * the project is filed under, in mono so ENG and PROD line up by letter. The
267
+ * chip is the kit's `KeyChip` (KeyChip.css); the suite below measures its ink
268
+ * on every ground a row can have, and on the reader's own row, which is raised
269
+ * too, its hairline is what draws it.
270
270
  */
271
- .crewlet-nav-item__lead {
272
- display: inline-flex;
273
- align-items: center;
274
- flex: none;
275
- padding: 0 calc(var(--spacing-1) + 1px);
276
- border: 1px solid var(--color-border-default);
277
- border-radius: var(--radius-xs);
278
- background: var(--color-surface-elevated);
279
- color: var(--color-text-secondary);
280
- font-family: var(--font-family-mono);
281
- font-size: var(--font-size-2xs);
282
- font-weight: var(--font-weight-medium);
283
- letter-spacing: var(--font-letter-spacing-normal);
284
- line-height: var(--font-line-height-body);
285
- }
286
271
 
287
272
  /*
288
273
  * THE COUNT: how many of something the destination holds, as a quiet figure
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Moving a page to another subject of the same kind: one project for another,
3
+ * or for all of them.
4
+ *
5
+ * # One panel, three places
6
+ *
7
+ * ANCHORED under its button where the page names its subject, which is a
8
+ * breadcrumb's heading (`Breadcrumb`'s `current`): the reader changes the
9
+ * subject where the subject is named. CENTRED over the page when it is opened
10
+ * by a key from a page with no such button, and nothing behind it moves until
11
+ * a row is chosen. A SHEET from the bottom edge below the phone breakpoint,
12
+ * whichever of the two it would otherwise be, because a thumb reaches the
13
+ * bottom of a phone and a panel hung from a heading at the top of one leaves
14
+ * no room for the keyboard.
15
+ *
16
+ * # It is a combobox in a dialog
17
+ *
18
+ * Focus stays in the search field and the arrows move a highlight through the
19
+ * rows, which the field names with `aria-activedescendant`, so a screen reader
20
+ * hears each row as it is reached. The rows are options in ONE listbox: the
21
+ * pinned row, the rows a message offers, the groups, and the footer's actions,
22
+ * which sit in their own band below the scrolling list and are owned by the
23
+ * listbox (`aria-owns`) so the arrows walk into them without a second list.
24
+ *
25
+ * # Every row that goes somewhere is a link
26
+ *
27
+ * A row with an `href` is an anchor, so a middle click and a Command or Control
28
+ * click open it in a new tab as every link does, and Command or Control with
29
+ * Enter does the same from the keyboard. The panel stays open for all three:
30
+ * the reader asked for another tab, not to leave this one.
31
+ *
32
+ * # A held row stays, with its reason
33
+ *
34
+ * A row the reader cannot take right now (New project, for a viewer without
35
+ * the credential) is drawn with the reason at its end and passed over by the
36
+ * arrows. A row that vanished would be one the reader could not know exists.
37
+ *
38
+ * # Leaving it
39
+ *
40
+ * Escape closes it and puts focus back on its button. Tab from the anchored
41
+ * panel closes it and carries on to whatever follows the button, which is
42
+ * what Tab from the button would have reached; a centred panel or a sheet is a
43
+ * modal surface and keeps Tab inside. Taking a row puts focus back on the
44
+ * button, which is the page's heading, so the reader stays on the name of the
45
+ * place they just moved to.
46
+ *
47
+ * IT KNOWS NOTHING ABOUT PROJECTS. The caller searches, ranks and groups, and
48
+ * hands over rows and the words around them; this owns the surface, the keys,
49
+ * and how a screen reader hears it.
50
+ */
51
+ import { type ReactNode } from 'react';
52
+ /** Where the panel opens. Derived, never asked for: see the component doc. */
53
+ export type SwitcherPlacement = 'anchored' | 'centered' | 'sheet';
54
+ export interface SwitcherOption {
55
+ /** Stable across a re-query: it keys the row and names its option element. */
56
+ id: string;
57
+ /** The row's words. Plain text, so a search's letters can be drawn bold in it. */
58
+ label: string;
59
+ /** A project's key, drawn as a `KeyChip` in the lead column. */
60
+ keyChip?: string | undefined;
61
+ /** A glyph in the lead column, for a row that is not a project. Decorative. */
62
+ icon?: ReactNode;
63
+ /** A short figure at the row's end, in the quiet ink: a project's open count. */
64
+ meta?: ReactNode;
65
+ /**
66
+ * What a screen reader calls the row where its words alone do not say it:
67
+ * "Product and Engineering, FAIR, 4 open" rather than a name followed by a
68
+ * bare figure.
69
+ */
70
+ accessibleLabel?: string | undefined;
71
+ /**
72
+ * Where the row goes. A row with one is a link: a middle click, a Command or
73
+ * Control click, and Command or Control with Enter open it in a new tab.
74
+ */
75
+ href?: string | undefined;
76
+ /** The subject the page is on now: outlined in the accent, and `aria-current="page"`. */
77
+ current?: boolean | undefined;
78
+ /** Why the row cannot be taken right now. Drawn at its end; the arrows pass over it. */
79
+ held?: string | undefined;
80
+ /** Taking the row. Without one, a row with an `href` follows it. */
81
+ onSelect?: (() => void) | undefined;
82
+ /**
83
+ * Taking the row leaves the panel open: an action on the list itself, such
84
+ * as asking for it again after it did not load, where closing would take
85
+ * the answer away from the reader who asked for it.
86
+ */
87
+ keepsOpen?: boolean | undefined;
88
+ }
89
+ export interface SwitcherGroup {
90
+ id: string;
91
+ /** The heading over the group, and the name a screen reader gives it. */
92
+ label: string;
93
+ /** A figure at the heading's end: how many rows the group holds. */
94
+ count?: number | undefined;
95
+ options: SwitcherOption[];
96
+ }
97
+ /**
98
+ * A state the list is in, said in the panel: nothing matches, nothing loaded,
99
+ * nothing exists yet. Its actions are rows, where the arrows reach them.
100
+ */
101
+ export interface SwitcherMessage {
102
+ title: string;
103
+ body?: string | undefined;
104
+ actions?: SwitcherOption[] | undefined;
105
+ }
106
+ /** The button the panel opens from, drawn as the page's own name. */
107
+ export interface SwitcherTrigger {
108
+ /** The subject's name. */
109
+ label: string;
110
+ /** Its key, drawn as a `KeyChip` before the name. */
111
+ keyChip?: string | undefined;
112
+ /** Drawn after the name: a `Tag` saying the subject is archived. */
113
+ tag?: ReactNode;
114
+ /** The name in the mono face: an identifier still waiting for its name. */
115
+ mono?: boolean | undefined;
116
+ /** The tooltip: what the button does and the key that does it from anywhere. */
117
+ title?: string | undefined;
118
+ }
119
+ export interface SwitcherProps {
120
+ /** Names the panel, "Switch project"; a sheet draws it as its title. */
121
+ label: string;
122
+ open: boolean;
123
+ onOpenChange: (open: boolean) => void;
124
+ /**
125
+ * The button the panel hangs from, drawn where the switcher is rendered.
126
+ * Without one the panel opens centred over the page.
127
+ */
128
+ trigger?: SwitcherTrigger | undefined;
129
+ query: string;
130
+ onQueryChange: (query: string) => void;
131
+ /** The field's placeholder, and its name: "Find a project". */
132
+ placeholder?: string | undefined;
133
+ /** Names the list of rows: "Projects". */
134
+ listLabel?: string | undefined;
135
+ /** The row that is always first and never matched: "All projects". */
136
+ pinned?: SwitcherOption | undefined;
137
+ /** A line about the list itself, under the pinned row: "200 of 340 listed." */
138
+ note?: string | undefined;
139
+ message?: SwitcherMessage | undefined;
140
+ groups?: SwitcherGroup[] | undefined;
141
+ /** Actions in a band under the list that does not scroll: "Browse all projects". */
142
+ footer?: SwitcherOption[] | undefined;
143
+ /** Placeholder rows in place of the groups, while the rows are on their way. */
144
+ loading?: boolean | undefined;
145
+ /** What a screen reader is told while loading: "Loading projects". */
146
+ loadingLabel?: string | undefined;
147
+ /** Said politely whenever it changes: "3 projects". */
148
+ announcement?: string | undefined;
149
+ className?: string | undefined;
150
+ }
151
+ export declare function Switcher({ label, open, onOpenChange, trigger, className, ...panel }: SwitcherProps): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import './Switcher.css';
2
+ export { Switcher } from './Switcher.js';
3
+ export type { SwitcherGroup, SwitcherMessage, SwitcherOption, SwitcherPlacement, SwitcherProps, SwitcherTrigger, } from './Switcher.js';
@@ -0,0 +1,16 @@
1
+ export { Switcher } from '../chunk-S3IENQ3E.js';
2
+ import '../chunk-W5J7R5EB.js';
3
+ import '../chunk-CF6DTETT.js';
4
+ import '../chunk-F73MC7EZ.js';
5
+ import '../chunk-FTEJPHBI.js';
6
+ import '../chunk-FYTIJM2T.js';
7
+ import '../chunk-OG6CL3EB.js';
8
+ import '../chunk-PQADV6P6.js';
9
+ import '../chunk-IG75YMUN.js';
10
+ import '../chunk-4FQT6ZAY.js';
11
+ import '../chunk-RSAQOKH3.js';
12
+ import '../chunk-O2ZDZZS7.js';
13
+ import '../chunk-7RPGY3JE.js';
14
+ import '../chunk-R25RGPUB.js';
15
+ import '../chunk-BZFWDIV6.js';
16
+ import '../chunk-ODEQTPFM.js';