@openbytes/ts-react-directives 0.2.0 → 0.2.1

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.
@@ -1 +1,2 @@
1
1
  "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('./index.css');const c=require("react/jsx-runtime"),h=require("react");var t=(e=>(e[e.IfBlockExpected=2001]="IfBlockExpected",e[e.OnlyOneIfBlockExpected=2002]="OnlyOneIfBlockExpected",e[e.OnlyOneElseBlockExpected=2003]="OnlyOneElseBlockExpected",e[e.SwitchBlockExpected=2005]="SwitchBlockExpected",e[e.InvalidIfBlockOrdinal=2004]="InvalidIfBlockOrdinal",e[e.InvalidElseBlockOrdinal=2006]="InvalidElseBlockOrdinal",e[e.InvalidElseIfBlockOrdinal=2007]="InvalidElseIfBlockOrdinal",e[e.InvalidElement=3002]="InvalidElement",e[e.ChildrenExpected=3003]="ChildrenExpected",e))(t||{});const m={[t.IfBlockExpected]:"Missing 'If'",[t.OnlyOneIfBlockExpected]:"Can only have one 'If'",[t.OnlyOneElseBlockExpected]:"Can only have one 'Else'",[t.SwitchBlockExpected]:"'If', 'ElseIf', 'Else' need to be wrapped in 'Switch'",[t.InvalidElseBlockOrdinal]:"Invalid ordinals, 'Else' should be the last",[t.InvalidIfBlockOrdinal]:"Invalid ordinals, 'If' block should be the first",[t.InvalidElseIfBlockOrdinal]:"Invalid ordinals, cannot have 'ElseIf' before 'If'",[t.ChildrenExpected]:"Should at least have one child",[t.InvalidElement]:"Invalid element"},I=({errors:e})=>c.jsx("ol",{className:"trd-error-list",children:e.map((l,n)=>c.jsx("li",{children:m[l]},`${l}-${n}`))}),p=e=>{const l=[];return e.length===0?(l.push(t.ChildrenExpected),l):(e.forEach(n=>{const{displayName:a}=n.type??{};(a===i.displayName||a===f.displayName||a===s.displayName)&&l.push(t.SwitchBlockExpected)}),l)},k=e=>{const l=[],n={};return e.length===0?(l.push(t.ChildrenExpected,t.IfBlockExpected),l):(e.forEach((a,d)=>{const{displayName:o="unknown"}=a.type,u=n[o]??0;n[o]=u+1,v(o,d,n,l),B(o,d,e.length,n,l),y(o,d,l),O(o,l)}),n[i.name]||l.push(t.IfBlockExpected),l)},v=(e,l,n,a)=>{e===i.name&&(l!==0&&a.push(t.InvalidIfBlockOrdinal),n[i.name]>1&&a.push(t.OnlyOneIfBlockExpected))},B=(e,l,n,a,d)=>{e===s.name&&(a[s.name]>1&&d.push(t.OnlyOneElseBlockExpected),(l===0||l!==n-1)&&d.push(t.InvalidElseBlockOrdinal))},y=(e,l,n)=>{e===f.name&&l===0&&n.push(t.InvalidElseIfBlockOrdinal)},O=(e,l)=>{e!==i.name&&e!==f.name&&e!==s.name&&l.push(t.InvalidElement)};class x{static get(l){let n;switch(l){case E.displayName:n=k;break;case i.displayName:case f.displayName:case s.displayName:n=p;break;default:n=()=>[]}return n}}const r=(e,l)=>{const{children:n}=e,a=h.Children.toArray(n);return x.get(l)(a)},S=e=>{const l=r(e,"SwitchIf");if(l.length)return{children:h.createElement(I,{errors:l})};const a=h.Children.toArray(e.children).filter(h.isValidElement);return{children:w(a)}},w=e=>{for(const l of e){if(!l||!h.isValidElement(l))continue;const{displayName:n}=l.type;if(n){const{condition:a}=l.props;if((n==="If"||n==="ElseIf")&&a===!0||n==="Else")return l}}return null},E=e=>{const{children:l}=S(e);return c.jsx(c.Fragment,{children:l})};E.displayName="SwitchIf";const i=e=>{const l=r(e,"If"),{condition:n}=e,a=l.length===0?e.children:c.jsx(I,{errors:l});return c.jsx(c.Fragment,{children:n&&a})};i.displayName="If";const f=e=>{const l=r(e,"ElseIf"),{condition:n}=e,a=l.length===0?e.children:c.jsx(I,{errors:l});return c.jsx(c.Fragment,{children:n&&a})};f.displayName="ElseIf";const s=e=>{const l=r(e,"Else"),n=l.length===0?e.children:c.jsx(I,{errors:l});return c.jsx(c.Fragment,{children:n})};s.displayName="Else";exports.Else=s;exports.ElseIf=f;exports.If=i;exports.SwitchIf=E;
2
+ //# sourceMappingURL=ts-react-directives.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-react-directives.cjs.js","sources":["../src/fixtures/enums.ts","../src/fixtures/constants.ts","../src/components/Errors.tsx","../src/utils/validators.ts","../src/hooks/useValidate.ts","../src/directives/if/SwitchIf.tsx","../src/directives/if/If.tsx","../src/directives/if/ElseIf.tsx","../src/directives/if/Else.tsx"],"sourcesContent":["export enum LogicErrors {\r\n // Switch\r\n IfBlockExpected = 2001,\r\n OnlyOneIfBlockExpected = 2002,\r\n OnlyOneElseBlockExpected = 2003,\r\n SwitchBlockExpected = 2005,\r\n InvalidIfBlockOrdinal = 2004,\r\n InvalidElseBlockOrdinal = 2006,\r\n InvalidElseIfBlockOrdinal = 2007,\r\n\r\n // General\r\n\r\n InvalidElement = 3002,\r\n ChildrenExpected = 3003,\r\n}\r\n","import { LogicErrors } from './enums';\r\n\r\nexport const ERRORS: Record<LogicErrors, string> = {\r\n [LogicErrors.IfBlockExpected]: \"Missing 'If'\",\r\n [LogicErrors.OnlyOneIfBlockExpected]: \"Can only have one 'If'\",\r\n [LogicErrors.OnlyOneElseBlockExpected]: \"Can only have one 'Else'\",\r\n [LogicErrors.SwitchBlockExpected]: \"'If', 'ElseIf', 'Else' need to be wrapped in 'Switch'\",\r\n [LogicErrors.InvalidElseBlockOrdinal]: \"Invalid ordinals, 'Else' should be the last\",\r\n [LogicErrors.InvalidIfBlockOrdinal]: \"Invalid ordinals, 'If' block should be the first\",\r\n [LogicErrors.InvalidElseIfBlockOrdinal]: \"Invalid ordinals, cannot have 'ElseIf' before 'If'\",\r\n [LogicErrors.ChildrenExpected]: 'Should at least have one child',\r\n [LogicErrors.InvalidElement]: 'Invalid element',\r\n};\r\n","import { FC } from 'react';\r\nimport { ERRORS, LogicErrors } from '@fixtures';\r\n\r\nimport '@assets/index.css';\r\n\r\ntype ErrorProps = { errors: LogicErrors[] };\r\n\r\nconst Errors: FC<ErrorProps> = ({ errors }) => (\r\n <ol className=\"trd-error-list\">\r\n {errors.map((error, index) => (\r\n <li key={`${error}-${index}`}>{ERRORS[error]}</li>\r\n ))}\r\n </ol>\r\n);\r\n\r\nexport default Errors;\r\n","import { Else, ElseIf, If, SwitchIf } from '@directives';\r\nimport { LogicErrors } from '@fixtures';\r\n\r\nimport { ReactNode } from 'react';\r\n\r\ntype ValidatorFn = (children: Array<Exclude<ReactNode, boolean | null | undefined>>) => number[];\r\n\r\nconst validateSwitchIfChildren: ValidatorFn = (children) => {\r\n const errors: LogicErrors[] = [];\r\n\r\n if (children.length === 0) {\r\n errors.push(LogicErrors.ChildrenExpected);\r\n return errors;\r\n }\r\n\r\n children.forEach((child) => {\r\n // @ts-expect-error child.type exist\r\n const { displayName } = child.type ?? {};\r\n\r\n // If, ElseIf, Else cannot be direct children of If, ElseIf, Else\r\n if (displayName === If.displayName || displayName === ElseIf.displayName || displayName === Else.displayName) {\r\n errors.push(LogicErrors.SwitchBlockExpected);\r\n }\r\n });\r\n\r\n return errors;\r\n};\r\n\r\nconst validateSwitchIf: ValidatorFn = (children) => {\r\n const errors: LogicErrors[] = [];\r\n const elementLookup: Record<string, number> = {};\r\n\r\n if (children.length === 0) {\r\n errors.push(LogicErrors.ChildrenExpected, LogicErrors.IfBlockExpected);\r\n return errors;\r\n }\r\n\r\n children.forEach((child, index) => {\r\n // @ts-expect-error child.type exist\r\n const { displayName = 'unknown' } = child.type;\r\n\r\n const count = elementLookup[displayName] ?? 0;\r\n elementLookup[displayName] = count + 1;\r\n\r\n validateIfBlock(displayName, index, elementLookup, errors);\r\n validateElseBlock(displayName, index, children.length, elementLookup, errors);\r\n validateElseIfBlock(displayName, index, errors);\r\n validateSwitchIfInvalidElement(displayName, errors);\r\n });\r\n\r\n if (!elementLookup[If.name]) {\r\n errors.push(LogicErrors.IfBlockExpected);\r\n }\r\n\r\n return errors;\r\n};\r\n\r\nconst validateIfBlock = (typeName: string, index: number, elements: Record<string, number>, errors: LogicErrors[]) => {\r\n if (typeName === If.name) {\r\n if (index !== 0) {\r\n errors.push(LogicErrors.InvalidIfBlockOrdinal);\r\n }\r\n\r\n if (elements[If.name] > 1) {\r\n errors.push(LogicErrors.OnlyOneIfBlockExpected);\r\n }\r\n }\r\n};\r\n\r\nconst validateElseBlock = (\r\n typeName: string,\r\n index: number,\r\n length: number,\r\n elements: Record<string, number>,\r\n errors: LogicErrors[],\r\n) => {\r\n if (typeName === Else.name) {\r\n if (elements[Else.name] > 1) {\r\n errors.push(LogicErrors.OnlyOneElseBlockExpected);\r\n }\r\n if (index === 0 || index !== length - 1) {\r\n errors.push(LogicErrors.InvalidElseBlockOrdinal);\r\n }\r\n }\r\n};\r\n\r\nconst validateElseIfBlock = (typeName: string, index: number, errors: LogicErrors[]) => {\r\n if (typeName === ElseIf.name && index === 0) {\r\n errors.push(LogicErrors.InvalidElseIfBlockOrdinal);\r\n }\r\n};\r\n\r\nconst validateSwitchIfInvalidElement = (typeName: string, errors: LogicErrors[]) => {\r\n if (typeName !== If.name && typeName !== ElseIf.name && typeName !== Else.name) {\r\n errors.push(LogicErrors.InvalidElement);\r\n }\r\n};\r\n\r\nexport class ValidationFactory {\r\n static get(validator: string) {\r\n let validatorFn: ValidatorFn;\r\n switch (validator) {\r\n case SwitchIf.displayName:\r\n validatorFn = validateSwitchIf;\r\n break;\r\n case If.displayName:\r\n case ElseIf.displayName:\r\n case Else.displayName:\r\n validatorFn = validateSwitchIfChildren;\r\n break;\r\n default:\r\n validatorFn = () => [];\r\n }\r\n\r\n return validatorFn;\r\n }\r\n}\r\n","import { ValidationFactory } from '@utils';\r\nimport { Children, PropsWithChildren } from 'react';\r\n\r\nexport const useValidate = (props: PropsWithChildren, name: string) => {\r\n const { children } = props;\r\n const _children = Children.toArray(children);\r\n\r\n return ValidationFactory.get(name)(_children);\r\n};\r\n","import { Errors } from '@components';\r\nimport { useValidate } from '@hooks';\r\n\r\nimport {\r\n Children,\r\n createElement,\r\n FC,\r\n FunctionComponent,\r\n isValidElement,\r\n NamedExoticComponent,\r\n PropsWithChildren,\r\n ReactElement,\r\n} from 'react';\r\n\r\nexport type SwitchIfProps = {};\r\n\r\nconst useSwitchIf = (props: PropsWithChildren) => {\r\n const errors = useValidate(props, 'SwitchIf');\r\n\r\n if (errors.length) {\r\n return { children: createElement(Errors, { errors }) };\r\n }\r\n\r\n const elements = Children.toArray(props.children);\r\n const validElements = elements.filter(isValidElement);\r\n const child = findChild(validElements);\r\n\r\n return { children: child };\r\n};\r\n\r\nconst findChild = (elements: ReactElement[]) => {\r\n for (const element of elements) {\r\n if (!element || !isValidElement(element)) {\r\n continue;\r\n }\r\n\r\n const { displayName } = element.type as NamedExoticComponent | FunctionComponent;\r\n\r\n if (displayName) {\r\n const { condition } = element.props as { condition: boolean };\r\n\r\n if ((displayName === 'If' || displayName === 'ElseIf') && condition === true) {\r\n return element;\r\n }\r\n\r\n if (displayName === 'Else') {\r\n return element;\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n};\r\n\r\nconst SwitchIf: FC<PropsWithChildren<SwitchIfProps>> = (props) => {\r\n const { children } = useSwitchIf(props);\r\n return <>{children}</>;\r\n};\r\n\r\nSwitchIf.displayName = 'SwitchIf';\r\n\r\nexport default SwitchIf;\r\n","import { Errors } from '@components';\r\nimport { useValidate } from '@hooks';\r\n\r\nimport { FC, PropsWithChildren } from 'react';\r\n\r\nexport type IfProps = PropsWithChildren<{\r\n condition: boolean;\r\n}>;\r\n\r\nconst If: FC<IfProps> = (props) => {\r\n const errors = useValidate(props, 'If');\r\n const { condition } = props;\r\n const children = errors.length === 0 ? props.children : <Errors errors={errors} />;\r\n\r\n return <>{condition && children}</>;\r\n};\r\n\r\nIf.displayName = 'If';\r\n\r\nexport default If;\r\n","import { Errors } from '@components';\r\nimport { useValidate } from '@hooks';\r\nimport { FC, PropsWithChildren } from 'react';\r\n\r\nexport type ElseIfProps = PropsWithChildren<{\r\n condition: boolean;\r\n}>;\r\n\r\nconst ElseIf: FC<ElseIfProps> = (props) => {\r\n const errors = useValidate(props, 'ElseIf');\r\n const { condition } = props;\r\n const children = errors.length === 0 ? props.children : <Errors errors={errors} />;\r\n\r\n return <>{condition && children}</>;\r\n};\r\n\r\nElseIf.displayName = 'ElseIf';\r\n\r\nexport default ElseIf;\r\n","import { Errors } from '@components';\r\nimport { useValidate } from '@hooks';\r\nimport { FC, PropsWithChildren } from 'react';\r\n\r\nexport type ElseProps = {};\r\n\r\nconst Else: FC<PropsWithChildren<ElseProps>> = (props) => {\r\n const errors = useValidate(props, 'Else');\r\n const children = errors.length === 0 ? props.children : <Errors errors={errors} />;\r\n\r\n return <>{children}</>;\r\n};\r\n\r\nElse.displayName = 'Else';\r\n\r\nexport default Else;\r\n"],"names":["LogicErrors","ERRORS","Errors","errors","error","index","jsx","validateSwitchIfChildren","children","child","displayName","If","ElseIf","Else","validateSwitchIf","elementLookup","count","validateIfBlock","validateElseBlock","validateElseIfBlock","validateSwitchIfInvalidElement","typeName","elements","length","ValidationFactory","validator","validatorFn","SwitchIf","useValidate","props","name","_children","Children","useSwitchIf","createElement","validElements","isValidElement","findChild","element","condition","Fragment"],"mappings":"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"}
@@ -97,3 +97,4 @@ export {
97
97
  i as If,
98
98
  m as SwitchIf
99
99
  };
100
+ //# sourceMappingURL=ts-react-directives.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-react-directives.es.js","sources":["../src/fixtures/enums.ts","../src/fixtures/constants.ts","../src/components/Errors.tsx","../src/utils/validators.ts","../src/hooks/useValidate.ts","../src/directives/if/SwitchIf.tsx","../src/directives/if/If.tsx","../src/directives/if/ElseIf.tsx","../src/directives/if/Else.tsx"],"sourcesContent":["export enum LogicErrors {\r\n // Switch\r\n IfBlockExpected = 2001,\r\n OnlyOneIfBlockExpected = 2002,\r\n OnlyOneElseBlockExpected = 2003,\r\n SwitchBlockExpected = 2005,\r\n InvalidIfBlockOrdinal = 2004,\r\n InvalidElseBlockOrdinal = 2006,\r\n InvalidElseIfBlockOrdinal = 2007,\r\n\r\n // General\r\n\r\n InvalidElement = 3002,\r\n ChildrenExpected = 3003,\r\n}\r\n","import { LogicErrors } from './enums';\r\n\r\nexport const ERRORS: Record<LogicErrors, string> = {\r\n [LogicErrors.IfBlockExpected]: \"Missing 'If'\",\r\n [LogicErrors.OnlyOneIfBlockExpected]: \"Can only have one 'If'\",\r\n [LogicErrors.OnlyOneElseBlockExpected]: \"Can only have one 'Else'\",\r\n [LogicErrors.SwitchBlockExpected]: \"'If', 'ElseIf', 'Else' need to be wrapped in 'Switch'\",\r\n [LogicErrors.InvalidElseBlockOrdinal]: \"Invalid ordinals, 'Else' should be the last\",\r\n [LogicErrors.InvalidIfBlockOrdinal]: \"Invalid ordinals, 'If' block should be the first\",\r\n [LogicErrors.InvalidElseIfBlockOrdinal]: \"Invalid ordinals, cannot have 'ElseIf' before 'If'\",\r\n [LogicErrors.ChildrenExpected]: 'Should at least have one child',\r\n [LogicErrors.InvalidElement]: 'Invalid element',\r\n};\r\n","import { FC } from 'react';\r\nimport { ERRORS, LogicErrors } from '@fixtures';\r\n\r\nimport '@assets/index.css';\r\n\r\ntype ErrorProps = { errors: LogicErrors[] };\r\n\r\nconst Errors: FC<ErrorProps> = ({ errors }) => (\r\n <ol className=\"trd-error-list\">\r\n {errors.map((error, index) => (\r\n <li key={`${error}-${index}`}>{ERRORS[error]}</li>\r\n ))}\r\n </ol>\r\n);\r\n\r\nexport default Errors;\r\n","import { Else, ElseIf, If, SwitchIf } from '@directives';\r\nimport { LogicErrors } from '@fixtures';\r\n\r\nimport { ReactNode } from 'react';\r\n\r\ntype ValidatorFn = (children: Array<Exclude<ReactNode, boolean | null | undefined>>) => number[];\r\n\r\nconst validateSwitchIfChildren: ValidatorFn = (children) => {\r\n const errors: LogicErrors[] = [];\r\n\r\n if (children.length === 0) {\r\n errors.push(LogicErrors.ChildrenExpected);\r\n return errors;\r\n }\r\n\r\n children.forEach((child) => {\r\n // @ts-expect-error child.type exist\r\n const { displayName } = child.type ?? {};\r\n\r\n // If, ElseIf, Else cannot be direct children of If, ElseIf, Else\r\n if (displayName === If.displayName || displayName === ElseIf.displayName || displayName === Else.displayName) {\r\n errors.push(LogicErrors.SwitchBlockExpected);\r\n }\r\n });\r\n\r\n return errors;\r\n};\r\n\r\nconst validateSwitchIf: ValidatorFn = (children) => {\r\n const errors: LogicErrors[] = [];\r\n const elementLookup: Record<string, number> = {};\r\n\r\n if (children.length === 0) {\r\n errors.push(LogicErrors.ChildrenExpected, LogicErrors.IfBlockExpected);\r\n return errors;\r\n }\r\n\r\n children.forEach((child, index) => {\r\n // @ts-expect-error child.type exist\r\n const { displayName = 'unknown' } = child.type;\r\n\r\n const count = elementLookup[displayName] ?? 0;\r\n elementLookup[displayName] = count + 1;\r\n\r\n validateIfBlock(displayName, index, elementLookup, errors);\r\n validateElseBlock(displayName, index, children.length, elementLookup, errors);\r\n validateElseIfBlock(displayName, index, errors);\r\n validateSwitchIfInvalidElement(displayName, errors);\r\n });\r\n\r\n if (!elementLookup[If.name]) {\r\n errors.push(LogicErrors.IfBlockExpected);\r\n }\r\n\r\n return errors;\r\n};\r\n\r\nconst validateIfBlock = (typeName: string, index: number, elements: Record<string, number>, errors: LogicErrors[]) => {\r\n if (typeName === If.name) {\r\n if (index !== 0) {\r\n errors.push(LogicErrors.InvalidIfBlockOrdinal);\r\n }\r\n\r\n if (elements[If.name] > 1) {\r\n errors.push(LogicErrors.OnlyOneIfBlockExpected);\r\n }\r\n }\r\n};\r\n\r\nconst validateElseBlock = (\r\n typeName: string,\r\n index: number,\r\n length: number,\r\n elements: Record<string, number>,\r\n errors: LogicErrors[],\r\n) => {\r\n if (typeName === Else.name) {\r\n if (elements[Else.name] > 1) {\r\n errors.push(LogicErrors.OnlyOneElseBlockExpected);\r\n }\r\n if (index === 0 || index !== length - 1) {\r\n errors.push(LogicErrors.InvalidElseBlockOrdinal);\r\n }\r\n }\r\n};\r\n\r\nconst validateElseIfBlock = (typeName: string, index: number, errors: LogicErrors[]) => {\r\n if (typeName === ElseIf.name && index === 0) {\r\n errors.push(LogicErrors.InvalidElseIfBlockOrdinal);\r\n }\r\n};\r\n\r\nconst validateSwitchIfInvalidElement = (typeName: string, errors: LogicErrors[]) => {\r\n if (typeName !== If.name && typeName !== ElseIf.name && typeName !== Else.name) {\r\n errors.push(LogicErrors.InvalidElement);\r\n }\r\n};\r\n\r\nexport class ValidationFactory {\r\n static get(validator: string) {\r\n let validatorFn: ValidatorFn;\r\n switch (validator) {\r\n case SwitchIf.displayName:\r\n validatorFn = validateSwitchIf;\r\n break;\r\n case If.displayName:\r\n case ElseIf.displayName:\r\n case Else.displayName:\r\n validatorFn = validateSwitchIfChildren;\r\n break;\r\n default:\r\n validatorFn = () => [];\r\n }\r\n\r\n return validatorFn;\r\n }\r\n}\r\n","import { ValidationFactory } from '@utils';\r\nimport { Children, PropsWithChildren } from 'react';\r\n\r\nexport const useValidate = (props: PropsWithChildren, name: string) => {\r\n const { children } = props;\r\n const _children = Children.toArray(children);\r\n\r\n return ValidationFactory.get(name)(_children);\r\n};\r\n","import { Errors } from '@components';\r\nimport { useValidate } from '@hooks';\r\n\r\nimport {\r\n Children,\r\n createElement,\r\n FC,\r\n FunctionComponent,\r\n isValidElement,\r\n NamedExoticComponent,\r\n PropsWithChildren,\r\n ReactElement,\r\n} from 'react';\r\n\r\nexport type SwitchIfProps = {};\r\n\r\nconst useSwitchIf = (props: PropsWithChildren) => {\r\n const errors = useValidate(props, 'SwitchIf');\r\n\r\n if (errors.length) {\r\n return { children: createElement(Errors, { errors }) };\r\n }\r\n\r\n const elements = Children.toArray(props.children);\r\n const validElements = elements.filter(isValidElement);\r\n const child = findChild(validElements);\r\n\r\n return { children: child };\r\n};\r\n\r\nconst findChild = (elements: ReactElement[]) => {\r\n for (const element of elements) {\r\n if (!element || !isValidElement(element)) {\r\n continue;\r\n }\r\n\r\n const { displayName } = element.type as NamedExoticComponent | FunctionComponent;\r\n\r\n if (displayName) {\r\n const { condition } = element.props as { condition: boolean };\r\n\r\n if ((displayName === 'If' || displayName === 'ElseIf') && condition === true) {\r\n return element;\r\n }\r\n\r\n if (displayName === 'Else') {\r\n return element;\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n};\r\n\r\nconst SwitchIf: FC<PropsWithChildren<SwitchIfProps>> = (props) => {\r\n const { children } = useSwitchIf(props);\r\n return <>{children}</>;\r\n};\r\n\r\nSwitchIf.displayName = 'SwitchIf';\r\n\r\nexport default SwitchIf;\r\n","import { Errors } from '@components';\r\nimport { useValidate } from '@hooks';\r\n\r\nimport { FC, PropsWithChildren } from 'react';\r\n\r\nexport type IfProps = PropsWithChildren<{\r\n condition: boolean;\r\n}>;\r\n\r\nconst If: FC<IfProps> = (props) => {\r\n const errors = useValidate(props, 'If');\r\n const { condition } = props;\r\n const children = errors.length === 0 ? props.children : <Errors errors={errors} />;\r\n\r\n return <>{condition && children}</>;\r\n};\r\n\r\nIf.displayName = 'If';\r\n\r\nexport default If;\r\n","import { Errors } from '@components';\r\nimport { useValidate } from '@hooks';\r\nimport { FC, PropsWithChildren } from 'react';\r\n\r\nexport type ElseIfProps = PropsWithChildren<{\r\n condition: boolean;\r\n}>;\r\n\r\nconst ElseIf: FC<ElseIfProps> = (props) => {\r\n const errors = useValidate(props, 'ElseIf');\r\n const { condition } = props;\r\n const children = errors.length === 0 ? props.children : <Errors errors={errors} />;\r\n\r\n return <>{condition && children}</>;\r\n};\r\n\r\nElseIf.displayName = 'ElseIf';\r\n\r\nexport default ElseIf;\r\n","import { Errors } from '@components';\r\nimport { useValidate } from '@hooks';\r\nimport { FC, PropsWithChildren } from 'react';\r\n\r\nexport type ElseProps = {};\r\n\r\nconst Else: FC<PropsWithChildren<ElseProps>> = (props) => {\r\n const errors = useValidate(props, 'Else');\r\n const children = errors.length === 0 ? props.children : <Errors errors={errors} />;\r\n\r\n return <>{children}</>;\r\n};\r\n\r\nElse.displayName = 'Else';\r\n\r\nexport default Else;\r\n"],"names":["LogicErrors","ERRORS","Errors","errors","error","index","jsx","validateSwitchIfChildren","children","child","displayName","If","ElseIf","Else","validateSwitchIf","elementLookup","count","validateIfBlock","validateElseBlock","validateElseIfBlock","validateSwitchIfInvalidElement","typeName","elements","length","ValidationFactory","validator","validatorFn","SwitchIf","useValidate","props","name","_children","Children","useSwitchIf","createElement","validElements","isValidElement","findChild","element","condition","Fragment"],"mappings":"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"}
@@ -1,2 +1,3 @@
1
1
  (function(c,a){typeof exports=="object"&&typeof module<"u"?a(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],a):(c=typeof globalThis<"u"?globalThis:c||self,a(c["ts-react-directives"]={},c["react/jsx-runtime"],c.React))})(this,function(c,a,h){"use strict";var E=document.createElement("style");E.textContent=`:root{--trd-color: 255, 100, 200;--trd-bg-color: 0, 100, 200}ol.trd-error-list{border:.2rem double rgb(var(--trd-bg-color));background-color:rgba(var(--trd-bg-color),.1);list-style-type:none;box-sizing:border-box;padding:.5rem;margin:0}.trd-error-list>li{color:#000;background-color:rgba(var(--trd-color),.1);padding:.125rem;margin:.125rem;border:2px solid rgb(var(--trd-color));font-size:1.5rem;font-family:monospace}.trd-error-list>li:before{content:"🛈 ";font-size:1.5rem;padding-left:.125rem;margin-right:.125rem}
2
2
  /*$vite$:1*/`,document.head.appendChild(E);var t=(e=>(e[e.IfBlockExpected=2001]="IfBlockExpected",e[e.OnlyOneIfBlockExpected=2002]="OnlyOneIfBlockExpected",e[e.OnlyOneElseBlockExpected=2003]="OnlyOneElseBlockExpected",e[e.SwitchBlockExpected=2005]="SwitchBlockExpected",e[e.InvalidIfBlockOrdinal=2004]="InvalidIfBlockOrdinal",e[e.InvalidElseBlockOrdinal=2006]="InvalidElseBlockOrdinal",e[e.InvalidElseIfBlockOrdinal=2007]="InvalidElseIfBlockOrdinal",e[e.InvalidElement=3002]="InvalidElement",e[e.ChildrenExpected=3003]="ChildrenExpected",e))(t||{});const u={[t.IfBlockExpected]:"Missing 'If'",[t.OnlyOneIfBlockExpected]:"Can only have one 'If'",[t.OnlyOneElseBlockExpected]:"Can only have one 'Else'",[t.SwitchBlockExpected]:"'If', 'ElseIf', 'Else' need to be wrapped in 'Switch'",[t.InvalidElseBlockOrdinal]:"Invalid ordinals, 'Else' should be the last",[t.InvalidIfBlockOrdinal]:"Invalid ordinals, 'If' block should be the first",[t.InvalidElseIfBlockOrdinal]:"Invalid ordinals, cannot have 'ElseIf' before 'If'",[t.ChildrenExpected]:"Should at least have one child",[t.InvalidElement]:"Invalid element"},I=({errors:e})=>a.jsx("ol",{className:"trd-error-list",children:e.map((l,n)=>a.jsx("li",{children:u[l]},`${l}-${n}`))}),v=e=>{const l=[];return e.length===0?(l.push(t.ChildrenExpected),l):(e.forEach(n=>{const{displayName:d}=n.type??{};(d===i.displayName||d===r.displayName||d===o.displayName)&&l.push(t.SwitchBlockExpected)}),l)},k=e=>{const l=[],n={};return e.length===0?(l.push(t.ChildrenExpected,t.IfBlockExpected),l):(e.forEach((d,s)=>{const{displayName:f="unknown"}=d.type,g=n[f]??0;n[f]=g+1,y(f,s,n,l),B(f,s,e.length,n,l),O(f,s,l),b(f,l)}),n[i.name]||l.push(t.IfBlockExpected),l)},y=(e,l,n,d)=>{e===i.name&&(l!==0&&d.push(t.InvalidIfBlockOrdinal),n[i.name]>1&&d.push(t.OnlyOneIfBlockExpected))},B=(e,l,n,d,s)=>{e===o.name&&(d[o.name]>1&&s.push(t.OnlyOneElseBlockExpected),(l===0||l!==n-1)&&s.push(t.InvalidElseBlockOrdinal))},O=(e,l,n)=>{e===r.name&&l===0&&n.push(t.InvalidElseIfBlockOrdinal)},b=(e,l)=>{e!==i.name&&e!==r.name&&e!==o.name&&l.push(t.InvalidElement)};class x{static get(l){let n;switch(l){case m.displayName:n=k;break;case i.displayName:case r.displayName:case o.displayName:n=v;break;default:n=()=>[]}return n}}const p=(e,l)=>{const{children:n}=e,d=h.Children.toArray(n);return x.get(l)(d)},S=e=>{const l=p(e,"SwitchIf");if(l.length)return{children:h.createElement(I,{errors:l})};const d=h.Children.toArray(e.children).filter(h.isValidElement);return{children:w(d)}},w=e=>{for(const l of e){if(!l||!h.isValidElement(l))continue;const{displayName:n}=l.type;if(n){const{condition:d}=l.props;if((n==="If"||n==="ElseIf")&&d===!0||n==="Else")return l}}return null},m=e=>{const{children:l}=S(e);return a.jsx(a.Fragment,{children:l})};m.displayName="SwitchIf";const i=e=>{const l=p(e,"If"),{condition:n}=e,d=l.length===0?e.children:a.jsx(I,{errors:l});return a.jsx(a.Fragment,{children:n&&d})};i.displayName="If";const r=e=>{const l=p(e,"ElseIf"),{condition:n}=e,d=l.length===0?e.children:a.jsx(I,{errors:l});return a.jsx(a.Fragment,{children:n&&d})};r.displayName="ElseIf";const o=e=>{const l=p(e,"Else"),n=l.length===0?e.children:a.jsx(I,{errors:l});return a.jsx(a.Fragment,{children:n})};o.displayName="Else",c.Else=o,c.ElseIf=r,c.If=i,c.SwitchIf=m,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})});
3
+ //# sourceMappingURL=ts-react-directives.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ts-react-directives.umd.js","sources":["../src/fixtures/enums.ts","../src/fixtures/constants.ts","../src/components/Errors.tsx","../src/utils/validators.ts","../src/hooks/useValidate.ts","../src/directives/if/SwitchIf.tsx","../src/directives/if/If.tsx","../src/directives/if/ElseIf.tsx","../src/directives/if/Else.tsx"],"sourcesContent":["export enum LogicErrors {\r\n // Switch\r\n IfBlockExpected = 2001,\r\n OnlyOneIfBlockExpected = 2002,\r\n OnlyOneElseBlockExpected = 2003,\r\n SwitchBlockExpected = 2005,\r\n InvalidIfBlockOrdinal = 2004,\r\n InvalidElseBlockOrdinal = 2006,\r\n InvalidElseIfBlockOrdinal = 2007,\r\n\r\n // General\r\n\r\n InvalidElement = 3002,\r\n ChildrenExpected = 3003,\r\n}\r\n","import { LogicErrors } from './enums';\r\n\r\nexport const ERRORS: Record<LogicErrors, string> = {\r\n [LogicErrors.IfBlockExpected]: \"Missing 'If'\",\r\n [LogicErrors.OnlyOneIfBlockExpected]: \"Can only have one 'If'\",\r\n [LogicErrors.OnlyOneElseBlockExpected]: \"Can only have one 'Else'\",\r\n [LogicErrors.SwitchBlockExpected]: \"'If', 'ElseIf', 'Else' need to be wrapped in 'Switch'\",\r\n [LogicErrors.InvalidElseBlockOrdinal]: \"Invalid ordinals, 'Else' should be the last\",\r\n [LogicErrors.InvalidIfBlockOrdinal]: \"Invalid ordinals, 'If' block should be the first\",\r\n [LogicErrors.InvalidElseIfBlockOrdinal]: \"Invalid ordinals, cannot have 'ElseIf' before 'If'\",\r\n [LogicErrors.ChildrenExpected]: 'Should at least have one child',\r\n [LogicErrors.InvalidElement]: 'Invalid element',\r\n};\r\n","import { FC } from 'react';\r\nimport { ERRORS, LogicErrors } from '@fixtures';\r\n\r\nimport '@assets/index.css';\r\n\r\ntype ErrorProps = { errors: LogicErrors[] };\r\n\r\nconst Errors: FC<ErrorProps> = ({ errors }) => (\r\n <ol className=\"trd-error-list\">\r\n {errors.map((error, index) => (\r\n <li key={`${error}-${index}`}>{ERRORS[error]}</li>\r\n ))}\r\n </ol>\r\n);\r\n\r\nexport default Errors;\r\n","import { Else, ElseIf, If, SwitchIf } from '@directives';\r\nimport { LogicErrors } from '@fixtures';\r\n\r\nimport { ReactNode } from 'react';\r\n\r\ntype ValidatorFn = (children: Array<Exclude<ReactNode, boolean | null | undefined>>) => number[];\r\n\r\nconst validateSwitchIfChildren: ValidatorFn = (children) => {\r\n const errors: LogicErrors[] = [];\r\n\r\n if (children.length === 0) {\r\n errors.push(LogicErrors.ChildrenExpected);\r\n return errors;\r\n }\r\n\r\n children.forEach((child) => {\r\n // @ts-expect-error child.type exist\r\n const { displayName } = child.type ?? {};\r\n\r\n // If, ElseIf, Else cannot be direct children of If, ElseIf, Else\r\n if (displayName === If.displayName || displayName === ElseIf.displayName || displayName === Else.displayName) {\r\n errors.push(LogicErrors.SwitchBlockExpected);\r\n }\r\n });\r\n\r\n return errors;\r\n};\r\n\r\nconst validateSwitchIf: ValidatorFn = (children) => {\r\n const errors: LogicErrors[] = [];\r\n const elementLookup: Record<string, number> = {};\r\n\r\n if (children.length === 0) {\r\n errors.push(LogicErrors.ChildrenExpected, LogicErrors.IfBlockExpected);\r\n return errors;\r\n }\r\n\r\n children.forEach((child, index) => {\r\n // @ts-expect-error child.type exist\r\n const { displayName = 'unknown' } = child.type;\r\n\r\n const count = elementLookup[displayName] ?? 0;\r\n elementLookup[displayName] = count + 1;\r\n\r\n validateIfBlock(displayName, index, elementLookup, errors);\r\n validateElseBlock(displayName, index, children.length, elementLookup, errors);\r\n validateElseIfBlock(displayName, index, errors);\r\n validateSwitchIfInvalidElement(displayName, errors);\r\n });\r\n\r\n if (!elementLookup[If.name]) {\r\n errors.push(LogicErrors.IfBlockExpected);\r\n }\r\n\r\n return errors;\r\n};\r\n\r\nconst validateIfBlock = (typeName: string, index: number, elements: Record<string, number>, errors: LogicErrors[]) => {\r\n if (typeName === If.name) {\r\n if (index !== 0) {\r\n errors.push(LogicErrors.InvalidIfBlockOrdinal);\r\n }\r\n\r\n if (elements[If.name] > 1) {\r\n errors.push(LogicErrors.OnlyOneIfBlockExpected);\r\n }\r\n }\r\n};\r\n\r\nconst validateElseBlock = (\r\n typeName: string,\r\n index: number,\r\n length: number,\r\n elements: Record<string, number>,\r\n errors: LogicErrors[],\r\n) => {\r\n if (typeName === Else.name) {\r\n if (elements[Else.name] > 1) {\r\n errors.push(LogicErrors.OnlyOneElseBlockExpected);\r\n }\r\n if (index === 0 || index !== length - 1) {\r\n errors.push(LogicErrors.InvalidElseBlockOrdinal);\r\n }\r\n }\r\n};\r\n\r\nconst validateElseIfBlock = (typeName: string, index: number, errors: LogicErrors[]) => {\r\n if (typeName === ElseIf.name && index === 0) {\r\n errors.push(LogicErrors.InvalidElseIfBlockOrdinal);\r\n }\r\n};\r\n\r\nconst validateSwitchIfInvalidElement = (typeName: string, errors: LogicErrors[]) => {\r\n if (typeName !== If.name && typeName !== ElseIf.name && typeName !== Else.name) {\r\n errors.push(LogicErrors.InvalidElement);\r\n }\r\n};\r\n\r\nexport class ValidationFactory {\r\n static get(validator: string) {\r\n let validatorFn: ValidatorFn;\r\n switch (validator) {\r\n case SwitchIf.displayName:\r\n validatorFn = validateSwitchIf;\r\n break;\r\n case If.displayName:\r\n case ElseIf.displayName:\r\n case Else.displayName:\r\n validatorFn = validateSwitchIfChildren;\r\n break;\r\n default:\r\n validatorFn = () => [];\r\n }\r\n\r\n return validatorFn;\r\n }\r\n}\r\n","import { ValidationFactory } from '@utils';\r\nimport { Children, PropsWithChildren } from 'react';\r\n\r\nexport const useValidate = (props: PropsWithChildren, name: string) => {\r\n const { children } = props;\r\n const _children = Children.toArray(children);\r\n\r\n return ValidationFactory.get(name)(_children);\r\n};\r\n","import { Errors } from '@components';\r\nimport { useValidate } from '@hooks';\r\n\r\nimport {\r\n Children,\r\n createElement,\r\n FC,\r\n FunctionComponent,\r\n isValidElement,\r\n NamedExoticComponent,\r\n PropsWithChildren,\r\n ReactElement,\r\n} from 'react';\r\n\r\nexport type SwitchIfProps = {};\r\n\r\nconst useSwitchIf = (props: PropsWithChildren) => {\r\n const errors = useValidate(props, 'SwitchIf');\r\n\r\n if (errors.length) {\r\n return { children: createElement(Errors, { errors }) };\r\n }\r\n\r\n const elements = Children.toArray(props.children);\r\n const validElements = elements.filter(isValidElement);\r\n const child = findChild(validElements);\r\n\r\n return { children: child };\r\n};\r\n\r\nconst findChild = (elements: ReactElement[]) => {\r\n for (const element of elements) {\r\n if (!element || !isValidElement(element)) {\r\n continue;\r\n }\r\n\r\n const { displayName } = element.type as NamedExoticComponent | FunctionComponent;\r\n\r\n if (displayName) {\r\n const { condition } = element.props as { condition: boolean };\r\n\r\n if ((displayName === 'If' || displayName === 'ElseIf') && condition === true) {\r\n return element;\r\n }\r\n\r\n if (displayName === 'Else') {\r\n return element;\r\n }\r\n }\r\n }\r\n\r\n return null;\r\n};\r\n\r\nconst SwitchIf: FC<PropsWithChildren<SwitchIfProps>> = (props) => {\r\n const { children } = useSwitchIf(props);\r\n return <>{children}</>;\r\n};\r\n\r\nSwitchIf.displayName = 'SwitchIf';\r\n\r\nexport default SwitchIf;\r\n","import { Errors } from '@components';\r\nimport { useValidate } from '@hooks';\r\n\r\nimport { FC, PropsWithChildren } from 'react';\r\n\r\nexport type IfProps = PropsWithChildren<{\r\n condition: boolean;\r\n}>;\r\n\r\nconst If: FC<IfProps> = (props) => {\r\n const errors = useValidate(props, 'If');\r\n const { condition } = props;\r\n const children = errors.length === 0 ? props.children : <Errors errors={errors} />;\r\n\r\n return <>{condition && children}</>;\r\n};\r\n\r\nIf.displayName = 'If';\r\n\r\nexport default If;\r\n","import { Errors } from '@components';\r\nimport { useValidate } from '@hooks';\r\nimport { FC, PropsWithChildren } from 'react';\r\n\r\nexport type ElseIfProps = PropsWithChildren<{\r\n condition: boolean;\r\n}>;\r\n\r\nconst ElseIf: FC<ElseIfProps> = (props) => {\r\n const errors = useValidate(props, 'ElseIf');\r\n const { condition } = props;\r\n const children = errors.length === 0 ? props.children : <Errors errors={errors} />;\r\n\r\n return <>{condition && children}</>;\r\n};\r\n\r\nElseIf.displayName = 'ElseIf';\r\n\r\nexport default ElseIf;\r\n","import { Errors } from '@components';\r\nimport { useValidate } from '@hooks';\r\nimport { FC, PropsWithChildren } from 'react';\r\n\r\nexport type ElseProps = {};\r\n\r\nconst Else: FC<PropsWithChildren<ElseProps>> = (props) => {\r\n const errors = useValidate(props, 'Else');\r\n const children = errors.length === 0 ? props.children : <Errors errors={errors} />;\r\n\r\n return <>{children}</>;\r\n};\r\n\r\nElse.displayName = 'Else';\r\n\r\nexport default Else;\r\n"],"names":["LogicErrors","ERRORS","Errors","errors","error","index","jsx","validateSwitchIfChildren","children","child","displayName","If","ElseIf","Else","validateSwitchIf","elementLookup","count","validateIfBlock","validateElseBlock","validateElseIfBlock","validateSwitchIfInvalidElement","typeName","elements","length","ValidationFactory","validator","validatorFn","SwitchIf","useValidate","props","name","_children","Children","useSwitchIf","createElement","validElements","isValidElement","findChild","element","condition","Fragment"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openbytes/ts-react-directives",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "type": "module",
5
5
  "author": {
6
6
  "name": "SkyCodr (aka: Dulan Sudasinghe)",
@@ -10,13 +10,19 @@
10
10
  "files": [
11
11
  "dist"
12
12
  ],
13
+ "types": "./dist/ts-react-directives.d.ts",
13
14
  "main": "dist/ts-react-directives.cjs.js",
14
15
  "module": "dist/ts-react-directives.es.js",
15
- "types": "dist/ts-react-directives.d.ts",
16
16
  "exports": {
17
17
  ".": {
18
- "import": "./dist/ts-react-directives.es.js",
19
- "require": "./dist/ts-react-directives.cjs.js"
18
+ "import": {
19
+ "types": "./dist/ts-react-directives.d.ts",
20
+ "default": "./dist/ts-react-directives.es.js"
21
+ },
22
+ "require": {
23
+ "types": "./dist/ts-react-directives.d.ts",
24
+ "default": "./dist/ts-react-directives.cjs.js"
25
+ }
20
26
  }
21
27
  },
22
28
  "dependencies": {