diff --git a/_templates/react/src/app/app.tsx b/_templates/react/src/app/app.tsx index d91f82c5b..927957301 100644 --- a/_templates/react/src/app/app.tsx +++ b/_templates/react/src/app/app.tsx @@ -1,38 +1,43 @@ import { Link, Outlet } from "react-router-dom"; -import { GoAAppFooter, GoAAppHeader, GoAMicrositeHeader, GoAOneColumnLayout, GoASideMenu, GoASideMenuGroup } from "@abgov/react-components"; +import { + GoabAppFooter, + GoabAppHeader, + GoabMicrositeHeader, + GoabOneColumnLayout, + GoabSideMenu, + GoabSideMenuGroup, +} from "@abgov/react-components"; import "@abgov/style"; export function App() { return ( - +
- - + + Sign in - +
- - + + Nothing here {/* Add links here */} - - + {/* Add links here */} - - +
- +
-
+ ); } diff --git a/_templates/web/src/app/App.svelte b/_templates/web/src/app/App.svelte index 31d7ff58d..85270c845 100644 --- a/_templates/web/src/app/App.svelte +++ b/_templates/web/src/app/App.svelte @@ -40,7 +40,7 @@ import TextareaPage from "../pages/TextareaPage.svelte" import TextFieldPage from "../pages/TextFieldPage.svelte" import TooltipPage from "../pages/TooltipPage.svelte" - + let hash: string = "#"; onMount(() => { @@ -48,13 +48,13 @@ window.addEventListener("hashchange", (e) => { // @ts-expect-error hash = e.target?.location?.hash; - }) - }) + }) + }) - GoA Component Playground + GoAB Component Playground @@ -206,7 +206,7 @@ {:else if hash === "#tooltip"} {/if} - + diff --git a/libs/common/.eslintrc.json b/libs/common/.eslintrc.json new file mode 100644 index 000000000..9d9c0db55 --- /dev/null +++ b/libs/common/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/common/.releaserc.json b/libs/common/.releaserc.json new file mode 100644 index 000000000..08de8fb7a --- /dev/null +++ b/libs/common/.releaserc.json @@ -0,0 +1,19 @@ +{ + "extends": "../../.releaserc.json", + "tagFormat": "common-v${version}", + "plugins": [ + [ + "@abgov/nx-release", + { + "project": "ui-components-common" + } + ], + [ + "@semantic-release/npm", + { + "pkgRoot": "dist/libs/common" + } + ], + "@semantic-release/github" + ] +} \ No newline at end of file diff --git a/libs/common/package.json b/libs/common/package.json new file mode 100644 index 000000000..7ad30039c --- /dev/null +++ b/libs/common/package.json @@ -0,0 +1,9 @@ +{ + "name": "@abgov/ui-components-common", + "version": "0.0.0", + "description": "Government of Alberta - UI Web components", + "private": true, + "type": "module", + "main": "./index.js", + "module": "./index.js" +} \ No newline at end of file diff --git a/libs/common/project.json b/libs/common/project.json new file mode 100644 index 000000000..8c5710357 --- /dev/null +++ b/libs/common/project.json @@ -0,0 +1,36 @@ +{ + "name": "common", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/common/src", + "projectType": "library", + "targets": { + "lint": { + "executor": "@nx/eslint:lint" + }, + "build": { + "executor": "@nx/vite:build", + "outputs": [ + "{options.outputPath}" + ], + "defaultConfiguration": "production", + "options": { + "outputPath": "dist/libs/common" + }, + "configurations": { + "development": { + "mode": "development" + }, + "production": { + "mode": "production" + } + } + }, + "release": { + "executor": "nx:run-commands", + "options": { + "command": "npx semantic-release -e ./libs/ui-components-common/.releaserc.json" + } + } + }, + "tags": [] +} \ No newline at end of file diff --git a/libs/common/src/index.ts b/libs/common/src/index.ts new file mode 100644 index 000000000..f1154d871 --- /dev/null +++ b/libs/common/src/index.ts @@ -0,0 +1 @@ +export * from "./lib/common"; diff --git a/libs/common/src/lib/common.ts b/libs/common/src/lib/common.ts new file mode 100644 index 000000000..aa19aa45e --- /dev/null +++ b/libs/common/src/lib/common.ts @@ -0,0 +1,925 @@ +export type GoabSpinnerType = "infinite" | "progress"; +export type GoabSpinnerSize = "small" | "medium" | "large" | "xlarge"; + +export type GoabRadioGroupOnChangeDetail = { + name: string; + value: string; +} + +export type GoabInputOnChangeDetail = { + name: string; + value: T; +} +export type GoabInputOnFocusDetail = GoabInputOnChangeDetail; +export type GoaInputOnBlurDetail = GoabInputOnChangeDetail; + +export type GoabInputAutoCapitalize = "on" | "off" | "none" | "sentences" | "words" | "characters"; + +export type GoabInputOnKeyPressDetail = { + name: string; + value: T; + key: T; +} + +export type GoabFormStepperOnChangeDetail = { + step: number; +} + +export type GoabFileUploadInputOnSelectFileDetail = { + file: File; +} + +export type GoabFileUploadOnCancelDetail = { + filename: string; +} + +export type GoabFileUploadOnDeleteDetail = { + filename: string; +} + +export type GoabDropdownItemMountType = "append" | "prepend" | "reset"; + + +export type GoabDropdownOnChangeDetail = { + name?: string; + value?: string; + values?: string[]; +} + +export type GoabDatePickerOnChangeDetail = { + name?: string; + value: string | Date | undefined; +} + +export type GoabChipVariant = "filter"; + +export type GoabChipTheme = "outline" | "filled" | "sharp"; + +export type GoabCheckboxOnChangeDetail = { + name?: string; + value?: string; + checked: boolean; + binding: "value" | "check"; +} + +export type GoabCalendarOnChangeDetail = { + name?: string; + value: string; +} + + +export type GoabBadgeType = + | "information" + | "success" + | "important" + | "emergency" + | "dark" + | "midtone" + | "light"; + +export type GoabPaginationVariant = "all" | "links-only"; + +export type GoabPaginationOnChangeDetail = { + page: number; +} + +export type GoabFormStepperType = "constrained" | "free"; +export type GoabFormStepStatus = "complete" | "incomplete" | "unstarted"; + +// Formitem +export type GoabFormItemLabelSize = "regular" | "large"; +export type GoabFormItemRequirement = "optional" | "required"; + +// FIle upload +export type GoabFileUploadInputVariant = "dragdrop" | "button"; + +// Container +export type GoabContainerAccent = "thick" | "thin" | "filled"; +export type GoabContainerPadding = "relaxed" | "compact"; +export type GoabContainerType = + | "interactive" + | "non-interactive" + | "info" + | "error" + | "success" + | "important"; +export type GoabContainerWidth = "full" | "content"; + +// Callout +export type GoabCalloutType = "information" | "success" | "important" | "emergency" | "event"; +export type GoabCalloutSize = "medium" | "large"; +export type GoabCalloutAriaLive = "off" | "polite" | "assertive"; + +// Button +export type GoabButtonType = + | "primary" + | "submit" + | "secondary" + | "tertiary" + | "start"; + +export type GoabButtonSize = "compact" | "normal"; +export type GoabButtonVariant = "normal" | "destructive"; + +// Button group +export type GoabButtonGroupAlignment = "start" | "end" | "center"; +export type GoabButtonGroupGap = "relaxed" | "compact"; + +// Accordion +export type GoabAccordionHeadingSize = "small" | "medium"; + +// Formstepper + +// Tooltip + +export type GoabTooltipPosition = "top" | "bottom" | "left" | "right"; +export type GoabTooltipHorizontalAlignment = "left" | "right" | "center"; + +// Textarea + +export type GoabTextAreaCountBy = "character" | "word" | ""; + + +export type GoabTextAreaOnChangeDetail = { + name: string; + value: string; +} + +export type GoabTextAreaOnKeyPressDetail = { + name: string; + value: string; + key: string; +} + +// Tabs + +export interface GoabTabsProps { + initialTab?: number; +} +export type GoabTabsOnChangeDetail = { + tab: number; +} +// Table + +export type GoabTableVariant = "normal" | "relaxed"; +export type GoabTableSortDirection = "asc" | "desc" | "none"; +export interface GoabTableProps extends Margins { + width?: string; + onSort?: (sortBy: string, sortDir: number) => void; + variant?: GoabTableVariant; + testId?: string; +} + + +export type GoabTableOnSortDetail = { + sortBy: string; + sortDir: number; +} + +// Spacer + +export type GoabSpacerHorizontalSpacing = Spacing | "fill" +export type GoabSpacerVerticalSpacing = Spacing; + +export interface GoabSpacerProps { + hSpacing?: Spacing | "fill"; + vSpacing?: Spacing; + testId?: string; +} + +// Skeleton + +export interface GoabSkeletonProps extends Margins { + maxWidth?: string; + size?: GoabSkeletonSize; + lineCount?: number; + type: GoabSkeletonType; + testId?: string; +} + +export type GoabSkeletonType = + | "image" + | "text" + | "title" + | "text-small" + | "avatar" + | "header" + | "paragraph" + | "thumbnail" + | "card" + | "profile" + | "article"; + +export type GoabSkeletonSize = "1" | "2" | "3" | "4"; + +// Radio + +export type GoabRadioGroupOrientation = "horizontal" | "vertical"; + +export interface GoabRadioGroup extends Margins { + name: string; + value?: string; + disabled?: boolean; + orientation?: GoabRadioGroupOrientation; + testId?: string; + error?: boolean; + ariaLabel?: string; +} + +export interface GoabRadioItem { + value?: string; + label?: string; + name?: string; + // description?: string | React.ReactNode; + disabled?: boolean; + checked?: boolean; + error?: boolean; + testId?: string; +} + +// Progress + +export type GoabCircularProgressVariant = "fullscreen" | "inline"; +export type GoabCircularProgressSize = "small" | "large"; + +// Popover + +export type GoabPopoverPosition = "above" | "below" | "auto"; + +export interface GoabPopoverProps extends Margins { + testId?: string; + maxWidth?: string; + padded?: boolean; + position?: GoabPopoverPosition; + relative?: boolean; +} + +// Notification + +export type GoabNotificationType = + | "important" + | "information" + | "event" + | "emergency"; + +export type GoabAriaLiveType = "polite" | "assertive" | "off"; + +// Microsite Header + +export type GoabServiceLevel = "alpha" | "beta" | "live"; +export type GoabLinkTarget = "self" | "blank"; + +// Modal +export type GoabModalRole = "dialog" | "alertdialog"; +export type GoabModalTransition = "fast" | "slow" | "none"; +export type GoabModalCalloutVariant = + | "information" + | "important" + | "emergency" + | "success" + | "event"; + +// Input + +export type GoabDate = Date | string; +export type GoabInputType = + | "text" + | "password" + | "email" + | "number" + | "date" + | "datetime-local" + | "month" + | "range" + | "search" + | "tel" + | "time" + | "url" + | "week"; + +export type GoabAutoCapitalize = + | "on" + | "off" + | "none" + | "sentences" + | "words" + | "characters"; + + +export type OnChange = (name: string, value: T) => void; +export type OnFocus = (name: string, value: T) => void; +export type OnBlur = (name: string, value: T) => void; +export type OnKeyPress = (name: string, value: T, key: string) => void; + +export interface GoabInputProps extends BaseProps { + onChange: OnChange; + value?: string; + min?: number | string; + max?: number | string; + step?: number; + onFocus?: OnFocus; + onBlur?: OnBlur; + onKeyPress?: OnKeyPress; +} + +export interface GoabNumberInputProps extends BaseProps { + onChange: OnChange; + value?: number; + min?: number; + max?: number; + step?: number; + onFocus?: OnFocus; + onBlur?: OnBlur; + onKeyPress?: OnKeyPress; +} + +export interface GoabDateInputProps extends BaseProps { + onChange: OnChange; + value?: GoabDate; + min?: GoabDate; + max?: GoabDate; + step?: number; + onFocus?: OnFocus; + onBlur?: OnBlur; + onKeyPress?: OnKeyPress; +} + +interface BaseProps extends Margins { + // required + name: string; + + // optional + id?: string; + debounce?: number; + disabled?: boolean; + autoCapitalize?: GoabAutoCapitalize; + placeholder?: string; + leadingIcon?: GoabIconType; + trailingIcon?: GoabIconType; + onTrailingIconClick?: () => void; + variant?: "goa" | "bare"; + focused?: boolean; + readonly?: boolean; + error?: boolean; + width?: string; + prefix?: string; + suffix?: string; + testId?: string; + ariaLabel?: string; + maxLength?: number; +} + +// Icon + +export type GoabIconFilledType = `${GoabIconType}-${GoabIconTheme}`; +export type GoabIconType = + | "accessibility" + | "add-circle" + | "add" + | "airplane" + | "alarm" + | "albums" + | "alert-circle" + | "alert" + | "american-football" + | "analytics" + | "aperture" + | "apps" + | "archive" + | "arrow-back-circle" + | "arrow-back" + | "arrow-down-circle" + | "arrow-down" + | "arrow-forward-circle" + | "arrow-forward" + | "arrow-redo-circle" + | "arrow-redo" + | "arrow-undo-circle" + | "arrow-undo" + | "arrow-up-circle" + | "arrow-up" + | "at-circle" + | "at" + | "attach" + | "backspace" + | "bag-add" + | "bag-check" + | "bag-handle" + | "bag" + | "bag-remove" + | "balloon" + | "ban" + | "bandage" + | "bar-chart" + | "barbell" + | "barcode" + | "baseball" + | "basket" + | "basketball" + | "battery-charging" + | "battery-dead" + | "battery-full" + | "battery-half" + | "beaker" + | "bed" + | "beer" + | "bicycle" + | "bluetooth" + | "boat" + | "body" + | "bonfire" + | "book" + | "bookmark" + | "bookmarks" + | "bowling-ball" + | "briefcase" + | "browsers" + | "brush" + | "bug" + | "build" + | "bulb" + | "bus" + | "business" + | "cafe" + | "calculator" + | "calendar-clear" + | "calendar-number" + | "calendar" + | "call" + | "camera" + | "camera-reverse" + | "car" + | "car-sport" + | "card" + | "caret-back-circle" + | "caret-back" + | "caret-down-circle" + | "caret-down" + | "caret-forward-circle" + | "caret-forward" + | "caret-up-circle" + | "caret-up" + | "cart" + | "cash" + | "cellular" + | "chatbox-ellipses" + | "chatbox" + | "chatbubble-ellipses" + | "chatbubble" + | "chatbubbles" + | "checkbox" + | "checkmark-circle" + | "checkmark-done-circle" + | "checkmark-done" + | "checkmark" + | "chevron-back-circle" + | "chevron-back" + | "chevron-down-circle" + | "chevron-down" + | "chevron-forward-circle" + | "chevron-forward" + | "chevron-up-circle" + | "chevron-up" + | "clipboard" + | "close-circle" + | "close" + | "cloud-circle" + | "cloud-done" + | "cloud-download" + | "cloud-offline" + | "cloud" + | "cloud-upload" + | "cloudy-night" + | "cloudy" + | "code-download" + | "code" + | "code-slash" + | "code-working" + | "cog" + | "color-fill" + | "color-filter" + | "color-palette" + | "color-wand" + | "compass" + | "construct" + | "contract" + | "contrast" + | "copy" + | "create" + | "crop" + | "cube" + | "cut" + | "desktop" + | "diamond" + | "dice" + | "disc" + | "document-attach" + | "document-lock" + | "document" + | "document-text" + | "documents" + | "download" + | "duplicate" + | "ear" + | "earth" + | "easel" + | "egg" + | "ellipse" + | "ellipsis-horizontal-circle" + | "ellipsis-horizontal" + | "ellipsis-vertical-circle" + | "ellipsis-vertical" + | "enter" + | "exit" + | "expand" + | "extension-puzzle" + | "eye-off" + | "eye" + | "eyedrop" + | "fast-food" + | "female" + | "file-tray-full" + | "file-tray" + | "file-tray-stacked" + | "filenames.ps1" + | "film" + | "filter-circle" + | "filter" + | "finger-print" + | "fish" + | "fitness" + | "flag" + | "flame" + | "flash-off" + | "flash" + | "flashlight" + | "flask" + | "flower" + | "folder-open" + | "folder" + | "football" + | "footsteps" + | "funnel" + | "game-controller" + | "gift" + | "git-branch" + | "git-commit" + | "git-compare" + | "git-merge" + | "git-network" + | "git-pull-request" + | "glasses" + | "globe" + | "golf" + | "grid" + | "hammer" + | "hand-left" + | "hand-right" + | "happy" + | "hardware-chip" + | "headset" + | "heart-circle" + | "heart-dislike-circle" + | "heart-dislike" + | "heart-half" + | "heart" + | "help-buoy" + | "help-circle" + | "help" + | "home" + | "hourglass" + | "ice-cream" + | "id-card" + | "image" + | "images" + | "infinite" + | "information-circle" + | "information" + | "invert-mode" + | "journal" + | "key" + | "keypad" + | "language" + | "laptop" + | "layers" + | "leaf" + | "library" + | "link" + | "list-circle" + | "list" + | "locate" + | "location" + | "lock-closed" + | "lock-open" + | "log-in" + | "log-out" + | "magnet" + | "mail-open" + | "mail" + | "mail-unread" + | "male-female" + | "male" + | "man" + | "map" + | "medal" + | "medical" + | "medkit" + | "megaphone" + | "menu" + | "mic-circle" + | "mic-off-circle" + | "mic-off" + | "mic" + | "moon" + | "move" + | "musical-note" + | "musical-notes" + | "navigate-circle" + | "navigate" + | "newspaper" + | "notifications-circle" + | "notifications-off-circle" + | "notifications-off" + | "notifications" + | "nuclear" + | "nutrition" + | "open" + | "options" + | "paper-plane" + | "partly-sunny" + | "pause-circle" + | "pause" + | "paw" + | "pencil" + | "people-circle" + | "people" + | "person-add" + | "person-circle" + | "person" + | "person-remove" + | "phone-landscape" + | "phone-portrait" + | "pie-chart" + | "pin" + | "pint" + | "pizza" + | "planet" + | "play-back-circle" + | "play-back" + | "play-circle" + | "play-forward-circle" + | "play-forward" + | "play" + | "play-skip-back-circle" + | "play-skip-back" + | "play-skip-forward-circle" + | "play-skip-forward" + | "podium" + | "power" + | "pricetag" + | "pricetags" + | "print" + | "prism" + | "pulse" + | "push" + | "qr-code" + | "radio-button-off" + | "radio-button-on" + | "radio" + | "rainy" + | "reader" + | "receipt" + | "recording" + | "refresh-circle" + | "refresh" + | "reload-circle" + | "reload" + | "remove-circle" + | "remove" + | "reorder-four" + | "reorder-three" + | "reorder-two" + | "repeat" + | "resize" + | "restaurant" + | "return-down-back" + | "return-down-forward" + | "return-up-back" + | "return-up-forward" + | "ribbon" + | "rocket" + | "rose" + | "sad" + | "save" + | "scale" + | "scan-circle" + | "scan" + | "school" + | "search-circle" + | "search" + | "send" + | "server" + | "settings" + | "shapes" + | "share" + | "share-social" + | "shield-checkmark" + | "shield-half" + | "shield" + | "shirt" + | "shuffle" + | "skull" + | "snow" + | "sparkles" + | "speedometer" + | "square" + | "star-half" + | "star" + | "stats-chart" + | "stop-circle" + | "stop" + | "stopwatch" + | "storefront" + | "subway" + | "sunny" + | "swap-horizontal" + | "swap-vertical" + | "sync-circle" + | "sync" + | "tablet-landscape" + | "tablet-portrait" + | "telescope" + | "tennisball" + | "terminal" + | "text" + | "thermometer" + | "thumbs-down" + | "thumbs-up" + | "thunderstorm" + | "ticket" + | "time" + | "timer" + | "today" + | "toggle" + | "trail-sign" + | "train" + | "transgender" + | "trash-bin" + | "trash" + | "trending-down" + | "trending-up" + | "triangle" + | "trophy" + | "tv" + | "umbrella" + | "unlink" + | "videocam-off" + | "videocam" + | "volume-high" + | "volume-low" + | "volume-medium" + | "volume-mute" + | "volume-off" + | "walk" + | "wallet" + | "warning" + | "watch" + | "water" + | "wifi" + | "wine" + | "woman" + | "logo-alipay" + | "logo-amazon" + | "logo-amplify" + | "logo-android" + | "logo-angular" + | "logo-apple" + | "logo-apple-appstore" + | "logo-apple-ar" + | "logo-behance" + | "logo-bitbucket" + | "logo-bitcoin" + | "logo-buffer" + | "logo-capacitor" + | "logo-chrome" + | "logo-closed-captioning" + | "logo-codepen" + | "logo-css3" + | "logo-designernews" + | "logo-deviantart" + | "logo-discord" + | "logo-docker" + | "logo-dribbble" + | "logo-dropbox" + | "logo-edge" + | "logo-electron" + | "logo-euro" + | "logo-facebook" + | "logo-figma" + | "logo-firebase" + | "logo-firefox" + | "logo-flickr" + | "logo-foursquare" + | "logo-github" + | "logo-gitlab" + | "logo-google" + | "logo-google-playstore" + | "logo-hackernews" + | "logo-html5" + | "logo-instagram" + | "logo-ionic" + | "logo-ionitron" + | "logo-javascript" + | "logo-laravel" + | "logo-linkedin" + | "logo-markdown" + | "logo-mastodon" + | "logo-medium" + | "logo-microsoft" + | "logo-no-smoking" + | "logo-nodejs" + | "logo-npm" + | "logo-octocat" + | "logo-paypal" + | "logo-pinterest" + | "logo-playstation" + | "logo-pwa" + | "logo-python" + | "logo-react" + | "logo-reddit" + | "logo-rss" + | "logo-sass" + | "logo-skype" + | "logo-slack" + | "logo-snapchat" + | "logo-soundcloud" + | "logo-stackoverflow" + | "logo-steam" + | "logo-stencil" + | "logo-tableau" + | "logo-tiktok" + | "logo-tumblr" + | "logo-tux" + | "logo-twitch" + | "logo-twitter" + | "logo-usd" + | "logo-venmo" + | "logo-vercel" + | "logo-vimeo" + | "logo-vk" + | "logo-vue" + | "logo-web-component" + | "logo-wechat" + | "logo-whatsapp" + | "logo-windows" + | "logo-wordpress" + | "logo-xbox" + | "logo-xing" + | "logo-yahoo" + | "logo-yen" + | "logo-youtube"; + +export type GoabIconSize = "small" | "medium" | "large" | "xlarge"; +export type GoabIconTheme = "outline" | "filled"; +export type GoabIconButtonVariant = "color" | "nocolor" | "dark" | "destructive"; +export type GoabIconVariant = "primary" | "secondary" | "tertiary"; + +// Common + +export type NumericSpacing = + | "0" + | "1" + | "2" + | "3" + | "4" + | "5" + | "6" + | "7" + | "8" + | "9" + | "10"; + +export type TShirtSpacing = + | "none" + | "3xs" + | "2xs" + | "xs" + | "s" + | "m" + | "l" + | "xl" + | "2xl" + | "3xl" + | "4xl"; + +export type Spacing = NumericSpacing | TShirtSpacing | null; + +export interface Margins { + mt?: Spacing; + mr?: Spacing; + mb?: Spacing; + ml?: Spacing; +} + +export type GoabBlockDirection = "row" | "column"; +export type GoabBlockAlignment = "center" | "start" | "end"; diff --git a/libs/common/tsconfig.json b/libs/common/tsconfig.json new file mode 100644 index 000000000..f098914cf --- /dev/null +++ b/libs/common/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} \ No newline at end of file diff --git a/libs/common/tsconfig.lib.json b/libs/common/tsconfig.lib.json new file mode 100644 index 000000000..faa09cc18 --- /dev/null +++ b/libs/common/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/libs/common/vite.config.ts b/libs/common/vite.config.ts new file mode 100644 index 000000000..7f121056e --- /dev/null +++ b/libs/common/vite.config.ts @@ -0,0 +1,43 @@ +/// +import { defineConfig } from "vite"; +import dts from "vite-plugin-dts"; +import * as path from "path"; +import { nxViteTsPaths } from "@nx/vite/plugins/nx-tsconfig-paths.plugin"; + +export default defineConfig({ + root: __dirname, + cacheDir: "../../node_modules/.vite/libs/common", + + plugins: [ + nxViteTsPaths(), + dts({ entryRoot: "src", tsconfigPath: path.join(__dirname, "tsconfig.lib.json") }), + ], + + // Uncomment this if you are using workers. + // worker: { + // plugins: [ nxViteTsPaths() ], + // }, + + // Configuration for building your library. + // See: https://vitejs.dev/guide/build.html#library-mode + build: { + outDir: "../../dist/libs/common", + reportCompressedSize: true, + commonjsOptions: { + transformMixedEsModules: true, + }, + lib: { + // Could also be a dictionary or array of multiple entry points. + entry: "src/index.ts", + name: "common", + fileName: "index", + // Change this to the formats you want to support. + // Don't forget to update your package.json as well. + formats: ["es", "cjs"], + }, + rollupOptions: { + // External packages that should not be bundled into your library. + external: [], + }, + }, +}); diff --git a/libs/react-components/CHANGELOG.md b/libs/react-components/CHANGELOG.md index e9c2b9c0a..c09d25c13 100644 --- a/libs/react-components/CHANGELOG.md +++ b/libs/react-components/CHANGELOG.md @@ -58,7 +58,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- onClick events inside a GoATable will now fire correctly +- onClick events inside a GoABTable will now fire correctly ## [4.12.0] - 2023-07-17 @@ -70,20 +70,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Added children properties for Accordion and Popover components -- Can no longer cause a page crash entering an invalid number with the `GoAInputDate` component +- Can no longer cause a page crash entering an invalid number with the `GoABInputDate` component ## [4.11.0] - 2023-06-19 -- Added a new wrapper for `GoATableSortHeader` -- Added an `ariaLive` property for `GoANotification` -- Added an `ariaLabel` property for `GoABadge` -- New component added, `GoAAppHeaderMenu` for use inside `GoAAppHeader` -- New `position` property added to `GoAPopover` -- Added `open` property to `GoADetails` -- Added `maxLength` property to `GoAInput` -- Added new `GoAFormStepStatusType` for `GoAFormStep` component, to be used to remove eslint messages -- Added new `GoASideMenuGroup` and `GoASideMenu` component -- Fixed an issue with the clear button on `GoAInputDate` - it no longer returns a value +- Added a new wrapper for `GoABTableSortHeader` +- Added an `ariaLive` property for `GoABNotification` +- Added an `ariaLabel` property for `GoABBadge` +- New component added, `GoABAppHeaderMenu` for use inside `GoABAppHeader` +- New `position` property added to `GoABPopover` +- Added `open` property to `GoABDetails` +- Added `maxLength` property to `GoABInput` +- Added new `GoABFormStepStatusType` for `GoABFormStep` component, to be used to remove eslint messages +- Added new `GoABSideMenuGroup` and `GoABSideMenu` component +- Fixed an issue with the clear button on `GoABInputDate` - it no longer returns a value ## [4.10.0] - 2023-04-21 @@ -110,8 +110,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New component [Details](https://ui-components.alberta.ca/?path=/docs/components-details--basic) - New component [Accordion](https://ui-components.alberta.ca/?path=/docs/components-accordion--basic) -- New feature for `GoATable`, [Sortable](https://ui-components.alberta.ca/?path=/docs/components-table--sortable) -- New property for `GoANotificationBanner`, [onDismiss](https://ui-components.alberta.ca/?path=/docs/components-notification-banner--types) +- New feature for `GoABTable`, [Sortable](https://ui-components.alberta.ca/?path=/docs/components-table--sortable) +- New property for `GoABNotificationBanner`, [onDismiss](https://ui-components.alberta.ca/?path=/docs/components-notification-banner--types) - New property has been added to all components, `testid` is available for supporting automated testing ## [4.5.0] - 2023-01-31 @@ -130,16 +130,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- `GoATable` has a new `relaxed` [variant](https://ui-components.alberta.ca/?path=/docs/components-table--relaxed-variant) +- `GoABTable` has a new `relaxed` [variant](https://ui-components.alberta.ca/?path=/docs/components-table--relaxed-variant) ## [4.3.0] - 2023-01-04 ### Added -- `ariaLabel` property added for `GoACheckbox` and `GoARadioGroup` components -- New `GoAHeroBanner` property, [minHeight](https://ui-components.alberta.ca/?path=/docs/components-hero-banner--min-height) +- `ariaLabel` property added for `GoABCheckbox` and `GoABRadioGroup` components +- New `GoABHeroBanner` property, [minHeight](https://ui-components.alberta.ca/?path=/docs/components-hero-banner--min-height) - New component [Table](https://ui-components.alberta.ca/?path=/docs/components-table--basic) -- New `GoADropdown` property, [native](https://ui-components.alberta.ca/?path=/docs/components-dropdown--native) +- New `GoABDropdown` property, [native](https://ui-components.alberta.ca/?path=/docs/components-dropdown--native) ### Changed diff --git a/libs/react-components/package.json b/libs/react-components/package.json index fbfa07b20..6c2b8d06e 100644 --- a/libs/react-components/package.json +++ b/libs/react-components/package.json @@ -6,7 +6,7 @@ "url": "https://github.com/GovAlta/ui-components/issues" }, "keywords": [ - "GoA", + "GoAB", "ui-components", "React" ], diff --git a/libs/react-components/project.json b/libs/react-components/project.json index d85600824..eb588b7fe 100644 --- a/libs/react-components/project.json +++ b/libs/react-components/project.json @@ -5,7 +5,8 @@ "projectType": "library", "tags": [], "implicitDependencies": [ - "web-components" + "web-components", + "common" ], "targets": { "lint": { diff --git a/libs/react-components/src/common/styling.ts b/libs/react-components/src/common/styling.ts deleted file mode 100644 index de7420693..000000000 --- a/libs/react-components/src/common/styling.ts +++ /dev/null @@ -1,36 +0,0 @@ -type NumericSpacing = - | "0" - | "1" - | "2" - | "3" - | "4" - | "5" - | "6" - | "7" - | "8" - | "9" - | "10"; - -type TShirtSpacing = - | "none" - | "3xs" - | "2xs" - | "xs" - | "s" - | "m" - | "l" - | "xl" - | "2xl" - | "3xl" - | "4xl"; - -export type Spacing = NumericSpacing | TShirtSpacing | null; - -export interface Margins { - mt?: Spacing; - mr?: Spacing; - mb?: Spacing; - ml?: Spacing; -} -export type Direction = "row" | "column"; -export type Alignment = "center" | "start" | "end"; diff --git a/libs/react-components/src/experimental/resizable-panel/ResizablePanel.tsx b/libs/react-components/src/experimental/resizable-panel/ResizablePanel.tsx index 3903df8e1..dd443b5fb 100644 --- a/libs/react-components/src/experimental/resizable-panel/ResizablePanel.tsx +++ b/libs/react-components/src/experimental/resizable-panel/ResizablePanel.tsx @@ -1,6 +1,6 @@ import { ReactNode, useEffect, useRef, useState } from "react"; import Css from "./ResizablePanel.module.css"; -import { GoAIcon } from "../../lib/icon/icon"; +import { GoabIcon } from "../../lib/icon/icon"; export type ResizableProps = { minWidth?: number; @@ -10,16 +10,16 @@ export type ResizableProps = { type MouseState = "static" | "active"; export function ResizablePanel(props: ResizableProps): JSX.Element { - // value refs - const maxWidth = useRef(0); - const resizeBarState = useRef("static"); - // element refs const bgRef = useRef(null); const sectionRef = useRef(null); const widthRef = useRef(null); const handleRef = useRef(null); + // value refs + const maxWidth = useRef(0); + const resizeBarState = useRef("static"); + // state const [width, setWidth] = useState(); @@ -91,7 +91,7 @@ export function ResizablePanel(props: ResizableProps): JSX.Element {
{props.children}
- +
diff --git a/libs/react-components/src/index.ts b/libs/react-components/src/index.ts index 4fcbf4c61..91486aaf6 100644 --- a/libs/react-components/src/index.ts +++ b/libs/react-components/src/index.ts @@ -59,5 +59,3 @@ export * from "./lib/three-column-layout/three-column-layout"; export * from "./lib/tooltip/tooltip"; export * from "./lib/two-column-layout/two-column-layout"; export * from "./lib/filter-chip/filter-chip"; - -export * from "./common/styling"; diff --git a/libs/react-components/src/lib/accordion/accordion.spec.tsx b/libs/react-components/src/lib/accordion/accordion.spec.tsx index a9f3a61c7..a0ec1f752 100644 --- a/libs/react-components/src/lib/accordion/accordion.spec.tsx +++ b/libs/react-components/src/lib/accordion/accordion.spec.tsx @@ -1,31 +1,29 @@ import { render } from "@testing-library/react"; -import { GoABadge } from "../badge/badge"; +import { GoabBadge } from "../badge/badge"; -import { GoAAccordion } from "./accordion"; +import { GoabAccordion } from "./accordion"; describe("Accordion", () => { it("should render successfully", () => { const { baseElement } = render( - Accordion Content + Accordion Content, ); const el = baseElement.querySelector("goa-accordion"); - expect(el.getAttribute("heading")).toBe("The heading"); + expect(el?.getAttribute("heading")).toBe("The heading"); expect(baseElement.innerHTML).toContain("Accordion Content"); }); it("should set the props correctly", () => { const { baseElement } = render( - - } + headingContent={} maxWidth="480px" > Accordion Content - + , ); const el = baseElement.querySelector("goa-accordion"); const headingContent = el?.querySelector("[slot='headingcontent']"); diff --git a/libs/react-components/src/lib/accordion/accordion.tsx b/libs/react-components/src/lib/accordion/accordion.tsx index 7783dab61..6ace50d35 100644 --- a/libs/react-components/src/lib/accordion/accordion.tsx +++ b/libs/react-components/src/lib/accordion/accordion.tsx @@ -1,13 +1,13 @@ -import React, { ReactNode, useEffect, useRef } from "react"; -import { Margins } from "../../common/styling"; +import { ReactNode , useEffect, useRef} from "react"; -export type GoAHeadingSize = "small" | "medium"; +import type { GoabAccordionHeadingSize, Margins } from "@abgov/ui-components-common"; +// TODO: move to ts export type GoAIconPosition = "left" | "right"; interface WCProps extends Margins { ref: React.RefObject; open?: boolean; - headingSize?: GoAHeadingSize; + headingSize?: GoabAccordionHeadingSize; heading: string; secondaryText?: string; headingContent?: ReactNode; @@ -25,9 +25,9 @@ declare global { } } -export interface GoAAccordionProps extends Margins { +export interface GoabAccordionProps extends Margins { open?: boolean; - headingSize?: GoAHeadingSize; + headingSize?: GoabAccordionHeadingSize; secondaryText?: string; heading: string; headingContent?: ReactNode; @@ -38,7 +38,7 @@ export interface GoAAccordionProps extends Margins { children: ReactNode; } -export function GoAAccordion({ +export function GoabAccordion({ open, heading, headingSize, @@ -53,7 +53,7 @@ export function GoAAccordion({ mr, mb, ml, -}: GoAAccordionProps): JSX.Element { +}: GoabAccordionProps): JSX.Element { const ref = useRef(null); useEffect(() => { @@ -69,7 +69,6 @@ export function GoAAccordion({ }; } }, [onChange]); - return ( { it("should render with no children", () => { - const { baseElement } = render(); + const { baseElement } = render(); const el = baseElement.querySelector("goa-app-header-menu"); expect(el).toBeTruthy(); - expect(el.getAttribute("heading")).toBe("Some label"); + expect(el?.getAttribute("heading")).toBe("Some label"); }); it("should render children", () => { const { baseElement } = render( - + Foo Bar - + , ); const el = baseElement.querySelector("goa-app-header-menu"); expect(el).toBeTruthy(); @@ -28,11 +27,8 @@ describe("AppHeaderMenu", () => { it("should set the props correctly", () => { const { baseElement } = render( - ); + , + ); const el = baseElement.querySelector("goa-app-header-menu"); expect(el).toBeTruthy(); expect(el?.getAttribute("heading")).toBe("Some label"); diff --git a/libs/react-components/src/lib/app-header-menu/app-header-menu.tsx b/libs/react-components/src/lib/app-header-menu/app-header-menu.tsx index ff20d965d..d62cb7444 100644 --- a/libs/react-components/src/lib/app-header-menu/app-header-menu.tsx +++ b/libs/react-components/src/lib/app-header-menu/app-header-menu.tsx @@ -1,5 +1,5 @@ import { ReactNode } from "react"; -import { GoAIconType } from "../icon/icon"; +import { GoabIconType } from "@abgov/ui-components-common"; interface WCProps { heading: string; @@ -8,9 +8,9 @@ interface WCProps { } /* eslint-disable-next-line */ -export interface GoAAppHeaderMenuProps { +export interface GoabAppHeaderMenuProps { heading: string; - leadingIcon?: GoAIconType; + leadingIcon?: GoabIconType; testId?: string; children?: ReactNode; } @@ -25,7 +25,7 @@ declare global { } } -export function GoAAppHeaderMenu(props: GoAAppHeaderMenuProps) { +export function GoabAppHeaderMenu(props: GoabAppHeaderMenuProps) { return ( { +describe("GoABAppHeader", () => { it("should render", () => { - const { baseElement } = render( - - ); + const { baseElement } = render(); const header = baseElement.querySelector("goa-app-header"); expect(header).toBeTruthy(); diff --git a/libs/react-components/src/lib/app-header/app-header.tsx b/libs/react-components/src/lib/app-header/app-header.tsx index 05d3ef889..5e72ea8da 100644 --- a/libs/react-components/src/lib/app-header/app-header.tsx +++ b/libs/react-components/src/lib/app-header/app-header.tsx @@ -19,7 +19,7 @@ declare global { } } -export interface GoAAppHeaderProps { +export interface GoabAppHeaderProps { heading?: string; url?: string; maxContentWidth?: string; @@ -29,7 +29,7 @@ export interface GoAAppHeaderProps { testId?: string; } -export function GoAAppHeader({ +export function GoabAppHeader({ heading, url, maxContentWidth, @@ -37,7 +37,7 @@ export function GoAAppHeader({ testId, children, onMenuClick, -}: GoAAppHeaderProps): JSX.Element { +}: GoabAppHeaderProps): JSX.Element { const el = useRef(null); useEffect(() => { @@ -72,4 +72,4 @@ export function GoAAppHeader({ ); } -export default GoAAppHeader; +export default GoabAppHeader; diff --git a/libs/react-components/src/lib/badge/badge.spec.tsx b/libs/react-components/src/lib/badge/badge.spec.tsx index d080fa25f..b2b5daf56 100644 --- a/libs/react-components/src/lib/badge/badge.spec.tsx +++ b/libs/react-components/src/lib/badge/badge.spec.tsx @@ -1,12 +1,10 @@ import { render } from "@testing-library/react"; -import { GoABadge } from "./badge"; +import { GoabBadge } from "./badge"; import { screen } from "@testing-library/dom"; -describe("GoA Badge", () => { +describe("GoAB Badge", () => { it("should render", () => { - render( - - ); + render(); const badge = screen.findByTestId("badge-test"); expect(badge).toBeTruthy(); @@ -14,7 +12,7 @@ describe("GoA Badge", () => { it("should render the properties", () => { const { container } = render( - { mb="l" ml="xl" ariaLabel="text" - /> + />, ); const el = container.querySelector("goa-badge"); diff --git a/libs/react-components/src/lib/badge/badge.tsx b/libs/react-components/src/lib/badge/badge.tsx index aaf885ad4..41302b3e6 100644 --- a/libs/react-components/src/lib/badge/badge.tsx +++ b/libs/react-components/src/lib/badge/badge.tsx @@ -1,16 +1,7 @@ -import { Margins } from "../../common/styling"; - -export type GoABadgeType = - | "information" - | "success" - | "important" - | "emergency" - | "dark" - | "midtone" - | "light"; +import { GoabBadgeType, Margins } from "@abgov/ui-components-common"; interface WCProps extends Margins { - type: GoABadgeType; + type: GoabBadgeType; icon?: boolean; content?: string; arialabel?: string; @@ -27,15 +18,15 @@ declare global { } } -export interface GoABadgeProps extends Margins { - type: GoABadgeType; +export interface GoabBadgeProps extends Margins { + type: GoabBadgeType; icon?: boolean; content?: string; testId?: string; ariaLabel?: string; } -export function GoABadge({ +export function GoabBadge({ type, content, icon, @@ -45,7 +36,7 @@ export function GoABadge({ mb, ml, ariaLabel, -}: GoABadgeProps): JSX.Element { +}: GoabBadgeProps): JSX.Element { return ( { it("should render successfully", () => { - const { baseElement } = render(); + const { baseElement } = render(); expect(baseElement).toBeTruthy(); }); it("should render the properties", () => { const { container } = render( - { mr="m" mb="l" ml="xl" - /> + />, ); const el = container.querySelector("goa-block"); diff --git a/libs/react-components/src/lib/block/block.tsx b/libs/react-components/src/lib/block/block.tsx index d2897e746..502c039b3 100644 --- a/libs/react-components/src/lib/block/block.tsx +++ b/libs/react-components/src/lib/block/block.tsx @@ -1,10 +1,15 @@ +import { + GoabBlockAlignment, + GoabBlockDirection, + Margins, + Spacing, +} from "@abgov/ui-components-common"; import { ReactNode } from "react"; -import { Alignment, Direction, Margins, Spacing } from "../../common/styling"; export interface WCProps extends Margins { gap?: Spacing; - direction?: Direction; - alignment?: Alignment; + direction?: GoabBlockDirection; + alignment?: GoabBlockAlignment; testid?: string; } @@ -19,18 +24,15 @@ declare global { } /* eslint-disable-next-line */ -export interface GoABlockProps extends Margins { +export interface GoabBlockProps extends Margins { gap?: Spacing; - direction?: Direction; - alignment?: Alignment; + direction?: GoabBlockDirection; + alignment?: GoabBlockAlignment; testId?: string; children?: ReactNode; } -// legacy -export type BlockProps = GoABlockProps; - -export function GoABlock(props: GoABlockProps) { +export function GoabBlock(props: GoabBlockProps) { return ( { +describe("GoAB Button", () => { const buttonText = "Test Title"; - const noop = () => { /* do nothing */ }; + const noop = () => { + /* do nothing */ + }; it("should render the properties", () => { const { container } = render( - { mr="m" mb="l" ml="xl" - /> + />, ); const el = container.querySelector("goa-button"); @@ -40,7 +43,13 @@ describe("GoA Button", () => { it("should render content", () => { const { baseElement } = render( - { /* do nothing */ }}>{buttonText} + { + /* do nothing */ + }} + > + {buttonText} + , ); expect(baseElement).toBeTruthy(); @@ -48,12 +57,12 @@ describe("GoA Button", () => { }); describe("size", () => { - (["compact", "normal"] as const).forEach((size: ButtonSize) => { + (["compact", "normal"] as const).forEach((size: GoabButtonSize) => { it(`should render ${size} size`, async () => { const { container } = render( - + Button - + , ); const button = container.querySelector("goa-button"); @@ -65,27 +74,25 @@ describe("GoA Button", () => { describe("type", () => { (["primary", "submit", "secondary", "tertiary"] as const).forEach( - (type: ButtonType) => { + (type: GoabButtonType) => { it(`should render ${type} type`, async () => { const { container } = render( - + Button - + , ); const button = container.querySelector("goa-button"); expect(button).toBeTruthy(); expect(button?.getAttribute("type")).toEqual(type); }); - } + }, ); }); it("responds to events", async () => { const onClick = vi.fn(); - const { container } = render( - Button - ); + const { container } = render(Button); const button = container.querySelector("goa-button"); expect(button).toBeTruthy(); button && fireEvent(button, new CustomEvent("_click")); diff --git a/libs/react-components/src/lib/button/button.tsx b/libs/react-components/src/lib/button/button.tsx index 44b201357..6f69c8a5d 100644 --- a/libs/react-components/src/lib/button/button.tsx +++ b/libs/react-components/src/lib/button/button.tsx @@ -1,26 +1,16 @@ import { ReactNode, useEffect, useRef } from "react"; -import { Margins } from "../../common/styling"; -import { GoAIconType } from "../icon/icon"; - -export type GoAButtonType = - | "primary" - | "submit" - | "secondary" - | "tertiary" - | "start"; - -export type GoAButtonSize = "compact" | "normal"; -export type GoAButtonVariant = "normal" | "destructive"; - -// legacy type names -export type ButtonType = GoAButtonType; -export type ButtonSize = GoAButtonSize; -export type ButtonVariant = GoAButtonVariant; +import { + GoabButtonSize, + GoabButtonType, + GoabButtonVariant, + GoabIconType, + Margins, +} from "@abgov/ui-components-common"; interface WCProps extends Margins { - type?: GoAButtonType; - size?: GoAButtonSize; - variant?: GoAButtonVariant; + type?: GoabButtonType; + size?: GoabButtonSize; + variant?: GoabButtonVariant; disabled?: boolean; leadingicon?: string; trailingicon?: string; @@ -39,20 +29,20 @@ declare global { } } -export interface GoAButtonProps extends Margins { - type?: GoAButtonType; - size?: GoAButtonSize; - variant?: GoAButtonVariant; +export interface GoabButtonProps extends Margins { + type?: GoabButtonType; + size?: GoabButtonSize; + variant?: GoabButtonVariant; disabled?: boolean; - leadingIcon?: GoAIconType; - trailingIcon?: GoAIconType; + leadingIcon?: GoabIconType; + trailingIcon?: GoabIconType; width?: string; onClick?: () => void; testId?: string; children?: ReactNode; } -export function GoAButton({ +export function GoabButton({ disabled = false, type = "primary", size, @@ -67,7 +57,7 @@ export function GoAButton({ mr, mb, ml, -}: GoAButtonProps): JSX.Element { +}: GoabButtonProps): JSX.Element { const el = useRef(null); useEffect(() => { if (!el.current) { @@ -108,4 +98,4 @@ export function GoAButton({ ); } -export default GoAButton; +export default GoabButton; diff --git a/libs/react-components/src/lib/calendar/calendar.tsx b/libs/react-components/src/lib/calendar/calendar.tsx index a1bf896fe..d04bd4dcf 100644 --- a/libs/react-components/src/lib/calendar/calendar.tsx +++ b/libs/react-components/src/lib/calendar/calendar.tsx @@ -1,5 +1,5 @@ import { useEffect, useRef } from "react"; -import { Margins } from "../../common/styling"; +import { GoabCalendarOnChangeDetail, Margins } from "@abgov/ui-components-common"; interface WCProps extends Margins { ref: React.RefObject; @@ -19,17 +19,16 @@ declare global { } } } - -export interface GoACalendarProps extends Margins { +export interface GoabCalendarProps extends Margins { name?: string; value?: Date; min?: Date; max?: Date; testId?: string; - onChange: (name: string, value: Date) => void; + onChange: (details: GoabCalendarOnChangeDetail) => void; } -export function GoACalendar({ +export function GoabCalendar({ name, value, min, @@ -40,7 +39,7 @@ export function GoACalendar({ mb, ml, onChange, -}: GoACalendarProps): JSX.Element { +}: GoabCalendarProps): JSX.Element { const ref = useRef(null); useEffect(() => { if (!ref.current) { @@ -48,7 +47,10 @@ export function GoACalendar({ } const current = ref.current; current.addEventListener("_change", (e: Event) => { - onChange(name || "", (e as CustomEvent).detail.value); + onChange({ + name: name || "", + value: (e as CustomEvent).detail.value, + }); }); }); @@ -68,4 +70,4 @@ export function GoACalendar({ ); } -export default GoACalendar; +export default GoabCalendar; diff --git a/libs/react-components/src/lib/callout/callout.spec.tsx b/libs/react-components/src/lib/callout/callout.spec.tsx index f87ae96ad..fe83ffa22 100644 --- a/libs/react-components/src/lib/callout/callout.spec.tsx +++ b/libs/react-components/src/lib/callout/callout.spec.tsx @@ -1,11 +1,11 @@ import React from "react"; import { render } from "@testing-library/react"; -import GoACallout from "./callout"; +import GoabCallout from "./callout"; describe("Callout", () => { test("Callout shall render", async () => { const result = render( - { > Information to the user goes in the content. Information can include markup as desired. - , + , ); const el = result.container.querySelector("goa-callout"); @@ -47,13 +47,13 @@ describe("Callout", () => { testCases.forEach(({ ariaLive, expected }) => { const result = render( - Test content - , + , ); const el = result.container.querySelector("goa-callout"); diff --git a/libs/react-components/src/lib/callout/callout.tsx b/libs/react-components/src/lib/callout/callout.tsx index ee0fff5e3..381488376 100644 --- a/libs/react-components/src/lib/callout/callout.tsx +++ b/libs/react-components/src/lib/callout/callout.tsx @@ -1,22 +1,14 @@ -import { Margins } from "../../common/styling"; +import { GoabCalloutAriaLive, GoabCalloutSize, GoabCalloutType, Margins } from "@abgov/ui-components-common"; -export type GoACalloutType = - | "important" - | "information" - | "event" - | "success" - | "emergency"; - -export type GoACalloutSize = "medium" | "large"; -export type GoACalloutAriaLive = "off" | "polite" | "assertive"; +// TODO: move to ts export type GoACalloutIconTheme = "outline" | "filled"; interface WCProps extends Margins { heading?: string; - type?: GoACalloutType; - size?: GoACalloutSize; + type?: GoabCalloutType; + size?: GoabCalloutSize; + arialive?: GoabCalloutAriaLive; maxwidth?: string; - arialive?: GoACalloutAriaLive; icontheme?: GoACalloutIconTheme; testid?: string; } @@ -30,20 +22,18 @@ declare global { } } -export interface GoACalloutProps extends Margins { +export interface GoabCalloutProps extends Margins { heading?: string; - type?: GoACalloutType; - size?: GoACalloutSize; + type?: GoabCalloutType; + size?: GoabCalloutSize; iconTheme?: GoACalloutIconTheme; maxWidth?: string; testId?: string; - ariaLive?: GoACalloutAriaLive; + ariaLive?: GoabCalloutAriaLive; children?: React.ReactNode; } -export type CalloutProps = GoACalloutProps; - -export const GoACallout = ({ +export const GoabCallout = ({ heading, type = "information", iconTheme = "outline", @@ -56,7 +46,7 @@ export const GoACallout = ({ mr, mb, ml, -}: GoACalloutProps) => { +}: GoabCalloutProps) => { return ( {children}; } -export default GoACardActions; +export default GoabCardActions; diff --git a/libs/react-components/src/lib/card/card-content.tsx b/libs/react-components/src/lib/card/card-content.tsx index 1dbdbd9a9..fb3958bf9 100644 --- a/libs/react-components/src/lib/card/card-content.tsx +++ b/libs/react-components/src/lib/card/card-content.tsx @@ -7,12 +7,12 @@ declare global { } } -export interface GoACardContentProps { +export interface GoabCardContentProps { children?: React.ReactNode; } -export function GoACardContent({ children }: GoACardContentProps): JSX.Element { +export function GoabCardContent({ children }: GoabCardContentProps): JSX.Element { return {children}; } -export default GoACardContent; +export default GoabCardContent; diff --git a/libs/react-components/src/lib/card/card-group.tsx b/libs/react-components/src/lib/card/card-group.tsx index e323e4efc..866eee0b0 100644 --- a/libs/react-components/src/lib/card/card-group.tsx +++ b/libs/react-components/src/lib/card/card-group.tsx @@ -7,12 +7,12 @@ declare global { } } -export interface GoACardGroupProps { +export interface GoabCardGroupProps { children?: React.ReactNode; } -export function GoACardGroup({ children }: GoACardGroupProps): JSX.Element { +export function GoabCardGroup({ children }: GoabCardGroupProps): JSX.Element { return {children}; } -export default GoACardGroup; +export default GoabCardGroup; diff --git a/libs/react-components/src/lib/card/card-image.tsx b/libs/react-components/src/lib/card/card-image.tsx index 51776b602..8499d9733 100644 --- a/libs/react-components/src/lib/card/card-image.tsx +++ b/libs/react-components/src/lib/card/card-image.tsx @@ -12,13 +12,13 @@ declare global { } } -export interface GoACardImageProps { +export interface GoabCardImageProps { src: string; height: string; } -export function GoACardImage({ src, height }: GoACardImageProps): JSX.Element { +export function GoabCardImage({ src, height }: GoabCardImageProps): JSX.Element { return ; } -export default GoACardImage; +export default GoabCardImage; diff --git a/libs/react-components/src/lib/card/card.spec.tsx b/libs/react-components/src/lib/card/card.spec.tsx index 5edd11cb9..7014a5195 100644 --- a/libs/react-components/src/lib/card/card.spec.tsx +++ b/libs/react-components/src/lib/card/card.spec.tsx @@ -1,10 +1,10 @@ import { render } from "@testing-library/react"; -import GoACard from "./card"; +import GoabCard from "./card"; -describe("GoA Card", () => { +describe("GoAB Card", () => { it("should render properties", () => { const { container } = render( - + , ); const el = container.querySelector("goa-card"); diff --git a/libs/react-components/src/lib/card/card.tsx b/libs/react-components/src/lib/card/card.tsx index 3285f207b..b8edeb310 100644 --- a/libs/react-components/src/lib/card/card.tsx +++ b/libs/react-components/src/lib/card/card.tsx @@ -1,4 +1,4 @@ -import { Margins } from "../../common/styling"; +import { Margins } from "@abgov/ui-components-common"; interface WCProps extends Margins { elevation?: number; @@ -15,14 +15,14 @@ declare global { } } -export interface GoACardProps extends Margins { +export interface GoabCardProps extends Margins { elevation?: number; width?: string; testId?: string; children?: React.ReactNode; } -export function GoACard({ +export function GoabCard({ elevation, width, mt, @@ -31,7 +31,7 @@ export function GoACard({ ml, testId, children, -}: GoACardProps): JSX.Element { +}: GoabCardProps): JSX.Element { return ( { +describe("GoAB Checkbox", () => { it("should render", () => { const props: CheckboxProps = { id: "abc", @@ -23,7 +24,7 @@ describe("GoA Checkbox", () => { ml: "xl", }; - render(); + render(); const checkbox = document.querySelector("goa-checkbox"); expect(checkbox).toBeTruthy(); @@ -43,7 +44,9 @@ describe("GoA Checkbox", () => { }); it("should render with text description", () => { - render(); + render( + , + ); const checkbox = document.querySelector("goa-checkbox"); expect(checkbox?.getAttribute("description")).toBe("description text"); @@ -51,18 +54,24 @@ describe("GoA Checkbox", () => { it("should render with slot description", () => { const result = render( - description slot
}/>); + description slot} + />, + ); const checkbox = document.querySelector("goa-checkbox"); expect(checkbox?.getAttribute("description")).toBe(null); - expect(result.container.querySelector('div[slot="description"]')?.innerHTML) - .toContain("description slot"); + expect( + result.container.querySelector('div[slot="description"]')?.innerHTML, + ).toContain("description slot"); }); it("should handle the onChange event", async function () { const onChangeStub = vi.fn(); - function onChange(name: string, checked: boolean, value: string) { + function onChange({ name, value, checked }: GoabCheckboxOnChangeDetail) { expect(name).toBe("foo"); expect(value).toBe("bar"); expect(checked).toBeTruthy(); @@ -80,14 +89,17 @@ describe("GoA Checkbox", () => { testId: testId, }; - render(); + render(); const checkbox = document.querySelector("goa-checkbox"); expect(checkbox).toBeTruthy(); - checkbox && fireEvent( - checkbox, - new CustomEvent("_change", { detail: { value: "bar", checked: true } }) - ); + checkbox && + fireEvent( + checkbox, + new CustomEvent("_change", { + detail: { name: "foo", value: "bar", checked: true }, + }), + ); expect(onChangeStub).toBeCalled(); }); }); diff --git a/libs/react-components/src/lib/checkbox/checkbox.tsx b/libs/react-components/src/lib/checkbox/checkbox.tsx index 41a436bdc..705c2c94d 100644 --- a/libs/react-components/src/lib/checkbox/checkbox.tsx +++ b/libs/react-components/src/lib/checkbox/checkbox.tsx @@ -1,5 +1,5 @@ +import { GoabCheckboxOnChangeDetail, Margins } from "@abgov/ui-components-common"; import { useEffect, useRef } from "react"; -import { Margins } from "../../common/styling"; declare global { // eslint-disable-next-line @typescript-eslint/no-namespace @@ -26,7 +26,7 @@ interface WCProps extends Margins { } /* eslint-disable-next-line */ -export interface GoACheckboxProps extends Margins { +export interface GoabCheckboxProps extends Margins { id?: string; name: string; checked?: boolean; @@ -39,13 +39,13 @@ export interface GoACheckboxProps extends Margins { ariaLabel?: string; description?: string | React.ReactNode; maxWidth?: string; - onChange?: (name: string, checked: boolean, value: string) => void; + onChange?: (detail: GoabCheckboxOnChangeDetail) => void; } // legacy -export type Props = GoACheckboxProps; +export type Props = GoabCheckboxProps; -export function GoACheckbox({ +export function GoabCheckbox({ id, name, testId, @@ -63,16 +63,16 @@ export function GoACheckbox({ mr, mb, ml, -}: GoACheckboxProps): JSX.Element { +}: GoabCheckboxProps): JSX.Element { const el = useRef(null); useEffect(() => { if (!el.current) { return; } const current = el.current; - const listener = (e: unknown) => { - const ce = e as CustomEvent; - onChange?.(name, ce.detail.checked, ce.detail.value); + const listener = (e: Event) => { + const detail = (e as CustomEvent).detail; + onChange?.(detail); }; current.addEventListener("_change", listener); @@ -101,10 +101,12 @@ export function GoACheckbox({ mb={mb} ml={ml} > - {description && typeof description !== "string" &&
{description}
} + {description && typeof description !== "string" && ( +
{description}
+ )} {children} ); } -export default GoACheckbox; +export default GoabCheckbox; diff --git a/libs/react-components/src/lib/chip/chip.spec.tsx b/libs/react-components/src/lib/chip/chip.spec.tsx index 95729606c..d920f0f16 100644 --- a/libs/react-components/src/lib/chip/chip.spec.tsx +++ b/libs/react-components/src/lib/chip/chip.spec.tsx @@ -1,23 +1,16 @@ import { fireEvent, render } from "@testing-library/react"; -import GoAChip from "./chip"; +import GoabChip from "./chip"; import { describe, it, expect, vi } from "vitest"; -describe("GoA Chip", () => { +describe("GoAB Chip", () => { it("should render", () => { - const { container } = render(); + const { container } = render(); expect(container.innerHTML).toContain("some chip"); }); it("should bind the properties", async () => { const { container } = render( - + , ); const el = container.querySelector("goa-chip"); @@ -32,9 +25,7 @@ describe("GoA Chip", () => { it("allows for the handling of the delete event", async () => { const onClick = vi.fn(); - const { container } = render( - - ); + const { container } = render(); const el = container.querySelector("goa-chip"); el && fireEvent(el, new CustomEvent("_click")); diff --git a/libs/react-components/src/lib/chip/chip.tsx b/libs/react-components/src/lib/chip/chip.tsx index 36534532d..63cb8644d 100644 --- a/libs/react-components/src/lib/chip/chip.tsx +++ b/libs/react-components/src/lib/chip/chip.tsx @@ -1,16 +1,15 @@ +import { GoabChipTheme, GoabChipVariant, Margins } from "@abgov/ui-components-common"; import { useEffect, useRef } from "react"; -import { Margins } from "../../common/styling"; -export type GoAChipVariant = "filter"; -export type GoAChipTheme = "outline" | "filled" | "sharp"; interface WCProps extends Margins { ref: React.RefObject; leadingicon: string; - icontheme: GoAChipTheme; + icontheme: GoabChipTheme; error: boolean; deletable: boolean; content: string; + variant?: GoabChipVariant; variant?: GoAChipVariant; testid?: string; } @@ -24,18 +23,18 @@ declare global { } } -export interface GoAChipProps extends Margins { +export interface GoabChipProps extends Margins { onClick?: () => void; deletable?: boolean; leadingIcon?: string; - iconTheme?: GoAChipTheme; + iconTheme?: GoabChipTheme; error?: boolean; content: string; - variant?: GoAChipVariant; + variant?: GoabChipVariant; testId?: string; } -export const GoAChip = ({ +export const GoabChip = ({ leadingIcon = "", iconTheme = "outline", deletable = false, @@ -48,7 +47,7 @@ export const GoAChip = ({ mb, ml, testId, -}: GoAChipProps) => { +}: GoabChipProps) => { const el = useRef(null); useEffect(() => { if (!el.current) return; @@ -83,4 +82,4 @@ export const GoAChip = ({ ); }; -export default GoAChip; +export default GoabChip; diff --git a/libs/react-components/src/lib/circular-progress/circular-progress.spec.tsx b/libs/react-components/src/lib/circular-progress/circular-progress.spec.tsx index a6e5ab00b..86a1769ea 100644 --- a/libs/react-components/src/lib/circular-progress/circular-progress.spec.tsx +++ b/libs/react-components/src/lib/circular-progress/circular-progress.spec.tsx @@ -1,34 +1,32 @@ import { render, waitFor } from "@testing-library/react"; -import { - GoACircularProgress, - CircularProgressVariant, -} from "./circular-progress"; +import { GoabCircularProgress } from "./circular-progress"; +import { GoabCircularProgressVariant } from "@abgov/ui-components-common"; describe("CircularProgress", () => { it("does not render anything when not visible", async () => { const { baseElement } = render( - + />, ); const el = baseElement.querySelector("goa-circular-progress"); expect(el?.innerHTML).toBeFalsy(); }); - (["fullscreen", "inline"] as const).forEach((variant: CircularProgressVariant) => { + (["fullscreen", "inline"] as const).forEach((variant: GoabCircularProgressVariant) => { [-1, 50].forEach((progress: number) => { it(`renders the ${variant} variant`, async () => { const { baseElement } = render( - + />, ); const el = baseElement.querySelector("goa-circular-progress"); await waitFor(() => { diff --git a/libs/react-components/src/lib/circular-progress/circular-progress.tsx b/libs/react-components/src/lib/circular-progress/circular-progress.tsx index 6d986942b..752f151e2 100644 --- a/libs/react-components/src/lib/circular-progress/circular-progress.tsx +++ b/libs/react-components/src/lib/circular-progress/circular-progress.tsx @@ -1,13 +1,11 @@ -export type GoACircularProgressVariant = "fullscreen" | "inline"; -export type GoACircularProgressSize = "small" | "large"; - -// legacy naming -export type CircularProgressVariant = GoACircularProgressVariant; -export type CircularProgressSize = GoACircularProgressSize; +import { + GoabCircularProgressSize, + GoabCircularProgressVariant, +} from "@abgov/ui-components-common"; interface WCProps { - variant?: GoACircularProgressVariant; - size?: GoACircularProgressSize; + variant?: GoabCircularProgressVariant; + size?: GoabCircularProgressSize; message?: string; visible?: string; progress?: number; @@ -23,23 +21,23 @@ declare global { } } -export interface GoACircularProgressProps { - variant?: GoACircularProgressVariant; - size?: GoACircularProgressSize; +export interface GoabCircularProgressProps { + variant?: GoabCircularProgressVariant; + size?: GoabCircularProgressSize; message?: string; visible?: boolean; progress?: number; testId?: string; } -export const GoACircularProgress = ({ +export const GoabCircularProgress = ({ visible, message, progress, variant, size, testId, -}: GoACircularProgressProps) => { +}: GoabCircularProgressProps) => { return ( ); -} +}; -export default GoACircularProgress; +export default GoabCircularProgress; diff --git a/libs/react-components/src/lib/container/container.spec.tsx b/libs/react-components/src/lib/container/container.spec.tsx index 71d5b294b..c579bf3cf 100644 --- a/libs/react-components/src/lib/container/container.spec.tsx +++ b/libs/react-components/src/lib/container/container.spec.tsx @@ -1,11 +1,11 @@ import { render } from "@testing-library/react"; -import GoAContainer from "./container"; -import { GoAButton } from "../button/button"; +import GoabContainer from "./container"; +import { GoabButton } from "../button/button"; describe("Container", () => { it("should render the properties", () => { const { container } = render( - { mr="m" mb="l" ml="xl" - actions={ { /* do nothing */ }}>Save} + actions={ + { + /* do nothing */ + }} + > + Save + + } > Container content - + , ); const el = container.querySelector("goa-container"); @@ -37,7 +45,7 @@ describe("Container", () => { expect(el?.querySelector("*[slot=title]")?.innerHTML).toContain("Text title"); expect( - el?.querySelector("*[slot=actions]")?.querySelector("goa-button") + el?.querySelector("*[slot=actions]")?.querySelector("goa-button"), ).not.toBeFalsy(); }); }); diff --git a/libs/react-components/src/lib/container/container.tsx b/libs/react-components/src/lib/container/container.tsx index 8fc98d2ce..1ccae44b0 100644 --- a/libs/react-components/src/lib/container/container.tsx +++ b/libs/react-components/src/lib/container/container.tsx @@ -1,22 +1,17 @@ +import { + GoabContainerAccent, + GoabContainerPadding, + GoabContainerType, + GoabContainerWidth, + Margins, +} from "@abgov/ui-components-common"; import { ReactNode } from "react"; -import { Margins } from "../../common/styling"; - -export type GoAContainerType = - | "interactive" - | "non-interactive" - | "info" - | "error" - | "success" - | "important"; -export type GoAContainerAccent = "thick" | "thin" | "filled"; -export type GoAContainerPadding = "relaxed" | "compact"; -export type GoAContainerWidth = "full" | "content"; interface WCProps extends Margins { - type?: GoAContainerType; - accent?: GoAContainerAccent; - padding?: GoAContainerPadding; - width?: GoAContainerWidth; + type?: GoabContainerType; + accent?: GoabContainerAccent; + padding?: GoabContainerPadding; + width?: GoabContainerWidth; maxwidth?: string; testid?: string; } @@ -30,20 +25,20 @@ declare global { } } -export interface GoAContainerProps extends Margins { - accent?: GoAContainerAccent; - type?: GoAContainerType; +export interface GoabContainerProps extends Margins { + accent?: GoabContainerAccent; + type?: GoabContainerType; heading?: ReactNode; title?: ReactNode; - padding?: GoAContainerPadding; + padding?: GoabContainerPadding; actions?: ReactNode; children?: ReactNode; - width?: GoAContainerWidth; + width?: GoabContainerWidth; maxWidth?: string; testId?: string; } -export function GoAContainer({ +export function GoabContainer({ accent, heading, title, @@ -58,7 +53,7 @@ export function GoAContainer({ mb, ml, testId, -}: GoAContainerProps): JSX.Element { +}: GoabContainerProps): JSX.Element { const headingContent = heading || title; return ( { }), ); - expect(onChange).toBeCalledWith(name, value); expect(onChange).toHaveBeenCalledTimes(1); + expect(onChange).toBeCalledWith({ name, value, type: "date" }); }); it("should render without relative property", () => { diff --git a/libs/react-components/src/lib/date-picker/date-picker.tsx b/libs/react-components/src/lib/date-picker/date-picker.tsx index fb7449f34..3ccf7d24b 100644 --- a/libs/react-components/src/lib/date-picker/date-picker.tsx +++ b/libs/react-components/src/lib/date-picker/date-picker.tsx @@ -1,5 +1,5 @@ import { useEffect, useRef } from "react"; -import { Margins } from "../../common/styling"; +import { GoabDatePickerOnChangeDetail, Margins } from "@abgov/ui-components-common"; interface WCProps extends Margins { ref: React.RefObject; @@ -23,7 +23,7 @@ declare global { } } -export interface GoADatePickerProps extends Margins { +export interface GoabDatePickerProps extends Margins { name?: string; value?: Date; error?: boolean; @@ -32,10 +32,10 @@ export interface GoADatePickerProps extends Margins { testId?: string; relative?: boolean; disabled?: boolean; - onChange?: (name: string, value: Date | undefined) => void; + onChange: (detail: GoabDatePickerOnChangeDetail) => void; } -export function GoADatePicker({ +export function GoabDatePicker({ name, value, error, @@ -49,8 +49,9 @@ export function GoADatePicker({ ml, relative, onChange, -}: GoADatePickerProps): JSX.Element { +}: GoabDatePickerProps): JSX.Element { const ref = useRef(null); + useEffect(() => { if (!ref.current) { return; @@ -58,8 +59,8 @@ export function GoADatePicker({ const current = ref.current; const handleChange = (e: Event) => { - const newValue = (e as CustomEvent).detail.value; - onChange?.(name || "", newValue ? new Date(newValue) : undefined); + const detail = (e as CustomEvent).detail; + onChange(detail); }; current.addEventListener("_change", handleChange); @@ -88,4 +89,4 @@ export function GoADatePicker({ ); } -export default GoADatePicker; +export default GoabDatePicker; diff --git a/libs/react-components/src/lib/details/details.spec.tsx b/libs/react-components/src/lib/details/details.spec.tsx index b5ea732ea..081723d35 100644 --- a/libs/react-components/src/lib/details/details.spec.tsx +++ b/libs/react-components/src/lib/details/details.spec.tsx @@ -1,18 +1,13 @@ import { render } from "@testing-library/react"; -import { GoADetails } from "./details"; +import { GoabDetails } from "./details"; describe("Detail", () => { it("should render successfully", () => { const { baseElement } = render( - + The content - + , ); const el = baseElement.querySelector("goa-details"); @@ -22,5 +17,4 @@ describe("Detail", () => { expect(el?.getAttribute("maxwidth")).toBe("480px"); expect(el?.getAttribute("testid")).toBe("foo"); }); - }); diff --git a/libs/react-components/src/lib/details/details.tsx b/libs/react-components/src/lib/details/details.tsx index d777daccb..b4e4e5035 100644 --- a/libs/react-components/src/lib/details/details.tsx +++ b/libs/react-components/src/lib/details/details.tsx @@ -1,5 +1,5 @@ +import { Margins } from "@abgov/ui-components-common"; import { ReactNode } from "react"; -import { Margins } from "../../common/styling"; interface WCProps extends Margins { heading: string; @@ -19,7 +19,7 @@ declare global { } /* eslint-disable-next-line */ -export interface GoADetailsProps extends Margins { +export interface GoabDetailsProps extends Margins { heading: string; open?: boolean; maxWidth?: string; @@ -27,9 +27,7 @@ export interface GoADetailsProps extends Margins { children: ReactNode; } -export type DetailsProps = GoADetailsProps; - -export function GoADetails(props: GoADetailsProps) { +export function GoabDetails(props: GoabDetailsProps) { return ( { it("should render successfully", () => { - const { container } = render(); + const { container } = render(); const el = container.querySelector("goa-divider"); diff --git a/libs/react-components/src/lib/divider/divider.tsx b/libs/react-components/src/lib/divider/divider.tsx index 0341519d7..89774e7bc 100644 --- a/libs/react-components/src/lib/divider/divider.tsx +++ b/libs/react-components/src/lib/divider/divider.tsx @@ -1,4 +1,4 @@ -import { Margins } from "../../common/styling"; +import { Margins } from "@abgov/ui-components-common"; interface WCProps extends Margins { testid?: string; @@ -13,11 +13,11 @@ declare global { } } -export interface GoADividerProps extends Margins { +export interface GoabDividerProps extends Margins { testId?: string; } -export function GoADivider(props: GoADividerProps) { +export function GoabDivider(props: GoabDividerProps) { return ( { - console.warn("GoADropdownOption is deprecated. Please use GoADropdownItem"); + console.warn("GoABDropdownOption is deprecated. Please use GoABDropdownItem"); }, []); - return ; + return ; } -export function GoADropdownItem({ value, label, filter, name, testId, mountType = "append" }: GoADropdownItemProps) { +export function GoabDropdownItem({ value, label, filter, name, testId, mountType = "append" }: GoabDropdownItemProps) { return ( { - it("should inform the user that GoADropdownOption is deprecated", async () => { - const mock = vi.spyOn(console, "warn").mockImplementation(() => { /* do nothing */ }); +describe("GoABDropdown", () => { + it("should inform the user that GoABDropdownOption is deprecated", async () => { + const mock = vi.spyOn(console, "warn").mockImplementation(() => { + /* do nothing */ + }); render( - { /* do nothing */ }}> - - + { + /* do nothing */ + }} + > + + , ); await waitFor(() => { @@ -23,7 +29,7 @@ describe("GoADropdown", () => { it("should bind all web-component attributes", async () => { const { baseElement } = render( - { ml="xl" ariaLabel={"label"} ariaLabelledBy={"foo-dropdown-label"} - onChange={() => { /* do nothing */ }} + onChange={() => { + /* do nothing */ + }} > - - - - + + + + , ); const el = baseElement.querySelector("goa-dropdown"); @@ -65,24 +73,25 @@ describe("GoADropdown", () => { const fn = vi.fn(); const { baseElement } = render( - - - - - + + + + + , ); const el = baseElement.querySelector("goa-dropdown"); expect(el).toBeTruthy(); - el && fireEvent( - el, - new CustomEvent("_change", { - detail: { name: "favColor", value: "blue" }, - }) - ); + el && + fireEvent( + el, + new CustomEvent("_change", { + detail: { name: "favColor", value: "blue" }, + }), + ); await waitFor(() => { - expect(fn).toBeCalledWith("favColor", "blue"); + expect(fn).toBeCalledWith({ name: "favColor", value: "blue" }); }); }); }); diff --git a/libs/react-components/src/lib/dropdown/dropdown.tsx b/libs/react-components/src/lib/dropdown/dropdown.tsx index b2ef46c6e..c69a6f4b1 100644 --- a/libs/react-components/src/lib/dropdown/dropdown.tsx +++ b/libs/react-components/src/lib/dropdown/dropdown.tsx @@ -1,6 +1,9 @@ +import { + GoabDropdownOnChangeDetail, + GoabIconType, + Margins, +} from "@abgov/ui-components-common"; import { useEffect, useRef } from "react"; -import { Margins } from "../../common/styling"; -import { GoAIconType } from "../icon/icon"; interface WCProps extends Margins { ref: React.MutableRefObject; @@ -32,10 +35,10 @@ declare global { } } -export interface GoADropdownProps extends Margins { +export interface GoabDropdownProps extends Margins { name?: string; value?: string[] | string; - onChange?: (name: string, values: string[] | string) => void; + onChange: (detail: GoabDropdownOnChangeDetail) => void; // optional ariaLabel?: string; @@ -45,7 +48,7 @@ export interface GoADropdownProps extends Margins { disabled?: boolean; error?: boolean; filterable?: boolean; - leadingIcon?: GoAIconType; + leadingIcon?: GoabIconType; maxHeight?: string; multiselect?: boolean; native?: boolean; @@ -65,16 +68,16 @@ function stringify(value: string | string[] | undefined): string { return JSON.stringify(value); } -export function GoADropdown(props: GoADropdownProps): JSX.Element { +export function GoabDropdown(props: GoabDropdownProps): JSX.Element { const el = useRef(null); useEffect(() => { if (!el.current) { return; } const current = el.current; - const handler = (e: unknown) => { - const { name, value, values } = (e as CustomEvent).detail; - props.onChange?.(name, props.multiselect ? values : value); + const handler = (e: Event) => { + const detail = (e as CustomEvent).detail; + props.onChange(detail); }; current.addEventListener("_change", handler); return () => { @@ -111,4 +114,4 @@ export function GoADropdown(props: GoADropdownProps): JSX.Element { ); } -export default GoADropdown; +export default GoabDropdown; diff --git a/libs/react-components/src/lib/file-upload-card/file-upload-card.tsx b/libs/react-components/src/lib/file-upload-card/file-upload-card.tsx index 49bdc2ac1..49305a1c3 100644 --- a/libs/react-components/src/lib/file-upload-card/file-upload-card.tsx +++ b/libs/react-components/src/lib/file-upload-card/file-upload-card.tsx @@ -1,3 +1,7 @@ +import { + GoabFileUploadOnCancelDetail, + GoabFileUploadOnDeleteDetail, +} from "@abgov/ui-components-common"; import { useEffect, useRef } from "react"; interface WCProps { @@ -21,18 +25,18 @@ declare global { } /* eslint-disable-next-line */ -export interface GoAFileUploadCardProps { +export interface GoabFileUploadCardProps { filename: string; size: number; type?: string; progress?: number; + testId: string; error?: string; - testId?: string; - onDelete?: () => void; - onCancel?: () => void; + onDelete?: (detail: GoabFileUploadOnDeleteDetail) => void; + onCancel?: (detail: GoabFileUploadOnCancelDetail) => void; } -export function GoAFileUploadCard({ +export function GoabFileUploadCard({ filename, size, type, @@ -41,15 +45,15 @@ export function GoAFileUploadCard({ testId, onDelete, onCancel, -}: GoAFileUploadCardProps) { +}: GoabFileUploadCardProps) { const el = useRef(null); useEffect(() => { if (!el.current) return; const current = el.current; - const deleteHandler = () => onDelete?.(); - const cancelHandler = () => onCancel?.(); + const deleteHandler = () => onDelete?.({ filename }); + const cancelHandler = () => onCancel?.({ filename }); current.addEventListener("_delete", deleteHandler); current.addEventListener("_cancel", cancelHandler); return () => { @@ -71,4 +75,4 @@ export function GoAFileUploadCard({ ); } -export default GoAFileUploadCard; +export default GoabFileUploadCard; diff --git a/libs/react-components/src/lib/file-upload-input/file-upload-input.tsx b/libs/react-components/src/lib/file-upload-input/file-upload-input.tsx index e822aab15..4470d5176 100644 --- a/libs/react-components/src/lib/file-upload-input/file-upload-input.tsx +++ b/libs/react-components/src/lib/file-upload-input/file-upload-input.tsx @@ -1,10 +1,12 @@ +import { + GoabFileUploadInputOnSelectFileDetail, + GoabFileUploadInputVariant, +} from "@abgov/ui-components-common"; import { useEffect, useRef } from "react"; -export type GoAFileUploadInputVariant = "dragdrop" | "button"; - interface WCProps { ref: React.MutableRefObject; - variant?: GoAFileUploadInputVariant; + variant?: GoabFileUploadInputVariant; accept?: string; maxfilesize?: string; testid?: string; @@ -21,21 +23,21 @@ declare global { } /* eslint-disable-next-line */ -export interface GoAFileUploadInputProps { - variant?: GoAFileUploadInputVariant; +export interface GoabFileUploadInputProps { + variant?: GoabFileUploadInputVariant; accept?: string; maxFileSize?: string; testId?: string; - onSelectFile: (file: File) => void; + onSelectFile: (detail: GoabFileUploadInputOnSelectFileDetail) => void; } -export function GoAFileUploadInput({ +export function GoabFileUploadInput({ variant, accept, maxFileSize, testId, onSelectFile, -}: GoAFileUploadInputProps) { +}: GoabFileUploadInputProps) { const el = useRef(null); useEffect(() => { @@ -43,7 +45,8 @@ export function GoAFileUploadInput({ const current = el.current; const handler = (e: Event) => { - onSelectFile((e as CustomEvent).detail.file); + const detail = (e as CustomEvent).detail; + onSelectFile(detail); }; current.addEventListener("_selectFile", handler); return () => { @@ -62,4 +65,4 @@ export function GoAFileUploadInput({ ); } -export default GoAFileUploadInput; +export default GoabFileUploadInput; diff --git a/libs/react-components/src/lib/footer-meta-section/footer-meta-section.tsx b/libs/react-components/src/lib/footer-meta-section/footer-meta-section.tsx index d59492ac5..eb8db5668 100644 --- a/libs/react-components/src/lib/footer-meta-section/footer-meta-section.tsx +++ b/libs/react-components/src/lib/footer-meta-section/footer-meta-section.tsx @@ -14,15 +14,15 @@ declare global { } /* eslint-disable-next-line */ -export interface GoAAppFooterMetaSectionProps { +export interface GoabAppFooterMetaSectionProps { testId?: string; children?: ReactNode; } -// legacy name -export type FooterMetaSectionProps = GoAAppFooterMetaSectionProps; - -export function GoAAppFooterMetaSection({ testId, children }: GoAAppFooterMetaSectionProps) { +export function GoabAppFooterMetaSection({ + testId, + children, +}: GoabAppFooterMetaSectionProps) { return ( {children} @@ -36,4 +36,4 @@ export function GoAAppFooter({ ); } -export default GoAAppFooter; +export default GoabAppFooter; diff --git a/libs/react-components/src/lib/form-item/form-item.spec.tsx b/libs/react-components/src/lib/form-item/form-item.spec.tsx index 5b702f67c..a99291b25 100644 --- a/libs/react-components/src/lib/form-item/form-item.spec.tsx +++ b/libs/react-components/src/lib/form-item/form-item.spec.tsx @@ -1,12 +1,12 @@ import { render, cleanup } from "@testing-library/react"; -import { GoAFormItem } from "./form-item"; +import { GoabFormItem } from "./form-item"; afterEach(cleanup); -describe("GoAFormItem", () => { +describe("GoABFormItem", () => { it("renders all with properties", () => { const { baseElement } = render( - { helpText="This is some help text" maxWidth="480px" id="firstName" - /> + />, ); const el = baseElement.querySelector("goa-form-item"); expect(el?.getAttribute("label")).toEqual("First Name"); diff --git a/libs/react-components/src/lib/form-item/form-item.tsx b/libs/react-components/src/lib/form-item/form-item.tsx index bcd9631ee..4e3a737cb 100644 --- a/libs/react-components/src/lib/form-item/form-item.tsx +++ b/libs/react-components/src/lib/form-item/form-item.tsx @@ -1,12 +1,13 @@ -import { Margins } from "../../common/styling"; - -export type GoAFormItemRequirement = "optional" | "required"; -export type GoAFormItemLabelSize = "regular" | "large"; +import { + GoabFormItemLabelSize, + GoabFormItemRequirement, + Margins, +} from "@abgov/ui-components-common"; interface WCProps extends Margins { label?: string; - labelsize?: GoAFormItemLabelSize; - requirement?: GoAFormItemRequirement; + labelsize?: GoabFormItemLabelSize; + requirement?: GoabFormItemRequirement; error?: string; helptext?: string; maxwidth?: string; @@ -23,19 +24,19 @@ declare global { } } -export interface GoAFormItemProps extends Margins { +export interface GoabFormItemprops extends Margins { label?: string; - labelSize?: GoAFormItemLabelSize; - requirement?: GoAFormItemRequirement; - error?: React.ReactNode; - helpText?: React.ReactNode; + labelSize?: GoabFormItemLabelSize; + requirement?: GoabFormItemRequirement; + error?: string | React.ReactNode; + helpText?: string | React.ReactNode; maxWidth?: string; children?: React.ReactNode; testId?: string; id?: string; } -export function GoAFormItem({ +export function GoabFormItem({ children, helpText, error, @@ -49,7 +50,7 @@ export function GoAFormItem({ ml, testId, id, -}: GoAFormItemProps): JSX.Element { +}: GoabFormItemprops): JSX.Element { return ( ; } -export default GoAFormStep; +export default GoabFormStep; diff --git a/libs/react-components/src/lib/form-stepper/form-stepper.tsx b/libs/react-components/src/lib/form-stepper/form-stepper.tsx index f398235e8..441c9ddd3 100644 --- a/libs/react-components/src/lib/form-stepper/form-stepper.tsx +++ b/libs/react-components/src/lib/form-stepper/form-stepper.tsx @@ -1,5 +1,5 @@ +import { GoabFormStepperOnChangeDetail, Margins } from "@abgov/ui-components-common"; import { ReactNode, useEffect, useRef } from "react"; -import { Margins } from "../../common/styling"; interface WCProps extends Margins { ref?: React.MutableRefObject; @@ -17,17 +17,14 @@ declare global { } } -export interface GoAFormStepperProps extends Margins { +export interface GoabFormStepperProps extends Margins { step?: number; testId?: string; children?: ReactNode; - onChange?: (step: number) => void; + onChange?: (detail: GoabFormStepperOnChangeDetail) => void; } -// legacy -export type FormStepperProps = GoAFormStepperProps; - -export function GoAFormStepper({ +export function GoabFormStepper({ testId, step, mt, @@ -36,7 +33,7 @@ export function GoAFormStepper({ mr, onChange, children, -}: GoAFormStepperProps) { +}: GoabFormStepperProps) { const ref = useRef(null); useEffect(() => { if (!ref.current) { @@ -44,8 +41,8 @@ export function GoAFormStepper({ } const current = ref.current; const changeListener = (e: unknown) => { - const { step } = (e as CustomEvent).detail; - onChange?.(+step); + const detail = (e as CustomEvent).detail; + onChange?.(detail); }; current.addEventListener("_change", changeListener); @@ -69,4 +66,4 @@ export function GoAFormStepper({ ); } -export default GoAFormStepper; +export default GoabFormStepper; diff --git a/libs/react-components/src/lib/grid/grid.tsx b/libs/react-components/src/lib/grid/grid.tsx index 6f0675cb3..8f9cfcdeb 100644 --- a/libs/react-components/src/lib/grid/grid.tsx +++ b/libs/react-components/src/lib/grid/grid.tsx @@ -1,4 +1,4 @@ -import { Margins, Spacing } from "../../common/styling"; +import { Margins, Spacing } from "@abgov/ui-components-common"; interface WCProps extends Margins { gap?: Spacing; @@ -15,14 +15,14 @@ declare global { } } -export interface GoAGridProps extends Margins { +export interface GoabGridProps extends Margins { gap?: Spacing; minChildWidth: string; testId?: string; children?: React.ReactNode; } -export function GoAGrid({ +export function GoabGrid({ gap, minChildWidth, mt, @@ -31,7 +31,7 @@ export function GoAGrid({ ml, testId, children, -}: GoAGridProps): JSX.Element { +}: GoabGridProps): JSX.Element { return ( {children}; } -export default GoAHeroBannerActions; +export default GoabHeroBannerActions; diff --git a/libs/react-components/src/lib/hero-banner/hero-banner.spec.tsx b/libs/react-components/src/lib/hero-banner/hero-banner.spec.tsx index cbf658cf4..b844b40e6 100644 --- a/libs/react-components/src/lib/hero-banner/hero-banner.spec.tsx +++ b/libs/react-components/src/lib/hero-banner/hero-banner.spec.tsx @@ -1,21 +1,21 @@ import { render, cleanup } from "@testing-library/react"; -import GoAHeroBanner from "./hero-banner"; -import { GoAHeroBannerActions } from "./hero-banner-actions"; -import GoAButton from "../button/button"; +import GoabHeroBanner from "./hero-banner"; +import { GoabHeroBannerActions } from "./hero-banner-actions"; +import GoabButton from "../button/button"; afterEach(cleanup); -describe("GoAHeroBanner", () => { +describe("GoABHeroBanner", () => { it("renders all with properties", () => { const { baseElement } = render( - + />, ); const el = baseElement.querySelector("goa-hero-banner"); expect(el?.getAttribute("heading")).toEqual("Upgrading our bitumen"); @@ -24,17 +24,13 @@ describe("GoAHeroBanner", () => { expect(el?.getAttribute("textcolor")).toEqual("#fff"); expect(el?.getAttribute("minheight")).toEqual("500px"); expect(el?.getAttribute("maxcontentwidth")).toEqual("500px"); - }); it("renders content", async () => { const { baseElement } = render( - + This is the hero banner content - + , ); const el = baseElement.querySelector("goa-hero-banner"); expect(el?.innerHTML).toContain("This is the hero banner content"); @@ -42,15 +38,18 @@ describe("GoAHeroBanner", () => { it("renders actions", async () => { const { baseElement } = render( - + This is the hero banner content - - { /* do nothing */ }}>Submit - - + + { + /* do nothing */ + }} + > + Submit + + + , ); const el = baseElement.querySelector("goa-hero-banner goa-button"); expect(el?.textContent).toBe("Submit"); @@ -59,10 +58,7 @@ describe("GoAHeroBanner", () => { describe("Min Height", () => { it("uses the default min height", async () => { const { baseElement } = render( - + , ); const el = baseElement.querySelector("goa-hero-banner"); expect(el?.getAttribute("minheight")).toBeNull(); @@ -70,11 +66,11 @@ describe("GoAHeroBanner", () => { it("uses the min height when supplied", async () => { const { baseElement } = render( - + />, ); const el = baseElement.querySelector("goa-hero-banner"); expect(el?.getAttribute("minheight")).toBe("700px"); diff --git a/libs/react-components/src/lib/hero-banner/hero-banner.tsx b/libs/react-components/src/lib/hero-banner/hero-banner.tsx index 1decc75fd..09a45f12b 100644 --- a/libs/react-components/src/lib/hero-banner/hero-banner.tsx +++ b/libs/react-components/src/lib/hero-banner/hero-banner.tsx @@ -17,7 +17,7 @@ declare global { } } -export interface GoAHeroBannerProps { +export interface GoabHeroBannerProps { heading: string; backgroundUrl?: string; minHeight?: string; @@ -28,7 +28,7 @@ export interface GoAHeroBannerProps { textColor?: string; } -export function GoAHeroBanner({ +export function GoabHeroBanner({ heading, backgroundUrl, minHeight, @@ -37,7 +37,7 @@ export function GoAHeroBanner({ textColor, children, testId, -}: GoAHeroBannerProps): JSX.Element { +}: GoabHeroBannerProps): JSX.Element { return ( { +describe("GoAB IconButton", () => { it("should render the properties", () => { const { container } = render( - + , ); const el = container.querySelector("goa-icon-button"); @@ -17,18 +25,18 @@ describe("GoA IconButton", () => { }); describe("Variants", () => { - (["color", "nocolor", "light", "dark", "destructive"] as const).forEach( - (variant: IconButtonVariant) => { + (["color", "nocolor", "dark", "destructive"] as const).forEach( + (variant: GoabIconButtonVariant) => { it(`should render ${variant} variant`, async () => { const { container } = render( - + , ); const el = container.querySelector("goa-icon-button"); expect(el).toBeTruthy(); expect(el?.getAttribute("variant")).toEqual(variant); }); - } + }, ); }); }); diff --git a/libs/react-components/src/lib/icon-button/icon-button.tsx b/libs/react-components/src/lib/icon-button/icon-button.tsx index 521d02ad7..da19545ce 100644 --- a/libs/react-components/src/lib/icon-button/icon-button.tsx +++ b/libs/react-components/src/lib/icon-button/icon-button.tsx @@ -1,17 +1,16 @@ +import { + GoabIconButtonVariant, + GoabIconSize, + GoabIconType, + Margins, +} from "@abgov/ui-components-common"; import { useEffect, useRef } from "react"; -import { Margins } from "../../common/styling"; -import { GoAIconSize, GoAIconType } from "../icon/icon"; - -export type GoAIconButtonVariant = "color" | "nocolor" | "light" | "dark" | "destructive"; - -// legacy naming -export type IconButtonVariant = GoAIconButtonVariant; interface WCProps extends Margins { ref: React.RefObject; - icon: GoAIconType; - size?: GoAIconSize; - variant?: GoAIconButtonVariant; + icon: GoabIconType; + size?: GoabIconSize; + variant?: GoabIconButtonVariant; title?: string; disabled?: boolean; arialabel?: string; @@ -27,10 +26,10 @@ declare global { } } -export interface GoAIconButtonProps extends Margins { - icon: GoAIconType; - size?: GoAIconSize; - variant?: GoAIconButtonVariant; +export interface GoabIconButtonProps extends Margins { + icon: GoabIconType; + size?: GoabIconSize; + variant?: GoabIconButtonVariant; title?: string; disabled?: boolean; children?: React.ReactNode; @@ -39,7 +38,7 @@ export interface GoAIconButtonProps extends Margins { ariaLabel?: string; } -export function GoAIconButton({ +export function GoabIconButton({ icon, disabled, variant = "color", @@ -53,7 +52,7 @@ export function GoAIconButton({ mr, mb, ml, -}: GoAIconButtonProps): JSX.Element { +}: GoabIconButtonProps): JSX.Element { const ref = useRef(null); useEffect(() => { if (!ref.current) { diff --git a/libs/react-components/src/lib/icon/icon.spec.tsx b/libs/react-components/src/lib/icon/icon.spec.tsx index 78be26816..5ed641893 100644 --- a/libs/react-components/src/lib/icon/icon.spec.tsx +++ b/libs/react-components/src/lib/icon/icon.spec.tsx @@ -1,10 +1,10 @@ import { render } from "@testing-library/react"; -import { GoAIcon } from "./icon"; +import { GoabIcon } from "./icon"; -describe("GoA Icon", () => { +describe("GoAB Icon", () => { it("should render the properties", () => { const { container } = render( - { /* do nothing */ }; +const noop = () => { + /* do nothing */ +}; const testId = "test-id"; -const defaultProps: GoAInputProps = { +const defaultProps: GoabInputProps = { name: "", value: "", testId: testId, @@ -15,13 +22,13 @@ const defaultProps: GoAInputProps = { describe("Input", () => { it("should render", () => { - const props: GoAInputProps = { + const props: GoabInputProps = { ...defaultProps, name: "foo", value: "bar", id: "foo", - leadingIcon: "search" as GoAIconType, - trailingIcon: "close" as GoAIconType, + leadingIcon: "search" as GoabIconType, + trailingIcon: "close" as GoabIconType, autoCapitalize: "on", variant: "bare", disabled: true, @@ -42,7 +49,7 @@ describe("Input", () => { onTrailingIconClick: noop, }; - render(); + render(); const input = document.querySelector("goa-input"); expect(input).toBeTruthy(); @@ -68,81 +75,94 @@ describe("Input", () => { expect(input?.getAttribute("ml")).toBe("xl"); expect(input?.getAttribute("maxlength")).toBe("10"); expect(input?.querySelector("[slot='leadingContent']")?.textContent).toContain("$"); - expect(input?.querySelector("[slot='trailingContent']")?.textContent).toContain("items"); + expect(input?.querySelector("[slot='trailingContent']")?.textContent).toContain( + "items", + ); expect(input?.getAttribute("handletrailingiconclick")).toBeTruthy(); }); - it("should handle the onChange event", async function() { + it("should handle the onChange event", async function () { const validateOnChange = vi.fn(); const newValue = "barfoo"; - const onChange = (name: string, value: string) => { + const onChange = ({ name, value }: GoabInputOnChangeDetail) => { expect(name).toBe("foo"); expect(value).toBe(newValue); validateOnChange(); }; const props = { ...defaultProps, onChange }; - render(); + render(); const input = document.querySelector("goa-input"); expect(input).toBeTruthy(); - input && fireEvent(input, new CustomEvent("_change", { - detail: { name: "foo", value: newValue } - })); + input && + fireEvent( + input, + new CustomEvent("_change", { + detail: { name: "foo", value: newValue }, + }), + ); expect(validateOnChange).toBeCalled(); }); it("should not error out with invalid dates", () => { const mockOnChangeHandler = vi.fn(); const { container } = render( - - ); - const inputElement = container.querySelector( - 'goa-input[type="datetime-local"]' + />, ); + const inputElement = container.querySelector('goa-input[type="datetime-local"]'); expect(inputElement).toBeTruthy(); //invalid dates do not trigger change event - inputElement && fireEvent( - inputElement, - new CustomEvent("_change", { - detail: { name: "dateInput", value: "invalid date" }, - }) - ); + inputElement && + fireEvent( + inputElement, + new CustomEvent("_change", { + detail: { name: "dateInput", value: "invalid date" }, + }), + ); expect(mockOnChangeHandler).not.toBeCalled(); const newDate = new Date().toISOString(); //valid dates trigger change event - inputElement && fireEvent( - inputElement, - new CustomEvent("_change", { - detail: { name: "dateInput", value: newDate }, - }) - ); - expect(mockOnChangeHandler).toBeCalledWith("dateInput", new Date(newDate)); + inputElement && + fireEvent( + inputElement, + new CustomEvent("_change", { + detail: { name: "dateInput", value: newDate }, + }), + ); + expect(mockOnChangeHandler).toBeCalledWith({ + name: "dateInput", + value: new Date(newDate), + }); }); - it("should handle decimal number for GoAInputNumber", () => { + it("should handle decimal number for GoABInputNumber", () => { const mockOnChangeHandler = vitest.fn(); - const {container} = render( - + const { container } = render( + , ); const inputElement = container.querySelector("goa-input[type='number']"); expect(inputElement).toBeTruthy(); const decimalValue = 1.3; - inputElement && fireEvent( - inputElement, - new CustomEvent("_change", { - detail: { - name: "numberInput", - value: decimalValue - } - }) - ); - expect(mockOnChangeHandler).toBeCalledWith("numberInput", decimalValue); - }) + inputElement && + fireEvent( + inputElement, + new CustomEvent("_change", { + detail: { + name: "numberInput", + value: decimalValue, + }, + }), + ); + expect(mockOnChangeHandler).toBeCalledWith({ + name: "numberInput", + value: decimalValue, + }); + }); }); diff --git a/libs/react-components/src/lib/input/input.tsx b/libs/react-components/src/lib/input/input.tsx index d30488eee..605d46564 100644 --- a/libs/react-components/src/lib/input/input.tsx +++ b/libs/react-components/src/lib/input/input.tsx @@ -1,40 +1,24 @@ import { useEffect, useRef } from "react"; -import { GoAIconType } from "../.."; import { format, isValid, parseISO } from "date-fns"; -import { Margins } from "../../common/styling"; - -export type GoADate = Date | string; - -export type GoAInputType = - | "text" - | "password" - | "email" - | "number" - | "date" - | "datetime-local" - | "month" - | "range" - | "search" - | "tel" - | "time" - | "url" - | "week"; - -export type GoAAutoCapitalize = - | "on" - | "off" - | "none" - | "sentences" - | "words" - | "characters"; +import { + GoabAutoCapitalize, + GoabDate, + GoabIconType, + GoaInputOnBlurDetail, + GoabInputOnChangeDetail, + GoabInputOnFocusDetail, + GoabInputOnKeyPressDetail, + GoabInputType, + Margins, +} from "@abgov/ui-components-common"; interface WCProps extends Margins { ref?: React.MutableRefObject; - type?: GoAInputType; + type?: GoabInputType; name: string; value?: string; id?: string; - autocapitalize?: GoAAutoCapitalize; + autocapitalize?: GoabAutoCapitalize; debounce?: number; placeholder?: string; leadingicon?: string; @@ -75,10 +59,10 @@ interface BaseProps extends Margins { id?: string; debounce?: number; disabled?: boolean; - autoCapitalize?: GoAAutoCapitalize; + autoCapitalize?: GoabAutoCapitalize; placeholder?: string; - leadingIcon?: GoAIconType; - trailingIcon?: GoAIconType; + leadingIcon?: GoabIconType; + trailingIcon?: GoabIconType; onTrailingIconClick?: () => void; variant?: "goa" | "bare"; focused?: boolean; @@ -94,13 +78,13 @@ interface BaseProps extends Margins { maxLength?: number; } -type OnChange = (name: string, value: T) => void; -type OnFocus = (name: string, value: T) => void; -type OnBlur = (name: string, value: T) => void; -type OnKeyPress = (name: string, value: T, key: string) => void; +type OnChange = (detail: GoabInputOnChangeDetail) => void; +type OnFocus = (detail: GoabInputOnFocusDetail) => void; +type OnBlur = (detail: GoaInputOnBlurDetail) => void; +type OnKeyPress = (detail: GoabInputOnKeyPressDetail) => void; -export interface GoAInputProps extends BaseProps { - onChange?: OnChange; +export interface GoabInputProps extends BaseProps { + onChange: OnChange; value?: string; min?: number | string; max?: number | string; @@ -110,8 +94,8 @@ export interface GoAInputProps extends BaseProps { onKeyPress?: OnKeyPress; } -interface GoANumberInputProps extends BaseProps { - onChange?: OnChange; +interface GoabNumberInputProps extends BaseProps { + onChange: OnChange; value?: number; min?: number; max?: number; @@ -121,18 +105,18 @@ interface GoANumberInputProps extends BaseProps { onKeyPress?: OnKeyPress; } -interface GoADateInputProps extends BaseProps { - onChange?: OnChange; - value?: GoADate; - min?: GoADate; - max?: GoADate; +interface GoabDateInputProps extends BaseProps { + onChange: OnChange; + value?: GoabDate; + min?: GoabDate; + max?: GoabDate; step?: number; - onFocus?: OnFocus; - onBlur?: OnBlur; - onKeyPress?: OnKeyPress; + onFocus?: OnFocus; + onBlur?: OnBlur; + onKeyPress?: OnKeyPress; } -export function GoAInput({ +export function GoabInput({ id, debounce, name, @@ -167,41 +151,42 @@ export function GoAInput({ onFocus, onBlur, onKeyPress, -}: GoAInputProps & { type?: GoAInputType }): JSX.Element { +}: GoabInputProps & { type?: GoabInputType }): JSX.Element { const ref = useRef(null); useEffect(() => { if (!ref.current) { return; } const current = ref.current; - const changeListener = (e: unknown) => { - const { name, value } = (e as CustomEvent).detail; - onChange?.(name, value); + const changeListener = (e: Event) => { + const detail = (e as CustomEvent).detail; + onChange(detail); }; const clickListener = () => { onTrailingIconClick?.(); }; - const focusListener = (e: unknown) => { - const { name, value } = (e as CustomEvent).detail; - onFocus?.(name, value); + const focusListener = (e: Event) => { + const detail = (e as CustomEvent).detail; + onFocus?.(detail); }; - const blurListener = (e: unknown) => { - const { name, value } = (e as CustomEvent).detail; - onBlur?.(name, value); + const blurListener = (e: Event) => { + const detail = (e as CustomEvent).detail; + onBlur?.(detail); }; - const keypressListener = (e: unknown) => { - const { name, value, key } = (e as CustomEvent).detail; - onKeyPress?.(name, value, key); - } + const keypressListener = (e: Event) => { + const detail = (e as CustomEvent).detail; + onKeyPress?.(detail); + }; current.addEventListener("_change", changeListener); current.addEventListener("_trailingIconClick", clickListener); current.addEventListener("_focus", focusListener); current.addEventListener("_blur", blurListener); current.addEventListener("_keyPress", keypressListener); + return () => { current.removeEventListener("_change", changeListener); current.removeEventListener("_trailingIconClick", clickListener); @@ -249,33 +234,36 @@ export function GoAInput({ ); } -const onDateChangeHandler = (onChange?: OnChange) => { - return (name: string, value: string) => { - if (!onChange) return; - +const onDateChangeHandler = (onChange: OnChange) => { + return ({ name, value }: GoabInputOnChangeDetail) => { if (!value) { - onChange(name, ""); + onChange({ name, value: "" }); return; } - if (isValid(new Date(value))) { - onChange(name, parseISO(value)); + // valid string date + if (typeof value === "string" && isValid(new Date(value))) { + onChange({ name, value: parseISO(value) }); + return; + } + // valid date + if (isValid(value)) { + onChange({ name, value }); + return; } }; }; -const onTimeChangeHandler = (onChange?: OnChange) => { - return (name: string, value: string) => { - if (!onChange) return; - +const onTimeChangeHandler = (onChange: OnChange) => { + return ({ name, value }: GoabInputOnChangeDetail) => { if (!value) { - onChange(name, ""); + onChange({ name, value: "" }); return; } - onChange(name, value); + onChange({ name, value }); }; }; -function toString(value: GoADate | null | undefined, tmpl = "yyyy-MM-dd"): string { +function toString(value: GoabDate | null | undefined, tmpl = "yyyy-MM-dd"): string { if (!value) { return ""; } @@ -288,22 +276,22 @@ function toString(value: GoADate | null | undefined, tmpl = "yyyy-MM-dd"): strin return format(value, tmpl); } -export function GoAInputText(props: GoAInputProps): JSX.Element { - return ; +export function GoabInputText(props: GoabInputProps): JSX.Element { + return ; } -export function GoAInputPassword(props: GoAInputProps): JSX.Element { - return ; +export function GoabInputPassword(props: GoabInputProps): JSX.Element { + return ; } -export function GoAInputDate({ +export function GoabInputDate({ value, min = "", max = "", ...props -}: GoADateInputProps): JSX.Element { +}: GoabDateInputProps): JSX.Element { return ( - ; +export function GoabInputEmail(props: GoabInputProps): JSX.Element { + return ; } -export function GoAInputSearch(props: GoAInputProps): JSX.Element { - return ; +export function GoabInputSearch(props: GoabInputProps): JSX.Element { + return ; } -export function GoAInputUrl(props: GoAInputProps): JSX.Element { - return ; +export function GoabInputUrl(props: GoabInputProps): JSX.Element { + return ; } -export function GoAInputTel(props: GoAInputProps): JSX.Element { - return ; +export function GoabInputTel(props: GoabInputProps): JSX.Element { + return ; } -export function GoAInputFile(props: GoAInputProps): JSX.Element { +export function GoabInputFile(props: GoabInputProps): JSX.Element { return ( props.onChange?.(e.target.name, e.target.value)} + onChange={(e) => props.onChange({ name: e.target.name, value: e.target.value })} style={{ backgroundColor: "revert" }} /> ); } -export function GoAInputMonth(props: GoAInputProps): JSX.Element { - return ; +export function GoabInputMonth(props: GoabInputProps): JSX.Element { + return ; } -export function GoAInputNumber({ +export function GoabInputNumber({ min = Number.MIN_VALUE, max = Number.MAX_VALUE, value, ...props -}: GoANumberInputProps): JSX.Element { - const onNumberChange = (name: string, value: string) => { - props.onChange?.(name, parseFloat(value)); +}: GoabNumberInputProps): JSX.Element { + const onNumberChange = ({ name, value }: GoabInputOnChangeDetail) => { + props.onChange({ name, value: parseFloat(value) }); }; - const onFocus = (name: string, value: string) => { - props.onFocus?.(name, parseFloat(value)); + const onFocus = ({ name, value }: GoabInputOnFocusDetail) => { + props.onFocus?.({ name, value: parseFloat(value) }); }; - const onBlur = (name: string, value: string) => { - props.onBlur?.(name, parseFloat(value)); + const onBlur = ({ name, value }: GoaInputOnBlurDetail) => { + props.onBlur?.({ name, value: parseFloat(value) }); }; - const onKeyPress = (name: string, value: string, key: string) => { - props.onKeyPress?.(name, parseFloat(value), key); + const onKeyPress = ({ name, value, key }: GoabInputOnKeyPressDetail) => { + props.onKeyPress?.({ name, value: parseFloat(value), key: parseInt(key) }); }; return ( - ; +export function GoabInputRange(props: GoabInputProps): JSX.Element { + return ; } -export default GoAInput; +export default GoabInput; diff --git a/libs/react-components/src/lib/microsite-header/microsite-header.spec.tsx b/libs/react-components/src/lib/microsite-header/microsite-header.spec.tsx index aa2e1102d..36ccad8f7 100644 --- a/libs/react-components/src/lib/microsite-header/microsite-header.spec.tsx +++ b/libs/react-components/src/lib/microsite-header/microsite-header.spec.tsx @@ -1,31 +1,38 @@ import { render } from "@testing-library/react"; -import GoAMicrositeHeader, { ServiceLevel } from "./microsite-header"; +import GoabMicrositeHeader from "./microsite-header"; +import { GoabServiceLevel } from "@abgov/ui-components-common"; describe("Header", () => { - (["alpha", "beta", "live"] as const).forEach((mode: ServiceLevel) => { - it("should show the all the flairs", async function() { - render(); + (["alpha", "beta", "live"] as const).forEach((mode: GoabServiceLevel) => { + it("should show the all the flairs", async function () { + render(); const el = document.querySelector("goa-microsite-header"); expect(el).not.toBeNull(); expect(el?.getAttribute("type")).toEqual(mode); }); }); - it("should show the all the flairs", async function() { - render(); + it("should show the all the flairs", async function () { + render(); const el = document.querySelector("goa-microsite-header"); expect(el?.getAttribute("version")).toEqual("v1.2.3"); }); it("should set self url target", () => { - render(); + render( + , + ); const el = document.querySelector("goa-microsite-header"); expect(el?.getAttribute("headerUrlTarget")).toBe("self"); expect(el?.getAttribute("feedbackUrlTarget")).toBe("self"); }); it("should render slotted version", () => { - render(foo} />); + render(foo} />); const el = document.querySelector("goa-microsite-header"); const slot = el?.querySelector("[slot='version']"); const slotContent = slot?.querySelector("span"); diff --git a/libs/react-components/src/lib/microsite-header/microsite-header.tsx b/libs/react-components/src/lib/microsite-header/microsite-header.tsx index 067fc00c3..58c654962 100644 --- a/libs/react-components/src/lib/microsite-header/microsite-header.tsx +++ b/libs/react-components/src/lib/microsite-header/microsite-header.tsx @@ -1,3 +1,5 @@ +import { GoabLinkTarget, GoabServiceLevel } from "@abgov/ui-components-common"; + import { useEffect, useRef } from "react"; declare global { @@ -9,39 +11,30 @@ declare global { } } -export type GoAServiceLevel = "alpha" | "beta" | "live"; -export type GoALinkTarget = "self" | "blank"; - -// leagcy type name -export type ServiceLevel = GoAServiceLevel; - interface WCProps { - type: GoAServiceLevel; + type: GoabServiceLevel; version?: string; feedbackurl?: string; maxcontentwidth?: string; - feedbackurltarget?: GoALinkTarget; - headerurltarget?: GoALinkTarget; + feedbackurltarget?: GoabLinkTarget; + headerurltarget?: GoabLinkTarget; hasfeedbackhandler?: boolean; ref: React.RefObject; testid?: string; } -export interface GoAHeaderProps { - type: GoAServiceLevel; - version?: React.ReactNode; +export interface GoabHeaderProps { + type: GoabServiceLevel; + version?: string | React.ReactNode; feedbackUrl?: string; testId?: string; maxContentWidth?: string; - feedbackUrlTarget?: GoALinkTarget; - headerUrlTarget?: GoALinkTarget; + feedbackUrlTarget?: GoabLinkTarget; + headerUrlTarget?: GoabLinkTarget; onFeedbackClick?: () => void; } -// legacy name -export type HeaderProps = GoAHeaderProps; - -export function GoAMicrositeHeader({ +export function GoabMicrositeHeader({ type, version, feedbackUrl, @@ -50,7 +43,7 @@ export function GoAMicrositeHeader({ headerUrlTarget, testId, onFeedbackClick, -}: GoAHeaderProps): JSX.Element { +}: GoabHeaderProps): JSX.Element { const el = useRef(null); useEffect(() => { @@ -88,4 +81,4 @@ export function GoAMicrositeHeader({ ); } -export default GoAMicrositeHeader; +export default GoabMicrositeHeader; diff --git a/libs/react-components/src/lib/modal/modal.spec.tsx b/libs/react-components/src/lib/modal/modal.spec.tsx index 96b91eaef..0da30362c 100644 --- a/libs/react-components/src/lib/modal/modal.spec.tsx +++ b/libs/react-components/src/lib/modal/modal.spec.tsx @@ -1,6 +1,6 @@ import { render } from "@testing-library/react"; -import GoAButton from "../../lib/button/button"; -import { GoAModal } from "./modal"; +import GoabButton from "../../lib/button/button"; +import { GoabModal, GoabModalProps } from "./modal"; describe("Modal Tests", () => { it("Modal - should render with close capability via icon and background", async () => { @@ -9,13 +9,21 @@ describe("Modal Tests", () => { open: true, maxWidth: "500px", role: "alertdialog", - actions: { /* do nothing */ }}>Close, - onClose: () => { /* do nothing */ }, - }; + actions: ( + { + /* do nothing */ + }} + > + Close + + ), + onClose: () => { + /* do nothing */ + }, + } as GoabModalProps; - const { baseElement } = render( - Modal Content - ); + const { baseElement } = render(Modal Content); const modal = baseElement.querySelector("goa-modal"); const actionContent = modal?.querySelector("[slot='actions']"); const heading = modal?.querySelector("[slot='heading']"); diff --git a/libs/react-components/src/lib/modal/modal.tsx b/libs/react-components/src/lib/modal/modal.tsx index a069c3aff..fa0dcdfbe 100644 --- a/libs/react-components/src/lib/modal/modal.tsx +++ b/libs/react-components/src/lib/modal/modal.tsx @@ -1,27 +1,19 @@ +import { + GoabModalCalloutVariant, + GoabModalRole, + GoabModalTransition, +} from "@abgov/ui-components-common"; import { ReactElement, ReactNode, RefObject, useEffect, useRef } from "react"; -export type GoAModalTransition = "fast" | "slow" | "none"; -export type GoAModalCalloutVariant = - | "information" - | "important" - | "emergency" - | "success" - | "event"; -export type GoAModalRole = "dialog" | "alertdialog"; - -// leagcy type names -export type ModalTransition = GoAModalTransition; -export type CalloutVariant = GoAModalCalloutVariant; - interface WCProps { ref: RefObject; heading?: ReactNode; open?: boolean; maxwidth?: string; closable?: boolean; - transition?: GoAModalTransition; - calloutvariant?: GoAModalCalloutVariant; - role?: GoAModalRole; + role?: GoabModalRole; + transition?: GoabModalTransition; + calloutvariant?: GoabModalCalloutVariant; testid?: string; } @@ -34,52 +26,33 @@ declare global { } } -export interface GoAModalProps { +export interface GoabModalProps { heading?: ReactNode; maxWidth?: string; actions?: ReactElement; onClose?: () => void; - transition?: GoAModalTransition; + transition?: GoabModalTransition; children?: ReactNode; open?: boolean; - calloutVariant?: GoAModalCalloutVariant; + calloutVariant?: GoabModalCalloutVariant; testId?: string; - role?: GoAModalRole; - // @deprecated: use maxWidth - width?: string; - // @deprecated: use variant - type?: string; + role?: GoabModalRole; } -export function GoAModal({ +export function GoabModal({ heading, children, maxWidth, open, actions, transition, - type, calloutVariant, onClose, testId, role, - width, -}: GoAModalProps): JSX.Element { +}: GoabModalProps): JSX.Element { const el = useRef(null); - // @deprecated - useEffect(() => { - if (type) { - console.warn("GoAModal [type] is deprecated."); - } - }, [type]); - - // @deprecated - useEffect(() => { - // @ts-expected-error: deprecated - maxWidth = width; - }, [width]); - useEffect(() => { if (!el.current) { return; @@ -113,4 +86,4 @@ export function GoAModal({ ); } -export default GoAModal; +export default GoabModal; diff --git a/libs/react-components/src/lib/notification/notification.spec.tsx b/libs/react-components/src/lib/notification/notification.spec.tsx index 0fd429c3d..698ce48ec 100644 --- a/libs/react-components/src/lib/notification/notification.spec.tsx +++ b/libs/react-components/src/lib/notification/notification.spec.tsx @@ -1,31 +1,32 @@ import { render } from "@testing-library/react"; -import GoANotification, { NotificationType } from "./notification"; +import GoabNotification from "./notification"; import { fireEvent } from "@testing-library/dom"; import { describe, it, expect, vi } from "vitest"; +import { GoabNotificationType } from "@abgov/ui-components-common"; describe("Notification Banner", () => { describe("type", () => { (["important", "information", "emergency", "event"] as const).forEach( - (type: NotificationType) => { - it(`should render ${type} notification`, async function() { + (type: GoabNotificationType) => { + it(`should render ${type} notification`, async function () { render( - + Information to the user goes in the content - + , ); const el = document.querySelector("goa-notification"); expect(el?.getAttribute("type")).toEqual(type); }); - } + }, ); }); it("Event triggered on notification banner dismiss", async () => { const onDismiss = vi.fn(); const { container } = render( - + Information to the user goes in the content - + , ); const notificationBanner = container.querySelector("goa-notification"); notificationBanner && fireEvent(notificationBanner, new CustomEvent("_dismiss")); @@ -34,9 +35,9 @@ describe("Notification Banner", () => { it("should render notification banner with ariaLive", async () => { render( - + Information to the user goes in the content - + , ); const el = document.querySelector("goa-notification"); expect(el?.getAttribute("ariaLive")).toEqual("assertive"); diff --git a/libs/react-components/src/lib/notification/notification.tsx b/libs/react-components/src/lib/notification/notification.tsx index 0f68a3c0a..1e52889e6 100644 --- a/libs/react-components/src/lib/notification/notification.tsx +++ b/libs/react-components/src/lib/notification/notification.tsx @@ -1,21 +1,11 @@ +import { GoabAriaLiveType, GoabNotificationType } from "@abgov/ui-components-common"; import { useEffect, useRef } from "react"; -export type GoANotificationType = - | "important" - | "information" - | "event" - | "emergency"; - -export type GoAAriaLiveType = "polite" | "assertive" | "off"; - -export type NotificationType = GoANotificationType; -export type AriaLiveType = GoAAriaLiveType; - interface WCProps { ref: React.RefObject; - type: GoANotificationType; + type: GoabNotificationType; maxcontentwidth?: string; - arialive?: GoAAriaLiveType; + arialive?: GoabAriaLiveType; testid?: string; } @@ -28,23 +18,23 @@ declare global { } } -export interface GoANotificationProps { - type?: GoANotificationType; - ariaLive?: GoAAriaLiveType; +export interface GoabNotificationProps { + type?: GoabNotificationType; + ariaLive?: GoabAriaLiveType; maxContentWidth?: string; children?: React.ReactNode; onDismiss?: () => void; testId?: string; } -export const GoANotification = ({ +export const GoabNotification = ({ type = "information", ariaLive, maxContentWidth, children, testId, onDismiss, -}: GoANotificationProps) => { +}: GoabNotificationProps) => { const el = useRef(null); useEffect(() => { @@ -73,6 +63,6 @@ export const GoANotification = ({ {children} ); -} +}; -export default GoANotification; +export default GoabNotification; diff --git a/libs/react-components/src/lib/one-column-layout/one-column-layout.spec.tsx b/libs/react-components/src/lib/one-column-layout/one-column-layout.spec.tsx index 44dad3082..b3ac913f2 100644 --- a/libs/react-components/src/lib/one-column-layout/one-column-layout.spec.tsx +++ b/libs/react-components/src/lib/one-column-layout/one-column-layout.spec.tsx @@ -1,10 +1,10 @@ import { render } from "@testing-library/react"; -import GoAOneColumnLayout from "./one-column-layout"; +import GoabOneColumnLayout from "./one-column-layout"; describe("Page", () => { it("should render successfully", () => { - const { baseElement } = render(); + const { baseElement } = render(); expect(baseElement).toBeTruthy(); }); }); diff --git a/libs/react-components/src/lib/one-column-layout/one-column-layout.tsx b/libs/react-components/src/lib/one-column-layout/one-column-layout.tsx index 0cea9e191..a6e3e31ae 100644 --- a/libs/react-components/src/lib/one-column-layout/one-column-layout.tsx +++ b/libs/react-components/src/lib/one-column-layout/one-column-layout.tsx @@ -9,14 +9,14 @@ declare global { } } -export interface GoAPageProps { +export interface GoabPageProps { children?: ReactNode; } -export type PageProps = GoAPageProps; +export type PageProps = GoabPageProps; -export function GoAOneColumnLayout(props: GoAPageProps): JSX.Element { +export function GoabOneColumnLayout(props: GoabPageProps): JSX.Element { return {props.children}; } -export default GoAOneColumnLayout; +export default GoabOneColumnLayout; diff --git a/libs/react-components/src/lib/page-block/page-block.tsx b/libs/react-components/src/lib/page-block/page-block.tsx index d959d5796..254c31d3e 100644 --- a/libs/react-components/src/lib/page-block/page-block.tsx +++ b/libs/react-components/src/lib/page-block/page-block.tsx @@ -14,16 +14,16 @@ declare global { } } -export interface GoAPageBlockProps { +export interface GoabPageBlockProps { width: "full" | string; testId?: string; children?: ReactNode; } // legacy name -export type PageBlockProps = GoAPageBlockProps; +export type PageBlockProps = GoabPageBlockProps; -export function GoAPageBlock(props: PageBlockProps): JSX.Element { +export function GoabPageBlock(props: PageBlockProps): JSX.Element { return ( {props.children} diff --git a/libs/react-components/src/lib/pages/pages.tsx b/libs/react-components/src/lib/pages/pages.tsx index 03b3cc5d8..efb30c2de 100644 --- a/libs/react-components/src/lib/pages/pages.tsx +++ b/libs/react-components/src/lib/pages/pages.tsx @@ -1,5 +1,5 @@ +import { Margins } from "@abgov/ui-components-common"; import { ReactNode } from "react"; -import { Margins } from "../../common/styling"; interface WCProps extends Margins { current?: number; @@ -16,12 +16,12 @@ declare global { } /* eslint-disable-next-line */ -export interface GoAPagesProps extends Margins { +export interface GoabPagesProps extends Margins { current?: number; children?: ReactNode; } -export function GoAPages(props: GoAPagesProps): JSX.Element { +export function GoabPages(props: GoabPagesProps): JSX.Element { return ( { it("should render successfully", () => { @@ -37,12 +38,13 @@ describe("Pagination", () => { const { baseElement } = render( ); + const detail: GoabPaginationOnChangeDetail = { page: 2 }; const el = baseElement.querySelector("goa-pagination"); - el && fireEvent(el, new CustomEvent("_change", { detail: { page: 2 } })); + el && fireEvent(el, new CustomEvent("_change", { detail: detail })); await waitFor(() => { - expect(fn).toBeCalledWith(2); + expect(fn).toBeCalledWith(detail); }); }); }); diff --git a/libs/react-components/src/lib/pagination/pagination.tsx b/libs/react-components/src/lib/pagination/pagination.tsx index 9e9e466b2..b6d63e83f 100644 --- a/libs/react-components/src/lib/pagination/pagination.tsx +++ b/libs/react-components/src/lib/pagination/pagination.tsx @@ -1,5 +1,5 @@ +import { GoabPaginationOnChangeDetail, Margins } from "@abgov/ui-components-common"; import { useEffect, useRef } from "react"; -import { Margins } from "../../common/styling"; interface WCProps extends Margins { ref?: React.MutableRefObject; @@ -20,19 +20,19 @@ declare global { } /* eslint-disable-next-line */ -export interface GoAPaginationProps extends Margins { +export interface GoabPaginationProps extends Margins { itemCount: number; perPageCount?: number; pageNumber: number; variant?: "all" | "links-only"; - onChange: (page: number) => void; + onChange: (detail: GoabPaginationOnChangeDetail) => void; testId?: string; } // legacy -export type PaginationProps = GoAPaginationProps; +export type PaginationProps = GoabPaginationProps; -export function GoAPagination({onChange, ...props}: GoAPaginationProps) { +export function GoabPagination({ onChange, ...props }: GoabPaginationProps) { const ref = useRef(); useEffect(() => { @@ -41,8 +41,8 @@ export function GoAPagination({onChange, ...props}: GoAPaginationProps) { } const current = ref.current; const changeListener = (e: Event) => { - const { page } = (e as CustomEvent).detail; - onChange(page); + const detail = (e as CustomEvent).detail; + onChange(detail); }; current.addEventListener("_change", changeListener); @@ -67,4 +67,4 @@ export function GoAPagination({onChange, ...props}: GoAPaginationProps) { ); } -export default GoAPagination; +export default GoabPagination; diff --git a/libs/react-components/src/lib/popover/popover.spec.tsx b/libs/react-components/src/lib/popover/popover.spec.tsx index 885119446..6a7504078 100644 --- a/libs/react-components/src/lib/popover/popover.spec.tsx +++ b/libs/react-components/src/lib/popover/popover.spec.tsx @@ -1,22 +1,20 @@ import { render } from "@testing-library/react"; -import GoAPopover from "./popover"; +import GoabPopover from "./popover"; describe("Popover", () => { it("should render successfully", () => { const { baseElement } = render( - The content + The content, ); const el = baseElement.querySelector("goa-popover"); - expect(el?.querySelector("[slot='target']")?.innerHTML).toContain( - "Click Action" - ); + expect(el?.querySelector("[slot='target']")?.innerHTML).toContain("Click Action"); expect(baseElement.innerHTML).toContain("The content"); }); it("should bind all web-component attributes", () => { const { baseElement } = render( - { padded={false} > The content - + , ); const el = baseElement.querySelector("goa-popover"); diff --git a/libs/react-components/src/lib/popover/popover.tsx b/libs/react-components/src/lib/popover/popover.tsx index 27613a4fc..403651f72 100644 --- a/libs/react-components/src/lib/popover/popover.tsx +++ b/libs/react-components/src/lib/popover/popover.tsx @@ -1,13 +1,11 @@ +import { GoabPopoverPosition, Margins } from "@abgov/ui-components-common"; import { ReactNode } from "react"; -import { Margins } from "../../common/styling"; - -export type GoAPosition = "above" | "below" | "auto"; interface WCProps extends Margins { maxwidth?: string; minwidth?: string; padded?: boolean; - position?: GoAPosition; + position?: GoabPopoverPosition; relative?: boolean; testid?: string; } @@ -21,18 +19,18 @@ declare global { } } -export interface GoAPopoverProps extends Margins { +export interface GoabPopoverProps extends Margins { target?: ReactNode; testId?: string; maxWidth?: string; minWidth?: string; padded?: boolean; - position?: GoAPosition; + position?: GoabPopoverPosition; children: ReactNode; relative?: boolean; } -export function GoAPopover({ +export function GoabPopover({ target, testId, maxWidth, @@ -45,7 +43,7 @@ export function GoAPopover({ mr, mb, ml, -}: GoAPopoverProps): JSX.Element { +}: GoabPopoverProps): JSX.Element { return ( { /* do nothing */ } +const noop = (detail: GoabRadioGroupOnChangeDetail) => { + /* do nothing */ +}; describe("RadioGroup", () => { const baseMockData: MockData = { @@ -32,14 +35,14 @@ describe("RadioGroup", () => { radios: [ { text: "Apples", value: "apples" }, { text: "Oranges", value: "oranges", description: "Oranges are orange" }, - { text: "Bananas", value: "bananas", description: (

Bananas are banana

) }, + { text: "Bananas", value: "bananas", description:

Bananas are banana

}, ], }; describe("Basic rendering", () => { it("should render successfully", async () => { const data = baseMockData; - const { baseElement } = render( { onChange={noop} > {data.radios.map((radio) => ( - { ariaLabel={"you are choosing " + radio.value} > {radio.text} - + ))} - ); - + ); expect(baseElement).toBeTruthy(); const el = baseElement.querySelector("goa-radio-group"); expect(el).toBeTruthy(); @@ -89,32 +91,32 @@ describe("RadioGroup", () => { it("initial data is set", async () => { const data = baseMockData; - render( - {data.radios.map((radio) => ( - - {radio.text} - - ))} - ); - + render( + + {data.radios.map((radio) => ( + + {radio.text} + + ))} + , + ); - const radios = - document.querySelectorAll("input[type=radio]"); + const radios = document.querySelectorAll("input[type=radio]"); radios.forEach((radio) => { expect(radio.checked).toBe(radio.value === selectedValue); }); @@ -122,25 +124,27 @@ describe("RadioGroup", () => { it("render with description", async () => { const data = baseMockData; - const result = render( - {data.radios.map((radio) => ( - - {radio.text} - - ))} - ); + const result = render( + + {data.radios.map((radio) => ( + + {radio.text} + + ))} + , + ); const radios = document.querySelectorAll("goa-radio-item"); expect(radios[0].getAttribute("description")).toBe(null); @@ -155,24 +159,26 @@ describe("RadioGroup", () => { const onChange = vi.fn(); const data = { ...baseMockData, value: "oranges", disabled: true }; - const { container } = render( onChange(name, newValue)} - > - {data.radios.map((radio) => ( - - {radio.text} - - ))} - ); + const { container } = render( + onChange(event)} + > + {data.radios.map((radio) => ( + + {radio.text} + + ))} + , + ); await waitFor(() => { const radios = container.querySelectorAll("goa-radio-item"); @@ -186,36 +192,36 @@ describe("RadioGroup", () => { it("change event should work", async () => { const onChange = vi.fn(); const data = { ...baseMockData, value: "oranges" }; - const { container } = render( - {data.radios.map((radio) => ( - - {radio.text} - - ))} - ); + const { container } = render( + + {data.radios.map((radio) => ( + + {radio.text} + + ))} + , + ); const radios = container.querySelectorAll("goa-radio-item"); const radioGroup = container.querySelector("goa-radio-group"); expect(radios[0]).toBeTruthy(); - radioGroup && fireEvent( - radioGroup, - new CustomEvent("_change", { detail: { name: "fruits", value: radios[0].value} }) - ); + radioGroup && + fireEvent( + radioGroup, + new CustomEvent("_change", { + detail: { name: "fruits", value: radios[0].value }, + }), + ); await waitFor(() => { expect(onChange).toBeCalled(); - }) + }); }); - }); diff --git a/libs/react-components/src/lib/radio-group/radio-group.tsx b/libs/react-components/src/lib/radio-group/radio-group.tsx index 9ec116ca7..519016316 100644 --- a/libs/react-components/src/lib/radio-group/radio-group.tsx +++ b/libs/react-components/src/lib/radio-group/radio-group.tsx @@ -1,15 +1,17 @@ import { useEffect, useRef } from "react"; -import { Margins } from "../../common/styling"; +import { + GoabRadioGroupOnChangeDetail, + GoabRadioGroupOrientation, + Margins, +} from "@abgov/ui-components-common"; export * from "./radio"; -export type GoARadioGroupOrientation = "horizontal" | "vertical"; - interface WCProps extends Margins { ref: React.RefObject; name: string; value?: string; - orientation?: GoARadioGroupOrientation; + orientation?: GoabRadioGroupOrientation; disabled?: boolean; error?: boolean; arialabel?: string; @@ -25,19 +27,19 @@ declare global { } } -export interface GoARadioGroupProps extends Margins { +export interface GoabRadioGroupProps extends Margins { name: string; value?: string; disabled?: boolean; - orientation?: GoARadioGroupOrientation; + orientation?: GoabRadioGroupOrientation; testId?: string; error?: boolean; ariaLabel?: string; children?: React.ReactNode; - onChange?: (name: string, value: string) => void; + onChange: (detail: GoabRadioGroupOnChangeDetail) => void; } -export function GoARadioGroup({ +export function GoabRadioGroup({ name, value, children, @@ -51,23 +53,24 @@ export function GoARadioGroup({ mb, ml, onChange, -}: GoARadioGroupProps): JSX.Element { - +}: GoabRadioGroupProps): JSX.Element { const el = useRef(null); useEffect(() => { - if (!el.current) { - return; - } - const listener = (e: unknown) => { + if (!el.current) return; + + const listener = (e: Event) => { if (!onChange) { console.warn("Missing onChange function"); return; } - onChange(name, (e as CustomEvent).detail.value); + const detail = (e as CustomEvent).detail; + onChange(detail); }; + const currentEl = el.current; currentEl.addEventListener("_change", listener); + return () => { currentEl.removeEventListener("_change", listener); }; @@ -93,4 +96,4 @@ export function GoARadioGroup({ ); } -export default GoARadioGroup; +export default GoabRadioGroup; diff --git a/libs/react-components/src/lib/radio-group/radio.tsx b/libs/react-components/src/lib/radio-group/radio.tsx index 1d69b7be6..ca5f1365c 100644 --- a/libs/react-components/src/lib/radio-group/radio.tsx +++ b/libs/react-components/src/lib/radio-group/radio.tsx @@ -1,4 +1,5 @@ -import { Margins } from "../../common/styling"; +import { Margins } from "@abgov/ui-components-common"; + interface RadioItemProps extends Margins { name?: string; value?: string; @@ -20,7 +21,7 @@ declare global { } } -export interface GoARadioItemProps extends Margins { +export interface GoabRadioItemProps extends Margins { value?: string; label?: string; name?: string; @@ -34,7 +35,7 @@ export interface GoARadioItemProps extends Margins { ariaLabel?: string; } -export function GoARadioItem({ +export function GoabRadioItem({ name, label, value, @@ -50,7 +51,7 @@ export function GoARadioItem({ mr, mb, ml, -}: GoARadioItemProps): JSX.Element { +}: GoabRadioItemProps): JSX.Element { return ( - {description && typeof description !== "string" &&
{description}
} + {description && typeof description !== "string" && ( +
{description}
+ )} {children}
); } -export default GoARadioItem; +export default GoabRadioItem; diff --git a/libs/react-components/src/lib/side-menu-group/side-menu-group.tsx b/libs/react-components/src/lib/side-menu-group/side-menu-group.tsx index 2e976da6a..f76a94f93 100644 --- a/libs/react-components/src/lib/side-menu-group/side-menu-group.tsx +++ b/libs/react-components/src/lib/side-menu-group/side-menu-group.tsx @@ -27,7 +27,7 @@ export interface GoASideMenuGroupProps extends Margins { children?: ReactNode; } -export function GoASideMenuGroup(props: GoASideMenuGroupProps): JSX.Element { +export function GoabSideMenuGroup(props: GoabSideMenuGroupProps): JSX.Element { return ( + {props.children} {props.meta && {props.meta}} ); } -export default GoASideMenuHeading; +export default GoabSideMenuHeading; diff --git a/libs/react-components/src/lib/side-menu/side-menu.tsx b/libs/react-components/src/lib/side-menu/side-menu.tsx index 07d0d471a..d339526e1 100644 --- a/libs/react-components/src/lib/side-menu/side-menu.tsx +++ b/libs/react-components/src/lib/side-menu/side-menu.tsx @@ -15,16 +15,13 @@ declare global { } /* eslint-disable-next-line */ -export interface GoASideMenuProps { +export interface GoabSideMenuProps { testId?: string; children: ReactNode; } -// legacy -export type SideMenuProps = GoASideMenuProps; - -export function GoASideMenu(props: GoASideMenuProps): JSX.Element { - return {props.children}; +export function GoabSideMenu(props: GoabSideMenuProps): JSX.Element { + return {props.children}; } -export default GoASideMenu; +export default GoabSideMenu; diff --git a/libs/react-components/src/lib/skeleton/skeleton.spec.tsx b/libs/react-components/src/lib/skeleton/skeleton.spec.tsx index f0235bfc1..e912739e5 100644 --- a/libs/react-components/src/lib/skeleton/skeleton.spec.tsx +++ b/libs/react-components/src/lib/skeleton/skeleton.spec.tsx @@ -1,5 +1,6 @@ import { render } from "@testing-library/react"; -import { GoASkeleton, SkeletonType } from "./skeleton"; +import { GoabSkeleton } from "./skeleton"; +import { GoabSkeletonType } from "@abgov/ui-components-common"; describe("Skeleton", () => { for (const type of [ @@ -16,12 +17,10 @@ describe("Skeleton", () => { ]) { it(`should render the ${type} type`, async () => { const { container } = render( - + , ); - expect( - container.querySelector(`goa-skeleton[type="${type}"]`) - ).toBeTruthy(); + expect(container.querySelector(`goa-skeleton[type="${type}"]`)).toBeTruthy(); const el = container.querySelector("goa-skeleton"); expect(el?.getAttribute("mt")).toBe("s"); diff --git a/libs/react-components/src/lib/skeleton/skeleton.tsx b/libs/react-components/src/lib/skeleton/skeleton.tsx index 75b72057e..efff573be 100644 --- a/libs/react-components/src/lib/skeleton/skeleton.tsx +++ b/libs/react-components/src/lib/skeleton/skeleton.tsx @@ -1,28 +1,10 @@ -import { Margins } from "../../common/styling"; - -export type GoASkeletonType = - | "image" - | "text" - | "title" - | "text-small" - | "avatar" - | "header" - | "paragraph" - | "thumbnail" - | "card" - | "profile" - | "article"; - -export type GoASkeletonSize = 1 | 2 | 3 | 4; - -// legacy naming -export type SkeletonType = GoASkeletonType; +import { GoabSkeletonSize, GoabSkeletonType, Margins } from "@abgov/ui-components-common"; interface WCProps extends Margins { maxwidth?: string; - size?: GoASkeletonSize; + size?: GoabSkeletonSize; linecount?: number; - type: GoASkeletonType; + type: GoabSkeletonType; testid?: string; } @@ -35,18 +17,18 @@ declare global { } } -export interface GoASkeletonProps extends Margins { +export interface GoabSkeletonProps extends Margins { maxWidth?: string; - size?: GoASkeletonSize; + size?: GoabSkeletonSize; lineCount?: number; - type: GoASkeletonType; + type: GoabSkeletonType; testId?: string; } // legacy name -export type SkeletonProps = GoASkeletonProps; +export type SkeletonProps = GoabSkeletonProps; -export const GoASkeleton = ({ +export const GoabSkeleton = ({ maxWidth, size, lineCount, @@ -56,7 +38,7 @@ export const GoASkeleton = ({ mr, mb, ml, -}: GoASkeletonProps) => { +}: GoabSkeletonProps) => { return ( { - (["small", "medium", "large", "xlarge"] as const).forEach((size: SpinnerSize) => { + (["small", "medium", "large", "xlarge"] as const).forEach((size: GoabSpinnerSize) => { it(`renders the ${size} spinner`, async () => { render( - + />, ); const el = document.querySelector("goa-spinner"); expect(el?.getAttribute("size")).toBe(size); diff --git a/libs/react-components/src/lib/spinner/spinner.tsx b/libs/react-components/src/lib/spinner/spinner.tsx index 026948a20..826fdb55f 100644 --- a/libs/react-components/src/lib/spinner/spinner.tsx +++ b/libs/react-components/src/lib/spinner/spinner.tsx @@ -1,9 +1,8 @@ -export type SpinnerType = "infinite" | "progress"; -export type SpinnerSize = "small" | "medium" | "large" | "xlarge"; +import { GoabSpinnerSize, GoabSpinnerType } from "@abgov/ui-components-common"; interface WCProps { - size: SpinnerSize; - type: SpinnerType; + size: GoabSpinnerSize; + type: GoabSpinnerType; invert?: boolean; progress?: number; testid?: string; @@ -18,23 +17,23 @@ declare global { } } -export interface GoASpinnerProps { - type: SpinnerType; - size: SpinnerSize; +export interface GoabSpinnerProps { + type: GoabSpinnerType; + size: GoabSpinnerSize; invert?: boolean; progress?: number; testId?: string; } -export type SpinnerProps = GoASpinnerProps; +export type SpinnerProps = GoabSpinnerProps; -export function GoASpinner({ +export function GoabSpinner({ type, size, progress, invert, testId, -}: GoASpinnerProps): JSX.Element { +}: GoabSpinnerProps): JSX.Element { return ( { +describe("GoABTab", () => { it("should render successfully", () => { const { container } = render( - +

- Profile: Lorem ipsum dolor sit amet, consectetur adipiscing - elit, sed do eiusmod tempor incididunt ut labore et dolore magna - aliqua. + Profile: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua.

-
+ , ); expect(container.querySelector("goa-tab")).toBeTruthy(); const heading = container.querySelector("[slot='heading']"); diff --git a/libs/react-components/src/lib/tab/tab.tsx b/libs/react-components/src/lib/tab/tab.tsx index 893f0536b..6ef94a8d4 100644 --- a/libs/react-components/src/lib/tab/tab.tsx +++ b/libs/react-components/src/lib/tab/tab.tsx @@ -11,14 +11,12 @@ declare global { } } -export interface GoATabItemProps { +export interface GoabTabItemProps { heading?: React.ReactNode; children?: React.ReactNode; } -export type TabItemProps = GoATabItemProps; - -export function GoATab({ heading, children }: GoATabItemProps): JSX.Element { +export function GoabTab({ heading, children }: GoabTabItemProps): JSX.Element { return ( {heading && {heading}} diff --git a/libs/react-components/src/lib/table/table-sort-header.spec.tsx b/libs/react-components/src/lib/table/table-sort-header.spec.tsx index 855c5026a..639fe6a2c 100644 --- a/libs/react-components/src/lib/table/table-sort-header.spec.tsx +++ b/libs/react-components/src/lib/table/table-sort-header.spec.tsx @@ -1,15 +1,15 @@ import { render } from "@testing-library/react"; -import GoATableSortHeader from "./table-sort-header"; +import GoabTableSortHeader from "./table-sort-header"; -describe("GoATableSortHeader", () => { +describe("GoABTableSortHeader", () => { it("renders", async () => { - render(); + render(); const el = document.querySelector("goa-table-sort-header"); expect(el).toBeTruthy(); }); it("binds direction param", async () => { - render(); + render(); const el = document.querySelector("goa-table-sort-header"); expect(el?.getAttribute("direction")).toBe("asc"); }); diff --git a/libs/react-components/src/lib/table/table-sort-header.tsx b/libs/react-components/src/lib/table/table-sort-header.tsx index 945a01eb2..cf590b835 100644 --- a/libs/react-components/src/lib/table/table-sort-header.tsx +++ b/libs/react-components/src/lib/table/table-sort-header.tsx @@ -1,8 +1,8 @@ -export type GoATableSortDirection = "asc" | "desc" | "none"; +import { GoabTableSortDirection } from "@abgov/ui-components-common"; interface WCProps { name?: string; - direction?: GoATableSortDirection; + direction?: GoabTableSortDirection; } declare global { @@ -16,17 +16,17 @@ declare global { } /* eslint-disable-next-line */ -export interface GoATableSortProps { +export interface GoabTableSortProps { name?: string; - direction?: GoATableSortDirection; + direction?: GoabTableSortDirection; children?: React.ReactNode; } -export function GoATableSortHeader({ +export function GoabTableSortHeader({ name, direction = "none", children, -}: GoATableSortProps): JSX.Element { +}: GoabTableSortProps): JSX.Element { return ( {children} @@ -34,4 +34,4 @@ export function GoATableSortHeader({ ); } -export default GoATableSortHeader; +export default GoabTableSortHeader; diff --git a/libs/react-components/src/lib/table/table.spec.tsx b/libs/react-components/src/lib/table/table.spec.tsx index 55e3424b9..d2ab715eb 100644 --- a/libs/react-components/src/lib/table/table.spec.tsx +++ b/libs/react-components/src/lib/table/table.spec.tsx @@ -1,6 +1,7 @@ import { render, fireEvent } from "@testing-library/react"; import { describe, it, vi } from "vitest"; import Table from "./table"; +import { GoabTableOnSortDetail } from "@abgov/ui-components-common"; describe("Table", () => { @@ -14,15 +15,16 @@ describe("Table", () => { const { baseElement } = render(); const table = baseElement.querySelector("goa-table"); + const event: GoabTableOnSortDetail = { sortBy: "name", sortDir: 1 }; expect(table).toBeTruthy(); table && fireEvent( table, new CustomEvent("_sort", { - detail: { sortBy: "name", sortDir: 1 } + detail: event }) ); - expect(onSort).toHaveBeenCalledWith("name", 1); + expect(onSort).toHaveBeenCalledWith(event); }); it("should handle _sort event gracefully when no onSort prop is passed", () => { @@ -31,12 +33,12 @@ describe("Table", () => { expect(table).toBeTruthy(); expect(() => - table && fireEvent( - table, - new CustomEvent("_sort", { - detail: { sortBy: "age", sortDir: -1 } - }) - ) + table && fireEvent( + table, + new CustomEvent("_sort", { + detail: { sortBy: "age", sortDir: -1 } + }) + ) ).not.toThrow(); }); }); diff --git a/libs/react-components/src/lib/table/table.tsx b/libs/react-components/src/lib/table/table.tsx index 167632c31..ab4145293 100644 --- a/libs/react-components/src/lib/table/table.tsx +++ b/libs/react-components/src/lib/table/table.tsx @@ -1,16 +1,11 @@ +import { GoabTableOnSortDetail, GoabTableVariant, Margins } from "@abgov/ui-components-common"; import { ReactNode, useEffect, useRef } from "react"; -import { Margins } from "../../common/styling"; - -export type GoATableVariant = "normal" | "relaxed"; - -// legacy naming -export type TableVariant = GoATableVariant; interface WCProps extends Margins { ref?: React.MutableRefObject; width?: string; stickyheader?: boolean; - variant?: GoATableVariant; + variant?: GoabTableVariant; testid?: string; } @@ -25,19 +20,19 @@ declare global { } /* eslint-disable-next-line */ -export interface GoATableProps extends Margins { +export interface GoabTableProps extends Margins { width?: string; - onSort?: (sortBy: string, sortDir: number) => void; + onSort?: (detail: GoabTableOnSortDetail) => void; // stickyHeader?: boolean; TODO: enable this later - variant?: GoATableVariant; + variant?: GoabTableVariant; testId?: string; children?: ReactNode; } // legacy name -export type TableProps = GoATableProps; +export type TableProps = GoabTableProps; -export function GoATable({onSort, ...props}: GoATableProps) { +export function GoabTable({ onSort, ...props }: GoabTableProps) { const ref = useRef(null); useEffect(() => { if (!ref.current) { @@ -45,8 +40,8 @@ export function GoATable({onSort, ...props}: GoATableProps) { } const current = ref.current; const sortListener = (e: unknown) => { - const { sortBy, sortDir } = (e as CustomEvent).detail; - onSort?.(sortBy, sortDir); + const detail = (e as CustomEvent).detail; + onSort?.(detail); }; current.addEventListener("_sort", sortListener); @@ -72,4 +67,4 @@ export function GoATable({onSort, ...props}: GoATableProps) { ); } -export default GoATable; +export default GoabTable; diff --git a/libs/react-components/src/lib/tabs/tabs.spec.tsx b/libs/react-components/src/lib/tabs/tabs.spec.tsx index 78f1c1b5c..775c55d81 100644 --- a/libs/react-components/src/lib/tabs/tabs.spec.tsx +++ b/libs/react-components/src/lib/tabs/tabs.spec.tsx @@ -1,19 +1,18 @@ import { render } from "@testing-library/react"; -import { GoATab } from "../tab/tab"; -import GoATabs from "./tabs"; +import { GoabTab } from "../tab/tab"; +import GoabTabs from "./tabs"; describe("Tabs", () => { it("should render successfully", () => { const { baseElement } = render( - - + +

- Profile: Lorem ipsum dolor sit amet, consectetur adipiscing - elit, sed do eiusmod tempor incididunt ut labore et dolore magna - aliqua. + Profile: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed + do eiusmod tempor incididunt ut labore et dolore magna aliqua.

-
-
+ + , ); const el = baseElement.querySelector("goa-tabs"); expect(el).toBeTruthy(); diff --git a/libs/react-components/src/lib/tabs/tabs.tsx b/libs/react-components/src/lib/tabs/tabs.tsx index 546e3e3a3..a522da219 100644 --- a/libs/react-components/src/lib/tabs/tabs.tsx +++ b/libs/react-components/src/lib/tabs/tabs.tsx @@ -1,4 +1,5 @@ import React, { useEffect, useRef } from "react"; +import { GoabTabsOnChangeDetail } from "@abgov/ui-components-common"; interface WCProps { initialtab?: number; @@ -16,27 +17,27 @@ declare global { } } -export interface GoATabsProps { +export interface GoabTabsProps { initialTab?: number; children?: React.ReactNode; testId?: string; - onChange?: (tab: number) => void; + onChange?: (detail: GoabTabsOnChangeDetail) => void; } -export function GoATabs({ +export function GoabTabs({ initialTab, children, testId, onChange, -}: GoATabsProps): JSX.Element { +}: GoabTabsProps): JSX.Element { const ref = useRef(null); useEffect(() => { const element = ref.current; if (element && onChange) { const handler = (event: Event) => { - const customEvent = event as CustomEvent; - onChange(customEvent.detail.tab); + const detail = (event as CustomEvent).detail; + onChange(detail); }; element.addEventListener("_change", handler); return () => { @@ -52,4 +53,4 @@ export function GoATabs({ ); } -export default GoATabs; +export default GoabTabs; diff --git a/libs/react-components/src/lib/textarea/textarea.spec.tsx b/libs/react-components/src/lib/textarea/textarea.spec.tsx index e3ffd6640..60880d9bc 100644 --- a/libs/react-components/src/lib/textarea/textarea.spec.tsx +++ b/libs/react-components/src/lib/textarea/textarea.spec.tsx @@ -1,11 +1,12 @@ import { fireEvent, render } from "@testing-library/react"; -import GoATextArea from "./textarea"; +import GoABTextArea from "./textarea"; import { describe, it, expect, vi } from "vitest"; +import { GoabTextAreaOnChangeDetail } from "@abgov/ui-components-common"; describe("TextArea", () => { it("renders the text area", async () => { render( - { mr="m" mb="l" ml="xl" - onChange={() => { /* do nothing */ }} - /> + onChange={() => { + /* do nothing */ + }} + />, ); const el = document.querySelector("goa-textarea"); - expect(el.getAttribute("name")).toBe("textarea-name"); - expect(el.getAttribute("value")).toBe("textarea-value"); - expect(el.getAttribute("rows")).toBe("10"); - expect(el.getAttribute("placeholder")).toBe("textarea-placeholder"); - expect(el.getAttribute("disabled")).toBe("true"); - expect(el.getAttribute("countby")).toBe("word"); - expect(el.getAttribute("maxcount")).toBe("50"); - expect(el.getAttribute("maxwidth")).toBe("100px"); - expect(el.getAttribute("mt")).toBe("s"); - expect(el.getAttribute("mr")).toBe("m"); - expect(el.getAttribute("mb")).toBe("l"); - expect(el.getAttribute("ml")).toBe("xl"); + expect(el?.getAttribute("name")).toBe("textarea-name"); + expect(el?.getAttribute("value")).toBe("textarea-value"); + expect(el?.getAttribute("rows")).toBe("10"); + expect(el?.getAttribute("placeholder")).toBe("textarea-placeholder"); + expect(el?.getAttribute("disabled")).toBe("true"); + expect(el?.getAttribute("countby")).toBe("word"); + expect(el?.getAttribute("maxcount")).toBe("50"); + expect(el?.getAttribute("maxwidth")).toBe("100px"); + expect(el?.getAttribute("mt")).toBe("s"); + expect(el?.getAttribute("mr")).toBe("m"); + expect(el?.getAttribute("mb")).toBe("l"); + expect(el?.getAttribute("ml")).toBe("xl"); }); it("handles the onChange event", async () => { @@ -43,7 +46,7 @@ describe("TextArea", () => { const newValue = "new-value"; render( - { rows={10} placeholder="textarea-placeholder" disabled={true} - onChange={(name: string, value: string) => { - expect(name).toBe("textarea-name"); - expect(value).toBe(newValue); + onChange={(event: GoabTextAreaOnChangeDetail) => { + expect(event.name).toBe("textarea-name"); + expect(event.value).toBe(newValue); onChange(); }} - /> + />, ); const el = document.querySelector("goa-textarea"); - fireEvent( - el, - new CustomEvent("_change", { - detail: { name: "textarea-name", value: newValue }, - }) - ); + if (el) { + fireEvent( + el, + new CustomEvent("_change", { + detail: { name: "textarea-name", value: newValue }, + }), + ); + } expect(onChange).toBeCalled(); }); diff --git a/libs/react-components/src/lib/textarea/textarea.tsx b/libs/react-components/src/lib/textarea/textarea.tsx index a13516b91..88c1d70c7 100644 --- a/libs/react-components/src/lib/textarea/textarea.tsx +++ b/libs/react-components/src/lib/textarea/textarea.tsx @@ -1,8 +1,10 @@ +import { + GoabTextAreaCountBy, + GoabTextAreaOnChangeDetail, + GoabTextAreaOnKeyPressDetail, + Margins, +} from "@abgov/ui-components-common"; import { useEffect, useRef } from "react"; -import { Margins } from "../../common/styling"; - - -type CountBy = "character" | "word"; interface WCProps extends Margins { ref: React.Ref; @@ -15,7 +17,7 @@ interface WCProps extends Margins { width?: string; maxwidth?: string; arialabel?: string; - countby?: CountBy; + countby?: GoabTextAreaCountBy; maxcount?: number; testid?: string; } @@ -29,7 +31,7 @@ declare global { } } -export interface GoATextAreaProps extends Margins { +export interface GoabTextAreaProps extends Margins { name: string; value?: string; id?: string; @@ -41,14 +43,14 @@ export interface GoATextAreaProps extends Margins { maxWidth?: string; testId?: string; ariaLabel?: string; - countBy?: CountBy; + countBy?: GoabTextAreaCountBy; maxCount?: number; - onChange?: (name: string, value: string) => void; - onKeyPress?: (name: string, value: string, key: string) => void; + onChange: (event: GoabTextAreaOnChangeDetail) => void; + onKeyPress?: (event: GoabTextAreaOnKeyPressDetail) => void; } -export function GoATextarea({ +export function GoabTextarea({ name, value, placeholder, @@ -67,7 +69,7 @@ export function GoATextarea({ ml, onChange, onKeyPress, -}: GoATextAreaProps): JSX.Element { +}: GoabTextAreaProps): JSX.Element { const el = useRef(null); useEffect(() => { @@ -75,9 +77,10 @@ export function GoATextarea({ return; } const current = el.current; - const listener: EventListener = (e: unknown) => { - const { name, value } = (e as CustomEvent).detail; - onChange?.(name, value); + const listener: EventListener = (e: Event) => { + const detail = (e as CustomEvent).detail; + + onChange(detail); }; current.addEventListener("_change", listener); @@ -86,16 +89,15 @@ export function GoATextarea({ }; }, [el, onChange]); - useEffect(() => { if (!el.current) { return; } const current = el.current; const keypressListener = (e: unknown) => { - const { name, value, key } = (e as CustomEvent).detail; - onKeyPress?.(name, value, key); - } + const detail = (e as CustomEvent).detail; + onKeyPress?.(detail); + }; current.addEventListener("_keyPress", keypressListener); return () => { @@ -126,6 +128,5 @@ export function GoATextarea({ ); } -export {GoATextarea as GoATextArea} -export default GoATextarea; - +export { GoabTextarea as GoABTextArea }; +export default GoabTextarea; diff --git a/libs/react-components/src/lib/three-column-layout/three-column-layout.spec.tsx b/libs/react-components/src/lib/three-column-layout/three-column-layout.spec.tsx index ba23804d5..bb1aa7d4f 100644 --- a/libs/react-components/src/lib/three-column-layout/three-column-layout.spec.tsx +++ b/libs/react-components/src/lib/three-column-layout/three-column-layout.spec.tsx @@ -1,7 +1,7 @@ import { render } from "@testing-library/react"; import ThreeColumnLayout from "./three-column-layout"; -import { GoAAppHeader } from "../app-header/app-header"; -import { GoAAppFooter } from "../footer/footer"; +import { GoabAppHeader } from "../app-header/app-header"; +import { GoabAppFooter } from "../footer/footer"; const Links = () => ( <> @@ -23,39 +23,39 @@ describe("ThreeColumnLayout", () => { it("should render successfully", () => { const { baseElement } = render( } - footer={} + header={} + footer={} nav={} sideMenu={} >

Heading

- Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint - cillum sint consectetur cupidatat. + Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint + consectetur cupidatat.

-
+ , ); expect(baseElement).toBeTruthy(); expect(baseElement.innerHTML).toContain( - "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat." + "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat.", ); expect(baseElement.querySelector("goa-app-header")).toBeTruthy(); expect(baseElement.innerHTML).toContain(""); expect(baseElement.querySelectorAll("[slot=nav] a").length).toEqual(5); - expect( - baseElement?.querySelector("[slot=side-menu] h2")?.innerHTML - ).toContain("Side Menu"); + expect(baseElement?.querySelector("[slot=side-menu] h2")?.innerHTML).toContain( + "Side Menu", + ); expect(baseElement?.querySelector("[slot=side-menu] p")?.innerHTML).toContain( - "Add content." + "Add content.", ); }); it("should render leftColumnWidth, rightColumnWidth, maxContentWidth accordingly", () => { const { baseElement } = render( } - footer={} + header={} + footer={} nav={} sideMenu={} leftColumnWidth="20%" @@ -64,15 +64,13 @@ describe("ThreeColumnLayout", () => { >

Heading

- Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint - cillum sint consectetur cupidatat. + Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint + consectetur cupidatat.

-
+ , ); - const el = baseElement.querySelector( - "goa-three-column-layout" - ); + const el = baseElement.querySelector("goa-three-column-layout"); expect(el).toBeTruthy(); expect(el?.getAttribute("leftcolumnwidth")).toBe("20%"); diff --git a/libs/react-components/src/lib/three-column-layout/three-column-layout.tsx b/libs/react-components/src/lib/three-column-layout/three-column-layout.tsx index 4c2d24fa0..f5426ad02 100644 --- a/libs/react-components/src/lib/three-column-layout/three-column-layout.tsx +++ b/libs/react-components/src/lib/three-column-layout/three-column-layout.tsx @@ -15,7 +15,7 @@ declare global { } } -export interface GoAThreeColumnLayoutProps { +export interface GoabThreeColumnLayoutProps { leftColumnWidth?: string; rightColumnWidth?: string; maxContentWidth?: string; @@ -27,7 +27,7 @@ export interface GoAThreeColumnLayoutProps { children: ReactNode; } -export function GoAThreeColumnLayout(props: GoAThreeColumnLayoutProps) { +export function GoabThreeColumnLayout(props: GoabThreeColumnLayoutProps) { return ( { it("should render successfully", () => { const { baseElement } = render( - Hover me + Hover me, ); const el = baseElement.querySelector("goa-tooltip"); @@ -15,14 +15,9 @@ describe("Tooltip", () => { it("should bind all web-component attributes", () => { const { baseElement } = render( - + Hover me - + , ); const el = baseElement.querySelector("goa-tooltip"); diff --git a/libs/react-components/src/lib/tooltip/tooltip.tsx b/libs/react-components/src/lib/tooltip/tooltip.tsx index deb5ad36b..1307f3919 100644 --- a/libs/react-components/src/lib/tooltip/tooltip.tsx +++ b/libs/react-components/src/lib/tooltip/tooltip.tsx @@ -1,15 +1,16 @@ +import { + GoabTooltipHorizontalAlignment, + GoabTooltipPosition, + Margins, +} from "@abgov/ui-components-common"; import { ReactNode } from "react"; -import { Margins } from "../../common/styling"; - -export type GoATooltipPosition = "top" | "bottom" | "left" | "right"; -export type GoATooltipHorizontalAlignment = "left" | "right" | "center"; /* eslint-disable-next-line */ interface WCProps extends Margins { - position?: GoATooltipPosition; + position?: GoabTooltipPosition; content?: string; - halign?: GoATooltipHorizontalAlignment; testid?: string; + halign?: GoabTooltipHorizontalAlignment; } declare global { @@ -22,15 +23,15 @@ declare global { } /* eslint-disable-next-line */ -export interface GoATooltipProps extends Margins { - position?: GoATooltipPosition; +export interface GoabTooltipProps extends Margins { + position?: GoabTooltipPosition; content?: string; - hAlign?: GoATooltipHorizontalAlignment; + hAlign?: GoabTooltipHorizontalAlignment; testId?: string; children?: ReactNode; } -export function GoATooltip(props: GoATooltipProps): JSX.Element { +export function GoabTooltip(props: GoabTooltipProps): JSX.Element { return ( { it("should render successfully", () => { const { baseElement } = render( } - footer={} + header={} + footer={} nav={} >

Heading

- Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint - cillum sint consectetur cupidatat. + Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint + consectetur cupidatat.

-
+ , ); expect(baseElement).toBeTruthy(); expect(baseElement.innerHTML).toContain( - "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat." + "Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum sint consectetur cupidatat.", ); expect(baseElement.querySelector("goa-app-header")).toBeTruthy(); expect(baseElement.innerHTML).toContain(""); diff --git a/libs/react-components/src/lib/two-column-layout/two-column-layout.tsx b/libs/react-components/src/lib/two-column-layout/two-column-layout.tsx index dbddac14b..6e4df518f 100644 --- a/libs/react-components/src/lib/two-column-layout/two-column-layout.tsx +++ b/libs/react-components/src/lib/two-column-layout/two-column-layout.tsx @@ -14,7 +14,7 @@ declare global { } } -export interface GoATwoColumnLayoutProps { +export interface GoabTwoColumnLayoutProps { navColumnWidth?: string; maxContentWidth?: string; header: ReactNode; @@ -23,7 +23,7 @@ export interface GoATwoColumnLayoutProps { children: ReactNode; } -export function GoATwoColumnLayout(props: GoATwoColumnLayoutProps) { +export function GoabTwoColumnLayout(props: GoabTwoColumnLayoutProps) { return (