ngx-com 0.1.14 → 0.1.16

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 CHANGED
@@ -64,12 +64,19 @@ Or import individual files for finer control:
64
64
  | `animations.css` | Keyframe animations used by components |
65
65
  | `utilities.css` | Utility classes |
66
66
 
67
- Switch themes at runtime by setting `data-theme` on the `<html>` element:
67
+ Switch themes at runtime by setting `data-theme` on the `<html>` element.
68
+ The library provides a theme service that handles this automatically:
68
69
 
69
- ```html
70
- <html data-theme="dark">
70
+ ```typescript
71
+ import { provideComTheme } from 'ngx-com/theme';
72
+
73
+ export const appConfig: ApplicationConfig = {
74
+ providers: [provideComTheme()],
75
+ };
71
76
  ```
72
77
 
78
+ See the [Theme service](#theme-service) section for details.
79
+
73
80
  ### 2. Add Tailwind source for ngx-com
74
81
 
75
82
  Library components use Tailwind utility classes in their templates. Tell
@@ -164,6 +171,41 @@ import { ComDropdown, ComDropdownOption } from 'ngx-com/components/dropdown';
164
171
  | Toast | `ngx-com/components/toast` | Toast notification service |
165
172
  | Tooltip | `ngx-com/components/tooltip` | Hover/focus tooltip |
166
173
 
174
+ ## Services
175
+
176
+ ### Theme service
177
+
178
+ Import path: `ngx-com/theme`
179
+
180
+ SSR-safe theme management with localStorage persistence and system
181
+ `prefers-color-scheme` detection. Applies the active theme via a `data-theme`
182
+ attribute on the document element.
183
+
184
+ ```typescript
185
+ import { provideComTheme, ComTheme } from 'ngx-com/theme';
186
+
187
+ // 1. Configure in app providers (zero-config works out of the box)
188
+ providers: [provideComTheme()]
189
+
190
+ // 2. Inject and use
191
+ readonly theme = inject(ComTheme);
192
+ this.theme.setTheme('dark'); // explicit override, persisted to localStorage
193
+ this.theme.clearPreference(); // revert to following system preference
194
+ this.theme.theme(); // current theme (Signal<string>)
195
+ this.theme.isAutomatic(); // true when following system preference
196
+ ```
197
+
198
+ Configuration options:
199
+
200
+ | Option | Type | Default | Description |
201
+ | --- | --- | --- | --- |
202
+ | `defaultTheme` | `string` | `'light'` | Fallback when no stored/system preference |
203
+ | `storageKey` | `string \| null` | `'com-theme'` | localStorage key (`null` to disable) |
204
+ | `darkSchemeTheme` | `string \| null` | `'dark'` | Theme for `prefers-color-scheme: dark` (`null` to disable) |
205
+ | `lightSchemeTheme` | `string` | `defaultTheme` | Theme for light system preference |
206
+ | `followSystemPreference` | `boolean` | `true` | Watch for live system preference changes |
207
+ | `attribute` | `string` | `'data-theme'` | HTML attribute applied to `documentElement` |
208
+
167
209
  ## Utilities
168
210
 
169
211
  General-purpose utilities are available from `ngx-com/utils`.
@@ -255,6 +255,8 @@ const dropdownTagVariants = cva([
255
255
  'font-medium',
256
256
  'transition-colors',
257
257
  'duration-fast',
258
+ 'max-w-full',
259
+ 'overflow-hidden',
258
260
  ], {
259
261
  variants: {
260
262
  size: {
@@ -321,6 +323,7 @@ const dropdownOverflowBadgeVariants = cva([
321
323
  'font-medium',
322
324
  'text-muted-foreground',
323
325
  'bg-muted',
326
+ 'shrink-0',
324
327
  ], {
325
328
  variants: {
326
329
  size: {
@@ -946,7 +949,7 @@ class ComDropdownTag {
946
949
  this.remove.emit(this.value());
947
950
  }
948
951
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: ComDropdownTag, deps: [], target: i0.ɵɵFactoryTarget.Component });
949
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: ComDropdownTag, isStandalone: true, selector: "com-dropdown-tag", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, displayText: { classPropertyName: "displayText", publicName: "displayText", isSignal: true, isRequired: false, transformFunction: null }, index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, tagTemplate: { classPropertyName: "tagTemplate", publicName: "tagTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { remove: "remove" }, host: { classAttribute: "com-dropdown-tag-host inline-flex max-w-full min-w-0" }, exportAs: ["comDropdownTag"], ngImport: i0, template: `
952
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: ComDropdownTag, isStandalone: true, selector: "com-dropdown-tag", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, displayText: { classPropertyName: "displayText", publicName: "displayText", isSignal: true, isRequired: false, transformFunction: null }, index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, tagTemplate: { classPropertyName: "tagTemplate", publicName: "tagTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { remove: "remove" }, host: { classAttribute: "com-dropdown-tag-host inline-flex min-w-0 max-w-[8rem]" }, exportAs: ["comDropdownTag"], ngImport: i0, template: `
950
953
  @if (tagTemplate()) {
951
954
  <ng-container
952
955
  [ngTemplateOutlet]="tagTemplate()!"
@@ -1025,7 +1028,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
1025
1028
  imports: [NgTemplateOutlet],
1026
1029
  changeDetection: ChangeDetectionStrategy.OnPush,
1027
1030
  host: {
1028
- class: 'com-dropdown-tag-host inline-flex max-w-full min-w-0',
1031
+ class: 'com-dropdown-tag-host inline-flex min-w-0 max-w-[8rem]',
1029
1032
  },
1030
1033
  }]
1031
1034
  }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], displayText: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayText", required: false }] }], index: [{ type: i0.Input, args: [{ isSignal: true, alias: "index", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], tagTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "tagTemplate", required: false }] }], remove: [{ type: i0.Output, args: ["remove"] }] } });
@@ -2294,7 +2297,7 @@ class ComDropdown {
2294
2297
  (blur)="onTriggerBlur()"
2295
2298
  >
2296
2299
  <!-- Selected value display -->
2297
- <span class="flex-1 min-w-0 truncate text-left">
2300
+ <span class="flex-1 min-w-0 text-left" [class.truncate]="!multiple()">
2298
2301
  @if (selectedTemplate()) {
2299
2302
  <ng-container
2300
2303
  [ngTemplateOutlet]="selectedTemplate()!.templateRef"
@@ -2302,7 +2305,7 @@ class ComDropdown {
2302
2305
  />
2303
2306
  } @else if (multiple()) {
2304
2307
  @if (selectedValues().length > 0) {
2305
- <span class="flex items-center gap-1 min-w-0 overflow-hidden">
2308
+ <span class="flex items-center gap-1.5 min-w-0 overflow-hidden">
2306
2309
  @for (item of visibleTags(); track trackByValue(item, $index); let i = $index) {
2307
2310
  <com-dropdown-tag
2308
2311
  [value]="item"
@@ -2549,7 +2552,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
2549
2552
  (blur)="onTriggerBlur()"
2550
2553
  >
2551
2554
  <!-- Selected value display -->
2552
- <span class="flex-1 min-w-0 truncate text-left">
2555
+ <span class="flex-1 min-w-0 text-left" [class.truncate]="!multiple()">
2553
2556
  @if (selectedTemplate()) {
2554
2557
  <ng-container
2555
2558
  [ngTemplateOutlet]="selectedTemplate()!.templateRef"
@@ -2557,7 +2560,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
2557
2560
  />
2558
2561
  } @else if (multiple()) {
2559
2562
  @if (selectedValues().length > 0) {
2560
- <span class="flex items-center gap-1 min-w-0 overflow-hidden">
2563
+ <span class="flex items-center gap-1.5 min-w-0 overflow-hidden">
2561
2564
  @for (item of visibleTags(); track trackByValue(item, $index); let i = $index) {
2562
2565
  <com-dropdown-tag
2563
2566
  [value]="item"