@nori-ui/core 1.0.6 → 1.1.0

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 (166) hide show
  1. package/dist/chunk-2UXKXUX2.js +286 -0
  2. package/dist/chunk-2UXKXUX2.js.map +1 -0
  3. package/dist/{chunk-DDGMLLS3.js → chunk-46OT4PA6.js} +3 -3
  4. package/dist/{chunk-DDGMLLS3.js.map → chunk-46OT4PA6.js.map} +1 -1
  5. package/dist/{chunk-SFNDR6DI.js → chunk-5BM6H2CD.js} +3 -3
  6. package/dist/{chunk-SFNDR6DI.js.map → chunk-5BM6H2CD.js.map} +1 -1
  7. package/dist/{chunk-EWWQQ5DB.js → chunk-6JVUVBZH.js} +5 -5
  8. package/dist/{chunk-EWWQQ5DB.js.map → chunk-6JVUVBZH.js.map} +1 -1
  9. package/dist/{chunk-FT2XBBQJ.js → chunk-6PO2IWB3.js} +8 -5
  10. package/dist/chunk-6PO2IWB3.js.map +1 -0
  11. package/dist/{chunk-YNKKEO2A.js → chunk-7D2BHQ6M.js} +3 -3
  12. package/dist/{chunk-YNKKEO2A.js.map → chunk-7D2BHQ6M.js.map} +1 -1
  13. package/dist/{chunk-MRJWPRCX.js → chunk-AFQIK6JI.js} +3 -3
  14. package/dist/{chunk-MRJWPRCX.js.map → chunk-AFQIK6JI.js.map} +1 -1
  15. package/dist/{chunk-IKLA2CVQ.js → chunk-C6TRLHMW.js} +21 -5
  16. package/dist/chunk-C6TRLHMW.js.map +1 -0
  17. package/dist/{chunk-NRYWNOG5.js → chunk-CGQIVFCN.js} +3 -3
  18. package/dist/{chunk-NRYWNOG5.js.map → chunk-CGQIVFCN.js.map} +1 -1
  19. package/dist/chunk-EFK7726V.js +104 -0
  20. package/dist/chunk-EFK7726V.js.map +1 -0
  21. package/dist/{chunk-3BDDPFCI.js → chunk-FDBQOQMW.js} +3 -3
  22. package/dist/{chunk-3BDDPFCI.js.map → chunk-FDBQOQMW.js.map} +1 -1
  23. package/dist/{chunk-XALU6LOT.js → chunk-GELLSU64.js} +3 -3
  24. package/dist/{chunk-XALU6LOT.js.map → chunk-GELLSU64.js.map} +1 -1
  25. package/dist/{chunk-BZLT6R62.js → chunk-GRDVE3IR.js} +3 -3
  26. package/dist/{chunk-BZLT6R62.js.map → chunk-GRDVE3IR.js.map} +1 -1
  27. package/dist/{chunk-OMU4R4Y5.js → chunk-HTF6FDB6.js} +3 -3
  28. package/dist/{chunk-OMU4R4Y5.js.map → chunk-HTF6FDB6.js.map} +1 -1
  29. package/dist/{chunk-X7APG7G2.js → chunk-HZKXPN6B.js} +154 -34
  30. package/dist/chunk-HZKXPN6B.js.map +1 -0
  31. package/dist/{chunk-WGT345SV.js → chunk-IGLMPAWE.js} +3 -3
  32. package/dist/{chunk-WGT345SV.js.map → chunk-IGLMPAWE.js.map} +1 -1
  33. package/dist/{chunk-5XEGZFG5.js → chunk-LWQZ257T.js} +3 -3
  34. package/dist/{chunk-5XEGZFG5.js.map → chunk-LWQZ257T.js.map} +1 -1
  35. package/dist/{chunk-RFW5SRZA.js → chunk-MJ4AGXS7.js} +3 -3
  36. package/dist/{chunk-RFW5SRZA.js.map → chunk-MJ4AGXS7.js.map} +1 -1
  37. package/dist/{chunk-PNP7L4TA.js → chunk-RM5TSXVE.js} +3 -3
  38. package/dist/{chunk-PNP7L4TA.js.map → chunk-RM5TSXVE.js.map} +1 -1
  39. package/dist/{chunk-MKSDYRWQ.js → chunk-SINLREQV.js} +3 -3
  40. package/dist/{chunk-MKSDYRWQ.js.map → chunk-SINLREQV.js.map} +1 -1
  41. package/dist/{chunk-TLS54G6Y.js → chunk-UF5OENHV.js} +3 -3
  42. package/dist/{chunk-TLS54G6Y.js.map → chunk-UF5OENHV.js.map} +1 -1
  43. package/dist/{chunk-ZQMNGPLE.js → chunk-UJ5KFRDE.js} +18 -6
  44. package/dist/chunk-UJ5KFRDE.js.map +1 -0
  45. package/dist/{chunk-SWC5CNKE.js → chunk-UPVNZPFV.js} +3 -3
  46. package/dist/{chunk-SWC5CNKE.js.map → chunk-UPVNZPFV.js.map} +1 -1
  47. package/dist/{chunk-3F4TXKDY.js → chunk-UUXWRDWW.js} +3 -3
  48. package/dist/chunk-UUXWRDWW.js.map +1 -0
  49. package/dist/{chunk-7GPDNQSX.js → chunk-V2AWSDDZ.js} +5 -5
  50. package/dist/{chunk-7GPDNQSX.js.map → chunk-V2AWSDDZ.js.map} +1 -1
  51. package/dist/{chunk-JQQ3FBN7.js → chunk-VCJF75T2.js} +3 -3
  52. package/dist/{chunk-JQQ3FBN7.js.map → chunk-VCJF75T2.js.map} +1 -1
  53. package/dist/{chunk-ZBW3BA5R.js → chunk-VMAGFYHG.js} +39 -4
  54. package/dist/chunk-VMAGFYHG.js.map +1 -0
  55. package/dist/{chunk-JZ774T7U.js → chunk-W3HMOOON.js} +3 -3
  56. package/dist/{chunk-JZ774T7U.js.map → chunk-W3HMOOON.js.map} +1 -1
  57. package/dist/{chunk-6AD6KCVB.js → chunk-WAKKQROH.js} +3 -3
  58. package/dist/{chunk-6AD6KCVB.js.map → chunk-WAKKQROH.js.map} +1 -1
  59. package/dist/{chunk-LVWNMQGR.js → chunk-WDNDTSNX.js} +5 -5
  60. package/dist/{chunk-LVWNMQGR.js.map → chunk-WDNDTSNX.js.map} +1 -1
  61. package/dist/chunk-WOF67PKT.js +60 -0
  62. package/dist/chunk-WOF67PKT.js.map +1 -0
  63. package/dist/{chunk-QJNV7YQP.js → chunk-WTNDPO2V.js} +39 -4
  64. package/dist/chunk-WTNDPO2V.js.map +1 -0
  65. package/dist/{chunk-FEPTH5RV.js → chunk-XP55RZ3D.js} +3 -3
  66. package/dist/{chunk-FEPTH5RV.js.map → chunk-XP55RZ3D.js.map} +1 -1
  67. package/dist/{chunk-CCUXO2HN.js → chunk-Y4ZRSW35.js} +3 -3
  68. package/dist/{chunk-CCUXO2HN.js.map → chunk-Y4ZRSW35.js.map} +1 -1
  69. package/dist/client.cjs +619 -123
  70. package/dist/client.cjs.map +1 -1
  71. package/dist/client.d.cts +2 -0
  72. package/dist/client.d.ts +2 -0
  73. package/dist/client.js +40 -38
  74. package/dist/client.js.map +1 -1
  75. package/dist/components/Accordion/index.js +2 -2
  76. package/dist/components/Alert/index.js +2 -2
  77. package/dist/components/AlertDialog/index.js +2 -2
  78. package/dist/components/Avatar/index.js +2 -2
  79. package/dist/components/Badge/index.js +2 -2
  80. package/dist/components/Box/index.js +4 -4
  81. package/dist/components/Breadcrumb/index.cjs +6 -3
  82. package/dist/components/Breadcrumb/index.cjs.map +1 -1
  83. package/dist/components/Breadcrumb/index.js +5 -5
  84. package/dist/components/Button/index.js +2 -2
  85. package/dist/components/Calendar/index.cjs +170 -35
  86. package/dist/components/Calendar/index.cjs.map +1 -1
  87. package/dist/components/Calendar/index.js +5 -5
  88. package/dist/components/Card/index.js +2 -2
  89. package/dist/components/Checkbox/index.cjs +36 -1
  90. package/dist/components/Checkbox/index.cjs.map +1 -1
  91. package/dist/components/Checkbox/index.d.cts +17 -1
  92. package/dist/components/Checkbox/index.d.ts +17 -1
  93. package/dist/components/Checkbox/index.js +2 -2
  94. package/dist/components/Dialog/index.js +2 -2
  95. package/dist/components/Field/index.cjs +703 -0
  96. package/dist/components/Field/index.cjs.map +1 -0
  97. package/dist/components/Field/index.d.cts +51 -0
  98. package/dist/components/Field/index.d.ts +51 -0
  99. package/dist/components/Field/index.js +9 -0
  100. package/dist/components/Field/index.js.map +1 -0
  101. package/dist/components/FloatButton/index.cjs +6 -3
  102. package/dist/components/FloatButton/index.cjs.map +1 -1
  103. package/dist/components/FloatButton/index.js +5 -5
  104. package/dist/components/HStack/index.js +4 -4
  105. package/dist/components/InputGroup/index.cjs.map +1 -1
  106. package/dist/components/InputGroup/index.d.cts +8 -1
  107. package/dist/components/InputGroup/index.d.ts +8 -1
  108. package/dist/components/InputGroup/index.js +2 -2
  109. package/dist/components/Label/index.cjs +458 -0
  110. package/dist/components/Label/index.cjs.map +1 -0
  111. package/dist/components/Label/index.d.cts +14 -0
  112. package/dist/components/Label/index.d.ts +14 -0
  113. package/dist/components/Label/index.js +8 -0
  114. package/dist/components/Label/index.js.map +1 -0
  115. package/dist/components/Pagination/index.cjs +21 -6
  116. package/dist/components/Pagination/index.cjs.map +1 -1
  117. package/dist/components/Pagination/index.js +5 -5
  118. package/dist/components/Popover/index.js +2 -2
  119. package/dist/components/Progress/index.js +2 -2
  120. package/dist/components/Radio/index.cjs +18 -2
  121. package/dist/components/Radio/index.cjs.map +1 -1
  122. package/dist/components/Radio/index.d.cts +17 -1
  123. package/dist/components/Radio/index.d.ts +17 -1
  124. package/dist/components/Radio/index.js +2 -2
  125. package/dist/components/SegmentedControl/index.js +2 -2
  126. package/dist/components/Select/index.cjs +15 -3
  127. package/dist/components/Select/index.cjs.map +1 -1
  128. package/dist/components/Select/index.d.cts +6 -0
  129. package/dist/components/Select/index.d.ts +6 -0
  130. package/dist/components/Select/index.js +2 -2
  131. package/dist/components/Switch/index.cjs +36 -1
  132. package/dist/components/Switch/index.cjs.map +1 -1
  133. package/dist/components/Switch/index.d.cts +17 -1
  134. package/dist/components/Switch/index.d.ts +17 -1
  135. package/dist/components/Switch/index.js +2 -2
  136. package/dist/components/Tabs/index.js +2 -2
  137. package/dist/components/Text/index.js +2 -2
  138. package/dist/components/TextArea/index.cjs +35 -84
  139. package/dist/components/TextArea/index.cjs.map +1 -1
  140. package/dist/components/TextArea/index.js +3 -3
  141. package/dist/components/TextInput/index.cjs +35 -84
  142. package/dist/components/TextInput/index.cjs.map +1 -1
  143. package/dist/components/TextInput/index.d.cts +7 -8
  144. package/dist/components/TextInput/index.d.ts +7 -8
  145. package/dist/components/TextInput/index.js +2 -2
  146. package/dist/components/Toggle/index.js +2 -2
  147. package/dist/components/Tooltip/index.js +2 -2
  148. package/dist/components/VStack/index.js +4 -4
  149. package/dist/i18n/index.cjs +6 -3
  150. package/dist/i18n/index.cjs.map +1 -1
  151. package/dist/i18n/index.js +1 -1
  152. package/dist/index.cjs +619 -123
  153. package/dist/index.cjs.map +1 -1
  154. package/dist/index.d.cts +2 -0
  155. package/dist/index.d.ts +2 -0
  156. package/dist/index.js +37 -35
  157. package/package.json +8 -1
  158. package/dist/chunk-3F4TXKDY.js.map +0 -1
  159. package/dist/chunk-FT2XBBQJ.js.map +0 -1
  160. package/dist/chunk-IKLA2CVQ.js.map +0 -1
  161. package/dist/chunk-QJNV7YQP.js.map +0 -1
  162. package/dist/chunk-X7APG7G2.js.map +0 -1
  163. package/dist/chunk-ZBW3BA5R.js.map +0 -1
  164. package/dist/chunk-ZQMNGPLE.js.map +0 -1
  165. package/dist/chunk-ZRD4FQBT.js +0 -153
  166. package/dist/chunk-ZRD4FQBT.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1950,8 +1950,8 @@ var defaultDictionary = {
1950
1950
  // floatButton
1951
1951
  "floatButton.backToTop": "Back to top",
1952
1952
  // calendar
1953
- "calendar.header.previous": "Previous",
1954
- "calendar.header.next": "Next",
1953
+ "calendar.header.previous": "Previous month",
1954
+ "calendar.header.next": "Next month",
1955
1955
  "calendar.header.openMonthView": "Open month picker",
1956
1956
  "calendar.header.openYearView": "Open year picker",
1957
1957
  "calendar.header.openDayView": "Open day picker",
@@ -1967,7 +1967,10 @@ var defaultDictionary = {
1967
1967
  "checkbox.checked": "Checked",
1968
1968
  "checkbox.unchecked": "Unchecked",
1969
1969
  "switch.on": "On",
1970
- "switch.off": "Off"
1970
+ "switch.off": "Off",
1971
+ // field
1972
+ "field.requiredIndicator": "*",
1973
+ "field.requiredLabel": "required"
1971
1974
  };
1972
1975
 
1973
1976
  // src/i18n/resolve.ts
@@ -3667,6 +3670,13 @@ var useLocale = /* @__PURE__ */ __name(() => {
3667
3670
  return ctx ?? detectLocale();
3668
3671
  }, "useLocale");
3669
3672
 
3673
+ // src/components/Calendar/scroll/ScrollBody.tsx
3674
+ var ScrollBody = /* @__PURE__ */ __name((_props) => {
3675
+ throw new Error(
3676
+ "[Calendar] ScrollBody: no platform implementation resolved. Ensure your bundler honors *.web.tsx / *.native.tsx extensions."
3677
+ );
3678
+ }, "ScrollBody");
3679
+
3670
3680
  // src/components/Calendar/state/locale-utils.ts
3671
3681
  var getFirstDayOfWeek = /* @__PURE__ */ __name((locale) => {
3672
3682
  try {
@@ -4028,9 +4038,15 @@ var Select = /* @__PURE__ */ __name((props) => {
4028
4038
  itemHeight = DEFAULT_ITEM_HEIGHT,
4029
4039
  maxMenuHeight = DEFAULT_MAX_MENU,
4030
4040
  className,
4031
- testID
4041
+ testID,
4042
+ id,
4043
+ name
4032
4044
  } = props;
4033
4045
  const ariaLabel = props["aria-label"];
4046
+ const ariaLabelledBy = props["aria-labelledby"];
4047
+ const ariaDescribedBy = props["aria-describedby"];
4048
+ const ariaInvalid = props["aria-invalid"];
4049
+ const ariaRequired = props["aria-required"];
4034
4050
  const multiple = props.multiple === true;
4035
4051
  const maxSelected = multiple ? props.maxSelected : void 0;
4036
4052
  const maxChips = multiple ? props.maxChips ?? 3 : void 0;
@@ -4394,11 +4410,11 @@ var Select = /* @__PURE__ */ __name((props) => {
4394
4410
  if (!open || searchable || reactNative.Platform.OS !== "web") {
4395
4411
  return;
4396
4412
  }
4397
- const id = requestAnimationFrame(() => {
4413
+ const id2 = requestAnimationFrame(() => {
4398
4414
  const node = popupRef.current;
4399
4415
  node?.focus?.();
4400
4416
  });
4401
- return () => cancelAnimationFrame(id);
4417
+ return () => cancelAnimationFrame(id2);
4402
4418
  }, [open, searchable]);
4403
4419
  const onListScroll = React.useCallback(
4404
4420
  (event) => {
@@ -4475,7 +4491,13 @@ var Select = /* @__PURE__ */ __name((props) => {
4475
4491
  "aria-controls": `${baseId}-listbox`,
4476
4492
  "aria-haspopup": "listbox",
4477
4493
  tabIndex: disabled ? -1 : 0,
4494
+ ...id !== void 0 ? { id, nativeID: id } : {},
4495
+ ...name !== void 0 ? { name } : {},
4478
4496
  ...ariaLabel !== void 0 ? { "aria-label": ariaLabel, accessibilityLabel: ariaLabel } : {},
4497
+ ...ariaLabelledBy !== void 0 ? { "aria-labelledby": ariaLabelledBy, accessibilityLabelledBy: ariaLabelledBy } : {},
4498
+ ...ariaDescribedBy !== void 0 ? { "aria-describedby": ariaDescribedBy, accessibilityDescribedBy: ariaDescribedBy } : {},
4499
+ ...ariaInvalid === true ? { "aria-invalid": true } : {},
4500
+ ...ariaRequired === true ? { "aria-required": true } : {},
4479
4501
  ...disabled ? { "aria-disabled": true, disabled: true } : {}
4480
4502
  },
4481
4503
  onPress: () => {
@@ -5149,7 +5171,7 @@ var Caption = /* @__PURE__ */ __name(({
5149
5171
  alignSelf: "center"
5150
5172
  },
5151
5173
  children: [
5152
- /* @__PURE__ */ jsxRuntime.jsx(NavButton, { label: t("calendar.header.previous", { defaultValue: "Previous" }), onPress: onPrev, children: "\u2039" }),
5174
+ /* @__PURE__ */ jsxRuntime.jsx(NavButton, { label: t("calendar.header.previous", { defaultValue: "Previous month" }), onPress: onPrev, children: "\u2039" }),
5153
5175
  /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexDirection: "row", gap: monthGap, width: titleRowWidth }, children: showMultiTitles ? months.map((m, i) => /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { width: gridWidth, alignItems: "center" }, children: caption === "dropdown" && view === "day" ? /* @__PURE__ */ jsxRuntime.jsx(
5154
5176
  DropdownPair,
5155
5177
  {
@@ -5195,7 +5217,7 @@ var Caption = /* @__PURE__ */ __name(({
5195
5217
  drilldown: true
5196
5218
  }
5197
5219
  ) }) }),
5198
- /* @__PURE__ */ jsxRuntime.jsx(NavButton, { label: t("calendar.header.next", { defaultValue: "Next" }), onPress: onNext, children: "\u203A" })
5220
+ /* @__PURE__ */ jsxRuntime.jsx(NavButton, { label: t("calendar.header.next", { defaultValue: "Next month" }), onPress: onNext, children: "\u203A" })
5199
5221
  ]
5200
5222
  }
5201
5223
  );
@@ -5238,8 +5260,53 @@ var DropdownPair = /* @__PURE__ */ __name(({ month, year, monthOptions, yearOpti
5238
5260
  ] });
5239
5261
  }, "DropdownPair");
5240
5262
  var CELL_SIZE = 40;
5241
- var DayCell = /* @__PURE__ */ __name(({ ctx, onPress, onHoverIn, onHoverOut, renderDay }) => {
5263
+ var formatterCache = /* @__PURE__ */ new Map();
5264
+ var RUNTIME_DEFAULT_LOCALE_KEY = "__default__";
5265
+ var getDayFormatter = /* @__PURE__ */ __name((locale) => {
5266
+ const key = locale ?? RUNTIME_DEFAULT_LOCALE_KEY;
5267
+ const cached2 = formatterCache.get(key);
5268
+ if (cached2) {
5269
+ return cached2;
5270
+ }
5271
+ try {
5272
+ const fmt = new Intl.DateTimeFormat(locale, {
5273
+ weekday: "long",
5274
+ month: "long",
5275
+ day: "numeric",
5276
+ year: "numeric",
5277
+ timeZone: "UTC"
5278
+ });
5279
+ formatterCache.set(key, fmt);
5280
+ return fmt;
5281
+ } catch {
5282
+ return null;
5283
+ }
5284
+ }, "getDayFormatter");
5285
+ var formatDayLabel = /* @__PURE__ */ __name((ctx, locale) => {
5286
+ const jsDate = new Date(Date.UTC(ctx.date.year, ctx.date.month - 1, ctx.date.day));
5287
+ const fmt = getDayFormatter(locale);
5288
+ const base = fmt ? fmt.format(jsDate) : (
5289
+ // Fallback if the runtime rejects the locale tag.
5290
+ `${ctx.date.month}/${ctx.date.day}/${ctx.date.year}`
5291
+ );
5292
+ const suffixes = [];
5293
+ if (ctx.isToday) {
5294
+ suffixes.push("today");
5295
+ }
5296
+ if (ctx.isSelected || ctx.isRangeStart || ctx.isRangeEnd) {
5297
+ suffixes.push("selected");
5298
+ }
5299
+ if (ctx.isInRange && !ctx.isRangeStart && !ctx.isRangeEnd) {
5300
+ suffixes.push("in range");
5301
+ }
5302
+ if (ctx.isUnavailable) {
5303
+ suffixes.push("unavailable");
5304
+ }
5305
+ return suffixes.length > 0 ? `${base}, ${suffixes.join(", ")}` : base;
5306
+ }, "formatDayLabel");
5307
+ var DayCell = /* @__PURE__ */ __name(({ ctx, onPress, onHoverIn, onHoverOut, renderDay, locale }) => {
5242
5308
  const colors = useThemeColors();
5309
+ const accessibilityLabel = formatDayLabel(ctx, locale);
5243
5310
  const isSelectedLike = ctx.isSelected || ctx.isRangeStart || ctx.isRangeEnd;
5244
5311
  const isInsideRange = ctx.isInRange || ctx.isInPreviewRange;
5245
5312
  const isRangeMiddle = isInsideRange && !isSelectedLike;
@@ -5248,7 +5315,8 @@ var DayCell = /* @__PURE__ */ __name(({ ctx, onPress, onHoverIn, onHoverOut, ren
5248
5315
  reactNative.Pressable,
5249
5316
  {
5250
5317
  accessibilityRole: "button",
5251
- accessibilityState: { disabled: ctx.isUnavailable },
5318
+ accessibilityLabel,
5319
+ accessibilityState: { disabled: ctx.isUnavailable, selected: isSelectedLike },
5252
5320
  disabled: ctx.isUnavailable,
5253
5321
  onPress,
5254
5322
  ...onHoverIn ? { onHoverIn } : {},
@@ -5506,6 +5574,7 @@ var DayGrid = /* @__PURE__ */ __name((props) => {
5506
5574
  DayCell,
5507
5575
  {
5508
5576
  ctx,
5577
+ locale,
5509
5578
  onPress: () => onDayPress(date),
5510
5579
  ...onDayHover ? {
5511
5580
  onHoverIn: /* @__PURE__ */ __name(() => onDayHover(date), "onHoverIn"),
@@ -5668,6 +5737,9 @@ var focusDayCell = /* @__PURE__ */ __name((root, date, force) => {
5668
5737
  if (!root) {
5669
5738
  return;
5670
5739
  }
5740
+ if (typeof document === "undefined" || typeof root.contains !== "function") {
5741
+ return;
5742
+ }
5671
5743
  if (!force && !root.contains(document.activeElement)) {
5672
5744
  return;
5673
5745
  }
@@ -5772,8 +5844,13 @@ var SingleOrMultiCalendar = /* @__PURE__ */ __name((props) => {
5772
5844
  const colors = useThemeColors();
5773
5845
  const firstDayOfWeek = props.firstDayOfWeek ?? getFirstDayOfWeek(locale);
5774
5846
  const weekendDays = props.weekendDays ?? getWeekendDays(locale);
5775
- const visibleMonths = pickVisibleMonths(props.visibleMonths, containerWidth);
5847
+ const visibleMonths = props.behavior === "scroll" ? 1 : pickVisibleMonths(props.visibleMonths, containerWidth);
5776
5848
  const { innerWidth, gridsRowWidth } = surfaceMetrics(visibleMonths);
5849
+ React.useEffect(() => {
5850
+ if (process.env.NODE_ENV !== "production" && props.behavior === "scroll" && typeof props.visibleMonths === "number" && props.visibleMonths > 1) {
5851
+ console.warn('[Calendar] visibleMonths is ignored when behavior="scroll"; falling back to single column.');
5852
+ }
5853
+ }, [props.behavior, props.visibleMonths]);
5777
5854
  const containerRef = React.useRef(null);
5778
5855
  const state = useCalendarState({
5779
5856
  ...props.mode !== void 0 ? { mode: props.mode } : {},
@@ -5836,6 +5913,8 @@ var SingleOrMultiCalendar = /* @__PURE__ */ __name((props) => {
5836
5913
  setAnchor((a) => a.add({ years: -10 }));
5837
5914
  } else if (state.view === "month") {
5838
5915
  setAnchor((a) => a.add({ years: -1 }));
5916
+ } else if (props.behavior === "scroll") {
5917
+ state.moveFocus({ months: -1 });
5839
5918
  } else {
5840
5919
  setAnchor((a) => a.add({ months: -1 }));
5841
5920
  }
@@ -5845,6 +5924,8 @@ var SingleOrMultiCalendar = /* @__PURE__ */ __name((props) => {
5845
5924
  setAnchor((a) => a.add({ years: 10 }));
5846
5925
  } else if (state.view === "month") {
5847
5926
  setAnchor((a) => a.add({ years: 1 }));
5927
+ } else if (props.behavior === "scroll") {
5928
+ state.moveFocus({ months: 1 });
5848
5929
  } else {
5849
5930
  setAnchor((a) => a.add({ months: 1 }));
5850
5931
  }
@@ -5907,22 +5988,44 @@ var SingleOrMultiCalendar = /* @__PURE__ */ __name((props) => {
5907
5988
  }
5908
5989
  ),
5909
5990
  /* @__PURE__ */ jsxRuntime.jsxs(FadeIn, { children: [
5910
- state.view === "day" && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexDirection: "row", gap: MONTH_GAP, alignSelf: "center", width: gridsRowWidth }, children: months.map((m) => /* @__PURE__ */ jsxRuntime.jsx(
5911
- DayGrid,
5991
+ state.view === "day" && (props.behavior === "scroll" ? /* @__PURE__ */ jsxRuntime.jsx(
5992
+ ScrollBody,
5912
5993
  {
5913
- visibleMonth: m,
5914
- locale,
5915
5994
  mode: props.mode ?? "single",
5916
- value: state.value,
5995
+ locale,
5917
5996
  focusedDate: state.focusedDate,
5918
- isUnavailable: state.isUnavailable,
5919
- weekendDays,
5997
+ onFocusedMonthChange: (next) => setAnchor(next),
5998
+ value: state.value,
5999
+ onSelectDate: (date) => state.selectDate(date, "click"),
5920
6000
  firstDayOfWeek,
5921
- onDayPress: (date) => state.selectDate(date, "click"),
6001
+ weekendDays,
6002
+ ...props.minValue !== void 0 ? { minValue: props.minValue } : {},
6003
+ ...props.maxValue !== void 0 ? { maxValue: props.maxValue } : {},
6004
+ ...props.isDateUnavailable !== void 0 ? { isDateUnavailable: props.isDateUnavailable } : {},
5922
6005
  ...renderDay ? { renderDay } : {}
5923
- },
5924
- `${m.year}-${m.month}`
5925
- )) }),
6006
+ }
6007
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
6008
+ reactNative.View,
6009
+ {
6010
+ style: { flexDirection: "row", gap: MONTH_GAP, alignSelf: "center", width: gridsRowWidth },
6011
+ children: months.map((m) => /* @__PURE__ */ jsxRuntime.jsx(
6012
+ DayGrid,
6013
+ {
6014
+ visibleMonth: m,
6015
+ locale,
6016
+ mode: props.mode ?? "single",
6017
+ value: state.value,
6018
+ focusedDate: state.focusedDate,
6019
+ isUnavailable: state.isUnavailable,
6020
+ weekendDays,
6021
+ firstDayOfWeek,
6022
+ onDayPress: (date) => state.selectDate(date, "click"),
6023
+ ...renderDay ? { renderDay } : {}
6024
+ },
6025
+ `${m.year}-${m.month}`
6026
+ ))
6027
+ }
6028
+ )),
5926
6029
  state.view === "month" && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { alignItems: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
5927
6030
  MonthGrid,
5928
6031
  {
@@ -5957,8 +6060,13 @@ var RangeCalendar = /* @__PURE__ */ __name((props) => {
5957
6060
  const colors = useThemeColors();
5958
6061
  const firstDayOfWeek = props.firstDayOfWeek ?? getFirstDayOfWeek(locale);
5959
6062
  const weekendDays = props.weekendDays ?? getWeekendDays(locale);
5960
- const visibleMonths = pickVisibleMonths(props.visibleMonths, containerWidth);
6063
+ const visibleMonths = props.behavior === "scroll" ? 1 : pickVisibleMonths(props.visibleMonths, containerWidth);
5961
6064
  const { innerWidth, gridsRowWidth } = surfaceMetrics(visibleMonths);
6065
+ React.useEffect(() => {
6066
+ if (process.env.NODE_ENV !== "production" && props.behavior === "scroll" && typeof props.visibleMonths === "number" && props.visibleMonths > 1) {
6067
+ console.warn('[Calendar] visibleMonths is ignored when behavior="scroll"; falling back to single column.');
6068
+ }
6069
+ }, [props.behavior, props.visibleMonths]);
5962
6070
  const containerRef = React.useRef(null);
5963
6071
  const range2 = useRangeState({
5964
6072
  ...props.value !== void 0 ? { value: props.value } : {},
@@ -6036,6 +6144,8 @@ var RangeCalendar = /* @__PURE__ */ __name((props) => {
6036
6144
  setAnchor((a) => a.add({ years: -10 }));
6037
6145
  } else if (view === "month") {
6038
6146
  setAnchor((a) => a.add({ years: -1 }));
6147
+ } else if (props.behavior === "scroll") {
6148
+ setFocusedDate((f) => f.add({ months: -1 }));
6039
6149
  } else {
6040
6150
  setAnchor((a) => a.add({ months: -1 }));
6041
6151
  }
@@ -6045,6 +6155,8 @@ var RangeCalendar = /* @__PURE__ */ __name((props) => {
6045
6155
  setAnchor((a) => a.add({ years: 10 }));
6046
6156
  } else if (view === "month") {
6047
6157
  setAnchor((a) => a.add({ years: 1 }));
6158
+ } else if (props.behavior === "scroll") {
6159
+ setFocusedDate((f) => f.add({ months: 1 }));
6048
6160
  } else {
6049
6161
  setAnchor((a) => a.add({ months: 1 }));
6050
6162
  }
@@ -6115,24 +6227,47 @@ var RangeCalendar = /* @__PURE__ */ __name((props) => {
6115
6227
  }
6116
6228
  ),
6117
6229
  /* @__PURE__ */ jsxRuntime.jsxs(FadeIn, { children: [
6118
- view === "day" && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexDirection: "row", gap: MONTH_GAP, alignSelf: "center", width: gridsRowWidth }, children: months.map((m) => /* @__PURE__ */ jsxRuntime.jsx(
6119
- DayGrid,
6230
+ view === "day" && (props.behavior === "scroll" ? /* @__PURE__ */ jsxRuntime.jsx(
6231
+ ScrollBody,
6120
6232
  {
6121
- visibleMonth: m,
6122
- locale,
6123
6233
  mode: "range",
6234
+ locale,
6235
+ focusedDate,
6236
+ onFocusedMonthChange: (next) => setAnchor(next),
6124
6237
  value: range2.value,
6125
6238
  previewRange: range2.previewRange,
6126
- focusedDate,
6127
- isUnavailable: range2.isUnavailable,
6128
- weekendDays,
6239
+ onSelectDate: (date) => range2.selectDate(date),
6129
6240
  firstDayOfWeek,
6130
- onDayPress: (date) => range2.selectDate(date),
6131
- onDayHover: (date) => range2.setHoveredDate(date),
6241
+ weekendDays,
6242
+ ...props.minValue !== void 0 ? { minValue: props.minValue } : {},
6243
+ ...props.maxValue !== void 0 ? { maxValue: props.maxValue } : {},
6244
+ ...props.isDateUnavailable !== void 0 ? { isDateUnavailable: props.isDateUnavailable } : {},
6132
6245
  ...renderDay ? { renderDay } : {}
6133
- },
6134
- `${m.year}-${m.month}`
6135
- )) }),
6246
+ }
6247
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
6248
+ reactNative.View,
6249
+ {
6250
+ style: { flexDirection: "row", gap: MONTH_GAP, alignSelf: "center", width: gridsRowWidth },
6251
+ children: months.map((m) => /* @__PURE__ */ jsxRuntime.jsx(
6252
+ DayGrid,
6253
+ {
6254
+ visibleMonth: m,
6255
+ locale,
6256
+ mode: "range",
6257
+ value: range2.value,
6258
+ previewRange: range2.previewRange,
6259
+ focusedDate,
6260
+ isUnavailable: range2.isUnavailable,
6261
+ weekendDays,
6262
+ firstDayOfWeek,
6263
+ onDayPress: (date) => range2.selectDate(date),
6264
+ onDayHover: (date) => range2.setHoveredDate(date),
6265
+ ...renderDay ? { renderDay } : {}
6266
+ },
6267
+ `${m.year}-${m.month}`
6268
+ ))
6269
+ }
6270
+ )),
6136
6271
  view === "month" && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { alignItems: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
6137
6272
  MonthGrid,
6138
6273
  {
@@ -6329,7 +6464,15 @@ var Checkbox = /* @__PURE__ */ __name(({
6329
6464
  className,
6330
6465
  testID,
6331
6466
  asChild,
6332
- children
6467
+ children,
6468
+ id,
6469
+ name,
6470
+ "aria-labelledby": ariaLabelledBy,
6471
+ accessibilityLabelledBy,
6472
+ "aria-describedby": ariaDescribedBy,
6473
+ accessibilityDescribedBy,
6474
+ "aria-invalid": ariaInvalid,
6475
+ "aria-required": ariaRequired
6333
6476
  }) => {
6334
6477
  const colors = useThemeColors();
6335
6478
  const [inner, setInner] = React.useState(defaultChecked);
@@ -6357,6 +6500,13 @@ var Checkbox = /* @__PURE__ */ __name(({
6357
6500
  accessibilityState: { checked: value, disabled: Boolean(disabled) },
6358
6501
  testID
6359
6502
  };
6503
+ if (id !== void 0) {
6504
+ commonProps.id = id;
6505
+ commonProps.nativeID = id;
6506
+ }
6507
+ if (name !== void 0) {
6508
+ commonProps.name = name;
6509
+ }
6360
6510
  if (disabled) {
6361
6511
  commonProps["aria-disabled"] = true;
6362
6512
  }
@@ -6364,6 +6514,26 @@ var Checkbox = /* @__PURE__ */ __name(({
6364
6514
  commonProps["aria-label"] = label;
6365
6515
  commonProps.accessibilityLabel = label;
6366
6516
  }
6517
+ if (ariaLabelledBy !== void 0) {
6518
+ commonProps["aria-labelledby"] = ariaLabelledBy;
6519
+ commonProps.accessibilityLabelledBy = ariaLabelledBy;
6520
+ }
6521
+ if (accessibilityLabelledBy !== void 0) {
6522
+ commonProps.accessibilityLabelledBy = accessibilityLabelledBy;
6523
+ }
6524
+ if (ariaDescribedBy !== void 0) {
6525
+ commonProps["aria-describedby"] = ariaDescribedBy;
6526
+ commonProps.accessibilityDescribedBy = ariaDescribedBy;
6527
+ }
6528
+ if (accessibilityDescribedBy !== void 0) {
6529
+ commonProps.accessibilityDescribedBy = accessibilityDescribedBy;
6530
+ }
6531
+ if (ariaInvalid) {
6532
+ commonProps["aria-invalid"] = true;
6533
+ }
6534
+ if (ariaRequired) {
6535
+ commonProps["aria-required"] = true;
6536
+ }
6367
6537
  if (asChild) {
6368
6538
  const slotProps = {
6369
6539
  role: "checkbox",
@@ -6832,6 +7002,279 @@ var Dialog = Object.assign(DialogRoot, {
6832
7002
  Footer: DialogFooter,
6833
7003
  Close: DialogClose
6834
7004
  });
7005
+ var FieldContext = React.createContext(null);
7006
+ var useFieldContextStrict = /* @__PURE__ */ __name((caller) => {
7007
+ const ctx = React.useContext(FieldContext);
7008
+ if (!ctx) {
7009
+ throw new Error(`[Field] ${caller} must be used inside <Field> or <Field.Group>.`);
7010
+ }
7011
+ return ctx;
7012
+ }, "useFieldContextStrict");
7013
+ var childHasDisplayName = /* @__PURE__ */ __name((child, name) => {
7014
+ if (!React.isValidElement(child)) {
7015
+ return false;
7016
+ }
7017
+ const t = child.type;
7018
+ return typeof t !== "string" && t?.displayName === name;
7019
+ }, "childHasDisplayName");
7020
+ var COMPOUND_DISPLAY_NAMES = ["Field.Label", "Field.Description", "Field.Error", "Field.Control"];
7021
+ var isCompoundChild = /* @__PURE__ */ __name((child) => COMPOUND_DISPLAY_NAMES.some((name) => childHasDisplayName(child, name)), "isCompoundChild");
7022
+ var FieldRoot = /* @__PURE__ */ __name(({
7023
+ name,
7024
+ required = false,
7025
+ disabled = false,
7026
+ error = null,
7027
+ label,
7028
+ description,
7029
+ validating = false,
7030
+ orientation = "vertical",
7031
+ id,
7032
+ children,
7033
+ className,
7034
+ testID,
7035
+ isGroup = false
7036
+ }) => {
7037
+ const colors = useThemeColors();
7038
+ const reactId = React.useId();
7039
+ const fieldId = id ?? `nori-ui-field-${reactId}`;
7040
+ const labelId = `${fieldId}-label`;
7041
+ const descriptionId = `${fieldId}-desc`;
7042
+ const errorId = `${fieldId}-error`;
7043
+ const isCompoundMode = React.useMemo(() => {
7044
+ let found = false;
7045
+ React.Children.forEach(children, (child) => {
7046
+ if (isCompoundChild(child)) {
7047
+ found = true;
7048
+ }
7049
+ });
7050
+ return found;
7051
+ }, [children]);
7052
+ const hasDescription = React.useMemo(() => {
7053
+ if (!isCompoundMode) {
7054
+ return description !== void 0 && description !== null && description !== false && description !== "";
7055
+ }
7056
+ let found = false;
7057
+ React.Children.forEach(children, (child) => {
7058
+ if (childHasDisplayName(child, "Field.Description")) {
7059
+ found = true;
7060
+ }
7061
+ });
7062
+ return found;
7063
+ }, [isCompoundMode, description, children]);
7064
+ const hasError = React.useMemo(() => {
7065
+ if (!isCompoundMode) {
7066
+ return Boolean(error);
7067
+ }
7068
+ let found = false;
7069
+ React.Children.forEach(children, (child) => {
7070
+ if (childHasDisplayName(child, "Field.Error") && React.isValidElement(child)) {
7071
+ const el = child;
7072
+ if (el.props.children !== void 0 && el.props.children !== null && el.props.children !== false && el.props.children !== "") {
7073
+ found = true;
7074
+ }
7075
+ }
7076
+ });
7077
+ if (!found && error !== null && error !== void 0 && error !== false && error !== "") {
7078
+ found = true;
7079
+ }
7080
+ return found;
7081
+ }, [isCompoundMode, error, children]);
7082
+ const describedBy = React.useMemo(() => {
7083
+ const ids = [];
7084
+ if (hasDescription) {
7085
+ ids.push(descriptionId);
7086
+ }
7087
+ if (hasError) {
7088
+ ids.push(errorId);
7089
+ }
7090
+ return ids.length === 0 ? void 0 : ids.join(" ");
7091
+ }, [hasDescription, hasError, descriptionId, errorId]);
7092
+ const value = {
7093
+ fieldId,
7094
+ labelId,
7095
+ descriptionId,
7096
+ errorId,
7097
+ hasError,
7098
+ hasDescription,
7099
+ describedBy,
7100
+ disabled,
7101
+ required,
7102
+ validating,
7103
+ ...name !== void 0 ? { name } : {},
7104
+ // In compound mode pass `error` (string) so Field.Error can fall back to it.
7105
+ // In shorthand mode the error prop may be ReactNode; only pass when it is a string/null.
7106
+ ...error !== null && error !== void 0 && typeof error === "string" ? { error } : {},
7107
+ isGroup
7108
+ };
7109
+ const warnedRef = React.useRef(false);
7110
+ React.useEffect(() => {
7111
+ if (process.env.NODE_ENV === "production" || warnedRef.current) {
7112
+ return;
7113
+ }
7114
+ const hasShorthand = label !== void 0 || description !== void 0 || error !== void 0;
7115
+ if (hasShorthand && isCompoundMode) {
7116
+ warnedRef.current = true;
7117
+ console.warn(
7118
+ "[Field] Mixing shorthand props (label/description/error) with compound children (Field.Label/Field.Description/Field.Error) is not supported. The compound children will win. To suppress this warning, use only one mode."
7119
+ );
7120
+ }
7121
+ }, [label, description, error, isCompoundMode]);
7122
+ const containerStyle = orientation === "horizontal" ? {
7123
+ flexDirection: "row",
7124
+ alignItems: "flex-start",
7125
+ gap: px(colors.spacing["3"])
7126
+ } : { flexDirection: "column", gap: px(colors.spacing["1"]) };
7127
+ const containerExtra = {};
7128
+ if (testID !== void 0) {
7129
+ containerExtra.testID = testID;
7130
+ }
7131
+ containerExtra["data-orientation"] = orientation;
7132
+ if (isGroup) {
7133
+ containerExtra.role = "group";
7134
+ containerExtra["aria-labelledby"] = labelId;
7135
+ containerExtra.accessibilityRole = "none";
7136
+ }
7137
+ if (validating) {
7138
+ containerExtra["data-validating"] = "";
7139
+ containerExtra["aria-busy"] = true;
7140
+ }
7141
+ const renderShorthand = /* @__PURE__ */ __name(() => {
7142
+ const childArray = React.Children.toArray(children);
7143
+ const controlChild = childArray.length === 1 && React.isValidElement(childArray[0]) ? childArray[0] : null;
7144
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7145
+ label !== void 0 && label !== null && label !== false ? /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { children: label }) : null,
7146
+ description !== void 0 && description !== null && description !== false && description !== "" ? /* @__PURE__ */ jsxRuntime.jsx(FieldDescription, { children: description }) : null,
7147
+ controlChild !== null ? /* @__PURE__ */ jsxRuntime.jsx(FieldControl, { children: controlChild }) : children,
7148
+ error !== void 0 && error !== null && error !== false && error !== "" ? /* @__PURE__ */ jsxRuntime.jsx(FieldError, { children: error }) : null
7149
+ ] });
7150
+ }, "renderShorthand");
7151
+ return /* @__PURE__ */ jsxRuntime.jsx(FieldContext.Provider, { value, children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: containerStyle, ...className !== void 0 ? { className } : {}, ...containerExtra, children: [
7152
+ isCompoundMode ? children : renderShorthand(),
7153
+ validating ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "sm" }) : null
7154
+ ] }) });
7155
+ }, "FieldRoot");
7156
+ var FieldLabel = /* @__PURE__ */ __name(({ children }) => {
7157
+ const ctx = useFieldContextStrict("Field.Label");
7158
+ const colors = useThemeColors();
7159
+ const { t } = useTranslation();
7160
+ const requiredIndicator = t("field.requiredIndicator");
7161
+ const requiredLabel = t("field.requiredLabel");
7162
+ const focusInput = /* @__PURE__ */ __name(() => {
7163
+ if (typeof document !== "undefined") {
7164
+ const el = document.getElementById(ctx.fieldId);
7165
+ if (el && typeof el.focus === "function") {
7166
+ el.focus();
7167
+ }
7168
+ }
7169
+ }, "focusInput");
7170
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: focusInput, accessibilityRole: "none", disabled: ctx.disabled, children: /* @__PURE__ */ jsxRuntime.jsxs(
7171
+ reactNative.Text,
7172
+ {
7173
+ nativeID: ctx.labelId,
7174
+ ...{ id: ctx.labelId },
7175
+ accessibilityRole: "text",
7176
+ style: {
7177
+ fontFamily: colors.fontFamily.body,
7178
+ fontSize: px(colors.fontSize.sm),
7179
+ fontWeight: colors.fontWeight.medium,
7180
+ color: ctx.disabled ? colors.semantic.text.muted : colors.semantic.text.default
7181
+ },
7182
+ children: [
7183
+ children,
7184
+ ctx.required ? /* @__PURE__ */ jsxRuntime.jsx(
7185
+ reactNative.Text,
7186
+ {
7187
+ accessibilityLabel: requiredLabel,
7188
+ ...{ "aria-label": requiredLabel },
7189
+ style: { color: colors.color.danger },
7190
+ children: ` ${requiredIndicator}`
7191
+ }
7192
+ ) : null
7193
+ ]
7194
+ }
7195
+ ) });
7196
+ }, "FieldLabel");
7197
+ FieldLabel.displayName = "Field.Label";
7198
+ var FieldControl = /* @__PURE__ */ __name(({ children }) => {
7199
+ const ctx = useFieldContextStrict("Field.Control");
7200
+ if (React.Children.count(children) !== 1 || !React.isValidElement(children)) {
7201
+ throw new Error("[Field.Control] expects exactly one child element.");
7202
+ }
7203
+ const child = children;
7204
+ const merged = {
7205
+ id: child.props.id ?? ctx.fieldId,
7206
+ accessibilityLabelledBy: ctx.labelId,
7207
+ "aria-labelledby": ctx.labelId
7208
+ };
7209
+ if (ctx.name !== void 0 && child.props.name === void 0) {
7210
+ merged.name = ctx.name;
7211
+ }
7212
+ if (ctx.describedBy !== void 0) {
7213
+ merged["aria-describedby"] = ctx.describedBy;
7214
+ merged.accessibilityDescribedBy = ctx.describedBy;
7215
+ }
7216
+ if (ctx.hasError) {
7217
+ merged["aria-invalid"] = true;
7218
+ }
7219
+ if (ctx.required) {
7220
+ merged["aria-required"] = true;
7221
+ }
7222
+ if (ctx.disabled || child.props.disabled) {
7223
+ merged.disabled = true;
7224
+ }
7225
+ return React.cloneElement(child, merged);
7226
+ }, "FieldControl");
7227
+ FieldControl.displayName = "Field.Control";
7228
+ var FieldDescription = /* @__PURE__ */ __name(({ children }) => {
7229
+ const ctx = useFieldContextStrict("Field.Description");
7230
+ const colors = useThemeColors();
7231
+ return /* @__PURE__ */ jsxRuntime.jsx(
7232
+ reactNative.Text,
7233
+ {
7234
+ nativeID: ctx.descriptionId,
7235
+ ...{ id: ctx.descriptionId },
7236
+ style: {
7237
+ fontFamily: colors.fontFamily.body,
7238
+ fontSize: px(colors.fontSize.sm),
7239
+ color: colors.semantic.text.muted
7240
+ },
7241
+ children
7242
+ }
7243
+ );
7244
+ }, "FieldDescription");
7245
+ FieldDescription.displayName = "Field.Description";
7246
+ var FieldError = /* @__PURE__ */ __name(({ children }) => {
7247
+ const ctx = useFieldContextStrict("Field.Error");
7248
+ const colors = useThemeColors();
7249
+ const content = children ?? ctx.error;
7250
+ if (content === null || content === void 0 || content === "" || content === false) {
7251
+ return null;
7252
+ }
7253
+ return /* @__PURE__ */ jsxRuntime.jsx(
7254
+ reactNative.Text,
7255
+ {
7256
+ nativeID: ctx.errorId,
7257
+ ...{ id: ctx.errorId, role: "alert" },
7258
+ accessibilityRole: "text",
7259
+ style: {
7260
+ fontFamily: colors.fontFamily.body,
7261
+ fontSize: px(colors.fontSize.sm),
7262
+ color: colors.color.danger
7263
+ },
7264
+ children: content
7265
+ }
7266
+ );
7267
+ }, "FieldError");
7268
+ FieldError.displayName = "Field.Error";
7269
+ var FieldGroup = /* @__PURE__ */ __name((props) => /* @__PURE__ */ jsxRuntime.jsx(FieldRoot, { ...props, isGroup: true }), "FieldGroup");
7270
+ FieldGroup.displayName = "Field.Group";
7271
+ var Field = Object.assign(FieldRoot, {
7272
+ Label: FieldLabel,
7273
+ Description: FieldDescription,
7274
+ Control: FieldControl,
7275
+ Error: FieldError,
7276
+ Group: FieldGroup
7277
+ });
6835
7278
  var isDev = process.env.NODE_ENV !== "production";
6836
7279
  var SafeAreaInsetsContext = /* @__PURE__ */ React__namespace.createContext(null);
6837
7280
  if (isDev) {
@@ -7842,6 +8285,55 @@ var InputGroup = Object.assign(InputGroupRoot, {
7842
8285
  Addon: InputGroupAddon,
7843
8286
  Input: InputGroupInput
7844
8287
  });
8288
+ var Label = /* @__PURE__ */ __name(({ htmlFor, required = false, disabled = false, children, className, testID }) => {
8289
+ const colors = useThemeColors();
8290
+ const { t } = useTranslation();
8291
+ const requiredIndicator = t("field.requiredIndicator");
8292
+ const requiredLabel = t("field.requiredLabel");
8293
+ const focusTarget = /* @__PURE__ */ __name(() => {
8294
+ if (typeof document !== "undefined") {
8295
+ const el = document.getElementById(htmlFor);
8296
+ if (el && typeof el.focus === "function") {
8297
+ el.focus();
8298
+ }
8299
+ }
8300
+ }, "focusTarget");
8301
+ return /* @__PURE__ */ jsxRuntime.jsx(
8302
+ reactNative.Pressable,
8303
+ {
8304
+ onPress: focusTarget,
8305
+ accessibilityRole: "none",
8306
+ disabled,
8307
+ ...testID !== void 0 ? { testID } : {},
8308
+ ...className !== void 0 ? { className } : {},
8309
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
8310
+ reactNative.Text,
8311
+ {
8312
+ ...{ htmlFor },
8313
+ accessibilityRole: "text",
8314
+ style: {
8315
+ fontFamily: colors.fontFamily.body,
8316
+ fontSize: px(colors.fontSize.sm),
8317
+ fontWeight: colors.fontWeight.medium,
8318
+ color: disabled ? colors.semantic.text.muted : colors.semantic.text.default
8319
+ },
8320
+ children: [
8321
+ children,
8322
+ required ? /* @__PURE__ */ jsxRuntime.jsx(
8323
+ reactNative.Text,
8324
+ {
8325
+ accessibilityLabel: requiredLabel,
8326
+ ...{ "aria-label": requiredLabel },
8327
+ style: { color: colors.color.danger },
8328
+ children: ` ${requiredIndicator}`
8329
+ }
8330
+ ) : null
8331
+ ]
8332
+ }
8333
+ )
8334
+ }
8335
+ );
8336
+ }, "Label");
7845
8337
  var range = /* @__PURE__ */ __name((from, to) => {
7846
8338
  if (to < from) {
7847
8339
  return [];
@@ -8988,7 +9480,15 @@ var RadioGroup = /* @__PURE__ */ __name(({
8988
9480
  name,
8989
9481
  children,
8990
9482
  className,
8991
- testID
9483
+ testID,
9484
+ id,
9485
+ nativeID,
9486
+ "aria-labelledby": ariaLabelledBy,
9487
+ accessibilityLabelledBy,
9488
+ "aria-describedby": ariaDescribedBy,
9489
+ accessibilityDescribedBy,
9490
+ "aria-invalid": ariaInvalid,
9491
+ "aria-required": ariaRequired
8992
9492
  }) => {
8993
9493
  const [inner, setInner] = React.useState(defaultValue2);
8994
9494
  const isControlled = value !== void 0;
@@ -9090,7 +9590,15 @@ var RadioGroup = /* @__PURE__ */ __name(({
9090
9590
  "aria-orientation": orientation,
9091
9591
  "aria-disabled": disabled || void 0,
9092
9592
  onKeyDown: handleKeyDown,
9093
- ...testID !== void 0 ? { testID } : {}
9593
+ ...testID !== void 0 ? { testID } : {},
9594
+ ...id !== void 0 ? { id } : {},
9595
+ ...nativeID !== void 0 ? { nativeID } : {},
9596
+ ...ariaLabelledBy !== void 0 ? { "aria-labelledby": ariaLabelledBy } : {},
9597
+ ...accessibilityLabelledBy !== void 0 ? { accessibilityLabelledBy } : {},
9598
+ ...ariaDescribedBy !== void 0 ? { "aria-describedby": ariaDescribedBy } : {},
9599
+ ...accessibilityDescribedBy !== void 0 ? { accessibilityDescribedBy } : {},
9600
+ ...ariaInvalid ? { "aria-invalid": true } : {},
9601
+ ...ariaRequired ? { "aria-required": true } : {}
9094
9602
  };
9095
9603
  return /* @__PURE__ */ jsxRuntime.jsx(RadioGroupContext.Provider, { value: ctxValue, children: /* @__PURE__ */ jsxRuntime.jsx(
9096
9604
  RadioGroupViewport,
@@ -10036,7 +10544,15 @@ var Switch = /* @__PURE__ */ __name(({
10036
10544
  className,
10037
10545
  testID,
10038
10546
  asChild,
10039
- children
10547
+ children,
10548
+ id,
10549
+ name,
10550
+ "aria-labelledby": ariaLabelledBy,
10551
+ accessibilityLabelledBy,
10552
+ "aria-describedby": ariaDescribedBy,
10553
+ accessibilityDescribedBy,
10554
+ "aria-invalid": ariaInvalid,
10555
+ "aria-required": ariaRequired
10040
10556
  }) => {
10041
10557
  const colors = useThemeColors();
10042
10558
  const [inner, setInner] = React.useState(defaultChecked);
@@ -10061,6 +10577,13 @@ var Switch = /* @__PURE__ */ __name(({
10061
10577
  accessibilityState: { checked: value, disabled: Boolean(disabled) },
10062
10578
  testID
10063
10579
  };
10580
+ if (id !== void 0) {
10581
+ commonProps.id = id;
10582
+ commonProps.nativeID = id;
10583
+ }
10584
+ if (name !== void 0) {
10585
+ commonProps.name = name;
10586
+ }
10064
10587
  if (disabled) {
10065
10588
  commonProps["aria-disabled"] = true;
10066
10589
  }
@@ -10068,6 +10591,26 @@ var Switch = /* @__PURE__ */ __name(({
10068
10591
  commonProps["aria-label"] = label;
10069
10592
  commonProps.accessibilityLabel = label;
10070
10593
  }
10594
+ if (ariaLabelledBy !== void 0) {
10595
+ commonProps["aria-labelledby"] = ariaLabelledBy;
10596
+ commonProps.accessibilityLabelledBy = ariaLabelledBy;
10597
+ }
10598
+ if (accessibilityLabelledBy !== void 0) {
10599
+ commonProps.accessibilityLabelledBy = accessibilityLabelledBy;
10600
+ }
10601
+ if (ariaDescribedBy !== void 0) {
10602
+ commonProps["aria-describedby"] = ariaDescribedBy;
10603
+ commonProps.accessibilityDescribedBy = ariaDescribedBy;
10604
+ }
10605
+ if (accessibilityDescribedBy !== void 0) {
10606
+ commonProps.accessibilityDescribedBy = accessibilityDescribedBy;
10607
+ }
10608
+ if (ariaInvalid) {
10609
+ commonProps["aria-invalid"] = true;
10610
+ }
10611
+ if (ariaRequired) {
10612
+ commonProps["aria-required"] = true;
10613
+ }
10071
10614
  if (asChild) {
10072
10615
  const slotProps = {
10073
10616
  role: "switch",
@@ -10434,7 +10977,6 @@ var Tabs = Object.assign(TabsRoot, {
10434
10977
  Trigger: TabsTrigger,
10435
10978
  Content: TabsContent
10436
10979
  });
10437
- var CONTAINER_LAYOUT_BASE4 = { flexDirection: "column" };
10438
10980
  var FIELD_LAYOUT_BASE2 = {
10439
10981
  flexDirection: "row",
10440
10982
  alignItems: "center",
@@ -10445,42 +10987,33 @@ var FIELD_LAYOUT_BASE2 = {
10445
10987
  overflow: "hidden"
10446
10988
  };
10447
10989
  var TextInput = /* @__PURE__ */ __name(({
10448
- label,
10449
- helperText,
10450
- error,
10451
10990
  disabled,
10452
10991
  leading,
10453
10992
  trailing,
10454
10993
  containerClassName,
10455
10994
  className,
10456
10995
  testID,
10996
+ id,
10997
+ name,
10457
10998
  onChangeText,
10458
10999
  multiline,
10459
11000
  numberOfLines,
10460
11001
  ...rest
10461
11002
  }) => {
10462
11003
  const colors = useThemeColors();
10463
- const reactId = React.useId();
10464
- const inputId = testID ?? `nori-ui-input-${reactId}`;
10465
11004
  const inputRef = React.useRef(null);
10466
- const focusInput = /* @__PURE__ */ __name(() => {
10467
- inputRef.current?.focus();
10468
- }, "focusInput");
10469
- const describeId = `${inputId}-describe`;
10470
- const hasError = Boolean(error);
10471
- const describedBy = error || helperText ? describeId : void 0;
11005
+ const restAny = rest;
11006
+ const hasError = restAny["aria-invalid"] === true || restAny["aria-invalid"] === "true";
10472
11007
  const inputExtras = {};
10473
11008
  if (testID !== void 0) {
10474
11009
  inputExtras.testID = testID;
10475
11010
  }
10476
- if (label !== void 0) {
10477
- inputExtras.accessibilityLabel = label;
10478
- }
10479
- if (hasError) {
10480
- inputExtras["aria-invalid"] = true;
11011
+ if (id !== void 0) {
11012
+ inputExtras.id = id;
11013
+ inputExtras.nativeID = id;
10481
11014
  }
10482
- if (describedBy !== void 0) {
10483
- inputExtras["aria-describedby"] = describedBy;
11015
+ if (name !== void 0) {
11016
+ inputExtras.name = name;
10484
11017
  }
10485
11018
  if (multiline !== void 0) {
10486
11019
  inputExtras.multiline = multiline;
@@ -10491,12 +11024,6 @@ var TextInput = /* @__PURE__ */ __name(({
10491
11024
  if (onChangeText !== void 0) {
10492
11025
  inputExtras.onChangeText = onChangeText;
10493
11026
  }
10494
- const labelStyle = {
10495
- fontFamily: colors.fontFamily.body,
10496
- fontSize: px(colors.fontSize.sm),
10497
- fontWeight: colors.fontWeight.medium,
10498
- color: colors.semantic.text.default
10499
- };
10500
11027
  const inputStyle = {
10501
11028
  flex: 1,
10502
11029
  paddingVertical: px(colors.spacing["2"]),
@@ -10504,17 +11031,6 @@ var TextInput = /* @__PURE__ */ __name(({
10504
11031
  fontSize: px(colors.fontSize.md),
10505
11032
  color: colors.semantic.text.default
10506
11033
  };
10507
- const helperStyle = {
10508
- fontFamily: colors.fontFamily.body,
10509
- fontSize: px(colors.fontSize.sm),
10510
- color: colors.semantic.text.muted
10511
- };
10512
- const errorStyle = {
10513
- fontFamily: colors.fontFamily.body,
10514
- fontSize: px(colors.fontSize.sm),
10515
- color: colors.color.danger
10516
- };
10517
- const containerStyle = { ...CONTAINER_LAYOUT_BASE4, gap: px(colors.spacing["1"]) };
10518
11034
  const fieldStyle = [
10519
11035
  FIELD_LAYOUT_BASE2,
10520
11036
  {
@@ -10525,55 +11041,33 @@ var TextInput = /* @__PURE__ */ __name(({
10525
11041
  },
10526
11042
  disabled ? { opacity: 0.6 } : null
10527
11043
  ];
10528
- return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { className: cn("flex flex-col gap-1", containerClassName), style: containerStyle, children: [
10529
- label !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: focusInput, accessibilityRole: "none", disabled, children: /* @__PURE__ */ jsxRuntime.jsx(
10530
- reactNative.Text,
10531
- {
10532
- nativeID: `${inputId}-label`,
10533
- accessibilityRole: "text",
10534
- className: "text-sm font-medium text-semantic-text-default",
10535
- style: labelStyle,
10536
- children: label
10537
- }
10538
- ) }) : null,
10539
- /* @__PURE__ */ jsxRuntime.jsxs(
10540
- reactNative.View,
10541
- {
10542
- className: cn(
10543
- "flex-row items-center rounded-md border px-3",
10544
- hasError ? "border-semantic-interactive-destructive" : "border-semantic-border-default",
10545
- disabled ? "opacity-60" : void 0
11044
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { className: cn(containerClassName), style: { flexDirection: "column" }, children: /* @__PURE__ */ jsxRuntime.jsxs(
11045
+ reactNative.View,
11046
+ {
11047
+ className: cn(
11048
+ "flex-row items-center rounded-md border px-3",
11049
+ hasError ? "border-semantic-interactive-destructive" : "border-semantic-border-default",
11050
+ disabled ? "opacity-60" : void 0
11051
+ ),
11052
+ style: fieldStyle,
11053
+ children: [
11054
+ leading ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { className: "mr-2", style: { marginRight: px(colors.spacing["2"]) }, children: leading }) : null,
11055
+ /* @__PURE__ */ jsxRuntime.jsx(
11056
+ reactNative.TextInput,
11057
+ {
11058
+ ref: inputRef,
11059
+ editable: !disabled,
11060
+ className: cn("flex-1 py-2 text-md text-semantic-text-default outline-none", className),
11061
+ placeholderTextColor: colors.semantic.text.muted,
11062
+ ...inputExtras,
11063
+ ...rest,
11064
+ style: [inputStyle, rest.style]
11065
+ }
10546
11066
  ),
10547
- style: fieldStyle,
10548
- children: [
10549
- leading ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { className: "mr-2", style: { marginRight: px(colors.spacing["2"]) }, children: leading }) : null,
10550
- /* @__PURE__ */ jsxRuntime.jsx(
10551
- reactNative.TextInput,
10552
- {
10553
- ref: inputRef,
10554
- nativeID: inputId,
10555
- editable: !disabled,
10556
- className: cn("flex-1 py-2 text-md text-semantic-text-default outline-none", className),
10557
- placeholderTextColor: colors.semantic.text.muted,
10558
- ...inputExtras,
10559
- ...rest,
10560
- style: [inputStyle, rest.style]
10561
- }
10562
- ),
10563
- trailing ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { className: "ml-2", style: { marginLeft: px(colors.spacing["2"]) }, children: trailing }) : null
10564
- ]
10565
- }
10566
- ),
10567
- error ? /* @__PURE__ */ jsxRuntime.jsx(
10568
- reactNative.Text,
10569
- {
10570
- nativeID: describeId,
10571
- className: "text-sm text-semantic-interactive-destructive",
10572
- style: errorStyle,
10573
- children: error
10574
- }
10575
- ) : helperText ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { nativeID: describeId, className: "text-sm text-semantic-text-muted", style: helperStyle, children: helperText }) : null
10576
- ] });
11067
+ trailing ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { className: "ml-2", style: { marginLeft: px(colors.spacing["2"]) }, children: trailing }) : null
11068
+ ]
11069
+ }
11070
+ ) });
10577
11071
  }, "TextInput");
10578
11072
  var TextArea = /* @__PURE__ */ __name(({ numberOfLines = 4, resize = "vertical", style, ...rest }) => {
10579
11073
  const resizeStyle = { resize };
@@ -11640,10 +12134,12 @@ exports.Calendar = Calendar;
11640
12134
  exports.Card = Card;
11641
12135
  exports.Checkbox = Checkbox;
11642
12136
  exports.Dialog = Dialog;
12137
+ exports.Field = Field;
11643
12138
  exports.FloatButton = FloatButton;
11644
12139
  exports.HStack = HStack;
11645
12140
  exports.Icon = Icon;
11646
12141
  exports.InputGroup = InputGroup;
12142
+ exports.Label = Label;
11647
12143
  exports.PAGINATION_COMPACT_BREAKPOINT = PAGINATION_COMPACT_BREAKPOINT;
11648
12144
  exports.Pagination = Pagination;
11649
12145
  exports.Popover = Popover;