minka-ds 0.2.7 → 0.2.9

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minka-ds",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "Minka product design system — tokenized component library",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -0,0 +1,58 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Calendar } from "./calendar"
5
+ import { Input } from "./input"
6
+ import { cn } from "../../lib/utils"
7
+
8
+ export interface DateTimeValue {
9
+ date: Date | null
10
+ time: string
11
+ }
12
+
13
+ interface DateTimePickerProps {
14
+ value?: DateTimeValue | null
15
+ onChange: (value: DateTimeValue | null) => void
16
+ className?: string
17
+ }
18
+
19
+ export function DateTimePicker({
20
+ value,
21
+ onChange,
22
+ className,
23
+ }: DateTimePickerProps) {
24
+ function handleDaySelect(selected: Date | undefined) {
25
+ if (!selected) { onChange(null); return }
26
+ onChange({ date: selected, time: value?.time ?? "" })
27
+ }
28
+
29
+ function handleTime(e: React.ChangeEvent<HTMLInputElement>) {
30
+ if (!value?.date) return
31
+ onChange({ ...value, time: e.target.value })
32
+ }
33
+
34
+ return (
35
+ <div className={cn(
36
+ "[border-radius:var(--radius-card)] border border-[var(--color-border-default)] bg-[var(--color-bg-raised)] overflow-hidden w-fit",
37
+ className
38
+ )}>
39
+ <Calendar
40
+ mode="single"
41
+ captionLayout="label"
42
+ selected={value?.date ?? undefined}
43
+ onSelect={handleDaySelect}
44
+ />
45
+ <div className="border-t border-[var(--color-border-default)] px-4 py-3">
46
+ <div className="flex flex-col gap-1.5">
47
+ <label className="text-body-sm">Time</label>
48
+ <Input
49
+ type="time"
50
+ value={value?.time ?? ""}
51
+ onChange={handleTime}
52
+ disabled={!value?.date}
53
+ />
54
+ </div>
55
+ </div>
56
+ </div>
57
+ )
58
+ }
@@ -41,6 +41,7 @@ function FilterCombobox({
41
41
  activeFilters = {},
42
42
  trigger,
43
43
  dropdownAlign = "left",
44
+ singleSelect = false,
44
45
  className,
45
46
  }: {
46
47
  categories: FilterCategory[]
@@ -48,6 +49,7 @@ function FilterCombobox({
48
49
  activeFilters?: Record<string, CategoryValue[]>
49
50
  trigger?: (props: { open: boolean; onClick: () => void }) => React.ReactNode
50
51
  dropdownAlign?: "left" | "right"
52
+ singleSelect?: boolean
51
53
  className?: string
52
54
  }) {
53
55
  const [open, setOpen] = React.useState(false)
@@ -273,8 +275,12 @@ function FilterCombobox({
273
275
  ? <EmptyRow />
274
276
  : step2Filtered.map(value => (
275
277
  <li key={value}>
276
- {selectedCategory.type === "hours" ? (
277
- <PickerRow onClick={() => { onApply(selectedCategory.id, [value]); handleClose() }}>
278
+ {selectedCategory.type === "hours" || singleSelect ? (
279
+ <PickerRow
280
+ onClick={() => { onApply(selectedCategory.id, [value]); handleClose() }}
281
+ selected={singleSelect && selectedValues.has(value)}
282
+ hideChevron={singleSelect}
283
+ >
278
284
  {selectedCategory.renderValue?.(value) ?? value}
279
285
  </PickerRow>
280
286
  ) : (
@@ -294,7 +300,7 @@ function FilterCombobox({
294
300
  </li>
295
301
  )}
296
302
  </ul>
297
- {selectedValues.size > 0 && selectedCategory.type !== "hours" && (
303
+ {selectedValues.size > 0 && selectedCategory.type !== "hours" && !singleSelect && (
298
304
  <div className="p-1">
299
305
  <Button size="sm" className="w-full" onClick={applyValues}>
300
306
  Apply
@@ -469,7 +475,7 @@ function StepHeader({ title, onBack }: { title: string; onBack: () => void }) {
469
475
  )
470
476
  }
471
477
 
472
- function PickerRow({ children, onClick }: { children: React.ReactNode; onClick: () => void }) {
478
+ function PickerRow({ children, onClick, selected = false, hideChevron = false }: { children: React.ReactNode; onClick: () => void; selected?: boolean; hideChevron?: boolean }) {
473
479
  return (
474
480
  <button
475
481
  type="button"
@@ -477,7 +483,8 @@ function PickerRow({ children, onClick }: { children: React.ReactNode; onClick:
477
483
  className="relative flex w-full items-center gap-2 [border-radius:var(--radius-tag)] py-1.5 pl-2 pr-8 text-body-sm text-[var(--color-text-default)] hover:bg-[var(--color-action-ghost-hover)] transition-colors"
478
484
  >
479
485
  {children}
480
- <ChevronRightIcon className="pointer-events-none absolute right-2 size-3.5 text-[var(--color-text-muted)]" />
486
+ {!hideChevron && <ChevronRightIcon className="pointer-events-none absolute right-2 size-3.5 text-[var(--color-text-muted)]" />}
487
+ {selected && <CheckIcon className="pointer-events-none absolute right-2 size-3.5 text-[var(--color-text-default)]" />}
481
488
  </button>
482
489
  )
483
490
  }
package/src/index.ts CHANGED
@@ -9,6 +9,7 @@ export * from "./components/ui/alert"
9
9
  export * from "./components/ui/badge"
10
10
  export * from "./components/ui/breadcrumb"
11
11
  export * from "./components/ui/calendar"
12
+ export * from "./components/ui/date-time-picker"
12
13
  export * from "./components/ui/date-time-range-picker"
13
14
  export * from "./components/ui/cell"
14
15
  export * from "./components/ui/button"