Skip to content

Commit

Permalink
fix: adapt the type of widget factories for slots in headless packages (
Browse files Browse the repository at this point in the history
  • Loading branch information
divdavem authored Sep 29, 2023
1 parent 6ce8cf4 commit 70ab1d0
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 19 deletions.
14 changes: 8 additions & 6 deletions angular/headless/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,14 @@ export type AdaptPropsSlots<Props> = Omit<Props, `slot${string}`> & {
[K in keyof Props & `slot${string}`]: Props[K] extends CoreSlotContent<infer U> ? SlotContent<AdaptSlotContentProps<U>> : Props[K];
};

export type AdaptWidgetFactories<T> = {
[K in keyof T]: T[K] extends WidgetFactory<infer U> ? WidgetFactory<AdaptWidgetSlots<U>> : T[K];
};

export type AdaptWidgetSlots<W extends Widget> = Widget<
AdaptPropsSlots<WidgetProps<W>>,
AdaptPropsSlots<WidgetState<W>>,
W['api'],
AdaptWidgetFactories<W['api']>,
W['actions'],
W['directives']
>;
Expand Down Expand Up @@ -150,18 +154,16 @@ const createPatchSlots = <T extends object>(set: (object: Partial<T>) => void) =
};
};

export type WithPatchSlots<W extends Widget> = AdaptWidgetSlots<W> & {
export type WithPatchSlots<W extends Widget> = W & {
patchSlots(slots: {
[K in keyof WidgetProps<W> & `slot${string}`]: WidgetProps<W>[K] extends CoreSlotContent<infer U>
? TemplateRef<AdaptSlotContentProps<U>> | undefined
: never;
[K in keyof WidgetProps<W> & `slot${string}`]: WidgetProps<W>[K] extends SlotContent<infer U> ? TemplateRef<U> | undefined : never;
}): void;
};

export const callWidgetFactory = <W extends Widget>(
factory: WidgetFactory<W>,
widgetName: keyof WidgetsConfig | null,
defaultConfig: Partial<AdaptPropsSlots<WidgetProps<W>>> | ReadableSignal<Partial<AdaptPropsSlots<WidgetProps<W>>>> = {}
defaultConfig: Partial<WidgetProps<W>> | ReadableSignal<Partial<WidgetProps<W>>> = {}
): WithPatchSlots<W> => {
const defaultConfigStore = typeof defaultConfig !== 'function' ? readable(defaultConfig) : defaultConfig;
const slots$ = writable({});
Expand Down
18 changes: 17 additions & 1 deletion angular/headless/src/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,43 +8,59 @@ export * from './lib/slot.directive';
export * from './lib/slotDefault.directive';
export * from './lib/use.directive';
export * from './lib/utils';

export type {SlotContent, WidgetsConfig} from './lib/utils';
import type {WidgetProps, WidgetState} from '@agnos-ui/core';
import type {PropsConfig, WidgetFactory, WidgetProps, WidgetState} from '@agnos-ui/core';
import type {AdaptSlotContentProps, AdaptWidgetSlots} from './lib/utils';

export type AccordionWidget = AdaptWidgetSlots<import('@agnos-ui/core').AccordionWidget>;
export type AccordionProps = WidgetProps<AccordionWidget>;
export type AccordionState = WidgetState<AccordionWidget>;
export type AccordionApi = AccordionWidget['api'];
export type AccordionItemWidget = AdaptWidgetSlots<import('@agnos-ui/core').AccordionItemWidget>;
export type AccordionItemProps = WidgetProps<AccordionItemWidget>;
export type AccordionItemState = WidgetState<AccordionItemWidget>;
export type AccordionItemContext = AdaptSlotContentProps<import('@agnos-ui/core').AccordionItemContext>;
import {createAccordion as coreCreateAccordion} from '@agnos-ui/core';
export const createAccordion: WidgetFactory<AccordionWidget> = coreCreateAccordion as any;

export type AlertWidget = AdaptWidgetSlots<import('@agnos-ui/core').AlertWidget>;
export type AlertProps = WidgetProps<AlertWidget>;
export type AlertState = WidgetState<AlertWidget>;
export type AlertContext = AdaptSlotContentProps<import('@agnos-ui/core').AlertContext>;
import {createAlert as coreCreateAlert} from '@agnos-ui/core';
export const createAlert: WidgetFactory<AlertWidget> = coreCreateAlert as any;

export type ModalWidget = AdaptWidgetSlots<import('@agnos-ui/core').ModalWidget>;
export type ModalProps = WidgetProps<ModalWidget>;
export type ModalState = WidgetState<ModalWidget>;
export type ModalContext = AdaptSlotContentProps<import('@agnos-ui/core').ModalContext>;
import {createModal as coreCreateModal} from '@agnos-ui/core';
export const createModal: WidgetFactory<ModalWidget> = coreCreateModal as any;

export type PaginationWidget = AdaptWidgetSlots<import('@agnos-ui/core').PaginationWidget>;
export type PaginationProps = WidgetProps<PaginationWidget>;
export type PaginationState = WidgetState<PaginationWidget>;
export type PaginationContext = AdaptSlotContentProps<import('@agnos-ui/core').PaginationContext>;
export type PaginationNumberContext = AdaptSlotContentProps<import('@agnos-ui/core').PaginationNumberContext>;
import {createPagination as coreCreatePagination} from '@agnos-ui/core';
export const createPagination: WidgetFactory<PaginationWidget> = coreCreatePagination as any;

export type RatingWidget = AdaptWidgetSlots<import('@agnos-ui/core').RatingWidget>;
export type RatingProps = WidgetProps<RatingWidget>;
export type RatingState = WidgetState<RatingWidget>;
import {createRating as coreCreateRating} from '@agnos-ui/core';
export const createRating: WidgetFactory<RatingWidget> = coreCreateRating as any;

export type SelectWidget<Item> = AdaptWidgetSlots<import('@agnos-ui/core').SelectWidget<Item>>;
export type SelectProps<Item> = WidgetProps<SelectWidget<Item>>;
export type SelectState<Item> = WidgetState<SelectWidget<Item>>;
import {createSelect as coreCreateSelect} from '@agnos-ui/core';
export const createSelect: <Item>(propsConfig?: PropsConfig<SelectProps<Item>>) => SelectWidget<Item> = coreCreateSelect as any;

export type ProgressbarWidget = AdaptWidgetSlots<import('@agnos-ui/core').ProgressbarWidget>;
export type ProgressbarProps = WidgetProps<ProgressbarWidget>;
export type ProgressbarState = WidgetState<ProgressbarWidget>;
export type ProgressbarContext = AdaptSlotContentProps<import('@agnos-ui/core').ProgressbarContext>;
import {createProgressbar as coreCreateProgressbar} from '@agnos-ui/core';
export const createProgressbar: WidgetFactory<ProgressbarWidget> = coreCreateProgressbar as any;
17 changes: 16 additions & 1 deletion react/headless/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,58 @@ export * from './Slot';
export * from './WidgetsDefaultConfig';
export * from './utils';

import type {WidgetProps, WidgetState} from '@agnos-ui/core';
import type {PropsConfig, WidgetFactory, WidgetProps, WidgetState} from '@agnos-ui/core';
import type {AdaptSlotContentProps, AdaptWidgetSlots} from './utils';

export type {SlotContent, WidgetsConfig} from './utils';
export type AccordionWidget = AdaptWidgetSlots<import('@agnos-ui/core').AccordionWidget>;
export type AccordionProps = WidgetProps<AccordionWidget>;
export type AccordionState = WidgetState<AccordionWidget>;
export type AccordionApi = AccordionWidget['api'];
export type AccordionItemWidget = AdaptWidgetSlots<import('@agnos-ui/core').AccordionItemWidget>;
export type AccordionItemProps = WidgetProps<AccordionItemWidget>;
export type AccordionItemState = WidgetState<AccordionItemWidget>;
export type AccordionItemContext = AdaptSlotContentProps<import('@agnos-ui/core').AccordionItemContext>;
import {createAccordion as coreCreateAccordion} from '@agnos-ui/core';
export const createAccordion: WidgetFactory<AccordionWidget> = coreCreateAccordion as any;

export type AlertWidget = AdaptWidgetSlots<import('@agnos-ui/core').AlertWidget>;
export type AlertProps = WidgetProps<AlertWidget>;
export type AlertState = WidgetState<AlertWidget>;
export type AlertContext = AdaptSlotContentProps<import('@agnos-ui/core').AlertContext>;
import {createAlert as coreCreateAlert} from '@agnos-ui/core';
export const createAlert: WidgetFactory<AlertWidget> = coreCreateAlert as any;

export type ModalWidget = AdaptWidgetSlots<import('@agnos-ui/core').ModalWidget>;
export type ModalProps = WidgetProps<ModalWidget>;
export type ModalState = WidgetState<ModalWidget>;
export type ModalContext = AdaptSlotContentProps<import('@agnos-ui/core').ModalContext>;
import {createModal as coreCreateModal} from '@agnos-ui/core';
export const createModal: WidgetFactory<ModalWidget> = coreCreateModal as any;

export type PaginationWidget = AdaptWidgetSlots<import('@agnos-ui/core').PaginationWidget>;
export type PaginationProps = WidgetProps<PaginationWidget>;
export type PaginationState = WidgetState<PaginationWidget>;
export type PaginationContext = AdaptSlotContentProps<import('@agnos-ui/core').PaginationContext>;
export type PaginationNumberContext = AdaptSlotContentProps<import('@agnos-ui/core').PaginationNumberContext>;
import {createPagination as coreCreatePagination} from '@agnos-ui/core';
export const createPagination: WidgetFactory<PaginationWidget> = coreCreatePagination as any;

export type RatingWidget = AdaptWidgetSlots<import('@agnos-ui/core').RatingWidget>;
export type RatingProps = WidgetProps<RatingWidget>;
export type RatingState = WidgetState<RatingWidget>;
import {createRating as coreCreateRating} from '@agnos-ui/core';
export const createRating: WidgetFactory<RatingWidget> = coreCreateRating as any;

export type SelectWidget<Item> = AdaptWidgetSlots<import('@agnos-ui/core').SelectWidget<Item>>;
export type SelectProps<Item> = WidgetProps<SelectWidget<Item>>;
export type SelectState<Item> = WidgetState<SelectWidget<Item>>;
import {createSelect as coreCreateSelect} from '@agnos-ui/core';
export const createSelect: <Item>(propsConfig?: PropsConfig<SelectProps<Item>>) => SelectWidget<Item> = coreCreateSelect as any;

export type ProgressbarWidget = AdaptWidgetSlots<import('@agnos-ui/core').ProgressbarWidget>;
export type ProgressbarProps = WidgetProps<ProgressbarWidget>;
export type ProgressbarState = WidgetState<ProgressbarWidget>;
export type ProgressbarContext = AdaptSlotContentProps<import('@agnos-ui/core').ProgressbarContext>;
import {createProgressbar as coreCreateProgressbar} from '@agnos-ui/core';
export const createProgressbar: WidgetFactory<ProgressbarWidget> = coreCreateProgressbar as any;
13 changes: 8 additions & 5 deletions react/headless/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ export type WidgetsConfig = {
[WidgetName in keyof CoreWidgetsConfig]: AdaptPropsSlots<CoreWidgetsConfig[WidgetName]>;
};

export type AdaptWidgetFactories<T> = {
[K in keyof T]: T[K] extends WidgetFactory<infer U> ? WidgetFactory<AdaptWidgetSlots<U>> : T[K];
};

export type AdaptWidgetSlots<W extends Widget> = Widget<
AdaptPropsSlots<WidgetProps<W>>,
AdaptPropsSlots<WidgetState<W>>,
W['api'],
AdaptWidgetFactories<W['api']>,
W['actions'],
W['directives']
>;
Expand Down Expand Up @@ -123,8 +127,7 @@ const useWidgetContext = <Props extends object>(widgetName: keyof WidgetsConfig

export const useWidgetWithConfig = <W extends Widget>(
factory: WidgetFactory<W>,
props: Partial<AdaptPropsSlots<WidgetProps<W>>> | undefined,
props: Partial<WidgetProps<W>> | undefined,
widgetName: keyof WidgetsConfig | null,
defaultProps?: Partial<AdaptPropsSlots<WidgetProps<W>>>
): [AdaptPropsSlots<WidgetState<W>>, AdaptWidgetSlots<W>] =>
useWidget(factory, props as any, {config: useWidgetContext(widgetName, defaultProps) as any}) as any;
defaultProps?: Partial<WidgetProps<W>>
): [WidgetState<W>, W] => useWidget(factory, props, {config: useWidgetContext(widgetName, defaultProps)});
17 changes: 16 additions & 1 deletion svelte/headless/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,62 @@ import Slot from './Slot.svelte';
export * from './utils';
export type {SlotContent, WidgetsConfig} from './utils';

import type {WidgetProps, WidgetState} from '@agnos-ui/core';
import type {PropsConfig, WidgetFactory, WidgetProps, WidgetState} from '@agnos-ui/core';
import type {AdaptSlotContentProps, AdaptWidgetSlots, WidgetPropsSlots} from './utils';

export type AccordionWidget = AdaptWidgetSlots<import('@agnos-ui/core').AccordionWidget>;
export type AccordionProps = WidgetProps<AccordionWidget>;
export type AccordionState = WidgetState<AccordionWidget>;
export type AccordionApi = AccordionWidget['api'];
export type AccordionSlots = WidgetPropsSlots<AccordionProps>;
export type AccordionItemWidget = AdaptWidgetSlots<import('@agnos-ui/core').AccordionItemWidget>;
export type AccordionItemProps = WidgetProps<AccordionItemWidget>;
export type AccordionItemState = WidgetState<AccordionItemWidget>;
export type AccordionItemContext = AdaptSlotContentProps<import('@agnos-ui/core').AccordionItemContext>;
import {createAccordion as coreCreateAccordion} from '@agnos-ui/core';
export const createAccordion: WidgetFactory<AccordionWidget> = coreCreateAccordion as any;

export type AlertWidget = AdaptWidgetSlots<import('@agnos-ui/core').AlertWidget>;
export type AlertProps = WidgetProps<AlertWidget>;
export type AlertState = WidgetState<AlertWidget>;
export type AlertSlots = WidgetPropsSlots<AlertProps>;
import {createAlert as coreCreateAlert} from '@agnos-ui/core';
export const createAlert: WidgetFactory<AlertWidget> = coreCreateAlert as any;

export type ModalWidget = AdaptWidgetSlots<import('@agnos-ui/core').ModalWidget>;
export type ModalProps = WidgetProps<ModalWidget>;
export type ModalState = WidgetState<ModalWidget>;
export type ModalContext = AdaptSlotContentProps<import('@agnos-ui/core').ModalContext>;
export type ModalSlots = WidgetPropsSlots<ModalProps>;
import {createModal as coreCreateModal} from '@agnos-ui/core';
export const createModal: WidgetFactory<ModalWidget> = coreCreateModal as any;

export type PaginationWidget = AdaptWidgetSlots<import('@agnos-ui/core').PaginationWidget>;
export type PaginationProps = WidgetProps<PaginationWidget>;
export type PaginationState = WidgetState<PaginationWidget>;
export type PaginationContext = AdaptSlotContentProps<import('@agnos-ui/core').PaginationContext>;
export type PaginationNumberContext = AdaptSlotContentProps<import('@agnos-ui/core').PaginationNumberContext>;
export type PaginationSlots = WidgetPropsSlots<PaginationProps>;
import {createPagination as coreCreatePagination} from '@agnos-ui/core';
export const createPagination: WidgetFactory<PaginationWidget> = coreCreatePagination as any;

export type RatingWidget = AdaptWidgetSlots<import('@agnos-ui/core').RatingWidget>;
export type RatingProps = WidgetProps<RatingWidget>;
export type RatingState = WidgetState<RatingWidget>;
export type RatingSlots = WidgetPropsSlots<RatingProps>;
import {createRating as coreCreateRating} from '@agnos-ui/core';
export const createRating: WidgetFactory<RatingWidget> = coreCreateRating as any;

export type SelectWidget<Item> = AdaptWidgetSlots<import('@agnos-ui/core').SelectWidget<Item>>;
export type SelectProps<Item> = WidgetProps<SelectWidget<Item>>;
export type SelectState<Item> = WidgetState<SelectWidget<Item>>;
export type SelectSlots<Item> = WidgetPropsSlots<SelectProps<Item>>;
import {createSelect as coreCreateSelect} from '@agnos-ui/core';
export const createSelect: <Item>(propsConfig?: PropsConfig<SelectProps<Item>>) => SelectWidget<Item> = coreCreateSelect as any;

export type ProgressbarWidget = AdaptWidgetSlots<import('@agnos-ui/core').ProgressbarWidget>;
export type ProgressbarProps = WidgetProps<ProgressbarWidget>;
export type ProgressbarState = WidgetState<ProgressbarWidget>;
export type ProgressbarSlots = WidgetPropsSlots<ProgressbarProps>;
import {createProgressbar as coreCreateProgressbar} from '@agnos-ui/core';
export const createProgressbar: WidgetFactory<ProgressbarWidget> = coreCreateProgressbar as any;
13 changes: 8 additions & 5 deletions svelte/headless/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,9 @@ const getContextWidgetConfig = <Props extends object>(
export const callWidgetFactory = <W extends Widget>(
factory: WidgetFactory<W>,
widgetName: keyof WidgetsConfig | null,
slots: SlotsPresent<WidgetProps<AdaptWidgetSlots<W>>>,
defaultConfig?: Partial<WidgetProps<AdaptWidgetSlots<W>>>
): AdaptWidgetSlots<W> & {patchChangedProps: AdaptWidgetSlots<W>['patch']} =>
withPatchChangedProps(factory({config: getContextWidgetConfig(widgetName, slots, defaultConfig)}) as any);
slots: SlotsPresent<WidgetProps<W>>,
defaultConfig?: Partial<WidgetProps<W>>
): W & {patchChangedProps: W['patch']} => withPatchChangedProps(factory({config: getContextWidgetConfig(widgetName, slots, defaultConfig)}) as any);

export const useSvelteSlot = Symbol('useSvelteSlot');

Expand All @@ -142,10 +141,14 @@ export type WidgetsConfig = {
[WidgetName in keyof CoreWidgetsConfig]: AdaptPropsSlots<CoreWidgetsConfig[WidgetName]>;
};

export type AdaptWidgetFactories<T> = {
[K in keyof T]: T[K] extends WidgetFactory<infer U> ? WidgetFactory<AdaptWidgetSlots<U>> : T[K];
};

export type AdaptWidgetSlots<W extends Widget> = Widget<
AdaptPropsSlots<WidgetProps<W>>,
AdaptPropsSlots<WidgetState<W>>,
W['api'],
AdaptWidgetFactories<W['api']>,
W['actions'],
W['directives']
>;
Expand Down

0 comments on commit 70ab1d0

Please sign in to comment.