@multinite_official/multiui
Version:
The first and only Component Framework.
241 lines • 9.1 kB
JavaScript
;
// import { ForwardedRef, HTMLAttributes, ReactNode } from "react";
// // import type { cn as cn_, __seperateClasses } from "../utils/cn";
// /**
// * Represents a chain of variants for component slots.
// */
// export type VariantChain<Slots extends Record<string, Record<string, any>>> = {
// createChainedVariant: CreateVariantFromChainedVariant<Slots, keyof Slots>;
// };
// /**
// * Type for creating a chained variant from an existing variant.
// */
// export type CreateVariantFromChainedVariant<
// Slots extends Record<string, Record<string, any>>,
// Slot extends keyof Slots,
// > = (args: {
// name: string;
// create: (
// props: Slots[Slot],
// chainedVariantClasses: string,
// cn: typeof cn_
// ) => string;
// }) => VariantChain<Slots>;
// /**
// * Type for creating a new variant function.
// */
// export type CreateVariantFn<
// Slots extends Record<string, Record<string, any>>,
// Slot extends keyof Slots,
// > = (args: {
// slot: Slot;
// name: string;
// create: (props: Slots[Slot], cn: typeof cn_) => string;
// }) => VariantChain<Slots>;
// /**
// * # Creates a new MultiUI component
// * Allows you to create a MultiUI component with customizable slots, variants and other features.
// *
// * ```tsx
// * // Make sure to add some JSDoc to your component.
// * const Component = createComponent("component_name", ({ props, createSlot, classNameSeperator }) => {
// * return (
// * <div className={classNameSeperator((cn) => [cn("bg-red-500"), cn("bg-blue-500")])} {...props}>
// * {props.children}
// * </div>
// * );
// * });
// *
// * export default Component;
// * ```
// *
// * @template ComponentProps - The props for the component.
// * @template Slots
// * ### ───────────────────────────
// * # Slots
// * Define the component's slots using an object structure. Each key represents a slot name,
// * and its corresponding value is an object containing all the properties that can be
// * passed to the variants when creating a variant for that slot.
// *
// * ```tsx
// * type MyComponentSlots = {
// * ㅤㅤbase: { // Defining the slot named `base`
// * ㅤㅤㅤㅤisDisabled: boolean; // The props that can be passed for the creation of the variant.
// * ㅤㅤㅤㅤisOpen: boolean;
// * ㅤㅤㅤㅤisHovering: boolean;
// * ㅤㅤ},
// * ㅤㅤ// ... rest of the slots
// * }
// *
// * const createMyComponent = createComponent<MyComponentProps, MyComponentSlots, HTMLButtonElement>(my_component_name, ({ props }) => {
// * ㅤㅤ// ... rest of the component
// * })
// * ```
// * ### ──────────────���────────────
// * @template Element - The HTML element type for the component.
// * @param {string} componentName - The name of the component.
// * @param {Function} create - Function to create the component structure.
// * @returns The created Component.
// */
// export type CreateComponentFn = <
// ComponentProps,
// Element extends HTMLElement = HTMLElement,
// >(args: {
// /**
// * The name of the component.
// */
// componentName: string;
// /**
// * The function to create the component structure.
// * ### ───────────────────────────
// * # Component Structure
// * 1. The component structure is created by passing a function to the createComponent function.
// * 2. This function is called with the `props` and the `createSlot` function, and others.
// * 3. The `createSlot` function is used to create a slot for the component to later be styled with variants.
// * 4. The component structure is then returned by the function.
// * ### ───────────────────────────
// *
// */
// create: (props: {
// /**
// * The props passed to the component.
// */
// props: ComponentProps & {
// ref: ForwardedRef<Element>;
// } & HTMLAttributes<Element>;
// /**
// * Slots define the structural components of a UI element.
// * ### ㅤㅤ
// * For example, a popout component might have the following slots:
// * - `base`: The wrapper for the entire popout (always present)
// * - `content`: The main content area of the popout
// * - `trigger`: The element that activates the popout
// *
// * Each slot can be styled and configured independently, allowing for
// * flexible and modular component design.
// * ### ㅤㅤ
// * @example
// * ```tsx
// * createSlot({
// * // The slot is the name of the slot to be created.
// * slot: "the_name_of_the_slot",
// * // The styling_args are the arguments that are passed to the createVariant function,
// * // this allows for the creation of the variant to be dynamic.
// * styling_args: {
// * some_variable,
// * some_other_variable,
// * even_a_function,
// * ...
// * },
// * });
// * ```
// * ### ㅤㅤ
// * ### Use this function to create a slot for an element.
// * 
// * ### ㅤㅤ
// * ### ㅤㅤ
// * ### Advance example:
// * 
// * ### ㅤㅤ
// * For more information on slots, see the [slots documentation](https://multiui.org/docs/slots).
// */
// createSlot: <SlotProperties, SlotName extends string>(
// slotName: SlotName
// ) => Record<
// | SlotName
// | `get${UppercaseFirstLetter<SlotName extends string ? SlotName : string>}Classes`,
// SlotName | SlotProperties
// >;
// /**
// * ## Use this function before passing classes to any element.
// * **In short:** It seperates internal classes from user passed classes with a symbol which is pre-defined by MultiUI.
// * ### ───────────────────────────
// * ### Example of what it returns:
// * ```ts
// * const myClasses = "internal hi";
// * const passedClasses = "external";
// * classNameSeperator((cn) => [cn(myClasses), cn(passedClasses)]) // -> "internal hi • external"
// * ```
// * ### ───────────────────────────
// * ### Example usage:
// * ```tsx
// * // The `class` on this div will be: "select-none • bg-blue-500".
// * <div className={classNameSeperator((cn) => [cn("bg-red-500 select-none"), cn("bg-blue-500")])}>
// * Hello, World!
// * </div>
// * // Note: The `bg-blue-500` passed by the user will override the `bg-red-500` that was set internally.
// * ```
// * ### ───────────────────────────
// *
// * @returns The classes to be passed to the element.
// */
// classNameSeperator: typeof __seperateClasses;
// }) => ReactNode;
// }) => (
// cb: (props: {
// props: ComponentProps & {
// ref: ForwardedRef<Element>;
// } & HTMLAttributes<Element>;
// helperFunctions: {};
// }) => ReactNode
// ) => React.ForwardRefExoticComponent<
// ComponentProps & {
// ref: ForwardedRef<Element>;
// } & HTMLAttributes<Element>
// >;
// type UppercaseFirstLetter<T extends string> =
// T extends `${infer First}${infer Rest}` ? `${Uppercase<First>}${Rest}` : T;
// const { test } = (<SlotName extends string>(): {
// test: <SomethingElse>(name: SlotName) => Record<`lol_${SlotName}`, "d">; // Change here
// } => {
// return {
// test: function <SomethingElse>(
// test: SlotName
// ): Record<`lol_${SlotName}`, "d"> {
// // Change here
// //@ts-ignore
// return 1;
// },
// };
// })();
// const ddddddd = test<{
// // ^?
// a: 1;
// }>("hi");
// ddddddd;
// /**
// * This allows you to create slots for your component which in-turn supports variants.
// *
// * ```tsx
// * const {base, getBaseClasses} = createSlot<"Base", {}>("Base");
// * <Button slot={base} className={getBaseClasses()}>Foo</Button>
// * ```
// */
// function createSlot<
// SlotName extends string,
// SlotProps extends Record<string, any>,
// >(
// slotName: SlotName
// ): {
// [K in SlotName]: SlotName;
// } & {
// [K in `get${UppercaseFirstLetter<SlotName>}Classes`]: (
// props: SlotProps
// ) => string;
// } {
// return {
// [slotName]: slotName,
// [`get${capitalize(slotName)}Classes`]: 1,
// } as any;
// }
// function capitalize<T extends string>(s: T): Capitalize<T> {
// return (s.charAt(0).toUpperCase() + s.slice(1)) as Capitalize<T>;
// }
// const test2 = createSlot<
// "base",
// {
// a: 1;
// }
// >("base");
// createSlot<"hi", { 1: 1 }>("hi");
//# sourceMappingURL=createComponentTypes.js.map