@vit-foundation/ui 0.7.0 → 0.9.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.
- package/dist/components/contact/ContactForm.svelte +4 -0
- package/dist/components/projects/ProjectCard.svelte +11 -3
- package/dist/components/timeline/TimelineMilestone.svelte +21 -6
- package/dist/components/ui/Field.svelte +23 -2
- package/dist/components/ui/Field.svelte.d.ts +8 -0
- package/dist/components/ui/FilterChips.svelte +21 -8
- package/dist/components/ui/FilterChips.svelte.d.ts +8 -0
- package/dist/components/weeklies/SortSelect.svelte +12 -7
- package/dist/edit/types.d.ts +1 -1
- package/package.json +1 -1
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
<Field
|
|
59
59
|
id="contact-category"
|
|
60
60
|
label={msg.contact_categoryLabel()}
|
|
61
|
+
labelEdit={config.messageEdit?.('contact_categoryLabel')}
|
|
61
62
|
field={f.fields.category}
|
|
62
63
|
constraint={null}
|
|
63
64
|
>
|
|
@@ -73,6 +74,7 @@
|
|
|
73
74
|
<Field
|
|
74
75
|
id="contact-name"
|
|
75
76
|
label={msg.contact_nameLabel()}
|
|
77
|
+
labelEdit={config.messageEdit?.('contact_nameLabel')}
|
|
76
78
|
field={f.fields.name}
|
|
77
79
|
constraint={CONTACT_NAME}
|
|
78
80
|
>
|
|
@@ -90,6 +92,7 @@
|
|
|
90
92
|
<Field
|
|
91
93
|
id="contact-email"
|
|
92
94
|
label={msg.contact_emailLabel()}
|
|
95
|
+
labelEdit={config.messageEdit?.('contact_emailLabel')}
|
|
93
96
|
field={f.fields.email}
|
|
94
97
|
constraint={EMAIL}
|
|
95
98
|
>
|
|
@@ -107,6 +110,7 @@
|
|
|
107
110
|
<Field
|
|
108
111
|
id="contact-message"
|
|
109
112
|
label={msg.contact_messageLabel()}
|
|
113
|
+
labelEdit={config.messageEdit?.('contact_messageLabel')}
|
|
110
114
|
field={f.fields.message}
|
|
111
115
|
constraint={CONTACT_MESSAGE}
|
|
112
116
|
>
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
<script lang="ts">
|
|
12
12
|
import { getUiConfig } from '../../config/context.js';
|
|
13
|
+
import ActionLabel from '../../edit/ActionLabel.svelte';
|
|
13
14
|
import type { ProjectCardData } from '../../content/types.js';
|
|
14
15
|
import { getEditAdapter } from '../../edit/context.js';
|
|
15
16
|
import Editable from '../../edit/Editable.svelte';
|
|
@@ -57,9 +58,16 @@
|
|
|
57
58
|
{#snippet children(text, attrs)}<p {...attrs}>{text}</p>{/snippet}
|
|
58
59
|
</Editable>
|
|
59
60
|
{#if project.hasStory}
|
|
60
|
-
<
|
|
61
|
-
{config.
|
|
62
|
-
|
|
61
|
+
<ActionLabel
|
|
62
|
+
edit={config.messageEdit?.('common_readMore')}
|
|
63
|
+
value={config.messages.common_readMore()}
|
|
64
|
+
>
|
|
65
|
+
{#snippet control()}
|
|
66
|
+
<Link href={`/what-we-do/${project.slug}`} class="more">
|
|
67
|
+
{config.messages.common_readMore()}
|
|
68
|
+
</Link>
|
|
69
|
+
{/snippet}
|
|
70
|
+
</ActionLabel>
|
|
63
71
|
{/if}
|
|
64
72
|
</div>
|
|
65
73
|
</article>
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
<script lang="ts">
|
|
12
12
|
import { getUiConfig } from '../../config/context.js';
|
|
13
|
+
import ActionLabel from '../../edit/ActionLabel.svelte';
|
|
13
14
|
import type { MilestoneData } from '../../content/types.js';
|
|
14
15
|
import Editable from '../../edit/Editable.svelte';
|
|
15
16
|
import { MILESTONE_CATEGORY_COLOR, milestoneCategoryLabel } from '../../utils/milestones.js';
|
|
@@ -47,7 +48,12 @@
|
|
|
47
48
|
|
|
48
49
|
<article style={`--milestone-color: ${color}`}>
|
|
49
50
|
<span class="dot" aria-hidden="true"></span>
|
|
50
|
-
<
|
|
51
|
+
<Editable
|
|
52
|
+
edit={config.messageEdit?.(`category_${milestone.category}`)}
|
|
53
|
+
value={milestoneCategoryLabel(milestone.category, config.messages)}
|
|
54
|
+
>
|
|
55
|
+
{#snippet children(text, attrs)}<p class="category" {...attrs}>{text}</p>{/snippet}
|
|
56
|
+
</Editable>
|
|
51
57
|
<DateText value={milestone.occurredOn} />
|
|
52
58
|
<Editable edit={edit?.title} value={milestone.title}>
|
|
53
59
|
{#snippet children(text, attrs)}<h3 {...attrs}>{text}</h3>{/snippet}
|
|
@@ -62,11 +68,20 @@
|
|
|
62
68
|
{/if}
|
|
63
69
|
{#if milestone.linkUrl}
|
|
64
70
|
<p class="more">
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
<ActionLabel
|
|
72
|
+
edit={config.messageEdit?.('common_readMore')}
|
|
73
|
+
value={config.messages.common_readMore()}
|
|
74
|
+
>
|
|
75
|
+
{#snippet control()}
|
|
76
|
+
{#if isExternal}
|
|
77
|
+
<a href={milestone.linkUrl} rel="external noopener"
|
|
78
|
+
>{config.messages.common_readMore()}</a
|
|
79
|
+
>
|
|
80
|
+
{:else if milestone.linkUrl}
|
|
81
|
+
<Link href={milestone.linkUrl}>{config.messages.common_readMore()}</Link>
|
|
82
|
+
{/if}
|
|
83
|
+
{/snippet}
|
|
84
|
+
</ActionLabel>
|
|
70
85
|
</p>
|
|
71
86
|
{/if}
|
|
72
87
|
</article>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { FieldConstraint } from '../../content/types.js';
|
|
4
|
+
import ActionLabel from '../../edit/ActionLabel.svelte';
|
|
5
|
+
import type { EditDescriptor } from '../../edit/types.js';
|
|
4
6
|
|
|
5
7
|
/** Attributes the control must spread (`{...attrs}`) to stay wired. */
|
|
6
8
|
interface ControlAttrs {
|
|
@@ -46,18 +48,37 @@
|
|
|
46
48
|
constraint: FieldConstraint | null;
|
|
47
49
|
/** Render the label visually hidden (surrounding context already labels it). */
|
|
48
50
|
hideLabel?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Edit descriptor for the LABEL's wording. While editing, only the
|
|
53
|
+
* label swaps for editable text — an editable span is not a <label>,
|
|
54
|
+
* so clicking it no longer focuses the control, and the control itself
|
|
55
|
+
* stays rendered and live. Hidden labels are never offered.
|
|
56
|
+
*/
|
|
57
|
+
labelEdit?: EditDescriptor;
|
|
49
58
|
/** The input/textarea/select, spreading the given attrs. */
|
|
50
59
|
children: Snippet<[ControlAttrs]>;
|
|
51
60
|
}
|
|
52
61
|
|
|
53
|
-
let {
|
|
62
|
+
let {
|
|
63
|
+
id,
|
|
64
|
+
label,
|
|
65
|
+
field,
|
|
66
|
+
constraint,
|
|
67
|
+
hideLabel = false,
|
|
68
|
+
labelEdit = undefined,
|
|
69
|
+
children
|
|
70
|
+
}: Props = $props();
|
|
54
71
|
|
|
55
72
|
const errorMessage = $derived(field.issues()?.[0]?.message);
|
|
56
73
|
const showError = $derived(errorMessage !== undefined);
|
|
57
74
|
</script>
|
|
58
75
|
|
|
59
76
|
<div class="field">
|
|
60
|
-
<
|
|
77
|
+
<ActionLabel edit={hideLabel ? undefined : labelEdit} value={label}>
|
|
78
|
+
{#snippet control()}
|
|
79
|
+
<label class:visually-hidden={hideLabel} for={id}>{label}</label>
|
|
80
|
+
{/snippet}
|
|
81
|
+
</ActionLabel>
|
|
61
82
|
{@render children({
|
|
62
83
|
id,
|
|
63
84
|
'aria-describedby': showError ? `${id}-error` : undefined,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { FieldConstraint } from '../../content/types.js';
|
|
3
|
+
import type { EditDescriptor } from '../../edit/types.js';
|
|
3
4
|
/** Attributes the control must spread (`{...attrs}`) to stay wired. */
|
|
4
5
|
interface ControlAttrs {
|
|
5
6
|
id: string;
|
|
@@ -47,6 +48,13 @@ interface Props {
|
|
|
47
48
|
constraint: FieldConstraint | null;
|
|
48
49
|
/** Render the label visually hidden (surrounding context already labels it). */
|
|
49
50
|
hideLabel?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Edit descriptor for the LABEL's wording. While editing, only the
|
|
53
|
+
* label swaps for editable text — an editable span is not a <label>,
|
|
54
|
+
* so clicking it no longer focuses the control, and the control itself
|
|
55
|
+
* stays rendered and live. Hidden labels are never offered.
|
|
56
|
+
*/
|
|
57
|
+
labelEdit?: EditDescriptor;
|
|
50
58
|
/** The input/textarea/select, spreading the given attrs. */
|
|
51
59
|
children: Snippet<[ControlAttrs]>;
|
|
52
60
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import ActionLabel from '../../edit/ActionLabel.svelte';
|
|
3
|
+
import type { EditDescriptor } from '../../edit/types.js';
|
|
2
4
|
import GhostButton from './GhostButton.svelte';
|
|
3
5
|
|
|
4
6
|
interface Chip {
|
|
@@ -13,9 +15,16 @@
|
|
|
13
15
|
label: string;
|
|
14
16
|
/** Called with the toggled value, or null when the active chip is unselected. */
|
|
15
17
|
onchange: (value: string | null) => void;
|
|
18
|
+
/**
|
|
19
|
+
* Edit descriptors for the chip LABELS — a function because the host
|
|
20
|
+
* owns what a chip's wording is (a theme's localized name, a category
|
|
21
|
+
* message). While editing, a chip with a descriptor renders as
|
|
22
|
+
* editable text instead of a button (see ActionLabel).
|
|
23
|
+
*/
|
|
24
|
+
editFor?: (chip: Chip) => EditDescriptor | undefined;
|
|
16
25
|
}
|
|
17
26
|
|
|
18
|
-
let { chips, selected, label, onchange }: Props = $props();
|
|
27
|
+
let { chips, selected, label, onchange, editFor = undefined }: Props = $props();
|
|
19
28
|
|
|
20
29
|
function toggle(value: string): void {
|
|
21
30
|
onchange(selected === value ? null : value);
|
|
@@ -24,13 +33,17 @@
|
|
|
24
33
|
|
|
25
34
|
<div class="chips" role="group" aria-label={label}>
|
|
26
35
|
{#each chips as chip (chip.value)}
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
<ActionLabel edit={editFor?.(chip)} value={chip.label}>
|
|
37
|
+
{#snippet control()}
|
|
38
|
+
<GhostButton
|
|
39
|
+
variant="chip"
|
|
40
|
+
aria-pressed={selected === chip.value}
|
|
41
|
+
onclick={() => toggle(chip.value)}
|
|
42
|
+
>
|
|
43
|
+
{chip.label}
|
|
44
|
+
</GhostButton>
|
|
45
|
+
{/snippet}
|
|
46
|
+
</ActionLabel>
|
|
34
47
|
{/each}
|
|
35
48
|
</div>
|
|
36
49
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { EditDescriptor } from '../../edit/types.js';
|
|
1
2
|
interface Chip {
|
|
2
3
|
value: string;
|
|
3
4
|
label: string;
|
|
@@ -9,6 +10,13 @@ interface Props {
|
|
|
9
10
|
label: string;
|
|
10
11
|
/** Called with the toggled value, or null when the active chip is unselected. */
|
|
11
12
|
onchange: (value: string | null) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Edit descriptors for the chip LABELS — a function because the host
|
|
15
|
+
* owns what a chip's wording is (a theme's localized name, a category
|
|
16
|
+
* message). While editing, a chip with a descriptor renders as
|
|
17
|
+
* editable text instead of a button (see ActionLabel).
|
|
18
|
+
*/
|
|
19
|
+
editFor?: (chip: Chip) => EditDescriptor | undefined;
|
|
12
20
|
}
|
|
13
21
|
declare const FilterChips: import("svelte").Component<Props, {}, "">;
|
|
14
22
|
type FilterChips = ReturnType<typeof FilterChips>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { getUiConfig } from '../../config/context.js';
|
|
3
3
|
import type { SortDirection } from '../../content/types.js';
|
|
4
|
+
import ActionLabel from '../../edit/ActionLabel.svelte';
|
|
4
5
|
|
|
5
6
|
interface Props {
|
|
6
7
|
value: SortDirection;
|
|
@@ -18,13 +19,17 @@
|
|
|
18
19
|
}
|
|
19
20
|
</script>
|
|
20
21
|
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
</
|
|
22
|
+
<ActionLabel edit={config.messageEdit?.('weeklies_sortLabel')} value={msg.weeklies_sortLabel()}>
|
|
23
|
+
{#snippet control()}
|
|
24
|
+
<label>
|
|
25
|
+
<span>{msg.weeklies_sortLabel()}</span>
|
|
26
|
+
<select class="control" {value} onchange={handleChange}>
|
|
27
|
+
<option value="desc">{msg.weeklies_sortDesc()}</option>
|
|
28
|
+
<option value="asc">{msg.weeklies_sortAsc()}</option>
|
|
29
|
+
</select>
|
|
30
|
+
</label>
|
|
31
|
+
{/snippet}
|
|
32
|
+
</ActionLabel>
|
|
28
33
|
|
|
29
34
|
<style>
|
|
30
35
|
label {
|
package/dist/edit/types.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export declare function localize(value: LocalizedText, locale: Locale): string;
|
|
|
15
15
|
* The entities whose fields the components can mark editable. Names match
|
|
16
16
|
* the content tables so an adapter can route a save without a mapping layer.
|
|
17
17
|
*/
|
|
18
|
-
export type EditableEntity = 'weeklies' | 'projects' | 'milestones' | 'team_members' | 'job_openings';
|
|
18
|
+
export type EditableEntity = 'weeklies' | 'projects' | 'milestones' | 'team_members' | 'job_openings' | 'themes';
|
|
19
19
|
/**
|
|
20
20
|
* The identity of one editable string in the content model: a page copy
|
|
21
21
|
* block (`page_content` row), one localized field of a domain entity, or one
|