@@ -198,6 +198,218 @@ if ( ! function_exists( 'stackable_get_blocks_array') ) {
198198 cb ( )
199199} )
200200
201+ gulp . task ( 'generate-block-design-system-php' , function ( cb ) {
202+ const fs = require ( 'fs' )
203+
204+ let blockDesignSystem = 'array()'
205+
206+ const toAssocArray = ( key , value , cb , indent ) => {
207+ if ( typeof value === 'object' ) {
208+ const parsed = cb ( value , indent + 1 )
209+ return `"${ key } " => ${ parsed } `
210+ }
211+
212+ if ( typeof value === 'string' ) {
213+ return `"${ key } " => "${ value } "`
214+ }
215+
216+ return `"${ key } " => ${ value } `
217+ }
218+
219+ const parseBlockDesignSystem = ( obj , indent ) => {
220+ let content = ''
221+ const tab = '\t' . repeat ( indent )
222+
223+ if ( typeof obj === 'object' ) {
224+ content += 'array(\n'
225+
226+ Object . entries ( obj ) . forEach ( ( [ key , value ] , index , bds ) => {
227+ if ( key === 'hoverStates' ) {
228+ return
229+ }
230+
231+ content += tab + toAssocArray ( key , value , parseBlockDesignSystem , indent )
232+
233+ if ( index !== bds . length - 1 ) {
234+ content += ',\n'
235+ } else {
236+ content += '\n'
237+ }
238+ } )
239+ content += `\t` . repeat ( indent - 1 ) + ')'
240+ }
241+ return content
242+ }
243+
244+ const parseBlockDesignSystemSections = ( sections , indent ) => {
245+ const combined = { }
246+ Object . values ( sections ) . forEach ( section => {
247+ Object . entries ( section ) . forEach ( ( [ key , value ] ) => {
248+ combined [ key ] = value
249+ } )
250+ } )
251+
252+ return parseBlockDesignSystem ( combined , indent )
253+ }
254+ const jsonPath = path . resolve ( __dirname , `src/styles/block-design-system.json` )
255+ if ( fs . existsSync ( jsonPath ) ) {
256+ const fileContent = fs . readFileSync ( jsonPath , 'utf-8' )
257+ const raw = JSON . parse ( fileContent )
258+ blockDesignSystem = parseBlockDesignSystemSections ( raw , 4 )
259+ }
260+
261+ // Generate PHP variable string
262+ const script = `<?php
263+ // This is a generated file by gulp generate-block-design-system-php
264+
265+ // Exit if accessed directly.
266+ if ( ! defined( 'ABSPATH' ) ) {
267+ exit;
268+ }
269+
270+ if ( ! class_exists( 'Stackable_Block_Design_System') ) {
271+ class Stackable_Block_Design_System {
272+
273+ function __construct() {
274+ }
275+
276+ public static function get_block_design_system() {
277+ $block_design_system = ${ blockDesignSystem } ;
278+
279+ return $block_design_system;
280+ }
281+ }
282+
283+ new Stackable_Block_Design_System();
284+ }
285+ ?>
286+ `
287+ // Write PHP variable to file
288+ fs . writeFileSync ( path . resolve ( __dirname , 'src/styles/index.php' ) , script )
289+
290+ cb ( )
291+ } )
292+
293+ gulp . task ( 'generate-block-design-system-scss' , function ( cb ) {
294+ const fs = require ( 'fs' )
295+
296+ let blockDesignSystem = ''
297+
298+ const getFourRangeValue = sides => {
299+ if ( Object . values ( sides ) . every ( s => s === sides . top ) ) {
300+ return `${ sides . top } px`
301+ }
302+
303+ if ( sides . top === sides . bottom && sides . right === sides . left ) {
304+ return `${ sides . top } px ${ sides . right } px`
305+ }
306+
307+ return `${ sides . top } px ${ sides . right } px ${ sides . bottom } px ${ sides . left } px`
308+ }
309+
310+ const getDeviceValue = ( obj , device = 'desktop' ) => {
311+ const value = obj [ device ]
312+
313+ if ( typeof value === 'number' ) {
314+ return `${ value } px`
315+ }
316+
317+ if ( typeof value === 'object' ) {
318+ return `${ getFourRangeValue ( value ) } `
319+ }
320+
321+ if ( value === '' ) {
322+ return 'none'
323+ }
324+
325+ return value
326+ }
327+
328+ const getValue = ( property , obj , indent ) => {
329+ if ( Object . keys ( obj ) . length === 1 ) {
330+ return getDeviceValue ( obj )
331+ }
332+
333+ const tab = `\t` . repeat ( indent )
334+ let content = getDeviceValue ( obj )
335+ let hoverProperties = ''
336+ if ( 'hoverStates' in obj ) {
337+ hoverProperties += ',\n'
338+ const _hoverProperties = [ ]
339+ Object . keys ( obj . hoverStates ) . forEach ( state => {
340+ if ( obj . hoverStates [ state ] ) {
341+ _hoverProperties . push ( tab + `${ property } -${ state } : cssvar(${ property } )` )
342+ }
343+ } )
344+ hoverProperties += _hoverProperties . join ( ',\n' )
345+ }
346+
347+ if ( 'hoverStates' in obj && Object . keys ( obj ) . length === 2 ) {
348+ content += hoverProperties
349+ return content
350+ }
351+
352+ content = '(\n'
353+ Object . keys ( obj ) . forEach ( device => {
354+ if ( device === 'hoverStates' ) {
355+ return
356+ }
357+ content += `\t` . repeat ( indent + 1 ) + `${ device } : ${ getDeviceValue ( obj , device ) } ,\n`
358+ } )
359+ content += tab + ')'
360+ content += hoverProperties
361+
362+ return content
363+ }
364+
365+ const parseBlockDesignSystem = ( obj , indent ) => {
366+ let content = ''
367+ const tab = `\t` . repeat ( indent )
368+ Object . entries ( obj ) . forEach ( ( [ key , v ] ) => {
369+ const value = getValue ( key , v , indent )
370+ content += tab + `${ key } : ${ value } ,\n`
371+ } )
372+ return content
373+ }
374+
375+ const parseBlockDesignSystemSections = ( sections , indent ) => {
376+ let content = ''
377+ if ( typeof sections === 'object' ) {
378+ Object . entries ( sections ) . forEach ( ( [ section , obj ] , index , s ) => {
379+ content += ` /**
380+ * ${ section }
381+ */
382+ `
383+ content += parseBlockDesignSystem ( obj , indent )
384+ content += index !== s . length - 1 ? '\n' : ''
385+ } )
386+ }
387+ return content
388+ }
389+
390+ const jsonPath = path . resolve ( __dirname , `src/styles/block-design-system.json` )
391+ if ( fs . existsSync ( jsonPath ) ) {
392+ const fileContent = fs . readFileSync ( jsonPath , 'utf-8' )
393+ const raw = JSON . parse ( fileContent )
394+ blockDesignSystem = parseBlockDesignSystemSections ( raw , 1 )
395+ }
396+
397+ // Generate PHP variable string
398+ const script = `@import "cssvars";
399+ // This is a generated file by gulp generate-block-design-system-scss
400+
401+ /**
402+ * Default Stackable UI Kit design.
403+ */
404+ $block-design-system: (
405+ ${ blockDesignSystem } );
406+ `
407+ // Write to SCSS file
408+ fs . writeFileSync ( path . resolve ( __dirname , 'src/styles/block-design-system.scss' ) , script )
409+
410+ cb ( )
411+ } )
412+
201413gulp . task ( 'generate-translations-js' , gulp . series (
202414 // The collect function has an issue where it will not continue if the
203415 // folder will it writes to doesn't exist, create it to prevent an error.
@@ -492,7 +704,9 @@ gulp.task( 'style-deprecated', gulp.parallel(
492704
493705gulp . task ( 'build-process' , gulp . parallel ( 'style' , 'style-editor' , 'welcome-styles' , 'style-deprecated' , 'generate-translations-js' , 'generate-stk-block-typesphp' ) )
494706
495- gulp . task ( 'build' , gulp . series ( 'build-process' ) )
707+ gulp . task ( 'build-block-design-system' , gulp . parallel ( 'generate-block-design-system-php' , 'generate-block-design-system-scss' ) )
708+
709+ gulp . task ( 'build' , gulp . series ( 'build-block-design-system' , 'build-process' ) )
496710
497711gulp . task ( 'package' , function ( ) {
498712 return gulp . src ( buildInclude , { base : './' } )
@@ -507,6 +721,10 @@ gulp.task( 'zip', function() {
507721} )
508722
509723const watchFuncs = ( basePath = '.' ) => {
724+ gulp . watch (
725+ [ `${ basePath } /src/styles/block-design-system.json` ] ,
726+ gulp . parallel ( [ 'generate-block-design-system-php' , 'generate-block-design-system-scss' ] )
727+ )
510728 gulp . watch (
511729 [ `${ basePath } /src/**/*.scss` ] ,
512730 gulp . parallel ( [ 'style' , 'style-editor' , 'welcome-styles' , 'style-deprecated' ] )
@@ -523,7 +741,7 @@ const watchFuncs = ( basePath = '.' ) => {
523741 )
524742}
525743
526- gulp . task ( 'watch' , gulp . series ( 'build-process' , function watch ( done ) {
744+ gulp . task ( 'watch' , gulp . series ( 'build-block-design-system' , 'build- process', function watch ( done ) {
527745 watchFuncs ( )
528746 done ( )
529747} ) )
0 commit comments