@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/client.cjs CHANGED
@@ -68,8 +68,8 @@ var defaultDictionary = {
68
68
  // floatButton
69
69
  "floatButton.backToTop": "Back to top",
70
70
  // calendar
71
- "calendar.header.previous": "Previous",
72
- "calendar.header.next": "Next",
71
+ "calendar.header.previous": "Previous month",
72
+ "calendar.header.next": "Next month",
73
73
  "calendar.header.openMonthView": "Open month picker",
74
74
  "calendar.header.openYearView": "Open year picker",
75
75
  "calendar.header.openDayView": "Open day picker",
@@ -85,7 +85,10 @@ var defaultDictionary = {
85
85
  "checkbox.checked": "Checked",
86
86
  "checkbox.unchecked": "Unchecked",
87
87
  "switch.on": "On",
88
- "switch.off": "Off"
88
+ "switch.off": "Off",
89
+ // field
90
+ "field.requiredIndicator": "*",
91
+ "field.requiredLabel": "required"
89
92
  };
90
93
 
91
94
  // src/i18n/resolve.ts
@@ -3697,6 +3700,13 @@ var Button = /* @__PURE__ */ __name(({
3697
3700
  );
3698
3701
  }, "Button");
3699
3702
 
3703
+ // src/components/Calendar/scroll/ScrollBody.tsx
3704
+ var ScrollBody = /* @__PURE__ */ __name((_props) => {
3705
+ throw new Error(
3706
+ "[Calendar] ScrollBody: no platform implementation resolved. Ensure your bundler honors *.web.tsx / *.native.tsx extensions."
3707
+ );
3708
+ }, "ScrollBody");
3709
+
3700
3710
  // src/components/Calendar/state/locale-utils.ts
3701
3711
  var getFirstDayOfWeek = /* @__PURE__ */ __name((locale) => {
3702
3712
  try {
@@ -4058,9 +4068,15 @@ var Select = /* @__PURE__ */ __name((props) => {
4058
4068
  itemHeight = DEFAULT_ITEM_HEIGHT,
4059
4069
  maxMenuHeight = DEFAULT_MAX_MENU,
4060
4070
  className,
4061
- testID
4071
+ testID,
4072
+ id,
4073
+ name
4062
4074
  } = props;
4063
4075
  const ariaLabel = props["aria-label"];
4076
+ const ariaLabelledBy = props["aria-labelledby"];
4077
+ const ariaDescribedBy = props["aria-describedby"];
4078
+ const ariaInvalid = props["aria-invalid"];
4079
+ const ariaRequired = props["aria-required"];
4064
4080
  const multiple = props.multiple === true;
4065
4081
  const maxSelected = multiple ? props.maxSelected : void 0;
4066
4082
  const maxChips = multiple ? props.maxChips ?? 3 : void 0;
@@ -4424,11 +4440,11 @@ var Select = /* @__PURE__ */ __name((props) => {
4424
4440
  if (!open || searchable || reactNative.Platform.OS !== "web") {
4425
4441
  return;
4426
4442
  }
4427
- const id = requestAnimationFrame(() => {
4443
+ const id2 = requestAnimationFrame(() => {
4428
4444
  const node = popupRef.current;
4429
4445
  node?.focus?.();
4430
4446
  });
4431
- return () => cancelAnimationFrame(id);
4447
+ return () => cancelAnimationFrame(id2);
4432
4448
  }, [open, searchable]);
4433
4449
  const onListScroll = React.useCallback(
4434
4450
  (event) => {
@@ -4505,7 +4521,13 @@ var Select = /* @__PURE__ */ __name((props) => {
4505
4521
  "aria-controls": `${baseId}-listbox`,
4506
4522
  "aria-haspopup": "listbox",
4507
4523
  tabIndex: disabled ? -1 : 0,
4524
+ ...id !== void 0 ? { id, nativeID: id } : {},
4525
+ ...name !== void 0 ? { name } : {},
4508
4526
  ...ariaLabel !== void 0 ? { "aria-label": ariaLabel, accessibilityLabel: ariaLabel } : {},
4527
+ ...ariaLabelledBy !== void 0 ? { "aria-labelledby": ariaLabelledBy, accessibilityLabelledBy: ariaLabelledBy } : {},
4528
+ ...ariaDescribedBy !== void 0 ? { "aria-describedby": ariaDescribedBy, accessibilityDescribedBy: ariaDescribedBy } : {},
4529
+ ...ariaInvalid === true ? { "aria-invalid": true } : {},
4530
+ ...ariaRequired === true ? { "aria-required": true } : {},
4509
4531
  ...disabled ? { "aria-disabled": true, disabled: true } : {}
4510
4532
  },
4511
4533
  onPress: () => {
@@ -5179,7 +5201,7 @@ var Caption = /* @__PURE__ */ __name(({
5179
5201
  alignSelf: "center"
5180
5202
  },
5181
5203
  children: [
5182
- /* @__PURE__ */ jsxRuntime.jsx(NavButton, { label: t("calendar.header.previous", { defaultValue: "Previous" }), onPress: onPrev, children: "\u2039" }),
5204
+ /* @__PURE__ */ jsxRuntime.jsx(NavButton, { label: t("calendar.header.previous", { defaultValue: "Previous month" }), onPress: onPrev, children: "\u2039" }),
5183
5205
  /* @__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(
5184
5206
  DropdownPair,
5185
5207
  {
@@ -5225,7 +5247,7 @@ var Caption = /* @__PURE__ */ __name(({
5225
5247
  drilldown: true
5226
5248
  }
5227
5249
  ) }) }),
5228
- /* @__PURE__ */ jsxRuntime.jsx(NavButton, { label: t("calendar.header.next", { defaultValue: "Next" }), onPress: onNext, children: "\u203A" })
5250
+ /* @__PURE__ */ jsxRuntime.jsx(NavButton, { label: t("calendar.header.next", { defaultValue: "Next month" }), onPress: onNext, children: "\u203A" })
5229
5251
  ]
5230
5252
  }
5231
5253
  );
@@ -5268,8 +5290,53 @@ var DropdownPair = /* @__PURE__ */ __name(({ month, year, monthOptions, yearOpti
5268
5290
  ] });
5269
5291
  }, "DropdownPair");
5270
5292
  var CELL_SIZE = 40;
5271
- var DayCell = /* @__PURE__ */ __name(({ ctx, onPress, onHoverIn, onHoverOut, renderDay }) => {
5293
+ var formatterCache = /* @__PURE__ */ new Map();
5294
+ var RUNTIME_DEFAULT_LOCALE_KEY = "__default__";
5295
+ var getDayFormatter = /* @__PURE__ */ __name((locale) => {
5296
+ const key = locale ?? RUNTIME_DEFAULT_LOCALE_KEY;
5297
+ const cached2 = formatterCache.get(key);
5298
+ if (cached2) {
5299
+ return cached2;
5300
+ }
5301
+ try {
5302
+ const fmt = new Intl.DateTimeFormat(locale, {
5303
+ weekday: "long",
5304
+ month: "long",
5305
+ day: "numeric",
5306
+ year: "numeric",
5307
+ timeZone: "UTC"
5308
+ });
5309
+ formatterCache.set(key, fmt);
5310
+ return fmt;
5311
+ } catch {
5312
+ return null;
5313
+ }
5314
+ }, "getDayFormatter");
5315
+ var formatDayLabel = /* @__PURE__ */ __name((ctx, locale) => {
5316
+ const jsDate = new Date(Date.UTC(ctx.date.year, ctx.date.month - 1, ctx.date.day));
5317
+ const fmt = getDayFormatter(locale);
5318
+ const base = fmt ? fmt.format(jsDate) : (
5319
+ // Fallback if the runtime rejects the locale tag.
5320
+ `${ctx.date.month}/${ctx.date.day}/${ctx.date.year}`
5321
+ );
5322
+ const suffixes = [];
5323
+ if (ctx.isToday) {
5324
+ suffixes.push("today");
5325
+ }
5326
+ if (ctx.isSelected || ctx.isRangeStart || ctx.isRangeEnd) {
5327
+ suffixes.push("selected");
5328
+ }
5329
+ if (ctx.isInRange && !ctx.isRangeStart && !ctx.isRangeEnd) {
5330
+ suffixes.push("in range");
5331
+ }
5332
+ if (ctx.isUnavailable) {
5333
+ suffixes.push("unavailable");
5334
+ }
5335
+ return suffixes.length > 0 ? `${base}, ${suffixes.join(", ")}` : base;
5336
+ }, "formatDayLabel");
5337
+ var DayCell = /* @__PURE__ */ __name(({ ctx, onPress, onHoverIn, onHoverOut, renderDay, locale }) => {
5272
5338
  const colors = useThemeColors();
5339
+ const accessibilityLabel = formatDayLabel(ctx, locale);
5273
5340
  const isSelectedLike = ctx.isSelected || ctx.isRangeStart || ctx.isRangeEnd;
5274
5341
  const isInsideRange = ctx.isInRange || ctx.isInPreviewRange;
5275
5342
  const isRangeMiddle = isInsideRange && !isSelectedLike;
@@ -5278,7 +5345,8 @@ var DayCell = /* @__PURE__ */ __name(({ ctx, onPress, onHoverIn, onHoverOut, ren
5278
5345
  reactNative.Pressable,
5279
5346
  {
5280
5347
  accessibilityRole: "button",
5281
- accessibilityState: { disabled: ctx.isUnavailable },
5348
+ accessibilityLabel,
5349
+ accessibilityState: { disabled: ctx.isUnavailable, selected: isSelectedLike },
5282
5350
  disabled: ctx.isUnavailable,
5283
5351
  onPress,
5284
5352
  ...onHoverIn ? { onHoverIn } : {},
@@ -5536,6 +5604,7 @@ var DayGrid = /* @__PURE__ */ __name((props) => {
5536
5604
  DayCell,
5537
5605
  {
5538
5606
  ctx,
5607
+ locale,
5539
5608
  onPress: () => onDayPress(date),
5540
5609
  ...onDayHover ? {
5541
5610
  onHoverIn: /* @__PURE__ */ __name(() => onDayHover(date), "onHoverIn"),
@@ -5698,6 +5767,9 @@ var focusDayCell = /* @__PURE__ */ __name((root, date, force) => {
5698
5767
  if (!root) {
5699
5768
  return;
5700
5769
  }
5770
+ if (typeof document === "undefined" || typeof root.contains !== "function") {
5771
+ return;
5772
+ }
5701
5773
  if (!force && !root.contains(document.activeElement)) {
5702
5774
  return;
5703
5775
  }
@@ -5802,8 +5874,13 @@ var SingleOrMultiCalendar = /* @__PURE__ */ __name((props) => {
5802
5874
  const colors = useThemeColors();
5803
5875
  const firstDayOfWeek = props.firstDayOfWeek ?? getFirstDayOfWeek(locale);
5804
5876
  const weekendDays = props.weekendDays ?? getWeekendDays(locale);
5805
- const visibleMonths = pickVisibleMonths(props.visibleMonths, containerWidth);
5877
+ const visibleMonths = props.behavior === "scroll" ? 1 : pickVisibleMonths(props.visibleMonths, containerWidth);
5806
5878
  const { innerWidth, gridsRowWidth } = surfaceMetrics(visibleMonths);
5879
+ React.useEffect(() => {
5880
+ if (process.env.NODE_ENV !== "production" && props.behavior === "scroll" && typeof props.visibleMonths === "number" && props.visibleMonths > 1) {
5881
+ console.warn('[Calendar] visibleMonths is ignored when behavior="scroll"; falling back to single column.');
5882
+ }
5883
+ }, [props.behavior, props.visibleMonths]);
5807
5884
  const containerRef = React.useRef(null);
5808
5885
  const state = useCalendarState({
5809
5886
  ...props.mode !== void 0 ? { mode: props.mode } : {},
@@ -5866,6 +5943,8 @@ var SingleOrMultiCalendar = /* @__PURE__ */ __name((props) => {
5866
5943
  setAnchor((a) => a.add({ years: -10 }));
5867
5944
  } else if (state.view === "month") {
5868
5945
  setAnchor((a) => a.add({ years: -1 }));
5946
+ } else if (props.behavior === "scroll") {
5947
+ state.moveFocus({ months: -1 });
5869
5948
  } else {
5870
5949
  setAnchor((a) => a.add({ months: -1 }));
5871
5950
  }
@@ -5875,6 +5954,8 @@ var SingleOrMultiCalendar = /* @__PURE__ */ __name((props) => {
5875
5954
  setAnchor((a) => a.add({ years: 10 }));
5876
5955
  } else if (state.view === "month") {
5877
5956
  setAnchor((a) => a.add({ years: 1 }));
5957
+ } else if (props.behavior === "scroll") {
5958
+ state.moveFocus({ months: 1 });
5878
5959
  } else {
5879
5960
  setAnchor((a) => a.add({ months: 1 }));
5880
5961
  }
@@ -5937,22 +6018,44 @@ var SingleOrMultiCalendar = /* @__PURE__ */ __name((props) => {
5937
6018
  }
5938
6019
  ),
5939
6020
  /* @__PURE__ */ jsxRuntime.jsxs(FadeIn, { children: [
5940
- 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(
5941
- DayGrid,
6021
+ state.view === "day" && (props.behavior === "scroll" ? /* @__PURE__ */ jsxRuntime.jsx(
6022
+ ScrollBody,
5942
6023
  {
5943
- visibleMonth: m,
5944
- locale,
5945
6024
  mode: props.mode ?? "single",
5946
- value: state.value,
6025
+ locale,
5947
6026
  focusedDate: state.focusedDate,
5948
- isUnavailable: state.isUnavailable,
5949
- weekendDays,
6027
+ onFocusedMonthChange: (next) => setAnchor(next),
6028
+ value: state.value,
6029
+ onSelectDate: (date) => state.selectDate(date, "click"),
5950
6030
  firstDayOfWeek,
5951
- onDayPress: (date) => state.selectDate(date, "click"),
6031
+ weekendDays,
6032
+ ...props.minValue !== void 0 ? { minValue: props.minValue } : {},
6033
+ ...props.maxValue !== void 0 ? { maxValue: props.maxValue } : {},
6034
+ ...props.isDateUnavailable !== void 0 ? { isDateUnavailable: props.isDateUnavailable } : {},
5952
6035
  ...renderDay ? { renderDay } : {}
5953
- },
5954
- `${m.year}-${m.month}`
5955
- )) }),
6036
+ }
6037
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
6038
+ reactNative.View,
6039
+ {
6040
+ style: { flexDirection: "row", gap: MONTH_GAP, alignSelf: "center", width: gridsRowWidth },
6041
+ children: months.map((m) => /* @__PURE__ */ jsxRuntime.jsx(
6042
+ DayGrid,
6043
+ {
6044
+ visibleMonth: m,
6045
+ locale,
6046
+ mode: props.mode ?? "single",
6047
+ value: state.value,
6048
+ focusedDate: state.focusedDate,
6049
+ isUnavailable: state.isUnavailable,
6050
+ weekendDays,
6051
+ firstDayOfWeek,
6052
+ onDayPress: (date) => state.selectDate(date, "click"),
6053
+ ...renderDay ? { renderDay } : {}
6054
+ },
6055
+ `${m.year}-${m.month}`
6056
+ ))
6057
+ }
6058
+ )),
5956
6059
  state.view === "month" && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { alignItems: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
5957
6060
  MonthGrid,
5958
6061
  {
@@ -5987,8 +6090,13 @@ var RangeCalendar = /* @__PURE__ */ __name((props) => {
5987
6090
  const colors = useThemeColors();
5988
6091
  const firstDayOfWeek = props.firstDayOfWeek ?? getFirstDayOfWeek(locale);
5989
6092
  const weekendDays = props.weekendDays ?? getWeekendDays(locale);
5990
- const visibleMonths = pickVisibleMonths(props.visibleMonths, containerWidth);
6093
+ const visibleMonths = props.behavior === "scroll" ? 1 : pickVisibleMonths(props.visibleMonths, containerWidth);
5991
6094
  const { innerWidth, gridsRowWidth } = surfaceMetrics(visibleMonths);
6095
+ React.useEffect(() => {
6096
+ if (process.env.NODE_ENV !== "production" && props.behavior === "scroll" && typeof props.visibleMonths === "number" && props.visibleMonths > 1) {
6097
+ console.warn('[Calendar] visibleMonths is ignored when behavior="scroll"; falling back to single column.');
6098
+ }
6099
+ }, [props.behavior, props.visibleMonths]);
5992
6100
  const containerRef = React.useRef(null);
5993
6101
  const range2 = useRangeState({
5994
6102
  ...props.value !== void 0 ? { value: props.value } : {},
@@ -6066,6 +6174,8 @@ var RangeCalendar = /* @__PURE__ */ __name((props) => {
6066
6174
  setAnchor((a) => a.add({ years: -10 }));
6067
6175
  } else if (view === "month") {
6068
6176
  setAnchor((a) => a.add({ years: -1 }));
6177
+ } else if (props.behavior === "scroll") {
6178
+ setFocusedDate((f) => f.add({ months: -1 }));
6069
6179
  } else {
6070
6180
  setAnchor((a) => a.add({ months: -1 }));
6071
6181
  }
@@ -6075,6 +6185,8 @@ var RangeCalendar = /* @__PURE__ */ __name((props) => {
6075
6185
  setAnchor((a) => a.add({ years: 10 }));
6076
6186
  } else if (view === "month") {
6077
6187
  setAnchor((a) => a.add({ years: 1 }));
6188
+ } else if (props.behavior === "scroll") {
6189
+ setFocusedDate((f) => f.add({ months: 1 }));
6078
6190
  } else {
6079
6191
  setAnchor((a) => a.add({ months: 1 }));
6080
6192
  }
@@ -6145,24 +6257,47 @@ var RangeCalendar = /* @__PURE__ */ __name((props) => {
6145
6257
  }
6146
6258
  ),
6147
6259
  /* @__PURE__ */ jsxRuntime.jsxs(FadeIn, { children: [
6148
- view === "day" && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { flexDirection: "row", gap: MONTH_GAP, alignSelf: "center", width: gridsRowWidth }, children: months.map((m) => /* @__PURE__ */ jsxRuntime.jsx(
6149
- DayGrid,
6260
+ view === "day" && (props.behavior === "scroll" ? /* @__PURE__ */ jsxRuntime.jsx(
6261
+ ScrollBody,
6150
6262
  {
6151
- visibleMonth: m,
6152
- locale,
6153
6263
  mode: "range",
6264
+ locale,
6265
+ focusedDate,
6266
+ onFocusedMonthChange: (next) => setAnchor(next),
6154
6267
  value: range2.value,
6155
6268
  previewRange: range2.previewRange,
6156
- focusedDate,
6157
- isUnavailable: range2.isUnavailable,
6158
- weekendDays,
6269
+ onSelectDate: (date) => range2.selectDate(date),
6159
6270
  firstDayOfWeek,
6160
- onDayPress: (date) => range2.selectDate(date),
6161
- onDayHover: (date) => range2.setHoveredDate(date),
6271
+ weekendDays,
6272
+ ...props.minValue !== void 0 ? { minValue: props.minValue } : {},
6273
+ ...props.maxValue !== void 0 ? { maxValue: props.maxValue } : {},
6274
+ ...props.isDateUnavailable !== void 0 ? { isDateUnavailable: props.isDateUnavailable } : {},
6162
6275
  ...renderDay ? { renderDay } : {}
6163
- },
6164
- `${m.year}-${m.month}`
6165
- )) }),
6276
+ }
6277
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
6278
+ reactNative.View,
6279
+ {
6280
+ style: { flexDirection: "row", gap: MONTH_GAP, alignSelf: "center", width: gridsRowWidth },
6281
+ children: months.map((m) => /* @__PURE__ */ jsxRuntime.jsx(
6282
+ DayGrid,
6283
+ {
6284
+ visibleMonth: m,
6285
+ locale,
6286
+ mode: "range",
6287
+ value: range2.value,
6288
+ previewRange: range2.previewRange,
6289
+ focusedDate,
6290
+ isUnavailable: range2.isUnavailable,
6291
+ weekendDays,
6292
+ firstDayOfWeek,
6293
+ onDayPress: (date) => range2.selectDate(date),
6294
+ onDayHover: (date) => range2.setHoveredDate(date),
6295
+ ...renderDay ? { renderDay } : {}
6296
+ },
6297
+ `${m.year}-${m.month}`
6298
+ ))
6299
+ }
6300
+ )),
6166
6301
  view === "month" && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { alignItems: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
6167
6302
  MonthGrid,
6168
6303
  {
@@ -6350,7 +6485,15 @@ var Checkbox = /* @__PURE__ */ __name(({
6350
6485
  className,
6351
6486
  testID,
6352
6487
  asChild,
6353
- children
6488
+ children,
6489
+ id,
6490
+ name,
6491
+ "aria-labelledby": ariaLabelledBy,
6492
+ accessibilityLabelledBy,
6493
+ "aria-describedby": ariaDescribedBy,
6494
+ accessibilityDescribedBy,
6495
+ "aria-invalid": ariaInvalid,
6496
+ "aria-required": ariaRequired
6354
6497
  }) => {
6355
6498
  const colors = useThemeColors();
6356
6499
  const [inner, setInner] = React.useState(defaultChecked);
@@ -6378,6 +6521,13 @@ var Checkbox = /* @__PURE__ */ __name(({
6378
6521
  accessibilityState: { checked: value, disabled: Boolean(disabled) },
6379
6522
  testID
6380
6523
  };
6524
+ if (id !== void 0) {
6525
+ commonProps.id = id;
6526
+ commonProps.nativeID = id;
6527
+ }
6528
+ if (name !== void 0) {
6529
+ commonProps.name = name;
6530
+ }
6381
6531
  if (disabled) {
6382
6532
  commonProps["aria-disabled"] = true;
6383
6533
  }
@@ -6385,6 +6535,26 @@ var Checkbox = /* @__PURE__ */ __name(({
6385
6535
  commonProps["aria-label"] = label;
6386
6536
  commonProps.accessibilityLabel = label;
6387
6537
  }
6538
+ if (ariaLabelledBy !== void 0) {
6539
+ commonProps["aria-labelledby"] = ariaLabelledBy;
6540
+ commonProps.accessibilityLabelledBy = ariaLabelledBy;
6541
+ }
6542
+ if (accessibilityLabelledBy !== void 0) {
6543
+ commonProps.accessibilityLabelledBy = accessibilityLabelledBy;
6544
+ }
6545
+ if (ariaDescribedBy !== void 0) {
6546
+ commonProps["aria-describedby"] = ariaDescribedBy;
6547
+ commonProps.accessibilityDescribedBy = ariaDescribedBy;
6548
+ }
6549
+ if (accessibilityDescribedBy !== void 0) {
6550
+ commonProps.accessibilityDescribedBy = accessibilityDescribedBy;
6551
+ }
6552
+ if (ariaInvalid) {
6553
+ commonProps["aria-invalid"] = true;
6554
+ }
6555
+ if (ariaRequired) {
6556
+ commonProps["aria-required"] = true;
6557
+ }
6388
6558
  if (asChild) {
6389
6559
  const slotProps = {
6390
6560
  role: "checkbox",
@@ -6853,6 +7023,279 @@ var Dialog = Object.assign(DialogRoot, {
6853
7023
  Footer: DialogFooter,
6854
7024
  Close: DialogClose
6855
7025
  });
7026
+ var FieldContext = React.createContext(null);
7027
+ var useFieldContextStrict = /* @__PURE__ */ __name((caller) => {
7028
+ const ctx = React.useContext(FieldContext);
7029
+ if (!ctx) {
7030
+ throw new Error(`[Field] ${caller} must be used inside <Field> or <Field.Group>.`);
7031
+ }
7032
+ return ctx;
7033
+ }, "useFieldContextStrict");
7034
+ var childHasDisplayName = /* @__PURE__ */ __name((child, name) => {
7035
+ if (!React.isValidElement(child)) {
7036
+ return false;
7037
+ }
7038
+ const t = child.type;
7039
+ return typeof t !== "string" && t?.displayName === name;
7040
+ }, "childHasDisplayName");
7041
+ var COMPOUND_DISPLAY_NAMES = ["Field.Label", "Field.Description", "Field.Error", "Field.Control"];
7042
+ var isCompoundChild = /* @__PURE__ */ __name((child) => COMPOUND_DISPLAY_NAMES.some((name) => childHasDisplayName(child, name)), "isCompoundChild");
7043
+ var FieldRoot = /* @__PURE__ */ __name(({
7044
+ name,
7045
+ required = false,
7046
+ disabled = false,
7047
+ error = null,
7048
+ label,
7049
+ description,
7050
+ validating = false,
7051
+ orientation = "vertical",
7052
+ id,
7053
+ children,
7054
+ className,
7055
+ testID,
7056
+ isGroup = false
7057
+ }) => {
7058
+ const colors = useThemeColors();
7059
+ const reactId = React.useId();
7060
+ const fieldId = id ?? `nori-ui-field-${reactId}`;
7061
+ const labelId = `${fieldId}-label`;
7062
+ const descriptionId = `${fieldId}-desc`;
7063
+ const errorId = `${fieldId}-error`;
7064
+ const isCompoundMode = React.useMemo(() => {
7065
+ let found = false;
7066
+ React.Children.forEach(children, (child) => {
7067
+ if (isCompoundChild(child)) {
7068
+ found = true;
7069
+ }
7070
+ });
7071
+ return found;
7072
+ }, [children]);
7073
+ const hasDescription = React.useMemo(() => {
7074
+ if (!isCompoundMode) {
7075
+ return description !== void 0 && description !== null && description !== false && description !== "";
7076
+ }
7077
+ let found = false;
7078
+ React.Children.forEach(children, (child) => {
7079
+ if (childHasDisplayName(child, "Field.Description")) {
7080
+ found = true;
7081
+ }
7082
+ });
7083
+ return found;
7084
+ }, [isCompoundMode, description, children]);
7085
+ const hasError = React.useMemo(() => {
7086
+ if (!isCompoundMode) {
7087
+ return Boolean(error);
7088
+ }
7089
+ let found = false;
7090
+ React.Children.forEach(children, (child) => {
7091
+ if (childHasDisplayName(child, "Field.Error") && React.isValidElement(child)) {
7092
+ const el = child;
7093
+ if (el.props.children !== void 0 && el.props.children !== null && el.props.children !== false && el.props.children !== "") {
7094
+ found = true;
7095
+ }
7096
+ }
7097
+ });
7098
+ if (!found && error !== null && error !== void 0 && error !== false && error !== "") {
7099
+ found = true;
7100
+ }
7101
+ return found;
7102
+ }, [isCompoundMode, error, children]);
7103
+ const describedBy = React.useMemo(() => {
7104
+ const ids = [];
7105
+ if (hasDescription) {
7106
+ ids.push(descriptionId);
7107
+ }
7108
+ if (hasError) {
7109
+ ids.push(errorId);
7110
+ }
7111
+ return ids.length === 0 ? void 0 : ids.join(" ");
7112
+ }, [hasDescription, hasError, descriptionId, errorId]);
7113
+ const value = {
7114
+ fieldId,
7115
+ labelId,
7116
+ descriptionId,
7117
+ errorId,
7118
+ hasError,
7119
+ hasDescription,
7120
+ describedBy,
7121
+ disabled,
7122
+ required,
7123
+ validating,
7124
+ ...name !== void 0 ? { name } : {},
7125
+ // In compound mode pass `error` (string) so Field.Error can fall back to it.
7126
+ // In shorthand mode the error prop may be ReactNode; only pass when it is a string/null.
7127
+ ...error !== null && error !== void 0 && typeof error === "string" ? { error } : {},
7128
+ isGroup
7129
+ };
7130
+ const warnedRef = React.useRef(false);
7131
+ React.useEffect(() => {
7132
+ if (process.env.NODE_ENV === "production" || warnedRef.current) {
7133
+ return;
7134
+ }
7135
+ const hasShorthand = label !== void 0 || description !== void 0 || error !== void 0;
7136
+ if (hasShorthand && isCompoundMode) {
7137
+ warnedRef.current = true;
7138
+ console.warn(
7139
+ "[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."
7140
+ );
7141
+ }
7142
+ }, [label, description, error, isCompoundMode]);
7143
+ const containerStyle = orientation === "horizontal" ? {
7144
+ flexDirection: "row",
7145
+ alignItems: "flex-start",
7146
+ gap: px(colors.spacing["3"])
7147
+ } : { flexDirection: "column", gap: px(colors.spacing["1"]) };
7148
+ const containerExtra = {};
7149
+ if (testID !== void 0) {
7150
+ containerExtra.testID = testID;
7151
+ }
7152
+ containerExtra["data-orientation"] = orientation;
7153
+ if (isGroup) {
7154
+ containerExtra.role = "group";
7155
+ containerExtra["aria-labelledby"] = labelId;
7156
+ containerExtra.accessibilityRole = "none";
7157
+ }
7158
+ if (validating) {
7159
+ containerExtra["data-validating"] = "";
7160
+ containerExtra["aria-busy"] = true;
7161
+ }
7162
+ const renderShorthand = /* @__PURE__ */ __name(() => {
7163
+ const childArray = React.Children.toArray(children);
7164
+ const controlChild = childArray.length === 1 && React.isValidElement(childArray[0]) ? childArray[0] : null;
7165
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7166
+ label !== void 0 && label !== null && label !== false ? /* @__PURE__ */ jsxRuntime.jsx(FieldLabel, { children: label }) : null,
7167
+ description !== void 0 && description !== null && description !== false && description !== "" ? /* @__PURE__ */ jsxRuntime.jsx(FieldDescription, { children: description }) : null,
7168
+ controlChild !== null ? /* @__PURE__ */ jsxRuntime.jsx(FieldControl, { children: controlChild }) : children,
7169
+ error !== void 0 && error !== null && error !== false && error !== "" ? /* @__PURE__ */ jsxRuntime.jsx(FieldError, { children: error }) : null
7170
+ ] });
7171
+ }, "renderShorthand");
7172
+ return /* @__PURE__ */ jsxRuntime.jsx(FieldContext.Provider, { value, children: /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: containerStyle, ...className !== void 0 ? { className } : {}, ...containerExtra, children: [
7173
+ isCompoundMode ? children : renderShorthand(),
7174
+ validating ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: "sm" }) : null
7175
+ ] }) });
7176
+ }, "FieldRoot");
7177
+ var FieldLabel = /* @__PURE__ */ __name(({ children }) => {
7178
+ const ctx = useFieldContextStrict("Field.Label");
7179
+ const colors = useThemeColors();
7180
+ const { t } = useTranslation();
7181
+ const requiredIndicator = t("field.requiredIndicator");
7182
+ const requiredLabel = t("field.requiredLabel");
7183
+ const focusInput = /* @__PURE__ */ __name(() => {
7184
+ if (typeof document !== "undefined") {
7185
+ const el = document.getElementById(ctx.fieldId);
7186
+ if (el && typeof el.focus === "function") {
7187
+ el.focus();
7188
+ }
7189
+ }
7190
+ }, "focusInput");
7191
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: focusInput, accessibilityRole: "none", disabled: ctx.disabled, children: /* @__PURE__ */ jsxRuntime.jsxs(
7192
+ reactNative.Text,
7193
+ {
7194
+ nativeID: ctx.labelId,
7195
+ ...{ id: ctx.labelId },
7196
+ accessibilityRole: "text",
7197
+ style: {
7198
+ fontFamily: colors.fontFamily.body,
7199
+ fontSize: px(colors.fontSize.sm),
7200
+ fontWeight: colors.fontWeight.medium,
7201
+ color: ctx.disabled ? colors.semantic.text.muted : colors.semantic.text.default
7202
+ },
7203
+ children: [
7204
+ children,
7205
+ ctx.required ? /* @__PURE__ */ jsxRuntime.jsx(
7206
+ reactNative.Text,
7207
+ {
7208
+ accessibilityLabel: requiredLabel,
7209
+ ...{ "aria-label": requiredLabel },
7210
+ style: { color: colors.color.danger },
7211
+ children: ` ${requiredIndicator}`
7212
+ }
7213
+ ) : null
7214
+ ]
7215
+ }
7216
+ ) });
7217
+ }, "FieldLabel");
7218
+ FieldLabel.displayName = "Field.Label";
7219
+ var FieldControl = /* @__PURE__ */ __name(({ children }) => {
7220
+ const ctx = useFieldContextStrict("Field.Control");
7221
+ if (React.Children.count(children) !== 1 || !React.isValidElement(children)) {
7222
+ throw new Error("[Field.Control] expects exactly one child element.");
7223
+ }
7224
+ const child = children;
7225
+ const merged = {
7226
+ id: child.props.id ?? ctx.fieldId,
7227
+ accessibilityLabelledBy: ctx.labelId,
7228
+ "aria-labelledby": ctx.labelId
7229
+ };
7230
+ if (ctx.name !== void 0 && child.props.name === void 0) {
7231
+ merged.name = ctx.name;
7232
+ }
7233
+ if (ctx.describedBy !== void 0) {
7234
+ merged["aria-describedby"] = ctx.describedBy;
7235
+ merged.accessibilityDescribedBy = ctx.describedBy;
7236
+ }
7237
+ if (ctx.hasError) {
7238
+ merged["aria-invalid"] = true;
7239
+ }
7240
+ if (ctx.required) {
7241
+ merged["aria-required"] = true;
7242
+ }
7243
+ if (ctx.disabled || child.props.disabled) {
7244
+ merged.disabled = true;
7245
+ }
7246
+ return React.cloneElement(child, merged);
7247
+ }, "FieldControl");
7248
+ FieldControl.displayName = "Field.Control";
7249
+ var FieldDescription = /* @__PURE__ */ __name(({ children }) => {
7250
+ const ctx = useFieldContextStrict("Field.Description");
7251
+ const colors = useThemeColors();
7252
+ return /* @__PURE__ */ jsxRuntime.jsx(
7253
+ reactNative.Text,
7254
+ {
7255
+ nativeID: ctx.descriptionId,
7256
+ ...{ id: ctx.descriptionId },
7257
+ style: {
7258
+ fontFamily: colors.fontFamily.body,
7259
+ fontSize: px(colors.fontSize.sm),
7260
+ color: colors.semantic.text.muted
7261
+ },
7262
+ children
7263
+ }
7264
+ );
7265
+ }, "FieldDescription");
7266
+ FieldDescription.displayName = "Field.Description";
7267
+ var FieldError = /* @__PURE__ */ __name(({ children }) => {
7268
+ const ctx = useFieldContextStrict("Field.Error");
7269
+ const colors = useThemeColors();
7270
+ const content = children ?? ctx.error;
7271
+ if (content === null || content === void 0 || content === "" || content === false) {
7272
+ return null;
7273
+ }
7274
+ return /* @__PURE__ */ jsxRuntime.jsx(
7275
+ reactNative.Text,
7276
+ {
7277
+ nativeID: ctx.errorId,
7278
+ ...{ id: ctx.errorId, role: "alert" },
7279
+ accessibilityRole: "text",
7280
+ style: {
7281
+ fontFamily: colors.fontFamily.body,
7282
+ fontSize: px(colors.fontSize.sm),
7283
+ color: colors.color.danger
7284
+ },
7285
+ children: content
7286
+ }
7287
+ );
7288
+ }, "FieldError");
7289
+ FieldError.displayName = "Field.Error";
7290
+ var FieldGroup = /* @__PURE__ */ __name((props) => /* @__PURE__ */ jsxRuntime.jsx(FieldRoot, { ...props, isGroup: true }), "FieldGroup");
7291
+ FieldGroup.displayName = "Field.Group";
7292
+ var Field = Object.assign(FieldRoot, {
7293
+ Label: FieldLabel,
7294
+ Description: FieldDescription,
7295
+ Control: FieldControl,
7296
+ Error: FieldError,
7297
+ Group: FieldGroup
7298
+ });
6856
7299
  var isDev = process.env.NODE_ENV !== "production";
6857
7300
  var SafeAreaInsetsContext = /* @__PURE__ */ React__namespace.createContext(null);
6858
7301
  if (isDev) {
@@ -7863,6 +8306,55 @@ var InputGroup = Object.assign(InputGroupRoot, {
7863
8306
  Addon: InputGroupAddon,
7864
8307
  Input: InputGroupInput
7865
8308
  });
8309
+ var Label = /* @__PURE__ */ __name(({ htmlFor, required = false, disabled = false, children, className, testID }) => {
8310
+ const colors = useThemeColors();
8311
+ const { t } = useTranslation();
8312
+ const requiredIndicator = t("field.requiredIndicator");
8313
+ const requiredLabel = t("field.requiredLabel");
8314
+ const focusTarget = /* @__PURE__ */ __name(() => {
8315
+ if (typeof document !== "undefined") {
8316
+ const el = document.getElementById(htmlFor);
8317
+ if (el && typeof el.focus === "function") {
8318
+ el.focus();
8319
+ }
8320
+ }
8321
+ }, "focusTarget");
8322
+ return /* @__PURE__ */ jsxRuntime.jsx(
8323
+ reactNative.Pressable,
8324
+ {
8325
+ onPress: focusTarget,
8326
+ accessibilityRole: "none",
8327
+ disabled,
8328
+ ...testID !== void 0 ? { testID } : {},
8329
+ ...className !== void 0 ? { className } : {},
8330
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
8331
+ reactNative.Text,
8332
+ {
8333
+ ...{ htmlFor },
8334
+ accessibilityRole: "text",
8335
+ style: {
8336
+ fontFamily: colors.fontFamily.body,
8337
+ fontSize: px(colors.fontSize.sm),
8338
+ fontWeight: colors.fontWeight.medium,
8339
+ color: disabled ? colors.semantic.text.muted : colors.semantic.text.default
8340
+ },
8341
+ children: [
8342
+ children,
8343
+ required ? /* @__PURE__ */ jsxRuntime.jsx(
8344
+ reactNative.Text,
8345
+ {
8346
+ accessibilityLabel: requiredLabel,
8347
+ ...{ "aria-label": requiredLabel },
8348
+ style: { color: colors.color.danger },
8349
+ children: ` ${requiredIndicator}`
8350
+ }
8351
+ ) : null
8352
+ ]
8353
+ }
8354
+ )
8355
+ }
8356
+ );
8357
+ }, "Label");
7866
8358
  var range = /* @__PURE__ */ __name((from, to) => {
7867
8359
  if (to < from) {
7868
8360
  return [];
@@ -9009,7 +9501,15 @@ var RadioGroup = /* @__PURE__ */ __name(({
9009
9501
  name,
9010
9502
  children,
9011
9503
  className,
9012
- testID
9504
+ testID,
9505
+ id,
9506
+ nativeID,
9507
+ "aria-labelledby": ariaLabelledBy,
9508
+ accessibilityLabelledBy,
9509
+ "aria-describedby": ariaDescribedBy,
9510
+ accessibilityDescribedBy,
9511
+ "aria-invalid": ariaInvalid,
9512
+ "aria-required": ariaRequired
9013
9513
  }) => {
9014
9514
  const [inner, setInner] = React.useState(defaultValue2);
9015
9515
  const isControlled = value !== void 0;
@@ -9111,7 +9611,15 @@ var RadioGroup = /* @__PURE__ */ __name(({
9111
9611
  "aria-orientation": orientation,
9112
9612
  "aria-disabled": disabled || void 0,
9113
9613
  onKeyDown: handleKeyDown,
9114
- ...testID !== void 0 ? { testID } : {}
9614
+ ...testID !== void 0 ? { testID } : {},
9615
+ ...id !== void 0 ? { id } : {},
9616
+ ...nativeID !== void 0 ? { nativeID } : {},
9617
+ ...ariaLabelledBy !== void 0 ? { "aria-labelledby": ariaLabelledBy } : {},
9618
+ ...accessibilityLabelledBy !== void 0 ? { accessibilityLabelledBy } : {},
9619
+ ...ariaDescribedBy !== void 0 ? { "aria-describedby": ariaDescribedBy } : {},
9620
+ ...accessibilityDescribedBy !== void 0 ? { accessibilityDescribedBy } : {},
9621
+ ...ariaInvalid ? { "aria-invalid": true } : {},
9622
+ ...ariaRequired ? { "aria-required": true } : {}
9115
9623
  };
9116
9624
  return /* @__PURE__ */ jsxRuntime.jsx(RadioGroupContext.Provider, { value: ctxValue, children: /* @__PURE__ */ jsxRuntime.jsx(
9117
9625
  RadioGroupViewport,
@@ -10057,7 +10565,15 @@ var Switch = /* @__PURE__ */ __name(({
10057
10565
  className,
10058
10566
  testID,
10059
10567
  asChild,
10060
- children
10568
+ children,
10569
+ id,
10570
+ name,
10571
+ "aria-labelledby": ariaLabelledBy,
10572
+ accessibilityLabelledBy,
10573
+ "aria-describedby": ariaDescribedBy,
10574
+ accessibilityDescribedBy,
10575
+ "aria-invalid": ariaInvalid,
10576
+ "aria-required": ariaRequired
10061
10577
  }) => {
10062
10578
  const colors = useThemeColors();
10063
10579
  const [inner, setInner] = React.useState(defaultChecked);
@@ -10082,6 +10598,13 @@ var Switch = /* @__PURE__ */ __name(({
10082
10598
  accessibilityState: { checked: value, disabled: Boolean(disabled) },
10083
10599
  testID
10084
10600
  };
10601
+ if (id !== void 0) {
10602
+ commonProps.id = id;
10603
+ commonProps.nativeID = id;
10604
+ }
10605
+ if (name !== void 0) {
10606
+ commonProps.name = name;
10607
+ }
10085
10608
  if (disabled) {
10086
10609
  commonProps["aria-disabled"] = true;
10087
10610
  }
@@ -10089,6 +10612,26 @@ var Switch = /* @__PURE__ */ __name(({
10089
10612
  commonProps["aria-label"] = label;
10090
10613
  commonProps.accessibilityLabel = label;
10091
10614
  }
10615
+ if (ariaLabelledBy !== void 0) {
10616
+ commonProps["aria-labelledby"] = ariaLabelledBy;
10617
+ commonProps.accessibilityLabelledBy = ariaLabelledBy;
10618
+ }
10619
+ if (accessibilityLabelledBy !== void 0) {
10620
+ commonProps.accessibilityLabelledBy = accessibilityLabelledBy;
10621
+ }
10622
+ if (ariaDescribedBy !== void 0) {
10623
+ commonProps["aria-describedby"] = ariaDescribedBy;
10624
+ commonProps.accessibilityDescribedBy = ariaDescribedBy;
10625
+ }
10626
+ if (accessibilityDescribedBy !== void 0) {
10627
+ commonProps.accessibilityDescribedBy = accessibilityDescribedBy;
10628
+ }
10629
+ if (ariaInvalid) {
10630
+ commonProps["aria-invalid"] = true;
10631
+ }
10632
+ if (ariaRequired) {
10633
+ commonProps["aria-required"] = true;
10634
+ }
10092
10635
  if (asChild) {
10093
10636
  const slotProps = {
10094
10637
  role: "switch",
@@ -10455,7 +10998,6 @@ var Tabs = Object.assign(TabsRoot, {
10455
10998
  Trigger: TabsTrigger,
10456
10999
  Content: TabsContent
10457
11000
  });
10458
- var CONTAINER_LAYOUT_BASE4 = { flexDirection: "column" };
10459
11001
  var FIELD_LAYOUT_BASE2 = {
10460
11002
  flexDirection: "row",
10461
11003
  alignItems: "center",
@@ -10466,42 +11008,33 @@ var FIELD_LAYOUT_BASE2 = {
10466
11008
  overflow: "hidden"
10467
11009
  };
10468
11010
  var TextInput = /* @__PURE__ */ __name(({
10469
- label,
10470
- helperText,
10471
- error,
10472
11011
  disabled,
10473
11012
  leading,
10474
11013
  trailing,
10475
11014
  containerClassName,
10476
11015
  className,
10477
11016
  testID,
11017
+ id,
11018
+ name,
10478
11019
  onChangeText,
10479
11020
  multiline,
10480
11021
  numberOfLines,
10481
11022
  ...rest
10482
11023
  }) => {
10483
11024
  const colors = useThemeColors();
10484
- const reactId = React.useId();
10485
- const inputId = testID ?? `nori-ui-input-${reactId}`;
10486
11025
  const inputRef = React.useRef(null);
10487
- const focusInput = /* @__PURE__ */ __name(() => {
10488
- inputRef.current?.focus();
10489
- }, "focusInput");
10490
- const describeId = `${inputId}-describe`;
10491
- const hasError = Boolean(error);
10492
- const describedBy = error || helperText ? describeId : void 0;
11026
+ const restAny = rest;
11027
+ const hasError = restAny["aria-invalid"] === true || restAny["aria-invalid"] === "true";
10493
11028
  const inputExtras = {};
10494
11029
  if (testID !== void 0) {
10495
11030
  inputExtras.testID = testID;
10496
11031
  }
10497
- if (label !== void 0) {
10498
- inputExtras.accessibilityLabel = label;
10499
- }
10500
- if (hasError) {
10501
- inputExtras["aria-invalid"] = true;
11032
+ if (id !== void 0) {
11033
+ inputExtras.id = id;
11034
+ inputExtras.nativeID = id;
10502
11035
  }
10503
- if (describedBy !== void 0) {
10504
- inputExtras["aria-describedby"] = describedBy;
11036
+ if (name !== void 0) {
11037
+ inputExtras.name = name;
10505
11038
  }
10506
11039
  if (multiline !== void 0) {
10507
11040
  inputExtras.multiline = multiline;
@@ -10512,12 +11045,6 @@ var TextInput = /* @__PURE__ */ __name(({
10512
11045
  if (onChangeText !== void 0) {
10513
11046
  inputExtras.onChangeText = onChangeText;
10514
11047
  }
10515
- const labelStyle = {
10516
- fontFamily: colors.fontFamily.body,
10517
- fontSize: px(colors.fontSize.sm),
10518
- fontWeight: colors.fontWeight.medium,
10519
- color: colors.semantic.text.default
10520
- };
10521
11048
  const inputStyle = {
10522
11049
  flex: 1,
10523
11050
  paddingVertical: px(colors.spacing["2"]),
@@ -10525,17 +11052,6 @@ var TextInput = /* @__PURE__ */ __name(({
10525
11052
  fontSize: px(colors.fontSize.md),
10526
11053
  color: colors.semantic.text.default
10527
11054
  };
10528
- const helperStyle = {
10529
- fontFamily: colors.fontFamily.body,
10530
- fontSize: px(colors.fontSize.sm),
10531
- color: colors.semantic.text.muted
10532
- };
10533
- const errorStyle = {
10534
- fontFamily: colors.fontFamily.body,
10535
- fontSize: px(colors.fontSize.sm),
10536
- color: colors.color.danger
10537
- };
10538
- const containerStyle = { ...CONTAINER_LAYOUT_BASE4, gap: px(colors.spacing["1"]) };
10539
11055
  const fieldStyle = [
10540
11056
  FIELD_LAYOUT_BASE2,
10541
11057
  {
@@ -10546,55 +11062,33 @@ var TextInput = /* @__PURE__ */ __name(({
10546
11062
  },
10547
11063
  disabled ? { opacity: 0.6 } : null
10548
11064
  ];
10549
- return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { className: cn("flex flex-col gap-1", containerClassName), style: containerStyle, children: [
10550
- label !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Pressable, { onPress: focusInput, accessibilityRole: "none", disabled, children: /* @__PURE__ */ jsxRuntime.jsx(
10551
- reactNative.Text,
10552
- {
10553
- nativeID: `${inputId}-label`,
10554
- accessibilityRole: "text",
10555
- className: "text-sm font-medium text-semantic-text-default",
10556
- style: labelStyle,
10557
- children: label
10558
- }
10559
- ) }) : null,
10560
- /* @__PURE__ */ jsxRuntime.jsxs(
10561
- reactNative.View,
10562
- {
10563
- className: cn(
10564
- "flex-row items-center rounded-md border px-3",
10565
- hasError ? "border-semantic-interactive-destructive" : "border-semantic-border-default",
10566
- disabled ? "opacity-60" : void 0
11065
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { className: cn(containerClassName), style: { flexDirection: "column" }, children: /* @__PURE__ */ jsxRuntime.jsxs(
11066
+ reactNative.View,
11067
+ {
11068
+ className: cn(
11069
+ "flex-row items-center rounded-md border px-3",
11070
+ hasError ? "border-semantic-interactive-destructive" : "border-semantic-border-default",
11071
+ disabled ? "opacity-60" : void 0
11072
+ ),
11073
+ style: fieldStyle,
11074
+ children: [
11075
+ leading ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { className: "mr-2", style: { marginRight: px(colors.spacing["2"]) }, children: leading }) : null,
11076
+ /* @__PURE__ */ jsxRuntime.jsx(
11077
+ reactNative.TextInput,
11078
+ {
11079
+ ref: inputRef,
11080
+ editable: !disabled,
11081
+ className: cn("flex-1 py-2 text-md text-semantic-text-default outline-none", className),
11082
+ placeholderTextColor: colors.semantic.text.muted,
11083
+ ...inputExtras,
11084
+ ...rest,
11085
+ style: [inputStyle, rest.style]
11086
+ }
10567
11087
  ),
10568
- style: fieldStyle,
10569
- children: [
10570
- leading ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { className: "mr-2", style: { marginRight: px(colors.spacing["2"]) }, children: leading }) : null,
10571
- /* @__PURE__ */ jsxRuntime.jsx(
10572
- reactNative.TextInput,
10573
- {
10574
- ref: inputRef,
10575
- nativeID: inputId,
10576
- editable: !disabled,
10577
- className: cn("flex-1 py-2 text-md text-semantic-text-default outline-none", className),
10578
- placeholderTextColor: colors.semantic.text.muted,
10579
- ...inputExtras,
10580
- ...rest,
10581
- style: [inputStyle, rest.style]
10582
- }
10583
- ),
10584
- trailing ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { className: "ml-2", style: { marginLeft: px(colors.spacing["2"]) }, children: trailing }) : null
10585
- ]
10586
- }
10587
- ),
10588
- error ? /* @__PURE__ */ jsxRuntime.jsx(
10589
- reactNative.Text,
10590
- {
10591
- nativeID: describeId,
10592
- className: "text-sm text-semantic-interactive-destructive",
10593
- style: errorStyle,
10594
- children: error
10595
- }
10596
- ) : helperText ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { nativeID: describeId, className: "text-sm text-semantic-text-muted", style: helperStyle, children: helperText }) : null
10597
- ] });
11088
+ trailing ? /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { className: "ml-2", style: { marginLeft: px(colors.spacing["2"]) }, children: trailing }) : null
11089
+ ]
11090
+ }
11091
+ ) });
10598
11092
  }, "TextInput");
10599
11093
  var TextArea = /* @__PURE__ */ __name(({ numberOfLines = 4, resize = "vertical", style, ...rest }) => {
10600
11094
  const resizeStyle = { resize };
@@ -11798,11 +12292,13 @@ exports.Calendar = Calendar;
11798
12292
  exports.Card = Card;
11799
12293
  exports.Checkbox = Checkbox;
11800
12294
  exports.Dialog = Dialog;
12295
+ exports.Field = Field;
11801
12296
  exports.FloatButton = FloatButton;
11802
12297
  exports.HStack = HStack;
11803
12298
  exports.I18nProvider = I18nProvider;
11804
12299
  exports.Icon = Icon;
11805
12300
  exports.InputGroup = InputGroup;
12301
+ exports.Label = Label;
11806
12302
  exports.LocaleProvider = LocaleProvider;
11807
12303
  exports.NoriProvider = NoriProvider;
11808
12304
  exports.PAGINATION_COMPACT_BREAKPOINT = PAGINATION_COMPACT_BREAKPOINT;