@milktop/react-ui 0.1.2 → 0.2.1

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 (142) hide show
  1. package/README.md +57 -6
  2. package/dist/accordion/Accordion.d.ts +1 -1
  3. package/dist/accordion/Accordion.js +1 -1
  4. package/dist/action-bar/ActionBar.d.ts +1 -1
  5. package/dist/action-bar/ActionBar.js +1 -1
  6. package/dist/alert/Alert.d.ts +1 -1
  7. package/dist/alert/Alert.js +1 -1
  8. package/dist/app-shell/AppShell.d.ts +9 -1
  9. package/dist/app-shell/AppShell.js +46 -5
  10. package/dist/app-shell/Topbar.d.ts +1 -1
  11. package/dist/app-shell/Topbar.js +1 -1
  12. package/dist/app-shell/app-shell.css +5 -0
  13. package/dist/app-shell/shell.d.ts +2 -0
  14. package/dist/appearance-panel/Appearance.d.ts +39 -0
  15. package/dist/appearance-panel/Appearance.js +74 -0
  16. package/dist/appearance-panel/appearance.css +17 -0
  17. package/dist/appearance.d.ts +42 -0
  18. package/dist/appearance.js +157 -0
  19. package/dist/attachments/Attachments.d.ts +1 -1
  20. package/dist/attachments/Attachments.js +1 -1
  21. package/dist/avatar/Avatar.d.ts +1 -1
  22. package/dist/avatar/Avatar.js +1 -1
  23. package/dist/badge/Badge.d.ts +1 -1
  24. package/dist/badge/Badge.js +1 -1
  25. package/dist/banner/Banner.d.ts +1 -1
  26. package/dist/banner/Banner.js +1 -1
  27. package/dist/breadcrumbs/Breadcrumbs.d.ts +1 -1
  28. package/dist/breadcrumbs/Breadcrumbs.js +1 -1
  29. package/dist/button/Button.d.ts +3 -2
  30. package/dist/button/Button.js +1 -1
  31. package/dist/card/Card.d.ts +2 -2
  32. package/dist/card/Card.js +1 -1
  33. package/dist/checkbox/Checkbox.d.ts +1 -1
  34. package/dist/checkbox/Checkbox.js +1 -1
  35. package/dist/checkbox/CheckboxGroup.d.ts +1 -1
  36. package/dist/checkbox/CheckboxGroup.js +1 -1
  37. package/dist/checkbox/checkbox.css +1 -1
  38. package/dist/collapsible/Collapsible.d.ts +1 -1
  39. package/dist/collapsible/Collapsible.js +1 -1
  40. package/dist/command/Command.d.ts +1 -1
  41. package/dist/command/Command.js +1 -1
  42. package/dist/copy-button/CopyButton.d.ts +1 -1
  43. package/dist/copy-button/CopyButton.js +1 -1
  44. package/dist/data-list/DataList.d.ts +1 -1
  45. package/dist/data-list/DataList.js +1 -1
  46. package/dist/date-picker/DatePicker.d.ts +1 -1
  47. package/dist/date-picker/DatePicker.js +1 -1
  48. package/dist/date-picker/date-picker.css +6 -3
  49. package/dist/dialog/Dialog.d.ts +1 -1
  50. package/dist/dialog/Dialog.js +1 -1
  51. package/dist/editable/Editable.d.ts +1 -1
  52. package/dist/editable/Editable.js +1 -1
  53. package/dist/editor/Editor.d.ts +1 -1
  54. package/dist/editor/Editor.js +1 -1
  55. package/dist/editor/editor.css +2 -1
  56. package/dist/empty-state/EmptyState.d.ts +1 -1
  57. package/dist/empty-state/EmptyState.js +1 -1
  58. package/dist/event-calendar/EventCalendar.d.ts +12 -5
  59. package/dist/event-calendar/EventCalendar.js +155 -41
  60. package/dist/event-calendar/event-calendar.css +10 -5
  61. package/dist/file-upload/FileUpload.d.ts +1 -1
  62. package/dist/file-upload/FileUpload.js +1 -1
  63. package/dist/format/messages.d.ts +12 -0
  64. package/dist/format/messages.js +12 -0
  65. package/dist/hover-card/hover-card.css +3 -1
  66. package/dist/icons.d.ts +1 -0
  67. package/dist/icons.js +7 -0
  68. package/dist/index.d.ts +2 -0
  69. package/dist/index.js +2 -0
  70. package/dist/input/Input.d.ts +1 -1
  71. package/dist/input/Input.js +1 -1
  72. package/dist/input/input.css +7 -1
  73. package/dist/menu/Menu.d.ts +1 -1
  74. package/dist/menu/Menu.js +1 -1
  75. package/dist/menu/menu.css +3 -1
  76. package/dist/native-select/NativeSelect.d.ts +1 -1
  77. package/dist/native-select/NativeSelect.js +1 -1
  78. package/dist/native-select/native-select.css +2 -1
  79. package/dist/number-input/NumberInput.d.ts +1 -1
  80. package/dist/number-input/NumberInput.js +1 -1
  81. package/dist/number-input/number-input.css +6 -3
  82. package/dist/page/Page.d.ts +4 -0
  83. package/dist/page/Page.js +4 -2
  84. package/dist/pagination/Pagination.d.ts +1 -1
  85. package/dist/pagination/Pagination.js +1 -1
  86. package/dist/password-input/PasswordInput.d.ts +1 -1
  87. package/dist/password-input/PasswordInput.js +1 -1
  88. package/dist/password-input/password-input.css +6 -3
  89. package/dist/pin-input/pin-input.css +2 -1
  90. package/dist/popover/Popover.d.ts +1 -1
  91. package/dist/popover/Popover.js +1 -1
  92. package/dist/popover/popover.css +3 -1
  93. package/dist/radio-group/RadioGroup.d.ts +1 -1
  94. package/dist/radio-group/RadioGroup.js +1 -1
  95. package/dist/radio-group/radio-group.css +1 -1
  96. package/dist/segment-group/Segmented.d.ts +1 -1
  97. package/dist/segment-group/Segmented.js +1 -1
  98. package/dist/select/ListSelect.d.ts +1 -1
  99. package/dist/select/ListSelect.js +1 -1
  100. package/dist/select/SearchSelect.d.ts +1 -1
  101. package/dist/select/SearchSelect.js +1 -1
  102. package/dist/select/search-select.css +6 -3
  103. package/dist/select/select.css +5 -2
  104. package/dist/sheet/Sheet.d.ts +1 -1
  105. package/dist/sheet/Sheet.js +1 -1
  106. package/dist/sidebar/NavGroup.d.ts +3 -2
  107. package/dist/sidebar/NavGroup.js +14 -4
  108. package/dist/sidebar/NavItem.d.ts +1 -1
  109. package/dist/sidebar/NavItem.js +1 -1
  110. package/dist/sidebar/NavSection.d.ts +1 -1
  111. package/dist/sidebar/NavSection.js +1 -1
  112. package/dist/sidebar/Sidebar.d.ts +1 -1
  113. package/dist/sidebar/Sidebar.js +1 -1
  114. package/dist/sidebar/SidebarUser.d.ts +1 -1
  115. package/dist/sidebar/SidebarUser.js +1 -1
  116. package/dist/sidebar/sidebar.css +75 -14
  117. package/dist/sortable-list/SortableList.d.ts +1 -1
  118. package/dist/sortable-list/SortableList.js +1 -1
  119. package/dist/stat/Stat.d.ts +1 -1
  120. package/dist/stat/Stat.js +1 -1
  121. package/dist/swatch-picker/SwatchPicker.d.ts +1 -1
  122. package/dist/swatch-picker/SwatchPicker.js +1 -1
  123. package/dist/swatch-picker/swatch-picker.css +3 -2
  124. package/dist/table/Table.d.ts +1 -1
  125. package/dist/table/Table.js +1 -1
  126. package/dist/tabs/Tabs.d.ts +1 -1
  127. package/dist/tabs/Tabs.js +1 -1
  128. package/dist/tags-input/TagsInput.d.ts +1 -1
  129. package/dist/tags-input/TagsInput.js +1 -1
  130. package/dist/tags-input/tags-input.css +6 -3
  131. package/dist/textarea/textarea.css +2 -1
  132. package/dist/theme-toggle/ThemeToggle.d.ts +1 -1
  133. package/dist/theme-toggle/ThemeToggle.js +1 -1
  134. package/dist/theme.css +51 -10
  135. package/dist/timeline/Timeline.d.ts +1 -1
  136. package/dist/timeline/Timeline.js +1 -1
  137. package/dist/toast/Toaster.d.ts +1 -1
  138. package/dist/toast/Toaster.js +1 -1
  139. package/dist/tooltip/tooltip.css +3 -1
  140. package/dist/tree-view/TreeView.d.ts +1 -1
  141. package/dist/tree-view/TreeView.js +1 -1
  142. package/package.json +7 -6
@@ -1,14 +1,19 @@
1
1
  @layer ui {
2
2
  [data-scope=sidebar][data-part=root] { display: flex; flex-direction: column; width: var(--ui-sidebar-width); height: 100dvh;
3
3
  position: sticky; top: 0; z-index: 35; flex-shrink: 0; box-sizing: border-box; overflow: hidden;
4
- background: var(--ui-sidebar-surface); border-right: 1px solid var(--ui-border); font-size: 14px; }
4
+ background: var(--ui-sidebar-surface); color: var(--ui-sidebar-text); border-right: 1px solid var(--ui-sidebar-border); font-size: 14px; }
5
5
  [data-scope=sidebar][data-part=root] {
6
6
  transition: width 200ms ease;
7
+ /* Sticky makes it a stacking context (z-index 35: over the page, under the
8
+ top bar's popups), so its flyouts can't rise out of it. While it's in
9
+ use it goes over the top bar, which would otherwise cover those near
10
+ the top. They're its children, so hovering one still counts. */
11
+ &:is(:hover, :focus-within) { z-index: 37; }
7
12
  /* The rail: icons only. */
8
13
  &[data-rail] { width: var(--ui-sidebar-rail-width); }
9
14
  /* The drawer, on phones. */
10
15
  &[data-mobile] { position: fixed; left: 0; top: 0; bottom: 0; z-index: 50; width: min(18rem, 85vw); display: none;
11
- box-shadow: var(--ui-shadow); background: var(--ui-surface); }
16
+ box-shadow: var(--ui-shadow); background: var(--ui-sidebar-surface); }
12
17
  &[data-mobile][data-open] { display: flex; animation: ui-drawer-in 200ms ease-out; } }
13
18
  @keyframes ui-drawer-in { from { translate: -100% 0; } }
14
19
  [data-scope=sidebar][data-part=header] { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
@@ -21,10 +26,17 @@
21
26
  &:focus-visible { outline: 2px solid var(--ui-ring-soft); }
22
27
  [data-part=footer] > & { margin: 0 auto; } }
23
28
  [data-scope=sidebar][data-part=nav] { display: flex; flex-direction: column; gap: 1rem; flex-grow: 1; overflow-y: auto; padding: 0.5rem; }
24
- [data-scope=sidebar][data-part=footer] { display: flex; flex-direction: column; gap: 0.25rem; padding: 0.75rem 0.5rem; flex-shrink: 0; }
29
+ /* A faint line above the footer (SidebarUser), like the top bar's. */
30
+ [data-scope=sidebar][data-part=footer] { display: flex; flex-direction: column; gap: 0.25rem; padding: 0.75rem 0.5rem; flex-shrink: 0;
31
+ border-top: 1px solid var(--ui-sidebar-divider); }
25
32
 
26
33
  [data-scope=nav-section][data-part=root] { display: flex; flex-direction: column; gap: 0.125rem; }
27
- [data-scope=nav-section][data-part=heading-row] { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; height: 1.5rem; padding-right: 0.25rem; }
34
+ [data-scope=nav-section][data-part=heading-row] { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; height: 1.5rem; padding-right: 0.25rem;
35
+ transition: height 150ms, margin 150ms;
36
+ /* In the rail the heading row shrinks to a divider that keeps sections
37
+ apart (none above the first), rather than leaving its height as a gap. */
38
+ [data-rail] & { height: 1px; margin: 0.375rem 0.5rem; background: var(--ui-sidebar-divider); overflow: hidden; }
39
+ [data-rail] [data-part=root]:first-child > & { display: none; } }
28
40
  [data-scope=nav-section][data-part=heading] { display: flex; align-items: center; flex-grow: 1; padding: 0 0.75rem;
29
41
  font-size: 12px; font-weight: 600; color: var(--ui-sidebar-heading); white-space: nowrap; overflow: hidden; }
30
42
  [data-scope=nav-section][data-part=collapse-all] { display: grid; place-items: center; width: 1.5rem; height: 1.5rem; padding: 0;
@@ -48,7 +60,8 @@
48
60
  &:focus-visible { outline: 2px solid var(--ui-ring-soft); outline-offset: -2px; }
49
61
  [data-active] > & { background: var(--ui-sidebar-active); color: var(--ui-sidebar-active-text);
50
62
  font-weight: var(--ui-sidebar-active-weight); box-shadow: var(--ui-sidebar-active-shadow); } }
51
- [data-scope=nav-item][data-part=icon] { font-size: 16px; width: 1rem; height: 1rem; flex-shrink: 0; }
63
+ [data-scope=nav-item][data-part=icon] { font-size: 16px; width: 1rem; height: 1rem; flex-shrink: 0;
64
+ [data-active] > [data-part=link] > & { color: var(--ui-sidebar-active-icon); } }
52
65
  [data-scope=nav-item][data-part=text] { flex-grow: 1; overflow: hidden; text-overflow: ellipsis; }
53
66
  [data-scope=nav-item][data-part=badge] { flex-shrink: 0; min-width: 1.25rem; height: 1.25rem; padding: 0 0.375rem; box-sizing: border-box;
54
67
  display: inline-flex; align-items: center; justify-content: center; border-radius: 9999px;
@@ -70,20 +83,25 @@
70
83
  [data-flyout] > & { background: var(--ui-sidebar-active); color: var(--ui-sidebar-active-text); box-shadow: var(--ui-sidebar-active-shadow); } }
71
84
  [data-scope=nav-group][data-part=icon] { font-size: 16px; width: 1rem; height: 1rem; flex-shrink: 0; }
72
85
  [data-scope=nav-group][data-part=text] { flex-grow: 1; overflow: hidden; text-overflow: ellipsis; }
73
- [data-scope=nav-group][data-part=indicator] { color: var(--ui-muted); font-size: 14px; transition: rotate 200ms;
86
+ [data-scope=nav-group][data-part=indicator] { color: var(--ui-sidebar-muted); font-size: 14px; transition: rotate 200ms;
74
87
  [data-open] > [data-part=trigger] > & { rotate: 180deg; } }
75
88
  [data-scope=nav-group][data-part=panel] { display: flex; flex-direction: column; gap: 0.125rem;
76
- margin: 0.125rem 0 0 1.25rem; padding-left: 0.5rem; border-left: 1px solid var(--ui-border); }
89
+ margin: 0.125rem 0 0 1.25rem; padding-left: 0.5rem; border-left: 1px solid var(--ui-sidebar-border); }
77
90
 
78
91
  /* In the rail: a panel beside the toggle. The wrapper's left padding
79
92
  bridges the gap, so the pointer can cross to it without closing it. */
80
93
  [data-scope=nav-group][data-part=children] {
81
94
  [data-rail] > & { position: fixed; top: var(--flyout-top); left: var(--flyout-left); z-index: 50; padding-left: 0.5rem; } }
82
95
  [data-scope=nav-group][data-part=panel] {
83
- [data-rail] > [data-part=children] > & { margin: 0; padding: 0.375rem; min-width: 11rem; border: 1px solid var(--ui-border);
84
- border-radius: calc(var(--ui-radius) + 2px); background: var(--ui-surface); box-shadow: var(--ui-shadow); animation: ui-flyout-in 120ms ease-out;
85
- /* On the white flyout, the plain (not inset) colours again. */
86
- --ui-sidebar-hover: var(--ui-hover); --ui-sidebar-active: var(--ui-hover); --ui-sidebar-active-shadow: none; } }
96
+ [data-rail] > [data-part=children] > & { margin: 0; padding: 0.375rem; min-width: 11rem; max-height: calc(100vh - 16px); box-sizing: border-box;
97
+ overflow-y: auto; border: 1px solid var(--ui-border); border-radius: calc(var(--ui-radius) + 2px); background: var(--ui-surface);
98
+ box-shadow: var(--ui-shadow); animation: ui-flyout-in 120ms ease-out;
99
+ /* On the white flyout, the plain (not inset) colours again, and the
100
+ page's text colours, should the sidebar be coloured. */
101
+ --ui-sidebar-hover: var(--ui-hover); --ui-sidebar-active: var(--ui-hover); --ui-sidebar-active-shadow: none;
102
+ --ui-sidebar-text: var(--ui-text); --ui-sidebar-muted: var(--ui-muted); --ui-sidebar-border: var(--ui-border); --ui-sidebar-divider: var(--ui-border);
103
+ --ui-sidebar-item-text: var(--ui-muted); --ui-sidebar-hover-text: var(--ui-text); --ui-sidebar-active-text: var(--ui-text);
104
+ color: var(--ui-text); } }
87
105
  [data-scope=nav-group][data-part=flyout-heading] { padding: 0.25rem 0.75rem 0.375rem; font-size: 12px; font-weight: 600; color: var(--ui-muted); }
88
106
  /* Inside the flyout, items show their labels again. */
89
107
  [data-scope=sidebar][data-rail] [data-part=panel] :is([data-scope=nav-item][data-part=link]) { justify-content: flex-start; padding: var(--ui-sidebar-item-padding); }
@@ -92,7 +110,7 @@
92
110
 
93
111
  [data-scope=sidebar-user][data-part=root] { display: block; width: 100%; }
94
112
  [data-scope=sidebar-user][data-part=trigger] { display: flex; align-items: center; gap: 0.625rem; width: 100%; padding: 0.375rem; box-sizing: border-box;
95
- border: none; border-radius: var(--ui-radius); background: transparent; color: var(--ui-text); font-family: inherit; font-size: 13px;
113
+ border: none; border-radius: var(--ui-radius); background: transparent; color: var(--ui-sidebar-text); font-family: inherit; font-size: 13px;
96
114
  text-align: left; white-space: nowrap; cursor: pointer;
97
115
  &:hover { background: var(--ui-sidebar-hover); }
98
116
  &:focus-visible { outline: 2px solid var(--ui-ring-soft); outline-offset: -2px; }
@@ -101,9 +119,52 @@
101
119
  [data-scope=sidebar-user][data-part=text] { display: flex; flex-direction: column; flex-grow: 1; min-width: 0; line-height: 1.3;
102
120
  [data-rail] > [data-part=trigger] > & { display: none; } }
103
121
  [data-scope=sidebar-user][data-part=name] { font-weight: 500; overflow: hidden; text-overflow: ellipsis; }
104
- [data-scope=sidebar-user][data-part=description] { font-size: 12px; color: var(--ui-muted); overflow: hidden; text-overflow: ellipsis; }
105
- [data-scope=sidebar-user][data-part=indicator] { flex-shrink: 0; color: var(--ui-muted); font-size: 14px;
122
+ [data-scope=sidebar-user][data-part=description] { font-size: 12px; color: var(--ui-sidebar-muted); overflow: hidden; text-overflow: ellipsis; }
123
+ [data-scope=sidebar-user][data-part=indicator] { flex-shrink: 0; color: var(--ui-sidebar-muted); font-size: 14px;
106
124
  [data-rail] > [data-part=trigger] > & { display: none; } }
107
125
  /* As wide as the trigger when it opens upwards, and never narrower than 13rem. */
108
126
  [data-scope=sidebar-user] [data-scope=menu][data-part=content] { min-width: max(13rem, var(--reference-width)); }
127
+
128
+ /* The sidebar styles `appearance` sets (data-ui-sidebar-style on <html>):
129
+ the sidebar tokens for both layouts (the plain one's surface and the
130
+ inset one's background), in light mode. They're set on the sidebar
131
+ itself, so they win over tokens set on <html>. */
132
+ /* Grey, the current page's icon in the accent (neutral-accent: the old
133
+ name, which a page may still paint before the bundle loads). */
134
+ :root:not(.dark):is([data-ui-sidebar-style=neutral], [data-ui-sidebar-style=neutral-accent]) [data-scope=sidebar][data-part=root] {
135
+ --ui-sidebar-hover: #eef0f3; --ui-sidebar-inset-hover: #eef0f3;
136
+ --ui-sidebar-active: #e6e9ee; --ui-sidebar-inset-active: #e6e9ee; --ui-sidebar-inset-active-shadow: none;
137
+ --ui-sidebar-active-icon: var(--ui-accent); }
138
+ :root:not(.dark)[data-ui-sidebar-style=soft] [data-scope=sidebar][data-part=root] {
139
+ --ui-sidebar-hover: var(--ui-accent-soft); --ui-sidebar-inset-hover: var(--ui-accent-soft);
140
+ --ui-sidebar-active: var(--ui-accent-soft); --ui-sidebar-inset-active: var(--ui-accent-soft); --ui-sidebar-inset-active-shadow: none; }
141
+ :root:not(.dark)[data-ui-sidebar-style=tint] [data-scope=sidebar][data-part=root] {
142
+ --ui-sidebar-surface: var(--ui-accent-50); --ui-sidebar-bg: var(--ui-accent-50);
143
+ --ui-sidebar-hover: color-mix(in srgb, var(--ui-accent-100) 60%, transparent);
144
+ --ui-sidebar-inset-hover: color-mix(in srgb, var(--ui-accent-100) 60%, transparent);
145
+ --ui-sidebar-active: var(--ui-accent-100); --ui-sidebar-inset-active: var(--ui-accent-100); --ui-sidebar-inset-active-shadow: none;
146
+ --ui-sidebar-active-text: var(--ui-accent-800); }
147
+ /* The coloured ones: white text and translucent white hovers. */
148
+ :root:not(.dark):is([data-ui-sidebar-style=accent], [data-ui-sidebar-style=dark], [data-ui-sidebar-style=deep]) [data-scope=sidebar][data-part=root] {
149
+ --ui-sidebar-text: white; --ui-sidebar-muted: rgba(255, 255, 255, 0.6);
150
+ --ui-sidebar-border: transparent; --ui-sidebar-divider: rgba(255, 255, 255, 0.12);
151
+ --ui-sidebar-item-text: rgba(255, 255, 255, 0.88); --ui-sidebar-heading: rgba(255, 255, 255, 0.55); --ui-sidebar-icon: rgba(255, 255, 255, 0.7);
152
+ --ui-sidebar-hover-text: white; --ui-sidebar-active-text: white;
153
+ --ui-sidebar-hover: rgba(255, 255, 255, 0.08); --ui-sidebar-inset-hover: rgba(255, 255, 255, 0.08);
154
+ --ui-sidebar-active-shadow: none; --ui-sidebar-inset-active-shadow: none; }
155
+ :root:not(.dark)[data-ui-sidebar-style=accent] [data-scope=sidebar][data-part=root] {
156
+ --ui-sidebar-surface: var(--ui-accent-600); --ui-sidebar-bg: var(--ui-accent-600);
157
+ --ui-sidebar-item-text: white; --ui-sidebar-heading: rgba(255, 255, 255, 0.7); --ui-sidebar-icon: rgba(255, 255, 255, 0.85);
158
+ /* Like the dark ones (below), a little stronger on the lighter colour. */
159
+ --ui-sidebar-hover: rgba(255, 255, 255, 0.1); --ui-sidebar-inset-hover: rgba(255, 255, 255, 0.1);
160
+ --ui-sidebar-active: rgba(255, 255, 255, 0.18); --ui-sidebar-inset-active: rgba(255, 255, 255, 0.18); }
161
+ /* The dark ones: the current page a stronger version of the hover, so it
162
+ stays quiet whatever the accent. */
163
+ :root:not(.dark):is([data-ui-sidebar-style=dark], [data-ui-sidebar-style=deep]) [data-scope=sidebar][data-part=root] {
164
+ --ui-sidebar-hover: rgba(255, 255, 255, 0.06); --ui-sidebar-inset-hover: rgba(255, 255, 255, 0.06);
165
+ --ui-sidebar-active: rgba(255, 255, 255, 0.12); --ui-sidebar-inset-active: rgba(255, 255, 255, 0.12); }
166
+ :root:not(.dark)[data-ui-sidebar-style=dark] [data-scope=sidebar][data-part=root] {
167
+ --ui-sidebar-surface: var(--ui-accent-900); --ui-sidebar-bg: var(--ui-accent-900); }
168
+ :root:not(.dark)[data-ui-sidebar-style=deep] [data-scope=sidebar][data-part=root] {
169
+ --ui-sidebar-surface: var(--ui-accent-950); --ui-sidebar-bg: var(--ui-accent-950); }
109
170
  }
@@ -21,7 +21,7 @@
21
21
  * - `disabled`: no reordering; `label`: the list's accessible name
22
22
  */
23
23
  import { type HTMLAttributes, type ReactNode } from 'react';
24
- import 'iconify-icon';
24
+ import '../icons.js';
25
25
  import { type Classes } from '../utils.js';
26
26
  import '../theme.css';
27
27
  import './sortable-list.css';
@@ -25,7 +25,7 @@ import { useRef } from 'react';
25
25
  import { DndContext, KeyboardSensor, PointerSensor, closestCenter, useSensor, useSensors, } from '@dnd-kit/core';
26
26
  import { SortableContext, arrayMove, sortableKeyboardCoordinates, useSortable, verticalListSortingStrategy } from '@dnd-kit/sortable';
27
27
  import { CSS } from '@dnd-kit/utilities';
28
- import 'iconify-icon';
28
+ import '../icons.js';
29
29
  import { cx, partsOf, useControllable } from '../utils.js';
30
30
  import { useMessages } from '../format/LocaleProvider.js';
31
31
  import '../theme.css';
@@ -19,7 +19,7 @@
19
19
  * Group stats in Stats for a responsive grid.
20
20
  */
21
21
  import type { HTMLAttributes, ReactNode } from 'react';
22
- import 'iconify-icon';
22
+ import '../icons.js';
23
23
  import { type Classes } from '../utils.js';
24
24
  import '../theme.css';
25
25
  import './stat.css';
package/dist/stat/Stat.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import 'iconify-icon';
2
+ import '../icons.js';
3
3
  import { formatNumber } from '../format/format.js';
4
4
  import { useLocale, useMessages } from '../format/LocaleProvider.js';
5
5
  import { RollingNumber } from '../rolling-number/RollingNumber.js';
@@ -21,7 +21,7 @@
21
21
  */
22
22
  import { type ReactNode } from 'react';
23
23
  import { RadioGroup as Ark } from '@ark-ui/react/radio-group';
24
- import 'iconify-icon';
24
+ import '../icons.js';
25
25
  import { type Classes } from '../utils.js';
26
26
  import '../theme.css';
27
27
  import './swatch-picker.css';
@@ -24,7 +24,7 @@ import { useId, useState } from 'react';
24
24
  import { Popover } from '../popover/Popover.js';
25
25
  import { RadioGroup as Ark } from '@ark-ui/react/radio-group';
26
26
  import { useFieldContext } from '@ark-ui/react/field';
27
- import 'iconify-icon';
27
+ import '../icons.js';
28
28
  import { cx, partsOf, useControllable } from '../utils.js';
29
29
  import { useMessages } from '../format/LocaleProvider.js';
30
30
  import '../theme.css';
@@ -20,8 +20,9 @@
20
20
  /* The popover variant: a field showing the colour, like our inputs. */
21
21
  [data-scope=swatch-picker][data-part=field] { display: block; min-width: 0; color: var(--ui-text); font-family: var(--ui-font); }
22
22
  [data-scope=swatch-picker][data-part=trigger] { display: flex; align-items: center; gap: 0.5rem; width: 100%; min-width: 0; box-sizing: border-box;
23
- height: var(--ui-control-height); padding: 0 0.625rem; border: 1px solid var(--ui-border); border-radius: var(--ui-radius);
24
- background: var(--ui-surface); color: var(--ui-text); font: inherit; font-size: 14px; text-align: left; cursor: pointer;
23
+ height: var(--ui-control-height); padding: 0 0.625rem; border: 1px solid var(--ui-field-border); border-radius: var(--ui-radius);
24
+ background: var(--ui-field-bg); color: var(--ui-text); font: inherit; font-size: 14px; text-align: left; cursor: pointer;
25
+ &:hover { border-color: var(--ui-field-border-hover); }
25
26
  &:focus-visible, &[aria-expanded=true] { border-color: var(--ui-ring); outline: 2px solid var(--ui-ring-soft); }
26
27
  &[aria-invalid=true] { border-color: var(--ui-danger); }
27
28
  &:disabled { opacity: 0.5; cursor: not-allowed; }
@@ -37,7 +37,7 @@
37
37
  * sorting, selection or loading states); `data-align` on cells works too.
38
38
  */
39
39
  import { type HTMLAttributes, type ReactNode } from 'react';
40
- import 'iconify-icon';
40
+ import '../icons.js';
41
41
  import { type Classes } from '../utils.js';
42
42
  import '../theme.css';
43
43
  import './table.css';
@@ -38,7 +38,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
38
38
  * sorting, selection or loading states); `data-align` on cells works too.
39
39
  */
40
40
  import { useEffect, useRef } from 'react';
41
- import 'iconify-icon';
41
+ import '../icons.js';
42
42
  import { Checkbox } from '../checkbox/Checkbox.js';
43
43
  import { Skeleton } from '../skeleton/Skeleton.js';
44
44
  import { cx, partsOf, useControllable } from '../utils.js';
@@ -30,7 +30,7 @@
30
30
  */
31
31
  import { type ReactElement, type ReactNode } from 'react';
32
32
  import { Tabs as Ark, type TabsValueChangeDetails } from '@ark-ui/react/tabs';
33
- import 'iconify-icon';
33
+ import '../icons.js';
34
34
  import { type Classes } from '../utils.js';
35
35
  import '../theme.css';
36
36
  import './tabs.css';
package/dist/tabs/Tabs.js CHANGED
@@ -31,7 +31,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
31
31
  */
32
32
  import { Children, isValidElement, useEffect } from 'react';
33
33
  import { Tabs as Ark } from '@ark-ui/react/tabs';
34
- import 'iconify-icon';
34
+ import '../icons.js';
35
35
  import { cx, partOf, partsOf, useControllable, withParts } from '../utils.js';
36
36
  import '../theme.css';
37
37
  import './tabs.css';
@@ -33,7 +33,7 @@
33
33
  */
34
34
  import { type ReactNode } from 'react';
35
35
  import { TagsInput as Ark, type TagsInputValueChangeDetails } from '@ark-ui/react/tags-input';
36
- import 'iconify-icon';
36
+ import '../icons.js';
37
37
  import { type Classes } from '../utils.js';
38
38
  import '../theme.css';
39
39
  import './tags-input.css';
@@ -35,7 +35,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
35
35
  import { useRef, useState } from 'react';
36
36
  import { TagsInput as Ark, useTagsInput } from '@ark-ui/react/tags-input';
37
37
  import { useFieldContext } from '@ark-ui/react/field';
38
- import 'iconify-icon';
38
+ import '../icons.js';
39
39
  import { cx, partOf, partsOf, useControllable, withParts } from '../utils.js';
40
40
  import { useMessages } from '../format/LocaleProvider.js';
41
41
  import '../theme.css';
@@ -7,9 +7,11 @@
7
7
  &[data-variant=outline] { --tag-bg: var(--ui-surface); --tag-border: var(--ui-border); } }
8
8
  [data-scope=tags-input][data-part=label] { display: block; font-size: 14px; font-weight: 500; margin-bottom: 0.375rem; }
9
9
  [data-scope=tags-input][data-part=control] { display: flex; align-items: center; gap: 0.25rem; min-height: var(--ui-control-height);
10
- padding: 0.25rem 0.25rem 0.25rem 0.375rem; box-sizing: border-box; background: var(--ui-surface);
11
- border: 1px solid var(--ui-border); border-radius: var(--ui-radius); font-size: 14px; cursor: text;
10
+ padding: 0.25rem 0.25rem 0.25rem 0.375rem; box-sizing: border-box; background: var(--ui-field-bg);
11
+ border: 1px solid var(--ui-field-border); border-radius: var(--ui-radius); font-size: 14px; cursor: text;
12
+ &:hover { border-color: var(--ui-field-border-hover); }
12
13
  &:focus-within { border-color: var(--ui-ring); outline: 2px solid var(--ui-ring-soft); }
14
+ &:has(input:autofill) { background: var(--ui-field-autofill-bg); }
13
15
  &[data-invalid], &:has([aria-invalid=true]), &[data-rejected] { border-color: var(--ui-danger); }
14
16
  &[data-rejected] { animation: ui-shake 300ms; }
15
17
  &[data-disabled] { opacity: 0.5; } }
@@ -28,7 +30,8 @@
28
30
  color: inherit; font-family: inherit; font-size: 13px; outline: none; }
29
31
  [data-scope=tags-input][data-part=input] { flex: 1; min-width: 4rem; height: 1.625rem; padding: 0 0.25rem; border: none;
30
32
  background: transparent; outline: none; color: inherit; font: inherit;
31
- &::placeholder { color: var(--ui-muted); } }
33
+ &::placeholder { color: var(--ui-muted); }
34
+ &:autofill { transition-property: background-color, color; transition-delay: 600000s; -webkit-text-fill-color: var(--ui-text); caret-color: var(--ui-text); } }
32
35
  [data-scope=tags-input][data-part=clear-trigger] { display: grid; place-items: center; flex-shrink: 0; align-self: center;
33
36
  width: 1.75rem; height: 1.75rem; border: none; background: transparent; border-radius: 4px; color: var(--ui-muted); cursor: pointer;
34
37
  &:hover { background: var(--ui-hover); color: var(--ui-text); } }
@@ -2,8 +2,9 @@
2
2
  [data-scope=textarea][data-part=root] { display: block; min-width: 0; color: var(--ui-text); font-family: var(--ui-font); }
3
3
  [data-scope=textarea][data-part=label] { display: block; font-size: 14px; font-weight: 500; margin-bottom: 0.375rem; }
4
4
  [data-scope=textarea][data-part=control] { display: block; min-width: 0; padding: 0.5rem 0.75rem; box-sizing: border-box;
5
- background: var(--ui-surface); border: 1px solid var(--ui-border); border-radius: var(--ui-radius);
5
+ background: var(--ui-field-bg); border: 1px solid var(--ui-field-border); border-radius: var(--ui-radius);
6
6
  color: var(--ui-text); font-family: var(--ui-font); font-size: 14px;
7
+ &:hover { border-color: var(--ui-field-border-hover); }
7
8
  &:focus-within { border-color: var(--ui-ring); outline: 2px solid var(--ui-ring-soft); }
8
9
  &:has([aria-invalid=true]) { border-color: var(--ui-danger); }
9
10
  &:has(:disabled) { opacity: 0.5; } }
@@ -24,7 +24,7 @@
24
24
  */
25
25
  import { type ComponentProps } from 'react';
26
26
  import { Menu } from '../menu/Menu.js';
27
- import 'iconify-icon';
27
+ import '../icons.js';
28
28
  import { type Scheme } from '../color-scheme.js';
29
29
  import { type Classes } from '../utils.js';
30
30
  import '../theme.css';
@@ -25,7 +25,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
25
25
  */
26
26
  import { useEffect, useState } from 'react';
27
27
  import { Menu } from '../menu/Menu.js';
28
- import 'iconify-icon';
28
+ import '../icons.js';
29
29
  import { Segmented } from '../segment-group/Segmented.js';
30
30
  import { Tooltip } from '../tooltip/Tooltip.js';
31
31
  import { useColorScheme } from '../color-scheme.js';
package/dist/theme.css CHANGED
@@ -23,18 +23,44 @@
23
23
  --ui-sidebar-bg: #f8f9fb;
24
24
  --ui-frame: white;
25
25
  --ui-border: #e4e4e7;
26
+ /* Form controls (inputs, selects, checkboxes, …): their fill and border, and
27
+ the border on hover. Light, they match cards; dark, they sit a step below
28
+ the card with a stronger edge, so they read as places to type. */
29
+ --ui-field-bg: var(--ui-surface);
30
+ --ui-field-border: var(--ui-border);
31
+ --ui-field-border-hover: #d4d4d8;
32
+ /* Text inputs the browser autofilled: a faint accent tint in place of its
33
+ own colour (--ui-field-bg hides it). */
34
+ --ui-field-autofill-bg: color-mix(in srgb, var(--ui-accent) 8%, var(--ui-field-bg));
26
35
  --ui-hover: #f4f4f5;
27
36
  /* Loading placeholders: visible on the canvas and on cards alike. */
28
37
  --ui-skeleton: #e4e4e7;
29
- --ui-accent: #2563eb;
38
+ /* The accent as an 11-step scale (Tailwind's blue until `appearance`, or
39
+ your own CSS, sets another); the accent tokens below are steps of it,
40
+ so setting the scale recolours them all, in light and dark.
41
+ --ui-accent-500-text is the text that reads on the 500 (dark mode's
42
+ accent): white, or the 950 for light accents like teal. */
43
+ --ui-accent-50: #eff6ff;
44
+ --ui-accent-100: #dbeafe;
45
+ --ui-accent-200: #bfdbfe;
46
+ --ui-accent-300: #93c5fd;
47
+ --ui-accent-400: #60a5fa;
48
+ --ui-accent-500: #3b82f6;
49
+ --ui-accent-600: #2563eb;
50
+ --ui-accent-700: #1d4ed8;
51
+ --ui-accent-800: #1e40af;
52
+ --ui-accent-900: #1e3a8a;
53
+ --ui-accent-950: #172554;
54
+ --ui-accent-500-text: white;
55
+ --ui-accent: var(--ui-accent-600);
30
56
  --ui-accent-text: white;
31
- --ui-accent-soft: #dbeafe;
32
- --ui-accent-soft-text: #1e40af;
57
+ --ui-accent-soft: var(--ui-accent-100);
58
+ --ui-accent-soft-text: var(--ui-accent-800);
33
59
  /* Selected text, and Highlight's marks. */
34
60
  --ui-selection: color-mix(in srgb, var(--ui-accent) 24%, transparent);
35
61
  --ui-highlight: color-mix(in srgb, var(--ui-accent) 22%, transparent);
36
- --ui-ring: #3b82f6;
37
- --ui-ring-soft: #3b82f633;
62
+ --ui-ring: var(--ui-accent-500);
63
+ --ui-ring-soft: color-mix(in srgb, var(--ui-accent-500) 20%, transparent);
38
64
  --ui-danger: #dc2626;
39
65
  --ui-success: #16a34a;
40
66
  --ui-warning: #d97706;
@@ -52,6 +78,8 @@
52
78
  --ui-control-height: 2.25rem;
53
79
  --ui-control-height-sm: 2rem;
54
80
  --ui-control-height-lg: 2.75rem;
81
+ /* Stroke icons' line weight (Lucide's own is 2, in a 24-unit grid). */
82
+ --ui-icon-stroke: 2;
55
83
  /* Sidebar and its items. */
56
84
  --ui-sidebar-width: 15rem;
57
85
  --ui-sidebar-rail-width: 3.5rem;
@@ -63,6 +91,13 @@
63
91
  its section headings, its own icon buttons, and hovered items' text.
64
92
  With the item tokens, enough for a coloured sidebar. */
65
93
  --ui-sidebar-surface: var(--ui-surface);
94
+ /* Its text outside the nav items (the logo, SidebarUser), muted text, and
95
+ its edge and nested groups' rule: for a coloured sidebar. */
96
+ --ui-sidebar-text: var(--ui-text);
97
+ --ui-sidebar-muted: var(--ui-muted);
98
+ --ui-sidebar-border: var(--ui-border);
99
+ /* The line above its footer. */
100
+ --ui-sidebar-divider: var(--ui-border);
66
101
  --ui-sidebar-heading: var(--ui-muted);
67
102
  --ui-sidebar-icon: var(--ui-muted);
68
103
  --ui-sidebar-hover-text: var(--ui-text);
@@ -71,6 +106,8 @@
71
106
  --ui-sidebar-active-text: var(--ui-text);
72
107
  --ui-sidebar-active-weight: 500;
73
108
  --ui-sidebar-active-shadow: none;
109
+ /* The current page's icon (its text colour by default). */
110
+ --ui-sidebar-active-icon: currentColor;
74
111
  /* The inset layout's sidebar is grey, so its hovered and current items go white. */
75
112
  --ui-sidebar-inset-hover: color-mix(in srgb, var(--ui-surface) 75%, transparent);
76
113
  --ui-sidebar-inset-active: var(--ui-surface);
@@ -85,15 +122,19 @@
85
122
  --ui-sidebar-bg: #0c0c0e;
86
123
  --ui-frame: #0c0c0e;
87
124
  --ui-border: #2b2b31;
125
+ --ui-field-bg: #17171b;
126
+ --ui-field-border: #3a3a42;
127
+ --ui-field-border-hover: #4a4a53;
88
128
  --ui-hover: #27272d;
89
129
  --ui-skeleton: #303036;
90
- --ui-accent: #3b82f6;
91
- --ui-accent-soft: #1e3a8a;
92
- --ui-accent-soft-text: #bfdbfe;
130
+ --ui-accent: var(--ui-accent-500);
131
+ --ui-accent-text: var(--ui-accent-500-text);
132
+ --ui-accent-soft: var(--ui-accent-900);
133
+ --ui-accent-soft-text: var(--ui-accent-200);
93
134
  --ui-selection: color-mix(in srgb, var(--ui-accent) 40%, transparent);
94
135
  --ui-highlight: color-mix(in srgb, var(--ui-accent) 35%, transparent);
95
- --ui-ring: #60a5fa;
96
- --ui-ring-soft: #60a5fa33;
136
+ --ui-ring: var(--ui-accent-400);
137
+ --ui-ring-soft: color-mix(in srgb, var(--ui-accent-400) 20%, transparent);
97
138
  --ui-danger: #f87171;
98
139
  --ui-success: #4ade80;
99
140
  --ui-warning: #fbbf24;
@@ -22,7 +22,7 @@
22
22
  * under the title
23
23
  */
24
24
  import type { HTMLAttributes, LiHTMLAttributes, ReactNode } from 'react';
25
- import 'iconify-icon';
25
+ import '../icons.js';
26
26
  import { type Classes } from '../utils.js';
27
27
  import '../theme.css';
28
28
  import './timeline.css';
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import 'iconify-icon';
2
+ import '../icons.js';
3
3
  import { cx, partsOf, withParts } from '../utils.js';
4
4
  import '../theme.css';
5
5
  import './timeline.css';
@@ -18,7 +18,7 @@
18
18
  */
19
19
  import type { ReactNode } from 'react';
20
20
  import { Toast, createToaster, type CreateToasterReturn, type ToastOptions } from '@ark-ui/react/toast';
21
- import 'iconify-icon';
21
+ import '../icons.js';
22
22
  import { type Classes } from '../utils.js';
23
23
  import '../theme.css';
24
24
  import './toast.css';
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Toaster as ArkToaster, Toast, createToaster } from '@ark-ui/react/toast';
3
3
  import { Portal } from '@ark-ui/react/portal';
4
- import 'iconify-icon';
4
+ import '../icons.js';
5
5
  import { cx, partsOf } from '../utils.js';
6
6
  import { useMessages } from '../format/LocaleProvider.js';
7
7
  import '../theme.css';
@@ -1,6 +1,8 @@
1
1
  @layer ui {
2
2
  [data-scope=tooltip][data-part=trigger] { display: inline-flex; }
3
- /* Zag copies the content's z-index onto its positioner. */
3
+ /* The positioner carries the z-index itself. Zag sets it inline as
4
+ var(--z-index) but doesn't always fill in the variable, so set both. */
5
+ [data-scope=tooltip][data-part=positioner] { z-index: 60; --z-index: 60; }
4
6
  [data-scope=tooltip][data-part=content] {
5
7
  z-index: 60; max-width: 16rem; padding: 0.25rem 0.5rem; white-space: normal; font-weight: 400;
6
8
  background: var(--ui-text); color: var(--ui-surface); font-family: var(--ui-font); font-size: 12px; line-height: 1.4;
@@ -24,7 +24,7 @@
24
24
  */
25
25
  import { type ReactNode } from 'react';
26
26
  import { TreeView as Ark, createTreeCollection } from '@ark-ui/react/tree-view';
27
- import 'iconify-icon';
27
+ import '../icons.js';
28
28
  import { type Classes } from '../utils.js';
29
29
  import '../theme.css';
30
30
  import './tree-view.css';
@@ -25,7 +25,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
25
25
  */
26
26
  import { useMemo } from 'react';
27
27
  import { TreeView as Ark, createTreeCollection, useTreeViewNodeContext } from '@ark-ui/react/tree-view';
28
- import 'iconify-icon';
28
+ import '../icons.js';
29
29
  import { cx, on, partsOf, withParts } from '../utils.js';
30
30
  import { useMessages } from '../format/LocaleProvider.js';
31
31
  import '../theme.css';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milktop/react-ui",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
4
  "description": "React components on Ark UI (Zag state machines), with imba-ui's API and design",
5
5
  "license": "MIT",
6
6
  "author": "André Goldstein",
@@ -22,7 +22,8 @@
22
22
  ],
23
23
  "type": "module",
24
24
  "sideEffects": [
25
- "*.css"
25
+ "*.css",
26
+ "./dist/icons.js"
26
27
  ],
27
28
  "main": "./dist/index.js",
28
29
  "types": "./dist/index.d.ts",
@@ -52,10 +53,10 @@
52
53
  "prepublishOnly": "npm run build:lib",
53
54
  "preversion": "npm run check && npm run build:lib",
54
55
  "postversion": "git push --follow-tags",
55
- "release:patch": "npm version patch && npm publish",
56
- "release:minor": "npm version minor && npm publish",
57
- "release:major": "npm version major && npm publish",
58
- "release:beta": "npm version prerelease --preid beta && npm publish --tag beta"
56
+ "release:patch": "npm version patch",
57
+ "release:minor": "npm version minor",
58
+ "release:major": "npm version major",
59
+ "release:beta": "npm version prerelease --preid beta"
59
60
  },
60
61
  "peerDependencies": {
61
62
  "react": "^19.0.0",