@stamcat/craftsman 0.1.4 → 0.1.8

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 (43) hide show
  1. package/AGENTS.md +1 -0
  2. package/Components.esm.js +38 -36
  3. package/README.md +1 -0
  4. package/package.json +5 -1
  5. package/skills/craftsman-component-usage/SKILL.md +63 -6
  6. package/skills/craftsman-style-utilities/SKILL.md +1 -0
  7. package/src/components/DatePicker/AGENTS.md +1 -0
  8. package/src/components/DatePicker/DatePicker.css +1 -1
  9. package/src/components/DatePicker/DatePicker.esm.js +6 -5
  10. package/src/components/DatePicker/_DatePicker.scss +2 -0
  11. package/src/components/DateRangePicker/AGENTS.md +1 -0
  12. package/src/components/DateRangePicker/DateRangePicker.css +1 -1
  13. package/src/components/DateRangePicker/DateRangePicker.esm.js +6 -5
  14. package/src/components/DateTimePicker/AGENTS.md +1 -0
  15. package/src/components/DateTimePicker/DateTimePicker.css +1 -1
  16. package/src/components/DateTimePicker/DateTimePicker.esm.js +23 -22
  17. package/src/components/Input/AGENTS.md +8 -0
  18. package/src/components/Input/Input.css +1 -1
  19. package/src/components/Input/Input.esm.js +7 -4
  20. package/src/components/Input/Input.scss +15 -0
  21. package/src/components/Input/InputWrapper.d.ts +4 -0
  22. package/src/components/Input/InputWrapper.esm.js +13 -8
  23. package/src/components/InputPhone/AGENTS.md +1 -0
  24. package/src/components/InputPhone/InputPhone.css +1 -1
  25. package/src/components/InputPhone/InputPhone.esm.js +7 -6
  26. package/src/components/InputPhone/InputPhone.scss +3 -0
  27. package/src/components/Popover/AGENTS.md +62 -0
  28. package/src/components/Popover/Popover.css +1 -0
  29. package/src/components/Popover/Popover.d.ts +14 -0
  30. package/src/components/Popover/Popover.esm.js +80 -0
  31. package/src/components/Popover/Popover.scss +16 -0
  32. package/src/components/Select/AGENTS.md +1 -0
  33. package/src/components/Select/Select.esm.js +6 -5
  34. package/src/components/Textarea/AGENTS.md +8 -0
  35. package/src/components/Textarea/Textarea.esm.js +24 -20
  36. package/src/components/TimePicker/AGENTS.md +1 -0
  37. package/src/components/TimePicker/TimePicker.css +1 -1
  38. package/src/components/TimePicker/TimePicker.esm.js +23 -22
  39. package/src/components/TimePicker/TimePicker.scss +6 -1
  40. package/src/components/Toggle/Toggle.d.ts +1 -1
  41. package/src/components/index.d.ts +1 -0
  42. package/src/styles/global/components/_input.scss +1 -0
  43. package/src/styles/global/globalStyles.scss +7 -0
package/AGENTS.md CHANGED
@@ -34,6 +34,7 @@ import { TimePicker } from "@stamcat/craftsman/TimePicker";
34
34
  import { DateTimePicker } from "@stamcat/craftsman/DateTimePicker";
35
35
  import { Toggle } from "@stamcat/craftsman/Toggle";
36
36
  import { Tooltip } from "@stamcat/craftsman/Tooltip";
37
+ import { Popover } from "@stamcat/craftsman/Popover";
37
38
  import { Notice } from "@stamcat/craftsman/Notice";
38
39
  import { SortableList } from "@stamcat/craftsman/SortableList";
39
40
  ```
package/Components.esm.js CHANGED
@@ -20,25 +20,26 @@ import { Carousel as v } from "./src/components/Carousel/Carousel.esm.js";
20
20
  import { TimePicker as y } from "./src/components/TimePicker/TimePicker.esm.js";
21
21
  import { DateTimePicker as b } from "./src/components/DateTimePicker/DateTimePicker.esm.js";
22
22
  import { Tooltip as x } from "./src/components/Tooltip/Tooltip.esm.js";
23
- import { Notice as S } from "./src/components/Notice/Notice.esm.js";
24
- import { SortableList as C } from "./src/components/SortableList/SortableList.esm.js";
25
- import { IconAmazonPay as w } from "./src/components/Icons/IconAmazonPay.esm.js";
26
- import { IconAmex as T } from "./src/components/Icons/IconAmex.esm.js";
27
- import { IconApplePay as E } from "./src/components/Icons/IconApplePay.esm.js";
28
- import { IconDiscover as D } from "./src/components/Icons/IconDiscover.esm.js";
29
- import { IconGooglePay as O } from "./src/components/Icons/IconGooglePay.esm.js";
30
- import { IconMaestro as k } from "./src/components/Icons/IconMaestro.esm.js";
31
- import { IconMastercard as A } from "./src/components/Icons/IconMastercard.esm.js";
32
- import { IconPayPal as j } from "./src/components/Icons/IconPayPal.esm.js";
33
- import { IconSepa as M } from "./src/components/Icons/IconSepa.esm.js";
34
- import { IconShopPay as N } from "./src/components/Icons/IconShopPay.esm.js";
35
- import { IconSquare as P } from "./src/components/Icons/IconSquare.esm.js";
36
- import { IconStripe as F } from "./src/components/Icons/IconStripe.esm.js";
37
- import { IconUnionPay as I } from "./src/components/Icons/IconUnionPay.esm.js";
38
- import { IconVenmo as L } from "./src/components/Icons/IconVenmo.esm.js";
39
- import { IconVisa as R } from "./src/components/Icons/IconVisa.esm.js";
23
+ import { Popover as S } from "./src/components/Popover/Popover.esm.js";
24
+ import { Notice as C } from "./src/components/Notice/Notice.esm.js";
25
+ import { SortableList as w } from "./src/components/SortableList/SortableList.esm.js";
26
+ import { IconAmazonPay as T } from "./src/components/Icons/IconAmazonPay.esm.js";
27
+ import { IconAmex as E } from "./src/components/Icons/IconAmex.esm.js";
28
+ import { IconApplePay as D } from "./src/components/Icons/IconApplePay.esm.js";
29
+ import { IconDiscover as O } from "./src/components/Icons/IconDiscover.esm.js";
30
+ import { IconGooglePay as k } from "./src/components/Icons/IconGooglePay.esm.js";
31
+ import { IconMaestro as A } from "./src/components/Icons/IconMaestro.esm.js";
32
+ import { IconMastercard as j } from "./src/components/Icons/IconMastercard.esm.js";
33
+ import { IconPayPal as M } from "./src/components/Icons/IconPayPal.esm.js";
34
+ import { IconSepa as N } from "./src/components/Icons/IconSepa.esm.js";
35
+ import { IconShopPay as P } from "./src/components/Icons/IconShopPay.esm.js";
36
+ import { IconSquare as F } from "./src/components/Icons/IconSquare.esm.js";
37
+ import { IconStripe as I } from "./src/components/Icons/IconStripe.esm.js";
38
+ import { IconUnionPay as L } from "./src/components/Icons/IconUnionPay.esm.js";
39
+ import { IconVenmo as R } from "./src/components/Icons/IconVenmo.esm.js";
40
+ import { IconVisa as z } from "./src/components/Icons/IconVisa.esm.js";
40
41
  //#region src/components/index.ts
41
- var z = /* @__PURE__ */ e({
42
+ var B = /* @__PURE__ */ e({
42
43
  Accordion: () => t,
43
44
  Button: () => n,
44
45
  Carousel: () => v,
@@ -46,32 +47,33 @@ var z = /* @__PURE__ */ e({
46
47
  DatePicker: () => f,
47
48
  DateRangePicker: () => p,
48
49
  DateTimePicker: () => b,
49
- IconAmazonPay: () => w,
50
- IconAmex: () => T,
51
- IconApplePay: () => E,
52
- IconDiscover: () => D,
53
- IconGooglePay: () => O,
54
- IconMaestro: () => k,
55
- IconMastercard: () => A,
56
- IconPayPal: () => j,
57
- IconSepa: () => M,
58
- IconShopPay: () => N,
59
- IconSquare: () => P,
60
- IconStripe: () => F,
61
- IconUnionPay: () => I,
62
- IconVenmo: () => L,
63
- IconVisa: () => R,
50
+ IconAmazonPay: () => T,
51
+ IconAmex: () => E,
52
+ IconApplePay: () => D,
53
+ IconDiscover: () => O,
54
+ IconGooglePay: () => k,
55
+ IconMaestro: () => A,
56
+ IconMastercard: () => j,
57
+ IconPayPal: () => M,
58
+ IconSepa: () => N,
59
+ IconShopPay: () => P,
60
+ IconSquare: () => F,
61
+ IconStripe: () => I,
62
+ IconUnionPay: () => L,
63
+ IconVenmo: () => R,
64
+ IconVisa: () => z,
64
65
  Input: () => r,
65
66
  InputNumber: () => h,
66
67
  InputPassword: () => i,
67
68
  InputPhone: () => m,
68
69
  Loader: () => a,
69
70
  Modal: () => u,
70
- Notice: () => S,
71
+ Notice: () => C,
71
72
  Pagination: () => _,
73
+ Popover: () => S,
72
74
  RadioButton: () => o,
73
75
  Select: () => d,
74
- SortableList: () => C,
76
+ SortableList: () => w,
75
77
  Text: () => l,
76
78
  Textarea: () => c,
77
79
  TimePicker: () => y,
@@ -79,4 +81,4 @@ var z = /* @__PURE__ */ e({
79
81
  Tooltip: () => x
80
82
  });
81
83
  //#endregion
82
- export { t as Accordion, n as Button, v as Carousel, s as Checkbox, f as DatePicker, p as DateRangePicker, b as DateTimePicker, w as IconAmazonPay, T as IconAmex, E as IconApplePay, D as IconDiscover, O as IconGooglePay, k as IconMaestro, A as IconMastercard, j as IconPayPal, M as IconSepa, N as IconShopPay, P as IconSquare, F as IconStripe, I as IconUnionPay, L as IconVenmo, R as IconVisa, r as Input, h as InputNumber, i as InputPassword, m as InputPhone, a as Loader, u as Modal, S as Notice, _ as Pagination, o as RadioButton, d as Select, C as SortableList, l as Text, c as Textarea, y as TimePicker, g as Toggle, x as Tooltip, z as components_exports };
84
+ export { t as Accordion, n as Button, v as Carousel, s as Checkbox, f as DatePicker, p as DateRangePicker, b as DateTimePicker, T as IconAmazonPay, E as IconAmex, D as IconApplePay, O as IconDiscover, k as IconGooglePay, A as IconMaestro, j as IconMastercard, M as IconPayPal, N as IconSepa, P as IconShopPay, F as IconSquare, I as IconStripe, L as IconUnionPay, R as IconVenmo, z as IconVisa, r as Input, h as InputNumber, i as InputPassword, m as InputPhone, a as Loader, u as Modal, C as Notice, _ as Pagination, S as Popover, o as RadioButton, d as Select, w as SortableList, l as Text, c as Textarea, y as TimePicker, g as Toggle, x as Tooltip, B as components_exports };
package/README.md CHANGED
@@ -96,6 +96,7 @@ Each component has its own package entry point, e.g. `@stamcat/craftsman/Button`
96
96
  | TimePicker | `@stamcat/craftsman/TimePicker` |
97
97
  | Toggle | `@stamcat/craftsman/Toggle` |
98
98
  | Tooltip | `@stamcat/craftsman/Tooltip` |
99
+ | Popover | `@stamcat/craftsman/Popover` |
99
100
 
100
101
  ## Styling notes
101
102
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stamcat/craftsman",
3
- "version": "0.1.4",
3
+ "version": "0.1.8",
4
4
  "type": "module",
5
5
  "description": "A powerful, lightweight framework for design systems",
6
6
  "repository": {
@@ -317,6 +317,10 @@
317
317
  "types": "./src/components/Tooltip/Tooltip.d.ts",
318
318
  "default": "./src/components/Tooltip/Tooltip.esm.js"
319
319
  },
320
+ "./Popover": {
321
+ "types": "./src/components/Popover/Popover.d.ts",
322
+ "default": "./src/components/Popover/Popover.esm.js"
323
+ },
320
324
  "./Notice": {
321
325
  "types": "./src/components/Notice/Notice.d.ts",
322
326
  "default": "./src/components/Notice/Notice.esm.js"
@@ -33,6 +33,7 @@ import { TimePicker } from "@stamcat/craftsman/TimePicker";
33
33
  import { DateTimePicker } from "@stamcat/craftsman/DateTimePicker";
34
34
  import { Toggle } from "@stamcat/craftsman/Toggle";
35
35
  import { Tooltip } from "@stamcat/craftsman/Tooltip";
36
+ import { Popover } from "@stamcat/craftsman/Popover";
36
37
  import { Notice } from "@stamcat/craftsman/Notice";
37
38
  import { SortableList } from "@stamcat/craftsman/SortableList";
38
39
  ```
@@ -72,6 +73,7 @@ Each entry links to the `AGENTS.md` co-located with that component's source for
72
73
  | Text | [../../src/components/Text/AGENTS.md](../../src/components/Text/AGENTS.md) |
73
74
  | DateTimePicker | [../../src/components/DateTimePicker/AGENTS.md](../../src/components/DateTimePicker/AGENTS.md) |
74
75
  | Tooltip | [../../src/components/Tooltip/AGENTS.md](../../src/components/Tooltip/AGENTS.md) |
76
+ | Popover | [../../src/components/Popover/AGENTS.md](../../src/components/Popover/AGENTS.md) |
75
77
  | Toggle | [../../src/components/Toggle/AGENTS.md](../../src/components/Toggle/AGENTS.md) |
76
78
  | Notice | [../../src/components/Notice/AGENTS.md](../../src/components/Notice/AGENTS.md) |
77
79
  | SortableList | [../../src/components/SortableList/AGENTS.md](../../src/components/SortableList/AGENTS.md) |
@@ -133,7 +135,14 @@ toast.info("New version available.");
133
135
 
134
136
  Craftsman uses `react-chartjs-2` directly, without modification — there is no Craftsman `Chart` wrapper component. Consumers install `react-chartjs-2` and its `chart.js` peer dependency themselves and use the upstream API exactly as documented at https://react-chartjs-2.js.org/examples.
135
137
 
136
- Import:
138
+ Do this, in order, every time a chart is requested — do not stop after only picking a chart type:
139
+
140
+ 1. Confirm `chart.js` and `react-chartjs-2` are installed (`npm install chart.js react-chartjs-2` if missing — do not skip this because you "can't run commands"; ask the user to run it if you truly cannot).
141
+ 2. Import the chart component (`Bar`, `Line`, `Pie`, `Doughnut`, `PolarArea`, `Radar`, `Scatter`, `Bubble`, or `Chart` for mixed types) from `react-chartjs-2`.
142
+ 3. Import and `ChartJS.register(...)` only the `chart.js` pieces that chart type needs, once at module scope, before any render.
143
+ 4. Build a `data` object (`labels` + `datasets`) and an `options` object, then render `<ChartComponent data={data} options={options} />`.
144
+
145
+ Full minimal working example (bar chart) — use this shape as the template for any chart type:
137
146
 
138
147
  ```tsx
139
148
  import { Chart as ChartJS, CategoryScale, LinearScale, BarElement, Tooltip, Legend } from "chart.js";
@@ -141,19 +150,67 @@ import { Bar } from "react-chartjs-2";
141
150
 
142
151
  // Register only the controllers/elements/scales/plugins the chart type needs — chart.js is tree-shakeable.
143
152
  ChartJS.register(CategoryScale, LinearScale, BarElement, Tooltip, Legend);
153
+
154
+ function RevenueChart() {
155
+ return (
156
+ <Bar
157
+ data={{
158
+ labels: ["January", "February", "March"],
159
+ datasets: [{ label: "Revenue", data: [12, 19, 8], backgroundColor: "#3A70C2" }],
160
+ }}
161
+ options={{ responsive: true }}
162
+ />
163
+ );
164
+ }
144
165
  ```
145
166
 
146
- Usage:
167
+ Usage notes:
147
168
 
148
- - Every chart type used (`Bar`, `Line`, `Pie`, `Doughnut`, `PolarArea`, `Radar`, `Scatter`, `Bubble`, `Chart` for mixed types) must have its corresponding `chart.js` pieces registered once at module scope before render.
169
+ - Every chart type used (`Bar`, `Line`, `Pie`, `Doughnut`, `PolarArea`, `Radar`, `Scatter`, `Bubble`, `Chart` for mixed types) must have its corresponding `chart.js` pieces registered once at module scope before render — a missing registration is the most common cause of a blank canvas, not a bug in the library.
170
+ - "Donut" is just the common spelling of "doughnut" — chart.js and react-chartjs-2 only export `Doughnut`, so treat a request for a "donut chart" as a request for the `Doughnut` chart type. Do not ask the user to clarify or stall on this — just use `Doughnut`.
149
171
  - Dataset colors must be literal color values (hex/`rgba()`), not CSS variables (`var(--blue500)`) — chart.js draws to a `<canvas>` 2D context, which cannot resolve CSS custom properties. Use `colors` and `hexToRgba` from `@stamcat/craftsman/styles` (see the [craftsman-style-utilities skill](../craftsman-style-utilities/SKILL.md)) to stay on-palette instead of hard-coding hex strings inline.
150
- - See `src/stories/organisms/Charts.stories.tsx` in this repo for a full worked example of every chart type from the react-chartjs-2 examples page.
172
+ - Storybook story files are **not published in the npm package** (excluded from the build to reduce package size) — do not look for them in `node_modules/@stamcat/craftsman`. If you are working inside the craftsman source repo itself, `src/stories/organisms/Charts.stories.tsx` has a full worked example of every chart type from the react-chartjs-2 examples page; copy the closest matching example and adapt the data. If you are in a consuming application, follow the steps and minimal example above directly instead.
151
173
 
152
174
  ## Tables (ag-grid-community)
153
175
 
154
176
  Craftsman does not wrap `ag-grid-community`/`ag-grid-react` with a custom component. We use them directly, without modification, for advanced data visualization tables (large sortable/filterable datasets) — exactly as documented upstream at https://www.ag-grid.com/react-data-grid/.
155
177
 
156
- Import:
178
+ Do this, in order, every time a table/grid is requested — do not stop after only picking column definitions:
179
+
180
+ 1. Confirm `ag-grid-community` and `ag-grid-react` are installed (`npm install ag-grid-community ag-grid-react` if missing — do not skip this because you "can't run commands"; ask the user to run it if you truly cannot).
181
+ 2. Call `ModuleRegistry.registerModules([AllCommunityModule])` once at module scope, before any grid renders. Without this call the grid renders blank/broken — this is expected AG Grid v33+ behavior, not a library bug.
182
+ 3. Define `columnDefs` (one entry per column) and `rowData` (your array of row objects).
183
+ 4. Render `<AgGridReact theme={themeQuartz} rowData={rowData} columnDefs={columnDefs} />` inside a container with an explicit height (AG Grid does not auto-size its container).
184
+ 5. Only reach for Community-safe options (see below). If the request needs row grouping, pivoting, master/detail, server-side row model, or Excel export, tell the user those are AG Grid Enterprise features requiring a separate commercial license — do not silently omit the feature or stall without explanation.
185
+
186
+ Full minimal working example — use this shape as the template for any table:
187
+
188
+ ```tsx
189
+ import { AllCommunityModule, ModuleRegistry, themeQuartz, type ColDef } from "ag-grid-community";
190
+ import { AgGridReact } from "ag-grid-react";
191
+
192
+ // Register only the Community module — do not register Enterprise modules without a license.
193
+ ModuleRegistry.registerModules([AllCommunityModule]);
194
+
195
+ type Product = { readonly name: string; readonly price: number };
196
+
197
+ const rowData: Product[] = [
198
+ { name: "Trail Runner Jacket", price: 129 },
199
+ { name: "Insulated Water Bottle", price: 32 },
200
+ ];
201
+
202
+ const columnDefs: ColDef<Product>[] = [{ field: "name", filter: true }, { field: "price" }];
203
+
204
+ function ProductTable() {
205
+ return (
206
+ <div style={{ height: 360 }}>
207
+ <AgGridReact<Product> theme={themeQuartz} rowData={rowData} columnDefs={columnDefs} pagination />
208
+ </div>
209
+ );
210
+ }
211
+ ```
212
+
213
+ Import reference:
157
214
 
158
215
  ```tsx
159
216
  import { AllCommunityModule, ModuleRegistry, themeQuartz } from "ag-grid-community";
@@ -167,7 +224,7 @@ Usage:
167
224
 
168
225
  - Only the **free Community feature set** is used/showcased in this repo: client-side sorting, filtering, pagination, row selection, cell rendering/formatting, quick filter, and CSV export.
169
226
  - AG Grid also sells **Enterprise-only** features (row grouping, pivoting, master/detail, server-side row model, Excel export, and others). These require registering separate Enterprise modules and a commercial license key. Do not enable or suggest Enterprise modules unless the consumer confirms they hold an AG Grid Enterprise license — it is the consumer's responsibility to obtain and configure that license.
170
- - See `src/stories/organisms/Tables.stories.tsx` in this repo for worked Community-only examples.
227
+ - Storybook story files are **not published in the npm package** (excluded from the build to reduce package size) — do not look for them in `node_modules/@stamcat/craftsman`. If you are working inside the craftsman source repo itself, `src/stories/organisms/Tables.stories.tsx` has worked Community-only examples. If you are in a consuming application, follow the steps and minimal example above directly instead.
171
228
 
172
229
  ## Code Generation Patterns to Prefer
173
230
 
@@ -127,6 +127,7 @@ Valid keys: `text` · `gutter` · `column` · `tablet` · `desktop` · `extDeskt
127
127
 
128
128
  - The `column` key automatically accounts for gutters between columns.
129
129
  - Never use hard-coded `px` values for spacing or layout widths. Always use `width()`.
130
+ - The multiplier must be a whole, half, or quarter number a human can read at a glance (`0.25`, `0.5`, `0.75`, `1`, `1.5`, `2`, `-0.5`, etc.). Do not use obscure multipliers like `0.1`, `0.45`, or `-0.1` — if the design doesn't reduce to a clean fraction of the gutter, use the literal `px` value instead of forcing it through `width()`.
130
131
 
131
132
  ### breakpoint()
132
133
 
@@ -15,6 +15,7 @@ Props:
15
15
  - `required?: boolean`
16
16
  - `value?: Date | null`
17
17
  - `onChange?: (value: DatePickerProps["value"]) => void`
18
+ - `width?: string` — sets the field's width, accepts any CSS length e.g. `"50%"` or `"320px"`. Sets it via the `--input-width` CSS variable; omit for the default intrinsic/auto width.
18
19
 
19
20
  Behavior notes:
20
21
 
@@ -1 +1 @@
1
- @layer cf-base{.react-date-picker__wrapper{color:var(--text);border:1px solid var(--gray400);padding:calc(var(--w-gutter) * .5);background-color:var(--white);border-radius:6px}.react-date-picker__wrapper:focus{box-shadow:none;outline:0}.react-date-picker__wrapper:hover{border-color:var(--gray500)}[type=number].react-date-picker__wrapper::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}[type=number].react-date-picker__wrapper::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}[type=number].react-date-picker__wrapper{appearance:textfield}.react-date-picker__wrapper:disabled,.disabled.react-date-picker__wrapper{border-color:var(--gray400);background-color:var(--gray100)}}.react-date-picker,.react-date-picker *,.react-date-picker :before,.react-date-picker :after{box-sizing:border-box}@layer cf-component{.react-date-picker{display:inline-flex;position:relative}.react-date-picker--disabled{color:#6d6d6d;background-color:#f0f0f0}.react-date-picker__wrapper{flex-grow:1;flex-shrink:0;padding:6px 8px;display:flex}.react-date-picker__inputGroup{box-sizing:content-box;flex-grow:1;padding:0 2px}.react-date-picker__inputGroup__divider{white-space:pre;padding:1px 0}.react-date-picker__inputGroup__divider,.react-date-picker__inputGroup__leadingZero{font:inherit;display:inline-block}.react-date-picker__inputGroup__input{text-align:center;color:currentColor;min-width:calc(2ch + 1px);height:calc(100% - 2px);font:inherit;box-sizing:content-box;appearance:textfield;background:0 0;border:0;padding:1px;position:relative}[name=year].react-date-picker__inputGroup__input{min-width:calc(4ch + 2px)}.react-date-picker__inputGroup__input:disabled{background-color:unset}.react-date-picker__inputGroup__input::-webkit-outer-spin-button{appearance:none;margin:0}.react-date-picker__inputGroup__input::-webkit-inner-spin-button{appearance:none;margin:0}.react-date-picker__inputGroup__input--hasLeadingZero{margin-left:-.54em;padding-left:calc(1px + .54em)}.react-date-picker__button{border:0;padding:4px 4px 4px 7px}.react-date-picker__button:hover{background:0 0}.react-date-picker__calendar{z-index:1;width:350px;max-width:100vw}.react-date-picker__calendar .react-calendar{border-width:thin}.react-date-picker__calendar--closed,.react-date-picker__clock--closed{display:none}.input-wrapper.datePicker[data-label-position=inside][data-has-input=false]:not(:focus-within) .react-date-picker__inputGroup__divider{color:#0000}.react-date-picker__calendar .react-date-picker__inputGroup__input:invalid{background:unset}}
1
+ @layer cf-base{.react-date-picker__wrapper{color:var(--text);border:1px solid var(--gray400);padding:calc(var(--w-gutter) * .5);background-color:var(--white);width:var(--input-width,auto);border-radius:6px}.react-date-picker__wrapper:focus{box-shadow:none;outline:0}.react-date-picker__wrapper:hover{border-color:var(--gray500)}[type=number].react-date-picker__wrapper::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}[type=number].react-date-picker__wrapper::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}[type=number].react-date-picker__wrapper{appearance:textfield}.react-date-picker__wrapper:disabled,.disabled.react-date-picker__wrapper{border-color:var(--gray400);background-color:var(--gray100)}}.react-date-picker,.react-date-picker *,.react-date-picker :before,.react-date-picker :after{box-sizing:border-box}@layer cf-component{.react-date-picker{width:var(--input-width,auto);display:inline-flex;position:relative}.react-date-picker--disabled{color:#6d6d6d;background-color:#f0f0f0}.react-date-picker__wrapper{flex-grow:1;flex-shrink:0;width:auto;padding:6px 8px;display:flex}.react-date-picker__inputGroup{box-sizing:content-box;flex-grow:1;padding:0 2px}.react-date-picker__inputGroup__divider{white-space:pre;padding:1px 0}.react-date-picker__inputGroup__divider,.react-date-picker__inputGroup__leadingZero{font:inherit;display:inline-block}.react-date-picker__inputGroup__input{text-align:center;color:currentColor;min-width:calc(2ch + 1px);height:calc(100% - 2px);font:inherit;box-sizing:content-box;appearance:textfield;background:0 0;border:0;padding:1px;position:relative}[name=year].react-date-picker__inputGroup__input{min-width:calc(4ch + 2px)}.react-date-picker__inputGroup__input:disabled{background-color:unset}.react-date-picker__inputGroup__input::-webkit-outer-spin-button{appearance:none;margin:0}.react-date-picker__inputGroup__input::-webkit-inner-spin-button{appearance:none;margin:0}.react-date-picker__inputGroup__input--hasLeadingZero{margin-left:-.54em;padding-left:calc(1px + .54em)}.react-date-picker__button{border:0;padding:4px 4px 4px 7px}.react-date-picker__button:hover{background:0 0}.react-date-picker__calendar{z-index:1;width:350px;max-width:100vw}.react-date-picker__calendar .react-calendar{border-width:thin}.react-date-picker__calendar--closed,.react-date-picker__clock--closed{display:none}.input-wrapper.datePicker[data-label-position=inside][data-has-input=false]:not(:focus-within) .react-date-picker__inputGroup__divider{color:#0000}.react-date-picker__calendar .react-date-picker__inputGroup__input:invalid{background:unset}}
@@ -8,21 +8,22 @@ import { FaRegCalendar as r, FaX as i } from "react-icons/fa6";
8
8
  import { jsx as a } from "react/jsx-runtime";
9
9
  import { DatePicker as o } from "react-date-picker";
10
10
  //#region src/components/DatePicker/DatePicker.tsx
11
- var s = ({ label: s, id: c, labelPosition: l = "top", required: u = !1, error: d, style: f, className: p, ...m }) => {
12
- let h = t();
11
+ var s = ({ label: s, id: c, labelPosition: l = "top", required: u = !1, error: d, style: f, className: p, width: m, ...h }) => {
12
+ let g = t();
13
13
  return /* @__PURE__ */ a(e, {
14
- id: c || h,
14
+ id: c || g,
15
15
  className: n("datePicker", p),
16
16
  label: s,
17
17
  labelPosition: l,
18
18
  error: d,
19
19
  required: u,
20
20
  style: f,
21
- value: m.value?.toString(),
21
+ width: m,
22
+ value: h.value?.toString(),
22
23
  children: /* @__PURE__ */ a(o, {
23
24
  calendarIcon: /* @__PURE__ */ a(r, { size: 16 }),
24
25
  clearIcon: /* @__PURE__ */ a(i, { size: 14 }),
25
- ...m
26
+ ...h
26
27
  })
27
28
  });
28
29
  };
@@ -6,6 +6,7 @@
6
6
  %date-picker-styles {
7
7
  display: inline-flex;
8
8
  position: relative;
9
+ width: var(--input-width, auto);
9
10
  }
10
11
  %date-picker-disabled {
11
12
  background-color: #f0f0f0;
@@ -16,6 +17,7 @@
16
17
  flex-grow: 1;
17
18
  flex-shrink: 0;
18
19
  @extend %input-base;
20
+ width: auto;
19
21
  padding: 6px 8px;
20
22
  }
21
23
  %date-picker-input-group {
@@ -15,6 +15,7 @@ Props:
15
15
  - `required?: boolean`
16
16
  - `id?: string`
17
17
  - `style?: React.CSSProperties`
18
+ - `width?: string` — sets the field's width, accepts any CSS length e.g. `"50%"` or `"320px"`. Sets it via the `--input-width` CSS variable; omit for the default intrinsic/auto width.
18
19
  - `value?` / `onChange?` — from the underlying library; `value` is typically a `[Date, Date] | null` tuple.
19
20
 
20
21
  Behavior notes:
@@ -1 +1 @@
1
- @layer cf-base{.react-daterange-picker__wrapper{color:var(--text);border:1px solid var(--gray400);padding:calc(var(--w-gutter) * .5);background-color:var(--white);border-radius:6px}.react-daterange-picker__wrapper:focus{box-shadow:none;outline:0}.react-daterange-picker__wrapper:hover{border-color:var(--gray500)}[type=number].react-daterange-picker__wrapper::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}[type=number].react-daterange-picker__wrapper::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}[type=number].react-daterange-picker__wrapper{appearance:textfield}.react-daterange-picker__wrapper:disabled,.disabled.react-daterange-picker__wrapper{border-color:var(--gray400);background-color:var(--gray100)}}.react-daterange-picker,.react-daterange-picker *,.react-daterange-picker :before,.react-daterange-picker :after{box-sizing:border-box}@layer cf-component{.react-daterange-picker{display:inline-flex;position:relative}.react-daterange-picker--disabled{color:#6d6d6d;background-color:#f0f0f0}.react-daterange-picker__wrapper{flex-grow:1;flex-shrink:0;padding:6px 8px;display:flex}.react-daterange-picker__inputGroup{box-sizing:content-box;flex-grow:1;padding:0 2px}.react-daterange-picker__inputGroup__divider{white-space:pre;padding:1px 0}.react-daterange-picker__inputGroup__divider,.react-daterange-picker__inputGroup__leadingZero{font:inherit;display:inline-block}.react-daterange-picker__inputGroup__input{text-align:center;color:currentColor;min-width:calc(2ch + 1px);height:calc(100% - 2px);font:inherit;box-sizing:content-box;appearance:textfield;background:0 0;border:0;padding:1px;position:relative}[name=year].react-daterange-picker__inputGroup__input{min-width:calc(4ch + 2px)}.react-daterange-picker__inputGroup__input:disabled{background-color:unset}.react-daterange-picker__inputGroup__input::-webkit-outer-spin-button{appearance:none;margin:0}.react-daterange-picker__inputGroup__input::-webkit-inner-spin-button{appearance:none;margin:0}.react-daterange-picker__inputGroup__input--hasLeadingZero{margin-left:-.54em;padding-left:calc(1px + .54em)}.react-daterange-picker__button{border:0;padding:4px 4px 4px 7px}.react-daterange-picker__button:hover{background:0 0}.dateRangePicker[data-label-position=inside][data-has-input=false]:not(:focus-within) .react-daterange-picker__range-divider,.dateRangePicker[data-label-position=inside][data-has-input=false]:not(:focus-within) .react-date-picker__inputGroup__divider{color:#0000}.react-daterange-picker__calendar{z-index:1;width:350px;max-width:100vw}.react-daterange-picker__calendar .react-calendar{border-width:thin}.react-daterange-picker__calendar--closed,.react-daterange-picker__clock--closed{display:none}.react-daterange-picker__calendar .react-daterange-picker__inputGroup__input:invalid{background:unset}}
1
+ @layer cf-base{.react-daterange-picker__wrapper{color:var(--text);border:1px solid var(--gray400);padding:calc(var(--w-gutter) * .5);background-color:var(--white);width:var(--input-width,auto);border-radius:6px}.react-daterange-picker__wrapper:focus{box-shadow:none;outline:0}.react-daterange-picker__wrapper:hover{border-color:var(--gray500)}[type=number].react-daterange-picker__wrapper::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}[type=number].react-daterange-picker__wrapper::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}[type=number].react-daterange-picker__wrapper{appearance:textfield}.react-daterange-picker__wrapper:disabled,.disabled.react-daterange-picker__wrapper{border-color:var(--gray400);background-color:var(--gray100)}}.react-daterange-picker,.react-daterange-picker *,.react-daterange-picker :before,.react-daterange-picker :after{box-sizing:border-box}@layer cf-component{.react-daterange-picker{width:var(--input-width,auto);display:inline-flex;position:relative}.react-daterange-picker--disabled{color:#6d6d6d;background-color:#f0f0f0}.react-daterange-picker__wrapper{flex-grow:1;flex-shrink:0;width:auto;padding:6px 8px;display:flex}.react-daterange-picker__inputGroup{box-sizing:content-box;flex-grow:1;padding:0 2px}.react-daterange-picker__inputGroup__divider{white-space:pre;padding:1px 0}.react-daterange-picker__inputGroup__divider,.react-daterange-picker__inputGroup__leadingZero{font:inherit;display:inline-block}.react-daterange-picker__inputGroup__input{text-align:center;color:currentColor;min-width:calc(2ch + 1px);height:calc(100% - 2px);font:inherit;box-sizing:content-box;appearance:textfield;background:0 0;border:0;padding:1px;position:relative}[name=year].react-daterange-picker__inputGroup__input{min-width:calc(4ch + 2px)}.react-daterange-picker__inputGroup__input:disabled{background-color:unset}.react-daterange-picker__inputGroup__input::-webkit-outer-spin-button{appearance:none;margin:0}.react-daterange-picker__inputGroup__input::-webkit-inner-spin-button{appearance:none;margin:0}.react-daterange-picker__inputGroup__input--hasLeadingZero{margin-left:-.54em;padding-left:calc(1px + .54em)}.react-daterange-picker__button{border:0;padding:4px 4px 4px 7px}.react-daterange-picker__button:hover{background:0 0}.dateRangePicker[data-label-position=inside][data-has-input=false]:not(:focus-within) .react-daterange-picker__range-divider,.dateRangePicker[data-label-position=inside][data-has-input=false]:not(:focus-within) .react-date-picker__inputGroup__divider{color:#0000}.react-daterange-picker__calendar{z-index:1;width:350px;max-width:100vw}.react-daterange-picker__calendar .react-calendar{border-width:thin}.react-daterange-picker__calendar--closed,.react-daterange-picker__clock--closed{display:none}.react-daterange-picker__calendar .react-daterange-picker__inputGroup__input:invalid{background:unset}}
@@ -8,21 +8,22 @@ import { FaRegCalendar as r, FaX as i } from "react-icons/fa6";
8
8
  import { jsx as a } from "react/jsx-runtime";
9
9
  import { DateRangePicker as o } from "@wojtekmaj/react-daterange-picker";
10
10
  //#region src/components/DateRangePicker/DateRangePicker.tsx
11
- var s = ({ label: s, id: c, labelPosition: l = "top", required: u = !1, error: d, style: f, className: p, ...m }) => {
12
- let h = t();
11
+ var s = ({ label: s, id: c, labelPosition: l = "top", required: u = !1, error: d, style: f, className: p, width: m, ...h }) => {
12
+ let g = t();
13
13
  return /* @__PURE__ */ a(e, {
14
- id: c || h,
14
+ id: c || g,
15
15
  className: n("dateRangePicker", p),
16
16
  label: s,
17
17
  labelPosition: l,
18
18
  error: d,
19
19
  required: u,
20
20
  style: f,
21
- value: m.value?.toString(),
21
+ width: m,
22
+ value: h.value?.toString(),
22
23
  children: /* @__PURE__ */ a(o, {
23
24
  calendarIcon: /* @__PURE__ */ a(r, { size: 16 }),
24
25
  clearIcon: /* @__PURE__ */ a(i, { size: 14 }),
25
- ...m
26
+ ...h
26
27
  })
27
28
  });
28
29
  };
@@ -11,6 +11,7 @@ Props:
11
11
  - Extends `react-datetime-picker`'s `DateTimePickerProps` plus `LabeledInput` (`label`, `labelPosition`, `error`, `required`).
12
12
  - `id?: string`
13
13
  - `style?: React.CSSProperties`
14
+ - `width?: string` — sets the field's width, accepts any CSS length e.g. `"50%"` or `"320px"`. Sets it via the `--input-width` CSS variable; omit for the default intrinsic/auto width.
14
15
  - `format?: 24 | 12` — hour format used by the custom time wheel display.
15
16
  - `labels?: { hour?: string; minute?: string }` — labels passed through to the time wheel.
16
17
  - `value` / `onChange` — standard `Date` value and change callback.
@@ -1 +1 @@
1
- @layer cf-base{.react-datetime-picker__wrapper{color:var(--text);border:1px solid var(--gray400);padding:calc(var(--w-gutter) * .5);background-color:var(--white);border-radius:6px}.react-datetime-picker__wrapper:focus{box-shadow:none;outline:0}.react-datetime-picker__wrapper:hover{border-color:var(--gray500)}[type=number].react-datetime-picker__wrapper::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}[type=number].react-datetime-picker__wrapper::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}[type=number].react-datetime-picker__wrapper{appearance:textfield}.react-datetime-picker__wrapper:disabled,.disabled.react-datetime-picker__wrapper{border-color:var(--gray400);background-color:var(--gray100)}}.react-datetime-picker,.react-datetime-picker *,.react-datetime-picker :before,.react-datetime-picker :after{box-sizing:border-box}@layer cf-component{.react-datetime-picker{display:inline-flex;position:relative}.react-datetime-picker--disabled{color:#6d6d6d;background-color:#f0f0f0}.react-datetime-picker__wrapper{flex-grow:1;flex-shrink:0;padding:6px 8px;display:flex}.react-datetime-picker__inputGroup{box-sizing:content-box;flex-grow:1;padding:0 2px}.react-datetime-picker__inputGroup__divider{white-space:pre;padding:1px 0}.react-datetime-picker__inputGroup__divider,.react-datetime-picker__inputGroup__leadingZero{font:inherit;display:inline-block}.react-datetime-picker__inputGroup__input{text-align:center;color:currentColor;min-width:calc(2ch + 1px);height:calc(100% - 2px);font:inherit;box-sizing:content-box;appearance:textfield;background:0 0;border:0;padding:1px;position:relative}[name=year].react-datetime-picker__inputGroup__input{min-width:calc(4ch + 2px)}.react-datetime-picker__inputGroup__input:disabled{background-color:unset}.react-datetime-picker__inputGroup__input::-webkit-outer-spin-button{appearance:none;margin:0}.react-datetime-picker__inputGroup__input::-webkit-inner-spin-button{appearance:none;margin:0}.react-datetime-picker__inputGroup__input--hasLeadingZero{margin-left:-.54em;padding-left:calc(1px + .54em)}.react-datetime-picker__button{border:0;padding:4px 4px 4px 7px}.react-datetime-picker__button:hover{background:0 0}.dateTimePicker__wrapper[data-label-position=inside][data-has-input=false]:not(:focus-within) .react-datetime-picker__inputGroup__divider,.dateTimePicker__wrapper[data-label-position=inside][data-has-input=false]:not(:focus-within) .react-datetime-picker__inputGroup__amPm{color:#0000}.react-datetime-picker__calendar--closed,.react-datetime-picker__clock--closed{display:none}.react-datetime-picker__calendar,.react-datetime-picker__clock{z-index:1}.react-datetime-picker__inputGroup__input:invalid{background:#ff00001a}.react-datetime-picker__inputGroup__amPm{font:inherit;appearance:menulist}.react-datetime-picker__calendar{width:350px;max-width:100vw}.react-datetime-picker__calendar .react-calendar{border-width:thin}.react-date-picker__inputGroup__input:invalid,.react-datetime-picker__inputGroup__input:invalid{background:unset}.dateTimePicker{display:inline-block}.dateTimePicker__time-display{margin-top:8px;display:flex}.dateTimePicker__wrapper{display:inline-block}}
1
+ @layer cf-base{.react-datetime-picker__wrapper{color:var(--text);border:1px solid var(--gray400);padding:calc(var(--w-gutter) * .5);background-color:var(--white);width:var(--input-width,auto);border-radius:6px}.react-datetime-picker__wrapper:focus{box-shadow:none;outline:0}.react-datetime-picker__wrapper:hover{border-color:var(--gray500)}[type=number].react-datetime-picker__wrapper::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}[type=number].react-datetime-picker__wrapper::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}[type=number].react-datetime-picker__wrapper{appearance:textfield}.react-datetime-picker__wrapper:disabled,.disabled.react-datetime-picker__wrapper{border-color:var(--gray400);background-color:var(--gray100)}}.react-datetime-picker,.react-datetime-picker *,.react-datetime-picker :before,.react-datetime-picker :after{box-sizing:border-box}@layer cf-component{.react-datetime-picker{width:var(--input-width,auto);display:inline-flex;position:relative}.react-datetime-picker--disabled{color:#6d6d6d;background-color:#f0f0f0}.react-datetime-picker__wrapper{flex-grow:1;flex-shrink:0;width:auto;padding:6px 8px;display:flex}.react-datetime-picker__inputGroup{box-sizing:content-box;flex-grow:1;padding:0 2px}.react-datetime-picker__inputGroup__divider{white-space:pre;padding:1px 0}.react-datetime-picker__inputGroup__divider,.react-datetime-picker__inputGroup__leadingZero{font:inherit;display:inline-block}.react-datetime-picker__inputGroup__input{text-align:center;color:currentColor;min-width:calc(2ch + 1px);height:calc(100% - 2px);font:inherit;box-sizing:content-box;appearance:textfield;background:0 0;border:0;padding:1px;position:relative}[name=year].react-datetime-picker__inputGroup__input{min-width:calc(4ch + 2px)}.react-datetime-picker__inputGroup__input:disabled{background-color:unset}.react-datetime-picker__inputGroup__input::-webkit-outer-spin-button{appearance:none;margin:0}.react-datetime-picker__inputGroup__input::-webkit-inner-spin-button{appearance:none;margin:0}.react-datetime-picker__inputGroup__input--hasLeadingZero{margin-left:-.54em;padding-left:calc(1px + .54em)}.react-datetime-picker__button{border:0;padding:4px 4px 4px 7px}.react-datetime-picker__button:hover{background:0 0}.dateTimePicker__wrapper[data-label-position=inside][data-has-input=false]:not(:focus-within) .react-datetime-picker__inputGroup__divider,.dateTimePicker__wrapper[data-label-position=inside][data-has-input=false]:not(:focus-within) .react-datetime-picker__inputGroup__amPm{color:#0000}.react-datetime-picker__calendar--closed,.react-datetime-picker__clock--closed{display:none}.react-datetime-picker__calendar,.react-datetime-picker__clock{z-index:1}.react-datetime-picker__inputGroup__input:invalid{background:#ff00001a}.react-datetime-picker__inputGroup__amPm{font:inherit;appearance:menulist}.react-datetime-picker__calendar{width:350px;max-width:100vw}.react-datetime-picker__calendar .react-calendar{border-width:thin}.react-date-picker__inputGroup__input:invalid,.react-datetime-picker__inputGroup__input:invalid{background:unset}.dateTimePicker{display:inline-block}.dateTimePicker__time-display{margin-top:8px;display:flex}.dateTimePicker__wrapper{display:inline-block}}
@@ -12,67 +12,68 @@ import { jsx as d, jsxs as f } from "react/jsx-runtime";
12
12
  import { isMobile as p } from "react-device-detect";
13
13
  import { DateTimePicker as m } from "react-datetime-picker";
14
14
  //#region src/components/DateTimePicker/DateTimePicker.tsx
15
- var h = ({ label: h, id: g, labelPosition: _ = "top", required: v = !1, error: y, style: b, className: x, locale: S, labels: C, format: w, value: T, onChange: E, ...D }) => {
16
- let O = a(), k = g || O, A = o(null), [j, M] = s(!1), N = n(S);
15
+ var h = ({ label: h, id: g, labelPosition: _ = "top", required: v = !1, error: y, style: b, className: x, locale: S, labels: C, format: w, value: T, onChange: E, width: D, ...O }) => {
16
+ let k = a(), A = g || k, j = o(null), [M, N] = s(!1), P = n(S);
17
17
  i(() => {
18
- if (!j) return;
18
+ if (!M) return;
19
19
  let e = (e) => {
20
20
  let t = e.target;
21
- A.current?.contains(t) || M(!1);
21
+ j.current?.contains(t) || N(!1);
22
22
  };
23
23
  return document.addEventListener("pointerdown", e, !0), () => {
24
24
  document.removeEventListener("pointerdown", e, !0);
25
25
  };
26
- }, [j]);
27
- let P = () => {
26
+ }, [M]);
27
+ let F = () => {
28
28
  if (!p && T instanceof Date) {
29
- M(!0);
29
+ N(!0);
30
30
  return;
31
31
  }
32
- (A.current?.querySelector("input[name=\"day\"]"))?.focus();
33
- }, F = (e) => {
34
- e.target instanceof HTMLInputElement && P();
32
+ (j.current?.querySelector("input[name=\"day\"]"))?.focus();
35
33
  }, I = (e) => {
36
- p && e.key === "Enter" && M(!1);
34
+ e.target instanceof HTMLInputElement && F();
37
35
  }, L = (e) => {
36
+ p && e.key === "Enter" && N(!1);
37
+ }, R = (e) => {
38
38
  let [t, n] = e.split(":"), r = Number(t), i = Number(n);
39
39
  if (Number.isNaN(r) || Number.isNaN(i)) return;
40
40
  let a = T instanceof Date ? new Date(T) : /* @__PURE__ */ new Date();
41
41
  a.setHours(r, i, 0, 0), E?.(a);
42
42
  };
43
43
  return /* @__PURE__ */ d("div", {
44
- ref: A,
44
+ ref: j,
45
45
  className: "dateTimePicker",
46
- onKeyDown: I,
46
+ onKeyDown: L,
47
47
  children: /* @__PURE__ */ f(t, {
48
- id: k,
49
- onFocus: F,
48
+ id: A,
49
+ onFocus: I,
50
50
  className: c(x, "dateTimePicker__wrapper"),
51
51
  label: h,
52
52
  labelPosition: _,
53
53
  error: y,
54
54
  required: v,
55
55
  style: b,
56
+ width: D,
56
57
  value: T instanceof Date ? T.toISOString() : void 0,
57
58
  children: [/* @__PURE__ */ d(m, {
58
59
  isClockOpen: !1,
59
- onClockOpen: P,
60
+ onClockOpen: F,
60
61
  onClockClose: () => {},
61
- onCalendarOpen: () => M(!1),
62
+ onCalendarOpen: () => N(!1),
62
63
  calendarIcon: /* @__PURE__ */ d(l, { size: 16 }),
63
64
  clearIcon: /* @__PURE__ */ d(u, { size: 14 }),
64
65
  value: T,
65
66
  onChange: E,
66
- ...D
67
- }), j && /* @__PURE__ */ d("div", {
67
+ ...O
68
+ }), M && /* @__PURE__ */ d("div", {
68
69
  className: "dateTimePicker__time-display",
69
70
  children: /* @__PURE__ */ d(r, {
70
71
  value: e(T, S),
71
- onChange: L,
72
- locale: N,
72
+ onChange: R,
73
+ locale: P,
73
74
  labels: C,
74
75
  format: w,
75
- visible: j
76
+ visible: M
76
77
  })
77
78
  })]
78
79
  })
@@ -15,6 +15,10 @@ Props:
15
15
  - `required?: boolean`
16
16
  - `style?: React.CSSProperties` — targets the wrapper element.
17
17
  - `inputStyle?: React.CSSProperties` — targets the `<input>` field directly.
18
+ - `inputClassName?: string` — adds a className to the `<input>` field directly (alongside the base `"input"` class).
19
+ - `labelStyle?: React.CSSProperties` — targets the wrapping `<label>` element.
20
+ - `labelClassName?: string` — adds a className to the wrapping `<label>` element.
21
+ - `width?: string` — sets the field's width, accepts any CSS length e.g. `"50%"` or `"320px"`. Sets it via the `--input-width` CSS variable; omit for the default intrinsic/auto width.
18
22
  - `type?: TextInputType` (checkbox/radio excluded)
19
23
 
20
24
  Behavior notes:
@@ -30,3 +34,7 @@ Example:
30
34
  ```tsx
31
35
  <Input type="email" placeholder="you@company.com" required />
32
36
  ```
37
+
38
+ ```tsx
39
+ <Input label="Name" width="50%" labelStyle={{ width: "100%" }} />
40
+ ```
@@ -1 +1 @@
1
- @layer cf-base{.input-pre-adornment,.input-end-adornment{z-index:1;align-items:center;margin-top:0;display:inline-flex;position:absolute;top:50%;transform:translateY(-50%)}.input-wrapper label .input-label{margin-bottom:calc(var(--w-gutter) * .25)}.input-wrapper[data-required=true] label .input-label:after{content:"*";color:var(--red700)}.input-wrapper[data-label-position=left] label{align-items:center;display:inline-flex}.input-wrapper[data-label-position=left] label .input-label{width:fit-content;margin-right:calc(var(--w-gutter) * .75)}.input-wrapper[data-label-position=left].textarea label{align-items:flex-start}.input-wrapper[data-label-position=bottom] label{flex-direction:column-reverse;align-items:flex-start;display:inline-flex}.input-wrapper[data-label-position=bottom] label .input-label{margin-bottom:0;margin-top:calc(var(--w-gutter) * .25)}.input-wrapper[data-label-position=right] label{flex-direction:row-reverse;align-items:baseline;display:inline-flex}.input-wrapper[data-label-position=right] label .input-label{margin-left:calc(var(--w-gutter) * .5);margin-bottom:0}.input-wrapper[data-label-position=inside]{--react-international-phone-height:50px;--react-international-phone-border-radius:8px;--react-international-phone-border-color:silver;position:relative}.input-wrapper[data-label-position=inside] .input-label{background-color:var(--white);z-index:1;width:fit-content;top:calc(var(--w-gutter) * .45);left:calc(var(--w-gutter) * .25);pointer-events:none;padding:0 5px;transition:top .15s,left .15s,font-size .15s,color .15s;position:absolute}.input-wrapper[data-label-position=inside]>label>.input-field>.input,.input-wrapper[data-label-position=inside]>.input{transition:border-color .2s}.input-wrapper[data-label-position=inside]:has(.input-field[data-has-pre-adornment=true]) .input-label{left:calc(var(--w-gutter) * 1.75)}.input-wrapper[data-label-position=inside]:focus-within .input-label{top:-.5rem;left:calc(var(--w-gutter) * .125);font-size:calc(var(--w-text) * .75);color:var(--blue500)}.input-wrapper[data-label-position=inside]:focus-within .input{border-color:var(--blue500)}.input-wrapper[data-label-position=inside]:focus-within input::placeholder{opacity:1}.input-wrapper[data-label-position=inside][data-has-input=true] .input-label,.input-wrapper[data-label-position=inside].select .input-label{top:-.5rem;left:calc(var(--w-gutter) * .125);font-size:calc(var(--w-text) * .75)}.input-wrapper[data-label-position=inside] .input[type=tel]{width:100%}.input-wrapper[data-label-position=inside] input::placeholder{opacity:0;transition:opacity .2s}.input-field{align-items:center;display:inline-flex;position:relative}.input-field[data-has-end-adornment=true]>.input{padding-right:calc(var(--w-gutter) * 1.5)}.input-field[data-has-pre-adornment=true]>.input{padding-left:calc(var(--w-gutter) * 1.75)}.input-end-adornment{right:calc(var(--w-gutter) * .5)}.input-pre-adornment{left:calc(var(--w-gutter) * .5)}.input-error{margin-top:calc(var(--w-gutter) * .25);font-size:calc(var(--w-text) * .75);color:var(--red600)}.input-view-toggle{align-items:"center";padding:0;line-height:1;display:inline-flex}}
1
+ @layer cf-base{.input-pre-adornment,.input-end-adornment{z-index:1;align-items:center;margin-top:0;display:inline-flex;position:absolute;top:50%;transform:translateY(-50%)}.input-wrapper label .input-label{margin-bottom:calc(var(--w-gutter) * .25)}.input-wrapper[data-label-position=top] label{display:block}.input-wrapper[data-required=true] label .input-label:after{content:"*";color:var(--red700)}.input-wrapper[data-label-position=left] label{align-items:center;display:inline-flex}.input-wrapper[data-label-position=left] label .input-label{width:fit-content;margin-right:calc(var(--w-gutter) * .75)}.input-wrapper[data-label-position=left].textarea label{align-items:flex-start}.input-wrapper[data-label-position=bottom] label{flex-direction:column-reverse;align-items:flex-start;display:inline-flex}.input-wrapper[data-label-position=bottom] label .input-label{margin-bottom:0;margin-top:calc(var(--w-gutter) * .25)}.input-wrapper[data-label-position=right] label{flex-direction:row-reverse;align-items:baseline;display:inline-flex}.input-wrapper[data-label-position=right] label .input-label{margin-left:calc(var(--w-gutter) * .5);margin-bottom:0}.input-wrapper[data-label-position=inside]{--react-international-phone-height:50px;--react-international-phone-border-radius:8px;--react-international-phone-border-color:silver;position:relative}.input-wrapper[data-label-position=inside] .input-label{background-color:var(--white);z-index:1;width:fit-content;top:calc(var(--w-gutter) * .45);left:calc(var(--w-gutter) * .25);pointer-events:none;padding:0 5px;transition:top .15s,left .15s,font-size .15s,color .15s;position:absolute}.input-wrapper[data-label-position=inside]>label>.input-field>.input,.input-wrapper[data-label-position=inside]>.input{transition:border-color .2s}.input-wrapper[data-label-position=inside]:has(.input-field[data-has-pre-adornment=true]) .input-label{left:calc(var(--w-gutter) * 1.75)}.input-wrapper[data-label-position=inside]:focus-within .input-label{top:-.5rem;left:calc(var(--w-gutter) * .125);font-size:calc(var(--w-text) * .75);color:var(--blue500)}.input-wrapper[data-label-position=inside]:focus-within .input{border-color:var(--blue500)}.input-wrapper[data-label-position=inside]:focus-within input::placeholder{opacity:1}.input-wrapper[data-label-position=inside][data-has-input=true] .input-label,.input-wrapper[data-label-position=inside].select .input-label{top:-.5rem;left:calc(var(--w-gutter) * .125);font-size:calc(var(--w-text) * .75)}.input-wrapper[data-label-position=inside] .input[type=tel]{width:100%}.input-wrapper[data-label-position=inside] input::placeholder{opacity:0;transition:opacity .2s}.input-field{width:var(--input-width,auto);align-items:center;display:inline-flex;position:relative}.input-field>.input{flex:1;width:auto;min-width:0}.input-field[data-has-end-adornment=true]>.input{padding-right:calc(var(--w-gutter) * 1.5)}.input-field[data-has-pre-adornment=true]>.input{padding-left:calc(var(--w-gutter) * 1.75)}.input-end-adornment{right:calc(var(--w-gutter) * .5)}.input-pre-adornment{left:calc(var(--w-gutter) * .5)}.input-error{margin-top:calc(var(--w-gutter) * .25);font-size:calc(var(--w-text) * .75);color:var(--red600)}.input-view-toggle{align-items:"center";padding:0;line-height:1;display:inline-flex}}
@@ -6,7 +6,7 @@ import r from "clsx";
6
6
  import { jsx as i, jsxs as a } from "react/jsx-runtime";
7
7
  //#region src/components/Input/Input.tsx
8
8
  var o = (o) => {
9
- let { label: s, id: c, labelPosition: l = "top", required: u = !1, type: d = "text", error: f, endAdornment: p, preAdornment: m, style: h, className: g, value: _, defaultValue: v, inputStyle: y, ...b } = o, x = n(), S = c || x;
9
+ let { label: s, id: c, labelPosition: l = "top", required: u = !1, type: d = "text", error: f, endAdornment: p, preAdornment: m, style: h, className: g, value: _, defaultValue: v, inputStyle: y, inputClassName: b, labelStyle: x, labelClassName: S, width: C, ...w } = o, T = n(), E = c || T;
10
10
  return /* @__PURE__ */ i(t, {
11
11
  className: g,
12
12
  label: s,
@@ -16,6 +16,9 @@ var o = (o) => {
16
16
  style: h,
17
17
  value: _,
18
18
  defaultValue: v,
19
+ labelStyle: x,
20
+ labelClassName: S,
21
+ width: C,
19
22
  children: /* @__PURE__ */ a("span", {
20
23
  className: "input-field",
21
24
  "data-has-end-adornment": !e(p),
@@ -26,13 +29,13 @@ var o = (o) => {
26
29
  children: m
27
30
  }),
28
31
  /* @__PURE__ */ i("input", {
29
- id: S,
32
+ id: E,
30
33
  type: d,
31
- className: r("input", d),
34
+ className: r("input", d, b),
32
35
  value: _,
33
36
  defaultValue: v,
34
37
  style: y,
35
- ...b
38
+ ...w
36
39
  }),
37
40
  !e(p) && /* @__PURE__ */ i("span", {
38
41
  className: "input-end-adornment",
@@ -24,6 +24,12 @@
24
24
  }
25
25
  }
26
26
 
27
+ &[data-label-position="top"] {
28
+ label {
29
+ display: block;
30
+ }
31
+ }
32
+
27
33
  &[data-required="true"] {
28
34
  label {
29
35
  .input-label {
@@ -153,6 +159,15 @@
153
159
  position: relative;
154
160
  display: inline-flex;
155
161
  align-items: center;
162
+ width: var(--input-width, auto);
163
+
164
+ // flex-grow (not a percentage) so sizing resolves against the already-sized .input-field above, avoiding a circular percentage calc
165
+ > .input {
166
+ width: auto;
167
+ min-width: 0;
168
+ flex: 1 1 0%;
169
+ }
170
+
156
171
  &[data-has-end-adornment="true"] {
157
172
  > .input {
158
173
  padding-right: #{u.width("gutter", 1.5)};
@@ -5,9 +5,13 @@ export type LabeledInput = {
5
5
  error?: string | boolean | React.ReactNode;
6
6
  required?: boolean;
7
7
  inputStyle?: React.CSSProperties;
8
+ inputClassName?: string;
8
9
  endAdornment?: React.ReactNode;
9
10
  preAdornment?: React.ReactNode;
10
11
  onLabelClick?: React.MouseEventHandler<HTMLLabelElement>;
12
+ labelStyle?: React.CSSProperties;
13
+ labelClassName?: string;
14
+ width?: string;
11
15
  };
12
16
  export type InputWrapperProps = React.ComponentProps<"input" | "textarea" | "select"> & LabeledInput;
13
17
  export declare const InputWrapper: React.FC<InputWrapperProps>;