@bagelink/vue 1.15.61 → 1.15.63

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/vue",
3
3
  "type": "module",
4
- "version": "1.15.61",
4
+ "version": "1.15.63",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Bagel Studio",
@@ -484,7 +484,7 @@ transform-origin: top left;
484
484
 
485
485
  /* Default menu breathing room so consumers don't wrap content in py-* just to
486
486
  stop items touching the rounded edges. */
487
- .bgl-dropdown__content--card {
487
+ .bgl-dropdown__content--card .bgl_card{
488
488
  padding-block: 0.375rem;
489
489
  }
490
490
 
@@ -173,6 +173,7 @@ const sidebarStyles = computed(() => {
173
173
  v-for="link in props.navLinks" :key="link.to || link.label"
174
174
  :link="link"
175
175
  :open="isVisuallyOpen"
176
+ :real-open="isOpen"
176
177
  :is-mobile="isMobile"
177
178
  :bg-color="props.bgColor"
178
179
  :text-color="props.textColor"
@@ -36,9 +36,9 @@ const slots = useSlots()
36
36
  />
37
37
 
38
38
  <!-- horizontal with label/slot: line — content — line -->
39
- <div v-else-if="label || slots.default" class="bgl-divider-labeled" :class="className" role="separator">
39
+ <div v-else-if="label || slots.default" class="bgl-divider-labeled flex gap-075" :class="className" role="separator">
40
40
  <span class="divider bgl-divider-line" />
41
- <span class="bgl-divider-label"><slot>{{ label }}</slot></span>
41
+ <span class="bgl-divider-label flex-shrink-0 white-space-nowrap"><slot>{{ label }}</slot></span>
42
42
  <span class="divider bgl-divider-line" />
43
43
  </div>
44
44
 
@@ -47,18 +47,11 @@ const slots = useSlots()
47
47
  </template>
48
48
 
49
49
  <style scoped>
50
- .bgl-divider-labeled {
51
- display: flex;
52
- align-items: center;
53
- gap: 0.75rem;
54
- }
55
50
  .bgl-divider-line {
56
51
  flex: 1;
57
52
  }
58
53
  .bgl-divider-label {
59
54
  font-size: 0.8125rem;
60
55
  color: var(--bgl-text-soft, var(--bgl-gray));
61
- white-space: nowrap;
62
- flex-shrink: 0;
63
56
  }
64
57
  </style>
@@ -13,8 +13,10 @@ interface LinkWithAction extends NavLink {
13
13
 
14
14
  const props = withDefaults(defineProps<{
15
15
  link: LinkWithAction
16
- /** sidebar is expanded (true) or collapsed to icons (false) */
16
+ /** sidebar is visually expanded (stays true during the collapse transition) */
17
17
  open: boolean
18
+ /** real open state — flips immediately when the user toggles the sidebar */
19
+ realOpen?: boolean
18
20
  isMobile: boolean
19
21
  bgColor: string
20
22
  textColor: string
@@ -45,6 +47,16 @@ const isActive = computed(() => selfActive.value || (hasChildren.value && childA
45
47
  const expanded = ref(childActive.value)
46
48
  watch(childActive, v => { if (v) expanded.value = true })
47
49
 
50
+ // Collapse the open child group smoothly *before* the layout switches to the
51
+ // icon-only flyout, so parents don't jump up when the sidebar narrows. We watch
52
+ // `realOpen` (which flips immediately on toggle) rather than `open` (which stays
53
+ // true throughout the width transition), so the grid-rows collapse animation runs
54
+ // in sync with the sidebar narrowing instead of snapping at the end.
55
+ watch(() => props.realOpen, (isOpenNow) => {
56
+ if (isOpenNow) expanded.value = childActive.value
57
+ else expanded.value = false
58
+ })
59
+
48
60
  function onParentClick() {
49
61
  if (hasChildren.value) expanded.value = !expanded.value
50
62
  else props.link.action?.()
@@ -71,11 +83,10 @@ function onParentClick() {
71
83
  <!-- PARENT with children, EXPANDED sidebar -->
72
84
  <div v-else-if="open || isMobile" class="sidebar-group w100p">
73
85
  <Btn
74
- fullWidth alignTxt="start" class="flex-shrink-0 px-075 sidebar-group-toggle"
75
- :class="{ 'nav-btn-active': isActive }"
86
+ fullWidth alignTxt="start" flat class="flex-shrink-0 px-075 sidebar-group-toggle txt-start sidebar-parent"
87
+ :class="{ 'sidebar-parent-active bold': isActive }"
76
88
  :style="{
77
- backgroundColor: isActive ? activeColor : bgColor,
78
- color: isActive ? 'white' : textColor,
89
+ color: isActive ? activeColor : textColor,
79
90
  }"
80
91
  @click="onParentClick"
81
92
  >
@@ -84,19 +95,22 @@ function onParentClick() {
84
95
  <Icon name="expand_more" size="1.1" class="nav-text sidebar-chevron" :class="{ 'sidebar-chevron-open': expanded }" />
85
96
  </Btn>
86
97
  <div class="sidebar-children" :class="{ 'sidebar-children-open': expanded }">
87
- <Btn
88
- v-for="child in link.children" :key="child.to || child.label"
89
- fullWidth alignTxt="start" class="flex-shrink-0 ps-2 pe-075 sidebar-child"
90
- :class="{ 'nav-btn-active': linkActive(child) }"
91
- :style="{
92
- backgroundColor: linkActive(child) ? activeColor : 'transparent',
93
- color: linkActive(child) ? 'white' : textColor,
94
- }"
95
- :to="child.to || '/'" @click="child.action"
96
- >
97
- <Icon v-if="child.icon" :name="child.icon" size="1.05" class="opacity-7" />
98
- <span class="nav-text">{{ resolveI18n(child.label) }}</span>
99
- </Btn>
98
+ <div class="sidebar-children-inner ps-1">
99
+ <Btn
100
+ v-for="child in link.children" :key="child.to || child.label"
101
+ fullWidth alignTxt="start" class="flex-shrink-0 ps-075 pe-075 sidebar-child"
102
+ :class="{ 'bold sidebar-child-active': linkActive(child) }"
103
+ :style="{
104
+ color: linkActive(child) ? activeColor : textColor,
105
+ '--sidebar-active-color': activeColor,
106
+ }"
107
+ flat
108
+ :to="child.to || '/'" @click="child.action"
109
+ >
110
+ <Icon v-if="child.icon" :name="child.icon" size="1.05" class="opacity-7" />
111
+ <span class="nav-text">{{ resolveI18n(child.label) }}</span>
112
+ </Btn>
113
+ </div>
100
114
  </div>
101
115
  </div>
102
116
 
@@ -105,6 +119,7 @@ function onParentClick() {
105
119
  v-else
106
120
  placement="right-start"
107
121
  :triggers="['hover']"
122
+ :delay="{ show: 0, hide: 200 }"
108
123
  card
109
124
  class="w100p sidebar-flyout-trigger"
110
125
  >
@@ -122,15 +137,15 @@ function onParentClick() {
122
137
  </Btn>
123
138
  </template>
124
139
  <!-- flyout content -->
125
- <div class="sidebar-flyout p-05">
126
- <p class="sidebar-flyout-label">{{ resolveI18n(link.label) }}</p>
140
+ <div class="sidebar-flyout p-05 min-w-180px display-flex gap-025 column">
141
+ <p class="sidebar-flyout-label m-0 semi opacity-5 uppercase">{{ resolveI18n(link.label) }}</p>
127
142
  <Btn
128
143
  v-for="child in link.children" :key="child.to || child.label"
129
- fullWidth alignTxt="start" thin class="flex-shrink-0 px-075 sidebar-flyout-item"
130
- :class="{ 'nav-btn-active': linkActive(child) }"
144
+ fullWidth alignTxt="start" thin flat class="flex-shrink-0 px-075 radius-1 sidebar-child"
145
+ :class="{ 'bold sidebar-child-active': linkActive(child) }"
131
146
  :style="{
132
- backgroundColor: linkActive(child) ? activeColor : 'transparent',
133
- color: linkActive(child) ? 'white' : 'var(--bgl-text-color)',
147
+ color: linkActive(child) ? activeColor : 'var(--bgl-text-color)',
148
+ '--sidebar-active-color': activeColor,
134
149
  }"
135
150
  :to="child.to || '/'" @click="child.action"
136
151
  >
@@ -148,39 +163,65 @@ function onParentClick() {
148
163
  opacity: 0.6;
149
164
  }
150
165
  .sidebar-chevron-open {
151
- transform: rotate(180deg);
166
+ transform: rotate(180deg)!important;
152
167
  }
153
168
  .sidebar-children {
154
169
  display: grid;
155
170
  grid-template-rows: 0fr;
156
- transition: grid-template-rows 0.25s ease;
171
+ transition: grid-template-rows 0.3s cubic-bezier(0.4, 0, 0.2, 1);
157
172
  overflow: hidden;
158
173
  }
159
174
  .sidebar-children-open {
160
175
  grid-template-rows: 1fr;
161
176
  }
162
- .sidebar-children > * {
177
+ .sidebar-children-inner {
163
178
  min-height: 0;
164
- }
165
- .sidebar-child {
166
- font-size: 0.85rem;
167
- }
168
- .sidebar-flyout {
169
- min-width: 180px;
170
179
  display: flex;
171
180
  flex-direction: column;
172
- gap: 2px;
181
+ gap: 0.125rem;
173
182
  }
183
+ .sidebar-children-open .sidebar-children-inner {
184
+ padding-block: 0.25rem;
185
+ }
186
+ /* Parent toggle — flat <Btn> with no color prop picks up a default `pair-black`
187
+ background; neutralize it so the active parent shows only colored text/icon. */
188
+ .sidebar-parent.bgl_btn {
189
+ background-color: transparent !important;
190
+ transition: background-color 0.15s ease, color 0.15s ease;
191
+ }
192
+ .sidebar-parent.bgl_btn:hover {
193
+ background-color: color-mix(in srgb, currentColor 8%, transparent) !important;
194
+ filter: none;
195
+ }
196
+
174
197
  .sidebar-flyout-label {
175
- margin: 0;
176
198
  padding: 0.25rem 0.5rem 0.375rem;
177
199
  font-size: 0.6875rem;
178
- font-weight: 600;
179
- text-transform: uppercase;
180
- letter-spacing: 0.05em;
181
- opacity: 0.45;
182
200
  }
183
- .sidebar-flyout-item {
184
- border-radius: var(--bgl-btn-border-radius);
201
+ </style>
202
+
203
+ <!-- Global (un-scoped) so the same child styling also applies inside the flyout,
204
+ which is teleported to <body> and therefore outside this component's scope. -->
205
+ <style>
206
+ .sidebar-child {
207
+ font-size: 0.85rem;
208
+ position: relative;
209
+ transition: background-color 0.15s ease, color 0.15s ease, font-weight 0.15s ease;
210
+ }
211
+ /* Neutralize the default `pair-black` background a flat <Btn> picks up when no
212
+ color prop is set, so we can control the child background ourselves. */
213
+ .sidebar-child.bgl_btn {
214
+ background-color: transparent !important;
215
+ }
216
+ /* Active child — filled with a subtle tint of the active color. */
217
+ .sidebar-child.bgl_btn.sidebar-child-active,
218
+ .sidebar-child.bgl_btn.sidebar-child-active:hover {
219
+ background-color: color-mix(in srgb, var(--sidebar-active-color) 14%, transparent) !important;
220
+ }
221
+
222
+ /* Hover indication for children (mirrors the parent feel) */
223
+ .sidebar-child.bgl_btn:hover {
224
+ background-color: color-mix(in srgb, currentColor 12%, transparent) !important;
225
+ filter: none;
185
226
  }
186
227
  </style>
@@ -80,6 +80,10 @@
80
80
  --bgl-skeleton-bg: var(--bgl-dm-surface-2);
81
81
  --bgl-skeleton-pulse: var(--bgl-dm-surface);
82
82
  --bgl-gray-light: var(--bgl-dm-surface-2);
83
+ /* --bgl-gray (#b7b7b7 in light) is used directly by color-gray / bg-gray and
84
+ as a neutral mid tone. On dark, keep it a readable mid-gray so color-gray
85
+ text stays legible; bg-gray fills get a dedicated darker treatment below. */
86
+ --bgl-gray: #8b8f96;
83
87
 
84
88
  /* ---- Text ------------------------------------------------------------- */
85
89
  --bgl-text-color: var(--bgl-dm-text);
@@ -269,6 +273,15 @@
269
273
  color: var(--bgl-dm-text);
270
274
  }
271
275
 
276
+ /* bg-gray is a solid light-gray (#b7b7b7) fill in light mode — used as a
277
+ neutral surface. On dark it becomes a bright patch, so remap it to a raised
278
+ dark surface (one step up from the card) like the other neutral fills. */
279
+ .bgl-dark-mode .bg-gray:not(.keep-white) {
280
+ background: var(--bgl-dm-surface-2) !important;
281
+ --alpha-color: var(--bgl-dm-surface-2);
282
+ color: var(--bgl-dm-text);
283
+ }
284
+
272
285
  .bgl-dark-mode .bg-input-white:not(.keep-white) input,
273
286
  .bgl-dark-mode .bg-input-white:not(.keep-white) textarea,
274
287
  .bgl-dark-mode .bg-input-white:not(.keep-white) .selectinput-btn,
@@ -217,21 +217,38 @@
217
217
  font-size: 0.25rem;
218
218
  }
219
219
 
220
+ .txt0375rem,
221
+ .txt-0375rem {
222
+ font-size: 0.375rem;
223
+ }
224
+
220
225
  .txt05rem,
221
226
  .txt-05rem {
222
227
  font-size: 0.5rem;
223
228
  }
224
229
 
230
+ .txt0625rem,
231
+ .txt-0625rem {
232
+ font-size: 0.625rem;
233
+ }
234
+
225
235
  .txt075rem,
226
236
  .txt-075rem {
227
237
  font-size: 0.75rem;
228
238
  }
229
239
 
240
+ .txt0875rem,
241
+ .txt-0875rem {
242
+ font-size: 0.875rem;
243
+ }
244
+
230
245
  .txt1rem,
231
246
  .txt-1rem {
232
247
  font-size: 1rem;
233
248
  }
234
249
 
250
+
251
+
235
252
  .txt1-25rem,
236
253
  .txt-1-25rem {
237
254
  font-size: 1.25rem;
@@ -1788,21 +1805,36 @@
1788
1805
  font-size: 9px;
1789
1806
  }
1790
1807
 
1791
- .m_txt025,
1792
- .m_txt-025 {
1808
+ .m_txt025rem,
1809
+ .m_txt-025rem {
1793
1810
  font-size: 0.25rem;
1794
1811
  }
1795
1812
 
1796
- .m_txt05,
1797
- .m_txt-05 {
1813
+ .m_txt0375rem,
1814
+ .m_txt-0375rem {
1815
+ font-size: 0.375rem;
1816
+ }
1817
+
1818
+ .m_txt05rem,
1819
+ .m_txt-05rem {
1798
1820
  font-size: 0.5rem;
1799
1821
  }
1800
1822
 
1801
- .m_txt075,
1802
- .m_txt-075 {
1823
+ .m_txt0625rem,
1824
+ .m_txt-0625rem {
1825
+ font-size: 0.625rem;
1826
+ }
1827
+
1828
+ .m_txt075rem,
1829
+ .m_txt-075rem {
1803
1830
  font-size: 0.75rem;
1804
1831
  }
1805
1832
 
1833
+ .m_txt0875rem,
1834
+ .m_txt-0875rem {
1835
+ font-size: 0.875rem;
1836
+ }
1837
+
1806
1838
  .m_txt1rem,
1807
1839
  .m_txt-1rem {
1808
1840
  font-size: 1rem;