@craftzbay/ui 0.10.0 → 0.11.1
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/README.md +18 -12
- package/dist-lib/__tests__/helpers/color.d.ts +9 -0
- package/dist-lib/__tests__/helpers/theme.d.ts +18 -0
- package/dist-lib/components/ui/Accordion.js +18 -7
- package/dist-lib/components/ui/Accordion.js.map +1 -1
- package/dist-lib/components/ui/Alert.d.ts +16 -0
- package/dist-lib/components/ui/Alert.js +47 -34
- package/dist-lib/components/ui/Alert.js.map +1 -1
- package/dist-lib/components/ui/Avatar.d.ts +1 -1
- package/dist-lib/components/ui/Avatar.js +45 -47
- package/dist-lib/components/ui/Avatar.js.map +1 -1
- package/dist-lib/components/ui/Badge.d.ts +3 -1
- package/dist-lib/components/ui/Badge.js +24 -15
- package/dist-lib/components/ui/Badge.js.map +1 -1
- package/dist-lib/components/ui/Breadcrumbs.d.ts +2 -0
- package/dist-lib/components/ui/Breadcrumbs.js +46 -28
- package/dist-lib/components/ui/Breadcrumbs.js.map +1 -1
- package/dist-lib/components/ui/Button.d.ts +5 -3
- package/dist-lib/components/ui/Button.js +59 -45
- package/dist-lib/components/ui/Button.js.map +1 -1
- package/dist-lib/components/ui/Calendar.d.ts +1 -1
- package/dist-lib/components/ui/Calendar.js +87 -59
- package/dist-lib/components/ui/Calendar.js.map +1 -1
- package/dist-lib/components/ui/Card.d.ts +2 -0
- package/dist-lib/components/ui/Card.js +48 -67
- package/dist-lib/components/ui/Card.js.map +1 -1
- package/dist-lib/components/ui/Carousel.d.ts +6 -6
- package/dist-lib/components/ui/Carousel.js +133 -102
- package/dist-lib/components/ui/Carousel.js.map +1 -1
- package/dist-lib/components/ui/Chart.d.ts +49 -10
- package/dist-lib/components/ui/Chart.js +415 -181
- package/dist-lib/components/ui/Chart.js.map +1 -1
- package/dist-lib/components/ui/Checkbox.js +42 -28
- package/dist-lib/components/ui/Checkbox.js.map +1 -1
- package/dist-lib/components/ui/Combobox.d.ts +2 -0
- package/dist-lib/components/ui/Combobox.js +142 -111
- package/dist-lib/components/ui/Combobox.js.map +1 -1
- package/dist-lib/components/ui/CommandPalette.d.ts +6 -3
- package/dist-lib/components/ui/CommandPalette.js +92 -87
- package/dist-lib/components/ui/CommandPalette.js.map +1 -1
- package/dist-lib/components/ui/ContextMenu.d.ts +7 -2
- package/dist-lib/components/ui/ContextMenu.js +77 -62
- package/dist-lib/components/ui/ContextMenu.js.map +1 -1
- package/dist-lib/components/ui/DataGrid.d.ts +17 -4
- package/dist-lib/components/ui/DataGrid.js +65 -50
- package/dist-lib/components/ui/DataGrid.js.map +1 -1
- package/dist-lib/components/ui/DatePicker.js +118 -99
- package/dist-lib/components/ui/DatePicker.js.map +1 -1
- package/dist-lib/components/ui/DesignSystemProvider.d.ts +94 -40
- package/dist-lib/components/ui/DesignSystemProvider.js +111 -55
- package/dist-lib/components/ui/DesignSystemProvider.js.map +1 -1
- package/dist-lib/components/ui/Dialog.d.ts +18 -3
- package/dist-lib/components/ui/Dialog.js +105 -80
- package/dist-lib/components/ui/Dialog.js.map +1 -1
- package/dist-lib/components/ui/Drawer.d.ts +17 -2
- package/dist-lib/components/ui/Drawer.js +89 -55
- package/dist-lib/components/ui/Drawer.js.map +1 -1
- package/dist-lib/components/ui/DropdownMenu.js +14 -9
- package/dist-lib/components/ui/DropdownMenu.js.map +1 -1
- package/dist-lib/components/ui/EmptyState.d.ts +2 -0
- package/dist-lib/components/ui/EmptyState.js +30 -16
- package/dist-lib/components/ui/EmptyState.js.map +1 -1
- package/dist-lib/components/ui/ErrorState.d.ts +13 -2
- package/dist-lib/components/ui/ErrorState.js +44 -23
- package/dist-lib/components/ui/ErrorState.js.map +1 -1
- package/dist-lib/components/ui/FileUpload.js +59 -56
- package/dist-lib/components/ui/FileUpload.js.map +1 -1
- package/dist-lib/components/ui/Form.d.ts +15 -2
- package/dist-lib/components/ui/Form.js +97 -71
- package/dist-lib/components/ui/Form.js.map +1 -1
- package/dist-lib/components/ui/Icon.d.ts +1 -1
- package/dist-lib/components/ui/Icon.js +20 -14
- package/dist-lib/components/ui/Icon.js.map +1 -1
- package/dist-lib/components/ui/IconButton.d.ts +2 -2
- package/dist-lib/components/ui/IconButton.js +28 -20
- package/dist-lib/components/ui/IconButton.js.map +1 -1
- package/dist-lib/components/ui/Input.d.ts +3 -1
- package/dist-lib/components/ui/Input.js +102 -79
- package/dist-lib/components/ui/Input.js.map +1 -1
- package/dist-lib/components/ui/Kbd.js +1 -1
- package/dist-lib/components/ui/Kbd.js.map +1 -1
- package/dist-lib/components/ui/MultiSelect.js +121 -107
- package/dist-lib/components/ui/MultiSelect.js.map +1 -1
- package/dist-lib/components/ui/Pagination.js +67 -62
- package/dist-lib/components/ui/Pagination.js.map +1 -1
- package/dist-lib/components/ui/Popover.js +14 -14
- package/dist-lib/components/ui/Popover.js.map +1 -1
- package/dist-lib/components/ui/Progress.d.ts +3 -3
- package/dist-lib/components/ui/Progress.js +77 -72
- package/dist-lib/components/ui/Progress.js.map +1 -1
- package/dist-lib/components/ui/RadioGroup.d.ts +1 -1
- package/dist-lib/components/ui/RadioGroup.js +69 -52
- package/dist-lib/components/ui/RadioGroup.js.map +1 -1
- package/dist-lib/components/ui/RelativeTime.d.ts +19 -0
- package/dist-lib/components/ui/RelativeTime.js +31 -0
- package/dist-lib/components/ui/RelativeTime.js.map +1 -0
- package/dist-lib/components/ui/ScrollArea.d.ts +9 -1
- package/dist-lib/components/ui/ScrollArea.js +43 -27
- package/dist-lib/components/ui/ScrollArea.js.map +1 -1
- package/dist-lib/components/ui/Select.d.ts +6 -1
- package/dist-lib/components/ui/Select.js +79 -71
- package/dist-lib/components/ui/Select.js.map +1 -1
- package/dist-lib/components/ui/Separator.js +1 -1
- package/dist-lib/components/ui/Separator.js.map +1 -1
- package/dist-lib/components/ui/Sheet.d.ts +9 -0
- package/dist-lib/components/ui/Sheet.js +69 -46
- package/dist-lib/components/ui/Sheet.js.map +1 -1
- package/dist-lib/components/ui/Sidebar.d.ts +12 -9
- package/dist-lib/components/ui/Sidebar.js +152 -109
- package/dist-lib/components/ui/Sidebar.js.map +1 -1
- package/dist-lib/components/ui/Skeleton.d.ts +13 -2
- package/dist-lib/components/ui/Skeleton.js +15 -14
- package/dist-lib/components/ui/Skeleton.js.map +1 -1
- package/dist-lib/components/ui/Slider.js +41 -29
- package/dist-lib/components/ui/Slider.js.map +1 -1
- package/dist-lib/components/ui/Snackbar.js +23 -22
- package/dist-lib/components/ui/Snackbar.js.map +1 -1
- package/dist-lib/components/ui/Spinner.js +18 -6
- package/dist-lib/components/ui/Spinner.js.map +1 -1
- package/dist-lib/components/ui/Stepper.d.ts +6 -0
- package/dist-lib/components/ui/Stepper.js +71 -48
- package/dist-lib/components/ui/Stepper.js.map +1 -1
- package/dist-lib/components/ui/Switch.js +46 -43
- package/dist-lib/components/ui/Switch.js.map +1 -1
- package/dist-lib/components/ui/Table.d.ts +33 -5
- package/dist-lib/components/ui/Table.js +141 -119
- package/dist-lib/components/ui/Table.js.map +1 -1
- package/dist-lib/components/ui/Tabs.js +50 -48
- package/dist-lib/components/ui/Tabs.js.map +1 -1
- package/dist-lib/components/ui/TagInput.js +45 -45
- package/dist-lib/components/ui/TagInput.js.map +1 -1
- package/dist-lib/components/ui/Textarea.js +65 -54
- package/dist-lib/components/ui/Textarea.js.map +1 -1
- package/dist-lib/components/ui/Timeline.js +39 -35
- package/dist-lib/components/ui/Timeline.js.map +1 -1
- package/dist-lib/components/ui/Toast.js +44 -57
- package/dist-lib/components/ui/Toast.js.map +1 -1
- package/dist-lib/components/ui/Tooltip.d.ts +4 -1
- package/dist-lib/components/ui/Tooltip.js +24 -22
- package/dist-lib/components/ui/Tooltip.js.map +1 -1
- package/dist-lib/components/ui/TopNav.d.ts +7 -3
- package/dist-lib/components/ui/TopNav.js +39 -22
- package/dist-lib/components/ui/TopNav.js.map +1 -1
- package/dist-lib/components/ui/Tree.d.ts +15 -10
- package/dist-lib/components/ui/Tree.js +82 -79
- package/dist-lib/components/ui/Tree.js.map +1 -1
- package/dist-lib/hooks/use-debounce.d.ts +19 -0
- package/dist-lib/hooks/use-debounce.js +36 -0
- package/dist-lib/hooks/use-debounce.js.map +1 -0
- package/dist-lib/hooks/use-delayed-loading.d.ts +21 -0
- package/dist-lib/hooks/use-delayed-loading.js +20 -0
- package/dist-lib/hooks/use-delayed-loading.js.map +1 -0
- package/dist-lib/hooks/use-field-ids.d.ts +2 -1
- package/dist-lib/hooks/use-field-ids.js +9 -9
- package/dist-lib/hooks/use-field-ids.js.map +1 -1
- package/dist-lib/hooks/use-media-query.d.ts +3 -1
- package/dist-lib/hooks/use-media-query.js +16 -12
- package/dist-lib/hooks/use-media-query.js.map +1 -1
- package/dist-lib/hooks/use-modifier-key.d.ts +13 -0
- package/dist-lib/hooks/use-modifier-key.js +19 -0
- package/dist-lib/hooks/use-modifier-key.js.map +1 -0
- package/dist-lib/hooks/use-toast.d.ts +7 -2
- package/dist-lib/hooks/use-toast.js +61 -30
- package/dist-lib/hooks/use-toast.js.map +1 -1
- package/dist-lib/icons/index.d.ts +9 -0
- package/dist-lib/icons/index.js +148 -130
- package/dist-lib/icons/index.js.map +1 -1
- package/dist-lib/illustrations/index.d.ts +1 -0
- package/dist-lib/illustrations/index.js +15 -6
- package/dist-lib/illustrations/index.js.map +1 -1
- package/dist-lib/index.d.ts +6 -0
- package/dist-lib/index.js +280 -260
- package/dist-lib/index.js.map +1 -1
- package/dist-lib/lib/format.d.ts +65 -0
- package/dist-lib/lib/format.js +95 -0
- package/dist-lib/lib/format.js.map +1 -0
- package/dist-lib/lib/return-focus.d.ts +11 -0
- package/dist-lib/lib/return-focus.js +12 -0
- package/dist-lib/lib/return-focus.js.map +1 -0
- package/dist-lib/lib/strings.d.ts +62 -1
- package/dist-lib/lib/strings.js +75 -19
- package/dist-lib/lib/strings.js.map +1 -1
- package/dist-lib/lib/strings.mn.js +50 -5
- package/dist-lib/lib/strings.mn.js.map +1 -1
- package/dist-lib/styles.css +1 -1
- package/dist-lib/theme.css +141 -78
- package/package.json +11 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Pagination.js","sources":["../../../src/components/ui/Pagination.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, useId, useMemo, type HTMLAttributes } from 'react';\nimport { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { defaultStrings, formatString, type UiStrings } from '@/lib/strings';\nimport { Select, SelectContent, SelectItem, SelectTrigger } from './Select';\n\nexport interface PaginationLabels {\n /** Summary line. Receives the computed range. */\n showing: (from: number, to: number, total: number) => string;\n /** sr-only label for the page-size select. */\n rowsPerPage: string;\n first: string;\n last: string;\n prev: string;\n next: string;\n /** aria-label for a numbered page button. */\n page: (n: number) => string;\n /** Suffix in the page-size options, e.g. \"20 / page\". */\n perPage: (n: number) => string;\n /** aria-label of the nav landmark. */\n nav: string;\n}\n\n/** Build the label set from a strings object (context → functions). */\nexport function paginationLabelsFromStrings(s: UiStrings['pagination']): PaginationLabels {\n return {\n showing: (from, to, total) => formatString(s.showing, { from, to, total }),\n rowsPerPage: s.rowsPerPage,\n first: s.first,\n last: s.last,\n prev: s.prev,\n next: s.next,\n page: (n) => formatString(s.page, { n }),\n perPage: (n) => formatString(s.perPage, { n }),\n nav: s.nav,\n };\n}\n\n/** English defaults — derived from `defaultStrings.pagination`. */\nexport const defaultPaginationLabels: PaginationLabels = paginationLabelsFromStrings(\n defaultStrings.pagination,\n);\n\nexport interface PaginationProps extends HTMLAttributes<HTMLElement> {\n /** 1-indexed current page. */\n page: number;\n /** Total number of pages. Set to 0 to hide page numbers. */\n pageCount: number;\n /** Called with the new page when navigating. */\n onPageChange: (page: number) => void;\n /** Total item count, for the \"Showing 1-20 of 200\" hint. Omit to hide. */\n totalItems?: number;\n /** Items shown per page (controlled if `onPageSizeChange` is provided). */\n pageSize?: number;\n /** Options for the page-size select. */\n pageSizeOptions?: number[];\n /** Called when the user picks a new page size. */\n onPageSizeChange?: (size: number) => void;\n /** Show first/last (« ») jump buttons. Default true. */\n showJump?: boolean;\n /** Override any of the visible / accessible strings (i18n). */\n labels?: Partial<PaginationLabels>;\n}\n\nfunction pageRange(current: number, total: number, max = 7): (number | 'gap')[] {\n if (total <= max) return Array.from({ length: total }, (_, i) => i + 1);\n const window = 1;\n const result: (number | 'gap')[] = [];\n const start = Math.max(2, current - window);\n const end = Math.min(total - 1, current + window);\n\n result.push(1);\n if (start > 2) result.push('gap');\n for (let i = start; i <= end; i++) result.push(i);\n if (end < total - 1) result.push('gap');\n result.push(total);\n return result;\n}\n\n/**\n * Numbered pagination with prev/next, first/last jumps, page-size selector,\n * and item-count summary.\n *\n * @example\n * <Pagination page={page} pageCount={20} onPageChange={setPage}\n * totalItems={400} pageSize={20}\n * pageSizeOptions={[10, 20, 50]} onPageSizeChange={setSize} />\n *\n * @do Place the count summary on the left and controls on the right.\n * @dont Show numbers when there are >100 pages — use a \"jump to\" input instead.\n */\nexport const Pagination = forwardRef<HTMLElement, PaginationProps>(function Pagination(\n {\n page,\n pageCount,\n onPageChange,\n totalItems,\n pageSize,\n pageSizeOptions,\n onPageSizeChange,\n showJump = true,\n labels: labelsProp,\n className,\n 'aria-label': ariaLabel,\n ...props\n },\n ref,\n) {\n const strings = useStrings();\n const labels = { ...paginationLabelsFromStrings(strings.pagination), ...labelsProp };\n const pageSizeId = useId();\n const pages = useMemo(() => pageRange(page, pageCount), [page, pageCount]);\n\n const from = pageSize ? (page - 1) * pageSize + 1 : undefined;\n const to = pageSize && totalItems ? Math.min(page * pageSize, totalItems) : undefined;\n\n const goto = (p: number) => {\n if (p < 1 || p > pageCount || p === page) return;\n onPageChange(p);\n };\n\n return (\n <nav\n ref={ref}\n aria-label={ariaLabel ?? labels.nav}\n className={cn('flex flex-wrap items-center justify-between gap-3', className)}\n {...props}\n >\n <div className=\"text-foreground-muted flex items-center gap-3 text-sm\">\n {totalItems !== undefined &&\n pageSize !== undefined &&\n from !== undefined &&\n to !== undefined && (\n <span className=\"tabular\">{labels.showing(from, to, totalItems)}</span>\n )}\n {pageSizeOptions && onPageSizeChange && pageSize !== undefined && (\n <div className=\"flex items-center gap-2\">\n <label htmlFor={pageSizeId} className=\"sr-only\">\n {labels.rowsPerPage}\n </label>\n <Select value={String(pageSize)} onValueChange={(v) => onPageSizeChange(Number(v))}>\n <SelectTrigger id={pageSizeId} size=\"sm\" className=\"w-[7.5rem] whitespace-nowrap\" />\n <SelectContent>\n {pageSizeOptions.map((s) => (\n <SelectItem key={s} value={String(s)}>\n {labels.perPage(s)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n </div>\n\n <ul className=\"flex items-center gap-1\">\n {showJump && (\n <li>\n <button\n type=\"button\"\n aria-label={labels.first}\n disabled={page === 1}\n onClick={() => goto(1)}\n className={navButtonClass}\n >\n <ChevronsLeft className=\"size-4\" aria-hidden />\n </button>\n </li>\n )}\n <li>\n <button\n type=\"button\"\n aria-label={labels.prev}\n disabled={page === 1}\n onClick={() => goto(page - 1)}\n className={navButtonClass}\n >\n <ChevronLeft className=\"size-4\" aria-hidden />\n </button>\n </li>\n {pages.map((p, i) =>\n p === 'gap' ? (\n <li key={`gap-${i}`} className=\"text-foreground-subtle px-2\">\n …\n </li>\n ) : (\n <li key={p}>\n <button\n type=\"button\"\n aria-label={labels.page(p)}\n aria-current={p === page ? 'page' : undefined}\n onClick={() => goto(p)}\n className={cn(\n 'tabular inline-flex size-8 items-center justify-center rounded-md text-sm outline-none',\n 'transition-colors duration-[var(--duration-fast)]',\n 'focus-visible:ring-ring focus-visible:ring-offset-background focus-visible:ring-2 focus-visible:ring-offset-2',\n p === page\n ? 'bg-accent text-on-accent font-medium'\n : 'text-foreground-muted hover:bg-background-muted hover:text-foreground',\n )}\n >\n {p}\n </button>\n </li>\n ),\n )}\n <li>\n <button\n type=\"button\"\n aria-label={labels.next}\n disabled={page === pageCount}\n onClick={() => goto(page + 1)}\n className={navButtonClass}\n >\n <ChevronRight className=\"size-4\" aria-hidden />\n </button>\n </li>\n {showJump && (\n <li>\n <button\n type=\"button\"\n aria-label={labels.last}\n disabled={page === pageCount}\n onClick={() => goto(pageCount)}\n className={navButtonClass}\n >\n <ChevronsRight className=\"size-4\" aria-hidden />\n </button>\n </li>\n )}\n </ul>\n </nav>\n );\n});\nPagination.displayName = 'Pagination';\n\nconst navButtonClass = cn(\n 'inline-flex size-8 items-center justify-center rounded-md text-foreground-muted',\n 'transition-colors duration-[var(--duration-fast)]',\n 'hover:bg-background-muted hover:text-foreground',\n 'disabled:opacity-50 disabled:pointer-events-none',\n 'outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',\n);\n"],"names":["paginationLabelsFromStrings","s","from","to","total","formatString","n","defaultPaginationLabels","defaultStrings","pageRange","current","max","_","i","window","result","start","end","Pagination","forwardRef","page","pageCount","onPageChange","totalItems","pageSize","pageSizeOptions","onPageSizeChange","showJump","labelsProp","className","ariaLabel","props","ref","strings","useStrings","labels","pageSizeId","useId","pages","useMemo","goto","p","jsxs","cn","jsx","Select","v","SelectTrigger","SelectContent","SelectItem","navButtonClass","ChevronsLeft","ChevronLeft","ChevronRight","ChevronsRight"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Pagination.js","sources":["../../../src/components/ui/Pagination.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, useId, useMemo, type HTMLAttributes } from 'react';\nimport { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { defaultStrings, formatString, type UiStrings } from '@/lib/strings';\nimport { Select, SelectContent, SelectItem, SelectTrigger } from './Select';\n\nexport interface PaginationLabels {\n /** Summary line. Receives the computed range. */\n showing: (from: number, to: number, total: number) => string;\n /** sr-only label for the page-size select. */\n rowsPerPage: string;\n first: string;\n last: string;\n prev: string;\n next: string;\n /** aria-label for a numbered page button. */\n page: (n: number) => string;\n /** Suffix in the page-size options, e.g. \"20 / page\". */\n perPage: (n: number) => string;\n /** aria-label of the nav landmark. */\n nav: string;\n}\n\n/** Build the label set from a strings object (context → functions). */\nexport function paginationLabelsFromStrings(s: UiStrings['pagination']): PaginationLabels {\n return {\n showing: (from, to, total) => formatString(s.showing, { from, to, total }),\n rowsPerPage: s.rowsPerPage,\n first: s.first,\n last: s.last,\n prev: s.prev,\n next: s.next,\n page: (n) => formatString(s.page, { n }),\n perPage: (n) => formatString(s.perPage, { n }),\n nav: s.nav,\n };\n}\n\n/** English defaults — derived from `defaultStrings.pagination`. */\nexport const defaultPaginationLabels: PaginationLabels = paginationLabelsFromStrings(\n defaultStrings.pagination,\n);\n\nexport interface PaginationProps extends HTMLAttributes<HTMLElement> {\n /** 1-indexed current page. */\n page: number;\n /** Total number of pages. Set to 0 to hide page numbers. */\n pageCount: number;\n /** Called with the new page when navigating. */\n onPageChange: (page: number) => void;\n /** Total item count, for the \"Showing 1-20 of 200\" hint. Omit to hide. */\n totalItems?: number;\n /** Items shown per page (controlled if `onPageSizeChange` is provided). */\n pageSize?: number;\n /** Options for the page-size select. */\n pageSizeOptions?: number[];\n /** Called when the user picks a new page size. */\n onPageSizeChange?: (size: number) => void;\n /** Show first/last (« ») jump buttons. Default true. */\n showJump?: boolean;\n /** Override any of the visible / accessible strings (i18n). */\n labels?: Partial<PaginationLabels>;\n}\n\nfunction pageRange(current: number, total: number, max = 7): (number | 'gap')[] {\n if (total <= max) return Array.from({ length: total }, (_, i) => i + 1);\n const window = 1;\n const result: (number | 'gap')[] = [];\n const start = Math.max(2, current - window);\n const end = Math.min(total - 1, current + window);\n\n result.push(1);\n if (start > 2) result.push('gap');\n for (let i = start; i <= end; i++) result.push(i);\n if (end < total - 1) result.push('gap');\n result.push(total);\n return result;\n}\n\n/**\n * Numbered pagination with prev/next, first/last jumps, page-size selector,\n * and item-count summary.\n *\n * @example\n * <Pagination page={page} pageCount={20} onPageChange={setPage}\n * totalItems={400} pageSize={20}\n * pageSizeOptions={[10, 20, 50]} onPageSizeChange={setSize} />\n *\n * @do Place the count summary on the left and controls on the right.\n * @dont Show numbers when there are >100 pages — use a \"jump to\" input instead.\n */\nexport const Pagination = forwardRef<HTMLElement, PaginationProps>(function Pagination(\n {\n page,\n pageCount,\n onPageChange,\n totalItems,\n pageSize,\n pageSizeOptions,\n onPageSizeChange,\n showJump = true,\n labels: labelsProp,\n className,\n 'aria-label': ariaLabel,\n ...props\n },\n ref,\n) {\n const strings = useStrings();\n const labels = { ...paginationLabelsFromStrings(strings.pagination), ...labelsProp };\n const pageSizeId = useId();\n const pages = useMemo(() => pageRange(page, pageCount), [page, pageCount]);\n\n const empty = !totalItems || pageCount <= 0;\n const from = pageSize === undefined ? undefined : empty ? 0 : (page - 1) * pageSize + 1;\n const to =\n pageSize === undefined || totalItems === undefined\n ? undefined\n : empty\n ? 0\n : Math.min(page * pageSize, totalItems);\n const atStart = page <= 1 || pageCount <= 0;\n const atEnd = page >= pageCount;\n\n const goto = (p: number) => {\n if (p < 1 || p > pageCount || p === page) return;\n onPageChange(p);\n };\n\n return (\n <nav\n ref={ref}\n aria-label={ariaLabel ?? labels.nav}\n className={cn('flex flex-wrap items-center justify-between gap-3', className)}\n {...props}\n >\n <div className=\"text-foreground-muted flex items-center gap-3 text-sm\">\n {totalItems !== undefined &&\n pageSize !== undefined &&\n from !== undefined &&\n to !== undefined && (\n <span className=\"tabular\">{labels.showing(from, to, totalItems)}</span>\n )}\n {pageSizeOptions && onPageSizeChange && pageSize !== undefined && (\n <div className=\"flex items-center gap-2\">\n <label htmlFor={pageSizeId} className=\"sr-only\">\n {labels.rowsPerPage}\n </label>\n <Select value={String(pageSize)} onValueChange={(v) => onPageSizeChange(Number(v))}>\n <SelectTrigger id={pageSizeId} size=\"sm\" className=\"w-[7.5rem] whitespace-nowrap\" />\n <SelectContent>\n {pageSizeOptions.map((s) => (\n <SelectItem key={s} value={String(s)}>\n {labels.perPage(s)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n )}\n </div>\n\n <ul className=\"flex items-center gap-1\">\n {showJump && (\n <li className=\"hidden sm:block\">\n <button\n type=\"button\"\n aria-label={labels.first}\n disabled={atStart}\n onClick={() => goto(1)}\n className={navButtonClass}\n >\n <ChevronsLeft className=\"size-4\" aria-hidden />\n </button>\n </li>\n )}\n <li>\n <button\n type=\"button\"\n aria-label={labels.prev}\n disabled={atStart}\n onClick={() => goto(page - 1)}\n className={navButtonClass}\n >\n <ChevronLeft className=\"size-4\" aria-hidden />\n </button>\n </li>\n {/* Below sm the page list collapses to \"current / total\". */}\n <li className=\"tabular text-foreground-muted px-2 text-sm sm:hidden\" aria-current=\"page\">\n {page} / {pageCount}\n </li>\n {pages.map((p, i) =>\n p === 'gap' ? (\n <li key={`gap-${i}`} className=\"text-foreground-subtle hidden px-2 sm:block\">\n …\n </li>\n ) : (\n <li key={p} className=\"hidden sm:block\">\n <button\n type=\"button\"\n aria-label={labels.page(p)}\n aria-current={p === page ? 'page' : undefined}\n onClick={() => goto(p)}\n className={cn(\n 'tabular inline-flex size-8 items-center justify-center rounded-md text-sm outline-none',\n 'transition-colors duration-[var(--duration-fast)]',\n 'focus-visible:ring-ring focus-visible:ring-offset-background focus-visible:ring-2 focus-visible:ring-offset-2',\n p === page\n ? 'bg-accent text-on-accent font-medium'\n : 'text-foreground-muted hover:bg-background-muted hover:text-foreground',\n )}\n >\n {p}\n </button>\n </li>\n ),\n )}\n <li>\n <button\n type=\"button\"\n aria-label={labels.next}\n disabled={atEnd}\n onClick={() => goto(page + 1)}\n className={navButtonClass}\n >\n <ChevronRight className=\"size-4\" aria-hidden />\n </button>\n </li>\n {showJump && (\n <li className=\"hidden sm:block\">\n <button\n type=\"button\"\n aria-label={labels.last}\n disabled={atEnd}\n onClick={() => goto(pageCount)}\n className={navButtonClass}\n >\n <ChevronsRight className=\"size-4\" aria-hidden />\n </button>\n </li>\n )}\n </ul>\n </nav>\n );\n});\nPagination.displayName = 'Pagination';\n\nconst navButtonClass = cn(\n 'inline-flex size-8 items-center justify-center rounded-md text-foreground-muted',\n 'transition-colors duration-[var(--duration-fast)]',\n 'hover:bg-background-muted hover:text-foreground',\n 'disabled:opacity-50 disabled:pointer-events-none',\n 'outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',\n);\n"],"names":["paginationLabelsFromStrings","s","from","to","total","formatString","n","defaultPaginationLabels","defaultStrings","pageRange","current","max","_","i","window","result","start","end","Pagination","forwardRef","page","pageCount","onPageChange","totalItems","pageSize","pageSizeOptions","onPageSizeChange","showJump","labelsProp","className","ariaLabel","props","ref","strings","useStrings","labels","pageSizeId","useId","pages","useMemo","empty","atStart","atEnd","goto","p","jsxs","cn","jsx","Select","v","SelectTrigger","SelectContent","SelectItem","navButtonClass","ChevronsLeft","ChevronLeft","ChevronRight","ChevronsRight"],"mappings":"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"}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as
|
|
3
|
-
import { forwardRef as
|
|
2
|
+
import { jsx as e } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef as s } from "react";
|
|
4
4
|
import * as o from "@radix-ui/react-popover";
|
|
5
|
-
import { cn as
|
|
6
|
-
const v = o.Root,
|
|
7
|
-
return /* @__PURE__ */
|
|
5
|
+
import { cn as d } from "../../lib/utils.js";
|
|
6
|
+
const v = o.Root, g = o.Trigger, u = o.Anchor, b = o.Close, p = s(function({ className: t, align: r = "center", sideOffset: i = 4, ...n }, a) {
|
|
7
|
+
return /* @__PURE__ */ e(o.Portal, { children: /* @__PURE__ */ e(
|
|
8
8
|
o.Content,
|
|
9
9
|
{
|
|
10
|
-
ref:
|
|
10
|
+
ref: a,
|
|
11
11
|
align: r,
|
|
12
|
-
sideOffset:
|
|
13
|
-
className:
|
|
14
|
-
"z-[var(--z-popover)]
|
|
15
|
-
"outline-none",
|
|
12
|
+
sideOffset: i,
|
|
13
|
+
className: d(
|
|
14
|
+
"border-border bg-popover text-popover-foreground z-[var(--z-popover)] max-w-sm min-w-72 rounded-lg border p-4 shadow-md",
|
|
15
|
+
"focus-visible:ring-ring focus-visible:ring-offset-background outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
|
|
16
16
|
"data-[state=open]:animate-in data-[state=closed]:animate-out",
|
|
17
17
|
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
18
18
|
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
19
19
|
"data-[side=bottom]:slide-in-from-top-1 data-[side=top]:slide-in-from-bottom-1",
|
|
20
20
|
"data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1",
|
|
21
|
-
|
|
21
|
+
t
|
|
22
22
|
),
|
|
23
23
|
...n
|
|
24
24
|
}
|
|
@@ -27,9 +27,9 @@ const v = o.Root, P = o.Trigger, g = o.Anchor, u = o.Close, p = i(function({ cla
|
|
|
27
27
|
p.displayName = "PopoverContent";
|
|
28
28
|
export {
|
|
29
29
|
v as Popover,
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
u as PopoverAnchor,
|
|
31
|
+
b as PopoverClose,
|
|
32
32
|
p as PopoverContent,
|
|
33
|
-
|
|
33
|
+
g as PopoverTrigger
|
|
34
34
|
};
|
|
35
35
|
//# sourceMappingURL=Popover.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popover.js","sources":["../../../src/components/ui/Popover.tsx"],"sourcesContent":["'use client';\n\nimport {
|
|
1
|
+
{"version":3,"file":"Popover.js","sources":["../../../src/components/ui/Popover.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type ComponentPropsWithoutRef, type ElementRef } from 'react';\nimport * as PopoverPrimitive from '@radix-ui/react-popover';\nimport { cn } from '@/lib/utils';\n\nexport const Popover = PopoverPrimitive.Root;\nexport const PopoverTrigger = PopoverPrimitive.Trigger;\nexport const PopoverAnchor = PopoverPrimitive.Anchor;\nexport const PopoverClose = PopoverPrimitive.Close;\n\nexport const PopoverContent = forwardRef<\n ElementRef<typeof PopoverPrimitive.Content>,\n ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>\n>(function PopoverContent({ className, align = 'center', sideOffset = 4, ...props }, ref) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Content\n ref={ref}\n align={align}\n sideOffset={sideOffset}\n className={cn(\n 'border-border bg-popover text-popover-foreground z-[var(--z-popover)] max-w-sm min-w-72 rounded-lg border p-4 shadow-md',\n 'focus-visible:ring-ring focus-visible:ring-offset-background outline-none focus-visible:ring-2 focus-visible:ring-offset-2',\n 'data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n 'data-[side=bottom]:slide-in-from-top-1 data-[side=top]:slide-in-from-bottom-1',\n 'data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1',\n className,\n )}\n {...props}\n />\n </PopoverPrimitive.Portal>\n );\n});\nPopoverContent.displayName = 'PopoverContent';\n\n/**\n * @example\n * <Popover>\n * <PopoverTrigger asChild><Button variant=\"outline\">Options</Button></PopoverTrigger>\n * <PopoverContent>…</PopoverContent>\n * </Popover>\n *\n * @do Reserve Popover for low-stakes, transient UI — pickers, mini-forms.\n * @dont Use Popover for navigation menus — that's DropdownMenu.\n */\n"],"names":["Popover","PopoverPrimitive","PopoverTrigger","PopoverAnchor","PopoverClose","PopoverContent","forwardRef","className","align","sideOffset","props","ref","jsx","cn"],"mappings":";;;;;AAMO,MAAMA,IAAUC,EAAiB,MAC3BC,IAAiBD,EAAiB,SAClCE,IAAgBF,EAAiB,QACjCG,IAAeH,EAAiB,OAEhCI,IAAiBC,EAG5B,SAAwB,EAAE,WAAAC,GAAW,OAAAC,IAAQ,UAAU,YAAAC,IAAa,GAAG,GAAGC,EAAA,GAASC,GAAK;AACxF,SACE,gBAAAC,EAACX,EAAiB,QAAjB,EACC,UAAA,gBAAAW;AAAA,IAACX,EAAiB;AAAA,IAAjB;AAAA,MACC,KAAAU;AAAA,MACA,OAAAH;AAAA,MACA,YAAAC;AAAA,MACA,WAAWI;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAN;AAAA,MAAA;AAAA,MAED,GAAGG;AAAA,IAAA;AAAA,EAAA,GAER;AAEJ,CAAC;AACDL,EAAe,cAAc;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ComponentPropsWithoutRef, SVGProps } from 'react';
|
|
2
2
|
import * as ProgressPrimitive from '@radix-ui/react-progress';
|
|
3
3
|
export interface ProgressProps extends Omit<ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>, 'value'> {
|
|
4
|
-
/** 0
|
|
4
|
+
/** 0–`max` (default 100). Clamped. Omit for indeterminate. */
|
|
5
5
|
value?: number | null;
|
|
6
6
|
/** Bar height. */
|
|
7
7
|
size?: 'sm' | 'md' | 'lg';
|
|
@@ -22,8 +22,8 @@ export declare const Progress: import('react').ForwardRefExoticComponent<Progres
|
|
|
22
22
|
export interface ProgressCircleProps extends SVGProps<SVGSVGElement> {
|
|
23
23
|
/** 0–100. Omit for indeterminate. */
|
|
24
24
|
value?: number;
|
|
25
|
-
/**
|
|
26
|
-
size?: number;
|
|
25
|
+
/** `sm` 24 / `md` 36 / `lg` 48, or an explicit pixel size. */
|
|
26
|
+
size?: 'sm' | 'md' | 'lg' | number;
|
|
27
27
|
/** Stroke thickness. */
|
|
28
28
|
thickness?: number;
|
|
29
29
|
/** Visible label for screen readers. */
|
|
@@ -1,95 +1,100 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as
|
|
3
|
-
import { forwardRef as
|
|
4
|
-
import * as
|
|
5
|
-
import { cn as
|
|
6
|
-
const
|
|
2
|
+
import { jsx as c, jsxs as N } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef as h } from "react";
|
|
4
|
+
import * as u from "@radix-ui/react-progress";
|
|
5
|
+
import { cn as m } from "../../lib/utils.js";
|
|
6
|
+
const b = { sm: "h-1", md: "h-1.5", lg: "h-2" }, v = {
|
|
7
7
|
accent: "bg-accent",
|
|
8
8
|
success: "bg-success",
|
|
9
9
|
warning: "bg-warning",
|
|
10
10
|
danger: "bg-danger"
|
|
11
|
-
},
|
|
12
|
-
function({ className:
|
|
13
|
-
const
|
|
14
|
-
return /* @__PURE__ */
|
|
15
|
-
|
|
11
|
+
}, w = h(
|
|
12
|
+
function({ className: o, value: s, max: t = 100, size: l = "md", tone: d = "accent", ...f }, g) {
|
|
13
|
+
const e = s == null || Number.isNaN(s), r = t > 0 ? t : 100, n = e ? 0 : Math.min(r, Math.max(0, s)), a = n / r * 100;
|
|
14
|
+
return /* @__PURE__ */ c(
|
|
15
|
+
u.Root,
|
|
16
16
|
{
|
|
17
|
-
ref:
|
|
18
|
-
value:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
ref: g,
|
|
18
|
+
value: e ? void 0 : n,
|
|
19
|
+
max: r,
|
|
20
|
+
className: m(
|
|
21
|
+
"bg-background-muted relative w-full overflow-hidden rounded-full",
|
|
22
|
+
b[l],
|
|
23
|
+
o
|
|
23
24
|
),
|
|
24
|
-
...
|
|
25
|
-
children: /* @__PURE__ */
|
|
26
|
-
|
|
25
|
+
...f,
|
|
26
|
+
children: /* @__PURE__ */ c(
|
|
27
|
+
u.Indicator,
|
|
27
28
|
{
|
|
28
|
-
className:
|
|
29
|
+
className: m(
|
|
29
30
|
"h-full w-full flex-1 transition-transform",
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
v[d],
|
|
32
|
+
e && "animate-progress-indeterminate origin-left"
|
|
32
33
|
),
|
|
33
|
-
|
|
34
|
+
"data-motion-keep": e ? "" : void 0,
|
|
35
|
+
style: e ? void 0 : { transform: `translateX(-${100 - a}%)` }
|
|
34
36
|
}
|
|
35
37
|
)
|
|
36
38
|
}
|
|
37
39
|
);
|
|
38
40
|
}
|
|
39
41
|
);
|
|
40
|
-
|
|
41
|
-
const x = {
|
|
42
|
+
w.displayName = "Progress";
|
|
43
|
+
const x = { sm: 24, md: 36, lg: 48 }, y = {
|
|
42
44
|
accent: "stroke-accent",
|
|
43
45
|
success: "stroke-success",
|
|
44
46
|
warning: "stroke-warning",
|
|
45
47
|
danger: "stroke-danger"
|
|
46
|
-
},
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
48
|
+
}, M = h(
|
|
49
|
+
function({ value: o, size: s = "md", thickness: t = 3, className: l, tone: d = "accent", ...f }, g) {
|
|
50
|
+
const e = typeof s == "number" ? s : x[s], r = o === void 0 || Number.isNaN(o), n = r ? 0 : Math.min(100, Math.max(0, o)), a = (e - t) / 2, i = 2 * Math.PI * a, k = r ? 0 : i - n / 100 * i;
|
|
51
|
+
return /* @__PURE__ */ N(
|
|
52
|
+
"svg",
|
|
53
|
+
{
|
|
54
|
+
ref: g,
|
|
55
|
+
width: e,
|
|
56
|
+
height: e,
|
|
57
|
+
viewBox: `0 0 ${e} ${e}`,
|
|
58
|
+
role: "progressbar",
|
|
59
|
+
"aria-valuemin": 0,
|
|
60
|
+
"aria-valuemax": 100,
|
|
61
|
+
"aria-valuenow": r ? void 0 : n,
|
|
62
|
+
"data-motion-keep": r ? "" : void 0,
|
|
63
|
+
className: m("shrink-0", r && "animate-spin", l),
|
|
64
|
+
...f,
|
|
65
|
+
children: [
|
|
66
|
+
/* @__PURE__ */ c(
|
|
67
|
+
"circle",
|
|
68
|
+
{
|
|
69
|
+
cx: e / 2,
|
|
70
|
+
cy: e / 2,
|
|
71
|
+
r: a,
|
|
72
|
+
strokeWidth: t,
|
|
73
|
+
className: "stroke-background-muted fill-none"
|
|
74
|
+
}
|
|
75
|
+
),
|
|
76
|
+
/* @__PURE__ */ c(
|
|
77
|
+
"circle",
|
|
78
|
+
{
|
|
79
|
+
cx: e / 2,
|
|
80
|
+
cy: e / 2,
|
|
81
|
+
r: a,
|
|
82
|
+
strokeWidth: t,
|
|
83
|
+
strokeLinecap: "round",
|
|
84
|
+
strokeDasharray: i,
|
|
85
|
+
strokeDashoffset: r ? i * 0.7 : k,
|
|
86
|
+
className: m(y[d], "fill-none transition-[stroke-dashoffset]"),
|
|
87
|
+
transform: `rotate(-90 ${e / 2} ${e / 2})`
|
|
88
|
+
}
|
|
89
|
+
)
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
M.displayName = "ProgressCircle";
|
|
91
96
|
export {
|
|
92
|
-
|
|
93
|
-
|
|
97
|
+
w as Progress,
|
|
98
|
+
M as ProgressCircle
|
|
94
99
|
};
|
|
95
100
|
//# sourceMappingURL=Progress.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Progress.js","sources":["../../../src/components/ui/Progress.tsx"],"sourcesContent":["'use client';\n\nimport {
|
|
1
|
+
{"version":3,"file":"Progress.js","sources":["../../../src/components/ui/Progress.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type ComponentPropsWithoutRef, type ElementRef, type SVGProps } from 'react';\nimport * as ProgressPrimitive from '@radix-ui/react-progress';\nimport { cn } from '@/lib/utils';\n\n/* -----------------------------------------------------------------------------\n * Linear — bar that fills left-to-right.\n * Circular — SVG ring. Both support determinate (value 0..100) and\n * indeterminate (`value` omitted) states.\n * --------------------------------------------------------------------------- */\n\nexport interface ProgressProps extends Omit<\n ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>,\n 'value'\n> {\n /** 0–`max` (default 100). Clamped. Omit for indeterminate. */\n value?: number | null;\n /** Bar height. */\n size?: 'sm' | 'md' | 'lg';\n /** Visual tone. Use `success`/`danger` to colour-code completion state. */\n tone?: 'accent' | 'success' | 'warning' | 'danger';\n}\n\nconst heightMap = { sm: 'h-1', md: 'h-1.5', lg: 'h-2' } as const;\nconst fillTone = {\n accent: 'bg-accent',\n success: 'bg-success',\n warning: 'bg-warning',\n danger: 'bg-danger',\n} as const;\n\n/**\n * Linear progress bar.\n *\n * @example\n * <Progress value={uploadPct} aria-label=\"Upload progress\" />\n * <Progress aria-label=\"Loading\" /> // indeterminate\n *\n * @do Always pair Progress with an `aria-label` describing what is progressing.\n * @dont Use a Progress for an unknown-completion task — use a Spinner.\n */\nexport const Progress = forwardRef<ElementRef<typeof ProgressPrimitive.Root>, ProgressProps>(\n function Progress({ className, value, max = 100, size = 'md', tone = 'accent', ...props }, ref) {\n const indeterminate = value === undefined || value === null || Number.isNaN(value);\n const safeMax = max > 0 ? max : 100;\n const clamped = indeterminate ? 0 : Math.min(safeMax, Math.max(0, value as number));\n const pct = (clamped / safeMax) * 100;\n return (\n <ProgressPrimitive.Root\n ref={ref}\n value={indeterminate ? undefined : clamped}\n max={safeMax}\n className={cn(\n 'bg-background-muted relative w-full overflow-hidden rounded-full',\n heightMap[size],\n className,\n )}\n {...props}\n >\n <ProgressPrimitive.Indicator\n className={cn(\n 'h-full w-full flex-1 transition-transform',\n fillTone[tone],\n indeterminate && 'animate-progress-indeterminate origin-left',\n )}\n data-motion-keep={indeterminate ? '' : undefined}\n style={indeterminate ? undefined : { transform: `translateX(-${100 - pct}%)` }}\n />\n </ProgressPrimitive.Root>\n );\n },\n);\nProgress.displayName = 'Progress';\n\nexport interface ProgressCircleProps extends SVGProps<SVGSVGElement> {\n /** 0–100. Omit for indeterminate. */\n value?: number;\n /** `sm` 24 / `md` 36 / `lg` 48, or an explicit pixel size. */\n size?: 'sm' | 'md' | 'lg' | number;\n /** Stroke thickness. */\n thickness?: number;\n /** Visible label for screen readers. */\n 'aria-label': string;\n tone?: 'accent' | 'success' | 'warning' | 'danger';\n}\n\nconst circleSize = { sm: 24, md: 36, lg: 48 } as const;\n\nconst circleTone = {\n accent: 'stroke-accent',\n success: 'stroke-success',\n warning: 'stroke-warning',\n danger: 'stroke-danger',\n} as const;\n\n/**\n * Circular progress ring. Pairs with a numeric label for percentage-style\n * indicators.\n *\n * @example\n * <ProgressCircle value={72} aria-label=\"Storage used\" />\n */\nexport const ProgressCircle = forwardRef<SVGSVGElement, ProgressCircleProps>(\n function ProgressCircle(\n { value, size: sizeProp = 'md', thickness = 3, className, tone = 'accent', ...props },\n ref,\n ) {\n const size = typeof sizeProp === 'number' ? sizeProp : circleSize[sizeProp];\n const isIndeterminate = value === undefined || Number.isNaN(value);\n const clamped = isIndeterminate ? 0 : Math.min(100, Math.max(0, value as number));\n const radius = (size - thickness) / 2;\n const circumference = 2 * Math.PI * radius;\n const offset = isIndeterminate ? 0 : circumference - (clamped / 100) * circumference;\n\n return (\n <svg\n ref={ref}\n width={size}\n height={size}\n viewBox={`0 0 ${size} ${size}`}\n role=\"progressbar\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={isIndeterminate ? undefined : clamped}\n data-motion-keep={isIndeterminate ? '' : undefined}\n className={cn('shrink-0', isIndeterminate && 'animate-spin', className)}\n {...props}\n >\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n strokeWidth={thickness}\n className=\"stroke-background-muted fill-none\"\n />\n <circle\n cx={size / 2}\n cy={size / 2}\n r={radius}\n strokeWidth={thickness}\n strokeLinecap=\"round\"\n strokeDasharray={circumference}\n strokeDashoffset={isIndeterminate ? circumference * 0.7 : offset}\n className={cn(circleTone[tone], 'fill-none transition-[stroke-dashoffset]')}\n transform={`rotate(-90 ${size / 2} ${size / 2})`}\n />\n </svg>\n );\n },\n);\nProgressCircle.displayName = 'ProgressCircle';\n"],"names":["heightMap","fillTone","Progress","forwardRef","className","value","max","size","tone","props","ref","indeterminate","safeMax","clamped","pct","jsx","ProgressPrimitive","cn","circleSize","circleTone","ProgressCircle","sizeProp","thickness","isIndeterminate","radius","circumference","offset","jsxs"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ComponentPropsWithoutRef, ReactNode } from 'react';
|
|
2
2
|
import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
|
|
3
3
|
export interface RadioGroupProps extends ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> {
|
|
4
|
-
/** Lay out the radios
|
|
4
|
+
/** Lay out the radios vertically (default) or horizontally. Also drives arrow-key navigation. */
|
|
5
5
|
orientation?: 'horizontal' | 'vertical';
|
|
6
6
|
}
|
|
7
7
|
export declare const RadioGroup: import('react').ForwardRefExoticComponent<RadioGroupProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
@@ -1,64 +1,81 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as e, jsxs as
|
|
3
|
-
import { forwardRef as f, useId as
|
|
4
|
-
import * as
|
|
5
|
-
import { cn as
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
ref: s,
|
|
11
|
-
className: o(
|
|
12
|
-
"flex gap-3",
|
|
13
|
-
t === "vertical" ? "flex-col" : "flex-row flex-wrap",
|
|
14
|
-
i
|
|
15
|
-
),
|
|
16
|
-
...r
|
|
17
|
-
}
|
|
18
|
-
);
|
|
19
|
-
});
|
|
20
|
-
v.displayName = "RadioGroup";
|
|
21
|
-
const h = f(function({ className: i, label: t, description: r, hideLabel: s, id: m, disabled: d, ...p }, x) {
|
|
22
|
-
const b = g(), a = m ?? b, l = r ? `${a}-desc` : void 0;
|
|
23
|
-
return /* @__PURE__ */ n("div", { className: o("flex items-start gap-2.5", i), children: [
|
|
24
|
-
/* @__PURE__ */ e(
|
|
25
|
-
c.Item,
|
|
2
|
+
import { jsx as e, jsxs as c } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef as f, useId as h } from "react";
|
|
4
|
+
import * as d from "@radix-ui/react-radio-group";
|
|
5
|
+
import { cn as i } from "../../lib/utils.js";
|
|
6
|
+
const y = f(
|
|
7
|
+
function({ className: a, orientation: r = "vertical", ...o }, t) {
|
|
8
|
+
return /* @__PURE__ */ e(
|
|
9
|
+
d.Root,
|
|
26
10
|
{
|
|
27
|
-
ref:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]",
|
|
34
|
-
"outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
35
|
-
"data-[state=checked]:border-accent",
|
|
36
|
-
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
37
|
-
"border-border-input"
|
|
11
|
+
ref: t,
|
|
12
|
+
orientation: r,
|
|
13
|
+
className: i(
|
|
14
|
+
"flex gap-3",
|
|
15
|
+
r === "vertical" ? "flex-col" : "flex-row flex-wrap",
|
|
16
|
+
a
|
|
38
17
|
),
|
|
39
|
-
...
|
|
40
|
-
children: /* @__PURE__ */ e(c.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ e("span", { className: "size-2 rounded-full bg-accent", "aria-hidden": !0 }) })
|
|
18
|
+
...o
|
|
41
19
|
}
|
|
42
|
-
)
|
|
43
|
-
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
y.displayName = "RadioGroup";
|
|
24
|
+
const N = f(
|
|
25
|
+
function({
|
|
26
|
+
className: a,
|
|
27
|
+
label: r,
|
|
28
|
+
description: o,
|
|
29
|
+
hideLabel: t,
|
|
30
|
+
id: m,
|
|
31
|
+
disabled: l,
|
|
32
|
+
"aria-describedby": b,
|
|
33
|
+
...p
|
|
34
|
+
}, x) {
|
|
35
|
+
const v = h(), s = m ?? v, n = o ? `${s}-desc` : void 0, g = [n, b].filter(Boolean).join(" ") || void 0;
|
|
36
|
+
return /* @__PURE__ */ c("div", { className: i("flex items-start gap-2.5", a), children: [
|
|
44
37
|
/* @__PURE__ */ e(
|
|
45
|
-
|
|
38
|
+
d.Item,
|
|
46
39
|
{
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
40
|
+
ref: x,
|
|
41
|
+
id: s,
|
|
42
|
+
disabled: l,
|
|
43
|
+
"aria-describedby": g,
|
|
44
|
+
className: i(
|
|
45
|
+
"bg-card relative mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full border",
|
|
46
|
+
// WCAG 2.5.8: 16px visual box, ≥24px hit area via an invisible inset halo.
|
|
47
|
+
'before:absolute before:-inset-1.5 before:rounded-full before:content-[""]',
|
|
48
|
+
"transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]",
|
|
49
|
+
"focus-visible:ring-ring focus-visible:ring-offset-background outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
|
|
50
|
+
"data-[state=checked]:border-accent",
|
|
51
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
52
|
+
"border-border-input aria-invalid:border-danger"
|
|
51
53
|
),
|
|
52
|
-
|
|
54
|
+
...p,
|
|
55
|
+
children: /* @__PURE__ */ e(d.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ e("span", { className: "bg-accent size-2 rounded-full", "aria-hidden": !0 }) })
|
|
53
56
|
}
|
|
54
57
|
),
|
|
55
|
-
r && /* @__PURE__ */
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
r && /* @__PURE__ */ c("div", { className: "flex flex-col gap-0.5", children: [
|
|
59
|
+
/* @__PURE__ */ e(
|
|
60
|
+
"label",
|
|
61
|
+
{
|
|
62
|
+
htmlFor: s,
|
|
63
|
+
className: i(
|
|
64
|
+
"text-foreground text-sm select-none",
|
|
65
|
+
l && "cursor-not-allowed opacity-50",
|
|
66
|
+
t && "sr-only"
|
|
67
|
+
),
|
|
68
|
+
children: r
|
|
69
|
+
}
|
|
70
|
+
),
|
|
71
|
+
o && /* @__PURE__ */ e("p", { id: n, className: "text-foreground-subtle text-xs", children: o })
|
|
72
|
+
] })
|
|
73
|
+
] });
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
N.displayName = "RadioItem";
|
|
60
77
|
export {
|
|
61
|
-
|
|
62
|
-
|
|
78
|
+
y as RadioGroup,
|
|
79
|
+
N as RadioItem
|
|
63
80
|
};
|
|
64
81
|
//# sourceMappingURL=RadioGroup.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RadioGroup.js","sources":["../../../src/components/ui/RadioGroup.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n useId,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type ReactNode,\n} from 'react';\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group';\nimport { cn } from '@/lib/utils';\n\nexport interface RadioGroupProps
|
|
1
|
+
{"version":3,"file":"RadioGroup.js","sources":["../../../src/components/ui/RadioGroup.tsx"],"sourcesContent":["'use client';\n\nimport {\n forwardRef,\n useId,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type ReactNode,\n} from 'react';\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group';\nimport { cn } from '@/lib/utils';\n\nexport interface RadioGroupProps extends ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> {\n /** Lay out the radios vertically (default) or horizontally. Also drives arrow-key navigation. */\n orientation?: 'horizontal' | 'vertical';\n}\n\nexport const RadioGroup = forwardRef<ElementRef<typeof RadioGroupPrimitive.Root>, RadioGroupProps>(\n function RadioGroup({ className, orientation = 'vertical', ...props }, ref) {\n return (\n <RadioGroupPrimitive.Root\n ref={ref}\n orientation={orientation}\n className={cn(\n 'flex gap-3',\n orientation === 'vertical' ? 'flex-col' : 'flex-row flex-wrap',\n className,\n )}\n {...props}\n />\n );\n },\n);\nRadioGroup.displayName = 'RadioGroup';\n\nexport interface RadioItemProps extends Omit<\n ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>,\n 'asChild'\n> {\n label?: ReactNode;\n description?: ReactNode;\n hideLabel?: boolean;\n}\n\n/**\n * One radio option with inline label + description.\n *\n * @example\n * <RadioGroup defaultValue=\"weekly\">\n * <RadioItem value=\"daily\" label=\"Daily\" description=\"Every morning at 9am\" />\n * <RadioItem value=\"weekly\" label=\"Weekly\" description=\"Monday mornings\" />\n * <RadioItem value=\"never\" label=\"Never\" />\n * </RadioGroup>\n *\n * @do Pair every RadioItem with a label — naked radios are unreachable for\n * screen reader users.\n * @dont Use RadioGroup for binary choices — use Switch.\n */\nexport const RadioItem = forwardRef<ElementRef<typeof RadioGroupPrimitive.Item>, RadioItemProps>(\n function RadioItem(\n {\n className,\n label,\n description,\n hideLabel,\n id,\n disabled,\n 'aria-describedby': ariaDescribedby,\n ...props\n },\n ref,\n ) {\n const autoId = useId();\n const fieldId = id ?? autoId;\n const descId = description ? `${fieldId}-desc` : undefined;\n const describedBy = [descId, ariaDescribedby].filter(Boolean).join(' ') || undefined;\n\n return (\n <div className={cn('flex items-start gap-2.5', className)}>\n <RadioGroupPrimitive.Item\n ref={ref}\n id={fieldId}\n disabled={disabled}\n aria-describedby={describedBy}\n className={cn(\n 'bg-card relative mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full border',\n // WCAG 2.5.8: 16px visual box, ≥24px hit area via an invisible inset halo.\n 'before:absolute before:-inset-1.5 before:rounded-full before:content-[\"\"]',\n 'transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]',\n 'focus-visible:ring-ring focus-visible:ring-offset-background outline-none focus-visible:ring-2 focus-visible:ring-offset-2',\n 'data-[state=checked]:border-accent',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n 'border-border-input aria-invalid:border-danger',\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center\">\n <span className=\"bg-accent size-2 rounded-full\" aria-hidden />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n\n {label && (\n <div className=\"flex flex-col gap-0.5\">\n <label\n htmlFor={fieldId}\n className={cn(\n 'text-foreground text-sm select-none',\n disabled && 'cursor-not-allowed opacity-50',\n hideLabel && 'sr-only',\n )}\n >\n {label}\n </label>\n {description && (\n <p id={descId} className=\"text-foreground-subtle text-xs\">\n {description}\n </p>\n )}\n </div>\n )}\n </div>\n );\n },\n);\nRadioItem.displayName = 'RadioItem';\n"],"names":["RadioGroup","forwardRef","className","orientation","props","ref","jsx","RadioGroupPrimitive","cn","RadioItem","label","description","hideLabel","id","disabled","ariaDescribedby","autoId","useId","fieldId","descId","describedBy","jsxs"],"mappings":";;;;;AAiBO,MAAMA,IAAaC;AAAA,EACxB,SAAoB,EAAE,WAAAC,GAAW,aAAAC,IAAc,YAAY,GAAGC,EAAA,GAASC,GAAK;AAC1E,WACE,gBAAAC;AAAA,MAACC,EAAoB;AAAA,MAApB;AAAA,QACC,KAAAF;AAAA,QACA,aAAAF;AAAA,QACA,WAAWK;AAAA,UACT;AAAA,UACAL,MAAgB,aAAa,aAAa;AAAA,UAC1CD;AAAA,QAAA;AAAA,QAED,GAAGE;AAAA,MAAA;AAAA,IAAA;AAAA,EAGV;AACF;AACAJ,EAAW,cAAc;AAyBlB,MAAMS,IAAYR;AAAA,EACvB,SACE;AAAA,IACE,WAAAC;AAAA,IACA,OAAAQ;AAAA,IACA,aAAAC;AAAA,IACA,WAAAC;AAAA,IACA,IAAAC;AAAA,IACA,UAAAC;AAAA,IACA,oBAAoBC;AAAA,IACpB,GAAGX;AAAA,EAAA,GAELC,GACA;AACA,UAAMW,IAASC,EAAA,GACTC,IAAUL,KAAMG,GAChBG,IAASR,IAAc,GAAGO,CAAO,UAAU,QAC3CE,IAAc,CAACD,GAAQJ,CAAe,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,KAAK;AAE3E,6BACG,OAAA,EAAI,WAAWP,EAAG,4BAA4BN,CAAS,GACtD,UAAA;AAAA,MAAA,gBAAAI;AAAA,QAACC,EAAoB;AAAA,QAApB;AAAA,UACC,KAAAF;AAAA,UACA,IAAIa;AAAA,UACJ,UAAAJ;AAAA,UACA,oBAAkBM;AAAA,UAClB,WAAWZ;AAAA,YACT;AAAA;AAAA,YAEA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAAA,UAED,GAAGJ;AAAA,UAEJ,UAAA,gBAAAE,EAACC,EAAoB,WAApB,EAA8B,WAAU,oCACvC,UAAA,gBAAAD,EAAC,QAAA,EAAK,WAAU,iCAAgC,eAAW,GAAA,CAAC,EAAA,CAC9D;AAAA,QAAA;AAAA,MAAA;AAAA,MAGDI,KACC,gBAAAW,EAAC,OAAA,EAAI,WAAU,yBACb,UAAA;AAAA,QAAA,gBAAAf;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,SAASY;AAAA,YACT,WAAWV;AAAA,cACT;AAAA,cACAM,KAAY;AAAA,cACZF,KAAa;AAAA,YAAA;AAAA,YAGd,UAAAF;AAAA,UAAA;AAAA,QAAA;AAAA,QAEFC,KACC,gBAAAL,EAAC,KAAA,EAAE,IAAIa,GAAQ,WAAU,kCACtB,UAAAR,EAAA,CACH;AAAA,MAAA,EAAA,CAEJ;AAAA,IAAA,GAEJ;AAAA,EAEJ;AACF;AACAF,EAAU,cAAc;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { TimeHTMLAttributes } from 'react';
|
|
2
|
+
import { FormatDateOptions } from '../../lib/format.js';
|
|
3
|
+
export interface RelativeTimeProps extends Omit<TimeHTMLAttributes<HTMLTimeElement>, 'dateTime'> {
|
|
4
|
+
/** The instant to describe. */
|
|
5
|
+
date: Date | number | string;
|
|
6
|
+
/** Reference "now". Default `Date.now()` at render — pass one for stable SSR/tests. */
|
|
7
|
+
now?: Date | number;
|
|
8
|
+
/** Options for the absolute `title` (tooltip). */
|
|
9
|
+
absolute?: FormatDateOptions;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* `<time>` showing "5 min ago" with the absolute timestamp as `title` and a
|
|
13
|
+
* machine-readable `dateTime`. Strings come from `UiStrings.relativeTime`.
|
|
14
|
+
* Beyond 30 days it falls back to the absolute date so text never goes stale.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* <RelativeTime date={post.createdAt} />
|
|
18
|
+
*/
|
|
19
|
+
export declare const RelativeTime: import('react').ForwardRefExoticComponent<RelativeTimeProps & import('react').RefAttributes<HTMLTimeElement>>;
|