diff --git a/apps/docs/CHANGELOG.md b/apps/docs/CHANGELOG.md index 0fc7594..99fd135 100644 --- a/apps/docs/CHANGELOG.md +++ b/apps/docs/CHANGELOG.md @@ -1,5 +1,14 @@ # @react-elf/docs +## 0.0.92 + +### Patch Changes + +- add ProgressCircle component, ActionGroupContext + +- Updated dependencies []: + - @react-elf/ui@0.0.92 + ## 0.0.91 ### Patch Changes diff --git a/apps/docs/package.json b/apps/docs/package.json index 69ed7b3..4b989bb 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -1,6 +1,6 @@ { "name": "@react-elf/docs", - "version": "0.0.91", + "version": "0.0.92", "private": true, "scripts": { "npm-check": "npx npm-check-updates -u", diff --git a/apps/docs/src/components/Status/ProgressCircle.mdx b/apps/docs/src/components/Status/ProgressCircle.mdx new file mode 100644 index 0000000..72770bb --- /dev/null +++ b/apps/docs/src/components/Status/ProgressCircle.mdx @@ -0,0 +1,100 @@ +import { Controls, Canvas, Meta, Unstyled, Source } from "@storybook/blocks"; +import * as ProgressCircleStories from "./ProgressCircle.stories"; + + + +import { MainView } from "./progresscircle/MainView"; +import { IndeterminateView } from "./progresscircle/IndeterminateView"; +import { SpinView } from "./progresscircle/SpinView"; +import { DefaultVariantView } from "./progresscircle/DefaultVariantView"; +import { OverBackgroundVariantView } from "./progresscircle/OverBackgroundVariantView"; +import { SizeView } from "./progresscircle/SizeView"; +import { MinMaxValueView } from "./progresscircle/MinMaxValueView"; + +# Progress Circle + +Progress circles show the progression of a system operation such as downloading, uploading, processing, etc. in a visual way. They can represent determinate or indeterminate progress. + +## Usage + + + + + + + +## Options + +### Default variant + +Progress circles are used to visually show the progression of a +system operation such as downloading, uploading, processing, etc. By +default, progress circles have a blue fill that shows the progress. + + + + + +### Over background variant + +When a progress circle needs to be placed on top of a colored +background, use the over background variant. This progress circle +uses a static white color regardless of the color theme. Make sure +the background offers enough contrast for the progress circle to be +legible. + + + + + +### Value, min value, max value + +The value is the progress of a system operation (e.g., downloading, +uploading, processing) within the progress circle’s range, from the +min value to max value. + +The min and max values can also be customized appropriately for +whatever the progress circle is showing. By default, the min value +starts at 0 and the max value is set to 100. + +These values are not applicable when a progress circle is +indeterminate. + + + + + +### Size + +Progress circles come in 3 sizes: small, medium (default), or large. +These are available to fit various contexts. For example, the small +progress circle can be used in place of an icon or in tight spaces, +while the large one can be used for full-page loading. + + + + + +### Indeterminate + +A progress circle can be either determinate or indeterminate. By +default, progress circles are determinate. Use a determinate +progress circle when progress can be calculated against a specific +goal (e.g., downloading a file of a known size). Use an +indeterminate progress circle when progress is happening but the +time or effort to completion can’t be determined (e.g., attempting +to reconnect to a server). + + + + + +### spin animation + +When part of the page is waiting for asynchronous data or during a +rendering process, an appropriate loading animation can effectively +alleviate users' inquietude. + + + + diff --git a/apps/docs/src/components/Status/ProgressCircle.stories.tsx b/apps/docs/src/components/Status/ProgressCircle.stories.tsx new file mode 100644 index 0000000..ea7236f --- /dev/null +++ b/apps/docs/src/components/Status/ProgressCircle.stories.tsx @@ -0,0 +1,24 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { ProgressCircle } from "@react-elf/ui"; + +const meta = { + title: "Components/Status/Progress Circle", + component: ProgressCircle, + tags: ["autodocs"], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +/** + * Preview ProgressCircle Story + */ +export const Default: Story = { + args: { + min: 0, + max: 1, + value: 0.5, + size: "large", + variant: "primary", + }, +}; diff --git a/apps/docs/src/components/Status/progresscircle/DefaultVariantView.jsx b/apps/docs/src/components/Status/progresscircle/DefaultVariantView.jsx deleted file mode 100644 index a23b0b6..0000000 --- a/apps/docs/src/components/Status/progresscircle/DefaultVariantView.jsx +++ /dev/null @@ -1,53 +0,0 @@ -import { Grid, ProgressCircle, VBox } from "@elf-framework/ui"; - -export function DefaultVariantView() { - return ( - - -
-
- - - -
-
-
-
-

-

- Progress circles are used to visually show the progression of a - system operation such as downloading, uploading, processing, etc. By - default, progress circles have a blue fill that shows the progress. -

-

-
-
- ); -} diff --git a/apps/docs/src/components/Status/progresscircle/DefaultVariantView.tsx b/apps/docs/src/components/Status/progresscircle/DefaultVariantView.tsx new file mode 100644 index 0000000..45add21 --- /dev/null +++ b/apps/docs/src/components/Status/progresscircle/DefaultVariantView.tsx @@ -0,0 +1,45 @@ +import React from "react"; +import { ProgressCircle, VBox } from "@react-elf/ui"; + +export function DefaultVariantView() { + return ( + +
+
+ + + +
+
+
+ ); +} diff --git a/apps/docs/src/components/Status/progresscircle/DisabledView.jsx b/apps/docs/src/components/Status/progresscircle/DisabledView.jsx deleted file mode 100644 index bd252bb..0000000 --- a/apps/docs/src/components/Status/progresscircle/DisabledView.jsx +++ /dev/null @@ -1,38 +0,0 @@ -import { Badge, Grid, VBox } from "@elf-framework/ui"; - -export function DisabledView() { - return ( - - -
-
- Traveling -
-
-
-
-

- A badge in a disabled state shows that it exists, but is not available - in that circumstance. This can be used to maintain layout continuity - and communicate that a badge may become available later. Badges should - only be able to be disabled if they are interactive. -

-
-
- ); -} diff --git a/apps/docs/src/components/Status/progresscircle/FixedView.jsx b/apps/docs/src/components/Status/progresscircle/FixedView.jsx deleted file mode 100644 index 4662532..0000000 --- a/apps/docs/src/components/Status/progresscircle/FixedView.jsx +++ /dev/null @@ -1,67 +0,0 @@ -import CheckCircleFilled from "@elf-framework/icon/CheckCircleFilled"; -import { Badge, Grid, VBox } from "@elf-framework/ui"; - -import { ucwords } from "~/utils/ucwords"; - -export function FixedView() { - return ( - - -
- {["none", "top", "right", "bottom", "left"].map((placement) => { - return ( -
-
- {ucwords(placement)} -
-
- - Traveling - -
-
- ); - })} -
-
-
-

- Tags have a read-only option for when content in the disabled state - still needs to be shown. This allows for content to be copied, but not - interacted with or changed. -

-
-
- ); -} diff --git a/apps/docs/src/components/Status/progresscircle/IndeterminateView.jsx b/apps/docs/src/components/Status/progresscircle/IndeterminateView.jsx deleted file mode 100644 index 15e07b6..0000000 --- a/apps/docs/src/components/Status/progresscircle/IndeterminateView.jsx +++ /dev/null @@ -1,57 +0,0 @@ -import { Grid, ProgressCircle, VBox } from "@elf-framework/ui"; - -export function IndeterminateView() { - return ( - - -
- -
-
- Determinate -
- -
-
-
- Indeterminate -
- -
-
-
-
-
-

-

- A progress circle can be either determinate or indeterminate. By - default, progress circles are determinate. Use a determinate - progress circle when progress can be calculated against a specific - goal (e.g., downloading a file of a known size). Use an - indeterminate progress circle when progress is happening but the - time or effort to completion can’t be determined (e.g., attempting - to reconnect to a server). -

-

-
-
- ); -} diff --git a/apps/docs/src/components/Status/progresscircle/IndeterminateView.tsx b/apps/docs/src/components/Status/progresscircle/IndeterminateView.tsx new file mode 100644 index 0000000..a4efba9 --- /dev/null +++ b/apps/docs/src/components/Status/progresscircle/IndeterminateView.tsx @@ -0,0 +1,45 @@ +import React from "react"; +import { Grid, ProgressCircle, VBox } from "@react-elf/ui"; + +export function IndeterminateView() { + return ( + +
+ +
+
+ Determinate +
+ +
+
+
+ Indeterminate +
+ +
+
+
+
+ ); +} diff --git a/apps/docs/src/components/Status/progresscircle/MainView.jsx b/apps/docs/src/components/Status/progresscircle/MainView.tsx similarity index 82% rename from apps/docs/src/components/Status/progresscircle/MainView.jsx rename to apps/docs/src/components/Status/progresscircle/MainView.tsx index c0a7c27..3ddf5e4 100644 --- a/apps/docs/src/components/Status/progresscircle/MainView.jsx +++ b/apps/docs/src/components/Status/progresscircle/MainView.tsx @@ -1,4 +1,5 @@ -import { ProgressCircle, VBox } from "@elf-framework/ui"; +import React from "react"; +import { ProgressCircle, VBox } from "@react-elf/ui"; export function MainView() { return ( @@ -6,8 +7,11 @@ export function MainView() { style={{ gap: 30, backgroundColor: "var(--color-gray-0)", - padding: [60, 300], position: "relative", + margin: [0, "auto"], + justifyContent: "center", + height: 200, + alignItems: "center", }} >
- -
-
-
- Example: file upload - -
-
Value: 15
-
Min value: 0
-
Max value: 18
-
- -
- -
-
-
-
- -
-
- Example: filter processing - -
-
Value: 0.92
-
Min value: 0
-
Max value: 1
-
-
- -
-
-
-
-
-
-
-

- The value is the progress of a system operation (e.g., downloading, - uploading, processing) within the progress circle’s range, from the - min value to max value. -

-

- The min and max values can also be customized appropriately for - whatever the progress circle is showing. By default, the min value - starts at 0 and the max value is set to 100. -

-

- These values are not applicable when a progress circle is - indeterminate. -

-
- - ); -} diff --git a/apps/docs/src/components/Status/progresscircle/MinMaxValueView.tsx b/apps/docs/src/components/Status/progresscircle/MinMaxValueView.tsx new file mode 100644 index 0000000..bd57af7 --- /dev/null +++ b/apps/docs/src/components/Status/progresscircle/MinMaxValueView.tsx @@ -0,0 +1,63 @@ +import React from "react"; +import { Grid, ProgressCircle, VBox } from "@react-elf/ui"; + +export function MinMaxValueView() { + return ( + +
+
+
+ Example: file upload + +
+
Value: 15
+
Min value: 0
+
Max value: 18
+
+ +
+ +
+
+
+
+ +
+
+ Example: filter processing + +
+
Value: 0.92
+
Min value: 0
+
Max value: 1
+
+
+ +
+
+
+
+
+
+ ); +} diff --git a/apps/docs/src/components/Status/progresscircle/OverBackgroundVariantView.jsx b/apps/docs/src/components/Status/progresscircle/OverBackgroundVariantView.jsx deleted file mode 100644 index bcb7ef9..0000000 --- a/apps/docs/src/components/Status/progresscircle/OverBackgroundVariantView.jsx +++ /dev/null @@ -1,55 +0,0 @@ -import { Grid, ProgressCircle, VBox } from "@elf-framework/ui"; - -export function OverBackgroundVariantView() { - return ( - - -
-
- - - -
-
-
-
-

-

- When a progress circle needs to be placed on top of a colored - background, use the over background variant. This progress circle - uses a static white color regardless of the color theme. Make sure - the background offers enough contrast for the progress circle to be - legible. -

-

-
-
- ); -} diff --git a/apps/docs/src/components/Status/progresscircle/OverBackgroundVariantView.tsx b/apps/docs/src/components/Status/progresscircle/OverBackgroundVariantView.tsx new file mode 100644 index 0000000..2393ecf --- /dev/null +++ b/apps/docs/src/components/Status/progresscircle/OverBackgroundVariantView.tsx @@ -0,0 +1,45 @@ +import React from "react"; +import { Grid, ProgressCircle, VBox } from "@react-elf/ui"; + +export function OverBackgroundVariantView() { + return ( + +
+
+ + + +
+
+
+ ); +} diff --git a/apps/docs/src/components/Status/progresscircle/SizeView.jsx b/apps/docs/src/components/Status/progresscircle/SizeView.jsx deleted file mode 100644 index be2ad8b..0000000 --- a/apps/docs/src/components/Status/progresscircle/SizeView.jsx +++ /dev/null @@ -1,60 +0,0 @@ -import { Grid, ProgressCircle, VBox } from "@elf-framework/ui"; - -export function SizeView() { - return ( - - -
- {["small", "medium", "large", "extra-large"].map((size) => ( - -
- {size} -
-
- -
-
- ))} -
-
-
-

-

- Progress circles come in 3 sizes: small, medium (default), or large. - These are available to fit various contexts. For example, the small - progress circle can be used in place of an icon or in tight spaces, - while the large one can be used for full-page loading. -

-

-
-
- ); -} diff --git a/apps/docs/src/components/Status/progresscircle/SizeView.tsx b/apps/docs/src/components/Status/progresscircle/SizeView.tsx new file mode 100644 index 0000000..1abafe3 --- /dev/null +++ b/apps/docs/src/components/Status/progresscircle/SizeView.tsx @@ -0,0 +1,52 @@ +import React from "react"; +import { Grid, ProgressCircle, VBox } from "@react-elf/ui"; + +export function SizeView() { + return ( + +
+ {["small", "medium", "large", "extra-large"].map((size) => ( + +
+ {size} +
+
+ +
+
+ ))} +
+
+ ); +} diff --git a/apps/docs/src/components/Status/progresscircle/SpinView.jsx b/apps/docs/src/components/Status/progresscircle/SpinView.jsx deleted file mode 100644 index 47e33bd..0000000 --- a/apps/docs/src/components/Status/progresscircle/SpinView.jsx +++ /dev/null @@ -1,36 +0,0 @@ -import { Animation, Grid, ProgressCircle, VBox } from "@elf-framework/ui"; - -export function SpinView() { - return ( - - -
- - - -
-
-
-

-

- When part of the page is waiting for asynchronous data or during a - rendering process, an appropriate loading animation can effectively - alleviate users' inquietude. -

-

-
-
- ); -} diff --git a/apps/docs/src/components/Status/progresscircle/SpinView.tsx b/apps/docs/src/components/Status/progresscircle/SpinView.tsx new file mode 100644 index 0000000..49d926d --- /dev/null +++ b/apps/docs/src/components/Status/progresscircle/SpinView.tsx @@ -0,0 +1,48 @@ +import React from "react"; +import { + SpinAnimation, + ProgressCircle, + VBox, + Button, + ActionGroup, +} from "@react-elf/ui"; + +export function SpinView() { + const ref = React.useRef(null); + + return ( + +
+ + + + +
+ + + + + +
+
+
+ ); +} diff --git a/apps/docs/src/components/Status/progresscircle/ValueView.jsx b/apps/docs/src/components/Status/progresscircle/ValueView.jsx deleted file mode 100644 index 9919250..0000000 --- a/apps/docs/src/components/Status/progresscircle/ValueView.jsx +++ /dev/null @@ -1,44 +0,0 @@ -import { Button, Grid, ProgressBar, VBox } from "@elf-framework/ui"; - -export function ValueView() { - return ( - - -
-
- } value={33} /> -
-
-
-
-

-

- Progress bars can have a value label that gives detailed information - about the progress (e.g. "60%" or "2 of 8"). This value label works - alongside the label and should not be displayed if the label itself - is not displayed. It should also not be displayed if the progress is - indeterminate. Similar to the label, the value label is always - placed above the track. -

-

-
-
- ); -} diff --git a/apps/docs/src/components/Status/progresscircle/VariantView.jsx b/apps/docs/src/components/Status/progresscircle/VariantView.jsx deleted file mode 100644 index 8ca5249..0000000 --- a/apps/docs/src/components/Status/progresscircle/VariantView.jsx +++ /dev/null @@ -1,73 +0,0 @@ -import { Badge, Grid, VBox } from "@elf-framework/ui"; - -import { ucwords } from "~/utils/ucwords"; - -const variants = [ - "informative", - "neutral", - "positive", - "notice", - "negative", - "indigo", - "celery", - "yellow", - "magenta", - "fuchsia", - "purple", - "seafoam", -]; - -export function VariantView() { - return ( - - -
-
-
- {variants.map((variant) => { - return ( -
- - {ucwords(variant)} - -
- ); - })} -
-
-
-
-
-

-

- When badges have a semantic meaning, they use semantic colors. Use - these variants for the following statuses: -

-

- Variant List -

    - {variants.map((variant) => { - return
  • {variant}
  • ; - })} -
-

-

-
-
- ); -} diff --git a/apps/docs/src/components/Status/progresscircle/WidthView.jsx b/apps/docs/src/components/Status/progresscircle/WidthView.jsx deleted file mode 100644 index a44bb8d..0000000 --- a/apps/docs/src/components/Status/progresscircle/WidthView.jsx +++ /dev/null @@ -1,58 +0,0 @@ -import { Button, Grid, ProgressBar, VBox } from "@elf-framework/ui"; - -export function WidthView() { - return ( - - -
-
- } - value={33} - style={{ - width: 200, - }} - /> -
- -
- } - value={33} - style={{ - width: 240, - }} - /> -
-
-
-
-

-

- The width of a progress bar can be customized appropriately for its - context. The default width is size-2400 (192 px on desktop and 240 - px on mobile). -

-

-
-
- ); -} diff --git a/apps/docs/src/components/actions/ActionGroup.mdx b/apps/docs/src/components/actions/ActionGroup.mdx index 50709bd..0c4e4de 100644 --- a/apps/docs/src/components/actions/ActionGroup.mdx +++ b/apps/docs/src/components/actions/ActionGroup.mdx @@ -35,7 +35,9 @@ An action group can be either horizontal or vertical in its orientation. By default, an action group is horizontal. The vertical option should be reserved for when horizontal space is limited. - + + + @@ -46,7 +48,9 @@ extra-large. The medium size is the default and most frequently used option. Use the other sizes sparingly; they should be used to create a hierarchy of importance within the page. - + + + @@ -56,7 +60,9 @@ Action groups come in 2 densities: regular and compact. The compact density retains the same font and icon sizes, but has tighter spacing. The action buttons also become connected for non-quiet action groups. - + + + @@ -66,7 +72,9 @@ Action groups come in 2 densities: regular and compact. The compact density retains the same font and icon sizes, but has tighter spacing. The action buttons also become connected for non-quiet action groups. - + + + @@ -83,7 +91,9 @@ layout (vertical stack, table, grid) makes it easy to parse the buttons. Too many quiet components in a small space can be hard to read. - + + + @@ -96,7 +106,9 @@ Selection can be enabled for an action group to allow for toggling. This can be used to disclose parts of an interface (e.g., showing or hiding panels) or to switch between views (e.g., grid or list views). - + + +   @@ -107,7 +119,9 @@ hiding panels) or to switch between views (e.g., grid or list views). When selection is enabled, an action group can allow for single or multiple selection of action buttons. - + + +   @@ -121,7 +135,9 @@ group is set to wrap, meaning that the action buttons inside the group wrap to form another line. Alternatively, an action group can be set to collapse inside a More (...) action button. - + + + @@ -132,6 +148,8 @@ within the group exist, but are not available in that circumstance. This state can be used to maintain layout continuity and to communicate that an action group may become available later. - + + + diff --git a/apps/docs/src/components/actions/ActionGroup.stories.tsx b/apps/docs/src/components/actions/ActionGroup.stories.tsx index 59d1f8c..522a15f 100644 --- a/apps/docs/src/components/actions/ActionGroup.stories.tsx +++ b/apps/docs/src/components/actions/ActionGroup.stories.tsx @@ -1,6 +1,6 @@ import React from "react"; import type { Meta, StoryObj } from "@storybook/react"; -import { ActionGroup, Button } from "@react-elf/ui"; +import { ActionGroup, Button, IconWrapper } from "@react-elf/ui"; import { MdContentCopy, MdEdit, MdMore, MdPadding } from "react-icons/md"; const meta = { @@ -17,21 +17,30 @@ type Story = StoryObj; */ export const Default: Story = { args: { + shape: "round", children: ( <> @@ -90,6 +99,7 @@ export const HorizontalQuiet: Story = { export const Vertical: Story = { args: { direction: "vertical", + shape: "round", children: ( <> - - - @@ -187,20 +199,21 @@ export const SizeSmall: Story = { export const SizeLarge: Story = { args: { + size: "large", children: ( <> - - - - @@ -211,20 +224,21 @@ export const SizeLarge: Story = { export const SizeExtraLarge: Story = { args: { + size: "extra-large", children: ( <> - - - - @@ -311,6 +325,7 @@ export const JustifiedCompact: Story = { export const Quiet: Story = { args: { + quiet: true, children: ( <> @@ -360,13 +376,15 @@ export const Selection: Story = { export const MultiSelection: Story = { args: { + compact: true, + value: [1, 2], children: ( <> - - @@ -409,20 +427,21 @@ export const Collapsed: Story = { export const Disabled: Story = { args: { + disabled: true, children: ( <> - - - - diff --git a/apps/docs/src/components/actions/actiongroup/DensityView.tsx b/apps/docs/src/components/actions/actiongroup/DensityView.tsx index 547576f..e00fcc7 100644 --- a/apps/docs/src/components/actions/actiongroup/DensityView.tsx +++ b/apps/docs/src/components/actions/actiongroup/DensityView.tsx @@ -1,17 +1,35 @@ import React from "react"; -import { ActionGroup, Button, Grid, IconButton, VBox } from "@react-elf/ui"; +import { + ActionGroup, + Button, + Grid, + IconButton, + IconWrapper, + VBox, +} from "@react-elf/ui"; import { MdDescription, MdEdit, MdSettings } from "react-icons/md"; export function DensityView() { return ( Regular - + diff --git a/apps/docs/src/components/actions/actiongroup/DisabledView.tsx b/apps/docs/src/components/actions/actiongroup/DisabledView.tsx index 798085c..5dc5a30 100644 --- a/apps/docs/src/components/actions/actiongroup/DisabledView.tsx +++ b/apps/docs/src/components/actions/actiongroup/DisabledView.tsx @@ -9,17 +9,17 @@ export function DisabledView() { >
- Wrap + Disabled
- - - - diff --git a/apps/docs/src/components/actions/actiongroup/EnableSelectionView.tsx b/apps/docs/src/components/actions/actiongroup/EnableSelectionView.tsx index 4cffaa7..384a8bb 100644 --- a/apps/docs/src/components/actions/actiongroup/EnableSelectionView.tsx +++ b/apps/docs/src/components/actions/actiongroup/EnableSelectionView.tsx @@ -12,7 +12,7 @@ export function EnableSelectionView() { Selection not enabled
- @@ -34,8 +34,8 @@ export function EnableSelectionView() {
Selection enabled
- - @@ -43,8 +43,8 @@ export function EnableSelectionView() { Settings - - diff --git a/apps/docs/src/components/actions/actiongroup/JustifiedView.tsx b/apps/docs/src/components/actions/actiongroup/JustifiedView.tsx index 2dd9681..e634a77 100644 --- a/apps/docs/src/components/actions/actiongroup/JustifiedView.tsx +++ b/apps/docs/src/components/actions/actiongroup/JustifiedView.tsx @@ -1,5 +1,11 @@ import React from "react"; -import { ActionGroup, Button, VBox } from "@react-elf/ui"; +import { + ActionGroup, + Button, + IconButton, + IconWrapper, + VBox, +} from "@react-elf/ui"; import { MdContentCopy, MdDescription, @@ -10,44 +16,70 @@ import { export function JustifiedView() { return ( - + Not justified - - - + - + Justified - - + diff --git a/apps/docs/src/components/actions/actiongroup/MultiSelectionView.tsx b/apps/docs/src/components/actions/actiongroup/MultiSelectionView.tsx index 0a5ad62..c12bd4a 100644 --- a/apps/docs/src/components/actions/actiongroup/MultiSelectionView.tsx +++ b/apps/docs/src/components/actions/actiongroup/MultiSelectionView.tsx @@ -11,12 +11,12 @@ export function MultiSelectionView() {
Single Selection
- - - - - + @@ -33,7 +33,11 @@ export function OptionsView() {
Vertical - + + + + + + Small - - - - + Medium - + - + Extra Large - + - - ) : undefined} + + {items} + {hiddenItems.length ? ( + + + + ) : undefined} +
); } diff --git a/packages/@react-elf/button/src/Button.tsx b/packages/@react-elf/button/src/Button.tsx index f8d2f8e..302645e 100644 --- a/packages/@react-elf/button/src/Button.tsx +++ b/packages/@react-elf/button/src/Button.tsx @@ -1,6 +1,13 @@ -import { ButtonProps } from "@react-elf-types/button"; +import React, { createRef, useContext, useMemo } from "react"; +import { + ButtonProps, + ButtonShape, + ButtonSize, + ButtonVariant, +} from "@react-elf-types/button"; import { makeCssVariablePrefixMap, propertyMap } from "@react-elf/shared"; import classnames from "classnames"; +import { ActionGroupContext } from "./context"; const cssProperties = makeCssVariablePrefixMap("--elf--button", { borderColor: true, @@ -16,17 +23,31 @@ const cssProperties = makeCssVariablePrefixMap("--elf--button", { borderRadius: true, }); +interface ButtonItemProps { + variant?: ButtonVariant; + size?: ButtonSize; + disabled?: boolean; + selected?: boolean; + shape?: ButtonShape; + quiet?: boolean; + outline?: boolean; + thin?: boolean; + iconOnly?: boolean; +} + export function Button(props: ButtonProps) { const { - variant = "default", - size = "medium", - disabled = false, + variant, + size, + disabled, selected, + shape, + quiet, + outline, + thin, + iconOnly, + focused, - shape = "none", - quiet = false, - outline = false, - thin = false, closable = false, place = "", style = {}, @@ -34,36 +55,90 @@ export function Button(props: ButtonProps) { target = "_blank", children, className = "", - iconOnly = false, justified = false, pending = false, play = false, hover = false, as = "button", hasMinWidth = false, + noContext = false, + ...extraProps } = props; - const localClass = classnames([ - "elf--button", - { - selected, - outline, + // Only Button + const buttonRef = createRef(); + + // for CheckboxGroup + let groupState = useContext(ActionGroupContext); + + const localProps: ButtonItemProps = {}; + + if (!groupState || noContext) { + localProps.variant = props.variant; + localProps.size = props.size; + localProps.disabled = props.disabled; + localProps.selected = props.selected; + localProps.shape = props.shape; + localProps.quiet = props.quiet; + localProps.outline = props.outline; + localProps.thin = props.thin; + localProps.iconOnly = props.iconOnly; + } else { + localProps.variant = groupState.variant; + localProps.size = groupState.size; + localProps.disabled = groupState.isDisabled; + localProps.selected = groupState.isSelected(props.value); + localProps.shape = groupState.shape; + localProps.quiet = groupState.quiet; + localProps.outline = groupState.outline; + localProps.thin = groupState.thin; + localProps.iconOnly = groupState.iconOnly; + } + + const localClass = useMemo( + () => + classnames([ + "elf--button", + { + selected: localProps.selected || false, + outline: localProps.outline || false, + focused, + quiet: localProps.quiet || false, + closable, + justified, + [localProps.variant || "default"]: true, + [localProps.size || "medium"]: true, + [localProps.shape || "rect"]: true, + [place]: true, + thin: localProps.thin || false, + hover, + "icon-only": localProps.iconOnly, + "has-min-width": hasMinWidth, + }, + className, + ]), + [ + /* context state */ + localProps.selected, + localProps.outline, + localProps.variant, + localProps.size, + localProps.shape, + localProps.thin, + localProps.quiet, + localProps.iconOnly, + + /* props */ focused, - quiet, closable, justified, - [variant]: true, - [size]: true, - [shape]: true, - [place]: true, - thin, + place, hover, - "icon-only": iconOnly, - "has-min-width": hasMinWidth, - }, - className, - ]); + hasMinWidth, + className, + ] + ); const buttonContent = ( @@ -80,7 +155,7 @@ export function Button(props: ButtonProps) { if (as === "link") { const styleObject = { className: localClass, - disabled, + disabled: localProps.disabled || false, style: propertyMap(style, cssProperties), ...extraProps, onClick: undefined, @@ -93,10 +168,14 @@ export function Button(props: ButtonProps) { } else { const styleObject = { className: localClass, - disabled, + disabled: localProps.disabled || false, style: propertyMap(style, cssProperties), ...extraProps, }; - return ; + return ( + + ); } } diff --git a/packages/@react-elf/button/src/IconButton.tsx b/packages/@react-elf/button/src/IconButton.tsx index 4962050..986a3fd 100644 --- a/packages/@react-elf/button/src/IconButton.tsx +++ b/packages/@react-elf/button/src/IconButton.tsx @@ -1,6 +1,12 @@ +import React from "react"; import { ButtonProps } from "@react-elf-types/button"; import { RoundButton } from "./RoundButton"; +import { IconWrapper } from "@react-elf/shared"; -export function IconButton(props: ButtonProps) { - return (); - } \ No newline at end of file +export function IconButton({ children, ...props }: ButtonProps) { + return ( + + {children} + + ); +} diff --git a/packages/@react-elf/button/src/context.tsx b/packages/@react-elf/button/src/context.tsx new file mode 100644 index 0000000..3af357a --- /dev/null +++ b/packages/@react-elf/button/src/context.tsx @@ -0,0 +1,4 @@ +import { createContext } from "react"; +import { ActionGroupState } from "./hooks/useActionGroupState"; + +export const ActionGroupContext = createContext(null); diff --git a/packages/@react-elf/button/src/hooks/useActionGroupState.tsx b/packages/@react-elf/button/src/hooks/useActionGroupState.tsx new file mode 100644 index 0000000..e5e4a5e --- /dev/null +++ b/packages/@react-elf/button/src/hooks/useActionGroupState.tsx @@ -0,0 +1,88 @@ +import { useCallback, useState } from "react"; +import { + ActionGroupProps, + ButtonShape, + ButtonSize, + ButtonValue, + ButtonVariant, +} from "@react-elf-types/button"; + +export interface ActionGroupState { + readonly value: readonly ButtonValue[]; + readonly variant: ButtonVariant; + readonly size: ButtonSize; + readonly isDisabled: boolean; + readonly isReadOnly: boolean; + readonly quiet: boolean; + readonly shape: ButtonShape; + readonly thin: boolean; + readonly outline: boolean; + readonly iconOnly: boolean; + + isSelected(val: any): boolean; + setValue(val: any): void; + toggleValue(val: any): void; + removeValue(val: any): void; +} + +export function useActionGroupState(props: ActionGroupProps): ActionGroupState { + const [selectedValues, setValue] = useState(props.value || []); + + const setStateValue = useCallback( + (value: ButtonValue[], index?: number) => { + setValue(value); + props.onChange?.(value); + }, + [setValue, props.onChange] + ); + + const state = { + value: selectedValues, + variant: props.variant, + size: props.size, + quiet: props.quiet, + shape: props.shape, + thin: props.thin, + outline: props.outline, + isDisabled: props.disabled, + isReadOnly: props.readonly, + iconOnly: props.iconOnly, + setValue: (value) => { + if (props.readonly || props.disabled) { + return; + } + + setStateValue(value); + }, + isSelected: (val: any) => { + return selectedValues?.includes(val); + }, + toggleValue: (val: any) => { + if (props.readonly || props.disabled) { + return; + } + + if (selectedValues.includes(val)) { + setStateValue(selectedValues.filter((v) => v !== val)); + } else { + setStateValue([...selectedValues, val]); + } + }, + removeValue: (val: any) => { + if (props.readonly || props.disabled) { + return; + } + + setStateValue(selectedValues.filter((v) => v !== val)); + }, + addValue: (val: any) => { + if (props.readonly || props.disabled) { + return; + } + + setStateValue([...selectedValues, val]); + }, + }; + + return state; +} diff --git a/packages/@react-elf/color-mixer/CHANGELOG.md b/packages/@react-elf/color-mixer/CHANGELOG.md index d3d9335..61a8373 100644 --- a/packages/@react-elf/color-mixer/CHANGELOG.md +++ b/packages/@react-elf/color-mixer/CHANGELOG.md @@ -1,5 +1,12 @@ # @react-elf/color-mixer +## 0.0.92 + +### Patch Changes + +- Updated dependencies []: + - @react-elf/button@0.0.92 + ## 0.0.88 ### Patch Changes diff --git a/packages/@react-elf/color-mixer/package.json b/packages/@react-elf/color-mixer/package.json index b2354ee..c566715 100644 --- a/packages/@react-elf/color-mixer/package.json +++ b/packages/@react-elf/color-mixer/package.json @@ -1,6 +1,6 @@ { "name": "@react-elf/color-mixer", - "version": "0.0.88", + "version": "0.0.92", "description": "", "files": [ "dist", diff --git a/packages/@react-elf/dialog/CHANGELOG.md b/packages/@react-elf/dialog/CHANGELOG.md index 316c31f..c237397 100644 --- a/packages/@react-elf/dialog/CHANGELOG.md +++ b/packages/@react-elf/dialog/CHANGELOG.md @@ -1,5 +1,13 @@ # @react-elf/dialog +## 0.0.92 + +### Patch Changes + +- Updated dependencies []: + - @react-elf/button@0.0.92 + - @react-elf-types/dialog@0.0.92 + ## 0.0.88 ### Patch Changes diff --git a/packages/@react-elf/dialog/package.json b/packages/@react-elf/dialog/package.json index 69b5d66..093eece 100644 --- a/packages/@react-elf/dialog/package.json +++ b/packages/@react-elf/dialog/package.json @@ -1,6 +1,6 @@ { "name": "@react-elf/dialog", - "version": "0.0.88", + "version": "0.0.92", "description": "", "files": [ "dist", diff --git a/packages/@react-elf/progress-circle/.gitignore b/packages/@react-elf/progress-circle/.gitignore new file mode 100644 index 0000000..12c18d4 --- /dev/null +++ b/packages/@react-elf/progress-circle/.gitignore @@ -0,0 +1 @@ +/lib/ diff --git a/packages/@react-elf/progress-circle/CHANGELOG.md b/packages/@react-elf/progress-circle/CHANGELOG.md new file mode 100644 index 0000000..f9d916f --- /dev/null +++ b/packages/@react-elf/progress-circle/CHANGELOG.md @@ -0,0 +1,19 @@ +# @react-elf/progress-bar + +## 0.0.92 + +### Patch Changes + +- add ProgressCircle component, ActionGroupContext + +- Updated dependencies []: + - @react-elf-types/progress-circle@0.0.92 + +## 0.0.91 + +### Patch Changes + +- add ProgressBar component + +- Updated dependencies []: + - @react-elf-types/progress-bar@0.0.91 diff --git a/packages/@react-elf/progress-circle/index.ts b/packages/@react-elf/progress-circle/index.ts new file mode 100644 index 0000000..3bd16e1 --- /dev/null +++ b/packages/@react-elf/progress-circle/index.ts @@ -0,0 +1 @@ +export * from "./src"; diff --git a/packages/@react-elf/progress-circle/package.json b/packages/@react-elf/progress-circle/package.json new file mode 100644 index 0000000..10ef6d7 --- /dev/null +++ b/packages/@react-elf/progress-circle/package.json @@ -0,0 +1,46 @@ +{ + "name": "@react-elf/progress-circle", + "version": "0.0.92", + "description": "", + "files": [ + "dist", + "README.md", + "package.json" + ], + "main": "./src/index.ts", + "publishConfig": { + "access": "public", + "main": "./dist/index.cjs", + "module": "./dist/index.mjs", + "types": "./dist/types/index.d.ts" + }, + "scripts": { + "npm-check": "npx npm-check-updates -u", + "vite:dist": "vite build --config=vite.dist.config.ts", + "lib:build": "pnpm run vite:dist", + "test": "vitest", + "coverage": "vitest --coverage" + }, + "keywords": [ + "react", + "elf", + "progress circle" + ], + "author": "elf-framework", + "license": "MIT", + "dependencies": { + "@react-elf-types/progress-circle": "workspace:*", + "@react-elf/shared": "workspace:*", + "@types/react": "^18.2.15", + "classnames": "^2.3.2", + "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0" + }, + "devDependencies": { + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^14.0.0", + "vite": "^4.4.6", + "vite-plugin-dts": "^3.3.1", + "vitest": "0.33.0" + } +} diff --git a/packages/@react-elf/progress-circle/src/ProgressCircle.tsx b/packages/@react-elf/progress-circle/src/ProgressCircle.tsx new file mode 100644 index 0000000..ab93b23 --- /dev/null +++ b/packages/@react-elf/progress-circle/src/ProgressCircle.tsx @@ -0,0 +1,73 @@ +import React, { ForwardRefRenderFunction, forwardRef, useMemo } from "react"; +import classNames from "classnames"; + +import { makeCssVariablePrefixMap, propertyMap } from "@react-elf/shared"; +import { ProgressCircleProps } from "@react-elf-types/progress-circle"; + +const cssProperties = makeCssVariablePrefixMap("--elf--progress-circle", { + backgroundColor: true, + color: true, + duration: true, + offset: true, + width: true, +}); + +interface ProgressCircleHandle {} + +const ProgressCircleComp: ForwardRefRenderFunction< + ProgressCircleHandle, + ProgressCircleProps +> = (props, ref) => { + const { + min = 0, + max = 100, + + variant = "default", + size = "medium", + style = {}, + value, + indeterminate = false, + animated = false, + animationType = "normal", + } = props; + + const localClass = useMemo(() => { + return classNames("elf--progress-circle", { + [variant]: true, + [size]: true, + animated, + indeterminate, + [animationType]: true, + }); + }, [variant, size, indeterminate, animated, animationType]); + + const currentValue = typeof value === "number" ? value : min; + const percentValue = (currentValue - min) / (max - min); + + const styleObject = { + className: localClass, + style: propertyMap( + { + ...style, + offset: percentValue, + }, + cssProperties + ), + }; + + return ( +
+
+ + + + +
+
+ ); +}; + +export const ProgressCircle = forwardRef< + ProgressCircleHandle, + ProgressCircleProps +>(ProgressCircleComp); diff --git a/packages/@react-elf/progress-circle/src/index.ts b/packages/@react-elf/progress-circle/src/index.ts new file mode 100644 index 0000000..da15e09 --- /dev/null +++ b/packages/@react-elf/progress-circle/src/index.ts @@ -0,0 +1 @@ +export * from "./ProgressCircle"; diff --git a/packages/@react-elf/progress-circle/test/ProgressCircle.test.tsx b/packages/@react-elf/progress-circle/test/ProgressCircle.test.tsx new file mode 100644 index 0000000..df61e2a --- /dev/null +++ b/packages/@react-elf/progress-circle/test/ProgressCircle.test.tsx @@ -0,0 +1,17 @@ +import { render, screen } from "@testing-library/react"; +import React from "react"; +import { describe, expect, it } from "vitest"; + +import { ProgressCircle } from "../src"; + +describe("ProgressCircle", () => { + it("renders ProgressCircle", () => { + const { container } = render(); + + // screen.debug(container); + + const tooltipEl = container.querySelector(".elf--tooltip"); + + expect(tooltipEl.classList.contains("primary")).toBe(true); + }); +}); diff --git a/packages/@react-elf/progress-circle/test/setup.js b/packages/@react-elf/progress-circle/test/setup.js new file mode 100644 index 0000000..694ae66 --- /dev/null +++ b/packages/@react-elf/progress-circle/test/setup.js @@ -0,0 +1,11 @@ +import matchers from "@testing-library/jest-dom/matchers"; +import { cleanup } from "@testing-library/react"; +import { expect, afterEach } from "vitest"; + +// extends Vitest's expect method with methods from react-testing-library +expect.extend(matchers); + +// runs a cleanup after each test case (e.g. clearing jsdom) +afterEach(() => { + cleanup(); +}); diff --git a/packages/@react-elf/progress-circle/tsconfig.json b/packages/@react-elf/progress-circle/tsconfig.json new file mode 100644 index 0000000..567e608 --- /dev/null +++ b/packages/@react-elf/progress-circle/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + "jsx": "react" + }, + "include": ["src"], + "exclude": [] +} diff --git a/packages/@react-elf/progress-circle/vite.config.js b/packages/@react-elf/progress-circle/vite.config.js new file mode 100644 index 0000000..1f5ed97 --- /dev/null +++ b/packages/@react-elf/progress-circle/vite.config.js @@ -0,0 +1,12 @@ +import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite"; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], + test: { + globals: true, + environment: "jsdom", + setupFiles: "./test/setup.js", + }, +}); diff --git a/packages/@react-elf/progress-circle/vite.dist.config.ts b/packages/@react-elf/progress-circle/vite.dist.config.ts new file mode 100644 index 0000000..f4d82af --- /dev/null +++ b/packages/@react-elf/progress-circle/vite.dist.config.ts @@ -0,0 +1,46 @@ +import { defineConfig } from "vite"; + +import path from "path"; +import dts from "vite-plugin-dts"; + +// https://vitejs.dev/config/ +export default defineConfig({ + css: { + modules: { + localsConvention: "camelCaseOnly", + }, + }, + esbuild: { + keepNames: true, + tsconfigRaw: { + compilerOptions: { + jsx: "react", + }, + }, + }, + build: { + emptyOutDir: false, + minify: false, + lib: { + entry: path.resolve(__dirname, "src/index.ts"), + name: "@react-elf/progress-circle", + fileName: "index", + }, + rollupOptions: { + // make sure to externalize deps that shouldn't be bundled + // into your library + external: ["react", "react-dom", "@react-elf/shared", "classnames"], + output: { + // Provide global variables to use in the UMD build + // for externalized deps + globals: { + react: "React", + "react-dom": "ReactDOM", + "@react-elf/shared": "ReactElfShared", + classnames: "classNames", + }, + }, + }, + }, + plugins: [dts({ outDir: "dist/types" })], +}); diff --git a/packages/@react-elf/toast/CHANGELOG.md b/packages/@react-elf/toast/CHANGELOG.md index 4435be7..f0da22d 100644 --- a/packages/@react-elf/toast/CHANGELOG.md +++ b/packages/@react-elf/toast/CHANGELOG.md @@ -1,5 +1,12 @@ # @react-elf/dialog +## 0.0.92 + +### Patch Changes + +- Updated dependencies []: + - @react-elf/button@0.0.92 + ## 0.0.88 ### Patch Changes diff --git a/packages/@react-elf/toast/package.json b/packages/@react-elf/toast/package.json index 175a140..14c2fcd 100644 --- a/packages/@react-elf/toast/package.json +++ b/packages/@react-elf/toast/package.json @@ -1,6 +1,6 @@ { "name": "@react-elf/toast", - "version": "0.0.88", + "version": "0.0.92", "description": "", "files": [ "dist", diff --git a/packages/@react-elf/ui/CHANGELOG.md b/packages/@react-elf/ui/CHANGELOG.md index 20f39e2..5b38dfb 100644 --- a/packages/@react-elf/ui/CHANGELOG.md +++ b/packages/@react-elf/ui/CHANGELOG.md @@ -1,5 +1,19 @@ # @react-elf/button +## 0.0.92 + +### Patch Changes + +- add ProgressCircle component, ActionGroupContext + +- Updated dependencies []: + - @react-elf/button@0.0.92 + - @react-elf/animation@0.0.92 + - @react-elf/progress-circle@0.0.92 + - @react-elf/color-mixer@0.0.92 + - @react-elf/dialog@0.0.92 + - @react-elf/toast@0.0.92 + ## 0.0.91 ### Patch Changes diff --git a/packages/@react-elf/ui/package.json b/packages/@react-elf/ui/package.json index 6b10bd4..d8c9358 100644 --- a/packages/@react-elf/ui/package.json +++ b/packages/@react-elf/ui/package.json @@ -1,6 +1,6 @@ { "name": "@react-elf/ui", - "version": "0.0.91", + "version": "0.0.92", "description": "", "files": [ "dist", @@ -52,7 +52,9 @@ "@react-elf/input-editor": "workspace:*", "@react-elf/switch": "workspace:*", "@react-elf/slider": "workspace:*", - "@react-elf/progress-bar": "workspace:*" + "@react-elf/progress-bar": "workspace:*", + "@react-elf/progress-circle": "workspace:*", + "@react-elf/animation": "workspace:*" }, "devDependencies": { "@testing-library/jest-dom": "^5.17.0", diff --git a/packages/@react-elf/ui/src/index.ts b/packages/@react-elf/ui/src/index.ts index d485824..dc685d6 100644 --- a/packages/@react-elf/ui/src/index.ts +++ b/packages/@react-elf/ui/src/index.ts @@ -23,3 +23,5 @@ export * from "@react-elf/input-editor"; export * from "@react-elf/switch"; export * from "@react-elf/slider"; export * from "@react-elf/progress-bar"; +export * from "@react-elf/progress-circle"; +export * from "@react-elf/animation"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ff7c4be..a699766 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -153,6 +153,15 @@ importers: specifier: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 version: 18.2.0 + packages/@react-elf-types/animation: + dependencies: + '@react-elf-types/shared': + specifier: workspace:* + version: link:../shared + react: + specifier: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + version: 18.2.0 + packages/@react-elf-types/badge: dependencies: '@react-elf-types/shared': @@ -307,6 +316,15 @@ importers: specifier: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 version: 18.2.0 + packages/@react-elf-types/progress-circle: + dependencies: + '@react-elf-types/shared': + specifier: workspace:* + version: link:../shared + react: + specifier: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + version: 18.2.0 + packages/@react-elf-types/radio: dependencies: '@react-elf-types/shared': @@ -419,6 +437,43 @@ importers: specifier: 0.33.0 version: 0.33.0 + packages/@react-elf/animation: + dependencies: + '@react-elf-types/animation': + specifier: workspace:* + version: link:../../@react-elf-types/animation + '@react-elf/shared': + specifier: workspace:* + version: link:../shared + '@types/react': + specifier: ^18.2.15 + version: 18.2.16 + classnames: + specifier: ^2.3.2 + version: 2.3.2 + react: + specifier: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + version: 18.2.0 + react-dom: + specifier: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + version: 18.2.0(react@18.2.0) + devDependencies: + '@testing-library/jest-dom': + specifier: ^5.17.0 + version: 5.17.0 + '@testing-library/react': + specifier: ^14.0.0 + version: 14.0.0(react-dom@18.2.0)(react@18.2.0) + vite: + specifier: ^4.4.6 + version: 4.4.7(@types/node@20.4.5)(less@4.1.3)(sass@1.64.1) + vite-plugin-dts: + specifier: ^3.3.1 + version: 3.3.1(@types/node@20.4.5)(typescript@5.1.6)(vite@4.4.7) + vitest: + specifier: 0.33.0 + version: 0.33.0 + packages/@react-elf/badge: dependencies: '@react-elf-types/badge': @@ -458,6 +513,9 @@ importers: '@react-elf-types/button': specifier: workspace:* version: link:../../@react-elf-types/button + '@react-elf-types/shared': + specifier: workspace:* + version: link:../../@react-elf-types/shared '@react-elf/shared': specifier: workspace:* version: link:../shared @@ -968,6 +1026,43 @@ importers: specifier: 0.33.0 version: 0.33.0 + packages/@react-elf/progress-circle: + dependencies: + '@react-elf-types/progress-circle': + specifier: workspace:* + version: link:../../@react-elf-types/progress-circle + '@react-elf/shared': + specifier: workspace:* + version: link:../shared + '@types/react': + specifier: ^18.2.15 + version: 18.2.16 + classnames: + specifier: ^2.3.2 + version: 2.3.2 + react: + specifier: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + version: 18.2.0 + react-dom: + specifier: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 + version: 18.2.0(react@18.2.0) + devDependencies: + '@testing-library/jest-dom': + specifier: ^5.17.0 + version: 5.17.0 + '@testing-library/react': + specifier: ^14.0.0 + version: 14.0.0(react-dom@18.2.0)(react@18.2.0) + vite: + specifier: ^4.4.6 + version: 4.4.7(@types/node@20.4.5)(less@4.1.3)(sass@1.64.1) + vite-plugin-dts: + specifier: ^3.3.1 + version: 3.3.1(@types/node@20.4.5)(typescript@5.1.6)(vite@4.4.7) + vitest: + specifier: 0.33.0 + version: 0.33.0 + packages/@react-elf/radio: dependencies: '@react-elf-types/radio': @@ -1278,6 +1373,9 @@ importers: '@react-elf/alert': specifier: workspace:* version: link:../alert + '@react-elf/animation': + specifier: workspace:* + version: link:../animation '@react-elf/badge': specifier: workspace:* version: link:../badge @@ -1323,6 +1421,9 @@ importers: '@react-elf/progress-bar': specifier: workspace:* version: link:../progress-bar + '@react-elf/progress-circle': + specifier: workspace:* + version: link:../progress-circle '@react-elf/radio': specifier: workspace:* version: link:../radio