@brickclay-org/ui 0.1.73 → 0.1.75

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@brickclay-org/ui",
3
- "version": "0.1.73",
3
+ "version": "0.1.75",
4
4
  "schematics": "./schematics/collection.json",
5
5
  "ng-add": {
6
6
  "save": "dependencies"
@@ -16,7 +16,12 @@
16
16
  }
17
17
 
18
18
  .hierarchical-select-control.disabled {
19
- @apply bg-[#F4F4F6] cursor-not-allowed opacity-60;
19
+ @apply cursor-not-allowed opacity-60;
20
+ /* !important beats the inline accent (showDots): a disabled control must read
21
+ as disabled even when a node's colour is applied. */
22
+ background-color: #f4f4f6 !important;
23
+ border-color: rgb(227 227 231) !important;
24
+ color: rgb(161 163 174) !important;
20
25
 
21
26
  .hierarchical-placeholder {
22
27
  @apply text-gray-400;
@@ -31,10 +36,26 @@
31
36
  @apply text-[#6B7080] font-normal text-sm truncate w-full pointer-events-none;
32
37
  }
33
38
 
39
+ /* Keeps the dot/avatar on the same line as the w-full label, which would
40
+ otherwise wrap inside the flex-wrap value container. */
41
+ .hierarchical-value-row {
42
+ @apply flex items-center gap-1.5 w-full min-w-0;
43
+ }
44
+
34
45
  .hierarchical-value-label {
35
46
  @apply font-normal text-sm leading-[18px] text-[#141414] truncate w-full flex items-center;
36
47
  }
37
48
 
49
+ /* Accent dot (showDots). Background is set inline per node. */
50
+ .hierarchical-dot {
51
+ @apply inline-block w-2 h-2 rounded-full shrink-0;
52
+ }
53
+
54
+ /* Leading side of an option row: dot / avatar / label. */
55
+ .hierarchical-option-body {
56
+ @apply flex items-center gap-2 min-w-0 flex-1;
57
+ }
58
+
38
59
  .hierarchical-actions {
39
60
  @apply flex items-center gap-2 flex-shrink-0;
40
61
  }
@@ -82,10 +103,6 @@
82
103
  @apply w-full outline-none font-normal text-sm text-[#141414] placeholder-[#A1A3AE] bg-transparent;
83
104
  }
84
105
 
85
- .hierarchical-search-input:-moz-focusring {
86
- outline: none;
87
- }
88
-
89
106
  .hierarchical-back {
90
107
  @apply w-full text-left px-2.5 py-2 text-sm text-[#141414] bg-[#F8F8F8] rounded-md transition-colors mt-1 flex items-center gap-1.5;
91
108
  }
@@ -124,9 +141,11 @@
124
141
  }
125
142
  }
126
143
 
127
- .hierarchical-option:hover,
144
+ .hierarchical-option:hover{
145
+ @apply bg-[#f9f9f9];
146
+ }
128
147
  .hierarchical-option.selected {
129
- @apply bg-[#F8F8F8];
148
+ @apply bg-[#f7f7f7];
130
149
  }
131
150
 
132
151
  .hierarchical-option.selected.disabled-item {
@@ -191,6 +210,8 @@
191
210
  }
192
211
 
193
212
 
213
+ /* !important beats the inline accent border (showDots): an errored control must
214
+ read as errored even when a node's colour is tinting it. */
194
215
  .hierarchical-select-control.hierarchical-select-control-has-error {
195
- @apply border-[#d11e14];
216
+ border-color: #d11e14 !important;
196
217
  }
@@ -2,6 +2,7 @@
2
2
  bk-menu — simple responsive navigation menu.
3
3
  Single light theme, matching the default bk-tabs styling:
4
4
  text #141414, hover #EDEEF0, active #141414 bg with white text.
5
+ Styling uses Tailwind @apply; CSS variables below drive the theme.
5
6
  ========================================================================= */
6
7
 
7
8
  .bk-menu {
@@ -17,156 +18,133 @@
17
18
  --menu-radius: 8px;
18
19
  --menu-disabled: 0.5;
19
20
 
20
- display: block;
21
- width: 100%;
22
- max-width: 100%;
23
- font-size: 0.875rem;
24
- line-height: 1.25rem;
25
- font-weight: 500;
26
- letter-spacing: -0.28px;
27
- background: var(--menu-bg);
28
- color: var(--menu-text);
29
- border: 1px solid var(--menu-border);
30
- border-radius: var(--menu-radius);
31
21
  /* Safe to clip to rounded corners: pop-up fly-outs are position:fixed and
32
22
  escape this box entirely, so nothing gets cut off. */
33
- overflow: hidden;
23
+ @apply block w-full max-w-full text-sm font-medium tracking-[-0.28px]
24
+ bg-[var(--menu-bg)] text-[color:var(--menu-text)]
25
+ border border-[var(--menu-border)] rounded-[var(--menu-radius)] overflow-hidden;
34
26
  }
35
27
 
36
28
  /* ---- Lists ---- */
37
29
  .bk-menu__list,
38
30
  .bk-menu__submenu {
39
- list-style: none;
40
- margin: 0;
41
- padding: 0;
31
+ @apply list-none m-0 p-0;
42
32
  }
43
33
 
44
34
  /* Scroll container: vertical scroll past max-height, horizontal scroll if a
45
35
  deeply-indented inline row is wider than the menu. Fixed fly-outs escape it. */
46
36
  .bk-menu__list--scroll {
47
- overflow: auto;
37
+ @apply overflow-auto;
48
38
  }
49
39
 
50
40
  /* Horizontal top-level row (menubar). Scrolls when crowded — fixed fly-outs are
51
41
  unaffected by the overflow. */
52
42
  .bk-menu--horizontal > .bk-menu__list {
53
- display: flex;
54
- flex-direction: row;
55
- align-items: stretch;
56
- overflow-x: auto;
43
+ @apply flex flex-row items-stretch overflow-x-auto;
57
44
  }
58
45
 
59
46
  /* ---- Item / button ---- */
60
47
  .bk-menu__item {
61
- position: relative; /* anchor for pop-up submenus */
48
+ @apply relative; /* anchor for pop-up submenus */
62
49
  }
63
50
 
64
51
  .bk-menu__button {
65
- display: flex;
66
- align-items: center;
67
- gap: 8px;
68
- width: 100%;
69
- padding: 10px 12px;
70
- margin: 0;
71
- border: 0;
72
- background: transparent;
73
- color: inherit;
52
+ @apply flex items-center gap-2 w-full py-2.5 px-3 m-0 border-0
53
+ bg-transparent text-inherit text-left cursor-pointer whitespace-nowrap
54
+ transition-colors duration-100;
74
55
  font: inherit;
75
56
  letter-spacing: inherit;
76
- text-align: left;
77
- cursor: pointer;
78
- white-space: nowrap;
79
- border-radius: 6px;
80
- transition: background 0.1s ease, color 0.1s ease;
81
57
  }
82
58
 
83
59
  .bk-menu--horizontal > .bk-menu__list > .bk-menu__item > .bk-menu__button {
84
- width: auto;
60
+ @apply w-auto;
61
+ }
62
+
63
+ /* ---- Edge rounding: make the first/last top-level items' outer corners match
64
+ the container so hover/active fills sit flush in the rounded corners.
65
+ Vertical = column → first rounds the top, last rounds the bottom.
66
+ Horizontal = row → first rounds the left, last rounds the right. ---- */
67
+ .bk-menu--vertical > .bk-menu__list > .bk-menu__item:first-child > .bk-menu__button {
68
+ @apply rounded-t-[var(--menu-radius)];
69
+ }
70
+ .bk-menu--vertical > .bk-menu__list > .bk-menu__item:last-child > .bk-menu__button {
71
+ @apply rounded-b-[var(--menu-radius)];
72
+ }
73
+ .bk-menu--horizontal > .bk-menu__list > .bk-menu__item:first-child > .bk-menu__button {
74
+ @apply rounded-l-[var(--menu-radius)];
75
+ }
76
+ .bk-menu--horizontal > .bk-menu__list > .bk-menu__item:last-child > .bk-menu__button {
77
+ @apply rounded-r-[var(--menu-radius)];
85
78
  }
86
79
 
87
80
  .bk-menu__button:hover:not(:disabled):not(.bk-menu__button--active) {
88
- background: var(--menu-hover-bg);
89
- color: var(--menu-hover-text);
81
+ @apply bg-[var(--menu-hover-bg)] text-[color:var(--menu-hover-text)];
90
82
  }
91
83
 
92
84
  .bk-menu__button--active {
93
- background: var(--menu-active-bg);
94
- color: var(--menu-active-text);
85
+ @apply bg-[var(--menu-active-bg)] text-[color:var(--menu-active-text)];
95
86
  }
96
87
 
97
88
  .bk-menu__button--disabled,
98
89
  .bk-menu__button:disabled {
99
- opacity: var(--menu-disabled);
100
- cursor: not-allowed;
90
+ @apply opacity-[var(--menu-disabled)] cursor-not-allowed;
101
91
  }
102
92
 
103
93
  /* Nested (child) items use the muted sub-text colour. */
104
94
  .bk-menu__submenu .bk-menu__button {
105
- color: var(--menu-subtext);
106
- font-weight: 400;
95
+ @apply text-[color:var(--menu-subtext)] font-normal;
107
96
  }
108
97
 
109
98
  .bk-menu__submenu .bk-menu__button--active {
110
- color: var(--menu-active-text);
99
+ @apply text-[color:var(--menu-active-text)];
111
100
  }
112
101
 
113
102
  /* ---- Icon (optional). Tinted monochrome when .bk-menu--tint. ---- */
114
103
  .bk-menu__icon {
115
- width: 16px;
116
- height: 16px;
117
- flex-shrink: 0;
118
- object-fit: contain;
104
+ @apply w-4 h-4 shrink-0 object-contain;
119
105
  }
120
106
 
121
107
  .bk-menu--tint .bk-menu__icon {
122
- filter: brightness(0) saturate(0); /* → near-black, matches #141414 text */
108
+ @apply [filter:brightness(0)_saturate(0)]; /* → near-black, matches #141414 text */
123
109
  }
124
110
 
125
111
  /* Active row has a dark background → force a white icon for contrast. */
126
112
  .bk-menu--tint .bk-menu__button--active .bk-menu__icon {
127
- filter: brightness(0) invert(1);
113
+ @apply [filter:brightness(0)_invert(1)];
128
114
  }
129
115
 
130
116
  .bk-menu__label {
131
- flex: 1 1 auto;
132
- min-width: 0;
133
- overflow: hidden;
134
- text-overflow: ellipsis;
117
+ @apply flex-auto min-w-0 overflow-hidden text-ellipsis;
135
118
  }
136
119
 
137
120
  .bk-menu--horizontal > .bk-menu__list > .bk-menu__item > .bk-menu__button > .bk-menu__label {
138
- flex: 0 0 auto;
139
- overflow: visible;
121
+ @apply flex-none overflow-visible;
140
122
  }
141
123
 
142
124
  /* ---- Chevron ---- */
143
125
  .bk-menu__chevron {
144
- flex-shrink: 0;
145
- transition: transform 0.18s ease;
146
- opacity: 0.8;
126
+ @apply shrink-0 opacity-80 transition-transform duration-[180ms];
147
127
  }
148
128
 
149
129
  /* Inline: rotate down → up on open. */
150
130
  .bk-menu__chevron--open {
151
- transform: rotate(180deg);
131
+ @apply rotate-180;
152
132
  }
153
133
 
154
134
  /* Pop-up fly-out: static caret pointing to where the panel opens (right). */
155
135
  .bk-menu__chevron--right {
156
- transform: rotate(-90deg);
136
+ @apply -rotate-90;
157
137
  }
158
138
 
159
139
  /* =========================================================================
160
140
  Inline submenus (accordion) — expand in place.
161
141
  ========================================================================= */
162
142
  .bk-menu__submenu--inline {
163
- overflow: hidden;
164
- max-height: 0;
165
- transition: max-height 0.2s ease;
143
+ @apply overflow-hidden max-h-0 transition-[max-height] duration-200;
166
144
  }
167
145
 
168
146
  .bk-menu__submenu--inline.bk-menu__submenu--open {
169
- max-height: 1000px; /* large enough to reveal nested content */
147
+ @apply max-h-[1000px]; /* large enough to reveal nested content */
170
148
  }
171
149
 
172
150
  /* =========================================================================
@@ -175,52 +153,34 @@
175
153
  .bk-menu__submenu--popup {
176
154
  /* Fixed so the fly-out escapes the menu's overflow/scroll box and renders
177
155
  outside the nav. Coordinates are set inline (top/left) from JS. */
178
- position: fixed;
179
- z-index: 1000;
180
- min-width: 200px;
181
- max-width: 280px;
182
- max-height: calc(100vh - 16px);
183
- overflow-y: auto;
184
- background: var(--menu-bg);
185
- border: 1px solid var(--menu-border);
186
- border-radius: 12px;
187
- box-shadow: var(--menu-shadow);
188
- padding: 4px;
189
- display: none;
156
+ @apply fixed z-[1000] min-w-[200px] max-w-[280px] max-h-[calc(100vh-16px)]
157
+ overflow-y-auto bg-[var(--menu-bg)] border border-[var(--menu-border)]
158
+ rounded-xl shadow-[var(--menu-shadow)] p-1 hidden;
190
159
  }
191
160
 
192
161
  .bk-menu__submenu--popup.bk-menu__submenu--open {
193
- display: block;
162
+ @apply block;
194
163
  }
195
164
 
196
165
  /* Invisible bridges spanning the gap between a parent and its fly-out, so the
197
166
  pointer stays "inside" the item while crossing — prevents hover flicker. */
198
167
  .bk-menu__submenu--popup-right::before {
199
168
  content: '';
200
- position: absolute;
201
- top: 0;
202
- left: -6px;
203
- width: 6px;
204
- height: 100%;
169
+ @apply absolute top-0 left-[-6px] w-1.5 h-full;
205
170
  }
206
171
  .bk-menu__submenu--popup-down::before {
207
172
  content: '';
208
- position: absolute;
209
- top: -6px;
210
- left: 0;
211
- width: 100%;
212
- height: 6px;
173
+ @apply absolute top-[-6px] left-0 w-full h-1.5;
213
174
  }
214
175
 
215
176
  /* =========================================================================
216
- Responsive: stack a horizontal menu into a vertical one on small screens.
177
+ Responsive: a horizontal menu STAYS horizontal on small screens and scrolls
178
+ sideways when the items don't fit (overflow-x: auto). Items keep their
179
+ natural width so they sit in a clean scrollable row instead of stretching.
217
180
  ========================================================================= */
218
181
  @media (max-width: 640px) {
219
182
  .bk-menu--horizontal > .bk-menu__list {
220
- flex-direction: column;
221
- overflow-x: visible;
222
- }
223
- .bk-menu--horizontal > .bk-menu__list > .bk-menu__item > .bk-menu__button {
224
- width: 100%;
183
+ @apply overflow-x-auto;
184
+ -webkit-overflow-scrolling: touch;
225
185
  }
226
186
  }
@@ -17,14 +17,29 @@
17
17
  }
18
18
 
19
19
  &.bk-focused {
20
- @apply border-[#6B7080] shadow-none z-10;
20
+ @apply shadow-none z-10;
21
21
  outline: none !important;
22
22
  }
23
23
 
24
+ /* Only an untinted control borrows the neutral focus border; a tinted one
25
+ keeps its accent border (set inline) so the colour never flicks to grey. */
26
+ &.bk-focused:not(.bk-filled) {
27
+ @apply border-[#6B7080];
28
+ }
29
+
30
+ /* Tinted by a selected option (showDots, single-select). The accent supplies
31
+ its own border, so the default shadow would only muddy it. */
32
+ &.bk-filled {
33
+ box-shadow: none;
34
+ }
35
+
24
36
  &.bk-disabled {
25
37
  @apply cursor-not-allowed;
26
- border-color: rgb(227 227 231);
27
- background-color: rgb(244 244 246);
38
+ /* !important beats the inline accent: a disabled control must read as
39
+ disabled even when an option's colour is applied. */
40
+ border-color: rgb(227 227 231) !important;
41
+ background-color: rgb(244 244 246) !important;
42
+ color: rgb(161 163 174) !important;
28
43
 
29
44
  .bk-placeholder {
30
45
  color: rgb(161 163 174);
@@ -40,8 +55,11 @@
40
55
  @apply px-3 py-[5px];
41
56
  }
42
57
 
58
+ /* The error background is applied inline (see controlStyle) so it can replace an
59
+ option's accent tint. The border can't be: !important is what makes it beat
60
+ the softer inline border that comes with that tint. */
43
61
  .bk-select-control.bk-has-error {
44
- @apply border-[#d11e14];
62
+ border-color: #d11e14 !important;
45
63
  }
46
64
 
47
65
 
@@ -64,8 +82,11 @@
64
82
  @apply text-[14px] !leading-[18px];
65
83
  }
66
84
 
85
+ /* 18px line box, same as the placeholder and the `default` value — otherwise a
86
+ text-only `sm` row is 16px while a row with an avatar is 18px, and the
87
+ control resizes as soon as something is selected. */
67
88
  .bk-select-container.sm .bk-select-control .bk-value-label-single {
68
- @apply text-xs;
89
+ @apply text-xs !leading-[18px];
69
90
  }
70
91
 
71
92
  /* --- NEW: Multi Select Chips --- */
@@ -101,6 +122,14 @@
101
122
  min-width: 0;
102
123
  }
103
124
 
125
+ /* The 16px avatar is taller than the 12px label, so drop the vertical padding
126
+ and let it set the chip height: 16 + 2px border = 18px, exactly matching a
127
+ text-only chip. Without this the row grows the moment showAvatar is on. */
128
+ .bk-multi-badge-item.bk-chip-has-avatar {
129
+ @apply py-0 ps-0.5;
130
+ max-width: 140px;
131
+ }
132
+
104
133
  .bk-multi-badge-item-text {
105
134
  @apply text-[10px] leading-[12px] font-normal text-[#6B7080];
106
135
  white-space: nowrap;
@@ -289,3 +318,15 @@
289
318
  .bk-chip-icon {
290
319
  @apply w-3 h-3 object-contain rounded-sm;
291
320
  }
321
+
322
+ /* ---- Accent dots (showDots). Background is set inline per option. ---- */
323
+
324
+ /* Options and the single-select value. */
325
+ .bk-value-dot {
326
+ @apply inline-block w-2 h-2 rounded-full shrink-0;
327
+ }
328
+
329
+ /* Multi-select chips — smaller to suit the 18px chip row. */
330
+ .bk-chip-dot {
331
+ @apply inline-block w-1.5 h-1.5 rounded-full shrink-0;
332
+ }
@@ -1,10 +1,13 @@
1
1
  /* =========================
2
2
  Base Avatar
3
3
  ========================= */
4
+ /* No transition here on purpose: bgColor/textColor arrive via [ngStyle] a tick
5
+ after the element first paints, so `transition-all` made every avatar fade
6
+ its colours in on render — very visible in a list of options. Nothing on the
7
+ avatar changes on hover/focus, so the transition bought nothing. */
4
8
  .avatar {
5
9
  @apply relative inline-flex items-center justify-center
6
- rounded-full flex-shrink-0 select-none
7
- transition-all duration-200;
10
+ rounded-full flex-shrink-0 select-none;
8
11
  }
9
12
 
10
13
  .avatar-img {
@@ -18,6 +21,10 @@
18
21
  /* =========================
19
22
  Sizes (container + text)
20
23
  ========================= */
24
+ /* Sized to sit inside an 18px text line box (form controls) without changing
25
+ the row height. 16px rather than 18px so it also fits a bordered chip
26
+ (16 + 2px border = 18px) — the same height as a text-only chip. */
27
+ .avatar.xxsm { @apply size-4 text-[8px] leading-[10px]; }
21
28
  .avatar.xsm { @apply size-6 text-[10px] leading-[14px]; }
22
29
  .avatar.sm { @apply size-8 text-sm; }
23
30
  .avatar.md { @apply size-10 text-base; }
@@ -28,6 +35,7 @@
28
35
  /* =========================
29
36
  Placeholder Icon Sizes
30
37
  ========================= */
38
+ .avatar.xxsm .placeholder-icon { @apply size-3; }
31
39
  .avatar.xsm .placeholder-icon { @apply size-4; }
32
40
  .avatar.sm .placeholder-icon { @apply size-5; }
33
41
  .avatar.md .placeholder-icon { @apply size-6; }
@@ -44,6 +52,7 @@
44
52
  }
45
53
 
46
54
  /* Dot size follows avatar size */
55
+ .avatar.xxsm .avatar-dot { @apply size-1; }
47
56
  .avatar.xsm .avatar-dot { @apply size-1; }
48
57
  .avatar.sm .avatar-dot { @apply size-1.5; }
49
58
  .avatar.md .avatar-dot { @apply size-2.5; }
@@ -69,5 +78,3 @@
69
78
  .avatar .none {
70
79
  @apply hidden;
71
80
  }
72
-
73
-
package/src/styles.css CHANGED
@@ -26,3 +26,6 @@
26
26
  @import './lib/pagination/pagination.css';
27
27
  @import './lib/loader/loader.css';
28
28
  @import './lib/dropdown/dropdown.css';
29
+ @import './lib/popover/popover.css';
30
+ @import './lib/menu/menu.css';
31
+ @import './lib/ui-avatar-group/ui-avatar-group.css';