@insymetri/styleguide 0.1.26 → 0.1.28
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/dist/IIButton/IIButton.svelte +1 -1
- package/dist/IICombobox/IICombobox.svelte +7 -0
- package/dist/IICombobox/IICombobox.svelte.d.ts +1 -0
- package/dist/IIDateInput/IIDateInput.svelte +2 -2
- package/dist/IIIconButton/IIIconButton.svelte +1 -1
- package/dist/IIInput/IIInput.svelte +2 -2
- package/dist/IISegmentedControl/IISegmentedControl.svelte +73 -19
- package/dist/IISegmentedControl/IISegmentedControl.svelte.d.ts +0 -1
- package/dist/IISegmentedControl/IISegmentedControlStories.svelte +10 -26
- package/dist/IISwitch/IISwitch.svelte +1 -1
- package/dist/IIToggle/IIToggle.svelte +1 -1
- package/dist/MobileOnboarding/LoginFlowBare.svelte +13 -2
- package/dist/MobileOnboarding/LoginFlowBareAlt.svelte +968 -0
- package/dist/MobileOnboarding/LoginFlowBareAlt.svelte.d.ts +3 -0
- package/dist/MobileOnboarding/LoginScreenBare.svelte +84 -67
- package/dist/MobileOnboarding/LoginScreenBare.svelte.d.ts +4 -0
- package/dist/MobileOnboarding/OTPScreenBare.svelte +196 -125
- package/dist/MobileOnboarding/OTPScreenBare.svelte.d.ts +4 -0
- package/dist/style/themes.css +145 -0
- package/package.json +1 -1
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
const isDisabled = $derived(disabled || loading)
|
|
40
40
|
|
|
41
41
|
const baseClasses =
|
|
42
|
-
'inline-flex items-center justify-center gap-8 whitespace-nowrap cursor-default transition-colors duration-base ease-in-out no-underline disabled:cursor-not-allowed'
|
|
42
|
+
'inline-flex items-center justify-center gap-8 whitespace-nowrap cursor-default transition-colors duration-base ease-in-out no-underline outline-none focus-visible:border-accent focus-visible:ring-3 focus-visible:ring-primary disabled:cursor-not-allowed'
|
|
43
43
|
|
|
44
44
|
const variantClasses = {
|
|
45
45
|
primary:
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
emptyContent?: Snippet
|
|
37
37
|
// Grouped items (alternative to flat items)
|
|
38
38
|
groups?: Group<T>[]
|
|
39
|
+
openOnFocus?: boolean
|
|
39
40
|
// CSS classes
|
|
40
41
|
class?: string
|
|
41
42
|
contentClass?: string
|
|
@@ -54,6 +55,7 @@
|
|
|
54
55
|
renderItem,
|
|
55
56
|
emptyContent,
|
|
56
57
|
groups,
|
|
58
|
+
openOnFocus = false,
|
|
57
59
|
class: className,
|
|
58
60
|
contentClass,
|
|
59
61
|
}: Props<T> = $props()
|
|
@@ -135,6 +137,10 @@
|
|
|
135
137
|
inputValue = e.currentTarget.value
|
|
136
138
|
}
|
|
137
139
|
|
|
140
|
+
function handleFocus() {
|
|
141
|
+
open = true
|
|
142
|
+
}
|
|
143
|
+
|
|
138
144
|
// Check if item looks like a SimpleItem for default rendering
|
|
139
145
|
function isSimpleItem(item: T): item is T & SimpleItem {
|
|
140
146
|
return typeof item === 'object' && item !== null && 'label' in item && 'value' in item
|
|
@@ -182,6 +188,7 @@
|
|
|
182
188
|
{placeholder}
|
|
183
189
|
{disabled}
|
|
184
190
|
oninput={handleInput}
|
|
191
|
+
onfocus={openOnFocus ? handleFocus : undefined}
|
|
185
192
|
class={cn(
|
|
186
193
|
'w-full box-border py-5 px-12 text-input-text bg-input-bg border border-input-border transition-all duration-fast outline-none placeholder:text-input-placeholder hover:border-input-border-hover focus:border-input-border-hover disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-input-bg-disabled motion-reduce:transition-none',
|
|
187
194
|
densityClasses[density.value]
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
{/if}
|
|
48
48
|
<DatePicker.Input
|
|
49
49
|
class={cn(
|
|
50
|
-
'flex items-center gap-4 px-12 border bg-input-bg border-input-border transition-all duration-fast hover:border-input-border-hover [&:has(:focus)]:border-
|
|
50
|
+
'flex items-center gap-4 px-12 border bg-input-bg border-input-border transition-all duration-fast hover:border-input-border-hover [&:has(:focus)]:border-accent [&:has(:focus)]:ring-3 [&:has(:focus)]:ring-primary motion-reduce:transition-none',
|
|
51
51
|
densityClasses[density.value],
|
|
52
|
-
showError && 'border-input-border-error [&:has(:focus)]:border-input-border-error',
|
|
52
|
+
showError && 'border-input-border-error [&:has(:focus)]:border-input-border-error [&:has(:focus)]:ring-error',
|
|
53
53
|
disabled && 'bg-input-bg-disabled cursor-not-allowed'
|
|
54
54
|
)}
|
|
55
55
|
>
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
const isDisabled = $derived(disabled || loading)
|
|
31
31
|
|
|
32
32
|
const baseClasses =
|
|
33
|
-
'inline-flex items-center justify-center cursor-default transition-colors duration-base ease-in-out disabled:cursor-not-allowed'
|
|
33
|
+
'inline-flex items-center justify-center cursor-default transition-colors duration-base ease-in-out outline-none focus-visible:ring-3 focus-visible:ring-primary disabled:cursor-not-allowed'
|
|
34
34
|
|
|
35
35
|
const variantClasses = {
|
|
36
36
|
primary:
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
{#if hasAddons}
|
|
72
72
|
<div
|
|
73
73
|
class={cn(
|
|
74
|
-
'flex items-center bg-input-bg border border-
|
|
74
|
+
'flex items-center bg-input-bg border border-button-secondary transition-all duration-fast hover:border-button-secondary-hover focus-within:border-button-secondary-hover motion-reduce:transition-none',
|
|
75
75
|
densityClasses[density.value],
|
|
76
76
|
showError && 'border-input-border-error focus-within:border-input-border-error',
|
|
77
77
|
shouldShake && 'animate-shake',
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
{type}
|
|
118
118
|
{disabled}
|
|
119
119
|
class={cn(
|
|
120
|
-
'py-5 px-12 font-[family-name:var(--font-family)] text-input-text bg-input-bg border border-
|
|
120
|
+
'py-5 px-12 font-[family-name:var(--font-family)] text-input-text bg-input-bg border border-button-secondary transition-all duration-fast outline-none w-full box-border placeholder:text-input-placeholder hover:border-button-secondary-hover focus:border-accent focus:ring-3 focus:ring-primary disabled:bg-input-bg-disabled disabled:text-input-text-disabled disabled:cursor-not-allowed motion-reduce:transition-none motion-reduce:animate-none',
|
|
121
121
|
densityClasses[density.value],
|
|
122
122
|
showError && 'border-input-border-error focus:border-input-border-error focus:ring-error',
|
|
123
123
|
shouldShake && 'animate-shake'
|
|
@@ -12,49 +12,103 @@
|
|
|
12
12
|
items: Item[]
|
|
13
13
|
value: string
|
|
14
14
|
onValueChange?: (value: string) => void
|
|
15
|
-
size?: 'sm' | 'md'
|
|
16
15
|
class?: string
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
let {items, value = $bindable(), onValueChange,
|
|
18
|
+
let {items, value = $bindable(), onValueChange, class: className}: Props = $props()
|
|
20
19
|
|
|
21
20
|
const density = useDensity()
|
|
22
21
|
|
|
23
|
-
const
|
|
24
|
-
compact: '
|
|
25
|
-
default: '
|
|
26
|
-
comfortable: '
|
|
27
|
-
mobile: '
|
|
22
|
+
const densityHeight = {
|
|
23
|
+
compact: 'h-28',
|
|
24
|
+
default: 'h-32',
|
|
25
|
+
comfortable: 'h-40',
|
|
26
|
+
mobile: 'h-48',
|
|
28
27
|
} as const
|
|
29
28
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
const densityClasses = {
|
|
30
|
+
compact: 'px-8 text-tiny',
|
|
31
|
+
default: 'px-8 text-small',
|
|
32
|
+
comfortable: 'px-12 text-small',
|
|
33
|
+
mobile: 'px-8 text-small',
|
|
33
34
|
} as const
|
|
34
35
|
|
|
36
|
+
const thumbInset = {
|
|
37
|
+
compact: 2,
|
|
38
|
+
default: 2,
|
|
39
|
+
comfortable: 3,
|
|
40
|
+
mobile: 3,
|
|
41
|
+
} as const
|
|
42
|
+
|
|
43
|
+
const activeIndex = $derived(items.findIndex((item) => item.value === value))
|
|
44
|
+
|
|
35
45
|
function select(v: string) {
|
|
36
46
|
value = v
|
|
37
47
|
onValueChange?.(v)
|
|
38
48
|
}
|
|
39
49
|
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
|
|
50
|
+
function cycle(direction: 1 | -1) {
|
|
51
|
+
const nextIndex = (activeIndex + direction + items.length) % items.length
|
|
52
|
+
select(items[nextIndex].value)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function handleKeydown(e: KeyboardEvent) {
|
|
56
|
+
if (e.key === ' ' || e.key === 'Enter') {
|
|
57
|
+
e.preventDefault()
|
|
58
|
+
cycle(1)
|
|
59
|
+
} else if (e.key === 'ArrowRight' || e.key === 'ArrowDown') {
|
|
60
|
+
e.preventDefault()
|
|
61
|
+
cycle(1)
|
|
62
|
+
} else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') {
|
|
63
|
+
e.preventDefault()
|
|
64
|
+
cycle(-1)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getThumbColor(item: Item | undefined): string {
|
|
69
|
+
if (item?.variant === 'danger') return 'var(--color-error, #ef4444)'
|
|
70
|
+
return 'var(--ii-primary-15, rgba(17, 115, 212, 0.15))'
|
|
43
71
|
}
|
|
44
72
|
</script>
|
|
45
73
|
|
|
46
|
-
<div
|
|
74
|
+
<div
|
|
75
|
+
class={cn(
|
|
76
|
+
'relative inline-flex bg-input-bg border border-button-secondary rounded-control outline-none focus-visible:ring-3 focus-visible:ring-primary cursor-default',
|
|
77
|
+
densityHeight[density.value],
|
|
78
|
+
className
|
|
79
|
+
)}
|
|
80
|
+
role="radiogroup"
|
|
81
|
+
tabindex="0"
|
|
82
|
+
onkeydown={handleKeydown}
|
|
83
|
+
style="padding: {thumbInset[density.value]}px;"
|
|
84
|
+
>
|
|
85
|
+
<!-- Sliding thumb -->
|
|
86
|
+
<div
|
|
87
|
+
class="absolute"
|
|
88
|
+
style:border-radius="calc(var(--ii-radius-control) - {thumbInset[density.value]}px)"
|
|
89
|
+
style="
|
|
90
|
+
top: {thumbInset[density.value]}px;
|
|
91
|
+
bottom: {thumbInset[density.value]}px;
|
|
92
|
+
left: calc({thumbInset[density.value]}px + {activeIndex} * (100% - {thumbInset[density.value] * 2}px) / {items.length});
|
|
93
|
+
width: calc((100% - {thumbInset[density.value] * 2}px) / {items.length});
|
|
94
|
+
background: {getThumbColor(items[activeIndex])};
|
|
95
|
+
transition: left 300ms cubic-bezier(0.4, 0, 0.2, 1);
|
|
96
|
+
"
|
|
97
|
+
></div>
|
|
98
|
+
|
|
47
99
|
{#each items as item (item.value)}
|
|
48
100
|
{@const isActive = value === item.value}
|
|
49
101
|
<button
|
|
50
102
|
type="button"
|
|
103
|
+
tabindex="-1"
|
|
51
104
|
class={cn(
|
|
52
|
-
'border-none font-medium cursor-default whitespace-nowrap text-center
|
|
53
|
-
|
|
54
|
-
isActive ?
|
|
105
|
+
'relative z-10 flex-1 border-none font-medium cursor-default whitespace-nowrap text-center outline-none bg-transparent',
|
|
106
|
+
densityClasses[density.value],
|
|
107
|
+
isActive ? 'text-primary' : 'text-secondary hover:text-body'
|
|
55
108
|
)}
|
|
56
|
-
style="transition:
|
|
57
|
-
|
|
109
|
+
style="transition: color var(--transition-fast)"
|
|
110
|
+
role="radio"
|
|
111
|
+
aria-checked={isActive}
|
|
58
112
|
onclick={() => select(item.value)}
|
|
59
113
|
>
|
|
60
114
|
{item.label}
|
|
@@ -62,32 +62,16 @@
|
|
|
62
62
|
/>
|
|
63
63
|
</section>
|
|
64
64
|
|
|
65
|
-
<!--
|
|
65
|
+
<!-- Density-responsive -->
|
|
66
66
|
<section>
|
|
67
|
-
<h2 class="text-default-emphasis text-primary mb-8">
|
|
68
|
-
<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
]}
|
|
77
|
-
value="on"
|
|
78
|
-
/>
|
|
79
|
-
</div>
|
|
80
|
-
<div class="flex flex-col items-start gap-4">
|
|
81
|
-
<span class="text-tiny text-secondary">md</span>
|
|
82
|
-
<IISegmentedControl
|
|
83
|
-
size="md"
|
|
84
|
-
items={[
|
|
85
|
-
{label: 'On', value: 'on'},
|
|
86
|
-
{label: 'Off', value: 'off'},
|
|
87
|
-
]}
|
|
88
|
-
value="on"
|
|
89
|
-
/>
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
67
|
+
<h2 class="text-default-emphasis text-primary mb-8">Density Responsive</h2>
|
|
68
|
+
<p class="text-small text-secondary mb-12">Sizing follows the density provider context.</p>
|
|
69
|
+
<IISegmentedControl
|
|
70
|
+
items={[
|
|
71
|
+
{label: 'On', value: 'on'},
|
|
72
|
+
{label: 'Off', value: 'off'},
|
|
73
|
+
]}
|
|
74
|
+
value="on"
|
|
75
|
+
/>
|
|
92
76
|
</section>
|
|
93
77
|
</div>
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
</span>
|
|
43
43
|
{/if}
|
|
44
44
|
<Switch.Root
|
|
45
|
-
class="group relative w-44 h-24 bg-muted rounded-full cursor-default transition-all duration-fast shrink-0 appearance-none border-none data-[state=checked]:bg-primary data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 motion-reduce:transition-none"
|
|
45
|
+
class="group relative w-44 h-24 bg-muted rounded-full cursor-default transition-all duration-fast shrink-0 appearance-none border-none outline-none focus-visible:ring-3 focus-visible:ring-primary data-[state=checked]:bg-primary data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 motion-reduce:transition-none"
|
|
46
46
|
{checked}
|
|
47
47
|
onCheckedChange={newChecked => {
|
|
48
48
|
checked = newChecked
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
{disabled}
|
|
56
56
|
aria-label={ariaLabel}
|
|
57
57
|
class={cn(
|
|
58
|
-
'inline-flex items-center justify-center cursor-default transition-colors duration-base ease-in-out text-secondary hover:bg-button-ghost-hover hover:text-button-ghost-hover data-[state=on]:bg-button-ghost-hover data-[state=on]:text-body disabled:opacity-50 disabled:cursor-not-allowed',
|
|
58
|
+
'inline-flex items-center justify-center cursor-default transition-colors duration-base ease-in-out outline-none focus-visible:ring-3 focus-visible:ring-primary text-secondary hover:bg-button-ghost-hover hover:text-button-ghost-hover data-[state=on]:bg-button-ghost-hover data-[state=on]:text-body disabled:opacity-50 disabled:cursor-not-allowed',
|
|
59
59
|
resolvedSizeClasses,
|
|
60
60
|
iconSizeClasses[size],
|
|
61
61
|
className
|
|
@@ -4,16 +4,27 @@
|
|
|
4
4
|
import StepIndicator from './StepIndicator.svelte'
|
|
5
5
|
|
|
6
6
|
let step: 'email' | 'otp' = $state('email')
|
|
7
|
+
let transitioning = $state(false)
|
|
8
|
+
|
|
9
|
+
const FADE_DURATION = 200
|
|
10
|
+
|
|
11
|
+
function transitionTo(newStep: 'email' | 'otp') {
|
|
12
|
+
transitioning = true
|
|
13
|
+
setTimeout(() => {
|
|
14
|
+
step = newStep
|
|
15
|
+
transitioning = false
|
|
16
|
+
}, FADE_DURATION)
|
|
17
|
+
}
|
|
7
18
|
</script>
|
|
8
19
|
|
|
9
20
|
{#if step === 'email'}
|
|
10
|
-
<LoginScreenBare onContinue={() => (
|
|
21
|
+
<LoginScreenBare onContinue={() => transitionTo('otp')} hideStepIndicator {transitioning}>
|
|
11
22
|
{#snippet stepIndicator()}
|
|
12
23
|
<StepIndicator current={step === 'email' ? 0 : 1} total={2} />
|
|
13
24
|
{/snippet}
|
|
14
25
|
</LoginScreenBare>
|
|
15
26
|
{:else}
|
|
16
|
-
<OTPScreenBare onBack={() => (
|
|
27
|
+
<OTPScreenBare onBack={() => transitionTo('email')} hideStepIndicator {transitioning}>
|
|
17
28
|
{#snippet stepIndicator()}
|
|
18
29
|
<StepIndicator current={step === 'email' ? 0 : 1} total={2} />
|
|
19
30
|
{/snippet}
|