@namroodinc/liquid-editorial 0.1.5 → 0.1.7

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 (168) hide show
  1. package/AGENTS.md +2 -0
  2. package/README.md +149 -4
  3. package/UPGRADING.md +127 -4
  4. package/dist/components/AppShell/index.cjs +2 -0
  5. package/dist/components/AppShell/index.cjs.map +1 -0
  6. package/dist/components/AppShell/index.d.cts +15 -0
  7. package/dist/components/AppShell/index.d.cts.map +1 -0
  8. package/dist/components/AppShell/index.d.ts +15 -0
  9. package/dist/components/AppShell/index.d.ts.map +1 -0
  10. package/dist/components/AppShell/index.js +93 -0
  11. package/dist/components/AppShell/index.js.map +1 -0
  12. package/dist/components/AppShell/style.css +79 -0
  13. package/dist/components/AssetGrid/index.cjs +1 -1
  14. package/dist/components/AssetGrid/index.cjs.map +1 -1
  15. package/dist/components/AssetGrid/index.d.cts.map +1 -1
  16. package/dist/components/AssetGrid/index.d.ts.map +1 -1
  17. package/dist/components/AssetGrid/index.js +57 -59
  18. package/dist/components/AssetGrid/index.js.map +1 -1
  19. package/dist/components/AssetGrid/style.css +8 -16
  20. package/dist/components/Board/index.cjs +1 -1
  21. package/dist/components/Board/index.cjs.map +1 -1
  22. package/dist/components/Board/index.d.cts.map +1 -1
  23. package/dist/components/Board/index.d.ts.map +1 -1
  24. package/dist/components/Board/index.js +88 -84
  25. package/dist/components/Board/index.js.map +1 -1
  26. package/dist/components/Board/style.css +17 -28
  27. package/dist/components/Button/index.cjs +1 -1
  28. package/dist/components/Button/index.cjs.map +1 -1
  29. package/dist/components/Button/index.d.cts +3 -2
  30. package/dist/components/Button/index.d.cts.map +1 -1
  31. package/dist/components/Button/index.d.ts +3 -2
  32. package/dist/components/Button/index.d.ts.map +1 -1
  33. package/dist/components/Button/index.js +1 -1
  34. package/dist/components/Button/index.js.map +1 -1
  35. package/dist/components/Button/style.css +21 -15
  36. package/dist/components/DatePicker/index.cjs +1 -1
  37. package/dist/components/DatePicker/index.cjs.map +1 -1
  38. package/dist/components/DatePicker/index.d.cts.map +1 -1
  39. package/dist/components/DatePicker/index.d.ts.map +1 -1
  40. package/dist/components/DatePicker/index.js +46 -45
  41. package/dist/components/DatePicker/index.js.map +1 -1
  42. package/dist/components/DatePicker/style.css +4 -61
  43. package/dist/components/Drawer/index.cjs +1 -1
  44. package/dist/components/Drawer/index.cjs.map +1 -1
  45. package/dist/components/Drawer/index.d.cts +10 -1
  46. package/dist/components/Drawer/index.d.cts.map +1 -1
  47. package/dist/components/Drawer/index.d.ts +10 -1
  48. package/dist/components/Drawer/index.d.ts.map +1 -1
  49. package/dist/components/Drawer/index.js +69 -47
  50. package/dist/components/Drawer/index.js.map +1 -1
  51. package/dist/components/Drawer/style.css +106 -0
  52. package/dist/components/EntryPicker/index.cjs +1 -1
  53. package/dist/components/EntryPicker/index.cjs.map +1 -1
  54. package/dist/components/EntryPicker/index.d.cts.map +1 -1
  55. package/dist/components/EntryPicker/index.d.ts.map +1 -1
  56. package/dist/components/EntryPicker/index.js +12 -11
  57. package/dist/components/EntryPicker/index.js.map +1 -1
  58. package/dist/components/EntryPicker/style.css +3 -30
  59. package/dist/components/Field/style.css +11 -3
  60. package/dist/components/ImageCropper/index.cjs +1 -1
  61. package/dist/components/ImageCropper/index.cjs.map +1 -1
  62. package/dist/components/ImageCropper/index.d.cts +3 -17
  63. package/dist/components/ImageCropper/index.d.cts.map +1 -1
  64. package/dist/components/ImageCropper/index.d.ts +3 -17
  65. package/dist/components/ImageCropper/index.d.ts.map +1 -1
  66. package/dist/components/ImageCropper/index.js +143 -180
  67. package/dist/components/ImageCropper/index.js.map +1 -1
  68. package/dist/components/ImageCropper/style.css +2 -94
  69. package/dist/components/Menu/index.cjs +1 -1
  70. package/dist/components/Menu/index.cjs.map +1 -1
  71. package/dist/components/Menu/index.d.cts.map +1 -1
  72. package/dist/components/Menu/index.d.ts.map +1 -1
  73. package/dist/components/Menu/index.js +11 -16
  74. package/dist/components/Menu/index.js.map +1 -1
  75. package/dist/components/Menu/style.css +7 -41
  76. package/dist/components/Modal/index.cjs +1 -1
  77. package/dist/components/Modal/index.cjs.map +1 -1
  78. package/dist/components/Modal/index.d.cts.map +1 -1
  79. package/dist/components/Modal/index.d.ts.map +1 -1
  80. package/dist/components/Modal/index.js +12 -12
  81. package/dist/components/Modal/index.js.map +1 -1
  82. package/dist/components/NumberField/index.cjs +1 -1
  83. package/dist/components/NumberField/index.cjs.map +1 -1
  84. package/dist/components/NumberField/index.js +13 -17
  85. package/dist/components/NumberField/index.js.map +1 -1
  86. package/dist/components/NumberField/style.css +1 -41
  87. package/dist/components/Pagination/index.cjs +2 -0
  88. package/dist/components/Pagination/index.cjs.map +1 -0
  89. package/dist/components/Pagination/index.d.cts +24 -0
  90. package/dist/components/Pagination/index.d.cts.map +1 -0
  91. package/dist/components/Pagination/index.d.ts +24 -0
  92. package/dist/components/Pagination/index.d.ts.map +1 -0
  93. package/dist/components/Pagination/index.js +96 -0
  94. package/dist/components/Pagination/index.js.map +1 -0
  95. package/dist/components/Pagination/style.css +52 -0
  96. package/dist/components/Popover/index.cjs +1 -1
  97. package/dist/components/Popover/index.cjs.map +1 -1
  98. package/dist/components/Popover/index.d.cts +5 -1
  99. package/dist/components/Popover/index.d.cts.map +1 -1
  100. package/dist/components/Popover/index.d.ts +5 -1
  101. package/dist/components/Popover/index.d.ts.map +1 -1
  102. package/dist/components/Popover/index.js +27 -26
  103. package/dist/components/Popover/index.js.map +1 -1
  104. package/dist/components/SearchField/index.cjs +1 -1
  105. package/dist/components/SearchField/index.cjs.map +1 -1
  106. package/dist/components/SearchField/index.d.cts.map +1 -1
  107. package/dist/components/SearchField/index.d.ts.map +1 -1
  108. package/dist/components/SearchField/index.js +26 -27
  109. package/dist/components/SearchField/index.js.map +1 -1
  110. package/dist/components/SearchField/style.css +0 -21
  111. package/dist/components/Select/index.cjs +1 -1
  112. package/dist/components/Select/index.cjs.map +1 -1
  113. package/dist/components/Select/index.d.cts +3 -0
  114. package/dist/components/Select/index.d.cts.map +1 -1
  115. package/dist/components/Select/index.d.ts +3 -0
  116. package/dist/components/Select/index.d.ts.map +1 -1
  117. package/dist/components/Select/index.js +82 -73
  118. package/dist/components/Select/index.js.map +1 -1
  119. package/dist/components/Select/style.css +5 -38
  120. package/dist/components/SideNav/index.cjs +1 -1
  121. package/dist/components/SideNav/index.cjs.map +1 -1
  122. package/dist/components/SideNav/index.d.cts.map +1 -1
  123. package/dist/components/SideNav/index.d.ts.map +1 -1
  124. package/dist/components/SideNav/index.js +52 -49
  125. package/dist/components/SideNav/index.js.map +1 -1
  126. package/dist/components/SideNav/style.css +2 -27
  127. package/dist/components/Slider/style.css +14 -5
  128. package/dist/components/SortableList/index.cjs +1 -1
  129. package/dist/components/SortableList/index.cjs.map +1 -1
  130. package/dist/components/SortableList/index.d.cts.map +1 -1
  131. package/dist/components/SortableList/index.d.ts.map +1 -1
  132. package/dist/components/SortableList/index.js +42 -39
  133. package/dist/components/SortableList/index.js.map +1 -1
  134. package/dist/components/SortableList/style.css +9 -15
  135. package/dist/components/Stepper/index.cjs +1 -1
  136. package/dist/components/Stepper/index.cjs.map +1 -1
  137. package/dist/components/Stepper/index.d.cts.map +1 -1
  138. package/dist/components/Stepper/index.d.ts.map +1 -1
  139. package/dist/components/Stepper/index.js +48 -39
  140. package/dist/components/Stepper/index.js.map +1 -1
  141. package/dist/components/Stepper/style.css +24 -18
  142. package/dist/components/SubNav/index.cjs +1 -1
  143. package/dist/components/SubNav/index.cjs.map +1 -1
  144. package/dist/components/SubNav/index.d.cts.map +1 -1
  145. package/dist/components/SubNav/index.d.ts.map +1 -1
  146. package/dist/components/SubNav/index.js +27 -28
  147. package/dist/components/SubNav/index.js.map +1 -1
  148. package/dist/components/SubNav/style.css +13 -0
  149. package/dist/components/Switch/index.cjs +1 -1
  150. package/dist/components/Switch/index.cjs.map +1 -1
  151. package/dist/components/Switch/index.d.cts.map +1 -1
  152. package/dist/components/Switch/index.d.ts.map +1 -1
  153. package/dist/components/Switch/index.js +23 -21
  154. package/dist/components/Switch/index.js.map +1 -1
  155. package/dist/components/Switch/style.css +2 -28
  156. package/dist/components/TagsInput/index.cjs +1 -1
  157. package/dist/components/TagsInput/index.cjs.map +1 -1
  158. package/dist/components/TagsInput/index.js +8 -10
  159. package/dist/components/TagsInput/index.js.map +1 -1
  160. package/dist/components/TagsInput/style.css +2 -24
  161. package/dist/index.cjs +1 -1
  162. package/dist/index.d.cts +7 -3
  163. package/dist/index.d.cts.map +1 -1
  164. package/dist/index.d.ts +7 -3
  165. package/dist/index.d.ts.map +1 -1
  166. package/dist/index.js +36 -34
  167. package/dist/styles.css +2 -0
  168. package/package.json +1 -1
@@ -1,49 +1,48 @@
1
1
  import { t as e } from "../../chunks/Icon-CGY1FNXT.js";
2
+ import { Button as t } from "../Button/index.js";
2
3
  /* empty css */
3
- import { FieldAffix as t } from "../FieldAffix/index.js";
4
- import { forwardRef as n, useRef as r } from "react";
5
- import { jsx as i } from "react/jsx-runtime";
4
+ import { FieldAffix as n } from "../FieldAffix/index.js";
5
+ import { forwardRef as r, useRef as i } from "react";
6
+ import { jsx as a } from "react/jsx-runtime";
6
7
  //#region src/components/SearchField/index.tsx
7
- var a = n(function({ size: n = "md", isDisabled: a = !1, onClear: o, className: s, placeholder: c = "Search", value: l, disabled: u, onKeyDown: d, ...f }, p) {
8
- let m = r(null), h = l !== void 0 && String(l).length > 0;
9
- return /* @__PURE__ */ i(t, {
10
- className: s,
11
- lead: /* @__PURE__ */ i(e, {
8
+ var o = r(function({ size: r = "md", isDisabled: o = !1, onClear: s, className: c, placeholder: l = "Search", value: u, disabled: d, onKeyDown: f, ...p }, m) {
9
+ let h = i(null), g = u !== void 0 && String(u).length > 0;
10
+ return /* @__PURE__ */ a(n, {
11
+ className: c,
12
+ lead: /* @__PURE__ */ a(e, {
12
13
  name: "search",
13
14
  size: 16
14
15
  }),
15
16
  isTrailInteractive: !0,
16
- trail: h && o ? /* @__PURE__ */ i("button", {
17
- type: "button",
18
- className: "ds-search__clear",
17
+ trail: g && s ? /* @__PURE__ */ a(t, {
18
+ variant: "simple",
19
+ size: "xs",
20
+ isIconOnly: !0,
21
+ iconStart: "x",
19
22
  "aria-label": "Clear search",
20
- disabled: a || u,
23
+ isDisabled: o || d,
21
24
  onClick: () => {
22
- o(), m.current?.focus();
23
- },
24
- children: /* @__PURE__ */ i(e, {
25
- name: "x",
26
- size: 16
27
- })
25
+ s(), h.current?.focus();
26
+ }
28
27
  }) : void 0,
29
- children: /* @__PURE__ */ i("input", {
28
+ children: /* @__PURE__ */ a("input", {
30
29
  ref: (e) => {
31
- m.current = e, typeof p == "function" ? p(e) : p && (p.current = e);
30
+ h.current = e, typeof m == "function" ? m(e) : m && (m.current = e);
32
31
  },
33
32
  type: "search",
34
- value: l,
35
- placeholder: c,
36
- disabled: a || u,
37
- "data-size": n,
33
+ value: u,
34
+ placeholder: l,
35
+ disabled: o || d,
36
+ "data-size": r,
38
37
  className: "ds-field-skin ds-search__input",
39
38
  onKeyDown: (e) => {
40
- e.key === "Escape" && o && o(), d?.(e);
39
+ e.key === "Escape" && s && s(), f?.(e);
41
40
  },
42
- ...f
41
+ ...p
43
42
  })
44
43
  });
45
44
  });
46
45
  //#endregion
47
- export { a as SearchField };
46
+ export { o as SearchField };
48
47
 
49
48
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["Icon","SearchField","forwardRef","rest","inner","useRef","hasValue","value","FieldAffix","onClear","isDisabled","disabled","node","ref","size","event","onKeyDown"],"sources":["../../../src/components/SearchField/index.tsx"],"sourcesContent":["import { forwardRef, useRef, type InputHTMLAttributes } from \"react\";\nimport { Icon } from \"../Icon\";\nimport { FieldAffix } from \"../FieldAffix\";\nimport type { FieldSize } from \"../Field\";\nimport \"../Field/style.css\";\nimport \"./style.css\";\n\nexport interface SearchFieldProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, \"size\" | \"type\"> {\n size?: FieldSize;\n isDisabled?: boolean;\n /** Fired by the clear button and by Escape. */\n onClear?: () => void;\n}\n\n/** A filter over a collection. Carries the glyph, and clears without a Save. */\nexport const SearchField = forwardRef<HTMLInputElement, SearchFieldProps>(function SearchField(\n {\n size = \"md\",\n isDisabled = false,\n onClear,\n className,\n placeholder = \"Search\",\n value,\n disabled,\n onKeyDown,\n ...rest\n },\n ref,\n) {\n const inner = useRef<HTMLInputElement | null>(null);\n const hasValue = value !== undefined ? String(value).length > 0 : false;\n\n return (\n <FieldAffix\n className={className}\n lead={<Icon name=\"search\" size={16} />}\n isTrailInteractive\n trail={\n hasValue && onClear ? (\n <button\n type=\"button\"\n className=\"ds-search__clear\"\n aria-label=\"Clear search\"\n disabled={isDisabled || disabled}\n onClick={() => {\n onClear();\n inner.current?.focus();\n }}\n >\n <Icon name=\"x\" size={16} />\n </button>\n ) : undefined\n }\n >\n <input\n ref={(node) => {\n inner.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n }}\n type=\"search\"\n value={value}\n placeholder={placeholder}\n disabled={isDisabled || disabled}\n data-size={size}\n className=\"ds-field-skin ds-search__input\"\n onKeyDown={(event) => {\n if (event.key === \"Escape\" && onClear) onClear();\n onKeyDown?.(event);\n }}\n {...rest}\n />\n </FieldAffix>\n );\n});\n"],"mappings":";;;;;;AAgBA,IAAaC,IAAcC,EAA+C,SACxE,EACE,UAAO,MACP,gBAAa,IACb,YACA,cACA,iBAAc,UACd,UACA,aACA,cACA,GAAGC,KAEL,GACA;CACA,IAAMC,IAAQC,EAAgC,IAAI,GAC5CC,IAAWC,MAAU,KAAA,KAAY,OAAOA,CAAK,CAAC,CAAC,SAAS;CAE9D,OACE,kBAACC,GAAD;EACa;EACX,MAAM,kBAACR,GAAD;GAAM,MAAK;GAAS,MAAM;EAAK,CAAA;EACrC,oBAAA;EACA,OACEM,KAAYG,IACV,kBAAC,UAAD;GACE,MAAK;GACL,WAAU;GACV,cAAW;GACX,UAAUC,KAAcC;GACxB,eAAe;IAEb,AADAF,EAAQ,GACRL,EAAM,SAAS,MAAM;GACvB;GAEA,UAAA,kBAACJ,GAAD;IAAM,MAAK;IAAI,MAAM;GAAK,CAAA;EACpB,CAAA,IACN,KAAA;EAGN,UAAA,kBAAC,SAAD;GACE,MAAM,MAAS;IAEb,AADA,EAAM,UAAUY,GACZ,OAAOC,KAAQ,aAAYA,EAAID,CAAI,IAC9BC,MAAK,EAAI,UAAUD;GAC9B;GACA,MAAK;GACE;GACM;GACb,UAAUF,KAAcC;GACxB,aAAWG;GACX,WAAU;GACV,YAAY,MAAU;IAEpB,AADIC,EAAM,QAAQ,YAAYN,KAASA,EAAQ,GAC/CO,IAAYD,CAAK;GACnB;GACA,GAAIZ;EACL,CAAA;CACS,CAAA;AAEhB,CAAC"}
1
+ {"version":3,"file":"index.js","names":["Icon","SearchField","forwardRef","rest","inner","useRef","hasValue","value","FieldAffix","onClear","Button","isDisabled","disabled","node","ref","size","event","onKeyDown"],"sources":["../../../src/components/SearchField/index.tsx"],"sourcesContent":["import { forwardRef, useRef, type InputHTMLAttributes } from \"react\";\nimport { Icon } from \"../Icon\";\nimport { Button } from \"../Button\";\nimport { FieldAffix } from \"../FieldAffix\";\nimport type { FieldSize } from \"../Field\";\nimport \"../Field/style.css\";\nimport \"./style.css\";\n\nexport interface SearchFieldProps\n extends Omit<InputHTMLAttributes<HTMLInputElement>, \"size\" | \"type\"> {\n size?: FieldSize;\n isDisabled?: boolean;\n /** Fired by the clear button and by Escape. */\n onClear?: () => void;\n}\n\n/** A filter over a collection. Carries the glyph, and clears without a Save. */\nexport const SearchField = forwardRef<HTMLInputElement, SearchFieldProps>(function SearchField(\n {\n size = \"md\",\n isDisabled = false,\n onClear,\n className,\n placeholder = \"Search\",\n value,\n disabled,\n onKeyDown,\n ...rest\n },\n ref,\n) {\n const inner = useRef<HTMLInputElement | null>(null);\n const hasValue = value !== undefined ? String(value).length > 0 : false;\n\n return (\n <FieldAffix\n className={className}\n lead={<Icon name=\"search\" size={16} />}\n isTrailInteractive\n trail={\n hasValue && onClear ? (\n <Button\n variant=\"simple\"\n size=\"xs\"\n isIconOnly\n iconStart=\"x\"\n aria-label=\"Clear search\"\n isDisabled={isDisabled || disabled}\n onClick={() => {\n onClear();\n inner.current?.focus();\n }}\n />\n ) : undefined\n }\n >\n <input\n ref={(node) => {\n inner.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n }}\n type=\"search\"\n value={value}\n placeholder={placeholder}\n disabled={isDisabled || disabled}\n data-size={size}\n className=\"ds-field-skin ds-search__input\"\n onKeyDown={(event) => {\n if (event.key === \"Escape\" && onClear) onClear();\n onKeyDown?.(event);\n }}\n {...rest}\n />\n </FieldAffix>\n );\n});\n"],"mappings":";;;;;;;AAiBA,IAAaC,IAAcC,EAA+C,SACxE,EACE,UAAO,MACP,gBAAa,IACb,YACA,cACA,iBAAc,UACd,UACA,aACA,cACA,GAAGC,KAEL,GACA;CACA,IAAMC,IAAQC,EAAgC,IAAI,GAC5CC,IAAWC,MAAU,KAAA,KAAY,OAAOA,CAAK,CAAC,CAAC,SAAS;CAE9D,OACE,kBAACC,GAAD;EACa;EACX,MAAM,kBAACR,GAAD;GAAM,MAAK;GAAS,MAAM;EAAK,CAAA;EACrC,oBAAA;EACA,OACEM,KAAYG,IACV,kBAACC,GAAD;GACE,SAAQ;GACR,MAAK;GACL,YAAA;GACA,WAAU;GACV,cAAW;GACX,YAAYC,KAAcC;GAC1B,eAAe;IAEb,AADAH,EAAQ,GACRL,EAAM,SAAS,MAAM;GACvB;EACD,CAAA,IACC,KAAA;EAGN,UAAA,kBAAC,SAAD;GACE,MAAM,MAAS;IAEb,AADA,EAAM,UAAUS,GACZ,OAAOC,KAAQ,aAAYA,EAAID,CAAI,IAC9BC,MAAK,EAAI,UAAUD;GAC9B;GACA,MAAK;GACE;GACM;GACb,UAAUF,KAAcC;GACxB,aAAWG;GACX,WAAU;GACV,YAAY,MAAU;IAEpB,AADIC,EAAM,QAAQ,YAAYP,KAASA,EAAQ,GAC/CQ,IAAYD,CAAK;GACnB;GACA,GAAIb;EACL,CAAA;CACS,CAAA;AAEhB,CAAC"}
@@ -3,25 +3,4 @@
3
3
  appearance: none;
4
4
  }
5
5
 
6
- .ds-search__clear {
7
- display: grid;
8
- place-items: center;
9
- inline-size: var(--space-6);
10
- block-size: var(--space-6);
11
- border: none;
12
- border-radius: var(--radius-sm);
13
- background: transparent;
14
- color: var(--color-text-muted);
15
- cursor: pointer;
16
- }
17
-
18
- .ds-search__clear:hover {
19
- background: var(--field-hover);
20
- color: var(--color-text);
21
- }
22
-
23
- .ds-search__clear:focus-visible {
24
- outline: var(--control-border-width) solid var(--color-focus);
25
- outline-offset: 2px;
26
- }
27
6
  }
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/Icon-CWsA1W83.cjs");;/* empty css */const t=require("../Popover/index.cjs");let n=require("react"),r=require("react/jsx-runtime");function i(...e){return e.filter(Boolean).join(` `)}var a=(0,n.forwardRef)(function({options:a,value:o,defaultValue:s,onValueChange:c,placeholder:l=`Select an option`,size:u=`md`,isDisabled:d=!1,isInvalid:f=!1,className:p,disabled:m,onClick:h,onKeyDown:g,..._},v){let[y,b]=(0,n.useState)(s??``),x=o??y,[S,C]=(0,n.useState)(!1),[w,T]=(0,n.useState)(0),E=(0,n.useRef)(null),D=(0,n.useRef)(null),O=(0,n.useRef)(null),k=(0,n.useId)(),A=d||m,j=S&&!A,M=a.find(e=>e.value===x),N=a.filter(e=>!e.isDisabled),P=(0,n.useCallback)(e=>{o===void 0&&b(e),c?.(e),C(!1)},[c,o]);(0,n.useEffect)(()=>{if(!j)return;let e=a.findIndex(e=>e.value===x&&!e.isDisabled);T(e<0?a.indexOf(N[0]):e);let t=e=>{let t=e.target;!E.current?.contains(t)&&!O.current?.contains(t)&&C(!1)};return document.addEventListener(`mousedown`,t),()=>document.removeEventListener(`mousedown`,t)},[j]),(0,n.useEffect)(()=>{j&&(O.current?.querySelectorAll(`[role='option']`)[w])?.scrollIntoView({block:`nearest`})},[w,j]);let F=e=>{let t=a.map((e,t)=>({option:e,index:t})).filter(e=>!e.option.isDisabled);if(t.length===0)return;let n=t[(t.findIndex(e=>e.index===w)+e+t.length)%t.length];T(n.index)},I=e=>{if(!A){if(e.key===`Escape`)C(!1),D.current?.focus();else if(!j&&(e.key===`ArrowDown`||e.key===`ArrowUp`||e.key===`Enter`||e.key===` `))e.preventDefault(),C(!0);else if(j){if(e.key===`Tab`)C(!1);else if(e.key===`ArrowDown`||e.key===`ArrowUp`)e.preventDefault(),F(e.key===`ArrowDown`?1:-1);else if(e.key===`Home`||e.key===`End`){e.preventDefault();let t=e.key===`Home`?N[0]:N[N.length-1];t&&T(a.indexOf(t))}else if(e.key===`Enter`||e.key===` `){e.preventDefault();let t=a[w];t&&!t.isDisabled&&P(t.value)}}}};return(0,r.jsxs)(`div`,{className:`ds-select-root`,ref:E,children:[(0,r.jsxs)(`button`,{ref:e=>{D.current=e,typeof v==`function`?v(e):v&&(v.current=e)},type:`button`,role:`combobox`,"aria-haspopup":`listbox`,"aria-expanded":j,"aria-controls":j?k:void 0,"aria-activedescendant":j&&a[w]&&!a[w].isDisabled?`${k}-option-${w}`:void 0,"aria-invalid":f||void 0,disabled:A,"data-size":u,"data-placeholder":M?void 0:``,className:i(`ds-field-skin`,`ds-select`,p),onClick:e=>{h?.(e),e.defaultPrevented||C(e=>!e)},onKeyDown:e=>{g?.(e),e.defaultPrevented||I(e)},..._,children:[(0,r.jsx)(`span`,{className:`ds-select__value`,children:M?M.label:l}),(0,r.jsx)(e.t,{name:`chevron-down`,size:16,className:`ds-select__chevron`})]}),(0,r.jsx)(t.Popover,{anchorRef:D,isOpen:j,matchAnchorWidth:!0,panelRef:O,id:k,role:`listbox`,"aria-label":_[`aria-label`]??l,className:`ds-surface-raised ds-select__menu`,children:(0,r.jsx)(`div`,{onKeyDown:I,children:a.map((t,n)=>(0,r.jsxs)(`div`,{id:`${k}-option-${n}`,role:`option`,"aria-selected":t.value===x,"aria-disabled":t.isDisabled||void 0,"data-active":n===w||void 0,className:`ds-select__option`,onMouseEnter:()=>!t.isDisabled&&T(n),onClick:()=>{t.isDisabled||(P(t.value),D.current?.focus())},children:[(0,r.jsxs)(`span`,{className:`ds-select__option-body`,children:[(0,r.jsx)(`span`,{className:`ds-select__option-label`,children:t.label}),t.description&&(0,r.jsx)(`span`,{className:`ds-select__option-description`,children:t.description})]}),t.value===x&&(0,r.jsx)(e.t,{name:`check`,size:16})]},t.value))})})]})});exports.Select=a;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/Icon-CWsA1W83.cjs"),t=require("../Button/index.cjs");;/* empty css */const n=require("../Popover/index.cjs");let r=require("react"),i=require("react/jsx-runtime");function a(...e){return e.filter(Boolean).join(` `)}var o=(0,r.forwardRef)(function({options:o,value:s,defaultValue:c,onValueChange:l,placeholder:u=`Select an option`,size:d=`md`,isDisabled:f=!1,isInvalid:p=!1,menuPlacement:m=`bottom`,className:h,disabled:g,onClick:_,onKeyDown:v,...y},b){let[x,S]=(0,r.useState)(c??``),C=s??x,[w,T]=(0,r.useState)(!1),[E,D]=(0,r.useState)(0),O=(0,r.useRef)(null),k=(0,r.useRef)(null),A=(0,r.useRef)(null),j=(0,r.useId)(),M=f||g,N=w&&!M,P=o.find(e=>e.value===C),F=o.filter(e=>!e.isDisabled),I=(0,r.useCallback)(e=>{s===void 0&&S(e),l?.(e),T(!1)},[l,s]);(0,r.useEffect)(()=>{if(!N)return;let e=o.findIndex(e=>e.value===C&&!e.isDisabled);D(e<0?o.indexOf(F[0]):e);let t=e=>{let t=e.target;!O.current?.contains(t)&&!A.current?.contains(t)&&T(!1)};return document.addEventListener(`mousedown`,t),()=>document.removeEventListener(`mousedown`,t)},[N]),(0,r.useEffect)(()=>{N&&(A.current?.querySelectorAll(`[role='option']`)[E])?.scrollIntoView({block:`nearest`})},[E,N]);let L=e=>{let t=o.map((e,t)=>({option:e,index:t})).filter(e=>!e.option.isDisabled);if(t.length===0)return;let n=t[(t.findIndex(e=>e.index===E)+e+t.length)%t.length];D(n.index)},R=e=>{if(!M){if(e.key===`Escape`){if(!N)return;e.preventDefault(),T(!1),k.current?.focus()}else if(!N&&(e.key===`ArrowDown`||e.key===`ArrowUp`||e.key===`Enter`||e.key===` `))e.preventDefault(),T(!0);else if(N){if(e.key===`Tab`)T(!1);else if(e.key===`ArrowDown`||e.key===`ArrowUp`)e.preventDefault(),L(e.key===`ArrowDown`?1:-1);else if(e.key===`Home`||e.key===`End`){e.preventDefault();let t=e.key===`Home`?F[0]:F[F.length-1];t&&D(o.indexOf(t))}else if(e.key===`Enter`||e.key===` `){e.preventDefault();let t=o[E];t&&!t.isDisabled&&I(t.value)}}}};return(0,i.jsxs)(`div`,{className:`ds-select-root`,ref:O,children:[(0,i.jsxs)(t.Button,{ref:e=>{k.current=e,typeof b==`function`?b(e):b&&(b.current=e)},size:d,role:`combobox`,"aria-haspopup":`listbox`,"aria-expanded":N,"aria-controls":N?j:void 0,"aria-activedescendant":N&&o[E]&&!o[E].isDisabled?`${j}-option-${E}`:void 0,"aria-invalid":p||void 0,isDisabled:M,"data-placeholder":P?void 0:``,className:a(`ds-field-skin`,`ds-select`,h),onClick:e=>{_?.(e),e.defaultPrevented||T(e=>!e)},onKeyDown:e=>{v?.(e),e.defaultPrevented||R(e)},...y,children:[(0,i.jsx)(`span`,{className:`ds-select__value`,children:P?P.label:u}),(0,i.jsx)(e.t,{name:`chevron-down`,size:16,className:`ds-select__chevron`})]}),(0,i.jsx)(n.Popover,{anchorRef:k,isOpen:N,placement:m,matchAnchorWidth:!0,panelRef:A,id:j,role:`listbox`,"aria-label":y[`aria-labelledby`]?void 0:y[`aria-label`]??u,"aria-labelledby":y[`aria-labelledby`],className:`ds-surface-raised ds-select__menu`,children:(0,i.jsx)(`div`,{onKeyDown:R,onPointerDown:e=>e.preventDefault(),children:o.map((n,r)=>(0,i.jsxs)(t.Button,{variant:r===E?`active`:`simple`,size:`sm`,isDisabled:n.isDisabled,tabIndex:-1,id:`${j}-option-${r}`,role:`option`,"aria-selected":n.value===C,"aria-disabled":n.isDisabled||void 0,"data-active":r===E||void 0,className:`ds-select__option`,onMouseEnter:()=>!n.isDisabled&&D(r),onClick:()=>{n.isDisabled||(I(n.value),k.current?.focus())},children:[(0,i.jsxs)(`span`,{className:`ds-select__option-body`,children:[(0,i.jsx)(`span`,{className:`ds-select__option-label`,children:n.label}),n.description&&(0,i.jsx)(`span`,{className:`ds-select__option-description`,children:n.description})]}),n.value===C&&(0,i.jsx)(e.t,{name:`check`,size:16})]},n.value))})})]})});exports.Select=o;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["forwardRef","useState","useRef","useId","useCallback","Icon","Popover","require_Icon","require_components_Popover_index","react","react_jsx_runtime","cx","parts","Select","rest","internal","setInternal","defaultValue","current","value","isOpen","setOpen","activeIndex","setActiveIndex","rootRef","triggerRef","listRef","listId","effectiveDisabled","isDisabled","disabled","isVisible","selected","options","option","enabled","commit","next","onValueChange","index","onPointerDown","target","event","step","order","o","delta","handleKeyDown","pick","node","ref","isInvalid","size","className","onClick","open","onKeyDown","placeholder"],"sources":["../../../src/components/Select/index.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n} from \"react\";\nimport { Icon } from \"../Icon\";\nimport { Popover } from \"../Popover\";\nimport type { FieldSize } from \"../Field\";\nimport \"../Field/style.css\";\nimport \"./style.css\";\n\nfunction cx(...parts: (string | undefined | false)[]) {\n return parts.filter(Boolean).join(\" \");\n}\n\nexport interface SelectOption {\n value: string;\n label: string;\n /** Secondary line under the label. */\n description?: string;\n isDisabled?: boolean;\n}\n\nexport interface SelectProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"value\" | \"defaultValue\" | \"onChange\"> {\n options: SelectOption[];\n /** Controlled value. Leave undefined to let the select hold its own. */\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n placeholder?: string;\n size?: FieldSize;\n isDisabled?: boolean;\n isInvalid?: boolean;\n}\n\n/**\n * One value out of a known list. Wears the field skin, opens a listbox: arrows\n * walk the options, Enter commits, Escape closes without changing anything.\n */\nexport const Select = forwardRef<HTMLButtonElement, SelectProps>(function Select(\n {\n options,\n value,\n defaultValue,\n onValueChange,\n placeholder = \"Select an option\",\n size = \"md\",\n isDisabled = false,\n isInvalid = false,\n className,\n disabled,\n onClick,\n onKeyDown,\n ...rest\n },\n ref,\n) {\n const [internal, setInternal] = useState(defaultValue ?? \"\");\n const current = value ?? internal;\n const [isOpen, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(0);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const listRef = useRef<HTMLDivElement | null>(null);\n const listId = useId();\n const effectiveDisabled = isDisabled || disabled;\n const isVisible = isOpen && !effectiveDisabled;\n\n const selected = options.find((option) => option.value === current);\n const enabled = options.filter((option) => !option.isDisabled);\n\n const commit = useCallback(\n (next: string) => {\n if (value === undefined) setInternal(next);\n onValueChange?.(next);\n setOpen(false);\n },\n [onValueChange, value],\n );\n\n useEffect(() => {\n if (!isVisible) return;\n const index = options.findIndex((option) => option.value === current && !option.isDisabled);\n setActiveIndex(index < 0 ? options.indexOf(enabled[0]!) : index);\n const onPointerDown = (event: MouseEvent) => {\n const target = event.target as Node;\n if (!rootRef.current?.contains(target) && !listRef.current?.contains(target)) setOpen(false);\n };\n document.addEventListener(\"mousedown\", onPointerDown);\n return () => document.removeEventListener(\"mousedown\", onPointerDown);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isVisible]);\n\n useEffect(() => {\n if (!isVisible) return;\n const activeOption = listRef.current?.querySelectorAll<HTMLElement>(\"[role='option']\")[activeIndex];\n activeOption?.scrollIntoView({ block: \"nearest\" });\n }, [activeIndex, isVisible]);\n\n const step = (delta: number) => {\n const order = options.map((option, index) => ({ option, index })).filter((o) => !o.option.isDisabled);\n if (order.length === 0) return;\n const at = order.findIndex((o) => o.index === activeIndex);\n const next = order[(at + delta + order.length) % order.length]!;\n setActiveIndex(next.index);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (effectiveDisabled) return;\n if (event.key === \"Escape\") {\n setOpen(false);\n triggerRef.current?.focus();\n return;\n }\n if (!isVisible && (event.key === \"ArrowDown\" || event.key === \"ArrowUp\" || event.key === \"Enter\" || event.key === \" \")) {\n event.preventDefault();\n setOpen(true);\n return;\n }\n if (!isVisible) return;\n if (event.key === \"Tab\") {\n setOpen(false);\n return;\n }\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n step(event.key === \"ArrowDown\" ? 1 : -1);\n } else if (event.key === \"Home\" || event.key === \"End\") {\n event.preventDefault();\n const pick = event.key === \"Home\" ? enabled[0] : enabled[enabled.length - 1];\n if (pick) setActiveIndex(options.indexOf(pick));\n } else if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n const option = options[activeIndex];\n if (option && !option.isDisabled) commit(option.value);\n }\n };\n\n return (\n <div className=\"ds-select-root\" ref={rootRef}>\n <button\n ref={(node) => {\n triggerRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n }}\n type=\"button\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={isVisible}\n aria-controls={isVisible ? listId : undefined}\n aria-activedescendant={isVisible && options[activeIndex] && !options[activeIndex].isDisabled ? `${listId}-option-${activeIndex}` : undefined}\n aria-invalid={isInvalid || undefined}\n disabled={effectiveDisabled}\n data-size={size}\n data-placeholder={selected ? undefined : \"\"}\n className={cx(\"ds-field-skin\", \"ds-select\", className)}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented) setOpen((open) => !open);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (!event.defaultPrevented) handleKeyDown(event);\n }}\n {...rest}\n >\n <span className=\"ds-select__value\">{selected ? selected.label : placeholder}</span>\n <Icon name=\"chevron-down\" size={16} className=\"ds-select__chevron\" />\n </button>\n <Popover\n anchorRef={triggerRef}\n isOpen={isVisible}\n matchAnchorWidth\n panelRef={listRef}\n id={listId}\n role=\"listbox\"\n aria-label={rest[\"aria-label\"] ?? placeholder}\n className=\"ds-surface-raised ds-select__menu\"\n >\n <div onKeyDown={handleKeyDown}>\n {options.map((option, index) => (\n <div\n key={option.value}\n id={`${listId}-option-${index}`}\n role=\"option\"\n aria-selected={option.value === current}\n aria-disabled={option.isDisabled || undefined}\n data-active={index === activeIndex || undefined}\n className=\"ds-select__option\"\n onMouseEnter={() => !option.isDisabled && setActiveIndex(index)}\n onClick={() => {\n if (!option.isDisabled) {\n commit(option.value);\n triggerRef.current?.focus();\n }\n }}\n >\n <span className=\"ds-select__option-body\">\n <span className=\"ds-select__option-label\">{option.label}</span>\n {option.description && (\n <span className=\"ds-select__option-description\">{option.description}</span>\n )}\n </span>\n {option.value === current && <Icon name=\"check\" size={16} />}\n </div>\n ))}\n </div>\n </Popover>\n </div>\n );\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["forwardRef","useState","useRef","useId","useCallback","Button","Icon","Popover","require_Icon","require_components_Button_index","require_components_Popover_index","react","react_jsx_runtime","cx","parts","Select","rest","internal","setInternal","defaultValue","current","value","isOpen","setOpen","activeIndex","setActiveIndex","rootRef","triggerRef","listRef","listId","effectiveDisabled","isDisabled","disabled","isVisible","selected","options","option","enabled","commit","next","onValueChange","index","onPointerDown","target","event","step","order","o","delta","handleKeyDown","pick","node","ref","isInvalid","className","onClick","open","onKeyDown","placeholder","menuPlacement"],"sources":["../../../src/components/Select/index.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n} from \"react\";\nimport { Icon } from \"../Icon\";\nimport { Button } from \"../Button\";\nimport { Popover, type PopoverPlacement } from \"../Popover\";\nimport type { FieldSize } from \"../Field\";\nimport \"../Field/style.css\";\nimport \"./style.css\";\n\nfunction cx(...parts: (string | undefined | false)[]) {\n return parts.filter(Boolean).join(\" \");\n}\n\nexport interface SelectOption {\n value: string;\n label: string;\n /** Secondary line under the label. */\n description?: string;\n isDisabled?: boolean;\n}\n\nexport interface SelectProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"value\" | \"defaultValue\" | \"onChange\"> {\n options: SelectOption[];\n /** Controlled value. Leave undefined to let the select hold its own. */\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n placeholder?: string;\n size?: FieldSize;\n isDisabled?: boolean;\n isInvalid?: boolean;\n /** Preferred side of the menu; flips when space requires it. */\n menuPlacement?: PopoverPlacement;\n}\n\n/**\n * One value out of a known list. Wears the field skin, opens a listbox: arrows\n * walk the options, Enter commits, Escape closes without changing anything.\n */\nexport const Select = forwardRef<HTMLButtonElement, SelectProps>(function Select(\n {\n options,\n value,\n defaultValue,\n onValueChange,\n placeholder = \"Select an option\",\n size = \"md\",\n isDisabled = false,\n isInvalid = false,\n menuPlacement = \"bottom\",\n className,\n disabled,\n onClick,\n onKeyDown,\n ...rest\n },\n ref,\n) {\n const [internal, setInternal] = useState(defaultValue ?? \"\");\n const current = value ?? internal;\n const [isOpen, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(0);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const listRef = useRef<HTMLDivElement | null>(null);\n const listId = useId();\n const effectiveDisabled = isDisabled || disabled;\n const isVisible = isOpen && !effectiveDisabled;\n\n const selected = options.find((option) => option.value === current);\n const enabled = options.filter((option) => !option.isDisabled);\n\n const commit = useCallback(\n (next: string) => {\n if (value === undefined) setInternal(next);\n onValueChange?.(next);\n setOpen(false);\n },\n [onValueChange, value],\n );\n\n useEffect(() => {\n if (!isVisible) return;\n const index = options.findIndex((option) => option.value === current && !option.isDisabled);\n setActiveIndex(index < 0 ? options.indexOf(enabled[0]!) : index);\n const onPointerDown = (event: MouseEvent) => {\n const target = event.target as Node;\n if (!rootRef.current?.contains(target) && !listRef.current?.contains(target)) setOpen(false);\n };\n document.addEventListener(\"mousedown\", onPointerDown);\n return () => document.removeEventListener(\"mousedown\", onPointerDown);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isVisible]);\n\n useEffect(() => {\n if (!isVisible) return;\n const activeOption = listRef.current?.querySelectorAll<HTMLElement>(\"[role='option']\")[activeIndex];\n activeOption?.scrollIntoView({ block: \"nearest\" });\n }, [activeIndex, isVisible]);\n\n const step = (delta: number) => {\n const order = options.map((option, index) => ({ option, index })).filter((o) => !o.option.isDisabled);\n if (order.length === 0) return;\n const at = order.findIndex((o) => o.index === activeIndex);\n const next = order[(at + delta + order.length) % order.length]!;\n setActiveIndex(next.index);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (effectiveDisabled) return;\n if (event.key === \"Escape\") {\n if (!isVisible) return;\n // Claims Escape so an enclosing Drawer stays open.\n event.preventDefault();\n setOpen(false);\n triggerRef.current?.focus();\n return;\n }\n if (!isVisible && (event.key === \"ArrowDown\" || event.key === \"ArrowUp\" || event.key === \"Enter\" || event.key === \" \")) {\n event.preventDefault();\n setOpen(true);\n return;\n }\n if (!isVisible) return;\n if (event.key === \"Tab\") {\n setOpen(false);\n return;\n }\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n step(event.key === \"ArrowDown\" ? 1 : -1);\n } else if (event.key === \"Home\" || event.key === \"End\") {\n event.preventDefault();\n const pick = event.key === \"Home\" ? enabled[0] : enabled[enabled.length - 1];\n if (pick) setActiveIndex(options.indexOf(pick));\n } else if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n const option = options[activeIndex];\n if (option && !option.isDisabled) commit(option.value);\n }\n };\n\n return (\n <div className=\"ds-select-root\" ref={rootRef}>\n <Button\n ref={(node) => {\n triggerRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n }}\n size={size}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={isVisible}\n aria-controls={isVisible ? listId : undefined}\n aria-activedescendant={isVisible && options[activeIndex] && !options[activeIndex].isDisabled ? `${listId}-option-${activeIndex}` : undefined}\n aria-invalid={isInvalid || undefined}\n isDisabled={effectiveDisabled}\n data-placeholder={selected ? undefined : \"\"}\n className={cx(\"ds-field-skin\", \"ds-select\", className)}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented) setOpen((open) => !open);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (!event.defaultPrevented) handleKeyDown(event);\n }}\n {...rest}\n >\n <span className=\"ds-select__value\">{selected ? selected.label : placeholder}</span>\n <Icon name=\"chevron-down\" size={16} className=\"ds-select__chevron\" />\n </Button>\n <Popover\n anchorRef={triggerRef}\n isOpen={isVisible}\n placement={menuPlacement}\n matchAnchorWidth\n panelRef={listRef}\n id={listId}\n role=\"listbox\"\n aria-label={rest[\"aria-labelledby\"] ? undefined : rest[\"aria-label\"] ?? placeholder}\n aria-labelledby={rest[\"aria-labelledby\"]}\n className=\"ds-surface-raised ds-select__menu\"\n >\n <div onKeyDown={handleKeyDown} onPointerDown={(event) => event.preventDefault()}>\n {options.map((option, index) => (\n <Button\n key={option.value}\n variant={index === activeIndex ? \"active\" : \"simple\"}\n size=\"sm\"\n isDisabled={option.isDisabled}\n tabIndex={-1}\n id={`${listId}-option-${index}`}\n role=\"option\"\n aria-selected={option.value === current}\n aria-disabled={option.isDisabled || undefined}\n data-active={index === activeIndex || undefined}\n className=\"ds-select__option\"\n onMouseEnter={() => !option.isDisabled && setActiveIndex(index)}\n onClick={() => {\n if (!option.isDisabled) {\n commit(option.value);\n triggerRef.current?.focus();\n }\n }}\n >\n <span className=\"ds-select__option-body\">\n <span className=\"ds-select__option-label\">{option.label}</span>\n {option.description && (\n <span className=\"ds-select__option-description\">{option.description}</span>\n )}\n </span>\n {option.value === current && <Icon name=\"check\" size={16} />}\n </Button>\n ))}\n </div>\n </Popover>\n </div>\n );\n});\n"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { type ButtonHTMLAttributes } from "react";
2
+ import { type PopoverPlacement } from "../Popover/index.cjs";
2
3
  import type { FieldSize } from "../Field/index.cjs";
3
4
  export interface SelectOption {
4
5
  value: string;
@@ -17,6 +18,8 @@ export interface SelectProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement
17
18
  size?: FieldSize;
18
19
  isDisabled?: boolean;
19
20
  isInvalid?: boolean;
21
+ /** Preferred side of the menu; flips when space requires it. */
22
+ menuPlacement?: PopoverPlacement;
20
23
  }
21
24
  /**
22
25
  * One value out of a known list. Wears the field skin, opens a listbox: arrows
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../../src/components/Select/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,oBAAoB,EAC1B,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,oBAAoB,CAAC;AAC5B,OAAO,aAAa,CAAC;AAMrB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WACf,SAAQ,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,OAAO,GAAG,cAAc,GAAG,UAAU,CAAC;IAC5F,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM,2GA4KjB,CAAC"}
1
+ {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../../src/components/Select/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,oBAAoB,EAC1B,MAAM,OAAO,CAAC;AAGf,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,oBAAoB,CAAC;AAC5B,OAAO,aAAa,CAAC;AAMrB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WACf,SAAQ,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,OAAO,GAAG,cAAc,GAAG,UAAU,CAAC;IAC5F,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gEAAgE;IAChE,aAAa,CAAC,EAAE,gBAAgB,CAAC;CAClC;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM,2GAqLjB,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { type ButtonHTMLAttributes } from "react";
2
+ import { type PopoverPlacement } from "../Popover/index.js";
2
3
  import type { FieldSize } from "../Field/index.js";
3
4
  export interface SelectOption {
4
5
  value: string;
@@ -17,6 +18,8 @@ export interface SelectProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement
17
18
  size?: FieldSize;
18
19
  isDisabled?: boolean;
19
20
  isInvalid?: boolean;
21
+ /** Preferred side of the menu; flips when space requires it. */
22
+ menuPlacement?: PopoverPlacement;
20
23
  }
21
24
  /**
22
25
  * One value out of a known list. Wears the field skin, opens a listbox: arrows
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Select/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,oBAAoB,EAC1B,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,oBAAoB,CAAC;AAC5B,OAAO,aAAa,CAAC;AAMrB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WACf,SAAQ,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,OAAO,GAAG,cAAc,GAAG,UAAU,CAAC;IAC5F,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM,2GA4KjB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Select/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,oBAAoB,EAC1B,MAAM,OAAO,CAAC;AAGf,OAAO,EAAW,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,oBAAoB,CAAC;AAC5B,OAAO,aAAa,CAAC;AAMrB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,WACf,SAAQ,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,OAAO,GAAG,cAAc,GAAG,UAAU,CAAC;IAC5F,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gEAAgE;IAChE,aAAa,CAAC,EAAE,gBAAgB,CAAC;CAClC;AAED;;;GAGG;AACH,eAAO,MAAM,MAAM,2GAqLjB,CAAC"}
@@ -1,129 +1,138 @@
1
1
  import { t as e } from "../../chunks/Icon-CGY1FNXT.js";
2
+ import { Button as t } from "../Button/index.js";
2
3
  /* empty css */
3
- import { Popover as t } from "../Popover/index.js";
4
- import { forwardRef as n, useCallback as r, useEffect as i, useId as a, useRef as o, useState as s } from "react";
5
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
4
+ import { Popover as n } from "../Popover/index.js";
5
+ import { forwardRef as r, useCallback as i, useEffect as a, useId as o, useRef as s, useState as c } from "react";
6
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
6
7
  //#region src/components/Select/index.tsx
7
- function u(...e) {
8
+ function d(...e) {
8
9
  return e.filter(Boolean).join(" ");
9
10
  }
10
- var d = n(function({ options: n, value: d, defaultValue: f, onValueChange: p, placeholder: m = "Select an option", size: h = "md", isDisabled: g = !1, isInvalid: _ = !1, className: v, disabled: y, onClick: b, onKeyDown: x, ...S }, C) {
11
- let [w, T] = s(f ?? ""), E = d ?? w, [D, O] = s(!1), [k, A] = s(0), j = o(null), M = o(null), N = o(null), P = a(), F = g || y, I = D && !F, L = n.find((e) => e.value === E), R = n.filter((e) => !e.isDisabled), z = r((e) => {
12
- d === void 0 && T(e), p?.(e), O(!1);
13
- }, [p, d]);
14
- i(() => {
15
- if (!I) return;
16
- let e = n.findIndex((e) => e.value === E && !e.isDisabled);
17
- A(e < 0 ? n.indexOf(R[0]) : e);
11
+ var f = r(function({ options: r, value: f, defaultValue: p, onValueChange: m, placeholder: h = "Select an option", size: g = "md", isDisabled: _ = !1, isInvalid: v = !1, menuPlacement: y = "bottom", className: b, disabled: x, onClick: S, onKeyDown: C, ...w }, T) {
12
+ let [E, D] = c(p ?? ""), O = f ?? E, [k, A] = c(!1), [j, M] = c(0), N = s(null), P = s(null), F = s(null), I = o(), L = _ || x, R = k && !L, z = r.find((e) => e.value === O), B = r.filter((e) => !e.isDisabled), V = i((e) => {
13
+ f === void 0 && D(e), m?.(e), A(!1);
14
+ }, [m, f]);
15
+ a(() => {
16
+ if (!R) return;
17
+ let e = r.findIndex((e) => e.value === O && !e.isDisabled);
18
+ M(e < 0 ? r.indexOf(B[0]) : e);
18
19
  let t = (e) => {
19
20
  let t = e.target;
20
- !j.current?.contains(t) && !N.current?.contains(t) && O(!1);
21
+ !N.current?.contains(t) && !F.current?.contains(t) && A(!1);
21
22
  };
22
23
  return document.addEventListener("mousedown", t), () => document.removeEventListener("mousedown", t);
23
- }, [I]), i(() => {
24
- I && (N.current?.querySelectorAll("[role='option']")[k])?.scrollIntoView({ block: "nearest" });
25
- }, [k, I]);
26
- let B = (e) => {
27
- let t = n.map((e, t) => ({
24
+ }, [R]), a(() => {
25
+ R && (F.current?.querySelectorAll("[role='option']")[j])?.scrollIntoView({ block: "nearest" });
26
+ }, [j, R]);
27
+ let H = (e) => {
28
+ let t = r.map((e, t) => ({
28
29
  option: e,
29
30
  index: t
30
31
  })).filter((e) => !e.option.isDisabled);
31
32
  if (t.length === 0) return;
32
- let r = t[(t.findIndex((e) => e.index === k) + e + t.length) % t.length];
33
- A(r.index);
34
- }, V = (e) => {
35
- if (!F) {
36
- if (e.key === "Escape") O(!1), M.current?.focus();
37
- else if (!I && (e.key === "ArrowDown" || e.key === "ArrowUp" || e.key === "Enter" || e.key === " ")) e.preventDefault(), O(!0);
38
- else if (I) {
39
- if (e.key === "Tab") O(!1);
40
- else if (e.key === "ArrowDown" || e.key === "ArrowUp") e.preventDefault(), B(e.key === "ArrowDown" ? 1 : -1);
33
+ let n = t[(t.findIndex((e) => e.index === j) + e + t.length) % t.length];
34
+ M(n.index);
35
+ }, U = (e) => {
36
+ if (!L) {
37
+ if (e.key === "Escape") {
38
+ if (!R) return;
39
+ e.preventDefault(), A(!1), P.current?.focus();
40
+ } else if (!R && (e.key === "ArrowDown" || e.key === "ArrowUp" || e.key === "Enter" || e.key === " ")) e.preventDefault(), A(!0);
41
+ else if (R) {
42
+ if (e.key === "Tab") A(!1);
43
+ else if (e.key === "ArrowDown" || e.key === "ArrowUp") e.preventDefault(), H(e.key === "ArrowDown" ? 1 : -1);
41
44
  else if (e.key === "Home" || e.key === "End") {
42
45
  e.preventDefault();
43
- let t = e.key === "Home" ? R[0] : R[R.length - 1];
44
- t && A(n.indexOf(t));
46
+ let t = e.key === "Home" ? B[0] : B[B.length - 1];
47
+ t && M(r.indexOf(t));
45
48
  } else if (e.key === "Enter" || e.key === " ") {
46
49
  e.preventDefault();
47
- let t = n[k];
48
- t && !t.isDisabled && z(t.value);
50
+ let t = r[j];
51
+ t && !t.isDisabled && V(t.value);
49
52
  }
50
53
  }
51
54
  }
52
55
  };
53
- return /* @__PURE__ */ l("div", {
56
+ return /* @__PURE__ */ u("div", {
54
57
  className: "ds-select-root",
55
- ref: j,
56
- children: [/* @__PURE__ */ l("button", {
58
+ ref: N,
59
+ children: [/* @__PURE__ */ u(t, {
57
60
  ref: (e) => {
58
- M.current = e, typeof C == "function" ? C(e) : C && (C.current = e);
61
+ P.current = e, typeof T == "function" ? T(e) : T && (T.current = e);
59
62
  },
60
- type: "button",
63
+ size: g,
61
64
  role: "combobox",
62
65
  "aria-haspopup": "listbox",
63
- "aria-expanded": I,
64
- "aria-controls": I ? P : void 0,
65
- "aria-activedescendant": I && n[k] && !n[k].isDisabled ? `${P}-option-${k}` : void 0,
66
- "aria-invalid": _ || void 0,
67
- disabled: F,
68
- "data-size": h,
69
- "data-placeholder": L ? void 0 : "",
70
- className: u("ds-field-skin", "ds-select", v),
66
+ "aria-expanded": R,
67
+ "aria-controls": R ? I : void 0,
68
+ "aria-activedescendant": R && r[j] && !r[j].isDisabled ? `${I}-option-${j}` : void 0,
69
+ "aria-invalid": v || void 0,
70
+ isDisabled: L,
71
+ "data-placeholder": z ? void 0 : "",
72
+ className: d("ds-field-skin", "ds-select", b),
71
73
  onClick: (e) => {
72
- b?.(e), e.defaultPrevented || O((e) => !e);
74
+ S?.(e), e.defaultPrevented || A((e) => !e);
73
75
  },
74
76
  onKeyDown: (e) => {
75
- x?.(e), e.defaultPrevented || V(e);
77
+ C?.(e), e.defaultPrevented || U(e);
76
78
  },
77
- ...S,
78
- children: [/* @__PURE__ */ c("span", {
79
+ ...w,
80
+ children: [/* @__PURE__ */ l("span", {
79
81
  className: "ds-select__value",
80
- children: L ? L.label : m
81
- }), /* @__PURE__ */ c(e, {
82
+ children: z ? z.label : h
83
+ }), /* @__PURE__ */ l(e, {
82
84
  name: "chevron-down",
83
85
  size: 16,
84
86
  className: "ds-select__chevron"
85
87
  })]
86
- }), /* @__PURE__ */ c(t, {
87
- anchorRef: M,
88
- isOpen: I,
88
+ }), /* @__PURE__ */ l(n, {
89
+ anchorRef: P,
90
+ isOpen: R,
91
+ placement: y,
89
92
  matchAnchorWidth: !0,
90
- panelRef: N,
91
- id: P,
93
+ panelRef: F,
94
+ id: I,
92
95
  role: "listbox",
93
- "aria-label": S["aria-label"] ?? m,
96
+ "aria-label": w["aria-labelledby"] ? void 0 : w["aria-label"] ?? h,
97
+ "aria-labelledby": w["aria-labelledby"],
94
98
  className: "ds-surface-raised ds-select__menu",
95
- children: /* @__PURE__ */ c("div", {
96
- onKeyDown: V,
97
- children: n.map((t, n) => /* @__PURE__ */ l("div", {
98
- id: `${P}-option-${n}`,
99
+ children: /* @__PURE__ */ l("div", {
100
+ onKeyDown: U,
101
+ onPointerDown: (e) => e.preventDefault(),
102
+ children: r.map((n, r) => /* @__PURE__ */ u(t, {
103
+ variant: r === j ? "active" : "simple",
104
+ size: "sm",
105
+ isDisabled: n.isDisabled,
106
+ tabIndex: -1,
107
+ id: `${I}-option-${r}`,
99
108
  role: "option",
100
- "aria-selected": t.value === E,
101
- "aria-disabled": t.isDisabled || void 0,
102
- "data-active": n === k || void 0,
109
+ "aria-selected": n.value === O,
110
+ "aria-disabled": n.isDisabled || void 0,
111
+ "data-active": r === j || void 0,
103
112
  className: "ds-select__option",
104
- onMouseEnter: () => !t.isDisabled && A(n),
113
+ onMouseEnter: () => !n.isDisabled && M(r),
105
114
  onClick: () => {
106
- t.isDisabled || (z(t.value), M.current?.focus());
115
+ n.isDisabled || (V(n.value), P.current?.focus());
107
116
  },
108
- children: [/* @__PURE__ */ l("span", {
117
+ children: [/* @__PURE__ */ u("span", {
109
118
  className: "ds-select__option-body",
110
- children: [/* @__PURE__ */ c("span", {
119
+ children: [/* @__PURE__ */ l("span", {
111
120
  className: "ds-select__option-label",
112
- children: t.label
113
- }), t.description && /* @__PURE__ */ c("span", {
121
+ children: n.label
122
+ }), n.description && /* @__PURE__ */ l("span", {
114
123
  className: "ds-select__option-description",
115
- children: t.description
124
+ children: n.description
116
125
  })]
117
- }), t.value === E && /* @__PURE__ */ c(e, {
126
+ }), n.value === O && /* @__PURE__ */ l(e, {
118
127
  name: "check",
119
128
  size: 16
120
129
  })]
121
- }, t.value))
130
+ }, n.value))
122
131
  })
123
132
  })]
124
133
  });
125
134
  });
126
135
  //#endregion
127
- export { d as Select };
136
+ export { f as Select };
128
137
 
129
138
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["Icon","cx","parts","Select","forwardRef","rest","internal","setInternal","useState","defaultValue","current","value","isOpen","setOpen","activeIndex","setActiveIndex","rootRef","useRef","triggerRef","listRef","listId","useId","effectiveDisabled","isDisabled","disabled","isVisible","selected","options","option","enabled","commit","useCallback","next","onValueChange","useEffect","index","onPointerDown","target","event","step","order","o","delta","handleKeyDown","pick","node","ref","isInvalid","size","className","onClick","open","onKeyDown","placeholder","Popover"],"sources":["../../../src/components/Select/index.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n} from \"react\";\nimport { Icon } from \"../Icon\";\nimport { Popover } from \"../Popover\";\nimport type { FieldSize } from \"../Field\";\nimport \"../Field/style.css\";\nimport \"./style.css\";\n\nfunction cx(...parts: (string | undefined | false)[]) {\n return parts.filter(Boolean).join(\" \");\n}\n\nexport interface SelectOption {\n value: string;\n label: string;\n /** Secondary line under the label. */\n description?: string;\n isDisabled?: boolean;\n}\n\nexport interface SelectProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"value\" | \"defaultValue\" | \"onChange\"> {\n options: SelectOption[];\n /** Controlled value. Leave undefined to let the select hold its own. */\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n placeholder?: string;\n size?: FieldSize;\n isDisabled?: boolean;\n isInvalid?: boolean;\n}\n\n/**\n * One value out of a known list. Wears the field skin, opens a listbox: arrows\n * walk the options, Enter commits, Escape closes without changing anything.\n */\nexport const Select = forwardRef<HTMLButtonElement, SelectProps>(function Select(\n {\n options,\n value,\n defaultValue,\n onValueChange,\n placeholder = \"Select an option\",\n size = \"md\",\n isDisabled = false,\n isInvalid = false,\n className,\n disabled,\n onClick,\n onKeyDown,\n ...rest\n },\n ref,\n) {\n const [internal, setInternal] = useState(defaultValue ?? \"\");\n const current = value ?? internal;\n const [isOpen, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(0);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const listRef = useRef<HTMLDivElement | null>(null);\n const listId = useId();\n const effectiveDisabled = isDisabled || disabled;\n const isVisible = isOpen && !effectiveDisabled;\n\n const selected = options.find((option) => option.value === current);\n const enabled = options.filter((option) => !option.isDisabled);\n\n const commit = useCallback(\n (next: string) => {\n if (value === undefined) setInternal(next);\n onValueChange?.(next);\n setOpen(false);\n },\n [onValueChange, value],\n );\n\n useEffect(() => {\n if (!isVisible) return;\n const index = options.findIndex((option) => option.value === current && !option.isDisabled);\n setActiveIndex(index < 0 ? options.indexOf(enabled[0]!) : index);\n const onPointerDown = (event: MouseEvent) => {\n const target = event.target as Node;\n if (!rootRef.current?.contains(target) && !listRef.current?.contains(target)) setOpen(false);\n };\n document.addEventListener(\"mousedown\", onPointerDown);\n return () => document.removeEventListener(\"mousedown\", onPointerDown);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isVisible]);\n\n useEffect(() => {\n if (!isVisible) return;\n const activeOption = listRef.current?.querySelectorAll<HTMLElement>(\"[role='option']\")[activeIndex];\n activeOption?.scrollIntoView({ block: \"nearest\" });\n }, [activeIndex, isVisible]);\n\n const step = (delta: number) => {\n const order = options.map((option, index) => ({ option, index })).filter((o) => !o.option.isDisabled);\n if (order.length === 0) return;\n const at = order.findIndex((o) => o.index === activeIndex);\n const next = order[(at + delta + order.length) % order.length]!;\n setActiveIndex(next.index);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (effectiveDisabled) return;\n if (event.key === \"Escape\") {\n setOpen(false);\n triggerRef.current?.focus();\n return;\n }\n if (!isVisible && (event.key === \"ArrowDown\" || event.key === \"ArrowUp\" || event.key === \"Enter\" || event.key === \" \")) {\n event.preventDefault();\n setOpen(true);\n return;\n }\n if (!isVisible) return;\n if (event.key === \"Tab\") {\n setOpen(false);\n return;\n }\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n step(event.key === \"ArrowDown\" ? 1 : -1);\n } else if (event.key === \"Home\" || event.key === \"End\") {\n event.preventDefault();\n const pick = event.key === \"Home\" ? enabled[0] : enabled[enabled.length - 1];\n if (pick) setActiveIndex(options.indexOf(pick));\n } else if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n const option = options[activeIndex];\n if (option && !option.isDisabled) commit(option.value);\n }\n };\n\n return (\n <div className=\"ds-select-root\" ref={rootRef}>\n <button\n ref={(node) => {\n triggerRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n }}\n type=\"button\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={isVisible}\n aria-controls={isVisible ? listId : undefined}\n aria-activedescendant={isVisible && options[activeIndex] && !options[activeIndex].isDisabled ? `${listId}-option-${activeIndex}` : undefined}\n aria-invalid={isInvalid || undefined}\n disabled={effectiveDisabled}\n data-size={size}\n data-placeholder={selected ? undefined : \"\"}\n className={cx(\"ds-field-skin\", \"ds-select\", className)}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented) setOpen((open) => !open);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (!event.defaultPrevented) handleKeyDown(event);\n }}\n {...rest}\n >\n <span className=\"ds-select__value\">{selected ? selected.label : placeholder}</span>\n <Icon name=\"chevron-down\" size={16} className=\"ds-select__chevron\" />\n </button>\n <Popover\n anchorRef={triggerRef}\n isOpen={isVisible}\n matchAnchorWidth\n panelRef={listRef}\n id={listId}\n role=\"listbox\"\n aria-label={rest[\"aria-label\"] ?? placeholder}\n className=\"ds-surface-raised ds-select__menu\"\n >\n <div onKeyDown={handleKeyDown}>\n {options.map((option, index) => (\n <div\n key={option.value}\n id={`${listId}-option-${index}`}\n role=\"option\"\n aria-selected={option.value === current}\n aria-disabled={option.isDisabled || undefined}\n data-active={index === activeIndex || undefined}\n className=\"ds-select__option\"\n onMouseEnter={() => !option.isDisabled && setActiveIndex(index)}\n onClick={() => {\n if (!option.isDisabled) {\n commit(option.value);\n triggerRef.current?.focus();\n }\n }}\n >\n <span className=\"ds-select__option-body\">\n <span className=\"ds-select__option-label\">{option.label}</span>\n {option.description && (\n <span className=\"ds-select__option-description\">{option.description}</span>\n )}\n </span>\n {option.value === current && <Icon name=\"check\" size={16} />}\n </div>\n ))}\n </div>\n </Popover>\n </div>\n );\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["Icon","cx","parts","Select","forwardRef","rest","internal","setInternal","useState","defaultValue","current","value","isOpen","setOpen","activeIndex","setActiveIndex","rootRef","useRef","triggerRef","listRef","listId","useId","effectiveDisabled","isDisabled","disabled","isVisible","selected","options","option","enabled","commit","useCallback","next","onValueChange","useEffect","index","onPointerDown","target","event","step","order","o","delta","handleKeyDown","pick","Button","node","ref","isInvalid","className","onClick","open","onKeyDown","placeholder","Popover","menuPlacement"],"sources":["../../../src/components/Select/index.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ButtonHTMLAttributes,\n} from \"react\";\nimport { Icon } from \"../Icon\";\nimport { Button } from \"../Button\";\nimport { Popover, type PopoverPlacement } from \"../Popover\";\nimport type { FieldSize } from \"../Field\";\nimport \"../Field/style.css\";\nimport \"./style.css\";\n\nfunction cx(...parts: (string | undefined | false)[]) {\n return parts.filter(Boolean).join(\" \");\n}\n\nexport interface SelectOption {\n value: string;\n label: string;\n /** Secondary line under the label. */\n description?: string;\n isDisabled?: boolean;\n}\n\nexport interface SelectProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"value\" | \"defaultValue\" | \"onChange\"> {\n options: SelectOption[];\n /** Controlled value. Leave undefined to let the select hold its own. */\n value?: string;\n defaultValue?: string;\n onValueChange?: (value: string) => void;\n placeholder?: string;\n size?: FieldSize;\n isDisabled?: boolean;\n isInvalid?: boolean;\n /** Preferred side of the menu; flips when space requires it. */\n menuPlacement?: PopoverPlacement;\n}\n\n/**\n * One value out of a known list. Wears the field skin, opens a listbox: arrows\n * walk the options, Enter commits, Escape closes without changing anything.\n */\nexport const Select = forwardRef<HTMLButtonElement, SelectProps>(function Select(\n {\n options,\n value,\n defaultValue,\n onValueChange,\n placeholder = \"Select an option\",\n size = \"md\",\n isDisabled = false,\n isInvalid = false,\n menuPlacement = \"bottom\",\n className,\n disabled,\n onClick,\n onKeyDown,\n ...rest\n },\n ref,\n) {\n const [internal, setInternal] = useState(defaultValue ?? \"\");\n const current = value ?? internal;\n const [isOpen, setOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(0);\n const rootRef = useRef<HTMLDivElement | null>(null);\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n const listRef = useRef<HTMLDivElement | null>(null);\n const listId = useId();\n const effectiveDisabled = isDisabled || disabled;\n const isVisible = isOpen && !effectiveDisabled;\n\n const selected = options.find((option) => option.value === current);\n const enabled = options.filter((option) => !option.isDisabled);\n\n const commit = useCallback(\n (next: string) => {\n if (value === undefined) setInternal(next);\n onValueChange?.(next);\n setOpen(false);\n },\n [onValueChange, value],\n );\n\n useEffect(() => {\n if (!isVisible) return;\n const index = options.findIndex((option) => option.value === current && !option.isDisabled);\n setActiveIndex(index < 0 ? options.indexOf(enabled[0]!) : index);\n const onPointerDown = (event: MouseEvent) => {\n const target = event.target as Node;\n if (!rootRef.current?.contains(target) && !listRef.current?.contains(target)) setOpen(false);\n };\n document.addEventListener(\"mousedown\", onPointerDown);\n return () => document.removeEventListener(\"mousedown\", onPointerDown);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isVisible]);\n\n useEffect(() => {\n if (!isVisible) return;\n const activeOption = listRef.current?.querySelectorAll<HTMLElement>(\"[role='option']\")[activeIndex];\n activeOption?.scrollIntoView({ block: \"nearest\" });\n }, [activeIndex, isVisible]);\n\n const step = (delta: number) => {\n const order = options.map((option, index) => ({ option, index })).filter((o) => !o.option.isDisabled);\n if (order.length === 0) return;\n const at = order.findIndex((o) => o.index === activeIndex);\n const next = order[(at + delta + order.length) % order.length]!;\n setActiveIndex(next.index);\n };\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (effectiveDisabled) return;\n if (event.key === \"Escape\") {\n if (!isVisible) return;\n // Claims Escape so an enclosing Drawer stays open.\n event.preventDefault();\n setOpen(false);\n triggerRef.current?.focus();\n return;\n }\n if (!isVisible && (event.key === \"ArrowDown\" || event.key === \"ArrowUp\" || event.key === \"Enter\" || event.key === \" \")) {\n event.preventDefault();\n setOpen(true);\n return;\n }\n if (!isVisible) return;\n if (event.key === \"Tab\") {\n setOpen(false);\n return;\n }\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n step(event.key === \"ArrowDown\" ? 1 : -1);\n } else if (event.key === \"Home\" || event.key === \"End\") {\n event.preventDefault();\n const pick = event.key === \"Home\" ? enabled[0] : enabled[enabled.length - 1];\n if (pick) setActiveIndex(options.indexOf(pick));\n } else if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n const option = options[activeIndex];\n if (option && !option.isDisabled) commit(option.value);\n }\n };\n\n return (\n <div className=\"ds-select-root\" ref={rootRef}>\n <Button\n ref={(node) => {\n triggerRef.current = node;\n if (typeof ref === \"function\") ref(node);\n else if (ref) ref.current = node;\n }}\n size={size}\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n aria-expanded={isVisible}\n aria-controls={isVisible ? listId : undefined}\n aria-activedescendant={isVisible && options[activeIndex] && !options[activeIndex].isDisabled ? `${listId}-option-${activeIndex}` : undefined}\n aria-invalid={isInvalid || undefined}\n isDisabled={effectiveDisabled}\n data-placeholder={selected ? undefined : \"\"}\n className={cx(\"ds-field-skin\", \"ds-select\", className)}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented) setOpen((open) => !open);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (!event.defaultPrevented) handleKeyDown(event);\n }}\n {...rest}\n >\n <span className=\"ds-select__value\">{selected ? selected.label : placeholder}</span>\n <Icon name=\"chevron-down\" size={16} className=\"ds-select__chevron\" />\n </Button>\n <Popover\n anchorRef={triggerRef}\n isOpen={isVisible}\n placement={menuPlacement}\n matchAnchorWidth\n panelRef={listRef}\n id={listId}\n role=\"listbox\"\n aria-label={rest[\"aria-labelledby\"] ? undefined : rest[\"aria-label\"] ?? placeholder}\n aria-labelledby={rest[\"aria-labelledby\"]}\n className=\"ds-surface-raised ds-select__menu\"\n >\n <div onKeyDown={handleKeyDown} onPointerDown={(event) => event.preventDefault()}>\n {options.map((option, index) => (\n <Button\n key={option.value}\n variant={index === activeIndex ? \"active\" : \"simple\"}\n size=\"sm\"\n isDisabled={option.isDisabled}\n tabIndex={-1}\n id={`${listId}-option-${index}`}\n role=\"option\"\n aria-selected={option.value === current}\n aria-disabled={option.isDisabled || undefined}\n data-active={index === activeIndex || undefined}\n className=\"ds-select__option\"\n onMouseEnter={() => !option.isDisabled && setActiveIndex(index)}\n onClick={() => {\n if (!option.isDisabled) {\n commit(option.value);\n triggerRef.current?.focus();\n }\n }}\n >\n <span className=\"ds-select__option-body\">\n <span className=\"ds-select__option-label\">{option.label}</span>\n {option.description && (\n <span className=\"ds-select__option-description\">{option.description}</span>\n )}\n </span>\n {option.value === current && <Icon name=\"check\" size={16} />}\n </Button>\n ))}\n </div>\n </Popover>\n </div>\n );\n});\n"],"mappings":"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"}
@@ -9,26 +9,10 @@
9
9
  align-items: center;
10
10
  justify-content: space-between;
11
11
  gap: var(--space-2);
12
- padding: 0 10px;
13
12
  text-align: start;
14
13
  cursor: pointer;
15
14
  }
16
15
 
17
- .ds-select[data-size="sm"] {
18
- block-size: var(--field-height-sm);
19
- font-size: var(--field-font-size-sm);
20
- }
21
-
22
- .ds-select[data-size="md"] {
23
- block-size: var(--field-height-md);
24
- font-size: var(--field-font-size-md);
25
- }
26
-
27
- .ds-select[data-size="lg"] {
28
- block-size: var(--field-height-lg);
29
- font-size: var(--field-font-size-md);
30
- }
31
-
32
16
  .ds-select[data-placeholder] .ds-select__value {
33
17
  color: var(--color-text-muted);
34
18
  }
@@ -49,28 +33,11 @@
49
33
  padding: var(--space-1);
50
34
  }
51
35
 
52
- .ds-select__option {
53
- display: flex;
54
- align-items: center;
55
- gap: var(--space-2);
56
- padding: var(--space-2) var(--space-3);
57
- border-radius: var(--radius-sm);
58
- color: var(--color-text);
59
- font-size: var(--font-size-sm);
60
- cursor: pointer;
61
- }
62
-
63
- .ds-select__option[data-active] {
64
- background: var(--field-hover);
65
- }
66
-
67
- .ds-select__option[aria-selected="true"] {
68
- font-weight: var(--font-weight-semibold);
69
- }
70
-
71
- .ds-select__option[aria-disabled="true"] {
72
- opacity: 45%;
73
- cursor: not-allowed;
36
+ .ds-select__option.ds-button {
37
+ inline-size: 100%;
38
+ height: auto;
39
+ min-block-size: var(--field-height-sm);
40
+ text-align: start;
74
41
  }
75
42
 
76
43
  .ds-select__option-body {