@dryui/ui 0.5.2 → 1.0.0

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 (99) hide show
  1. package/dist/alert/{alert-root.svelte → alert.svelte} +78 -20
  2. package/dist/alert/alert.svelte.d.ts +15 -0
  3. package/dist/alert/index.d.ts +15 -14
  4. package/dist/alert/index.js +3 -12
  5. package/dist/breadcrumb/breadcrumb-link.svelte +1 -1
  6. package/dist/button/button.svelte +1 -1
  7. package/dist/card/card-root.svelte +2 -2
  8. package/dist/chromatic-shift/chromatic-shift.svelte +2 -2
  9. package/dist/code-block/code-block-button.svelte +1 -1
  10. package/dist/color-picker/color-picker-area.svelte +2 -2
  11. package/dist/color-picker/color-picker-channel-input.svelte +2 -2
  12. package/dist/color-picker/color-picker-input-alpha-slider.svelte +2 -2
  13. package/dist/color-picker/color-picker-input-hue-slider.svelte +2 -2
  14. package/dist/color-picker/color-picker-input.svelte +9 -9
  15. package/dist/color-picker/color-picker-swatch.svelte +2 -2
  16. package/dist/combobox/combobox-input.svelte +9 -9
  17. package/dist/command-palette/command-palette-item.svelte +1 -1
  18. package/dist/data-grid/data-grid-button-input-column.svelte +1 -1
  19. package/dist/diagram/diagram.svelte +222 -32
  20. package/dist/diagram/diagram.svelte.d.ts +1 -0
  21. package/dist/diagram/edge-routing.d.ts +63 -1
  22. package/dist/diagram/edge-routing.js +316 -26
  23. package/dist/diagram/layout.js +633 -62
  24. package/dist/diagram/types.d.ts +58 -0
  25. package/dist/drag-and-drop/drag-and-drop-handle.svelte +1 -1
  26. package/dist/drag-and-drop/drag-and-drop-item.svelte +1 -1
  27. package/dist/file-select/file-select-root.svelte +2 -2
  28. package/dist/file-upload/file-upload-dropzone.svelte +2 -2
  29. package/dist/gauge/gauge.svelte +1 -1
  30. package/dist/image-comparison/image-comparison.svelte +1 -1
  31. package/dist/index.d.ts +3 -3
  32. package/dist/index.js +1 -1
  33. package/dist/input/input.svelte +10 -11
  34. package/dist/label/label.svelte +1 -1
  35. package/dist/link/link.svelte +1 -1
  36. package/dist/list/list-item.svelte +2 -2
  37. package/dist/multi-select-combobox/multi-select-combobox-selection-item.svelte +9 -3
  38. package/dist/multi-select-combobox/multi-select-combobox-selection-remove-button.svelte +2 -0
  39. package/dist/navigation-menu/navigation-menu-link.svelte +1 -1
  40. package/dist/notification-center/notification-center-item.svelte +1 -1
  41. package/dist/number-input/number-input-button.svelte +3 -3
  42. package/dist/option-picker/context.svelte.d.ts +9 -0
  43. package/dist/option-picker/context.svelte.js +2 -0
  44. package/dist/option-picker/option-picker-item.svelte +31 -4
  45. package/dist/option-picker/option-picker-preview.svelte +2 -2
  46. package/dist/option-picker/option-picker-root.svelte +2 -2
  47. package/dist/phone-input/phone-input-select.svelte +2 -2
  48. package/dist/pin-input/pin-input-cell.svelte +1 -1
  49. package/dist/pin-input/pin-input-root.svelte +1 -1
  50. package/dist/progress/progress.svelte +1 -1
  51. package/dist/scroll-area/scroll-area.svelte +1 -1
  52. package/dist/shimmer/index.d.ts +8 -0
  53. package/dist/shimmer/index.js +1 -0
  54. package/dist/shimmer/shimmer.svelte +87 -0
  55. package/dist/shimmer/shimmer.svelte.d.ts +10 -0
  56. package/dist/sidebar/sidebar-item.svelte +1 -1
  57. package/dist/slider/slider-input.svelte +2 -2
  58. package/dist/splitter/splitter-handle.svelte +1 -1
  59. package/dist/table-of-contents/table-of-contents-item.svelte +1 -1
  60. package/dist/table-of-contents/table-of-contents-list.svelte +1 -1
  61. package/dist/tags-input/tags-input-root.svelte +1 -1
  62. package/dist/tags-input/tags-input-tag-delete-button.svelte +2 -0
  63. package/dist/tags-input/tags-input-tag.svelte +9 -3
  64. package/dist/textarea/textarea.svelte +11 -11
  65. package/dist/themes/default.css +31 -0
  66. package/dist/toast/toast-root.svelte +1 -1
  67. package/dist/tour/tour-root.css +3 -3
  68. package/dist/tree/tree-item-children.svelte +1 -1
  69. package/dist/tree/tree-item-label.svelte +1 -1
  70. package/dist/video-embed/video-embed-button.svelte +1 -1
  71. package/package.json +11 -750
  72. package/skills/dryui/SKILL.md +26 -21
  73. package/skills/dryui/rules/compound-components.md +3 -3
  74. package/skills/dryui/rules/theming.md +1 -1
  75. package/dist/alert/alert-button-close.svelte +0 -29
  76. package/dist/alert/alert-button-close.svelte.d.ts +0 -8
  77. package/dist/alert/alert-description.svelte +0 -28
  78. package/dist/alert/alert-description.svelte.d.ts +0 -8
  79. package/dist/alert/alert-icon.svelte +0 -26
  80. package/dist/alert/alert-icon.svelte.d.ts +0 -8
  81. package/dist/alert/alert-root.svelte.d.ts +0 -12
  82. package/dist/alert/alert-title.svelte +0 -29
  83. package/dist/alert/alert-title.svelte.d.ts +0 -8
  84. package/dist/alert/context.svelte.d.ts +0 -9
  85. package/dist/alert/context.svelte.js +0 -10
  86. package/dist/option-swatch-group/context.svelte.d.ts +0 -9
  87. package/dist/option-swatch-group/context.svelte.js +0 -2
  88. package/dist/option-swatch-group/index.d.ts +0 -29
  89. package/dist/option-swatch-group/index.js +0 -12
  90. package/dist/option-swatch-group/option-swatch-group-item-button.svelte +0 -214
  91. package/dist/option-swatch-group/option-swatch-group-item-button.svelte.d.ts +0 -12
  92. package/dist/option-swatch-group/option-swatch-group-label.svelte +0 -24
  93. package/dist/option-swatch-group/option-swatch-group-label.svelte.d.ts +0 -8
  94. package/dist/option-swatch-group/option-swatch-group-meta.svelte +0 -24
  95. package/dist/option-swatch-group/option-swatch-group-meta.svelte.d.ts +0 -8
  96. package/dist/option-swatch-group/option-swatch-group-root.svelte +0 -81
  97. package/dist/option-swatch-group/option-swatch-group-root.svelte.d.ts +0 -12
  98. package/dist/option-swatch-group/option-swatch-group-swatch.svelte +0 -52
  99. package/dist/option-swatch-group/option-swatch-group-swatch.svelte.d.ts +0 -10
@@ -1,16 +1,35 @@
1
+ import type { Component } from 'svelte';
1
2
  export type DiagramColor = 'neutral' | 'brand' | 'success' | 'warning' | 'error' | 'info';
2
3
  export type DiagramDirection = 'TB' | 'BT' | 'LR' | 'RL';
4
+ export type DiagramIconComponent = Component<{
5
+ size?: number | string;
6
+ 'aria-hidden'?: boolean | string;
7
+ }>;
3
8
  export interface DiagramNode {
4
9
  id: string;
5
10
  label: string;
6
11
  description?: string;
7
12
  icon?: string;
13
+ iconComponent?: DiagramIconComponent;
8
14
  variant?: 'default' | 'filled' | 'outlined' | 'pill';
9
15
  color?: DiagramColor;
10
16
  state?: 'default' | 'active' | 'complete' | 'blocked';
11
17
  width?: number;
12
18
  height?: number;
13
19
  }
20
+ export type DiagramLoopSide = 'over' | 'under' | 'left' | 'right';
21
+ export interface DiagramWaypoint {
22
+ id?: string;
23
+ label: string;
24
+ description?: string;
25
+ icon?: string;
26
+ iconComponent?: DiagramIconComponent;
27
+ color?: DiagramColor;
28
+ variant?: 'default' | 'filled' | 'outlined' | 'pill';
29
+ width?: number;
30
+ height?: number;
31
+ position?: number;
32
+ }
14
33
  export interface DiagramEdge {
15
34
  from: string;
16
35
  to: string;
@@ -18,13 +37,26 @@ export interface DiagramEdge {
18
37
  arrow?: 'end' | 'start' | 'both' | 'none';
19
38
  dashed?: boolean;
20
39
  color?: DiagramColor;
40
+ loop?: DiagramLoopSide;
41
+ waypoint?: DiagramWaypoint;
21
42
  }
43
+ export type DiagramClusterLabelPosition = 'top-left' | 'left';
22
44
  export interface DiagramCluster {
23
45
  id: string;
24
46
  label?: string;
47
+ labelPosition?: DiagramClusterLabelPosition;
48
+ iconComponent?: DiagramIconComponent;
25
49
  nodes: string[];
26
50
  color?: DiagramColor;
27
51
  dashed?: boolean;
52
+ direction?: DiagramDirection;
53
+ spacing?: {
54
+ nodeGap?: number;
55
+ layerGap?: number;
56
+ clusterPadding?: number;
57
+ cornerRadius?: number;
58
+ backEdgeLaneGap?: number;
59
+ };
28
60
  }
29
61
  export interface DiagramAnnotation {
30
62
  text: string;
@@ -82,6 +114,8 @@ export interface DiagramConfig {
82
114
  nodeGap?: number;
83
115
  layerGap?: number;
84
116
  clusterPadding?: number;
117
+ cornerRadius?: number;
118
+ backEdgeLaneGap?: number;
85
119
  };
86
120
  ariaLabel?: string;
87
121
  }
@@ -94,6 +128,7 @@ export interface PositionedNode {
94
128
  label: string;
95
129
  description?: string;
96
130
  icon?: string;
131
+ iconComponent?: DiagramIconComponent;
97
132
  variant: string;
98
133
  color: DiagramColor;
99
134
  state: string;
@@ -108,6 +143,26 @@ export interface PositionedEdge {
108
143
  arrow: string;
109
144
  dashed: boolean;
110
145
  color: DiagramColor;
146
+ kind?: 'full' | 'entry' | 'exit';
147
+ bounds?: {
148
+ minX: number;
149
+ minY: number;
150
+ maxX: number;
151
+ maxY: number;
152
+ };
153
+ }
154
+ export interface PositionedWaypoint {
155
+ id: string;
156
+ x: number;
157
+ y: number;
158
+ width: number;
159
+ height: number;
160
+ label: string;
161
+ description?: string;
162
+ icon?: string;
163
+ iconComponent?: DiagramIconComponent;
164
+ variant: string;
165
+ color: DiagramColor;
111
166
  }
112
167
  export interface PositionedCluster {
113
168
  id: string;
@@ -116,6 +171,8 @@ export interface PositionedCluster {
116
171
  width: number;
117
172
  height: number;
118
173
  label?: string;
174
+ labelPosition?: DiagramClusterLabelPosition;
175
+ iconComponent?: DiagramIconComponent;
119
176
  color: DiagramColor;
120
177
  dashed: boolean;
121
178
  }
@@ -189,6 +246,7 @@ export interface LayoutResult {
189
246
  messages: PositionedMessage[];
190
247
  lifelines: PositionedLifeline[];
191
248
  positionedFragments: PositionedFragment[];
249
+ waypoints: PositionedWaypoint[];
192
250
  viewBox: {
193
251
  width: number;
194
252
  height: number;
@@ -67,7 +67,7 @@
67
67
  }
68
68
 
69
69
  [data-dnd-handle]:focus-visible {
70
- outline: 2px solid var(--dry-color-focus-ring);
70
+ outline: var(--dry-focus-ring);
71
71
  outline-offset: 2px;
72
72
  }
73
73
 
@@ -101,7 +101,7 @@
101
101
  }
102
102
 
103
103
  [data-dnd-item]:focus-visible {
104
- outline: 2px solid var(--dry-color-focus-ring);
104
+ outline: var(--dry-focus-ring);
105
105
  outline-offset: 2px;
106
106
  }
107
107
 
@@ -94,12 +94,12 @@
94
94
 
95
95
  [data-file-select]:focus-within {
96
96
  border-color: var(--dry-color-focus-ring);
97
- outline: 2px solid var(--dry-color-focus-ring);
97
+ outline: var(--dry-focus-ring);
98
98
  outline-offset: -1px;
99
99
  }
100
100
 
101
101
  [data-file-select][data-disabled] {
102
- opacity: 0.5;
102
+ opacity: var(--dry-state-disabled-opacity);
103
103
  cursor: not-allowed;
104
104
  pointer-events: none;
105
105
  }
@@ -107,7 +107,7 @@
107
107
  }
108
108
 
109
109
  [data-fu-dropzone]:focus-visible {
110
- outline: 2px solid var(--dry-color-focus-ring);
110
+ outline: var(--dry-focus-ring);
111
111
  outline-offset: 2px;
112
112
  --dry-fu-border: var(--dry-color-focus-ring);
113
113
  }
@@ -119,7 +119,7 @@
119
119
  }
120
120
 
121
121
  [data-fu-dropzone][data-disabled] {
122
- opacity: 0.5;
122
+ opacity: var(--dry-state-disabled-opacity);
123
123
  cursor: not-allowed;
124
124
  pointer-events: none;
125
125
  }
@@ -118,7 +118,7 @@
118
118
  stroke: var(--_gauge-fill-stroke, var(--dry-gauge-fill-color));
119
119
  stroke-width: var(--dry-gauge-stroke-width);
120
120
  stroke-linecap: round;
121
- transition: d var(--dry-duration-normal, 0.3s) var(--dry-ease-default, ease);
121
+ transition: d var(--dry-duration-normal) var(--dry-ease-default);
122
122
  }
123
123
 
124
124
  [data-gauge-label] {
@@ -272,7 +272,7 @@
272
272
 
273
273
  /* Focus */
274
274
  [data-ic-handle-wrapper]:focus-visible [data-ic-grip] {
275
- outline: 2px solid var(--dry-color-focus-ring);
275
+ outline: var(--dry-focus-ring);
276
276
  outline-offset: 2px;
277
277
  }
278
278
  </style>
package/dist/index.d.ts CHANGED
@@ -54,8 +54,6 @@ export { ToggleGroup } from './toggle-group/index.js';
54
54
  export type { ToggleGroupRootProps, ToggleGroupItemProps } from './toggle-group/index.js';
55
55
  export { InputGroup } from './input-group/index.js';
56
56
  export type { InputGroupRootProps, InputGroupPrefixProps, InputGroupInputProps, InputGroupSuffixProps, InputGroupSelectProps, InputGroupSeparatorProps, InputGroupActionProps } from './input-group/index.js';
57
- export { OptionSwatchGroup } from './option-swatch-group/index.js';
58
- export type { OptionSwatchGroupRootProps, OptionSwatchGroupItemProps, OptionSwatchGroupSwatchProps, OptionSwatchGroupLabelProps, OptionSwatchGroupMetaProps } from './option-swatch-group/index.js';
59
57
  export { OptionPicker } from './option-picker/index.js';
60
58
  export type { OptionPickerRootProps, OptionPickerItemProps, OptionPickerPreviewProps, OptionPickerLabelProps, OptionPickerDescriptionProps, OptionPickerMetaProps } from './option-picker/index.js';
61
59
  export { Container } from './container/index.js';
@@ -125,7 +123,7 @@ export type { TextProps } from './text/index.js';
125
123
  export { DescriptionList } from './description-list/index.js';
126
124
  export type { DescriptionListRootProps, DescriptionListItemProps, DescriptionListTermProps, DescriptionListDescriptionProps } from './description-list/index.js';
127
125
  export { Alert } from './alert/index.js';
128
- export type { AlertVariant, AlertRootProps, AlertIconProps, AlertTitleProps, AlertDescriptionProps, AlertCloseProps } from './alert/index.js';
126
+ export type { AlertProps, AlertVariant } from './alert/index.js';
129
127
  export { Toast, toastStore, createToastStore } from './toast/index.js';
130
128
  export type { ToastData, ToastProviderProps, ToastRootProps, ToastActionProps, ToastTitleProps, ToastDescriptionProps, ToastCloseProps } from './toast/index.js';
131
129
  export { Progress } from './progress/index.js';
@@ -272,6 +270,8 @@ export { AlphaSlider } from './alpha-slider/index.js';
272
270
  export type { AlphaSliderProps } from './alpha-slider/index.js';
273
271
  export { Beam } from './beam/index.js';
274
272
  export type { BeamProps } from './beam/index.js';
273
+ export { Shimmer } from './shimmer/index.js';
274
+ export type { ShimmerProps } from './shimmer/index.js';
275
275
  export { Glass } from './glass/index.js';
276
276
  export type { GlassProps } from './glass/index.js';
277
277
  export { GodRays } from './god-rays/index.js';
package/dist/index.js CHANGED
@@ -27,7 +27,6 @@ export { Slider } from './slider/index.js';
27
27
  export { Toggle } from './toggle/index.js';
28
28
  export { ToggleGroup } from './toggle-group/index.js';
29
29
  export { InputGroup } from './input-group/index.js';
30
- export { OptionSwatchGroup } from './option-swatch-group/index.js';
31
30
  export { OptionPicker } from './option-picker/index.js';
32
31
  // Phase 4 — Layout Primitives
33
32
  export { Container } from './container/index.js';
@@ -140,6 +139,7 @@ export { Glow } from './glow/index.js';
140
139
  export { Adjust } from './adjust/index.js';
141
140
  export { AlphaSlider } from './alpha-slider/index.js';
142
141
  export { Beam } from './beam/index.js';
142
+ export { Shimmer } from './shimmer/index.js';
143
143
  export { Glass } from './glass/index.js';
144
144
  export { GodRays } from './god-rays/index.js';
145
145
  export { GradientMesh } from './gradient-mesh/index.js';
@@ -48,16 +48,15 @@
48
48
  }
49
49
 
50
50
  input {
51
- padding: var(--dry-input-padding-y, var(--dry-space-2))
52
- var(--dry-input-padding-x, var(--dry-space-3));
53
- font-size: var(--dry-input-font-size, var(--dry-type-small-size));
51
+ padding: var(--dry-input-padding-y, var(--dry-form-control-padding-block))
52
+ var(--dry-input-padding-x, var(--dry-form-control-padding-inline));
53
+ font-size: var(--dry-input-font-size, var(--dry-form-control-font-size));
54
54
  line-height: var(--dry-type-small-leading);
55
55
  font-family: var(--dry-font-sans);
56
- color: var(--dry-input-color, var(--dry-color-text-strong));
57
- background: var(--dry-input-bg, var(--dry-control-bg, var(--dry-color-bg-raised)));
58
- border: 1px solid
59
- var(--dry-input-border, var(--dry-control-border, var(--dry-color-stroke-strong)));
60
- border-radius: var(--dry-input-radius, var(--dry-control-radius, var(--dry-radius-md)));
56
+ color: var(--dry-input-color, var(--dry-form-control-color));
57
+ background: var(--dry-input-bg, var(--dry-form-control-bg));
58
+ border: 1px solid var(--dry-input-border, var(--dry-form-control-border));
59
+ border-radius: var(--dry-input-radius, var(--dry-form-control-radius));
61
60
  transition:
62
61
  border-color var(--dry-duration-fast) var(--dry-ease-default),
63
62
  box-shadow var(--dry-duration-fast) var(--dry-ease-default);
@@ -65,15 +64,15 @@
65
64
  appearance: none;
66
65
 
67
66
  &::placeholder {
68
- color: var(--dry-color-text-weak);
67
+ color: var(--dry-form-control-color-placeholder);
69
68
  }
70
69
 
71
70
  &:hover:not([data-disabled]) {
72
- border-color: var(--dry-color-stroke-strong);
71
+ border-color: var(--dry-form-control-border-hover);
73
72
  }
74
73
 
75
74
  &:focus-visible {
76
- outline: 2px solid var(--dry-color-focus-ring);
75
+ outline: var(--dry-focus-ring);
77
76
  outline-offset: -1px;
78
77
  border-color: var(--dry-color-stroke-focus);
79
78
  box-shadow: 0 0 0 1px var(--dry-color-stroke-focus);
@@ -45,7 +45,7 @@
45
45
  cursor: pointer;
46
46
 
47
47
  &[data-disabled] {
48
- opacity: 0.5;
48
+ opacity: var(--dry-state-disabled-opacity);
49
49
  cursor: not-allowed;
50
50
  }
51
51
 
@@ -87,7 +87,7 @@
87
87
  }
88
88
 
89
89
  a:focus-visible {
90
- outline: 2px solid var(--dry-color-focus-ring);
90
+ outline: var(--dry-focus-ring);
91
91
  outline-offset: 2px;
92
92
  border-radius: var(--dry-radius-sm);
93
93
  }
@@ -75,12 +75,12 @@
75
75
  }
76
76
 
77
77
  [data-list-item][data-interactive='true']:focus-visible {
78
- outline: 2px solid var(--dry-color-focus-ring);
78
+ outline: var(--dry-focus-ring);
79
79
  outline-offset: -2px;
80
80
  }
81
81
 
82
82
  [data-list-item][data-disabled='true'] {
83
- opacity: 0.5;
83
+ opacity: var(--dry-state-disabled-opacity);
84
84
  cursor: not-allowed;
85
85
  pointer-events: none;
86
86
  }
@@ -35,18 +35,24 @@
35
35
  grid-auto-flow: column;
36
36
  grid-auto-columns: max-content;
37
37
  align-items: center;
38
- gap: var(--dry-space-1);
39
- padding: 4px var(--dry-space-2);
38
+ padding-block: 4px;
39
+ padding-inline-start: var(--dry-space-2);
40
+ padding-inline-end: 0;
40
41
  background: var(--dry-color-fill-brand-weak);
41
42
  color: var(--dry-color-text-brand);
42
43
  box-shadow: inset 0 0 0 1px var(--dry-color-stroke-selected);
43
- border-radius: var(--dry-radius-full);
44
+ border-radius: var(--dry-radius-md);
45
+ overflow: hidden;
44
46
  font-size: var(--dry-type-tiny-size, var(--dry-text-xs-size));
45
47
  font-family: var(--dry-font-sans);
46
48
  font-weight: 500;
47
49
  line-height: 1.5;
48
50
  white-space: nowrap;
49
51
  user-select: none;
52
+ --dry-btn-radius: 0;
53
+ --dry-btn-padding-x: var(--dry-space-2);
54
+ --dry-btn-padding-y: 0;
55
+ --dry-btn-font-size: inherit;
50
56
  }
51
57
 
52
58
  @container (max-width: 200px) {
@@ -27,6 +27,8 @@
27
27
  </script>
28
28
 
29
29
  <CloseButtonBase
30
+ variant="bare"
31
+ size="sm"
30
32
  aria-label={`Remove selection: ${label ?? value}`}
31
33
  disabled={ctx.disabled}
32
34
  {...rest}
@@ -44,7 +44,7 @@
44
44
  }
45
45
 
46
46
  [data-nav-menu-link]:focus-visible {
47
- outline: 2px solid var(--dry-color-focus-ring);
47
+ outline: var(--dry-focus-ring);
48
48
  outline-offset: 2px;
49
49
  }
50
50
  </style>
@@ -45,7 +45,7 @@
45
45
  padding: var(--dry-nc-item-padding, 0.75rem);
46
46
  color: var(--dry-color-text-strong);
47
47
  border-bottom: 1px solid var(--dry-color-stroke-weak, #e2e8f0);
48
- transition: background var(--dry-duration-fast, 100ms) ease;
48
+ transition: background var(--dry-duration-fast) var(--dry-ease-default);
49
49
  }
50
50
 
51
51
  [data-notification-center-item]:last-child {
@@ -109,18 +109,18 @@
109
109
  }
110
110
 
111
111
  [data-number-input-wrapper] input:focus-visible {
112
- outline: 2px solid var(--dry-color-focus-ring);
112
+ outline: var(--dry-focus-ring);
113
113
  outline-offset: -1px;
114
114
  border-color: var(--dry-color-focus-ring);
115
115
  }
116
116
 
117
117
  [data-number-input-wrapper] input[data-disabled] {
118
- opacity: 0.5;
118
+ opacity: var(--dry-state-disabled-opacity);
119
119
  cursor: not-allowed;
120
120
  }
121
121
 
122
122
  [data-number-input-wrapper][data-disabled] {
123
- opacity: 0.5;
123
+ opacity: var(--dry-state-disabled-opacity);
124
124
  cursor: not-allowed;
125
125
  }
126
126
 
@@ -0,0 +1,9 @@
1
+ interface OptionPickerContext {
2
+ readonly value: string;
3
+ readonly disabled: boolean;
4
+ readonly orientation: 'horizontal' | 'vertical';
5
+ select: (value: string) => void;
6
+ isSelected: (value: string) => boolean;
7
+ }
8
+ export declare const setOptionPickerCtx: (ctx: OptionPickerContext) => OptionPickerContext, getOptionPickerCtx: () => OptionPickerContext;
9
+ export {};
@@ -0,0 +1,2 @@
1
+ import { createContext } from '@dryui/primitives';
2
+ export const [setOptionPickerCtx, getOptionPickerCtx] = createContext('option-picker');
@@ -1,8 +1,9 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
+ import type { Attachment } from 'svelte/attachments';
3
4
  import type { HTMLButtonAttributes } from 'svelte/elements';
4
5
  import Button from '../button/button.svelte';
5
- import { getSelectableTileGroupCtx } from '../option-swatch-group/context.svelte.js';
6
+ import { getOptionPickerCtx } from './context.svelte.js';
6
7
 
7
8
  interface Props extends Omit<HTMLButtonAttributes, 'value'> {
8
9
  value: string;
@@ -23,9 +24,10 @@
23
24
  ...rest
24
25
  }: Props = $props();
25
26
 
26
- const ctx = getSelectableTileGroupCtx();
27
+ const ctx = getOptionPickerCtx();
27
28
  const isDisabled = $derived(disabled || unavailable || ctx.disabled);
28
29
  const isSelected = $derived(ctx.isSelected(value));
30
+ let hasSingleLabelChild = $state(false);
29
31
 
30
32
  function moveFocus(current: HTMLButtonElement, direction: -1 | 1) {
31
33
  const group = current.closest('[role="radiogroup"]');
@@ -63,6 +65,22 @@
63
65
  ctx.select(value);
64
66
  }
65
67
  }
68
+
69
+ const singleLabelLayout: Attachment<HTMLSpanElement> = (node) => {
70
+ const updateLayout = () => {
71
+ const directChildren = Array.from(node.children);
72
+ hasSingleLabelChild =
73
+ directChildren.length === 1 &&
74
+ directChildren[0] instanceof HTMLElement &&
75
+ directChildren[0].hasAttribute('data-option-picker-label');
76
+ };
77
+
78
+ updateLayout();
79
+ const observer = new MutationObserver(updateLayout);
80
+ observer.observe(node, { childList: true });
81
+
82
+ return () => observer.disconnect();
83
+ };
66
84
  </script>
67
85
 
68
86
  <span
@@ -92,7 +110,7 @@
92
110
  }}
93
111
  onkeydown={handleKeydown}
94
112
  >
95
- <span class="content">
113
+ <span class="content" class:single-label={hasSingleLabelChild} {@attach singleLabelLayout}>
96
114
  {@render children()}
97
115
  </span>
98
116
  </Button>
@@ -168,7 +186,7 @@
168
186
  }
169
187
 
170
188
  .root:focus-within {
171
- outline: 2px solid var(--dry-color-focus-ring);
189
+ outline: var(--dry-focus-ring);
172
190
  outline-offset: 2px;
173
191
  }
174
192
 
@@ -199,6 +217,15 @@
199
217
  --dry-option-picker-meta-row: 4;
200
218
  }
201
219
 
220
+ .content.single-label {
221
+ grid-template-columns: 1fr;
222
+ justify-items: center;
223
+ text-align: center;
224
+
225
+ --dry-option-picker-label-column: 1;
226
+ --dry-option-picker-label-row: 1;
227
+ }
228
+
202
229
  .root[data-size='compact'] .content {
203
230
  min-block-size: 2.75rem;
204
231
  }
@@ -84,7 +84,7 @@
84
84
  box-shadow:
85
85
  inset 0 1px 0 color-mix(in srgb, white 22%, transparent),
86
86
  inset 0 -1px 0 color-mix(in srgb, black 10%, transparent);
87
- transition: border-radius var(--dry-duration-fast, 100ms) ease;
87
+ transition: border-radius var(--dry-duration-fast) var(--dry-ease-default);
88
88
  }
89
89
 
90
90
  [data-option-picker-preview][data-variant='font'] {
@@ -109,7 +109,7 @@
109
109
  transparent
110
110
  );
111
111
  --dry-option-picker-preview-size: 2rem;
112
- transition: border-radius var(--dry-duration-fast, 100ms) ease;
112
+ transition: border-radius var(--dry-duration-fast) var(--dry-ease-default);
113
113
  }
114
114
 
115
115
  [data-option-picker-preview][data-variant='preset'][data-shape='sharp'],
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLAttributes } from 'svelte/elements';
4
- import { setSelectableTileGroupCtx } from '../option-swatch-group/context.svelte.js';
4
+ import { setOptionPickerCtx } from './context.svelte.js';
5
5
 
6
6
  interface Props extends HTMLAttributes<HTMLDivElement> {
7
7
  value?: string;
@@ -21,7 +21,7 @@
21
21
  ...rest
22
22
  }: Props = $props();
23
23
 
24
- setSelectableTileGroupCtx({
24
+ setOptionPickerCtx({
25
25
  get value() {
26
26
  return value;
27
27
  },
@@ -306,7 +306,7 @@
306
306
  }
307
307
 
308
308
  [data-phone-input]:focus-within {
309
- outline: 2px solid var(--dry-color-focus-ring);
309
+ outline: var(--dry-focus-ring);
310
310
  outline-offset: -1px;
311
311
  border-color: var(--dry-color-focus-ring);
312
312
  box-shadow: 0 0 0 1px var(--dry-color-focus-ring);
@@ -317,7 +317,7 @@
317
317
  }
318
318
 
319
319
  [data-phone-input][data-disabled] {
320
- opacity: 0.5;
320
+ opacity: var(--dry-state-disabled-opacity);
321
321
  cursor: not-allowed;
322
322
  pointer-events: none;
323
323
  }
@@ -83,7 +83,7 @@
83
83
  [data-pin-input-cell][data-active] {
84
84
  border-color: var(--dry-color-fill-brand);
85
85
  z-index: 2;
86
- outline: 2px solid var(--dry-color-focus-ring);
86
+ outline: var(--dry-focus-ring);
87
87
  outline-offset: -2px;
88
88
  }
89
89
 
@@ -292,7 +292,7 @@
292
292
  }
293
293
 
294
294
  [data-pin-input-root][data-disabled] {
295
- opacity: 0.5;
295
+ opacity: var(--dry-state-disabled-opacity);
296
296
  cursor: not-allowed;
297
297
  }
298
298
 
@@ -240,7 +240,7 @@
240
240
  [data-part='segment'] {
241
241
  background-color: var(--_segment-bg, var(--dry-progress-bar));
242
242
  height: 100%;
243
- transition: width var(--dry-duration-slow, 300ms) ease;
243
+ transition: width var(--dry-duration-slow) var(--dry-ease-default);
244
244
  }
245
245
 
246
246
  [data-part='segment']:first-child {
@@ -67,7 +67,7 @@
67
67
  }
68
68
 
69
69
  [data-scroll-area]:focus-visible {
70
- outline: 2px solid var(--dry-color-focus-ring);
70
+ outline: var(--dry-focus-ring);
71
71
  outline-offset: -2px;
72
72
  }
73
73
  </style>
@@ -0,0 +1,8 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ export interface ShimmerProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {
4
+ color?: string;
5
+ duration?: number;
6
+ children: Snippet;
7
+ }
8
+ export { default as Shimmer } from './shimmer.svelte';
@@ -0,0 +1 @@
1
+ export { default as Shimmer } from './shimmer.svelte';