ngx-com 0.0.1 → 0.0.3
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/fesm2022/ngx-com-components-badge.mjs +138 -0
- package/fesm2022/ngx-com-components-badge.mjs.map +1 -0
- package/fesm2022/ngx-com-components-button.mjs +146 -0
- package/fesm2022/ngx-com-components-button.mjs.map +1 -0
- package/fesm2022/ngx-com-components-calendar.mjs +5046 -0
- package/fesm2022/ngx-com-components-calendar.mjs.map +1 -0
- package/fesm2022/ngx-com-components-card.mjs +590 -0
- package/fesm2022/ngx-com-components-card.mjs.map +1 -0
- package/fesm2022/ngx-com-components-checkbox.mjs +344 -0
- package/fesm2022/ngx-com-components-checkbox.mjs.map +1 -0
- package/fesm2022/ngx-com-components-collapsible.mjs +612 -0
- package/fesm2022/ngx-com-components-collapsible.mjs.map +1 -0
- package/fesm2022/ngx-com-components-dropdown-testing.mjs +255 -0
- package/fesm2022/ngx-com-components-dropdown-testing.mjs.map +1 -0
- package/fesm2022/ngx-com-components-dropdown.mjs +2598 -0
- package/fesm2022/ngx-com-components-dropdown.mjs.map +1 -0
- package/fesm2022/ngx-com-components-form-field.mjs +923 -0
- package/fesm2022/ngx-com-components-form-field.mjs.map +1 -0
- package/fesm2022/ngx-com-components-icon.mjs +183 -0
- package/fesm2022/ngx-com-components-icon.mjs.map +1 -0
- package/fesm2022/ngx-com-components-menu.mjs +1200 -0
- package/fesm2022/ngx-com-components-menu.mjs.map +1 -0
- package/fesm2022/ngx-com-components-popover.mjs +901 -0
- package/fesm2022/ngx-com-components-popover.mjs.map +1 -0
- package/fesm2022/ngx-com-components-radio.mjs +621 -0
- package/fesm2022/ngx-com-components-radio.mjs.map +1 -0
- package/fesm2022/ngx-com-components-sort.mjs +368 -0
- package/fesm2022/ngx-com-components-sort.mjs.map +1 -0
- package/fesm2022/ngx-com-components-tabs.mjs +1522 -0
- package/fesm2022/ngx-com-components-tabs.mjs.map +1 -0
- package/fesm2022/ngx-com-components.mjs +17 -0
- package/fesm2022/ngx-com-components.mjs.map +1 -0
- package/fesm2022/ngx-com-tokens.mjs +12 -0
- package/fesm2022/ngx-com-tokens.mjs.map +1 -0
- package/fesm2022/ngx-com-utils.mjs +601 -0
- package/fesm2022/ngx-com-utils.mjs.map +1 -0
- package/fesm2022/ngx-com.mjs +9 -23
- package/fesm2022/ngx-com.mjs.map +1 -1
- package/package.json +73 -1
- package/types/ngx-com-components-badge.d.ts +97 -0
- package/types/ngx-com-components-button.d.ts +69 -0
- package/types/ngx-com-components-calendar.d.ts +1665 -0
- package/types/ngx-com-components-card.d.ts +373 -0
- package/types/ngx-com-components-checkbox.d.ts +116 -0
- package/types/ngx-com-components-collapsible.d.ts +379 -0
- package/types/ngx-com-components-dropdown-testing.d.ts +116 -0
- package/types/ngx-com-components-dropdown.d.ts +914 -0
- package/types/ngx-com-components-form-field.d.ts +531 -0
- package/types/ngx-com-components-icon.d.ts +94 -0
- package/types/ngx-com-components-menu.d.ts +479 -0
- package/types/ngx-com-components-popover.d.ts +309 -0
- package/types/ngx-com-components-radio.d.ts +258 -0
- package/types/ngx-com-components-sort.d.ts +133 -0
- package/types/ngx-com-components-tabs.d.ts +396 -0
- package/types/ngx-com-components.d.ts +12 -0
- package/types/ngx-com-tokens.d.ts +7 -0
- package/types/ngx-com-utils.d.ts +424 -0
- package/types/ngx-com.d.ts +10 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngx-com-components-radio.mjs","sources":["../../../projects/com/components/radio/radio.variants.ts","../../../projects/com/components/radio/radio.utils.ts","../../../projects/com/components/radio/radio-group.component.ts","../../../projects/com/components/radio/radio.component.ts","../../../projects/com/components/radio/index.ts","../../../projects/com/components/radio/ngx-com-components-radio.ts"],"sourcesContent":["import { cva } from 'class-variance-authority';\n\n/** Radio size variants. */\nexport type RadioSize = 'sm' | 'md' | 'lg';\n\n/** Radio color variants. */\nexport type RadioVariant = 'primary' | 'accent' | 'warn';\n\n/** Radio group orientation. */\nexport type RadioOrientation = 'vertical' | 'horizontal';\n\n/**\n * CVA variants for the visual radio circle.\n *\n * Uses `peer` selectors to style based on native input state:\n * - `peer-checked:` for checked state\n * - `peer-focus-visible:` for keyboard focus\n * - `peer-disabled:` for disabled state\n *\n * @tokens `--color-border`, `--color-primary`, `--color-primary-hover`,\n * `--color-accent`, `--color-accent-hover`,\n * `--color-warn`, `--color-warn-hover`,\n * `--color-disabled`, `--color-ring`\n */\nexport const radioCircleVariants: (props?: {\n variant?: RadioVariant;\n size?: RadioSize;\n}) => string = cva(\n [\n 'com-radio__circle',\n 'inline-flex shrink-0 items-center justify-center',\n 'rounded-full border-2 border-border',\n 'transition-colors duration-150',\n 'peer-focus-visible:outline-2 peer-focus-visible:outline-offset-2 peer-focus-visible:outline-ring',\n 'peer-disabled:cursor-not-allowed peer-disabled:border-disabled peer-disabled:bg-disabled',\n ],\n {\n variants: {\n variant: {\n primary: [\n 'peer-checked:border-primary peer-checked:bg-primary peer-checked:text-primary-foreground',\n 'group-hover:border-primary-hover',\n 'peer-checked:group-hover:bg-primary-hover peer-checked:group-hover:border-primary-hover',\n ],\n accent: [\n 'peer-checked:border-accent peer-checked:bg-accent peer-checked:text-accent-foreground',\n 'group-hover:border-accent-hover',\n 'peer-checked:group-hover:bg-accent-hover peer-checked:group-hover:border-accent-hover',\n ],\n warn: [\n 'peer-checked:border-warn peer-checked:bg-warn peer-checked:text-warn-foreground',\n 'group-hover:border-warn-hover',\n 'peer-checked:group-hover:bg-warn-hover peer-checked:group-hover:border-warn-hover',\n ],\n },\n size: {\n sm: 'size-4',\n md: 'size-5',\n lg: 'size-6',\n },\n },\n defaultVariants: {\n variant: 'primary',\n size: 'md',\n },\n }\n);\n\n/** Size-based classes for the inner dot indicator. */\nexport const RADIO_DOT_SIZES: Record<RadioSize, string> = {\n sm: 'size-1.5',\n md: 'size-2',\n lg: 'size-2.5',\n};\n\n/** Size-based classes for the label content. */\nexport const RADIO_LABEL_SIZES: Record<RadioSize, string> = {\n sm: 'text-sm ms-2',\n md: 'text-base ms-2.5',\n lg: 'text-lg ms-3',\n};\n\n/** Base classes for the radio group container. */\nconst RADIO_GROUP_BASE = 'com-radio-group__container flex';\n\n/** Orientation-based classes for the radio group container. */\nexport const RADIO_GROUP_ORIENTATIONS: Record<RadioOrientation, string> = {\n vertical: `${RADIO_GROUP_BASE} flex-col gap-2`,\n horizontal: `${RADIO_GROUP_BASE} flex-row flex-wrap gap-4`,\n};\n","/** Auto-incrementing ID counter for unique radio IDs. */\nlet nextRadioId = 0;\n\n/** Generates a unique radio ID. */\nexport function generateRadioId(): string {\n return `com-radio-${nextRadioId++}`;\n}\n\n/** Auto-incrementing ID counter for unique radio group IDs. */\nlet nextGroupId = 0;\n\n/** Generates a unique radio group ID. */\nexport function generateRadioGroupId(): string {\n return `com-radio-group-${nextGroupId++}`;\n}\n","import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n InjectionToken,\n input,\n linkedSignal,\n model,\n output,\n signal,\n ViewEncapsulation,\n} from '@angular/core';\nimport type {\n InputSignal,\n InputSignalWithTransform,\n ModelSignal,\n OutputEmitterRef,\n Signal,\n WritableSignal,\n} from '@angular/core';\nimport { FormGroupDirective, NgControl, NgForm } from '@angular/forms';\nimport type { ControlValueAccessor } from '@angular/forms';\nimport { ErrorStateMatcher } from 'ngx-com/components/form-field';\nimport { RADIO_GROUP_ORIENTATIONS } from './radio.variants';\nimport type { RadioOrientation, RadioSize, RadioVariant } from './radio.variants';\nimport { generateRadioGroupId } from './radio.utils';\n\n/** Event emitted when radio group value changes. */\nexport interface RadioGroupChange {\n value: string | null;\n}\n\n/** Interface for radio items that register with the group. */\nexport interface RadioItem {\n value: () => string;\n isDisabled: () => boolean;\n focus: () => void;\n}\n\n/** Context provided to child radio components via DI. */\nexport interface ComRadioGroupContext {\n name: Signal<string>;\n value: Signal<string | null>;\n disabled: Signal<boolean>;\n size: Signal<RadioSize>;\n variant: Signal<RadioVariant>;\n orientation: Signal<RadioOrientation>;\n focusedValue: Signal<string | null>;\n select: (value: string) => void;\n focusNext: (currentValue: string) => void;\n focusPrevious: (currentValue: string) => void;\n register: (radio: RadioItem) => void;\n unregister: (radio: RadioItem) => void;\n onTouched?: () => void;\n}\n\n/** Injection token for radio group context. */\nexport const COM_RADIO_GROUP: InjectionToken<ComRadioGroupContext> = new InjectionToken<ComRadioGroupContext>('COM_RADIO_GROUP');\n\n/**\n * Radio group component that manages a set of radio buttons.\n *\n * Provides mutual exclusion, shared name, and roving tabindex keyboard navigation.\n * Implements `ControlValueAccessor` for Reactive Forms integration.\n *\n * @tokens `--color-border`, `--color-primary`, `--color-primary-foreground`, `--color-primary-hover`,\n * `--color-accent`, `--color-accent-foreground`, `--color-accent-hover`,\n * `--color-warn`, `--color-warn-foreground`, `--color-warn-hover`,\n * `--color-disabled`, `--color-disabled-foreground`, `--color-ring`\n *\n * @example Basic usage\n * ```html\n * <com-radio-group [(value)]=\"selectedFruit\" aria-label=\"Select a fruit\">\n * <com-radio value=\"apple\">Apple</com-radio>\n * <com-radio value=\"banana\">Banana</com-radio>\n * <com-radio value=\"cherry\">Cherry</com-radio>\n * </com-radio-group>\n * ```\n *\n * @example With reactive forms\n * ```html\n * <com-radio-group formControlName=\"size\" aria-label=\"Select size\">\n * <com-radio value=\"sm\">Small</com-radio>\n * <com-radio value=\"md\">Medium</com-radio>\n * <com-radio value=\"lg\">Large</com-radio>\n * </com-radio-group>\n * ```\n *\n * @example Horizontal orientation\n * ```html\n * <com-radio-group [(value)]=\"color\" orientation=\"horizontal\">\n * <com-radio value=\"red\">Red</com-radio>\n * <com-radio value=\"green\">Green</com-radio>\n * <com-radio value=\"blue\">Blue</com-radio>\n * </com-radio-group>\n * ```\n *\n * @example With variants\n * ```html\n * <com-radio-group [(value)]=\"priority\" variant=\"warn\" size=\"lg\">\n * <com-radio value=\"low\">Low</com-radio>\n * <com-radio value=\"medium\">Medium</com-radio>\n * <com-radio value=\"high\">High</com-radio>\n * </com-radio-group>\n * ```\n */\n@Component({\n selector: 'com-radio-group',\n exportAs: 'comRadioGroup',\n template: `\n <div\n role=\"radiogroup\"\n [class]=\"groupClasses()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n [attr.aria-describedby]=\"computedAriaDescribedby()\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"errorState() || null\"\n >\n <ng-content />\n </div>\n @if (errorState() && errorMessage()) {\n <div\n [id]=\"errorId\"\n class=\"com-radio-group__error mt-1.5 text-sm text-warn\"\n role=\"alert\"\n >\n {{ errorMessage() }}\n </div>\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n providers: [\n {\n provide: COM_RADIO_GROUP,\n useFactory: () => {\n const group = inject(ComRadioGroup);\n return group.createContext();\n },\n },\n ],\n host: {\n class: 'com-radio-group block',\n '[class.com-radio-group--disabled]': 'disabled()',\n '[class.com-radio-group--error]': 'errorState()',\n },\n})\nexport class ComRadioGroup implements ControlValueAccessor {\n /** Optional NgControl for reactive forms integration. */\n readonly ngControl: NgControl | null = inject(NgControl, { optional: true, self: true });\n\n /** Error state matcher for determining when to show validation errors. */\n private readonly defaultErrorStateMatcher: ErrorStateMatcher = inject(ErrorStateMatcher);\n private readonly parentForm: NgForm | null = inject(NgForm, { optional: true });\n private readonly parentFormGroup: FormGroupDirective | null = inject(FormGroupDirective, { optional: true });\n\n /** Unique ID for this radio group instance. */\n private readonly uniqueId: string = generateRadioGroupId();\n\n /** ID for the error message element. */\n readonly errorId: string = `${this.uniqueId}-error`;\n\n /** Registered radio items. */\n private readonly registeredRadios: WritableSignal<RadioItem[]> = signal([]);\n\n // Inputs\n readonly name: InputSignal<string> = input<string>(this.uniqueId);\n readonly value: ModelSignal<string | null> = model<string | null>(null);\n readonly disabled: ModelSignal<boolean> = model<boolean>(false);\n readonly required: InputSignalWithTransform<boolean, unknown> = input(false, {\n transform: booleanAttribute,\n });\n readonly orientation: InputSignal<RadioOrientation> = input<RadioOrientation>('vertical');\n readonly size: InputSignal<RadioSize> = input<RadioSize>('md');\n readonly variant: InputSignal<RadioVariant> = input<RadioVariant>('primary');\n readonly errorMessage: InputSignal<string> = input<string>('');\n readonly errorStateMatcher: InputSignal<ErrorStateMatcher | undefined> = input<ErrorStateMatcher>();\n\n /** Internal signal to track when control is touched, used to trigger error state re-evaluation. */\n private readonly _touched: WritableSignal<boolean> = signal(false);\n readonly ariaLabel: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-label' });\n readonly ariaLabelledby: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-labelledby' });\n readonly ariaDescribedby: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-describedby' });\n\n // Outputs\n /** Emits when the selection changes, with full event details. */\n readonly selectionChange: OutputEmitterRef<RadioGroupChange> = output<RadioGroupChange>();\n\n /**\n * Tracks the currently focused radio value for roving tabindex.\n * Resets to the current selection (or first focusable) when value or radios change.\n */\n private readonly focusedValueSignal: WritableSignal<string | null> = linkedSignal({\n source: () => ({ value: this.value(), radios: this.registeredRadios() }),\n computation: ({ value, radios }) => {\n if (value && radios.some((r) => r.value() === value && !r.isDisabled())) {\n return value;\n }\n const firstFocusable = radios.find((r) => !r.isDisabled());\n return firstFocusable?.value() ?? null;\n },\n });\n\n // Computed\n /**\n * Computed error state derived from form validation.\n * Shows errors when control is invalid and touched/submitted.\n */\n readonly errorState: Signal<boolean> = computed(() => {\n // Read _touched to trigger re-evaluation when touched changes\n this._touched();\n const matcher = this.errorStateMatcher() ?? this.defaultErrorStateMatcher;\n const form = this.parentFormGroup ?? this.parentForm;\n return matcher.isErrorState(this.ngControl?.control ?? null, form);\n });\n\n readonly computedAriaDescribedby: Signal<string | null> = computed(() => {\n const userDescribedby = this.ariaDescribedby();\n if (this.errorState() && this.errorMessage()) {\n return userDescribedby ? `${userDescribedby} ${this.errorId}` : this.errorId;\n }\n return userDescribedby;\n });\n\n protected readonly groupClasses: Signal<string> = computed(() =>\n RADIO_GROUP_ORIENTATIONS[this.orientation()]\n );\n\n // CVA callbacks\n private onChange: (value: string | null) => void = () => {};\n private onTouchedCallback: () => void = () => {};\n\n constructor() {\n if (this.ngControl) {\n this.ngControl.valueAccessor = this;\n }\n }\n\n /** Creates the context object for child radios. */\n createContext(): ComRadioGroupContext {\n return {\n name: this.name,\n value: this.value,\n disabled: this.disabled,\n size: this.size,\n variant: this.variant,\n orientation: this.orientation,\n focusedValue: this.focusedValueSignal,\n select: this.select.bind(this),\n focusNext: this.focusNext.bind(this),\n focusPrevious: this.focusPrevious.bind(this),\n register: this.register.bind(this),\n unregister: this.unregister.bind(this),\n onTouched: () => this.onTouchedCallback(),\n };\n }\n\n /** Register a radio item with the group. */\n private register(radio: RadioItem): void {\n this.registeredRadios.update((radios) => [...radios, radio]);\n }\n\n /** Unregister a radio item from the group. */\n private unregister(radio: RadioItem): void {\n this.registeredRadios.update((radios) => radios.filter((r) => r !== radio));\n }\n\n // ControlValueAccessor implementation\n writeValue(value: string | null): void {\n this.value.set(value);\n }\n\n registerOnChange(fn: (value: string | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouchedCallback = () => {\n this._touched.set(true);\n fn();\n };\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.disabled.set(isDisabled);\n }\n\n // Public API\n /** Selects a radio by value. */\n select(newValue: string): void {\n if (this.disabled()) {\n return;\n }\n this.value.set(newValue);\n this.focusedValueSignal.set(newValue);\n this.onChange(newValue);\n this.selectionChange.emit({ value: newValue });\n }\n\n /** Focuses the next non-disabled radio (with cyclic wrap). */\n focusNext(currentValue: string): void {\n const allRadios = this.registeredRadios();\n const focusableRadios = allRadios.filter((r) => !r.isDisabled());\n\n if (focusableRadios.length === 0) {\n return;\n }\n\n const currentIndex = focusableRadios.findIndex((r) => r.value() === currentValue);\n const nextIndex = (currentIndex + 1) % focusableRadios.length;\n const nextRadio = focusableRadios[nextIndex];\n\n if (nextRadio) {\n this.focusedValueSignal.set(nextRadio.value());\n this.select(nextRadio.value());\n nextRadio.focus();\n }\n }\n\n /** Focuses the previous non-disabled radio (with cyclic wrap). */\n focusPrevious(currentValue: string): void {\n const allRadios = this.registeredRadios();\n const focusableRadios = allRadios.filter((r) => !r.isDisabled());\n\n if (focusableRadios.length === 0) {\n return;\n }\n\n const currentIndex = focusableRadios.findIndex((r) => r.value() === currentValue);\n const prevIndex = (currentIndex - 1 + focusableRadios.length) % focusableRadios.length;\n const prevRadio = focusableRadios[prevIndex];\n\n if (prevRadio) {\n this.focusedValueSignal.set(prevRadio.value());\n this.select(prevRadio.value());\n prevRadio.focus();\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n inject,\n input,\n model,\n output,\n viewChild,\n ViewEncapsulation,\n} from '@angular/core';\nimport type {\n InputSignal,\n ModelSignal,\n OnInit,\n OutputEmitterRef,\n Signal,\n} from '@angular/core';\nimport {\n radioCircleVariants,\n RADIO_DOT_SIZES,\n RADIO_LABEL_SIZES,\n} from './radio.variants';\nimport type { RadioSize, RadioVariant } from './radio.variants';\nimport { generateRadioId } from './radio.utils';\nimport { COM_RADIO_GROUP, type ComRadioGroupContext, type RadioItem } from './radio-group.component';\n\n/** Event emitted when a radio is selected. */\nexport interface RadioChange {\n value: string;\n source: ComRadio;\n}\n\n/**\n * Production-grade radio component with full accessibility support.\n *\n * Uses a native `<input type=\"radio\">` for built-in keyboard handling,\n * `:checked` pseudo-class, and screen reader support.\n *\n * Must be used within a `ComRadioGroup` which manages the selected value\n * and provides the shared `name` attribute.\n *\n * @tokens `--color-border`, `--color-primary`, `--color-primary-foreground`, `--color-primary-hover`,\n * `--color-accent`, `--color-accent-foreground`, `--color-accent-hover`,\n * `--color-warn`, `--color-warn-foreground`, `--color-warn-hover`,\n * `--color-disabled`, `--color-disabled-foreground`, `--color-ring`\n *\n * @example Basic usage within a group\n * ```html\n * <com-radio-group [(value)]=\"selectedOption\">\n * <com-radio value=\"option1\">Option 1</com-radio>\n * <com-radio value=\"option2\">Option 2</com-radio>\n * <com-radio value=\"option3\">Option 3</com-radio>\n * </com-radio-group>\n * ```\n *\n * @example Disabled option\n * ```html\n * <com-radio-group [(value)]=\"selected\">\n * <com-radio value=\"enabled\">Enabled option</com-radio>\n * <com-radio value=\"disabled\" [disabled]=\"true\">Disabled option</com-radio>\n * </com-radio-group>\n * ```\n */\n@Component({\n selector: 'com-radio',\n exportAs: 'comRadio',\n template: `\n <label\n class=\"group relative inline-flex items-center\"\n [class.cursor-pointer]=\"!isDisabled()\"\n [class.cursor-not-allowed]=\"isDisabled()\"\n >\n <span><input\n #inputElement\n type=\"radio\"\n class=\"peer sr-only\"\n [id]=\"inputId()\"\n [checked]=\"isChecked()\"\n [disabled]=\"isDisabled()\"\n [attr.name]=\"groupName()\"\n [attr.value]=\"value()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-labelledby]=\"ariaLabelledby()\"\n [attr.aria-describedby]=\"ariaDescribedby()\"\n [attr.tabindex]=\"tabIndex()\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n (keydown)=\"onKeyDown($event)\"\n /></span>\n <div [class]=\"circleClasses()\">\n <div\n class=\"com-radio__dot rounded-full bg-current transition-transform duration-150 peer-disabled:bg-disabled-foreground\"\n [class]=\"dotSizeClass()\"\n [class.scale-100]=\"isChecked()\"\n [class.scale-0]=\"!isChecked()\"\n ></div>\n </div>\n <span\n class=\"com-radio__label select-none peer-disabled:cursor-not-allowed peer-disabled:text-disabled-foreground\"\n [class]=\"labelSizeClass()\"\n >\n <ng-content />\n </span>\n </label>\n `,\n styles: `\n .sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n host: {\n class: 'com-radio inline-block align-middle',\n '[class.com-radio--disabled]': 'isDisabled()',\n '[class.com-radio--checked]': 'isChecked()',\n },\n})\nexport class ComRadio implements OnInit, RadioItem {\n /** Optional parent radio group context. */\n private readonly group: ComRadioGroupContext | null = inject(COM_RADIO_GROUP, {\n optional: true,\n });\n\n /** DestroyRef for cleanup. */\n private readonly destroyRef: DestroyRef = inject(DestroyRef);\n\n /** Reference to the native input element. */\n readonly inputRef: Signal<ElementRef<HTMLInputElement> | undefined> =\n viewChild<ElementRef<HTMLInputElement>>('inputElement');\n\n /** Unique ID for this radio instance. */\n private readonly uniqueId: string = generateRadioId();\n\n // Inputs\n readonly value: InputSignal<string> = input.required<string>();\n readonly size: InputSignal<RadioSize> = input<RadioSize>('md');\n readonly variant: InputSignal<RadioVariant> = input<RadioVariant>('primary');\n readonly disabled: ModelSignal<boolean> = model<boolean>(false);\n readonly id: InputSignal<string | undefined> = input<string>();\n readonly ariaLabel: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-label' });\n readonly ariaLabelledby: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-labelledby' });\n readonly ariaDescribedby: InputSignal<string | null> = input<string | null>(null, { alias: 'aria-describedby' });\n\n // Outputs\n readonly changed: OutputEmitterRef<RadioChange> = output<RadioChange>();\n\n // Computed state\n readonly inputId: Signal<string> = computed(() => this.id() ?? this.uniqueId);\n\n /** Resolve size from group or local input. */\n readonly resolvedSize: Signal<RadioSize> = computed(\n () => this.group?.size() ?? this.size()\n );\n\n /** Resolve variant from group or local input. */\n readonly resolvedVariant: Signal<RadioVariant> = computed(\n () => this.group?.variant() ?? this.variant()\n );\n\n /** Whether this radio is checked based on group value. */\n readonly isChecked: Signal<boolean> = computed(() => {\n if (!this.group) {\n return false;\n }\n return this.group.value() === this.value();\n });\n\n /** Whether this radio is disabled (from local or group). */\n readonly isDisabled: Signal<boolean> = computed(\n () => this.disabled() || (this.group?.disabled() ?? false)\n );\n\n /** Get name from group. */\n readonly groupName: Signal<string | undefined> = computed(() => this.group?.name());\n\n /** Tab index for roving tabindex pattern. */\n readonly tabIndex: Signal<number> = computed(() => {\n if (this.isDisabled()) {\n return -1;\n }\n if (!this.group) {\n return 0;\n }\n // Roving tabindex: only the selected or first focusable item gets tabindex 0\n const isSelected = this.isChecked();\n const isFocusTarget = this.group.focusedValue() === this.value();\n\n if (isSelected || isFocusTarget) {\n return 0;\n }\n return -1;\n });\n\n protected readonly circleClasses: Signal<string> = computed(() =>\n radioCircleVariants({ variant: this.resolvedVariant(), size: this.resolvedSize() })\n );\n\n protected readonly dotSizeClass: Signal<string> = computed(() => RADIO_DOT_SIZES[this.resolvedSize()]);\n protected readonly labelSizeClass: Signal<string> = computed(() => RADIO_LABEL_SIZES[this.resolvedSize()]);\n\n ngOnInit(): void {\n // Register with the group\n this.group?.register(this);\n\n // Unregister on destroy\n this.destroyRef.onDestroy(() => {\n this.group?.unregister(this);\n });\n }\n\n // Event handlers\n protected onInputChange(event: Event): void {\n const input = event.target as HTMLInputElement;\n if (input.checked && this.group) {\n this.group.select(this.value());\n this.changed.emit({ value: this.value(), source: this });\n }\n }\n\n protected onBlur(): void {\n this.group?.onTouched?.();\n }\n\n protected onKeyDown(event: KeyboardEvent): void {\n if (!this.group) {\n return;\n }\n\n const { key } = event;\n const isVertical = this.group.orientation() === 'vertical';\n const isHorizontal = this.group.orientation() === 'horizontal';\n\n let handled = false;\n\n if (\n (isVertical && key === 'ArrowDown') ||\n (isHorizontal && key === 'ArrowRight')\n ) {\n this.group.focusNext(this.value());\n handled = true;\n } else if (\n (isVertical && key === 'ArrowUp') ||\n (isHorizontal && key === 'ArrowLeft')\n ) {\n this.group.focusPrevious(this.value());\n handled = true;\n } else if (key === ' ') {\n // Space selects the focused radio\n if (!this.isChecked()) {\n this.group.select(this.value());\n this.changed.emit({ value: this.value(), source: this });\n }\n handled = true;\n }\n\n if (handled) {\n event.preventDefault();\n event.stopPropagation();\n }\n }\n\n // Public API\n /** Focuses this radio's input element. */\n focus(): void {\n this.inputRef()?.nativeElement.focus();\n }\n\n /** Selects this radio programmatically. */\n select(): void {\n if (this.isDisabled() || !this.group) {\n return;\n }\n this.group.select(this.value());\n this.changed.emit({ value: this.value(), source: this });\n }\n}\n","// Public API for the radio component\n\n// Main components\nexport { ComRadio } from './radio.component';\nexport { ComRadioGroup, COM_RADIO_GROUP } from './radio-group.component';\n\n// Types\nexport type { RadioChange } from './radio.component';\nexport type { RadioGroupChange, ComRadioGroupContext, RadioItem } from './radio-group.component';\n\n// Variants (for advanced customization)\nexport {\n radioCircleVariants,\n RADIO_GROUP_ORIENTATIONS,\n RADIO_DOT_SIZES,\n RADIO_LABEL_SIZES,\n} from './radio.variants';\n\nexport type { RadioSize, RadioVariant, RadioOrientation } from './radio.variants';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
import { cva } from 'class-variance-authority';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { model, input, booleanAttribute, output, Directive, computed, ChangeDetectionStrategy, Component, inject, DestroyRef } from '@angular/core';
|
|
4
|
+
|
|
5
|
+
// ─── Sort Header Variants ───
|
|
6
|
+
/**
|
|
7
|
+
* @tokens `--color-foreground`, `--color-muted-foreground`
|
|
8
|
+
*/
|
|
9
|
+
const sortHeaderVariants = cva(['inline-flex items-center gap-1.5', 'select-none', 'transition-colors duration-150'], {
|
|
10
|
+
variants: {
|
|
11
|
+
sortable: {
|
|
12
|
+
true: 'cursor-pointer hover:text-foreground',
|
|
13
|
+
false: 'cursor-default',
|
|
14
|
+
},
|
|
15
|
+
active: {
|
|
16
|
+
true: 'text-foreground',
|
|
17
|
+
false: 'text-muted-foreground',
|
|
18
|
+
},
|
|
19
|
+
disabled: {
|
|
20
|
+
true: 'text-disabled-foreground cursor-not-allowed pointer-events-none',
|
|
21
|
+
false: '',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
defaultVariants: {
|
|
25
|
+
sortable: true,
|
|
26
|
+
active: false,
|
|
27
|
+
disabled: false,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
// ─── Sort Icon Variants ───
|
|
31
|
+
/**
|
|
32
|
+
* @tokens `--color-foreground`, `--color-muted-foreground`
|
|
33
|
+
*/
|
|
34
|
+
const sortIconVariants = cva(['inline-flex items-center justify-center', 'shrink-0', 'transition-all duration-200 ease-out'], {
|
|
35
|
+
variants: {
|
|
36
|
+
size: {
|
|
37
|
+
sm: 'size-3',
|
|
38
|
+
md: 'size-3.5',
|
|
39
|
+
lg: 'size-4',
|
|
40
|
+
},
|
|
41
|
+
state: {
|
|
42
|
+
asc: 'opacity-100 rotate-0',
|
|
43
|
+
desc: 'opacity-100 rotate-180',
|
|
44
|
+
unsorted: 'opacity-40 rotate-0',
|
|
45
|
+
hidden: 'opacity-0 scale-75',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
defaultVariants: {
|
|
49
|
+
size: 'md',
|
|
50
|
+
state: 'hidden',
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const DEFAULT_SORT_CYCLE = ['asc', 'desc', undefined];
|
|
55
|
+
/**
|
|
56
|
+
* Parent directive that manages sort state for a group of sortable headers.
|
|
57
|
+
*
|
|
58
|
+
* Apply to a container element (e.g., `<tr>`, `<div>`) that contains `[uiSortHeader]` children.
|
|
59
|
+
* Children inject this directive via DI and read its signals directly.
|
|
60
|
+
*
|
|
61
|
+
* @tokens `--color-foreground`, `--color-muted-foreground`
|
|
62
|
+
*
|
|
63
|
+
* @example Basic usage
|
|
64
|
+
* ```html
|
|
65
|
+
* <tr comSort (sortChange)="onSort($event)">
|
|
66
|
+
* <th comSortHeader="name">Name</th>
|
|
67
|
+
* <th comSortHeader="age">Age</th>
|
|
68
|
+
* </tr>
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example Two-way binding
|
|
72
|
+
* ```html
|
|
73
|
+
* <tr comSort [(sortActive)]="column" [(sortDirection)]="direction">
|
|
74
|
+
* <th comSortHeader="name">Name</th>
|
|
75
|
+
* </tr>
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
class SortDirective {
|
|
79
|
+
// ─── Inputs ───
|
|
80
|
+
/** Currently active sort column id — two-way via model() */
|
|
81
|
+
sortActive = model(undefined, ...(ngDevMode ? [{ debugName: "sortActive" }] : []));
|
|
82
|
+
/** Current sort direction — two-way via model() */
|
|
83
|
+
sortDirection = model(undefined, ...(ngDevMode ? [{ debugName: "sortDirection" }] : []));
|
|
84
|
+
/** Disables all sorting in this container */
|
|
85
|
+
sortDisabled = input(false, { ...(ngDevMode ? { debugName: "sortDisabled" } : {}), transform: booleanAttribute });
|
|
86
|
+
/** Customize the click cycle (e.g., ['asc', 'desc'] to skip unsorted) */
|
|
87
|
+
sortCycle = input(DEFAULT_SORT_CYCLE, ...(ngDevMode ? [{ debugName: "sortCycle" }] : []));
|
|
88
|
+
/** Show a muted arrow on unsorted headers */
|
|
89
|
+
sortShowIndicator = input(false, { ...(ngDevMode ? { debugName: "sortShowIndicator" } : {}), transform: booleanAttribute });
|
|
90
|
+
// ─── Outputs ───
|
|
91
|
+
/** Emitted when active column or direction changes */
|
|
92
|
+
sortChange = output();
|
|
93
|
+
// ─── Registration ───
|
|
94
|
+
headers = new Map();
|
|
95
|
+
/** Register a sort header with this parent */
|
|
96
|
+
register(header) {
|
|
97
|
+
this.headers.set(header.id(), header);
|
|
98
|
+
}
|
|
99
|
+
/** Deregister a sort header */
|
|
100
|
+
deregister(id) {
|
|
101
|
+
this.headers.delete(id);
|
|
102
|
+
}
|
|
103
|
+
// ─── Public API ───
|
|
104
|
+
/** Programmatically sort by a column */
|
|
105
|
+
sort(id) {
|
|
106
|
+
if (this.sortDisabled())
|
|
107
|
+
return;
|
|
108
|
+
const cycle = this.sortCycle();
|
|
109
|
+
if (this.sortActive() !== id) {
|
|
110
|
+
// New column — start at first direction in cycle
|
|
111
|
+
this.sortActive.set(id);
|
|
112
|
+
this.sortDirection.set(cycle[0]);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// Same column — advance cycle
|
|
116
|
+
const currentIndex = cycle.indexOf(this.sortDirection());
|
|
117
|
+
const nextIndex = (currentIndex + 1) % cycle.length;
|
|
118
|
+
const nextDir = cycle[nextIndex];
|
|
119
|
+
this.sortDirection.set(nextDir);
|
|
120
|
+
// If direction is undefined, clear active
|
|
121
|
+
if (nextDir === undefined) {
|
|
122
|
+
this.sortActive.set(undefined);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
this.sortChange.emit({
|
|
126
|
+
active: this.sortActive(),
|
|
127
|
+
direction: this.sortDirection(),
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/** Returns the next direction in the cycle for a given column */
|
|
131
|
+
getNextDirection(id) {
|
|
132
|
+
const cycle = this.sortCycle();
|
|
133
|
+
if (this.sortActive() !== id) {
|
|
134
|
+
return cycle[0];
|
|
135
|
+
}
|
|
136
|
+
const currentIndex = cycle.indexOf(this.sortDirection());
|
|
137
|
+
const nextIndex = (currentIndex + 1) % cycle.length;
|
|
138
|
+
return cycle[nextIndex];
|
|
139
|
+
}
|
|
140
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SortDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
141
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.0", type: SortDirective, isStandalone: true, selector: "[comSort]", inputs: { sortActive: { classPropertyName: "sortActive", publicName: "sortActive", isSignal: true, isRequired: false, transformFunction: null }, sortDirection: { classPropertyName: "sortDirection", publicName: "sortDirection", isSignal: true, isRequired: false, transformFunction: null }, sortDisabled: { classPropertyName: "sortDisabled", publicName: "sortDisabled", isSignal: true, isRequired: false, transformFunction: null }, sortCycle: { classPropertyName: "sortCycle", publicName: "sortCycle", isSignal: true, isRequired: false, transformFunction: null }, sortShowIndicator: { classPropertyName: "sortShowIndicator", publicName: "sortShowIndicator", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sortActive: "sortActiveChange", sortDirection: "sortDirectionChange", sortChange: "sortChange" }, host: { classAttribute: "contents" }, exportAs: ["comSort"], ngImport: i0 });
|
|
142
|
+
}
|
|
143
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SortDirective, decorators: [{
|
|
144
|
+
type: Directive,
|
|
145
|
+
args: [{
|
|
146
|
+
selector: '[comSort]',
|
|
147
|
+
exportAs: 'comSort',
|
|
148
|
+
host: {
|
|
149
|
+
class: 'contents',
|
|
150
|
+
},
|
|
151
|
+
}]
|
|
152
|
+
}], propDecorators: { sortActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortActive", required: false }] }, { type: i0.Output, args: ["sortActiveChange"] }], sortDirection: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortDirection", required: false }] }, { type: i0.Output, args: ["sortDirectionChange"] }], sortDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortDisabled", required: false }] }], sortCycle: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortCycle", required: false }] }], sortShowIndicator: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortShowIndicator", required: false }] }], sortChange: [{ type: i0.Output, args: ["sortChange"] }] } });
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Internal animated SVG arrow indicator for sort headers.
|
|
156
|
+
* Not exported — used only inside SortHeaderComponent.
|
|
157
|
+
*
|
|
158
|
+
* @tokens `--color-foreground`, `--color-muted-foreground`
|
|
159
|
+
*/
|
|
160
|
+
class SortIconComponent {
|
|
161
|
+
/** Current sort direction */
|
|
162
|
+
direction = input(undefined, ...(ngDevMode ? [{ debugName: "direction" }] : []));
|
|
163
|
+
/** Whether the column is actively sorted */
|
|
164
|
+
isSorted = input(false, ...(ngDevMode ? [{ debugName: "isSorted" }] : []));
|
|
165
|
+
/** Show a muted indicator when not sorted */
|
|
166
|
+
showWhenUnsorted = input(false, ...(ngDevMode ? [{ debugName: "showWhenUnsorted" }] : []));
|
|
167
|
+
/** Compute the icon state for CVA */
|
|
168
|
+
iconState = computed(() => {
|
|
169
|
+
if (this.isSorted()) {
|
|
170
|
+
return this.direction() === 'asc' ? 'asc' : 'desc';
|
|
171
|
+
}
|
|
172
|
+
if (this.showWhenUnsorted()) {
|
|
173
|
+
return 'unsorted';
|
|
174
|
+
}
|
|
175
|
+
return 'hidden';
|
|
176
|
+
}, ...(ngDevMode ? [{ debugName: "iconState" }] : []));
|
|
177
|
+
/** CVA-generated classes for the icon container */
|
|
178
|
+
iconClasses = computed(() => sortIconVariants({
|
|
179
|
+
size: 'md',
|
|
180
|
+
state: this.iconState(),
|
|
181
|
+
}), ...(ngDevMode ? [{ debugName: "iconClasses" }] : []));
|
|
182
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SortIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
183
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.0", type: SortIconComponent, isStandalone: true, selector: "com-sort-icon", inputs: { direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, isSorted: { classPropertyName: "isSorted", publicName: "isSorted", isSignal: true, isRequired: false, transformFunction: null }, showWhenUnsorted: { classPropertyName: "showWhenUnsorted", publicName: "showWhenUnsorted", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
184
|
+
<span [class]="iconClasses()">
|
|
185
|
+
<svg
|
|
186
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
187
|
+
viewBox="0 0 24 24"
|
|
188
|
+
fill="none"
|
|
189
|
+
stroke="currentColor"
|
|
190
|
+
stroke-width="2.5"
|
|
191
|
+
stroke-linecap="round"
|
|
192
|
+
stroke-linejoin="round"
|
|
193
|
+
class="size-full"
|
|
194
|
+
aria-hidden="true"
|
|
195
|
+
>
|
|
196
|
+
<path d="M12 19V5" />
|
|
197
|
+
<path d="M5 12l7-7 7 7" />
|
|
198
|
+
</svg>
|
|
199
|
+
</span>
|
|
200
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
201
|
+
}
|
|
202
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SortIconComponent, decorators: [{
|
|
203
|
+
type: Component,
|
|
204
|
+
args: [{
|
|
205
|
+
selector: 'com-sort-icon',
|
|
206
|
+
template: `
|
|
207
|
+
<span [class]="iconClasses()">
|
|
208
|
+
<svg
|
|
209
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
210
|
+
viewBox="0 0 24 24"
|
|
211
|
+
fill="none"
|
|
212
|
+
stroke="currentColor"
|
|
213
|
+
stroke-width="2.5"
|
|
214
|
+
stroke-linecap="round"
|
|
215
|
+
stroke-linejoin="round"
|
|
216
|
+
class="size-full"
|
|
217
|
+
aria-hidden="true"
|
|
218
|
+
>
|
|
219
|
+
<path d="M12 19V5" />
|
|
220
|
+
<path d="M5 12l7-7 7 7" />
|
|
221
|
+
</svg>
|
|
222
|
+
</span>
|
|
223
|
+
`,
|
|
224
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
225
|
+
}]
|
|
226
|
+
}], propDecorators: { direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], isSorted: [{ type: i0.Input, args: [{ isSignal: true, alias: "isSorted", required: false }] }], showWhenUnsorted: [{ type: i0.Input, args: [{ isSignal: true, alias: "showWhenUnsorted", required: false }] }] } });
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Sortable header component — child of [uiSort] directive.
|
|
230
|
+
*
|
|
231
|
+
* Apply to table headers, div columns, or any clickable element that should trigger sorting.
|
|
232
|
+
*
|
|
233
|
+
* @tokens `--color-foreground`, `--color-muted-foreground`, `--color-disabled-foreground`
|
|
234
|
+
*
|
|
235
|
+
* @example Basic usage
|
|
236
|
+
* ```html
|
|
237
|
+
* <tr comSort (sortChange)="onSort($event)">
|
|
238
|
+
* <th comSortHeader="name">Name</th>
|
|
239
|
+
* <th comSortHeader="age">Age</th>
|
|
240
|
+
* </tr>
|
|
241
|
+
* ```
|
|
242
|
+
*
|
|
243
|
+
* @example Arrow placement
|
|
244
|
+
* ```html
|
|
245
|
+
* <th comSortHeader="name" comSortHeaderArrowPosition="before">Name</th>
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
class SortHeaderComponent {
|
|
249
|
+
sort = inject(SortDirective, { optional: true });
|
|
250
|
+
destroyRef = inject(DestroyRef);
|
|
251
|
+
// ─── Inputs ───
|
|
252
|
+
/** The column id — aliased from the selector */
|
|
253
|
+
id = input.required({ ...(ngDevMode ? { debugName: "id" } : {}), alias: 'comSortHeader' });
|
|
254
|
+
/** Disable sorting for this specific header */
|
|
255
|
+
sortHeaderDisabled = input(false, { ...(ngDevMode ? { debugName: "sortHeaderDisabled" } : {}), transform: booleanAttribute });
|
|
256
|
+
/** Override parent's sortShowIndicator for this header */
|
|
257
|
+
sortHeaderShowIndicator = input(undefined, ...(ngDevMode ? [{ debugName: "sortHeaderShowIndicator" }] : []));
|
|
258
|
+
/** Arrow placement relative to content */
|
|
259
|
+
sortHeaderArrowPosition = input('after', { ...(ngDevMode ? { debugName: "sortHeaderArrowPosition" } : {}), alias: 'comSortHeaderArrowPosition' });
|
|
260
|
+
// ─── Computed State (from parent signals) ───
|
|
261
|
+
/** Whether this header is the currently active sort column */
|
|
262
|
+
isActive = computed(() => this.sort?.sortActive() === this.id(), ...(ngDevMode ? [{ debugName: "isActive" }] : []));
|
|
263
|
+
/** Current direction if active, undefined otherwise */
|
|
264
|
+
direction = computed(() => this.isActive() ? this.sort?.sortDirection() : undefined, ...(ngDevMode ? [{ debugName: "direction" }] : []));
|
|
265
|
+
/** Whether this header is sorted (active + has direction) */
|
|
266
|
+
isSorted = computed(() => this.isActive() && this.sort?.sortDirection() !== undefined, ...(ngDevMode ? [{ debugName: "isSorted" }] : []));
|
|
267
|
+
/** Whether to show the muted indicator when unsorted */
|
|
268
|
+
showUnsortedIndicator = computed(() => this.sortHeaderShowIndicator() ?? this.sort?.sortShowIndicator() ?? false, ...(ngDevMode ? [{ debugName: "showUnsortedIndicator" }] : []));
|
|
269
|
+
/** Whether sorting is disabled for this header */
|
|
270
|
+
isDisabled = computed(() => this.sortHeaderDisabled() || this.sort?.sortDisabled() || false, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
271
|
+
/** aria-sort attribute value */
|
|
272
|
+
ariaSort = computed(() => {
|
|
273
|
+
if (!this.isSorted())
|
|
274
|
+
return 'none';
|
|
275
|
+
return this.direction() === 'asc' ? 'ascending' : 'descending';
|
|
276
|
+
}, ...(ngDevMode ? [{ debugName: "ariaSort" }] : []));
|
|
277
|
+
/** CVA-generated host classes */
|
|
278
|
+
hostClasses = computed(() => sortHeaderVariants({
|
|
279
|
+
sortable: !this.isDisabled(),
|
|
280
|
+
active: this.isSorted(),
|
|
281
|
+
disabled: this.isDisabled(),
|
|
282
|
+
}), ...(ngDevMode ? [{ debugName: "hostClasses" }] : []));
|
|
283
|
+
constructor() {
|
|
284
|
+
if (!this.sort) {
|
|
285
|
+
throw new Error('comSortHeader must be placed inside a [comSort] container.');
|
|
286
|
+
}
|
|
287
|
+
this.destroyRef.onDestroy(() => {
|
|
288
|
+
this.sort?.deregister(this.id());
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
ngOnInit() {
|
|
292
|
+
this.sort.register(this);
|
|
293
|
+
}
|
|
294
|
+
// ─── Event Handlers ───
|
|
295
|
+
onClick() {
|
|
296
|
+
if (this.isDisabled())
|
|
297
|
+
return;
|
|
298
|
+
this.sort.sort(this.id());
|
|
299
|
+
}
|
|
300
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SortHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
301
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: SortHeaderComponent, isStandalone: true, selector: "[comSortHeader]", inputs: { id: { classPropertyName: "id", publicName: "comSortHeader", isSignal: true, isRequired: true, transformFunction: null }, sortHeaderDisabled: { classPropertyName: "sortHeaderDisabled", publicName: "sortHeaderDisabled", isSignal: true, isRequired: false, transformFunction: null }, sortHeaderShowIndicator: { classPropertyName: "sortHeaderShowIndicator", publicName: "sortHeaderShowIndicator", isSignal: true, isRequired: false, transformFunction: null }, sortHeaderArrowPosition: { classPropertyName: "sortHeaderArrowPosition", publicName: "comSortHeaderArrowPosition", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick()", "keydown.enter": "onClick()", "keydown.space": "$event.preventDefault(); onClick()" }, properties: { "class": "hostClasses()", "attr.aria-sort": "ariaSort()", "attr.role": "\"columnheader\"", "attr.tabindex": "isDisabled() ? -1 : 0", "attr.aria-disabled": "isDisabled() || null" } }, ngImport: i0, template: `
|
|
302
|
+
@if (sortHeaderArrowPosition() === 'before') {
|
|
303
|
+
<com-sort-icon
|
|
304
|
+
[direction]="direction()"
|
|
305
|
+
[isSorted]="isSorted()"
|
|
306
|
+
[showWhenUnsorted]="showUnsortedIndicator()"
|
|
307
|
+
/>
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
<ng-content />
|
|
311
|
+
|
|
312
|
+
@if (sortHeaderArrowPosition() === 'after') {
|
|
313
|
+
<com-sort-icon
|
|
314
|
+
[direction]="direction()"
|
|
315
|
+
[isSorted]="isSorted()"
|
|
316
|
+
[showWhenUnsorted]="showUnsortedIndicator()"
|
|
317
|
+
/>
|
|
318
|
+
}
|
|
319
|
+
`, isInline: true, dependencies: [{ kind: "component", type: SortIconComponent, selector: "com-sort-icon", inputs: ["direction", "isSorted", "showWhenUnsorted"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
320
|
+
}
|
|
321
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: SortHeaderComponent, decorators: [{
|
|
322
|
+
type: Component,
|
|
323
|
+
args: [{
|
|
324
|
+
selector: '[comSortHeader]',
|
|
325
|
+
template: `
|
|
326
|
+
@if (sortHeaderArrowPosition() === 'before') {
|
|
327
|
+
<com-sort-icon
|
|
328
|
+
[direction]="direction()"
|
|
329
|
+
[isSorted]="isSorted()"
|
|
330
|
+
[showWhenUnsorted]="showUnsortedIndicator()"
|
|
331
|
+
/>
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
<ng-content />
|
|
335
|
+
|
|
336
|
+
@if (sortHeaderArrowPosition() === 'after') {
|
|
337
|
+
<com-sort-icon
|
|
338
|
+
[direction]="direction()"
|
|
339
|
+
[isSorted]="isSorted()"
|
|
340
|
+
[showWhenUnsorted]="showUnsortedIndicator()"
|
|
341
|
+
/>
|
|
342
|
+
}
|
|
343
|
+
`,
|
|
344
|
+
imports: [SortIconComponent],
|
|
345
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
346
|
+
host: {
|
|
347
|
+
'[class]': 'hostClasses()',
|
|
348
|
+
'[attr.aria-sort]': 'ariaSort()',
|
|
349
|
+
'[attr.role]': '"columnheader"',
|
|
350
|
+
'[attr.tabindex]': 'isDisabled() ? -1 : 0',
|
|
351
|
+
'[attr.aria-disabled]': 'isDisabled() || null',
|
|
352
|
+
'(click)': 'onClick()',
|
|
353
|
+
'(keydown.enter)': 'onClick()',
|
|
354
|
+
'(keydown.space)': '$event.preventDefault(); onClick()',
|
|
355
|
+
},
|
|
356
|
+
}]
|
|
357
|
+
}], ctorParameters: () => [], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "comSortHeader", required: true }] }], sortHeaderDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortHeaderDisabled", required: false }] }], sortHeaderShowIndicator: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortHeaderShowIndicator", required: false }] }], sortHeaderArrowPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "comSortHeaderArrowPosition", required: false }] }] } });
|
|
358
|
+
|
|
359
|
+
// Public API for the sort component
|
|
360
|
+
// Types & Variants
|
|
361
|
+
// NOT exported: SortIconComponent (internal)
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Generated bundle index. Do not edit.
|
|
365
|
+
*/
|
|
366
|
+
|
|
367
|
+
export { SortDirective, SortHeaderComponent, sortHeaderVariants, sortIconVariants };
|
|
368
|
+
//# sourceMappingURL=ngx-com-components-sort.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngx-com-components-sort.mjs","sources":["../../../projects/com/components/sort/sort.variants.ts","../../../projects/com/components/sort/sort.directive.ts","../../../projects/com/components/sort/sort-icon.component.ts","../../../projects/com/components/sort/sort-header.component.ts","../../../projects/com/components/sort/index.ts","../../../projects/com/components/sort/ngx-com-components-sort.ts"],"sourcesContent":["import { cva } from 'class-variance-authority';\n\n// ─── Type Exports ───\n\n/** Sort direction — three states */\nexport type SortDirection = 'asc' | 'desc' | undefined;\n\n/** Configures the three-state sort cycle */\nexport type SortCycle = SortDirection[];\n\n/** Emitted when sort state changes */\nexport interface SortEvent {\n /** The active column id, or undefined if unsorted */\n active: string | undefined;\n /** The sort direction */\n direction: SortDirection;\n}\n\n// ─── Sort Header Variants ───\n\n/**\n * @tokens `--color-foreground`, `--color-muted-foreground`\n */\nexport const sortHeaderVariants: (props?: {\n sortable?: boolean;\n active?: boolean;\n disabled?: boolean;\n}) => string = cva(\n ['inline-flex items-center gap-1.5', 'select-none', 'transition-colors duration-150'],\n {\n variants: {\n sortable: {\n true: 'cursor-pointer hover:text-foreground',\n false: 'cursor-default',\n },\n active: {\n true: 'text-foreground',\n false: 'text-muted-foreground',\n },\n disabled: {\n true: 'text-disabled-foreground cursor-not-allowed pointer-events-none',\n false: '',\n },\n },\n defaultVariants: {\n sortable: true,\n active: false,\n disabled: false,\n },\n }\n);\n\n// ─── Sort Icon Variants ───\n\n/**\n * @tokens `--color-foreground`, `--color-muted-foreground`\n */\nexport const sortIconVariants: (props?: {\n size?: 'sm' | 'md' | 'lg';\n state?: 'asc' | 'desc' | 'unsorted' | 'hidden';\n}) => string = cva(\n ['inline-flex items-center justify-center', 'shrink-0', 'transition-all duration-200 ease-out'],\n {\n variants: {\n size: {\n sm: 'size-3',\n md: 'size-3.5',\n lg: 'size-4',\n },\n state: {\n asc: 'opacity-100 rotate-0',\n desc: 'opacity-100 rotate-180',\n unsorted: 'opacity-40 rotate-0',\n hidden: 'opacity-0 scale-75',\n },\n },\n defaultVariants: {\n size: 'md',\n state: 'hidden',\n },\n }\n);\n","import { booleanAttribute, Directive, input, model, output } from '@angular/core';\nimport type {\n InputSignal,\n InputSignalWithTransform,\n ModelSignal,\n OutputEmitterRef,\n} from '@angular/core';\nimport type { SortDirection, SortCycle, SortEvent } from './sort.variants';\nimport type { SortHeaderComponent } from './sort-header.component';\n\nconst DEFAULT_SORT_CYCLE: SortCycle = ['asc', 'desc', undefined];\n\n/**\n * Parent directive that manages sort state for a group of sortable headers.\n *\n * Apply to a container element (e.g., `<tr>`, `<div>`) that contains `[uiSortHeader]` children.\n * Children inject this directive via DI and read its signals directly.\n *\n * @tokens `--color-foreground`, `--color-muted-foreground`\n *\n * @example Basic usage\n * ```html\n * <tr comSort (sortChange)=\"onSort($event)\">\n * <th comSortHeader=\"name\">Name</th>\n * <th comSortHeader=\"age\">Age</th>\n * </tr>\n * ```\n *\n * @example Two-way binding\n * ```html\n * <tr comSort [(sortActive)]=\"column\" [(sortDirection)]=\"direction\">\n * <th comSortHeader=\"name\">Name</th>\n * </tr>\n * ```\n */\n@Directive({\n selector: '[comSort]',\n exportAs: 'comSort',\n host: {\n class: 'contents',\n },\n})\nexport class SortDirective {\n // ─── Inputs ───\n\n /** Currently active sort column id — two-way via model() */\n readonly sortActive: ModelSignal<string | undefined> = model<string | undefined>(undefined);\n\n /** Current sort direction — two-way via model() */\n readonly sortDirection: ModelSignal<SortDirection> = model<SortDirection>(undefined);\n\n /** Disables all sorting in this container */\n readonly sortDisabled: InputSignalWithTransform<boolean, unknown> = input(false, {\n transform: booleanAttribute,\n });\n\n /** Customize the click cycle (e.g., ['asc', 'desc'] to skip unsorted) */\n readonly sortCycle: InputSignal<SortCycle> = input<SortCycle>(DEFAULT_SORT_CYCLE);\n\n /** Show a muted arrow on unsorted headers */\n readonly sortShowIndicator: InputSignalWithTransform<boolean, unknown> = input(false, {\n transform: booleanAttribute,\n });\n\n // ─── Outputs ───\n\n /** Emitted when active column or direction changes */\n readonly sortChange: OutputEmitterRef<SortEvent> = output<SortEvent>();\n\n // ─── Registration ───\n\n private readonly headers: Map<string, SortHeaderComponent> = new Map<string, SortHeaderComponent>();\n\n /** Register a sort header with this parent */\n register(header: SortHeaderComponent): void {\n this.headers.set(header.id(), header);\n }\n\n /** Deregister a sort header */\n deregister(id: string): void {\n this.headers.delete(id);\n }\n\n // ─── Public API ───\n\n /** Programmatically sort by a column */\n sort(id: string): void {\n if (this.sortDisabled()) return;\n\n const cycle = this.sortCycle();\n\n if (this.sortActive() !== id) {\n // New column — start at first direction in cycle\n this.sortActive.set(id);\n this.sortDirection.set(cycle[0]);\n } else {\n // Same column — advance cycle\n const currentIndex = cycle.indexOf(this.sortDirection());\n const nextIndex = (currentIndex + 1) % cycle.length;\n const nextDir = cycle[nextIndex];\n this.sortDirection.set(nextDir);\n\n // If direction is undefined, clear active\n if (nextDir === undefined) {\n this.sortActive.set(undefined);\n }\n }\n\n this.sortChange.emit({\n active: this.sortActive(),\n direction: this.sortDirection(),\n });\n }\n\n /** Returns the next direction in the cycle for a given column */\n getNextDirection(id: string): SortDirection {\n const cycle = this.sortCycle();\n\n if (this.sortActive() !== id) {\n return cycle[0];\n }\n\n const currentIndex = cycle.indexOf(this.sortDirection());\n const nextIndex = (currentIndex + 1) % cycle.length;\n return cycle[nextIndex];\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, input } from '@angular/core';\nimport type { InputSignal, Signal } from '@angular/core';\nimport { sortIconVariants } from './sort.variants';\nimport type { SortDirection } from './sort.variants';\n\n/**\n * Internal animated SVG arrow indicator for sort headers.\n * Not exported — used only inside SortHeaderComponent.\n *\n * @tokens `--color-foreground`, `--color-muted-foreground`\n */\n@Component({\n selector: 'com-sort-icon',\n template: `\n <span [class]=\"iconClasses()\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n class=\"size-full\"\n aria-hidden=\"true\"\n >\n <path d=\"M12 19V5\" />\n <path d=\"M5 12l7-7 7 7\" />\n </svg>\n </span>\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SortIconComponent {\n /** Current sort direction */\n readonly direction: InputSignal<SortDirection> = input<SortDirection>(undefined);\n\n /** Whether the column is actively sorted */\n readonly isSorted: InputSignal<boolean> = input(false);\n\n /** Show a muted indicator when not sorted */\n readonly showWhenUnsorted: InputSignal<boolean> = input(false);\n\n /** Compute the icon state for CVA */\n private readonly iconState: Signal<'asc' | 'desc' | 'unsorted' | 'hidden'> = computed(() => {\n if (this.isSorted()) {\n return this.direction() === 'asc' ? 'asc' : 'desc';\n }\n if (this.showWhenUnsorted()) {\n return 'unsorted';\n }\n return 'hidden';\n });\n\n /** CVA-generated classes for the icon container */\n readonly iconClasses: Signal<string> = computed(() =>\n sortIconVariants({\n size: 'md',\n state: this.iconState(),\n })\n );\n}\n","import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n inject,\n input,\n} from '@angular/core';\nimport type {\n InputSignal,\n InputSignalWithTransform,\n OnInit,\n Signal,\n} from '@angular/core';\nimport { SortDirective } from './sort.directive';\nimport { SortIconComponent } from './sort-icon.component';\nimport { sortHeaderVariants } from './sort.variants';\nimport type { SortDirection } from './sort.variants';\n\n/**\n * Sortable header component — child of [uiSort] directive.\n *\n * Apply to table headers, div columns, or any clickable element that should trigger sorting.\n *\n * @tokens `--color-foreground`, `--color-muted-foreground`, `--color-disabled-foreground`\n *\n * @example Basic usage\n * ```html\n * <tr comSort (sortChange)=\"onSort($event)\">\n * <th comSortHeader=\"name\">Name</th>\n * <th comSortHeader=\"age\">Age</th>\n * </tr>\n * ```\n *\n * @example Arrow placement\n * ```html\n * <th comSortHeader=\"name\" comSortHeaderArrowPosition=\"before\">Name</th>\n * ```\n */\n@Component({\n selector: '[comSortHeader]',\n template: `\n @if (sortHeaderArrowPosition() === 'before') {\n <com-sort-icon\n [direction]=\"direction()\"\n [isSorted]=\"isSorted()\"\n [showWhenUnsorted]=\"showUnsortedIndicator()\"\n />\n }\n\n <ng-content />\n\n @if (sortHeaderArrowPosition() === 'after') {\n <com-sort-icon\n [direction]=\"direction()\"\n [isSorted]=\"isSorted()\"\n [showWhenUnsorted]=\"showUnsortedIndicator()\"\n />\n }\n `,\n imports: [SortIconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'hostClasses()',\n '[attr.aria-sort]': 'ariaSort()',\n '[attr.role]': '\"columnheader\"',\n '[attr.tabindex]': 'isDisabled() ? -1 : 0',\n '[attr.aria-disabled]': 'isDisabled() || null',\n '(click)': 'onClick()',\n '(keydown.enter)': 'onClick()',\n '(keydown.space)': '$event.preventDefault(); onClick()',\n },\n})\nexport class SortHeaderComponent implements OnInit {\n private readonly sort: SortDirective | null = inject(SortDirective, { optional: true });\n private readonly destroyRef: DestroyRef = inject(DestroyRef);\n\n // ─── Inputs ───\n\n /** The column id — aliased from the selector */\n readonly id: InputSignal<string> = input.required<string>({ alias: 'comSortHeader' });\n\n /** Disable sorting for this specific header */\n readonly sortHeaderDisabled: InputSignalWithTransform<boolean, unknown> = input(false, {\n transform: booleanAttribute,\n });\n\n /** Override parent's sortShowIndicator for this header */\n readonly sortHeaderShowIndicator: InputSignal<boolean | undefined> = input<boolean | undefined>(\n undefined\n );\n\n /** Arrow placement relative to content */\n readonly sortHeaderArrowPosition: InputSignal<'before' | 'after'> = input<'before' | 'after'>(\n 'after',\n { alias: 'comSortHeaderArrowPosition' }\n );\n\n // ─── Computed State (from parent signals) ───\n\n /** Whether this header is the currently active sort column */\n readonly isActive: Signal<boolean> = computed(() => this.sort?.sortActive() === this.id());\n\n /** Current direction if active, undefined otherwise */\n readonly direction: Signal<SortDirection> = computed(() =>\n this.isActive() ? this.sort?.sortDirection() : undefined\n );\n\n /** Whether this header is sorted (active + has direction) */\n readonly isSorted: Signal<boolean> = computed(\n () => this.isActive() && this.sort?.sortDirection() !== undefined\n );\n\n /** Whether to show the muted indicator when unsorted */\n readonly showUnsortedIndicator: Signal<boolean> = computed(\n () => this.sortHeaderShowIndicator() ?? this.sort?.sortShowIndicator() ?? false\n );\n\n /** Whether sorting is disabled for this header */\n readonly isDisabled: Signal<boolean> = computed(\n () => this.sortHeaderDisabled() || this.sort?.sortDisabled() || false\n );\n\n /** aria-sort attribute value */\n readonly ariaSort: Signal<'ascending' | 'descending' | 'none'> = computed(() => {\n if (!this.isSorted()) return 'none';\n return this.direction() === 'asc' ? 'ascending' : 'descending';\n });\n\n /** CVA-generated host classes */\n readonly hostClasses: Signal<string> = computed(() =>\n sortHeaderVariants({\n sortable: !this.isDisabled(),\n active: this.isSorted(),\n disabled: this.isDisabled(),\n })\n );\n\n constructor() {\n if (!this.sort) {\n throw new Error('comSortHeader must be placed inside a [comSort] container.');\n }\n\n this.destroyRef.onDestroy(() => {\n this.sort?.deregister(this.id());\n });\n }\n\n ngOnInit(): void {\n this.sort!.register(this);\n }\n\n // ─── Event Handlers ───\n\n protected onClick(): void {\n if (this.isDisabled()) return;\n this.sort!.sort(this.id());\n }\n}\n","// Public API for the sort component\n\n// Types & Variants\nexport {\n sortHeaderVariants,\n sortIconVariants,\n type SortDirection,\n type SortCycle,\n type SortEvent,\n} from './sort.variants';\n\n// Directives & Components\nexport { SortDirective } from './sort.directive';\nexport { SortHeaderComponent } from './sort-header.component';\n\n// NOT exported: SortIconComponent (internal)\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|