terminoir 0.4.0 → 0.5.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.
- package/README.md +38 -28
- package/css/components.css +62 -0
- package/css/shell.css +32 -1
- package/dist/components/AccentSwatches.svelte +1 -1
- package/dist/components/AppShell.svelte +33 -5
- package/dist/components/AppShell.svelte.d.ts +10 -1
- package/dist/components/AppShellNavLink.svelte +2 -4
- package/dist/components/Button.svelte +32 -14
- package/dist/components/Button.svelte.d.ts +2 -0
- package/dist/components/CalendarGrid.svelte +260 -0
- package/dist/components/CalendarGrid.svelte.d.ts +12 -0
- package/dist/components/CanvasStage.svelte +81 -0
- package/dist/components/CanvasStage.svelte.d.ts +19 -0
- package/dist/components/Centered.svelte +36 -0
- package/dist/components/Centered.svelte.d.ts +10 -0
- package/dist/components/Checkbox.svelte +64 -12
- package/dist/components/Checkbox.svelte.d.ts +5 -0
- package/dist/components/Chip.svelte +90 -2
- package/dist/components/Chip.svelte.d.ts +8 -0
- package/dist/components/CommandPalette.svelte +178 -97
- package/dist/components/CommandPalette.svelte.d.ts +15 -8
- package/dist/components/ContextMenu.svelte +68 -0
- package/dist/components/ContextMenu.svelte.d.ts +12 -0
- package/dist/components/DataTable.svelte +139 -0
- package/dist/components/DataTable.svelte.d.ts +39 -0
- package/dist/components/DescriptionList.svelte +41 -0
- package/dist/components/DescriptionList.svelte.d.ts +8 -0
- package/dist/components/Dialog.svelte +17 -8
- package/dist/components/Disclosure.svelte +55 -0
- package/dist/components/Disclosure.svelte.d.ts +10 -0
- package/dist/components/DocumentViewer.svelte +105 -0
- package/dist/components/DocumentViewer.svelte.d.ts +23 -0
- package/dist/components/Drawer.svelte +119 -0
- package/dist/components/Drawer.svelte.d.ts +16 -0
- package/dist/components/DropdownMenu.svelte +46 -62
- package/dist/components/DropdownMenu.svelte.d.ts +7 -6
- package/dist/components/FieldMessage.svelte +9 -0
- package/dist/components/FieldMessage.svelte.d.ts +8 -0
- package/dist/components/FileButton.svelte +44 -0
- package/dist/components/FileButton.svelte.d.ts +16 -0
- package/dist/components/FormRow.svelte +62 -0
- package/dist/components/FormRow.svelte.d.ts +13 -0
- package/dist/components/IconField.svelte +80 -5
- package/dist/components/IconField.svelte.d.ts +2 -0
- package/dist/components/Inline.svelte +52 -0
- package/dist/components/Inline.svelte.d.ts +16 -0
- package/dist/components/Input.svelte +23 -3
- package/dist/components/Input.svelte.d.ts +9 -0
- package/dist/components/List.svelte +42 -0
- package/dist/components/List.svelte.d.ts +13 -0
- package/dist/components/ListItem.svelte +114 -0
- package/dist/components/ListItem.svelte.d.ts +17 -0
- package/dist/components/MenuItems.svelte +44 -0
- package/dist/components/MenuItems.svelte.d.ts +8 -0
- package/dist/components/NavSection.svelte +45 -0
- package/dist/components/NavSection.svelte.d.ts +12 -0
- package/dist/components/Page.svelte +53 -0
- package/dist/components/Page.svelte.d.ts +12 -0
- package/dist/components/PageHeader.svelte +91 -0
- package/dist/components/PageHeader.svelte.d.ts +15 -0
- package/dist/components/Prose.svelte +33 -0
- package/dist/components/Prose.svelte.d.ts +8 -0
- package/dist/components/RadioCards.svelte +68 -0
- package/dist/components/RadioCards.svelte.d.ts +11 -0
- package/dist/components/SearchPicker.svelte +171 -0
- package/dist/components/SearchPicker.svelte.d.ts +19 -0
- package/dist/components/Section.svelte +71 -0
- package/dist/components/Section.svelte.d.ts +12 -0
- package/dist/components/SegmentedControl.svelte +63 -0
- package/dist/components/SegmentedControl.svelte.d.ts +12 -0
- package/dist/components/Select.svelte +22 -4
- package/dist/components/Select.svelte.d.ts +9 -1
- package/dist/components/Spacer.svelte +6 -0
- package/dist/components/Spacer.svelte.d.ts +26 -0
- package/dist/components/Stack.svelte +37 -0
- package/dist/components/Stack.svelte.d.ts +12 -0
- package/dist/components/Switch.svelte +6 -2
- package/dist/components/Switch.svelte.d.ts +2 -0
- package/dist/components/Tabs.svelte +6 -4
- package/dist/components/Text.svelte +68 -0
- package/dist/components/Text.svelte.d.ts +15 -0
- package/dist/components/Textarea.svelte +19 -3
- package/dist/components/Textarea.svelte.d.ts +6 -0
- package/dist/components/TitleInput.svelte +62 -0
- package/dist/components/TitleInput.svelte.d.ts +10 -0
- package/dist/index.d.ts +35 -2
- package/dist/index.js +31 -0
- package/dist/utils/calendar.d.ts +48 -0
- package/dist/utils/calendar.js +105 -0
- package/dist/utils/commands.d.ts +22 -0
- package/dist/utils/commands.js +17 -0
- package/dist/utils/componentTypes.d.ts +41 -0
- package/dist/utils/componentTypes.js +1 -0
- package/dist/utils/listNav.d.ts +2 -0
- package/dist/utils/listNav.js +8 -0
- package/dist/utils/menu.d.ts +10 -0
- package/dist/utils/menu.js +1 -0
- package/package.json +5 -3
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import { cn } from '../utils/cn.js';
|
|
4
|
+
import FieldMessage from './FieldMessage.svelte';
|
|
3
5
|
|
|
4
6
|
let {
|
|
5
7
|
label,
|
|
8
|
+
hideLabel = false,
|
|
9
|
+
quiet = false,
|
|
10
|
+
hint,
|
|
11
|
+
error,
|
|
6
12
|
id,
|
|
7
13
|
value = $bindable(''),
|
|
8
14
|
disabled = false,
|
|
@@ -11,25 +17,37 @@
|
|
|
11
17
|
...rest
|
|
12
18
|
}: {
|
|
13
19
|
label: string;
|
|
20
|
+
/** Keep the label for screen readers only (compact rows, toolbars). */
|
|
21
|
+
hideLabel?: boolean;
|
|
22
|
+
/** Borderless until hovered or focused, for inline editing (property rows). */
|
|
23
|
+
quiet?: boolean;
|
|
24
|
+
hint?: string;
|
|
25
|
+
error?: string;
|
|
14
26
|
id?: string;
|
|
15
27
|
value?: string;
|
|
16
28
|
disabled?: boolean;
|
|
17
29
|
class?: string;
|
|
18
|
-
|
|
30
|
+
/** `<option>` elements. */
|
|
31
|
+
children?: Snippet;
|
|
19
32
|
} & Record<string, unknown> = $props();
|
|
20
33
|
|
|
21
|
-
const
|
|
34
|
+
const fallbackId = $props.id();
|
|
35
|
+
const selectId = $derived(id ?? fallbackId);
|
|
36
|
+
const messageId = $derived(`${selectId}-message`);
|
|
22
37
|
</script>
|
|
23
38
|
|
|
24
|
-
<div class={cn('terminoir-field', className)}>
|
|
25
|
-
<label class=
|
|
39
|
+
<div class={cn('terminoir-field', quiet && 'terminoir-field--quiet', className)}>
|
|
40
|
+
<label class={cn('terminoir-field__label', hideLabel && 'terminoir-sr-only')} for={selectId}>{label}</label>
|
|
26
41
|
<select
|
|
27
42
|
id={selectId}
|
|
28
43
|
class="terminoir-select terminoir-focusable"
|
|
29
44
|
bind:value
|
|
30
45
|
{disabled}
|
|
46
|
+
aria-invalid={error ? true : undefined}
|
|
47
|
+
aria-describedby={error || hint ? messageId : undefined}
|
|
31
48
|
{...rest}
|
|
32
49
|
>
|
|
33
50
|
{@render children?.()}
|
|
34
51
|
</select>
|
|
52
|
+
<FieldMessage id={messageId} {hint} {error} />
|
|
35
53
|
</div>
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
type $$ComponentProps = {
|
|
2
3
|
label: string;
|
|
4
|
+
/** Keep the label for screen readers only (compact rows, toolbars). */
|
|
5
|
+
hideLabel?: boolean;
|
|
6
|
+
/** Borderless until hovered or focused, for inline editing (property rows). */
|
|
7
|
+
quiet?: boolean;
|
|
8
|
+
hint?: string;
|
|
9
|
+
error?: string;
|
|
3
10
|
id?: string;
|
|
4
11
|
value?: string;
|
|
5
12
|
disabled?: boolean;
|
|
6
13
|
class?: string;
|
|
7
|
-
|
|
14
|
+
/** `<option>` elements. */
|
|
15
|
+
children?: Snippet;
|
|
8
16
|
} & Record<string, unknown>;
|
|
9
17
|
declare const Select: import("svelte").Component<$$ComponentProps, {}, "value">;
|
|
10
18
|
type Select = ReturnType<typeof Select>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export default Spacer;
|
|
2
|
+
type Spacer = SvelteComponent<{
|
|
3
|
+
[x: string]: never;
|
|
4
|
+
}, {
|
|
5
|
+
[evt: string]: CustomEvent<any>;
|
|
6
|
+
}, {}> & {
|
|
7
|
+
$$bindings?: string | undefined;
|
|
8
|
+
};
|
|
9
|
+
declare const Spacer: $$__sveltets_2_IsomorphicComponent<{
|
|
10
|
+
[x: string]: never;
|
|
11
|
+
}, {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
}, {}, {}, string>;
|
|
14
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
15
|
+
new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
|
|
16
|
+
$$bindings?: Bindings;
|
|
17
|
+
} & Exports;
|
|
18
|
+
(internal: unknown, props: {
|
|
19
|
+
$$events?: Events;
|
|
20
|
+
$$slots?: Slots;
|
|
21
|
+
}): Exports & {
|
|
22
|
+
$set?: any;
|
|
23
|
+
$on?: any;
|
|
24
|
+
};
|
|
25
|
+
z_$$bindings?: Bindings;
|
|
26
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { cn } from '../utils/cn.js';
|
|
4
|
+
|
|
5
|
+
type Gap = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12;
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
gap = 4,
|
|
9
|
+
align = 'stretch',
|
|
10
|
+
class: className = '',
|
|
11
|
+
children,
|
|
12
|
+
...rest
|
|
13
|
+
}: {
|
|
14
|
+
/** Spacing between children, as a `--space-*` step. */
|
|
15
|
+
gap?: Gap;
|
|
16
|
+
align?: 'stretch' | 'start' | 'center' | 'end';
|
|
17
|
+
class?: string;
|
|
18
|
+
children?: Snippet;
|
|
19
|
+
} & Record<string, unknown> = $props();
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<div
|
|
23
|
+
class={cn('terminoir-stack', className)}
|
|
24
|
+
style:gap={`var(--space-${gap})`}
|
|
25
|
+
style:align-items={align === 'stretch' ? 'stretch' : align === 'center' ? 'center' : `flex-${align}`}
|
|
26
|
+
{...rest}
|
|
27
|
+
>
|
|
28
|
+
{@render children?.()}
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<style>
|
|
32
|
+
.terminoir-stack {
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
min-width: 0;
|
|
36
|
+
}
|
|
37
|
+
</style>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type Gap = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12;
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
/** Spacing between children, as a `--space-*` step. */
|
|
5
|
+
gap?: Gap;
|
|
6
|
+
align?: 'stretch' | 'start' | 'center' | 'end';
|
|
7
|
+
class?: string;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
} & Record<string, unknown>;
|
|
10
|
+
declare const Stack: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
11
|
+
type Stack = ReturnType<typeof Stack>;
|
|
12
|
+
export default Stack;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
let {
|
|
5
5
|
label,
|
|
6
|
+
hideLabel = false,
|
|
6
7
|
checked = $bindable(false),
|
|
7
8
|
disabled = false,
|
|
8
9
|
class: className = '',
|
|
@@ -10,17 +11,20 @@
|
|
|
10
11
|
...rest
|
|
11
12
|
}: {
|
|
12
13
|
label: string;
|
|
14
|
+
/** Keep the label for screen readers only (e.g. a switch inside a list row). */
|
|
15
|
+
hideLabel?: boolean;
|
|
13
16
|
checked?: boolean;
|
|
14
17
|
disabled?: boolean;
|
|
15
18
|
class?: string;
|
|
16
19
|
id?: string;
|
|
17
20
|
} & Record<string, unknown> = $props();
|
|
18
21
|
|
|
19
|
-
const
|
|
22
|
+
const fallbackId = $props.id();
|
|
23
|
+
const inputId = $derived(id ?? fallbackId);
|
|
20
24
|
</script>
|
|
21
25
|
|
|
22
26
|
<label class={cn('terminoir-switch', className)}>
|
|
23
|
-
<span class=
|
|
27
|
+
<span class={cn('terminoir-field__label', hideLabel && 'terminoir-sr-only')}>{label}</span>
|
|
24
28
|
<input
|
|
25
29
|
id={inputId}
|
|
26
30
|
type="checkbox"
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
children?: Snippet;
|
|
15
15
|
} = $props();
|
|
16
16
|
|
|
17
|
+
const uid = $props.id();
|
|
18
|
+
|
|
17
19
|
$effect.pre(() => {
|
|
18
20
|
if (!value && tabs[0]) value = tabs[0].id;
|
|
19
21
|
});
|
|
@@ -25,9 +27,9 @@
|
|
|
25
27
|
<button
|
|
26
28
|
type="button"
|
|
27
29
|
role="tab"
|
|
28
|
-
id={
|
|
30
|
+
id={`${uid}-tab-${tab.id}`}
|
|
29
31
|
aria-selected={value === tab.id}
|
|
30
|
-
aria-controls={
|
|
32
|
+
aria-controls={`${uid}-panel-${tab.id}`}
|
|
31
33
|
class="terminoir-tabs__trigger terminoir-focusable"
|
|
32
34
|
onclick={() => (value = tab.id)}
|
|
33
35
|
>
|
|
@@ -38,8 +40,8 @@
|
|
|
38
40
|
{#each tabs as tab (tab.id)}
|
|
39
41
|
<div
|
|
40
42
|
role="tabpanel"
|
|
41
|
-
id={
|
|
42
|
-
aria-labelledby={
|
|
43
|
+
id={`${uid}-panel-${tab.id}`}
|
|
44
|
+
aria-labelledby={`${uid}-tab-${tab.id}`}
|
|
43
45
|
hidden={value !== tab.id}
|
|
44
46
|
class="terminoir-tabs__panel"
|
|
45
47
|
>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import { cn } from '../utils/cn.js';
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
as = 'p',
|
|
7
|
+
tone = 'default',
|
|
8
|
+
size = 'md',
|
|
9
|
+
weight = 'normal',
|
|
10
|
+
truncate = false,
|
|
11
|
+
mono = false,
|
|
12
|
+
class: className = '',
|
|
13
|
+
children,
|
|
14
|
+
...rest
|
|
15
|
+
}: {
|
|
16
|
+
as?: 'p' | 'span' | 'div' | 'small';
|
|
17
|
+
tone?: 'default' | 'muted' | 'danger' | 'success' | 'warning';
|
|
18
|
+
size?: 'xs' | 'sm' | 'md' | 'lg';
|
|
19
|
+
weight?: 'normal' | 'medium' | 'semibold';
|
|
20
|
+
/** Single line with an ellipsis. */
|
|
21
|
+
truncate?: boolean;
|
|
22
|
+
mono?: boolean;
|
|
23
|
+
class?: string;
|
|
24
|
+
children?: Snippet;
|
|
25
|
+
} & Record<string, unknown> = $props();
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<svelte:element
|
|
29
|
+
this={as}
|
|
30
|
+
class={cn(
|
|
31
|
+
'terminoir-text',
|
|
32
|
+
`terminoir-text--${tone}`,
|
|
33
|
+
`terminoir-text--${size}`,
|
|
34
|
+
`terminoir-text--${weight}`,
|
|
35
|
+
truncate && 'terminoir-text--truncate',
|
|
36
|
+
mono && 'terminoir-text--mono',
|
|
37
|
+
className,
|
|
38
|
+
)}
|
|
39
|
+
{...rest}
|
|
40
|
+
>
|
|
41
|
+
{@render children?.()}
|
|
42
|
+
</svelte:element>
|
|
43
|
+
|
|
44
|
+
<style>
|
|
45
|
+
.terminoir-text {
|
|
46
|
+
margin: 0;
|
|
47
|
+
min-width: 0;
|
|
48
|
+
line-height: 1.5;
|
|
49
|
+
}
|
|
50
|
+
.terminoir-text--default { color: var(--foreground); }
|
|
51
|
+
.terminoir-text--muted { color: var(--muted-foreground); }
|
|
52
|
+
.terminoir-text--danger { color: var(--destructive); }
|
|
53
|
+
.terminoir-text--success { color: var(--status-done); }
|
|
54
|
+
.terminoir-text--warning { color: var(--status-today); }
|
|
55
|
+
.terminoir-text--xs { font-size: 0.75rem; }
|
|
56
|
+
.terminoir-text--sm { font-size: 0.8125rem; }
|
|
57
|
+
.terminoir-text--md { font-size: 0.875rem; }
|
|
58
|
+
.terminoir-text--lg { font-size: 1rem; }
|
|
59
|
+
.terminoir-text--normal { font-weight: 400; }
|
|
60
|
+
.terminoir-text--medium { font-weight: 500; }
|
|
61
|
+
.terminoir-text--semibold { font-weight: 600; }
|
|
62
|
+
.terminoir-text--truncate {
|
|
63
|
+
overflow: hidden;
|
|
64
|
+
text-overflow: ellipsis;
|
|
65
|
+
white-space: nowrap;
|
|
66
|
+
}
|
|
67
|
+
.terminoir-text--mono { font-family: var(--font-mono); }
|
|
68
|
+
</style>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
as?: 'p' | 'span' | 'div' | 'small';
|
|
4
|
+
tone?: 'default' | 'muted' | 'danger' | 'success' | 'warning';
|
|
5
|
+
size?: 'xs' | 'sm' | 'md' | 'lg';
|
|
6
|
+
weight?: 'normal' | 'medium' | 'semibold';
|
|
7
|
+
/** Single line with an ellipsis. */
|
|
8
|
+
truncate?: boolean;
|
|
9
|
+
mono?: boolean;
|
|
10
|
+
class?: string;
|
|
11
|
+
children?: Snippet;
|
|
12
|
+
} & Record<string, unknown>;
|
|
13
|
+
declare const Text: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
14
|
+
type Text = ReturnType<typeof Text>;
|
|
15
|
+
export default Text;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { cn } from '../utils/cn.js';
|
|
3
|
+
import FieldMessage from './FieldMessage.svelte';
|
|
3
4
|
|
|
4
5
|
let {
|
|
5
6
|
label,
|
|
7
|
+
hideLabel = false,
|
|
8
|
+
quiet = false,
|
|
9
|
+
hint,
|
|
10
|
+
error,
|
|
6
11
|
id,
|
|
7
12
|
value = $bindable(''),
|
|
8
13
|
rows = 4,
|
|
@@ -12,6 +17,12 @@
|
|
|
12
17
|
...rest
|
|
13
18
|
}: {
|
|
14
19
|
label: string;
|
|
20
|
+
/** Keep the label for screen readers only. */
|
|
21
|
+
hideLabel?: boolean;
|
|
22
|
+
/** Borderless until hovered or focused, for inline editing (property rows). */
|
|
23
|
+
quiet?: boolean;
|
|
24
|
+
hint?: string;
|
|
25
|
+
error?: string;
|
|
15
26
|
id?: string;
|
|
16
27
|
value?: string;
|
|
17
28
|
rows?: number;
|
|
@@ -20,11 +31,13 @@
|
|
|
20
31
|
class?: string;
|
|
21
32
|
} & Record<string, unknown> = $props();
|
|
22
33
|
|
|
23
|
-
const
|
|
34
|
+
const fallbackId = $props.id();
|
|
35
|
+
const inputId = $derived(id ?? fallbackId);
|
|
36
|
+
const messageId = $derived(`${inputId}-message`);
|
|
24
37
|
</script>
|
|
25
38
|
|
|
26
|
-
<div class={cn('terminoir-field', className)}>
|
|
27
|
-
<label class=
|
|
39
|
+
<div class={cn('terminoir-field', quiet && 'terminoir-field--quiet', className)}>
|
|
40
|
+
<label class={cn('terminoir-field__label', hideLabel && 'terminoir-sr-only')} for={inputId}>{label}</label>
|
|
28
41
|
<textarea
|
|
29
42
|
id={inputId}
|
|
30
43
|
class="terminoir-textarea terminoir-focusable"
|
|
@@ -32,6 +45,9 @@
|
|
|
32
45
|
{rows}
|
|
33
46
|
{placeholder}
|
|
34
47
|
{disabled}
|
|
48
|
+
aria-invalid={error ? true : undefined}
|
|
49
|
+
aria-describedby={error || hint ? messageId : undefined}
|
|
35
50
|
{...rest}
|
|
36
51
|
></textarea>
|
|
52
|
+
<FieldMessage id={messageId} {hint} {error} />
|
|
37
53
|
</div>
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
type $$ComponentProps = {
|
|
2
2
|
label: string;
|
|
3
|
+
/** Keep the label for screen readers only. */
|
|
4
|
+
hideLabel?: boolean;
|
|
5
|
+
/** Borderless until hovered or focused, for inline editing (property rows). */
|
|
6
|
+
quiet?: boolean;
|
|
7
|
+
hint?: string;
|
|
8
|
+
error?: string;
|
|
3
9
|
id?: string;
|
|
4
10
|
value?: string;
|
|
5
11
|
rows?: number;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { cn } from '../utils/cn.js';
|
|
3
|
+
|
|
4
|
+
let {
|
|
5
|
+
label,
|
|
6
|
+
value = $bindable(''),
|
|
7
|
+
placeholder = 'Untitled',
|
|
8
|
+
class: className = '',
|
|
9
|
+
...rest
|
|
10
|
+
}: {
|
|
11
|
+
/** Accessible name; not shown (the title itself is the heading). */
|
|
12
|
+
label: string;
|
|
13
|
+
value?: string;
|
|
14
|
+
placeholder?: string;
|
|
15
|
+
class?: string;
|
|
16
|
+
} & Record<string, unknown> = $props();
|
|
17
|
+
|
|
18
|
+
/** Titles are one line: Enter commits instead of inserting a newline. */
|
|
19
|
+
function onkeydown(event: KeyboardEvent) {
|
|
20
|
+
if (event.key === 'Enter') {
|
|
21
|
+
event.preventDefault();
|
|
22
|
+
(event.currentTarget as HTMLTextAreaElement).blur();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<textarea
|
|
28
|
+
class={cn('terminoir-title-input terminoir-focusable', className)}
|
|
29
|
+
aria-label={label}
|
|
30
|
+
rows="1"
|
|
31
|
+
bind:value
|
|
32
|
+
{placeholder}
|
|
33
|
+
{onkeydown}
|
|
34
|
+
{...rest}
|
|
35
|
+
></textarea>
|
|
36
|
+
|
|
37
|
+
<style>
|
|
38
|
+
.terminoir-title-input {
|
|
39
|
+
width: 100%;
|
|
40
|
+
margin: 0;
|
|
41
|
+
padding: 0.1rem 0.25rem;
|
|
42
|
+
margin-inline: -0.25rem;
|
|
43
|
+
border: 1px solid transparent;
|
|
44
|
+
border-radius: var(--radius-control);
|
|
45
|
+
background: transparent;
|
|
46
|
+
color: var(--foreground);
|
|
47
|
+
font: inherit;
|
|
48
|
+
font-size: 1.75rem;
|
|
49
|
+
font-weight: 600;
|
|
50
|
+
line-height: 1.25;
|
|
51
|
+
letter-spacing: -0.01em;
|
|
52
|
+
resize: none;
|
|
53
|
+
field-sizing: content;
|
|
54
|
+
overflow: hidden;
|
|
55
|
+
}
|
|
56
|
+
.terminoir-title-input:hover { border-color: color-mix(in srgb, var(--foreground) 10%, transparent); }
|
|
57
|
+
.terminoir-title-input:focus-visible { outline: none; border-color: var(--ring); }
|
|
58
|
+
.terminoir-title-input::placeholder { color: var(--muted-foreground); }
|
|
59
|
+
@media (max-width: 700px) {
|
|
60
|
+
.terminoir-title-input { font-size: 1.375rem; }
|
|
61
|
+
}
|
|
62
|
+
</style>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type $$ComponentProps = {
|
|
2
|
+
/** Accessible name; not shown (the title itself is the heading). */
|
|
3
|
+
label: string;
|
|
4
|
+
value?: string;
|
|
5
|
+
placeholder?: string;
|
|
6
|
+
class?: string;
|
|
7
|
+
} & Record<string, unknown>;
|
|
8
|
+
declare const TitleInput: import("svelte").Component<$$ComponentProps, {}, "value">;
|
|
9
|
+
type TitleInput = ReturnType<typeof TitleInput>;
|
|
10
|
+
export default TitleInput;
|
package/dist/index.d.ts
CHANGED
|
@@ -17,10 +17,10 @@ export { default as CardGrid } from './components/CardGrid.svelte';
|
|
|
17
17
|
export { default as Checkbox } from './components/Checkbox.svelte';
|
|
18
18
|
export { default as Chip } from './components/Chip.svelte';
|
|
19
19
|
export { default as CommandPalette } from './components/CommandPalette.svelte';
|
|
20
|
-
export type { CommandItem } from './
|
|
20
|
+
export type { CommandItem } from './utils/commands.js';
|
|
21
21
|
export { default as Dialog } from './components/Dialog.svelte';
|
|
22
22
|
export { default as DropdownMenu } from './components/DropdownMenu.svelte';
|
|
23
|
-
export type { MenuItem } from './
|
|
23
|
+
export type { MenuItem } from './utils/menu.js';
|
|
24
24
|
export { default as EmptyState } from './components/EmptyState.svelte';
|
|
25
25
|
export { default as FontPicker } from './components/FontPicker.svelte';
|
|
26
26
|
export { default as NavIcon } from './components/NavIcon.svelte';
|
|
@@ -38,3 +38,36 @@ export { default as Tabs } from './components/Tabs.svelte';
|
|
|
38
38
|
export { default as Textarea } from './components/Textarea.svelte';
|
|
39
39
|
export { default as Toaster } from './components/Toaster.svelte';
|
|
40
40
|
export { default as Tooltip } from './components/Tooltip.svelte';
|
|
41
|
+
export { default as Page } from './components/Page.svelte';
|
|
42
|
+
export { default as PageHeader } from './components/PageHeader.svelte';
|
|
43
|
+
export { default as Section } from './components/Section.svelte';
|
|
44
|
+
export { default as Stack } from './components/Stack.svelte';
|
|
45
|
+
export { default as Inline } from './components/Inline.svelte';
|
|
46
|
+
export { default as Text } from './components/Text.svelte';
|
|
47
|
+
export { default as Disclosure } from './components/Disclosure.svelte';
|
|
48
|
+
export { default as NavSection } from './components/NavSection.svelte';
|
|
49
|
+
export { default as Spacer } from './components/Spacer.svelte';
|
|
50
|
+
export { default as Centered } from './components/Centered.svelte';
|
|
51
|
+
export { default as Prose } from './components/Prose.svelte';
|
|
52
|
+
export { default as CanvasStage } from './components/CanvasStage.svelte';
|
|
53
|
+
export { default as CalendarGrid } from './components/CalendarGrid.svelte';
|
|
54
|
+
export { default as DocumentViewer } from './components/DocumentViewer.svelte';
|
|
55
|
+
export type { ViewerMark } from './utils/componentTypes.js';
|
|
56
|
+
export { default as DataTable } from './components/DataTable.svelte';
|
|
57
|
+
export type { DataColumn } from './utils/componentTypes.js';
|
|
58
|
+
export { default as List } from './components/List.svelte';
|
|
59
|
+
export { default as ListItem } from './components/ListItem.svelte';
|
|
60
|
+
export { default as DescriptionList } from './components/DescriptionList.svelte';
|
|
61
|
+
export type { DescriptionItem } from './utils/componentTypes.js';
|
|
62
|
+
export { default as FormRow } from './components/FormRow.svelte';
|
|
63
|
+
export { default as SearchPicker } from './components/SearchPicker.svelte';
|
|
64
|
+
export { default as FileButton } from './components/FileButton.svelte';
|
|
65
|
+
export { default as TitleInput } from './components/TitleInput.svelte';
|
|
66
|
+
export type { PickerOption } from './utils/componentTypes.js';
|
|
67
|
+
export { default as RadioCards } from './components/RadioCards.svelte';
|
|
68
|
+
export type { RadioCardOption } from './utils/componentTypes.js';
|
|
69
|
+
export { default as SegmentedControl } from './components/SegmentedControl.svelte';
|
|
70
|
+
export type { SegmentOption } from './utils/componentTypes.js';
|
|
71
|
+
export { default as ContextMenu } from './components/ContextMenu.svelte';
|
|
72
|
+
export { default as Drawer } from './components/Drawer.svelte';
|
|
73
|
+
export { addDays, calendarRange, eventsOn, sameDay, shiftCalendar, startOfDay, startOfWeek, type CalendarEvent, type CalendarMode, } from './utils/calendar.js';
|
package/dist/index.js
CHANGED
|
@@ -36,3 +36,34 @@ export { default as Tabs } from './components/Tabs.svelte';
|
|
|
36
36
|
export { default as Textarea } from './components/Textarea.svelte';
|
|
37
37
|
export { default as Toaster } from './components/Toaster.svelte';
|
|
38
38
|
export { default as Tooltip } from './components/Tooltip.svelte';
|
|
39
|
+
// Layout
|
|
40
|
+
export { default as Page } from './components/Page.svelte';
|
|
41
|
+
export { default as PageHeader } from './components/PageHeader.svelte';
|
|
42
|
+
export { default as Section } from './components/Section.svelte';
|
|
43
|
+
export { default as Stack } from './components/Stack.svelte';
|
|
44
|
+
export { default as Inline } from './components/Inline.svelte';
|
|
45
|
+
export { default as Text } from './components/Text.svelte';
|
|
46
|
+
export { default as Disclosure } from './components/Disclosure.svelte';
|
|
47
|
+
export { default as NavSection } from './components/NavSection.svelte';
|
|
48
|
+
export { default as Spacer } from './components/Spacer.svelte';
|
|
49
|
+
export { default as Centered } from './components/Centered.svelte';
|
|
50
|
+
export { default as Prose } from './components/Prose.svelte';
|
|
51
|
+
export { default as CanvasStage } from './components/CanvasStage.svelte';
|
|
52
|
+
export { default as CalendarGrid } from './components/CalendarGrid.svelte';
|
|
53
|
+
export { default as DocumentViewer } from './components/DocumentViewer.svelte';
|
|
54
|
+
// Data display
|
|
55
|
+
export { default as DataTable } from './components/DataTable.svelte';
|
|
56
|
+
export { default as List } from './components/List.svelte';
|
|
57
|
+
export { default as ListItem } from './components/ListItem.svelte';
|
|
58
|
+
export { default as DescriptionList } from './components/DescriptionList.svelte';
|
|
59
|
+
export { default as FormRow } from './components/FormRow.svelte';
|
|
60
|
+
// Inputs
|
|
61
|
+
export { default as SearchPicker } from './components/SearchPicker.svelte';
|
|
62
|
+
export { default as FileButton } from './components/FileButton.svelte';
|
|
63
|
+
export { default as TitleInput } from './components/TitleInput.svelte';
|
|
64
|
+
export { default as RadioCards } from './components/RadioCards.svelte';
|
|
65
|
+
export { default as SegmentedControl } from './components/SegmentedControl.svelte';
|
|
66
|
+
// Overlays
|
|
67
|
+
export { default as ContextMenu } from './components/ContextMenu.svelte';
|
|
68
|
+
export { default as Drawer } from './components/Drawer.svelte';
|
|
69
|
+
export { addDays, calendarRange, eventsOn, sameDay, shiftCalendar, startOfDay, startOfWeek, } from './utils/calendar.js';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** Wall-clock calendar helpers (local time zone) for week and month views. */
|
|
2
|
+
export type CalendarMode = 'week' | 'month';
|
|
3
|
+
export type CalendarEvent = {
|
|
4
|
+
id: string;
|
|
5
|
+
title: string;
|
|
6
|
+
start: Date;
|
|
7
|
+
end: Date;
|
|
8
|
+
allDay: boolean;
|
|
9
|
+
/** Dimmed (e.g. "free" / transparent events). */
|
|
10
|
+
muted?: boolean;
|
|
11
|
+
/** Accent colour (palette name or CSS colour). */
|
|
12
|
+
color?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const MINUTES_PER_DAY: number;
|
|
15
|
+
export declare function startOfDay(d: Date): Date;
|
|
16
|
+
/** Monday of the week containing `d`. */
|
|
17
|
+
export declare function startOfWeek(d: Date): Date;
|
|
18
|
+
export declare function addDays(d: Date, n: number): Date;
|
|
19
|
+
export declare function sameDay(a: Date, b: Date): boolean;
|
|
20
|
+
/** Visible range `[start, end)` around `anchor`: a Monday-start week or a calendar month. */
|
|
21
|
+
export declare function calendarRange(anchor: Date, mode: CalendarMode): {
|
|
22
|
+
start: Date;
|
|
23
|
+
end: Date;
|
|
24
|
+
};
|
|
25
|
+
/** Move the anchor by `delta` weeks or months. */
|
|
26
|
+
export declare function shiftCalendar(anchor: Date, mode: CalendarMode, delta: number): Date;
|
|
27
|
+
/** Six Monday-start weeks covering the month of `monthStart`. */
|
|
28
|
+
export declare function monthGrid(monthStart: Date): Date[];
|
|
29
|
+
/** Events showing on `day` (multi-day all-day events on each day), all-day first, then by start time. */
|
|
30
|
+
export declare function eventsOn(events: CalendarEvent[], day: Date): CalendarEvent[];
|
|
31
|
+
/** Vertical position of a timed event in a day column, as percentages of the day. */
|
|
32
|
+
export declare function dayLayout(event: CalendarEvent): {
|
|
33
|
+
top: number;
|
|
34
|
+
height: number;
|
|
35
|
+
};
|
|
36
|
+
export type PlacedEvent = {
|
|
37
|
+
event: CalendarEvent;
|
|
38
|
+
/** Percent of the day from the top. */
|
|
39
|
+
top: number;
|
|
40
|
+
height: number;
|
|
41
|
+
/** Side-by-side column within its overlap group, and how many columns the group has. */
|
|
42
|
+
lane: number;
|
|
43
|
+
lanes: number;
|
|
44
|
+
/** Short enough to render as one line. */
|
|
45
|
+
compact: boolean;
|
|
46
|
+
};
|
|
47
|
+
/** Lay out a day's timed events so overlapping ones sit side by side instead of on top of each other. */
|
|
48
|
+
export declare function layoutDay(events: CalendarEvent[]): PlacedEvent[];
|