@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.
@@ -1,8 +1,10 @@
1
1
  <script>import { createEventDispatcher, onMount, tick } from "svelte";
2
- import { v4 as uuidv4 } from "uuid";
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 = uuidv4();
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
- bind:this={selectRef}
144
- use:clickOutside
145
- aria-controls={popupId}
146
- aria-haspopup="listbox"
147
- aria-expanded={open}
148
- class="sterling-select"
149
- class:disabled
150
- role="combobox"
151
- tabindex="0"
152
- on:click_outside={() => (open = false)}
153
- on:click={onSelectClick}
154
- on:blur
155
- on:click
156
- on:copy
157
- on:cut
158
- on:dblclick
159
- on:focus
160
- on:focusin
161
- on:focusout
162
- on:keydown={onSelectKeydown}
163
- on:keydown
164
- on:keypress
165
- on:keyup
166
- on:mousedown
167
- on:mouseenter
168
- on:mouseleave
169
- on:mousemove
170
- on:mouseover
171
- on:mouseout
172
- on:mouseup
173
- on:wheel
174
- on:paste
175
- {...$$restProps}
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
- <!-- svelte-ignore a11y-label-has-associated-control -->
178
- <label class="sterling-select-label">
179
- {#if $$slots.label}
180
- <div class="label-content" class:disabled>
181
- <slot name="label" />
182
- </div>
183
- {/if}
184
- <div class="input">
185
- <div class="value">
186
- <slot name="value">
187
- {items[selectedIndex]}
188
- </slot>
189
- </div>
190
- <div class="button">
191
- <slot name="button" {open}>
192
- <div class="chevron" />
193
- </slot>
194
- </div>
195
- </div>
196
- </label>
197
- <div
198
- bind:this={popupRef}
199
- class="popup"
200
- class:open
201
- id={popupId}
202
- style="left:{popupPosition.x}px; top:{popupPosition.y}px"
203
- >
204
- <div class="popup-content">
205
- <slot name="list">
206
- {#if $$slots.default === true}
207
- <List
208
- bind:this={listRef}
209
- selectedIndex={pendingSelectedIndex}
210
- {items}
211
- {disabled}
212
- let:disabled
213
- let:index
214
- let:item
215
- let:selected
216
- on:click={onListClick}
217
- on:keydown={onListKeydown}
218
- on:itemSelected={onPendingItemSelected}
219
- >
220
- <slot {disabled} {index} {item} {selected} />
221
- </List>
222
- {:else}
223
- <List
224
- bind:this={listRef}
225
- selectedIndex={pendingSelectedIndex}
226
- {items}
227
- {disabled}
228
- let:disabled
229
- let:index
230
- let:item
231
- let:selected
232
- on:click={onListClick}
233
- on:keydown={onListKeydown}
234
- on:itemSelected={onPendingItemSelected}
235
- />
236
- {/if}
237
- </slot>
238
- </div>
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
- sterling-select
245
- sterling-select-label
246
- label-content
247
- input
248
- value
249
- button
250
- (popup)
251
- */
252
- .sterling-select {
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
- .sterling-select:focus-within {
270
- background-color: var(--Input__background-color--focus);
271
- border-color: var(--Input__border-color--focus);
272
- color: var(--Input__color--focus);
273
- outline-color: var(--Common__outline-color);
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
- .sterling-select.disabled {
280
- background-color: var(--Input__background-color--disabled);
281
- border-color: var(---Input__border-color--disabled);
282
- color: var(--Input__color--disabled);
283
- cursor: not-allowed;
284
- outline: none;
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
- .label-content {
288
- font-size: 0.7em;
289
- margin: 0.5em 0.7em 0 0.7em;
290
- color: var(--Display__color--subtle);
291
- transition: background-color 250ms, color 250ms, border-color 250ms;
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
- .label-content.disabled {
295
- color: var(--Display__color--disabled);
296
- }
279
+ .label {
280
+ font-size: 0.7em;
281
+ margin: 0.5em 0.7em 0 0.7em;
282
+ }
297
283
 
298
- .input {
299
- display: grid;
300
- grid-template-columns: 1fr auto;
301
- grid-template-rows: auto;
302
- align-content: center;
303
- align-items: center;
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
- .value {
307
- padding: 0.5em;
308
- }
292
+ .value {
293
+ padding: 0.5em;
294
+ }
309
295
 
310
- .chevron {
311
- display: block;
312
- position: relative;
313
- border: none;
314
- background: none;
315
- margin: 0;
316
- height: 100%;
317
- width: 32px;
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
- .chevron::after {
321
- position: absolute;
322
- content: '';
323
- top: 50%;
324
- left: 50%;
325
- width: 7px;
326
- height: 7px;
327
- border-right: 3px solid currentColor;
328
- border-top: 3px solid currentColor;
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
- transform: translate(-50%, calc(-50% / 0.707)) rotate(135deg);
343
- transform-origin: 50% 50%;
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
- .popup {
347
- box-sizing: border-box;
348
- display: none;
349
- overflow: hidden;
350
- position: absolute;
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
- .popup.open {
358
- display: grid;
359
- grid-template-columns: 1fr;
360
- grid-template-rows: 1fr;
361
- }
349
+ .popup-content {
350
+ max-height: 15em;
351
+ }
362
352
 
363
- .popup-content {
364
- max-height: 15em;
365
- }
353
+ @media (prefers-reduced-motion) {
354
+ .sterling-select {
355
+ transition: none;
356
+ }
357
+ }
366
358
  </style>