@antadesign/anta 0.3.10 → 0.3.12

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 (37) hide show
  1. package/dist/components/Button.d.ts +4 -46
  2. package/dist/components/Button.js +7 -25
  3. package/dist/components/ButtonCopy.d.ts +45 -21
  4. package/dist/components/ButtonCopy.js +46 -4
  5. package/dist/components/Expander.js +1 -1
  6. package/dist/components/MenuItem.d.ts +2 -8
  7. package/dist/components/MenuItem.js +2 -14
  8. package/dist/components/MenuItemCopy.d.ts +23 -19
  9. package/dist/components/MenuItemCopy.js +38 -3
  10. package/dist/components/Select.d.ts +8 -0
  11. package/dist/components/Select.js +4 -0
  12. package/dist/components/SelectFaceted.d.ts +8 -0
  13. package/dist/components/SelectFaceted.js +4 -0
  14. package/dist/components/copy-props.d.ts +72 -0
  15. package/dist/components/copy-props.js +20 -0
  16. package/dist/elements/a-button.css +1 -1
  17. package/dist/elements/a-button.d.ts +0 -4
  18. package/dist/elements/a-button.js +7 -20
  19. package/dist/elements/a-copy.css +1 -0
  20. package/dist/elements/a-copy.d.ts +16 -0
  21. package/dist/elements/a-copy.js +148 -0
  22. package/dist/elements/a-expander.css +1 -1
  23. package/dist/elements/a-expander.js +20 -19
  24. package/dist/elements/a-menu-item.d.ts +8 -1
  25. package/dist/elements/a-menu-item.js +7 -11
  26. package/dist/elements/a-menu.d.ts +6 -2
  27. package/dist/elements/a-menu.js +35 -5
  28. package/dist/elements/copy-behavior.d.ts +31 -13
  29. package/dist/elements/copy-behavior.js +20 -18
  30. package/dist/elements/index.d.ts +1 -0
  31. package/dist/elements/index.js +3 -0
  32. package/dist/elements/key-activation.d.ts +28 -0
  33. package/dist/elements/key-activation.js +32 -0
  34. package/dist/general_types.d.ts +27 -37
  35. package/dist/index.d.ts +2 -1
  36. package/dist/jsx-runtime.d.ts +2 -1
  37. package/package.json +1 -1
@@ -1 +1 @@
1
- @layer anta{a-button,a[role=button][data-anta],button[data-anta]{--button-primary-fg: #ffffff;--bg-primary-disabled: #ece9ec;--bg-secondary-disabled: #f6f4f6;--fg-disabled-primary: #afa9b1;--fg-disabled: #afa9b1;--button-loading-stripe: 14px;--button-loading-stripe-gap: 16px;--button-loading-period: 30px;--button-loading-angle: 125deg;--button-loading-x-period: calc( var(--button-loading-period) / cos(var(--button-loading-angle) - 90deg) );--button-loading-opacity: .15;--button-loading-blur: 2.5px;--button-bg-primary-rest: #635b65;--button-bg-primary-hover: #534c57;--button-bg-primary-active: #49424c;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #45374c12;--button-bg-secondary-hover: #44374b1a;--button-bg-secondary-active: #44374b26;--button-fg-secondary-rest: #534c57;--button-fg-secondary-hover: #49424c;--button-fg-secondary-l-shift: .05;--button-fg-tertiary-rest: #635b65;--button-fg-tertiary-hover: #534c57;--button-bg-tertiary-hover: #44374b0d;--button-bg-tertiary-active: #44374b1a;--button-fg-quaternary-rest: #635b65;--button-fg-quaternary-hover: #49424c;--_fs: 15px;--_lh: 20px;--_pb: 1px;--button-padding-x: 9px;--button-padding-y: calc((8px - var(--_pb)) / 2);--button-timing-in: 75ms ease-in;--button-timing-active: 50ms linear;--button-timing-out: .15s ease-out;--button-loading-duration: .5s}a-button[round],a[role=button][data-anta][round],button[data-anta][round]{--button-round: attr(round type(<length>), 999px);border-radius:var(--button-round, 999px)}a-button[tone=brand],a[role=button][data-anta][tone=brand],button[data-anta][tone=brand]{--button-bg-primary-rest: #5f4bc3;--button-bg-primary-hover: #503cb4;--button-bg-primary-active: #483493;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #7460d71a;--button-bg-secondary-hover: #7460d726;--button-bg-secondary-active: #7460d733;--button-fg-secondary-rest: #5f4bc3;--button-fg-secondary-hover: #503cb4;--button-fg-tertiary-rest: #5f4bc3;--button-fg-tertiary-hover: #503cb4;--button-bg-tertiary-hover: #7460d71a;--button-bg-tertiary-active: #7460d726;--button-fg-quaternary-rest: #5f4bc3;--button-fg-quaternary-hover: #483493}a-button[tone=critical],a[role=button][data-anta][tone=critical],button[data-anta][tone=critical]{--button-bg-primary-rest: #c9302c;--button-bg-primary-hover: #b02120;--button-bg-primary-active: #a01c1c;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #de45451a;--button-bg-secondary-hover: #de454526;--button-bg-secondary-active: #de454533;--button-fg-secondary-rest: #c9302c;--button-fg-secondary-hover: #b02120;--button-fg-tertiary-rest: #c9302c;--button-fg-tertiary-hover: #b02120;--button-bg-tertiary-hover: #de45451a;--button-bg-tertiary-active: #de454533;--button-fg-quaternary-rest: #c9302c;--button-fg-quaternary-hover: #a01c1c}a-button[tone=info],a[role=button][data-anta][tone=info],button[data-anta][tone=info]{--button-bg-primary-rest: #1f6eb2;--button-bg-primary-hover: #1a5b93;--button-bg-primary-active: #175082;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #2686d91a;--button-bg-secondary-hover: #2686d926;--button-bg-secondary-active: #2686d933;--button-fg-secondary-rest: #1f6eb2;--button-fg-secondary-hover: #1a5b93;--button-fg-tertiary-rest: #1f6eb2;--button-fg-tertiary-hover: #1a5b93;--button-bg-tertiary-hover: #2686d91a;--button-bg-tertiary-active: #2686d926;--button-fg-quaternary-rest: #1f6eb2;--button-fg-quaternary-hover: #175082}a-button[tone=success],a[role=button][data-anta][tone=success],button[data-anta][tone=success]{--button-bg-primary-rest: #2a7e43;--button-bg-primary-hover: #226737;--button-bg-primary-active: #1f5c31;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #3295501a;--button-bg-secondary-hover: #32955026;--button-bg-secondary-active: #32955033;--button-fg-secondary-rest: #2a7e43;--button-fg-secondary-hover: #226737;--button-fg-tertiary-rest: #2a7e43;--button-fg-tertiary-hover: #226737;--button-bg-tertiary-hover: #3295501a;--button-bg-tertiary-active: #32955026;--button-fg-quaternary-rest: #2a7e43;--button-fg-quaternary-hover: #1f5c31}a-button[tone=warning],a[role=button][data-anta][tone=warning],button[data-anta][tone=warning]{--button-bg-primary-rest: #c37416;--button-bg-primary-hover: #ae6613;--button-bg-primary-active: #995200;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #c374161a;--button-bg-secondary-hover: #c3741626;--button-bg-secondary-active: #c3741633;--button-fg-secondary-rest: #c37416;--button-fg-secondary-hover: #ae6613;--button-fg-tertiary-rest: #c37416;--button-fg-tertiary-hover: #ae6613;--button-bg-tertiary-hover: #c374161a;--button-bg-tertiary-active: #c3741633;--button-fg-quaternary-rest: #c37416;--button-fg-quaternary-hover: #995200}.dark a-button,.dark a[role=button][data-anta],.dark button[data-anta]{--bg-primary-disabled: #272329;--bg-secondary-disabled: #1d1a1e;--fg-disabled-primary: #776e77;--fg-disabled: #635b65;--button-bg-primary-rest: #534c57;--button-bg-primary-hover: #635b65;--button-bg-primary-active: #938d96;--button-bg-secondary-rest: #e4d1ef1c;--button-bg-secondary-hover: #e4d1ef24;--button-bg-secondary-active: #e4d1ef2e;--button-fg-secondary-rest: #c1b9c1;--button-fg-secondary-hover: #d4ced4;--button-fg-secondary-l-shift: 0;--button-fg-tertiary-rest: #afa9b1;--button-fg-tertiary-hover: #afa9b1;--button-bg-tertiary-hover: #e4d1ef14;--button-bg-tertiary-active: #e4d1ef21;--button-fg-quaternary-rest: #afa9b1;--button-fg-quaternary-hover: #cac4ca}.dark a-button[tone=brand],.dark a[role=button][data-anta][tone=brand],.dark button[data-anta][tone=brand]{--button-bg-primary-rest: #503cb4;--button-bg-primary-hover: #5f4bc3;--button-bg-primary-active: #7460d7;--button-bg-secondary-rest: #7460d73b;--button-bg-secondary-hover: #7460d747;--button-bg-secondary-active: #7460d754;--button-fg-secondary-rest: #c5baff;--button-fg-secondary-hover: #d2cbf6;--button-fg-tertiary-rest: #ada0ee;--button-fg-tertiary-hover: #bcb1f1;--button-bg-tertiary-hover: #7460d73b;--button-bg-tertiary-active: #7460d747;--button-fg-quaternary-rest: #ada0ee;--button-fg-quaternary-hover: #c7bef4}.dark a-button[tone=critical],.dark a[role=button][data-anta][tone=critical],.dark button[data-anta][tone=critical]{--button-bg-primary-rest: #b02120;--button-bg-primary-hover: #c9302c;--button-bg-primary-active: #de4545;--button-bg-secondary-rest: #de45453b;--button-bg-secondary-hover: #de454547;--button-bg-secondary-active: #de454554;--button-fg-secondary-rest: #ffabac;--button-fg-secondary-hover: #f4c2c2;--button-fg-tertiary-rest: #e78e90;--button-fg-tertiary-hover: #efa4a4;--button-bg-tertiary-hover: #de45453b;--button-bg-tertiary-active: #de454547;--button-fg-quaternary-rest: #e78e90;--button-fg-quaternary-hover: #ffabac}.dark a-button[tone=info],.dark a[role=button][data-anta][tone=info],.dark button[data-anta][tone=info]{--button-bg-primary-rest: #1a5b93;--button-bg-primary-hover: #1f6eb2;--button-bg-primary-active: #2686d9;--button-bg-secondary-rest: #2686d93b;--button-bg-secondary-hover: #2686d947;--button-bg-secondary-active: #2686d954;--button-fg-secondary-rest: #9ed2ff;--button-fg-secondary-hover: #bad6f3;--button-fg-tertiary-rest: #7db6e8;--button-fg-tertiary-hover: #93c5ec;--button-bg-tertiary-hover: #2686d93b;--button-bg-tertiary-active: #2686d947;--button-fg-quaternary-rest: #7db6e8;--button-fg-quaternary-hover: #a6cdef}.dark a-button[tone=success],.dark a[role=button][data-anta][tone=success],.dark button[data-anta][tone=success]{--button-bg-primary-rest: #226737;--button-bg-primary-hover: #2a7e43;--button-bg-primary-active: #329550;--button-bg-secondary-rest: #3295503b;--button-bg-secondary-hover: #32955047;--button-bg-secondary-active: #32955054;--button-fg-secondary-rest: #8ceca9;--button-fg-secondary-hover: #b3e5c2;--button-fg-tertiary-rest: #74cd8e;--button-fg-tertiary-hover: #88d7a0;--button-bg-tertiary-hover: #3295503b;--button-bg-tertiary-active: #32955047;--button-fg-quaternary-rest: #74cd8e;--button-fg-quaternary-hover: #9ddeb1}.dark a-button[tone=warning],.dark a[role=button][data-anta][tone=warning],.dark button[data-anta][tone=warning]{--button-bg-primary-rest: #7f410b;--button-bg-primary-hover: #995200;--button-bg-primary-active: #ae6613;--button-bg-secondary-rest: #c374163b;--button-bg-secondary-hover: #c3741647;--button-bg-secondary-active: #c3741654;--button-fg-secondary-rest: #f7c06e;--button-fg-secondary-hover: #f3cc91;--button-fg-tertiary-rest: #e1a452;--button-fg-tertiary-hover: #edb25a;--button-bg-tertiary-hover: #c374163b;--button-bg-tertiary-active: #c3741647;--button-fg-quaternary-rest: #e1a452;--button-fg-quaternary-hover: #f0bf75}button[data-anta]{box-sizing:border-box;margin:0;appearance:none;-webkit-appearance:none;border:none}a-button,a[role=button][data-anta],button[data-anta]{user-select:none;display:inline-flex;align-items:center;gap:.5ch;overflow:hidden;cursor:pointer;flex-shrink:0;color:var(--button-fg);background-color:var(--button-bg);border-radius:4px;text-decoration:none;box-shadow:inset 0 0 1px color-mix(in oklch,currentColor,transparent 90%);font-size:var(--_fs);font-family:var(--sans-serif);font-weight:450;font-variation-settings:"wdth" 88,"slnt" 0,"ital" 0;font-feature-settings:"ss02","ss05","tnum";line-height:var(--_lh);letter-spacing:.05ch;text-overflow:ellipsis;text-wrap:nowrap;white-space:nowrap;max-width:100%;padding-inline:var(--button-padding-x);padding-block:var(--button-padding-y);min-height:28px;>a-button-label{display:inline-block;text-overflow:ellipsis;text-wrap:nowrap;white-space:nowrap;overflow:hidden;min-width:0;line-height:var(--_lh);padding-bottom:var(--_pb);&:has(>*){display:inline-flex;gap:.25ch}}>*{pointer-events:none}& a-icon{transition:color var(--button-timing-out)}transition:color var(--button-timing-out),background-color var(--button-timing-out);&:hover,&:focus-visible{transition:color var(--button-timing-in),background-color var(--button-timing-in);& a-icon{transition:color var(--button-timing-in)}}&:active,&[selected]{transition:color var(--button-timing-active),background-color var(--button-timing-active);& a-icon{transition:color var(--button-timing-active)}}&[disabled]{pointer-events:none;cursor:not-allowed;transition:none;& a-icon{transition:none}}&:focus-visible{outline:1px solid var(--focus-ring);outline-offset:1px}&[priority=quaternary]{--button-timing-in: 0s;--button-timing-active: 0s;--button-timing-out: 0s}&[size=small]{--button-padding-x: 7px;--_fs: 13px;--_lh: 16px;--_pb: .5px;min-height:24px;& a-icon{--icon-size: 14px}}&[size=large]{--button-padding-x: 13px;--_fs: 17px;--_lh: 24px;--_pb: 1.5px;min-height:32px;& a-icon{--icon-size: 18px}}&[priority=tertiary],&[priority=quaternary]{&[underline=solid]{text-decoration:underline solid}&[underline=dashed]{text-decoration:underline dashed}&[underline=dotted]{text-decoration:underline dotted}&[underline]{text-decoration-color:color-mix(in srgb,currentColor 75%,transparent);text-decoration-thickness:1px;text-underline-offset:3px;&[selected]{text-decoration-color:var(--button-fg);text-decoration-thickness:1px}@media(hover:hover)and (pointer:fine){&:hover{text-decoration-color:var(--button-fg);text-decoration-thickness:1px}}}}&[priority=quaternary][paddingless]{--button-padding-x: 0;--button-padding-y: 0;min-height:0}&:has(>a-icon):not(:has(>a-icon~a-icon)):not(:has(>:not(a-icon):not(a-tooltip))){--button-padding-y: 5px;--button-padding-x: 5px;min-width:28px;justify-content:center;&[size=small]{--button-padding-y: 3px;--button-padding-x: 3px;min-width:24px}&[size=large]{--button-padding-y: 7px;--button-padding-x: 7px;min-width:32px}}&:is(:has(>a-icon:first-child),:has(>a-tooltip:first-child+a-icon)):is(:has(>a-icon~a-icon),:has(>:not(a-icon):not(a-tooltip))){padding-inline-start:max(0px,var(--button-padding-x) - 2px)}&:is(:has(>a-icon:last-child),:has(>a-icon+a-tooltip:last-child)):is(:has(>a-icon~a-icon),:has(>:not(a-icon):not(a-tooltip))){padding-inline-end:max(0px,var(--button-padding-x) - 2px)}&[loading]{position:relative;pointer-events:none;cursor:wait;&:before{content:"";position:absolute;top:0;bottom:0;left:calc(0px - var(--button-loading-x-period));right:0;pointer-events:none;background:repeating-linear-gradient(var(--button-loading-angle),transparent 0,transparent var(--button-loading-stripe-gap),currentColor var(--button-loading-stripe-gap),currentColor calc(var(--button-loading-stripe-gap) + var(--button-loading-stripe)));opacity:var(--button-loading-opacity);filter:blur(var(--button-loading-blur));will-change:transform;animation:btn-loading-slide var(--button-loading-duration) linear infinite;animation-delay:-9999s}}&[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=critical],[tone=info],[tone=success],[tone=warning]){--button-tone-source: attr(tone type(<color>), transparent);--_tone-fg-l: .46;--_tone-fg-strong-l: .4;--_tone-fg-c: .17;--_tone-bg-l: .54;--_tone-bg-c: .16;--_tone-bg-a-rest: .1;--_tone-bg-a-hover: .15;--_tone-bg-a-active: .2;--_tone-primary-l-rest: .5;--_tone-primary-l-hover: .45;--_tone-primary-l-active: .4;--button-bg-primary-rest: oklch(from var(--button-tone-source) var(--_tone-primary-l-rest) c h);--button-bg-primary-hover: oklch(from var(--button-tone-source) var(--_tone-primary-l-hover) c h);--button-bg-primary-active: oklch(from var(--button-tone-source) var(--_tone-primary-l-active) c h);--button-fg-primary-rest: var(--button-primary-fg);--button-fg-secondary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-secondary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-fg-tertiary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-tertiary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-fg-quaternary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-quaternary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-bg-secondary-rest: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-rest));--button-bg-secondary-hover: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-hover));--button-bg-secondary-active: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-active));--button-bg-tertiary-hover: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-rest));--button-bg-tertiary-active: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-hover))}.dark &[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=critical],[tone=info],[tone=success],[tone=warning]){--_tone-fg-l: .78;--_tone-fg-strong-l: .85;--_tone-fg-c: .11;--_tone-bg-l: .58;--_tone-bg-a-rest: .23;--_tone-bg-a-hover: .28;--_tone-bg-a-active: .33;--_tone-primary-l-rest: .45;--_tone-primary-l-hover: .5;--_tone-primary-l-active: .57}--button-fg: oklch(from var(--button-fg-secondary-rest) calc(l - var(--button-fg-secondary-l-shift)) c h);--button-bg: var(--button-bg-secondary-rest);@media(hover:hover)and (pointer:fine){&:hover{--button-fg: var(--button-fg-secondary-hover);--button-bg: var(--button-bg-secondary-hover)}}&:active{--button-fg: var(--button-fg-secondary-hover);--button-bg: var(--button-bg-secondary-active)}&[selected]{--button-fg: var(--button-fg-secondary-hover);--button-bg: var(--button-bg-secondary-hover)}&[priority=primary]{--button-fg: var(--button-fg-primary-rest);--button-bg: var(--button-bg-primary-rest);box-shadow:none;@media(hover:hover)and (pointer:fine){&:hover{--button-bg: var(--button-bg-primary-hover)}}&:active{--button-bg: var(--button-bg-primary-active)}&[selected]{--button-bg: var(--button-bg-primary-hover)}}&[priority=tertiary]{--button-fg: var(--button-fg-tertiary-rest);--button-bg: transparent;box-shadow:none;@media(hover:hover)and (pointer:fine){&:hover{--button-fg: var(--button-fg-tertiary-hover);--button-bg: var(--button-bg-tertiary-hover)}}&:active{--button-fg: var(--button-fg-tertiary-hover);--button-bg: var(--button-bg-tertiary-active)}&[selected]{--button-fg: var(--button-fg-tertiary-hover);--button-bg: var(--button-bg-tertiary-hover)}}&[priority=quaternary]{--button-fg: var(--button-fg-quaternary-rest);--button-bg: transparent;box-shadow:none;font-weight:400;letter-spacing:.06ch;@media(hover:hover)and (pointer:fine){&:hover{--button-fg: var(--button-fg-quaternary-hover)}}&[selected]{--button-fg: var(--button-fg-quaternary-hover)}&:active{--button-fg: oklch(from var(--button-fg-quaternary-rest) calc(l + .05) c h)}.dark &:active{--button-fg: var(--button-fg-quaternary-rest)}}&[selected]{box-shadow:inset 0 0 0 .5px currentColor}&[disabled]{background-color:var(--bg-secondary-disabled);color:var(--fg-disabled);&[priority=primary]{background-color:var(--bg-primary-disabled);color:var(--fg-disabled-primary)}&[priority=tertiary],&[priority=quaternary]{background-color:transparent;color:var(--fg-disabled)}}}}@keyframes btn-loading-slide{to{transform:translate(var(--button-loading-x-period))}}
1
+ @layer anta{a-button,a[role=button][data-anta],button[data-anta]{--button-primary-fg: #ffffff;--bg-primary-disabled: #ece9ec;--bg-secondary-disabled: #f6f4f6;--fg-disabled-primary: #afa9b1;--fg-disabled: #afa9b1;--button-loading-stripe: 14px;--button-loading-stripe-gap: 16px;--button-loading-period: 30px;--button-loading-angle: 125deg;--button-loading-x-period: calc( var(--button-loading-period) / cos(var(--button-loading-angle) - 90deg) );--button-loading-opacity: .15;--button-loading-blur: 2.5px;--button-bg-primary-rest: #635b65;--button-bg-primary-hover: #534c57;--button-bg-primary-active: #49424c;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #45374c12;--button-bg-secondary-hover: #44374b1a;--button-bg-secondary-active: #44374b26;--button-fg-secondary-rest: #534c57;--button-fg-secondary-hover: #49424c;--button-fg-secondary-l-shift: .05;--button-fg-tertiary-rest: #635b65;--button-fg-tertiary-hover: #534c57;--button-bg-tertiary-hover: #44374b0d;--button-bg-tertiary-active: #44374b1a;--button-fg-quaternary-rest: #635b65;--button-fg-quaternary-hover: #49424c;--_fs: 15px;--_lh: 20px;--_pb: 1px;--button-padding-x: 9px;--button-padding-y: calc((8px - var(--_pb)) / 2);--button-timing-in: 75ms ease-in;--button-timing-active: 50ms linear;--button-timing-out: .15s ease-out;--button-loading-duration: .5s}a-button[round],a[role=button][data-anta][round],button[data-anta][round]{--button-round: attr(round type(<length>), 999px);border-radius:var(--button-round, 999px)}a-button[tone=brand],a[role=button][data-anta][tone=brand],button[data-anta][tone=brand]{--button-bg-primary-rest: #5f4bc3;--button-bg-primary-hover: #503cb4;--button-bg-primary-active: #483493;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #7460d71a;--button-bg-secondary-hover: #7460d726;--button-bg-secondary-active: #7460d733;--button-fg-secondary-rest: #5f4bc3;--button-fg-secondary-hover: #503cb4;--button-fg-tertiary-rest: #5f4bc3;--button-fg-tertiary-hover: #503cb4;--button-bg-tertiary-hover: #7460d71a;--button-bg-tertiary-active: #7460d726;--button-fg-quaternary-rest: #5f4bc3;--button-fg-quaternary-hover: #483493}a-button[tone=critical],a[role=button][data-anta][tone=critical],button[data-anta][tone=critical]{--button-bg-primary-rest: #c9302c;--button-bg-primary-hover: #b02120;--button-bg-primary-active: #a01c1c;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #de45451a;--button-bg-secondary-hover: #de454526;--button-bg-secondary-active: #de454533;--button-fg-secondary-rest: #c9302c;--button-fg-secondary-hover: #b02120;--button-fg-tertiary-rest: #c9302c;--button-fg-tertiary-hover: #b02120;--button-bg-tertiary-hover: #de45451a;--button-bg-tertiary-active: #de454533;--button-fg-quaternary-rest: #c9302c;--button-fg-quaternary-hover: #a01c1c}a-button[tone=info],a[role=button][data-anta][tone=info],button[data-anta][tone=info]{--button-bg-primary-rest: #1f6eb2;--button-bg-primary-hover: #1a5b93;--button-bg-primary-active: #175082;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #2686d91a;--button-bg-secondary-hover: #2686d926;--button-bg-secondary-active: #2686d933;--button-fg-secondary-rest: #1f6eb2;--button-fg-secondary-hover: #1a5b93;--button-fg-tertiary-rest: #1f6eb2;--button-fg-tertiary-hover: #1a5b93;--button-bg-tertiary-hover: #2686d91a;--button-bg-tertiary-active: #2686d926;--button-fg-quaternary-rest: #1f6eb2;--button-fg-quaternary-hover: #175082}a-button[tone=success],a[role=button][data-anta][tone=success],button[data-anta][tone=success]{--button-bg-primary-rest: #2a7e43;--button-bg-primary-hover: #226737;--button-bg-primary-active: #1f5c31;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #3295501a;--button-bg-secondary-hover: #32955026;--button-bg-secondary-active: #32955033;--button-fg-secondary-rest: #2a7e43;--button-fg-secondary-hover: #226737;--button-fg-tertiary-rest: #2a7e43;--button-fg-tertiary-hover: #226737;--button-bg-tertiary-hover: #3295501a;--button-bg-tertiary-active: #32955026;--button-fg-quaternary-rest: #2a7e43;--button-fg-quaternary-hover: #1f5c31}a-button[tone=warning],a[role=button][data-anta][tone=warning],button[data-anta][tone=warning]{--button-bg-primary-rest: #c37416;--button-bg-primary-hover: #ae6613;--button-bg-primary-active: #995200;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #c374161a;--button-bg-secondary-hover: #c3741626;--button-bg-secondary-active: #c3741633;--button-fg-secondary-rest: #c37416;--button-fg-secondary-hover: #ae6613;--button-fg-tertiary-rest: #c37416;--button-fg-tertiary-hover: #ae6613;--button-bg-tertiary-hover: #c374161a;--button-bg-tertiary-active: #c3741633;--button-fg-quaternary-rest: #c37416;--button-fg-quaternary-hover: #995200}.dark a-button,.dark a[role=button][data-anta],.dark button[data-anta]{--bg-primary-disabled: #272329;--bg-secondary-disabled: #1d1a1e;--fg-disabled-primary: #776e77;--fg-disabled: #635b65;--button-bg-primary-rest: #534c57;--button-bg-primary-hover: #635b65;--button-bg-primary-active: #938d96;--button-bg-secondary-rest: #e4d1ef1c;--button-bg-secondary-hover: #e4d1ef24;--button-bg-secondary-active: #e4d1ef2e;--button-fg-secondary-rest: #c1b9c1;--button-fg-secondary-hover: #d4ced4;--button-fg-secondary-l-shift: 0;--button-fg-tertiary-rest: #afa9b1;--button-fg-tertiary-hover: #afa9b1;--button-bg-tertiary-hover: #e4d1ef14;--button-bg-tertiary-active: #e4d1ef21;--button-fg-quaternary-rest: #afa9b1;--button-fg-quaternary-hover: #cac4ca}.dark a-button[tone=brand],.dark a[role=button][data-anta][tone=brand],.dark button[data-anta][tone=brand]{--button-bg-primary-rest: #503cb4;--button-bg-primary-hover: #5f4bc3;--button-bg-primary-active: #7460d7;--button-bg-secondary-rest: #7460d73b;--button-bg-secondary-hover: #7460d747;--button-bg-secondary-active: #7460d754;--button-fg-secondary-rest: #c5baff;--button-fg-secondary-hover: #d2cbf6;--button-fg-tertiary-rest: #ada0ee;--button-fg-tertiary-hover: #bcb1f1;--button-bg-tertiary-hover: #7460d73b;--button-bg-tertiary-active: #7460d747;--button-fg-quaternary-rest: #ada0ee;--button-fg-quaternary-hover: #c7bef4}.dark a-button[tone=critical],.dark a[role=button][data-anta][tone=critical],.dark button[data-anta][tone=critical]{--button-bg-primary-rest: #b02120;--button-bg-primary-hover: #c9302c;--button-bg-primary-active: #de4545;--button-bg-secondary-rest: #de45453b;--button-bg-secondary-hover: #de454547;--button-bg-secondary-active: #de454554;--button-fg-secondary-rest: #ffabac;--button-fg-secondary-hover: #f4c2c2;--button-fg-tertiary-rest: #e78e90;--button-fg-tertiary-hover: #efa4a4;--button-bg-tertiary-hover: #de45453b;--button-bg-tertiary-active: #de454547;--button-fg-quaternary-rest: #e78e90;--button-fg-quaternary-hover: #ffabac}.dark a-button[tone=info],.dark a[role=button][data-anta][tone=info],.dark button[data-anta][tone=info]{--button-bg-primary-rest: #1a5b93;--button-bg-primary-hover: #1f6eb2;--button-bg-primary-active: #2686d9;--button-bg-secondary-rest: #2686d93b;--button-bg-secondary-hover: #2686d947;--button-bg-secondary-active: #2686d954;--button-fg-secondary-rest: #9ed2ff;--button-fg-secondary-hover: #bad6f3;--button-fg-tertiary-rest: #7db6e8;--button-fg-tertiary-hover: #93c5ec;--button-bg-tertiary-hover: #2686d93b;--button-bg-tertiary-active: #2686d947;--button-fg-quaternary-rest: #7db6e8;--button-fg-quaternary-hover: #a6cdef}.dark a-button[tone=success],.dark a[role=button][data-anta][tone=success],.dark button[data-anta][tone=success]{--button-bg-primary-rest: #226737;--button-bg-primary-hover: #2a7e43;--button-bg-primary-active: #329550;--button-bg-secondary-rest: #3295503b;--button-bg-secondary-hover: #32955047;--button-bg-secondary-active: #32955054;--button-fg-secondary-rest: #8ceca9;--button-fg-secondary-hover: #b3e5c2;--button-fg-tertiary-rest: #74cd8e;--button-fg-tertiary-hover: #88d7a0;--button-bg-tertiary-hover: #3295503b;--button-bg-tertiary-active: #32955047;--button-fg-quaternary-rest: #74cd8e;--button-fg-quaternary-hover: #9ddeb1}.dark a-button[tone=warning],.dark a[role=button][data-anta][tone=warning],.dark button[data-anta][tone=warning]{--button-bg-primary-rest: #7f410b;--button-bg-primary-hover: #995200;--button-bg-primary-active: #ae6613;--button-bg-secondary-rest: #c374163b;--button-bg-secondary-hover: #c3741647;--button-bg-secondary-active: #c3741654;--button-fg-secondary-rest: #f7c06e;--button-fg-secondary-hover: #f3cc91;--button-fg-tertiary-rest: #e1a452;--button-fg-tertiary-hover: #edb25a;--button-bg-tertiary-hover: #c374163b;--button-bg-tertiary-active: #c3741647;--button-fg-quaternary-rest: #e1a452;--button-fg-quaternary-hover: #f0bf75}button[data-anta]{box-sizing:border-box;margin:0;appearance:none;-webkit-appearance:none;border:none}a-button,a[role=button][data-anta],button[data-anta]{user-select:none;display:inline-flex;align-items:center;gap:.5ch;overflow:hidden;cursor:pointer;&:has(>a-copy):not(:has(>a-icon)){cursor:copy}flex-shrink:0;color:var(--button-fg);background-color:var(--button-bg);border-radius:4px;text-decoration:none;box-shadow:inset 0 0 1px color-mix(in oklch,currentColor,transparent 90%);font-size:var(--_fs);font-family:var(--sans-serif);font-weight:450;font-variation-settings:"wdth" 88,"slnt" 0,"ital" 0;font-feature-settings:"ss02","ss05","tnum";line-height:var(--_lh);letter-spacing:.05ch;text-overflow:ellipsis;text-wrap:nowrap;white-space:nowrap;max-width:100%;padding-inline:var(--button-padding-x);padding-block:var(--button-padding-y);min-height:28px;>a-button-label{display:inline-block;text-overflow:ellipsis;text-wrap:nowrap;white-space:nowrap;overflow:hidden;min-width:0;line-height:var(--_lh);padding-bottom:var(--_pb);&:has(>*){display:inline-flex;gap:.25ch}}>*{pointer-events:none}& a-icon{transition:color var(--button-timing-out)}transition:color var(--button-timing-out),background-color var(--button-timing-out);&:hover,&:focus-visible{transition:color var(--button-timing-in),background-color var(--button-timing-in);& a-icon{transition:color var(--button-timing-in)}}&:active,&[selected]{transition:color var(--button-timing-active),background-color var(--button-timing-active);& a-icon{transition:color var(--button-timing-active)}}&[disabled]{pointer-events:none;cursor:not-allowed;transition:none;& a-icon{transition:none}}&:focus-visible{outline:1px solid var(--focus-ring);outline-offset:1px}&[priority=quaternary]{--button-timing-in: 0s;--button-timing-active: 0s;--button-timing-out: 0s}&[size=small]{--button-padding-x: 7px;--_fs: 13px;--_lh: 16px;--_pb: .5px;min-height:24px;& a-icon{--icon-size: 14px}}&[size=large]{--button-padding-x: 13px;--_fs: 17px;--_lh: 24px;--_pb: 1.5px;min-height:32px;& a-icon{--icon-size: 18px}}&[priority=tertiary],&[priority=quaternary]{&[underline=solid]{text-decoration:underline solid}&[underline=dashed]{text-decoration:underline dashed}&[underline=dotted]{text-decoration:underline dotted}&[underline]{text-decoration-color:color-mix(in srgb,currentColor 75%,transparent);text-decoration-thickness:1px;text-underline-offset:3px;&[selected]{text-decoration-color:var(--button-fg);text-decoration-thickness:1px}@media(hover:hover)and (pointer:fine){&:hover{text-decoration-color:var(--button-fg);text-decoration-thickness:1px}}}}&[priority=quaternary][paddingless]{--button-padding-x: 0;--button-padding-y: 0;min-height:0}&:has(>a-icon):not(:has(>a-icon~a-icon)):not(:has(>:not(a-icon):not(a-tooltip):not(a-copy))){--button-padding-y: 5px;--button-padding-x: 5px;min-width:28px;justify-content:center;&[size=small]{--button-padding-y: 3px;--button-padding-x: 3px;min-width:24px}&[size=large]{--button-padding-y: 7px;--button-padding-x: 7px;min-width:32px}}&:is(:has(>a-icon:first-child),:has(>a-tooltip:first-child+a-icon)):is(:has(>a-icon~a-icon),:has(>:not(a-icon):not(a-tooltip):not(a-copy))){padding-inline-start:max(0px,var(--button-padding-x) - 2px)}&:is(:has(>a-icon:last-child),:has(>a-icon+a-tooltip:last-child)):is(:has(>a-icon~a-icon),:has(>:not(a-icon):not(a-tooltip):not(a-copy))){padding-inline-end:max(0px,var(--button-padding-x) - 2px)}&[loading]{position:relative;pointer-events:none;cursor:wait;&:before{content:"";position:absolute;top:0;bottom:0;left:calc(0px - var(--button-loading-x-period));right:0;pointer-events:none;background:repeating-linear-gradient(var(--button-loading-angle),transparent 0,transparent var(--button-loading-stripe-gap),currentColor var(--button-loading-stripe-gap),currentColor calc(var(--button-loading-stripe-gap) + var(--button-loading-stripe)));opacity:var(--button-loading-opacity);filter:blur(var(--button-loading-blur));will-change:transform;animation:btn-loading-slide var(--button-loading-duration) linear infinite;animation-delay:-9999s}}&[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=critical],[tone=info],[tone=success],[tone=warning]){--button-tone-source: attr(tone type(<color>), transparent);--_tone-fg-l: .46;--_tone-fg-strong-l: .4;--_tone-fg-c: .17;--_tone-bg-l: .54;--_tone-bg-c: .16;--_tone-bg-a-rest: .1;--_tone-bg-a-hover: .15;--_tone-bg-a-active: .2;--_tone-primary-l-rest: .5;--_tone-primary-l-hover: .45;--_tone-primary-l-active: .4;--button-bg-primary-rest: oklch(from var(--button-tone-source) var(--_tone-primary-l-rest) c h);--button-bg-primary-hover: oklch(from var(--button-tone-source) var(--_tone-primary-l-hover) c h);--button-bg-primary-active: oklch(from var(--button-tone-source) var(--_tone-primary-l-active) c h);--button-fg-primary-rest: var(--button-primary-fg);--button-fg-secondary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-secondary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-fg-tertiary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-tertiary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-fg-quaternary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-quaternary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-bg-secondary-rest: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-rest));--button-bg-secondary-hover: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-hover));--button-bg-secondary-active: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-active));--button-bg-tertiary-hover: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-rest));--button-bg-tertiary-active: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-hover))}.dark &[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=critical],[tone=info],[tone=success],[tone=warning]){--_tone-fg-l: .78;--_tone-fg-strong-l: .85;--_tone-fg-c: .11;--_tone-bg-l: .58;--_tone-bg-a-rest: .23;--_tone-bg-a-hover: .28;--_tone-bg-a-active: .33;--_tone-primary-l-rest: .45;--_tone-primary-l-hover: .5;--_tone-primary-l-active: .57}--button-fg: oklch(from var(--button-fg-secondary-rest) calc(l - var(--button-fg-secondary-l-shift)) c h);--button-bg: var(--button-bg-secondary-rest);@media(hover:hover)and (pointer:fine){&:hover{--button-fg: var(--button-fg-secondary-hover);--button-bg: var(--button-bg-secondary-hover)}}&:active{--button-fg: var(--button-fg-secondary-hover);--button-bg: var(--button-bg-secondary-active)}&[selected]{--button-fg: var(--button-fg-secondary-hover);--button-bg: var(--button-bg-secondary-hover)}&[priority=primary]{--button-fg: var(--button-fg-primary-rest);--button-bg: var(--button-bg-primary-rest);box-shadow:none;@media(hover:hover)and (pointer:fine){&:hover{--button-bg: var(--button-bg-primary-hover)}}&:active{--button-bg: var(--button-bg-primary-active)}&[selected]{--button-bg: var(--button-bg-primary-hover)}}&[priority=tertiary]{--button-fg: var(--button-fg-tertiary-rest);--button-bg: transparent;box-shadow:none;@media(hover:hover)and (pointer:fine){&:hover{--button-fg: var(--button-fg-tertiary-hover);--button-bg: var(--button-bg-tertiary-hover)}}&:active{--button-fg: var(--button-fg-tertiary-hover);--button-bg: var(--button-bg-tertiary-active)}&[selected]{--button-fg: var(--button-fg-tertiary-hover);--button-bg: var(--button-bg-tertiary-hover)}}&[priority=quaternary]{--button-fg: var(--button-fg-quaternary-rest);--button-bg: transparent;box-shadow:none;font-weight:400;letter-spacing:.06ch;@media(hover:hover)and (pointer:fine){&:hover{--button-fg: var(--button-fg-quaternary-hover)}}&[selected]{--button-fg: var(--button-fg-quaternary-hover)}&:active{--button-fg: oklch(from var(--button-fg-quaternary-rest) calc(l + .05) c h)}.dark &:active{--button-fg: var(--button-fg-quaternary-rest)}}&[selected]{box-shadow:inset 0 0 0 .5px currentColor}&[disabled]{background-color:var(--bg-secondary-disabled);color:var(--fg-disabled);&[priority=primary]{background-color:var(--bg-primary-disabled);color:var(--fg-disabled-primary)}&[priority=tertiary],&[priority=quaternary]{background-color:transparent;color:var(--fg-disabled)}}}}@keyframes btn-loading-slide{to{transform:translate(var(--button-loading-x-period))}}
@@ -63,9 +63,5 @@ declare global {
63
63
  */
64
64
  export declare class AButtonElement extends HTMLElementBase {
65
65
  connectedCallback(): void;
66
- /** Perform a copy if this button is a copy control (`copy` / `copy-node` /
67
- * `copy-lazy`). Called from the delegated click handler on activation. The
68
- * outcome is announced via a `copydone` event the wrapper reflects. */
69
- performCopy(): boolean;
70
66
  }
71
67
  export declare function register_a_button(): void;
@@ -1,9 +1,14 @@
1
1
  import { HTMLElementBase } from "../anta_helpers";
2
- import { runCopy } from "./copy-behavior";
2
+ import { installKeyActivation } from "./key-activation";
3
3
  import "./a-button.css";
4
4
  function installDocumentHandlers(doc) {
5
5
  if (!doc || doc.hasKeyListenerForAButton) return;
6
- doc.addEventListener("keydown", handleKeyDown, true);
6
+ installKeyActivation(doc, {
7
+ keys: ["Enter", " "],
8
+ resolve: (t) => t?.closest?.("a-button"),
9
+ blocked: (el) => el.hasAttribute("disabled") || el.hasAttribute("loading"),
10
+ activate: (el) => el.click()
11
+ });
7
12
  doc.addEventListener("click", handleClick, true);
8
13
  doc.hasKeyListenerForAButton = true;
9
14
  }
@@ -11,12 +16,6 @@ class AButtonElement extends HTMLElementBase {
11
16
  connectedCallback() {
12
17
  installDocumentHandlers(this.doc);
13
18
  }
14
- /** Perform a copy if this button is a copy control (`copy` / `copy-node` /
15
- * `copy-lazy`). Called from the delegated click handler on activation. The
16
- * outcome is announced via a `copydone` event the wrapper reflects. */
17
- performCopy() {
18
- return runCopy(this);
19
- }
20
19
  }
21
20
  function findForm(el) {
22
21
  const formId = el.getAttribute("form");
@@ -25,17 +24,6 @@ function findForm(el) {
25
24
  }
26
25
  return el.closest("form");
27
26
  }
28
- function handleKeyDown(e) {
29
- if (e.key !== "Enter" && e.key !== " ") return;
30
- if (e.repeat) return;
31
- const el = e.target.closest(
32
- "a-button"
33
- );
34
- if (!el) return;
35
- if (el.hasAttribute("disabled") || el.hasAttribute("loading")) return;
36
- e.preventDefault();
37
- el.click();
38
- }
39
27
  function handleClick(e) {
40
28
  const el = e.target.closest(
41
29
  "a-button"
@@ -48,7 +36,6 @@ function handleClick(e) {
48
36
  new CustomEvent(customEvent, { bubbles: true, cancelable: true })
49
37
  );
50
38
  }
51
- el.performCopy();
52
39
  const type = el.getAttribute("type") || "button";
53
40
  const form = findForm(el);
54
41
  if (!form) return;
@@ -0,0 +1 @@
1
+ @layer anta{a-copy,a-copy:not(:defined){display:contents}}
@@ -0,0 +1,16 @@
1
+ import { HTMLElementBase } from "../anta_helpers";
2
+ import "./a-copy.css";
3
+ declare global {
4
+ interface Document {
5
+ hasCopyDelegation?: boolean;
6
+ }
7
+ }
8
+ export declare class ACopyElement extends HTMLElementBase {
9
+ #private;
10
+ connectedCallback(): void;
11
+ /** Run the copy for the activated host. Called from the delegated click /
12
+ * menuselect handlers; the ghost (if any) follows on `copydone`. */
13
+ activate(): void;
14
+ disconnectedCallback(): void;
15
+ }
16
+ export declare function register_a_copy(): void;
@@ -0,0 +1,148 @@
1
+ import { HTMLElementBase } from "../anta_helpers";
2
+ import { emitCopyRequest, runCopy } from "./copy-behavior";
3
+ import "./a-copy.css";
4
+ const BUTTON_HOST = "a-button, button, [role=button]";
5
+ const MENU_HOST = "a-menu-item, [role=menuitem]";
6
+ const ANY_HOST = `${BUTTON_HOST}, ${MENU_HOST}`;
7
+ function copyChild(host) {
8
+ return host?.querySelector(":scope > a-copy") ?? null;
9
+ }
10
+ function hostBlocked(host) {
11
+ return host.hasAttribute("disabled") || host.hasAttribute("loading") || host.getAttribute("aria-disabled") === "true";
12
+ }
13
+ function installCopyDelegation(doc) {
14
+ if (!doc || doc.hasCopyDelegation) return;
15
+ const preRequest = (target) => {
16
+ const host = target?.closest?.(ANY_HOST);
17
+ if (!host || hostBlocked(host)) return;
18
+ const el = copyChild(host);
19
+ if (el) emitCopyRequest(el);
20
+ };
21
+ doc.addEventListener("pointerdown", (e) => preRequest(e.target), true);
22
+ doc.addEventListener(
23
+ "keydown",
24
+ (e) => {
25
+ if (e.key === "Enter" || e.key === " ")
26
+ preRequest(e.target);
27
+ },
28
+ true
29
+ );
30
+ doc.addEventListener(
31
+ "click",
32
+ (e) => {
33
+ const host = e.target?.closest?.(BUTTON_HOST);
34
+ if (!host || hostBlocked(host)) return;
35
+ copyChild(host)?.activate();
36
+ },
37
+ true
38
+ );
39
+ doc.addEventListener(
40
+ "menuselect",
41
+ (e) => {
42
+ const host = e.target?.closest?.(MENU_HOST);
43
+ if (!host || hostBlocked(host)) return;
44
+ copyChild(host)?.activate();
45
+ },
46
+ true
47
+ );
48
+ doc.hasCopyDelegation = true;
49
+ }
50
+ const GHOST_MS = 650;
51
+ class ACopyElement extends HTMLElementBase {
52
+ #ghost;
53
+ #ghostTimer;
54
+ connectedCallback() {
55
+ installCopyDelegation(this.doc);
56
+ this.addEventListener("copydone", this.#onCopyDone);
57
+ }
58
+ /** Run the copy for the activated host. Called from the delegated click /
59
+ * menuselect handlers; the ghost (if any) follows on `copydone`. */
60
+ activate() {
61
+ runCopy(this);
62
+ }
63
+ #onCopyDone = (e) => {
64
+ if (!this.hasAttribute("toast")) return;
65
+ if (!e.detail?.ok) return;
66
+ const host = this.closest(ANY_HOST);
67
+ if (host) this.#showGhost(host);
68
+ };
69
+ #buildShadow() {
70
+ const root = this.attachShadow({ mode: "open" });
71
+ root.innerHTML = `<style>
72
+ .ghost {
73
+ position: fixed;
74
+ margin: 0;
75
+ padding: 0;
76
+ border: 0;
77
+ inset: auto;
78
+ background: none;
79
+ overflow: visible;
80
+ pointer-events: none;
81
+ display: grid;
82
+ place-items: center;
83
+ font: inherit;
84
+ color: inherit;
85
+ white-space: nowrap;
86
+ }
87
+ .ghost:not(:popover-open) { display: none; }
88
+ .ghost[data-show] { animation: a-copy-rise ${GHOST_MS - 50}ms ease-out forwards; }
89
+ @keyframes a-copy-rise {
90
+ from { opacity: 1; transform: translateY(0); }
91
+ to { opacity: 0; transform: translateY(-1.5em); }
92
+ }
93
+ </style><div class="ghost" part="ghost" popover="manual"></div>`;
94
+ this.#ghost = root.querySelector(".ghost");
95
+ }
96
+ #showGhost(host) {
97
+ if (!this.#ghost) this.#buildShadow();
98
+ const ghost = this.#ghost;
99
+ if (!ghost || typeof ghost.showPopover !== "function") return;
100
+ const text = (host.textContent ?? "").trim();
101
+ if (!text) return;
102
+ const r = host.getBoundingClientRect();
103
+ ghost.textContent = text;
104
+ ghost.style.left = `${r.left}px`;
105
+ ghost.style.top = `${r.top}px`;
106
+ ghost.style.width = `${r.width}px`;
107
+ ghost.style.height = `${r.height}px`;
108
+ clearTimeout(this.#ghostTimer);
109
+ ghost.removeAttribute("data-show");
110
+ if (ghost.matches(":popover-open")) {
111
+ try {
112
+ ghost.hidePopover();
113
+ } catch {
114
+ }
115
+ }
116
+ try {
117
+ ghost.showPopover();
118
+ } catch {
119
+ return;
120
+ }
121
+ void ghost.offsetWidth;
122
+ ghost.setAttribute("data-show", "");
123
+ this.#ghostTimer = setTimeout(() => {
124
+ ghost.removeAttribute("data-show");
125
+ if (ghost.matches(":popover-open")) {
126
+ try {
127
+ ghost.hidePopover();
128
+ } catch {
129
+ }
130
+ }
131
+ }, GHOST_MS);
132
+ }
133
+ disconnectedCallback() {
134
+ clearTimeout(this.#ghostTimer);
135
+ this.removeEventListener("copydone", this.#onCopyDone);
136
+ }
137
+ }
138
+ function register_a_copy() {
139
+ if (typeof customElements === "undefined") return;
140
+ if (!customElements.get("a-copy")) {
141
+ customElements.define("a-copy", ACopyElement);
142
+ }
143
+ }
144
+ register_a_copy();
145
+ export {
146
+ ACopyElement,
147
+ register_a_copy
148
+ };
@@ -1 +1 @@
1
- @layer anta{a-expander{--expander-text: var(--text-2);--expander-text-hover: var(--text-1);--expander-bg-secondary: var(--bg-2);--expander-border-secondary: var(--border-5);--expander-bg-primary: var(--bg-4);--expander-border-primary: var(--border-4);--expander-bg: var(--expander-bg-secondary);--expander-border: var(--expander-border-secondary);--expander-bg-hover-lift: .01;--expander-bg-hover: oklch(from var(--expander-bg) calc(l + var(--expander-bg-hover-lift)) c h);--expander-gutter: 24px;--_expander-chevron: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'%3e%3cpath stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m9 18 6-6-6-6'/%3e%3c/svg%3e");display:block;width:100%;box-sizing:border-box;border:1px solid var(--expander-border);border-radius:4px;color:var(--expander-text);background:var(--expander-bg);transition:background-color .1s ease}a-expander[round]{--expander-round: attr(round type(<length>));border-radius:var(--expander-round, var(--_expander-round-radius, 999px))}a-expander:not(:defined) a-expander-details{display:none}a-expander:not(:defined)[state=open] a-expander-details,a-expander:not(:defined)[default-state=open] a-expander-details{display:block}a-expander:not(:defined) a-expander-summary{position:relative;padding:6px 4px 6px var(--expander-gutter)}a-expander:not(:defined) a-expander-summary:before{content:"";position:absolute;left:calc(var(--expander-gutter) - 16px - 2px);top:50%;width:16px;height:16px;transform:translateY(-50%);background-color:currentColor;-webkit-mask:var(--_expander-chevron) center / contain no-repeat;mask:var(--_expander-chevron) center / contain no-repeat;opacity:.6}a-expander-summary{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-decoration-line:var(--_summary-underline, none);text-decoration-style:dotted;text-decoration-color:color-mix(in oklch,currentColor 75%,transparent);text-decoration-thickness:1px;text-underline-offset:3px;transition:color .15s ease}a-expander-details{display:block;padding:2px 4px 6px var(--expander-gutter);line-height:20px}a-expander[priority=primary]{--expander-bg: var(--expander-bg-primary);--expander-border: var(--expander-border-primary)}a-expander[priority=tertiary]{--expander-bg: transparent;--expander-border: transparent}a-expander:not([disabled]):not(:state(open)):hover{background:var(--expander-bg-hover)}a-expander:not([disabled]):not(:state(open)):active{background:var(--expander-bg)}a-expander[priority=tertiary][outdent]{--expander-gutter: 0px}a-expander[tone=brand]{--expander-text: var(--text-2-brand);--expander-text-hover: var(--text-1-brand);--expander-bg-secondary: var(--bg-2-brand);--expander-border-secondary: var(--border-5-brand);--expander-bg-primary: var(--bg-4-brand);--expander-border-primary: var(--border-4-brand)}a-expander[tone=info]{--expander-text: var(--text-2-info);--expander-text-hover: var(--text-1-info);--expander-bg-secondary: var(--bg-2-info);--expander-border-secondary: var(--border-5-info);--expander-bg-primary: var(--bg-4-info);--expander-border-primary: var(--border-4-info)}a-expander[tone=success]{--expander-text: var(--text-2-success);--expander-text-hover: var(--text-1-success);--expander-bg-secondary: var(--bg-2-success);--expander-border-secondary: var(--border-5-success);--expander-bg-primary: var(--bg-4-success);--expander-border-primary: var(--border-4-success)}a-expander[tone=warning]{--expander-text: var(--text-2-warning);--expander-text-hover: var(--text-1-warning);--expander-bg-secondary: var(--bg-2-warning);--expander-border-secondary: var(--border-5-warning);--expander-bg-primary: var(--bg-4-warning);--expander-border-primary: var(--border-4-warning)}a-expander[tone=critical]{--expander-text: var(--text-2-critical);--expander-text-hover: var(--text-1-critical);--expander-bg-secondary: var(--bg-2-critical);--expander-border-secondary: var(--border-5-critical);--expander-bg-primary: var(--bg-4-critical);--expander-border-primary: var(--border-4-critical)}a-expander[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--expander-tone-source: attr(tone type(<color>), currentColor);--expander-text: oklch(from var(--expander-tone-source) .41 .15 h);--expander-text-hover: oklch(from var(--expander-tone-source) .33 .15 h);--expander-bg-secondary: oklch(from var(--expander-tone-source) .99 .006 h);--expander-border-secondary: oklch(from var(--expander-tone-source) .93 .03 h);--expander-bg-primary: oklch(from var(--expander-tone-source) .955 .02 h);--expander-border-primary: oklch(from var(--expander-tone-source) .895 .045 h)}.dark a-expander[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--expander-text: oklch(from var(--expander-tone-source) .75 .11 h);--expander-text-hover: oklch(from var(--expander-tone-source) .82 .1 h);--expander-bg-secondary: oklch(from var(--expander-tone-source) .13 .02 h);--expander-border-secondary: oklch(from var(--expander-tone-source) .22 .05 h);--expander-bg-primary: oklch(from var(--expander-tone-source) .19 .04 h);--expander-border-primary: oklch(from var(--expander-tone-source) .26 .07 h)}a-expander[disabled],a-expander[disabled][tone]{--expander-text: #afa9b1}.dark a-expander[disabled],.dark a-expander[disabled][tone]{--expander-text: #635b65}}
1
+ @layer anta{a-expander{--expander-text: var(--text-2);--expander-text-hover: var(--text-1);--expander-bg-secondary: var(--bg-2);--expander-border-secondary: var(--border-5);--expander-bg-primary: var(--bg-4);--expander-border-primary: var(--border-4);--expander-bg: var(--expander-bg-secondary);--expander-border: var(--expander-border-secondary);--expander-bg-hover-lift: .01;--expander-bg-hover: oklch(from var(--expander-bg) calc(l + var(--expander-bg-hover-lift)) c h);--expander-gutter: 24px;--_expander-chevron: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'%3e%3cpath stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m9 18 6-6-6-6'/%3e%3c/svg%3e");display:block;width:100%;box-sizing:border-box;border:1px solid var(--expander-border);border-radius:4px;color:var(--expander-text);background:var(--expander-bg);transition:background-color .1s ease}a-expander[round]{--expander-round: attr(round type(<length>));border-radius:var(--expander-round, var(--_expander-round-radius, 999px))}a-expander>[slot=actions]{display:contents}a-expander:not(:defined) a-expander-details{display:none}a-expander:not(:defined)[state=open] a-expander-details,a-expander:not(:defined)[default-state=open] a-expander-details{display:block}a-expander:not(:defined) a-expander-summary{position:relative;padding:6px 4px 6px var(--expander-gutter)}a-expander:not(:defined) a-expander-summary:before{content:"";position:absolute;left:calc(var(--expander-gutter) - 16px - 2px);top:50%;width:16px;height:16px;transform:translateY(-50%);background-color:currentColor;-webkit-mask:var(--_expander-chevron) center / contain no-repeat;mask:var(--_expander-chevron) center / contain no-repeat;opacity:.6}a-expander:not(:defined){display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center}a-expander:not(:defined) a-expander-summary{grid-column:1}a-expander:not(:defined)>[slot=actions]{grid-column:2;display:flex;align-items:center;gap:2px;flex-shrink:0;margin-inline-start:8px;margin-inline-end:4px}a-expander:not(:defined) a-expander-details{grid-column:1 / -1}a-expander-summary{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:15px;line-height:20px;font-weight:584.62;letter-spacing:0;text-decoration-line:var(--_summary-underline, none);text-decoration-style:dotted;text-decoration-color:color-mix(in oklch,currentColor 75%,transparent);text-decoration-thickness:1px;text-underline-offset:3px;transition:color .15s ease}a-expander[level="1"] a-expander-summary{font-size:28px;line-height:32px}a-expander[level="2"] a-expander-summary{font-size:24px;line-height:28px}a-expander[level="3"] a-expander-summary{font-size:20px;line-height:24px}a-expander[level="4"] a-expander-summary{font-size:17px;line-height:20px}a-expander[level="6"] a-expander-summary{font-size:13px;line-height:16px}a-expander-details{display:block;padding:2px 4px 6px var(--expander-gutter);line-height:20px}a-expander[priority=tertiary][outdent] a-expander-details{padding-inline-start:4px;margin-inline-start:-4px}a-expander[priority=primary]{--expander-bg: var(--expander-bg-primary);--expander-border: var(--expander-border-primary)}a-expander[priority=tertiary]{--expander-bg: transparent;--expander-border: transparent}a-expander:not([disabled]):not(:state(open)):hover{background:var(--expander-bg-hover)}a-expander:not([disabled]):not(:state(open)):active{background:var(--expander-bg)}a-expander[priority=tertiary][outdent]{--expander-gutter: 0px}a-expander[tone=brand]{--expander-text: var(--text-2-brand);--expander-text-hover: var(--text-1-brand);--expander-bg-secondary: var(--bg-2-brand);--expander-border-secondary: var(--border-5-brand);--expander-bg-primary: var(--bg-4-brand);--expander-border-primary: var(--border-4-brand)}a-expander[tone=info]{--expander-text: var(--text-2-info);--expander-text-hover: var(--text-1-info);--expander-bg-secondary: var(--bg-2-info);--expander-border-secondary: var(--border-5-info);--expander-bg-primary: var(--bg-4-info);--expander-border-primary: var(--border-4-info)}a-expander[tone=success]{--expander-text: var(--text-2-success);--expander-text-hover: var(--text-1-success);--expander-bg-secondary: var(--bg-2-success);--expander-border-secondary: var(--border-5-success);--expander-bg-primary: var(--bg-4-success);--expander-border-primary: var(--border-4-success)}a-expander[tone=warning]{--expander-text: var(--text-2-warning);--expander-text-hover: var(--text-1-warning);--expander-bg-secondary: var(--bg-2-warning);--expander-border-secondary: var(--border-5-warning);--expander-bg-primary: var(--bg-4-warning);--expander-border-primary: var(--border-4-warning)}a-expander[tone=critical]{--expander-text: var(--text-2-critical);--expander-text-hover: var(--text-1-critical);--expander-bg-secondary: var(--bg-2-critical);--expander-border-secondary: var(--border-5-critical);--expander-bg-primary: var(--bg-4-critical);--expander-border-primary: var(--border-4-critical)}a-expander[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--expander-tone-source: attr(tone type(<color>), currentColor);--expander-text: oklch(from var(--expander-tone-source) .41 .15 h);--expander-text-hover: oklch(from var(--expander-tone-source) .33 .15 h);--expander-bg-secondary: oklch(from var(--expander-tone-source) .99 .006 h);--expander-border-secondary: oklch(from var(--expander-tone-source) .93 .03 h);--expander-bg-primary: oklch(from var(--expander-tone-source) .955 .02 h);--expander-border-primary: oklch(from var(--expander-tone-source) .895 .045 h)}.dark a-expander[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--expander-text: oklch(from var(--expander-tone-source) .75 .11 h);--expander-text-hover: oklch(from var(--expander-tone-source) .82 .1 h);--expander-bg-secondary: oklch(from var(--expander-tone-source) .13 .02 h);--expander-border-secondary: oklch(from var(--expander-tone-source) .22 .05 h);--expander-bg-primary: oklch(from var(--expander-tone-source) .19 .04 h);--expander-border-primary: oklch(from var(--expander-tone-source) .26 .07 h)}a-expander[disabled],a-expander[disabled][tone]{--expander-text: #afa9b1}.dark a-expander[disabled],.dark a-expander[disabled][tone]{--expander-text: #635b65}}
@@ -1,18 +1,12 @@
1
1
  import { HTMLElementBase, parseOpenState } from "../anta_helpers";
2
2
  import "./a-expander.css";
3
3
  const ANIM_MS = 200;
4
- const SUMMARY_TYPE_SCALE = {
5
- "1": [28, 32],
6
- "2": [24, 28],
7
- "3": [20, 24],
8
- "4": [17, 20],
9
- "5": [15, 20],
10
- "6": [13, 16]
11
- };
12
- const SUMMARY_FONT_WEIGHT = 584.62;
13
- const SUMMARY_LEVEL_RULES = Object.entries(SUMMARY_TYPE_SCALE).map(
14
- ([level, [size, line]]) => `:host([level="${level}"]) button { font-size: ${size}px; line-height: ${line}px; }`
15
- ).join("\n ");
4
+ const INTERACTIVE_SELECTOR = 'a-button,a-checkbox,a-radio,a-radio-group,a-input,a-input-time,a-calendar,a-menu-item,a-tab,[data-anta][role="button"],button,a[href],input,select,textarea,label,[contenteditable=""],[contenteditable="true"]';
5
+ const DISABLED_SELECTOR = ':disabled,[disabled],[aria-disabled="true"]';
6
+ function ignoresToggle(el) {
7
+ if (el.matches("[data-expander-ignore]")) return true;
8
+ return el.matches(INTERACTIVE_SELECTOR) && !el.matches(DISABLED_SELECTOR);
9
+ }
16
10
  const SHADOW_STYLE = `
17
11
  :host { display: block; }
18
12
 
@@ -61,10 +55,6 @@ const SHADOW_STYLE = `
61
55
  user-select: none;
62
56
  border-radius: 2px;
63
57
  outline: none;
64
- font-size: ${SUMMARY_TYPE_SCALE["5"][0]}px;
65
- line-height: ${SUMMARY_TYPE_SCALE["5"][1]}px;
66
- font-weight: ${SUMMARY_FONT_WEIGHT};
67
- letter-spacing: 0;
68
58
  }
69
59
 
70
60
  button:focus-visible {
@@ -72,8 +62,6 @@ const SHADOW_STYLE = `
72
62
  outline-offset: 0px;
73
63
  }
74
64
 
75
- ${SUMMARY_LEVEL_RULES}
76
-
77
65
  /* The chevron sits absolutely INSIDE the gutter \u2014 out of flow, so it never
78
66
  pushes the title. Its right edge lands 2px before the gutter (left = gutter
79
67
  - 16px - 2px), leaving a 2px gap before the title; at the default 24px
@@ -266,11 +254,24 @@ class AExpanderElement extends HTMLElementBase {
266
254
  } catch {
267
255
  }
268
256
  }
257
+ /** Refuse to toggle when the click landed on a control inside the projected
258
+ * title — walk the composed path up to (not including) the summary button and
259
+ * test each element with `ignoresToggle` (enabled interactive control or the
260
+ * opt-out marker). Synchronous and read here in the element, so it stands in
261
+ * off-UI-thread runtimes. Suppressing before the dispatch also keeps a
262
+ * *controlled* consumer from toggling (no `statechange` fires). */
263
+ #clickIgnoresToggle(e) {
264
+ const path = e.composedPath();
265
+ const end = path.indexOf(this.summary);
266
+ const scope = end === -1 ? path : path.slice(0, end);
267
+ return scope.some((n) => n instanceof Element && ignoresToggle(n));
268
+ }
269
269
  /** Compute the requested next state, announce it (cancelable, *before*
270
270
  * applying), then — uncontrolled only, and only if not vetoed — apply it.
271
271
  * Controlled: never self-apply; the consumer answers via the `state`
272
272
  * attribute. See STATEFUL-COMPONENTS.md. */
273
- onSummaryClick = () => {
273
+ onSummaryClick = (e) => {
274
+ if (this.#clickIgnoresToggle(e)) return;
274
275
  const prev = this.#current;
275
276
  const next = prev === "open" ? "closed" : "open";
276
277
  const ok = this.dispatchEvent(
@@ -67,6 +67,13 @@ export declare function isMenuItemEl(el: EventTarget | null | undefined): el is
67
67
  /** Install the one-per-document Enter/Space activation listener. Called from
68
68
  * both `AMenuItemElement` and `AMenuElement` on connect, so a menu built only
69
69
  * from link items (no `<a-menu-item>` ever upgrades) still gets keyboard
70
- * activation. Idempotent per document. */
70
+ * activation. Idempotent per document.
71
+ *
72
+ * Shares `installKeyActivation` with `<a-button>`: activation is on keyup.
73
+ * `.click()` on a link item navigates natively (honoring download / target);
74
+ * on the custom element it routes through the menu's click delegation — one
75
+ * path for both. (The combobox-filter Enter is a separate path handled by
76
+ * `a-menu`.) A slotted `<a-copy>` adds its own keydown pre-request when a row
77
+ * is a copy control — the menu item itself no longer carries copy behavior. */
71
78
  export declare function ensureMenuItemKeyListener(doc: Document): void;
72
79
  export declare function register_a_menu_item(): void;
@@ -1,12 +1,11 @@
1
1
  import { HTMLElementBase } from "../anta_helpers";
2
- import { runCopy } from "./copy-behavior";
2
+ import { installKeyActivation } from "./key-activation";
3
3
  import "./a-menu-item.css";
4
4
  class AMenuItemElement extends HTMLElementBase {
5
5
  internals;
6
6
  constructor() {
7
7
  super();
8
8
  this.internals = this.attachInternals?.();
9
- this.addEventListener("menuselect", () => runCopy(this));
10
9
  }
11
10
  /** The active (combobox) cursor. `a-menu` sets this **property** (never an
12
11
  * attribute — no DOM mutation, same rule as `a-radio.selected`) as ArrowUp/Down
@@ -30,17 +29,14 @@ function isMenuItemEl(el) {
30
29
  }
31
30
  function ensureMenuItemKeyListener(doc) {
32
31
  if (doc.hasKeyListenerForAMenuItem) return;
33
- doc.addEventListener("keydown", handleKeyDown, true);
32
+ installKeyActivation(doc, {
33
+ keys: ["Enter", " "],
34
+ resolve: (t) => t?.closest?.(MENU_ITEM_SELECTOR),
35
+ blocked: (el) => el.hasAttribute("disabled"),
36
+ activate: (el) => el.click()
37
+ });
34
38
  doc.hasKeyListenerForAMenuItem = true;
35
39
  }
36
- function handleKeyDown(e) {
37
- if (e.key !== "Enter" && e.key !== " ") return;
38
- const el = e.target?.closest?.(MENU_ITEM_SELECTOR);
39
- if (!el) return;
40
- e.preventDefault();
41
- if (el.hasAttribute("disabled")) return;
42
- el.click();
43
- }
44
40
  function register_a_menu_item() {
45
41
  if (typeof customElements === "undefined") return;
46
42
  if (!customElements.get("a-menu-item")) {
@@ -122,6 +122,9 @@ export declare class AMenuElement extends HTMLElementBase {
122
122
  * (line start/end); PageUp / PageDown jump the option list to first / last
123
123
  * instead. Any other key falls through to the input (typing). */
124
124
  private handleComboKey;
125
+ /** Combobox keyup: activate the item a filter-field Enter armed. Paired with the
126
+ * keydown pre-request in `handleComboKey` so lazy content resolves in the gap. */
127
+ handleKeyUp(e: KeyboardEvent): void;
125
128
  /** Public imperative API. Routes through the same intent path as the
126
129
  * triggers, so it emits `statechange` and respects controlled mode. */
127
130
  open(opts?: {
@@ -212,8 +215,9 @@ export declare class AMenuElement extends HTMLElementBase {
212
215
  /** Close the whole open menu system from the root down. */
213
216
  private closeSystem;
214
217
  /** Called by the coordinator on the topmost open menu. Handles navigation;
215
- * Enter / Space activation is handled by a-menu-item's own global keydown
216
- * (which synthesizes a click → routed through onSurfaceClick). */
218
+ * roving Enter / Space activation is `<a-menu-item>`'s own delegated keyup
219
+ * (synthesizes a click → routed through onSurfaceClick). Combobox Enter (focus
220
+ * in the filter field) is handled here via handleComboKey / handleKeyUp. */
217
221
  handleKey(e: KeyboardEvent): void;
218
222
  private submenuOf;
219
223
  private typeahead;
@@ -1,5 +1,6 @@
1
1
  import { HTMLElementBase, anchorRect, setMenuPresence } from "../anta_helpers";
2
2
  import { AMenuItemElement, isMenuItemEl, ensureMenuItemKeyListener } from "./a-menu-item";
3
+ import { emitCopyRequest } from "./copy-behavior";
3
4
  import "./a-menu.css";
4
5
  const MARGIN = 4;
5
6
  const MIN_HEIGHT = 96;
@@ -18,6 +19,7 @@ function bindDocListeners(doc, view) {
18
19
  if (docBound) return;
19
20
  doc.addEventListener("pointerdown", onDocPointerDown, true);
20
21
  doc.addEventListener("keydown", onDocKeyDown, true);
22
+ doc.addEventListener("keyup", onDocKeyUp, true);
21
23
  doc.addEventListener("contextmenu", onDocContextMenu, true);
22
24
  view.addEventListener("resize", onResize);
23
25
  boundDoc = doc;
@@ -28,6 +30,7 @@ function unbindDocListeners() {
28
30
  if (!docBound) return;
29
31
  boundDoc?.removeEventListener("pointerdown", onDocPointerDown, true);
30
32
  boundDoc?.removeEventListener("keydown", onDocKeyDown, true);
33
+ boundDoc?.removeEventListener("keyup", onDocKeyUp, true);
31
34
  boundDoc?.removeEventListener("contextmenu", onDocContextMenu, true);
32
35
  boundView?.removeEventListener("resize", onResize);
33
36
  removePosTracker?.();
@@ -66,11 +69,17 @@ function pathHitsMenus(e, primaryClick = false) {
66
69
  }
67
70
  return false;
68
71
  }
72
+ function pathCrossesTopLayerBeforeAnchor(e, anchor) {
73
+ for (const node of e.composedPath()) {
74
+ if (node === anchor) return false;
75
+ if (node instanceof HTMLDialogElement && node.matches(":modal") || node instanceof HTMLElement && node.matches(":popover-open"))
76
+ return true;
77
+ }
78
+ return false;
79
+ }
69
80
  function nodeHitsMenus(node) {
70
81
  for (const m of openStack) {
71
82
  if (m.contains(node) || m.surface.contains(node)) return true;
72
- const anchor = m.triggerAnchor;
73
- if (anchor && anchor.contains(node)) return true;
74
83
  }
75
84
  return false;
76
85
  }
@@ -95,6 +104,11 @@ function onDocKeyDown(e) {
95
104
  if (!menu) return;
96
105
  menu.handleKey(e);
97
106
  }
107
+ function onDocKeyUp(e) {
108
+ const menu = openStack[openStack.length - 1];
109
+ if (!menu) return;
110
+ menu.handleKeyUp(e);
111
+ }
98
112
  function dismiss(originEvent) {
99
113
  openStack[0]?.requestClose(originEvent);
100
114
  }
@@ -535,13 +549,27 @@ class AMenuElement extends HTMLElementBase {
535
549
  case "Enter":
536
550
  if (this.activeItem) {
537
551
  e.preventDefault();
538
- this.activeItem.click();
552
+ const copyEl = this.activeItem.querySelector(":scope > a-copy");
553
+ if (copyEl) emitCopyRequest(copyEl);
554
+ this.#pendingComboActivate = this.activeItem;
539
555
  }
540
556
  return true;
541
557
  default:
542
558
  return false;
543
559
  }
544
560
  }
561
+ /** The combobox cursor armed by an Enter keydown in the filter field, consumed
562
+ * on the matching keyup. Only the combobox path arms this — the roving Enter/
563
+ * Space activation is `<a-menu-item>`'s (also keyup, via key-activation). */
564
+ #pendingComboActivate = null;
565
+ /** Combobox keyup: activate the item a filter-field Enter armed. Paired with the
566
+ * keydown pre-request in `handleComboKey` so lazy content resolves in the gap. */
567
+ handleKeyUp(e) {
568
+ if (e.key !== "Enter") return;
569
+ const el = this.#pendingComboActivate;
570
+ this.#pendingComboActivate = null;
571
+ el?.click();
572
+ }
545
573
  /* ============================ open / close ============================ */
546
574
  /** Public imperative API. Routes through the same intent path as the
547
575
  * triggers, so it emits `statechange` and respects controlled mode. */
@@ -863,8 +891,9 @@ class AMenuElement extends HTMLElementBase {
863
891
  }
864
892
  /* ============================ keyboard ============================ */
865
893
  /** Called by the coordinator on the topmost open menu. Handles navigation;
866
- * Enter / Space activation is handled by a-menu-item's own global keydown
867
- * (which synthesizes a click → routed through onSurfaceClick). */
894
+ * roving Enter / Space activation is `<a-menu-item>`'s own delegated keyup
895
+ * (synthesizes a click → routed through onSurfaceClick). Combobox Enter (focus
896
+ * in the filter field) is handled here via handleComboKey / handleKeyUp. */
868
897
  handleKey(e) {
869
898
  const active = this.doc.activeElement;
870
899
  if (e.key === "Escape") {
@@ -998,6 +1027,7 @@ class AMenuElement extends HTMLElementBase {
998
1027
  };
999
1028
  } else if (this.#isContext) {
1000
1029
  const onContext = (e) => {
1030
+ if (pathCrossesTopLayerBeforeAnchor(e, anchor)) return;
1001
1031
  e.preventDefault();
1002
1032
  this.requestOpen({ coord: [e.clientX, e.clientY], originEvent: e });
1003
1033
  };