Step 5 — 3 packs alta-frecuencia (silencio + tap leve):
switch, toggle, toggle-group
+ tuning `form.toggle.silent: { gain: { op: 'add', value: -0.3 } }`
Step 6 — 6 packs menús + árboles (emerge.soft / form.commit.subtle):
menubar, navigation-menu, dropdown-menu, context-menu,
tree-view, tree-grid
Step 7 — card scope: KEEP `sema` + `family-default` (sin código).
Step 8 — 2 packs (versión lean tras descartar 5 prematuros):
tooltip (silent-by-default)
collapsible (mirror accordion)
+ tuning `tooltip.silent: { gain: { op: 'add', value: -0.2 } }`
Doctrina codificada en LIBRO_VARIACIONES_Y_EXTENSIONES.md:
- D.5 — packs alta frecuencia (toggles)
- D.6 — packs superficies menú / árbol
- D.7 — sonido canónico vs samples
SOUND_LIBRARY = recursos | SOUND_TUNINGS = canon | packs = composición
samples NO sustituyen firma con intent.deltas
sampleOverlay descartado permanentemente (sobreingeniería)
family signal admite excepción para marcas culturales
Cierra Lectura C steps 5-8 del audit-codex P1 #3. Total: 11 packs
nuevos sobre 9 perfiles canónicos de tuning. 195/195 tests.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
active-uix
parent
504780ad8b
commit
2d562f3788
@ -0,0 +1,41 @@
|
||||
import { semaSelector } from '$uix/morfo';
|
||||
import { collapsibleMorfo } from '$uix/morfo/components/collapsible';
|
||||
import { soundTuning } from '../sounds';
|
||||
import type { Sema } from '../sema-map';
|
||||
|
||||
/**
|
||||
* Collapsible perceptual defaults — MIRRORS ACCORDION.
|
||||
*
|
||||
* Collapsible is the single-panel sibling of Accordion (which already
|
||||
* ships a pack). Coherence demands they share the perceptual signature:
|
||||
* a user disclosing a section gets the same cue regardless of whether
|
||||
* the surface is grouped (accordion) or standalone (collapsible).
|
||||
*
|
||||
* Per `src/uix/sema/components/accordion.ts`:
|
||||
* - `expand` (emerge.open / verb=expand in our case): `emerge.soft`
|
||||
* — soft chime at gain 0.08. The family base ascending contour
|
||||
* reads as "panel reveals".
|
||||
* - `collapse` (emerge.close / verb=collapse): `emerge.exit` at
|
||||
* gain 0.06 — descending pitch, same direction discipline as the
|
||||
* rest of the system (dialog, drawer, popover, menus).
|
||||
*
|
||||
* No haptic — disclosure is a deliberate, already-acknowledged gesture
|
||||
* on a trigger button; tactile feedback on top would be noise.
|
||||
*/
|
||||
|
||||
const onContent = (matchers?: Parameters<typeof semaSelector<typeof collapsibleMorfo>>[2]) =>
|
||||
semaSelector(collapsibleMorfo, 'content', matchers);
|
||||
|
||||
export const collapsibleSema: Sema = {
|
||||
name: 'collapsible',
|
||||
cascade: [
|
||||
{
|
||||
selector: onContent({ eventName: 'expand' }),
|
||||
sound: soundTuning('emerge.soft')
|
||||
},
|
||||
{
|
||||
selector: onContent({ eventName: 'collapse' }),
|
||||
sound: soundTuning('emerge.exit', { gain: 0.06 })
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -0,0 +1,43 @@
|
||||
import { semaSelector } from '$uix/morfo';
|
||||
import { contextMenuMorfo } from '$uix/morfo/components/context-menu';
|
||||
import { soundTuning } from '../sounds';
|
||||
import type { Sema } from '../sema-map';
|
||||
|
||||
/**
|
||||
* ContextMenu perceptual defaults — SOFT EMERGE + COMMIT.
|
||||
*
|
||||
* ContextMenu shares the event surface of DropdownMenu (open / close /
|
||||
* commit-select), but the gesture is different: triggered by right-click
|
||||
* or long-press on arbitrary content rather than by a dedicated trigger
|
||||
* button. Frequency is bursty (one menu per investigative gesture) vs
|
||||
* DropdownMenu's steady traversal, but the perceptual signature stays
|
||||
* identical for system coherence — a user shouldn't have to learn two
|
||||
* different "menu sounds".
|
||||
*
|
||||
* Strategy mirrors DropdownMenu — see `dropdown-menu.ts` for the
|
||||
* doctrinal rationale.
|
||||
*/
|
||||
|
||||
const onContent = (matchers?: Parameters<typeof semaSelector<typeof contextMenuMorfo>>[2]) =>
|
||||
semaSelector(contextMenuMorfo, 'content', matchers);
|
||||
const onItem = (matchers?: Parameters<typeof semaSelector<typeof contextMenuMorfo>>[2]) =>
|
||||
semaSelector(contextMenuMorfo, 'item', matchers);
|
||||
|
||||
export const contextMenuSema: Sema = {
|
||||
name: 'context-menu',
|
||||
cascade: [
|
||||
{
|
||||
selector: onContent({ eventName: 'open' }),
|
||||
sound: soundTuning('emerge.soft')
|
||||
},
|
||||
{
|
||||
selector: onContent({ eventName: 'close' }),
|
||||
sound: soundTuning('emerge.exit.soft')
|
||||
},
|
||||
{
|
||||
selector: onItem({ eventName: 'commit-select' }),
|
||||
sound: soundTuning('form.commit.subtle'),
|
||||
haptic: { kind: 'tap', intensity: 0.3, duration: 12, delay: 0 }
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -0,0 +1,54 @@
|
||||
import { semaSelector } from '$uix/morfo';
|
||||
import { dropdownMenuMorfo } from '$uix/morfo/components/dropdown-menu';
|
||||
import { soundTuning } from '../sounds';
|
||||
import type { Sema } from '../sema-map';
|
||||
|
||||
/**
|
||||
* DropdownMenu perceptual defaults — SOFT EMERGE + COMMIT.
|
||||
*
|
||||
* DropdownMenu has three event surfaces:
|
||||
* - `open` (emerge.open on `content`) — menu reveals
|
||||
* - `close` (emerge.close on `content`) — menu retracts
|
||||
* - `commit-select` (commit.select on `item`, affirm) — user picks a
|
||||
* menu item
|
||||
*
|
||||
* Strategy (book cap. 22 §10 + cap. 26 emerge open/close discipline):
|
||||
* - OPEN: `emerge.soft` (gain 0.08). The family.emerge.base.gain is
|
||||
* 0.2 — too prominent for a menu the user opens dozens of times per
|
||||
* session. Soft chime keeps the "menu appeared" cue without fatigue.
|
||||
* - CLOSE: `emerge.exit.soft` — descending pitch (open ascends, close
|
||||
* descends — same direction discipline as Dialog / Popover) plus
|
||||
* gain 0.05. Even softer than open because closing is usually
|
||||
* immediately followed by the item-select chime OR the surface the
|
||||
* user navigated to.
|
||||
* - SELECT: `form.commit.subtle` (gain 0.03) + light `tap` haptic.
|
||||
* Softer than radio-group because the close emerge and the select
|
||||
* commit usually fire together — two signals in quick succession
|
||||
* would double-tap perceptually if both were at 0.05.
|
||||
* - The morfo event carries `intent: 'affirm'`; pack does NOT override
|
||||
* pitch / contour, so intent.deltas (capa 2) provide the positive lift.
|
||||
*/
|
||||
|
||||
const onContent = (matchers?: Parameters<typeof semaSelector<typeof dropdownMenuMorfo>>[2]) =>
|
||||
semaSelector(dropdownMenuMorfo, 'content', matchers);
|
||||
const onItem = (matchers?: Parameters<typeof semaSelector<typeof dropdownMenuMorfo>>[2]) =>
|
||||
semaSelector(dropdownMenuMorfo, 'item', matchers);
|
||||
|
||||
export const dropdownMenuSema: Sema = {
|
||||
name: 'dropdown-menu',
|
||||
cascade: [
|
||||
{
|
||||
selector: onContent({ eventName: 'open' }),
|
||||
sound: soundTuning('emerge.soft')
|
||||
},
|
||||
{
|
||||
selector: onContent({ eventName: 'close' }),
|
||||
sound: soundTuning('emerge.exit.soft')
|
||||
},
|
||||
{
|
||||
selector: onItem({ eventName: 'commit-select' }),
|
||||
sound: soundTuning('form.commit.subtle'),
|
||||
haptic: { kind: 'tap', intensity: 0.3, duration: 12, delay: 0 }
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -0,0 +1,36 @@
|
||||
import { semaSelector } from '$uix/morfo';
|
||||
import { menubarMorfo } from '$uix/morfo/components/menubar';
|
||||
import { soundTuning } from '../sounds';
|
||||
import type { Sema } from '../sema-map';
|
||||
|
||||
/**
|
||||
* Menubar perceptual defaults — SOFT COMMIT + TAP HAPTIC.
|
||||
*
|
||||
* Menubar declares a single `commit-select` on its top-level trigger.
|
||||
* The actual menu content lives in a sibling DropdownMenu / ContextMenu
|
||||
* (each with its own pack); Menubar only carries the act of "this top
|
||||
* trigger is now active". Same frequency profile as a toolbar.
|
||||
*
|
||||
* Strategy (book cap. 22 §10 — baja intensidad):
|
||||
* - SOUND: `form.commit.subtle` (gain 0.03). Triggers fire as the user
|
||||
* scrubs across the menubar — softer than radio-group / checkbox to
|
||||
* avoid fatigue during multi-trigger traversal.
|
||||
* - HAPTIC: light `tap` (intensity 0.3, duration 12). Same family as
|
||||
* toggles — sober, frequency-tolerant.
|
||||
* - The intent on the morfo event is `affirm`; pitch lift comes from
|
||||
* the intent.deltas (capa 2). Pack does NOT override pitch / contour.
|
||||
*/
|
||||
|
||||
const onTrigger = (matchers?: Parameters<typeof semaSelector<typeof menubarMorfo>>[2]) =>
|
||||
semaSelector(menubarMorfo, 'trigger', matchers);
|
||||
|
||||
export const menubarSema: Sema = {
|
||||
name: 'menubar',
|
||||
cascade: [
|
||||
{
|
||||
selector: onTrigger({ eventName: 'commit-select' }),
|
||||
sound: soundTuning('form.commit.subtle'),
|
||||
haptic: { kind: 'tap', intensity: 0.3, duration: 12, delay: 0 }
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -0,0 +1,35 @@
|
||||
import { semaSelector } from '$uix/morfo';
|
||||
import { navigationMenuMorfo } from '$uix/morfo/components/navigation-menu';
|
||||
import { soundTuning } from '../sounds';
|
||||
import type { Sema } from '../sema-map';
|
||||
|
||||
/**
|
||||
* NavigationMenu perceptual defaults — SOFT COMMIT + TAP HAPTIC.
|
||||
*
|
||||
* NavigationMenu emits `commit-select` per item (link or trigger).
|
||||
* Browsing a navigation bar is high-frequency, low-intensity — same
|
||||
* fatigue profile as Menubar.
|
||||
*
|
||||
* Strategy (book cap. 22 §10):
|
||||
* - SOUND: `form.commit.subtle` (gain 0.03). Selecting a nav link is
|
||||
* usually followed by a route change / focus shift, so the chime
|
||||
* must not compete with the next surface's signals.
|
||||
* - HAPTIC: light `tap`. Confirms the click landed.
|
||||
* - The morfo event carries `intent: 'affirm'`; the pack does NOT
|
||||
* override pitch / contour — intent.deltas (capa 2) supply the
|
||||
* positive lift.
|
||||
*/
|
||||
|
||||
const onItem = (matchers?: Parameters<typeof semaSelector<typeof navigationMenuMorfo>>[2]) =>
|
||||
semaSelector(navigationMenuMorfo, 'item', matchers);
|
||||
|
||||
export const navigationMenuSema: Sema = {
|
||||
name: 'navigation-menu',
|
||||
cascade: [
|
||||
{
|
||||
selector: onItem({ eventName: 'commit-select' }),
|
||||
sound: soundTuning('form.commit.subtle'),
|
||||
haptic: { kind: 'tap', intensity: 0.3, duration: 12, delay: 0 }
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -0,0 +1,40 @@
|
||||
import { semaSelector } from '$uix/morfo';
|
||||
import { switchMorfo } from '$uix/morfo/components/switch';
|
||||
import { soundTuning } from '../sounds';
|
||||
import type { Sema } from '../sema-map';
|
||||
|
||||
/**
|
||||
* Switch perceptual defaults — SILENT-BY-DEFAULT + LIGHT HAPTIC.
|
||||
*
|
||||
* Switches are high-frequency form controls (settings panels, preference
|
||||
* trays). Fatigue is the dominant risk: a sober signature lets the user
|
||||
* flip a dozen toggles without auditory noise. Book cap. 22 §10 maps a
|
||||
* single `commit.toggle` verb to both directions; the intent prop carries
|
||||
* the evaluative load.
|
||||
*
|
||||
* Strategy (per author directive 2026-05-26):
|
||||
* - SOUND: `form.toggle.silent` subtracts the family.commit gain (0.3),
|
||||
* so neutral/affirm/risk land silent. Threat (+0.1 from intent.delta)
|
||||
* still surfaces, so destructive toggles emit a cue. Pitch / contour
|
||||
* differentiation stays computed but inaudible when gain is 0.
|
||||
* - HAPTIC: light `tap` (intensity 0.3 vs family's 0.5, duration 12 vs
|
||||
* 20, no delay). Replaces the intent-driven `kind` so toggles always
|
||||
* feel like a tap — keeping the gesture intelligible without
|
||||
* amplifying frequency. Intent loading lives in `data-color` + (for
|
||||
* threat only) the audible sound surface.
|
||||
* - Motion lives in eidos recipes; not part of this pack.
|
||||
*/
|
||||
|
||||
const onProvider = (matchers?: Parameters<typeof semaSelector<typeof switchMorfo>>[2]) =>
|
||||
semaSelector(switchMorfo, 'provider', matchers);
|
||||
|
||||
export const switchSema: Sema = {
|
||||
name: 'switch',
|
||||
cascade: [
|
||||
{
|
||||
selector: onProvider({ eventName: 'commit-toggle' }),
|
||||
sound: soundTuning('form.toggle.silent'),
|
||||
haptic: { kind: 'tap', intensity: 0.3, duration: 12, delay: 0 }
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -0,0 +1,32 @@
|
||||
import { semaSelector } from '$uix/morfo';
|
||||
import { toggleGroupMorfo } from '$uix/morfo/components/toggle-group';
|
||||
import { soundTuning } from '../sounds';
|
||||
import type { Sema } from '../sema-map';
|
||||
|
||||
/**
|
||||
* ToggleGroup perceptual defaults — SILENT-BY-DEFAULT + LIGHT HAPTIC.
|
||||
*
|
||||
* ToggleGroup composes N toggles under one provider (segmented controls,
|
||||
* formatter ribbons, filter chips). Fatigue compounds with each
|
||||
* additional item, so the sober signature is even more important here
|
||||
* than for a lone Switch / Toggle. Each item emits `commit-toggle`
|
||||
* targeting the `item` part.
|
||||
*
|
||||
* Strategy mirrors Switch / Toggle — silent by default, light tap haptic.
|
||||
* The pack targets `item` (not provider) so the cascade matches the
|
||||
* actual element that carries the `data-event-*` stamp.
|
||||
*/
|
||||
|
||||
const onItem = (matchers?: Parameters<typeof semaSelector<typeof toggleGroupMorfo>>[2]) =>
|
||||
semaSelector(toggleGroupMorfo, 'item', matchers);
|
||||
|
||||
export const toggleGroupSema: Sema = {
|
||||
name: 'toggle-group',
|
||||
cascade: [
|
||||
{
|
||||
selector: onItem({ eventName: 'commit-toggle' }),
|
||||
sound: soundTuning('form.toggle.silent'),
|
||||
haptic: { kind: 'tap', intensity: 0.3, duration: 12, delay: 0 }
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -0,0 +1,32 @@
|
||||
import { semaSelector } from '$uix/morfo';
|
||||
import { toggleMorfo } from '$uix/morfo/components/toggle';
|
||||
import { soundTuning } from '../sounds';
|
||||
import type { Sema } from '../sema-map';
|
||||
|
||||
/**
|
||||
* Toggle perceptual defaults — SILENT-BY-DEFAULT + LIGHT HAPTIC.
|
||||
*
|
||||
* Toggles are single-button two-state controls (toolbar pressed-states,
|
||||
* inline filters). Same fatigue profile as Switch and Checkbox: dozens of
|
||||
* presses in seconds during a typical edit session. Book cap. 22 §10
|
||||
* declares a single `commit.toggle` verb for both directions; intent
|
||||
* carries evaluative weight.
|
||||
*
|
||||
* Strategy mirrors Switch — see `switch.ts` for the doctrinal rationale.
|
||||
* Toggle and Switch share the same perceptual signature because they
|
||||
* share the same UX role at the gesture layer (one press, one flip).
|
||||
*/
|
||||
|
||||
const onProvider = (matchers?: Parameters<typeof semaSelector<typeof toggleMorfo>>[2]) =>
|
||||
semaSelector(toggleMorfo, 'provider', matchers);
|
||||
|
||||
export const toggleSema: Sema = {
|
||||
name: 'toggle',
|
||||
cascade: [
|
||||
{
|
||||
selector: onProvider({ eventName: 'commit-toggle' }),
|
||||
sound: soundTuning('form.toggle.silent'),
|
||||
haptic: { kind: 'tap', intensity: 0.3, duration: 12, delay: 0 }
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -0,0 +1,46 @@
|
||||
import { semaSelector } from '$uix/morfo';
|
||||
import { tooltipMorfo } from '$uix/morfo/components/tooltip';
|
||||
import { soundTuning } from '../sounds';
|
||||
import type { Sema } from '../sema-map';
|
||||
|
||||
/**
|
||||
* Tooltip perceptual defaults — SILENT-BY-DEFAULT.
|
||||
*
|
||||
* Tooltips reveal on hover or focus. Hovering is a continuous, ambient
|
||||
* gesture: cursor crosses the trigger and the tooltip pops. If the
|
||||
* framework shipped audible defaults here, every cursor sweep across a
|
||||
* dense UI would "puff" emerge.base sounds — fatigue is immediate.
|
||||
*
|
||||
* Doctrinal (`LIBRO_VARIACIONES_Y_EXTENSIONES.md` D.7):
|
||||
* - Tooltip is auxiliary presence, not signal.
|
||||
* - Silence is a valid canonical signature.
|
||||
*
|
||||
* Strategy:
|
||||
* - `open` / `close` / `close-dismiss` (all emerge family on content):
|
||||
* all routed through `tooltip.silent`. That tuning subtracts the
|
||||
* family.emerge.base.gain (0.2), so the final gain is 0 for
|
||||
* neutral/affirm/risk/loss. Intent threat (+0.1) and fulfill (+0.05)
|
||||
* still surface — a tooltip used to convey an error or success
|
||||
* hint can still be heard if the consumer sets `intent`.
|
||||
* - NO haptic. Hover is not a tactile gesture; tactile feedback on
|
||||
* hover would be perceptually wrong.
|
||||
* - NO pack on `Trigger` — the trigger does not emit semantic
|
||||
* events; only `Content` participates in sema.
|
||||
*
|
||||
* Override path for themes: app cascade rule
|
||||
* `[data-tooltip-content] { sound: { gain: 0.05 } }` resurrects an
|
||||
* audible signature. The default ships silent.
|
||||
*/
|
||||
|
||||
const onContent = (matchers?: Parameters<typeof semaSelector<typeof tooltipMorfo>>[2]) =>
|
||||
semaSelector(tooltipMorfo, 'content', matchers);
|
||||
|
||||
export const tooltipSema: Sema = {
|
||||
name: 'tooltip',
|
||||
cascade: [
|
||||
{
|
||||
selector: onContent({ eventFamily: 'emerge' }),
|
||||
sound: soundTuning('tooltip.silent')
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -0,0 +1,39 @@
|
||||
import { semaSelector } from '$uix/morfo';
|
||||
import { treeGridMorfo } from '$uix/morfo/components/tree-grid';
|
||||
import { soundTuning } from '../sounds';
|
||||
import type { Sema } from '../sema-map';
|
||||
|
||||
/**
|
||||
* TreeGrid perceptual defaults — SOFT EMERGE + COMMIT.
|
||||
*
|
||||
* TreeGrid composes TreeView's expand/collapse with Table's row
|
||||
* structure. Three event surfaces, all targeting the `row` part:
|
||||
* - `commit-select` (commit.select, affirm) — row selected
|
||||
* - `emerge-expand` (emerge.expand) — row reveals child rows
|
||||
* - `emerge-collapse` (emerge.collapse) — row hides children
|
||||
*
|
||||
* Strategy mirrors TreeView — same frequency / fatigue profile, just on
|
||||
* a tabular layout. See `tree-view.ts` for the doctrinal rationale.
|
||||
*/
|
||||
|
||||
const onRow = (matchers?: Parameters<typeof semaSelector<typeof treeGridMorfo>>[2]) =>
|
||||
semaSelector(treeGridMorfo, 'row', matchers);
|
||||
|
||||
export const treeGridSema: Sema = {
|
||||
name: 'tree-grid',
|
||||
cascade: [
|
||||
{
|
||||
selector: onRow({ eventName: 'emerge-expand' }),
|
||||
sound: soundTuning('emerge.soft')
|
||||
},
|
||||
{
|
||||
selector: onRow({ eventName: 'emerge-collapse' }),
|
||||
sound: soundTuning('emerge.exit.soft')
|
||||
},
|
||||
{
|
||||
selector: onRow({ eventName: 'commit-select' }),
|
||||
sound: soundTuning('form.commit.subtle'),
|
||||
haptic: { kind: 'tap', intensity: 0.3, duration: 12, delay: 0 }
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -0,0 +1,53 @@
|
||||
import { semaSelector } from '$uix/morfo';
|
||||
import { treeViewMorfo } from '$uix/morfo/components/tree-view';
|
||||
import { soundTuning } from '../sounds';
|
||||
import type { Sema } from '../sema-map';
|
||||
|
||||
/**
|
||||
* TreeView perceptual defaults — SOFT EMERGE + COMMIT.
|
||||
*
|
||||
* TreeView has three event surfaces, all targeting the `item` part:
|
||||
* - `commit-select` (commit.select, affirm) — leaf or branch selected
|
||||
* - `emerge-expand` (emerge.expand) — branch reveals children
|
||||
* - `emerge-collapse` (emerge.collapse) — branch hides children
|
||||
*
|
||||
* Strategy (book cap. 22 §10 + cap. 26 emerge open/close discipline):
|
||||
* - EXPAND: `emerge.soft` (gain 0.08) — content reveals, ascending
|
||||
* family base. Same character as Accordion expand.
|
||||
* - COLLAPSE: `emerge.exit.soft` — descending pitch + gain 0.05,
|
||||
* same direction discipline as menus / dialogs.
|
||||
* - SELECT: `form.commit.subtle` + light `tap`. Soft because tree
|
||||
* exploration is often paired with a focus change (the leaf
|
||||
* content surfaces elsewhere), and the select chime mustn't
|
||||
* compete with that downstream signal.
|
||||
*
|
||||
* Note on target: morfo declares all three events targeting `item`
|
||||
* (leaves). Branches also have role="treeitem" but a different part
|
||||
* marker (`data-tree-view-branch`). If branches end up emitting at
|
||||
* runtime without the `data-tree-view-item` marker, this cascade will
|
||||
* miss them — a known concern noted in the morfo declaration audit.
|
||||
* The pack follows the morfo declaration verbatim; any mismatch is a
|
||||
* morfo-level fix outside this pack's scope.
|
||||
*/
|
||||
|
||||
const onItem = (matchers?: Parameters<typeof semaSelector<typeof treeViewMorfo>>[2]) =>
|
||||
semaSelector(treeViewMorfo, 'item', matchers);
|
||||
|
||||
export const treeViewSema: Sema = {
|
||||
name: 'tree-view',
|
||||
cascade: [
|
||||
{
|
||||
selector: onItem({ eventName: 'emerge-expand' }),
|
||||
sound: soundTuning('emerge.soft')
|
||||
},
|
||||
{
|
||||
selector: onItem({ eventName: 'emerge-collapse' }),
|
||||
sound: soundTuning('emerge.exit.soft')
|
||||
},
|
||||
{
|
||||
selector: onItem({ eventName: 'commit-select' }),
|
||||
sound: soundTuning('form.commit.subtle'),
|
||||
haptic: { kind: 'tap', intensity: 0.3, duration: 12, delay: 0 }
|
||||
}
|
||||
]
|
||||
};
|
||||
Loading…
Reference in new issue