@insymetri/styleguide 0.1.23 → 0.1.24

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.
Files changed (76) hide show
  1. package/dist/DensityProvider/DensityProvider.svelte +16 -0
  2. package/dist/DensityProvider/DensityProvider.svelte.d.ts +9 -0
  3. package/dist/IIButton/IIButton.svelte +19 -7
  4. package/dist/IICombobox/IICombobox.svelte +14 -1
  5. package/dist/IICombobox/IIComboboxStories.svelte +1 -1
  6. package/dist/IIDateInput/IIDateInput.svelte +13 -2
  7. package/dist/IIDatePicker/IIDatePicker.svelte +11 -1
  8. package/dist/IIDropdownInput/IIDropdownInput.svelte +12 -1
  9. package/dist/IIIconButton/IIIconButton.svelte +18 -6
  10. package/dist/IIInput/IIInput.svelte +19 -7
  11. package/dist/IIMultiSelect/IIMultiSelect.svelte +12 -1
  12. package/dist/IIPillTabs/IIPillTabs.svelte +12 -1
  13. package/dist/IISegmentedControl/IISegmentedControl.svelte +11 -1
  14. package/dist/IITabs/IITabs.svelte +14 -1
  15. package/dist/IIToggle/IIToggle.svelte +19 -6
  16. package/dist/IIToggle/IIToggleStories.svelte +1 -1
  17. package/dist/Icons/Icons.svelte +1 -1
  18. package/dist/MobileOnboarding/ApplyFinancialScreen.svelte +189 -0
  19. package/dist/MobileOnboarding/ApplyFinancialScreen.svelte.d.ts +7 -0
  20. package/dist/MobileOnboarding/ApplyPersonalScreen.svelte +213 -0
  21. package/dist/MobileOnboarding/ApplyPersonalScreen.svelte.d.ts +7 -0
  22. package/dist/MobileOnboarding/DashboardScreen.svelte +191 -0
  23. package/dist/MobileOnboarding/DashboardScreen.svelte.d.ts +3 -0
  24. package/dist/MobileOnboarding/EsignScreen.svelte +103 -0
  25. package/dist/MobileOnboarding/EsignScreen.svelte.d.ts +6 -0
  26. package/dist/MobileOnboarding/LoginDesktopA.svelte +35 -0
  27. package/dist/MobileOnboarding/LoginDesktopA.svelte.d.ts +18 -0
  28. package/dist/MobileOnboarding/LoginDesktopB.svelte +35 -0
  29. package/dist/MobileOnboarding/LoginDesktopB.svelte.d.ts +18 -0
  30. package/dist/MobileOnboarding/LoginDesktopC.svelte +34 -0
  31. package/dist/MobileOnboarding/LoginDesktopC.svelte.d.ts +18 -0
  32. package/dist/MobileOnboarding/LoginDesktopD.svelte +33 -0
  33. package/dist/MobileOnboarding/LoginDesktopD.svelte.d.ts +18 -0
  34. package/dist/MobileOnboarding/LoginFlowBare.svelte +21 -0
  35. package/dist/MobileOnboarding/LoginFlowBare.svelte.d.ts +3 -0
  36. package/dist/MobileOnboarding/LoginScreen.svelte +97 -0
  37. package/dist/MobileOnboarding/LoginScreen.svelte.d.ts +6 -0
  38. package/dist/MobileOnboarding/LoginScreenBare.svelte +200 -0
  39. package/dist/MobileOnboarding/LoginScreenBare.svelte.d.ts +13 -0
  40. package/dist/MobileOnboarding/MobileFlow.svelte +103 -0
  41. package/dist/MobileOnboarding/MobileFlow.svelte.d.ts +3 -0
  42. package/dist/MobileOnboarding/MobileFrame.svelte +111 -0
  43. package/dist/MobileOnboarding/MobileFrame.svelte.d.ts +13 -0
  44. package/dist/MobileOnboarding/OTPScreen.svelte +208 -0
  45. package/dist/MobileOnboarding/OTPScreen.svelte.d.ts +7 -0
  46. package/dist/MobileOnboarding/OTPScreenBare.svelte +285 -0
  47. package/dist/MobileOnboarding/OTPScreenBare.svelte.d.ts +10 -0
  48. package/dist/MobileOnboarding/OfferSelectScreen.svelte +172 -0
  49. package/dist/MobileOnboarding/OfferSelectScreen.svelte.d.ts +6 -0
  50. package/dist/MobileOnboarding/ProfileScreen.svelte +189 -0
  51. package/dist/MobileOnboarding/ProfileScreen.svelte.d.ts +6 -0
  52. package/dist/MobileOnboarding/ReviewScreen.svelte +129 -0
  53. package/dist/MobileOnboarding/ReviewScreen.svelte.d.ts +7 -0
  54. package/dist/MobileOnboarding/StatusScreen.svelte +132 -0
  55. package/dist/MobileOnboarding/StatusScreen.svelte.d.ts +6 -0
  56. package/dist/MobileOnboarding/StepIndicator.svelte +33 -0
  57. package/dist/MobileOnboarding/StepIndicator.svelte.d.ts +7 -0
  58. package/dist/MobileOnboarding/current/ComparisonFlow.svelte +112 -0
  59. package/dist/MobileOnboarding/current/ComparisonFlow.svelte.d.ts +3 -0
  60. package/dist/MobileOnboarding/current/CurrentApplyScreen.svelte +211 -0
  61. package/dist/MobileOnboarding/current/CurrentApplyScreen.svelte.d.ts +7 -0
  62. package/dist/MobileOnboarding/current/CurrentFrame.svelte +110 -0
  63. package/dist/MobileOnboarding/current/CurrentFrame.svelte.d.ts +7 -0
  64. package/dist/MobileOnboarding/current/CurrentLoginScreen.svelte +168 -0
  65. package/dist/MobileOnboarding/current/CurrentLoginScreen.svelte.d.ts +6 -0
  66. package/dist/MobileOnboarding/current/CurrentProfileScreen.svelte +133 -0
  67. package/dist/MobileOnboarding/current/CurrentProfileScreen.svelte.d.ts +6 -0
  68. package/dist/Typography/Typography.svelte +2 -0
  69. package/dist/density/index.d.ts +13 -0
  70. package/dist/density/index.js +11 -0
  71. package/dist/index.d.ts +3 -0
  72. package/dist/index.js +5 -0
  73. package/dist/style/colors.css +1 -1
  74. package/dist/style/tailwind/typography.d.ts +8 -0
  75. package/dist/style/tailwind/typography.js +2 -0
  76. package/package.json +1 -1
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import type {Snippet} from 'svelte'
3
+ import {setContext} from 'svelte'
4
+ import {DENSITY_KEY, type Density} from '../density'
5
+
6
+ type Props = {
7
+ density?: Density
8
+ children: Snippet
9
+ }
10
+
11
+ let {density = 'default', children}: Props = $props()
12
+
13
+ setContext(DENSITY_KEY, {get current() { return density }})
14
+ </script>
15
+
16
+ {@render children()}
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from 'svelte';
2
+ import { type Density } from '../density';
3
+ type Props = {
4
+ density?: Density;
5
+ children: Snippet;
6
+ };
7
+ declare const DensityProvider: import("svelte").Component<Props, {}, "">;
8
+ type DensityProvider = ReturnType<typeof DensityProvider>;
9
+ export default DensityProvider;
@@ -4,6 +4,7 @@
4
4
  import type {IconName} from '../icons'
5
5
  import IIIcon from '../IIIcon/IIIcon.svelte'
6
6
  import {cn} from '../utils/cn'
7
+ import {useDensity} from '../density'
7
8
 
8
9
  type BaseProps = {
9
10
  variant?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'success' | 'accent'
@@ -34,10 +35,11 @@
34
35
  ...restProps
35
36
  }: Props = $props()
36
37
 
38
+ const density = useDensity()
37
39
  const isDisabled = $derived(disabled || loading)
38
40
 
39
41
  const baseClasses =
40
- 'inline-flex items-center justify-center gap-8 whitespace-nowrap rounded-control 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 disabled:cursor-not-allowed'
41
43
 
42
44
  const variantClasses = {
43
45
  primary:
@@ -53,10 +55,16 @@
53
55
  'bg-button-accent text-button-accent border-0 hover:bg-button-accent-hover disabled:bg-button-accent-disabled',
54
56
  } as const
55
57
 
56
- const sizeClasses = {
57
- sm: 'py-4 px-8 text-tiny h-24',
58
- md: 'py-5 px-12 text-small h-28',
59
- lg: 'py-10 px-16 text-large h-32',
58
+ const densityClasses = {
59
+ compact: 'h-28 py-4 px-8 text-tiny rounded-control',
60
+ default: 'h-32 py-5 px-12 text-small rounded-control',
61
+ comfortable: 'h-40 py-8 px-12 text-small rounded-control',
62
+ mobile: 'h-48 py-10 px-16 text-default rounded-control',
63
+ } as const
64
+
65
+ const fixedSizeClasses = {
66
+ sm: 'py-4 px-8 text-tiny h-24 rounded-control',
67
+ lg: 'py-10 px-16 text-large h-40 rounded-control',
60
68
  } as const
61
69
 
62
70
  const iconSizeClasses = {
@@ -64,6 +72,10 @@
64
72
  md: 'w-14 h-14',
65
73
  lg: 'w-16 h-16',
66
74
  } as const
75
+
76
+ const resolvedSizeClasses = $derived(
77
+ size === 'md' ? densityClasses[density.value] : fixedSizeClasses[size]
78
+ )
67
79
  </script>
68
80
 
69
81
  {#snippet iconContent()}
@@ -80,7 +92,7 @@
80
92
  <a
81
93
  bind:this={ref}
82
94
  {href}
83
- class={cn(baseClasses, variantClasses[variant], sizeClasses[size], className)}
95
+ class={cn(baseClasses, variantClasses[variant], resolvedSizeClasses, className)}
84
96
  {...restProps as HTMLAnchorAttributes}
85
97
  >
86
98
  {@render iconContent()}
@@ -89,7 +101,7 @@
89
101
  <button
90
102
  bind:this={ref}
91
103
  disabled={isDisabled}
92
- class={cn(baseClasses, variantClasses[variant], sizeClasses[size], className)}
104
+ class={cn(baseClasses, variantClasses[variant], resolvedSizeClasses, className)}
93
105
  {...restProps as HTMLButtonAttributes}
94
106
  >
95
107
  {@render iconContent()}
@@ -3,6 +3,7 @@
3
3
  import {Combobox} from 'bits-ui'
4
4
  import {IIIcon} from '../IIIcon'
5
5
  import {cn} from '../utils/cn'
6
+ import {useDensity} from '../density'
6
7
 
7
8
  // Simple default item type for basic usage
8
9
  type SimpleItem = {
@@ -57,6 +58,15 @@
57
58
  contentClass,
58
59
  }: Props<T> = $props()
59
60
 
61
+ const density = useDensity()
62
+
63
+ const densityClasses = {
64
+ compact: 'h-28 rounded-control text-tiny',
65
+ default: 'h-32 rounded-control text-small',
66
+ comfortable: 'h-40 rounded-control text-small',
67
+ mobile: 'h-48 rounded-control text-default',
68
+ } as const
69
+
60
70
  let inputValue = $state('')
61
71
  let open = $state(false)
62
72
 
@@ -162,7 +172,10 @@
162
172
  {placeholder}
163
173
  {disabled}
164
174
  oninput={handleInput}
165
- class="w-full box-border py-5 px-12 text-small text-input-text bg-input-bg border border-input-border rounded-control 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"
175
+ class={cn(
176
+ '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',
177
+ densityClasses[density.value]
178
+ )}
166
179
  />
167
180
  <Combobox.Portal>
168
181
  {#if filteredItems.length > 0 || emptyContent || loading}
@@ -87,7 +87,7 @@
87
87
  />
88
88
  </div>
89
89
  <button
90
- class="px-12 py-5 rounded-control border border-button-secondary text-small text-button-secondary hover:border-button-secondary-hover cursor-default"
90
+ class="px-12 py-5 rounded-8 border border-button-secondary text-small text-button-secondary hover:border-button-secondary-hover cursor-default"
91
91
  onclick={simulateLoading}
92
92
  >
93
93
  Simulate Load
@@ -4,6 +4,7 @@
4
4
  import {IIIcon} from '../IIIcon'
5
5
  import {IIIconButton} from '../IIIconButton'
6
6
  import {cn} from '../utils/cn'
7
+ import {useDensity} from '../density'
7
8
 
8
9
  type Props = {
9
10
  value: DateValue | undefined
@@ -27,6 +28,15 @@
27
28
  class: className,
28
29
  }: Props = $props()
29
30
 
31
+ const density = useDensity()
32
+
33
+ const densityClasses = {
34
+ compact: 'h-28 rounded-control text-tiny',
35
+ default: 'h-32 rounded-control text-small',
36
+ comfortable: 'h-40 rounded-control text-small',
37
+ mobile: 'h-48 rounded-control text-default',
38
+ } as const
39
+
30
40
  const showError = $derived(error || !!errorMessage)
31
41
  </script>
32
42
 
@@ -37,7 +47,8 @@
37
47
  {/if}
38
48
  <DatePicker.Input
39
49
  class={cn(
40
- 'flex items-center gap-4 py-5 px-12 border rounded-control text-small bg-input-bg border-input-border transition-all duration-fast hover:border-input-border-hover [&:has(:focus)]:border-input-border-hover motion-reduce:transition-none',
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-input-border-hover motion-reduce:transition-none',
51
+ densityClasses[density.value],
41
52
  showError && 'border-input-border-error [&:has(:focus)]:border-input-border-error',
42
53
  disabled && 'bg-input-bg-disabled cursor-not-allowed'
43
54
  )}
@@ -46,7 +57,7 @@
46
57
  {#each segments as { part, value: segValue }, i (`${part}-${i}`)}
47
58
  <DatePicker.Segment
48
59
  {part}
49
- class="py-4 min-w-[2ch] text-center text-input-text outline-none cursor-text rounded-4 transition-all duration-fast focus:bg-primary focus:text-inverse data-[placeholder]:text-input-placeholder motion-reduce:transition-none"
60
+ class="min-w-[2ch] text-center text-input-text outline-none cursor-text rounded-4 transition-all duration-fast focus:bg-primary focus:text-inverse data-[placeholder]:text-input-placeholder motion-reduce:transition-none"
50
61
  >
51
62
  {segValue}
52
63
  </DatePicker.Segment>
@@ -2,6 +2,7 @@
2
2
  import {DatePicker} from 'bits-ui'
3
3
  import type {DateValue} from '@internationalized/date'
4
4
  import {IIIcon} from '../IIIcon'
5
+ import {useDensity} from '../density'
5
6
 
6
7
  type Props = {
7
8
  value: DateValue | undefined
@@ -10,6 +11,15 @@
10
11
  }
11
12
 
12
13
  let {value = $bindable(), label, onValueChange}: Props = $props()
14
+
15
+ const density = useDensity()
16
+
17
+ const densityClasses = {
18
+ compact: 'rounded-control text-tiny',
19
+ default: 'rounded-control text-small',
20
+ comfortable: 'rounded-control text-small',
21
+ mobile: 'rounded-control text-default',
22
+ } as const
13
23
  </script>
14
24
 
15
25
  <DatePicker.Root bind:value {onValueChange}>
@@ -18,7 +28,7 @@
18
28
  {/if}
19
29
  <div class="relative">
20
30
  <DatePicker.Input
21
- class="flex items-center gap-4 py-5 px-12 border border-strong rounded-control text-small text-gray-800 bg-surface transition-all duration-fast [&:has(:focus)]:border-primary [&:has(:focus)]:ring-3 [&:has(:focus)]:ring-primary"
31
+ class={`flex items-center gap-4 py-5 px-12 border border-strong bg-surface transition-all duration-fast [&:has(:focus)]:border-primary [&:has(:focus)]:ring-3 [&:has(:focus)]:ring-primary ${densityClasses[density.value]} text-gray-800`}
22
32
  >
23
33
  {#snippet children({segments})}
24
34
  {#each segments as { part, value: segValue }, i (`${part}-${i}`)}
@@ -3,6 +3,7 @@
3
3
  import {DropdownMenu} from 'bits-ui'
4
4
  import {IIIcon} from '../IIIcon'
5
5
  import {cn} from '../utils/cn'
6
+ import {useDensity} from '../density'
6
7
 
7
8
  type Item = {
8
9
  label: string
@@ -35,6 +36,15 @@
35
36
  class: className,
36
37
  }: Props = $props()
37
38
 
39
+ const density = useDensity()
40
+
41
+ const densityClasses = {
42
+ compact: 'h-28 rounded-control text-tiny',
43
+ default: 'h-32 rounded-control text-small',
44
+ comfortable: 'h-40 rounded-control text-small',
45
+ mobile: 'h-48 rounded-control text-default',
46
+ } as const
47
+
38
48
  let open = $state(false)
39
49
  let triggerEl = $state<HTMLElement | null>(null)
40
50
  let triggerWidth = $state<number | undefined>(undefined)
@@ -60,7 +70,8 @@
60
70
  bind:ref={triggerEl}
61
71
  {disabled}
62
72
  class={cn(
63
- 'flex items-center justify-between gap-4 py-5 pl-12 pr-8 border rounded-control bg-input-bg cursor-default text-small text-button-secondary box-border appearance-none font-inherit outline-none transition-colors duration-base ease-in-out hover:text-button-secondary-hover hover:border-button-secondary-hover focus:border-accent focus:ring-3 focus:ring-primary disabled:opacity-50 disabled:cursor-not-allowed',
73
+ 'flex items-center justify-between gap-4 py-5 pl-12 pr-8 border bg-input-bg cursor-default text-button-secondary box-border appearance-none font-inherit outline-none transition-colors duration-base ease-in-out hover:text-button-secondary-hover hover:border-button-secondary-hover focus:border-accent focus:ring-3 focus:ring-primary disabled:opacity-50 disabled:cursor-not-allowed',
74
+ densityClasses[density.value],
64
75
  open ? 'border-button-secondary-hover' : 'border-button-secondary',
65
76
  className
66
77
  )}
@@ -3,6 +3,7 @@
3
3
  import type {IconName} from '../icons'
4
4
  import IIIcon from '../IIIcon/IIIcon.svelte'
5
5
  import {cn} from '../utils/cn'
6
+ import {useDensity} from '../density'
6
7
 
7
8
  type Props = Omit<HTMLButtonAttributes, 'disabled'> & {
8
9
  iconName: IconName
@@ -25,10 +26,11 @@
25
26
  ...restProps
26
27
  }: Props = $props()
27
28
 
29
+ const density = useDensity()
28
30
  const isDisabled = $derived(disabled || loading)
29
31
 
30
32
  const baseClasses =
31
- 'inline-flex items-center justify-center rounded-control 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 disabled:cursor-not-allowed'
32
34
 
33
35
  const variantClasses = {
34
36
  primary:
@@ -44,10 +46,16 @@
44
46
  'bg-button-accent text-button-accent border-0 hover:bg-button-accent-hover disabled:bg-button-accent-disabled',
45
47
  } as const
46
48
 
47
- const sizeClasses = {
48
- sm: 'w-24 h-24 p-0',
49
- md: 'w-28 h-28 p-0',
50
- lg: 'w-32 h-32 p-0',
49
+ const densityClasses = {
50
+ compact: 'w-28 h-28 p-0 rounded-control',
51
+ default: 'w-32 h-32 p-0 rounded-control',
52
+ comfortable: 'w-40 h-40 p-0 rounded-control',
53
+ mobile: 'w-48 h-48 p-0 rounded-control',
54
+ } as const
55
+
56
+ const fixedSizeClasses = {
57
+ sm: 'w-24 h-24 p-0 rounded-control',
58
+ lg: 'w-40 h-40 p-0 rounded-control',
51
59
  } as const
52
60
 
53
61
  const iconSizeClasses = {
@@ -55,12 +63,16 @@
55
63
  md: 'w-14 h-14',
56
64
  lg: 'w-16 h-16',
57
65
  } as const
66
+
67
+ const resolvedSizeClasses = $derived(
68
+ size === 'md' ? densityClasses[density.value] : fixedSizeClasses[size]
69
+ )
58
70
  </script>
59
71
 
60
72
  <button
61
73
  bind:this={ref}
62
74
  disabled={isDisabled}
63
- class={cn(baseClasses, variantClasses[variant], sizeClasses[size], className)}
75
+ class={cn(baseClasses, variantClasses[variant], resolvedSizeClasses, className)}
64
76
  {...restProps}
65
77
  >
66
78
  {#if loading}
@@ -3,6 +3,7 @@
3
3
  import type {HTMLInputAttributes} from 'svelte/elements'
4
4
  import IIIconButton from '../IIIconButton/IIIconButton.svelte'
5
5
  import {cn} from '../utils/cn'
6
+ import {useDensity} from '../density'
6
7
 
7
8
  type Props = Omit<HTMLInputAttributes, 'prefix'> & {
8
9
  label?: string
@@ -33,6 +34,15 @@
33
34
  ...restProps
34
35
  }: Props = $props()
35
36
 
37
+ const density = useDensity()
38
+
39
+ const densityClasses = {
40
+ compact: 'h-28 rounded-control text-small',
41
+ default: 'h-32 rounded-control text-small',
42
+ comfortable: 'h-40 rounded-control text-small',
43
+ mobile: 'h-48 rounded-control text-default',
44
+ } as const
45
+
36
46
  const showError = $derived(error || !!errorMessage)
37
47
  const isSearch = $derived(type === 'search')
38
48
  const showClear = $derived(isSearch && !!value)
@@ -52,16 +62,17 @@
52
62
  })
53
63
  </script>
54
64
 
55
- <div class={cn('flex flex-col gap-4', className)}>
65
+ <div class={cn('flex flex-col', className)}>
56
66
  {#if label}
57
- <label for={restProps.id} class="text-small-emphasis text-body">
67
+ <label for={restProps.id} class="text-small-emphasis text-secondary mb-4">
58
68
  {label}
59
69
  </label>
60
70
  {/if}
61
71
  {#if hasAddons}
62
72
  <div
63
73
  class={cn(
64
- 'flex items-center bg-input-bg border border-input-border rounded-control transition-all duration-fast hover:border-input-border-hover focus-within:border-input-border-hover motion-reduce:transition-none',
74
+ 'flex items-center bg-input-bg border border-input-border transition-all duration-fast hover:border-input-border-hover focus-within:border-input-border-hover motion-reduce:transition-none',
75
+ densityClasses[density.value],
65
76
  showError && 'border-input-border-error focus-within:border-input-border-error',
66
77
  shouldShake && 'animate-shake',
67
78
  disabled && 'bg-input-bg-disabled cursor-not-allowed'
@@ -77,7 +88,7 @@
77
88
  bind:value
78
89
  {type}
79
90
  {disabled}
80
- class="py-5 px-12 text-small font-[family-name:var(--font-family)] text-input-text bg-transparent border-0 outline-none w-full box-border placeholder:text-input-placeholder disabled:text-input-text-disabled disabled:cursor-not-allowed [&::-webkit-search-cancel-button]:appearance-none"
91
+ class="py-5 px-12 h-full font-[family-name:var(--font-family)] text-input-text bg-transparent border-0 outline-none w-full box-border placeholder:text-input-placeholder disabled:text-input-text-disabled disabled:cursor-not-allowed [&::-webkit-search-cancel-button]:appearance-none"
81
92
  {...restProps}
82
93
  />
83
94
  {#if suffix}
@@ -106,7 +117,8 @@
106
117
  {type}
107
118
  {disabled}
108
119
  class={cn(
109
- 'py-5 px-12 text-small font-[family-name:var(--font-family)] text-input-text bg-input-bg border border-input-border rounded-control transition-all duration-fast outline-none w-full box-border placeholder:text-input-placeholder hover:border-input-border-hover focus:border-input-border-hover disabled:bg-input-bg-disabled disabled:text-input-text-disabled disabled:cursor-not-allowed motion-reduce:transition-none motion-reduce:animate-none',
120
+ 'py-5 px-12 font-[family-name:var(--font-family)] text-input-text bg-input-bg border border-input-border transition-all duration-fast outline-none w-full box-border placeholder:text-input-placeholder hover:border-input-border-hover focus:border-input-border-hover disabled:bg-input-bg-disabled disabled:text-input-text-disabled disabled:cursor-not-allowed motion-reduce:transition-none motion-reduce:animate-none',
121
+ densityClasses[density.value],
110
122
  showError && 'border-input-border-error focus:border-input-border-error focus:ring-error',
111
123
  shouldShake && 'animate-shake'
112
124
  )}
@@ -114,8 +126,8 @@
114
126
  />
115
127
  {/if}
116
128
  {#if showError && errorMessage}
117
- <span class="text-tiny text-error">{errorMessage}</span>
129
+ <span class="text-tiny text-error mt-4">{errorMessage}</span>
118
130
  {:else if helperText}
119
- <span class="text-tiny text-secondary">{helperText}</span>
131
+ <span class="text-tiny text-secondary mt-4">{helperText}</span>
120
132
  {/if}
121
133
  </div>
@@ -3,6 +3,7 @@
3
3
  import {DropdownMenu} from 'bits-ui'
4
4
  import {IIIcon} from '../IIIcon'
5
5
  import {cn} from '../utils/cn'
6
+ import {useDensity} from '../density'
6
7
 
7
8
  type Item = {
8
9
  label: string
@@ -34,6 +35,15 @@
34
35
  class: className,
35
36
  }: Props = $props()
36
37
 
38
+ const density = useDensity()
39
+
40
+ const densityRadius = {
41
+ compact: 'rounded-control',
42
+ default: 'rounded-control',
43
+ comfortable: 'rounded-control',
44
+ mobile: 'rounded-control',
45
+ } as const
46
+
37
47
  let open = $state(false)
38
48
  let triggerEl = $state<HTMLElement | null>(null)
39
49
  let triggerWidth = $state<number | undefined>(undefined)
@@ -75,7 +85,8 @@
75
85
  bind:ref={triggerEl}
76
86
  {disabled}
77
87
  class={cn(
78
- 'flex items-center gap-4 py-5 pl-12 pr-8 border rounded-control bg-button-secondary cursor-default text-small text-button-secondary box-border appearance-none font-inherit outline-none transition-colors duration-base ease-in-out hover:text-button-secondary-hover hover:border-button-secondary-hover focus:border-accent focus:ring-3 focus:ring-primary disabled:opacity-50 disabled:cursor-not-allowed',
88
+ 'flex items-center gap-4 py-5 pl-12 pr-8 border bg-button-secondary cursor-default text-small text-button-secondary box-border appearance-none font-inherit outline-none transition-colors duration-base ease-in-out hover:text-button-secondary-hover hover:border-button-secondary-hover focus:border-accent focus:ring-3 focus:ring-primary disabled:opacity-50 disabled:cursor-not-allowed',
89
+ densityRadius[density.value],
79
90
  open ? 'border-button-secondary-hover' : 'border-button-secondary',
80
91
  className
81
92
  )}
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import {cn} from '../utils/cn'
3
3
  import IIDropdownInput from '../IIDropdownInput/IIDropdownInput.svelte'
4
+ import {useDensity} from '../density'
4
5
 
5
6
  type Tab = {
6
7
  value: string
@@ -17,6 +18,15 @@
17
18
 
18
19
  let {tabs, value = $bindable(), onchange, class: className}: Props = $props()
19
20
 
21
+ const density = useDensity()
22
+
23
+ const densityClasses = {
24
+ compact: 'h-28 text-tiny',
25
+ default: 'h-32 text-small',
26
+ comfortable: 'h-40 text-small',
27
+ mobile: 'h-48 text-default',
28
+ } as const
29
+
20
30
  let containerEl = $state<HTMLDivElement | null>(null)
21
31
  let measureEl = $state<HTMLDivElement | null>(null)
22
32
  let overflow = $state(false)
@@ -55,7 +65,8 @@
55
65
  {#each tabs as tab (tab.value)}
56
66
  <button
57
67
  class={cn(
58
- 'flex items-center h-28 px-10 rounded-full border-none outline-none text-small cursor-default whitespace-nowrap',
68
+ 'flex items-center px-10 rounded-full border-none outline-none cursor-default whitespace-nowrap',
69
+ densityClasses[density.value],
59
70
  value === tab.value
60
71
  ? 'bg-gray-100 text-gray-700'
61
72
  : 'bg-surface text-secondary shadow-pill hover:bg-gray-100 hover:text-gray-700'
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import {cn} from '../utils/cn'
3
+ import {useDensity} from '../density'
3
4
 
4
5
  type Item = {
5
6
  label: string
@@ -17,6 +18,15 @@
17
18
 
18
19
  let {items, value = $bindable(), onValueChange, size = 'sm', class: className}: Props = $props()
19
20
 
21
+ const density = useDensity()
22
+
23
+ const densityRadius = {
24
+ compact: 'rounded-control',
25
+ default: 'rounded-control',
26
+ comfortable: 'rounded-control',
27
+ mobile: 'rounded-control',
28
+ } as const
29
+
20
30
  const sizeClasses = {
21
31
  sm: 'px-12 py-4 text-small',
22
32
  md: 'px-16 py-6 text-default',
@@ -33,7 +43,7 @@
33
43
  }
34
44
  </script>
35
45
 
36
- <div class={cn('inline-flex border border-primary rounded-control overflow-hidden', className)} role="group">
46
+ <div class={cn('inline-flex border border-primary overflow-hidden', densityRadius[density.value], className)} role="group">
37
47
  {#each items as item (item.value)}
38
48
  {@const isActive = value === item.value}
39
49
  <button
@@ -3,6 +3,7 @@
3
3
  import {DropdownMenu, Tabs, type WithoutChildrenOrChild} from 'bits-ui'
4
4
  import {IIIcon} from '../IIIcon'
5
5
  import {cn} from '../utils/cn'
6
+ import {useDensity} from '../density'
6
7
 
7
8
  type Tab = {
8
9
  value: string
@@ -35,6 +36,15 @@
35
36
  let overflowing = $state(false)
36
37
  let dropdownOpen = $state(false)
37
38
 
39
+ const density = useDensity()
40
+
41
+ const densityRadius = {
42
+ compact: 'rounded-control',
43
+ default: 'rounded-control',
44
+ comfortable: 'rounded-control',
45
+ mobile: 'rounded-control',
46
+ } as const
47
+
38
48
  const activeLabel = $derived(tabs.find(t => t.value === value)?.label ?? '')
39
49
 
40
50
  $effect(() => {
@@ -69,7 +79,10 @@
69
79
  <div class="flex items-center border-b border-primary px-24" style="padding-left: calc(2.4rem - 1.2rem - 1px)">
70
80
  <DropdownMenu.Root bind:open={dropdownOpen}>
71
81
  <DropdownMenu.Trigger
72
- class="[all:unset] inline-flex items-center gap-4 py-4 pr-8 pl-12 border border-primary rounded-control bg-surface cursor-default transition-all duration-fast hover:border-strong motion-reduce:transition-none"
82
+ class={cn(
83
+ '[all:unset] inline-flex items-center gap-4 py-4 pr-8 pl-12 border border-primary bg-surface cursor-default transition-all duration-fast hover:border-strong motion-reduce:transition-none',
84
+ densityRadius[density.value]
85
+ )}
73
86
  >
74
87
  <span class="text-small-emphasis text-body">{activeLabel}</span>
75
88
  <IIIcon iconName="caret-down" class="w-14 h-14 text-secondary shrink-0" />
@@ -2,6 +2,7 @@
2
2
  import type {Snippet} from 'svelte'
3
3
  import {Toggle} from 'bits-ui'
4
4
  import {cn} from '../utils/cn'
5
+ import {useDensity} from '../density'
5
6
 
6
7
  type Props = {
7
8
  pressed: boolean
@@ -23,10 +24,18 @@
23
24
  class: className,
24
25
  }: Props = $props()
25
26
 
26
- const sizeClasses = {
27
- sm: 'w-24 h-24',
28
- md: 'w-28 h-28',
29
- lg: 'w-32 h-32',
27
+ const density = useDensity()
28
+
29
+ const densityClasses = {
30
+ compact: 'w-28 h-28 rounded-control',
31
+ default: 'w-32 h-32 rounded-control',
32
+ comfortable: 'w-40 h-40 rounded-control',
33
+ mobile: 'w-48 h-48 rounded-control',
34
+ } as const
35
+
36
+ const fixedSizeClasses = {
37
+ sm: 'w-24 h-24 rounded-control',
38
+ lg: 'w-40 h-40 rounded-control',
30
39
  } as const
31
40
 
32
41
  const iconSizeClasses = {
@@ -34,6 +43,10 @@
34
43
  md: '[&_svg]:w-14 [&_svg]:h-14',
35
44
  lg: '[&_svg]:w-16 [&_svg]:h-16',
36
45
  } as const
46
+
47
+ const resolvedSizeClasses = $derived(
48
+ size === 'md' ? densityClasses[density.value] : fixedSizeClasses[size]
49
+ )
37
50
  </script>
38
51
 
39
52
  <Toggle.Root
@@ -42,8 +55,8 @@
42
55
  {disabled}
43
56
  aria-label={ariaLabel}
44
57
  class={cn(
45
- 'inline-flex items-center justify-center rounded-control 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',
46
- sizeClasses[size],
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',
59
+ resolvedSizeClasses,
47
60
  iconSizeClasses[size],
48
61
  className
49
62
  )}
@@ -47,7 +47,7 @@
47
47
  <section>
48
48
  <h2 class="text-default-emphasis text-primary mb-8">Toolbar Example</h2>
49
49
  <p class="text-small text-secondary mb-12">Multiple toggles used together as a formatting toolbar.</p>
50
- <div class="flex items-center gap-4 p-4 border border-subtle rounded-control bg-surface inline-flex">
50
+ <div class="flex items-center gap-4 p-4 border border-subtle rounded-8 bg-surface inline-flex">
51
51
  <IIToggle bind:pressed={filterPressed} aria-label="Filter">
52
52
  {#snippet children({pressed})}
53
53
  <IIIcon iconName="funnel-fill" />
@@ -21,7 +21,7 @@
21
21
  type="search"
22
22
  placeholder="Search icons..."
23
23
  bind:value={search}
24
- class="py-5 px-12 text-small bg-surface border border-strong rounded-control w-full max-w-300 outline-none focus:border-primary"
24
+ class="py-5 px-12 text-small bg-surface border border-strong rounded-8 w-full max-w-300 outline-none focus:border-primary"
25
25
  style="margin-bottom: 32px;"
26
26
  />
27
27
  <div