C3 cierra con `more-link` y C4 con los seis marcadores que eidos estilizaba sin declaracion. Los tres botones sin fuentes (`day-add`, `edit-action`, `search-button`) comparten una clase; `undo`/`redo` se cablean sobre la del nav; `timegrid` pasa a `time-view` porque estaba a un guion de la parte `time-grid` que vive dentro; `peek-panel` y `day-peek` quedan como partes de display puro con marcador inline. Cada una renderiza un `<button>` real cuando el morfo lo declara: una `Region` que cae a `<div>` pondria el `type` declarado sobre un no-boton. La lupa deja de ser un adorno sin `onclick`: abre una paleta `Command.Dialog` sobre TODOS los eventos, no un filtro de la vista, con `goToDate` nuevo en el provider — la generalizacion de la que `goToday` era un caso particular. El texto buscable viaja en `keywords` porque el scorer de Command lee value + keywords y NUNCA los hijos renderizados, asi que se busca por titulo, por tipo y por fecha. Y tres etiquetas que mentian en silencio: `translationRef` / `commonRef` normalizan la clave LITERAL y no consultan ningun mapa, asi que `prevMonth` / `nextMonth` / `moreEvents` y `action.undo` / `action.redo` caian al fallback ingles en una pagina `es`. Corregidas contra el catalogo, con `common.buttons.undo` / `redo` anadidas. Verificado: check 74 = base (delta cero) · 458 vitest · docs:check 0/621 · rtl:check 0/177 · eidos-lint chronos morfo-backed 32 -> 44, invalid 0 · navegador limpio en las tres vistas, con el A/B del undo medido (18 jun -> drag -> 25 jun -> undo -> 18 jun -> redo -> 25 jun) y el salto de la paleta (noviembre -> elegir Retro -> junio). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>alpha-0.1-dir-prefs
parent
56a96114f8
commit
968fff9cdf
@ -0,0 +1,46 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* Soma `Chronos.DayAdd` — the "+" create affordance inside a day cell. A real
|
||||
* `<button>` (its morfo declares `role: 'button'` plus the `type` literal),
|
||||
* so the native element is the honest one here.
|
||||
*/
|
||||
import { readableActive, writableActive } from '$libs/reactive';
|
||||
import { mergeProps } from '../../../props';
|
||||
import { createId } from '$active-uix/id';
|
||||
import { ChronosActionProvider } from '../chronos-provider.svelte';
|
||||
import type { ChronosActionProps } from '../types';
|
||||
|
||||
const uid = $props.id();
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
id = createId(uid, 'chronos-day-add'),
|
||||
children,
|
||||
child,
|
||||
...restProps
|
||||
}: ChronosActionProps = $props();
|
||||
|
||||
const state = ChronosActionProvider.create('day-add', {
|
||||
id: readableActive(() => id),
|
||||
ref: writableActive(
|
||||
() => ref,
|
||||
(v) => (ref = v)
|
||||
)
|
||||
});
|
||||
|
||||
// The morfo declares a translated `aria-label` here, so the resolved bag
|
||||
// always carries one — `mergeProps` just cannot express that. Asserted at
|
||||
// this single boundary, which is what lets `IconButton` (it requires a
|
||||
// label) be composed without the view re-typing what the morfo owns.
|
||||
const mergedProps = $derived(
|
||||
mergeProps(restProps, state.props) as Record<string, unknown> & { 'aria-label': string }
|
||||
);
|
||||
</script>
|
||||
|
||||
{#if child}
|
||||
{@render child({ props: mergedProps })}
|
||||
{:else}
|
||||
<button {...mergedProps}>
|
||||
{@render children?.()}
|
||||
</button>
|
||||
{/if}
|
||||
@ -0,0 +1,47 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* Soma `Chronos.EditAction` — the view→edit toggle pinned in the editor
|
||||
* dialog's corner. The editor IS a reused Dialog and chronos declares none
|
||||
* of its parts, but this control is chronos's own and eidos positions it,
|
||||
* so it is a part — the same shape as `MoreLink` inside a composed Popover.
|
||||
*/
|
||||
import { readableActive, writableActive } from '$libs/reactive';
|
||||
import { mergeProps } from '../../../props';
|
||||
import { createId } from '$active-uix/id';
|
||||
import { ChronosActionProvider } from '../chronos-provider.svelte';
|
||||
import type { ChronosActionProps } from '../types';
|
||||
|
||||
const uid = $props.id();
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
id = createId(uid, 'chronos-edit-action'),
|
||||
children,
|
||||
child,
|
||||
...restProps
|
||||
}: ChronosActionProps = $props();
|
||||
|
||||
const state = ChronosActionProvider.create('edit-action', {
|
||||
id: readableActive(() => id),
|
||||
ref: writableActive(
|
||||
() => ref,
|
||||
(v) => (ref = v)
|
||||
)
|
||||
});
|
||||
|
||||
// The morfo declares a translated `aria-label` here, so the resolved bag
|
||||
// always carries one — `mergeProps` just cannot express that. Asserted at
|
||||
// this single boundary, which is what lets `IconButton` (it requires a
|
||||
// label) be composed without the view re-typing what the morfo owns.
|
||||
const mergedProps = $derived(
|
||||
mergeProps(restProps, state.props) as Record<string, unknown> & { 'aria-label': string }
|
||||
);
|
||||
</script>
|
||||
|
||||
{#if child}
|
||||
{@render child({ props: mergedProps })}
|
||||
{:else}
|
||||
<button {...mergedProps}>
|
||||
{@render children?.()}
|
||||
</button>
|
||||
{/if}
|
||||
@ -0,0 +1,48 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* Soma `Chronos.MoreLink` — a month cell's "+N more" overflow link. A real
|
||||
* `<button>` like the agenda item (its morfo declares `role: 'button'` plus
|
||||
* the `type` literal, and it nests no control), so the native element is
|
||||
* the honest one here.
|
||||
*/
|
||||
import { readableActive, writableActive } from '$libs/reactive';
|
||||
import { mergeProps } from '../../../props';
|
||||
import { createId } from '$active-uix/id';
|
||||
import { ChronosMoreLinkProvider } from '../chronos-provider.svelte';
|
||||
import type { ChronosMoreLinkProps } from '../types';
|
||||
|
||||
const uid = $props.id();
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
id = createId(uid, 'chronos-more-link'),
|
||||
count,
|
||||
children,
|
||||
child,
|
||||
...restProps
|
||||
}: ChronosMoreLinkProps = $props();
|
||||
|
||||
const state = ChronosMoreLinkProvider.create({
|
||||
id: readableActive(() => id),
|
||||
ref: writableActive(
|
||||
() => ref,
|
||||
(v) => (ref = v)
|
||||
),
|
||||
count: readableActive(() => count)
|
||||
});
|
||||
|
||||
// Same guarantee as the nav buttons: the morfo declares a translated
|
||||
// `aria-label` here, so the resolved bag always carries one — `mergeProps`
|
||||
// just cannot express that. Asserted at this single boundary.
|
||||
const mergedProps = $derived(
|
||||
mergeProps(restProps, state.props) as Record<string, unknown> & { 'aria-label': string }
|
||||
);
|
||||
</script>
|
||||
|
||||
{#if child}
|
||||
{@render child({ props: mergedProps })}
|
||||
{:else}
|
||||
<button {...mergedProps}>
|
||||
{@render children?.()}
|
||||
</button>
|
||||
{/if}
|
||||
@ -0,0 +1,46 @@
|
||||
<script lang="ts">
|
||||
/**
|
||||
* Soma `Chronos.SearchButton` — opens the search palette. Its contract is
|
||||
* just the trigger's: the palette's anatomy belongs to the composed
|
||||
* `Command` + `Dialog`, which chronos does not re-declare.
|
||||
*/
|
||||
import { readableActive, writableActive } from '$libs/reactive';
|
||||
import { mergeProps } from '../../../props';
|
||||
import { createId } from '$active-uix/id';
|
||||
import { ChronosActionProvider } from '../chronos-provider.svelte';
|
||||
import type { ChronosActionProps } from '../types';
|
||||
|
||||
const uid = $props.id();
|
||||
|
||||
let {
|
||||
ref = $bindable(null),
|
||||
id = createId(uid, 'chronos-search-button'),
|
||||
children,
|
||||
child,
|
||||
...restProps
|
||||
}: ChronosActionProps = $props();
|
||||
|
||||
const state = ChronosActionProvider.create('search-button', {
|
||||
id: readableActive(() => id),
|
||||
ref: writableActive(
|
||||
() => ref,
|
||||
(v) => (ref = v)
|
||||
)
|
||||
});
|
||||
|
||||
// The morfo declares a translated `aria-label` here, so the resolved bag
|
||||
// always carries one — `mergeProps` just cannot express that. Asserted at
|
||||
// this single boundary, which is what lets `IconButton` (it requires a
|
||||
// label) be composed without the view re-typing what the morfo owns.
|
||||
const mergedProps = $derived(
|
||||
mergeProps(restProps, state.props) as Record<string, unknown> & { 'aria-label': string }
|
||||
);
|
||||
</script>
|
||||
|
||||
{#if child}
|
||||
{@render child({ props: mergedProps })}
|
||||
{:else}
|
||||
<button {...mergedProps}>
|
||||
{@render children?.()}
|
||||
</button>
|
||||
{/if}
|
||||
Loading…
Reference in new issue