@brickclay-org/ui 0.1.67 → 0.1.68

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/index.d.ts CHANGED
@@ -1104,6 +1104,21 @@ declare class BkInputChips implements ControlValueAccessor, AfterViewInit {
1104
1104
  }
1105
1105
 
1106
1106
  type TabIconDirection = 'left' | 'right';
1107
+ type TabsOrientation = 'horizontal' | 'vertical';
1108
+ type TabsVariant = 'default' | 'segmented';
1109
+ /**
1110
+ * Per-usage CSS classes for the 'segmented' variant.
1111
+ * Pass Tailwind classes (not raw colors). Because the component uses
1112
+ * emulated encapsulation, its default color rules out-specify plain
1113
+ * utilities — so use the important prefix, e.g. '!bg-white', '!text-black'.
1114
+ * Any field left undefined keeps the default design token from tabs.css.
1115
+ */
1116
+ interface TabsColors {
1117
+ wrapper?: string;
1118
+ active?: string;
1119
+ activeText?: string;
1120
+ inactive?: string;
1121
+ }
1107
1122
  interface TabItem {
1108
1123
  id: string;
1109
1124
  label: string;
@@ -1120,12 +1135,19 @@ declare class BkTabs {
1120
1135
  list: TabItem[];
1121
1136
  activeTabId: string;
1122
1137
  disabled: boolean;
1138
+ orientation: TabsOrientation;
1139
+ variant: TabsVariant;
1140
+ colors: TabsColors;
1141
+ get isVertical(): boolean;
1142
+ get isSegmented(): boolean;
1143
+ get wrapperClass(): string;
1144
+ segmentedTabClass(tab: TabItem): string;
1123
1145
  change: EventEmitter<TabItem>;
1124
1146
  setActiveTab(tab: TabItem): void;
1125
1147
  isActive(tabId: string): boolean;
1126
1148
  getTabIcon(tab: TabItem): string | undefined;
1127
1149
  static ɵfac: i0.ɵɵFactoryDeclaration<BkTabs, never>;
1128
- static ɵcmp: i0.ɵɵComponentDeclaration<BkTabs, "bk-tabs", never, { "list": { "alias": "list"; "required": false; }; "activeTabId": { "alias": "activeTabId"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; }, { "change": "change"; }, never, never, true, never>;
1150
+ static ɵcmp: i0.ɵɵComponentDeclaration<BkTabs, "bk-tabs", never, { "list": { "alias": "list"; "required": false; }; "activeTabId": { "alias": "activeTabId"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "orientation": { "alias": "orientation"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "colors": { "alias": "colors"; "required": false; }; }, { "change": "change"; }, never, never, true, never>;
1129
1151
  }
1130
1152
 
1131
1153
  /**
@@ -2290,5 +2312,76 @@ declare class BkLoader {
2290
2312
  static ɵcmp: i0.ɵɵComponentDeclaration<BkLoader, "bk-loader", never, { "loading": { "alias": "loading"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; }, {}, never, never, true, never>;
2291
2313
  }
2292
2314
 
2293
- export { BKTooltipDirective, BK_DEFAULT_DIALOG_CONFIG, BK_DIALOG_DATA, BK_DIALOG_GLOBAL_CONFIG, BkAvatar, BkAvatarUploader, BkBadge, BkButton, BkButtonGroup, BkCalendarManagerService, BkCheckbox, BkColumnFilterService, BkColumnSelect, BkCustomCalendar, BkDialogActions, BkDialogClose, BkDialogContent, BkDialogModule, BkDialogRef, BkDialogService, BkDialogTitle, BkFileCard, BkFilePicker, BkGrid, BkHierarchicalSelect, BkIconButton, BkInput, BkInputChips, BkLoader, BkPagination, BkPill, BkRadioButton, BkScheduledDatePicker, BkSelect, BkSpinner, BkTabs, BkTextarea, BkTimePicker, BkToastr, BkToastrService, BkToggle, BkValidator, BrickclayIcons, BrickclayLib, CalendarModule, CalendarSelection, ColumnFilterOption, getDialogBackdropAnimation, getDialogPanelAnimation };
2294
- export type { AvatarFallback, AvatarSize, AvatarVariant, BadgeColor, BadgeSize, BadgeVariant, BkAnimationKeyframes, BkAvatarFallback, BkAvatarSize, BkDialogAnimation, BkDialogConfig, BkDialogPosition, BkInputAutoCapitalize, BkInputAutoComplete, BkInputMode, BkInputType, BkLoaderVariant, BkPageSize, BkTextAreaAutoCapitalize, BkTextAreaAutoComplete, BkTextAreaInputMode, ButtonSize, ButtonVariant, CalendarRange, CountryOption, CustomRangesConfig, DotPosition, DotStatus, FileState, GroupItem, GroupMode, HierarchicalNode, IconButtonSize, IconButtonVariant, IconOrientation, PillColor, PillSize, PillVariant, ScheduledDateSelection, SortDirection, SpinnerSize, TabIconDirection, TabItem, TableAction, TableBadge, TableColumn, TableIcon, TimeConfiguration, ToastConfig, ToastMessage, ToastMethodOptions, ToastPosition, ToastSeverity };
2315
+ type DropdownVariant = 'black' | 'white';
2316
+ type DropdownSize = 'sm' | 'md' | 'lg';
2317
+ type DropdownTrigger = 'click' | 'hover';
2318
+ type DropdownPlacement = 'bottomLeft' | 'bottom' | 'bottomRight' | 'topLeft' | 'top' | 'topRight';
2319
+ interface DropdownItem {
2320
+ id?: string | number;
2321
+ label?: string;
2322
+ icon?: string;
2323
+ disabled?: boolean;
2324
+ divider?: boolean;
2325
+ children?: DropdownItem[];
2326
+ }
2327
+ declare class BkDropdown {
2328
+ private readonly host;
2329
+ /** Text shown on the trigger button. */
2330
+ label: string;
2331
+ /** Menu items (supports divider / disabled / children). */
2332
+ items: DropdownItem[];
2333
+ /** Black (dark) or white (light, bordered) — mirrors the segment-tab look. */
2334
+ variant: DropdownVariant;
2335
+ /** Trigger size. */
2336
+ size: DropdownSize;
2337
+ /** Open on click or on hover. */
2338
+ trigger: DropdownTrigger;
2339
+ /** One of 6 placements for the menu. */
2340
+ placement: DropdownPlacement;
2341
+ /** Show the caret (▾) on the trigger. Rotates when open. */
2342
+ arrow: boolean;
2343
+ /** Split button: a primary action + a separate caret that opens the menu. */
2344
+ splitButton: boolean;
2345
+ /** Currently selected item id — the matching item shows a tick. */
2346
+ selectedId?: string | number;
2347
+ /** Disable the whole control. */
2348
+ disabled: boolean;
2349
+ /** Optional leading icon on the trigger. */
2350
+ iconSrc?: string;
2351
+ /** Extra classes appended to the trigger button. */
2352
+ customClass: string;
2353
+ /** Emits when a (non-disabled) leaf item is chosen. */
2354
+ select: EventEmitter<DropdownItem>;
2355
+ /** Emits the open/closed state whenever it changes. */
2356
+ openChange: EventEmitter<boolean>;
2357
+ /** Split button primary-action click. */
2358
+ buttonClick: EventEmitter<Event>;
2359
+ open: boolean;
2360
+ private closeTimer;
2361
+ constructor(host: ElementRef<HTMLElement>);
2362
+ toggle(): void;
2363
+ onPrimaryClick(event: Event): void;
2364
+ selectItem(item: DropdownItem, event: Event): void;
2365
+ isSelected(item: DropdownItem): boolean;
2366
+ get hasSubmenus(): boolean;
2367
+ private setOpen;
2368
+ onHoverEnter(): void;
2369
+ onHoverLeave(): void;
2370
+ /**
2371
+ * When a parent item is hovered, decide whether its submenu should open to
2372
+ * the right (default) or flip to the left if it would overflow the viewport.
2373
+ */
2374
+ onSubmenuEnter(event: MouseEvent): void;
2375
+ private clearCloseTimer;
2376
+ onDocumentClick(event: MouseEvent): void;
2377
+ onEscape(): void;
2378
+ get triggerClasses(): string;
2379
+ get caretSizeClass(): string;
2380
+ /** Position classes for the menu panel per placement. */
2381
+ get menuPositionClass(): string;
2382
+ static ɵfac: i0.ɵɵFactoryDeclaration<BkDropdown, never>;
2383
+ static ɵcmp: i0.ɵɵComponentDeclaration<BkDropdown, "bk-dropdown", never, { "label": { "alias": "label"; "required": false; }; "items": { "alias": "items"; "required": false; }; "variant": { "alias": "variant"; "required": false; }; "size": { "alias": "size"; "required": false; }; "trigger": { "alias": "trigger"; "required": false; }; "placement": { "alias": "placement"; "required": false; }; "arrow": { "alias": "arrow"; "required": false; }; "splitButton": { "alias": "splitButton"; "required": false; }; "selectedId": { "alias": "selectedId"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "iconSrc": { "alias": "iconSrc"; "required": false; }; "customClass": { "alias": "customClass"; "required": false; }; }, { "select": "select"; "openChange": "openChange"; "buttonClick": "buttonClick"; }, never, never, true, never>;
2384
+ }
2385
+
2386
+ export { BKTooltipDirective, BK_DEFAULT_DIALOG_CONFIG, BK_DIALOG_DATA, BK_DIALOG_GLOBAL_CONFIG, BkAvatar, BkAvatarUploader, BkBadge, BkButton, BkButtonGroup, BkCalendarManagerService, BkCheckbox, BkColumnFilterService, BkColumnSelect, BkCustomCalendar, BkDialogActions, BkDialogClose, BkDialogContent, BkDialogModule, BkDialogRef, BkDialogService, BkDialogTitle, BkDropdown, BkFileCard, BkFilePicker, BkGrid, BkHierarchicalSelect, BkIconButton, BkInput, BkInputChips, BkLoader, BkPagination, BkPill, BkRadioButton, BkScheduledDatePicker, BkSelect, BkSpinner, BkTabs, BkTextarea, BkTimePicker, BkToastr, BkToastrService, BkToggle, BkValidator, BrickclayIcons, BrickclayLib, CalendarModule, CalendarSelection, ColumnFilterOption, getDialogBackdropAnimation, getDialogPanelAnimation };
2387
+ export type { AvatarFallback, AvatarSize, AvatarVariant, BadgeColor, BadgeSize, BadgeVariant, BkAnimationKeyframes, BkAvatarFallback, BkAvatarSize, BkDialogAnimation, BkDialogConfig, BkDialogPosition, BkInputAutoCapitalize, BkInputAutoComplete, BkInputMode, BkInputType, BkLoaderVariant, BkPageSize, BkTextAreaAutoCapitalize, BkTextAreaAutoComplete, BkTextAreaInputMode, ButtonSize, ButtonVariant, CalendarRange, CountryOption, CustomRangesConfig, DotPosition, DotStatus, DropdownItem, DropdownPlacement, DropdownSize, DropdownTrigger, DropdownVariant, FileState, GroupItem, GroupMode, HierarchicalNode, IconButtonSize, IconButtonVariant, IconOrientation, PillColor, PillSize, PillVariant, ScheduledDateSelection, SortDirection, SpinnerSize, TabIconDirection, TabItem, TableAction, TableBadge, TableColumn, TableIcon, TabsColors, TabsOrientation, TabsVariant, TimeConfiguration, ToastConfig, ToastMessage, ToastMethodOptions, ToastPosition, ToastSeverity };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brickclay-org/ui",
3
- "version": "0.1.67",
3
+ "version": "0.1.68",
4
4
  "schematics": "./schematics/collection.json",
5
5
  "ng-add": {
6
6
  "save": "dependencies"
@@ -3,14 +3,23 @@
3
3
  @apply w-full;
4
4
  }
5
5
 
6
- /* Tabs List */
6
+ /* Tabs List
7
+ Grid layout: columns flow horizontally and size to content
8
+ (auto-cols-max), matching the old flex row while giving grid control. */
7
9
  .tabs-list {
8
- @apply flex gap-0 list-none m-0 px-0 py-0.5;
10
+ @apply grid grid-flow-col auto-cols-max gap-0 list-none m-0 px-0 py-0.5;
9
11
  }
10
12
 
11
13
  /* Tab Item */
12
14
  .tabs-item {
13
- @apply flex-shrink-0;
15
+ @apply min-w-0;
16
+ }
17
+
18
+ /* Vertical (default variant): single-column grid = stacked full-width tabs.
19
+ Defined after the base .tabs-list so grid-flow-row reliably overrides the
20
+ base grid-flow-col (otherwise items flow into columns = horizontal). */
21
+ .tabs-list--vertical {
22
+ @apply grid-cols-1 grid-flow-row auto-rows-max;
14
23
  }
15
24
 
16
25
  /* Tab Button - Base Styles */
@@ -62,3 +71,54 @@
62
71
  @apply whitespace-nowrap;
63
72
  }
64
73
 
74
+
75
+ /* =========================================================
76
+ Segmented variant (pill-in-a-track)
77
+ Colors are driven by CSS vars set per-usage via [colors],
78
+ falling back to the default design tokens.
79
+ ========================================================= */
80
+
81
+ /* Track / wrapper — default background; override via colors.wrapper (use ! classes). */
82
+ .tabs-container--segmented {
83
+ @apply p-[3px] rounded-md w-full md:w-auto;
84
+ background: #54578E12;
85
+ }
86
+
87
+ /* Pill row — equal-width columns (auto-cols-fr) replace the old flex-1. */
88
+ .tabs-list--segmented {
89
+ @apply grid grid-flow-col auto-cols-fr items-center gap-2 rounded-md font-medium text-sm leading-4 w-full sm:w-auto py-0;
90
+ color: #6B7080;
91
+ }
92
+
93
+ /* Pill button — min-width keeps short labels even, but lets icon/long
94
+ labels grow instead of clipping the icon. Default inactive text; override
95
+ via colors.inactive (use ! classes). */
96
+ .tabs-button--segmented {
97
+ @apply border border-transparent px-3 sm:min-w-[5rem] py-1.5 w-full text-center justify-center rounded;
98
+ color: #6B7080;
99
+ }
100
+
101
+ /* Pill hover (not on active / disabled) */
102
+ .tabs-button--segmented:hover:not(:disabled):not(.tabs-button--active) {
103
+ border-color: #42578A26;
104
+ background: #FFFFFF;
105
+ color: #15191E;
106
+ }
107
+
108
+ /* Pill active — default colors; override via colors.active / colors.activeText
109
+ (use ! classes, which out-specify this scoped rule). */
110
+ .tabs-button--segmented.tabs-button--active {
111
+ background: #FFFFFF;
112
+ color: #15191E;
113
+ }
114
+
115
+ /* Segmented + vertical: single-column grid = stacked full-width pills.
116
+ Placed after the base segmented rules so it wins on equal specificity. */
117
+ .tabs-list--segmented-vertical {
118
+ @apply grid-cols-1 grid-flow-row auto-rows-max gap-1;
119
+ }
120
+
121
+ /* Left-align pill content in the vertical segmented layout */
122
+ .tabs-list--segmented-vertical .tabs-button--segmented {
123
+ @apply justify-start text-left;
124
+ }
package/src/styles.css CHANGED
@@ -25,3 +25,4 @@
25
25
  @import './lib/file-card/file-card.css';
26
26
  @import './lib/pagination/pagination.css';
27
27
  @import './lib/loader/loader.css';
28
+ @import './lib/dropdown/dropdown.css';