@astryxdesign/core 0.6.2-canary.7f5bd12 → 0.6.2-canary.8112fcc

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.
@@ -1,8 +1,7 @@
1
1
  /**
2
2
  * @file InputClearButton.tsx
3
- * @input Uses React, Button, and Icon
4
- * @output Exports the public InputClearButton and an internal popup-aware variant,
5
- * both with a contextual tooltip matching their required label.
3
+ * @input Uses React, Button, Icon
4
+ * @output Exports the public InputClearButton and an internal popup-aware variant.
6
5
  * @position Shared primitive. Every input that renders a clear affordance —
7
6
  * TextInput, NumberInput, TimeInput, DateInput, DateTimeInput,
8
7
  * DateRangeInput, Selector, MultiSelector, Typeahead, Tokenizer, FileInput —
@@ -13,7 +12,6 @@
13
12
  import type { ReactNode } from 'react';
14
13
  import * as stylex from '@stylexjs/stylex';
15
14
  export interface InputClearButtonProps {
16
- /** Contextual accessible name for the button, such as "Clear Search". */
17
15
  label: string;
18
16
  onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
19
17
  xstyle?: stylex.StyleXStyles;
@@ -1 +1 @@
1
- {"version":3,"file":"InputClearButton.d.ts","sourceRoot":"","sources":["../../src/Field/InputClearButton.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAkD3C,MAAM,WAAW,qBAAqB;IACpC,yEAAyE;IACzE,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC;IAC7B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,6BAA8B,SAAQ,qBAAqB;IACnE,aAAa,EAAE,KAAK,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;IACtD,cAAc,EAAE,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;CACtD;AAiDD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,SAAS,CAExE;yBAFe,gBAAgB;;;AAIhC,4EAA4E;AAC5E,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,6BAA6B,GACnC,SAAS,CAEX"}
1
+ {"version":3,"file":"InputClearButton.d.ts","sourceRoot":"","sources":["../../src/Field/InputClearButton.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAkD3C,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC;IAC7B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,6BAA8B,SAAQ,qBAAqB;IACnE,aAAa,EAAE,KAAK,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;IACtD,cAAc,EAAE,KAAK,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;CACtD;AAgDD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,SAAS,CAExE;yBAFe,gBAAgB;;;AAIhC,4EAA4E;AAC5E,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,6BAA6B,GACnC,SAAS,CAEX"}
@@ -4,9 +4,8 @@
4
4
 
5
5
  /**
6
6
  * @file InputClearButton.tsx
7
- * @input Uses React, Button, and Icon
8
- * @output Exports the public InputClearButton and an internal popup-aware variant,
9
- * both with a contextual tooltip matching their required label.
7
+ * @input Uses React, Button, Icon
8
+ * @output Exports the public InputClearButton and an internal popup-aware variant.
10
9
  * @position Shared primitive. Every input that renders a clear affordance —
11
10
  * TextInput, NumberInput, TimeInput, DateInput, DateTimeInput,
12
11
  * DateRangeInput, Selector, MultiSelector, Typeahead, Tokenizer, FileInput —
@@ -50,7 +49,6 @@ function renderInputClearButton({
50
49
  variant: "ghost",
51
50
  size: "sm",
52
51
  label: label,
53
- tooltip: label,
54
52
  className: buttonTargetClassName,
55
53
  icon: /*#__PURE__*/_jsx(Icon, {
56
54
  icon: "close",
@@ -341,7 +341,7 @@
341
341
  },
342
342
  "@astryx.checkboxList.item.checkbox": {
343
343
  "defaultMessage": "Merkblokkie",
344
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
344
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
345
345
  },
346
346
  "@astryx.commandPalette.emptySearch": {
347
347
  "defaultMessage": "Geen resultate",
@@ -952,4 +952,3 @@
952
952
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
953
953
  }
954
954
  }
955
-
@@ -365,7 +365,7 @@
365
365
  },
366
366
  "@astryx.checkboxList.item.checkbox": {
367
367
  "defaultMessage": "مربع اختيار",
368
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
368
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
369
369
  },
370
370
  "@astryx.commandPalette.emptySearch": {
371
371
  "defaultMessage": "لا توجد نتائج",
@@ -992,4 +992,3 @@
992
992
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
993
993
  }
994
994
  }
995
-
@@ -357,7 +357,7 @@
357
357
  },
358
358
  "@astryx.checkboxList.item.checkbox": {
359
359
  "defaultMessage": "Casella de selecció",
360
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
360
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
361
361
  },
362
362
  "@astryx.commandPalette.emptySearch": {
363
363
  "defaultMessage": "Cap resultat",
@@ -968,4 +968,3 @@
968
968
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
969
969
  }
970
970
  }
971
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "Zaškrtávací políčko",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "Žádné výsledky",
@@ -984,4 +984,3 @@
984
984
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
985
985
  }
986
986
  }
987
-
@@ -357,7 +357,7 @@
357
357
  },
358
358
  "@astryx.checkboxList.item.checkbox": {
359
359
  "defaultMessage": "Afkrydsningsfelt",
360
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
360
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
361
361
  },
362
362
  "@astryx.commandPalette.emptySearch": {
363
363
  "defaultMessage": "Ingen resultater",
@@ -960,4 +960,3 @@
960
960
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
961
961
  }
962
962
  }
963
-
@@ -357,7 +357,7 @@
357
357
  },
358
358
  "@astryx.checkboxList.item.checkbox": {
359
359
  "defaultMessage": "Kontrollkästchen",
360
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
360
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
361
361
  },
362
362
  "@astryx.commandPalette.emptySearch": {
363
363
  "defaultMessage": "Keine Ergebnisse",
@@ -960,4 +960,3 @@
960
960
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
961
961
  }
962
962
  }
963
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "Πλαίσιο ελέγχου",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "Κανένα αποτέλεσμα",
@@ -984,4 +984,3 @@
984
984
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
985
985
  }
986
986
  }
987
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "Casilla",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "Sin resultados",
@@ -972,4 +972,3 @@
972
972
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
973
973
  }
974
974
  }
975
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "Valintaruutu",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "Ei tuloksia",
@@ -984,4 +984,3 @@
984
984
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
985
985
  }
986
986
  }
987
-
@@ -1,4 +1,8 @@
1
1
  {
2
+ "@astryx.pagination.label": {
3
+ "defaultMessage": "Pagination",
4
+ "description": "Aria label for the pagination navigation region."
5
+ },
2
6
  "@astryx.pagination.previous": {
3
7
  "defaultMessage": "Aller à la page précédente",
4
8
  "description": "Aria label for the previous-page button."
@@ -31,6 +35,10 @@
31
35
  "defaultMessage": "Aller à la page",
32
36
  "description": "Aria label for the editable page/row number box in the input pagination variant. No number — the box holds the value itself."
33
37
  },
38
+ "@astryx.pagination.pageLabel": {
39
+ "defaultMessage": "Page",
40
+ "description": "Visible label before the editable box in the input pagination variant. Example: \"Page [ 1 ] / 10\"."
41
+ },
34
42
  "@astryx.pagination.pageIndicators": {
35
43
  "defaultMessage": "Indicateurs de page",
36
44
  "description": "Aria label for the dots-variant page-indicator group."
@@ -337,7 +345,7 @@
337
345
  },
338
346
  "@astryx.checkboxList.item.checkbox": {
339
347
  "defaultMessage": "Case à cocher",
340
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
348
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
341
349
  },
342
350
  "@astryx.commandPalette.emptySearch": {
343
351
  "defaultMessage": "Aucun résultat",
@@ -940,4 +948,3 @@
940
948
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
941
949
  }
942
950
  }
943
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "תיבת סימון",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "אין תוצאות",
@@ -984,4 +984,3 @@
984
984
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
985
985
  }
986
986
  }
987
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "Jelölőnégyzet",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "Nincs találat",
@@ -984,4 +984,3 @@
984
984
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
985
985
  }
986
986
  }
987
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "Casella di controllo",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "Nessun risultato",
@@ -972,4 +972,3 @@
972
972
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
973
973
  }
974
974
  }
975
-
@@ -365,7 +365,7 @@
365
365
  },
366
366
  "@astryx.checkboxList.item.checkbox": {
367
367
  "defaultMessage": "チェックボックス",
368
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
368
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
369
369
  },
370
370
  "@astryx.commandPalette.emptySearch": {
371
371
  "defaultMessage": "結果がありません",
@@ -992,4 +992,3 @@
992
992
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
993
993
  }
994
994
  }
995
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "체크박스",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "결과 없음",
@@ -984,4 +984,3 @@
984
984
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
985
985
  }
986
986
  }
987
-
@@ -337,7 +337,7 @@
337
337
  },
338
338
  "@astryx.checkboxList.item.checkbox": {
339
339
  "defaultMessage": "Selectievakje",
340
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
340
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
341
341
  },
342
342
  "@astryx.commandPalette.emptySearch": {
343
343
  "defaultMessage": "Geen resultaten",
@@ -948,4 +948,3 @@
948
948
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
949
949
  }
950
950
  }
951
-
@@ -357,7 +357,7 @@
357
357
  },
358
358
  "@astryx.checkboxList.item.checkbox": {
359
359
  "defaultMessage": "Avmerkingsboks",
360
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
360
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
361
361
  },
362
362
  "@astryx.commandPalette.emptySearch": {
363
363
  "defaultMessage": "Ingen resultater",
@@ -972,4 +972,3 @@
972
972
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
973
973
  }
974
974
  }
975
-
@@ -357,7 +357,7 @@
357
357
  },
358
358
  "@astryx.checkboxList.item.checkbox": {
359
359
  "defaultMessage": "Pole wyboru",
360
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
360
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
361
361
  },
362
362
  "@astryx.commandPalette.emptySearch": {
363
363
  "defaultMessage": "Brak wyników",
@@ -976,4 +976,3 @@
976
976
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
977
977
  }
978
978
  }
979
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "Caixa de seleção",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "Nenhum resultado",
@@ -976,4 +976,3 @@
976
976
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
977
977
  }
978
978
  }
979
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "Caixa de verificação",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "Sem resultados",
@@ -976,4 +976,3 @@
976
976
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
977
977
  }
978
978
  }
979
-
@@ -357,7 +357,7 @@
357
357
  },
358
358
  "@astryx.checkboxList.item.checkbox": {
359
359
  "defaultMessage": "Casetă de selectare",
360
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
360
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
361
361
  },
362
362
  "@astryx.commandPalette.emptySearch": {
363
363
  "defaultMessage": "Niciun rezultat",
@@ -976,4 +976,3 @@
976
976
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
977
977
  }
978
978
  }
979
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "Флажок",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "Ничего не найдено",
@@ -984,4 +984,3 @@
984
984
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
985
985
  }
986
986
  }
987
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "Поље за потврду",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "Нема резултата",
@@ -984,4 +984,3 @@
984
984
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
985
985
  }
986
986
  }
987
-
@@ -357,7 +357,7 @@
357
357
  },
358
358
  "@astryx.checkboxList.item.checkbox": {
359
359
  "defaultMessage": "Kryssruta",
360
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
360
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
361
361
  },
362
362
  "@astryx.commandPalette.emptySearch": {
363
363
  "defaultMessage": "Inga resultat",
@@ -980,4 +980,3 @@
980
980
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
981
981
  }
982
982
  }
983
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "Onay kutusu",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "Sonuç yok",
@@ -984,4 +984,3 @@
984
984
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
985
985
  }
986
986
  }
987
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "Прапорець",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "Немає результатів",
@@ -984,4 +984,3 @@
984
984
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
985
985
  }
986
986
  }
987
-
@@ -361,7 +361,7 @@
361
361
  },
362
362
  "@astryx.checkboxList.item.checkbox": {
363
363
  "defaultMessage": "Hộp kiểm",
364
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
364
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
365
365
  },
366
366
  "@astryx.commandPalette.emptySearch": {
367
367
  "defaultMessage": "Không có kết quả",
@@ -980,4 +980,3 @@
980
980
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
981
981
  }
982
982
  }
983
-
@@ -365,7 +365,7 @@
365
365
  },
366
366
  "@astryx.checkboxList.item.checkbox": {
367
367
  "defaultMessage": "复选框",
368
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
368
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
369
369
  },
370
370
  "@astryx.commandPalette.emptySearch": {
371
371
  "defaultMessage": "无结果",
@@ -992,4 +992,3 @@
992
992
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
993
993
  }
994
994
  }
995
-
@@ -365,7 +365,7 @@
365
365
  },
366
366
  "@astryx.checkboxList.item.checkbox": {
367
367
  "defaultMessage": "核取方塊",
368
- "description": "Localized hidden text used internally when a rich visible label names the checkbox through aria-labelledby. It does not become the computed name; callers must provide aria-label when rich content has no text."
368
+ "description": "Screen-reader-only last-ditch fallback name for a checkbox inside a list item when no label is provided. Should almost never render — consumers should supply a real label."
369
369
  },
370
370
  "@astryx.commandPalette.emptySearch": {
371
371
  "defaultMessage": "無結果",
@@ -992,4 +992,3 @@
992
992
  "description": "Screen-reader-only label on the \"×\" on an individual Token/chip. Example: `Remove John Smith`, `Remove Active`. Imperative verb."
993
993
  }
994
994
  }
995
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/core",
3
- "version": "0.6.2-canary.7f5bd12",
3
+ "version": "0.6.2-canary.8112fcc",
4
4
  "displayName": "Astryx Core",
5
5
  "description": "The component library. Accessible, themeable React components with built-in spacing, dark mode, and StyleX styling.",
6
6
  "author": "Meta Open Source",
@@ -687,8 +687,8 @@
687
687
  "react-dom": ">=19.0.0"
688
688
  },
689
689
  "devDependencies": {
690
- "@astryxdesign/a11y-spec": "0.6.2-canary.7f5bd12",
691
- "@astryxdesign/cli": "0.6.2-canary.7f5bd12",
690
+ "@astryxdesign/a11y-spec": "0.6.2-canary.8112fcc",
691
+ "@astryxdesign/cli": "0.6.2-canary.8112fcc",
692
692
  "@babel/cli": "^7.29.7",
693
693
  "@babel/core": "^7.29.7",
694
694
  "@babel/preset-react": "^7.29.7",
@@ -3,11 +3,11 @@ schema_version: 3
3
3
  template_version: 5
4
4
  kind: component
5
5
  id: component:ChatComposerDrawer
6
- authority: current
6
+ authority: draft
7
7
  archive_reason: null
8
8
  superseded_by: null
9
- approved_by: cixzhang
10
- approved_at: 2026-09-21
9
+ approved_by: null
10
+ approved_at: null
11
11
  owners: [cixzhang]
12
12
  review_triggers: [public-api, behavior, layout, theming, accessibility]
13
13
  verified_by:
@@ -24,25 +24,24 @@ architecture:
24
24
  architecture:component-theming-surface,
25
25
  architecture:interaction-modality,
26
26
  architecture:knowledge-contracts,
27
- architecture:public-component-api,
28
27
  ]
29
- contributing: [contributing:api-conventions]
30
- system_specs: [spec:AST-002/DEC-1, spec:AST-002/DEC-2]
28
+ contributing: []
29
+ system_specs: [spec:AST-002, spec:AST-029]
31
30
  ---
32
31
 
33
32
  # ChatComposerDrawer component contract
34
33
 
35
34
  ## Contract at a glance
36
35
 
37
- | Area | Contract |
38
- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
39
- | Public contract | Add one optional `collapsedSummary?: ReactNode` slot, named from the canonical **Collapsed summary** anatomy part, for caller-composed visual content. |
40
- | Behavior | `count` continues to enable the disclosure. Omitting `collapsedSummary` keeps the neutral Badge count plus resolved label; providing it replaces that complete visual summary without changing collapse behavior or naming. |
41
- | End-user impact | People retain the established Badge hierarchy by default. Products that need a quieter or differently composed collapsed row may provide one localized visual summary without weakening disclosure semantics. |
42
- | Builder impact | Existing callsites do not change. A builder choosing the slot owns its visual content and localization, while `label` continues to identify the controlled content for the component-owned accessible name. |
43
- | Compatibility/readiness | Additive and default-preserving. This record is current authority; the slot and its mapped implementation, consumer docs, tests, and rendered evidence have not shipped yet. |
44
- | Review checks | Reject a plain-text default, a second summary API, custom content that changes naming or collapse state, reachable interactive descendants inside the visual summary, or any regression to the no-slot and no-count paths. |
45
- | Governing rules | `component:ChatComposerDrawer/FR1–FR10, AR1–AR4, DEC-1–DEC-2`; `architecture:public-component-api/INV3–INV4, INV9, INV13`; `spec:AST-002/DEC-1, DEC-2`. |
36
+ | Area | Contract |
37
+ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
38
+ | Public contract | No API or default change. ChatComposerDrawer remains a required-content panel whose optional `count` enables a controlled or uncontrolled disclosure. |
39
+ | Behavior | The disclosure reports expanded state and its controlled region, preserves mounted content for animation, and makes collapsed descendants unavailable to keyboard and assistive-technology navigation. |
40
+ | End-user impact | Keyboard and screen-reader users do not enter visually hidden drawer actions, and keyboard focus remains visible on the disclosure control. |
41
+ | Builder impact | None. Existing props, defaults, exports, child composition, and callback values remain unchanged. |
42
+ | Compatibility/readiness | Patch-compatible accessibility correction to released behavior. This observational record remains draft; collapsed-summary representation is not decided here. |
43
+ | Review checks | Reject hidden focusable descendants, an invisible disclosure focus state, broken `aria-controls`, changed callback values, or any claim that the collapsed-summary representation is settled. |
44
+ | Governing rules | `architecture:interaction-modality/INV1–INV4, INV9`; `architecture:knowledge-contracts/INV11, INV16`; `spec:AST-002/FR14, FR19`; WCAG 2.4.3 and 2.4.7. |
46
45
 
47
46
  This table is a review projection; the body below is authoritative.
48
47
 
@@ -52,216 +51,113 @@ ChatComposerDrawer composes supplementary content above ChatComposer input. When
52
51
  `count` is present, builders may let people collapse that content while keeping a
53
52
  compact summary available.
54
53
 
55
- Two otherwise identical drawers may need different visual hierarchy in the
56
- collapsed state. The product builder knows whether the established count Badge or
57
- a quieter, product-specific summary fits that context, and ChatComposerDrawer
58
- cannot derive that distinction from count, content, layout, locale, or collapse
59
- state. The component therefore exposes one visual composition seam while retaining
60
- its existing default and owning all disclosure behavior.
61
-
62
54
  ## Compatibility and migration
63
55
 
64
- - Released default preserved: yes. Omitting `collapsedSummary` keeps the neutral
65
- count Badge followed by the resolved label.
66
- - Compatibility class: additive optional composition slot with no default change.
67
- - Controlled/uncontrolled behavior: unchanged.
68
- - Migration decision: none. Existing callsites require no edits.
69
-
70
- Consumer migration instructions belong in consumer docs and release notes.
56
+ - Released default preserved: yes
57
+ - Compatibility class: patch-compatible behavior correction; no public type or default changes
58
+ - Controlled/uncontrolled behavior: unchanged
59
+ - Migration decision: none
71
60
 
72
61
  ## Ownership boundary
73
62
 
74
63
  **Owns**
75
64
 
76
- - The drawer surface, optional disclosure state, disclosure association, and
77
- availability of collapsed descendants.
65
+ - The drawer surface, optional disclosure state, disclosure association, and availability of collapsed descendants.
78
66
  - Controlled and uncontrolled collapse requests.
79
- - The Badge-preserving default summary and the presentation-only boundary for one
80
- caller-composed collapsed summary.
81
- - The disclosure's localized accessible name, independently of visual summary
82
- content.
83
67
 
84
68
  **Does not own / non-goals**
85
69
 
86
- - The meaning, styling, or localization of caller-provided drawer children or custom
87
- summary content.
88
- - Interactive behavior inside the custom summary; the summary is visual-only and
89
- never creates another focus or activation target.
70
+ - The meaning or behavior of arbitrary caller children.
90
71
  - ChatComposer input, submission, status, and action behavior.
91
- - A presentation enum, Badge toggle, render callback, summary-specific theme target,
92
- or a second accessible-name prop.
72
+ - The final visual representation of the collapsed count-and-label summary; this draft records only shipped observation.
93
73
 
94
74
  ## Public concepts
95
75
 
96
- | Concept | Closed values or states | Meaning | Availability by state | Default | Owner | Stability | Invalid-value behavior |
97
- | ----------------- | -------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------- | ------------------------ | ------------------------------ | ------------------- | ------------------------------------------------------------------ |
98
- | drawer content | any React node | Supplementary content composed above the chat input. | always | none | `component:ChatComposerDrawer` | stable | Missing content is rejected by the required type. |
99
- | collapse support | unavailable, expanded, collapsed | Presence of `count`, including zero, enables one disclosure and supplies its summary count. | unavailable when `count` is omitted | unavailable | `component:ChatComposerDrawer` | stable | Collapse inputs have no visible effect without `count`. |
100
- | collapse control | uncontrolled, controlled | Internal state or `isCollapsed` determines the current disclosure state. | when collapse support is available | uncontrolled | `component:ChatComposerDrawer` | stable | Controlled state wins over the initial default. |
101
- | collapsed summary | default, caller-composed | Visual content shown for the collapsed disclosure. | when collapse support is available | neutral Badge plus label | caller choice; component seam | accepted, unshipped | Omission uses the default; without `count`, no summary is exposed. |
102
- | collapse request | next state | Activation asks for the opposite effective collapsed state. | when collapse support is available | none | `component:ChatComposerDrawer` | stable | No request is emitted without a disclosure. |
103
-
104
- `collapsedSummary` is the camelCase public API projection of the canonical
105
- **Collapsed summary** anatomy part. It is the complete custom visual summary, not
106
- an addition before or after the default. The component does not parse, clone,
107
- decorate, or supply data to the node. Builders already own the values they pass as
108
- `count` and `label`; when a custom summary forms a sentence or formats a number,
109
- its callsite owns the complete localized message.
76
+ | Concept | Closed values or states | Meaning | Availability by state | Default | Owner | Stability | Invalid-value behavior |
77
+ | ---------------- | -------------------------------- | ------------------------------------------------------------------------ | ----------------------------------- | ------------ | ------------------------------ | --------- | ---------------------------------------------------- |
78
+ | drawer content | any React node | Supplementary content composed above the chat input. | always | none | `component:ChatComposerDrawer` | stable | Missing content is rejected by the required type. |
79
+ | collapse support | unavailable, expanded, collapsed | `count` enables a disclosure and supplies its summary count. | unavailable when `count` is omitted | unavailable | `component:ChatComposerDrawer` | stable | Collapse props have no visible effect without count. |
80
+ | collapse control | uncontrolled, controlled | Internal state or `isCollapsed` determines the current disclosure state. | when collapse support is available | uncontrolled | `component:ChatComposerDrawer` | stable | Controlled state wins over the initial default. |
81
+ | collapse request | next state | Activation asks for the opposite effective state. | when collapse support is available | none | `component:ChatComposerDrawer` | stable | No request is emitted without a disclosure. |
110
82
 
111
83
  ## Behavioral and layout contract
112
84
 
113
- | ID | Invariant | Basis |
114
- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
115
- | FR1 | When `count` is present, including when it is `0`, the component MUST expose one named disclosure control with `aria-expanded` and a resolvable `aria-controls` relationship. | released API and implementation; WAI-ARIA disclosure semantics |
116
- | FR2 | Pointer activation, Enter, and Space MUST request the opposite effective collapsed state exactly once. | released implementation and public callback contract |
117
- | FR3 | In controlled mode, `isCollapsed` MUST remain authoritative; in uncontrolled mode, activation MUST update internal state before the next render. | released implementation and consumer docs |
118
- | FR4 | Collapsed drawer content MAY remain mounted for the grid transition, but its descendants MUST be absent from keyboard and assistive-technology navigation. | WAI-ARIA disclosure semantics; WCAG 2.4.3 and 2.4.7 |
119
- | FR5 | Keyboard focus on the disclosure MUST remain visibly perceivable through the shared focus-indicator mechanism. | `architecture:interaction-modality/INV1–INV4` |
120
- | FR6 | Omitting `count` MUST render drawer content directly, MUST NOT create a disclosure control, and MUST NOT expose `collapsedSummary`. Existing collapse inputs continue to have no visible effect in this state. | released no-count behavior and compatibility |
121
- | FR7 | The root MUST continue forwarding its ref, BaseProps attributes, and styling seams without moving them to an internal child. | released public surface and `architecture:public-component-api/INV5–INV6, INV8–INV9` |
122
- | FR8 | `collapsedSummary` MUST remain the camelCase public name of the canonical **Collapsed summary** anatomy part. When omitted, the collapsed disclosure MUST preserve the existing neutral Badge containing `count`, followed by the resolved `label`; when provided, the node MUST replace that complete anatomy part exactly once. | approved anatomy-aligned caller-composition boundary and released default |
123
- | FR9 | The custom summary MUST affect visual content only. It MUST NOT change whether collapse is available, effective collapse state, toggle activation, callback values, the controlled region, or the component-owned accessible name. | constrained slot contract and `spec:AST-002/DEC-2` |
124
- | FR10 | The summary subtree MUST remain presentation-only: the disclosure is the sole focus and activation target, summary descendants MUST be absent from the tab order and accessibility tree, and custom content MUST NOT add another action. | WAI-ARIA disclosure semantics and component-owned accessibility boundary |
85
+ | ID | Candidate invariant | Basis | Draft review state |
86
+ | --- | --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------ |
87
+ | FR1 | When `count` is present, the component MUST expose one named disclosure control with `aria-expanded` and a resolvable `aria-controls` relationship. | Shipped API and implementation; WAI-ARIA disclosure semantics. | verify |
88
+ | FR2 | Pointer activation, Enter, and Space MUST request the opposite effective collapsed state exactly once. | Shipped implementation and public callback contract. | verify |
89
+ | FR3 | In controlled mode, `isCollapsed` MUST remain authoritative; in uncontrolled mode, activation MUST update internal state before the next render. | Shipped implementation and consumer docs. | verify |
90
+ | FR4 | Collapsed content MAY remain mounted for the grid transition, but its descendants MUST be absent from keyboard and assistive-technology navigation. | WCAG 2.4.3 and 2.4.7; objective restoration of the shipped visually hidden state. | settled |
91
+ | FR5 | Keyboard focus on the disclosure MUST remain visibly perceivable through the shared focus-indicator mechanism. | `architecture:interaction-modality/INV1–INV4`; WCAG 2.4.7. | settled |
92
+ | FR6 | Omitting `count` MUST render content directly and MUST NOT create a disclosure control. | Shipped implementation and consumer docs. | verify |
93
+ | FR7 | The root MUST continue forwarding its ref, BaseProps attributes, and styling seams without moving them to an internal child. | Released public surface and `architecture:knowledge-contracts/INV11`. | verify |
125
94
 
126
95
  ### Allowed variation
127
96
 
128
- - **AV1 — Drawer child composition.** Builders choose the drawer content and its own
129
- semantics.
130
- - **AV2 — Custom summary composition.** Builders may compose any visual content that
131
- fits the presentation-only boundary, including localized text or existing Astryx
132
- display components.
133
- - **AV3 — Summary lifecycle.** The component may keep the default or custom summary
134
- mounted while visually expanded to preserve animation. Callers MUST NOT depend on
135
- mount or unmount timing.
136
- - **AV4 — Custom summary styling.** Caller-composed content retains the styling and
137
- theme seams of the components it uses. ChatComposerDrawer adds no summary-specific
138
- target.
97
+ - **AV1 — Child composition.** Builders choose the child content and its own semantics.
98
+ - **AV2 — Collapsed summary paint.** The current count-and-label presentation is observation, not an approved durable representation.
139
99
 
140
100
  ### Representative states
141
101
 
142
- | State | Required invariant | Allowed variation |
143
- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
144
- | `count` omitted | Content is visible; no disclosure or summary is exposed. | Child content and root styling. |
145
- | default summary, collapsed | One disclosure shows the neutral count Badge plus resolved label. | Count value and localized label. |
146
- | custom summary, collapsed | One disclosure shows the caller node instead of both default summary parts. | Presentation-only custom content and styling. |
147
- | custom summary, expanded | The disclosure retains its state and name; the custom summary may stay mounted but is visually and semantically hidden. | Internal crossfade and mount timing. |
148
- | controlled expanded or collapsed | Rendered state follows `isCollapsed`; activation reports the requested next state. | Parent timing and whether it accepts the request. |
102
+ | State | Required invariant | Allowed variation |
103
+ | ----------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------- |
104
+ | count omitted | Content is visible and no disclosure is rendered. | Child content and root styling. |
105
+ | uncontrolled expanded | Disclosure is expanded and descendants are available. | Child content and count value. |
106
+ | uncontrolled collapsed | Disclosure is collapsed and mounted descendants are inert. | Current summary presentation. |
107
+ | controlled expanded/collapsed | Rendered state follows `isCollapsed`; activation reports the requested next state. | Parent timing and whether it accepts the request. |
149
108
 
150
109
  ### Transformation and precedence order
151
110
 
152
- - **ORD1 — Collapse availability.** `count` present → disclosure enabled; `count`
153
- omitted → no disclosure or collapsed summary.
154
- - **ORD2 — Effective state.** `isCollapsed` when defined → otherwise internal state
155
- initialized from `defaultIsCollapsed`.
156
- - **ORD3 — Visual summary.** Caller-provided `collapsedSummary` → otherwise the
157
- neutral Badge for `count` followed by the resolved `label`.
158
- - **ORD4 — Accessible name.** Resolve `label` from the prop or locale catalog → use
159
- the catalog's expand or collapse action message for the effective state. Visual
160
- summary content never enters or overrides this pipeline.
111
+ - **ORD1 — Effective state.** `isCollapsed` when defined → otherwise internal state initialized from `defaultIsCollapsed` → disclosure output only when `count` is present.
161
112
 
162
113
  ### Performance and resources
163
114
 
164
- - **PR1 — Local state only.** The summary seam MUST NOT require an Effect, observer,
165
- listener, timer, or external resource.
115
+ - **PR1 — Local state only.** The component owns no Effect, observer, listener, timer, or external resource.
166
116
 
167
117
  ## Accessibility contract
168
118
 
169
- - **AR1 — Disclosure relationship.** The toggle exposes one localized name, expanded
170
- state, and a resolvable controlled-content ID.
171
- - **AR2 — Naming stays component-owned.** `label` identifies the controlled drawer
172
- content in the expand/collapse catalog message. Default or custom visual summary
173
- text MUST NOT replace, duplicate, or concatenate into that accessible name.
174
- - **AR3 — Hidden content is unavailable.** Visually collapsed drawer descendants are
175
- unavailable until expansion.
176
- - **AR4 — Custom summary remains presentation-only.** Custom content cannot add a
177
- second focus stop, activation target, role, or announcement inside the disclosure.
119
+ - **AR1 — Disclosure relationship.** The toggle exposes a name, expanded state, and a resolvable controlled-content ID.
120
+ - **AR2 — Hidden content is unavailable.** A visually collapsed mounted subtree is inert until expansion.
121
+ - **AR3 — Focus remains visible.** Keyboard focus on the toggle uses the shared focus indicator.
178
122
 
179
123
  ## Design relationships
180
124
 
181
- No current design specification governs this component-local representation.
182
-
183
- | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
184
- | ----------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------ | -------------- | ------------------ |
185
- | root surface | Existing released surface remains unchanged by this decision. | released behavior | supporting | FR7 |
186
- | disclosure toggle | One operable, named control owns collapse interaction. | component-owned | supporting | FR1–FR5, AR1 |
187
- | collapsed summary | Badge hierarchy remains the default; callers may choose one visual composition slot. | component default or caller-selected composition | supporting | FR8–FR10, AR2–AR4 |
188
- | content area | Collapsed descendants remain unavailable to keyboard and assistive technology. | component-owned | supporting | FR4, FR6, AR3 |
125
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
126
+ | ----------------- | ------------------ | ------------------------ | -------------- | ------------------ |
127
+ | root surface | unsettled | human-selected | supporting | FR7 |
128
+ | disclosure toggle | unsettled | human-selected | supporting | FR1, FR5 |
129
+ | collapsed summary | unsettled | human-selected | supporting | AV2 |
130
+ | content area | unsettled | human-selected | supporting | FR4, FR6 |
189
131
 
190
- The existing `chat-composer-drawer` target remains on the painted root. The
191
- Badge-preserving default delegates count paint to Badge. Caller-composed summary
192
- content retains the theme ownership of the components it supplies. This decision
193
- adds no ChatComposerDrawer summary target and does not make arbitrary slot internals
194
- part of ChatComposerDrawer's theming API.
132
+ The existing `chat-composer-drawer` target remains on the painted root. This
133
+ observational draft does not add targets or decide a separate theming boundary for
134
+ the disclosure, summary, or content area.
195
135
 
196
136
  ## Family and system relationships
197
137
 
198
- - `architecture:public-component-api` owns reachability, naming grammar, and
199
- compatibility of the additive slot; this component owns its local meaning and
200
- default.
201
- - `architecture:interaction-modality` owns shared focus-visibility mechanics; this
202
- component owns the disclosure as its semantic focus owner.
203
- - `architecture:component-theming-surface` owns target and anatomy mapping rules; the
204
- custom summary does not create a new target or transfer ownership of caller
205
- content.
206
- - `architecture:knowledge-contracts` limits this current authority to the explicit
207
- claims in this record.
208
- - `spec:AST-002/DEC-1` admits the slot because otherwise-identical drawers may need
209
- a caller-owned visual hierarchy the component cannot derive. `DEC-2` requires the
210
- seam to preserve a dependable, accessibility-safe outcome.
138
+ - `architecture:interaction-modality` owns shared focus-visibility mechanics; this component owns the disclosure as its semantic focus owner.
139
+ - `architecture:component-theming-surface` owns target and anatomy mapping rules; this component exposes only the existing root target.
140
+ - `spec:AST-029` owns the observational audit-backfill boundary.
211
141
 
212
142
  ## Verification map
213
143
 
214
- | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
215
- | ------------------------ | ----------------------------------------------------------------------- | -------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
216
- | FR1–FR3, FR6, ORD1–2 | focused ChatComposerDrawer state and keyboard tests | no count; zero count; controlled; uncontrolled; pointer; Enter; Space | Presence/truthiness changes collapse availability, state authority changes, or callback reports the wrong next state. | `audit:ChatComposerDrawer/behavior` |
217
- | FR8–FR9, ORD3 | focused default/custom summary tests and consumer-doc projection checks | default; custom node; expanded; collapsed; no count | The default Badge disappears, default and custom content render together, custom content changes behavior, or no-count exposes it. | `audit:ChatComposerDrawer/api` |
218
- | FR4, FR10, AR2–AR4 | focused inert-state and custom-descendant tests plus exact-head a11y CI | default text; custom text; custom focusable descendant; collapsed/expanded | Hidden drawer content or custom summary becomes focusable, announced, or a second action; visual text replaces the catalog name. | `audit:ChatComposerDrawer/accessibility` |
219
- | FR5, AR1 | `KeyboardFocus` Storybook play and exact-head visual/a11y gates | keyboard focus in representative light and dark themes | Focus has no shared visible indicator or the disclosure relationship/name breaks. | `audit:ChatComposerDrawer/accessibility` |
220
- | FR7 | focused DOM/type tests and package checks | ref, BaseProps, xstyle, className, style | Root ownership or a styling seam moves or disappears. | `audit:ChatComposerDrawer/api` |
221
- | AV4 and theming boundary | source/runtime theme inspection of default and custom summaries | default Badge; caller-composed Astryx content | A new summary target appears, Badge loses its target, or caller-owned content is retargeted as ChatComposerDrawer anatomy. | `audit:ChatComposerDrawer/theming` |
144
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
145
+ | ------------ | --------------------------------------------------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------- | ---------------------------------------- |
146
+ | FR1–FR3, FR6 | `ChatComposerDrawer.test.tsx` | no count; controlled; uncontrolled; Enter; Space | Relationship breaks, state authority changes, or callback reports the wrong next state. | `audit:ChatComposerDrawer/behavior` |
147
+ | FR4, AR2 | focused inert-state test plus exact-head accessibility CI | expanded → collapsed → expanded with focusable child | A visually hidden child remains reachable or expansion fails to restore availability. | `audit:ChatComposerDrawer/accessibility` |
148
+ | FR5, AR3 | `KeyboardFocus` Storybook play and exact-head visual/a11y gates | keyboard focus in representative light and dark themes | Focus has no shared visible indicator or pointer interaction changes the keyboard-only outcome. | `audit:ChatComposerDrawer/accessibility` |
149
+ | FR7 | focused DOM/type tests and package checks | ref, BaseProps, xstyle, className, style | Root ownership or a styling seam moves or disappears. | `audit:ChatComposerDrawer/api` |
222
150
 
223
151
  ## Decision log
224
152
 
225
- ### DEC-1 — One visual slot preserves the Badge default
226
-
227
- **Reference:** `component:ChatComposerDrawer/DEC-1`
228
- **Decider:** `cixzhang`, `2026-09-21`
229
-
230
- ChatComposerDrawer admits one optional `collapsedSummary` node for the complete
231
- visual summary. Product builders own whether a particular collapsed row needs the
232
- established Badge hierarchy or a quieter localized composition, and the component
233
- cannot derive that visual hierarchy. Omitting the slot preserves the existing
234
- neutral Badge plus label, so no current builder receives a new choice or migration.
235
-
236
- Rejected: replacing the default with a `{count} {label}` sentence, adding a Badge
237
- boolean or finite presentation enum, adding a render callback for values already
238
- owned by the caller, or exposing parallel summary seams. Those shapes either break
239
- the released default, encode presentation machinery, invite locale-unsafe string
240
- concatenation, or add more API than the caller-owned distinction requires.
241
-
242
- ### DEC-2 — Visual composition does not own disclosure semantics
243
-
244
- **Reference:** `component:ChatComposerDrawer/DEC-2`
245
- **Decider:** `cixzhang`, `2026-09-21`
246
-
247
- The custom summary is presentation-only. The existing `label` and locale catalog
248
- continue to name the expand/collapse action; `count` continues to enable the
249
- disclosure; and the component keeps summary descendants out of focus, activation,
250
- and assistive-technology navigation. The seam cannot replace these obligations.
251
-
252
- Rejected: deriving the accessible name from arbitrary summary content or letting a
253
- custom summary introduce another action inside the disclosure. Both make correct
254
- semantics depend on caller markup the component cannot verify.
153
+ No component-local policy decision is created by this observational draft.
255
154
 
256
155
  ## Open questions
257
156
 
258
- None for this contract slice.
157
+ - **OQ1 — Collapsed-summary representation.** Should the existing count badge remain, or should the summary use another representation? (`human-design`)
259
158
 
260
159
  ## Content boundary
261
160
 
262
- This file owns ChatComposerDrawer's collapsed-summary composition boundary,
263
- Badge-preserving default, collapse gating and state behavior, accessible naming,
264
- compatibility, and required evidence. It does not duplicate the complete consumer
265
- prop reference, implementation steps, current audit score, or unrelated component
266
- gaps. Current authority is claim-scoped to the explicit requirements above and does
267
- not certify every ChatComposerDrawer behavior.
161
+ This file does not duplicate consumer prop tables, examples, current audit scores,
162
+ or visual design rationale. It records observed behavior, objective remediation,
163
+ and the unresolved representation boundary without deciding it.
@@ -8,8 +8,8 @@
8
8
  * @output Unit tests for the shared clear-button primitive
9
9
  * @position Testing; validates InputClearButton.tsx — the single home for the
10
10
  * clearable input family's clear (✕) affordance and its theme target. Covers
11
- * the accessible name, contextual hover tooltip, click callback, decorative
12
- * registry glyph, both theme targets, touch hit area, and xstyle forwarding.
11
+ * the accessible name, the click callback, the decorative registry glyph,
12
+ * both theme targets, the touch hit area, and xstyle forwarding.
13
13
  *
14
14
  * SYNC: When InputClearButton.tsx changes, update tests to match new behavior.
15
15
  */
@@ -17,7 +17,7 @@
17
17
  import {readFileSync} from 'node:fs';
18
18
  import path from 'node:path';
19
19
  import {describe, it, expect, vi, afterEach} from 'vitest';
20
- import {render, screen, fireEvent, waitFor} from '@testing-library/react';
20
+ import {render, screen, fireEvent} from '@testing-library/react';
21
21
  import * as stylex from '@stylexjs/stylex';
22
22
  import {
23
23
  InputClearButton,
@@ -95,20 +95,6 @@ describe('InputClearButton public props', () => {
95
95
  });
96
96
 
97
97
  describe('InputClearButton', () => {
98
- it('uses the contextual label for the tooltip and accessible name', async () => {
99
- const showPopover = vi.spyOn(HTMLElement.prototype, 'showPopover');
100
- render(<InputClearButton label="Clear Search" onClick={() => {}} />);
101
-
102
- const button = screen.getByRole('button', {name: 'Clear Search'});
103
- const tooltip = screen.getByRole('tooltip', {hidden: true});
104
- expect(tooltip).toHaveTextContent(/^Clear Search$/);
105
- expect(button.getAttribute('aria-describedby')).toBe(tooltip.id);
106
-
107
- fireEvent.mouseEnter(button);
108
- await waitFor(() => expect(showPopover).toHaveBeenCalled());
109
- showPopover.mockRestore();
110
- });
111
-
112
98
  it('renders a real button with the given accessible label', () => {
113
99
  render(<InputClearButton label="Clear" onClick={() => {}} />);
114
100
  const button = screen.getByRole('button', {name: 'Clear'});
@@ -4,9 +4,8 @@
4
4
 
5
5
  /**
6
6
  * @file InputClearButton.tsx
7
- * @input Uses React, Button, and Icon
8
- * @output Exports the public InputClearButton and an internal popup-aware variant,
9
- * both with a contextual tooltip matching their required label.
7
+ * @input Uses React, Button, Icon
8
+ * @output Exports the public InputClearButton and an internal popup-aware variant.
10
9
  * @position Shared primitive. Every input that renders a clear affordance —
11
10
  * TextInput, NumberInput, TimeInput, DateInput, DateTimeInput,
12
11
  * DateRangeInput, Selector, MultiSelector, Typeahead, Tokenizer, FileInput —
@@ -67,7 +66,6 @@ const styles = stylex.create({
67
66
  });
68
67
 
69
68
  export interface InputClearButtonProps {
70
- /** Contextual accessible name for the button, such as "Clear Search". */
71
69
  label: string;
72
70
  onClick: (e: React.MouseEvent<HTMLButtonElement>) => void;
73
71
  xstyle?: stylex.StyleXStyles;
@@ -106,7 +104,6 @@ function renderInputClearButton({
106
104
  variant="ghost"
107
105
  size="sm"
108
106
  label={label}
109
- tooltip={label}
110
107
  className={buttonTargetClassName}
111
108
  icon={
112
109
  <Icon