@geoffcox/sterling-svelte 0.0.8 → 0.0.10
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/buttons/Button.svelte +152 -145
- package/display/Label.svelte +27 -0
- package/display/Label.svelte.d.ts +20 -0
- package/display/Progress.svelte +141 -133
- package/index.d.ts +3 -1
- package/index.js +3 -1
- package/inputs/Checkbox.svelte +129 -117
- package/inputs/Input.svelte +108 -142
- package/inputs/Radio.svelte +129 -113
- package/inputs/Select.svelte +191 -199
- package/inputs/Slider.svelte +182 -209
- package/lists/List.svelte +143 -214
- package/package.json +5 -1
- package/surfaces/CloseX.svelte +5 -0
- package/surfaces/CloseX.svelte.d.ts +23 -0
- package/surfaces/Dialog.svelte +241 -0
- package/surfaces/Dialog.svelte.d.ts +34 -0
- package/theme/colors.js +2 -0
- package/theme/darkTheme.js +3 -3
package/inputs/Select.svelte
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<script>import { createEventDispatcher, onMount, tick } from "svelte";
|
|
2
|
-
import { v4 as
|
|
2
|
+
import { v4 as uuid } from "uuid";
|
|
3
3
|
import { computePosition, flip, offset, shift, autoUpdate } from "@floating-ui/dom";
|
|
4
4
|
import { clickOutside } from "../clickOutside";
|
|
5
|
+
import Label from "../display/Label.svelte";
|
|
5
6
|
import List from "../lists/List.svelte";
|
|
7
|
+
import Input from "./Input.svelte";
|
|
6
8
|
export let disabled = false;
|
|
7
9
|
export let items = [];
|
|
8
10
|
export let open = false;
|
|
@@ -11,12 +13,13 @@ export let selectedItem = void 0;
|
|
|
11
13
|
$: {
|
|
12
14
|
selectedItem = items[selectedIndex];
|
|
13
15
|
}
|
|
16
|
+
const inputId = uuid();
|
|
14
17
|
let prevOpen = false;
|
|
15
18
|
let pendingSelectedIndex = selectedIndex;
|
|
16
19
|
let selectRef;
|
|
17
20
|
let popupRef;
|
|
18
21
|
let listRef;
|
|
19
|
-
const popupId =
|
|
22
|
+
const popupId = uuid();
|
|
20
23
|
let popupPosition = {
|
|
21
24
|
x: void 0,
|
|
22
25
|
y: void 0
|
|
@@ -36,7 +39,6 @@ $: {
|
|
|
36
39
|
raiseItemSelected(selectedIndex);
|
|
37
40
|
}
|
|
38
41
|
$: {
|
|
39
|
-
console.log("raise pendingSelectedIndex changed");
|
|
40
42
|
raiseItemSelectPending(pendingSelectedIndex);
|
|
41
43
|
}
|
|
42
44
|
$: {
|
|
@@ -140,193 +142,177 @@ const onPendingItemSelected = (event) => {
|
|
|
140
142
|
A single item that can be selected from a popup list of items.
|
|
141
143
|
-->
|
|
142
144
|
<div
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
145
|
+
bind:this={selectRef}
|
|
146
|
+
use:clickOutside
|
|
147
|
+
aria-controls={popupId}
|
|
148
|
+
aria-haspopup="listbox"
|
|
149
|
+
aria-expanded={open}
|
|
150
|
+
class="sterling-select"
|
|
151
|
+
class:disabled
|
|
152
|
+
role="combobox"
|
|
153
|
+
tabindex="0"
|
|
154
|
+
on:click_outside={() => (open = false)}
|
|
155
|
+
on:click={onSelectClick}
|
|
156
|
+
on:blur
|
|
157
|
+
on:click
|
|
158
|
+
on:copy
|
|
159
|
+
on:cut
|
|
160
|
+
on:dblclick
|
|
161
|
+
on:focus
|
|
162
|
+
on:focusin
|
|
163
|
+
on:focusout
|
|
164
|
+
on:keydown={onSelectKeydown}
|
|
165
|
+
on:keydown
|
|
166
|
+
on:keypress
|
|
167
|
+
on:keyup
|
|
168
|
+
on:mousedown
|
|
169
|
+
on:mouseenter
|
|
170
|
+
on:mouseleave
|
|
171
|
+
on:mousemove
|
|
172
|
+
on:mouseover
|
|
173
|
+
on:mouseout
|
|
174
|
+
on:mouseup
|
|
175
|
+
on:wheel
|
|
176
|
+
on:paste
|
|
177
|
+
{...$$restProps}
|
|
176
178
|
>
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
</div>
|
|
179
|
+
{#if $$slots.label}
|
|
180
|
+
<div class="label">
|
|
181
|
+
<Label {disabled} for={inputId}>
|
|
182
|
+
<slot name="label" />
|
|
183
|
+
</Label>
|
|
184
|
+
</div>
|
|
185
|
+
{/if}
|
|
186
|
+
<div class="input" id={inputId}>
|
|
187
|
+
<div class="value">
|
|
188
|
+
<slot name="value">
|
|
189
|
+
{items[selectedIndex]}
|
|
190
|
+
</slot>
|
|
191
|
+
</div>
|
|
192
|
+
<div class="button">
|
|
193
|
+
<slot name="button" {open}>
|
|
194
|
+
<div class="chevron" />
|
|
195
|
+
</slot>
|
|
196
|
+
</div>
|
|
197
|
+
</div>
|
|
198
|
+
<div
|
|
199
|
+
bind:this={popupRef}
|
|
200
|
+
class="popup"
|
|
201
|
+
class:open
|
|
202
|
+
id={popupId}
|
|
203
|
+
style="left:{popupPosition.x}px; top:{popupPosition.y}px"
|
|
204
|
+
>
|
|
205
|
+
<div class="popup-content">
|
|
206
|
+
<slot name="list">
|
|
207
|
+
{#if $$slots.default === true}
|
|
208
|
+
<List
|
|
209
|
+
bind:this={listRef}
|
|
210
|
+
selectedIndex={pendingSelectedIndex}
|
|
211
|
+
{items}
|
|
212
|
+
{disabled}
|
|
213
|
+
let:disabled
|
|
214
|
+
let:index
|
|
215
|
+
let:item
|
|
216
|
+
let:selected
|
|
217
|
+
on:click={onListClick}
|
|
218
|
+
on:keydown={onListKeydown}
|
|
219
|
+
on:itemSelected={onPendingItemSelected}
|
|
220
|
+
>
|
|
221
|
+
<slot {disabled} {index} {item} {selected} />
|
|
222
|
+
</List>
|
|
223
|
+
{:else}
|
|
224
|
+
<List
|
|
225
|
+
bind:this={listRef}
|
|
226
|
+
selectedIndex={pendingSelectedIndex}
|
|
227
|
+
{items}
|
|
228
|
+
{disabled}
|
|
229
|
+
let:disabled
|
|
230
|
+
let:index
|
|
231
|
+
let:item
|
|
232
|
+
let:selected
|
|
233
|
+
on:click={onListClick}
|
|
234
|
+
on:keydown={onListKeydown}
|
|
235
|
+
on:itemSelected={onPendingItemSelected}
|
|
236
|
+
/>
|
|
237
|
+
{/if}
|
|
238
|
+
</slot>
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
240
241
|
</div>
|
|
241
242
|
|
|
242
243
|
<style>
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
background-color: var(--Input__background-color);
|
|
254
|
-
border-color: var(--Input__border-color);
|
|
255
|
-
border-radius: var(--Input__border-radius);
|
|
256
|
-
border-style: var(--Input__border-style);
|
|
257
|
-
border-width: var(--Input__border-width);
|
|
258
|
-
color: var(--Input__color);
|
|
259
|
-
padding: 0;
|
|
260
|
-
transition: background-color 250ms, color 250ms, border-color 250ms;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
.sterling-select:hover {
|
|
264
|
-
background-color: var(--Input__background-color--hover);
|
|
265
|
-
border-color: var(--Input__border-color--hover);
|
|
266
|
-
color: var(--Input__color--hover);
|
|
267
|
-
}
|
|
244
|
+
.sterling-select {
|
|
245
|
+
background-color: var(--Input__background-color);
|
|
246
|
+
border-color: var(--Input__border-color);
|
|
247
|
+
border-radius: var(--Input__border-radius);
|
|
248
|
+
border-style: var(--Input__border-style);
|
|
249
|
+
border-width: var(--Input__border-width);
|
|
250
|
+
color: var(--Input__color);
|
|
251
|
+
padding: 0;
|
|
252
|
+
transition: background-color 250ms, color 250ms, border-color 250ms;
|
|
253
|
+
}
|
|
268
254
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
outline-offset: var(--Common__outline-offset);
|
|
275
|
-
outline-style: var(--Common__outline-style);
|
|
276
|
-
outline-width: var(--Common__outline-width);
|
|
277
|
-
}
|
|
255
|
+
.sterling-select:hover {
|
|
256
|
+
background-color: var(--Input__background-color--hover);
|
|
257
|
+
border-color: var(--Input__border-color--hover);
|
|
258
|
+
color: var(--Input__color--hover);
|
|
259
|
+
}
|
|
278
260
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
261
|
+
.sterling-select:focus-within {
|
|
262
|
+
background-color: var(--Input__background-color--focus);
|
|
263
|
+
border-color: var(--Input__border-color--focus);
|
|
264
|
+
color: var(--Input__color--focus);
|
|
265
|
+
outline-color: var(--Common__outline-color);
|
|
266
|
+
outline-offset: var(--Common__outline-offset);
|
|
267
|
+
outline-style: var(--Common__outline-style);
|
|
268
|
+
outline-width: var(--Common__outline-width);
|
|
269
|
+
}
|
|
286
270
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
271
|
+
.sterling-select.disabled {
|
|
272
|
+
background-color: var(--Input__background-color--disabled);
|
|
273
|
+
border-color: var(---Input__border-color--disabled);
|
|
274
|
+
color: var(--Input__color--disabled);
|
|
275
|
+
cursor: not-allowed;
|
|
276
|
+
outline: none;
|
|
277
|
+
}
|
|
293
278
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
279
|
+
.label {
|
|
280
|
+
font-size: 0.7em;
|
|
281
|
+
margin: 0.5em 0.7em 0 0.7em;
|
|
282
|
+
}
|
|
297
283
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
284
|
+
.input {
|
|
285
|
+
display: grid;
|
|
286
|
+
grid-template-columns: 1fr auto;
|
|
287
|
+
grid-template-rows: auto;
|
|
288
|
+
align-content: center;
|
|
289
|
+
align-items: center;
|
|
290
|
+
}
|
|
305
291
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
292
|
+
.value {
|
|
293
|
+
padding: 0.5em;
|
|
294
|
+
}
|
|
309
295
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
296
|
+
.chevron {
|
|
297
|
+
display: block;
|
|
298
|
+
position: relative;
|
|
299
|
+
border: none;
|
|
300
|
+
background: none;
|
|
301
|
+
margin: 0;
|
|
302
|
+
height: 100%;
|
|
303
|
+
width: 32px;
|
|
304
|
+
}
|
|
319
305
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
306
|
+
.chevron::after {
|
|
307
|
+
position: absolute;
|
|
308
|
+
content: '';
|
|
309
|
+
top: 50%;
|
|
310
|
+
left: 50%;
|
|
311
|
+
width: 7px;
|
|
312
|
+
height: 7px;
|
|
313
|
+
border-right: 3px solid currentColor;
|
|
314
|
+
border-top: 3px solid currentColor;
|
|
315
|
+
/*
|
|
330
316
|
The chevron is a right triangle, rotated to face down.
|
|
331
317
|
It should be moved up so it is centered vertically after rotation.
|
|
332
318
|
The amount to move is the hypotenuse of the right triangle of the chevron.
|
|
@@ -339,28 +325,34 @@ A single item that can be selected from a popup list of items.
|
|
|
339
325
|
a = sqrt(0.5)
|
|
340
326
|
a = 0.707
|
|
341
327
|
*/
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
328
|
+
transform: translate(-50%, calc(-50% / 0.707)) rotate(135deg);
|
|
329
|
+
transform-origin: 50% 50%;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.popup {
|
|
333
|
+
box-sizing: border-box;
|
|
334
|
+
display: none;
|
|
335
|
+
overflow: hidden;
|
|
336
|
+
position: absolute;
|
|
337
|
+
box-shadow: rgba(0, 0, 0, 0.4) 2px 2px 4px -1px;
|
|
338
|
+
width: fit-content;
|
|
339
|
+
height: fit-content;
|
|
340
|
+
z-index: 1;
|
|
341
|
+
}
|
|
345
342
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
box-shadow: rgba(0, 0, 0, 0.4) 2px 2px 4px -1px;
|
|
352
|
-
width: fit-content;
|
|
353
|
-
height: fit-content;
|
|
354
|
-
z-index: 1;
|
|
355
|
-
}
|
|
343
|
+
.popup.open {
|
|
344
|
+
display: grid;
|
|
345
|
+
grid-template-columns: 1fr;
|
|
346
|
+
grid-template-rows: 1fr;
|
|
347
|
+
}
|
|
356
348
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
grid-template-rows: 1fr;
|
|
361
|
-
}
|
|
349
|
+
.popup-content {
|
|
350
|
+
max-height: 15em;
|
|
351
|
+
}
|
|
362
352
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
353
|
+
@media (prefers-reduced-motion) {
|
|
354
|
+
.sterling-select {
|
|
355
|
+
transition: none;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
366
358
|
</style>
|