|
1 | 1 | <script lang="ts"> |
| 2 | + import { fade } from 'svelte/transition'; |
| 3 | +
|
2 | 4 | import DemoElevationPicker from '../utils/DemoElevationPicker.svelte'; |
3 | 5 | import SphereBackdrop from '../utils/SphereBackdrop.svelte'; |
4 | 6 |
|
|
11 | 13 | import NeoInput from '~/inputs/NeoInput.svelte'; |
12 | 14 | import NeoNumberStep from '~/inputs/NeoNumberStep.svelte'; |
13 | 15 | import NeoPassword from '~/inputs/NeoPassword.svelte'; |
| 16 | + import NeoPin from '~/inputs/NeoPin.svelte'; |
14 | 17 | import NeoTextArea from '~/inputs/NeoTextarea.svelte'; |
15 | 18 | import { DefaultShadowElevation, MaxShadowElevation, MinShadowElevation } from '~/utils/shadow.utils'; |
16 | 19 |
|
|
26 | 29 | touched = $state(false); |
27 | 30 | dirty = $state(false); |
28 | 31 | valid = $state(undefined); |
29 | | - value = $state(''); |
| 32 | + value = $state<string | number>(''); |
| 33 | +
|
| 34 | + constructor({ |
| 35 | + touched = false, |
| 36 | + dirty = false, |
| 37 | + valid = undefined, |
| 38 | + value = '', |
| 39 | + }: { |
| 40 | + touched?: boolean; |
| 41 | + dirty?: boolean; |
| 42 | + valid?: boolean; |
| 43 | + value?: string | number; |
| 44 | + } = {}) { |
| 45 | + this.touched = touched; |
| 46 | + this.dirty = dirty; |
| 47 | + this.valid = valid; |
| 48 | + this.value = value; |
| 49 | + } |
30 | 50 |
|
31 | 51 | clear() { |
32 | 52 | this.touched = false; |
|
64 | 84 | const invalidState = new ValidationState(); |
65 | 85 | const customState = new ValidationState(); |
66 | 86 |
|
| 87 | + const numberState = new ValidationState({ value: 0 }); |
| 88 | +
|
| 89 | + const pinState = new ValidationState(); |
| 90 | + const pinStateSeparator = new ValidationState(); |
| 91 | + const pinPasswordState = new ValidationState(); |
| 92 | +
|
67 | 93 | const onClear = () => { |
68 | 94 | validation.clear(); |
69 | 95 | validState.clear(); |
70 | 96 | invalidState.clear(); |
| 97 | + customState.clear(); |
| 98 | +
|
| 99 | + pinState.clear(); |
| 100 | + pinStateSeparator.clear(); |
| 101 | + pinPasswordState.clear(); |
71 | 102 | }; |
72 | 103 |
|
73 | 104 | const onclick = (e: MouseEvent) => console.info('suffix click', e); |
|
329 | 360 | {/if} |
330 | 361 | {/snippet} |
331 | 362 |
|
332 | | -{#snippet validationState({ touched, dirty, valid }: ValidationState)} |
| 363 | +{#snippet validationState({ touched, dirty, valid, value }: ValidationState, show = false)} |
333 | 364 | <div class="row"> |
334 | 365 | <div class="label">Touched: {touched}</div> |
335 | 366 | <div class="label">Dirty: {dirty}</div> |
336 | 367 | <div class="label">Valid: {valid}</div> |
| 368 | + {#if show} |
| 369 | + <div class="label">Value: {value}</div> |
| 370 | + {/if} |
337 | 371 | </div> |
338 | 372 | {/snippet} |
339 | 373 |
|
|
348 | 382 | </div> |
349 | 383 | {/each} |
350 | 384 | </div> |
| 385 | +</form> |
351 | 386 |
|
352 | | - <div class="row"> |
353 | | - {#each validationColumns as column} |
354 | | - <div class="column content"> |
355 | | - <span class="label">{column.label}</span> |
356 | | - {@render validationState(column.state)} |
357 | | - {@render group(column)} |
358 | | - </div> |
359 | | - {/each} |
360 | | - </div> |
361 | | - |
362 | | - <div class="row"> |
| 387 | +<!-- Password --> |
| 388 | +<div class="row"> |
| 389 | + {#each validationColumns as column} |
363 | 390 | <div class="column content"> |
364 | | - <span class="label">Password</span> |
365 | | - {#if options.glass} |
366 | | - <SphereBackdrop> |
367 | | - <NeoPassword label="Password" auto-complete="current-password" {...options} /> |
368 | | - </SphereBackdrop> |
369 | | - {:else} |
370 | | - <NeoPassword label="Password" auto-complete="current-password" {...options} /> |
371 | | - {/if} |
| 391 | + <span class="label">{column.label}</span> |
| 392 | + {@render validationState(column.state)} |
| 393 | + {@render group(column)} |
372 | 394 | </div> |
| 395 | + {/each} |
| 396 | +</div> |
| 397 | + |
| 398 | +<div class="row"> |
| 399 | + <div class="column content"> |
| 400 | + <span class="label">Password</span> |
| 401 | + {#if options.glass} |
| 402 | + <SphereBackdrop> |
| 403 | + <NeoPassword label="Password" autocomplete="current-password" {...options} /> |
| 404 | + </SphereBackdrop> |
| 405 | + {:else} |
| 406 | + <NeoPassword in={fade} label="Password" autocomplete="current-password" {...options} /> |
| 407 | + {/if} |
373 | 408 | </div> |
| 409 | +</div> |
374 | 410 |
|
375 | | - <div class="row"> |
376 | | - <div class="column content"> |
377 | | - <span class="label">Number</span> |
378 | | - {#if options.glass} |
379 | | - <SphereBackdrop> |
380 | | - <NeoNumberStep {...options} /> |
381 | | - </SphereBackdrop> |
382 | | - {:else} |
383 | | - <NeoNumberStep {...options} /> |
384 | | - {/if} |
385 | | - </div> |
| 411 | +<!-- Number inputs --> |
| 412 | +<div class="row"> |
| 413 | + <div class="column content"> |
| 414 | + <span class="label">Number</span> |
| 415 | + {@render validationState(numberState)} |
| 416 | + {#if options.glass} |
| 417 | + <SphereBackdrop> |
| 418 | + <NeoNumberStep |
| 419 | + bind:touched={numberState.touched} |
| 420 | + bind:dirty={numberState.dirty} |
| 421 | + bind:valid={numberState.valid} |
| 422 | + bind:value={numberState.value} |
| 423 | + {...options} |
| 424 | + /> |
| 425 | + </SphereBackdrop> |
| 426 | + {:else} |
| 427 | + <NeoNumberStep |
| 428 | + bind:touched={numberState.touched} |
| 429 | + bind:dirty={numberState.dirty} |
| 430 | + bind:valid={numberState.valid} |
| 431 | + bind:value={numberState.value} |
| 432 | + {...options} |
| 433 | + /> |
| 434 | + {/if} |
| 435 | + </div> |
386 | 436 |
|
387 | | - <div class="column content"> |
388 | | - <span class="label">Min Max</span> |
389 | | - {#if options.glass} |
390 | | - <SphereBackdrop> |
391 | | - <NeoNumberStep min="-5" max="5" {...options} /> |
392 | | - </SphereBackdrop> |
393 | | - {:else} |
394 | | - <NeoNumberStep min="-5" max="5" {...options} /> |
395 | | - {/if} |
396 | | - </div> |
| 437 | + <div class="column content"> |
| 438 | + <span class="label">Min Max</span> |
| 439 | + {@render validationState(numberState)} |
| 440 | + {#if options.glass} |
| 441 | + <SphereBackdrop> |
| 442 | + <NeoNumberStep |
| 443 | + bind:touched={numberState.touched} |
| 444 | + bind:dirty={numberState.dirty} |
| 445 | + bind:valid={numberState.valid} |
| 446 | + bind:value={numberState.value} |
| 447 | + min="-5" |
| 448 | + max="5" |
| 449 | + {...options} |
| 450 | + /> |
| 451 | + </SphereBackdrop> |
| 452 | + {:else} |
| 453 | + <NeoNumberStep |
| 454 | + bind:touched={numberState.touched} |
| 455 | + bind:dirty={numberState.dirty} |
| 456 | + bind:valid={numberState.valid} |
| 457 | + bind:value={numberState.value} |
| 458 | + min="-5" |
| 459 | + max="5" |
| 460 | + {...options} |
| 461 | + /> |
| 462 | + {/if} |
397 | 463 | </div> |
398 | | -</form> |
| 464 | +</div> |
| 465 | + |
| 466 | +<!-- Number inputs --> |
| 467 | +<div class="row"> |
| 468 | + <div class="column content"> |
| 469 | + <span class="label">Pin</span> |
| 470 | + {@render validationState(pinState, true)} |
| 471 | + {#if options.glass} |
| 472 | + <SphereBackdrop> |
| 473 | + <NeoPin bind:touched={pinState.touched} bind:dirty={pinState.dirty} bind:valid={pinState.valid} bind:value={pinState.value} {...options} /> |
| 474 | + </SphereBackdrop> |
| 475 | + {:else} |
| 476 | + <NeoPin bind:touched={pinState.touched} bind:dirty={pinState.dirty} bind:valid={pinState.valid} bind:value={pinState.value} {...options} /> |
| 477 | + {/if} |
| 478 | + </div> |
| 479 | + |
| 480 | + <div class="column content"> |
| 481 | + <span class="label">Pin Groups</span> |
| 482 | + {@render validationState(pinStateSeparator, true)} |
| 483 | + {#if options.glass} |
| 484 | + <SphereBackdrop> |
| 485 | + <NeoPin |
| 486 | + groups={2} |
| 487 | + bind:touched={pinStateSeparator.touched} |
| 488 | + bind:dirty={pinStateSeparator.dirty} |
| 489 | + bind:valid={pinStateSeparator.valid} |
| 490 | + bind:value={pinStateSeparator.value} |
| 491 | + {...options} |
| 492 | + /> |
| 493 | + </SphereBackdrop> |
| 494 | + {:else} |
| 495 | + <NeoPin |
| 496 | + groups={2} |
| 497 | + bind:touched={pinStateSeparator.touched} |
| 498 | + bind:dirty={pinStateSeparator.dirty} |
| 499 | + bind:valid={pinStateSeparator.valid} |
| 500 | + bind:value={pinStateSeparator.value} |
| 501 | + {...options} |
| 502 | + /> |
| 503 | + {/if} |
| 504 | + </div> |
| 505 | + |
| 506 | + <div class="column content"> |
| 507 | + <span class="label">Pin Password</span> |
| 508 | + {@render validationState(pinPasswordState, true)} |
| 509 | + {#if options.glass} |
| 510 | + <SphereBackdrop> |
| 511 | + <NeoPin |
| 512 | + bind:touched={pinPasswordState.touched} |
| 513 | + bind:dirty={pinPasswordState.dirty} |
| 514 | + bind:valid={pinPasswordState.valid} |
| 515 | + bind:value={pinPasswordState.value} |
| 516 | + type="password" |
| 517 | + {...options} |
| 518 | + /> |
| 519 | + </SphereBackdrop> |
| 520 | + {:else} |
| 521 | + <NeoPin |
| 522 | + bind:touched={pinPasswordState.touched} |
| 523 | + bind:dirty={pinPasswordState.dirty} |
| 524 | + bind:valid={pinPasswordState.valid} |
| 525 | + bind:value={pinPasswordState.value} |
| 526 | + type="password" |
| 527 | + {...options} |
| 528 | + /> |
| 529 | + {/if} |
| 530 | + </div> |
| 531 | +</div> |
399 | 532 |
|
400 | 533 | <style lang="scss"> |
401 | 534 | @use 'src/lib/styles/common/flex' as flex; |
|
417 | 550 | &.content { |
418 | 551 | flex: 1 0 20%; |
419 | 552 | max-width: 25%; |
| 553 | +
|
| 554 | + :global(.neo-pin-container) { |
| 555 | + container-type: inline-size; |
| 556 | + width: 100%; |
| 557 | + } |
| 558 | +
|
| 559 | + :global(.neo-pin-separator) { |
| 560 | + @container (width > 500px) { |
| 561 | + width: 100%; |
| 562 | + } |
| 563 | + } |
420 | 564 | } |
421 | 565 | } |
422 | 566 |
|
|
0 commit comments