@plexui/ui 0.19.1 → 0.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -138
- package/dist/es/components/Accordion/Accordion.js +2 -2
- package/dist/es/components/Accordion/Accordion.js.map +1 -1
- package/dist/es/components/Accordion/index.js +1 -1
- package/dist/es/components/Alert/Alert.js +6 -6
- package/dist/es/components/Alert/Alert.js.map +1 -1
- package/dist/es/components/Alert/index.js +1 -1
- package/dist/es/components/Avatar/Avatar.js +12 -5
- package/dist/es/components/Avatar/Avatar.js.map +1 -1
- package/dist/es/components/Avatar/AvatarGroup.js +2 -2
- package/dist/es/components/Avatar/AvatarGroup.js.map +1 -1
- package/dist/es/components/Avatar/index.js +2 -2
- package/dist/es/components/Badge/index.js +3 -3
- package/dist/es/components/Badge/index.js.map +1 -1
- package/dist/es/components/Breadcrumb/Breadcrumb.js +34 -0
- package/dist/es/components/Breadcrumb/Breadcrumb.js.map +1 -0
- package/dist/es/components/Breadcrumb/index.js +2 -0
- package/dist/es/components/Breadcrumb/index.js.map +1 -0
- package/dist/es/components/Button/Button.js +7 -7
- package/dist/es/components/Button/Button.js.map +1 -1
- package/dist/es/components/Button/CopyButton.js +25 -13
- package/dist/es/components/Button/CopyButton.js.map +1 -1
- package/dist/es/components/Button/index.js +2 -2
- package/dist/es/components/ButtonGroup/ButtonGroup.js +2 -2
- package/dist/es/components/ButtonGroup/ButtonGroup.js.map +1 -1
- package/dist/es/components/ButtonGroup/index.js +1 -1
- package/dist/es/components/Card/Card.js +4 -3
- package/dist/es/components/Card/Card.js.map +1 -1
- package/dist/es/components/Card/index.js +1 -1
- package/dist/es/components/Checkbox/Checkbox.js +12 -6
- package/dist/es/components/Checkbox/Checkbox.js.map +1 -1
- package/dist/es/components/Checkbox/index.js +1 -1
- package/dist/es/components/CodeBlock/CodeBlock.js +25 -25
- package/dist/es/components/CodeBlock/CodeBlock.js.map +1 -1
- package/dist/es/components/CodeBlock/CollapsibleCodeBlock.js +6 -4
- package/dist/es/components/CodeBlock/CollapsibleCodeBlock.js.map +1 -1
- package/dist/es/components/CodeBlock/index.js +2 -2
- package/dist/es/components/DataTable/DataTable.js +108 -27
- package/dist/es/components/DataTable/DataTable.js.map +1 -1
- package/dist/es/components/DataTable/DataTableColumnHeader.js +2 -2
- package/dist/es/components/DataTable/DataTableColumnHeader.js.map +1 -1
- package/dist/es/components/DataTable/DataTablePagination.js +8 -4
- package/dist/es/components/DataTable/DataTablePagination.js.map +1 -1
- package/dist/es/components/DataTable/columnHelpers.js +3 -3
- package/dist/es/components/DataTable/index.js +4 -4
- package/dist/es/components/DateInput/DateInput.js +21 -13
- package/dist/es/components/DateInput/DateInput.js.map +1 -1
- package/dist/es/components/DateInput/index.js +1 -1
- package/dist/es/components/DatePicker/Calendar.js +136 -32
- package/dist/es/components/DatePicker/Calendar.js.map +1 -1
- package/dist/es/components/DatePicker/DatePicker.js +15 -11
- package/dist/es/components/DatePicker/DatePicker.js.map +1 -1
- package/dist/es/components/DatePicker/index.js +1 -1
- package/dist/es/components/DateRangePicker/Calendar.js +125 -22
- package/dist/es/components/DateRangePicker/Calendar.js.map +1 -1
- package/dist/es/components/DateRangePicker/DateRangePicker.js +10 -9
- package/dist/es/components/DateRangePicker/DateRangePicker.js.map +1 -1
- package/dist/es/components/DateRangePicker/Trigger.js +12 -9
- package/dist/es/components/DateRangePicker/Trigger.js.map +1 -1
- package/dist/es/components/DateRangePicker/index.js +2 -2
- package/dist/es/components/Dialog/Dialog.js +11 -6
- package/dist/es/components/Dialog/Dialog.js.map +1 -1
- package/dist/es/components/Dialog/index.js +1 -1
- package/dist/es/components/Dialog/index.js.map +1 -1
- package/dist/es/components/EmptyMessage/EmptyMessage.js +4 -4
- package/dist/es/components/EmptyMessage/EmptyMessage.js.map +1 -1
- package/dist/es/components/EmptyMessage/index.js +1 -1
- package/dist/es/components/Field/Field.js +22 -7
- package/dist/es/components/Field/Field.js.map +1 -1
- package/dist/es/components/Field/index.js +1 -1
- package/dist/es/components/FieldError/FieldError.js +4 -4
- package/dist/es/components/FieldError/FieldError.js.map +1 -1
- package/dist/es/components/FieldError/index.js +1 -1
- package/dist/es/components/FileUpload/FileUpload.js +12 -9
- package/dist/es/components/FileUpload/FileUpload.js.map +1 -1
- package/dist/es/components/FileUpload/index.js +1 -1
- package/dist/es/components/FloatingLabelInput/FloatingLabelInput.js +31 -4
- package/dist/es/components/FloatingLabelInput/FloatingLabelInput.js.map +1 -1
- package/dist/es/components/FloatingLabelInput/index.js +1 -1
- package/dist/es/components/FloatingLabelSelect/FloatingLabelSelect.js +28 -8
- package/dist/es/components/FloatingLabelSelect/FloatingLabelSelect.js.map +1 -1
- package/dist/es/components/FloatingLabelSelect/index.js +1 -1
- package/dist/es/components/Icon/aliases.js +20 -20
- package/dist/es/components/Icon/index.js +653 -653
- package/dist/es/components/Image/Image.js +19 -7
- package/dist/es/components/Image/Image.js.map +1 -1
- package/dist/es/components/Image/index.js +1 -1
- package/dist/es/components/Indicator/CircularProgress.js +3 -3
- package/dist/es/components/Indicator/CircularProgress.js.map +1 -1
- package/dist/es/components/Indicator/LoadingDots.js +1 -1
- package/dist/es/components/Indicator/LoadingDots.js.map +1 -1
- package/dist/es/components/Indicator/LoadingIndicator.js +2 -2
- package/dist/es/components/Indicator/LoadingIndicator.js.map +1 -1
- package/dist/es/components/Indicator/index.js +3 -3
- package/dist/es/components/Input/Input.js +16 -5
- package/dist/es/components/Input/Input.js.map +1 -1
- package/dist/es/components/Input/index.js +1 -1
- package/dist/es/components/InputGroup/InputGroup.js +60 -0
- package/dist/es/components/InputGroup/InputGroup.js.map +1 -0
- package/dist/es/components/InputGroup/index.js +2 -0
- package/dist/es/components/InputGroup/index.js.map +1 -0
- package/dist/es/components/Kbd/Kbd.js +13 -0
- package/dist/es/components/Kbd/Kbd.js.map +1 -0
- package/dist/es/components/Kbd/index.js +2 -0
- package/dist/es/components/Kbd/index.js.map +1 -0
- package/dist/es/components/Label/Label.js +1 -1
- package/dist/es/components/Label/Label.js.map +1 -1
- package/dist/es/components/Label/index.js +1 -1
- package/dist/es/components/Markdown/Markdown.js +8 -8
- package/dist/es/components/Markdown/Markdown.js.map +1 -1
- package/dist/es/components/Markdown/directives.js +2 -2
- package/dist/es/components/Markdown/index.js +4 -5
- package/dist/es/components/Markdown/index.js.map +1 -1
- package/dist/es/components/MarkdownEditor/MarkdownEditor.js +35 -11
- package/dist/es/components/MarkdownEditor/MarkdownEditor.js.map +1 -1
- package/dist/es/components/MarkdownEditor/index.js +1 -1
- package/dist/es/components/Menu/Menu.js +30 -22
- package/dist/es/components/Menu/Menu.js.map +1 -1
- package/dist/es/components/Menu/index.js +1 -1
- package/dist/es/components/OTPInput/OTPInput.js +51 -34
- package/dist/es/components/OTPInput/OTPInput.js.map +1 -1
- package/dist/es/components/OTPInput/index.js +1 -1
- package/dist/es/components/PlexUIProvider/PlexUIProvider.js +3 -1
- package/dist/es/components/PlexUIProvider/PlexUIProvider.js.map +1 -1
- package/dist/es/components/PlexUIProvider/index.js +1 -1
- package/dist/es/components/PlexUIProvider/internal.js +1 -1
- package/dist/es/components/Popover/Popover.js +7 -7
- package/dist/es/components/Popover/Popover.js.map +1 -1
- package/dist/es/components/Popover/index.js +2 -3
- package/dist/es/components/Popover/index.js.map +1 -1
- package/dist/es/components/Popover/usePopoverController.js +2 -2
- package/dist/es/components/Progress/Progress.js +1 -1
- package/dist/es/components/Progress/Progress.js.map +1 -1
- package/dist/es/components/Progress/index.js +1 -1
- package/dist/es/components/ProgressSteps/ProgressSteps.js +6 -4
- package/dist/es/components/ProgressSteps/ProgressSteps.js.map +1 -1
- package/dist/es/components/ProgressSteps/index.js +1 -1
- package/dist/es/components/RadioGroup/RadioGroup.js +10 -6
- package/dist/es/components/RadioGroup/RadioGroup.js.map +1 -1
- package/dist/es/components/RadioGroup/index.js +1 -1
- package/dist/es/components/SegmentedControl/index.js +1 -1
- package/dist/es/components/Select/Select.js +103 -67
- package/dist/es/components/Select/Select.js.map +1 -1
- package/dist/es/components/Select/index.js +1 -1
- package/dist/es/components/SelectControl/SelectControl.js +10 -5
- package/dist/es/components/SelectControl/SelectControl.js.map +1 -1
- package/dist/es/components/SelectControl/index.js +1 -1
- package/dist/es/components/Separator/Separator.js +1 -1
- package/dist/es/components/Separator/Separator.js.map +1 -1
- package/dist/es/components/Separator/index.js +1 -1
- package/dist/es/components/ShimmerText/ShimmerText.js +1 -1
- package/dist/es/components/ShimmerText/ShimmerText.js.map +1 -1
- package/dist/es/components/ShimmerText/index.js +1 -1
- package/dist/es/components/Sidebar/Sidebar.js +37 -29
- package/dist/es/components/Sidebar/Sidebar.js.map +1 -1
- package/dist/es/components/Sidebar/index.js +2 -2
- package/dist/es/components/Sidebar/useSidebarContext.js +17 -19
- package/dist/es/components/Sidebar/useSidebarContext.js.map +1 -1
- package/dist/es/components/Skeleton/index.js +1 -1
- package/dist/es/components/Skeleton/index.js.map +1 -1
- package/dist/es/components/Slider/Slider.js +48 -19
- package/dist/es/components/Slider/Slider.js.map +1 -1
- package/dist/es/components/Slider/index.js +1 -1
- package/dist/es/components/StatCard/StatCard.js +5 -5
- package/dist/es/components/StatCard/StatCard.js.map +1 -1
- package/dist/es/components/StatCard/index.js +1 -1
- package/dist/es/components/Switch/Switch.js +7 -3
- package/dist/es/components/Switch/Switch.js.map +1 -1
- package/dist/es/components/Switch/index.js +1 -1
- package/dist/es/components/Table/Table.js +1 -1
- package/dist/es/components/Table/Table.js.map +1 -1
- package/dist/es/components/Table/index.js +1 -1
- package/dist/es/components/Tabs/Tabs.js +154 -6
- package/dist/es/components/Tabs/Tabs.js.map +1 -1
- package/dist/es/components/Tabs/index.js +1 -1
- package/dist/es/components/Tabs/overflow.js +44 -0
- package/dist/es/components/Tabs/overflow.js.map +1 -0
- package/dist/es/components/TagInput/TagInput.js +47 -23
- package/dist/es/components/TagInput/TagInput.js.map +1 -1
- package/dist/es/components/TagInput/index.js +1 -1
- package/dist/es/components/TextLink/TextLink.js +16 -5
- package/dist/es/components/TextLink/TextLink.js.map +1 -1
- package/dist/es/components/TextLink/index.js +1 -1
- package/dist/es/components/Textarea/Textarea.js +4 -4
- package/dist/es/components/Textarea/Textarea.js.map +1 -1
- package/dist/es/components/Textarea/index.js +1 -1
- package/dist/es/components/Toast/Toaster.js +2 -2
- package/dist/es/components/Toast/Toaster.js.map +1 -1
- package/dist/es/components/Toast/index.js +1 -1
- package/dist/es/components/Tooltip/CopyTooltip.js +30 -9
- package/dist/es/components/Tooltip/CopyTooltip.js.map +1 -1
- package/dist/es/components/Tooltip/Tooltip.js +3 -3
- package/dist/es/components/Tooltip/Tooltip.js.map +1 -1
- package/dist/es/components/Tooltip/index.js +2 -2
- package/dist/es/components/Transition/Animate.js +4 -4
- package/dist/es/components/Transition/Animate.js.map +1 -1
- package/dist/es/components/Transition/AnimateLayout.js +4 -4
- package/dist/es/components/Transition/AnimateLayout.js.map +1 -1
- package/dist/es/components/Transition/AnimateLayoutGroup.js +12 -8
- package/dist/es/components/Transition/AnimateLayoutGroup.js.map +1 -1
- package/dist/es/components/Transition/SlotTransitionGroup.js +4 -4
- package/dist/es/components/Transition/TransitionGroup.js +5 -5
- package/dist/es/components/Transition/TransitionGroup.js.map +1 -1
- package/dist/es/components/Transition/getDisableAnimations.js +1 -1
- package/dist/es/components/Transition/index.js +5 -5
- package/dist/es/components/Transition/shared.js +7 -5
- package/dist/es/components/Transition/shared.js.map +1 -1
- package/dist/es/components/UIProvider/UIProvider.js +1 -1
- package/dist/es/components/UIProvider/index.js +1 -1
- package/dist/es/components/UIProvider/internal.js +1 -1
- package/dist/es/hooks/useAnimatedScrollTo.js +1 -1
- package/dist/es/hooks/useBreakpoints.js +8 -2
- package/dist/es/hooks/useBreakpoints.js.map +1 -1
- package/dist/es/hooks/useEscCloseStack.js +1 -1
- package/dist/es/hooks/usePrevious.js +7 -5
- package/dist/es/hooks/usePrevious.js.map +1 -1
- package/dist/es/hooks/useTextSelection.js +2 -2
- package/dist/es/hooks/useTrailingValue.js +1 -1
- package/dist/es/lib/constants.js +1 -1
- package/dist/es/lib/helpers.js +1 -1
- package/dist/es/lib/helpers.js.map +1 -1
- package/dist/es/lib/renderHelpers.js +15 -6
- package/dist/es/lib/renderHelpers.js.map +1 -1
- package/dist/es/lib/theme.js +16 -16
- package/dist/es/lib/theme.js.map +1 -1
- package/dist/es/lib/userAgent.js +3 -2
- package/dist/es/lib/userAgent.js.map +1 -1
- package/dist/es/styles/base.css +1 -102
- package/dist/es/styles/globals.css +1 -50
- package/dist/es/styles/index.css +1 -25
- package/dist/es/styles/katex.min.css +1 -1296
- package/dist/es/styles/tailwind-utilities.css +1 -1316
- package/dist/es/styles/touch.css +1 -0
- package/dist/es/styles/variables-components.css +1 -626
- package/dist/es/styles/variables-primitive.css +1 -327
- package/dist/es/styles/variables-semantic.css +1 -609
- package/dist/es/styles/variables-tailwind-theme.css +1 -34
- package/dist/es/styles/variables-tokens-root.css +1 -41
- package/dist/es/types.js +1 -1
- package/dist/es/types.js.map +1 -1
- package/dist/es/vite/index.js +3 -53
- package/dist/es/vite/index.js.map +1 -1
- package/dist/types/components/Accordion/index.d.ts +1 -1
- package/dist/types/components/Alert/Alert.d.ts +8 -2
- package/dist/types/components/Alert/index.d.ts +1 -1
- package/dist/types/components/Avatar/Avatar.d.ts +1 -1
- package/dist/types/components/Avatar/index.d.ts +2 -2
- package/dist/types/components/Badge/index.d.ts +1 -1
- package/dist/types/components/Breadcrumb/Breadcrumb.d.ts +34 -0
- package/dist/types/components/Breadcrumb/index.d.ts +1 -0
- package/dist/types/components/Button/Button.d.ts +3 -3
- package/dist/types/components/Button/CopyButton.d.ts +9 -4
- package/dist/types/components/Button/index.d.ts +2 -2
- package/dist/types/components/ButtonGroup/ButtonGroup.d.ts +4 -3
- package/dist/types/components/ButtonGroup/index.d.ts +1 -1
- package/dist/types/components/Card/index.d.ts +1 -1
- package/dist/types/components/Checkbox/Checkbox.d.ts +3 -1
- package/dist/types/components/Checkbox/index.d.ts +1 -1
- package/dist/types/components/CodeBlock/index.d.ts +2 -2
- package/dist/types/components/DataTable/DataTable.d.ts +3 -2
- package/dist/types/components/DataTable/index.d.ts +4 -4
- package/dist/types/components/DateInput/DateInput.d.ts +1 -1
- package/dist/types/components/DateInput/index.d.ts +1 -1
- package/dist/types/components/DatePicker/DatePicker.d.ts +7 -6
- package/dist/types/components/DatePicker/context.d.ts +1 -1
- package/dist/types/components/DatePicker/index.d.ts +2 -2
- package/dist/types/components/DateRangePicker/Calendar.d.ts +1 -1
- package/dist/types/components/DateRangePicker/DateRangePicker.d.ts +5 -5
- package/dist/types/components/DateRangePicker/context.d.ts +2 -2
- package/dist/types/components/DateRangePicker/index.d.ts +2 -2
- package/dist/types/components/Dialog/Dialog.d.ts +19 -1
- package/dist/types/components/Dialog/index.d.ts +1 -1
- package/dist/types/components/EmptyMessage/EmptyMessage.d.ts +15 -3
- package/dist/types/components/EmptyMessage/index.d.ts +1 -1
- package/dist/types/components/Field/Field.d.ts +14 -4
- package/dist/types/components/Field/index.d.ts +1 -1
- package/dist/types/components/FieldError/FieldError.d.ts +7 -1
- package/dist/types/components/FieldError/index.d.ts +1 -1
- package/dist/types/components/FileUpload/index.d.ts +1 -1
- package/dist/types/components/FloatingLabelInput/index.d.ts +1 -1
- package/dist/types/components/FloatingLabelSelect/index.d.ts +1 -1
- package/dist/types/components/Icon/aliases.d.ts +20 -20
- package/dist/types/components/Icon/index.d.ts +653 -653
- package/dist/types/components/Image/Image.d.ts +1 -1
- package/dist/types/components/Image/index.d.ts +1 -1
- package/dist/types/components/Indicator/index.d.ts +3 -3
- package/dist/types/components/Input/Input.d.ts +2 -2
- package/dist/types/components/Input/index.d.ts +1 -1
- package/dist/types/components/InputGroup/InputGroup.d.ts +78 -0
- package/dist/types/components/InputGroup/index.d.ts +1 -0
- package/dist/types/components/Kbd/Kbd.d.ts +20 -0
- package/dist/types/components/Kbd/index.d.ts +1 -0
- package/dist/types/components/Label/index.d.ts +1 -1
- package/dist/types/components/Markdown/Markdown.d.ts +1 -1
- package/dist/types/components/Markdown/index.d.ts +4 -4
- package/dist/types/components/MarkdownEditor/MarkdownEditor.d.ts +6 -2
- package/dist/types/components/MarkdownEditor/index.d.ts +1 -1
- package/dist/types/components/Menu/Menu.d.ts +19 -5
- package/dist/types/components/Menu/index.d.ts +1 -1
- package/dist/types/components/OTPInput/index.d.ts +1 -1
- package/dist/types/components/PlexUIProvider/PlexUIProvider.d.ts +0 -11
- package/dist/types/components/PlexUIProvider/index.d.ts +1 -1
- package/dist/types/components/Popover/index.d.ts +2 -2
- package/dist/types/components/Progress/index.d.ts +1 -1
- package/dist/types/components/ProgressSteps/ProgressSteps.d.ts +1 -1
- package/dist/types/components/ProgressSteps/index.d.ts +1 -1
- package/dist/types/components/RadioGroup/RadioGroup.d.ts +3 -1
- package/dist/types/components/RadioGroup/index.d.ts +1 -1
- package/dist/types/components/SegmentedControl/index.d.ts +2 -2
- package/dist/types/components/Select/Select.d.ts +8 -1
- package/dist/types/components/Select/index.d.ts +1 -1
- package/dist/types/components/SelectControl/SelectControl.d.ts +1 -1
- package/dist/types/components/SelectControl/index.d.ts +1 -1
- package/dist/types/components/Separator/index.d.ts +1 -1
- package/dist/types/components/ShimmerText/index.d.ts +1 -1
- package/dist/types/components/Sidebar/Sidebar.d.ts +4 -8
- package/dist/types/components/Sidebar/index.d.ts +4 -4
- package/dist/types/components/Slider/Slider.d.ts +8 -0
- package/dist/types/components/Slider/index.d.ts +2 -2
- package/dist/types/components/StatCard/index.d.ts +1 -1
- package/dist/types/components/Switch/index.d.ts +1 -1
- package/dist/types/components/Table/index.d.ts +1 -1
- package/dist/types/components/Tabs/Tabs.d.ts +15 -2
- package/dist/types/components/Tabs/index.d.ts +2 -2
- package/dist/types/components/Tabs/overflow.d.ts +17 -0
- package/dist/types/components/TagInput/TagInput.d.ts +1 -1
- package/dist/types/components/TagInput/index.d.ts +1 -1
- package/dist/types/components/TextLink/index.d.ts +1 -1
- package/dist/types/components/Textarea/Textarea.d.ts +1 -1
- package/dist/types/components/Textarea/index.d.ts +1 -1
- package/dist/types/components/Toast/index.d.ts +1 -1
- package/dist/types/components/Tooltip/CopyTooltip.d.ts +6 -1
- package/dist/types/components/Tooltip/index.d.ts +2 -2
- package/dist/types/components/Transition/Animate.d.ts +2 -2
- package/dist/types/components/Transition/AnimateLayout.d.ts +2 -2
- package/dist/types/components/Transition/AnimateLayoutGroup.d.ts +2 -2
- package/dist/types/components/Transition/SlotTransitionGroup.d.ts +1 -1
- package/dist/types/components/Transition/TransitionGroup.d.ts +1 -1
- package/dist/types/components/Transition/index.d.ts +5 -5
- package/dist/types/components/UIProvider/index.d.ts +1 -1
- package/dist/types/global.d.ts +5 -1
- package/dist/types/lib/constants.d.ts +1 -1
- package/dist/types/lib/helpers.d.ts +4 -4
- package/dist/types/lib/theme.d.ts +1 -1
- package/dist/types/types.d.ts +2 -15
- package/dist/types/vite/index.d.ts +2 -55
- package/package.json +10 -18
- package/dist/es/components/Accordion/Accordion.module.css +0 -89
- package/dist/es/components/Alert/Alert.module.css +0 -187
- package/dist/es/components/Avatar/Avatar.module.css +0 -168
- package/dist/es/components/Avatar/AvatarGroup.module.css +0 -26
- package/dist/es/components/Badge/Badge.module.css +0 -196
- package/dist/es/components/Button/Button.module.css +0 -859
- package/dist/es/components/ButtonGroup/ButtonGroup.module.css +0 -159
- package/dist/es/components/Card/Card.module.css +0 -125
- package/dist/es/components/Checkbox/Checkbox.module.css +0 -198
- package/dist/es/components/CodeBlock/CodeBlock.module.css +0 -137
- package/dist/es/components/DataTable/DataTable.module.css +0 -108
- package/dist/es/components/DatePicker/Calendar.module.css +0 -271
- package/dist/es/components/DateRangePicker/Calendar.module.css +0 -295
- package/dist/es/components/DateRangePicker/Trigger.module.css +0 -25
- package/dist/es/components/Dialog/Dialog.module.css +0 -133
- package/dist/es/components/EmptyMessage/EmptyMessage.module.css +0 -82
- package/dist/es/components/Field/Field.module.css +0 -137
- package/dist/es/components/FieldError/FieldError.module.css +0 -22
- package/dist/es/components/FileUpload/FileUpload.module.css +0 -133
- package/dist/es/components/FloatingLabelInput/FloatingLabelInput.module.css +0 -220
- package/dist/es/components/FloatingLabelSelect/FloatingLabelSelect.module.css +0 -146
- package/dist/es/components/Image/Image.module.css +0 -9
- package/dist/es/components/Indicator/CircularProgress.module.css +0 -28
- package/dist/es/components/Indicator/LoadingDots.module.css +0 -35
- package/dist/es/components/Indicator/LoadingIndicator.module.css +0 -41
- package/dist/es/components/Input/Input.module.css +0 -507
- package/dist/es/components/Label/Label.module.css +0 -16
- package/dist/es/components/Markdown/Markdown.module.css +0 -233
- package/dist/es/components/MarkdownEditor/MarkdownEditor.module.css +0 -297
- package/dist/es/components/Menu/Menu.module.css +0 -377
- package/dist/es/components/OTPInput/OTPInput.module.css +0 -66
- package/dist/es/components/Popover/Popover.module.css +0 -82
- package/dist/es/components/Progress/Progress.module.css +0 -34
- package/dist/es/components/ProgressSteps/ProgressSteps.module.css +0 -246
- package/dist/es/components/RadioGroup/RadioGroup.module.css +0 -137
- package/dist/es/components/Select/Select.module.css +0 -310
- package/dist/es/components/SelectControl/SelectControl.module.css +0 -558
- package/dist/es/components/Separator/Separator.module.css +0 -16
- package/dist/es/components/ShimmerText/ShimmerText.module.css +0 -43
- package/dist/es/components/Sidebar/Sidebar.module.css +0 -909
- package/dist/es/components/Skeleton/Skeleton.module.css +0 -17
- package/dist/es/components/Slider/Slider.module.css +0 -203
- package/dist/es/components/StatCard/StatCard.module.css +0 -234
- package/dist/es/components/Switch/Switch.module.css +0 -121
- package/dist/es/components/Table/Table.module.css +0 -56
- package/dist/es/components/Tabs/Tabs.module.css +0 -672
- package/dist/es/components/TagInput/TagInput.module.css +0 -320
- package/dist/es/components/TextLink/TextLink.module.css +0 -50
- package/dist/es/components/Textarea/Textarea.module.css +0 -272
- package/dist/es/components/Toast/Toast.module.css +0 -84
- package/dist/es/components/Tooltip/Tooltip.module.css +0 -91
- package/dist/es/components/Transition/Animate.module.css +0 -54
- package/dist/es/components/Transition/AnimateLayout.module.css +0 -101
- package/dist/es/components/Transition/AnimateLayoutGroup.module.css +0 -72
- package/dist/es/components/Transition/TransitionGroup.module.css +0 -4
package/README.md
CHANGED
|
@@ -1,175 +1,52 @@
|
|
|
1
1
|
# @plexui/ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
React components of [Plex UI](https://plexui.com): 50 accessible components on Radix primitives, one 9-size scale across every control, three-layer design tokens and dark mode. Built for AI agents, with an MCP server, an agent skill and `llms.txt`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The same components for Vue: [`@plexui/vue`](https://www.npmjs.com/package/@plexui/vue).
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
[Docs](https://plexui.com) · [Components](https://plexui.com/components) · [GitHub](https://github.com/plex-ui/ui)
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## Highlights
|
|
12
|
-
|
|
13
|
-
- **Production-grade** — components designed and tested for real products at scale.
|
|
14
|
-
- **9-step size scale** — all key controls (Button, Input, Select, SegmentedControl, etc.) share a unified `ControlSize` scale from `3xs` (22 px) to `3xl` (48 px). Most competitors offer only 3–4.
|
|
15
|
-
- **Three-layer design tokens** — primitive → semantic → component CSS custom properties with `light-dark()` theming, alpha transparency scale, and 4-level elevation system.
|
|
16
|
-
- **Radix + Tailwind 4** — accessible primitives under the hood, utility-first styling on top.
|
|
17
|
-
- **Built for AI code editors** — consistent naming, clear token system, and comprehensive props give Claude, Cursor, Codex & other AI tools the building blocks to generate professional UI.
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Installation
|
|
9
|
+
## Install
|
|
22
10
|
|
|
23
11
|
```bash
|
|
24
12
|
npm install @plexui/ui
|
|
25
13
|
```
|
|
26
14
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
The package requires the following peers — install them if they are not already in your project:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
npm install react react-dom tailwindcss
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
| Peer | Version |
|
|
36
|
-
|------|---------|
|
|
37
|
-
| `react` | `^18 \|\| ^19` |
|
|
38
|
-
| `react-dom` | `^18 \|\| ^19` |
|
|
39
|
-
| `tailwindcss` | `^4.0.10` |
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
## Setup
|
|
44
|
-
|
|
45
|
-
### 1. Import CSS
|
|
46
|
-
|
|
47
|
-
Add the Plex UI stylesheet to your global CSS file alongside Tailwind:
|
|
15
|
+
Requires React 19 and Tailwind CSS 4.
|
|
48
16
|
|
|
49
17
|
```css
|
|
50
|
-
/*
|
|
18
|
+
/* globals.css */
|
|
19
|
+
@layer theme, base, components, utilities;
|
|
51
20
|
@import "tailwindcss";
|
|
52
21
|
@import "@plexui/ui/css";
|
|
22
|
+
@source "../node_modules/@plexui/ui";
|
|
53
23
|
```
|
|
54
24
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
`PlexUIProvider` supplies shared context (e.g. the link component) to all Plex UI components.
|
|
25
|
+
On Vite, add `plexui()` from `@plexui/ui/vite` and drop the `@layer` line. Wrap the app in `PlexUIProvider` to set the link component (for example Next.js `Link`):
|
|
58
26
|
|
|
59
27
|
```tsx
|
|
60
|
-
// app/layout.tsx (Next.js example)
|
|
61
28
|
import { PlexUIProvider } from "@plexui/ui/components/PlexUIProvider";
|
|
62
29
|
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
<html lang="en">
|
|
66
|
-
<body>
|
|
67
|
-
<PlexUIProvider linkComponent="a">
|
|
68
|
-
{children}
|
|
69
|
-
</PlexUIProvider>
|
|
70
|
-
</body>
|
|
71
|
-
</html>
|
|
72
|
-
);
|
|
73
|
-
}
|
|
30
|
+
<PlexUIProvider linkComponent={Link}>{children}</PlexUIProvider>
|
|
74
31
|
```
|
|
75
32
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
### 3. Use components
|
|
33
|
+
## Use
|
|
79
34
|
|
|
80
35
|
```tsx
|
|
81
36
|
import { Button } from "@plexui/ui/components/Button";
|
|
82
37
|
|
|
83
|
-
|
|
84
|
-
return (
|
|
85
|
-
<Button color="primary" variant="solid" size="md">
|
|
86
|
-
Get started
|
|
87
|
-
</Button>
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
---
|
|
93
|
-
|
|
94
|
-
## Exports
|
|
95
|
-
|
|
96
|
-
All exports use subpath imports for optimal tree-shaking.
|
|
97
|
-
|
|
98
|
-
### Components
|
|
99
|
-
|
|
100
|
-
```ts
|
|
101
|
-
import { Button, ButtonLink } from "@plexui/ui/components/Button";
|
|
102
|
-
import { Input } from "@plexui/ui/components/Input";
|
|
103
|
-
import { Select, Option } from "@plexui/ui/components/Select";
|
|
104
|
-
// ... 35 components total
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
<details>
|
|
108
|
-
<summary>Full component list</summary>
|
|
109
|
-
|
|
110
|
-
Alert, Avatar, AvatarGroup, Badge, Button, ButtonLink, Checkbox, CodeBlock, CopyTooltip, DateInput, DatePicker, DateRangePicker, EmptyMessage, FieldError, FloatingLabelInput, Icon, Image, Indicators (LoadingIndicator, LoadingDots, CircularProgress), Input, Markdown, Menu, PlexUIProvider, Popover, ProgressSteps, RadioGroup, SegmentedControl, Select, SelectControl, ShimmerText, Sidebar, Skeleton, Slider, Switch, TagInput, TextLink, Textarea, Tooltip, Transition (Animate, AnimateLayout, AnimateLayoutGroup, TransitionGroup)
|
|
111
|
-
|
|
112
|
-
</details>
|
|
113
|
-
|
|
114
|
-
### Hooks
|
|
115
|
-
|
|
116
|
-
```ts
|
|
117
|
-
import { useBreakpoints } from "@plexui/ui/hooks/useBreakpoints";
|
|
118
|
-
import { useScrollable } from "@plexui/ui/hooks/useScrollable";
|
|
119
|
-
// ... 14 hooks total
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### Types
|
|
123
|
-
|
|
124
|
-
```ts
|
|
125
|
-
import type { ControlSize, SemanticColors, Variants } from "@plexui/ui/types";
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### CSS
|
|
129
|
-
|
|
130
|
-
```css
|
|
131
|
-
@import "@plexui/ui/css";
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Utilities
|
|
135
|
-
|
|
136
|
-
```ts
|
|
137
|
-
import { theme } from "@plexui/ui/theme";
|
|
138
|
-
import { helpers } from "@plexui/ui/helpers";
|
|
139
|
-
import { dateUtils } from "@plexui/ui/dateUtils";
|
|
38
|
+
<Button color="primary" size="lg">Get started</Button>
|
|
140
39
|
```
|
|
141
40
|
|
|
142
|
-
|
|
41
|
+
Every component has its own subpath: `@plexui/ui/components/<Name>`. Hooks live in `@plexui/ui/hooks/<name>`, shared types in `@plexui/ui/types`, theme helpers in `@plexui/ui/theme`.
|
|
143
42
|
|
|
144
43
|
## Size scale
|
|
145
44
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
| Size | Height |
|
|
149
|
-
|------|--------|
|
|
150
|
-
| `3xs` | 22 px |
|
|
151
|
-
| `2xs` | 24 px |
|
|
152
|
-
| `xs` | 26 px |
|
|
153
|
-
| `sm` | 28 px |
|
|
154
|
-
| **`md`** | **32 px** (default) |
|
|
155
|
-
| `lg` | 36 px |
|
|
156
|
-
| `xl` | 40 px |
|
|
157
|
-
| `2xl` | 44 px |
|
|
158
|
-
| `3xl` | 48 px |
|
|
159
|
-
|
|
160
|
-
---
|
|
45
|
+
Controls share one `size` scale: `3xs` 22px, `2xs` 24px, `xs` 26px, `sm` 28px, `md` 32px (default), `lg` 36px, `xl` 40px, `2xl` 44px, `3xl` 48px.
|
|
161
46
|
|
|
162
47
|
## Dark mode
|
|
163
48
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
```css
|
|
167
|
-
:root { color-scheme: light; } /* light theme */
|
|
168
|
-
:root { color-scheme: dark; } /* dark theme */
|
|
169
|
-
:root { color-scheme: light dark; } /* follows OS preference */
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
---
|
|
49
|
+
Set `data-theme="dark"` (or `"light"`) on `<html>`; it also works on any element for a nested scope. `applyDocumentTheme`, `getDocumentTheme` and `useDocumentTheme` from `@plexui/ui/theme` read and set it. See [Dark mode](https://plexui.com/docs/concepts#dark-mode).
|
|
173
50
|
|
|
174
51
|
## License
|
|
175
52
|
|
|
@@ -3,8 +3,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import clsx from "clsx";
|
|
4
4
|
import {} from "react";
|
|
5
5
|
import { Accordion as RadixAccordion } from "radix-ui";
|
|
6
|
-
import { ChevronDownMd } from "../Icon";
|
|
7
|
-
import s from "
|
|
6
|
+
import { ChevronDownMd } from "../Icon/index.js";
|
|
7
|
+
import s from "@plexui/styles/components/Accordion/Accordion.module.css";
|
|
8
8
|
const AccordionRoot = ({ className, ...restProps }) => (_jsx(RadixAccordion.Root, { className: clsx(s.Root, className), ...restProps }));
|
|
9
9
|
const AccordionItem = ({ className, ...restProps }) => (_jsx(RadixAccordion.Item, { className: clsx(s.Item, className), ...restProps }));
|
|
10
10
|
const AccordionTrigger = ({ className, children, ref, ...restProps }) => (_jsx(RadixAccordion.Header, { className: s.Header, children: _jsxs(RadixAccordion.Trigger, { ref: ref, className: clsx(s.Trigger, className), ...restProps, children: [children, _jsx(ChevronDownMd, { className: s.Chevron, "aria-hidden": true })] }) }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Accordion.js","sourceRoot":"","sources":["../../../../src/components/Accordion/Accordion.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAiC,MAAM,OAAO,CAAA;AACrD,OAAO,EAAE,SAAS,IAAI,cAAc,EAAE,MAAM,UAAU,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACvC,OAAO,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"Accordion.js","sourceRoot":"","sources":["../../../../src/components/Accordion/Accordion.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAiC,MAAM,OAAO,CAAA;AACrD,OAAO,EAAE,SAAS,IAAI,cAAc,EAAE,MAAM,UAAU,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AACvC,OAAO,CAAC,MAAM,0DAA0D,CAAA;AAUxE,MAAM,aAAa,GAAG,CAAC,EACrB,SAAS,EACT,GAAG,SAAS,EACG,EAAE,EAAE,CAAC,CACpB,KAAC,cAAc,CAAC,IAAI,IAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,KAAM,SAAS,GAAI,CAC3E,CAAA;AAUD,MAAM,aAAa,GAAG,CAAC,EACrB,SAAS,EACT,GAAG,SAAS,EACO,EAAE,EAAE,CAAC,CACxB,KAAC,cAAc,CAAC,IAAI,IAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,KAAM,SAAS,GAAI,CAC3E,CAAA;AAaD,MAAM,gBAAgB,GAAG,CAAC,EACxB,SAAS,EACT,QAAQ,EACR,GAAG,EACH,GAAG,SAAS,EACU,EAAE,EAAE,CAAC,CAC3B,KAAC,cAAc,CAAC,MAAM,IAAC,SAAS,EAAE,CAAC,CAAC,MAAM,YACxC,MAAC,cAAc,CAAC,OAAO,IACrB,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,KACjC,SAAS,aAEZ,QAAQ,EACT,KAAC,aAAa,IAAC,SAAS,EAAE,CAAC,CAAC,OAAO,wBAAgB,IAC5B,GACH,CACzB,CAAA;AAYD,MAAM,gBAAgB,GAAG,CAAC,EACxB,SAAS,EACT,QAAQ,EACR,GAAG,SAAS,EACU,EAAE,EAAE,CAAC,CAC3B,KAAC,cAAc,CAAC,OAAO,IAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,KAAM,SAAS,YAC1E,cAAK,SAAS,EAAE,CAAC,CAAC,YAAY,YAAG,QAAQ,GAAO,GACzB,CAC1B,CAAA;AAYD,MAAM,CAAC,MAAM,SAAS,GAAG,aAAmC,CAAA;AAC5D,SAAS,CAAC,IAAI,GAAG,aAAa,CAAA;AAC9B,SAAS,CAAC,OAAO,GAAG,gBAAgB,CAAA;AACpC,SAAS,CAAC,OAAO,GAAG,gBAAgB,CAAA","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { type ComponentProps, type Ref } from \"react\"\nimport { Accordion as RadixAccordion } from \"radix-ui\"\nimport { ChevronDownMd } from \"../Icon\"\nimport s from \"@plexui/styles/components/Accordion/Accordion.module.css\"\n\n/* ------------------------------------------------------------------ */\n/* Root */\n/* ------------------------------------------------------------------ */\n\nexport type AccordionProps = ComponentProps<typeof RadixAccordion.Root> & {\n className?: string\n}\n\nconst AccordionRoot = ({\n className,\n ...restProps\n}: AccordionProps) => (\n <RadixAccordion.Root className={clsx(s.Root, className)} {...restProps} />\n)\n\n/* ------------------------------------------------------------------ */\n/* Item */\n/* ------------------------------------------------------------------ */\n\nexport type AccordionItemProps = ComponentProps<typeof RadixAccordion.Item> & {\n className?: string\n}\n\nconst AccordionItem = ({\n className,\n ...restProps\n}: AccordionItemProps) => (\n <RadixAccordion.Item className={clsx(s.Item, className)} {...restProps} />\n)\n\n/* ------------------------------------------------------------------ */\n/* Trigger */\n/* ------------------------------------------------------------------ */\n\nexport type AccordionTriggerProps = ComponentProps<\n typeof RadixAccordion.Trigger\n> & {\n className?: string\n ref?: Ref<HTMLButtonElement>\n}\n\nconst AccordionTrigger = ({\n className,\n children,\n ref,\n ...restProps\n}: AccordionTriggerProps) => (\n <RadixAccordion.Header className={s.Header}>\n <RadixAccordion.Trigger\n ref={ref}\n className={clsx(s.Trigger, className)}\n {...restProps}\n >\n {children}\n <ChevronDownMd className={s.Chevron} aria-hidden />\n </RadixAccordion.Trigger>\n </RadixAccordion.Header>\n)\n\n/* ------------------------------------------------------------------ */\n/* Content */\n/* ------------------------------------------------------------------ */\n\nexport type AccordionContentProps = ComponentProps<\n typeof RadixAccordion.Content\n> & {\n className?: string\n}\n\nconst AccordionContent = ({\n className,\n children,\n ...restProps\n}: AccordionContentProps) => (\n <RadixAccordion.Content className={clsx(s.Content, className)} {...restProps}>\n <div className={s.ContentInner}>{children}</div>\n </RadixAccordion.Content>\n)\n\n/* ------------------------------------------------------------------ */\n/* Export — compound API */\n/* ------------------------------------------------------------------ */\n\ntype AccordionComponent = typeof AccordionRoot & {\n Item: typeof AccordionItem\n Trigger: typeof AccordionTrigger\n Content: typeof AccordionContent\n}\n\nexport const Accordion = AccordionRoot as AccordionComponent\nAccordion.Item = AccordionItem\nAccordion.Trigger = AccordionTrigger\nAccordion.Content = AccordionContent\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { Accordion, } from "./Accordion";
|
|
1
|
+
export { Accordion, } from "./Accordion.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -4,11 +4,11 @@ import clsx from "clsx";
|
|
|
4
4
|
import { useEffect, useRef, useState } from "react";
|
|
5
5
|
import { mergeRefs } from "react-merge-refs";
|
|
6
6
|
import { useResizeObserver } from "usehooks-ts";
|
|
7
|
-
import {} from "../../types";
|
|
8
|
-
import { CheckCircle, Info, Warning } from "../Icon";
|
|
9
|
-
import { Button } from "../Button";
|
|
10
|
-
import s from "
|
|
11
|
-
export const Alert = ({ color = "primary", variant = "outline", title, description, actions, actionsPlacement, indicator, className, actionsClassName, onDismiss, ref, ...restProps }) => {
|
|
7
|
+
import {} from "../../types.js";
|
|
8
|
+
import { CheckCircle, Info, Warning } from "../Icon/index.js";
|
|
9
|
+
import { Button } from "../Button/index.js";
|
|
10
|
+
import s from "@plexui/styles/components/Alert/Alert.module.css";
|
|
11
|
+
export const Alert = ({ color = "primary", variant = "outline", title, description, actions, actionsPlacement, indicator, className, actionsClassName, onDismiss, banner = false, ref, ...restProps }) => {
|
|
12
12
|
const containerRef = useRef(null);
|
|
13
13
|
const actionsRef = useRef(null);
|
|
14
14
|
const [actionsAutoPlacement, setActionsAutoPlacement] = useState("end");
|
|
@@ -22,7 +22,7 @@ export const Alert = ({ color = "primary", variant = "outline", title, descripti
|
|
|
22
22
|
setActionsAutoPlacement(placement);
|
|
23
23
|
}
|
|
24
24
|
}, [containerWidth]);
|
|
25
|
-
return (_jsxs("div", { ref: mergeRefs([ref, containerRef]), className: clsx(s.Alert, className), "data-variant": variant, "data-color": color, role: color === "danger" ? "alert" : undefined, "data-actions-placement": actionsPlacement ?? actionsAutoPlacement, ...restProps, children: [indicator === false ? null : (_jsx("div", { className: s.Indicator, children: indicator ?? _jsx(Indicator, { color: color }) })), _jsxs("div", { className: s.Content, children: [_jsxs("div", { className: s.Message, children: [title && _jsx("div", { className: s.Title, children: title }), description && _jsx("div", { className: s.Description, children: description })] }), (actions || onDismiss) && (_jsxs("div", { className: clsx(s.Actions, actionsClassName), ref: actionsRef, children: [actions, onDismiss && (_jsx(Button, { type: "button", onClick: onDismiss, color: color, variant: "soft", pill: true, children: "Dismiss" }))] }))] })] }));
|
|
25
|
+
return (_jsxs("div", { ref: mergeRefs([ref, containerRef]), className: clsx(s.Alert, className), "data-variant": variant, "data-color": color, role: color === "danger" ? "alert" : undefined, "data-actions-placement": actionsPlacement ?? actionsAutoPlacement, "data-banner": banner ? "" : undefined, ...restProps, children: [indicator === false ? null : (_jsx("div", { className: s.Indicator, children: indicator ?? _jsx(Indicator, { color: color }) })), _jsxs("div", { className: s.Content, children: [_jsxs("div", { className: s.Message, children: [title && _jsx("div", { className: s.Title, children: title }), description && _jsx("div", { className: s.Description, children: description })] }), (actions || onDismiss) && (_jsxs("div", { className: clsx(s.Actions, actionsClassName), ref: actionsRef, children: [actions, onDismiss && (_jsx(Button, { type: "button", onClick: onDismiss, color: color, variant: "soft", pill: true, children: "Dismiss" }))] }))] })] }));
|
|
26
26
|
};
|
|
27
27
|
export const Indicator = ({ color }) => {
|
|
28
28
|
// Choose a default icon based on the color (which signals intention)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Alert.js","sourceRoot":"","sources":["../../../../src/components/Alert/Alert.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAA4B,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAsC,MAAM,aAAa,CAAA;AAChE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAClC,OAAO,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"Alert.js","sourceRoot":"","sources":["../../../../src/components/Alert/Alert.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { type ReactNode, type Ref, useEffect, useRef, useState } from \"react\"\nimport { mergeRefs } from \"react-merge-refs\"\nimport { useResizeObserver } from \"usehooks-ts\"\nimport { type SemanticColors, type Variants } from \"../../types\"\nimport { CheckCircle, Info, Warning } from \"../Icon\"\nimport { Button } from \"../Button\"\nimport s from \"@plexui/styles/components/Alert/Alert.module.css\"\n\nexport type AlertProps = {\n /**\n * Color for the button\n * @default primary\n */\n color?: SemanticColors<\n \"primary\" | \"danger\" | \"success\" | \"info\" | \"discovery\" | \"caution\" | \"warning\"\n >\n /**\n * Style variant for the Button\n * @default fill\n */\n variant?: Variants<\"solid\" | \"soft\" | \"outline\">\n /** Title displayed in the alert. */\n title?: ReactNode\n /** Description text displayed in the alert */\n description?: ReactNode\n /** Actions associated with the Alert. */\n actions?: ReactNode\n /** Sets the placement of `actions` always on the end or the bottom. Default behavior is automatic placement based on sizing. */\n actionsPlacement?: \"end\" | \"bottom\"\n /** Optional override for the default indicator of the alert. When `false`, no indicator is shown. */\n indicator?: ReactNode | false\n /** Class applied to the alert container */\n className?: string\n /** Class applied to the actions container */\n actionsClassName?: string\n /** Callback when dismiss button is clicked. Shows dismiss button when provided. */\n onDismiss?: () => void\n /**\n * A full-width strip across the top or bottom of a page or panel (offline,\n * read-only, a new version): square corners and lines above and below only.\n * @default false\n */\n banner?: boolean\n /** Ref applied to the alert container */\n ref?: Ref<HTMLDivElement>\n}\n\nexport const Alert = ({\n color = \"primary\",\n variant = \"outline\",\n title,\n description,\n actions,\n actionsPlacement,\n indicator,\n className,\n actionsClassName,\n onDismiss,\n banner = false,\n ref,\n ...restProps\n}: AlertProps) => {\n const containerRef = useRef<HTMLDivElement>(null)\n const actionsRef = useRef<HTMLDivElement>(null)\n const [actionsAutoPlacement, setActionsAutoPlacement] = useState<\"end\" | \"bottom\">(\"end\")\n // @ts-expect-error -- Type issue in usehooks-ts\n const { width: containerWidth } = useResizeObserver({ ref: containerRef })\n\n useEffect(() => {\n const actionsWidth = actionsRef.current?.clientWidth ?? 0\n\n if (actionsWidth && containerWidth) {\n // If actions are larger than a third of the container width, wrap them.\n const placement = actionsWidth > containerWidth / 3 ? \"bottom\" : \"end\"\n setActionsAutoPlacement(placement)\n }\n }, [containerWidth])\n\n return (\n <div\n ref={mergeRefs([ref, containerRef])}\n className={clsx(s.Alert, className)}\n data-variant={variant}\n data-color={color}\n role={color === \"danger\" ? \"alert\" : undefined}\n data-actions-placement={actionsPlacement ?? actionsAutoPlacement}\n data-banner={banner ? \"\" : undefined}\n {...restProps}\n >\n {indicator === false ? null : (\n <div className={s.Indicator}>{indicator ?? <Indicator color={color} />}</div>\n )}\n <div className={s.Content}>\n <div className={s.Message}>\n {title && <div className={s.Title}>{title}</div>}\n {description && <div className={s.Description}>{description}</div>}\n </div>\n {(actions || onDismiss) && (\n <div className={clsx(s.Actions, actionsClassName)} ref={actionsRef}>\n {actions}\n {onDismiss && (\n <Button type=\"button\" onClick={onDismiss} color={color} variant=\"soft\" pill>\n Dismiss\n </Button>\n )}\n </div>\n )}\n </div>\n </div>\n )\n}\n\nexport const Indicator = ({ color }: { color: AlertProps[\"color\"] }) => {\n // Choose a default icon based on the color (which signals intention)\n switch (color) {\n case \"warning\":\n case \"caution\":\n case \"danger\":\n return <Warning />\n case \"success\":\n return <CheckCircle />\n default:\n return <Info />\n }\n}\n"]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { Alert } from "./Alert";
|
|
1
|
+
export { Alert } from "./Alert.js";
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -3,9 +3,9 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
3
3
|
import { createElement as _createElement } from "react";
|
|
4
4
|
import clsx from "clsx";
|
|
5
5
|
import { useMemo, useState } from "react";
|
|
6
|
-
import { toCssVariables } from "../../lib/helpers";
|
|
7
|
-
import {} from "../../types";
|
|
8
|
-
import s from "
|
|
6
|
+
import { toCssVariables } from "../../lib/helpers.js";
|
|
7
|
+
import {} from "../../types.js";
|
|
8
|
+
import s from "@plexui/styles/components/Avatar/Avatar.module.css";
|
|
9
9
|
export const Avatar = (props) => {
|
|
10
10
|
// Validate the image url before sending to the component
|
|
11
11
|
const validImageUrl = validateImageUrl(props.imageUrl);
|
|
@@ -21,7 +21,7 @@ export const AvatarInner = (props) => {
|
|
|
21
21
|
const TagName = isInteractive ? "button" : "span";
|
|
22
22
|
return (_jsx(TagName, { className: clsx(s.Avatar, className), style: toCssVariables({
|
|
23
23
|
"avatar-size": size,
|
|
24
|
-
}), role: isInteractive ? undefined : "presentation", "data-color": color, "data-variant": variant, type: isInteractive ? "button" : undefined, ...restProps, children: (() => {
|
|
24
|
+
}), role: isInteractive ? undefined : "presentation", "aria-label": isInteractive ? name : undefined, "data-color": color, "data-variant": variant, type: isInteractive ? "button" : undefined, ...restProps, children: (() => {
|
|
25
25
|
// Render a placeholder layer (initials / overflow / icon) behind the
|
|
26
26
|
// image so slow networks never leave the avatar visually empty while
|
|
27
27
|
// the image is loading. The image overlays it once loaded and hides
|
|
@@ -44,7 +44,14 @@ const validateImageUrl = (imageUrl) => {
|
|
|
44
44
|
return imageUrl;
|
|
45
45
|
};
|
|
46
46
|
const AvatarImage = ({ url, status, onLoad, onError, }) => {
|
|
47
|
-
return (_jsx("span", { className: s.AvatarImageContainer, children: _jsx("img", {
|
|
47
|
+
return (_jsx("span", { className: s.AvatarImageContainer, children: _jsx("img", {
|
|
48
|
+
// An image that loaded before hydration fired its load event before
|
|
49
|
+
// React listened for it, and React does not replay it: read the
|
|
50
|
+
// element instead
|
|
51
|
+
ref: (img) => {
|
|
52
|
+
if (img && status !== "loaded" && img.complete && img.naturalWidth > 0)
|
|
53
|
+
onLoad();
|
|
54
|
+
}, src: url, className: s.AvatarImage, "data-loaded": status === "loaded" ? "" : undefined, onLoad: onLoad, onError: onError, alt: "", role: "presentation" }) }));
|
|
48
55
|
};
|
|
49
56
|
const AvatarInitial = ({ name = "" }) => {
|
|
50
57
|
const firstInitial = useMemo(() => name.charAt(0).toUpperCase(), [name]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Avatar.js","sourceRoot":"","sources":["../../../../src/components/Avatar/Avatar.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;;AAEZ,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAsC,MAAM,aAAa,CAAA;AAChE,OAAO,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"Avatar.js","sourceRoot":"","sources":["../../../../src/components/Avatar/Avatar.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { useMemo, useState } from \"react\"\nimport { toCssVariables } from \"../../lib/helpers\"\nimport { type SemanticColors, type Variants } from \"../../types\"\nimport s from \"@plexui/styles/components/Avatar/Avatar.module.css\"\n\ntype ImageStatus = undefined | \"error\" | \"loaded\"\n\nexport type AvatarProps = {\n /** Class name applied to the avatar */\n className?: string\n /** Size of the avatar's width & height, in pixels. */\n size?: number\n /** Display a formatted count of overflow objects. */\n overflowCount?: number\n /** Name used to display initials from */\n name?: string\n /**\n * Color used for the avatar\n * @default secondary\n */\n color?: SemanticColors<\"primary\" | \"secondary\" | \"success\" | \"info\" | \"discovery\" | \"danger\">\n /**\n * Style variant of the avatar\n * @default soft\n */\n variant?: Variants<\"soft\" | \"solid\">\n /** URL of the image to display as the avatar */\n imageUrl?: string\n /** Icon to render in the avatar circle */\n Icon?: React.ComponentType<React.SVGProps<SVGSVGElement>>\n /** Optional click handler, which also enables semantic interactions */\n onClick?: () => void\n /** Optional pointer handler, which also enables semantic interactions */\n onPointerDown?: () => void\n}\n\nexport const Avatar = (props: AvatarProps) => {\n // Validate the image url before sending to the component\n const validImageUrl = validateImageUrl(props.imageUrl)\n\n // Keying off of imageUrl allows us to refresh imageStatus automatically through React rendering\n return <AvatarInner {...props} imageUrl={validImageUrl} key={validImageUrl} />\n}\n\nexport const AvatarInner = (props: AvatarProps) => {\n const {\n className,\n size,\n overflowCount,\n name,\n color = \"secondary\",\n variant = \"soft\",\n imageUrl,\n Icon,\n // asChild support\n ...restProps\n } = props\n const [imageStatus, setImageStatus] = useState<ImageStatus>()\n const isInteractive = !!(restProps.onPointerDown || restProps.onClick)\n const TagName = isInteractive ? \"button\" : \"span\"\n\n return (\n <TagName\n className={clsx(s.Avatar, className)}\n style={toCssVariables({\n \"avatar-size\": size,\n })}\n role={isInteractive ? undefined : \"presentation\"}\n // An interactive avatar is a button; name it by the full name, not the initial\n aria-label={isInteractive ? name : undefined}\n data-color={color}\n data-variant={variant}\n type={isInteractive ? \"button\" : undefined}\n {...restProps}\n >\n {(() => {\n // Render a placeholder layer (initials / overflow / icon) behind the\n // image so slow networks never leave the avatar visually empty while\n // the image is loading. The image overlays it once loaded and hides\n // it when it fails — either way the avatar is never blank.\n const placeholder = overflowCount ? (\n <AvatarOverflowCount count={overflowCount} />\n ) : Icon ? (\n <Icon className={s.AvatarIcon} />\n ) : (\n <AvatarInitial name={name} />\n )\n\n if (imageUrl && imageStatus !== \"error\") {\n return (\n <>\n {placeholder}\n <AvatarImage\n status={imageStatus}\n url={imageUrl}\n onError={() => setImageStatus(\"error\")}\n onLoad={() => setImageStatus(\"loaded\")}\n />\n </>\n )\n }\n return placeholder\n })()}\n </TagName>\n )\n}\n\nconst validateImageUrl = (imageUrl?: string): string | undefined => {\n if (!imageUrl) {\n return\n }\n\n // Avoid specific pattern of images from gravatar.com, which use a pair of initials, instead of a single initial.\n if (imageUrl.includes(\"gravatar.com\") && imageUrl.includes(\"cdn.auth0.com\")) {\n return\n }\n\n return imageUrl\n}\n\nconst AvatarImage = ({\n url,\n status,\n onLoad,\n onError,\n}: {\n url: string\n status: ImageStatus\n onLoad: () => void\n onError: () => void\n}) => {\n return (\n <span className={s.AvatarImageContainer}>\n <img\n // An image that loaded before hydration fired its load event before\n // React listened for it, and React does not replay it: read the\n // element instead\n ref={(img) => {\n if (img && status !== \"loaded\" && img.complete && img.naturalWidth > 0) onLoad()\n }}\n src={url}\n className={s.AvatarImage}\n data-loaded={status === \"loaded\" ? \"\" : undefined}\n onLoad={onLoad}\n onError={onError}\n alt=\"\"\n role=\"presentation\"\n />\n </span>\n )\n}\n\nconst AvatarInitial = ({ name = \"\" }: { name?: string }) => {\n const firstInitial = useMemo(() => name.charAt(0).toUpperCase(), [name])\n\n return <span className={s.AvatarInitial}>{firstInitial}</span>\n}\n\nconst AvatarOverflowCount = ({ count }: { count: number }) => {\n const formattedCount = useMemo<string>(() => {\n return new Intl.NumberFormat(\"en\", {\n notation: \"compact\",\n compactDisplay: \"short\",\n maximumFractionDigits: 0,\n })\n .format(count)\n .toLocaleLowerCase()\n }, [count])\n\n return (\n <span className={s.AvatarOverflowCount} data-letter-count={formattedCount.length}>\n <span className={s.AvatarOverflowCountSymbol}>+</span>\n {formattedCount}\n </span>\n )\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import clsx from "clsx";
|
|
3
3
|
import { Children, cloneElement, isValidElement } from "react";
|
|
4
|
-
import { toCssVariables } from "../../lib/helpers";
|
|
5
|
-
import s from "
|
|
4
|
+
import { toCssVariables } from "../../lib/helpers.js";
|
|
5
|
+
import s from "@plexui/styles/components/Avatar/AvatarGroup.module.css";
|
|
6
6
|
export const AvatarGroup = ({ className, stack = "start", size, children }) => {
|
|
7
7
|
const childrenArray = Children.toArray(children);
|
|
8
8
|
// Conditionally reverse the array depending on desired stacking priority
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AvatarGroup.js","sourceRoot":"","sources":["../../../../src/components/Avatar/AvatarGroup.tsx"],"names":[],"mappings":";AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAkB,MAAM,OAAO,CAAA;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"AvatarGroup.js","sourceRoot":"","sources":["../../../../src/components/Avatar/AvatarGroup.tsx"],"names":[],"mappings":";AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAkB,MAAM,OAAO,CAAA;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,CAAC,MAAM,yDAAyD,CAAA;AAevE,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAAE,SAAS,EAAE,KAAK,GAAG,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAoB,EAAE,EAAE;IAC9F,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAChD,yEAAyE;IACzE,MAAM,qBAAqB,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,aAAa,CAAA;IAEjG,OAAO,CACL,cACE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,gBACvB,KAAK,EACjB,KAAK,EAAE,cAAc,CAAC;YACpB,aAAa,EAAE,IAAI;SACpB,CAAC,YAED,qBAAqB,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GACxF,CACP,CAAA;AACH,CAAC,CAAA","sourcesContent":["import clsx from \"clsx\"\nimport { Children, cloneElement, isValidElement, type ReactNode } from \"react\"\nimport { toCssVariables } from \"../../lib/helpers\"\nimport s from \"@plexui/styles/components/Avatar/AvatarGroup.module.css\"\n\nexport type AvatarGroupProps = {\n /** Class name passed to the group container */\n className?: string\n /**\n * Determines stacking layer order\n * @default start\n */\n stack?: \"start\" | \"end\"\n /** Size all avatars in the group, in pixels. */\n size?: number\n children: ReactNode\n}\n\nexport const AvatarGroup = ({ className, stack = \"start\", size, children }: AvatarGroupProps) => {\n const childrenArray = Children.toArray(children)\n // Conditionally reverse the array depending on desired stacking priority\n const maybeReversedChildren = stack === \"start\" ? childrenArray.slice().reverse() : childrenArray\n\n return (\n <div\n className={clsx(s.Group, className)}\n data-stack={stack}\n style={toCssVariables({\n \"avatar-size\": size,\n })}\n >\n {maybeReversedChildren.map((child) => (isValidElement(child) ? cloneElement(child) : child))}\n </div>\n )\n}\n"]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { Avatar } from "./Avatar";
|
|
2
|
-
export { AvatarGroup } from "./AvatarGroup";
|
|
1
|
+
export { Avatar } from "./Avatar.js";
|
|
2
|
+
export { AvatarGroup } from "./AvatarGroup.js";
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import clsx from "clsx";
|
|
3
3
|
import {} from "react";
|
|
4
|
-
import { wrapTextNodeSiblings } from "../../lib/renderHelpers";
|
|
5
|
-
import {} from "../../types";
|
|
6
|
-
import s from "
|
|
4
|
+
import { wrapTextNodeSiblings } from "../../lib/renderHelpers.js";
|
|
5
|
+
import {} from "../../types.js";
|
|
6
|
+
import s from "@plexui/styles/components/Badge/Badge.module.css";
|
|
7
7
|
export const Badge = ({ children, className, variant = "soft", color = "secondary", size = "sm", pill, ...restMaybeAsChildProps }) => {
|
|
8
8
|
return (_jsx("div", { className: clsx(s.Badge, className), "data-color": color, "data-size": size, "data-pill": pill ? "" : undefined, "data-variant": variant, ...restMaybeAsChildProps, children: wrapTextNodeSiblings(children) }));
|
|
9
9
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/Badge/index.tsx"],"names":[],"mappings":";AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAkB,MAAM,OAAO,CAAA;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,EAAkD,MAAM,aAAa,CAAA;AAC5E,OAAO,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/Badge/index.tsx"],"names":[],"mappings":";AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAkB,MAAM,OAAO,CAAA;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,EAAkD,MAAM,aAAa,CAAA;AAC5E,OAAO,CAAC,MAAM,kDAAkD,CAAA;AAmChE,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,EACpB,QAAQ,EACR,SAAS,EACT,OAAO,GAAG,MAAM,EAChB,KAAK,GAAG,WAAW,EACnB,IAAI,GAAG,IAAI,EACX,IAAI,EACJ,GAAG,qBAAqB,EACb,EAAE,EAAE;IACf,OAAO,CACL,cACE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,gBACvB,KAAK,eACN,IAAI,eACJ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,kBAClB,OAAO,KACjB,qBAAqB,YAExB,oBAAoB,CAAC,QAAQ,CAAC,GAC3B,CACP,CAAA;AACH,CAAC,CAAA","sourcesContent":["import clsx from \"clsx\"\nimport { type ReactNode } from \"react\"\nimport { wrapTextNodeSiblings } from \"../../lib/renderHelpers\"\nimport { type SemanticColors, type Sizes, type Variants } from \"../../types\"\nimport s from \"@plexui/styles/components/Badge/Badge.module.css\"\n\nexport type BadgeProps = {\n /** Content rendered inside the badge */\n children: ReactNode\n /** Class applied to the badge */\n className?: string\n /**\n * Visual style of the badge\n * @default soft\n */\n variant?: Variants<\"solid\" | \"soft\" | \"outline\">\n /**\n * Size scale of the badge\n *\n * | sm | md | lg |\n * | ------- | ------- | ------- |\n * | `20px` | `22px` | `24px` |\n * @default sm\n */\n size?: Sizes<\"sm\" | \"md\" | \"lg\">\n /**\n * Determines if the badge should be a fully rounded pill shape\n * @default false\n */\n pill?: boolean\n /**\n * Color of the badge, related to its meaning or intent\n * @default secondary\n */\n color?: SemanticColors<\n \"secondary\" | \"success\" | \"danger\" | \"warning\" | \"info\" | \"discovery\" | \"caution\"\n >\n}\n\nexport const Badge = ({\n children,\n className,\n variant = \"soft\",\n color = \"secondary\",\n size = \"sm\",\n pill,\n ...restMaybeAsChildProps\n}: BadgeProps) => {\n return (\n <div\n className={clsx(s.Badge, className)}\n data-color={color}\n data-size={size}\n data-pill={pill ? \"\" : undefined}\n data-variant={variant}\n {...restMaybeAsChildProps}\n >\n {wrapTextNodeSiblings(children)}\n </div>\n )\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import { createContext, useContext } from "react";
|
|
5
|
+
import { ChevronRightSm } from "../Icon/index.js";
|
|
6
|
+
import { TextLink } from "../TextLink/index.js";
|
|
7
|
+
import s from "@plexui/styles/components/Breadcrumb/Breadcrumb.module.css";
|
|
8
|
+
const SeparatorContext = createContext(null);
|
|
9
|
+
// TextLink types `to` only for link components that take it; an item passes
|
|
10
|
+
// whichever destination it got through to it
|
|
11
|
+
const ItemLink = TextLink;
|
|
12
|
+
/**
|
|
13
|
+
* The trail of pages that leads to the current one. Each `Breadcrumb.Item`
|
|
14
|
+
* is a link, a button (`onClick`) or the current page (`current`).
|
|
15
|
+
*/
|
|
16
|
+
export const Breadcrumb = ({ children, size = "md", separator, className, "aria-label": ariaLabel = "Breadcrumb", ...restProps }) => {
|
|
17
|
+
return (_jsx("nav", { "aria-label": ariaLabel, className: clsx(s.Breadcrumb, className), "data-size": size, ...restProps, children: _jsx(SeparatorContext.Provider, { value: separator ?? _jsx(ChevronRightSm, {}), children: _jsx("ol", { className: s.List, children: children }) }) }));
|
|
18
|
+
};
|
|
19
|
+
const Item = ({ children, href, to, current = false, onClick, className }) => {
|
|
20
|
+
const separator = useContext(SeparatorContext);
|
|
21
|
+
let content;
|
|
22
|
+
if (current) {
|
|
23
|
+
content = (_jsx("span", { className: s.Current, "aria-current": "page", children: children }));
|
|
24
|
+
}
|
|
25
|
+
else if (href || to || onClick) {
|
|
26
|
+
content = (_jsx(ItemLink, { className: s.Link, href: href, to: to, onClick: onClick, underline: false, children: children }));
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
content = _jsx("span", { children: children });
|
|
30
|
+
}
|
|
31
|
+
return (_jsxs("li", { className: clsx(s.Item, className), children: [_jsx("span", { className: s.Separator, "aria-hidden": "true", children: separator }), content] }));
|
|
32
|
+
};
|
|
33
|
+
Breadcrumb.Item = Item;
|
|
34
|
+
//# sourceMappingURL=Breadcrumb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Breadcrumb.js","sourceRoot":"","sources":["../../../../src/components/Breadcrumb/Breadcrumb.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,aAAa,EAAE,UAAU,EAA2D,MAAM,OAAO,CAAA;AAC1G,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,CAAC,MAAM,4DAA4D,CAAA;AAE1E,MAAM,gBAAgB,GAAG,aAAa,CAAY,IAAI,CAAC,CAAA;AAEvD,4EAA4E;AAC5E,6CAA6C;AAC7C,MAAM,QAAQ,GAAG,QAA6D,CAAA;AAgB9E;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EACzB,QAAQ,EACR,IAAI,GAAG,IAAI,EACX,SAAS,EACT,SAAS,EACT,YAAY,EAAE,SAAS,GAAG,YAAY,EACtC,GAAG,SAAS,EACI,EAAE,EAAE;IACpB,OAAO,CACL,4BAAiB,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,EAAE,SAAS,CAAC,eAAa,IAAI,KAAM,SAAS,YAClG,KAAC,gBAAgB,CAAC,QAAQ,IAAC,KAAK,EAAE,SAAS,IAAI,KAAC,cAAc,KAAG,YAC/D,aAAI,SAAS,EAAE,CAAC,CAAC,IAAI,YAAG,QAAQ,GAAM,GACZ,GACxB,CACP,CAAA;AACH,CAAC,CAAA;AAeD,MAAM,IAAI,GAAG,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,GAAG,KAAK,EAAE,OAAO,EAAE,SAAS,EAAuB,EAAE,EAAE;IAChG,MAAM,SAAS,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAA;IAE9C,IAAI,OAAkB,CAAA;IACtB,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,GAAG,CACR,eAAM,SAAS,EAAE,CAAC,CAAC,OAAO,kBAAe,MAAM,YAC5C,QAAQ,GACJ,CACR,CAAA;IACH,CAAC;SAAM,IAAI,IAAI,IAAI,EAAE,IAAI,OAAO,EAAE,CAAC;QACjC,OAAO,GAAG,CACR,KAAC,QAAQ,IAAC,SAAS,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,YAChF,QAAQ,GACA,CACZ,CAAA;IACH,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,yBAAO,QAAQ,GAAQ,CAAA;IACnC,CAAC;IAED,OAAO,CACL,cAAI,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,aACpC,eAAM,SAAS,EAAE,CAAC,CAAC,SAAS,iBAAc,MAAM,YAC7C,SAAS,GACL,EACN,OAAO,IACL,CACN,CAAA;AACH,CAAC,CAAA;AAED,UAAU,CAAC,IAAI,GAAG,IAAI,CAAA","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport { createContext, useContext, type ComponentProps, type ComponentType, type ReactNode } from \"react\"\nimport { ChevronRightSm } from \"../Icon\"\nimport { TextLink } from \"../TextLink\"\nimport s from \"@plexui/styles/components/Breadcrumb/Breadcrumb.module.css\"\n\nconst SeparatorContext = createContext<ReactNode>(null)\n\n// TextLink types `to` only for link components that take it; an item passes\n// whichever destination it got through to it\nconst ItemLink = TextLink as unknown as ComponentType<Record<string, unknown>>\n\nexport type BreadcrumbProps = Omit<ComponentProps<\"nav\">, \"children\"> & {\n children: ReactNode\n /**\n * Text size: `sm` for a trail above a compact header, `md` above a page title\n * @default md\n */\n size?: \"sm\" | \"md\"\n /**\n * What stands between two items\n * @default a small chevron\n */\n separator?: ReactNode\n}\n\n/**\n * The trail of pages that leads to the current one. Each `Breadcrumb.Item`\n * is a link, a button (`onClick`) or the current page (`current`).\n */\nexport const Breadcrumb = ({\n children,\n size = \"md\",\n separator,\n className,\n \"aria-label\": ariaLabel = \"Breadcrumb\",\n ...restProps\n}: BreadcrumbProps) => {\n return (\n <nav aria-label={ariaLabel} className={clsx(s.Breadcrumb, className)} data-size={size} {...restProps}>\n <SeparatorContext.Provider value={separator ?? <ChevronRightSm />}>\n <ol className={s.List}>{children}</ol>\n </SeparatorContext.Provider>\n </nav>\n )\n}\n\nexport type BreadcrumbItemProps = {\n children: ReactNode\n /** Link destination. Internal paths use the `linkComponent` of `PlexUIProvider` */\n href?: string\n /** Router link destination, for link components that take `to` */\n to?: string\n /** The current page: not a link, marked `aria-current=\"page\"` */\n current?: boolean\n /** Makes an item without a destination act as a button */\n onClick?: (event: React.MouseEvent<HTMLElement>) => void\n className?: string\n}\n\nconst Item = ({ children, href, to, current = false, onClick, className }: BreadcrumbItemProps) => {\n const separator = useContext(SeparatorContext)\n\n let content: ReactNode\n if (current) {\n content = (\n <span className={s.Current} aria-current=\"page\">\n {children}\n </span>\n )\n } else if (href || to || onClick) {\n content = (\n <ItemLink className={s.Link} href={href} to={to} onClick={onClick} underline={false}>\n {children}\n </ItemLink>\n )\n } else {\n content = <span>{children}</span>\n }\n\n return (\n <li className={clsx(s.Item, className)}>\n <span className={s.Separator} aria-hidden=\"true\">\n {separator}\n </span>\n {content}\n </li>\n )\n}\n\nBreadcrumb.Item = Item\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/Breadcrumb/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAkD,MAAM,cAAc,CAAA","sourcesContent":["export { Breadcrumb, type BreadcrumbItemProps, type BreadcrumbProps } from \"./Breadcrumb\"\n"]}
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import clsx from "clsx";
|
|
4
4
|
import { useCallback, } from "react";
|
|
5
|
-
import { handlePressableMouseEnter } from "../../lib/helpers";
|
|
6
|
-
import { wrapTextNodeSiblings } from "../../lib/renderHelpers";
|
|
7
|
-
import {} from "../../types";
|
|
8
|
-
import { LoadingIndicator } from "../Indicator";
|
|
9
|
-
import { useLinkComponent } from "../PlexUIProvider/internal";
|
|
10
|
-
import { TransitionGroup } from "../Transition/TransitionGroup";
|
|
11
|
-
import s from "
|
|
5
|
+
import { handlePressableMouseEnter } from "../../lib/helpers.js";
|
|
6
|
+
import { wrapTextNodeSiblings } from "../../lib/renderHelpers.js";
|
|
7
|
+
import {} from "../../types.js";
|
|
8
|
+
import { LoadingIndicator } from "../Indicator/index.js";
|
|
9
|
+
import { useLinkComponent } from "../PlexUIProvider/internal.js";
|
|
10
|
+
import { TransitionGroup } from "../Transition/TransitionGroup.js";
|
|
11
|
+
import s from "@plexui/styles/components/Button/Button.module.css";
|
|
12
12
|
export const Button = (props) => {
|
|
13
13
|
const { type = "button", color = "primary", variant = "solid", pill = false, uniform = false, size = "md", iconSize, gutterSize, loading, selected, block, opticallyAlign, children, className, onClick, disabled, disabledTone,
|
|
14
14
|
// Defaults to `loading` state
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.js","sourceRoot":"","sources":["../../../../src/components/Button/Button.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAML,WAAW,GACZ,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,EAAoE,MAAM,aAAa,CAAA;AAC9F,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAA;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAC/D,OAAO,CAAC,MAAM,qBAAqB,CAAA;AA+FnC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAkB,EAAE,EAAE;IAC3C,MAAM,EACJ,IAAI,GAAG,QAAQ,EACf,KAAK,GAAG,SAAS,EACjB,OAAO,GAAG,OAAO,EACjB,IAAI,GAAG,KAAK,EACZ,OAAO,GAAG,KAAK,EACf,IAAI,GAAG,IAAI,EACX,QAAQ,EACR,UAAU,EACV,OAAO,EACP,QAAQ,EACR,KAAK,EACL,cAAc,EACd,QAAQ,EACR,SAAS,EACT,OAAO,EACP,QAAQ,EACR,YAAY;IACZ,8BAA8B;IAC9B,KAAK,GAAG,OAAO,EACf,GAAG,SAAS,EACb,GAAG,KAAK,CAAA;IAET,MAAM,OAAO,GAAG,QAAQ,IAAI,KAAK,CAAA;IAEjC,MAAM,WAAW,GAAyC,WAAW,CACnE,CAAC,CAAC,EAAE,EAAE;QACJ,IAAI,QAAQ,EAAE,CAAC;YACb,OAAM;QACR,CAAC;QACD,OAAO,EAAE,CAAC,CAAC,CAAC,CAAA;IACd,CAAC,EACD,CAAC,OAAO,EAAE,QAAQ,CAAC,CACpB,CAAA;IAED,OAAO,CACL,kBACE,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,gBACxB,KAAK,kBACH,OAAO,eACV,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,kBAClB,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,eAC3B,IAAI,sBACG,UAAU,oBACZ,QAAQ,kBACV,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,mBACvB,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,gBAC5B,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,0BACZ,cAAc,EACpC,cAAc,EAAE,yBAAyB;QACzC,qCAAqC;QACrC,0EAA0E;QAC1E,QAAQ,EAAE,OAAO,mBACF,OAAO,EACtB,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,mBAEnB,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,wBACpB,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,EACvD,OAAO,EAAE,WAAW,KAChB,SAAS,aAEb,KAAC,eAAe,IAAC,SAAS,EAAE,CAAC,CAAC,YAAY,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,YAC9E,OAAO,IAAI,KAAC,gBAAgB,MAAK,QAAQ,CAAG,GAC7B,EAClB,eAAM,SAAS,EAAE,CAAC,CAAC,WAAW,YAAG,oBAAoB,CAAC,QAAQ,CAAC,GAAQ,IAChE,CACV,CAAA;AACH,CAAC,CAAA;AAyBD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CACzB,KAMG,EACH,EAAE;IACF,MAAM,EACJ,KAAK,GAAG,SAAS,EACjB,OAAO,GAAG,OAAO,EACjB,IAAI,GAAG,KAAK,EACZ,IAAI,GAAG,IAAI,EACX,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,cAAc,EACd,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,OAAO,EACP,cAAc,EACd,EAAE,EAAE,iBAAiB,EACrB,IAAI,EACJ,EAAE,EACF,GAAG,SAAS,EACb,GAAG,KAAK,CAAA;IAET,MAAM,UAAU,GAAG,QAAQ,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IACpE,MAAM,gBAAgB,GAAG,gBAAgB,EAAE,CAAA;IAC3C,MAAM,aAAa,GAAG,iBAAiB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAA;IAEhF,MAAM,WAAW,GAAG;QAClB,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC;QACtC,QAAQ;QACR,eAAe,EAAE,QAAQ;QACzB,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QACrC,oEAAoE;QACpE,eAAe,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;QAC1C,oBAAoB,EAAE,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS;QACzD,YAAY,EAAE,KAAK;QACnB,cAAc,EAAE,OAAO;QACvB,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;QAClC,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;QACpC,sBAAsB,EAAE,cAAc;QACtC,WAAW,EAAE,IAAI;QACjB,kBAAkB,EAAE,UAAU;QAC9B,gBAAgB,EAAE,QAAQ;QAC1B,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO;QACzC,gBAAgB,EAAE,CAAC,GAA0C,EAAE,EAAE;YAC/D,yBAAyB,CAAC,GAAG,CAAC,CAAA;YAC9B,cAAc,EAAE,CAAC,GAAG,CAAC,CAAA;QACvB,CAAC;KACF,CAAA;IAED,IAAI,QAAQ,EAAE,CAAC;QACb,qFAAqF;QACrF,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CACnC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,MAAM,CAC9B,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,KAAK,KAAK,UAAU,CACtE,CACF,CAAA;QACD,OAAO,CACL,eAAM,IAAI,EAAC,MAAM,KAAK,WAAW,KAAM,UAAU,YAC/C,eAAM,SAAS,EAAE,CAAC,CAAC,WAAW,YAAG,oBAAoB,CAAC,QAAQ,CAAC,GAAQ,GAClE,CACR,CAAA;IACH,CAAC;IAED,MAAM,SAAS,GAAG;QAChB,GAAG,CAAC,UAAU;YACZ,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,qBAAqB,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE;YACpE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACjB,GAAG,WAAW;QACd,GAAG,SAAS;KACb,CAAA;IAED,OAAO,CACL,KAAC,aAAa,OAAK,SAAS,YAC1B,eAAM,SAAS,EAAE,CAAC,CAAC,WAAW,YAAG,oBAAoB,CAAC,QAAQ,CAAC,GAAQ,GACzD,CACjB,CAAA;AACH,CAAC,CAAe,CAAA","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport {\n type ButtonHTMLAttributes,\n type ComponentProps,\n type ComponentType,\n type MouseEventHandler,\n type ReactNode,\n useCallback,\n} from \"react\"\nimport { handlePressableMouseEnter } from \"../../lib/helpers\"\nimport { wrapTextNodeSiblings } from \"../../lib/renderHelpers\"\nimport { type ControlSize, type SemanticColors, type Sizes, type Variants } from \"../../types\"\nimport { LoadingIndicator } from \"../Indicator\"\nimport { useLinkComponent } from \"../PlexUIProvider/internal\"\nimport { TransitionGroup } from \"../Transition/TransitionGroup\"\nimport s from \"./Button.module.css\"\n\ntype CommonProps = {\n /**\n * Color for the button\n * @default secondary\n */\n color: SemanticColors<\n \"primary\" | \"secondary\" | \"danger\" | \"success\" | \"info\" | \"discovery\" | \"caution\" | \"warning\"\n >\n /**\n * Style variant for the Button\n * @default \"solid\"\n */\n variant?: Variants<\"solid\" | \"soft\" | \"outline\" | \"ghost\">\n /**\n * Determines if the button should be a fully rounded pill shape\n * @default false\n */\n pill?: boolean\n /**\n * Disables the button visually and from interactions\n * @default false\n */\n disabled?: boolean\n /**\n * Controls the visual tone when the button is disabled. \"relaxed\" will use a default cursor instead of not-allowed.\n */\n disabledTone?: \"relaxed\"\n /**\n * Determines if the button should take up 100% of available width\n * @default false\n */\n block?: boolean\n /**\n * Applies a negative margin using the current gutter to optically align the button\n * with surrounding content.\n */\n opticallyAlign?: \"start\" | \"end\"\n /**\n * Controls size of the button, specifically height, but also includes defaults for `gutterSize`, `iconSize`, `font-size`, etc.\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n * @default md\n */\n size?: ControlSize\n /**\n * Controls the size of icons within the button, defaults to value from `size`.\n *\n * | xs | sm | md | lg | xl | 2xl |\n * | ------ | ------ | ------ | ------ | ------ | ------ |\n * | `14px` | `16px` | `18px` | `20px` | `22px` | `24px` |\n */\n iconSize?: Sizes<\"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\">\n /**\n * Controls gutter on the edges of the button, defaults to value from `size`.\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl |\n * | ------ | ------ | ------ | ------ | ------ | ------ | ------ |\n * | `4px` | `6px` | `8px` | `10px` | `12px` | `14px` | `16px` |\n */\n gutterSize?: Sizes<\"3xs\" | \"2xs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\">\n /** Custom class applied to the Button element */\n className?: string\n /** Content rendered inside of the Button */\n children: React.ReactNode\n}\n\nexport type ButtonProps = CommonProps & {\n /**\n * Determines if the button should have matching width and height, based on the `size`.\n * @default false\n */\n uniform?: boolean\n /**\n * Displays selected styles on the button, varying by `variant\n * @default false\n */\n selected?: boolean\n /**\n * Displays loading indicator on top of button contents\n * @default false\n */\n loading?: boolean\n /**\n * Determines whether the button should be made inert, without introducing visual change.\n * @default false\n */\n inert?: boolean\n /** Ref for the button */\n ref?: React.Ref<HTMLButtonElement | null>\n} & ButtonHTMLAttributes<HTMLButtonElement>\n\nexport const Button = (props: ButtonProps) => {\n const {\n type = \"button\",\n color = \"primary\",\n variant = \"solid\",\n pill = false,\n uniform = false,\n size = \"md\",\n iconSize,\n gutterSize,\n loading,\n selected,\n block,\n opticallyAlign,\n children,\n className,\n onClick,\n disabled,\n disabledTone,\n // Defaults to `loading` state\n inert = loading,\n ...restProps\n } = props\n\n const isInert = disabled || inert\n\n const handleClick: MouseEventHandler<HTMLButtonElement> = useCallback(\n (e) => {\n if (disabled) {\n return\n }\n onClick?.(e)\n },\n [onClick, disabled],\n )\n\n return (\n <button\n type={type}\n className={clsx(s.Button, className)}\n data-color={color}\n data-variant={variant}\n data-pill={pill ? \"\" : undefined}\n data-uniform={uniform ? \"\" : undefined}\n data-size={size}\n data-gutter-size={gutterSize}\n data-icon-size={iconSize}\n data-loading={loading ? \"\" : undefined}\n data-selected={selected ? \"\" : undefined}\n data-block={block ? \"\" : undefined}\n data-optically-align={opticallyAlign}\n onPointerEnter={handlePressableMouseEnter}\n // Non-visual, accessible disablement\n // NOTE: Do not use literal `inert` because that is incorrect semantically\n disabled={isInert}\n aria-disabled={isInert}\n tabIndex={isInert ? -1 : undefined}\n // Visual disablement\n data-disabled={disabled ? \"\" : undefined}\n data-disabled-tone={disabled ? disabledTone : undefined}\n onClick={handleClick}\n {...restProps}\n >\n <TransitionGroup className={s.ButtonLoader} enterDuration={250} exitDuration={150}>\n {loading && <LoadingIndicator key=\"loader\" />}\n </TransitionGroup>\n <span className={s.ButtonInner}>{wrapTextNodeSiblings(children)}</span>\n </button>\n )\n}\n\ntype ButtonLink = <\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends ComponentType<any> | \"a\" = PlexUI.LinkComponent,\n>(\n props: Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> &\n CommonProps & {\n /**\n * Explicity specify that the link is an external link. This should be\n * automatically detected based on the URL, but in some cases (e.g.\n * my-app://foo) you may want to explicitly set this.\n */\n external?: boolean\n /**\n * Override the default component used for the link. This is useful for\n * using a routing library, or SSR rendering.\n * purposes.\n *\n * @default 'a'\n */\n as?: T\n } & ComponentProps<T>,\n) => ReactNode\n\nexport const ButtonLink = ((\n props: Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> &\n CommonProps & {\n href?: string\n to?: string\n external?: boolean\n as?: PlexUI.LinkComponent\n },\n) => {\n const {\n color = \"primary\",\n variant = \"solid\",\n pill = false,\n size = \"md\",\n gutterSize,\n iconSize,\n external,\n block,\n opticallyAlign,\n children,\n className,\n disabled,\n disabledTone,\n onClick,\n onPointerEnter,\n as: OverrideComponent,\n href,\n to,\n ...restProps\n } = props\n\n const isExternal = external ?? /^https?:\\/\\//.test(href ?? to ?? \"\")\n const DefaultComponent = useLinkComponent()\n const LinkComponent = OverrideComponent || (isExternal ? \"a\" : DefaultComponent)\n\n const sharedProps = {\n \"className\": clsx(s.Button, className),\n disabled,\n \"aria-disabled\": disabled,\n \"tabIndex\": disabled ? -1 : undefined,\n // Visual disablement (inert not supported in links, always applied)\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-disabled-tone\": disabled ? disabledTone : undefined,\n \"data-color\": color,\n \"data-variant\": variant,\n \"data-pill\": pill ? \"\" : undefined,\n \"data-block\": block ? \"\" : undefined,\n \"data-optically-align\": opticallyAlign,\n \"data-size\": size,\n \"data-gutter-size\": gutterSize,\n \"data-icon-size\": iconSize,\n \"onClick\": disabled ? undefined : onClick,\n \"onPointerEnter\": (evt: React.PointerEvent<HTMLAnchorElement>) => {\n handlePressableMouseEnter(evt)\n onPointerEnter?.(evt)\n },\n }\n\n if (disabled) {\n // Don't thread down stuff that isn't valid for a span - just keep the event handlers\n const eventProps = Object.fromEntries(\n Object.entries(restProps).filter(\n ([key, value]) => key.startsWith(\"on\") && typeof value === \"function\",\n ),\n )\n return (\n <span role=\"link\" {...sharedProps} {...eventProps}>\n <span className={s.ButtonInner}>{wrapTextNodeSiblings(children)}</span>\n </span>\n )\n }\n\n const linkProps = {\n ...(isExternal\n ? { target: \"_blank\", rel: \"noopener noreferrer\", href: href ?? to }\n : { href, to }),\n ...sharedProps,\n ...restProps,\n }\n\n return (\n <LinkComponent {...linkProps}>\n <span className={s.ButtonInner}>{wrapTextNodeSiblings(children)}</span>\n </LinkComponent>\n )\n}) as ButtonLink\n"]}
|
|
1
|
+
{"version":3,"file":"Button.js","sourceRoot":"","sources":["../../../../src/components/Button/Button.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\"\n\nimport clsx from \"clsx\"\nimport {\n type ButtonHTMLAttributes,\n type ComponentProps,\n type ComponentType,\n type MouseEventHandler,\n type ReactNode,\n useCallback,\n} from \"react\"\nimport { handlePressableMouseEnter } from \"../../lib/helpers\"\nimport { wrapTextNodeSiblings } from \"../../lib/renderHelpers\"\nimport { type ControlSize, type SemanticColors, type Sizes, type Variants } from \"../../types\"\nimport { LoadingIndicator } from \"../Indicator\"\nimport { useLinkComponent } from \"../PlexUIProvider/internal\"\nimport { TransitionGroup } from \"../Transition/TransitionGroup\"\nimport s from \"@plexui/styles/components/Button/Button.module.css\"\n\ntype CommonProps = {\n /**\n * Color for the button\n * @default primary\n */\n color?: SemanticColors<\n \"primary\" | \"secondary\" | \"danger\" | \"success\" | \"info\" | \"discovery\" | \"caution\" | \"warning\"\n >\n /**\n * Style variant for the Button\n * @default \"solid\"\n */\n variant?: Variants<\"solid\" | \"soft\" | \"outline\" | \"ghost\">\n /**\n * Determines if the button should be a fully rounded pill shape\n * @default false\n */\n pill?: boolean\n /**\n * Disables the button visually and from interactions\n * @default false\n */\n disabled?: boolean\n /**\n * Controls the visual tone when the button is disabled. \"relaxed\" will use a default cursor instead of not-allowed.\n */\n disabledTone?: \"relaxed\"\n /**\n * Determines if the button should take up 100% of available width\n * @default false\n */\n block?: boolean\n /**\n * Applies a negative margin using the current gutter to optically align the button\n * with surrounding content.\n */\n opticallyAlign?: \"start\" | \"end\"\n /**\n * Controls size of the button, specifically height, but also includes defaults for `gutterSize`, `iconSize`, `font-size`, etc.\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl |\n * | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- |\n * | `22px` | `24px` | `26px` | `28px` | `32px` | `36px` | `40px` | `44px` | `48px` |\n * @default md\n */\n size?: ControlSize\n /**\n * Controls the size of icons within the button, defaults to value from `size`.\n *\n * | xs | sm | md | lg | xl | 2xl |\n * | ------ | ------ | ------ | ------ | ------ | ------ |\n * | `14px` | `16px` | `18px` | `20px` | `22px` | `24px` |\n */\n iconSize?: Sizes<\"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\">\n /**\n * Controls gutter on the edges of the button, defaults to value from `size`.\n *\n * | 3xs | 2xs | xs | sm | md | lg | xl |\n * | ------ | ------ | ------ | ------ | ------ | ------ | ------ |\n * | `4px` | `6px` | `8px` | `10px` | `12px` | `14px` | `16px` |\n */\n gutterSize?: Sizes<\"3xs\" | \"2xs\" | \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\">\n /** Custom class applied to the Button element */\n className?: string\n /** Content rendered inside of the Button */\n children: React.ReactNode\n}\n\nexport type ButtonProps = CommonProps & {\n /**\n * Determines if the button should have matching width and height, based on the `size`.\n * @default false\n */\n uniform?: boolean\n /**\n * Displays selected styles on the button, varying by `variant\n * @default false\n */\n selected?: boolean\n /**\n * Displays loading indicator on top of button contents\n * @default false\n */\n loading?: boolean\n /**\n * Determines whether the button should be made inert, without introducing visual change.\n * @default false\n */\n inert?: boolean\n /** Ref for the button */\n ref?: React.Ref<HTMLButtonElement | null>\n} & ButtonHTMLAttributes<HTMLButtonElement>\n\nexport const Button = (props: ButtonProps) => {\n const {\n type = \"button\",\n color = \"primary\",\n variant = \"solid\",\n pill = false,\n uniform = false,\n size = \"md\",\n iconSize,\n gutterSize,\n loading,\n selected,\n block,\n opticallyAlign,\n children,\n className,\n onClick,\n disabled,\n disabledTone,\n // Defaults to `loading` state\n inert = loading,\n ...restProps\n } = props\n\n const isInert = disabled || inert\n\n const handleClick: MouseEventHandler<HTMLButtonElement> = useCallback(\n (e) => {\n if (disabled) {\n return\n }\n onClick?.(e)\n },\n [onClick, disabled],\n )\n\n return (\n <button\n type={type}\n className={clsx(s.Button, className)}\n data-color={color}\n data-variant={variant}\n data-pill={pill ? \"\" : undefined}\n data-uniform={uniform ? \"\" : undefined}\n data-size={size}\n data-gutter-size={gutterSize}\n data-icon-size={iconSize}\n data-loading={loading ? \"\" : undefined}\n data-selected={selected ? \"\" : undefined}\n data-block={block ? \"\" : undefined}\n data-optically-align={opticallyAlign}\n onPointerEnter={handlePressableMouseEnter}\n // Non-visual, accessible disablement\n // NOTE: Do not use literal `inert` because that is incorrect semantically\n disabled={isInert}\n aria-disabled={isInert}\n tabIndex={isInert ? -1 : undefined}\n // Visual disablement\n data-disabled={disabled ? \"\" : undefined}\n data-disabled-tone={disabled ? disabledTone : undefined}\n onClick={handleClick}\n {...restProps}\n >\n <TransitionGroup className={s.ButtonLoader} enterDuration={250} exitDuration={150}>\n {loading && <LoadingIndicator key=\"loader\" />}\n </TransitionGroup>\n <span className={s.ButtonInner}>{wrapTextNodeSiblings(children)}</span>\n </button>\n )\n}\n\ntype ButtonLink = <\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n T extends ComponentType<any> | \"a\" = PlexUI.LinkComponent,\n>(\n props: Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> &\n CommonProps & {\n /**\n * Explicity specify that the link is an external link. This should be\n * automatically detected based on the URL, but in some cases (e.g.\n * my-app://foo) you may want to explicitly set this.\n */\n external?: boolean\n /**\n * Override the default component used for the link. This is useful for\n * using a routing library, or SSR rendering.\n * purposes.\n *\n * @default 'a'\n */\n as?: T\n } & ComponentProps<T>,\n) => ReactNode\n\nexport const ButtonLink = ((\n props: Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, \"href\"> &\n CommonProps & {\n href?: string\n to?: string\n external?: boolean\n as?: PlexUI.LinkComponent\n },\n) => {\n const {\n color = \"primary\",\n variant = \"solid\",\n pill = false,\n size = \"md\",\n gutterSize,\n iconSize,\n external,\n block,\n opticallyAlign,\n children,\n className,\n disabled,\n disabledTone,\n onClick,\n onPointerEnter,\n as: OverrideComponent,\n href,\n to,\n ...restProps\n } = props\n\n const isExternal = external ?? /^https?:\\/\\//.test(href ?? to ?? \"\")\n const DefaultComponent = useLinkComponent()\n const LinkComponent = OverrideComponent || (isExternal ? \"a\" : DefaultComponent)\n\n const sharedProps = {\n \"className\": clsx(s.Button, className),\n disabled,\n \"aria-disabled\": disabled,\n \"tabIndex\": disabled ? -1 : undefined,\n // Visual disablement (inert not supported in links, always applied)\n \"data-disabled\": disabled ? \"\" : undefined,\n \"data-disabled-tone\": disabled ? disabledTone : undefined,\n \"data-color\": color,\n \"data-variant\": variant,\n \"data-pill\": pill ? \"\" : undefined,\n \"data-block\": block ? \"\" : undefined,\n \"data-optically-align\": opticallyAlign,\n \"data-size\": size,\n \"data-gutter-size\": gutterSize,\n \"data-icon-size\": iconSize,\n \"onClick\": disabled ? undefined : onClick,\n \"onPointerEnter\": (evt: React.PointerEvent<HTMLAnchorElement>) => {\n handlePressableMouseEnter(evt)\n onPointerEnter?.(evt)\n },\n }\n\n if (disabled) {\n // Don't thread down stuff that isn't valid for a span - just keep the event handlers\n const eventProps = Object.fromEntries(\n Object.entries(restProps).filter(\n ([key, value]) => key.startsWith(\"on\") && typeof value === \"function\",\n ),\n )\n return (\n <span role=\"link\" {...sharedProps} {...eventProps}>\n <span className={s.ButtonInner}>{wrapTextNodeSiblings(children)}</span>\n </span>\n )\n }\n\n const linkProps = {\n ...(isExternal\n ? { target: \"_blank\", rel: \"noopener noreferrer\", href: href ?? to }\n : { href, to }),\n ...sharedProps,\n ...restProps,\n }\n\n return (\n <LinkComponent {...linkProps}>\n <span className={s.ButtonInner}>{wrapTextNodeSiblings(children)}</span>\n </LinkComponent>\n )\n}) as ButtonLink\n"]}
|