@janbox/storefront-ui 3.0.4 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +2 -2
  2. package/dist/lib/accordion/accordion-content/accordion-content.js +1 -1
  3. package/dist/lib/avatar/README.md +1 -1
  4. package/dist/lib/avatar/types.d.ts +2 -2
  5. package/dist/lib/badge/README.md +1 -1
  6. package/dist/lib/badge/types.d.ts +2 -2
  7. package/dist/lib/breadcrumbs/README.md +1 -1
  8. package/dist/lib/breadcrumbs/breadcrumbs/types.d.ts +2 -2
  9. package/dist/lib/button/README.md +1 -1
  10. package/dist/lib/button/button.js +2 -5
  11. package/dist/lib/button/types.d.ts +2 -2
  12. package/dist/lib/checkbox/README.md +1 -1
  13. package/dist/lib/checkbox/types.d.ts +2 -2
  14. package/dist/lib/chip/README.md +1 -1
  15. package/dist/lib/chip/types.d.ts +2 -2
  16. package/dist/lib/icon-button/types.d.ts +2 -2
  17. package/dist/lib/linear-progress/README.md +1 -1
  18. package/dist/lib/linear-progress/types.d.ts +2 -2
  19. package/dist/lib/loading/README.md +1 -1
  20. package/dist/lib/loading/loading-overlay/types.d.ts +2 -2
  21. package/dist/lib/notifications/helpers.d.ts +2 -2
  22. package/dist/lib/price-label/README.md +1 -1
  23. package/dist/lib/price-label/types.d.ts +2 -2
  24. package/dist/lib/radio-button/README.md +1 -1
  25. package/dist/lib/radio-button/types.d.ts +2 -2
  26. package/dist/lib/star-rating/README.md +4 -4
  27. package/dist/lib/star-rating/star-rating.d.ts +1 -1
  28. package/dist/lib/star-rating/star-rating.js +32 -34
  29. package/dist/lib/star-rating/types.d.ts +4 -2
  30. package/dist/lib/swiper/README.md +1 -1
  31. package/dist/lib/swiper/swiper-dots-paging/types.d.ts +2 -2
  32. package/dist/lib/swiper/swiper-side-arrows-paging/types.d.ts +2 -2
  33. package/dist/lib/switch/README.md +1 -1
  34. package/dist/lib/switch/types.d.ts +2 -2
  35. package/dist/lib/tabs/tab-indicator/tab-indicator.js +1 -1
  36. package/dist/lib/textarea/textarea.js +2 -5
  37. package/dist/theme/create-theme.d.ts +26 -0
  38. package/dist/theme/create-theme.js +102 -0
  39. package/dist/theme/index.d.ts +1 -0
  40. package/dist/theme/index.js +3 -0
  41. package/dist/theme/palette.d.ts +4 -12
  42. package/dist/types/index.d.ts +1 -1
  43. package/dist/utils/index.d.ts +3 -3
  44. package/package.json +1 -1
package/README.md CHANGED
@@ -265,7 +265,7 @@ import { ThemeProvider, getColorVar } from '@janbox/storefront-ui/theme';
265
265
  import { useWindowScreen, useControllableState } from '@janbox/storefront-ui/hooks';
266
266
 
267
267
  // Types
268
- import type { SizeVariant, ColorVariant, StyledCSS } from '@janbox/storefront-ui/types';
268
+ import type { SizeVariant, ColorScale, StyledCSS } from '@janbox/storefront-ui/types';
269
269
 
270
270
  // Utils
271
271
  import { cn, formatPrice } from '@janbox/storefront-ui/utils';
@@ -541,7 +541,7 @@ Mọi component đều có README riêng với API reference, examples, và usag
541
541
  type SizeVariant = 'xs' | 'sm' | 'md' | 'lg';
542
542
 
543
543
  // Color variants
544
- type ColorVariant = 'primary' | 'secondary' | 'green' | 'red' | 'orange' | 'blue' | 'neutral';
544
+ type ColorScale = 'primary' | 'secondary' | 'green' | 'red' | 'orange' | 'blue' | 'neutral' | 'yellow' | 'violet';
545
545
 
546
546
  // Button variants
547
547
  type ButtonVariant = 'contained' | 'outlined' | 'text';
@@ -3,8 +3,8 @@ import { useRef } from "react";
3
3
  import { motion } from "motion/react";
4
4
  import { getAccordionContentProps } from "./helpers.js";
5
5
  import { useAccordionContext } from "../accordion/helpers.js";
6
- import { Stylesheet } from "../../stylesheet/stylesheet.js";
7
6
  import { useAccordionGroupContext } from "../accordion-group/helpers.js";
7
+ import { Stylesheet } from "../../stylesheet/stylesheet.js";
8
8
  import { Primitive } from "../../primitive/primitive.js";
9
9
  const AccordionContent = ({ children, ref, ..._props }) => {
10
10
  const { accordionContentProps: accordionContentPropsByGroup = {} } = useAccordionGroupContext();
@@ -15,7 +15,7 @@ import { Avatar } from '@janbox/storefront-ui';
15
15
  | `src` | `string` | - | URL of the avatar image. Falls back to initials if the image fails to load or is not provided. |
16
16
  | `name` | `string` | - | User's full name — used to generate initials for the fallback display and as the alt/aria-label for the image. |
17
17
  | `status` | `'online' \| 'offline' \| 'busy' \| 'away'` | - | Online status indicator shown as a colored dot in the bottom-right corner of the avatar. |
18
- | `color` | `ColorVariant` | `'primary'` | Color variant for the initials fallback background. Uses the 600 shade of the specified color. |
18
+ | `color` | `ColorScale` | `'primary'` | Color variant for the initials fallback background. Uses the 600 shade of the specified color. |
19
19
  | `size` | `number` | `40` | Width and height of the avatar in pixels. Font size and status dot scale proportionally. |
20
20
  | `sm` | `{ size?: number }` | - | Responsive overrides applied at the sm breakpoint (≥768px). |
21
21
  | `md` | `{ size?: number }` | - | Responsive overrides applied at the md breakpoint (≥1280px). |
@@ -1,5 +1,5 @@
1
1
  import { JSX } from 'react';
2
- import { ColorVariant, PropsWithSx, ShallowMerge, ToResponsiveProps } from '../../types';
2
+ import { ColorScale, PropsWithSx, ShallowMerge, ToResponsiveProps } from '../../types';
3
3
  export type AvatarStatus = 'online' | 'offline' | 'busy' | 'away';
4
4
  export type AvatarResponsiveProps = {
5
5
  size?: number;
@@ -13,6 +13,6 @@ export type AvatarProps = PropsWithSx<ShallowMerge<AvatarHTMLProps, ToResponsive
13
13
  /** Shape of the avatar */
14
14
  /** Online status indicator */
15
15
  status?: AvatarStatus;
16
- color?: ColorVariant;
16
+ color?: ColorScale;
17
17
  }>>;
18
18
  export {};
@@ -14,7 +14,7 @@ import { Badge } from '@janbox/storefront-ui';
14
14
  |------|------|---------|-------------|
15
15
  | `children*` | `ReactElement<{ ref?: Ref<Element> }>` | - | The anchor element the badge is positioned relative to. Must be a single React element that accepts a ref. |
16
16
  | `content` | `number \| string` | - | The content displayed inside the badge bubble. When undefined or null, the badge is hidden. |
17
- | `color` | `ColorVariant` | `red` | Color variant for the badge background. Accepts any ColorVariant (`'primary' \| 'secondary' \| 'green' \| 'red' \| 'orange' \| 'blue' \| 'neutral'`). |
17
+ | `color` | `ColorScale` | `red` | Color variant for the badge background. Accepts any ColorScale (`'primary' \| 'secondary' \| 'green' \| 'red' \| 'orange' \| 'blue' \| 'neutral'`). |
18
18
  | `offset` | `number \| { x?: number; y?: number }` | `0` | Fine-tunes the badge position relative to the anchor corner. A number applies the same offset on both axes; an object allows independent x/y control. |
19
19
  | `offsetY` | `number` | - | Legacy vertical offset prop. Prefer using the `offset` prop instead. |
20
20
 
@@ -1,12 +1,12 @@
1
1
  import { ReactElement, Ref } from 'react';
2
- import { ColorVariant } from '../../types';
2
+ import { ColorScale } from '../../types';
3
3
  export type BadgeProps<T extends {
4
4
  ref?: Ref<Element>;
5
5
  } = {
6
6
  ref?: Ref<Element>;
7
7
  }> = {
8
8
  content?: number | string;
9
- color?: ColorVariant;
9
+ color?: ColorScale;
10
10
  offset?: number | {
11
11
  x?: number;
12
12
  y?: number;
@@ -13,7 +13,7 @@ import { Breadcrumbs } from '@janbox/storefront-ui';
13
13
  | Prop | Type | Default | Description |
14
14
  |------|------|---------|-------------|
15
15
  | `separator` | `string \| IconProps` | `'>'` | The separator rendered between each breadcrumb item. Can be a plain string (e.g. `'>'` or `'/'`) or an IconProps object to render an icon. |
16
- | `color` | `ColorVariant` | `'primary'` | Controls the hover color of breadcrumb items. Accepts any ColorVariant: `'primary' \| 'secondary' \| 'green' \| 'red' \| 'orange' \| 'blue' \| 'neutral'`. |
16
+ | `color` | `ColorScale` | `'primary'` | Controls the hover color of breadcrumb items. Accepts any ColorScale: `'primary' \| 'secondary' \| 'green' \| 'red' \| 'orange' \| 'blue' \| 'neutral'`. |
17
17
  | `children` | `React.ReactNode` | - | BreadcrumbItem elements to render as the navigation trail. Flattened automatically to support wrapping in Fragments. |
18
18
  | `BreadcrumbItem.to` | `ReactRouterLinkProps['to']` | - | (BreadcrumbItem prop) The route target passed to react-router Link. |
19
19
  | `BreadcrumbItem.icon` | `IconProps` | - | (BreadcrumbItem prop) An optional icon rendered before the item label. |
@@ -1,9 +1,9 @@
1
1
  import { JSX } from 'react';
2
2
  import { IconProps } from '../../icon';
3
- import { ColorVariant, ShallowMerge } from '../../../types';
3
+ import { ColorScale, ShallowMerge } from '../../../types';
4
4
  type BreadcrumbsSeparator = string | IconProps;
5
5
  export type BreadcrumbsProps = ShallowMerge<JSX.IntrinsicElements['div'], {
6
6
  separator?: BreadcrumbsSeparator;
7
- color?: ColorVariant;
7
+ color?: ColorScale;
8
8
  }>;
9
9
  export {};
@@ -13,7 +13,7 @@ import { Button } from '@janbox/storefront-ui';
13
13
  | Prop | Type | Default | Description |
14
14
  |------|------|---------|-------------|
15
15
  | `variant` | `ButtonVariant` | contained | Visual style variant of the button: 'contained' (filled background), 'outlined' (border only), or 'text' (no background) |
16
- | `color` | `ColorVariant` | primary | Color theme for the button: 'primary', 'secondary', 'green', 'red', 'orange', 'blue', or 'neutral' |
16
+ | `color` | `ColorScale` | primary | Color theme for the button: 'primary', 'secondary', 'green', 'red', 'orange', 'blue', or 'neutral' |
17
17
  | `size` | `ButtonSizeVariant` | md | Size variant: 'sm', 'md', or 'lg' (excludes 'xs'). Controls padding, height, and typography |
18
18
  | `sm` | `ButtonResponsiveProps` | - | Responsive props override for small screens (≥768px) |
19
19
  | `md` | `ButtonResponsiveProps` | - | Responsive props override for medium screens (≥1280px) |
@@ -1,6 +1,5 @@
1
1
  import { jsxs, jsx } from "@emotion/react/jsx-runtime";
2
- import { useRef, Fragment, isValidElement } from "react";
3
- import { useMergeRefs } from "@floating-ui/react";
2
+ import { Fragment, isValidElement } from "react";
4
3
  import { isNil, isString } from "lodash-es";
5
4
  import { useNavigate, createPath } from "react-router";
6
5
  import { getButtonProps, getButtonCssBySize } from "./helpers.js";
@@ -14,8 +13,6 @@ import { RippleEffect } from "../ripple-effect/ripple-effect.js";
14
13
  import { Icon } from "../icon/icon.js";
15
14
  import { Primitive } from "../primitive/primitive.js";
16
15
  const Button = ({ children, ref, ..._props }) => {
17
- const buttonRef = useRef(null);
18
- const mergedRef = useMergeRefs([ref, buttonRef]);
19
16
  const {
20
17
  color,
21
18
  variant,
@@ -141,7 +138,7 @@ const Button = ({ children, ref, ..._props }) => {
141
138
  }
142
139
  }
143
140
  };
144
- return /* @__PURE__ */ jsxs("button", { css, disabled, ...rest, onClick, ref: mergedRef, children: [
141
+ return /* @__PURE__ */ jsxs("button", { css, disabled, ...rest, onClick, ref, children: [
145
142
  prefix,
146
143
  !!startIcon && /* @__PURE__ */ jsx(
147
144
  Icon,
@@ -2,7 +2,7 @@ import { JSX } from 'react';
2
2
  import { RouterNavigateOptions } from 'react-router';
3
3
  import { IconProps } from '../icon';
4
4
  import { LinkProps } from '../link';
5
- import { ButtonVariant, ColorVariant, SizeVariant, ShallowMerge, PropsWithSx, ToResponsiveProps } from '../../types';
5
+ import { ButtonVariant, ColorScale, SizeVariant, ShallowMerge, PropsWithSx, ToResponsiveProps } from '../../types';
6
6
  export type ButtonSizeVariant = Exclude<SizeVariant, 'xs'>;
7
7
  export type ButtonResponsiveProps = {
8
8
  size?: ButtonSizeVariant;
@@ -12,7 +12,7 @@ type ButtonExtendedProps = PropsWithSx<ToResponsiveProps<ButtonResponsiveProps>
12
12
  to?: LinkProps['to'];
13
13
  target?: LinkProps['target'];
14
14
  };
15
- color?: ColorVariant;
15
+ color?: ColorScale;
16
16
  variant?: ButtonVariant;
17
17
  prefix?: React.ReactNode;
18
18
  suffix?: React.ReactNode;
@@ -12,7 +12,7 @@ import { Checkbox } from '@janbox/storefront-ui';
12
12
 
13
13
  | Prop | Type | Default | Description |
14
14
  |------|------|---------|-------------|
15
- | `color` | `ColorVariant` | "primary" | Color variant for the checkbox. Controls the checked/focus color using design tokens. |
15
+ | `color` | `ColorScale` | "primary" | Color variant for the checkbox. Controls the checked/focus color using design tokens. |
16
16
  | `indeterminate` | `boolean` | false | When true, sets the checkbox to an indeterminate state (shows a minus icon). The checked prop is ignored when this is set. See https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/indeterminate |
17
17
  | `containerProps` | `PrimitiveProps<JSX.IntrinsicElements['label']>` | - | Props forwarded to the outer <label> wrapper (Primitive as='label'). Supports sx prop for responsive styling. |
18
18
  | `children` | `React.ReactNode` | - | Label content rendered next to the checkbox. |
@@ -1,8 +1,8 @@
1
1
  import { JSX } from 'react';
2
- import { ColorVariant, ShallowMerge } from '../../types';
2
+ import { ColorScale, ShallowMerge } from '../../types';
3
3
  import { PrimitiveProps } from '../primitive';
4
4
  export type CheckboxProps = PrimitiveProps<ShallowMerge<JSX.IntrinsicElements['input'], {
5
- color?: ColorVariant;
5
+ color?: ColorScale;
6
6
  /**
7
7
  * using this prop will make the checkbox indeterminate
8
8
  * and the checked prop will be ignored
@@ -12,7 +12,7 @@ import { Chip } from '@janbox/storefront-ui';
12
12
 
13
13
  | Prop | Type | Default | Description |
14
14
  |------|------|---------|-------------|
15
- | `color` | `ColorVariant` | `primary` | Color variant controlling the background (light shade) and border/text (main shade). Accepts `'primary' \| 'secondary' \| 'green' \| 'red' \| 'orange' \| 'blue' \| 'neutral'`. |
15
+ | `color` | `ColorScale` | `primary` | Color variant controlling the background (light shade) and border/text (main shade). Accepts `'primary' \| 'secondary' \| 'green' \| 'red' \| 'orange' \| 'blue' \| 'neutral'`. |
16
16
  | `size` | `SizeVariant` | `md` | Base size of the chip controlling height, padding, font size, and border radius. Accepts `'xs' \| 'sm' \| 'md' \| 'lg'`. |
17
17
  | `sm` | `ChipResponsiveProps` | - | Responsive size override applied at the sm breakpoint (768px+). Accepts `{ size?: SizeVariant }`. |
18
18
  | `md` | `ChipResponsiveProps` | - | Responsive size override applied at the md breakpoint (1280px+). Accepts `{ size?: SizeVariant }`. |
@@ -1,11 +1,11 @@
1
1
  import { JSX } from 'react';
2
- import { ColorVariant, ShallowMerge, SizeVariant, ToResponsiveProps } from '../../types';
2
+ import { ColorScale, ShallowMerge, SizeVariant, ToResponsiveProps } from '../../types';
3
3
  import { PrimitiveProps } from '../primitive';
4
4
  export interface ChipResponsiveProps {
5
5
  size?: SizeVariant;
6
6
  }
7
7
  type ChipExtendedProps = ToResponsiveProps<ChipResponsiveProps> & {
8
- color?: ColorVariant;
8
+ color?: ColorScale;
9
9
  };
10
10
  export type ChipProps = PrimitiveProps<ShallowMerge<JSX.IntrinsicElements['div'], ChipExtendedProps>>;
11
11
  export {};
@@ -1,11 +1,11 @@
1
1
  import { JSX } from 'react';
2
2
  import { IconProps } from '../icon';
3
- import { ButtonVariant, ColorVariant, SizeVariant, ShallowMerge, PropsWithSx, ToResponsiveProps } from '../../types';
3
+ import { ButtonVariant, ColorScale, SizeVariant, ShallowMerge, PropsWithSx, ToResponsiveProps } from '../../types';
4
4
  export type IconButtonResponsiveProps = {
5
5
  size?: SizeVariant;
6
6
  };
7
7
  type IconButtonExtendedProps = PropsWithSx<ToResponsiveProps<IconButtonResponsiveProps> & {
8
- color?: ColorVariant;
8
+ color?: ColorScale;
9
9
  variant?: ButtonVariant;
10
10
  icon?: IconProps;
11
11
  isLoading?: boolean;
@@ -14,7 +14,7 @@ import { LinearProgress } from '@janbox/storefront-ui';
14
14
  |------|------|---------|-------------|
15
15
  | `value` | `number` | - | Progress value as a percentage (0–100). When omitted, the component falls back to indeterminate mode automatically. |
16
16
  | `variant` | `'determinate' \| 'indeterminate'` | - | Explicitly set the progress mode. If not provided, inferred from whether `value` is set: defined value → determinate, undefined value → indeterminate. |
17
- | `color` | `ColorVariant` | `primary` | Color theme of the progress bar. Accepts any ColorVariant token: `'primary' \| 'secondary' \| 'green' \| 'red' \| 'orange' \| 'blue' \| 'neutral'`. |
17
+ | `color` | `ColorScale` | `primary` | Color theme of the progress bar. Accepts any ColorScale token: `'primary' \| 'secondary' \| 'green' \| 'red' \| 'orange' \| 'blue' \| 'neutral'`. |
18
18
  | `size` | `number` | `4` | Height of the progress bar in pixels. Border-radius is automatically set to `size/2` to keep pill shape. |
19
19
  | `sm` | `LinearProgressResponsiveProps` | - | Responsive overrides at the `sm` breakpoint (≥768px). Accepts `{ size?: number }`. |
20
20
  | `md` | `LinearProgressResponsiveProps` | - | Responsive overrides at the `md` breakpoint (≥1280px). Accepts `{ size?: number }`. |
@@ -1,5 +1,5 @@
1
1
  import { JSX } from 'react';
2
- import { ColorVariant, ShallowMerge, ToResponsiveProps } from '../../types';
2
+ import { ColorScale, ShallowMerge, ToResponsiveProps } from '../../types';
3
3
  export type LinearProgressResponsiveProps = {
4
4
  size?: number;
5
5
  };
@@ -7,7 +7,7 @@ type LinearProgressExtendedProps = ToResponsiveProps<LinearProgressResponsivePro
7
7
  duration?: number;
8
8
  value?: number;
9
9
  variant?: 'determinate' | 'indeterminate';
10
- color?: ColorVariant;
10
+ color?: ColorScale;
11
11
  };
12
12
  export type LinearProgressProps = ShallowMerge<JSX.IntrinsicElements['div'], LinearProgressExtendedProps>;
13
13
  export {};
@@ -14,7 +14,7 @@ import { LoadingOverlay } from '@janbox/storefront-ui';
14
14
  |------|------|---------|-------------|
15
15
  | `isLoading` | `boolean` | false | Controls whether the loading overlay spinner is visible over the content. |
16
16
  | `size` | `number` | 32 | Size in pixels for the spinning loader icon and minimum dimensions of the container. |
17
- | `color` | `ColorVariant` | 'primary' | Color variant for the spinning loader icon. Accepts 'primary' | 'secondary' | 'green' | 'red' | 'orange' | 'blue' | 'neutral'. |
17
+ | `color` | `ColorScale` | 'primary' | Color variant for the spinning loader icon. Accepts 'primary' | 'secondary' | 'green' | 'red' | 'orange' | 'blue' | 'neutral'. |
18
18
  | `iconProps` | `PrimitiveProps<JSX.IntrinsicElements['div']>` | - | Additional props passed to the overlay container div that wraps the spinner icon. |
19
19
  | `children` | `React.ReactNode` | - | Content rendered beneath the overlay. Visible when isLoading is false; obscured by the spinner when isLoading is true. |
20
20
  | `sx` | `ToResponsiveProps<StyledCSS>` | - | Responsive style overrides via the sx prop, inherited from PrimitiveProps. |
@@ -1,9 +1,9 @@
1
1
  import { JSX } from 'react';
2
- import { ColorVariant, PropsWithSx, ShallowMerge } from '../../../types';
2
+ import { ColorScale, PropsWithSx, ShallowMerge } from '../../../types';
3
3
  import { PrimitiveProps } from '../../primitive';
4
4
  export type LoadingOverlayProps = ShallowMerge<PrimitiveProps<JSX.IntrinsicElements['div']>, PropsWithSx<{
5
5
  isLoading?: boolean;
6
6
  size?: number;
7
- color?: ColorVariant;
7
+ color?: ColorScale;
8
8
  iconProps?: PrimitiveProps<JSX.IntrinsicElements['div']>;
9
9
  }>>;
@@ -1,9 +1,9 @@
1
- import { ColorVariant } from '../../types';
1
+ import { ColorScale } from '../../types';
2
2
  export type NotificationEntry = {
3
3
  id: string;
4
4
  title: React.ReactNode;
5
5
  message?: React.ReactNode;
6
- color: ColorVariant;
6
+ color: ColorScale;
7
7
  duration?: number;
8
8
  align?: 'left' | 'center' | 'right';
9
9
  };
@@ -22,7 +22,7 @@ import { PriceLabel } from '@janbox/storefront-ui';
22
22
  | `exchangePrice` | `PriceLabelEntry` | - | Optional secondary/exchange price displayed below (vertical) or beside (horizontal) the primary price. |
23
23
  | `priceProps` | `PrimitiveProps<JSX.IntrinsicElements['span']>` | - | Additional props forwarded to the primary price span element, including sx for style overrides. |
24
24
  | `exchangePriceProps` | `PrimitiveProps<JSX.IntrinsicElements['span']>` | - | Additional props forwarded to the exchange price span element, including sx for style overrides. |
25
- | `color` | `ColorVariant` | `neutral` | Color variant used for the price text. Primary price uses the 600 shade, exchange price uses the 500 shade. |
25
+ | `color` | `ColorScale` | `neutral` | Color variant used for the price text. Primary price uses the 600 shade, exchange price uses the 500 shade. |
26
26
  | `orientation` | `'horizontal' \| 'vertical'` | `vertical` | Layout direction of the primary and exchange prices. Vertical stacks them with a line break; horizontal places them side by side. |
27
27
  | `showEqual` | `boolean` | `false` | When true, shows the exchange price even if it is equal to the primary price (same currency and value). |
28
28
  | `size` | `TypographySizeVariant` | `sm` | Typography size for the primary price. Accepts responsive values via sm/md/lg breakpoint props. Exchange price automatically uses one size smaller. |
@@ -1,6 +1,6 @@
1
1
  import { JSX } from 'react';
2
2
  import { TypographySizeVariant } from '../../theme';
3
- import { ColorVariant, ShallowMerge, ToResponsiveProps } from '../../types';
3
+ import { ColorScale, ShallowMerge, ToResponsiveProps } from '../../types';
4
4
  import { PrimitiveProps } from '../primitive';
5
5
  export type PriceLabelEntry = {
6
6
  currency?: string;
@@ -18,7 +18,7 @@ type PriceLabelExtendedProps = ToResponsiveProps<PriceLabelResponsiveProps> & {
18
18
  priceProps?: PrimitiveProps<JSX.IntrinsicElements['span']>;
19
19
  exchangePrice?: PriceLabelEntry;
20
20
  exchangePriceProps?: PrimitiveProps<JSX.IntrinsicElements['span']>;
21
- color?: ColorVariant;
21
+ color?: ColorScale;
22
22
  orientation?: 'horizontal' | 'vertical';
23
23
  showEqual?: boolean;
24
24
  };
@@ -12,7 +12,7 @@ import { RadioButton } from '@janbox/storefront-ui';
12
12
 
13
13
  | Prop | Type | Default | Description |
14
14
  |------|------|---------|-------------|
15
- | `color` | `ColorVariant` | `'primary'` | Điều khiển màu accent của radio button. Map tới design token color shades qua getColorShadesByVariant. |
15
+ | `color` | `ColorScale` | `'primary'` | Điều khiển màu accent của radio button. Map tới design token color shades qua getColorShadesByVariant. |
16
16
  | `containerProps` | `PrimitiveProps<JSX.IntrinsicElements['label']>` | - | Props được forward tới outer label element (Primitive as='label'). Hỗ trợ sx cho responsive styles và tất cả standard label HTML attributes. |
17
17
  | `children` | `React.ReactNode` | - | Nội dung label được render bên cạnh radio button checkmark. |
18
18
  | `className` | `string` | - | CSS class names bổ sung được apply vào inner input element. |
@@ -1,8 +1,8 @@
1
1
  import { JSX } from 'react';
2
- import { ColorVariant, ShallowMerge } from '../../types';
2
+ import { ColorScale, ShallowMerge } from '../../types';
3
3
  import { PrimitiveProps } from '../primitive';
4
4
  interface RadioButtonExtendedProps {
5
- color?: ColorVariant;
5
+ color?: ColorScale;
6
6
  containerProps?: PrimitiveProps<JSX.IntrinsicElements['label']>;
7
7
  }
8
8
  export type RadioButtonProps = ShallowMerge<JSX.IntrinsicElements['input'], RadioButtonExtendedProps>;
@@ -15,7 +15,7 @@ import { StarRating } from '@janbox/storefront-ui';
15
15
  | `rating*` | `number` | - | Giá trị rating hiện tại. Kiểm soát mức độ tô màu ngôi sao qua clip-path. Hỗ trợ giá trị thập phân (VD: 2.5). |
16
16
  | `maxRating` | `number` | 5 | Giá trị rating tối đa. Dùng để tính phần trăm tô màu của ngôi sao. |
17
17
  | `size` | `number` | 24 | Chiều rộng và chiều cao của SVG tính bằng pixel. ViewBox nội bộ luôn là 24x24 nên giá trị này scale output. |
18
- | `colorVariant` | `ColorVariant` | `"secondary"` | Color variant dùng cho cả stroke và fill của ngôi sao. Ánh xạ tới design token color shades qua `getColorShadesByVariant`. |
18
+ | `color` | `ColorScale` | `"secondary"` | Color variant dùng cho cả stroke và fill của ngôi sao. Ánh xạ tới design token color shades qua `getColorShadesByVariant`. |
19
19
  | `className` | `string` | - | CSS class name tùy chọn áp dụng lên root SVG element. |
20
20
 
21
21
  *Props bắt buộc
@@ -37,7 +37,7 @@ import { StarRating } from '@janbox/storefront-ui';
37
37
  ### Max rating tùy chỉnh và color variant
38
38
 
39
39
  ```tsx
40
- <StarRating rating={7} maxRating={10} colorVariant="primary" />
40
+ <StarRating rating={7} maxRating={10} color="primary" />
41
41
  ```
42
42
 
43
43
  ### Ngôi sao đầy và rỗng
@@ -56,9 +56,9 @@ import { StarRating } from '@janbox/storefront-ui';
56
56
 
57
57
  ## Dependencies
58
58
 
59
- - react (forwardRef, useId)
59
+ - react (useId)
60
60
  - @/utils (getColorShadesByVariant)
61
- - @/types (ColorVariant)
61
+ - @/types (ColorScale)
62
62
 
63
63
  ## See Also
64
64
 
@@ -1,2 +1,2 @@
1
1
  import { StarRatingProps } from './types';
2
- export declare const StarRating: import('react').ForwardRefExoticComponent<StarRatingProps & import('react').RefAttributes<SVGSVGElement>>;
2
+ export declare const StarRating: ({ rating, maxRating, size, ref, color }: StarRatingProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,39 +1,37 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
- import { forwardRef, useId } from "react";
2
+ import { useId } from "react";
3
3
  import { getColorShadesByVariant } from "../../utils/index.js";
4
- const StarRating = forwardRef(
5
- ({ rating, maxRating = 5, size = 24, colorVariant = "secondary" }, ref) => {
6
- const id = useId();
7
- const percent = rating / maxRating * 24;
8
- const { main } = getColorShadesByVariant(colorVariant);
9
- return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", ref, children: [
10
- /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("clipPath", { id, children: /* @__PURE__ */ jsx("rect", { x: "0", y: "0", width: percent, height: 24 }) }) }),
11
- /* @__PURE__ */ jsx(
12
- "path",
13
- {
14
- d: "M12 2.89648L14.935 8.88948L21.5 9.85648L16.75 14.5185L17.871 21.1045L12 17.9935L6.129 21.1045L7.25 14.5185L2.5 9.85648L9.064 8.88948L12 2.89648Z",
15
- fill: "white",
16
- stroke: main,
17
- strokeWidth: "1.5",
18
- strokeLinecap: "round",
19
- strokeLinejoin: "round"
20
- }
21
- ),
22
- /* @__PURE__ */ jsx(
23
- "path",
24
- {
25
- d: "M12 2.89648L14.935 8.88948L21.5 9.85648L16.75 14.5185L17.871 21.1045L12 17.9935L6.129 21.1045L7.25 14.5185L2.5 9.85648L9.064 8.88948L12 2.89648Z",
26
- fill: main,
27
- clipPath: `url(#${id})`,
28
- strokeLinecap: "round",
29
- strokeLinejoin: "round",
30
- strokeWidth: "1.5",
31
- stroke: main
32
- }
33
- )
34
- ] });
35
- }
36
- );
4
+ const StarRating = ({ rating, maxRating = 5, size = 24, ref, color = "primary" }) => {
5
+ const id = useId();
6
+ const percent = rating / maxRating * 24;
7
+ const { main } = getColorShadesByVariant(color);
8
+ return /* @__PURE__ */ jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", ref, children: [
9
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("clipPath", { id, children: /* @__PURE__ */ jsx("rect", { x: "0", y: "0", width: percent, height: 24 }) }) }),
10
+ /* @__PURE__ */ jsx(
11
+ "path",
12
+ {
13
+ d: "M12 2.89648L14.935 8.88948L21.5 9.85648L16.75 14.5185L17.871 21.1045L12 17.9935L6.129 21.1045L7.25 14.5185L2.5 9.85648L9.064 8.88948L12 2.89648Z",
14
+ fill: "white",
15
+ stroke: main,
16
+ strokeWidth: "1.5",
17
+ strokeLinecap: "round",
18
+ strokeLinejoin: "round"
19
+ }
20
+ ),
21
+ /* @__PURE__ */ jsx(
22
+ "path",
23
+ {
24
+ d: "M12 2.89648L14.935 8.88948L21.5 9.85648L16.75 14.5185L17.871 21.1045L12 17.9935L6.129 21.1045L7.25 14.5185L2.5 9.85648L9.064 8.88948L12 2.89648Z",
25
+ fill: main,
26
+ clipPath: `url(#${id})`,
27
+ strokeLinecap: "round",
28
+ strokeLinejoin: "round",
29
+ strokeWidth: "1.5",
30
+ stroke: main
31
+ }
32
+ )
33
+ ] });
34
+ };
37
35
  export {
38
36
  StarRating
39
37
  };
@@ -1,8 +1,10 @@
1
- import { ColorVariant } from '../../types';
1
+ import { ColorScale } from '../../types';
2
+ import { Ref } from 'react';
2
3
  export type StarRatingProps = {
3
4
  rating: number;
4
5
  maxRating?: number;
5
6
  size?: number;
6
7
  className?: string;
7
- colorVariant?: ColorVariant;
8
+ color?: ColorScale;
9
+ ref?: Ref<SVGSVGElement>;
8
10
  };
@@ -20,7 +20,7 @@ import { Swiper } from '@janbox/storefront-ui';
20
20
  | `lg` | `{ slidesPerView?: number \| 'auto'; spaceBetween?: number }` | - | Override `slidesPerView` và `spaceBetween` tại breakpoint lg (≥1680px). |
21
21
  | `autoplayOptions` | `ShallowMerge<AutoplayOptionsType, { delay?: number }>` | `{ active: false, delay: 3000, stopOnFocusIn: false, stopOnInteraction: false, stopOnLastSnap: false }` | Embla Carousel Autoplay plugin options. Autoplay mặc định không kích hoạt. |
22
22
  | `options` | `Partial<SwiperOptions>` | - | Raw Embla Carousel options (e.g. `loop`, `axis`, `align`). Truyền thẳng vào `useEmblaCarousel`. Default `align` là `'start'`. |
23
- | `paging` | `{ type: 'dots'; color?: ColorVariant; size?: number; spaceBetween?: number; offset?: number } \| { type: 'side-arrows'; color?: ColorVariant; visibility?: 'auto' \| 'always'; anchorSelector?: string; size?: number; offsetX?: number \| 'center'; offsetY?: number \| 'center' }` | - | Cấu hình paging control. Dùng `'dots'` cho dải chấm tròn bên dưới slides, hoặc `'side-arrows'` cho nút prev/next ở hai bên. |
23
+ | `paging` | `{ type: 'dots'; color?: ColorScale; size?: number; spaceBetween?: number; offset?: number } \| { type: 'side-arrows'; color?: ColorScale; visibility?: 'auto' \| 'always'; anchorSelector?: string; size?: number; offsetX?: number \| 'center'; offsetY?: number \| 'center' }` | - | Cấu hình paging control. Dùng `'dots'` cho dải chấm tròn bên dưới slides, hoặc `'side-arrows'` cho nút prev/next ở hai bên. |
24
24
  | `onApi` | `(api: EmblaCarouselType) => void` | - | Callback khi Embla Carousel API instance sẵn sàng, cho phép truy cập trực tiếp các carousel methods. |
25
25
  | `sx` | `ToResponsiveProps<StyledCSS>` | - | Responsive style overrides áp dụng lên root container của swiper. |
26
26
  | `ref` | `React.Ref<HTMLDivElement>` | - | Forwarded ref đến root container element (cũng được forward vào Embla's ref). |
@@ -1,4 +1,4 @@
1
- import { ColorVariant, ToResponsiveProps } from '../../../types';
1
+ import { ColorScale, ToResponsiveProps } from '../../../types';
2
2
  import { SwiperApi } from '../swiper/types';
3
3
  export type SwiperDotsPagingResponsiveProps = {
4
4
  size?: number;
@@ -7,5 +7,5 @@ export type SwiperDotsPagingResponsiveProps = {
7
7
  };
8
8
  export type SwiperDotsPagingProps = {
9
9
  api: SwiperApi;
10
- color?: ColorVariant;
10
+ color?: ColorScale;
11
11
  } & ToResponsiveProps<SwiperDotsPagingResponsiveProps>;
@@ -1,4 +1,4 @@
1
- import { ColorVariant, ToResponsiveProps } from '../../../types';
1
+ import { ColorScale, ToResponsiveProps } from '../../../types';
2
2
  import { SwiperApi } from '../swiper/types';
3
3
  export type SwiperSideArrowsPagingResponsiveProps = {
4
4
  size?: number;
@@ -8,7 +8,7 @@ export type SwiperSideArrowsPagingResponsiveProps = {
8
8
  export type SwiperSideArrowsPagingVisibility = 'auto' | 'always';
9
9
  export type SwiperSideArrowsPagingProps = {
10
10
  api: SwiperApi;
11
- color?: ColorVariant;
11
+ color?: ColorScale;
12
12
  visibility?: SwiperSideArrowsPagingVisibility;
13
13
  anchorSelector?: string;
14
14
  } & ToResponsiveProps<SwiperSideArrowsPagingResponsiveProps>;
@@ -12,7 +12,7 @@ import { Switch } from '@janbox/storefront-ui';
12
12
 
13
13
  | Prop | Type | Default | Description |
14
14
  |------|------|---------|-------------|
15
- | `color` | `ColorVariant` | `'primary'` | Color variant for the checked state. Accepts `'primary'` \| `'secondary'` \| `'green'` \| `'red'` \| `'orange'` \| `'blue'` \| `'neutral'`. |
15
+ | `color` | `ColorScale` | `'primary'` | Color variant for the checked state. Accepts `'primary'` \| `'secondary'` \| `'green'` \| `'red'` \| `'orange'` \| `'blue'` \| `'neutral'`. |
16
16
  | `checked` | `boolean` | - | Controlled checked state of the switch. |
17
17
  | `defaultChecked` | `boolean` | `false` | Initial checked state for uncontrolled usage. |
18
18
  | `disabled` | `boolean` | `false` | Disables the switch and prevents interaction. Renders the knob in a neutral gray and suppresses pointer events. |
@@ -1,5 +1,5 @@
1
1
  import { JSX } from 'react';
2
- import { ColorVariant, ShallowMerge } from '../../types';
2
+ import { ColorScale, ShallowMerge } from '../../types';
3
3
  export type SwitchProps = ShallowMerge<JSX.IntrinsicElements['input'], {
4
- color?: ColorVariant;
4
+ color?: ColorScale;
5
5
  }>;
@@ -1,8 +1,8 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { useRef, useState, useEffect } from "react";
3
3
  import { motion } from "motion/react";
4
- import { Stylesheet } from "../../stylesheet/stylesheet.js";
5
4
  import { useTabsContext } from "../tabs/helpers.js";
5
+ import { Stylesheet } from "../../stylesheet/stylesheet.js";
6
6
  const TabIndicator = () => {
7
7
  const { activeIndex, tabIndicatorProps } = useTabsContext();
8
8
  const indicatorEl = useRef(null);
@@ -1,6 +1,5 @@
1
1
  import { jsxs, jsx } from "react/jsx-runtime";
2
- import { useRef, useState } from "react";
3
- import { useMergeRefs } from "@floating-ui/react";
2
+ import { useState, useRef } from "react";
4
3
  import { isString } from "lodash-es";
5
4
  import { getTextareaProps } from "./helpers.js";
6
5
  import { getColorVar } from "../../theme/palette.js";
@@ -26,11 +25,9 @@ const Textarea = ({ ref, ..._props }) => {
26
25
  value,
27
26
  ...rest
28
27
  } = getTextareaProps(_props);
29
- const textareaRef = useRef(null);
30
28
  const [typingValue, setTypingValue] = useState();
31
29
  const timeoutFn = useRef(null);
32
30
  const beforeChangeValue = useRef("");
33
- const mergedRefs = useMergeRefs([ref, textareaRef]);
34
31
  const onChange = (e, force = false) => {
35
32
  if (timeoutFn.current) {
36
33
  clearTimeout(timeoutFn.current);
@@ -150,7 +147,7 @@ const Textarea = ({ ref, ..._props }) => {
150
147
  className,
151
148
  ...rest,
152
149
  value: typingValue ?? value,
153
- ref: mergedRefs,
150
+ ref,
154
151
  onChange,
155
152
  onBlur,
156
153
  onFocus,
@@ -0,0 +1,26 @@
1
+ import { Palette } from './palette';
2
+ import { ThemeTypography } from './typography';
3
+ import { Theme } from '.';
4
+ export type ColorScaleConfig = {
5
+ main: string;
6
+ contrast: string;
7
+ };
8
+ export type CreateThemeConfig = {
9
+ palette?: {
10
+ background?: Partial<Palette['background']>;
11
+ border?: Partial<Palette['border']>;
12
+ surface?: Partial<Palette['surface']>;
13
+ primary?: ColorScaleConfig;
14
+ secondary?: ColorScaleConfig;
15
+ red?: ColorScaleConfig;
16
+ orange?: ColorScaleConfig;
17
+ yellow?: ColorScaleConfig;
18
+ green?: ColorScaleConfig;
19
+ blue?: ColorScaleConfig;
20
+ neutral?: ColorScaleConfig;
21
+ violet?: ColorScaleConfig;
22
+ };
23
+ typography?: ThemeTypography;
24
+ };
25
+ export declare const defaultTheme: Theme;
26
+ export declare const createTheme: (config?: CreateThemeConfig) => Theme;
@@ -0,0 +1,102 @@
1
+ import Color from "color";
2
+ const MIX_RATIOS = {
3
+ 100: 0.1,
4
+ 200: 0.2,
5
+ 300: 0.35,
6
+ 400: 0.55,
7
+ 500: 0.75
8
+ };
9
+ const generateColorScale = (main, contrast, background) => {
10
+ const center = Color(main);
11
+ const bg = Color(background);
12
+ const scale = {};
13
+ for (const [shade, ratio] of Object.entries(MIX_RATIOS)) {
14
+ scale[Number(shade)] = bg.mix(center, ratio).hex();
15
+ }
16
+ scale[600] = center.hex();
17
+ const black = Color("#000");
18
+ scale[700] = center.mix(black, 0.2).hex();
19
+ scale[800] = center.mix(black, 0.4).hex();
20
+ scale.contrast = contrast;
21
+ return scale;
22
+ };
23
+ const DEFAULT_BACKGROUND = "#FFFFFF";
24
+ const DEFAULT_COLOR_CONFIGS = {
25
+ primary: { main: "#7866ff", contrast: "#FFFFFF" },
26
+ secondary: { main: "#14B8A6", contrast: "#FFFFFF" },
27
+ red: { main: "#f5222d", contrast: "#FFFFFF" },
28
+ orange: { main: "#FA8C16", contrast: "#FFFFFF" },
29
+ yellow: { main: "#FADB14", contrast: "#FFFFFF" },
30
+ green: { main: "#389E0D", contrast: "#FFFFFF" },
31
+ blue: { main: "#0F62FE", contrast: "#FFFFFF" },
32
+ violet: { main: "#722ED1", contrast: "#FFFFFF" },
33
+ neutral: { main: "#333333", contrast: "#FFFFFF" }
34
+ };
35
+ const DEFAULT_TYPOGRAPHY = {
36
+ xs: { fontSize: "0.75rem", lineHeight: "1rem" },
37
+ sm: { fontSize: "0.875rem", lineHeight: "1.25rem" },
38
+ base: { fontSize: "1rem", lineHeight: "1.5rem" },
39
+ lg: { fontSize: "1.125rem", lineHeight: "1.75rem" },
40
+ xl: { fontSize: "1.25rem", lineHeight: "1.75rem" },
41
+ "2xl": { fontSize: "1.5rem", lineHeight: "2rem" },
42
+ "3xl": { fontSize: "1.875rem", lineHeight: "2.25rem" },
43
+ "4xl": { fontSize: "2.25rem", lineHeight: "2.5rem" },
44
+ "5xl": { fontSize: "3rem", lineHeight: "3.5rem" },
45
+ "6xl": { fontSize: "3.75rem", lineHeight: "4.5rem" }
46
+ };
47
+ const buildPalette = (bg, overrides) => {
48
+ const result = {};
49
+ for (const key of Object.keys(DEFAULT_COLOR_CONFIGS)) {
50
+ const cfg = overrides[key] ?? DEFAULT_COLOR_CONFIGS[key];
51
+ result[key] = generateColorScale(cfg.main, cfg.contrast, bg);
52
+ }
53
+ return result;
54
+ };
55
+ const defaultTheme = {
56
+ palette: {
57
+ common: {
58
+ black: "#000000",
59
+ white: "#FFFFFF"
60
+ },
61
+ background: {
62
+ subtle: "#F0F0F0",
63
+ default: DEFAULT_BACKGROUND,
64
+ emphasis: "#F2F2F2"
65
+ },
66
+ surface: {
67
+ default: "#FFFFFF"
68
+ },
69
+ border: {
70
+ default: "#E3E3E3"
71
+ },
72
+ ...buildPalette(DEFAULT_BACKGROUND, {})
73
+ },
74
+ typography: DEFAULT_TYPOGRAPHY
75
+ };
76
+ const createTheme = (config) => {
77
+ var _a, _b, _c, _d;
78
+ if (!config) return defaultTheme;
79
+ const background = { ...defaultTheme.palette.background, ...(_a = config.palette) == null ? void 0 : _a.background };
80
+ const bg = background.default;
81
+ const colorOverrides = {};
82
+ for (const key of Object.keys(DEFAULT_COLOR_CONFIGS)) {
83
+ if ((_b = config.palette) == null ? void 0 : _b[key]) {
84
+ colorOverrides[key] = config.palette[key];
85
+ }
86
+ }
87
+ const palette = {
88
+ ...defaultTheme.palette,
89
+ background,
90
+ border: { ...defaultTheme.palette.border, ...(_c = config.palette) == null ? void 0 : _c.border },
91
+ surface: { ...defaultTheme.palette.surface, ...(_d = config.palette) == null ? void 0 : _d.surface },
92
+ ...buildPalette(bg, colorOverrides)
93
+ };
94
+ return {
95
+ palette,
96
+ typography: config.typography ?? defaultTheme.typography
97
+ };
98
+ };
99
+ export {
100
+ createTheme,
101
+ defaultTheme
102
+ };
@@ -4,6 +4,7 @@ export * from './screens';
4
4
  export * from './palette';
5
5
  export * from './typography';
6
6
  export * from './provider';
7
+ export * from './create-theme';
7
8
  export interface Theme {
8
9
  palette: Palette;
9
10
  typography: ThemeTypography;
@@ -2,12 +2,15 @@ import { breakpoint, containerQuery, getSmallerScreens, mediaQuery, screens } fr
2
2
  import { getColorVar, groupedColors, paletteVars, parseColor } from "./palette.js";
3
3
  import { getSmallerTypographyVariants, getTypographyVar, typographyVars } from "./typography.js";
4
4
  import { ThemeProvider, useTheme } from "./provider.js";
5
+ import { createTheme, defaultTheme } from "./create-theme.js";
5
6
  const FLOATING_Z_INDEX = 9999;
6
7
  export {
7
8
  FLOATING_Z_INDEX,
8
9
  ThemeProvider,
9
10
  breakpoint,
10
11
  containerQuery,
12
+ createTheme,
13
+ defaultTheme,
11
14
  getColorVar,
12
15
  getSmallerScreens,
13
16
  getSmallerTypographyVariants,
@@ -1,10 +1,11 @@
1
1
  import { Paths } from 'type-fest';
2
2
  export declare const getColorVar: (key: PaletteKey, fullVar?: boolean) => string;
3
3
  type Scale = 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800;
4
- type ColorScale = Record<Scale, string> & {
4
+ export type ColorScaleValue = Record<Scale, string> & {
5
5
  contrast: string;
6
6
  };
7
- export interface Palette {
7
+ export type ColorScale = 'primary' | 'secondary' | 'red' | 'orange' | 'yellow' | 'green' | 'blue' | 'neutral' | 'violet';
8
+ export type Palette = {
8
9
  readonly common: {
9
10
  readonly black: '#000000';
10
11
  readonly white: '#FFFFFF';
@@ -20,16 +21,7 @@ export interface Palette {
20
21
  surface: {
21
22
  default: string;
22
23
  };
23
- primary: ColorScale;
24
- secondary: ColorScale;
25
- red: ColorScale;
26
- orange: ColorScale;
27
- yellow: ColorScale;
28
- green: ColorScale;
29
- blue: ColorScale;
30
- neutral: ColorScale;
31
- violet: ColorScale;
32
- }
24
+ } & Record<ColorScale, ColorScaleValue>;
33
25
  export type PaletteKey = Paths<Palette>;
34
26
  export declare const paletteVars: Palette;
35
27
  export type GroupedColor = {
@@ -6,7 +6,7 @@ export type Dict<T> = Record<string, T>;
6
6
  export type ShallowMerge<T1, T2> = Omit<T1, keyof T2> & T2;
7
7
  export type ToResponsiveProps<T extends object = object> = T & Partial<Record<Exclude<Screen, 'xs'>, T>>;
8
8
  export type SizeVariant = 'xs' | 'sm' | 'md' | 'lg';
9
- export type ColorVariant = 'primary' | 'secondary' | 'green' | 'red' | 'orange' | 'blue' | 'neutral';
9
+ export type { ColorScale } from '../theme/palette';
10
10
  export type ButtonVariant = 'contained' | 'outlined' | 'text';
11
11
  export type ProgressDirection = 'horizontal' | 'vertical';
12
12
  /**
@@ -1,11 +1,11 @@
1
1
  import { ReactElement } from 'react';
2
- import { Screen, TypographySizeVariant } from '../theme';
3
- import { SizeVariant, ColorVariant, ToResponsiveProps } from '../types';
2
+ import { Screen, TypographySizeVariant, ColorScale } from '../theme';
3
+ import { SizeVariant, ToResponsiveProps } from '../types';
4
4
  import { Get, Paths, SetRequired } from 'type-fest';
5
5
  export * from './common';
6
6
  export * from './query-params';
7
7
  export { createUnderlineEffect } from './stylesheet';
8
- export declare const getColorShadesByVariant: (variant?: ColorVariant) => {
8
+ export declare const getColorShadesByVariant: (variant?: ColorScale) => {
9
9
  main: string;
10
10
  contrast: string;
11
11
  dark: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@janbox/storefront-ui",
3
- "version": "3.0.4",
3
+ "version": "4.0.0",
4
4
  "description": "Storefront UI component library for Janbox",
5
5
  "author": "Janbox",
6
6
  "keywords": [