diff --git a/packages/react/.eslintrc.cjs b/packages/react/.eslintrc.cjs deleted file mode 100644 index 378d7bc5d..000000000 --- a/packages/react/.eslintrc.cjs +++ /dev/null @@ -1,8 +0,0 @@ -/* eslint-env node */ -module.exports = { - extends: ['../../.eslintrc.js', 'plugin:storybook/recommended'], - parserOptions: { - project: './tsconfig.json', - tsconfigRootDir: __dirname, - }, -}; diff --git a/packages/react/.gitignore b/packages/react/.gitignore deleted file mode 100644 index efd3e61da..000000000 --- a/packages/react/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.css -!src/**/*.css diff --git a/packages/react/.storybook/main.ts b/packages/react/.storybook/main.ts deleted file mode 100644 index bae34d0cf..000000000 --- a/packages/react/.storybook/main.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { join, dirname } from 'path'; -import type { StorybookConfig } from '@storybook/react-vite'; - -/** - * This function is used to resolve the absolute path of a package. - * It is needed in projects that use Yarn PnP or are set up within a monorepo. - */ -function getAbsolutePath(value: string) { - return dirname(require.resolve(join(value, 'package.json'))); -} - -const config: StorybookConfig = { - stories: ['../docs/**/*.mdx', '../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'], - addons: [ - getAbsolutePath('@storybook/addon-onboarding'), - getAbsolutePath('@storybook/addon-essentials'), - getAbsolutePath('@chromatic-com/storybook'), - getAbsolutePath('@storybook/addon-interactions'), - getAbsolutePath('@storybook/addon-mdx-gfm'), - ], - framework: { - name: getAbsolutePath('@storybook/react-vite'), - options: {}, - }, - async viteFinal(config) { - // Add your configuration here - config.optimizeDeps = { - exclude: ['node_modules/.cache/sb-vite'], - }; - return config; - }, -}; -export default config; diff --git a/packages/react/.storybook/preview.ts b/packages/react/.storybook/preview.ts deleted file mode 100644 index b7d400751..000000000 --- a/packages/react/.storybook/preview.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Preview } from '@storybook/react'; -import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport'; -import '@utilitywarehouse/fontsource'; -import '@utilitywarehouse/css-reset'; -import '@utilitywarehouse/colour-system/css/colours.css'; -import '../styles.css'; -import '../src/storybook/styles.css'; -import { breakpoints } from '../../web-ui/src/tokens'; - -const customViewports = { - mobile: { - name: 'mobile', - styles: { - width: `${breakpoints.tablet / 2}px`, - height: '100vh', - }, - }, - tablet: { - name: 'tablet', - styles: { - width: `${breakpoints.tablet}px`, - height: '100vh', - }, - }, - desktop: { - name: 'desktop', - styles: { - width: `${breakpoints.desktop}px`, - height: '100vh', - }, - }, - wide: { - name: 'wide', - styles: { - width: `${breakpoints.wide}px`, - height: '100vh', - }, - }, - ...INITIAL_VIEWPORTS, -}; - -const preview: Preview = { - parameters: { - viewport: { - viewports: customViewports, - }, - }, -}; - -export default preview; diff --git a/packages/react/.stylelintrc.cjs b/packages/react/.stylelintrc.cjs deleted file mode 100644 index c7e6bb206..000000000 --- a/packages/react/.stylelintrc.cjs +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = { - extends: 'stylelint-config-standard', - plugins: ['stylelint-media-use-custom-media'], - rules: { - 'csstools/media-use-custom-media': ['known', { importFrom: ['./src/styles/breakpoints.css'] }], - 'at-rule-no-unknown': [true, { ignoreAtRules: ['breakpoints'] }], - // Enforce prefixes on classnames and keyframes - 'selector-class-pattern': /^((mobile|tablet|desktop|wide):)?-?uw-([a-zA-Z\d]|-)+$/, - 'custom-property-pattern': /([a-zA-Z\d]|-)+$/, - 'keyframes-name-pattern': /^uw-([a-z]|-)+$/, - }, -}; diff --git a/packages/react/README.md b/packages/react/README.md deleted file mode 100644 index 2534f0107..000000000 --- a/packages/react/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# React - -[Storybook](https://uw-ds-react.vercel.app) diff --git a/packages/react/docs/media-queries.mdx b/packages/react/docs/media-queries.mdx deleted file mode 100644 index 9de5b14c3..000000000 --- a/packages/react/docs/media-queries.mdx +++ /dev/null @@ -1,99 +0,0 @@ -import { Meta, Unstyled } from '@storybook/blocks'; - -import { BodyText, Flex, Divider } from '../src/components'; -import { media } from '../src/utils/media'; - - - -# Media Queries - -While you should be able to do most things using the responsive style props, if -you need to you can use the `media` object to help create responsive -styles. - -```tsx -import { media } from '@utilitywarehouse/ds-react'; - -[...] - - - {...} - -``` - - - - - - {`media.mobile`} - - - {media.mobile} - - - - - - {`media.tablet`} - - - {media.tablet} - - - - - - {`media.desktop`} - - - {media.desktop} - - - - - - {`media.wide`} - - - {media.wide} - - - - - - - -## Media query helpers - -There are also some media query helper functions available for more specific -media queries. These helpers all take only the breakpoint values as arguments -(`mobile`, `tablet`, `desktop`, `wide`). - -| helper | description | example | query string | -| :-------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------: | :----------------------------------: | -| `media.above` | This function takes a breakpoint key and returns a min-width media query string matching screen widths greater than the screen size given by the breakpoint. This is the same as using the above base media queries. | `media.above("tablet")` | {media.above("tablet")} | -| `media.below` | This function takes a breakpoint key and returns a max-width media query string matching screen widths less than than the screen size given by the breakpoint. | `media.below("wide")` | {media.below("wide")} | -| `media.between` | This function takes a breakpoint key and returns a media query string matching screen widths greater than the given start screen size and less than the given end screen size. | `media.between("tablet", "desktop")` | {media.between("tablet", "desktop")} | -| `media.only` | This function takes a breakpoint key and returns a media query string matching screen widths starting from the given screen size and stopping just before the next breakpoint. | `media.only("tablet")` | {media.only("tablet")} | -| `media.not` | This function takes a breakpoint key and returns a media query string matching screen widths stopping at the given screen size and starting just before the next breakpoint. | `media.not("desktop")` | {media.not("desktop")} | - -## useMediaQuery hook - -This is a custom hook that tracks the state of a media query using the [`Match Media API`](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia). - -We recommend you use it with the `media` object, however you can pass in your own custom media query strings. - -```tsx -import { useMediaQuery, media } from '@utilitywarehouse/ds-react'; - -const isMobileOrTablet = useMediaQuery(media.below('desktop')); -const isDesktop = useMediaQuery(media.above('desktop')); -const isTablet = useMediaQuery(media.between('tablet', 'desktop')); -``` diff --git a/packages/react/package.json b/packages/react/package.json deleted file mode 100644 index a18e05ddb..000000000 --- a/packages/react/package.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "name": "@utilitywarehouse/ds-react", - "version": "0.0.0", - "description": "React components", - "type": "module", - "main": "dist/index.cjs", - "module": "dist/index.js", - "types": "dist/index.d.ts", - "sideEffects": false, - "scripts": { - "clean": "rm -rf .turbo node_modules dist *.css", - "build": "pnpm build:css && pnpm build:js", - "build:css": "postcss ./src/styles/index.css -o styles.css", - "build:js": "NODE_OPTIONS='--max-old-space-size=16384' tsup", - "build:storybook": "storybook build", - "build:storybook:ci": "pnpm build && pnpm build:storybook", - "dev": "pnpm dev:storybook & pnpm dev:css", - "dev:css": "postcss --watch --verbose src/styles/index.css -o styles.css", - "dev:storybook": "storybook dev -p 6006", - "ts-types": "tsc", - "lint": "pnpm lint:js && pnpm lint:css", - "lint:fix": "pnpm lint:js:fix && pnpm lint:css:fix", - "lint:js": "TIMING=1 eslint --max-warnings 0 \"src/**/*.ts*\"", - "lint:js:fix": "TIMING=1 eslint --fix --max-warnings 0 \"src/**/*.ts*\" src", - "lint:css": "stylelint \"src/**/*.css\"", - "lint:css:fix": "stylelint \"src/**/*.css\" --fix", - "format": "prettier --write \"src/**/*.ts*\"", - "format:ci": "prettier --list-different \"src/**/*.ts*\"" - }, - "publishConfig": { - "access": "restricted" - }, - "files": [ - "dist", - "*.css" - ], - "peerDependencies": { - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" - }, - "dependencies": { - "@radix-ui/react-checkbox": "^1.0.4", - "@radix-ui/react-radio-group": "^1.2.1", - "@radix-ui/react-slot": "^1.1.0", - "@radix-ui/react-use-controllable-state": "^1.0.1", - "@utilitywarehouse/react-icons": "^1.11.0", - "clsx": "^2.1.1" - }, - "devDependencies": { - "@chromatic-com/storybook": "^3.2.2", - "@storybook/addon-essentials": "^8.4.2", - "@storybook/addon-interactions": "^8.4.2", - "@storybook/addon-mdx-gfm": "^8.4.5", - "@storybook/addon-onboarding": "^8.4.2", - "@storybook/blocks": "^8.4.2", - "@storybook/react": "^8.4.2", - "@storybook/react-vite": "^8.4.2", - "@storybook/test": "^8.4.2", - "@types/node": "^22.9.0", - "@types/react": "^18.3.12", - "@utilitywarehouse/colour-system": "^0.5.0", - "@utilitywarehouse/css-reset": "^0.1.0", - "@utilitywarehouse/fontsource": "^0.1.0", - "autoprefixer": "^10.4.20", - "cssnano": "^7.0.6", - "eslint-plugin-storybook": "^0.11.0", - "postcss": "^8.4.49", - "postcss-cli": "^11.0.0", - "postcss-custom-media": "^11.0.5", - "postcss-import": "^16.1.0", - "postcss-nesting": "^13.0.1", - "prop-types": "^15.8.1", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0", - "storybook": "^8.4.2", - "stylelint": "^16.10.0", - "stylelint-config-standard": "^36.0.1", - "stylelint-media-use-custom-media": "^4.0.0", - "tsup": "^8.3.5" - } -} diff --git a/packages/react/postcss-breakpoints.cjs b/packages/react/postcss-breakpoints.cjs deleted file mode 100644 index 00fc09182..000000000 --- a/packages/react/postcss-breakpoints.cjs +++ /dev/null @@ -1,133 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const postcss = require('postcss'); - -/** - * - * Many thanks to Radix for blazing the trail: https://github.com/radix-ui/themes/blob/main/packages/radix-ui-themes/postcss-breakpoints.cjs - * - */ - -// Build a list of breakpoints from "@custom media" rules in "breakpoints.css" -const breakpointsFile = path.resolve('./src/styles/breakpoints.css'); -const breakpointsCss = fs.readFileSync(breakpointsFile, 'utf-8'); -const breakpoints = postcss - .parse(breakpointsCss) - .nodes.map(node => { - if (node.type === 'atrule' && node.name === 'custom-media') { - const [_match, name, params] = node.params.match(/--(\w+)\s+(.+)/); - return { name, params }; - } - - return null; - }) - .filter(Boolean); - -const cache = new WeakMap(); - -module.exports = () => ({ - postcssPlugin: 'postcss-breakpoints', - Rule(rule) { - if (rule.parent.name === 'breakpoints') { - const breakpointsRule = rule.parent; - - // when we first meet a given @breakpoints at-rule - if (!cache.has(breakpointsRule)) { - // create the final media rules for this @breakpoints at-rule - const medias = breakpoints.reduce((breakpointsMedias, breakpoint) => { - breakpointsMedias[breakpoint.name] = new postcss.AtRule({ - name: 'media', - params: breakpoint.params, - }); - return breakpointsMedias; - }, {}); - - // add an entry to the cache - cache.set(breakpointsRule, medias); - - // add final media rules after the @breakpoints at-rule - const mediaRules = Object.values(medias).reverse(); - mediaRules.forEach(media => { - breakpointsRule.after(media); - }); - } - - // move the rule itself before @breakpoints at-rule - breakpointsRule.before(rule); - - // save clone of the rule before we modify it - const originalRule = rule.clone(); - // clean up the extra indentation - rule.selector = rule.selector.replace(/\n\s\s/g, '\n'); - rule.cleanRaws(); - - // add breakpoint-level rules - breakpoints.forEach(breakpoint => { - const clone = originalRule.clone(); - updateClass(clone, breakpoint.name); - cache.get(breakpointsRule)[breakpoint.name].append(clone); - }); - - // remove @breakpoints at-rule and clear cache if it has no rules - if (breakpointsRule.nodes.length === 0) { - breakpointsRule.remove(); - cache.delete(breakpointsRule); - } - } - }, -}); - -module.exports.postcss = true; - -function updateClass(node, prefix) { - if (node.type === 'atrule') { - node.each(child => updateClass(child, prefix)); - } - - /** - * Should match responsive classes (uw-r- prefix): - * ``` - * .uw-r-size-1 - * .uw-r-m-2 - * .-uw-r-m-2 - * .uw-Button.uw-r-size-1 (captures "uw-r-size-1") - * ``` - * - * Should not match: - * .uw-Button - */ - const classNameRegexp = /\.(-?uw-r-[a-z0-9-]+)/g; - - // Check for rules that use compound props on a component: - // - a component name (prefixed with "rt-" and pascal cased) - // - followed by 2 or more prop selectors (lowercase, numbers, -) - // - // e.g. ".rt-DialogContent.rt-r-size-2.gray" - if (/\.uw-(?:[A-Z][a-z]+)+(?:\.[a-z0-9-]+){2,}/.test(node.selector)) { - throw Error(` - "${node.selector}" looks like it uses compound props on a component. - "@breakpoints" does not support compound props yet. - `); - } - - if (classNameRegexp.test(node.selector)) { - node.selector = node.selector.replace(classNameRegexp, `.${prefix}\\:$1`); - } - - addPropertySuffixes(node, prefix); -} - -function addPropertySuffixes(propertyNode, suffix) { - propertyNode.nodes.map(node => { - /** - * Should match custom properties with responsive --r prefix: - * ``` - * --r-padding - * ``` - */ - const propertyNameRegexp = /(--r-[a-z0-9-]+)/g; - if (propertyNameRegexp.test(node.value)) { - node.value = node.value.replace(propertyNameRegexp, `$1-${suffix}`); - } - }); -} diff --git a/packages/react/postcss.config.cjs b/packages/react/postcss.config.cjs deleted file mode 100644 index 995cd1dd3..000000000 --- a/packages/react/postcss.config.cjs +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = { - plugins: [ - require('postcss-import'), - require('postcss-nesting'), - require('./postcss-breakpoints.cjs'), - require('postcss-custom-media'), - require('autoprefixer'), - // require('cssnano')({ - // preset: 'default', - // }), - ], -}; diff --git a/packages/react/src/components/Alert/Alert.css b/packages/react/src/components/Alert/Alert.css deleted file mode 100644 index 012fc3b05..000000000 --- a/packages/react/src/components/Alert/Alert.css +++ /dev/null @@ -1,103 +0,0 @@ -.uw-Alert { - flex-direction: row; - gap: var(--space-100); - padding: var(--space-200); - border-radius: 8px; - border-width: 1px; - border-style: solid; - border-color: var(--alert-border-color); - background-color: var(--alert-background-color); - color: var(--alert-text-color); - - &:where(:focus-visible) { - outline: none; - border-radius: 4px; - box-shadow: 0 0 0 2px var(--alert-focus-color); - } - - > :where(svg, [data-icon]) { - color: var(--alert-icon-color); - } - - &:where([data-colorscheme='cyan']) { - --alert-text-color: var(--color-cyan900); - --alert-background-color: var(--color-cyan50); - --alert-icon-color: var(--color-cyan700); - --alert-border-color: var(--color-cyan500); - } - - &:where([data-colorscheme='green']) { - --alert-text-color: var(--color-green900); - --alert-background-color: var(--color-green50); - --alert-icon-color: var(--color-green700); - --alert-border-color: var(--color-green500); - } - - &:where([data-colorscheme='gold']) { - --alert-text-color: var(--color-gold900); - --alert-background-color: var(--color-gold50); - --alert-icon-color: var(--color-gold700); - --alert-border-color: var(--color-gold500); - } - - &:where([data-colorscheme='red']) { - --alert-text-color: var(--color-red900); - --alert-background-color: var(--color-red50); - --alert-icon-color: var(--color-red700); - --alert-border-color: var(--color-red500); - } - - .uw-IconButton { - height: auto; - width: auto; - - &:where(:active) { - background-color: transparent; - } - } -} - -.uw-AlertLink { - font-weight: var(--font-weight-semibold); - color: var(--alert-link-color); - text-decoration-color: var(--alert-link-color); - - &:where(:visited) { - color: var(--alert-link-color); - text-decoration-color: var(--alert-link-color); /* TODO: do we need this? */ - } - - &:where([data-colorscheme='cyan'] &) { - --alert-link-color: var(--color-cyan700); - --alert-focus-color: var(--color-cyan700); - } - - &:where([data-colorscheme='green'] &) { - --alert-link-color: var(--color-green700); - --alert-focus-color: var(--color-green700); - } - - &:where([data-colorscheme='gold'] &) { - --alert-link-color: var(--color-gold700); - --alert-focus-color: var(--color-gold700); - } - - &:where([data-colorscheme='red'] &) { - --alert-link-color: var(--color-red700); - --alert-focus-color: var(--color-red700); - } -} - -.uw-AlertButton { - color: var(--alert-button-color); - - @media (hover: hover) { - &:where(:hover) { - color: var(--alert-button-color-hover); - } - } -} - -.uw-AlertTitle { - color: var(--alert-text-color); -} diff --git a/packages/react/src/components/Alert/Alert.props.ts b/packages/react/src/components/Alert/Alert.props.ts deleted file mode 100644 index 7f392d1ec..000000000 --- a/packages/react/src/components/Alert/Alert.props.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; - -export interface AlertProps extends ComponentPropsWithout<'div', RemovedProps> { - /** - * Sets the colour scheme. - * @default cyan - */ - colorScheme?: 'cyan' | 'green' | 'gold' | 'red'; - /** - * Sets the function to be called when the alert is closed. - */ - onClose?: () => void; - /** - * Sets the direction of the alert content. - * @default column - */ - direction?: 'row' | 'column'; - /** - * Sets the title of the alert. - */ - title?: string; - /** - * Sets the text of the alert. - */ - text?: React.ReactNode; - /** - * Sets the link text of the alert. - */ - linkText?: string; - /** - * Sets the link href of the alert. - */ - linkHref?: string; -} diff --git a/packages/react/src/components/Alert/Alert.stories.tsx b/packages/react/src/components/Alert/Alert.stories.tsx deleted file mode 100644 index 4d02c4255..000000000 --- a/packages/react/src/components/Alert/Alert.stories.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { Alert } from './Alert'; -import { Flex } from '../Flex/Flex'; -import { Button } from '../Button/Button'; -import { AlertText } from './AlertText'; -import { Strong } from '../Strong/Strong'; - -const colorSchemes = ['cyan', 'red', 'green', 'gold'] as const; - -const meta: Meta = { - title: 'Stories / Alert', - component: Alert, - argTypes: { - children: { control: { type: 'text' } }, - colorScheme: { options: colorSchemes, control: { type: 'radio' } }, - direction: { options: ['column', 'row'], control: { type: 'radio' } }, - }, - args: { - title: 'Did you know?', - text: 'The quick brown fox jumps over the lazy dog.', - linkText: 'Learn more', - linkHref: '#', - }, -}; - -export default meta; -type Story = StoryObj; - -export const KitchenSink: Story = { - parameters: { controls: { hideNoControlsWarning: true } }, - render: args => { - return ( - - {colorSchemes.map(colorScheme => ( - - - - alert('closed')} - /> - alert('closed')} - /> - - - - ))} - - ); - }, -}; - -export const Workshop: Story = {}; - -export const ToggleAlert: Story = { - parameters: { layout: 'none' }, - render: () => { - const [open, setOpen] = React.useState(false); - const handleOpen = () => setOpen(true); - const handleClose = () => setOpen(false); - - return ( - - - {open ? ( - - ) : null} - - ); - }, -}; - -export const AlertColorSchemes: Story = { - name: 'Alert ColorSchemes', - render: () => { - return ( - - - - - - - ); - }, -}; - -export const AlertAdvancedUsage: Story = { - render: () => { - return ( - - - Are you sure you want to do this? - - } - linkHref="#" - linkText="Delete" - onClose={() => {}} - direction="row" - /> - - ); - }, -}; diff --git a/packages/react/src/components/Alert/Alert.tsx b/packages/react/src/components/Alert/Alert.tsx deleted file mode 100644 index 6be0ce401..000000000 --- a/packages/react/src/components/Alert/Alert.tsx +++ /dev/null @@ -1,115 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { - ChevronRightMediumIcon, - CloseMediumIcon, - InformationMediumContainedIcon, - TickMediumContainedIcon, - WarningMediumContainedIcon, -} from '@utilitywarehouse/react-icons'; - -import { AlertProps } from './Alert.props'; -import { AlertLink } from './AlertLink'; -import { AlertText } from './AlertText'; -import { AlertTitle } from './AlertTitle'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import { ElementRef } from 'react'; -import { DATA_ATTRIBUTES } from '../../helpers/data-attributes'; -import { Flex } from '../Flex/Flex'; -import { IconButton } from '../IconButton/IconButton'; - -const componentName = 'Alert'; -const componentClassName = withGlobalPrefix(componentName); - -type AlertElement = ElementRef<'div'>; - -/** - * Provide feedback messages to users. Alerts are dynamic content that is - * injected into the page when it changes and should be used sparingly. - */ -export const Alert = React.forwardRef( - ( - { - className, - colorScheme = 'cyan', - direction = 'column', - children, - onClose, - title, - text, - linkText, - linkHref, - ...props - }, - ref - ) => { - const icons = { - cyan: InformationMediumContainedIcon, - green: TickMediumContainedIcon, - gold: WarningMediumContainedIcon, - red: WarningMediumContainedIcon, - }; - const AlertIcon = icons[colorScheme]; - const dataAttributeProps = { - [DATA_ATTRIBUTES.colorscheme]: colorScheme, - 'data-direction': direction, - }; - return ( - - - - - {children ?? ( - <> - {title ? {title} : null} - {text ? {text} : null} - {linkText && linkHref ? {linkText} : null} - - )} - - {linkHref && !linkText ? ( - - - - - - ) : null} - {onClose ? ( - - - - ) : null} - - ); - } -); - -Alert.displayName = componentName; diff --git a/packages/react/src/components/Alert/AlertLink.tsx b/packages/react/src/components/Alert/AlertLink.tsx deleted file mode 100644 index 25667d487..000000000 --- a/packages/react/src/components/Alert/AlertLink.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import type { ElementRef } from 'react'; -import type { TextLinkProps } from '../TextLink/TextLink.props'; -import { TextLink } from '../TextLink/TextLink'; - -const componentName = 'AlertLink'; -const componentClassName = withGlobalPrefix(componentName); - -type AlertLinkElement = ElementRef<'a'>; -type AlertLinkProps = TextLinkProps; - -/** - * An `AlertLink` is a component that is used to display the link of an `Alert`. - */ -export const AlertLink = React.forwardRef( - ({ className, ...props }, ref) => ( - - ) -); - -AlertLink.displayName = componentName; diff --git a/packages/react/src/components/Alert/AlertText.tsx b/packages/react/src/components/Alert/AlertText.tsx deleted file mode 100644 index 475f44af5..000000000 --- a/packages/react/src/components/Alert/AlertText.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import type { ElementRef } from 'react'; -import type { BodyTextProps } from '../BodyText/BodyText.props'; -import { BodyText } from '../BodyText/BodyText'; - -const componentName = 'AlertText'; -const componentClassName = withGlobalPrefix(componentName); - -type AlertTextElement = ElementRef<'h2'>; -type AlertTextProps = BodyTextProps; - -/** - * An `AlertText` is a component that is used to display the text of an `Alert`. - */ -export const AlertText = React.forwardRef( - ({ className, ...props }, ref) => ( - - ) -); - -AlertText.displayName = componentName; diff --git a/packages/react/src/components/Alert/AlertTitle.tsx b/packages/react/src/components/Alert/AlertTitle.tsx deleted file mode 100644 index df1eb4606..000000000 --- a/packages/react/src/components/Alert/AlertTitle.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import type { ElementRef } from 'react'; -import type { BodyTextProps } from '../BodyText/BodyText.props'; -import { BodyText } from '../BodyText/BodyText'; - -const componentName = 'AlertTitle'; -const componentClassName = withGlobalPrefix(componentName); - -type AlertTitleElement = ElementRef<'h2'>; -type AlertTitleProps = BodyTextProps; - -/** - * An `AlertTitle` is a component that is used to display the title of an `Alert`. - */ -export const AlertTitle = React.forwardRef( - ({ className, children, ...props }, ref) => ( - -

{children}

-
- ) -); - -AlertTitle.displayName = componentName; diff --git a/packages/react/src/components/Badge/Badge.css b/packages/react/src/components/Badge/Badge.css deleted file mode 100644 index 473df3bec..000000000 --- a/packages/react/src/components/Badge/Badge.css +++ /dev/null @@ -1,108 +0,0 @@ -.uw-Badge { - display: inline-flex; - gap: var(--space-50); - align-items: center; - white-space: nowrap; - font-size: var(--font-size-body-sm); - font-family: var(--font-family-body); - font-weight: var(--font-weight-regular); - font-style: normal; - flex-shrink: 0; - line-height: var(--line-height-md); - text-align: center; - - /* Make sure that the height is not stretched in a Flex/Grid layout */ - height: fit-content; - border-radius: 4px; - color: var(--badge-color); - background-color: var(--badge-background-color); - padding-block: var(--space-50); - - @breakpoints { - &:where(.uw-r-size-medium) { - padding-inline: var(--space-200); - } - - &:where(.uw-r-size-small) { - padding-inline: var(--space-100); - } - } - - &:where([data-bottom-radius-zero]) { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - } - - &:where(.uw-variant-soft) { - --badge-color: var(--badge-soft-color); - --badge-background-color: var(--badge-soft-background-color); - } - - &:where(.uw-variant-strong) { - --badge-color: var(--badge-strong-color); - --badge-background-color: var(--badge-strong-background-color); - } - - &:where(.uw-variant-outline) { - --badge-color: var(--badge-outline-color); - --badge-background-color: transparent; - --badge-border-color: var(--badge-outline-border-color); - - box-shadow: inset 0 0 0 2px var(--badge-border-color); - } - - &:where([data-colorscheme='cyan']) { - --badge-soft-color: var(--color-cyan900); - --badge-soft-background-color: var(--color-cyan200); - --badge-strong-color: var(--color-cyan50); - --badge-strong-background-color: var(--color-cyan600); - --badge-outline-color: var(--color-cyan900); - --badge-outline-border-color: var(--color-cyan600); - --badge-outline-color-inverted: var(--color-cyan50); - --badge-outline-border-color-inverted: var(--color-cyan500); - } - - &:where([data-colorscheme='green']) { - --badge-soft-color: var(--color-green900); - --badge-soft-background-color: var(--color-green200); - --badge-strong-color: var(--color-green50); - --badge-strong-background-color: var(--color-green600); - --badge-outline-color: var(--color-green900); - --badge-outline-border-color: var(--color-green600); - --badge-outline-color-inverted: var(--color-green50); - --badge-outline-border-color-inverted: var(--color-green400); - } - - &:where([data-colorscheme='red']) { - --badge-soft-color: var(--color-red900); - --badge-soft-background-color: var(--color-red200); - --badge-strong-color: var(--color-red50); - --badge-strong-background-color: var(--color-red600); - --badge-outline-color: var(--color-red900); - --badge-outline-border-color: var(--color-red600); - --badge-outline-color-inverted: var(--color-red50); - --badge-outline-border-color-inverted: var(--color-red500); - } - - &:where([data-colorscheme='gold']) { - --badge-soft-color: var(--color-gold900); - --badge-soft-background-color: var(--color-gold200); - --badge-strong-color: var(--color-gold900); - --badge-strong-background-color: var(--color-gold300); - --badge-outline-color: var(--color-gold900); - --badge-outline-border-color: var(--color-gold500); - --badge-outline-color-inverted: var(--color-gold50); - --badge-outline-border-color-inverted: var(--color-gold400); - } - - &:where([data-colorscheme='grey']) { - --badge-soft-color: var(--color-grey900); - --badge-soft-background-color: var(--color-grey100); - --badge-strong-color: var(--color-grey900); - --badge-strong-background-color: var(--color-grey200); - --badge-outline-color: var(--color-grey900); - --badge-outline-border-color: var(--color-grey500); - --badge-outline-color-inverted: var(--color-grey50); - --badge-outline-border-color-inverted: var(--color-grey300); - } -} diff --git a/packages/react/src/components/Badge/Badge.docs.mdx b/packages/react/src/components/Badge/Badge.docs.mdx deleted file mode 100644 index 558694889..000000000 --- a/packages/react/src/components/Badge/Badge.docs.mdx +++ /dev/null @@ -1,77 +0,0 @@ -import { Meta, Canvas, ArgTypes } from '@storybook/blocks'; - -import * as Stories from './Badge.stories'; - -import { DocsHeader } from '../../storybook/DocsHeader'; - - - - - - - -- [Variants](#variants) -- [Color schemes](#color-schemes) -- [Size](#size) -- [Bottom radius](#bottom-radius) -- [API](#api) - -## Variants - -The variant prop controls the visual appearance of the Badge. - - - -```tsx -Badge -Badge -Badge -``` - -## Color schemes - -The `colorScheme` prop will change the Badge colours. - - - -## Size - -The small size is a more compact Badge. - -```tsx -Small badge -Medium badge -``` - -This prop is responsive, so you can set the value according to breakpoint values. - -```tsx -Responsive badge size -``` - - - -## Bottom radius - -The `bottomRadiusZero` will remove the `border-bottom-right-radius` and `border-bottom-left-radius`, for use when the badge is positioned on top of another element. - -```tsx -Multi SIM offer -``` - - - -## API - -This component is based on the `span` element. - -| Prop | Type | Description | Default | -| ------------------ | -------------------------------------------- | ------------------------------------------------------------------------------------ | -------- | -| `variant` | `soft` \| `strong` \| `outline` | Sets the badges's visual variant. | `soft` | -| `colorScheme` | `cyan` \|`green` \| `red` \|`gold` \| `grey` | Sets the colour scheme. | `cyan` | -| `size` | `small` \|`medium` | Sets the size. | `medium` | -| `bottomRadiusZero` | `boolean` | Removes the bottom radius, set when the Badge sits directly above another container. | `false` | diff --git a/packages/react/src/components/Badge/Badge.props.ts b/packages/react/src/components/Badge/Badge.props.ts deleted file mode 100644 index 32f78dbdc..000000000 --- a/packages/react/src/components/Badge/Badge.props.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { PropDef } from '../../props/prop-def'; -import { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; -import { Responsive } from '../../types/responsive'; - -const variants = ['soft', 'strong', 'outline'] as const; -const sizes = ['small', 'medium'] as const; - -export const badgePropDefs = { - variant: { className: 'variant', tokens: variants, responsive: false, default: 'soft' }, - size: { className: 'size', tokens: sizes, responsive: true, default: 'medium' }, -} satisfies { - variant: PropDef<(typeof variants)[number]>; - size: PropDef<(typeof sizes)[number]>; -}; - -export interface BadgeProps extends ComponentPropsWithout<'span', RemovedProps> { - /** - * Sets the badges's visual variant - * @default soft - */ - variant?: (typeof variants)[number]; - /** - * Sets the colour scheme. - * @default cyan - */ - colorScheme?: 'cyan' | 'green' | 'red' | 'gold' | 'grey'; - /** - * Removes the bottom radius, set when the Badge sits directly above another container - * @default false - */ - bottomRadiusZero?: boolean; - /** - * Set the size of the Badge - * @default medium - */ - size?: Responsive<(typeof sizes)[number]>; -} diff --git a/packages/react/src/components/Badge/Badge.stories.tsx b/packages/react/src/components/Badge/Badge.stories.tsx deleted file mode 100644 index 30e6b79da..000000000 --- a/packages/react/src/components/Badge/Badge.stories.tsx +++ /dev/null @@ -1,135 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { colors } from '@utilitywarehouse/colour-system'; -import { StarSmallIcon } from '@utilitywarehouse/react-icons'; - -import { Badge } from './Badge'; -import { Flex } from '../Flex/Flex'; -import { Box } from '../Box/Box'; - -const variants = ['soft', 'strong', 'outline'] as const; -const colorSchemes = ['cyan', 'green', 'red', 'gold', 'grey'] as const; - -const meta: Meta = { - title: 'Stories / Badge', - component: Badge, - argTypes: { - children: { control: { type: 'text' } }, - variant: { options: variants, control: { type: 'radio' } }, - size: { options: ['small', 'medium'], control: { type: 'radio' } }, - colorScheme: { options: colorSchemes, control: { type: 'radio' } }, - bottomRadiusZero: { control: { type: 'boolean' } }, - }, - args: { - children: 'Badge', - variant: 'soft', - size: 'medium', - colorScheme: 'cyan', - bottomRadiusZero: false, - }, -}; - -export default meta; -type Story = StoryObj; - -export const KitchenSink: Story = { - parameters: { controls: { hideNoControlsWarning: true } }, - render: () => { - return ( - - {variants.map(variant => ( - - {colorSchemes.map(colorScheme => ( - - - Badge - - - Badge - - - - Badge - - - - Badge - - - Badge - - - Badge - - - - Badge - - - - Badge - - - ))} - - ))} - - ); - }, -}; - -export const Workshop: Story = {}; - -export const Variants: Story = { - render: () => ( - - {variants.map(variant => ( - - {variant} - - ))} - - ), -}; - -export const ColorSchemes: Story = { - render: () => ( - - {colorSchemes.map(colorScheme => ( - - {colorScheme} - - ))} - - ), -}; - -export const ResponsiveSize: Story = { - render: args => ( - - Responsive badge size - - ), -}; - -export const BottomRadiusZero: Story = { - render: () => { - return ( - - - - Multi SIM offer - - - - - ); - }, -}; diff --git a/packages/react/src/components/Badge/Badge.tsx b/packages/react/src/components/Badge/Badge.tsx deleted file mode 100644 index 68e15d34e..000000000 --- a/packages/react/src/components/Badge/Badge.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import * as React from 'react'; -import type { ElementRef } from 'react'; - -import clsx from 'clsx'; - -import { badgePropDefs, BadgeProps } from './Badge.props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import { DATA_ATTRIBUTES } from '../../helpers/data-attributes'; -import { extractProps } from '../../helpers/extract-props'; - -const componentName = 'Badge'; -const componentClassName = withGlobalPrefix(componentName); - -type BadgeElement = ElementRef<'span'>; - -/** - * Provide additional context (such as status), or to draw attention to another - * interface element. - */ -export const Badge = React.forwardRef((props, ref) => { - const { - className, - colorScheme = 'cyan', - bottomRadiusZero, - ...badgeProps - } = extractProps(props, badgePropDefs); - const dataAttributeProps = { - [DATA_ATTRIBUTES.colorscheme]: colorScheme, - 'data-bottom-radius-zero': bottomRadiusZero ? '' : undefined, - }; - return ( - - ); -}); - -Badge.displayName = componentName; diff --git a/packages/react/src/components/BodyText/BodyText.css b/packages/react/src/components/BodyText/BodyText.css deleted file mode 100644 index 2f6c5949c..000000000 --- a/packages/react/src/components/BodyText/BodyText.css +++ /dev/null @@ -1,39 +0,0 @@ -.uw-BodyText { - font-family: var(--font-family-body); - color: var(--color-brand-midnight); - - &:where(.uw-body-text-color) { - color: var(--body-text-color); - } - - &:where([data-truncate]) { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - - /** variants **/ - &:where(.uw-variant-subtitle) { - font-size: var(--font-size-body-lg); - line-height: var(--line-height-lg); - - @media (--desktop) { - font-size: var(--font-size-body-xl); - } - } - - &:where(.uw-variant-body) { - font-size: var(--font-size-body-md); - line-height: var(--line-height-lg); - } - - &:where(.uw-variant-legalNote) { - font-size: var(--font-size-body-sm); - line-height: var(--line-height-lg); - } - - &:where(.uw-variant-caption) { - font-size: var(--font-size-body-xs); - line-height: var(--line-height-xl); - } -} diff --git a/packages/react/src/components/BodyText/BodyText.docs.mdx b/packages/react/src/components/BodyText/BodyText.docs.mdx deleted file mode 100644 index 969a7a067..000000000 --- a/packages/react/src/components/BodyText/BodyText.docs.mdx +++ /dev/null @@ -1,68 +0,0 @@ -import { Meta, Canvas, ArgTypes } from '@storybook/blocks'; - -import * as Stories from './BodyText.stories'; - -import { DocsHeader } from '../../storybook/DocsHeader'; - - - - - - - -- [Alternatives](#alternatives) -- [Variants](#variants) -- [Colour](#colour) -- [Text truncate](#text-truncate) -- [Styles](#styles) -- [API](#api) - -## Alternatives - -- [Heading](?path=/docs/components-heading--documentation) - For heading-level text -- [Strong](?path=/docs/components-strong--documentation) - For strong importance -- [Em](?path=/docs/components-em--documentation) - For emphasis - -## Variants - - - -## Colour - -You can pass any valid string color to the `Text` component. It is recommended -you use the `@utilitywarehouse/colour-system` package, and pass colour values -from that into the component. The default colour is `colorsCommon.brandMidnight` -from this package. - -```tsx -import { colorsCommon } from '@utilitywarehouse/colour-system' - -{...} -``` - -## Text truncate - -Use the `truncate` prop to set the text to truncate, instead of wrapping, with a -text overflow ellipsis. Note that text overflow can only happen with block or -inline-block level elements (the element needs to have a width in order to -overflow). - - - -## API - -This component is based on the `p` element. - -| Prop | Type | Description | Default | -| ---------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | -| `as` | `"p" \| "div" \| "span"` | Shorthand for changing the default rendered element into a semantically appropriate alternative. Cannot be used in combination with `asChild`. | `"p"` | -| `asChild` | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behavior. | `false` | -| `variant` | `"body" \| "subtitle" \| "legalNote" \| "caption"` | Applies the text font styles. | `"body"` | -| `weight` | `Responsive<"regular" \| "medium" \| "semibold">` | Set the font-weight. | `"regular"` | -| `align` | `Responsive<"left" \| "center" \| "right">` | Set the text-align. | | -| `truncate` | `boolean` | If true, the text will not wrap, but instead will truncate with a text overflow ellipsis. Note that text overflow can only happen with block or inline-block level elements (the element needs to have a width in order to overflow). | | -| `color` | `string` | Sets the text colour. It is recommended to use the colours from the `@utilitywarehouse/colour-system` package. | `--color-brandMidnight` | diff --git a/packages/react/src/components/BodyText/BodyText.props.ts b/packages/react/src/components/BodyText/BodyText.props.ts deleted file mode 100644 index 939d7c7ba..000000000 --- a/packages/react/src/components/BodyText/BodyText.props.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { PropDef } from '../../props/prop-def'; -import { TextAlignProps } from '../../props/text-align.props'; -import type { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; -import type { Responsive } from '../../types/responsive'; - -const weights = ['regular', 'medium', 'semibold'] as const; -const variants = ['subtitle', 'body', 'legalNote', 'caption'] as const; - -export const bodyTextPropDefs = { - weight: { className: 'weight', tokens: weights, responsive: true, default: 'regular' }, - variant: { className: 'variant', tokens: variants, responsive: false, default: 'body' }, - color: { className: 'body-text-color', responsive: false }, -} satisfies { - weight: PropDef<(typeof weights)[number]>; - variant: PropDef<(typeof variants)[number]>; - color: PropDef; -}; - -interface CommonBodyTextProps extends TextAlignProps { - /** - * @default p - */ - as?: 'p' | 'div' | 'span'; - /** Change the default rendered element for the one passed as a child, merging their props and behavior. */ - asChild?: boolean; - /** - * Applies the text font styles. - * @default body - */ - variant?: (typeof variants)[number]; - /** - * Set the text color - * It is recommended to use the colours from the `@utilitywarehouse/colour-system` package. - */ - color?: string; - /** - * Set the font-weight - * @default regular - */ - weight?: Responsive<(typeof weights)[number]>; - /** - * If true, the text will not wrap, but instead will truncate with a text overflow ellipsis. - * Note that text overflow can only happen with block or inline-block level elements (the element needs to have a width in order to overflow). - */ - truncate?: boolean | undefined; -} -type BodyTextDivProps = { as: 'div' } & ComponentPropsWithout<'div', RemovedProps>; -type BodyTextSpanProps = { as: 'span' } & ComponentPropsWithout<'span', RemovedProps>; -type BodyTextPProps = { as?: 'p' } & ComponentPropsWithout<'p', RemovedProps>; -export type BodyTextProps = CommonBodyTextProps & - (BodyTextSpanProps | BodyTextDivProps | BodyTextPProps); diff --git a/packages/react/src/components/BodyText/BodyText.stories.tsx b/packages/react/src/components/BodyText/BodyText.stories.tsx deleted file mode 100644 index df35485e9..000000000 --- a/packages/react/src/components/BodyText/BodyText.stories.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; - -import { BodyText } from './BodyText'; -import { Flex } from '../Flex/Flex'; -import * as React from 'react'; -import { colors, colorsCommon } from '@utilitywarehouse/colour-system'; - -const variants = ['subtitle', 'body', 'legalNote', 'caption'] as const; -const weights = ['regular', 'medium', 'semibold'] as const; - -const meta: Meta = { - title: 'Stories / BodyText', - component: BodyText, - parameters: { layout: 'centered' }, - argTypes: { - children: { control: { type: 'text' } }, - as: { options: ['span', 'p', 'div'], control: { type: 'radio' } }, - variant: { options: variants, control: { type: 'radio' } }, - weight: { options: weights, control: { type: 'radio' } }, - truncate: { control: { type: 'boolean' } }, - }, - args: { - children: 'Hamburgefons', - variant: 'body', - weight: { mobile: 'regular', tablet: 'medium', desktop: 'semibold' }, - align: { mobile: 'left', tablet: 'center', desktop: 'right' }, - truncate: false, - }, -}; - -export default meta; -type Story = StoryObj; - -export const KitchenSink: Story = { - parameters: { controls: { hideNoControlsWarning: true } }, - render: () => { - return ( - - {variants.map(variant => ( - - Hamburgefons - - ))} - - ); - }, -}; - -export const Workshop: Story = { - render: ({ color = undefined, ...args }) => { - return ( - - ); - }, - argTypes: { - color: { - options: [undefined, ...Object.keys(colorsCommon), ...Object.keys(colors)], - control: { type: 'select' }, - }, - }, - args: { - color: undefined, - }, -}; - -export const TextVariants: Story = { - name: 'Variants', - render: () => { - return ( - - {variants.map(variant => ( - - {variant} - - ))} - - ); - }, -}; - -export const TextTruncate: Story = { - name: 'Truncate', - render: args => { - return ( - - {variants.map(variant => ( - - the quick brown fox jumped over the lazy dog. - - ))} - - ); - }, - args: { - truncate: true, - weight: 'regular', - }, -}; diff --git a/packages/react/src/components/BodyText/BodyText.tsx b/packages/react/src/components/BodyText/BodyText.tsx deleted file mode 100644 index 6a05a58e9..000000000 --- a/packages/react/src/components/BodyText/BodyText.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import * as React from 'react'; -import type { ElementRef } from 'react'; - -import clsx from 'clsx'; - -import { bodyTextPropDefs, BodyTextProps } from './BodyText.props'; -import { Slot } from '@radix-ui/react-slot'; -import { extractProps } from '../../helpers/extract-props'; -import { textAlignPropDefs } from '../../props/text-align.props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; - -const componentName = 'BodyText'; -const componentClassName = withGlobalPrefix(componentName); - -type BodyTextElement = ElementRef<'p'>; - -/** - * BodyText renders the secondary UW font, Work Sans, to be used for body text. - */ -export const BodyText = React.forwardRef((props, ref) => { - const { - className, - asChild, - as: Tag = 'p', - children, - truncate, - ...bodyTextProps - } = extractProps(props, bodyTextPropDefs, textAlignPropDefs); - - return ( - - {asChild ? children : {children}} - - ); -}); - -BodyText.displayName = componentName; diff --git a/packages/react/src/components/Box/Box.css b/packages/react/src/components/Box/Box.css deleted file mode 100644 index 2d3fcec43..000000000 --- a/packages/react/src/components/Box/Box.css +++ /dev/null @@ -1,4 +0,0 @@ -.uw-Box { - box-sizing: border-box; - display: block; -} diff --git a/packages/react/src/components/Box/Box.props.ts b/packages/react/src/components/Box/Box.props.ts deleted file mode 100644 index ca4f1e7f0..000000000 --- a/packages/react/src/components/Box/Box.props.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { ColorProps } from '../../props/color.props'; -import type { PaddingProps } from '../../props/padding.props'; -import type { SizeProps } from '../../props/size.props'; -import type { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; - -interface CommonBoxProps extends ColorProps, PaddingProps, SizeProps { - as?: 'div' | 'span'; - /** - * Change the default rendered element for the one passed as a child, merging their props and behavior. - */ - asChild?: boolean; -} -type BoxDivProps = { as?: 'div' } & ComponentPropsWithout<'div', RemovedProps>; -type BoxSpanProps = { as: 'span' } & ComponentPropsWithout<'span', RemovedProps>; -export type BoxProps = CommonBoxProps & (BoxSpanProps | BoxDivProps); diff --git a/packages/react/src/components/Box/Box.stories.tsx b/packages/react/src/components/Box/Box.stories.tsx deleted file mode 100644 index 529bb0bdf..000000000 --- a/packages/react/src/components/Box/Box.stories.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { Box } from './Box'; -import { paddingTokens } from '../../props/padding.props'; - -// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export -const meta: Meta = { - title: 'Stories / Box', - component: Box, - parameters: { layout: 'centered' }, - argTypes: { - children: { control: { type: 'text' } }, - as: { options: ['div', 'span'], control: { type: 'radio' } }, - padding: { options: paddingTokens, control: { type: 'select' } }, - paddingInline: { options: paddingTokens, control: { type: 'select' } }, - paddingBlock: { options: paddingTokens, control: { type: 'select' } }, - paddingTop: { options: paddingTokens, control: { type: 'select' } }, - paddingRight: { options: paddingTokens, control: { type: 'select' } }, - paddingBottom: { options: paddingTokens, control: { type: 'select' } }, - paddingLeft: { options: paddingTokens, control: { type: 'select' } }, - width: { control: { type: 'text' } }, - minWidth: { control: { type: 'text' } }, - maxWidth: { control: { type: 'text' } }, - height: { control: { type: 'text' } }, - minHeight: { control: { type: 'text' } }, - maxHeight: { control: { type: 'text' } }, - color: { control: { type: 'text' } }, - backgroundColor: { control: { type: 'text' } }, - }, - args: { - children: 'Box', - style: { border: '1px solid rebeccapurple' }, - }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = {}; - -export const ResponsiveProps: Story = { - args: { - children: 'Responsive props', - padding: { - mobile: '4px', - tablet: '200', - desktop: '16px', - wide: '0', - }, - width: { - mobile: '100px', - tablet: '200px', - desktop: '300px', - wide: '400px', - }, - }, -}; diff --git a/packages/react/src/components/Box/Box.tsx b/packages/react/src/components/Box/Box.tsx deleted file mode 100644 index cbf92a5bf..000000000 --- a/packages/react/src/components/Box/Box.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import * as React from 'react'; -import clsx from 'clsx'; - -import type { BoxProps } from './Box.props'; - -import type { ElementRef } from 'react'; -import { Slot } from '@radix-ui/react-slot'; -import { extractProps } from '../../helpers/extract-props'; -import { paddingPropDefs } from '../../props/padding.props'; -import { colorPropDefs } from '../../props/color.props'; -import { sizePropDefs } from '../../props/size.props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; - -const componentName = 'Box'; -const componentClassName = withGlobalPrefix(componentName); - -type BoxElement = ElementRef<'div'>; - -export const Box = React.forwardRef((props, ref) => { - const { - className, - asChild, - as: Tag = 'div', - ...boxProps - } = extractProps(props, paddingPropDefs, colorPropDefs, sizePropDefs); - - const Component = asChild ? Slot : Tag; - - return ; -}); - -Box.displayName = componentName; diff --git a/packages/react/src/components/Button/Button.css b/packages/react/src/components/Button/Button.css deleted file mode 100644 index 0454c5395..000000000 --- a/packages/react/src/components/Button/Button.css +++ /dev/null @@ -1,26 +0,0 @@ -.uw-Button { - font-family: var(--font-family-body); - font-size: var(--font-size-body-md); - font-weight: var(--font-weight-medium); - line-height: var(--button-line-height); - min-width: var(--button-min-width); - gap: var(--space-100); - padding-block: var(--button-padding-block); - padding-inline: var(--button-padding-inline); - - @breakpoints { - &:where(.uw-r-size-medium) { - --button-line-height: 1.5; - --button-min-width: 136px; - --button-padding-inline: var(--space-300); - --button-padding-block: var(--space-200); - } - - &:where(.uw-r-size-small) { - --button-line-height: 1; - --button-min-width: 120px; - --button-padding-inline: var(--space-200); - --button-padding-block: var(--space-100); - } - } -} diff --git a/packages/react/src/components/Button/Button.props.ts b/packages/react/src/components/Button/Button.props.ts deleted file mode 100644 index 8cbe5dc8f..000000000 --- a/packages/react/src/components/Button/Button.props.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { PropDef } from '../../props/prop-def'; -import { Responsive } from '../../types/responsive'; -import { ButtonBaseProps } from '../ButtonBase/ButtonBase.props'; - -const sizes = ['small', 'medium'] as const; - -export const buttonPropDefs = { - size: { className: 'size', tokens: sizes, responsive: true, default: 'medium' }, -} satisfies { - size: PropDef<(typeof sizes)[number]>; -}; - -export type ButtonProps = ButtonBaseProps & { - /** - * Sets the button height. - * @default medium - */ - size?: Responsive<(typeof sizes)[number]>; -}; diff --git a/packages/react/src/components/Button/Button.stories.tsx b/packages/react/src/components/Button/Button.stories.tsx deleted file mode 100644 index 919e4d7f5..000000000 --- a/packages/react/src/components/Button/Button.stories.tsx +++ /dev/null @@ -1,139 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { fn } from '@storybook/test'; -import { Button } from './Button'; -import * as React from 'react'; -import { Flex } from '../Flex/Flex'; -import { Heading } from '../Heading/Heading'; - -const sizes = ['medium', 'small'] as const; -const variants = ['solid', 'outline', 'ghost'] as const; -const solidColorSchemes = ['cyan', 'red', 'green'] as const; -const colorSchemes = [...solidColorSchemes, 'grey', 'gold'] as const; - -// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export -const meta: Meta = { - title: 'Stories / Button', - component: Button, - parameters: { layout: 'centered' }, - argTypes: { - children: { control: { type: 'text' } }, - variant: { control: { type: 'radio' }, options: variants }, - colorScheme: { options: colorSchemes, control: { type: 'radio' } }, - size: { control: { type: 'radio' }, options: sizes }, - disabled: { control: { type: 'boolean' } }, - }, - args: { - children: 'Button', - onClick: fn(), - variant: 'solid', - colorScheme: 'cyan', - }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = {}; - -export const KitchenSink: Story = { - parameters: { controls: { hideNoControlsWarning: true } }, - render: () => { - return ( - - - Solid - - {sizes.map(size => ( - - {solidColorSchemes.map(colorScheme => ( - - ))} - - ))} - - - {sizes.map(size => ( - - {solidColorSchemes.map(colorScheme => ( - - ))} - - ))} - - - {(['outline', 'ghost'] as const).map(variant => ( - - - {variant} - - - {sizes.map(size => ( - - {colorSchemes.map(colorScheme => ( - - ))} - - ))} - - - {sizes.map(size => ( - - {colorSchemes.map(colorScheme => ( - - ))} - - ))} - - - ))} - - ); - }, -}; - -export const ResponsiveSize: Story = { - args: { - children: 'Responsive size button', - size: { - mobile: 'medium', - tablet: 'small', - desktop: 'medium', - wide: 'small', - }, - }, -}; - -export const AsLink: Story = { - render: args => { - return ( - - ); - }, -}; diff --git a/packages/react/src/components/Button/Button.tsx b/packages/react/src/components/Button/Button.tsx deleted file mode 100644 index 574a0444e..000000000 --- a/packages/react/src/components/Button/Button.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; -import { buttonPropDefs } from './Button.props'; -import type { ButtonProps } from './Button.props'; -import { ButtonBase } from '../ButtonBase/ButtonBase'; -import type { ButtonBaseElement } from '../ButtonBase/ButtonBase'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import { extractProps } from '../../helpers/extract-props'; - -const componentName = 'Button'; -const componentClassName = withGlobalPrefix(componentName); - -export const Button = React.forwardRef((props, forwardedRef) => { - const { className, ...buttonProps } = extractProps(props, buttonPropDefs); - return ( - - ); -}); - -Button.displayName = componentName; diff --git a/packages/react/src/components/ButtonBase/ButtonBase.css b/packages/react/src/components/ButtonBase/ButtonBase.css deleted file mode 100644 index c9d11e55d..000000000 --- a/packages/react/src/components/ButtonBase/ButtonBase.css +++ /dev/null @@ -1,196 +0,0 @@ -.uw-ButtonBase { - all: unset; - outline: transparent; - appearance: none; - box-sizing: border-box; - cursor: pointer; - display: inline-flex; - align-items: center; - justify-content: center; - text-align: center; - flex-shrink: 0; - user-select: none; /* make inner text unselectable */ - vertical-align: top; - -webkit-tap-highlight-color: transparent; - -webkit-touch-callout: none; - touch-action: manipulation; /* make clicks not need to wait and observe a potential double click, making the buttons feel faster */ - border: none; - transition-duration: 0.2s; - transition-property: color, background-color, border-color; - border-radius: 9999px; - color: var(--button-base-foreground-color); - background-color: var(--button-base-background-color); - - &:where([data-colorscheme='cyan']) { - --focus-outline-color: var(--color-cyan700); - - /* solid */ - --solid-background-color: var(--color-cyan400); - --solid-background-color-active: var(--color-cyan300); - --solid-background-color-disabled: var(--color-cyan100); - --solid-background-color-hover: var(--color-cyan500); - --solid-foreground-color: var(--color-cyan1000); - --solid-foreground-color-disabled: var(--color-cyan300); - - /* outline */ - --outline-background-color-active: var(--color-cyan100); - --outline-background-color-hover: var(--color-cyan50); - --outline-border-color: var(--color-cyan400); - --outline-border-color-disabled: var(--color-cyan300); - --outline-foreground-color: var(--color-cyan1000); - --outline-foreground-color-disabled: var(--color-cyan300); - - /* ghost */ - --ghost-background-color-hover: var(--color-cyan50); - --ghost-background-color-active: var(--color-cyan100); - --ghost-foreground-color: var(--color-cyan700); - --ghost-foreground-color-disabled: var(--color-cyan300); - } - - &:where([data-colorscheme='green']) { - --focus-outline-color: var(--color-green700); - - /* solid */ - --solid-background-color: var(--color-green500); - --solid-background-color-active: var(--color-green700); - --solid-background-color-disabled: var(--color-green100); - --solid-background-color-hover: var(--color-green600); - --solid-foreground-color: white; - --solid-foreground-color-disabled: var(--color-green300); - - /* outline */ - --outline-background-color-active: var(--color-green100); - --outline-background-color-hover: var(--color-green50); - --outline-border-color: var(--color-green500); - --outline-border-color-disabled: var(--color-green300); - --outline-foreground-color: var(--color-green900); - --outline-foreground-color-disabled: var(--color-green300); - - /* ghost */ - --ghost-background-color-hover: var(--color-green50); - --ghost-background-color-active: var(--color-green100); - --ghost-foreground-color: var(--color-green700); - --ghost-foreground-color-disabled: var(--color-green300); - } - - &:where([data-colorscheme='red']) { - --focus-outline-color: var(--color-red700); - - /* solid */ - --solid-background-color: var(--color-red500); - --solid-background-color-active: var(--color-red700); - --solid-background-color-disabled: var(--color-red100); - --solid-background-color-hover: var(--color-red600); - --solid-foreground-color: white; - --solid-foreground-color-disabled: var(--color-red300); - - /* outline */ - --outline-background-color-active: var(--color-red100); - --outline-background-color-hover: var(--color-red50); - --outline-border-color: var(--color-red500); - --outline-border-color-disabled: var(--color-red300); - --outline-foreground-color: var(--color-red900); - --outline-foreground-color-disabled: var(--color-red300); - - /* ghost */ - --ghost-background-color-hover: var(--color-red50); - --ghost-background-color-active: var(--color-red100); - --ghost-foreground-color: var(--color-red700); - --ghost-foreground-color-disabled: var(--color-red300); - } - - &:where([data-colorscheme='gold']) { - --focus-outline-color: var(--color-gold700); - - /* outline */ - --outline-background-color-active: var(--color-gold100); - --outline-background-color-hover: var(--color-gold50); - --outline-border-color: var(--color-gold500); - --outline-border-color-disabled: var(--color-gold300); - --outline-foreground-color: var(--color-gold900); - --outline-foreground-color-disabled: var(--color-gold300); - - /* ghost */ - --ghost-background-color-hover: var(--color-gold50); - --ghost-background-color-active: var(--color-gold100); - --ghost-foreground-color: var(--color-gold700); - --ghost-foreground-color-disabled: var(--color-gold300); - } - - &:where([data-colorscheme='grey']) { - --focus-outline-color: var(--color-grey700); - - /* outline */ - --outline-background-color-active: var(--color-grey100); - --outline-background-color-hover: var(--color-grey50); - --outline-border-color: var(--color-grey500); - --outline-border-color-disabled: var(--color-grey300); - --outline-foreground-color: var(--color-grey900); - --outline-foreground-color-disabled: var(--color-grey300); - - /* ghost */ - --ghost-background-color-hover: var(--color-grey50); - --ghost-background-color-active: var(--color-grey100); - --ghost-foreground-color: var(--color-grey700); - --ghost-foreground-color-disabled: var(--color-grey300); - } - - &:where(.uw-variant-solid) { - --button-base-foreground-color: var(--solid-foreground-color); - --button-base-background-color: var(--solid-background-color); - --button-base-background-color-hover: var(--solid-background-color-hover); - --button-base-background-color-active: var(--solid-background-color-active); - --button-base-foreground-color-disabled: var(--solid-foreground-color-disabled); - --button-base-background-color-disabled: var(--solid-background-color-disabled); - } - - &:where(.uw-variant-ghost) { - --button-base-background-color: transparent; - --button-base-background-color-disabled: transparent; - --button-base-foreground-color: var(--ghost-foreground-color); - --button-base-background-color-hover: var(--ghost-background-color-hover); - --button-base-background-color-active: var(--ghost-background-color-active); - --button-base-foreground-color-disabled: var(--ghost-foreground-color-disabled); - } - - &:where(.uw-variant-outline) { - box-shadow: inset 0 0 0 2px var(--outline-border-color); - - --button-base-background-color: transparent; - --button-base-background-color-disabled: transparent; - --button-base-foreground-color: var(--outline-foreground-color); - --button-base-background-color-hover: var(--outline-background-color-hover); - --button-base-background-color-active: var(--outline-background-color-active); - --button-base-foreground-color-disabled: var(--outline-foreground-color-disabled); - --button-base-border-color-disabled: var(--outline-border-color-disabled); - } - - &:where(:focus-visible) { - outline: 2px solid var(--focus-outline-color); - outline-offset: 2px; - } - - @media (hover: hover) { - &:where(:hover) { - --button-base-background-color: var(--button-base-background-color-hover); - } - } - - &:where(:active) { - transition-duration: 0s; - - --button-base-background-color: var(--button-base-background-color-active); - } - - &:where([aria-disabled]) { - cursor: not-allowed; - - --button-base-foreground-color: var(--button-base-foreground-color-disabled); - --button-base-background-color: var(--button-base-background-color-disabled); - --button-base-border-color: var(--button-base-border-color-disabled); - - &:where(.uw-variant-outline) { - --outline-border-color: var(--outline-border-color-disabled); - } - } -} diff --git a/packages/react/src/components/ButtonBase/ButtonBase.props.ts b/packages/react/src/components/ButtonBase/ButtonBase.props.ts deleted file mode 100644 index ad7ffe701..000000000 --- a/packages/react/src/components/ButtonBase/ButtonBase.props.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { PropDef } from '../../props/prop-def'; -import { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; - -const variants = ['solid', 'outline', 'ghost'] as const; - -export const buttonBasePropDefs = { - variant: { className: 'variant', tokens: variants, responsive: false, default: 'solid' }, -} satisfies { - variant: PropDef<(typeof variants)[number]>; -}; - -export type ButtonBaseProps = ComponentPropsWithout<'button', RemovedProps> & - ( - | { - /** - * Sets the button's visual variant - * @default solid - */ - variant?: 'solid'; - /** - * Sets the button's colour scheme - * @default cyan - */ - colorScheme?: 'cyan' | 'red' | 'green'; - } - | { - variant?: 'outline' | 'ghost'; - colorScheme?: 'cyan' | 'red' | 'green' | 'gold' | 'grey'; - } - ) & { - /** - * Change the default rendered element for the one passed as a child, merging their props and behavior. - */ - asChild?: boolean; - }; diff --git a/packages/react/src/components/ButtonBase/ButtonBase.tsx b/packages/react/src/components/ButtonBase/ButtonBase.tsx deleted file mode 100644 index f57bab4ef..000000000 --- a/packages/react/src/components/ButtonBase/ButtonBase.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import * as React from 'react'; -import { Slot } from '@radix-ui/react-slot'; - -import clsx from 'clsx'; -import { buttonBasePropDefs, ButtonBaseProps } from './ButtonBase.props'; -import { DATA_ATTRIBUTES } from '../../helpers/data-attributes'; -import type { ElementRef } from 'react'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import { extractProps } from '../../helpers/extract-props'; - -const componentName = 'ButtonBase'; -const componentClassName = withGlobalPrefix(componentName); - -export type ButtonBaseElement = ElementRef<'button'>; - -export const ButtonBase = React.forwardRef((props, ref) => { - const { - colorScheme = 'cyan', - className, - disabled, - onClick, - asChild, - ...buttonBaseProps - } = extractProps(props, buttonBasePropDefs); - const dataAttributeProps = { [DATA_ATTRIBUTES.colorscheme]: colorScheme }; - - const Component = asChild ? Slot : 'button'; - - return ( - - ); -}); - -ButtonBase.displayName = componentName; diff --git a/packages/react/src/components/Checkbox/Checkbox.css b/packages/react/src/components/Checkbox/Checkbox.css deleted file mode 100644 index 347d71923..000000000 --- a/packages/react/src/components/Checkbox/Checkbox.css +++ /dev/null @@ -1,26 +0,0 @@ -.uw-Checkbox { - cursor: pointer; - - * { - cursor: pointer; - } - - .uw-CheckboxBase { - &:where(:focus-visible) { - --checkbox-outline-color: var(--color-cyan700); - } - } - - /* we do this so that the gap between the checkbox & label is clickable */ - .uw-Label { - position: relative; - - &::before { - content: ''; - position: absolute; - height: 100%; - width: 100%; - left: -8px; - } - } -} diff --git a/packages/react/src/components/Checkbox/Checkbox.props.ts b/packages/react/src/components/Checkbox/Checkbox.props.ts deleted file mode 100644 index 1e9292526..000000000 --- a/packages/react/src/components/Checkbox/Checkbox.props.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CheckboxBaseProps } from '../CheckboxBase/CheckboxBase.props'; - -export type CheckboxProps = CheckboxBaseProps; diff --git a/packages/react/src/components/Checkbox/Checkbox.stories.tsx b/packages/react/src/components/Checkbox/Checkbox.stories.tsx deleted file mode 100644 index 6b3bd8165..000000000 --- a/packages/react/src/components/Checkbox/Checkbox.stories.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { Checkbox } from './Checkbox'; -import { Flex } from '../Flex/Flex'; -import { BodyText } from '../BodyText/BodyText'; - -const meta: Meta = { - title: 'Stories / Checkbox', - component: Checkbox, - argTypes: { - helperText: { control: { type: 'text' } }, - label: { control: { type: 'text' } }, - value: { control: { type: 'text' } }, - disabled: { type: 'boolean' }, - }, - args: { - label: 'Label', - helperText: 'Helper text', - disabled: false, - value: '1', - }, -}; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = {}; - -export const KitchenSink: Story = { - render: () => ( - - - Standalone - - - - With label - - - - ), -}; - -export const Controlled: Story = { - render: () => { - const [checked, setChecked] = React.useState(false); - return ( - - Checked: {checked ? 'true' : 'false'} - setChecked(c)} /> - - ); - }, -}; diff --git a/packages/react/src/components/Checkbox/Checkbox.tsx b/packages/react/src/components/Checkbox/Checkbox.tsx deleted file mode 100644 index af8e59c12..000000000 --- a/packages/react/src/components/Checkbox/Checkbox.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import type { CheckboxProps } from './Checkbox.props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import { Flex } from '../Flex/Flex'; -import { Label } from '../Label/Label'; -import { useFormFieldGroup } from '../FormFieldGroup/FormFieldGroup.context'; -import { HelperText } from '../HelperText/HelperText'; -import { useIds } from '../../hooks/use-ids'; -import { CheckboxBase } from '../CheckboxBase/CheckboxBase'; -import type { ElementRef } from 'react'; - -const componentName = 'Checkbox'; -const componentClassName = withGlobalPrefix(componentName); - -export type CheckboxElement = ElementRef<'button'>; - -/** - * The `Checkbox` component is a dual-state checkbox allowing users to toggle - * between checked and not checked. `Checkbox` can be used independently, - * however multiple checkboxes should be used with a `CheckboxGroup` or - * `CheckboxGridGroup` to handle the state control and layout. `Checkbox` is, - * by default, appropriately labelled when using the `label` prop, if you do - * not provide a label, you must specify an `aria-label` or `aria-labelledby` - * for accessibility. - */ -export const Checkbox = React.forwardRef( - ( - { - id: providedId, - label, - helperText, - className, - disabled, - 'aria-labelledby': ariaLabelledby, - ...props - }, - ref - ) => { - const { id, labelId, helperTextId } = useIds({ providedId, componentPrefix: 'checkbox' }); - const context = useFormFieldGroup(); - const hasGroupHelperText = context?.hasGroupHelperText; - const ariaDescribedby = context ? context['aria-describedby'] : ''; - const showHelperText = !hasGroupHelperText && !!helperText; - const showLabel = !!label; - - return ( - - - {showLabel ? ( - - - {showHelperText ? ( - - {helperText} - - ) : null} - - ) : null} - - ); - } -); - -Checkbox.displayName = componentName; diff --git a/packages/react/src/components/CheckboxBase/CheckboxBase.css b/packages/react/src/components/CheckboxBase/CheckboxBase.css deleted file mode 100644 index 725dcf3a4..000000000 --- a/packages/react/src/components/CheckboxBase/CheckboxBase.css +++ /dev/null @@ -1,65 +0,0 @@ -.uw-CheckboxBase { - --checkbox-box-shadow-color: var(--color-grey500); - - position: relative; - display: inline-flex; - align-items: center; - justify-content: center; - vertical-align: top; - flex-shrink: 0; - padding: 0; - height: 24px; - width: 24px; - border: none; - border-radius: 50%; - color: var(--color-cyan1000); - background-color: white; - outline: none; - - &::before { - content: ''; - display: block; - height: 24px; - width: 24px; - border-radius: 3px; - background-color: inherit; - box-shadow: inset 0 0 0 2px var(--checkbox-box-shadow-color); - outline: 2px solid transparent; - } - - &:where([data-state='unchecked']) { - background-color: white; - - --checkbox-box-shadow-color-disabled: var(--color-grey300); - } - - &:where([data-state='checked']) { - background-color: var(--color-cyan500); - - --checkbox-box-shadow-color: var(--color-cyan500); - --checkbox-box-shadow-color-disabled: var(--color-grey150); - --checkbox-background-color-disabled: var(--color-grey150); - } - - @media (hover: hover) { - &:where(:hover:enabled) { - border-color: var(--color-cyan500); - box-shadow: 0 0 0 8px var(--color-cyan75); - } - } - - &:where([data-disabled], [data-disabled] &) { - --checkbox-box-shadow-color: var(--checkbox-box-shadow-color-disabled); - - color: var(--color-grey400); - background-color: var(--checkbox-background-color-disabled); - } - - &:where(:focus-visible) { - border-color: var(--color-cyan500); - } - - .uw-CheckboxBaseIndicator { - position: absolute; - } -} diff --git a/packages/react/src/components/CheckboxBase/CheckboxBase.props.ts b/packages/react/src/components/CheckboxBase/CheckboxBase.props.ts deleted file mode 100644 index 8bb49a37f..000000000 --- a/packages/react/src/components/CheckboxBase/CheckboxBase.props.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { ReactNode } from 'react'; - -import type { CheckboxProps as RadixCheckboxProps } from '@radix-ui/react-checkbox'; - -export interface CheckboxBaseProps - extends Omit< - RadixCheckboxProps, - 'asChild' | 'value' | 'onCheckedChange' | 'defaultChecked' | 'defaultValue' - > { - /** The value given as data when submitted with a `name`. */ - value?: string; - defaultValue?: string; - /** - * The label for the Checkbox. If not using please properly associate the - * checkbox with a label using the `aria-label` or `aria-labelledby` props. - */ - label?: ReactNode; - /** Helper text for the Checkbox. Will not display if the checkbox group has `helperText` set. */ - helperText?: ReactNode; - /** The controlled checked state of the checkbox. Must be used in conjunction with onCheckedChange. */ - checked?: boolean; - /** Event handler called when the checked state of the checkbox changes. */ - onCheckedChange?: (checked: boolean) => void; - /** The checked state of the checkbox when it is initially rendered. Use when you do not need to control its checked state. */ - defaultChecked?: boolean; -} diff --git a/packages/react/src/components/CheckboxBase/CheckboxBase.tsx b/packages/react/src/components/CheckboxBase/CheckboxBase.tsx deleted file mode 100644 index 404245a78..000000000 --- a/packages/react/src/components/CheckboxBase/CheckboxBase.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import * as React from 'react'; - -import * as RadixCheckbox from '@radix-ui/react-checkbox'; - -import { TickMediumIcon } from '@utilitywarehouse/react-icons'; - -import type { CheckboxBaseProps } from './CheckboxBase.props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import clsx from 'clsx'; -import type { ElementRef } from 'react'; -import { useCheckboxGroupBase } from '../CheckboxGroupBase/CheckboxGroupBase.context'; - -const componentName = 'CheckboxBase'; -const componentClassName = withGlobalPrefix(componentName); - -export type CheckboxBaseElement = ElementRef<'button'>; - -export const CheckboxBase = React.forwardRef( - ({ onCheckedChange, value = 'on', className, ...props }, ref) => { - const context = useCheckboxGroupBase(); - const checked = context?.value?.includes(value); - - return ( - { - if (context) { - if (checked) { - context?.onItemCheck(value); - } else { - context?.onItemUncheck(value); - } - } - if (onCheckedChange) { - onCheckedChange(checked); - } - }} - > - - - - - ); - } -); - -CheckboxBase.displayName = componentName; diff --git a/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroup.css b/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroup.css deleted file mode 100644 index c27d3fc34..000000000 --- a/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroup.css +++ /dev/null @@ -1,7 +0,0 @@ -.uw-CheckboxGridGroup { - .uw-CheckboxGridGroupRoot { - display: grid; - gap: 16px; - min-width: fit-content; - } -} diff --git a/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroup.props.ts b/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroup.props.ts deleted file mode 100644 index 123291f99..000000000 --- a/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroup.props.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { ColumnsProps } from '../../props/columns.props'; -import { SizeProps } from '../../props/size.props'; -import { CheckboxGroupRootProps } from '../CheckboxGroup/CheckboxGroup.props'; -import { CheckboxGroupBaseProps } from '../CheckboxGroupBase/CheckboxGroupBase.props'; -import { FormFieldGroupProps } from '../FormFieldGroup/FormFieldGroup.props'; - -export interface CheckboxGridGroupRootProps - extends Omit, - ColumnsProps {} - -export interface CheckboxGridGroupProps - extends Omit, - CheckboxGroupBaseProps, - FormFieldGroupProps { - /** - * Set the container width of the CheckboxGridGroup children, independent to the width of the - * parent RadioGroup. - */ - contentWidth?: SizeProps['width']; -} diff --git a/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroup.stories.tsx b/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroup.stories.tsx deleted file mode 100644 index 1960ec39d..000000000 --- a/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroup.stories.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { CheckboxGridGroup } from './CheckboxGridGroup'; -import { CheckboxGridGroupRoot } from './CheckboxGridGroupRoot'; -import { CheckboxTile } from '../CheckboxTile/CheckboxTile'; -import { Flex } from '../Flex/Flex'; -import { BodyText } from '../BodyText/BodyText'; - -const meta: Meta = { - title: 'Stories / CheckboxGridGroup', - component: CheckboxGridGroup, - argTypes: { - helperText: { control: { type: 'text' } }, - helperTextPosition: { options: ['top', 'bottom'], control: { type: 'radio' } }, - showHelperTextIcon: { control: { type: 'boolean' } }, - label: { control: { type: 'text' } }, - error: { control: { type: 'boolean' } }, - errorMessage: { control: { type: 'text' } }, - showErrorMessageIcon: { control: { type: 'boolean' } }, - disabled: { control: { type: 'boolean' } }, - contentWidth: { control: { type: 'text' } }, - columns: { control: { type: 'number' } }, - }, - args: { - label: 'Label', - defaultValue: ['1', '2'], - columns: 2, - disabled: false, - helperText: 'Helper text', - helperTextPosition: 'top', - showHelperTextIcon: false, - error: false, - errorMessage: 'There is an error', - showErrorMessageIcon: true, - contentWidth: undefined, - }, -}; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = { - name: 'CheckboxGridGroup', - render: args => ( -
- - - - - - - - -
- ), -}; - -export const Controlled: Story = { - render: () => { - const [value, setValue] = React.useState(['1']); - return ( - - Checked: {value.join(', ')} - setValue(v)}> - - - - - - - - - ); - }, -}; - -export const CheckboxGridWithRadioHelperText: Story = { - name: 'With Checkbox HelperText', - render: args => { - return ( - - - - - - - - - ); - }, - args: { - helperText: '', - }, -}; - -export const CheckboxGridGroupResponsiveColumns: Story = { - name: 'With Responsive Columns', - render: args => { - return ( - - - - - - - - - ); - }, - args: { - helperText: 'CheckboxGridGroup with Responsive Columns', - columns: { mobile: 1, tablet: 2, desktop: 3, wide: 6 }, - }, -}; - -export const CheckboxGridGroupRootStory: StoryObj = { - name: 'CheckboxGridGroupRoot', - render: args => ( - -
- - - - - - - - -
-
- ), - parameters: { - controls: { - exclude: [ - 'helperText', - 'label', - 'helperTextPosition', - 'showHelperTextIcon', - 'error', - 'errorMessage', - 'showErrorMessageIcon', - 'contentWidth', - ], - }, - }, -}; diff --git a/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroup.tsx b/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroup.tsx deleted file mode 100644 index f864a3596..000000000 --- a/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroup.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import type { CheckboxGridGroupProps } from './CheckboxGridGroup.props'; -import { CheckboxGridGroupRoot } from './CheckboxGridGroupRoot'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import type { ElementRef } from 'react'; -import { FormFieldGroup } from '../FormFieldGroup/FormFieldGroup'; - -const componentName = 'CheckboxGridGroup'; -const componentClassName = withGlobalPrefix(componentName); - -type CheckboxGridGroupElement = ElementRef<'fieldset'>; - -/** - * Set of interactive buttons where multiple options can be selected at a time, - * displayed in a grid layout. The `CheckboxGridGroup` uses a fieldset to group - * related `Checkbox` controls. For displaying checkboxes in a column or row, - * please use the `CheckboxGroup` component. The `CheckboxGridGroup` is - * responsible for handling the value, helper text, error state, error message, - * and disabled state, as well as determining the presentation and selection of - * the items in the list. - */ -export const CheckboxGridGroup = React.forwardRef( - ( - { - disabled, - required, - label, - helperText, - helperTextPosition, - showHelperTextIcon, - error, - errorMessage, - showErrorMessageIcon, - value, - defaultValue, - onValueChange, - name, - children, - contentWidth = 'fit-content', - columns = 2, - className, - ...props - }, - ref - ) => { - const formFieldGroupProps = { - ...props, - disabled, - required, - label, - helperText, - helperTextPosition, - showHelperTextIcon, - error, - errorMessage, - showErrorMessageIcon, - }; - const checkboxGridGroupRootProps = { - width: contentWidth, - columns, - name, - required, - disabled, - defaultValue, - value, - onValueChange, - children, - }; - return ( - - - - ); - } -); - -CheckboxGridGroup.displayName = componentName; diff --git a/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroupRoot.tsx b/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroupRoot.tsx deleted file mode 100644 index 84eafd88a..000000000 --- a/packages/react/src/components/CheckboxGridGroup/CheckboxGridGroupRoot.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import type { ElementRef } from 'react'; -import { CheckboxGroupBase } from '../CheckboxGroupBase/CheckboxGroupBase'; -import { Box } from '../Box/Box'; -import { extractProps } from '../../helpers/extract-props'; -import type { CheckboxGridGroupRootProps } from './CheckboxGridGroup.props'; -import { columnsPropDefs } from '../../props/columns.props'; - -const componentName = 'CheckboxGridGroupRoot'; -const componentClassName = withGlobalPrefix(componentName); - -type CheckboxGridGroupRootElement = ElementRef<'div'>; - -export const CheckboxGridGroupRoot = React.forwardRef< - CheckboxGridGroupRootElement, - CheckboxGridGroupRootProps ->(({ ...props }, ref) => { - const { - className, - width, - children, - name, - value, - defaultValue, - onValueChange, - disabled, - ...checkboxGridGroupRootProps - } = extractProps(props, columnsPropDefs); - const checkboxGroupBaseProps = { name, value, defaultValue, onValueChange, children }; - return ( - - - - ); -}); - -CheckboxGridGroupRoot.displayName = componentName; diff --git a/packages/react/src/components/CheckboxGroup/CheckboxGroup.css b/packages/react/src/components/CheckboxGroup/CheckboxGroup.css deleted file mode 100644 index cf4c8d896..000000000 --- a/packages/react/src/components/CheckboxGroup/CheckboxGroup.css +++ /dev/null @@ -1,12 +0,0 @@ -.uw-CheckboxGroupRoot { - min-width: fit-content; - flex-wrap: wrap; - - &:where([data-orientation='horizontal']) { - flex-direction: row; - } - - &:where([data-orientation='vertical']) { - flex-direction: column; - } -} diff --git a/packages/react/src/components/CheckboxGroup/CheckboxGroup.props.ts b/packages/react/src/components/CheckboxGroup/CheckboxGroup.props.ts deleted file mode 100644 index 613db8e9c..000000000 --- a/packages/react/src/components/CheckboxGroup/CheckboxGroup.props.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { SizeProps } from '../../props/size.props'; -import { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; -import { CheckboxGroupBaseProps } from '../CheckboxGroupBase/CheckboxGroupBase.props'; -import { FormFieldGroupProps } from '../FormFieldGroup/FormFieldGroup.props'; - -export interface CheckboxGroupRootOwnProps { - name?: string; - required?: boolean; - disabled?: boolean; - defaultValue?: Array; - value?: Array; - onValueChange?: (value: Array) => void; - /** The direction of the checkboxes, will also set the aria-orientation value. */ - direction?: 'column' | 'row'; // TODO: make this responsive? - /** - * Set the width of the RadioGroup. - */ - width?: SizeProps['width']; -} - -export interface CheckboxGroupRootProps - extends CheckboxGroupRootOwnProps, - ComponentPropsWithout<'div', keyof CheckboxGroupRootOwnProps | RemovedProps> {} - -export interface CheckboxGroupProps - extends Omit, - CheckboxGroupBaseProps, - Omit { - /** - * Set the container width of the RadioGroup children, independent to the width of the - * parent RadioGroup. - */ - contentWidth?: SizeProps['width']; -} diff --git a/packages/react/src/components/CheckboxGroup/CheckboxGroup.stories.tsx b/packages/react/src/components/CheckboxGroup/CheckboxGroup.stories.tsx deleted file mode 100644 index 6efb11e19..000000000 --- a/packages/react/src/components/CheckboxGroup/CheckboxGroup.stories.tsx +++ /dev/null @@ -1,199 +0,0 @@ -import * as React from 'react'; -import { useState } from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { CheckboxGroup } from './CheckboxGroup'; -import { CheckboxGroupRoot } from './CheckboxGroupRoot'; -import { Flex } from '../Flex/Flex'; -import { Checkbox } from '../Checkbox/Checkbox'; -import { BodyText } from '../BodyText/BodyText'; -import { CheckboxTile } from '../CheckboxTile/CheckboxTile'; -import { Box } from '../Box/Box'; -import { colors } from '@utilitywarehouse/colour-system'; - -const meta: Meta = { - title: 'Stories / CheckboxGroup', - component: CheckboxGroup, - argTypes: { - direction: { - options: ['column', 'row'], - control: { type: 'radio' }, - }, - helperText: { control: { type: 'text' } }, - helperTextPosition: { options: ['top', 'bottom'], control: { type: 'radio' } }, - showHelperTextIcon: { control: { type: 'boolean' } }, - label: { control: { type: 'text' } }, - error: { control: { type: 'boolean' } }, - errorMessage: { control: { type: 'text' } }, - showErrorMessageIcon: { control: { type: 'boolean' } }, - disabled: { control: { type: 'boolean' } }, - contentWidth: { control: { type: 'text' } }, - }, - args: { - label: 'Which services do you currently have with UW?', - defaultValue: ['1', '2'], - direction: 'column', - disabled: false, - helperText: 'Select all that apply', - helperTextPosition: 'top', - showHelperTextIcon: false, - error: false, - errorMessage: 'There is an error', - showErrorMessageIcon: true, - contentWidth: undefined, - }, -}; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = { - render: args => ( - -
- - - - - - - - - - - - -
-
- ), -}; - -export const Controlled: Story = { - render: () => { - const [value, setValue] = React.useState(['1']); - return ( - - Checked: {value.join(', ')} - setValue(v)}> - - - - - - ); - }, -}; - -export const CheckboxHelperText: Story = { - name: 'Checkbox HelperText', - render: args => { - return ( - - - - - - - ); - }, - args: { - label: 'Choose music you enjoy.', - helperText: 'Please choose wisely.', - }, -}; - -export const ShowingError: Story = { - name: 'Error message', - render: args => { - const [selected, setSelected] = useState>([]); - return ( - - - - - - - - - ); - }, - args: { - errorMessage: 'Please pick two.', - label: 'What are your two favourite animals?', - helperTextPosition: 'bottom', - }, -}; - -export const ContentWidth: Story = { - render: args => { - return ( - - - - - - ); - }, - args: { contentWidth: '200px' }, -}; - -export const Wrap: Story = { - render: args => { - return ( - - - - - - - - - - ); - }, -}; - -export const CheckboxGroupRootStory: StoryObj = { - name: 'CheckboxGroupRoot', - render: args => ( - -
- - - - - - - - - - -
-
- ), - parameters: { - controls: { - exclude: [ - 'helperText', - 'label', - 'helperTextPosition', - 'showHelperTextIcon', - 'error', - 'errorMessage', - 'showErrorMessageIcon', - 'contentWidth', - ], - }, - }, -}; diff --git a/packages/react/src/components/CheckboxGroup/CheckboxGroup.tsx b/packages/react/src/components/CheckboxGroup/CheckboxGroup.tsx deleted file mode 100644 index bc94883dc..000000000 --- a/packages/react/src/components/CheckboxGroup/CheckboxGroup.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { CheckboxGroupProps } from './CheckboxGroup.props'; -import { CheckboxGroupRoot } from './CheckboxGroupRoot'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import type { ElementRef } from 'react'; -import { FormFieldGroup } from '../FormFieldGroup/FormFieldGroup'; - -const componentName = 'CheckboxGroup'; -const componentClassName = withGlobalPrefix(componentName); - -type CheckboxGroupElement = ElementRef<'fieldset'>; - -/** - * Set of interactive buttons where multiple options can be selected at a time. - * The `CheckboxGroup` uses a fieldset to group related `Checkbox` controls. - * The `CheckboxGroup` is responsible for handling the value, label, helper - * text, error state, error message, and disabled state, as well as determining - * the presentation and selection of the items in the list. - */ -export const CheckboxGroup = React.forwardRef( - ( - { - contentWidth, - disabled, - required, - label, - helperText, - helperTextPosition, - showHelperTextIcon, - error, - errorMessage, - showErrorMessageIcon, - direction, - value, - defaultValue, - onValueChange, - children, - className, - name, - ...props - }, - ref - ) => { - const formFieldGroupProps = { - ...props, - disabled, - required, - label, - helperText, - helperTextPosition, - showHelperTextIcon, - error, - errorMessage, - showErrorMessageIcon, - }; - const checkboxGroupRootProps = { - width: contentWidth, - direction, - name, - required, - disabled, - defaultValue, - value, - onValueChange, - children, - }; - return ( - - - - ); - } -); - -CheckboxGroup.displayName = componentName; diff --git a/packages/react/src/components/CheckboxGroup/CheckboxGroupRoot.tsx b/packages/react/src/components/CheckboxGroup/CheckboxGroupRoot.tsx deleted file mode 100644 index 293b633d5..000000000 --- a/packages/react/src/components/CheckboxGroup/CheckboxGroupRoot.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import { Flex } from '../Flex/Flex'; -import { CheckboxGroupBase } from '../CheckboxGroupBase/CheckboxGroupBase'; -import type { ElementRef } from 'react'; -import { CheckboxGroupRootProps } from './CheckboxGroup.props'; - -const componentName = 'CheckboxGroupRoot'; -const componentClassName = withGlobalPrefix(componentName); - -type CheckboxGroupRootElement = ElementRef<'div'>; - -/** - * Set of interactive buttons where multiple options can be selected at a time. - */ -export const CheckboxGroupRoot = React.forwardRef( - ( - { - name, - disabled, - value, - defaultValue, - onValueChange, - width = 'fit-content', - direction = 'column', - children, - className, - ...props - }, - ref - ) => { - const checkboxGroupBaseProps = { name, value, defaultValue, onValueChange, children }; - return ( - - - - ); - } -); - -CheckboxGroupRoot.displayName = componentName; diff --git a/packages/react/src/components/CheckboxGroupBase/CheckboxGroupBase.context.ts b/packages/react/src/components/CheckboxGroupBase/CheckboxGroupBase.context.ts deleted file mode 100644 index 5ee6e7c24..000000000 --- a/packages/react/src/components/CheckboxGroupBase/CheckboxGroupBase.context.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { createContext, useContext } from 'react'; - -export type CheckboxGroupBaseContextValue = { - name?: string; - value?: Array; - onItemCheck(value: string): void; - onItemUncheck(value: string): void; -}; -export const CheckboxGroupBaseContext = createContext( - undefined -); -export const CheckboxGroupBaseProvider = CheckboxGroupBaseContext.Provider; -export const useCheckboxGroupBase = () => useContext(CheckboxGroupBaseContext); diff --git a/packages/react/src/components/CheckboxGroupBase/CheckboxGroupBase.props.ts b/packages/react/src/components/CheckboxGroupBase/CheckboxGroupBase.props.ts deleted file mode 100644 index a171078bf..000000000 --- a/packages/react/src/components/CheckboxGroupBase/CheckboxGroupBase.props.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { CheckboxGroupBaseContextValue } from './CheckboxGroupBase.context'; - -export interface CheckboxGroupBaseProps { - name?: string; - defaultValue?: Array; - value?: CheckboxGroupBaseContextValue['value']; - onValueChange?: (value: Array) => void; -} diff --git a/packages/react/src/components/CheckboxGroupBase/CheckboxGroupBase.tsx b/packages/react/src/components/CheckboxGroupBase/CheckboxGroupBase.tsx deleted file mode 100644 index 6be7c07cc..000000000 --- a/packages/react/src/components/CheckboxGroupBase/CheckboxGroupBase.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import * as React from 'react'; -import type { PropsWithChildren } from 'react'; - -import { useControllableState } from '@radix-ui/react-use-controllable-state'; - -import { CheckboxGroupBaseProvider } from './CheckboxGroupBase.context'; -import { CheckboxGroupBaseProps } from './CheckboxGroupBase.props'; - -const componentName = 'CheckboxGroupBase'; - -export const CheckboxGroupBase = ({ - name, - defaultValue, - value: valueProp, - onValueChange, - children, -}: PropsWithChildren) => { - // useControllableState will handle whether controlled or uncontrolled - const [value = [], setValue] = useControllableState({ - prop: valueProp, - defaultProp: defaultValue, - onChange: onValueChange, - }); - - const handleItemCheck = React.useCallback( - (itemValue: string) => setValue((prevValue = []) => [...prevValue, itemValue]), - [setValue] - ); - - const handleItemUncheck = React.useCallback( - (itemValue: string) => - setValue((prevValue = []) => prevValue.filter(value => value !== itemValue)), - [setValue] - ); - - const providerValue = { - name, - value, - onItemCheck: handleItemCheck, - onItemUncheck: handleItemUncheck, - }; - - return {children}; -}; - -CheckboxGroupBase.displayName = componentName; diff --git a/packages/react/src/components/CheckboxTile/CheckboxTile.css b/packages/react/src/components/CheckboxTile/CheckboxTile.css deleted file mode 100644 index 3c95cad7f..000000000 --- a/packages/react/src/components/CheckboxTile/CheckboxTile.css +++ /dev/null @@ -1,39 +0,0 @@ -.uw-CheckboxTile { - display: flex; - gap: var(--space-100); - padding: var(--space-200); - border-radius: 8px; - - --checkbox-tile-border-width: 2px; - --checkbox-tile-border-color: var(--color-grey400); - --checkbox-tile-border-color-hover: var(--color-cyan500); - --checkbox-tile-border-color-focus: var(--color-cyan500); - --checkbox-tile-border-color-disabled: var(--color-grey300); - - box-shadow: inset 0 0 0 var(--checkbox-tile-border-width) var(--checkbox-tile-border-color); - - &:where(:has(:focus-visible)) { - background-color: var(--color-cyan75); - outline: 4px solid var(--color-cyan700); - - --checkbox-tile-border-color: var(--checkbox-tile-border-color-focus); - } - - @media (hover: hover) { - &:where(:hover:not([data-disabled], [data-disabled] &)) { - background-color: var(--color-cyan75); - - --checkbox-tile-border-color: var(--checkbox-tile-border-color-hover); - } - } - - &:where([data-disabled], [data-disabled] &) { - --checkbox-tile-border-color: var(--checkbox-tile-border-color-disabled); - } - - cursor: pointer; - - * { - cursor: pointer; - } -} diff --git a/packages/react/src/components/CheckboxTile/CheckboxTile.props.ts b/packages/react/src/components/CheckboxTile/CheckboxTile.props.ts deleted file mode 100644 index 29893a6a5..000000000 --- a/packages/react/src/components/CheckboxTile/CheckboxTile.props.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { CheckboxBaseProps } from '../CheckboxBase/CheckboxBase.props'; - -export type CheckboxTileProps = CheckboxBaseProps; diff --git a/packages/react/src/components/CheckboxTile/CheckboxTile.stories.tsx b/packages/react/src/components/CheckboxTile/CheckboxTile.stories.tsx deleted file mode 100644 index 0e08d8c89..000000000 --- a/packages/react/src/components/CheckboxTile/CheckboxTile.stories.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { CheckboxTile } from './CheckboxTile'; -import { Flex } from '../Flex/Flex'; -import { BodyText } from '../BodyText/BodyText'; - -const meta: Meta = { - title: 'Stories / CheckboxTile', - component: CheckboxTile, - argTypes: { - helperText: { control: { type: 'text' } }, - label: { control: { type: 'text' } }, - disabled: { type: 'boolean' }, - }, - args: { - label: 'Label', - helperText: 'Helper text', - disabled: false, - }, -}; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = { - render: args => ( - - - - ), -}; - -export const Controlled: Story = { - render: () => { - const [checked, setChecked] = React.useState(false); - return ( - - Checked: {checked ? 'true' : 'false'} - setChecked(c)} - /> - - ); - }, -}; diff --git a/packages/react/src/components/CheckboxTile/CheckboxTile.tsx b/packages/react/src/components/CheckboxTile/CheckboxTile.tsx deleted file mode 100644 index 4bc1fdf35..000000000 --- a/packages/react/src/components/CheckboxTile/CheckboxTile.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { CheckboxTileProps } from './CheckboxTile.props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import { useIds } from '../../hooks/use-ids'; -import { useFormFieldGroup } from '../FormFieldGroup/FormFieldGroup.context'; -import type { ElementRef } from 'react'; -import { CheckboxBase } from '../CheckboxBase/CheckboxBase'; -import { Flex } from '../Flex/Flex'; -import { Label } from '../Label/Label'; -import { HelperText } from '../HelperText/HelperText'; - -const componentName = 'CheckboxTile'; -const componentClassName = withGlobalPrefix(componentName); - -type CheckboxTileElement = ElementRef<'button'>; - -/** - * The `CheckboxTile` component is a dual-state checkbox allowing users to - * toggle between checked and not checked. `CheckboxTile` can be used - * independently, however multiple checkboxes should be used with a - * `CheckboxGroup` or `CheckboxGridGroup` to handle the state control and - * layout. `CheckboxTile` is, by default, appropriately labelled when using the - * `label` prop, if you do not provide a label, you must specify an - * `aria-label` or `aria-labelledby` for accessibility. - */ -export const CheckboxTile = React.forwardRef( - ( - { - id: providedId, - label, - helperText, - className, - disabled, - 'aria-labelledby': ariaLabelledby, - ...props - }, - ref - ) => { - const { labelId, helperTextId } = useIds({ providedId, componentPrefix: componentName }); - const context = useFormFieldGroup(); - const ariaDescribedby = context ? context['aria-describedby'] : ''; - const showHelperText = !context?.hasGroupHelperText && !!helperText; - const showLabel = !!label; - return ( - - ); - } -); - -CheckboxTile.displayName = componentName; diff --git a/packages/react/src/components/Divider/Divider.css b/packages/react/src/components/Divider/Divider.css deleted file mode 100644 index 525a2e698..000000000 --- a/packages/react/src/components/Divider/Divider.css +++ /dev/null @@ -1,21 +0,0 @@ -.uw-Divider { - all: unset; - display: block; /* explicitly set this so horizontal dividers show inside block elements */ - align-self: stretch; - flex-shrink: 0; - background-color: var(--color-grey175); - - &:where(.uw-divider-color) { - background-color: var(--divider-color); - } - - &:where([data-orientation='horizontal']) { - height: 1px; - width: auto; - } - - &:where([data-orientation='vertical']) { - height: auto; - width: 1px; - } -} diff --git a/packages/react/src/components/Divider/Divider.docs.mdx b/packages/react/src/components/Divider/Divider.docs.mdx deleted file mode 100644 index 61ab66653..000000000 --- a/packages/react/src/components/Divider/Divider.docs.mdx +++ /dev/null @@ -1,61 +0,0 @@ -import { Meta, Canvas } from '@storybook/blocks'; - -import * as Stories from './Divider.stories'; - -import { DocsHeader } from '../../storybook/DocsHeader'; - - - - - - - -- [Accessibility](#accessibility) -- [Custom colour](#custom-colour) -- [API](#api) - -## Accessibility - -Follows the [Separator role requirements](https://www.w3.org/TR/wai-aria-1.2/#separator). - -By default the `Divider` component renders an `hr` which has a role of -`separator` by default. This is a semantically meaningful division between -elements, and should be used considerately. - -If you need a purely visual separation you can use the `decorative` prop, which -will remove the element from the accessibility tree. Alternatively you could -use CSS styling, such as `border-color`, instead of this component. - -```tsx - -``` - -## Custom colour - -If necessary you can override the default colour using the `color` prop. We -recommend you use the `@utilitywarehouse/colour-system` library for this. - -```tsx -import { Divider } from "@utilitywarehouse/web-ui"; -import { colors } from "@utilitywarehouse/colour-system"; - -[...] - - -``` - - - -## API - -This component is based on the `hr` element. - -| Prop | Type | Description | Default | -| ------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------- | -| `orientation` | `"horizontal" \| "vertical"` | | `'horizontal'` | -| `decorative` | `boolean` | Whether or not the component is purely decorative. When true, accessibility-related attributes are updated so that that the rendered element is removed from the accessibility tree. | `false` | -| `color` | `string` | Override the default Divider colour. | `--color-grey175` | diff --git a/packages/react/src/components/Divider/Divider.props.ts b/packages/react/src/components/Divider/Divider.props.ts deleted file mode 100644 index aeac3f3ef..000000000 --- a/packages/react/src/components/Divider/Divider.props.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { PropDef } from '../../props/prop-def'; -import { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; -import { Orientation } from '../../types/orientation'; - -export const dividerPropDefs = { - color: { className: 'divider-color', responsive: false }, -} satisfies { - color: PropDef; -}; - -export interface DividerProps extends ComponentPropsWithout<'hr', 'children' | RemovedProps> { - /** - * @default horizontal - */ - orientation?: Orientation; - /** - * Whether or not the component is purely decorative. When true, accessibility-related attributes - * are updated so that that the rendered element is removed from the accessibility tree. - */ - decorative?: boolean; - /** - * Override the default Divider colour. - * It is recommended to use the colours from the `@utilitywarehouse/colour-system` package. - */ - color?: string; -} diff --git a/packages/react/src/components/Divider/Divider.stories.tsx b/packages/react/src/components/Divider/Divider.stories.tsx deleted file mode 100644 index d03482576..000000000 --- a/packages/react/src/components/Divider/Divider.stories.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { colors } from '@utilitywarehouse/colour-system'; - -import { Divider } from './Divider'; -import { Flex } from '../Flex/Flex'; -import { Heading } from '../Heading/Heading'; -import { Strong } from '../Strong/Strong'; -import { Box } from '../Box/Box'; -import { BodyText } from '../BodyText/BodyText'; - -const meta: Meta = { - title: 'Stories / Divider', - component: Divider, - argTypes: { - orientation: { options: ['horizontal', 'vertical'], control: { type: 'radio' } }, - decorative: { control: { type: 'boolean' } }, - color: { control: { type: 'text' } }, - }, - args: { - orientation: 'horizontal', - decorative: true, - color: '', - }, -}; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = {}; - -export const KitchenSink: Story = { - render: () => { - return ( - - - Mobile number: 07891123456 - - Unlimited Tariff - - - Budget control: On - - - - SIM number: 249320592996 - - - - - - Mobile number: 07875123456 - - Value Tariff - - - Budget control: On - - - - SIM number: 249320592996 - - - - - - Mobile number: 07929123456 - - Unlimited Tariff - - - Budget control: Off - - - - SIM number: 249320592996 - - - - - ); - }, -}; - -export const CustomColor: Story = { - render: () => { - return ( - - - First item - - Second item - - Third item - - - ); - }, -}; - -export const UsageOutsideFlexbox: Story = { - render: () => ( - - - - - - - ), -}; diff --git a/packages/react/src/components/Divider/Divider.tsx b/packages/react/src/components/Divider/Divider.tsx deleted file mode 100644 index 2c6d58146..000000000 --- a/packages/react/src/components/Divider/Divider.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { dividerPropDefs, type DividerProps } from './Divider.props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import { ORIENTATIONS, type Orientation } from '../../types/orientation'; -import type { ElementRef } from 'react'; -import { extractProps } from '../../helpers/extract-props'; - -const componentName = 'Divider'; -const componentClassName = withGlobalPrefix(componentName); - -type DividerElement = ElementRef<'hr'>; - -function isValidOrientation(orientation?: Orientation) { - if (orientation === undefined) return false; - return ORIENTATIONS.includes(orientation); -} - -/** - * Used to provide a visual break and semantically divide content. Supports - * vertical and horizontal orientations. Vertical dividers will only be visible - * when contained inside an element with display set to `flexbox` or `grid`. - */ -export const Divider = React.forwardRef((props, ref) => { - const { - decorative, - orientation: providedOrientation, - className, - ...dividerProps - } = extractProps(props, dividerPropDefs); - - const orientation = isValidOrientation(providedOrientation) ? providedOrientation : 'horizontal'; - - // `aria-orientation` defaults to `horizontal` so we only need it if `orientation` is vertical - const ariaOrientation = orientation === 'vertical' ? orientation : undefined; - const semanticProps = decorative - ? { 'aria-hidden': true } - : { 'aria-orientation': ariaOrientation }; - - return ( -
- ); -}); - -Divider.displayName = componentName; diff --git a/packages/react/src/components/Em/Em.css b/packages/react/src/components/Em/Em.css deleted file mode 100644 index 97c2d3fbc..000000000 --- a/packages/react/src/components/Em/Em.css +++ /dev/null @@ -1,8 +0,0 @@ -.uw-Em { - font-style: italic; - font-family: inherit; - font-size: inherit; - font-weight: inherit; - line-height: inherit; - color: inherit; -} diff --git a/packages/react/src/components/Em/Em.docs.mdx b/packages/react/src/components/Em/Em.docs.mdx deleted file mode 100644 index e1ab623a3..000000000 --- a/packages/react/src/components/Em/Em.docs.mdx +++ /dev/null @@ -1,15 +0,0 @@ -import { Meta, Canvas, ArgTypes } from '@storybook/blocks'; - -import * as Stories from './Em.stories'; - -import { DocsHeader } from '../../storybook/DocsHeader'; - - - - - - - -## API - -This component is based on the `em` element. diff --git a/packages/react/src/components/Em/Em.props.ts b/packages/react/src/components/Em/Em.props.ts deleted file mode 100644 index ba0f96609..000000000 --- a/packages/react/src/components/Em/Em.props.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; - -export type EmProps = ComponentPropsWithout<'em', RemovedProps>; diff --git a/packages/react/src/components/Em/Em.stories.tsx b/packages/react/src/components/Em/Em.stories.tsx deleted file mode 100644 index d97919024..000000000 --- a/packages/react/src/components/Em/Em.stories.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { Em } from './Em'; -import { Flex } from '../Flex/Flex'; -import { BodyText } from '../BodyText/BodyText'; - -const textVariants = ['subtitle', 'body', 'legalNote', 'caption'] as const; - -const meta: Meta = { - title: 'Stories / Em', - component: Em, -}; - -export default meta; -type Story = StoryObj; - -export const KitchenSink: Story = { - render: () => ( - - {textVariants.map(variant => ( - - We had to do something about it. - - ))} - - ), -}; diff --git a/packages/react/src/components/Em/Em.tsx b/packages/react/src/components/Em/Em.tsx deleted file mode 100644 index 4a8897d9f..000000000 --- a/packages/react/src/components/Em/Em.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { EmProps } from './Em.props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; - -import type { ElementRef } from 'react'; - -const componentName = 'Em'; -const componentClassName = withGlobalPrefix(componentName); - -type EmElement = ElementRef<'em'>; - -/** - * The `Em` component is based on the HTML `em` element and is used to indicate - * text that has stress emphasis. `Em` should be wrapped in a `Text` component, and will inherit the parent - * styles. It should __not__ be used within the `Heading` component, as this - * will result in invalid HTML. - */ -export const Em = React.forwardRef(({ className, ...props }, ref) => { - return ; -}); - -Em.displayName = componentName; diff --git a/packages/react/src/components/Fieldset/Fieldset.css b/packages/react/src/components/Fieldset/Fieldset.css deleted file mode 100644 index 1ce7c9f05..000000000 --- a/packages/react/src/components/Fieldset/Fieldset.css +++ /dev/null @@ -1,5 +0,0 @@ -.uw-Fieldset { - border: 0; - margin: 0; - padding: 0; -} diff --git a/packages/react/src/components/Fieldset/Fieldset.docs.mdx b/packages/react/src/components/Fieldset/Fieldset.docs.mdx deleted file mode 100644 index 7a608d295..000000000 --- a/packages/react/src/components/Fieldset/Fieldset.docs.mdx +++ /dev/null @@ -1,15 +0,0 @@ -import { Meta, Canvas, ArgTypes } from '@storybook/blocks'; - -import * as Stories from './Fieldset.stories'; - -import { DocsHeader } from '../../storybook/DocsHeader'; - - - - - - - -## API - -This component is based on the `fieldset` element. diff --git a/packages/react/src/components/Fieldset/Fieldset.props.ts b/packages/react/src/components/Fieldset/Fieldset.props.ts deleted file mode 100644 index eae703508..000000000 --- a/packages/react/src/components/Fieldset/Fieldset.props.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; - -export type FieldsetProps = ComponentPropsWithout<'fieldset', RemovedProps>; diff --git a/packages/react/src/components/Fieldset/Fieldset.stories.tsx b/packages/react/src/components/Fieldset/Fieldset.stories.tsx deleted file mode 100644 index ccc7c0efa..000000000 --- a/packages/react/src/components/Fieldset/Fieldset.stories.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { Fieldset } from './Fieldset'; -import { FieldsetLegend } from '../FieldsetLegend/FieldsetLegend'; -import { Box } from '../Box/Box'; - -const meta: Meta = { - title: 'Stories / Fieldset', - component: Fieldset, -}; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = { - render: args => { - return ( -
- Fieldset legend - -
- ); - }, -}; diff --git a/packages/react/src/components/Fieldset/Fieldset.tsx b/packages/react/src/components/Fieldset/Fieldset.tsx deleted file mode 100644 index b6a26e2ff..000000000 --- a/packages/react/src/components/Fieldset/Fieldset.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import type { FieldsetProps } from './Fieldset.props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import type { ElementRef } from 'react'; -import { Flex } from '../Flex/Flex'; - -const componentName = 'Fieldset'; -const componentClassName = withGlobalPrefix(componentName); - -type FieldsetElement = ElementRef<'fieldset'>; - -/** - * The `Fieldset` component should be used to group related form inputs, and - * should be used with the `FieldsetLegend` component - */ -export const Fieldset = React.forwardRef( - ({ children, className, ...props }, ref) => { - return ( -
- - {children} - -
- ); - } -); - -Fieldset.displayName = componentName; diff --git a/packages/react/src/components/FieldsetLegend/FieldsetLegend.css b/packages/react/src/components/FieldsetLegend/FieldsetLegend.css deleted file mode 100644 index dfbd659f8..000000000 --- a/packages/react/src/components/FieldsetLegend/FieldsetLegend.css +++ /dev/null @@ -1,15 +0,0 @@ -.uw-FieldsetLegend { - --fieldset-legend-color: var(--color-grey1000); - --fieldset-legend-color-disabled: var(--color-grey400); - - padding: 0; - font-family: var(--font-family-body); - font-weight: var(--font-weight-semibold); - font-size: var(--font-size-body-md); - line-height: var(--line-height-lg); - color: var(--fieldset-legend-color); - - &:where([data-disabled]) { - --fieldset-legend-color: var(--fieldset-legend-color-disabled); - } -} diff --git a/packages/react/src/components/FieldsetLegend/FieldsetLegend.docs.mdx b/packages/react/src/components/FieldsetLegend/FieldsetLegend.docs.mdx deleted file mode 100644 index 1fa962cb5..000000000 --- a/packages/react/src/components/FieldsetLegend/FieldsetLegend.docs.mdx +++ /dev/null @@ -1,15 +0,0 @@ -import { Meta, Canvas, ArgTypes } from '@storybook/blocks'; - -import * as Stories from './FieldsetLegend.stories'; - -import { DocsHeader } from '../../storybook-components'; - - - - - - - -## API - -This component is based on the `legend` element. diff --git a/packages/react/src/components/FieldsetLegend/FieldsetLegend.props.ts b/packages/react/src/components/FieldsetLegend/FieldsetLegend.props.ts deleted file mode 100644 index cd35a971b..000000000 --- a/packages/react/src/components/FieldsetLegend/FieldsetLegend.props.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; - -interface CommonFieldsetLegendProps { - /** - * Set the legend text appearance to disabled. - */ - disabled?: boolean; -} -export interface FieldsetLegendProps - extends CommonFieldsetLegendProps, - ComponentPropsWithout<'legend', RemovedProps> {} diff --git a/packages/react/src/components/FieldsetLegend/FieldsetLegend.stories.tsx b/packages/react/src/components/FieldsetLegend/FieldsetLegend.stories.tsx deleted file mode 100644 index 368ade387..000000000 --- a/packages/react/src/components/FieldsetLegend/FieldsetLegend.stories.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; - -import { FieldsetLegend } from './FieldsetLegend'; - -const meta: Meta = { - title: 'Stories / FieldsetLegend', - component: FieldsetLegend, - parameters: { layout: 'centered' }, - argTypes: { - children: { control: { type: 'text' } }, - disabled: { control: { type: 'boolean' } }, - }, - args: { - children: 'Pollen fieldset legend', - disabled: false, - }, -}; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = {}; diff --git a/packages/react/src/components/FieldsetLegend/FieldsetLegend.tsx b/packages/react/src/components/FieldsetLegend/FieldsetLegend.tsx deleted file mode 100644 index bff0407f7..000000000 --- a/packages/react/src/components/FieldsetLegend/FieldsetLegend.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import type { ElementRef } from 'react'; - -import clsx from 'clsx'; - -import { FieldsetLegendProps } from './FieldsetLegend.props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; - -const componentName = 'FieldsetLegend'; -const componentClassName = withGlobalPrefix(componentName); - -type FieldsetLegendElement = ElementRef<'legend'>; - -/** - * The `FieldsetLegend` should be used with the `Fieldset` component to label - * grouped form inputs. - */ -export const FieldsetLegend = React.forwardRef( - ({ disabled, className, ...props }, ref) => { - return ( - - ); - } -); - -FieldsetLegend.displayName = componentName; diff --git a/packages/react/src/components/Flex/Flex.css b/packages/react/src/components/Flex/Flex.css deleted file mode 100644 index d6d83f982..000000000 --- a/packages/react/src/components/Flex/Flex.css +++ /dev/null @@ -1,7 +0,0 @@ -.uw-Flex { - box-sizing: border-box; - - /* Default values to provide the initial styles in the object syntax, e.g. `` */ - display: flex; - justify-content: flex-start; -} diff --git a/packages/react/src/components/Flex/Flex.props.ts b/packages/react/src/components/Flex/Flex.props.ts deleted file mode 100644 index 95cdd05c1..000000000 --- a/packages/react/src/components/Flex/Flex.props.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { ColorProps } from '../../props/color.props'; -import { GapProps } from '../../props/gap.props'; -import type { PaddingProps } from '../../props/padding.props'; -import { PropDef } from '../../props/prop-def'; -import type { SizeProps } from '../../props/size.props'; -import type { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; -import type { Responsive } from '../../types/responsive'; - -const displayValues = ['none', 'inline-flex', 'flex'] as const; -const directionValues = ['row', 'column', 'row-reverse', 'column-reverse'] as const; -const alignValues = [ - 'start', - 'center', - 'end', - 'baseline', - 'stretch', - 'space-between', - 'space-around', - 'space-evenly', -] as const; -const justifyValues = [ - 'start', - 'center', - 'end', - 'between', - 'space-between', - 'space-around', - 'space-evenly', -] as const; -const wrapValues = ['nowrap', 'wrap', 'wrap-reverse'] as const; - -export const flexPropDefs = { - display: { className: 'display', tokens: displayValues, responsive: true }, - direction: { className: 'flex-direction', tokens: directionValues, responsive: true }, - align: { className: 'align-items', tokens: alignValues, responsive: true }, - justify: { className: 'justify-content', tokens: justifyValues, responsive: true }, - wrap: { className: 'flex-wrap', tokens: wrapValues, responsive: true }, -} satisfies { - display: PropDef<(typeof displayValues)[number]>; - direction: PropDef<(typeof directionValues)[number]>; - align: PropDef<(typeof alignValues)[number]>; - justify: PropDef<(typeof justifyValues)[number]>; - wrap: PropDef<(typeof wrapValues)[number]>; -}; - -interface CommonFlexProps extends ColorProps, PaddingProps, SizeProps, GapProps { - as?: 'div' | 'span'; - /** Change the default rendered element for the one passed as a child, merging their props and behavior. */ - asChild?: boolean; - display?: Responsive<(typeof displayValues)[number]>; - direction?: Responsive<(typeof directionValues)[number]>; - align?: Responsive<(typeof alignValues)[number]>; - justify?: Responsive<(typeof justifyValues)[number]>; - wrap?: Responsive<(typeof wrapValues)[number]>; -} -type FlexDivProps = { as?: 'div' } & ComponentPropsWithout<'div', RemovedProps>; -type FlexSpanProps = { as: 'span' } & ComponentPropsWithout<'span', RemovedProps>; -export type FlexProps = CommonFlexProps & (FlexSpanProps | FlexDivProps); -export { displayValues, directionValues, alignValues, justifyValues, wrapValues }; diff --git a/packages/react/src/components/Flex/Flex.stories.tsx b/packages/react/src/components/Flex/Flex.stories.tsx deleted file mode 100644 index 47526297c..000000000 --- a/packages/react/src/components/Flex/Flex.stories.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { Flex } from './Flex'; -import React from 'react'; -import { Box } from '../Box/Box'; -import { paddingTokens } from '../../props/padding.props'; -import { gapTokens } from '../../props/gap.props'; - -// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export -const meta: Meta = { - title: 'Stories / Flex', - component: Flex, - parameters: { layout: 'centered' }, - argTypes: { - children: { control: { type: 'text' } }, - as: { options: ['div', 'span'], control: { type: 'radio' } }, - display: { options: ['none', 'flex', 'inline-flex'], control: { type: 'radio' } }, - padding: { options: paddingTokens, control: { type: 'select' } }, - paddingInline: { options: paddingTokens, control: { type: 'select' } }, - paddingBlock: { options: paddingTokens, control: { type: 'select' } }, - paddingTop: { options: paddingTokens, control: { type: 'select' } }, - paddingRight: { options: paddingTokens, control: { type: 'select' } }, - paddingBottom: { options: paddingTokens, control: { type: 'select' } }, - paddingLeft: { options: paddingTokens, control: { type: 'select' } }, - gap: { options: gapTokens, control: { type: 'select' } }, - width: { control: { type: 'text' } }, - minWidth: { control: { type: 'text' } }, - maxWidth: { control: { type: 'text' } }, - height: { control: { type: 'text' } }, - minHeight: { control: { type: 'text' } }, - maxHeight: { control: { type: 'text' } }, - color: { control: { type: 'text' } }, - backgroundColor: { control: { type: 'text' } }, - }, - args: { - children: 'Flex', - style: { border: '1px solid rebeccapurple' }, - }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = {}; - -export const ResponsiveGap: Story = { - render: args => ( - - - - - - ), - args: { - gap: { - mobile: '50', - tablet: '100', - desktop: '200', - wide: '400', - }, - children: '', - style: { border: 'none' }, - direction: 'column', - }, -}; diff --git a/packages/react/src/components/Flex/Flex.tsx b/packages/react/src/components/Flex/Flex.tsx deleted file mode 100644 index 35c9a4c54..000000000 --- a/packages/react/src/components/Flex/Flex.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import * as React from 'react'; -import clsx from 'clsx'; - -import { flexPropDefs, type FlexProps } from './Flex.props'; - -import type { ElementRef } from 'react'; -import { Slot } from '@radix-ui/react-slot'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import { extractProps } from '../../helpers/extract-props'; -import { paddingPropDefs } from '../../props/padding.props'; -import { colorPropDefs } from '../../props/color.props'; -import { sizePropDefs } from '../../props/size.props'; -import { gapPropDefs } from '../../props/gap.props'; - -const componentName = 'Flex'; -const componentClassName = withGlobalPrefix(componentName); - -type FlexElement = ElementRef<'div'>; - -export const Flex = React.forwardRef((props, ref) => { - const { - className, - asChild, - as: Tag = 'div', - ...flexProps - } = extractProps(props, flexPropDefs, paddingPropDefs, colorPropDefs, sizePropDefs, gapPropDefs); - - const Component = asChild ? Slot : Tag; - - return ; -}); - -Flex.displayName = componentName; diff --git a/packages/react/src/components/FormFieldGroup/FormFieldGroup.context.ts b/packages/react/src/components/FormFieldGroup/FormFieldGroup.context.ts deleted file mode 100644 index 8f2a61a36..000000000 --- a/packages/react/src/components/FormFieldGroup/FormFieldGroup.context.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createContext, useContext } from 'react'; - -export type FormFieldGroupContextValue = { - hasGroupHelperText: boolean; - 'aria-describedby'?: string; -}; - -export const FormFieldGroupContext = createContext({ - hasGroupHelperText: false, -} as FormFieldGroupContextValue); - -export const FormFieldGroupProvider = FormFieldGroupContext.Provider; - -export const useFormFieldGroup = () => useContext(FormFieldGroupContext); diff --git a/packages/react/src/components/FormFieldGroup/FormFieldGroup.props.ts b/packages/react/src/components/FormFieldGroup/FormFieldGroup.props.ts deleted file mode 100644 index a8380e3e0..000000000 --- a/packages/react/src/components/FormFieldGroup/FormFieldGroup.props.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { ReactNode } from 'react'; -import { FieldsetProps } from '../Fieldset/Fieldset.props'; - -export interface FormFieldGroupProps extends FieldsetProps { - /** - * The label for the formfield group. This should contain the question being - * answered by the formfield group. - * - * If you don't include a label you need to ensure you use the `aria-label` - * or `aria-labelledby` prop to properly associate a label with the formfield - * group. - */ - label?: ReactNode; - /** - * Helper text for the formfield group. Provides a hint such as specific - * requirements for what to choose. When displayed, child - * components should not display their own `helperText`. - */ - helperText?: ReactNode; - /** - * Position of the helper text. - * @default 'top' - */ - helperTextPosition?: 'top' | 'bottom'; - /** Set whether to display the helper text icon. */ - showHelperTextIcon?: boolean; - /** Controls whether the error message is displayed. */ - error?: boolean; - /** The error message to be displayed. */ - errorMessage?: ReactNode; - /** Set whether to display the error message icon. */ - showErrorMessageIcon?: boolean; -} diff --git a/packages/react/src/components/FormFieldGroup/FormFieldGroup.stories.tsx b/packages/react/src/components/FormFieldGroup/FormFieldGroup.stories.tsx deleted file mode 100644 index 1c2a7c72b..000000000 --- a/packages/react/src/components/FormFieldGroup/FormFieldGroup.stories.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { FormFieldGroup } from './FormFieldGroup'; -import { Box } from '../Box/Box'; - -const meta: Meta = { - title: 'Stories / FormFieldGroup', - component: FormFieldGroup, - argTypes: { - helperText: { control: { type: 'text' } }, - helperTextPosition: { options: ['top', 'bottom'], control: { type: 'radio' } }, - showHelperTextIcon: { control: { type: 'boolean' } }, - label: { control: { type: 'text' } }, - error: { control: { type: 'boolean' } }, - errorMessage: { control: { type: 'text' } }, - showErrorMessageIcon: { control: { type: 'boolean' } }, - disabled: { control: { type: 'boolean' } }, - }, - args: { - label: 'Label', - disabled: false, - helperText: 'Helper text', - helperTextPosition: 'top', - showHelperTextIcon: false, - error: false, - errorMessage: 'There is an error', - showErrorMessageIcon: true, - }, -}; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = { - render: args => { - return ( - - - - ); - }, -}; diff --git a/packages/react/src/components/FormFieldGroup/FormFieldGroup.tsx b/packages/react/src/components/FormFieldGroup/FormFieldGroup.tsx deleted file mode 100644 index 8cd2a7302..000000000 --- a/packages/react/src/components/FormFieldGroup/FormFieldGroup.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import * as React from 'react'; -import type { ElementRef } from 'react'; - -import { FormFieldGroupProvider } from './FormFieldGroup.context'; -import { FormFieldGroupProps } from './FormFieldGroup.props'; -import { useIds } from '../../hooks/use-ids'; -import { mergeIds } from '../../helpers/merge-ids'; -import { Fieldset } from '../Fieldset/Fieldset'; -import { Flex } from '../Flex/Flex'; -import { FieldsetLegend } from '../FieldsetLegend/FieldsetLegend'; -import { HelperText } from '../HelperText/HelperText'; - -const componentName = 'FormFieldGroup'; - -type FormFieldGroupElement = ElementRef<'fieldset'>; - -/** - * The `FormFieldGroup` component should be used to group related form inputs. - * It renders an HTML `fieldset` and is responsible for handling the value, - * label, helper text, error state, error message, and disabled state. - */ -export const FormFieldGroup = React.forwardRef( - ( - { - id: providedId, - children, - label, - helperText, - helperTextPosition = 'top', - showHelperTextIcon, - error, - errorMessage, - showErrorMessageIcon, - disabled, - 'aria-labelledby': ariaLabelledby, - 'aria-describedby': ariaDescribedby, - 'aria-errormessage': ariaErrorMessage, - ...props - }, - ref - ) => { - const { id, labelId, helperTextId, errorMessageId } = useIds({ - providedId, - componentPrefix: 'radiogroup', - }); - const showErrorMessage = Boolean(error && errorMessage); - const showTopHelperText = helperText && helperTextPosition === 'top'; - const showBottomHelperText = helperText && helperTextPosition === 'bottom'; - - const ariaDescribedbyValue = mergeIds( - ariaDescribedby || !!helperText ? helperTextId : undefined, - ariaErrorMessage || showErrorMessage ? errorMessageId : undefined - ); - const value = { - hasGroupHelperText: !!helperText, - 'aria-describedby': ariaDescribedbyValue, - }; - - return ( -
- {label || showTopHelperText ? ( - - {label ? ( - - {label} - - ) : null} - {showTopHelperText ? ( - - {helperText} - - ) : null} - - ) : null} - - {children} - - {showBottomHelperText || showErrorMessage ? ( - - {showBottomHelperText ? ( - - {helperText} - - ) : null} - {showErrorMessage ? ( - - {errorMessage} - - ) : null} - - ) : null} -
- ); - } -); - -FormFieldGroup.displayName = componentName; diff --git a/packages/react/src/components/Heading/Heading.css b/packages/react/src/components/Heading/Heading.css deleted file mode 100644 index 373bb5b9c..000000000 --- a/packages/react/src/components/Heading/Heading.css +++ /dev/null @@ -1,54 +0,0 @@ -.uw-Heading { - font-family: var(--font-family-heading); - color: var(--color-brand-primaryPurple); - - &:where(.uw-heading-color) { - color: var(--heading-color); - } - - &:where(.uw-variant-displayHeading) { - font-size: var(--font-size-heading-3xl); - line-height: var(--line-height-md); - - @media (--desktop) { - font-size: var(--font-size-heading-4xl); - } - } - - &:where(.uw-variant-h1) { - font-size: var(--font-size-heading-2xl); - line-height: var(--line-height-md); - - @media (--desktop) { - font-size: var(--font-size-heading-3xl); - } - } - - &:where(.uw-variant-h2) { - font-size: var(--font-size-heading-xl); - line-height: var(--line-height-md); - - @media (--desktop) { - font-size: var(--font-size-heading-2xl); - line-height: var(--line-height-lg); - } - } - - &:where(.uw-variant-h3) { - font-size: var(--font-size-heading-md); - line-height: var(--line-height-lg); - - @media (--desktop) { - font-size: var(--font-size-heading-lg); - } - } - - &:where(.uw-variant-h4) { - font-size: var(--font-size-heading-xs); - line-height: var(--line-height-lg); - - @media (--desktop) { - font-size: var(--font-size-heading-sm); - } - } -} diff --git a/packages/react/src/components/Heading/Heading.props.ts b/packages/react/src/components/Heading/Heading.props.ts deleted file mode 100644 index 34d4cb8aa..000000000 --- a/packages/react/src/components/Heading/Heading.props.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { PropDef } from '../../props/prop-def'; -import { TextAlignProps } from '../../props/text-align.props'; -import type { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; -import type { Responsive } from '../../types/responsive'; - -const weights = ['regular', 'bold'] as const; -const variants = ['displayHeading', 'h1', 'h2', 'h3', 'h4'] as const; - -export const headingPropDefs = { - weight: { className: 'weight', tokens: weights, responsive: true, default: 'bold' }, - variant: { className: 'variant', tokens: variants, responsive: false, default: 'h2' }, - color: { className: 'heading-color', responsive: false }, -} satisfies { - weight: PropDef<(typeof weights)[number]>; - variant: PropDef<(typeof variants)[number]>; - color: PropDef; -}; - -export interface HeadingProps extends TextAlignProps, ComponentPropsWithout<'h2', RemovedProps> { - /** - * @default h2 - */ - as?: 'h1' | 'h2' | 'h3' | 'h4'; - /** Change the default rendered element for the one passed as a child, merging their props and behavior. */ - asChild?: boolean; - /** - * Applies the text font styles. - * @default h2 - */ - variant?: (typeof variants)[number]; - /** - * Set the text color - * It is recommended to use the colours from the `@utilitywarehouse/colour-system` package. - */ - color?: string; - /** - * Set the font-weight - * @default 'bold' - */ - weight?: Responsive<(typeof weights)[number]>; - /** - * Set the text-align on the component. - */ - align?: Responsive<'left' | 'center' | 'right'>; -} diff --git a/packages/react/src/components/Heading/Heading.stories.tsx b/packages/react/src/components/Heading/Heading.stories.tsx deleted file mode 100644 index fbe9b0de7..000000000 --- a/packages/react/src/components/Heading/Heading.stories.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; - -import { Heading } from './Heading'; -import { Flex } from '../Flex/Flex'; -import * as React from 'react'; -import { colors, colorsCommon } from '@utilitywarehouse/colour-system'; - -const variants = ['displayHeading', 'h1', 'h2', 'h3', 'h4'] as const; -const weights = ['regular', 'bold'] as const; - -const meta: Meta = { - title: 'Stories / Heading', - component: Heading, - parameters: { layout: 'centered' }, - argTypes: { - children: { control: { type: 'text' } }, - variant: { options: variants, control: { type: 'radio' } }, - weight: { options: weights, control: { type: 'radio' } }, - }, - args: { - children: 'Hamburgefons', - variant: 'h2', - align: { mobile: 'left', tablet: 'center', desktop: 'right' }, - }, -}; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = { - render: ({ color = undefined, ...args }) => { - return ( - - ); - }, - argTypes: { - color: { - options: [undefined, ...Object.keys(colorsCommon), ...Object.keys(colors)], - control: { type: 'select' }, - }, - }, -}; - -export const KitchenSink: Story = { - render: () => { - return ( - - {variants.map(variant => ( - - Hamburgefons - - ))} - - ); - }, -}; diff --git a/packages/react/src/components/Heading/Heading.tsx b/packages/react/src/components/Heading/Heading.tsx deleted file mode 100644 index 292dca56d..000000000 --- a/packages/react/src/components/Heading/Heading.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { headingPropDefs, HeadingProps } from './Heading.props'; -import type { ElementRef } from 'react'; -import { extractProps } from '../../helpers/extract-props'; -import { textAlignPropDefs } from '../../props/text-align.props'; -import { Slot } from '@radix-ui/react-slot'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; - -const componentName = 'Heading'; -const componentClassName = withGlobalPrefix(componentName); - -type HeadingElement = ElementRef<'h2'>; - -export const Heading = React.forwardRef( - ({ variant, ...props }, ref) => { - const { className, as, asChild, children, ...headingProps } = extractProps( - { variant, ...props }, - headingPropDefs, - textAlignPropDefs - ); - const defaultElement = 'h2'; - const variantElement = variant === 'displayHeading' ? 'h1' : variant || defaultElement; - const Tag = as ? as : variant ? variantElement : defaultElement; - return ( - - {asChild ? children : {children}} - - ); - } -); - -Heading.displayName = componentName; diff --git a/packages/react/src/components/HelperText/HelperText.css b/packages/react/src/components/HelperText/HelperText.css deleted file mode 100644 index e2482968b..000000000 --- a/packages/react/src/components/HelperText/HelperText.css +++ /dev/null @@ -1,27 +0,0 @@ -.uw-HelperText { - --helper-text-color: var(--color-grey700); - --helper-text-color-disabled: var(--color-grey400); - --helper-text-color-valid: var(--color-green600); - --helper-text-color-invalid: var(--color-red600); - - display: inline-flex; - font-family: var(--font-family-body); - font-size: var(--font-size-body-md); - font-weight: var(--font-weight-regular); - line-height: var(--line-height-lg); - color: var(--helper-text-color); - gap: 8px; - align-items: center; - - &:where([data-disabled], [data-disabled] &) { - color: var(--helper-text-color-disabled); - } - - &:where([data-validation='valid']) { - color: var(--helper-text-color-valid); - } - - &:where([data-validation='invalid']) { - color: var(--helper-text-color-invalid); - } -} diff --git a/packages/react/src/components/HelperText/HelperText.props.ts b/packages/react/src/components/HelperText/HelperText.props.ts deleted file mode 100644 index c44ce325f..000000000 --- a/packages/react/src/components/HelperText/HelperText.props.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; - -interface CommonHelperTextProps { - /** - * Set the helper text appearance to disabled. - * This will be overriden by the validation status. - */ - disabled?: boolean; - /** - * Set the helper text appearance to show the validation status. - * This will override the disabled styles. - * - * @default undefined - */ - validationStatus?: 'valid' | 'invalid'; - /** - * Show the relevant pre-defined icon. - */ - showIcon?: boolean; - /** Make the text unselectable, for use when associated with input elements. */ - disableUserSelect?: boolean; -} -export interface HelperTextProps - extends CommonHelperTextProps, - ComponentPropsWithout<'span', RemovedProps> {} diff --git a/packages/react/src/components/HelperText/HelperText.stories.tsx b/packages/react/src/components/HelperText/HelperText.stories.tsx deleted file mode 100644 index e06ebedeb..000000000 --- a/packages/react/src/components/HelperText/HelperText.stories.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; - -import { HelperText } from './HelperText'; - -const meta: Meta = { - title: 'Stories / HelperText', - component: HelperText, - parameters: { layout: 'centered' }, - argTypes: { - children: { control: { type: 'text' } }, - disabled: { control: { type: 'boolean' } }, - disableUserSelect: { control: { type: 'boolean' } }, - showIcon: { control: { type: 'boolean' } }, - validationStatus: { control: { type: 'radio' }, options: [undefined, 'valid', 'invalid'] }, - }, - args: { - children: 'Pollen helper text', - disabled: false, - showIcon: false, - validationStatus: undefined, - }, -}; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = {}; diff --git a/packages/react/src/components/HelperText/HelperText.tsx b/packages/react/src/components/HelperText/HelperText.tsx deleted file mode 100644 index 576f580af..000000000 --- a/packages/react/src/components/HelperText/HelperText.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import * as React from 'react'; -import type { ElementRef } from 'react'; - -import clsx from 'clsx'; - -import { HelperTextProps } from './HelperText.props'; -import { - InformationMediumContainedIcon, - TickMediumContainedIcon, - WarningMediumContainedIcon, -} from '@utilitywarehouse/react-icons'; -import { DATA_ATTRIBUTES } from '../../helpers/data-attributes'; - -const componentName = 'HelperText'; -const componentClassName = 'uw-' + componentName; - -type HelperTextElement = ElementRef<'span'>; - -export const HelperText = React.forwardRef( - ( - { children, disabled, disableUserSelect, validationStatus, showIcon, className, ...props }, - ref - ) => { - const icons: { [key: string]: typeof TickMediumContainedIcon } = { - valid: TickMediumContainedIcon, - invalid: WarningMediumContainedIcon, - }; - const Icon = validationStatus - ? (icons[validationStatus] as JSX.ElementType) - : (InformationMediumContainedIcon as JSX.ElementType); - - const dataAttributeProps = { - [DATA_ATTRIBUTES.disableUserSelect]: disableUserSelect ? '' : undefined, - 'data-disabled': disabled ? '' : undefined, - 'data-validation': validationStatus ? validationStatus : undefined, - }; - return ( - - {showIcon ? : null} - {children} - - ); - } -); - -HelperText.displayName = componentName; diff --git a/packages/react/src/components/IconButton/IconButton.css b/packages/react/src/components/IconButton/IconButton.css deleted file mode 100644 index ab31b19f3..000000000 --- a/packages/react/src/components/IconButton/IconButton.css +++ /dev/null @@ -1,18 +0,0 @@ -.uw-IconButton { - height: var(--icon-button-size); - width: var(--icon-button-size); - - @breakpoints { - &:where(.uw-r-size-medium) { - --icon-button-size: 3rem; - } - - &:where(.uw-r-size-small) { - --icon-button-size: 2rem; - } - - &:where(.uw-r-size-xsmall) { - --icon-button-size: 1.5rem; - } - } -} diff --git a/packages/react/src/components/IconButton/IconButton.props.ts b/packages/react/src/components/IconButton/IconButton.props.ts deleted file mode 100644 index 4d9306060..000000000 --- a/packages/react/src/components/IconButton/IconButton.props.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { PropDef } from '../../props/prop-def'; -import { Responsive } from '../../types/responsive'; -import { ButtonBaseProps } from '../ButtonBase/ButtonBase.props'; - -const sizes = ['xsmall', 'small', 'medium'] as const; - -export const iconButtonPropDefs = { - size: { className: 'size', tokens: sizes, responsive: true, default: 'medium' }, -} satisfies { - size: PropDef<(typeof sizes)[number]>; -}; - -export type IconButtonProps = ButtonBaseProps & { - /** - * An accessibility label that describes the button. - * Make sure this label reflects the visual icon. - */ - label: string; - /** - * Sets the button height. - * @default medium - */ - size?: Responsive<(typeof sizes)[number]>; -}; diff --git a/packages/react/src/components/IconButton/IconButton.stories.tsx b/packages/react/src/components/IconButton/IconButton.stories.tsx deleted file mode 100644 index 75a36057f..000000000 --- a/packages/react/src/components/IconButton/IconButton.stories.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { fn } from '@storybook/test'; -import { IconButton } from './IconButton'; -import * as React from 'react'; -import { Flex } from '../Flex/Flex'; -import { Heading } from '../Heading/Heading'; -import { ChevronRightMediumIcon, ChevronRightSmallIcon } from '@utilitywarehouse/react-icons'; - -const sizes = ['medium', 'small', 'xsmall'] as const; -const variants = ['solid', 'outline', 'ghost'] as const; -const colorSchemes = { - solid: ['cyan', 'red', 'green'] as const, - outline: ['cyan', 'red', 'green', 'gold', 'grey'] as const, - ghost: ['cyan', 'red', 'green', 'gold', 'grey'] as const, -}; - -const meta: Meta = { - title: 'Stories / IconButton', - component: IconButton, - parameters: { layout: 'centered' }, - argTypes: { - children: { control: { type: 'text' } }, - variant: { control: { type: 'radio' }, options: variants }, - colorScheme: { options: colorSchemes.outline, control: { type: 'radio' } }, - size: { control: { type: 'radio' }, options: sizes }, - disabled: { control: { type: 'boolean' } }, - }, - args: { - onClick: fn(), - variant: 'solid', - colorScheme: 'cyan', - }, -} satisfies Meta; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = { - render: args => ( - - - - - - ), -}; - -export const KitchenSink: Story = { - parameters: { controls: { hideNoControlsWarning: true } }, - render: () => { - return ( - - - - Solid - - - {sizes.map(size => ( - - {colorSchemes.solid.map(colorScheme => ( - alert('hello, world!')} - label="continue" - > - {size === 'xsmall' ? : } - - ))} - - ))} - - - {sizes.map(size => ( - - {colorSchemes.solid.map(colorScheme => ( - alert('hello, world!')} - label="continue" - > - {size === 'xsmall' ? : } - - ))} - - ))} - - - {(['outline', 'ghost'] as const).map(variant => ( - - - {variant} - - - {sizes.map(size => ( - - {colorSchemes[variant].map(colorScheme => ( - alert('hello, world!')} - label="continue" - > - {size === 'xsmall' ? : } - - ))} - - ))} - - - {sizes.map(size => ( - - {colorSchemes[variant].map(colorScheme => ( - alert('hello, world!')} - label="continue" - > - {size === 'xsmall' ? : } - - ))} - - ))} - - - ))} - - ); - }, -}; - -export const AsLink: Story = { - render: args => { - return ( - - - - - - ); - }, -}; diff --git a/packages/react/src/components/IconButton/IconButton.tsx b/packages/react/src/components/IconButton/IconButton.tsx deleted file mode 100644 index d8fcb02c3..000000000 --- a/packages/react/src/components/IconButton/IconButton.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; -import { iconButtonPropDefs, IconButtonProps } from './IconButton.props'; -import { ButtonBase } from '../ButtonBase/ButtonBase'; -import type { ButtonBaseElement } from '../ButtonBase/ButtonBase'; -import { extractProps } from '../../helpers/extract-props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; - -const componentName = 'IconButton'; -const componentClassName = withGlobalPrefix(componentName); - -export const IconButton = React.forwardRef( - (props, forwardedRef) => { - const { className, label, ...iconButtonProps } = extractProps(props, iconButtonPropDefs); - return ( - - ); - } -); - -IconButton.displayName = componentName; diff --git a/packages/react/src/components/Label/Label.css b/packages/react/src/components/Label/Label.css deleted file mode 100644 index 9e0cd129d..000000000 --- a/packages/react/src/components/Label/Label.css +++ /dev/null @@ -1,20 +0,0 @@ -.uw-Label { - --label-color: var(--color-grey1000); - --label-color-disabled: var(--color-grey400); - --label-font-weight: var(--font-weight-semibold); - --label-font-weight-nested: var(--font-weight-regular); - - font-family: var(--font-family-body); - font-size: var(--font-size-body-md); - font-weight: var(--label-font-weight); - line-height: var(--line-height-lg); - color: var(--label-color); - - &:where([data-disabled], [data-disabled] &) { - color: var(--label-color-disabled); - } - - &:where([data-nested]) { - font-weight: var(--label-font-weight-nested); - } -} diff --git a/packages/react/src/components/Label/Label.props.ts b/packages/react/src/components/Label/Label.props.ts deleted file mode 100644 index 8515d907b..000000000 --- a/packages/react/src/components/Label/Label.props.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; - -interface CommonLabelProps { - /** - * @default label - */ - as?: 'label' | 'span'; - /** Change the default rendered element for the one passed as a child, merging their props and behavior. */ - asChild?: boolean; - /** Sets the disabled prop, when true sets the label colour to grey */ - disabled?: boolean; - /** - * Sets the nested prop, when true will set the font-weight to regular. Use - * this when nesting the labelled element inside a Fieldset, for instance if - * labelling a Radio inside a RadioGroup. - */ - nested?: boolean; - /** Make the text unselectable, for use when associated with input elements. */ - disableUserSelect?: boolean; -} -type LabelSpanProps = { as?: 'span' } & ComponentPropsWithout<'span', RemovedProps>; -type LabelLabelProps = { as: 'label' } & ComponentPropsWithout<'label', RemovedProps>; -export type LabelProps = CommonLabelProps & (LabelSpanProps | LabelLabelProps); diff --git a/packages/react/src/components/Label/Label.stories.tsx b/packages/react/src/components/Label/Label.stories.tsx deleted file mode 100644 index 71ebe8ae6..000000000 --- a/packages/react/src/components/Label/Label.stories.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; - -import { Label } from './Label'; - -const meta: Meta = { - title: 'Stories / Label', - component: Label, - parameters: { - layout: 'centered', - }, - argTypes: { - children: { control: { type: 'text' } }, - disabled: { control: { type: 'boolean' } }, - nested: { control: { type: 'boolean' } }, - disableUserSelect: { control: { type: 'boolean' } }, - }, - args: { - children: 'Pollen Label', - nested: false, - disabled: false, - disableUserSelect: false, - }, -}; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = {}; diff --git a/packages/react/src/components/Label/Label.tsx b/packages/react/src/components/Label/Label.tsx deleted file mode 100644 index e0d1a1f9e..000000000 --- a/packages/react/src/components/Label/Label.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import * as React from 'react'; -import type { ElementRef } from 'react'; - -import clsx from 'clsx'; - -import { LabelProps } from './Label.props'; -import { Slot } from '@radix-ui/react-slot'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import { DATA_ATTRIBUTES } from '../../helpers/data-attributes'; - -const componentName = 'Label'; -const componentClassName = withGlobalPrefix(componentName); - -type LabelElement = ElementRef<'label'>; - -export const Label = React.forwardRef( - ( - { - children, - asChild, - as: Tag = 'label', - disabled, - nested, - disableUserSelect, - className, - ...props - }, - ref - ) => { - const dataAttributeProps = { - [DATA_ATTRIBUTES.disableUserSelect]: disableUserSelect ? '' : undefined, - 'data-disabled': disabled ? '' : undefined, - 'data-nested': nested ? '' : undefined, - }; - return ( - - {asChild ? children : {children}} - - ); - } -); - -Label.displayName = componentName; diff --git a/packages/react/src/components/Link/Link.css b/packages/react/src/components/Link/Link.css deleted file mode 100644 index 483b2de57..000000000 --- a/packages/react/src/components/Link/Link.css +++ /dev/null @@ -1,49 +0,0 @@ -.uw-Link { - --link-color: var(--color-cyan700); - --link-underline-color: var(--color-cyan400); - --link-underline-color-hover: var(--color-cyan500); - --link-underline-color-active: var(--color-cyan600); - --focus-outline-color: var(--color-cyan700); - - /* unset button styles when asChild is used */ - &:where(button) { - outline: transparent; - appearance: none; - border: none; - background: transparent; - padding: 0; - } - - cursor: pointer; - display: inline; - font-family: var(--font-family-body); - line-height: var(--line-height-sm); - font-weight: var(--font-weight-medium); - color: var(--link-color); - text-decoration: solid var(--link-underline-color) underline 2px; - text-underline-position: under; - border-radius: 4px; - - @media (hover: hover) { - &:where(:hover) { - --link-underline-color: var(--link-underline-color-hover); - } - } - - @breakpoints { - &:where(.uw-r-size-large) { - font-size: var(--font-size-body-lg); - } - - &:where(.uw-r-size-small) { - font-size: var(--font-size-body-md); - } - } - - &:has(svg, [data-icon]) { - display: inline-flex; - align-items: center; - flex-shrink: 0; - gap: 4px; - } -} diff --git a/packages/react/src/components/Link/Link.props.ts b/packages/react/src/components/Link/Link.props.ts deleted file mode 100644 index 32fe376f9..000000000 --- a/packages/react/src/components/Link/Link.props.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { PropDef } from '../../props/prop-def'; -import { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; -import { Responsive } from '../../types/responsive'; - -const sizes = ['small', 'large']; - -export const linkPropDefs = { - size: { className: 'size', tokens: sizes, responsive: true, default: 'large' }, -} satisfies { - size: PropDef<(typeof sizes)[number]>; -}; - -export interface LinkProps extends ComponentPropsWithout<'a', RemovedProps> { - /** - * Sets the link size. - * @default large - */ - size?: Responsive<(typeof sizes)[number]>; - /** - * Change the default rendered element for the one passed as a child, merging their props and behavior. - */ - asChild?: boolean; -} diff --git a/packages/react/src/components/Link/Link.stories.tsx b/packages/react/src/components/Link/Link.stories.tsx deleted file mode 100644 index d6747892f..000000000 --- a/packages/react/src/components/Link/Link.stories.tsx +++ /dev/null @@ -1,121 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { - ChevronLeftSmallIcon, - ChevronRightSmallIcon, - ChevronUpSmallIcon, -} from '@utilitywarehouse/react-icons'; - -import { Link } from './Link'; -import { Flex } from '../Flex/Flex'; - -const meta: Meta = { - title: 'Stories / Link', - component: Link, - args: { href: '#', size: 'small' }, - argTypes: { - children: { control: { type: 'text' } }, - href: { control: { type: 'text' } }, - size: { control: { type: 'radio' }, options: ['large', 'small'] }, - }, -}; - -export default meta; -type Story = StoryObj; - -const sizes = ['large', 'small'] as const; - -export const KitchenSink: Story = { - render: () => ( - - - {sizes.map(size => ( - - Hamburgefons - - - ))} - - - {sizes.map(size => ( - - - Hamburgefons - - ))} - - - ), -}; - -export const Workshop: Story = { - args: { - children: 'Link', - href: '#', - }, -}; - -export const SimpleExample: Story = { - render: () => ( - - Link - - - ), -}; - -export const WithIcons: Story = { - render: args => ( - - - - Back to Home - - - - Back to top - - - Continue - - - - ), -}; - -export const ResponsiveSize: Story = { - args: { - children: 'Responsive size link', - size: { - mobile: 'large', - tablet: 'small', - desktop: 'large', - wide: 'small', - }, - }, -}; - -export const AsButton: Story = { - render: () => ( - - - - ), -}; - -export const LengthyContent: Story = { - render: args => ( - - {args.children} - - ), - args: { - children: - 'Agnes Bernice Martin was an American abstract painter known for her minimalist style and abstract expressionism.', - }, -}; diff --git a/packages/react/src/components/Link/Link.tsx b/packages/react/src/components/Link/Link.tsx deleted file mode 100644 index 3bf3791b3..000000000 --- a/packages/react/src/components/Link/Link.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { Slot } from '@radix-ui/react-slot'; - -import { linkPropDefs, type LinkProps } from './Link.props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import type { ElementRef } from 'react'; -import { extractProps } from '../../helpers/extract-props'; - -const componentName = 'Link'; -const componentClassName = withGlobalPrefix(componentName); - -type LinkElement = ElementRef<'a'>; - -/** - * A semantic Call To Action for navigating between pages. - */ -export const Link = React.forwardRef((props, ref) => { - const { className, asChild, children, ...linkProps } = extractProps(props, linkPropDefs); - return ( - - {asChild ? children : {children}} - - ); -}); - -Link.displayName = componentName; diff --git a/packages/react/src/components/Radio/Radio.css b/packages/react/src/components/Radio/Radio.css deleted file mode 100644 index dd8a496eb..000000000 --- a/packages/react/src/components/Radio/Radio.css +++ /dev/null @@ -1,92 +0,0 @@ -.uw-Radio { - --radio-border-color: var(--color-grey500); - --radio-border-color-hover: var(--color-cyan500); - --radio-border-color-focus: var(--color-cyan500); - --radio-border-color-checked: var(--color-cyan500); - --radio-border-color-disabled: var(--color-grey300); - - cursor: pointer; - - * { - cursor: pointer; - } - - flex: 1; - - .uw-RadioContainer { - width: 40px; - height: 40px; - margin: -8px; - } - - .uw-RadioItem { - all: unset; - height: 20px; - width: 20px; - background-color: white; - border-radius: 100%; - border: 2px solid var(--radio-border-color); - - &:where(:focus-visible) { - --border-color: var(--radio-border-color-focus); - - outline: 2px solid var(--color-cyan700); - } - - &:where([data-state='checked']) { - --radio-border-color: var(--radio-border-color-checked); - } - - @media (hover: hover) { - &:where(:hover:enabled) { - --radio-border-color: var(--radio-border-color-hover); - - box-shadow: 0 0 0 8px var(--color-cyan75); - } - } - - &:where([data-disabled]) { - --radio-border-color: var(--radio-border-color-disabled); - } - } - - /* we do this so that the gap between the checkbox & label is clickable */ - .uw-RadioLabel { - position: relative; - - &::before { - content: ''; - position: absolute; - height: 100%; - width: 100%; - left: -8; - } - } -} - -.uw-RadioIndicator { - --radio-indicator-background-color: var(--color-cyan500); - --radio-indicator-background-color-disabled: var(--color-grey300); - - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; - position: relative; - - &::after { - content: ''; - display: block; - width: 14px; - height: 14px; - border-radius: 50%; - background-color: var(--radio-indicator-background-color); - } - - &:where([data-disabled]) { - &::after { - background-color: var(--radio-indicator-background-color-disabled); - } - } -} diff --git a/packages/react/src/components/Radio/Radio.props.ts b/packages/react/src/components/Radio/Radio.props.ts deleted file mode 100644 index 9b9dcfb8a..000000000 --- a/packages/react/src/components/Radio/Radio.props.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { ReactNode } from 'react'; - -import type { RadioGroupItemProps } from '@radix-ui/react-radio-group'; - -export interface RadioProps extends RadioGroupItemProps { - /** - * The label for the Radio. If not using please properly associate the - * Radio with a label using the `aria-label` or `aria-labelledby` props. - */ - label?: ReactNode; - /** Helper text for the Radio. Will not display if the radio group has `helperText` set. */ - helperText?: ReactNode; -} diff --git a/packages/react/src/components/Radio/Radio.stories.tsx b/packages/react/src/components/Radio/Radio.stories.tsx deleted file mode 100644 index 95c41d5f8..000000000 --- a/packages/react/src/components/Radio/Radio.stories.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { Radio } from './Radio'; -import { Flex } from '../Flex/Flex'; -import { RadioGroup } from '../RadioGroup/RadioGroup'; - -const meta: Meta = { - title: 'Stories / Radio', - component: Radio, - parameters: { layout: 'centered' }, -}; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = { - render: args => { - return ( - - - - - - - - - - ); - }, - argTypes: { - value: { control: { type: 'text' } }, - helperText: { control: { type: 'text' } }, - label: { control: { type: 'text' } }, - disabled: { control: { type: 'boolean' } }, - }, - args: { - value: '1', - disabled: false, - label: 'Radio label', - helperText: 'Radio helper text', - }, -}; diff --git a/packages/react/src/components/Radio/Radio.tsx b/packages/react/src/components/Radio/Radio.tsx deleted file mode 100644 index b3a98ff61..000000000 --- a/packages/react/src/components/Radio/Radio.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { - Indicator as RadixRadioIndicator, - Item as RadixRadioItem, -} from '@radix-ui/react-radio-group'; - -import type { RadioProps } from './Radio.props'; - -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import { Flex } from '../Flex/Flex'; -import { Label } from '../Label/Label'; -import { useIds } from '../../hooks/use-ids'; -import { HelperText } from '../HelperText/HelperText'; -import type { ElementRef } from 'react'; -import { useFormFieldGroup } from '../FormFieldGroup/FormFieldGroup.context'; - -const componentName = 'Radio'; -const componentClassName = withGlobalPrefix(componentName); - -type RadioElement = ElementRef<'button'>; - -/** - * `Radio` can be used to choose between a set of more than two options. - * - * `Radio` should always be used with a `RadioGroup` or `RadioGridGroup` to - * handle the state control and layout. - * - * `Radio` is, by default, appropriately labelled when using - * the `label` prop, if you do not provide a label, you must specify an - * `aria-label` or `aria-labelledby` for accessibility. - * - * > This component does not need to be wrapped in a `ThemeProvider` and can be used standalone with other component libraries. - */ -export const Radio = React.forwardRef( - ( - { - id: providedId, - label, - helperText, - disabled, - className, - 'aria-labelledby': ariaLabelledby, - ...props - }, - ref - ) => { - const { id, labelId, helperTextId } = useIds({ providedId, componentPrefix: 'radio' }); - const { hasGroupHelperText, 'aria-describedby': ariaDescribedby } = useFormFieldGroup(); - const showHelperText = !hasGroupHelperText && !!helperText; - const showLabel = !!label; - - return ( - - - - - - - {showLabel ? ( - - - {showHelperText ? ( - - {helperText} - - ) : null} - - ) : null} - - ); - } -); - -Radio.displayName = componentName; diff --git a/packages/react/src/components/RadioGridGroup/RadioGridGroup.css b/packages/react/src/components/RadioGridGroup/RadioGridGroup.css deleted file mode 100644 index c00f2526d..000000000 --- a/packages/react/src/components/RadioGridGroup/RadioGridGroup.css +++ /dev/null @@ -1,7 +0,0 @@ -.uw-RadioGridGroup { - .uw-RadioGridGroupRoot { - display: grid; - gap: 16px; - min-width: fit-content; - } -} diff --git a/packages/react/src/components/RadioGridGroup/RadioGridGroup.props.ts b/packages/react/src/components/RadioGridGroup/RadioGridGroup.props.ts deleted file mode 100644 index 141f455f7..000000000 --- a/packages/react/src/components/RadioGridGroup/RadioGridGroup.props.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ColumnsProps } from '../../props/columns.props'; -import { SizeProps } from '../../props/size.props'; -import { FormFieldGroupProps } from '../FormFieldGroup/FormFieldGroup.props'; -import { RadioGroupProps, RadioGroupRootProps } from '../RadioGroup/RadioGroup.props'; - -export interface RadioGridGroupRootProps - extends Omit, - ColumnsProps {} - -export interface RadioGridGroupProps - extends Omit, - Pick, - FormFieldGroupProps { - /** - * Set the container width of the RadioGroup children, independent to the width of the - * parent RadioGridGroup. - */ - contentWidth?: SizeProps['width']; -} diff --git a/packages/react/src/components/RadioGridGroup/RadioGridGroup.stories.tsx b/packages/react/src/components/RadioGridGroup/RadioGridGroup.stories.tsx deleted file mode 100644 index be0a7dd09..000000000 --- a/packages/react/src/components/RadioGridGroup/RadioGridGroup.stories.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; -import { RadioGridGroup } from './RadioGridGroup'; -import { RadioTile } from '../RadioTile/RadioTile'; - -const meta: Meta = { - title: 'Stories / RadioGridGroup', - component: RadioGridGroup, - argTypes: { - error: { control: { type: 'boolean' } }, - defaultValue: { control: { type: 'text' } }, - helperText: { control: { type: 'text' } }, - helperTextPosition: { options: ['top', 'bottom'], control: { type: 'radio' } }, - showHelperTextIcon: { control: { type: 'boolean' } }, - label: { control: { type: 'text' } }, - errorMessage: { control: { type: 'text' } }, - showErrorMessageIcon: { control: { type: 'boolean' } }, - disabled: { control: { type: 'boolean' } }, - contentWidth: { control: { type: 'text' } }, - columns: { control: { type: 'number' } }, - }, - args: { - defaultValue: '1', - columns: 2, - label: 'Label', - disabled: false, - helperText: 'Helper text', - showHelperTextIcon: false, - error: false, - errorMessage: 'There is an error', - showErrorMessageIcon: true, - contentWidth: undefined, - }, -}; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = { - render: args => { - return ( - - - - - - - - - ); - }, - args: { - helperText: 'RadioGridGroup with RadioTile', - }, -}; - -export const RadioGridWithRadioHelperText: Story = { - name: 'With Radio HelperText', - render: args => { - return ( - - - - - - - - - ); - }, - args: { - helperText: '', - }, -}; - -export const RadioGridGroupResponsiveColumns: Story = { - name: 'With Responsive Columns', - render: args => { - return ( - - - - - - - - - ); - }, - args: { - helperText: 'RadioGridGroup with Responsive Columns', - columns: { mobile: 1, tablet: 2, desktop: 3, wide: 6 }, - }, -}; diff --git a/packages/react/src/components/RadioGridGroup/RadioGridGroup.tsx b/packages/react/src/components/RadioGridGroup/RadioGridGroup.tsx deleted file mode 100644 index f0ecce2db..000000000 --- a/packages/react/src/components/RadioGridGroup/RadioGridGroup.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import type { ElementRef } from 'react'; -import type { RadioGridGroupProps } from './RadioGridGroup.props'; -import { FormFieldGroup } from '../FormFieldGroup/FormFieldGroup'; -import { RadioGridGroupRoot } from './RadioGridGroupRoot'; - -const componentName = 'RadioGridGroup'; -const componentClassName = withGlobalPrefix(componentName); - -type RadioGridGroupElement = ElementRef<'fieldset'>; - -/** - * The `RadioGridGroup` provides an accessible way to group and control a set - * of `Radio` or `RadioTile` components, displayed in a grid layout, allowing - * the user to select one option from a set. For displaying radios in a column - * or row, please use the `RadioGroup` component. The `RadioGridGroup` is - * responsible for handling the value, helper text, error state, error message, - * and disabled state, as well as determining the presentation and selection of - * the items in the list. Follows the [WAI-ARIA Radio Group Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/) for radio groups not contained in a toolbar. - */ -export const RadioGridGroup = React.forwardRef( - ( - { - children, - contentWidth = 'fit-content', - className, - label, - helperText, - helperTextPosition, - showHelperTextIcon, - error, - errorMessage, - showErrorMessageIcon, - required, - disabled, - loop, - defaultValue, - value, - onValueChange, - name, - columns, - ...props - }, - ref - ) => { - const formFieldGroupProps = { - ...props, - disabled, - required, - label, - helperText, - helperTextPosition, - showHelperTextIcon, - error, - errorMessage, - showErrorMessageIcon, - }; - const radioGridGroupRootProps = { - width: contentWidth, - name, - required, - disabled, - loop, - defaultValue, - value, - onValueChange, - columns, - }; - return ( - - {children} - - ); - } -); - -RadioGridGroup.displayName = componentName; diff --git a/packages/react/src/components/RadioGridGroup/RadioGridGroupRoot.tsx b/packages/react/src/components/RadioGridGroup/RadioGridGroupRoot.tsx deleted file mode 100644 index 00a8c334f..000000000 --- a/packages/react/src/components/RadioGridGroup/RadioGridGroupRoot.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { Root } from '@radix-ui/react-radio-group'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import type { ElementRef } from 'react'; -import type { RadioGridGroupRootProps } from './RadioGridGroup.props'; -import { Box } from '../Box/Box'; -import { extractProps } from '../../helpers/extract-props'; -import { columnsPropDefs } from '../../props/columns.props'; - -const componentName = 'RadioGridGroupRoot'; -const componentClassName = withGlobalPrefix(componentName); - -type RadioGridGroupRootElement = ElementRef<'div'>; - -export const RadioGridGroupRoot = React.forwardRef< - RadioGridGroupRootElement, - RadioGridGroupRootProps ->((props, ref) => { - const { className, width, children, ...radioGridGroupProps } = extractProps( - props, - columnsPropDefs - ); - - return ( - - - {children} - - - ); -}); - -RadioGridGroupRoot.displayName = componentName; diff --git a/packages/react/src/components/RadioGroup/RadioGroup.css b/packages/react/src/components/RadioGroup/RadioGroup.css deleted file mode 100644 index 41e7fe6f3..000000000 --- a/packages/react/src/components/RadioGroup/RadioGroup.css +++ /dev/null @@ -1,12 +0,0 @@ -.uw-RadioGroupRoot { - min-width: fit-content; - flex-wrap: wrap; - - &:where([data-orientation='horizontal']) { - flex-direction: row; - } - - &:where([data-orientation='vertical']) { - flex-direction: column; - } -} diff --git a/packages/react/src/components/RadioGroup/RadioGroup.props.ts b/packages/react/src/components/RadioGroup/RadioGroup.props.ts deleted file mode 100644 index aa6ff9639..000000000 --- a/packages/react/src/components/RadioGroup/RadioGroup.props.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { RadioGroupProps as RadixRadioGroupProps } from '@radix-ui/react-radio-group'; -import type { FormFieldGroupProps } from '../FormFieldGroup/FormFieldGroup.props'; -import { SizeProps } from '../../props/size.props'; - -export interface RadioGroupRootProps extends Omit { - /** The direction of the radios, will also set the aria-orientation value. */ - direction?: 'column' | 'row'; - /** - * Set the width of the RadioGroup. - */ - width?: SizeProps['width']; -} - -export interface RadioGroupProps - extends Omit, - FormFieldGroupProps, - Pick { - /** - * Set the container width of the RadioGroup children, independent to the width of the - * parent RadioGroup. - */ - contentWidth?: SizeProps['width']; -} diff --git a/packages/react/src/components/RadioGroup/RadioGroup.stories.tsx b/packages/react/src/components/RadioGroup/RadioGroup.stories.tsx deleted file mode 100644 index 9d38808f4..000000000 --- a/packages/react/src/components/RadioGroup/RadioGroup.stories.tsx +++ /dev/null @@ -1,154 +0,0 @@ -import * as React from 'react'; -import { useState } from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { RadioGroup } from './RadioGroup'; -import { Flex } from '../Flex/Flex'; -import { Radio } from '../Radio/Radio'; -import { RadioTile } from '../RadioTile/RadioTile'; -import { Box } from '../Box/Box'; - -const meta: Meta = { - title: 'Stories / RadioGroup', - component: RadioGroup, - argTypes: { - direction: { - options: ['column', 'row'], - control: { type: 'radio' }, - }, - defaultValue: { control: { type: 'text' } }, - helperText: { control: { type: 'text' } }, - helperTextPosition: { options: ['top', 'bottom'], control: { type: 'radio' } }, - showHelperTextIcon: { control: { type: 'boolean' } }, - label: { control: { type: 'text' } }, - error: { control: { type: 'boolean' } }, - errorMessage: { control: { type: 'text' } }, - showErrorMessageIcon: { control: { type: 'boolean' } }, - disabled: { control: { type: 'boolean' } }, - contentWidth: { control: { type: 'text' } }, - }, - args: { - defaultValue: '1', - label: 'Label', - disabled: false, - helperText: 'Helper text', - showHelperTextIcon: false, - error: false, - errorMessage: 'There is an error', - showErrorMessageIcon: true, - contentWidth: undefined, - }, -}; - -export default meta; -type Story = StoryObj; - -export const Workshop: Story = { - render: args => { - return ( - - - - - - - - - - - - - ); - }, -}; - -export const RadioHelperText: Story = { - name: 'Radio HelperText', - render: args => { - return ( - - - - - - ); - }, - args: { - helperText: '', - }, -}; - -// export const ContentWidth: Story = { -// name: 'Content Width', -// render: args => { -// return ( -// -// -// -// -// -// ); -// }, -// args: { contentWidth: '200px' }, -// }; - -export const Controlled: Story = { - render: args => { - const options = ['Bear', 'Koala', 'Wolf', 'Horse']; - const [selected, setSelected] = useState(options[0]); - return ( - - {options.map(animal => ( - - ))} - - ); - }, - args: { - errorMessage: 'There is an error', - label: 'What is your favourite animal?', - }, -}; - -export const ShowingError: Story = { - name: 'Error message', - render: args => { - const [selected, setSelected] = useState(''); - return ( - - - - - - - ); - }, - args: { - errorMessage: 'Please tell us what your favourite animal is.', - label: 'What is your favourite animal?', - helperText: 'These are the best animals.', - helperTextPosition: 'bottom', - }, -}; - -export const Wrap: Story = { - render: args => { - return ( - - - - - - - - - - ); - }, -}; diff --git a/packages/react/src/components/RadioGroup/RadioGroup.tsx b/packages/react/src/components/RadioGroup/RadioGroup.tsx deleted file mode 100644 index 88013ba90..000000000 --- a/packages/react/src/components/RadioGroup/RadioGroup.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { Root } from '@radix-ui/react-radio-group'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import type { ElementRef } from 'react'; -import { RadioGroupProps, RadioGroupRootProps } from './RadioGroup.props'; -import { Flex } from '../Flex/Flex'; -import { FormFieldGroup } from '../FormFieldGroup/FormFieldGroup'; - -const rootComponentName = 'RadioGroupRoot'; -const rootComponentClassName = withGlobalPrefix(rootComponentName); - -type RadioGroupRootElement = ElementRef<'div'>; - -export const RadioGroupRoot = React.forwardRef( - ({ id, disabled, children, direction = 'column', width, className, ...props }, ref) => { - return ( - - - {children} - - - ); - } -); - -RadioGroupRoot.displayName = rootComponentName; - -const componentName = 'RadioGroup'; -const componentClassName = withGlobalPrefix(componentName); - -type RadioGroupElement = ElementRef<'fieldset'>; - -/** - * The `RadioGroup` provides an accessible way to group and control a set of - * `Radio` or `RadioTile` components, allowing the user to select one option - * from a set. The `RadioGroup` is responsible for handling the value, helper - * text, error state, error message, and disabled state, as well as determining - * the presentation and selection of the items in the list. Follows the - * [WAI-ARIA Radio Group Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/) for radio - * groups not contained in a toolbar. - */ -export const RadioGroup = React.forwardRef( - ( - { - children, - contentWidth = 'fit-content', - direction = 'column', - className, - label, - helperText, - helperTextPosition, - showHelperTextIcon, - error, - errorMessage, - showErrorMessageIcon, - required, - disabled, - loop, - defaultValue, - value, - onValueChange, - name, - ...props - }, - ref - ) => { - const formFieldGroupProps = { - ...props, - disabled, - required, - label, - helperText, - helperTextPosition, - showHelperTextIcon, - error, - errorMessage, - showErrorMessageIcon, - }; - const radioGroupRootProps = { - width: contentWidth, - direction, - name, - required, - disabled, - loop, - defaultValue, - value, - onValueChange, - }; - - return ( - - {children} - - ); - } -); - -RadioGroup.displayName = componentName; diff --git a/packages/react/src/components/RadioTile/RadioTile.css b/packages/react/src/components/RadioTile/RadioTile.css deleted file mode 100644 index dc3d2c065..000000000 --- a/packages/react/src/components/RadioTile/RadioTile.css +++ /dev/null @@ -1,72 +0,0 @@ -.uw-RadioTile { - --radio-item-background-color: white; - --radio-item-background-color-focus: var(--color-cyan100); - --radio-item-background-color-hover: var(--color-cyan75); - --radio-item-box-shadow-color: var(--color-grey400); - --radio-item-box-shadow-color-focus: var(--color-cyan500); - --radio-item-box-shadow-color-hover: var(--color-cyan500); - --radio-item-box-shadow-color-disabled: var(--color-grey300); - --radio-border-color: var(--color-grey500); - --radio-border-color-focus: var(--color-cyan500); - --radio-border-color-checked: var(--color-cyan500); - --radio-border-color-disabled: var(--color-grey300); - - all: unset; - display: flex; - border-radius: 8px; - padding: 16px; - flex: 1; - box-shadow: inset 0 0 0 2px var(--radio-item-box-shadow-color); - background-color: var(--radio-item-background-color); - - &:where(:focus-visible) { - --radio-item-background-color: var(--radio-item-background-color-focus); - --radio-item-box-shadow-color: var(--radio-item-box-shadow-color-focus); - - outline: 4px solid var(--color-cyan700); - } - - @media (hover: hover) { - &:where(:hover:enabled) { - --radio-item-background-color: var(--radio-item-background-color-hover); - --radio-item-box-shadow-color: var(--radio-item-box-shadow-color-hover); - - & div:first-child { - border-color: var(--color-cyan500); - } - } - } - - &:where([data-disabled]) { - --radio-item-box-shadow-color: var(--radio-item-box-shadow-color-disabled); - } - - cursor: pointer; - - * { - cursor: pointer; - } - - .uw-RadioTileRadio { - height: 24px; - width: 24px; - flex-shrink: 0; - background-color: white; - border-radius: 100%; - border: 2px solid var(--radio-border-color); - - &:where(:focus-visible) { - --radio-border-color: var(--radio-border-color-focus); - - box-shadow: 0 0 0 2px var(--color-cyan700); - } - - &:where([data-state='checked'] &) { - --radio-border-color: var(--radio-border-color-checked); - } - - &:where([data-disabled] &) { - --radio-border-color: var(--radio-border-color-disabled); - } - } -} diff --git a/packages/react/src/components/RadioTile/RadioTile.props.ts b/packages/react/src/components/RadioTile/RadioTile.props.ts deleted file mode 100644 index 980130b46..000000000 --- a/packages/react/src/components/RadioTile/RadioTile.props.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { RadioProps } from '../Radio/Radio.props'; - -export type RadioTileProps = RadioProps; diff --git a/packages/react/src/components/RadioTile/RadioTile.stories.tsx b/packages/react/src/components/RadioTile/RadioTile.stories.tsx deleted file mode 100644 index 6c1169021..000000000 --- a/packages/react/src/components/RadioTile/RadioTile.stories.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { RadioTile } from './RadioTile'; -import { Flex } from '../Flex/Flex'; -import { RadioGroup } from '../RadioGroup/RadioGroup'; - -const meta: Meta = { - title: 'Stories / RadioTile', - component: RadioTile, - argTypes: { - value: { control: { type: 'text' } }, - helperText: { control: { type: 'text' } }, - label: { control: { type: 'text' } }, - disabled: { control: { type: 'boolean' } }, - }, - args: { - value: '1', - disabled: false, - label: 'Label', - helperText: 'Helper text', - }, -}; - -export default meta; -type Story = StoryObj; - -export const RadioTileStory: Story = { - name: 'RadioTile', - render: args => { - return ( - - - - - - - - - - ); - }, -}; - -export const RadioTileStoryWithOneLongLabel: Story = { - name: 'RadioTile with one long label', - render: () => { - return ( - - - - - - ); - }, -}; - -// export const RadioTileWidth: Story = { -// render: () => { -// return ( -// -// -// -// -// -// -// ); -// }, -// }; diff --git a/packages/react/src/components/RadioTile/RadioTile.tsx b/packages/react/src/components/RadioTile/RadioTile.tsx deleted file mode 100644 index c51cde115..000000000 --- a/packages/react/src/components/RadioTile/RadioTile.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; -import type { ElementRef } from 'react'; - -import { - Indicator as RadixRadioIndicator, - Item as RadixRadioItem, -} from '@radix-ui/react-radio-group'; - -import { RadioTileProps } from './RadioTile.props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import { useIds } from '../../hooks/use-ids'; -import { useFormFieldGroup } from '../FormFieldGroup/FormFieldGroup.context'; -import { Flex } from '../Flex/Flex'; -import { Label } from '../Label/Label'; -import { HelperText } from '../HelperText/HelperText'; - -const componentName = 'RadioTile'; -const componentClassName = withGlobalPrefix(componentName); - -type RadioTileElement = ElementRef<'button'>; - -/** - * `RadioTile` can be used to choose between a set of more than two options. - * - * `RadioTile` should always be used with a `RadioGroup` or `RadioGridGroup` to - * handle the state control and layout. - * - * `RadioTile` is, by default, appropriately labelled when using - * the `label` prop, if you do not provide a label, you must specify an - * `aria-label` or `aria-labelledby` for accessibility. - */ -export const RadioTile = React.forwardRef( - ( - { - id: providedId, - label, - helperText, - disabled, - 'aria-labelledby': ariaLabelledby, - className, - ...props - }, - ref - ) => { - const { id, labelId, helperTextId } = useIds({ providedId, componentPrefix: 'radiotile' }); - const { hasGroupHelperText, 'aria-describedby': ariaDescribedby } = useFormFieldGroup(); - const showHelperText = !hasGroupHelperText && !!helperText; - const showLabel = !!label; - - return ( - - -
- -
- {showLabel ? ( - - - {showHelperText ? ( - - {helperText} - - ) : null} - - ) : null} -
-
- ); - } -); - -RadioTile.displayName = componentName; diff --git a/packages/react/src/components/Strong/Strong.css b/packages/react/src/components/Strong/Strong.css deleted file mode 100644 index d4244c645..000000000 --- a/packages/react/src/components/Strong/Strong.css +++ /dev/null @@ -1,7 +0,0 @@ -.uw-Strong { - font-family: inherit; - font-size: inherit; - font-weight: var(--font-weight-semibold); - line-height: inherit; - color: inherit; -} diff --git a/packages/react/src/components/Strong/Strong.props.ts b/packages/react/src/components/Strong/Strong.props.ts deleted file mode 100644 index 9c94c8eab..000000000 --- a/packages/react/src/components/Strong/Strong.props.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; - -export type StrongProps = ComponentPropsWithout<'strong', RemovedProps>; diff --git a/packages/react/src/components/Strong/Strong.stories.tsx b/packages/react/src/components/Strong/Strong.stories.tsx deleted file mode 100644 index 06c823d42..000000000 --- a/packages/react/src/components/Strong/Strong.stories.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { Strong } from './Strong'; -import { Flex } from '../Flex/Flex'; -import { BodyText } from '../BodyText/BodyText'; - -const textVariants = ['subtitle', 'body', 'legalNote', 'caption'] as const; - -const meta: Meta = { - title: 'Stories / Strong', - component: Strong, -}; - -export default meta; -type Story = StoryObj; - -export const KitchenSink: Story = { - render: () => ( - - {textVariants.map(variant => ( - - The most important thing to remember is, stay positive. - - ))} - - ), -}; diff --git a/packages/react/src/components/Strong/Strong.tsx b/packages/react/src/components/Strong/Strong.tsx deleted file mode 100644 index 44e923e1b..000000000 --- a/packages/react/src/components/Strong/Strong.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { StrongProps } from './Strong.props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; - -import type { ElementRef } from 'react'; - -const componentName = 'Strong'; -const componentClassName = withGlobalPrefix(componentName); - -type StrongElement = ElementRef<'strong'>; - -/** - * The `Em` component is based on the HTML `em` element and is used to indicate - * text that has stress emphasis. `Em` should be wrapped in a `Text` component, and will inherit the parent - * styles. It should __not__ be used within the `Heading` component, as this - * will result in invalid HTML. - */ -export const Strong = React.forwardRef( - ({ className, ...props }, ref) => { - return ; - } -); - -Strong.displayName = componentName; diff --git a/packages/react/src/components/TextLink/TextLink.css b/packages/react/src/components/TextLink/TextLink.css deleted file mode 100644 index c7cdaba33..000000000 --- a/packages/react/src/components/TextLink/TextLink.css +++ /dev/null @@ -1,58 +0,0 @@ -.uw-TextLink { - --text-link-color: var(--color-cyan600); - --text-link-color-active: var(--color-cyan800); - --text-link-color-visited: var(--color-purple700); - --text-link-focus-outline-color: var(--color-cyan700); - - /* unset button styles when asChild is used */ - &:where(button) { - outline: transparent; - appearance: none; - border: none; - background: transparent; - padding: 0; - } - - cursor: pointer; - display: inline; - font-family: inherit; - font-size: inherit; - line-height: inherit; - font-weight: inherit; - color: var(--text-link-color); - text-decoration: underline; - text-decoration-color: var(--text-link-color); - border-radius: 4px; - - &:where(:visited) { - --text-link-color: var(--text-link-color-visited); - } - - @media (hover: hover) { - &:where(:hover) { - text-decoration: none; - } - } - - &:where(:active) { - --text-link-color: var(--text-link-color-active); - } - - &:where(:focus-visible) { - outline: 2px solid var(--text-link-focus-outline-color); - outline-offset: 2px; - } - - &:where([data-color-custom]) { - --text-link-color: var(--text-link-color-custom); - --text-link-color-active: var(--text-link-color-custom); - --text-link-color-visited: var(--text-link-color-custom); - } - - &:has(svg, [data-icon]) { - display: inline-flex; - align-items: center; - flex-shrink: 0; - gap: 4px; - } -} diff --git a/packages/react/src/components/TextLink/TextLink.docs.mdx b/packages/react/src/components/TextLink/TextLink.docs.mdx deleted file mode 100644 index c499daaf8..000000000 --- a/packages/react/src/components/TextLink/TextLink.docs.mdx +++ /dev/null @@ -1,166 +0,0 @@ -import { Meta, Canvas, ArgTypes } from '@storybook/blocks'; - -import * as Stories from './TextLink.stories'; - -import { DocsHeader } from '../../storybook/DocsHeader'; - - - - - - - -- [Semantic HTML](#semantic-html) -- [Guidelines](#guidelines) -- [Size](#size) -- [Colour](#colour) -- [Usage with Next.js](#usage-with-next.js) - - [Next.js v13](#next.js-v13) - - [Next.js before v13](#next.js-before-v13) -- [API](#api) - -## Semantic HTML - -> If it goes somewhere it's a link, if it does something it's a button. - -A semantic HTML `a` is rendered by default, however you can change the -underlying HTML element by using the `asChild` prop. - -When `asChild` is set to true, we will not render a default DOM element, -instead cloning the child and passing it the props and behaviour required to -make it functional. - -Read more about this idea in the [Radix UI composition docs](https://www.radix-ui.com/primitives/docs/guides/composition). - -```tsx -// You may need to disable this eslint warning: -// eslint-disable-next-line jsx-a11y/anchor-is-valid - - - -``` - - - -## Guidelines - -Try and avoid using `target=_blank` if possible: [When to use target="\_blank"](https://css-tricks.com/use-target_blank/). -Though if you do use it, then be aware that [browsers now implicitly set rel=noopener for any target=\_blank link](https://mathiasbynens.github.io/rel-noopener/). - -## Size - -The `TextLink` component must be wrapped in a `Text` component, and will -inherit it's styles, so it's size will be controlled by the parent -`Text` variant. - -## Colour - -You can use the `color` prop to override the `TextLink` colours. This will set -the `active` & `visited` states to the same colour as the default state. If you -set it to `"inherit"` then the `TextLink` component will inherit the colour of -the parent element. - -```tsx -import { Box, Text, TextLink } from "@utilitywarehouse/web-ui"; - -[...] - - - - Text with a{' '} - - TextLink - {' '} - on brand midnight background with custom color - - - - - Text with a{' '} - - TextLink - {' '} - on white background with custom color - - -``` - -> **NOTE:** While it is technically possible to use a custom, or inherited, -> colour, it is not encouraged. - -## Usage with Next.js - -### Next.js v13 - -The Next.js `Link` component behaviour has changed in v13, so that an `` is -no longer required as a child. You can render the Web UI `TextLink` component as a -Next.js `Link` component using `asChild`: - -```tsx -import NextLink from 'next/link'; -import { TextLink } from '@utilitywarehouse/ds-react'; - -[...] - -{/* // eslint-disable-next-line jsx-a11y/anchor-is-valid */} - - - {title} - - -``` - -You can also use the `legacyBehavior` prop directly on the Next.js Link component: - -```tsx -import NextLink from 'next/link'; -import { TextLink } from '@utilitywarehouse/ds-react'; - -[...] - - - {/* // eslint-disable-next-line jsx-a11y/anchor-is-valid */} - {title} - -``` - -And if you want to set this behavior globally you can use the following Next.js -configuration: - -``` -{ - experimental: { - newNextLinkBehavior: false - } -} -``` - -### Next.js before v13 - -```tsx -import NextLink from 'next/link'; -import { TextLink } from '@utilitywarehouse/ds-react'; - -[...] - - - {/* // eslint-disable-next-line jsx-a11y/anchor-is-valid */} - {title} - -``` - -## API - -This component is based on the `a` element. - -| Prop | Type | Description | Default | -| --------- | --------- | ----------------------------------------------------------------------------------------------------- | ----------------- | -| `color` | `string` | Override the default TextLink colours. | `--color-grey175` | -| `asChild` | `boolean` | Change the default rendered element for the one passed as a child, merging their props and behaviour. | `false` | diff --git a/packages/react/src/components/TextLink/TextLink.props.ts b/packages/react/src/components/TextLink/TextLink.props.ts deleted file mode 100644 index 28c95f803..000000000 --- a/packages/react/src/components/TextLink/TextLink.props.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { ComponentPropsWithout, RemovedProps } from '../../types/component-props'; - -export interface TextLinkProps extends ComponentPropsWithout<'a', RemovedProps> { - /** - * Sets the text colour. - * It is recommended to use the colours from the `@utilitywarehouse/colour-system` package. - * - * @default color.cyan600 - */ - color?: string; - /** - * Change the default rendered element for the one passed as a child, merging their props and behaviour. - */ - asChild?: boolean; -} diff --git a/packages/react/src/components/TextLink/TextLink.stories.tsx b/packages/react/src/components/TextLink/TextLink.stories.tsx deleted file mode 100644 index ea9fc3c5c..000000000 --- a/packages/react/src/components/TextLink/TextLink.stories.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import * as React from 'react'; - -import type { Meta, StoryObj } from '@storybook/react'; - -import { colors } from '@utilitywarehouse/colour-system'; -import { ChevronRightMediumIcon, OpenMediumIcon } from '@utilitywarehouse/react-icons'; - -import { TextLink } from './TextLink'; -import { Flex } from '../Flex/Flex'; -import { BodyText } from '../BodyText/BodyText'; - -const meta: Meta = { - title: 'Stories / TextLink', - component: TextLink, - argTypes: { - children: { control: { type: 'text' } }, - href: { control: { type: 'text' } }, - color: { control: { type: 'text' } }, - }, -}; - -export default meta; -type Story = StoryObj; - -const variants = ['subtitle', 'body', 'legalNote', 'caption'] as const; - -export const Workshop: Story = { - render: args => ( - - - - - - Agnes Martin was an American abstract painter known for her{' '} - minimalist style. Martin's art was characterized by - serene compositions featuring grids and lines. Martin's - minimalist approach conveyed tranquility and spirituality, - and her paintings often carried positive names reflective of her{' '} - philosophy. - - - ), - args: { - children: 'TextLink', - href: '#', - }, -}; - -export const KitchenSink: Story = { - render: () => { - return ( - - {variants.map(variant => ( - - - {variant} TextLink - - - ))} - - ); - }, -}; - -export const WithinText: Story = { - name: 'In a block of text', - render: () => { - return ( - - {variants.map(variant => ( - - This is the {variant} text style, and it contains{' '} - an embedded link within this text. - - ))} - - ); - }, -}; - -export const WithIcons: Story = { - render: args => ( - - - Learn More - - - - Open in a new tab - - - - ), -}; - -export const AsButton: Story = { - render: () => ( - - - - - - ), -}; - -export const LengthyContent: Story = { - render: args => ( - - - To limit spend on international calls, turn on Budget Control and then{' '} - {args.children}. - - - ), - args: { children: 'follow our handy guide to set your International call cap' }, -}; diff --git a/packages/react/src/components/TextLink/TextLink.tsx b/packages/react/src/components/TextLink/TextLink.tsx deleted file mode 100644 index f11f08139..000000000 --- a/packages/react/src/components/TextLink/TextLink.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import * as React from 'react'; - -import clsx from 'clsx'; - -import { Slot } from '@radix-ui/react-slot'; - -import type { TextLinkProps } from './TextLink.props'; -import { withGlobalPrefix } from '../../helpers/with-global-prefix'; -import type { ElementRef } from 'react'; - -const componentName = 'TextLink'; -const componentClassName = withGlobalPrefix(componentName); - -type TextLinkElement = ElementRef<'a'>; - -/** - * A semantic element for navigating between pages. The `TextLink` component is - * intended to be used within a block of text, and should be nested in a `Text` - * component. This should happen even when using as a standalone link element - * as it will inherit many styles from the parent `Text` component. - */ -export const TextLink = React.forwardRef( - ({ className, color, asChild, children, style, ...props }, ref) => { - const styleProps = { '--text-link-color-custom': color, ...style }; - return ( - - {asChild ? children : {children}} - - ); - } -); - -TextLink.displayName = componentName; diff --git a/packages/react/src/components/index.css b/packages/react/src/components/index.css deleted file mode 100644 index 860ea3678..000000000 --- a/packages/react/src/components/index.css +++ /dev/null @@ -1,27 +0,0 @@ -@import url('./Box/Box.css'); -@import url('./Flex/Flex.css'); -@import url('./BodyText/BodyText.css'); -@import url('./ButtonBase/ButtonBase.css'); -@import url('./Button/Button.css'); -@import url('./Heading/Heading.css'); -@import url('./IconButton/IconButton.css'); -@import url('./Label/Label.css'); -@import url('./HelperText/HelperText.css'); -@import url('./Radio/Radio.css'); -@import url('./FieldsetLegend/FieldsetLegend.css'); -@import url('./Fieldset/Fieldset.css'); -@import url('./RadioGroup/RadioGroup.css'); -@import url('./RadioTile/RadioTile.css'); -@import url('./RadioGridGroup/RadioGridGroup.css'); -@import url('./Link/Link.css'); -@import url('./TextLink/TextLink.css'); -@import url('./Em/Em.css'); -@import url('./Strong/Strong.css'); -@import url('./Divider/Divider.css'); -@import url('./Badge/Badge.css'); -@import url('./Checkbox/Checkbox.css'); -@import url('./CheckboxBase/CheckboxBase.css'); -@import url('./CheckboxGroup/CheckboxGroup.css'); -@import url('./CheckboxTile/CheckboxTile.css'); -@import url('./CheckboxGridGroup/CheckboxGridGroup.css'); -@import url('./Alert/Alert.css'); diff --git a/packages/react/src/components/index.ts b/packages/react/src/components/index.ts deleted file mode 100644 index 104620c3f..000000000 --- a/packages/react/src/components/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -export { Box } from './Box/Box'; -export type { BoxProps } from './Box/Box.props'; - -export { BodyText } from './BodyText/BodyText'; -export type { BodyTextProps } from './BodyText/BodyText.props'; - -export { Flex } from './Flex/Flex'; -export type { FlexProps } from './Flex/Flex.props'; - -export { Divider } from './Divider/Divider'; -export type { DividerProps } from './Divider/Divider.props'; diff --git a/packages/react/src/helpers/data-attributes.ts b/packages/react/src/helpers/data-attributes.ts deleted file mode 100644 index 4d983b337..000000000 --- a/packages/react/src/helpers/data-attributes.ts +++ /dev/null @@ -1,9 +0,0 @@ -function withDataPrefix(name: string) { - return `data-${name}`; -} - -/* a set of data-attributes used for styling */ -export const DATA_ATTRIBUTES = { - colorscheme: withDataPrefix('colorscheme'), - disableUserSelect: withDataPrefix('disable-user-select'), -}; diff --git a/packages/react/src/helpers/extract-props.ts b/packages/react/src/helpers/extract-props.ts deleted file mode 100644 index d98e4968a..000000000 --- a/packages/react/src/helpers/extract-props.ts +++ /dev/null @@ -1,34 +0,0 @@ -import clsx from 'clsx'; -import { mergeStyles } from './merge-styles'; -import { getClassNameStyles } from './get-classname-styles'; -import { PropDef } from '../props/prop-def'; - -/* eslint-disable @typescript-eslint/no-explicit-any */ -export function extractProps< - P extends { className?: string; style?: React.CSSProperties; [key: string]: any }, - T extends Array>, ->(props: P, ...propDefs: T) { - const allPropDefs: Record = Object.assign({}, ...propDefs); - const extractedProps = { ...props }; - let className: string | undefined; - let style: ReturnType; - - for (const key in allPropDefs) { - const value = extractedProps[key]; - delete extractedProps[key]; - const tokens = allPropDefs[key]?.tokens; - const prefix = allPropDefs[key]?.className; - const { className: propClassName, style: propStyle } = getClassNameStyles({ - value, - prefix, - defaultValue: allPropDefs[key]?.default, - tokens, - isResponsive: Boolean(allPropDefs[key]?.responsive), - }); - className = clsx(className, propClassName); - style = mergeStyles(style, propStyle); - } - extractedProps.className = clsx(className, props.className); - extractedProps.style = mergeStyles(style, props.style); - return extractedProps; -} diff --git a/packages/react/src/helpers/get-classname-styles.ts b/packages/react/src/helpers/get-classname-styles.ts deleted file mode 100644 index 84c0bd16d..000000000 --- a/packages/react/src/helpers/get-classname-styles.ts +++ /dev/null @@ -1,72 +0,0 @@ -import type { Breakpoints, Responsive } from '../types/responsive'; -import { isResponsiveObject } from './is-responsive-object'; -import { GLOBAL_PREFIX } from './with-global-prefix'; - -type GetClassNameStylesOptions = { - value: Responsive | undefined; - prefix: string | undefined; - tokens: ReadonlyArray | undefined; - isResponsive: boolean; - defaultValue?: string | number; -}; - -export const getClassNameStyles = ({ - value, - prefix, - tokens, - isResponsive, - defaultValue, -}: GetClassNameStylesOptions) => { - const responsivePrefix = isResponsive ? '-r' : ''; - - if (value === undefined && defaultValue) { - return { className: `${GLOBAL_PREFIX}${responsivePrefix}-${prefix}-${defaultValue}` }; - } - - if (typeof value === 'string' || typeof value === 'number') { - const isTokenValue = tokens?.includes(value); - if (isTokenValue) { - return { className: `${GLOBAL_PREFIX}${responsivePrefix}-${prefix}-${value}` }; - } - return { - className: `${GLOBAL_PREFIX}${responsivePrefix}-${prefix}`, - style: { [`-${responsivePrefix}-${prefix}`]: value || defaultValue }, - }; - } - - if (isResponsiveObject(value)) { - const initialBreakpoint = 'mobile'; - - const classes = (Object.keys(value) as Array).map(bp => { - const breakpointValue = value[bp]; - if (breakpointValue !== undefined) { - const isTokenValue = tokens?.includes(breakpointValue); - let baseClassName: string; - if (isTokenValue) { - baseClassName = `${GLOBAL_PREFIX}${responsivePrefix}-${prefix}-${breakpointValue}`; - } else { - baseClassName = `${GLOBAL_PREFIX}${responsivePrefix}-${prefix}`; - } - const className = bp === initialBreakpoint ? baseClassName : `${bp}:${baseClassName}`; - return className; - } - }); - - const styles = (Object.keys(value) as Array).reduce( - (acc: { [key: string]: string | number }, bp: Breakpoints) => { - const breakpointValue = value[bp]; - const isTokenValue = tokens?.includes(breakpointValue); - if (breakpointValue !== undefined && !isTokenValue) { - const baseStyleName = `-${responsivePrefix}-${prefix}`; - const styleName = bp === initialBreakpoint ? baseStyleName : `${baseStyleName}-${bp}`; - acc[styleName] = breakpointValue; - return acc; - } - return acc; - }, - {} - ); - return { className: classes.join(' '), style: styles }; - } - return { className: '', styles: {} }; -}; diff --git a/packages/react/src/helpers/is-responsive-object.ts b/packages/react/src/helpers/is-responsive-object.ts deleted file mode 100644 index a7cb896a8..000000000 --- a/packages/react/src/helpers/is-responsive-object.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { breakpoints, type Breakpoint, type Responsive } from '../types/responsive'; - -export function isResponsiveObject( - obj: Responsive> | undefined -): obj is Record { - return ( - typeof obj === 'object' && - Object.keys(obj).some(key => (breakpoints as unknown as ReadonlyArray).includes(key)) - ); -} diff --git a/packages/react/src/helpers/merge-ids.ts b/packages/react/src/helpers/merge-ids.ts deleted file mode 100644 index 3f82bc1e7..000000000 --- a/packages/react/src/helpers/merge-ids.ts +++ /dev/null @@ -1,10 +0,0 @@ -// https://github.com/seek-oss/braid-design-system/blob/master/packages/braid-design-system/src/lib/components/private/mergeIds.ts -export const mergeIds = (...ids: Array) => { - const validIds = ids.filter(Boolean); - - if (validIds.length === 0) { - return undefined; - } - - return validIds.join(' '); -}; diff --git a/packages/react/src/helpers/merge-styles.ts b/packages/react/src/helpers/merge-styles.ts deleted file mode 100644 index 6a72d3930..000000000 --- a/packages/react/src/helpers/merge-styles.ts +++ /dev/null @@ -1,17 +0,0 @@ -type InlineStyle = - | React.CSSProperties - | Record - | undefined; - -// Merges CSS styles like `classNames` merges CSS classes -export function mergeStyles(...styles: Array): InlineStyle { - let result: InlineStyle = {}; - - for (const style of styles) { - if (style) { - result = { ...result, ...style }; - } - } - - return Object.keys(result).length ? result : undefined; -} diff --git a/packages/react/src/helpers/with-global-prefix.ts b/packages/react/src/helpers/with-global-prefix.ts deleted file mode 100644 index d3fe39b2c..000000000 --- a/packages/react/src/helpers/with-global-prefix.ts +++ /dev/null @@ -1,7 +0,0 @@ -/* The global prefix, mostly used with component class names */ -export const GLOBAL_PREFIX = 'uw'; - -/* returns the given value prefixed with the global prefix */ -export function withGlobalPrefix(name: string) { - return `${GLOBAL_PREFIX}-${name}`; -} diff --git a/packages/react/src/hooks/use-ids.ts b/packages/react/src/hooks/use-ids.ts deleted file mode 100644 index 346946e67..000000000 --- a/packages/react/src/hooks/use-ids.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { useId } from 'react'; - -import { withGlobalPrefix } from '../helpers/with-global-prefix'; - -interface UseIdsProps { - providedId?: string; - providedLabelId?: string; - providedHelperTextId?: string; - providedErrorMessageId?: string; - componentPrefix?: string; -} - -export const useIds = ({ - providedId, - providedLabelId, - providedHelperTextId, - providedErrorMessageId, - componentPrefix, -}: UseIdsProps) => { - const generatedId = useId(); - const defaultId = withGlobalPrefix( - componentPrefix ? `${componentPrefix}-${generatedId}` : generatedId - ); - const id = providedId || defaultId; - const labelId = providedLabelId || `${defaultId}-label`; - const helperTextId = providedHelperTextId || `${defaultId}-helper-text`; - const errorMessageId = providedErrorMessageId || `${defaultId}-error-message`; - return { id, labelId, helperTextId, errorMessageId }; -}; diff --git a/packages/react/src/hooks/use-media-query.ts b/packages/react/src/hooks/use-media-query.ts deleted file mode 100644 index f0461d770..000000000 --- a/packages/react/src/hooks/use-media-query.ts +++ /dev/null @@ -1,75 +0,0 @@ -import * as React from 'react'; - -// gratefully copied from MUI -> https://github.com/mui/material-ui/blob/master/packages/mui-system/src/useMediaQuery/useMediaQuery.ts - -export interface UseMediaQueryOptions { - /** - * As `window.matchMedia()` is unavailable on the server, - * this is the default value to return. - * @default false - */ - defaultValue?: boolean; - /** - * To perform the server-side hydration, the hook needs to render twice. - * A first time with `defaultValue`, the value of the server, and a second time with the resolved value. - * This double pass rendering cycle comes with a drawback: it's slower. - * In SSR, you should set it to `true`, returning `options.defaultValue` or `false` initially. - * @default false - */ - initializeWithDefaultValue?: boolean; -} - -/** - * Custom hook that tracks the state of a media query using the [`Match Media API`](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia). - * @param {string} query - The media query to track. - * @param {?UseMediaQueryOptions} [options] - The options for customizing the behavior of the hook (optional). - * @returns {boolean} The current state of the media query (true if the query matches, false otherwise). - * @see [Documentation](https://uw-web-ui.vercel.app/?path=/docs/web-ui-helpers-media-queries--documentation##usemediaqueries-hook) - * @example - * ```tsx - * import { useMediaQuery, media } from '@utilitywarehouse/ds-react'; - * - * const isMobileOrTablet = useMediaQuery(media.below('desktop')); - * // Use `isMobileOrTablet ` to conditionally apply styles or logic based on the screen size. - * ``` - */ -export function useMediaQuery(query: string, options: UseMediaQueryOptions = {}): boolean { - const { defaultValue = false, initializeWithDefaultValue = false } = options; - - query = query.replace(/^@media( ?)/m, ''); - - const getDefaultSnapshot = React.useCallback(() => defaultValue, [defaultValue]); - const getServerSnapshot = React.useMemo(() => { - if (initializeWithDefaultValue) { - return getDefaultSnapshot; - } - return () => window.matchMedia(query).matches; - }, [getDefaultSnapshot, query, initializeWithDefaultValue]); - - const [getSnapshot, subscribe] = React.useMemo(() => { - if (window.matchMedia === null) { - return [getDefaultSnapshot, () => () => {}]; - } - - const mediaQueryList = window.matchMedia(query); - - return [ - () => mediaQueryList.matches, - (notify: () => void) => { - mediaQueryList.addEventListener('change', notify); - return () => { - mediaQueryList.removeEventListener('change', notify); - }; - }, - ]; - }, [getDefaultSnapshot, query]); - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call - const match = React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot); - - if (process.env.NODE_ENV !== 'production') { - // eslint-disable-next-line react-hooks/rules-of-hooks - React.useDebugValue({ query, match }); - } - - return match; -} diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts deleted file mode 100644 index 07635cbbc..000000000 --- a/packages/react/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './components'; diff --git a/packages/react/src/props/color.props.ts b/packages/react/src/props/color.props.ts deleted file mode 100644 index 93b0f900e..000000000 --- a/packages/react/src/props/color.props.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { PropDef } from './prop-def'; - -const colorPropDefs = { - color: { className: 'color', responsive: false }, - backgroundColor: { className: 'background-color', responsive: false }, -} satisfies { - color: PropDef; - backgroundColor: PropDef; -}; - -interface ColorProps { - /** - * Set the foreground colour. - * It is recommended to use the colours from the `@utilitywarehouse/colour-system` package. - */ - color?: string; - /** - * Set the background colour. - * It is recommended to use the colours from the `@utilitywarehouse/colour-system` package. - */ - backgroundColor?: string; -} - -export { colorPropDefs }; -export type { ColorProps }; diff --git a/packages/react/src/props/columns.props.ts b/packages/react/src/props/columns.props.ts deleted file mode 100644 index 61d936a0d..000000000 --- a/packages/react/src/props/columns.props.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Responsive } from '../types/responsive'; -import { PropDef } from './prop-def'; - -const columnsPropDefs = { - columns: { className: 'columns', responsive: true }, -} satisfies { - columns: PropDef; -}; - -interface ColumnsProps { - /** Sets the number of columns to display the contents in. */ - columns?: Responsive; -} - -export { columnsPropDefs }; -export type { ColumnsProps }; diff --git a/packages/react/src/props/gap.props.ts b/packages/react/src/props/gap.props.ts deleted file mode 100644 index ee60d0840..000000000 --- a/packages/react/src/props/gap.props.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Responsive, Union } from '../types/responsive'; -import { PropDef } from './prop-def'; - -const gapTokens = [ - '0', - '25', - '50', - '75', - '100', - '150', - '200', - '250', - '300', - '350', - '400', - '500', - '600', - '700', - '800', - '900', - '1000', -] as const; - -const gapPropDefs = { - gap: { className: 'gap', tokens: gapTokens, responsive: true }, -} satisfies { - gap: PropDef<(typeof gapTokens)[number]>; -}; - -interface GapProps { - gap?: Responsive>; -} - -export { gapPropDefs, gapTokens }; -export type { GapProps }; diff --git a/packages/react/src/props/padding.props.ts b/packages/react/src/props/padding.props.ts deleted file mode 100644 index 1b58b871f..000000000 --- a/packages/react/src/props/padding.props.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Responsive, Union } from '../types/responsive'; -import { PropDef } from './prop-def'; - -const paddingTokens = [ - '0', - '25', - '50', - '75', - '100', - '150', - '200', - '250', - '300', - '350', - '400', - '500', - '600', - '700', - '800', - '900', - '1000', -] as const; - -const paddingPropDefs = { - padding: { className: 'padding', tokens: paddingTokens, responsive: true }, - paddingTop: { className: 'padding-top', tokens: paddingTokens, responsive: true }, - paddingRight: { className: 'padding-right', tokens: paddingTokens, responsive: true }, - paddingBottom: { className: 'padding-bottom', tokens: paddingTokens, responsive: true }, - paddingLeft: { className: 'padding-left', tokens: paddingTokens, responsive: true }, - paddingInline: { className: 'padding-inline', tokens: paddingTokens, responsive: true }, - paddingBlock: { className: 'padding-block', tokens: paddingTokens, responsive: true }, -} satisfies { - padding: PropDef<(typeof paddingTokens)[number]>; - paddingTop: PropDef<(typeof paddingTokens)[number]>; - paddingRight: PropDef<(typeof paddingTokens)[number]>; - paddingBottom: PropDef<(typeof paddingTokens)[number]>; - paddingLeft: PropDef<(typeof paddingTokens)[number]>; - paddingInline: PropDef<(typeof paddingTokens)[number]>; - paddingBlock: PropDef<(typeof paddingTokens)[number]>; -}; - -interface PaddingProps { - padding?: Responsive>; - paddingTop?: Responsive>; - paddingRight?: Responsive>; - paddingBottom?: Responsive>; - paddingLeft?: Responsive>; - paddingInline?: Responsive>; - paddingBlock?: Responsive>; -} - -export { paddingPropDefs, paddingTokens }; -export type { PaddingProps }; diff --git a/packages/react/src/props/prop-def.ts b/packages/react/src/props/prop-def.ts deleted file mode 100644 index 702cf4890..000000000 --- a/packages/react/src/props/prop-def.ts +++ /dev/null @@ -1,6 +0,0 @@ -export type PropDef = { - tokens?: ReadonlyArray; - className: string; - default?: string | number; - responsive: boolean; -}; diff --git a/packages/react/src/props/size.props.ts b/packages/react/src/props/size.props.ts deleted file mode 100644 index e3556cc38..000000000 --- a/packages/react/src/props/size.props.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Responsive } from '../types/responsive'; -import { PropDef } from './prop-def'; - -const sizePropDefs = { - width: { className: 'width', responsive: true }, - maxWidth: { className: 'max-width', responsive: true }, - minWidth: { className: 'min-width', responsive: true }, - height: { className: 'height', responsive: true }, - maxHeight: { className: 'max-height', responsive: true }, - minHeight: { className: 'min-height', responsive: true }, -} satisfies { - width: PropDef; - maxWidth: PropDef; - minWidth: PropDef; - height: PropDef; - maxHeight: PropDef; - minHeight: PropDef; -}; - -interface SizeProps { - width?: Responsive; - maxWidth?: Responsive; - minWidth?: Responsive; - height?: Responsive; - maxHeight?: Responsive; - minHeight?: Responsive; -} - -export type { SizeProps }; -export { sizePropDefs }; diff --git a/packages/react/src/props/text-align.props.ts b/packages/react/src/props/text-align.props.ts deleted file mode 100644 index 7fca2a2c1..000000000 --- a/packages/react/src/props/text-align.props.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Responsive } from '../types/responsive'; -import { PropDef } from './prop-def'; - -const textAlignValues = ['left', 'center', 'right'] as const; - -const textAlignPropDefs = { - align: { className: 'text-align', tokens: textAlignValues, responsive: true }, -} satisfies { - align: PropDef<(typeof textAlignValues)[number]>; -}; - -interface TextAlignProps { - /** - * Set the text-align on the component. - */ - align?: Responsive<(typeof textAlignValues)[number]>; -} - -export { textAlignPropDefs }; -export type { TextAlignProps }; diff --git a/packages/react/src/storybook/DocsHeader.tsx b/packages/react/src/storybook/DocsHeader.tsx deleted file mode 100644 index 2623b9913..000000000 --- a/packages/react/src/storybook/DocsHeader.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import * as React from 'react'; - -import { Unstyled, Description } from '@storybook/blocks'; -import { Flex } from '../components/Flex/Flex'; -import { Heading } from '../components/Heading/Heading'; -import { Link } from '../components/Link/Link'; - -interface DocsHeaderProps { - componentName: string; - figmaLink?: string; - themeProviderRequired?: boolean; - stories: React.ReactNode; -} - -export const DocsHeader = ({ componentName, figmaLink, stories }: DocsHeaderProps) => ( - - - - {componentName} - - Stories - - Source - - {figmaLink ? Design : null} - - - - - -); diff --git a/packages/react/src/storybook/styles.css b/packages/react/src/storybook/styles.css deleted file mode 100644 index 1843d1bcf..000000000 --- a/packages/react/src/storybook/styles.css +++ /dev/null @@ -1,6 +0,0 @@ -.uw-sb-Placeholder { - border: 1px solid var(--color-grey100); - background-color: var(--color-grey75); - border-width: 2px; - border-radius: 4px; -} diff --git a/packages/react/src/styles/align-items.css b/packages/react/src/styles/align-items.css deleted file mode 100644 index 0f99b4ce7..000000000 --- a/packages/react/src/styles/align-items.css +++ /dev/null @@ -1,33 +0,0 @@ -@breakpoints { - .uw-r-align-items-start { - align-items: flex-start; - } - - .uw-r-align-items-center { - align-items: center; - } - - .uw-r-align-items-end { - align-items: flex-end; - } - - .uw-r-align-items-baseline { - align-items: baseline; - } - - .uw-r-align-items-stretch { - align-items: stretch; - } - - .uw-r-align-items-space-between { - align-items: space-between; - } - - .uw-r-align-items-space-around { - align-items: space-between; - } - - .uw-r-align-items-space-evenly { - align-items: space-between; - } -} diff --git a/packages/react/src/styles/breakpoints.css b/packages/react/src/styles/breakpoints.css deleted file mode 100644 index 68742beed..000000000 --- a/packages/react/src/styles/breakpoints.css +++ /dev/null @@ -1,3 +0,0 @@ -@custom-media --tablet (min-width: 740px); -@custom-media --desktop (min-width: 992px); -@custom-media --wide (min-width: 1200px); diff --git a/packages/react/src/styles/color.css b/packages/react/src/styles/color.css deleted file mode 100644 index 26c329e4f..000000000 --- a/packages/react/src/styles/color.css +++ /dev/null @@ -1,7 +0,0 @@ -.uw-color { - color: var(--color); -} - -.uw-background-color { - background-color: var(--background-color); -} diff --git a/packages/react/src/styles/columns.css b/packages/react/src/styles/columns.css deleted file mode 100644 index d3283ccde..000000000 --- a/packages/react/src/styles/columns.css +++ /dev/null @@ -1,5 +0,0 @@ -@breakpoints { - .uw-r-columns { - grid-template-columns: repeat(var(--r-columns), minmax(10px, 1fr)); - } -} diff --git a/packages/react/src/styles/disable-user-select.css b/packages/react/src/styles/disable-user-select.css deleted file mode 100644 index 3a2e0a2d6..000000000 --- a/packages/react/src/styles/disable-user-select.css +++ /dev/null @@ -1,3 +0,0 @@ -:where([data-disable-user-select]) { - user-select: none; -} diff --git a/packages/react/src/styles/display.css b/packages/react/src/styles/display.css deleted file mode 100644 index 4610225bc..000000000 --- a/packages/react/src/styles/display.css +++ /dev/null @@ -1,33 +0,0 @@ -@breakpoints { - .uw-r-display-block { - display: block; - } - - .uw-r-display-inline { - display: inline; - } - - .uw-r-display-inline-block { - display: inline-block; - } - - .uw-r-display-flex { - display: flex; - } - - .uw-r-display-inline-flex { - display: inline-flex; - } - - .uw-r-display-grid { - display: grid; - } - - .uw-r-display-inline-grid { - display: inline-grid; - } - - .uw-r-display-none { - display: none; - } -} diff --git a/packages/react/src/styles/flex-direction.css b/packages/react/src/styles/flex-direction.css deleted file mode 100644 index a3a3aff10..000000000 --- a/packages/react/src/styles/flex-direction.css +++ /dev/null @@ -1,17 +0,0 @@ -@breakpoints { - .uw-r-flex-direction-row { - flex-direction: row; - } - - .uw-r-flex-direction-column { - flex-direction: column; - } - - .uw-r-flex-direction-row-reverse { - flex-direction: row-reverse; - } - - .uw-r-flex-direction-column-reverse { - flex-direction: column-reverse; - } -} diff --git a/packages/react/src/styles/font-weight.css b/packages/react/src/styles/font-weight.css deleted file mode 100644 index e43c4b45b..000000000 --- a/packages/react/src/styles/font-weight.css +++ /dev/null @@ -1,17 +0,0 @@ -@breakpoints { - .uw-r-weight-regular { - font-weight: var(--font-weight-regular); - } - - .uw-r-weight-medium { - font-weight: var(--font-weight-medium); - } - - .uw-r-weight-semibold { - font-weight: var(--font-weight-semibold); - } - - .uw-r-weight-bold { - font-weight: var(--font-weight-bold); - } -} diff --git a/packages/react/src/styles/gap.css b/packages/react/src/styles/gap.css deleted file mode 100644 index c858b93d5..000000000 --- a/packages/react/src/styles/gap.css +++ /dev/null @@ -1,73 +0,0 @@ -@breakpoints { - .uw-r-gap { - gap: var(--r-gap); - } - - .uw-r-gap-0 { - gap: 0; - } - - .uw-r-gap-25 { - gap: var(--space-25); - } - - .uw-r-gap-50 { - gap: var(--space-50); - } - - .uw-r-gap-75 { - gap: var(--space-75); - } - - .uw-r-gap-100 { - gap: var(--space-100); - } - - .uw-r-gap-150 { - gap: var(--space-150); - } - - .uw-r-gap-200 { - gap: var(--space-200); - } - - .uw-r-gap-250 { - gap: var(--space-250); - } - - .uw-r-gap-300 { - gap: var(--space-300); - } - - .uw-r-gap-350 { - gap: var(--space-350); - } - - .uw-r-gap-400 { - gap: var(--space-400); - } - - .uw-r-gap-500 { - gap: var(--space-500); - } - - .uw-r-gap-600 { - gap: var(--space-600); - } - - .uw-r-gap-700 { - gap: var(--space-700); - } - - .uw-r-gap-800 { - gap: var(--space-800); - } - - .uw-r-gap-900 { - gap: var(--space-900); - } - - .uw-r-gap-1000 { - gap: var(--space-1000); - } -} diff --git a/packages/react/src/styles/index.css b/packages/react/src/styles/index.css deleted file mode 100644 index 0c852db95..000000000 --- a/packages/react/src/styles/index.css +++ /dev/null @@ -1,16 +0,0 @@ -@import url('./tokens/typography.css'); -@import url('./tokens/space.css'); -@import url('../components/index.css'); -@import url('./breakpoints.css'); -@import url('./padding.css'); -@import url('./text-align.css'); -@import url('./font-weight.css'); -@import url('./display.css'); -@import url('./flex-direction.css'); -@import url('./gap.css'); -@import url('./color.css'); -@import url('./align-items.css'); -@import url('./justify-content.css'); -@import url('./disable-user-select.css'); -@import url('./size.css'); -@import url('./columns.css'); diff --git a/packages/react/src/styles/justify-content.css b/packages/react/src/styles/justify-content.css deleted file mode 100644 index ba7968689..000000000 --- a/packages/react/src/styles/justify-content.css +++ /dev/null @@ -1,33 +0,0 @@ -@breakpoints { - .uw-r-justify-content-start { - justify-content: flex-start; - } - - .uw-r-justify-content-center { - justify-content: center; - } - - .uw-r-justify-content-end { - justify-content: flex-end; - } - - .uw-r-justify-content-baseline { - justify-content: baseline; - } - - .uw-r-justify-content-stretch { - justify-content: stretch; - } - - .uw-r-justify-content-space-between { - justify-content: space-between; - } - - .uw-r-justify-content-space-around { - justify-content: space-around; - } - - .uw-r-justify-content-space-evenly { - justify-content: space-evenly; - } -} diff --git a/packages/react/src/styles/padding.css b/packages/react/src/styles/padding.css deleted file mode 100644 index c4736c16a..000000000 --- a/packages/react/src/styles/padding.css +++ /dev/null @@ -1,517 +0,0 @@ -@breakpoints { - .uw-r-padding { - padding: var(--r-padding); - } - - .uw-r-padding-0 { - padding: 0; - } - - .uw-r-padding-25 { - padding: var(--space-25); - } - - .uw-r-padding-50 { - padding: var(--space-50); - } - - .uw-r-padding-75 { - padding: var(--space-75); - } - - .uw-r-padding-100 { - padding: var(--space-100); - } - - .uw-r-padding-150 { - padding: var(--space-150); - } - - .uw-r-padding-200 { - padding: var(--space-200); - } - - .uw-r-padding-250 { - padding: var(--space-250); - } - - .uw-r-padding-300 { - padding: var(--space-300); - } - - .uw-r-padding-350 { - padding: var(--space-350); - } - - .uw-r-padding-400 { - padding: var(--space-400); - } - - .uw-r-padding-500 { - padding: var(--space-500); - } - - .uw-r-padding-600 { - padding: var(--space-600); - } - - .uw-r-padding-700 { - padding: var(--space-700); - } - - .uw-r-padding-800 { - padding: var(--space-800); - } - - .uw-r-padding-900 { - padding: var(--space-900); - } - - .uw-r-padding-1000 { - padding: var(--space-1000); - } -} - -@breakpoints { - .uw-r-padding-inline { - padding-inline: var(--r-padding-inline); - } - - .uw-r-padding-inline-0 { - padding-inline: 0; - } - - .uw-r-padding-inline-25 { - padding-inline: var(--space-25); - } - - .uw-r-padding-inline-50 { - padding-inline: var(--space-50); - } - - .uw-r-padding-inline-75 { - padding-inline: var(--space-75); - } - - .uw-r-padding-inline-100 { - padding-inline: var(--space-100); - } - - .uw-r-padding-inline-150 { - padding-inline: var(--space-150); - } - - .uw-r-padding-inline-200 { - padding-inline: var(--space-200); - } - - .uw-r-padding-inline-250 { - padding-inline: var(--space-250); - } - - .uw-r-padding-inline-300 { - padding-inline: var(--space-300); - } - - .uw-r-padding-inline-350 { - padding-inline: var(--space-350); - } - - .uw-r-padding-inline-400 { - padding-inline: var(--space-400); - } - - .uw-r-padding-inline-500 { - padding-inline: var(--space-500); - } - - .uw-r-padding-inline-600 { - padding-inline: var(--space-600); - } - - .uw-r-padding-inline-700 { - padding-inline: var(--space-700); - } - - .uw-r-padding-inline-800 { - padding-inline: var(--space-800); - } - - .uw-r-padding-inline-900 { - padding-inline: var(--space-900); - } - - .uw-r-padding-inline-1000 { - padding-inline: var(--space-1000); - } -} - -@breakpoints { - .uw-r-padding-block { - padding-block: var(--r-padding-block); - } - - .uw-r-padding-block-0 { - padding-block: 0; - } - - .uw-r-padding-block-25 { - padding-block: var(--space-25); - } - - .uw-r-padding-block-50 { - padding-block: var(--space-50); - } - - .uw-r-padding-block-75 { - padding-block: var(--space-75); - } - - .uw-r-padding-block-100 { - padding-block: var(--space-100); - } - - .uw-r-padding-block-150 { - padding-block: var(--space-150); - } - - .uw-r-padding-block-200 { - padding-block: var(--space-200); - } - - .uw-r-padding-block-250 { - padding-block: var(--space-250); - } - - .uw-r-padding-block-300 { - padding-block: var(--space-300); - } - - .uw-r-padding-block-350 { - padding-block: var(--space-350); - } - - .uw-r-padding-block-400 { - padding-block: var(--space-400); - } - - .uw-r-padding-block-500 { - padding-block: var(--space-500); - } - - .uw-r-padding-block-600 { - padding-block: var(--space-600); - } - - .uw-r-padding-block-700 { - padding-block: var(--space-700); - } - - .uw-r-padding-block-800 { - padding-block: var(--space-800); - } - - .uw-r-padding-block-900 { - padding-block: var(--space-900); - } - - .uw-r-padding-block-1000 { - padding-block: var(--space-1000); - } -} - -@breakpoints { - .uw-r-padding-top { - padding-top: var(--r-padding-top); - } - - .uw-r-padding-top-0 { - padding-top: 0; - } - - .uw-r-padding-top-25 { - padding-top: var(--space-25); - } - - .uw-r-padding-top-50 { - padding-top: var(--space-50); - } - - .uw-r-padding-top-75 { - padding-top: var(--space-75); - } - - .uw-r-padding-top-100 { - padding-top: var(--space-100); - } - - .uw-r-padding-top-150 { - padding-top: var(--space-150); - } - - .uw-r-padding-top-200 { - padding-top: var(--space-200); - } - - .uw-r-padding-top-250 { - padding-top: var(--space-250); - } - - .uw-r-padding-top-300 { - padding-top: var(--space-300); - } - - .uw-r-padding-top-350 { - padding-top: var(--space-350); - } - - .uw-r-padding-top-400 { - padding-top: var(--space-400); - } - - .uw-r-padding-top-500 { - padding-top: var(--space-500); - } - - .uw-r-padding-top-600 { - padding-top: var(--space-600); - } - - .uw-r-padding-top-700 { - padding-top: var(--space-700); - } - - .uw-r-padding-top-800 { - padding-top: var(--space-800); - } - - .uw-r-padding-top-900 { - padding-top: var(--space-900); - } - - .uw-r-padding-top-1000 { - padding-top: var(--space-1000); - } -} - -@breakpoints { - .uw-r-padding-right { - padding-right: var(--r-padding-right); - } - - .uw-r-padding-right-0 { - padding-right: 0; - } - - .uw-r-padding-right-25 { - padding-right: var(--space-25); - } - - .uw-r-padding-right-50 { - padding-right: var(--space-50); - } - - .uw-r-padding-right-75 { - padding-right: var(--space-75); - } - - .uw-r-padding-right-100 { - padding-right: var(--space-100); - } - - .uw-r-padding-right-150 { - padding-right: var(--space-150); - } - - .uw-r-padding-right-200 { - padding-right: var(--space-200); - } - - .uw-r-padding-right-250 { - padding-right: var(--space-250); - } - - .uw-r-padding-right-300 { - padding-right: var(--space-300); - } - - .uw-r-padding-right-350 { - padding-right: var(--space-350); - } - - .uw-r-padding-right-400 { - padding-right: var(--space-400); - } - - .uw-r-padding-right-500 { - padding-right: var(--space-500); - } - - .uw-r-padding-right-600 { - padding-right: var(--space-600); - } - - .uw-r-padding-right-700 { - padding-right: var(--space-700); - } - - .uw-r-padding-right-800 { - padding-right: var(--space-800); - } - - .uw-r-padding-right-900 { - padding-right: var(--space-900); - } - - .uw-r-padding-right-1000 { - padding-right: var(--space-1000); - } -} - -@breakpoints { - .uw-r-padding-bottom { - padding-bottom: var(--r-padding-bottom); - } - - .uw-r-padding-bottom-0 { - padding-bottom: 0; - } - - .uw-r-padding-bottom-25 { - padding-bottom: var(--space-25); - } - - .uw-r-padding-bottom-50 { - padding-bottom: var(--space-50); - } - - .uw-r-padding-bottom-75 { - padding-bottom: var(--space-75); - } - - .uw-r-padding-bottom-100 { - padding-bottom: var(--space-100); - } - - .uw-r-padding-bottom-150 { - padding-bottom: var(--space-150); - } - - .uw-r-padding-bottom-200 { - padding-bottom: var(--space-200); - } - - .uw-r-padding-bottom-250 { - padding-bottom: var(--space-250); - } - - .uw-r-padding-bottom-300 { - padding-bottom: var(--space-300); - } - - .uw-r-padding-bottom-350 { - padding-bottom: var(--space-350); - } - - .uw-r-padding-bottom-400 { - padding-bottom: var(--space-400); - } - - .uw-r-padding-bottom-500 { - padding-bottom: var(--space-500); - } - - .uw-r-padding-bottom-600 { - padding-bottom: var(--space-600); - } - - .uw-r-padding-bottom-700 { - padding-bottom: var(--space-700); - } - - .uw-r-padding-bottom-800 { - padding-bottom: var(--space-800); - } - - .uw-r-padding-bottom-900 { - padding-bottom: var(--space-900); - } - - .uw-r-padding-bottom-1000 { - padding-bottom: var(--space-1000); - } -} - -@breakpoints { - .uw-r-padding-left { - padding-left: var(--r-padding-left); - } - - .uw-r-padding-left-0 { - padding-left: 0; - } - - .uw-r-padding-left-25 { - padding-left: var(--space-25); - } - - .uw-r-padding-left-50 { - padding-left: var(--space-50); - } - - .uw-r-padding-left-75 { - padding-left: var(--space-75); - } - - .uw-r-padding-left-100 { - padding-left: var(--space-100); - } - - .uw-r-padding-left-150 { - padding-left: var(--space-150); - } - - .uw-r-padding-left-200 { - padding-left: var(--space-200); - } - - .uw-r-padding-left-250 { - padding-left: var(--space-250); - } - - .uw-r-padding-left-300 { - padding-left: var(--space-300); - } - - .uw-r-padding-left-350 { - padding-left: var(--space-350); - } - - .uw-r-padding-left-400 { - padding-left: var(--space-400); - } - - .uw-r-padding-left-500 { - padding-left: var(--space-500); - } - - .uw-r-padding-left-600 { - padding-left: var(--space-600); - } - - .uw-r-padding-left-700 { - padding-left: var(--space-700); - } - - .uw-r-padding-left-800 { - padding-left: var(--space-800); - } - - .uw-r-padding-left-900 { - padding-left: var(--space-900); - } - - .uw-r-padding-left-1000 { - padding-left: var(--space-1000); - } -} diff --git a/packages/react/src/styles/size.css b/packages/react/src/styles/size.css deleted file mode 100644 index acbcf79ff..000000000 --- a/packages/react/src/styles/size.css +++ /dev/null @@ -1,11 +0,0 @@ -@breakpoints { - .uw-r-width { - width: var(--r-width); - } -} - -@breakpoints { - .uw-r-height { - height: var(--r-height); - } -} diff --git a/packages/react/src/styles/text-align.css b/packages/react/src/styles/text-align.css deleted file mode 100644 index b9e714690..000000000 --- a/packages/react/src/styles/text-align.css +++ /dev/null @@ -1,13 +0,0 @@ -@breakpoints { - :where(.uw-r-text-align-left) { - text-align: left; - } - - :where(.uw-r-text-align-center) { - text-align: center; - } - - :where(.uw-r-text-align-right) { - text-align: right; - } -} diff --git a/packages/react/src/styles/tokens/space.css b/packages/react/src/styles/tokens/space.css deleted file mode 100644 index 0332178ef..000000000 --- a/packages/react/src/styles/tokens/space.css +++ /dev/null @@ -1,19 +0,0 @@ -& { - --space-0: 0px; - --space-25: 2px; - --space-50: 4px; - --space-75: 6px; - --space-100: 8px; - --space-150: 12px; - --space-200: 16px; - --space-250: 20px; - --space-300: 24px; - --space-350: 28px; - --space-400: 32px; - --space-500: 40px; - --space-600: 48px; - --space-700: 56px; - --space-800: 64px; - --space-900: 72px; - --space-1000: 80px; -} diff --git a/packages/react/src/styles/tokens/typography.css b/packages/react/src/styles/tokens/typography.css deleted file mode 100644 index 5be0ebf6a..000000000 --- a/packages/react/src/styles/tokens/typography.css +++ /dev/null @@ -1,32 +0,0 @@ -& { - /** font-family **/ - --font-family-body: 'Work Sans', arial, sans-serif; - --font-family-heading: aeonik, arial, sans-serif; - - /** font-sizes **/ - --font-size-body-xs: 0.75rem; - --font-size-body-sm: 0.875rem; - --font-size-body-md: 1rem; - --font-size-body-lg: 1.125rem; - --font-size-body-xl: 1.25rem; - --font-size-heading-xs: 1.125rem; - --font-size-heading-sm: 1.25rem; - --font-size-heading-md: 1.375rem; - --font-size-heading-lg: 1.5rem; - --font-size-heading-xl: 1.75rem; - --font-size-heading-2xl: 2rem; - --font-size-heading-3xl: 2.625rem; - --font-size-heading-4xl: 4rem; - - /** font-weights **/ - --font-weight-regular: 400; - --font-weight-medium: 500; - --font-weight-semibold: 600; - --font-weight-bold: 700; - - /** line-heights **/ - --line-height-sm: 1; - --line-height-md: 1.2; - --line-height-lg: 1.5; - --line-height-xl: 2; -} diff --git a/packages/react/src/tokens/breakpoints.ts b/packages/react/src/tokens/breakpoints.ts deleted file mode 100644 index 7e6a9fe67..000000000 --- a/packages/react/src/tokens/breakpoints.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const breakpoints = { - // px - mobile: 0, - tablet: 740, - desktop: 992, - wide: 1200, -}; diff --git a/packages/react/src/types/component-props.ts b/packages/react/src/types/component-props.ts deleted file mode 100644 index c71771e8b..000000000 --- a/packages/react/src/types/component-props.ts +++ /dev/null @@ -1,12 +0,0 @@ -import * as React from 'react'; - -// Omits the specified props from the component props. Autocomplete will suggest props -// of the component, but won't restrict the omittable props to those that actually exist. -export type ComponentPropsWithout< - T extends React.ElementType, - O extends - | Omit> - | keyof React.ComponentPropsWithoutRef, -> = Omit, O & string>; - -export type RemovedProps = 'asChild' | 'defaultChecked' | 'defaultValue' | 'color'; diff --git a/packages/react/src/types/orientation.ts b/packages/react/src/types/orientation.ts deleted file mode 100644 index efffbe096..000000000 --- a/packages/react/src/types/orientation.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const ORIENTATIONS = ['horizontal', 'vertical'] as const; - -export type Orientation = (typeof ORIENTATIONS)[number]; diff --git a/packages/react/src/types/responsive.ts b/packages/react/src/types/responsive.ts deleted file mode 100644 index dca10622a..000000000 --- a/packages/react/src/types/responsive.ts +++ /dev/null @@ -1,8 +0,0 @@ -export type Breakpoints = 'mobile' | 'tablet' | 'desktop' | 'wide'; -export const breakpoints = ['mobile', 'tablet', 'desktop', 'wide'] as const; -export type Breakpoint = (typeof breakpoints)[number]; -export type Responsive = T | Partial>; - -// Creates a union type of string literals with strings, but retains intellisense for the literals. -// Union => string | Omit -export type Union = T | Omit; diff --git a/packages/react/src/utils/media.ts b/packages/react/src/utils/media.ts deleted file mode 100644 index ce4c10b16..000000000 --- a/packages/react/src/utils/media.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { breakpoints } from '../tokens/breakpoints'; - -/** - * A lot of this file is directly copied from MUI - https://github.com/mui/material-ui/blob/next/packages/mui-system/src/createTheme/createBreakpoints.js - */ - -const unit = 'px'; -const step = 100; -const mq = (breakpoint: string) => `@media (min-width: ${breakpoint})`; -const keys = Object.keys(breakpoints); - -type Breakpoint = keyof typeof breakpoints; - -/** - * Returns a min-width media query string matching screen widths greater than the screen size given by the breakpoint. - */ -function above(breakpoint: Breakpoint) { - const bp = breakpoints[breakpoint]; - if (bp === 0) { - return '@media all'; - } - return mq(bp + unit); -} - -/** - * Returns a max-width media query string matching screen widths less than than the screen size given by the breakpoint. - */ -function below(breakpoint: Breakpoint) { - return `@media not all and (min-width:${breakpoints[breakpoint] + unit})`; -} - -/** - * Returns a media query string matching screen widths greater than the given start screen size and less than the given end screen size. - */ -function between(start: Breakpoint, end: Breakpoint) { - return ( - `@media (min-width:${breakpoints[start] + unit}) and ` + - `(max-width:${breakpoints[end] - step / 100 + unit})` - ); -} - -/** - * Returns a media query string matching screen widths starting from the given screen size and stopping just before the next breakpoint. - */ -function only(breakpoint: Breakpoint) { - if (keys.indexOf(breakpoint) + 1 < keys.length) { - return between(breakpoint, keys[keys.indexOf(breakpoint) + 1] as Breakpoint); - } - return above(breakpoint); -} - -/** - * Returns a media query string matching screen widths stopping at the given screen size and starting just before the next breakpoint. - */ -function not(breakpoint: Breakpoint) { - const keyIndex = keys.indexOf(breakpoint); - if (keyIndex === 0) { - return above(keys[1] as Breakpoint); - } - if (keyIndex === keys.length - 1) { - return below(keys[keyIndex] as Breakpoint); - } - const end = keys[keys.indexOf(breakpoint as string) + 1] as Breakpoint; - return between(breakpoint, end).replace('@media', '@media not all and'); -} - -export const media = { - above, - below, - between, - only, - not, - /* mobile first media queries mirroring the design system breakpoint values */ - mobile: '@media all', - tablet: mq(breakpoints.tablet + unit), - desktop: mq(breakpoints.desktop + unit), - wide: mq(breakpoints.wide + unit), -}; diff --git a/packages/react/tsconfig.build.json b/packages/react/tsconfig.build.json deleted file mode 100644 index a063ee640..000000000 --- a/packages/react/tsconfig.build.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": "./tsconfig.json", - "include": ["."], - "exclude": ["dist", "node_modules"] -} diff --git a/packages/react/tsconfig.json b/packages/react/tsconfig.json deleted file mode 100644 index 7c31eccac..000000000 --- a/packages/react/tsconfig.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "compilerOptions": { - "esModuleInterop": true, - "skipLibCheck": true, - "target": "es2022", - "allowJs": true, - "resolveJsonModule": true, - "moduleDetection": "force", - "isolatedModules": true, - "strict": true, - "noUncheckedIndexedAccess": true, - "noEmit": false, - "allowSyntheticDefaultImports": true, - "declaration": true, - "declarationMap": true, - "sourceMap": true, - "importHelpers": true, - "alwaysStrict": true, - "forceConsistentCasingInFileNames": true, - "module": "ES2020", - "moduleResolution": "node", - "outDir": "dist", - "rootDir": "src", - "lib": ["es2022", "dom", "dom.iterable"], - "jsx": "react", - "emitDeclarationOnly": true, - "types": ["node"] - }, - "exclude": ["dist", "node_modules"], - "include": ["src/**/*"] -} - diff --git a/packages/react/tsup.config.ts b/packages/react/tsup.config.ts deleted file mode 100644 index cecce9645..000000000 --- a/packages/react/tsup.config.ts +++ /dev/null @@ -1,20 +0,0 @@ -import path from 'path'; -import { defineConfig } from 'tsup'; - -// actual exposed modules = 1 per component -export default defineConfig([ - { - splitting: true, - sourcemap: true, - clean: true, - dts: true, - format: ['cjs', 'esm'], - minify: true, - bundle: true, - skipNodeModulesBundle: true, - target: 'es2020', - outDir: 'dist', - entry: [ './src/**/*.ts?(x)' ], - tsconfig: path.join(__dirname, './tsconfig.build.json'), - }, -]); diff --git a/packages/react/vercel.json b/packages/react/vercel.json deleted file mode 100644 index 4b1c4d22a..000000000 --- a/packages/react/vercel.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "installCommand": "pnpm install", - "buildCommand": "pnpm build:storybook:ci", - "outputDirectory": "storybook-static" -}