@lapis-notes/bases 0.2.1 → 0.3.0

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 (55) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +1 -1
  3. package/dist/bases-plugin.js +18 -21
  4. package/dist/bases-view/bases.svelte.d.ts +7 -0
  5. package/dist/bases-view/bases.svelte.js +37 -7
  6. package/dist/bases-view/card-view/components/card-placeholder.svelte +7 -3
  7. package/dist/bases-view/card-view/components/card.svelte +23 -15
  8. package/dist/bases-view/cell.svelte +147 -16
  9. package/dist/bases-view/cell.svelte.d.ts +2 -0
  10. package/dist/bases-view/columns.js +3 -2
  11. package/dist/bases-view/components/bases-embed.svelte +28 -0
  12. package/dist/bases-view/components/bases-embed.svelte.d.ts +12 -0
  13. package/dist/bases-view/components/bases-error.svelte +26 -0
  14. package/dist/bases-view/components/bases-error.svelte.d.ts +6 -0
  15. package/dist/bases-view/components/datetime.svelte +3 -0
  16. package/dist/bases-view/components/datetime.svelte.d.ts +1 -0
  17. package/dist/bases-view/components/file-preview.svelte +57 -0
  18. package/dist/bases-view/components/file-preview.svelte.d.ts +8 -0
  19. package/dist/bases-view/components/file.svelte +22 -5
  20. package/dist/bases-view/components/property-picker.svelte +147 -0
  21. package/dist/bases-view/components/property-picker.svelte.d.ts +13 -0
  22. package/dist/bases-view/components/sort/sort-root.svelte +107 -88
  23. package/dist/bases-view/components/sort/sort-root.svelte.d.ts +1 -0
  24. package/dist/bases-view/components/views.svelte +96 -42
  25. package/dist/bases-view/document-core.js +30 -0
  26. package/dist/bases-view/filter-parser.d.ts +1 -1
  27. package/dist/bases-view/filter-parser.js +2 -1
  28. package/dist/bases-view/index.js +15 -0
  29. package/dist/bases-view/kanban-view/configuration.d.ts +8 -0
  30. package/dist/bases-view/kanban-view/configuration.js +40 -0
  31. package/dist/bases-view/kanban-view/index.d.ts +55 -0
  32. package/dist/bases-view/kanban-view/index.js +296 -0
  33. package/dist/bases-view/kanban-view/kanban.svelte +284 -0
  34. package/dist/bases-view/kanban-view/kanban.svelte.d.ts +7 -0
  35. package/dist/bases-view/kanban-view/mapping.d.ts +77 -0
  36. package/dist/bases-view/kanban-view/mapping.js +206 -0
  37. package/dist/bases-view/kanban-view/markdown-detail.svelte +123 -0
  38. package/dist/bases-view/kanban-view/markdown-detail.svelte.d.ts +13 -0
  39. package/dist/bases-view/kanban-view/settings.svelte +87 -0
  40. package/dist/bases-view/kanban-view/settings.svelte.d.ts +7 -0
  41. package/dist/bases-view/list-view/list.svelte +84 -84
  42. package/dist/bases-view/map-view/view.svelte +6 -1
  43. package/dist/bases-view/metadata-invalidation-core.d.ts +1 -0
  44. package/dist/bases-view/metadata-invalidation-core.js +3 -2
  45. package/dist/bases-view/models.d.ts +26 -0
  46. package/dist/bases-view/unknown-view/view.svelte +13 -6
  47. package/dist/bases-view/view-header.svelte +20 -6
  48. package/dist/bases-view/view-registration-inventory.d.ts +8 -0
  49. package/dist/bases-view/view-registration-inventory.js +2 -0
  50. package/dist/bases-view/view-settings.svelte +213 -237
  51. package/dist/index.d.ts +1 -1
  52. package/dist/styles.css +495 -74
  53. package/manifest.json +2 -1
  54. package/package.json +3 -2
  55. package/registry.json +85 -1
@@ -0,0 +1,26 @@
1
+ <script lang="ts">
2
+ import * as Alert from "@lapismd/design-core/shadcn/alert";
3
+ import CircleAlert from "@lucide/svelte/icons/circle-alert";
4
+
5
+ let { message }: { message: string } = $props();
6
+ </script>
7
+
8
+ <div class="bases-view-error-container">
9
+ <Alert.Root variant="destructive" class="bases-view-error">
10
+ <CircleAlert aria-hidden="true" />
11
+ <Alert.Title>Unable to render base</Alert.Title>
12
+ <Alert.Description>
13
+ <p class="bases-view-error__message">{message}</p>
14
+ </Alert.Description>
15
+ </Alert.Root>
16
+ </div>
17
+
18
+ <style>
19
+ .bases-view-error-container {
20
+ margin: 1rem;
21
+ }
22
+ .bases-view-error__message {
23
+ white-space: pre-wrap;
24
+ overflow-wrap: anywhere;
25
+ }
26
+ </style>
@@ -0,0 +1,6 @@
1
+ type $$ComponentProps = {
2
+ message: string;
3
+ };
4
+ declare const BasesError: import("svelte").Component<$$ComponentProps, {}, "">;
5
+ type BasesError = ReturnType<typeof BasesError>;
6
+ export default BasesError;
@@ -4,8 +4,10 @@
4
4
 
5
5
  let {
6
6
  value,
7
+ label,
7
8
  }: {
8
9
  value: number | DateTime | string;
10
+ label: string;
9
11
  } = $props();
10
12
 
11
13
  let date = $derived.by(() => {
@@ -26,6 +28,7 @@
26
28
 
27
29
  <div class="bases-table-cell bases-rendered-value">
28
30
  <input
31
+ aria-label={label}
29
32
  class="metadata-input metadata-input-text mod-datetime !static !ps-0"
30
33
  value={date}
31
34
  step="any"
@@ -1,6 +1,7 @@
1
1
  import { DateTime } from "luxon";
2
2
  type $$ComponentProps = {
3
3
  value: number | DateTime | string;
4
+ label: string;
4
5
  };
5
6
  declare const Datetime: import("svelte").Component<$$ComponentProps, {}, "">;
6
7
  type Datetime = ReturnType<typeof Datetime>;
@@ -0,0 +1,57 @@
1
+ <script lang="ts">
2
+ import { untrack } from "svelte";
3
+ import type { App, TFile } from "@lapis-notes/api";
4
+ import { ScrollArea } from "@lapismd/design-core/shadcn/scroll-area";
5
+
6
+ let { app, file }: { app: App; file: TFile } = $props();
7
+ let container = $state<HTMLDivElement>();
8
+ let error = $state("");
9
+
10
+ $effect(() => {
11
+ if (!container) return;
12
+ const owner = app;
13
+ const source = file;
14
+ const host = container;
15
+ error = "";
16
+ let cancelled = false;
17
+ // Defer invocation so synchronous and asynchronous provider errors share
18
+ // the same fallback and late mounts still get disposed after dismissal.
19
+ const mounted = Promise.resolve().then(() =>
20
+ untrack(() =>
21
+ owner.markdownFileSurfaces.mount({
22
+ containerEl: host,
23
+ file: source,
24
+ editable: false,
25
+ surface: {
26
+ id: "bases-file-link-preview",
27
+ context: { path: source.path },
28
+ },
29
+ }),
30
+ ),
31
+ );
32
+ void mounted.catch((reason) => {
33
+ if (!cancelled)
34
+ error = reason instanceof Error ? reason.message : String(reason);
35
+ });
36
+ return () => {
37
+ cancelled = true;
38
+ void mounted
39
+ .then(
40
+ (surface) => surface.dispose(),
41
+ () => undefined,
42
+ )
43
+ .catch(console.error);
44
+ };
45
+ });
46
+ </script>
47
+
48
+ <section
49
+ aria-label={`Preview of ${file.name}`}
50
+ data-ui-component="bases-file-preview"
51
+ >
52
+ <div class="bases-file-preview__title">{file.name}</div>
53
+ <ScrollArea class="bases-file-preview__scroll" orientation="vertical">
54
+ {#if error}<p role="status">Preview unavailable: {error}</p>{/if}
55
+ <div bind:this={container} class="bases-file-preview__surface"></div>
56
+ </ScrollArea>
57
+ </section>
@@ -0,0 +1,8 @@
1
+ import type { App, TFile } from "@lapis-notes/api";
2
+ type $$ComponentProps = {
3
+ app: App;
4
+ file: TFile;
5
+ };
6
+ declare const FilePreview: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type FilePreview = ReturnType<typeof FilePreview>;
8
+ export default FilePreview;
@@ -1,5 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { App, TFile } from "@lapis-notes/api";
3
+ import * as HoverCard from "@lapismd/design-core/shadcn/hover-card";
4
+ import FilePreview from "./file-preview.svelte";
3
5
  let {
4
6
  app,
5
7
  file,
@@ -7,8 +9,14 @@
7
9
  app: App;
8
10
  file: TFile;
9
11
  } = $props();
12
+ let open = $state(false);
13
+ const previewable = $derived(
14
+ ["md", "markdown"].includes(file.extension.toLowerCase()) &&
15
+ app.markdownFileSurfaces.available,
16
+ );
10
17
 
11
18
  function openFile(evt: MouseEvent) {
19
+ open = false;
12
20
  if (evt.metaKey || evt.ctrlKey) {
13
21
  const leaf = app.workspace.getLeaf("tab");
14
22
  leaf.openFile(file).then(() => {
@@ -24,8 +32,17 @@
24
32
  }
25
33
  </script>
26
34
 
27
- <a
28
- href="#/"
29
- class="bases-style-text-var-text-accent-69c994 underline"
30
- onclick={(evt) => openFile(evt)}>{file.name}</a
31
- >
35
+ {#if previewable}
36
+ <HoverCard.Root bind:open openDelay={350} closeDelay={150}>
37
+ <HoverCard.Trigger href="#/" onclick={openFile}>
38
+ {#snippet child({ props })}
39
+ <a {...props} role="link" class="bases-file-link">{file.name}</a>
40
+ {/snippet}
41
+ </HoverCard.Trigger>
42
+ <HoverCard.Content class="bases-file-preview" align="start">
43
+ <FilePreview {app} {file} />
44
+ </HoverCard.Content>
45
+ </HoverCard.Root>
46
+ {:else}
47
+ <a href="#/" class="bases-file-link" onclick={openFile}>{file.name}</a>
48
+ {/if}
@@ -0,0 +1,147 @@
1
+ <script lang="ts">
2
+ import { tick } from "svelte";
3
+ import { Icon } from "@lapis-notes/api/icon";
4
+ import type { BasesPropertyId } from "@lapis-notes/api";
5
+ import { Button } from "@lapismd/design-core/shadcn/button";
6
+ import * as Popover from "@lapismd/design-core/shadcn/popover";
7
+ import * as Command from "@lapismd/design-core/shadcn/command";
8
+ import ArrowUpDown from "@lucide/svelte/icons/chevrons-up-down";
9
+ import X from "@lucide/svelte/icons/x";
10
+ import Check from "@lucide/svelte/icons/check";
11
+ import type { ColumnDefinition } from "../columns";
12
+
13
+ let {
14
+ id,
15
+ label,
16
+ columns,
17
+ value,
18
+ placeholder = "Property",
19
+ onChange,
20
+ }: {
21
+ id?: string;
22
+ label: string;
23
+ columns: ColumnDefinition[];
24
+ value?: BasesPropertyId | null;
25
+ placeholder?: string;
26
+ onChange: (value: BasesPropertyId | "") => void;
27
+ } = $props();
28
+ let open = $state(false);
29
+ let trigger = $state<HTMLButtonElement>(null!);
30
+ const selected = $derived(columns.find((column) => column.id === value));
31
+ const listId = $props.id();
32
+ async function choose(next: BasesPropertyId | "") {
33
+ onChange(next);
34
+ open = false;
35
+ await tick();
36
+ trigger?.focus();
37
+ }
38
+ </script>
39
+
40
+ <div class="bases-property-setting">
41
+ <Popover.Root bind:open>
42
+ <Popover.Trigger>
43
+ {#snippet child({ props })}
44
+ <Button
45
+ {...props}
46
+ bind:ref={trigger}
47
+ {id}
48
+ variant="outline"
49
+ role="combobox"
50
+ aria-label={label}
51
+ aria-expanded={open}
52
+ class="bases-property-setting__trigger"
53
+ >
54
+ <Icon name={selected?.icon ?? "lucide-file"} />
55
+ <span>{selected?.displayName ?? placeholder}</span>
56
+ <ArrowUpDown />
57
+ </Button>
58
+ {/snippet}
59
+ </Popover.Trigger>
60
+ <Popover.Content
61
+ class="bases-style-w-310px-8357f2 bases-style-p-0-8a539c"
62
+ align="start"
63
+ >
64
+ <Command.Root label="Find property">
65
+ <Command.Input
66
+ aria-label="Find property"
67
+ aria-controls={listId}
68
+ placeholder="Find property"
69
+ />
70
+ <Command.List id={listId}>
71
+ <Command.Empty>No properties found.</Command.Empty>
72
+ <Command.Group>
73
+ {#each columns as column (column.id)}
74
+ <Command.Item
75
+ class="bases-property-setting-option"
76
+ value={`${column.displayName} ${column.id}`}
77
+ onSelect={() => choose(column.id)}
78
+ >
79
+ <span
80
+ class="bases-property-setting__check"
81
+ class:is-selected={value === column.id}><Check /></span
82
+ >
83
+ <Icon name={column.icon ?? "lucide-info"} />
84
+ <span>{column.displayName}</span>
85
+ <span class="bases-property-setting__id">{column.id}</span>
86
+ </Command.Item>
87
+ {/each}
88
+ </Command.Group>
89
+ </Command.List>
90
+ </Command.Root>
91
+ </Popover.Content>
92
+ </Popover.Root>
93
+ {#if value}
94
+ <Button
95
+ variant="ghost"
96
+ size="icon-xs"
97
+ class="bases-property-setting__clear"
98
+ aria-label={`Clear ${label.toLowerCase()}`}
99
+ onclick={() => choose("")}><X /></Button
100
+ >
101
+ {/if}
102
+ </div>
103
+
104
+ <style>
105
+ .bases-property-setting {
106
+ position: relative;
107
+ min-width: 0;
108
+ width: 100%;
109
+ }
110
+ .bases-property-setting :global(.bases-property-setting__trigger) {
111
+ width: 100%;
112
+ justify-content: space-between;
113
+ padding-inline-end: 0.75rem;
114
+ }
115
+ .bases-property-setting :global(.bases-property-setting__trigger > span) {
116
+ min-width: 0;
117
+ flex: 1;
118
+ text-align: left;
119
+ overflow: hidden;
120
+ text-overflow: ellipsis;
121
+ white-space: nowrap;
122
+ padding-inline-end: 1.5rem;
123
+ }
124
+ .bases-property-setting :global(.bases-property-setting__clear) {
125
+ position: absolute;
126
+ inset-inline-end: 1.65rem;
127
+ top: 50%;
128
+ transform: translateY(-50%);
129
+ }
130
+ .bases-property-setting__check {
131
+ visibility: hidden;
132
+ }
133
+ .bases-property-setting__check.is-selected {
134
+ visibility: visible;
135
+ }
136
+ .bases-property-setting__id {
137
+ margin-inline-start: auto;
138
+ color: var(--ui-workspace-muted-foreground);
139
+ font-size: 0.75rem;
140
+ }
141
+ /* The leading check reflects the saved mapping, independently of search focus. */
142
+ :global(
143
+ .bases-property-setting-option > [data-ui-part="command-check-icon"]
144
+ ) {
145
+ display: none;
146
+ }
147
+ </style>
@@ -0,0 +1,13 @@
1
+ import type { BasesPropertyId } from "@lapis-notes/api";
2
+ import type { ColumnDefinition } from "../columns";
3
+ type $$ComponentProps = {
4
+ id?: string;
5
+ label: string;
6
+ columns: ColumnDefinition[];
7
+ value?: BasesPropertyId | null;
8
+ placeholder?: string;
9
+ onChange: (value: BasesPropertyId | "") => void;
10
+ };
11
+ declare const PropertyPicker: import("svelte").Component<$$ComponentProps, {}, "">;
12
+ type PropertyPicker = ReturnType<typeof PropertyPicker>;
13
+ export default PropertyPicker;
@@ -21,12 +21,14 @@
21
21
  import { getSortDirectionLabels } from "./sort-direction-labels";
22
22
 
23
23
  let {
24
+ showGrouping = true,
24
25
  class: className,
25
26
  orderBy = $bindable(),
26
27
  table,
27
28
  controller = table as QueryController,
28
29
  }: {
29
30
  orderBy: Array<SortColumn>;
31
+ showGrouping?: boolean;
30
32
  class?: string;
31
33
  controller?: QueryController;
32
34
  table?: any;
@@ -106,7 +108,10 @@
106
108
  {...props}
107
109
  variant="outline"
108
110
  size="sm"
109
- class={cn("bases-style-h-8-ed8a5d bases-style-border-dashed-a29b7a", className)}
111
+ class={cn(
112
+ "bases-style-h-8-ed8a5d bases-style-border-dashed-a29b7a",
113
+ className,
114
+ )}
110
115
  >
111
116
  <SortIcon /> Sort
112
117
  </Button>
@@ -117,99 +122,113 @@
117
122
  data-bases-popover="sort"
118
123
  align="start"
119
124
  >
120
- <div class="bases-style-mb-2-a77ed4 bases-style-grid-f3c543 bases-style-gap-2-77a2a2">
125
+ {#if showGrouping}
121
126
  <div
122
- class="bases-style-text-muted-foreground-bfa603 bases-style-px-1-d8e0e3 bases-style-text-xs-359090 bases-style-font-semibold-e83a70 bases-style-tracking-0-18em-a82f6f uppercase"
127
+ class="bases-style-mb-2-a77ed4 bases-style-grid-f3c543 bases-style-gap-2-77a2a2"
123
128
  >
124
- Group by
125
- </div>
126
- <div class="bases-style-flex-60fbb7 bases-style-h-9-e7a768 bases-style-items-center-3960ff bases-style-rounded-md-421ac2 bases-style-border-2-65935d">
127
- <Popover.Root>
128
- <Popover.Trigger>
129
- {#snippet child({ props }: { props: Record<string, any> })}
130
- <Button
131
- {...props}
132
- variant="outline"
133
- size="sm"
134
- class="bases-style-h-8-ed8a5d grow bases-style-rounded-none-0c5e91 bases-style-rounded-l-md-9b2e91 bases-style-border-none-4a5f0e bases-style-shadow-none-ad47d1 bases-style-outline-none-df37b1"
135
- >
136
- {#if selectedGroupColumn}
137
- <Icon name={[selectedGroupColumn.icon ?? "lucide-file"]} />
138
- {selectedGroupColumn.displayName}
139
- {:else}
140
- <span class="bases-style-opacity-50-0b8c50">Property</span>
141
- {/if}
142
- <SortIcon />
143
- </Button>
144
- {/snippet}
145
- </Popover.Trigger>
146
- <Popover.Content class="bases-style-w-max-2f935d bases-style-p-0-8a539c" align="start">
147
- <Command.Root>
148
- <Command.Input aria-controls={commandListId} placeholder="Group by property" />
149
- <Command.List id={commandListId} class="bases-style-p-1-eb6a3c">
150
- <Command.Empty>No results found.</Command.Empty>
151
- {#each controller.getAllColumns() as column (column.id)}
152
- <Command.Item onSelect={() => setGroupBy(column.id)}>
153
- <div
154
- data-ui-part="bases-option-indicator"
155
- data-selected={groupBy?.property === column.id}
156
- class={cn(
157
- "bases-style-mr-2-d2347e bases-style-flex-60fbb7 bases-style-size-4-f7b5fa bases-style-items-center-3960ff bases-style-justify-center-86843c bases-style-rounded-sm-36d446 border bases-style-border-var-interactive-accent-f46c93",
158
- groupBy?.property === column.id
159
- ? "bases-style-ring-ring-3e1868 bases-style-border-none-4a5f0e bases-style-bg-var-interactive-accent-c58cc0 bases-style-text-var-text-on-accent-22b2b1 hover:ring"
160
- : "bases-style-opacity-50-0b8c50 [&_svg]:invisible",
161
- )}
162
- >
163
- <CheckIcon class="bases-style-size-4-f7b5fa" />
164
- </div>
165
- <Icon name={[column.icon ?? "lucide-info"]} />
166
- <span class="bases-style-overflow-hidden-2cd02d bases-style-text-ellipsis-6e2e11"
167
- >{column.displayName}</span
168
- >
169
- {#if !column.id.startsWith("note.")}
170
- <Command.Shortcut class="bases-style-font-mono-0e6570 bases-style-text-0-75em-c425cc"
171
- >{column.id}</Command.Shortcut
172
- >
173
- {/if}
174
- </Command.Item>
175
- {/each}
176
- </Command.List>
177
- </Command.Root>
178
- </Popover.Content>
179
- </Popover.Root>
180
- <Select.Root
181
- type="single"
182
- bind:value={getGroupDirection, setGroupDirection}
129
+ <div
130
+ class="bases-style-text-muted-foreground-bfa603 bases-style-px-1-d8e0e3 bases-style-text-xs-359090 bases-style-font-semibold-e83a70 bases-style-tracking-0-18em-a82f6f uppercase"
183
131
  >
184
- <Select.Trigger
185
- aria-label="Group sort direction"
132
+ Group by
133
+ </div>
134
+ <div
135
+ class="bases-style-flex-60fbb7 bases-style-h-9-e7a768 bases-style-items-center-3960ff bases-style-rounded-md-421ac2 bases-style-border-2-65935d"
136
+ >
137
+ <Popover.Root>
138
+ <Popover.Trigger>
139
+ {#snippet child({ props }: { props: Record<string, any> })}
140
+ <Button
141
+ {...props}
142
+ variant="outline"
143
+ size="sm"
144
+ class="bases-style-h-8-ed8a5d grow bases-style-rounded-none-0c5e91 bases-style-rounded-l-md-9b2e91 bases-style-border-none-4a5f0e bases-style-shadow-none-ad47d1 bases-style-outline-none-df37b1"
145
+ >
146
+ {#if selectedGroupColumn}
147
+ <Icon name={[selectedGroupColumn.icon ?? "lucide-file"]} />
148
+ {selectedGroupColumn.displayName}
149
+ {:else}
150
+ <span class="bases-style-opacity-50-0b8c50">Property</span>
151
+ {/if}
152
+ <SortIcon />
153
+ </Button>
154
+ {/snippet}
155
+ </Popover.Trigger>
156
+ <Popover.Content
157
+ class="bases-style-w-max-2f935d bases-style-p-0-8a539c"
158
+ align="start"
159
+ >
160
+ <Command.Root>
161
+ <Command.Input
162
+ aria-controls={commandListId}
163
+ placeholder="Group by property"
164
+ />
165
+ <Command.List id={commandListId} class="bases-style-p-1-eb6a3c">
166
+ <Command.Empty>No results found.</Command.Empty>
167
+ {#each controller.getAllColumns() as column (column.id)}
168
+ <Command.Item onSelect={() => setGroupBy(column.id)}>
169
+ <div
170
+ data-ui-part="bases-option-indicator"
171
+ data-selected={groupBy?.property === column.id}
172
+ class={cn(
173
+ "bases-style-mr-2-d2347e bases-style-flex-60fbb7 bases-style-size-4-f7b5fa bases-style-items-center-3960ff bases-style-justify-center-86843c bases-style-rounded-sm-36d446 border bases-style-border-var-interactive-accent-f46c93",
174
+ groupBy?.property === column.id
175
+ ? "bases-style-ring-ring-3e1868 bases-style-border-none-4a5f0e bases-style-bg-var-interactive-accent-c58cc0 bases-style-text-var-text-on-accent-22b2b1 hover:ring"
176
+ : "bases-style-opacity-50-0b8c50 [&_svg]:invisible",
177
+ )}
178
+ >
179
+ <CheckIcon class="bases-style-size-4-f7b5fa" />
180
+ </div>
181
+ <Icon name={[column.icon ?? "lucide-info"]} />
182
+ <span
183
+ class="bases-style-overflow-hidden-2cd02d bases-style-text-ellipsis-6e2e11"
184
+ >{column.displayName}</span
185
+ >
186
+ {#if !column.id.startsWith("note.")}
187
+ <Command.Shortcut
188
+ class="bases-style-font-mono-0e6570 bases-style-text-0-75em-c425cc"
189
+ >{column.id}</Command.Shortcut
190
+ >
191
+ {/if}
192
+ </Command.Item>
193
+ {/each}
194
+ </Command.List>
195
+ </Command.Root>
196
+ </Popover.Content>
197
+ </Popover.Root>
198
+ <Select.Root
199
+ type="single"
200
+ bind:value={getGroupDirection, setGroupDirection}
201
+ >
202
+ <Select.Trigger
203
+ aria-label="Group sort direction"
204
+ size="sm"
205
+ class="bases-style-bg-background-e6f9e3 bases-style-h-8-ed8a5d bases-style-rounded-none-0c5e91 bases-style-border-none-4a5f0e bases-style-shadow-none-ad47d1 bases-style-outline-none-df37b1"
206
+ >
207
+ {groupDirectionLabel}
208
+ <SortIcon />
209
+ </Select.Trigger>
210
+ <Select.Content>
211
+ {#each groupDirections as direction (direction.value)}
212
+ <Select.Item value={direction.value} label={direction.label}
213
+ >{direction.label}</Select.Item
214
+ >
215
+ {/each}
216
+ </Select.Content>
217
+ </Select.Root>
218
+ <Button
219
+ variant="ghost"
186
220
  size="sm"
187
- class="bases-style-bg-background-e6f9e3 bases-style-h-8-ed8a5d bases-style-rounded-none-0c5e91 bases-style-border-none-4a5f0e bases-style-shadow-none-ad47d1 bases-style-outline-none-df37b1"
221
+ aria-label="Clear grouping"
222
+ class="bases-style-bg-background-e6f9e3 bases-style-h-8-ed8a5d bases-style-rounded-none-0c5e91 bases-style-rounded-r-md-d4eb07 bases-style-border-none-4a5f0e bases-style-shadow-none-ad47d1 bases-style-outline-none-df37b1"
223
+ disabled={!selectedGroupColumn}
224
+ onclick={() => (controller.selectedView.groupBy = undefined)}
188
225
  >
189
- {groupDirectionLabel}
190
- <SortIcon />
191
- </Select.Trigger>
192
- <Select.Content>
193
- {#each groupDirections as direction (direction.value)}
194
- <Select.Item value={direction.value} label={direction.label}
195
- >{direction.label}</Select.Item
196
- >
197
- {/each}
198
- </Select.Content>
199
- </Select.Root>
200
- <Button
201
- variant="ghost"
202
- size="sm"
203
- aria-label="Clear grouping"
204
- class="bases-style-bg-background-e6f9e3 bases-style-h-8-ed8a5d bases-style-rounded-none-0c5e91 bases-style-rounded-r-md-d4eb07 bases-style-border-none-4a5f0e bases-style-shadow-none-ad47d1 bases-style-outline-none-df37b1"
205
- disabled={!selectedGroupColumn}
206
- onclick={() => (controller.selectedView.groupBy = undefined)}
207
- >
208
- <Trash />
209
- </Button>
226
+ <Trash />
227
+ </Button>
228
+ </div>
210
229
  </div>
211
- </div>
212
- <div class="bases-style-mb-2-a77ed4 bases-style-border-t-b950dd"></div>
230
+ <div class="bases-style-mb-2-a77ed4 bases-style-border-t-b950dd"></div>
231
+ {/if}
213
232
  <div
214
233
  class="bases-style-text-muted-foreground-bfa603 bases-style-mb-2-a77ed4 bases-style-px-1-d8e0e3 bases-style-text-xs-359090 bases-style-font-semibold-e83a70 bases-style-tracking-0-18em-a82f6f uppercase"
215
234
  >
@@ -2,6 +2,7 @@ import type { SortColumn } from "../..";
2
2
  import type { QueryController } from "../../bases.svelte";
3
3
  type $$ComponentProps = {
4
4
  orderBy: Array<SortColumn>;
5
+ showGrouping?: boolean;
5
6
  class?: string;
6
7
  controller?: QueryController;
7
8
  table?: any;