setSelected(index)}
>
@@ -55,10 +55,10 @@ const Tabs: React.FunctionComponent<
return (
{item?.props.children}
diff --git a/packages/docs/stories/GettingStarted.stories.mdx b/packages/docs/stories/GettingStarted.stories.mdx
index 2015e3488..78e1b593a 100644
--- a/packages/docs/stories/GettingStarted.stories.mdx
+++ b/packages/docs/stories/GettingStarted.stories.mdx
@@ -32,27 +32,19 @@ import { Unstyled } from '@storybook/blocks';
title="Installing Shared UI"
>
- To get all the components packages, run the following command:
- ```
- npm install @wpmudev/sui-react
- ```
- When you install this package, additional packages will also be installed.
-
-
-
-
-
- You will also need to install `sui-css` and `sui-icons` packages:
+ Install `sui-css` package:
```
npm install @wpmudev/sui-css @wpmudev/sui-icons
```
- Finally, make sure to import the styles in your app, you can add this line to your top-most component in your application:
+ Make sure to import the styles in your app, you can add this line to your top-most component in your application:
```
import '@wpmudev/sui-css/dist/css/sui-css.min.css'
```
-
+
+ Sui React is organized into a collection of individual packages, with each component developed as a standalone package. For detailed installation guidance, please refer to the documentation for each component.
+
diff --git a/packages/hooks/CHANGELOG.md b/packages/hooks/CHANGELOG.md
index 2c0ad9b44..7628a5208 100644
--- a/packages/hooks/CHANGELOG.md
+++ b/packages/hooks/CHANGELOG.md
@@ -1,5 +1,13 @@
# @wpmudev/sui-hooks
+## 0.0.2
+
+### Patch Changes
+
+- 0784d2c: Updated and improved components used by the Dash plugin
+- Updated dependencies [0784d2c]
+ - @wpmudev/sui-utils@0.0.2
+
## 0.0.1
### Patch Changes
diff --git a/packages/hooks/package.json b/packages/hooks/package.json
index 227de9810..b4ea97635 100644
--- a/packages/hooks/package.json
+++ b/packages/hooks/package.json
@@ -1,6 +1,6 @@
{
"name": "@wpmudev/sui-hooks",
- "version": "0.0.1",
+ "version": "0.0.2",
"description": "WPMU DEV Shared UI React Global Hooks",
"keywords": [],
"author": "WPMU DEV (https://wpmudev.com)",
@@ -36,7 +36,7 @@
"homepage": "https://github.com/wpmudev/sui-docs#readme",
"clean-package": "../../postpack.config.json",
"dependencies": {
- "@wpmudev/sui-utils": "^0.0.1",
+ "@wpmudev/sui-utils": "^0.0.2",
"@emotion/css": "^11.11.2"
},
"devDependencies": {
diff --git a/packages/hooks/src/index.ts b/packages/hooks/src/index.ts
index 739daacf0..45e2c5201 100644
--- a/packages/hooks/src/index.ts
+++ b/packages/hooks/src/index.ts
@@ -1,3 +1,4 @@
+import { useScrollable } from "./use-scrollable"
// useInteraction hook
export { useInteraction } from "./use-intraction"
export type { InteractionTypes } from "./use-intraction"
@@ -32,8 +33,20 @@ export { useBottomEnd } from "./use-bottom-end"
// useDebounce
export { useDebounce } from "./use-debounce"
+// useResponsive
+export { useResponsive } from "./use-responsive"
+
+// useIsOverflowing
+export { useIsOverflowing } from "./use-is-overflowing"
+
+// useScrollable
+export { useScrollable } from "./use-scrollable"
+
// useStyles
export * from "./use-styles"
// validation
export * from "./use-validation"
+
+// prevent unload hook
+export * from "./use-prevent-unload"
diff --git a/packages/hooks/src/use-default-children.ts b/packages/hooks/src/use-default-children.ts
index 61e488d21..aa12fb035 100644
--- a/packages/hooks/src/use-default-children.ts
+++ b/packages/hooks/src/use-default-children.ts
@@ -8,7 +8,8 @@ const useDefaultChildren = (
children: ReactNode, // the component children prop
content?: ReactNode, // the default content to display
) => {
- return children || content || "{children content}"
+ // Explicitly check for null or undefined
+ return children !== null ? children : content || "{children content}"
}
export { useDefaultChildren }
diff --git a/packages/hooks/src/use-is-overflowing.ts b/packages/hooks/src/use-is-overflowing.ts
new file mode 100644
index 000000000..f99008eb3
--- /dev/null
+++ b/packages/hooks/src/use-is-overflowing.ts
@@ -0,0 +1,32 @@
+import React, { useLayoutEffect, RefObject, useState } from "react"
+
+/**
+ * Detects if the text height exceeds the maximum allowed lines.
+ *
+ * @param {RefObject} ref - The reference to the target element.
+ * @param {number} maxLines - The maximum number of lines allowed before overflow.
+ * @param {any} dependency - The dependency that triggers recalculation (e.g., text).
+ * @return {boolean} - Returns `true` if the text overflows the allowed lines, otherwise `false`.
+ */
+
+const useIsOverflowing = (
+ ref: RefObject,
+ maxLines: number,
+ dependency: any,
+) => {
+ const [isOverflowing, setIsOverflowing] = useState(false)
+
+ useLayoutEffect(() => {
+ if (ref.current) {
+ const lineHeight = parseFloat(
+ window.getComputedStyle(ref.current).lineHeight,
+ )
+ const maxHeight = lineHeight * maxLines
+ setIsOverflowing(ref.current.scrollHeight > maxHeight)
+ }
+ }, [dependency, maxLines, ref])
+
+ return isOverflowing
+}
+
+export { useIsOverflowing }
diff --git a/packages/hooks/src/use-prevent-unload.ts b/packages/hooks/src/use-prevent-unload.ts
new file mode 100644
index 000000000..86a2ff794
--- /dev/null
+++ b/packages/hooks/src/use-prevent-unload.ts
@@ -0,0 +1,33 @@
+import { useEffect } from "react"
+
+/**
+ *
+ * Trigger a browser-generated confirmation dialog that asks users to confirm if they really want to leave the page
+ * when they try to close or reload it, or navigate somewhere else. This's intended to help prevent loss of unsaved
+ * data or to wait for processies to finish
+ *
+ * Limitations:
+ * - A mobile user visits your page.
+ * - The user then switches to a different app.
+ * - Later, the user closes the browser from the app manager.
+ *
+ * @param preventUnload boolean
+ */
+export const usePreventUnload = (preventUnload: boolean) => {
+ useEffect(() => {
+ const handleBeforeUnload = (event: BeforeUnloadEvent) => {
+ if (preventUnload) {
+ event.preventDefault()
+
+ return null
+ }
+ }
+
+ window.addEventListener("beforeunload", handleBeforeUnload)
+
+ // Clean up the event listener when the component is unmounted
+ return () => {
+ window.removeEventListener("beforeunload", handleBeforeUnload)
+ }
+ }, [preventUnload])
+}
diff --git a/packages/hooks/src/use-responsive.ts b/packages/hooks/src/use-responsive.ts
new file mode 100644
index 000000000..002a40979
--- /dev/null
+++ b/packages/hooks/src/use-responsive.ts
@@ -0,0 +1,85 @@
+import { useState, useEffect, useMemo } from "react"
+
+type ValueType = number | number[]
+
+// Config type.
+interface ConfigType {
+ [key: string]: ValueType
+}
+
+// Sort the config object.
+const sort = (devices: ConfigType) => {
+ return Object.entries(devices).sort((a, b) => {
+ const [aValue, bValue] = [a[1], b[1]]
+ const [aIsRange, bIsRange] = [Array.isArray(aValue), Array.isArray(bValue)]
+
+ if (aIsRange && bIsRange) {
+ // compare min-width, then max-width if necessary
+ const [aMin, aMax] = aValue as [number, number]
+ const [bMin, bMax] = bValue as [number, number]
+ return bMin !== aMin ? bMin - aMin : bMax - aMax
+ }
+
+ // prioritize ranges over single values
+ if (aIsRange !== bIsRange) return aIsRange ? -1 : 1
+ return (bValue as number) - (aValue as number)
+ })
+}
+
+// Generate the media queries.
+const getMediaQuery = (value: ValueType): string => {
+ if (typeof value === "number") {
+ return `(min-width: ${value}px)`
+ }
+
+ if (Array.isArray(value)) {
+ let [min, max] = value
+ // swap values if min is greater than max
+ if (min > max) [min, max] = [max, min]
+
+ return `(min-width: ${min}px) and (max-width: ${max - 1}px)` // Subtract 1 for inclusivity
+ }
+
+ return ""
+}
+
+// Get the deivce key.
+const getDevice = (devices: ConfigType): string => {
+ for (const [deviceKey, value] of sort(devices)) {
+ if (window.matchMedia(getMediaQuery(value)).matches) {
+ return deviceKey
+ }
+ }
+ return "OutOfScope"
+}
+
+const useResponsive = (config: ConfigType = {}) => {
+ const defaultBreakpoints = useMemo(
+ () => ({ desktop: 1024, tablet: 600, mobile: [600, 0], ...config }),
+ [config],
+ )
+
+ const [device, setDevice] = useState(() => getDevice(defaultBreakpoints))
+
+ useEffect(() => {
+ const handleResize = () => setDevice(getDevice(defaultBreakpoints))
+
+ // initialize matchMedia for each device and listen for changes
+ const mediaQueries = Object.values(defaultBreakpoints).map((value) => {
+ const mediaList = window.matchMedia(getMediaQuery(value))
+ mediaList.addEventListener("change", handleResize)
+ return mediaList
+ })
+
+ // cleanup event listeners on unmount
+ return () => {
+ mediaQueries.forEach((mediaList) =>
+ mediaList.removeEventListener("change", handleResize),
+ )
+ }
+ }, [defaultBreakpoints])
+
+ return device
+}
+
+export { useResponsive }
diff --git a/packages/hooks/src/use-scrollable.ts b/packages/hooks/src/use-scrollable.ts
new file mode 100644
index 000000000..be7759a37
--- /dev/null
+++ b/packages/hooks/src/use-scrollable.ts
@@ -0,0 +1,172 @@
+import { useCallback, useEffect, useRef, useState } from "react"
+import { useDetectRTL } from "./use-rtl-detect"
+
+const useScrollable = ({ scrollOffset = 0 }) => {
+ const [isScrollableRight, setIsScrollableRight] = useState(false)
+ const [isScrollableLeft, setIsScrollableLeft] = useState(false)
+ const containerRef = useRef(null)
+ const isRTL = useDetectRTL()
+
+ const handleScroll = useCallback(() => {
+ const current = containerRef.current
+ if (!current) return
+
+ const { scrollLeft, scrollWidth, clientWidth } = current
+ const navLeft = Math.abs(scrollLeft ?? 0)
+
+ setIsScrollableRight(
+ isRTL ? navLeft >= 1 : navLeft < scrollWidth - clientWidth - 1,
+ )
+ setIsScrollableLeft(
+ isRTL ? navLeft < scrollWidth - clientWidth - 1 : navLeft >= 1,
+ )
+ }, [isRTL])
+
+ const findPartiallyVisibleItem = (direction: "left" | "right") => {
+ if (!containerRef.current) return null
+
+ const container = containerRef.current
+ const children = Array.from(container.children) as HTMLElement[]
+ const containerRect = container.getBoundingClientRect()
+ const currentScroll = container.scrollLeft
+
+ for (let i = 0; i < children.length; i++) {
+ const child = children[i]
+ const childRect = child.getBoundingClientRect()
+
+ // Calculate relative positions within the container
+ const childLeft = childRect.left - containerRect.left + currentScroll
+ const childRight = childLeft + childRect.width
+ const containerLeft = currentScroll
+ const containerRight = currentScroll + container.clientWidth
+
+ // Check if item is partially visible
+ const isPartiallyLeft =
+ childLeft < containerLeft && childRight > containerLeft
+ const isPartiallyRight =
+ childLeft < containerRight && childRight > containerRight
+
+ if (direction === "left" && isPartiallyLeft) {
+ // For left scroll, we want to show the hidden part on the left
+ const hiddenWidth = containerLeft - childLeft
+ return {
+ element: child,
+ hiddenWidth,
+ targetScroll: childLeft - scrollOffset,
+ }
+ }
+
+ if (direction === "right" && isPartiallyRight) {
+ // For right scroll, we want to show the hidden part on the right
+ const hiddenWidth = childRight - containerRight
+ return {
+ element: child,
+ hiddenWidth,
+ targetScroll: childRight - container.clientWidth + scrollOffset,
+ }
+ }
+ }
+
+ // If no partially visible item found, find the next completely hidden item
+ for (let i = 0; i < children.length; i++) {
+ const child = children[i]
+ const childRect = child.getBoundingClientRect()
+
+ const childLeft = childRect.left - containerRect.left + currentScroll
+ const childRight = childLeft + childRect.width
+ const containerLeft = currentScroll
+ const containerRight = currentScroll + container.clientWidth
+
+ if (direction === "left" && childRight <= containerLeft) {
+ // Find the rightmost hidden item on the left
+ let targetItem = child
+ let targetIndex = i
+
+ for (let j = i + 1; j < children.length; j++) {
+ const nextChild = children[j]
+ const nextChildRect = nextChild.getBoundingClientRect()
+ const nextChildRight =
+ nextChildRect.left -
+ containerRect.left +
+ currentScroll +
+ nextChildRect.width
+
+ if (nextChildRight <= containerLeft) {
+ targetItem = nextChild
+ targetIndex = j
+ } else {
+ break
+ }
+ }
+
+ return {
+ element: targetItem,
+ hiddenWidth: targetItem.offsetWidth,
+ targetScroll: childLeft - scrollOffset,
+ }
+ }
+
+ if (direction === "right" && childLeft >= containerRight) {
+ // First completely hidden item on the right
+ return {
+ element: child,
+ hiddenWidth: child.offsetWidth,
+ targetScroll: childLeft - scrollOffset,
+ }
+ }
+ }
+
+ return null
+ }
+
+ const scroll = (direction: "left" | "right") => {
+ if (!containerRef.current) return
+ const container = containerRef.current
+ const targetItem = findPartiallyVisibleItem(direction)
+
+ container.scrollTo({
+ left: targetItem?.targetScroll ?? 0,
+ behavior: "smooth",
+ })
+ }
+
+ useEffect(() => {
+ const current = containerRef.current
+ if (!current) return
+
+ handleScroll()
+ current.addEventListener("scroll", handleScroll)
+
+ return () => {
+ current.removeEventListener("scroll", handleScroll)
+ }
+ }, [handleScroll])
+
+ useEffect(() => {
+ const handleResize = () => handleScroll()
+ window.addEventListener("resize", handleResize)
+ return () => window.removeEventListener("resize", handleResize)
+ }, [handleScroll])
+
+ // Observe the container.
+ useEffect(() => {
+ const observer = new IntersectionObserver(
+ (entries) => {
+ if (entries[0].isIntersecting) {
+ handleScroll()
+ }
+ },
+ { threshold: 0.1 },
+ )
+
+ if (containerRef.current) {
+ observer.observe(containerRef.current)
+ }
+
+ return () => observer.disconnect()
+ }, [handleScroll])
+
+ return { containerRef, isScrollableLeft, isScrollableRight, scroll }
+}
+
+export { useScrollable }
diff --git a/packages/hooks/src/use-styles.ts b/packages/hooks/src/use-styles.ts
index 33228b53a..ff8137fbd 100644
--- a/packages/hooks/src/use-styles.ts
+++ b/packages/hooks/src/use-styles.ts
@@ -4,7 +4,6 @@ import createEmotion from "@emotion/css/create-instance"
import {
_isTestingMode,
generateCN,
- isValidCSSProperty,
isObjectEmpty,
isNestedStyleProperty,
} from "@wpmudev/sui-utils"
@@ -102,7 +101,7 @@ export const CSS_SHORTHAND_MAPS: Record = {
}
// We need this to wrap inline styles to prioritize
-const parentSelector: string = "body .sui-wrap &"
+const parentSelector: string = "body #sui-wrap &"
/**
* Build style object based on prop name and value
@@ -197,13 +196,13 @@ const { css } = createEmotion({
const createStyles = (styleObject: Record) =>
!isObjectEmpty(styleObject) ? css(styleObject) : ""
-/**
- * Check if an object has valid CSSProperty
- *
- * @param {Object} props expected to be CSSProperties
- */
-const isValidCSSPropExists = (props: object): boolean =>
- Object.keys(props).filter((p) => !!isValidCSSProperty(p)).length > 0
+// /**
+// * Check if an object has valid CSSProperty, this one check for native css properties
+// *
+// * @param {Object} props expected to be CSSProperties
+// */
+// const isValidCSSPropExists = (props: Record): boolean =>
+// Object.keys(props).filter((p) => !!isValidCSSRule(p, props[p])).length > 0
/**
* SUI custom hook for generating className based on passed CSS properties
@@ -227,8 +226,10 @@ export const useStyles = (
const styleObject = JSON.parse(stringifiedStyles)
let generatedCSS: Record = {}
- // process if styleProps has valid CSS properties
- if (!isObjectEmpty(styleObject) && isValidCSSPropExists(styleObject)) {
+ /* Process if styleProps has valid CSS propertie
+ We don't have to check for css properties validity since we are making type checking
+ and the reason is there's no one way that works with all browsers */
+ if (!isObjectEmpty(styleObject)) {
// go through all props
for (const name of Object.keys(styleObject)) {
const val = styleObject[name as keyof CSSProperties]
diff --git a/packages/hooks/stories/pages/Usage.mdx b/packages/hooks/stories/pages/Usage.mdx
index 3ae7fd9b2..725e11ce4 100644
--- a/packages/hooks/stories/pages/Usage.mdx
+++ b/packages/hooks/stories/pages/Usage.mdx
@@ -1,4 +1,5 @@
import { Section, Code, Snippet, List } from '@wpmudev/sui-docs';
+import { usePreventUnload } from '../../src';
@@ -369,3 +370,186 @@ import { Section, Code, Snippet, List } from '@wpmudev/sui-docs';
+
+
+
+ The useResponsive hook is designed to detect and manage the current device type
+ (e.g., mobile, tablet, desktop) based on window width. It provides a dynamic way to handle
+ responsive behavior in React applications.
+
+
+ It accepts 1 parameter:
+
+ - config: optional configuration for custom device breakpoints
+
+
+
+ config
+
+ The config object defines custom breakpoints for different devices. Each key in the object
+ corresponds to a device type (e.g., mobile, tablet, desktop), and the value defines its screen size.
+
+
+ There are two types of values you can use for each device key:
+
+
+ -
+ number: a minimum width for the device. This will match when the window width is
+ greater than or equal to this number.
+
+ -
+ array: a range of widths for the device in the form
[min, max]. The
+ device will be active when the window width is within this range.
+
+
+
+ If no config is provided, the hook will use the following default breakpoints:
+
+ ```javascript
+ {
+ desktop: 1024, // (min-width: 1024px)
+ tablet: 600, // (min-width: 600px)
+ mobile: [600, 0] // (min-width: 0px) and (max-width: 599px)
+ }
+ ```
+
+ Example config
+
+ ```javascript
+ {
+ largeDesktop: 1440,
+ tablet: [768, 1024],
+ smallMobile: [0, 480]
+ }
+ ```
+
+ How it works
+
+ Internally, the hook sorts the devices based on their widths and ranges. It listens to the
+ resize event and uses window.matchMedia() to detect the current width of the
+ browser window. When the window size changes, the hook updates the active device type accordingly.
+
+
+ Return value
+
+ The useResponsive hook returns a single value:
+
+ -
+ device: a string representing the active device based on the current window width
+ (e.g., 'mobile', 'tablet', 'desktop'). If no match is found, it returns 'unknown'.
+
+
+
+
+ Example
+
+ ```javascript
+ import React from 'react';
+ import { useResponsive } from './hooks/useResponsive';
+
+ const MyComponent = () => {
+ const device = useResponsive({
+ desktop: 1200,
+ tablet: [600, 1200],
+ mobile: [0, 600],
+ });
+
+ return (
+
+ {device === 'mobile' &&
You are on a mobile device!
}
+ {device === 'tablet' &&
You are on a tablet!
}
+ {device === 'desktop' &&
You are on a desktop!
}
+ {device === 'unknown' &&
Device type is unknown.
}
+
+ );
+ };
+ ```
+
+ Dynamic behavior
+
+ The useResponsive hook listens for changes to the window width and updates the
+ device value dynamically. This makes it ideal for implementing responsive components
+ that need to adapt based on screen size.
+
+
+ Responsive in action
+
+ ```javascript
+ import React from 'react';
+ import { useResponsive } from './hooks/useResponsive';
+
+ const ResponsiveLayout = () => {
+ const device = useResponsive();
+
+ return (
+
+ {device === 'mobile' &&
}
+ {device === 'tablet' &&
}
+ {device === 'desktop' &&
}
+
+ );
+ };
+ ```
+
+
+
+
+
+
+ The usePreventUnload hook is designed to trigger a browser-generated confirmation dialog that asks users to confirm if they really want to leave the page when they try to close or reload it, or navigate somewhere else. This's intended to help prevent loss of unsaved data or to wait for processies to finish
+
+
+ It accepts 1 parameter:
+
+ - preventUnload: a boolean to indicate whether to prevent unload or not
+
+
+
+ Example
+
+ ```javascript
+ import React, { useState } from "react";
+ import { usePreventUnload } from "@wpmudev/sui-hooks";
+
+ export const SaveDataComponent: React.FC = () => {
+ const [isSaving, setIsSaving] = useState(false);
+ const [data, setData] = useState("");
+
+ // Prevent unload when saving data
+ usePreventUnload(isSaving);
+
+ const handleSave = async () => {
+ setIsSaving(true);
+ try {
+ await fetch("https://api.example.com/save", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ data }),
+ });
+ alert("Data saved successfully!");
+ } catch (error) {
+ console.error("Error saving data:", error);
+ } finally {
+ setIsSaving(false);
+ }
+ };
+
+ return (
+
+
+ );
+ };
+
+ ```
+
+ This example uses the usePreventUnload hook to prevent the user from leaving the page while data is saving. The isSaving state tracks the save process, and usePreventUnload(isSaving) triggers a confirmation dialog if the user tries to leave before the data has finished saving.
+
+
\ No newline at end of file
diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md
deleted file mode 100644
index 293c5681a..000000000
--- a/packages/react/CHANGELOG.md
+++ /dev/null
@@ -1,2 +0,0 @@
-# Change Log
-
diff --git a/packages/react/__tests__/sui-core.test.js b/packages/react/__tests__/sui-core.test.js
deleted file mode 100644
index 14d6b98c7..000000000
--- a/packages/react/__tests__/sui-core.test.js
+++ /dev/null
@@ -1,3 +0,0 @@
-"use strict"
-
-describe("@wpmudev/sui-react", () => {})
diff --git a/packages/react/package.json b/packages/react/package.json
deleted file mode 100644
index 1d16304bd..000000000
--- a/packages/react/package.json
+++ /dev/null
@@ -1,104 +0,0 @@
-{
- "name": "@wpmudev/sui-react",
- "version": "0.0.1",
- "description": "It provides all the ui components for available for sui react",
- "keywords": [],
- "author": "WPMU DEV (https://wpmudev.com)",
- "contributors": [
- {
- "name": "Govind Kumar",
- "email": "gkprmr@gmail.com",
- "url": "https://govind.js.org/"
- }
- ],
- "license": "GPL-2.0",
- "main": "src/index.ts",
- "directories": {
- "lib": "src",
- "test": "__tests__"
- },
- "files": [
- "dist"
- ],
- "publishConfig": {
- "access": "public"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/wpmudev/sui-react.git",
- "directory": "packages/react"
- },
- "scripts": {
- "clean": "rm -rf dist && rm -rf lib",
- "build": "npx tsup",
- "build:dev": "npx tsup --watch",
- "build:fast": "tsup src",
- "dev": "npm build:fast -- --watch",
- "prepack": "clean-package",
- "postpack": "clean-package restore",
- "build:readme": "readme generate --input ../../blueprint.md"
- },
- "bugs": {
- "url": "https://github.com/wpmudev/sui-react/issues"
- },
- "homepage": "https://github.com/wpmudev/sui-react#readme",
- "dependencies": {
- "@wpmudev/sui-accordion": "^0.0.1",
- "@wpmudev/sui-advanced-banner": "^0.0.1",
- "@wpmudev/sui-alert-banner": "^0.0.1",
- "@wpmudev/sui-avatar": "^0.0.1",
- "@wpmudev/sui-basic-box": "^0.0.1",
- "@wpmudev/sui-box": "^0.0.1",
- "@wpmudev/sui-button": "^0.0.1",
- "@wpmudev/sui-builder": "^0.0.1",
- "@wpmudev/sui-checkbox": "^0.0.1",
- "@wpmudev/sui-code-editor": "^0.0.1",
- "@wpmudev/sui-code-snippet": "^0.0.1",
- "@wpmudev/sui-color-picker": "^0.0.1",
- "@wpmudev/sui-config-table": "^0.0.1",
- "@wpmudev/sui-dashboard-widget": "^0.0.1",
- "@wpmudev/sui-date-picker": "^0.0.1",
- "@wpmudev/sui-dropdown": "^0.0.1",
- "@wpmudev/sui-editor-toolbar": "^0.0.1",
- "@wpmudev/sui-empty-state": "^0.0.1",
- "@wpmudev/sui-field-list": "^0.0.1",
- "@wpmudev/sui-footer": "^0.0.1",
- "@wpmudev/sui-form-field": "^0.0.1",
- "@wpmudev/sui-grid": "^0.0.1",
- "@wpmudev/sui-icon": "^0.0.1",
- "@wpmudev/sui-input": "^0.0.1",
- "@wpmudev/sui-integration": "^0.0.1",
- "@wpmudev/sui-link": "^0.0.1",
- "@wpmudev/sui-modal": "^0.0.1",
- "@wpmudev/sui-navigation": "^0.0.1",
- "@wpmudev/sui-notification": "^0.0.1",
- "@wpmudev/sui-pagination": "^0.0.1",
- "@wpmudev/sui-password-field": "^0.0.1",
- "@wpmudev/sui-progress-bar": "^0.0.1",
- "@wpmudev/sui-radio": "^0.0.1",
- "@wpmudev/sui-recipient": "^0.0.1",
- "@wpmudev/sui-rich-text-editor": "^0.0.1",
- "@wpmudev/sui-score": "^0.0.1",
- "@wpmudev/sui-search": "^0.0.1",
- "@wpmudev/sui-segmented-control": "^0.0.1",
- "@wpmudev/sui-select": "^0.0.1",
- "@wpmudev/sui-selector": "^0.0.1",
- "@wpmudev/sui-setting-block": "^0.0.1",
- "@wpmudev/sui-setup-banner": "^0.0.1",
- "@wpmudev/sui-sidebar": "^0.0.1",
- "@wpmudev/sui-spinner": "^0.0.1",
- "@wpmudev/sui-summary-box": "^0.0.1",
- "@wpmudev/sui-table": "^0.0.1",
- "@wpmudev/sui-tabs": "^0.0.1",
- "@wpmudev/sui-tag": "^0.0.1",
- "@wpmudev/sui-textarea": "^0.0.1",
- "@wpmudev/sui-toggle": "^0.0.1",
- "@wpmudev/sui-tooltip": "^0.0.1",
- "@wpmudev/sui-tree-view": "^0.0.1",
- "@wpmudev/sui-uploader": "^0.0.1",
- "@wpmudev/sui-upsell-notice": "^0.0.1",
- "@wpmudev/sui-upsell": "^0.0.1",
- "@wpmudev/sui-hooks": "^0.0.1",
- "@wpmudev/sui-utils": "^0.0.1"
- }
-}
diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts
deleted file mode 100644
index ac12c98c5..000000000
--- a/packages/react/src/index.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-// Core
-export * from "@wpmudev/sui-avatar"
-export * from "@wpmudev/sui-box"
-export * from "@wpmudev/sui-grid"
-export * from "@wpmudev/sui-link"
-export * from "@wpmudev/sui-icon"
-export * from "@wpmudev/sui-score"
-export * from "@wpmudev/sui-segmented-control"
-export * from "@wpmudev/sui-selector"
-export * from "@wpmudev/sui-spinner"
-export * from "@wpmudev/sui-tag"
-export * from "@wpmudev/sui-tooltip"
-
-// Forms
-export * from "@wpmudev/sui-checkbox"
-export * from "@wpmudev/sui-radio"
-export * from "@wpmudev/sui-button"
-export * from "@wpmudev/sui-form-field"
-export * from "@wpmudev/sui-input"
-export * from "@wpmudev/sui-textarea"
-export * from "@wpmudev/sui-toggle"
-
-// Advanced
-export * from "@wpmudev/sui-accordion"
-export * from "@wpmudev/sui-alert-banner"
-export * from "@wpmudev/sui-code-editor"
-export * from "@wpmudev/sui-code-snippet"
-export * from "@wpmudev/sui-color-picker"
-export * from "@wpmudev/sui-date-picker"
-export * from "@wpmudev/sui-dropdown"
-export * from "@wpmudev/sui-empty-state"
-export * from "@wpmudev/sui-password-field"
-export * from "@wpmudev/sui-modal"
-export * from "@wpmudev/sui-notification"
-export * from "@wpmudev/sui-progress-bar"
-export * from "@wpmudev/sui-select"
-export * from "@wpmudev/sui-sidebar"
-export * from "@wpmudev/sui-summary-box"
-export * from "@wpmudev/sui-tabs"
-export * from "@wpmudev/sui-tree-view"
-export * from "@wpmudev/sui-uploader"
-export * from "@wpmudev/sui-field-list"
-export * from "@wpmudev/sui-recipient"
-export * from "@wpmudev/sui-rich-text-editor"
-export * from "@wpmudev/sui-advanced-banner"
-export * from "@wpmudev/sui-builder"
-export * from "@wpmudev/sui-editor-toolbar"
-export * from "@wpmudev/sui-pagination"
-export * from "@wpmudev/sui-search"
-export * from "@wpmudev/sui-basic-box"
-export * from "@wpmudev/sui-setting-block"
-export * from "@wpmudev/sui-popover"
-
-// Modules
-export * from "@wpmudev/sui-table"
-export * from "@wpmudev/sui-dashboard-widget"
-export * from "@wpmudev/sui-navigation"
-export * from "@wpmudev/sui-integration"
-
-// Collections
-export * from "@wpmudev/sui-footer"
-export * from "@wpmudev/sui-config-table"
-export * from "@wpmudev/sui-setup-banner"
-export * from "@wpmudev/sui-upsell"
-export * from "@wpmudev/sui-upsell-notice"
diff --git a/packages/react/stories/Overview.stories.mdx b/packages/react/stories/Overview.stories.mdx
deleted file mode 100644
index 0e67f9dc9..000000000
--- a/packages/react/stories/Overview.stories.mdx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { Meta } from '@storybook/addon-docs';
-import { Page } from '@wpmudev/sui-docs';
-import { Unstyled } from '@storybook/blocks';
-
-import Installation from './pages/Installation.mdx';
-import Usage from './pages/Usage.mdx';
-
-
-
-
-
- This package provides a set of components, allowing you to enhance your plugin's functionality effortlessly
- >
- }
- >
-
-
-
-
-
-
-
-
diff --git a/packages/react/stories/pages/Installation.mdx b/packages/react/stories/pages/Installation.mdx
deleted file mode 100644
index 8fe4e0bdc..000000000
--- a/packages/react/stories/pages/Installation.mdx
+++ /dev/null
@@ -1,56 +0,0 @@
-import { Section, Code, Snippet, NodeJSWarning } from "@wpmudev/sui-docs"
-
-
-
-
-
-
- @wpmudev/sui-react, a package within our library, offers all the UI components required for your plugin. This package allows developers to load all these components from the library at once, ensuring convenience. Notably, please be aware that it doesn't includes following packages: @wpmudev/sui-utils, @wpmudev/sui-css, @wpmudev/sui-hooks, and @wpmudev/react-icons.
-
-
-
-
-
- In your project root directory (where the package.json file
- lives), run the following command:
-
- ```js
- npm install --save @wpmudev/sui-react
- ```
-
-
-
- In your project root directory (where the package.json file
- lives), run the following command:
-
- ```js
- yarn add @wpmudev/sui-react
- ```
-
diff --git a/packages/react/stories/pages/Usage.mdx b/packages/react/stories/pages/Usage.mdx
deleted file mode 100644
index a08175754..000000000
--- a/packages/react/stories/pages/Usage.mdx
+++ /dev/null
@@ -1,100 +0,0 @@
-import dedent from 'ts-dedent';
-
-import { Section, Code, Snippet } from '@wpmudev/sui-docs';
-
-
-
- Once you've installed the React Package package into your plugin, you
- can import any SUI 3 React components.
-
-
- For an example, if you want to import Button component in your plugin/app, you can import as follow:
- ```js
- import { Button } from "@wpmudev/sui-react"
- ```
-
-
-
Here is a list of component packages, it contains:
-
- - Core components:
-
- - `@wpmudev/sui-avatar`
- - `@wpmudev/sui-box`
- - `@wpmudev/sui-grid`
- - `@wpmudev/sui-link`
- - `@wpmudev/sui-icon`
- - `@wpmudev/sui-score`
- - `@wpmudev/sui-segmented-control`
- - `@wpmudev/sui-selector`
- - `@wpmudev/sui-spinner`
- - `@wpmudev/sui-tag`
- - `@wpmudev/sui-tooltip`
-
-
-
- - Form components:
-
- - `@wpmudev/sui-checkbox`
- - `@wpmudev/sui-radio`
- - `@wpmudev/sui-button`
- - `@wpmudev/sui-form-field`
- - `@wpmudev/sui-input`
- - `@wpmudev/sui-textarea`
- - `@wpmudev/sui-toggle`
-
-
-
- - Advanced components
-
- - `@wpmudev/sui-accordion`
- - `@wpmudev/sui-alert-banner`
- - `@wpmudev/sui-code-editor`
- - `@wpmudev/sui-code-snippet`
- - `@wpmudev/sui-color-picker`
- - `@wpmudev/sui-date-picker`
- - `@wpmudev/sui-dropdown`
- - `@wpmudev/sui-empty-state`
- - `@wpmudev/sui-password-field`
- - `@wpmudev/sui-modal`
- - `@wpmudev/sui-notification`
- - `@wpmudev/sui-progress-bar`
- - `@wpmudev/sui-select`
- - `@wpmudev/sui-sidebar`
- - `@wpmudev/sui-summary-box`
- - `@wpmudev/sui-tabs`
- - `@wpmudev/sui-tree-view`
- - `@wpmudev/sui-uploader`
- - `@wpmudev/sui-field-list`
- - `@wpmudev/sui-recipient`
- - `@wpmudev/sui-rich-text-editor`
- - `@wpmudev/sui-advanced-banner`
- - `@wpmudev/sui-builder`
- - `@wpmudev/sui-editor-toolbar`
- - `@wpmudev/sui-pagination`
- - `@wpmudev/sui-search`
- - `@wpmudev/sui-basic-box`
- - `@wpmudev/sui-setting-block`
- - `@wpmudev/sui-popover`
-
-
-
- - Module Components:
-
- - `@wpmudev/sui-table`
- - `@wpmudev/sui-dashboard-widget`
- - `@wpmudev/sui-navigation`
- - `@wpmudev/sui-integration`
-
-
-
- - Collection Components:
-
- - `@wpmudev/sui-footer`
- - `@wpmudev/sui-config-table`
- - `@wpmudev/sui-setup-banner`
- - `@wpmudev/sui-upsell`
- - `@wpmudev/sui-upsell-notice`
-
-
-
-
diff --git a/packages/ui/accordion/CHANGELOG.md b/packages/ui/accordion/CHANGELOG.md
index a138cea53..5fe8c10a8 100644
--- a/packages/ui/accordion/CHANGELOG.md
+++ b/packages/ui/accordion/CHANGELOG.md
@@ -1,5 +1,17 @@
# Change Log
+## 0.0.2
+
+### Patch Changes
+
+- 0784d2c: Updated and improved components used by the Dash plugin
+- Updated dependencies [0784d2c]
+ - @wpmudev/sui-icons@0.0.2
+ - @wpmudev/sui-checkbox@0.0.2
+ - @wpmudev/sui-box@0.0.2
+ - @wpmudev/sui-hooks@0.0.2
+ - @wpmudev/sui-utils@0.0.2
+
## 0.0.1
### Patch Changes
diff --git a/packages/ui/accordion/__tests__/accordion.test.tsx b/packages/ui/accordion/__tests__/accordion.test.tsx
index 37fc4dab1..8ceef29af 100644
--- a/packages/ui/accordion/__tests__/accordion.test.tsx
+++ b/packages/ui/accordion/__tests__/accordion.test.tsx
@@ -5,7 +5,7 @@ import { fireEvent, render, screen } from "@testing-library/react"
import { Accordion, AccordionItem, AccordionItemBody } from "../src"
import { InfoAlt } from "@wpmudev/sui-icons"
-import { a11yTest } from "@wpmudev/sui-utils"
+import { a11yTest } from "@wpmudev/sui-dev-utils"
describe("@wpmudev/sui-accordion", () => {
// Common props for the Accordion component
diff --git a/packages/ui/accordion/package.json b/packages/ui/accordion/package.json
index 9a0dadf12..a3d65da56 100644
--- a/packages/ui/accordion/package.json
+++ b/packages/ui/accordion/package.json
@@ -1,6 +1,6 @@
{
"name": "@wpmudev/sui-accordion",
- "version": "0.0.1",
+ "version": "0.0.2",
"description": "The Accordion component allows users to show and hide the content of related titles on a page.",
"keywords": [],
"author": "WPMU DEV (https://wpmudev.com)",
@@ -58,12 +58,10 @@
"homepage": "https://github.com/wpmudev/sui-docs#readme",
"clean-package": "../../../postpack.config.json",
"dependencies": {
- "@wpmudev/sui-checkbox": "^0.0.1",
- "@wpmudev/sui-icons": "^0.0.1",
- "@wpmudev/sui-utils": "^0.0.1",
- "@wpmudev/sui-hooks": "^0.0.1",
- "@wpmudev/sui-box": "^0.0.1",
- "react-dom": "^18.2.0",
- "react": "^18.2.0"
+ "@wpmudev/sui-checkbox": "^0.0.2",
+ "@wpmudev/sui-icons": "^0.0.2",
+ "@wpmudev/sui-utils": "^0.0.2",
+ "@wpmudev/sui-hooks": "^0.0.2",
+ "@wpmudev/sui-box": "^0.0.2"
}
}
diff --git a/packages/ui/accordion/src/accordion-item.tsx b/packages/ui/accordion/src/accordion-item.tsx
index 0870c0b1b..f7b37d6ba 100644
--- a/packages/ui/accordion/src/accordion-item.tsx
+++ b/packages/ui/accordion/src/accordion-item.tsx
@@ -17,6 +17,7 @@ import { AccordionItemProps } from "./accordion.types"
// The AccordionItem component is defined as a functional component using React.FC.
const AccordionItem: React.FC
= ({
+ id,
title = "{title}",
description,
children,
@@ -40,7 +41,8 @@ const AccordionItem: React.FC = ({
const [isPressed, setIsPressed] = useState(false)
// Custom hook to generate a unique ID for the accordion item.
- const uniqueId = useId()
+ const generatedId = useId()
+ const uniqueId = id || `sui-accordion-${generatedId}`
// Get the "toggle" method and "isCurrentlyExpanded" state from the current AccordionItem
const { toggle, isCurrentlyExpanded } = useAccordion({
@@ -50,8 +52,8 @@ const AccordionItem: React.FC = ({
const { spacing } = useContext(AccordionContext)
// IDs for the accordion and its panel to manage accessibility.
- const accordionId = `sui-accordion-${uniqueId}`
- const accordionPanelId = `sui-accordion-panel-${uniqueId}`
+ const accordionId = `${uniqueId}-header`
+ const accordionPanelId = `${uniqueId}-panel`
const onMouseDownCapture = () => {
setIsPressed(true)
@@ -100,6 +102,7 @@ const AccordionItem: React.FC = ({
// Render the AccordionItem component with proper accessibility attributes.
return (
= ({
>
{hasCheckbox && (
= ({
)}
{/* Content of the accordion item's header */}
-
+
)
diff --git a/packages/ui/accordion/src/accordion.tsx b/packages/ui/accordion/src/accordion.tsx
index 21d876b10..5ef29f049 100644
--- a/packages/ui/accordion/src/accordion.tsx
+++ b/packages/ui/accordion/src/accordion.tsx
@@ -1,5 +1,5 @@
// Import necessary modules and types
-import React, { useState } from "react"
+import React, { useState, useId } from "react"
import { _renderHTMLPropsSafely, generateCN, isEmpty } from "@wpmudev/sui-utils"
import { AccordionProps } from "./accordion.types"
@@ -8,6 +8,7 @@ import { useDefaultChildren, useStyles } from "@wpmudev/sui-hooks"
// Define the Accordion component as a functional component (React.FC)
const Accordion: React.FC
= ({
+ id,
className,
state = "default",
noBorderRadius = false,
@@ -19,6 +20,8 @@ const Accordion: React.FC = ({
_htmlProps = {},
_style = {},
}) => {
+ const generatedId = useId()
+ const accordionId = id || `sui-accordion-${generatedId}`
const [expandState, setExpandState] = useState>({})
// Default children content
@@ -48,7 +51,11 @@ const Accordion: React.FC = ({
isFlushed,
}}
>
-
+
{children}
diff --git a/packages/ui/accordion/src/accordion.types.ts b/packages/ui/accordion/src/accordion.types.ts
index 6508eac27..71e7d211a 100644
--- a/packages/ui/accordion/src/accordion.types.ts
+++ b/packages/ui/accordion/src/accordion.types.ts
@@ -8,6 +8,7 @@ import { SuiHTMLAttributes, SuiStyleType } from "@wpmudev/sui-utils"
interface AccordionProps
extends SuiHTMLAttributes
>,
SuiStyleType {
+ id?: string // Optional custom ID for the accordion item.
/** Additional CSS class name for styling the accordion component. */
className?: string
/** Remove border-radius when true */
@@ -36,6 +37,7 @@ type AccordionCheckboxProps =
interface AccordionItemBaseProps
extends SuiHTMLAttributes>,
SuiStyleType {
+ id?: string // Optional custom ID for the accordion item.
title?: string // The title of the accordion item.
description?: string // The description of the accordion item.
children?: React.ReactNode // The content of the accordion item, which can be any valid React node.
diff --git a/packages/ui/advanced-banner/CHANGELOG.md b/packages/ui/advanced-banner/CHANGELOG.md
index 22d51acf2..0193160b7 100644
--- a/packages/ui/advanced-banner/CHANGELOG.md
+++ b/packages/ui/advanced-banner/CHANGELOG.md
@@ -1,5 +1,59 @@
# Change Log
+## 0.0.2
+
+### Patch Changes
+
+- 0784d2c: Updated and improved components used by the Dash plugin
+- Updated dependencies [0784d2c]
+ - @wpmudev/sui-button@0.0.2
+ - @wpmudev/sui-utils@0.0.2
+
+## 0.0.4
+
+### Patch Changes
+
+- [#334](https://github.com/wpmudev/sui-react/pull/334)
+ [`de4695f`](https://github.com/wpmudev/sui-react/commit/de4695feb4886a3af66e5c4b51031915907e2490)
+ Thanks [@abder](https://github.com/abder)! - Remove sui react package.
+
+- [#361](https://github.com/wpmudev/sui-react/pull/361)
+ [`a9ead37`](https://github.com/wpmudev/sui-react/commit/a9ead374fd02ebd63882d55bc01ab2fc7375732f)
+ Thanks [@creador-dev](https://github.com/creador-dev)! - Change ids to
+ kebab-case
+
+- Updated dependencies
+ [[`de4695f`](https://github.com/wpmudev/sui-react/commit/de4695feb4886a3af66e5c4b51031915907e2490),
+ [`a9ead37`](https://github.com/wpmudev/sui-react/commit/a9ead374fd02ebd63882d55bc01ab2fc7375732f)]:
+ - @wpmudev/sui-button@0.1.2
+
+## 0.0.3
+
+### Patch Changes
+
+- [#358](https://github.com/wpmudev/sui-react/pull/358)
+ [`a98b0db`](https://github.com/wpmudev/sui-react/commit/a98b0dbed76c7d20abae0d027524a4281ca66028)
+ Thanks [@creador-dev](https://github.com/creador-dev)! - Added missing ids to
+ components
+
+- Updated dependencies
+ [[`a98b0db`](https://github.com/wpmudev/sui-react/commit/a98b0dbed76c7d20abae0d027524a4281ca66028)]:
+ - @wpmudev/sui-button@0.1.1
+
+## 0.0.2
+
+### Patch Changes
+
+- [#307](https://github.com/wpmudev/sui-react/pull/307)
+ [`190911a`](https://github.com/wpmudev/sui-react/commit/190911aac575eb4748915b31403d00e6bf03003d)
+ Thanks [@emgk](https://github.com/emgk)! - Update SUI for wpmudev-dashboard 5
+
+- Updated dependencies
+ [[`334ea9e`](https://github.com/wpmudev/sui-react/commit/334ea9e237fee28bf3fa3c6671f7a2a0bd5ea0a8),
+ [`190911a`](https://github.com/wpmudev/sui-react/commit/190911aac575eb4748915b31403d00e6bf03003d)]:
+ - @wpmudev/sui-utils@1.0.0
+ - @wpmudev/sui-button@0.1.0
+
## 0.0.1
### Patch Changes
diff --git a/packages/ui/advanced-banner/__tests__/advanced-banner.test.tsx b/packages/ui/advanced-banner/__tests__/advanced-banner.test.tsx
index 6fe272767..2ddf32410 100644
--- a/packages/ui/advanced-banner/__tests__/advanced-banner.test.tsx
+++ b/packages/ui/advanced-banner/__tests__/advanced-banner.test.tsx
@@ -4,7 +4,7 @@ import { render, screen } from "@testing-library/react"
import { AdvancedBanner } from "../src"
-import { a11yTest } from "@wpmudev/sui-utils"
+import { a11yTest } from "@wpmudev/sui-dev-utils"
describe("@wpmudev/sui-advanced-banner", () => {
it("render correctly", () => {
diff --git a/packages/ui/advanced-banner/package.json b/packages/ui/advanced-banner/package.json
index a11bc78dd..83ee5deb1 100644
--- a/packages/ui/advanced-banner/package.json
+++ b/packages/ui/advanced-banner/package.json
@@ -1,6 +1,6 @@
{
"name": "@wpmudev/sui-advanced-banner",
- "version": "0.0.1",
+ "version": "0.0.2",
"description": "The Advanced Banner component is designed to be used for promoting special deals and offers.",
"keywords": [],
"author": "WPMU DEV (https://wpmudev.com)",
@@ -53,8 +53,7 @@
"homepage": "https://github.com/wpmudev/sui-docs#readme",
"clean-package": "../../../postpack.config.json",
"dependencies": {
- "@wpmudev/sui-button": "^0.0.1",
- "@wpmudev/sui-utils": "^0.0.1",
- "react": "^18.2.0"
+ "@wpmudev/sui-button": "^0.0.2",
+ "@wpmudev/sui-utils": "^0.0.2"
}
}
diff --git a/packages/ui/advanced-banner/src/advanced-banner.tsx b/packages/ui/advanced-banner/src/advanced-banner.tsx
index 980bbcc3b..ccd6ff180 100644
--- a/packages/ui/advanced-banner/src/advanced-banner.tsx
+++ b/packages/ui/advanced-banner/src/advanced-banner.tsx
@@ -1,4 +1,4 @@
-import React from "react"
+import React, { useId } from "react"
import { _renderHTMLPropsSafely, generateCN, isEmpty } from "@wpmudev/sui-utils"
import { Button, ButtonProps } from "@wpmudev/sui-button"
@@ -7,6 +7,7 @@ import { useStyles } from "@wpmudev/sui-hooks"
// Build "advanced-banner" component
const AdvancedBanner: React.FC = ({
+ id,
variation = "plugin",
imageUrl = "https://placehold.co/100",
title = "Banner Title",
@@ -23,6 +24,8 @@ const AdvancedBanner: React.FC = ({
_htmlProps = {},
_style = {},
}) => {
+ const generatedId = useId()
+ const advancedBannerId = id || `sui-advanced-banner-${generatedId}`
const { suiInlineClassname } = useStyles(_style, className)
// Define class name
@@ -43,6 +46,7 @@ const AdvancedBanner: React.FC = ({
return (
>,
SuiStyleType {
+ /**
+ * Unique identifier for the advanced banner.
+ */
+ id?: string
/**
* Sets the headline text
*/
diff --git a/packages/ui/alert-banner/CHANGELOG.md b/packages/ui/alert-banner/CHANGELOG.md
index 6adb8f75d..dafc03ed1 100644
--- a/packages/ui/alert-banner/CHANGELOG.md
+++ b/packages/ui/alert-banner/CHANGELOG.md
@@ -1,5 +1,15 @@
# Change Log
+## 0.0.2
+
+### Patch Changes
+
+- 0784d2c: Updated and improved components used by the Dash plugin
+- Updated dependencies [0784d2c]
+ - @wpmudev/sui-icons@0.0.2
+ - @wpmudev/sui-button@0.0.2
+ - @wpmudev/sui-utils@0.0.2
+
## 0.0.1
### Patch Changes
diff --git a/packages/ui/alert-banner/__tests__/alert-banner.test.tsx b/packages/ui/alert-banner/__tests__/alert-banner.test.tsx
index 6e7ce6e0e..d5f626504 100644
--- a/packages/ui/alert-banner/__tests__/alert-banner.test.tsx
+++ b/packages/ui/alert-banner/__tests__/alert-banner.test.tsx
@@ -1,7 +1,7 @@
import React from "react"
import "@testing-library/jest-dom"
import { render, screen } from "@testing-library/react"
-import { a11yTest } from "@wpmudev/sui-utils"
+import { a11yTest } from "@wpmudev/sui-dev-utils"
import { AlertBanner } from "../src"
diff --git a/packages/ui/alert-banner/package.json b/packages/ui/alert-banner/package.json
index 5b1e55c62..523962487 100644
--- a/packages/ui/alert-banner/package.json
+++ b/packages/ui/alert-banner/package.json
@@ -1,6 +1,6 @@
{
"name": "@wpmudev/sui-alert-banner",
- "version": "0.0.1",
+ "version": "0.0.2",
"description": "Alert banners are used to display critical notifications such as system alarms. They should be noticeable and encourage users to act.",
"keywords": [],
"author": "WPMU DEV (https://wpmudev.com)",
@@ -49,9 +49,8 @@
"homepage": "https://github.com/wpmudev/sui-react#readme",
"clean-package": "../../../postpack.config.json",
"dependencies": {
- "@wpmudev/sui-button": "^0.0.1",
- "@wpmudev/sui-utils": "^0.0.1",
- "@wpmudev/sui-icons": "^0.0.1",
- "react": "^18.2.0"
+ "@wpmudev/sui-button": "^0.0.2",
+ "@wpmudev/sui-utils": "^0.0.2",
+ "@wpmudev/sui-icons": "^0.0.2"
}
}
diff --git a/packages/ui/alert-banner/src/alert-banner.tsx b/packages/ui/alert-banner/src/alert-banner.tsx
index 898b53c3a..58c1f1f7f 100644
--- a/packages/ui/alert-banner/src/alert-banner.tsx
+++ b/packages/ui/alert-banner/src/alert-banner.tsx
@@ -1,4 +1,4 @@
-import React, { useState, useCallback } from "react"
+import React, { useId, useState, useCallback } from "react"
import { _renderHTMLPropsSafely, generateCN, isEmpty } from "@wpmudev/sui-utils"
import { Button, ButtonProps } from "@wpmudev/sui-button"
import Icons from "@wpmudev/sui-icons"
@@ -7,16 +7,20 @@ import { useDefaultChildren, useStyles } from "@wpmudev/sui-hooks"
import { AlertBannerProps } from "./alert-banner.types"
const AlertBanner: React.FC
= ({
+ id,
children,
variation = "informative",
actions,
displayIcon = true,
isCenter = false,
+ isContentFluid = false,
isDismissible = true,
onDismiss = () => {},
_style = {},
_htmlProps,
}) => {
+ const generatedId = useId()
+ const alertBannerId = id || `sui-alert-banner-${generatedId}`
// State to control the visibility of the alert banner
const [isVisible, setIsVisible] = useState(true)
@@ -42,6 +46,7 @@ const AlertBanner: React.FC = ({
"sui-alert-banner",
{
[variation as string]: !isEmpty(variation ?? ""),
+ fluid: isContentFluid,
},
suiInlineClassname,
)
@@ -83,12 +88,16 @@ const AlertBanner: React.FC = ({
return (
{/* Render the Icon if available and displayIcon is true */}
@@ -100,7 +109,7 @@ const AlertBanner: React.FC
= ({
)}
- {children}
+
{children}
{/* Render actions if provided */}
{actions && (
diff --git a/packages/ui/alert-banner/src/alert-banner.types.ts b/packages/ui/alert-banner/src/alert-banner.types.ts
index 0315263f7..0d7c738e4 100644
--- a/packages/ui/alert-banner/src/alert-banner.types.ts
+++ b/packages/ui/alert-banner/src/alert-banner.types.ts
@@ -8,6 +8,10 @@ import { SuiHTMLAttributes, SuiStyleType } from "@wpmudev/sui-utils"
interface AlertBannerProps
extends SuiStyleType,
SuiHTMLAttributes
> {
+ /**
+ * Unique identifier for the alert banner.
+ */
+ id?: string
/**
* Alert Banner content
*/
@@ -28,6 +32,11 @@ interface AlertBannerProps
*/
isDismissible?: boolean
+ /**
+ * Whether make alert banner content fluid or not
+ */
+ isContentFluid?: boolean
+
/**
* Callback function when dismiss the banner
*/
diff --git a/packages/ui/alert-banner/stories/alert-banner.stories.tsx b/packages/ui/alert-banner/stories/alert-banner.stories.tsx
index 95d01077c..ccac38bd0 100644
--- a/packages/ui/alert-banner/stories/alert-banner.stories.tsx
+++ b/packages/ui/alert-banner/stories/alert-banner.stories.tsx
@@ -70,6 +70,7 @@ AlertBanner.args = {
variation: "informative",
displayIcon: true,
isDismissible: true,
+ isContentFluid: false,
}
AlertBanner.argTypes = {
@@ -107,4 +108,10 @@ AlertBanner.argTypes = {
type: "boolean",
},
},
+ isContentFluid: {
+ name: "Is Content Fluid",
+ control: {
+ type: "boolean",
+ },
+ },
}
diff --git a/packages/ui/avatar/CHANGELOG.md b/packages/ui/avatar/CHANGELOG.md
index eaca1e528..10e015fb4 100644
--- a/packages/ui/avatar/CHANGELOG.md
+++ b/packages/ui/avatar/CHANGELOG.md
@@ -1,5 +1,52 @@
# Change Log
+## 0.0.2
+
+### Patch Changes
+
+- 0784d2c: Updated and improved components used by the Dash plugin
+- Updated dependencies [0784d2c]
+ - @wpmudev/sui-utils@0.0.2
+
+## 0.0.4
+
+### Patch Changes
+
+- [#313](https://github.com/wpmudev/sui-react/pull/313)
+ [`0a9e7dd`](https://github.com/wpmudev/sui-react/commit/0a9e7dda13f63ed410df711027ef032d05a41654)
+ Thanks [@creador-dev](https://github.com/creador-dev)! - Update colors
+
+- [#334](https://github.com/wpmudev/sui-react/pull/334)
+ [`de4695f`](https://github.com/wpmudev/sui-react/commit/de4695feb4886a3af66e5c4b51031915907e2490)
+ Thanks [@abder](https://github.com/abder)! - Remove sui react package.
+
+- [#361](https://github.com/wpmudev/sui-react/pull/361)
+ [`a9ead37`](https://github.com/wpmudev/sui-react/commit/a9ead374fd02ebd63882d55bc01ab2fc7375732f)
+ Thanks [@creador-dev](https://github.com/creador-dev)! - Change ids to
+ kebab-case
+
+## 0.0.3
+
+### Patch Changes
+
+- [#358](https://github.com/wpmudev/sui-react/pull/358)
+ [`a98b0db`](https://github.com/wpmudev/sui-react/commit/a98b0dbed76c7d20abae0d027524a4281ca66028)
+ Thanks [@creador-dev](https://github.com/creador-dev)! - Added missing ids to
+ components
+
+## 0.0.2
+
+### Patch Changes
+
+- [#307](https://github.com/wpmudev/sui-react/pull/307)
+ [`190911a`](https://github.com/wpmudev/sui-react/commit/190911aac575eb4748915b31403d00e6bf03003d)
+ Thanks [@emgk](https://github.com/emgk)! - Update SUI for wpmudev-dashboard 5
+
+- Updated dependencies
+ [[`334ea9e`](https://github.com/wpmudev/sui-react/commit/334ea9e237fee28bf3fa3c6671f7a2a0bd5ea0a8),
+ [`190911a`](https://github.com/wpmudev/sui-react/commit/190911aac575eb4748915b31403d00e6bf03003d)]:
+ - @wpmudev/sui-utils@1.0.0
+
## 0.0.1
### Patch Changes
diff --git a/packages/ui/avatar/__tests__/avatar.test.tsx b/packages/ui/avatar/__tests__/avatar.test.tsx
index 125f50af1..0b16b0b30 100644
--- a/packages/ui/avatar/__tests__/avatar.test.tsx
+++ b/packages/ui/avatar/__tests__/avatar.test.tsx
@@ -1,7 +1,7 @@
import React from "react"
import { render, screen } from "@testing-library/react"
import "@testing-library/jest-dom" // This is still needed to extend Jest's expect
-import { a11yTest } from "@wpmudev/sui-utils"
+import { a11yTest } from "@wpmudev/sui-dev-utils"
import { Avatar } from "../src"
describe("@wpmudev/sui-avatar", () => {
diff --git a/packages/ui/avatar/package.json b/packages/ui/avatar/package.json
index dbaff3c4a..a5159bad6 100644
--- a/packages/ui/avatar/package.json
+++ b/packages/ui/avatar/package.json
@@ -1,6 +1,6 @@
{
"name": "@wpmudev/sui-avatar",
- "version": "0.0.1",
+ "version": "0.0.2",
"description": "An avatar is a thumbnail that represents a user or an organization.",
"keywords": [],
"author": "WPMU DEV (https://wpmudev.com)",
@@ -58,7 +58,6 @@
"homepage": "https://github.com/wpmudev/sui-docs#readme",
"clean-package": "../../../postpack.config.json",
"dependencies": {
- "@wpmudev/sui-utils": "^0.0.1",
- "react": "^18.2.0"
+ "@wpmudev/sui-utils": "^0.0.2"
}
}
diff --git a/packages/ui/avatar/src/avatar.tsx b/packages/ui/avatar/src/avatar.tsx
index 789dd3b2c..0d775585d 100644
--- a/packages/ui/avatar/src/avatar.tsx
+++ b/packages/ui/avatar/src/avatar.tsx
@@ -1,4 +1,4 @@
-import React from "react"
+import React, { useId } from "react"
import {
_renderHTMLPropsSafely,
generateCN,
@@ -16,14 +16,19 @@ import { useStyles } from "@wpmudev/sui-hooks"
// Build "avatar" component
const Avatar: React.FC = ({
+ id,
image,
status = "none",
isSmall = false,
className,
+ icon = "UserAlt",
_htmlProps = {},
_style = {},
onClick,
}) => {
+ const generatedId = useId()
+ const avatarId = id || `sui-avatar-${generatedId}`
+
// Define image object
const imageObj = Object.assign(
{
@@ -50,6 +55,7 @@ const Avatar: React.FC = ({
)
const attributes = {
+ id: avatarId,
className: classNames,
..._renderHTMLPropsSafely(_htmlProps),
"data-testid": "avatar",
@@ -58,9 +64,17 @@ const Avatar: React.FC = ({
return (
- {hasImage && }
- {!hasImage && }
- {hasStatus && status !== "none" && }
+ {hasImage && (
+
+ )}
+ {!hasImage && }
+ {hasStatus && status !== "none" && (
+
+ )}
)
}
diff --git a/packages/ui/avatar/src/avatar.types.ts b/packages/ui/avatar/src/avatar.types.ts
index f91b42844..22b057fe7 100644
--- a/packages/ui/avatar/src/avatar.types.ts
+++ b/packages/ui/avatar/src/avatar.types.ts
@@ -1,6 +1,7 @@
import { HTMLProps } from "react"
import { useStylesTypes } from "@wpmudev/sui-hooks"
import { SuiHTMLAttributes, SuiStyleType } from "@wpmudev/sui-utils"
+import { IconsNamesType } from "@wpmudev/sui-icons"
/**
* Represents the properties for an avatar component.
@@ -8,6 +9,10 @@ import { SuiHTMLAttributes, SuiStyleType } from "@wpmudev/sui-utils"
interface AvatarProps
extends SuiHTMLAttributes>,
SuiStyleType {
+ /**
+ * Unique identifier for the avatar.
+ */
+ id?: string
/**
* The image source for the avatar.
*/
@@ -27,6 +32,11 @@ interface AvatarProps
* The CSS class name for the avatar.
*/
className?: string
+
+ /**
+ * The icon for the avatar.
+ */
+ icon?: IconsNamesType
/**
* Callback function when click on avatar
*/
diff --git a/packages/ui/avatar/src/elements/icon-avatar.tsx b/packages/ui/avatar/src/elements/icon-avatar.tsx
index 22be11691..32fe98fc0 100644
--- a/packages/ui/avatar/src/elements/icon-avatar.tsx
+++ b/packages/ui/avatar/src/elements/icon-avatar.tsx
@@ -1,10 +1,13 @@
import React, { Fragment } from "react"
-import { User, UserAlt } from "@wpmudev/sui-icons"
+import Icons, { IconsNamesType, User, UserAlt } from "@wpmudev/sui-icons"
// Build "icon avatar" element
-const Icon = () => (
-
-
-
-)
+const Icon = ({ id, iconName }: { id?: string; iconName: IconsNamesType }) => {
+ const IconTag = Icons?.[iconName as IconsNamesType]
+ return (
+
+
+
+ )
+}
export { Icon }
diff --git a/packages/ui/avatar/src/elements/image-avatar.tsx b/packages/ui/avatar/src/elements/image-avatar.tsx
index 06c745953..7bb565cf0 100644
--- a/packages/ui/avatar/src/elements/image-avatar.tsx
+++ b/packages/ui/avatar/src/elements/image-avatar.tsx
@@ -4,7 +4,7 @@ import { isEmpty, isUndefined } from "@wpmudev/sui-utils"
import { ImageAvatarProps } from "./image-avatar.types"
// Build "image avatar" element
-const Image: React.FC = ({ source, text }) => {
+const Image: React.FC = ({ id, source, text }) => {
// Props validation
const hasSrc = !isUndefined(source) && !isEmpty(source)
const hasAlt = !isUndefined(text) && !isEmpty(text)
@@ -19,12 +19,17 @@ const Image: React.FC = ({ source, text }) => {
return (
-
+
{hasAlt ? text : "Logged in user avatar"}
diff --git a/packages/ui/avatar/src/elements/image-avatar.types.ts b/packages/ui/avatar/src/elements/image-avatar.types.ts
index 697336cc0..0f4565c54 100644
--- a/packages/ui/avatar/src/elements/image-avatar.types.ts
+++ b/packages/ui/avatar/src/elements/image-avatar.types.ts
@@ -2,6 +2,11 @@
* Interface representing the properties of an image avatar.
*/
interface ImageAvatarProps {
+ /**
+ * Optional unique identifier for the image avatar.
+ */
+ id?: string
+
/**
* Source URL of the image for the avatar.
*/
diff --git a/packages/ui/avatar/src/elements/status.tsx b/packages/ui/avatar/src/elements/status.tsx
index da48e3dd6..ea7f697b5 100644
--- a/packages/ui/avatar/src/elements/status.tsx
+++ b/packages/ui/avatar/src/elements/status.tsx
@@ -4,7 +4,7 @@ import { Clock, CheckAlt, Warning } from "@wpmudev/sui-icons"
import { StatusProps } from "./status.types"
// Build "status" element
-const Status: React.FC = ({ status }) => {
+const Status: React.FC = ({ id, status }) => {
// Determine the IconTag based on the provided icon value
let IconName,
classes = "sui-avatar__status-icon"
@@ -28,7 +28,7 @@ const Status: React.FC = ({ status }) => {
case "awaiting":
IconName = Clock
- classes += " sui-color-neutral--60"
+ classes += " sui-color-neutral--50"
break
default:
@@ -38,6 +38,7 @@ const Status: React.FC = ({ status }) => {
// Return element
return (
= ({
+ id,
title = "Box Title",
description,
headerActions,
footerActions,
+ centerFooterActions,
className,
isPro = false,
+ hasBg = true,
+ isFluid = false,
children,
+ hasLargeRadius,
_htmlProps,
_style,
}) => {
+ const generatedId = useId()
+ const basicBoxId = id || `sui-basic-box-${generatedId}`
+
// Interaction methods
const [isHovered, isFocused, methods] = useInteraction({})
@@ -35,32 +43,42 @@ const BasicBox: React.FC = ({
focus: isFocused,
hover: isHovered && !isFocused,
pro: isPro,
+ bg: hasBg,
+ "is-fluid": isFluid,
+ "center-footer-actions": centerFooterActions,
+ "large-radius": hasLargeRadius,
},
suiInlineClassname,
)
return (