@egose/shadcn-theme-ng-tw 0.0.28 → 0.2.0
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/README.md +130 -13
- package/accordion/README.md +376 -34
- package/accordion/fesm2022/accordion.mjs +20 -20
- package/alert/README.md +343 -34
- package/alert/fesm2022/alert.mjs +18 -18
- package/alert-dialog/README.md +471 -5
- package/alert-dialog/fesm2022/alert-dialog.mjs +48 -48
- package/alert-dialog/types/alert-dialog.d.ts +1 -1
- package/aspect-ratio/README.md +272 -5
- package/aspect-ratio/fesm2022/aspect-ratio.mjs +9 -9
- package/autocomplete/README.md +473 -34
- package/autocomplete/fesm2022/autocomplete.mjs +54 -54
- package/autocomplete/types/autocomplete.d.ts +1 -1
- package/avatar/README.md +357 -5
- package/avatar/fesm2022/avatar.mjs +32 -32
- package/badge/README.md +289 -34
- package/badge/fesm2022/badge.mjs +4 -4
- package/basic-alert/README.md +324 -34
- package/basic-alert/fesm2022/basic-alert.mjs +4 -4
- package/basic-alert/types/basic-alert.d.ts +1 -1
- package/breadcrumb/README.md +406 -5
- package/breadcrumb/fesm2022/breadcrumb.mjs +34 -34
- package/button/README.md +453 -34
- package/button/fesm2022/button.mjs +96 -118
- package/button/types/button.d.ts +7 -10
- package/button-group/README.md +318 -5
- package/button-group/fesm2022/button-group.mjs +20 -20
- package/calendar/README.md +328 -34
- package/calendar/fesm2022/calendar.mjs +154 -154
- package/card/README.md +331 -5
- package/card/fesm2022/card.mjs +33 -33
- package/carousel/README.md +333 -5
- package/carousel/fesm2022/carousel.mjs +47 -44
- package/carousel/types/carousel.d.ts +1 -1
- package/checkbox/README.md +291 -34
- package/checkbox/fesm2022/checkbox.mjs +22 -20
- package/checkbox/types/checkbox.d.ts +5 -4
- package/collapsible/README.md +332 -5
- package/collapsible/fesm2022/collapsible.mjs +15 -15
- package/combobox/README.md +507 -5
- package/combobox/fesm2022/combobox.mjs +95 -92
- package/combobox/types/combobox.d.ts +1 -1
- package/command/README.md +435 -5
- package/command/fesm2022/command.mjs +56 -56
- package/confirmation-dialog/README.md +272 -34
- package/confirmation-dialog/fesm2022/confirmation-dialog.mjs +13 -12
- package/confirmation-dialog/types/confirmation-dialog.d.ts +9 -5
- package/context-menu/README.md +366 -5
- package/context-menu/fesm2022/context-menu.mjs +9 -9
- package/date-picker/README.md +436 -34
- package/date-picker/fesm2022/date-picker.mjs +79 -68
- package/date-picker/types/date-picker.d.ts +8 -4
- package/dialog/README.md +419 -34
- package/dialog/fesm2022/dialog.mjs +48 -48
- package/drawer/README.md +395 -5
- package/drawer/fesm2022/drawer.mjs +45 -45
- package/dropdown-menu/README.md +417 -5
- package/dropdown-menu/fesm2022/dropdown-menu.mjs +85 -73
- package/dropdown-menu/types/dropdown-menu.d.ts +4 -0
- package/empty/README.md +329 -5
- package/empty/fesm2022/empty.mjs +31 -31
- package/field/README.md +385 -5
- package/field/fesm2022/field.mjs +59 -59
- package/field/types/field.d.ts +1 -1
- package/form-checkbox/README.md +283 -34
- package/form-checkbox/fesm2022/form-checkbox.mjs +37 -19
- package/form-checkbox/types/form-checkbox.d.ts +7 -1
- package/form-date-picker/README.md +293 -34
- package/form-date-picker/fesm2022/form-date-picker.mjs +59 -24
- package/form-date-picker/types/form-date-picker.d.ts +7 -1
- package/form-field/README.md +327 -34
- package/form-field/fesm2022/form-field.mjs +30 -16
- package/form-field/types/form-field.d.ts +28 -20
- package/form-field-simple/README.md +311 -34
- package/form-field-simple/fesm2022/form-field-simple.mjs +4 -4
- package/form-searchable-multiselect/README.md +332 -34
- package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +41 -21
- package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +8 -2
- package/form-select/README.md +321 -34
- package/form-select/fesm2022/form-select.mjs +62 -29
- package/form-select/types/form-select.d.ts +7 -1
- package/form-text-input/README.md +342 -34
- package/form-text-input/fesm2022/form-text-input.mjs +43 -55
- package/form-text-input/types/form-text-input.d.ts +9 -12
- package/form-textarea/README.md +318 -34
- package/form-textarea/fesm2022/form-textarea.mjs +42 -23
- package/form-textarea/types/form-textarea.d.ts +8 -1
- package/hover-card/README.md +256 -5
- package/hover-card/fesm2022/hover-card.mjs +19 -19
- package/icon/README.md +210 -34
- package/icon/fesm2022/icon.mjs +8 -8
- package/input/README.md +240 -34
- package/input/fesm2022/input.mjs +17 -12
- package/input/types/input.d.ts +2 -1
- package/input-group/README.md +335 -5
- package/input-group/fesm2022/input-group.mjs +37 -37
- package/input-group/types/input-group.d.ts +3 -3
- package/input-otp/README.md +375 -5
- package/input-otp/fesm2022/input-otp.mjs +27 -27
- package/item/README.md +385 -5
- package/item/fesm2022/item.mjs +54 -54
- package/kbd/README.md +291 -5
- package/kbd/fesm2022/kbd.mjs +13 -13
- package/label/README.md +243 -34
- package/label/fesm2022/label.mjs +9 -9
- package/label/types/label.d.ts +1 -1
- package/layout-simple/README.md +174 -44
- package/layout-simple/fesm2022/layout-simple.mjs +917 -398
- package/layout-simple/types/layout-simple.d.ts +180 -129
- package/menu/README.md +418 -0
- package/menu/fesm2022/menu.mjs +461 -0
- package/menu/package.json +24 -0
- package/menu/types/menu.d.ts +137 -0
- package/menubar/README.md +343 -5
- package/menubar/fesm2022/menubar.mjs +13 -13
- package/native-select/README.md +323 -5
- package/native-select/fesm2022/native-select.mjs +19 -19
- package/navigation-menu/README.md +369 -5
- package/navigation-menu/fesm2022/navigation-menu.mjs +37 -37
- package/package.json +183 -154
- package/pagination/README.md +388 -5
- package/pagination/fesm2022/pagination.mjs +63 -63
- package/popover/README.md +302 -34
- package/popover/fesm2022/popover.mjs +30 -30
- package/progress/README.md +311 -5
- package/progress/fesm2022/progress.mjs +13 -13
- package/radio-group/README.md +335 -34
- package/radio-group/fesm2022/radio-group.mjs +26 -19
- package/resizable/README.md +269 -5
- package/resizable/fesm2022/resizable.mjs +19 -19
- package/scroll-area/README.md +233 -5
- package/scroll-area/fesm2022/scroll-area.mjs +9 -9
- package/searchable-multiselect/README.md +294 -34
- package/searchable-multiselect/fesm2022/searchable-multiselect.mjs +63 -16
- package/searchable-multiselect/types/searchable-multiselect.d.ts +8 -2
- package/select/README.md +408 -34
- package/select/fesm2022/select.mjs +80 -72
- package/select/types/select.d.ts +3 -1
- package/separator/README.md +193 -34
- package/separator/fesm2022/separator.mjs +9 -9
- package/separator/types/separator.d.ts +1 -1
- package/sheet/README.md +282 -34
- package/sheet/fesm2022/sheet.mjs +30 -30
- package/sidebar/README.md +457 -5
- package/sidebar/fesm2022/sidebar.mjs +136 -134
- package/sidebar/types/sidebar.d.ts +3 -3
- package/skeleton/README.md +217 -5
- package/skeleton/fesm2022/skeleton.mjs +9 -9
- package/slider/README.md +273 -5
- package/slider/fesm2022/slider.mjs +29 -25
- package/sonner/README.md +317 -34
- package/sonner/fesm2022/sonner.mjs +9 -9
- package/spinner/README.md +255 -34
- package/spinner/fesm2022/spinner.mjs +8 -8
- package/switch/README.md +281 -34
- package/switch/fesm2022/switch.mjs +12 -14
- package/table/README.md +423 -5
- package/table/fesm2022/table.mjs +41 -41
- package/tabs/README.md +382 -34
- package/tabs/fesm2022/tabs.mjs +48 -38
- package/textarea/README.md +282 -5
- package/textarea/fesm2022/textarea.mjs +9 -9
- package/toggle/README.md +270 -5
- package/toggle/fesm2022/toggle.mjs +14 -14
- package/toggle-group/README.md +340 -5
- package/toggle-group/fesm2022/toggle-group.mjs +13 -13
- package/toggle-group/types/toggle-group.d.ts +13 -7
- package/tooltip/README.md +240 -34
- package/tooltip/fesm2022/tooltip.mjs +14 -14
- package/typography/README.md +271 -5
- package/typography/fesm2022/typography.mjs +53 -53
- package/typography/types/typography.d.ts +12 -12
- package/utils/README.md +274 -34
- package/utils/fesm2022/utils.mjs +68 -44
- package/accordion/fesm2022/accordion.mjs.map +0 -1
- package/alert/fesm2022/alert.mjs.map +0 -1
- package/alert-dialog/fesm2022/alert-dialog.mjs.map +0 -1
- package/aspect-ratio/fesm2022/aspect-ratio.mjs.map +0 -1
- package/autocomplete/fesm2022/autocomplete.mjs.map +0 -1
- package/avatar/fesm2022/avatar.mjs.map +0 -1
- package/badge/fesm2022/badge.mjs.map +0 -1
- package/basic-alert/fesm2022/basic-alert.mjs.map +0 -1
- package/breadcrumb/fesm2022/breadcrumb.mjs.map +0 -1
- package/button/fesm2022/button.mjs.map +0 -1
- package/button-group/fesm2022/button-group.mjs.map +0 -1
- package/calendar/fesm2022/calendar.mjs.map +0 -1
- package/card/fesm2022/card.mjs.map +0 -1
- package/carousel/fesm2022/carousel.mjs.map +0 -1
- package/checkbox/fesm2022/checkbox.mjs.map +0 -1
- package/collapsible/fesm2022/collapsible.mjs.map +0 -1
- package/combobox/fesm2022/combobox.mjs.map +0 -1
- package/command/fesm2022/command.mjs.map +0 -1
- package/confirmation-dialog/fesm2022/confirmation-dialog.mjs.map +0 -1
- package/context-menu/fesm2022/context-menu.mjs.map +0 -1
- package/date-picker/fesm2022/date-picker.mjs.map +0 -1
- package/dialog/fesm2022/dialog.mjs.map +0 -1
- package/drawer/fesm2022/drawer.mjs.map +0 -1
- package/dropdown-menu/fesm2022/dropdown-menu.mjs.map +0 -1
- package/empty/fesm2022/empty.mjs.map +0 -1
- package/field/fesm2022/field.mjs.map +0 -1
- package/form-checkbox/fesm2022/form-checkbox.mjs.map +0 -1
- package/form-date-picker/fesm2022/form-date-picker.mjs.map +0 -1
- package/form-field/fesm2022/form-field.mjs.map +0 -1
- package/form-field-simple/fesm2022/form-field-simple.mjs.map +0 -1
- package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs.map +0 -1
- package/form-select/fesm2022/form-select.mjs.map +0 -1
- package/form-text-input/fesm2022/form-text-input.mjs.map +0 -1
- package/form-textarea/fesm2022/form-textarea.mjs.map +0 -1
- package/hover-card/fesm2022/hover-card.mjs.map +0 -1
- package/icon/fesm2022/icon.mjs.map +0 -1
- package/input/fesm2022/input.mjs.map +0 -1
- package/input-group/fesm2022/input-group.mjs.map +0 -1
- package/input-otp/fesm2022/input-otp.mjs.map +0 -1
- package/item/fesm2022/item.mjs.map +0 -1
- package/kbd/fesm2022/kbd.mjs.map +0 -1
- package/label/fesm2022/label.mjs.map +0 -1
- package/layout-simple/fesm2022/layout-simple.mjs.map +0 -1
- package/menubar/fesm2022/menubar.mjs.map +0 -1
- package/native-select/fesm2022/native-select.mjs.map +0 -1
- package/navigation-menu/fesm2022/navigation-menu.mjs.map +0 -1
- package/pagination/fesm2022/pagination.mjs.map +0 -1
- package/popover/fesm2022/popover.mjs.map +0 -1
- package/progress/fesm2022/progress.mjs.map +0 -1
- package/radio-group/fesm2022/radio-group.mjs.map +0 -1
- package/resizable/fesm2022/resizable.mjs.map +0 -1
- package/scroll-area/fesm2022/scroll-area.mjs.map +0 -1
- package/searchable-multiselect/fesm2022/searchable-multiselect.mjs.map +0 -1
- package/select/fesm2022/select.mjs.map +0 -1
- package/separator/fesm2022/separator.mjs.map +0 -1
- package/sheet/fesm2022/sheet.mjs.map +0 -1
- package/sidebar/fesm2022/sidebar.mjs.map +0 -1
- package/skeleton/fesm2022/skeleton.mjs.map +0 -1
- package/slider/fesm2022/slider.mjs.map +0 -1
- package/sonner/fesm2022/sonner.mjs.map +0 -1
- package/spinner/fesm2022/spinner.mjs.map +0 -1
- package/switch/fesm2022/switch.mjs.map +0 -1
- package/table/fesm2022/table.mjs.map +0 -1
- package/tabs/fesm2022/tabs.mjs.map +0 -1
- package/textarea/fesm2022/textarea.mjs.map +0 -1
- package/toggle/fesm2022/toggle.mjs.map +0 -1
- package/toggle-group/fesm2022/toggle-group.mjs.map +0 -1
- package/tooltip/fesm2022/tooltip.mjs.map +0 -1
- package/typography/fesm2022/typography.mjs.map +0 -1
- package/utils/fesm2022/utils.mjs.map +0 -1
package/button-group/README.md
CHANGED
|
@@ -1,11 +1,324 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Button Group (`@egose/shadcn-theme-ng/button-group`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A joined, toolbar-style group layout that fuses buttons, inputs, selects, and static text into one visually continuous control — the Angular port of shadcn/ui `Button Group`. There is no interactive behavior of its own: `HlmButtonGroup` is a thin `cva`-styled layout directive (`orientation: horizontal | vertical`) that strips inner border-radii and collapses adjacent borders, while `HlmButtonGroupText` and `HlmButtonGroupSeparator` provide the static-text cell and the divider cell. The only headless primitive involved is `BrnSeparator` from `@spartan-ng/brain/separator` (used inside the separator directive).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Ships as `@egose/shadcn-theme-ng/button-group` and `@egose/shadcn-theme-ng-tw/button-group` (the `tw:`-prefixed variant). See the [package README](../../README.md) for install, peer dependencies, and Tailwind setup. Do not publish this project directory independently — it is consumed via the published subpath only.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Installation
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
|
|
10
|
+
# Plain Tailwind (no prefix):
|
|
11
|
+
npm install @egose/shadcn-theme-ng
|
|
12
|
+
|
|
13
|
+
# Or the tw:-prefixed variant:
|
|
14
|
+
npm install @egose/shadcn-theme-ng-tw
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Peer dependencies (Angular, `@spartan-ng/brain`, etc.) are documented in the [package README](../../README.md). This subpath itself declares `@angular/common`, `@angular/core`, and `@spartan-ng/brain` as peers (see `projects/button-group/package.json`).
|
|
18
|
+
|
|
19
|
+
## Imports
|
|
20
|
+
|
|
21
|
+
Named imports from the subpath public API (`projects/button-group/src/public-api.ts`):
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import {
|
|
25
|
+
HlmButtonGroup,
|
|
26
|
+
HlmButtonGroupText,
|
|
27
|
+
HlmButtonGroupSeparator,
|
|
28
|
+
HlmButtonGroupImports,
|
|
29
|
+
HlmButtonGroupModule,
|
|
30
|
+
} from '@egose/shadcn-theme-ng/button-group';
|
|
31
|
+
// tw variant:
|
|
32
|
+
// import { ... } from '@egose/shadcn-theme-ng-tw/button-group';
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Standalone-component usage (preferred):
|
|
36
|
+
|
|
37
|
+
```ts
|
|
38
|
+
import { Component } from '@angular/core';
|
|
39
|
+
import { HlmButtonGroupImports } from '@egose/shadcn-theme-ng/button-group';
|
|
40
|
+
|
|
41
|
+
@Component({
|
|
42
|
+
selector: 'app-demo',
|
|
43
|
+
standalone: true,
|
|
44
|
+
imports: [...HlmButtonGroupImports],
|
|
45
|
+
template: `...`,
|
|
46
|
+
})
|
|
47
|
+
export class DemoComponent {}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
NgModule usage:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
import { NgModule } from '@angular/core';
|
|
54
|
+
import { HlmButtonGroupModule } from '@egose/shadcn-theme-ng/button-group';
|
|
55
|
+
|
|
56
|
+
@NgModule({ imports: [HlmButtonGroupModule] })
|
|
57
|
+
export class DemoModule {}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
You can also import the three directives individually (`HlmButtonGroup`, `HlmButtonGroupText`, `HlmButtonGroupSeparator`) instead of the whole `HlmButtonGroupImports` array.
|
|
61
|
+
|
|
62
|
+
## Anatomy / Structure
|
|
63
|
+
|
|
64
|
+
```html
|
|
65
|
+
<!-- Element OR attribute form for the group itself -->
|
|
66
|
+
<hlm-button-group orientation="horizontal">
|
|
67
|
+
<button hlmBtn variant="outline">Left</button>
|
|
68
|
+
<button hlmBtn variant="outline">Middle</button>
|
|
69
|
+
<button hlmBtn variant="outline">Right</button>
|
|
70
|
+
</hlm-button-group>
|
|
71
|
+
|
|
72
|
+
<!-- With static text + separator (attribute forms also work) -->
|
|
73
|
+
<div hlmButtonGroup orientation="horizontal">
|
|
74
|
+
<span hlmButtonGroupText>https://</span>
|
|
75
|
+
<input hlmInput placeholder="example.com" />
|
|
76
|
+
<hlm-button-group-separator></hlm-button-group-separator>
|
|
77
|
+
<button hlmBtn>Go</button>
|
|
78
|
+
</div>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Real selectors (from source):
|
|
82
|
+
|
|
83
|
+
| Class | Selectors |
|
|
84
|
+
| ------------------------- | --------------------------------------------------------- |
|
|
85
|
+
| `HlmButtonGroup` | `[hlmButtonGroup]`, `hlm-button-group` |
|
|
86
|
+
| `HlmButtonGroupText` | `[hlmButtonGroupText]`, `hlm-button-group-text` |
|
|
87
|
+
| `HlmButtonGroupSeparator` | `[hlmButtonGroupSeparator]`, `hlm-button-group-separator` |
|
|
88
|
+
|
|
89
|
+
All three carry a `data-slot` host attribute (`button-group`, `button-group-text`, `button-group-separator`). The group host also sets `role="group"` and `[attr.data-orientation]`.
|
|
90
|
+
|
|
91
|
+
## API reference
|
|
92
|
+
|
|
93
|
+
### `HlmButtonGroup` (`[hlmButtonGroup]`, `hlm-button-group`)
|
|
94
|
+
|
|
95
|
+
| Input | Type | Default | Description |
|
|
96
|
+
| ------------- | ---------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
97
|
+
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Layout axis. `horizontal` collapses left/right radii and left borders; `vertical` stacks, collapses top/bottom radii and top borders. Reflected as `data-orientation`. |
|
|
98
|
+
|
|
99
|
+
No outputs, no methods. Styling is computed by `buttonGroupVariants({ orientation })` (cva) plus helpers for nested `select-trigger`, `input`, and nested `button-group` spacing.
|
|
100
|
+
|
|
101
|
+
### `HlmButtonGroupText` (`[hlmButtonGroupText]`, `hlm-button-group-text`)
|
|
102
|
+
|
|
103
|
+
Thin directive wrapper — no inputs, outputs, or methods. Renders a muted, bordered, static-text cell (`bg-muted`, `rounded-lg`, `px-2.5`, icon-aware). Use for prefixes/suffixes such as `https://`, `.com`, currency symbols, or counts.
|
|
104
|
+
|
|
105
|
+
### `HlmButtonGroupSeparator` (`[hlmButtonGroupSeparator]`, `hlm-button-group-separator`)
|
|
106
|
+
|
|
107
|
+
| Brain input (via `BrnSeparator` hostDirective) | Type | Default | Description |
|
|
108
|
+
| ---------------------------------------------- | ---------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
109
|
+
| `orientation` | `'horizontal' \| 'vertical'` | `'vertical'` (via `provideBrnSeparatorConfig`) | Separator axis. The provider defaults it to `vertical` so it divides horizontal groups out of the box; override for vertical groups. |
|
|
110
|
+
| `decorative` | `boolean` | — | Passed straight to `BrnSeparator` (aria-hidden handling). |
|
|
111
|
+
|
|
112
|
+
No outputs of its own. Host classes make it `self-stretch`, `bg-input`, 1px thick on the active axis.
|
|
113
|
+
|
|
114
|
+
## Examples
|
|
115
|
+
|
|
116
|
+
### 1. Basic horizontal button cluster
|
|
117
|
+
|
|
118
|
+
Three outline buttons fused into one segmented control.
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { Component } from '@angular/core';
|
|
122
|
+
import { HlmButtonGroupImports } from '@egose/shadcn-theme-ng/button-group';
|
|
123
|
+
import { HlmButtonImports } from '@egose/shadcn-theme-ng/button';
|
|
124
|
+
|
|
125
|
+
@Component({
|
|
126
|
+
selector: 'app-basic-group',
|
|
127
|
+
standalone: true,
|
|
128
|
+
imports: [...HlmButtonGroupImports, ...HlmButtonImports],
|
|
129
|
+
template: `
|
|
130
|
+
<hlm-button-group>
|
|
131
|
+
<button hlmBtn variant="outline">Left</button>
|
|
132
|
+
<button hlmBtn variant="outline">Center</button>
|
|
133
|
+
<button hlmBtn variant="outline">Right</button>
|
|
134
|
+
</hlm-button-group>
|
|
135
|
+
`,
|
|
136
|
+
})
|
|
137
|
+
export class BasicGroupComponent {}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### 2. All orientations
|
|
141
|
+
|
|
142
|
+
`horizontal` (default) vs `vertical`. Vertical stacks children and collapses vertical borders instead.
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
import { Component } from '@angular/core';
|
|
146
|
+
import { HlmButtonGroupImports } from '@egose/shadcn-theme-ng/button-group';
|
|
147
|
+
import { HlmButtonImports } from '@egose/shadcn-theme-ng/button';
|
|
148
|
+
|
|
149
|
+
@Component({
|
|
150
|
+
selector: 'app-orientations',
|
|
151
|
+
standalone: true,
|
|
152
|
+
imports: [...HlmButtonGroupImports, ...HlmButtonImports],
|
|
153
|
+
template: `
|
|
154
|
+
<div class="flex gap-8">
|
|
155
|
+
<hlm-button-group orientation="horizontal">
|
|
156
|
+
<button hlmBtn variant="outline">A</button>
|
|
157
|
+
<button hlmBtn variant="outline">B</button>
|
|
158
|
+
<button hlmBtn variant="outline">C</button>
|
|
159
|
+
</hlm-button-group>
|
|
160
|
+
|
|
161
|
+
<hlm-button-group orientation="vertical">
|
|
162
|
+
<button hlmBtn variant="outline">Top</button>
|
|
163
|
+
<button hlmBtn variant="outline">Middle</button>
|
|
164
|
+
<button hlmBtn variant="outline">Bottom</button>
|
|
165
|
+
</hlm-button-group>
|
|
166
|
+
</div>
|
|
167
|
+
`,
|
|
168
|
+
})
|
|
169
|
+
export class OrientationsComponent {}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### 3. Input group with static prefix/suffix text
|
|
173
|
+
|
|
174
|
+
Classic URL / price field: muted text cells fused with a native-styled input and an action button.
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
import { Component } from '@angular/core';
|
|
178
|
+
import { HlmButtonGroupImports } from '@egose/shadcn-theme-ng/button-group';
|
|
179
|
+
import { HlmButtonImports } from '@egose/shadcn-theme-ng/button';
|
|
180
|
+
import { HlmInput } from '@egose/shadcn-theme-ng/input';
|
|
181
|
+
|
|
182
|
+
@Component({
|
|
183
|
+
selector: 'app-addon-group',
|
|
184
|
+
standalone: true,
|
|
185
|
+
imports: [...HlmButtonGroupImports, ...HlmButtonImports, HlmInput],
|
|
186
|
+
template: `
|
|
187
|
+
<div hlmButtonGroup>
|
|
188
|
+
<span hlmButtonGroupText>https://</span>
|
|
189
|
+
<input hlmInput placeholder="example.com" class="w-48" />
|
|
190
|
+
<span hlmButtonGroupText>.com</span>
|
|
191
|
+
<button hlmBtn>Visit</button>
|
|
192
|
+
</div>
|
|
193
|
+
`,
|
|
194
|
+
})
|
|
195
|
+
export class AddonGroupComponent {}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### 4. Separated actions (divider cells)
|
|
199
|
+
|
|
200
|
+
Use `hlm-button-group-separator` between clusters instead of spacing utilities so the divider stretches to the group height.
|
|
201
|
+
|
|
202
|
+
```ts
|
|
203
|
+
import { Component } from '@angular/core';
|
|
204
|
+
import { HlmButtonGroupImports } from '@egose/shadcn-theme-ng/button-group';
|
|
205
|
+
import { HlmButtonImports } from '@egose/shadcn-theme-ng/button';
|
|
206
|
+
|
|
207
|
+
@Component({
|
|
208
|
+
selector: 'app-separated-group',
|
|
209
|
+
standalone: true,
|
|
210
|
+
imports: [...HlmButtonGroupImports, ...HlmButtonImports],
|
|
211
|
+
template: `
|
|
212
|
+
<hlm-button-group>
|
|
213
|
+
<button hlmBtn variant="outline">Cut</button>
|
|
214
|
+
<button hlmBtn variant="outline">Copy</button>
|
|
215
|
+
<button hlmBtn variant="outline">Paste</button>
|
|
216
|
+
<hlm-button-group-separator></hlm-button-group-separator>
|
|
217
|
+
<button hlmBtn variant="outline">Undo</button>
|
|
218
|
+
<button hlmBtn variant="outline">Redo</button>
|
|
219
|
+
</hlm-button-group>
|
|
220
|
+
`,
|
|
221
|
+
})
|
|
222
|
+
export class SeparatedGroupComponent {}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Explanation: the separator defaults to `orientation="vertical"` via its provider. Inside a `orientation="vertical"` group, bind it explicitly:
|
|
226
|
+
|
|
227
|
+
```html
|
|
228
|
+
<hlm-button-group orientation="vertical">
|
|
229
|
+
<button hlmBtn variant="outline">One</button>
|
|
230
|
+
<hlm-button-group-separator orientation="horizontal"></hlm-button-group-separator>
|
|
231
|
+
<button hlmBtn variant="outline">Two</button>
|
|
232
|
+
</hlm-button-group>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### 5. Mixed controls: select + input + button
|
|
236
|
+
|
|
237
|
+
The group stylesheet special-cases `select-trigger` and `input` children (`w-fit` triggers, `flex-1` inputs), so mixed toolbars fuse cleanly.
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
import { Component, signal } from '@angular/core';
|
|
241
|
+
import { HlmButtonGroupImports } from '@egose/shadcn-theme-ng/button-group';
|
|
242
|
+
import { HlmButtonImports } from '@egose/shadcn-theme-ng/button';
|
|
243
|
+
import { HlmInput } from '@egose/shadcn-theme-ng/input';
|
|
244
|
+
import { HlmSelectImports } from '@egose/shadcn-theme-ng/select';
|
|
245
|
+
|
|
246
|
+
@Component({
|
|
247
|
+
selector: 'app-mixed-group',
|
|
248
|
+
standalone: true,
|
|
249
|
+
imports: [...HlmButtonGroupImports, ...HlmButtonImports, HlmInput, ...HlmSelectImports],
|
|
250
|
+
template: `
|
|
251
|
+
<div hlmButtonGroup>
|
|
252
|
+
<hlm-select [value]="unit()">
|
|
253
|
+
<hlm-select-trigger class="w-28">
|
|
254
|
+
<hlm-select-value />
|
|
255
|
+
</hlm-select-trigger>
|
|
256
|
+
<hlm-select-content *hlmSelectPortal>
|
|
257
|
+
<hlm-select-item value="px">px</hlm-select-item>
|
|
258
|
+
<hlm-select-item value="rem">rem</hlm-select-item>
|
|
259
|
+
<hlm-select-item value="em">em</hlm-select-item>
|
|
260
|
+
</hlm-select-content>
|
|
261
|
+
</hlm-select>
|
|
262
|
+
<input hlmInput type="number" value="16" class="w-24" />
|
|
263
|
+
<button hlmBtn (click)="apply()">Apply</button>
|
|
264
|
+
</div>
|
|
265
|
+
`,
|
|
266
|
+
})
|
|
267
|
+
export class MixedGroupComponent {
|
|
268
|
+
readonly unit = signal('px');
|
|
269
|
+
apply() {
|
|
270
|
+
console.log('apply', this.unit());
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### 6. Icon toolbar with labels for assistive tech
|
|
276
|
+
|
|
277
|
+
Buttons keep their own `aria-label`s; the group only adds `role="group"` — give it an `aria-label` for context.
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
import { Component } from '@angular/core';
|
|
281
|
+
import { HlmButtonGroupImports } from '@egose/shadcn-theme-ng/button-group';
|
|
282
|
+
import { HlmButtonImports } from '@egose/shadcn-theme-ng/button';
|
|
283
|
+
import { NgIcon, provideIcons } from '@ng-icons/core';
|
|
284
|
+
import { lucideBold, lucideItalic, lucideUnderline } from '@ng-icons/lucide';
|
|
285
|
+
|
|
286
|
+
@Component({
|
|
287
|
+
selector: 'app-toolbar-group',
|
|
288
|
+
standalone: true,
|
|
289
|
+
imports: [...HlmButtonGroupImports, ...HlmButtonImports, NgIcon],
|
|
290
|
+
providers: [provideIcons({ lucideBold, lucideItalic, lucideUnderline })],
|
|
291
|
+
template: `
|
|
292
|
+
<hlm-button-group aria-label="Text formatting">
|
|
293
|
+
<button hlmBtn variant="outline" size="icon" aria-label="Bold">
|
|
294
|
+
<ng-icon name="lucideBold" />
|
|
295
|
+
</button>
|
|
296
|
+
<button hlmBtn variant="outline" size="icon" aria-label="Italic">
|
|
297
|
+
<ng-icon name="lucideItalic" />
|
|
298
|
+
</button>
|
|
299
|
+
<button hlmBtn variant="outline" size="icon" aria-label="Underline">
|
|
300
|
+
<ng-icon name="lucideUnderline" />
|
|
301
|
+
</button>
|
|
302
|
+
</hlm-button-group>
|
|
303
|
+
`,
|
|
304
|
+
})
|
|
305
|
+
export class ToolbarGroupComponent {}
|
|
11
306
|
```
|
|
307
|
+
|
|
308
|
+
## Accessibility notes
|
|
309
|
+
|
|
310
|
+
- The group host renders `role="group"` — always pair it with `aria-label` or `aria-labelledby` when the purpose is not obvious from the buttons alone.
|
|
311
|
+
- `HlmButtonGroupSeparator` delegates to `BrnSeparator`: mark purely visual dividers `decorative`, otherwise keep them exposed so screen readers announce the grouping break.
|
|
312
|
+
- `HlmButtonGroupText` is a plain `<span>`-style cell with no semantics; never put interactive content inside it.
|
|
313
|
+
- Keyboard behavior is unchanged — Tab moves through each fused button/input normally; roving tabindex is not applied.
|
|
314
|
+
|
|
315
|
+
## Theming / CSS variables
|
|
316
|
+
|
|
317
|
+
No component-specific CSS variables. Styling is Tailwind-driven (`bg-muted` text cells, `bg-input` separators, ring/border tokens). Dark mode follows the shared `tw:dark:` theme tokens. Override via `class` on any cell — the `classes()` helper merges your classes with the defaults.
|
|
318
|
+
|
|
319
|
+
## Related subpaths
|
|
320
|
+
|
|
321
|
+
- `@egose/shadcn-theme-ng/button` — `hlmBtn` / `HlmBtn` used for every fused button.
|
|
322
|
+
- `@egose/shadcn-theme-ng/input` — `hlmInput` fused text/number fields.
|
|
323
|
+
- `@egose/shadcn-theme-ng/select` — triggers auto-size (`w-fit`) inside groups.
|
|
324
|
+
- `@egose/shadcn-theme-ng/separator` — standalone separator primitive (the group ships its own opinionated divider).
|
|
@@ -5,11 +5,11 @@ import { cva } from 'class-variance-authority';
|
|
|
5
5
|
import * as i1 from '@spartan-ng/brain/separator';
|
|
6
6
|
import { provideBrnSeparatorConfig, BrnSeparator } from '@spartan-ng/brain/separator';
|
|
7
7
|
|
|
8
|
-
const buttonGroupVariants = cva("has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-
|
|
8
|
+
const buttonGroupVariants = cva("tw:has-[>[data-slot=button-group]]:gap-2 tw:has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-lg tw:flex tw:w-fit tw:items-stretch tw:*:focus-visible:relative tw:*:focus-visible:z-10 tw:[&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit tw:[&>input]:flex-1", {
|
|
9
9
|
variants: {
|
|
10
10
|
orientation: {
|
|
11
|
-
horizontal: '[&>[data-slot]:not(:has(~[data-slot]))]:rounded-
|
|
12
|
-
vertical: '[&>[data-slot]:not(:has(~[data-slot]))]:rounded-b-
|
|
11
|
+
horizontal: 'tw:[&>[data-slot]:not(:has(~[data-slot]))]:rounded-r-lg! tw:[&>*:not(:first-child)]:rounded-l-none tw:[&>*:not(:first-child)]:border-l-0 tw:[&>*:not(:last-child)]:rounded-r-none',
|
|
12
|
+
vertical: 'tw:[&>[data-slot]:not(:has(~[data-slot]))]:rounded-b-lg! tw:flex-col tw:[&>*:not(:first-child)]:rounded-t-none tw:[&>*:not(:first-child)]:border-t-0 tw:[&>*:not(:last-child)]:rounded-b-none',
|
|
13
13
|
},
|
|
14
14
|
},
|
|
15
15
|
defaultVariants: {
|
|
@@ -22,10 +22,10 @@ class HlmButtonGroup {
|
|
|
22
22
|
}
|
|
23
23
|
orientation = input('horizontal', /* @ts-ignore */
|
|
24
24
|
...(ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []));
|
|
25
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
26
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.
|
|
25
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmButtonGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
26
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.3", type: HlmButtonGroup, isStandalone: true, selector: "[hlmButtonGroup],hlm-button-group", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "data-slot": "button-group", "role": "group" }, properties: { "attr.data-orientation": "orientation()" } }, ngImport: i0 });
|
|
27
27
|
}
|
|
28
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
28
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmButtonGroup, decorators: [{
|
|
29
29
|
type: Directive,
|
|
30
30
|
args: [{
|
|
31
31
|
selector: '[hlmButtonGroup],hlm-button-group',
|
|
@@ -40,15 +40,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
40
40
|
class HlmButtonGroupSeparator {
|
|
41
41
|
constructor() {
|
|
42
42
|
classes(() => [
|
|
43
|
-
'bg-input relative self-stretch data-horizontal:mx-px data-horizontal:w-auto data-vertical:my-px data-vertical:h-auto',
|
|
43
|
+
'tw:bg-input tw:relative tw:self-stretch tw:data-horizontal:mx-px tw:data-horizontal:w-auto tw:data-vertical:my-px tw:data-vertical:h-auto',
|
|
44
44
|
// separator classes
|
|
45
|
-
'shrink-0 data-horizontal:h-px data-vertical:w-px data-vertical:self-stretch',
|
|
45
|
+
'tw:shrink-0 tw:data-horizontal:h-px tw:data-vertical:w-px tw:data-vertical:self-stretch',
|
|
46
46
|
]);
|
|
47
47
|
}
|
|
48
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
49
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.
|
|
48
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmButtonGroupSeparator, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
49
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmButtonGroupSeparator, isStandalone: true, selector: "[hlmButtonGroupSeparator],hlm-button-group-separator", host: { attributes: { "data-slot": "button-group-separator" } }, providers: [provideBrnSeparatorConfig({ orientation: 'vertical' })], hostDirectives: [{ directive: i1.BrnSeparator, inputs: ["orientation", "orientation", "decorative", "decorative"] }], ngImport: i0 });
|
|
50
50
|
}
|
|
51
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
51
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmButtonGroupSeparator, decorators: [{
|
|
52
52
|
type: Directive,
|
|
53
53
|
args: [{
|
|
54
54
|
selector: '[hlmButtonGroupSeparator],hlm-button-group-separator',
|
|
@@ -62,12 +62,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
62
62
|
|
|
63
63
|
class HlmButtonGroupText {
|
|
64
64
|
constructor() {
|
|
65
|
-
classes(() => "bg-muted gap-2 rounded-
|
|
65
|
+
classes(() => "tw:bg-muted tw:gap-2 tw:rounded-lg tw:border tw:px-2.5 tw:text-sm tw:font-medium tw:shadow-xs tw:[&_ng-icon:not([class*='text-'])]:text-[length:--spacing(4)] tw:flex tw:items-center tw:[&_ng-icon]:pointer-events-none");
|
|
66
66
|
}
|
|
67
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
68
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.
|
|
67
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmButtonGroupText, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
68
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmButtonGroupText, isStandalone: true, selector: "[hlmButtonGroupText],hlm-button-group-text", host: { attributes: { "data-slot": "button-group-text" } }, ngImport: i0 });
|
|
69
69
|
}
|
|
70
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
70
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmButtonGroupText, decorators: [{
|
|
71
71
|
type: Directive,
|
|
72
72
|
args: [{
|
|
73
73
|
selector: '[hlmButtonGroupText],hlm-button-group-text',
|
|
@@ -82,11 +82,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
82
82
|
*/
|
|
83
83
|
const HlmButtonGroupImports = [HlmButtonGroup, HlmButtonGroupText, HlmButtonGroupSeparator];
|
|
84
84
|
class HlmButtonGroupModule {
|
|
85
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
86
|
-
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.
|
|
87
|
-
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.
|
|
85
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmButtonGroupModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
86
|
+
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.1.3", ngImport: i0, type: HlmButtonGroupModule, imports: [HlmButtonGroup, HlmButtonGroupText, HlmButtonGroupSeparator], exports: [HlmButtonGroup, HlmButtonGroupText, HlmButtonGroupSeparator] });
|
|
87
|
+
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmButtonGroupModule });
|
|
88
88
|
}
|
|
89
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
89
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmButtonGroupModule, decorators: [{
|
|
90
90
|
type: NgModule,
|
|
91
91
|
args: [{
|
|
92
92
|
imports: [...HlmButtonGroupImports],
|
|
@@ -99,4 +99,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
99
99
|
*/
|
|
100
100
|
|
|
101
101
|
export { HlmButtonGroup, HlmButtonGroupImports, HlmButtonGroupModule, HlmButtonGroupSeparator, HlmButtonGroupText };
|
|
102
|
-
|
|
102
|
+
|