@boyernick/standard-ui-react 0.1.1-canary.8 → 0.2.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.
Files changed (83) hide show
  1. package/package.json +5 -3
  2. package/src/accordion.tsx +5 -2
  3. package/src/alert-dialog.tsx +1 -1
  4. package/src/attachment.tsx +5 -2
  5. package/src/autocomplete.tsx +4 -3
  6. package/src/block-editor.tsx +1747 -0
  7. package/src/brand.tsx +2 -2
  8. package/src/breadcrumb.tsx +14 -7
  9. package/src/button.tsx +22 -11
  10. package/src/calendar.tsx +6 -3
  11. package/src/carousel.tsx +220 -53
  12. package/src/checkbox.tsx +3 -2
  13. package/src/code-block.tsx +66 -5
  14. package/src/collapsible.tsx +4 -2
  15. package/src/combobox.tsx +4 -3
  16. package/src/command.tsx +41 -13
  17. package/src/date-picker.tsx +7 -2
  18. package/src/dialog.tsx +33 -10
  19. package/src/empty.tsx +4 -4
  20. package/src/field.tsx +4 -3
  21. package/src/filter-group.tsx +143 -0
  22. package/src/icons.tsx +28 -1
  23. package/src/illustrations.tsx +219 -141
  24. package/src/index.ts +245 -18
  25. package/src/input.tsx +8 -5
  26. package/src/kbd.tsx +49 -0
  27. package/src/lib/focus.ts +41 -0
  28. package/src/lib/popup.ts +1 -1
  29. package/src/lifeline/company-icon.tsx +71 -0
  30. package/src/lifeline/index.ts +42 -0
  31. package/src/lifeline/lifeline-data.ts +97 -0
  32. package/src/lifeline/lifeline-desktop.tsx +204 -0
  33. package/src/lifeline/lifeline-event.tsx +108 -0
  34. package/src/lifeline/lifeline-fireworks.tsx +302 -0
  35. package/src/lifeline/lifeline-hover-image.tsx +269 -0
  36. package/src/lifeline/lifeline-icons.tsx +39 -0
  37. package/src/lifeline/lifeline-intro-timing.ts +105 -0
  38. package/src/lifeline/lifeline-labels.tsx +24 -0
  39. package/src/lifeline/lifeline-layout.ts +1 -0
  40. package/src/lifeline/lifeline-legend.tsx +31 -0
  41. package/src/lifeline/lifeline-lightbox.tsx +309 -0
  42. package/src/lifeline/lifeline-marker.tsx +183 -0
  43. package/src/lifeline/lifeline-people.tsx +99 -0
  44. package/src/lifeline/lifeline-photos.tsx +366 -0
  45. package/src/lifeline/lifeline-shell.tsx +135 -0
  46. package/src/lifeline/lifeline-utils.ts +83 -0
  47. package/src/lifeline/lifeline-vertical.tsx +482 -0
  48. package/src/lifeline/lifeline.tsx +69 -0
  49. package/src/lifeline/types.ts +112 -0
  50. package/src/lifeline/use-lifeline-intro.ts +130 -0
  51. package/src/lifeline/use-lifeline-scroll.ts +1011 -0
  52. package/src/lifeline/use-lifeline-vertical-scroll.ts +271 -0
  53. package/src/menubar.tsx +9 -2
  54. package/src/minimap.tsx +296 -0
  55. package/src/modal.tsx +608 -0
  56. package/src/navigation-menu.tsx +338 -67
  57. package/src/number-field.tsx +336 -61
  58. package/src/otp-field.tsx +4 -3
  59. package/src/pagination.tsx +262 -42
  60. package/src/password-protection.tsx +345 -0
  61. package/src/popover.tsx +1 -1
  62. package/src/progress.tsx +5 -0
  63. package/src/questionnaire.tsx +284 -0
  64. package/src/radio.tsx +4 -2
  65. package/src/scroll-area.tsx +4 -1
  66. package/src/select.tsx +5 -2
  67. package/src/sidebar.tsx +113 -28
  68. package/src/slider.tsx +66 -6
  69. package/src/sounds.tsx +6 -10
  70. package/src/spinner.tsx +105 -32
  71. package/src/switch.tsx +4 -1
  72. package/src/table.tsx +82 -15
  73. package/src/tabs.tsx +189 -38
  74. package/src/text-animate.tsx +71 -28
  75. package/src/textarea.tsx +6 -1
  76. package/src/timeline.tsx +378 -0
  77. package/src/toast.tsx +214 -35
  78. package/src/toggle.tsx +4 -2
  79. package/src/toolbar.tsx +12 -7
  80. package/src/tooltip.tsx +43 -3
  81. package/src/video-player.tsx +396 -127
  82. package/src/image-modal.tsx +0 -110
  83. package/src/markdown-editor.tsx +0 -302
package/src/index.ts CHANGED
@@ -1,5 +1,12 @@
1
1
  export { Button, buttonVariants, type ButtonProps } from "./button";
2
2
  export { Input, inputVariants, type InputProps } from "./input";
3
+ export {
4
+ Kbd,
5
+ KbdGroup,
6
+ kbdVariants,
7
+ type KbdGroupProps,
8
+ type KbdProps,
9
+ } from "./kbd";
3
10
  export { Badge, badgeVariants, type BadgeProps } from "./badge";
4
11
  export { Switch, type SwitchProps } from "./switch";
5
12
  export { Checkbox, type CheckboxProps } from "./checkbox";
@@ -165,6 +172,7 @@ export {
165
172
  CommandItem,
166
173
  CommandEmpty,
167
174
  CommandTitle,
175
+ CommandMeta,
168
176
  CommandDialogTitle,
169
177
  type CommandProps,
170
178
  type CommandTriggerProps,
@@ -184,6 +192,7 @@ export {
184
192
  type CommandItemProps,
185
193
  type CommandEmptyProps,
186
194
  type CommandTitleProps,
195
+ type CommandMetaProps,
187
196
  type CommandDialogTitleProps,
188
197
  } from "./command";
189
198
  export {
@@ -357,6 +366,18 @@ export {
357
366
  type FieldsetProps,
358
367
  type FieldsetLegendProps,
359
368
  } from "./fieldset";
369
+ export {
370
+ FilterGroup,
371
+ FilterItem,
372
+ FilterCount,
373
+ filterGroupVariants,
374
+ filterItemVariants,
375
+ type FilterGroupProps,
376
+ type FilterItemProps,
377
+ type FilterCountProps,
378
+ type FilterGroupVariant,
379
+ type FilterGroupSize,
380
+ } from "./filter-group";
360
381
  export { Form, type FormProps } from "./form";
361
382
  export {
362
383
  Meter,
@@ -413,19 +434,38 @@ export {
413
434
  type MenuViewportProps,
414
435
  } from "./menu";
415
436
  export { Menubar, type MenubarProps } from "./menubar";
437
+ export {
438
+ Minimap,
439
+ minimapVariants,
440
+ type MinimapProps,
441
+ type MinimapSection,
442
+ } from "./minimap";
416
443
  export {
417
444
  NumberField,
418
445
  NumberFieldGroup,
419
446
  NumberFieldInput,
420
447
  NumberFieldIncrement,
421
448
  NumberFieldDecrement,
449
+ NumberFieldStepper,
450
+ NumberFieldPrefix,
451
+ NumberFieldSuffix,
422
452
  NumberFieldScrubArea,
423
453
  NumberFieldScrubAreaCursor,
454
+ numberFieldAffixVariants,
455
+ numberFieldControlVariants,
456
+ numberFieldGroupVariants,
457
+ numberFieldInputVariants,
458
+ numberFieldStepperVariants,
459
+ type NumberFieldSize,
460
+ type NumberFieldAlign,
424
461
  type NumberFieldProps,
425
462
  type NumberFieldGroupProps,
426
463
  type NumberFieldInputProps,
427
464
  type NumberFieldIncrementProps,
428
465
  type NumberFieldDecrementProps,
466
+ type NumberFieldStepperProps,
467
+ type NumberFieldPrefixProps,
468
+ type NumberFieldSuffixProps,
429
469
  type NumberFieldScrubAreaProps,
430
470
  type NumberFieldScrubAreaCursorProps,
431
471
  } from "./number-field";
@@ -442,8 +482,18 @@ export {
442
482
  NavigationMenuPopup,
443
483
  NavigationMenuArrow,
444
484
  NavigationMenuLink,
485
+ NavigationMenuBarLink,
486
+ NavigationMenuLinkIcon,
487
+ NavigationMenuLinkTitle,
488
+ NavigationMenuLinkDescription,
445
489
  NavigationMenuIcon,
490
+ navigationMenuBarItemVariants,
491
+ navigationMenuLinkVariants,
492
+ navigationMenuListVariants,
493
+ navigationMenuRootVariants,
446
494
  navigationMenuTriggerClassName,
495
+ type NavigationMenuVariant,
496
+ type NavigationMenuSize,
447
497
  type NavigationMenuProps,
448
498
  type NavigationMenuListProps,
449
499
  type NavigationMenuItemProps,
@@ -456,6 +506,10 @@ export {
456
506
  type NavigationMenuPopupProps,
457
507
  type NavigationMenuArrowProps,
458
508
  type NavigationMenuLinkProps,
509
+ type NavigationMenuBarLinkProps,
510
+ type NavigationMenuLinkIconProps,
511
+ type NavigationMenuLinkTitleProps,
512
+ type NavigationMenuLinkDescriptionProps,
459
513
  type NavigationMenuIconProps,
460
514
  } from "./navigation-menu";
461
515
  export {
@@ -466,6 +520,13 @@ export {
466
520
  type OTPFieldInputProps,
467
521
  type OTPFieldSeparatorProps,
468
522
  } from "./otp-field";
523
+ export {
524
+ PasswordProtection,
525
+ PasswordProtectionDialog,
526
+ type PasswordProtectionProps,
527
+ type PasswordProtectionDialogProps,
528
+ type PasswordProtectionVerify,
529
+ } from "./password-protection";
469
530
  export {
470
531
  Popover,
471
532
  PopoverTrigger,
@@ -517,6 +578,47 @@ export {
517
578
  type ProgressTrackProps,
518
579
  type ProgressIndicatorProps,
519
580
  } from "./progress";
581
+ export {
582
+ Questionnaire,
583
+ QuestionnaireProgress,
584
+ QuestionnaireItem,
585
+ QuestionnaireTitle,
586
+ QuestionnaireDescription,
587
+ QuestionnaireChoices,
588
+ QuestionnaireChoice,
589
+ QuestionnaireChoiceInput,
590
+ QuestionnaireChoiceLabel,
591
+ QuestionnaireChoiceShortcut,
592
+ QuestionnaireInput,
593
+ QuestionnaireError,
594
+ QuestionnaireActions,
595
+ QuestionnairePrevious,
596
+ QuestionnaireSkip,
597
+ QuestionnaireNext,
598
+ QuestionnaireSubmit,
599
+ type QuestionnaireProps,
600
+ type QuestionnaireProgressProps,
601
+ type QuestionnaireItemProps,
602
+ type QuestionnaireTitleProps,
603
+ type QuestionnaireDescriptionProps,
604
+ type QuestionnaireChoicesProps,
605
+ type QuestionnaireChoiceProps,
606
+ type QuestionnaireChoiceInputProps,
607
+ type QuestionnaireChoiceLabelProps,
608
+ type QuestionnaireChoiceShortcutProps,
609
+ type QuestionnaireInputProps,
610
+ type QuestionnaireErrorProps,
611
+ type QuestionnaireActionsProps,
612
+ type QuestionnairePreviousProps,
613
+ type QuestionnaireSkipProps,
614
+ type QuestionnaireNextProps,
615
+ type QuestionnaireSubmitProps,
616
+ type QuestionnaireChoiceDefinition,
617
+ type QuestionnaireInputType,
618
+ type QuestionnaireItemDefinition,
619
+ type QuestionnaireItemStatus,
620
+ type QuestionnaireShortcutMode,
621
+ } from "./questionnaire";
520
622
  export {
521
623
  RadioGroup,
522
624
  Radio,
@@ -574,11 +676,14 @@ export {
574
676
  SliderTrack,
575
677
  SliderIndicator,
576
678
  SliderThumb,
679
+ SliderTicks,
680
+ sliderVariants,
577
681
  type SliderProps,
578
682
  type SliderControlProps,
579
683
  type SliderTrackProps,
580
684
  type SliderIndicatorProps,
581
685
  type SliderThumbProps,
686
+ type SliderTicksProps,
582
687
  } from "./slider";
583
688
  export {
584
689
  Tabs,
@@ -586,7 +691,12 @@ export {
586
691
  TabsTab,
587
692
  TabsIndicator,
588
693
  TabsPanel,
694
+ tabsListVariants,
695
+ tabsTabVariants,
696
+ tabsIndicatorVariants,
589
697
  type TabsProps,
698
+ type TabsVariant,
699
+ type TabsSize,
590
700
  type TabsListProps,
591
701
  type TabsTabProps,
592
702
  type TabsIndicatorProps,
@@ -599,6 +709,9 @@ export {
599
709
  ToastViewport,
600
710
  ToastRoot,
601
711
  ToastContent,
712
+ ToastIcon,
713
+ toastRootVariants,
714
+ toastViewportVariants,
602
715
  ToastTitle,
603
716
  ToastDescription,
604
717
  ToastAction,
@@ -612,6 +725,9 @@ export {
612
725
  type ToastViewportProps,
613
726
  type ToastRootProps,
614
727
  type ToastContentProps,
728
+ type ToastIconProps,
729
+ type ToastType,
730
+ type ToastPlacement,
615
731
  type ToastTitleProps,
616
732
  type ToastDescriptionProps,
617
733
  type ToastActionProps,
@@ -688,14 +804,27 @@ export {
688
804
  PaginationLink,
689
805
  PaginationPrevious,
690
806
  PaginationNext,
807
+ PaginationFirst,
808
+ PaginationLast,
691
809
  PaginationEllipsis,
810
+ PaginationStatus,
811
+ PaginationRange,
812
+ paginationLinkVariants,
813
+ paginationDirectionVariants,
692
814
  type PaginationProps,
693
815
  type PaginationContentProps,
694
816
  type PaginationItemProps,
695
817
  type PaginationLinkProps,
818
+ type PaginationButtonProps,
819
+ type PaginationAnchorProps,
696
820
  type PaginationPreviousProps,
697
821
  type PaginationNextProps,
822
+ type PaginationFirstProps,
823
+ type PaginationLastProps,
698
824
  type PaginationEllipsisProps,
825
+ type PaginationStatusProps,
826
+ type PaginationRangeProps,
827
+ type PaginationSize,
699
828
  } from "./pagination";
700
829
  export {
701
830
  Sidebar,
@@ -704,14 +833,20 @@ export {
704
833
  SidebarFooter,
705
834
  SidebarNav,
706
835
  SidebarNavItem,
836
+ SidebarNavItemLabel,
837
+ SidebarNavBadge,
707
838
  SidebarGroup,
708
839
  SidebarGroupLabel,
840
+ sidebarVariants,
841
+ sidebarNavItemVariants,
709
842
  type SidebarProps,
710
843
  type SidebarHeaderProps,
711
844
  type SidebarContentProps,
712
845
  type SidebarFooterProps,
713
846
  type SidebarNavProps,
714
847
  type SidebarNavItemProps,
848
+ type SidebarNavItemLabelProps,
849
+ type SidebarNavBadgeProps,
715
850
  type SidebarGroupProps,
716
851
  type SidebarGroupLabelProps,
717
852
  } from "./sidebar";
@@ -723,6 +858,7 @@ export {
723
858
  CarouselItem,
724
859
  CarouselPrevious,
725
860
  CarouselNext,
861
+ CarouselDots,
726
862
  useCarousel,
727
863
  type CarouselApi,
728
864
  type CarouselProps,
@@ -730,6 +866,7 @@ export {
730
866
  type CarouselItemProps,
731
867
  type CarouselPreviousProps,
732
868
  type CarouselNextProps,
869
+ type CarouselDotsProps,
733
870
  } from "./carousel";
734
871
  export {
735
872
  SoundsProvider,
@@ -746,19 +883,50 @@ export {
746
883
  type VideoPlayerProps,
747
884
  } from "./video-player";
748
885
  export {
749
- ImageModal,
750
- ImageModalTrigger,
751
- ImageModalContent,
752
- type ImageModalProps,
753
- type ImageModalTriggerProps,
754
- type ImageModalContentProps,
755
- } from "./image-modal";
886
+ Modal,
887
+ ModalTrigger,
888
+ ModalContent,
889
+ Gallery,
890
+ GalleryTrigger,
891
+ modalContentVariants,
892
+ type ModalProps,
893
+ type ModalTriggerProps,
894
+ type ModalContentProps,
895
+ type GalleryProps,
896
+ type GalleryTriggerProps,
897
+ type GalleryItem,
898
+ } from "./modal";
756
899
  export {
757
900
  Ticker,
758
901
  TickerItem,
759
902
  type TickerProps,
760
903
  type TickerItemProps,
761
904
  } from "./ticker";
905
+ export {
906
+ Timeline,
907
+ TimelineTrack,
908
+ TimelineItem,
909
+ TimelineMarker,
910
+ TimelineTime,
911
+ TimelineContent,
912
+ TimelineTitle,
913
+ TimelineDescription,
914
+ TimelineMedia,
915
+ timelineVariants,
916
+ timelineTrackVariants,
917
+ timelineItemVariants,
918
+ timelineMarkerVariants,
919
+ timelineTimeVariants,
920
+ type TimelineProps,
921
+ type TimelineTrackProps,
922
+ type TimelineItemProps,
923
+ type TimelineMarkerProps,
924
+ type TimelineTimeProps,
925
+ type TimelineContentProps,
926
+ type TimelineTitleProps,
927
+ type TimelineDescriptionProps,
928
+ type TimelineMediaProps,
929
+ } from "./timeline";
762
930
  export {
763
931
  Table,
764
932
  TableHeader,
@@ -768,6 +936,8 @@ export {
768
936
  TableHead,
769
937
  TableCell,
770
938
  TableCaption,
939
+ tableHeaderVariants,
940
+ tableVariants,
771
941
  type TableProps,
772
942
  type TableHeaderProps,
773
943
  type TableBodyProps,
@@ -784,6 +954,7 @@ export {
784
954
  TooltipPortal,
785
955
  TooltipPositioner,
786
956
  TooltipPopup,
957
+ tooltipPopupVariants,
787
958
  type TooltipProviderProps,
788
959
  type TooltipProps,
789
960
  type TooltipTriggerProps,
@@ -795,9 +966,11 @@ export {
795
966
  CENTRAL_ICON_SIZE,
796
967
  withCentralIconDefaults,
797
968
  iconGallery,
969
+ IconArrowDown,
798
970
  IconBell,
799
971
  IconCalendar1,
800
972
  IconChainLink1,
973
+ IconChainLink3,
801
974
  IconCheckmark1,
802
975
  IconChevronBottom,
803
976
  IconChevronDownSmall,
@@ -807,41 +980,86 @@ export {
807
980
  IconClipboard,
808
981
  IconCrossSmall,
809
982
  IconDotGrid1x3Horizontal,
983
+ IconDotGrid2x3,
810
984
  IconExclamationCircle,
811
985
  IconExclamationTriangle,
986
+ IconFullScreen,
987
+ IconHighlight,
812
988
  IconHome,
813
989
  IconMagnifyingGlass,
814
990
  IconMinus,
815
991
  IconMoon,
992
+ IconPause,
816
993
  IconPeople,
994
+ IconPlay,
817
995
  IconPlus,
818
996
  IconSettingsGear1,
819
997
  IconSquareBehindSquare6,
820
998
  IconStar,
999
+ IconStrikeThrough,
821
1000
  IconSun,
1001
+ IconVolumeFull,
1002
+ IconVolumeOff,
822
1003
  IconX,
823
1004
  type CentralIconProps,
824
1005
  type CentralIconComponent,
825
1006
  } from "./icons";
826
- export { CodeBlock, type CodeBlockProps } from "./code-block";
827
- export {
828
- MarkdownEditor,
829
- MarkdownEditorToolbar,
830
- MarkdownEditorInput,
831
- MarkdownEditorPreview,
832
- type MarkdownEditorProps,
833
- type MarkdownEditorToolbarProps,
834
- type MarkdownEditorInputProps,
835
- type MarkdownEditorPreviewProps,
836
- } from "./markdown-editor";
1007
+ export { CodeBlock, type CodeBlockProps, type CodeBlockHighlightLine } from "./code-block";
1008
+ export {
1009
+ BlockEditor,
1010
+ createBlockEditorBlock,
1011
+ defaultBlockEditorBlocks,
1012
+ type BlockEditorProps,
1013
+ type BlockEditorBlock,
1014
+ type BlockEditorBlockType,
1015
+ } from "./block-editor";
837
1016
  export {
838
1017
  IllustrationEmpty,
839
1018
  IllustrationError,
840
1019
  IllustrationSuccess,
841
1020
  IllustrationSearch,
1021
+ IllustrationUpload,
1022
+ IllustrationFile,
842
1023
  type IllustrationProps,
1024
+ type IllustrationFileProps,
1025
+ type FileIllustrationType,
843
1026
  } from "./illustrations"
844
1027
  export { BrandMark, BrandWordmark, type BrandMarkProps, type BrandWordmarkProps } from "./brand"
1028
+ export {
1029
+ Lifeline,
1030
+ LifelineMarkerColumn,
1031
+ LifelineLegend,
1032
+ LifelineShell,
1033
+ LifelineNav,
1034
+ LifelineStage,
1035
+ LifelineFooter,
1036
+ CompanyIcon,
1037
+ registerCompanyIcons,
1038
+ useLifelineScroll,
1039
+ defineLifeline,
1040
+ localizeLifelineMarkers,
1041
+ LIFELINE_CURRENT_YEAR,
1042
+ type CompanyIconEntry,
1043
+ type CompanyIconId,
1044
+ type LifelineBirthday,
1045
+ type LifelineMilestone,
1046
+ type LifelineMilestones,
1047
+ type LifelineRecord,
1048
+ type LifelineTextOverrides,
1049
+ type LifelineCompany,
1050
+ type LifelineEvent,
1051
+ type LifelineEventEffect,
1052
+ type LifelineEventImage,
1053
+ type LifelineEventObject,
1054
+ type LifelineEventSegment,
1055
+ type LifelineLegendItem,
1056
+ type LifelineMarker,
1057
+ type LifelineMetPerson,
1058
+ type LifelineMentor,
1059
+ type LifelineMode,
1060
+ type LifelinePhoto,
1061
+ type LifelineProps,
1062
+ } from "./lifeline"
845
1063
  export {
846
1064
  TextAnimate,
847
1065
  type TextAnimateProps,
@@ -849,3 +1067,12 @@ export {
849
1067
  } from "./text-animate"
850
1068
  export { cn } from "./lib/cn"
851
1069
  export { motion } from "./lib/motion"
1070
+ export {
1071
+ focusRing,
1072
+ focusRingWithin,
1073
+ focusRingDestructive,
1074
+ focusRingWithinDestructive,
1075
+ focusRingInvalid,
1076
+ focusRingInvalidWithin,
1077
+ focusRingBorder,
1078
+ } from "./lib/focus"
package/src/input.tsx CHANGED
@@ -3,14 +3,18 @@
3
3
  import { cva, type VariantProps } from "class-variance-authority"
4
4
  import { forwardRef, type InputHTMLAttributes } from "react"
5
5
  import { cn } from "./lib/cn"
6
+ import { focusRing, focusRingInvalid } from "./lib/focus"
6
7
 
7
8
  const inputVariants = cva(
8
- "text-sm flex w-full cursor-text rounded-md text-fg-primary transition-[color,box-shadow] duration-[var(--duration-sm)] ease-enter placeholder:text-fg-quaternary outline-none aria-invalid:border-destructive disabled:cursor-not-allowed disabled:opacity-50",
9
+ cn(
10
+ "text-sm flex w-full cursor-text rounded-md text-fg-primary transition-[color,box-shadow] duration-[var(--duration-sm)] ease-enter placeholder:text-fg-quaternary aria-invalid:border-destructive disabled:cursor-not-allowed disabled:opacity-50",
11
+ focusRing,
12
+ focusRingInvalid,
13
+ ),
9
14
  {
10
15
  variants: {
11
16
  variant: {
12
- default:
13
- "border bg-surface inset-shadow-outline-top focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20 aria-invalid:focus-visible:border-destructive aria-invalid:focus-visible:ring-destructive/20",
17
+ default: "border bg-surface inset-shadow-outline-top",
14
18
  ghost: "border border-transparent bg-transparent",
15
19
  },
16
20
  size: {
@@ -37,8 +41,7 @@ const inputVariants = cva(
37
41
  {
38
42
  variant: "ghost",
39
43
  invalid: true,
40
- class:
41
- "border-destructive focus-visible:border-destructive focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-destructive/20",
44
+ class: "border-destructive",
42
45
  },
43
46
  ],
44
47
  defaultVariants: {
package/src/kbd.tsx ADDED
@@ -0,0 +1,49 @@
1
+ import { cva, type VariantProps } from "class-variance-authority"
2
+ import type { ComponentProps } from "react"
3
+ import { cn } from "./lib/cn"
4
+
5
+ const kbdVariants = cva(
6
+ // `text-xs` carries the size, line-height and tracking; the weight is set
7
+ // separately because 600 sits above the 400/500 the type scale defines, so
8
+ // there is no `-strong` utility to reach for.
9
+ // The border is bottom-only on purpose: it reads as the lip of a physical
10
+ // key without boxing the glyph in on all four sides, which at 12px turns a
11
+ // keycap into a cramped badge.
12
+ "inline-flex shrink-0 items-center justify-center border-b px-1 font-sans text-xs font-semibold whitespace-nowrap select-none",
13
+ {
14
+ variants: {
15
+ variant: {
16
+ default: "border-border-primary bg-background-tertiary text-fg-secondary",
17
+ // The default fill is a light grey that vanishes on a dark surface, so
18
+ // an inverted keycap tints with the inverted foreground instead. It has
19
+ // to be that token rather than a literal `white`: the grey ramp flips
20
+ // under `.dark`, so a hardcoded white wash would sit invisibly on the
21
+ // now-light inverted surface.
22
+ inverted: "border-fg-inverted/10 bg-fg-inverted/10 text-fg-inverted",
23
+ },
24
+ size: {
25
+ sm: "h-4 min-w-3.5 rounded-2xs",
26
+ md: "h-5 min-w-4 rounded-xs",
27
+ },
28
+ },
29
+ defaultVariants: { variant: "default", size: "md" },
30
+ },
31
+ )
32
+
33
+ export type KbdProps = ComponentProps<"kbd"> & VariantProps<typeof kbdVariants>
34
+ export type KbdGroupProps = ComponentProps<"span">
35
+
36
+ /** A single keycap. Presentational — map "cmd" to ⌘ before it gets here. */
37
+ export const Kbd = ({ className, variant, size, ...props }: KbdProps) => (
38
+ <kbd className={cn(kbdVariants({ variant, size }), className)} {...props} />
39
+ )
40
+
41
+ /** A full shortcut. Keeps the caps on one line at a consistent gap. */
42
+ export const KbdGroup = ({ className, ...props }: KbdGroupProps) => (
43
+ <span
44
+ className={cn("inline-flex items-center gap-1 align-middle", className)}
45
+ {...props}
46
+ />
47
+ )
48
+
49
+ export { kbdVariants }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Canonical keyboard focus for StandardUI controls.
3
+ *
4
+ * Two layers, always together:
5
+ * 1. Hard edge — `border-ring` turns the control's border to `--ring`.
6
+ * Borderless chrome must carry `border border-transparent` so the edge
7
+ * can light up on focus without shifting layout.
8
+ * 2. Soft wash — 3px `ring-ring/20` with a 1px page-colored gap.
9
+ *
10
+ * Use these strings everywhere. Do not invent a second focus recipe.
11
+ */
12
+
13
+ /** Default focus-visible ring for buttons, tabs, toggles, links, etc. */
14
+ export const focusRing =
15
+ "outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20"
16
+
17
+ /** Same recipe keyed to `:focus-within` for composite fields. */
18
+ export const focusRingWithin =
19
+ "outline-none focus-within:border-ring focus-within:ring-[3px] focus-within:ring-offset-1 focus-within:ring-offset-background-primary focus-within:ring-ring/20"
20
+
21
+ /** Destructive focus-visible ring — use instead of `focusRing` on error actions. */
22
+ export const focusRingDestructive =
23
+ "outline-none focus-visible:border-destructive focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-destructive/20"
24
+
25
+ /** Destructive focus-within ring — use instead of `focusRingWithin` when invalid. */
26
+ export const focusRingWithinDestructive =
27
+ "outline-none focus-within:border-destructive focus-within:ring-[3px] focus-within:ring-offset-1 focus-within:ring-offset-background-primary focus-within:ring-destructive/20"
28
+
29
+ /**
30
+ * Invalid-state modifiers that pair with `focusRing` / `focusRingWithin`.
31
+ * Keeps the 3px + offset geometry; only the edge and wash go destructive.
32
+ */
33
+ export const focusRingInvalid =
34
+ "aria-invalid:border-destructive aria-invalid:focus-visible:border-destructive aria-invalid:focus-visible:ring-destructive/20"
35
+
36
+ export const focusRingInvalidWithin =
37
+ "aria-invalid:border-destructive aria-invalid:focus-within:border-destructive aria-invalid:focus-within:ring-destructive/20"
38
+
39
+ /** Transparent border so borderless chrome can take `focusRing`'s hard edge. */
40
+ export const focusRingBorder =
41
+ "border border-transparent"
package/src/lib/popup.ts CHANGED
@@ -36,7 +36,7 @@ export const popupInset = "p-1.5 empty:p-0"
36
36
 
37
37
  /** One selectable row. */
38
38
  export const popupItem =
39
- "flex min-h-9 cursor-default items-center gap-2 rounded-sm px-3 py-2 text-sm text-fg-primary outline-none select-none"
39
+ "flex min-h-9 cursor-pointer items-center gap-2 rounded-sm px-3 py-2 text-sm text-fg-primary outline-none select-none"
40
40
 
41
41
  /** A group heading. Shares the item's left edge. */
42
42
  export const popupLabel = "px-3 py-1.5 text-xs text-fg-tertiary"
@@ -0,0 +1,71 @@
1
+ import type { ComponentType } from "react"
2
+ import { cn } from "../lib/cn"
3
+
4
+ export type CompanyIconId = string
5
+
6
+ export interface CompanyIconEntry {
7
+ icon: ComponentType<{ className?: string }>
8
+ /** Tailwind size for the mark — wordmarks want a wide box. */
9
+ sizeClassName?: string
10
+ }
11
+
12
+ const registry: Record<string, CompanyIconEntry> = {}
13
+
14
+ /**
15
+ * Map your organization ids to icon components. Call once at module
16
+ * scope, from a module that loads before the timeline renders:
17
+ *
18
+ * registerCompanyIcons({
19
+ * acme: { icon: AcmeIcon, sizeClassName: "h-4 w-4" },
20
+ * })
21
+ *
22
+ * Unregistered ids fall back to the name's initial in a small ring,
23
+ * so a timeline reads cleanly before you've drawn a single logo.
24
+ */
25
+ export function registerCompanyIcons(
26
+ entries: Record<string, CompanyIconEntry>,
27
+ ) {
28
+ Object.assign(registry, entries)
29
+ }
30
+
31
+ export function CompanyIcon({
32
+ id,
33
+ label,
34
+ className,
35
+ }: {
36
+ id: CompanyIconId
37
+ label: string
38
+ className?: string
39
+ }) {
40
+ const entry = registry[id]
41
+
42
+ if (entry) {
43
+ const Icon = entry.icon
44
+ return (
45
+ <span
46
+ className={cn(
47
+ "inline-flex shrink-0 items-center justify-center text-fg-primary transition-colors duration-300",
48
+ entry.sizeClassName ?? "h-4 w-4",
49
+ className,
50
+ )}
51
+ aria-label={label}
52
+ title={label}
53
+ >
54
+ <Icon className="h-full w-full" />
55
+ </span>
56
+ )
57
+ }
58
+
59
+ return (
60
+ <span
61
+ title={label}
62
+ aria-label={label}
63
+ className={cn(
64
+ "inline-flex h-5 w-5 select-none items-center justify-center rounded-full text-[10px] font-semibold leading-none ring-1 ring-current/30",
65
+ className,
66
+ )}
67
+ >
68
+ {label.charAt(0)}
69
+ </span>
70
+ )
71
+ }