solara 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a886519a93f39b2e87df6f2f427fa72e6baf9d4f3520424a7c86c207cb684e56
4
- data.tar.gz: e5f0f1673493a4177eaf70ba1af01ef6de900074f8c934c6b15600197f2af474
3
+ metadata.gz: b672162bbb4a247a016626afacc37b2deaab1dbde0c2f86e30a4ceedeb8a635d
4
+ data.tar.gz: a0e53ed9ce61d791a50df3c292b1c096414903e7c573164e7553089048f289cc
5
5
  SHA512:
6
- metadata.gz: cd784de6b07c8208c290f6cdb00827e0aa2e44f0f10d19e584592bca6d1aa2d7c7bb195c599286500dbacb71662956b6247f1fb7ca82daf40f0c60ab0022e4ad
7
- data.tar.gz: 0e920bd5ba5938eac7933c40708df506762620bb3466ff743851361f414845d396c363e66145008b3b46a539ca3633f2117ecee6c44cc862764f3014112a8df6
6
+ metadata.gz: a22345201f6d5756cc2a54702dc8a0db0806d4fd1fd47f9f85dfde81545368908d22408345dae944bc004c4fe3507ceef563e6044cf7a90daad5a157efb1295f
7
+ data.tar.gz: be3473d1802240cf75b4f934561e22302cbf93dee710dead6c0439b474e3b7c16ca858f3b647e480e04a493622ce9b8da488135179bca97caa808feedd1b2b18
Binary file
@@ -81,7 +81,6 @@ class BrandDetailController {
81
81
  async addNewBrand() {
82
82
  this.view.showOnboardBrandForm(async (key, name) => {
83
83
  const configurations = await this.model.createNewBrandConfogurations()
84
- console.log(configurations)
85
84
  await this.addBrand(key, name, configurations)
86
85
  })
87
86
  }
@@ -143,20 +142,19 @@ class BrandDetailController {
143
142
  const sectionItems = configuraationsResult.configurations
144
143
 
145
144
  for (let i = 0; i < sectionItems.length; i++) {
146
- const sectionInfo = sectionItems[i];
147
- console.log('Processing section:', i, sectionInfo);
145
+ const sectionData = sectionItems[i];
148
146
 
149
- if (sectionInfo.key === 'theme.json') {
150
- this.createThemeSections(sectionInfo)
151
- } else if (sectionInfo.key === 'InfoPlist.xcstrings') {
147
+ if (sectionData.key === 'theme.json') {
148
+ this.createThemeSections(sectionData)
149
+ } else if (sectionData.key === 'InfoPlist.xcstrings') {
152
150
  this.createSection(
153
- sectionInfo.key,
154
- sectionInfo,
155
- new InfoPlistStringCatalogManager(sectionInfo.content).extractLocalizations(),
156
- sectionInfo.name,
157
- sectionInfo.inputType)
151
+ sectionData.key,
152
+ sectionData,
153
+ new InfoPlistStringCatalogManager(sectionData.content).extractLocalizations(),
154
+ sectionData.name,
155
+ sectionData.inputType)
158
156
  } else {
159
- this.createSection(sectionInfo.key, sectionInfo, sectionInfo.content, sectionInfo.name, sectionInfo.inputType)
157
+ this.createSection(sectionData.key, sectionData, sectionData.content, sectionData.name, sectionData.inputType)
160
158
  }
161
159
  }
162
160
  } catch (error) {
@@ -165,55 +163,53 @@ class BrandDetailController {
165
163
  }
166
164
  }
167
165
 
168
- createThemeSections(sectionInfo) {
169
- this.createSection(`${sectionInfo.key}_colors`,
170
- sectionInfo,
171
- sectionInfo.content.colors,
166
+ createThemeSections(sectionData) {
167
+ this.createSection(`${sectionData.key}_colors`,
168
+ sectionData,
169
+ sectionData.content.colors,
172
170
  'Theme Colors',
173
171
  'color',
174
172
  'colors')
175
- this.createSection(`${sectionInfo.key}_typography`,
176
- sectionInfo,
177
- sectionInfo.content.typography,
173
+ this.createSection(`${sectionData.key}_typography`,
174
+ sectionData,
175
+ sectionData.content.typography,
178
176
  'Theme Typography',
179
177
  'text',
180
178
  'typography')
181
- this.createSection(`${sectionInfo.key}_spacing`,
182
- sectionInfo,
183
- sectionInfo.content.spacing,
179
+ this.createSection(`${sectionData.key}_spacing`,
180
+ sectionData,
181
+ sectionData.content.spacing,
184
182
  'Theme Spacing', 'text',
185
183
  'spacing')
186
184
  this.createSection(
187
- `${sectionInfo.key}_borderRadius`,
188
- sectionInfo,
189
- sectionInfo.content.borderRadius,
185
+ `${sectionData.key}_borderRadius`,
186
+ sectionData,
187
+ sectionData.content.borderRadius,
190
188
  'Theme Border Radius',
191
189
  'text',
192
190
  'borderRadius')
193
191
  this.createSection(
194
- `${sectionInfo.key}_elevation`,
195
- sectionInfo,
196
- sectionInfo.content.elevation,
192
+ `${sectionData.key}_elevation`,
193
+ sectionData,
194
+ sectionData.content.elevation,
197
195
  'Theme Elevation',
198
196
  'text',
199
197
  'elevation')
200
198
  }
201
199
 
202
- createSection(id, sectionInfo, content, sectionName, inputType, propertiesGroupName = null) {
203
- const sectionElement = this.view.createSection(sectionInfo.key, sectionName, inputType);
200
+ createSection(id, sectionData, content, sectionName, inputType, propertiesGroupName = null) {
201
+ const sectionElement = this.view.createSection(sectionData.key, sectionName, inputType);
204
202
  sectionElement.id = id;
205
203
  sectionElement.dataset.propertiesGroupName = propertiesGroupName
206
204
 
207
205
  this.view.sectionsContainer.appendChild(sectionElement);
208
206
 
209
- console.log('Section element created:', sectionElement);
210
-
211
- this.view.populateSection(sectionInfo, sectionElement, content, inputType);
207
+ this.view.populateJsonFields(sectionData, sectionElement, content, inputType);
212
208
 
213
209
  const addButton = document.createElement('button');
214
210
  addButton.textContent = 'Add Field';
215
211
  addButton.className = 'add-field-btn';
216
- addButton.onclick = () => this.addNewField(sectionInfo, sectionElement, inputType);
212
+ addButton.onclick = () => this.addNewField(sectionData, sectionElement, inputType);
217
213
  sectionElement.appendChild(addButton);
218
214
  }
219
215
 
@@ -229,25 +225,60 @@ class BrandDetailController {
229
225
  }
230
226
  }
231
227
 
232
- getSectionConfiguration(sectionElement) {
233
- const configuration = {};
234
- const inputs = sectionElement.querySelectorAll('input:not(.array-item-input)');
235
- inputs.forEach(input => {
236
- const keys = input.id.split('.');
237
- let current = configuration;
238
- for (let i = 0; i < keys.length - 1; i++) {
239
- if (!current[keys[i]]) {
240
- current[keys[i]] = {};
228
+ collectJsonData(container) {
229
+ const data = {};
230
+ const level = container.dataset.level
231
+
232
+ const jsonObjects = container.querySelectorAll(`.json-object-${level}`);
233
+ jsonObjects.forEach(jsonObject => {
234
+ const jsonObjectLabel = jsonObject.querySelector('label').textContent;
235
+ data[jsonObjectLabel] = this.collectJsonData(jsonObject);
236
+
237
+ });
238
+
239
+ const group = container.querySelectorAll(`.json-array-${level}`);
240
+ group.forEach(arrayItem => {
241
+ const label = arrayItem.querySelector('label').textContent;
242
+ const items = arrayItem.querySelectorAll(`.json-array-item-${level}`);
243
+ const indexed = arrayItem.querySelectorAll(`.json-array-item-indexed-${level}`).length !== 0;
244
+
245
+ data[label] = Array.from(items).map((item, index) => {
246
+ const values = this.collectJsonData(item)
247
+ if (indexed) {
248
+ return values[index]
241
249
  }
242
- current = current[keys[i]];
243
- }
244
- const lastKey = keys[keys.length - 1];
250
+ return values;
251
+ });
252
+ });
253
+
254
+ const result = this.collectJsonFields(container, level);
255
+
256
+ Object.keys(data).forEach(key => {
257
+ result[key] = data[key];
258
+ });
259
+ return result
260
+ }
261
+
262
+ collectJsonFields(container, level) {
263
+ const result = {};
264
+
265
+ const inputFields = container.querySelectorAll(`.json-field-${level}`);
266
+ inputFields.forEach(inputField => {
267
+ const values = this.getInputFieldsData(inputField);
268
+ Object.keys(values).forEach(key => {
269
+ result[key] = values[key];
270
+ });
271
+ })
272
+ return result
273
+ }
274
+
275
+ getInputFieldsData(container) {
276
+ const data = {};
245
277
 
246
- if (input.classList.contains('array-input')) {
247
- const arrayItemsContainer = input.closest('.input-wrapper').querySelector('.array-items-container');
248
- current[lastKey] = this.getArrayValue(arrayItemsContainer);
249
- } else if (input.type === 'checkbox') {
250
- current[lastKey] = input.checked;
278
+ const inputs = container.querySelectorAll('input');
279
+ inputs.forEach(input => {
280
+ if (input.type === 'checkbox') {
281
+ data[input.id] = input.checked;
251
282
  } else {
252
283
  let value = input.value;
253
284
  if (input.type === 'color') {
@@ -256,10 +287,11 @@ class BrandDetailController {
256
287
  // Convert to number if it's a valid number string
257
288
  value = parseFloat(value);
258
289
  }
259
- current[lastKey] = value;
290
+ data[input.id] = value;
260
291
  }
261
292
  });
262
- return configuration;
293
+
294
+ return data;
263
295
  }
264
296
 
265
297
  addNewField(sectionItem, sectionElement, inputType) {
@@ -326,12 +358,12 @@ class BrandDetailController {
326
358
  .filter(element => element.dataset.key === sectionKey);
327
359
 
328
360
  if (sectionElements.length === 1) {
329
- return this.getSectionConfiguration(sectionElements[0])
361
+ return this.collectJsonData(sectionElements[0])
330
362
  }
331
363
 
332
364
  const configurations = sectionElements.map(sectionElement => {
333
365
  const propertiesGroupName = sectionElement.dataset.propertiesGroupName;
334
- const config = this.getSectionConfiguration(sectionElement);
366
+ const config = this.collectJsonData(sectionElement);
335
367
 
336
368
  if (propertiesGroupName !== "null") {
337
369
  return {[propertiesGroupName]: config};
@@ -340,16 +372,12 @@ class BrandDetailController {
340
372
  }
341
373
  });
342
374
 
343
- const result = configurations.reduce((acc, config) => {
375
+ return configurations.reduce((acc, config) => {
344
376
  const key = Object.keys(config)[0]; // Get the key from the configuration item
345
377
  acc[key] = config[key]; // Assign the value to the dynamic object
346
378
  return acc;
347
379
  }, {});
348
380
 
349
- const json = JSON.stringify(result, null, 2); // Pretty-printing JSON
350
- console.log(json);
351
- return result;
352
-
353
381
  } catch (error) {
354
382
  console.error('Error downloading brand:', error);
355
383
  alert(error.message);
@@ -399,5 +427,4 @@ class BrandDetailController {
399
427
  }
400
428
 
401
429
 
402
-
403
430
  export default BrandDetailController;
@@ -92,67 +92,111 @@ class BrandDetailView {
92
92
  return section;
93
93
  }
94
94
 
95
- populateSection(sectionItem, sectionElement, content, inputType) {
95
+ populateJsonFields(data, container, content, inputType, level = 0) {
96
+ container.dataset.key = data.key
97
+ container.dataset.level = `${level}`
98
+
96
99
  for (const [key, value] of Object.entries(content)) {
97
100
  if (Array.isArray(value)) {
98
- sectionElement.appendChild(this.createInputField(sectionItem, key, value, 'array'));
99
- } else if (typeof value === 'object' && value !== null) {
100
- for (const [subKey, subValue] of Object.entries(value)) {
101
- const subInputType = subValue === true || subValue === false ? 'boolean' : inputType;
102
- sectionElement.appendChild(this.createInputField(sectionItem, `${key}.${subKey}`, subValue, subInputType));
103
- }
104
- } else {
105
- const fieldInputType = value === true || value === false ? 'boolean' : inputType;
106
- sectionElement.appendChild(this.createInputField(sectionItem, key, value, fieldInputType));
101
+ this.populateJsonArray(key, value, data, container, content, inputType, level)
102
+ continue
107
103
  }
104
+
105
+ if (value !== null && typeof value === 'object') {
106
+ this.populateJsonObject(key, value, data, container, content, inputType, level)
107
+ continue
108
+ }
109
+
110
+ const fieldElement = this.createJsonField(data, key, value, inputType, level)
111
+ container.appendChild(fieldElement);
108
112
  }
109
113
  }
110
114
 
111
- createInputField(sectionItem, key, value, inputType) {
112
- const container = document.createElement('div');
113
- container.className = 'input-group';
115
+ populateJsonArray(key, value, data, container, content, inputType, level) {
116
+ const arrayContainer = document.createElement('div');
117
+ arrayContainer.className = 'json-array';
118
+ arrayContainer.classList.add(`json-array-${level}`);
119
+
120
+ const labelContainer = document.createElement('div');
121
+ labelContainer.className = 'json-array-label-group';
114
122
  const label = document.createElement('label');
115
123
  label.textContent = key;
116
- container.appendChild(label);
117
-
118
- const inputWrapper = document.createElement('div');
119
- inputWrapper.className = 'input-wrapper';
120
-
121
- if (inputType === 'array') {
122
- const arrayInputContainer = document.createElement('div');
123
- arrayInputContainer.className = 'array-input-container';
124
-
125
- const input = document.createElement('input');
126
- input.type = 'text';
127
- input.id = key;
128
- input.className = 'array-input';
129
- input.placeholder = 'Enter array value';
124
+ labelContainer.appendChild(label);
130
125
 
126
+ // TODO: to be implemented later
127
+ if (false) {
131
128
  const addButton = document.createElement('button');
132
129
  addButton.className = 'add-array-item';
133
130
  addButton.textContent = '+';
131
+ let lastItemIndex = value.length - 1
132
+ addButton.addEventListener('click', () => {
133
+ const itemContainer = document.createElement('div');
134
+ itemContainer.className = 'json-array-item';
134
135
 
135
- arrayInputContainer.appendChild(input);
136
- arrayInputContainer.appendChild(addButton);
136
+ lastItemIndex += 1
137
+ let fieldKey = `${key}[${lastItemIndex}]`
137
138
 
138
- const arrayItemsContainer = document.createElement('div');
139
- arrayItemsContainer.className = 'array-items-container';
139
+ const indexed = container.querySelectorAll(`.json-array-item-indexed-${level}`).length !== 0;
140
+ if (indexed) {
141
+ fieldKey = lastItemIndex
142
+ }
143
+ const field = this.createJsonField(data, fieldKey, '', inputType, level + 1)
144
+ field.classList.add(`json-array-item-${level}`);
145
+ itemContainer.appendChild(field);
140
146
 
141
- inputWrapper.appendChild(arrayInputContainer);
142
- inputWrapper.appendChild(arrayItemsContainer);
147
+ arrayContainer.insertBefore(itemContainer, arrayContainer.lastElementChild);
143
148
 
144
- if (Array.isArray(value)) {
145
- value.forEach(item => {
146
- this.addArrayItem(sectionItem, arrayItemsContainer, item);
147
- });
149
+ this.onSectionChanged(data, container.closest('.section'));
150
+ });
151
+ }
152
+ arrayContainer.appendChild(labelContainer);
153
+
154
+ value.forEach((item, index) => {
155
+ const itemContainer = document.createElement('div');
156
+ itemContainer.className = 'json-array-item';
157
+ itemContainer.classList.add(`json-array-item-${level}`);
158
+ if (typeof item === 'object' && item !== null) {
159
+ this.populateJsonFields(data, itemContainer, item, inputType, level + 1);
160
+ } else {
161
+ itemContainer.dataset.level = `${level + 1}`
162
+ const field = this.createJsonField(data, `${index}`, item, inputType, level + 1)
163
+ itemContainer.classList.add(`json-array-item-indexed-${level}`);
164
+ itemContainer.appendChild(field);
148
165
  }
166
+ arrayContainer.appendChild(itemContainer);
167
+ });
149
168
 
150
- addButton.addEventListener('click', () => {
151
- this.addArrayItem(sectionItem, arrayItemsContainer, input.value.trim());
152
- input.value = '';
153
- });
169
+ // TODO: to be implemented later
170
+ // arrayContainer.appendChild(addButton);
171
+ container.appendChild(arrayContainer);
172
+ }
173
+
174
+ populateJsonObject(key, value, data, container, content, inputType, level) {
175
+ const objectContainer = document.createElement('div');
176
+ objectContainer.className = 'json-object';
177
+ objectContainer.classList.add(`json-object-${level}`);
178
+ const objectLabel = document.createElement('label');
179
+ objectLabel.className = 'json-object-title';
180
+ objectLabel.textContent = key;
181
+ objectContainer.appendChild(objectLabel);
182
+
183
+ this.populateJsonFields(data, objectContainer, value, inputType, level + 1);
154
184
 
155
- } else if (inputType === 'boolean') {
185
+ container.appendChild(objectContainer);
186
+ }
187
+
188
+ createJsonField(data, key, value, inputType, level) {
189
+ const fieldInputType = typeof value === 'boolean' ? 'boolean' : inputType;
190
+ const container = document.createElement('div');
191
+ container.className = 'input-group';
192
+ const label = document.createElement('label');
193
+ label.textContent = key;
194
+ container.appendChild(label);
195
+
196
+ const inputWrapper = document.createElement('div');
197
+ inputWrapper.className = 'input-wrapper';
198
+
199
+ if (fieldInputType === 'boolean') {
156
200
  const checkbox = document.createElement('input');
157
201
  checkbox.type = 'checkbox';
158
202
  checkbox.id = key;
@@ -165,18 +209,18 @@ class BrandDetailView {
165
209
 
166
210
  checkbox.addEventListener('change', () => {
167
211
  checkboxLabel.textContent = checkbox.checked ? 'True' : 'False';
168
- this.onSectionChanged(sectionItem, container.closest('.section'));
212
+ this.onSectionChanged(data, container.closest('.section'));
169
213
  });
170
214
 
171
215
  inputWrapper.appendChild(checkbox);
172
216
  inputWrapper.appendChild(checkboxLabel);
173
217
  } else {
174
218
  const input = document.createElement('input');
175
- input.type = inputType;
219
+ input.type = fieldInputType;
176
220
  input.id = key;
177
221
 
178
222
  console.log(value)
179
- if (inputType === 'color') {
223
+ if (fieldInputType === 'color') {
180
224
  input.value = value.startsWith('#') ? value : `#${value.substring(4)}`;
181
225
  } else {
182
226
  input.value = value;
@@ -188,45 +232,23 @@ class BrandDetailView {
188
232
  const deleteIcon = document.createElement('span');
189
233
  deleteIcon.className = 'delete-icon';
190
234
  deleteIcon.textContent = '×';
191
- deleteIcon.onclick = () => this.onDeleteField(sectionItem, container);
235
+ deleteIcon.onclick = () => this.onDeleteField(data, container);
192
236
  inputWrapper.appendChild(deleteIcon);
193
237
 
194
238
  container.appendChild(inputWrapper);
195
239
 
196
- container.addEventListener('change', () => this.onSectionChanged(sectionItem, container.closest('.section')));
240
+ container.addEventListener('change', () => this.onSectionChanged(data, container.closest('.section')));
197
241
 
198
- return container;
199
- }
200
-
201
- addArrayItem(sectionItem, container, value) {
202
- const itemContainer = document.createElement('div');
203
- itemContainer.classList.add('array-item');
204
-
205
- const itemInput = document.createElement('input');
206
- itemInput.type = 'text';
207
- itemInput.classList.add('array-item-input');
208
- itemInput.value = value;
209
-
210
- const deleteButton = document.createElement('button');
211
- deleteButton.classList.add('delete-array-item');
212
- deleteButton.textContent = '×';
213
- deleteButton.addEventListener('click', () => {
214
- itemContainer.remove();
215
- this.onSectionChanged(sectionItem, container.closest('.section'));
216
- });
242
+ container.classList.add(`json-field-${level}`);
217
243
 
218
- itemContainer.appendChild(itemInput);
219
- itemContainer.appendChild(deleteButton);
220
- container.appendChild(itemContainer);
221
-
222
- this.onSectionChanged(sectionItem, container.closest('.section'));
244
+ return container;
223
245
  }
224
246
 
225
- showAddFieldForm(sectionItem, sectionElement, inputType) {
247
+ showAddFieldForm(data, sectionElement, inputType) {
226
248
  this.addFieldSheet.show(inputType, (name, value) => {
227
- const newField = this.createInputField(sectionItem, name, value, inputType);
249
+ const newField = this.createJsonField(data, name, value, inputType, 0);
228
250
  sectionElement.insertBefore(newField, sectionElement.lastElementChild);
229
- this.onSectionChanged(sectionItem, sectionElement);
251
+ this.onSectionChanged(data, sectionElement);
230
252
  })
231
253
  }
232
254
 
@@ -118,7 +118,8 @@
118
118
  font-size: 1.4em;
119
119
  }
120
120
  .input-group {
121
- margin-bottom: 17.5px;
121
+ min-width: 80%;
122
+ margin-bottom: 10px;
122
123
  display: flex;
123
124
  align-items: center;
124
125
  background-color: white;
@@ -149,7 +150,7 @@
149
150
  display: inline-block;
150
151
  margin-right: 7px;
151
152
  font-weight: bold;
152
- min-width: 175px;
153
+ min-width: 10%;
153
154
  flex-shrink: 0;
154
155
  }
155
156
  input, select {
@@ -177,19 +178,6 @@
177
178
  background-color: #3CC2A3;
178
179
  }
179
180
 
180
- .save-section-btn {
181
- background-color: #28a745;
182
- margin-top: 7px;
183
- margin-right: 7px;
184
- }
185
- .save-section-btn:hover {
186
- background-color: #218838;
187
- }
188
- .button-group {
189
- display: flex;
190
- justify-content: flex-start;
191
- margin-top: 14px;
192
- }
193
181
  .delete-icon {
194
182
  color: var(--delete-color);
195
183
  cursor: pointer;
@@ -233,18 +221,6 @@
233
221
  }
234
222
  }
235
223
 
236
- .array-input-container {
237
- display: flex;
238
- align-items: center;
239
- margin-bottom: 3.5px;
240
- width: 100%;
241
- }
242
-
243
- .array-input {
244
- flex-grow: 1;
245
- margin-right: 5.6px;
246
- }
247
-
248
224
  .add-array-item {
249
225
  background-color: #4CAF50;
250
226
  color: white;
@@ -254,30 +230,6 @@
254
230
  cursor: pointer;
255
231
  }
256
232
 
257
- .array-items-container {
258
- margin-top: 3.5px;
259
- width: 100%;
260
- }
261
-
262
- .array-item {
263
- display: flex;
264
- align-items: center;
265
- margin-bottom: 3.5px;
266
- }
267
-
268
- .array-item-input {
269
- flex-grow: 1;
270
- margin: 11.2px;
271
- }
272
-
273
- .delete-array-item {
274
- background-color: #f44336;
275
- color: white;
276
- border: none;
277
- padding: 1.4px 4.2px;
278
- border-radius: 2.8px;
279
- cursor: pointer;
280
- }
281
233
  .logo {
282
234
  width: 52.5px;
283
235
  height: 52.5px;
@@ -544,6 +496,44 @@
544
496
  filter: drop-shadow(2.1px 2.1px 2.1px rgba(0, 0, 0, 0.3));
545
497
  transition: transform 0.3s ease;
546
498
  }
499
+
500
+ .json-object {
501
+ margin-bottom: 10px;
502
+ border: 3px solid #1e88e5; /* Blue border */
503
+ padding: 10px;
504
+ }
505
+ .json-object-title {
506
+ font-weight: bold;
507
+ flex-shrink: 0;
508
+ color: black;
509
+ font-size: 16px;
510
+ margin-bottom: 10px;
511
+ }
512
+
513
+ .json-array {
514
+ border-left: 2px solid #ff9800; /* Orange border */
515
+ padding: 10px;
516
+ }
517
+
518
+ .json-array-item {
519
+ margin-left: 20px;
520
+ }
521
+
522
+ .json-array-label-group {
523
+ min-width: 80%;
524
+ margin-bottom: 17.5px;
525
+ display: flex;
526
+ align-items: center;
527
+ background-color: white;
528
+ border-radius: 5.6px;
529
+ box-shadow: var(--field-shadow);
530
+ padding: 7px;
531
+ transition: box-shadow 0.3s ease;
532
+ }
533
+ .json-array-label-group:hover {
534
+ box-shadow: 0 2.8px 5.6px rgba(0, 0, 0, 0.15);
535
+ }
536
+
547
537
  </style>
548
538
  </head>
549
539
  <body>
@@ -591,11 +581,11 @@
591
581
  <img src="../solara.png" alt="Solara Logo">
592
582
  <h2>Solara simplifies the management of your brand configurations, allowing you to access and update them anytime, anywhere.</h2>
593
583
  <div class="button-message">You can select a JSON file containing brand configurations that were exported using Solara.</div>
594
- <button id="uploadJsonBtn" style=" animation-delay: 0.5s;">Upload JSON</button>
595
- <div class="button-message" style=" animation-delay: 0.7s;">Alternatively, upload from a folder that includes the brand's JSON files.</div>
596
- <button id="uploadBrandBtn" style=" animation-delay: 0.9s;">Upload Folder</button>
597
- <div class="button-message" style=" animation-delay: 1.1s;">You also have the option to create new brand configurations.</div>
598
- <button id="newBrandBtn" style=" animation-delay: 1.3s;">New Brand</button>
584
+ <button id="uploadJsonBtn" style=" animation-delay: 0.5s;">Upload JSON</button>
585
+ <div class="button-message" style=" animation-delay: 0.7s;">Alternatively, upload from a folder that includes the brand's JSON files.</div>
586
+ <button id="uploadBrandBtn" style=" animation-delay: 0.9s;">Upload Folder</button>
587
+ <div class="button-message" style=" animation-delay: 1.1s;">You also have the option to create new brand configurations.</div>
588
+ <button id="newBrandBtn" style=" animation-delay: 1.3s;">New Brand</button>
599
589
  </div>
600
590
 
601
591
  </div>
@@ -1,3 +1,3 @@
1
1
  module Solara
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solara
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Malek Kamel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-10 00:00:00.000000000 Z
11
+ date: 2024-10-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor