@suphark/ui 0.18.0 → 0.20.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/CHANGELOG.md +47 -0
- package/package.json +14 -13
- package/scripts/audit.mjs +0 -0
- package/src/components/app-shell/app-shell.tsx +15 -9
- package/src/components/app-shell/index.ts +1 -0
- package/src/components/app-shell/mobile-tab-bar.tsx +104 -0
- package/src/components/shared/action-menu.tsx +155 -0
- package/src/components/shared/confirm-dialog.tsx +41 -2
- package/src/components/shared/count-badge.tsx +41 -0
- package/src/components/shared/filter-bar.tsx +108 -0
- package/src/components/shared/form/slider-field.tsx +79 -0
- package/src/components/shared/form-dialog.tsx +43 -4
- package/src/components/shared/month-stepper.tsx +124 -0
- package/src/components/shared/save-status.tsx +99 -0
- package/src/components/shared/segmented-control.tsx +73 -0
- package/src/components/shared/settings-layout.tsx +170 -0
- package/src/components/shared/settings-row.tsx +118 -0
- package/src/components/shared/setup-checklist.tsx +104 -0
- package/src/components/shared/simple-dialog.tsx +172 -0
- package/src/components/shared/simple-pagination.tsx +109 -0
- package/src/components/shared/simple-table.tsx +93 -0
- package/src/components/shared/simple-tabs.tsx +118 -0
- package/src/components/shared/simple-tooltip.tsx +87 -0
- package/src/components/shared/skip-link.tsx +30 -0
- package/src/components/shared/stat.tsx +110 -6
- package/src/components/shared/ui-text.tsx +35 -0
- package/src/components/shared/user-identity.tsx +61 -0
- package/src/components/ui/accordion.tsx +2 -2
- package/src/components/ui/alert-dialog.tsx +4 -4
- package/src/components/ui/alert.tsx +2 -2
- package/src/components/ui/attachment.tsx +9 -9
- package/src/components/ui/avatar.tsx +4 -4
- package/src/components/ui/badge.tsx +1 -1
- package/src/components/ui/breadcrumb.tsx +1 -1
- package/src/components/ui/bubble.tsx +123 -0
- package/src/components/ui/button-group.tsx +2 -2
- package/src/components/ui/button.tsx +6 -6
- package/src/components/ui/calendar.tsx +9 -9
- package/src/components/ui/card.tsx +3 -3
- package/src/components/ui/chart.tsx +2 -2
- package/src/components/ui/checkbox.tsx +1 -1
- package/src/components/ui/combobox.tsx +6 -6
- package/src/components/ui/command.tsx +4 -4
- package/src/components/ui/context-menu.tsx +7 -7
- package/src/components/ui/dialog.tsx +4 -4
- package/src/components/ui/direction.tsx +6 -0
- package/src/components/ui/drawer.tsx +10 -10
- package/src/components/ui/dropdown-menu.tsx +8 -8
- package/src/components/ui/empty.tsx +4 -4
- package/src/components/ui/field.tsx +8 -8
- package/src/components/ui/hover-card.tsx +1 -2
- package/src/components/ui/input-group.tsx +3 -3
- package/src/components/ui/input-otp.tsx +1 -1
- package/src/components/ui/input.tsx +1 -1
- package/src/components/ui/item.tsx +4 -4
- package/src/components/ui/kbd.tsx +1 -1
- package/src/components/ui/label.tsx +1 -1
- package/src/components/ui/marker.tsx +67 -0
- package/src/components/ui/menubar.tsx +9 -9
- package/src/components/ui/message-scroller.tsx +129 -0
- package/src/components/ui/message.tsx +84 -0
- package/src/components/ui/native-select.tsx +1 -1
- package/src/components/ui/navigation-menu.tsx +6 -6
- package/src/components/ui/popover.tsx +1 -1
- package/src/components/ui/progress.tsx +2 -3
- package/src/components/ui/questionnaire.tsx +314 -0
- package/src/components/ui/radio-group.tsx +1 -2
- package/src/components/ui/resizable.tsx +1 -1
- package/src/components/ui/select.tsx +4 -4
- package/src/components/ui/separator.tsx +0 -1
- package/src/components/ui/sheet.tsx +3 -3
- package/src/components/ui/sidebar.tsx +14 -14
- package/src/components/ui/switch.tsx +2 -3
- package/src/components/ui/textarea.tsx +1 -1
- package/src/components/ui/toast.tsx +221 -0
- package/src/components/ui/toggle-group.tsx +2 -2
- package/src/components/ui/toggle.tsx +1 -1
- package/src/components/ui/tooltip.tsx +0 -1
- package/src/hooks/use-confirm.tsx +2 -0
- package/src/index.ts +48 -1
- package/src/lib/month.ts +60 -0
- package/src/styles.css +10 -0
package/src/index.ts
CHANGED
|
@@ -14,6 +14,11 @@ export type { DateRange } from "react-day-picker";
|
|
|
14
14
|
// sonner: `toast()` คู่กับ <Toaster /> — แอปไม่ต้องติดตั้ง sonner เอง
|
|
15
15
|
export { toast } from "sonner";
|
|
16
16
|
export { ActionForm } from "./components/shared/action-form";
|
|
17
|
+
export {
|
|
18
|
+
ActionMenu,
|
|
19
|
+
type ActionMenuCommand,
|
|
20
|
+
type ActionMenuItem,
|
|
21
|
+
} from "./components/shared/action-menu";
|
|
17
22
|
export * from "./components/shared/button";
|
|
18
23
|
export {
|
|
19
24
|
type CalendarDayContext,
|
|
@@ -37,6 +42,7 @@ export {
|
|
|
37
42
|
type ConfirmSpec,
|
|
38
43
|
normalizeConfirm,
|
|
39
44
|
} from "./components/shared/confirm-dialog";
|
|
45
|
+
export { CountBadge } from "./components/shared/count-badge";
|
|
40
46
|
export { DataList, DataRow } from "./components/shared/data-list";
|
|
41
47
|
export { DateRangePicker } from "./components/shared/date/date-range-picker";
|
|
42
48
|
export { DescriptionList } from "./components/shared/description-list";
|
|
@@ -62,6 +68,7 @@ export { EmptyRow } from "./components/shared/empty-row";
|
|
|
62
68
|
export { EmptyState } from "./components/shared/empty-state";
|
|
63
69
|
export { EnvSnippet, randomSecret } from "./components/shared/env-snippet";
|
|
64
70
|
export { type FileKind, FileTypeIcon, getFileKind } from "./components/shared/file-type-icon";
|
|
71
|
+
export { FilterBar, type FilterBarFilter } from "./components/shared/filter-bar";
|
|
65
72
|
export { FormFieldBoolean } from "./components/shared/form/form-field-boolean";
|
|
66
73
|
export { FormFieldColorSelect } from "./components/shared/form/form-field-color-select";
|
|
67
74
|
export { FormFieldCombobox } from "./components/shared/form/form-field-combobox";
|
|
@@ -84,6 +91,7 @@ export {
|
|
|
84
91
|
type SimpleSelectOptions,
|
|
85
92
|
type SimpleSelectProps,
|
|
86
93
|
} from "./components/shared/form/simple-select";
|
|
94
|
+
export { SliderField, type SliderFieldProps } from "./components/shared/form/slider-field";
|
|
87
95
|
export {
|
|
88
96
|
type FormAction,
|
|
89
97
|
FormMessage,
|
|
@@ -107,6 +115,11 @@ export {
|
|
|
107
115
|
type LanguageSwitchProps,
|
|
108
116
|
} from "./components/shared/language/language-switch";
|
|
109
117
|
export { ErrorState, type RouteError } from "./components/shared/layout/error-state";
|
|
118
|
+
export {
|
|
119
|
+
MonthStepper,
|
|
120
|
+
type MonthStepperProps,
|
|
121
|
+
useMonthCursor,
|
|
122
|
+
} from "./components/shared/month-stepper";
|
|
110
123
|
export {
|
|
111
124
|
MultiSelectCombobox,
|
|
112
125
|
type MultiSelectComboboxProps,
|
|
@@ -136,10 +149,26 @@ export {
|
|
|
136
149
|
type RuleLeaf,
|
|
137
150
|
type RuleNot,
|
|
138
151
|
} from "./components/shared/rule-builder";
|
|
152
|
+
export { type SaveState, SaveStatus, type SaveStatusText } from "./components/shared/save-status";
|
|
139
153
|
export { SecretReveal } from "./components/shared/secret-reveal";
|
|
140
154
|
export { SectionCard } from "./components/shared/section-card";
|
|
155
|
+
export { SegmentedControl, type SegmentedOption } from "./components/shared/segmented-control";
|
|
141
156
|
export { SelectionButton } from "./components/shared/selection-button";
|
|
142
|
-
export {
|
|
157
|
+
export { SettingsLayout, type SettingsSection } from "./components/shared/settings-layout";
|
|
158
|
+
export { DangerZone, SettingsRow, SwitchRow } from "./components/shared/settings-row";
|
|
159
|
+
export { SetupChecklist, type SetupChecklistStep } from "./components/shared/setup-checklist";
|
|
160
|
+
export { SimpleDialog, SimpleSheet } from "./components/shared/simple-dialog";
|
|
161
|
+
export { paginationRange, SimplePagination } from "./components/shared/simple-pagination";
|
|
162
|
+
export { SimpleTable, type SimpleTableColumn } from "./components/shared/simple-table";
|
|
163
|
+
export {
|
|
164
|
+
SimpleAccordion,
|
|
165
|
+
type SimpleAccordionItem,
|
|
166
|
+
type SimpleTabItem,
|
|
167
|
+
SimpleTabs,
|
|
168
|
+
} from "./components/shared/simple-tabs";
|
|
169
|
+
export { SimplePopover, SimpleTooltip } from "./components/shared/simple-tooltip";
|
|
170
|
+
export { SkipLink } from "./components/shared/skip-link";
|
|
171
|
+
export { Stat, type StatDelta, StatGrid, type StatTone } from "./components/shared/stat";
|
|
143
172
|
export { StatusBadge, statusTone, type Tone } from "./components/shared/status-badge";
|
|
144
173
|
export { SwitcherChevron } from "./components/shared/switcher-chevron";
|
|
145
174
|
export { CodeBlock, type CodeBlockProps } from "./components/shared/text/code-block";
|
|
@@ -164,6 +193,7 @@ export {
|
|
|
164
193
|
type UploadListText,
|
|
165
194
|
type UploadStatus,
|
|
166
195
|
} from "./components/shared/upload-list";
|
|
196
|
+
export { UserIdentity, type UserIdentityProps } from "./components/shared/user-identity";
|
|
167
197
|
// ---------- shadcn/ui primitives ----------
|
|
168
198
|
export * from "./components/ui/accordion";
|
|
169
199
|
export * from "./components/ui/alert";
|
|
@@ -172,7 +202,9 @@ export * from "./components/ui/aspect-ratio";
|
|
|
172
202
|
export * from "./components/ui/attachment";
|
|
173
203
|
export * from "./components/ui/avatar";
|
|
174
204
|
export * from "./components/ui/badge";
|
|
205
|
+
// toast.tsx (Base UI) ไม่อยู่ใน barrel: ชื่อ toast/Toaster ชนกับ sonner ที่แพ็กเกจใช้ — import ตรงจาก @suphark/ui/components/ui/toast ถ้าต้องการ
|
|
175
206
|
export * from "./components/ui/breadcrumb";
|
|
207
|
+
export * from "./components/ui/bubble";
|
|
176
208
|
export * from "./components/ui/button";
|
|
177
209
|
export * from "./components/ui/button-group";
|
|
178
210
|
export * from "./components/ui/calendar";
|
|
@@ -185,6 +217,7 @@ export * from "./components/ui/command";
|
|
|
185
217
|
export * from "./components/ui/context-menu";
|
|
186
218
|
export * from "./components/ui/date-picker";
|
|
187
219
|
export * from "./components/ui/dialog";
|
|
220
|
+
export * from "./components/ui/direction";
|
|
188
221
|
export * from "./components/ui/drawer";
|
|
189
222
|
export * from "./components/ui/dropdown-menu";
|
|
190
223
|
export * from "./components/ui/empty";
|
|
@@ -197,12 +230,16 @@ export * from "./components/ui/input-otp";
|
|
|
197
230
|
export * from "./components/ui/item";
|
|
198
231
|
export * from "./components/ui/kbd";
|
|
199
232
|
export * from "./components/ui/label";
|
|
233
|
+
export * from "./components/ui/marker";
|
|
200
234
|
export * from "./components/ui/menubar";
|
|
235
|
+
export * from "./components/ui/message";
|
|
236
|
+
export * from "./components/ui/message-scroller";
|
|
201
237
|
export * from "./components/ui/native-select";
|
|
202
238
|
export * from "./components/ui/navigation-menu";
|
|
203
239
|
export * from "./components/ui/pagination";
|
|
204
240
|
export * from "./components/ui/popover";
|
|
205
241
|
export * from "./components/ui/progress";
|
|
242
|
+
export * from "./components/ui/questionnaire";
|
|
206
243
|
export * from "./components/ui/radio-group";
|
|
207
244
|
export * from "./components/ui/relative-date";
|
|
208
245
|
export * from "./components/ui/resizable";
|
|
@@ -233,6 +270,16 @@ export { useTrackedState } from "./hooks/use-tracked-state";
|
|
|
233
270
|
export { copyText, selectContents } from "./lib/copy-text";
|
|
234
271
|
export { formatBytes, formatRelativeThaiDate, formatThaiFullDate } from "./lib/formatters";
|
|
235
272
|
export { getDateTimeFormat, getNumberFormat } from "./lib/intl-cache";
|
|
273
|
+
export {
|
|
274
|
+
compareMonth,
|
|
275
|
+
currentMonthKey,
|
|
276
|
+
formatMonthKey,
|
|
277
|
+
isMonthKey,
|
|
278
|
+
type MonthKey,
|
|
279
|
+
parseMonthKey,
|
|
280
|
+
shiftMonth,
|
|
281
|
+
toMonthKey,
|
|
282
|
+
} from "./lib/month";
|
|
236
283
|
export {
|
|
237
284
|
type AtomicPermissionRequirement,
|
|
238
285
|
type CheckPermissionOptions,
|
package/src/lib/month.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { getDateTimeFormat } from "./intl-cache";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* เดือนแบบ `"YYYY-MM"` (รูปแบบเดียวกับ `CalendarMonthGrid month`) — ไม่มีวัน/เวลา จึงไม่มีปัญหาโซนเวลา
|
|
5
|
+
* ยกจาก DueBell `CycleMonth` ให้แอปบัญชี/รายงานใช้ร่วม
|
|
6
|
+
*/
|
|
7
|
+
export type MonthKey = string;
|
|
8
|
+
|
|
9
|
+
const MONTH_KEY = /^(\d{4})-(\d{2})$/;
|
|
10
|
+
|
|
11
|
+
/** แยก `"YYYY-MM"` → ปี + เดือน (0–11); รูปแบบผิด = throw (ค่าจาก URL ให้เช็กด้วย `isMonthKey` ก่อน) */
|
|
12
|
+
export function parseMonthKey(key: MonthKey): { year: number; monthIndex: number } {
|
|
13
|
+
const m = MONTH_KEY.exec(key);
|
|
14
|
+
const monthIndex = m ? Number(m[2]) - 1 : Number.NaN;
|
|
15
|
+
if (!m || monthIndex < 0 || monthIndex > 11) {
|
|
16
|
+
throw new Error(`month ต้องเป็น "YYYY-MM" ได้ "${key}"`);
|
|
17
|
+
}
|
|
18
|
+
return { year: Number(m[1]), monthIndex };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function isMonthKey(value: unknown): value is MonthKey {
|
|
22
|
+
if (typeof value !== "string") return false;
|
|
23
|
+
const m = MONTH_KEY.exec(value);
|
|
24
|
+
return !!m && Number(m[2]) >= 1 && Number(m[2]) <= 12;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Date → `"YYYY-MM"` ตามเวลาท้องถิ่นของเครื่อง */
|
|
28
|
+
export function toMonthKey(date: Date): MonthKey {
|
|
29
|
+
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function currentMonthKey(now: Date = new Date()): MonthKey {
|
|
33
|
+
return toMonthKey(now);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** เลื่อนเดือน (ลบ = ย้อนหลัง) ข้ามปีให้เอง: shiftMonth("2026-01", -1) → "2025-12" */
|
|
37
|
+
export function shiftMonth(key: MonthKey, by: number): MonthKey {
|
|
38
|
+
const { year, monthIndex } = parseMonthKey(key);
|
|
39
|
+
return toMonthKey(new Date(year, monthIndex + by, 1));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** เทียบเดือน: < 0 = a ก่อน b (เทียบเป็นสตริงได้เพราะเติม 0 แล้ว) */
|
|
43
|
+
export function compareMonth(a: MonthKey, b: MonthKey): number {
|
|
44
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* ชื่อเดือนสำหรับแสดง — `th-TH` ได้ปี พ.ศ. ตาม Intl (`"ตุลาคม 2569"`), `en-US` ได้ ค.ศ.
|
|
49
|
+
* ต้องการ ค.ศ. ในภาษาไทย ใช้ locale `"th-TH-u-ca-gregory"`
|
|
50
|
+
*/
|
|
51
|
+
export function formatMonthKey(
|
|
52
|
+
key: MonthKey,
|
|
53
|
+
locale = "th-TH",
|
|
54
|
+
style: "long" | "short" = "long",
|
|
55
|
+
): string {
|
|
56
|
+
const { year, monthIndex } = parseMonthKey(key);
|
|
57
|
+
return getDateTimeFormat(locale, { month: style, year: "numeric" }).format(
|
|
58
|
+
new Date(year, monthIndex, 1),
|
|
59
|
+
);
|
|
60
|
+
}
|
package/src/styles.css
CHANGED
|
@@ -282,6 +282,16 @@
|
|
|
282
282
|
}
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
+
/* ขอบล่างของจอ iPhone (home indicator) — แถบที่ fixed ติดล่าง เช่น MobileTabBar */
|
|
286
|
+
@utility pb-safe {
|
|
287
|
+
padding-bottom: env(safe-area-inset-bottom, 0px);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/* เว้นที่ใต้เนื้อหาให้พ้น MobileTabBar (สูง ~4rem + safe-area) — AppShell mobileTabs ใส่ให้เอง */
|
|
291
|
+
@utility pb-tab-bar {
|
|
292
|
+
padding-bottom: calc(5rem + env(safe-area-inset-bottom, 0px));
|
|
293
|
+
}
|
|
294
|
+
|
|
285
295
|
@utility scrollbar-thin {
|
|
286
296
|
scrollbar-width: thin;
|
|
287
297
|
scrollbar-color: var(--scrollbar-thumb) transparent;
|