@nori-ui/core 1.1.0 → 1.2.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.
@@ -0,0 +1,58 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { CalendarDate } from '@internationalized/date';
3
+
4
+ type DatePickerProps = {
5
+ value?: CalendarDate | null;
6
+ defaultValue?: CalendarDate | null;
7
+ onChange?: (date: CalendarDate | null) => void;
8
+ /** BCP 47 locale; defaults from NoriProvider's i18n context. */
9
+ locale?: string;
10
+ /** Min/max selectable date. */
11
+ minValue?: CalendarDate;
12
+ maxValue?: CalendarDate;
13
+ /** Custom unavailable predicate. */
14
+ isDateUnavailable?: (date: CalendarDate) => boolean;
15
+ /** First day of week override (0=Sun, 1=Mon, ...). Defaults from locale. */
16
+ firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
17
+ /** Placeholder text shown when no value. */
18
+ placeholder?: string;
19
+ /** Disable the whole picker. */
20
+ disabled?: boolean;
21
+ id?: string;
22
+ name?: string;
23
+ 'aria-labelledby'?: string;
24
+ 'aria-describedby'?: string;
25
+ 'aria-invalid'?: boolean;
26
+ 'aria-required'?: boolean;
27
+ testID?: string;
28
+ className?: string;
29
+ };
30
+ type DateRangeValue = {
31
+ start: CalendarDate | null;
32
+ end: CalendarDate | null;
33
+ };
34
+ type DatePickerRangeProps = {
35
+ value?: DateRangeValue;
36
+ defaultValue?: DateRangeValue;
37
+ onChange?: (range: DateRangeValue) => void;
38
+ locale?: string;
39
+ minValue?: CalendarDate;
40
+ maxValue?: CalendarDate;
41
+ isDateUnavailable?: (date: CalendarDate) => boolean;
42
+ firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
43
+ placeholder?: string;
44
+ disabled?: boolean;
45
+ id?: string;
46
+ name?: string;
47
+ 'aria-labelledby'?: string;
48
+ 'aria-describedby'?: string;
49
+ 'aria-invalid'?: boolean;
50
+ 'aria-required'?: boolean;
51
+ testID?: string;
52
+ className?: string;
53
+ };
54
+ declare const DatePicker: (({ value, defaultValue, onChange, locale: localeProp, minValue, maxValue, isDateUnavailable, firstDayOfWeek, placeholder, disabled, id, name: _name, className, testID, ...ariaProps }: DatePickerProps) => react_jsx_runtime.JSX.Element) & {
55
+ Range: ({ value, defaultValue, onChange, locale: localeProp, minValue, maxValue, isDateUnavailable, firstDayOfWeek, placeholder, disabled, id, name: _name, className, testID, ...ariaProps }: DatePickerRangeProps) => react_jsx_runtime.JSX.Element;
56
+ };
57
+
58
+ export { DatePicker, type DatePickerProps, type DatePickerRangeProps, type DateRangeValue };
@@ -0,0 +1,58 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { CalendarDate } from '@internationalized/date';
3
+
4
+ type DatePickerProps = {
5
+ value?: CalendarDate | null;
6
+ defaultValue?: CalendarDate | null;
7
+ onChange?: (date: CalendarDate | null) => void;
8
+ /** BCP 47 locale; defaults from NoriProvider's i18n context. */
9
+ locale?: string;
10
+ /** Min/max selectable date. */
11
+ minValue?: CalendarDate;
12
+ maxValue?: CalendarDate;
13
+ /** Custom unavailable predicate. */
14
+ isDateUnavailable?: (date: CalendarDate) => boolean;
15
+ /** First day of week override (0=Sun, 1=Mon, ...). Defaults from locale. */
16
+ firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
17
+ /** Placeholder text shown when no value. */
18
+ placeholder?: string;
19
+ /** Disable the whole picker. */
20
+ disabled?: boolean;
21
+ id?: string;
22
+ name?: string;
23
+ 'aria-labelledby'?: string;
24
+ 'aria-describedby'?: string;
25
+ 'aria-invalid'?: boolean;
26
+ 'aria-required'?: boolean;
27
+ testID?: string;
28
+ className?: string;
29
+ };
30
+ type DateRangeValue = {
31
+ start: CalendarDate | null;
32
+ end: CalendarDate | null;
33
+ };
34
+ type DatePickerRangeProps = {
35
+ value?: DateRangeValue;
36
+ defaultValue?: DateRangeValue;
37
+ onChange?: (range: DateRangeValue) => void;
38
+ locale?: string;
39
+ minValue?: CalendarDate;
40
+ maxValue?: CalendarDate;
41
+ isDateUnavailable?: (date: CalendarDate) => boolean;
42
+ firstDayOfWeek?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
43
+ placeholder?: string;
44
+ disabled?: boolean;
45
+ id?: string;
46
+ name?: string;
47
+ 'aria-labelledby'?: string;
48
+ 'aria-describedby'?: string;
49
+ 'aria-invalid'?: boolean;
50
+ 'aria-required'?: boolean;
51
+ testID?: string;
52
+ className?: string;
53
+ };
54
+ declare const DatePicker: (({ value, defaultValue, onChange, locale: localeProp, minValue, maxValue, isDateUnavailable, firstDayOfWeek, placeholder, disabled, id, name: _name, className, testID, ...ariaProps }: DatePickerProps) => react_jsx_runtime.JSX.Element) & {
55
+ Range: ({ value, defaultValue, onChange, locale: localeProp, minValue, maxValue, isDateUnavailable, firstDayOfWeek, placeholder, disabled, id, name: _name, className, testID, ...ariaProps }: DatePickerRangeProps) => react_jsx_runtime.JSX.Element;
56
+ };
57
+
58
+ export { DatePicker, type DatePickerProps, type DatePickerRangeProps, type DateRangeValue };
@@ -0,0 +1,14 @@
1
+ export { DatePicker } from '../../chunk-XBNVKPJN.js';
2
+ import '../../chunk-7D2BHQ6M.js';
3
+ import '../../chunk-HZKXPN6B.js';
4
+ import '../../chunk-UJ5KFRDE.js';
5
+ import '../../chunk-MJ4AGXS7.js';
6
+ import '../../chunk-6PO2IWB3.js';
7
+ import '../../chunk-7Z4NMNX6.js';
8
+ import '../../chunk-ZIBNLXIV.js';
9
+ import '../../chunk-CHXHRJNZ.js';
10
+ import '../../chunk-5A2QOOVN.js';
11
+ import '../../chunk-R5JMDDCB.js';
12
+ import '../../chunk-WCQVDF3K.js';
13
+ //# sourceMappingURL=index.js.map
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
package/dist/index.cjs CHANGED
@@ -6590,6 +6590,334 @@ var Checkbox = /* @__PURE__ */ __name(({
6590
6590
  }
6591
6591
  );
6592
6592
  }, "Checkbox");
6593
+ function formatDate(date$1, locale) {
6594
+ try {
6595
+ return new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(date$1.toDate(date.getLocalTimeZone()));
6596
+ } catch {
6597
+ return `${date$1.year}-${String(date$1.month).padStart(2, "0")}-${String(date$1.day).padStart(2, "0")}`;
6598
+ }
6599
+ }
6600
+ __name(formatDate, "formatDate");
6601
+ function CalendarIcon({ size = 16, color = "currentColor" }) {
6602
+ const colors = useThemeColors();
6603
+ if (reactNative.Platform.OS === "web") {
6604
+ return /* @__PURE__ */ jsxRuntime.jsx(
6605
+ "svg",
6606
+ {
6607
+ width: size,
6608
+ height: size,
6609
+ viewBox: "0 0 24 24",
6610
+ fill: "none",
6611
+ stroke: color,
6612
+ strokeWidth: "2",
6613
+ strokeLinecap: "round",
6614
+ strokeLinejoin: "round",
6615
+ "aria-hidden": "true",
6616
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 2v4M16 2v4M3 10h18M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z" })
6617
+ }
6618
+ );
6619
+ }
6620
+ const resolvedColor = color === "currentColor" ? colors.semantic.text.muted : color;
6621
+ return /* @__PURE__ */ jsxRuntime.jsx(
6622
+ reactNative.Text,
6623
+ {
6624
+ accessibilityElementsHidden: true,
6625
+ importantForAccessibility: "no-hide-descendants",
6626
+ style: { fontSize: size, lineHeight: size, color: resolvedColor },
6627
+ children: "\u{1F4C5}"
6628
+ }
6629
+ );
6630
+ }
6631
+ __name(CalendarIcon, "CalendarIcon");
6632
+ function buildCalendarOptional(minValue, maxValue, isDateUnavailable, firstDayOfWeek) {
6633
+ const out = {};
6634
+ if (minValue !== void 0) {
6635
+ out.minValue = minValue;
6636
+ }
6637
+ if (maxValue !== void 0) {
6638
+ out.maxValue = maxValue;
6639
+ }
6640
+ if (isDateUnavailable !== void 0) {
6641
+ out.isDateUnavailable = isDateUnavailable;
6642
+ }
6643
+ if (firstDayOfWeek !== void 0) {
6644
+ out.firstDayOfWeek = firstDayOfWeek;
6645
+ }
6646
+ return out;
6647
+ }
6648
+ __name(buildCalendarOptional, "buildCalendarOptional");
6649
+ function buildTriggerAriaProps(ariaProps) {
6650
+ const out = {};
6651
+ if (ariaProps["aria-labelledby"] !== void 0) {
6652
+ out["aria-labelledby"] = ariaProps["aria-labelledby"];
6653
+ }
6654
+ if (ariaProps["aria-describedby"] !== void 0) {
6655
+ out["aria-describedby"] = ariaProps["aria-describedby"];
6656
+ }
6657
+ if (ariaProps["aria-invalid"] !== void 0) {
6658
+ out["aria-invalid"] = ariaProps["aria-invalid"];
6659
+ }
6660
+ if (ariaProps["aria-required"] !== void 0) {
6661
+ out["aria-required"] = ariaProps["aria-required"];
6662
+ }
6663
+ return out;
6664
+ }
6665
+ __name(buildTriggerAriaProps, "buildTriggerAriaProps");
6666
+ var DatePickerRoot = /* @__PURE__ */ __name(({
6667
+ value,
6668
+ defaultValue: defaultValue2,
6669
+ onChange,
6670
+ locale: localeProp,
6671
+ minValue,
6672
+ maxValue,
6673
+ isDateUnavailable,
6674
+ firstDayOfWeek,
6675
+ placeholder,
6676
+ disabled = false,
6677
+ id,
6678
+ name: _name,
6679
+ className,
6680
+ testID,
6681
+ ...ariaProps
6682
+ }) => {
6683
+ const providerLocale = useLocale();
6684
+ const locale = localeProp ?? providerLocale;
6685
+ const [open, setOpen] = React.useState(false);
6686
+ const isControlled = value !== void 0;
6687
+ const [inner, setInner] = React.useState(defaultValue2 ?? null);
6688
+ const current = isControlled ? value ?? null : inner;
6689
+ const handleChange = React.useCallback(
6690
+ (date) => {
6691
+ if (!isControlled) {
6692
+ setInner(date);
6693
+ }
6694
+ onChange?.(date);
6695
+ setOpen(false);
6696
+ },
6697
+ [isControlled, onChange]
6698
+ );
6699
+ const handleOpenChange = React.useCallback(
6700
+ (next) => {
6701
+ if (!disabled) {
6702
+ setOpen(next);
6703
+ }
6704
+ },
6705
+ [disabled]
6706
+ );
6707
+ const displayValue = current ? formatDate(current, locale) : null;
6708
+ const calendarOptional = buildCalendarOptional(minValue, maxValue, isDateUnavailable, firstDayOfWeek);
6709
+ const triggerAriaProps = buildTriggerAriaProps(ariaProps);
6710
+ const colors = useThemeColors();
6711
+ const hasError = ariaProps["aria-invalid"] === true || ariaProps["aria-invalid"] === "true";
6712
+ const pressableStyle = {
6713
+ flexDirection: "row",
6714
+ alignItems: "center",
6715
+ borderWidth: 1,
6716
+ borderRadius: px(colors.radius.md),
6717
+ paddingHorizontal: px(colors.spacing["3"]),
6718
+ paddingVertical: px(colors.spacing["2"]),
6719
+ backgroundColor: colors.semantic.background.elevated,
6720
+ borderColor: hasError ? colors.color.danger : colors.semantic.border.default,
6721
+ opacity: disabled ? 0.6 : 1
6722
+ };
6723
+ const textStyle = {
6724
+ flex: 1,
6725
+ fontFamily: colors.fontFamily.body,
6726
+ fontSize: px(colors.fontSize.md),
6727
+ color: displayValue ? colors.semantic.text.default : colors.semantic.text.muted
6728
+ };
6729
+ const triggerExtraProps = {
6730
+ role: "combobox",
6731
+ accessibilityRole: "button",
6732
+ "aria-haspopup": "dialog",
6733
+ "aria-expanded": open,
6734
+ ...triggerAriaProps
6735
+ };
6736
+ if (id !== void 0) {
6737
+ triggerExtraProps.id = id;
6738
+ triggerExtraProps.nativeID = id;
6739
+ }
6740
+ if (testID !== void 0) {
6741
+ triggerExtraProps.testID = testID;
6742
+ }
6743
+ if (hasError) {
6744
+ triggerExtraProps["aria-invalid"] = true;
6745
+ }
6746
+ if (ariaProps["aria-required"]) {
6747
+ triggerExtraProps["aria-required"] = true;
6748
+ }
6749
+ if (disabled) {
6750
+ triggerExtraProps["aria-disabled"] = true;
6751
+ }
6752
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
6753
+ /* @__PURE__ */ jsxRuntime.jsx(Popover.Trigger, { asChild: false, className: cn(className), children: /* @__PURE__ */ jsxRuntime.jsxs(
6754
+ reactNative.Pressable,
6755
+ {
6756
+ onPress: disabled ? void 0 : () => setOpen(!open),
6757
+ disabled,
6758
+ className: cn(
6759
+ "flex-row items-center rounded-md border px-3 py-2",
6760
+ hasError ? "border-semantic-interactive-destructive" : "border-semantic-border-default",
6761
+ disabled ? "opacity-60" : void 0,
6762
+ className
6763
+ ),
6764
+ style: pressableStyle,
6765
+ ...triggerExtraProps,
6766
+ children: [
6767
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: textStyle, numberOfLines: 1, children: displayValue ?? placeholder ?? "" }),
6768
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { marginLeft: px(colors.spacing["2"]) }, children: /* @__PURE__ */ jsxRuntime.jsx(CalendarIcon, { size: 16, color: colors.semantic.text.muted }) })
6769
+ ]
6770
+ }
6771
+ ) }),
6772
+ /* @__PURE__ */ jsxRuntime.jsx(Popover.Content, { "aria-label": "Date picker", side: "bottom", align: "start", children: /* @__PURE__ */ jsxRuntime.jsx(
6773
+ Calendar,
6774
+ {
6775
+ mode: "single",
6776
+ value: current,
6777
+ onChange: (date) => {
6778
+ handleChange(date);
6779
+ },
6780
+ locale,
6781
+ ...calendarOptional
6782
+ }
6783
+ ) })
6784
+ ] });
6785
+ }, "DatePickerRoot");
6786
+ var DatePickerRange = /* @__PURE__ */ __name(({
6787
+ value,
6788
+ defaultValue: defaultValue2,
6789
+ onChange,
6790
+ locale: localeProp,
6791
+ minValue,
6792
+ maxValue,
6793
+ isDateUnavailable,
6794
+ firstDayOfWeek,
6795
+ placeholder,
6796
+ disabled = false,
6797
+ id,
6798
+ name: _name,
6799
+ className,
6800
+ testID,
6801
+ ...ariaProps
6802
+ }) => {
6803
+ const providerLocale = useLocale();
6804
+ const locale = localeProp ?? providerLocale;
6805
+ const [open, setOpen] = React.useState(false);
6806
+ const isControlled = value !== void 0;
6807
+ const [inner, setInner] = React.useState(defaultValue2 ?? { start: null, end: null });
6808
+ const current = isControlled ? value ?? { start: null, end: null } : inner;
6809
+ const calendarValue = current.start !== null ? { start: current.start, end: current.end } : null;
6810
+ const handleChange = React.useCallback(
6811
+ (calRange) => {
6812
+ const next = {
6813
+ start: calRange?.start ?? null,
6814
+ end: calRange?.end ?? null
6815
+ };
6816
+ if (!isControlled) {
6817
+ setInner(next);
6818
+ }
6819
+ onChange?.(next);
6820
+ if (next.start !== null && next.end !== null) {
6821
+ setOpen(false);
6822
+ }
6823
+ },
6824
+ [isControlled, onChange]
6825
+ );
6826
+ const handleOpenChange = React.useCallback(
6827
+ (next) => {
6828
+ if (!disabled) {
6829
+ setOpen(next);
6830
+ }
6831
+ },
6832
+ [disabled]
6833
+ );
6834
+ let displayValue = null;
6835
+ if (current.start !== null) {
6836
+ const startStr = formatDate(current.start, locale);
6837
+ const endStr = current.end !== null ? formatDate(current.end, locale) : "";
6838
+ displayValue = `${startStr} \u2013 ${endStr}`;
6839
+ }
6840
+ const calendarOptional = buildCalendarOptional(minValue, maxValue, isDateUnavailable, firstDayOfWeek);
6841
+ const triggerAriaProps = buildTriggerAriaProps(ariaProps);
6842
+ const colors = useThemeColors();
6843
+ const hasError = ariaProps["aria-invalid"] === true || ariaProps["aria-invalid"] === "true";
6844
+ const pressableStyle = {
6845
+ flexDirection: "row",
6846
+ alignItems: "center",
6847
+ borderWidth: 1,
6848
+ borderRadius: px(colors.radius.md),
6849
+ paddingHorizontal: px(colors.spacing["3"]),
6850
+ paddingVertical: px(colors.spacing["2"]),
6851
+ backgroundColor: colors.semantic.background.elevated,
6852
+ borderColor: hasError ? colors.color.danger : colors.semantic.border.default,
6853
+ opacity: disabled ? 0.6 : 1
6854
+ };
6855
+ const textStyle = {
6856
+ flex: 1,
6857
+ fontFamily: colors.fontFamily.body,
6858
+ fontSize: px(colors.fontSize.md),
6859
+ color: displayValue ? colors.semantic.text.default : colors.semantic.text.muted
6860
+ };
6861
+ const triggerExtraProps = {
6862
+ role: "combobox",
6863
+ accessibilityRole: "button",
6864
+ "aria-haspopup": "dialog",
6865
+ "aria-expanded": open,
6866
+ ...triggerAriaProps
6867
+ };
6868
+ if (id !== void 0) {
6869
+ triggerExtraProps.id = id;
6870
+ triggerExtraProps.nativeID = id;
6871
+ }
6872
+ if (testID !== void 0) {
6873
+ triggerExtraProps.testID = testID;
6874
+ }
6875
+ if (hasError) {
6876
+ triggerExtraProps["aria-invalid"] = true;
6877
+ }
6878
+ if (ariaProps["aria-required"]) {
6879
+ triggerExtraProps["aria-required"] = true;
6880
+ }
6881
+ if (disabled) {
6882
+ triggerExtraProps["aria-disabled"] = true;
6883
+ }
6884
+ return /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: handleOpenChange, children: [
6885
+ /* @__PURE__ */ jsxRuntime.jsx(Popover.Trigger, { asChild: false, className: cn(className), children: /* @__PURE__ */ jsxRuntime.jsxs(
6886
+ reactNative.Pressable,
6887
+ {
6888
+ onPress: disabled ? void 0 : () => setOpen(!open),
6889
+ disabled,
6890
+ className: cn(
6891
+ "flex-row items-center rounded-md border px-3 py-2",
6892
+ hasError ? "border-semantic-interactive-destructive" : "border-semantic-border-default",
6893
+ disabled ? "opacity-60" : void 0,
6894
+ className
6895
+ ),
6896
+ style: pressableStyle,
6897
+ ...triggerExtraProps,
6898
+ children: [
6899
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: textStyle, numberOfLines: 1, children: displayValue ?? placeholder ?? "" }),
6900
+ /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: { marginLeft: px(colors.spacing["2"]) }, children: /* @__PURE__ */ jsxRuntime.jsx(CalendarIcon, { size: 16, color: colors.semantic.text.muted }) })
6901
+ ]
6902
+ }
6903
+ ) }),
6904
+ /* @__PURE__ */ jsxRuntime.jsx(Popover.Content, { "aria-label": "Date range picker", side: "bottom", align: "start", children: /* @__PURE__ */ jsxRuntime.jsx(
6905
+ Calendar,
6906
+ {
6907
+ mode: "range",
6908
+ value: calendarValue,
6909
+ onChange: (range2) => {
6910
+ handleChange(range2);
6911
+ },
6912
+ locale,
6913
+ ...calendarOptional
6914
+ }
6915
+ ) })
6916
+ ] });
6917
+ }, "DatePickerRange");
6918
+ var DatePicker = Object.assign(DatePickerRoot, {
6919
+ Range: DatePickerRange
6920
+ });
6593
6921
  var DialogContext = React.createContext(null);
6594
6922
  var useDialogContext = /* @__PURE__ */ __name((label) => {
6595
6923
  const ctx = React.useContext(DialogContext);
@@ -12133,6 +12461,7 @@ exports.Button = Button;
12133
12461
  exports.Calendar = Calendar;
12134
12462
  exports.Card = Card;
12135
12463
  exports.Checkbox = Checkbox;
12464
+ exports.DatePicker = DatePicker;
12136
12465
  exports.Dialog = Dialog;
12137
12466
  exports.Field = Field;
12138
12467
  exports.FloatButton = FloatButton;