@crewlethq/ui 0.11.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.
- package/README.md +76 -5
- package/dist/AppShell/index.js +2 -1
- package/dist/Avatar/index.js +1 -1
- package/dist/{Avatar-QHYOFID3.css → Avatar-BPJ36QZR.css} +1 -1
- package/dist/AvatarPicker/index.js +6 -6
- package/dist/Breadcrumb/Breadcrumb.d.ts +68 -0
- package/dist/Breadcrumb/index.d.ts +3 -0
- package/dist/Breadcrumb/index.js +3 -0
- package/dist/Breadcrumb-YMWVM3SV.css +193 -0
- package/dist/ChoiceButtons/ChoiceButtons.d.ts +43 -0
- package/dist/ChoiceButtons/index.d.ts +3 -0
- package/dist/ChoiceButtons/index.js +3 -0
- package/dist/ChoiceButtons-DJ5EOGUA.css +127 -0
- package/dist/ChoiceList/ChoiceList.d.ts +45 -0
- package/dist/ChoiceList/index.d.ts +3 -0
- package/dist/ChoiceList/index.js +2 -0
- package/dist/ChoiceList-2PQJS4DX.css +109 -0
- package/dist/Combobox/index.js +2 -2
- package/dist/CommandPalette/CommandPalette.d.ts +48 -1
- package/dist/CommandPalette/index.js +3 -3
- package/dist/{CommandPalette-C5AMKGN2.css → CommandPalette-HBTNKHZQ.css} +55 -2
- package/dist/Composer/Composer.d.ts +27 -0
- package/dist/Composer/index.d.ts +3 -0
- package/dist/Composer/index.js +7 -0
- package/dist/Composer-ABGJIAIR.css +88 -0
- package/dist/DataTable/index.js +3 -3
- package/dist/DataView/index.js +11 -11
- package/dist/DateTimePicker/index.js +2 -2
- package/dist/Document/Document.d.ts +56 -0
- package/dist/Document/index.d.ts +3 -0
- package/dist/Document/index.js +2 -0
- package/dist/Document-PQGXJHB7.css +288 -0
- package/dist/EntityChip/index.js +1 -1
- package/dist/Highlight/Highlight.d.ts +45 -0
- package/dist/Highlight/index.d.ts +3 -0
- package/dist/Highlight/index.js +2 -0
- package/dist/Highlight-DXLV2R6L.css +29 -0
- package/dist/HuePicker/index.js +3 -3
- package/dist/ImageUpload/index.js +2 -2
- package/dist/{ImageUpload-L2GE4JUM.css → ImageUpload-NVGMN7DP.css} +9 -6
- package/dist/InboxList/InboxList.d.ts +116 -0
- package/dist/InboxList/index.d.ts +3 -0
- package/dist/InboxList/index.js +5 -0
- package/dist/InboxList-YMFWKGGS.css +252 -0
- package/dist/KeyChip/KeyChip.d.ts +21 -0
- package/dist/KeyChip/index.d.ts +3 -0
- package/dist/KeyChip/index.js +2 -0
- package/dist/KeyChip-4XJU4BBE.css +30 -0
- package/dist/Link/Link.d.ts +17 -2
- package/dist/Link/index.js +1 -1
- package/dist/{Link-6BEFNMN2.css → Link-WPMVLKLY.css} +36 -1
- package/dist/Listbox/index.d.ts +2 -0
- package/dist/Listbox/index.js +1 -1
- package/dist/Listbox/useHighlightRest.d.ts +35 -0
- package/dist/MarkdownEditor/MarkdownEditor.d.ts +93 -0
- package/dist/MarkdownEditor/format.d.ts +34 -0
- package/dist/MarkdownEditor/index.d.ts +5 -0
- package/dist/MarkdownEditor/index.js +12 -0
- package/dist/MarkdownEditor-ZLSHTOIZ.css +146 -0
- package/dist/Modal/Modal.d.ts +5 -1
- package/dist/Modal/index.js +1 -1
- package/dist/{Modal-BNT3TDV2.css → Modal-3YJ2GG2T.css} +33 -0
- package/dist/OrgLabel/index.js +1 -1
- package/dist/OrgNode/index.js +1 -1
- package/dist/OrgTable/index.js +5 -5
- package/dist/Outline/Outline.d.ts +72 -0
- package/dist/Outline/index.d.ts +3 -0
- package/dist/Outline/index.js +2 -0
- package/dist/Outline-VCXKKU3E.css +78 -0
- package/dist/Popover/Popover.d.ts +21 -1
- package/dist/Popover/index.js +1 -1
- package/dist/ReadingPane/ReadingPane.d.ts +95 -0
- package/dist/ReadingPane/index.d.ts +3 -0
- package/dist/ReadingPane/index.js +4 -0
- package/dist/ReadingPane-5UOLPWY5.css +194 -0
- package/dist/SegmentedControl/SegmentedControl.d.ts +9 -1
- package/dist/SegmentedControl/index.js +3 -3
- package/dist/{SegmentedControl-76HODRBT.css → SegmentedControl-PKBLJVSA.css} +18 -0
- package/dist/Select/Select.d.ts +22 -0
- package/dist/Select/index.js +2 -2
- package/dist/{Select-4ANVLHUY.css → Select-XMZ44RWY.css} +24 -0
- package/dist/SidebarNav/index.js +2 -1
- package/dist/{SidebarNav-X5NLZNWA.css → SidebarNav-KF66MLOM.css} +4 -19
- package/dist/Switcher/Switcher.d.ts +151 -0
- package/dist/Switcher/index.d.ts +3 -0
- package/dist/Switcher/index.js +16 -0
- package/dist/Switcher-B44Q4WF4.css +346 -0
- package/dist/Tabs/Tabs.d.ts +7 -1
- package/dist/Tabs/index.js +1 -1
- package/dist/{Tabs-5I5Q5KKM.css → Tabs-ITJYJFMU.css} +49 -0
- package/dist/TagsInput/index.js +2 -2
- package/dist/ThemeGallery/ThemeGallery.d.ts +65 -0
- package/dist/ThemeGallery/index.d.ts +3 -0
- package/dist/ThemeGallery/index.js +6 -0
- package/dist/ThemeGallery-NITASULQ.css +93 -0
- package/dist/ThemeSwatch/ThemeSwatch.d.ts +71 -0
- package/dist/ThemeSwatch/index.d.ts +3 -0
- package/dist/ThemeSwatch/index.js +2 -0
- package/dist/ThemeSwatch-4DL457ZB.css +256 -0
- package/dist/ThemeSwitcher/ThemeSwitcher.d.ts +5 -1
- package/dist/ThemeSwitcher/index.js +4 -4
- package/dist/ThemeToggle/ThemeToggle.d.ts +1 -1
- package/dist/ThemeToggle/index.js +1 -1
- package/dist/TimeWindowPicker/index.js +4 -4
- package/dist/Toaster/index.js +1 -1
- package/dist/{Toaster-NVDCEIP5.css → Toaster-KZ7YE2HA.css} +1 -0
- package/dist/Tree/index.d.ts +1 -1
- package/dist/Tree/index.js +1 -1
- package/dist/Tree/useTreeState.d.ts +37 -7
- package/dist/TreeCanvas/index.js +2 -2
- package/dist/TreeGrid/TreeGrid.d.ts +22 -2
- package/dist/TreeGrid/index.js +2 -2
- package/dist/{TreeGrid-NSW7VMOX.css → TreeGrid-FBX3MSJA.css} +19 -0
- package/dist/{chunk-EBBAAQDY.js → chunk-26PEPONN.js} +3 -1
- package/dist/{chunk-HV6IZFBK.js → chunk-4FFHJBEN.js} +2 -2
- package/dist/{chunk-JHQUT4WJ.js → chunk-4LDTQWS7.js} +1 -1
- package/dist/{chunk-ELZKOVEC.js → chunk-4Y7WKXAW.js} +1 -1
- package/dist/{chunk-MCPKHYMC.js → chunk-6LXMLQUM.js} +17 -4
- package/dist/{chunk-3UK4VFSK.js → chunk-6NIZCQUM.js} +1 -1
- package/dist/{chunk-ORNOOMVY.js → chunk-6TSZCBID.js} +2 -2
- package/dist/{chunk-ZMJHK7DR.js → chunk-75WOCYGC.js} +2 -2
- package/dist/chunk-77IEHFY4.js +299 -0
- package/dist/chunk-A5YKNRG6.js +94 -0
- package/dist/{chunk-HLBRPES3.js → chunk-B2CITO6R.js} +2 -2
- package/dist/{chunk-TEEJSTFG.js → chunk-CF6DTETT.js} +1 -1
- package/dist/{chunk-LAQK4V3Z.js → chunk-DJMLHCLD.js} +1 -1
- package/dist/{chunk-6MU7HNB4.js → chunk-F73MC7EZ.js} +47 -2
- package/dist/{chunk-ZPSOF6VL.js → chunk-FBSEJO2C.js} +1 -1
- package/dist/chunk-FYTIJM2T.js +40 -0
- package/dist/{chunk-7JGWSOLM.js → chunk-GG2QEZO2.js} +1 -1
- package/dist/chunk-H6VKCIWV.js +41 -0
- package/dist/{chunk-6SDGRKQ7.js → chunk-HKGS67VG.js} +94 -41
- package/dist/chunk-IG75YMUN.js +22 -0
- package/dist/{chunk-JCNUQ3US.js → chunk-JDPAA2JU.js} +1 -1
- package/dist/chunk-KLIEPFEZ.js +95 -0
- package/dist/{chunk-7LD6P32I.js → chunk-L3CTFFLZ.js} +2 -18
- package/dist/{chunk-UG5ZMAXW.js → chunk-LELD5KPA.js} +1 -1
- package/dist/chunk-MNFU2RNT.js +74 -0
- package/dist/{chunk-S3BCVWTU.js → chunk-MY374UUD.js} +49 -31
- package/dist/{chunk-K5Q2DK3P.js → chunk-NXDEPUVG.js} +1 -1
- package/dist/{chunk-PDUZO35I.js → chunk-O2ZDZZS7.js} +15 -6
- package/dist/chunk-QBXZLGK2.js +40 -0
- package/dist/chunk-QSLIN64M.js +47 -0
- package/dist/{chunk-5WEVLIB6.js → chunk-RZ7RGECB.js} +1 -1
- package/dist/chunk-S3IENQ3E.js +336 -0
- package/dist/{chunk-WEIINZPA.js → chunk-SBRE7IML.js} +6 -2
- package/dist/{chunk-IVFJD7WY.js → chunk-UCCC7YVZ.js} +3 -2
- package/dist/{chunk-CIOKUMVC.js → chunk-UZPHPW3Z.js} +7 -7
- package/dist/chunk-VWNC2L6W.js +110 -0
- package/dist/chunk-VYY56AMX.js +2 -0
- package/dist/chunk-WI6K5M5X.js +24 -0
- package/dist/{chunk-R4ZJB5YX.js → chunk-WY2NLRZN.js} +2 -2
- package/dist/{chunk-SEFMO2EV.js → chunk-XFE5W2I4.js} +44 -5
- package/dist/chunk-XYCADWZN.js +100 -0
- package/dist/chunk-YSJC7AZC.js +62 -0
- package/dist/chunk-ZAJHGDAW.js +93 -0
- package/dist/generated/index.d.ts +14 -0
- package/dist/generated/index.js +65 -50
- package/dist/index.js +65 -50
- package/dist/styles.css +4456 -1965
- package/dist/utils/highlight.d.ts +17 -0
- package/dist/utils/useMediaMatch.d.ts +12 -0
- package/package.json +3 -3
- package/dist/chunk-UAQIUSSK.js +0 -2
- /package/dist/{chunk-PQLMLG5K.js → chunk-6AR2T5Y4.js} +0 -0
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The switcher: a button that is the page's name, and a banded panel under it
|
|
3
|
+
* (a search band, a list that scrolls, and a footer that does not).
|
|
4
|
+
*
|
|
5
|
+
* The rows are the listbox register (`Listbox.css`), because a project in this
|
|
6
|
+
* list and a result in the command palette are read the same way, and the
|
|
7
|
+
* raised row that marks where the arrows are must mean the same in both. What
|
|
8
|
+
* this adds is the switcher's own: a lead column every row's key lines up in,
|
|
9
|
+
* the current subject outlined in the accent, and a held row that keeps its
|
|
10
|
+
* reason without a hover.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
.crewlet-switcher {
|
|
14
|
+
/* The panel's own measures: a width that holds a key, a long name and a
|
|
15
|
+
count, and a height that holds eight projects with Recent above them
|
|
16
|
+
without scrolling. */
|
|
17
|
+
--crewlet-switcher-width: 360px;
|
|
18
|
+
--crewlet-switcher-max-height: 520px;
|
|
19
|
+
--crewlet-switcher-lead: 52px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* ── The button ─────────────────────────────────────────────────────────── */
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
* THE PAGE'S NAME, WITH NO BOX AT REST. It is the heading of the page as much
|
|
26
|
+
* as it is a control, so it reads as text in the trail until the pointer
|
|
27
|
+
* reaches it; the fill appears under the pointer and stays while the panel is
|
|
28
|
+
* open, and the chevron turns. The name takes the cut, never the key or the
|
|
29
|
+
* chevron.
|
|
30
|
+
*/
|
|
31
|
+
.crewlet-switcher-trigger {
|
|
32
|
+
display: inline-flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
gap: calc(var(--spacing-1) * 1.5);
|
|
35
|
+
min-width: 0;
|
|
36
|
+
max-width: 100%;
|
|
37
|
+
height: var(--size-row-sm);
|
|
38
|
+
padding: 0 var(--spacing-1) 0 calc(var(--spacing-1) * 1.5);
|
|
39
|
+
border: none;
|
|
40
|
+
border-radius: var(--radius-md);
|
|
41
|
+
background: transparent;
|
|
42
|
+
color: var(--color-text-primary);
|
|
43
|
+
font: inherit;
|
|
44
|
+
font-weight: var(--font-weight-medium);
|
|
45
|
+
cursor: pointer;
|
|
46
|
+
transition: background-color var(--motion-duration-fast) var(--motion-easing-default);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.crewlet-switcher-trigger:hover,
|
|
50
|
+
.crewlet-switcher-trigger[aria-expanded='true'] {
|
|
51
|
+
background: var(--color-surface-hover);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.crewlet-switcher-trigger:active {
|
|
55
|
+
background: var(--color-surface-pressed);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* Inside the button's own edge, so the trail's scrollport never clips it. */
|
|
59
|
+
.crewlet-switcher-trigger:focus-visible {
|
|
60
|
+
outline: 2px solid var(--color-focus);
|
|
61
|
+
outline-offset: var(--size-focus-ring-inset-offset);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.crewlet-switcher-trigger__label {
|
|
65
|
+
min-width: 0;
|
|
66
|
+
overflow: hidden;
|
|
67
|
+
text-overflow: ellipsis;
|
|
68
|
+
white-space: nowrap;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.crewlet-switcher-trigger.is-mono .crewlet-switcher-trigger__label {
|
|
72
|
+
font-family: var(--font-family-mono);
|
|
73
|
+
font-size: var(--font-size-compact);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.crewlet-switcher-trigger .crewlet-key-chip,
|
|
77
|
+
.crewlet-switcher-trigger__tag {
|
|
78
|
+
display: inline-flex;
|
|
79
|
+
flex: none;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
svg.crewlet-switcher-trigger__chevron {
|
|
83
|
+
flex: none;
|
|
84
|
+
color: var(--color-text-tertiary);
|
|
85
|
+
transition:
|
|
86
|
+
transform var(--motion-duration-fast) var(--motion-easing-default),
|
|
87
|
+
color var(--motion-duration-fast) var(--motion-easing-default);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.crewlet-switcher-trigger:hover svg.crewlet-switcher-trigger__chevron {
|
|
91
|
+
color: var(--color-text-secondary);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.crewlet-switcher-trigger[aria-expanded='true'] svg.crewlet-switcher-trigger__chevron {
|
|
95
|
+
color: var(--color-text-secondary);
|
|
96
|
+
transform: rotate(180deg);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* ── The three surfaces ─────────────────────────────────────────────────── */
|
|
100
|
+
|
|
101
|
+
/*
|
|
102
|
+
* ANCHORED: the popover's own surface (the subtle rung, the default hairline,
|
|
103
|
+
* the large corner and the deepest shadow) at the switcher's size. The bands
|
|
104
|
+
* lay themselves out inside it, so the panel itself does not scroll.
|
|
105
|
+
*/
|
|
106
|
+
.crewlet-popover.crewlet-switcher {
|
|
107
|
+
display: flex;
|
|
108
|
+
flex-direction: column;
|
|
109
|
+
width: var(--crewlet-switcher-width);
|
|
110
|
+
min-width: 0;
|
|
111
|
+
max-width: calc(100vw - var(--spacing-4));
|
|
112
|
+
max-height: min(var(--crewlet-switcher-max-height), calc(100dvh - var(--spacing-10) - var(--spacing-4)));
|
|
113
|
+
overflow: hidden;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/*
|
|
117
|
+
* CENTRED: the same panel as a dialog, a step lower than a dialog stands so
|
|
118
|
+
* it clears the page's bar, arriving at the popover's pace rather than a
|
|
119
|
+
* dialog's, because it is the same panel opened from somewhere else.
|
|
120
|
+
*/
|
|
121
|
+
.crewlet-modal.crewlet-switcher--centered {
|
|
122
|
+
--crewlet-modal-width: var(--crewlet-switcher-width);
|
|
123
|
+
|
|
124
|
+
max-height: min(var(--crewlet-switcher-max-height), calc(100dvh - var(--spacing-10) - var(--spacing-6)));
|
|
125
|
+
margin-top: var(--spacing-2);
|
|
126
|
+
animation-duration: var(--motion-duration-base);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* A SHEET carries a grab handle over its title, which says it came from the
|
|
130
|
+
edge it is pinned to. Decoration: the close control is what closes it. */
|
|
131
|
+
.crewlet-modal.crewlet-switcher--sheet::before {
|
|
132
|
+
content: '';
|
|
133
|
+
flex: none;
|
|
134
|
+
width: calc(var(--spacing-7) + var(--spacing-1));
|
|
135
|
+
height: var(--spacing-1);
|
|
136
|
+
margin: var(--spacing-2) auto 0;
|
|
137
|
+
border-radius: var(--radius-pill);
|
|
138
|
+
background: var(--color-border-strong);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.crewlet-switcher--sheet .crewlet-modal__header {
|
|
142
|
+
min-height: var(--size-control-lg);
|
|
143
|
+
padding: 0 var(--spacing-2) 0 var(--spacing-4);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* A dialog's body scrolls its whole content; here the list alone scrolls. */
|
|
147
|
+
.crewlet-switcher .crewlet-modal__body {
|
|
148
|
+
display: flex;
|
|
149
|
+
flex-direction: column;
|
|
150
|
+
overflow: hidden;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.crewlet-switcher__panel {
|
|
154
|
+
display: flex;
|
|
155
|
+
flex: 1 1 auto;
|
|
156
|
+
flex-direction: column;
|
|
157
|
+
min-height: 0;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* ── The search band ────────────────────────────────────────────────────── */
|
|
161
|
+
|
|
162
|
+
/*
|
|
163
|
+
* The field with no box of its own, as the command palette draws it: the band
|
|
164
|
+
* is the field. It is set at the trail's size rather than the palette's
|
|
165
|
+
* headline size, because the panel is a list read at a glance, and at the
|
|
166
|
+
* reading size on a phone, where a smaller field zooms the page when tapped.
|
|
167
|
+
*/
|
|
168
|
+
.crewlet-input.crewlet-switcher__search {
|
|
169
|
+
flex-shrink: 0;
|
|
170
|
+
min-height: var(--size-control-lg);
|
|
171
|
+
padding-inline: var(--spacing-3) var(--spacing-2);
|
|
172
|
+
border: none;
|
|
173
|
+
border-bottom: 1px solid var(--color-border-default);
|
|
174
|
+
border-radius: 0;
|
|
175
|
+
background: transparent;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.crewlet-input.crewlet-switcher__search .crewlet-input__control {
|
|
179
|
+
font-size: var(--font-size-sm);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.crewlet-switcher--sheet .crewlet-input.crewlet-switcher__search .crewlet-input__control {
|
|
183
|
+
font-size: var(--font-size-md);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* ── The list ───────────────────────────────────────────────────────────── */
|
|
187
|
+
|
|
188
|
+
.crewlet-switcher__scroller {
|
|
189
|
+
flex: 1 1 auto;
|
|
190
|
+
min-height: 0;
|
|
191
|
+
overflow-y: auto;
|
|
192
|
+
overscroll-behavior: contain;
|
|
193
|
+
padding: var(--spacing-1);
|
|
194
|
+
scrollbar-width: thin;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.crewlet-switcher__list {
|
|
198
|
+
display: flex;
|
|
199
|
+
flex-direction: column;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/*
|
|
203
|
+
* A ROW: a lead column, the name, and a figure at the end. Both classes are
|
|
204
|
+
* named so this ties with nothing in `Listbox.css`, whose rows are a step
|
|
205
|
+
* shorter and padded on every side.
|
|
206
|
+
*/
|
|
207
|
+
.crewlet-listbox__option.crewlet-switcher__option {
|
|
208
|
+
gap: 0;
|
|
209
|
+
min-height: var(--size-row-md);
|
|
210
|
+
padding-block: 0;
|
|
211
|
+
font-weight: var(--font-weight-medium);
|
|
212
|
+
text-decoration: none;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.crewlet-switcher--sheet .crewlet-listbox__option.crewlet-switcher__option {
|
|
216
|
+
min-height: var(--size-control-lg);
|
|
217
|
+
font-size: var(--font-size-sm);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/*
|
|
221
|
+
* THE CURRENT SUBJECT, outlined by its own accent hairline inside the row: an
|
|
222
|
+
* outline rather than a shadow, so forced-colours mode keeps it. The row the
|
|
223
|
+
* arrows are on takes the raised fill as every listbox row does; both can land
|
|
224
|
+
* on one row, and it never gains a second border.
|
|
225
|
+
*/
|
|
226
|
+
.crewlet-listbox__option.crewlet-switcher__option.is-current {
|
|
227
|
+
color: var(--color-text-primary);
|
|
228
|
+
outline: 1px solid var(--color-brand-accent);
|
|
229
|
+
outline-offset: -1px;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* A HELD ROW answers no pointer: no fill under it, and the reason in the quiet
|
|
233
|
+
ink at its end says why. */
|
|
234
|
+
.crewlet-listbox__option.crewlet-switcher__option[aria-disabled='true'] {
|
|
235
|
+
background: transparent;
|
|
236
|
+
color: var(--color-text-tertiary);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/* Every row's key starts on one line, whatever the key's length. */
|
|
240
|
+
.crewlet-switcher__lead {
|
|
241
|
+
display: flex;
|
|
242
|
+
flex: none;
|
|
243
|
+
align-items: center;
|
|
244
|
+
width: var(--crewlet-switcher-lead);
|
|
245
|
+
color: var(--color-text-tertiary);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.crewlet-switcher__label {
|
|
249
|
+
flex: 1 1 auto;
|
|
250
|
+
min-width: 0;
|
|
251
|
+
overflow: hidden;
|
|
252
|
+
text-overflow: ellipsis;
|
|
253
|
+
white-space: nowrap;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* The letters a search matched: the weight carries it, in the primary ink. */
|
|
257
|
+
b.crewlet-switcher__match {
|
|
258
|
+
font-weight: var(--font-weight-bold);
|
|
259
|
+
color: var(--color-text-primary);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.crewlet-switcher__meta {
|
|
263
|
+
display: inline-flex;
|
|
264
|
+
flex: none;
|
|
265
|
+
align-items: center;
|
|
266
|
+
gap: calc(var(--spacing-1) * 1.5);
|
|
267
|
+
margin-left: var(--spacing-3);
|
|
268
|
+
color: var(--color-text-tertiary);
|
|
269
|
+
font-size: var(--font-size-xs);
|
|
270
|
+
font-weight: var(--font-weight-regular);
|
|
271
|
+
font-variant-numeric: tabular-nums;
|
|
272
|
+
white-space: nowrap;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/* A group's heading carries its count at its end. */
|
|
276
|
+
.crewlet-switcher__heading {
|
|
277
|
+
display: flex;
|
|
278
|
+
align-items: baseline;
|
|
279
|
+
justify-content: space-between;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.crewlet-switcher__count {
|
|
283
|
+
font-variant-numeric: tabular-nums;
|
|
284
|
+
letter-spacing: normal;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/* A line about the list itself, on the inset rung: not a row, so not a row's
|
|
288
|
+
shape. */
|
|
289
|
+
.crewlet-switcher__note {
|
|
290
|
+
margin: calc(var(--spacing-1) * 1.5) var(--spacing-2) var(--spacing-1);
|
|
291
|
+
padding: var(--spacing-2) calc(var(--spacing-2) + var(--spacing-1) / 2);
|
|
292
|
+
border-radius: var(--radius-md);
|
|
293
|
+
background: var(--color-surface-inset);
|
|
294
|
+
color: var(--color-text-secondary);
|
|
295
|
+
font-size: var(--font-size-xs);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/* A state of the list, said in two lines, with its actions as rows under it. */
|
|
299
|
+
.crewlet-switcher__message {
|
|
300
|
+
display: grid;
|
|
301
|
+
gap: var(--spacing-1);
|
|
302
|
+
padding: var(--spacing-3) var(--spacing-3) var(--spacing-2);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.crewlet-switcher__message-title {
|
|
306
|
+
color: var(--color-text-primary);
|
|
307
|
+
font-size: var(--font-size-compact);
|
|
308
|
+
font-weight: var(--font-weight-semibold);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.crewlet-switcher__message-body {
|
|
312
|
+
color: var(--color-text-secondary);
|
|
313
|
+
font-size: var(--font-size-xs);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/* Placeholder rows the shape of the rows on their way. */
|
|
317
|
+
.crewlet-switcher__skeleton-row {
|
|
318
|
+
display: flex;
|
|
319
|
+
align-items: center;
|
|
320
|
+
height: var(--size-row-md);
|
|
321
|
+
padding: 0 var(--spacing-3);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.crewlet-switcher__skeleton-row > .crewlet-switcher__meta {
|
|
325
|
+
margin-left: auto;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/* ── The footer ─────────────────────────────────────────────────────────── */
|
|
329
|
+
|
|
330
|
+
.crewlet-switcher__footer {
|
|
331
|
+
display: flex;
|
|
332
|
+
flex: none;
|
|
333
|
+
flex-direction: column;
|
|
334
|
+
padding: var(--spacing-1);
|
|
335
|
+
border-top: 1px solid var(--color-border-default);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
@media (prefers-reduced-motion: reduce) {
|
|
339
|
+
.crewlet-switcher-trigger {
|
|
340
|
+
transition: none;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
svg.crewlet-switcher-trigger__chevron {
|
|
344
|
+
transition: none;
|
|
345
|
+
}
|
|
346
|
+
}
|
package/dist/Tabs/Tabs.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import React, { type ReactNode } from 'react';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* How the row is drawn. `pill` is a segmented well with a raised chip for the
|
|
4
|
+
* one that is on; `underline` is a strip with a sliding bar, for a screen's
|
|
5
|
+
* sections; `chip` is a row of quiet chips with no well, the one that is on
|
|
6
|
+
* outlined in the accent, for the lenses beside an object's name in a bar.
|
|
7
|
+
*/
|
|
8
|
+
export type TabsVariant = 'pill' | 'underline' | 'chip';
|
|
3
9
|
export type TabsSize = 'sm' | 'md';
|
|
4
10
|
export interface TabsItem {
|
|
5
11
|
/** Stable identity: the value reported, and half of the tab's id. */
|
package/dist/Tabs/index.js
CHANGED
|
@@ -300,6 +300,55 @@
|
|
|
300
300
|
outline-offset: 0;
|
|
301
301
|
}
|
|
302
302
|
|
|
303
|
+
/* ─── Chip (a lens row) ───────────────────────────────────────── */
|
|
304
|
+
/*
|
|
305
|
+
* QUIET CHIPS WITH NO WELL: the lenses of an object or a scope, set beside its
|
|
306
|
+
* name in a page's bar. A well round them was a second box beside the name the
|
|
307
|
+
* lenses are about, and a raised chip inside it a second highlight. Here the
|
|
308
|
+
* chip that is on is drawn by its own border in the accent and nothing else,
|
|
309
|
+
* which is the kit's one way of saying "this one is chosen".
|
|
310
|
+
*/
|
|
311
|
+
.crewlet-tabs--chip {
|
|
312
|
+
display: inline-flex;
|
|
313
|
+
align-items: center;
|
|
314
|
+
gap: calc(var(--spacing-1) / 2);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.crewlet-tabs--chip .crewlet-tabs__tab {
|
|
318
|
+
min-height: var(--size-control-sm);
|
|
319
|
+
padding: 0 calc(var(--spacing-2) + var(--spacing-1) / 2);
|
|
320
|
+
border-radius: var(--radius-md);
|
|
321
|
+
color: var(--color-text-secondary);
|
|
322
|
+
font-size: var(--font-size-xs);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.crewlet-tabs--chip .crewlet-tabs__tab:hover:not(.is-disabled):not(.is-active) {
|
|
326
|
+
background: var(--color-surface-hover);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/* A COUNT IS A QUIET FIGURE here, not a pill: a pill inside a chip is a box
|
|
330
|
+
inside a box, beside a name that already has its own. */
|
|
331
|
+
.crewlet-tabs--chip .crewlet-count {
|
|
332
|
+
min-width: 0;
|
|
333
|
+
padding: 0;
|
|
334
|
+
background: none;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/* An outline rather than a border, so a chip turning on does not move its
|
|
338
|
+
neighbours by a pixel, and forced-colors mode keeps it. */
|
|
339
|
+
.crewlet-tabs--chip .crewlet-tabs__tab.is-active {
|
|
340
|
+
color: var(--color-text-primary);
|
|
341
|
+
outline: 1px solid var(--color-brand-accent);
|
|
342
|
+
outline-offset: -1px;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/* THE RING TAKES THE BORDER'S PLACE: declared after it and of the same
|
|
346
|
+
weight, so a focused chip that is on draws one edge, the ring. */
|
|
347
|
+
.crewlet-tabs--chip .crewlet-tabs__tab:focus-visible {
|
|
348
|
+
outline: 2px solid var(--color-focus);
|
|
349
|
+
outline-offset: -2px;
|
|
350
|
+
}
|
|
351
|
+
|
|
303
352
|
.crewlet-tabs__tab.is-disabled,
|
|
304
353
|
.crewlet-tabs__tab:disabled {
|
|
305
354
|
opacity: 0.55;
|
package/dist/TagsInput/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export { TagsInput } from '../chunk-
|
|
1
|
+
export { TagsInput } from '../chunk-GG2QEZO2.js';
|
|
2
2
|
import '../chunk-LOECRMHA.js';
|
|
3
3
|
import '../chunk-WIATRXEJ.js';
|
|
4
|
-
import '../chunk-
|
|
4
|
+
import '../chunk-F73MC7EZ.js';
|
|
5
5
|
import '../chunk-4FQT6ZAY.js';
|
|
6
6
|
import '../chunk-RSAQOKH3.js';
|
|
7
7
|
import '../chunk-7RPGY3JE.js';
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type HTMLAttributes } from 'react';
|
|
2
|
+
import { type ThemeId } from '@crewlethq/tokens';
|
|
3
|
+
import { type ThemeSwatchPair } from '../ThemeSwatch/index.js';
|
|
4
|
+
/** A theme as the gallery offers it: the fields of a `themeRegistry` entry it reads. */
|
|
5
|
+
export interface ThemeGalleryTheme<T extends string = string> {
|
|
6
|
+
id: T;
|
|
7
|
+
name: string;
|
|
8
|
+
/** A few words on what sets it apart, said with its name. */
|
|
9
|
+
tag: string;
|
|
10
|
+
/** The id of the group it is listed under. */
|
|
11
|
+
group: string;
|
|
12
|
+
swatch: ThemeSwatchPair;
|
|
13
|
+
}
|
|
14
|
+
/** A heading the themes are listed under, as `themeGroups` carries it. */
|
|
15
|
+
export interface ThemeGalleryGroup {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ThemeGalleryProps<T extends string = ThemeId> extends Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'onChange'> {
|
|
20
|
+
/** The group's name, said on entering it. "Theme" by default. */
|
|
21
|
+
label?: string | undefined;
|
|
22
|
+
/** The theme in use. */
|
|
23
|
+
value: T;
|
|
24
|
+
/** The reader chose a theme: a click, Space or Enter, or an arrow key. */
|
|
25
|
+
onValueChange: (id: T) => void;
|
|
26
|
+
/**
|
|
27
|
+
* The theme the pointer has come to rest on, for a preview beside the
|
|
28
|
+
* gallery, and `null` when it leaves: told once the pointer has rested on a
|
|
29
|
+
* card for `HIGHLIGHT_REST_MS`, so crossing the grid does not repaint the
|
|
30
|
+
* preview at every card it passes.
|
|
31
|
+
*/
|
|
32
|
+
onPreview?: ((id: T | null) => void) | undefined;
|
|
33
|
+
/** The themes offered. Every theme `@crewlethq/tokens` ships, by default. */
|
|
34
|
+
themes?: readonly ThemeGalleryTheme<T>[] | undefined;
|
|
35
|
+
/** The headings they are listed under, in order. The registry's groups, by default. */
|
|
36
|
+
groups?: readonly ThemeGalleryGroup[] | undefined;
|
|
37
|
+
/** How many cards a row holds. Three by default. */
|
|
38
|
+
columns?: number | undefined;
|
|
39
|
+
/** Nothing can be chosen, and the gallery says so. */
|
|
40
|
+
disabled?: boolean | undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The choice of a theme: every theme, each drawn as its two palettes, listed
|
|
44
|
+
* under its group.
|
|
45
|
+
*
|
|
46
|
+
* A RADIO GROUP, because a theme is a setting and exactly one is in use: the
|
|
47
|
+
* gallery is one tab stop, and the arrows move through it and choose as they
|
|
48
|
+
* move, as the platform's own radio group does. They walk the cards in
|
|
49
|
+
* reading order, across the groups, because the groups break the rows and an
|
|
50
|
+
* arrow that jumped a row would land somewhere the reader is not looking.
|
|
51
|
+
*
|
|
52
|
+
* THE CHOSEN CARD IS SAID WITH ITS OWN BORDER, in the accent: one line round
|
|
53
|
+
* the card, and the line means "this one". Focus draws its ring over that
|
|
54
|
+
* border rather than outside it, so a focused card is never two outlines.
|
|
55
|
+
*
|
|
56
|
+
* POINTING PREVIEWS, CHOOSING APPLIES. `onPreview` is told the card the
|
|
57
|
+
* pointer rests on, for a pane beside the gallery to show it in, so a reader
|
|
58
|
+
* crossing the grid with the pointer does not repaint the whole window at
|
|
59
|
+
* every card. The keys choose as they move, which is what applies.
|
|
60
|
+
*
|
|
61
|
+
* A CARD IS NAMED BY THE THEME'S NAME AND ITS TAG ("Abyss, Vivid violet"),
|
|
62
|
+
* and described by its group's heading; the drawing is decoration, because
|
|
63
|
+
* the name is printed under it.
|
|
64
|
+
*/
|
|
65
|
+
export declare function ThemeGallery<T extends string = ThemeId>({ label, value, onValueChange, onPreview, themes, groups, columns, disabled, className, style, ...rest }: ThemeGalleryProps<T>): import("react").JSX.Element;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The gallery of themes: each group's heading over a grid of cards.
|
|
3
|
+
*
|
|
4
|
+
* A ROW HOLDS THE SAME NUMBER OF CARDS IN EVERY GROUP (`columns`, three by
|
|
5
|
+
* default), so a group of one draws a card the size of every other card
|
|
6
|
+
* rather than one stretched across the row, and the swatches line up from
|
|
7
|
+
* group to group.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
.crewlet-theme-gallery__groups {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-direction: column;
|
|
13
|
+
gap: var(--spacing-3);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.crewlet-theme-gallery__group {
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
gap: var(--spacing-1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.crewlet-theme-gallery__heading {
|
|
23
|
+
color: var(--color-text-tertiary);
|
|
24
|
+
font-size: var(--font-size-2xs);
|
|
25
|
+
line-height: var(--font-line-height-normal);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.crewlet-theme-gallery__cards {
|
|
29
|
+
display: grid;
|
|
30
|
+
grid-template-columns: repeat(var(--crewlet-theme-gallery-columns), minmax(0, 1fr));
|
|
31
|
+
gap: var(--spacing-2);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/*
|
|
35
|
+
* A CARD IS ITS BORDER. Resting, the plain hairline; under the pointer, the
|
|
36
|
+
* strong one; chosen, the accent. One line round the card in every state, so
|
|
37
|
+
* the chosen card is never a card inside a frame.
|
|
38
|
+
*/
|
|
39
|
+
.crewlet-theme-gallery__card {
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
gap: var(--spacing-1);
|
|
43
|
+
min-width: 0;
|
|
44
|
+
padding: var(--spacing-2);
|
|
45
|
+
border: 1px solid var(--color-border-default);
|
|
46
|
+
border-radius: var(--radius-md);
|
|
47
|
+
background: var(--color-surface-subtle);
|
|
48
|
+
color: var(--color-text-primary);
|
|
49
|
+
font: inherit;
|
|
50
|
+
text-align: left;
|
|
51
|
+
cursor: pointer;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Not on the chosen card: under the pointer it keeps the accent, or the one
|
|
55
|
+
card that says "this one" would stop saying it while it is being pointed at. */
|
|
56
|
+
.crewlet-theme-gallery__card:hover:not(:disabled):not(.is-chosen) {
|
|
57
|
+
border-color: var(--color-border-strong);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.crewlet-theme-gallery__card.is-chosen {
|
|
61
|
+
border-color: var(--color-brand-accent);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/* The ring is drawn OVER the border, inset by its width, never a second line outside it. */
|
|
65
|
+
.crewlet-theme-gallery__card:focus-visible {
|
|
66
|
+
outline: 2px solid var(--color-focus);
|
|
67
|
+
outline-offset: -1px;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.crewlet-theme-gallery__card:disabled {
|
|
71
|
+
cursor: not-allowed;
|
|
72
|
+
opacity: 0.5;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.crewlet-theme-gallery__name {
|
|
76
|
+
overflow: hidden;
|
|
77
|
+
font-size: var(--font-size-xs);
|
|
78
|
+
font-weight: var(--font-weight-medium);
|
|
79
|
+
line-height: var(--font-line-height-tight);
|
|
80
|
+
text-overflow: ellipsis;
|
|
81
|
+
white-space: nowrap;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/*
|
|
85
|
+
* FORCED COLORS keeps the border and drops the accent, so the chosen card
|
|
86
|
+
* would look like every other; the system's own selected colour says it.
|
|
87
|
+
*/
|
|
88
|
+
@media (forced-colors: active) {
|
|
89
|
+
.crewlet-theme-gallery__card.is-chosen {
|
|
90
|
+
border-color: Highlight;
|
|
91
|
+
border-width: 2px;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* The colours a theme's thumbnail is drawn with, in one mode: the shape of a
|
|
4
|
+
* `themeRegistry` entry's `swatch.dark` and `swatch.light` in
|
|
5
|
+
* `@crewlethq/tokens`, which the build reads off the sheet that paints the
|
|
6
|
+
* theme.
|
|
7
|
+
*/
|
|
8
|
+
export interface ThemeSwatchColours {
|
|
9
|
+
frame: string;
|
|
10
|
+
sheet: string;
|
|
11
|
+
card: string;
|
|
12
|
+
raised: string;
|
|
13
|
+
hairline: string;
|
|
14
|
+
text: string;
|
|
15
|
+
muted: string;
|
|
16
|
+
accent: string;
|
|
17
|
+
onAccent: string;
|
|
18
|
+
info: string;
|
|
19
|
+
warning: string;
|
|
20
|
+
danger: string;
|
|
21
|
+
success: string;
|
|
22
|
+
}
|
|
23
|
+
/** A theme's two palettes, as its registry entry carries them. */
|
|
24
|
+
export interface ThemeSwatchPair {
|
|
25
|
+
dark: ThemeSwatchColours;
|
|
26
|
+
light: ThemeSwatchColours;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* How much of the theme is drawn.
|
|
30
|
+
*
|
|
31
|
+
* `chip` is a mark beside a name in a list: each palette's frame with its
|
|
32
|
+
* accent on it. `card` is a picker's thumbnail: a rail, a sheet and a card
|
|
33
|
+
* with the primary action and the four states. `pane` is the same sketch
|
|
34
|
+
* large enough to read as a screen, for a preview beside a picker.
|
|
35
|
+
*/
|
|
36
|
+
export type ThemeSwatchSize = 'chip' | 'card' | 'pane';
|
|
37
|
+
export interface ThemeSwatchProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {
|
|
38
|
+
/** The theme's colours: a `themeRegistry` entry's `swatch`. */
|
|
39
|
+
swatch: ThemeSwatchPair;
|
|
40
|
+
size?: ThemeSwatchSize | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* One palette alone. Without it both are drawn, dark beside light, which is
|
|
43
|
+
* what a theme IS: a pair the mode chooses between.
|
|
44
|
+
*/
|
|
45
|
+
mode?: 'dark' | 'light' | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Names the drawing as an image. Without one it is decoration and hidden
|
|
48
|
+
* from assistive technology, which is right wherever the theme's name is
|
|
49
|
+
* printed beside it.
|
|
50
|
+
*/
|
|
51
|
+
label?: string | undefined;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A theme, drawn from its colours: the thumbnail every theme picker shows.
|
|
55
|
+
*
|
|
56
|
+
* DRAWN FROM THE REGISTRY, NOT FROM THE PAGE. A thumbnail has to show a theme
|
|
57
|
+
* that is NOT on screen, so it cannot read the page's custom properties: it
|
|
58
|
+
* paints each half with its own, set from the colours the build read off the
|
|
59
|
+
* theme's sheet. The outline round it is the page's own hairline, because
|
|
60
|
+
* that is where the thumbnail sits.
|
|
61
|
+
*
|
|
62
|
+
* BOTH MODES BY DEFAULT, dark beside light, because a theme is a pair and the
|
|
63
|
+
* reader's mode is a separate choice: a thumbnail of one half would show a
|
|
64
|
+
* light reader a dark theme they would never see, or hide the half they
|
|
65
|
+
* would. `mode` draws one, for a preview that follows the reader's mode.
|
|
66
|
+
*
|
|
67
|
+
* DECORATION UNLESS NAMED. Wherever the theme's name is printed beside it the
|
|
68
|
+
* drawing says nothing a reader needs; given a `label`, it is an image with
|
|
69
|
+
* that name.
|
|
70
|
+
*/
|
|
71
|
+
export declare function ThemeSwatch({ swatch, size, mode, label, className, ...rest }: ThemeSwatchProps): import("react").JSX.Element;
|