diff --git a/packages/components/card/package.json b/packages/components/card/package.json index b86e33b10..88cf45ee7 100644 --- a/packages/components/card/package.json +++ b/packages/components/card/package.json @@ -42,7 +42,6 @@ "@nextui-org/shared-css": "workspace:*", "@nextui-org/dom-utils": "workspace:*", "@nextui-org/drip": "workspace:*", - "@nextui-org/image": "workspace:*", "@react-aria/focus": "^3.11.0", "@react-aria/utils": "^3.15.0", "@react-aria/interactions": "^3.14.0" diff --git a/packages/components/switch/README.md b/packages/components/switch/README.md new file mode 100644 index 000000000..72c858a74 --- /dev/null +++ b/packages/components/switch/README.md @@ -0,0 +1,24 @@ +# @nextui-org/switch + +A Quick description of the component + +> This is an internal utility, not intended for public usage. + +## Installation + +```sh +yarn add @nextui-org/switch +# or +npm i @nextui-org/switch +``` + +## Contribution + +Yes please! See the +[contributing guidelines](https://github.com/nextui-org/nextui/blob/master/CONTRIBUTING.md) +for details. + +## Licence + +This project is licensed under the terms of the +[MIT license](https://github.com/nextui-org/nextui/blob/master/LICENSE). diff --git a/packages/components/switch/__tests__/switch.test.tsx b/packages/components/switch/__tests__/switch.test.tsx new file mode 100644 index 000000000..51ffbdee3 --- /dev/null +++ b/packages/components/switch/__tests__/switch.test.tsx @@ -0,0 +1,19 @@ +import * as React from "react"; +import {render} from "@testing-library/react"; + +import {Switch} from "../src"; + +describe("Switch", () => { + it("should render correctly", () => { + const wrapper = render(); + + expect(() => wrapper.unmount()).not.toThrow(); + }); + + it("ref should be forwarded", () => { + const ref = React.createRef(); + + render(); + expect(ref.current).not.toBeNull(); + }); +}); diff --git a/packages/components/switch/clean-package.config.json b/packages/components/switch/clean-package.config.json new file mode 100644 index 000000000..8c377bd30 --- /dev/null +++ b/packages/components/switch/clean-package.config.json @@ -0,0 +1,11 @@ +{ + "replace": { + "main": "dist/index.cjs.js", + "module": "dist/index.esm.js", + "types": "dist/index.d.ts", + "exports": { + ".": {"import": "./dist/index.esm.js", "require": "./dist/index.cjs.js"}, + "./package.json": "./package.json" + } + } +} diff --git a/packages/components/switch/package.json b/packages/components/switch/package.json new file mode 100644 index 000000000..2e60fce7e --- /dev/null +++ b/packages/components/switch/package.json @@ -0,0 +1,57 @@ +{ + "name": "@nextui-org/switch", + "version": "2.0.0-beta.1", + "description": "A switch is similar to a checkbox, but represents on/off values as opposed to selection.", + "keywords": [ + "switch" + ], + "author": "Junior Garcia ", + "homepage": "https://nextui.org", + "license": "MIT", + "main": "src/index.ts", + "sideEffects": false, + "files": [ + "dist" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/nextui-org/nextui.git", + "directory": "packages/components/switch" + }, + "bugs": { + "url": "https://github.com/nextui-org/nextui/issues" + }, + "scripts": { + "build": "tsup src --dts", + "build:fast": "tsup src", + "dev": "yarn build:fast -- --watch", + "clean": "rimraf dist .turbo", + "typecheck": "tsc --noEmit", + "prepack": "clean-package", + "postpack": "clean-package restore" + }, + "peerDependencies": { + "react": ">=18" + }, + "dependencies": { + "@nextui-org/system": "workspace:*", + "@nextui-org/theme": "workspace:*", + "@nextui-org/shared-utils": "workspace:*", + "@nextui-org/dom-utils": "workspace:*" + }, + "devDependencies": { + "clean-package": "2.2.0", + "react": "^18.0.0" + }, + "tsup": { + "clean": true, + "target": "es2019", + "format": [ + "cjs", + "esm" + ] + } +} diff --git a/packages/components/switch/src/index.ts b/packages/components/switch/src/index.ts new file mode 100644 index 000000000..8c0ecb522 --- /dev/null +++ b/packages/components/switch/src/index.ts @@ -0,0 +1,10 @@ +import Switch from "./switch"; + +// export types +export type {SwitchProps} from "./switch"; + +// export hooks +export {useSwitch} from "./use-switch"; + +// export component +export {Switch}; diff --git a/packages/components/switch/src/switch.tsx b/packages/components/switch/src/switch.tsx new file mode 100644 index 000000000..272f3daa6 --- /dev/null +++ b/packages/components/switch/src/switch.tsx @@ -0,0 +1,22 @@ +import {forwardRef} from "@nextui-org/system"; +import {__DEV__} from "@nextui-org/shared-utils"; + +import {UseSwitchProps, useSwitch} from "./use-switch"; + +export interface SwitchProps extends Omit {} + +const Switch = forwardRef((props, ref) => { + const {Component, domRef, children, styles, ...otherProps} = useSwitch({ref, ...props}); + + return ( + + {children} + + ); +}); + +if (__DEV__) { + Switch.displayName = "NextUI.Switch"; +} + +export default Switch; diff --git a/packages/components/switch/src/use-switch.ts b/packages/components/switch/src/use-switch.ts new file mode 100644 index 000000000..88641ff16 --- /dev/null +++ b/packages/components/switch/src/use-switch.ts @@ -0,0 +1,37 @@ +import type {ToggleVariantProps} from "@nextui-org/theme"; + +import {HTMLNextUIProps, mapPropsVariants} from "@nextui-org/system"; +import {toggle} from "@nextui-org/theme"; +import {useDOMRef} from "@nextui-org/dom-utils"; +import {ReactRef} from "@nextui-org/shared-utils"; +import {useMemo} from "react"; + +export interface UseSwitchProps extends HTMLNextUIProps<"div">, ToggleVariantProps { + /** + * Ref to the DOM node. + */ + ref?: ReactRef; +} + +export function useSwitch(originalProps: UseSwitchProps) { + const [props, variantProps] = mapPropsVariants(originalProps, toggle.variantKeys); + + const {ref, as, className, ...otherProps} = props; + + const Component = as || "div"; + + const domRef = useDOMRef(ref); + + const styles = useMemo( + () => + toggle({ + ...variantProps, + className, + }), + [...Object.values(variantProps), className], + ); + + return {Component, styles, domRef, ...otherProps}; +} + +export type UseSwitchReturn = ReturnType; diff --git a/packages/components/switch/stories/switch.stories.tsx b/packages/components/switch/stories/switch.stories.tsx new file mode 100644 index 000000000..9df3b543a --- /dev/null +++ b/packages/components/switch/stories/switch.stories.tsx @@ -0,0 +1,46 @@ +import React from "react"; +import {ComponentStory, ComponentMeta} from "@storybook/react"; +import {toggle} from "@nextui-org/theme"; + +import {Switch, SwitchProps} from "../src"; + +export default { + title: "Switch", + component: Switch, + argTypes: { + color: { + control: { + type: "select", + options: ["neutral", "primary", "secondary", "success", "warning", "danger"], + }, + }, + radius: { + control: { + type: "select", + options: ["none", "base", "sm", "md", "lg", "xl", "full"], + }, + }, + size: { + control: { + type: "select", + options: ["xs", "sm", "md", "lg", "xl"], + }, + }, + isDisabled: { + control: { + type: "boolean", + }, + }, + }, +} as ComponentMeta; + +const defaultProps = { + ...toggle.defaultVariants, +}; + +const Template: ComponentStory = (args: SwitchProps) => ; + +export const Default = Template.bind({}); +Default.args = { + ...defaultProps, +}; diff --git a/packages/components/switch/tsconfig.json b/packages/components/switch/tsconfig.json new file mode 100644 index 000000000..1f783ade2 --- /dev/null +++ b/packages/components/switch/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "baseUrl": ".", + "paths": { + "tailwind-variants": ["../../../node_modules/tailwind-variants"] + } + }, + "include": ["src", "index.ts"] +} diff --git a/packages/core/react/package.json b/packages/core/react/package.json index 74c5ad41f..7fc132c60 100644 --- a/packages/core/react/package.json +++ b/packages/core/react/package.json @@ -48,7 +48,6 @@ "@nextui-org/checkbox": "workspace:*", "@nextui-org/code": "workspace:*", "@nextui-org/drip": "workspace:*", - "@nextui-org/image": "workspace:*", "@nextui-org/link": "workspace:*", "@nextui-org/spinner": "workspace:*", "@nextui-org/pagination": "workspace:*", diff --git a/packages/core/theme/src/components/index.ts b/packages/core/theme/src/components/index.ts index b76e80d6a..98ac3ba09 100644 --- a/packages/core/theme/src/components/index.ts +++ b/packages/core/theme/src/components/index.ts @@ -16,3 +16,4 @@ export * from "./checkbox-group"; export * from "./radio"; export * from "./radio-group"; export * from "./pagination"; +export * from "./toggle"; diff --git a/packages/core/theme/src/components/toggle.ts b/packages/core/theme/src/components/toggle.ts new file mode 100644 index 000000000..6ad69bc0a --- /dev/null +++ b/packages/core/theme/src/components/toggle.ts @@ -0,0 +1,25 @@ +import {tv, type VariantProps} from "tailwind-variants"; + +/** + * Toggle (Switch) wrapper **Tailwind Variants** component + * + * const {base, content, dot, avatar, closeButton} = toggle({...}) + * + * @example + *
+ * // left content + * + * + * Default + * close button + * // right content + *
+ */ +const toggle = tv({ + variants: {}, +}); + +export type ToggleVariantProps = VariantProps; +export type ToggleSlots = keyof ReturnType; + +export {toggle}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9ba2f2ec8..24e2db244 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -391,7 +391,6 @@ importers: '@nextui-org/code': workspace:* '@nextui-org/dom-utils': workspace:* '@nextui-org/drip': workspace:* - '@nextui-org/image': workspace:* '@nextui-org/link': workspace:* '@nextui-org/shared-css': workspace:* '@nextui-org/shared-utils': workspace:* @@ -405,7 +404,6 @@ importers: dependencies: '@nextui-org/dom-utils': link:../../utilities/dom-utils '@nextui-org/drip': link:../drip - '@nextui-org/image': link:../image '@nextui-org/shared-css': link:../../utilities/shared-css '@nextui-org/shared-utils': link:../../utilities/shared-utils '@nextui-org/system': link:../../core/system @@ -558,27 +556,6 @@ importers: clean-package: 2.2.0 react: 18.2.0 - packages/components/image: - specifiers: - '@nextui-org/dom-utils': workspace:* - '@nextui-org/shared-utils': workspace:* - '@nextui-org/system': workspace:* - '@nextui-org/use-real-shape': workspace:* - '@nextui-org/use-ref-state': workspace:* - '@nextui-org/use-resize': workspace:* - clean-package: 2.2.0 - react: ^18.2.0 - dependencies: - '@nextui-org/dom-utils': link:../../utilities/dom-utils - '@nextui-org/shared-utils': link:../../utilities/shared-utils - '@nextui-org/system': link:../../core/system - '@nextui-org/use-real-shape': link:../../hooks/use-real-shape - '@nextui-org/use-ref-state': link:../../hooks/use-ref-state - '@nextui-org/use-resize': link:../../hooks/use-resize - devDependencies: - clean-package: 2.2.0 - react: 18.2.0 - packages/components/link: specifiers: '@nextui-org/dom-utils': workspace:* @@ -706,6 +683,23 @@ importers: clean-package: 2.2.0 react: 18.2.0 + packages/components/switch: + specifiers: + '@nextui-org/dom-utils': workspace:* + '@nextui-org/shared-utils': workspace:* + '@nextui-org/system': workspace:* + '@nextui-org/theme': workspace:* + clean-package: 2.2.0 + react: ^18.2.0 + dependencies: + '@nextui-org/dom-utils': link:../../utilities/dom-utils + '@nextui-org/shared-utils': link:../../utilities/shared-utils + '@nextui-org/system': link:../../core/system + '@nextui-org/theme': link:../../core/theme + devDependencies: + clean-package: 2.2.0 + react: 18.2.0 + packages/components/tooltip: specifiers: '@nextui-org/aria-utils': workspace:* @@ -777,7 +771,6 @@ importers: '@nextui-org/checkbox': workspace:* '@nextui-org/code': workspace:* '@nextui-org/drip': workspace:* - '@nextui-org/image': workspace:* '@nextui-org/link': workspace:* '@nextui-org/pagination': workspace:* '@nextui-org/radio': workspace:* @@ -796,7 +789,6 @@ importers: '@nextui-org/checkbox': link:../../components/checkbox '@nextui-org/code': link:../../components/code '@nextui-org/drip': link:../../components/drip - '@nextui-org/image': link:../../components/image '@nextui-org/link': link:../../components/link '@nextui-org/pagination': link:../../components/pagination '@nextui-org/radio': link:../../components/radio