From c480ff92b2a03a0cacb77e5d17d217a70b4888eb Mon Sep 17 00:00:00 2001 From: "@casey_baggz_omni" Date: Mon, 19 Aug 2024 09:36:35 -0500 Subject: [PATCH 01/10] feat(react): create init FileUploader API --- .../react/src/components/FileUploader.tsx | 77 +++++++++++++++++++ packages/react/src/index.ts | 1 + 2 files changed, 78 insertions(+) create mode 100644 packages/react/src/components/FileUploader.tsx diff --git a/packages/react/src/components/FileUploader.tsx b/packages/react/src/components/FileUploader.tsx new file mode 100644 index 00000000..eeb8fe4b --- /dev/null +++ b/packages/react/src/components/FileUploader.tsx @@ -0,0 +1,77 @@ +import { css, cx } from '@cerberus-design/styled-system/css' +import { cq, vstack } from '@cerberus-design/styled-system/patterns' +import type { InputHTMLAttributes, PropsWithChildren } from 'react' +import { Show } from './Show' + +export interface FileUploaderProps + extends InputHTMLAttributes { + heading?: string + name: string +} + +export function FileUploader(props: PropsWithChildren) { + return ( +
+ +
+ ) +} diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 9a1dbe9c..e58de6ce 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -8,6 +8,7 @@ export * from './components/Button' export * from './components/FieldMessage' export * from './components/FeatureFlag' +export * from './components/FileUploader' export * from './components/IconButton' export * from './components/Input' export * from './components/Label' From 006a22559f1df4c421e252b21502f2d267bb3be9 Mon Sep 17 00:00:00 2001 From: "@casey_baggz_omni" Date: Mon, 19 Aug 2024 10:29:36 -0500 Subject: [PATCH 02/10] docs: add File Uploader section --- docs/app/data/categories.json | 2 +- docs/app/react/file-uploader/a11y.mdx | 32 +++++ .../components/file-uploader-preview.tsx | 9 ++ .../components/label-preview.tsx | 61 ++++++++ docs/app/react/file-uploader/dev.mdx | 133 ++++++++++++++++++ docs/app/react/file-uploader/guidelines.mdx | 49 +++++++ docs/app/react/file-uploader/overview.mdx | 27 ++++ docs/app/react/file-uploader/page.tsx | 54 +++++++ docs/app/react/side-nav.json | 7 + .../react/src/components/FileUploader.tsx | 33 +++-- 10 files changed, 393 insertions(+), 14 deletions(-) create mode 100644 docs/app/react/file-uploader/a11y.mdx create mode 100644 docs/app/react/file-uploader/components/file-uploader-preview.tsx create mode 100644 docs/app/react/file-uploader/components/label-preview.tsx create mode 100644 docs/app/react/file-uploader/dev.mdx create mode 100644 docs/app/react/file-uploader/guidelines.mdx create mode 100644 docs/app/react/file-uploader/overview.mdx create mode 100644 docs/app/react/file-uploader/page.tsx diff --git a/docs/app/data/categories.json b/docs/app/data/categories.json index 241185bf..a5e3c583 100644 --- a/docs/app/data/categories.json +++ b/docs/app/data/categories.json @@ -27,6 +27,6 @@ "inputs": { "name": "Inputs", "description": "Components that allow users to input data.", - "items": ["Input", "Textarea"] + "items": ["Input", "Textarea", "File Uploader"] } } diff --git a/docs/app/react/file-uploader/a11y.mdx b/docs/app/react/file-uploader/a11y.mdx new file mode 100644 index 00000000..1486256c --- /dev/null +++ b/docs/app/react/file-uploader/a11y.mdx @@ -0,0 +1,32 @@ +--- +--- + +import { + WhenToUseAdmonition +} from '@/app/components/Admonition' +import OverviewList from '@/app/components/OverviewList' + +## Use Cases + + + +## Interaction & Style + +The containers for both filled and outlined text fields provide the same functionality. Changes to color and thickness of stroke help provide clear visual cues for interaction. + +## Keyboard Navigation + +| Keys | Actions | +| -------- | --------------------------------------------------------------- | +| Tab | Focus lands on (non-disabled) input | + +## Labeling Elements + +If the UI text is correctly linked, assistive tech (such as a screenreader) will read the UI text followed by the component's role. + +The accessibility label for a textfield is typically the same as the label for the textfield. \ No newline at end of file diff --git a/docs/app/react/file-uploader/components/file-uploader-preview.tsx b/docs/app/react/file-uploader/components/file-uploader-preview.tsx new file mode 100644 index 00000000..38cc163e --- /dev/null +++ b/docs/app/react/file-uploader/components/file-uploader-preview.tsx @@ -0,0 +1,9 @@ +import { FileUploader } from '@cerberus-design/react' + +export function BasicFileUploader() { + return ( + + Import .csv file + + ) +} diff --git a/docs/app/react/file-uploader/components/label-preview.tsx b/docs/app/react/file-uploader/components/label-preview.tsx new file mode 100644 index 00000000..0e264ede --- /dev/null +++ b/docs/app/react/file-uploader/components/label-preview.tsx @@ -0,0 +1,61 @@ +import { Field, Input, Label } from '@cerberus-design/react' +import { css } from '@cerberus/styled-system/css' + +const overrideStyles = css({ + w: '1/2', +}) + +export function LabelBasicPreview() { + return ( +
+ + + + +
+ ) +} + +export function LabelHiddenPreview() { + return ( +
+ + + + +
+ ) +} + +export function LabelOptionalPreview() { + return ( +
+ + + + +
+ ) +} + +export function LabelCustomPreview() { + return ( +
+ + + + +
+ ) +} diff --git a/docs/app/react/file-uploader/dev.mdx b/docs/app/react/file-uploader/dev.mdx new file mode 100644 index 00000000..1e5c37a1 --- /dev/null +++ b/docs/app/react/file-uploader/dev.mdx @@ -0,0 +1,133 @@ +--- +npm: '@cerberus-design/react' +source: 'components/Label.tsx' +recipe: 'label.ts' +--- + +import CodePreview from '@/app/components/CodePreview' +import { + LabelBasicPreview, + LabelHiddenPreview, + LabelOptionalPreview, + LabelCustomPreview +} from '@/app/react/label/components/label-preview' +import { NoteAdmonition } from '@/app/components/Admonition' + +```ts +import { Field, Label } from '@cerberus-design/react' +``` + +## Usage + +}> +```tsx title="first-name-input.tsx" {5,6} +import { Field, Label } from '@cerberus-design/react' + +function LabelBasicPreview() { + return ( + + + + + ) +} +``` + + +## Hidden + +}> +```tsx title="search-input.tsx" {6} +import { Field, Label } from '@cerberus-design/react' + +function LabelHiddenPreview() { + return ( + + + + + ) +} +``` + + +## Optional + +}> +```tsx title="search-input.tsx" {5} +import { Field, Label } from '@cerberus-design/react' + +function LabelOptionalPreview() { + return ( + + + + + ) +} +``` + + +## Customizing + +}> +```tsx title="search-input.tsx" +import { Field, Label } from '@cerberus-design/react' + +function LabelCustomPreview() { + return ( + + + + + ) +} + +``` + + +## API + + + +```ts showLineNumbers=false +export interface FieldProps { + disabled?: boolean + invalid?: boolean + required?: boolean + readOnly?: boolean +} + +define function Field(props: PropsWithChildren): ReactNode +``` + +```ts showLineNumbers=false +export interface LabelProps extends LabelHTMLAttributes { + htmlFor: string + hidden?: boolean + size?: 'sm' | 'md' +} + +define function Label(props: LabelProps): ReactNode +``` + +### Props + +The `LabelProps` component accepts the following props: + +| Name | Default | Description | +| -------- | ------- | ------------------------------------------------------------- | +| htmlFor | null | The `name` attribute of the Input the Label is associated with. | +| hidden | false | Whether the Label content should be visually hidden. | +| size | 'md' | The size of the Label. | diff --git a/docs/app/react/file-uploader/guidelines.mdx b/docs/app/react/file-uploader/guidelines.mdx new file mode 100644 index 00000000..a0d10658 --- /dev/null +++ b/docs/app/react/file-uploader/guidelines.mdx @@ -0,0 +1,49 @@ +--- +--- + +import CodePreview from '@/app/components/CodePreview' +import OverviewList from '@/app/components/OverviewList' +import { + WhenToUseAdmonition, + WhenNotToUseAdmonition, +} from '@/app/components/Admonition' +import { + LabelBasicPreview, + LabelHiddenPreview, + LabelOptionalPreview +} from '@/app/react/label/components/label-preview' + +## Usage + + + + + + +## Standard Labels + +Standard labels are used for most input use cases. + +} /> + + + +## Hidden Labels + +Hidden labels are used when the label is not visible to the user, but still needs to be present for screen readers. + +} /> + + + +## Required Labels + +Required labels are used when the input is required. + +} /> + + + +## Placement + +Labels should be placed above the input field. For checkboxes and radio buttons, the label should be placed to the right of the input. diff --git a/docs/app/react/file-uploader/overview.mdx b/docs/app/react/file-uploader/overview.mdx new file mode 100644 index 00000000..d5383a3f --- /dev/null +++ b/docs/app/react/file-uploader/overview.mdx @@ -0,0 +1,27 @@ +--- +heading: 'File Uploader' +description: 'File uploaders allow users to upload files to a server' +a11y: 'forms' +--- + +import CodePreview from '@/app/components/CodePreview' +import OverviewList from '@/app/components/OverviewList' +import { + BasicFileUploader +} from '@/app/react/file-uploader/components/file-uploader-preview' + + + +## Example + +} /> + +## Resources + +| Name | Resource | Status | +| -------- | -------- | ---------------------------------------------------- | +| Figma | [Design Kit (Figma)](https://www.figma.com/design/ducwqOCxoxcWc3ReV3FYd8/Digital-University-Component-Library?m=auto&node-id=0-1) | Private | \ No newline at end of file diff --git a/docs/app/react/file-uploader/page.tsx b/docs/app/react/file-uploader/page.tsx new file mode 100644 index 00000000..9f4d6074 --- /dev/null +++ b/docs/app/react/file-uploader/page.tsx @@ -0,0 +1,54 @@ +import ApiLinks from '@/app/components/ApiLinks' +import { + TabPageContent, + TabPageContentLayout, +} from '../../components/PageLayout' +import FeatureHeader from '@/app/components/FeatureHeader' +import type { MatchFeatureKind } from '@/app/components/MatchFeatureImg' +import PageTabs from '@/app/components/PageTabs' + +import Overview, { frontmatter } from './overview.mdx' +import Guidelines from './guidelines.mdx' +import Dev, { frontmatter as devFrontmatter } from './dev.mdx' +import A11y from './a11y.mdx' + +export default function FileUploaderPage() { + return ( + <> + + + + + + + } + guidelines={ + + + + } + dev={ + +
+ + +
+
+ } + a11y={ + + + + } + /> +
+ + ) +} diff --git a/docs/app/react/side-nav.json b/docs/app/react/side-nav.json index 53b7e946..d4c3a8b5 100644 --- a/docs/app/react/side-nav.json +++ b/docs/app/react/side-nav.json @@ -142,6 +142,13 @@ "tag": "new", "type": "route" }, + { + "id": "2:s", + "label": "File Uploader", + "route": "/react/file-uploader", + "tag": "next", + "type": "route" + }, { "id": "3", "label": "Hooks", diff --git a/packages/react/src/components/FileUploader.tsx b/packages/react/src/components/FileUploader.tsx index eeb8fe4b..8b3f5fbf 100644 --- a/packages/react/src/components/FileUploader.tsx +++ b/packages/react/src/components/FileUploader.tsx @@ -1,5 +1,5 @@ import { css, cx } from '@cerberus-design/styled-system/css' -import { cq, vstack } from '@cerberus-design/styled-system/patterns' +import { vstack } from '@cerberus-design/styled-system/patterns' import type { InputHTMLAttributes, PropsWithChildren } from 'react' import { Show } from './Show' @@ -10,13 +10,18 @@ export interface FileUploaderProps } export function FileUploader(props: PropsWithChildren) { + const { children, ...nativeProps } = props return (