@egose/shadcn-theme-ng 0.0.28 → 0.1.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 +2 -63
- package/accordion/fesm2022/accordion.mjs +27 -39
- package/alert/README.md +2 -63
- package/alert/fesm2022/alert.mjs +47 -47
- package/alert-dialog/fesm2022/alert-dialog.mjs +47 -47
- package/aspect-ratio/fesm2022/aspect-ratio.mjs +9 -9
- package/autocomplete/README.md +2 -63
- package/autocomplete/fesm2022/autocomplete.mjs +53 -71
- package/avatar/fesm2022/avatar.mjs +32 -32
- package/badge/README.md +2 -63
- package/badge/fesm2022/badge.mjs +57 -57
- package/basic-alert/README.md +2 -63
- package/basic-alert/fesm2022/basic-alert.mjs +6 -18
- package/breadcrumb/fesm2022/breadcrumb.mjs +33 -39
- package/button/README.md +2 -63
- package/button/fesm2022/button.mjs +126 -176
- package/button/types/button.d.ts +2 -2
- package/button-group/fesm2022/button-group.mjs +20 -20
- package/calendar/README.md +2 -63
- package/calendar/fesm2022/calendar.mjs +29 -743
- package/card/fesm2022/card.mjs +33 -33
- package/carousel/fesm2022/carousel.mjs +36 -78
- package/checkbox/README.md +2 -63
- package/checkbox/fesm2022/checkbox.mjs +20 -58
- package/checkbox/types/checkbox.d.ts +5 -4
- package/collapsible/fesm2022/collapsible.mjs +15 -15
- package/combobox/fesm2022/combobox.mjs +88 -224
- package/command/fesm2022/command.mjs +49 -109
- package/confirmation-dialog/README.md +2 -63
- package/confirmation-dialog/fesm2022/confirmation-dialog.mjs +15 -40
- package/confirmation-dialog/types/confirmation-dialog.d.ts +8 -4
- package/context-menu/fesm2022/context-menu.mjs +9 -9
- package/date-picker/README.md +2 -63
- package/date-picker/fesm2022/date-picker.mjs +63 -266
- package/date-picker/types/date-picker.d.ts +7 -3
- package/dialog/README.md +2 -63
- package/dialog/fesm2022/dialog.mjs +45 -71
- package/drawer/fesm2022/drawer.mjs +44 -54
- package/dropdown-menu/fesm2022/dropdown-menu.mjs +82 -70
- package/dropdown-menu/types/dropdown-menu.d.ts +4 -0
- package/empty/fesm2022/empty.mjs +30 -30
- package/field/fesm2022/field.mjs +56 -72
- package/form-checkbox/README.md +2 -63
- package/form-checkbox/fesm2022/form-checkbox.mjs +25 -85
- package/form-checkbox/types/form-checkbox.d.ts +7 -1
- package/form-date-picker/README.md +2 -63
- package/form-date-picker/fesm2022/form-date-picker.mjs +31 -84
- package/form-date-picker/types/form-date-picker.d.ts +7 -1
- package/form-field/README.md +2 -63
- package/form-field/fesm2022/form-field.mjs +33 -19
- package/form-field/types/form-field.d.ts +28 -20
- package/form-field-simple/README.md +2 -63
- package/form-field-simple/fesm2022/form-field-simple.mjs +4 -4
- package/form-searchable-multiselect/README.md +2 -63
- package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +31 -91
- package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +7 -1
- package/form-select/README.md +2 -63
- package/form-select/fesm2022/form-select.mjs +32 -149
- package/form-select/types/form-select.d.ts +7 -1
- package/form-text-input/README.md +2 -63
- package/form-text-input/fesm2022/form-text-input.mjs +35 -149
- package/form-text-input/types/form-text-input.d.ts +9 -12
- package/form-textarea/README.md +2 -63
- package/form-textarea/fesm2022/form-textarea.mjs +34 -109
- package/form-textarea/types/form-textarea.d.ts +8 -1
- package/hover-card/fesm2022/hover-card.mjs +19 -19
- package/icon/README.md +2 -63
- package/icon/fesm2022/icon.mjs +8 -8
- package/input/README.md +2 -63
- package/input/fesm2022/input.mjs +17 -12
- package/input/types/input.d.ts +2 -1
- package/input-group/fesm2022/input-group.mjs +33 -33
- package/input-otp/fesm2022/input-otp.mjs +26 -26
- package/item/fesm2022/item.mjs +53 -53
- package/kbd/fesm2022/kbd.mjs +12 -12
- package/label/README.md +2 -63
- package/label/fesm2022/label.mjs +10 -10
- package/label/types/label.d.ts +1 -1
- package/layout-simple/README.md +2 -63
- package/layout-simple/fesm2022/layout-simple.mjs +98 -429
- package/layout-simple/types/layout-simple.d.ts +25 -11
- package/menu/README.md +3 -0
- package/menu/fesm2022/menu.mjs +455 -0
- package/menu/package.json +24 -0
- package/menu/types/menu.d.ts +137 -0
- package/menubar/fesm2022/menubar.mjs +13 -13
- package/native-select/fesm2022/native-select.mjs +19 -19
- package/navigation-menu/fesm2022/navigation-menu.mjs +35 -47
- package/package.json +183 -154
- package/pagination/fesm2022/pagination.mjs +45 -331
- package/popover/README.md +2 -63
- package/popover/fesm2022/popover.mjs +30 -30
- package/progress/fesm2022/progress.mjs +13 -13
- package/radio-group/README.md +2 -63
- package/radio-group/fesm2022/radio-group.mjs +22 -19
- package/resizable/fesm2022/resizable.mjs +18 -26
- package/scroll-area/fesm2022/scroll-area.mjs +9 -9
- package/searchable-multiselect/README.md +2 -63
- package/searchable-multiselect/fesm2022/searchable-multiselect.mjs +28 -117
- package/searchable-multiselect/types/searchable-multiselect.d.ts +8 -2
- package/select/README.md +2 -63
- package/select/fesm2022/select.mjs +71 -111
- package/select/types/select.d.ts +3 -1
- package/separator/README.md +2 -63
- package/separator/fesm2022/separator.mjs +9 -9
- package/separator/types/separator.d.ts +1 -1
- package/sheet/README.md +2 -63
- package/sheet/fesm2022/sheet.mjs +41 -53
- package/sidebar/fesm2022/sidebar.mjs +125 -227
- package/skeleton/fesm2022/skeleton.mjs +9 -9
- package/slider/fesm2022/slider.mjs +10 -80
- package/sonner/README.md +2 -63
- package/sonner/fesm2022/sonner.mjs +13 -13
- package/spinner/README.md +2 -63
- package/spinner/fesm2022/spinner.mjs +11 -11
- package/switch/README.md +2 -63
- package/switch/fesm2022/switch.mjs +13 -15
- package/table/fesm2022/table.mjs +41 -41
- package/tabs/README.md +2 -63
- package/tabs/fesm2022/tabs.mjs +35 -111
- package/textarea/fesm2022/textarea.mjs +9 -9
- package/toggle/fesm2022/toggle.mjs +13 -13
- package/toggle-group/fesm2022/toggle-group.mjs +13 -13
- package/toggle-group/types/toggle-group.d.ts +13 -7
- package/tooltip/README.md +2 -63
- package/tooltip/fesm2022/tooltip.mjs +14 -14
- package/typography/fesm2022/typography.mjs +53 -53
- package/typography/types/typography.d.ts +12 -12
- package/utils/README.md +2 -63
- 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
|
@@ -1,64 +1,3 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Searchable Multiselect Subpath
|
|
2
2
|
|
|
3
|
-
This project
|
|
4
|
-
|
|
5
|
-
## Code scaffolding
|
|
6
|
-
|
|
7
|
-
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
ng generate component component-name
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
ng generate --help
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Building
|
|
20
|
-
|
|
21
|
-
To build the library, run:
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
ng build searchable-multiselect
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
|
|
28
|
-
|
|
29
|
-
### Publishing the Library
|
|
30
|
-
|
|
31
|
-
Once the project is built, you can publish your library by following these steps:
|
|
32
|
-
|
|
33
|
-
1. Navigate to the `dist` directory:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
cd dist/searchable-multiselect
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
2. Run the `npm publish` command to publish your library to the npm registry:
|
|
40
|
-
```bash
|
|
41
|
-
npm publish
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Running unit tests
|
|
45
|
-
|
|
46
|
-
To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
ng test
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Running end-to-end tests
|
|
53
|
-
|
|
54
|
-
For end-to-end (e2e) testing, run:
|
|
55
|
-
|
|
56
|
-
```bash
|
|
57
|
-
ng e2e
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
|
|
61
|
-
|
|
62
|
-
## Additional Resources
|
|
63
|
-
|
|
64
|
-
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
|
3
|
+
This project ships only as `@egose/shadcn-theme-ng/searchable-multiselect` or `@egose/shadcn-theme-ng-tw/searchable-multiselect`. See the [package README](../../README.md) for installation, compatibility, Tailwind variant, test, and release guidance. Do not publish this project directory independently.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { input, output, signal, computed, forwardRef, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
3
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
4
|
-
import { HlmPopover, HlmPopoverTrigger, HlmPopoverContent } from '@egose/shadcn-theme-ng/popover';
|
|
4
|
+
import { HlmPopover, HlmPopoverTrigger, HlmPopoverContent, HlmPopoverPortal } from '@egose/shadcn-theme-ng/popover';
|
|
5
5
|
import { HlmButton } from '@egose/shadcn-theme-ng/button';
|
|
6
6
|
import { HlmCheckbox } from '@egose/shadcn-theme-ng/checkbox';
|
|
7
7
|
import { hlm } from '@egose/shadcn-theme-ng/utils';
|
|
@@ -12,6 +12,16 @@ class EgSearchableMultiselect {
|
|
|
12
12
|
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
13
13
|
placeholder = input('Start typing to add…', /* @ts-ignore */
|
|
14
14
|
...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
15
|
+
id = input('', /* @ts-ignore */
|
|
16
|
+
...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
17
|
+
disabled = input(false, /* @ts-ignore */
|
|
18
|
+
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
19
|
+
wrapperDisabled = input(false, /* @ts-ignore */
|
|
20
|
+
...(ngDevMode ? [{ debugName: "wrapperDisabled" }] : /* istanbul ignore next */ []));
|
|
21
|
+
ariaLabel = input(undefined, /* @ts-ignore */
|
|
22
|
+
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
23
|
+
ariaDescribedby = input(null, /* @ts-ignore */
|
|
24
|
+
...(ngDevMode ? [{ debugName: "ariaDescribedby" }] : /* istanbul ignore next */ []));
|
|
15
25
|
userClass = input('', { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: 'class' });
|
|
16
26
|
/** Value: array of selected values (string[]) */
|
|
17
27
|
value = input([], /* @ts-ignore */
|
|
@@ -19,7 +29,10 @@ class EgSearchableMultiselect {
|
|
|
19
29
|
valueChange = output();
|
|
20
30
|
selectedItems = signal([], /* @ts-ignore */
|
|
21
31
|
...(ngDevMode ? [{ debugName: "selectedItems" }] : /* istanbul ignore next */ []));
|
|
22
|
-
|
|
32
|
+
formDisabled = signal(false, /* @ts-ignore */
|
|
33
|
+
...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
|
|
34
|
+
disabledState = computed(() => this.disabled() || this.wrapperDisabled() || this.formDisabled(), /* @ts-ignore */
|
|
35
|
+
...(ngDevMode ? [{ debugName: "disabledState" }] : /* istanbul ignore next */ []));
|
|
23
36
|
isFormBound = false;
|
|
24
37
|
_hostClass = computed(() => hlm(this.userClass()), /* @ts-ignore */
|
|
25
38
|
...(ngDevMode ? [{ debugName: "_hostClass" }] : /* istanbul ignore next */ []));
|
|
@@ -27,6 +40,8 @@ class EgSearchableMultiselect {
|
|
|
27
40
|
return this.selectedItems().some((s) => s.value === value);
|
|
28
41
|
}
|
|
29
42
|
toggle(value, checked) {
|
|
43
|
+
if (this.disabledState())
|
|
44
|
+
return;
|
|
30
45
|
if (checked) {
|
|
31
46
|
this.addItem(value);
|
|
32
47
|
}
|
|
@@ -44,6 +59,8 @@ class EgSearchableMultiselect {
|
|
|
44
59
|
}
|
|
45
60
|
}
|
|
46
61
|
removeItem(value) {
|
|
62
|
+
if (this.disabledState())
|
|
63
|
+
return;
|
|
47
64
|
const updated = this.selectedItems().filter((i) => i.value !== value);
|
|
48
65
|
this.updateValueFromSelected(updated);
|
|
49
66
|
}
|
|
@@ -75,76 +92,23 @@ class EgSearchableMultiselect {
|
|
|
75
92
|
this.onTouched = fn;
|
|
76
93
|
}
|
|
77
94
|
setDisabledState(isDisabled) {
|
|
78
|
-
this.isDisabled
|
|
95
|
+
this.formDisabled.set(isDisabled);
|
|
79
96
|
}
|
|
80
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
81
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.
|
|
97
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: EgSearchableMultiselect, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
98
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.3", type: EgSearchableMultiselect, isStandalone: true, selector: "eg-searchable-multiselect", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, wrapperDisabled: { classPropertyName: "wrapperDisabled", publicName: "wrapperDisabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaDescribedby: { classPropertyName: "ariaDescribedby", publicName: "ariaDescribedby", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange" }, host: { properties: { "class": "_hostClass()" } }, providers: [
|
|
82
99
|
{
|
|
83
100
|
provide: NG_VALUE_ACCESSOR,
|
|
84
101
|
useExisting: forwardRef(() => EgSearchableMultiselect),
|
|
85
102
|
multi: true,
|
|
86
103
|
},
|
|
87
|
-
], ngImport: i0, template:
|
|
88
|
-
<div class="flex flex-col gap-2 w-full">
|
|
89
|
-
<!-- Selected chips -->
|
|
90
|
-
<div class="flex flex-wrap gap-2">
|
|
91
|
-
@if (selectedItems().length === 0) {
|
|
92
|
-
<span
|
|
93
|
-
class="bg-gray-100 text-gray-400 rounded-full
|
|
94
|
-
px-2 py-1 inline-flex items-center text-xs"
|
|
95
|
-
>
|
|
96
|
-
{{ placeholder() }}
|
|
97
|
-
</span>
|
|
98
|
-
} @else {
|
|
99
|
-
@for (item of selectedItems(); track item.value) {
|
|
100
|
-
<span
|
|
101
|
-
class="bg-gray-200 rounded-full px-2 py-1
|
|
102
|
-
inline-flex items-center gap-2 text-xs"
|
|
103
|
-
>
|
|
104
|
-
{{ item.label }}
|
|
105
|
-
<button
|
|
106
|
-
type="button"
|
|
107
|
-
(click)="removeItem(item.value)"
|
|
108
|
-
class="bg-transparent border-0 text-gray-600
|
|
109
|
-
hover:text-red-500 cursor-pointer"
|
|
110
|
-
>
|
|
111
|
-
✕
|
|
112
|
-
</button>
|
|
113
|
-
</span>
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
</div>
|
|
117
|
-
|
|
118
|
-
<!-- Trigger -->
|
|
119
|
-
<hlm-popover>
|
|
120
|
-
<button hlmPopoverTrigger hlmButton variant="secondary" appearance="outline" type="button">
|
|
121
|
-
{{ selectedItems().length }} selected
|
|
122
|
-
</button>
|
|
123
|
-
|
|
124
|
-
<hlm-popover-content class="w-64 p-2">
|
|
125
|
-
<div class="max-h-60 overflow-auto flex flex-col gap-1">
|
|
126
|
-
@for (option of options(); track option.value) {
|
|
127
|
-
<label
|
|
128
|
-
class="flex items-center gap-2 cursor-pointer px-2 py-1 rounded-sm hover:bg-secondary"
|
|
129
|
-
>
|
|
130
|
-
<hlm-checkbox [checked]="isSelected(option.value)" (changed)="toggle(option.value, $event)" />
|
|
131
|
-
<span class="text-sm">{{ option.label }}</span>
|
|
132
|
-
</label>
|
|
133
|
-
} @empty {
|
|
134
|
-
<span class="text-xs text-muted-foreground px-2 py-1">No options</span>
|
|
135
|
-
}
|
|
136
|
-
</div>
|
|
137
|
-
</hlm-popover-content>
|
|
138
|
-
</hlm-popover>
|
|
139
|
-
</div>
|
|
140
|
-
`, isInline: true, dependencies: [{ kind: "directive", type: HlmPopover, selector: "[hlmPopover],hlm-popover" }, { kind: "directive", type: HlmPopoverTrigger, selector: "button[hlmPopoverTrigger],button[hlmPopoverTriggerFor]" }, { kind: "directive", type: HlmPopoverContent, selector: "[hlmPopoverContent],hlm-popover-content" }, { kind: "component", type: HlmButton, selector: "button[hlmButton], a[hlmButton]", inputs: ["variant", "size", "appearance", "loading", "icon", "iconPosition", "class", "spinnerUserClass", "disabled", "type"] }, { kind: "component", type: HlmCheckbox, selector: "hlm-checkbox", inputs: ["class", "id", "aria-label", "aria-labelledby", "aria-describedby", "checked", "name", "required", "disabled"], outputs: ["checkedChange", "changed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
104
|
+
], ngImport: i0, template: "\n <div class=\"flex flex-col gap-2 w-full\">\n <!-- Selected chips -->\n <div class=\"flex flex-wrap gap-2\">\n @if (selectedItems().length === 0) {\n <span\n class=\"bg-gray-100 text-gray-400 rounded-full\n px-2 py-1 inline-flex items-center text-xs\"\n >\n {{ placeholder() }}\n </span>\n } @else {\n @for (item of selectedItems(); track item.value) {\n <span\n class=\"bg-gray-200 rounded-full px-2 py-1\n inline-flex items-center gap-2 text-xs\"\n >\n {{ item.label }}\n <button\n type=\"button\"\n [disabled]=\"disabledState()\"\n (click)=\"removeItem(item.value)\"\n class=\"bg-transparent border-0 text-gray-600\n hover:text-red-500 cursor-pointer\"\n >\n ✕\n </button>\n </span>\n }\n }\n </div>\n\n <!-- Trigger -->\n <hlm-popover>\n <button\n hlmPopoverTrigger\n hlmButton\n variant=\"secondary\"\n appearance=\"outline\"\n type=\"button\"\n [id]=\"id()\"\n [disabled]=\"disabledState()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-describedby]=\"ariaDescribedby()\"\n >\n {{ selectedItems().length }} selected\n </button>\n\n <hlm-popover-content class=\"w-64 p-2\" *hlmPopoverPortal=\"let ctx\">\n <div class=\"max-h-60 overflow-auto flex flex-col gap-1\">\n @for (option of options(); track option.value) {\n <label\n class=\"flex items-center gap-2 cursor-pointer px-2 py-1 rounded-sm hover:bg-secondary\"\n >\n <hlm-checkbox\n [checked]=\"isSelected(option.value)\"\n [disabled]=\"disabledState()\"\n (changed)=\"toggle(option.value, $event)\"\n />\n <span class=\"text-sm\">{{ option.label }}</span>\n </label>\n } @empty {\n <span class=\"text-xs text-muted-foreground px-2 py-1\">No options</span>\n }\n </div>\n </hlm-popover-content>\n </hlm-popover>\n </div>\n ", isInline: true, dependencies: [{ kind: "directive", type: HlmPopover, selector: "[hlmPopover],hlm-popover" }, { kind: "directive", type: HlmPopoverTrigger, selector: "button[hlmPopoverTrigger],button[hlmPopoverTriggerFor]" }, { kind: "directive", type: HlmPopoverContent, selector: "[hlmPopoverContent],hlm-popover-content" }, { kind: "directive", type: HlmPopoverPortal, selector: "[hlmPopoverPortal]" }, { kind: "component", type: HlmButton, selector: "button[hlmButton], a[hlmButton]", inputs: ["variant", "size", "appearance", "loading", "icon", "iconPosition", "class", "spinnerUserClass", "disabled", "type"] }, { kind: "component", type: HlmCheckbox, selector: "hlm-checkbox", inputs: ["class", "id", "aria-label", "aria-labelledby", "aria-describedby", "checked", "name", "required", "disabled", "wrapperDisabled"], outputs: ["checkedChange", "changed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
141
105
|
}
|
|
142
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
106
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: EgSearchableMultiselect, decorators: [{
|
|
143
107
|
type: Component,
|
|
144
108
|
args: [{
|
|
145
109
|
selector: 'eg-searchable-multiselect',
|
|
146
110
|
standalone: true,
|
|
147
|
-
imports: [HlmPopover, HlmPopoverTrigger, HlmPopoverContent, HlmButton, HlmCheckbox],
|
|
111
|
+
imports: [HlmPopover, HlmPopoverTrigger, HlmPopoverContent, HlmPopoverPortal, HlmButton, HlmCheckbox],
|
|
148
112
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
149
113
|
providers: [
|
|
150
114
|
{
|
|
@@ -156,62 +120,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
156
120
|
host: {
|
|
157
121
|
'[class]': '_hostClass()',
|
|
158
122
|
},
|
|
159
|
-
template:
|
|
160
|
-
<div class="flex flex-col gap-2 w-full">
|
|
161
|
-
<!-- Selected chips -->
|
|
162
|
-
<div class="flex flex-wrap gap-2">
|
|
163
|
-
@if (selectedItems().length === 0) {
|
|
164
|
-
<span
|
|
165
|
-
class="bg-gray-100 text-gray-400 rounded-full
|
|
166
|
-
px-2 py-1 inline-flex items-center text-xs"
|
|
167
|
-
>
|
|
168
|
-
{{ placeholder() }}
|
|
169
|
-
</span>
|
|
170
|
-
} @else {
|
|
171
|
-
@for (item of selectedItems(); track item.value) {
|
|
172
|
-
<span
|
|
173
|
-
class="bg-gray-200 rounded-full px-2 py-1
|
|
174
|
-
inline-flex items-center gap-2 text-xs"
|
|
175
|
-
>
|
|
176
|
-
{{ item.label }}
|
|
177
|
-
<button
|
|
178
|
-
type="button"
|
|
179
|
-
(click)="removeItem(item.value)"
|
|
180
|
-
class="bg-transparent border-0 text-gray-600
|
|
181
|
-
hover:text-red-500 cursor-pointer"
|
|
182
|
-
>
|
|
183
|
-
✕
|
|
184
|
-
</button>
|
|
185
|
-
</span>
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
</div>
|
|
189
|
-
|
|
190
|
-
<!-- Trigger -->
|
|
191
|
-
<hlm-popover>
|
|
192
|
-
<button hlmPopoverTrigger hlmButton variant="secondary" appearance="outline" type="button">
|
|
193
|
-
{{ selectedItems().length }} selected
|
|
194
|
-
</button>
|
|
195
|
-
|
|
196
|
-
<hlm-popover-content class="w-64 p-2">
|
|
197
|
-
<div class="max-h-60 overflow-auto flex flex-col gap-1">
|
|
198
|
-
@for (option of options(); track option.value) {
|
|
199
|
-
<label
|
|
200
|
-
class="flex items-center gap-2 cursor-pointer px-2 py-1 rounded-sm hover:bg-secondary"
|
|
201
|
-
>
|
|
202
|
-
<hlm-checkbox [checked]="isSelected(option.value)" (changed)="toggle(option.value, $event)" />
|
|
203
|
-
<span class="text-sm">{{ option.label }}</span>
|
|
204
|
-
</label>
|
|
205
|
-
} @empty {
|
|
206
|
-
<span class="text-xs text-muted-foreground px-2 py-1">No options</span>
|
|
207
|
-
}
|
|
208
|
-
</div>
|
|
209
|
-
</hlm-popover-content>
|
|
210
|
-
</hlm-popover>
|
|
211
|
-
</div>
|
|
212
|
-
`,
|
|
123
|
+
template: "\n <div class=\"flex flex-col gap-2 w-full\">\n <!-- Selected chips -->\n <div class=\"flex flex-wrap gap-2\">\n @if (selectedItems().length === 0) {\n <span\n class=\"bg-gray-100 text-gray-400 rounded-full\n px-2 py-1 inline-flex items-center text-xs\"\n >\n {{ placeholder() }}\n </span>\n } @else {\n @for (item of selectedItems(); track item.value) {\n <span\n class=\"bg-gray-200 rounded-full px-2 py-1\n inline-flex items-center gap-2 text-xs\"\n >\n {{ item.label }}\n <button\n type=\"button\"\n [disabled]=\"disabledState()\"\n (click)=\"removeItem(item.value)\"\n class=\"bg-transparent border-0 text-gray-600\n hover:text-red-500 cursor-pointer\"\n >\n ✕\n </button>\n </span>\n }\n }\n </div>\n\n <!-- Trigger -->\n <hlm-popover>\n <button\n hlmPopoverTrigger\n hlmButton\n variant=\"secondary\"\n appearance=\"outline\"\n type=\"button\"\n [id]=\"id()\"\n [disabled]=\"disabledState()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-describedby]=\"ariaDescribedby()\"\n >\n {{ selectedItems().length }} selected\n </button>\n\n <hlm-popover-content class=\"w-64 p-2\" *hlmPopoverPortal=\"let ctx\">\n <div class=\"max-h-60 overflow-auto flex flex-col gap-1\">\n @for (option of options(); track option.value) {\n <label\n class=\"flex items-center gap-2 cursor-pointer px-2 py-1 rounded-sm hover:bg-secondary\"\n >\n <hlm-checkbox\n [checked]=\"isSelected(option.value)\"\n [disabled]=\"disabledState()\"\n (changed)=\"toggle(option.value, $event)\"\n />\n <span class=\"text-sm\">{{ option.label }}</span>\n </label>\n } @empty {\n <span class=\"text-xs text-muted-foreground px-2 py-1\">No options</span>\n }\n </div>\n </hlm-popover-content>\n </hlm-popover>\n </div>\n ",
|
|
213
124
|
}]
|
|
214
|
-
}], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
125
|
+
}], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], wrapperDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrapperDisabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], ariaDescribedby: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaDescribedby", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }] } });
|
|
215
126
|
|
|
216
127
|
/*
|
|
217
128
|
* Public API Surface of searchable-multiselect
|
|
@@ -222,4 +133,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
222
133
|
*/
|
|
223
134
|
|
|
224
135
|
export { EgSearchableMultiselect };
|
|
225
|
-
|
|
136
|
+
|
|
@@ -10,12 +10,18 @@ declare class EgSearchableMultiselect implements ControlValueAccessor {
|
|
|
10
10
|
/** Full option list with labels/values */
|
|
11
11
|
options: _angular_core.InputSignal<SelectOption[]>;
|
|
12
12
|
placeholder: _angular_core.InputSignal<string>;
|
|
13
|
+
id: _angular_core.InputSignal<string>;
|
|
14
|
+
disabled: _angular_core.InputSignal<boolean>;
|
|
15
|
+
wrapperDisabled: _angular_core.InputSignal<boolean>;
|
|
16
|
+
ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
17
|
+
ariaDescribedby: _angular_core.InputSignal<string | null>;
|
|
13
18
|
userClass: _angular_core.InputSignal<ClassValue>;
|
|
14
19
|
/** Value: array of selected values (string[]) */
|
|
15
20
|
value: _angular_core.InputSignal<string[]>;
|
|
16
21
|
valueChange: _angular_core.OutputEmitterRef<string[]>;
|
|
17
22
|
protected readonly selectedItems: _angular_core.WritableSignal<SelectOption[]>;
|
|
18
|
-
protected
|
|
23
|
+
protected readonly formDisabled: _angular_core.WritableSignal<boolean>;
|
|
24
|
+
protected readonly disabledState: _angular_core.Signal<boolean>;
|
|
19
25
|
private isFormBound;
|
|
20
26
|
protected readonly _hostClass: _angular_core.Signal<string>;
|
|
21
27
|
protected isSelected(value: string): boolean;
|
|
@@ -32,7 +38,7 @@ declare class EgSearchableMultiselect implements ControlValueAccessor {
|
|
|
32
38
|
registerOnTouched(fn: () => void): void;
|
|
33
39
|
setDisabledState(isDisabled: boolean): void;
|
|
34
40
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<EgSearchableMultiselect, never>;
|
|
35
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EgSearchableMultiselect, "eg-searchable-multiselect", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
41
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<EgSearchableMultiselect, "eg-searchable-multiselect", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "wrapperDisabled": { "alias": "wrapperDisabled"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaDescribedby": { "alias": "ariaDescribedby"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
36
42
|
}
|
|
37
43
|
|
|
38
44
|
export { EgSearchableMultiselect };
|
package/select/README.md
CHANGED
|
@@ -1,64 +1,3 @@
|
|
|
1
|
-
# Select
|
|
1
|
+
# Select Subpath
|
|
2
2
|
|
|
3
|
-
This project
|
|
4
|
-
|
|
5
|
-
## Code scaffolding
|
|
6
|
-
|
|
7
|
-
Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
ng generate component component-name
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
ng generate --help
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## Building
|
|
20
|
-
|
|
21
|
-
To build the library, run:
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
ng build select
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
|
|
28
|
-
|
|
29
|
-
### Publishing the Library
|
|
30
|
-
|
|
31
|
-
Once the project is built, you can publish your library by following these steps:
|
|
32
|
-
|
|
33
|
-
1. Navigate to the `dist` directory:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
cd dist/select
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
2. Run the `npm publish` command to publish your library to the npm registry:
|
|
40
|
-
```bash
|
|
41
|
-
npm publish
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Running unit tests
|
|
45
|
-
|
|
46
|
-
To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
ng test
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Running end-to-end tests
|
|
53
|
-
|
|
54
|
-
For end-to-end (e2e) testing, run:
|
|
55
|
-
|
|
56
|
-
```bash
|
|
57
|
-
ng e2e
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
|
|
61
|
-
|
|
62
|
-
## Additional Resources
|
|
63
|
-
|
|
64
|
-
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
|
3
|
+
This project ships only as `@egose/shadcn-theme-ng/select` or `@egose/shadcn-theme-ng-tw/select`. See the [package README](../../README.md) for installation, compatibility, Tailwind variant, test, and release guidance. Do not publish this project directory independently.
|