@refraction-ui/react 0.19.1 → 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/dist/chunk-533MCMSU.js +2355 -0
- package/dist/chunk-533MCMSU.js.map +7 -0
- package/dist/chunk-AMK4VCBG.js +250 -0
- package/dist/chunk-AMK4VCBG.js.map +7 -0
- package/dist/chunk-BOLFYVI6.js +90 -0
- package/dist/chunk-BOLFYVI6.js.map +7 -0
- package/dist/chunk-F7B64KT3.js +187 -0
- package/dist/chunk-F7B64KT3.js.map +7 -0
- package/dist/chunk-FD37DFCC.js +77 -0
- package/dist/chunk-FD37DFCC.js.map +7 -0
- package/dist/chunk-H54FLNAF.js +132 -0
- package/dist/chunk-H54FLNAF.js.map +7 -0
- package/dist/chunk-INP46354.js +664 -0
- package/dist/chunk-INP46354.js.map +7 -0
- package/dist/chunk-ONACRMG4.js +116 -0
- package/dist/chunk-ONACRMG4.js.map +7 -0
- package/dist/chunk-SDZ3LROZ.js +7 -0
- package/dist/chunk-SDZ3LROZ.js.map +7 -0
- package/dist/chunk-TOZBR4GL.js +154 -0
- package/dist/chunk-TOZBR4GL.js.map +7 -0
- package/dist/chunk-UNEM2TRI.js +225 -0
- package/dist/chunk-UNEM2TRI.js.map +7 -0
- package/dist/chunk-VK3EQ34F.js +92 -0
- package/dist/chunk-VK3EQ34F.js.map +7 -0
- package/dist/chunk-WK2IIUFO.js +316 -0
- package/dist/chunk-WK2IIUFO.js.map +7 -0
- package/dist/chunk-WSPJTQAV.js +59 -0
- package/dist/chunk-WSPJTQAV.js.map +7 -0
- package/dist/chunk-XWP763SH.js +3 -2
- package/dist/chunk-XWP763SH.js.map +7 -1
- package/dist/chunk-Y2FNNAIL.js +80 -0
- package/dist/chunk-Y2FNNAIL.js.map +1 -0
- package/dist/{chunk-4A4BW3GR.js → chunk-ZF3OHCGV.js} +28 -5
- package/dist/chunk-ZF3OHCGV.js.map +7 -0
- package/dist/form.cjs +5 -11
- package/dist/form.cjs.map +1 -1
- package/dist/form.js +6 -12
- package/dist/form.js.map +1 -1
- package/dist/index.cjs +2879 -33936
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +126 -28780
- package/dist/internal/react-app-shell/index.d.cts +2 -22
- package/dist/internal/react-app-shell/index.d.ts +2 -22
- package/dist/internal/react-badge/index.d.cts +5 -0
- package/dist/internal/react-badge/index.d.ts +5 -0
- package/dist/internal/react-callout/index.d.cts +4 -0
- package/dist/internal/react-callout/index.d.ts +4 -0
- package/dist/internal/react-card/index.d.cts +8 -1
- package/dist/internal/react-card/index.d.ts +8 -1
- package/dist/internal/react-collapsible/index.d.cts +0 -3
- package/dist/internal/react-collapsible/index.d.ts +0 -3
- package/dist/internal/react-combobox/index.d.cts +0 -3
- package/dist/internal/react-combobox/index.d.ts +0 -3
- package/dist/internal/react-command/index.d.cts +0 -3
- package/dist/internal/react-command/index.d.ts +0 -3
- package/dist/internal/react-data-table/index.d.cts +0 -3
- package/dist/internal/react-data-table/index.d.ts +0 -3
- package/dist/internal/react-dialog/index.d.cts +0 -3
- package/dist/internal/react-dialog/index.d.ts +0 -3
- package/dist/internal/react-dropdown-menu/index.d.cts +0 -3
- package/dist/internal/react-dropdown-menu/index.d.ts +0 -3
- package/dist/internal/react-feedback-dialog/index.d.cts +0 -3
- package/dist/internal/react-feedback-dialog/index.d.ts +0 -3
- package/dist/internal/react-form/index.d.cts +2 -21
- package/dist/internal/react-form/index.d.ts +2 -21
- package/dist/internal/react-keyboard-shortcut/index.d.cts +0 -6
- package/dist/internal/react-keyboard-shortcut/index.d.ts +0 -6
- package/dist/internal/react-link-card/index.d.cts +8 -2
- package/dist/internal/react-link-card/index.d.ts +8 -2
- package/dist/internal/react-popover/index.d.cts +0 -3
- package/dist/internal/react-popover/index.d.ts +0 -3
- package/dist/internal/react-sheet/index.d.cts +0 -3
- package/dist/internal/react-sheet/index.d.ts +0 -3
- package/dist/internal/react-slot/index.d.cts +23 -0
- package/dist/internal/react-slot/index.d.ts +23 -0
- package/dist/internal/react-toast/index.d.cts +0 -3
- package/dist/internal/react-toast/index.d.ts +0 -3
- package/dist/internal/react-tooltip/index.d.cts +0 -3
- package/dist/internal/react-tooltip/index.d.ts +0 -3
- package/dist/react-accordion.js +125 -0
- package/dist/react-accordion.js.map +7 -0
- package/dist/react-ai.js +257 -0
- package/dist/react-ai.js.map +7 -0
- package/dist/react-analytics.js +1698 -0
- package/dist/react-analytics.js.map +7 -0
- package/dist/react-animated-text.js +164 -0
- package/dist/react-animated-text.js.map +7 -0
- package/dist/react-app-shell.js +631 -0
- package/dist/react-app-shell.js.map +7 -0
- package/dist/react-audience-feature-card.js +53 -0
- package/dist/react-audience-feature-card.js.map +7 -0
- package/dist/react-audio-room.js +166 -0
- package/dist/react-audio-room.js.map +7 -0
- package/dist/react-auth.js +211 -0
- package/dist/react-auth.js.map +7 -0
- package/dist/react-avatar-group.js +154 -0
- package/dist/react-avatar-group.js.map +7 -0
- package/dist/react-avatar.js +168 -0
- package/dist/react-avatar.js.map +7 -0
- package/dist/react-badge.js +86 -0
- package/dist/react-badge.js.map +7 -0
- package/dist/react-bottom-nav.js +67 -0
- package/dist/react-bottom-nav.js.map +7 -0
- package/dist/react-brand-network-cell.js +92 -0
- package/dist/react-brand-network-cell.js.map +7 -0
- package/dist/react-breadcrumbs.js +104 -0
- package/dist/react-breadcrumbs.js.map +7 -0
- package/dist/react-browser-chrome-mock.js +89 -0
- package/dist/react-browser-chrome-mock.js.map +7 -0
- package/dist/react-button.js +13 -0
- package/dist/react-button.js.map +7 -0
- package/dist/react-calendar.js +301 -0
- package/dist/react-calendar.js.map +7 -0
- package/dist/react-call-controls.js +113 -0
- package/dist/react-call-controls.js.map +7 -0
- package/dist/react-callout.js +152 -0
- package/dist/react-callout.js.map +7 -0
- package/dist/react-card-grid.js +34 -0
- package/dist/react-card-grid.js.map +7 -0
- package/dist/react-card.js +200 -0
- package/dist/react-card.js.map +7 -0
- package/dist/react-carousel.js +132 -0
- package/dist/react-carousel.js.map +7 -0
- package/dist/react-charts.js +509 -0
- package/dist/react-charts.js.map +7 -0
- package/dist/react-checkbox.js +156 -0
- package/dist/react-checkbox.js.map +7 -0
- package/dist/react-checklist.js +168 -0
- package/dist/react-checklist.js.map +7 -0
- package/dist/react-code-block.js +78 -0
- package/dist/react-code-block.js.map +7 -0
- package/dist/react-code-editor.js +184 -0
- package/dist/react-code-editor.js.map +7 -0
- package/dist/react-collapsible.js +192 -0
- package/dist/react-collapsible.js.map +7 -0
- package/dist/react-combobox.js +609 -0
- package/dist/react-combobox.js.map +7 -0
- package/dist/react-command-input.js +202 -0
- package/dist/react-command-input.js.map +7 -0
- package/dist/react-command.js +364 -0
- package/dist/react-command.js.map +7 -0
- package/dist/react-composer.js +2036 -0
- package/dist/react-composer.js.map +7 -0
- package/dist/react-content-protection.js +133 -0
- package/dist/react-content-protection.js.map +7 -0
- package/dist/react-conversation.js +1226 -0
- package/dist/react-conversation.js.map +7 -0
- package/dist/react-cookie-consent.js +291 -0
- package/dist/react-cookie-consent.js.map +7 -0
- package/dist/react-data-table.js +310 -0
- package/dist/react-data-table.js.map +7 -0
- package/dist/react-date-picker.js +95 -0
- package/dist/react-date-picker.js.map +7 -0
- package/dist/react-device-frame.js +137 -0
- package/dist/react-device-frame.js.map +7 -0
- package/dist/react-dialog.js +218 -0
- package/dist/react-dialog.js.map +7 -0
- package/dist/react-diff-viewer.js +460 -0
- package/dist/react-diff-viewer.js.map +7 -0
- package/dist/react-dropdown-menu.js +292 -0
- package/dist/react-dropdown-menu.js.map +7 -0
- package/dist/react-editor-status-bar.js +148 -0
- package/dist/react-editor-status-bar.js.map +7 -0
- package/dist/react-editor-tabs.js +159 -0
- package/dist/react-editor-tabs.js.map +7 -0
- package/dist/react-emoji-picker.js +238 -0
- package/dist/react-emoji-picker.js.map +7 -0
- package/dist/react-empty-state.js +90 -0
- package/dist/react-empty-state.js.map +7 -0
- package/dist/react-feedback-dialog.js +275 -0
- package/dist/react-feedback-dialog.js.map +7 -0
- package/dist/react-file-tree.js +376 -0
- package/dist/react-file-tree.js.map +7 -0
- package/dist/react-file-upload.js +360 -0
- package/dist/react-file-upload.js.map +7 -0
- package/dist/react-floating-reactions.js +124 -0
- package/dist/react-floating-reactions.js.map +7 -0
- package/dist/react-flow-editor.js +198 -0
- package/dist/react-flow-editor.js.map +7 -0
- package/dist/react-footer.js +67 -0
- package/dist/react-footer.js.map +7 -0
- package/dist/react-graph-view.js +197 -0
- package/dist/react-graph-view.js.map +7 -0
- package/dist/react-icon-system.js +9 -0
- package/dist/react-icon-system.js.map +7 -0
- package/dist/react-infinite-canvas.js +8 -0
- package/dist/react-infinite-canvas.js.map +7 -0
- package/dist/react-inline-editor.js +216 -0
- package/dist/react-inline-editor.js.map +7 -0
- package/dist/react-input-group.js +150 -0
- package/dist/react-input-group.js.map +7 -0
- package/dist/react-input.js +10 -0
- package/dist/react-input.js.map +7 -0
- package/dist/react-install-prompt.js +132 -0
- package/dist/react-install-prompt.js.map +7 -0
- package/dist/react-kanban-board.js +198 -0
- package/dist/react-kanban-board.js.map +7 -0
- package/dist/react-keyboard-shortcut.js +36 -0
- package/dist/react-keyboard-shortcut.js.map +7 -0
- package/dist/react-language-selector.js +311 -0
- package/dist/react-language-selector.js.map +7 -0
- package/dist/react-link-card.js +48 -0
- package/dist/react-link-card.js.map +7 -0
- package/dist/react-live-captions.js +92 -0
- package/dist/react-live-captions.js.map +7 -0
- package/dist/react-live-cursors.js +145 -0
- package/dist/react-live-cursors.js.map +7 -0
- package/dist/react-live-transcript.js +117 -0
- package/dist/react-live-transcript.js.map +7 -0
- package/dist/react-location-selector.js +252 -0
- package/dist/react-location-selector.js.map +7 -0
- package/dist/react-logger.js +415 -0
- package/dist/react-logger.js.map +7 -0
- package/dist/react-markdown-renderer.js +12 -0
- package/dist/react-markdown-renderer.js.map +7 -0
- package/dist/react-marquee-strip.js +62 -0
- package/dist/react-marquee-strip.js.map +7 -0
- package/dist/react-mascot.js +367 -0
- package/dist/react-mascot.js.map +7 -0
- package/dist/react-mastery-bar.js +97 -0
- package/dist/react-mastery-bar.js.map +7 -0
- package/dist/react-mini-map.js +207 -0
- package/dist/react-mini-map.js.map +7 -0
- package/dist/react-mobile-nav.js +216 -0
- package/dist/react-mobile-nav.js.map +7 -0
- package/dist/react-navbar.js +96 -0
- package/dist/react-navbar.js.map +7 -0
- package/dist/react-numbered-steps.js +67 -0
- package/dist/react-numbered-steps.js.map +7 -0
- package/dist/react-otp-input.js +318 -0
- package/dist/react-otp-input.js.map +7 -0
- package/dist/react-pagination.js +199 -0
- package/dist/react-pagination.js.map +7 -0
- package/dist/react-password-input.js +104 -0
- package/dist/react-password-input.js.map +7 -0
- package/dist/react-payment.js +81 -0
- package/dist/react-payment.js.map +7 -0
- package/dist/react-popover.js +176 -0
- package/dist/react-popover.js.map +7 -0
- package/dist/react-pre-call-lobby.js +309 -0
- package/dist/react-pre-call-lobby.js.map +7 -0
- package/dist/react-presence-indicator.js +86 -0
- package/dist/react-presence-indicator.js.map +7 -0
- package/dist/react-pricing-card.js +142 -0
- package/dist/react-pricing-card.js.map +7 -0
- package/dist/react-progress-display.js +188 -0
- package/dist/react-progress-display.js.map +7 -0
- package/dist/react-radial-gauge.js +193 -0
- package/dist/react-radial-gauge.js.map +7 -0
- package/dist/react-radio.js +169 -0
- package/dist/react-radio.js.map +7 -0
- package/dist/react-rating-scale.js +171 -0
- package/dist/react-rating-scale.js.map +7 -0
- package/dist/react-reaction-bar.js +111 -0
- package/dist/react-reaction-bar.js.map +7 -0
- package/dist/react-resizable-layout.js +298 -0
- package/dist/react-resizable-layout.js.map +7 -0
- package/dist/react-rich-editor.js +1 -0
- package/dist/react-rich-editor.js.map +7 -0
- package/dist/react-search-bar.js +285 -0
- package/dist/react-search-bar.js.map +7 -0
- package/dist/react-section-head.js +65 -0
- package/dist/react-section-head.js.map +7 -0
- package/dist/react-segmented-control.js +215 -0
- package/dist/react-segmented-control.js.map +7 -0
- package/dist/react-select.js +389 -0
- package/dist/react-select.js.map +7 -0
- package/dist/react-separator.js +86 -0
- package/dist/react-separator.js.map +7 -0
- package/dist/react-sheet.js +310 -0
- package/dist/react-sheet.js.map +7 -0
- package/dist/react-sidebar.js +100 -0
- package/dist/react-sidebar.js.map +7 -0
- package/dist/react-skeleton.js +91 -0
- package/dist/react-skeleton.js.map +7 -0
- package/dist/react-skip-to-content.js +38 -0
- package/dist/react-skip-to-content.js.map +7 -0
- package/dist/react-slide-viewer.js +264 -0
- package/dist/react-slide-viewer.js.map +7 -0
- package/dist/react-slider.js +105 -0
- package/dist/react-slider.js.map +7 -0
- package/dist/react-slot-picker.js +184 -0
- package/dist/react-slot-picker.js.map +7 -0
- package/dist/react-slot.js +7 -0
- package/dist/react-slot.js.map +7 -0
- package/dist/react-social-auth-button.js +169 -0
- package/dist/react-social-auth-button.js.map +7 -0
- package/dist/react-sortable-list.js +204 -0
- package/dist/react-sortable-list.js.map +7 -0
- package/dist/react-stat-grid.js +69 -0
- package/dist/react-stat-grid.js.map +7 -0
- package/dist/react-status-indicator.js +117 -0
- package/dist/react-status-indicator.js.map +7 -0
- package/dist/react-steps.js +167 -0
- package/dist/react-steps.js.map +7 -0
- package/dist/react-sticky-note.js +131 -0
- package/dist/react-sticky-note.js.map +7 -0
- package/dist/react-switch.js +139 -0
- package/dist/react-switch.js.map +7 -0
- package/dist/react-table-of-contents.js +80 -0
- package/dist/react-table-of-contents.js.map +7 -0
- package/dist/react-tabs.js +230 -0
- package/dist/react-tabs.js.map +7 -0
- package/dist/react-terminal.js +101 -0
- package/dist/react-terminal.js.map +7 -0
- package/dist/react-test-results.js +158 -0
- package/dist/react-test-results.js.map +7 -0
- package/dist/react-textarea.js +89 -0
- package/dist/react-textarea.js.map +7 -0
- package/dist/react-thread-view.js +139 -0
- package/dist/react-thread-view.js.map +7 -0
- package/dist/react-timeline.js +153 -0
- package/dist/react-timeline.js.map +7 -0
- package/dist/react-toast.js +253 -0
- package/dist/react-toast.js.map +7 -0
- package/dist/react-tooltip.js +221 -0
- package/dist/react-tooltip.js.map +7 -0
- package/dist/react-version-selector.js +270 -0
- package/dist/react-version-selector.js.map +7 -0
- package/dist/react-video-grid.js +129 -0
- package/dist/react-video-grid.js.map +7 -0
- package/dist/react-video-player.js +206 -0
- package/dist/react-video-player.js.map +7 -0
- package/dist/react-video-tile.js +8 -0
- package/dist/react-video-tile.js.map +7 -0
- package/dist/react-voice-pill.js +314 -0
- package/dist/react-voice-pill.js.map +7 -0
- package/dist/react-waveform.js +558 -0
- package/dist/react-waveform.js.map +7 -0
- package/dist/react-wizard.js +337 -0
- package/dist/react-wizard.js.map +7 -0
- package/dist/styles.css +7 -0
- package/dist/theme.js +1 -1
- package/package.json +3 -2
- package/dist/applicationinsights-web-H7OBLIVJ.js +0 -23393
- package/dist/applicationinsights-web-H7OBLIVJ.js.map +0 -1
- package/dist/chunk-4A4BW3GR.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/module-X3HTTRQK.js +0 -6438
- package/dist/module-X3HTTRQK.js.map +0 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../brand-network-cell/src/brand-network-cell.ts", "../../brand-network-cell/src/brand-network-cell.styles.ts", "../../react-brand-network-cell/src/brand-network-cell.tsx"],
|
|
4
|
+
"sourcesContent": ["import type { AccessibilityProps } from '@refraction-ui/shared'\n\nexport interface BrandNetworkCellProps {\n /** Whether this cell represents the current/active product in the network. */\n current?: boolean\n}\n\nexport interface BrandNetworkCellAPI {\n /** ARIA attributes to spread on the group element (`role=\"group\"`). */\n ariaProps: Partial<AccessibilityProps>\n /** Data attributes for styling hooks. */\n dataAttributes: Record<string, string>\n}\n\n/**\n * Build the framework-agnostic group props for a brand network card.\n *\n * Returns `role=\"group\"` plus a `data-current` attribute so adapters and\n * consumers can style the \"You are here\" state without coupling to class names.\n */\nexport function createBrandNetworkCell(\n props: BrandNetworkCellProps = {},\n): BrandNetworkCellAPI {\n const { current = false } = props\n\n const ariaProps: Partial<AccessibilityProps> = {\n role: 'group',\n }\n\n const dataAttributes: Record<string, string> = {\n 'data-current': String(current),\n }\n\n return { ariaProps, dataAttributes }\n}\n", "import { cva } from '@refraction-ui/shared'\n\n/**\n * Root card container. The `current` variant adds the primary ring that signals\n * \"You are here\". Background and border come from semantic tokens so the card\n * works in both light and dark themes without callers touching class names.\n */\nexport const brandNetworkCellVariants = cva({\n base: [\n 'relative rounded-xl border border-border bg-card p-4',\n 'flex flex-col gap-3 transition-shadow',\n ].join(' '),\n variants: {\n current: {\n true: 'ring-1 ring-primary',\n false: '',\n },\n },\n defaultVariants: {\n current: 'false',\n },\n})\n\n/**\n * Square glyph box — the brand monogram or icon.\n * Background and text colour are caller-provided via inline `style` (brand\n * tints vary per product); this class only controls geometry and typography.\n */\nexport const brandNetworkCellGlyphClass =\n 'flex size-10 items-center justify-center rounded-lg text-sm font-bold'\n\n/** Domain / product name row. */\nexport const brandNetworkCellDomainClass = 'font-semibold text-foreground'\n\n/**\n * \"You are here\" badge shown beside the domain when `current` is true.\n * Uses semantic token colours so it inherits the active theme automatically.\n */\nexport const brandNetworkCellCurrentBadgeClass =\n 'inline-flex items-center rounded-md bg-primary/10 px-2 py-0.5 text-xs font-medium text-primary'\n\n/** Supporting body text below the domain. */\nexport const brandNetworkCellBodyClass = 'text-sm text-muted-foreground'\n\n/** Inline link row rendered at the bottom of the card. */\nexport const brandNetworkCellLinkClass = 'text-sm text-primary'\n", "import * as React from 'react'\nimport {\n createBrandNetworkCell,\n brandNetworkCellVariants,\n brandNetworkCellGlyphClass,\n brandNetworkCellDomainClass,\n brandNetworkCellCurrentBadgeClass,\n brandNetworkCellBodyClass,\n brandNetworkCellLinkClass,\n} from '@refraction-ui/brand-network-cell'\nimport { cn } from '@refraction-ui/shared'\n\nexport interface BrandNetworkCellProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'content'> {\n /** Single character or short string used as the brand monogram. */\n glyph: string\n /** CSS colour value for the glyph box background (brand tint). Applied via inline style. */\n glyphBg?: string\n /** CSS colour value for the glyph text (brand tint). Applied via inline style. */\n glyphColor?: string\n /** Primary identifier shown below the glyph (product domain or name). */\n domain: string\n /** Supporting description text. */\n body: string\n /** When provided, renders a link at the bottom of the card. */\n href?: string\n /** Label for the link. Defaults to \"Visit →\". */\n linkLabel?: string\n /** Marks this cell as the current/active product in the network. */\n current?: boolean\n}\n\n/**\n * BrandNetworkCell — a card for surfacing related products in a brand network.\n *\n * Renders a glyph monogram (brand tint via inline style), the product domain,\n * a \"You are here\" badge when `current`, body copy, and an optional visit link.\n * The `current` variant adds `ring-1 ring-primary` to the card border.\n */\nexport const BrandNetworkCell = React.forwardRef<\n HTMLDivElement,\n BrandNetworkCellProps\n>(\n function BrandNetworkCell(\n {\n glyph,\n glyphBg,\n glyphColor,\n domain,\n body,\n href,\n linkLabel,\n current = false,\n className,\n ...props\n },\n ref,\n ) {\n const api = createBrandNetworkCell({ current })\n\n return (\n <div\n ref={ref}\n className={cn(\n brandNetworkCellVariants({ current: current ? 'true' : 'false' }),\n className,\n )}\n {...api.ariaProps}\n {...api.dataAttributes}\n {...props}\n >\n {/* Glyph box — brand tint via inline style, never Tailwind classes */}\n <div\n className={brandNetworkCellGlyphClass}\n style={{ background: glyphBg, color: glyphColor }}\n aria-hidden=\"true\"\n >\n {glyph}\n </div>\n\n {/* Domain row */}\n <div className=\"flex items-center gap-2\">\n <span className={brandNetworkCellDomainClass}>{domain}</span>\n {current && (\n <span className={brandNetworkCellCurrentBadgeClass}>\n You are here\n </span>\n )}\n </div>\n\n {/* Body */}\n <p className={brandNetworkCellBodyClass}>{body}</p>\n\n {/* Optional link */}\n {href != null && (\n <a href={href} className={brandNetworkCellLinkClass}>\n {linkLabel ?? 'Visit →'}\n </a>\n )}\n </div>\n )\n },\n)\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;AAoBO,SAAS,uBACd,QAA+B,CAAA,GACV;AACrB,QAAM,EAAE,UAAU,MAAA,IAAU;AAE5B,QAAM,YAAyC;IAC7C,MAAM;EAAA;AAGR,QAAM,iBAAyC;IAC7C,gBAAgB,OAAO,OAAO;EAAA;AAGhC,SAAO,EAAE,WAAW,eAAA;AACtB;AC3BO,IAAM,2BAA2B,IAAI;EAC1C,MAAM;IACJ;IACA;EAAA,EACA,KAAK,GAAG;EACV,UAAU;IACR,SAAS;MACP,MAAM;MACN,OAAO;IAAA;EACT;EAEF,iBAAiB;IACf,SAAS;EAAA;AAEb,CAAC;AAOM,IAAM,6BACX;AAGK,IAAM,8BAA8B;AAMpC,IAAM,oCACX;AAGK,IAAM,4BAA4B;AAGlC,IAAM,4BAA4B;;;;ACNlC,IAAM,mBAAyB;EAIpC,SAASA,kBACP;IACE;IACA;IACA;IACA;IACA;IACA;IACA;IACA,UAAU;IACV;IACA,GAAG;EAAA,GAEL,KACA;AACA,UAAM,MAAM,uBAAuB,EAAE,QAAA,CAAS;AAE9C,WACE;MAAC;MAAA;QACC;QACA,WAAW;UACT,yBAAyB,EAAE,SAAS,UAAU,SAAS,QAAA,CAAS;UAChE;QAAA;QAED,GAAG,IAAI;QACP,GAAG,IAAI;QACP,GAAG;QAGJ,UAAA;UAAA;YAAC;YAAA;cACC,WAAW;cACX,OAAO,EAAE,YAAY,SAAS,OAAO,WAAA;cACrC,eAAY;cAEX,UAAA;YAAA;UAAA;UAIH,qBAAC,OAAA,EAAI,WAAU,2BACb,UAAA;YAAA,oBAAC,QAAA,EAAK,WAAW,6BAA8B,UAAA,OAAA,CAAO;YACrD,WACC,oBAAC,QAAA,EAAK,WAAW,mCAAmC,UAAA,eAAA,CAEpD;UAAA,EAAA,CAEJ;UAGA,oBAAC,KAAA,EAAE,WAAW,2BAA4B,UAAA,KAAA,CAAK;UAG9C,QAAQ,QACP,oBAAC,KAAA,EAAE,MAAY,WAAW,2BACvB,UAAA,aAAa,eAAA,CAChB;QAAA;MAAA;IAAA;EAIR;AACF;",
|
|
6
|
+
"names": ["BrandNetworkCell"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cn,
|
|
3
|
+
cva
|
|
4
|
+
} from "./chunk-ZF3OHCGV.js";
|
|
5
|
+
|
|
6
|
+
// ../react-breadcrumbs/dist/index.js
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
|
|
9
|
+
// ../breadcrumbs/dist/index.js
|
|
10
|
+
function kebabToTitle(segment) {
|
|
11
|
+
return segment.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
12
|
+
}
|
|
13
|
+
function pathToItems(pathname, labels = {}) {
|
|
14
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
15
|
+
const items = [{ label: "Home", href: "/" }];
|
|
16
|
+
let currentPath = "";
|
|
17
|
+
for (const segment of segments) {
|
|
18
|
+
currentPath += `/${segment}`;
|
|
19
|
+
items.push({
|
|
20
|
+
label: labels[segment] ?? labels[currentPath] ?? kebabToTitle(segment),
|
|
21
|
+
href: currentPath
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return items;
|
|
25
|
+
}
|
|
26
|
+
function createBreadcrumbs(props = {}) {
|
|
27
|
+
const { pathname, items: manualItems, labels = {}, separator = "/", maxItems } = props;
|
|
28
|
+
let items = manualItems ?? (pathname ? pathToItems(pathname, labels) : []);
|
|
29
|
+
if (maxItems && items.length > maxItems) {
|
|
30
|
+
const first = items[0];
|
|
31
|
+
const last = items.slice(-(maxItems - 1));
|
|
32
|
+
items = [first, { label: "..." }, ...last];
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
items,
|
|
36
|
+
ariaProps: { "aria-label": "Breadcrumb" },
|
|
37
|
+
separator,
|
|
38
|
+
isLast: (index) => index === items.length - 1,
|
|
39
|
+
itemAriaProps: (index) => index === items.length - 1 ? { "aria-current": "page" } : {}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
var breadcrumbsVariants = cva({
|
|
43
|
+
base: "flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground"
|
|
44
|
+
});
|
|
45
|
+
var breadcrumbItemVariants = cva({
|
|
46
|
+
base: "transition-colors",
|
|
47
|
+
variants: {
|
|
48
|
+
active: {
|
|
49
|
+
true: "font-medium text-foreground",
|
|
50
|
+
false: "hover:text-foreground"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
defaultVariants: {
|
|
54
|
+
active: "false"
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
var breadcrumbSeparatorStyles = "text-muted-foreground/50 select-none";
|
|
58
|
+
|
|
59
|
+
// ../react-breadcrumbs/dist/index.js
|
|
60
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
61
|
+
var Breadcrumbs = React.forwardRef(
|
|
62
|
+
function Breadcrumbs2({
|
|
63
|
+
pathname,
|
|
64
|
+
items,
|
|
65
|
+
labels,
|
|
66
|
+
separator,
|
|
67
|
+
maxItems,
|
|
68
|
+
className,
|
|
69
|
+
...props
|
|
70
|
+
}, ref) {
|
|
71
|
+
const api = createBreadcrumbs({ pathname, items, labels, separator, maxItems });
|
|
72
|
+
const classes = cn(breadcrumbsVariants(), className);
|
|
73
|
+
return /* @__PURE__ */ jsx("nav", { ref, className: classes, ...api.ariaProps, ...props, children: /* @__PURE__ */ jsx("ol", { className: "flex items-center gap-1.5", children: api.items.map((item, index) => {
|
|
74
|
+
const isLast = api.isLast(index);
|
|
75
|
+
return /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-1.5", children: [
|
|
76
|
+
index > 0 && /* @__PURE__ */ jsx("span", { className: breadcrumbSeparatorStyles, "aria-hidden": "true", children: api.separator }),
|
|
77
|
+
item.href && !isLast ? /* @__PURE__ */ jsx(
|
|
78
|
+
"a",
|
|
79
|
+
{
|
|
80
|
+
href: item.href,
|
|
81
|
+
className: breadcrumbItemVariants({ active: "false" }),
|
|
82
|
+
children: item.label
|
|
83
|
+
}
|
|
84
|
+
) : /* @__PURE__ */ jsx(
|
|
85
|
+
"span",
|
|
86
|
+
{
|
|
87
|
+
className: breadcrumbItemVariants({
|
|
88
|
+
active: isLast ? "true" : "false"
|
|
89
|
+
}),
|
|
90
|
+
...api.itemAriaProps(index),
|
|
91
|
+
children: item.label
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
] }, index);
|
|
95
|
+
}) }) });
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
export {
|
|
99
|
+
Breadcrumbs,
|
|
100
|
+
breadcrumbItemVariants,
|
|
101
|
+
breadcrumbSeparatorStyles,
|
|
102
|
+
breadcrumbsVariants
|
|
103
|
+
};
|
|
104
|
+
//# sourceMappingURL=react-breadcrumbs.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../breadcrumbs/src/breadcrumbs.ts", "../../breadcrumbs/src/breadcrumbs.styles.ts", "../../react-breadcrumbs/src/breadcrumbs.tsx"],
|
|
4
|
+
"sourcesContent": ["export interface BreadcrumbItem {\n label: string\n href?: string\n}\n\nexport interface BreadcrumbsProps {\n /** Current pathname to auto-generate from */\n pathname?: string\n /** Manual items (overrides pathname) */\n items?: BreadcrumbItem[]\n /** Custom label map for pathname segments */\n labels?: Record<string, string>\n /** Separator character */\n separator?: string\n /** Max items to show before truncating */\n maxItems?: number\n}\n\nexport interface BreadcrumbsAPI {\n items: BreadcrumbItem[]\n ariaProps: Record<string, string>\n separator: string\n isLast: (index: number) => boolean\n itemAriaProps: (index: number) => Record<string, string>\n}\n\nfunction kebabToTitle(segment: string): string {\n return segment\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ')\n}\n\nfunction pathToItems(\n pathname: string,\n labels: Record<string, string> = {},\n): BreadcrumbItem[] {\n const segments = pathname.split('/').filter(Boolean)\n const items: BreadcrumbItem[] = [{ label: 'Home', href: '/' }]\n\n let currentPath = ''\n for (const segment of segments) {\n currentPath += `/${segment}`\n items.push({\n label: labels[segment] ?? labels[currentPath] ?? kebabToTitle(segment),\n href: currentPath,\n })\n }\n\n return items\n}\n\nexport function createBreadcrumbs(props: BreadcrumbsProps = {}): BreadcrumbsAPI {\n const { pathname, items: manualItems, labels = {}, separator = '/', maxItems } = props\n\n let items = manualItems ?? (pathname ? pathToItems(pathname, labels) : [])\n\n if (maxItems && items.length > maxItems) {\n const first = items[0]\n const last = items.slice(-(maxItems - 1))\n items = [first, { label: '...' }, ...last]\n }\n\n return {\n items,\n ariaProps: { 'aria-label': 'Breadcrumb' },\n separator,\n isLast: (index: number) => index === items.length - 1,\n itemAriaProps: (index: number): Record<string, string> =>\n index === items.length - 1 ? { 'aria-current': 'page' } : {},\n }\n}\n", "import { cva } from '@refraction-ui/shared'\n\nexport const breadcrumbsVariants = cva({\n base: 'flex flex-wrap items-center gap-1.5 text-sm text-muted-foreground',\n})\n\nexport const breadcrumbItemVariants = cva({\n base: 'transition-colors',\n variants: {\n active: {\n true: 'font-medium text-foreground',\n false: 'hover:text-foreground',\n },\n },\n defaultVariants: {\n active: 'false',\n },\n})\n\nexport const breadcrumbSeparatorStyles = 'text-muted-foreground/50 select-none'\n", "import * as React from 'react'\nimport {\n createBreadcrumbs,\n breadcrumbsVariants,\n breadcrumbItemVariants,\n breadcrumbSeparatorStyles,\n type BreadcrumbItem,\n} from '@refraction-ui/breadcrumbs'\nimport { cn } from '@refraction-ui/shared'\n\nexport interface BreadcrumbsProps extends React.HTMLAttributes<HTMLElement> {\n /** Current pathname to auto-generate breadcrumbs from */\n pathname?: string\n /** Manual breadcrumb items (overrides pathname) */\n items?: BreadcrumbItem[]\n /** Custom label map for pathname segments */\n labels?: Record<string, string>\n /** Separator character. Default: '/' */\n separator?: string\n /** Max items before truncation */\n maxItems?: number\n}\n\n/**\n * Breadcrumbs component — renders a breadcrumb navigation trail.\n *\n * Uses the headless @refraction-ui/breadcrumbs core for state and ARIA attributes.\n */\nexport const Breadcrumbs = React.forwardRef<HTMLElement, BreadcrumbsProps>(\n function Breadcrumbs(\n {\n pathname,\n items,\n labels,\n separator,\n maxItems,\n className,\n ...props\n },\n ref,\n ) {\n const api = createBreadcrumbs({ pathname, items, labels, separator, maxItems })\n const classes = cn(breadcrumbsVariants(), className)\n\n return (\n <nav ref={ref} className={classes} {...api.ariaProps} {...props}>\n <ol className=\"flex items-center gap-1.5\">\n {api.items.map((item, index) => {\n const isLast = api.isLast(index)\n return (\n <li key={index} className=\"flex items-center gap-1.5\">\n {index > 0 && (\n <span className={breadcrumbSeparatorStyles} aria-hidden=\"true\">\n {api.separator}\n </span>\n )}\n {item.href && !isLast ? (\n <a\n href={item.href}\n className={breadcrumbItemVariants({ active: 'false' })}\n >\n {item.label}\n </a>\n ) : (\n <span\n className={breadcrumbItemVariants({\n active: isLast ? 'true' : 'false',\n })}\n {...api.itemAriaProps(index)}\n >\n {item.label}\n </span>\n )}\n </li>\n )\n })}\n </ol>\n </nav>\n )\n },\n)\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;AA0BA,SAAS,aAAa,SAAyB;AAC7C,SAAO,QACJ,MAAM,GAAG,EACT,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAA,IAAgB,KAAK,MAAM,CAAC,CAAC,EAC1D,KAAK,GAAG;AACb;AAEA,SAAS,YACP,UACA,SAAiC,CAAA,GACf;AAClB,QAAM,WAAW,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AACnD,QAAM,QAA0B,CAAC,EAAE,OAAO,QAAQ,MAAM,IAAA,CAAK;AAE7D,MAAI,cAAc;AAClB,aAAW,WAAW,UAAU;AAC9B,mBAAe,IAAI,OAAO;AAC1B,UAAM,KAAK;MACT,OAAO,OAAO,OAAO,KAAK,OAAO,WAAW,KAAK,aAAa,OAAO;MACrE,MAAM;IAAA,CACP;EACH;AAEA,SAAO;AACT;AAEO,SAAS,kBAAkB,QAA0B,CAAA,GAAoB;AAC9E,QAAM,EAAE,UAAU,OAAO,aAAa,SAAS,CAAA,GAAI,YAAY,KAAK,SAAA,IAAa;AAEjF,MAAI,QAAQ,gBAAgB,WAAW,YAAY,UAAU,MAAM,IAAI,CAAA;AAEvE,MAAI,YAAY,MAAM,SAAS,UAAU;AACvC,UAAM,QAAQ,MAAM,CAAC;AACrB,UAAM,OAAO,MAAM,MAAM,EAAE,WAAW,EAAE;AACxC,YAAQ,CAAC,OAAO,EAAE,OAAO,MAAA,GAAS,GAAG,IAAI;EAC3C;AAEA,SAAO;IACL;IACA,WAAW,EAAE,cAAc,aAAA;IAC3B;IACA,QAAQ,CAAC,UAAkB,UAAU,MAAM,SAAS;IACpD,eAAe,CAAC,UACd,UAAU,MAAM,SAAS,IAAI,EAAE,gBAAgB,OAAA,IAAW,CAAA;EAAC;AAEjE;ACrEO,IAAM,sBAAsB,IAAI;EACrC,MAAM;AACR,CAAC;AAEM,IAAM,yBAAyB,IAAI;EACxC,MAAM;EACN,UAAU;IACR,QAAQ;MACN,MAAM;MACN,OAAO;IAAA;EACT;EAEF,iBAAiB;IACf,QAAQ;EAAA;AAEZ,CAAC;AAEM,IAAM,4BAA4B;;;;ACSlC,IAAM,cAAoB;EAC/B,SAASA,aACP;IACE;IACA;IACA;IACA;IACA;IACA;IACA,GAAG;EAAA,GAEL,KACA;AACA,UAAM,MAAM,kBAAkB,EAAE,UAAU,OAAO,QAAQ,WAAW,SAAA,CAAU;AAC9E,UAAM,UAAU,GAAG,oBAAA,GAAuB,SAAS;AAEnD,WAAA,oBACG,OAAA,EAAI,KAAU,WAAW,SAAU,GAAG,IAAI,WAAY,GAAG,OACxD,UAAA,oBAAC,MAAA,EAAG,WAAU,6BACX,UAAA,IAAI,MAAM,IAAI,CAAC,MAAM,UAAU;AAC9B,YAAM,SAAS,IAAI,OAAO,KAAK;AAC/B,aACE,qBAAC,MAAA,EAAe,WAAU,6BACvB,UAAA;QAAA,QAAQ,KAAA,oBACN,QAAA,EAAK,WAAW,2BAA2B,eAAY,QACrD,UAAA,IAAI,UAAA,CACP;QAED,KAAK,QAAQ,CAAC,SACb;UAAC;UAAA;YACC,MAAM,KAAK;YACX,WAAW,uBAAuB,EAAE,QAAQ,QAAA,CAAS;YAEpD,UAAA,KAAK;UAAA;QAAA,IAGR;UAAC;UAAA;YACC,WAAW,uBAAuB;cAChC,QAAQ,SAAS,SAAS;YAAA,CAC3B;YACA,GAAG,IAAI,cAAc,KAAK;YAE1B,UAAA,KAAK;UAAA;QAAA;MACR,EAAA,GArBK,KAuBT;IAEJ,CAAC,EAAA,CACH,EAAA,CACF;EAEJ;AACF;",
|
|
6
|
+
"names": ["Breadcrumbs"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cn,
|
|
3
|
+
cva
|
|
4
|
+
} from "./chunk-ZF3OHCGV.js";
|
|
5
|
+
|
|
6
|
+
// ../react-browser-chrome-mock/dist/index.js
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
|
|
9
|
+
// ../browser-chrome-mock/dist/index.js
|
|
10
|
+
function splitUrl(url) {
|
|
11
|
+
const slashIndex = url.indexOf("/");
|
|
12
|
+
if (slashIndex === -1) {
|
|
13
|
+
return { domain: url, path: "" };
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
domain: url.slice(0, slashIndex),
|
|
17
|
+
path: url.slice(slashIndex)
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function createBrowserChromeMock(props = {}) {
|
|
21
|
+
const { status } = props;
|
|
22
|
+
const ariaProps = {
|
|
23
|
+
role: "group",
|
|
24
|
+
"aria-label": "Browser preview"
|
|
25
|
+
};
|
|
26
|
+
const dataAttributes = {};
|
|
27
|
+
if (status !== void 0) {
|
|
28
|
+
dataAttributes["data-status"] = status;
|
|
29
|
+
}
|
|
30
|
+
return { ariaProps, dataAttributes };
|
|
31
|
+
}
|
|
32
|
+
var browserChromeMockVariants = cva({
|
|
33
|
+
base: "rounded-xl border border-border overflow-hidden bg-card",
|
|
34
|
+
variants: {},
|
|
35
|
+
defaultVariants: {}
|
|
36
|
+
});
|
|
37
|
+
var chromeBarClass = "flex items-center gap-2 bg-muted/40 border-b border-border px-3 py-2";
|
|
38
|
+
var trafficDotClass = "size-2.5 rounded-full border border-border";
|
|
39
|
+
var urlBarClass = "flex-1 text-center font-mono text-[11px] text-muted-foreground";
|
|
40
|
+
var urlDomainClass = "font-semibold text-foreground";
|
|
41
|
+
var statusBadgeVariants = cva({
|
|
42
|
+
base: "inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide",
|
|
43
|
+
variants: {
|
|
44
|
+
status: {
|
|
45
|
+
live: "text-emerald-500 bg-emerald-500/10",
|
|
46
|
+
rec: "text-destructive bg-destructive/10"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
defaultVariants: {
|
|
50
|
+
status: "live"
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
var contentAreaClass = "p-0";
|
|
54
|
+
|
|
55
|
+
// ../react-browser-chrome-mock/dist/index.js
|
|
56
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
57
|
+
var TRAFFIC_DOTS = ["bg-red-400", "bg-yellow-400", "bg-green-400"];
|
|
58
|
+
var BrowserChromeMock = React.forwardRef(function BrowserChromeMock2({ url, status, className, children, ...props }, ref) {
|
|
59
|
+
const { ariaProps, dataAttributes } = createBrowserChromeMock({ status });
|
|
60
|
+
const { domain, path } = splitUrl(url);
|
|
61
|
+
return /* @__PURE__ */ jsxs(
|
|
62
|
+
"div",
|
|
63
|
+
{
|
|
64
|
+
ref,
|
|
65
|
+
className: cn(browserChromeMockVariants(), className),
|
|
66
|
+
...ariaProps,
|
|
67
|
+
...dataAttributes,
|
|
68
|
+
...props,
|
|
69
|
+
children: [
|
|
70
|
+
/* @__PURE__ */ jsxs("div", { className: chromeBarClass, children: [
|
|
71
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 shrink-0", children: TRAFFIC_DOTS.map((color) => /* @__PURE__ */ jsx("span", { className: cn(trafficDotClass, color) }, color)) }),
|
|
72
|
+
/* @__PURE__ */ jsxs("div", { className: urlBarClass, children: [
|
|
73
|
+
/* @__PURE__ */ jsx("span", { className: urlDomainClass, children: domain }),
|
|
74
|
+
path && /* @__PURE__ */ jsx("span", { children: path })
|
|
75
|
+
] }),
|
|
76
|
+
status && /* @__PURE__ */ jsxs("div", { className: statusBadgeVariants({ status }), children: [
|
|
77
|
+
status === "rec" && /* @__PURE__ */ jsx("span", { className: "size-1.5 rounded-full bg-destructive animate-pulse" }),
|
|
78
|
+
status
|
|
79
|
+
] })
|
|
80
|
+
] }),
|
|
81
|
+
/* @__PURE__ */ jsx("div", { className: contentAreaClass, children })
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
export {
|
|
87
|
+
BrowserChromeMock
|
|
88
|
+
};
|
|
89
|
+
//# sourceMappingURL=react-browser-chrome-mock.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../browser-chrome-mock/src/browser-chrome-mock.ts", "../../browser-chrome-mock/src/browser-chrome-mock.styles.ts", "../../react-browser-chrome-mock/src/browser-chrome-mock.tsx"],
|
|
4
|
+
"sourcesContent": ["/** Recording or live stream status for the browser chrome mock. */\nexport type BrowserChromeStatus = 'live' | 'rec'\n\nexport interface BrowserChromeMockProps {\n /** URL to display in the address bar. */\n url: string\n /** Optional status badge shown in the chrome bar. */\n status?: BrowserChromeStatus\n}\n\nexport interface BrowserChromeMockAPI {\n /** ARIA attributes to spread on the group element. */\n ariaProps: { role: 'group'; 'aria-label': string }\n /** Data attributes for styling hooks. */\n dataAttributes: Record<string, string>\n}\n\n/** Split a URL into bold domain and normal path segments. */\nexport function splitUrl(url: string): { domain: string; path: string } {\n const slashIndex = url.indexOf('/')\n if (slashIndex === -1) {\n return { domain: url, path: '' }\n }\n return {\n domain: url.slice(0, slashIndex),\n path: url.slice(slashIndex),\n }\n}\n\n/**\n * Build the framework-agnostic props for a BrowserChromeMock.\n *\n * Returns a `role=\"group\"` aria label plus optional `data-status` so adapters\n * can hook CSS without duplicating logic.\n */\nexport function createBrowserChromeMock(\n props: Pick<BrowserChromeMockProps, 'status'> = {},\n): BrowserChromeMockAPI {\n const { status } = props\n\n const ariaProps = {\n role: 'group' as const,\n 'aria-label': 'Browser preview',\n }\n\n const dataAttributes: Record<string, string> = {}\n if (status !== undefined) {\n dataAttributes['data-status'] = status\n }\n\n return { ariaProps, dataAttributes }\n}\n", "import { cva } from '@refraction-ui/shared'\n\n/** Outer frame wrapping the chrome bar and content. */\nexport const browserChromeMockVariants = cva({\n base: 'rounded-xl border border-border overflow-hidden bg-card',\n variants: {},\n defaultVariants: {},\n})\n\n/** The chrome toolbar row containing dots, URL bar, and optional badge. */\nexport const chromeBarClass =\n 'flex items-center gap-2 bg-muted/40 border-b border-border px-3 py-2'\n\n/** A single traffic-light dot. */\nexport const trafficDotClass = 'size-2.5 rounded-full border border-border'\n\n/** Centered URL bar. */\nexport const urlBarClass = 'flex-1 text-center font-mono text-[11px] text-muted-foreground'\n\n/** Bold domain segment inside the URL bar. */\nexport const urlDomainClass = 'font-semibold text-foreground'\n\n/**\n * Status badge shown in the chrome bar.\n *\n * live → emerald tint (approved exception to semantic tokens)\n * rec → destructive tint with a pulsing dot\n */\nexport const statusBadgeVariants = cva({\n base: 'inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide',\n variants: {\n status: {\n live: 'text-emerald-500 bg-emerald-500/10',\n rec: 'text-destructive bg-destructive/10',\n },\n },\n defaultVariants: {\n status: 'live',\n },\n})\n\n/** Inner content area that receives slotted/children content. */\nexport const contentAreaClass = 'p-0'\n", "import * as React from 'react'\nimport {\n createBrowserChromeMock,\n splitUrl,\n browserChromeMockVariants,\n chromeBarClass,\n trafficDotClass,\n urlBarClass,\n urlDomainClass,\n statusBadgeVariants,\n contentAreaClass,\n type BrowserChromeStatus,\n} from '@refraction-ui/browser-chrome-mock'\nimport { cn } from '@refraction-ui/shared'\n\nexport type { BrowserChromeStatus }\n\nexport interface BrowserChromeMockProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'content'> {\n /** URL to display in the address bar. Bold domain + normal path. */\n url: string\n /** Optional status badge shown in the chrome bar. */\n status?: BrowserChromeStatus\n}\n\n/** Three traffic-light dots rendered in the chrome bar. */\nconst TRAFFIC_DOTS = ['bg-red-400', 'bg-yellow-400', 'bg-green-400'] as const\n\n/**\n * BrowserChromeMock — a decorative browser window frame.\n *\n * Renders a mock browser chrome with traffic-light dots, a monospace URL bar\n * (bold domain + normal path), an optional live/rec status badge, and a\n * content area for arbitrary children. Logic and styles come from the headless\n * `@refraction-ui/browser-chrome-mock` core.\n */\nexport const BrowserChromeMock = React.forwardRef<\n HTMLDivElement,\n BrowserChromeMockProps\n>(function BrowserChromeMock({ url, status, className, children, ...props }, ref) {\n const { ariaProps, dataAttributes } = createBrowserChromeMock({ status })\n const { domain, path } = splitUrl(url)\n\n return (\n <div\n ref={ref}\n className={cn(browserChromeMockVariants(), className)}\n {...ariaProps}\n {...dataAttributes}\n {...props}\n >\n {/* Chrome toolbar */}\n <div className={chromeBarClass}>\n {/* Traffic-light dots */}\n <div className=\"flex items-center gap-1.5 shrink-0\">\n {TRAFFIC_DOTS.map((color) => (\n <span key={color} className={cn(trafficDotClass, color)} />\n ))}\n </div>\n\n {/* URL bar */}\n <div className={urlBarClass}>\n <span className={urlDomainClass}>{domain}</span>\n {path && <span>{path}</span>}\n </div>\n\n {/* Status badge */}\n {status && (\n <div className={statusBadgeVariants({ status })}>\n {status === 'rec' && (\n <span className=\"size-1.5 rounded-full bg-destructive animate-pulse\" />\n )}\n {status}\n </div>\n )}\n </div>\n\n {/* Content area */}\n <div className={contentAreaClass}>{children}</div>\n </div>\n )\n})\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;AAkBO,SAAS,SAAS,KAA+C;AACtE,QAAM,aAAa,IAAI,QAAQ,GAAG;AAClC,MAAI,eAAe,IAAI;AACrB,WAAO,EAAE,QAAQ,KAAK,MAAM,GAAA;EAC9B;AACA,SAAO;IACL,QAAQ,IAAI,MAAM,GAAG,UAAU;IAC/B,MAAM,IAAI,MAAM,UAAU;EAAA;AAE9B;AAQO,SAAS,wBACd,QAAgD,CAAA,GAC1B;AACtB,QAAM,EAAE,OAAA,IAAW;AAEnB,QAAM,YAAY;IAChB,MAAM;IACN,cAAc;EAAA;AAGhB,QAAM,iBAAyC,CAAA;AAC/C,MAAI,WAAW,QAAW;AACxB,mBAAe,aAAa,IAAI;EAClC;AAEA,SAAO,EAAE,WAAW,eAAA;AACtB;AChDO,IAAM,4BAA4B,IAAI;EAC3C,MAAM;EACN,UAAU,CAAA;EACV,iBAAiB,CAAA;AACnB,CAAC;AAGM,IAAM,iBACX;AAGK,IAAM,kBAAkB;AAGxB,IAAM,cAAc;AAGpB,IAAM,iBAAiB;AAQvB,IAAM,sBAAsB,IAAI;EACrC,MAAM;EACN,UAAU;IACR,QAAQ;MACN,MAAM;MACN,KAAK;IAAA;EACP;EAEF,iBAAiB;IACf,QAAQ;EAAA;AAEZ,CAAC;AAGM,IAAM,mBAAmB;;;;AChBhC,IAAM,eAAe,CAAC,cAAc,iBAAiB,cAAc;AAU5D,IAAM,oBAA0B,iBAGrC,SAASA,mBAAkB,EAAE,KAAK,QAAQ,WAAW,UAAU,GAAG,MAAA,GAAS,KAAK;AAChF,QAAM,EAAE,WAAW,eAAA,IAAmB,wBAAwB,EAAE,OAAA,CAAQ;AACxE,QAAM,EAAE,QAAQ,KAAA,IAAS,SAAS,GAAG;AAErC,SACE;IAAC;IAAA;MACC;MACA,WAAW,GAAG,0BAAA,GAA6B,SAAS;MACnD,GAAG;MACH,GAAG;MACH,GAAG;MAGJ,UAAA;QAAA,qBAAC,OAAA,EAAI,WAAW,gBAEd,UAAA;UAAA,oBAAC,OAAA,EAAI,WAAU,sCACZ,UAAA,aAAa,IAAI,CAAC,UACjB,oBAAC,QAAA,EAAiB,WAAW,GAAG,iBAAiB,KAAK,EAAA,GAA3C,KAA8C,CAC1D,EAAA,CACH;UAGA,qBAAC,OAAA,EAAI,WAAW,aACd,UAAA;YAAA,oBAAC,QAAA,EAAK,WAAW,gBAAiB,UAAA,OAAA,CAAO;YACxC,QAAQ,oBAAC,QAAA,EAAM,UAAA,KAAA,CAAK;UAAA,EAAA,CACvB;UAGC,UAAA,qBACE,OAAA,EAAI,WAAW,oBAAoB,EAAE,OAAA,CAAQ,GAC3C,UAAA;YAAA,WAAW,SACV,oBAAC,QAAA,EAAK,WAAU,qDAAA,CAAqD;YAEtE;UAAA,EAAA,CACH;QAAA,EAAA,CAEJ;QAGA,oBAAC,OAAA,EAAI,WAAW,kBAAmB,SAAA,CAAS;MAAA;IAAA;EAAA;AAGlD,CAAC;",
|
|
6
|
+
"names": ["BrowserChromeMock"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cn,
|
|
3
|
+
cva,
|
|
4
|
+
generateId
|
|
5
|
+
} from "./chunk-ZF3OHCGV.js";
|
|
6
|
+
|
|
7
|
+
// ../react-calendar/dist/index.js
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
|
|
10
|
+
// ../calendar/dist/index.js
|
|
11
|
+
function isSameDay(a, b) {
|
|
12
|
+
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
13
|
+
}
|
|
14
|
+
function startOfMonth(date) {
|
|
15
|
+
return new Date(date.getFullYear(), date.getMonth(), 1);
|
|
16
|
+
}
|
|
17
|
+
var DAY_NAMES = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
|
18
|
+
function createCalendar(props = {}) {
|
|
19
|
+
const {
|
|
20
|
+
value: controlledValue,
|
|
21
|
+
defaultValue,
|
|
22
|
+
onSelect,
|
|
23
|
+
month: controlledMonth,
|
|
24
|
+
onMonthChange,
|
|
25
|
+
minDate,
|
|
26
|
+
maxDate,
|
|
27
|
+
disabledDates = [],
|
|
28
|
+
today: injectedToday
|
|
29
|
+
} = props;
|
|
30
|
+
const today = injectedToday ?? /* @__PURE__ */ new Date();
|
|
31
|
+
const selectedDate = controlledValue ?? defaultValue;
|
|
32
|
+
const currentMonth = controlledMonth ? startOfMonth(controlledMonth) : selectedDate ? startOfMonth(selectedDate) : startOfMonth(today);
|
|
33
|
+
const gridId = generateId("rfr-calendar");
|
|
34
|
+
const labelId = generateId("rfr-calendar-label");
|
|
35
|
+
function isDateDisabled(date) {
|
|
36
|
+
if (minDate && date < startOfDay(minDate)) return true;
|
|
37
|
+
if (maxDate && date > endOfDay(maxDate)) return true;
|
|
38
|
+
return disabledDates.some((d) => isSameDay(d, date));
|
|
39
|
+
}
|
|
40
|
+
function startOfDay(date) {
|
|
41
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
42
|
+
}
|
|
43
|
+
function endOfDay(date) {
|
|
44
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999);
|
|
45
|
+
}
|
|
46
|
+
function buildDays() {
|
|
47
|
+
const year = currentMonth.getFullYear();
|
|
48
|
+
const month = currentMonth.getMonth();
|
|
49
|
+
const first = new Date(year, month, 1);
|
|
50
|
+
const startDow = first.getDay();
|
|
51
|
+
const gridStart = new Date(year, month, 1 - startDow);
|
|
52
|
+
const days = [];
|
|
53
|
+
for (let i = 0; i < 42; i++) {
|
|
54
|
+
const date = new Date(
|
|
55
|
+
gridStart.getFullYear(),
|
|
56
|
+
gridStart.getMonth(),
|
|
57
|
+
gridStart.getDate() + i
|
|
58
|
+
);
|
|
59
|
+
days.push({
|
|
60
|
+
date,
|
|
61
|
+
isToday: isSameDay(date, today),
|
|
62
|
+
isSelected: selectedDate ? isSameDay(date, selectedDate) : false,
|
|
63
|
+
isCurrentMonth: date.getMonth() === month,
|
|
64
|
+
isDisabled: isDateDisabled(date)
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return days;
|
|
68
|
+
}
|
|
69
|
+
function prevMonth() {
|
|
70
|
+
const prev = new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1, 1);
|
|
71
|
+
onMonthChange?.(prev);
|
|
72
|
+
}
|
|
73
|
+
function nextMonth() {
|
|
74
|
+
const next = new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1, 1);
|
|
75
|
+
onMonthChange?.(next);
|
|
76
|
+
}
|
|
77
|
+
function select(date) {
|
|
78
|
+
if (!isDateDisabled(date)) {
|
|
79
|
+
onSelect?.(date);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const ariaProps = {
|
|
83
|
+
role: "grid",
|
|
84
|
+
"aria-labelledby": labelId,
|
|
85
|
+
id: gridId
|
|
86
|
+
};
|
|
87
|
+
function getDayAriaProps(day) {
|
|
88
|
+
return {
|
|
89
|
+
role: "gridcell",
|
|
90
|
+
"aria-selected": day.isSelected,
|
|
91
|
+
"aria-disabled": day.isDisabled,
|
|
92
|
+
// Key absent (not undefined) when not today — the ARIA record type excludes undefined.
|
|
93
|
+
...day.isToday ? { "aria-current": "date" } : {},
|
|
94
|
+
"aria-label": `${DAY_NAMES[day.date.getDay()]}, ${day.date.toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" })}`
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
state: {
|
|
99
|
+
currentMonth,
|
|
100
|
+
selectedDate
|
|
101
|
+
},
|
|
102
|
+
days: buildDays(),
|
|
103
|
+
prevMonth,
|
|
104
|
+
nextMonth,
|
|
105
|
+
select,
|
|
106
|
+
ariaProps,
|
|
107
|
+
getDayAriaProps,
|
|
108
|
+
ids: {
|
|
109
|
+
grid: gridId,
|
|
110
|
+
label: labelId
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
var calendarVariants = cva({
|
|
115
|
+
base: "p-3 rounded-md border bg-background"
|
|
116
|
+
});
|
|
117
|
+
var dayVariants = cva({
|
|
118
|
+
base: "inline-flex items-center justify-center rounded-md text-sm h-9 w-9",
|
|
119
|
+
variants: {
|
|
120
|
+
state: {
|
|
121
|
+
default: "hover:bg-accent hover:text-accent-foreground",
|
|
122
|
+
selected: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
123
|
+
today: "bg-accent text-accent-foreground",
|
|
124
|
+
disabled: "text-muted-foreground opacity-50 cursor-not-allowed",
|
|
125
|
+
outside: "text-muted-foreground opacity-50"
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
defaultVariants: {
|
|
129
|
+
state: "default"
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// ../react-calendar/dist/index.js
|
|
134
|
+
var MONTH_NAMES = [
|
|
135
|
+
"January",
|
|
136
|
+
"February",
|
|
137
|
+
"March",
|
|
138
|
+
"April",
|
|
139
|
+
"May",
|
|
140
|
+
"June",
|
|
141
|
+
"July",
|
|
142
|
+
"August",
|
|
143
|
+
"September",
|
|
144
|
+
"October",
|
|
145
|
+
"November",
|
|
146
|
+
"December"
|
|
147
|
+
];
|
|
148
|
+
var DAY_HEADERS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
149
|
+
var Calendar = React.forwardRef(
|
|
150
|
+
function Calendar2({ className, value, defaultValue, onSelect, month, onMonthChange, minDate, maxDate, disabledDates }, ref) {
|
|
151
|
+
const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue);
|
|
152
|
+
const [uncontrolledMonth, setUncontrolledMonth] = React.useState(
|
|
153
|
+
() => month ?? value ?? defaultValue ?? /* @__PURE__ */ new Date()
|
|
154
|
+
);
|
|
155
|
+
const isValueControlled = value !== void 0;
|
|
156
|
+
const isMonthControlled = month !== void 0;
|
|
157
|
+
const selectedValue = isValueControlled ? value : uncontrolledValue;
|
|
158
|
+
const displayMonth = isMonthControlled ? month : uncontrolledMonth;
|
|
159
|
+
const handleSelect = React.useCallback(
|
|
160
|
+
(date) => {
|
|
161
|
+
if (!isValueControlled) {
|
|
162
|
+
setUncontrolledValue(date);
|
|
163
|
+
}
|
|
164
|
+
onSelect?.(date);
|
|
165
|
+
},
|
|
166
|
+
[isValueControlled, onSelect]
|
|
167
|
+
);
|
|
168
|
+
const handleMonthChange = React.useCallback(
|
|
169
|
+
(m) => {
|
|
170
|
+
if (!isMonthControlled) {
|
|
171
|
+
setUncontrolledMonth(m);
|
|
172
|
+
}
|
|
173
|
+
onMonthChange?.(m);
|
|
174
|
+
},
|
|
175
|
+
[isMonthControlled, onMonthChange]
|
|
176
|
+
);
|
|
177
|
+
const api = createCalendar({
|
|
178
|
+
value: selectedValue,
|
|
179
|
+
month: displayMonth,
|
|
180
|
+
onSelect: handleSelect,
|
|
181
|
+
onMonthChange: handleMonthChange,
|
|
182
|
+
minDate,
|
|
183
|
+
maxDate,
|
|
184
|
+
disabledDates
|
|
185
|
+
});
|
|
186
|
+
function getDayState(day) {
|
|
187
|
+
if (day.isDisabled) return "disabled";
|
|
188
|
+
if (day.isSelected) return "selected";
|
|
189
|
+
if (!day.isCurrentMonth) return "outside";
|
|
190
|
+
if (day.isToday) return "today";
|
|
191
|
+
return "default";
|
|
192
|
+
}
|
|
193
|
+
const monthLabel = `${MONTH_NAMES[api.state.currentMonth.getMonth()]} ${api.state.currentMonth.getFullYear()}`;
|
|
194
|
+
return React.createElement(
|
|
195
|
+
"div",
|
|
196
|
+
{
|
|
197
|
+
ref,
|
|
198
|
+
className: cn(calendarVariants(), className),
|
|
199
|
+
...api.ariaProps
|
|
200
|
+
},
|
|
201
|
+
// Header row: prev, month label, next
|
|
202
|
+
React.createElement(CalendarHeader, {
|
|
203
|
+
label: monthLabel,
|
|
204
|
+
labelId: api.ids.label,
|
|
205
|
+
onPrevMonth: api.prevMonth,
|
|
206
|
+
onNextMonth: api.nextMonth
|
|
207
|
+
}),
|
|
208
|
+
// Day-of-week headers
|
|
209
|
+
React.createElement(
|
|
210
|
+
"div",
|
|
211
|
+
{
|
|
212
|
+
className: "grid grid-cols-7 gap-1 mb-1",
|
|
213
|
+
role: "row"
|
|
214
|
+
},
|
|
215
|
+
DAY_HEADERS.map(
|
|
216
|
+
(d) => React.createElement(
|
|
217
|
+
"div",
|
|
218
|
+
{
|
|
219
|
+
key: d,
|
|
220
|
+
className: "text-center text-xs font-medium text-muted-foreground h-9 flex items-center justify-center",
|
|
221
|
+
role: "columnheader",
|
|
222
|
+
"aria-label": d
|
|
223
|
+
},
|
|
224
|
+
d
|
|
225
|
+
)
|
|
226
|
+
)
|
|
227
|
+
),
|
|
228
|
+
// Day grid
|
|
229
|
+
React.createElement(
|
|
230
|
+
"div",
|
|
231
|
+
{
|
|
232
|
+
className: "grid grid-cols-7 gap-1",
|
|
233
|
+
role: "rowgroup"
|
|
234
|
+
},
|
|
235
|
+
api.days.map((day, i) => {
|
|
236
|
+
const dayAriaProps = api.getDayAriaProps(day);
|
|
237
|
+
const state = getDayState(day);
|
|
238
|
+
return React.createElement(
|
|
239
|
+
"button",
|
|
240
|
+
{
|
|
241
|
+
key: i,
|
|
242
|
+
type: "button",
|
|
243
|
+
className: dayVariants({ state }),
|
|
244
|
+
disabled: day.isDisabled,
|
|
245
|
+
onClick: () => api.select(day.date),
|
|
246
|
+
...dayAriaProps
|
|
247
|
+
},
|
|
248
|
+
day.date.getDate()
|
|
249
|
+
);
|
|
250
|
+
})
|
|
251
|
+
)
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
);
|
|
255
|
+
var CalendarHeader = React.forwardRef(
|
|
256
|
+
function CalendarHeader2({ label, labelId, onPrevMonth, onNextMonth, className }, ref) {
|
|
257
|
+
return React.createElement(
|
|
258
|
+
"div",
|
|
259
|
+
{
|
|
260
|
+
ref,
|
|
261
|
+
className: cn("flex items-center justify-between mb-2", className)
|
|
262
|
+
},
|
|
263
|
+
React.createElement(
|
|
264
|
+
"button",
|
|
265
|
+
{
|
|
266
|
+
type: "button",
|
|
267
|
+
"aria-label": "Previous month",
|
|
268
|
+
onClick: onPrevMonth,
|
|
269
|
+
className: "inline-flex items-center justify-center h-7 w-7 rounded-md hover:bg-accent"
|
|
270
|
+
},
|
|
271
|
+
"\u2039"
|
|
272
|
+
),
|
|
273
|
+
React.createElement(
|
|
274
|
+
"div",
|
|
275
|
+
{
|
|
276
|
+
id: labelId,
|
|
277
|
+
className: "text-sm font-medium",
|
|
278
|
+
"aria-live": "polite"
|
|
279
|
+
},
|
|
280
|
+
label
|
|
281
|
+
),
|
|
282
|
+
React.createElement(
|
|
283
|
+
"button",
|
|
284
|
+
{
|
|
285
|
+
type: "button",
|
|
286
|
+
"aria-label": "Next month",
|
|
287
|
+
onClick: onNextMonth,
|
|
288
|
+
className: "inline-flex items-center justify-center h-7 w-7 rounded-md hover:bg-accent"
|
|
289
|
+
},
|
|
290
|
+
"\u203A"
|
|
291
|
+
)
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
);
|
|
295
|
+
export {
|
|
296
|
+
Calendar,
|
|
297
|
+
CalendarHeader,
|
|
298
|
+
calendarVariants,
|
|
299
|
+
dayVariants
|
|
300
|
+
};
|
|
301
|
+
//# sourceMappingURL=react-calendar.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../calendar/src/calendar.ts", "../../calendar/src/calendar.styles.ts", "../../react-calendar/src/calendar.tsx"],
|
|
4
|
+
"sourcesContent": ["import type { AccessibilityProps } from '@refraction-ui/shared'\nimport { generateId } from '@refraction-ui/shared'\n\nexport interface CalendarProps {\n /** Selected date (controlled) */\n value?: Date\n /** Default selected date (uncontrolled) */\n defaultValue?: Date\n /** Callback when a date is selected */\n onSelect?: (date: Date) => void\n /** Displayed month (controlled) */\n month?: Date\n /** Callback when the displayed month changes */\n onMonthChange?: (month: Date) => void\n /** Minimum selectable date */\n minDate?: Date\n /** Maximum selectable date */\n maxDate?: Date\n /** Specific dates to disable */\n disabledDates?: Date[]\n /** Reference \"today\" for isToday/aria-current. Default: ambient `new Date()` — inject to avoid SSR/CSR hydration mismatch. */\n today?: Date\n}\n\nexport interface CalendarDay {\n /** The date this cell represents */\n date: Date\n /** Whether the date is today */\n isToday: boolean\n /** Whether the date is currently selected */\n isSelected: boolean\n /** Whether the date belongs to the currently displayed month */\n isCurrentMonth: boolean\n /** Whether the date is disabled */\n isDisabled: boolean\n}\n\nexport interface CalendarState {\n /** The currently displayed month */\n currentMonth: Date\n /** The currently selected date, if any */\n selectedDate: Date | undefined\n}\n\nexport interface CalendarAPI {\n /** Current calendar state */\n state: CalendarState\n /** Array of day objects for the current month grid (always 42: 6 weeks x 7 days) */\n days: CalendarDay[]\n /** Navigate to the previous month */\n prevMonth(): void\n /** Navigate to the next month */\n nextMonth(): void\n /** Select a date */\n select(date: Date): void\n /** ARIA attributes for the calendar grid */\n ariaProps: Partial<AccessibilityProps> & Record<string, string | number | boolean>\n /** Get ARIA attributes for a specific day cell */\n getDayAriaProps(day: CalendarDay): Partial<AccessibilityProps> & Record<string, string | number | boolean>\n /** Generated IDs */\n ids: {\n grid: string\n label: string\n }\n}\n\n/** Check if two dates represent the same calendar day */\nfunction isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n )\n}\n\n/** Get the first day of a month */\nfunction startOfMonth(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), 1)\n}\n\n/** Get day names */\nconst DAY_NAMES = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']\n\nexport function createCalendar(props: CalendarProps = {}): CalendarAPI {\n const {\n value: controlledValue,\n defaultValue,\n onSelect,\n month: controlledMonth,\n onMonthChange,\n minDate,\n maxDate,\n disabledDates = [],\n today: injectedToday,\n } = props\n\n // Injection boundary: ambient \"today\" is the default; inject `today` so SSR and client agree.\n const today = injectedToday ?? new Date()\n\n // Determine selected date\n const selectedDate = controlledValue ?? defaultValue\n\n // Determine current displayed month\n const currentMonth = controlledMonth\n ? startOfMonth(controlledMonth)\n : selectedDate\n ? startOfMonth(selectedDate)\n : startOfMonth(today)\n\n const gridId = generateId('rfr-calendar')\n const labelId = generateId('rfr-calendar-label')\n\n function isDateDisabled(date: Date): boolean {\n if (minDate && date < startOfDay(minDate)) return true\n if (maxDate && date > endOfDay(maxDate)) return true\n return disabledDates.some((d) => isSameDay(d, date))\n }\n\n function startOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate())\n }\n\n function endOfDay(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999)\n }\n\n /** Build the 42-cell grid for the current month view */\n function buildDays(): CalendarDay[] {\n const year = currentMonth.getFullYear()\n const month = currentMonth.getMonth()\n\n // First day of the month\n const first = new Date(year, month, 1)\n // Day of week the month starts on (0 = Sunday)\n const startDow = first.getDay()\n\n // Start from the Sunday before (or on) the first\n const gridStart = new Date(year, month, 1 - startDow)\n\n const days: CalendarDay[] = []\n for (let i = 0; i < 42; i++) {\n const date = new Date(\n gridStart.getFullYear(),\n gridStart.getMonth(),\n gridStart.getDate() + i,\n )\n days.push({\n date,\n isToday: isSameDay(date, today),\n isSelected: selectedDate ? isSameDay(date, selectedDate) : false,\n isCurrentMonth: date.getMonth() === month,\n isDisabled: isDateDisabled(date),\n })\n }\n return days\n }\n\n function prevMonth(): void {\n const prev = new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1, 1)\n onMonthChange?.(prev)\n }\n\n function nextMonth(): void {\n const next = new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1, 1)\n onMonthChange?.(next)\n }\n\n function select(date: Date): void {\n if (!isDateDisabled(date)) {\n onSelect?.(date)\n }\n }\n\n const ariaProps: Partial<AccessibilityProps> & Record<string, string | number | boolean> = {\n role: 'grid',\n 'aria-labelledby': labelId,\n id: gridId,\n }\n\n function getDayAriaProps(day: CalendarDay): Partial<AccessibilityProps> & Record<string, string | number | boolean> {\n return {\n role: 'gridcell',\n 'aria-selected': day.isSelected,\n 'aria-disabled': day.isDisabled,\n // Key absent (not undefined) when not today — the ARIA record type excludes undefined.\n ...(day.isToday ? { 'aria-current': 'date' as const } : {}),\n 'aria-label': `${DAY_NAMES[day.date.getDay()]}, ${day.date.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })}`,\n }\n }\n\n return {\n state: {\n currentMonth,\n selectedDate,\n },\n days: buildDays(),\n prevMonth,\n nextMonth,\n select,\n ariaProps,\n getDayAriaProps,\n ids: {\n grid: gridId,\n label: labelId,\n },\n }\n}\n", "import { cva } from '@refraction-ui/shared'\n\nexport const calendarVariants = cva({\n base: 'p-3 rounded-md border bg-background',\n})\n\nexport const dayVariants = cva({\n base: 'inline-flex items-center justify-center rounded-md text-sm h-9 w-9',\n variants: {\n state: {\n default: 'hover:bg-accent hover:text-accent-foreground',\n selected: 'bg-primary text-primary-foreground hover:bg-primary/90',\n today: 'bg-accent text-accent-foreground',\n disabled: 'text-muted-foreground opacity-50 cursor-not-allowed',\n outside: 'text-muted-foreground opacity-50',\n },\n },\n defaultVariants: {\n state: 'default',\n },\n})\n", "import * as React from 'react'\nimport {\n createCalendar,\n calendarVariants,\n dayVariants,\n type CalendarProps as CoreCalendarProps,\n type CalendarDay,\n} from '@refraction-ui/calendar'\nimport { cn } from '@refraction-ui/shared'\n\n// ---------------------------------------------------------------------------\n// Calendar\n// ---------------------------------------------------------------------------\n\nexport interface CalendarProps extends CoreCalendarProps {\n className?: string\n children?: React.ReactNode\n}\n\nconst MONTH_NAMES = [\n 'January', 'February', 'March', 'April', 'May', 'June',\n 'July', 'August', 'September', 'October', 'November', 'December',\n]\n\nconst DAY_HEADERS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']\n\nexport const Calendar = React.forwardRef<HTMLDivElement, CalendarProps>(\n function Calendar({ className, value, defaultValue, onSelect, month, onMonthChange, minDate, maxDate, disabledDates }: CalendarProps, ref) {\n const [uncontrolledValue, setUncontrolledValue] = React.useState<Date | undefined>(defaultValue)\n const [uncontrolledMonth, setUncontrolledMonth] = React.useState<Date>(\n () => month ?? value ?? defaultValue ?? new Date(),\n )\n\n const isValueControlled = value !== undefined\n const isMonthControlled = month !== undefined\n\n const selectedValue = isValueControlled ? value : uncontrolledValue\n const displayMonth = isMonthControlled ? month : uncontrolledMonth\n\n const handleSelect = React.useCallback(\n (date: Date) => {\n if (!isValueControlled) {\n setUncontrolledValue(date)\n }\n onSelect?.(date)\n },\n [isValueControlled, onSelect],\n )\n\n const handleMonthChange = React.useCallback(\n (m: Date) => {\n if (!isMonthControlled) {\n setUncontrolledMonth(m)\n }\n onMonthChange?.(m)\n },\n [isMonthControlled, onMonthChange],\n )\n\n const api = createCalendar({\n value: selectedValue,\n month: displayMonth,\n onSelect: handleSelect,\n onMonthChange: handleMonthChange,\n minDate,\n maxDate,\n disabledDates,\n })\n\n function getDayState(day: CalendarDay): 'selected' | 'today' | 'disabled' | 'outside' | 'default' {\n if (day.isDisabled) return 'disabled'\n if (day.isSelected) return 'selected'\n if (!day.isCurrentMonth) return 'outside'\n if (day.isToday) return 'today'\n return 'default'\n }\n\n const monthLabel = `${MONTH_NAMES[api.state.currentMonth.getMonth()]} ${api.state.currentMonth.getFullYear()}`\n\n return React.createElement(\n 'div',\n {\n ref,\n className: cn(calendarVariants(), className),\n ...api.ariaProps,\n },\n // Header row: prev, month label, next\n React.createElement(CalendarHeader, {\n label: monthLabel,\n labelId: api.ids.label,\n onPrevMonth: api.prevMonth,\n onNextMonth: api.nextMonth,\n }),\n // Day-of-week headers\n React.createElement(\n 'div',\n {\n className: 'grid grid-cols-7 gap-1 mb-1',\n role: 'row',\n },\n DAY_HEADERS.map((d) =>\n React.createElement(\n 'div',\n {\n key: d,\n className: 'text-center text-xs font-medium text-muted-foreground h-9 flex items-center justify-center',\n role: 'columnheader',\n 'aria-label': d,\n },\n d,\n ),\n ),\n ),\n // Day grid\n React.createElement(\n 'div',\n {\n className: 'grid grid-cols-7 gap-1',\n role: 'rowgroup',\n },\n api.days.map((day, i) => {\n const dayAriaProps = api.getDayAriaProps(day)\n const state = getDayState(day)\n return React.createElement(\n 'button',\n {\n key: i,\n type: 'button',\n className: dayVariants({ state }),\n disabled: day.isDisabled,\n onClick: () => api.select(day.date),\n ...dayAriaProps,\n },\n day.date.getDate(),\n )\n }),\n ),\n )\n },\n)\n\n// ---------------------------------------------------------------------------\n// CalendarHeader\n// ---------------------------------------------------------------------------\n\nexport interface CalendarHeaderProps {\n label: string\n labelId: string\n onPrevMonth: () => void\n onNextMonth: () => void\n className?: string\n}\n\nexport const CalendarHeader = React.forwardRef<HTMLDivElement, CalendarHeaderProps>(\n function CalendarHeader({ label, labelId, onPrevMonth, onNextMonth, className }, ref) {\n return React.createElement(\n 'div',\n {\n ref,\n className: cn('flex items-center justify-between mb-2', className),\n },\n React.createElement(\n 'button',\n {\n type: 'button',\n 'aria-label': 'Previous month',\n onClick: onPrevMonth,\n className: 'inline-flex items-center justify-center h-7 w-7 rounded-md hover:bg-accent',\n },\n '\\u2039',\n ),\n React.createElement(\n 'div',\n {\n id: labelId,\n className: 'text-sm font-medium',\n 'aria-live': 'polite',\n },\n label,\n ),\n React.createElement(\n 'button',\n {\n type: 'button',\n 'aria-label': 'Next month',\n onClick: onNextMonth,\n className: 'inline-flex items-center justify-center h-7 w-7 rounded-md hover:bg-accent',\n },\n '\\u203A',\n ),\n )\n },\n)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Calendar", "CalendarHeader"]
|
|
7
|
+
}
|