alus-ui-mcp 0.3.1 → 0.3.2

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 (2) hide show
  1. package/dist/index.js +128 -20
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5175,6 +5175,7 @@ var BUNDLED_DATA = {
5175
5175
  mergeAttrs
5176
5176
  } from '$utils/a11y/index.js';
5177
5177
  import Portal from '../../utility/portal/Portal.svelte';
5178
+ import VisuallyHidden from '../../utility/visually-hidden/VisuallyHidden.svelte';
5178
5179
 
5179
5180
  interface Props {
5180
5181
  options: AutoCompleteOption<T>[];
@@ -5186,6 +5187,7 @@ var BUNDLED_DATA = {
5186
5187
  required?: boolean;
5187
5188
  minLength?: number;
5188
5189
  maxResults?: number;
5190
+ noResultsText?: string;
5189
5191
  filter?: (option: AutoCompleteOption<T>, query: string) => boolean;
5190
5192
  class?: string;
5191
5193
  inputClass?: string;
@@ -5212,6 +5214,7 @@ var BUNDLED_DATA = {
5212
5214
  required = false,
5213
5215
  minLength = 0,
5214
5216
  maxResults = 50,
5217
+ noResultsText = 'No results',
5215
5218
  filter,
5216
5219
  class: className = '',
5217
5220
  inputClass = '',
@@ -5369,6 +5372,10 @@ var BUNDLED_DATA = {
5369
5372
  </script>
5370
5373
 
5371
5374
  <div class={className}>
5375
+ <!-- Live region announces empty/no-results state to screen readers -->
5376
+ <VisuallyHidden as="div" role="status" aria-live="polite" aria-atomic={true}>
5377
+ {#if showEmpty}{noResultsText}{/if}
5378
+ </VisuallyHidden>
5372
5379
  <input
5373
5380
  type="text"
5374
5381
  role="combobox"
@@ -5379,6 +5386,7 @@ var BUNDLED_DATA = {
5379
5386
  {placeholder}
5380
5387
  {value}
5381
5388
  aria-autocomplete="list"
5389
+ aria-owns={listId}
5382
5390
  class={inputClass}
5383
5391
  oninput={onInputEvent}
5384
5392
  onkeydown={onKeydown}
@@ -5422,7 +5430,7 @@ var BUNDLED_DATA = {
5422
5430
  {#if empty}
5423
5431
  {@render empty({ query: value })}
5424
5432
  {:else}
5425
- No results.
5433
+ {noResultsText}
5426
5434
  {/if}
5427
5435
  </li>
5428
5436
  {/if}
@@ -6060,7 +6068,8 @@ var BUNDLED_DATA = {
6060
6068
  mergeAttrs(
6061
6069
  labelAttrs({ label: ariaLabel, labelledby: ariaLabelledby, describedby: ariaDescribedby }),
6062
6070
  interactiveStateAttrs({
6063
- disabled
6071
+ disabled,
6072
+ checked: indeterminate ? 'mixed' : undefined
6064
6073
  }),
6065
6074
  validationAttrs({
6066
6075
  invalid: ariaInvalid === 'false' ? false : ariaInvalid === 'true' ? true : ariaInvalid,
@@ -6135,6 +6144,8 @@ var BUNDLED_DATA = {
6135
6144
  swatchClass?: string;
6136
6145
  'aria-label'?: string;
6137
6146
  'aria-labelledby'?: string;
6147
+ swatchesLabel?: string;
6148
+ nativeInputLabel?: string;
6138
6149
  onChange?: (value: string) => void;
6139
6150
  }
6140
6151
 
@@ -6151,6 +6162,8 @@ var BUNDLED_DATA = {
6151
6162
  swatchClass = '',
6152
6163
  'aria-label': ariaLabel = 'Color',
6153
6164
  'aria-labelledby': ariaLabelledby,
6165
+ swatchesLabel = 'Color swatches',
6166
+ nativeInputLabel = 'Color',
6154
6167
  onChange
6155
6168
  }: Props = $props();
6156
6169
 
@@ -6234,7 +6247,7 @@ var BUNDLED_DATA = {
6234
6247
  {#if showNative}
6235
6248
  <input
6236
6249
  type="color"
6237
- aria-label={\`\${ariaLabel} picker\`}
6250
+ aria-label={nativeInputLabel}
6238
6251
  {disabled}
6239
6252
  {value}
6240
6253
  class={nativeClass}
@@ -6258,7 +6271,7 @@ var BUNDLED_DATA = {
6258
6271
  class={swatchesClass}
6259
6272
  role="listbox"
6260
6273
  tabindex="-1"
6261
- aria-label="Color swatches"
6274
+ aria-label={swatchesLabel}
6262
6275
  bind:this={swatchListEl}
6263
6276
  onkeydown={onSwatchKeydown}
6264
6277
  >
@@ -7010,6 +7023,8 @@ var BUNDLED_DATA = {
7010
7023
  files?: FileList | null;
7011
7024
  accept?: string;
7012
7025
  multiple?: boolean;
7026
+ capture?: 'user' | 'environment';
7027
+ webkitdirectory?: boolean;
7013
7028
  disabled?: boolean;
7014
7029
  required?: boolean;
7015
7030
  name?: string;
@@ -7028,6 +7043,8 @@ var BUNDLED_DATA = {
7028
7043
  files = $bindable(null),
7029
7044
  accept,
7030
7045
  multiple = false,
7046
+ capture,
7047
+ webkitdirectory,
7031
7048
  disabled = false,
7032
7049
  required = false,
7033
7050
  name,
@@ -7069,6 +7086,8 @@ var BUNDLED_DATA = {
7069
7086
  {name}
7070
7087
  {accept}
7071
7088
  {multiple}
7089
+ {capture}
7090
+ {webkitdirectory}
7072
7091
  {disabled}
7073
7092
  {required}
7074
7093
  class="sr-only"
@@ -7084,6 +7103,8 @@ var BUNDLED_DATA = {
7084
7103
  {name}
7085
7104
  {accept}
7086
7105
  {multiple}
7106
+ {capture}
7107
+ {webkitdirectory}
7087
7108
  {disabled}
7088
7109
  {required}
7089
7110
  class={className}
@@ -7274,6 +7295,10 @@ var BUNDLED_DATA = {
7274
7295
  'aria-required'?: AriaBoolean;
7275
7296
  'aria-errormessage'?: string;
7276
7297
  tabindex?: number;
7298
+ autofocus?: boolean;
7299
+ spellcheck?: boolean;
7300
+ enterkeyhint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';
7301
+ list?: string;
7277
7302
  }
7278
7303
 
7279
7304
  let {
@@ -7306,7 +7331,11 @@ var BUNDLED_DATA = {
7306
7331
  'aria-invalid': ariaInvalid,
7307
7332
  'aria-required': ariaRequired,
7308
7333
  'aria-errormessage': ariaErrormessage,
7309
- tabindex
7334
+ tabindex,
7335
+ autofocus,
7336
+ spellcheck,
7337
+ enterkeyhint,
7338
+ list
7310
7339
  }: Props = $props();
7311
7340
 
7312
7341
  // Build ARIA attributes using reusable utilities
@@ -7324,6 +7353,7 @@ var BUNDLED_DATA = {
7324
7353
  );
7325
7354
  </script>
7326
7355
 
7356
+ <!-- svelte-ignore a11y_autofocus -->
7327
7357
  <input
7328
7358
  {type}
7329
7359
  {placeholder}
@@ -7349,6 +7379,10 @@ var BUNDLED_DATA = {
7349
7379
  {onkeydown}
7350
7380
  {onkeyup}
7351
7381
  {tabindex}
7382
+ {autofocus}
7383
+ {spellcheck}
7384
+ {enterkeyhint}
7385
+ {list}
7352
7386
  {...ariaAttrs}
7353
7387
  />
7354
7388
  `,
@@ -7480,6 +7514,7 @@ var BUNDLED_DATA = {
7480
7514
  'aria-errormessage'?: string;
7481
7515
  oninput?: (event: Event) => void;
7482
7516
  onchange?: (value: number | null) => void;
7517
+ autofocus?: boolean;
7483
7518
  }
7484
7519
 
7485
7520
  let {
@@ -7504,7 +7539,8 @@ var BUNDLED_DATA = {
7504
7539
  'aria-invalid': ariaInvalid,
7505
7540
  'aria-errormessage': ariaErrormessage,
7506
7541
  oninput,
7507
- onchange
7542
+ onchange,
7543
+ autofocus
7508
7544
  }: Props = $props();
7509
7545
 
7510
7546
  let ariaAttrs: Record<string, string> = $derived(
@@ -7554,6 +7590,7 @@ var BUNDLED_DATA = {
7554
7590
  >
7555
7591
  \u2212
7556
7592
  </button>
7593
+ <!-- svelte-ignore a11y_autofocus -->
7557
7594
  <input
7558
7595
  type="number"
7559
7596
  {id}
@@ -7565,6 +7602,8 @@ var BUNDLED_DATA = {
7565
7602
  {readonly}
7566
7603
  {required}
7567
7604
  {placeholder}
7605
+ inputmode="numeric"
7606
+ {autofocus}
7568
7607
  value={value ?? ''}
7569
7608
  class={inputClass}
7570
7609
  oninput={handleInput}
@@ -8062,7 +8101,7 @@ var BUNDLED_DATA = {
8062
8101
  let highlighted = $state<unknown>(undefined);
8063
8102
  let triggerEl = $state<HTMLElement | null>(null);
8064
8103
  let contentEl = $state<HTMLElement | null>(null);
8065
- let opts = $state<SelectOptionEntry[]>([]);
8104
+ let opts: SelectOptionEntry[] = [];
8066
8105
 
8067
8106
  const triggerId = generateCounterId('select-trigger');
8068
8107
  const contentId = generateCounterId('select-content');
@@ -8145,7 +8184,7 @@ var BUNDLED_DATA = {
8145
8184
 
8146
8185
  {#if children}{@render children()}{/if}
8147
8186
  `,
8148
- "SelectContent.svelte": "<script lang=\"ts\">\n import type { Attachment } from 'svelte/attachments';\n import { computePosition, autoUpdate, flip, shift, offset, size } from '@floating-ui/dom';\n import { getSelectContext } from './Select.svelte';\n import Portal from '../../utility/portal/Portal.svelte';\n\n interface Props {\n children?: import('svelte').Snippet;\n class?: string;\n placement?: 'top' | 'bottom' | 'top-start' | 'bottom-start' | 'top-end' | 'bottom-end';\n offset?: number;\n sameWidth?: boolean;\n }\n\n let {\n children,\n class: className = '',\n placement = 'bottom-start',\n offset: offsetPx = 4,\n sameWidth = true\n }: Props = $props();\n\n const ctx = getSelectContext();\n\n const contentRef: Attachment<HTMLDivElement> = (node) => {\n ctx.setContentEl(node);\n\n const trigger = ctx.triggerEl.current;\n let cleanupAutoUpdate: (() => void) | undefined;\n\n if (trigger) {\n cleanupAutoUpdate = autoUpdate(trigger, node, async () => {\n const { x, y } = await computePosition(trigger, node, {\n placement,\n strategy: 'fixed',\n middleware: [\n offset(offsetPx),\n flip(),\n shift({ padding: 8 }),\n size({\n apply({ rects, elements }) {\n if (sameWidth) {\n Object.assign(elements.floating.style, {\n minWidth: `${rects.reference.width}px`\n });\n }\n }\n })\n ]\n });\n Object.assign(node.style, {\n left: `${x}px`,\n top: `${y}px`\n });\n });\n }\n\n function onPointerDown(e: PointerEvent) {\n const t = e.target as Node;\n if (node.contains(t) || ctx.triggerEl.current?.contains(t)) return;\n ctx.setOpen(false);\n }\n\n document.addEventListener('pointerdown', onPointerDown, true);\n\n queueMicrotask(() => node.focus());\n\n return () => {\n cleanupAutoUpdate?.();\n document.removeEventListener('pointerdown', onPointerDown, true);\n ctx.setContentEl(null);\n ctx.triggerEl.current?.focus();\n };\n };\n\n function move(dir: 1 | -1) {\n const opts = ctx.options().filter((o) => !o.disabled);\n if (opts.length === 0) return;\n const cur = opts.findIndex((o) => o.value === ctx.highlighted());\n let next: number;\n if (cur === -1) next = dir === 1 ? 0 : opts.length - 1;\n else next = (cur + dir + opts.length) % opts.length;\n ctx.setHighlighted(opts[next].value);\n opts[next].el.scrollIntoView({ block: 'nearest' });\n }\n\n function onKeydown(e: KeyboardEvent) {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n move(1);\n break;\n case 'ArrowUp':\n e.preventDefault();\n move(-1);\n break;\n case 'Home': {\n e.preventDefault();\n const opts = ctx.options().filter((o) => !o.disabled);\n if (opts[0]) {\n ctx.setHighlighted(opts[0].value);\n opts[0].el.scrollIntoView({ block: 'nearest' });\n }\n break;\n }\n case 'End': {\n e.preventDefault();\n const opts = ctx.options().filter((o) => !o.disabled);\n const last = opts.at(-1);\n if (last) {\n ctx.setHighlighted(last.value);\n last.el.scrollIntoView({ block: 'nearest' });\n }\n break;\n }\n case 'Enter':\n case ' ': {\n e.preventDefault();\n const h = ctx.highlighted();\n if (h !== undefined) ctx.toggleValue(h);\n break;\n }\n case 'Escape':\n e.preventDefault();\n ctx.setOpen(false);\n break;\n case 'Tab':\n ctx.setOpen(false);\n break;\n }\n }\n\n let activeId = $derived.by(() => {\n const opts = ctx.options();\n const found = opts.find((o) => o.value === ctx.highlighted());\n return found?.el.id;\n });\n</script>\n\n{#if ctx.open()}\n <Portal>\n <div\n id={ctx.contentId}\n role=\"listbox\"\n tabindex=\"-1\"\n aria-labelledby={ctx.labelId() ?? ctx.triggerId}\n aria-multiselectable={ctx.multiple() ? true : undefined}\n aria-activedescendant={activeId}\n class={className}\n style=\"position:fixed; top:0; left:0;\"\n onkeydown={onKeydown}\n {@attach contentRef}\n >\n {#if children}{@render children()}{/if}\n </div>\n </Portal>\n{/if}\n",
8187
+ "SelectContent.svelte": "<script lang=\"ts\">\n import type { Attachment } from 'svelte/attachments';\n import { computePosition, autoUpdate, flip, shift, offset, size } from '@floating-ui/dom';\n import { getSelectContext } from './Select.svelte';\n import Portal from '../../utility/portal/Portal.svelte';\n\n interface Props {\n children?: import('svelte').Snippet;\n class?: string;\n placement?: 'top' | 'bottom' | 'top-start' | 'bottom-start' | 'top-end' | 'bottom-end';\n offset?: number;\n sameWidth?: boolean;\n }\n\n let {\n children,\n class: className = '',\n placement = 'bottom-start',\n offset: offsetPx = 4,\n sameWidth = true\n }: Props = $props();\n\n const ctx = getSelectContext();\n\n const contentRef: Attachment<HTMLDivElement> = (node) => {\n ctx.setContentEl(node);\n\n const trigger = ctx.triggerEl.current;\n let cleanupAutoUpdate: (() => void) | undefined;\n\n if (trigger) {\n cleanupAutoUpdate = autoUpdate(trigger, node, async () => {\n const { x, y } = await computePosition(trigger, node, {\n placement,\n strategy: 'fixed',\n middleware: [\n offset(offsetPx),\n flip(),\n shift({ padding: 8 }),\n size({\n apply({ rects, elements }) {\n if (sameWidth) {\n Object.assign(elements.floating.style, {\n minWidth: `${rects.reference.width}px`\n });\n }\n }\n })\n ]\n });\n Object.assign(node.style, {\n left: `${x}px`,\n top: `${y}px`\n });\n });\n }\n\n function onPointerDown(e: PointerEvent) {\n const t = e.target as Node;\n if (node.contains(t) || ctx.triggerEl.current?.contains(t)) return;\n ctx.setOpen(false);\n }\n\n document.addEventListener('pointerdown', onPointerDown, true);\n\n queueMicrotask(() => node.focus());\n\n return () => {\n cleanupAutoUpdate?.();\n document.removeEventListener('pointerdown', onPointerDown, true);\n ctx.setContentEl(null);\n ctx.triggerEl.current?.focus();\n };\n };\n\n function move(dir: 1 | -1) {\n const opts = ctx.options().filter((o) => !o.disabled);\n if (opts.length === 0) return;\n const cur = opts.findIndex((o) => o.value === ctx.highlighted());\n let next: number;\n if (cur === -1) next = dir === 1 ? 0 : opts.length - 1;\n else next = (cur + dir + opts.length) % opts.length;\n ctx.setHighlighted(opts[next].value);\n opts[next].el.scrollIntoView({ block: 'nearest' });\n }\n\n function onKeydown(e: KeyboardEvent) {\n // type-ahead: first-char match, wraps from current position\n const char = e.key.length === 1 ? e.key.toLowerCase() : '';\n if (char) {\n e.preventDefault();\n const opts = ctx.options().filter((o) => !o.disabled);\n const cur = opts.findIndex((o) => o.value === ctx.highlighted());\n const after = [...opts.slice(cur + 1), ...opts.slice(0, cur + 1)];\n const match = after.find((o) => o.el.textContent?.trim().toLowerCase().startsWith(char));\n if (match) {\n ctx.setHighlighted(match.value);\n match.el.scrollIntoView({ block: 'nearest' });\n }\n return;\n }\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n move(1);\n break;\n case 'ArrowUp':\n e.preventDefault();\n move(-1);\n break;\n case 'Home': {\n e.preventDefault();\n const opts = ctx.options().filter((o) => !o.disabled);\n if (opts[0]) {\n ctx.setHighlighted(opts[0].value);\n opts[0].el.scrollIntoView({ block: 'nearest' });\n }\n break;\n }\n case 'End': {\n e.preventDefault();\n const opts = ctx.options().filter((o) => !o.disabled);\n const last = opts.at(-1);\n if (last) {\n ctx.setHighlighted(last.value);\n last.el.scrollIntoView({ block: 'nearest' });\n }\n break;\n }\n case 'Enter':\n case ' ': {\n e.preventDefault();\n const h = ctx.highlighted();\n if (h !== undefined) ctx.toggleValue(h);\n break;\n }\n case 'Escape':\n e.preventDefault();\n ctx.setOpen(false);\n break;\n case 'Tab':\n ctx.setOpen(false);\n break;\n }\n }\n\n let activeId = $derived.by(() => {\n const opts = ctx.options();\n const found = opts.find((o) => o.value === ctx.highlighted());\n return found?.el.id;\n });\n</script>\n\n{#if ctx.open()}\n <Portal>\n <div\n id={ctx.contentId}\n role=\"listbox\"\n tabindex=\"-1\"\n aria-labelledby={ctx.labelId() ?? ctx.triggerId}\n aria-multiselectable={ctx.multiple() ? true : undefined}\n aria-activedescendant={activeId}\n class={className}\n style=\"position:fixed; top:0; left:0;\"\n onkeydown={onKeydown}\n {@attach contentRef}\n >\n {#if children}{@render children()}{/if}\n </div>\n </Portal>\n{/if}\n",
8149
8188
  "SelectOption.svelte": `<script lang="ts">
8150
8189
  import type { Attachment } from 'svelte/attachments';
8151
8190
  import { generateCounterId } from '$utils/a11y/id.js';
@@ -8310,6 +8349,7 @@ var BUNDLED_DATA = {
8310
8349
  'aria-valuetext'?: string;
8311
8350
  oninput?: (event: Event) => void;
8312
8351
  onchange?: (event: Event) => void;
8352
+ onkeydown?: (event: KeyboardEvent) => void;
8313
8353
  }
8314
8354
 
8315
8355
  let {
@@ -8328,9 +8368,12 @@ var BUNDLED_DATA = {
8328
8368
  'aria-describedby': ariaDescribedby,
8329
8369
  'aria-valuetext': ariaValuetext,
8330
8370
  oninput,
8331
- onchange
8371
+ onchange,
8372
+ onkeydown
8332
8373
  }: Props = $props();
8333
8374
 
8375
+ let pageStep = $derived(Math.max(1, Math.round((max - min) / 10)));
8376
+
8334
8377
  let ariaAttrs: Record<string, string> = $derived(
8335
8378
  mergeAttrs(
8336
8379
  labelAttrs({ label: ariaLabel, labelledby: ariaLabelledby, describedby: ariaDescribedby }),
@@ -8345,6 +8388,17 @@ var BUNDLED_DATA = {
8345
8388
  })
8346
8389
  )
8347
8390
  );
8391
+
8392
+ function handleKeydown(e: KeyboardEvent) {
8393
+ if (e.key === 'PageUp') {
8394
+ e.preventDefault();
8395
+ value = Math.min(max, value + pageStep);
8396
+ } else if (e.key === 'PageDown') {
8397
+ e.preventDefault();
8398
+ value = Math.max(min, value - pageStep);
8399
+ }
8400
+ onkeydown?.(e);
8401
+ }
8348
8402
  </script>
8349
8403
 
8350
8404
  <input
@@ -8360,6 +8414,7 @@ var BUNDLED_DATA = {
8360
8414
  class={className}
8361
8415
  {oninput}
8362
8416
  {onchange}
8417
+ onkeydown={handleKeydown}
8363
8418
  {...ariaAttrs}
8364
8419
  />
8365
8420
  `,
@@ -8462,7 +8517,7 @@ var BUNDLED_DATA = {
8462
8517
  "category": "form",
8463
8518
  "slug": "textarea",
8464
8519
  "files": {
8465
- "Textarea.svelte": "<script lang=\"ts\">\n import { labelAttrs, validationAttrs, mergeAttrs } from '$utils/a11y/index.js';\n import type { AriaBoolean } from '$types/index.js';\n\n interface Props {\n value?: string;\n placeholder?: string;\n class?: string;\n disabled?: boolean;\n readonly?: boolean;\n required?: boolean;\n name?: string;\n id?: string;\n rows?: number;\n cols?: number;\n minlength?: number;\n maxlength?: number;\n wrap?: 'hard' | 'soft' | 'off';\n autocomplete?: 'on' | 'off';\n resize?: 'none' | 'both' | 'horizontal' | 'vertical';\n oninput?: (event: Event) => void;\n onchange?: (event: Event) => void;\n onfocus?: (event: FocusEvent) => void;\n onblur?: (event: FocusEvent) => void;\n onkeydown?: (event: KeyboardEvent) => void;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'aria-invalid'?: AriaBoolean;\n 'aria-required'?: AriaBoolean;\n 'aria-errormessage'?: string;\n tabindex?: number;\n }\n\n let {\n value = $bindable(''),\n placeholder = '',\n class: className = '',\n disabled = false,\n readonly = false,\n required = false,\n name,\n id,\n rows,\n cols,\n minlength,\n maxlength,\n wrap,\n autocomplete,\n resize,\n oninput,\n onchange,\n onfocus,\n onblur,\n onkeydown,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n 'aria-describedby': ariaDescribedby,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-errormessage': ariaErrormessage,\n tabindex\n }: Props = $props();\n\n let ariaAttrs: Record<string, string> = $derived(\n mergeAttrs(\n labelAttrs({ label: ariaLabel, labelledby: ariaLabelledby, describedby: ariaDescribedby }),\n validationAttrs({\n invalid: ariaInvalid === 'false' ? false : ariaInvalid === 'true' ? true : ariaInvalid,\n required:\n (ariaRequired === 'false' ? false : ariaRequired === 'true' ? true : ariaRequired) ??\n required,\n errormessage: ariaErrormessage\n })\n )\n );\n\n let style = $derived(resize ? `resize:${resize};` : undefined);\n</script>\n\n<textarea\n bind:value\n {placeholder}\n {disabled}\n {readonly}\n {required}\n {name}\n {id}\n {rows}\n {cols}\n {minlength}\n {maxlength}\n {wrap}\n {autocomplete}\n {style}\n class={className}\n {oninput}\n {onchange}\n {onfocus}\n {onblur}\n {onkeydown}\n {tabindex}\n {...ariaAttrs}\n></textarea>\n",
8520
+ "Textarea.svelte": "<script lang=\"ts\">\n import { labelAttrs, validationAttrs, mergeAttrs } from '$utils/a11y/index.js';\n import type { AriaBoolean } from '$types/index.js';\n\n interface Props {\n value?: string;\n placeholder?: string;\n class?: string;\n disabled?: boolean;\n readonly?: boolean;\n required?: boolean;\n name?: string;\n id?: string;\n rows?: number;\n cols?: number;\n minlength?: number;\n maxlength?: number;\n wrap?: 'hard' | 'soft' | 'off';\n autocomplete?: 'on' | 'off';\n resize?: 'none' | 'both' | 'horizontal' | 'vertical';\n oninput?: (event: Event) => void;\n onchange?: (event: Event) => void;\n onfocus?: (event: FocusEvent) => void;\n onblur?: (event: FocusEvent) => void;\n onkeydown?: (event: KeyboardEvent) => void;\n 'aria-label'?: string;\n 'aria-labelledby'?: string;\n 'aria-describedby'?: string;\n 'aria-invalid'?: AriaBoolean;\n 'aria-required'?: AriaBoolean;\n 'aria-errormessage'?: string;\n tabindex?: number;\n autofocus?: boolean;\n spellcheck?: boolean;\n enterkeyhint?: 'enter' | 'done' | 'go' | 'next' | 'previous' | 'search' | 'send';\n }\n\n let {\n value = $bindable(''),\n placeholder = '',\n class: className = '',\n disabled = false,\n readonly = false,\n required = false,\n name,\n id,\n rows,\n cols,\n minlength,\n maxlength,\n wrap,\n autocomplete,\n resize,\n oninput,\n onchange,\n onfocus,\n onblur,\n onkeydown,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n 'aria-describedby': ariaDescribedby,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n 'aria-errormessage': ariaErrormessage,\n tabindex,\n autofocus,\n spellcheck,\n enterkeyhint\n }: Props = $props();\n\n let ariaAttrs: Record<string, string> = $derived(\n mergeAttrs(\n labelAttrs({ label: ariaLabel, labelledby: ariaLabelledby, describedby: ariaDescribedby }),\n validationAttrs({\n invalid: ariaInvalid === 'false' ? false : ariaInvalid === 'true' ? true : ariaInvalid,\n required:\n (ariaRequired === 'false' ? false : ariaRequired === 'true' ? true : ariaRequired) ??\n required,\n errormessage: ariaErrormessage\n })\n )\n );\n\n let style = $derived(resize ? `resize:${resize};` : undefined);\n</script>\n\n<!-- svelte-ignore a11y_autofocus -->\n<textarea\n bind:value\n {placeholder}\n {disabled}\n {readonly}\n {required}\n {name}\n {id}\n {rows}\n {cols}\n {minlength}\n {maxlength}\n {wrap}\n {autocomplete}\n {style}\n class={className}\n {oninput}\n {onchange}\n {onfocus}\n {onblur}\n {onkeydown}\n {tabindex}\n {autofocus}\n {spellcheck}\n {enterkeyhint}\n {...ariaAttrs}\n></textarea>\n",
8466
8521
  "index.ts": "export { default as Textarea } from './Textarea.svelte';\n"
8467
8522
  }
8468
8523
  },
@@ -8993,9 +9048,9 @@ var BUNDLED_DATA = {
8993
9048
  let { children, class: className = '' }: Props = $props();
8994
9049
  </script>
8995
9050
 
8996
- <li class={className} aria-hidden="true" role="presentation">
9051
+ <span aria-hidden="true" class={className}>
8997
9052
  {#if children}{@render children()}{:else}/{/if}
8998
- </li>
9053
+ </span>
8999
9054
  `,
9000
9055
  "index.ts": "export { default as Breadcrumb } from './Breadcrumb.svelte';\nexport { default as BreadcrumbItem } from './BreadcrumbItem.svelte';\nexport { default as BreadcrumbSeparator } from './BreadcrumbSeparator.svelte';\n"
9001
9056
  }
@@ -9642,9 +9697,18 @@ var BUNDLED_DATA = {
9642
9697
  class?: string;
9643
9698
  disabled?: boolean;
9644
9699
  onSelect?: () => void;
9700
+ role?: 'menuitem' | 'menuitemcheckbox' | 'menuitemradio';
9701
+ checked?: boolean;
9645
9702
  }
9646
9703
 
9647
- let { children, class: className = '', disabled = false, onSelect }: Props = $props();
9704
+ let {
9705
+ children,
9706
+ class: className = '',
9707
+ disabled = false,
9708
+ onSelect,
9709
+ role = 'menuitem',
9710
+ checked
9711
+ }: Props = $props();
9648
9712
 
9649
9713
  const ctx = getMenuContext();
9650
9714
 
@@ -9681,10 +9745,17 @@ var BUNDLED_DATA = {
9681
9745
  activate();
9682
9746
  }
9683
9747
  }
9748
+
9749
+ const ariaAttrs = $derived(
9750
+ interactiveStateAttrs({
9751
+ disabled,
9752
+ checked: role === 'menuitemcheckbox' || role === 'menuitemradio' ? checked : undefined
9753
+ })
9754
+ );
9684
9755
  </script>
9685
9756
 
9686
9757
  <div
9687
- role="menuitem"
9758
+ {role}
9688
9759
  tabindex="-1"
9689
9760
  data-highlighted={highlighted || undefined}
9690
9761
  data-disabled={disabled || undefined}
@@ -9692,7 +9763,7 @@ var BUNDLED_DATA = {
9692
9763
  onclick={activate}
9693
9764
  onpointerenter={onPointerEnter}
9694
9765
  onkeydown={onKeydown}
9695
- {...interactiveStateAttrs({ disabled })}
9766
+ {...ariaAttrs}
9696
9767
  {@attach itemRef}
9697
9768
  >
9698
9769
  {#if children}{@render children({ highlighted })}{/if}
@@ -9819,6 +9890,7 @@ var BUNDLED_DATA = {
9819
9890
  next: () => void;
9820
9891
  canPrev: boolean;
9821
9892
  canNext: boolean;
9893
+ isCurrentPage: (p: number) => boolean;
9822
9894
  }
9823
9895
  ]
9824
9896
  >;
@@ -9888,7 +9960,17 @@ var BUNDLED_DATA = {
9888
9960
 
9889
9961
  <nav class={className} aria-label={ariaLabel}>
9890
9962
  {#if children}
9891
- {@render children({ page, totalPages, pages, goto, prev, next, canPrev, canNext })}
9963
+ {@render children({
9964
+ page,
9965
+ totalPages,
9966
+ pages,
9967
+ goto,
9968
+ prev,
9969
+ next,
9970
+ canPrev,
9971
+ canNext,
9972
+ isCurrentPage: (p) => p === page
9973
+ })}
9892
9974
  {/if}
9893
9975
  </nav>
9894
9976
  `,
@@ -9965,7 +10047,12 @@ var BUNDLED_DATA = {
9965
10047
  let ariaAttrs: Record<string, string> = $derived(
9966
10048
  mergeAttrs(
9967
10049
  labelAttrs({ label: ariaLabel, labelledby: ariaLabelledby }),
9968
- widgetAttrs({ orientation })
10050
+ widgetAttrs({
10051
+ orientation,
10052
+ valuenow: current + 1,
10053
+ valuemin: 1,
10054
+ valuemax: total
10055
+ })
9969
10056
  )
9970
10057
  );
9971
10058
  </script>
@@ -10436,6 +10523,7 @@ var BUNDLED_DATA = {
10436
10523
  <div
10437
10524
  {role}
10438
10525
  aria-live={role === 'alert' ? 'assertive' : 'polite'}
10526
+ aria-atomic="true"
10439
10527
  data-variant={variant}
10440
10528
  class={className}
10441
10529
  {...ariaAttrs}
@@ -10868,7 +10956,7 @@ var BUNDLED_DATA = {
10868
10956
  class: className = '',
10869
10957
  indicatorClass = '',
10870
10958
  id,
10871
- 'aria-label': ariaLabel,
10959
+ 'aria-label': ariaLabel = 'Progress',
10872
10960
  'aria-labelledby': ariaLabelledby,
10873
10961
  'aria-describedby': ariaDescribedby
10874
10962
  }: Props = $props();
@@ -11682,6 +11770,7 @@ var BUNDLED_DATA = {
11682
11770
  `,
11683
11771
  "CarouselSlides.svelte": `<script lang="ts">
11684
11772
  import { getCarouselContext } from './Carousel.svelte';
11773
+ import { VisuallyHidden } from '$components/utility/visually-hidden/index.js';
11685
11774
 
11686
11775
  interface Props {
11687
11776
  children?: import('svelte').Snippet;
@@ -11693,6 +11782,12 @@ var BUNDLED_DATA = {
11693
11782
  const ctx = getCarouselContext();
11694
11783
  </script>
11695
11784
 
11785
+ <VisuallyHidden as="div">
11786
+ <span aria-live="polite" aria-atomic="true">
11787
+ Slide {ctx.index() + 1} of {ctx.count()}
11788
+ </span>
11789
+ </VisuallyHidden>
11790
+
11696
11791
  <div id={ctx.slidesId} class={className} aria-live={live} aria-atomic="false">
11697
11792
  {#if children}{@render children()}{/if}
11698
11793
  </div>
@@ -12284,6 +12379,19 @@ var BUNDLED_DATA = {
12284
12379
  const expanded = $derived(ctx.isExpanded(id));
12285
12380
  const selected = $derived(ctx.isSelected(id));
12286
12381
  let itemEl = $state<HTMLLIElement | null>(null);
12382
+ let setsize = $state(1);
12383
+ let posinset = $state(1);
12384
+
12385
+ $effect(() => {
12386
+ if (!itemEl) return;
12387
+ const parent = itemEl.parentElement;
12388
+ if (!parent) return;
12389
+ const siblings = Array.from(parent.children).filter(
12390
+ (c) => c.getAttribute('role') === 'treeitem'
12391
+ );
12392
+ setsize = siblings.length;
12393
+ posinset = siblings.indexOf(itemEl) + 1;
12394
+ });
12287
12395
 
12288
12396
  function onClick(e: MouseEvent) {
12289
12397
  if (disabled) return;
@@ -12321,7 +12429,7 @@ var BUNDLED_DATA = {
12321
12429
  selected: selected || undefined,
12322
12430
  disabled
12323
12431
  }),
12324
- widgetAttrs({ level })
12432
+ widgetAttrs({ level, setsize, posinset })
12325
12433
  )}
12326
12434
  >
12327
12435
  {#if label}{@render label({ expanded, selected })}{/if}
@@ -28346,7 +28454,7 @@ sum(1, 2);\`;
28346
28454
  </main>
28347
28455
  `
28348
28456
  },
28349
- generated_at: "2026-05-31T14:52:05.218Z"
28457
+ generated_at: "2026-06-20T14:48:51.850Z"
28350
28458
  };
28351
28459
 
28352
28460
  // ../mcp-server/src/lib/fs.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alus-ui-mcp",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "MCP stdio server for the alus-ui Svelte 5 component library — gives LLMs direct access to component source, demos, exports, and utilities",
5
5
  "license": "MIT",
6
6
  "type": "module",