@dryui/ui 1.2.0 → 1.3.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 (74) hide show
  1. package/dist/accordion/accordion-button-trigger.svelte +6 -0
  2. package/dist/alert/alert.svelte +2 -1
  3. package/dist/alert-dialog/alert-dialog-content.svelte +9 -69
  4. package/dist/alpha-slider/alpha-slider-input.svelte +4 -0
  5. package/dist/avatar/avatar.svelte +3 -4
  6. package/dist/backdrop/backdrop.svelte +12 -9
  7. package/dist/badge/badge.svelte +84 -72
  8. package/dist/button/button.svelte +3 -6
  9. package/dist/button-group/button-group.svelte +2 -2
  10. package/dist/calendar/calendar-button-grid.svelte +1 -1
  11. package/dist/card/card-root.svelte +9 -4
  12. package/dist/chip-group/chip-group-root.svelte +2 -2
  13. package/dist/code-block/code-block-button.svelte +6 -2
  14. package/dist/context-menu/context-menu-content.svelte +12 -79
  15. package/dist/diagram/diagram.svelte +3 -4
  16. package/dist/dialog/dialog-content.svelte +5 -103
  17. package/dist/drag-and-drop/drag-and-drop-item.svelte +1 -1
  18. package/dist/drawer/drawer-dialog-content.svelte +5 -155
  19. package/dist/dropdown-menu/dropdown-menu-content.svelte +14 -71
  20. package/dist/heading/heading.svelte +7 -6
  21. package/dist/hover-card/hover-card-content.svelte +3 -12
  22. package/dist/icon/icon.svelte +2 -2
  23. package/dist/index.d.ts +2 -2
  24. package/dist/index.js +1 -1
  25. package/dist/input/input.svelte +3 -3
  26. package/dist/internal/calendar-grid-button.svelte +29 -26
  27. package/dist/internal/calendar-grid-button.svelte.d.ts +1 -0
  28. package/dist/internal/close-button-base.svelte +15 -2
  29. package/dist/internal/close-button-base.svelte.d.ts +1 -0
  30. package/dist/internal/modal-content.svelte +331 -0
  31. package/dist/internal/modal-content.svelte.d.ts +26 -0
  32. package/dist/link-preview/link-preview-content.svelte +3 -11
  33. package/dist/logo-mark/logo-mark.svelte +2 -3
  34. package/dist/mask-reveal/mask-reveal.svelte +17 -14
  35. package/dist/mega-menu/mega-menu-panel.svelte +14 -2
  36. package/dist/mega-menu/mega-menu-panel.svelte.d.ts +1 -0
  37. package/dist/menubar/menubar-content.svelte +21 -81
  38. package/dist/noise/noise.svelte +1 -0
  39. package/dist/option-picker/option-picker-preview.svelte +11 -10
  40. package/dist/popover/popover-content.svelte +10 -36
  41. package/dist/progress/progress.svelte +2 -2
  42. package/dist/prompt-input/index.d.ts +13 -1
  43. package/dist/prompt-input/prompt-input-button-textarea.svelte +13 -1
  44. package/dist/prompt-input/prompt-input-button-textarea.svelte.d.ts +3 -0
  45. package/dist/shimmer/shimmer.svelte +28 -3
  46. package/dist/slider/slider-input.svelte +3 -4
  47. package/dist/spacer/spacer.svelte +2 -2
  48. package/dist/spinner/spinner.svelte +2 -2
  49. package/dist/tabs/tabs-content.svelte +1 -1
  50. package/dist/tabs/tabs-list.svelte +1 -0
  51. package/dist/tag/tag-button.svelte +2 -3
  52. package/dist/text/text.svelte +4 -15
  53. package/dist/themes/dark.css +40 -24
  54. package/dist/themes/default.css +16 -12
  55. package/dist/themes/token-scope.d.ts +1 -0
  56. package/dist/themes/token-scope.js +1 -0
  57. package/dist/timeline/timeline-icon.svelte +11 -1
  58. package/dist/timeline/timeline-item.svelte +18 -5
  59. package/dist/timeline/timeline-root.svelte +3 -10
  60. package/dist/toast/toast-close-button.svelte +19 -7
  61. package/dist/toast/toast-provider.svelte +22 -1
  62. package/dist/toggle/toggle-button.svelte +7 -3
  63. package/dist/toggle-group/toggle-group-root.svelte +2 -2
  64. package/dist/tooltip/tooltip-content.svelte +8 -32
  65. package/dist/tour/tour-root.css +26 -26
  66. package/dist/tree/tree-item-label.svelte +8 -14
  67. package/dist/tree/tree-item-label.svelte.d.ts +2 -2
  68. package/dist/typography/heading.svelte +7 -6
  69. package/dist/typography/text.svelte +4 -3
  70. package/package.json +6 -2
  71. package/skills/dryui/SKILL.md +3 -3
  72. package/skills/dryui/rules/native-web-transitions.md +2 -2
  73. package/dist/themes/use-theme-override.svelte.d.ts +0 -1
  74. package/dist/themes/use-theme-override.svelte.js +0 -1
@@ -91,19 +91,23 @@ samp {
91
91
  --dry-color-bg-brand: var(--dry-color-fill-brand);
92
92
  --dry-color-bg-inverse: hsl(233, 18%, 9%);
93
93
 
94
- /* ─── Component: Toggle ───────────────────────────────────────── */
95
- --dry-toggle-track-bg: rgba(0, 21, 128, 0.04);
96
- --dry-toggle-track-stroke: rgba(0, 13, 77, 0.45);
97
- --dry-toggle-selected-bg: #4c64d9;
98
- --dry-toggle-selected-stroke: #4c64d9;
94
+ /* ─── Component: Toggle ─────────────────────────────────────────
95
+ Derived from semantic tokens so brand overrides (e.g. a consumer
96
+ retheming --dry-color-fill-brand) flow through to toggles too.
97
+ Thumb bg is intentionally a neutral literal — it's a surface knob,
98
+ not a brand-tinted element. */
99
+ --dry-toggle-track-bg: var(--dry-color-fill-brand-weak);
100
+ --dry-toggle-track-stroke: var(--dry-color-stroke-strong);
101
+ --dry-toggle-selected-bg: var(--dry-color-fill-brand);
102
+ --dry-toggle-selected-stroke: var(--dry-color-fill-brand);
99
103
  --dry-toggle-thumb-bg: #ffffff;
100
- --dry-toggle-hover-bg: rgba(0, 21, 128, 0.04);
101
- --dry-toggle-press-bg: rgba(0, 17, 102, 0.1);
102
- --dry-toggle-disabled-fill: rgba(0, 17, 102, 0.1);
103
- --dry-toggle-disabled-stroke: rgba(0, 17, 102, 0.1);
104
- --dry-toggle-focus-ring: #4c64d9;
105
- --dry-toggle-label-color: rgba(0, 6, 38, 0.9);
106
- --dry-toggle-label-disabled-color: rgba(0, 17, 102, 0.1);
104
+ --dry-toggle-hover-bg: var(--dry-color-fill-brand-weak);
105
+ --dry-toggle-press-bg: var(--dry-color-fill-active);
106
+ --dry-toggle-disabled-fill: var(--dry-color-stroke-weak);
107
+ --dry-toggle-disabled-stroke: var(--dry-color-stroke-weak);
108
+ --dry-toggle-focus-ring: var(--dry-color-fill-brand);
109
+ --dry-toggle-label-color: var(--dry-color-text-strong);
110
+ --dry-toggle-label-disabled-color: var(--dry-color-text-disabled);
107
111
 
108
112
  /* ─── Component: Beam ─────────────────────────────────────────── */
109
113
  --dry-beam-default-blend: multiply;
@@ -0,0 +1 @@
1
+ export { TokenScope, type TokenScopeProps } from '@dryui/primitives/token-scope';
@@ -0,0 +1 @@
1
+ export { TokenScope } from '@dryui/primitives/token-scope';
@@ -21,11 +21,21 @@
21
21
  place-items: center;
22
22
  height: var(--dry-timeline-dot-size, 0.875rem);
23
23
  aspect-ratio: 1;
24
+ margin-block-start: var(
25
+ --dry-timeline-icon-offset,
26
+ calc(
27
+ (var(--dry-timeline-content-line-height, 1.5rem) - var(--dry-timeline-dot-size, 0.875rem)) /
28
+ 2
29
+ )
30
+ );
24
31
  border-radius: var(--dry-radius-full);
25
32
  background: var(--dry-timeline-dot-color, var(--dry-color-fill-brand));
26
33
  color: var(--dry-color-bg-raised);
27
- font-size: var(--dry-type-tiny-size, var(--dry-type-tiny-size));
34
+ font-family: var(--dry-font-sans);
35
+ font-size: var(--dry-timeline-icon-font-size, var(--dry-type-tiny-size));
28
36
  font-weight: 700;
37
+ font-variant-numeric: tabular-nums lining-nums;
38
+ line-height: 1;
29
39
  box-shadow: 0 0 0 3px var(--dry-color-bg-raised);
30
40
  }
31
41
  </style>
@@ -15,12 +15,18 @@
15
15
 
16
16
  <style>
17
17
  [data-part='item'] {
18
+ --_timeline-item-pl: var(--dry-timeline-item-pl, var(--dry-space-4));
19
+ --_timeline-dot-size: var(--dry-timeline-dot-size, 0.875rem);
20
+ --_timeline-line-w: var(--dry-timeline-line-w, 1px);
21
+ --_timeline-content-lh: var(--dry-timeline-content-line-height, 1.5rem);
22
+ --_timeline-gap: var(--dry-timeline-gap, var(--dry-space-4));
23
+
18
24
  position: relative;
19
25
  display: grid;
20
26
  grid-template-columns: var(--dry-timeline-item-columns, auto minmax(0, 1fr));
21
27
  align-items: start;
22
28
  gap: var(--dry-timeline-item-gap, var(--dry-space-3));
23
- padding-left: var(--dry-timeline-item-pl, var(--dry-space-4));
29
+ padding-left: var(--_timeline-item-pl);
24
30
  padding-top: var(--dry-timeline-item-pt, 0);
25
31
  }
26
32
 
@@ -29,16 +35,23 @@
29
35
  position: absolute;
30
36
  left: var(
31
37
  --dry-timeline-line-left,
32
- calc(var(--dry-timeline-dot-size, 0.875rem) / 2 + var(--dry-space-2))
38
+ calc(var(--_timeline-item-pl) + var(--_timeline-dot-size) / 2 - var(--_timeline-line-w) / 2)
33
39
  );
34
40
  top: var(
35
41
  --dry-timeline-line-top,
36
- calc(var(--dry-timeline-dot-size, 0.875rem) + var(--dry-space-1))
42
+ calc((var(--_timeline-content-lh) + var(--_timeline-dot-size)) / 2 + var(--dry-space-1))
43
+ );
44
+ bottom: var(
45
+ --dry-timeline-line-bottom,
46
+ calc(-1 * (var(--_timeline-gap) + var(--_timeline-content-lh) / 2 - var(--dry-space-1)))
37
47
  );
38
- bottom: var(--dry-timeline-line-bottom, calc(var(--dry-space-1) * -1));
39
48
  right: var(--dry-timeline-line-right, auto);
40
49
  height: var(--dry-timeline-line-h, auto);
41
- border-left: var(--dry-timeline-line-w, 1px) solid
50
+ border-left: var(--_timeline-line-w) solid
42
51
  var(--dry-timeline-line-color, var(--dry-color-stroke-weak));
43
52
  }
53
+
54
+ [data-part='item']:last-child::before {
55
+ display: none;
56
+ }
44
57
  </style>
@@ -16,15 +16,8 @@
16
16
 
17
17
  <style>
18
18
  [data-part='root'] {
19
- --dry-timeline-line-color: var(--dry-color-stroke-weak);
20
- --dry-timeline-dot-size: 0.875rem;
21
- --dry-timeline-dot-color: var(--dry-color-fill-brand);
22
- --dry-timeline-gap: var(--dry-space-4);
23
- --dry-timeline-item-gap: var(--dry-space-3);
24
- --dry-timeline-content-gap: var(--dry-space-1);
25
-
26
19
  display: grid;
27
- gap: var(--dry-timeline-gap);
20
+ gap: var(--dry-timeline-gap, var(--dry-space-4));
28
21
  color: var(--dry-color-text-strong);
29
22
  }
30
23
 
@@ -32,7 +25,7 @@
32
25
  display: grid;
33
26
  grid-auto-flow: column;
34
27
  grid-auto-columns: max-content;
35
- gap: var(--dry-space-4);
28
+ gap: var(--dry-timeline-gap, var(--dry-space-4));
36
29
  overflow-x: auto;
37
30
  padding-bottom: var(--dry-space-1);
38
31
 
@@ -41,7 +34,7 @@
41
34
  --dry-timeline-item-pl: 0;
42
35
  --dry-timeline-item-pt: var(--dry-space-4);
43
36
  --dry-timeline-line-left: 0;
44
- --dry-timeline-line-top: calc(var(--dry-timeline-dot-size) / 2 + var(--dry-space-2));
37
+ --dry-timeline-line-top: calc(var(--dry-space-4) + var(--dry-timeline-dot-size, 0.875rem) / 2);
45
38
  --dry-timeline-line-right: calc(var(--dry-space-1) * -1);
46
39
  --dry-timeline-line-bottom: auto;
47
40
  --dry-timeline-line-w: auto;
@@ -14,10 +14,22 @@
14
14
  const ctx = getToastCtx();
15
15
  </script>
16
16
 
17
- <CloseButtonBase
18
- aria-label="Close notification"
19
- {...rest}
20
- onclick={() => toastStore.remove(ctx.id)}
21
- >
22
- {@render children()}
23
- </CloseButtonBase>
17
+ <span data-part="toast-close">
18
+ <CloseButtonBase
19
+ aria-label="Close notification"
20
+ {...rest}
21
+ onclick={() => toastStore.remove(ctx.id)}
22
+ >
23
+ {@render children()}
24
+ </CloseButtonBase>
25
+ </span>
26
+
27
+ <style>
28
+ [data-part='toast-close'] {
29
+ position: absolute;
30
+ top: var(--dry-space-3);
31
+ right: var(--dry-space-3);
32
+ display: inline-grid;
33
+ --dry-btn-font-size: var(--dry-type-heading-3-size, var(--dry-text-xl-size));
34
+ }
35
+ </style>
@@ -20,10 +20,30 @@
20
20
 
21
21
  let { class: className, position = 'bottom-right', children, ...rest }: Props = $props();
22
22
  const visible = $derived(Boolean(children) || toastStore.toasts.length > 0);
23
+
24
+ let panelEl = $state<HTMLDivElement>();
25
+
26
+ $effect(() => {
27
+ if (!panelEl) return;
28
+ if (visible) {
29
+ try {
30
+ if (!panelEl.matches(':popover-open')) panelEl.showPopover();
31
+ } catch {
32
+ // already open
33
+ }
34
+ } else {
35
+ try {
36
+ if (panelEl.matches(':popover-open')) panelEl.hidePopover();
37
+ } catch {
38
+ // already closed
39
+ }
40
+ }
41
+ });
23
42
  </script>
24
43
 
25
44
  <div
26
- hidden={!visible}
45
+ bind:this={panelEl}
46
+ popover="manual"
27
47
  role="region"
28
48
  aria-label="Notifications"
29
49
  data-part="provider"
@@ -71,6 +91,7 @@
71
91
  margin: 0;
72
92
  border: none;
73
93
  background: transparent;
94
+ color: inherit;
74
95
  overflow: visible;
75
96
  container-type: inline-size;
76
97
 
@@ -88,10 +88,8 @@
88
88
  <style>
89
89
  .root {
90
90
  display: inline-grid;
91
- grid-template-columns: var(--_track-w) max-content;
91
+ grid-template-columns: var(--_track-w);
92
92
  align-items: center;
93
- gap: var(--_gap);
94
- padding-inline-end: var(--_gap);
95
93
  --dry-btn-bg: var(--dry-toggle-track-bg, var(--dry-color-fill-weak));
96
94
  --dry-btn-border: var(--dry-toggle-track-stroke, var(--dry-color-stroke-strong));
97
95
  --dry-btn-radius: var(--_track-w);
@@ -101,6 +99,12 @@
101
99
  --dry-btn-min-height: var(--_track-h);
102
100
  }
103
101
 
102
+ .root:has(.label) {
103
+ grid-template-columns: var(--_track-w) max-content;
104
+ gap: var(--_gap);
105
+ padding-inline-end: var(--_gap);
106
+ }
107
+
104
108
  .root[data-state='on'] {
105
109
  --dry-btn-bg: var(--dry-toggle-selected-bg, var(--dry-color-fill-selected));
106
110
  }
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLAttributes } from 'svelte/elements';
4
+ import { variantAttrs } from '@dryui/primitives';
4
5
  import { setToggleGroupCtx } from './context.svelte.js';
5
6
 
6
7
  interface Props extends HTMLAttributes<HTMLDivElement> {
@@ -57,8 +58,7 @@
57
58
  role="toolbar"
58
59
  aria-orientation={orientation}
59
60
  data-part="root"
60
- data-orientation={orientation}
61
- data-size={size}
61
+ {...variantAttrs({ orientation, size })}
62
62
  class={className}
63
63
  {...rest}
64
64
  >
@@ -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 { createAnchorPosition, type Placement } from '@dryui/primitives';
4
+ import { createAnchoredPopover, type Placement } from '@dryui/primitives';
5
5
  import { getTooltipCtx } from './context.svelte.js';
6
6
 
7
7
  interface Props extends HTMLAttributes<HTMLDivElement> {
@@ -23,37 +23,12 @@
23
23
 
24
24
  let contentEl = $state<HTMLDivElement>();
25
25
 
26
- const anchor = createAnchorPosition(
27
- () => ctx.triggerEl,
28
- () => contentEl ?? null,
29
- {
30
- get placement() {
31
- return placement;
32
- },
33
- get offset() {
34
- return offset;
35
- }
36
- }
37
- );
38
-
39
- $effect(() => {
40
- if (!contentEl) return;
41
-
42
- contentEl.style.cssText = typeof style === 'string' ? style : '';
43
- const positionStyles = anchor.styles;
44
- for (const [key, value] of Object.entries(positionStyles)) {
45
- contentEl.style.setProperty(key, value);
46
- }
47
- });
48
-
49
- $effect(() => {
50
- if (!contentEl) return;
51
-
52
- if (ctx.open && !contentEl.matches(':popover-open')) {
53
- contentEl.showPopover();
54
- } else if (!ctx.open && contentEl.matches(':popover-open')) {
55
- contentEl.hidePopover();
56
- }
26
+ const popover = createAnchoredPopover({
27
+ triggerEl: () => ctx.triggerEl,
28
+ contentEl: () => contentEl ?? null,
29
+ open: () => ctx.open,
30
+ placement: () => placement,
31
+ offset: () => offset
57
32
  });
58
33
  </script>
59
34
 
@@ -64,6 +39,7 @@
64
39
  popover="manual"
65
40
  data-tooltip-content
66
41
  data-state={ctx.open ? 'open' : 'closed'}
42
+ use:popover.applyPosition={style}
67
43
  class={className}
68
44
  {...rest}
69
45
  >
@@ -1,11 +1,11 @@
1
- [data-tour-root] [data-tour-overlay] {
1
+ [data-tour-overlay] {
2
2
  position: fixed;
3
3
  inset: 0;
4
4
  z-index: var(--dry-layer-tour-overlay);
5
5
  pointer-events: auto;
6
6
  }
7
7
 
8
- [data-tour-root] [data-tour-spotlight] {
8
+ [data-tour-spotlight] {
9
9
  --dry-tour-overlay-color: var(--dry-color-overlay-backdrop-strong);
10
10
  --dry-tour-spotlight-padding: 8px;
11
11
  --dry-tour-spotlight-radius: 4px;
@@ -29,7 +29,7 @@
29
29
  height var(--dry-duration-normal) var(--dry-ease-out);
30
30
  }
31
31
 
32
- [data-tour-root] [data-part='tooltip'] {
32
+ [data-tour-tooltip] {
33
33
  --dry-tour-tooltip-bg: var(--dry-color-bg-overlay);
34
34
  --dry-tour-tooltip-radius: var(--dry-radius-xl);
35
35
  --dry-tour-tooltip-shadow: var(--dry-shadow-overlay);
@@ -59,7 +59,7 @@
59
59
  opacity var(--dry-duration-fast) var(--dry-ease-out);
60
60
  }
61
61
 
62
- [data-tour-root] [data-part='tooltipTitle'] {
62
+ [data-tour-tooltip] [data-part='tooltipTitle'] {
63
63
  font-family: var(--dry-font-sans);
64
64
  font-size: var(--dry-type-small-size, var(--dry-text-base-size));
65
65
  font-weight: 600;
@@ -68,7 +68,7 @@
68
68
  line-height: 1.3;
69
69
  }
70
70
 
71
- [data-tour-root] [data-part='tooltipContent'] {
71
+ [data-tour-tooltip] [data-part='tooltipContent'] {
72
72
  font-family: var(--dry-font-sans);
73
73
  font-size: var(--dry-type-small-size, var(--dry-text-sm-size));
74
74
  line-height: var(--dry-type-small-leading, var(--dry-text-sm-leading));
@@ -76,20 +76,20 @@
76
76
  margin: 0 0 var(--dry-space-4);
77
77
  }
78
78
 
79
- [data-tour-root] [data-part='tooltipFooter'] {
79
+ [data-tour-tooltip] [data-part='tooltipFooter'] {
80
80
  display: grid;
81
81
  grid-template-columns: 1fr auto;
82
82
  align-items: center;
83
83
  gap: var(--dry-space-3);
84
84
  }
85
85
 
86
- [data-tour-root] [data-part='tooltipCounter'] {
86
+ [data-tour-tooltip] [data-part='tooltipCounter'] {
87
87
  font-family: var(--dry-font-sans);
88
88
  font-size: var(--dry-type-tiny-size, var(--dry-text-xs-size));
89
89
  color: var(--dry-color-text-weak);
90
90
  }
91
91
 
92
- [data-tour-root] [data-part='tooltipActions'] {
92
+ [data-tour-tooltip] [data-part='tooltipActions'] {
93
93
  display: grid;
94
94
  grid-auto-flow: column;
95
95
  grid-auto-columns: max-content;
@@ -98,7 +98,7 @@
98
98
  justify-items: end;
99
99
  }
100
100
 
101
- [data-tour-root] [data-part='skipButton'] {
101
+ [data-tour-tooltip] [data-part='skipButton'] {
102
102
  font-family: var(--dry-font-sans);
103
103
  font-size: var(--dry-type-small-size, var(--dry-text-sm-size));
104
104
  color: var(--dry-color-text-weak);
@@ -110,16 +110,16 @@
110
110
  transition: color var(--dry-duration-fast);
111
111
  }
112
112
 
113
- [data-tour-root] [data-part='skipButton']:hover {
113
+ [data-tour-tooltip] [data-part='skipButton']:hover {
114
114
  color: var(--dry-color-text-strong);
115
115
  }
116
116
 
117
- [data-tour-root] [data-part='skipButton']:focus-visible {
117
+ [data-tour-tooltip] [data-part='skipButton']:focus-visible {
118
118
  outline: var(--dry-focus-ring);
119
119
  outline-offset: 2px;
120
120
  }
121
121
 
122
- [data-tour-root] [data-part='prevButton'] {
122
+ [data-tour-tooltip] [data-part='prevButton'] {
123
123
  font-family: var(--dry-font-sans);
124
124
  font-size: var(--dry-type-small-size, var(--dry-text-sm-size));
125
125
  color: var(--dry-color-text-strong);
@@ -131,16 +131,16 @@
131
131
  transition: background var(--dry-duration-fast);
132
132
  }
133
133
 
134
- [data-tour-root] [data-part='prevButton']:hover {
134
+ [data-tour-tooltip] [data-part='prevButton']:hover {
135
135
  background: var(--dry-color-bg-raised);
136
136
  }
137
137
 
138
- [data-tour-root] [data-part='prevButton']:focus-visible {
138
+ [data-tour-tooltip] [data-part='prevButton']:focus-visible {
139
139
  outline: var(--dry-focus-ring);
140
140
  outline-offset: 2px;
141
141
  }
142
142
 
143
- [data-tour-root] [data-part='nextButton'] {
143
+ [data-tour-tooltip] [data-part='nextButton'] {
144
144
  font-family: var(--dry-font-sans);
145
145
  font-size: var(--dry-type-small-size, var(--dry-text-sm-size));
146
146
  color: var(--dry-color-on-brand);
@@ -152,16 +152,16 @@
152
152
  transition: opacity var(--dry-duration-fast);
153
153
  }
154
154
 
155
- [data-tour-root] [data-part='nextButton']:hover {
155
+ [data-tour-tooltip] [data-part='nextButton']:hover {
156
156
  opacity: 0.9;
157
157
  }
158
158
 
159
- [data-tour-root] [data-part='nextButton']:focus-visible {
159
+ [data-tour-tooltip] [data-part='nextButton']:focus-visible {
160
160
  outline: var(--dry-focus-ring);
161
161
  outline-offset: 2px;
162
162
  }
163
163
 
164
- [data-tour-root] [data-part='tooltip']::before {
164
+ [data-tour-tooltip]::before {
165
165
  content: '';
166
166
  position: absolute;
167
167
  height: var(--dry-tour-arrow-size);
@@ -171,28 +171,28 @@
171
171
  transform: translate(-50%, -50%) rotate(45deg);
172
172
  }
173
173
 
174
- [data-tour-root] [data-part='tooltip'][data-placement='bottom']::before {
174
+ [data-tour-tooltip][data-placement='bottom']::before {
175
175
  top: 0;
176
176
  left: var(--dry-tour-tooltip-arrow-offset, 50%);
177
177
  border-right: none;
178
178
  border-bottom: none;
179
179
  }
180
180
 
181
- [data-tour-root] [data-part='tooltip'][data-placement='top']::before {
182
- bottom: 0;
181
+ [data-tour-tooltip][data-placement='top']::before {
182
+ top: 100%;
183
183
  left: var(--dry-tour-tooltip-arrow-offset, 50%);
184
184
  border-left: none;
185
185
  border-top: none;
186
186
  }
187
187
 
188
- [data-tour-root] [data-part='tooltip'][data-placement='left']::before {
189
- right: 0;
188
+ [data-tour-tooltip][data-placement='left']::before {
189
+ left: 100%;
190
190
  top: var(--dry-tour-tooltip-arrow-offset, 50%);
191
191
  border-left: none;
192
192
  border-bottom: none;
193
193
  }
194
194
 
195
- [data-tour-root] [data-part='tooltip'][data-placement='right']::before {
195
+ [data-tour-tooltip][data-placement='right']::before {
196
196
  left: 0;
197
197
  top: var(--dry-tour-tooltip-arrow-offset, 50%);
198
198
  border-right: none;
@@ -200,11 +200,11 @@
200
200
  }
201
201
 
202
202
  @container (max-width: 480px) {
203
- [data-tour-root] [data-part='tooltip'] {
203
+ [data-tour-tooltip] {
204
204
  grid-template-columns: minmax(0, min(16rem, calc(100vw - var(--dry-space-4))));
205
205
  }
206
206
 
207
- [data-tour-root] [data-part='tooltipFooter'] {
207
+ [data-tour-tooltip] [data-part='tooltipFooter'] {
208
208
  grid-template-columns: 1fr;
209
209
  align-items: stretch;
210
210
  }
@@ -1,9 +1,9 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
- import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { HTMLButtonAttributes } from 'svelte/elements';
4
4
  import { getTreeCtx, getTreeItemCtx } from './context.svelte.js';
5
5
 
6
- interface Props extends HTMLAttributes<HTMLDivElement> {
6
+ interface Props extends HTMLButtonAttributes {
7
7
  children: Snippet;
8
8
  }
9
9
 
@@ -13,9 +13,8 @@
13
13
  const itemCtx = getTreeItemCtx();
14
14
  </script>
15
15
 
16
- <div
17
- role="button"
18
- tabindex={0}
16
+ <button
17
+ type="button"
19
18
  data-part="label"
20
19
  data-tree-label
21
20
  data-selected={ctx.isSelected(itemCtx.itemId) || undefined}
@@ -24,29 +23,24 @@
24
23
  ctx.selectItem(itemCtx.itemId);
25
24
  ctx.toggleItem(itemCtx.itemId);
26
25
  }}
27
- onkeydown={(e) => {
28
- if (e.key === 'Enter' || e.key === ' ') {
29
- e.preventDefault();
30
- ctx.selectItem(itemCtx.itemId);
31
- ctx.toggleItem(itemCtx.itemId);
32
- }
33
- }}
34
26
  {...rest}
35
27
  >
36
28
  {@render children()}
37
- </div>
29
+ </button>
38
30
 
39
31
  <style>
40
32
  [data-part='label'] {
33
+ appearance: none;
41
34
  display: grid;
42
35
  grid-auto-flow: column;
43
36
  grid-auto-columns: max-content;
44
37
  align-items: center;
45
38
  gap: var(--dry-space-2);
46
39
  padding: var(--dry-tree-item-padding, var(--dry-space-1) var(--dry-space-2));
47
- border: none;
40
+ border: 0;
48
41
  border-radius: var(--dry-tree-item-radius, var(--dry-radius-md));
49
42
  background: none;
43
+ text-align: inherit;
50
44
  font-size: var(--dry-type-small-size, var(--dry-text-sm-size));
51
45
  font-family: var(--dry-font-sans);
52
46
  color: var(--dry-color-text-strong);
@@ -1,6 +1,6 @@
1
1
  import type { Snippet } from 'svelte';
2
- import type { HTMLAttributes } from 'svelte/elements';
3
- interface Props extends HTMLAttributes<HTMLDivElement> {
2
+ import type { HTMLButtonAttributes } from 'svelte/elements';
3
+ interface Props extends HTMLButtonAttributes {
4
4
  children: Snippet;
5
5
  }
6
6
  declare const TreeItemLabel: import("svelte").Component<Props, {}, "">;
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLAttributes } from 'svelte/elements';
4
+ import { variantAttrs } from '@dryui/primitives';
4
5
 
5
6
  interface Props extends HTMLAttributes<HTMLHeadingElement> {
6
7
  level?: 1 | 2 | 3 | 4 | 5 | 6;
@@ -12,27 +13,27 @@
12
13
  </script>
13
14
 
14
15
  {#if level === 1}
15
- <h1 class={className} data-level={level} data-variant={variant} {...rest}>
16
+ <h1 class={className} {...variantAttrs({ level, variant })} {...rest}>
16
17
  {@render children()}
17
18
  </h1>
18
19
  {:else if level === 2}
19
- <h2 class={className} data-level={level} data-variant={variant} {...rest}>
20
+ <h2 class={className} {...variantAttrs({ level, variant })} {...rest}>
20
21
  {@render children()}
21
22
  </h2>
22
23
  {:else if level === 3}
23
- <h3 class={className} data-level={level} data-variant={variant} {...rest}>
24
+ <h3 class={className} {...variantAttrs({ level, variant })} {...rest}>
24
25
  {@render children()}
25
26
  </h3>
26
27
  {:else if level === 4}
27
- <h4 class={className} data-level={level} data-variant={variant} {...rest}>
28
+ <h4 class={className} {...variantAttrs({ level, variant })} {...rest}>
28
29
  {@render children()}
29
30
  </h4>
30
31
  {:else if level === 5}
31
- <h5 class={className} data-level={level} data-variant={variant} {...rest}>
32
+ <h5 class={className} {...variantAttrs({ level, variant })} {...rest}>
32
33
  {@render children()}
33
34
  </h5>
34
35
  {:else}
35
- <h6 class={className} data-level={level} data-variant={variant} {...rest}>
36
+ <h6 class={className} {...variantAttrs({ level, variant })} {...rest}>
36
37
  {@render children()}
37
38
  </h6>
38
39
  {/if}
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
3
  import type { HTMLAttributes } from 'svelte/elements';
4
+ import { variantAttrs } from '@dryui/primitives';
4
5
 
5
6
  interface Props extends HTMLAttributes<HTMLElement> {
6
7
  as?: 'p' | 'span' | 'div';
@@ -24,15 +25,15 @@
24
25
  </script>
25
26
 
26
27
  {#if as === 'span'}
27
- <span class={className} data-as={as} data-color={tone} data-size={size} {...rest}
28
+ <span class={className} {...variantAttrs({ as, color: tone, size })} {...rest}
28
29
  >{@render children()}</span
29
30
  >
30
31
  {:else if as === 'div'}
31
- <div class={className} data-as={as} data-color={tone} data-size={size} {...rest}>
32
+ <div class={className} {...variantAttrs({ as, color: tone, size })} {...rest}>
32
33
  {@render children()}
33
34
  </div>
34
35
  {:else}
35
- <p class={className} data-as={as} data-color={tone} data-size={size} {...rest}>
36
+ <p class={className} {...variantAttrs({ as, color: tone, size })} {...rest}>
36
37
  {@render children()}
37
38
  </p>
38
39
  {/if}
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@dryui/ui",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
+ "description": "Zero-dependency styled Svelte 5 components with scoped styles and --dry-* CSS variable theming.",
4
5
  "author": "Rob Balfre",
5
6
  "license": "MIT",
6
7
  "repository": {
@@ -13,6 +14,9 @@
13
14
  "url": "https://github.com/rob-balfre/dryui/issues"
14
15
  },
15
16
  "type": "module",
17
+ "sideEffects": [
18
+ "**/*.css"
19
+ ],
16
20
  "svelte": "./dist/index.js",
17
21
  "types": "./dist/index.d.ts",
18
22
  "exports": {
@@ -775,7 +779,7 @@
775
779
  "postpack": "bun ../../scripts/postpack-exports.ts"
776
780
  },
777
781
  "dependencies": {
778
- "@dryui/primitives": "^1.2.0"
782
+ "@dryui/primitives": "^1.3.0"
779
783
  },
780
784
  "peerDependencies": {
781
785
  "svelte": "^5.55.1"