diff --git a/dsp/data/components.json b/dsp/data/components.json index 80028138..e4774bab 100644 --- a/dsp/data/components.json +++ b/dsp/data/components.json @@ -12055,6 +12055,644 @@ } } } + }, + { + "class": "component", + "type": "page", + "id": "Textarea", + "name": "Textarea", + "last_updated_by": "System", + "description": "Textarea is a styled HTML Textarea.\n\nThere are no behavior changes applied to the native HTML tag other\nthan light styling done via CSS in order to keep inputs accessible.", + "related_entity_ids": [], + "tags": [ + "component" + ], + "snippets": { + "trigger": "textarea", + "languages": { + "javascriptreact": "\n" + } + }, + "ext_com_draculaui_variations": [ + { + "title": "Usage", + "html": "\n", + "react": "\n\n", + "react": "\n \n\n", + "react": "\n \n\n", + "react": "\n \n \n
\n

md

\n \n
\n
\n

lg

\n \n
\n\n", + "react": "\n \n sm\n \n \n \n \n md\n \n \n \n \n lg\n \n \n \n;\n", + "docs": "Border size can be customize to use several different sizes.", + "screenshot": "./dsp/assets/TextareaBorder Sizes.png" + } + ], + "ext_com_draculaui_props": { + "color": { + "defaultValue": null, + "description": "The Dracula UI theme color to be used", + "name": "color", + "parent": { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + }, + "declarations": [ + { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + } + ], + "required": false, + "type": { + "name": "\"cyan\" | \"green\" | \"orange\" | \"pink\" | \"purple\" | \"red\" | \"yellow\" | \"white\" | undefined" + } + }, + "size": { + "defaultValue": null, + "description": "Controls the size of the textarea based on pre-configured Dracula UI sizes.", + "name": "size", + "parent": { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + }, + "declarations": [ + { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + } + ], + "required": false, + "type": { + "name": "number | \"lg\" | \"md\" | \"sm\" | undefined" + } + }, + "borderSize": { + "defaultValue": null, + "description": "Controls the border size of the textarea based on pre-configured Dracula UI sizes.", + "name": "borderSize", + "parent": { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + }, + "declarations": [ + { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | undefined" + } + }, + "variant": { + "defaultValue": null, + "description": "Controls the variation the textarea.\n`normal` -> Regular Textarea component with a light background color.\n`outline` -> Keeps the accent color, but removes the background.", + "name": "variant", + "parent": { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + }, + "declarations": [ + { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + } + ], + "required": false, + "type": { + "name": "\"normal\" | \"outline\" | undefined" + } + }, + "p": { + "defaultValue": null, + "description": "", + "name": "p", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | undefined" + } + }, + "py": { + "defaultValue": null, + "description": "", + "name": "py", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | undefined" + } + }, + "px": { + "defaultValue": null, + "description": "", + "name": "px", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | undefined" + } + }, + "pt": { + "defaultValue": null, + "description": "", + "name": "pt", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | undefined" + } + }, + "pb": { + "defaultValue": null, + "description": "", + "name": "pb", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | undefined" + } + }, + "pl": { + "defaultValue": null, + "description": "", + "name": "pl", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | undefined" + } + }, + "pr": { + "defaultValue": null, + "description": "", + "name": "pr", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | undefined" + } + }, + "m": { + "defaultValue": null, + "description": "", + "name": "m", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | \"auto\" | undefined" + } + }, + "my": { + "defaultValue": null, + "description": "", + "name": "my", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | \"auto\" | undefined" + } + }, + "mx": { + "defaultValue": null, + "description": "", + "name": "mx", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | \"auto\" | undefined" + } + }, + "mt": { + "defaultValue": null, + "description": "", + "name": "mt", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | \"auto\" | undefined" + } + }, + "mb": { + "defaultValue": null, + "description": "", + "name": "mb", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | \"auto\" | undefined" + } + }, + "ml": { + "defaultValue": null, + "description": "", + "name": "ml", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | \"auto\" | undefined" + } + }, + "mr": { + "defaultValue": null, + "description": "", + "name": "mr", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | \"auto\" | undefined" + } + } + }, + "ext_com_draculaui_docgen": { + "tags": {}, + "description": "Textarea is a styled HTML Textarea.\n\nThere are no behavior changes applied to the native HTML tag other\nthan light styling done via CSS in order to keep inputs accessible.", + "displayName": "Textarea", + "methods": [], + "props": { + "color": { + "defaultValue": null, + "description": "The Dracula UI theme color to be used", + "name": "color", + "parent": { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + }, + "declarations": [ + { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + } + ], + "required": false, + "type": { + "name": "\"cyan\" | \"green\" | \"orange\" | \"pink\" | \"purple\" | \"red\" | \"yellow\" | \"white\" | undefined" + } + }, + "size": { + "defaultValue": null, + "description": "Controls the size of the textarea based on pre-configured Dracula UI sizes.", + "name": "size", + "parent": { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + }, + "declarations": [ + { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + } + ], + "required": false, + "type": { + "name": "number | \"lg\" | \"md\" | \"sm\" | undefined" + } + }, + "borderSize": { + "defaultValue": null, + "description": "Controls the border size of the textarea based on pre-configured Dracula UI sizes.", + "name": "borderSize", + "parent": { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + }, + "declarations": [ + { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | undefined" + } + }, + "variant": { + "defaultValue": null, + "description": "Controls the variation the textarea.\n`normal` -> Regular Textarea component with a light background color.\n`outline` -> Keeps the accent color, but removes the background.", + "name": "variant", + "parent": { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + }, + "declarations": [ + { + "fileName": "src/components/Textarea/Textarea.tsx", + "name": "TextareaProps" + } + ], + "required": false, + "type": { + "name": "\"normal\" | \"outline\" | undefined" + } + }, + "p": { + "defaultValue": null, + "description": "", + "name": "p", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | undefined" + } + }, + "py": { + "defaultValue": null, + "description": "", + "name": "py", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | undefined" + } + }, + "px": { + "defaultValue": null, + "description": "", + "name": "px", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | undefined" + } + }, + "pt": { + "defaultValue": null, + "description": "", + "name": "pt", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | undefined" + } + }, + "pb": { + "defaultValue": null, + "description": "", + "name": "pb", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | undefined" + } + }, + "pl": { + "defaultValue": null, + "description": "", + "name": "pl", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | undefined" + } + }, + "pr": { + "defaultValue": null, + "description": "", + "name": "pr", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | undefined" + } + }, + "m": { + "defaultValue": null, + "description": "", + "name": "m", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | \"auto\" | undefined" + } + }, + "my": { + "defaultValue": null, + "description": "", + "name": "my", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | \"auto\" | undefined" + } + }, + "mx": { + "defaultValue": null, + "description": "", + "name": "mx", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | \"auto\" | undefined" + } + }, + "mt": { + "defaultValue": null, + "description": "", + "name": "mt", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | \"auto\" | undefined" + } + }, + "mb": { + "defaultValue": null, + "description": "", + "name": "mb", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | \"auto\" | undefined" + } + }, + "ml": { + "defaultValue": null, + "description": "", + "name": "ml", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | \"auto\" | undefined" + } + }, + "mr": { + "defaultValue": null, + "description": "", + "name": "mr", + "declarations": [ + { + "fileName": "dracula-ui/src/base/spacing.ts", + "name": "TypeLiteral" + } + ], + "required": false, + "type": { + "name": "\"lg\" | \"md\" | \"sm\" | \"none\" | \"xxs\" | \"xs\" | \"auto\" | undefined" + } + } + } + } } ] -} \ No newline at end of file +} diff --git a/src/components/Textarea/Textarea.tsx b/src/components/Textarea/Textarea.tsx new file mode 100644 index 00000000..e5bbc243 --- /dev/null +++ b/src/components/Textarea/Textarea.tsx @@ -0,0 +1,80 @@ +import cx from 'classnames/dedupe' +import React, { TextareaHTMLAttributes } from 'react' +import { BaseColorMap } from '../../base/colors' +import { + cleanProps, + marginMixin, + MarginMixin, + paddingMixin, + PaddingMixin +} from '../../base/spacing' + +export const textareaVariants = { + normal: 'drac-textarea', + outline: 'drac-textarea-outline' +} + +export const textareaSizes = { + lg: 'drac-textarea-lg', + md: 'drac-textarea', + sm: 'drac-textarea-sm' +} + +export const textareaBorderSizes = { + lg: 'drac-textarea-border-lg', + md: 'drac-textarea-border-md', + sm: 'drac-textarea-border-sm' +} + +export const textareaColors: BaseColorMap & { white: string } = { + white: 'drac-textarea-white drac-text-white', + cyan: 'drac-textarea-cyandrac-text-cyan', + green: 'drac-textarea-green drac-text-green', + orange: 'drac-textarea-orange drac-text-orange', + pink: 'drac-textarea-pink drac-text-pink', + purple: 'drac-textarea-purple drac-text-purple', + red: 'drac-textarea-red drac-text-red', + yellow: 'drac-textarea-yellow drac-text-yellow' +} + +export interface TextareaProps + extends Omit, 'size'>, + PaddingMixin, + MarginMixin { + + color?: keyof typeof textareaColors + + size?: keyof typeof textareaSizes | number + + borderSize?: keyof typeof textareaBorderSizes + + variant?: keyof typeof textareaVariants +} + +export const Textarea = React.forwardRef( + (props, ref) => { + const { color, size, borderSize, variant, ...htmlProps} = props + + const finalProps: Record = { + ...htmlProps, + className: cx( + `drac-textarea`, + props.className, + variant && textareaVariants[variant], + size && typeof size === 'string' && textareaSizes[size], + borderSize && textareaBorderSizes[borderSize], + color && textareaColors[color], + ...paddingMixin(props), + ...marginMixin(props) + ) + } + + if (size && typeof size === 'number') { + finalProps[size] = size + } + + return + } +) + +Textarea.displayName = 'Textarea' diff --git a/src/components/Textarea/__tests__/Textarea.test.tsx b/src/components/Textarea/__tests__/Textarea.test.tsx new file mode 100644 index 00000000..942bf2a8 --- /dev/null +++ b/src/components/Textarea/__tests__/Textarea.test.tsx @@ -0,0 +1,130 @@ +import React from 'react' +import { docs } from '@/documentation/site-docs' +import { snapshot } from '@/documentation/render-component' +import { Box } from '@/components/Box/Box' +import { Textarea } from '@/components/Textarea/Textarea' +import { Heading } from '@/components/Heading/Heading' + +docs(Textarea, { + basic() { + return snapshot('Usage', Usage, 'Styles or abstrats HTML textarea elements.') + }, + variations() { + return [ + snapshot( + 'Colors', + Colors, + 'Textareas can be customized to use any of the Dracula UI theme colors.' + ), + snapshot( + 'Sizes', + Sizes, + 'Textareaas can be customized to use several different sizes.' + ), + snapshot( + 'Variants', + Variants, + 'Use the `outline` variant to represent subtler Textareas' + ), + snapshot( + 'Border Sizes', + BorderSizes, + 'Border size can be customized to use several different sizes' + ) + ] + } +}) + +function Usage() { + return +} + +function Colors() { + return ( + + + + + ) +} + +function Sizes() { + return ( + + + + + + ) +} + +function Variants() { + return ( + + + + + ) +} + +function BorderSizes() { + return ( + + + sm + + + + + + md + + + + + + + lg + + + + + + ) +} diff --git a/src/components/Textarea/__tests__/__snapshots__/Textarea.test.tsx.snap b/src/components/Textarea/__tests__/__snapshots__/Textarea.test.tsx.snap new file mode 100644 index 00000000..5bf4f6c0 --- /dev/null +++ b/src/components/Textarea/__tests__/__snapshots__/Textarea.test.tsx.snap @@ -0,0 +1,186 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Site: Textarea Basic Usage 1`] = ` +Object { + "docs": "Styles or abstrats HTML textarea elements.", + "html": " +", + "react": " + +
+

md

+ +
+
+

lg

+ +
+ +", + "react": " + + sm + + +", + "react": " + + +", + "react": " + + +", + "react": " +