@qwickapps/react-framework 1.5.5 → 1.5.7

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.
Files changed (125) hide show
  1. package/dist/components/QwickApp.d.ts.map +1 -1
  2. package/dist/components/ResponsiveMenu.d.ts.map +1 -1
  3. package/dist/components/Scaffold.d.ts.map +1 -1
  4. package/dist/components/index.d.ts +1 -0
  5. package/dist/components/index.d.ts.map +1 -1
  6. package/dist/contexts/NavigationContext.d.ts +64 -0
  7. package/dist/contexts/NavigationContext.d.ts.map +1 -0
  8. package/dist/contexts/index.d.ts +2 -0
  9. package/dist/contexts/index.d.ts.map +1 -1
  10. package/dist/hooks/useBaseProps.d.ts +12 -1161
  11. package/dist/hooks/useBaseProps.d.ts.map +1 -1
  12. package/dist/index.esm.js +514 -272
  13. package/dist/index.js +514 -272
  14. package/dist/palettes/manifest.json +19 -19
  15. package/dist/palettes/palette-autumn.1.4.9.css +172 -0
  16. package/dist/palettes/palette-autumn.1.4.9.min.css +1 -0
  17. package/dist/palettes/palette-autumn.1.5.0.css +172 -0
  18. package/dist/palettes/palette-autumn.1.5.0.min.css +1 -0
  19. package/dist/palettes/palette-autumn.1.5.1.css +172 -0
  20. package/dist/palettes/palette-autumn.1.5.1.min.css +1 -0
  21. package/dist/palettes/palette-autumn.1.5.2.css +172 -0
  22. package/dist/palettes/palette-autumn.1.5.2.min.css +1 -0
  23. package/dist/palettes/palette-autumn.1.5.3.css +172 -0
  24. package/dist/palettes/palette-autumn.1.5.3.min.css +1 -0
  25. package/dist/palettes/palette-autumn.1.5.4.css +172 -0
  26. package/dist/palettes/palette-autumn.1.5.4.min.css +1 -0
  27. package/dist/palettes/palette-autumn.1.5.6.css +172 -0
  28. package/dist/palettes/palette-autumn.1.5.6.min.css +1 -0
  29. package/dist/palettes/palette-autumn.1.5.7.css +172 -0
  30. package/dist/palettes/palette-autumn.1.5.7.min.css +1 -0
  31. package/dist/palettes/palette-cosmic.1.4.9.css +172 -0
  32. package/dist/palettes/palette-cosmic.1.4.9.min.css +1 -0
  33. package/dist/palettes/palette-cosmic.1.5.0.css +172 -0
  34. package/dist/palettes/palette-cosmic.1.5.0.min.css +1 -0
  35. package/dist/palettes/palette-cosmic.1.5.1.css +172 -0
  36. package/dist/palettes/palette-cosmic.1.5.1.min.css +1 -0
  37. package/dist/palettes/palette-cosmic.1.5.2.css +172 -0
  38. package/dist/palettes/palette-cosmic.1.5.2.min.css +1 -0
  39. package/dist/palettes/palette-cosmic.1.5.3.css +172 -0
  40. package/dist/palettes/palette-cosmic.1.5.3.min.css +1 -0
  41. package/dist/palettes/palette-cosmic.1.5.4.css +172 -0
  42. package/dist/palettes/palette-cosmic.1.5.4.min.css +1 -0
  43. package/dist/palettes/palette-cosmic.1.5.6.css +172 -0
  44. package/dist/palettes/palette-cosmic.1.5.6.min.css +1 -0
  45. package/dist/palettes/palette-cosmic.1.5.7.css +172 -0
  46. package/dist/palettes/palette-cosmic.1.5.7.min.css +1 -0
  47. package/dist/palettes/palette-default.1.4.9.css +178 -0
  48. package/dist/palettes/palette-default.1.4.9.min.css +1 -0
  49. package/dist/palettes/palette-default.1.5.0.css +178 -0
  50. package/dist/palettes/palette-default.1.5.0.min.css +1 -0
  51. package/dist/palettes/palette-default.1.5.1.css +178 -0
  52. package/dist/palettes/palette-default.1.5.1.min.css +1 -0
  53. package/dist/palettes/palette-default.1.5.2.css +178 -0
  54. package/dist/palettes/palette-default.1.5.2.min.css +1 -0
  55. package/dist/palettes/palette-default.1.5.3.css +178 -0
  56. package/dist/palettes/palette-default.1.5.3.min.css +1 -0
  57. package/dist/palettes/palette-default.1.5.4.css +178 -0
  58. package/dist/palettes/palette-default.1.5.4.min.css +1 -0
  59. package/dist/palettes/palette-default.1.5.6.css +178 -0
  60. package/dist/palettes/palette-default.1.5.6.min.css +1 -0
  61. package/dist/palettes/palette-default.1.5.7.css +178 -0
  62. package/dist/palettes/palette-default.1.5.7.min.css +1 -0
  63. package/dist/palettes/palette-ocean.1.4.9.css +172 -0
  64. package/dist/palettes/palette-ocean.1.4.9.min.css +1 -0
  65. package/dist/palettes/palette-ocean.1.5.0.css +172 -0
  66. package/dist/palettes/palette-ocean.1.5.0.min.css +1 -0
  67. package/dist/palettes/palette-ocean.1.5.1.css +172 -0
  68. package/dist/palettes/palette-ocean.1.5.1.min.css +1 -0
  69. package/dist/palettes/palette-ocean.1.5.2.css +172 -0
  70. package/dist/palettes/palette-ocean.1.5.2.min.css +1 -0
  71. package/dist/palettes/palette-ocean.1.5.3.css +172 -0
  72. package/dist/palettes/palette-ocean.1.5.3.min.css +1 -0
  73. package/dist/palettes/palette-ocean.1.5.4.css +172 -0
  74. package/dist/palettes/palette-ocean.1.5.4.min.css +1 -0
  75. package/dist/palettes/palette-ocean.1.5.6.css +172 -0
  76. package/dist/palettes/palette-ocean.1.5.6.min.css +1 -0
  77. package/dist/palettes/palette-ocean.1.5.7.css +172 -0
  78. package/dist/palettes/palette-ocean.1.5.7.min.css +1 -0
  79. package/dist/palettes/palette-spring.1.4.9.css +160 -0
  80. package/dist/palettes/palette-spring.1.4.9.min.css +1 -0
  81. package/dist/palettes/palette-spring.1.5.0.css +160 -0
  82. package/dist/palettes/palette-spring.1.5.0.min.css +1 -0
  83. package/dist/palettes/palette-spring.1.5.1.css +160 -0
  84. package/dist/palettes/palette-spring.1.5.1.min.css +1 -0
  85. package/dist/palettes/palette-spring.1.5.2.css +160 -0
  86. package/dist/palettes/palette-spring.1.5.2.min.css +1 -0
  87. package/dist/palettes/palette-spring.1.5.3.css +166 -0
  88. package/dist/palettes/palette-spring.1.5.3.min.css +1 -0
  89. package/dist/palettes/palette-spring.1.5.4.css +166 -0
  90. package/dist/palettes/palette-spring.1.5.4.min.css +1 -0
  91. package/dist/palettes/palette-spring.1.5.6.css +166 -0
  92. package/dist/palettes/palette-spring.1.5.6.min.css +1 -0
  93. package/dist/palettes/palette-spring.1.5.7.css +166 -0
  94. package/dist/palettes/palette-spring.1.5.7.min.css +1 -0
  95. package/dist/palettes/palette-winter.1.4.9.css +172 -0
  96. package/dist/palettes/palette-winter.1.4.9.min.css +1 -0
  97. package/dist/palettes/palette-winter.1.5.0.css +172 -0
  98. package/dist/palettes/palette-winter.1.5.0.min.css +1 -0
  99. package/dist/palettes/palette-winter.1.5.1.css +172 -0
  100. package/dist/palettes/palette-winter.1.5.1.min.css +1 -0
  101. package/dist/palettes/palette-winter.1.5.2.css +172 -0
  102. package/dist/palettes/palette-winter.1.5.2.min.css +1 -0
  103. package/dist/palettes/palette-winter.1.5.3.css +172 -0
  104. package/dist/palettes/palette-winter.1.5.3.min.css +1 -0
  105. package/dist/palettes/palette-winter.1.5.4.css +172 -0
  106. package/dist/palettes/palette-winter.1.5.4.min.css +1 -0
  107. package/dist/palettes/palette-winter.1.5.6.css +172 -0
  108. package/dist/palettes/palette-winter.1.5.6.min.css +1 -0
  109. package/dist/palettes/palette-winter.1.5.7.css +172 -0
  110. package/dist/palettes/palette-winter.1.5.7.min.css +1 -0
  111. package/dist/utils/iconMap.d.ts +21 -8
  112. package/dist/utils/iconMap.d.ts.map +1 -1
  113. package/dist/utils/reactUtils.d.ts +0 -23
  114. package/dist/utils/reactUtils.d.ts.map +1 -1
  115. package/package.json +1 -1
  116. package/src/__tests__/utils/iconMap.test.tsx +197 -0
  117. package/src/components/QwickApp.tsx +24 -15
  118. package/src/components/ResponsiveMenu.tsx +3 -4
  119. package/src/components/Scaffold.tsx +3 -4
  120. package/src/components/index.ts +1 -0
  121. package/src/components/pages/Page.tsx +2 -2
  122. package/src/contexts/NavigationContext.tsx +168 -0
  123. package/src/contexts/index.ts +2 -0
  124. package/src/utils/iconMap.tsx +209 -151
  125. package/src/utils/reactUtils.tsx +2 -47
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ var iconsMaterial = require('@mui/icons-material');
10
10
  var classValidator = require('class-validator');
11
11
  require('reflect-metadata');
12
12
  var classTransformer = require('class-transformer');
13
+ var reactRouterDom = require('react-router-dom');
13
14
 
14
15
  /**
15
16
  * Breakpoint utilities for QwickApps React Framework
@@ -3074,181 +3075,189 @@ Code.transformCodeHighlight = element => {
3074
3075
  };
3075
3076
 
3076
3077
  /**
3077
- * Centralized icon registry mapping icon names to their representations
3078
- * Supports both Material-UI components and emoji for different contexts
3078
+ * Centralized icon registry mapping icon names to their representations.
3079
+ * Sorted alphabetically by category, then by key within each category.
3080
+ *
3081
+ * For icons not in this map, getIconComponent() will return a HelpOutline fallback
3082
+ * and log a warning. Use registerIcon() to add app-specific icons at runtime.
3079
3083
  */
3080
3084
  const iconMap = {
3081
- // Navigation & Layout
3082
- home: {
3083
- emoji: '🏠',
3084
- component: iconsMaterial.Home
3085
- },
3086
- menu: {
3087
- emoji: '☰',
3088
- component: iconsMaterial.Menu
3089
- },
3090
- dashboard: {
3091
- emoji: '📊',
3092
- component: iconsMaterial.Dashboard
3093
- },
3094
- // Information & Help
3095
- info: {
3096
- emoji: 'ℹ️',
3097
- component: iconsMaterial.Info
3098
- },
3099
- about: {
3100
- emoji: 'ℹ️',
3101
- component: iconsMaterial.Info
3102
- },
3103
- help: {
3104
- emoji: '❓',
3105
- component: iconsMaterial.Help
3106
- },
3107
- book: {
3108
- emoji: '📖',
3109
- component: iconsMaterial.Book
3110
- },
3111
- // Communication
3112
- email: {
3113
- emoji: '📧',
3114
- component: iconsMaterial.Email
3115
- },
3116
- contact: {
3117
- emoji: '📧',
3118
- component: iconsMaterial.Email
3119
- },
3120
- phone: {
3121
- emoji: '📱',
3122
- component: iconsMaterial.Phone
3123
- },
3124
- send: {
3125
- emoji: '📤',
3126
- component: iconsMaterial.Send
3127
- },
3128
- // Actions
3085
+ // === Actions ===
3129
3086
  add: {
3130
3087
  emoji: '➕',
3131
3088
  component: iconsMaterial.Add
3132
3089
  },
3133
- edit: {
3134
- emoji: '✏️',
3135
- component: iconsMaterial.Edit
3136
- },
3137
- delete: {
3138
- emoji: '🗑️',
3139
- component: iconsMaterial.Delete
3140
- },
3141
- save: {
3142
- emoji: '💾',
3143
- component: iconsMaterial.Save
3144
- },
3145
3090
  check: {
3146
3091
  emoji: '✓',
3147
3092
  component: iconsMaterial.Check
3148
3093
  },
3094
+ check_circle: {
3095
+ emoji: '✅',
3096
+ component: iconsMaterial.CheckCircle
3097
+ },
3149
3098
  close: {
3150
3099
  emoji: '✕',
3151
3100
  component: iconsMaterial.Close
3152
3101
  },
3153
- // Navigation
3154
- arrowforward: {
3155
- emoji: '→',
3156
- component: iconsMaterial.ArrowForward
3102
+ delete: {
3103
+ emoji: '🗑️',
3104
+ component: iconsMaterial.Delete
3157
3105
  },
3158
- arrowback: {
3159
- emoji: '',
3160
- component: iconsMaterial.ArrowBack
3106
+ edit: {
3107
+ emoji: '✏️',
3108
+ component: iconsMaterial.Edit
3109
+ },
3110
+ refresh: {
3111
+ emoji: '🔄',
3112
+ component: iconsMaterial.Refresh
3113
+ },
3114
+ rotate_right: {
3115
+ emoji: '🔄',
3116
+ component: iconsMaterial.RotateRight
3117
+ },
3118
+ save: {
3119
+ emoji: '💾',
3120
+ component: iconsMaterial.Save
3161
3121
  },
3162
- // Content
3163
3122
  search: {
3164
3123
  emoji: '🔍',
3165
3124
  component: iconsMaterial.Search
3166
3125
  },
3126
+ send: {
3127
+ emoji: '📤',
3128
+ component: iconsMaterial.Send
3129
+ },
3167
3130
  share: {
3168
3131
  emoji: '🔗',
3169
3132
  component: iconsMaterial.Share
3170
3133
  },
3171
- download: {
3172
- emoji: '⬇️',
3173
- component: iconsMaterial.Download
3134
+ sync: {
3135
+ emoji: '🔄',
3136
+ component: iconsMaterial.Sync
3174
3137
  },
3175
- clouddownload: {
3176
- emoji: '☁️⬇️',
3177
- component: iconsMaterial.CloudDownload
3138
+ // === Authentication & Security ===
3139
+ block: {
3140
+ emoji: '🚫',
3141
+ component: iconsMaterial.Block
3178
3142
  },
3179
- cloudupload: {
3180
- emoji: '☁️⬆️',
3181
- component: iconsMaterial.CloudUpload
3143
+ key: {
3144
+ emoji: '🔑',
3145
+ component: iconsMaterial.Key
3182
3146
  },
3183
- // User & Social
3184
- person: {
3185
- emoji: '👤',
3186
- component: iconsMaterial.Person
3147
+ lock: {
3148
+ emoji: '🔒',
3149
+ component: iconsMaterial.Lock
3187
3150
  },
3188
- user: {
3189
- emoji: '👤',
3190
- component: iconsMaterial.Person
3151
+ lock_open: {
3152
+ emoji: '🔓',
3153
+ component: iconsMaterial.LockOpen
3191
3154
  },
3192
- group: {
3193
- emoji: '👥',
3194
- component: iconsMaterial.Group
3155
+ lockopen: {
3156
+ emoji: '🔓',
3157
+ component: iconsMaterial.LockOpen
3195
3158
  },
3196
- favorite: {
3197
- emoji: '❤️',
3198
- component: iconsMaterial.Favorite
3159
+ // alias
3160
+ login: {
3161
+ emoji: '🔑',
3162
+ component: iconsMaterial.Login
3199
3163
  },
3200
- star: {
3201
- emoji: '',
3202
- component: iconsMaterial.Star
3164
+ logout: {
3165
+ emoji: '🚪',
3166
+ component: iconsMaterial.Logout
3167
+ },
3168
+ security: {
3169
+ emoji: '🔐',
3170
+ component: iconsMaterial.Security
3171
+ },
3172
+ shield: {
3173
+ emoji: '🛡️',
3174
+ component: iconsMaterial.Shield
3203
3175
  },
3204
3176
  verified_user: {
3205
3177
  emoji: '✅',
3206
3178
  component: iconsMaterial.VerifiedUser
3207
3179
  },
3208
- // Business
3180
+ visibility: {
3181
+ emoji: '👁️',
3182
+ component: iconsMaterial.Visibility
3183
+ },
3184
+ visibility_off: {
3185
+ emoji: '🙈',
3186
+ component: iconsMaterial.VisibilityOff
3187
+ },
3188
+ visibilityoff: {
3189
+ emoji: '🙈',
3190
+ component: iconsMaterial.VisibilityOff
3191
+ },
3192
+ // alias
3193
+ vpn_key: {
3194
+ emoji: '🔐',
3195
+ component: iconsMaterial.VpnKey
3196
+ },
3197
+ // === Business & Commerce ===
3198
+ attach_money: {
3199
+ emoji: '💰',
3200
+ component: iconsMaterial.AttachMoney
3201
+ },
3202
+ attachmoney: {
3203
+ emoji: '💰',
3204
+ component: iconsMaterial.AttachMoney
3205
+ },
3206
+ // alias
3209
3207
  business: {
3210
3208
  emoji: '🏢',
3211
3209
  component: iconsMaterial.Business
3212
3210
  },
3213
- shoppingcart: {
3211
+ cart: {
3214
3212
  emoji: '🛒',
3215
3213
  component: iconsMaterial.ShoppingCart
3216
3214
  },
3217
- cart: {
3215
+ // alias
3216
+ shopping_cart: {
3218
3217
  emoji: '🛒',
3219
3218
  component: iconsMaterial.ShoppingCart
3220
3219
  },
3221
- attachmoney: {
3222
- emoji: '💰',
3223
- component: iconsMaterial.AttachMoney
3220
+ shoppingcart: {
3221
+ emoji: '🛒',
3222
+ component: iconsMaterial.ShoppingCart
3224
3223
  },
3225
- // Security
3226
- lock: {
3227
- emoji: '🔒',
3228
- component: iconsMaterial.Lock
3224
+ // alias
3225
+ work: {
3226
+ emoji: '💼',
3227
+ component: iconsMaterial.Work
3229
3228
  },
3230
- lockopen: {
3231
- emoji: '🔓',
3232
- component: iconsMaterial.LockOpen
3229
+ workspace_premium: {
3230
+ emoji: '',
3231
+ component: iconsMaterial.WorkspacePremium
3233
3232
  },
3234
- visibility: {
3235
- emoji: '👁️',
3236
- component: iconsMaterial.Visibility
3233
+ // === Communication ===
3234
+ contact: {
3235
+ emoji: '📧',
3236
+ component: iconsMaterial.Email
3237
3237
  },
3238
- visibilityoff: {
3239
- emoji: '🙈',
3240
- component: iconsMaterial.VisibilityOff
3238
+ // alias
3239
+ email: {
3240
+ emoji: '📧',
3241
+ component: iconsMaterial.Email
3241
3242
  },
3242
- // System
3243
- settings: {
3244
- emoji: '⚙️',
3245
- component: iconsMaterial.Settings
3243
+ mail: {
3244
+ emoji: '📧',
3245
+ component: iconsMaterial.Email
3246
3246
  },
3247
- computer: {
3248
- emoji: '💻',
3249
- component: iconsMaterial.Computer
3247
+ // alias
3248
+ notifications: {
3249
+ emoji: '🔔',
3250
+ component: iconsMaterial.Notifications
3251
+ },
3252
+ phone: {
3253
+ emoji: '📱',
3254
+ component: iconsMaterial.Phone
3255
+ },
3256
+ support_agent: {
3257
+ emoji: '🛎️',
3258
+ component: iconsMaterial.SupportAgent
3250
3259
  },
3251
- // Content Types
3260
+ // === Content & Media ===
3252
3261
  article: {
3253
3262
  emoji: '📰',
3254
3263
  component: iconsMaterial.Article
@@ -3257,162 +3266,297 @@ const iconMap = {
3257
3266
  emoji: '📝',
3258
3267
  component: iconsMaterial.Book
3259
3268
  },
3269
+ // alias
3270
+ book: {
3271
+ emoji: '📖',
3272
+ component: iconsMaterial.Book
3273
+ },
3274
+ gallery: {
3275
+ emoji: '🖼️',
3276
+ component: iconsMaterial.InsertPhoto
3277
+ },
3278
+ // alias
3279
+ image: {
3280
+ emoji: '🖼️',
3281
+ component: iconsMaterial.InsertPhoto
3282
+ },
3283
+ insert_photo: {
3284
+ emoji: '🖼️',
3285
+ component: iconsMaterial.InsertPhoto
3286
+ },
3287
+ library_books: {
3288
+ emoji: '📚',
3289
+ component: iconsMaterial.LibraryBooks
3290
+ },
3260
3291
  news: {
3261
3292
  emoji: '📰',
3262
- component: iconsMaterial.Book
3293
+ component: iconsMaterial.Article
3263
3294
  },
3264
- products: {
3265
- emoji: '🛍️',
3266
- component: iconsMaterial.ShoppingCart
3295
+ // alias
3296
+ photo_library: {
3297
+ emoji: '📸',
3298
+ component: iconsMaterial.PhotoLibrary
3267
3299
  },
3268
- services: {
3269
- emoji: '⚙️',
3270
- component: iconsMaterial.Settings
3300
+ play: {
3301
+ emoji: '▶️',
3302
+ component: iconsMaterial.PlayArrow
3303
+ },
3304
+ // alias
3305
+ play_arrow: {
3306
+ emoji: '▶️',
3307
+ component: iconsMaterial.PlayArrow
3271
3308
  },
3272
3309
  portfolio: {
3273
3310
  emoji: '💼',
3274
3311
  component: iconsMaterial.Business
3275
3312
  },
3276
- gallery: {
3277
- emoji: '🖼️',
3278
- component: iconsMaterial.Business
3313
+ // alias
3314
+ // === Development & Technology ===
3315
+ architecture: {
3316
+ emoji: '🏛️',
3317
+ component: iconsMaterial.Architecture
3279
3318
  },
3280
- inventory: {
3281
- emoji: '📦',
3282
- component: iconsMaterial.Inventory
3319
+ autorenew: {
3320
+ emoji: '🔄',
3321
+ component: iconsMaterial.Autorenew
3283
3322
  },
3284
- inventory_2: {
3285
- emoji: '📦',
3286
- component: iconsMaterial.Inventory2
3323
+ cloud: {
3324
+ emoji: '☁️',
3325
+ component: iconsMaterial.Cloud
3287
3326
  },
3288
- speed: {
3289
- emoji: '',
3290
- component: iconsMaterial.Speed
3327
+ cloud_download: {
3328
+ emoji: '☁️⬇️',
3329
+ component: iconsMaterial.CloudDownload
3291
3330
  },
3292
- support_agent: {
3293
- emoji: '🛎️',
3294
- component: iconsMaterial.SupportAgent
3331
+ cloud_upload: {
3332
+ emoji: '☁️⬆️',
3333
+ component: iconsMaterial.CloudUpload
3295
3334
  },
3296
- tune: {
3297
- emoji: '🎛️',
3298
- component: iconsMaterial.Tune
3335
+ clouddownload: {
3336
+ emoji: '☁️⬇️',
3337
+ component: iconsMaterial.CloudDownload
3338
+ },
3339
+ // alias
3340
+ cloudupload: {
3341
+ emoji: '☁️⬆️',
3342
+ component: iconsMaterial.CloudUpload
3299
3343
  },
3300
- // Development & Technology
3344
+ // alias
3301
3345
  code: {
3302
3346
  emoji: '💻',
3303
3347
  component: iconsMaterial.Code
3304
3348
  },
3305
- psychology: {
3306
- emoji: '🧠',
3307
- component: iconsMaterial.Psychology
3349
+ computer: {
3350
+ emoji: '💻',
3351
+ component: iconsMaterial.Computer
3308
3352
  },
3309
- autorenew: {
3310
- emoji: '🔄',
3311
- component: iconsMaterial.Autorenew
3353
+ construction: {
3354
+ emoji: '🚧',
3355
+ component: iconsMaterial.Construction
3312
3356
  },
3313
3357
  integration_instructions: {
3314
3358
  emoji: '🔌',
3315
3359
  component: iconsMaterial.IntegrationInstructions
3316
3360
  },
3317
- construction: {
3318
- emoji: '🚧',
3319
- component: iconsMaterial.Construction
3361
+ memory: {
3362
+ emoji: '🧠',
3363
+ component: iconsMaterial.Memory
3320
3364
  },
3321
- work: {
3322
- emoji: '💼',
3323
- component: iconsMaterial.Work
3365
+ psychology: {
3366
+ emoji: '🧠',
3367
+ component: iconsMaterial.Psychology
3368
+ },
3369
+ rocket: {
3370
+ emoji: '🚀',
3371
+ component: iconsMaterial.Rocket
3372
+ },
3373
+ storage: {
3374
+ emoji: '💾',
3375
+ component: iconsMaterial.Storage
3376
+ },
3377
+ // === Navigation & Layout ===
3378
+ arrow_back: {
3379
+ emoji: '←',
3380
+ component: iconsMaterial.ArrowBack
3381
+ },
3382
+ arrow_forward: {
3383
+ emoji: '→',
3384
+ component: iconsMaterial.ArrowForward
3385
+ },
3386
+ arrowback: {
3387
+ emoji: '←',
3388
+ component: iconsMaterial.ArrowBack
3389
+ },
3390
+ // alias
3391
+ arrowforward: {
3392
+ emoji: '→',
3393
+ component: iconsMaterial.ArrowForward
3394
+ },
3395
+ // alias
3396
+ dashboard: {
3397
+ emoji: '📊',
3398
+ component: iconsMaterial.Dashboard
3399
+ },
3400
+ download: {
3401
+ emoji: '⬇️',
3402
+ component: iconsMaterial.Download
3403
+ },
3404
+ explore: {
3405
+ emoji: '🧭',
3406
+ component: iconsMaterial.Explore
3407
+ },
3408
+ home: {
3409
+ emoji: '🏠',
3410
+ component: iconsMaterial.Home
3324
3411
  },
3325
3412
  layers: {
3326
3413
  emoji: '📚',
3327
3414
  component: iconsMaterial.Layers
3328
3415
  },
3329
- trending_up: {
3330
- emoji: '📈',
3331
- component: iconsMaterial.TrendingUp
3416
+ menu: {
3417
+ emoji: '',
3418
+ component: iconsMaterial.Menu
3332
3419
  },
3333
3420
  route: {
3334
3421
  emoji: '🗺️',
3335
3422
  component: iconsMaterial.Route
3336
3423
  },
3337
- sync: {
3338
- emoji: '🔄',
3339
- component: iconsMaterial.Sync
3424
+ settings: {
3425
+ emoji: '⚙️',
3426
+ component: iconsMaterial.Settings
3340
3427
  },
3341
- architecture: {
3342
- emoji: '🏛️',
3343
- component: iconsMaterial.Architecture
3428
+ trending_up: {
3429
+ emoji: '📈',
3430
+ component: iconsMaterial.TrendingUp
3344
3431
  },
3345
- security: {
3346
- emoji: '🔐',
3347
- component: iconsMaterial.Security
3432
+ tune: {
3433
+ emoji: '🎛️',
3434
+ component: iconsMaterial.Tune
3348
3435
  },
3349
- // Control Panel & Admin UI Icons
3350
- key: {
3351
- emoji: '🔑',
3352
- component: iconsMaterial.Key
3436
+ // === Products & Inventory ===
3437
+ inventory: {
3438
+ emoji: '📦',
3439
+ component: iconsMaterial.Inventory
3353
3440
  },
3354
- vpn_key: {
3355
- emoji: '🔐',
3356
- component: iconsMaterial.VpnKey
3441
+ inventory_2: {
3442
+ emoji: '📦',
3443
+ component: iconsMaterial.Inventory2
3357
3444
  },
3358
- person_search: {
3359
- emoji: '🔍',
3360
- component: iconsMaterial.PersonSearch
3445
+ local_offer: {
3446
+ emoji: '🏷️',
3447
+ component: iconsMaterial.LocalOffer
3361
3448
  },
3362
- manage_accounts: {
3449
+ products: {
3450
+ emoji: '🛍️',
3451
+ component: iconsMaterial.ShoppingCart
3452
+ },
3453
+ // alias
3454
+ services: {
3455
+ emoji: '⚙️',
3456
+ component: iconsMaterial.Settings
3457
+ },
3458
+ // alias
3459
+ speed: {
3460
+ emoji: '⚡',
3461
+ component: iconsMaterial.Speed
3462
+ },
3463
+ // === Status & Feedback ===
3464
+ about: {
3465
+ emoji: 'ℹ️',
3466
+ component: iconsMaterial.Info
3467
+ },
3468
+ // alias
3469
+ favorite: {
3470
+ emoji: '❤️',
3471
+ component: iconsMaterial.Favorite
3472
+ },
3473
+ heart: {
3474
+ emoji: '❤️',
3475
+ component: iconsMaterial.Favorite
3476
+ },
3477
+ // alias
3478
+ help: {
3479
+ emoji: '❓',
3480
+ component: iconsMaterial.Help
3481
+ },
3482
+ info: {
3483
+ emoji: 'ℹ️',
3484
+ component: iconsMaterial.Info
3485
+ },
3486
+ star: {
3487
+ emoji: '⭐',
3488
+ component: iconsMaterial.Star
3489
+ },
3490
+ // === Users & People ===
3491
+ account_circle: {
3492
+ emoji: '👤',
3493
+ component: iconsMaterial.AccountCircle
3494
+ },
3495
+ group: {
3363
3496
  emoji: '👥',
3364
- component: iconsMaterial.ManageAccounts
3497
+ component: iconsMaterial.Group
3365
3498
  },
3366
- storage: {
3367
- emoji: '💾',
3368
- component: iconsMaterial.Storage
3499
+ manage_accounts: {
3500
+ emoji: '👤',
3501
+ component: iconsMaterial.ManageAccounts
3369
3502
  },
3370
- refresh: {
3371
- emoji: '🔄',
3372
- component: iconsMaterial.Refresh
3503
+ people: {
3504
+ emoji: '👥',
3505
+ component: iconsMaterial.People
3373
3506
  },
3374
- block: {
3375
- emoji: '🚫',
3376
- component: iconsMaterial.Block
3507
+ person: {
3508
+ emoji: '👤',
3509
+ component: iconsMaterial.Person
3377
3510
  },
3378
- check_circle: {
3379
- emoji: '',
3380
- component: iconsMaterial.CheckCircle
3511
+ person_search: {
3512
+ emoji: '🔍',
3513
+ component: iconsMaterial.PersonSearch
3381
3514
  },
3382
- rotate_right: {
3383
- emoji: '🔄',
3384
- component: iconsMaterial.RotateRight
3515
+ user: {
3516
+ emoji: '👤',
3517
+ component: iconsMaterial.Person
3385
3518
  },
3386
- memory: {
3387
- emoji: '🧠',
3388
- component: iconsMaterial.Memory
3389
- }
3519
+ // alias
3520
+ users: {
3521
+ emoji: '👥',
3522
+ component: iconsMaterial.People
3523
+ } // alias
3390
3524
  };
3391
3525
  /**
3392
3526
  * Get emoji representation of an icon
3393
- * @param iconName - Icon name (case-insensitive)
3527
+ * @param iconName - Icon name (case-insensitive, supports snake_case)
3394
3528
  * @param fallback - Fallback emoji if icon not found (default: 🔗)
3395
3529
  * @returns Emoji string
3396
3530
  */
3397
3531
  function getIconEmoji(iconName, fallback = '🔗') {
3398
3532
  if (!iconName) return fallback;
3399
- const mapping = iconMap[iconName.toLowerCase()];
3400
- return mapping?.emoji || iconName;
3533
+ const normalized = iconName.toLowerCase();
3534
+ const mapping = iconMap[normalized];
3535
+ return mapping?.emoji || fallback;
3401
3536
  }
3402
3537
  /**
3403
- * Get Material-UI component representation of an icon
3404
- * @param iconName - Icon name (case-insensitive)
3405
- * @returns React element or null if not found
3538
+ * Get Material-UI component representation of an icon.
3539
+ *
3540
+ * Uses the static iconMap for known icons. For unmapped icons,
3541
+ * returns a HelpOutline fallback and logs a warning.
3542
+ *
3543
+ * @param iconName - Icon name (case-insensitive, supports snake_case)
3544
+ * @returns React element (mapped icon or HelpOutline fallback), or null if no name provided
3406
3545
  */
3407
3546
  function getIconComponent(iconName) {
3408
3547
  if (!iconName) return null;
3409
- const mapping = iconMap[iconName.toLowerCase()];
3410
- if (!mapping?.component) {
3411
- console.warn(`[IconMap] Icon "${iconName}" not found in registry`);
3412
- return null;
3548
+ const normalized = iconName.toLowerCase();
3549
+ const mapping = iconMap[normalized];
3550
+ if (mapping?.component) {
3551
+ const IconComponent = mapping.component;
3552
+ return jsxRuntime.jsx(IconComponent, {});
3553
+ }
3554
+ // Fallback: Return HelpOutline icon and warn about unmapped icon
3555
+ // Use registerIcon() to add app-specific icons at runtime
3556
+ {
3557
+ console.warn(`[IconMap] Icon "${iconName}" not found. Add it to iconMap or use registerIcon().`);
3413
3558
  }
3414
- const IconComponent = mapping.component;
3415
- return jsxRuntime.jsx(IconComponent, {});
3559
+ return jsxRuntime.jsx(iconsMaterial.HelpOutline, {});
3416
3560
  }
3417
3561
  /**
3418
3562
  * Register a new icon or override an existing one
@@ -3422,13 +3566,14 @@ function registerIcon(name, mapping) {
3422
3566
  iconMap[name.toLowerCase()] = mapping;
3423
3567
  }
3424
3568
  /**
3425
- * Check if an icon is registered
3569
+ * Check if an icon is registered in the static map
3570
+ * If false, getIconComponent will return HelpOutline fallback
3426
3571
  */
3427
3572
  function hasIcon(iconName) {
3428
3573
  return iconName.toLowerCase() in iconMap;
3429
3574
  }
3430
3575
  /**
3431
- * Get all registered icon names
3576
+ * Get all registered icon names from the static map
3432
3577
  */
3433
3578
  function getRegisteredIcons() {
3434
3579
  return Object.keys(iconMap);
@@ -4817,41 +4962,6 @@ var FormBlockModel = exports.FormBlockModel;
4817
4962
  *
4818
4963
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
4819
4964
  */
4820
- /**
4821
- * Get the current location from browser or undefined in SSR
4822
- * Works without relying on routing libraries
4823
- * @returns {object | undefined} - The location object if in browser, otherwise undefined
4824
- */
4825
- const useSafeLocation = () => {
4826
- // Use browser location if available (works in any React app)
4827
- if (typeof window !== 'undefined') {
4828
- return {
4829
- pathname: window.location.pathname,
4830
- search: window.location.search,
4831
- hash: window.location.hash
4832
- };
4833
- }
4834
- return undefined;
4835
- };
4836
- /**
4837
- * Get a navigation function with fallback to window.location
4838
- * Works without relying on routing libraries
4839
- * @returns {NavigateFunction} - The navigate function
4840
- */
4841
- const useSafeNavigate = () => {
4842
- // Return function that uses window.location
4843
- return to => {
4844
- if (typeof to === 'string') {
4845
- if (typeof window !== 'undefined') {
4846
- window.location.href = to;
4847
- }
4848
- } else if (typeof to === 'number') {
4849
- if (typeof window !== 'undefined' && window.history) {
4850
- window.history.go(to);
4851
- }
4852
- }
4853
- };
4854
- };
4855
4965
  /**
4856
4966
  * Extract text content from ReactNode for code processing
4857
4967
  * Handles natural React usage like <Code>const x = 1;</Code>
@@ -23388,6 +23498,121 @@ const useDimensions = () => {
23388
23498
  return context;
23389
23499
  };
23390
23500
 
23501
+ const NavigationContext = /*#__PURE__*/React.createContext(null);
23502
+ /**
23503
+ * Internal provider that uses React Router hooks
23504
+ * Only rendered when we're inside a Router context
23505
+ */
23506
+ function ReactRouterNavigationProvider({
23507
+ children
23508
+ }) {
23509
+ const reactRouterNavigate = reactRouterDom.useNavigate();
23510
+ const reactRouterLocation = reactRouterDom.useLocation();
23511
+ const navigate = to => {
23512
+ if (typeof to === 'string') {
23513
+ reactRouterNavigate(to);
23514
+ } else if (typeof to === 'number') {
23515
+ reactRouterNavigate(to);
23516
+ }
23517
+ };
23518
+ // Defensive check for location - fall back to window.location if React Router's location is undefined
23519
+ const location = reactRouterLocation ? {
23520
+ pathname: reactRouterLocation.pathname,
23521
+ search: reactRouterLocation.search,
23522
+ hash: reactRouterLocation.hash
23523
+ } : typeof window !== 'undefined' ? {
23524
+ pathname: window.location.pathname,
23525
+ search: window.location.search,
23526
+ hash: window.location.hash
23527
+ } : undefined;
23528
+ return jsxRuntime.jsx(NavigationContext.Provider, {
23529
+ value: {
23530
+ navigate,
23531
+ location
23532
+ },
23533
+ children: children
23534
+ });
23535
+ }
23536
+ /**
23537
+ * Internal provider that uses window.location fallback
23538
+ * Used when not inside a React Router context
23539
+ */
23540
+ function FallbackNavigationProvider({
23541
+ children
23542
+ }) {
23543
+ const navigate = to => {
23544
+ if (typeof window === 'undefined') return;
23545
+ if (typeof to === 'string') {
23546
+ window.location.href = to;
23547
+ } else if (typeof to === 'number') {
23548
+ window.history.go(to);
23549
+ }
23550
+ };
23551
+ const location = typeof window !== 'undefined' ? {
23552
+ pathname: window.location.pathname,
23553
+ search: window.location.search,
23554
+ hash: window.location.hash
23555
+ } : undefined;
23556
+ return jsxRuntime.jsx(NavigationContext.Provider, {
23557
+ value: {
23558
+ navigate,
23559
+ location
23560
+ },
23561
+ children: children
23562
+ });
23563
+ }
23564
+ /**
23565
+ * Smart Navigation Provider
23566
+ *
23567
+ * Automatically detects if the app is inside a React Router context:
23568
+ * - If inside Router: uses React Router's useNavigate/useLocation (respects basename)
23569
+ * - If outside Router: falls back to window.location
23570
+ *
23571
+ * This is included automatically by QwickApp - you don't need to add it manually.
23572
+ */
23573
+ function NavigationProvider({
23574
+ children
23575
+ }) {
23576
+ // Check if we're inside a React Router using the official hook
23577
+ // This is more reliable than checking internal UNSAFE contexts
23578
+ const isInRouter = reactRouterDom.useInRouterContext();
23579
+ if (isInRouter) {
23580
+ // We're inside a Router, use React Router's navigation
23581
+ return jsxRuntime.jsx(ReactRouterNavigationProvider, {
23582
+ children: children
23583
+ });
23584
+ }
23585
+ // Not inside a Router, use window.location fallback
23586
+ return jsxRuntime.jsx(FallbackNavigationProvider, {
23587
+ children: children
23588
+ });
23589
+ }
23590
+ /**
23591
+ * Hook to access navigation functions
23592
+ *
23593
+ * @returns Object containing navigate function and current location
23594
+ *
23595
+ * @example
23596
+ * ```tsx
23597
+ * function MyComponent() {
23598
+ * const { navigate, location } = useNavigation();
23599
+ *
23600
+ * const handleClick = () => {
23601
+ * navigate('/dashboard');
23602
+ * };
23603
+ *
23604
+ * return <button onClick={handleClick}>Go to Dashboard</button>;
23605
+ * }
23606
+ * ```
23607
+ */
23608
+ function useNavigation() {
23609
+ const context = React.useContext(NavigationContext);
23610
+ if (!context) {
23611
+ throw new Error('useNavigation must be used within a NavigationProvider. ' + 'Make sure your component is wrapped in QwickApp or NavigationProvider.');
23612
+ }
23613
+ return context;
23614
+ }
23615
+
23391
23616
  /**
23392
23617
  * Schema for PaletteSwitcher component - Color palette switching control
23393
23618
  *
@@ -24535,7 +24760,9 @@ const PageView = ({
24535
24760
  };
24536
24761
  }, [isPrintMode, printConfig]);
24537
24762
  // Route (fallback to current location)
24538
- const location = useSafeLocation();
24763
+ const {
24764
+ location
24765
+ } = useNavigation();
24539
24766
  const actualRoute = resolved.route || location?.pathname || '';
24540
24767
  // Context value
24541
24768
  const contextValue = React.useMemo(() => ({
@@ -24650,9 +24877,11 @@ const Scaffold = ({
24650
24877
  const [isDrawerOpen, setIsDrawerOpen] = React.useState(false);
24651
24878
  const [isRailExpanded, setIsRailExpanded] = React.useState(false);
24652
24879
  const [isMounted, setIsMounted] = React.useState(false);
24653
- // React Router hooks (if available)
24654
- const location = useSafeLocation();
24655
- const navigate = useSafeNavigate();
24880
+ // Navigation (uses React Router if available, falls back to window.location)
24881
+ const {
24882
+ navigate,
24883
+ location
24884
+ } = useNavigation();
24656
24885
  const currentPath = isMounted ? location?.pathname : undefined;
24657
24886
  // Debug logging for navigation
24658
24887
  React.useEffect(() => {
@@ -25021,9 +25250,11 @@ const ResponsiveMenu = props => {
25021
25250
  appName,
25022
25251
  logo: contextLogo
25023
25252
  } = useQwickApp$1();
25024
- // React Router hooks (if available)
25025
- const navigate = useSafeNavigate();
25026
- const location = useSafeLocation();
25253
+ // Navigation (uses React Router if available, falls back to window.location)
25254
+ const {
25255
+ navigate,
25256
+ location
25257
+ } = useNavigation();
25027
25258
  const currentPath = location?.pathname;
25028
25259
  // Debug logging
25029
25260
  React.useEffect(() => {
@@ -25898,6 +26129,15 @@ const QwickApp = ({
25898
26129
  ...updates
25899
26130
  }));
25900
26131
  };
26132
+ // Sync logo prop changes with internal state (for dynamic logo updates)
26133
+ React.useEffect(() => {
26134
+ if (resolvedConfig.logo !== appConfig.logo) {
26135
+ setAppConfig(prev => ({
26136
+ ...prev,
26137
+ logo: resolvedConfig.logo
26138
+ }));
26139
+ }
26140
+ }, [resolvedConfig.logo]);
25901
26141
  const contextValue = {
25902
26142
  appName: resolvedConfig.appName,
25903
26143
  // Safe to use ! since we validated above
@@ -25925,17 +26165,19 @@ const QwickApp = ({
25925
26165
  }) : content;
25926
26166
  const appContent = jsxRuntime.jsx(ErrorBoundary, {
25927
26167
  children: jsxRuntime.jsx(AccessibilityProvider, {
25928
- children: jsxRuntime.jsx("div", {
25929
- className: `qwick-app ${className || ''}`,
25930
- style: style,
25931
- children: jsxRuntime.jsx(ThemeProvider, {
25932
- appId: resolvedConfig.appId,
25933
- defaultTheme: resolvedConfig.defaultTheme,
25934
- defaultPalette: resolvedConfig.defaultPalette,
25935
- children: jsxRuntime.jsx(QwickAppContext.Provider, {
25936
- value: contextValue,
25937
- children: jsxRuntime.jsx(PrintModeProvider, {
25938
- children: wrappedContent
26168
+ children: jsxRuntime.jsx(NavigationProvider, {
26169
+ children: jsxRuntime.jsx("div", {
26170
+ className: `qwick-app ${className || ''}`,
26171
+ style: style,
26172
+ children: jsxRuntime.jsx(ThemeProvider, {
26173
+ appId: resolvedConfig.appId,
26174
+ defaultTheme: resolvedConfig.defaultTheme,
26175
+ defaultPalette: resolvedConfig.defaultPalette,
26176
+ children: jsxRuntime.jsx(QwickAppContext.Provider, {
26177
+ value: contextValue,
26178
+ children: jsxRuntime.jsx(PrintModeProvider, {
26179
+ children: wrappedContent
26180
+ })
25939
26181
  })
25940
26182
  })
25941
26183
  })
@@ -31854,6 +32096,7 @@ exports.Image = Image;
31854
32096
  exports.Logo = Logo;
31855
32097
  exports.Markdown = Markdown;
31856
32098
  exports.ModelView = ModelView;
32099
+ exports.NavigationProvider = NavigationProvider;
31857
32100
  exports.Page = Page;
31858
32101
  exports.PageBannerHeader = PageBannerHeader;
31859
32102
  exports.PaletteAutumn = PaletteAutumn;
@@ -31954,14 +32197,13 @@ exports.useDataBinding = useDataBinding;
31954
32197
  exports.useDataContext = useDataContext;
31955
32198
  exports.useDataProvider = useDataProvider;
31956
32199
  exports.useDimensions = useDimensions;
32200
+ exports.useNavigation = useNavigation;
31957
32201
  exports.usePageContext = usePageContext;
31958
32202
  exports.usePalette = usePalette;
31959
32203
  exports.usePrintMode = usePrintMode$1;
31960
32204
  exports.usePrintModeHook = usePrintMode;
31961
32205
  exports.useQwickApp = useQwickApp;
31962
32206
  exports.useResolveTemplate = useResolveTemplate;
31963
- exports.useSafeLocation = useSafeLocation;
31964
- exports.useSafeNavigate = useSafeNavigate;
31965
32207
  exports.useTemplate = useTemplate;
31966
32208
  exports.useTheme = useTheme;
31967
32209
  exports.withAccessibility = withAccessibility;