windmill-components 1.79.0 → 1.82.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.
Files changed (204) hide show
  1. package/components/ArgInput.svelte +3 -0
  2. package/components/ArgInput.svelte.d.ts +1 -0
  3. package/components/DisplayResult.svelte +18 -15
  4. package/components/Multiselect.svelte.d.ts +2 -2
  5. package/components/SchemaEditor.svelte +15 -10
  6. package/components/SettingSection.svelte +1 -1
  7. package/components/Toggle.svelte +5 -2
  8. package/components/Toggle.svelte.d.ts +1 -0
  9. package/components/apps/components/buttons/AppButton.svelte +35 -56
  10. package/components/apps/components/buttons/AppButton.svelte.d.ts +2 -1
  11. package/components/apps/components/buttons/AppForm.svelte +24 -24
  12. package/components/apps/components/buttons/AppForm.svelte.d.ts +1 -1
  13. package/components/apps/components/buttons/AppFormButton.svelte +79 -94
  14. package/components/apps/components/buttons/AppFormButton.svelte.d.ts +1 -3
  15. package/components/apps/components/display/AppBarChart.svelte +2 -2
  16. package/components/apps/components/display/AppBarChart.svelte.d.ts +1 -1
  17. package/components/apps/components/display/AppDisplayComponent.svelte +2 -2
  18. package/components/apps/components/display/AppDisplayComponent.svelte.d.ts +1 -1
  19. package/components/apps/components/display/AppHtml.svelte +10 -2
  20. package/components/apps/components/display/AppHtml.svelte.d.ts +1 -1
  21. package/components/apps/components/display/AppIcon.svelte +4 -1
  22. package/components/apps/components/display/AppIcon.svelte.d.ts +1 -1
  23. package/components/apps/components/display/AppImage.svelte +28 -15
  24. package/components/apps/components/display/AppImage.svelte.d.ts +1 -1
  25. package/components/apps/components/display/AppMap.svelte.d.ts +1 -1
  26. package/components/apps/components/display/AppPdf.svelte +3 -2
  27. package/components/apps/components/display/AppPdf.svelte.d.ts +1 -1
  28. package/components/apps/components/display/AppPieChart.svelte +2 -2
  29. package/components/apps/components/display/AppPieChart.svelte.d.ts +1 -1
  30. package/components/apps/components/display/AppScatterChart.svelte +2 -2
  31. package/components/apps/components/display/AppScatterChart.svelte.d.ts +1 -1
  32. package/components/apps/components/display/AppText.svelte +35 -22
  33. package/components/apps/components/display/AppText.svelte.d.ts +1 -1
  34. package/components/apps/components/display/AppTimeseries.svelte +2 -2
  35. package/components/apps/components/display/AppTimeseries.svelte.d.ts +1 -1
  36. package/components/apps/components/display/PlotlyHtml.svelte +3 -3
  37. package/components/apps/components/display/VegaLiteHtml.svelte +2 -2
  38. package/components/apps/components/display/table/AppAggridTable.svelte +1 -1
  39. package/components/apps/components/display/table/AppTable.svelte +40 -17
  40. package/components/apps/components/display/table/AppTable.svelte.d.ts +1 -1
  41. package/components/apps/components/helpers/HiddenComponent.svelte +6 -3
  42. package/components/apps/components/helpers/HiddenComponent.svelte.d.ts +1 -1
  43. package/components/apps/components/helpers/InputValue.svelte +9 -9
  44. package/components/apps/components/helpers/Loader.svelte +18 -0
  45. package/components/apps/components/helpers/Loader.svelte.d.ts +18 -0
  46. package/components/apps/components/helpers/NonRunnableComponent.svelte +1 -12
  47. package/components/apps/components/helpers/ResolveConfig.svelte +29 -0
  48. package/components/apps/components/helpers/ResolveConfig.svelte.d.ts +21 -0
  49. package/components/apps/components/helpers/RunnableComponent.svelte +117 -89
  50. package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +14 -3
  51. package/components/apps/components/helpers/RunnableWrapper.svelte +50 -9
  52. package/components/apps/components/helpers/RunnableWrapper.svelte.d.ts +27 -2
  53. package/components/apps/components/inputs/AppCheckbox.svelte +1 -1
  54. package/components/apps/components/inputs/AppCheckbox.svelte.d.ts +1 -1
  55. package/components/apps/components/inputs/AppDateInput.svelte.d.ts +1 -1
  56. package/components/apps/components/inputs/AppFileInput.svelte.d.ts +1 -1
  57. package/components/apps/components/inputs/AppMultiSelect.svelte +0 -1
  58. package/components/apps/components/inputs/AppMultiSelect.svelte.d.ts +1 -1
  59. package/components/apps/components/inputs/AppNumberInput.svelte +1 -1
  60. package/components/apps/components/inputs/AppNumberInput.svelte.d.ts +1 -3
  61. package/components/apps/components/inputs/AppRangeInput.svelte +7 -1
  62. package/components/apps/components/inputs/AppRangeInput.svelte.d.ts +2 -1
  63. package/components/apps/components/inputs/AppSelect.svelte +8 -3
  64. package/components/apps/components/inputs/AppSelect.svelte.d.ts +1 -1
  65. package/components/apps/components/inputs/AppSliderInputs.svelte +7 -1
  66. package/components/apps/components/inputs/AppSliderInputs.svelte.d.ts +2 -1
  67. package/components/apps/components/inputs/AppTextInput.svelte +4 -4
  68. package/components/apps/components/inputs/AppTextInput.svelte.d.ts +1 -3
  69. package/components/apps/components/inputs/currency/AppCurrencyInput.svelte +17 -19
  70. package/components/apps/components/inputs/currency/AppCurrencyInput.svelte.d.ts +1 -1
  71. package/components/apps/components/layout/AppContainer.svelte +7 -4
  72. package/components/apps/components/layout/AppContainer.svelte.d.ts +1 -1
  73. package/components/apps/components/layout/AppDivider.svelte +4 -1
  74. package/components/apps/components/layout/AppDivider.svelte.d.ts +1 -1
  75. package/components/apps/components/layout/AppDrawer.svelte +7 -4
  76. package/components/apps/components/layout/AppDrawer.svelte.d.ts +1 -1
  77. package/components/apps/components/layout/AppSplitpanes.svelte +34 -21
  78. package/components/apps/components/layout/AppSplitpanes.svelte.d.ts +1 -3
  79. package/components/apps/components/layout/AppTabs.svelte +17 -34
  80. package/components/apps/components/layout/AppTabs.svelte.d.ts +1 -2
  81. package/components/apps/editor/AppEditor.svelte +17 -13
  82. package/components/apps/editor/AppEditorHeader.svelte +2 -3
  83. package/components/apps/editor/AppPreview.svelte +11 -17
  84. package/components/apps/editor/ComponentHeader.svelte +10 -8
  85. package/components/apps/editor/ComponentHeader.svelte.d.ts +0 -1
  86. package/components/apps/editor/GridEditor.svelte +21 -50
  87. package/components/apps/editor/GridEditor.svelte.d.ts +0 -2
  88. package/components/apps/editor/RecomputeAllComponents.svelte +13 -2
  89. package/components/apps/editor/SettingsPanel.svelte +103 -40
  90. package/components/apps/editor/SubGridEditor.svelte +32 -41
  91. package/components/apps/editor/SubGridEditor.svelte.d.ts +1 -2
  92. package/components/apps/editor/appUtils.d.ts +49 -7
  93. package/components/apps/editor/appUtils.js +133 -37
  94. package/components/apps/editor/component/Component.svelte +22 -11
  95. package/components/apps/editor/component/Component.svelte.d.ts +1 -2
  96. package/components/apps/editor/component/ComponentNavigation.svelte +19 -12
  97. package/components/apps/editor/component/README.md +4 -0
  98. package/components/apps/editor/component/components.d.ts +1550 -17
  99. package/components/apps/editor/component/components.js +295 -325
  100. package/components/apps/editor/component/default-codes.d.ts +1 -1
  101. package/components/apps/editor/component/default-codes.js +25 -25
  102. package/components/apps/editor/componentsPanel/ComponentList.svelte +18 -3
  103. package/components/apps/editor/componentsPanel/CssProperty.svelte +92 -50
  104. package/components/apps/editor/componentsPanel/CssProperty.svelte.d.ts +8 -3
  105. package/components/apps/editor/componentsPanel/CssSettings.svelte +48 -90
  106. package/components/apps/editor/componentsPanel/ListItem.svelte +3 -0
  107. package/components/apps/editor/componentsPanel/ListItem.svelte.d.ts +2 -0
  108. package/components/apps/editor/componentsPanel/QuickStyleMenu.svelte +167 -0
  109. package/components/apps/editor/componentsPanel/QuickStyleMenu.svelte.d.ts +18 -0
  110. package/components/apps/editor/componentsPanel/QuickStyleProperty.svelte +130 -0
  111. package/components/apps/editor/componentsPanel/QuickStyleProperty.svelte.d.ts +21 -0
  112. package/components/apps/editor/componentsPanel/quickStyleProperties.d.ts +535 -0
  113. package/components/apps/editor/componentsPanel/quickStyleProperties.js +595 -0
  114. package/components/apps/editor/inlineScriptsPanel/EmptyInlineScript.svelte +1 -1
  115. package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte +146 -130
  116. package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte.d.ts +2 -1
  117. package/components/apps/editor/inlineScriptsPanel/InlineScriptEditorPanel.svelte +31 -3
  118. package/components/apps/editor/inlineScriptsPanel/InlineScriptEditorPanel.svelte.d.ts +1 -0
  119. package/components/apps/editor/inlineScriptsPanel/InlineScriptsPanel.svelte +42 -76
  120. package/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelList.svelte +67 -17
  121. package/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelList.svelte.d.ts +1 -3
  122. package/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelWithTable.svelte +27 -0
  123. package/components/apps/editor/inlineScriptsPanel/InlineScriptsPanelWithTable.svelte.d.ts +17 -0
  124. package/components/apps/editor/inlineScriptsPanel/utils.d.ts +2 -0
  125. package/components/apps/editor/inlineScriptsPanel/utils.js +6 -5
  126. package/components/apps/editor/settingsPanel/AlignmentEditor.svelte +10 -2
  127. package/components/apps/editor/settingsPanel/ArrayStaticInputEditor.svelte +37 -31
  128. package/components/apps/editor/settingsPanel/ArrayStaticInputEditor.svelte.d.ts +4 -104
  129. package/components/apps/editor/settingsPanel/ComponentPanel.svelte +113 -67
  130. package/components/apps/editor/settingsPanel/ComponentPanel.svelte.d.ts +5 -3
  131. package/components/apps/editor/settingsPanel/GridTab.svelte +0 -1
  132. package/components/apps/editor/settingsPanel/InputsSpecEditor.svelte +99 -80
  133. package/components/apps/editor/settingsPanel/InputsSpecEditor.svelte.d.ts +8 -0
  134. package/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte +25 -2
  135. package/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte.d.ts +1 -0
  136. package/components/apps/editor/settingsPanel/OneOfInputSpecsEditor.svelte +52 -0
  137. package/components/apps/editor/settingsPanel/OneOfInputSpecsEditor.svelte.d.ts +28 -0
  138. package/components/apps/editor/settingsPanel/SelectedRunnable.svelte +70 -26
  139. package/components/apps/editor/settingsPanel/SelectedRunnable.svelte.d.ts +2 -0
  140. package/components/apps/editor/settingsPanel/StylePanel.svelte +23 -0
  141. package/components/apps/editor/settingsPanel/StylePanel.svelte.d.ts +17 -0
  142. package/components/apps/editor/settingsPanel/SubTypeEditor.svelte +7 -5
  143. package/components/apps/editor/settingsPanel/SubTypeEditor.svelte.d.ts +3 -2
  144. package/components/apps/editor/settingsPanel/TableActions.svelte +8 -63
  145. package/components/apps/editor/settingsPanel/inputEditor/ColorInput.svelte +12 -12
  146. package/components/apps/editor/settingsPanel/inputEditor/ColorInput.svelte.d.ts +3 -4
  147. package/components/apps/editor/settingsPanel/inputEditor/ConnectedInputEditor.svelte +3 -1
  148. package/components/apps/editor/settingsPanel/inputEditor/IconSelectInput.svelte.d.ts +2 -4
  149. package/components/apps/editor/settingsPanel/inputEditor/RunnableInputEditor.svelte +5 -5
  150. package/components/apps/editor/settingsPanel/inputEditor/RunnableInputEditor.svelte.d.ts +2 -0
  151. package/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte +48 -32
  152. package/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte.d.ts +8 -2
  153. package/components/apps/editor/settingsPanel/inputEditor/TabSelectInput.svelte +46 -0
  154. package/components/apps/editor/settingsPanel/inputEditor/TabSelectInput.svelte.d.ts +20 -0
  155. package/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte +7 -0
  156. package/components/apps/editor/settingsPanel/mainInput/RunnableSelector.svelte.d.ts +1 -0
  157. package/components/apps/editor/settingsPanel/secondaryMenu/SecondaryMenu.svelte +47 -0
  158. package/components/apps/editor/settingsPanel/secondaryMenu/SecondaryMenu.svelte.d.ts +14 -0
  159. package/components/apps/editor/settingsPanel/secondaryMenu/index.d.ts +2 -0
  160. package/components/apps/editor/settingsPanel/secondaryMenu/index.js +2 -0
  161. package/components/apps/editor/settingsPanel/secondaryMenu/menuStore.d.ts +12 -0
  162. package/components/apps/editor/settingsPanel/secondaryMenu/menuStore.js +10 -0
  163. package/components/apps/editor/settingsPanel/triggerLists/BackgroundScriptTriggerList.svelte +20 -70
  164. package/components/apps/editor/settingsPanel/triggerLists/BackgroundScriptTriggerList.svelte.d.ts +1 -0
  165. package/components/apps/editor/settingsPanel/triggerLists/ComponentTriggerList.svelte +14 -8
  166. package/components/apps/editor/settingsPanel/triggerLists/ComponentTriggerList.svelte.d.ts +5 -1
  167. package/components/apps/editor/settingsPanel/triggerLists/TriggerBadgesList.svelte +85 -27
  168. package/components/apps/editor/settingsPanel/triggerLists/TriggerBadgesList.svelte.d.ts +4 -6
  169. package/components/apps/gridUtils.js +1 -1
  170. package/components/apps/inputType.d.ts +12 -16
  171. package/components/apps/rx.d.ts +2 -0
  172. package/components/apps/rx.js +8 -2
  173. package/components/apps/svelte-grid/Grid.svelte +0 -4
  174. package/components/apps/svelte-grid/Grid.svelte.d.ts +1 -1
  175. package/components/apps/svelte-grid/MoveResize.svelte +24 -30
  176. package/components/apps/svelte-grid/MoveResize.svelte.d.ts +0 -4
  177. package/components/apps/svelte-grid/types.d.ts +1 -7
  178. package/components/apps/svelte-grid/utils/helper.js +6 -10
  179. package/components/apps/types.d.ts +22 -22
  180. package/components/apps/utils.d.ts +2 -2
  181. package/components/apps/utils.js +13 -11
  182. package/components/common/button/ButtonPopup.svelte +5 -2
  183. package/components/common/button/ButtonPopup.svelte.d.ts +5 -1
  184. package/components/common/button/ButtonPopupItem.svelte +2 -1
  185. package/components/common/button/ButtonPopupItem.svelte.d.ts +1 -0
  186. package/components/common/clearableInput/ClearableInput.svelte +56 -0
  187. package/components/common/clearableInput/ClearableInput.svelte.d.ts +28 -0
  188. package/components/common/index.d.ts +1 -0
  189. package/components/common/index.js +1 -0
  190. package/components/common/kbd/Kbd.svelte +4 -1
  191. package/components/common/kbd/Kbd.svelte.d.ts +6 -14
  192. package/components/common/menu/Menu.svelte +8 -2
  193. package/components/common/menu/Menu.svelte.d.ts +4 -1
  194. package/components/common/modal/AlwaysMountedModal.svelte +109 -0
  195. package/components/common/modal/AlwaysMountedModal.svelte.d.ts +22 -0
  196. package/components/common/skeleton/Skeleton.svelte +1 -1
  197. package/components/flows/flowStateUtils.js +8 -1
  198. package/package.json +672 -659
  199. package/utils.d.ts +1 -0
  200. package/utils.js +3 -0
  201. package/components/apps/editor/GridPanel.svelte +0 -31
  202. package/components/apps/editor/GridPanel.svelte.d.ts +0 -18
  203. package/components/apps/editor/componentsPanel/componentStaticValues.d.ts +0 -12
  204. package/components/apps/editor/componentsPanel/componentStaticValues.js +0 -25
@@ -1,3 +1,3 @@
1
- import type { AppComponent } from ".";
1
+ import type { AppComponent } from '.';
2
2
  export declare function defaultCode(component: string, language: string): string | undefined;
3
3
  export declare const DEFAULT_CODES: Partial<Record<AppComponent['type'], Record<'deno' | 'python3', string>>>;
@@ -4,32 +4,32 @@ export function defaultCode(component, language) {
4
4
  export const DEFAULT_CODES = {
5
5
  tablecomponent: {
6
6
  deno: `export async function main() {
7
- return [
8
- {
9
- "id": 1,
10
- "name": "A cell with a long name",
11
- "age": 42
12
- },
13
- {
14
- "id": 2,
15
- "name": "A briefer cell",
16
- "age": 84
17
- }
18
- ]
19
- }`,
7
+ return [
8
+ {
9
+ "id": 1,
10
+ "name": "A cell with a long name",
11
+ "age": 42
12
+ },
13
+ {
14
+ "id": 2,
15
+ "name": "A briefer cell",
16
+ "age": 84
17
+ }
18
+ ]
19
+ }`,
20
20
  python3: `def main():
21
- return [
22
- {
23
- "id": 1,
24
- "name": "A cell with a long name",
25
- "age": 42
26
- },
27
- {
28
- "id": 2,
29
- "name": "A briefer cell",
30
- "age": 84
31
- }
32
- ]`
21
+ return [
22
+ {
23
+ "id": 1,
24
+ "name": "A cell with a long name",
25
+ "age": 42
26
+ },
27
+ {
28
+ "id": 2,
29
+ "name": "A briefer cell",
30
+ "age": 84
31
+ }
32
+ ]`
33
33
  },
34
34
  textcomponent: {
35
35
  deno: `export async function main() {
@@ -3,7 +3,7 @@ import { fade, slide } from 'svelte/transition';
3
3
  import { dirtyStore } from '../../../common/confirmationModal/dirtyStore';
4
4
  import { components as componentsRecord, COMPONENT_SETS } from '../component';
5
5
  import ListItem from './ListItem.svelte';
6
- import { insertNewGridItem } from '../appUtils';
6
+ import { appComponentFromType, insertNewGridItem } from '../appUtils';
7
7
  import { X } from 'lucide-svelte';
8
8
  import { push } from '../../../../history';
9
9
  import { flip } from 'svelte/animate';
@@ -12,9 +12,9 @@ const { history } = getContext('AppEditorContext');
12
12
  function addComponent(appComponentType) {
13
13
  push(history, $app);
14
14
  $dirtyStore = true;
15
- const data = componentsRecord[appComponentType].data;
16
- const id = insertNewGridItem($app, data, $focusedGrid);
15
+ const id = insertNewGridItem($app, appComponentFromType(appComponentType), $focusedGrid);
17
16
  $selectedComponent = id;
17
+ $app = $app;
18
18
  $worldStore = $worldStore;
19
19
  }
20
20
  let search = '';
@@ -44,6 +44,21 @@ $: componentsFiltered = COMPONENT_SETS.map((set) => ({
44
44
  </button>
45
45
  {/if}
46
46
  </div>
47
+ <!-- {#if $focusedGrid}
48
+ <Badge color="indigo" baseClass="w-full">
49
+ <div class="flex flex-row gap-2 justify-center items-center">
50
+ <div>{`Subgrid: ${$focusedGrid.parentComponentId} (${$focusedGrid.subGridIndex})`}</div>
51
+ <button
52
+ on:click={() => {
53
+ $selectedComponent = undefined
54
+ $focusedGrid = undefined
55
+ }}
56
+ >
57
+ <X size={14} />
58
+ </button>
59
+ </div>
60
+ </Badge>
61
+ {/if} -->
47
62
  </section>
48
63
 
49
64
  <div class="relative">
@@ -1,65 +1,107 @@
1
- <script>import { X } from 'lucide-svelte';
1
+ <script>import { Forward, Paintbrush2 } from 'lucide-svelte';
2
+ import { createEventDispatcher, getContext } from 'svelte';
2
3
  import { fade } from 'svelte/transition';
3
- import { addWhitespaceBeforeCapitals } from '../../../../utils';
4
+ import { addWhitespaceBeforeCapitals, sendUserToast } from '../../../../utils';
5
+ import { Button, ClearableInput } from '../../../common';
6
+ import Popover from '../../../Popover.svelte';
7
+ import QuickStyleMenu from './QuickStyleMenu.svelte';
4
8
  export let name;
5
- export let value;
6
- function reset(property) {
7
- if (value) {
8
- value[property] = '';
9
+ export let componentType = undefined;
10
+ export let value = {};
11
+ export let forceStyle = false;
12
+ export let forceClass = false;
13
+ export let quickStyleProperties = undefined;
14
+ const { app } = getContext('AppViewerContext');
15
+ const dispatch = createEventDispatcher();
16
+ let isQuickMenuOpen = false;
17
+ $: dispatch('change', value);
18
+ function toggleQuickMenu() {
19
+ isQuickMenuOpen = !isQuickMenuOpen;
20
+ }
21
+ function applyToAllInstances() {
22
+ if (componentType &&
23
+ componentType in ($app?.css || {}) &&
24
+ name in ($app?.css?.[componentType] || {})) {
25
+ $app.css[componentType][name].style = value.style;
26
+ sendUserToast(`Applied style to all instances of the ${componentType.replace('component', '')} component`);
9
27
  }
10
28
  }
11
29
  </script>
12
30
 
13
- <div class="text-sm font-semibold text-gray-500 capitalize pt-2">
31
+ <div
32
+ class="sticky top-0 z-20 text-lg bg-white font-semibold [font-variant:small-caps] text-gray-700 pt-2 pb-1"
33
+ >
14
34
  {addWhitespaceBeforeCapitals(name)}
15
35
  </div>
16
36
  {#if value}
17
- <div class="border-l border-gray-400/80 py-1 pl-3.5 mt-1 ml-0.5">
18
- {#if value.style !== undefined}
19
- <label class="block pb-2">
20
- <div class="text-xs font-medium pb-0.5"> Style </div>
21
- <div class="relative">
22
- <input
23
- on:keydown|stopPropagation
24
- type="text"
25
- class="!pr-7"
26
- bind:value={value.style}
27
- on:focus
28
- />
29
- {#if value?.style}
30
- <button
31
- transition:fade|local={{ duration: 100 }}
32
- class="absolute z-10 top-1.5 right-1 rounded-full p-1 duration-200 hover:bg-gray-200"
33
- aria-label="Remove styles"
34
- on:click|preventDefault|stopPropagation={() => reset('style')}
35
- >
36
- <X size={14} />
37
- </button>
38
- {/if}
39
- </div>
40
- </label>
37
+ <div class="border-l border-gray-400/80 py-1 pl-3.5 ml-0.5">
38
+ {#if value.style !== undefined || forceStyle}
39
+ <div class="pb-2">
40
+ <!-- svelte-ignore a11y-label-has-associated-control -->
41
+ <label class="block">
42
+ <div class="text-sm font-medium text-gray-600 pb-0.5"> Style </div>
43
+ <div class="flex gap-1">
44
+ <div class="relative grow">
45
+ <ClearableInput
46
+ bind:value={value.style}
47
+ type="textarea"
48
+ wrapperClass="h-full min-h-[72px]"
49
+ inputClass="h-full"
50
+ />
51
+ </div>
52
+ <div class="flex flex-col gap-1">
53
+ {#if componentType}
54
+ <Popover placement="bottom" notClickable disapperTimoout={0}>
55
+ <Button
56
+ variant="border"
57
+ color="light"
58
+ size="xs"
59
+ btnClasses="!p-1 !w-[34px] !h-[34px]"
60
+ aria-label="Apply to all instances of this component"
61
+ on:click={applyToAllInstances}
62
+ >
63
+ <Forward size={18} />
64
+ </Button>
65
+ <svelte:fragment slot="text">
66
+ Apply to all instances of this component
67
+ </svelte:fragment>
68
+ </Popover>
69
+ {/if}
70
+ {#if quickStyleProperties?.length}
71
+ <Popover placement="bottom" notClickable disapperTimoout={0}>
72
+ <Button
73
+ variant="border"
74
+ color="light"
75
+ size="xs"
76
+ btnClasses="!p-1 !w-[34px] !h-[34px] {isQuickMenuOpen
77
+ ? '!bg-gray-200/60 hover:!bg-gray-200'
78
+ : ''}"
79
+ aria-label="{isQuickMenuOpen ? 'Close' : 'Open'} styling menu"
80
+ on:click={toggleQuickMenu}
81
+ >
82
+ <Paintbrush2 size={18} />
83
+ </Button>
84
+ <svelte:fragment slot="text">
85
+ {isQuickMenuOpen ? 'Close' : 'Open'} styling menu
86
+ </svelte:fragment>
87
+ </Popover>
88
+ {/if}
89
+ </div>
90
+ </div>
91
+ </label>
92
+ {#if quickStyleProperties?.length && isQuickMenuOpen}
93
+ <div transition:fade|local={{ duration: 200 }} class="w-full pt-1">
94
+ <QuickStyleMenu bind:value={value.style} properties={quickStyleProperties} />
95
+ </div>
96
+ {/if}
97
+ </div>
41
98
  {/if}
42
- {#if value.class !== undefined}
99
+ {#if value.class !== undefined || forceClass}
100
+ <!-- svelte-ignore a11y-label-has-associated-control -->
43
101
  <label class="block">
44
- <div class="text-xs font-medium pb-0.5"> Tailwind classes </div>
102
+ <div class="text-sm font-medium text-gray-600 pb-0.5"> Tailwind classes </div>
45
103
  <div class="relative">
46
- <input
47
- on:keydown|stopPropagation
48
- type="text"
49
- class="!pr-7"
50
- bind:value={value.class}
51
- on:focus
52
- />
53
- {#if value?.class}
54
- <button
55
- transition:fade|local={{ duration: 100 }}
56
- class="absolute z-10 top-1.5 right-1 rounded-full p-1 duration-200 hover:bg-gray-200"
57
- aria-label="Remove classes"
58
- on:click|preventDefault|stopPropagation={() => reset('class')}
59
- >
60
- <X size={14} />
61
- </button>
62
- {/if}
104
+ <ClearableInput bind:value={value.class} />
63
105
  </div>
64
106
  </label>
65
107
  {/if}
@@ -1,13 +1,18 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  import type { ComponentCssProperty } from '../../types';
3
+ import type { AppComponent } from '../component/components';
4
+ import type { StylePropertyKey } from './quickStyleProperties';
3
5
  declare const __propDef: {
4
6
  props: {
5
7
  name: string;
6
- value: ComponentCssProperty | undefined;
8
+ componentType?: AppComponent['type'] | undefined;
9
+ value?: ComponentCssProperty | undefined;
10
+ forceStyle?: boolean | undefined;
11
+ forceClass?: boolean | undefined;
12
+ quickStyleProperties?: StylePropertyKey[] | undefined;
7
13
  };
8
14
  events: {
9
- keydown: KeyboardEvent;
10
- focus: FocusEvent;
15
+ change: CustomEvent<any>;
11
16
  } & {
12
17
  [evt: string]: CustomEvent<any>;
13
18
  };
@@ -1,16 +1,13 @@
1
- <script>import { onMount, getContext } from 'svelte';
2
- import { LayoutDashboardIcon, MousePointer2, CurlyBraces } from 'lucide-svelte';
1
+ <script>import { getContext } from 'svelte';
2
+ import { LayoutDashboardIcon, MousePointer2, CurlyBraces, X } from 'lucide-svelte';
3
3
  import SimpleEditor from '../../../SimpleEditor.svelte';
4
4
  import { emptyString } from '../../../../utils';
5
5
  import { Tab, TabContent, Tabs } from '../../../common';
6
6
  import ListItem from './ListItem.svelte';
7
- import { isOpenStore } from './store';
8
7
  import CssProperty from './CssProperty.svelte';
9
- import { components } from '../component';
10
- import { slide } from 'svelte/transition';
8
+ import { ccomponents, components } from '../component';
11
9
  const STATIC_ELEMENTS = ['app'];
12
10
  const TITLE_PREFIX = 'Css.';
13
- const SHOW_UNUSED_ID = 'Setting.ShowUnused';
14
11
  const { app } = getContext('AppViewerContext');
15
12
  let rawCode = '';
16
13
  let viewJsonSchema = false;
@@ -39,53 +36,21 @@ const entries = [
39
36
  type: 'app',
40
37
  name: 'App',
41
38
  icon: LayoutDashboardIcon,
42
- ids: ['viewer', 'grid', 'component']
39
+ ids: ['viewer', 'grid', 'component'].map((id) => ({ id, forceStyle: true, forceClass: true }))
43
40
  },
44
- ...Object.values(components).map(({ name, icon, data: { type, customCss } }) => ({
45
- type,
41
+ ...Object.entries(ccomponents).map(([type, { name, icon, customCss }]) => ({
42
+ type: type,
46
43
  name,
47
44
  icon,
48
- ids: Object.keys(customCss ?? {}) ?? []
45
+ ids: Object.entries(customCss).map(([id, v]) => ({
46
+ id,
47
+ forceStyle: v?.style != undefined,
48
+ forceClass: v?.['class'] != undefined
49
+ }))
49
50
  }))
50
51
  ];
51
- let isCustom = Object.fromEntries(Object.keys(entries).map((k) => [k, false]));
52
- let newCss = $app.css ?? {};
53
- entries.forEach((e) => {
54
- if (!newCss[e.type]) {
55
- isCustom[e.type] = true;
56
- newCss[e.type] = {};
57
- }
58
- e.ids.forEach((id) => {
59
- if (!newCss[e.type][id]) {
60
- newCss[e.type][id] = components?.[e.type]?.data?.customCss?.[id] ?? { class: '', style: '' };
61
- }
62
- });
63
- e.ids
64
- .map((id) => newCss[e.type][id].class != '' || newCss[e.type][id].style != '')
65
- .forEach((c) => {
66
- if (c) {
67
- isCustom[e.type] = true;
68
- }
69
- });
70
- });
71
- //@ts-ignore
72
- $app.css = newCss;
73
- $: staticComponents = entries.filter(({ type }) => STATIC_ELEMENTS.includes(type));
74
- $: usedComponents = Object.keys($app.grid.reduce((acc, { data }) => {
75
- acc[data.type] = true;
76
- return acc;
77
- }, {}))
78
- .map((type) => entries.find((entry) => entry.type === type))
79
- .filter(Boolean);
80
- $: unusedComponents = entries.filter(({ type }) => {
81
- return (!STATIC_ELEMENTS.includes(type) && !usedComponents.find((entry) => entry.type === type));
82
- });
83
- onMount(() => {
84
- isOpenStore.addItems([{ name: 'App' }, ...Object.values(components)].map((component) => {
85
- return { [TITLE_PREFIX + component.name]: false };
86
- }));
87
- isOpenStore.addItems([{ [SHOW_UNUSED_ID]: false }]);
88
- });
52
+ entries.sort((a, b) => a.name.localeCompare(b.name));
53
+ let search = '';
89
54
  </script>
90
55
 
91
56
  <Tabs selected="ui" on:selected={(e) => switchTab(e.detail === 'json')} class="relative">
@@ -103,9 +68,38 @@ onMount(() => {
103
68
  </Tab>
104
69
  <div slot="content" class="h-full overflow-y-auto">
105
70
  <TabContent value="ui">
106
- {#each [...staticComponents, ...usedComponents] as { type, name, icon, ids }}
71
+ <div class="sticky top-0 left-0 w-full bg-white p-2">
72
+ <div class="relative">
73
+ <input
74
+ bind:value={search}
75
+ class="px-2 pb-1 border border-gray-300 rounded-sm {search ? 'pr-8' : ''}"
76
+ placeholder="Search..."
77
+ />
78
+ {#if search}
79
+ <button
80
+ class="absolute right-2 top-1/2 transform -translate-y-1/2 hover:bg-gray-200 rounded-full p-0.5"
81
+ on:click|stopPropagation|preventDefault={() => (search = '')}
82
+ >
83
+ <X size="14" />
84
+ </button>
85
+ {/if}
86
+ </div>
87
+ </div>
88
+ {#each search != '' ? entries.filter((x) => x.name
89
+ .toLowerCase()
90
+ .includes(search.toLowerCase())) : entries as { type, name, icon, ids } (name)}
107
91
  {#if ids.length > 0}
108
- <ListItem title={name} prefix={TITLE_PREFIX}>
92
+ <ListItem
93
+ title={name}
94
+ prefix={TITLE_PREFIX}
95
+ on:open={(e) => {
96
+ if ($app.css != undefined) {
97
+ if (e.detail && $app.css[type] == undefined) {
98
+ $app.css[type] = Object.fromEntries(ids.map(({ id }) => [id, {}]))
99
+ }
100
+ }
101
+ }}
102
+ >
109
103
  <div slot="title" class="flex items-center">
110
104
  <svelte:component this={icon} size={18} />
111
105
  <span class="ml-1">
@@ -113,13 +107,14 @@ onMount(() => {
113
107
  </span>
114
108
  </div>
115
109
  <div class="pb-2">
116
- {#each ids as id}
110
+ {#each ids as { id, forceStyle, forceClass }}
117
111
  <div class="mb-3">
118
- {#if $app?.css?.[type][id]}
112
+ {#if $app?.css?.[type]}
119
113
  <CssProperty
114
+ {forceClass}
115
+ {forceStyle}
120
116
  name={id}
121
117
  bind:value={$app.css[type][id]}
122
- on:focus={() => (isCustom[type] = true)}
123
118
  />
124
119
  {/if}
125
120
  </div>
@@ -128,43 +123,6 @@ onMount(() => {
128
123
  </ListItem>
129
124
  {/if}
130
125
  {/each}
131
- <div class="px-1 my-4">
132
- <button
133
- on:click|preventDefault|stopPropagation={() => isOpenStore.toggle(SHOW_UNUSED_ID)}
134
- class="w-full text-xs text-gray-500 text-center font-medium hover:underline p-2"
135
- >
136
- {$isOpenStore[SHOW_UNUSED_ID] ? 'Hide' : 'Show'} unused components
137
- </button>
138
- </div>
139
- {#if $isOpenStore[SHOW_UNUSED_ID]}
140
- <div transition:slide|local={{ duration: 300 }}>
141
- {#each unusedComponents as { type, name, icon, ids }}
142
- {#if ids.length > 0}
143
- <ListItem title={name} prefix={TITLE_PREFIX}>
144
- <div slot="title" class="flex items-center">
145
- <svelte:component this={icon} size={18} />
146
- <span class="ml-1">
147
- {name}
148
- </span>
149
- </div>
150
- <div class="pb-2">
151
- {#each ids as id}
152
- <div class="mb-3">
153
- {#if $app?.css?.[type][id]}
154
- <CssProperty
155
- name={id}
156
- bind:value={$app.css[type][id]}
157
- on:focus={() => (isCustom[type] = true)}
158
- />
159
- {/if}
160
- </div>
161
- {/each}
162
- </div>
163
- </ListItem>
164
- {/if}
165
- {/each}
166
- </div>
167
- {/if}
168
126
  </TabContent>
169
127
  <TabContent value="json">
170
128
  {#if !emptyString(jsonError)}
@@ -1,10 +1,13 @@
1
1
  <script>import { slide } from 'svelte/transition';
2
2
  import { ChevronDown } from 'lucide-svelte';
3
3
  import { isOpenStore } from './store';
4
+ import { createEventDispatcher } from 'svelte';
4
5
  export let title;
5
6
  export let prefix = undefined;
7
+ const dispatch = createEventDispatcher();
6
8
  $: storeTitle = prefix + title;
7
9
  $: isOpen = prefix ? $isOpenStore[storeTitle] : true;
10
+ $: dispatch('open', isOpen);
8
11
  </script>
9
12
 
10
13
  <section class="pt-1 pb-2 px-1">
@@ -5,6 +5,8 @@ declare const __propDef: {
5
5
  prefix?: string | undefined;
6
6
  };
7
7
  events: {
8
+ open: CustomEvent<any>;
9
+ } & {
8
10
  [evt: string]: CustomEvent<any>;
9
11
  };
10
12
  slots: {
@@ -0,0 +1,167 @@
1
+ <script>import { getContext, onMount, setContext } from 'svelte';
2
+ import parse from 'style-to-object';
3
+ import { isValidHexColor } from '../../../../utils';
4
+ import { createStyleStore, StylePropertyType, StylePropertyUnits, STYLE_STORE_KEY } from './quickStyleProperties';
5
+ import QuickStyleProperty from './QuickStyleProperty.svelte';
6
+ export let value = '';
7
+ export let properties;
8
+ const { app } = getContext('AppViewerContext');
9
+ const styleStore = createStyleStore(properties);
10
+ setContext(STYLE_STORE_KEY, styleStore);
11
+ let multiValues = initiateMultiValues();
12
+ let mounted = false;
13
+ $: mounted && $styleStore && writeStyle();
14
+ $: mounted && (!value || value) && parseStyle();
15
+ $: $app && setTopColors();
16
+ function parseStyle() {
17
+ styleStore.resetStyle();
18
+ if (!value) {
19
+ multiValues = initiateMultiValues();
20
+ return;
21
+ }
22
+ const current = parse(value) || {};
23
+ Object.entries(current).forEach(([k, v]) => {
24
+ styleStore.updatePropValue(k, v);
25
+ const { prop, index } = styleStore.getProp(k);
26
+ if (Array.isArray(prop?.prop?.value) && index !== undefined) {
27
+ const valueArray = v.split(' ');
28
+ multiValues[index] = multiValues[index].map((v, i) => valueArray[i] || v);
29
+ }
30
+ });
31
+ setTopColors();
32
+ }
33
+ function writeStyle() {
34
+ const current = parse(value) || {};
35
+ $styleStore.style.forEach((s) => {
36
+ current[s.prop.key] = convertValue(s.value);
37
+ });
38
+ const entries = Object.entries(current);
39
+ value = entries.reduce((style, [k, v]) => {
40
+ return v ? `${style} ${k}: ${v}; `.trim() : style;
41
+ }, '');
42
+ }
43
+ function convertValue(value) {
44
+ switch (typeof value) {
45
+ case 'number':
46
+ return value + '';
47
+ case 'string':
48
+ return value;
49
+ default:
50
+ return '';
51
+ }
52
+ }
53
+ function setTopColors() {
54
+ const styles = collectStyles();
55
+ const parsedStyles = styles.map((style) => parse(style) || {});
56
+ const usedColors = {};
57
+ parsedStyles.forEach((style) => {
58
+ Object.values(style).reduce((colors, v) => {
59
+ // TODO: support RGB and HSL colors as well
60
+ // Splitting is needed so colors can be extracted
61
+ // from values like '1px solid #000000'
62
+ v.split(' ').forEach((v) => {
63
+ if (isValidHexColor(v)) {
64
+ colors[v] = (colors[v] || 0) + 1;
65
+ }
66
+ });
67
+ return colors;
68
+ }, usedColors);
69
+ });
70
+ const colors = Object.entries(usedColors)
71
+ .sort((a, b) => b[1] - a[1])
72
+ .slice(0, 3)
73
+ .map(([color]) => color);
74
+ styleStore.setTopColors(colors);
75
+ }
76
+ function collectStyles() {
77
+ const styles = [];
78
+ // Getting global app styles
79
+ Object.values($app.css || {}).forEach((element) => {
80
+ Object.values(element).filter(({ style }) => style && styles.push(style));
81
+ });
82
+ // Getting styles from individual components
83
+ $app.grid.map((component) => {
84
+ Object.values(component.data.customCss || {}).forEach(({ style }) => {
85
+ style && styles.push(style);
86
+ });
87
+ });
88
+ // Getting style from subgrids
89
+ Object.values($app.subgrids || {}).forEach((grid) => {
90
+ grid.map((component) => {
91
+ Object.values(component.data.customCss || {}).forEach(({ style }) => {
92
+ style && styles.push(style);
93
+ });
94
+ });
95
+ });
96
+ return styles;
97
+ }
98
+ function initiateMultiValues() {
99
+ return $styleStore.style.reduce((acc, curr, i) => {
100
+ if (Array.isArray(curr.prop.value)) {
101
+ acc[i] = Array.from({ length: curr.prop.value.length }, () => {
102
+ return '';
103
+ });
104
+ }
105
+ return acc;
106
+ }, {});
107
+ }
108
+ function setMultiValueProperty(index) {
109
+ if (multiValues[index].every((v) => !v || +v === 0 || StylePropertyUnits.includes(v))) {
110
+ $styleStore.style[index].value = '';
111
+ return;
112
+ }
113
+ const values = multiValues[index].map((v, i) => {
114
+ v = StylePropertyUnits.includes(v) ? '' : v;
115
+ const type = $styleStore.style[index].prop.value[i].type;
116
+ if (v) {
117
+ multiValues[index][i] = v;
118
+ return v;
119
+ }
120
+ else if (type === StylePropertyType.color) {
121
+ return '#000000';
122
+ }
123
+ else if (type === StylePropertyType.number) {
124
+ return 0;
125
+ }
126
+ else if (type === StylePropertyType.unit) {
127
+ return 0;
128
+ }
129
+ else if (type === StylePropertyType.text) {
130
+ const options = $styleStore.style[index].prop.value[i].options;
131
+ return options ? options[0].text : '';
132
+ }
133
+ else {
134
+ return '';
135
+ }
136
+ });
137
+ $styleStore.style[index].value = values.join(' ').trim();
138
+ }
139
+ onMount(() => {
140
+ parseStyle();
141
+ mounted = true;
142
+ });
143
+ </script>
144
+
145
+ <div class="bg-gray-200/60 rounded-md p-2">
146
+ {#each $styleStore.style as { prop }, index}
147
+ <div class="pb-3 last:pb-0">
148
+ <div class="text-sm font-medium text-gray-600 pb-0.5"> {prop.key} </div>
149
+ <div class="flex items-center gap-1 w-full">
150
+ {#if Array.isArray(prop.value)}
151
+ <div class="flex justify-start items-center flex-wrap gap-x-4 gap-y-1">
152
+ {#each prop.value as value, i}
153
+ <QuickStyleProperty
154
+ prop={{ ...prop, value }}
155
+ inline
156
+ bind:value={multiValues[index][i]}
157
+ on:change={() => setMultiValueProperty(index)}
158
+ />
159
+ {/each}
160
+ </div>
161
+ {:else}
162
+ <QuickStyleProperty {prop} bind:value={$styleStore.style[index].value} />
163
+ {/if}
164
+ </div>
165
+ </div>
166
+ {/each}
167
+ </div>