@x12i/ui 0.0.0-stage → 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 x12i
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,144 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
1
+ # @x12i/ui
2
+
3
+ React components for the Unified UI Kit, styled by kit tokens only.
4
+
5
+ Behavior (focus, keyboard, ARIA, positioning) comes from
6
+ [Base UI](https://base-ui.com) (`@base-ui/react`, MIT). The kit adds the tokens,
7
+ the visual design and a consistent API on top. Dates and times use
8
+ [React Aria Components](https://react-spectrum.adobe.com/react-aria/) (Apache-2.0),
9
+ and they load only from the separate `@x12i/ui/date` entry, so an app that does
10
+ not use them does not pay for them.
11
+
12
+ This is a working foundation, not the whole catalog from the product spec.
13
+
14
+ | Family | Components |
15
+ | --- | --- |
16
+ | Actions | `Button`, `IconButton`, `ButtonGroup`, `SplitButton`, `Toggle`, `ToggleGroup`, `Link`, `Kbd`, `CopyButton` |
17
+ | Form controls | `Field`, `Fieldset`, `Input`, `InputGroup`, `PasswordInput`, `Textarea`, `NumberInput`, `Checkbox`, `CheckboxGroup`, `Radio`, `RadioGroup`, `Switch`, `Slider`, `Select`, `Combobox`, `MultiCombobox`, `OTPInput` |
18
+ | Date and time (`@x12i/ui/date`) | `DateField`, `TimeField`, `DatePicker`, `DateRangePicker`, `Calendar`, `RangeCalendar`, `LocaleProvider` |
19
+ | Feedback and status | `Alert`, `Callout`, `Badge`, `Progress`, `ProgressCircle`, `Meter`, `Skeleton`, `EmptyState`, `Spinner`, `ToastProvider` and `useToast` |
20
+ | Data display | `Card`, `Avatar`, `AvatarGroup`, `Tag`, `Stat`, `AnimatedNumber`, `Table`, `ScrollArea`, `Collapsible` |
21
+ | Navigation | `Tabs`, `Breadcrumb`, `Pagination`, `Accordion`, `SegmentedControl`, `Stepper`, `Toolbar` |
22
+ | Overlays | `Dialog`, `AlertDialog`, `Drawer`, `Popover`, `Tooltip`, `Menu`, `ContextMenu` |
23
+ | Layout | `Stack`, `Inline`, `Divider` |
24
+ | Utilities | `VisuallyHidden`, `ThemeProvider`, `DensityProvider` |
25
+
26
+ ## Install
27
+
28
+ ```sh
29
+ pnpm add @x12i/ui @x12i/themes react react-dom
30
+ ```
31
+
32
+ ```css
33
+ @import "@x12i/themes/themes.css";
34
+ @import "@x12i/ui/styles.css";
35
+ ```
36
+
37
+ ```tsx
38
+ import { Button, Stack, ThemeProvider } from "@x12i/ui";
39
+
40
+ export function App() {
41
+ return (
42
+ <ThemeProvider scope="root">
43
+ <Stack gap="4">
44
+ <Button>Save</Button>
45
+ <Button variant="outline" tone="neutral">
46
+ Cancel
47
+ </Button>
48
+ </Stack>
49
+ </ThemeProvider>
50
+ );
51
+ }
52
+ ```
53
+
54
+ ## A small form
55
+
56
+ ```tsx
57
+ import { Button, Field, Input, ToastProvider, useToast } from "@x12i/ui";
58
+
59
+ function Rename() {
60
+ const toast = useToast();
61
+ return (
62
+ <>
63
+ <Field label="Project name" description="Everyone on the team sees it.">
64
+ <Input defaultValue="Apollo" />
65
+ </Field>
66
+ <Button onClick={() => toast.show({ tone: "success", title: "Renamed" })}>Save</Button>
67
+ </>
68
+ );
69
+ }
70
+
71
+ export const App = () => (
72
+ <ToastProvider closeLabel="Dismiss notification" regionLabel="Notifications">
73
+ <Rename />
74
+ </ToastProvider>
75
+ );
76
+ ```
77
+
78
+ Every label, hint and error is a prop you pass, so translating the app never
79
+ means patching the kit.
80
+
81
+ ## Dates and times
82
+
83
+ ```tsx
84
+ import { DatePicker, LocaleProvider, parseDate } from "@x12i/ui/date";
85
+
86
+ <LocaleProvider locale="de-DE">
87
+ <DatePicker label="Anreise" defaultValue={parseDate("2026-12-01")} />
88
+ </LocaleProvider>;
89
+ ```
90
+
91
+ The order of day, month and year, the month and weekday names, the numerals and
92
+ the first day of the week follow the locale. The entry re-exports the date value
93
+ helpers (`parseDate`, `today`, `CalendarDate`, ...), so you do not install
94
+ `@internationalized/date` yourself.
95
+
96
+ ## Conventions
97
+
98
+ - **Tokens only.** A lint rule and a test ban hard-coded colors, spacing and font
99
+ sizes in components and in `styles.css`.
100
+ - **Zero specificity.** Every selector in `styles.css` sits inside `:where()`, so
101
+ your own classes always win.
102
+ - **Styling hooks are data attributes**: `data-variant`, `data-tone`, `data-size`,
103
+ `data-loading`, `data-disabled`, plus the state attributes of the behavior layer
104
+ (`data-open`, `data-checked`, `data-selected`, ...). Internal class names are not
105
+ a public API.
106
+ - **No user-facing strings.** Anything announced to assistive technology, such as
107
+ `Spinner`'s `label`, `IconButton`'s `label`, a dialog's `closeLabel` or a
108
+ pagination's `getPageLabel`, is passed in by the app. TypeScript requires the
109
+ ones a screen reader would otherwise miss.
110
+ - **`render` and `asChild`** put your element in place of the default one while
111
+ keeping the component's behavior and styling:
112
+ `<DialogTrigger render={<Button />}>Open</DialogTrigger>`,
113
+ `<Button asChild><a href="/docs">Docs</a></Button>`.
114
+ - **Density** follows `data-density`, so the same components fit compact tables
115
+ and comfortable forms.
116
+ - **Logical CSS properties** keep right-to-left layouts working without a second
117
+ stylesheet. Drawers, submenus, tab indicators and the calendar mirror by themselves.
118
+ - **Server rendering.** The bundles are marked `"use client"`. Providers read
119
+ storage after mount, so server and client first renders agree.
120
+
121
+ ## Theme and density
122
+
123
+ ```tsx
124
+ <ThemeProvider scope="root" defaultTheme="system">
125
+ <DensityProvider scope="root">{children}</DensityProvider>
126
+ </ThemeProvider>
127
+ ```
128
+
129
+ `scope="root"` sets the attribute on `<html>` and remembers the choice. The
130
+ default `scope="subtree"` wraps its children, so one region can differ from the
131
+ page. An explicit theme on a subtree paints its own surface.
132
+
133
+ Pair a `root` provider with `getNoFlashScript()` from `@x12i/themes` to avoid a
134
+ flash of the wrong theme on first paint.
135
+
136
+ ## Try it
137
+
138
+ `apps/playground` in this repository shows every component in every theme and
139
+ density, in left-to-right and right-to-left. Run `pnpm --filter @x12i/playground dev`.
140
+
141
+ ## Status
142
+
143
+ `@x12i/ui` ships as an npm build today. Registry distribution (installing
144
+ components as source with the CLI) is planned in the spec but not built yet.
package/dist/date.d.ts ADDED
@@ -0,0 +1,69 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+ import { DateValue, CalendarProps as CalendarProps$1, RangeCalendarProps as RangeCalendarProps$1, DateFieldProps as DateFieldProps$1, ValidationResult, TimeValue, TimeFieldProps as TimeFieldProps$1, DatePickerProps as DatePickerProps$1, DateRangePickerProps as DateRangePickerProps$1 } from 'react-aria-components';
4
+ export { DateRange, DateValue, I18nProvider as LocaleProvider, TimeValue, ValidationResult } from 'react-aria-components';
5
+ import { ControlSize } from './index.js';
6
+ export { CalendarDate, CalendarDateTime, DateDuration, Time, ZonedDateTime, getLocalTimeZone, now, parseDate, parseDateTime, parseTime, parseZonedDateTime, today } from '@internationalized/date';
7
+
8
+ type OwnProps$2 = "children" | "className" | "style" | "aria-label";
9
+ interface CalendarProps<T extends DateValue> extends Omit<CalendarProps$1<T>, OwnProps$2> {
10
+ /** Name of the calendar, for example "Appointment date". Pass a translated string. */
11
+ "aria-label": string;
12
+ }
13
+ interface RangeCalendarProps<T extends DateValue> extends Omit<RangeCalendarProps$1<T>, OwnProps$2> {
14
+ /** Name of the calendar, for example "Trip dates". Pass a translated string. */
15
+ "aria-label": string;
16
+ }
17
+ /**
18
+ * A month grid for picking one date. Arrow keys move by day and week, Page
19
+ * Up/Down by month, Home/End to the start and end of the week. Dates are
20
+ * `@internationalized/date` values (`CalendarDate`, `parseDate`, `today`), so
21
+ * calendar systems, locales and time zones are handled by the library.
22
+ */
23
+ declare function Calendar<T extends DateValue>(props: CalendarProps<T>): react.JSX.Element;
24
+ /** A month grid for picking a start and an end date. */
25
+ declare function RangeCalendar<T extends DateValue>(props: RangeCalendarProps<T>): react.JSX.Element;
26
+
27
+ type OwnProps$1 = "children" | "className" | "style";
28
+ /** The label, help text and error shared by every date and time field. */
29
+ interface DateFieldChrome {
30
+ /** The visible label. It names the field for assistive technology. */
31
+ label: ReactNode;
32
+ /** Help text under the label, announced with the field. */
33
+ description?: ReactNode;
34
+ /**
35
+ * Shown when the value is invalid (out of range, unavailable, or rejected
36
+ * by `validate`). A function receives the validation result.
37
+ */
38
+ errorMessage?: ReactNode | ((validation: ValidationResult) => ReactNode);
39
+ size?: ControlSize;
40
+ }
41
+ interface DateFieldProps<T extends DateValue> extends Omit<DateFieldProps$1<T>, OwnProps$1 | "label">, DateFieldChrome {
42
+ }
43
+ /**
44
+ * A date typed into segments (day, month, year in the locale's order). Arrow
45
+ * keys step a segment, digits fill it and move on. Pair it with a `Calendar`
46
+ * or use `DatePicker` for both.
47
+ */
48
+ declare function DateField<T extends DateValue>({ label, description, errorMessage, size, ...props }: DateFieldProps<T>): react.JSX.Element;
49
+ interface TimeFieldProps<T extends TimeValue> extends Omit<TimeFieldProps$1<T>, OwnProps$1 | "label">, DateFieldChrome {
50
+ }
51
+ /** A time typed into segments (hour, minute, optional second and day period). */
52
+ declare function TimeField<T extends TimeValue>({ label, description, errorMessage, size, ...props }: TimeFieldProps<T>): react.JSX.Element;
53
+
54
+ type OwnProps = "children" | "className" | "style";
55
+ interface DatePickerProps<T extends DateValue> extends Omit<DatePickerProps$1<T>, OwnProps | "label">, DateFieldChrome {
56
+ }
57
+ /**
58
+ * A date field with a calendar popover. Type the date into the segments or
59
+ * open the calendar from the button; both stay in sync. The calendar button
60
+ * is named by the library in the user's language.
61
+ */
62
+ declare function DatePicker<T extends DateValue>({ label, description, errorMessage, size, ...props }: DatePickerProps<T>): react.JSX.Element;
63
+ interface DateRangePickerProps<T extends DateValue> extends Omit<DateRangePickerProps$1<T>, OwnProps | "label">, DateFieldChrome {
64
+ }
65
+ /** Two date fields (start and end) with one range calendar popover. */
66
+ declare function DateRangePicker<T extends DateValue>({ label, description, errorMessage, size, ...props }: DateRangePickerProps<T>): react.JSX.Element;
67
+
68
+ export { Calendar, DateField, DatePicker, DateRangePicker, RangeCalendar, TimeField };
69
+ export type { CalendarProps, DateFieldChrome, DateFieldProps, DatePickerProps, DateRangePickerProps, RangeCalendarProps, TimeFieldProps };
package/dist/date.js ADDED
@@ -0,0 +1,223 @@
1
+ "use client";
2
+
3
+ // src/date/calendar.tsx
4
+ import { Icon } from "@x12i/icons";
5
+ import {
6
+ Button as AriaButton,
7
+ Calendar as AriaCalendar,
8
+ CalendarCell,
9
+ CalendarGrid,
10
+ CalendarGridBody,
11
+ CalendarGridHeader,
12
+ CalendarHeaderCell,
13
+ Heading,
14
+ RangeCalendar as AriaRangeCalendar
15
+ } from "react-aria-components";
16
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
17
+ function NavButton({ slot, icon }) {
18
+ return /* @__PURE__ */ jsx(
19
+ AriaButton,
20
+ {
21
+ slot,
22
+ "data-kit": "button",
23
+ "data-variant": "ghost",
24
+ "data-tone": "neutral",
25
+ "data-size": "sm",
26
+ "data-icon-only": "",
27
+ "data-kit-slot": "calendar-nav",
28
+ children: /* @__PURE__ */ jsx("span", { "data-kit-slot": "content", children: /* @__PURE__ */ jsx(Icon, { name: icon }) })
29
+ }
30
+ );
31
+ }
32
+ function CalendarContents() {
33
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
34
+ /* @__PURE__ */ jsxs("div", { "data-kit-slot": "calendar-header", children: [
35
+ /* @__PURE__ */ jsx(NavButton, { slot: "previous", icon: "chevron-left" }),
36
+ /* @__PURE__ */ jsx(Heading, { "data-kit-slot": "calendar-heading" }),
37
+ /* @__PURE__ */ jsx(NavButton, { slot: "next", icon: "chevron-right" })
38
+ ] }),
39
+ /* @__PURE__ */ jsxs(CalendarGrid, { "data-kit-slot": "calendar-grid", children: [
40
+ /* @__PURE__ */ jsx(CalendarGridHeader, { children: (day) => /* @__PURE__ */ jsx(CalendarHeaderCell, { "data-kit-slot": "calendar-weekday", children: day }) }),
41
+ /* @__PURE__ */ jsx(CalendarGridBody, { children: (date) => /* @__PURE__ */ jsx(CalendarCell, { date, "data-kit-slot": "calendar-cell", children: ({ formattedDate }) => /* @__PURE__ */ jsx("span", { "data-kit-slot": "calendar-day", children: formattedDate }) }) })
42
+ ] })
43
+ ] });
44
+ }
45
+ function PickerCalendar() {
46
+ return /* @__PURE__ */ jsx(AriaCalendar, { "data-kit": "calendar", children: /* @__PURE__ */ jsx(CalendarContents, {}) });
47
+ }
48
+ function PickerRangeCalendar() {
49
+ return /* @__PURE__ */ jsx(AriaRangeCalendar, { "data-kit": "calendar", "data-range": "", children: /* @__PURE__ */ jsx(CalendarContents, {}) });
50
+ }
51
+ function Calendar(props) {
52
+ return /* @__PURE__ */ jsx(AriaCalendar, { "data-kit": "calendar", ...props, children: /* @__PURE__ */ jsx(CalendarContents, {}) });
53
+ }
54
+ function RangeCalendar(props) {
55
+ return /* @__PURE__ */ jsx(AriaRangeCalendar, { "data-kit": "calendar", "data-range": "", ...props, children: /* @__PURE__ */ jsx(CalendarContents, {}) });
56
+ }
57
+
58
+ // src/date/date-field.tsx
59
+ import {
60
+ DateField as AriaDateField,
61
+ DateInput,
62
+ DateSegment,
63
+ FieldError,
64
+ Label,
65
+ Text,
66
+ TimeField as AriaTimeField
67
+ } from "react-aria-components";
68
+ import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
69
+ function DateSegments({
70
+ size,
71
+ bare = false,
72
+ slot
73
+ }) {
74
+ return /* @__PURE__ */ jsx2(
75
+ DateInput,
76
+ {
77
+ slot,
78
+ "data-kit": bare ? void 0 : "input-group",
79
+ "data-kit-slot": "date-segments",
80
+ "data-size": bare ? void 0 : size,
81
+ children: (segment) => /* @__PURE__ */ jsx2(DateSegment, { segment, "data-kit-slot": "date-segment" })
82
+ }
83
+ );
84
+ }
85
+ function FieldLabel({ children, required }) {
86
+ return /* @__PURE__ */ jsxs2(Label, { "data-kit-slot": "field-label", children: [
87
+ children,
88
+ required ? /* @__PURE__ */ jsx2("span", { "aria-hidden": "true", "data-kit-slot": "field-required", children: "*" }) : null
89
+ ] });
90
+ }
91
+ function FieldFooter({
92
+ description,
93
+ errorMessage
94
+ }) {
95
+ return /* @__PURE__ */ jsxs2(Fragment2, { children: [
96
+ description ? /* @__PURE__ */ jsx2(Text, { slot: "description", "data-kit-slot": "field-description", children: description }) : null,
97
+ /* @__PURE__ */ jsx2(FieldError, { "data-kit-slot": "field-error", children: errorMessage })
98
+ ] });
99
+ }
100
+ function DateField({
101
+ label,
102
+ description,
103
+ errorMessage,
104
+ size = "md",
105
+ ...props
106
+ }) {
107
+ return /* @__PURE__ */ jsxs2(AriaDateField, { "data-kit": "field", ...props, children: [
108
+ /* @__PURE__ */ jsx2(FieldLabel, { required: props.isRequired, children: label }),
109
+ /* @__PURE__ */ jsx2(DateSegments, { size }),
110
+ /* @__PURE__ */ jsx2(FieldFooter, { description, errorMessage })
111
+ ] });
112
+ }
113
+ function TimeField({
114
+ label,
115
+ description,
116
+ errorMessage,
117
+ size = "md",
118
+ ...props
119
+ }) {
120
+ return /* @__PURE__ */ jsxs2(AriaTimeField, { "data-kit": "field", ...props, children: [
121
+ /* @__PURE__ */ jsx2(FieldLabel, { required: props.isRequired, children: label }),
122
+ /* @__PURE__ */ jsx2(DateSegments, { size }),
123
+ /* @__PURE__ */ jsx2(FieldFooter, { description, errorMessage })
124
+ ] });
125
+ }
126
+
127
+ // src/date/date-picker.tsx
128
+ import { Icon as Icon2 } from "@x12i/icons";
129
+ import {
130
+ Button as AriaButton2,
131
+ DatePicker as AriaDatePicker,
132
+ DateRangePicker as AriaDateRangePicker,
133
+ Dialog,
134
+ Group,
135
+ Popover
136
+ } from "react-aria-components";
137
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
138
+ function CalendarButton() {
139
+ return /* @__PURE__ */ jsx3(
140
+ AriaButton2,
141
+ {
142
+ "data-kit": "button",
143
+ "data-variant": "ghost",
144
+ "data-tone": "neutral",
145
+ "data-size": "xs",
146
+ "data-icon-only": "",
147
+ children: /* @__PURE__ */ jsx3("span", { "data-kit-slot": "content", children: /* @__PURE__ */ jsx3(Icon2, { name: "calendar" }) })
148
+ }
149
+ );
150
+ }
151
+ function DatePicker({
152
+ label,
153
+ description,
154
+ errorMessage,
155
+ size = "md",
156
+ ...props
157
+ }) {
158
+ return /* @__PURE__ */ jsxs3(AriaDatePicker, { "data-kit": "field", ...props, children: [
159
+ /* @__PURE__ */ jsx3(FieldLabel, { required: props.isRequired, children: label }),
160
+ /* @__PURE__ */ jsxs3(Group, { "data-kit": "input-group", "data-size": size, children: [
161
+ /* @__PURE__ */ jsx3(DateSegments, { size, bare: true }),
162
+ /* @__PURE__ */ jsx3(CalendarButton, {})
163
+ ] }),
164
+ /* @__PURE__ */ jsx3(FieldFooter, { description, errorMessage }),
165
+ /* @__PURE__ */ jsx3(Popover, { "data-kit": "date-popover", placement: "bottom start", offset: 4, children: /* @__PURE__ */ jsx3(Dialog, { "data-kit-slot": "date-dialog", children: /* @__PURE__ */ jsx3(PickerCalendar, {}) }) })
166
+ ] });
167
+ }
168
+ function DateRangePicker({
169
+ label,
170
+ description,
171
+ errorMessage,
172
+ size = "md",
173
+ ...props
174
+ }) {
175
+ return /* @__PURE__ */ jsxs3(AriaDateRangePicker, { "data-kit": "field", ...props, children: [
176
+ /* @__PURE__ */ jsx3(FieldLabel, { required: props.isRequired, children: label }),
177
+ /* @__PURE__ */ jsxs3(Group, { "data-kit": "input-group", "data-size": size, children: [
178
+ /* @__PURE__ */ jsx3(DateSegments, { size, bare: true, slot: "start" }),
179
+ /* @__PURE__ */ jsx3("span", { "aria-hidden": "true", "data-kit-slot": "date-range-separator", children: "\u2013" }),
180
+ /* @__PURE__ */ jsx3(DateSegments, { size, bare: true, slot: "end" }),
181
+ /* @__PURE__ */ jsx3(CalendarButton, {})
182
+ ] }),
183
+ /* @__PURE__ */ jsx3(FieldFooter, { description, errorMessage }),
184
+ /* @__PURE__ */ jsx3(Popover, { "data-kit": "date-popover", placement: "bottom start", offset: 4, children: /* @__PURE__ */ jsx3(Dialog, { "data-kit-slot": "date-dialog", children: /* @__PURE__ */ jsx3(PickerRangeCalendar, {}) }) })
185
+ ] });
186
+ }
187
+
188
+ // src/date.ts
189
+ import {
190
+ CalendarDate,
191
+ CalendarDateTime,
192
+ Time,
193
+ ZonedDateTime,
194
+ getLocalTimeZone,
195
+ now,
196
+ parseDate,
197
+ parseDateTime,
198
+ parseTime,
199
+ parseZonedDateTime,
200
+ today
201
+ } from "@internationalized/date";
202
+ import { I18nProvider } from "react-aria-components";
203
+ export {
204
+ Calendar,
205
+ CalendarDate,
206
+ CalendarDateTime,
207
+ DateField,
208
+ DatePicker,
209
+ DateRangePicker,
210
+ I18nProvider as LocaleProvider,
211
+ RangeCalendar,
212
+ Time,
213
+ TimeField,
214
+ ZonedDateTime,
215
+ getLocalTimeZone,
216
+ now,
217
+ parseDate,
218
+ parseDateTime,
219
+ parseTime,
220
+ parseZonedDateTime,
221
+ today
222
+ };
223
+ //# sourceMappingURL=date.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/date/calendar.tsx","../src/date/date-field.tsx","../src/date/date-picker.tsx","../src/date.ts"],"sourcesContent":["import { Icon } from \"@x12i/icons\";\nimport {\n Button as AriaButton,\n Calendar as AriaCalendar,\n CalendarCell,\n CalendarGrid,\n CalendarGridBody,\n CalendarGridHeader,\n CalendarHeaderCell,\n type CalendarProps as AriaCalendarProps,\n type DateValue,\n Heading,\n RangeCalendar as AriaRangeCalendar,\n type RangeCalendarProps as AriaRangeCalendarProps,\n} from \"react-aria-components\";\n\ntype OwnProps = \"children\" | \"className\" | \"style\" | \"aria-label\";\n\nexport interface CalendarProps<T extends DateValue> extends Omit<AriaCalendarProps<T>, OwnProps> {\n /** Name of the calendar, for example \"Appointment date\". Pass a translated string. */\n \"aria-label\": string;\n}\n\nexport interface RangeCalendarProps<T extends DateValue> extends Omit<AriaRangeCalendarProps<T>, OwnProps> {\n /** Name of the calendar, for example \"Trip dates\". Pass a translated string. */\n \"aria-label\": string;\n}\n\n/**\n * The previous and next month buttons. They are React Aria buttons, so they\n * receive their localized names (\"Previous\", \"Next\") and disabled state from\n * the calendar, and look like a ghost icon `Button`.\n */\nfunction NavButton({ slot, icon }: { slot: \"previous\" | \"next\"; icon: \"chevron-left\" | \"chevron-right\" }) {\n return (\n <AriaButton\n slot={slot}\n data-kit=\"button\"\n data-variant=\"ghost\"\n data-tone=\"neutral\"\n data-size=\"sm\"\n data-icon-only=\"\"\n data-kit-slot=\"calendar-nav\"\n >\n <span data-kit-slot=\"content\">\n <Icon name={icon} />\n </span>\n </AriaButton>\n );\n}\n\n/** Header, weekday row and day grid shared by single and range calendars. */\nexport function CalendarContents() {\n return (\n <>\n {/* A div, not a header: inside a landmark a header would become a nested banner. */}\n <div data-kit-slot=\"calendar-header\">\n <NavButton slot=\"previous\" icon=\"chevron-left\" />\n <Heading data-kit-slot=\"calendar-heading\" />\n <NavButton slot=\"next\" icon=\"chevron-right\" />\n </div>\n <CalendarGrid data-kit-slot=\"calendar-grid\">\n <CalendarGridHeader>\n {(day) => <CalendarHeaderCell data-kit-slot=\"calendar-weekday\">{day}</CalendarHeaderCell>}\n </CalendarGridHeader>\n <CalendarGridBody>\n {(date) => (\n <CalendarCell date={date} data-kit-slot=\"calendar-cell\">\n {({ formattedDate }) => <span data-kit-slot=\"calendar-day\">{formattedDate}</span>}\n </CalendarCell>\n )}\n </CalendarGridBody>\n </CalendarGrid>\n </>\n );\n}\n\n/**\n * The calendars inside `DatePicker` and `DateRangePicker`. The picker supplies\n * their name and value through context, so they take no props.\n */\nexport function PickerCalendar() {\n return (\n <AriaCalendar data-kit=\"calendar\">\n <CalendarContents />\n </AriaCalendar>\n );\n}\n\nexport function PickerRangeCalendar() {\n return (\n <AriaRangeCalendar data-kit=\"calendar\" data-range=\"\">\n <CalendarContents />\n </AriaRangeCalendar>\n );\n}\n\n/**\n * A month grid for picking one date. Arrow keys move by day and week, Page\n * Up/Down by month, Home/End to the start and end of the week. Dates are\n * `@internationalized/date` values (`CalendarDate`, `parseDate`, `today`), so\n * calendar systems, locales and time zones are handled by the library.\n */\nexport function Calendar<T extends DateValue>(props: CalendarProps<T>) {\n return (\n <AriaCalendar data-kit=\"calendar\" {...props}>\n <CalendarContents />\n </AriaCalendar>\n );\n}\n\n/** A month grid for picking a start and an end date. */\nexport function RangeCalendar<T extends DateValue>(props: RangeCalendarProps<T>) {\n return (\n <AriaRangeCalendar data-kit=\"calendar\" data-range=\"\" {...props}>\n <CalendarContents />\n </AriaRangeCalendar>\n );\n}\n","import type { ReactNode } from \"react\";\nimport {\n DateField as AriaDateField,\n type DateFieldProps as AriaDateFieldProps,\n DateInput,\n DateSegment,\n type DateValue,\n FieldError,\n Label,\n Text,\n TimeField as AriaTimeField,\n type TimeFieldProps as AriaTimeFieldProps,\n type TimeValue,\n type ValidationResult,\n} from \"react-aria-components\";\nimport type { ControlSize } from \"../types\";\n\ntype OwnProps = \"children\" | \"className\" | \"style\";\n\n/** The label, help text and error shared by every date and time field. */\nexport interface DateFieldChrome {\n /** The visible label. It names the field for assistive technology. */\n label: ReactNode;\n /** Help text under the label, announced with the field. */\n description?: ReactNode;\n /**\n * Shown when the value is invalid (out of range, unavailable, or rejected\n * by `validate`). A function receives the validation result.\n */\n errorMessage?: ReactNode | ((validation: ValidationResult) => ReactNode);\n size?: ControlSize;\n}\n\n/** The editable year, month, day, hour... segments. Each one is a spin button. */\nexport function DateSegments({\n size,\n bare = false,\n slot,\n}: {\n size: ControlSize;\n /** Inside a picker the surrounding group draws the border, so the segments go bare. */\n bare?: boolean;\n /** `start` or `end` inside a range picker. */\n slot?: \"start\" | \"end\";\n}) {\n return (\n <DateInput\n slot={slot}\n data-kit={bare ? undefined : \"input-group\"}\n data-kit-slot=\"date-segments\"\n data-size={bare ? undefined : size}\n >\n {(segment) => <DateSegment segment={segment} data-kit-slot=\"date-segment\" />}\n </DateInput>\n );\n}\n\nexport function FieldLabel({ children, required }: { children: ReactNode; required?: boolean }) {\n return (\n <Label data-kit-slot=\"field-label\">\n {children}\n {required ? (\n <span aria-hidden=\"true\" data-kit-slot=\"field-required\">\n *\n </span>\n ) : null}\n </Label>\n );\n}\n\nexport function FieldFooter({\n description,\n errorMessage,\n}: Pick<DateFieldChrome, \"description\" | \"errorMessage\">) {\n return (\n <>\n {description ? (\n <Text slot=\"description\" data-kit-slot=\"field-description\">\n {description}\n </Text>\n ) : null}\n <FieldError data-kit-slot=\"field-error\">{errorMessage}</FieldError>\n </>\n );\n}\n\nexport interface DateFieldProps<T extends DateValue>\n extends Omit<AriaDateFieldProps<T>, OwnProps | \"label\">,\n DateFieldChrome {}\n\n/**\n * A date typed into segments (day, month, year in the locale's order). Arrow\n * keys step a segment, digits fill it and move on. Pair it with a `Calendar`\n * or use `DatePicker` for both.\n */\nexport function DateField<T extends DateValue>({\n label,\n description,\n errorMessage,\n size = \"md\",\n ...props\n}: DateFieldProps<T>) {\n return (\n <AriaDateField data-kit=\"field\" {...props}>\n <FieldLabel required={props.isRequired}>{label}</FieldLabel>\n <DateSegments size={size} />\n <FieldFooter description={description} errorMessage={errorMessage} />\n </AriaDateField>\n );\n}\n\nexport interface TimeFieldProps<T extends TimeValue>\n extends Omit<AriaTimeFieldProps<T>, OwnProps | \"label\">,\n DateFieldChrome {}\n\n/** A time typed into segments (hour, minute, optional second and day period). */\nexport function TimeField<T extends TimeValue>({\n label,\n description,\n errorMessage,\n size = \"md\",\n ...props\n}: TimeFieldProps<T>) {\n return (\n <AriaTimeField data-kit=\"field\" {...props}>\n <FieldLabel required={props.isRequired}>{label}</FieldLabel>\n <DateSegments size={size} />\n <FieldFooter description={description} errorMessage={errorMessage} />\n </AriaTimeField>\n );\n}\n","import { Icon } from \"@x12i/icons\";\nimport {\n Button as AriaButton,\n DatePicker as AriaDatePicker,\n type DatePickerProps as AriaDatePickerProps,\n DateRangePicker as AriaDateRangePicker,\n type DateRangePickerProps as AriaDateRangePickerProps,\n type DateValue,\n Dialog,\n Group,\n Popover,\n} from \"react-aria-components\";\nimport { PickerCalendar, PickerRangeCalendar } from \"./calendar\";\nimport { type DateFieldChrome, DateSegments, FieldFooter, FieldLabel } from \"./date-field\";\n\ntype OwnProps = \"children\" | \"className\" | \"style\";\n\n/** The button that opens the calendar. React Aria names it and wires it to the popover. */\nfunction CalendarButton() {\n return (\n <AriaButton\n data-kit=\"button\"\n data-variant=\"ghost\"\n data-tone=\"neutral\"\n data-size=\"xs\"\n data-icon-only=\"\"\n >\n <span data-kit-slot=\"content\">\n <Icon name=\"calendar\" />\n </span>\n </AriaButton>\n );\n}\n\nexport interface DatePickerProps<T extends DateValue>\n extends Omit<AriaDatePickerProps<T>, OwnProps | \"label\">,\n DateFieldChrome {}\n\n/**\n * A date field with a calendar popover. Type the date into the segments or\n * open the calendar from the button; both stay in sync. The calendar button\n * is named by the library in the user's language.\n */\nexport function DatePicker<T extends DateValue>({\n label,\n description,\n errorMessage,\n size = \"md\",\n ...props\n}: DatePickerProps<T>) {\n return (\n <AriaDatePicker data-kit=\"field\" {...props}>\n <FieldLabel required={props.isRequired}>{label}</FieldLabel>\n <Group data-kit=\"input-group\" data-size={size}>\n <DateSegments size={size} bare />\n <CalendarButton />\n </Group>\n <FieldFooter description={description} errorMessage={errorMessage} />\n <Popover data-kit=\"date-popover\" placement=\"bottom start\" offset={4}>\n <Dialog data-kit-slot=\"date-dialog\">\n <PickerCalendar />\n </Dialog>\n </Popover>\n </AriaDatePicker>\n );\n}\n\nexport interface DateRangePickerProps<T extends DateValue>\n extends Omit<AriaDateRangePickerProps<T>, OwnProps | \"label\">,\n DateFieldChrome {}\n\n/** Two date fields (start and end) with one range calendar popover. */\nexport function DateRangePicker<T extends DateValue>({\n label,\n description,\n errorMessage,\n size = \"md\",\n ...props\n}: DateRangePickerProps<T>) {\n return (\n <AriaDateRangePicker data-kit=\"field\" {...props}>\n <FieldLabel required={props.isRequired}>{label}</FieldLabel>\n <Group data-kit=\"input-group\" data-size={size}>\n <DateSegments size={size} bare slot=\"start\" />\n <span aria-hidden=\"true\" data-kit-slot=\"date-range-separator\">\n –\n </span>\n <DateSegments size={size} bare slot=\"end\" />\n <CalendarButton />\n </Group>\n <FieldFooter description={description} errorMessage={errorMessage} />\n <Popover data-kit=\"date-popover\" placement=\"bottom start\" offset={4}>\n <Dialog data-kit-slot=\"date-dialog\">\n <PickerRangeCalendar />\n </Dialog>\n </Popover>\n </AriaDateRangePicker>\n );\n}\n","/**\n * Date and time components: `@x12i/ui/date`.\n *\n * Kept in its own entry because it is built on React Aria Components and\n * `@internationalized/date`, which add real weight. Apps that never show a\n * calendar do not pay for them.\n *\n * Dates are `@internationalized/date` values (`CalendarDate`, `Time`...), not\n * JavaScript `Date`s, so calendar systems, locales and time zones are handled\n * correctly. The library localizes its own built-in labels (\"Previous month\",\n * \"Calendar\"); set the locale with `LocaleProvider`.\n */\nexport { Calendar, RangeCalendar } from \"./date/calendar\";\nexport type { CalendarProps, RangeCalendarProps } from \"./date/calendar\";\nexport { DateField, TimeField } from \"./date/date-field\";\nexport type { DateFieldChrome, DateFieldProps, TimeFieldProps } from \"./date/date-field\";\nexport { DatePicker, DateRangePicker } from \"./date/date-picker\";\nexport type { DatePickerProps, DateRangePickerProps } from \"./date/date-picker\";\n\nexport {\n CalendarDate,\n CalendarDateTime,\n Time,\n ZonedDateTime,\n getLocalTimeZone,\n now,\n parseDate,\n parseDateTime,\n parseTime,\n parseZonedDateTime,\n today,\n} from \"@internationalized/date\";\nexport type { DateDuration } from \"@internationalized/date\";\nexport { I18nProvider as LocaleProvider } from \"react-aria-components\";\nexport type { DateRange, DateValue, TimeValue, ValidationResult } from \"react-aria-components\";\n"],"mappings":"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","names":["Fragment","jsx","jsxs","Icon","AriaButton","jsx","jsxs","AriaButton","Icon"]}