Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 50 additions & 1 deletion packages/angular-table/src/angularReactivityFeature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,53 @@ declare module '@tanstack/table-core' {
> extends Table_AngularReactivity<TFeatures, TData> {}
}

/**
* Predicate used to skip/ignore a property name when applying Angular reactivity.
*
* Returning `true` means the property should NOT be wrapped/made reactive.
*/
type SkipPropertyFn = (property: string) => boolean

/**
* Fine-grained configuration for Angular reactivity.
*
* Each key controls whether prototype methods/getters on the corresponding TanStack Table
* objects are wrapped with signal-aware access.
*
* - `true` enables wrapping using the default skip rules.
* - `false` disables wrapping entirely for that object type.
* - a function allows customizing the skip rules (see {@link SkipPropertyFn}).
*/
export interface AngularReactivityFlags {
/** Controls reactive wrapping for `Header` instances. */
header: boolean | SkipPropertyFn
/** Controls reactive wrapping for `Column` instances. */
column: boolean | SkipPropertyFn
/** Controls reactive wrapping for `Row` instances. */
row: boolean | SkipPropertyFn
/** Controls reactive wrapping for `Cell` instances. */
cell: boolean | SkipPropertyFn
}

/**
* Table option extension for Angular reactivity.
*
* Available on `createTable` options via module augmentation in this file.
*/
interface TableOptions_AngularReactivity {
/**
* Enables/disables and configures Angular reactivity on table-related prototypes.
*
* If omitted, defaults are provided by the feature.
*/
reactivity?: Partial<AngularReactivityFlags>
}

/**
* Table API extension for Angular reactivity.
*
* Added to the table instance via module augmentation.
*/
interface Table_AngularReactivity<
TFeatures extends TableFeatures,
TData extends RowData,
Expand All @@ -42,11 +76,16 @@ interface Table_AngularReactivity<
*/
get: Signal<Table<TFeatures, TData>>
/**
* @internal
* Sets the reactive notifier that powers {@link get}.
*
* @internal Used by the Angular table adapter to connect its notifier to the core table.
*/
setTableNotifier: (signal: Signal<Table<TFeatures, TData>>) => void
}

/**
* Type map describing what this feature adds to TanStack Table constructors.
*/
interface AngularReactivityFeatureConstructors<
TFeatures extends TableFeatures,
TData extends RowData,
Expand All @@ -55,6 +94,13 @@ interface AngularReactivityFeatureConstructors<
Table: Table_AngularReactivity<TFeatures, TData>
}

/**
* Resolves the user-provided `reactivity.*` config to a skip predicate.
*
* - `false` is handled by callers (feature method returns early)
* - `true` selects the default predicate
* - a function overrides the default predicate
*/
const getUserSkipPropertyFn = (
value: undefined | null | boolean | SkipPropertyFn,
defaultPropertyFn: SkipPropertyFn,
Expand Down Expand Up @@ -147,6 +193,9 @@ function constructAngularReactivityFeature<

export const angularReactivityFeature = constructAngularReactivityFeature()

/**
* Default predicate used to skip base/non-reactive properties.
*/
function skipBaseProperties(property: string): boolean {
return (
// equals `getContext`
Expand Down
5 changes: 5 additions & 0 deletions packages/angular-table/src/flex-render/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ export const FlexRenderComponentProps = new InjectionToken<
NonNullable<unknown>
>('[@tanstack/angular-table] Flex render component context props')

/**
* Inject the flex render context props.
*
* Can be used in components rendered via FlexRender directives.
*/
export function injectFlexRenderContext<T extends NonNullable<unknown>>(): T {
return inject<T>(FlexRenderComponentProps)
}
18 changes: 9 additions & 9 deletions packages/angular-table/src/flex-render/flags.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
/**
* Flags used to manage and optimize the rendering lifecycle of content of the cell,
* while using FlexRenderDirective.
* Flags used to manage and optimize the rendering lifecycle of the content of the cell
* while using {@link FlexViewRenderer}.
*/
export enum FlexRenderFlags {
export const FlexRenderFlags = {
/**
* Indicates that the view is being created for the first time or will be cleared during the next update phase.
* This is the initial state and will transition after the first ngDoCheck.
*/
ViewFirstRender = 1 << 0,
ViewFirstRender: 1 << 0,
/**
* Indicates the `content` property has been modified or the view requires a complete re-render.
* When this flag is enabled, the view will be cleared and recreated from scratch.
*/
ContentChanged = 1 << 1,
ContentChanged: 1 << 1,
/**
* Indicates that the `props` property reference has changed.
* When this flag is enabled, the view context is updated based on the type of the content.
*
* For Component view, inputs will be updated and view will be marked as dirty.
* For TemplateRef and primitive values, view will be marked as dirty
*/
PropsReferenceChanged = 1 << 2,
PropsReferenceChanged: 1 << 2,
/**
* Indicates that the current rendered view needs to be checked for changes.
* This will be set to true when `content(props)` result has changed or during
* forced update
*/
Dirty = 1 << 3,
Dirty: 1 << 3,
/**
* Indicates that the first render effect has been checked at least one time.
*/
RenderEffectChecked = 1 << 4,
}
RenderEffectChecked: 1 << 4,
} as const
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,13 @@ import type {
Type,
} from '@angular/core'

type Inputs<T> = {
[K in keyof T as T[K] extends InputSignal<infer R>
? K
: never]?: T[K] extends InputSignal<infer R> ? R : never
}

type Outputs<T> = {
[K in keyof T as T[K] extends OutputEmitterRef<infer R>
? K
: never]?: T[K] extends OutputEmitterRef<infer R>
? OutputEmitterRef<R>['emit']
: never
}

type OptionalKeys<T, K = keyof T> = K extends keyof T
? T[K] extends Required<T>[K]
? undefined extends T[K]
? K
: never
: K
: never

interface FlexRenderRequiredOptions<
interface FlexRenderRequiredInputOptions<
TInputs extends Record<string, any>,
TOutputs extends Record<string, any>,
> {
/**
* Component instance inputs. They will be set via [componentRef.setInput API](https://angular.dev/api/core/ComponentRef#setInput)
* Component instance inputs.
* They will be set via [componentRef.setInput API](https://angular.dev/api/core/ComponentRef#setInput)
*/
inputs: TInputs
/**
Expand All @@ -52,7 +31,8 @@ interface FlexRenderOptions<
TOutputs extends Record<string, any>,
> {
/**
* Component instance inputs. They will be set via [componentRef.setInput API](https://angular.dev/api/core/ComponentRef#setInput)
* Component instance inputs.
* They will be set via [componentRef.setInput API](https://angular.dev/api/core/ComponentRef#setInput)
*/
inputs?: TInputs
/**
Expand All @@ -65,6 +45,28 @@ interface FlexRenderOptions<
injector?: Injector
}

type Inputs<T> = {
[K in keyof T as T[K] extends InputSignal<infer R>
? K
: never]?: T[K] extends InputSignal<infer R> ? R : never
}

type Outputs<T> = {
[K in keyof T as T[K] extends OutputEmitterRef<infer R>
? K
: never]?: T[K] extends OutputEmitterRef<infer R>
? OutputEmitterRef<R>['emit']
: never
}

type OptionalKeys<T, K = keyof T> = K extends keyof T
? T[K] extends Required<T>[K]
? undefined extends T[K]
? K
: never
: K
: never

/**
* Helper function to create a [@link FlexRenderComponent] instance, with better type-safety.
*
Expand All @@ -80,7 +82,7 @@ export function flexRenderComponent<
component: Type<TComponent>,
...options: OptionalKeys<TInputs> extends never
? [FlexRenderOptions<TInputs, TOutputs>?]
: [FlexRenderRequiredOptions<TInputs, TOutputs>]
: [FlexRenderRequiredInputOptions<TInputs, TOutputs>]
): FlexRenderComponent<TComponent> {
const { inputs, injector, outputs } = options[0] ?? {}
return new FlexRenderComponent(component, inputs, injector, outputs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
OutputRefSubscription,
ViewContainerRef,
} from '@angular/core'
import { FlexRenderComponent } from './flex-render-component'
import { FlexRenderComponent } from './flexRenderComponent'

@Injectable()
export class FlexRenderComponentFactory {
Expand Down
Loading
Loading