@@ -126,40 +126,164 @@ export function createAtomsFn<Args extends ReadonlyArray<AtomicStyles>>(
126126 for ( const prop in finalProps ) {
127127 const propValue = finalProps [ prop ] ;
128128 const atomicProperty = atomicStyles [ prop ] ;
129+ try {
130+ if ( atomicProperty . mappings ) {
131+ // Skip shorthands
132+ continue ;
133+ }
129134
130- if ( atomicProperty . mappings ) {
131- // Skip shorthands
132- continue ;
133- }
135+ if ( typeof propValue === 'string' || typeof propValue === 'number' ) {
136+ if ( process . env . NODE_ENV !== 'production' ) {
137+ if ( ! atomicProperty . values [ propValue ] . defaultClass ) {
138+ throw new Error ( ) ;
139+ }
140+ }
141+ classNames . push ( atomicProperty . values [ propValue ] . defaultClass ) ;
142+ } else if ( Array . isArray ( propValue ) ) {
143+ for ( const responsiveIndex in propValue ) {
144+ const responsiveValue = propValue [ responsiveIndex ] ;
145+
146+ if ( responsiveValue != null ) {
147+ const conditionName =
148+ atomicProperty . responsiveArray [ responsiveIndex ] ;
149+
150+ if ( process . env . NODE_ENV !== 'production' ) {
151+ if (
152+ ! atomicProperty . values [ responsiveValue ] . conditions [
153+ conditionName
154+ ]
155+ ) {
156+ throw new Error ( ) ;
157+ }
158+ }
159+
160+ classNames . push (
161+ atomicProperty . values [ responsiveValue ] . conditions [
162+ conditionName
163+ ] ,
164+ ) ;
165+ }
166+ }
167+ } else {
168+ for ( const conditionName in propValue ) {
169+ // Conditional style
170+ const value = propValue [ conditionName ] ;
134171
135- if ( typeof propValue === 'string' || typeof propValue === 'number' ) {
136- classNames . push ( atomicProperty . values [ propValue ] . defaultClass ) ;
137- } else if ( Array . isArray ( propValue ) ) {
138- for ( const responsiveIndex in propValue ) {
139- const responsiveValue = propValue [ responsiveIndex ] ;
140-
141- if (
142- typeof responsiveValue === 'string' ||
143- typeof responsiveValue === 'number'
144- ) {
145- const conditionName =
146- atomicProperty . responsiveArray [ responsiveIndex ] ;
172+ if ( process . env . NODE_ENV !== 'production' ) {
173+ if ( ! atomicProperty . values [ value ] . conditions [ conditionName ] ) {
174+ throw new Error ( ) ;
175+ }
176+ }
147177 classNames . push (
148- atomicProperty . values [ responsiveValue ] . conditions [ conditionName ] ,
178+ atomicProperty . values [ value ] . conditions [ conditionName ] ,
149179 ) ;
150180 }
151181 }
152- } else {
153- for ( const conditionName in propValue ) {
154- // Conditional style
155- const value = propValue [ conditionName ] ;
182+ } catch ( e ) {
183+ if ( process . env . NODE_ENV !== 'production' ) {
184+ class SprinklesError extends Error {
185+ constructor ( message : string ) {
186+ super ( message ) ;
187+ this . name = 'SprinklesError' ;
188+ }
189+ }
156190
157- if ( typeof value === 'string' || typeof value === 'number' ) {
158- classNames . push (
159- atomicProperty . values [ value ] . conditions [ conditionName ] ,
191+ const format = ( v : string | number ) =>
192+ typeof v === 'string' ? `"${ v } "` : v ;
193+
194+ const invalidPropValue = (
195+ prop : string ,
196+ value : string | number ,
197+ possibleValues : Array < string | number > ,
198+ ) => {
199+ throw new SprinklesError (
200+ `"${ prop } " has no value ${ format (
201+ value ,
202+ ) } . Possible values are ${ Object . keys ( possibleValues )
203+ . map ( format )
204+ . join ( ', ' ) } `,
160205 ) ;
206+ } ;
207+
208+ if ( ! atomicProperty ) {
209+ throw new SprinklesError ( `"${ prop } " is not a valid atom property` ) ;
210+ }
211+
212+ if ( typeof propValue === 'string' || typeof propValue === 'number' ) {
213+ if ( ! ( propValue in atomicProperty . values ) ) {
214+ invalidPropValue ( prop , propValue , atomicProperty . values ) ;
215+ }
216+ if ( ! atomicProperty . values [ propValue ] . defaultClass ) {
217+ throw new SprinklesError (
218+ `"${ prop } " has no default condition. You must specify which conditions to target explicitly. Possible options are ${ Object . keys (
219+ atomicProperty . values [ propValue ] . conditions ,
220+ )
221+ . map ( format )
222+ . join ( ', ' ) } `,
223+ ) ;
224+ }
225+ }
226+
227+ if ( typeof propValue === 'object' ) {
228+ if (
229+ ! (
230+ 'conditions' in
231+ atomicProperty . values [ Object . keys ( atomicProperty . values ) [ 0 ] ]
232+ )
233+ ) {
234+ throw new SprinklesError (
235+ `"${ prop } " is not a conditional property` ,
236+ ) ;
237+ }
238+
239+ if ( Array . isArray ( propValue ) ) {
240+ if ( ! ( 'responsiveArray' in atomicProperty ) ) {
241+ throw new SprinklesError (
242+ `"${ prop } " does not support responsive arrays` ,
243+ ) ;
244+ }
245+
246+ const breakpointCount = atomicProperty . responsiveArray . length ;
247+ if ( breakpointCount < propValue . length ) {
248+ throw new SprinklesError (
249+ `"${ prop } " only supports up to ${ breakpointCount } breakpoints. You passed ${ propValue . length } ` ,
250+ ) ;
251+ }
252+
253+ for ( const responsiveValue of propValue ) {
254+ if ( ! atomicProperty . values [ responsiveValue ] ) {
255+ invalidPropValue (
256+ prop ,
257+ responsiveValue ,
258+ atomicProperty . values ,
259+ ) ;
260+ }
261+ }
262+ } else {
263+ for ( const conditionName in propValue ) {
264+ const value = propValue [ conditionName ] ;
265+
266+ if ( ! atomicProperty . values [ value ] ) {
267+ invalidPropValue ( prop , value , atomicProperty . values ) ;
268+ }
269+
270+ if ( ! atomicProperty . values [ value ] . conditions [ conditionName ] ) {
271+ throw new SprinklesError (
272+ `"${ prop } " has no condition named ${ format (
273+ conditionName ,
274+ ) } . Possible values are ${ Object . keys (
275+ atomicProperty . values [ value ] . conditions ,
276+ )
277+ . map ( format )
278+ . join ( ', ' ) } `,
279+ ) ;
280+ }
281+ }
282+ }
161283 }
162284 }
285+
286+ throw e ;
163287 }
164288 }
165289
0 commit comments