@jswork/react-render-controls 1.2.0 → 1.2.2
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/dist/main.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/feizheng/github/react-render-controls/packages/lib/dist/main.cjs.js","../src/render-list/index.tsx","../src/shared/env.ts","../src/render-list/render-list.utils.ts"],"names":["_a","isDev","process","env","NODE_ENV","isRenderFn","render","getKey","item","index","items","keyBy","undefined","value","console","warn","String","JSON","stringify"],"mappings":"AAAA,6KAAI,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CCA3d,4EAAkB,ICAlBA,CAAAA,CAGaC,CAAAA,CACX,OAAOC,OAAAA,EAAY,WAAA,EAAA,CAAA,CAAeA,CAAAA,CAAAA,OAAAA,CAAQC,GAAAA,CAAAA,EAARD,IAAAA,CAAAA,KAAAA,CAAAA,CAAAA,CAAAA,CAAaE,QAAAA,CAAAA,GAAa,YAAA,CCEvD,SAASC,CAAAA,CAAcC,CAAAA,CAAqB,CACjD,OAAO,OAAOA,CAAAA,EAAW,UAC3B,CAFgBD,CAAAA,CAAAA,CAAAA,CAAAA,YAAAA,CAAAA,
|
|
1
|
+
{"version":3,"sources":["/Users/feizheng/github/react-render-controls/packages/lib/dist/main.cjs.js","../src/render-list/index.tsx","../src/shared/env.ts","../src/render-list/render-list.utils.ts"],"names":["_a","isDev","process","env","NODE_ENV","isRenderFn","render","getKey","item","index","items","keyBy","undefined","value","console","warn","String","JSON","stringify"],"mappings":"AAAA,6KAAI,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CCA3d,4EAAkB,ICAlBA,CAAAA,CAGaC,CAAAA,CACX,OAAOC,OAAAA,EAAY,WAAA,EAAA,CAAA,CAAeA,CAAAA,CAAAA,OAAAA,CAAQC,GAAAA,CAAAA,EAARD,IAAAA,CAAAA,KAAAA,CAAAA,CAAAA,CAAAA,CAAaE,QAAAA,CAAAA,GAAa,YAAA,CCEvD,SAASC,CAAAA,CAAcC,CAAAA,CAAqB,CACjD,OAAO,OAAOA,CAAAA,EAAW,UAC3B,CAFgBD,CAAAA,CAAAA,CAAAA,CAAAA,YAAAA,CAAAA,CAWT,SAASE,CAAAA,CACdC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CAA2B,CAE3B,EAAA,CAAIA,CAAAA,GAAUC,KAAAA,CAAAA,CACZ,OAAOH,CAAAA,CAGT,EAAA,CAAI,OAAOE,CAAAA,EAAU,UAAA,CACnB,OAAOA,CAAAA,CAAMH,CAAAA,CAAMC,CAAAA,CAAOC,CAAAA,CAAAA,CAG5B,IAAMG,CAAAA,CAASL,CAAAA,CAAiCG,CAAAA,CAAAA,CAChD,OAA2BE,CAAAA,EAAU,IAAA,CAAA,CAC/BZ,CAAAA,EACFa,OAAAA,CAAQC,IAAAA,CACN,CAAA,mBAAA,EAAsBC,MAAAA,CAAOL,CAAAA,CAAAA,CAAAA,gCAAAA,EAAyCM,IAAAA,CAAKC,SAAAA,CAAUV,CAAAA,CAAAA,CAAAA,CAAAA","file":"/Users/feizheng/github/react-render-controls/packages/lib/dist/main.cjs.js","sourcesContent":[null,"import React from 'react';\nimport type { RenderListProps } from './render-list.type';\nimport { isRenderFn, getKey } from './render-list.utils';\n\n/**\n * RenderList - Recommended list component\n *\n * @example Function style\n * ```tsx\n * <RenderList\n * items={users}\n * render={(user) => <UserCard user={user} />}\n * keyBy=\"id\"\n * />\n * ```\n *\n * @example Component style\n * ```tsx\n * <RenderList\n * items={users}\n * render={{\n * component: UserCard,\n * dataKey: \"user\",\n * props: { variant: 'compact' }\n * }}\n * keyBy=\"id\"\n * />\n * ```\n */\nexport default function RenderList<T>({ items, render, keyBy }: RenderListProps<T>) {\n return (\n <>\n {items.map((item, index) => {\n const key = getKey(item, index, items, keyBy);\n\n // If render is a function, call it directly\n if (isRenderFn(render)) {\n return <React.Fragment key={key}>{render(item, index, items)}</React.Fragment>;\n }\n\n // If render is component config, wrap props automatically\n const { component: Component, dataKey = 'item', props = {} } = render;\n const componentProps = {\n ...props,\n [dataKey]: item,\n };\n\n return (\n <React.Fragment key={key}>\n <Component {...componentProps} />\n </React.Fragment>\n );\n })}\n </>\n );\n}\n","/**\n * Check if running in development mode\n */\nexport const isDev =\n typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production';\n\n","import type { RenderProp, RenderFn, KeyBy } from './render-list.type';\nimport { isDev } from '../shared/env';\n\n/**\n * Type guard: check if render is a function type\n */\nexport function isRenderFn<T>(render: RenderProp<T>): render is RenderFn<T> {\n return typeof render === 'function';\n}\n\n/**\n * Get the unique key for a list item\n * @param item The list item\n * @param index The index of the item in the list\n * @param items The list of items\n * @param keyBy The keyBy function or field name to get the key from the item\n */\nexport function getKey<T>(\n item: T,\n index: number,\n items: readonly T[],\n keyBy: KeyBy<T> | undefined,\n): string | number {\n if (keyBy === undefined) {\n return index;\n }\n\n if (typeof keyBy === 'function') {\n return keyBy(item, index, items);\n }\n\n const value = (item as Record<string, unknown>)[keyBy as string];\n if (value === undefined || value === null) {\n if (isDev) {\n console.warn(\n `RenderList: keyBy=\"${String(keyBy)}\" but the field is undefined in ${JSON.stringify(item)}`,\n );\n }\n return index;\n }\n\n return value as string | number;\n}\n"]}
|
package/dist/main.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/render-list/index.tsx","../src/shared/env.ts","../src/render-list/render-list.utils.ts","../src/render-if/index.tsx","../src/render-match/index.tsx","../src/render-match/render-match.utils.ts","../src/render-switch/index.tsx","../src/render-switch/render-switch.utils.ts"],"sourcesContent":["import React from 'react';\nimport type { RenderListProps } from './render-list.type';\nimport { isRenderFn, getKey } from './render-list.utils';\n\n/**\n * RenderList - Recommended list component\n *\n * @example Function style\n * ```tsx\n * <RenderList\n * items={users}\n * render={(user) => <UserCard user={user} />}\n * keyBy=\"id\"\n * />\n * ```\n *\n * @example Component style\n * ```tsx\n * <RenderList\n * items={users}\n * render={{\n * component: UserCard,\n * dataKey: \"user\",\n * props: { variant: 'compact' }\n * }}\n * keyBy=\"id\"\n * />\n * ```\n */\nexport default function RenderList<T>({ items, render, keyBy }: RenderListProps<T>) {\n return (\n <>\n {items.map((item, index) => {\n const key = getKey(item, index, items, keyBy);\n\n // If render is a function, call it directly\n if (isRenderFn(render)) {\n return <React.Fragment key={key}>{render(item, index, items)}</React.Fragment>;\n }\n\n // If render is component config, wrap props automatically\n const { component: Component, dataKey = 'item', props = {} } = render;\n const componentProps = {\n ...props,\n [dataKey]: item,\n };\n\n return (\n <React.Fragment key={key}>\n <Component {...componentProps} />\n </React.Fragment>\n );\n })}\n </>\n );\n}\n","/**\n * Check if running in development mode\n */\nexport const isDev =\n typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production';\n\n","import type { RenderProp, RenderFn, KeyBy } from './render-list.type';\nimport { isDev } from '../shared/env';\n\n/**\n * Type guard: check if render is a function type\n */\nexport function isRenderFn<T>(render: RenderProp<T>): render is RenderFn<T> {\n return typeof render === 'function';\n}\n\n/**\n * Get the unique key for a list item\n */\nexport function getKey<T>(\n item: T,\n index: number,\n items: readonly T[],\n keyBy: KeyBy<T> | undefined,\n): string | number {\n if (keyBy === undefined) {\n return index;\n }\n\n if (typeof keyBy === 'function') {\n return keyBy(item, index, items);\n }\n\n const value = (item as Record<string, unknown>)[keyBy as string];\n if (value === undefined || value === null) {\n if (isDev) {\n console.warn(\n `RenderList: keyBy=\"${String(keyBy)}\" but the field is undefined in ${JSON.stringify(item)}`,\n );\n }\n return index;\n }\n\n return value as string | number;\n}\n","import { Children } from 'react';\nimport type { RenderIfProps } from './render-if.type';\nimport { isDev } from '../shared/env';\n\n/**\n * RenderIf - Conditional rendering component\n *\n * @example Single child (render when true, nothing when false)\n * ```tsx\n * <RenderIf when={isLoggedIn}>\n * <Dashboard />\n * </RenderIf>\n * ```\n *\n * @example Two children (if/else pattern)\n * ```tsx\n * <RenderIf when={isLoggedIn}>\n * <Dashboard />\n * <Login />\n * </RenderIf>\n * ```\n */\nexport function RenderIf({ when, children }: RenderIfProps) {\n const childArray = Children.toArray(children);\n\n if (childArray.length === 0) {\n return null;\n }\n\n if (childArray.length > 2) {\n if (isDev) {\n console.warn(\n `RenderIf: Expected at most 2 children, but got ${childArray.length}. Only the first 2 children will be used.`\n );\n }\n }\n\n if (childArray.length === 1) {\n return when ? childArray[0] : null;\n }\n\n // length >= 2: first child for true, second for false\n return when ? childArray[0] : childArray[1];\n}\n\nexport default RenderIf;\n","import { Children, isValidElement, type ReactElement } from 'react';\nimport type { RenderMatchProps } from './render-match.type';\nimport { findMatchIndex, getAllValues } from './render-match.utils';\nimport { isDev } from '../shared/env';\n\n/**\n * RenderMatch - Match value against items and render corresponding child\n *\n * @example Basic usage\n * ```tsx\n * <RenderMatch value=\"success\" items={['pending', 'success', 'error']}>\n * <PendingState />\n * <SuccessState />\n * <ErrorState />\n * </RenderMatch>\n * ```\n *\n * @example With array values (multiple values map to same child)\n * ```tsx\n * <RenderMatch\n * value=\"processing\"\n * items={[['pending', 'processing'], 'success', 'error']}\n * >\n * <LoadingState />\n * <SuccessState />\n * <ErrorState />\n * </RenderMatch>\n * ```\n */\nexport function RenderMatch<T extends string = string>({\n value,\n items,\n children,\n}: RenderMatchProps<T>) {\n // Find the matched slot index\n const matchedIndex = findMatchIndex(value, items);\n\n if (matchedIndex === -1) {\n if (isDev) {\n const allValues = getAllValues(items);\n console.warn(\n `RenderMatch: Value \"${value}\" not found in any of the items. Available values: [${allValues.join(', ')}]`\n );\n }\n return null;\n }\n\n const validChildren = Children.toArray(children).filter(\n (child): child is ReactElement => isValidElement(child)\n );\n\n if (matchedIndex >= validChildren.length) {\n if (isDev) {\n console.warn(\n `RenderMatch: Not enough children provided. Expected at least ${matchedIndex + 1}, but got ${validChildren.length}.`\n );\n }\n return null;\n }\n\n return validChildren[matchedIndex] ?? null;\n}\n\nexport default RenderMatch;\n","import type { MatchValue } from './render-match.type';\n\n/**\n * Find the index of the item that matches the value\n * @returns The matched index, or -1 if not found\n */\nexport function findMatchIndex(\n value: string,\n items: readonly MatchValue[]\n): number {\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n if (typeof item === 'string') {\n if (item === value) {\n return i;\n }\n } else {\n // item is string[]\n if (item.includes(value)) {\n return i;\n }\n }\n }\n return -1;\n}\n\n/**\n * Get all possible values from items (flatten string arrays)\n */\nexport function getAllValues(items: readonly MatchValue[]): string[] {\n const result: string[] = [];\n for (const item of items) {\n if (typeof item === 'string') {\n result.push(item);\n } else {\n result.push(...item);\n }\n }\n return result;\n}\n","import { Children, isValidElement, type ReactElement } from 'react';\nimport type { RenderSwitchProps } from './render-switch.type';\nimport { findTrueCaseIndex, validateCasesLength } from './render-switch.utils';\n\n/**\n * RenderSwitch - Switch-style conditional rendering\n *\n * Renders the first child whose corresponding case condition is true.\n * If none matches, renders `fallback` (or null if not provided).\n *\n * @example Basic usage\n * ```tsx\n * <RenderSwitch cases={[isLoading, isError, isSuccess]}>\n * <LoadingSpinner />\n * <ErrorDisplay />\n * <SuccessMessage />\n * </RenderSwitch>\n * ```\n *\n * @example With fallback\n * ```tsx\n * <RenderSwitch\n * cases={[isAdmin, isModerator]}\n * fallback={<AccessDenied />}\n * >\n * <AdminPanel />\n * <ModeratorPanel />\n * </RenderSwitch>\n * ```\n */\nexport function RenderSwitch({\n cases,\n children,\n fallback = null,\n}: RenderSwitchProps) {\n const childArray = Children.toArray(children).filter(\n (child): child is ReactElement => isValidElement(child)\n );\n\n validateCasesLength(cases.length, childArray.length, 'RenderSwitch');\n\n const matchedIndex = findTrueCaseIndex(cases);\n\n // Check if the matched index is within the children bounds\n if (matchedIndex >= 0 && matchedIndex < childArray.length) {\n return childArray[matchedIndex];\n }\n\n return fallback;\n}\n\nexport default RenderSwitch;\n","import { isDev } from '../shared/env';\n\n/**\n * Find the index of the first true case\n * @returns The index of the first true case, or -1 if none are true\n */\nexport function findTrueCaseIndex(cases: readonly boolean[]): number {\n for (let i = 0; i < cases.length; i++) {\n if (cases[i]) {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * Validate that the number of cases matches the number of children\n */\nexport function validateCasesLength(\n casesLength: number,\n childrenLength: number,\n componentName: string\n): void {\n if (isDev && casesLength > childrenLength) {\n console.warn(\n `${componentName}: More cases (${casesLength}) than children (${childrenLength}). Extra cases will be ignored.`\n );\n }\n}\n"],"mappings":"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","names":["React","_a","isDev","process","env","NODE_ENV","isRenderFn","render","getKey","item","index","items","keyBy","undefined","value","isDev","console","warn","String","JSON","stringify","RenderList","items","render","keyBy","React","map","item","index","key","getKey","isRenderFn","Fragment","component","Component","dataKey","props","componentProps","__spreadProps","__spreadValues","Children","RenderIf","when","children","childArray","Children","toArray","length","isDev","console","warn","render_if_default","Children","isValidElement","findMatchIndex","value","items","i","length","item","includes","getAllValues","result","push","RenderMatch","value","items","children","_a","matchedIndex","findMatchIndex","isDev","allValues","getAllValues","console","warn","join","validChildren","Children","toArray","filter","child","isValidElement","length","render_match_default","Children","isValidElement","findTrueCaseIndex","cases","i","length","validateCasesLength","casesLength","childrenLength","componentName","isDev","console","warn","RenderSwitch","cases","children","fallback","childArray","Children","toArray","filter","child","isValidElement","validateCasesLength","length","matchedIndex","findTrueCaseIndex","render_switch_default"]}
|
|
1
|
+
{"version":3,"sources":["../src/render-list/index.tsx","../src/shared/env.ts","../src/render-list/render-list.utils.ts","../src/render-if/index.tsx","../src/render-match/index.tsx","../src/render-match/render-match.utils.ts","../src/render-switch/index.tsx","../src/render-switch/render-switch.utils.ts"],"sourcesContent":["import React from 'react';\nimport type { RenderListProps } from './render-list.type';\nimport { isRenderFn, getKey } from './render-list.utils';\n\n/**\n * RenderList - Recommended list component\n *\n * @example Function style\n * ```tsx\n * <RenderList\n * items={users}\n * render={(user) => <UserCard user={user} />}\n * keyBy=\"id\"\n * />\n * ```\n *\n * @example Component style\n * ```tsx\n * <RenderList\n * items={users}\n * render={{\n * component: UserCard,\n * dataKey: \"user\",\n * props: { variant: 'compact' }\n * }}\n * keyBy=\"id\"\n * />\n * ```\n */\nexport default function RenderList<T>({ items, render, keyBy }: RenderListProps<T>) {\n return (\n <>\n {items.map((item, index) => {\n const key = getKey(item, index, items, keyBy);\n\n // If render is a function, call it directly\n if (isRenderFn(render)) {\n return <React.Fragment key={key}>{render(item, index, items)}</React.Fragment>;\n }\n\n // If render is component config, wrap props automatically\n const { component: Component, dataKey = 'item', props = {} } = render;\n const componentProps = {\n ...props,\n [dataKey]: item,\n };\n\n return (\n <React.Fragment key={key}>\n <Component {...componentProps} />\n </React.Fragment>\n );\n })}\n </>\n );\n}\n","/**\n * Check if running in development mode\n */\nexport const isDev =\n typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production';\n\n","import type { RenderProp, RenderFn, KeyBy } from './render-list.type';\nimport { isDev } from '../shared/env';\n\n/**\n * Type guard: check if render is a function type\n */\nexport function isRenderFn<T>(render: RenderProp<T>): render is RenderFn<T> {\n return typeof render === 'function';\n}\n\n/**\n * Get the unique key for a list item\n * @param item The list item\n * @param index The index of the item in the list\n * @param items The list of items\n * @param keyBy The keyBy function or field name to get the key from the item\n */\nexport function getKey<T>(\n item: T,\n index: number,\n items: readonly T[],\n keyBy: KeyBy<T> | undefined,\n): string | number {\n if (keyBy === undefined) {\n return index;\n }\n\n if (typeof keyBy === 'function') {\n return keyBy(item, index, items);\n }\n\n const value = (item as Record<string, unknown>)[keyBy as string];\n if (value === undefined || value === null) {\n if (isDev) {\n console.warn(\n `RenderList: keyBy=\"${String(keyBy)}\" but the field is undefined in ${JSON.stringify(item)}`,\n );\n }\n return index;\n }\n\n return value as string | number;\n}\n","import { Children } from 'react';\nimport type { RenderIfProps } from './render-if.type';\nimport { isDev } from '../shared/env';\n\n/**\n * RenderIf - Conditional rendering component\n *\n * @example Single child (render when true, nothing when false)\n * ```tsx\n * <RenderIf when={isLoggedIn}>\n * <Dashboard />\n * </RenderIf>\n * ```\n *\n * @example Two children (if/else pattern)\n * ```tsx\n * <RenderIf when={isLoggedIn}>\n * <Dashboard />\n * <Login />\n * </RenderIf>\n * ```\n */\nexport function RenderIf({ when, children }: RenderIfProps) {\n const childArray = Children.toArray(children);\n\n if (childArray.length === 0) {\n return null;\n }\n\n if (childArray.length > 2) {\n if (isDev) {\n console.warn(\n `RenderIf: Expected at most 2 children, but got ${childArray.length}. Only the first 2 children will be used.`\n );\n }\n }\n\n if (childArray.length === 1) {\n return when ? childArray[0] : null;\n }\n\n // length >= 2: first child for true, second for false\n return when ? childArray[0] : childArray[1];\n}\n\nexport default RenderIf;\n","import { Children, isValidElement, type ReactElement } from 'react';\nimport type { RenderMatchProps } from './render-match.type';\nimport { findMatchIndex, getAllValues } from './render-match.utils';\nimport { isDev } from '../shared/env';\n\n/**\n * RenderMatch - Match value against items and render corresponding child\n *\n * @example Basic usage\n * ```tsx\n * <RenderMatch value=\"success\" items={['pending', 'success', 'error']}>\n * <PendingState />\n * <SuccessState />\n * <ErrorState />\n * </RenderMatch>\n * ```\n *\n * @example With array values (multiple values map to same child)\n * ```tsx\n * <RenderMatch\n * value=\"processing\"\n * items={[['pending', 'processing'], 'success', 'error']}\n * >\n * <LoadingState />\n * <SuccessState />\n * <ErrorState />\n * </RenderMatch>\n * ```\n */\nexport function RenderMatch<T extends string = string>({\n value,\n items,\n children,\n}: RenderMatchProps<T>) {\n // Find the matched slot index\n const matchedIndex = findMatchIndex(value, items);\n\n if (matchedIndex === -1) {\n if (isDev) {\n const allValues = getAllValues(items);\n console.warn(\n `RenderMatch: Value \"${value}\" not found in any of the items. Available values: [${allValues.join(', ')}]`\n );\n }\n return null;\n }\n\n const validChildren = Children.toArray(children).filter(\n (child): child is ReactElement => isValidElement(child)\n );\n\n if (matchedIndex >= validChildren.length) {\n if (isDev) {\n console.warn(\n `RenderMatch: Not enough children provided. Expected at least ${matchedIndex + 1}, but got ${validChildren.length}.`\n );\n }\n return null;\n }\n\n return validChildren[matchedIndex] ?? null;\n}\n\nexport default RenderMatch;\n","import type { MatchValue } from './render-match.type';\n\n/**\n * Find the index of the item that matches the value\n * @param items The items to search in\n * @param value The value to match\n * @returns The matched index, or -1 if not found\n */\nexport function findMatchIndex(\n value: string,\n items: readonly MatchValue[]\n): number {\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n if (typeof item === 'string') {\n if (item === value) {\n return i;\n }\n } else {\n // item is string[]\n if (item.includes(value)) {\n return i;\n }\n }\n }\n return -1;\n}\n\n/**\n * Get all possible values from items (flatten string arrays)\n * @param items The items to get values from\n * @returns The flattened string array of all values\n */\nexport function getAllValues(items: readonly MatchValue[]): string[] {\n const result: string[] = [];\n for (const item of items) {\n if (typeof item === 'string') {\n result.push(item);\n } else {\n result.push(...item);\n }\n }\n return result;\n}\n","import { Children, isValidElement, type ReactElement } from 'react';\nimport type { RenderSwitchProps } from './render-switch.type';\nimport { findTrueCaseIndex, validateCasesLength } from './render-switch.utils';\n\n/**\n * RenderSwitch - Switch-style conditional rendering\n *\n * Renders the first child whose corresponding case condition is true.\n * If none matches, renders `fallback` (or null if not provided).\n *\n * @example Basic usage\n * ```tsx\n * <RenderSwitch cases={[isLoading, isError, isSuccess]}>\n * <LoadingSpinner />\n * <ErrorDisplay />\n * <SuccessMessage />\n * </RenderSwitch>\n * ```\n *\n * @example With fallback\n * ```tsx\n * <RenderSwitch\n * cases={[isAdmin, isModerator]}\n * fallback={<AccessDenied />}\n * >\n * <AdminPanel />\n * <ModeratorPanel />\n * </RenderSwitch>\n * ```\n */\nexport function RenderSwitch({\n cases,\n children,\n fallback = null,\n}: RenderSwitchProps) {\n const childArray = Children.toArray(children).filter(\n (child): child is ReactElement => isValidElement(child)\n );\n\n validateCasesLength(cases.length, childArray.length, 'RenderSwitch');\n\n const matchedIndex = findTrueCaseIndex(cases);\n\n // Check if the matched index is within the children bounds\n if (matchedIndex >= 0 && matchedIndex < childArray.length) {\n return childArray[matchedIndex];\n }\n\n return fallback;\n}\n\nexport default RenderSwitch;\n","import { isDev } from '../shared/env';\n\n/**\n * Find the index of the first true case\n * @param cases An array of boolean values\n * @returns The index of the first true case, or -1 if none are true\n */\nexport function findTrueCaseIndex(cases: readonly boolean[]): number {\n for (let i = 0; i < cases.length; i++) {\n if (cases[i]) {\n return i;\n }\n }\n return -1;\n}\n\n/**\n * Validate that the number of cases matches the number of children\n * @param casesLength The number of cases\n * @param childrenLength The number of children\n * @param componentName The name of the component\n * @throws An error if the number of cases is greater than the number of children\n * @returns void\n */\nexport function validateCasesLength(\n casesLength: number,\n childrenLength: number,\n componentName: string\n): void {\n if (isDev && casesLength > childrenLength) {\n console.warn(\n `${componentName}: More cases (${casesLength}) than children (${childrenLength}). Extra cases will be ignored.`\n );\n }\n}\n"],"mappings":"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","names":["React","_a","isDev","process","env","NODE_ENV","isRenderFn","render","getKey","item","index","items","keyBy","undefined","value","isDev","console","warn","String","JSON","stringify","RenderList","items","render","keyBy","React","map","item","index","key","getKey","isRenderFn","Fragment","component","Component","dataKey","props","componentProps","__spreadProps","__spreadValues","Children","RenderIf","when","children","childArray","Children","toArray","length","isDev","console","warn","render_if_default","Children","isValidElement","findMatchIndex","value","items","i","length","item","includes","getAllValues","result","push","RenderMatch","value","items","children","_a","matchedIndex","findMatchIndex","isDev","allValues","getAllValues","console","warn","join","validChildren","Children","toArray","filter","child","isValidElement","length","render_match_default","Children","isValidElement","findTrueCaseIndex","cases","i","length","validateCasesLength","casesLength","childrenLength","componentName","isDev","console","warn","RenderSwitch","cases","children","fallback","childArray","Children","toArray","filter","child","isValidElement","validateCasesLength","length","matchedIndex","findTrueCaseIndex","render_switch_default"]}
|
package/package.json
CHANGED
|
@@ -10,6 +10,10 @@ export function isRenderFn<T>(render: RenderProp<T>): render is RenderFn<T> {
|
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Get the unique key for a list item
|
|
13
|
+
* @param item The list item
|
|
14
|
+
* @param index The index of the item in the list
|
|
15
|
+
* @param items The list of items
|
|
16
|
+
* @param keyBy The keyBy function or field name to get the key from the item
|
|
13
17
|
*/
|
|
14
18
|
export function getKey<T>(
|
|
15
19
|
item: T,
|
|
@@ -2,6 +2,8 @@ import type { MatchValue } from './render-match.type';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Find the index of the item that matches the value
|
|
5
|
+
* @param items The items to search in
|
|
6
|
+
* @param value The value to match
|
|
5
7
|
* @returns The matched index, or -1 if not found
|
|
6
8
|
*/
|
|
7
9
|
export function findMatchIndex(
|
|
@@ -26,6 +28,8 @@ export function findMatchIndex(
|
|
|
26
28
|
|
|
27
29
|
/**
|
|
28
30
|
* Get all possible values from items (flatten string arrays)
|
|
31
|
+
* @param items The items to get values from
|
|
32
|
+
* @returns The flattened string array of all values
|
|
29
33
|
*/
|
|
30
34
|
export function getAllValues(items: readonly MatchValue[]): string[] {
|
|
31
35
|
const result: string[] = [];
|
|
@@ -2,6 +2,7 @@ import { isDev } from '../shared/env';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Find the index of the first true case
|
|
5
|
+
* @param cases An array of boolean values
|
|
5
6
|
* @returns The index of the first true case, or -1 if none are true
|
|
6
7
|
*/
|
|
7
8
|
export function findTrueCaseIndex(cases: readonly boolean[]): number {
|
|
@@ -15,6 +16,11 @@ export function findTrueCaseIndex(cases: readonly boolean[]): number {
|
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Validate that the number of cases matches the number of children
|
|
19
|
+
* @param casesLength The number of cases
|
|
20
|
+
* @param childrenLength The number of children
|
|
21
|
+
* @param componentName The name of the component
|
|
22
|
+
* @throws An error if the number of cases is greater than the number of children
|
|
23
|
+
* @returns void
|
|
18
24
|
*/
|
|
19
25
|
export function validateCasesLength(
|
|
20
26
|
casesLength: number,
|
package/src/style.scss
DELETED