@crewlethq/ui 0.18.0 → 0.20.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 +40 -4
- package/dist/AccessDeniedCard/index.js +2 -2
- package/dist/AppShell/index.js +2 -2
- package/dist/ArrangeBoard/ArrangeBoard.d.ts +32 -0
- package/dist/ArrangeBoard/index.d.ts +3 -0
- package/dist/ArrangeBoard/index.js +2 -0
- package/dist/ArrangeBoard-MQE35P6Z.css +80 -0
- package/dist/ArrangeFrame/ArrangeFrame.d.ts +82 -0
- package/dist/ArrangeFrame/index.d.ts +5 -0
- package/dist/ArrangeFrame/index.js +5 -0
- package/dist/ArrangeFrame/useGridResize.d.ts +66 -0
- package/dist/ArrangeFrame-3PLZAG22.css +329 -0
- package/dist/ArrangeGroup/ArrangeGroup.d.ts +42 -0
- package/dist/ArrangeGroup/index.d.ts +3 -0
- package/dist/ArrangeGroup/index.js +4 -0
- package/dist/ArrangeGroup-SHFHA7BE.css +170 -0
- package/dist/ArrangeList/ArrangeList.d.ts +64 -0
- package/dist/ArrangeList/index.d.ts +3 -0
- package/dist/ArrangeList/index.js +10 -0
- package/dist/ArrangeList-NNRTDFI5.css +94 -0
- package/dist/ArtifactCard/index.js +2 -2
- package/dist/AuthLayout/index.js +2 -2
- package/dist/AvatarPicker/index.js +4 -4
- package/dist/Canvas/index.js +2 -2
- package/dist/Card/index.js +1 -1
- package/dist/Checkbox/index.js +3 -3
- package/dist/Combobox/index.js +4 -4
- package/dist/CommandPalette/index.js +6 -6
- package/dist/CommentThread/CommentThread.d.ts +85 -0
- package/dist/CommentThread/index.d.ts +3 -0
- package/dist/CommentThread/index.js +16 -0
- package/dist/CommentThread-7VXOFTZO.css +90 -0
- package/dist/Composer/index.js +3 -3
- package/dist/ConfirmField/index.js +3 -3
- package/dist/ConflictNote/ConflictNote.d.ts +42 -0
- package/dist/ConflictNote/index.d.ts +3 -0
- package/dist/ConflictNote/index.js +4 -0
- package/dist/ConflictNote-DH77PYF7.css +27 -0
- package/dist/DataTable/index.js +8 -8
- package/dist/DataView/index.js +13 -13
- package/dist/DateTimePicker/index.js +3 -3
- package/dist/DiffView/DiffView.d.ts +59 -0
- package/dist/DiffView/diff.d.ts +97 -0
- package/dist/DiffView/index.d.ts +5 -0
- package/dist/DiffView/index.js +3 -0
- package/dist/DiffView-RVLIHTKG.css +91 -0
- package/dist/Divider/Divider.d.ts +15 -0
- package/dist/Divider/index.d.ts +3 -0
- package/dist/Divider/index.js +2 -0
- package/dist/Divider-3Z77ZAJH.css +37 -0
- package/dist/HuePicker/HuePicker.d.ts +16 -4
- package/dist/HuePicker/index.js +2 -2
- package/dist/{HuePicker-5QIUR6L7.css → HuePicker-PAIGH6LR.css} +6 -0
- package/dist/IconTile/IconTile.d.ts +23 -0
- package/dist/IconTile/index.d.ts +3 -0
- package/dist/IconTile/index.js +2 -0
- package/dist/IconTile-4GNWTLAW.css +30 -0
- package/dist/Input/index.js +2 -2
- package/dist/LinkInterstitial/index.js +4 -4
- package/dist/ListInput/index.js +5 -5
- package/dist/MarkdownEditor/index.js +2 -2
- package/dist/Menu/index.js +2 -2
- package/dist/Modal/Modal.d.ts +20 -0
- package/dist/Modal/index.js +3 -3
- package/dist/{Modal-RQAYGG4L.css → Modal-XOSV6FAH.css} +14 -0
- package/dist/Note/Note.d.ts +23 -0
- package/dist/Note/index.d.ts +3 -0
- package/dist/Note/index.js +2 -0
- package/dist/Note-RT4L6VUT.css +58 -0
- package/dist/OrgTable/index.js +5 -5
- package/dist/PeopleRail/PeopleRail.d.ts +52 -0
- package/dist/PeopleRail/index.d.ts +3 -0
- package/dist/PeopleRail/index.js +11 -0
- package/dist/PeopleRail-R64WVOSH.css +75 -0
- package/dist/PinTile/PinTile.d.ts +37 -0
- package/dist/PinTile/index.d.ts +3 -0
- package/dist/PinTile/index.js +4 -0
- package/dist/PinTile-IIA25MNZ.css +141 -0
- package/dist/PresenceStack/index.js +1 -1
- package/dist/PrincipalPicker/index.js +5 -5
- package/dist/Reorder/index.d.ts +2 -0
- package/dist/Reorder/index.js +4 -0
- package/dist/Reorder/useReorder.d.ts +138 -0
- package/dist/ShareDialog/index.js +7 -7
- package/dist/SheetGrid/index.js +5 -5
- package/dist/StatGroup/StatGroup.d.ts +7 -1
- package/dist/StatGroup/index.js +1 -1
- package/dist/{StatGroup-HVG6O62W.css → StatGroup-PADTJCUQ.css} +7 -0
- package/dist/Switcher/index.js +8 -8
- package/dist/TableCells/TableCells.d.ts +153 -0
- package/dist/TableCells/index.d.ts +3 -0
- package/dist/TableCells/index.js +10 -0
- package/dist/TableCells-3VN5N2M3.css +104 -0
- package/dist/TagsInput/index.js +3 -3
- package/dist/TimeWindowPicker/index.js +5 -5
- package/dist/TreeCanvas/index.js +3 -3
- package/dist/TreeGrid/index.js +2 -2
- package/dist/VersionCompare/VersionCompare.d.ts +70 -0
- package/dist/VersionCompare/index.d.ts +3 -0
- package/dist/VersionCompare/index.js +11 -0
- package/dist/VersionCompare-UUZOPTQO.css +68 -0
- package/dist/chunk-35XVR5JQ.js +81 -0
- package/dist/chunk-63WJLRB2.js +24 -0
- package/dist/{chunk-L4ZLXYPO.js → chunk-6A7P6II6.js} +1 -1
- package/dist/chunk-6KWNXIDE.js +18 -0
- package/dist/chunk-6MIXD6IW.js +49 -0
- package/dist/chunk-73QBUUYX.js +102 -0
- package/dist/{chunk-NZY77ZDU.js → chunk-7FQEUNHX.js} +4 -4
- package/dist/{chunk-2TZATTIU.js → chunk-7IJARUIF.js} +18 -5
- package/dist/{chunk-A7EBCHEG.js → chunk-A4VMJMXJ.js} +1 -1
- package/dist/chunk-AIVZVKYZ.js +126 -0
- package/dist/{chunk-76FXDZAZ.js → chunk-AJESMWJS.js} +4 -4
- package/dist/chunk-BVWSLXTY.js +187 -0
- package/dist/chunk-DEJHAOC5.js +279 -0
- package/dist/{chunk-ERV5BUS3.js → chunk-EIGEIT4O.js} +3 -3
- package/dist/chunk-EZBLOUWX.js +176 -0
- package/dist/chunk-FFMCMSJB.js +1 -0
- package/dist/{chunk-LFZ45HV2.js → chunk-G3EEUNZQ.js} +1 -1
- package/dist/{chunk-2YR5ZPQ3.js → chunk-HTCJSUIZ.js} +3 -3
- package/dist/{chunk-75CLJNDQ.js → chunk-I6NZKJGK.js} +1 -1
- package/dist/chunk-IXJHTFXG.js +17 -0
- package/dist/{chunk-3UAA4IWJ.js → chunk-JEDWC3GI.js} +1 -1
- package/dist/{chunk-QVAFL2LE.js → chunk-JXRI5YD2.js} +3 -3
- package/dist/{chunk-ZFH7H7GS.js → chunk-LOLELDBW.js} +1 -1
- package/dist/chunk-MUGM7SEG.js +88 -0
- package/dist/chunk-N4GFRW5C.js +96 -0
- package/dist/{chunk-KVT3TJVG.js → chunk-OIMAK5AE.js} +6 -6
- package/dist/chunk-QO7QEQKV.js +24 -0
- package/dist/{chunk-BOW2VUCH.js → chunk-T7ICFXEC.js} +1 -1
- package/dist/{chunk-2OLCUNG7.js → chunk-TBIZSQHB.js} +1 -1
- package/dist/{chunk-4U3GQ7D2.js → chunk-TODND5AD.js} +1 -1
- package/dist/chunk-UO7JZVCO.js +35 -0
- package/dist/{chunk-IFKBDRNJ.js → chunk-UXELEORU.js} +3 -3
- package/dist/{chunk-6NIMZ5XC.js → chunk-VJLYGPPE.js} +1 -1
- package/dist/{chunk-7QFAORCY.js → chunk-WHZFDS62.js} +1 -1
- package/dist/chunk-XJ2QEBMM.js +277 -0
- package/dist/{chunk-PA4CYTBY.js → chunk-XU4ZUGLE.js} +19 -4
- package/dist/{chunk-T3ZWBZ65.js → chunk-YSJYWQSP.js} +2 -2
- package/dist/{chunk-CXBAIVYZ.js → chunk-YSY6UJ4F.js} +1 -1
- package/dist/{chunk-EG6NYWVK.js → chunk-YZCJ63JF.js} +1 -1
- package/dist/generated/index.d.ts +15 -0
- package/dist/generated/index.js +89 -74
- package/dist/index.js +89 -74
- package/dist/styles.css +1533 -70
- package/package.json +3 -3
- package/dist/chunk-EXHQ2QVW.js +0 -1
- package/dist/{chunk-AQCV62K6.js → chunk-7ZNKEPLN.js} +1 -1
- package/dist/{chunk-OYOQU7O5.js → chunk-EDGCPVVD.js} +1 -1
- package/dist/{chunk-FYXRWBJJ.js → chunk-J2G4HGQM.js} +1 -1
- package/dist/{chunk-NS7BVLL3.js → chunk-JULMZNGT.js} +1 -1
- package/dist/{chunk-5NVKTB6E.js → chunk-L4H7SSWF.js} +1 -1
- package/dist/{chunk-ESKP3TXM.js → chunk-MSSZHDZI.js} +0 -0
- package/dist/{chunk-4GB57WIT.js → chunk-Q55TXPA3.js} +1 -1
- package/dist/{chunk-B2Z2CDM5.js → chunk-T5TFZ2JB.js} +1 -1
- package/dist/{chunk-AMH67MLM.js → chunk-TXAFKH2A.js} +1 -1
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ArrangeFrame: a block of a page being arranged.
|
|
3
|
+
*
|
|
4
|
+
* Off, the frame is layout only. Editing, the block keeps its own look at
|
|
5
|
+
* rest; hovered or focused, one accent ring is drawn over its own edge and
|
|
6
|
+
* its toolbar and resize handle appear. Every piece of chrome floats, so a
|
|
7
|
+
* block is the same size while arranging as afterwards.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
.crewlet-arrange-frame {
|
|
11
|
+
/* The corner every ring and bracket follows: a card's own. */
|
|
12
|
+
--crewlet-arrange-frame-radius: var(--radius-lg);
|
|
13
|
+
/* How far outside the block its ring is drawn; the chrome sits on the ring. */
|
|
14
|
+
--crewlet-arrange-frame-outset: 0px;
|
|
15
|
+
|
|
16
|
+
position: relative;
|
|
17
|
+
display: flex;
|
|
18
|
+
flex-direction: column;
|
|
19
|
+
min-width: 0;
|
|
20
|
+
border-radius: var(--crewlet-arrange-frame-radius);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.crewlet-arrange-frame__content {
|
|
24
|
+
display: flex;
|
|
25
|
+
flex: 1 1 auto;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
min-width: 0;
|
|
28
|
+
min-height: 0;
|
|
29
|
+
}
|
|
30
|
+
.crewlet-arrange-frame__content > * {
|
|
31
|
+
flex: 1 1 auto;
|
|
32
|
+
min-height: 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* A height of the reader's: the content scrolls inside it. */
|
|
36
|
+
.crewlet-arrange-frame.is-fixed-height .crewlet-arrange-frame__content > * {
|
|
37
|
+
overflow: auto;
|
|
38
|
+
overscroll-behavior: contain;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* ---- Editing ---------------------------------------------------------- */
|
|
42
|
+
|
|
43
|
+
/* The block itself is what moves: focused, its ring is its focus mark. The
|
|
44
|
+
transparent outline is the one forced-colors mode paints in its place. */
|
|
45
|
+
.crewlet-arrange-frame.is-editing:focus-visible {
|
|
46
|
+
outline: 2px solid transparent;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* The surface is what a pointer moves a block by. */
|
|
50
|
+
.crewlet-arrange-frame.is-editing:not(.is-container) {
|
|
51
|
+
cursor: grab;
|
|
52
|
+
}
|
|
53
|
+
.crewlet-arrange-frame.is-editing:not(.is-container):active {
|
|
54
|
+
cursor: grabbing;
|
|
55
|
+
}
|
|
56
|
+
.crewlet-arrange-frame.is-editing:not(.is-container) > .crewlet-arrange-frame__content {
|
|
57
|
+
user-select: none;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/*
|
|
61
|
+
* THE ONE RING, over the block's own edge, on the innermost block the
|
|
62
|
+
* pointer or the focus is in. A hairline drawn exactly over the block's own
|
|
63
|
+
* 1px border, so the border turns to the accent rather than a second, heavier
|
|
64
|
+
* line appearing around it.
|
|
65
|
+
*
|
|
66
|
+
* IT IS A LAYER OF ITS OWN, above the content. An outline is painted with the
|
|
67
|
+
* block, under any content that is positioned or scrolls (a card with a fixed
|
|
68
|
+
* height scrolls its list), and that content covered it. Positioned after the
|
|
69
|
+
* content with no depth of its own, it paints over the content and under the
|
|
70
|
+
* toolbar and the handle, which are raised.
|
|
71
|
+
*/
|
|
72
|
+
.crewlet-arrange-frame.is-editing::after {
|
|
73
|
+
content: '';
|
|
74
|
+
position: absolute;
|
|
75
|
+
inset: calc(var(--crewlet-arrange-frame-outset) * -1);
|
|
76
|
+
box-sizing: border-box;
|
|
77
|
+
border: 1px solid transparent;
|
|
78
|
+
border-radius: inherit;
|
|
79
|
+
pointer-events: none;
|
|
80
|
+
}
|
|
81
|
+
.crewlet-arrange-frame.is-editing:is(:hover, :focus-visible, :has(:focus-visible)):not(
|
|
82
|
+
:has(.crewlet-arrange-frame:is(:hover, :focus-visible, :has(:focus-visible)))
|
|
83
|
+
)::after,
|
|
84
|
+
.crewlet-arrange-frame.is-selected::after,
|
|
85
|
+
.crewlet-arrange-frame.is-resizing::after {
|
|
86
|
+
border-color: var(--color-brand-accent);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* A block with no surface of its own takes its ring a step outside it. */
|
|
90
|
+
.crewlet-arrange-frame.is-bare {
|
|
91
|
+
--crewlet-arrange-frame-radius: var(--radius-md);
|
|
92
|
+
--crewlet-arrange-frame-outset: var(--spacing-1);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* Carried, the block is the hole it leaves. */
|
|
96
|
+
.crewlet-arrange-frame.is-editing[data-reorder='dragging']::after {
|
|
97
|
+
border-style: dashed;
|
|
98
|
+
border-color: var(--color-brand-accent);
|
|
99
|
+
}
|
|
100
|
+
.crewlet-arrange-frame[data-reorder='dragging'] > .crewlet-arrange-frame__content {
|
|
101
|
+
opacity: 0.3;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* Where a block from another list will land: a bar of the accent in the gap
|
|
105
|
+
before the block it will precede. */
|
|
106
|
+
.crewlet-arrange-frame[data-reorder-target='before']::before {
|
|
107
|
+
content: '';
|
|
108
|
+
position: absolute;
|
|
109
|
+
top: 0;
|
|
110
|
+
bottom: 0;
|
|
111
|
+
left: calc(var(--spacing-2) * -1 - 2px);
|
|
112
|
+
width: 3px;
|
|
113
|
+
border-radius: var(--radius-pill);
|
|
114
|
+
background: var(--color-brand-accent);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* ...or after the last block, when it will land at the end. */
|
|
118
|
+
.crewlet-arrange-frame[data-reorder-target='after']::before {
|
|
119
|
+
content: '';
|
|
120
|
+
position: absolute;
|
|
121
|
+
top: 0;
|
|
122
|
+
right: calc(var(--spacing-2) * -1 - 2px);
|
|
123
|
+
bottom: 0;
|
|
124
|
+
width: 3px;
|
|
125
|
+
border-radius: var(--radius-pill);
|
|
126
|
+
background: var(--color-brand-accent);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* Beside a block that spans its row, the bar runs along the gap above it,
|
|
130
|
+
or below it when it is the last. */
|
|
131
|
+
.crewlet-arrange-frame[data-reorder-line='horizontal'][data-reorder-target]::before {
|
|
132
|
+
top: auto;
|
|
133
|
+
right: 0;
|
|
134
|
+
bottom: auto;
|
|
135
|
+
left: 0;
|
|
136
|
+
width: auto;
|
|
137
|
+
height: 3px;
|
|
138
|
+
}
|
|
139
|
+
.crewlet-arrange-frame[data-reorder-line='horizontal'][data-reorder-target='before']::before {
|
|
140
|
+
top: calc(var(--spacing-2) * -1 - 2px);
|
|
141
|
+
}
|
|
142
|
+
.crewlet-arrange-frame[data-reorder-line='horizontal'][data-reorder-target='after']::before {
|
|
143
|
+
bottom: calc(var(--spacing-2) * -1 - 2px);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* Just added: one pulse of the accent around it. */
|
|
147
|
+
.crewlet-arrange-frame.is-fresh {
|
|
148
|
+
animation: crewlet-arrange-frame-fresh calc(var(--motion-duration-slow) * 4) var(--motion-easing-out) 1;
|
|
149
|
+
}
|
|
150
|
+
@keyframes crewlet-arrange-frame-fresh {
|
|
151
|
+
0%,
|
|
152
|
+
40% {
|
|
153
|
+
box-shadow: 0 0 0 4px var(--color-brand-accent-soft);
|
|
154
|
+
}
|
|
155
|
+
100% {
|
|
156
|
+
box-shadow: 0 0 0 0 transparent;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/* ---- The toolbar -------------------------------------------------------- */
|
|
161
|
+
|
|
162
|
+
/* On the block's top edge, half outside it: clear of a card's own header
|
|
163
|
+
links, and of the block above, which is a row gap away. */
|
|
164
|
+
.crewlet-arrange-frame__bar {
|
|
165
|
+
position: absolute;
|
|
166
|
+
top: calc(var(--crewlet-arrange-frame-outset) * -1);
|
|
167
|
+
right: var(--spacing-3);
|
|
168
|
+
z-index: var(--z-index-raised);
|
|
169
|
+
display: flex;
|
|
170
|
+
align-items: center;
|
|
171
|
+
gap: 2px;
|
|
172
|
+
padding: 2px;
|
|
173
|
+
border: 1px solid var(--color-border-default);
|
|
174
|
+
border-radius: var(--radius-md);
|
|
175
|
+
background: var(--color-surface-elevated);
|
|
176
|
+
box-shadow: var(--shadow-md);
|
|
177
|
+
transform: translateY(-50%);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.crewlet-arrange-frame__sep:first-child {
|
|
181
|
+
display: none;
|
|
182
|
+
}
|
|
183
|
+
.crewlet-arrange-frame__sep {
|
|
184
|
+
align-self: stretch;
|
|
185
|
+
width: 1px;
|
|
186
|
+
margin: 3px 2px;
|
|
187
|
+
background: var(--color-border-default);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/* ---- Resize handles ------------------------------------------------------- */
|
|
191
|
+
|
|
192
|
+
.crewlet-arrange-frame__resize {
|
|
193
|
+
position: absolute;
|
|
194
|
+
z-index: var(--z-index-raised);
|
|
195
|
+
padding: 0;
|
|
196
|
+
border: 0;
|
|
197
|
+
background: none;
|
|
198
|
+
color: var(--color-text-tertiary);
|
|
199
|
+
touch-action: none;
|
|
200
|
+
}
|
|
201
|
+
.crewlet-arrange-frame__grip {
|
|
202
|
+
position: absolute;
|
|
203
|
+
transition: background-color var(--motion-duration-fast) var(--motion-easing-default),
|
|
204
|
+
border-color var(--motion-duration-fast) var(--motion-easing-default);
|
|
205
|
+
}
|
|
206
|
+
.crewlet-arrange-frame__resize:hover,
|
|
207
|
+
.crewlet-arrange-frame__resize:focus-visible,
|
|
208
|
+
.crewlet-arrange-frame.is-resizing .crewlet-arrange-frame__resize {
|
|
209
|
+
color: var(--color-brand-accent);
|
|
210
|
+
}
|
|
211
|
+
.crewlet-arrange-frame__resize:focus-visible {
|
|
212
|
+
outline: 2px solid var(--color-focus);
|
|
213
|
+
outline-offset: 0;
|
|
214
|
+
border-radius: var(--radius-sm);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/* BOTH WAYS: a bracket in the corner, following the card's own radius. */
|
|
218
|
+
.crewlet-arrange-frame__resize.is-corner {
|
|
219
|
+
right: calc(var(--crewlet-arrange-frame-outset) * -1);
|
|
220
|
+
bottom: calc(var(--crewlet-arrange-frame-outset) * -1);
|
|
221
|
+
width: 22px;
|
|
222
|
+
height: 22px;
|
|
223
|
+
cursor: nwse-resize;
|
|
224
|
+
}
|
|
225
|
+
.crewlet-arrange-frame__resize.is-corner > .crewlet-arrange-frame__grip {
|
|
226
|
+
right: 4px;
|
|
227
|
+
bottom: 4px;
|
|
228
|
+
width: 10px;
|
|
229
|
+
height: 10px;
|
|
230
|
+
border-right: 2px solid currentColor;
|
|
231
|
+
border-bottom: 2px solid currentColor;
|
|
232
|
+
border-bottom-right-radius: calc(var(--crewlet-arrange-frame-radius) - 4px);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/* WIDTH ONLY: a grip on the right edge, the handle of a column splitter,
|
|
236
|
+
in the corner bracket's colour and ringed in the page's ground so it reads
|
|
237
|
+
over the card's border. */
|
|
238
|
+
.crewlet-arrange-frame__resize.is-edge {
|
|
239
|
+
top: 50%;
|
|
240
|
+
right: calc(-7px - var(--crewlet-arrange-frame-outset));
|
|
241
|
+
width: 14px;
|
|
242
|
+
height: 36px;
|
|
243
|
+
cursor: ew-resize;
|
|
244
|
+
transform: translateY(-50%);
|
|
245
|
+
}
|
|
246
|
+
.crewlet-arrange-frame__resize.is-edge > .crewlet-arrange-frame__grip {
|
|
247
|
+
top: 4px;
|
|
248
|
+
bottom: 4px;
|
|
249
|
+
left: 4px;
|
|
250
|
+
width: 6px;
|
|
251
|
+
border-radius: var(--radius-pill);
|
|
252
|
+
background: currentColor;
|
|
253
|
+
box-shadow: 0 0 0 2px var(--color-surface-background);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/* ---- What shows when ---------------------------------------------------- */
|
|
257
|
+
|
|
258
|
+
/* The toolbar and the handle belong to the innermost block hovered or
|
|
259
|
+
focused, and stay while its menu is open or it is being resized. */
|
|
260
|
+
.crewlet-arrange-frame__bar,
|
|
261
|
+
.crewlet-arrange-frame__resize {
|
|
262
|
+
opacity: 0;
|
|
263
|
+
pointer-events: none;
|
|
264
|
+
transition: opacity var(--motion-duration-fast) var(--motion-easing-default);
|
|
265
|
+
}
|
|
266
|
+
.crewlet-arrange-frame.is-editing:is(:hover, :focus-visible, :has(:focus-visible)):not(
|
|
267
|
+
:has(.crewlet-arrange-frame:is(:hover, :focus-visible, :has(:focus-visible)))
|
|
268
|
+
)
|
|
269
|
+
> :is(.crewlet-arrange-frame__bar, .crewlet-arrange-frame__resize),
|
|
270
|
+
.crewlet-arrange-frame.is-editing > .crewlet-arrange-frame__bar:has([aria-expanded='true']),
|
|
271
|
+
.crewlet-arrange-frame.is-editing:has(> .crewlet-arrange-frame__bar [aria-expanded='true'])
|
|
272
|
+
> .crewlet-arrange-frame__resize,
|
|
273
|
+
.crewlet-arrange-frame.is-resizing > :is(.crewlet-arrange-frame__bar, .crewlet-arrange-frame__resize) {
|
|
274
|
+
opacity: 1;
|
|
275
|
+
pointer-events: auto;
|
|
276
|
+
}
|
|
277
|
+
/* A touch screen has no hover to reveal them with. */
|
|
278
|
+
@media (hover: none) {
|
|
279
|
+
.crewlet-arrange-frame.is-editing > :is(.crewlet-arrange-frame__bar, .crewlet-arrange-frame__resize) {
|
|
280
|
+
opacity: 1;
|
|
281
|
+
pointer-events: auto;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/* ---- While resizing ------------------------------------------------------- */
|
|
286
|
+
|
|
287
|
+
/* The columns of the grid the block sits on, across its row. */
|
|
288
|
+
.crewlet-arrange-frame__guides {
|
|
289
|
+
position: absolute;
|
|
290
|
+
top: 0;
|
|
291
|
+
bottom: 0;
|
|
292
|
+
z-index: var(--z-index-raised);
|
|
293
|
+
display: grid;
|
|
294
|
+
pointer-events: none;
|
|
295
|
+
}
|
|
296
|
+
.crewlet-arrange-frame__guides > span {
|
|
297
|
+
border-inline: 1px dashed var(--color-brand-accent);
|
|
298
|
+
background: var(--color-brand-accent-soft);
|
|
299
|
+
opacity: 0.3;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/* The size it will land at, over the middle of the block. */
|
|
303
|
+
.crewlet-arrange-frame__size {
|
|
304
|
+
position: absolute;
|
|
305
|
+
top: 50%;
|
|
306
|
+
left: 50%;
|
|
307
|
+
z-index: calc(var(--z-index-raised) + 1);
|
|
308
|
+
padding: var(--spacing-1) var(--spacing-3);
|
|
309
|
+
border-radius: var(--radius-pill);
|
|
310
|
+
background: var(--color-surface-inverse);
|
|
311
|
+
color: var(--color-text-inverse);
|
|
312
|
+
font-size: var(--font-size-xs);
|
|
313
|
+
font-weight: var(--font-weight-medium);
|
|
314
|
+
font-variant-numeric: tabular-nums;
|
|
315
|
+
white-space: nowrap;
|
|
316
|
+
transform: translate(-50%, -50%);
|
|
317
|
+
pointer-events: none;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
@media (prefers-reduced-motion: reduce) {
|
|
321
|
+
.crewlet-arrange-frame__bar,
|
|
322
|
+
.crewlet-arrange-frame__resize,
|
|
323
|
+
.crewlet-arrange-frame__grip {
|
|
324
|
+
transition: none;
|
|
325
|
+
}
|
|
326
|
+
.crewlet-arrange-frame.is-fresh {
|
|
327
|
+
animation: none;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
import type { NodeHue } from '../utils/nodeHue.js';
|
|
3
|
+
/** A surface's colour: one of the six hues, or none. */
|
|
4
|
+
export type SurfaceTone = NodeHue | 'none';
|
|
5
|
+
export interface ArrangeGroupProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
|
|
6
|
+
/** What the group holds, in the reader's words: "Delivery". */
|
|
7
|
+
title: string;
|
|
8
|
+
tone?: SurfaceTone | undefined;
|
|
9
|
+
collapsed: boolean;
|
|
10
|
+
onCollapsedChange: (collapsed: boolean) => void;
|
|
11
|
+
/** How many blocks it holds, beside the title. */
|
|
12
|
+
count?: number | undefined;
|
|
13
|
+
/** Editing, the title is a field. Left out, it is read only. */
|
|
14
|
+
onTitleChange?: ((title: string) => void) | undefined;
|
|
15
|
+
/** Props for the body the blocks are laid in (a drop target, a class). */
|
|
16
|
+
bodyProps?: (HTMLAttributes<HTMLDivElement> & {
|
|
17
|
+
'data-reorder-over'?: string | undefined;
|
|
18
|
+
}) | undefined;
|
|
19
|
+
/** Drawn in the body when it holds nothing. */
|
|
20
|
+
empty?: ReactNode;
|
|
21
|
+
/** Columns of the body's grid. */
|
|
22
|
+
columns?: number | undefined;
|
|
23
|
+
/** Controls at the end of the header. */
|
|
24
|
+
actions?: ReactNode;
|
|
25
|
+
children?: ReactNode;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A titled band that holds blocks of a page, the way a dashboard groups its
|
|
29
|
+
* widgets: "Needs attention", "Delivery", "Spend".
|
|
30
|
+
*
|
|
31
|
+
* A HEADING THAT FOLDS. The header is the group's name and the control that
|
|
32
|
+
* collapses it, one button with `aria-expanded`, so a reader skimming the
|
|
33
|
+
* page's outline finds every group and opens the one they want.
|
|
34
|
+
*
|
|
35
|
+
* ITS OWN GRID. The blocks inside are laid on the same column count as the
|
|
36
|
+
* page, measured across the group, so a half-width card in a half-width group
|
|
37
|
+
* is a quarter of the page and reads as half of its group.
|
|
38
|
+
*
|
|
39
|
+
* THE TONE IS A BAND, never the whole surface: the header carries the hue and
|
|
40
|
+
* the body stays the page's, so the cards inside keep their own contrast.
|
|
41
|
+
*/
|
|
42
|
+
export declare function ArrangeGroup({ title, tone, collapsed, onCollapsedChange, count, onTitleChange, bodyProps, empty, columns, actions, className, children, ...rest }: ArrangeGroupProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ArrangeGroup: a titled band of blocks. The hue is the header's; the body
|
|
3
|
+
* stays the page's ground, so the cards inside keep their own contrast.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
.crewlet-arrange-group {
|
|
7
|
+
--crewlet-arrange-group-band: var(--color-surface-subtle);
|
|
8
|
+
--crewlet-arrange-group-line: var(--color-border-default);
|
|
9
|
+
--crewlet-arrange-group-ink: var(--color-text-primary);
|
|
10
|
+
--crewlet-arrange-group-mark: var(--color-border-strong);
|
|
11
|
+
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: column;
|
|
14
|
+
min-width: 0;
|
|
15
|
+
border: 1px solid var(--crewlet-arrange-group-line);
|
|
16
|
+
border-radius: var(--radius-lg);
|
|
17
|
+
background: var(--color-surface-background);
|
|
18
|
+
overflow: clip;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.crewlet-arrange-group--purple { --crewlet-arrange-group-band: var(--color-node-purple-fill); --crewlet-arrange-group-line: var(--color-node-purple-line); --crewlet-arrange-group-ink: var(--color-node-purple-ink); --crewlet-arrange-group-mark: var(--color-node-purple); }
|
|
22
|
+
.crewlet-arrange-group--cyan { --crewlet-arrange-group-band: var(--color-node-cyan-fill); --crewlet-arrange-group-line: var(--color-node-cyan-line); --crewlet-arrange-group-ink: var(--color-node-cyan-ink); --crewlet-arrange-group-mark: var(--color-node-cyan); }
|
|
23
|
+
.crewlet-arrange-group--green { --crewlet-arrange-group-band: var(--color-node-green-fill); --crewlet-arrange-group-line: var(--color-node-green-line); --crewlet-arrange-group-ink: var(--color-node-green-ink); --crewlet-arrange-group-mark: var(--color-node-green); }
|
|
24
|
+
.crewlet-arrange-group--amber { --crewlet-arrange-group-band: var(--color-node-amber-fill); --crewlet-arrange-group-line: var(--color-node-amber-line); --crewlet-arrange-group-ink: var(--color-node-amber-ink); --crewlet-arrange-group-mark: var(--color-node-amber); }
|
|
25
|
+
.crewlet-arrange-group--rose { --crewlet-arrange-group-band: var(--color-node-rose-fill); --crewlet-arrange-group-line: var(--color-node-rose-line); --crewlet-arrange-group-ink: var(--color-node-rose-ink); --crewlet-arrange-group-mark: var(--color-node-rose); }
|
|
26
|
+
.crewlet-arrange-group--blue { --crewlet-arrange-group-band: var(--color-node-blue-fill); --crewlet-arrange-group-line: var(--color-node-blue-line); --crewlet-arrange-group-ink: var(--color-node-blue-ink); --crewlet-arrange-group-mark: var(--color-node-blue); }
|
|
27
|
+
|
|
28
|
+
.crewlet-arrange-group__head {
|
|
29
|
+
display: flex;
|
|
30
|
+
align-items: center;
|
|
31
|
+
gap: var(--spacing-2);
|
|
32
|
+
min-height: var(--size-row-lg);
|
|
33
|
+
padding: var(--spacing-1) var(--spacing-3) var(--spacing-1) var(--spacing-2);
|
|
34
|
+
border-bottom: 1px solid var(--crewlet-arrange-group-line);
|
|
35
|
+
background: var(--crewlet-arrange-group-band);
|
|
36
|
+
}
|
|
37
|
+
.crewlet-arrange-group.is-collapsed .crewlet-arrange-group__head {
|
|
38
|
+
border-bottom-color: transparent;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.crewlet-arrange-group__toggle {
|
|
42
|
+
display: inline-flex;
|
|
43
|
+
flex: 0 1 auto;
|
|
44
|
+
align-items: center;
|
|
45
|
+
gap: var(--spacing-2);
|
|
46
|
+
min-width: 0;
|
|
47
|
+
min-height: var(--size-row-sm);
|
|
48
|
+
padding: 0 var(--spacing-2);
|
|
49
|
+
border: 0;
|
|
50
|
+
border-radius: var(--radius-sm);
|
|
51
|
+
background: none;
|
|
52
|
+
color: var(--crewlet-arrange-group-ink);
|
|
53
|
+
font: inherit;
|
|
54
|
+
cursor: pointer;
|
|
55
|
+
}
|
|
56
|
+
/* Editing, the toggle is the chevron alone, a square of its own, so its
|
|
57
|
+
hover never runs into the name field beside it. */
|
|
58
|
+
.crewlet-arrange-group__toggle.is-icon {
|
|
59
|
+
flex: 0 0 auto;
|
|
60
|
+
justify-content: center;
|
|
61
|
+
width: var(--size-row-sm);
|
|
62
|
+
padding: 0;
|
|
63
|
+
}
|
|
64
|
+
.crewlet-arrange-group__toggle:hover {
|
|
65
|
+
background: var(--color-surface-hover);
|
|
66
|
+
}
|
|
67
|
+
.crewlet-arrange-group__toggle:focus-visible {
|
|
68
|
+
outline: 2px solid var(--color-focus);
|
|
69
|
+
outline-offset: 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.crewlet-arrange-group__chevron {
|
|
73
|
+
flex-shrink: 0;
|
|
74
|
+
transition: transform var(--motion-duration-fast) var(--motion-easing-default);
|
|
75
|
+
}
|
|
76
|
+
.crewlet-arrange-group.is-collapsed .crewlet-arrange-group__chevron {
|
|
77
|
+
transform: rotate(-90deg);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.crewlet-arrange-group__title,
|
|
81
|
+
.crewlet-arrange-group__title-field {
|
|
82
|
+
overflow: hidden;
|
|
83
|
+
font-size: var(--font-size-md);
|
|
84
|
+
font-weight: var(--font-weight-semibold);
|
|
85
|
+
letter-spacing: var(--font-letter-spacing-tight);
|
|
86
|
+
color: var(--crewlet-arrange-group-ink);
|
|
87
|
+
text-overflow: ellipsis;
|
|
88
|
+
white-space: nowrap;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* Editing, the name is typed where it is read: the title itself, which
|
|
92
|
+
shows it is a field on hover and takes a ring when focused. */
|
|
93
|
+
.crewlet-arrange-group__title-field {
|
|
94
|
+
/* As wide as the name, so the count sits just after it. */
|
|
95
|
+
field-sizing: content;
|
|
96
|
+
min-width: 3ch;
|
|
97
|
+
max-width: 100%;
|
|
98
|
+
height: var(--size-row-sm);
|
|
99
|
+
padding: 0 var(--spacing-2);
|
|
100
|
+
border: 1px dashed transparent;
|
|
101
|
+
border-radius: var(--radius-sm);
|
|
102
|
+
background: transparent;
|
|
103
|
+
font-family: inherit;
|
|
104
|
+
cursor: text;
|
|
105
|
+
transition: border-color var(--motion-duration-fast) var(--motion-easing-default),
|
|
106
|
+
background-color var(--motion-duration-fast) var(--motion-easing-default);
|
|
107
|
+
}
|
|
108
|
+
.crewlet-arrange-group__title-field:hover {
|
|
109
|
+
border-color: var(--crewlet-arrange-group-mark);
|
|
110
|
+
}
|
|
111
|
+
/* The ring is drawn over the field's own edge, never beside it. */
|
|
112
|
+
.crewlet-arrange-group__title-field:focus-visible {
|
|
113
|
+
outline: 2px solid var(--color-focus);
|
|
114
|
+
outline-offset: -1px;
|
|
115
|
+
border-style: solid;
|
|
116
|
+
border-color: var(--color-focus);
|
|
117
|
+
background: var(--color-surface-background);
|
|
118
|
+
}
|
|
119
|
+
.crewlet-arrange-group__title-field::placeholder {
|
|
120
|
+
color: var(--color-text-tertiary);
|
|
121
|
+
font-weight: var(--font-weight-regular);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.crewlet-arrange-group__count {
|
|
125
|
+
flex-shrink: 0;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.crewlet-arrange-group__actions {
|
|
129
|
+
display: inline-flex;
|
|
130
|
+
align-items: center;
|
|
131
|
+
gap: var(--spacing-1);
|
|
132
|
+
margin-inline-start: auto;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.crewlet-arrange-group__body {
|
|
136
|
+
display: grid;
|
|
137
|
+
grid-template-columns: repeat(var(--crewlet-arrange-columns, 12), minmax(0, 1fr));
|
|
138
|
+
gap: var(--spacing-4);
|
|
139
|
+
align-items: stretch;
|
|
140
|
+
padding: var(--spacing-4);
|
|
141
|
+
min-height: 5rem;
|
|
142
|
+
}
|
|
143
|
+
.crewlet-arrange-group__body[data-reorder-over='true'] {
|
|
144
|
+
background: var(--color-brand-accent-soft);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.crewlet-arrange-group__empty {
|
|
148
|
+
display: flex;
|
|
149
|
+
grid-column: 1 / -1;
|
|
150
|
+
align-items: center;
|
|
151
|
+
justify-content: center;
|
|
152
|
+
min-height: 4rem;
|
|
153
|
+
border: 1px dashed var(--color-border-strong);
|
|
154
|
+
border-radius: var(--radius-md);
|
|
155
|
+
font-size: var(--font-size-sm);
|
|
156
|
+
color: var(--color-text-tertiary);
|
|
157
|
+
pointer-events: none;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
@media (prefers-reduced-motion: reduce) {
|
|
161
|
+
.crewlet-arrange-group__chevron,
|
|
162
|
+
.crewlet-arrange-group__title-field {
|
|
163
|
+
transition: none;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* Arranging, the header is what a pointer moves the group by. */
|
|
168
|
+
.crewlet-arrange-frame[draggable='true'] > .crewlet-arrange-frame__content > .crewlet-arrange-group > .crewlet-arrange-group__head {
|
|
169
|
+
cursor: grab;
|
|
170
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import { type ReorderLabels } from '../Reorder/index.js';
|
|
3
|
+
export interface ArrangeItem {
|
|
4
|
+
/** The identity, stable across moves. */
|
|
5
|
+
key: string;
|
|
6
|
+
/** What the reader calls it; also the toggle's and the handle's name. */
|
|
7
|
+
label: string;
|
|
8
|
+
/** One line on what it shows, under the label. */
|
|
9
|
+
description?: ReactNode;
|
|
10
|
+
/** A glyph before the label. */
|
|
11
|
+
icon?: ReactNode;
|
|
12
|
+
/** Whether it is on. */
|
|
13
|
+
shown: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Why it cannot be turned off, when it cannot. The toggle stays reachable
|
|
16
|
+
* and says so, rather than going `disabled` and dropping out of the reading
|
|
17
|
+
* order.
|
|
18
|
+
*/
|
|
19
|
+
fixed?: string | undefined;
|
|
20
|
+
/** A control of the item's own at the row's end, before the move buttons. */
|
|
21
|
+
trailing?: ReactNode;
|
|
22
|
+
}
|
|
23
|
+
export interface ArrangeListLabels extends ReorderLabels {
|
|
24
|
+
moveUp: (name: string) => string;
|
|
25
|
+
moveDown: (name: string) => string;
|
|
26
|
+
atTop: (name: string) => string;
|
|
27
|
+
atBottom: (name: string) => string;
|
|
28
|
+
}
|
|
29
|
+
export declare const DEFAULT_ARRANGE_LABELS: ArrangeListLabels;
|
|
30
|
+
export interface ArrangeListProps {
|
|
31
|
+
/** What the list arranges, for its accessible name: "Cards on Home". */
|
|
32
|
+
label: string;
|
|
33
|
+
items: readonly ArrangeItem[];
|
|
34
|
+
onReorder: (keys: string[]) => void;
|
|
35
|
+
onShownChange: (key: string, shown: boolean) => void;
|
|
36
|
+
/**
|
|
37
|
+
* `switch` when a change applies as it is made, `checkbox` when it is read
|
|
38
|
+
* on a Save. See `Switch` for why the two are not interchangeable.
|
|
39
|
+
*/
|
|
40
|
+
toggle?: 'switch' | 'checkbox' | undefined;
|
|
41
|
+
/** Draw the move buttons beside the handle. On by default. */
|
|
42
|
+
moveButtons?: boolean | undefined;
|
|
43
|
+
labels?: Partial<ArrangeListLabels> | undefined;
|
|
44
|
+
className?: string | undefined;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A list a reader puts in order and switches items on and off in: the
|
|
48
|
+
* sections of a page, the columns of a table, the figures on a summary row.
|
|
49
|
+
*
|
|
50
|
+
* LIFTED OUT OF DATATABLE'S COLUMN SETTINGS, where these rules were first
|
|
51
|
+
* written, so every "choose and arrange" panel reads the same: a handle that
|
|
52
|
+
* is a named control, the arrow keys on it, Move up and Move down beside it,
|
|
53
|
+
* a move announced, and a toggle that can refuse with a reason.
|
|
54
|
+
*
|
|
55
|
+
* AN ITEM SWITCHED OFF KEEPS ITS PLACE. Turning something off is not
|
|
56
|
+
* removing it, so it stays in the list, in order, drawn quieter; turning it
|
|
57
|
+
* back on puts it back where it was.
|
|
58
|
+
*
|
|
59
|
+
* THE ENDS ARE NOT DISABLED. Move up on the first item is `aria-disabled`
|
|
60
|
+
* with a reason (`disabledReason`), because a disabled button drops focus to
|
|
61
|
+
* the page and the reader who moved an item to the top loses their place by
|
|
62
|
+
* doing it.
|
|
63
|
+
*/
|
|
64
|
+
export declare function ArrangeList({ label, items, onReorder, onShownChange, toggle, moveButtons, labels: overrides, className, }: ArrangeListProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { ArrangeList, DEFAULT_ARRANGE_LABELS } from '../chunk-AIVZVKYZ.js';
|
|
2
|
+
import '../chunk-A722MUNR.js';
|
|
3
|
+
import '../chunk-XJ2QEBMM.js';
|
|
4
|
+
import '../chunk-I6NZKJGK.js';
|
|
5
|
+
import '../chunk-Q55TXPA3.js';
|
|
6
|
+
import '../chunk-PQADV6P6.js';
|
|
7
|
+
import '../chunk-RSAQOKH3.js';
|
|
8
|
+
import '../chunk-4FQT6ZAY.js';
|
|
9
|
+
import '../chunk-BZFWDIV6.js';
|
|
10
|
+
import '../chunk-ODEQTPFM.js';
|