@nonoun/native-ui 0.2.5 → 0.2.6

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.
@@ -3769,7 +3769,7 @@
3769
3769
  line-height: 1;
3770
3770
  min-height: var(--ui-kbd-size-md);
3771
3771
  padding-inline: 0.4em;
3772
- border-radius: 0.25rem;
3772
+ border-radius: 0.5em;
3773
3773
  background: var(--_ground, var(--_body));
3774
3774
  border: 1px solid var(--_border-muted);
3775
3775
  color: var(--_ink-muted);
@@ -4080,6 +4080,18 @@
4080
4080
  user-select: none;
4081
4081
  }
4082
4082
 
4083
+ /* WHY: Fixed-size icon well — matches ui-layout-sidebar-item [slot="icon"].
4084
+ All sidebar icons align on the same 1.5rem column regardless of icon size.
4085
+ JS wraps the first <ui-icon> child in a .icon-well span during setup(). */
4086
+ :where(ui-nav-group-header) > :where(.icon-well) {
4087
+ display: inline-flex;
4088
+ align-items: center;
4089
+ justify-content: center;
4090
+ width: 1.5rem;
4091
+ height: 1.5rem;
4092
+ flex-shrink: 0;
4093
+ }
4094
+
4083
4095
  /* ── Chevron icon (right side of summary) ── */
4084
4096
 
4085
4097
  :where(ui-nav-group) > :where(details) > :where(summary)::after {
@@ -4133,13 +4145,14 @@
4133
4145
 
4134
4146
  /* WHY: Insets account for the summary's padding-inline so the connector
4135
4147
  line passes through the icon center and child text aligns with header text. */
4136
- :where(ui-nav-group):has(:where(ui-nav-group-header) :where(ui-icon)) {
4148
+ :where(ui-nav-group):has(:where(ui-nav-group-header) :where(.icon-well)) {
4137
4149
  --_group-pad: calc(var(--_space-k) * var(--_space));
4138
- --_group-line-inset: calc(var(--_group-pad) + var(--_icon-size) / 2);
4139
- --_group-child-inset: calc(var(--_icon-size) + var(--_space) * 2);
4150
+ --_group-icon-well: 1.5rem;
4151
+ --_group-line-inset: calc(var(--_group-pad) + var(--_group-icon-well) / 2);
4152
+ --_group-child-inset: calc(var(--_group-icon-well) + var(--_space) * 2);
4140
4153
  }
4141
4154
 
4142
- :where(ui-nav-group):has(:where(ui-nav-group-header) :where(ui-icon)):has(:where(details[open]))::after {
4155
+ :where(ui-nav-group):has(:where(ui-nav-group-header) :where(.icon-well)):has(:where(details[open]))::after {
4143
4156
  content: '';
4144
4157
  position: absolute;
4145
4158
  inset-inline-start: var(--_group-line-inset);
@@ -4154,7 +4167,7 @@
4154
4167
  /* WHY: A ::before pseudo on the group slides along the connector line.
4155
4168
  JS sets --_indicator-index; :state(has-selection) gates visibility. */
4156
4169
 
4157
- :where(ui-nav-group):has(:where(ui-nav-group-header) :where(ui-icon)):has(:where(details[open])):state(has-selection)::before {
4170
+ :where(ui-nav-group):has(:where(ui-nav-group-header) :where(.icon-well)):has(:where(details[open])):state(has-selection)::before {
4158
4171
  content: '';
4159
4172
  position: absolute;
4160
4173
  z-index: 1;
@@ -4238,7 +4251,7 @@
4238
4251
  gap: 0;
4239
4252
  }
4240
4253
 
4241
- :where(ui-nav-group-header) :where(ui-icon) {
4254
+ :where(ui-nav-group-header) :where(.icon-well) :where(ui-icon) {
4242
4255
  font-size: var(--_font-size, 1rem);
4243
4256
  }
4244
4257
 
@@ -6889,6 +6902,20 @@
6889
6902
  outline-offset: -2px;
6890
6903
  }
6891
6904
 
6905
+ /* WHY: Fixed-size icon well so all sidebar icons (header logo, nav group icons,
6906
+ standalone icons) center-align on the same column width regardless of intrinsic
6907
+ icon size. 1.5rem matches the sidebar's visual rhythm at default density.
6908
+ Consumer wraps the icon: <span slot="icon"><ui-icon name="..."></ui-icon></span>
6909
+ The wrapper is the well; the icon keeps its own --ui-icon-size dimensions. */
6910
+ :where(ui-layout-sidebar-item) > :where([slot="icon"]) {
6911
+ display: inline-flex;
6912
+ align-items: center;
6913
+ justify-content: center;
6914
+ width: 1.5rem;
6915
+ height: 1.5rem;
6916
+ flex-shrink: 0;
6917
+ }
6918
+
6892
6919
  /* WHY: Trailing caret pushes to end — same pattern as button justify="spread". */
6893
6920
  :where(ui-layout-sidebar-item) > :where([slot="trailing"]) {
6894
6921
  margin-inline-start: auto;
@@ -6966,7 +6993,7 @@
6966
6993
  }
6967
6994
 
6968
6995
  :where(ui-layout-sidebar-item) > :where([slot="icon"]) {
6969
- display: block;
6996
+ display: inline-flex;
6970
6997
  }
6971
6998
 
6972
6999
  :where(ui-layout-sidebar-item) > :where(:not([slot="icon"]):not(ui-listbox[popover]):not(.nav-group-flyout)) {
@@ -3791,7 +3791,7 @@
3791
3791
  line-height: 1;
3792
3792
  min-height: var(--ui-kbd-size-md);
3793
3793
  padding-inline: 0.4em;
3794
- border-radius: 0.25rem;
3794
+ border-radius: 0.5em;
3795
3795
  background: var(--_ground, var(--_body));
3796
3796
  border: 1px solid var(--_border-muted);
3797
3797
  color: var(--_ink-muted);
@@ -4108,6 +4108,18 @@
4108
4108
  user-select: none;
4109
4109
  }
4110
4110
 
4111
+ /* WHY: Fixed-size icon well — matches ui-layout-sidebar-item [slot="icon"].
4112
+ All sidebar icons align on the same 1.5rem column regardless of icon size.
4113
+ JS wraps the first <ui-icon> child in a .icon-well span during setup(). */
4114
+ :where(ui-nav-group-header) > :where(.icon-well) {
4115
+ display: inline-flex;
4116
+ align-items: center;
4117
+ justify-content: center;
4118
+ width: 1.5rem;
4119
+ height: 1.5rem;
4120
+ flex-shrink: 0;
4121
+ }
4122
+
4111
4123
  /* ── Chevron icon (right side of summary) ── */
4112
4124
 
4113
4125
  :where(ui-nav-group) > :where(details) > :where(summary)::after {
@@ -4163,13 +4175,14 @@
4163
4175
 
4164
4176
  /* WHY: Insets account for the summary's padding-inline so the connector
4165
4177
  line passes through the icon center and child text aligns with header text. */
4166
- :where(ui-nav-group):has(:where(ui-nav-group-header) :where(ui-icon)) {
4178
+ :where(ui-nav-group):has(:where(ui-nav-group-header) :where(.icon-well)) {
4167
4179
  --_group-pad: calc(var(--_space-k) * var(--_space));
4168
- --_group-line-inset: calc(var(--_group-pad) + var(--_icon-size) / 2);
4169
- --_group-child-inset: calc(var(--_icon-size) + var(--_space) * 2);
4180
+ --_group-icon-well: 1.5rem;
4181
+ --_group-line-inset: calc(var(--_group-pad) + var(--_group-icon-well) / 2);
4182
+ --_group-child-inset: calc(var(--_group-icon-well) + var(--_space) * 2);
4170
4183
  }
4171
4184
 
4172
- :where(ui-nav-group):has(:where(ui-nav-group-header) :where(ui-icon)):has(:where(details[open]))::after {
4185
+ :where(ui-nav-group):has(:where(ui-nav-group-header) :where(.icon-well)):has(:where(details[open]))::after {
4173
4186
  content: '';
4174
4187
  position: absolute;
4175
4188
  inset-inline-start: var(--_group-line-inset);
@@ -4184,7 +4197,7 @@
4184
4197
  /* WHY: A ::before pseudo on the group slides along the connector line.
4185
4198
  JS sets --_indicator-index; :state(has-selection) gates visibility. */
4186
4199
 
4187
- :where(ui-nav-group):has(:where(ui-nav-group-header) :where(ui-icon)):has(:where(details[open])):state(has-selection)::before {
4200
+ :where(ui-nav-group):has(:where(ui-nav-group-header) :where(.icon-well)):has(:where(details[open])):state(has-selection)::before {
4188
4201
  content: '';
4189
4202
  position: absolute;
4190
4203
  z-index: 1;
@@ -4268,7 +4281,7 @@
4268
4281
  gap: 0;
4269
4282
  }
4270
4283
 
4271
- :where(ui-nav-group-header) :where(ui-icon) {
4284
+ :where(ui-nav-group-header) :where(.icon-well) :where(ui-icon) {
4272
4285
  font-size: var(--_font-size, 1rem);
4273
4286
  }
4274
4287
 
@@ -6960,6 +6973,20 @@
6960
6973
  outline-offset: -2px;
6961
6974
  }
6962
6975
 
6976
+ /* WHY: Fixed-size icon well so all sidebar icons (header logo, nav group icons,
6977
+ standalone icons) center-align on the same column width regardless of intrinsic
6978
+ icon size. 1.5rem matches the sidebar's visual rhythm at default density.
6979
+ Consumer wraps the icon: <span slot="icon"><ui-icon name="..."></ui-icon></span>
6980
+ The wrapper is the well; the icon keeps its own --ui-icon-size dimensions. */
6981
+ :where(ui-layout-sidebar-item) > :where([slot="icon"]) {
6982
+ display: inline-flex;
6983
+ align-items: center;
6984
+ justify-content: center;
6985
+ width: 1.5rem;
6986
+ height: 1.5rem;
6987
+ flex-shrink: 0;
6988
+ }
6989
+
6963
6990
  /* WHY: Trailing caret pushes to end — same pattern as button justify="spread". */
6964
6991
  :where(ui-layout-sidebar-item) > :where([slot="trailing"]) {
6965
6992
  margin-inline-start: auto;
@@ -7037,7 +7064,7 @@
7037
7064
  }
7038
7065
 
7039
7066
  :where(ui-layout-sidebar-item) > :where([slot="icon"]) {
7040
- display: block;
7067
+ display: inline-flex;
7041
7068
  }
7042
7069
 
7043
7070
  :where(ui-layout-sidebar-item) > :where(:not([slot="icon"]):not(ui-listbox[popover]):not(.nav-group-flyout)) {
@@ -4107,6 +4107,11 @@ var ve = class extends y(c) {
4107
4107
  super.setup(), this.id ||= e("ngh");
4108
4108
  let t = this.closest("ui-nav-group");
4109
4109
  t && t.setAttribute("aria-labelledby", this.id);
4110
+ let n = this.querySelector(":scope > ui-icon");
4111
+ if (n) {
4112
+ let e = document.createElement("span");
4113
+ e.className = "icon-well", this.insertBefore(e, n), e.appendChild(n);
4114
+ }
4110
4115
  }
4111
4116
  }, Y = class extends c {
4112
4117
  static observedAttributes = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nonoun/native-ui",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "Zero-dependency web component library with an OKLCH CSS design system, signal-based reactivity, and composable trait controllers",
5
5
  "license": "MIT",
6
6
  "type": "module",